@clawos-dev/clawd 0.2.188 → 0.2.189-beta.376.57d5363
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 +589 -538
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -733,8 +733,8 @@ var init_parseUtil = __esm({
|
|
|
733
733
|
init_errors2();
|
|
734
734
|
init_en();
|
|
735
735
|
makeIssue = (params) => {
|
|
736
|
-
const { data, path:
|
|
737
|
-
const fullPath = [...
|
|
736
|
+
const { data, path: path67, errorMaps, issueData } = params;
|
|
737
|
+
const fullPath = [...path67, ...issueData.path || []];
|
|
738
738
|
const fullIssue = {
|
|
739
739
|
...issueData,
|
|
740
740
|
path: fullPath
|
|
@@ -1045,11 +1045,11 @@ var init_types = __esm({
|
|
|
1045
1045
|
init_parseUtil();
|
|
1046
1046
|
init_util();
|
|
1047
1047
|
ParseInputLazyPath = class {
|
|
1048
|
-
constructor(parent, value,
|
|
1048
|
+
constructor(parent, value, path67, key) {
|
|
1049
1049
|
this._cachedPath = [];
|
|
1050
1050
|
this.parent = parent;
|
|
1051
1051
|
this.data = value;
|
|
1052
|
-
this._path =
|
|
1052
|
+
this._path = path67;
|
|
1053
1053
|
this._key = key;
|
|
1054
1054
|
}
|
|
1055
1055
|
get path() {
|
|
@@ -6364,8 +6364,8 @@ var require_req = __commonJS({
|
|
|
6364
6364
|
if (req.originalUrl) {
|
|
6365
6365
|
_req.url = req.originalUrl;
|
|
6366
6366
|
} else {
|
|
6367
|
-
const
|
|
6368
|
-
_req.url = typeof
|
|
6367
|
+
const path67 = req.path;
|
|
6368
|
+
_req.url = typeof path67 === "string" ? path67 : req.url ? req.url.path || req.url : void 0;
|
|
6369
6369
|
}
|
|
6370
6370
|
if (req.query) {
|
|
6371
6371
|
_req.query = req.query;
|
|
@@ -6530,14 +6530,14 @@ var require_redact = __commonJS({
|
|
|
6530
6530
|
}
|
|
6531
6531
|
return obj;
|
|
6532
6532
|
}
|
|
6533
|
-
function parsePath(
|
|
6533
|
+
function parsePath(path67) {
|
|
6534
6534
|
const parts = [];
|
|
6535
6535
|
let current = "";
|
|
6536
6536
|
let inBrackets = false;
|
|
6537
6537
|
let inQuotes = false;
|
|
6538
6538
|
let quoteChar = "";
|
|
6539
|
-
for (let i = 0; i <
|
|
6540
|
-
const char =
|
|
6539
|
+
for (let i = 0; i < path67.length; i++) {
|
|
6540
|
+
const char = path67[i];
|
|
6541
6541
|
if (!inBrackets && char === ".") {
|
|
6542
6542
|
if (current) {
|
|
6543
6543
|
parts.push(current);
|
|
@@ -6668,10 +6668,10 @@ var require_redact = __commonJS({
|
|
|
6668
6668
|
return current;
|
|
6669
6669
|
}
|
|
6670
6670
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6671
|
-
for (const
|
|
6672
|
-
const parts = parsePath(
|
|
6671
|
+
for (const path67 of paths) {
|
|
6672
|
+
const parts = parsePath(path67);
|
|
6673
6673
|
if (parts.includes("*")) {
|
|
6674
|
-
redactWildcardPath(obj, parts, censor,
|
|
6674
|
+
redactWildcardPath(obj, parts, censor, path67, remove);
|
|
6675
6675
|
} else {
|
|
6676
6676
|
if (remove) {
|
|
6677
6677
|
removeKey(obj, parts);
|
|
@@ -6756,8 +6756,8 @@ var require_redact = __commonJS({
|
|
|
6756
6756
|
}
|
|
6757
6757
|
} else {
|
|
6758
6758
|
if (afterWildcard.includes("*")) {
|
|
6759
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6760
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
6759
|
+
const wrappedCensor = typeof censor === "function" ? (value, path67) => {
|
|
6760
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path67];
|
|
6761
6761
|
return censor(value, fullPath);
|
|
6762
6762
|
} : censor;
|
|
6763
6763
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -6792,8 +6792,8 @@ var require_redact = __commonJS({
|
|
|
6792
6792
|
return null;
|
|
6793
6793
|
}
|
|
6794
6794
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
6795
|
-
for (const
|
|
6796
|
-
const parts = parsePath(
|
|
6795
|
+
for (const path67 of pathsToClone) {
|
|
6796
|
+
const parts = parsePath(path67);
|
|
6797
6797
|
let current = pathStructure;
|
|
6798
6798
|
for (let i = 0; i < parts.length; i++) {
|
|
6799
6799
|
const part = parts[i];
|
|
@@ -6845,24 +6845,24 @@ var require_redact = __commonJS({
|
|
|
6845
6845
|
}
|
|
6846
6846
|
return cloneSelectively(obj, pathStructure);
|
|
6847
6847
|
}
|
|
6848
|
-
function validatePath(
|
|
6849
|
-
if (typeof
|
|
6848
|
+
function validatePath(path67) {
|
|
6849
|
+
if (typeof path67 !== "string") {
|
|
6850
6850
|
throw new Error("Paths must be (non-empty) strings");
|
|
6851
6851
|
}
|
|
6852
|
-
if (
|
|
6852
|
+
if (path67 === "") {
|
|
6853
6853
|
throw new Error("Invalid redaction path ()");
|
|
6854
6854
|
}
|
|
6855
|
-
if (
|
|
6856
|
-
throw new Error(`Invalid redaction path (${
|
|
6855
|
+
if (path67.includes("..")) {
|
|
6856
|
+
throw new Error(`Invalid redaction path (${path67})`);
|
|
6857
6857
|
}
|
|
6858
|
-
if (
|
|
6859
|
-
throw new Error(`Invalid redaction path (${
|
|
6858
|
+
if (path67.includes(",")) {
|
|
6859
|
+
throw new Error(`Invalid redaction path (${path67})`);
|
|
6860
6860
|
}
|
|
6861
6861
|
let bracketCount = 0;
|
|
6862
6862
|
let inQuotes = false;
|
|
6863
6863
|
let quoteChar = "";
|
|
6864
|
-
for (let i = 0; i <
|
|
6865
|
-
const char =
|
|
6864
|
+
for (let i = 0; i < path67.length; i++) {
|
|
6865
|
+
const char = path67[i];
|
|
6866
6866
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
6867
6867
|
if (!inQuotes) {
|
|
6868
6868
|
inQuotes = true;
|
|
@@ -6876,20 +6876,20 @@ var require_redact = __commonJS({
|
|
|
6876
6876
|
} else if (char === "]" && !inQuotes) {
|
|
6877
6877
|
bracketCount--;
|
|
6878
6878
|
if (bracketCount < 0) {
|
|
6879
|
-
throw new Error(`Invalid redaction path (${
|
|
6879
|
+
throw new Error(`Invalid redaction path (${path67})`);
|
|
6880
6880
|
}
|
|
6881
6881
|
}
|
|
6882
6882
|
}
|
|
6883
6883
|
if (bracketCount !== 0) {
|
|
6884
|
-
throw new Error(`Invalid redaction path (${
|
|
6884
|
+
throw new Error(`Invalid redaction path (${path67})`);
|
|
6885
6885
|
}
|
|
6886
6886
|
}
|
|
6887
6887
|
function validatePaths(paths) {
|
|
6888
6888
|
if (!Array.isArray(paths)) {
|
|
6889
6889
|
throw new TypeError("paths must be an array");
|
|
6890
6890
|
}
|
|
6891
|
-
for (const
|
|
6892
|
-
validatePath(
|
|
6891
|
+
for (const path67 of paths) {
|
|
6892
|
+
validatePath(path67);
|
|
6893
6893
|
}
|
|
6894
6894
|
}
|
|
6895
6895
|
function slowRedact(options = {}) {
|
|
@@ -7057,8 +7057,8 @@ var require_redaction = __commonJS({
|
|
|
7057
7057
|
if (shape[k2] === null) {
|
|
7058
7058
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
7059
7059
|
} else {
|
|
7060
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
7061
|
-
return censor(value, [k2, ...
|
|
7060
|
+
const wrappedCensor = typeof censor === "function" ? (value, path67) => {
|
|
7061
|
+
return censor(value, [k2, ...path67]);
|
|
7062
7062
|
} : censor;
|
|
7063
7063
|
o[k2] = Redact({
|
|
7064
7064
|
paths: shape[k2],
|
|
@@ -7279,7 +7279,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7279
7279
|
var fs60 = require("fs");
|
|
7280
7280
|
var EventEmitter3 = require("events");
|
|
7281
7281
|
var inherits = require("util").inherits;
|
|
7282
|
-
var
|
|
7282
|
+
var path67 = require("path");
|
|
7283
7283
|
var sleep2 = require_atomic_sleep();
|
|
7284
7284
|
var assert = require("assert");
|
|
7285
7285
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7333,7 +7333,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7333
7333
|
const mode = sonic.mode;
|
|
7334
7334
|
if (sonic.sync) {
|
|
7335
7335
|
try {
|
|
7336
|
-
if (sonic.mkdir) fs60.mkdirSync(
|
|
7336
|
+
if (sonic.mkdir) fs60.mkdirSync(path67.dirname(file), { recursive: true });
|
|
7337
7337
|
const fd = fs60.openSync(file, flags, mode);
|
|
7338
7338
|
fileOpened(null, fd);
|
|
7339
7339
|
} catch (err) {
|
|
@@ -7341,7 +7341,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7341
7341
|
throw err;
|
|
7342
7342
|
}
|
|
7343
7343
|
} else if (sonic.mkdir) {
|
|
7344
|
-
fs60.mkdir(
|
|
7344
|
+
fs60.mkdir(path67.dirname(file), { recursive: true }, (err) => {
|
|
7345
7345
|
if (err) return fileOpened(err);
|
|
7346
7346
|
fs60.open(file, flags, mode, fileOpened);
|
|
7347
7347
|
});
|
|
@@ -10201,7 +10201,7 @@ var require_multistream = __commonJS({
|
|
|
10201
10201
|
var require_pino = __commonJS({
|
|
10202
10202
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
10203
10203
|
"use strict";
|
|
10204
|
-
var
|
|
10204
|
+
var os23 = require("os");
|
|
10205
10205
|
var stdSerializers = require_pino_std_serializers();
|
|
10206
10206
|
var caller = require_caller();
|
|
10207
10207
|
var redaction = require_redaction();
|
|
@@ -10248,7 +10248,7 @@ var require_pino = __commonJS({
|
|
|
10248
10248
|
} = symbols;
|
|
10249
10249
|
var { epochTime, nullTime } = time;
|
|
10250
10250
|
var { pid } = process;
|
|
10251
|
-
var hostname =
|
|
10251
|
+
var hostname = os23.hostname();
|
|
10252
10252
|
var defaultErrorSerializer = stdSerializers.err;
|
|
10253
10253
|
var defaultOptions = {
|
|
10254
10254
|
level: "info",
|
|
@@ -10972,11 +10972,11 @@ var init_lib = __esm({
|
|
|
10972
10972
|
}
|
|
10973
10973
|
}
|
|
10974
10974
|
},
|
|
10975
|
-
addToPath: function addToPath(
|
|
10976
|
-
var last =
|
|
10975
|
+
addToPath: function addToPath(path67, added, removed, oldPosInc, options) {
|
|
10976
|
+
var last = path67.lastComponent;
|
|
10977
10977
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
10978
10978
|
return {
|
|
10979
|
-
oldPos:
|
|
10979
|
+
oldPos: path67.oldPos + oldPosInc,
|
|
10980
10980
|
lastComponent: {
|
|
10981
10981
|
count: last.count + 1,
|
|
10982
10982
|
added,
|
|
@@ -10986,7 +10986,7 @@ var init_lib = __esm({
|
|
|
10986
10986
|
};
|
|
10987
10987
|
} else {
|
|
10988
10988
|
return {
|
|
10989
|
-
oldPos:
|
|
10989
|
+
oldPos: path67.oldPos + oldPosInc,
|
|
10990
10990
|
lastComponent: {
|
|
10991
10991
|
count: 1,
|
|
10992
10992
|
added,
|
|
@@ -11044,7 +11044,7 @@ var init_lib = __esm({
|
|
|
11044
11044
|
tokenize: function tokenize(value) {
|
|
11045
11045
|
return Array.from(value);
|
|
11046
11046
|
},
|
|
11047
|
-
join: function
|
|
11047
|
+
join: function join3(chars) {
|
|
11048
11048
|
return chars.join("");
|
|
11049
11049
|
},
|
|
11050
11050
|
postProcess: function postProcess(changeObjects) {
|
|
@@ -11226,13 +11226,33 @@ var init_tool_result_extra = __esm({
|
|
|
11226
11226
|
function cwdToHashDir(cwd) {
|
|
11227
11227
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
11228
11228
|
}
|
|
11229
|
+
function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
|
|
11230
|
+
const dir = import_node_path4.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
|
|
11231
|
+
let entries;
|
|
11232
|
+
try {
|
|
11233
|
+
entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
11234
|
+
} catch {
|
|
11235
|
+
return null;
|
|
11236
|
+
}
|
|
11237
|
+
let newest = null;
|
|
11238
|
+
for (const e of entries) {
|
|
11239
|
+
if (!e.isFile()) continue;
|
|
11240
|
+
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11241
|
+
try {
|
|
11242
|
+
const m2 = import_node_fs4.default.statSync(import_node_path4.default.join(dir, e.name)).mtimeMs;
|
|
11243
|
+
if (newest === null || m2 > newest) newest = m2;
|
|
11244
|
+
} catch {
|
|
11245
|
+
}
|
|
11246
|
+
}
|
|
11247
|
+
return newest;
|
|
11248
|
+
}
|
|
11229
11249
|
function hashDirToCwd(hash) {
|
|
11230
11250
|
const body = hash.startsWith("-") ? hash.slice(1) : hash;
|
|
11231
11251
|
return "/" + body.replace(/-/g, "/");
|
|
11232
11252
|
}
|
|
11233
11253
|
function safeStatMtime(p2) {
|
|
11234
11254
|
try {
|
|
11235
|
-
return
|
|
11255
|
+
return import_node_fs4.default.statSync(p2).mtimeMs;
|
|
11236
11256
|
} catch {
|
|
11237
11257
|
return 0;
|
|
11238
11258
|
}
|
|
@@ -11240,7 +11260,7 @@ function safeStatMtime(p2) {
|
|
|
11240
11260
|
function readJsonlLines(file) {
|
|
11241
11261
|
let raw;
|
|
11242
11262
|
try {
|
|
11243
|
-
raw =
|
|
11263
|
+
raw = import_node_fs4.default.readFileSync(file, "utf8");
|
|
11244
11264
|
} catch (err) {
|
|
11245
11265
|
if (err.code === "ENOENT") return [];
|
|
11246
11266
|
throw err;
|
|
@@ -11432,10 +11452,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11432
11452
|
const memories = raw.map((m2) => {
|
|
11433
11453
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11434
11454
|
const rec3 = m2;
|
|
11435
|
-
const
|
|
11455
|
+
const path67 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11436
11456
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11437
|
-
if (!
|
|
11438
|
-
const entry = { path:
|
|
11457
|
+
if (!path67 || content == null) return null;
|
|
11458
|
+
const entry = { path: path67, content };
|
|
11439
11459
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11440
11460
|
return entry;
|
|
11441
11461
|
}).filter((m2) => m2 !== null);
|
|
@@ -11471,8 +11491,8 @@ function attachmentDeferredToolsText(a) {
|
|
|
11471
11491
|
function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
11472
11492
|
if (backupFileName === null) return null;
|
|
11473
11493
|
try {
|
|
11474
|
-
return
|
|
11475
|
-
|
|
11494
|
+
return import_node_fs4.default.readFileSync(
|
|
11495
|
+
import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
11476
11496
|
"utf8"
|
|
11477
11497
|
);
|
|
11478
11498
|
} catch {
|
|
@@ -11481,19 +11501,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
11481
11501
|
}
|
|
11482
11502
|
function readCurrentContent(filePath) {
|
|
11483
11503
|
try {
|
|
11484
|
-
return
|
|
11504
|
+
return import_node_fs4.default.readFileSync(filePath, "utf8");
|
|
11485
11505
|
} catch (err) {
|
|
11486
11506
|
if (err.code === "ENOENT") return null;
|
|
11487
11507
|
return null;
|
|
11488
11508
|
}
|
|
11489
11509
|
}
|
|
11490
|
-
var
|
|
11510
|
+
var import_node_fs4, import_node_os3, import_node_path4, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
|
|
11491
11511
|
var init_claude_history = __esm({
|
|
11492
11512
|
"src/tools/claude-history.ts"() {
|
|
11493
11513
|
"use strict";
|
|
11494
|
-
|
|
11495
|
-
|
|
11496
|
-
|
|
11514
|
+
import_node_fs4 = __toESM(require("fs"), 1);
|
|
11515
|
+
import_node_os3 = __toESM(require("os"), 1);
|
|
11516
|
+
import_node_path4 = __toESM(require("path"), 1);
|
|
11497
11517
|
init_lib();
|
|
11498
11518
|
init_tool_result_extra();
|
|
11499
11519
|
TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
|
|
@@ -11517,14 +11537,14 @@ var init_claude_history = __esm({
|
|
|
11517
11537
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
11518
11538
|
fileHistoryRoot;
|
|
11519
11539
|
constructor(opts = {}) {
|
|
11520
|
-
const base = opts.baseDir ??
|
|
11521
|
-
this.projectsRoot =
|
|
11522
|
-
this.fileHistoryRoot =
|
|
11540
|
+
const base = opts.baseDir ?? import_node_path4.default.join(import_node_os3.default.homedir(), ".claude");
|
|
11541
|
+
this.projectsRoot = import_node_path4.default.join(base, "projects");
|
|
11542
|
+
this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
|
|
11523
11543
|
}
|
|
11524
11544
|
async listProjects() {
|
|
11525
11545
|
let entries;
|
|
11526
11546
|
try {
|
|
11527
|
-
entries =
|
|
11547
|
+
entries = import_node_fs4.default.readdirSync(this.projectsRoot, { withFileTypes: true });
|
|
11528
11548
|
} catch (err) {
|
|
11529
11549
|
if (err.code === "ENOENT") return [];
|
|
11530
11550
|
throw err;
|
|
@@ -11532,9 +11552,9 @@ var init_claude_history = __esm({
|
|
|
11532
11552
|
const out = [];
|
|
11533
11553
|
for (const ent of entries) {
|
|
11534
11554
|
if (!ent.isDirectory()) continue;
|
|
11535
|
-
const dir =
|
|
11536
|
-
const files =
|
|
11537
|
-
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(
|
|
11555
|
+
const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
|
|
11556
|
+
const files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11557
|
+
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
|
|
11538
11558
|
out.push({
|
|
11539
11559
|
projectPath: hashDirToCwd(ent.name),
|
|
11540
11560
|
hashDir: ent.name,
|
|
@@ -11546,17 +11566,17 @@ var init_claude_history = __esm({
|
|
|
11546
11566
|
return out;
|
|
11547
11567
|
}
|
|
11548
11568
|
async listSessions(args) {
|
|
11549
|
-
const dir =
|
|
11569
|
+
const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
11550
11570
|
let files;
|
|
11551
11571
|
try {
|
|
11552
|
-
files =
|
|
11572
|
+
files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11553
11573
|
} catch (err) {
|
|
11554
11574
|
if (err.code === "ENOENT") return [];
|
|
11555
11575
|
throw err;
|
|
11556
11576
|
}
|
|
11557
11577
|
const out = [];
|
|
11558
11578
|
for (const f of files) {
|
|
11559
|
-
const full =
|
|
11579
|
+
const full = import_node_path4.default.join(dir, f);
|
|
11560
11580
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
11561
11581
|
const lines = readJsonlLines(full);
|
|
11562
11582
|
let summary = "";
|
|
@@ -11611,7 +11631,7 @@ var init_claude_history = __esm({
|
|
|
11611
11631
|
return out;
|
|
11612
11632
|
}
|
|
11613
11633
|
async read(args) {
|
|
11614
|
-
const file =
|
|
11634
|
+
const file = import_node_path4.default.join(
|
|
11615
11635
|
this.projectsRoot,
|
|
11616
11636
|
cwdToHashDir(args.cwd),
|
|
11617
11637
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11648,7 +11668,7 @@ var init_claude_history = __esm({
|
|
|
11648
11668
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
11649
11669
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
11650
11670
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
11651
|
-
const dir =
|
|
11671
|
+
const dir = import_node_path4.default.join(
|
|
11652
11672
|
this.projectsRoot,
|
|
11653
11673
|
cwdToHashDir(cwd),
|
|
11654
11674
|
toolSessionId,
|
|
@@ -11656,7 +11676,7 @@ var init_claude_history = __esm({
|
|
|
11656
11676
|
);
|
|
11657
11677
|
let entries;
|
|
11658
11678
|
try {
|
|
11659
|
-
entries =
|
|
11679
|
+
entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
11660
11680
|
} catch (err) {
|
|
11661
11681
|
if (err.code === "ENOENT") return null;
|
|
11662
11682
|
return null;
|
|
@@ -11666,7 +11686,7 @@ var init_claude_history = __esm({
|
|
|
11666
11686
|
if (!e.isFile()) continue;
|
|
11667
11687
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11668
11688
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
11669
|
-
const filePath =
|
|
11689
|
+
const filePath = import_node_path4.default.join(dir, e.name);
|
|
11670
11690
|
const lines = readJsonlLines(filePath);
|
|
11671
11691
|
let firstText = "";
|
|
11672
11692
|
let messageCount = 0;
|
|
@@ -11683,7 +11703,7 @@ var init_claude_history = __esm({
|
|
|
11683
11703
|
return out;
|
|
11684
11704
|
}
|
|
11685
11705
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
11686
|
-
const file =
|
|
11706
|
+
const file = import_node_path4.default.join(
|
|
11687
11707
|
this.projectsRoot,
|
|
11688
11708
|
cwdToHashDir(cwd),
|
|
11689
11709
|
`${toolSessionId}.jsonl`
|
|
@@ -11718,7 +11738,7 @@ var init_claude_history = __esm({
|
|
|
11718
11738
|
}
|
|
11719
11739
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
11720
11740
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
11721
|
-
const file =
|
|
11741
|
+
const file = import_node_path4.default.join(
|
|
11722
11742
|
this.projectsRoot,
|
|
11723
11743
|
cwdToHashDir(cwd),
|
|
11724
11744
|
toolSessionId,
|
|
@@ -11727,7 +11747,7 @@ var init_claude_history = __esm({
|
|
|
11727
11747
|
);
|
|
11728
11748
|
let exists = false;
|
|
11729
11749
|
try {
|
|
11730
|
-
exists =
|
|
11750
|
+
exists = import_node_fs4.default.statSync(file).isFile();
|
|
11731
11751
|
} catch {
|
|
11732
11752
|
return null;
|
|
11733
11753
|
}
|
|
@@ -11746,7 +11766,7 @@ var init_claude_history = __esm({
|
|
|
11746
11766
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
11747
11767
|
*/
|
|
11748
11768
|
readFileHistorySnapshots(args) {
|
|
11749
|
-
const file =
|
|
11769
|
+
const file = import_node_path4.default.join(
|
|
11750
11770
|
this.projectsRoot,
|
|
11751
11771
|
cwdToHashDir(args.cwd),
|
|
11752
11772
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11791,7 +11811,7 @@ var init_claude_history = __esm({
|
|
|
11791
11811
|
for (const [anchorId, target] of snapshots) {
|
|
11792
11812
|
let hasAny = false;
|
|
11793
11813
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11794
|
-
const absPath =
|
|
11814
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
11795
11815
|
const backupContent = readBackupContent(
|
|
11796
11816
|
this.fileHistoryRoot,
|
|
11797
11817
|
args.toolSessionId,
|
|
@@ -11831,7 +11851,7 @@ var init_claude_history = __esm({
|
|
|
11831
11851
|
let totalInsertions = 0;
|
|
11832
11852
|
let totalDeletions = 0;
|
|
11833
11853
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11834
|
-
const absPath =
|
|
11854
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
11835
11855
|
const backupContent = readBackupContent(
|
|
11836
11856
|
this.fileHistoryRoot,
|
|
11837
11857
|
args.toolSessionId,
|
|
@@ -11878,7 +11898,7 @@ var init_claude_history = __esm({
|
|
|
11878
11898
|
};
|
|
11879
11899
|
}
|
|
11880
11900
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
11881
|
-
const file =
|
|
11901
|
+
const file = import_node_path4.default.join(
|
|
11882
11902
|
this.projectsRoot,
|
|
11883
11903
|
cwdToHashDir(cwd),
|
|
11884
11904
|
`${toolSessionId}.jsonl`
|
|
@@ -12244,10 +12264,10 @@ function parseAttachment(obj) {
|
|
|
12244
12264
|
const memories = raw.map((m2) => {
|
|
12245
12265
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12246
12266
|
const rec3 = m2;
|
|
12247
|
-
const
|
|
12267
|
+
const path67 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12248
12268
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12249
|
-
if (!
|
|
12250
|
-
const out = { path:
|
|
12269
|
+
if (!path67 || content == null) return null;
|
|
12270
|
+
const out = { path: path67, content };
|
|
12251
12271
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12252
12272
|
return out;
|
|
12253
12273
|
}).filter((m2) => m2 !== null);
|
|
@@ -33211,8 +33231,8 @@ var require_utils = __commonJS({
|
|
|
33211
33231
|
var result = transform[inputType][outputType](input);
|
|
33212
33232
|
return result;
|
|
33213
33233
|
};
|
|
33214
|
-
exports2.resolve = function(
|
|
33215
|
-
var parts =
|
|
33234
|
+
exports2.resolve = function(path67) {
|
|
33235
|
+
var parts = path67.split("/");
|
|
33216
33236
|
var result = [];
|
|
33217
33237
|
for (var index = 0; index < parts.length; index++) {
|
|
33218
33238
|
var part = parts[index];
|
|
@@ -39065,18 +39085,18 @@ var require_object = __commonJS({
|
|
|
39065
39085
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
39066
39086
|
this.files[name] = object;
|
|
39067
39087
|
};
|
|
39068
|
-
var parentFolder = function(
|
|
39069
|
-
if (
|
|
39070
|
-
|
|
39088
|
+
var parentFolder = function(path67) {
|
|
39089
|
+
if (path67.slice(-1) === "/") {
|
|
39090
|
+
path67 = path67.substring(0, path67.length - 1);
|
|
39071
39091
|
}
|
|
39072
|
-
var lastSlash =
|
|
39073
|
-
return lastSlash > 0 ?
|
|
39092
|
+
var lastSlash = path67.lastIndexOf("/");
|
|
39093
|
+
return lastSlash > 0 ? path67.substring(0, lastSlash) : "";
|
|
39074
39094
|
};
|
|
39075
|
-
var forceTrailingSlash = function(
|
|
39076
|
-
if (
|
|
39077
|
-
|
|
39095
|
+
var forceTrailingSlash = function(path67) {
|
|
39096
|
+
if (path67.slice(-1) !== "/") {
|
|
39097
|
+
path67 += "/";
|
|
39078
39098
|
}
|
|
39079
|
-
return
|
|
39099
|
+
return path67;
|
|
39080
39100
|
};
|
|
39081
39101
|
var folderAdd = function(name, createFolders) {
|
|
39082
39102
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -40078,7 +40098,7 @@ var require_lib3 = __commonJS({
|
|
|
40078
40098
|
// src/run-case/recorder.ts
|
|
40079
40099
|
function startRunCaseRecorder(opts) {
|
|
40080
40100
|
const now = opts.now ?? Date.now;
|
|
40081
|
-
const dir =
|
|
40101
|
+
const dir = import_node_path55.default.dirname(opts.recordPath);
|
|
40082
40102
|
let stream = null;
|
|
40083
40103
|
let closing = false;
|
|
40084
40104
|
let closedSettled = false;
|
|
@@ -40118,12 +40138,12 @@ function startRunCaseRecorder(opts) {
|
|
|
40118
40138
|
};
|
|
40119
40139
|
return { tap, close, closed };
|
|
40120
40140
|
}
|
|
40121
|
-
var import_node_fs42,
|
|
40141
|
+
var import_node_fs42, import_node_path55;
|
|
40122
40142
|
var init_recorder = __esm({
|
|
40123
40143
|
"src/run-case/recorder.ts"() {
|
|
40124
40144
|
"use strict";
|
|
40125
40145
|
import_node_fs42 = __toESM(require("fs"), 1);
|
|
40126
|
-
|
|
40146
|
+
import_node_path55 = __toESM(require("path"), 1);
|
|
40127
40147
|
}
|
|
40128
40148
|
});
|
|
40129
40149
|
|
|
@@ -40166,7 +40186,7 @@ var init_wire = __esm({
|
|
|
40166
40186
|
// src/run-case/controller.ts
|
|
40167
40187
|
async function runController(opts) {
|
|
40168
40188
|
const now = opts.now ?? Date.now;
|
|
40169
|
-
const cwd = opts.cwd ?? (0, import_node_fs43.mkdtempSync)(
|
|
40189
|
+
const cwd = opts.cwd ?? (0, import_node_fs43.mkdtempSync)(import_node_path56.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
|
|
40170
40190
|
const ownsCwd = opts.cwd === void 0;
|
|
40171
40191
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40172
40192
|
const spawnCtx = { cwd };
|
|
@@ -40333,13 +40353,13 @@ async function runController(opts) {
|
|
|
40333
40353
|
}
|
|
40334
40354
|
return exitCode ?? 0;
|
|
40335
40355
|
}
|
|
40336
|
-
var import_node_fs43,
|
|
40356
|
+
var import_node_fs43, import_node_os22, import_node_path56;
|
|
40337
40357
|
var init_controller = __esm({
|
|
40338
40358
|
"src/run-case/controller.ts"() {
|
|
40339
40359
|
"use strict";
|
|
40340
40360
|
import_node_fs43 = require("fs");
|
|
40341
|
-
|
|
40342
|
-
|
|
40361
|
+
import_node_os22 = __toESM(require("os"), 1);
|
|
40362
|
+
import_node_path56 = __toESM(require("path"), 1);
|
|
40343
40363
|
init_claude();
|
|
40344
40364
|
init_stdout_splitter();
|
|
40345
40365
|
init_permission_stdio();
|
|
@@ -40601,9 +40621,9 @@ Env (advanced):
|
|
|
40601
40621
|
`;
|
|
40602
40622
|
|
|
40603
40623
|
// src/index.ts
|
|
40604
|
-
var
|
|
40624
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
40605
40625
|
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
40606
|
-
var
|
|
40626
|
+
var import_node_os21 = __toESM(require("os"), 1);
|
|
40607
40627
|
|
|
40608
40628
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
40609
40629
|
var byteToHex = [];
|
|
@@ -41220,9 +41240,9 @@ var SessionStoreFactory = class {
|
|
|
41220
41240
|
};
|
|
41221
41241
|
|
|
41222
41242
|
// src/session/manager.ts
|
|
41223
|
-
var
|
|
41224
|
-
var
|
|
41225
|
-
var
|
|
41243
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
41244
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
41245
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
41226
41246
|
init_protocol();
|
|
41227
41247
|
|
|
41228
41248
|
// src/tools/guest-settings.ts
|
|
@@ -41320,6 +41340,10 @@ function escapeAttr(v2) {
|
|
|
41320
41340
|
return v2.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
41321
41341
|
}
|
|
41322
41342
|
|
|
41343
|
+
// src/session/runner.ts
|
|
41344
|
+
var import_node_os4 = __toESM(require("os"), 1);
|
|
41345
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
41346
|
+
|
|
41323
41347
|
// src/session/reducer.ts
|
|
41324
41348
|
init_runtime();
|
|
41325
41349
|
|
|
@@ -41458,7 +41482,8 @@ function cloneState(s) {
|
|
|
41458
41482
|
pendingSend: s.pendingSend.slice()
|
|
41459
41483
|
};
|
|
41460
41484
|
}
|
|
41461
|
-
var IDLE_KILL_DELAY_MS =
|
|
41485
|
+
var IDLE_KILL_DELAY_MS = 36e5;
|
|
41486
|
+
var IDLE_KILL_SUBAGENT_RECHECK_MS = 3e5;
|
|
41462
41487
|
function tryFlushPending(state, deps) {
|
|
41463
41488
|
if (!state.readyForSend || state.pendingSend.length === 0) return [];
|
|
41464
41489
|
const text = state.pendingSend.shift();
|
|
@@ -42127,6 +42152,18 @@ function reduceSession(state, input, deps) {
|
|
|
42127
42152
|
if (state.status !== "running-idle") {
|
|
42128
42153
|
return { state, effects: [] };
|
|
42129
42154
|
}
|
|
42155
|
+
if (input.subagentActive) {
|
|
42156
|
+
return {
|
|
42157
|
+
state,
|
|
42158
|
+
effects: [
|
|
42159
|
+
{
|
|
42160
|
+
kind: "schedule-idle-kill",
|
|
42161
|
+
sessionId: state.file.sessionId,
|
|
42162
|
+
ms: IDLE_KILL_SUBAGENT_RECHECK_MS
|
|
42163
|
+
}
|
|
42164
|
+
]
|
|
42165
|
+
};
|
|
42166
|
+
}
|
|
42130
42167
|
const next = cloneState(state);
|
|
42131
42168
|
next.status = "stopping";
|
|
42132
42169
|
return {
|
|
@@ -42183,10 +42220,11 @@ function reduceSession(state, input, deps) {
|
|
|
42183
42220
|
// src/session/runner.ts
|
|
42184
42221
|
init_stdout_splitter();
|
|
42185
42222
|
init_permission_stdio();
|
|
42223
|
+
init_claude_history();
|
|
42186
42224
|
|
|
42187
42225
|
// src/ipc-recorder.ts
|
|
42188
|
-
var
|
|
42189
|
-
var
|
|
42226
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
42227
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
42190
42228
|
function tsForFilename(ms) {
|
|
42191
42229
|
return new Date(ms).toISOString().replace(/[:.]/g, "-");
|
|
42192
42230
|
}
|
|
@@ -42197,8 +42235,8 @@ function startRecorder(opts) {
|
|
|
42197
42235
|
return null;
|
|
42198
42236
|
}
|
|
42199
42237
|
const now = opts.now ?? Date.now;
|
|
42200
|
-
const dir =
|
|
42201
|
-
const filePath =
|
|
42238
|
+
const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
|
|
42239
|
+
const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
|
|
42202
42240
|
let stream = null;
|
|
42203
42241
|
let closedResolve;
|
|
42204
42242
|
const closed = new Promise((resolve6) => {
|
|
@@ -42207,8 +42245,8 @@ function startRecorder(opts) {
|
|
|
42207
42245
|
let exited = false;
|
|
42208
42246
|
const ensureStream = () => {
|
|
42209
42247
|
if (stream) return stream;
|
|
42210
|
-
|
|
42211
|
-
stream =
|
|
42248
|
+
import_node_fs5.default.mkdirSync(dir, { recursive: true });
|
|
42249
|
+
stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
|
|
42212
42250
|
stream.on("close", () => closedResolve());
|
|
42213
42251
|
return stream;
|
|
42214
42252
|
};
|
|
@@ -42253,6 +42291,7 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
|
|
|
42253
42291
|
return JSON.stringify(payload) + "\n";
|
|
42254
42292
|
}
|
|
42255
42293
|
var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
|
|
42294
|
+
var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
|
|
42256
42295
|
var SessionRunner = class {
|
|
42257
42296
|
constructor(initial, hooks) {
|
|
42258
42297
|
this.hooks = hooks;
|
|
@@ -42564,7 +42603,7 @@ var SessionRunner = class {
|
|
|
42564
42603
|
if (existing) clearTimeout(existing);
|
|
42565
42604
|
const timer = setTimeout(() => {
|
|
42566
42605
|
this.idleKillTimers.delete(effect.sessionId);
|
|
42567
|
-
this.input({ kind: "idle-kill-fired" });
|
|
42606
|
+
this.input({ kind: "idle-kill-fired", subagentActive: this.isSubagentActive() });
|
|
42568
42607
|
}, effect.ms);
|
|
42569
42608
|
timer.unref?.();
|
|
42570
42609
|
this.idleKillTimers.set(effect.sessionId, timer);
|
|
@@ -42580,6 +42619,18 @@ var SessionRunner = class {
|
|
|
42580
42619
|
}
|
|
42581
42620
|
}
|
|
42582
42621
|
}
|
|
42622
|
+
// idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
|
|
42623
|
+
// 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
|
|
42624
|
+
// 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
|
|
42625
|
+
isSubagentActive() {
|
|
42626
|
+
const toolSessionId = this.state.file.toolSessionId;
|
|
42627
|
+
if (!toolSessionId) return false;
|
|
42628
|
+
const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
|
|
42629
|
+
const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
|
|
42630
|
+
if (mtime === null) return false;
|
|
42631
|
+
const now = (this.hooks.now ?? Date.now)();
|
|
42632
|
+
return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
|
|
42633
|
+
}
|
|
42583
42634
|
// 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
|
|
42584
42635
|
// 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
|
|
42585
42636
|
clearIdleKillTimers() {
|
|
@@ -42662,15 +42713,15 @@ function extractEditPath(input) {
|
|
|
42662
42713
|
}
|
|
42663
42714
|
|
|
42664
42715
|
// src/debug/pty-probe.ts
|
|
42665
|
-
var
|
|
42666
|
-
var
|
|
42716
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
42717
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
42667
42718
|
var PROBE_DIR = "/tmp/clawd-probe";
|
|
42668
|
-
var EVENTS_FILE =
|
|
42719
|
+
var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
|
|
42669
42720
|
var inited = false;
|
|
42670
42721
|
function ensureDir() {
|
|
42671
42722
|
if (inited) return true;
|
|
42672
42723
|
try {
|
|
42673
|
-
|
|
42724
|
+
import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
|
|
42674
42725
|
inited = true;
|
|
42675
42726
|
return true;
|
|
42676
42727
|
} catch {
|
|
@@ -42681,15 +42732,15 @@ function probeEvent(event, data = {}) {
|
|
|
42681
42732
|
try {
|
|
42682
42733
|
if (!ensureDir()) return;
|
|
42683
42734
|
const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
|
|
42684
|
-
|
|
42735
|
+
import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
|
|
42685
42736
|
} catch {
|
|
42686
42737
|
}
|
|
42687
42738
|
}
|
|
42688
42739
|
function probeDumpReplay(sessionId, payload) {
|
|
42689
42740
|
try {
|
|
42690
42741
|
if (!ensureDir()) return "";
|
|
42691
|
-
const file =
|
|
42692
|
-
|
|
42742
|
+
const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
|
|
42743
|
+
import_node_fs6.default.writeFileSync(file, payload, "utf8");
|
|
42693
42744
|
return file;
|
|
42694
42745
|
} catch {
|
|
42695
42746
|
return "";
|
|
@@ -42796,7 +42847,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
|
|
|
42796
42847
|
`derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
|
|
42797
42848
|
);
|
|
42798
42849
|
}
|
|
42799
|
-
return
|
|
42850
|
+
return import_node_path8.default.join(personaRoot, safeFileName(personaId));
|
|
42800
42851
|
}
|
|
42801
42852
|
function makeInitialState(file, subSessionMeta) {
|
|
42802
42853
|
return {
|
|
@@ -42921,10 +42972,10 @@ var SessionManager = class {
|
|
|
42921
42972
|
// <dataDir>/sessions/ 列子目录 (排除 'default').
|
|
42922
42973
|
listPersonaIdsOnDisk() {
|
|
42923
42974
|
if (!this.deps.dataDir) return [];
|
|
42924
|
-
const root = this.deps.storeFactory ?
|
|
42975
|
+
const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
|
|
42925
42976
|
let entries;
|
|
42926
42977
|
try {
|
|
42927
|
-
entries =
|
|
42978
|
+
entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
|
|
42928
42979
|
} catch (err) {
|
|
42929
42980
|
const code = err?.code;
|
|
42930
42981
|
if (code === "ENOENT") return [];
|
|
@@ -42937,7 +42988,7 @@ var SessionManager = class {
|
|
|
42937
42988
|
// 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
|
|
42938
42989
|
listGuestCapIdsForPersona(personaId) {
|
|
42939
42990
|
if (!this.deps.dataDir || !this.deps.storeFactory) return [];
|
|
42940
|
-
const root =
|
|
42991
|
+
const root = import_node_path8.default.join(
|
|
42941
42992
|
this.deps.dataDir,
|
|
42942
42993
|
"personas",
|
|
42943
42994
|
personaId,
|
|
@@ -42947,7 +42998,7 @@ var SessionManager = class {
|
|
|
42947
42998
|
);
|
|
42948
42999
|
let entries;
|
|
42949
43000
|
try {
|
|
42950
|
-
entries =
|
|
43001
|
+
entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
|
|
42951
43002
|
} catch (err) {
|
|
42952
43003
|
const code = err?.code;
|
|
42953
43004
|
if (code === "ENOENT") return [];
|
|
@@ -43066,7 +43117,7 @@ var SessionManager = class {
|
|
|
43066
43117
|
callerDisplayName
|
|
43067
43118
|
);
|
|
43068
43119
|
if (subSessionMeta?.userWorkDir) {
|
|
43069
|
-
|
|
43120
|
+
import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
|
|
43070
43121
|
}
|
|
43071
43122
|
if (scope.kind === "persona" && scope.mode === "guest") {
|
|
43072
43123
|
if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
|
|
@@ -43077,8 +43128,8 @@ var SessionManager = class {
|
|
|
43077
43128
|
const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
|
|
43078
43129
|
const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
|
|
43079
43130
|
subSessionMeta.extraSettings = JSON.stringify(settings);
|
|
43080
|
-
const home =
|
|
43081
|
-
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ?
|
|
43131
|
+
const home = import_node_os5.default.homedir();
|
|
43132
|
+
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
|
|
43082
43133
|
const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
|
|
43083
43134
|
subSessionMeta.codexSandbox = {
|
|
43084
43135
|
writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
|
|
@@ -43230,7 +43281,7 @@ var SessionManager = class {
|
|
|
43230
43281
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
|
|
43231
43282
|
}
|
|
43232
43283
|
try {
|
|
43233
|
-
const stat =
|
|
43284
|
+
const stat = import_node_fs7.default.statSync(cwd);
|
|
43234
43285
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43235
43286
|
} catch {
|
|
43236
43287
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
|
|
@@ -43761,7 +43812,7 @@ var SessionManager = class {
|
|
|
43761
43812
|
*/
|
|
43762
43813
|
createForScope(args) {
|
|
43763
43814
|
try {
|
|
43764
|
-
const stat =
|
|
43815
|
+
const stat = import_node_fs7.default.statSync(args.cwd);
|
|
43765
43816
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43766
43817
|
} catch {
|
|
43767
43818
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -43977,7 +44028,7 @@ var SessionManager = class {
|
|
|
43977
44028
|
personaId: args.targetPersona,
|
|
43978
44029
|
mode: "owner"
|
|
43979
44030
|
};
|
|
43980
|
-
const cwd =
|
|
44031
|
+
const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
43981
44032
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
43982
44033
|
const file = {
|
|
43983
44034
|
sessionId,
|
|
@@ -44042,7 +44093,7 @@ var SessionManager = class {
|
|
|
44042
44093
|
personaId: args.targetPersona,
|
|
44043
44094
|
mode: "owner"
|
|
44044
44095
|
};
|
|
44045
|
-
const cwd =
|
|
44096
|
+
const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44046
44097
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44047
44098
|
const file = {
|
|
44048
44099
|
sessionId,
|
|
@@ -44524,28 +44575,28 @@ var SessionManager = class {
|
|
|
44524
44575
|
};
|
|
44525
44576
|
|
|
44526
44577
|
// src/persona/store.ts
|
|
44527
|
-
var
|
|
44528
|
-
var
|
|
44578
|
+
var fs8 = __toESM(require("fs"), 1);
|
|
44579
|
+
var path11 = __toESM(require("path"), 1);
|
|
44529
44580
|
init_protocol();
|
|
44530
44581
|
var PersonaStore = class {
|
|
44531
44582
|
constructor(root) {
|
|
44532
44583
|
this.root = root;
|
|
44533
|
-
|
|
44584
|
+
fs8.mkdirSync(root, { recursive: true });
|
|
44534
44585
|
}
|
|
44535
44586
|
root;
|
|
44536
44587
|
personaDir(personaId) {
|
|
44537
|
-
return
|
|
44588
|
+
return path11.join(this.root, safeFileName(personaId));
|
|
44538
44589
|
}
|
|
44539
44590
|
metaPath(personaId) {
|
|
44540
|
-
return
|
|
44591
|
+
return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
|
|
44541
44592
|
}
|
|
44542
44593
|
claudeMdPath(personaId) {
|
|
44543
|
-
return
|
|
44594
|
+
return path11.join(this.personaDir(personaId), "CLAUDE.md");
|
|
44544
44595
|
}
|
|
44545
44596
|
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
44546
44597
|
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
44547
44598
|
agentsMdPath(personaId) {
|
|
44548
|
-
return
|
|
44599
|
+
return path11.join(this.personaDir(personaId), "AGENTS.md");
|
|
44549
44600
|
}
|
|
44550
44601
|
/**
|
|
44551
44602
|
* persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
@@ -44554,11 +44605,11 @@ var PersonaStore = class {
|
|
|
44554
44605
|
* spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
|
|
44555
44606
|
*/
|
|
44556
44607
|
sandboxSettingsPath(personaId) {
|
|
44557
|
-
return
|
|
44608
|
+
return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
|
|
44558
44609
|
}
|
|
44559
44610
|
write(persona, personality) {
|
|
44560
44611
|
const dir = this.personaDir(persona.personaId);
|
|
44561
|
-
|
|
44612
|
+
fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
|
|
44562
44613
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
44563
44614
|
this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
|
|
44564
44615
|
this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
|
|
@@ -44577,9 +44628,9 @@ var PersonaStore = class {
|
|
|
44577
44628
|
ensureAgentsMirror(personaId) {
|
|
44578
44629
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44579
44630
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44580
|
-
if (!
|
|
44581
|
-
if (
|
|
44582
|
-
this.atomicWrite(agentsMd,
|
|
44631
|
+
if (!fs8.existsSync(claudeMd)) return false;
|
|
44632
|
+
if (fs8.existsSync(agentsMd)) return false;
|
|
44633
|
+
this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
|
|
44583
44634
|
return true;
|
|
44584
44635
|
}
|
|
44585
44636
|
/**
|
|
@@ -44603,22 +44654,22 @@ var PersonaStore = class {
|
|
|
44603
44654
|
return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
|
|
44604
44655
|
}
|
|
44605
44656
|
codexSandboxSettingsPath(personaId) {
|
|
44606
|
-
return
|
|
44657
|
+
return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
|
|
44607
44658
|
}
|
|
44608
44659
|
/** 读 codex-sandbox.json;不存在/损坏 → null。 */
|
|
44609
44660
|
readCodexSandboxSettings(personaId) {
|
|
44610
44661
|
const p2 = this.codexSandboxSettingsPath(personaId);
|
|
44611
|
-
if (!
|
|
44662
|
+
if (!fs8.existsSync(p2)) return null;
|
|
44612
44663
|
try {
|
|
44613
|
-
return CodexSandboxSettingsSchema.parse(JSON.parse(
|
|
44664
|
+
return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
|
|
44614
44665
|
} catch {
|
|
44615
44666
|
return null;
|
|
44616
44667
|
}
|
|
44617
44668
|
}
|
|
44618
44669
|
/** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
|
|
44619
44670
|
writeCodexSandboxSettings(personaId, settings) {
|
|
44620
|
-
const dir =
|
|
44621
|
-
|
|
44671
|
+
const dir = path11.join(this.personaDir(personaId), ".clawd");
|
|
44672
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
44622
44673
|
this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
|
|
44623
44674
|
}
|
|
44624
44675
|
writeMeta(persona) {
|
|
@@ -44626,8 +44677,8 @@ var PersonaStore = class {
|
|
|
44626
44677
|
}
|
|
44627
44678
|
read(personaId) {
|
|
44628
44679
|
const p2 = this.metaPath(personaId);
|
|
44629
|
-
if (!
|
|
44630
|
-
const raw = JSON.parse(
|
|
44680
|
+
if (!fs8.existsSync(p2)) return null;
|
|
44681
|
+
const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
44631
44682
|
if (raw && typeof raw === "object" && "tokenMap" in raw) {
|
|
44632
44683
|
delete raw.tokenMap;
|
|
44633
44684
|
this.atomicWrite(p2, JSON.stringify(raw, null, 2));
|
|
@@ -44635,13 +44686,13 @@ var PersonaStore = class {
|
|
|
44635
44686
|
return PersonaFileSchema.parse(raw);
|
|
44636
44687
|
}
|
|
44637
44688
|
has(personaId) {
|
|
44638
|
-
return
|
|
44689
|
+
return fs8.existsSync(this.metaPath(personaId));
|
|
44639
44690
|
}
|
|
44640
44691
|
readPersonality(personaId) {
|
|
44641
44692
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44642
|
-
if (
|
|
44693
|
+
if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
|
|
44643
44694
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44644
|
-
if (
|
|
44695
|
+
if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
|
|
44645
44696
|
return null;
|
|
44646
44697
|
}
|
|
44647
44698
|
/**
|
|
@@ -44650,23 +44701,23 @@ var PersonaStore = class {
|
|
|
44650
44701
|
*/
|
|
44651
44702
|
readSandboxSettings(personaId) {
|
|
44652
44703
|
const p2 = this.sandboxSettingsPath(personaId);
|
|
44653
|
-
if (!
|
|
44704
|
+
if (!fs8.existsSync(p2)) return null;
|
|
44654
44705
|
try {
|
|
44655
|
-
return JSON.parse(
|
|
44706
|
+
return JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
44656
44707
|
} catch {
|
|
44657
44708
|
return null;
|
|
44658
44709
|
}
|
|
44659
44710
|
}
|
|
44660
44711
|
/** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
|
|
44661
44712
|
skillsDir(personaId) {
|
|
44662
|
-
return
|
|
44713
|
+
return path11.join(this.personaDir(personaId), ".claude", "skills");
|
|
44663
44714
|
}
|
|
44664
44715
|
/**
|
|
44665
44716
|
* Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
|
|
44666
44717
|
* 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
|
|
44667
44718
|
*/
|
|
44668
44719
|
claudeSettingsPath(personaId) {
|
|
44669
|
-
return
|
|
44720
|
+
return path11.join(this.personaDir(personaId), ".claude", "settings.json");
|
|
44670
44721
|
}
|
|
44671
44722
|
/**
|
|
44672
44723
|
* 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
|
|
@@ -44681,10 +44732,10 @@ var PersonaStore = class {
|
|
|
44681
44732
|
*/
|
|
44682
44733
|
readEnabledPlugins(personaId) {
|
|
44683
44734
|
const p2 = this.claudeSettingsPath(personaId);
|
|
44684
|
-
if (!
|
|
44735
|
+
if (!fs8.existsSync(p2)) return [];
|
|
44685
44736
|
let raw;
|
|
44686
44737
|
try {
|
|
44687
|
-
raw = JSON.parse(
|
|
44738
|
+
raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
44688
44739
|
} catch {
|
|
44689
44740
|
return [];
|
|
44690
44741
|
}
|
|
@@ -44698,22 +44749,22 @@ var PersonaStore = class {
|
|
|
44698
44749
|
return out;
|
|
44699
44750
|
}
|
|
44700
44751
|
list() {
|
|
44701
|
-
if (!
|
|
44702
|
-
return
|
|
44703
|
-
return
|
|
44752
|
+
if (!fs8.existsSync(this.root)) return [];
|
|
44753
|
+
return fs8.readdirSync(this.root).filter((name) => {
|
|
44754
|
+
return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
|
|
44704
44755
|
});
|
|
44705
44756
|
}
|
|
44706
44757
|
remove(personaId) {
|
|
44707
44758
|
const dir = this.personaDir(personaId);
|
|
44708
|
-
if (
|
|
44759
|
+
if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
|
|
44709
44760
|
}
|
|
44710
44761
|
personaDirPath(personaId) {
|
|
44711
44762
|
return this.personaDir(personaId);
|
|
44712
44763
|
}
|
|
44713
44764
|
atomicWrite(file, content) {
|
|
44714
44765
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
44715
|
-
|
|
44716
|
-
|
|
44766
|
+
fs8.writeFileSync(tmp, content, { mode: 384 });
|
|
44767
|
+
fs8.renameSync(tmp, file);
|
|
44717
44768
|
}
|
|
44718
44769
|
};
|
|
44719
44770
|
|
|
@@ -44759,9 +44810,9 @@ var PersonaRegistry = class {
|
|
|
44759
44810
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
44760
44811
|
|
|
44761
44812
|
// src/skills/scanner.ts
|
|
44762
|
-
var
|
|
44763
|
-
var
|
|
44764
|
-
var
|
|
44813
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
44814
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
44815
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
44765
44816
|
|
|
44766
44817
|
// src/skills/frontmatter.ts
|
|
44767
44818
|
var STRIP_QUOTES = /^["']|["']$/g;
|
|
@@ -44870,7 +44921,7 @@ function parseDescription(content) {
|
|
|
44870
44921
|
}
|
|
44871
44922
|
function isDirLikeSync(p2) {
|
|
44872
44923
|
try {
|
|
44873
|
-
return
|
|
44924
|
+
return import_node_fs8.default.statSync(p2).isDirectory();
|
|
44874
44925
|
} catch {
|
|
44875
44926
|
return false;
|
|
44876
44927
|
}
|
|
@@ -44878,19 +44929,19 @@ function isDirLikeSync(p2) {
|
|
|
44878
44929
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
44879
44930
|
let entries;
|
|
44880
44931
|
try {
|
|
44881
|
-
entries =
|
|
44932
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
44882
44933
|
} catch {
|
|
44883
44934
|
return;
|
|
44884
44935
|
}
|
|
44885
44936
|
for (const ent of entries) {
|
|
44886
|
-
const entryPath =
|
|
44937
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
44887
44938
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
44888
44939
|
let content;
|
|
44889
44940
|
try {
|
|
44890
|
-
content =
|
|
44941
|
+
content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
|
|
44891
44942
|
} catch {
|
|
44892
44943
|
try {
|
|
44893
|
-
content =
|
|
44944
|
+
content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
|
|
44894
44945
|
} catch {
|
|
44895
44946
|
continue;
|
|
44896
44947
|
}
|
|
@@ -44914,26 +44965,26 @@ function listSkillsForDir(dir, source) {
|
|
|
44914
44965
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
44915
44966
|
let entries;
|
|
44916
44967
|
try {
|
|
44917
|
-
entries =
|
|
44968
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
44918
44969
|
} catch {
|
|
44919
44970
|
return;
|
|
44920
44971
|
}
|
|
44921
44972
|
for (const ent of entries) {
|
|
44922
|
-
const entryPath =
|
|
44973
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
44923
44974
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
44924
44975
|
const ns = ent.name;
|
|
44925
44976
|
let subEntries;
|
|
44926
44977
|
try {
|
|
44927
|
-
subEntries =
|
|
44978
|
+
subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
|
|
44928
44979
|
} catch {
|
|
44929
44980
|
continue;
|
|
44930
44981
|
}
|
|
44931
44982
|
for (const se of subEntries) {
|
|
44932
44983
|
if (!se.name.endsWith(".md")) continue;
|
|
44933
|
-
const sePath =
|
|
44984
|
+
const sePath = import_node_path9.default.join(entryPath, se.name);
|
|
44934
44985
|
let content;
|
|
44935
44986
|
try {
|
|
44936
|
-
content =
|
|
44987
|
+
content = import_node_fs8.default.readFileSync(sePath, "utf8");
|
|
44937
44988
|
} catch {
|
|
44938
44989
|
continue;
|
|
44939
44990
|
}
|
|
@@ -44950,7 +45001,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
44950
45001
|
} else if (ent.name.endsWith(".md")) {
|
|
44951
45002
|
let content;
|
|
44952
45003
|
try {
|
|
44953
|
-
content =
|
|
45004
|
+
content = import_node_fs8.default.readFileSync(entryPath, "utf8");
|
|
44954
45005
|
} catch {
|
|
44955
45006
|
continue;
|
|
44956
45007
|
}
|
|
@@ -44966,10 +45017,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
44966
45017
|
}
|
|
44967
45018
|
}
|
|
44968
45019
|
function readInstalledPlugins(home) {
|
|
44969
|
-
const file =
|
|
45020
|
+
const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
44970
45021
|
let raw;
|
|
44971
45022
|
try {
|
|
44972
|
-
raw =
|
|
45023
|
+
raw = import_node_fs8.default.readFileSync(file, "utf8");
|
|
44973
45024
|
} catch {
|
|
44974
45025
|
return [];
|
|
44975
45026
|
}
|
|
@@ -44994,7 +45045,7 @@ var SkillsScanner = class {
|
|
|
44994
45045
|
home;
|
|
44995
45046
|
extraPluginRoots;
|
|
44996
45047
|
constructor(opts = {}) {
|
|
44997
|
-
this.home = opts.home ??
|
|
45048
|
+
this.home = opts.home ?? import_node_os6.default.homedir();
|
|
44998
45049
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
44999
45050
|
}
|
|
45000
45051
|
/**
|
|
@@ -45017,14 +45068,14 @@ var SkillsScanner = class {
|
|
|
45017
45068
|
});
|
|
45018
45069
|
}
|
|
45019
45070
|
const fsBlock = [];
|
|
45020
|
-
scanSkillDir(
|
|
45021
|
-
scanCommandDir(
|
|
45022
|
-
scanSkillDir(
|
|
45023
|
-
scanCommandDir(
|
|
45071
|
+
scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
|
|
45072
|
+
scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
|
|
45073
|
+
scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
|
|
45074
|
+
scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
|
|
45024
45075
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
45025
45076
|
for (const { name, root } of plugins) {
|
|
45026
|
-
scanSkillDir(
|
|
45027
|
-
scanCommandDir(
|
|
45077
|
+
scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
|
|
45078
|
+
scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
|
|
45028
45079
|
}
|
|
45029
45080
|
fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
|
|
45030
45081
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -45130,8 +45181,8 @@ var PersonaManager = class {
|
|
|
45130
45181
|
};
|
|
45131
45182
|
|
|
45132
45183
|
// src/persona/seed.ts
|
|
45133
|
-
var
|
|
45134
|
-
var
|
|
45184
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
45185
|
+
var path13 = __toESM(require("path"), 1);
|
|
45135
45186
|
var import_node_url = require("url");
|
|
45136
45187
|
var import_meta = {};
|
|
45137
45188
|
var DEFAULT_BYPASS_PROFILE = {
|
|
@@ -45301,24 +45352,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
|
|
|
45301
45352
|
if (!argv1) return null;
|
|
45302
45353
|
let real = argv1;
|
|
45303
45354
|
try {
|
|
45304
|
-
real =
|
|
45355
|
+
real = fs10.realpathSync(argv1);
|
|
45305
45356
|
} catch {
|
|
45306
45357
|
}
|
|
45307
|
-
return
|
|
45358
|
+
return path13.resolve(path13.dirname(real), sibling);
|
|
45308
45359
|
}
|
|
45309
45360
|
function findDefaultsRoot(logger) {
|
|
45310
45361
|
const candidates = [];
|
|
45311
45362
|
try {
|
|
45312
|
-
const here =
|
|
45313
|
-
candidates.push(
|
|
45314
|
-
candidates.push(
|
|
45363
|
+
const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45364
|
+
candidates.push(path13.resolve(here, "defaults"));
|
|
45365
|
+
candidates.push(path13.resolve(here, "persona-defaults"));
|
|
45315
45366
|
} catch {
|
|
45316
45367
|
}
|
|
45317
45368
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
|
|
45318
45369
|
if (fromArgv) candidates.push(fromArgv);
|
|
45319
45370
|
for (const c of candidates) {
|
|
45320
45371
|
try {
|
|
45321
|
-
if (
|
|
45372
|
+
if (fs10.statSync(c).isDirectory()) {
|
|
45322
45373
|
logger?.info("persona.defaults-root.resolved", { root: c });
|
|
45323
45374
|
return c;
|
|
45324
45375
|
}
|
|
@@ -45335,8 +45386,8 @@ function seedDefaultPersonas(args) {
|
|
|
45335
45386
|
args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
|
|
45336
45387
|
continue;
|
|
45337
45388
|
}
|
|
45338
|
-
const bundleDir =
|
|
45339
|
-
if (!
|
|
45389
|
+
const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
|
|
45390
|
+
if (!fs10.existsSync(bundleDir)) {
|
|
45340
45391
|
args.logger.warn("persona.seed.skip", {
|
|
45341
45392
|
personaId: entry.personaId,
|
|
45342
45393
|
reason: "bundle-missing",
|
|
@@ -45344,8 +45395,8 @@ function seedDefaultPersonas(args) {
|
|
|
45344
45395
|
});
|
|
45345
45396
|
continue;
|
|
45346
45397
|
}
|
|
45347
|
-
const claudeMdPath =
|
|
45348
|
-
if (!
|
|
45398
|
+
const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
|
|
45399
|
+
if (!fs10.existsSync(claudeMdPath)) {
|
|
45349
45400
|
args.logger.warn("persona.seed.skip", {
|
|
45350
45401
|
personaId: entry.personaId,
|
|
45351
45402
|
reason: "no-CLAUDE.md",
|
|
@@ -45353,7 +45404,7 @@ function seedDefaultPersonas(args) {
|
|
|
45353
45404
|
});
|
|
45354
45405
|
continue;
|
|
45355
45406
|
}
|
|
45356
|
-
const personality =
|
|
45407
|
+
const personality = fs10.readFileSync(claudeMdPath, "utf8");
|
|
45357
45408
|
const now = Date.now();
|
|
45358
45409
|
const persona = {
|
|
45359
45410
|
personaId: entry.personaId,
|
|
@@ -45379,17 +45430,17 @@ function seedDefaultPersonas(args) {
|
|
|
45379
45430
|
}
|
|
45380
45431
|
}
|
|
45381
45432
|
function skipNodeModulesUnder(srcRoot) {
|
|
45382
|
-
return (src) => !
|
|
45433
|
+
return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
|
|
45383
45434
|
}
|
|
45384
45435
|
function copyBundleExtras(srcDir, dstDir) {
|
|
45385
|
-
for (const entry of
|
|
45436
|
+
for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
|
|
45386
45437
|
if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
|
|
45387
|
-
const srcPath =
|
|
45388
|
-
const dstPath =
|
|
45438
|
+
const srcPath = path13.join(srcDir, entry.name);
|
|
45439
|
+
const dstPath = path13.join(dstDir, entry.name);
|
|
45389
45440
|
if (entry.isDirectory()) {
|
|
45390
|
-
|
|
45441
|
+
fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45391
45442
|
} else if (entry.isFile()) {
|
|
45392
|
-
|
|
45443
|
+
fs10.copyFileSync(srcPath, dstPath);
|
|
45393
45444
|
}
|
|
45394
45445
|
}
|
|
45395
45446
|
}
|
|
@@ -45397,16 +45448,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
|
|
|
45397
45448
|
function refreshDaemonManagedDirs(args) {
|
|
45398
45449
|
const entries = args.entries ?? DEFAULT_PERSONAS;
|
|
45399
45450
|
for (const entry of entries) {
|
|
45400
|
-
const bundleDir =
|
|
45401
|
-
if (!
|
|
45451
|
+
const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
|
|
45452
|
+
if (!fs10.existsSync(bundleDir)) continue;
|
|
45402
45453
|
const personaDir = args.store.personaDirPath(entry.personaId);
|
|
45403
|
-
if (!
|
|
45454
|
+
if (!fs10.existsSync(personaDir)) continue;
|
|
45404
45455
|
for (const relPath of DAEMON_MANAGED_PATHS) {
|
|
45405
|
-
const srcPath =
|
|
45406
|
-
if (!
|
|
45407
|
-
const dstPath =
|
|
45456
|
+
const srcPath = path13.join(bundleDir, relPath);
|
|
45457
|
+
if (!fs10.existsSync(srcPath)) continue;
|
|
45458
|
+
const dstPath = path13.join(personaDir, relPath);
|
|
45408
45459
|
try {
|
|
45409
|
-
|
|
45460
|
+
fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45410
45461
|
args.logger.info("persona.refresh.synced", {
|
|
45411
45462
|
personaId: entry.personaId,
|
|
45412
45463
|
path: relPath
|
|
@@ -45466,15 +45517,15 @@ function migrateCodexSandbox(args) {
|
|
|
45466
45517
|
function findDeployKitRoot(logger) {
|
|
45467
45518
|
const candidates = [];
|
|
45468
45519
|
try {
|
|
45469
|
-
const here =
|
|
45470
|
-
candidates.push(
|
|
45520
|
+
const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45521
|
+
candidates.push(path13.resolve(here, "..", "deploy-kit"));
|
|
45471
45522
|
} catch {
|
|
45472
45523
|
}
|
|
45473
45524
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
|
|
45474
45525
|
if (fromArgv) candidates.push(fromArgv);
|
|
45475
45526
|
for (const c of candidates) {
|
|
45476
45527
|
try {
|
|
45477
|
-
if (
|
|
45528
|
+
if (fs10.statSync(c).isDirectory()) {
|
|
45478
45529
|
logger?.info("persona.deploy-kit-root.resolved", { root: c });
|
|
45479
45530
|
return c;
|
|
45480
45531
|
}
|
|
@@ -45485,8 +45536,8 @@ function findDeployKitRoot(logger) {
|
|
|
45485
45536
|
return null;
|
|
45486
45537
|
}
|
|
45487
45538
|
function seedDeployKit(args) {
|
|
45488
|
-
const dst =
|
|
45489
|
-
|
|
45539
|
+
const dst = path13.join(args.dataDir, "deploy-kit");
|
|
45540
|
+
fs10.cpSync(args.deployKitBundleRoot, dst, {
|
|
45490
45541
|
recursive: true,
|
|
45491
45542
|
dereference: true,
|
|
45492
45543
|
force: false,
|
|
@@ -45495,35 +45546,35 @@ function seedDeployKit(args) {
|
|
|
45495
45546
|
args.logger.info("deploy-kit.seed.done", { dst });
|
|
45496
45547
|
}
|
|
45497
45548
|
function refreshDeployKit(args) {
|
|
45498
|
-
const dst =
|
|
45499
|
-
if (!
|
|
45549
|
+
const dst = path13.join(args.dataDir, "deploy-kit");
|
|
45550
|
+
if (!fs10.existsSync(dst)) {
|
|
45500
45551
|
seedDeployKit(args);
|
|
45501
45552
|
return;
|
|
45502
45553
|
}
|
|
45503
45554
|
for (const sub of ["scripts", "contract"]) {
|
|
45504
|
-
const s =
|
|
45505
|
-
if (
|
|
45506
|
-
|
|
45555
|
+
const s = path13.join(args.deployKitBundleRoot, sub);
|
|
45556
|
+
if (fs10.existsSync(s)) {
|
|
45557
|
+
fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
|
|
45507
45558
|
}
|
|
45508
45559
|
}
|
|
45509
|
-
const secretsSrc =
|
|
45510
|
-
if (
|
|
45511
|
-
|
|
45512
|
-
for (const f of
|
|
45560
|
+
const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
|
|
45561
|
+
if (fs10.existsSync(secretsSrc)) {
|
|
45562
|
+
fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
|
|
45563
|
+
for (const f of fs10.readdirSync(secretsSrc)) {
|
|
45513
45564
|
if (!f.endsWith(".example")) continue;
|
|
45514
|
-
|
|
45565
|
+
fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
|
|
45515
45566
|
}
|
|
45516
45567
|
}
|
|
45517
45568
|
args.logger.info("deploy-kit.refresh.done", { dst });
|
|
45518
45569
|
}
|
|
45519
45570
|
|
|
45520
45571
|
// src/share-md-viewer/load.ts
|
|
45521
|
-
var
|
|
45522
|
-
var
|
|
45572
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
45573
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
45523
45574
|
var import_node_url2 = require("url");
|
|
45524
45575
|
|
|
45525
45576
|
// src/share-md-viewer/asset-loader.ts
|
|
45526
|
-
var
|
|
45577
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
45527
45578
|
function htmlEscape(s) {
|
|
45528
45579
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
45529
45580
|
}
|
|
@@ -45531,12 +45582,12 @@ function createViewerAssetLoader(opts) {
|
|
|
45531
45582
|
let viewerTemplate;
|
|
45532
45583
|
let errorTemplate;
|
|
45533
45584
|
try {
|
|
45534
|
-
viewerTemplate =
|
|
45585
|
+
viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
|
|
45535
45586
|
} catch (err) {
|
|
45536
45587
|
throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
|
|
45537
45588
|
}
|
|
45538
45589
|
try {
|
|
45539
|
-
errorTemplate =
|
|
45590
|
+
errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
|
|
45540
45591
|
} catch (err) {
|
|
45541
45592
|
throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
|
|
45542
45593
|
}
|
|
@@ -45555,25 +45606,25 @@ var import_meta2 = {};
|
|
|
45555
45606
|
function tryLoadViewerAssets(logger) {
|
|
45556
45607
|
const candidates = [];
|
|
45557
45608
|
try {
|
|
45558
|
-
const here =
|
|
45609
|
+
const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
45559
45610
|
candidates.push(here);
|
|
45560
|
-
candidates.push(
|
|
45561
|
-
candidates.push(
|
|
45611
|
+
candidates.push(import_node_path10.default.resolve(here, ".."));
|
|
45612
|
+
candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
|
|
45562
45613
|
} catch {
|
|
45563
45614
|
}
|
|
45564
45615
|
if (process.argv[1]) {
|
|
45565
45616
|
let real = process.argv[1];
|
|
45566
45617
|
try {
|
|
45567
|
-
real =
|
|
45618
|
+
real = import_node_fs10.default.realpathSync(process.argv[1]);
|
|
45568
45619
|
} catch {
|
|
45569
45620
|
}
|
|
45570
|
-
candidates.push(
|
|
45621
|
+
candidates.push(import_node_path10.default.dirname(real));
|
|
45571
45622
|
}
|
|
45572
45623
|
for (const root of candidates) {
|
|
45573
|
-
const viewerHtmlPath =
|
|
45574
|
-
const errorHtmlPath =
|
|
45624
|
+
const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
|
|
45625
|
+
const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
|
|
45575
45626
|
try {
|
|
45576
|
-
if (
|
|
45627
|
+
if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
|
|
45577
45628
|
logger?.info("share-md-viewer.assets-root.resolved", { root });
|
|
45578
45629
|
return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
|
|
45579
45630
|
}
|
|
@@ -45588,30 +45639,30 @@ function tryLoadViewerAssets(logger) {
|
|
|
45588
45639
|
}
|
|
45589
45640
|
|
|
45590
45641
|
// src/share-ui/load.ts
|
|
45591
|
-
var
|
|
45592
|
-
var
|
|
45642
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
45643
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
45593
45644
|
var import_node_url3 = require("url");
|
|
45594
45645
|
|
|
45595
45646
|
// src/share-ui/asset-loader.ts
|
|
45596
|
-
var
|
|
45597
|
-
var
|
|
45647
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
45648
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
45598
45649
|
function createShareUiAssetLoader(opts) {
|
|
45599
45650
|
let indexHtml;
|
|
45600
45651
|
try {
|
|
45601
|
-
indexHtml =
|
|
45652
|
+
indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
|
|
45602
45653
|
} catch (err) {
|
|
45603
45654
|
throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
|
|
45604
45655
|
}
|
|
45605
|
-
const assetsDir =
|
|
45656
|
+
const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
|
|
45606
45657
|
return {
|
|
45607
45658
|
renderIndexHtml() {
|
|
45608
45659
|
return indexHtml;
|
|
45609
45660
|
},
|
|
45610
45661
|
resolveAssetPath(rel) {
|
|
45611
|
-
const resolved =
|
|
45612
|
-
if (resolved !== assetsDir && !resolved.startsWith(assetsDir +
|
|
45662
|
+
const resolved = import_node_path11.default.resolve(assetsDir, rel);
|
|
45663
|
+
if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
|
|
45613
45664
|
try {
|
|
45614
|
-
if (
|
|
45665
|
+
if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
|
|
45615
45666
|
} catch {
|
|
45616
45667
|
}
|
|
45617
45668
|
return null;
|
|
@@ -45625,28 +45676,28 @@ function bundleDirFromArgv(argv1) {
|
|
|
45625
45676
|
if (!argv1) return null;
|
|
45626
45677
|
let real = argv1;
|
|
45627
45678
|
try {
|
|
45628
|
-
real =
|
|
45679
|
+
real = import_node_fs12.default.realpathSync(argv1);
|
|
45629
45680
|
} catch {
|
|
45630
45681
|
}
|
|
45631
|
-
return
|
|
45682
|
+
return import_node_path12.default.dirname(real);
|
|
45632
45683
|
}
|
|
45633
45684
|
function tryLoadShareUi(logger) {
|
|
45634
45685
|
const candidates = [];
|
|
45635
45686
|
try {
|
|
45636
|
-
const here =
|
|
45687
|
+
const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
45637
45688
|
candidates.push(here);
|
|
45638
|
-
candidates.push(
|
|
45639
|
-
candidates.push(
|
|
45689
|
+
candidates.push(import_node_path12.default.resolve(here, ".."));
|
|
45690
|
+
candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
|
|
45640
45691
|
} catch {
|
|
45641
45692
|
}
|
|
45642
45693
|
const argvDir = bundleDirFromArgv(process.argv[1]);
|
|
45643
45694
|
if (argvDir) candidates.push(argvDir);
|
|
45644
45695
|
for (const root of candidates) {
|
|
45645
|
-
const shareUiDir =
|
|
45646
|
-
const indexHtmlPath =
|
|
45647
|
-
const assetsDir =
|
|
45696
|
+
const shareUiDir = import_node_path12.default.join(root, "share-ui");
|
|
45697
|
+
const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
|
|
45698
|
+
const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
|
|
45648
45699
|
try {
|
|
45649
|
-
if (
|
|
45700
|
+
if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
|
|
45650
45701
|
logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
|
|
45651
45702
|
return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
|
|
45652
45703
|
}
|
|
@@ -45728,20 +45779,20 @@ function buildVisitorLogin(deps) {
|
|
|
45728
45779
|
}
|
|
45729
45780
|
|
|
45730
45781
|
// src/visitor/visitor-store.ts
|
|
45731
|
-
var
|
|
45732
|
-
var
|
|
45782
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
45783
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
45733
45784
|
function createVisitorStore(opts) {
|
|
45734
|
-
const file =
|
|
45785
|
+
const file = import_node_path13.default.join(opts.dir, "visitors.json");
|
|
45735
45786
|
const read = () => {
|
|
45736
45787
|
try {
|
|
45737
|
-
return JSON.parse(
|
|
45788
|
+
return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
|
|
45738
45789
|
} catch {
|
|
45739
45790
|
return [];
|
|
45740
45791
|
}
|
|
45741
45792
|
};
|
|
45742
45793
|
const write = (rows) => {
|
|
45743
|
-
|
|
45744
|
-
|
|
45794
|
+
import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
|
|
45795
|
+
import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
|
|
45745
45796
|
};
|
|
45746
45797
|
return {
|
|
45747
45798
|
upsert(r) {
|
|
@@ -46023,8 +46074,8 @@ function turnStartInput(text) {
|
|
|
46023
46074
|
const items = [];
|
|
46024
46075
|
let leftover = text;
|
|
46025
46076
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
46026
|
-
const [marker, name,
|
|
46027
|
-
items.push({ type: "skill", name, path:
|
|
46077
|
+
const [marker, name, path67] = m2;
|
|
46078
|
+
items.push({ type: "skill", name, path: path67 });
|
|
46028
46079
|
leftover = leftover.replace(marker, "");
|
|
46029
46080
|
}
|
|
46030
46081
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -46257,8 +46308,8 @@ var CodexAdapter = class {
|
|
|
46257
46308
|
|
|
46258
46309
|
// src/tools/claude-tui.ts
|
|
46259
46310
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
46260
|
-
var
|
|
46261
|
-
var
|
|
46311
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
46312
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
46262
46313
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
46263
46314
|
|
|
46264
46315
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -47391,8 +47442,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
47391
47442
|
}
|
|
47392
47443
|
function jsonlExistsForCtx(ctx) {
|
|
47393
47444
|
if (!ctx.toolSessionId) return false;
|
|
47394
|
-
const home =
|
|
47395
|
-
const file =
|
|
47445
|
+
const home = import_node_os7.default.homedir();
|
|
47446
|
+
const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
47396
47447
|
try {
|
|
47397
47448
|
return import_node_fs16.default.statSync(file).isFile();
|
|
47398
47449
|
} catch {
|
|
@@ -47464,9 +47515,9 @@ var PersonaDispatchManager = class {
|
|
|
47464
47515
|
|
|
47465
47516
|
// src/dispatch/mcp-config.ts
|
|
47466
47517
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
47467
|
-
var
|
|
47518
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
47468
47519
|
function dispatchMcpConfigPath(dataDir) {
|
|
47469
|
-
return
|
|
47520
|
+
return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
|
|
47470
47521
|
}
|
|
47471
47522
|
function writeDispatchMcpConfig(args) {
|
|
47472
47523
|
const cfgPath = dispatchMcpConfigPath(args.dataDir);
|
|
@@ -47488,9 +47539,9 @@ function writeDispatchMcpConfig(args) {
|
|
|
47488
47539
|
|
|
47489
47540
|
// src/ticket/mcp-config.ts
|
|
47490
47541
|
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
47491
|
-
var
|
|
47542
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
47492
47543
|
function ticketMcpConfigPath(dataDir) {
|
|
47493
|
-
return
|
|
47544
|
+
return import_node_path16.default.join(dataDir, "ticket.mcp.json");
|
|
47494
47545
|
}
|
|
47495
47546
|
function writeTicketMcpConfig(args) {
|
|
47496
47547
|
const cfgPath = ticketMcpConfigPath(args.dataDir);
|
|
@@ -47518,9 +47569,9 @@ function writeTicketMcpConfig(args) {
|
|
|
47518
47569
|
|
|
47519
47570
|
// src/shift/mcp-config.ts
|
|
47520
47571
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
47521
|
-
var
|
|
47572
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
47522
47573
|
function shiftMcpConfigPath(dataDir) {
|
|
47523
|
-
return
|
|
47574
|
+
return import_node_path17.default.join(dataDir, "shift.mcp.json");
|
|
47524
47575
|
}
|
|
47525
47576
|
async function writeShiftMcpConfig(args) {
|
|
47526
47577
|
const cfgPath = shiftMcpConfigPath(args.dataDir);
|
|
@@ -47542,7 +47593,7 @@ async function writeShiftMcpConfig(args) {
|
|
|
47542
47593
|
|
|
47543
47594
|
// src/shift/store.ts
|
|
47544
47595
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
47545
|
-
var
|
|
47596
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
47546
47597
|
var import_node_crypto5 = require("crypto");
|
|
47547
47598
|
|
|
47548
47599
|
// src/shift/constants.ts
|
|
@@ -47611,7 +47662,7 @@ function createShiftStore(deps) {
|
|
|
47611
47662
|
flushTimer = null;
|
|
47612
47663
|
}
|
|
47613
47664
|
const content = { version: 1, shifts };
|
|
47614
|
-
await import_promises.default.mkdir(
|
|
47665
|
+
await import_promises.default.mkdir(import_node_path18.default.dirname(deps.filePath), { recursive: true });
|
|
47615
47666
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
47616
47667
|
await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
47617
47668
|
await import_promises.default.rename(tmp, deps.filePath);
|
|
@@ -48382,13 +48433,13 @@ function mapSkillsListResponse(res) {
|
|
|
48382
48433
|
const r = s ?? {};
|
|
48383
48434
|
const name = str3(r.name);
|
|
48384
48435
|
if (!name) continue;
|
|
48385
|
-
const
|
|
48436
|
+
const path67 = str3(r.path);
|
|
48386
48437
|
const description = str3(r.description);
|
|
48387
48438
|
const isPlugin = name.includes(":");
|
|
48388
48439
|
out.push({
|
|
48389
48440
|
name,
|
|
48390
48441
|
source: isPlugin ? "plugin" : "project",
|
|
48391
|
-
...
|
|
48442
|
+
...path67 ? { path: path67 } : {},
|
|
48392
48443
|
...description ? { description } : {},
|
|
48393
48444
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
48394
48445
|
});
|
|
@@ -48428,15 +48479,15 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
48428
48479
|
|
|
48429
48480
|
// src/workspace/browser.ts
|
|
48430
48481
|
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
48431
|
-
var
|
|
48432
|
-
var
|
|
48482
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
48483
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
48433
48484
|
init_protocol();
|
|
48434
48485
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
48435
48486
|
function resolveInsideCwd(cwd, subpath) {
|
|
48436
|
-
const absCwd =
|
|
48437
|
-
const joined =
|
|
48438
|
-
const rel =
|
|
48439
|
-
if (rel.startsWith("..") ||
|
|
48487
|
+
const absCwd = import_node_path19.default.resolve(cwd);
|
|
48488
|
+
const joined = import_node_path19.default.resolve(absCwd, subpath ?? ".");
|
|
48489
|
+
const rel = import_node_path19.default.relative(absCwd, joined);
|
|
48490
|
+
if (rel.startsWith("..") || import_node_path19.default.isAbsolute(rel)) {
|
|
48440
48491
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
48441
48492
|
}
|
|
48442
48493
|
return joined;
|
|
@@ -48454,7 +48505,7 @@ function ensureCwd(cwd) {
|
|
|
48454
48505
|
}
|
|
48455
48506
|
var WorkspaceBrowser = class {
|
|
48456
48507
|
list(args) {
|
|
48457
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
48508
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
|
|
48458
48509
|
ensureCwd(cwd);
|
|
48459
48510
|
const full = resolveInsideCwd(cwd, args.path);
|
|
48460
48511
|
const dirents = import_node_fs20.default.readdirSync(full, { withFileTypes: true });
|
|
@@ -48467,7 +48518,7 @@ var WorkspaceBrowser = class {
|
|
|
48467
48518
|
mtime: ""
|
|
48468
48519
|
};
|
|
48469
48520
|
try {
|
|
48470
|
-
const st = import_node_fs20.default.statSync(
|
|
48521
|
+
const st = import_node_fs20.default.statSync(import_node_path19.default.join(full, d.name));
|
|
48471
48522
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
48472
48523
|
if (d.isFile()) entry.size = st.size;
|
|
48473
48524
|
} catch {
|
|
@@ -48513,8 +48564,8 @@ var WorkspaceBrowser = class {
|
|
|
48513
48564
|
|
|
48514
48565
|
// src/skills/agents-scanner.ts
|
|
48515
48566
|
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
48516
|
-
var
|
|
48517
|
-
var
|
|
48567
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
48568
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
48518
48569
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
48519
48570
|
function isDirLikeSync2(p2) {
|
|
48520
48571
|
try {
|
|
@@ -48552,10 +48603,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
48552
48603
|
}
|
|
48553
48604
|
for (const ent of entries) {
|
|
48554
48605
|
if (!ent.name.endsWith(".md")) continue;
|
|
48555
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
48606
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path20.default.join(dir, ent.name)))) {
|
|
48556
48607
|
continue;
|
|
48557
48608
|
}
|
|
48558
|
-
const filePath =
|
|
48609
|
+
const filePath = import_node_path20.default.join(dir, ent.name);
|
|
48559
48610
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
48560
48611
|
if (seen.has(baseName)) continue;
|
|
48561
48612
|
seen.add(baseName);
|
|
@@ -48578,7 +48629,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48578
48629
|
return;
|
|
48579
48630
|
}
|
|
48580
48631
|
for (const ent of entries) {
|
|
48581
|
-
const childPath =
|
|
48632
|
+
const childPath = import_node_path20.default.join(dir, ent.name);
|
|
48582
48633
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
48583
48634
|
walk2(childPath, [...namespaces, ent.name]);
|
|
48584
48635
|
continue;
|
|
@@ -48603,9 +48654,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48603
48654
|
walk2(root, []);
|
|
48604
48655
|
}
|
|
48605
48656
|
function readInstalledPlugins2(home) {
|
|
48606
|
-
const pluginsDir =
|
|
48607
|
-
const v2 =
|
|
48608
|
-
const v1 =
|
|
48657
|
+
const pluginsDir = import_node_path20.default.join(home, ".claude", "plugins");
|
|
48658
|
+
const v2 = import_node_path20.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
48659
|
+
const v1 = import_node_path20.default.join(pluginsDir, "installed_plugins.json");
|
|
48609
48660
|
let raw = null;
|
|
48610
48661
|
for (const candidate of [v2, v1]) {
|
|
48611
48662
|
try {
|
|
@@ -48634,19 +48685,19 @@ function readInstalledPlugins2(home) {
|
|
|
48634
48685
|
return out;
|
|
48635
48686
|
}
|
|
48636
48687
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
48637
|
-
let cur =
|
|
48638
|
-
const fsRoot =
|
|
48688
|
+
let cur = import_node_path20.default.resolve(startCwd);
|
|
48689
|
+
const fsRoot = import_node_path20.default.parse(cur).root;
|
|
48639
48690
|
while (true) {
|
|
48640
|
-
scanAgentsDir(
|
|
48691
|
+
scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
48641
48692
|
let hasGit = false;
|
|
48642
48693
|
try {
|
|
48643
|
-
hasGit = import_node_fs21.default.existsSync(
|
|
48694
|
+
hasGit = import_node_fs21.default.existsSync(import_node_path20.default.join(cur, ".git"));
|
|
48644
48695
|
} catch {
|
|
48645
48696
|
}
|
|
48646
48697
|
if (hasGit) return;
|
|
48647
48698
|
if (cur === home) return;
|
|
48648
48699
|
if (cur === fsRoot) return;
|
|
48649
|
-
const parent =
|
|
48700
|
+
const parent = import_node_path20.default.dirname(cur);
|
|
48650
48701
|
if (parent === cur) return;
|
|
48651
48702
|
cur = parent;
|
|
48652
48703
|
}
|
|
@@ -48656,7 +48707,7 @@ var AgentsScanner = class {
|
|
|
48656
48707
|
extraPluginRoots;
|
|
48657
48708
|
policyDir;
|
|
48658
48709
|
constructor(opts = {}) {
|
|
48659
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
48710
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
|
|
48660
48711
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
48661
48712
|
if (opts.policyDir !== void 0) {
|
|
48662
48713
|
this.policyDir = opts.policyDir;
|
|
@@ -48681,7 +48732,7 @@ var AgentsScanner = class {
|
|
|
48681
48732
|
}
|
|
48682
48733
|
const fsBlock = [];
|
|
48683
48734
|
scanAgentsDir(
|
|
48684
|
-
|
|
48735
|
+
import_node_path20.default.join(this.home, ".claude", "agents"),
|
|
48685
48736
|
"global",
|
|
48686
48737
|
seen,
|
|
48687
48738
|
fsBlock
|
|
@@ -48695,7 +48746,7 @@ var AgentsScanner = class {
|
|
|
48695
48746
|
...this.extraPluginRoots
|
|
48696
48747
|
];
|
|
48697
48748
|
for (const { name, root } of plugins) {
|
|
48698
|
-
const agentsRoot =
|
|
48749
|
+
const agentsRoot = import_node_path20.default.join(root, "agents");
|
|
48699
48750
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
48700
48751
|
}
|
|
48701
48752
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -48704,27 +48755,27 @@ var AgentsScanner = class {
|
|
|
48704
48755
|
|
|
48705
48756
|
// src/observer/session-observer.ts
|
|
48706
48757
|
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
48707
|
-
var
|
|
48708
|
-
var
|
|
48758
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
48759
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
48709
48760
|
init_claude_history();
|
|
48710
48761
|
|
|
48711
48762
|
// src/observer/subagent-meta-observer.ts
|
|
48712
48763
|
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
48713
|
-
var
|
|
48714
|
-
var
|
|
48764
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
48765
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
48715
48766
|
init_claude_history();
|
|
48716
48767
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
48717
48768
|
var SubagentMetaObserver = class {
|
|
48718
48769
|
constructor(opts) {
|
|
48719
48770
|
this.opts = opts;
|
|
48720
|
-
this.home = opts.home ??
|
|
48771
|
+
this.home = opts.home ?? import_node_os10.default.homedir();
|
|
48721
48772
|
}
|
|
48722
48773
|
opts;
|
|
48723
48774
|
home;
|
|
48724
48775
|
watches = /* @__PURE__ */ new Map();
|
|
48725
48776
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
48726
48777
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
48727
|
-
return
|
|
48778
|
+
return import_node_path21.default.join(
|
|
48728
48779
|
this.home,
|
|
48729
48780
|
".claude",
|
|
48730
48781
|
"projects",
|
|
@@ -48780,7 +48831,7 @@ var SubagentMetaObserver = class {
|
|
|
48780
48831
|
if (!m2) return;
|
|
48781
48832
|
const agentId = m2[1];
|
|
48782
48833
|
if (w2.emitted.has(agentId)) return;
|
|
48783
|
-
const file =
|
|
48834
|
+
const file = import_node_path21.default.join(w2.dirPath, name);
|
|
48784
48835
|
let raw;
|
|
48785
48836
|
try {
|
|
48786
48837
|
raw = import_node_fs22.default.readFileSync(file, "utf8");
|
|
@@ -48828,7 +48879,7 @@ var SubagentMetaObserver = class {
|
|
|
48828
48879
|
var SessionObserver = class {
|
|
48829
48880
|
constructor(opts) {
|
|
48830
48881
|
this.opts = opts;
|
|
48831
|
-
this.home = opts.home ??
|
|
48882
|
+
this.home = opts.home ?? import_node_os11.default.homedir();
|
|
48832
48883
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
48833
48884
|
}
|
|
48834
48885
|
opts;
|
|
@@ -48840,7 +48891,7 @@ var SessionObserver = class {
|
|
|
48840
48891
|
metaObserver;
|
|
48841
48892
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
48842
48893
|
if (override) return override;
|
|
48843
|
-
return
|
|
48894
|
+
return import_node_path22.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
48844
48895
|
}
|
|
48845
48896
|
start(args) {
|
|
48846
48897
|
this.stop(args.sessionId);
|
|
@@ -48861,10 +48912,10 @@ var SessionObserver = class {
|
|
|
48861
48912
|
prevIsRejectSentinel: false
|
|
48862
48913
|
};
|
|
48863
48914
|
try {
|
|
48864
|
-
import_node_fs23.default.mkdirSync(
|
|
48915
|
+
import_node_fs23.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
|
|
48865
48916
|
} catch {
|
|
48866
48917
|
}
|
|
48867
|
-
w2.watcher = import_node_fs23.default.watch(
|
|
48918
|
+
w2.watcher = import_node_fs23.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
48868
48919
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
48869
48920
|
this.poll(w2);
|
|
48870
48921
|
});
|
|
@@ -49744,7 +49795,7 @@ async function authenticate(token, deps) {
|
|
|
49744
49795
|
|
|
49745
49796
|
// src/permission/capability-store.ts
|
|
49746
49797
|
var fs27 = __toESM(require("fs"), 1);
|
|
49747
|
-
var
|
|
49798
|
+
var path27 = __toESM(require("path"), 1);
|
|
49748
49799
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
49749
49800
|
var FILE_VERSION = 1;
|
|
49750
49801
|
var CapabilityStore = class {
|
|
@@ -49774,7 +49825,7 @@ var CapabilityStore = class {
|
|
|
49774
49825
|
this.flush();
|
|
49775
49826
|
}
|
|
49776
49827
|
filePath() {
|
|
49777
|
-
return
|
|
49828
|
+
return path27.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
49778
49829
|
}
|
|
49779
49830
|
readFromDisk() {
|
|
49780
49831
|
const file = this.filePath();
|
|
@@ -49921,7 +49972,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
49921
49972
|
|
|
49922
49973
|
// src/inbox/inbox-store.ts
|
|
49923
49974
|
var fs29 = __toESM(require("fs"), 1);
|
|
49924
|
-
var
|
|
49975
|
+
var path28 = __toESM(require("path"), 1);
|
|
49925
49976
|
var INBOX_SUBDIR = "inbox";
|
|
49926
49977
|
var InboxStore = class {
|
|
49927
49978
|
constructor(dataDir) {
|
|
@@ -50019,10 +50070,10 @@ var InboxStore = class {
|
|
|
50019
50070
|
}
|
|
50020
50071
|
}
|
|
50021
50072
|
dirPath() {
|
|
50022
|
-
return
|
|
50073
|
+
return path28.join(this.dataDir, INBOX_SUBDIR);
|
|
50023
50074
|
}
|
|
50024
50075
|
filePath(peerDeviceId) {
|
|
50025
|
-
return
|
|
50076
|
+
return path28.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
50026
50077
|
}
|
|
50027
50078
|
};
|
|
50028
50079
|
function parseAllLines(raw) {
|
|
@@ -50110,7 +50161,7 @@ var InboxManager = class {
|
|
|
50110
50161
|
|
|
50111
50162
|
// src/state/contact-store.ts
|
|
50112
50163
|
var fs30 = __toESM(require("fs"), 1);
|
|
50113
|
-
var
|
|
50164
|
+
var path29 = __toESM(require("path"), 1);
|
|
50114
50165
|
var FILE_NAME = "contacts.json";
|
|
50115
50166
|
var ContactStore = class {
|
|
50116
50167
|
constructor(dataDir) {
|
|
@@ -50120,7 +50171,7 @@ var ContactStore = class {
|
|
|
50120
50171
|
contacts = /* @__PURE__ */ new Map();
|
|
50121
50172
|
load() {
|
|
50122
50173
|
this.contacts.clear();
|
|
50123
|
-
const file =
|
|
50174
|
+
const file = path29.join(this.dataDir, FILE_NAME);
|
|
50124
50175
|
let raw;
|
|
50125
50176
|
try {
|
|
50126
50177
|
raw = fs30.readFileSync(file, "utf8");
|
|
@@ -50166,7 +50217,7 @@ var ContactStore = class {
|
|
|
50166
50217
|
return existed;
|
|
50167
50218
|
}
|
|
50168
50219
|
flush() {
|
|
50169
|
-
const file =
|
|
50220
|
+
const file = path29.join(this.dataDir, FILE_NAME);
|
|
50170
50221
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
50171
50222
|
const content = JSON.stringify(
|
|
50172
50223
|
{ contacts: Array.from(this.contacts.values()) },
|
|
@@ -50330,52 +50381,52 @@ async function autoReverseContact(args) {
|
|
|
50330
50381
|
|
|
50331
50382
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
50332
50383
|
var fs31 = __toESM(require("fs"), 1);
|
|
50333
|
-
var
|
|
50384
|
+
var path30 = __toESM(require("path"), 1);
|
|
50334
50385
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
50335
50386
|
function migrateFlattenSessions(opts) {
|
|
50336
50387
|
const dataDir = opts.dataDir;
|
|
50337
50388
|
const now = opts.now ?? Date.now;
|
|
50338
|
-
const sessionsDir =
|
|
50339
|
-
const flagPath =
|
|
50389
|
+
const sessionsDir = path30.join(dataDir, "sessions");
|
|
50390
|
+
const flagPath = path30.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
50340
50391
|
if (existsSync3(flagPath)) {
|
|
50341
50392
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
50342
50393
|
}
|
|
50343
50394
|
let movedBare = 0;
|
|
50344
50395
|
let movedVmOwner = 0;
|
|
50345
50396
|
let archivedListener = 0;
|
|
50346
|
-
const defaultDir =
|
|
50397
|
+
const defaultDir = path30.join(sessionsDir, "default");
|
|
50347
50398
|
if (existsSync3(defaultDir)) {
|
|
50348
50399
|
for (const entry of readdirSafe(defaultDir)) {
|
|
50349
50400
|
if (!entry.endsWith(".json")) continue;
|
|
50350
|
-
const src =
|
|
50351
|
-
const dst =
|
|
50401
|
+
const src = path30.join(defaultDir, entry);
|
|
50402
|
+
const dst = path30.join(sessionsDir, entry);
|
|
50352
50403
|
fs31.renameSync(src, dst);
|
|
50353
50404
|
movedBare += 1;
|
|
50354
50405
|
}
|
|
50355
50406
|
rmdirIfEmpty(defaultDir);
|
|
50356
50407
|
}
|
|
50357
50408
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
50358
|
-
const personaDir =
|
|
50409
|
+
const personaDir = path30.join(sessionsDir, pid);
|
|
50359
50410
|
if (!isDir(personaDir)) continue;
|
|
50360
50411
|
if (pid === "default") continue;
|
|
50361
|
-
const ownerSrc =
|
|
50412
|
+
const ownerSrc = path30.join(personaDir, "owner");
|
|
50362
50413
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
50363
|
-
const ownerDst =
|
|
50414
|
+
const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
50364
50415
|
fs31.mkdirSync(ownerDst, { recursive: true });
|
|
50365
50416
|
for (const file of readdirSafe(ownerSrc)) {
|
|
50366
50417
|
if (!file.endsWith(".json")) continue;
|
|
50367
|
-
fs31.renameSync(
|
|
50418
|
+
fs31.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
|
|
50368
50419
|
movedVmOwner += 1;
|
|
50369
50420
|
}
|
|
50370
50421
|
rmdirIfEmpty(ownerSrc);
|
|
50371
50422
|
}
|
|
50372
|
-
const listenerSrc =
|
|
50423
|
+
const listenerSrc = path30.join(personaDir, "listener");
|
|
50373
50424
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
50374
|
-
const archiveDst =
|
|
50425
|
+
const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
|
|
50375
50426
|
fs31.mkdirSync(archiveDst, { recursive: true });
|
|
50376
50427
|
for (const file of readdirSafe(listenerSrc)) {
|
|
50377
50428
|
if (!file.endsWith(".json")) continue;
|
|
50378
|
-
fs31.renameSync(
|
|
50429
|
+
fs31.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
|
|
50379
50430
|
archivedListener += 1;
|
|
50380
50431
|
}
|
|
50381
50432
|
rmdirIfEmpty(listenerSrc);
|
|
@@ -50423,10 +50474,10 @@ function rmdirIfEmpty(p2) {
|
|
|
50423
50474
|
|
|
50424
50475
|
// src/transport/http-router.ts
|
|
50425
50476
|
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
50426
|
-
var
|
|
50477
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
50427
50478
|
|
|
50428
50479
|
// src/attachment/mime.ts
|
|
50429
|
-
var
|
|
50480
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
50430
50481
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
50431
50482
|
var EXT_TO_NATIVE_MIME = {
|
|
50432
50483
|
// 图片
|
|
@@ -50533,7 +50584,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
50533
50584
|
".mk"
|
|
50534
50585
|
]);
|
|
50535
50586
|
function lookupMime(filePathOrName) {
|
|
50536
|
-
const ext =
|
|
50587
|
+
const ext = import_node_path23.default.extname(filePathOrName).toLowerCase();
|
|
50537
50588
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
50538
50589
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
50539
50590
|
return "application/octet-stream";
|
|
@@ -50603,7 +50654,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
50603
50654
|
|
|
50604
50655
|
// src/attachment/upload.ts
|
|
50605
50656
|
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
50606
|
-
var
|
|
50657
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
50607
50658
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
50608
50659
|
var import_promises2 = require("stream/promises");
|
|
50609
50660
|
var UploadError = class extends Error {
|
|
@@ -50615,14 +50666,14 @@ var UploadError = class extends Error {
|
|
|
50615
50666
|
code;
|
|
50616
50667
|
};
|
|
50617
50668
|
function assertValidFileName(fileName) {
|
|
50618
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
50669
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path24.default.basename(fileName)) {
|
|
50619
50670
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
50620
50671
|
}
|
|
50621
50672
|
}
|
|
50622
50673
|
var HASH_PREFIX_LEN = 16;
|
|
50623
50674
|
async function writeUploadedAttachment(args) {
|
|
50624
50675
|
assertValidFileName(args.fileName);
|
|
50625
|
-
const attachmentsRoot =
|
|
50676
|
+
const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
|
|
50626
50677
|
try {
|
|
50627
50678
|
import_node_fs24.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
50628
50679
|
} catch (err) {
|
|
@@ -50630,7 +50681,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50630
50681
|
}
|
|
50631
50682
|
const hasher = import_node_crypto7.default.createHash("sha256");
|
|
50632
50683
|
let actualSize = 0;
|
|
50633
|
-
const tmpPath =
|
|
50684
|
+
const tmpPath = import_node_path24.default.join(
|
|
50634
50685
|
attachmentsRoot,
|
|
50635
50686
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto7.default.randomBytes(4).toString("hex")}`
|
|
50636
50687
|
);
|
|
@@ -50665,7 +50716,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50665
50716
|
);
|
|
50666
50717
|
}
|
|
50667
50718
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
50668
|
-
const hashDir =
|
|
50719
|
+
const hashDir = import_node_path24.default.join(attachmentsRoot, attachmentId);
|
|
50669
50720
|
let finalFileName;
|
|
50670
50721
|
let hashDirExists = false;
|
|
50671
50722
|
try {
|
|
@@ -50683,7 +50734,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50683
50734
|
try {
|
|
50684
50735
|
import_node_fs24.default.mkdirSync(hashDir, { recursive: true });
|
|
50685
50736
|
finalFileName = args.fileName;
|
|
50686
|
-
import_node_fs24.default.renameSync(tmpPath,
|
|
50737
|
+
import_node_fs24.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
|
|
50687
50738
|
} catch (err) {
|
|
50688
50739
|
try {
|
|
50689
50740
|
import_node_fs24.default.unlinkSync(tmpPath);
|
|
@@ -50692,8 +50743,8 @@ async function writeUploadedAttachment(args) {
|
|
|
50692
50743
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
50693
50744
|
}
|
|
50694
50745
|
}
|
|
50695
|
-
const absPath =
|
|
50696
|
-
const relPath =
|
|
50746
|
+
const absPath = import_node_path24.default.join(hashDir, finalFileName);
|
|
50747
|
+
const relPath = import_node_path24.default.relative(args.sessionDir, absPath);
|
|
50697
50748
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
50698
50749
|
relPath: absPath,
|
|
50699
50750
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -50707,8 +50758,8 @@ async function writeUploadedAttachment(args) {
|
|
|
50707
50758
|
|
|
50708
50759
|
// src/extension/import.ts
|
|
50709
50760
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
50710
|
-
var
|
|
50711
|
-
var
|
|
50761
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
50762
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
50712
50763
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
50713
50764
|
var ImportError = class extends Error {
|
|
50714
50765
|
constructor(code, message) {
|
|
@@ -50725,7 +50776,7 @@ async function importZip(buf, root) {
|
|
|
50725
50776
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
50726
50777
|
}
|
|
50727
50778
|
for (const name of Object.keys(zip.files)) {
|
|
50728
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
50779
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path25.default.isAbsolute(name)) {
|
|
50729
50780
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
50730
50781
|
}
|
|
50731
50782
|
}
|
|
@@ -50758,7 +50809,7 @@ async function importZip(buf, root) {
|
|
|
50758
50809
|
);
|
|
50759
50810
|
}
|
|
50760
50811
|
}
|
|
50761
|
-
const destDir =
|
|
50812
|
+
const destDir = import_node_path25.default.join(root, manifest.id);
|
|
50762
50813
|
let destExists = false;
|
|
50763
50814
|
try {
|
|
50764
50815
|
await import_promises3.default.access(destDir);
|
|
@@ -50768,15 +50819,15 @@ async function importZip(buf, root) {
|
|
|
50768
50819
|
if (destExists) {
|
|
50769
50820
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
50770
50821
|
}
|
|
50771
|
-
const stage = await import_promises3.default.mkdtemp(
|
|
50822
|
+
const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
50772
50823
|
try {
|
|
50773
50824
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
50774
|
-
const dest =
|
|
50825
|
+
const dest = import_node_path25.default.join(stage, name);
|
|
50775
50826
|
if (entry.dir) {
|
|
50776
50827
|
await import_promises3.default.mkdir(dest, { recursive: true });
|
|
50777
50828
|
continue;
|
|
50778
50829
|
}
|
|
50779
|
-
await import_promises3.default.mkdir(
|
|
50830
|
+
await import_promises3.default.mkdir(import_node_path25.default.dirname(dest), { recursive: true });
|
|
50780
50831
|
const content = await entry.async("nodebuffer");
|
|
50781
50832
|
await import_promises3.default.writeFile(dest, content);
|
|
50782
50833
|
}
|
|
@@ -50807,7 +50858,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
50807
50858
|
".wasm": "application/wasm"
|
|
50808
50859
|
};
|
|
50809
50860
|
function shareUiAssetMime(filePath) {
|
|
50810
|
-
const ext =
|
|
50861
|
+
const ext = import_node_path26.default.extname(filePath).toLowerCase();
|
|
50811
50862
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
50812
50863
|
}
|
|
50813
50864
|
var DISPATCH_HEARTBEAT_MS = 25e3;
|
|
@@ -50894,7 +50945,7 @@ function isValidUploadFileName(fileName) {
|
|
|
50894
50945
|
if (fileName === "." || fileName === "..") return false;
|
|
50895
50946
|
if (fileName.startsWith(".")) return false;
|
|
50896
50947
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
50897
|
-
return fileName ===
|
|
50948
|
+
return fileName === import_node_path26.default.basename(fileName);
|
|
50898
50949
|
}
|
|
50899
50950
|
function createHttpRouter(deps) {
|
|
50900
50951
|
return async (req, res) => {
|
|
@@ -51190,7 +51241,7 @@ function createHttpRouter(deps) {
|
|
|
51190
51241
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
51191
51242
|
return true;
|
|
51192
51243
|
}
|
|
51193
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
51244
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path26.default.basename(r.absPath)));
|
|
51194
51245
|
return true;
|
|
51195
51246
|
}
|
|
51196
51247
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -51311,7 +51362,7 @@ function createHttpRouter(deps) {
|
|
|
51311
51362
|
return true;
|
|
51312
51363
|
}
|
|
51313
51364
|
let absPath;
|
|
51314
|
-
if (
|
|
51365
|
+
if (import_node_path26.default.isAbsolute(pathParam)) {
|
|
51315
51366
|
absPath = pathParam;
|
|
51316
51367
|
} else if (deps.sessionStore) {
|
|
51317
51368
|
const file = deps.sessionStore.read(sid);
|
|
@@ -51319,7 +51370,7 @@ function createHttpRouter(deps) {
|
|
|
51319
51370
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
51320
51371
|
return true;
|
|
51321
51372
|
}
|
|
51322
|
-
absPath =
|
|
51373
|
+
absPath = import_node_path26.default.join(file.cwd, pathParam);
|
|
51323
51374
|
} else {
|
|
51324
51375
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
51325
51376
|
return true;
|
|
@@ -51421,7 +51472,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51421
51472
|
return;
|
|
51422
51473
|
}
|
|
51423
51474
|
const mime = lookupMime(absPath);
|
|
51424
|
-
const basename =
|
|
51475
|
+
const basename = import_node_path26.default.basename(absPath);
|
|
51425
51476
|
res.writeHead(200, {
|
|
51426
51477
|
"Content-Type": mime,
|
|
51427
51478
|
"Content-Length": String(stat.size),
|
|
@@ -51439,7 +51490,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51439
51490
|
|
|
51440
51491
|
// src/attachment/gc.ts
|
|
51441
51492
|
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
51442
|
-
var
|
|
51493
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
51443
51494
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
51444
51495
|
function runAttachmentGc(args) {
|
|
51445
51496
|
const now = (args.now ?? Date.now)();
|
|
@@ -51448,17 +51499,17 @@ function runAttachmentGc(args) {
|
|
|
51448
51499
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
51449
51500
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
51450
51501
|
if (entry.stale) continue;
|
|
51451
|
-
if (
|
|
51502
|
+
if (import_node_path27.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
51452
51503
|
}
|
|
51453
51504
|
}
|
|
51454
51505
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
51455
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
51506
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path27.default.join(
|
|
51456
51507
|
args.dataDir,
|
|
51457
51508
|
"sessions",
|
|
51458
51509
|
...scopeSubPath(scope).map(safeFileName),
|
|
51459
51510
|
safeFileName(sessionId)
|
|
51460
51511
|
);
|
|
51461
|
-
const attRoot =
|
|
51512
|
+
const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
|
|
51462
51513
|
let hashDirs;
|
|
51463
51514
|
try {
|
|
51464
51515
|
hashDirs = import_node_fs26.default.readdirSync(attRoot);
|
|
@@ -51468,7 +51519,7 @@ function runAttachmentGc(args) {
|
|
|
51468
51519
|
continue;
|
|
51469
51520
|
}
|
|
51470
51521
|
for (const hashDir of hashDirs) {
|
|
51471
|
-
const hashDirAbs =
|
|
51522
|
+
const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
|
|
51472
51523
|
let files;
|
|
51473
51524
|
try {
|
|
51474
51525
|
files = import_node_fs26.default.readdirSync(hashDirAbs);
|
|
@@ -51476,7 +51527,7 @@ function runAttachmentGc(args) {
|
|
|
51476
51527
|
continue;
|
|
51477
51528
|
}
|
|
51478
51529
|
for (const name of files) {
|
|
51479
|
-
const file =
|
|
51530
|
+
const file = import_node_path27.default.join(hashDirAbs, name);
|
|
51480
51531
|
let stat;
|
|
51481
51532
|
try {
|
|
51482
51533
|
stat = import_node_fs26.default.statSync(file);
|
|
@@ -51507,7 +51558,7 @@ function runAttachmentGc(args) {
|
|
|
51507
51558
|
|
|
51508
51559
|
// src/attachment/group.ts
|
|
51509
51560
|
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
51510
|
-
var
|
|
51561
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
51511
51562
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
51512
51563
|
init_protocol();
|
|
51513
51564
|
var GroupFileStore = class {
|
|
@@ -51519,11 +51570,11 @@ var GroupFileStore = class {
|
|
|
51519
51570
|
this.logger = opts.logger;
|
|
51520
51571
|
}
|
|
51521
51572
|
rootForScope(scope) {
|
|
51522
|
-
return
|
|
51573
|
+
return import_node_path28.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
51523
51574
|
}
|
|
51524
51575
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
51525
51576
|
filePath(scope, sessionId) {
|
|
51526
|
-
return
|
|
51577
|
+
return import_node_path28.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
51527
51578
|
}
|
|
51528
51579
|
cacheKey(scope, sessionId) {
|
|
51529
51580
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -51558,7 +51609,7 @@ var GroupFileStore = class {
|
|
|
51558
51609
|
}
|
|
51559
51610
|
writeFile(scope, sessionId, entries) {
|
|
51560
51611
|
const file = this.filePath(scope, sessionId);
|
|
51561
|
-
import_node_fs27.default.mkdirSync(
|
|
51612
|
+
import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
|
|
51562
51613
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
51563
51614
|
import_node_fs27.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
51564
51615
|
import_node_fs27.default.renameSync(tmp, file);
|
|
@@ -51648,9 +51699,9 @@ var GroupFileStore = class {
|
|
|
51648
51699
|
|
|
51649
51700
|
// src/discovery/state-file.ts
|
|
51650
51701
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
51651
|
-
var
|
|
51702
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
51652
51703
|
function defaultStateFilePath(dataDir) {
|
|
51653
|
-
return
|
|
51704
|
+
return import_node_path29.default.join(dataDir, "state.json");
|
|
51654
51705
|
}
|
|
51655
51706
|
function isPidAlive(pid) {
|
|
51656
51707
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -51686,7 +51737,7 @@ var StateFileManager = class {
|
|
|
51686
51737
|
return { status: "stale", existing };
|
|
51687
51738
|
}
|
|
51688
51739
|
write(state) {
|
|
51689
|
-
import_node_fs28.default.mkdirSync(
|
|
51740
|
+
import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
|
|
51690
51741
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
51691
51742
|
import_node_fs28.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
51692
51743
|
import_node_fs28.default.renameSync(tmp, this.file);
|
|
@@ -51715,13 +51766,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
51715
51766
|
|
|
51716
51767
|
// src/tunnel/tunnel-manager.ts
|
|
51717
51768
|
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
51718
|
-
var
|
|
51769
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
51719
51770
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
51720
51771
|
var import_node_child_process9 = require("child_process");
|
|
51721
51772
|
|
|
51722
51773
|
// src/tunnel/tunnel-store.ts
|
|
51723
51774
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
51724
|
-
var
|
|
51775
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
51725
51776
|
var TunnelStore = class {
|
|
51726
51777
|
constructor(filePath) {
|
|
51727
51778
|
this.filePath = filePath;
|
|
@@ -51740,7 +51791,7 @@ var TunnelStore = class {
|
|
|
51740
51791
|
}
|
|
51741
51792
|
}
|
|
51742
51793
|
async set(v2) {
|
|
51743
|
-
const dir =
|
|
51794
|
+
const dir = import_node_path30.default.dirname(this.filePath);
|
|
51744
51795
|
await import_node_fs29.default.promises.mkdir(dir, { recursive: true });
|
|
51745
51796
|
const data = JSON.stringify(v2, null, 2);
|
|
51746
51797
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -51851,8 +51902,8 @@ function escape(v2) {
|
|
|
51851
51902
|
|
|
51852
51903
|
// src/tunnel/frpc-binary.ts
|
|
51853
51904
|
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
51854
|
-
var
|
|
51855
|
-
var
|
|
51905
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
51906
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
51856
51907
|
var import_node_child_process7 = require("child_process");
|
|
51857
51908
|
var import_node_stream3 = require("stream");
|
|
51858
51909
|
var import_promises4 = require("stream/promises");
|
|
@@ -51891,13 +51942,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
51891
51942
|
}
|
|
51892
51943
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
51893
51944
|
const platform = opts.platform ?? detectPlatform();
|
|
51894
|
-
const binDir =
|
|
51945
|
+
const binDir = import_node_path31.default.join(opts.dataDir, "bin");
|
|
51895
51946
|
import_node_fs30.default.mkdirSync(binDir, { recursive: true });
|
|
51896
51947
|
cleanupStaleArtifacts(binDir);
|
|
51897
|
-
const stableBin =
|
|
51948
|
+
const stableBin = import_node_path31.default.join(binDir, "frpc");
|
|
51898
51949
|
if (import_node_fs30.default.existsSync(stableBin)) return stableBin;
|
|
51899
51950
|
const partialBin = `${stableBin}.partial`;
|
|
51900
|
-
const tarballPath =
|
|
51951
|
+
const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
51901
51952
|
try {
|
|
51902
51953
|
const url = frpcDownloadUrl(version2, platform);
|
|
51903
51954
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -51923,7 +51974,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
51923
51974
|
}
|
|
51924
51975
|
for (const name of entries) {
|
|
51925
51976
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
51926
|
-
const full =
|
|
51977
|
+
const full = import_node_path31.default.join(binDir, name);
|
|
51927
51978
|
try {
|
|
51928
51979
|
import_node_fs30.default.rmSync(full, { recursive: true, force: true });
|
|
51929
51980
|
} catch {
|
|
@@ -51949,7 +52000,7 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
51949
52000
|
await (0, import_promises4.pipeline)(nodeStream, out);
|
|
51950
52001
|
}
|
|
51951
52002
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
51952
|
-
const work =
|
|
52003
|
+
const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
51953
52004
|
import_node_fs30.default.mkdirSync(work, { recursive: true });
|
|
51954
52005
|
try {
|
|
51955
52006
|
await new Promise((resolve6, reject) => {
|
|
@@ -51958,7 +52009,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
51958
52009
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
51959
52010
|
});
|
|
51960
52011
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
51961
|
-
const src =
|
|
52012
|
+
const src = import_node_path31.default.join(work, dirName, "frpc");
|
|
51962
52013
|
if (!import_node_fs30.default.existsSync(src)) {
|
|
51963
52014
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
51964
52015
|
}
|
|
@@ -51970,10 +52021,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
51970
52021
|
|
|
51971
52022
|
// src/tunnel/frpc-process.ts
|
|
51972
52023
|
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
51973
|
-
var
|
|
52024
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
51974
52025
|
var import_node_child_process8 = require("child_process");
|
|
51975
52026
|
function frpcPidFilePath(dataDir) {
|
|
51976
|
-
return
|
|
52027
|
+
return import_node_path32.default.join(dataDir, "frpc.pid");
|
|
51977
52028
|
}
|
|
51978
52029
|
function writeFrpcPid(dataDir, pid) {
|
|
51979
52030
|
try {
|
|
@@ -52015,7 +52066,7 @@ function defaultSleep(ms) {
|
|
|
52015
52066
|
}
|
|
52016
52067
|
async function killStaleFrpc(deps) {
|
|
52017
52068
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
52018
|
-
const tomlPath =
|
|
52069
|
+
const tomlPath = import_node_path32.default.join(deps.dataDir, "frpc.toml");
|
|
52019
52070
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
52020
52071
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
52021
52072
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -52087,7 +52138,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
52087
52138
|
var TunnelManager = class {
|
|
52088
52139
|
constructor(deps) {
|
|
52089
52140
|
this.deps = deps;
|
|
52090
|
-
this.store = deps.store ?? new TunnelStore(
|
|
52141
|
+
this.store = deps.store ?? new TunnelStore(import_node_path33.default.join(deps.dataDir, "tunnel.json"));
|
|
52091
52142
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
52092
52143
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
52093
52144
|
}
|
|
@@ -52214,7 +52265,7 @@ var TunnelManager = class {
|
|
|
52214
52265
|
dataDir: this.deps.dataDir,
|
|
52215
52266
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
52216
52267
|
});
|
|
52217
|
-
const tomlPath =
|
|
52268
|
+
const tomlPath = import_node_path33.default.join(this.deps.dataDir, "frpc.toml");
|
|
52218
52269
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto9.default.randomBytes(3).toString("hex")}`;
|
|
52219
52270
|
const toml = buildFrpcToml({
|
|
52220
52271
|
serverAddr: t.frpsHost,
|
|
@@ -52229,7 +52280,7 @@ var TunnelManager = class {
|
|
|
52229
52280
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
52230
52281
|
stdio: ["ignore", "pipe", "pipe"]
|
|
52231
52282
|
});
|
|
52232
|
-
const logFilePath =
|
|
52283
|
+
const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
|
|
52233
52284
|
const logStream = import_node_fs32.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
52234
52285
|
logStream.on("error", () => {
|
|
52235
52286
|
});
|
|
@@ -52312,16 +52363,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52312
52363
|
}
|
|
52313
52364
|
|
|
52314
52365
|
// src/tunnel/device-key.ts
|
|
52315
|
-
var
|
|
52316
|
-
var
|
|
52366
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
52367
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
52317
52368
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
52318
52369
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
52319
52370
|
function deriveStableDeviceKey(opts = {}) {
|
|
52320
|
-
const hostname = opts.hostname ??
|
|
52321
|
-
const uid = opts.uid ?? (typeof
|
|
52322
|
-
const home = opts.home ??
|
|
52323
|
-
const defaultDataDir =
|
|
52324
|
-
const normalizedDataDir = opts.dataDir ?
|
|
52371
|
+
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
52372
|
+
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
52373
|
+
const home = opts.home ?? import_node_os14.default.homedir();
|
|
52374
|
+
const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
|
|
52375
|
+
const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
|
|
52325
52376
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
52326
52377
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
52327
52378
|
return import_node_crypto10.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
@@ -52329,11 +52380,11 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
52329
52380
|
|
|
52330
52381
|
// src/auth-store.ts
|
|
52331
52382
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
52332
|
-
var
|
|
52383
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
52333
52384
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
52334
52385
|
var AUTH_FILE_NAME = "auth.json";
|
|
52335
52386
|
function authFilePath(dataDir) {
|
|
52336
|
-
return
|
|
52387
|
+
return import_node_path35.default.join(dataDir, AUTH_FILE_NAME);
|
|
52337
52388
|
}
|
|
52338
52389
|
function loadOrCreateAuthFile(opts) {
|
|
52339
52390
|
const file = authFilePath(opts.dataDir);
|
|
@@ -52389,7 +52440,7 @@ function readAuthFile(file) {
|
|
|
52389
52440
|
}
|
|
52390
52441
|
}
|
|
52391
52442
|
function writeAuthFile(file, content) {
|
|
52392
|
-
import_node_fs33.default.mkdirSync(
|
|
52443
|
+
import_node_fs33.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
|
|
52393
52444
|
import_node_fs33.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
52394
52445
|
try {
|
|
52395
52446
|
import_node_fs33.default.chmodSync(file, 384);
|
|
@@ -52399,12 +52450,12 @@ function writeAuthFile(file, content) {
|
|
|
52399
52450
|
|
|
52400
52451
|
// src/owner-profile.ts
|
|
52401
52452
|
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
52402
|
-
var
|
|
52403
|
-
var
|
|
52453
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
52454
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
52404
52455
|
var PROFILE_FILENAME = "profile.json";
|
|
52405
52456
|
function loadOwnerDisplayName(dataDir) {
|
|
52406
|
-
const fallback =
|
|
52407
|
-
const profilePath =
|
|
52457
|
+
const fallback = import_node_os15.default.userInfo().username;
|
|
52458
|
+
const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
|
|
52408
52459
|
let raw;
|
|
52409
52460
|
try {
|
|
52410
52461
|
raw = import_node_fs34.default.readFileSync(profilePath, "utf8");
|
|
@@ -52431,12 +52482,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
52431
52482
|
|
|
52432
52483
|
// src/feishu-auth/owner-identity-store.ts
|
|
52433
52484
|
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
52434
|
-
var
|
|
52485
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
52435
52486
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
52436
52487
|
var OwnerIdentityStore = class {
|
|
52437
52488
|
file;
|
|
52438
52489
|
constructor(dataDir) {
|
|
52439
|
-
this.file =
|
|
52490
|
+
this.file = import_node_path37.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
52440
52491
|
}
|
|
52441
52492
|
read() {
|
|
52442
52493
|
let raw;
|
|
@@ -52469,7 +52520,7 @@ var OwnerIdentityStore = class {
|
|
|
52469
52520
|
};
|
|
52470
52521
|
}
|
|
52471
52522
|
write(record) {
|
|
52472
|
-
import_node_fs35.default.mkdirSync(
|
|
52523
|
+
import_node_fs35.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
|
|
52473
52524
|
import_node_fs35.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
52474
52525
|
try {
|
|
52475
52526
|
import_node_fs35.default.chmodSync(this.file, 384);
|
|
@@ -52599,9 +52650,9 @@ var CentralClientError = class extends Error {
|
|
|
52599
52650
|
code;
|
|
52600
52651
|
cause;
|
|
52601
52652
|
};
|
|
52602
|
-
async function centralRequest(opts,
|
|
52653
|
+
async function centralRequest(opts, path67, init) {
|
|
52603
52654
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
52604
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52655
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path67}`;
|
|
52605
52656
|
const ctrl = new AbortController();
|
|
52606
52657
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
52607
52658
|
let res;
|
|
@@ -52744,7 +52795,7 @@ function verifyConnectToken(args) {
|
|
|
52744
52795
|
|
|
52745
52796
|
// src/feishu-auth/server-key.ts
|
|
52746
52797
|
var fs45 = __toESM(require("fs"), 1);
|
|
52747
|
-
var
|
|
52798
|
+
var path46 = __toESM(require("path"), 1);
|
|
52748
52799
|
var FILE_NAME2 = "server-signing-key.json";
|
|
52749
52800
|
var ServerKeyStore = class {
|
|
52750
52801
|
constructor(dataDir) {
|
|
@@ -52752,7 +52803,7 @@ var ServerKeyStore = class {
|
|
|
52752
52803
|
}
|
|
52753
52804
|
dataDir;
|
|
52754
52805
|
filePath() {
|
|
52755
|
-
return
|
|
52806
|
+
return path46.join(this.dataDir, FILE_NAME2);
|
|
52756
52807
|
}
|
|
52757
52808
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
52758
52809
|
read() {
|
|
@@ -52791,8 +52842,8 @@ init_protocol();
|
|
|
52791
52842
|
|
|
52792
52843
|
// src/session/fork.ts
|
|
52793
52844
|
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
52794
|
-
var
|
|
52795
|
-
var
|
|
52845
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
52846
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
52796
52847
|
init_claude_history();
|
|
52797
52848
|
function readJsonlEntries(file) {
|
|
52798
52849
|
const raw = import_node_fs36.default.readFileSync(file, "utf8");
|
|
@@ -52808,9 +52859,9 @@ function readJsonlEntries(file) {
|
|
|
52808
52859
|
return out;
|
|
52809
52860
|
}
|
|
52810
52861
|
function forkSession(input) {
|
|
52811
|
-
const baseDir = input.baseDir ??
|
|
52812
|
-
const projectDir =
|
|
52813
|
-
const sourceFile =
|
|
52862
|
+
const baseDir = input.baseDir ?? import_node_path38.default.join(import_node_os16.default.homedir(), ".claude");
|
|
52863
|
+
const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
52864
|
+
const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
52814
52865
|
if (!import_node_fs36.default.existsSync(sourceFile)) {
|
|
52815
52866
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
52816
52867
|
}
|
|
@@ -52841,7 +52892,7 @@ function forkSession(input) {
|
|
|
52841
52892
|
}
|
|
52842
52893
|
forkedLines.push(JSON.stringify(forked));
|
|
52843
52894
|
}
|
|
52844
|
-
const forkedFilePath =
|
|
52895
|
+
const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
52845
52896
|
import_node_fs36.default.mkdirSync(projectDir, { recursive: true });
|
|
52846
52897
|
import_node_fs36.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
52847
52898
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -53195,7 +53246,7 @@ function buildPermissionHandlers(deps) {
|
|
|
53195
53246
|
}
|
|
53196
53247
|
|
|
53197
53248
|
// src/handlers/history.ts
|
|
53198
|
-
var
|
|
53249
|
+
var path49 = __toESM(require("path"), 1);
|
|
53199
53250
|
init_protocol();
|
|
53200
53251
|
|
|
53201
53252
|
// src/session/recent-dirs.ts
|
|
@@ -53213,7 +53264,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
53213
53264
|
}
|
|
53214
53265
|
|
|
53215
53266
|
// src/permission/persona-paths.ts
|
|
53216
|
-
var
|
|
53267
|
+
var path48 = __toESM(require("path"), 1);
|
|
53217
53268
|
function getAllowedPersonaIds(grants, action) {
|
|
53218
53269
|
const ids = /* @__PURE__ */ new Set();
|
|
53219
53270
|
for (const g2 of grants) {
|
|
@@ -53226,42 +53277,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
53226
53277
|
return ids;
|
|
53227
53278
|
}
|
|
53228
53279
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
53229
|
-
const target =
|
|
53280
|
+
const target = path48.resolve(absPath);
|
|
53230
53281
|
if (userWorkDir) {
|
|
53231
|
-
const u =
|
|
53232
|
-
const usep = u.endsWith(
|
|
53282
|
+
const u = path48.resolve(userWorkDir);
|
|
53283
|
+
const usep = u.endsWith(path48.sep) ? "" : path48.sep;
|
|
53233
53284
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
53234
53285
|
}
|
|
53235
|
-
const root =
|
|
53236
|
-
const sep3 = root.endsWith(
|
|
53286
|
+
const root = path48.resolve(personaRoot);
|
|
53287
|
+
const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
|
|
53237
53288
|
if (!target.startsWith(root + sep3)) return false;
|
|
53238
|
-
const rel =
|
|
53289
|
+
const rel = path48.relative(root, target);
|
|
53239
53290
|
if (!rel || rel.startsWith("..")) return false;
|
|
53240
|
-
const personaId = rel.split(
|
|
53291
|
+
const personaId = rel.split(path48.sep)[0];
|
|
53241
53292
|
if (!personaId) return false;
|
|
53242
53293
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
53243
53294
|
if (allowed === "*") return true;
|
|
53244
53295
|
return allowed.has(personaId);
|
|
53245
53296
|
}
|
|
53246
53297
|
function personaIdFromPath(absPath, personaRoot) {
|
|
53247
|
-
const root =
|
|
53248
|
-
const target =
|
|
53249
|
-
const sep3 = root.endsWith(
|
|
53298
|
+
const root = path48.resolve(personaRoot);
|
|
53299
|
+
const target = path48.resolve(absPath);
|
|
53300
|
+
const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
|
|
53250
53301
|
if (!target.startsWith(root + sep3)) return null;
|
|
53251
|
-
const rel =
|
|
53302
|
+
const rel = path48.relative(root, target);
|
|
53252
53303
|
if (!rel || rel.startsWith("..")) return null;
|
|
53253
|
-
const id = rel.split(
|
|
53304
|
+
const id = rel.split(path48.sep)[0];
|
|
53254
53305
|
return id || null;
|
|
53255
53306
|
}
|
|
53256
53307
|
function isPathWithin(dir, absPath) {
|
|
53257
|
-
const d =
|
|
53258
|
-
const t =
|
|
53259
|
-
const sep3 = d.endsWith(
|
|
53308
|
+
const d = path48.resolve(dir);
|
|
53309
|
+
const t = path48.resolve(absPath);
|
|
53310
|
+
const sep3 = d.endsWith(path48.sep) ? "" : path48.sep;
|
|
53260
53311
|
return t === d || t.startsWith(d + sep3);
|
|
53261
53312
|
}
|
|
53262
53313
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
53263
53314
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
53264
|
-
return personaIdFromPath(
|
|
53315
|
+
return personaIdFromPath(path48.resolve(absPath), personaRoot) === personaId;
|
|
53265
53316
|
}
|
|
53266
53317
|
|
|
53267
53318
|
// src/handlers/history.ts
|
|
@@ -53287,7 +53338,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53287
53338
|
if (!pid) return false;
|
|
53288
53339
|
return isGuestPathAllowed(
|
|
53289
53340
|
ctx.grants,
|
|
53290
|
-
|
|
53341
|
+
path49.join(personaRoot, pid),
|
|
53291
53342
|
personaRoot,
|
|
53292
53343
|
"read",
|
|
53293
53344
|
userWorkDir
|
|
@@ -53299,7 +53350,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53299
53350
|
};
|
|
53300
53351
|
const list = async (frame, _client, ctx) => {
|
|
53301
53352
|
const args = HistoryListArgs.parse(frame);
|
|
53302
|
-
assertGuestPath(ctx,
|
|
53353
|
+
assertGuestPath(ctx, path49.resolve(args.projectPath), personaRoot, "history:list");
|
|
53303
53354
|
const sessions = await history.listSessions(args);
|
|
53304
53355
|
return { response: { type: "history:list", sessions } };
|
|
53305
53356
|
};
|
|
@@ -53331,13 +53382,13 @@ function buildHistoryHandlers(deps) {
|
|
|
53331
53382
|
};
|
|
53332
53383
|
const subagents = async (frame, _client, ctx) => {
|
|
53333
53384
|
const args = HistorySubagentsArgs.parse(frame);
|
|
53334
|
-
assertGuestPath(ctx,
|
|
53385
|
+
assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
53335
53386
|
const subs = await history.listSubagents(args);
|
|
53336
53387
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
53337
53388
|
};
|
|
53338
53389
|
const subagentRead = async (frame, _client, ctx) => {
|
|
53339
53390
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
53340
|
-
assertGuestPath(ctx,
|
|
53391
|
+
assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
53341
53392
|
const res = await history.readSubagent(args);
|
|
53342
53393
|
return { response: { type: "history:subagent-read", ...res } };
|
|
53343
53394
|
};
|
|
@@ -53346,7 +53397,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53346
53397
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
53347
53398
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
53348
53399
|
const filtered = dirs.filter(
|
|
53349
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
53400
|
+
(d) => isGuestPathAllowed(ctx.grants, path49.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
53350
53401
|
);
|
|
53351
53402
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
53352
53403
|
}
|
|
@@ -53363,8 +53414,8 @@ function buildHistoryHandlers(deps) {
|
|
|
53363
53414
|
}
|
|
53364
53415
|
|
|
53365
53416
|
// src/handlers/workspace.ts
|
|
53366
|
-
var
|
|
53367
|
-
var
|
|
53417
|
+
var path50 = __toESM(require("path"), 1);
|
|
53418
|
+
var os16 = __toESM(require("os"), 1);
|
|
53368
53419
|
init_protocol();
|
|
53369
53420
|
init_protocol();
|
|
53370
53421
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -53404,23 +53455,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53404
53455
|
const list = async (frame, _client, ctx) => {
|
|
53405
53456
|
const args = WorkspaceListArgs.parse(frame);
|
|
53406
53457
|
const isGuest = ctx?.principal.kind === "guest";
|
|
53407
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
53408
|
-
const resolvedCwd =
|
|
53409
|
-
const target = args.path ?
|
|
53458
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
53459
|
+
const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
|
|
53460
|
+
const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
53410
53461
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
53411
53462
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
53412
53463
|
return { response: { type: "workspace:list", ...res } };
|
|
53413
53464
|
};
|
|
53414
53465
|
const read = async (frame, _client, ctx) => {
|
|
53415
53466
|
const args = WorkspaceReadArgs.parse(frame);
|
|
53416
|
-
const target =
|
|
53467
|
+
const target = path50.isAbsolute(args.path) ? path50.resolve(args.path) : path50.resolve(args.cwd, args.path);
|
|
53417
53468
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
53418
53469
|
const res = workspace.read(args);
|
|
53419
53470
|
return { response: { type: "workspace:read", ...res } };
|
|
53420
53471
|
};
|
|
53421
53472
|
const skillsList = async (frame, _client, ctx) => {
|
|
53422
53473
|
const args = SkillsListArgs.parse(frame);
|
|
53423
|
-
const cwdAbs =
|
|
53474
|
+
const cwdAbs = path50.resolve(args.cwd);
|
|
53424
53475
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
53425
53476
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
53426
53477
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -53432,7 +53483,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53432
53483
|
};
|
|
53433
53484
|
const agentsList = async (frame, _client, ctx) => {
|
|
53434
53485
|
const args = AgentsListArgs.parse(frame);
|
|
53435
|
-
const cwdAbs =
|
|
53486
|
+
const cwdAbs = path50.resolve(args.cwd);
|
|
53436
53487
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
53437
53488
|
if (args.tool === "codex") {
|
|
53438
53489
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -53454,18 +53505,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53454
53505
|
}
|
|
53455
53506
|
|
|
53456
53507
|
// src/handlers/git.ts
|
|
53457
|
-
var
|
|
53508
|
+
var path52 = __toESM(require("path"), 1);
|
|
53458
53509
|
init_protocol();
|
|
53459
53510
|
init_protocol();
|
|
53460
53511
|
|
|
53461
53512
|
// src/workspace/git.ts
|
|
53462
53513
|
var import_node_child_process10 = require("child_process");
|
|
53463
53514
|
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
53464
|
-
var
|
|
53515
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
53465
53516
|
var import_node_util = require("util");
|
|
53466
53517
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
53467
53518
|
function normalizePath(p2) {
|
|
53468
|
-
const resolved =
|
|
53519
|
+
const resolved = import_node_path39.default.resolve(p2);
|
|
53469
53520
|
try {
|
|
53470
53521
|
return import_node_fs37.default.realpathSync(resolved);
|
|
53471
53522
|
} catch {
|
|
@@ -53541,7 +53592,7 @@ async function listGitBranches(cwd) {
|
|
|
53541
53592
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
53542
53593
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
53543
53594
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
53544
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
53595
|
+
if (!isGuestPathAllowed(ctx.grants, path52.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
53545
53596
|
throw new ClawdError(
|
|
53546
53597
|
ERROR_CODES.UNAUTHORIZED,
|
|
53547
53598
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -53930,7 +53981,7 @@ function buildDeviceHandlers(deps) {
|
|
|
53930
53981
|
}
|
|
53931
53982
|
|
|
53932
53983
|
// src/handlers/meta.ts
|
|
53933
|
-
var
|
|
53984
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
53934
53985
|
init_protocol();
|
|
53935
53986
|
|
|
53936
53987
|
// src/version.ts
|
|
@@ -53962,7 +54013,7 @@ function buildReadyFrame(deps, client) {
|
|
|
53962
54013
|
return {
|
|
53963
54014
|
version,
|
|
53964
54015
|
protocolVersion: PROTOCOL_VERSION,
|
|
53965
|
-
hostname:
|
|
54016
|
+
hostname: import_node_os17.default.hostname(),
|
|
53966
54017
|
os: process.platform,
|
|
53967
54018
|
tools,
|
|
53968
54019
|
runningSessions: info.runningSessions,
|
|
@@ -54059,7 +54110,7 @@ function buildPersonaHandlers(deps) {
|
|
|
54059
54110
|
}
|
|
54060
54111
|
|
|
54061
54112
|
// src/handlers/attachment.ts
|
|
54062
|
-
var
|
|
54113
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
54063
54114
|
init_protocol();
|
|
54064
54115
|
init_protocol();
|
|
54065
54116
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -54139,12 +54190,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
54139
54190
|
`session ${args.sessionId} scope unresolved`
|
|
54140
54191
|
);
|
|
54141
54192
|
}
|
|
54142
|
-
const cwdAbs =
|
|
54143
|
-
const candidateAbs =
|
|
54193
|
+
const cwdAbs = import_node_path40.default.resolve(sessionFile.cwd);
|
|
54194
|
+
const candidateAbs = import_node_path40.default.isAbsolute(args.relPath) ? import_node_path40.default.resolve(args.relPath) : import_node_path40.default.resolve(cwdAbs, args.relPath);
|
|
54144
54195
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
54145
54196
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
54146
54197
|
const entry = entries.find((e) => {
|
|
54147
|
-
const storedAbs =
|
|
54198
|
+
const storedAbs = import_node_path40.default.isAbsolute(e.relPath) ? import_node_path40.default.resolve(e.relPath) : import_node_path40.default.resolve(cwdAbs, e.relPath);
|
|
54148
54199
|
return storedAbs === candidateAbs && !e.stale;
|
|
54149
54200
|
});
|
|
54150
54201
|
if (!entry) {
|
|
@@ -54169,7 +54220,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
54169
54220
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
54170
54221
|
const f = deps.sessionStore.read(sessionId);
|
|
54171
54222
|
if (!f) return;
|
|
54172
|
-
assertGuestAttachmentPath(ctx,
|
|
54223
|
+
assertGuestAttachmentPath(ctx, import_node_path40.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
54173
54224
|
}
|
|
54174
54225
|
const groupAdd = async (frame, _client, ctx) => {
|
|
54175
54226
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -54184,8 +54235,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
54184
54235
|
if (!scope) {
|
|
54185
54236
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
54186
54237
|
}
|
|
54187
|
-
const cwdAbs =
|
|
54188
|
-
const candidateAbs =
|
|
54238
|
+
const cwdAbs = import_node_path40.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
54239
|
+
const candidateAbs = import_node_path40.default.isAbsolute(args.relPath) ? import_node_path40.default.resolve(args.relPath) : import_node_path40.default.resolve(cwdAbs, args.relPath);
|
|
54189
54240
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
54190
54241
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
54191
54242
|
const size = 0;
|
|
@@ -54244,19 +54295,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
54244
54295
|
|
|
54245
54296
|
// src/handlers/extension.ts
|
|
54246
54297
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
54247
|
-
var
|
|
54298
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
54248
54299
|
init_protocol();
|
|
54249
54300
|
|
|
54250
54301
|
// src/extension/bundle-zip.ts
|
|
54251
54302
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
54252
|
-
var
|
|
54303
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
54253
54304
|
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
54254
54305
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
54255
54306
|
async function bundleExtensionDir(dir) {
|
|
54256
54307
|
const entries = await listFilesSorted(dir);
|
|
54257
54308
|
const zip = new import_jszip2.default();
|
|
54258
54309
|
for (const rel of entries) {
|
|
54259
|
-
const abs =
|
|
54310
|
+
const abs = import_node_path41.default.join(dir, rel);
|
|
54260
54311
|
const content = await import_promises5.default.readFile(abs);
|
|
54261
54312
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
54262
54313
|
}
|
|
@@ -54277,7 +54328,7 @@ async function listFilesSorted(rootDir) {
|
|
|
54277
54328
|
return out;
|
|
54278
54329
|
}
|
|
54279
54330
|
async function walk(absRoot, relPrefix, out) {
|
|
54280
|
-
const dirAbs =
|
|
54331
|
+
const dirAbs = import_node_path41.default.join(absRoot, relPrefix);
|
|
54281
54332
|
const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
|
|
54282
54333
|
for (const e of entries) {
|
|
54283
54334
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -54331,25 +54382,25 @@ function computePublishCheck(args) {
|
|
|
54331
54382
|
|
|
54332
54383
|
// src/extension/install-flow.ts
|
|
54333
54384
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
54334
|
-
var
|
|
54335
|
-
var
|
|
54385
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
54386
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
54336
54387
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
54337
54388
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
54338
54389
|
|
|
54339
54390
|
// src/extension/paths.ts
|
|
54340
|
-
var
|
|
54341
|
-
var
|
|
54391
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
54392
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
54342
54393
|
function clawdHomeRoot(override) {
|
|
54343
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
54394
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
54344
54395
|
}
|
|
54345
54396
|
function extensionsRoot(override) {
|
|
54346
|
-
return
|
|
54397
|
+
return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
|
|
54347
54398
|
}
|
|
54348
54399
|
function publishedChannelsFile(override) {
|
|
54349
|
-
return
|
|
54400
|
+
return import_node_path42.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
54350
54401
|
}
|
|
54351
54402
|
function bundleCacheRoot(override) {
|
|
54352
|
-
return
|
|
54403
|
+
return import_node_path42.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
54353
54404
|
}
|
|
54354
54405
|
|
|
54355
54406
|
// src/extension/install-flow.ts
|
|
@@ -54376,7 +54427,7 @@ async function installFromChannel(args, deps) {
|
|
|
54376
54427
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54377
54428
|
}
|
|
54378
54429
|
for (const name of Object.keys(zip.files)) {
|
|
54379
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
54430
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
|
|
54380
54431
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
54381
54432
|
}
|
|
54382
54433
|
}
|
|
@@ -54408,7 +54459,7 @@ async function installFromChannel(args, deps) {
|
|
|
54408
54459
|
);
|
|
54409
54460
|
}
|
|
54410
54461
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
54411
|
-
const destDir =
|
|
54462
|
+
const destDir = import_node_path43.default.join(deps.extensionsRoot, localExtId);
|
|
54412
54463
|
let destExists = false;
|
|
54413
54464
|
try {
|
|
54414
54465
|
await import_promises6.default.access(destDir);
|
|
@@ -54422,16 +54473,16 @@ async function installFromChannel(args, deps) {
|
|
|
54422
54473
|
);
|
|
54423
54474
|
}
|
|
54424
54475
|
const stage = await import_promises6.default.mkdtemp(
|
|
54425
|
-
|
|
54476
|
+
import_node_path43.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
54426
54477
|
);
|
|
54427
54478
|
try {
|
|
54428
54479
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
54429
|
-
const dest =
|
|
54480
|
+
const dest = import_node_path43.default.join(stage, name);
|
|
54430
54481
|
if (entry.dir) {
|
|
54431
54482
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
54432
54483
|
continue;
|
|
54433
54484
|
}
|
|
54434
|
-
await import_promises6.default.mkdir(
|
|
54485
|
+
await import_promises6.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
|
|
54435
54486
|
if (name === "manifest.json") {
|
|
54436
54487
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
54437
54488
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -54452,8 +54503,8 @@ async function installFromChannel(args, deps) {
|
|
|
54452
54503
|
|
|
54453
54504
|
// src/extension/update-flow.ts
|
|
54454
54505
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
54455
|
-
var
|
|
54456
|
-
var
|
|
54506
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
54507
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
54457
54508
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
54458
54509
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
54459
54510
|
var UpdateError = class extends Error {
|
|
@@ -54469,11 +54520,11 @@ async function updateFromChannel(args, deps) {
|
|
|
54469
54520
|
channelRef.extId,
|
|
54470
54521
|
channelRef.ownerPrincipalId
|
|
54471
54522
|
);
|
|
54472
|
-
const liveDir =
|
|
54523
|
+
const liveDir = import_node_path44.default.join(deps.extensionsRoot, localExtId);
|
|
54473
54524
|
const prevDir = `${liveDir}.prev`;
|
|
54474
54525
|
let existingVersion;
|
|
54475
54526
|
try {
|
|
54476
|
-
const raw = await import_promises7.default.readFile(
|
|
54527
|
+
const raw = await import_promises7.default.readFile(import_node_path44.default.join(liveDir, "manifest.json"), "utf8");
|
|
54477
54528
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
54478
54529
|
if (!parsed2.success) {
|
|
54479
54530
|
throw new UpdateError(
|
|
@@ -54506,7 +54557,7 @@ async function updateFromChannel(args, deps) {
|
|
|
54506
54557
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54507
54558
|
}
|
|
54508
54559
|
for (const name of Object.keys(zip.files)) {
|
|
54509
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
54560
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
|
|
54510
54561
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
54511
54562
|
}
|
|
54512
54563
|
}
|
|
@@ -54541,16 +54592,16 @@ async function updateFromChannel(args, deps) {
|
|
|
54541
54592
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
54542
54593
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
54543
54594
|
const stage = await import_promises7.default.mkdtemp(
|
|
54544
|
-
|
|
54595
|
+
import_node_path44.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
54545
54596
|
);
|
|
54546
54597
|
try {
|
|
54547
54598
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
54548
|
-
const dest =
|
|
54599
|
+
const dest = import_node_path44.default.join(stage, name);
|
|
54549
54600
|
if (entry.dir) {
|
|
54550
54601
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
54551
54602
|
continue;
|
|
54552
54603
|
}
|
|
54553
|
-
await import_promises7.default.mkdir(
|
|
54604
|
+
await import_promises7.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
|
|
54554
54605
|
if (name === "manifest.json") {
|
|
54555
54606
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
54556
54607
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -54643,7 +54694,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
54643
54694
|
);
|
|
54644
54695
|
}
|
|
54645
54696
|
}
|
|
54646
|
-
const manifestPath =
|
|
54697
|
+
const manifestPath = import_node_path45.default.join(root, extId, "manifest.json");
|
|
54647
54698
|
const manifest = await readManifest(root, extId);
|
|
54648
54699
|
const next = { ...manifest, version: newVersion };
|
|
54649
54700
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -54651,7 +54702,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
54651
54702
|
await import_promises8.default.rename(tmp, manifestPath);
|
|
54652
54703
|
}
|
|
54653
54704
|
async function readManifest(root, extId) {
|
|
54654
|
-
const file =
|
|
54705
|
+
const file = import_node_path45.default.join(root, extId, "manifest.json");
|
|
54655
54706
|
let raw;
|
|
54656
54707
|
try {
|
|
54657
54708
|
raw = await import_promises8.default.readFile(file, "utf8");
|
|
@@ -54742,7 +54793,7 @@ function buildExtensionHandlers(deps) {
|
|
|
54742
54793
|
};
|
|
54743
54794
|
async function buildSnapshotMeta(extId) {
|
|
54744
54795
|
const manifest = await readManifest(deps.root, extId);
|
|
54745
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
54796
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path45.default.join(deps.root, extId));
|
|
54746
54797
|
return { manifest, contentHash: sha256, buffer };
|
|
54747
54798
|
}
|
|
54748
54799
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -54925,7 +54976,7 @@ function buildExtensionHandlers(deps) {
|
|
|
54925
54976
|
// src/app-builder/project-store.ts
|
|
54926
54977
|
var import_node_fs38 = require("fs");
|
|
54927
54978
|
var import_node_child_process11 = require("child_process");
|
|
54928
|
-
var
|
|
54979
|
+
var import_node_path46 = require("path");
|
|
54929
54980
|
init_protocol();
|
|
54930
54981
|
var PROJECTS_DIR = "projects";
|
|
54931
54982
|
var META_FILE = ".clawd-project.json";
|
|
@@ -54939,14 +54990,14 @@ var ProjectStore = class {
|
|
|
54939
54990
|
root;
|
|
54940
54991
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
54941
54992
|
metaPath(name) {
|
|
54942
|
-
return (0,
|
|
54993
|
+
return (0, import_node_path46.join)(this.projectsRoot(), name, META_FILE);
|
|
54943
54994
|
}
|
|
54944
54995
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
54945
54996
|
projectDir(name) {
|
|
54946
|
-
return (0,
|
|
54997
|
+
return (0, import_node_path46.join)(this.projectsRoot(), name);
|
|
54947
54998
|
}
|
|
54948
54999
|
projectsRoot() {
|
|
54949
|
-
return (0,
|
|
55000
|
+
return (0, import_node_path46.join)(this.root, PROJECTS_DIR);
|
|
54950
55001
|
}
|
|
54951
55002
|
async list() {
|
|
54952
55003
|
let entries;
|
|
@@ -55249,7 +55300,7 @@ var PublishJobRegistry = class {
|
|
|
55249
55300
|
// src/app-builder/publish-job-runner.ts
|
|
55250
55301
|
var import_node_child_process13 = require("child_process");
|
|
55251
55302
|
var import_node_fs39 = require("fs");
|
|
55252
|
-
var
|
|
55303
|
+
var import_node_path47 = require("path");
|
|
55253
55304
|
|
|
55254
55305
|
// src/app-builder/publish-stage-parser.ts
|
|
55255
55306
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -55281,7 +55332,7 @@ async function startPublishJob(deps, args) {
|
|
|
55281
55332
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
55282
55333
|
}
|
|
55283
55334
|
const projDir = projectDir(args.name);
|
|
55284
|
-
const logPath = (0,
|
|
55335
|
+
const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
|
|
55285
55336
|
let logStream = null;
|
|
55286
55337
|
try {
|
|
55287
55338
|
logStream = (0, import_node_fs39.createWriteStream)(logPath, { flags: "w" });
|
|
@@ -55541,7 +55592,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
55541
55592
|
|
|
55542
55593
|
// src/handlers/app-builder.ts
|
|
55543
55594
|
init_protocol();
|
|
55544
|
-
var
|
|
55595
|
+
var import_node_path48 = require("path");
|
|
55545
55596
|
var import_node_fs40 = require("fs");
|
|
55546
55597
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
55547
55598
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
@@ -55699,8 +55750,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
55699
55750
|
const project = await userStore.create(f.name, reservedPorts);
|
|
55700
55751
|
try {
|
|
55701
55752
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
55702
|
-
const templateSrcDir = (0,
|
|
55703
|
-
const scaffoldScript = (0,
|
|
55753
|
+
const templateSrcDir = (0, import_node_path48.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
55754
|
+
const scaffoldScript = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
55704
55755
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
55705
55756
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
55706
55757
|
name: project.name,
|
|
@@ -55921,7 +55972,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
55921
55972
|
await userStore.clearPublishJob(args.name);
|
|
55922
55973
|
}
|
|
55923
55974
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
55924
|
-
const scriptPath = (0,
|
|
55975
|
+
const scriptPath = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
55925
55976
|
deps.logger?.info("app-builder.publish.start", {
|
|
55926
55977
|
name: args.name,
|
|
55927
55978
|
sessionId: boundSession.sessionId,
|
|
@@ -56090,7 +56141,7 @@ function buildVisitorHandlers(deps) {
|
|
|
56090
56141
|
|
|
56091
56142
|
// src/extension/registry.ts
|
|
56092
56143
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
56093
|
-
var
|
|
56144
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
56094
56145
|
async function loadAll(root) {
|
|
56095
56146
|
let entries;
|
|
56096
56147
|
try {
|
|
@@ -56103,13 +56154,13 @@ async function loadAll(root) {
|
|
|
56103
56154
|
for (const ent of entries) {
|
|
56104
56155
|
if (!ent.isDirectory()) continue;
|
|
56105
56156
|
if (ent.name.startsWith(".")) continue;
|
|
56106
|
-
records.push(await loadOne(
|
|
56157
|
+
records.push(await loadOne(import_node_path49.default.join(root, ent.name), ent.name));
|
|
56107
56158
|
}
|
|
56108
56159
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
56109
56160
|
return records;
|
|
56110
56161
|
}
|
|
56111
56162
|
async function loadOne(dir, dirName) {
|
|
56112
|
-
const manifestPath =
|
|
56163
|
+
const manifestPath = import_node_path49.default.join(dir, "manifest.json");
|
|
56113
56164
|
let raw;
|
|
56114
56165
|
try {
|
|
56115
56166
|
raw = await import_promises9.default.readFile(manifestPath, "utf8");
|
|
@@ -56154,7 +56205,7 @@ async function loadOne(dir, dirName) {
|
|
|
56154
56205
|
|
|
56155
56206
|
// src/extension/uninstall.ts
|
|
56156
56207
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
56157
|
-
var
|
|
56208
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
56158
56209
|
var UninstallError = class extends Error {
|
|
56159
56210
|
constructor(code, message) {
|
|
56160
56211
|
super(message);
|
|
@@ -56163,7 +56214,7 @@ var UninstallError = class extends Error {
|
|
|
56163
56214
|
code;
|
|
56164
56215
|
};
|
|
56165
56216
|
async function uninstall(deps) {
|
|
56166
|
-
const dir =
|
|
56217
|
+
const dir = import_node_path50.default.join(deps.root, deps.extId);
|
|
56167
56218
|
try {
|
|
56168
56219
|
await import_promises10.default.access(dir);
|
|
56169
56220
|
} catch {
|
|
@@ -56719,7 +56770,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
56719
56770
|
|
|
56720
56771
|
// src/extension/runtime.ts
|
|
56721
56772
|
var import_node_child_process15 = require("child_process");
|
|
56722
|
-
var
|
|
56773
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56723
56774
|
var import_promises11 = require("timers/promises");
|
|
56724
56775
|
|
|
56725
56776
|
// src/extension/port-allocator.ts
|
|
@@ -56820,7 +56871,7 @@ var Runtime = class {
|
|
|
56820
56871
|
/\$CLAWOS_EXT_PORT/g,
|
|
56821
56872
|
String(port)
|
|
56822
56873
|
);
|
|
56823
|
-
const dir =
|
|
56874
|
+
const dir = import_node_path51.default.join(this.root, extId);
|
|
56824
56875
|
const env = {
|
|
56825
56876
|
...process.env,
|
|
56826
56877
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -56932,7 +56983,7 @@ ${handle.stderrTail}`
|
|
|
56932
56983
|
|
|
56933
56984
|
// src/extension/published-channels.ts
|
|
56934
56985
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
56935
|
-
var
|
|
56986
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
56936
56987
|
init_zod();
|
|
56937
56988
|
var PublishedChannelsError = class extends Error {
|
|
56938
56989
|
constructor(code, message) {
|
|
@@ -57031,7 +57082,7 @@ var PublishedChannelStore = class {
|
|
|
57031
57082
|
)
|
|
57032
57083
|
};
|
|
57033
57084
|
const tmp = `${this.filePath}.tmp`;
|
|
57034
|
-
await import_promises12.default.mkdir(
|
|
57085
|
+
await import_promises12.default.mkdir(import_node_path52.default.dirname(this.filePath), { recursive: true });
|
|
57035
57086
|
await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
57036
57087
|
await import_promises12.default.rename(tmp, this.filePath);
|
|
57037
57088
|
}
|
|
@@ -57039,7 +57090,7 @@ var PublishedChannelStore = class {
|
|
|
57039
57090
|
|
|
57040
57091
|
// src/extension/bundle-cache.ts
|
|
57041
57092
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
57042
|
-
var
|
|
57093
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
57043
57094
|
var BundleCache = class {
|
|
57044
57095
|
constructor(rootDir) {
|
|
57045
57096
|
this.rootDir = rootDir;
|
|
@@ -57048,14 +57099,14 @@ var BundleCache = class {
|
|
|
57048
57099
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
57049
57100
|
async write(snapshotHash, buffer) {
|
|
57050
57101
|
await import_promises13.default.mkdir(this.rootDir, { recursive: true });
|
|
57051
|
-
const file =
|
|
57102
|
+
const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57052
57103
|
const tmp = `${file}.tmp`;
|
|
57053
57104
|
await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
|
|
57054
57105
|
await import_promises13.default.rename(tmp, file);
|
|
57055
57106
|
}
|
|
57056
57107
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
57057
57108
|
async read(snapshotHash) {
|
|
57058
|
-
const file =
|
|
57109
|
+
const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57059
57110
|
try {
|
|
57060
57111
|
return await import_promises13.default.readFile(file);
|
|
57061
57112
|
} catch (e) {
|
|
@@ -57065,7 +57116,7 @@ var BundleCache = class {
|
|
|
57065
57116
|
}
|
|
57066
57117
|
/** Idempotent — missing file is not an error. */
|
|
57067
57118
|
async delete(snapshotHash) {
|
|
57068
|
-
const file =
|
|
57119
|
+
const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57069
57120
|
await import_promises13.default.rm(file, { force: true });
|
|
57070
57121
|
}
|
|
57071
57122
|
};
|
|
@@ -57086,11 +57137,11 @@ async function startDaemon(config) {
|
|
|
57086
57137
|
},
|
|
57087
57138
|
source: "daemon",
|
|
57088
57139
|
sampling: logShippingCfg.sampling,
|
|
57089
|
-
homeDir:
|
|
57140
|
+
homeDir: import_node_os21.default.homedir()
|
|
57090
57141
|
});
|
|
57091
57142
|
const logger = createLogger({
|
|
57092
57143
|
level: config.logLevel,
|
|
57093
|
-
file:
|
|
57144
|
+
file: import_node_path54.default.join(config.dataDir, "clawd.log"),
|
|
57094
57145
|
logClient
|
|
57095
57146
|
});
|
|
57096
57147
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
@@ -57230,8 +57281,8 @@ async function startDaemon(config) {
|
|
|
57230
57281
|
const agents = new AgentsScanner();
|
|
57231
57282
|
const history = new ClaudeHistoryReader();
|
|
57232
57283
|
let transport = null;
|
|
57233
|
-
const personaStore = new PersonaStore(
|
|
57234
|
-
const usersRoot =
|
|
57284
|
+
const personaStore = new PersonaStore(import_node_path54.default.join(config.dataDir, "personas"));
|
|
57285
|
+
const usersRoot = import_node_path54.default.join(config.dataDir, "users");
|
|
57235
57286
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
57236
57287
|
if (defaultsRoot) {
|
|
57237
57288
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -57251,17 +57302,17 @@ async function startDaemon(config) {
|
|
|
57251
57302
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
57252
57303
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
57253
57304
|
const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
|
|
57254
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
57305
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path54.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
57255
57306
|
const dispatchServerCandidates = [
|
|
57256
|
-
|
|
57307
|
+
import_node_path54.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
57257
57308
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
57258
|
-
|
|
57309
|
+
import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
57259
57310
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
57260
57311
|
];
|
|
57261
57312
|
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
|
|
57262
57313
|
let dispatchMcpConfigPath2;
|
|
57263
57314
|
if (dispatchServerScriptPath) {
|
|
57264
|
-
const dispatchLogPath =
|
|
57315
|
+
const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
57265
57316
|
dispatchMcpConfigPath2 = writeDispatchMcpConfig({
|
|
57266
57317
|
dataDir: config.dataDir,
|
|
57267
57318
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -57278,15 +57329,15 @@ async function startDaemon(config) {
|
|
|
57278
57329
|
});
|
|
57279
57330
|
}
|
|
57280
57331
|
const ticketServerCandidates = [
|
|
57281
|
-
|
|
57282
|
-
|
|
57332
|
+
import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
|
|
57333
|
+
import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
57283
57334
|
];
|
|
57284
57335
|
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
|
|
57285
57336
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
57286
57337
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
57287
57338
|
let ticketMcpConfigPath2;
|
|
57288
57339
|
if (ticketServerScriptPath && ticketOwnerUnionId) {
|
|
57289
|
-
const ticketLogPath =
|
|
57340
|
+
const ticketLogPath = import_node_path54.default.join(config.dataDir, "ticket-mcp-server.log");
|
|
57290
57341
|
ticketMcpConfigPath2 = writeTicketMcpConfig({
|
|
57291
57342
|
dataDir: config.dataDir,
|
|
57292
57343
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -57307,13 +57358,13 @@ async function startDaemon(config) {
|
|
|
57307
57358
|
});
|
|
57308
57359
|
}
|
|
57309
57360
|
const shiftServerCandidates = [
|
|
57310
|
-
|
|
57311
|
-
|
|
57361
|
+
import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
|
|
57362
|
+
import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
57312
57363
|
];
|
|
57313
57364
|
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
|
|
57314
57365
|
let shiftMcpConfigPath2;
|
|
57315
57366
|
if (shiftServerScriptPath) {
|
|
57316
|
-
const shiftLogPath =
|
|
57367
|
+
const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
|
|
57317
57368
|
shiftMcpConfigPath2 = await writeShiftMcpConfig({
|
|
57318
57369
|
dataDir: config.dataDir,
|
|
57319
57370
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -57331,7 +57382,7 @@ async function startDaemon(config) {
|
|
|
57331
57382
|
);
|
|
57332
57383
|
}
|
|
57333
57384
|
const shiftStore = createShiftStore({
|
|
57334
|
-
filePath:
|
|
57385
|
+
filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
|
|
57335
57386
|
ownerIdProvider: () => ownerPrincipalId,
|
|
57336
57387
|
now: () => Date.now()
|
|
57337
57388
|
});
|
|
@@ -57349,7 +57400,7 @@ async function startDaemon(config) {
|
|
|
57349
57400
|
getAdapter,
|
|
57350
57401
|
historyReader: history,
|
|
57351
57402
|
dataDir: config.dataDir,
|
|
57352
|
-
personaRoot:
|
|
57403
|
+
personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
|
|
57353
57404
|
usersRoot,
|
|
57354
57405
|
personaStore,
|
|
57355
57406
|
ownerDisplayName,
|
|
@@ -57390,7 +57441,7 @@ async function startDaemon(config) {
|
|
|
57390
57441
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
57391
57442
|
attachmentGroup: {
|
|
57392
57443
|
onFileEdit: (input) => {
|
|
57393
|
-
const absPath =
|
|
57444
|
+
const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
|
|
57394
57445
|
let size = 0;
|
|
57395
57446
|
try {
|
|
57396
57447
|
size = import_node_fs41.default.statSync(absPath).size;
|
|
@@ -57591,11 +57642,11 @@ async function startDaemon(config) {
|
|
|
57591
57642
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
57592
57643
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
57593
57644
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
57594
|
-
personaRoot:
|
|
57645
|
+
personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
|
|
57595
57646
|
usersRoot
|
|
57596
57647
|
},
|
|
57597
57648
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
57598
|
-
personaRoot:
|
|
57649
|
+
personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
|
|
57599
57650
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
57600
57651
|
usersRoot,
|
|
57601
57652
|
// capability:list / delete handler 依赖
|
|
@@ -57702,11 +57753,11 @@ async function startDaemon(config) {
|
|
|
57702
57753
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
57703
57754
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
57704
57755
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
57705
|
-
appBuilderPersonaRoot:
|
|
57756
|
+
appBuilderPersonaRoot: import_node_path54.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
57706
57757
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
57707
|
-
deployKitRoot:
|
|
57758
|
+
deployKitRoot: import_node_path54.default.join(config.dataDir, "deploy-kit"),
|
|
57708
57759
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
57709
|
-
resolvePersonaRoot: (personaId) =>
|
|
57760
|
+
resolvePersonaRoot: (personaId) => import_node_path54.default.join(config.dataDir, "personas", personaId),
|
|
57710
57761
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
57711
57762
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
57712
57763
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -57749,8 +57800,8 @@ async function startDaemon(config) {
|
|
|
57749
57800
|
}
|
|
57750
57801
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
57751
57802
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
57752
|
-
sourceJsonlPath =
|
|
57753
|
-
|
|
57803
|
+
sourceJsonlPath = import_node_path54.default.join(
|
|
57804
|
+
import_node_os21.default.homedir(),
|
|
57754
57805
|
".claude",
|
|
57755
57806
|
"projects",
|
|
57756
57807
|
cwdToHashDir(sourceFile.cwd),
|
|
@@ -58049,8 +58100,8 @@ async function startDaemon(config) {
|
|
|
58049
58100
|
const lines = [
|
|
58050
58101
|
`Tunnel: ${r.url}`,
|
|
58051
58102
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
58052
|
-
`Frpc config: ${
|
|
58053
|
-
`Frpc log: ${
|
|
58103
|
+
`Frpc config: ${import_node_path54.default.join(config.dataDir, "frpc.toml")}`,
|
|
58104
|
+
`Frpc log: ${import_node_path54.default.join(config.dataDir, "frpc.log")}`
|
|
58054
58105
|
];
|
|
58055
58106
|
const width = Math.max(...lines.map((l) => l.length));
|
|
58056
58107
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -58063,7 +58114,7 @@ ${bar}
|
|
|
58063
58114
|
|
|
58064
58115
|
`);
|
|
58065
58116
|
try {
|
|
58066
|
-
const connectPath =
|
|
58117
|
+
const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
|
|
58067
58118
|
import_node_fs41.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
58068
58119
|
} catch {
|
|
58069
58120
|
}
|
|
@@ -58136,7 +58187,7 @@ ${bar}
|
|
|
58136
58187
|
};
|
|
58137
58188
|
}
|
|
58138
58189
|
function migrateDropPersonsDir(dataDir) {
|
|
58139
|
-
const dir =
|
|
58190
|
+
const dir = import_node_path54.default.join(dataDir, "persons");
|
|
58140
58191
|
try {
|
|
58141
58192
|
import_node_fs41.default.rmSync(dir, { recursive: true, force: true });
|
|
58142
58193
|
} catch {
|