@clawos-dev/clawd 0.2.190-beta.380.a359b26 → 0.2.191-beta.381.2ccc9ac
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 +647 -505
- package/dist/dispatch/mcp-server.cjs +1 -1
- package/dist/inbox/mcp-server.cjs +21181 -0
- package/dist/persona-defaults/persona-bug-fixer/.claude/settings.json +7 -0
- package/dist/persona-defaults/persona-bug-fixer/.mcp.json +15 -0
- package/dist/persona-defaults/persona-bug-fixer/CLAUDE.md +102 -0
- package/dist/persona-defaults/persona-ticket-manager/CLAUDE.md +97 -0
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-DiorWojn.js → guest-DG1-7F5a.js} +118 -118
- package/dist/share-ui/assets/{guest-3SNamz2y.css → guest-DfbgxtZt.css} +1 -1
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -5599,7 +5599,7 @@ var init_capability = __esm({
|
|
|
5599
5599
|
});
|
|
5600
5600
|
|
|
5601
5601
|
// ../protocol/src/inbox.ts
|
|
5602
|
-
var InboxMessageSchema, InboxPostMessageArgsSchema, InboxListArgsSchema, InboxMarkReadArgsSchema;
|
|
5602
|
+
var InboxMessageSchema, InboxPostMessageArgsSchema, InboxListArgsSchema, InboxMarkReadArgsSchema, InboxSendDmArgsSchema;
|
|
5603
5603
|
var init_inbox = __esm({
|
|
5604
5604
|
"../protocol/src/inbox.ts"() {
|
|
5605
5605
|
"use strict";
|
|
@@ -5610,13 +5610,18 @@ var init_inbox = __esm({
|
|
|
5610
5610
|
senderDeviceId: external_exports.string().min(1),
|
|
5611
5611
|
text: external_exports.string().min(1),
|
|
5612
5612
|
createdAt: external_exports.number().int().nonnegative(),
|
|
5613
|
-
readBy: external_exports.record(external_exports.string().min(1), external_exports.number().int().positive()).default({})
|
|
5613
|
+
readBy: external_exports.record(external_exports.string().min(1), external_exports.number().int().positive()).default({}),
|
|
5614
|
+
// persona 代发署名(B 版设计):非空 = 该消息由某 persona 代发,非真人手打。
|
|
5615
|
+
// 缺省 = 真人。routing 身份仍看 senderDeviceId;origin 只用于末端 UI 渲染来源。
|
|
5616
|
+
origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
|
|
5614
5617
|
}).strict();
|
|
5615
5618
|
InboxPostMessageArgsSchema = external_exports.object({
|
|
5616
5619
|
peerDeviceId: external_exports.string().min(1).optional(),
|
|
5617
5620
|
id: external_exports.string().min(1),
|
|
5618
5621
|
text: external_exports.string().min(1),
|
|
5619
|
-
createdAt: external_exports.number().int().nonnegative()
|
|
5622
|
+
createdAt: external_exports.number().int().nonnegative(),
|
|
5623
|
+
// persona 代发署名(跨 daemon forward 时随远程腿透传;真人发缺省)。
|
|
5624
|
+
origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
|
|
5620
5625
|
}).strict();
|
|
5621
5626
|
InboxListArgsSchema = external_exports.object({
|
|
5622
5627
|
peerDeviceId: external_exports.string().min(1),
|
|
@@ -5626,6 +5631,10 @@ var init_inbox = __esm({
|
|
|
5626
5631
|
peerDeviceId: external_exports.string().min(1),
|
|
5627
5632
|
upToCreatedAt: external_exports.number().int().nonnegative()
|
|
5628
5633
|
}).strict();
|
|
5634
|
+
InboxSendDmArgsSchema = external_exports.object({
|
|
5635
|
+
peerDeviceId: external_exports.string().min(1).optional(),
|
|
5636
|
+
text: external_exports.string().min(1)
|
|
5637
|
+
});
|
|
5629
5638
|
}
|
|
5630
5639
|
});
|
|
5631
5640
|
|
|
@@ -7276,7 +7285,7 @@ var require_atomic_sleep = __commonJS({
|
|
|
7276
7285
|
var require_sonic_boom = __commonJS({
|
|
7277
7286
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
7278
7287
|
"use strict";
|
|
7279
|
-
var
|
|
7288
|
+
var fs61 = require("fs");
|
|
7280
7289
|
var EventEmitter3 = require("events");
|
|
7281
7290
|
var inherits = require("util").inherits;
|
|
7282
7291
|
var path67 = require("path");
|
|
@@ -7333,20 +7342,20 @@ var require_sonic_boom = __commonJS({
|
|
|
7333
7342
|
const mode = sonic.mode;
|
|
7334
7343
|
if (sonic.sync) {
|
|
7335
7344
|
try {
|
|
7336
|
-
if (sonic.mkdir)
|
|
7337
|
-
const fd =
|
|
7345
|
+
if (sonic.mkdir) fs61.mkdirSync(path67.dirname(file), { recursive: true });
|
|
7346
|
+
const fd = fs61.openSync(file, flags, mode);
|
|
7338
7347
|
fileOpened(null, fd);
|
|
7339
7348
|
} catch (err) {
|
|
7340
7349
|
fileOpened(err);
|
|
7341
7350
|
throw err;
|
|
7342
7351
|
}
|
|
7343
7352
|
} else if (sonic.mkdir) {
|
|
7344
|
-
|
|
7353
|
+
fs61.mkdir(path67.dirname(file), { recursive: true }, (err) => {
|
|
7345
7354
|
if (err) return fileOpened(err);
|
|
7346
|
-
|
|
7355
|
+
fs61.open(file, flags, mode, fileOpened);
|
|
7347
7356
|
});
|
|
7348
7357
|
} else {
|
|
7349
|
-
|
|
7358
|
+
fs61.open(file, flags, mode, fileOpened);
|
|
7350
7359
|
}
|
|
7351
7360
|
}
|
|
7352
7361
|
function SonicBoom(opts) {
|
|
@@ -7387,8 +7396,8 @@ var require_sonic_boom = __commonJS({
|
|
|
7387
7396
|
this.flush = flushBuffer;
|
|
7388
7397
|
this.flushSync = flushBufferSync;
|
|
7389
7398
|
this._actualWrite = actualWriteBuffer;
|
|
7390
|
-
fsWriteSync = () =>
|
|
7391
|
-
fsWrite = () =>
|
|
7399
|
+
fsWriteSync = () => fs61.writeSync(this.fd, this._writingBuf);
|
|
7400
|
+
fsWrite = () => fs61.write(this.fd, this._writingBuf, this.release);
|
|
7392
7401
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
7393
7402
|
this._writingBuf = "";
|
|
7394
7403
|
this.write = write;
|
|
@@ -7397,15 +7406,15 @@ var require_sonic_boom = __commonJS({
|
|
|
7397
7406
|
this._actualWrite = actualWrite;
|
|
7398
7407
|
fsWriteSync = () => {
|
|
7399
7408
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7400
|
-
return
|
|
7409
|
+
return fs61.writeSync(this.fd, this._writingBuf);
|
|
7401
7410
|
}
|
|
7402
|
-
return
|
|
7411
|
+
return fs61.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7403
7412
|
};
|
|
7404
7413
|
fsWrite = () => {
|
|
7405
7414
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7406
|
-
return
|
|
7415
|
+
return fs61.write(this.fd, this._writingBuf, this.release);
|
|
7407
7416
|
}
|
|
7408
|
-
return
|
|
7417
|
+
return fs61.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
7409
7418
|
};
|
|
7410
7419
|
} else {
|
|
7411
7420
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -7462,7 +7471,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7462
7471
|
}
|
|
7463
7472
|
}
|
|
7464
7473
|
if (this._fsync) {
|
|
7465
|
-
|
|
7474
|
+
fs61.fsyncSync(this.fd);
|
|
7466
7475
|
}
|
|
7467
7476
|
const len = this._len;
|
|
7468
7477
|
if (this._reopening) {
|
|
@@ -7576,7 +7585,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7576
7585
|
const onDrain = () => {
|
|
7577
7586
|
if (!this._fsync) {
|
|
7578
7587
|
try {
|
|
7579
|
-
|
|
7588
|
+
fs61.fsync(this.fd, (err) => {
|
|
7580
7589
|
this._flushPending = false;
|
|
7581
7590
|
cb(err);
|
|
7582
7591
|
});
|
|
@@ -7678,7 +7687,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7678
7687
|
const fd = this.fd;
|
|
7679
7688
|
this.once("ready", () => {
|
|
7680
7689
|
if (fd !== this.fd) {
|
|
7681
|
-
|
|
7690
|
+
fs61.close(fd, (err) => {
|
|
7682
7691
|
if (err) {
|
|
7683
7692
|
return this.emit("error", err);
|
|
7684
7693
|
}
|
|
@@ -7727,7 +7736,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7727
7736
|
buf = this._bufs[0];
|
|
7728
7737
|
}
|
|
7729
7738
|
try {
|
|
7730
|
-
const n = Buffer.isBuffer(buf) ?
|
|
7739
|
+
const n = Buffer.isBuffer(buf) ? fs61.writeSync(this.fd, buf) : fs61.writeSync(this.fd, buf, "utf8");
|
|
7731
7740
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
7732
7741
|
buf = releasedBufObj.writingBuf;
|
|
7733
7742
|
this._len = releasedBufObj.len;
|
|
@@ -7743,7 +7752,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7743
7752
|
}
|
|
7744
7753
|
}
|
|
7745
7754
|
try {
|
|
7746
|
-
|
|
7755
|
+
fs61.fsyncSync(this.fd);
|
|
7747
7756
|
} catch {
|
|
7748
7757
|
}
|
|
7749
7758
|
}
|
|
@@ -7764,7 +7773,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7764
7773
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
7765
7774
|
}
|
|
7766
7775
|
try {
|
|
7767
|
-
const n =
|
|
7776
|
+
const n = fs61.writeSync(this.fd, buf);
|
|
7768
7777
|
buf = buf.subarray(n);
|
|
7769
7778
|
this._len = Math.max(this._len - n, 0);
|
|
7770
7779
|
if (buf.length <= 0) {
|
|
@@ -7792,13 +7801,13 @@ var require_sonic_boom = __commonJS({
|
|
|
7792
7801
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
7793
7802
|
if (this.sync) {
|
|
7794
7803
|
try {
|
|
7795
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
7804
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs61.writeSync(this.fd, this._writingBuf) : fs61.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7796
7805
|
release(null, written);
|
|
7797
7806
|
} catch (err) {
|
|
7798
7807
|
release(err);
|
|
7799
7808
|
}
|
|
7800
7809
|
} else {
|
|
7801
|
-
|
|
7810
|
+
fs61.write(this.fd, this._writingBuf, release);
|
|
7802
7811
|
}
|
|
7803
7812
|
}
|
|
7804
7813
|
function actualWriteBuffer() {
|
|
@@ -7807,7 +7816,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7807
7816
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
7808
7817
|
if (this.sync) {
|
|
7809
7818
|
try {
|
|
7810
|
-
const written =
|
|
7819
|
+
const written = fs61.writeSync(this.fd, this._writingBuf);
|
|
7811
7820
|
release(null, written);
|
|
7812
7821
|
} catch (err) {
|
|
7813
7822
|
release(err);
|
|
@@ -7816,7 +7825,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7816
7825
|
if (kCopyBuffer) {
|
|
7817
7826
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
7818
7827
|
}
|
|
7819
|
-
|
|
7828
|
+
fs61.write(this.fd, this._writingBuf, release);
|
|
7820
7829
|
}
|
|
7821
7830
|
}
|
|
7822
7831
|
function actualClose(sonic) {
|
|
@@ -7832,12 +7841,12 @@ var require_sonic_boom = __commonJS({
|
|
|
7832
7841
|
sonic._lens = [];
|
|
7833
7842
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
7834
7843
|
try {
|
|
7835
|
-
|
|
7844
|
+
fs61.fsync(sonic.fd, closeWrapped);
|
|
7836
7845
|
} catch {
|
|
7837
7846
|
}
|
|
7838
7847
|
function closeWrapped() {
|
|
7839
7848
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
7840
|
-
|
|
7849
|
+
fs61.close(sonic.fd, done);
|
|
7841
7850
|
} else {
|
|
7842
7851
|
done();
|
|
7843
7852
|
}
|
|
@@ -10201,7 +10210,7 @@ var require_multistream = __commonJS({
|
|
|
10201
10210
|
var require_pino = __commonJS({
|
|
10202
10211
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
10203
10212
|
"use strict";
|
|
10204
|
-
var
|
|
10213
|
+
var os22 = require("os");
|
|
10205
10214
|
var stdSerializers = require_pino_std_serializers();
|
|
10206
10215
|
var caller = require_caller();
|
|
10207
10216
|
var redaction = require_redaction();
|
|
@@ -10248,7 +10257,7 @@ var require_pino = __commonJS({
|
|
|
10248
10257
|
} = symbols;
|
|
10249
10258
|
var { epochTime, nullTime } = time;
|
|
10250
10259
|
var { pid } = process;
|
|
10251
|
-
var hostname =
|
|
10260
|
+
var hostname = os22.hostname();
|
|
10252
10261
|
var defaultErrorSerializer = stdSerializers.err;
|
|
10253
10262
|
var defaultOptions = {
|
|
10254
10263
|
level: "info",
|
|
@@ -11044,7 +11053,7 @@ var init_lib = __esm({
|
|
|
11044
11053
|
tokenize: function tokenize(value) {
|
|
11045
11054
|
return Array.from(value);
|
|
11046
11055
|
},
|
|
11047
|
-
join: function
|
|
11056
|
+
join: function join5(chars) {
|
|
11048
11057
|
return chars.join("");
|
|
11049
11058
|
},
|
|
11050
11059
|
postProcess: function postProcess(changeObjects) {
|
|
@@ -11226,33 +11235,13 @@ var init_tool_result_extra = __esm({
|
|
|
11226
11235
|
function cwdToHashDir(cwd) {
|
|
11227
11236
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
11228
11237
|
}
|
|
11229
|
-
function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
|
|
11230
|
-
const dir = import_node_path4.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
|
|
11231
|
-
let entries;
|
|
11232
|
-
try {
|
|
11233
|
-
entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
11234
|
-
} catch {
|
|
11235
|
-
return null;
|
|
11236
|
-
}
|
|
11237
|
-
let newest = null;
|
|
11238
|
-
for (const e of entries) {
|
|
11239
|
-
if (!e.isFile()) continue;
|
|
11240
|
-
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11241
|
-
try {
|
|
11242
|
-
const m2 = import_node_fs4.default.statSync(import_node_path4.default.join(dir, e.name)).mtimeMs;
|
|
11243
|
-
if (newest === null || m2 > newest) newest = m2;
|
|
11244
|
-
} catch {
|
|
11245
|
-
}
|
|
11246
|
-
}
|
|
11247
|
-
return newest;
|
|
11248
|
-
}
|
|
11249
11238
|
function hashDirToCwd(hash) {
|
|
11250
11239
|
const body = hash.startsWith("-") ? hash.slice(1) : hash;
|
|
11251
11240
|
return "/" + body.replace(/-/g, "/");
|
|
11252
11241
|
}
|
|
11253
11242
|
function safeStatMtime(p2) {
|
|
11254
11243
|
try {
|
|
11255
|
-
return
|
|
11244
|
+
return import_node_fs13.default.statSync(p2).mtimeMs;
|
|
11256
11245
|
} catch {
|
|
11257
11246
|
return 0;
|
|
11258
11247
|
}
|
|
@@ -11260,7 +11249,7 @@ function safeStatMtime(p2) {
|
|
|
11260
11249
|
function readJsonlLines(file) {
|
|
11261
11250
|
let raw;
|
|
11262
11251
|
try {
|
|
11263
|
-
raw =
|
|
11252
|
+
raw = import_node_fs13.default.readFileSync(file, "utf8");
|
|
11264
11253
|
} catch (err) {
|
|
11265
11254
|
if (err.code === "ENOENT") return [];
|
|
11266
11255
|
throw err;
|
|
@@ -11491,8 +11480,8 @@ function attachmentDeferredToolsText(a) {
|
|
|
11491
11480
|
function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
11492
11481
|
if (backupFileName === null) return null;
|
|
11493
11482
|
try {
|
|
11494
|
-
return
|
|
11495
|
-
|
|
11483
|
+
return import_node_fs13.default.readFileSync(
|
|
11484
|
+
import_node_path12.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
11496
11485
|
"utf8"
|
|
11497
11486
|
);
|
|
11498
11487
|
} catch {
|
|
@@ -11501,19 +11490,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
11501
11490
|
}
|
|
11502
11491
|
function readCurrentContent(filePath) {
|
|
11503
11492
|
try {
|
|
11504
|
-
return
|
|
11493
|
+
return import_node_fs13.default.readFileSync(filePath, "utf8");
|
|
11505
11494
|
} catch (err) {
|
|
11506
11495
|
if (err.code === "ENOENT") return null;
|
|
11507
11496
|
return null;
|
|
11508
11497
|
}
|
|
11509
11498
|
}
|
|
11510
|
-
var
|
|
11499
|
+
var import_node_fs13, import_node_os5, import_node_path12, 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;
|
|
11511
11500
|
var init_claude_history = __esm({
|
|
11512
11501
|
"src/tools/claude-history.ts"() {
|
|
11513
11502
|
"use strict";
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11503
|
+
import_node_fs13 = __toESM(require("fs"), 1);
|
|
11504
|
+
import_node_os5 = __toESM(require("os"), 1);
|
|
11505
|
+
import_node_path12 = __toESM(require("path"), 1);
|
|
11517
11506
|
init_lib();
|
|
11518
11507
|
init_tool_result_extra();
|
|
11519
11508
|
TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
|
|
@@ -11537,14 +11526,14 @@ var init_claude_history = __esm({
|
|
|
11537
11526
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
11538
11527
|
fileHistoryRoot;
|
|
11539
11528
|
constructor(opts = {}) {
|
|
11540
|
-
const base = opts.baseDir ??
|
|
11541
|
-
this.projectsRoot =
|
|
11542
|
-
this.fileHistoryRoot =
|
|
11529
|
+
const base = opts.baseDir ?? import_node_path12.default.join(import_node_os5.default.homedir(), ".claude");
|
|
11530
|
+
this.projectsRoot = import_node_path12.default.join(base, "projects");
|
|
11531
|
+
this.fileHistoryRoot = import_node_path12.default.join(base, "file-history");
|
|
11543
11532
|
}
|
|
11544
11533
|
async listProjects() {
|
|
11545
11534
|
let entries;
|
|
11546
11535
|
try {
|
|
11547
|
-
entries =
|
|
11536
|
+
entries = import_node_fs13.default.readdirSync(this.projectsRoot, { withFileTypes: true });
|
|
11548
11537
|
} catch (err) {
|
|
11549
11538
|
if (err.code === "ENOENT") return [];
|
|
11550
11539
|
throw err;
|
|
@@ -11552,9 +11541,9 @@ var init_claude_history = __esm({
|
|
|
11552
11541
|
const out = [];
|
|
11553
11542
|
for (const ent of entries) {
|
|
11554
11543
|
if (!ent.isDirectory()) continue;
|
|
11555
|
-
const dir =
|
|
11556
|
-
const files =
|
|
11557
|
-
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(
|
|
11544
|
+
const dir = import_node_path12.default.join(this.projectsRoot, ent.name);
|
|
11545
|
+
const files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11546
|
+
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path12.default.join(dir, f))), 0);
|
|
11558
11547
|
out.push({
|
|
11559
11548
|
projectPath: hashDirToCwd(ent.name),
|
|
11560
11549
|
hashDir: ent.name,
|
|
@@ -11566,17 +11555,17 @@ var init_claude_history = __esm({
|
|
|
11566
11555
|
return out;
|
|
11567
11556
|
}
|
|
11568
11557
|
async listSessions(args) {
|
|
11569
|
-
const dir =
|
|
11558
|
+
const dir = import_node_path12.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
11570
11559
|
let files;
|
|
11571
11560
|
try {
|
|
11572
|
-
files =
|
|
11561
|
+
files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11573
11562
|
} catch (err) {
|
|
11574
11563
|
if (err.code === "ENOENT") return [];
|
|
11575
11564
|
throw err;
|
|
11576
11565
|
}
|
|
11577
11566
|
const out = [];
|
|
11578
11567
|
for (const f of files) {
|
|
11579
|
-
const full =
|
|
11568
|
+
const full = import_node_path12.default.join(dir, f);
|
|
11580
11569
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
11581
11570
|
const lines = readJsonlLines(full);
|
|
11582
11571
|
let summary = "";
|
|
@@ -11631,7 +11620,7 @@ var init_claude_history = __esm({
|
|
|
11631
11620
|
return out;
|
|
11632
11621
|
}
|
|
11633
11622
|
async read(args) {
|
|
11634
|
-
const file =
|
|
11623
|
+
const file = import_node_path12.default.join(
|
|
11635
11624
|
this.projectsRoot,
|
|
11636
11625
|
cwdToHashDir(args.cwd),
|
|
11637
11626
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11668,7 +11657,7 @@ var init_claude_history = __esm({
|
|
|
11668
11657
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
11669
11658
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
11670
11659
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
11671
|
-
const dir =
|
|
11660
|
+
const dir = import_node_path12.default.join(
|
|
11672
11661
|
this.projectsRoot,
|
|
11673
11662
|
cwdToHashDir(cwd),
|
|
11674
11663
|
toolSessionId,
|
|
@@ -11676,7 +11665,7 @@ var init_claude_history = __esm({
|
|
|
11676
11665
|
);
|
|
11677
11666
|
let entries;
|
|
11678
11667
|
try {
|
|
11679
|
-
entries =
|
|
11668
|
+
entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
|
|
11680
11669
|
} catch (err) {
|
|
11681
11670
|
if (err.code === "ENOENT") return null;
|
|
11682
11671
|
return null;
|
|
@@ -11686,7 +11675,7 @@ var init_claude_history = __esm({
|
|
|
11686
11675
|
if (!e.isFile()) continue;
|
|
11687
11676
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11688
11677
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
11689
|
-
const filePath =
|
|
11678
|
+
const filePath = import_node_path12.default.join(dir, e.name);
|
|
11690
11679
|
const lines = readJsonlLines(filePath);
|
|
11691
11680
|
let firstText = "";
|
|
11692
11681
|
let messageCount = 0;
|
|
@@ -11703,7 +11692,7 @@ var init_claude_history = __esm({
|
|
|
11703
11692
|
return out;
|
|
11704
11693
|
}
|
|
11705
11694
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
11706
|
-
const file =
|
|
11695
|
+
const file = import_node_path12.default.join(
|
|
11707
11696
|
this.projectsRoot,
|
|
11708
11697
|
cwdToHashDir(cwd),
|
|
11709
11698
|
`${toolSessionId}.jsonl`
|
|
@@ -11738,7 +11727,7 @@ var init_claude_history = __esm({
|
|
|
11738
11727
|
}
|
|
11739
11728
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
11740
11729
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
11741
|
-
const file =
|
|
11730
|
+
const file = import_node_path12.default.join(
|
|
11742
11731
|
this.projectsRoot,
|
|
11743
11732
|
cwdToHashDir(cwd),
|
|
11744
11733
|
toolSessionId,
|
|
@@ -11747,7 +11736,7 @@ var init_claude_history = __esm({
|
|
|
11747
11736
|
);
|
|
11748
11737
|
let exists = false;
|
|
11749
11738
|
try {
|
|
11750
|
-
exists =
|
|
11739
|
+
exists = import_node_fs13.default.statSync(file).isFile();
|
|
11751
11740
|
} catch {
|
|
11752
11741
|
return null;
|
|
11753
11742
|
}
|
|
@@ -11766,7 +11755,7 @@ var init_claude_history = __esm({
|
|
|
11766
11755
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
11767
11756
|
*/
|
|
11768
11757
|
readFileHistorySnapshots(args) {
|
|
11769
|
-
const file =
|
|
11758
|
+
const file = import_node_path12.default.join(
|
|
11770
11759
|
this.projectsRoot,
|
|
11771
11760
|
cwdToHashDir(args.cwd),
|
|
11772
11761
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11811,7 +11800,7 @@ var init_claude_history = __esm({
|
|
|
11811
11800
|
for (const [anchorId, target] of snapshots) {
|
|
11812
11801
|
let hasAny = false;
|
|
11813
11802
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11814
|
-
const absPath =
|
|
11803
|
+
const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
|
|
11815
11804
|
const backupContent = readBackupContent(
|
|
11816
11805
|
this.fileHistoryRoot,
|
|
11817
11806
|
args.toolSessionId,
|
|
@@ -11851,7 +11840,7 @@ var init_claude_history = __esm({
|
|
|
11851
11840
|
let totalInsertions = 0;
|
|
11852
11841
|
let totalDeletions = 0;
|
|
11853
11842
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11854
|
-
const absPath =
|
|
11843
|
+
const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
|
|
11855
11844
|
const backupContent = readBackupContent(
|
|
11856
11845
|
this.fileHistoryRoot,
|
|
11857
11846
|
args.toolSessionId,
|
|
@@ -11898,7 +11887,7 @@ var init_claude_history = __esm({
|
|
|
11898
11887
|
};
|
|
11899
11888
|
}
|
|
11900
11889
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
11901
|
-
const file =
|
|
11890
|
+
const file = import_node_path12.default.join(
|
|
11902
11891
|
this.projectsRoot,
|
|
11903
11892
|
cwdToHashDir(cwd),
|
|
11904
11893
|
`${toolSessionId}.jsonl`
|
|
@@ -11984,6 +11973,9 @@ function buildSpawnArgs(ctx) {
|
|
|
11984
11973
|
if (ctx.shiftMcpConfigPath) {
|
|
11985
11974
|
args.push("--mcp-config", ctx.shiftMcpConfigPath);
|
|
11986
11975
|
}
|
|
11976
|
+
if (ctx.inboxMcpConfigPath) {
|
|
11977
|
+
args.push("--mcp-config", ctx.inboxMcpConfigPath);
|
|
11978
|
+
}
|
|
11987
11979
|
args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
|
|
11988
11980
|
if (ctx.effort) args.push("--effort", ctx.effort);
|
|
11989
11981
|
if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
|
|
@@ -40112,8 +40104,8 @@ function startRunCaseRecorder(opts) {
|
|
|
40112
40104
|
});
|
|
40113
40105
|
const ensureStream = () => {
|
|
40114
40106
|
if (stream) return stream;
|
|
40115
|
-
|
|
40116
|
-
stream =
|
|
40107
|
+
import_node_fs43.default.mkdirSync(dir, { recursive: true });
|
|
40108
|
+
stream = import_node_fs43.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
40117
40109
|
stream.on("close", () => closedResolve());
|
|
40118
40110
|
return stream;
|
|
40119
40111
|
};
|
|
@@ -40138,11 +40130,11 @@ function startRunCaseRecorder(opts) {
|
|
|
40138
40130
|
};
|
|
40139
40131
|
return { tap, close, closed };
|
|
40140
40132
|
}
|
|
40141
|
-
var
|
|
40133
|
+
var import_node_fs43, import_node_path55;
|
|
40142
40134
|
var init_recorder = __esm({
|
|
40143
40135
|
"src/run-case/recorder.ts"() {
|
|
40144
40136
|
"use strict";
|
|
40145
|
-
|
|
40137
|
+
import_node_fs43 = __toESM(require("fs"), 1);
|
|
40146
40138
|
import_node_path55 = __toESM(require("path"), 1);
|
|
40147
40139
|
}
|
|
40148
40140
|
});
|
|
@@ -40186,7 +40178,7 @@ var init_wire = __esm({
|
|
|
40186
40178
|
// src/run-case/controller.ts
|
|
40187
40179
|
async function runController(opts) {
|
|
40188
40180
|
const now = opts.now ?? Date.now;
|
|
40189
|
-
const cwd = opts.cwd ?? (0,
|
|
40181
|
+
const cwd = opts.cwd ?? (0, import_node_fs44.mkdtempSync)(import_node_path56.default.join(import_node_os21.default.tmpdir(), "clawd-runcase-"));
|
|
40190
40182
|
const ownsCwd = opts.cwd === void 0;
|
|
40191
40183
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40192
40184
|
const spawnCtx = { cwd };
|
|
@@ -40347,18 +40339,18 @@ async function runController(opts) {
|
|
|
40347
40339
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
40348
40340
|
if (ownsCwd) {
|
|
40349
40341
|
try {
|
|
40350
|
-
(0,
|
|
40342
|
+
(0, import_node_fs44.rmSync)(cwd, { recursive: true, force: true });
|
|
40351
40343
|
} catch {
|
|
40352
40344
|
}
|
|
40353
40345
|
}
|
|
40354
40346
|
return exitCode ?? 0;
|
|
40355
40347
|
}
|
|
40356
|
-
var
|
|
40348
|
+
var import_node_fs44, import_node_os21, import_node_path56;
|
|
40357
40349
|
var init_controller = __esm({
|
|
40358
40350
|
"src/run-case/controller.ts"() {
|
|
40359
40351
|
"use strict";
|
|
40360
|
-
|
|
40361
|
-
|
|
40352
|
+
import_node_fs44 = require("fs");
|
|
40353
|
+
import_node_os21 = __toESM(require("os"), 1);
|
|
40362
40354
|
import_node_path56 = __toESM(require("path"), 1);
|
|
40363
40355
|
init_claude();
|
|
40364
40356
|
init_stdout_splitter();
|
|
@@ -40622,8 +40614,8 @@ Env (advanced):
|
|
|
40622
40614
|
|
|
40623
40615
|
// src/index.ts
|
|
40624
40616
|
var import_node_path54 = __toESM(require("path"), 1);
|
|
40625
|
-
var
|
|
40626
|
-
var
|
|
40617
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
40618
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
40627
40619
|
|
|
40628
40620
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
40629
40621
|
var byteToHex = [];
|
|
@@ -41240,9 +41232,9 @@ var SessionStoreFactory = class {
|
|
|
41240
41232
|
};
|
|
41241
41233
|
|
|
41242
41234
|
// src/session/manager.ts
|
|
41243
|
-
var
|
|
41244
|
-
var
|
|
41245
|
-
var
|
|
41235
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
41236
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
41237
|
+
var import_node_os3 = __toESM(require("os"), 1);
|
|
41246
41238
|
init_protocol();
|
|
41247
41239
|
|
|
41248
41240
|
// src/tools/guest-settings.ts
|
|
@@ -41340,10 +41332,6 @@ function escapeAttr(v2) {
|
|
|
41340
41332
|
return v2.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
41341
41333
|
}
|
|
41342
41334
|
|
|
41343
|
-
// src/session/runner.ts
|
|
41344
|
-
var import_node_os4 = __toESM(require("os"), 1);
|
|
41345
|
-
var import_node_path6 = __toESM(require("path"), 1);
|
|
41346
|
-
|
|
41347
41335
|
// src/session/reducer.ts
|
|
41348
41336
|
init_runtime();
|
|
41349
41337
|
|
|
@@ -41430,7 +41418,7 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
|
|
|
41430
41418
|
// src/dispatch/system-prompt.ts
|
|
41431
41419
|
var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
|
|
41432
41420
|
|
|
41433
|
-
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-
|
|
41421
|
+
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-bug-fixer\`\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
|
|
41434
41422
|
|
|
41435
41423
|
- \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
|
|
41436
41424
|
- \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
|
|
@@ -41482,7 +41470,7 @@ function cloneState(s) {
|
|
|
41482
41470
|
pendingSend: s.pendingSend.slice()
|
|
41483
41471
|
};
|
|
41484
41472
|
}
|
|
41485
|
-
var IDLE_KILL_DELAY_MS =
|
|
41473
|
+
var IDLE_KILL_DELAY_MS = 6e4;
|
|
41486
41474
|
function tryFlushPending(state, deps) {
|
|
41487
41475
|
if (!state.readyForSend || state.pendingSend.length === 0) return [];
|
|
41488
41476
|
const text = state.pendingSend.shift();
|
|
@@ -41547,6 +41535,7 @@ function buildSpawnContext(state, deps) {
|
|
|
41547
41535
|
const ticketMcpConfigPathRaw = deps.getTicketMcpConfigPath?.() ?? null;
|
|
41548
41536
|
const ticketMcpConfigPath2 = ticketMcpConfigPathRaw && file.ownerPersonaId === "persona-ticket-manager" ? ticketMcpConfigPathRaw : null;
|
|
41549
41537
|
const shiftMcpConfigPath2 = deps.getShiftMcpConfigPath?.() ?? null;
|
|
41538
|
+
const inboxMcpConfigPath2 = deps.getInboxMcpConfigPath?.() ?? null;
|
|
41550
41539
|
const ctx = {
|
|
41551
41540
|
cwd: file.cwd,
|
|
41552
41541
|
toolSessionId: file.toolSessionId,
|
|
@@ -41562,6 +41551,7 @@ function buildSpawnContext(state, deps) {
|
|
|
41562
41551
|
dispatchMcpConfigPath: dispatchMcpConfigPath2 ?? void 0,
|
|
41563
41552
|
ticketMcpConfigPath: ticketMcpConfigPath2 ?? void 0,
|
|
41564
41553
|
shiftMcpConfigPath: shiftMcpConfigPath2 ?? void 0,
|
|
41554
|
+
inboxMcpConfigPath: inboxMcpConfigPath2 ?? void 0,
|
|
41565
41555
|
// shift v1:把 SessionFile.ownerPersonaId 透传到 SpawnContext;buildSpawnArgs 等下游
|
|
41566
41556
|
// 不直接读这个字段(只读 env),但保留显式字段方便 daemon 内部诊断/日志。
|
|
41567
41557
|
personaId
|
|
@@ -42151,18 +42141,6 @@ function reduceSession(state, input, deps) {
|
|
|
42151
42141
|
if (state.status !== "running-idle") {
|
|
42152
42142
|
return { state, effects: [] };
|
|
42153
42143
|
}
|
|
42154
|
-
if (input.subagentActive) {
|
|
42155
|
-
return {
|
|
42156
|
-
state,
|
|
42157
|
-
effects: [
|
|
42158
|
-
{
|
|
42159
|
-
kind: "schedule-idle-kill",
|
|
42160
|
-
sessionId: state.file.sessionId,
|
|
42161
|
-
ms: IDLE_KILL_DELAY_MS
|
|
42162
|
-
}
|
|
42163
|
-
]
|
|
42164
|
-
};
|
|
42165
|
-
}
|
|
42166
42144
|
const next = cloneState(state);
|
|
42167
42145
|
next.status = "stopping";
|
|
42168
42146
|
return {
|
|
@@ -42219,11 +42197,10 @@ function reduceSession(state, input, deps) {
|
|
|
42219
42197
|
// src/session/runner.ts
|
|
42220
42198
|
init_stdout_splitter();
|
|
42221
42199
|
init_permission_stdio();
|
|
42222
|
-
init_claude_history();
|
|
42223
42200
|
|
|
42224
42201
|
// src/ipc-recorder.ts
|
|
42225
|
-
var
|
|
42226
|
-
var
|
|
42202
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
42203
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
42227
42204
|
function tsForFilename(ms) {
|
|
42228
42205
|
return new Date(ms).toISOString().replace(/[:.]/g, "-");
|
|
42229
42206
|
}
|
|
@@ -42234,8 +42211,8 @@ function startRecorder(opts) {
|
|
|
42234
42211
|
return null;
|
|
42235
42212
|
}
|
|
42236
42213
|
const now = opts.now ?? Date.now;
|
|
42237
|
-
const dir =
|
|
42238
|
-
const filePath =
|
|
42214
|
+
const dir = import_node_path4.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
|
|
42215
|
+
const filePath = import_node_path4.default.join(dir, `${tsForFilename(now())}.jsonl`);
|
|
42239
42216
|
let stream = null;
|
|
42240
42217
|
let closedResolve;
|
|
42241
42218
|
const closed = new Promise((resolve6) => {
|
|
@@ -42244,8 +42221,8 @@ function startRecorder(opts) {
|
|
|
42244
42221
|
let exited = false;
|
|
42245
42222
|
const ensureStream = () => {
|
|
42246
42223
|
if (stream) return stream;
|
|
42247
|
-
|
|
42248
|
-
stream =
|
|
42224
|
+
import_node_fs4.default.mkdirSync(dir, { recursive: true });
|
|
42225
|
+
stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
|
|
42249
42226
|
stream.on("close", () => closedResolve());
|
|
42250
42227
|
return stream;
|
|
42251
42228
|
};
|
|
@@ -42290,7 +42267,6 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
|
|
|
42290
42267
|
return JSON.stringify(payload) + "\n";
|
|
42291
42268
|
}
|
|
42292
42269
|
var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
|
|
42293
|
-
var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
|
|
42294
42270
|
var SessionRunner = class {
|
|
42295
42271
|
constructor(initial, hooks) {
|
|
42296
42272
|
this.hooks = hooks;
|
|
@@ -42348,6 +42324,7 @@ var SessionRunner = class {
|
|
|
42348
42324
|
// 见 reducer.buildSpawnContext 注 CLAWD_DISPATCH_ID env / 派生 SpawnContext.dispatchMcpConfigPath
|
|
42349
42325
|
getDispatchMcpConfigPath: this.hooks.getDispatchMcpConfigPath,
|
|
42350
42326
|
getShiftMcpConfigPath: this.hooks.getShiftMcpConfigPath,
|
|
42327
|
+
getInboxMcpConfigPath: this.hooks.getInboxMcpConfigPath,
|
|
42351
42328
|
// Ticket MCP:透传 ticket.mcp.json 路径闭包(reducer 内做 persona-ticket-manager gating)
|
|
42352
42329
|
getTicketMcpConfigPath: this.hooks.getTicketMcpConfigPath,
|
|
42353
42330
|
lookupDispatchByBSessionId: this.hooks.lookupDispatchByBSessionId,
|
|
@@ -42602,7 +42579,7 @@ var SessionRunner = class {
|
|
|
42602
42579
|
if (existing) clearTimeout(existing);
|
|
42603
42580
|
const timer = setTimeout(() => {
|
|
42604
42581
|
this.idleKillTimers.delete(effect.sessionId);
|
|
42605
|
-
this.input({ kind: "idle-kill-fired"
|
|
42582
|
+
this.input({ kind: "idle-kill-fired" });
|
|
42606
42583
|
}, effect.ms);
|
|
42607
42584
|
timer.unref?.();
|
|
42608
42585
|
this.idleKillTimers.set(effect.sessionId, timer);
|
|
@@ -42618,18 +42595,6 @@ var SessionRunner = class {
|
|
|
42618
42595
|
}
|
|
42619
42596
|
}
|
|
42620
42597
|
}
|
|
42621
|
-
// idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
|
|
42622
|
-
// 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
|
|
42623
|
-
// 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
|
|
42624
|
-
isSubagentActive() {
|
|
42625
|
-
const toolSessionId = this.state.file.toolSessionId;
|
|
42626
|
-
if (!toolSessionId) return false;
|
|
42627
|
-
const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
|
|
42628
|
-
const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
|
|
42629
|
-
if (mtime === null) return false;
|
|
42630
|
-
const now = (this.hooks.now ?? Date.now)();
|
|
42631
|
-
return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
|
|
42632
|
-
}
|
|
42633
42598
|
// 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
|
|
42634
42599
|
// 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
|
|
42635
42600
|
clearIdleKillTimers() {
|
|
@@ -42712,15 +42677,15 @@ function extractEditPath(input) {
|
|
|
42712
42677
|
}
|
|
42713
42678
|
|
|
42714
42679
|
// src/debug/pty-probe.ts
|
|
42715
|
-
var
|
|
42716
|
-
var
|
|
42680
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
42681
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
42717
42682
|
var PROBE_DIR = "/tmp/clawd-probe";
|
|
42718
|
-
var EVENTS_FILE =
|
|
42683
|
+
var EVENTS_FILE = import_node_path5.default.join(PROBE_DIR, "events.jsonl");
|
|
42719
42684
|
var inited = false;
|
|
42720
42685
|
function ensureDir() {
|
|
42721
42686
|
if (inited) return true;
|
|
42722
42687
|
try {
|
|
42723
|
-
|
|
42688
|
+
import_node_fs5.default.mkdirSync(PROBE_DIR, { recursive: true });
|
|
42724
42689
|
inited = true;
|
|
42725
42690
|
return true;
|
|
42726
42691
|
} catch {
|
|
@@ -42731,15 +42696,15 @@ function probeEvent(event, data = {}) {
|
|
|
42731
42696
|
try {
|
|
42732
42697
|
if (!ensureDir()) return;
|
|
42733
42698
|
const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
|
|
42734
|
-
|
|
42699
|
+
import_node_fs5.default.appendFileSync(EVENTS_FILE, line);
|
|
42735
42700
|
} catch {
|
|
42736
42701
|
}
|
|
42737
42702
|
}
|
|
42738
42703
|
function probeDumpReplay(sessionId, payload) {
|
|
42739
42704
|
try {
|
|
42740
42705
|
if (!ensureDir()) return "";
|
|
42741
|
-
const file =
|
|
42742
|
-
|
|
42706
|
+
const file = import_node_path5.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
|
|
42707
|
+
import_node_fs5.default.writeFileSync(file, payload, "utf8");
|
|
42743
42708
|
return file;
|
|
42744
42709
|
} catch {
|
|
42745
42710
|
return "";
|
|
@@ -42846,7 +42811,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
|
|
|
42846
42811
|
`derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
|
|
42847
42812
|
);
|
|
42848
42813
|
}
|
|
42849
|
-
return
|
|
42814
|
+
return import_node_path6.default.join(personaRoot, safeFileName(personaId));
|
|
42850
42815
|
}
|
|
42851
42816
|
function makeInitialState(file, subSessionMeta) {
|
|
42852
42817
|
return {
|
|
@@ -42971,10 +42936,10 @@ var SessionManager = class {
|
|
|
42971
42936
|
// <dataDir>/sessions/ 列子目录 (排除 'default').
|
|
42972
42937
|
listPersonaIdsOnDisk() {
|
|
42973
42938
|
if (!this.deps.dataDir) return [];
|
|
42974
|
-
const root = this.deps.storeFactory ?
|
|
42939
|
+
const root = this.deps.storeFactory ? import_node_path6.default.join(this.deps.dataDir, "personas") : import_node_path6.default.join(this.deps.dataDir, "sessions");
|
|
42975
42940
|
let entries;
|
|
42976
42941
|
try {
|
|
42977
|
-
entries =
|
|
42942
|
+
entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
|
|
42978
42943
|
} catch (err) {
|
|
42979
42944
|
const code = err?.code;
|
|
42980
42945
|
if (code === "ENOENT") return [];
|
|
@@ -42987,7 +42952,7 @@ var SessionManager = class {
|
|
|
42987
42952
|
// 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
|
|
42988
42953
|
listGuestCapIdsForPersona(personaId) {
|
|
42989
42954
|
if (!this.deps.dataDir || !this.deps.storeFactory) return [];
|
|
42990
|
-
const root =
|
|
42955
|
+
const root = import_node_path6.default.join(
|
|
42991
42956
|
this.deps.dataDir,
|
|
42992
42957
|
"personas",
|
|
42993
42958
|
personaId,
|
|
@@ -42997,7 +42962,7 @@ var SessionManager = class {
|
|
|
42997
42962
|
);
|
|
42998
42963
|
let entries;
|
|
42999
42964
|
try {
|
|
43000
|
-
entries =
|
|
42965
|
+
entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
|
|
43001
42966
|
} catch (err) {
|
|
43002
42967
|
const code = err?.code;
|
|
43003
42968
|
if (code === "ENOENT") return [];
|
|
@@ -43116,7 +43081,7 @@ var SessionManager = class {
|
|
|
43116
43081
|
callerDisplayName
|
|
43117
43082
|
);
|
|
43118
43083
|
if (subSessionMeta?.userWorkDir) {
|
|
43119
|
-
|
|
43084
|
+
import_node_fs6.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
|
|
43120
43085
|
}
|
|
43121
43086
|
if (scope.kind === "persona" && scope.mode === "guest") {
|
|
43122
43087
|
if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
|
|
@@ -43127,8 +43092,8 @@ var SessionManager = class {
|
|
|
43127
43092
|
const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
|
|
43128
43093
|
const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
|
|
43129
43094
|
subSessionMeta.extraSettings = JSON.stringify(settings);
|
|
43130
|
-
const home =
|
|
43131
|
-
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ?
|
|
43095
|
+
const home = import_node_os3.default.homedir();
|
|
43096
|
+
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path6.default.join(home, p2.slice(2)) : p2;
|
|
43132
43097
|
const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
|
|
43133
43098
|
subSessionMeta.codexSandbox = {
|
|
43134
43099
|
writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
|
|
@@ -43162,6 +43127,7 @@ var SessionManager = class {
|
|
|
43162
43127
|
getDispatchMcpConfigPath: this.deps.dispatchMcpConfigPath ? () => this.deps.dispatchMcpConfigPath ?? null : void 0,
|
|
43163
43128
|
getTicketMcpConfigPath: this.deps.ticketMcpConfigPath ? () => this.deps.ticketMcpConfigPath ?? null : void 0,
|
|
43164
43129
|
getShiftMcpConfigPath: this.deps.shiftMcpConfigPath ? () => this.deps.shiftMcpConfigPath ?? null : void 0,
|
|
43130
|
+
getInboxMcpConfigPath: this.deps.inboxMcpConfigPath ? () => this.deps.inboxMcpConfigPath ?? null : void 0,
|
|
43165
43131
|
lookupDispatchByBSessionId: this.deps.personaDispatchManager ? (bSid) => this.deps.personaDispatchManager?.lookupDispatchByBSessionId(bSid) : void 0,
|
|
43166
43132
|
// file-sharing (spec §6 PR 3):闭包 scope + sessionId,runner 只暴露 tool/relPath/cwd
|
|
43167
43133
|
onFileEdit: attachmentGroup ? (input) => attachmentGroup.onFileEdit({
|
|
@@ -43280,7 +43246,7 @@ var SessionManager = class {
|
|
|
43280
43246
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
|
|
43281
43247
|
}
|
|
43282
43248
|
try {
|
|
43283
|
-
const stat =
|
|
43249
|
+
const stat = import_node_fs6.default.statSync(cwd);
|
|
43284
43250
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43285
43251
|
} catch {
|
|
43286
43252
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
|
|
@@ -43811,7 +43777,7 @@ var SessionManager = class {
|
|
|
43811
43777
|
*/
|
|
43812
43778
|
createForScope(args) {
|
|
43813
43779
|
try {
|
|
43814
|
-
const stat =
|
|
43780
|
+
const stat = import_node_fs6.default.statSync(args.cwd);
|
|
43815
43781
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43816
43782
|
} catch {
|
|
43817
43783
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -44027,7 +43993,7 @@ var SessionManager = class {
|
|
|
44027
43993
|
personaId: args.targetPersona,
|
|
44028
43994
|
mode: "owner"
|
|
44029
43995
|
};
|
|
44030
|
-
const cwd =
|
|
43996
|
+
const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44031
43997
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44032
43998
|
const file = {
|
|
44033
43999
|
sessionId,
|
|
@@ -44092,7 +44058,7 @@ var SessionManager = class {
|
|
|
44092
44058
|
personaId: args.targetPersona,
|
|
44093
44059
|
mode: "owner"
|
|
44094
44060
|
};
|
|
44095
|
-
const cwd =
|
|
44061
|
+
const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44096
44062
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44097
44063
|
const file = {
|
|
44098
44064
|
sessionId,
|
|
@@ -44574,28 +44540,28 @@ var SessionManager = class {
|
|
|
44574
44540
|
};
|
|
44575
44541
|
|
|
44576
44542
|
// src/persona/store.ts
|
|
44577
|
-
var
|
|
44578
|
-
var
|
|
44543
|
+
var fs7 = __toESM(require("fs"), 1);
|
|
44544
|
+
var path9 = __toESM(require("path"), 1);
|
|
44579
44545
|
init_protocol();
|
|
44580
44546
|
var PersonaStore = class {
|
|
44581
44547
|
constructor(root) {
|
|
44582
44548
|
this.root = root;
|
|
44583
|
-
|
|
44549
|
+
fs7.mkdirSync(root, { recursive: true });
|
|
44584
44550
|
}
|
|
44585
44551
|
root;
|
|
44586
44552
|
personaDir(personaId) {
|
|
44587
|
-
return
|
|
44553
|
+
return path9.join(this.root, safeFileName(personaId));
|
|
44588
44554
|
}
|
|
44589
44555
|
metaPath(personaId) {
|
|
44590
|
-
return
|
|
44556
|
+
return path9.join(this.personaDir(personaId), ".clawd", "persona.json");
|
|
44591
44557
|
}
|
|
44592
44558
|
claudeMdPath(personaId) {
|
|
44593
|
-
return
|
|
44559
|
+
return path9.join(this.personaDir(personaId), "CLAUDE.md");
|
|
44594
44560
|
}
|
|
44595
44561
|
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
44596
44562
|
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
44597
44563
|
agentsMdPath(personaId) {
|
|
44598
|
-
return
|
|
44564
|
+
return path9.join(this.personaDir(personaId), "AGENTS.md");
|
|
44599
44565
|
}
|
|
44600
44566
|
/**
|
|
44601
44567
|
* persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
@@ -44604,11 +44570,11 @@ var PersonaStore = class {
|
|
|
44604
44570
|
* spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
|
|
44605
44571
|
*/
|
|
44606
44572
|
sandboxSettingsPath(personaId) {
|
|
44607
|
-
return
|
|
44573
|
+
return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
|
|
44608
44574
|
}
|
|
44609
44575
|
write(persona, personality) {
|
|
44610
44576
|
const dir = this.personaDir(persona.personaId);
|
|
44611
|
-
|
|
44577
|
+
fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
|
|
44612
44578
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
44613
44579
|
this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
|
|
44614
44580
|
this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
|
|
@@ -44627,9 +44593,9 @@ var PersonaStore = class {
|
|
|
44627
44593
|
ensureAgentsMirror(personaId) {
|
|
44628
44594
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44629
44595
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44630
|
-
if (!
|
|
44631
|
-
if (
|
|
44632
|
-
this.atomicWrite(agentsMd,
|
|
44596
|
+
if (!fs7.existsSync(claudeMd)) return false;
|
|
44597
|
+
if (fs7.existsSync(agentsMd)) return false;
|
|
44598
|
+
this.atomicWrite(agentsMd, fs7.readFileSync(claudeMd, "utf8"));
|
|
44633
44599
|
return true;
|
|
44634
44600
|
}
|
|
44635
44601
|
/**
|
|
@@ -44653,22 +44619,22 @@ var PersonaStore = class {
|
|
|
44653
44619
|
return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
|
|
44654
44620
|
}
|
|
44655
44621
|
codexSandboxSettingsPath(personaId) {
|
|
44656
|
-
return
|
|
44622
|
+
return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
|
|
44657
44623
|
}
|
|
44658
44624
|
/** 读 codex-sandbox.json;不存在/损坏 → null。 */
|
|
44659
44625
|
readCodexSandboxSettings(personaId) {
|
|
44660
44626
|
const p2 = this.codexSandboxSettingsPath(personaId);
|
|
44661
|
-
if (!
|
|
44627
|
+
if (!fs7.existsSync(p2)) return null;
|
|
44662
44628
|
try {
|
|
44663
|
-
return CodexSandboxSettingsSchema.parse(JSON.parse(
|
|
44629
|
+
return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
|
|
44664
44630
|
} catch {
|
|
44665
44631
|
return null;
|
|
44666
44632
|
}
|
|
44667
44633
|
}
|
|
44668
44634
|
/** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
|
|
44669
44635
|
writeCodexSandboxSettings(personaId, settings) {
|
|
44670
|
-
const dir =
|
|
44671
|
-
|
|
44636
|
+
const dir = path9.join(this.personaDir(personaId), ".clawd");
|
|
44637
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
44672
44638
|
this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
|
|
44673
44639
|
}
|
|
44674
44640
|
writeMeta(persona) {
|
|
@@ -44676,8 +44642,8 @@ var PersonaStore = class {
|
|
|
44676
44642
|
}
|
|
44677
44643
|
read(personaId) {
|
|
44678
44644
|
const p2 = this.metaPath(personaId);
|
|
44679
|
-
if (!
|
|
44680
|
-
const raw = JSON.parse(
|
|
44645
|
+
if (!fs7.existsSync(p2)) return null;
|
|
44646
|
+
const raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
|
|
44681
44647
|
if (raw && typeof raw === "object" && "tokenMap" in raw) {
|
|
44682
44648
|
delete raw.tokenMap;
|
|
44683
44649
|
this.atomicWrite(p2, JSON.stringify(raw, null, 2));
|
|
@@ -44685,13 +44651,13 @@ var PersonaStore = class {
|
|
|
44685
44651
|
return PersonaFileSchema.parse(raw);
|
|
44686
44652
|
}
|
|
44687
44653
|
has(personaId) {
|
|
44688
|
-
return
|
|
44654
|
+
return fs7.existsSync(this.metaPath(personaId));
|
|
44689
44655
|
}
|
|
44690
44656
|
readPersonality(personaId) {
|
|
44691
44657
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44692
|
-
if (
|
|
44658
|
+
if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
|
|
44693
44659
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44694
|
-
if (
|
|
44660
|
+
if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
|
|
44695
44661
|
return null;
|
|
44696
44662
|
}
|
|
44697
44663
|
/**
|
|
@@ -44700,23 +44666,23 @@ var PersonaStore = class {
|
|
|
44700
44666
|
*/
|
|
44701
44667
|
readSandboxSettings(personaId) {
|
|
44702
44668
|
const p2 = this.sandboxSettingsPath(personaId);
|
|
44703
|
-
if (!
|
|
44669
|
+
if (!fs7.existsSync(p2)) return null;
|
|
44704
44670
|
try {
|
|
44705
|
-
return JSON.parse(
|
|
44671
|
+
return JSON.parse(fs7.readFileSync(p2, "utf8"));
|
|
44706
44672
|
} catch {
|
|
44707
44673
|
return null;
|
|
44708
44674
|
}
|
|
44709
44675
|
}
|
|
44710
44676
|
/** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
|
|
44711
44677
|
skillsDir(personaId) {
|
|
44712
|
-
return
|
|
44678
|
+
return path9.join(this.personaDir(personaId), ".claude", "skills");
|
|
44713
44679
|
}
|
|
44714
44680
|
/**
|
|
44715
44681
|
* Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
|
|
44716
44682
|
* 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
|
|
44717
44683
|
*/
|
|
44718
44684
|
claudeSettingsPath(personaId) {
|
|
44719
|
-
return
|
|
44685
|
+
return path9.join(this.personaDir(personaId), ".claude", "settings.json");
|
|
44720
44686
|
}
|
|
44721
44687
|
/**
|
|
44722
44688
|
* 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
|
|
@@ -44731,10 +44697,10 @@ var PersonaStore = class {
|
|
|
44731
44697
|
*/
|
|
44732
44698
|
readEnabledPlugins(personaId) {
|
|
44733
44699
|
const p2 = this.claudeSettingsPath(personaId);
|
|
44734
|
-
if (!
|
|
44700
|
+
if (!fs7.existsSync(p2)) return [];
|
|
44735
44701
|
let raw;
|
|
44736
44702
|
try {
|
|
44737
|
-
raw = JSON.parse(
|
|
44703
|
+
raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
|
|
44738
44704
|
} catch {
|
|
44739
44705
|
return [];
|
|
44740
44706
|
}
|
|
@@ -44748,22 +44714,22 @@ var PersonaStore = class {
|
|
|
44748
44714
|
return out;
|
|
44749
44715
|
}
|
|
44750
44716
|
list() {
|
|
44751
|
-
if (!
|
|
44752
|
-
return
|
|
44753
|
-
return
|
|
44717
|
+
if (!fs7.existsSync(this.root)) return [];
|
|
44718
|
+
return fs7.readdirSync(this.root).filter((name) => {
|
|
44719
|
+
return fs7.existsSync(path9.join(this.root, name, ".clawd", "persona.json"));
|
|
44754
44720
|
});
|
|
44755
44721
|
}
|
|
44756
44722
|
remove(personaId) {
|
|
44757
44723
|
const dir = this.personaDir(personaId);
|
|
44758
|
-
if (
|
|
44724
|
+
if (fs7.existsSync(dir)) fs7.rmSync(dir, { recursive: true, force: true });
|
|
44759
44725
|
}
|
|
44760
44726
|
personaDirPath(personaId) {
|
|
44761
44727
|
return this.personaDir(personaId);
|
|
44762
44728
|
}
|
|
44763
44729
|
atomicWrite(file, content) {
|
|
44764
44730
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
44765
|
-
|
|
44766
|
-
|
|
44731
|
+
fs7.writeFileSync(tmp, content, { mode: 384 });
|
|
44732
|
+
fs7.renameSync(tmp, file);
|
|
44767
44733
|
}
|
|
44768
44734
|
};
|
|
44769
44735
|
|
|
@@ -44809,9 +44775,9 @@ var PersonaRegistry = class {
|
|
|
44809
44775
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
44810
44776
|
|
|
44811
44777
|
// src/skills/scanner.ts
|
|
44812
|
-
var
|
|
44813
|
-
var
|
|
44814
|
-
var
|
|
44778
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
44779
|
+
var import_node_os4 = __toESM(require("os"), 1);
|
|
44780
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
44815
44781
|
|
|
44816
44782
|
// src/skills/frontmatter.ts
|
|
44817
44783
|
var STRIP_QUOTES = /^["']|["']$/g;
|
|
@@ -44920,7 +44886,7 @@ function parseDescription(content) {
|
|
|
44920
44886
|
}
|
|
44921
44887
|
function isDirLikeSync(p2) {
|
|
44922
44888
|
try {
|
|
44923
|
-
return
|
|
44889
|
+
return import_node_fs7.default.statSync(p2).isDirectory();
|
|
44924
44890
|
} catch {
|
|
44925
44891
|
return false;
|
|
44926
44892
|
}
|
|
@@ -44928,19 +44894,19 @@ function isDirLikeSync(p2) {
|
|
|
44928
44894
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
44929
44895
|
let entries;
|
|
44930
44896
|
try {
|
|
44931
|
-
entries =
|
|
44897
|
+
entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
|
|
44932
44898
|
} catch {
|
|
44933
44899
|
return;
|
|
44934
44900
|
}
|
|
44935
44901
|
for (const ent of entries) {
|
|
44936
|
-
const entryPath =
|
|
44902
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
44937
44903
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
44938
44904
|
let content;
|
|
44939
44905
|
try {
|
|
44940
|
-
content =
|
|
44906
|
+
content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
|
|
44941
44907
|
} catch {
|
|
44942
44908
|
try {
|
|
44943
|
-
content =
|
|
44909
|
+
content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
|
|
44944
44910
|
} catch {
|
|
44945
44911
|
continue;
|
|
44946
44912
|
}
|
|
@@ -44964,26 +44930,26 @@ function listSkillsForDir(dir, source) {
|
|
|
44964
44930
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
44965
44931
|
let entries;
|
|
44966
44932
|
try {
|
|
44967
|
-
entries =
|
|
44933
|
+
entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
|
|
44968
44934
|
} catch {
|
|
44969
44935
|
return;
|
|
44970
44936
|
}
|
|
44971
44937
|
for (const ent of entries) {
|
|
44972
|
-
const entryPath =
|
|
44938
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
44973
44939
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
44974
44940
|
const ns = ent.name;
|
|
44975
44941
|
let subEntries;
|
|
44976
44942
|
try {
|
|
44977
|
-
subEntries =
|
|
44943
|
+
subEntries = import_node_fs7.default.readdirSync(entryPath, { withFileTypes: true });
|
|
44978
44944
|
} catch {
|
|
44979
44945
|
continue;
|
|
44980
44946
|
}
|
|
44981
44947
|
for (const se of subEntries) {
|
|
44982
44948
|
if (!se.name.endsWith(".md")) continue;
|
|
44983
|
-
const sePath =
|
|
44949
|
+
const sePath = import_node_path7.default.join(entryPath, se.name);
|
|
44984
44950
|
let content;
|
|
44985
44951
|
try {
|
|
44986
|
-
content =
|
|
44952
|
+
content = import_node_fs7.default.readFileSync(sePath, "utf8");
|
|
44987
44953
|
} catch {
|
|
44988
44954
|
continue;
|
|
44989
44955
|
}
|
|
@@ -45000,7 +44966,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
45000
44966
|
} else if (ent.name.endsWith(".md")) {
|
|
45001
44967
|
let content;
|
|
45002
44968
|
try {
|
|
45003
|
-
content =
|
|
44969
|
+
content = import_node_fs7.default.readFileSync(entryPath, "utf8");
|
|
45004
44970
|
} catch {
|
|
45005
44971
|
continue;
|
|
45006
44972
|
}
|
|
@@ -45016,10 +44982,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
45016
44982
|
}
|
|
45017
44983
|
}
|
|
45018
44984
|
function readInstalledPlugins(home) {
|
|
45019
|
-
const file =
|
|
44985
|
+
const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
45020
44986
|
let raw;
|
|
45021
44987
|
try {
|
|
45022
|
-
raw =
|
|
44988
|
+
raw = import_node_fs7.default.readFileSync(file, "utf8");
|
|
45023
44989
|
} catch {
|
|
45024
44990
|
return [];
|
|
45025
44991
|
}
|
|
@@ -45044,7 +45010,7 @@ var SkillsScanner = class {
|
|
|
45044
45010
|
home;
|
|
45045
45011
|
extraPluginRoots;
|
|
45046
45012
|
constructor(opts = {}) {
|
|
45047
|
-
this.home = opts.home ??
|
|
45013
|
+
this.home = opts.home ?? import_node_os4.default.homedir();
|
|
45048
45014
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
45049
45015
|
}
|
|
45050
45016
|
/**
|
|
@@ -45067,14 +45033,14 @@ var SkillsScanner = class {
|
|
|
45067
45033
|
});
|
|
45068
45034
|
}
|
|
45069
45035
|
const fsBlock = [];
|
|
45070
|
-
scanSkillDir(
|
|
45071
|
-
scanCommandDir(
|
|
45072
|
-
scanSkillDir(
|
|
45073
|
-
scanCommandDir(
|
|
45036
|
+
scanSkillDir(import_node_path7.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
|
|
45037
|
+
scanCommandDir(import_node_path7.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
|
|
45038
|
+
scanSkillDir(import_node_path7.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
|
|
45039
|
+
scanCommandDir(import_node_path7.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
|
|
45074
45040
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
45075
45041
|
for (const { name, root } of plugins) {
|
|
45076
|
-
scanSkillDir(
|
|
45077
|
-
scanCommandDir(
|
|
45042
|
+
scanSkillDir(import_node_path7.default.join(root, "skills"), "plugin", seen, fsBlock, name);
|
|
45043
|
+
scanCommandDir(import_node_path7.default.join(root, "commands"), "plugin", seen, fsBlock, name);
|
|
45078
45044
|
}
|
|
45079
45045
|
fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
|
|
45080
45046
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -45180,8 +45146,8 @@ var PersonaManager = class {
|
|
|
45180
45146
|
};
|
|
45181
45147
|
|
|
45182
45148
|
// src/persona/seed.ts
|
|
45183
|
-
var
|
|
45184
|
-
var
|
|
45149
|
+
var fs9 = __toESM(require("fs"), 1);
|
|
45150
|
+
var path11 = __toESM(require("path"), 1);
|
|
45185
45151
|
var import_node_url = require("url");
|
|
45186
45152
|
var import_meta = {};
|
|
45187
45153
|
var DEFAULT_BYPASS_PROFILE = {
|
|
@@ -45212,6 +45178,16 @@ var DEFAULT_PERSONAS = [
|
|
|
45212
45178
|
public: false,
|
|
45213
45179
|
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45214
45180
|
},
|
|
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
|
+
},
|
|
45215
45191
|
{
|
|
45216
45192
|
personaId: "persona-feishu-assistant",
|
|
45217
45193
|
label: "\u98DE\u4E66\u52A9\u7406",
|
|
@@ -45305,6 +45281,14 @@ var DEFAULT_PERSONAS = [
|
|
|
45305
45281
|
public: false,
|
|
45306
45282
|
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45307
45283
|
},
|
|
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
|
+
},
|
|
45308
45292
|
{
|
|
45309
45293
|
// HTML PPT 制作师:把想法/文字/旧 PPT 转成单文件 HTML 演示稿
|
|
45310
45294
|
// bundle 含 frontend-slides skill(MIT,Zara Zhang),daemon ship 进 .claude/skills/
|
|
@@ -45351,24 +45335,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
|
|
|
45351
45335
|
if (!argv1) return null;
|
|
45352
45336
|
let real = argv1;
|
|
45353
45337
|
try {
|
|
45354
|
-
real =
|
|
45338
|
+
real = fs9.realpathSync(argv1);
|
|
45355
45339
|
} catch {
|
|
45356
45340
|
}
|
|
45357
|
-
return
|
|
45341
|
+
return path11.resolve(path11.dirname(real), sibling);
|
|
45358
45342
|
}
|
|
45359
45343
|
function findDefaultsRoot(logger) {
|
|
45360
45344
|
const candidates = [];
|
|
45361
45345
|
try {
|
|
45362
|
-
const here =
|
|
45363
|
-
candidates.push(
|
|
45364
|
-
candidates.push(
|
|
45346
|
+
const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45347
|
+
candidates.push(path11.resolve(here, "defaults"));
|
|
45348
|
+
candidates.push(path11.resolve(here, "persona-defaults"));
|
|
45365
45349
|
} catch {
|
|
45366
45350
|
}
|
|
45367
45351
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
|
|
45368
45352
|
if (fromArgv) candidates.push(fromArgv);
|
|
45369
45353
|
for (const c of candidates) {
|
|
45370
45354
|
try {
|
|
45371
|
-
if (
|
|
45355
|
+
if (fs9.statSync(c).isDirectory()) {
|
|
45372
45356
|
logger?.info("persona.defaults-root.resolved", { root: c });
|
|
45373
45357
|
return c;
|
|
45374
45358
|
}
|
|
@@ -45385,8 +45369,8 @@ function seedDefaultPersonas(args) {
|
|
|
45385
45369
|
args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
|
|
45386
45370
|
continue;
|
|
45387
45371
|
}
|
|
45388
|
-
const bundleDir =
|
|
45389
|
-
if (!
|
|
45372
|
+
const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
|
|
45373
|
+
if (!fs9.existsSync(bundleDir)) {
|
|
45390
45374
|
args.logger.warn("persona.seed.skip", {
|
|
45391
45375
|
personaId: entry.personaId,
|
|
45392
45376
|
reason: "bundle-missing",
|
|
@@ -45394,8 +45378,8 @@ function seedDefaultPersonas(args) {
|
|
|
45394
45378
|
});
|
|
45395
45379
|
continue;
|
|
45396
45380
|
}
|
|
45397
|
-
const claudeMdPath =
|
|
45398
|
-
if (!
|
|
45381
|
+
const claudeMdPath = path11.join(bundleDir, "CLAUDE.md");
|
|
45382
|
+
if (!fs9.existsSync(claudeMdPath)) {
|
|
45399
45383
|
args.logger.warn("persona.seed.skip", {
|
|
45400
45384
|
personaId: entry.personaId,
|
|
45401
45385
|
reason: "no-CLAUDE.md",
|
|
@@ -45403,7 +45387,7 @@ function seedDefaultPersonas(args) {
|
|
|
45403
45387
|
});
|
|
45404
45388
|
continue;
|
|
45405
45389
|
}
|
|
45406
|
-
const personality =
|
|
45390
|
+
const personality = fs9.readFileSync(claudeMdPath, "utf8");
|
|
45407
45391
|
const now = Date.now();
|
|
45408
45392
|
const persona = {
|
|
45409
45393
|
personaId: entry.personaId,
|
|
@@ -45429,17 +45413,17 @@ function seedDefaultPersonas(args) {
|
|
|
45429
45413
|
}
|
|
45430
45414
|
}
|
|
45431
45415
|
function skipNodeModulesUnder(srcRoot) {
|
|
45432
|
-
return (src) => !
|
|
45416
|
+
return (src) => !path11.relative(srcRoot, src).split(path11.sep).includes("node_modules");
|
|
45433
45417
|
}
|
|
45434
45418
|
function copyBundleExtras(srcDir, dstDir) {
|
|
45435
|
-
for (const entry of
|
|
45419
|
+
for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
|
|
45436
45420
|
if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
|
|
45437
|
-
const srcPath =
|
|
45438
|
-
const dstPath =
|
|
45421
|
+
const srcPath = path11.join(srcDir, entry.name);
|
|
45422
|
+
const dstPath = path11.join(dstDir, entry.name);
|
|
45439
45423
|
if (entry.isDirectory()) {
|
|
45440
|
-
|
|
45424
|
+
fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45441
45425
|
} else if (entry.isFile()) {
|
|
45442
|
-
|
|
45426
|
+
fs9.copyFileSync(srcPath, dstPath);
|
|
45443
45427
|
}
|
|
45444
45428
|
}
|
|
45445
45429
|
}
|
|
@@ -45447,16 +45431,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
|
|
|
45447
45431
|
function refreshDaemonManagedDirs(args) {
|
|
45448
45432
|
const entries = args.entries ?? DEFAULT_PERSONAS;
|
|
45449
45433
|
for (const entry of entries) {
|
|
45450
|
-
const bundleDir =
|
|
45451
|
-
if (!
|
|
45434
|
+
const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
|
|
45435
|
+
if (!fs9.existsSync(bundleDir)) continue;
|
|
45452
45436
|
const personaDir = args.store.personaDirPath(entry.personaId);
|
|
45453
|
-
if (!
|
|
45437
|
+
if (!fs9.existsSync(personaDir)) continue;
|
|
45454
45438
|
for (const relPath of DAEMON_MANAGED_PATHS) {
|
|
45455
|
-
const srcPath =
|
|
45456
|
-
if (!
|
|
45457
|
-
const dstPath =
|
|
45439
|
+
const srcPath = path11.join(bundleDir, relPath);
|
|
45440
|
+
if (!fs9.existsSync(srcPath)) continue;
|
|
45441
|
+
const dstPath = path11.join(personaDir, relPath);
|
|
45458
45442
|
try {
|
|
45459
|
-
|
|
45443
|
+
fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45460
45444
|
args.logger.info("persona.refresh.synced", {
|
|
45461
45445
|
personaId: entry.personaId,
|
|
45462
45446
|
path: relPath
|
|
@@ -45516,15 +45500,15 @@ function migrateCodexSandbox(args) {
|
|
|
45516
45500
|
function findDeployKitRoot(logger) {
|
|
45517
45501
|
const candidates = [];
|
|
45518
45502
|
try {
|
|
45519
|
-
const here =
|
|
45520
|
-
candidates.push(
|
|
45503
|
+
const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45504
|
+
candidates.push(path11.resolve(here, "..", "deploy-kit"));
|
|
45521
45505
|
} catch {
|
|
45522
45506
|
}
|
|
45523
45507
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
|
|
45524
45508
|
if (fromArgv) candidates.push(fromArgv);
|
|
45525
45509
|
for (const c of candidates) {
|
|
45526
45510
|
try {
|
|
45527
|
-
if (
|
|
45511
|
+
if (fs9.statSync(c).isDirectory()) {
|
|
45528
45512
|
logger?.info("persona.deploy-kit-root.resolved", { root: c });
|
|
45529
45513
|
return c;
|
|
45530
45514
|
}
|
|
@@ -45535,8 +45519,8 @@ function findDeployKitRoot(logger) {
|
|
|
45535
45519
|
return null;
|
|
45536
45520
|
}
|
|
45537
45521
|
function seedDeployKit(args) {
|
|
45538
|
-
const dst =
|
|
45539
|
-
|
|
45522
|
+
const dst = path11.join(args.dataDir, "deploy-kit");
|
|
45523
|
+
fs9.cpSync(args.deployKitBundleRoot, dst, {
|
|
45540
45524
|
recursive: true,
|
|
45541
45525
|
dereference: true,
|
|
45542
45526
|
force: false,
|
|
@@ -45545,35 +45529,35 @@ function seedDeployKit(args) {
|
|
|
45545
45529
|
args.logger.info("deploy-kit.seed.done", { dst });
|
|
45546
45530
|
}
|
|
45547
45531
|
function refreshDeployKit(args) {
|
|
45548
|
-
const dst =
|
|
45549
|
-
if (!
|
|
45532
|
+
const dst = path11.join(args.dataDir, "deploy-kit");
|
|
45533
|
+
if (!fs9.existsSync(dst)) {
|
|
45550
45534
|
seedDeployKit(args);
|
|
45551
45535
|
return;
|
|
45552
45536
|
}
|
|
45553
45537
|
for (const sub of ["scripts", "contract"]) {
|
|
45554
|
-
const s =
|
|
45555
|
-
if (
|
|
45556
|
-
|
|
45538
|
+
const s = path11.join(args.deployKitBundleRoot, sub);
|
|
45539
|
+
if (fs9.existsSync(s)) {
|
|
45540
|
+
fs9.cpSync(s, path11.join(dst, sub), { recursive: true, force: true, dereference: true });
|
|
45557
45541
|
}
|
|
45558
45542
|
}
|
|
45559
|
-
const secretsSrc =
|
|
45560
|
-
if (
|
|
45561
|
-
|
|
45562
|
-
for (const f of
|
|
45543
|
+
const secretsSrc = path11.join(args.deployKitBundleRoot, ".secrets");
|
|
45544
|
+
if (fs9.existsSync(secretsSrc)) {
|
|
45545
|
+
fs9.mkdirSync(path11.join(dst, ".secrets"), { recursive: true });
|
|
45546
|
+
for (const f of fs9.readdirSync(secretsSrc)) {
|
|
45563
45547
|
if (!f.endsWith(".example")) continue;
|
|
45564
|
-
|
|
45548
|
+
fs9.copyFileSync(path11.join(secretsSrc, f), path11.join(dst, ".secrets", f));
|
|
45565
45549
|
}
|
|
45566
45550
|
}
|
|
45567
45551
|
args.logger.info("deploy-kit.refresh.done", { dst });
|
|
45568
45552
|
}
|
|
45569
45553
|
|
|
45570
45554
|
// src/share-md-viewer/load.ts
|
|
45571
|
-
var
|
|
45572
|
-
var
|
|
45555
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
45556
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
45573
45557
|
var import_node_url2 = require("url");
|
|
45574
45558
|
|
|
45575
45559
|
// src/share-md-viewer/asset-loader.ts
|
|
45576
|
-
var
|
|
45560
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
45577
45561
|
function htmlEscape(s) {
|
|
45578
45562
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
45579
45563
|
}
|
|
@@ -45581,12 +45565,12 @@ function createViewerAssetLoader(opts) {
|
|
|
45581
45565
|
let viewerTemplate;
|
|
45582
45566
|
let errorTemplate;
|
|
45583
45567
|
try {
|
|
45584
|
-
viewerTemplate =
|
|
45568
|
+
viewerTemplate = import_node_fs8.default.readFileSync(opts.viewerHtmlPath, "utf8");
|
|
45585
45569
|
} catch (err) {
|
|
45586
45570
|
throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
|
|
45587
45571
|
}
|
|
45588
45572
|
try {
|
|
45589
|
-
errorTemplate =
|
|
45573
|
+
errorTemplate = import_node_fs8.default.readFileSync(opts.errorHtmlPath, "utf8");
|
|
45590
45574
|
} catch (err) {
|
|
45591
45575
|
throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
|
|
45592
45576
|
}
|
|
@@ -45605,25 +45589,25 @@ var import_meta2 = {};
|
|
|
45605
45589
|
function tryLoadViewerAssets(logger) {
|
|
45606
45590
|
const candidates = [];
|
|
45607
45591
|
try {
|
|
45608
|
-
const here =
|
|
45592
|
+
const here = import_node_path8.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
45609
45593
|
candidates.push(here);
|
|
45610
|
-
candidates.push(
|
|
45611
|
-
candidates.push(
|
|
45594
|
+
candidates.push(import_node_path8.default.resolve(here, ".."));
|
|
45595
|
+
candidates.push(import_node_path8.default.resolve(here, "..", "..", "dist"));
|
|
45612
45596
|
} catch {
|
|
45613
45597
|
}
|
|
45614
45598
|
if (process.argv[1]) {
|
|
45615
45599
|
let real = process.argv[1];
|
|
45616
45600
|
try {
|
|
45617
|
-
real =
|
|
45601
|
+
real = import_node_fs9.default.realpathSync(process.argv[1]);
|
|
45618
45602
|
} catch {
|
|
45619
45603
|
}
|
|
45620
|
-
candidates.push(
|
|
45604
|
+
candidates.push(import_node_path8.default.dirname(real));
|
|
45621
45605
|
}
|
|
45622
45606
|
for (const root of candidates) {
|
|
45623
|
-
const viewerHtmlPath =
|
|
45624
|
-
const errorHtmlPath =
|
|
45607
|
+
const viewerHtmlPath = import_node_path8.default.join(root, "share-md-viewer.html");
|
|
45608
|
+
const errorHtmlPath = import_node_path8.default.join(root, "share-md-viewer-error.html");
|
|
45625
45609
|
try {
|
|
45626
|
-
if (
|
|
45610
|
+
if (import_node_fs9.default.statSync(viewerHtmlPath).isFile() && import_node_fs9.default.statSync(errorHtmlPath).isFile()) {
|
|
45627
45611
|
logger?.info("share-md-viewer.assets-root.resolved", { root });
|
|
45628
45612
|
return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
|
|
45629
45613
|
}
|
|
@@ -45638,30 +45622,30 @@ function tryLoadViewerAssets(logger) {
|
|
|
45638
45622
|
}
|
|
45639
45623
|
|
|
45640
45624
|
// src/share-ui/load.ts
|
|
45641
|
-
var
|
|
45642
|
-
var
|
|
45625
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
45626
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
45643
45627
|
var import_node_url3 = require("url");
|
|
45644
45628
|
|
|
45645
45629
|
// src/share-ui/asset-loader.ts
|
|
45646
|
-
var
|
|
45647
|
-
var
|
|
45630
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
45631
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
45648
45632
|
function createShareUiAssetLoader(opts) {
|
|
45649
45633
|
let indexHtml;
|
|
45650
45634
|
try {
|
|
45651
|
-
indexHtml =
|
|
45635
|
+
indexHtml = import_node_fs10.default.readFileSync(opts.indexHtmlPath, "utf8");
|
|
45652
45636
|
} catch (err) {
|
|
45653
45637
|
throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
|
|
45654
45638
|
}
|
|
45655
|
-
const assetsDir =
|
|
45639
|
+
const assetsDir = import_node_path9.default.resolve(opts.assetsDir);
|
|
45656
45640
|
return {
|
|
45657
45641
|
renderIndexHtml() {
|
|
45658
45642
|
return indexHtml;
|
|
45659
45643
|
},
|
|
45660
45644
|
resolveAssetPath(rel) {
|
|
45661
|
-
const resolved =
|
|
45662
|
-
if (resolved !== assetsDir && !resolved.startsWith(assetsDir +
|
|
45645
|
+
const resolved = import_node_path9.default.resolve(assetsDir, rel);
|
|
45646
|
+
if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path9.default.sep)) return null;
|
|
45663
45647
|
try {
|
|
45664
|
-
if (
|
|
45648
|
+
if (import_node_fs10.default.statSync(resolved).isFile()) return resolved;
|
|
45665
45649
|
} catch {
|
|
45666
45650
|
}
|
|
45667
45651
|
return null;
|
|
@@ -45675,28 +45659,28 @@ function bundleDirFromArgv(argv1) {
|
|
|
45675
45659
|
if (!argv1) return null;
|
|
45676
45660
|
let real = argv1;
|
|
45677
45661
|
try {
|
|
45678
|
-
real =
|
|
45662
|
+
real = import_node_fs11.default.realpathSync(argv1);
|
|
45679
45663
|
} catch {
|
|
45680
45664
|
}
|
|
45681
|
-
return
|
|
45665
|
+
return import_node_path10.default.dirname(real);
|
|
45682
45666
|
}
|
|
45683
45667
|
function tryLoadShareUi(logger) {
|
|
45684
45668
|
const candidates = [];
|
|
45685
45669
|
try {
|
|
45686
|
-
const here =
|
|
45670
|
+
const here = import_node_path10.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
45687
45671
|
candidates.push(here);
|
|
45688
|
-
candidates.push(
|
|
45689
|
-
candidates.push(
|
|
45672
|
+
candidates.push(import_node_path10.default.resolve(here, ".."));
|
|
45673
|
+
candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
|
|
45690
45674
|
} catch {
|
|
45691
45675
|
}
|
|
45692
45676
|
const argvDir = bundleDirFromArgv(process.argv[1]);
|
|
45693
45677
|
if (argvDir) candidates.push(argvDir);
|
|
45694
45678
|
for (const root of candidates) {
|
|
45695
|
-
const shareUiDir =
|
|
45696
|
-
const indexHtmlPath =
|
|
45697
|
-
const assetsDir =
|
|
45679
|
+
const shareUiDir = import_node_path10.default.join(root, "share-ui");
|
|
45680
|
+
const indexHtmlPath = import_node_path10.default.join(shareUiDir, "guest.html");
|
|
45681
|
+
const assetsDir = import_node_path10.default.join(shareUiDir, "assets");
|
|
45698
45682
|
try {
|
|
45699
|
-
if (
|
|
45683
|
+
if (import_node_fs11.default.statSync(indexHtmlPath).isFile() && import_node_fs11.default.statSync(assetsDir).isDirectory()) {
|
|
45700
45684
|
logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
|
|
45701
45685
|
return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
|
|
45702
45686
|
}
|
|
@@ -45778,20 +45762,20 @@ function buildVisitorLogin(deps) {
|
|
|
45778
45762
|
}
|
|
45779
45763
|
|
|
45780
45764
|
// src/visitor/visitor-store.ts
|
|
45781
|
-
var
|
|
45782
|
-
var
|
|
45765
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
45766
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
45783
45767
|
function createVisitorStore(opts) {
|
|
45784
|
-
const file =
|
|
45768
|
+
const file = import_node_path11.default.join(opts.dir, "visitors.json");
|
|
45785
45769
|
const read = () => {
|
|
45786
45770
|
try {
|
|
45787
|
-
return JSON.parse(
|
|
45771
|
+
return JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
|
|
45788
45772
|
} catch {
|
|
45789
45773
|
return [];
|
|
45790
45774
|
}
|
|
45791
45775
|
};
|
|
45792
45776
|
const write = (rows) => {
|
|
45793
|
-
|
|
45794
|
-
|
|
45777
|
+
import_node_fs12.default.mkdirSync(opts.dir, { recursive: true });
|
|
45778
|
+
import_node_fs12.default.writeFileSync(file, JSON.stringify(rows, null, 2));
|
|
45795
45779
|
};
|
|
45796
45780
|
return {
|
|
45797
45781
|
upsert(r) {
|
|
@@ -46307,8 +46291,8 @@ var CodexAdapter = class {
|
|
|
46307
46291
|
|
|
46308
46292
|
// src/tools/claude-tui.ts
|
|
46309
46293
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
46310
|
-
var
|
|
46311
|
-
var
|
|
46294
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
46295
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
46312
46296
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
46313
46297
|
|
|
46314
46298
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -47435,14 +47419,17 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
47435
47419
|
if (ctx.shiftMcpConfigPath) {
|
|
47436
47420
|
args.push("--mcp-config", ctx.shiftMcpConfigPath);
|
|
47437
47421
|
}
|
|
47422
|
+
if (ctx.inboxMcpConfigPath) {
|
|
47423
|
+
args.push("--mcp-config", ctx.inboxMcpConfigPath);
|
|
47424
|
+
}
|
|
47438
47425
|
args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
|
|
47439
47426
|
if (ctx.effort) args.push("--effort", ctx.effort);
|
|
47440
47427
|
return args;
|
|
47441
47428
|
}
|
|
47442
47429
|
function jsonlExistsForCtx(ctx) {
|
|
47443
47430
|
if (!ctx.toolSessionId) return false;
|
|
47444
|
-
const home =
|
|
47445
|
-
const file =
|
|
47431
|
+
const home = import_node_os6.default.homedir();
|
|
47432
|
+
const file = import_node_path13.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
47446
47433
|
try {
|
|
47447
47434
|
return import_node_fs16.default.statSync(file).isFile();
|
|
47448
47435
|
} catch {
|
|
@@ -47514,9 +47501,9 @@ var PersonaDispatchManager = class {
|
|
|
47514
47501
|
|
|
47515
47502
|
// src/dispatch/mcp-config.ts
|
|
47516
47503
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
47517
|
-
var
|
|
47504
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
47518
47505
|
function dispatchMcpConfigPath(dataDir) {
|
|
47519
|
-
return
|
|
47506
|
+
return import_node_path14.default.join(dataDir, "dispatch.mcp.json");
|
|
47520
47507
|
}
|
|
47521
47508
|
function writeDispatchMcpConfig(args) {
|
|
47522
47509
|
const cfgPath = dispatchMcpConfigPath(args.dataDir);
|
|
@@ -47538,9 +47525,9 @@ function writeDispatchMcpConfig(args) {
|
|
|
47538
47525
|
|
|
47539
47526
|
// src/ticket/mcp-config.ts
|
|
47540
47527
|
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
47541
|
-
var
|
|
47528
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
47542
47529
|
function ticketMcpConfigPath(dataDir) {
|
|
47543
|
-
return
|
|
47530
|
+
return import_node_path15.default.join(dataDir, "ticket.mcp.json");
|
|
47544
47531
|
}
|
|
47545
47532
|
function writeTicketMcpConfig(args) {
|
|
47546
47533
|
const cfgPath = ticketMcpConfigPath(args.dataDir);
|
|
@@ -47568,9 +47555,9 @@ function writeTicketMcpConfig(args) {
|
|
|
47568
47555
|
|
|
47569
47556
|
// src/shift/mcp-config.ts
|
|
47570
47557
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
47571
|
-
var
|
|
47558
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
47572
47559
|
function shiftMcpConfigPath(dataDir) {
|
|
47573
|
-
return
|
|
47560
|
+
return import_node_path16.default.join(dataDir, "shift.mcp.json");
|
|
47574
47561
|
}
|
|
47575
47562
|
async function writeShiftMcpConfig(args) {
|
|
47576
47563
|
const cfgPath = shiftMcpConfigPath(args.dataDir);
|
|
@@ -47590,6 +47577,29 @@ async function writeShiftMcpConfig(args) {
|
|
|
47590
47577
|
return cfgPath;
|
|
47591
47578
|
}
|
|
47592
47579
|
|
|
47580
|
+
// src/inbox/mcp-config.ts
|
|
47581
|
+
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
47582
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
47583
|
+
function inboxMcpConfigPath(dataDir) {
|
|
47584
|
+
return import_node_path17.default.join(dataDir, "inbox.mcp.json");
|
|
47585
|
+
}
|
|
47586
|
+
async function writeInboxMcpConfig(args) {
|
|
47587
|
+
const cfgPath = inboxMcpConfigPath(args.dataDir);
|
|
47588
|
+
const content = {
|
|
47589
|
+
_comment: "daemon \u542F\u52A8\u65F6\u81EA\u52A8\u751F\u6210\uFF1Bcc spawn \u901A\u8FC7 --mcp-config \u6CE8\u5165\u3002inbox/mcp-server.cjs \u662F daemon \u81EA\u5E26\u7684 stdio MCP server\uFF0C\u66B4\u9732 sendDm tool\uFF08persona \u53D7\u63A7\u53D1 P2P IM DM\uFF09\u3002",
|
|
47590
|
+
mcpServers: {
|
|
47591
|
+
"clawd-inbox": {
|
|
47592
|
+
type: "stdio",
|
|
47593
|
+
command: "node",
|
|
47594
|
+
args: [args.serverScriptPath]
|
|
47595
|
+
}
|
|
47596
|
+
}
|
|
47597
|
+
};
|
|
47598
|
+
await import_node_fs20.default.promises.mkdir(args.dataDir, { recursive: true });
|
|
47599
|
+
await import_node_fs20.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
47600
|
+
return cfgPath;
|
|
47601
|
+
}
|
|
47602
|
+
|
|
47593
47603
|
// src/shift/store.ts
|
|
47594
47604
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
47595
47605
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
@@ -48245,6 +48255,39 @@ async function forwardDispatchToPeer(args) {
|
|
|
48245
48255
|
}
|
|
48246
48256
|
return json.result.outcome;
|
|
48247
48257
|
}
|
|
48258
|
+
async function forwardInboxPostToPeer(args) {
|
|
48259
|
+
const f = args.fetchImpl ?? fetch;
|
|
48260
|
+
const base = wsUrlToHttp(args.contact.remoteUrl).replace(/\/+$/, "");
|
|
48261
|
+
const url = `${base}/rpc/inbox:postMessage`;
|
|
48262
|
+
let res;
|
|
48263
|
+
try {
|
|
48264
|
+
res = await f(url, {
|
|
48265
|
+
method: "POST",
|
|
48266
|
+
headers: {
|
|
48267
|
+
"content-type": "application/json",
|
|
48268
|
+
authorization: `Bearer ${args.contact.connectToken}`
|
|
48269
|
+
},
|
|
48270
|
+
body: JSON.stringify({
|
|
48271
|
+
id: args.id,
|
|
48272
|
+
text: args.text,
|
|
48273
|
+
createdAt: args.createdAt,
|
|
48274
|
+
...args.origin ? { origin: args.origin } : {}
|
|
48275
|
+
})
|
|
48276
|
+
});
|
|
48277
|
+
} catch (err) {
|
|
48278
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
48279
|
+
}
|
|
48280
|
+
let json = null;
|
|
48281
|
+
try {
|
|
48282
|
+
json = await res.json();
|
|
48283
|
+
} catch {
|
|
48284
|
+
return { ok: false, error: `peer non-JSON (HTTP ${res.status})` };
|
|
48285
|
+
}
|
|
48286
|
+
if (res.status < 200 || res.status >= 300 || json?.ok === false) {
|
|
48287
|
+
return { ok: false, error: json?.error ?? `HTTP ${res.status}` };
|
|
48288
|
+
}
|
|
48289
|
+
return { ok: true };
|
|
48290
|
+
}
|
|
48248
48291
|
|
|
48249
48292
|
// src/tools/codex-history.ts
|
|
48250
48293
|
var import_node_child_process5 = require("child_process");
|
|
@@ -48477,8 +48520,8 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
48477
48520
|
}
|
|
48478
48521
|
|
|
48479
48522
|
// src/workspace/browser.ts
|
|
48480
|
-
var
|
|
48481
|
-
var
|
|
48523
|
+
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
48524
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
48482
48525
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
48483
48526
|
init_protocol();
|
|
48484
48527
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
@@ -48493,7 +48536,7 @@ function resolveInsideCwd(cwd, subpath) {
|
|
|
48493
48536
|
}
|
|
48494
48537
|
function ensureCwd(cwd) {
|
|
48495
48538
|
try {
|
|
48496
|
-
const stat =
|
|
48539
|
+
const stat = import_node_fs21.default.statSync(cwd);
|
|
48497
48540
|
if (!stat.isDirectory()) {
|
|
48498
48541
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
48499
48542
|
}
|
|
@@ -48504,10 +48547,10 @@ function ensureCwd(cwd) {
|
|
|
48504
48547
|
}
|
|
48505
48548
|
var WorkspaceBrowser = class {
|
|
48506
48549
|
list(args) {
|
|
48507
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
48550
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
|
|
48508
48551
|
ensureCwd(cwd);
|
|
48509
48552
|
const full = resolveInsideCwd(cwd, args.path);
|
|
48510
|
-
const dirents =
|
|
48553
|
+
const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
|
|
48511
48554
|
const entries = [];
|
|
48512
48555
|
for (const d of dirents) {
|
|
48513
48556
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -48517,7 +48560,7 @@ var WorkspaceBrowser = class {
|
|
|
48517
48560
|
mtime: ""
|
|
48518
48561
|
};
|
|
48519
48562
|
try {
|
|
48520
|
-
const st =
|
|
48563
|
+
const st = import_node_fs21.default.statSync(import_node_path19.default.join(full, d.name));
|
|
48521
48564
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
48522
48565
|
if (d.isFile()) entry.size = st.size;
|
|
48523
48566
|
} catch {
|
|
@@ -48533,14 +48576,14 @@ var WorkspaceBrowser = class {
|
|
|
48533
48576
|
read(args) {
|
|
48534
48577
|
ensureCwd(args.cwd);
|
|
48535
48578
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
48536
|
-
const st =
|
|
48579
|
+
const st = import_node_fs21.default.statSync(full);
|
|
48537
48580
|
if (!st.isFile()) {
|
|
48538
48581
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
48539
48582
|
}
|
|
48540
48583
|
if (st.size > MAX_FILE_BYTES) {
|
|
48541
48584
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
48542
48585
|
}
|
|
48543
|
-
const buf =
|
|
48586
|
+
const buf = import_node_fs21.default.readFileSync(full);
|
|
48544
48587
|
const isBinary = buf.includes(0);
|
|
48545
48588
|
if (isBinary) {
|
|
48546
48589
|
return {
|
|
@@ -48562,20 +48605,20 @@ var WorkspaceBrowser = class {
|
|
|
48562
48605
|
};
|
|
48563
48606
|
|
|
48564
48607
|
// src/skills/agents-scanner.ts
|
|
48565
|
-
var
|
|
48566
|
-
var
|
|
48608
|
+
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
48609
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
48567
48610
|
var import_node_path20 = __toESM(require("path"), 1);
|
|
48568
48611
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
48569
48612
|
function isDirLikeSync2(p2) {
|
|
48570
48613
|
try {
|
|
48571
|
-
return
|
|
48614
|
+
return import_node_fs22.default.statSync(p2).isDirectory();
|
|
48572
48615
|
} catch {
|
|
48573
48616
|
return false;
|
|
48574
48617
|
}
|
|
48575
48618
|
}
|
|
48576
48619
|
function fileExistsSync(p2) {
|
|
48577
48620
|
try {
|
|
48578
|
-
return
|
|
48621
|
+
return import_node_fs22.default.statSync(p2).isFile();
|
|
48579
48622
|
} catch {
|
|
48580
48623
|
return false;
|
|
48581
48624
|
}
|
|
@@ -48583,7 +48626,7 @@ function fileExistsSync(p2) {
|
|
|
48583
48626
|
function parseAgentFile(filePath) {
|
|
48584
48627
|
let content;
|
|
48585
48628
|
try {
|
|
48586
|
-
content =
|
|
48629
|
+
content = import_node_fs22.default.readFileSync(filePath, "utf8");
|
|
48587
48630
|
} catch {
|
|
48588
48631
|
return {};
|
|
48589
48632
|
}
|
|
@@ -48596,7 +48639,7 @@ function parseAgentFile(filePath) {
|
|
|
48596
48639
|
function scanAgentsDir(dir, source, seen, out) {
|
|
48597
48640
|
let entries;
|
|
48598
48641
|
try {
|
|
48599
|
-
entries =
|
|
48642
|
+
entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
48600
48643
|
} catch {
|
|
48601
48644
|
return;
|
|
48602
48645
|
}
|
|
@@ -48623,7 +48666,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48623
48666
|
function walk2(dir, namespaces) {
|
|
48624
48667
|
let entries;
|
|
48625
48668
|
try {
|
|
48626
|
-
entries =
|
|
48669
|
+
entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
48627
48670
|
} catch {
|
|
48628
48671
|
return;
|
|
48629
48672
|
}
|
|
@@ -48659,7 +48702,7 @@ function readInstalledPlugins2(home) {
|
|
|
48659
48702
|
let raw = null;
|
|
48660
48703
|
for (const candidate of [v2, v1]) {
|
|
48661
48704
|
try {
|
|
48662
|
-
raw =
|
|
48705
|
+
raw = import_node_fs22.default.readFileSync(candidate, "utf8");
|
|
48663
48706
|
break;
|
|
48664
48707
|
} catch {
|
|
48665
48708
|
}
|
|
@@ -48690,7 +48733,7 @@ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
|
48690
48733
|
scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
48691
48734
|
let hasGit = false;
|
|
48692
48735
|
try {
|
|
48693
|
-
hasGit =
|
|
48736
|
+
hasGit = import_node_fs22.default.existsSync(import_node_path20.default.join(cur, ".git"));
|
|
48694
48737
|
} catch {
|
|
48695
48738
|
}
|
|
48696
48739
|
if (hasGit) return;
|
|
@@ -48706,7 +48749,7 @@ var AgentsScanner = class {
|
|
|
48706
48749
|
extraPluginRoots;
|
|
48707
48750
|
policyDir;
|
|
48708
48751
|
constructor(opts = {}) {
|
|
48709
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
48752
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
|
|
48710
48753
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
48711
48754
|
if (opts.policyDir !== void 0) {
|
|
48712
48755
|
this.policyDir = opts.policyDir;
|
|
@@ -48753,21 +48796,21 @@ var AgentsScanner = class {
|
|
|
48753
48796
|
};
|
|
48754
48797
|
|
|
48755
48798
|
// src/observer/session-observer.ts
|
|
48756
|
-
var
|
|
48757
|
-
var
|
|
48799
|
+
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
48800
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
48758
48801
|
var import_node_path22 = __toESM(require("path"), 1);
|
|
48759
48802
|
init_claude_history();
|
|
48760
48803
|
|
|
48761
48804
|
// src/observer/subagent-meta-observer.ts
|
|
48762
|
-
var
|
|
48763
|
-
var
|
|
48805
|
+
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
48806
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
48764
48807
|
var import_node_path21 = __toESM(require("path"), 1);
|
|
48765
48808
|
init_claude_history();
|
|
48766
48809
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
48767
48810
|
var SubagentMetaObserver = class {
|
|
48768
48811
|
constructor(opts) {
|
|
48769
48812
|
this.opts = opts;
|
|
48770
|
-
this.home = opts.home ??
|
|
48813
|
+
this.home = opts.home ?? import_node_os9.default.homedir();
|
|
48771
48814
|
}
|
|
48772
48815
|
opts;
|
|
48773
48816
|
home;
|
|
@@ -48804,7 +48847,7 @@ var SubagentMetaObserver = class {
|
|
|
48804
48847
|
attachWatcher(w2) {
|
|
48805
48848
|
if (w2.watcher) return;
|
|
48806
48849
|
try {
|
|
48807
|
-
w2.watcher =
|
|
48850
|
+
w2.watcher = import_node_fs23.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
|
|
48808
48851
|
if (!name) return;
|
|
48809
48852
|
const m2 = META_RE.exec(String(name));
|
|
48810
48853
|
if (!m2) return;
|
|
@@ -48816,7 +48859,7 @@ var SubagentMetaObserver = class {
|
|
|
48816
48859
|
scan(w2) {
|
|
48817
48860
|
let entries;
|
|
48818
48861
|
try {
|
|
48819
|
-
entries =
|
|
48862
|
+
entries = import_node_fs23.default.readdirSync(w2.dirPath);
|
|
48820
48863
|
} catch {
|
|
48821
48864
|
return;
|
|
48822
48865
|
}
|
|
@@ -48833,7 +48876,7 @@ var SubagentMetaObserver = class {
|
|
|
48833
48876
|
const file = import_node_path21.default.join(w2.dirPath, name);
|
|
48834
48877
|
let raw;
|
|
48835
48878
|
try {
|
|
48836
|
-
raw =
|
|
48879
|
+
raw = import_node_fs23.default.readFileSync(file, "utf8");
|
|
48837
48880
|
} catch {
|
|
48838
48881
|
return;
|
|
48839
48882
|
}
|
|
@@ -48878,7 +48921,7 @@ var SubagentMetaObserver = class {
|
|
|
48878
48921
|
var SessionObserver = class {
|
|
48879
48922
|
constructor(opts) {
|
|
48880
48923
|
this.opts = opts;
|
|
48881
|
-
this.home = opts.home ??
|
|
48924
|
+
this.home = opts.home ?? import_node_os10.default.homedir();
|
|
48882
48925
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
48883
48926
|
}
|
|
48884
48927
|
opts;
|
|
@@ -48897,7 +48940,7 @@ var SessionObserver = class {
|
|
|
48897
48940
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
48898
48941
|
let size = 0;
|
|
48899
48942
|
try {
|
|
48900
|
-
size =
|
|
48943
|
+
size = import_node_fs24.default.statSync(filePath).size;
|
|
48901
48944
|
} catch {
|
|
48902
48945
|
}
|
|
48903
48946
|
const w2 = {
|
|
@@ -48911,10 +48954,10 @@ var SessionObserver = class {
|
|
|
48911
48954
|
prevIsRejectSentinel: false
|
|
48912
48955
|
};
|
|
48913
48956
|
try {
|
|
48914
|
-
|
|
48957
|
+
import_node_fs24.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
|
|
48915
48958
|
} catch {
|
|
48916
48959
|
}
|
|
48917
|
-
w2.watcher =
|
|
48960
|
+
w2.watcher = import_node_fs24.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
48918
48961
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
48919
48962
|
this.poll(w2);
|
|
48920
48963
|
});
|
|
@@ -48937,7 +48980,7 @@ var SessionObserver = class {
|
|
|
48937
48980
|
// 异常静默吞,不阻塞 watcher 启动
|
|
48938
48981
|
hydrateMetaTail(w2, maxLines = 200) {
|
|
48939
48982
|
try {
|
|
48940
|
-
const raw =
|
|
48983
|
+
const raw = import_node_fs24.default.readFileSync(w2.filePath, "utf8");
|
|
48941
48984
|
if (!raw) return;
|
|
48942
48985
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
48943
48986
|
if (allLines.length === 0) return;
|
|
@@ -48961,7 +49004,7 @@ var SessionObserver = class {
|
|
|
48961
49004
|
poll(w2) {
|
|
48962
49005
|
let size = 0;
|
|
48963
49006
|
try {
|
|
48964
|
-
size =
|
|
49007
|
+
size = import_node_fs24.default.statSync(w2.filePath).size;
|
|
48965
49008
|
} catch {
|
|
48966
49009
|
return;
|
|
48967
49010
|
}
|
|
@@ -48970,11 +49013,11 @@ var SessionObserver = class {
|
|
|
48970
49013
|
w2.buf = "";
|
|
48971
49014
|
}
|
|
48972
49015
|
if (size === w2.lastSize) return;
|
|
48973
|
-
const fd =
|
|
49016
|
+
const fd = import_node_fs24.default.openSync(w2.filePath, "r");
|
|
48974
49017
|
try {
|
|
48975
49018
|
const len = size - w2.lastSize;
|
|
48976
49019
|
const buf = Buffer.alloc(len);
|
|
48977
|
-
|
|
49020
|
+
import_node_fs24.default.readSync(fd, buf, 0, len, w2.lastSize);
|
|
48978
49021
|
w2.lastSize = size;
|
|
48979
49022
|
w2.buf += buf.toString("utf8");
|
|
48980
49023
|
let newlineIndex;
|
|
@@ -48997,7 +49040,7 @@ var SessionObserver = class {
|
|
|
48997
49040
|
}
|
|
48998
49041
|
}
|
|
48999
49042
|
} finally {
|
|
49000
|
-
|
|
49043
|
+
import_node_fs24.default.closeSync(fd);
|
|
49001
49044
|
}
|
|
49002
49045
|
}
|
|
49003
49046
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -49557,7 +49600,9 @@ var EXPOSED_RPC_METHODS = [
|
|
|
49557
49600
|
// file-sharing:persona guest agent 把自己工作目录内的产物入群+签名分享。
|
|
49558
49601
|
// 路径越界由 handlers/attachment.ts guardAttachmentPath(scope-based)拦截。
|
|
49559
49602
|
"attachment.groupAdd",
|
|
49560
|
-
"attachment.signUrl"
|
|
49603
|
+
"attachment.signUrl",
|
|
49604
|
+
// persona 受控发 P2P IM DM(sender 由 session scope 推,driver 分级授权见 handlers/inbox.ts)
|
|
49605
|
+
"inbox.sendDm"
|
|
49561
49606
|
];
|
|
49562
49607
|
async function handleRpcRequest(input) {
|
|
49563
49608
|
const { method, body, sessionId, dispatcher } = input;
|
|
@@ -49793,14 +49838,14 @@ async function authenticate(token, deps) {
|
|
|
49793
49838
|
}
|
|
49794
49839
|
|
|
49795
49840
|
// src/permission/capability-store.ts
|
|
49796
|
-
var
|
|
49841
|
+
var fs28 = __toESM(require("fs"), 1);
|
|
49797
49842
|
var path27 = __toESM(require("path"), 1);
|
|
49798
49843
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
49799
49844
|
var FILE_VERSION = 1;
|
|
49800
49845
|
var CapabilityStore = class {
|
|
49801
49846
|
constructor(dataDir) {
|
|
49802
49847
|
this.dataDir = dataDir;
|
|
49803
|
-
|
|
49848
|
+
fs28.mkdirSync(dataDir, { recursive: true });
|
|
49804
49849
|
this.cache = this.readFromDisk();
|
|
49805
49850
|
}
|
|
49806
49851
|
dataDir;
|
|
@@ -49830,7 +49875,7 @@ var CapabilityStore = class {
|
|
|
49830
49875
|
const file = this.filePath();
|
|
49831
49876
|
let raw;
|
|
49832
49877
|
try {
|
|
49833
|
-
raw =
|
|
49878
|
+
raw = fs28.readFileSync(file, "utf8");
|
|
49834
49879
|
} catch (err) {
|
|
49835
49880
|
if (err?.code === "ENOENT") return [];
|
|
49836
49881
|
return [];
|
|
@@ -49858,10 +49903,10 @@ var CapabilityStore = class {
|
|
|
49858
49903
|
}
|
|
49859
49904
|
atomicWrite(file, content) {
|
|
49860
49905
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
49861
|
-
|
|
49862
|
-
|
|
49906
|
+
fs28.writeFileSync(tmp, content, { mode: 384 });
|
|
49907
|
+
fs28.renameSync(tmp, file);
|
|
49863
49908
|
try {
|
|
49864
|
-
|
|
49909
|
+
fs28.chmodSync(file, 384);
|
|
49865
49910
|
} catch {
|
|
49866
49911
|
}
|
|
49867
49912
|
}
|
|
@@ -49954,14 +49999,14 @@ var CapabilityManager = class {
|
|
|
49954
49999
|
};
|
|
49955
50000
|
|
|
49956
50001
|
// src/permission/cleanup.ts
|
|
49957
|
-
var
|
|
50002
|
+
var fs29 = __toESM(require("fs"), 1);
|
|
49958
50003
|
function cleanupGuestSessionsForCapability(cap, factory) {
|
|
49959
50004
|
const removed = [];
|
|
49960
50005
|
for (const g2 of cap.grants) {
|
|
49961
50006
|
if (g2.resource.type !== "persona") continue;
|
|
49962
50007
|
const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
|
|
49963
50008
|
try {
|
|
49964
|
-
|
|
50009
|
+
fs29.rmSync(dir, { recursive: true, force: true });
|
|
49965
50010
|
removed.push(dir);
|
|
49966
50011
|
} catch {
|
|
49967
50012
|
}
|
|
@@ -49970,13 +50015,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
49970
50015
|
}
|
|
49971
50016
|
|
|
49972
50017
|
// src/inbox/inbox-store.ts
|
|
49973
|
-
var
|
|
50018
|
+
var fs30 = __toESM(require("fs"), 1);
|
|
49974
50019
|
var path28 = __toESM(require("path"), 1);
|
|
49975
50020
|
var INBOX_SUBDIR = "inbox";
|
|
49976
50021
|
var InboxStore = class {
|
|
49977
50022
|
constructor(dataDir) {
|
|
49978
50023
|
this.dataDir = dataDir;
|
|
49979
|
-
|
|
50024
|
+
fs30.mkdirSync(this.dirPath(), { recursive: true });
|
|
49980
50025
|
}
|
|
49981
50026
|
dataDir;
|
|
49982
50027
|
/**
|
|
@@ -49988,7 +50033,7 @@ var InboxStore = class {
|
|
|
49988
50033
|
const file = this.filePath(peerDeviceId);
|
|
49989
50034
|
let raw;
|
|
49990
50035
|
try {
|
|
49991
|
-
raw =
|
|
50036
|
+
raw = fs30.readFileSync(file, "utf8");
|
|
49992
50037
|
} catch (err) {
|
|
49993
50038
|
if (err?.code === "ENOENT") return [];
|
|
49994
50039
|
return [];
|
|
@@ -50004,7 +50049,7 @@ var InboxStore = class {
|
|
|
50004
50049
|
const dir = this.dirPath();
|
|
50005
50050
|
let entries;
|
|
50006
50051
|
try {
|
|
50007
|
-
entries =
|
|
50052
|
+
entries = fs30.readdirSync(dir);
|
|
50008
50053
|
} catch (err) {
|
|
50009
50054
|
if (err?.code === "ENOENT") return [];
|
|
50010
50055
|
return [];
|
|
@@ -50020,9 +50065,9 @@ var InboxStore = class {
|
|
|
50020
50065
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
50021
50066
|
const file = this.filePath(message.peerDeviceId);
|
|
50022
50067
|
const line = JSON.stringify(message) + "\n";
|
|
50023
|
-
|
|
50068
|
+
fs30.appendFileSync(file, line, { mode: 384 });
|
|
50024
50069
|
try {
|
|
50025
|
-
|
|
50070
|
+
fs30.chmodSync(file, 384);
|
|
50026
50071
|
} catch {
|
|
50027
50072
|
}
|
|
50028
50073
|
}
|
|
@@ -50052,7 +50097,7 @@ var InboxStore = class {
|
|
|
50052
50097
|
removeByPeerDeviceId(peerDeviceId) {
|
|
50053
50098
|
const file = this.filePath(peerDeviceId);
|
|
50054
50099
|
try {
|
|
50055
|
-
|
|
50100
|
+
fs30.unlinkSync(file);
|
|
50056
50101
|
} catch (err) {
|
|
50057
50102
|
if (err?.code === "ENOENT") return;
|
|
50058
50103
|
}
|
|
@@ -50061,10 +50106,10 @@ var InboxStore = class {
|
|
|
50061
50106
|
const file = this.filePath(peerDeviceId);
|
|
50062
50107
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
50063
50108
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
50064
|
-
|
|
50065
|
-
|
|
50109
|
+
fs30.writeFileSync(tmp, content, { mode: 384 });
|
|
50110
|
+
fs30.renameSync(tmp, file);
|
|
50066
50111
|
try {
|
|
50067
|
-
|
|
50112
|
+
fs30.chmodSync(file, 384);
|
|
50068
50113
|
} catch {
|
|
50069
50114
|
}
|
|
50070
50115
|
}
|
|
@@ -50115,7 +50160,8 @@ var InboxManager = class {
|
|
|
50115
50160
|
senderDeviceId: args.senderDeviceId,
|
|
50116
50161
|
text: args.text,
|
|
50117
50162
|
createdAt: args.createdAt,
|
|
50118
|
-
readBy: {}
|
|
50163
|
+
readBy: {},
|
|
50164
|
+
...args.origin ? { origin: args.origin } : {}
|
|
50119
50165
|
};
|
|
50120
50166
|
this.store.append(msg);
|
|
50121
50167
|
const afterLen = this.store.list(args.peerDeviceId).length;
|
|
@@ -50159,7 +50205,7 @@ var InboxManager = class {
|
|
|
50159
50205
|
};
|
|
50160
50206
|
|
|
50161
50207
|
// src/state/contact-store.ts
|
|
50162
|
-
var
|
|
50208
|
+
var fs31 = __toESM(require("fs"), 1);
|
|
50163
50209
|
var path29 = __toESM(require("path"), 1);
|
|
50164
50210
|
var FILE_NAME = "contacts.json";
|
|
50165
50211
|
var ContactStore = class {
|
|
@@ -50173,7 +50219,7 @@ var ContactStore = class {
|
|
|
50173
50219
|
const file = path29.join(this.dataDir, FILE_NAME);
|
|
50174
50220
|
let raw;
|
|
50175
50221
|
try {
|
|
50176
|
-
raw =
|
|
50222
|
+
raw = fs31.readFileSync(file, "utf8");
|
|
50177
50223
|
} catch (err) {
|
|
50178
50224
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
50179
50225
|
return;
|
|
@@ -50223,13 +50269,13 @@ var ContactStore = class {
|
|
|
50223
50269
|
null,
|
|
50224
50270
|
2
|
|
50225
50271
|
);
|
|
50226
|
-
|
|
50227
|
-
|
|
50228
|
-
|
|
50272
|
+
fs31.mkdirSync(this.dataDir, { recursive: true });
|
|
50273
|
+
fs31.writeFileSync(tmp, content, { mode: 384 });
|
|
50274
|
+
fs31.renameSync(tmp, file);
|
|
50229
50275
|
}
|
|
50230
50276
|
renameBak(file) {
|
|
50231
50277
|
try {
|
|
50232
|
-
|
|
50278
|
+
fs31.renameSync(file, `${file}.bak`);
|
|
50233
50279
|
} catch {
|
|
50234
50280
|
}
|
|
50235
50281
|
}
|
|
@@ -50379,7 +50425,7 @@ async function autoReverseContact(args) {
|
|
|
50379
50425
|
}
|
|
50380
50426
|
|
|
50381
50427
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
50382
|
-
var
|
|
50428
|
+
var fs32 = __toESM(require("fs"), 1);
|
|
50383
50429
|
var path30 = __toESM(require("path"), 1);
|
|
50384
50430
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
50385
50431
|
function migrateFlattenSessions(opts) {
|
|
@@ -50399,7 +50445,7 @@ function migrateFlattenSessions(opts) {
|
|
|
50399
50445
|
if (!entry.endsWith(".json")) continue;
|
|
50400
50446
|
const src = path30.join(defaultDir, entry);
|
|
50401
50447
|
const dst = path30.join(sessionsDir, entry);
|
|
50402
|
-
|
|
50448
|
+
fs32.renameSync(src, dst);
|
|
50403
50449
|
movedBare += 1;
|
|
50404
50450
|
}
|
|
50405
50451
|
rmdirIfEmpty(defaultDir);
|
|
@@ -50411,10 +50457,10 @@ function migrateFlattenSessions(opts) {
|
|
|
50411
50457
|
const ownerSrc = path30.join(personaDir, "owner");
|
|
50412
50458
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
50413
50459
|
const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
50414
|
-
|
|
50460
|
+
fs32.mkdirSync(ownerDst, { recursive: true });
|
|
50415
50461
|
for (const file of readdirSafe(ownerSrc)) {
|
|
50416
50462
|
if (!file.endsWith(".json")) continue;
|
|
50417
|
-
|
|
50463
|
+
fs32.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
|
|
50418
50464
|
movedVmOwner += 1;
|
|
50419
50465
|
}
|
|
50420
50466
|
rmdirIfEmpty(ownerSrc);
|
|
@@ -50422,18 +50468,18 @@ function migrateFlattenSessions(opts) {
|
|
|
50422
50468
|
const listenerSrc = path30.join(personaDir, "listener");
|
|
50423
50469
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
50424
50470
|
const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
|
|
50425
|
-
|
|
50471
|
+
fs32.mkdirSync(archiveDst, { recursive: true });
|
|
50426
50472
|
for (const file of readdirSafe(listenerSrc)) {
|
|
50427
50473
|
if (!file.endsWith(".json")) continue;
|
|
50428
|
-
|
|
50474
|
+
fs32.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
|
|
50429
50475
|
archivedListener += 1;
|
|
50430
50476
|
}
|
|
50431
50477
|
rmdirIfEmpty(listenerSrc);
|
|
50432
50478
|
}
|
|
50433
50479
|
rmdirIfEmpty(personaDir);
|
|
50434
50480
|
}
|
|
50435
|
-
|
|
50436
|
-
|
|
50481
|
+
fs32.mkdirSync(sessionsDir, { recursive: true });
|
|
50482
|
+
fs32.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
50437
50483
|
return {
|
|
50438
50484
|
skipped: false,
|
|
50439
50485
|
flagWritten: true,
|
|
@@ -50444,7 +50490,7 @@ function migrateFlattenSessions(opts) {
|
|
|
50444
50490
|
}
|
|
50445
50491
|
function existsSync3(p2) {
|
|
50446
50492
|
try {
|
|
50447
|
-
|
|
50493
|
+
fs32.statSync(p2);
|
|
50448
50494
|
return true;
|
|
50449
50495
|
} catch {
|
|
50450
50496
|
return false;
|
|
@@ -50452,27 +50498,27 @@ function existsSync3(p2) {
|
|
|
50452
50498
|
}
|
|
50453
50499
|
function isDir(p2) {
|
|
50454
50500
|
try {
|
|
50455
|
-
return
|
|
50501
|
+
return fs32.statSync(p2).isDirectory();
|
|
50456
50502
|
} catch {
|
|
50457
50503
|
return false;
|
|
50458
50504
|
}
|
|
50459
50505
|
}
|
|
50460
50506
|
function readdirSafe(p2) {
|
|
50461
50507
|
try {
|
|
50462
|
-
return
|
|
50508
|
+
return fs32.readdirSync(p2);
|
|
50463
50509
|
} catch {
|
|
50464
50510
|
return [];
|
|
50465
50511
|
}
|
|
50466
50512
|
}
|
|
50467
50513
|
function rmdirIfEmpty(p2) {
|
|
50468
50514
|
try {
|
|
50469
|
-
|
|
50515
|
+
fs32.rmdirSync(p2);
|
|
50470
50516
|
} catch {
|
|
50471
50517
|
}
|
|
50472
50518
|
}
|
|
50473
50519
|
|
|
50474
50520
|
// src/transport/http-router.ts
|
|
50475
|
-
var
|
|
50521
|
+
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
50476
50522
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
50477
50523
|
|
|
50478
50524
|
// src/attachment/mime.ts
|
|
@@ -50652,7 +50698,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
50652
50698
|
}
|
|
50653
50699
|
|
|
50654
50700
|
// src/attachment/upload.ts
|
|
50655
|
-
var
|
|
50701
|
+
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
50656
50702
|
var import_node_path24 = __toESM(require("path"), 1);
|
|
50657
50703
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
50658
50704
|
var import_promises2 = require("stream/promises");
|
|
@@ -50674,7 +50720,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50674
50720
|
assertValidFileName(args.fileName);
|
|
50675
50721
|
const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
|
|
50676
50722
|
try {
|
|
50677
|
-
|
|
50723
|
+
import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
50678
50724
|
} catch (err) {
|
|
50679
50725
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
50680
50726
|
}
|
|
@@ -50695,18 +50741,18 @@ async function writeUploadedAttachment(args) {
|
|
|
50695
50741
|
yield buf;
|
|
50696
50742
|
}
|
|
50697
50743
|
},
|
|
50698
|
-
|
|
50744
|
+
import_node_fs25.default.createWriteStream(tmpPath, { mode: 384 })
|
|
50699
50745
|
);
|
|
50700
50746
|
} catch (err) {
|
|
50701
50747
|
try {
|
|
50702
|
-
|
|
50748
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50703
50749
|
} catch {
|
|
50704
50750
|
}
|
|
50705
50751
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
50706
50752
|
}
|
|
50707
50753
|
if (actualSize !== args.contentLength) {
|
|
50708
50754
|
try {
|
|
50709
|
-
|
|
50755
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50710
50756
|
} catch {
|
|
50711
50757
|
}
|
|
50712
50758
|
throw new UploadError(
|
|
@@ -50719,24 +50765,24 @@ async function writeUploadedAttachment(args) {
|
|
|
50719
50765
|
let finalFileName;
|
|
50720
50766
|
let hashDirExists = false;
|
|
50721
50767
|
try {
|
|
50722
|
-
hashDirExists =
|
|
50768
|
+
hashDirExists = import_node_fs25.default.statSync(hashDir).isDirectory();
|
|
50723
50769
|
} catch {
|
|
50724
50770
|
}
|
|
50725
50771
|
if (hashDirExists) {
|
|
50726
|
-
const existing =
|
|
50772
|
+
const existing = import_node_fs25.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
|
|
50727
50773
|
finalFileName = existing[0] ?? args.fileName;
|
|
50728
50774
|
try {
|
|
50729
|
-
|
|
50775
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50730
50776
|
} catch {
|
|
50731
50777
|
}
|
|
50732
50778
|
} else {
|
|
50733
50779
|
try {
|
|
50734
|
-
|
|
50780
|
+
import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
|
|
50735
50781
|
finalFileName = args.fileName;
|
|
50736
|
-
|
|
50782
|
+
import_node_fs25.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
|
|
50737
50783
|
} catch (err) {
|
|
50738
50784
|
try {
|
|
50739
|
-
|
|
50785
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50740
50786
|
} catch {
|
|
50741
50787
|
}
|
|
50742
50788
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
@@ -50758,7 +50804,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50758
50804
|
// src/extension/import.ts
|
|
50759
50805
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
50760
50806
|
var import_node_path25 = __toESM(require("path"), 1);
|
|
50761
|
-
var
|
|
50807
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
50762
50808
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
50763
50809
|
var ImportError = class extends Error {
|
|
50764
50810
|
constructor(code, message) {
|
|
@@ -50818,7 +50864,7 @@ async function importZip(buf, root) {
|
|
|
50818
50864
|
if (destExists) {
|
|
50819
50865
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
50820
50866
|
}
|
|
50821
|
-
const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(
|
|
50867
|
+
const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
50822
50868
|
try {
|
|
50823
50869
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
50824
50870
|
const dest = import_node_path25.default.join(stage, name);
|
|
@@ -51016,7 +51062,7 @@ function createHttpRouter(deps) {
|
|
|
51016
51062
|
}
|
|
51017
51063
|
let buf;
|
|
51018
51064
|
try {
|
|
51019
|
-
buf = await
|
|
51065
|
+
buf = await import_node_fs26.default.promises.readFile(abs);
|
|
51020
51066
|
} catch {
|
|
51021
51067
|
sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
51022
51068
|
return true;
|
|
@@ -51456,7 +51502,7 @@ function withCtx(ctx, body) {
|
|
|
51456
51502
|
function streamFile(res, absPath, logger) {
|
|
51457
51503
|
let stat;
|
|
51458
51504
|
try {
|
|
51459
|
-
stat =
|
|
51505
|
+
stat = import_node_fs26.default.statSync(absPath);
|
|
51460
51506
|
} catch (err) {
|
|
51461
51507
|
const code = err?.code;
|
|
51462
51508
|
if (code === "ENOENT") {
|
|
@@ -51479,7 +51525,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51479
51525
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
51480
51526
|
"X-Content-Type-Options": "nosniff"
|
|
51481
51527
|
});
|
|
51482
|
-
const stream =
|
|
51528
|
+
const stream = import_node_fs26.default.createReadStream(absPath);
|
|
51483
51529
|
stream.on("error", (err) => {
|
|
51484
51530
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
51485
51531
|
res.destroy();
|
|
@@ -51488,7 +51534,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51488
51534
|
}
|
|
51489
51535
|
|
|
51490
51536
|
// src/attachment/gc.ts
|
|
51491
|
-
var
|
|
51537
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
51492
51538
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
51493
51539
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
51494
51540
|
function runAttachmentGc(args) {
|
|
@@ -51511,7 +51557,7 @@ function runAttachmentGc(args) {
|
|
|
51511
51557
|
const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
|
|
51512
51558
|
let hashDirs;
|
|
51513
51559
|
try {
|
|
51514
|
-
hashDirs =
|
|
51560
|
+
hashDirs = import_node_fs27.default.readdirSync(attRoot);
|
|
51515
51561
|
} catch (err) {
|
|
51516
51562
|
if (err.code === "ENOENT") continue;
|
|
51517
51563
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
@@ -51521,7 +51567,7 @@ function runAttachmentGc(args) {
|
|
|
51521
51567
|
const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
|
|
51522
51568
|
let files;
|
|
51523
51569
|
try {
|
|
51524
|
-
files =
|
|
51570
|
+
files = import_node_fs27.default.readdirSync(hashDirAbs);
|
|
51525
51571
|
} catch {
|
|
51526
51572
|
continue;
|
|
51527
51573
|
}
|
|
@@ -51529,7 +51575,7 @@ function runAttachmentGc(args) {
|
|
|
51529
51575
|
const file = import_node_path27.default.join(hashDirAbs, name);
|
|
51530
51576
|
let stat;
|
|
51531
51577
|
try {
|
|
51532
|
-
stat =
|
|
51578
|
+
stat = import_node_fs27.default.statSync(file);
|
|
51533
51579
|
} catch {
|
|
51534
51580
|
continue;
|
|
51535
51581
|
}
|
|
@@ -51538,25 +51584,25 @@ function runAttachmentGc(args) {
|
|
|
51538
51584
|
if (age < ttlMs) continue;
|
|
51539
51585
|
if (liveAbs.has(file)) continue;
|
|
51540
51586
|
try {
|
|
51541
|
-
|
|
51587
|
+
import_node_fs27.default.unlinkSync(file);
|
|
51542
51588
|
} catch (err) {
|
|
51543
51589
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
51544
51590
|
}
|
|
51545
51591
|
}
|
|
51546
51592
|
try {
|
|
51547
|
-
if (
|
|
51593
|
+
if (import_node_fs27.default.readdirSync(hashDirAbs).length === 0) import_node_fs27.default.rmdirSync(hashDirAbs);
|
|
51548
51594
|
} catch {
|
|
51549
51595
|
}
|
|
51550
51596
|
}
|
|
51551
51597
|
try {
|
|
51552
|
-
if (
|
|
51598
|
+
if (import_node_fs27.default.readdirSync(attRoot).length === 0) import_node_fs27.default.rmdirSync(attRoot);
|
|
51553
51599
|
} catch {
|
|
51554
51600
|
}
|
|
51555
51601
|
}
|
|
51556
51602
|
}
|
|
51557
51603
|
|
|
51558
51604
|
// src/attachment/group.ts
|
|
51559
|
-
var
|
|
51605
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
51560
51606
|
var import_node_path28 = __toESM(require("path"), 1);
|
|
51561
51607
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
51562
51608
|
init_protocol();
|
|
@@ -51582,7 +51628,7 @@ var GroupFileStore = class {
|
|
|
51582
51628
|
readFile(scope, sessionId) {
|
|
51583
51629
|
const file = this.filePath(scope, sessionId);
|
|
51584
51630
|
try {
|
|
51585
|
-
const raw =
|
|
51631
|
+
const raw = import_node_fs28.default.readFileSync(file, "utf8");
|
|
51586
51632
|
const parsed = JSON.parse(raw);
|
|
51587
51633
|
if (!Array.isArray(parsed)) {
|
|
51588
51634
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -51608,10 +51654,10 @@ var GroupFileStore = class {
|
|
|
51608
51654
|
}
|
|
51609
51655
|
writeFile(scope, sessionId, entries) {
|
|
51610
51656
|
const file = this.filePath(scope, sessionId);
|
|
51611
|
-
|
|
51657
|
+
import_node_fs28.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
|
|
51612
51658
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
51613
|
-
|
|
51614
|
-
|
|
51659
|
+
import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
51660
|
+
import_node_fs28.default.renameSync(tmp, file);
|
|
51615
51661
|
}
|
|
51616
51662
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
51617
51663
|
list(scope, sessionId) {
|
|
@@ -51697,7 +51743,7 @@ var GroupFileStore = class {
|
|
|
51697
51743
|
};
|
|
51698
51744
|
|
|
51699
51745
|
// src/discovery/state-file.ts
|
|
51700
|
-
var
|
|
51746
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
51701
51747
|
var import_node_path29 = __toESM(require("path"), 1);
|
|
51702
51748
|
function defaultStateFilePath(dataDir) {
|
|
51703
51749
|
return import_node_path29.default.join(dataDir, "state.json");
|
|
@@ -51722,7 +51768,7 @@ var StateFileManager = class {
|
|
|
51722
51768
|
}
|
|
51723
51769
|
read() {
|
|
51724
51770
|
try {
|
|
51725
|
-
const raw =
|
|
51771
|
+
const raw = import_node_fs29.default.readFileSync(this.file, "utf8");
|
|
51726
51772
|
const parsed = JSON.parse(raw);
|
|
51727
51773
|
return parsed;
|
|
51728
51774
|
} catch {
|
|
@@ -51736,20 +51782,20 @@ var StateFileManager = class {
|
|
|
51736
51782
|
return { status: "stale", existing };
|
|
51737
51783
|
}
|
|
51738
51784
|
write(state) {
|
|
51739
|
-
|
|
51785
|
+
import_node_fs29.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
|
|
51740
51786
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
51741
|
-
|
|
51742
|
-
|
|
51787
|
+
import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
51788
|
+
import_node_fs29.default.renameSync(tmp, this.file);
|
|
51743
51789
|
if (process.platform !== "win32") {
|
|
51744
51790
|
try {
|
|
51745
|
-
|
|
51791
|
+
import_node_fs29.default.chmodSync(this.file, 384);
|
|
51746
51792
|
} catch {
|
|
51747
51793
|
}
|
|
51748
51794
|
}
|
|
51749
51795
|
}
|
|
51750
51796
|
delete() {
|
|
51751
51797
|
try {
|
|
51752
|
-
|
|
51798
|
+
import_node_fs29.default.unlinkSync(this.file);
|
|
51753
51799
|
} catch {
|
|
51754
51800
|
}
|
|
51755
51801
|
}
|
|
@@ -51764,13 +51810,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
51764
51810
|
}
|
|
51765
51811
|
|
|
51766
51812
|
// src/tunnel/tunnel-manager.ts
|
|
51767
|
-
var
|
|
51813
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
51768
51814
|
var import_node_path33 = __toESM(require("path"), 1);
|
|
51769
51815
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
51770
51816
|
var import_node_child_process9 = require("child_process");
|
|
51771
51817
|
|
|
51772
51818
|
// src/tunnel/tunnel-store.ts
|
|
51773
|
-
var
|
|
51819
|
+
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
51774
51820
|
var import_node_path30 = __toESM(require("path"), 1);
|
|
51775
51821
|
var TunnelStore = class {
|
|
51776
51822
|
constructor(filePath) {
|
|
@@ -51779,7 +51825,7 @@ var TunnelStore = class {
|
|
|
51779
51825
|
filePath;
|
|
51780
51826
|
async get() {
|
|
51781
51827
|
try {
|
|
51782
|
-
const raw = await
|
|
51828
|
+
const raw = await import_node_fs30.default.promises.readFile(this.filePath, "utf8");
|
|
51783
51829
|
const obj = JSON.parse(raw);
|
|
51784
51830
|
if (!isPersistedTunnel(obj)) return null;
|
|
51785
51831
|
return obj;
|
|
@@ -51791,21 +51837,21 @@ var TunnelStore = class {
|
|
|
51791
51837
|
}
|
|
51792
51838
|
async set(v2) {
|
|
51793
51839
|
const dir = import_node_path30.default.dirname(this.filePath);
|
|
51794
|
-
await
|
|
51840
|
+
await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
|
|
51795
51841
|
const data = JSON.stringify(v2, null, 2);
|
|
51796
51842
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
51797
|
-
await
|
|
51843
|
+
await import_node_fs30.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
51798
51844
|
if (process.platform !== "win32") {
|
|
51799
51845
|
try {
|
|
51800
|
-
await
|
|
51846
|
+
await import_node_fs30.default.promises.chmod(tmp, 384);
|
|
51801
51847
|
} catch {
|
|
51802
51848
|
}
|
|
51803
51849
|
}
|
|
51804
|
-
await
|
|
51850
|
+
await import_node_fs30.default.promises.rename(tmp, this.filePath);
|
|
51805
51851
|
}
|
|
51806
51852
|
async clear() {
|
|
51807
51853
|
try {
|
|
51808
|
-
await
|
|
51854
|
+
await import_node_fs30.default.promises.unlink(this.filePath);
|
|
51809
51855
|
} catch (err) {
|
|
51810
51856
|
const code = err?.code;
|
|
51811
51857
|
if (code !== "ENOENT") throw err;
|
|
@@ -51900,8 +51946,8 @@ function escape(v2) {
|
|
|
51900
51946
|
}
|
|
51901
51947
|
|
|
51902
51948
|
// src/tunnel/frpc-binary.ts
|
|
51903
|
-
var
|
|
51904
|
-
var
|
|
51949
|
+
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
51950
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
51905
51951
|
var import_node_path31 = __toESM(require("path"), 1);
|
|
51906
51952
|
var import_node_child_process7 = require("child_process");
|
|
51907
51953
|
var import_node_stream3 = require("stream");
|
|
@@ -51934,7 +51980,7 @@ function frpcDownloadUrl(version2, p2) {
|
|
|
51934
51980
|
}
|
|
51935
51981
|
async function ensureFrpcBinary(opts) {
|
|
51936
51982
|
if (opts.override) {
|
|
51937
|
-
if (!
|
|
51983
|
+
if (!import_node_fs31.default.existsSync(opts.override)) {
|
|
51938
51984
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
51939
51985
|
}
|
|
51940
51986
|
return opts.override;
|
|
@@ -51942,10 +51988,10 @@ async function ensureFrpcBinary(opts) {
|
|
|
51942
51988
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
51943
51989
|
const platform = opts.platform ?? detectPlatform();
|
|
51944
51990
|
const binDir = import_node_path31.default.join(opts.dataDir, "bin");
|
|
51945
|
-
|
|
51991
|
+
import_node_fs31.default.mkdirSync(binDir, { recursive: true });
|
|
51946
51992
|
cleanupStaleArtifacts(binDir);
|
|
51947
51993
|
const stableBin = import_node_path31.default.join(binDir, "frpc");
|
|
51948
|
-
if (
|
|
51994
|
+
if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
|
|
51949
51995
|
const partialBin = `${stableBin}.partial`;
|
|
51950
51996
|
const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
51951
51997
|
try {
|
|
@@ -51956,8 +52002,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
51956
52002
|
} else {
|
|
51957
52003
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
51958
52004
|
}
|
|
51959
|
-
|
|
51960
|
-
|
|
52005
|
+
import_node_fs31.default.chmodSync(partialBin, 493);
|
|
52006
|
+
import_node_fs31.default.renameSync(partialBin, stableBin);
|
|
51961
52007
|
} finally {
|
|
51962
52008
|
safeUnlink(tarballPath);
|
|
51963
52009
|
safeUnlink(partialBin);
|
|
@@ -51967,7 +52013,7 @@ async function ensureFrpcBinary(opts) {
|
|
|
51967
52013
|
function cleanupStaleArtifacts(binDir) {
|
|
51968
52014
|
let entries;
|
|
51969
52015
|
try {
|
|
51970
|
-
entries =
|
|
52016
|
+
entries = import_node_fs31.default.readdirSync(binDir);
|
|
51971
52017
|
} catch {
|
|
51972
52018
|
return;
|
|
51973
52019
|
}
|
|
@@ -51975,7 +52021,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
51975
52021
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
51976
52022
|
const full = import_node_path31.default.join(binDir, name);
|
|
51977
52023
|
try {
|
|
51978
|
-
|
|
52024
|
+
import_node_fs31.default.rmSync(full, { recursive: true, force: true });
|
|
51979
52025
|
} catch {
|
|
51980
52026
|
}
|
|
51981
52027
|
}
|
|
@@ -51983,7 +52029,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
51983
52029
|
}
|
|
51984
52030
|
function safeUnlink(p2) {
|
|
51985
52031
|
try {
|
|
51986
|
-
|
|
52032
|
+
import_node_fs31.default.unlinkSync(p2);
|
|
51987
52033
|
} catch {
|
|
51988
52034
|
}
|
|
51989
52035
|
}
|
|
@@ -51994,13 +52040,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
51994
52040
|
if (!res.ok || !res.body) {
|
|
51995
52041
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
51996
52042
|
}
|
|
51997
|
-
const out =
|
|
52043
|
+
const out = import_node_fs31.default.createWriteStream(dest);
|
|
51998
52044
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
51999
52045
|
await (0, import_promises4.pipeline)(nodeStream, out);
|
|
52000
52046
|
}
|
|
52001
52047
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
52002
52048
|
const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
52003
|
-
|
|
52049
|
+
import_node_fs31.default.mkdirSync(work, { recursive: true });
|
|
52004
52050
|
try {
|
|
52005
52051
|
await new Promise((resolve6, reject) => {
|
|
52006
52052
|
const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -52009,17 +52055,17 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
52009
52055
|
});
|
|
52010
52056
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
52011
52057
|
const src = import_node_path31.default.join(work, dirName, "frpc");
|
|
52012
|
-
if (!
|
|
52058
|
+
if (!import_node_fs31.default.existsSync(src)) {
|
|
52013
52059
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
52014
52060
|
}
|
|
52015
|
-
|
|
52061
|
+
import_node_fs31.default.copyFileSync(src, destBin);
|
|
52016
52062
|
} finally {
|
|
52017
|
-
|
|
52063
|
+
import_node_fs31.default.rmSync(work, { recursive: true, force: true });
|
|
52018
52064
|
}
|
|
52019
52065
|
}
|
|
52020
52066
|
|
|
52021
52067
|
// src/tunnel/frpc-process.ts
|
|
52022
|
-
var
|
|
52068
|
+
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
52023
52069
|
var import_node_path32 = __toESM(require("path"), 1);
|
|
52024
52070
|
var import_node_child_process8 = require("child_process");
|
|
52025
52071
|
function frpcPidFilePath(dataDir) {
|
|
@@ -52027,13 +52073,13 @@ function frpcPidFilePath(dataDir) {
|
|
|
52027
52073
|
}
|
|
52028
52074
|
function writeFrpcPid(dataDir, pid) {
|
|
52029
52075
|
try {
|
|
52030
|
-
|
|
52076
|
+
import_node_fs32.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
52031
52077
|
} catch {
|
|
52032
52078
|
}
|
|
52033
52079
|
}
|
|
52034
52080
|
function clearFrpcPid(dataDir) {
|
|
52035
52081
|
try {
|
|
52036
|
-
|
|
52082
|
+
import_node_fs32.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
52037
52083
|
} catch {
|
|
52038
52084
|
}
|
|
52039
52085
|
}
|
|
@@ -52049,7 +52095,7 @@ function defaultIsPidAlive(pid) {
|
|
|
52049
52095
|
}
|
|
52050
52096
|
function defaultReadPidFile(file) {
|
|
52051
52097
|
try {
|
|
52052
|
-
return
|
|
52098
|
+
return import_node_fs32.default.readFileSync(file, "utf8");
|
|
52053
52099
|
} catch {
|
|
52054
52100
|
return null;
|
|
52055
52101
|
}
|
|
@@ -52089,7 +52135,7 @@ async function killStaleFrpc(deps) {
|
|
|
52089
52135
|
}
|
|
52090
52136
|
if (victims.size === 0) {
|
|
52091
52137
|
try {
|
|
52092
|
-
|
|
52138
|
+
import_node_fs32.default.unlinkSync(pidFile);
|
|
52093
52139
|
} catch {
|
|
52094
52140
|
}
|
|
52095
52141
|
return;
|
|
@@ -52100,7 +52146,7 @@ async function killStaleFrpc(deps) {
|
|
|
52100
52146
|
}
|
|
52101
52147
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
52102
52148
|
try {
|
|
52103
|
-
|
|
52149
|
+
import_node_fs32.default.unlinkSync(pidFile);
|
|
52104
52150
|
} catch {
|
|
52105
52151
|
}
|
|
52106
52152
|
}
|
|
@@ -52275,12 +52321,12 @@ var TunnelManager = class {
|
|
|
52275
52321
|
localPort,
|
|
52276
52322
|
logLevel: "info"
|
|
52277
52323
|
});
|
|
52278
|
-
await
|
|
52324
|
+
await import_node_fs33.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
52279
52325
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
52280
52326
|
stdio: ["ignore", "pipe", "pipe"]
|
|
52281
52327
|
});
|
|
52282
52328
|
const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
|
|
52283
|
-
const logStream =
|
|
52329
|
+
const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
52284
52330
|
logStream.on("error", () => {
|
|
52285
52331
|
});
|
|
52286
52332
|
const tee = (chunk) => {
|
|
@@ -52362,14 +52408,14 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52362
52408
|
}
|
|
52363
52409
|
|
|
52364
52410
|
// src/tunnel/device-key.ts
|
|
52365
|
-
var
|
|
52411
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
52366
52412
|
var import_node_path34 = __toESM(require("path"), 1);
|
|
52367
52413
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
52368
52414
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
52369
52415
|
function deriveStableDeviceKey(opts = {}) {
|
|
52370
|
-
const hostname = opts.hostname ??
|
|
52371
|
-
const uid = opts.uid ?? (typeof
|
|
52372
|
-
const home = opts.home ??
|
|
52416
|
+
const hostname = opts.hostname ?? import_node_os13.default.hostname();
|
|
52417
|
+
const uid = opts.uid ?? (typeof import_node_os13.default.userInfo === "function" ? import_node_os13.default.userInfo().uid : 0);
|
|
52418
|
+
const home = opts.home ?? import_node_os13.default.homedir();
|
|
52373
52419
|
const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
|
|
52374
52420
|
const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
|
|
52375
52421
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
@@ -52378,7 +52424,7 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
52378
52424
|
}
|
|
52379
52425
|
|
|
52380
52426
|
// src/auth-store.ts
|
|
52381
|
-
var
|
|
52427
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
52382
52428
|
var import_node_path35 = __toESM(require("path"), 1);
|
|
52383
52429
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
52384
52430
|
var AUTH_FILE_NAME = "auth.json";
|
|
@@ -52419,7 +52465,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
52419
52465
|
}
|
|
52420
52466
|
function readAuthFile(file) {
|
|
52421
52467
|
try {
|
|
52422
|
-
const raw =
|
|
52468
|
+
const raw = import_node_fs34.default.readFileSync(file, "utf8");
|
|
52423
52469
|
const parsed = JSON.parse(raw);
|
|
52424
52470
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
52425
52471
|
return null;
|
|
@@ -52439,25 +52485,25 @@ function readAuthFile(file) {
|
|
|
52439
52485
|
}
|
|
52440
52486
|
}
|
|
52441
52487
|
function writeAuthFile(file, content) {
|
|
52442
|
-
|
|
52443
|
-
|
|
52488
|
+
import_node_fs34.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
|
|
52489
|
+
import_node_fs34.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
52444
52490
|
try {
|
|
52445
|
-
|
|
52491
|
+
import_node_fs34.default.chmodSync(file, 384);
|
|
52446
52492
|
} catch {
|
|
52447
52493
|
}
|
|
52448
52494
|
}
|
|
52449
52495
|
|
|
52450
52496
|
// src/owner-profile.ts
|
|
52451
|
-
var
|
|
52452
|
-
var
|
|
52497
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
52498
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
52453
52499
|
var import_node_path36 = __toESM(require("path"), 1);
|
|
52454
52500
|
var PROFILE_FILENAME = "profile.json";
|
|
52455
52501
|
function loadOwnerDisplayName(dataDir) {
|
|
52456
|
-
const fallback =
|
|
52502
|
+
const fallback = import_node_os14.default.userInfo().username;
|
|
52457
52503
|
const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
|
|
52458
52504
|
let raw;
|
|
52459
52505
|
try {
|
|
52460
|
-
raw =
|
|
52506
|
+
raw = import_node_fs35.default.readFileSync(profilePath, "utf8");
|
|
52461
52507
|
} catch {
|
|
52462
52508
|
return fallback;
|
|
52463
52509
|
}
|
|
@@ -52480,7 +52526,7 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
52480
52526
|
}
|
|
52481
52527
|
|
|
52482
52528
|
// src/feishu-auth/owner-identity-store.ts
|
|
52483
|
-
var
|
|
52529
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
52484
52530
|
var import_node_path37 = __toESM(require("path"), 1);
|
|
52485
52531
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
52486
52532
|
var OwnerIdentityStore = class {
|
|
@@ -52491,7 +52537,7 @@ var OwnerIdentityStore = class {
|
|
|
52491
52537
|
read() {
|
|
52492
52538
|
let raw;
|
|
52493
52539
|
try {
|
|
52494
|
-
raw =
|
|
52540
|
+
raw = import_node_fs36.default.readFileSync(this.file, "utf8");
|
|
52495
52541
|
} catch {
|
|
52496
52542
|
return null;
|
|
52497
52543
|
}
|
|
@@ -52519,16 +52565,16 @@ var OwnerIdentityStore = class {
|
|
|
52519
52565
|
};
|
|
52520
52566
|
}
|
|
52521
52567
|
write(record) {
|
|
52522
|
-
|
|
52523
|
-
|
|
52568
|
+
import_node_fs36.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
|
|
52569
|
+
import_node_fs36.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
52524
52570
|
try {
|
|
52525
|
-
|
|
52571
|
+
import_node_fs36.default.chmodSync(this.file, 384);
|
|
52526
52572
|
} catch {
|
|
52527
52573
|
}
|
|
52528
52574
|
}
|
|
52529
52575
|
clear() {
|
|
52530
52576
|
try {
|
|
52531
|
-
|
|
52577
|
+
import_node_fs36.default.unlinkSync(this.file);
|
|
52532
52578
|
} catch (err) {
|
|
52533
52579
|
const code = err?.code;
|
|
52534
52580
|
if (code !== "ENOENT") throw err;
|
|
@@ -52793,7 +52839,7 @@ function verifyConnectToken(args) {
|
|
|
52793
52839
|
}
|
|
52794
52840
|
|
|
52795
52841
|
// src/feishu-auth/server-key.ts
|
|
52796
|
-
var
|
|
52842
|
+
var fs46 = __toESM(require("fs"), 1);
|
|
52797
52843
|
var path46 = __toESM(require("path"), 1);
|
|
52798
52844
|
var FILE_NAME2 = "server-signing-key.json";
|
|
52799
52845
|
var ServerKeyStore = class {
|
|
@@ -52807,7 +52853,7 @@ var ServerKeyStore = class {
|
|
|
52807
52853
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
52808
52854
|
read() {
|
|
52809
52855
|
try {
|
|
52810
|
-
const raw =
|
|
52856
|
+
const raw = fs46.readFileSync(this.filePath(), "utf8");
|
|
52811
52857
|
const parsed = JSON.parse(raw);
|
|
52812
52858
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
52813
52859
|
return parsed.publicKeyPem;
|
|
@@ -52822,12 +52868,12 @@ var ServerKeyStore = class {
|
|
|
52822
52868
|
publicKeyPem,
|
|
52823
52869
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
52824
52870
|
};
|
|
52825
|
-
|
|
52826
|
-
|
|
52871
|
+
fs46.mkdirSync(this.dataDir, { recursive: true });
|
|
52872
|
+
fs46.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
52827
52873
|
}
|
|
52828
52874
|
clear() {
|
|
52829
52875
|
try {
|
|
52830
|
-
|
|
52876
|
+
fs46.unlinkSync(this.filePath());
|
|
52831
52877
|
} catch {
|
|
52832
52878
|
}
|
|
52833
52879
|
}
|
|
@@ -52840,12 +52886,12 @@ init_protocol();
|
|
|
52840
52886
|
init_protocol();
|
|
52841
52887
|
|
|
52842
52888
|
// src/session/fork.ts
|
|
52843
|
-
var
|
|
52844
|
-
var
|
|
52889
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
52890
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
52845
52891
|
var import_node_path38 = __toESM(require("path"), 1);
|
|
52846
52892
|
init_claude_history();
|
|
52847
52893
|
function readJsonlEntries(file) {
|
|
52848
|
-
const raw =
|
|
52894
|
+
const raw = import_node_fs37.default.readFileSync(file, "utf8");
|
|
52849
52895
|
const out = [];
|
|
52850
52896
|
for (const line of raw.split("\n")) {
|
|
52851
52897
|
const t = line.trim();
|
|
@@ -52858,10 +52904,10 @@ function readJsonlEntries(file) {
|
|
|
52858
52904
|
return out;
|
|
52859
52905
|
}
|
|
52860
52906
|
function forkSession(input) {
|
|
52861
|
-
const baseDir = input.baseDir ?? import_node_path38.default.join(
|
|
52907
|
+
const baseDir = input.baseDir ?? import_node_path38.default.join(import_node_os15.default.homedir(), ".claude");
|
|
52862
52908
|
const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
52863
52909
|
const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
52864
|
-
if (!
|
|
52910
|
+
if (!import_node_fs37.default.existsSync(sourceFile)) {
|
|
52865
52911
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
52866
52912
|
}
|
|
52867
52913
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -52892,8 +52938,8 @@ function forkSession(input) {
|
|
|
52892
52938
|
forkedLines.push(JSON.stringify(forked));
|
|
52893
52939
|
}
|
|
52894
52940
|
const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
52895
|
-
|
|
52896
|
-
|
|
52941
|
+
import_node_fs37.default.mkdirSync(projectDir, { recursive: true });
|
|
52942
|
+
import_node_fs37.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
52897
52943
|
return { forkedToolSessionId, forkedFilePath };
|
|
52898
52944
|
}
|
|
52899
52945
|
|
|
@@ -53414,7 +53460,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53414
53460
|
|
|
53415
53461
|
// src/handlers/workspace.ts
|
|
53416
53462
|
var path50 = __toESM(require("path"), 1);
|
|
53417
|
-
var
|
|
53463
|
+
var os15 = __toESM(require("os"), 1);
|
|
53418
53464
|
init_protocol();
|
|
53419
53465
|
init_protocol();
|
|
53420
53466
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -53454,7 +53500,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53454
53500
|
const list = async (frame, _client, ctx) => {
|
|
53455
53501
|
const args = WorkspaceListArgs.parse(frame);
|
|
53456
53502
|
const isGuest = ctx?.principal.kind === "guest";
|
|
53457
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
53503
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
|
|
53458
53504
|
const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
|
|
53459
53505
|
const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
53460
53506
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
@@ -53510,14 +53556,14 @@ init_protocol();
|
|
|
53510
53556
|
|
|
53511
53557
|
// src/workspace/git.ts
|
|
53512
53558
|
var import_node_child_process10 = require("child_process");
|
|
53513
|
-
var
|
|
53559
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53514
53560
|
var import_node_path39 = __toESM(require("path"), 1);
|
|
53515
53561
|
var import_node_util = require("util");
|
|
53516
53562
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
53517
53563
|
function normalizePath(p2) {
|
|
53518
53564
|
const resolved = import_node_path39.default.resolve(p2);
|
|
53519
53565
|
try {
|
|
53520
|
-
return
|
|
53566
|
+
return import_node_fs38.default.realpathSync(resolved);
|
|
53521
53567
|
} catch {
|
|
53522
53568
|
return resolved;
|
|
53523
53569
|
}
|
|
@@ -53713,7 +53759,8 @@ function buildInboxHandlers(deps) {
|
|
|
53713
53759
|
senderDeviceId: ctx.principal.id,
|
|
53714
53760
|
text: args.text,
|
|
53715
53761
|
id: args.id,
|
|
53716
|
-
createdAt: args.createdAt
|
|
53762
|
+
createdAt: args.createdAt,
|
|
53763
|
+
origin: args.origin
|
|
53717
53764
|
});
|
|
53718
53765
|
return {
|
|
53719
53766
|
response: { type: "inbox:postMessage:ok", message }
|
|
@@ -53752,8 +53799,66 @@ function buildInboxHandlers(deps) {
|
|
|
53752
53799
|
}
|
|
53753
53800
|
};
|
|
53754
53801
|
};
|
|
53802
|
+
const sendDm = async (frame) => {
|
|
53803
|
+
const { type: _t, requestId: _r, ...rest } = frame;
|
|
53804
|
+
const sessionId = typeof rest.sessionId === "string" ? rest.sessionId : void 0;
|
|
53805
|
+
const args = InboxSendDmArgsSchema.parse(rest);
|
|
53806
|
+
const d = deps.sendDmDeps;
|
|
53807
|
+
if (!d) throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:sendDm not wired");
|
|
53808
|
+
if (!sessionId) {
|
|
53809
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "inbox:sendDm requires sessionId");
|
|
53810
|
+
}
|
|
53811
|
+
const scope = d.getSessionScope(sessionId);
|
|
53812
|
+
if (!scope || scope.kind !== "persona") {
|
|
53813
|
+
throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "inbox:sendDm requires a persona session");
|
|
53814
|
+
}
|
|
53815
|
+
const origin = { kind: "persona", personaId: scope.personaId };
|
|
53816
|
+
const id = d.genId();
|
|
53817
|
+
const createdAt = d.now();
|
|
53818
|
+
if (scope.mode === "guest") {
|
|
53819
|
+
if (args.peerDeviceId && args.peerDeviceId !== d.ownerPrincipalId) {
|
|
53820
|
+
throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "guest-driven persona may only DM the owner");
|
|
53821
|
+
}
|
|
53822
|
+
const message2 = manager.postMessage({
|
|
53823
|
+
peerDeviceId: scope.capId,
|
|
53824
|
+
senderDeviceId: scope.capId,
|
|
53825
|
+
text: args.text,
|
|
53826
|
+
id,
|
|
53827
|
+
createdAt,
|
|
53828
|
+
origin
|
|
53829
|
+
});
|
|
53830
|
+
return { response: { type: "inbox:sendDm:ok", message: message2 } };
|
|
53831
|
+
}
|
|
53832
|
+
if (!args.peerDeviceId) {
|
|
53833
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "owner-driven sendDm requires peerDeviceId");
|
|
53834
|
+
}
|
|
53835
|
+
const contact = d.getContact(args.peerDeviceId);
|
|
53836
|
+
if (!contact) {
|
|
53837
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `unknown contact: ${args.peerDeviceId}`);
|
|
53838
|
+
}
|
|
53839
|
+
const fwd = await d.forwardInboxPostToPeer({
|
|
53840
|
+
contact: { remoteUrl: contact.remoteUrl, connectToken: contact.connectToken },
|
|
53841
|
+
id,
|
|
53842
|
+
text: args.text,
|
|
53843
|
+
createdAt,
|
|
53844
|
+
origin
|
|
53845
|
+
});
|
|
53846
|
+
if (!fwd.ok) {
|
|
53847
|
+
throw new ClawdError(ERROR_CODES.INTERNAL, `deliver to peer failed: ${fwd.error ?? "unknown"}`);
|
|
53848
|
+
}
|
|
53849
|
+
const message = manager.postMessage({
|
|
53850
|
+
peerDeviceId: args.peerDeviceId,
|
|
53851
|
+
senderDeviceId: d.ownerPrincipalId,
|
|
53852
|
+
text: args.text,
|
|
53853
|
+
id,
|
|
53854
|
+
createdAt,
|
|
53855
|
+
origin
|
|
53856
|
+
});
|
|
53857
|
+
return { response: { type: "inbox:sendDm:ok", message } };
|
|
53858
|
+
};
|
|
53755
53859
|
return {
|
|
53756
53860
|
"inbox:postMessage": postMessage,
|
|
53861
|
+
"inbox:sendDm": sendDm,
|
|
53757
53862
|
"inbox:list": list,
|
|
53758
53863
|
"inbox:markRead": markRead
|
|
53759
53864
|
};
|
|
@@ -53980,7 +54085,7 @@ function buildDeviceHandlers(deps) {
|
|
|
53980
54085
|
}
|
|
53981
54086
|
|
|
53982
54087
|
// src/handlers/meta.ts
|
|
53983
|
-
var
|
|
54088
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
53984
54089
|
init_protocol();
|
|
53985
54090
|
|
|
53986
54091
|
// src/version.ts
|
|
@@ -54012,7 +54117,7 @@ function buildReadyFrame(deps, client) {
|
|
|
54012
54117
|
return {
|
|
54013
54118
|
version,
|
|
54014
54119
|
protocolVersion: PROTOCOL_VERSION,
|
|
54015
|
-
hostname:
|
|
54120
|
+
hostname: import_node_os16.default.hostname(),
|
|
54016
54121
|
os: process.platform,
|
|
54017
54122
|
tools,
|
|
54018
54123
|
runningSessions: info.runningSessions,
|
|
@@ -54382,15 +54487,15 @@ function computePublishCheck(args) {
|
|
|
54382
54487
|
// src/extension/install-flow.ts
|
|
54383
54488
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
54384
54489
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
54385
|
-
var
|
|
54490
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
54386
54491
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
54387
54492
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
54388
54493
|
|
|
54389
54494
|
// src/extension/paths.ts
|
|
54390
|
-
var
|
|
54495
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
54391
54496
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
54392
54497
|
function clawdHomeRoot(override) {
|
|
54393
|
-
return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(
|
|
54498
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os17.default.homedir(), ".clawd");
|
|
54394
54499
|
}
|
|
54395
54500
|
function extensionsRoot(override) {
|
|
54396
54501
|
return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
|
|
@@ -54472,7 +54577,7 @@ async function installFromChannel(args, deps) {
|
|
|
54472
54577
|
);
|
|
54473
54578
|
}
|
|
54474
54579
|
const stage = await import_promises6.default.mkdtemp(
|
|
54475
|
-
import_node_path43.default.join(
|
|
54580
|
+
import_node_path43.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
54476
54581
|
);
|
|
54477
54582
|
try {
|
|
54478
54583
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
@@ -54503,7 +54608,7 @@ async function installFromChannel(args, deps) {
|
|
|
54503
54608
|
// src/extension/update-flow.ts
|
|
54504
54609
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
54505
54610
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
54506
|
-
var
|
|
54611
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
54507
54612
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
54508
54613
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
54509
54614
|
var UpdateError = class extends Error {
|
|
@@ -54591,7 +54696,7 @@ async function updateFromChannel(args, deps) {
|
|
|
54591
54696
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
54592
54697
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
54593
54698
|
const stage = await import_promises7.default.mkdtemp(
|
|
54594
|
-
import_node_path44.default.join(
|
|
54699
|
+
import_node_path44.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
54595
54700
|
);
|
|
54596
54701
|
try {
|
|
54597
54702
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
@@ -54973,7 +55078,7 @@ function buildExtensionHandlers(deps) {
|
|
|
54973
55078
|
}
|
|
54974
55079
|
|
|
54975
55080
|
// src/app-builder/project-store.ts
|
|
54976
|
-
var
|
|
55081
|
+
var import_node_fs39 = require("fs");
|
|
54977
55082
|
var import_node_child_process11 = require("child_process");
|
|
54978
55083
|
var import_node_path46 = require("path");
|
|
54979
55084
|
init_protocol();
|
|
@@ -55001,7 +55106,7 @@ var ProjectStore = class {
|
|
|
55001
55106
|
async list() {
|
|
55002
55107
|
let entries;
|
|
55003
55108
|
try {
|
|
55004
|
-
entries = await
|
|
55109
|
+
entries = await import_node_fs39.promises.readdir(this.projectsRoot());
|
|
55005
55110
|
} catch (err) {
|
|
55006
55111
|
if (err.code === "ENOENT") return [];
|
|
55007
55112
|
throw err;
|
|
@@ -55009,7 +55114,7 @@ var ProjectStore = class {
|
|
|
55009
55114
|
const out = [];
|
|
55010
55115
|
for (const name of entries) {
|
|
55011
55116
|
try {
|
|
55012
|
-
const raw = await
|
|
55117
|
+
const raw = await import_node_fs39.promises.readFile(this.metaPath(name), "utf8");
|
|
55013
55118
|
const json = JSON.parse(raw);
|
|
55014
55119
|
let migrated = false;
|
|
55015
55120
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -55020,7 +55125,7 @@ var ProjectStore = class {
|
|
|
55020
55125
|
if (parsed.success) {
|
|
55021
55126
|
out.push(parsed.data);
|
|
55022
55127
|
if (migrated) {
|
|
55023
|
-
void
|
|
55128
|
+
void import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
55024
55129
|
});
|
|
55025
55130
|
}
|
|
55026
55131
|
}
|
|
@@ -55064,8 +55169,8 @@ var ProjectStore = class {
|
|
|
55064
55169
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
55065
55170
|
}
|
|
55066
55171
|
const dir = this.projectDir(name);
|
|
55067
|
-
await
|
|
55068
|
-
await
|
|
55172
|
+
await import_node_fs39.promises.mkdir(dir, { recursive: true });
|
|
55173
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
55069
55174
|
return meta;
|
|
55070
55175
|
}
|
|
55071
55176
|
/**
|
|
@@ -55108,7 +55213,7 @@ var ProjectStore = class {
|
|
|
55108
55213
|
}
|
|
55109
55214
|
async delete(name) {
|
|
55110
55215
|
const dir = this.projectDir(name);
|
|
55111
|
-
await
|
|
55216
|
+
await import_node_fs39.promises.rm(dir, { recursive: true, force: true });
|
|
55112
55217
|
}
|
|
55113
55218
|
async updatePort(name, newPort) {
|
|
55114
55219
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -55124,7 +55229,7 @@ var ProjectStore = class {
|
|
|
55124
55229
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
55125
55230
|
}
|
|
55126
55231
|
const updated = { ...target, port: newPort };
|
|
55127
|
-
await
|
|
55232
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
55128
55233
|
return updated;
|
|
55129
55234
|
}
|
|
55130
55235
|
/**
|
|
@@ -55141,7 +55246,7 @@ var ProjectStore = class {
|
|
|
55141
55246
|
if (!validated.success) {
|
|
55142
55247
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
55143
55248
|
}
|
|
55144
|
-
await
|
|
55249
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
55145
55250
|
return validated.data;
|
|
55146
55251
|
}
|
|
55147
55252
|
/**
|
|
@@ -55162,7 +55267,7 @@ var ProjectStore = class {
|
|
|
55162
55267
|
if (!validated.success) {
|
|
55163
55268
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
55164
55269
|
}
|
|
55165
|
-
await
|
|
55270
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
55166
55271
|
return validated.data;
|
|
55167
55272
|
}
|
|
55168
55273
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -55177,7 +55282,7 @@ var ProjectStore = class {
|
|
|
55177
55282
|
if (!validated.success) {
|
|
55178
55283
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
55179
55284
|
}
|
|
55180
|
-
await
|
|
55285
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
55181
55286
|
return validated.data;
|
|
55182
55287
|
}
|
|
55183
55288
|
};
|
|
@@ -55298,7 +55403,7 @@ var PublishJobRegistry = class {
|
|
|
55298
55403
|
|
|
55299
55404
|
// src/app-builder/publish-job-runner.ts
|
|
55300
55405
|
var import_node_child_process13 = require("child_process");
|
|
55301
|
-
var
|
|
55406
|
+
var import_node_fs40 = require("fs");
|
|
55302
55407
|
var import_node_path47 = require("path");
|
|
55303
55408
|
|
|
55304
55409
|
// src/app-builder/publish-stage-parser.ts
|
|
@@ -55334,7 +55439,7 @@ async function startPublishJob(deps, args) {
|
|
|
55334
55439
|
const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
|
|
55335
55440
|
let logStream = null;
|
|
55336
55441
|
try {
|
|
55337
|
-
logStream = (0,
|
|
55442
|
+
logStream = (0, import_node_fs40.createWriteStream)(logPath, { flags: "w" });
|
|
55338
55443
|
} catch {
|
|
55339
55444
|
logStream = null;
|
|
55340
55445
|
}
|
|
@@ -55592,7 +55697,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
55592
55697
|
// src/handlers/app-builder.ts
|
|
55593
55698
|
init_protocol();
|
|
55594
55699
|
var import_node_path48 = require("path");
|
|
55595
|
-
var
|
|
55700
|
+
var import_node_fs41 = require("fs");
|
|
55596
55701
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
55597
55702
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
55598
55703
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -55673,7 +55778,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
55673
55778
|
async function listAllUsersProjects() {
|
|
55674
55779
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
55675
55780
|
const getStore = deps.getStore;
|
|
55676
|
-
const userIds = await
|
|
55781
|
+
const userIds = await import_node_fs41.promises.readdir(deps.usersRoot).catch(() => []);
|
|
55677
55782
|
const perUser = await Promise.all(
|
|
55678
55783
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
55679
55784
|
);
|
|
@@ -56224,6 +56329,7 @@ async function uninstall(deps) {
|
|
|
56224
56329
|
}
|
|
56225
56330
|
|
|
56226
56331
|
// src/handlers/index.ts
|
|
56332
|
+
var import_node_crypto17 = require("crypto");
|
|
56227
56333
|
function buildMethodHandlers(deps) {
|
|
56228
56334
|
return {
|
|
56229
56335
|
...buildSessionHandlers({
|
|
@@ -56248,7 +56354,18 @@ function buildMethodHandlers(deps) {
|
|
|
56248
56354
|
manager: deps.capabilityManager
|
|
56249
56355
|
}),
|
|
56250
56356
|
...buildInboxHandlers({
|
|
56251
|
-
manager: deps.inboxManager
|
|
56357
|
+
manager: deps.inboxManager,
|
|
56358
|
+
sendDmDeps: {
|
|
56359
|
+
ownerPrincipalId: deps.ownerPrincipalId,
|
|
56360
|
+
getSessionScope: deps.getSessionScope,
|
|
56361
|
+
getContact: (deviceId) => {
|
|
56362
|
+
const c = deps.contactStore.get(deviceId);
|
|
56363
|
+
return c ? { deviceId: c.deviceId, remoteUrl: c.remoteUrl, connectToken: c.connectToken } : null;
|
|
56364
|
+
},
|
|
56365
|
+
genId: () => (0, import_node_crypto17.randomUUID)(),
|
|
56366
|
+
now: () => Date.now(),
|
|
56367
|
+
forwardInboxPostToPeer
|
|
56368
|
+
}
|
|
56252
56369
|
}),
|
|
56253
56370
|
...buildContactHandlers({
|
|
56254
56371
|
store: deps.contactStore,
|
|
@@ -57136,7 +57253,7 @@ async function startDaemon(config) {
|
|
|
57136
57253
|
},
|
|
57137
57254
|
source: "daemon",
|
|
57138
57255
|
sampling: logShippingCfg.sampling,
|
|
57139
|
-
homeDir:
|
|
57256
|
+
homeDir: import_node_os20.default.homedir()
|
|
57140
57257
|
});
|
|
57141
57258
|
const logger = createLogger({
|
|
57142
57259
|
level: config.logLevel,
|
|
@@ -57308,7 +57425,7 @@ async function startDaemon(config) {
|
|
|
57308
57425
|
import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
57309
57426
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
57310
57427
|
];
|
|
57311
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
57428
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57312
57429
|
let dispatchMcpConfigPath2;
|
|
57313
57430
|
if (dispatchServerScriptPath) {
|
|
57314
57431
|
const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
@@ -57331,7 +57448,7 @@ async function startDaemon(config) {
|
|
|
57331
57448
|
import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
|
|
57332
57449
|
import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
57333
57450
|
];
|
|
57334
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
57451
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57335
57452
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
57336
57453
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
57337
57454
|
let ticketMcpConfigPath2;
|
|
@@ -57360,7 +57477,7 @@ async function startDaemon(config) {
|
|
|
57360
57477
|
import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
|
|
57361
57478
|
import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
57362
57479
|
];
|
|
57363
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
57480
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57364
57481
|
let shiftMcpConfigPath2;
|
|
57365
57482
|
if (shiftServerScriptPath) {
|
|
57366
57483
|
const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
|
|
@@ -57380,6 +57497,27 @@ async function startDaemon(config) {
|
|
|
57380
57497
|
{ tried: shiftServerCandidates }
|
|
57381
57498
|
);
|
|
57382
57499
|
}
|
|
57500
|
+
const inboxServerCandidates = [
|
|
57501
|
+
import_node_path54.default.join(here, "inbox", "mcp-server.cjs"),
|
|
57502
|
+
import_node_path54.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
57503
|
+
];
|
|
57504
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57505
|
+
let inboxMcpConfigPath2;
|
|
57506
|
+
if (inboxServerScriptPath) {
|
|
57507
|
+
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
57508
|
+
dataDir: config.dataDir,
|
|
57509
|
+
serverScriptPath: inboxServerScriptPath
|
|
57510
|
+
});
|
|
57511
|
+
logger.info("inbox.mcp.json written", {
|
|
57512
|
+
path: inboxMcpConfigPath2,
|
|
57513
|
+
server: inboxServerScriptPath
|
|
57514
|
+
});
|
|
57515
|
+
} else {
|
|
57516
|
+
logger.warn(
|
|
57517
|
+
"inbox-mcp-server.cjs not found; sendDm MCP tool disabled (dev tsx \u6A21\u5F0F\u4E0B\u9700\u5148\u8DD1\u8FC7 build)",
|
|
57518
|
+
{ tried: inboxServerCandidates }
|
|
57519
|
+
);
|
|
57520
|
+
}
|
|
57383
57521
|
const shiftStore = createShiftStore({
|
|
57384
57522
|
filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
|
|
57385
57523
|
ownerIdProvider: () => ownerPrincipalId,
|
|
@@ -57421,6 +57559,8 @@ async function startDaemon(config) {
|
|
|
57421
57559
|
// shift v1:所有 persona session 都挂 shift.mcp.json(不做 persona gating)。
|
|
57422
57560
|
// 缺省 = shift-mcp-server.cjs 没 build 出来,cc 看不到 shift tool 但 scheduler 仍跑。
|
|
57423
57561
|
shiftMcpConfigPath: shiftMcpConfigPath2,
|
|
57562
|
+
// sendDm MCP tool:所有 persona session 都挂 inbox.mcp.json(无 gating)。
|
|
57563
|
+
inboxMcpConfigPath: inboxMcpConfigPath2,
|
|
57424
57564
|
broadcastFrame: (frame, target) => {
|
|
57425
57565
|
if (target === "all") {
|
|
57426
57566
|
transport?.broadcastAll(frame);
|
|
@@ -57443,7 +57583,7 @@ async function startDaemon(config) {
|
|
|
57443
57583
|
const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
|
|
57444
57584
|
let size = 0;
|
|
57445
57585
|
try {
|
|
57446
|
-
size =
|
|
57586
|
+
size = import_node_fs42.default.statSync(absPath).size;
|
|
57447
57587
|
} catch (err) {
|
|
57448
57588
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
57449
57589
|
sessionId: input.sessionId,
|
|
@@ -57665,6 +57805,8 @@ async function startDaemon(config) {
|
|
|
57665
57805
|
inboxStore,
|
|
57666
57806
|
// 联系人列表 store(device:connect / 自动反向落同一 store)
|
|
57667
57807
|
contactStore,
|
|
57808
|
+
// inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
|
|
57809
|
+
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
57668
57810
|
// contact:removed broadcast;复用 capability:tokenIssued 同款通路
|
|
57669
57811
|
broadcastToOwners: (frame) => wsServer?.broadcastToOwners(frame),
|
|
57670
57812
|
// extension runtime (v1: local-mode only). Instance owned by daemon top
|
|
@@ -57800,7 +57942,7 @@ async function startDaemon(config) {
|
|
|
57800
57942
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
57801
57943
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
57802
57944
|
sourceJsonlPath = import_node_path54.default.join(
|
|
57803
|
-
|
|
57945
|
+
import_node_os20.default.homedir(),
|
|
57804
57946
|
".claude",
|
|
57805
57947
|
"projects",
|
|
57806
57948
|
cwdToHashDir(sourceFile.cwd),
|
|
@@ -58114,7 +58256,7 @@ ${bar}
|
|
|
58114
58256
|
`);
|
|
58115
58257
|
try {
|
|
58116
58258
|
const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
|
|
58117
|
-
|
|
58259
|
+
import_node_fs42.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
58118
58260
|
} catch {
|
|
58119
58261
|
}
|
|
58120
58262
|
} catch (err) {
|
|
@@ -58188,7 +58330,7 @@ ${bar}
|
|
|
58188
58330
|
function migrateDropPersonsDir(dataDir) {
|
|
58189
58331
|
const dir = import_node_path54.default.join(dataDir, "persons");
|
|
58190
58332
|
try {
|
|
58191
|
-
|
|
58333
|
+
import_node_fs42.default.rmSync(dir, { recursive: true, force: true });
|
|
58192
58334
|
} catch {
|
|
58193
58335
|
}
|
|
58194
58336
|
}
|