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