@clawos-dev/clawd 0.2.191-beta.382.4a6606c → 0.2.191
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 +603 -566
- package/dist/dispatch/mcp-server.cjs +1 -1
- package/dist/inbox/mcp-server.cjs +31 -8
- package/dist/share-ui/assets/{guest-DG1-7F5a.js → guest-Dc3fMzbg.js} +118 -118
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
- package/dist/persona-defaults/persona-bug-fixer/.claude/settings.json +0 -7
- package/dist/persona-defaults/persona-bug-fixer/.mcp.json +0 -15
- package/dist/persona-defaults/persona-bug-fixer/CLAUDE.md +0 -102
- package/dist/persona-defaults/persona-ticket-manager/CLAUDE.md +0 -97
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: path68, errorMaps, issueData } = params;
|
|
737
|
+
const fullPath = [...path68, ...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, path68, key) {
|
|
1049
1049
|
this._cachedPath = [];
|
|
1050
1050
|
this.parent = parent;
|
|
1051
1051
|
this.data = value;
|
|
1052
|
-
this._path =
|
|
1052
|
+
this._path = path68;
|
|
1053
1053
|
this._key = key;
|
|
1054
1054
|
}
|
|
1055
1055
|
get path() {
|
|
@@ -6373,8 +6373,8 @@ var require_req = __commonJS({
|
|
|
6373
6373
|
if (req.originalUrl) {
|
|
6374
6374
|
_req.url = req.originalUrl;
|
|
6375
6375
|
} else {
|
|
6376
|
-
const
|
|
6377
|
-
_req.url = typeof
|
|
6376
|
+
const path68 = req.path;
|
|
6377
|
+
_req.url = typeof path68 === "string" ? path68 : req.url ? req.url.path || req.url : void 0;
|
|
6378
6378
|
}
|
|
6379
6379
|
if (req.query) {
|
|
6380
6380
|
_req.query = req.query;
|
|
@@ -6539,14 +6539,14 @@ var require_redact = __commonJS({
|
|
|
6539
6539
|
}
|
|
6540
6540
|
return obj;
|
|
6541
6541
|
}
|
|
6542
|
-
function parsePath(
|
|
6542
|
+
function parsePath(path68) {
|
|
6543
6543
|
const parts = [];
|
|
6544
6544
|
let current = "";
|
|
6545
6545
|
let inBrackets = false;
|
|
6546
6546
|
let inQuotes = false;
|
|
6547
6547
|
let quoteChar = "";
|
|
6548
|
-
for (let i = 0; i <
|
|
6549
|
-
const char =
|
|
6548
|
+
for (let i = 0; i < path68.length; i++) {
|
|
6549
|
+
const char = path68[i];
|
|
6550
6550
|
if (!inBrackets && char === ".") {
|
|
6551
6551
|
if (current) {
|
|
6552
6552
|
parts.push(current);
|
|
@@ -6677,10 +6677,10 @@ var require_redact = __commonJS({
|
|
|
6677
6677
|
return current;
|
|
6678
6678
|
}
|
|
6679
6679
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6680
|
-
for (const
|
|
6681
|
-
const parts = parsePath(
|
|
6680
|
+
for (const path68 of paths) {
|
|
6681
|
+
const parts = parsePath(path68);
|
|
6682
6682
|
if (parts.includes("*")) {
|
|
6683
|
-
redactWildcardPath(obj, parts, censor,
|
|
6683
|
+
redactWildcardPath(obj, parts, censor, path68, remove);
|
|
6684
6684
|
} else {
|
|
6685
6685
|
if (remove) {
|
|
6686
6686
|
removeKey(obj, parts);
|
|
@@ -6765,8 +6765,8 @@ var require_redact = __commonJS({
|
|
|
6765
6765
|
}
|
|
6766
6766
|
} else {
|
|
6767
6767
|
if (afterWildcard.includes("*")) {
|
|
6768
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6769
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
6768
|
+
const wrappedCensor = typeof censor === "function" ? (value, path68) => {
|
|
6769
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path68];
|
|
6770
6770
|
return censor(value, fullPath);
|
|
6771
6771
|
} : censor;
|
|
6772
6772
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -6801,8 +6801,8 @@ var require_redact = __commonJS({
|
|
|
6801
6801
|
return null;
|
|
6802
6802
|
}
|
|
6803
6803
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
6804
|
-
for (const
|
|
6805
|
-
const parts = parsePath(
|
|
6804
|
+
for (const path68 of pathsToClone) {
|
|
6805
|
+
const parts = parsePath(path68);
|
|
6806
6806
|
let current = pathStructure;
|
|
6807
6807
|
for (let i = 0; i < parts.length; i++) {
|
|
6808
6808
|
const part = parts[i];
|
|
@@ -6854,24 +6854,24 @@ var require_redact = __commonJS({
|
|
|
6854
6854
|
}
|
|
6855
6855
|
return cloneSelectively(obj, pathStructure);
|
|
6856
6856
|
}
|
|
6857
|
-
function validatePath(
|
|
6858
|
-
if (typeof
|
|
6857
|
+
function validatePath(path68) {
|
|
6858
|
+
if (typeof path68 !== "string") {
|
|
6859
6859
|
throw new Error("Paths must be (non-empty) strings");
|
|
6860
6860
|
}
|
|
6861
|
-
if (
|
|
6861
|
+
if (path68 === "") {
|
|
6862
6862
|
throw new Error("Invalid redaction path ()");
|
|
6863
6863
|
}
|
|
6864
|
-
if (
|
|
6865
|
-
throw new Error(`Invalid redaction path (${
|
|
6864
|
+
if (path68.includes("..")) {
|
|
6865
|
+
throw new Error(`Invalid redaction path (${path68})`);
|
|
6866
6866
|
}
|
|
6867
|
-
if (
|
|
6868
|
-
throw new Error(`Invalid redaction path (${
|
|
6867
|
+
if (path68.includes(",")) {
|
|
6868
|
+
throw new Error(`Invalid redaction path (${path68})`);
|
|
6869
6869
|
}
|
|
6870
6870
|
let bracketCount = 0;
|
|
6871
6871
|
let inQuotes = false;
|
|
6872
6872
|
let quoteChar = "";
|
|
6873
|
-
for (let i = 0; i <
|
|
6874
|
-
const char =
|
|
6873
|
+
for (let i = 0; i < path68.length; i++) {
|
|
6874
|
+
const char = path68[i];
|
|
6875
6875
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
6876
6876
|
if (!inQuotes) {
|
|
6877
6877
|
inQuotes = true;
|
|
@@ -6885,20 +6885,20 @@ var require_redact = __commonJS({
|
|
|
6885
6885
|
} else if (char === "]" && !inQuotes) {
|
|
6886
6886
|
bracketCount--;
|
|
6887
6887
|
if (bracketCount < 0) {
|
|
6888
|
-
throw new Error(`Invalid redaction path (${
|
|
6888
|
+
throw new Error(`Invalid redaction path (${path68})`);
|
|
6889
6889
|
}
|
|
6890
6890
|
}
|
|
6891
6891
|
}
|
|
6892
6892
|
if (bracketCount !== 0) {
|
|
6893
|
-
throw new Error(`Invalid redaction path (${
|
|
6893
|
+
throw new Error(`Invalid redaction path (${path68})`);
|
|
6894
6894
|
}
|
|
6895
6895
|
}
|
|
6896
6896
|
function validatePaths(paths) {
|
|
6897
6897
|
if (!Array.isArray(paths)) {
|
|
6898
6898
|
throw new TypeError("paths must be an array");
|
|
6899
6899
|
}
|
|
6900
|
-
for (const
|
|
6901
|
-
validatePath(
|
|
6900
|
+
for (const path68 of paths) {
|
|
6901
|
+
validatePath(path68);
|
|
6902
6902
|
}
|
|
6903
6903
|
}
|
|
6904
6904
|
function slowRedact(options = {}) {
|
|
@@ -7066,8 +7066,8 @@ var require_redaction = __commonJS({
|
|
|
7066
7066
|
if (shape[k2] === null) {
|
|
7067
7067
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
7068
7068
|
} else {
|
|
7069
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
7070
|
-
return censor(value, [k2, ...
|
|
7069
|
+
const wrappedCensor = typeof censor === "function" ? (value, path68) => {
|
|
7070
|
+
return censor(value, [k2, ...path68]);
|
|
7071
7071
|
} : censor;
|
|
7072
7072
|
o[k2] = Redact({
|
|
7073
7073
|
paths: shape[k2],
|
|
@@ -7288,7 +7288,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7288
7288
|
var fs61 = require("fs");
|
|
7289
7289
|
var EventEmitter3 = require("events");
|
|
7290
7290
|
var inherits = require("util").inherits;
|
|
7291
|
-
var
|
|
7291
|
+
var path68 = require("path");
|
|
7292
7292
|
var sleep2 = require_atomic_sleep();
|
|
7293
7293
|
var assert = require("assert");
|
|
7294
7294
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7342,7 +7342,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7342
7342
|
const mode = sonic.mode;
|
|
7343
7343
|
if (sonic.sync) {
|
|
7344
7344
|
try {
|
|
7345
|
-
if (sonic.mkdir) fs61.mkdirSync(
|
|
7345
|
+
if (sonic.mkdir) fs61.mkdirSync(path68.dirname(file), { recursive: true });
|
|
7346
7346
|
const fd = fs61.openSync(file, flags, mode);
|
|
7347
7347
|
fileOpened(null, fd);
|
|
7348
7348
|
} catch (err) {
|
|
@@ -7350,7 +7350,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7350
7350
|
throw err;
|
|
7351
7351
|
}
|
|
7352
7352
|
} else if (sonic.mkdir) {
|
|
7353
|
-
fs61.mkdir(
|
|
7353
|
+
fs61.mkdir(path68.dirname(file), { recursive: true }, (err) => {
|
|
7354
7354
|
if (err) return fileOpened(err);
|
|
7355
7355
|
fs61.open(file, flags, mode, fileOpened);
|
|
7356
7356
|
});
|
|
@@ -10210,7 +10210,7 @@ var require_multistream = __commonJS({
|
|
|
10210
10210
|
var require_pino = __commonJS({
|
|
10211
10211
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
10212
10212
|
"use strict";
|
|
10213
|
-
var
|
|
10213
|
+
var os23 = require("os");
|
|
10214
10214
|
var stdSerializers = require_pino_std_serializers();
|
|
10215
10215
|
var caller = require_caller();
|
|
10216
10216
|
var redaction = require_redaction();
|
|
@@ -10257,7 +10257,7 @@ var require_pino = __commonJS({
|
|
|
10257
10257
|
} = symbols;
|
|
10258
10258
|
var { epochTime, nullTime } = time;
|
|
10259
10259
|
var { pid } = process;
|
|
10260
|
-
var hostname =
|
|
10260
|
+
var hostname = os23.hostname();
|
|
10261
10261
|
var defaultErrorSerializer = stdSerializers.err;
|
|
10262
10262
|
var defaultOptions = {
|
|
10263
10263
|
level: "info",
|
|
@@ -10981,11 +10981,11 @@ var init_lib = __esm({
|
|
|
10981
10981
|
}
|
|
10982
10982
|
}
|
|
10983
10983
|
},
|
|
10984
|
-
addToPath: function addToPath(
|
|
10985
|
-
var last =
|
|
10984
|
+
addToPath: function addToPath(path68, added, removed, oldPosInc, options) {
|
|
10985
|
+
var last = path68.lastComponent;
|
|
10986
10986
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
10987
10987
|
return {
|
|
10988
|
-
oldPos:
|
|
10988
|
+
oldPos: path68.oldPos + oldPosInc,
|
|
10989
10989
|
lastComponent: {
|
|
10990
10990
|
count: last.count + 1,
|
|
10991
10991
|
added,
|
|
@@ -10995,7 +10995,7 @@ var init_lib = __esm({
|
|
|
10995
10995
|
};
|
|
10996
10996
|
} else {
|
|
10997
10997
|
return {
|
|
10998
|
-
oldPos:
|
|
10998
|
+
oldPos: path68.oldPos + oldPosInc,
|
|
10999
10999
|
lastComponent: {
|
|
11000
11000
|
count: 1,
|
|
11001
11001
|
added,
|
|
@@ -11053,7 +11053,7 @@ var init_lib = __esm({
|
|
|
11053
11053
|
tokenize: function tokenize(value) {
|
|
11054
11054
|
return Array.from(value);
|
|
11055
11055
|
},
|
|
11056
|
-
join: function
|
|
11056
|
+
join: function join3(chars) {
|
|
11057
11057
|
return chars.join("");
|
|
11058
11058
|
},
|
|
11059
11059
|
postProcess: function postProcess(changeObjects) {
|
|
@@ -11235,13 +11235,33 @@ var init_tool_result_extra = __esm({
|
|
|
11235
11235
|
function cwdToHashDir(cwd) {
|
|
11236
11236
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
11237
11237
|
}
|
|
11238
|
+
function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
|
|
11239
|
+
const dir = import_node_path4.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
|
|
11240
|
+
let entries;
|
|
11241
|
+
try {
|
|
11242
|
+
entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
11243
|
+
} catch {
|
|
11244
|
+
return null;
|
|
11245
|
+
}
|
|
11246
|
+
let newest = null;
|
|
11247
|
+
for (const e of entries) {
|
|
11248
|
+
if (!e.isFile()) continue;
|
|
11249
|
+
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11250
|
+
try {
|
|
11251
|
+
const m2 = import_node_fs4.default.statSync(import_node_path4.default.join(dir, e.name)).mtimeMs;
|
|
11252
|
+
if (newest === null || m2 > newest) newest = m2;
|
|
11253
|
+
} catch {
|
|
11254
|
+
}
|
|
11255
|
+
}
|
|
11256
|
+
return newest;
|
|
11257
|
+
}
|
|
11238
11258
|
function hashDirToCwd(hash) {
|
|
11239
11259
|
const body = hash.startsWith("-") ? hash.slice(1) : hash;
|
|
11240
11260
|
return "/" + body.replace(/-/g, "/");
|
|
11241
11261
|
}
|
|
11242
11262
|
function safeStatMtime(p2) {
|
|
11243
11263
|
try {
|
|
11244
|
-
return
|
|
11264
|
+
return import_node_fs4.default.statSync(p2).mtimeMs;
|
|
11245
11265
|
} catch {
|
|
11246
11266
|
return 0;
|
|
11247
11267
|
}
|
|
@@ -11249,7 +11269,7 @@ function safeStatMtime(p2) {
|
|
|
11249
11269
|
function readJsonlLines(file) {
|
|
11250
11270
|
let raw;
|
|
11251
11271
|
try {
|
|
11252
|
-
raw =
|
|
11272
|
+
raw = import_node_fs4.default.readFileSync(file, "utf8");
|
|
11253
11273
|
} catch (err) {
|
|
11254
11274
|
if (err.code === "ENOENT") return [];
|
|
11255
11275
|
throw err;
|
|
@@ -11441,10 +11461,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11441
11461
|
const memories = raw.map((m2) => {
|
|
11442
11462
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11443
11463
|
const rec3 = m2;
|
|
11444
|
-
const
|
|
11464
|
+
const path68 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11445
11465
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11446
|
-
if (!
|
|
11447
|
-
const entry = { path:
|
|
11466
|
+
if (!path68 || content == null) return null;
|
|
11467
|
+
const entry = { path: path68, content };
|
|
11448
11468
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11449
11469
|
return entry;
|
|
11450
11470
|
}).filter((m2) => m2 !== null);
|
|
@@ -11480,8 +11500,8 @@ function attachmentDeferredToolsText(a) {
|
|
|
11480
11500
|
function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
11481
11501
|
if (backupFileName === null) return null;
|
|
11482
11502
|
try {
|
|
11483
|
-
return
|
|
11484
|
-
|
|
11503
|
+
return import_node_fs4.default.readFileSync(
|
|
11504
|
+
import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
11485
11505
|
"utf8"
|
|
11486
11506
|
);
|
|
11487
11507
|
} catch {
|
|
@@ -11490,19 +11510,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
11490
11510
|
}
|
|
11491
11511
|
function readCurrentContent(filePath) {
|
|
11492
11512
|
try {
|
|
11493
|
-
return
|
|
11513
|
+
return import_node_fs4.default.readFileSync(filePath, "utf8");
|
|
11494
11514
|
} catch (err) {
|
|
11495
11515
|
if (err.code === "ENOENT") return null;
|
|
11496
11516
|
return null;
|
|
11497
11517
|
}
|
|
11498
11518
|
}
|
|
11499
|
-
var
|
|
11519
|
+
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;
|
|
11500
11520
|
var init_claude_history = __esm({
|
|
11501
11521
|
"src/tools/claude-history.ts"() {
|
|
11502
11522
|
"use strict";
|
|
11503
|
-
|
|
11504
|
-
|
|
11505
|
-
|
|
11523
|
+
import_node_fs4 = __toESM(require("fs"), 1);
|
|
11524
|
+
import_node_os3 = __toESM(require("os"), 1);
|
|
11525
|
+
import_node_path4 = __toESM(require("path"), 1);
|
|
11506
11526
|
init_lib();
|
|
11507
11527
|
init_tool_result_extra();
|
|
11508
11528
|
TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
|
|
@@ -11526,14 +11546,14 @@ var init_claude_history = __esm({
|
|
|
11526
11546
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
11527
11547
|
fileHistoryRoot;
|
|
11528
11548
|
constructor(opts = {}) {
|
|
11529
|
-
const base = opts.baseDir ??
|
|
11530
|
-
this.projectsRoot =
|
|
11531
|
-
this.fileHistoryRoot =
|
|
11549
|
+
const base = opts.baseDir ?? import_node_path4.default.join(import_node_os3.default.homedir(), ".claude");
|
|
11550
|
+
this.projectsRoot = import_node_path4.default.join(base, "projects");
|
|
11551
|
+
this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
|
|
11532
11552
|
}
|
|
11533
11553
|
async listProjects() {
|
|
11534
11554
|
let entries;
|
|
11535
11555
|
try {
|
|
11536
|
-
entries =
|
|
11556
|
+
entries = import_node_fs4.default.readdirSync(this.projectsRoot, { withFileTypes: true });
|
|
11537
11557
|
} catch (err) {
|
|
11538
11558
|
if (err.code === "ENOENT") return [];
|
|
11539
11559
|
throw err;
|
|
@@ -11541,9 +11561,9 @@ var init_claude_history = __esm({
|
|
|
11541
11561
|
const out = [];
|
|
11542
11562
|
for (const ent of entries) {
|
|
11543
11563
|
if (!ent.isDirectory()) continue;
|
|
11544
|
-
const dir =
|
|
11545
|
-
const files =
|
|
11546
|
-
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(
|
|
11564
|
+
const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
|
|
11565
|
+
const files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11566
|
+
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
|
|
11547
11567
|
out.push({
|
|
11548
11568
|
projectPath: hashDirToCwd(ent.name),
|
|
11549
11569
|
hashDir: ent.name,
|
|
@@ -11555,17 +11575,17 @@ var init_claude_history = __esm({
|
|
|
11555
11575
|
return out;
|
|
11556
11576
|
}
|
|
11557
11577
|
async listSessions(args) {
|
|
11558
|
-
const dir =
|
|
11578
|
+
const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
11559
11579
|
let files;
|
|
11560
11580
|
try {
|
|
11561
|
-
files =
|
|
11581
|
+
files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11562
11582
|
} catch (err) {
|
|
11563
11583
|
if (err.code === "ENOENT") return [];
|
|
11564
11584
|
throw err;
|
|
11565
11585
|
}
|
|
11566
11586
|
const out = [];
|
|
11567
11587
|
for (const f of files) {
|
|
11568
|
-
const full =
|
|
11588
|
+
const full = import_node_path4.default.join(dir, f);
|
|
11569
11589
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
11570
11590
|
const lines = readJsonlLines(full);
|
|
11571
11591
|
let summary = "";
|
|
@@ -11620,7 +11640,7 @@ var init_claude_history = __esm({
|
|
|
11620
11640
|
return out;
|
|
11621
11641
|
}
|
|
11622
11642
|
async read(args) {
|
|
11623
|
-
const file =
|
|
11643
|
+
const file = import_node_path4.default.join(
|
|
11624
11644
|
this.projectsRoot,
|
|
11625
11645
|
cwdToHashDir(args.cwd),
|
|
11626
11646
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11657,7 +11677,7 @@ var init_claude_history = __esm({
|
|
|
11657
11677
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
11658
11678
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
11659
11679
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
11660
|
-
const dir =
|
|
11680
|
+
const dir = import_node_path4.default.join(
|
|
11661
11681
|
this.projectsRoot,
|
|
11662
11682
|
cwdToHashDir(cwd),
|
|
11663
11683
|
toolSessionId,
|
|
@@ -11665,7 +11685,7 @@ var init_claude_history = __esm({
|
|
|
11665
11685
|
);
|
|
11666
11686
|
let entries;
|
|
11667
11687
|
try {
|
|
11668
|
-
entries =
|
|
11688
|
+
entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
11669
11689
|
} catch (err) {
|
|
11670
11690
|
if (err.code === "ENOENT") return null;
|
|
11671
11691
|
return null;
|
|
@@ -11675,7 +11695,7 @@ var init_claude_history = __esm({
|
|
|
11675
11695
|
if (!e.isFile()) continue;
|
|
11676
11696
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11677
11697
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
11678
|
-
const filePath =
|
|
11698
|
+
const filePath = import_node_path4.default.join(dir, e.name);
|
|
11679
11699
|
const lines = readJsonlLines(filePath);
|
|
11680
11700
|
let firstText = "";
|
|
11681
11701
|
let messageCount = 0;
|
|
@@ -11692,7 +11712,7 @@ var init_claude_history = __esm({
|
|
|
11692
11712
|
return out;
|
|
11693
11713
|
}
|
|
11694
11714
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
11695
|
-
const file =
|
|
11715
|
+
const file = import_node_path4.default.join(
|
|
11696
11716
|
this.projectsRoot,
|
|
11697
11717
|
cwdToHashDir(cwd),
|
|
11698
11718
|
`${toolSessionId}.jsonl`
|
|
@@ -11727,7 +11747,7 @@ var init_claude_history = __esm({
|
|
|
11727
11747
|
}
|
|
11728
11748
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
11729
11749
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
11730
|
-
const file =
|
|
11750
|
+
const file = import_node_path4.default.join(
|
|
11731
11751
|
this.projectsRoot,
|
|
11732
11752
|
cwdToHashDir(cwd),
|
|
11733
11753
|
toolSessionId,
|
|
@@ -11736,7 +11756,7 @@ var init_claude_history = __esm({
|
|
|
11736
11756
|
);
|
|
11737
11757
|
let exists = false;
|
|
11738
11758
|
try {
|
|
11739
|
-
exists =
|
|
11759
|
+
exists = import_node_fs4.default.statSync(file).isFile();
|
|
11740
11760
|
} catch {
|
|
11741
11761
|
return null;
|
|
11742
11762
|
}
|
|
@@ -11755,7 +11775,7 @@ var init_claude_history = __esm({
|
|
|
11755
11775
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
11756
11776
|
*/
|
|
11757
11777
|
readFileHistorySnapshots(args) {
|
|
11758
|
-
const file =
|
|
11778
|
+
const file = import_node_path4.default.join(
|
|
11759
11779
|
this.projectsRoot,
|
|
11760
11780
|
cwdToHashDir(args.cwd),
|
|
11761
11781
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11800,7 +11820,7 @@ var init_claude_history = __esm({
|
|
|
11800
11820
|
for (const [anchorId, target] of snapshots) {
|
|
11801
11821
|
let hasAny = false;
|
|
11802
11822
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11803
|
-
const absPath =
|
|
11823
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
11804
11824
|
const backupContent = readBackupContent(
|
|
11805
11825
|
this.fileHistoryRoot,
|
|
11806
11826
|
args.toolSessionId,
|
|
@@ -11840,7 +11860,7 @@ var init_claude_history = __esm({
|
|
|
11840
11860
|
let totalInsertions = 0;
|
|
11841
11861
|
let totalDeletions = 0;
|
|
11842
11862
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11843
|
-
const absPath =
|
|
11863
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
11844
11864
|
const backupContent = readBackupContent(
|
|
11845
11865
|
this.fileHistoryRoot,
|
|
11846
11866
|
args.toolSessionId,
|
|
@@ -11887,7 +11907,7 @@ var init_claude_history = __esm({
|
|
|
11887
11907
|
};
|
|
11888
11908
|
}
|
|
11889
11909
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
11890
|
-
const file =
|
|
11910
|
+
const file = import_node_path4.default.join(
|
|
11891
11911
|
this.projectsRoot,
|
|
11892
11912
|
cwdToHashDir(cwd),
|
|
11893
11913
|
`${toolSessionId}.jsonl`
|
|
@@ -12256,10 +12276,10 @@ function parseAttachment(obj) {
|
|
|
12256
12276
|
const memories = raw.map((m2) => {
|
|
12257
12277
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12258
12278
|
const rec3 = m2;
|
|
12259
|
-
const
|
|
12279
|
+
const path68 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12260
12280
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12261
|
-
if (!
|
|
12262
|
-
const out = { path:
|
|
12281
|
+
if (!path68 || content == null) return null;
|
|
12282
|
+
const out = { path: path68, content };
|
|
12263
12283
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12264
12284
|
return out;
|
|
12265
12285
|
}).filter((m2) => m2 !== null);
|
|
@@ -12391,8 +12411,9 @@ var init_claude = __esm({
|
|
|
12391
12411
|
};
|
|
12392
12412
|
CLAUDE_MODELS = [
|
|
12393
12413
|
{ id: "", label: "Default", description: "CLI default model", contextWindowSize: 2e5, default: true },
|
|
12394
|
-
{ id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 2e5 },
|
|
12395
12414
|
{ id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
|
|
12415
|
+
{ id: "fable", label: "Fable", contextWindowSize: 2e5 },
|
|
12416
|
+
{ id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 2e5 },
|
|
12396
12417
|
{ id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 2e5 }
|
|
12397
12418
|
];
|
|
12398
12419
|
CLAUDE_PERMISSION_MODES = [
|
|
@@ -33223,8 +33244,8 @@ var require_utils = __commonJS({
|
|
|
33223
33244
|
var result = transform[inputType][outputType](input);
|
|
33224
33245
|
return result;
|
|
33225
33246
|
};
|
|
33226
|
-
exports2.resolve = function(
|
|
33227
|
-
var parts =
|
|
33247
|
+
exports2.resolve = function(path68) {
|
|
33248
|
+
var parts = path68.split("/");
|
|
33228
33249
|
var result = [];
|
|
33229
33250
|
for (var index = 0; index < parts.length; index++) {
|
|
33230
33251
|
var part = parts[index];
|
|
@@ -39077,18 +39098,18 @@ var require_object = __commonJS({
|
|
|
39077
39098
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
39078
39099
|
this.files[name] = object;
|
|
39079
39100
|
};
|
|
39080
|
-
var parentFolder = function(
|
|
39081
|
-
if (
|
|
39082
|
-
|
|
39101
|
+
var parentFolder = function(path68) {
|
|
39102
|
+
if (path68.slice(-1) === "/") {
|
|
39103
|
+
path68 = path68.substring(0, path68.length - 1);
|
|
39083
39104
|
}
|
|
39084
|
-
var lastSlash =
|
|
39085
|
-
return lastSlash > 0 ?
|
|
39105
|
+
var lastSlash = path68.lastIndexOf("/");
|
|
39106
|
+
return lastSlash > 0 ? path68.substring(0, lastSlash) : "";
|
|
39086
39107
|
};
|
|
39087
|
-
var forceTrailingSlash = function(
|
|
39088
|
-
if (
|
|
39089
|
-
|
|
39108
|
+
var forceTrailingSlash = function(path68) {
|
|
39109
|
+
if (path68.slice(-1) !== "/") {
|
|
39110
|
+
path68 += "/";
|
|
39090
39111
|
}
|
|
39091
|
-
return
|
|
39112
|
+
return path68;
|
|
39092
39113
|
};
|
|
39093
39114
|
var folderAdd = function(name, createFolders) {
|
|
39094
39115
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -40090,7 +40111,7 @@ var require_lib3 = __commonJS({
|
|
|
40090
40111
|
// src/run-case/recorder.ts
|
|
40091
40112
|
function startRunCaseRecorder(opts) {
|
|
40092
40113
|
const now = opts.now ?? Date.now;
|
|
40093
|
-
const dir =
|
|
40114
|
+
const dir = import_node_path56.default.dirname(opts.recordPath);
|
|
40094
40115
|
let stream = null;
|
|
40095
40116
|
let closing = false;
|
|
40096
40117
|
let closedSettled = false;
|
|
@@ -40130,12 +40151,12 @@ function startRunCaseRecorder(opts) {
|
|
|
40130
40151
|
};
|
|
40131
40152
|
return { tap, close, closed };
|
|
40132
40153
|
}
|
|
40133
|
-
var import_node_fs43,
|
|
40154
|
+
var import_node_fs43, import_node_path56;
|
|
40134
40155
|
var init_recorder = __esm({
|
|
40135
40156
|
"src/run-case/recorder.ts"() {
|
|
40136
40157
|
"use strict";
|
|
40137
40158
|
import_node_fs43 = __toESM(require("fs"), 1);
|
|
40138
|
-
|
|
40159
|
+
import_node_path56 = __toESM(require("path"), 1);
|
|
40139
40160
|
}
|
|
40140
40161
|
});
|
|
40141
40162
|
|
|
@@ -40178,7 +40199,7 @@ var init_wire = __esm({
|
|
|
40178
40199
|
// src/run-case/controller.ts
|
|
40179
40200
|
async function runController(opts) {
|
|
40180
40201
|
const now = opts.now ?? Date.now;
|
|
40181
|
-
const cwd = opts.cwd ?? (0, import_node_fs44.mkdtempSync)(
|
|
40202
|
+
const cwd = opts.cwd ?? (0, import_node_fs44.mkdtempSync)(import_node_path57.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
|
|
40182
40203
|
const ownsCwd = opts.cwd === void 0;
|
|
40183
40204
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40184
40205
|
const spawnCtx = { cwd };
|
|
@@ -40345,13 +40366,13 @@ async function runController(opts) {
|
|
|
40345
40366
|
}
|
|
40346
40367
|
return exitCode ?? 0;
|
|
40347
40368
|
}
|
|
40348
|
-
var import_node_fs44,
|
|
40369
|
+
var import_node_fs44, import_node_os22, import_node_path57;
|
|
40349
40370
|
var init_controller = __esm({
|
|
40350
40371
|
"src/run-case/controller.ts"() {
|
|
40351
40372
|
"use strict";
|
|
40352
40373
|
import_node_fs44 = require("fs");
|
|
40353
|
-
|
|
40354
|
-
|
|
40374
|
+
import_node_os22 = __toESM(require("os"), 1);
|
|
40375
|
+
import_node_path57 = __toESM(require("path"), 1);
|
|
40355
40376
|
init_claude();
|
|
40356
40377
|
init_stdout_splitter();
|
|
40357
40378
|
init_permission_stdio();
|
|
@@ -40613,9 +40634,9 @@ Env (advanced):
|
|
|
40613
40634
|
`;
|
|
40614
40635
|
|
|
40615
40636
|
// src/index.ts
|
|
40616
|
-
var
|
|
40637
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
40617
40638
|
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
40618
|
-
var
|
|
40639
|
+
var import_node_os21 = __toESM(require("os"), 1);
|
|
40619
40640
|
|
|
40620
40641
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
40621
40642
|
var byteToHex = [];
|
|
@@ -41232,9 +41253,9 @@ var SessionStoreFactory = class {
|
|
|
41232
41253
|
};
|
|
41233
41254
|
|
|
41234
41255
|
// src/session/manager.ts
|
|
41235
|
-
var
|
|
41236
|
-
var
|
|
41237
|
-
var
|
|
41256
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
41257
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
41258
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
41238
41259
|
init_protocol();
|
|
41239
41260
|
|
|
41240
41261
|
// src/tools/guest-settings.ts
|
|
@@ -41332,6 +41353,10 @@ function escapeAttr(v2) {
|
|
|
41332
41353
|
return v2.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
41333
41354
|
}
|
|
41334
41355
|
|
|
41356
|
+
// src/session/runner.ts
|
|
41357
|
+
var import_node_os4 = __toESM(require("os"), 1);
|
|
41358
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
41359
|
+
|
|
41335
41360
|
// src/session/reducer.ts
|
|
41336
41361
|
init_runtime();
|
|
41337
41362
|
|
|
@@ -41418,7 +41443,7 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
|
|
|
41418
41443
|
// src/dispatch/system-prompt.ts
|
|
41419
41444
|
var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
|
|
41420
41445
|
|
|
41421
|
-
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-
|
|
41446
|
+
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-app-builder\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 MCP tool \`mcp__clawd-dispatch__personaDispatch\` \u59D4\u6D3E\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF1A
|
|
41422
41447
|
|
|
41423
41448
|
- \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
|
|
41424
41449
|
- \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
|
|
@@ -41470,7 +41495,7 @@ function cloneState(s) {
|
|
|
41470
41495
|
pendingSend: s.pendingSend.slice()
|
|
41471
41496
|
};
|
|
41472
41497
|
}
|
|
41473
|
-
var IDLE_KILL_DELAY_MS =
|
|
41498
|
+
var IDLE_KILL_DELAY_MS = 6e5;
|
|
41474
41499
|
function tryFlushPending(state, deps) {
|
|
41475
41500
|
if (!state.readyForSend || state.pendingSend.length === 0) return [];
|
|
41476
41501
|
const text = state.pendingSend.shift();
|
|
@@ -42141,6 +42166,18 @@ function reduceSession(state, input, deps) {
|
|
|
42141
42166
|
if (state.status !== "running-idle") {
|
|
42142
42167
|
return { state, effects: [] };
|
|
42143
42168
|
}
|
|
42169
|
+
if (input.subagentActive) {
|
|
42170
|
+
return {
|
|
42171
|
+
state,
|
|
42172
|
+
effects: [
|
|
42173
|
+
{
|
|
42174
|
+
kind: "schedule-idle-kill",
|
|
42175
|
+
sessionId: state.file.sessionId,
|
|
42176
|
+
ms: IDLE_KILL_DELAY_MS
|
|
42177
|
+
}
|
|
42178
|
+
]
|
|
42179
|
+
};
|
|
42180
|
+
}
|
|
42144
42181
|
const next = cloneState(state);
|
|
42145
42182
|
next.status = "stopping";
|
|
42146
42183
|
return {
|
|
@@ -42197,10 +42234,11 @@ function reduceSession(state, input, deps) {
|
|
|
42197
42234
|
// src/session/runner.ts
|
|
42198
42235
|
init_stdout_splitter();
|
|
42199
42236
|
init_permission_stdio();
|
|
42237
|
+
init_claude_history();
|
|
42200
42238
|
|
|
42201
42239
|
// src/ipc-recorder.ts
|
|
42202
|
-
var
|
|
42203
|
-
var
|
|
42240
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
42241
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
42204
42242
|
function tsForFilename(ms) {
|
|
42205
42243
|
return new Date(ms).toISOString().replace(/[:.]/g, "-");
|
|
42206
42244
|
}
|
|
@@ -42211,8 +42249,8 @@ function startRecorder(opts) {
|
|
|
42211
42249
|
return null;
|
|
42212
42250
|
}
|
|
42213
42251
|
const now = opts.now ?? Date.now;
|
|
42214
|
-
const dir =
|
|
42215
|
-
const filePath =
|
|
42252
|
+
const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
|
|
42253
|
+
const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
|
|
42216
42254
|
let stream = null;
|
|
42217
42255
|
let closedResolve;
|
|
42218
42256
|
const closed = new Promise((resolve6) => {
|
|
@@ -42221,8 +42259,8 @@ function startRecorder(opts) {
|
|
|
42221
42259
|
let exited = false;
|
|
42222
42260
|
const ensureStream = () => {
|
|
42223
42261
|
if (stream) return stream;
|
|
42224
|
-
|
|
42225
|
-
stream =
|
|
42262
|
+
import_node_fs5.default.mkdirSync(dir, { recursive: true });
|
|
42263
|
+
stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
|
|
42226
42264
|
stream.on("close", () => closedResolve());
|
|
42227
42265
|
return stream;
|
|
42228
42266
|
};
|
|
@@ -42267,6 +42305,7 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
|
|
|
42267
42305
|
return JSON.stringify(payload) + "\n";
|
|
42268
42306
|
}
|
|
42269
42307
|
var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
|
|
42308
|
+
var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
|
|
42270
42309
|
var SessionRunner = class {
|
|
42271
42310
|
constructor(initial, hooks) {
|
|
42272
42311
|
this.hooks = hooks;
|
|
@@ -42579,7 +42618,7 @@ var SessionRunner = class {
|
|
|
42579
42618
|
if (existing) clearTimeout(existing);
|
|
42580
42619
|
const timer = setTimeout(() => {
|
|
42581
42620
|
this.idleKillTimers.delete(effect.sessionId);
|
|
42582
|
-
this.input({ kind: "idle-kill-fired" });
|
|
42621
|
+
this.input({ kind: "idle-kill-fired", subagentActive: this.isSubagentActive() });
|
|
42583
42622
|
}, effect.ms);
|
|
42584
42623
|
timer.unref?.();
|
|
42585
42624
|
this.idleKillTimers.set(effect.sessionId, timer);
|
|
@@ -42595,6 +42634,18 @@ var SessionRunner = class {
|
|
|
42595
42634
|
}
|
|
42596
42635
|
}
|
|
42597
42636
|
}
|
|
42637
|
+
// idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
|
|
42638
|
+
// 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
|
|
42639
|
+
// 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
|
|
42640
|
+
isSubagentActive() {
|
|
42641
|
+
const toolSessionId = this.state.file.toolSessionId;
|
|
42642
|
+
if (!toolSessionId) return false;
|
|
42643
|
+
const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
|
|
42644
|
+
const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
|
|
42645
|
+
if (mtime === null) return false;
|
|
42646
|
+
const now = (this.hooks.now ?? Date.now)();
|
|
42647
|
+
return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
|
|
42648
|
+
}
|
|
42598
42649
|
// 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
|
|
42599
42650
|
// 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
|
|
42600
42651
|
clearIdleKillTimers() {
|
|
@@ -42677,15 +42728,15 @@ function extractEditPath(input) {
|
|
|
42677
42728
|
}
|
|
42678
42729
|
|
|
42679
42730
|
// src/debug/pty-probe.ts
|
|
42680
|
-
var
|
|
42681
|
-
var
|
|
42731
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
42732
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
42682
42733
|
var PROBE_DIR = "/tmp/clawd-probe";
|
|
42683
|
-
var EVENTS_FILE =
|
|
42734
|
+
var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
|
|
42684
42735
|
var inited = false;
|
|
42685
42736
|
function ensureDir() {
|
|
42686
42737
|
if (inited) return true;
|
|
42687
42738
|
try {
|
|
42688
|
-
|
|
42739
|
+
import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
|
|
42689
42740
|
inited = true;
|
|
42690
42741
|
return true;
|
|
42691
42742
|
} catch {
|
|
@@ -42696,15 +42747,15 @@ function probeEvent(event, data = {}) {
|
|
|
42696
42747
|
try {
|
|
42697
42748
|
if (!ensureDir()) return;
|
|
42698
42749
|
const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
|
|
42699
|
-
|
|
42750
|
+
import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
|
|
42700
42751
|
} catch {
|
|
42701
42752
|
}
|
|
42702
42753
|
}
|
|
42703
42754
|
function probeDumpReplay(sessionId, payload) {
|
|
42704
42755
|
try {
|
|
42705
42756
|
if (!ensureDir()) return "";
|
|
42706
|
-
const file =
|
|
42707
|
-
|
|
42757
|
+
const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
|
|
42758
|
+
import_node_fs6.default.writeFileSync(file, payload, "utf8");
|
|
42708
42759
|
return file;
|
|
42709
42760
|
} catch {
|
|
42710
42761
|
return "";
|
|
@@ -42811,7 +42862,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
|
|
|
42811
42862
|
`derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
|
|
42812
42863
|
);
|
|
42813
42864
|
}
|
|
42814
|
-
return
|
|
42865
|
+
return import_node_path8.default.join(personaRoot, safeFileName(personaId));
|
|
42815
42866
|
}
|
|
42816
42867
|
function makeInitialState(file, subSessionMeta) {
|
|
42817
42868
|
return {
|
|
@@ -42936,10 +42987,10 @@ var SessionManager = class {
|
|
|
42936
42987
|
// <dataDir>/sessions/ 列子目录 (排除 'default').
|
|
42937
42988
|
listPersonaIdsOnDisk() {
|
|
42938
42989
|
if (!this.deps.dataDir) return [];
|
|
42939
|
-
const root = this.deps.storeFactory ?
|
|
42990
|
+
const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
|
|
42940
42991
|
let entries;
|
|
42941
42992
|
try {
|
|
42942
|
-
entries =
|
|
42993
|
+
entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
|
|
42943
42994
|
} catch (err) {
|
|
42944
42995
|
const code = err?.code;
|
|
42945
42996
|
if (code === "ENOENT") return [];
|
|
@@ -42952,7 +43003,7 @@ var SessionManager = class {
|
|
|
42952
43003
|
// 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
|
|
42953
43004
|
listGuestCapIdsForPersona(personaId) {
|
|
42954
43005
|
if (!this.deps.dataDir || !this.deps.storeFactory) return [];
|
|
42955
|
-
const root =
|
|
43006
|
+
const root = import_node_path8.default.join(
|
|
42956
43007
|
this.deps.dataDir,
|
|
42957
43008
|
"personas",
|
|
42958
43009
|
personaId,
|
|
@@ -42962,7 +43013,7 @@ var SessionManager = class {
|
|
|
42962
43013
|
);
|
|
42963
43014
|
let entries;
|
|
42964
43015
|
try {
|
|
42965
|
-
entries =
|
|
43016
|
+
entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
|
|
42966
43017
|
} catch (err) {
|
|
42967
43018
|
const code = err?.code;
|
|
42968
43019
|
if (code === "ENOENT") return [];
|
|
@@ -43081,7 +43132,7 @@ var SessionManager = class {
|
|
|
43081
43132
|
callerDisplayName
|
|
43082
43133
|
);
|
|
43083
43134
|
if (subSessionMeta?.userWorkDir) {
|
|
43084
|
-
|
|
43135
|
+
import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
|
|
43085
43136
|
}
|
|
43086
43137
|
if (scope.kind === "persona" && scope.mode === "guest") {
|
|
43087
43138
|
if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
|
|
@@ -43092,8 +43143,8 @@ var SessionManager = class {
|
|
|
43092
43143
|
const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
|
|
43093
43144
|
const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
|
|
43094
43145
|
subSessionMeta.extraSettings = JSON.stringify(settings);
|
|
43095
|
-
const home =
|
|
43096
|
-
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ?
|
|
43146
|
+
const home = import_node_os5.default.homedir();
|
|
43147
|
+
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
|
|
43097
43148
|
const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
|
|
43098
43149
|
subSessionMeta.codexSandbox = {
|
|
43099
43150
|
writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
|
|
@@ -43246,7 +43297,7 @@ var SessionManager = class {
|
|
|
43246
43297
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
|
|
43247
43298
|
}
|
|
43248
43299
|
try {
|
|
43249
|
-
const stat =
|
|
43300
|
+
const stat = import_node_fs7.default.statSync(cwd);
|
|
43250
43301
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43251
43302
|
} catch {
|
|
43252
43303
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
|
|
@@ -43777,7 +43828,7 @@ var SessionManager = class {
|
|
|
43777
43828
|
*/
|
|
43778
43829
|
createForScope(args) {
|
|
43779
43830
|
try {
|
|
43780
|
-
const stat =
|
|
43831
|
+
const stat = import_node_fs7.default.statSync(args.cwd);
|
|
43781
43832
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43782
43833
|
} catch {
|
|
43783
43834
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -43993,7 +44044,7 @@ var SessionManager = class {
|
|
|
43993
44044
|
personaId: args.targetPersona,
|
|
43994
44045
|
mode: "owner"
|
|
43995
44046
|
};
|
|
43996
|
-
const cwd =
|
|
44047
|
+
const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
43997
44048
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
43998
44049
|
const file = {
|
|
43999
44050
|
sessionId,
|
|
@@ -44058,7 +44109,7 @@ var SessionManager = class {
|
|
|
44058
44109
|
personaId: args.targetPersona,
|
|
44059
44110
|
mode: "owner"
|
|
44060
44111
|
};
|
|
44061
|
-
const cwd =
|
|
44112
|
+
const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44062
44113
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44063
44114
|
const file = {
|
|
44064
44115
|
sessionId,
|
|
@@ -44540,28 +44591,28 @@ var SessionManager = class {
|
|
|
44540
44591
|
};
|
|
44541
44592
|
|
|
44542
44593
|
// src/persona/store.ts
|
|
44543
|
-
var
|
|
44544
|
-
var
|
|
44594
|
+
var fs8 = __toESM(require("fs"), 1);
|
|
44595
|
+
var path11 = __toESM(require("path"), 1);
|
|
44545
44596
|
init_protocol();
|
|
44546
44597
|
var PersonaStore = class {
|
|
44547
44598
|
constructor(root) {
|
|
44548
44599
|
this.root = root;
|
|
44549
|
-
|
|
44600
|
+
fs8.mkdirSync(root, { recursive: true });
|
|
44550
44601
|
}
|
|
44551
44602
|
root;
|
|
44552
44603
|
personaDir(personaId) {
|
|
44553
|
-
return
|
|
44604
|
+
return path11.join(this.root, safeFileName(personaId));
|
|
44554
44605
|
}
|
|
44555
44606
|
metaPath(personaId) {
|
|
44556
|
-
return
|
|
44607
|
+
return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
|
|
44557
44608
|
}
|
|
44558
44609
|
claudeMdPath(personaId) {
|
|
44559
|
-
return
|
|
44610
|
+
return path11.join(this.personaDir(personaId), "CLAUDE.md");
|
|
44560
44611
|
}
|
|
44561
44612
|
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
44562
44613
|
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
44563
44614
|
agentsMdPath(personaId) {
|
|
44564
|
-
return
|
|
44615
|
+
return path11.join(this.personaDir(personaId), "AGENTS.md");
|
|
44565
44616
|
}
|
|
44566
44617
|
/**
|
|
44567
44618
|
* persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
@@ -44570,11 +44621,11 @@ var PersonaStore = class {
|
|
|
44570
44621
|
* spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
|
|
44571
44622
|
*/
|
|
44572
44623
|
sandboxSettingsPath(personaId) {
|
|
44573
|
-
return
|
|
44624
|
+
return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
|
|
44574
44625
|
}
|
|
44575
44626
|
write(persona, personality) {
|
|
44576
44627
|
const dir = this.personaDir(persona.personaId);
|
|
44577
|
-
|
|
44628
|
+
fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
|
|
44578
44629
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
44579
44630
|
this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
|
|
44580
44631
|
this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
|
|
@@ -44593,9 +44644,9 @@ var PersonaStore = class {
|
|
|
44593
44644
|
ensureAgentsMirror(personaId) {
|
|
44594
44645
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44595
44646
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44596
|
-
if (!
|
|
44597
|
-
if (
|
|
44598
|
-
this.atomicWrite(agentsMd,
|
|
44647
|
+
if (!fs8.existsSync(claudeMd)) return false;
|
|
44648
|
+
if (fs8.existsSync(agentsMd)) return false;
|
|
44649
|
+
this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
|
|
44599
44650
|
return true;
|
|
44600
44651
|
}
|
|
44601
44652
|
/**
|
|
@@ -44619,22 +44670,22 @@ var PersonaStore = class {
|
|
|
44619
44670
|
return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
|
|
44620
44671
|
}
|
|
44621
44672
|
codexSandboxSettingsPath(personaId) {
|
|
44622
|
-
return
|
|
44673
|
+
return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
|
|
44623
44674
|
}
|
|
44624
44675
|
/** 读 codex-sandbox.json;不存在/损坏 → null。 */
|
|
44625
44676
|
readCodexSandboxSettings(personaId) {
|
|
44626
44677
|
const p2 = this.codexSandboxSettingsPath(personaId);
|
|
44627
|
-
if (!
|
|
44678
|
+
if (!fs8.existsSync(p2)) return null;
|
|
44628
44679
|
try {
|
|
44629
|
-
return CodexSandboxSettingsSchema.parse(JSON.parse(
|
|
44680
|
+
return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
|
|
44630
44681
|
} catch {
|
|
44631
44682
|
return null;
|
|
44632
44683
|
}
|
|
44633
44684
|
}
|
|
44634
44685
|
/** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
|
|
44635
44686
|
writeCodexSandboxSettings(personaId, settings) {
|
|
44636
|
-
const dir =
|
|
44637
|
-
|
|
44687
|
+
const dir = path11.join(this.personaDir(personaId), ".clawd");
|
|
44688
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
44638
44689
|
this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
|
|
44639
44690
|
}
|
|
44640
44691
|
writeMeta(persona) {
|
|
@@ -44642,8 +44693,8 @@ var PersonaStore = class {
|
|
|
44642
44693
|
}
|
|
44643
44694
|
read(personaId) {
|
|
44644
44695
|
const p2 = this.metaPath(personaId);
|
|
44645
|
-
if (!
|
|
44646
|
-
const raw = JSON.parse(
|
|
44696
|
+
if (!fs8.existsSync(p2)) return null;
|
|
44697
|
+
const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
44647
44698
|
if (raw && typeof raw === "object" && "tokenMap" in raw) {
|
|
44648
44699
|
delete raw.tokenMap;
|
|
44649
44700
|
this.atomicWrite(p2, JSON.stringify(raw, null, 2));
|
|
@@ -44651,13 +44702,13 @@ var PersonaStore = class {
|
|
|
44651
44702
|
return PersonaFileSchema.parse(raw);
|
|
44652
44703
|
}
|
|
44653
44704
|
has(personaId) {
|
|
44654
|
-
return
|
|
44705
|
+
return fs8.existsSync(this.metaPath(personaId));
|
|
44655
44706
|
}
|
|
44656
44707
|
readPersonality(personaId) {
|
|
44657
44708
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44658
|
-
if (
|
|
44709
|
+
if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
|
|
44659
44710
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44660
|
-
if (
|
|
44711
|
+
if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
|
|
44661
44712
|
return null;
|
|
44662
44713
|
}
|
|
44663
44714
|
/**
|
|
@@ -44666,23 +44717,23 @@ var PersonaStore = class {
|
|
|
44666
44717
|
*/
|
|
44667
44718
|
readSandboxSettings(personaId) {
|
|
44668
44719
|
const p2 = this.sandboxSettingsPath(personaId);
|
|
44669
|
-
if (!
|
|
44720
|
+
if (!fs8.existsSync(p2)) return null;
|
|
44670
44721
|
try {
|
|
44671
|
-
return JSON.parse(
|
|
44722
|
+
return JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
44672
44723
|
} catch {
|
|
44673
44724
|
return null;
|
|
44674
44725
|
}
|
|
44675
44726
|
}
|
|
44676
44727
|
/** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
|
|
44677
44728
|
skillsDir(personaId) {
|
|
44678
|
-
return
|
|
44729
|
+
return path11.join(this.personaDir(personaId), ".claude", "skills");
|
|
44679
44730
|
}
|
|
44680
44731
|
/**
|
|
44681
44732
|
* Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
|
|
44682
44733
|
* 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
|
|
44683
44734
|
*/
|
|
44684
44735
|
claudeSettingsPath(personaId) {
|
|
44685
|
-
return
|
|
44736
|
+
return path11.join(this.personaDir(personaId), ".claude", "settings.json");
|
|
44686
44737
|
}
|
|
44687
44738
|
/**
|
|
44688
44739
|
* 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
|
|
@@ -44697,10 +44748,10 @@ var PersonaStore = class {
|
|
|
44697
44748
|
*/
|
|
44698
44749
|
readEnabledPlugins(personaId) {
|
|
44699
44750
|
const p2 = this.claudeSettingsPath(personaId);
|
|
44700
|
-
if (!
|
|
44751
|
+
if (!fs8.existsSync(p2)) return [];
|
|
44701
44752
|
let raw;
|
|
44702
44753
|
try {
|
|
44703
|
-
raw = JSON.parse(
|
|
44754
|
+
raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
44704
44755
|
} catch {
|
|
44705
44756
|
return [];
|
|
44706
44757
|
}
|
|
@@ -44714,22 +44765,22 @@ var PersonaStore = class {
|
|
|
44714
44765
|
return out;
|
|
44715
44766
|
}
|
|
44716
44767
|
list() {
|
|
44717
|
-
if (!
|
|
44718
|
-
return
|
|
44719
|
-
return
|
|
44768
|
+
if (!fs8.existsSync(this.root)) return [];
|
|
44769
|
+
return fs8.readdirSync(this.root).filter((name) => {
|
|
44770
|
+
return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
|
|
44720
44771
|
});
|
|
44721
44772
|
}
|
|
44722
44773
|
remove(personaId) {
|
|
44723
44774
|
const dir = this.personaDir(personaId);
|
|
44724
|
-
if (
|
|
44775
|
+
if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
|
|
44725
44776
|
}
|
|
44726
44777
|
personaDirPath(personaId) {
|
|
44727
44778
|
return this.personaDir(personaId);
|
|
44728
44779
|
}
|
|
44729
44780
|
atomicWrite(file, content) {
|
|
44730
44781
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
44731
|
-
|
|
44732
|
-
|
|
44782
|
+
fs8.writeFileSync(tmp, content, { mode: 384 });
|
|
44783
|
+
fs8.renameSync(tmp, file);
|
|
44733
44784
|
}
|
|
44734
44785
|
};
|
|
44735
44786
|
|
|
@@ -44775,9 +44826,9 @@ var PersonaRegistry = class {
|
|
|
44775
44826
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
44776
44827
|
|
|
44777
44828
|
// src/skills/scanner.ts
|
|
44778
|
-
var
|
|
44779
|
-
var
|
|
44780
|
-
var
|
|
44829
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
44830
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
44831
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
44781
44832
|
|
|
44782
44833
|
// src/skills/frontmatter.ts
|
|
44783
44834
|
var STRIP_QUOTES = /^["']|["']$/g;
|
|
@@ -44886,7 +44937,7 @@ function parseDescription(content) {
|
|
|
44886
44937
|
}
|
|
44887
44938
|
function isDirLikeSync(p2) {
|
|
44888
44939
|
try {
|
|
44889
|
-
return
|
|
44940
|
+
return import_node_fs8.default.statSync(p2).isDirectory();
|
|
44890
44941
|
} catch {
|
|
44891
44942
|
return false;
|
|
44892
44943
|
}
|
|
@@ -44894,19 +44945,19 @@ function isDirLikeSync(p2) {
|
|
|
44894
44945
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
44895
44946
|
let entries;
|
|
44896
44947
|
try {
|
|
44897
|
-
entries =
|
|
44948
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
44898
44949
|
} catch {
|
|
44899
44950
|
return;
|
|
44900
44951
|
}
|
|
44901
44952
|
for (const ent of entries) {
|
|
44902
|
-
const entryPath =
|
|
44953
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
44903
44954
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
44904
44955
|
let content;
|
|
44905
44956
|
try {
|
|
44906
|
-
content =
|
|
44957
|
+
content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
|
|
44907
44958
|
} catch {
|
|
44908
44959
|
try {
|
|
44909
|
-
content =
|
|
44960
|
+
content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
|
|
44910
44961
|
} catch {
|
|
44911
44962
|
continue;
|
|
44912
44963
|
}
|
|
@@ -44930,26 +44981,26 @@ function listSkillsForDir(dir, source) {
|
|
|
44930
44981
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
44931
44982
|
let entries;
|
|
44932
44983
|
try {
|
|
44933
|
-
entries =
|
|
44984
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
44934
44985
|
} catch {
|
|
44935
44986
|
return;
|
|
44936
44987
|
}
|
|
44937
44988
|
for (const ent of entries) {
|
|
44938
|
-
const entryPath =
|
|
44989
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
44939
44990
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
44940
44991
|
const ns = ent.name;
|
|
44941
44992
|
let subEntries;
|
|
44942
44993
|
try {
|
|
44943
|
-
subEntries =
|
|
44994
|
+
subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
|
|
44944
44995
|
} catch {
|
|
44945
44996
|
continue;
|
|
44946
44997
|
}
|
|
44947
44998
|
for (const se of subEntries) {
|
|
44948
44999
|
if (!se.name.endsWith(".md")) continue;
|
|
44949
|
-
const sePath =
|
|
45000
|
+
const sePath = import_node_path9.default.join(entryPath, se.name);
|
|
44950
45001
|
let content;
|
|
44951
45002
|
try {
|
|
44952
|
-
content =
|
|
45003
|
+
content = import_node_fs8.default.readFileSync(sePath, "utf8");
|
|
44953
45004
|
} catch {
|
|
44954
45005
|
continue;
|
|
44955
45006
|
}
|
|
@@ -44966,7 +45017,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
44966
45017
|
} else if (ent.name.endsWith(".md")) {
|
|
44967
45018
|
let content;
|
|
44968
45019
|
try {
|
|
44969
|
-
content =
|
|
45020
|
+
content = import_node_fs8.default.readFileSync(entryPath, "utf8");
|
|
44970
45021
|
} catch {
|
|
44971
45022
|
continue;
|
|
44972
45023
|
}
|
|
@@ -44982,10 +45033,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
44982
45033
|
}
|
|
44983
45034
|
}
|
|
44984
45035
|
function readInstalledPlugins(home) {
|
|
44985
|
-
const file =
|
|
45036
|
+
const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
44986
45037
|
let raw;
|
|
44987
45038
|
try {
|
|
44988
|
-
raw =
|
|
45039
|
+
raw = import_node_fs8.default.readFileSync(file, "utf8");
|
|
44989
45040
|
} catch {
|
|
44990
45041
|
return [];
|
|
44991
45042
|
}
|
|
@@ -45010,7 +45061,7 @@ var SkillsScanner = class {
|
|
|
45010
45061
|
home;
|
|
45011
45062
|
extraPluginRoots;
|
|
45012
45063
|
constructor(opts = {}) {
|
|
45013
|
-
this.home = opts.home ??
|
|
45064
|
+
this.home = opts.home ?? import_node_os6.default.homedir();
|
|
45014
45065
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
45015
45066
|
}
|
|
45016
45067
|
/**
|
|
@@ -45033,14 +45084,14 @@ var SkillsScanner = class {
|
|
|
45033
45084
|
});
|
|
45034
45085
|
}
|
|
45035
45086
|
const fsBlock = [];
|
|
45036
|
-
scanSkillDir(
|
|
45037
|
-
scanCommandDir(
|
|
45038
|
-
scanSkillDir(
|
|
45039
|
-
scanCommandDir(
|
|
45087
|
+
scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
|
|
45088
|
+
scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
|
|
45089
|
+
scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
|
|
45090
|
+
scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
|
|
45040
45091
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
45041
45092
|
for (const { name, root } of plugins) {
|
|
45042
|
-
scanSkillDir(
|
|
45043
|
-
scanCommandDir(
|
|
45093
|
+
scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
|
|
45094
|
+
scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
|
|
45044
45095
|
}
|
|
45045
45096
|
fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
|
|
45046
45097
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -45146,8 +45197,8 @@ var PersonaManager = class {
|
|
|
45146
45197
|
};
|
|
45147
45198
|
|
|
45148
45199
|
// src/persona/seed.ts
|
|
45149
|
-
var
|
|
45150
|
-
var
|
|
45200
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
45201
|
+
var path13 = __toESM(require("path"), 1);
|
|
45151
45202
|
var import_node_url = require("url");
|
|
45152
45203
|
var import_meta = {};
|
|
45153
45204
|
var DEFAULT_BYPASS_PROFILE = {
|
|
@@ -45178,16 +45229,6 @@ var DEFAULT_PERSONAS = [
|
|
|
45178
45229
|
public: false,
|
|
45179
45230
|
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45180
45231
|
},
|
|
45181
|
-
{
|
|
45182
|
-
// 工单管理员:纯操作员,按指令调 clawd-ticket MCP 增删改查 ticket。MCP 由 daemon 全局
|
|
45183
|
-
// 注入(index.ts ticket-mcp wiring),persona 端不需要单独 .mcp.json。
|
|
45184
|
-
personaId: "persona-ticket-manager",
|
|
45185
|
-
label: "\u5DE5\u5355\u7BA1\u7406\u5458",
|
|
45186
|
-
model: "opus",
|
|
45187
|
-
iconKey: "assist",
|
|
45188
|
-
public: false,
|
|
45189
|
-
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45190
|
-
},
|
|
45191
45232
|
{
|
|
45192
45233
|
personaId: "persona-feishu-assistant",
|
|
45193
45234
|
label: "\u98DE\u4E66\u52A9\u7406",
|
|
@@ -45281,14 +45322,6 @@ var DEFAULT_PERSONAS = [
|
|
|
45281
45322
|
public: false,
|
|
45282
45323
|
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45283
45324
|
},
|
|
45284
|
-
{
|
|
45285
|
-
personaId: "persona-bug-fixer",
|
|
45286
|
-
label: "Bug \u4FEE\u590D\u5E08",
|
|
45287
|
-
model: "opus",
|
|
45288
|
-
iconKey: "debug",
|
|
45289
|
-
public: false,
|
|
45290
|
-
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45291
|
-
},
|
|
45292
45325
|
{
|
|
45293
45326
|
// HTML PPT 制作师:把想法/文字/旧 PPT 转成单文件 HTML 演示稿
|
|
45294
45327
|
// bundle 含 frontend-slides skill(MIT,Zara Zhang),daemon ship 进 .claude/skills/
|
|
@@ -45335,24 +45368,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
|
|
|
45335
45368
|
if (!argv1) return null;
|
|
45336
45369
|
let real = argv1;
|
|
45337
45370
|
try {
|
|
45338
|
-
real =
|
|
45371
|
+
real = fs10.realpathSync(argv1);
|
|
45339
45372
|
} catch {
|
|
45340
45373
|
}
|
|
45341
|
-
return
|
|
45374
|
+
return path13.resolve(path13.dirname(real), sibling);
|
|
45342
45375
|
}
|
|
45343
45376
|
function findDefaultsRoot(logger) {
|
|
45344
45377
|
const candidates = [];
|
|
45345
45378
|
try {
|
|
45346
|
-
const here =
|
|
45347
|
-
candidates.push(
|
|
45348
|
-
candidates.push(
|
|
45379
|
+
const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45380
|
+
candidates.push(path13.resolve(here, "defaults"));
|
|
45381
|
+
candidates.push(path13.resolve(here, "persona-defaults"));
|
|
45349
45382
|
} catch {
|
|
45350
45383
|
}
|
|
45351
45384
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
|
|
45352
45385
|
if (fromArgv) candidates.push(fromArgv);
|
|
45353
45386
|
for (const c of candidates) {
|
|
45354
45387
|
try {
|
|
45355
|
-
if (
|
|
45388
|
+
if (fs10.statSync(c).isDirectory()) {
|
|
45356
45389
|
logger?.info("persona.defaults-root.resolved", { root: c });
|
|
45357
45390
|
return c;
|
|
45358
45391
|
}
|
|
@@ -45369,8 +45402,8 @@ function seedDefaultPersonas(args) {
|
|
|
45369
45402
|
args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
|
|
45370
45403
|
continue;
|
|
45371
45404
|
}
|
|
45372
|
-
const bundleDir =
|
|
45373
|
-
if (!
|
|
45405
|
+
const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
|
|
45406
|
+
if (!fs10.existsSync(bundleDir)) {
|
|
45374
45407
|
args.logger.warn("persona.seed.skip", {
|
|
45375
45408
|
personaId: entry.personaId,
|
|
45376
45409
|
reason: "bundle-missing",
|
|
@@ -45378,8 +45411,8 @@ function seedDefaultPersonas(args) {
|
|
|
45378
45411
|
});
|
|
45379
45412
|
continue;
|
|
45380
45413
|
}
|
|
45381
|
-
const claudeMdPath =
|
|
45382
|
-
if (!
|
|
45414
|
+
const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
|
|
45415
|
+
if (!fs10.existsSync(claudeMdPath)) {
|
|
45383
45416
|
args.logger.warn("persona.seed.skip", {
|
|
45384
45417
|
personaId: entry.personaId,
|
|
45385
45418
|
reason: "no-CLAUDE.md",
|
|
@@ -45387,7 +45420,7 @@ function seedDefaultPersonas(args) {
|
|
|
45387
45420
|
});
|
|
45388
45421
|
continue;
|
|
45389
45422
|
}
|
|
45390
|
-
const personality =
|
|
45423
|
+
const personality = fs10.readFileSync(claudeMdPath, "utf8");
|
|
45391
45424
|
const now = Date.now();
|
|
45392
45425
|
const persona = {
|
|
45393
45426
|
personaId: entry.personaId,
|
|
@@ -45413,17 +45446,17 @@ function seedDefaultPersonas(args) {
|
|
|
45413
45446
|
}
|
|
45414
45447
|
}
|
|
45415
45448
|
function skipNodeModulesUnder(srcRoot) {
|
|
45416
|
-
return (src) => !
|
|
45449
|
+
return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
|
|
45417
45450
|
}
|
|
45418
45451
|
function copyBundleExtras(srcDir, dstDir) {
|
|
45419
|
-
for (const entry of
|
|
45452
|
+
for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
|
|
45420
45453
|
if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
|
|
45421
|
-
const srcPath =
|
|
45422
|
-
const dstPath =
|
|
45454
|
+
const srcPath = path13.join(srcDir, entry.name);
|
|
45455
|
+
const dstPath = path13.join(dstDir, entry.name);
|
|
45423
45456
|
if (entry.isDirectory()) {
|
|
45424
|
-
|
|
45457
|
+
fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45425
45458
|
} else if (entry.isFile()) {
|
|
45426
|
-
|
|
45459
|
+
fs10.copyFileSync(srcPath, dstPath);
|
|
45427
45460
|
}
|
|
45428
45461
|
}
|
|
45429
45462
|
}
|
|
@@ -45431,16 +45464,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
|
|
|
45431
45464
|
function refreshDaemonManagedDirs(args) {
|
|
45432
45465
|
const entries = args.entries ?? DEFAULT_PERSONAS;
|
|
45433
45466
|
for (const entry of entries) {
|
|
45434
|
-
const bundleDir =
|
|
45435
|
-
if (!
|
|
45467
|
+
const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
|
|
45468
|
+
if (!fs10.existsSync(bundleDir)) continue;
|
|
45436
45469
|
const personaDir = args.store.personaDirPath(entry.personaId);
|
|
45437
|
-
if (!
|
|
45470
|
+
if (!fs10.existsSync(personaDir)) continue;
|
|
45438
45471
|
for (const relPath of DAEMON_MANAGED_PATHS) {
|
|
45439
|
-
const srcPath =
|
|
45440
|
-
if (!
|
|
45441
|
-
const dstPath =
|
|
45472
|
+
const srcPath = path13.join(bundleDir, relPath);
|
|
45473
|
+
if (!fs10.existsSync(srcPath)) continue;
|
|
45474
|
+
const dstPath = path13.join(personaDir, relPath);
|
|
45442
45475
|
try {
|
|
45443
|
-
|
|
45476
|
+
fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45444
45477
|
args.logger.info("persona.refresh.synced", {
|
|
45445
45478
|
personaId: entry.personaId,
|
|
45446
45479
|
path: relPath
|
|
@@ -45500,15 +45533,15 @@ function migrateCodexSandbox(args) {
|
|
|
45500
45533
|
function findDeployKitRoot(logger) {
|
|
45501
45534
|
const candidates = [];
|
|
45502
45535
|
try {
|
|
45503
|
-
const here =
|
|
45504
|
-
candidates.push(
|
|
45536
|
+
const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45537
|
+
candidates.push(path13.resolve(here, "..", "deploy-kit"));
|
|
45505
45538
|
} catch {
|
|
45506
45539
|
}
|
|
45507
45540
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
|
|
45508
45541
|
if (fromArgv) candidates.push(fromArgv);
|
|
45509
45542
|
for (const c of candidates) {
|
|
45510
45543
|
try {
|
|
45511
|
-
if (
|
|
45544
|
+
if (fs10.statSync(c).isDirectory()) {
|
|
45512
45545
|
logger?.info("persona.deploy-kit-root.resolved", { root: c });
|
|
45513
45546
|
return c;
|
|
45514
45547
|
}
|
|
@@ -45519,8 +45552,8 @@ function findDeployKitRoot(logger) {
|
|
|
45519
45552
|
return null;
|
|
45520
45553
|
}
|
|
45521
45554
|
function seedDeployKit(args) {
|
|
45522
|
-
const dst =
|
|
45523
|
-
|
|
45555
|
+
const dst = path13.join(args.dataDir, "deploy-kit");
|
|
45556
|
+
fs10.cpSync(args.deployKitBundleRoot, dst, {
|
|
45524
45557
|
recursive: true,
|
|
45525
45558
|
dereference: true,
|
|
45526
45559
|
force: false,
|
|
@@ -45529,35 +45562,35 @@ function seedDeployKit(args) {
|
|
|
45529
45562
|
args.logger.info("deploy-kit.seed.done", { dst });
|
|
45530
45563
|
}
|
|
45531
45564
|
function refreshDeployKit(args) {
|
|
45532
|
-
const dst =
|
|
45533
|
-
if (!
|
|
45565
|
+
const dst = path13.join(args.dataDir, "deploy-kit");
|
|
45566
|
+
if (!fs10.existsSync(dst)) {
|
|
45534
45567
|
seedDeployKit(args);
|
|
45535
45568
|
return;
|
|
45536
45569
|
}
|
|
45537
45570
|
for (const sub of ["scripts", "contract"]) {
|
|
45538
|
-
const s =
|
|
45539
|
-
if (
|
|
45540
|
-
|
|
45571
|
+
const s = path13.join(args.deployKitBundleRoot, sub);
|
|
45572
|
+
if (fs10.existsSync(s)) {
|
|
45573
|
+
fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
|
|
45541
45574
|
}
|
|
45542
45575
|
}
|
|
45543
|
-
const secretsSrc =
|
|
45544
|
-
if (
|
|
45545
|
-
|
|
45546
|
-
for (const f of
|
|
45576
|
+
const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
|
|
45577
|
+
if (fs10.existsSync(secretsSrc)) {
|
|
45578
|
+
fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
|
|
45579
|
+
for (const f of fs10.readdirSync(secretsSrc)) {
|
|
45547
45580
|
if (!f.endsWith(".example")) continue;
|
|
45548
|
-
|
|
45581
|
+
fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
|
|
45549
45582
|
}
|
|
45550
45583
|
}
|
|
45551
45584
|
args.logger.info("deploy-kit.refresh.done", { dst });
|
|
45552
45585
|
}
|
|
45553
45586
|
|
|
45554
45587
|
// src/share-md-viewer/load.ts
|
|
45555
|
-
var
|
|
45556
|
-
var
|
|
45588
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
45589
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
45557
45590
|
var import_node_url2 = require("url");
|
|
45558
45591
|
|
|
45559
45592
|
// src/share-md-viewer/asset-loader.ts
|
|
45560
|
-
var
|
|
45593
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
45561
45594
|
function htmlEscape(s) {
|
|
45562
45595
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
45563
45596
|
}
|
|
@@ -45565,12 +45598,12 @@ function createViewerAssetLoader(opts) {
|
|
|
45565
45598
|
let viewerTemplate;
|
|
45566
45599
|
let errorTemplate;
|
|
45567
45600
|
try {
|
|
45568
|
-
viewerTemplate =
|
|
45601
|
+
viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
|
|
45569
45602
|
} catch (err) {
|
|
45570
45603
|
throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
|
|
45571
45604
|
}
|
|
45572
45605
|
try {
|
|
45573
|
-
errorTemplate =
|
|
45606
|
+
errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
|
|
45574
45607
|
} catch (err) {
|
|
45575
45608
|
throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
|
|
45576
45609
|
}
|
|
@@ -45589,25 +45622,25 @@ var import_meta2 = {};
|
|
|
45589
45622
|
function tryLoadViewerAssets(logger) {
|
|
45590
45623
|
const candidates = [];
|
|
45591
45624
|
try {
|
|
45592
|
-
const here =
|
|
45625
|
+
const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
45593
45626
|
candidates.push(here);
|
|
45594
|
-
candidates.push(
|
|
45595
|
-
candidates.push(
|
|
45627
|
+
candidates.push(import_node_path10.default.resolve(here, ".."));
|
|
45628
|
+
candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
|
|
45596
45629
|
} catch {
|
|
45597
45630
|
}
|
|
45598
45631
|
if (process.argv[1]) {
|
|
45599
45632
|
let real = process.argv[1];
|
|
45600
45633
|
try {
|
|
45601
|
-
real =
|
|
45634
|
+
real = import_node_fs10.default.realpathSync(process.argv[1]);
|
|
45602
45635
|
} catch {
|
|
45603
45636
|
}
|
|
45604
|
-
candidates.push(
|
|
45637
|
+
candidates.push(import_node_path10.default.dirname(real));
|
|
45605
45638
|
}
|
|
45606
45639
|
for (const root of candidates) {
|
|
45607
|
-
const viewerHtmlPath =
|
|
45608
|
-
const errorHtmlPath =
|
|
45640
|
+
const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
|
|
45641
|
+
const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
|
|
45609
45642
|
try {
|
|
45610
|
-
if (
|
|
45643
|
+
if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
|
|
45611
45644
|
logger?.info("share-md-viewer.assets-root.resolved", { root });
|
|
45612
45645
|
return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
|
|
45613
45646
|
}
|
|
@@ -45622,30 +45655,30 @@ function tryLoadViewerAssets(logger) {
|
|
|
45622
45655
|
}
|
|
45623
45656
|
|
|
45624
45657
|
// src/share-ui/load.ts
|
|
45625
|
-
var
|
|
45626
|
-
var
|
|
45658
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
45659
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
45627
45660
|
var import_node_url3 = require("url");
|
|
45628
45661
|
|
|
45629
45662
|
// src/share-ui/asset-loader.ts
|
|
45630
|
-
var
|
|
45631
|
-
var
|
|
45663
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
45664
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
45632
45665
|
function createShareUiAssetLoader(opts) {
|
|
45633
45666
|
let indexHtml;
|
|
45634
45667
|
try {
|
|
45635
|
-
indexHtml =
|
|
45668
|
+
indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
|
|
45636
45669
|
} catch (err) {
|
|
45637
45670
|
throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
|
|
45638
45671
|
}
|
|
45639
|
-
const assetsDir =
|
|
45672
|
+
const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
|
|
45640
45673
|
return {
|
|
45641
45674
|
renderIndexHtml() {
|
|
45642
45675
|
return indexHtml;
|
|
45643
45676
|
},
|
|
45644
45677
|
resolveAssetPath(rel) {
|
|
45645
|
-
const resolved =
|
|
45646
|
-
if (resolved !== assetsDir && !resolved.startsWith(assetsDir +
|
|
45678
|
+
const resolved = import_node_path11.default.resolve(assetsDir, rel);
|
|
45679
|
+
if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
|
|
45647
45680
|
try {
|
|
45648
|
-
if (
|
|
45681
|
+
if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
|
|
45649
45682
|
} catch {
|
|
45650
45683
|
}
|
|
45651
45684
|
return null;
|
|
@@ -45659,28 +45692,28 @@ function bundleDirFromArgv(argv1) {
|
|
|
45659
45692
|
if (!argv1) return null;
|
|
45660
45693
|
let real = argv1;
|
|
45661
45694
|
try {
|
|
45662
|
-
real =
|
|
45695
|
+
real = import_node_fs12.default.realpathSync(argv1);
|
|
45663
45696
|
} catch {
|
|
45664
45697
|
}
|
|
45665
|
-
return
|
|
45698
|
+
return import_node_path12.default.dirname(real);
|
|
45666
45699
|
}
|
|
45667
45700
|
function tryLoadShareUi(logger) {
|
|
45668
45701
|
const candidates = [];
|
|
45669
45702
|
try {
|
|
45670
|
-
const here =
|
|
45703
|
+
const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
45671
45704
|
candidates.push(here);
|
|
45672
|
-
candidates.push(
|
|
45673
|
-
candidates.push(
|
|
45705
|
+
candidates.push(import_node_path12.default.resolve(here, ".."));
|
|
45706
|
+
candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
|
|
45674
45707
|
} catch {
|
|
45675
45708
|
}
|
|
45676
45709
|
const argvDir = bundleDirFromArgv(process.argv[1]);
|
|
45677
45710
|
if (argvDir) candidates.push(argvDir);
|
|
45678
45711
|
for (const root of candidates) {
|
|
45679
|
-
const shareUiDir =
|
|
45680
|
-
const indexHtmlPath =
|
|
45681
|
-
const assetsDir =
|
|
45712
|
+
const shareUiDir = import_node_path12.default.join(root, "share-ui");
|
|
45713
|
+
const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
|
|
45714
|
+
const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
|
|
45682
45715
|
try {
|
|
45683
|
-
if (
|
|
45716
|
+
if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
|
|
45684
45717
|
logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
|
|
45685
45718
|
return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
|
|
45686
45719
|
}
|
|
@@ -45762,20 +45795,20 @@ function buildVisitorLogin(deps) {
|
|
|
45762
45795
|
}
|
|
45763
45796
|
|
|
45764
45797
|
// src/visitor/visitor-store.ts
|
|
45765
|
-
var
|
|
45766
|
-
var
|
|
45798
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
45799
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
45767
45800
|
function createVisitorStore(opts) {
|
|
45768
|
-
const file =
|
|
45801
|
+
const file = import_node_path13.default.join(opts.dir, "visitors.json");
|
|
45769
45802
|
const read = () => {
|
|
45770
45803
|
try {
|
|
45771
|
-
return JSON.parse(
|
|
45804
|
+
return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
|
|
45772
45805
|
} catch {
|
|
45773
45806
|
return [];
|
|
45774
45807
|
}
|
|
45775
45808
|
};
|
|
45776
45809
|
const write = (rows) => {
|
|
45777
|
-
|
|
45778
|
-
|
|
45810
|
+
import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
|
|
45811
|
+
import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
|
|
45779
45812
|
};
|
|
45780
45813
|
return {
|
|
45781
45814
|
upsert(r) {
|
|
@@ -46057,8 +46090,8 @@ function turnStartInput(text) {
|
|
|
46057
46090
|
const items = [];
|
|
46058
46091
|
let leftover = text;
|
|
46059
46092
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
46060
|
-
const [marker, name,
|
|
46061
|
-
items.push({ type: "skill", name, path:
|
|
46093
|
+
const [marker, name, path68] = m2;
|
|
46094
|
+
items.push({ type: "skill", name, path: path68 });
|
|
46062
46095
|
leftover = leftover.replace(marker, "");
|
|
46063
46096
|
}
|
|
46064
46097
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -46291,8 +46324,8 @@ var CodexAdapter = class {
|
|
|
46291
46324
|
|
|
46292
46325
|
// src/tools/claude-tui.ts
|
|
46293
46326
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
46294
|
-
var
|
|
46295
|
-
var
|
|
46327
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
46328
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
46296
46329
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
46297
46330
|
|
|
46298
46331
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -47428,8 +47461,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
47428
47461
|
}
|
|
47429
47462
|
function jsonlExistsForCtx(ctx) {
|
|
47430
47463
|
if (!ctx.toolSessionId) return false;
|
|
47431
|
-
const home =
|
|
47432
|
-
const file =
|
|
47464
|
+
const home = import_node_os7.default.homedir();
|
|
47465
|
+
const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
47433
47466
|
try {
|
|
47434
47467
|
return import_node_fs16.default.statSync(file).isFile();
|
|
47435
47468
|
} catch {
|
|
@@ -47501,9 +47534,9 @@ var PersonaDispatchManager = class {
|
|
|
47501
47534
|
|
|
47502
47535
|
// src/dispatch/mcp-config.ts
|
|
47503
47536
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
47504
|
-
var
|
|
47537
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
47505
47538
|
function dispatchMcpConfigPath(dataDir) {
|
|
47506
|
-
return
|
|
47539
|
+
return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
|
|
47507
47540
|
}
|
|
47508
47541
|
function writeDispatchMcpConfig(args) {
|
|
47509
47542
|
const cfgPath = dispatchMcpConfigPath(args.dataDir);
|
|
@@ -47525,9 +47558,9 @@ function writeDispatchMcpConfig(args) {
|
|
|
47525
47558
|
|
|
47526
47559
|
// src/ticket/mcp-config.ts
|
|
47527
47560
|
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
47528
|
-
var
|
|
47561
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
47529
47562
|
function ticketMcpConfigPath(dataDir) {
|
|
47530
|
-
return
|
|
47563
|
+
return import_node_path16.default.join(dataDir, "ticket.mcp.json");
|
|
47531
47564
|
}
|
|
47532
47565
|
function writeTicketMcpConfig(args) {
|
|
47533
47566
|
const cfgPath = ticketMcpConfigPath(args.dataDir);
|
|
@@ -47555,9 +47588,9 @@ function writeTicketMcpConfig(args) {
|
|
|
47555
47588
|
|
|
47556
47589
|
// src/shift/mcp-config.ts
|
|
47557
47590
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
47558
|
-
var
|
|
47591
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
47559
47592
|
function shiftMcpConfigPath(dataDir) {
|
|
47560
|
-
return
|
|
47593
|
+
return import_node_path17.default.join(dataDir, "shift.mcp.json");
|
|
47561
47594
|
}
|
|
47562
47595
|
async function writeShiftMcpConfig(args) {
|
|
47563
47596
|
const cfgPath = shiftMcpConfigPath(args.dataDir);
|
|
@@ -47579,19 +47612,20 @@ async function writeShiftMcpConfig(args) {
|
|
|
47579
47612
|
|
|
47580
47613
|
// src/inbox/mcp-config.ts
|
|
47581
47614
|
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
47582
|
-
var
|
|
47615
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
47583
47616
|
function inboxMcpConfigPath(dataDir) {
|
|
47584
|
-
return
|
|
47617
|
+
return import_node_path18.default.join(dataDir, "inbox.mcp.json");
|
|
47585
47618
|
}
|
|
47586
47619
|
async function writeInboxMcpConfig(args) {
|
|
47587
47620
|
const cfgPath = inboxMcpConfigPath(args.dataDir);
|
|
47588
47621
|
const content = {
|
|
47589
|
-
_comment: "daemon \u542F\u52A8\u65F6\u81EA\u52A8\u751F\u6210\uFF1Bcc spawn \u901A\u8FC7 --mcp-config \u6CE8\u5165\u3002inbox/mcp-server.cjs \u662F daemon \u81EA\u5E26\u7684 stdio MCP server\uFF0C\u66B4\u9732 sendDm tool\uFF08persona \u53D7\u63A7\u53D1 P2P IM DM\uFF09\u3002",
|
|
47622
|
+
_comment: "daemon \u542F\u52A8\u65F6\u81EA\u52A8\u751F\u6210\uFF1Bcc spawn \u901A\u8FC7 --mcp-config \u6CE8\u5165\u3002inbox/mcp-server.cjs \u662F daemon \u81EA\u5E26\u7684 stdio MCP server\uFF0C\u66B4\u9732 sendDm tool\uFF08persona \u53D7\u63A7\u53D1 P2P IM DM\uFF09\u3002env.CLAWD_INBOX_LOG \u6307 server \u5199\u65E5\u5FD7\u7684 append \u6587\u4EF6\u8DEF\u5F84\u3002",
|
|
47590
47623
|
mcpServers: {
|
|
47591
47624
|
"clawd-inbox": {
|
|
47592
47625
|
type: "stdio",
|
|
47593
47626
|
command: "node",
|
|
47594
|
-
args: [args.serverScriptPath]
|
|
47627
|
+
args: [args.serverScriptPath],
|
|
47628
|
+
...args.logPath ? { env: { CLAWD_INBOX_LOG: args.logPath } } : {}
|
|
47595
47629
|
}
|
|
47596
47630
|
}
|
|
47597
47631
|
};
|
|
@@ -47602,7 +47636,7 @@ async function writeInboxMcpConfig(args) {
|
|
|
47602
47636
|
|
|
47603
47637
|
// src/shift/store.ts
|
|
47604
47638
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
47605
|
-
var
|
|
47639
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
47606
47640
|
var import_node_crypto5 = require("crypto");
|
|
47607
47641
|
|
|
47608
47642
|
// src/shift/constants.ts
|
|
@@ -47671,7 +47705,7 @@ function createShiftStore(deps) {
|
|
|
47671
47705
|
flushTimer = null;
|
|
47672
47706
|
}
|
|
47673
47707
|
const content = { version: 1, shifts };
|
|
47674
|
-
await import_promises.default.mkdir(
|
|
47708
|
+
await import_promises.default.mkdir(import_node_path19.default.dirname(deps.filePath), { recursive: true });
|
|
47675
47709
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
47676
47710
|
await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
47677
47711
|
await import_promises.default.rename(tmp, deps.filePath);
|
|
@@ -48475,13 +48509,13 @@ function mapSkillsListResponse(res) {
|
|
|
48475
48509
|
const r = s ?? {};
|
|
48476
48510
|
const name = str3(r.name);
|
|
48477
48511
|
if (!name) continue;
|
|
48478
|
-
const
|
|
48512
|
+
const path68 = str3(r.path);
|
|
48479
48513
|
const description = str3(r.description);
|
|
48480
48514
|
const isPlugin = name.includes(":");
|
|
48481
48515
|
out.push({
|
|
48482
48516
|
name,
|
|
48483
48517
|
source: isPlugin ? "plugin" : "project",
|
|
48484
|
-
...
|
|
48518
|
+
...path68 ? { path: path68 } : {},
|
|
48485
48519
|
...description ? { description } : {},
|
|
48486
48520
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
48487
48521
|
});
|
|
@@ -48521,15 +48555,15 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
48521
48555
|
|
|
48522
48556
|
// src/workspace/browser.ts
|
|
48523
48557
|
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
48524
|
-
var
|
|
48525
|
-
var
|
|
48558
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
48559
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
48526
48560
|
init_protocol();
|
|
48527
48561
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
48528
48562
|
function resolveInsideCwd(cwd, subpath) {
|
|
48529
|
-
const absCwd =
|
|
48530
|
-
const joined =
|
|
48531
|
-
const rel =
|
|
48532
|
-
if (rel.startsWith("..") ||
|
|
48563
|
+
const absCwd = import_node_path20.default.resolve(cwd);
|
|
48564
|
+
const joined = import_node_path20.default.resolve(absCwd, subpath ?? ".");
|
|
48565
|
+
const rel = import_node_path20.default.relative(absCwd, joined);
|
|
48566
|
+
if (rel.startsWith("..") || import_node_path20.default.isAbsolute(rel)) {
|
|
48533
48567
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
48534
48568
|
}
|
|
48535
48569
|
return joined;
|
|
@@ -48547,7 +48581,7 @@ function ensureCwd(cwd) {
|
|
|
48547
48581
|
}
|
|
48548
48582
|
var WorkspaceBrowser = class {
|
|
48549
48583
|
list(args) {
|
|
48550
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
48584
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
|
|
48551
48585
|
ensureCwd(cwd);
|
|
48552
48586
|
const full = resolveInsideCwd(cwd, args.path);
|
|
48553
48587
|
const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
|
|
@@ -48560,7 +48594,7 @@ var WorkspaceBrowser = class {
|
|
|
48560
48594
|
mtime: ""
|
|
48561
48595
|
};
|
|
48562
48596
|
try {
|
|
48563
|
-
const st = import_node_fs21.default.statSync(
|
|
48597
|
+
const st = import_node_fs21.default.statSync(import_node_path20.default.join(full, d.name));
|
|
48564
48598
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
48565
48599
|
if (d.isFile()) entry.size = st.size;
|
|
48566
48600
|
} catch {
|
|
@@ -48606,8 +48640,8 @@ var WorkspaceBrowser = class {
|
|
|
48606
48640
|
|
|
48607
48641
|
// src/skills/agents-scanner.ts
|
|
48608
48642
|
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
48609
|
-
var
|
|
48610
|
-
var
|
|
48643
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
48644
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
48611
48645
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
48612
48646
|
function isDirLikeSync2(p2) {
|
|
48613
48647
|
try {
|
|
@@ -48645,10 +48679,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
48645
48679
|
}
|
|
48646
48680
|
for (const ent of entries) {
|
|
48647
48681
|
if (!ent.name.endsWith(".md")) continue;
|
|
48648
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
48682
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path21.default.join(dir, ent.name)))) {
|
|
48649
48683
|
continue;
|
|
48650
48684
|
}
|
|
48651
|
-
const filePath =
|
|
48685
|
+
const filePath = import_node_path21.default.join(dir, ent.name);
|
|
48652
48686
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
48653
48687
|
if (seen.has(baseName)) continue;
|
|
48654
48688
|
seen.add(baseName);
|
|
@@ -48671,7 +48705,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48671
48705
|
return;
|
|
48672
48706
|
}
|
|
48673
48707
|
for (const ent of entries) {
|
|
48674
|
-
const childPath =
|
|
48708
|
+
const childPath = import_node_path21.default.join(dir, ent.name);
|
|
48675
48709
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
48676
48710
|
walk2(childPath, [...namespaces, ent.name]);
|
|
48677
48711
|
continue;
|
|
@@ -48696,9 +48730,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48696
48730
|
walk2(root, []);
|
|
48697
48731
|
}
|
|
48698
48732
|
function readInstalledPlugins2(home) {
|
|
48699
|
-
const pluginsDir =
|
|
48700
|
-
const v2 =
|
|
48701
|
-
const v1 =
|
|
48733
|
+
const pluginsDir = import_node_path21.default.join(home, ".claude", "plugins");
|
|
48734
|
+
const v2 = import_node_path21.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
48735
|
+
const v1 = import_node_path21.default.join(pluginsDir, "installed_plugins.json");
|
|
48702
48736
|
let raw = null;
|
|
48703
48737
|
for (const candidate of [v2, v1]) {
|
|
48704
48738
|
try {
|
|
@@ -48727,19 +48761,19 @@ function readInstalledPlugins2(home) {
|
|
|
48727
48761
|
return out;
|
|
48728
48762
|
}
|
|
48729
48763
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
48730
|
-
let cur =
|
|
48731
|
-
const fsRoot =
|
|
48764
|
+
let cur = import_node_path21.default.resolve(startCwd);
|
|
48765
|
+
const fsRoot = import_node_path21.default.parse(cur).root;
|
|
48732
48766
|
while (true) {
|
|
48733
|
-
scanAgentsDir(
|
|
48767
|
+
scanAgentsDir(import_node_path21.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
48734
48768
|
let hasGit = false;
|
|
48735
48769
|
try {
|
|
48736
|
-
hasGit = import_node_fs22.default.existsSync(
|
|
48770
|
+
hasGit = import_node_fs22.default.existsSync(import_node_path21.default.join(cur, ".git"));
|
|
48737
48771
|
} catch {
|
|
48738
48772
|
}
|
|
48739
48773
|
if (hasGit) return;
|
|
48740
48774
|
if (cur === home) return;
|
|
48741
48775
|
if (cur === fsRoot) return;
|
|
48742
|
-
const parent =
|
|
48776
|
+
const parent = import_node_path21.default.dirname(cur);
|
|
48743
48777
|
if (parent === cur) return;
|
|
48744
48778
|
cur = parent;
|
|
48745
48779
|
}
|
|
@@ -48749,7 +48783,7 @@ var AgentsScanner = class {
|
|
|
48749
48783
|
extraPluginRoots;
|
|
48750
48784
|
policyDir;
|
|
48751
48785
|
constructor(opts = {}) {
|
|
48752
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
48786
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
|
|
48753
48787
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
48754
48788
|
if (opts.policyDir !== void 0) {
|
|
48755
48789
|
this.policyDir = opts.policyDir;
|
|
@@ -48774,7 +48808,7 @@ var AgentsScanner = class {
|
|
|
48774
48808
|
}
|
|
48775
48809
|
const fsBlock = [];
|
|
48776
48810
|
scanAgentsDir(
|
|
48777
|
-
|
|
48811
|
+
import_node_path21.default.join(this.home, ".claude", "agents"),
|
|
48778
48812
|
"global",
|
|
48779
48813
|
seen,
|
|
48780
48814
|
fsBlock
|
|
@@ -48788,7 +48822,7 @@ var AgentsScanner = class {
|
|
|
48788
48822
|
...this.extraPluginRoots
|
|
48789
48823
|
];
|
|
48790
48824
|
for (const { name, root } of plugins) {
|
|
48791
|
-
const agentsRoot =
|
|
48825
|
+
const agentsRoot = import_node_path21.default.join(root, "agents");
|
|
48792
48826
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
48793
48827
|
}
|
|
48794
48828
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -48797,27 +48831,27 @@ var AgentsScanner = class {
|
|
|
48797
48831
|
|
|
48798
48832
|
// src/observer/session-observer.ts
|
|
48799
48833
|
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
48800
|
-
var
|
|
48801
|
-
var
|
|
48834
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
48835
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
48802
48836
|
init_claude_history();
|
|
48803
48837
|
|
|
48804
48838
|
// src/observer/subagent-meta-observer.ts
|
|
48805
48839
|
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
48806
|
-
var
|
|
48807
|
-
var
|
|
48840
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
48841
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
48808
48842
|
init_claude_history();
|
|
48809
48843
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
48810
48844
|
var SubagentMetaObserver = class {
|
|
48811
48845
|
constructor(opts) {
|
|
48812
48846
|
this.opts = opts;
|
|
48813
|
-
this.home = opts.home ??
|
|
48847
|
+
this.home = opts.home ?? import_node_os10.default.homedir();
|
|
48814
48848
|
}
|
|
48815
48849
|
opts;
|
|
48816
48850
|
home;
|
|
48817
48851
|
watches = /* @__PURE__ */ new Map();
|
|
48818
48852
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
48819
48853
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
48820
|
-
return
|
|
48854
|
+
return import_node_path22.default.join(
|
|
48821
48855
|
this.home,
|
|
48822
48856
|
".claude",
|
|
48823
48857
|
"projects",
|
|
@@ -48873,7 +48907,7 @@ var SubagentMetaObserver = class {
|
|
|
48873
48907
|
if (!m2) return;
|
|
48874
48908
|
const agentId = m2[1];
|
|
48875
48909
|
if (w2.emitted.has(agentId)) return;
|
|
48876
|
-
const file =
|
|
48910
|
+
const file = import_node_path22.default.join(w2.dirPath, name);
|
|
48877
48911
|
let raw;
|
|
48878
48912
|
try {
|
|
48879
48913
|
raw = import_node_fs23.default.readFileSync(file, "utf8");
|
|
@@ -48921,7 +48955,7 @@ var SubagentMetaObserver = class {
|
|
|
48921
48955
|
var SessionObserver = class {
|
|
48922
48956
|
constructor(opts) {
|
|
48923
48957
|
this.opts = opts;
|
|
48924
|
-
this.home = opts.home ??
|
|
48958
|
+
this.home = opts.home ?? import_node_os11.default.homedir();
|
|
48925
48959
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
48926
48960
|
}
|
|
48927
48961
|
opts;
|
|
@@ -48933,7 +48967,7 @@ var SessionObserver = class {
|
|
|
48933
48967
|
metaObserver;
|
|
48934
48968
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
48935
48969
|
if (override) return override;
|
|
48936
|
-
return
|
|
48970
|
+
return import_node_path23.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
48937
48971
|
}
|
|
48938
48972
|
start(args) {
|
|
48939
48973
|
this.stop(args.sessionId);
|
|
@@ -48954,10 +48988,10 @@ var SessionObserver = class {
|
|
|
48954
48988
|
prevIsRejectSentinel: false
|
|
48955
48989
|
};
|
|
48956
48990
|
try {
|
|
48957
|
-
import_node_fs24.default.mkdirSync(
|
|
48991
|
+
import_node_fs24.default.mkdirSync(import_node_path23.default.dirname(filePath), { recursive: true });
|
|
48958
48992
|
} catch {
|
|
48959
48993
|
}
|
|
48960
|
-
w2.watcher = import_node_fs24.default.watch(
|
|
48994
|
+
w2.watcher = import_node_fs24.default.watch(import_node_path23.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
48961
48995
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
48962
48996
|
this.poll(w2);
|
|
48963
48997
|
});
|
|
@@ -49839,7 +49873,7 @@ async function authenticate(token, deps) {
|
|
|
49839
49873
|
|
|
49840
49874
|
// src/permission/capability-store.ts
|
|
49841
49875
|
var fs28 = __toESM(require("fs"), 1);
|
|
49842
|
-
var
|
|
49876
|
+
var path28 = __toESM(require("path"), 1);
|
|
49843
49877
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
49844
49878
|
var FILE_VERSION = 1;
|
|
49845
49879
|
var CapabilityStore = class {
|
|
@@ -49869,7 +49903,7 @@ var CapabilityStore = class {
|
|
|
49869
49903
|
this.flush();
|
|
49870
49904
|
}
|
|
49871
49905
|
filePath() {
|
|
49872
|
-
return
|
|
49906
|
+
return path28.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
49873
49907
|
}
|
|
49874
49908
|
readFromDisk() {
|
|
49875
49909
|
const file = this.filePath();
|
|
@@ -50016,7 +50050,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
50016
50050
|
|
|
50017
50051
|
// src/inbox/inbox-store.ts
|
|
50018
50052
|
var fs30 = __toESM(require("fs"), 1);
|
|
50019
|
-
var
|
|
50053
|
+
var path29 = __toESM(require("path"), 1);
|
|
50020
50054
|
var INBOX_SUBDIR = "inbox";
|
|
50021
50055
|
var InboxStore = class {
|
|
50022
50056
|
constructor(dataDir) {
|
|
@@ -50114,10 +50148,10 @@ var InboxStore = class {
|
|
|
50114
50148
|
}
|
|
50115
50149
|
}
|
|
50116
50150
|
dirPath() {
|
|
50117
|
-
return
|
|
50151
|
+
return path29.join(this.dataDir, INBOX_SUBDIR);
|
|
50118
50152
|
}
|
|
50119
50153
|
filePath(peerDeviceId) {
|
|
50120
|
-
return
|
|
50154
|
+
return path29.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
50121
50155
|
}
|
|
50122
50156
|
};
|
|
50123
50157
|
function parseAllLines(raw) {
|
|
@@ -50206,7 +50240,7 @@ var InboxManager = class {
|
|
|
50206
50240
|
|
|
50207
50241
|
// src/state/contact-store.ts
|
|
50208
50242
|
var fs31 = __toESM(require("fs"), 1);
|
|
50209
|
-
var
|
|
50243
|
+
var path30 = __toESM(require("path"), 1);
|
|
50210
50244
|
var FILE_NAME = "contacts.json";
|
|
50211
50245
|
var ContactStore = class {
|
|
50212
50246
|
constructor(dataDir) {
|
|
@@ -50216,7 +50250,7 @@ var ContactStore = class {
|
|
|
50216
50250
|
contacts = /* @__PURE__ */ new Map();
|
|
50217
50251
|
load() {
|
|
50218
50252
|
this.contacts.clear();
|
|
50219
|
-
const file =
|
|
50253
|
+
const file = path30.join(this.dataDir, FILE_NAME);
|
|
50220
50254
|
let raw;
|
|
50221
50255
|
try {
|
|
50222
50256
|
raw = fs31.readFileSync(file, "utf8");
|
|
@@ -50262,7 +50296,7 @@ var ContactStore = class {
|
|
|
50262
50296
|
return existed;
|
|
50263
50297
|
}
|
|
50264
50298
|
flush() {
|
|
50265
|
-
const file =
|
|
50299
|
+
const file = path30.join(this.dataDir, FILE_NAME);
|
|
50266
50300
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
50267
50301
|
const content = JSON.stringify(
|
|
50268
50302
|
{ contacts: Array.from(this.contacts.values()) },
|
|
@@ -50426,52 +50460,52 @@ async function autoReverseContact(args) {
|
|
|
50426
50460
|
|
|
50427
50461
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
50428
50462
|
var fs32 = __toESM(require("fs"), 1);
|
|
50429
|
-
var
|
|
50463
|
+
var path31 = __toESM(require("path"), 1);
|
|
50430
50464
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
50431
50465
|
function migrateFlattenSessions(opts) {
|
|
50432
50466
|
const dataDir = opts.dataDir;
|
|
50433
50467
|
const now = opts.now ?? Date.now;
|
|
50434
|
-
const sessionsDir =
|
|
50435
|
-
const flagPath =
|
|
50468
|
+
const sessionsDir = path31.join(dataDir, "sessions");
|
|
50469
|
+
const flagPath = path31.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
50436
50470
|
if (existsSync3(flagPath)) {
|
|
50437
50471
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
50438
50472
|
}
|
|
50439
50473
|
let movedBare = 0;
|
|
50440
50474
|
let movedVmOwner = 0;
|
|
50441
50475
|
let archivedListener = 0;
|
|
50442
|
-
const defaultDir =
|
|
50476
|
+
const defaultDir = path31.join(sessionsDir, "default");
|
|
50443
50477
|
if (existsSync3(defaultDir)) {
|
|
50444
50478
|
for (const entry of readdirSafe(defaultDir)) {
|
|
50445
50479
|
if (!entry.endsWith(".json")) continue;
|
|
50446
|
-
const src =
|
|
50447
|
-
const dst =
|
|
50480
|
+
const src = path31.join(defaultDir, entry);
|
|
50481
|
+
const dst = path31.join(sessionsDir, entry);
|
|
50448
50482
|
fs32.renameSync(src, dst);
|
|
50449
50483
|
movedBare += 1;
|
|
50450
50484
|
}
|
|
50451
50485
|
rmdirIfEmpty(defaultDir);
|
|
50452
50486
|
}
|
|
50453
50487
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
50454
|
-
const personaDir =
|
|
50488
|
+
const personaDir = path31.join(sessionsDir, pid);
|
|
50455
50489
|
if (!isDir(personaDir)) continue;
|
|
50456
50490
|
if (pid === "default") continue;
|
|
50457
|
-
const ownerSrc =
|
|
50491
|
+
const ownerSrc = path31.join(personaDir, "owner");
|
|
50458
50492
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
50459
|
-
const ownerDst =
|
|
50493
|
+
const ownerDst = path31.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
50460
50494
|
fs32.mkdirSync(ownerDst, { recursive: true });
|
|
50461
50495
|
for (const file of readdirSafe(ownerSrc)) {
|
|
50462
50496
|
if (!file.endsWith(".json")) continue;
|
|
50463
|
-
fs32.renameSync(
|
|
50497
|
+
fs32.renameSync(path31.join(ownerSrc, file), path31.join(ownerDst, file));
|
|
50464
50498
|
movedVmOwner += 1;
|
|
50465
50499
|
}
|
|
50466
50500
|
rmdirIfEmpty(ownerSrc);
|
|
50467
50501
|
}
|
|
50468
|
-
const listenerSrc =
|
|
50502
|
+
const listenerSrc = path31.join(personaDir, "listener");
|
|
50469
50503
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
50470
|
-
const archiveDst =
|
|
50504
|
+
const archiveDst = path31.join(dataDir, ".legacy", `listener-${pid}`);
|
|
50471
50505
|
fs32.mkdirSync(archiveDst, { recursive: true });
|
|
50472
50506
|
for (const file of readdirSafe(listenerSrc)) {
|
|
50473
50507
|
if (!file.endsWith(".json")) continue;
|
|
50474
|
-
fs32.renameSync(
|
|
50508
|
+
fs32.renameSync(path31.join(listenerSrc, file), path31.join(archiveDst, file));
|
|
50475
50509
|
archivedListener += 1;
|
|
50476
50510
|
}
|
|
50477
50511
|
rmdirIfEmpty(listenerSrc);
|
|
@@ -50519,10 +50553,10 @@ function rmdirIfEmpty(p2) {
|
|
|
50519
50553
|
|
|
50520
50554
|
// src/transport/http-router.ts
|
|
50521
50555
|
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
50522
|
-
var
|
|
50556
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
50523
50557
|
|
|
50524
50558
|
// src/attachment/mime.ts
|
|
50525
|
-
var
|
|
50559
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
50526
50560
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
50527
50561
|
var EXT_TO_NATIVE_MIME = {
|
|
50528
50562
|
// 图片
|
|
@@ -50629,7 +50663,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
50629
50663
|
".mk"
|
|
50630
50664
|
]);
|
|
50631
50665
|
function lookupMime(filePathOrName) {
|
|
50632
|
-
const ext =
|
|
50666
|
+
const ext = import_node_path24.default.extname(filePathOrName).toLowerCase();
|
|
50633
50667
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
50634
50668
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
50635
50669
|
return "application/octet-stream";
|
|
@@ -50699,7 +50733,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
50699
50733
|
|
|
50700
50734
|
// src/attachment/upload.ts
|
|
50701
50735
|
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
50702
|
-
var
|
|
50736
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
50703
50737
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
50704
50738
|
var import_promises2 = require("stream/promises");
|
|
50705
50739
|
var UploadError = class extends Error {
|
|
@@ -50711,14 +50745,14 @@ var UploadError = class extends Error {
|
|
|
50711
50745
|
code;
|
|
50712
50746
|
};
|
|
50713
50747
|
function assertValidFileName(fileName) {
|
|
50714
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
50748
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path25.default.basename(fileName)) {
|
|
50715
50749
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
50716
50750
|
}
|
|
50717
50751
|
}
|
|
50718
50752
|
var HASH_PREFIX_LEN = 16;
|
|
50719
50753
|
async function writeUploadedAttachment(args) {
|
|
50720
50754
|
assertValidFileName(args.fileName);
|
|
50721
|
-
const attachmentsRoot =
|
|
50755
|
+
const attachmentsRoot = import_node_path25.default.join(args.sessionDir, ".attachments");
|
|
50722
50756
|
try {
|
|
50723
50757
|
import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
50724
50758
|
} catch (err) {
|
|
@@ -50726,7 +50760,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50726
50760
|
}
|
|
50727
50761
|
const hasher = import_node_crypto7.default.createHash("sha256");
|
|
50728
50762
|
let actualSize = 0;
|
|
50729
|
-
const tmpPath =
|
|
50763
|
+
const tmpPath = import_node_path25.default.join(
|
|
50730
50764
|
attachmentsRoot,
|
|
50731
50765
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto7.default.randomBytes(4).toString("hex")}`
|
|
50732
50766
|
);
|
|
@@ -50761,7 +50795,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50761
50795
|
);
|
|
50762
50796
|
}
|
|
50763
50797
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
50764
|
-
const hashDir =
|
|
50798
|
+
const hashDir = import_node_path25.default.join(attachmentsRoot, attachmentId);
|
|
50765
50799
|
let finalFileName;
|
|
50766
50800
|
let hashDirExists = false;
|
|
50767
50801
|
try {
|
|
@@ -50779,7 +50813,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50779
50813
|
try {
|
|
50780
50814
|
import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
|
|
50781
50815
|
finalFileName = args.fileName;
|
|
50782
|
-
import_node_fs25.default.renameSync(tmpPath,
|
|
50816
|
+
import_node_fs25.default.renameSync(tmpPath, import_node_path25.default.join(hashDir, finalFileName));
|
|
50783
50817
|
} catch (err) {
|
|
50784
50818
|
try {
|
|
50785
50819
|
import_node_fs25.default.unlinkSync(tmpPath);
|
|
@@ -50788,8 +50822,8 @@ async function writeUploadedAttachment(args) {
|
|
|
50788
50822
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
50789
50823
|
}
|
|
50790
50824
|
}
|
|
50791
|
-
const absPath =
|
|
50792
|
-
const relPath =
|
|
50825
|
+
const absPath = import_node_path25.default.join(hashDir, finalFileName);
|
|
50826
|
+
const relPath = import_node_path25.default.relative(args.sessionDir, absPath);
|
|
50793
50827
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
50794
50828
|
relPath: absPath,
|
|
50795
50829
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -50803,8 +50837,8 @@ async function writeUploadedAttachment(args) {
|
|
|
50803
50837
|
|
|
50804
50838
|
// src/extension/import.ts
|
|
50805
50839
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
50806
|
-
var
|
|
50807
|
-
var
|
|
50840
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
50841
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
50808
50842
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
50809
50843
|
var ImportError = class extends Error {
|
|
50810
50844
|
constructor(code, message) {
|
|
@@ -50821,7 +50855,7 @@ async function importZip(buf, root) {
|
|
|
50821
50855
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
50822
50856
|
}
|
|
50823
50857
|
for (const name of Object.keys(zip.files)) {
|
|
50824
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
50858
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path26.default.isAbsolute(name)) {
|
|
50825
50859
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
50826
50860
|
}
|
|
50827
50861
|
}
|
|
@@ -50854,7 +50888,7 @@ async function importZip(buf, root) {
|
|
|
50854
50888
|
);
|
|
50855
50889
|
}
|
|
50856
50890
|
}
|
|
50857
|
-
const destDir =
|
|
50891
|
+
const destDir = import_node_path26.default.join(root, manifest.id);
|
|
50858
50892
|
let destExists = false;
|
|
50859
50893
|
try {
|
|
50860
50894
|
await import_promises3.default.access(destDir);
|
|
@@ -50864,15 +50898,15 @@ async function importZip(buf, root) {
|
|
|
50864
50898
|
if (destExists) {
|
|
50865
50899
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
50866
50900
|
}
|
|
50867
|
-
const stage = await import_promises3.default.mkdtemp(
|
|
50901
|
+
const stage = await import_promises3.default.mkdtemp(import_node_path26.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
50868
50902
|
try {
|
|
50869
50903
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
50870
|
-
const dest =
|
|
50904
|
+
const dest = import_node_path26.default.join(stage, name);
|
|
50871
50905
|
if (entry.dir) {
|
|
50872
50906
|
await import_promises3.default.mkdir(dest, { recursive: true });
|
|
50873
50907
|
continue;
|
|
50874
50908
|
}
|
|
50875
|
-
await import_promises3.default.mkdir(
|
|
50909
|
+
await import_promises3.default.mkdir(import_node_path26.default.dirname(dest), { recursive: true });
|
|
50876
50910
|
const content = await entry.async("nodebuffer");
|
|
50877
50911
|
await import_promises3.default.writeFile(dest, content);
|
|
50878
50912
|
}
|
|
@@ -50903,7 +50937,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
50903
50937
|
".wasm": "application/wasm"
|
|
50904
50938
|
};
|
|
50905
50939
|
function shareUiAssetMime(filePath) {
|
|
50906
|
-
const ext =
|
|
50940
|
+
const ext = import_node_path27.default.extname(filePath).toLowerCase();
|
|
50907
50941
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
50908
50942
|
}
|
|
50909
50943
|
var DISPATCH_HEARTBEAT_MS = 25e3;
|
|
@@ -50990,7 +51024,7 @@ function isValidUploadFileName(fileName) {
|
|
|
50990
51024
|
if (fileName === "." || fileName === "..") return false;
|
|
50991
51025
|
if (fileName.startsWith(".")) return false;
|
|
50992
51026
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
50993
|
-
return fileName ===
|
|
51027
|
+
return fileName === import_node_path27.default.basename(fileName);
|
|
50994
51028
|
}
|
|
50995
51029
|
function createHttpRouter(deps) {
|
|
50996
51030
|
return async (req, res) => {
|
|
@@ -51286,7 +51320,7 @@ function createHttpRouter(deps) {
|
|
|
51286
51320
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
51287
51321
|
return true;
|
|
51288
51322
|
}
|
|
51289
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
51323
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path27.default.basename(r.absPath)));
|
|
51290
51324
|
return true;
|
|
51291
51325
|
}
|
|
51292
51326
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -51407,7 +51441,7 @@ function createHttpRouter(deps) {
|
|
|
51407
51441
|
return true;
|
|
51408
51442
|
}
|
|
51409
51443
|
let absPath;
|
|
51410
|
-
if (
|
|
51444
|
+
if (import_node_path27.default.isAbsolute(pathParam)) {
|
|
51411
51445
|
absPath = pathParam;
|
|
51412
51446
|
} else if (deps.sessionStore) {
|
|
51413
51447
|
const file = deps.sessionStore.read(sid);
|
|
@@ -51415,7 +51449,7 @@ function createHttpRouter(deps) {
|
|
|
51415
51449
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
51416
51450
|
return true;
|
|
51417
51451
|
}
|
|
51418
|
-
absPath =
|
|
51452
|
+
absPath = import_node_path27.default.join(file.cwd, pathParam);
|
|
51419
51453
|
} else {
|
|
51420
51454
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
51421
51455
|
return true;
|
|
@@ -51517,7 +51551,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51517
51551
|
return;
|
|
51518
51552
|
}
|
|
51519
51553
|
const mime = lookupMime(absPath);
|
|
51520
|
-
const basename =
|
|
51554
|
+
const basename = import_node_path27.default.basename(absPath);
|
|
51521
51555
|
res.writeHead(200, {
|
|
51522
51556
|
"Content-Type": mime,
|
|
51523
51557
|
"Content-Length": String(stat.size),
|
|
@@ -51535,7 +51569,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51535
51569
|
|
|
51536
51570
|
// src/attachment/gc.ts
|
|
51537
51571
|
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
51538
|
-
var
|
|
51572
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
51539
51573
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
51540
51574
|
function runAttachmentGc(args) {
|
|
51541
51575
|
const now = (args.now ?? Date.now)();
|
|
@@ -51544,17 +51578,17 @@ function runAttachmentGc(args) {
|
|
|
51544
51578
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
51545
51579
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
51546
51580
|
if (entry.stale) continue;
|
|
51547
|
-
if (
|
|
51581
|
+
if (import_node_path28.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
51548
51582
|
}
|
|
51549
51583
|
}
|
|
51550
51584
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
51551
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
51585
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path28.default.join(
|
|
51552
51586
|
args.dataDir,
|
|
51553
51587
|
"sessions",
|
|
51554
51588
|
...scopeSubPath(scope).map(safeFileName),
|
|
51555
51589
|
safeFileName(sessionId)
|
|
51556
51590
|
);
|
|
51557
|
-
const attRoot =
|
|
51591
|
+
const attRoot = import_node_path28.default.join(sessionDir, ".attachments");
|
|
51558
51592
|
let hashDirs;
|
|
51559
51593
|
try {
|
|
51560
51594
|
hashDirs = import_node_fs27.default.readdirSync(attRoot);
|
|
@@ -51564,7 +51598,7 @@ function runAttachmentGc(args) {
|
|
|
51564
51598
|
continue;
|
|
51565
51599
|
}
|
|
51566
51600
|
for (const hashDir of hashDirs) {
|
|
51567
|
-
const hashDirAbs =
|
|
51601
|
+
const hashDirAbs = import_node_path28.default.join(attRoot, hashDir);
|
|
51568
51602
|
let files;
|
|
51569
51603
|
try {
|
|
51570
51604
|
files = import_node_fs27.default.readdirSync(hashDirAbs);
|
|
@@ -51572,7 +51606,7 @@ function runAttachmentGc(args) {
|
|
|
51572
51606
|
continue;
|
|
51573
51607
|
}
|
|
51574
51608
|
for (const name of files) {
|
|
51575
|
-
const file =
|
|
51609
|
+
const file = import_node_path28.default.join(hashDirAbs, name);
|
|
51576
51610
|
let stat;
|
|
51577
51611
|
try {
|
|
51578
51612
|
stat = import_node_fs27.default.statSync(file);
|
|
@@ -51603,7 +51637,7 @@ function runAttachmentGc(args) {
|
|
|
51603
51637
|
|
|
51604
51638
|
// src/attachment/group.ts
|
|
51605
51639
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
51606
|
-
var
|
|
51640
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
51607
51641
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
51608
51642
|
init_protocol();
|
|
51609
51643
|
var GroupFileStore = class {
|
|
@@ -51615,11 +51649,11 @@ var GroupFileStore = class {
|
|
|
51615
51649
|
this.logger = opts.logger;
|
|
51616
51650
|
}
|
|
51617
51651
|
rootForScope(scope) {
|
|
51618
|
-
return
|
|
51652
|
+
return import_node_path29.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
51619
51653
|
}
|
|
51620
51654
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
51621
51655
|
filePath(scope, sessionId) {
|
|
51622
|
-
return
|
|
51656
|
+
return import_node_path29.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
51623
51657
|
}
|
|
51624
51658
|
cacheKey(scope, sessionId) {
|
|
51625
51659
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -51654,7 +51688,7 @@ var GroupFileStore = class {
|
|
|
51654
51688
|
}
|
|
51655
51689
|
writeFile(scope, sessionId, entries) {
|
|
51656
51690
|
const file = this.filePath(scope, sessionId);
|
|
51657
|
-
import_node_fs28.default.mkdirSync(
|
|
51691
|
+
import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(file), { recursive: true });
|
|
51658
51692
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
51659
51693
|
import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
51660
51694
|
import_node_fs28.default.renameSync(tmp, file);
|
|
@@ -51744,9 +51778,9 @@ var GroupFileStore = class {
|
|
|
51744
51778
|
|
|
51745
51779
|
// src/discovery/state-file.ts
|
|
51746
51780
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
51747
|
-
var
|
|
51781
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
51748
51782
|
function defaultStateFilePath(dataDir) {
|
|
51749
|
-
return
|
|
51783
|
+
return import_node_path30.default.join(dataDir, "state.json");
|
|
51750
51784
|
}
|
|
51751
51785
|
function isPidAlive(pid) {
|
|
51752
51786
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -51782,7 +51816,7 @@ var StateFileManager = class {
|
|
|
51782
51816
|
return { status: "stale", existing };
|
|
51783
51817
|
}
|
|
51784
51818
|
write(state) {
|
|
51785
|
-
import_node_fs29.default.mkdirSync(
|
|
51819
|
+
import_node_fs29.default.mkdirSync(import_node_path30.default.dirname(this.file), { recursive: true });
|
|
51786
51820
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
51787
51821
|
import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
51788
51822
|
import_node_fs29.default.renameSync(tmp, this.file);
|
|
@@ -51811,13 +51845,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
51811
51845
|
|
|
51812
51846
|
// src/tunnel/tunnel-manager.ts
|
|
51813
51847
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
51814
|
-
var
|
|
51848
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
51815
51849
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
51816
51850
|
var import_node_child_process9 = require("child_process");
|
|
51817
51851
|
|
|
51818
51852
|
// src/tunnel/tunnel-store.ts
|
|
51819
51853
|
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
51820
|
-
var
|
|
51854
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
51821
51855
|
var TunnelStore = class {
|
|
51822
51856
|
constructor(filePath) {
|
|
51823
51857
|
this.filePath = filePath;
|
|
@@ -51836,7 +51870,7 @@ var TunnelStore = class {
|
|
|
51836
51870
|
}
|
|
51837
51871
|
}
|
|
51838
51872
|
async set(v2) {
|
|
51839
|
-
const dir =
|
|
51873
|
+
const dir = import_node_path31.default.dirname(this.filePath);
|
|
51840
51874
|
await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
|
|
51841
51875
|
const data = JSON.stringify(v2, null, 2);
|
|
51842
51876
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -51947,8 +51981,8 @@ function escape(v2) {
|
|
|
51947
51981
|
|
|
51948
51982
|
// src/tunnel/frpc-binary.ts
|
|
51949
51983
|
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
51950
|
-
var
|
|
51951
|
-
var
|
|
51984
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
51985
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
51952
51986
|
var import_node_child_process7 = require("child_process");
|
|
51953
51987
|
var import_node_stream3 = require("stream");
|
|
51954
51988
|
var import_promises4 = require("stream/promises");
|
|
@@ -51987,13 +52021,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
51987
52021
|
}
|
|
51988
52022
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
51989
52023
|
const platform = opts.platform ?? detectPlatform();
|
|
51990
|
-
const binDir =
|
|
52024
|
+
const binDir = import_node_path32.default.join(opts.dataDir, "bin");
|
|
51991
52025
|
import_node_fs31.default.mkdirSync(binDir, { recursive: true });
|
|
51992
52026
|
cleanupStaleArtifacts(binDir);
|
|
51993
|
-
const stableBin =
|
|
52027
|
+
const stableBin = import_node_path32.default.join(binDir, "frpc");
|
|
51994
52028
|
if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
|
|
51995
52029
|
const partialBin = `${stableBin}.partial`;
|
|
51996
|
-
const tarballPath =
|
|
52030
|
+
const tarballPath = import_node_path32.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
51997
52031
|
try {
|
|
51998
52032
|
const url = frpcDownloadUrl(version2, platform);
|
|
51999
52033
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -52019,7 +52053,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
52019
52053
|
}
|
|
52020
52054
|
for (const name of entries) {
|
|
52021
52055
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
52022
|
-
const full =
|
|
52056
|
+
const full = import_node_path32.default.join(binDir, name);
|
|
52023
52057
|
try {
|
|
52024
52058
|
import_node_fs31.default.rmSync(full, { recursive: true, force: true });
|
|
52025
52059
|
} catch {
|
|
@@ -52045,7 +52079,7 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
52045
52079
|
await (0, import_promises4.pipeline)(nodeStream, out);
|
|
52046
52080
|
}
|
|
52047
52081
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
52048
|
-
const work =
|
|
52082
|
+
const work = import_node_path32.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
52049
52083
|
import_node_fs31.default.mkdirSync(work, { recursive: true });
|
|
52050
52084
|
try {
|
|
52051
52085
|
await new Promise((resolve6, reject) => {
|
|
@@ -52054,7 +52088,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
52054
52088
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
52055
52089
|
});
|
|
52056
52090
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
52057
|
-
const src =
|
|
52091
|
+
const src = import_node_path32.default.join(work, dirName, "frpc");
|
|
52058
52092
|
if (!import_node_fs31.default.existsSync(src)) {
|
|
52059
52093
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
52060
52094
|
}
|
|
@@ -52066,10 +52100,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
52066
52100
|
|
|
52067
52101
|
// src/tunnel/frpc-process.ts
|
|
52068
52102
|
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
52069
|
-
var
|
|
52103
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
52070
52104
|
var import_node_child_process8 = require("child_process");
|
|
52071
52105
|
function frpcPidFilePath(dataDir) {
|
|
52072
|
-
return
|
|
52106
|
+
return import_node_path33.default.join(dataDir, "frpc.pid");
|
|
52073
52107
|
}
|
|
52074
52108
|
function writeFrpcPid(dataDir, pid) {
|
|
52075
52109
|
try {
|
|
@@ -52111,7 +52145,7 @@ function defaultSleep(ms) {
|
|
|
52111
52145
|
}
|
|
52112
52146
|
async function killStaleFrpc(deps) {
|
|
52113
52147
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
52114
|
-
const tomlPath =
|
|
52148
|
+
const tomlPath = import_node_path33.default.join(deps.dataDir, "frpc.toml");
|
|
52115
52149
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
52116
52150
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
52117
52151
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -52183,7 +52217,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
52183
52217
|
var TunnelManager = class {
|
|
52184
52218
|
constructor(deps) {
|
|
52185
52219
|
this.deps = deps;
|
|
52186
|
-
this.store = deps.store ?? new TunnelStore(
|
|
52220
|
+
this.store = deps.store ?? new TunnelStore(import_node_path34.default.join(deps.dataDir, "tunnel.json"));
|
|
52187
52221
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
52188
52222
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
52189
52223
|
}
|
|
@@ -52310,7 +52344,7 @@ var TunnelManager = class {
|
|
|
52310
52344
|
dataDir: this.deps.dataDir,
|
|
52311
52345
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
52312
52346
|
});
|
|
52313
|
-
const tomlPath =
|
|
52347
|
+
const tomlPath = import_node_path34.default.join(this.deps.dataDir, "frpc.toml");
|
|
52314
52348
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto9.default.randomBytes(3).toString("hex")}`;
|
|
52315
52349
|
const toml = buildFrpcToml({
|
|
52316
52350
|
serverAddr: t.frpsHost,
|
|
@@ -52325,7 +52359,7 @@ var TunnelManager = class {
|
|
|
52325
52359
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
52326
52360
|
stdio: ["ignore", "pipe", "pipe"]
|
|
52327
52361
|
});
|
|
52328
|
-
const logFilePath =
|
|
52362
|
+
const logFilePath = import_node_path34.default.join(this.deps.dataDir, "frpc.log");
|
|
52329
52363
|
const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
52330
52364
|
logStream.on("error", () => {
|
|
52331
52365
|
});
|
|
@@ -52408,16 +52442,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52408
52442
|
}
|
|
52409
52443
|
|
|
52410
52444
|
// src/tunnel/device-key.ts
|
|
52411
|
-
var
|
|
52412
|
-
var
|
|
52445
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
52446
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
52413
52447
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
52414
52448
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
52415
52449
|
function deriveStableDeviceKey(opts = {}) {
|
|
52416
|
-
const hostname = opts.hostname ??
|
|
52417
|
-
const uid = opts.uid ?? (typeof
|
|
52418
|
-
const home = opts.home ??
|
|
52419
|
-
const defaultDataDir =
|
|
52420
|
-
const normalizedDataDir = opts.dataDir ?
|
|
52450
|
+
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
52451
|
+
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
52452
|
+
const home = opts.home ?? import_node_os14.default.homedir();
|
|
52453
|
+
const defaultDataDir = import_node_path35.default.resolve(import_node_path35.default.join(home, ".clawd"));
|
|
52454
|
+
const normalizedDataDir = opts.dataDir ? import_node_path35.default.resolve(opts.dataDir) : null;
|
|
52421
52455
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
52422
52456
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
52423
52457
|
return import_node_crypto10.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
@@ -52425,11 +52459,11 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
52425
52459
|
|
|
52426
52460
|
// src/auth-store.ts
|
|
52427
52461
|
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
52428
|
-
var
|
|
52462
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
52429
52463
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
52430
52464
|
var AUTH_FILE_NAME = "auth.json";
|
|
52431
52465
|
function authFilePath(dataDir) {
|
|
52432
|
-
return
|
|
52466
|
+
return import_node_path36.default.join(dataDir, AUTH_FILE_NAME);
|
|
52433
52467
|
}
|
|
52434
52468
|
function loadOrCreateAuthFile(opts) {
|
|
52435
52469
|
const file = authFilePath(opts.dataDir);
|
|
@@ -52485,7 +52519,7 @@ function readAuthFile(file) {
|
|
|
52485
52519
|
}
|
|
52486
52520
|
}
|
|
52487
52521
|
function writeAuthFile(file, content) {
|
|
52488
|
-
import_node_fs34.default.mkdirSync(
|
|
52522
|
+
import_node_fs34.default.mkdirSync(import_node_path36.default.dirname(file), { recursive: true });
|
|
52489
52523
|
import_node_fs34.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
52490
52524
|
try {
|
|
52491
52525
|
import_node_fs34.default.chmodSync(file, 384);
|
|
@@ -52495,12 +52529,12 @@ function writeAuthFile(file, content) {
|
|
|
52495
52529
|
|
|
52496
52530
|
// src/owner-profile.ts
|
|
52497
52531
|
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
52498
|
-
var
|
|
52499
|
-
var
|
|
52532
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
52533
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
52500
52534
|
var PROFILE_FILENAME = "profile.json";
|
|
52501
52535
|
function loadOwnerDisplayName(dataDir) {
|
|
52502
|
-
const fallback =
|
|
52503
|
-
const profilePath =
|
|
52536
|
+
const fallback = import_node_os15.default.userInfo().username;
|
|
52537
|
+
const profilePath = import_node_path37.default.join(dataDir, PROFILE_FILENAME);
|
|
52504
52538
|
let raw;
|
|
52505
52539
|
try {
|
|
52506
52540
|
raw = import_node_fs35.default.readFileSync(profilePath, "utf8");
|
|
@@ -52527,12 +52561,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
52527
52561
|
|
|
52528
52562
|
// src/feishu-auth/owner-identity-store.ts
|
|
52529
52563
|
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
52530
|
-
var
|
|
52564
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
52531
52565
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
52532
52566
|
var OwnerIdentityStore = class {
|
|
52533
52567
|
file;
|
|
52534
52568
|
constructor(dataDir) {
|
|
52535
|
-
this.file =
|
|
52569
|
+
this.file = import_node_path38.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
52536
52570
|
}
|
|
52537
52571
|
read() {
|
|
52538
52572
|
let raw;
|
|
@@ -52565,7 +52599,7 @@ var OwnerIdentityStore = class {
|
|
|
52565
52599
|
};
|
|
52566
52600
|
}
|
|
52567
52601
|
write(record) {
|
|
52568
|
-
import_node_fs36.default.mkdirSync(
|
|
52602
|
+
import_node_fs36.default.mkdirSync(import_node_path38.default.dirname(this.file), { recursive: true });
|
|
52569
52603
|
import_node_fs36.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
52570
52604
|
try {
|
|
52571
52605
|
import_node_fs36.default.chmodSync(this.file, 384);
|
|
@@ -52695,9 +52729,9 @@ var CentralClientError = class extends Error {
|
|
|
52695
52729
|
code;
|
|
52696
52730
|
cause;
|
|
52697
52731
|
};
|
|
52698
|
-
async function centralRequest(opts,
|
|
52732
|
+
async function centralRequest(opts, path68, init) {
|
|
52699
52733
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
52700
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52734
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path68}`;
|
|
52701
52735
|
const ctrl = new AbortController();
|
|
52702
52736
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
52703
52737
|
let res;
|
|
@@ -52840,7 +52874,7 @@ function verifyConnectToken(args) {
|
|
|
52840
52874
|
|
|
52841
52875
|
// src/feishu-auth/server-key.ts
|
|
52842
52876
|
var fs46 = __toESM(require("fs"), 1);
|
|
52843
|
-
var
|
|
52877
|
+
var path47 = __toESM(require("path"), 1);
|
|
52844
52878
|
var FILE_NAME2 = "server-signing-key.json";
|
|
52845
52879
|
var ServerKeyStore = class {
|
|
52846
52880
|
constructor(dataDir) {
|
|
@@ -52848,7 +52882,7 @@ var ServerKeyStore = class {
|
|
|
52848
52882
|
}
|
|
52849
52883
|
dataDir;
|
|
52850
52884
|
filePath() {
|
|
52851
|
-
return
|
|
52885
|
+
return path47.join(this.dataDir, FILE_NAME2);
|
|
52852
52886
|
}
|
|
52853
52887
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
52854
52888
|
read() {
|
|
@@ -52887,8 +52921,8 @@ init_protocol();
|
|
|
52887
52921
|
|
|
52888
52922
|
// src/session/fork.ts
|
|
52889
52923
|
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
52890
|
-
var
|
|
52891
|
-
var
|
|
52924
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
52925
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
52892
52926
|
init_claude_history();
|
|
52893
52927
|
function readJsonlEntries(file) {
|
|
52894
52928
|
const raw = import_node_fs37.default.readFileSync(file, "utf8");
|
|
@@ -52904,9 +52938,9 @@ function readJsonlEntries(file) {
|
|
|
52904
52938
|
return out;
|
|
52905
52939
|
}
|
|
52906
52940
|
function forkSession(input) {
|
|
52907
|
-
const baseDir = input.baseDir ??
|
|
52908
|
-
const projectDir =
|
|
52909
|
-
const sourceFile =
|
|
52941
|
+
const baseDir = input.baseDir ?? import_node_path39.default.join(import_node_os16.default.homedir(), ".claude");
|
|
52942
|
+
const projectDir = import_node_path39.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
52943
|
+
const sourceFile = import_node_path39.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
52910
52944
|
if (!import_node_fs37.default.existsSync(sourceFile)) {
|
|
52911
52945
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
52912
52946
|
}
|
|
@@ -52937,7 +52971,7 @@ function forkSession(input) {
|
|
|
52937
52971
|
}
|
|
52938
52972
|
forkedLines.push(JSON.stringify(forked));
|
|
52939
52973
|
}
|
|
52940
|
-
const forkedFilePath =
|
|
52974
|
+
const forkedFilePath = import_node_path39.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
52941
52975
|
import_node_fs37.default.mkdirSync(projectDir, { recursive: true });
|
|
52942
52976
|
import_node_fs37.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
52943
52977
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -53291,7 +53325,7 @@ function buildPermissionHandlers(deps) {
|
|
|
53291
53325
|
}
|
|
53292
53326
|
|
|
53293
53327
|
// src/handlers/history.ts
|
|
53294
|
-
var
|
|
53328
|
+
var path50 = __toESM(require("path"), 1);
|
|
53295
53329
|
init_protocol();
|
|
53296
53330
|
|
|
53297
53331
|
// src/session/recent-dirs.ts
|
|
@@ -53309,7 +53343,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
53309
53343
|
}
|
|
53310
53344
|
|
|
53311
53345
|
// src/permission/persona-paths.ts
|
|
53312
|
-
var
|
|
53346
|
+
var path49 = __toESM(require("path"), 1);
|
|
53313
53347
|
function getAllowedPersonaIds(grants, action) {
|
|
53314
53348
|
const ids = /* @__PURE__ */ new Set();
|
|
53315
53349
|
for (const g2 of grants) {
|
|
@@ -53322,42 +53356,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
53322
53356
|
return ids;
|
|
53323
53357
|
}
|
|
53324
53358
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
53325
|
-
const target =
|
|
53359
|
+
const target = path49.resolve(absPath);
|
|
53326
53360
|
if (userWorkDir) {
|
|
53327
|
-
const u =
|
|
53328
|
-
const usep = u.endsWith(
|
|
53361
|
+
const u = path49.resolve(userWorkDir);
|
|
53362
|
+
const usep = u.endsWith(path49.sep) ? "" : path49.sep;
|
|
53329
53363
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
53330
53364
|
}
|
|
53331
|
-
const root =
|
|
53332
|
-
const sep3 = root.endsWith(
|
|
53365
|
+
const root = path49.resolve(personaRoot);
|
|
53366
|
+
const sep3 = root.endsWith(path49.sep) ? "" : path49.sep;
|
|
53333
53367
|
if (!target.startsWith(root + sep3)) return false;
|
|
53334
|
-
const rel =
|
|
53368
|
+
const rel = path49.relative(root, target);
|
|
53335
53369
|
if (!rel || rel.startsWith("..")) return false;
|
|
53336
|
-
const personaId = rel.split(
|
|
53370
|
+
const personaId = rel.split(path49.sep)[0];
|
|
53337
53371
|
if (!personaId) return false;
|
|
53338
53372
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
53339
53373
|
if (allowed === "*") return true;
|
|
53340
53374
|
return allowed.has(personaId);
|
|
53341
53375
|
}
|
|
53342
53376
|
function personaIdFromPath(absPath, personaRoot) {
|
|
53343
|
-
const root =
|
|
53344
|
-
const target =
|
|
53345
|
-
const sep3 = root.endsWith(
|
|
53377
|
+
const root = path49.resolve(personaRoot);
|
|
53378
|
+
const target = path49.resolve(absPath);
|
|
53379
|
+
const sep3 = root.endsWith(path49.sep) ? "" : path49.sep;
|
|
53346
53380
|
if (!target.startsWith(root + sep3)) return null;
|
|
53347
|
-
const rel =
|
|
53381
|
+
const rel = path49.relative(root, target);
|
|
53348
53382
|
if (!rel || rel.startsWith("..")) return null;
|
|
53349
|
-
const id = rel.split(
|
|
53383
|
+
const id = rel.split(path49.sep)[0];
|
|
53350
53384
|
return id || null;
|
|
53351
53385
|
}
|
|
53352
53386
|
function isPathWithin(dir, absPath) {
|
|
53353
|
-
const d =
|
|
53354
|
-
const t =
|
|
53355
|
-
const sep3 = d.endsWith(
|
|
53387
|
+
const d = path49.resolve(dir);
|
|
53388
|
+
const t = path49.resolve(absPath);
|
|
53389
|
+
const sep3 = d.endsWith(path49.sep) ? "" : path49.sep;
|
|
53356
53390
|
return t === d || t.startsWith(d + sep3);
|
|
53357
53391
|
}
|
|
53358
53392
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
53359
53393
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
53360
|
-
return personaIdFromPath(
|
|
53394
|
+
return personaIdFromPath(path49.resolve(absPath), personaRoot) === personaId;
|
|
53361
53395
|
}
|
|
53362
53396
|
|
|
53363
53397
|
// src/handlers/history.ts
|
|
@@ -53383,7 +53417,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53383
53417
|
if (!pid) return false;
|
|
53384
53418
|
return isGuestPathAllowed(
|
|
53385
53419
|
ctx.grants,
|
|
53386
|
-
|
|
53420
|
+
path50.join(personaRoot, pid),
|
|
53387
53421
|
personaRoot,
|
|
53388
53422
|
"read",
|
|
53389
53423
|
userWorkDir
|
|
@@ -53395,7 +53429,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53395
53429
|
};
|
|
53396
53430
|
const list = async (frame, _client, ctx) => {
|
|
53397
53431
|
const args = HistoryListArgs.parse(frame);
|
|
53398
|
-
assertGuestPath(ctx,
|
|
53432
|
+
assertGuestPath(ctx, path50.resolve(args.projectPath), personaRoot, "history:list");
|
|
53399
53433
|
const sessions = await history.listSessions(args);
|
|
53400
53434
|
return { response: { type: "history:list", sessions } };
|
|
53401
53435
|
};
|
|
@@ -53427,13 +53461,13 @@ function buildHistoryHandlers(deps) {
|
|
|
53427
53461
|
};
|
|
53428
53462
|
const subagents = async (frame, _client, ctx) => {
|
|
53429
53463
|
const args = HistorySubagentsArgs.parse(frame);
|
|
53430
|
-
assertGuestPath(ctx,
|
|
53464
|
+
assertGuestPath(ctx, path50.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
53431
53465
|
const subs = await history.listSubagents(args);
|
|
53432
53466
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
53433
53467
|
};
|
|
53434
53468
|
const subagentRead = async (frame, _client, ctx) => {
|
|
53435
53469
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
53436
|
-
assertGuestPath(ctx,
|
|
53470
|
+
assertGuestPath(ctx, path50.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
53437
53471
|
const res = await history.readSubagent(args);
|
|
53438
53472
|
return { response: { type: "history:subagent-read", ...res } };
|
|
53439
53473
|
};
|
|
@@ -53442,7 +53476,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53442
53476
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
53443
53477
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
53444
53478
|
const filtered = dirs.filter(
|
|
53445
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
53479
|
+
(d) => isGuestPathAllowed(ctx.grants, path50.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
53446
53480
|
);
|
|
53447
53481
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
53448
53482
|
}
|
|
@@ -53459,8 +53493,8 @@ function buildHistoryHandlers(deps) {
|
|
|
53459
53493
|
}
|
|
53460
53494
|
|
|
53461
53495
|
// src/handlers/workspace.ts
|
|
53462
|
-
var
|
|
53463
|
-
var
|
|
53496
|
+
var path51 = __toESM(require("path"), 1);
|
|
53497
|
+
var os16 = __toESM(require("os"), 1);
|
|
53464
53498
|
init_protocol();
|
|
53465
53499
|
init_protocol();
|
|
53466
53500
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -53500,23 +53534,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53500
53534
|
const list = async (frame, _client, ctx) => {
|
|
53501
53535
|
const args = WorkspaceListArgs.parse(frame);
|
|
53502
53536
|
const isGuest = ctx?.principal.kind === "guest";
|
|
53503
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
53504
|
-
const resolvedCwd =
|
|
53505
|
-
const target = args.path ?
|
|
53537
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
53538
|
+
const resolvedCwd = path51.resolve(args.cwd ?? fallbackCwd);
|
|
53539
|
+
const target = args.path ? path51.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
53506
53540
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
53507
53541
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
53508
53542
|
return { response: { type: "workspace:list", ...res } };
|
|
53509
53543
|
};
|
|
53510
53544
|
const read = async (frame, _client, ctx) => {
|
|
53511
53545
|
const args = WorkspaceReadArgs.parse(frame);
|
|
53512
|
-
const target =
|
|
53546
|
+
const target = path51.isAbsolute(args.path) ? path51.resolve(args.path) : path51.resolve(args.cwd, args.path);
|
|
53513
53547
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
53514
53548
|
const res = workspace.read(args);
|
|
53515
53549
|
return { response: { type: "workspace:read", ...res } };
|
|
53516
53550
|
};
|
|
53517
53551
|
const skillsList = async (frame, _client, ctx) => {
|
|
53518
53552
|
const args = SkillsListArgs.parse(frame);
|
|
53519
|
-
const cwdAbs =
|
|
53553
|
+
const cwdAbs = path51.resolve(args.cwd);
|
|
53520
53554
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
53521
53555
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
53522
53556
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -53528,7 +53562,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53528
53562
|
};
|
|
53529
53563
|
const agentsList = async (frame, _client, ctx) => {
|
|
53530
53564
|
const args = AgentsListArgs.parse(frame);
|
|
53531
|
-
const cwdAbs =
|
|
53565
|
+
const cwdAbs = path51.resolve(args.cwd);
|
|
53532
53566
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
53533
53567
|
if (args.tool === "codex") {
|
|
53534
53568
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -53550,18 +53584,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53550
53584
|
}
|
|
53551
53585
|
|
|
53552
53586
|
// src/handlers/git.ts
|
|
53553
|
-
var
|
|
53587
|
+
var path53 = __toESM(require("path"), 1);
|
|
53554
53588
|
init_protocol();
|
|
53555
53589
|
init_protocol();
|
|
53556
53590
|
|
|
53557
53591
|
// src/workspace/git.ts
|
|
53558
53592
|
var import_node_child_process10 = require("child_process");
|
|
53559
53593
|
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53560
|
-
var
|
|
53594
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
53561
53595
|
var import_node_util = require("util");
|
|
53562
53596
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
53563
53597
|
function normalizePath(p2) {
|
|
53564
|
-
const resolved =
|
|
53598
|
+
const resolved = import_node_path40.default.resolve(p2);
|
|
53565
53599
|
try {
|
|
53566
53600
|
return import_node_fs38.default.realpathSync(resolved);
|
|
53567
53601
|
} catch {
|
|
@@ -53637,7 +53671,7 @@ async function listGitBranches(cwd) {
|
|
|
53637
53671
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
53638
53672
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
53639
53673
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
53640
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
53674
|
+
if (!isGuestPathAllowed(ctx.grants, path53.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
53641
53675
|
throw new ClawdError(
|
|
53642
53676
|
ERROR_CODES.UNAUTHORIZED,
|
|
53643
53677
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -54123,7 +54157,7 @@ function buildDeviceHandlers(deps) {
|
|
|
54123
54157
|
}
|
|
54124
54158
|
|
|
54125
54159
|
// src/handlers/meta.ts
|
|
54126
|
-
var
|
|
54160
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
54127
54161
|
init_protocol();
|
|
54128
54162
|
|
|
54129
54163
|
// src/version.ts
|
|
@@ -54155,7 +54189,7 @@ function buildReadyFrame(deps, client) {
|
|
|
54155
54189
|
return {
|
|
54156
54190
|
version,
|
|
54157
54191
|
protocolVersion: PROTOCOL_VERSION,
|
|
54158
|
-
hostname:
|
|
54192
|
+
hostname: import_node_os17.default.hostname(),
|
|
54159
54193
|
os: process.platform,
|
|
54160
54194
|
tools,
|
|
54161
54195
|
runningSessions: info.runningSessions,
|
|
@@ -54252,7 +54286,7 @@ function buildPersonaHandlers(deps) {
|
|
|
54252
54286
|
}
|
|
54253
54287
|
|
|
54254
54288
|
// src/handlers/attachment.ts
|
|
54255
|
-
var
|
|
54289
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
54256
54290
|
init_protocol();
|
|
54257
54291
|
init_protocol();
|
|
54258
54292
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -54332,12 +54366,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
54332
54366
|
`session ${args.sessionId} scope unresolved`
|
|
54333
54367
|
);
|
|
54334
54368
|
}
|
|
54335
|
-
const cwdAbs =
|
|
54336
|
-
const candidateAbs =
|
|
54369
|
+
const cwdAbs = import_node_path41.default.resolve(sessionFile.cwd);
|
|
54370
|
+
const candidateAbs = import_node_path41.default.isAbsolute(args.relPath) ? import_node_path41.default.resolve(args.relPath) : import_node_path41.default.resolve(cwdAbs, args.relPath);
|
|
54337
54371
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
54338
54372
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
54339
54373
|
const entry = entries.find((e) => {
|
|
54340
|
-
const storedAbs =
|
|
54374
|
+
const storedAbs = import_node_path41.default.isAbsolute(e.relPath) ? import_node_path41.default.resolve(e.relPath) : import_node_path41.default.resolve(cwdAbs, e.relPath);
|
|
54341
54375
|
return storedAbs === candidateAbs && !e.stale;
|
|
54342
54376
|
});
|
|
54343
54377
|
if (!entry) {
|
|
@@ -54362,7 +54396,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
54362
54396
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
54363
54397
|
const f = deps.sessionStore.read(sessionId);
|
|
54364
54398
|
if (!f) return;
|
|
54365
|
-
assertGuestAttachmentPath(ctx,
|
|
54399
|
+
assertGuestAttachmentPath(ctx, import_node_path41.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
54366
54400
|
}
|
|
54367
54401
|
const groupAdd = async (frame, _client, ctx) => {
|
|
54368
54402
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -54377,8 +54411,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
54377
54411
|
if (!scope) {
|
|
54378
54412
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
54379
54413
|
}
|
|
54380
|
-
const cwdAbs =
|
|
54381
|
-
const candidateAbs =
|
|
54414
|
+
const cwdAbs = import_node_path41.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
54415
|
+
const candidateAbs = import_node_path41.default.isAbsolute(args.relPath) ? import_node_path41.default.resolve(args.relPath) : import_node_path41.default.resolve(cwdAbs, args.relPath);
|
|
54382
54416
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
54383
54417
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
54384
54418
|
const size = 0;
|
|
@@ -54437,19 +54471,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
54437
54471
|
|
|
54438
54472
|
// src/handlers/extension.ts
|
|
54439
54473
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
54440
|
-
var
|
|
54474
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
54441
54475
|
init_protocol();
|
|
54442
54476
|
|
|
54443
54477
|
// src/extension/bundle-zip.ts
|
|
54444
54478
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
54445
|
-
var
|
|
54479
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
54446
54480
|
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
54447
54481
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
54448
54482
|
async function bundleExtensionDir(dir) {
|
|
54449
54483
|
const entries = await listFilesSorted(dir);
|
|
54450
54484
|
const zip = new import_jszip2.default();
|
|
54451
54485
|
for (const rel of entries) {
|
|
54452
|
-
const abs =
|
|
54486
|
+
const abs = import_node_path42.default.join(dir, rel);
|
|
54453
54487
|
const content = await import_promises5.default.readFile(abs);
|
|
54454
54488
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
54455
54489
|
}
|
|
@@ -54470,7 +54504,7 @@ async function listFilesSorted(rootDir) {
|
|
|
54470
54504
|
return out;
|
|
54471
54505
|
}
|
|
54472
54506
|
async function walk(absRoot, relPrefix, out) {
|
|
54473
|
-
const dirAbs =
|
|
54507
|
+
const dirAbs = import_node_path42.default.join(absRoot, relPrefix);
|
|
54474
54508
|
const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
|
|
54475
54509
|
for (const e of entries) {
|
|
54476
54510
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -54524,25 +54558,25 @@ function computePublishCheck(args) {
|
|
|
54524
54558
|
|
|
54525
54559
|
// src/extension/install-flow.ts
|
|
54526
54560
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
54527
|
-
var
|
|
54528
|
-
var
|
|
54561
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
54562
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
54529
54563
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
54530
54564
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
54531
54565
|
|
|
54532
54566
|
// src/extension/paths.ts
|
|
54533
|
-
var
|
|
54534
|
-
var
|
|
54567
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
54568
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
54535
54569
|
function clawdHomeRoot(override) {
|
|
54536
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
54570
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path43.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
54537
54571
|
}
|
|
54538
54572
|
function extensionsRoot(override) {
|
|
54539
|
-
return
|
|
54573
|
+
return import_node_path43.default.join(clawdHomeRoot(override), "extensions");
|
|
54540
54574
|
}
|
|
54541
54575
|
function publishedChannelsFile(override) {
|
|
54542
|
-
return
|
|
54576
|
+
return import_node_path43.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
54543
54577
|
}
|
|
54544
54578
|
function bundleCacheRoot(override) {
|
|
54545
|
-
return
|
|
54579
|
+
return import_node_path43.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
54546
54580
|
}
|
|
54547
54581
|
|
|
54548
54582
|
// src/extension/install-flow.ts
|
|
@@ -54569,7 +54603,7 @@ async function installFromChannel(args, deps) {
|
|
|
54569
54603
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54570
54604
|
}
|
|
54571
54605
|
for (const name of Object.keys(zip.files)) {
|
|
54572
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
54606
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
|
|
54573
54607
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
54574
54608
|
}
|
|
54575
54609
|
}
|
|
@@ -54601,7 +54635,7 @@ async function installFromChannel(args, deps) {
|
|
|
54601
54635
|
);
|
|
54602
54636
|
}
|
|
54603
54637
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
54604
|
-
const destDir =
|
|
54638
|
+
const destDir = import_node_path44.default.join(deps.extensionsRoot, localExtId);
|
|
54605
54639
|
let destExists = false;
|
|
54606
54640
|
try {
|
|
54607
54641
|
await import_promises6.default.access(destDir);
|
|
@@ -54615,16 +54649,16 @@ async function installFromChannel(args, deps) {
|
|
|
54615
54649
|
);
|
|
54616
54650
|
}
|
|
54617
54651
|
const stage = await import_promises6.default.mkdtemp(
|
|
54618
|
-
|
|
54652
|
+
import_node_path44.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
54619
54653
|
);
|
|
54620
54654
|
try {
|
|
54621
54655
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
54622
|
-
const dest =
|
|
54656
|
+
const dest = import_node_path44.default.join(stage, name);
|
|
54623
54657
|
if (entry.dir) {
|
|
54624
54658
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
54625
54659
|
continue;
|
|
54626
54660
|
}
|
|
54627
|
-
await import_promises6.default.mkdir(
|
|
54661
|
+
await import_promises6.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
|
|
54628
54662
|
if (name === "manifest.json") {
|
|
54629
54663
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
54630
54664
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -54645,8 +54679,8 @@ async function installFromChannel(args, deps) {
|
|
|
54645
54679
|
|
|
54646
54680
|
// src/extension/update-flow.ts
|
|
54647
54681
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
54648
|
-
var
|
|
54649
|
-
var
|
|
54682
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
54683
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
54650
54684
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
54651
54685
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
54652
54686
|
var UpdateError = class extends Error {
|
|
@@ -54662,11 +54696,11 @@ async function updateFromChannel(args, deps) {
|
|
|
54662
54696
|
channelRef.extId,
|
|
54663
54697
|
channelRef.ownerPrincipalId
|
|
54664
54698
|
);
|
|
54665
|
-
const liveDir =
|
|
54699
|
+
const liveDir = import_node_path45.default.join(deps.extensionsRoot, localExtId);
|
|
54666
54700
|
const prevDir = `${liveDir}.prev`;
|
|
54667
54701
|
let existingVersion;
|
|
54668
54702
|
try {
|
|
54669
|
-
const raw = await import_promises7.default.readFile(
|
|
54703
|
+
const raw = await import_promises7.default.readFile(import_node_path45.default.join(liveDir, "manifest.json"), "utf8");
|
|
54670
54704
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
54671
54705
|
if (!parsed2.success) {
|
|
54672
54706
|
throw new UpdateError(
|
|
@@ -54699,7 +54733,7 @@ async function updateFromChannel(args, deps) {
|
|
|
54699
54733
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54700
54734
|
}
|
|
54701
54735
|
for (const name of Object.keys(zip.files)) {
|
|
54702
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
54736
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path45.default.isAbsolute(name)) {
|
|
54703
54737
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
54704
54738
|
}
|
|
54705
54739
|
}
|
|
@@ -54734,16 +54768,16 @@ async function updateFromChannel(args, deps) {
|
|
|
54734
54768
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
54735
54769
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
54736
54770
|
const stage = await import_promises7.default.mkdtemp(
|
|
54737
|
-
|
|
54771
|
+
import_node_path45.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
54738
54772
|
);
|
|
54739
54773
|
try {
|
|
54740
54774
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
54741
|
-
const dest =
|
|
54775
|
+
const dest = import_node_path45.default.join(stage, name);
|
|
54742
54776
|
if (entry.dir) {
|
|
54743
54777
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
54744
54778
|
continue;
|
|
54745
54779
|
}
|
|
54746
|
-
await import_promises7.default.mkdir(
|
|
54780
|
+
await import_promises7.default.mkdir(import_node_path45.default.dirname(dest), { recursive: true });
|
|
54747
54781
|
if (name === "manifest.json") {
|
|
54748
54782
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
54749
54783
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -54836,7 +54870,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
54836
54870
|
);
|
|
54837
54871
|
}
|
|
54838
54872
|
}
|
|
54839
|
-
const manifestPath =
|
|
54873
|
+
const manifestPath = import_node_path46.default.join(root, extId, "manifest.json");
|
|
54840
54874
|
const manifest = await readManifest(root, extId);
|
|
54841
54875
|
const next = { ...manifest, version: newVersion };
|
|
54842
54876
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -54844,7 +54878,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
54844
54878
|
await import_promises8.default.rename(tmp, manifestPath);
|
|
54845
54879
|
}
|
|
54846
54880
|
async function readManifest(root, extId) {
|
|
54847
|
-
const file =
|
|
54881
|
+
const file = import_node_path46.default.join(root, extId, "manifest.json");
|
|
54848
54882
|
let raw;
|
|
54849
54883
|
try {
|
|
54850
54884
|
raw = await import_promises8.default.readFile(file, "utf8");
|
|
@@ -54935,7 +54969,7 @@ function buildExtensionHandlers(deps) {
|
|
|
54935
54969
|
};
|
|
54936
54970
|
async function buildSnapshotMeta(extId) {
|
|
54937
54971
|
const manifest = await readManifest(deps.root, extId);
|
|
54938
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
54972
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path46.default.join(deps.root, extId));
|
|
54939
54973
|
return { manifest, contentHash: sha256, buffer };
|
|
54940
54974
|
}
|
|
54941
54975
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -55118,7 +55152,7 @@ function buildExtensionHandlers(deps) {
|
|
|
55118
55152
|
// src/app-builder/project-store.ts
|
|
55119
55153
|
var import_node_fs39 = require("fs");
|
|
55120
55154
|
var import_node_child_process11 = require("child_process");
|
|
55121
|
-
var
|
|
55155
|
+
var import_node_path47 = require("path");
|
|
55122
55156
|
init_protocol();
|
|
55123
55157
|
var PROJECTS_DIR = "projects";
|
|
55124
55158
|
var META_FILE = ".clawd-project.json";
|
|
@@ -55132,14 +55166,14 @@ var ProjectStore = class {
|
|
|
55132
55166
|
root;
|
|
55133
55167
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
55134
55168
|
metaPath(name) {
|
|
55135
|
-
return (0,
|
|
55169
|
+
return (0, import_node_path47.join)(this.projectsRoot(), name, META_FILE);
|
|
55136
55170
|
}
|
|
55137
55171
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
55138
55172
|
projectDir(name) {
|
|
55139
|
-
return (0,
|
|
55173
|
+
return (0, import_node_path47.join)(this.projectsRoot(), name);
|
|
55140
55174
|
}
|
|
55141
55175
|
projectsRoot() {
|
|
55142
|
-
return (0,
|
|
55176
|
+
return (0, import_node_path47.join)(this.root, PROJECTS_DIR);
|
|
55143
55177
|
}
|
|
55144
55178
|
async list() {
|
|
55145
55179
|
let entries;
|
|
@@ -55442,7 +55476,7 @@ var PublishJobRegistry = class {
|
|
|
55442
55476
|
// src/app-builder/publish-job-runner.ts
|
|
55443
55477
|
var import_node_child_process13 = require("child_process");
|
|
55444
55478
|
var import_node_fs40 = require("fs");
|
|
55445
|
-
var
|
|
55479
|
+
var import_node_path48 = require("path");
|
|
55446
55480
|
|
|
55447
55481
|
// src/app-builder/publish-stage-parser.ts
|
|
55448
55482
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -55474,7 +55508,7 @@ async function startPublishJob(deps, args) {
|
|
|
55474
55508
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
55475
55509
|
}
|
|
55476
55510
|
const projDir = projectDir(args.name);
|
|
55477
|
-
const logPath = (0,
|
|
55511
|
+
const logPath = (0, import_node_path48.join)(projDir, ".publish.log");
|
|
55478
55512
|
let logStream = null;
|
|
55479
55513
|
try {
|
|
55480
55514
|
logStream = (0, import_node_fs40.createWriteStream)(logPath, { flags: "w" });
|
|
@@ -55734,7 +55768,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
55734
55768
|
|
|
55735
55769
|
// src/handlers/app-builder.ts
|
|
55736
55770
|
init_protocol();
|
|
55737
|
-
var
|
|
55771
|
+
var import_node_path49 = require("path");
|
|
55738
55772
|
var import_node_fs41 = require("fs");
|
|
55739
55773
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
55740
55774
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
@@ -55892,8 +55926,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
55892
55926
|
const project = await userStore.create(f.name, reservedPorts);
|
|
55893
55927
|
try {
|
|
55894
55928
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
55895
|
-
const templateSrcDir = (0,
|
|
55896
|
-
const scaffoldScript = (0,
|
|
55929
|
+
const templateSrcDir = (0, import_node_path49.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
55930
|
+
const scaffoldScript = (0, import_node_path49.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
55897
55931
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
55898
55932
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
55899
55933
|
name: project.name,
|
|
@@ -56114,7 +56148,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
56114
56148
|
await userStore.clearPublishJob(args.name);
|
|
56115
56149
|
}
|
|
56116
56150
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
56117
|
-
const scriptPath = (0,
|
|
56151
|
+
const scriptPath = (0, import_node_path49.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
56118
56152
|
deps.logger?.info("app-builder.publish.start", {
|
|
56119
56153
|
name: args.name,
|
|
56120
56154
|
sessionId: boundSession.sessionId,
|
|
@@ -56283,7 +56317,7 @@ function buildVisitorHandlers(deps) {
|
|
|
56283
56317
|
|
|
56284
56318
|
// src/extension/registry.ts
|
|
56285
56319
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
56286
|
-
var
|
|
56320
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
56287
56321
|
async function loadAll(root) {
|
|
56288
56322
|
let entries;
|
|
56289
56323
|
try {
|
|
@@ -56296,13 +56330,13 @@ async function loadAll(root) {
|
|
|
56296
56330
|
for (const ent of entries) {
|
|
56297
56331
|
if (!ent.isDirectory()) continue;
|
|
56298
56332
|
if (ent.name.startsWith(".")) continue;
|
|
56299
|
-
records.push(await loadOne(
|
|
56333
|
+
records.push(await loadOne(import_node_path50.default.join(root, ent.name), ent.name));
|
|
56300
56334
|
}
|
|
56301
56335
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
56302
56336
|
return records;
|
|
56303
56337
|
}
|
|
56304
56338
|
async function loadOne(dir, dirName) {
|
|
56305
|
-
const manifestPath =
|
|
56339
|
+
const manifestPath = import_node_path50.default.join(dir, "manifest.json");
|
|
56306
56340
|
let raw;
|
|
56307
56341
|
try {
|
|
56308
56342
|
raw = await import_promises9.default.readFile(manifestPath, "utf8");
|
|
@@ -56347,7 +56381,7 @@ async function loadOne(dir, dirName) {
|
|
|
56347
56381
|
|
|
56348
56382
|
// src/extension/uninstall.ts
|
|
56349
56383
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
56350
|
-
var
|
|
56384
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56351
56385
|
var UninstallError = class extends Error {
|
|
56352
56386
|
constructor(code, message) {
|
|
56353
56387
|
super(message);
|
|
@@ -56356,7 +56390,7 @@ var UninstallError = class extends Error {
|
|
|
56356
56390
|
code;
|
|
56357
56391
|
};
|
|
56358
56392
|
async function uninstall(deps) {
|
|
56359
|
-
const dir =
|
|
56393
|
+
const dir = import_node_path51.default.join(deps.root, deps.extId);
|
|
56360
56394
|
try {
|
|
56361
56395
|
await import_promises10.default.access(dir);
|
|
56362
56396
|
} catch {
|
|
@@ -56925,7 +56959,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
56925
56959
|
|
|
56926
56960
|
// src/extension/runtime.ts
|
|
56927
56961
|
var import_node_child_process15 = require("child_process");
|
|
56928
|
-
var
|
|
56962
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
56929
56963
|
var import_promises11 = require("timers/promises");
|
|
56930
56964
|
|
|
56931
56965
|
// src/extension/port-allocator.ts
|
|
@@ -57026,7 +57060,7 @@ var Runtime = class {
|
|
|
57026
57060
|
/\$CLAWOS_EXT_PORT/g,
|
|
57027
57061
|
String(port)
|
|
57028
57062
|
);
|
|
57029
|
-
const dir =
|
|
57063
|
+
const dir = import_node_path52.default.join(this.root, extId);
|
|
57030
57064
|
const env = {
|
|
57031
57065
|
...process.env,
|
|
57032
57066
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -57138,7 +57172,7 @@ ${handle.stderrTail}`
|
|
|
57138
57172
|
|
|
57139
57173
|
// src/extension/published-channels.ts
|
|
57140
57174
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
57141
|
-
var
|
|
57175
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
57142
57176
|
init_zod();
|
|
57143
57177
|
var PublishedChannelsError = class extends Error {
|
|
57144
57178
|
constructor(code, message) {
|
|
@@ -57237,7 +57271,7 @@ var PublishedChannelStore = class {
|
|
|
57237
57271
|
)
|
|
57238
57272
|
};
|
|
57239
57273
|
const tmp = `${this.filePath}.tmp`;
|
|
57240
|
-
await import_promises12.default.mkdir(
|
|
57274
|
+
await import_promises12.default.mkdir(import_node_path53.default.dirname(this.filePath), { recursive: true });
|
|
57241
57275
|
await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
57242
57276
|
await import_promises12.default.rename(tmp, this.filePath);
|
|
57243
57277
|
}
|
|
@@ -57245,7 +57279,7 @@ var PublishedChannelStore = class {
|
|
|
57245
57279
|
|
|
57246
57280
|
// src/extension/bundle-cache.ts
|
|
57247
57281
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
57248
|
-
var
|
|
57282
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
57249
57283
|
var BundleCache = class {
|
|
57250
57284
|
constructor(rootDir) {
|
|
57251
57285
|
this.rootDir = rootDir;
|
|
@@ -57254,14 +57288,14 @@ var BundleCache = class {
|
|
|
57254
57288
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
57255
57289
|
async write(snapshotHash, buffer) {
|
|
57256
57290
|
await import_promises13.default.mkdir(this.rootDir, { recursive: true });
|
|
57257
|
-
const file =
|
|
57291
|
+
const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57258
57292
|
const tmp = `${file}.tmp`;
|
|
57259
57293
|
await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
|
|
57260
57294
|
await import_promises13.default.rename(tmp, file);
|
|
57261
57295
|
}
|
|
57262
57296
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
57263
57297
|
async read(snapshotHash) {
|
|
57264
|
-
const file =
|
|
57298
|
+
const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57265
57299
|
try {
|
|
57266
57300
|
return await import_promises13.default.readFile(file);
|
|
57267
57301
|
} catch (e) {
|
|
@@ -57271,7 +57305,7 @@ var BundleCache = class {
|
|
|
57271
57305
|
}
|
|
57272
57306
|
/** Idempotent — missing file is not an error. */
|
|
57273
57307
|
async delete(snapshotHash) {
|
|
57274
|
-
const file =
|
|
57308
|
+
const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57275
57309
|
await import_promises13.default.rm(file, { force: true });
|
|
57276
57310
|
}
|
|
57277
57311
|
};
|
|
@@ -57292,11 +57326,11 @@ async function startDaemon(config) {
|
|
|
57292
57326
|
},
|
|
57293
57327
|
source: "daemon",
|
|
57294
57328
|
sampling: logShippingCfg.sampling,
|
|
57295
|
-
homeDir:
|
|
57329
|
+
homeDir: import_node_os21.default.homedir()
|
|
57296
57330
|
});
|
|
57297
57331
|
const logger = createLogger({
|
|
57298
57332
|
level: config.logLevel,
|
|
57299
|
-
file:
|
|
57333
|
+
file: import_node_path55.default.join(config.dataDir, "clawd.log"),
|
|
57300
57334
|
logClient
|
|
57301
57335
|
});
|
|
57302
57336
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
@@ -57436,8 +57470,8 @@ async function startDaemon(config) {
|
|
|
57436
57470
|
const agents = new AgentsScanner();
|
|
57437
57471
|
const history = new ClaudeHistoryReader();
|
|
57438
57472
|
let transport = null;
|
|
57439
|
-
const personaStore = new PersonaStore(
|
|
57440
|
-
const usersRoot =
|
|
57473
|
+
const personaStore = new PersonaStore(import_node_path55.default.join(config.dataDir, "personas"));
|
|
57474
|
+
const usersRoot = import_node_path55.default.join(config.dataDir, "users");
|
|
57441
57475
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
57442
57476
|
if (defaultsRoot) {
|
|
57443
57477
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -57457,17 +57491,17 @@ async function startDaemon(config) {
|
|
|
57457
57491
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
57458
57492
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
57459
57493
|
const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
|
|
57460
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
57494
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path55.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
57461
57495
|
const dispatchServerCandidates = [
|
|
57462
|
-
|
|
57496
|
+
import_node_path55.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
57463
57497
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
57464
|
-
|
|
57498
|
+
import_node_path55.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
57465
57499
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
57466
57500
|
];
|
|
57467
57501
|
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57468
57502
|
let dispatchMcpConfigPath2;
|
|
57469
57503
|
if (dispatchServerScriptPath) {
|
|
57470
|
-
const dispatchLogPath =
|
|
57504
|
+
const dispatchLogPath = import_node_path55.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
57471
57505
|
dispatchMcpConfigPath2 = writeDispatchMcpConfig({
|
|
57472
57506
|
dataDir: config.dataDir,
|
|
57473
57507
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -57484,15 +57518,15 @@ async function startDaemon(config) {
|
|
|
57484
57518
|
});
|
|
57485
57519
|
}
|
|
57486
57520
|
const ticketServerCandidates = [
|
|
57487
|
-
|
|
57488
|
-
|
|
57521
|
+
import_node_path55.default.join(here, "ticket", "mcp-server.cjs"),
|
|
57522
|
+
import_node_path55.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
57489
57523
|
];
|
|
57490
57524
|
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57491
57525
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
57492
57526
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
57493
57527
|
let ticketMcpConfigPath2;
|
|
57494
57528
|
if (ticketServerScriptPath && ticketOwnerUnionId) {
|
|
57495
|
-
const ticketLogPath =
|
|
57529
|
+
const ticketLogPath = import_node_path55.default.join(config.dataDir, "ticket-mcp-server.log");
|
|
57496
57530
|
ticketMcpConfigPath2 = writeTicketMcpConfig({
|
|
57497
57531
|
dataDir: config.dataDir,
|
|
57498
57532
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -57513,13 +57547,13 @@ async function startDaemon(config) {
|
|
|
57513
57547
|
});
|
|
57514
57548
|
}
|
|
57515
57549
|
const shiftServerCandidates = [
|
|
57516
|
-
|
|
57517
|
-
|
|
57550
|
+
import_node_path55.default.join(here, "shift", "mcp-server.cjs"),
|
|
57551
|
+
import_node_path55.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
57518
57552
|
];
|
|
57519
57553
|
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57520
57554
|
let shiftMcpConfigPath2;
|
|
57521
57555
|
if (shiftServerScriptPath) {
|
|
57522
|
-
const shiftLogPath =
|
|
57556
|
+
const shiftLogPath = import_node_path55.default.join(config.dataDir, "shift-mcp-server.log");
|
|
57523
57557
|
shiftMcpConfigPath2 = await writeShiftMcpConfig({
|
|
57524
57558
|
dataDir: config.dataDir,
|
|
57525
57559
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -57537,19 +57571,22 @@ async function startDaemon(config) {
|
|
|
57537
57571
|
);
|
|
57538
57572
|
}
|
|
57539
57573
|
const inboxServerCandidates = [
|
|
57540
|
-
|
|
57541
|
-
|
|
57574
|
+
import_node_path55.default.join(here, "inbox", "mcp-server.cjs"),
|
|
57575
|
+
import_node_path55.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
57542
57576
|
];
|
|
57543
57577
|
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57544
57578
|
let inboxMcpConfigPath2;
|
|
57545
57579
|
if (inboxServerScriptPath) {
|
|
57580
|
+
const inboxLogPath = import_node_path55.default.join(config.dataDir, "inbox-mcp-server.log");
|
|
57546
57581
|
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
57547
57582
|
dataDir: config.dataDir,
|
|
57548
|
-
serverScriptPath: inboxServerScriptPath
|
|
57583
|
+
serverScriptPath: inboxServerScriptPath,
|
|
57584
|
+
logPath: inboxLogPath
|
|
57549
57585
|
});
|
|
57550
57586
|
logger.info("inbox.mcp.json written", {
|
|
57551
57587
|
path: inboxMcpConfigPath2,
|
|
57552
|
-
server: inboxServerScriptPath
|
|
57588
|
+
server: inboxServerScriptPath,
|
|
57589
|
+
serverLog: inboxLogPath
|
|
57553
57590
|
});
|
|
57554
57591
|
} else {
|
|
57555
57592
|
logger.warn(
|
|
@@ -57558,7 +57595,7 @@ async function startDaemon(config) {
|
|
|
57558
57595
|
);
|
|
57559
57596
|
}
|
|
57560
57597
|
const shiftStore = createShiftStore({
|
|
57561
|
-
filePath:
|
|
57598
|
+
filePath: import_node_path55.default.join(config.dataDir, "shift.json"),
|
|
57562
57599
|
ownerIdProvider: () => ownerPrincipalId,
|
|
57563
57600
|
now: () => Date.now()
|
|
57564
57601
|
});
|
|
@@ -57576,7 +57613,7 @@ async function startDaemon(config) {
|
|
|
57576
57613
|
getAdapter,
|
|
57577
57614
|
historyReader: history,
|
|
57578
57615
|
dataDir: config.dataDir,
|
|
57579
|
-
personaRoot:
|
|
57616
|
+
personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
|
|
57580
57617
|
usersRoot,
|
|
57581
57618
|
personaStore,
|
|
57582
57619
|
ownerDisplayName,
|
|
@@ -57619,7 +57656,7 @@ async function startDaemon(config) {
|
|
|
57619
57656
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
57620
57657
|
attachmentGroup: {
|
|
57621
57658
|
onFileEdit: (input) => {
|
|
57622
|
-
const absPath =
|
|
57659
|
+
const absPath = import_node_path55.default.isAbsolute(input.relPath) ? input.relPath : import_node_path55.default.join(input.cwd, input.relPath);
|
|
57623
57660
|
let size = 0;
|
|
57624
57661
|
try {
|
|
57625
57662
|
size = import_node_fs42.default.statSync(absPath).size;
|
|
@@ -57820,11 +57857,11 @@ async function startDaemon(config) {
|
|
|
57820
57857
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
57821
57858
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
57822
57859
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
57823
|
-
personaRoot:
|
|
57860
|
+
personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
|
|
57824
57861
|
usersRoot
|
|
57825
57862
|
},
|
|
57826
57863
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
57827
|
-
personaRoot:
|
|
57864
|
+
personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
|
|
57828
57865
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
57829
57866
|
usersRoot,
|
|
57830
57867
|
// capability:list / delete handler 依赖
|
|
@@ -57933,11 +57970,11 @@ async function startDaemon(config) {
|
|
|
57933
57970
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
57934
57971
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
57935
57972
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
57936
|
-
appBuilderPersonaRoot:
|
|
57973
|
+
appBuilderPersonaRoot: import_node_path55.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
57937
57974
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
57938
|
-
deployKitRoot:
|
|
57975
|
+
deployKitRoot: import_node_path55.default.join(config.dataDir, "deploy-kit"),
|
|
57939
57976
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
57940
|
-
resolvePersonaRoot: (personaId) =>
|
|
57977
|
+
resolvePersonaRoot: (personaId) => import_node_path55.default.join(config.dataDir, "personas", personaId),
|
|
57941
57978
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
57942
57979
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
57943
57980
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -57980,8 +58017,8 @@ async function startDaemon(config) {
|
|
|
57980
58017
|
}
|
|
57981
58018
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
57982
58019
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
57983
|
-
sourceJsonlPath =
|
|
57984
|
-
|
|
58020
|
+
sourceJsonlPath = import_node_path55.default.join(
|
|
58021
|
+
import_node_os21.default.homedir(),
|
|
57985
58022
|
".claude",
|
|
57986
58023
|
"projects",
|
|
57987
58024
|
cwdToHashDir(sourceFile.cwd),
|
|
@@ -58280,8 +58317,8 @@ async function startDaemon(config) {
|
|
|
58280
58317
|
const lines = [
|
|
58281
58318
|
`Tunnel: ${r.url}`,
|
|
58282
58319
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
58283
|
-
`Frpc config: ${
|
|
58284
|
-
`Frpc log: ${
|
|
58320
|
+
`Frpc config: ${import_node_path55.default.join(config.dataDir, "frpc.toml")}`,
|
|
58321
|
+
`Frpc log: ${import_node_path55.default.join(config.dataDir, "frpc.log")}`
|
|
58285
58322
|
];
|
|
58286
58323
|
const width = Math.max(...lines.map((l) => l.length));
|
|
58287
58324
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -58294,7 +58331,7 @@ ${bar}
|
|
|
58294
58331
|
|
|
58295
58332
|
`);
|
|
58296
58333
|
try {
|
|
58297
|
-
const connectPath =
|
|
58334
|
+
const connectPath = import_node_path55.default.join(config.dataDir, "connect.txt");
|
|
58298
58335
|
import_node_fs42.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
58299
58336
|
} catch {
|
|
58300
58337
|
}
|
|
@@ -58367,7 +58404,7 @@ ${bar}
|
|
|
58367
58404
|
};
|
|
58368
58405
|
}
|
|
58369
58406
|
function migrateDropPersonsDir(dataDir) {
|
|
58370
|
-
const dir =
|
|
58407
|
+
const dir = import_node_path55.default.join(dataDir, "persons");
|
|
58371
58408
|
try {
|
|
58372
58409
|
import_node_fs42.default.rmSync(dir, { recursive: true, force: true });
|
|
58373
58410
|
} catch {
|