@clawos-dev/clawd 0.2.191-beta.383.956b6ae → 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 +596 -563
- package/dist/dispatch/mcp-server.cjs +1 -1
- 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,9 +47612,9 @@ 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);
|
|
@@ -47603,7 +47636,7 @@ async function writeInboxMcpConfig(args) {
|
|
|
47603
47636
|
|
|
47604
47637
|
// src/shift/store.ts
|
|
47605
47638
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
47606
|
-
var
|
|
47639
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
47607
47640
|
var import_node_crypto5 = require("crypto");
|
|
47608
47641
|
|
|
47609
47642
|
// src/shift/constants.ts
|
|
@@ -47672,7 +47705,7 @@ function createShiftStore(deps) {
|
|
|
47672
47705
|
flushTimer = null;
|
|
47673
47706
|
}
|
|
47674
47707
|
const content = { version: 1, shifts };
|
|
47675
|
-
await import_promises.default.mkdir(
|
|
47708
|
+
await import_promises.default.mkdir(import_node_path19.default.dirname(deps.filePath), { recursive: true });
|
|
47676
47709
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
47677
47710
|
await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
47678
47711
|
await import_promises.default.rename(tmp, deps.filePath);
|
|
@@ -48476,13 +48509,13 @@ function mapSkillsListResponse(res) {
|
|
|
48476
48509
|
const r = s ?? {};
|
|
48477
48510
|
const name = str3(r.name);
|
|
48478
48511
|
if (!name) continue;
|
|
48479
|
-
const
|
|
48512
|
+
const path68 = str3(r.path);
|
|
48480
48513
|
const description = str3(r.description);
|
|
48481
48514
|
const isPlugin = name.includes(":");
|
|
48482
48515
|
out.push({
|
|
48483
48516
|
name,
|
|
48484
48517
|
source: isPlugin ? "plugin" : "project",
|
|
48485
|
-
...
|
|
48518
|
+
...path68 ? { path: path68 } : {},
|
|
48486
48519
|
...description ? { description } : {},
|
|
48487
48520
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
48488
48521
|
});
|
|
@@ -48522,15 +48555,15 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
48522
48555
|
|
|
48523
48556
|
// src/workspace/browser.ts
|
|
48524
48557
|
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
48525
|
-
var
|
|
48526
|
-
var
|
|
48558
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
48559
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
48527
48560
|
init_protocol();
|
|
48528
48561
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
48529
48562
|
function resolveInsideCwd(cwd, subpath) {
|
|
48530
|
-
const absCwd =
|
|
48531
|
-
const joined =
|
|
48532
|
-
const rel =
|
|
48533
|
-
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)) {
|
|
48534
48567
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
48535
48568
|
}
|
|
48536
48569
|
return joined;
|
|
@@ -48548,7 +48581,7 @@ function ensureCwd(cwd) {
|
|
|
48548
48581
|
}
|
|
48549
48582
|
var WorkspaceBrowser = class {
|
|
48550
48583
|
list(args) {
|
|
48551
|
-
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();
|
|
48552
48585
|
ensureCwd(cwd);
|
|
48553
48586
|
const full = resolveInsideCwd(cwd, args.path);
|
|
48554
48587
|
const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
|
|
@@ -48561,7 +48594,7 @@ var WorkspaceBrowser = class {
|
|
|
48561
48594
|
mtime: ""
|
|
48562
48595
|
};
|
|
48563
48596
|
try {
|
|
48564
|
-
const st = import_node_fs21.default.statSync(
|
|
48597
|
+
const st = import_node_fs21.default.statSync(import_node_path20.default.join(full, d.name));
|
|
48565
48598
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
48566
48599
|
if (d.isFile()) entry.size = st.size;
|
|
48567
48600
|
} catch {
|
|
@@ -48607,8 +48640,8 @@ var WorkspaceBrowser = class {
|
|
|
48607
48640
|
|
|
48608
48641
|
// src/skills/agents-scanner.ts
|
|
48609
48642
|
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
48610
|
-
var
|
|
48611
|
-
var
|
|
48643
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
48644
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
48612
48645
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
48613
48646
|
function isDirLikeSync2(p2) {
|
|
48614
48647
|
try {
|
|
@@ -48646,10 +48679,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
48646
48679
|
}
|
|
48647
48680
|
for (const ent of entries) {
|
|
48648
48681
|
if (!ent.name.endsWith(".md")) continue;
|
|
48649
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
48682
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path21.default.join(dir, ent.name)))) {
|
|
48650
48683
|
continue;
|
|
48651
48684
|
}
|
|
48652
|
-
const filePath =
|
|
48685
|
+
const filePath = import_node_path21.default.join(dir, ent.name);
|
|
48653
48686
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
48654
48687
|
if (seen.has(baseName)) continue;
|
|
48655
48688
|
seen.add(baseName);
|
|
@@ -48672,7 +48705,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48672
48705
|
return;
|
|
48673
48706
|
}
|
|
48674
48707
|
for (const ent of entries) {
|
|
48675
|
-
const childPath =
|
|
48708
|
+
const childPath = import_node_path21.default.join(dir, ent.name);
|
|
48676
48709
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
48677
48710
|
walk2(childPath, [...namespaces, ent.name]);
|
|
48678
48711
|
continue;
|
|
@@ -48697,9 +48730,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48697
48730
|
walk2(root, []);
|
|
48698
48731
|
}
|
|
48699
48732
|
function readInstalledPlugins2(home) {
|
|
48700
|
-
const pluginsDir =
|
|
48701
|
-
const v2 =
|
|
48702
|
-
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");
|
|
48703
48736
|
let raw = null;
|
|
48704
48737
|
for (const candidate of [v2, v1]) {
|
|
48705
48738
|
try {
|
|
@@ -48728,19 +48761,19 @@ function readInstalledPlugins2(home) {
|
|
|
48728
48761
|
return out;
|
|
48729
48762
|
}
|
|
48730
48763
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
48731
|
-
let cur =
|
|
48732
|
-
const fsRoot =
|
|
48764
|
+
let cur = import_node_path21.default.resolve(startCwd);
|
|
48765
|
+
const fsRoot = import_node_path21.default.parse(cur).root;
|
|
48733
48766
|
while (true) {
|
|
48734
|
-
scanAgentsDir(
|
|
48767
|
+
scanAgentsDir(import_node_path21.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
48735
48768
|
let hasGit = false;
|
|
48736
48769
|
try {
|
|
48737
|
-
hasGit = import_node_fs22.default.existsSync(
|
|
48770
|
+
hasGit = import_node_fs22.default.existsSync(import_node_path21.default.join(cur, ".git"));
|
|
48738
48771
|
} catch {
|
|
48739
48772
|
}
|
|
48740
48773
|
if (hasGit) return;
|
|
48741
48774
|
if (cur === home) return;
|
|
48742
48775
|
if (cur === fsRoot) return;
|
|
48743
|
-
const parent =
|
|
48776
|
+
const parent = import_node_path21.default.dirname(cur);
|
|
48744
48777
|
if (parent === cur) return;
|
|
48745
48778
|
cur = parent;
|
|
48746
48779
|
}
|
|
@@ -48750,7 +48783,7 @@ var AgentsScanner = class {
|
|
|
48750
48783
|
extraPluginRoots;
|
|
48751
48784
|
policyDir;
|
|
48752
48785
|
constructor(opts = {}) {
|
|
48753
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
48786
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
|
|
48754
48787
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
48755
48788
|
if (opts.policyDir !== void 0) {
|
|
48756
48789
|
this.policyDir = opts.policyDir;
|
|
@@ -48775,7 +48808,7 @@ var AgentsScanner = class {
|
|
|
48775
48808
|
}
|
|
48776
48809
|
const fsBlock = [];
|
|
48777
48810
|
scanAgentsDir(
|
|
48778
|
-
|
|
48811
|
+
import_node_path21.default.join(this.home, ".claude", "agents"),
|
|
48779
48812
|
"global",
|
|
48780
48813
|
seen,
|
|
48781
48814
|
fsBlock
|
|
@@ -48789,7 +48822,7 @@ var AgentsScanner = class {
|
|
|
48789
48822
|
...this.extraPluginRoots
|
|
48790
48823
|
];
|
|
48791
48824
|
for (const { name, root } of plugins) {
|
|
48792
|
-
const agentsRoot =
|
|
48825
|
+
const agentsRoot = import_node_path21.default.join(root, "agents");
|
|
48793
48826
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
48794
48827
|
}
|
|
48795
48828
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -48798,27 +48831,27 @@ var AgentsScanner = class {
|
|
|
48798
48831
|
|
|
48799
48832
|
// src/observer/session-observer.ts
|
|
48800
48833
|
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
48801
|
-
var
|
|
48802
|
-
var
|
|
48834
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
48835
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
48803
48836
|
init_claude_history();
|
|
48804
48837
|
|
|
48805
48838
|
// src/observer/subagent-meta-observer.ts
|
|
48806
48839
|
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
48807
|
-
var
|
|
48808
|
-
var
|
|
48840
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
48841
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
48809
48842
|
init_claude_history();
|
|
48810
48843
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
48811
48844
|
var SubagentMetaObserver = class {
|
|
48812
48845
|
constructor(opts) {
|
|
48813
48846
|
this.opts = opts;
|
|
48814
|
-
this.home = opts.home ??
|
|
48847
|
+
this.home = opts.home ?? import_node_os10.default.homedir();
|
|
48815
48848
|
}
|
|
48816
48849
|
opts;
|
|
48817
48850
|
home;
|
|
48818
48851
|
watches = /* @__PURE__ */ new Map();
|
|
48819
48852
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
48820
48853
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
48821
|
-
return
|
|
48854
|
+
return import_node_path22.default.join(
|
|
48822
48855
|
this.home,
|
|
48823
48856
|
".claude",
|
|
48824
48857
|
"projects",
|
|
@@ -48874,7 +48907,7 @@ var SubagentMetaObserver = class {
|
|
|
48874
48907
|
if (!m2) return;
|
|
48875
48908
|
const agentId = m2[1];
|
|
48876
48909
|
if (w2.emitted.has(agentId)) return;
|
|
48877
|
-
const file =
|
|
48910
|
+
const file = import_node_path22.default.join(w2.dirPath, name);
|
|
48878
48911
|
let raw;
|
|
48879
48912
|
try {
|
|
48880
48913
|
raw = import_node_fs23.default.readFileSync(file, "utf8");
|
|
@@ -48922,7 +48955,7 @@ var SubagentMetaObserver = class {
|
|
|
48922
48955
|
var SessionObserver = class {
|
|
48923
48956
|
constructor(opts) {
|
|
48924
48957
|
this.opts = opts;
|
|
48925
|
-
this.home = opts.home ??
|
|
48958
|
+
this.home = opts.home ?? import_node_os11.default.homedir();
|
|
48926
48959
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
48927
48960
|
}
|
|
48928
48961
|
opts;
|
|
@@ -48934,7 +48967,7 @@ var SessionObserver = class {
|
|
|
48934
48967
|
metaObserver;
|
|
48935
48968
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
48936
48969
|
if (override) return override;
|
|
48937
|
-
return
|
|
48970
|
+
return import_node_path23.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
48938
48971
|
}
|
|
48939
48972
|
start(args) {
|
|
48940
48973
|
this.stop(args.sessionId);
|
|
@@ -48955,10 +48988,10 @@ var SessionObserver = class {
|
|
|
48955
48988
|
prevIsRejectSentinel: false
|
|
48956
48989
|
};
|
|
48957
48990
|
try {
|
|
48958
|
-
import_node_fs24.default.mkdirSync(
|
|
48991
|
+
import_node_fs24.default.mkdirSync(import_node_path23.default.dirname(filePath), { recursive: true });
|
|
48959
48992
|
} catch {
|
|
48960
48993
|
}
|
|
48961
|
-
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) => {
|
|
48962
48995
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
48963
48996
|
this.poll(w2);
|
|
48964
48997
|
});
|
|
@@ -49840,7 +49873,7 @@ async function authenticate(token, deps) {
|
|
|
49840
49873
|
|
|
49841
49874
|
// src/permission/capability-store.ts
|
|
49842
49875
|
var fs28 = __toESM(require("fs"), 1);
|
|
49843
|
-
var
|
|
49876
|
+
var path28 = __toESM(require("path"), 1);
|
|
49844
49877
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
49845
49878
|
var FILE_VERSION = 1;
|
|
49846
49879
|
var CapabilityStore = class {
|
|
@@ -49870,7 +49903,7 @@ var CapabilityStore = class {
|
|
|
49870
49903
|
this.flush();
|
|
49871
49904
|
}
|
|
49872
49905
|
filePath() {
|
|
49873
|
-
return
|
|
49906
|
+
return path28.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
49874
49907
|
}
|
|
49875
49908
|
readFromDisk() {
|
|
49876
49909
|
const file = this.filePath();
|
|
@@ -50017,7 +50050,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
50017
50050
|
|
|
50018
50051
|
// src/inbox/inbox-store.ts
|
|
50019
50052
|
var fs30 = __toESM(require("fs"), 1);
|
|
50020
|
-
var
|
|
50053
|
+
var path29 = __toESM(require("path"), 1);
|
|
50021
50054
|
var INBOX_SUBDIR = "inbox";
|
|
50022
50055
|
var InboxStore = class {
|
|
50023
50056
|
constructor(dataDir) {
|
|
@@ -50115,10 +50148,10 @@ var InboxStore = class {
|
|
|
50115
50148
|
}
|
|
50116
50149
|
}
|
|
50117
50150
|
dirPath() {
|
|
50118
|
-
return
|
|
50151
|
+
return path29.join(this.dataDir, INBOX_SUBDIR);
|
|
50119
50152
|
}
|
|
50120
50153
|
filePath(peerDeviceId) {
|
|
50121
|
-
return
|
|
50154
|
+
return path29.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
50122
50155
|
}
|
|
50123
50156
|
};
|
|
50124
50157
|
function parseAllLines(raw) {
|
|
@@ -50207,7 +50240,7 @@ var InboxManager = class {
|
|
|
50207
50240
|
|
|
50208
50241
|
// src/state/contact-store.ts
|
|
50209
50242
|
var fs31 = __toESM(require("fs"), 1);
|
|
50210
|
-
var
|
|
50243
|
+
var path30 = __toESM(require("path"), 1);
|
|
50211
50244
|
var FILE_NAME = "contacts.json";
|
|
50212
50245
|
var ContactStore = class {
|
|
50213
50246
|
constructor(dataDir) {
|
|
@@ -50217,7 +50250,7 @@ var ContactStore = class {
|
|
|
50217
50250
|
contacts = /* @__PURE__ */ new Map();
|
|
50218
50251
|
load() {
|
|
50219
50252
|
this.contacts.clear();
|
|
50220
|
-
const file =
|
|
50253
|
+
const file = path30.join(this.dataDir, FILE_NAME);
|
|
50221
50254
|
let raw;
|
|
50222
50255
|
try {
|
|
50223
50256
|
raw = fs31.readFileSync(file, "utf8");
|
|
@@ -50263,7 +50296,7 @@ var ContactStore = class {
|
|
|
50263
50296
|
return existed;
|
|
50264
50297
|
}
|
|
50265
50298
|
flush() {
|
|
50266
|
-
const file =
|
|
50299
|
+
const file = path30.join(this.dataDir, FILE_NAME);
|
|
50267
50300
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
50268
50301
|
const content = JSON.stringify(
|
|
50269
50302
|
{ contacts: Array.from(this.contacts.values()) },
|
|
@@ -50427,52 +50460,52 @@ async function autoReverseContact(args) {
|
|
|
50427
50460
|
|
|
50428
50461
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
50429
50462
|
var fs32 = __toESM(require("fs"), 1);
|
|
50430
|
-
var
|
|
50463
|
+
var path31 = __toESM(require("path"), 1);
|
|
50431
50464
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
50432
50465
|
function migrateFlattenSessions(opts) {
|
|
50433
50466
|
const dataDir = opts.dataDir;
|
|
50434
50467
|
const now = opts.now ?? Date.now;
|
|
50435
|
-
const sessionsDir =
|
|
50436
|
-
const flagPath =
|
|
50468
|
+
const sessionsDir = path31.join(dataDir, "sessions");
|
|
50469
|
+
const flagPath = path31.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
50437
50470
|
if (existsSync3(flagPath)) {
|
|
50438
50471
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
50439
50472
|
}
|
|
50440
50473
|
let movedBare = 0;
|
|
50441
50474
|
let movedVmOwner = 0;
|
|
50442
50475
|
let archivedListener = 0;
|
|
50443
|
-
const defaultDir =
|
|
50476
|
+
const defaultDir = path31.join(sessionsDir, "default");
|
|
50444
50477
|
if (existsSync3(defaultDir)) {
|
|
50445
50478
|
for (const entry of readdirSafe(defaultDir)) {
|
|
50446
50479
|
if (!entry.endsWith(".json")) continue;
|
|
50447
|
-
const src =
|
|
50448
|
-
const dst =
|
|
50480
|
+
const src = path31.join(defaultDir, entry);
|
|
50481
|
+
const dst = path31.join(sessionsDir, entry);
|
|
50449
50482
|
fs32.renameSync(src, dst);
|
|
50450
50483
|
movedBare += 1;
|
|
50451
50484
|
}
|
|
50452
50485
|
rmdirIfEmpty(defaultDir);
|
|
50453
50486
|
}
|
|
50454
50487
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
50455
|
-
const personaDir =
|
|
50488
|
+
const personaDir = path31.join(sessionsDir, pid);
|
|
50456
50489
|
if (!isDir(personaDir)) continue;
|
|
50457
50490
|
if (pid === "default") continue;
|
|
50458
|
-
const ownerSrc =
|
|
50491
|
+
const ownerSrc = path31.join(personaDir, "owner");
|
|
50459
50492
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
50460
|
-
const ownerDst =
|
|
50493
|
+
const ownerDst = path31.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
50461
50494
|
fs32.mkdirSync(ownerDst, { recursive: true });
|
|
50462
50495
|
for (const file of readdirSafe(ownerSrc)) {
|
|
50463
50496
|
if (!file.endsWith(".json")) continue;
|
|
50464
|
-
fs32.renameSync(
|
|
50497
|
+
fs32.renameSync(path31.join(ownerSrc, file), path31.join(ownerDst, file));
|
|
50465
50498
|
movedVmOwner += 1;
|
|
50466
50499
|
}
|
|
50467
50500
|
rmdirIfEmpty(ownerSrc);
|
|
50468
50501
|
}
|
|
50469
|
-
const listenerSrc =
|
|
50502
|
+
const listenerSrc = path31.join(personaDir, "listener");
|
|
50470
50503
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
50471
|
-
const archiveDst =
|
|
50504
|
+
const archiveDst = path31.join(dataDir, ".legacy", `listener-${pid}`);
|
|
50472
50505
|
fs32.mkdirSync(archiveDst, { recursive: true });
|
|
50473
50506
|
for (const file of readdirSafe(listenerSrc)) {
|
|
50474
50507
|
if (!file.endsWith(".json")) continue;
|
|
50475
|
-
fs32.renameSync(
|
|
50508
|
+
fs32.renameSync(path31.join(listenerSrc, file), path31.join(archiveDst, file));
|
|
50476
50509
|
archivedListener += 1;
|
|
50477
50510
|
}
|
|
50478
50511
|
rmdirIfEmpty(listenerSrc);
|
|
@@ -50520,10 +50553,10 @@ function rmdirIfEmpty(p2) {
|
|
|
50520
50553
|
|
|
50521
50554
|
// src/transport/http-router.ts
|
|
50522
50555
|
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
50523
|
-
var
|
|
50556
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
50524
50557
|
|
|
50525
50558
|
// src/attachment/mime.ts
|
|
50526
|
-
var
|
|
50559
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
50527
50560
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
50528
50561
|
var EXT_TO_NATIVE_MIME = {
|
|
50529
50562
|
// 图片
|
|
@@ -50630,7 +50663,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
50630
50663
|
".mk"
|
|
50631
50664
|
]);
|
|
50632
50665
|
function lookupMime(filePathOrName) {
|
|
50633
|
-
const ext =
|
|
50666
|
+
const ext = import_node_path24.default.extname(filePathOrName).toLowerCase();
|
|
50634
50667
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
50635
50668
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
50636
50669
|
return "application/octet-stream";
|
|
@@ -50700,7 +50733,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
50700
50733
|
|
|
50701
50734
|
// src/attachment/upload.ts
|
|
50702
50735
|
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
50703
|
-
var
|
|
50736
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
50704
50737
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
50705
50738
|
var import_promises2 = require("stream/promises");
|
|
50706
50739
|
var UploadError = class extends Error {
|
|
@@ -50712,14 +50745,14 @@ var UploadError = class extends Error {
|
|
|
50712
50745
|
code;
|
|
50713
50746
|
};
|
|
50714
50747
|
function assertValidFileName(fileName) {
|
|
50715
|
-
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)) {
|
|
50716
50749
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
50717
50750
|
}
|
|
50718
50751
|
}
|
|
50719
50752
|
var HASH_PREFIX_LEN = 16;
|
|
50720
50753
|
async function writeUploadedAttachment(args) {
|
|
50721
50754
|
assertValidFileName(args.fileName);
|
|
50722
|
-
const attachmentsRoot =
|
|
50755
|
+
const attachmentsRoot = import_node_path25.default.join(args.sessionDir, ".attachments");
|
|
50723
50756
|
try {
|
|
50724
50757
|
import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
50725
50758
|
} catch (err) {
|
|
@@ -50727,7 +50760,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50727
50760
|
}
|
|
50728
50761
|
const hasher = import_node_crypto7.default.createHash("sha256");
|
|
50729
50762
|
let actualSize = 0;
|
|
50730
|
-
const tmpPath =
|
|
50763
|
+
const tmpPath = import_node_path25.default.join(
|
|
50731
50764
|
attachmentsRoot,
|
|
50732
50765
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto7.default.randomBytes(4).toString("hex")}`
|
|
50733
50766
|
);
|
|
@@ -50762,7 +50795,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50762
50795
|
);
|
|
50763
50796
|
}
|
|
50764
50797
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
50765
|
-
const hashDir =
|
|
50798
|
+
const hashDir = import_node_path25.default.join(attachmentsRoot, attachmentId);
|
|
50766
50799
|
let finalFileName;
|
|
50767
50800
|
let hashDirExists = false;
|
|
50768
50801
|
try {
|
|
@@ -50780,7 +50813,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50780
50813
|
try {
|
|
50781
50814
|
import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
|
|
50782
50815
|
finalFileName = args.fileName;
|
|
50783
|
-
import_node_fs25.default.renameSync(tmpPath,
|
|
50816
|
+
import_node_fs25.default.renameSync(tmpPath, import_node_path25.default.join(hashDir, finalFileName));
|
|
50784
50817
|
} catch (err) {
|
|
50785
50818
|
try {
|
|
50786
50819
|
import_node_fs25.default.unlinkSync(tmpPath);
|
|
@@ -50789,8 +50822,8 @@ async function writeUploadedAttachment(args) {
|
|
|
50789
50822
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
50790
50823
|
}
|
|
50791
50824
|
}
|
|
50792
|
-
const absPath =
|
|
50793
|
-
const relPath =
|
|
50825
|
+
const absPath = import_node_path25.default.join(hashDir, finalFileName);
|
|
50826
|
+
const relPath = import_node_path25.default.relative(args.sessionDir, absPath);
|
|
50794
50827
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
50795
50828
|
relPath: absPath,
|
|
50796
50829
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -50804,8 +50837,8 @@ async function writeUploadedAttachment(args) {
|
|
|
50804
50837
|
|
|
50805
50838
|
// src/extension/import.ts
|
|
50806
50839
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
50807
|
-
var
|
|
50808
|
-
var
|
|
50840
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
50841
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
50809
50842
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
50810
50843
|
var ImportError = class extends Error {
|
|
50811
50844
|
constructor(code, message) {
|
|
@@ -50822,7 +50855,7 @@ async function importZip(buf, root) {
|
|
|
50822
50855
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
50823
50856
|
}
|
|
50824
50857
|
for (const name of Object.keys(zip.files)) {
|
|
50825
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
50858
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path26.default.isAbsolute(name)) {
|
|
50826
50859
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
50827
50860
|
}
|
|
50828
50861
|
}
|
|
@@ -50855,7 +50888,7 @@ async function importZip(buf, root) {
|
|
|
50855
50888
|
);
|
|
50856
50889
|
}
|
|
50857
50890
|
}
|
|
50858
|
-
const destDir =
|
|
50891
|
+
const destDir = import_node_path26.default.join(root, manifest.id);
|
|
50859
50892
|
let destExists = false;
|
|
50860
50893
|
try {
|
|
50861
50894
|
await import_promises3.default.access(destDir);
|
|
@@ -50865,15 +50898,15 @@ async function importZip(buf, root) {
|
|
|
50865
50898
|
if (destExists) {
|
|
50866
50899
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
50867
50900
|
}
|
|
50868
|
-
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}-`));
|
|
50869
50902
|
try {
|
|
50870
50903
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
50871
|
-
const dest =
|
|
50904
|
+
const dest = import_node_path26.default.join(stage, name);
|
|
50872
50905
|
if (entry.dir) {
|
|
50873
50906
|
await import_promises3.default.mkdir(dest, { recursive: true });
|
|
50874
50907
|
continue;
|
|
50875
50908
|
}
|
|
50876
|
-
await import_promises3.default.mkdir(
|
|
50909
|
+
await import_promises3.default.mkdir(import_node_path26.default.dirname(dest), { recursive: true });
|
|
50877
50910
|
const content = await entry.async("nodebuffer");
|
|
50878
50911
|
await import_promises3.default.writeFile(dest, content);
|
|
50879
50912
|
}
|
|
@@ -50904,7 +50937,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
50904
50937
|
".wasm": "application/wasm"
|
|
50905
50938
|
};
|
|
50906
50939
|
function shareUiAssetMime(filePath) {
|
|
50907
|
-
const ext =
|
|
50940
|
+
const ext = import_node_path27.default.extname(filePath).toLowerCase();
|
|
50908
50941
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
50909
50942
|
}
|
|
50910
50943
|
var DISPATCH_HEARTBEAT_MS = 25e3;
|
|
@@ -50991,7 +51024,7 @@ function isValidUploadFileName(fileName) {
|
|
|
50991
51024
|
if (fileName === "." || fileName === "..") return false;
|
|
50992
51025
|
if (fileName.startsWith(".")) return false;
|
|
50993
51026
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
50994
|
-
return fileName ===
|
|
51027
|
+
return fileName === import_node_path27.default.basename(fileName);
|
|
50995
51028
|
}
|
|
50996
51029
|
function createHttpRouter(deps) {
|
|
50997
51030
|
return async (req, res) => {
|
|
@@ -51287,7 +51320,7 @@ function createHttpRouter(deps) {
|
|
|
51287
51320
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
51288
51321
|
return true;
|
|
51289
51322
|
}
|
|
51290
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
51323
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path27.default.basename(r.absPath)));
|
|
51291
51324
|
return true;
|
|
51292
51325
|
}
|
|
51293
51326
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -51408,7 +51441,7 @@ function createHttpRouter(deps) {
|
|
|
51408
51441
|
return true;
|
|
51409
51442
|
}
|
|
51410
51443
|
let absPath;
|
|
51411
|
-
if (
|
|
51444
|
+
if (import_node_path27.default.isAbsolute(pathParam)) {
|
|
51412
51445
|
absPath = pathParam;
|
|
51413
51446
|
} else if (deps.sessionStore) {
|
|
51414
51447
|
const file = deps.sessionStore.read(sid);
|
|
@@ -51416,7 +51449,7 @@ function createHttpRouter(deps) {
|
|
|
51416
51449
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
51417
51450
|
return true;
|
|
51418
51451
|
}
|
|
51419
|
-
absPath =
|
|
51452
|
+
absPath = import_node_path27.default.join(file.cwd, pathParam);
|
|
51420
51453
|
} else {
|
|
51421
51454
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
51422
51455
|
return true;
|
|
@@ -51518,7 +51551,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51518
51551
|
return;
|
|
51519
51552
|
}
|
|
51520
51553
|
const mime = lookupMime(absPath);
|
|
51521
|
-
const basename =
|
|
51554
|
+
const basename = import_node_path27.default.basename(absPath);
|
|
51522
51555
|
res.writeHead(200, {
|
|
51523
51556
|
"Content-Type": mime,
|
|
51524
51557
|
"Content-Length": String(stat.size),
|
|
@@ -51536,7 +51569,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51536
51569
|
|
|
51537
51570
|
// src/attachment/gc.ts
|
|
51538
51571
|
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
51539
|
-
var
|
|
51572
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
51540
51573
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
51541
51574
|
function runAttachmentGc(args) {
|
|
51542
51575
|
const now = (args.now ?? Date.now)();
|
|
@@ -51545,17 +51578,17 @@ function runAttachmentGc(args) {
|
|
|
51545
51578
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
51546
51579
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
51547
51580
|
if (entry.stale) continue;
|
|
51548
|
-
if (
|
|
51581
|
+
if (import_node_path28.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
51549
51582
|
}
|
|
51550
51583
|
}
|
|
51551
51584
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
51552
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
51585
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path28.default.join(
|
|
51553
51586
|
args.dataDir,
|
|
51554
51587
|
"sessions",
|
|
51555
51588
|
...scopeSubPath(scope).map(safeFileName),
|
|
51556
51589
|
safeFileName(sessionId)
|
|
51557
51590
|
);
|
|
51558
|
-
const attRoot =
|
|
51591
|
+
const attRoot = import_node_path28.default.join(sessionDir, ".attachments");
|
|
51559
51592
|
let hashDirs;
|
|
51560
51593
|
try {
|
|
51561
51594
|
hashDirs = import_node_fs27.default.readdirSync(attRoot);
|
|
@@ -51565,7 +51598,7 @@ function runAttachmentGc(args) {
|
|
|
51565
51598
|
continue;
|
|
51566
51599
|
}
|
|
51567
51600
|
for (const hashDir of hashDirs) {
|
|
51568
|
-
const hashDirAbs =
|
|
51601
|
+
const hashDirAbs = import_node_path28.default.join(attRoot, hashDir);
|
|
51569
51602
|
let files;
|
|
51570
51603
|
try {
|
|
51571
51604
|
files = import_node_fs27.default.readdirSync(hashDirAbs);
|
|
@@ -51573,7 +51606,7 @@ function runAttachmentGc(args) {
|
|
|
51573
51606
|
continue;
|
|
51574
51607
|
}
|
|
51575
51608
|
for (const name of files) {
|
|
51576
|
-
const file =
|
|
51609
|
+
const file = import_node_path28.default.join(hashDirAbs, name);
|
|
51577
51610
|
let stat;
|
|
51578
51611
|
try {
|
|
51579
51612
|
stat = import_node_fs27.default.statSync(file);
|
|
@@ -51604,7 +51637,7 @@ function runAttachmentGc(args) {
|
|
|
51604
51637
|
|
|
51605
51638
|
// src/attachment/group.ts
|
|
51606
51639
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
51607
|
-
var
|
|
51640
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
51608
51641
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
51609
51642
|
init_protocol();
|
|
51610
51643
|
var GroupFileStore = class {
|
|
@@ -51616,11 +51649,11 @@ var GroupFileStore = class {
|
|
|
51616
51649
|
this.logger = opts.logger;
|
|
51617
51650
|
}
|
|
51618
51651
|
rootForScope(scope) {
|
|
51619
|
-
return
|
|
51652
|
+
return import_node_path29.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
51620
51653
|
}
|
|
51621
51654
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
51622
51655
|
filePath(scope, sessionId) {
|
|
51623
|
-
return
|
|
51656
|
+
return import_node_path29.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
51624
51657
|
}
|
|
51625
51658
|
cacheKey(scope, sessionId) {
|
|
51626
51659
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -51655,7 +51688,7 @@ var GroupFileStore = class {
|
|
|
51655
51688
|
}
|
|
51656
51689
|
writeFile(scope, sessionId, entries) {
|
|
51657
51690
|
const file = this.filePath(scope, sessionId);
|
|
51658
|
-
import_node_fs28.default.mkdirSync(
|
|
51691
|
+
import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(file), { recursive: true });
|
|
51659
51692
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
51660
51693
|
import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
51661
51694
|
import_node_fs28.default.renameSync(tmp, file);
|
|
@@ -51745,9 +51778,9 @@ var GroupFileStore = class {
|
|
|
51745
51778
|
|
|
51746
51779
|
// src/discovery/state-file.ts
|
|
51747
51780
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
51748
|
-
var
|
|
51781
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
51749
51782
|
function defaultStateFilePath(dataDir) {
|
|
51750
|
-
return
|
|
51783
|
+
return import_node_path30.default.join(dataDir, "state.json");
|
|
51751
51784
|
}
|
|
51752
51785
|
function isPidAlive(pid) {
|
|
51753
51786
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -51783,7 +51816,7 @@ var StateFileManager = class {
|
|
|
51783
51816
|
return { status: "stale", existing };
|
|
51784
51817
|
}
|
|
51785
51818
|
write(state) {
|
|
51786
|
-
import_node_fs29.default.mkdirSync(
|
|
51819
|
+
import_node_fs29.default.mkdirSync(import_node_path30.default.dirname(this.file), { recursive: true });
|
|
51787
51820
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
51788
51821
|
import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
51789
51822
|
import_node_fs29.default.renameSync(tmp, this.file);
|
|
@@ -51812,13 +51845,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
51812
51845
|
|
|
51813
51846
|
// src/tunnel/tunnel-manager.ts
|
|
51814
51847
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
51815
|
-
var
|
|
51848
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
51816
51849
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
51817
51850
|
var import_node_child_process9 = require("child_process");
|
|
51818
51851
|
|
|
51819
51852
|
// src/tunnel/tunnel-store.ts
|
|
51820
51853
|
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
51821
|
-
var
|
|
51854
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
51822
51855
|
var TunnelStore = class {
|
|
51823
51856
|
constructor(filePath) {
|
|
51824
51857
|
this.filePath = filePath;
|
|
@@ -51837,7 +51870,7 @@ var TunnelStore = class {
|
|
|
51837
51870
|
}
|
|
51838
51871
|
}
|
|
51839
51872
|
async set(v2) {
|
|
51840
|
-
const dir =
|
|
51873
|
+
const dir = import_node_path31.default.dirname(this.filePath);
|
|
51841
51874
|
await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
|
|
51842
51875
|
const data = JSON.stringify(v2, null, 2);
|
|
51843
51876
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -51948,8 +51981,8 @@ function escape(v2) {
|
|
|
51948
51981
|
|
|
51949
51982
|
// src/tunnel/frpc-binary.ts
|
|
51950
51983
|
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
51951
|
-
var
|
|
51952
|
-
var
|
|
51984
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
51985
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
51953
51986
|
var import_node_child_process7 = require("child_process");
|
|
51954
51987
|
var import_node_stream3 = require("stream");
|
|
51955
51988
|
var import_promises4 = require("stream/promises");
|
|
@@ -51988,13 +52021,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
51988
52021
|
}
|
|
51989
52022
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
51990
52023
|
const platform = opts.platform ?? detectPlatform();
|
|
51991
|
-
const binDir =
|
|
52024
|
+
const binDir = import_node_path32.default.join(opts.dataDir, "bin");
|
|
51992
52025
|
import_node_fs31.default.mkdirSync(binDir, { recursive: true });
|
|
51993
52026
|
cleanupStaleArtifacts(binDir);
|
|
51994
|
-
const stableBin =
|
|
52027
|
+
const stableBin = import_node_path32.default.join(binDir, "frpc");
|
|
51995
52028
|
if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
|
|
51996
52029
|
const partialBin = `${stableBin}.partial`;
|
|
51997
|
-
const tarballPath =
|
|
52030
|
+
const tarballPath = import_node_path32.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
51998
52031
|
try {
|
|
51999
52032
|
const url = frpcDownloadUrl(version2, platform);
|
|
52000
52033
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -52020,7 +52053,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
52020
52053
|
}
|
|
52021
52054
|
for (const name of entries) {
|
|
52022
52055
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
52023
|
-
const full =
|
|
52056
|
+
const full = import_node_path32.default.join(binDir, name);
|
|
52024
52057
|
try {
|
|
52025
52058
|
import_node_fs31.default.rmSync(full, { recursive: true, force: true });
|
|
52026
52059
|
} catch {
|
|
@@ -52046,7 +52079,7 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
52046
52079
|
await (0, import_promises4.pipeline)(nodeStream, out);
|
|
52047
52080
|
}
|
|
52048
52081
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
52049
|
-
const work =
|
|
52082
|
+
const work = import_node_path32.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
52050
52083
|
import_node_fs31.default.mkdirSync(work, { recursive: true });
|
|
52051
52084
|
try {
|
|
52052
52085
|
await new Promise((resolve6, reject) => {
|
|
@@ -52055,7 +52088,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
52055
52088
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
52056
52089
|
});
|
|
52057
52090
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
52058
|
-
const src =
|
|
52091
|
+
const src = import_node_path32.default.join(work, dirName, "frpc");
|
|
52059
52092
|
if (!import_node_fs31.default.existsSync(src)) {
|
|
52060
52093
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
52061
52094
|
}
|
|
@@ -52067,10 +52100,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
52067
52100
|
|
|
52068
52101
|
// src/tunnel/frpc-process.ts
|
|
52069
52102
|
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
52070
|
-
var
|
|
52103
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
52071
52104
|
var import_node_child_process8 = require("child_process");
|
|
52072
52105
|
function frpcPidFilePath(dataDir) {
|
|
52073
|
-
return
|
|
52106
|
+
return import_node_path33.default.join(dataDir, "frpc.pid");
|
|
52074
52107
|
}
|
|
52075
52108
|
function writeFrpcPid(dataDir, pid) {
|
|
52076
52109
|
try {
|
|
@@ -52112,7 +52145,7 @@ function defaultSleep(ms) {
|
|
|
52112
52145
|
}
|
|
52113
52146
|
async function killStaleFrpc(deps) {
|
|
52114
52147
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
52115
|
-
const tomlPath =
|
|
52148
|
+
const tomlPath = import_node_path33.default.join(deps.dataDir, "frpc.toml");
|
|
52116
52149
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
52117
52150
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
52118
52151
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -52184,7 +52217,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
52184
52217
|
var TunnelManager = class {
|
|
52185
52218
|
constructor(deps) {
|
|
52186
52219
|
this.deps = deps;
|
|
52187
|
-
this.store = deps.store ?? new TunnelStore(
|
|
52220
|
+
this.store = deps.store ?? new TunnelStore(import_node_path34.default.join(deps.dataDir, "tunnel.json"));
|
|
52188
52221
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
52189
52222
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
52190
52223
|
}
|
|
@@ -52311,7 +52344,7 @@ var TunnelManager = class {
|
|
|
52311
52344
|
dataDir: this.deps.dataDir,
|
|
52312
52345
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
52313
52346
|
});
|
|
52314
|
-
const tomlPath =
|
|
52347
|
+
const tomlPath = import_node_path34.default.join(this.deps.dataDir, "frpc.toml");
|
|
52315
52348
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto9.default.randomBytes(3).toString("hex")}`;
|
|
52316
52349
|
const toml = buildFrpcToml({
|
|
52317
52350
|
serverAddr: t.frpsHost,
|
|
@@ -52326,7 +52359,7 @@ var TunnelManager = class {
|
|
|
52326
52359
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
52327
52360
|
stdio: ["ignore", "pipe", "pipe"]
|
|
52328
52361
|
});
|
|
52329
|
-
const logFilePath =
|
|
52362
|
+
const logFilePath = import_node_path34.default.join(this.deps.dataDir, "frpc.log");
|
|
52330
52363
|
const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
52331
52364
|
logStream.on("error", () => {
|
|
52332
52365
|
});
|
|
@@ -52409,16 +52442,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52409
52442
|
}
|
|
52410
52443
|
|
|
52411
52444
|
// src/tunnel/device-key.ts
|
|
52412
|
-
var
|
|
52413
|
-
var
|
|
52445
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
52446
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
52414
52447
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
52415
52448
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
52416
52449
|
function deriveStableDeviceKey(opts = {}) {
|
|
52417
|
-
const hostname = opts.hostname ??
|
|
52418
|
-
const uid = opts.uid ?? (typeof
|
|
52419
|
-
const home = opts.home ??
|
|
52420
|
-
const defaultDataDir =
|
|
52421
|
-
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;
|
|
52422
52455
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
52423
52456
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
52424
52457
|
return import_node_crypto10.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
@@ -52426,11 +52459,11 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
52426
52459
|
|
|
52427
52460
|
// src/auth-store.ts
|
|
52428
52461
|
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
52429
|
-
var
|
|
52462
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
52430
52463
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
52431
52464
|
var AUTH_FILE_NAME = "auth.json";
|
|
52432
52465
|
function authFilePath(dataDir) {
|
|
52433
|
-
return
|
|
52466
|
+
return import_node_path36.default.join(dataDir, AUTH_FILE_NAME);
|
|
52434
52467
|
}
|
|
52435
52468
|
function loadOrCreateAuthFile(opts) {
|
|
52436
52469
|
const file = authFilePath(opts.dataDir);
|
|
@@ -52486,7 +52519,7 @@ function readAuthFile(file) {
|
|
|
52486
52519
|
}
|
|
52487
52520
|
}
|
|
52488
52521
|
function writeAuthFile(file, content) {
|
|
52489
|
-
import_node_fs34.default.mkdirSync(
|
|
52522
|
+
import_node_fs34.default.mkdirSync(import_node_path36.default.dirname(file), { recursive: true });
|
|
52490
52523
|
import_node_fs34.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
52491
52524
|
try {
|
|
52492
52525
|
import_node_fs34.default.chmodSync(file, 384);
|
|
@@ -52496,12 +52529,12 @@ function writeAuthFile(file, content) {
|
|
|
52496
52529
|
|
|
52497
52530
|
// src/owner-profile.ts
|
|
52498
52531
|
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
52499
|
-
var
|
|
52500
|
-
var
|
|
52532
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
52533
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
52501
52534
|
var PROFILE_FILENAME = "profile.json";
|
|
52502
52535
|
function loadOwnerDisplayName(dataDir) {
|
|
52503
|
-
const fallback =
|
|
52504
|
-
const profilePath =
|
|
52536
|
+
const fallback = import_node_os15.default.userInfo().username;
|
|
52537
|
+
const profilePath = import_node_path37.default.join(dataDir, PROFILE_FILENAME);
|
|
52505
52538
|
let raw;
|
|
52506
52539
|
try {
|
|
52507
52540
|
raw = import_node_fs35.default.readFileSync(profilePath, "utf8");
|
|
@@ -52528,12 +52561,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
52528
52561
|
|
|
52529
52562
|
// src/feishu-auth/owner-identity-store.ts
|
|
52530
52563
|
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
52531
|
-
var
|
|
52564
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
52532
52565
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
52533
52566
|
var OwnerIdentityStore = class {
|
|
52534
52567
|
file;
|
|
52535
52568
|
constructor(dataDir) {
|
|
52536
|
-
this.file =
|
|
52569
|
+
this.file = import_node_path38.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
52537
52570
|
}
|
|
52538
52571
|
read() {
|
|
52539
52572
|
let raw;
|
|
@@ -52566,7 +52599,7 @@ var OwnerIdentityStore = class {
|
|
|
52566
52599
|
};
|
|
52567
52600
|
}
|
|
52568
52601
|
write(record) {
|
|
52569
|
-
import_node_fs36.default.mkdirSync(
|
|
52602
|
+
import_node_fs36.default.mkdirSync(import_node_path38.default.dirname(this.file), { recursive: true });
|
|
52570
52603
|
import_node_fs36.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
52571
52604
|
try {
|
|
52572
52605
|
import_node_fs36.default.chmodSync(this.file, 384);
|
|
@@ -52696,9 +52729,9 @@ var CentralClientError = class extends Error {
|
|
|
52696
52729
|
code;
|
|
52697
52730
|
cause;
|
|
52698
52731
|
};
|
|
52699
|
-
async function centralRequest(opts,
|
|
52732
|
+
async function centralRequest(opts, path68, init) {
|
|
52700
52733
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
52701
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52734
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path68}`;
|
|
52702
52735
|
const ctrl = new AbortController();
|
|
52703
52736
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
52704
52737
|
let res;
|
|
@@ -52841,7 +52874,7 @@ function verifyConnectToken(args) {
|
|
|
52841
52874
|
|
|
52842
52875
|
// src/feishu-auth/server-key.ts
|
|
52843
52876
|
var fs46 = __toESM(require("fs"), 1);
|
|
52844
|
-
var
|
|
52877
|
+
var path47 = __toESM(require("path"), 1);
|
|
52845
52878
|
var FILE_NAME2 = "server-signing-key.json";
|
|
52846
52879
|
var ServerKeyStore = class {
|
|
52847
52880
|
constructor(dataDir) {
|
|
@@ -52849,7 +52882,7 @@ var ServerKeyStore = class {
|
|
|
52849
52882
|
}
|
|
52850
52883
|
dataDir;
|
|
52851
52884
|
filePath() {
|
|
52852
|
-
return
|
|
52885
|
+
return path47.join(this.dataDir, FILE_NAME2);
|
|
52853
52886
|
}
|
|
52854
52887
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
52855
52888
|
read() {
|
|
@@ -52888,8 +52921,8 @@ init_protocol();
|
|
|
52888
52921
|
|
|
52889
52922
|
// src/session/fork.ts
|
|
52890
52923
|
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
52891
|
-
var
|
|
52892
|
-
var
|
|
52924
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
52925
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
52893
52926
|
init_claude_history();
|
|
52894
52927
|
function readJsonlEntries(file) {
|
|
52895
52928
|
const raw = import_node_fs37.default.readFileSync(file, "utf8");
|
|
@@ -52905,9 +52938,9 @@ function readJsonlEntries(file) {
|
|
|
52905
52938
|
return out;
|
|
52906
52939
|
}
|
|
52907
52940
|
function forkSession(input) {
|
|
52908
|
-
const baseDir = input.baseDir ??
|
|
52909
|
-
const projectDir =
|
|
52910
|
-
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`);
|
|
52911
52944
|
if (!import_node_fs37.default.existsSync(sourceFile)) {
|
|
52912
52945
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
52913
52946
|
}
|
|
@@ -52938,7 +52971,7 @@ function forkSession(input) {
|
|
|
52938
52971
|
}
|
|
52939
52972
|
forkedLines.push(JSON.stringify(forked));
|
|
52940
52973
|
}
|
|
52941
|
-
const forkedFilePath =
|
|
52974
|
+
const forkedFilePath = import_node_path39.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
52942
52975
|
import_node_fs37.default.mkdirSync(projectDir, { recursive: true });
|
|
52943
52976
|
import_node_fs37.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
52944
52977
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -53292,7 +53325,7 @@ function buildPermissionHandlers(deps) {
|
|
|
53292
53325
|
}
|
|
53293
53326
|
|
|
53294
53327
|
// src/handlers/history.ts
|
|
53295
|
-
var
|
|
53328
|
+
var path50 = __toESM(require("path"), 1);
|
|
53296
53329
|
init_protocol();
|
|
53297
53330
|
|
|
53298
53331
|
// src/session/recent-dirs.ts
|
|
@@ -53310,7 +53343,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
53310
53343
|
}
|
|
53311
53344
|
|
|
53312
53345
|
// src/permission/persona-paths.ts
|
|
53313
|
-
var
|
|
53346
|
+
var path49 = __toESM(require("path"), 1);
|
|
53314
53347
|
function getAllowedPersonaIds(grants, action) {
|
|
53315
53348
|
const ids = /* @__PURE__ */ new Set();
|
|
53316
53349
|
for (const g2 of grants) {
|
|
@@ -53323,42 +53356,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
53323
53356
|
return ids;
|
|
53324
53357
|
}
|
|
53325
53358
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
53326
|
-
const target =
|
|
53359
|
+
const target = path49.resolve(absPath);
|
|
53327
53360
|
if (userWorkDir) {
|
|
53328
|
-
const u =
|
|
53329
|
-
const usep = u.endsWith(
|
|
53361
|
+
const u = path49.resolve(userWorkDir);
|
|
53362
|
+
const usep = u.endsWith(path49.sep) ? "" : path49.sep;
|
|
53330
53363
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
53331
53364
|
}
|
|
53332
|
-
const root =
|
|
53333
|
-
const sep3 = root.endsWith(
|
|
53365
|
+
const root = path49.resolve(personaRoot);
|
|
53366
|
+
const sep3 = root.endsWith(path49.sep) ? "" : path49.sep;
|
|
53334
53367
|
if (!target.startsWith(root + sep3)) return false;
|
|
53335
|
-
const rel =
|
|
53368
|
+
const rel = path49.relative(root, target);
|
|
53336
53369
|
if (!rel || rel.startsWith("..")) return false;
|
|
53337
|
-
const personaId = rel.split(
|
|
53370
|
+
const personaId = rel.split(path49.sep)[0];
|
|
53338
53371
|
if (!personaId) return false;
|
|
53339
53372
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
53340
53373
|
if (allowed === "*") return true;
|
|
53341
53374
|
return allowed.has(personaId);
|
|
53342
53375
|
}
|
|
53343
53376
|
function personaIdFromPath(absPath, personaRoot) {
|
|
53344
|
-
const root =
|
|
53345
|
-
const target =
|
|
53346
|
-
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;
|
|
53347
53380
|
if (!target.startsWith(root + sep3)) return null;
|
|
53348
|
-
const rel =
|
|
53381
|
+
const rel = path49.relative(root, target);
|
|
53349
53382
|
if (!rel || rel.startsWith("..")) return null;
|
|
53350
|
-
const id = rel.split(
|
|
53383
|
+
const id = rel.split(path49.sep)[0];
|
|
53351
53384
|
return id || null;
|
|
53352
53385
|
}
|
|
53353
53386
|
function isPathWithin(dir, absPath) {
|
|
53354
|
-
const d =
|
|
53355
|
-
const t =
|
|
53356
|
-
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;
|
|
53357
53390
|
return t === d || t.startsWith(d + sep3);
|
|
53358
53391
|
}
|
|
53359
53392
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
53360
53393
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
53361
|
-
return personaIdFromPath(
|
|
53394
|
+
return personaIdFromPath(path49.resolve(absPath), personaRoot) === personaId;
|
|
53362
53395
|
}
|
|
53363
53396
|
|
|
53364
53397
|
// src/handlers/history.ts
|
|
@@ -53384,7 +53417,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53384
53417
|
if (!pid) return false;
|
|
53385
53418
|
return isGuestPathAllowed(
|
|
53386
53419
|
ctx.grants,
|
|
53387
|
-
|
|
53420
|
+
path50.join(personaRoot, pid),
|
|
53388
53421
|
personaRoot,
|
|
53389
53422
|
"read",
|
|
53390
53423
|
userWorkDir
|
|
@@ -53396,7 +53429,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53396
53429
|
};
|
|
53397
53430
|
const list = async (frame, _client, ctx) => {
|
|
53398
53431
|
const args = HistoryListArgs.parse(frame);
|
|
53399
|
-
assertGuestPath(ctx,
|
|
53432
|
+
assertGuestPath(ctx, path50.resolve(args.projectPath), personaRoot, "history:list");
|
|
53400
53433
|
const sessions = await history.listSessions(args);
|
|
53401
53434
|
return { response: { type: "history:list", sessions } };
|
|
53402
53435
|
};
|
|
@@ -53428,13 +53461,13 @@ function buildHistoryHandlers(deps) {
|
|
|
53428
53461
|
};
|
|
53429
53462
|
const subagents = async (frame, _client, ctx) => {
|
|
53430
53463
|
const args = HistorySubagentsArgs.parse(frame);
|
|
53431
|
-
assertGuestPath(ctx,
|
|
53464
|
+
assertGuestPath(ctx, path50.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
53432
53465
|
const subs = await history.listSubagents(args);
|
|
53433
53466
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
53434
53467
|
};
|
|
53435
53468
|
const subagentRead = async (frame, _client, ctx) => {
|
|
53436
53469
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
53437
|
-
assertGuestPath(ctx,
|
|
53470
|
+
assertGuestPath(ctx, path50.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
53438
53471
|
const res = await history.readSubagent(args);
|
|
53439
53472
|
return { response: { type: "history:subagent-read", ...res } };
|
|
53440
53473
|
};
|
|
@@ -53443,7 +53476,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53443
53476
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
53444
53477
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
53445
53478
|
const filtered = dirs.filter(
|
|
53446
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
53479
|
+
(d) => isGuestPathAllowed(ctx.grants, path50.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
53447
53480
|
);
|
|
53448
53481
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
53449
53482
|
}
|
|
@@ -53460,8 +53493,8 @@ function buildHistoryHandlers(deps) {
|
|
|
53460
53493
|
}
|
|
53461
53494
|
|
|
53462
53495
|
// src/handlers/workspace.ts
|
|
53463
|
-
var
|
|
53464
|
-
var
|
|
53496
|
+
var path51 = __toESM(require("path"), 1);
|
|
53497
|
+
var os16 = __toESM(require("os"), 1);
|
|
53465
53498
|
init_protocol();
|
|
53466
53499
|
init_protocol();
|
|
53467
53500
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -53501,23 +53534,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53501
53534
|
const list = async (frame, _client, ctx) => {
|
|
53502
53535
|
const args = WorkspaceListArgs.parse(frame);
|
|
53503
53536
|
const isGuest = ctx?.principal.kind === "guest";
|
|
53504
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
53505
|
-
const resolvedCwd =
|
|
53506
|
-
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;
|
|
53507
53540
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
53508
53541
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
53509
53542
|
return { response: { type: "workspace:list", ...res } };
|
|
53510
53543
|
};
|
|
53511
53544
|
const read = async (frame, _client, ctx) => {
|
|
53512
53545
|
const args = WorkspaceReadArgs.parse(frame);
|
|
53513
|
-
const target =
|
|
53546
|
+
const target = path51.isAbsolute(args.path) ? path51.resolve(args.path) : path51.resolve(args.cwd, args.path);
|
|
53514
53547
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
53515
53548
|
const res = workspace.read(args);
|
|
53516
53549
|
return { response: { type: "workspace:read", ...res } };
|
|
53517
53550
|
};
|
|
53518
53551
|
const skillsList = async (frame, _client, ctx) => {
|
|
53519
53552
|
const args = SkillsListArgs.parse(frame);
|
|
53520
|
-
const cwdAbs =
|
|
53553
|
+
const cwdAbs = path51.resolve(args.cwd);
|
|
53521
53554
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
53522
53555
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
53523
53556
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -53529,7 +53562,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53529
53562
|
};
|
|
53530
53563
|
const agentsList = async (frame, _client, ctx) => {
|
|
53531
53564
|
const args = AgentsListArgs.parse(frame);
|
|
53532
|
-
const cwdAbs =
|
|
53565
|
+
const cwdAbs = path51.resolve(args.cwd);
|
|
53533
53566
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
53534
53567
|
if (args.tool === "codex") {
|
|
53535
53568
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -53551,18 +53584,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53551
53584
|
}
|
|
53552
53585
|
|
|
53553
53586
|
// src/handlers/git.ts
|
|
53554
|
-
var
|
|
53587
|
+
var path53 = __toESM(require("path"), 1);
|
|
53555
53588
|
init_protocol();
|
|
53556
53589
|
init_protocol();
|
|
53557
53590
|
|
|
53558
53591
|
// src/workspace/git.ts
|
|
53559
53592
|
var import_node_child_process10 = require("child_process");
|
|
53560
53593
|
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53561
|
-
var
|
|
53594
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
53562
53595
|
var import_node_util = require("util");
|
|
53563
53596
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
53564
53597
|
function normalizePath(p2) {
|
|
53565
|
-
const resolved =
|
|
53598
|
+
const resolved = import_node_path40.default.resolve(p2);
|
|
53566
53599
|
try {
|
|
53567
53600
|
return import_node_fs38.default.realpathSync(resolved);
|
|
53568
53601
|
} catch {
|
|
@@ -53638,7 +53671,7 @@ async function listGitBranches(cwd) {
|
|
|
53638
53671
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
53639
53672
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
53640
53673
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
53641
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
53674
|
+
if (!isGuestPathAllowed(ctx.grants, path53.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
53642
53675
|
throw new ClawdError(
|
|
53643
53676
|
ERROR_CODES.UNAUTHORIZED,
|
|
53644
53677
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -54124,7 +54157,7 @@ function buildDeviceHandlers(deps) {
|
|
|
54124
54157
|
}
|
|
54125
54158
|
|
|
54126
54159
|
// src/handlers/meta.ts
|
|
54127
|
-
var
|
|
54160
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
54128
54161
|
init_protocol();
|
|
54129
54162
|
|
|
54130
54163
|
// src/version.ts
|
|
@@ -54156,7 +54189,7 @@ function buildReadyFrame(deps, client) {
|
|
|
54156
54189
|
return {
|
|
54157
54190
|
version,
|
|
54158
54191
|
protocolVersion: PROTOCOL_VERSION,
|
|
54159
|
-
hostname:
|
|
54192
|
+
hostname: import_node_os17.default.hostname(),
|
|
54160
54193
|
os: process.platform,
|
|
54161
54194
|
tools,
|
|
54162
54195
|
runningSessions: info.runningSessions,
|
|
@@ -54253,7 +54286,7 @@ function buildPersonaHandlers(deps) {
|
|
|
54253
54286
|
}
|
|
54254
54287
|
|
|
54255
54288
|
// src/handlers/attachment.ts
|
|
54256
|
-
var
|
|
54289
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
54257
54290
|
init_protocol();
|
|
54258
54291
|
init_protocol();
|
|
54259
54292
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -54333,12 +54366,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
54333
54366
|
`session ${args.sessionId} scope unresolved`
|
|
54334
54367
|
);
|
|
54335
54368
|
}
|
|
54336
|
-
const cwdAbs =
|
|
54337
|
-
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);
|
|
54338
54371
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
54339
54372
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
54340
54373
|
const entry = entries.find((e) => {
|
|
54341
|
-
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);
|
|
54342
54375
|
return storedAbs === candidateAbs && !e.stale;
|
|
54343
54376
|
});
|
|
54344
54377
|
if (!entry) {
|
|
@@ -54363,7 +54396,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
54363
54396
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
54364
54397
|
const f = deps.sessionStore.read(sessionId);
|
|
54365
54398
|
if (!f) return;
|
|
54366
|
-
assertGuestAttachmentPath(ctx,
|
|
54399
|
+
assertGuestAttachmentPath(ctx, import_node_path41.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
54367
54400
|
}
|
|
54368
54401
|
const groupAdd = async (frame, _client, ctx) => {
|
|
54369
54402
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -54378,8 +54411,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
54378
54411
|
if (!scope) {
|
|
54379
54412
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
54380
54413
|
}
|
|
54381
|
-
const cwdAbs =
|
|
54382
|
-
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);
|
|
54383
54416
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
54384
54417
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
54385
54418
|
const size = 0;
|
|
@@ -54438,19 +54471,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
54438
54471
|
|
|
54439
54472
|
// src/handlers/extension.ts
|
|
54440
54473
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
54441
|
-
var
|
|
54474
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
54442
54475
|
init_protocol();
|
|
54443
54476
|
|
|
54444
54477
|
// src/extension/bundle-zip.ts
|
|
54445
54478
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
54446
|
-
var
|
|
54479
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
54447
54480
|
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
54448
54481
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
54449
54482
|
async function bundleExtensionDir(dir) {
|
|
54450
54483
|
const entries = await listFilesSorted(dir);
|
|
54451
54484
|
const zip = new import_jszip2.default();
|
|
54452
54485
|
for (const rel of entries) {
|
|
54453
|
-
const abs =
|
|
54486
|
+
const abs = import_node_path42.default.join(dir, rel);
|
|
54454
54487
|
const content = await import_promises5.default.readFile(abs);
|
|
54455
54488
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
54456
54489
|
}
|
|
@@ -54471,7 +54504,7 @@ async function listFilesSorted(rootDir) {
|
|
|
54471
54504
|
return out;
|
|
54472
54505
|
}
|
|
54473
54506
|
async function walk(absRoot, relPrefix, out) {
|
|
54474
|
-
const dirAbs =
|
|
54507
|
+
const dirAbs = import_node_path42.default.join(absRoot, relPrefix);
|
|
54475
54508
|
const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
|
|
54476
54509
|
for (const e of entries) {
|
|
54477
54510
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -54525,25 +54558,25 @@ function computePublishCheck(args) {
|
|
|
54525
54558
|
|
|
54526
54559
|
// src/extension/install-flow.ts
|
|
54527
54560
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
54528
|
-
var
|
|
54529
|
-
var
|
|
54561
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
54562
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
54530
54563
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
54531
54564
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
54532
54565
|
|
|
54533
54566
|
// src/extension/paths.ts
|
|
54534
|
-
var
|
|
54535
|
-
var
|
|
54567
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
54568
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
54536
54569
|
function clawdHomeRoot(override) {
|
|
54537
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
54570
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path43.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
54538
54571
|
}
|
|
54539
54572
|
function extensionsRoot(override) {
|
|
54540
|
-
return
|
|
54573
|
+
return import_node_path43.default.join(clawdHomeRoot(override), "extensions");
|
|
54541
54574
|
}
|
|
54542
54575
|
function publishedChannelsFile(override) {
|
|
54543
|
-
return
|
|
54576
|
+
return import_node_path43.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
54544
54577
|
}
|
|
54545
54578
|
function bundleCacheRoot(override) {
|
|
54546
|
-
return
|
|
54579
|
+
return import_node_path43.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
54547
54580
|
}
|
|
54548
54581
|
|
|
54549
54582
|
// src/extension/install-flow.ts
|
|
@@ -54570,7 +54603,7 @@ async function installFromChannel(args, deps) {
|
|
|
54570
54603
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54571
54604
|
}
|
|
54572
54605
|
for (const name of Object.keys(zip.files)) {
|
|
54573
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
54606
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
|
|
54574
54607
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
54575
54608
|
}
|
|
54576
54609
|
}
|
|
@@ -54602,7 +54635,7 @@ async function installFromChannel(args, deps) {
|
|
|
54602
54635
|
);
|
|
54603
54636
|
}
|
|
54604
54637
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
54605
|
-
const destDir =
|
|
54638
|
+
const destDir = import_node_path44.default.join(deps.extensionsRoot, localExtId);
|
|
54606
54639
|
let destExists = false;
|
|
54607
54640
|
try {
|
|
54608
54641
|
await import_promises6.default.access(destDir);
|
|
@@ -54616,16 +54649,16 @@ async function installFromChannel(args, deps) {
|
|
|
54616
54649
|
);
|
|
54617
54650
|
}
|
|
54618
54651
|
const stage = await import_promises6.default.mkdtemp(
|
|
54619
|
-
|
|
54652
|
+
import_node_path44.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
54620
54653
|
);
|
|
54621
54654
|
try {
|
|
54622
54655
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
54623
|
-
const dest =
|
|
54656
|
+
const dest = import_node_path44.default.join(stage, name);
|
|
54624
54657
|
if (entry.dir) {
|
|
54625
54658
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
54626
54659
|
continue;
|
|
54627
54660
|
}
|
|
54628
|
-
await import_promises6.default.mkdir(
|
|
54661
|
+
await import_promises6.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
|
|
54629
54662
|
if (name === "manifest.json") {
|
|
54630
54663
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
54631
54664
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -54646,8 +54679,8 @@ async function installFromChannel(args, deps) {
|
|
|
54646
54679
|
|
|
54647
54680
|
// src/extension/update-flow.ts
|
|
54648
54681
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
54649
|
-
var
|
|
54650
|
-
var
|
|
54682
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
54683
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
54651
54684
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
54652
54685
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
54653
54686
|
var UpdateError = class extends Error {
|
|
@@ -54663,11 +54696,11 @@ async function updateFromChannel(args, deps) {
|
|
|
54663
54696
|
channelRef.extId,
|
|
54664
54697
|
channelRef.ownerPrincipalId
|
|
54665
54698
|
);
|
|
54666
|
-
const liveDir =
|
|
54699
|
+
const liveDir = import_node_path45.default.join(deps.extensionsRoot, localExtId);
|
|
54667
54700
|
const prevDir = `${liveDir}.prev`;
|
|
54668
54701
|
let existingVersion;
|
|
54669
54702
|
try {
|
|
54670
|
-
const raw = await import_promises7.default.readFile(
|
|
54703
|
+
const raw = await import_promises7.default.readFile(import_node_path45.default.join(liveDir, "manifest.json"), "utf8");
|
|
54671
54704
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
54672
54705
|
if (!parsed2.success) {
|
|
54673
54706
|
throw new UpdateError(
|
|
@@ -54700,7 +54733,7 @@ async function updateFromChannel(args, deps) {
|
|
|
54700
54733
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54701
54734
|
}
|
|
54702
54735
|
for (const name of Object.keys(zip.files)) {
|
|
54703
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
54736
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path45.default.isAbsolute(name)) {
|
|
54704
54737
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
54705
54738
|
}
|
|
54706
54739
|
}
|
|
@@ -54735,16 +54768,16 @@ async function updateFromChannel(args, deps) {
|
|
|
54735
54768
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
54736
54769
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
54737
54770
|
const stage = await import_promises7.default.mkdtemp(
|
|
54738
|
-
|
|
54771
|
+
import_node_path45.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
54739
54772
|
);
|
|
54740
54773
|
try {
|
|
54741
54774
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
54742
|
-
const dest =
|
|
54775
|
+
const dest = import_node_path45.default.join(stage, name);
|
|
54743
54776
|
if (entry.dir) {
|
|
54744
54777
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
54745
54778
|
continue;
|
|
54746
54779
|
}
|
|
54747
|
-
await import_promises7.default.mkdir(
|
|
54780
|
+
await import_promises7.default.mkdir(import_node_path45.default.dirname(dest), { recursive: true });
|
|
54748
54781
|
if (name === "manifest.json") {
|
|
54749
54782
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
54750
54783
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -54837,7 +54870,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
54837
54870
|
);
|
|
54838
54871
|
}
|
|
54839
54872
|
}
|
|
54840
|
-
const manifestPath =
|
|
54873
|
+
const manifestPath = import_node_path46.default.join(root, extId, "manifest.json");
|
|
54841
54874
|
const manifest = await readManifest(root, extId);
|
|
54842
54875
|
const next = { ...manifest, version: newVersion };
|
|
54843
54876
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -54845,7 +54878,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
54845
54878
|
await import_promises8.default.rename(tmp, manifestPath);
|
|
54846
54879
|
}
|
|
54847
54880
|
async function readManifest(root, extId) {
|
|
54848
|
-
const file =
|
|
54881
|
+
const file = import_node_path46.default.join(root, extId, "manifest.json");
|
|
54849
54882
|
let raw;
|
|
54850
54883
|
try {
|
|
54851
54884
|
raw = await import_promises8.default.readFile(file, "utf8");
|
|
@@ -54936,7 +54969,7 @@ function buildExtensionHandlers(deps) {
|
|
|
54936
54969
|
};
|
|
54937
54970
|
async function buildSnapshotMeta(extId) {
|
|
54938
54971
|
const manifest = await readManifest(deps.root, extId);
|
|
54939
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
54972
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path46.default.join(deps.root, extId));
|
|
54940
54973
|
return { manifest, contentHash: sha256, buffer };
|
|
54941
54974
|
}
|
|
54942
54975
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -55119,7 +55152,7 @@ function buildExtensionHandlers(deps) {
|
|
|
55119
55152
|
// src/app-builder/project-store.ts
|
|
55120
55153
|
var import_node_fs39 = require("fs");
|
|
55121
55154
|
var import_node_child_process11 = require("child_process");
|
|
55122
|
-
var
|
|
55155
|
+
var import_node_path47 = require("path");
|
|
55123
55156
|
init_protocol();
|
|
55124
55157
|
var PROJECTS_DIR = "projects";
|
|
55125
55158
|
var META_FILE = ".clawd-project.json";
|
|
@@ -55133,14 +55166,14 @@ var ProjectStore = class {
|
|
|
55133
55166
|
root;
|
|
55134
55167
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
55135
55168
|
metaPath(name) {
|
|
55136
|
-
return (0,
|
|
55169
|
+
return (0, import_node_path47.join)(this.projectsRoot(), name, META_FILE);
|
|
55137
55170
|
}
|
|
55138
55171
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
55139
55172
|
projectDir(name) {
|
|
55140
|
-
return (0,
|
|
55173
|
+
return (0, import_node_path47.join)(this.projectsRoot(), name);
|
|
55141
55174
|
}
|
|
55142
55175
|
projectsRoot() {
|
|
55143
|
-
return (0,
|
|
55176
|
+
return (0, import_node_path47.join)(this.root, PROJECTS_DIR);
|
|
55144
55177
|
}
|
|
55145
55178
|
async list() {
|
|
55146
55179
|
let entries;
|
|
@@ -55443,7 +55476,7 @@ var PublishJobRegistry = class {
|
|
|
55443
55476
|
// src/app-builder/publish-job-runner.ts
|
|
55444
55477
|
var import_node_child_process13 = require("child_process");
|
|
55445
55478
|
var import_node_fs40 = require("fs");
|
|
55446
|
-
var
|
|
55479
|
+
var import_node_path48 = require("path");
|
|
55447
55480
|
|
|
55448
55481
|
// src/app-builder/publish-stage-parser.ts
|
|
55449
55482
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -55475,7 +55508,7 @@ async function startPublishJob(deps, args) {
|
|
|
55475
55508
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
55476
55509
|
}
|
|
55477
55510
|
const projDir = projectDir(args.name);
|
|
55478
|
-
const logPath = (0,
|
|
55511
|
+
const logPath = (0, import_node_path48.join)(projDir, ".publish.log");
|
|
55479
55512
|
let logStream = null;
|
|
55480
55513
|
try {
|
|
55481
55514
|
logStream = (0, import_node_fs40.createWriteStream)(logPath, { flags: "w" });
|
|
@@ -55735,7 +55768,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
55735
55768
|
|
|
55736
55769
|
// src/handlers/app-builder.ts
|
|
55737
55770
|
init_protocol();
|
|
55738
|
-
var
|
|
55771
|
+
var import_node_path49 = require("path");
|
|
55739
55772
|
var import_node_fs41 = require("fs");
|
|
55740
55773
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
55741
55774
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
@@ -55893,8 +55926,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
55893
55926
|
const project = await userStore.create(f.name, reservedPorts);
|
|
55894
55927
|
try {
|
|
55895
55928
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
55896
|
-
const templateSrcDir = (0,
|
|
55897
|
-
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");
|
|
55898
55931
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
55899
55932
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
55900
55933
|
name: project.name,
|
|
@@ -56115,7 +56148,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
56115
56148
|
await userStore.clearPublishJob(args.name);
|
|
56116
56149
|
}
|
|
56117
56150
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
56118
|
-
const scriptPath = (0,
|
|
56151
|
+
const scriptPath = (0, import_node_path49.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
56119
56152
|
deps.logger?.info("app-builder.publish.start", {
|
|
56120
56153
|
name: args.name,
|
|
56121
56154
|
sessionId: boundSession.sessionId,
|
|
@@ -56284,7 +56317,7 @@ function buildVisitorHandlers(deps) {
|
|
|
56284
56317
|
|
|
56285
56318
|
// src/extension/registry.ts
|
|
56286
56319
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
56287
|
-
var
|
|
56320
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
56288
56321
|
async function loadAll(root) {
|
|
56289
56322
|
let entries;
|
|
56290
56323
|
try {
|
|
@@ -56297,13 +56330,13 @@ async function loadAll(root) {
|
|
|
56297
56330
|
for (const ent of entries) {
|
|
56298
56331
|
if (!ent.isDirectory()) continue;
|
|
56299
56332
|
if (ent.name.startsWith(".")) continue;
|
|
56300
|
-
records.push(await loadOne(
|
|
56333
|
+
records.push(await loadOne(import_node_path50.default.join(root, ent.name), ent.name));
|
|
56301
56334
|
}
|
|
56302
56335
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
56303
56336
|
return records;
|
|
56304
56337
|
}
|
|
56305
56338
|
async function loadOne(dir, dirName) {
|
|
56306
|
-
const manifestPath =
|
|
56339
|
+
const manifestPath = import_node_path50.default.join(dir, "manifest.json");
|
|
56307
56340
|
let raw;
|
|
56308
56341
|
try {
|
|
56309
56342
|
raw = await import_promises9.default.readFile(manifestPath, "utf8");
|
|
@@ -56348,7 +56381,7 @@ async function loadOne(dir, dirName) {
|
|
|
56348
56381
|
|
|
56349
56382
|
// src/extension/uninstall.ts
|
|
56350
56383
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
56351
|
-
var
|
|
56384
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56352
56385
|
var UninstallError = class extends Error {
|
|
56353
56386
|
constructor(code, message) {
|
|
56354
56387
|
super(message);
|
|
@@ -56357,7 +56390,7 @@ var UninstallError = class extends Error {
|
|
|
56357
56390
|
code;
|
|
56358
56391
|
};
|
|
56359
56392
|
async function uninstall(deps) {
|
|
56360
|
-
const dir =
|
|
56393
|
+
const dir = import_node_path51.default.join(deps.root, deps.extId);
|
|
56361
56394
|
try {
|
|
56362
56395
|
await import_promises10.default.access(dir);
|
|
56363
56396
|
} catch {
|
|
@@ -56926,7 +56959,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
56926
56959
|
|
|
56927
56960
|
// src/extension/runtime.ts
|
|
56928
56961
|
var import_node_child_process15 = require("child_process");
|
|
56929
|
-
var
|
|
56962
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
56930
56963
|
var import_promises11 = require("timers/promises");
|
|
56931
56964
|
|
|
56932
56965
|
// src/extension/port-allocator.ts
|
|
@@ -57027,7 +57060,7 @@ var Runtime = class {
|
|
|
57027
57060
|
/\$CLAWOS_EXT_PORT/g,
|
|
57028
57061
|
String(port)
|
|
57029
57062
|
);
|
|
57030
|
-
const dir =
|
|
57063
|
+
const dir = import_node_path52.default.join(this.root, extId);
|
|
57031
57064
|
const env = {
|
|
57032
57065
|
...process.env,
|
|
57033
57066
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -57139,7 +57172,7 @@ ${handle.stderrTail}`
|
|
|
57139
57172
|
|
|
57140
57173
|
// src/extension/published-channels.ts
|
|
57141
57174
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
57142
|
-
var
|
|
57175
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
57143
57176
|
init_zod();
|
|
57144
57177
|
var PublishedChannelsError = class extends Error {
|
|
57145
57178
|
constructor(code, message) {
|
|
@@ -57238,7 +57271,7 @@ var PublishedChannelStore = class {
|
|
|
57238
57271
|
)
|
|
57239
57272
|
};
|
|
57240
57273
|
const tmp = `${this.filePath}.tmp`;
|
|
57241
|
-
await import_promises12.default.mkdir(
|
|
57274
|
+
await import_promises12.default.mkdir(import_node_path53.default.dirname(this.filePath), { recursive: true });
|
|
57242
57275
|
await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
57243
57276
|
await import_promises12.default.rename(tmp, this.filePath);
|
|
57244
57277
|
}
|
|
@@ -57246,7 +57279,7 @@ var PublishedChannelStore = class {
|
|
|
57246
57279
|
|
|
57247
57280
|
// src/extension/bundle-cache.ts
|
|
57248
57281
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
57249
|
-
var
|
|
57282
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
57250
57283
|
var BundleCache = class {
|
|
57251
57284
|
constructor(rootDir) {
|
|
57252
57285
|
this.rootDir = rootDir;
|
|
@@ -57255,14 +57288,14 @@ var BundleCache = class {
|
|
|
57255
57288
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
57256
57289
|
async write(snapshotHash, buffer) {
|
|
57257
57290
|
await import_promises13.default.mkdir(this.rootDir, { recursive: true });
|
|
57258
|
-
const file =
|
|
57291
|
+
const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57259
57292
|
const tmp = `${file}.tmp`;
|
|
57260
57293
|
await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
|
|
57261
57294
|
await import_promises13.default.rename(tmp, file);
|
|
57262
57295
|
}
|
|
57263
57296
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
57264
57297
|
async read(snapshotHash) {
|
|
57265
|
-
const file =
|
|
57298
|
+
const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57266
57299
|
try {
|
|
57267
57300
|
return await import_promises13.default.readFile(file);
|
|
57268
57301
|
} catch (e) {
|
|
@@ -57272,7 +57305,7 @@ var BundleCache = class {
|
|
|
57272
57305
|
}
|
|
57273
57306
|
/** Idempotent — missing file is not an error. */
|
|
57274
57307
|
async delete(snapshotHash) {
|
|
57275
|
-
const file =
|
|
57308
|
+
const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
57276
57309
|
await import_promises13.default.rm(file, { force: true });
|
|
57277
57310
|
}
|
|
57278
57311
|
};
|
|
@@ -57293,11 +57326,11 @@ async function startDaemon(config) {
|
|
|
57293
57326
|
},
|
|
57294
57327
|
source: "daemon",
|
|
57295
57328
|
sampling: logShippingCfg.sampling,
|
|
57296
|
-
homeDir:
|
|
57329
|
+
homeDir: import_node_os21.default.homedir()
|
|
57297
57330
|
});
|
|
57298
57331
|
const logger = createLogger({
|
|
57299
57332
|
level: config.logLevel,
|
|
57300
|
-
file:
|
|
57333
|
+
file: import_node_path55.default.join(config.dataDir, "clawd.log"),
|
|
57301
57334
|
logClient
|
|
57302
57335
|
});
|
|
57303
57336
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
@@ -57437,8 +57470,8 @@ async function startDaemon(config) {
|
|
|
57437
57470
|
const agents = new AgentsScanner();
|
|
57438
57471
|
const history = new ClaudeHistoryReader();
|
|
57439
57472
|
let transport = null;
|
|
57440
|
-
const personaStore = new PersonaStore(
|
|
57441
|
-
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");
|
|
57442
57475
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
57443
57476
|
if (defaultsRoot) {
|
|
57444
57477
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -57458,17 +57491,17 @@ async function startDaemon(config) {
|
|
|
57458
57491
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
57459
57492
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
57460
57493
|
const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
|
|
57461
|
-
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));
|
|
57462
57495
|
const dispatchServerCandidates = [
|
|
57463
|
-
|
|
57496
|
+
import_node_path55.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
57464
57497
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
57465
|
-
|
|
57498
|
+
import_node_path55.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
57466
57499
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
57467
57500
|
];
|
|
57468
57501
|
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57469
57502
|
let dispatchMcpConfigPath2;
|
|
57470
57503
|
if (dispatchServerScriptPath) {
|
|
57471
|
-
const dispatchLogPath =
|
|
57504
|
+
const dispatchLogPath = import_node_path55.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
57472
57505
|
dispatchMcpConfigPath2 = writeDispatchMcpConfig({
|
|
57473
57506
|
dataDir: config.dataDir,
|
|
57474
57507
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -57485,15 +57518,15 @@ async function startDaemon(config) {
|
|
|
57485
57518
|
});
|
|
57486
57519
|
}
|
|
57487
57520
|
const ticketServerCandidates = [
|
|
57488
|
-
|
|
57489
|
-
|
|
57521
|
+
import_node_path55.default.join(here, "ticket", "mcp-server.cjs"),
|
|
57522
|
+
import_node_path55.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
57490
57523
|
];
|
|
57491
57524
|
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57492
57525
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
57493
57526
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
57494
57527
|
let ticketMcpConfigPath2;
|
|
57495
57528
|
if (ticketServerScriptPath && ticketOwnerUnionId) {
|
|
57496
|
-
const ticketLogPath =
|
|
57529
|
+
const ticketLogPath = import_node_path55.default.join(config.dataDir, "ticket-mcp-server.log");
|
|
57497
57530
|
ticketMcpConfigPath2 = writeTicketMcpConfig({
|
|
57498
57531
|
dataDir: config.dataDir,
|
|
57499
57532
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -57514,13 +57547,13 @@ async function startDaemon(config) {
|
|
|
57514
57547
|
});
|
|
57515
57548
|
}
|
|
57516
57549
|
const shiftServerCandidates = [
|
|
57517
|
-
|
|
57518
|
-
|
|
57550
|
+
import_node_path55.default.join(here, "shift", "mcp-server.cjs"),
|
|
57551
|
+
import_node_path55.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
57519
57552
|
];
|
|
57520
57553
|
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57521
57554
|
let shiftMcpConfigPath2;
|
|
57522
57555
|
if (shiftServerScriptPath) {
|
|
57523
|
-
const shiftLogPath =
|
|
57556
|
+
const shiftLogPath = import_node_path55.default.join(config.dataDir, "shift-mcp-server.log");
|
|
57524
57557
|
shiftMcpConfigPath2 = await writeShiftMcpConfig({
|
|
57525
57558
|
dataDir: config.dataDir,
|
|
57526
57559
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -57538,13 +57571,13 @@ async function startDaemon(config) {
|
|
|
57538
57571
|
);
|
|
57539
57572
|
}
|
|
57540
57573
|
const inboxServerCandidates = [
|
|
57541
|
-
|
|
57542
|
-
|
|
57574
|
+
import_node_path55.default.join(here, "inbox", "mcp-server.cjs"),
|
|
57575
|
+
import_node_path55.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
57543
57576
|
];
|
|
57544
57577
|
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57545
57578
|
let inboxMcpConfigPath2;
|
|
57546
57579
|
if (inboxServerScriptPath) {
|
|
57547
|
-
const inboxLogPath =
|
|
57580
|
+
const inboxLogPath = import_node_path55.default.join(config.dataDir, "inbox-mcp-server.log");
|
|
57548
57581
|
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
57549
57582
|
dataDir: config.dataDir,
|
|
57550
57583
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -57562,7 +57595,7 @@ async function startDaemon(config) {
|
|
|
57562
57595
|
);
|
|
57563
57596
|
}
|
|
57564
57597
|
const shiftStore = createShiftStore({
|
|
57565
|
-
filePath:
|
|
57598
|
+
filePath: import_node_path55.default.join(config.dataDir, "shift.json"),
|
|
57566
57599
|
ownerIdProvider: () => ownerPrincipalId,
|
|
57567
57600
|
now: () => Date.now()
|
|
57568
57601
|
});
|
|
@@ -57580,7 +57613,7 @@ async function startDaemon(config) {
|
|
|
57580
57613
|
getAdapter,
|
|
57581
57614
|
historyReader: history,
|
|
57582
57615
|
dataDir: config.dataDir,
|
|
57583
|
-
personaRoot:
|
|
57616
|
+
personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
|
|
57584
57617
|
usersRoot,
|
|
57585
57618
|
personaStore,
|
|
57586
57619
|
ownerDisplayName,
|
|
@@ -57623,7 +57656,7 @@ async function startDaemon(config) {
|
|
|
57623
57656
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
57624
57657
|
attachmentGroup: {
|
|
57625
57658
|
onFileEdit: (input) => {
|
|
57626
|
-
const absPath =
|
|
57659
|
+
const absPath = import_node_path55.default.isAbsolute(input.relPath) ? input.relPath : import_node_path55.default.join(input.cwd, input.relPath);
|
|
57627
57660
|
let size = 0;
|
|
57628
57661
|
try {
|
|
57629
57662
|
size = import_node_fs42.default.statSync(absPath).size;
|
|
@@ -57824,11 +57857,11 @@ async function startDaemon(config) {
|
|
|
57824
57857
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
57825
57858
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
57826
57859
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
57827
|
-
personaRoot:
|
|
57860
|
+
personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
|
|
57828
57861
|
usersRoot
|
|
57829
57862
|
},
|
|
57830
57863
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
57831
|
-
personaRoot:
|
|
57864
|
+
personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
|
|
57832
57865
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
57833
57866
|
usersRoot,
|
|
57834
57867
|
// capability:list / delete handler 依赖
|
|
@@ -57937,11 +57970,11 @@ async function startDaemon(config) {
|
|
|
57937
57970
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
57938
57971
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
57939
57972
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
57940
|
-
appBuilderPersonaRoot:
|
|
57973
|
+
appBuilderPersonaRoot: import_node_path55.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
57941
57974
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
57942
|
-
deployKitRoot:
|
|
57975
|
+
deployKitRoot: import_node_path55.default.join(config.dataDir, "deploy-kit"),
|
|
57943
57976
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
57944
|
-
resolvePersonaRoot: (personaId) =>
|
|
57977
|
+
resolvePersonaRoot: (personaId) => import_node_path55.default.join(config.dataDir, "personas", personaId),
|
|
57945
57978
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
57946
57979
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
57947
57980
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -57984,8 +58017,8 @@ async function startDaemon(config) {
|
|
|
57984
58017
|
}
|
|
57985
58018
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
57986
58019
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
57987
|
-
sourceJsonlPath =
|
|
57988
|
-
|
|
58020
|
+
sourceJsonlPath = import_node_path55.default.join(
|
|
58021
|
+
import_node_os21.default.homedir(),
|
|
57989
58022
|
".claude",
|
|
57990
58023
|
"projects",
|
|
57991
58024
|
cwdToHashDir(sourceFile.cwd),
|
|
@@ -58284,8 +58317,8 @@ async function startDaemon(config) {
|
|
|
58284
58317
|
const lines = [
|
|
58285
58318
|
`Tunnel: ${r.url}`,
|
|
58286
58319
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
58287
|
-
`Frpc config: ${
|
|
58288
|
-
`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")}`
|
|
58289
58322
|
];
|
|
58290
58323
|
const width = Math.max(...lines.map((l) => l.length));
|
|
58291
58324
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -58298,7 +58331,7 @@ ${bar}
|
|
|
58298
58331
|
|
|
58299
58332
|
`);
|
|
58300
58333
|
try {
|
|
58301
|
-
const connectPath =
|
|
58334
|
+
const connectPath = import_node_path55.default.join(config.dataDir, "connect.txt");
|
|
58302
58335
|
import_node_fs42.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
58303
58336
|
} catch {
|
|
58304
58337
|
}
|
|
@@ -58371,7 +58404,7 @@ ${bar}
|
|
|
58371
58404
|
};
|
|
58372
58405
|
}
|
|
58373
58406
|
function migrateDropPersonsDir(dataDir) {
|
|
58374
|
-
const dir =
|
|
58407
|
+
const dir = import_node_path55.default.join(dataDir, "persons");
|
|
58375
58408
|
try {
|
|
58376
58409
|
import_node_fs42.default.rmSync(dir, { recursive: true, force: true });
|
|
58377
58410
|
} catch {
|