@clawos-dev/clawd 0.2.190 → 0.2.191-beta.382.4a6606c
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 +687 -507
- 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);
|
|
@@ -12399,9 +12391,8 @@ var init_claude = __esm({
|
|
|
12399
12391
|
};
|
|
12400
12392
|
CLAUDE_MODELS = [
|
|
12401
12393
|
{ id: "", label: "Default", description: "CLI default model", contextWindowSize: 2e5, default: true },
|
|
12402
|
-
{ id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
|
|
12403
|
-
{ id: "fable", label: "Fable", contextWindowSize: 2e5 },
|
|
12404
12394
|
{ id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 2e5 },
|
|
12395
|
+
{ id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
|
|
12405
12396
|
{ id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 2e5 }
|
|
12406
12397
|
];
|
|
12407
12398
|
CLAUDE_PERMISSION_MODES = [
|
|
@@ -40113,8 +40104,8 @@ function startRunCaseRecorder(opts) {
|
|
|
40113
40104
|
});
|
|
40114
40105
|
const ensureStream = () => {
|
|
40115
40106
|
if (stream) return stream;
|
|
40116
|
-
|
|
40117
|
-
stream =
|
|
40107
|
+
import_node_fs43.default.mkdirSync(dir, { recursive: true });
|
|
40108
|
+
stream = import_node_fs43.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
40118
40109
|
stream.on("close", () => closedResolve());
|
|
40119
40110
|
return stream;
|
|
40120
40111
|
};
|
|
@@ -40139,11 +40130,11 @@ function startRunCaseRecorder(opts) {
|
|
|
40139
40130
|
};
|
|
40140
40131
|
return { tap, close, closed };
|
|
40141
40132
|
}
|
|
40142
|
-
var
|
|
40133
|
+
var import_node_fs43, import_node_path55;
|
|
40143
40134
|
var init_recorder = __esm({
|
|
40144
40135
|
"src/run-case/recorder.ts"() {
|
|
40145
40136
|
"use strict";
|
|
40146
|
-
|
|
40137
|
+
import_node_fs43 = __toESM(require("fs"), 1);
|
|
40147
40138
|
import_node_path55 = __toESM(require("path"), 1);
|
|
40148
40139
|
}
|
|
40149
40140
|
});
|
|
@@ -40187,7 +40178,7 @@ var init_wire = __esm({
|
|
|
40187
40178
|
// src/run-case/controller.ts
|
|
40188
40179
|
async function runController(opts) {
|
|
40189
40180
|
const now = opts.now ?? Date.now;
|
|
40190
|
-
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-"));
|
|
40191
40182
|
const ownsCwd = opts.cwd === void 0;
|
|
40192
40183
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40193
40184
|
const spawnCtx = { cwd };
|
|
@@ -40348,18 +40339,18 @@ async function runController(opts) {
|
|
|
40348
40339
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
40349
40340
|
if (ownsCwd) {
|
|
40350
40341
|
try {
|
|
40351
|
-
(0,
|
|
40342
|
+
(0, import_node_fs44.rmSync)(cwd, { recursive: true, force: true });
|
|
40352
40343
|
} catch {
|
|
40353
40344
|
}
|
|
40354
40345
|
}
|
|
40355
40346
|
return exitCode ?? 0;
|
|
40356
40347
|
}
|
|
40357
|
-
var
|
|
40348
|
+
var import_node_fs44, import_node_os21, import_node_path56;
|
|
40358
40349
|
var init_controller = __esm({
|
|
40359
40350
|
"src/run-case/controller.ts"() {
|
|
40360
40351
|
"use strict";
|
|
40361
|
-
|
|
40362
|
-
|
|
40352
|
+
import_node_fs44 = require("fs");
|
|
40353
|
+
import_node_os21 = __toESM(require("os"), 1);
|
|
40363
40354
|
import_node_path56 = __toESM(require("path"), 1);
|
|
40364
40355
|
init_claude();
|
|
40365
40356
|
init_stdout_splitter();
|
|
@@ -40623,8 +40614,8 @@ Env (advanced):
|
|
|
40623
40614
|
|
|
40624
40615
|
// src/index.ts
|
|
40625
40616
|
var import_node_path54 = __toESM(require("path"), 1);
|
|
40626
|
-
var
|
|
40627
|
-
var
|
|
40617
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
40618
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
40628
40619
|
|
|
40629
40620
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
40630
40621
|
var byteToHex = [];
|
|
@@ -41241,9 +41232,9 @@ var SessionStoreFactory = class {
|
|
|
41241
41232
|
};
|
|
41242
41233
|
|
|
41243
41234
|
// src/session/manager.ts
|
|
41244
|
-
var
|
|
41245
|
-
var
|
|
41246
|
-
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);
|
|
41247
41238
|
init_protocol();
|
|
41248
41239
|
|
|
41249
41240
|
// src/tools/guest-settings.ts
|
|
@@ -41341,10 +41332,6 @@ function escapeAttr(v2) {
|
|
|
41341
41332
|
return v2.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
41342
41333
|
}
|
|
41343
41334
|
|
|
41344
|
-
// src/session/runner.ts
|
|
41345
|
-
var import_node_os4 = __toESM(require("os"), 1);
|
|
41346
|
-
var import_node_path6 = __toESM(require("path"), 1);
|
|
41347
|
-
|
|
41348
41335
|
// src/session/reducer.ts
|
|
41349
41336
|
init_runtime();
|
|
41350
41337
|
|
|
@@ -41431,7 +41418,7 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
|
|
|
41431
41418
|
// src/dispatch/system-prompt.ts
|
|
41432
41419
|
var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
|
|
41433
41420
|
|
|
41434
|
-
\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
|
|
41435
41422
|
|
|
41436
41423
|
- \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
|
|
41437
41424
|
- \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
|
|
@@ -41483,7 +41470,7 @@ function cloneState(s) {
|
|
|
41483
41470
|
pendingSend: s.pendingSend.slice()
|
|
41484
41471
|
};
|
|
41485
41472
|
}
|
|
41486
|
-
var IDLE_KILL_DELAY_MS =
|
|
41473
|
+
var IDLE_KILL_DELAY_MS = 6e4;
|
|
41487
41474
|
function tryFlushPending(state, deps) {
|
|
41488
41475
|
if (!state.readyForSend || state.pendingSend.length === 0) return [];
|
|
41489
41476
|
const text = state.pendingSend.shift();
|
|
@@ -41548,6 +41535,7 @@ function buildSpawnContext(state, deps) {
|
|
|
41548
41535
|
const ticketMcpConfigPathRaw = deps.getTicketMcpConfigPath?.() ?? null;
|
|
41549
41536
|
const ticketMcpConfigPath2 = ticketMcpConfigPathRaw && file.ownerPersonaId === "persona-ticket-manager" ? ticketMcpConfigPathRaw : null;
|
|
41550
41537
|
const shiftMcpConfigPath2 = deps.getShiftMcpConfigPath?.() ?? null;
|
|
41538
|
+
const inboxMcpConfigPath2 = deps.getInboxMcpConfigPath?.() ?? null;
|
|
41551
41539
|
const ctx = {
|
|
41552
41540
|
cwd: file.cwd,
|
|
41553
41541
|
toolSessionId: file.toolSessionId,
|
|
@@ -41563,6 +41551,7 @@ function buildSpawnContext(state, deps) {
|
|
|
41563
41551
|
dispatchMcpConfigPath: dispatchMcpConfigPath2 ?? void 0,
|
|
41564
41552
|
ticketMcpConfigPath: ticketMcpConfigPath2 ?? void 0,
|
|
41565
41553
|
shiftMcpConfigPath: shiftMcpConfigPath2 ?? void 0,
|
|
41554
|
+
inboxMcpConfigPath: inboxMcpConfigPath2 ?? void 0,
|
|
41566
41555
|
// shift v1:把 SessionFile.ownerPersonaId 透传到 SpawnContext;buildSpawnArgs 等下游
|
|
41567
41556
|
// 不直接读这个字段(只读 env),但保留显式字段方便 daemon 内部诊断/日志。
|
|
41568
41557
|
personaId
|
|
@@ -42152,18 +42141,6 @@ function reduceSession(state, input, deps) {
|
|
|
42152
42141
|
if (state.status !== "running-idle") {
|
|
42153
42142
|
return { state, effects: [] };
|
|
42154
42143
|
}
|
|
42155
|
-
if (input.subagentActive) {
|
|
42156
|
-
return {
|
|
42157
|
-
state,
|
|
42158
|
-
effects: [
|
|
42159
|
-
{
|
|
42160
|
-
kind: "schedule-idle-kill",
|
|
42161
|
-
sessionId: state.file.sessionId,
|
|
42162
|
-
ms: IDLE_KILL_DELAY_MS
|
|
42163
|
-
}
|
|
42164
|
-
]
|
|
42165
|
-
};
|
|
42166
|
-
}
|
|
42167
42144
|
const next = cloneState(state);
|
|
42168
42145
|
next.status = "stopping";
|
|
42169
42146
|
return {
|
|
@@ -42220,11 +42197,10 @@ function reduceSession(state, input, deps) {
|
|
|
42220
42197
|
// src/session/runner.ts
|
|
42221
42198
|
init_stdout_splitter();
|
|
42222
42199
|
init_permission_stdio();
|
|
42223
|
-
init_claude_history();
|
|
42224
42200
|
|
|
42225
42201
|
// src/ipc-recorder.ts
|
|
42226
|
-
var
|
|
42227
|
-
var
|
|
42202
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
42203
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
42228
42204
|
function tsForFilename(ms) {
|
|
42229
42205
|
return new Date(ms).toISOString().replace(/[:.]/g, "-");
|
|
42230
42206
|
}
|
|
@@ -42235,8 +42211,8 @@ function startRecorder(opts) {
|
|
|
42235
42211
|
return null;
|
|
42236
42212
|
}
|
|
42237
42213
|
const now = opts.now ?? Date.now;
|
|
42238
|
-
const dir =
|
|
42239
|
-
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`);
|
|
42240
42216
|
let stream = null;
|
|
42241
42217
|
let closedResolve;
|
|
42242
42218
|
const closed = new Promise((resolve6) => {
|
|
@@ -42245,8 +42221,8 @@ function startRecorder(opts) {
|
|
|
42245
42221
|
let exited = false;
|
|
42246
42222
|
const ensureStream = () => {
|
|
42247
42223
|
if (stream) return stream;
|
|
42248
|
-
|
|
42249
|
-
stream =
|
|
42224
|
+
import_node_fs4.default.mkdirSync(dir, { recursive: true });
|
|
42225
|
+
stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
|
|
42250
42226
|
stream.on("close", () => closedResolve());
|
|
42251
42227
|
return stream;
|
|
42252
42228
|
};
|
|
@@ -42291,7 +42267,6 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
|
|
|
42291
42267
|
return JSON.stringify(payload) + "\n";
|
|
42292
42268
|
}
|
|
42293
42269
|
var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
|
|
42294
|
-
var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
|
|
42295
42270
|
var SessionRunner = class {
|
|
42296
42271
|
constructor(initial, hooks) {
|
|
42297
42272
|
this.hooks = hooks;
|
|
@@ -42349,6 +42324,7 @@ var SessionRunner = class {
|
|
|
42349
42324
|
// 见 reducer.buildSpawnContext 注 CLAWD_DISPATCH_ID env / 派生 SpawnContext.dispatchMcpConfigPath
|
|
42350
42325
|
getDispatchMcpConfigPath: this.hooks.getDispatchMcpConfigPath,
|
|
42351
42326
|
getShiftMcpConfigPath: this.hooks.getShiftMcpConfigPath,
|
|
42327
|
+
getInboxMcpConfigPath: this.hooks.getInboxMcpConfigPath,
|
|
42352
42328
|
// Ticket MCP:透传 ticket.mcp.json 路径闭包(reducer 内做 persona-ticket-manager gating)
|
|
42353
42329
|
getTicketMcpConfigPath: this.hooks.getTicketMcpConfigPath,
|
|
42354
42330
|
lookupDispatchByBSessionId: this.hooks.lookupDispatchByBSessionId,
|
|
@@ -42603,7 +42579,7 @@ var SessionRunner = class {
|
|
|
42603
42579
|
if (existing) clearTimeout(existing);
|
|
42604
42580
|
const timer = setTimeout(() => {
|
|
42605
42581
|
this.idleKillTimers.delete(effect.sessionId);
|
|
42606
|
-
this.input({ kind: "idle-kill-fired"
|
|
42582
|
+
this.input({ kind: "idle-kill-fired" });
|
|
42607
42583
|
}, effect.ms);
|
|
42608
42584
|
timer.unref?.();
|
|
42609
42585
|
this.idleKillTimers.set(effect.sessionId, timer);
|
|
@@ -42619,18 +42595,6 @@ var SessionRunner = class {
|
|
|
42619
42595
|
}
|
|
42620
42596
|
}
|
|
42621
42597
|
}
|
|
42622
|
-
// idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
|
|
42623
|
-
// 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
|
|
42624
|
-
// 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
|
|
42625
|
-
isSubagentActive() {
|
|
42626
|
-
const toolSessionId = this.state.file.toolSessionId;
|
|
42627
|
-
if (!toolSessionId) return false;
|
|
42628
|
-
const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
|
|
42629
|
-
const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
|
|
42630
|
-
if (mtime === null) return false;
|
|
42631
|
-
const now = (this.hooks.now ?? Date.now)();
|
|
42632
|
-
return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
|
|
42633
|
-
}
|
|
42634
42598
|
// 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
|
|
42635
42599
|
// 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
|
|
42636
42600
|
clearIdleKillTimers() {
|
|
@@ -42713,15 +42677,15 @@ function extractEditPath(input) {
|
|
|
42713
42677
|
}
|
|
42714
42678
|
|
|
42715
42679
|
// src/debug/pty-probe.ts
|
|
42716
|
-
var
|
|
42717
|
-
var
|
|
42680
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
42681
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
42718
42682
|
var PROBE_DIR = "/tmp/clawd-probe";
|
|
42719
|
-
var EVENTS_FILE =
|
|
42683
|
+
var EVENTS_FILE = import_node_path5.default.join(PROBE_DIR, "events.jsonl");
|
|
42720
42684
|
var inited = false;
|
|
42721
42685
|
function ensureDir() {
|
|
42722
42686
|
if (inited) return true;
|
|
42723
42687
|
try {
|
|
42724
|
-
|
|
42688
|
+
import_node_fs5.default.mkdirSync(PROBE_DIR, { recursive: true });
|
|
42725
42689
|
inited = true;
|
|
42726
42690
|
return true;
|
|
42727
42691
|
} catch {
|
|
@@ -42732,15 +42696,15 @@ function probeEvent(event, data = {}) {
|
|
|
42732
42696
|
try {
|
|
42733
42697
|
if (!ensureDir()) return;
|
|
42734
42698
|
const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
|
|
42735
|
-
|
|
42699
|
+
import_node_fs5.default.appendFileSync(EVENTS_FILE, line);
|
|
42736
42700
|
} catch {
|
|
42737
42701
|
}
|
|
42738
42702
|
}
|
|
42739
42703
|
function probeDumpReplay(sessionId, payload) {
|
|
42740
42704
|
try {
|
|
42741
42705
|
if (!ensureDir()) return "";
|
|
42742
|
-
const file =
|
|
42743
|
-
|
|
42706
|
+
const file = import_node_path5.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
|
|
42707
|
+
import_node_fs5.default.writeFileSync(file, payload, "utf8");
|
|
42744
42708
|
return file;
|
|
42745
42709
|
} catch {
|
|
42746
42710
|
return "";
|
|
@@ -42847,7 +42811,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
|
|
|
42847
42811
|
`derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
|
|
42848
42812
|
);
|
|
42849
42813
|
}
|
|
42850
|
-
return
|
|
42814
|
+
return import_node_path6.default.join(personaRoot, safeFileName(personaId));
|
|
42851
42815
|
}
|
|
42852
42816
|
function makeInitialState(file, subSessionMeta) {
|
|
42853
42817
|
return {
|
|
@@ -42972,10 +42936,10 @@ var SessionManager = class {
|
|
|
42972
42936
|
// <dataDir>/sessions/ 列子目录 (排除 'default').
|
|
42973
42937
|
listPersonaIdsOnDisk() {
|
|
42974
42938
|
if (!this.deps.dataDir) return [];
|
|
42975
|
-
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");
|
|
42976
42940
|
let entries;
|
|
42977
42941
|
try {
|
|
42978
|
-
entries =
|
|
42942
|
+
entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
|
|
42979
42943
|
} catch (err) {
|
|
42980
42944
|
const code = err?.code;
|
|
42981
42945
|
if (code === "ENOENT") return [];
|
|
@@ -42988,7 +42952,7 @@ var SessionManager = class {
|
|
|
42988
42952
|
// 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
|
|
42989
42953
|
listGuestCapIdsForPersona(personaId) {
|
|
42990
42954
|
if (!this.deps.dataDir || !this.deps.storeFactory) return [];
|
|
42991
|
-
const root =
|
|
42955
|
+
const root = import_node_path6.default.join(
|
|
42992
42956
|
this.deps.dataDir,
|
|
42993
42957
|
"personas",
|
|
42994
42958
|
personaId,
|
|
@@ -42998,7 +42962,7 @@ var SessionManager = class {
|
|
|
42998
42962
|
);
|
|
42999
42963
|
let entries;
|
|
43000
42964
|
try {
|
|
43001
|
-
entries =
|
|
42965
|
+
entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
|
|
43002
42966
|
} catch (err) {
|
|
43003
42967
|
const code = err?.code;
|
|
43004
42968
|
if (code === "ENOENT") return [];
|
|
@@ -43117,7 +43081,7 @@ var SessionManager = class {
|
|
|
43117
43081
|
callerDisplayName
|
|
43118
43082
|
);
|
|
43119
43083
|
if (subSessionMeta?.userWorkDir) {
|
|
43120
|
-
|
|
43084
|
+
import_node_fs6.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
|
|
43121
43085
|
}
|
|
43122
43086
|
if (scope.kind === "persona" && scope.mode === "guest") {
|
|
43123
43087
|
if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
|
|
@@ -43128,8 +43092,8 @@ var SessionManager = class {
|
|
|
43128
43092
|
const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
|
|
43129
43093
|
const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
|
|
43130
43094
|
subSessionMeta.extraSettings = JSON.stringify(settings);
|
|
43131
|
-
const home =
|
|
43132
|
-
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;
|
|
43133
43097
|
const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
|
|
43134
43098
|
subSessionMeta.codexSandbox = {
|
|
43135
43099
|
writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
|
|
@@ -43163,6 +43127,7 @@ var SessionManager = class {
|
|
|
43163
43127
|
getDispatchMcpConfigPath: this.deps.dispatchMcpConfigPath ? () => this.deps.dispatchMcpConfigPath ?? null : void 0,
|
|
43164
43128
|
getTicketMcpConfigPath: this.deps.ticketMcpConfigPath ? () => this.deps.ticketMcpConfigPath ?? null : void 0,
|
|
43165
43129
|
getShiftMcpConfigPath: this.deps.shiftMcpConfigPath ? () => this.deps.shiftMcpConfigPath ?? null : void 0,
|
|
43130
|
+
getInboxMcpConfigPath: this.deps.inboxMcpConfigPath ? () => this.deps.inboxMcpConfigPath ?? null : void 0,
|
|
43166
43131
|
lookupDispatchByBSessionId: this.deps.personaDispatchManager ? (bSid) => this.deps.personaDispatchManager?.lookupDispatchByBSessionId(bSid) : void 0,
|
|
43167
43132
|
// file-sharing (spec §6 PR 3):闭包 scope + sessionId,runner 只暴露 tool/relPath/cwd
|
|
43168
43133
|
onFileEdit: attachmentGroup ? (input) => attachmentGroup.onFileEdit({
|
|
@@ -43281,7 +43246,7 @@ var SessionManager = class {
|
|
|
43281
43246
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
|
|
43282
43247
|
}
|
|
43283
43248
|
try {
|
|
43284
|
-
const stat =
|
|
43249
|
+
const stat = import_node_fs6.default.statSync(cwd);
|
|
43285
43250
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43286
43251
|
} catch {
|
|
43287
43252
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
|
|
@@ -43812,7 +43777,7 @@ var SessionManager = class {
|
|
|
43812
43777
|
*/
|
|
43813
43778
|
createForScope(args) {
|
|
43814
43779
|
try {
|
|
43815
|
-
const stat =
|
|
43780
|
+
const stat = import_node_fs6.default.statSync(args.cwd);
|
|
43816
43781
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43817
43782
|
} catch {
|
|
43818
43783
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -44028,7 +43993,7 @@ var SessionManager = class {
|
|
|
44028
43993
|
personaId: args.targetPersona,
|
|
44029
43994
|
mode: "owner"
|
|
44030
43995
|
};
|
|
44031
|
-
const cwd =
|
|
43996
|
+
const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44032
43997
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44033
43998
|
const file = {
|
|
44034
43999
|
sessionId,
|
|
@@ -44093,7 +44058,7 @@ var SessionManager = class {
|
|
|
44093
44058
|
personaId: args.targetPersona,
|
|
44094
44059
|
mode: "owner"
|
|
44095
44060
|
};
|
|
44096
|
-
const cwd =
|
|
44061
|
+
const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44097
44062
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44098
44063
|
const file = {
|
|
44099
44064
|
sessionId,
|
|
@@ -44575,28 +44540,28 @@ var SessionManager = class {
|
|
|
44575
44540
|
};
|
|
44576
44541
|
|
|
44577
44542
|
// src/persona/store.ts
|
|
44578
|
-
var
|
|
44579
|
-
var
|
|
44543
|
+
var fs7 = __toESM(require("fs"), 1);
|
|
44544
|
+
var path9 = __toESM(require("path"), 1);
|
|
44580
44545
|
init_protocol();
|
|
44581
44546
|
var PersonaStore = class {
|
|
44582
44547
|
constructor(root) {
|
|
44583
44548
|
this.root = root;
|
|
44584
|
-
|
|
44549
|
+
fs7.mkdirSync(root, { recursive: true });
|
|
44585
44550
|
}
|
|
44586
44551
|
root;
|
|
44587
44552
|
personaDir(personaId) {
|
|
44588
|
-
return
|
|
44553
|
+
return path9.join(this.root, safeFileName(personaId));
|
|
44589
44554
|
}
|
|
44590
44555
|
metaPath(personaId) {
|
|
44591
|
-
return
|
|
44556
|
+
return path9.join(this.personaDir(personaId), ".clawd", "persona.json");
|
|
44592
44557
|
}
|
|
44593
44558
|
claudeMdPath(personaId) {
|
|
44594
|
-
return
|
|
44559
|
+
return path9.join(this.personaDir(personaId), "CLAUDE.md");
|
|
44595
44560
|
}
|
|
44596
44561
|
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
44597
44562
|
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
44598
44563
|
agentsMdPath(personaId) {
|
|
44599
|
-
return
|
|
44564
|
+
return path9.join(this.personaDir(personaId), "AGENTS.md");
|
|
44600
44565
|
}
|
|
44601
44566
|
/**
|
|
44602
44567
|
* persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
@@ -44605,11 +44570,11 @@ var PersonaStore = class {
|
|
|
44605
44570
|
* spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
|
|
44606
44571
|
*/
|
|
44607
44572
|
sandboxSettingsPath(personaId) {
|
|
44608
|
-
return
|
|
44573
|
+
return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
|
|
44609
44574
|
}
|
|
44610
44575
|
write(persona, personality) {
|
|
44611
44576
|
const dir = this.personaDir(persona.personaId);
|
|
44612
|
-
|
|
44577
|
+
fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
|
|
44613
44578
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
44614
44579
|
this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
|
|
44615
44580
|
this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
|
|
@@ -44628,9 +44593,9 @@ var PersonaStore = class {
|
|
|
44628
44593
|
ensureAgentsMirror(personaId) {
|
|
44629
44594
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44630
44595
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44631
|
-
if (!
|
|
44632
|
-
if (
|
|
44633
|
-
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"));
|
|
44634
44599
|
return true;
|
|
44635
44600
|
}
|
|
44636
44601
|
/**
|
|
@@ -44654,22 +44619,22 @@ var PersonaStore = class {
|
|
|
44654
44619
|
return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
|
|
44655
44620
|
}
|
|
44656
44621
|
codexSandboxSettingsPath(personaId) {
|
|
44657
|
-
return
|
|
44622
|
+
return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
|
|
44658
44623
|
}
|
|
44659
44624
|
/** 读 codex-sandbox.json;不存在/损坏 → null。 */
|
|
44660
44625
|
readCodexSandboxSettings(personaId) {
|
|
44661
44626
|
const p2 = this.codexSandboxSettingsPath(personaId);
|
|
44662
|
-
if (!
|
|
44627
|
+
if (!fs7.existsSync(p2)) return null;
|
|
44663
44628
|
try {
|
|
44664
|
-
return CodexSandboxSettingsSchema.parse(JSON.parse(
|
|
44629
|
+
return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
|
|
44665
44630
|
} catch {
|
|
44666
44631
|
return null;
|
|
44667
44632
|
}
|
|
44668
44633
|
}
|
|
44669
44634
|
/** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
|
|
44670
44635
|
writeCodexSandboxSettings(personaId, settings) {
|
|
44671
|
-
const dir =
|
|
44672
|
-
|
|
44636
|
+
const dir = path9.join(this.personaDir(personaId), ".clawd");
|
|
44637
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
44673
44638
|
this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
|
|
44674
44639
|
}
|
|
44675
44640
|
writeMeta(persona) {
|
|
@@ -44677,8 +44642,8 @@ var PersonaStore = class {
|
|
|
44677
44642
|
}
|
|
44678
44643
|
read(personaId) {
|
|
44679
44644
|
const p2 = this.metaPath(personaId);
|
|
44680
|
-
if (!
|
|
44681
|
-
const raw = JSON.parse(
|
|
44645
|
+
if (!fs7.existsSync(p2)) return null;
|
|
44646
|
+
const raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
|
|
44682
44647
|
if (raw && typeof raw === "object" && "tokenMap" in raw) {
|
|
44683
44648
|
delete raw.tokenMap;
|
|
44684
44649
|
this.atomicWrite(p2, JSON.stringify(raw, null, 2));
|
|
@@ -44686,13 +44651,13 @@ var PersonaStore = class {
|
|
|
44686
44651
|
return PersonaFileSchema.parse(raw);
|
|
44687
44652
|
}
|
|
44688
44653
|
has(personaId) {
|
|
44689
|
-
return
|
|
44654
|
+
return fs7.existsSync(this.metaPath(personaId));
|
|
44690
44655
|
}
|
|
44691
44656
|
readPersonality(personaId) {
|
|
44692
44657
|
const claudeMd = this.claudeMdPath(personaId);
|
|
44693
|
-
if (
|
|
44658
|
+
if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
|
|
44694
44659
|
const agentsMd = this.agentsMdPath(personaId);
|
|
44695
|
-
if (
|
|
44660
|
+
if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
|
|
44696
44661
|
return null;
|
|
44697
44662
|
}
|
|
44698
44663
|
/**
|
|
@@ -44701,23 +44666,23 @@ var PersonaStore = class {
|
|
|
44701
44666
|
*/
|
|
44702
44667
|
readSandboxSettings(personaId) {
|
|
44703
44668
|
const p2 = this.sandboxSettingsPath(personaId);
|
|
44704
|
-
if (!
|
|
44669
|
+
if (!fs7.existsSync(p2)) return null;
|
|
44705
44670
|
try {
|
|
44706
|
-
return JSON.parse(
|
|
44671
|
+
return JSON.parse(fs7.readFileSync(p2, "utf8"));
|
|
44707
44672
|
} catch {
|
|
44708
44673
|
return null;
|
|
44709
44674
|
}
|
|
44710
44675
|
}
|
|
44711
44676
|
/** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
|
|
44712
44677
|
skillsDir(personaId) {
|
|
44713
|
-
return
|
|
44678
|
+
return path9.join(this.personaDir(personaId), ".claude", "skills");
|
|
44714
44679
|
}
|
|
44715
44680
|
/**
|
|
44716
44681
|
* Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
|
|
44717
44682
|
* 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
|
|
44718
44683
|
*/
|
|
44719
44684
|
claudeSettingsPath(personaId) {
|
|
44720
|
-
return
|
|
44685
|
+
return path9.join(this.personaDir(personaId), ".claude", "settings.json");
|
|
44721
44686
|
}
|
|
44722
44687
|
/**
|
|
44723
44688
|
* 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
|
|
@@ -44732,10 +44697,10 @@ var PersonaStore = class {
|
|
|
44732
44697
|
*/
|
|
44733
44698
|
readEnabledPlugins(personaId) {
|
|
44734
44699
|
const p2 = this.claudeSettingsPath(personaId);
|
|
44735
|
-
if (!
|
|
44700
|
+
if (!fs7.existsSync(p2)) return [];
|
|
44736
44701
|
let raw;
|
|
44737
44702
|
try {
|
|
44738
|
-
raw = JSON.parse(
|
|
44703
|
+
raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
|
|
44739
44704
|
} catch {
|
|
44740
44705
|
return [];
|
|
44741
44706
|
}
|
|
@@ -44749,22 +44714,22 @@ var PersonaStore = class {
|
|
|
44749
44714
|
return out;
|
|
44750
44715
|
}
|
|
44751
44716
|
list() {
|
|
44752
|
-
if (!
|
|
44753
|
-
return
|
|
44754
|
-
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"));
|
|
44755
44720
|
});
|
|
44756
44721
|
}
|
|
44757
44722
|
remove(personaId) {
|
|
44758
44723
|
const dir = this.personaDir(personaId);
|
|
44759
|
-
if (
|
|
44724
|
+
if (fs7.existsSync(dir)) fs7.rmSync(dir, { recursive: true, force: true });
|
|
44760
44725
|
}
|
|
44761
44726
|
personaDirPath(personaId) {
|
|
44762
44727
|
return this.personaDir(personaId);
|
|
44763
44728
|
}
|
|
44764
44729
|
atomicWrite(file, content) {
|
|
44765
44730
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
44766
|
-
|
|
44767
|
-
|
|
44731
|
+
fs7.writeFileSync(tmp, content, { mode: 384 });
|
|
44732
|
+
fs7.renameSync(tmp, file);
|
|
44768
44733
|
}
|
|
44769
44734
|
};
|
|
44770
44735
|
|
|
@@ -44810,9 +44775,9 @@ var PersonaRegistry = class {
|
|
|
44810
44775
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
44811
44776
|
|
|
44812
44777
|
// src/skills/scanner.ts
|
|
44813
|
-
var
|
|
44814
|
-
var
|
|
44815
|
-
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);
|
|
44816
44781
|
|
|
44817
44782
|
// src/skills/frontmatter.ts
|
|
44818
44783
|
var STRIP_QUOTES = /^["']|["']$/g;
|
|
@@ -44921,7 +44886,7 @@ function parseDescription(content) {
|
|
|
44921
44886
|
}
|
|
44922
44887
|
function isDirLikeSync(p2) {
|
|
44923
44888
|
try {
|
|
44924
|
-
return
|
|
44889
|
+
return import_node_fs7.default.statSync(p2).isDirectory();
|
|
44925
44890
|
} catch {
|
|
44926
44891
|
return false;
|
|
44927
44892
|
}
|
|
@@ -44929,19 +44894,19 @@ function isDirLikeSync(p2) {
|
|
|
44929
44894
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
44930
44895
|
let entries;
|
|
44931
44896
|
try {
|
|
44932
|
-
entries =
|
|
44897
|
+
entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
|
|
44933
44898
|
} catch {
|
|
44934
44899
|
return;
|
|
44935
44900
|
}
|
|
44936
44901
|
for (const ent of entries) {
|
|
44937
|
-
const entryPath =
|
|
44902
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
44938
44903
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
44939
44904
|
let content;
|
|
44940
44905
|
try {
|
|
44941
|
-
content =
|
|
44906
|
+
content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
|
|
44942
44907
|
} catch {
|
|
44943
44908
|
try {
|
|
44944
|
-
content =
|
|
44909
|
+
content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
|
|
44945
44910
|
} catch {
|
|
44946
44911
|
continue;
|
|
44947
44912
|
}
|
|
@@ -44965,26 +44930,26 @@ function listSkillsForDir(dir, source) {
|
|
|
44965
44930
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
44966
44931
|
let entries;
|
|
44967
44932
|
try {
|
|
44968
|
-
entries =
|
|
44933
|
+
entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
|
|
44969
44934
|
} catch {
|
|
44970
44935
|
return;
|
|
44971
44936
|
}
|
|
44972
44937
|
for (const ent of entries) {
|
|
44973
|
-
const entryPath =
|
|
44938
|
+
const entryPath = import_node_path7.default.join(dir, ent.name);
|
|
44974
44939
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
44975
44940
|
const ns = ent.name;
|
|
44976
44941
|
let subEntries;
|
|
44977
44942
|
try {
|
|
44978
|
-
subEntries =
|
|
44943
|
+
subEntries = import_node_fs7.default.readdirSync(entryPath, { withFileTypes: true });
|
|
44979
44944
|
} catch {
|
|
44980
44945
|
continue;
|
|
44981
44946
|
}
|
|
44982
44947
|
for (const se of subEntries) {
|
|
44983
44948
|
if (!se.name.endsWith(".md")) continue;
|
|
44984
|
-
const sePath =
|
|
44949
|
+
const sePath = import_node_path7.default.join(entryPath, se.name);
|
|
44985
44950
|
let content;
|
|
44986
44951
|
try {
|
|
44987
|
-
content =
|
|
44952
|
+
content = import_node_fs7.default.readFileSync(sePath, "utf8");
|
|
44988
44953
|
} catch {
|
|
44989
44954
|
continue;
|
|
44990
44955
|
}
|
|
@@ -45001,7 +44966,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
45001
44966
|
} else if (ent.name.endsWith(".md")) {
|
|
45002
44967
|
let content;
|
|
45003
44968
|
try {
|
|
45004
|
-
content =
|
|
44969
|
+
content = import_node_fs7.default.readFileSync(entryPath, "utf8");
|
|
45005
44970
|
} catch {
|
|
45006
44971
|
continue;
|
|
45007
44972
|
}
|
|
@@ -45017,10 +44982,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
45017
44982
|
}
|
|
45018
44983
|
}
|
|
45019
44984
|
function readInstalledPlugins(home) {
|
|
45020
|
-
const file =
|
|
44985
|
+
const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
45021
44986
|
let raw;
|
|
45022
44987
|
try {
|
|
45023
|
-
raw =
|
|
44988
|
+
raw = import_node_fs7.default.readFileSync(file, "utf8");
|
|
45024
44989
|
} catch {
|
|
45025
44990
|
return [];
|
|
45026
44991
|
}
|
|
@@ -45045,7 +45010,7 @@ var SkillsScanner = class {
|
|
|
45045
45010
|
home;
|
|
45046
45011
|
extraPluginRoots;
|
|
45047
45012
|
constructor(opts = {}) {
|
|
45048
|
-
this.home = opts.home ??
|
|
45013
|
+
this.home = opts.home ?? import_node_os4.default.homedir();
|
|
45049
45014
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
45050
45015
|
}
|
|
45051
45016
|
/**
|
|
@@ -45068,14 +45033,14 @@ var SkillsScanner = class {
|
|
|
45068
45033
|
});
|
|
45069
45034
|
}
|
|
45070
45035
|
const fsBlock = [];
|
|
45071
|
-
scanSkillDir(
|
|
45072
|
-
scanCommandDir(
|
|
45073
|
-
scanSkillDir(
|
|
45074
|
-
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);
|
|
45075
45040
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
45076
45041
|
for (const { name, root } of plugins) {
|
|
45077
|
-
scanSkillDir(
|
|
45078
|
-
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);
|
|
45079
45044
|
}
|
|
45080
45045
|
fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
|
|
45081
45046
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -45181,8 +45146,8 @@ var PersonaManager = class {
|
|
|
45181
45146
|
};
|
|
45182
45147
|
|
|
45183
45148
|
// src/persona/seed.ts
|
|
45184
|
-
var
|
|
45185
|
-
var
|
|
45149
|
+
var fs9 = __toESM(require("fs"), 1);
|
|
45150
|
+
var path11 = __toESM(require("path"), 1);
|
|
45186
45151
|
var import_node_url = require("url");
|
|
45187
45152
|
var import_meta = {};
|
|
45188
45153
|
var DEFAULT_BYPASS_PROFILE = {
|
|
@@ -45213,6 +45178,16 @@ var DEFAULT_PERSONAS = [
|
|
|
45213
45178
|
public: false,
|
|
45214
45179
|
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45215
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
|
+
},
|
|
45216
45191
|
{
|
|
45217
45192
|
personaId: "persona-feishu-assistant",
|
|
45218
45193
|
label: "\u98DE\u4E66\u52A9\u7406",
|
|
@@ -45306,6 +45281,14 @@ var DEFAULT_PERSONAS = [
|
|
|
45306
45281
|
public: false,
|
|
45307
45282
|
sandboxProfile: DEFAULT_BYPASS_PROFILE
|
|
45308
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
|
+
},
|
|
45309
45292
|
{
|
|
45310
45293
|
// HTML PPT 制作师:把想法/文字/旧 PPT 转成单文件 HTML 演示稿
|
|
45311
45294
|
// bundle 含 frontend-slides skill(MIT,Zara Zhang),daemon ship 进 .claude/skills/
|
|
@@ -45352,24 +45335,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
|
|
|
45352
45335
|
if (!argv1) return null;
|
|
45353
45336
|
let real = argv1;
|
|
45354
45337
|
try {
|
|
45355
|
-
real =
|
|
45338
|
+
real = fs9.realpathSync(argv1);
|
|
45356
45339
|
} catch {
|
|
45357
45340
|
}
|
|
45358
|
-
return
|
|
45341
|
+
return path11.resolve(path11.dirname(real), sibling);
|
|
45359
45342
|
}
|
|
45360
45343
|
function findDefaultsRoot(logger) {
|
|
45361
45344
|
const candidates = [];
|
|
45362
45345
|
try {
|
|
45363
|
-
const here =
|
|
45364
|
-
candidates.push(
|
|
45365
|
-
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"));
|
|
45366
45349
|
} catch {
|
|
45367
45350
|
}
|
|
45368
45351
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
|
|
45369
45352
|
if (fromArgv) candidates.push(fromArgv);
|
|
45370
45353
|
for (const c of candidates) {
|
|
45371
45354
|
try {
|
|
45372
|
-
if (
|
|
45355
|
+
if (fs9.statSync(c).isDirectory()) {
|
|
45373
45356
|
logger?.info("persona.defaults-root.resolved", { root: c });
|
|
45374
45357
|
return c;
|
|
45375
45358
|
}
|
|
@@ -45386,8 +45369,8 @@ function seedDefaultPersonas(args) {
|
|
|
45386
45369
|
args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
|
|
45387
45370
|
continue;
|
|
45388
45371
|
}
|
|
45389
|
-
const bundleDir =
|
|
45390
|
-
if (!
|
|
45372
|
+
const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
|
|
45373
|
+
if (!fs9.existsSync(bundleDir)) {
|
|
45391
45374
|
args.logger.warn("persona.seed.skip", {
|
|
45392
45375
|
personaId: entry.personaId,
|
|
45393
45376
|
reason: "bundle-missing",
|
|
@@ -45395,8 +45378,8 @@ function seedDefaultPersonas(args) {
|
|
|
45395
45378
|
});
|
|
45396
45379
|
continue;
|
|
45397
45380
|
}
|
|
45398
|
-
const claudeMdPath =
|
|
45399
|
-
if (!
|
|
45381
|
+
const claudeMdPath = path11.join(bundleDir, "CLAUDE.md");
|
|
45382
|
+
if (!fs9.existsSync(claudeMdPath)) {
|
|
45400
45383
|
args.logger.warn("persona.seed.skip", {
|
|
45401
45384
|
personaId: entry.personaId,
|
|
45402
45385
|
reason: "no-CLAUDE.md",
|
|
@@ -45404,7 +45387,7 @@ function seedDefaultPersonas(args) {
|
|
|
45404
45387
|
});
|
|
45405
45388
|
continue;
|
|
45406
45389
|
}
|
|
45407
|
-
const personality =
|
|
45390
|
+
const personality = fs9.readFileSync(claudeMdPath, "utf8");
|
|
45408
45391
|
const now = Date.now();
|
|
45409
45392
|
const persona = {
|
|
45410
45393
|
personaId: entry.personaId,
|
|
@@ -45430,17 +45413,17 @@ function seedDefaultPersonas(args) {
|
|
|
45430
45413
|
}
|
|
45431
45414
|
}
|
|
45432
45415
|
function skipNodeModulesUnder(srcRoot) {
|
|
45433
|
-
return (src) => !
|
|
45416
|
+
return (src) => !path11.relative(srcRoot, src).split(path11.sep).includes("node_modules");
|
|
45434
45417
|
}
|
|
45435
45418
|
function copyBundleExtras(srcDir, dstDir) {
|
|
45436
|
-
for (const entry of
|
|
45419
|
+
for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
|
|
45437
45420
|
if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
|
|
45438
|
-
const srcPath =
|
|
45439
|
-
const dstPath =
|
|
45421
|
+
const srcPath = path11.join(srcDir, entry.name);
|
|
45422
|
+
const dstPath = path11.join(dstDir, entry.name);
|
|
45440
45423
|
if (entry.isDirectory()) {
|
|
45441
|
-
|
|
45424
|
+
fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45442
45425
|
} else if (entry.isFile()) {
|
|
45443
|
-
|
|
45426
|
+
fs9.copyFileSync(srcPath, dstPath);
|
|
45444
45427
|
}
|
|
45445
45428
|
}
|
|
45446
45429
|
}
|
|
@@ -45448,16 +45431,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
|
|
|
45448
45431
|
function refreshDaemonManagedDirs(args) {
|
|
45449
45432
|
const entries = args.entries ?? DEFAULT_PERSONAS;
|
|
45450
45433
|
for (const entry of entries) {
|
|
45451
|
-
const bundleDir =
|
|
45452
|
-
if (!
|
|
45434
|
+
const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
|
|
45435
|
+
if (!fs9.existsSync(bundleDir)) continue;
|
|
45453
45436
|
const personaDir = args.store.personaDirPath(entry.personaId);
|
|
45454
|
-
if (!
|
|
45437
|
+
if (!fs9.existsSync(personaDir)) continue;
|
|
45455
45438
|
for (const relPath of DAEMON_MANAGED_PATHS) {
|
|
45456
|
-
const srcPath =
|
|
45457
|
-
if (!
|
|
45458
|
-
const dstPath =
|
|
45439
|
+
const srcPath = path11.join(bundleDir, relPath);
|
|
45440
|
+
if (!fs9.existsSync(srcPath)) continue;
|
|
45441
|
+
const dstPath = path11.join(personaDir, relPath);
|
|
45459
45442
|
try {
|
|
45460
|
-
|
|
45443
|
+
fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
45461
45444
|
args.logger.info("persona.refresh.synced", {
|
|
45462
45445
|
personaId: entry.personaId,
|
|
45463
45446
|
path: relPath
|
|
@@ -45517,15 +45500,15 @@ function migrateCodexSandbox(args) {
|
|
|
45517
45500
|
function findDeployKitRoot(logger) {
|
|
45518
45501
|
const candidates = [];
|
|
45519
45502
|
try {
|
|
45520
|
-
const here =
|
|
45521
|
-
candidates.push(
|
|
45503
|
+
const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45504
|
+
candidates.push(path11.resolve(here, "..", "deploy-kit"));
|
|
45522
45505
|
} catch {
|
|
45523
45506
|
}
|
|
45524
45507
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
|
|
45525
45508
|
if (fromArgv) candidates.push(fromArgv);
|
|
45526
45509
|
for (const c of candidates) {
|
|
45527
45510
|
try {
|
|
45528
|
-
if (
|
|
45511
|
+
if (fs9.statSync(c).isDirectory()) {
|
|
45529
45512
|
logger?.info("persona.deploy-kit-root.resolved", { root: c });
|
|
45530
45513
|
return c;
|
|
45531
45514
|
}
|
|
@@ -45536,8 +45519,8 @@ function findDeployKitRoot(logger) {
|
|
|
45536
45519
|
return null;
|
|
45537
45520
|
}
|
|
45538
45521
|
function seedDeployKit(args) {
|
|
45539
|
-
const dst =
|
|
45540
|
-
|
|
45522
|
+
const dst = path11.join(args.dataDir, "deploy-kit");
|
|
45523
|
+
fs9.cpSync(args.deployKitBundleRoot, dst, {
|
|
45541
45524
|
recursive: true,
|
|
45542
45525
|
dereference: true,
|
|
45543
45526
|
force: false,
|
|
@@ -45546,35 +45529,35 @@ function seedDeployKit(args) {
|
|
|
45546
45529
|
args.logger.info("deploy-kit.seed.done", { dst });
|
|
45547
45530
|
}
|
|
45548
45531
|
function refreshDeployKit(args) {
|
|
45549
|
-
const dst =
|
|
45550
|
-
if (!
|
|
45532
|
+
const dst = path11.join(args.dataDir, "deploy-kit");
|
|
45533
|
+
if (!fs9.existsSync(dst)) {
|
|
45551
45534
|
seedDeployKit(args);
|
|
45552
45535
|
return;
|
|
45553
45536
|
}
|
|
45554
45537
|
for (const sub of ["scripts", "contract"]) {
|
|
45555
|
-
const s =
|
|
45556
|
-
if (
|
|
45557
|
-
|
|
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 });
|
|
45558
45541
|
}
|
|
45559
45542
|
}
|
|
45560
|
-
const secretsSrc =
|
|
45561
|
-
if (
|
|
45562
|
-
|
|
45563
|
-
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)) {
|
|
45564
45547
|
if (!f.endsWith(".example")) continue;
|
|
45565
|
-
|
|
45548
|
+
fs9.copyFileSync(path11.join(secretsSrc, f), path11.join(dst, ".secrets", f));
|
|
45566
45549
|
}
|
|
45567
45550
|
}
|
|
45568
45551
|
args.logger.info("deploy-kit.refresh.done", { dst });
|
|
45569
45552
|
}
|
|
45570
45553
|
|
|
45571
45554
|
// src/share-md-viewer/load.ts
|
|
45572
|
-
var
|
|
45573
|
-
var
|
|
45555
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
45556
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
45574
45557
|
var import_node_url2 = require("url");
|
|
45575
45558
|
|
|
45576
45559
|
// src/share-md-viewer/asset-loader.ts
|
|
45577
|
-
var
|
|
45560
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
45578
45561
|
function htmlEscape(s) {
|
|
45579
45562
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
45580
45563
|
}
|
|
@@ -45582,12 +45565,12 @@ function createViewerAssetLoader(opts) {
|
|
|
45582
45565
|
let viewerTemplate;
|
|
45583
45566
|
let errorTemplate;
|
|
45584
45567
|
try {
|
|
45585
|
-
viewerTemplate =
|
|
45568
|
+
viewerTemplate = import_node_fs8.default.readFileSync(opts.viewerHtmlPath, "utf8");
|
|
45586
45569
|
} catch (err) {
|
|
45587
45570
|
throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
|
|
45588
45571
|
}
|
|
45589
45572
|
try {
|
|
45590
|
-
errorTemplate =
|
|
45573
|
+
errorTemplate = import_node_fs8.default.readFileSync(opts.errorHtmlPath, "utf8");
|
|
45591
45574
|
} catch (err) {
|
|
45592
45575
|
throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
|
|
45593
45576
|
}
|
|
@@ -45606,25 +45589,25 @@ var import_meta2 = {};
|
|
|
45606
45589
|
function tryLoadViewerAssets(logger) {
|
|
45607
45590
|
const candidates = [];
|
|
45608
45591
|
try {
|
|
45609
|
-
const here =
|
|
45592
|
+
const here = import_node_path8.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
45610
45593
|
candidates.push(here);
|
|
45611
|
-
candidates.push(
|
|
45612
|
-
candidates.push(
|
|
45594
|
+
candidates.push(import_node_path8.default.resolve(here, ".."));
|
|
45595
|
+
candidates.push(import_node_path8.default.resolve(here, "..", "..", "dist"));
|
|
45613
45596
|
} catch {
|
|
45614
45597
|
}
|
|
45615
45598
|
if (process.argv[1]) {
|
|
45616
45599
|
let real = process.argv[1];
|
|
45617
45600
|
try {
|
|
45618
|
-
real =
|
|
45601
|
+
real = import_node_fs9.default.realpathSync(process.argv[1]);
|
|
45619
45602
|
} catch {
|
|
45620
45603
|
}
|
|
45621
|
-
candidates.push(
|
|
45604
|
+
candidates.push(import_node_path8.default.dirname(real));
|
|
45622
45605
|
}
|
|
45623
45606
|
for (const root of candidates) {
|
|
45624
|
-
const viewerHtmlPath =
|
|
45625
|
-
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");
|
|
45626
45609
|
try {
|
|
45627
|
-
if (
|
|
45610
|
+
if (import_node_fs9.default.statSync(viewerHtmlPath).isFile() && import_node_fs9.default.statSync(errorHtmlPath).isFile()) {
|
|
45628
45611
|
logger?.info("share-md-viewer.assets-root.resolved", { root });
|
|
45629
45612
|
return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
|
|
45630
45613
|
}
|
|
@@ -45639,30 +45622,30 @@ function tryLoadViewerAssets(logger) {
|
|
|
45639
45622
|
}
|
|
45640
45623
|
|
|
45641
45624
|
// src/share-ui/load.ts
|
|
45642
|
-
var
|
|
45643
|
-
var
|
|
45625
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
45626
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
45644
45627
|
var import_node_url3 = require("url");
|
|
45645
45628
|
|
|
45646
45629
|
// src/share-ui/asset-loader.ts
|
|
45647
|
-
var
|
|
45648
|
-
var
|
|
45630
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
45631
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
45649
45632
|
function createShareUiAssetLoader(opts) {
|
|
45650
45633
|
let indexHtml;
|
|
45651
45634
|
try {
|
|
45652
|
-
indexHtml =
|
|
45635
|
+
indexHtml = import_node_fs10.default.readFileSync(opts.indexHtmlPath, "utf8");
|
|
45653
45636
|
} catch (err) {
|
|
45654
45637
|
throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
|
|
45655
45638
|
}
|
|
45656
|
-
const assetsDir =
|
|
45639
|
+
const assetsDir = import_node_path9.default.resolve(opts.assetsDir);
|
|
45657
45640
|
return {
|
|
45658
45641
|
renderIndexHtml() {
|
|
45659
45642
|
return indexHtml;
|
|
45660
45643
|
},
|
|
45661
45644
|
resolveAssetPath(rel) {
|
|
45662
|
-
const resolved =
|
|
45663
|
-
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;
|
|
45664
45647
|
try {
|
|
45665
|
-
if (
|
|
45648
|
+
if (import_node_fs10.default.statSync(resolved).isFile()) return resolved;
|
|
45666
45649
|
} catch {
|
|
45667
45650
|
}
|
|
45668
45651
|
return null;
|
|
@@ -45676,28 +45659,28 @@ function bundleDirFromArgv(argv1) {
|
|
|
45676
45659
|
if (!argv1) return null;
|
|
45677
45660
|
let real = argv1;
|
|
45678
45661
|
try {
|
|
45679
|
-
real =
|
|
45662
|
+
real = import_node_fs11.default.realpathSync(argv1);
|
|
45680
45663
|
} catch {
|
|
45681
45664
|
}
|
|
45682
|
-
return
|
|
45665
|
+
return import_node_path10.default.dirname(real);
|
|
45683
45666
|
}
|
|
45684
45667
|
function tryLoadShareUi(logger) {
|
|
45685
45668
|
const candidates = [];
|
|
45686
45669
|
try {
|
|
45687
|
-
const here =
|
|
45670
|
+
const here = import_node_path10.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
45688
45671
|
candidates.push(here);
|
|
45689
|
-
candidates.push(
|
|
45690
|
-
candidates.push(
|
|
45672
|
+
candidates.push(import_node_path10.default.resolve(here, ".."));
|
|
45673
|
+
candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
|
|
45691
45674
|
} catch {
|
|
45692
45675
|
}
|
|
45693
45676
|
const argvDir = bundleDirFromArgv(process.argv[1]);
|
|
45694
45677
|
if (argvDir) candidates.push(argvDir);
|
|
45695
45678
|
for (const root of candidates) {
|
|
45696
|
-
const shareUiDir =
|
|
45697
|
-
const indexHtmlPath =
|
|
45698
|
-
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");
|
|
45699
45682
|
try {
|
|
45700
|
-
if (
|
|
45683
|
+
if (import_node_fs11.default.statSync(indexHtmlPath).isFile() && import_node_fs11.default.statSync(assetsDir).isDirectory()) {
|
|
45701
45684
|
logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
|
|
45702
45685
|
return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
|
|
45703
45686
|
}
|
|
@@ -45779,20 +45762,20 @@ function buildVisitorLogin(deps) {
|
|
|
45779
45762
|
}
|
|
45780
45763
|
|
|
45781
45764
|
// src/visitor/visitor-store.ts
|
|
45782
|
-
var
|
|
45783
|
-
var
|
|
45765
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
45766
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
45784
45767
|
function createVisitorStore(opts) {
|
|
45785
|
-
const file =
|
|
45768
|
+
const file = import_node_path11.default.join(opts.dir, "visitors.json");
|
|
45786
45769
|
const read = () => {
|
|
45787
45770
|
try {
|
|
45788
|
-
return JSON.parse(
|
|
45771
|
+
return JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
|
|
45789
45772
|
} catch {
|
|
45790
45773
|
return [];
|
|
45791
45774
|
}
|
|
45792
45775
|
};
|
|
45793
45776
|
const write = (rows) => {
|
|
45794
|
-
|
|
45795
|
-
|
|
45777
|
+
import_node_fs12.default.mkdirSync(opts.dir, { recursive: true });
|
|
45778
|
+
import_node_fs12.default.writeFileSync(file, JSON.stringify(rows, null, 2));
|
|
45796
45779
|
};
|
|
45797
45780
|
return {
|
|
45798
45781
|
upsert(r) {
|
|
@@ -46308,8 +46291,8 @@ var CodexAdapter = class {
|
|
|
46308
46291
|
|
|
46309
46292
|
// src/tools/claude-tui.ts
|
|
46310
46293
|
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
46311
|
-
var
|
|
46312
|
-
var
|
|
46294
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
46295
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
46313
46296
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
46314
46297
|
|
|
46315
46298
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -47436,14 +47419,17 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
47436
47419
|
if (ctx.shiftMcpConfigPath) {
|
|
47437
47420
|
args.push("--mcp-config", ctx.shiftMcpConfigPath);
|
|
47438
47421
|
}
|
|
47422
|
+
if (ctx.inboxMcpConfigPath) {
|
|
47423
|
+
args.push("--mcp-config", ctx.inboxMcpConfigPath);
|
|
47424
|
+
}
|
|
47439
47425
|
args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
|
|
47440
47426
|
if (ctx.effort) args.push("--effort", ctx.effort);
|
|
47441
47427
|
return args;
|
|
47442
47428
|
}
|
|
47443
47429
|
function jsonlExistsForCtx(ctx) {
|
|
47444
47430
|
if (!ctx.toolSessionId) return false;
|
|
47445
|
-
const home =
|
|
47446
|
-
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`);
|
|
47447
47433
|
try {
|
|
47448
47434
|
return import_node_fs16.default.statSync(file).isFile();
|
|
47449
47435
|
} catch {
|
|
@@ -47515,9 +47501,9 @@ var PersonaDispatchManager = class {
|
|
|
47515
47501
|
|
|
47516
47502
|
// src/dispatch/mcp-config.ts
|
|
47517
47503
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
47518
|
-
var
|
|
47504
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
47519
47505
|
function dispatchMcpConfigPath(dataDir) {
|
|
47520
|
-
return
|
|
47506
|
+
return import_node_path14.default.join(dataDir, "dispatch.mcp.json");
|
|
47521
47507
|
}
|
|
47522
47508
|
function writeDispatchMcpConfig(args) {
|
|
47523
47509
|
const cfgPath = dispatchMcpConfigPath(args.dataDir);
|
|
@@ -47539,9 +47525,9 @@ function writeDispatchMcpConfig(args) {
|
|
|
47539
47525
|
|
|
47540
47526
|
// src/ticket/mcp-config.ts
|
|
47541
47527
|
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
47542
|
-
var
|
|
47528
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
47543
47529
|
function ticketMcpConfigPath(dataDir) {
|
|
47544
|
-
return
|
|
47530
|
+
return import_node_path15.default.join(dataDir, "ticket.mcp.json");
|
|
47545
47531
|
}
|
|
47546
47532
|
function writeTicketMcpConfig(args) {
|
|
47547
47533
|
const cfgPath = ticketMcpConfigPath(args.dataDir);
|
|
@@ -47569,9 +47555,9 @@ function writeTicketMcpConfig(args) {
|
|
|
47569
47555
|
|
|
47570
47556
|
// src/shift/mcp-config.ts
|
|
47571
47557
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
47572
|
-
var
|
|
47558
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
47573
47559
|
function shiftMcpConfigPath(dataDir) {
|
|
47574
|
-
return
|
|
47560
|
+
return import_node_path16.default.join(dataDir, "shift.mcp.json");
|
|
47575
47561
|
}
|
|
47576
47562
|
async function writeShiftMcpConfig(args) {
|
|
47577
47563
|
const cfgPath = shiftMcpConfigPath(args.dataDir);
|
|
@@ -47591,6 +47577,29 @@ async function writeShiftMcpConfig(args) {
|
|
|
47591
47577
|
return cfgPath;
|
|
47592
47578
|
}
|
|
47593
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
|
+
|
|
47594
47603
|
// src/shift/store.ts
|
|
47595
47604
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
47596
47605
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
@@ -48246,6 +48255,39 @@ async function forwardDispatchToPeer(args) {
|
|
|
48246
48255
|
}
|
|
48247
48256
|
return json.result.outcome;
|
|
48248
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
|
+
}
|
|
48249
48291
|
|
|
48250
48292
|
// src/tools/codex-history.ts
|
|
48251
48293
|
var import_node_child_process5 = require("child_process");
|
|
@@ -48478,8 +48520,8 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
48478
48520
|
}
|
|
48479
48521
|
|
|
48480
48522
|
// src/workspace/browser.ts
|
|
48481
|
-
var
|
|
48482
|
-
var
|
|
48523
|
+
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
48524
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
48483
48525
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
48484
48526
|
init_protocol();
|
|
48485
48527
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
@@ -48494,7 +48536,7 @@ function resolveInsideCwd(cwd, subpath) {
|
|
|
48494
48536
|
}
|
|
48495
48537
|
function ensureCwd(cwd) {
|
|
48496
48538
|
try {
|
|
48497
|
-
const stat =
|
|
48539
|
+
const stat = import_node_fs21.default.statSync(cwd);
|
|
48498
48540
|
if (!stat.isDirectory()) {
|
|
48499
48541
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
48500
48542
|
}
|
|
@@ -48505,10 +48547,10 @@ function ensureCwd(cwd) {
|
|
|
48505
48547
|
}
|
|
48506
48548
|
var WorkspaceBrowser = class {
|
|
48507
48549
|
list(args) {
|
|
48508
|
-
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();
|
|
48509
48551
|
ensureCwd(cwd);
|
|
48510
48552
|
const full = resolveInsideCwd(cwd, args.path);
|
|
48511
|
-
const dirents =
|
|
48553
|
+
const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
|
|
48512
48554
|
const entries = [];
|
|
48513
48555
|
for (const d of dirents) {
|
|
48514
48556
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -48518,7 +48560,7 @@ var WorkspaceBrowser = class {
|
|
|
48518
48560
|
mtime: ""
|
|
48519
48561
|
};
|
|
48520
48562
|
try {
|
|
48521
|
-
const st =
|
|
48563
|
+
const st = import_node_fs21.default.statSync(import_node_path19.default.join(full, d.name));
|
|
48522
48564
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
48523
48565
|
if (d.isFile()) entry.size = st.size;
|
|
48524
48566
|
} catch {
|
|
@@ -48534,14 +48576,14 @@ var WorkspaceBrowser = class {
|
|
|
48534
48576
|
read(args) {
|
|
48535
48577
|
ensureCwd(args.cwd);
|
|
48536
48578
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
48537
|
-
const st =
|
|
48579
|
+
const st = import_node_fs21.default.statSync(full);
|
|
48538
48580
|
if (!st.isFile()) {
|
|
48539
48581
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
48540
48582
|
}
|
|
48541
48583
|
if (st.size > MAX_FILE_BYTES) {
|
|
48542
48584
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
48543
48585
|
}
|
|
48544
|
-
const buf =
|
|
48586
|
+
const buf = import_node_fs21.default.readFileSync(full);
|
|
48545
48587
|
const isBinary = buf.includes(0);
|
|
48546
48588
|
if (isBinary) {
|
|
48547
48589
|
return {
|
|
@@ -48563,20 +48605,20 @@ var WorkspaceBrowser = class {
|
|
|
48563
48605
|
};
|
|
48564
48606
|
|
|
48565
48607
|
// src/skills/agents-scanner.ts
|
|
48566
|
-
var
|
|
48567
|
-
var
|
|
48608
|
+
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
48609
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
48568
48610
|
var import_node_path20 = __toESM(require("path"), 1);
|
|
48569
48611
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
48570
48612
|
function isDirLikeSync2(p2) {
|
|
48571
48613
|
try {
|
|
48572
|
-
return
|
|
48614
|
+
return import_node_fs22.default.statSync(p2).isDirectory();
|
|
48573
48615
|
} catch {
|
|
48574
48616
|
return false;
|
|
48575
48617
|
}
|
|
48576
48618
|
}
|
|
48577
48619
|
function fileExistsSync(p2) {
|
|
48578
48620
|
try {
|
|
48579
|
-
return
|
|
48621
|
+
return import_node_fs22.default.statSync(p2).isFile();
|
|
48580
48622
|
} catch {
|
|
48581
48623
|
return false;
|
|
48582
48624
|
}
|
|
@@ -48584,7 +48626,7 @@ function fileExistsSync(p2) {
|
|
|
48584
48626
|
function parseAgentFile(filePath) {
|
|
48585
48627
|
let content;
|
|
48586
48628
|
try {
|
|
48587
|
-
content =
|
|
48629
|
+
content = import_node_fs22.default.readFileSync(filePath, "utf8");
|
|
48588
48630
|
} catch {
|
|
48589
48631
|
return {};
|
|
48590
48632
|
}
|
|
@@ -48597,7 +48639,7 @@ function parseAgentFile(filePath) {
|
|
|
48597
48639
|
function scanAgentsDir(dir, source, seen, out) {
|
|
48598
48640
|
let entries;
|
|
48599
48641
|
try {
|
|
48600
|
-
entries =
|
|
48642
|
+
entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
48601
48643
|
} catch {
|
|
48602
48644
|
return;
|
|
48603
48645
|
}
|
|
@@ -48624,7 +48666,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
48624
48666
|
function walk2(dir, namespaces) {
|
|
48625
48667
|
let entries;
|
|
48626
48668
|
try {
|
|
48627
|
-
entries =
|
|
48669
|
+
entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
48628
48670
|
} catch {
|
|
48629
48671
|
return;
|
|
48630
48672
|
}
|
|
@@ -48660,7 +48702,7 @@ function readInstalledPlugins2(home) {
|
|
|
48660
48702
|
let raw = null;
|
|
48661
48703
|
for (const candidate of [v2, v1]) {
|
|
48662
48704
|
try {
|
|
48663
|
-
raw =
|
|
48705
|
+
raw = import_node_fs22.default.readFileSync(candidate, "utf8");
|
|
48664
48706
|
break;
|
|
48665
48707
|
} catch {
|
|
48666
48708
|
}
|
|
@@ -48691,7 +48733,7 @@ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
|
48691
48733
|
scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
48692
48734
|
let hasGit = false;
|
|
48693
48735
|
try {
|
|
48694
|
-
hasGit =
|
|
48736
|
+
hasGit = import_node_fs22.default.existsSync(import_node_path20.default.join(cur, ".git"));
|
|
48695
48737
|
} catch {
|
|
48696
48738
|
}
|
|
48697
48739
|
if (hasGit) return;
|
|
@@ -48707,7 +48749,7 @@ var AgentsScanner = class {
|
|
|
48707
48749
|
extraPluginRoots;
|
|
48708
48750
|
policyDir;
|
|
48709
48751
|
constructor(opts = {}) {
|
|
48710
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
48752
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
|
|
48711
48753
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
48712
48754
|
if (opts.policyDir !== void 0) {
|
|
48713
48755
|
this.policyDir = opts.policyDir;
|
|
@@ -48754,21 +48796,21 @@ var AgentsScanner = class {
|
|
|
48754
48796
|
};
|
|
48755
48797
|
|
|
48756
48798
|
// src/observer/session-observer.ts
|
|
48757
|
-
var
|
|
48758
|
-
var
|
|
48799
|
+
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
48800
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
48759
48801
|
var import_node_path22 = __toESM(require("path"), 1);
|
|
48760
48802
|
init_claude_history();
|
|
48761
48803
|
|
|
48762
48804
|
// src/observer/subagent-meta-observer.ts
|
|
48763
|
-
var
|
|
48764
|
-
var
|
|
48805
|
+
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
48806
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
48765
48807
|
var import_node_path21 = __toESM(require("path"), 1);
|
|
48766
48808
|
init_claude_history();
|
|
48767
48809
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
48768
48810
|
var SubagentMetaObserver = class {
|
|
48769
48811
|
constructor(opts) {
|
|
48770
48812
|
this.opts = opts;
|
|
48771
|
-
this.home = opts.home ??
|
|
48813
|
+
this.home = opts.home ?? import_node_os9.default.homedir();
|
|
48772
48814
|
}
|
|
48773
48815
|
opts;
|
|
48774
48816
|
home;
|
|
@@ -48805,7 +48847,7 @@ var SubagentMetaObserver = class {
|
|
|
48805
48847
|
attachWatcher(w2) {
|
|
48806
48848
|
if (w2.watcher) return;
|
|
48807
48849
|
try {
|
|
48808
|
-
w2.watcher =
|
|
48850
|
+
w2.watcher = import_node_fs23.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
|
|
48809
48851
|
if (!name) return;
|
|
48810
48852
|
const m2 = META_RE.exec(String(name));
|
|
48811
48853
|
if (!m2) return;
|
|
@@ -48817,7 +48859,7 @@ var SubagentMetaObserver = class {
|
|
|
48817
48859
|
scan(w2) {
|
|
48818
48860
|
let entries;
|
|
48819
48861
|
try {
|
|
48820
|
-
entries =
|
|
48862
|
+
entries = import_node_fs23.default.readdirSync(w2.dirPath);
|
|
48821
48863
|
} catch {
|
|
48822
48864
|
return;
|
|
48823
48865
|
}
|
|
@@ -48834,7 +48876,7 @@ var SubagentMetaObserver = class {
|
|
|
48834
48876
|
const file = import_node_path21.default.join(w2.dirPath, name);
|
|
48835
48877
|
let raw;
|
|
48836
48878
|
try {
|
|
48837
|
-
raw =
|
|
48879
|
+
raw = import_node_fs23.default.readFileSync(file, "utf8");
|
|
48838
48880
|
} catch {
|
|
48839
48881
|
return;
|
|
48840
48882
|
}
|
|
@@ -48879,7 +48921,7 @@ var SubagentMetaObserver = class {
|
|
|
48879
48921
|
var SessionObserver = class {
|
|
48880
48922
|
constructor(opts) {
|
|
48881
48923
|
this.opts = opts;
|
|
48882
|
-
this.home = opts.home ??
|
|
48924
|
+
this.home = opts.home ?? import_node_os10.default.homedir();
|
|
48883
48925
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
48884
48926
|
}
|
|
48885
48927
|
opts;
|
|
@@ -48898,7 +48940,7 @@ var SessionObserver = class {
|
|
|
48898
48940
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
48899
48941
|
let size = 0;
|
|
48900
48942
|
try {
|
|
48901
|
-
size =
|
|
48943
|
+
size = import_node_fs24.default.statSync(filePath).size;
|
|
48902
48944
|
} catch {
|
|
48903
48945
|
}
|
|
48904
48946
|
const w2 = {
|
|
@@ -48912,10 +48954,10 @@ var SessionObserver = class {
|
|
|
48912
48954
|
prevIsRejectSentinel: false
|
|
48913
48955
|
};
|
|
48914
48956
|
try {
|
|
48915
|
-
|
|
48957
|
+
import_node_fs24.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
|
|
48916
48958
|
} catch {
|
|
48917
48959
|
}
|
|
48918
|
-
w2.watcher =
|
|
48960
|
+
w2.watcher = import_node_fs24.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
48919
48961
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
48920
48962
|
this.poll(w2);
|
|
48921
48963
|
});
|
|
@@ -48938,7 +48980,7 @@ var SessionObserver = class {
|
|
|
48938
48980
|
// 异常静默吞,不阻塞 watcher 启动
|
|
48939
48981
|
hydrateMetaTail(w2, maxLines = 200) {
|
|
48940
48982
|
try {
|
|
48941
|
-
const raw =
|
|
48983
|
+
const raw = import_node_fs24.default.readFileSync(w2.filePath, "utf8");
|
|
48942
48984
|
if (!raw) return;
|
|
48943
48985
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
48944
48986
|
if (allLines.length === 0) return;
|
|
@@ -48962,7 +49004,7 @@ var SessionObserver = class {
|
|
|
48962
49004
|
poll(w2) {
|
|
48963
49005
|
let size = 0;
|
|
48964
49006
|
try {
|
|
48965
|
-
size =
|
|
49007
|
+
size = import_node_fs24.default.statSync(w2.filePath).size;
|
|
48966
49008
|
} catch {
|
|
48967
49009
|
return;
|
|
48968
49010
|
}
|
|
@@ -48971,11 +49013,11 @@ var SessionObserver = class {
|
|
|
48971
49013
|
w2.buf = "";
|
|
48972
49014
|
}
|
|
48973
49015
|
if (size === w2.lastSize) return;
|
|
48974
|
-
const fd =
|
|
49016
|
+
const fd = import_node_fs24.default.openSync(w2.filePath, "r");
|
|
48975
49017
|
try {
|
|
48976
49018
|
const len = size - w2.lastSize;
|
|
48977
49019
|
const buf = Buffer.alloc(len);
|
|
48978
|
-
|
|
49020
|
+
import_node_fs24.default.readSync(fd, buf, 0, len, w2.lastSize);
|
|
48979
49021
|
w2.lastSize = size;
|
|
48980
49022
|
w2.buf += buf.toString("utf8");
|
|
48981
49023
|
let newlineIndex;
|
|
@@ -48998,7 +49040,7 @@ var SessionObserver = class {
|
|
|
48998
49040
|
}
|
|
48999
49041
|
}
|
|
49000
49042
|
} finally {
|
|
49001
|
-
|
|
49043
|
+
import_node_fs24.default.closeSync(fd);
|
|
49002
49044
|
}
|
|
49003
49045
|
}
|
|
49004
49046
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -49558,7 +49600,9 @@ var EXPOSED_RPC_METHODS = [
|
|
|
49558
49600
|
// file-sharing:persona guest agent 把自己工作目录内的产物入群+签名分享。
|
|
49559
49601
|
// 路径越界由 handlers/attachment.ts guardAttachmentPath(scope-based)拦截。
|
|
49560
49602
|
"attachment.groupAdd",
|
|
49561
|
-
"attachment.signUrl"
|
|
49603
|
+
"attachment.signUrl",
|
|
49604
|
+
// persona 受控发 P2P IM DM(sender 由 session scope 推,driver 分级授权见 handlers/inbox.ts)
|
|
49605
|
+
"inbox.sendDm"
|
|
49562
49606
|
];
|
|
49563
49607
|
async function handleRpcRequest(input) {
|
|
49564
49608
|
const { method, body, sessionId, dispatcher } = input;
|
|
@@ -49794,14 +49838,14 @@ async function authenticate(token, deps) {
|
|
|
49794
49838
|
}
|
|
49795
49839
|
|
|
49796
49840
|
// src/permission/capability-store.ts
|
|
49797
|
-
var
|
|
49841
|
+
var fs28 = __toESM(require("fs"), 1);
|
|
49798
49842
|
var path27 = __toESM(require("path"), 1);
|
|
49799
49843
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
49800
49844
|
var FILE_VERSION = 1;
|
|
49801
49845
|
var CapabilityStore = class {
|
|
49802
49846
|
constructor(dataDir) {
|
|
49803
49847
|
this.dataDir = dataDir;
|
|
49804
|
-
|
|
49848
|
+
fs28.mkdirSync(dataDir, { recursive: true });
|
|
49805
49849
|
this.cache = this.readFromDisk();
|
|
49806
49850
|
}
|
|
49807
49851
|
dataDir;
|
|
@@ -49831,7 +49875,7 @@ var CapabilityStore = class {
|
|
|
49831
49875
|
const file = this.filePath();
|
|
49832
49876
|
let raw;
|
|
49833
49877
|
try {
|
|
49834
|
-
raw =
|
|
49878
|
+
raw = fs28.readFileSync(file, "utf8");
|
|
49835
49879
|
} catch (err) {
|
|
49836
49880
|
if (err?.code === "ENOENT") return [];
|
|
49837
49881
|
return [];
|
|
@@ -49859,10 +49903,10 @@ var CapabilityStore = class {
|
|
|
49859
49903
|
}
|
|
49860
49904
|
atomicWrite(file, content) {
|
|
49861
49905
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
49862
|
-
|
|
49863
|
-
|
|
49906
|
+
fs28.writeFileSync(tmp, content, { mode: 384 });
|
|
49907
|
+
fs28.renameSync(tmp, file);
|
|
49864
49908
|
try {
|
|
49865
|
-
|
|
49909
|
+
fs28.chmodSync(file, 384);
|
|
49866
49910
|
} catch {
|
|
49867
49911
|
}
|
|
49868
49912
|
}
|
|
@@ -49955,14 +49999,14 @@ var CapabilityManager = class {
|
|
|
49955
49999
|
};
|
|
49956
50000
|
|
|
49957
50001
|
// src/permission/cleanup.ts
|
|
49958
|
-
var
|
|
50002
|
+
var fs29 = __toESM(require("fs"), 1);
|
|
49959
50003
|
function cleanupGuestSessionsForCapability(cap, factory) {
|
|
49960
50004
|
const removed = [];
|
|
49961
50005
|
for (const g2 of cap.grants) {
|
|
49962
50006
|
if (g2.resource.type !== "persona") continue;
|
|
49963
50007
|
const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
|
|
49964
50008
|
try {
|
|
49965
|
-
|
|
50009
|
+
fs29.rmSync(dir, { recursive: true, force: true });
|
|
49966
50010
|
removed.push(dir);
|
|
49967
50011
|
} catch {
|
|
49968
50012
|
}
|
|
@@ -49971,13 +50015,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
49971
50015
|
}
|
|
49972
50016
|
|
|
49973
50017
|
// src/inbox/inbox-store.ts
|
|
49974
|
-
var
|
|
50018
|
+
var fs30 = __toESM(require("fs"), 1);
|
|
49975
50019
|
var path28 = __toESM(require("path"), 1);
|
|
49976
50020
|
var INBOX_SUBDIR = "inbox";
|
|
49977
50021
|
var InboxStore = class {
|
|
49978
50022
|
constructor(dataDir) {
|
|
49979
50023
|
this.dataDir = dataDir;
|
|
49980
|
-
|
|
50024
|
+
fs30.mkdirSync(this.dirPath(), { recursive: true });
|
|
49981
50025
|
}
|
|
49982
50026
|
dataDir;
|
|
49983
50027
|
/**
|
|
@@ -49989,7 +50033,7 @@ var InboxStore = class {
|
|
|
49989
50033
|
const file = this.filePath(peerDeviceId);
|
|
49990
50034
|
let raw;
|
|
49991
50035
|
try {
|
|
49992
|
-
raw =
|
|
50036
|
+
raw = fs30.readFileSync(file, "utf8");
|
|
49993
50037
|
} catch (err) {
|
|
49994
50038
|
if (err?.code === "ENOENT") return [];
|
|
49995
50039
|
return [];
|
|
@@ -50005,7 +50049,7 @@ var InboxStore = class {
|
|
|
50005
50049
|
const dir = this.dirPath();
|
|
50006
50050
|
let entries;
|
|
50007
50051
|
try {
|
|
50008
|
-
entries =
|
|
50052
|
+
entries = fs30.readdirSync(dir);
|
|
50009
50053
|
} catch (err) {
|
|
50010
50054
|
if (err?.code === "ENOENT") return [];
|
|
50011
50055
|
return [];
|
|
@@ -50021,9 +50065,9 @@ var InboxStore = class {
|
|
|
50021
50065
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
50022
50066
|
const file = this.filePath(message.peerDeviceId);
|
|
50023
50067
|
const line = JSON.stringify(message) + "\n";
|
|
50024
|
-
|
|
50068
|
+
fs30.appendFileSync(file, line, { mode: 384 });
|
|
50025
50069
|
try {
|
|
50026
|
-
|
|
50070
|
+
fs30.chmodSync(file, 384);
|
|
50027
50071
|
} catch {
|
|
50028
50072
|
}
|
|
50029
50073
|
}
|
|
@@ -50053,7 +50097,7 @@ var InboxStore = class {
|
|
|
50053
50097
|
removeByPeerDeviceId(peerDeviceId) {
|
|
50054
50098
|
const file = this.filePath(peerDeviceId);
|
|
50055
50099
|
try {
|
|
50056
|
-
|
|
50100
|
+
fs30.unlinkSync(file);
|
|
50057
50101
|
} catch (err) {
|
|
50058
50102
|
if (err?.code === "ENOENT") return;
|
|
50059
50103
|
}
|
|
@@ -50062,10 +50106,10 @@ var InboxStore = class {
|
|
|
50062
50106
|
const file = this.filePath(peerDeviceId);
|
|
50063
50107
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
50064
50108
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
50065
|
-
|
|
50066
|
-
|
|
50109
|
+
fs30.writeFileSync(tmp, content, { mode: 384 });
|
|
50110
|
+
fs30.renameSync(tmp, file);
|
|
50067
50111
|
try {
|
|
50068
|
-
|
|
50112
|
+
fs30.chmodSync(file, 384);
|
|
50069
50113
|
} catch {
|
|
50070
50114
|
}
|
|
50071
50115
|
}
|
|
@@ -50116,7 +50160,8 @@ var InboxManager = class {
|
|
|
50116
50160
|
senderDeviceId: args.senderDeviceId,
|
|
50117
50161
|
text: args.text,
|
|
50118
50162
|
createdAt: args.createdAt,
|
|
50119
|
-
readBy: {}
|
|
50163
|
+
readBy: {},
|
|
50164
|
+
...args.origin ? { origin: args.origin } : {}
|
|
50120
50165
|
};
|
|
50121
50166
|
this.store.append(msg);
|
|
50122
50167
|
const afterLen = this.store.list(args.peerDeviceId).length;
|
|
@@ -50160,7 +50205,7 @@ var InboxManager = class {
|
|
|
50160
50205
|
};
|
|
50161
50206
|
|
|
50162
50207
|
// src/state/contact-store.ts
|
|
50163
|
-
var
|
|
50208
|
+
var fs31 = __toESM(require("fs"), 1);
|
|
50164
50209
|
var path29 = __toESM(require("path"), 1);
|
|
50165
50210
|
var FILE_NAME = "contacts.json";
|
|
50166
50211
|
var ContactStore = class {
|
|
@@ -50174,7 +50219,7 @@ var ContactStore = class {
|
|
|
50174
50219
|
const file = path29.join(this.dataDir, FILE_NAME);
|
|
50175
50220
|
let raw;
|
|
50176
50221
|
try {
|
|
50177
|
-
raw =
|
|
50222
|
+
raw = fs31.readFileSync(file, "utf8");
|
|
50178
50223
|
} catch (err) {
|
|
50179
50224
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
50180
50225
|
return;
|
|
@@ -50224,13 +50269,13 @@ var ContactStore = class {
|
|
|
50224
50269
|
null,
|
|
50225
50270
|
2
|
|
50226
50271
|
);
|
|
50227
|
-
|
|
50228
|
-
|
|
50229
|
-
|
|
50272
|
+
fs31.mkdirSync(this.dataDir, { recursive: true });
|
|
50273
|
+
fs31.writeFileSync(tmp, content, { mode: 384 });
|
|
50274
|
+
fs31.renameSync(tmp, file);
|
|
50230
50275
|
}
|
|
50231
50276
|
renameBak(file) {
|
|
50232
50277
|
try {
|
|
50233
|
-
|
|
50278
|
+
fs31.renameSync(file, `${file}.bak`);
|
|
50234
50279
|
} catch {
|
|
50235
50280
|
}
|
|
50236
50281
|
}
|
|
@@ -50380,7 +50425,7 @@ async function autoReverseContact(args) {
|
|
|
50380
50425
|
}
|
|
50381
50426
|
|
|
50382
50427
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
50383
|
-
var
|
|
50428
|
+
var fs32 = __toESM(require("fs"), 1);
|
|
50384
50429
|
var path30 = __toESM(require("path"), 1);
|
|
50385
50430
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
50386
50431
|
function migrateFlattenSessions(opts) {
|
|
@@ -50400,7 +50445,7 @@ function migrateFlattenSessions(opts) {
|
|
|
50400
50445
|
if (!entry.endsWith(".json")) continue;
|
|
50401
50446
|
const src = path30.join(defaultDir, entry);
|
|
50402
50447
|
const dst = path30.join(sessionsDir, entry);
|
|
50403
|
-
|
|
50448
|
+
fs32.renameSync(src, dst);
|
|
50404
50449
|
movedBare += 1;
|
|
50405
50450
|
}
|
|
50406
50451
|
rmdirIfEmpty(defaultDir);
|
|
@@ -50412,10 +50457,10 @@ function migrateFlattenSessions(opts) {
|
|
|
50412
50457
|
const ownerSrc = path30.join(personaDir, "owner");
|
|
50413
50458
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
50414
50459
|
const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
50415
|
-
|
|
50460
|
+
fs32.mkdirSync(ownerDst, { recursive: true });
|
|
50416
50461
|
for (const file of readdirSafe(ownerSrc)) {
|
|
50417
50462
|
if (!file.endsWith(".json")) continue;
|
|
50418
|
-
|
|
50463
|
+
fs32.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
|
|
50419
50464
|
movedVmOwner += 1;
|
|
50420
50465
|
}
|
|
50421
50466
|
rmdirIfEmpty(ownerSrc);
|
|
@@ -50423,18 +50468,18 @@ function migrateFlattenSessions(opts) {
|
|
|
50423
50468
|
const listenerSrc = path30.join(personaDir, "listener");
|
|
50424
50469
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
50425
50470
|
const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
|
|
50426
|
-
|
|
50471
|
+
fs32.mkdirSync(archiveDst, { recursive: true });
|
|
50427
50472
|
for (const file of readdirSafe(listenerSrc)) {
|
|
50428
50473
|
if (!file.endsWith(".json")) continue;
|
|
50429
|
-
|
|
50474
|
+
fs32.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
|
|
50430
50475
|
archivedListener += 1;
|
|
50431
50476
|
}
|
|
50432
50477
|
rmdirIfEmpty(listenerSrc);
|
|
50433
50478
|
}
|
|
50434
50479
|
rmdirIfEmpty(personaDir);
|
|
50435
50480
|
}
|
|
50436
|
-
|
|
50437
|
-
|
|
50481
|
+
fs32.mkdirSync(sessionsDir, { recursive: true });
|
|
50482
|
+
fs32.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
50438
50483
|
return {
|
|
50439
50484
|
skipped: false,
|
|
50440
50485
|
flagWritten: true,
|
|
@@ -50445,7 +50490,7 @@ function migrateFlattenSessions(opts) {
|
|
|
50445
50490
|
}
|
|
50446
50491
|
function existsSync3(p2) {
|
|
50447
50492
|
try {
|
|
50448
|
-
|
|
50493
|
+
fs32.statSync(p2);
|
|
50449
50494
|
return true;
|
|
50450
50495
|
} catch {
|
|
50451
50496
|
return false;
|
|
@@ -50453,27 +50498,27 @@ function existsSync3(p2) {
|
|
|
50453
50498
|
}
|
|
50454
50499
|
function isDir(p2) {
|
|
50455
50500
|
try {
|
|
50456
|
-
return
|
|
50501
|
+
return fs32.statSync(p2).isDirectory();
|
|
50457
50502
|
} catch {
|
|
50458
50503
|
return false;
|
|
50459
50504
|
}
|
|
50460
50505
|
}
|
|
50461
50506
|
function readdirSafe(p2) {
|
|
50462
50507
|
try {
|
|
50463
|
-
return
|
|
50508
|
+
return fs32.readdirSync(p2);
|
|
50464
50509
|
} catch {
|
|
50465
50510
|
return [];
|
|
50466
50511
|
}
|
|
50467
50512
|
}
|
|
50468
50513
|
function rmdirIfEmpty(p2) {
|
|
50469
50514
|
try {
|
|
50470
|
-
|
|
50515
|
+
fs32.rmdirSync(p2);
|
|
50471
50516
|
} catch {
|
|
50472
50517
|
}
|
|
50473
50518
|
}
|
|
50474
50519
|
|
|
50475
50520
|
// src/transport/http-router.ts
|
|
50476
|
-
var
|
|
50521
|
+
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
50477
50522
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
50478
50523
|
|
|
50479
50524
|
// src/attachment/mime.ts
|
|
@@ -50653,7 +50698,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
50653
50698
|
}
|
|
50654
50699
|
|
|
50655
50700
|
// src/attachment/upload.ts
|
|
50656
|
-
var
|
|
50701
|
+
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
50657
50702
|
var import_node_path24 = __toESM(require("path"), 1);
|
|
50658
50703
|
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
50659
50704
|
var import_promises2 = require("stream/promises");
|
|
@@ -50675,7 +50720,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50675
50720
|
assertValidFileName(args.fileName);
|
|
50676
50721
|
const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
|
|
50677
50722
|
try {
|
|
50678
|
-
|
|
50723
|
+
import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
50679
50724
|
} catch (err) {
|
|
50680
50725
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
50681
50726
|
}
|
|
@@ -50696,18 +50741,18 @@ async function writeUploadedAttachment(args) {
|
|
|
50696
50741
|
yield buf;
|
|
50697
50742
|
}
|
|
50698
50743
|
},
|
|
50699
|
-
|
|
50744
|
+
import_node_fs25.default.createWriteStream(tmpPath, { mode: 384 })
|
|
50700
50745
|
);
|
|
50701
50746
|
} catch (err) {
|
|
50702
50747
|
try {
|
|
50703
|
-
|
|
50748
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50704
50749
|
} catch {
|
|
50705
50750
|
}
|
|
50706
50751
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
50707
50752
|
}
|
|
50708
50753
|
if (actualSize !== args.contentLength) {
|
|
50709
50754
|
try {
|
|
50710
|
-
|
|
50755
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50711
50756
|
} catch {
|
|
50712
50757
|
}
|
|
50713
50758
|
throw new UploadError(
|
|
@@ -50720,24 +50765,24 @@ async function writeUploadedAttachment(args) {
|
|
|
50720
50765
|
let finalFileName;
|
|
50721
50766
|
let hashDirExists = false;
|
|
50722
50767
|
try {
|
|
50723
|
-
hashDirExists =
|
|
50768
|
+
hashDirExists = import_node_fs25.default.statSync(hashDir).isDirectory();
|
|
50724
50769
|
} catch {
|
|
50725
50770
|
}
|
|
50726
50771
|
if (hashDirExists) {
|
|
50727
|
-
const existing =
|
|
50772
|
+
const existing = import_node_fs25.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
|
|
50728
50773
|
finalFileName = existing[0] ?? args.fileName;
|
|
50729
50774
|
try {
|
|
50730
|
-
|
|
50775
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50731
50776
|
} catch {
|
|
50732
50777
|
}
|
|
50733
50778
|
} else {
|
|
50734
50779
|
try {
|
|
50735
|
-
|
|
50780
|
+
import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
|
|
50736
50781
|
finalFileName = args.fileName;
|
|
50737
|
-
|
|
50782
|
+
import_node_fs25.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
|
|
50738
50783
|
} catch (err) {
|
|
50739
50784
|
try {
|
|
50740
|
-
|
|
50785
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
50741
50786
|
} catch {
|
|
50742
50787
|
}
|
|
50743
50788
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
@@ -50759,7 +50804,7 @@ async function writeUploadedAttachment(args) {
|
|
|
50759
50804
|
// src/extension/import.ts
|
|
50760
50805
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
50761
50806
|
var import_node_path25 = __toESM(require("path"), 1);
|
|
50762
|
-
var
|
|
50807
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
50763
50808
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
50764
50809
|
var ImportError = class extends Error {
|
|
50765
50810
|
constructor(code, message) {
|
|
@@ -50819,7 +50864,7 @@ async function importZip(buf, root) {
|
|
|
50819
50864
|
if (destExists) {
|
|
50820
50865
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
50821
50866
|
}
|
|
50822
|
-
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}-`));
|
|
50823
50868
|
try {
|
|
50824
50869
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
50825
50870
|
const dest = import_node_path25.default.join(stage, name);
|
|
@@ -51017,7 +51062,7 @@ function createHttpRouter(deps) {
|
|
|
51017
51062
|
}
|
|
51018
51063
|
let buf;
|
|
51019
51064
|
try {
|
|
51020
|
-
buf = await
|
|
51065
|
+
buf = await import_node_fs26.default.promises.readFile(abs);
|
|
51021
51066
|
} catch {
|
|
51022
51067
|
sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
51023
51068
|
return true;
|
|
@@ -51457,7 +51502,7 @@ function withCtx(ctx, body) {
|
|
|
51457
51502
|
function streamFile(res, absPath, logger) {
|
|
51458
51503
|
let stat;
|
|
51459
51504
|
try {
|
|
51460
|
-
stat =
|
|
51505
|
+
stat = import_node_fs26.default.statSync(absPath);
|
|
51461
51506
|
} catch (err) {
|
|
51462
51507
|
const code = err?.code;
|
|
51463
51508
|
if (code === "ENOENT") {
|
|
@@ -51480,7 +51525,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51480
51525
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
51481
51526
|
"X-Content-Type-Options": "nosniff"
|
|
51482
51527
|
});
|
|
51483
|
-
const stream =
|
|
51528
|
+
const stream = import_node_fs26.default.createReadStream(absPath);
|
|
51484
51529
|
stream.on("error", (err) => {
|
|
51485
51530
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
51486
51531
|
res.destroy();
|
|
@@ -51489,7 +51534,7 @@ function streamFile(res, absPath, logger) {
|
|
|
51489
51534
|
}
|
|
51490
51535
|
|
|
51491
51536
|
// src/attachment/gc.ts
|
|
51492
|
-
var
|
|
51537
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
51493
51538
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
51494
51539
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
51495
51540
|
function runAttachmentGc(args) {
|
|
@@ -51512,7 +51557,7 @@ function runAttachmentGc(args) {
|
|
|
51512
51557
|
const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
|
|
51513
51558
|
let hashDirs;
|
|
51514
51559
|
try {
|
|
51515
|
-
hashDirs =
|
|
51560
|
+
hashDirs = import_node_fs27.default.readdirSync(attRoot);
|
|
51516
51561
|
} catch (err) {
|
|
51517
51562
|
if (err.code === "ENOENT") continue;
|
|
51518
51563
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
@@ -51522,7 +51567,7 @@ function runAttachmentGc(args) {
|
|
|
51522
51567
|
const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
|
|
51523
51568
|
let files;
|
|
51524
51569
|
try {
|
|
51525
|
-
files =
|
|
51570
|
+
files = import_node_fs27.default.readdirSync(hashDirAbs);
|
|
51526
51571
|
} catch {
|
|
51527
51572
|
continue;
|
|
51528
51573
|
}
|
|
@@ -51530,7 +51575,7 @@ function runAttachmentGc(args) {
|
|
|
51530
51575
|
const file = import_node_path27.default.join(hashDirAbs, name);
|
|
51531
51576
|
let stat;
|
|
51532
51577
|
try {
|
|
51533
|
-
stat =
|
|
51578
|
+
stat = import_node_fs27.default.statSync(file);
|
|
51534
51579
|
} catch {
|
|
51535
51580
|
continue;
|
|
51536
51581
|
}
|
|
@@ -51539,25 +51584,25 @@ function runAttachmentGc(args) {
|
|
|
51539
51584
|
if (age < ttlMs) continue;
|
|
51540
51585
|
if (liveAbs.has(file)) continue;
|
|
51541
51586
|
try {
|
|
51542
|
-
|
|
51587
|
+
import_node_fs27.default.unlinkSync(file);
|
|
51543
51588
|
} catch (err) {
|
|
51544
51589
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
51545
51590
|
}
|
|
51546
51591
|
}
|
|
51547
51592
|
try {
|
|
51548
|
-
if (
|
|
51593
|
+
if (import_node_fs27.default.readdirSync(hashDirAbs).length === 0) import_node_fs27.default.rmdirSync(hashDirAbs);
|
|
51549
51594
|
} catch {
|
|
51550
51595
|
}
|
|
51551
51596
|
}
|
|
51552
51597
|
try {
|
|
51553
|
-
if (
|
|
51598
|
+
if (import_node_fs27.default.readdirSync(attRoot).length === 0) import_node_fs27.default.rmdirSync(attRoot);
|
|
51554
51599
|
} catch {
|
|
51555
51600
|
}
|
|
51556
51601
|
}
|
|
51557
51602
|
}
|
|
51558
51603
|
|
|
51559
51604
|
// src/attachment/group.ts
|
|
51560
|
-
var
|
|
51605
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
51561
51606
|
var import_node_path28 = __toESM(require("path"), 1);
|
|
51562
51607
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
51563
51608
|
init_protocol();
|
|
@@ -51583,7 +51628,7 @@ var GroupFileStore = class {
|
|
|
51583
51628
|
readFile(scope, sessionId) {
|
|
51584
51629
|
const file = this.filePath(scope, sessionId);
|
|
51585
51630
|
try {
|
|
51586
|
-
const raw =
|
|
51631
|
+
const raw = import_node_fs28.default.readFileSync(file, "utf8");
|
|
51587
51632
|
const parsed = JSON.parse(raw);
|
|
51588
51633
|
if (!Array.isArray(parsed)) {
|
|
51589
51634
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -51609,10 +51654,10 @@ var GroupFileStore = class {
|
|
|
51609
51654
|
}
|
|
51610
51655
|
writeFile(scope, sessionId, entries) {
|
|
51611
51656
|
const file = this.filePath(scope, sessionId);
|
|
51612
|
-
|
|
51657
|
+
import_node_fs28.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
|
|
51613
51658
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
51614
|
-
|
|
51615
|
-
|
|
51659
|
+
import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
51660
|
+
import_node_fs28.default.renameSync(tmp, file);
|
|
51616
51661
|
}
|
|
51617
51662
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
51618
51663
|
list(scope, sessionId) {
|
|
@@ -51698,7 +51743,7 @@ var GroupFileStore = class {
|
|
|
51698
51743
|
};
|
|
51699
51744
|
|
|
51700
51745
|
// src/discovery/state-file.ts
|
|
51701
|
-
var
|
|
51746
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
51702
51747
|
var import_node_path29 = __toESM(require("path"), 1);
|
|
51703
51748
|
function defaultStateFilePath(dataDir) {
|
|
51704
51749
|
return import_node_path29.default.join(dataDir, "state.json");
|
|
@@ -51723,7 +51768,7 @@ var StateFileManager = class {
|
|
|
51723
51768
|
}
|
|
51724
51769
|
read() {
|
|
51725
51770
|
try {
|
|
51726
|
-
const raw =
|
|
51771
|
+
const raw = import_node_fs29.default.readFileSync(this.file, "utf8");
|
|
51727
51772
|
const parsed = JSON.parse(raw);
|
|
51728
51773
|
return parsed;
|
|
51729
51774
|
} catch {
|
|
@@ -51737,20 +51782,20 @@ var StateFileManager = class {
|
|
|
51737
51782
|
return { status: "stale", existing };
|
|
51738
51783
|
}
|
|
51739
51784
|
write(state) {
|
|
51740
|
-
|
|
51785
|
+
import_node_fs29.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
|
|
51741
51786
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
51742
|
-
|
|
51743
|
-
|
|
51787
|
+
import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
51788
|
+
import_node_fs29.default.renameSync(tmp, this.file);
|
|
51744
51789
|
if (process.platform !== "win32") {
|
|
51745
51790
|
try {
|
|
51746
|
-
|
|
51791
|
+
import_node_fs29.default.chmodSync(this.file, 384);
|
|
51747
51792
|
} catch {
|
|
51748
51793
|
}
|
|
51749
51794
|
}
|
|
51750
51795
|
}
|
|
51751
51796
|
delete() {
|
|
51752
51797
|
try {
|
|
51753
|
-
|
|
51798
|
+
import_node_fs29.default.unlinkSync(this.file);
|
|
51754
51799
|
} catch {
|
|
51755
51800
|
}
|
|
51756
51801
|
}
|
|
@@ -51765,13 +51810,13 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
51765
51810
|
}
|
|
51766
51811
|
|
|
51767
51812
|
// src/tunnel/tunnel-manager.ts
|
|
51768
|
-
var
|
|
51813
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
51769
51814
|
var import_node_path33 = __toESM(require("path"), 1);
|
|
51770
51815
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
51771
51816
|
var import_node_child_process9 = require("child_process");
|
|
51772
51817
|
|
|
51773
51818
|
// src/tunnel/tunnel-store.ts
|
|
51774
|
-
var
|
|
51819
|
+
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
51775
51820
|
var import_node_path30 = __toESM(require("path"), 1);
|
|
51776
51821
|
var TunnelStore = class {
|
|
51777
51822
|
constructor(filePath) {
|
|
@@ -51780,7 +51825,7 @@ var TunnelStore = class {
|
|
|
51780
51825
|
filePath;
|
|
51781
51826
|
async get() {
|
|
51782
51827
|
try {
|
|
51783
|
-
const raw = await
|
|
51828
|
+
const raw = await import_node_fs30.default.promises.readFile(this.filePath, "utf8");
|
|
51784
51829
|
const obj = JSON.parse(raw);
|
|
51785
51830
|
if (!isPersistedTunnel(obj)) return null;
|
|
51786
51831
|
return obj;
|
|
@@ -51792,21 +51837,21 @@ var TunnelStore = class {
|
|
|
51792
51837
|
}
|
|
51793
51838
|
async set(v2) {
|
|
51794
51839
|
const dir = import_node_path30.default.dirname(this.filePath);
|
|
51795
|
-
await
|
|
51840
|
+
await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
|
|
51796
51841
|
const data = JSON.stringify(v2, null, 2);
|
|
51797
51842
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
51798
|
-
await
|
|
51843
|
+
await import_node_fs30.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
51799
51844
|
if (process.platform !== "win32") {
|
|
51800
51845
|
try {
|
|
51801
|
-
await
|
|
51846
|
+
await import_node_fs30.default.promises.chmod(tmp, 384);
|
|
51802
51847
|
} catch {
|
|
51803
51848
|
}
|
|
51804
51849
|
}
|
|
51805
|
-
await
|
|
51850
|
+
await import_node_fs30.default.promises.rename(tmp, this.filePath);
|
|
51806
51851
|
}
|
|
51807
51852
|
async clear() {
|
|
51808
51853
|
try {
|
|
51809
|
-
await
|
|
51854
|
+
await import_node_fs30.default.promises.unlink(this.filePath);
|
|
51810
51855
|
} catch (err) {
|
|
51811
51856
|
const code = err?.code;
|
|
51812
51857
|
if (code !== "ENOENT") throw err;
|
|
@@ -51901,8 +51946,8 @@ function escape(v2) {
|
|
|
51901
51946
|
}
|
|
51902
51947
|
|
|
51903
51948
|
// src/tunnel/frpc-binary.ts
|
|
51904
|
-
var
|
|
51905
|
-
var
|
|
51949
|
+
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
51950
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
51906
51951
|
var import_node_path31 = __toESM(require("path"), 1);
|
|
51907
51952
|
var import_node_child_process7 = require("child_process");
|
|
51908
51953
|
var import_node_stream3 = require("stream");
|
|
@@ -51935,7 +51980,7 @@ function frpcDownloadUrl(version2, p2) {
|
|
|
51935
51980
|
}
|
|
51936
51981
|
async function ensureFrpcBinary(opts) {
|
|
51937
51982
|
if (opts.override) {
|
|
51938
|
-
if (!
|
|
51983
|
+
if (!import_node_fs31.default.existsSync(opts.override)) {
|
|
51939
51984
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
51940
51985
|
}
|
|
51941
51986
|
return opts.override;
|
|
@@ -51943,10 +51988,10 @@ async function ensureFrpcBinary(opts) {
|
|
|
51943
51988
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
51944
51989
|
const platform = opts.platform ?? detectPlatform();
|
|
51945
51990
|
const binDir = import_node_path31.default.join(opts.dataDir, "bin");
|
|
51946
|
-
|
|
51991
|
+
import_node_fs31.default.mkdirSync(binDir, { recursive: true });
|
|
51947
51992
|
cleanupStaleArtifacts(binDir);
|
|
51948
51993
|
const stableBin = import_node_path31.default.join(binDir, "frpc");
|
|
51949
|
-
if (
|
|
51994
|
+
if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
|
|
51950
51995
|
const partialBin = `${stableBin}.partial`;
|
|
51951
51996
|
const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
51952
51997
|
try {
|
|
@@ -51957,8 +52002,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
51957
52002
|
} else {
|
|
51958
52003
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
51959
52004
|
}
|
|
51960
|
-
|
|
51961
|
-
|
|
52005
|
+
import_node_fs31.default.chmodSync(partialBin, 493);
|
|
52006
|
+
import_node_fs31.default.renameSync(partialBin, stableBin);
|
|
51962
52007
|
} finally {
|
|
51963
52008
|
safeUnlink(tarballPath);
|
|
51964
52009
|
safeUnlink(partialBin);
|
|
@@ -51968,7 +52013,7 @@ async function ensureFrpcBinary(opts) {
|
|
|
51968
52013
|
function cleanupStaleArtifacts(binDir) {
|
|
51969
52014
|
let entries;
|
|
51970
52015
|
try {
|
|
51971
|
-
entries =
|
|
52016
|
+
entries = import_node_fs31.default.readdirSync(binDir);
|
|
51972
52017
|
} catch {
|
|
51973
52018
|
return;
|
|
51974
52019
|
}
|
|
@@ -51976,7 +52021,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
51976
52021
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
51977
52022
|
const full = import_node_path31.default.join(binDir, name);
|
|
51978
52023
|
try {
|
|
51979
|
-
|
|
52024
|
+
import_node_fs31.default.rmSync(full, { recursive: true, force: true });
|
|
51980
52025
|
} catch {
|
|
51981
52026
|
}
|
|
51982
52027
|
}
|
|
@@ -51984,7 +52029,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
51984
52029
|
}
|
|
51985
52030
|
function safeUnlink(p2) {
|
|
51986
52031
|
try {
|
|
51987
|
-
|
|
52032
|
+
import_node_fs31.default.unlinkSync(p2);
|
|
51988
52033
|
} catch {
|
|
51989
52034
|
}
|
|
51990
52035
|
}
|
|
@@ -51995,13 +52040,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
51995
52040
|
if (!res.ok || !res.body) {
|
|
51996
52041
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
51997
52042
|
}
|
|
51998
|
-
const out =
|
|
52043
|
+
const out = import_node_fs31.default.createWriteStream(dest);
|
|
51999
52044
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
52000
52045
|
await (0, import_promises4.pipeline)(nodeStream, out);
|
|
52001
52046
|
}
|
|
52002
52047
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
52003
52048
|
const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
52004
|
-
|
|
52049
|
+
import_node_fs31.default.mkdirSync(work, { recursive: true });
|
|
52005
52050
|
try {
|
|
52006
52051
|
await new Promise((resolve6, reject) => {
|
|
52007
52052
|
const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -52010,17 +52055,17 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
52010
52055
|
});
|
|
52011
52056
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
52012
52057
|
const src = import_node_path31.default.join(work, dirName, "frpc");
|
|
52013
|
-
if (!
|
|
52058
|
+
if (!import_node_fs31.default.existsSync(src)) {
|
|
52014
52059
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
52015
52060
|
}
|
|
52016
|
-
|
|
52061
|
+
import_node_fs31.default.copyFileSync(src, destBin);
|
|
52017
52062
|
} finally {
|
|
52018
|
-
|
|
52063
|
+
import_node_fs31.default.rmSync(work, { recursive: true, force: true });
|
|
52019
52064
|
}
|
|
52020
52065
|
}
|
|
52021
52066
|
|
|
52022
52067
|
// src/tunnel/frpc-process.ts
|
|
52023
|
-
var
|
|
52068
|
+
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
52024
52069
|
var import_node_path32 = __toESM(require("path"), 1);
|
|
52025
52070
|
var import_node_child_process8 = require("child_process");
|
|
52026
52071
|
function frpcPidFilePath(dataDir) {
|
|
@@ -52028,13 +52073,13 @@ function frpcPidFilePath(dataDir) {
|
|
|
52028
52073
|
}
|
|
52029
52074
|
function writeFrpcPid(dataDir, pid) {
|
|
52030
52075
|
try {
|
|
52031
|
-
|
|
52076
|
+
import_node_fs32.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
52032
52077
|
} catch {
|
|
52033
52078
|
}
|
|
52034
52079
|
}
|
|
52035
52080
|
function clearFrpcPid(dataDir) {
|
|
52036
52081
|
try {
|
|
52037
|
-
|
|
52082
|
+
import_node_fs32.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
52038
52083
|
} catch {
|
|
52039
52084
|
}
|
|
52040
52085
|
}
|
|
@@ -52050,7 +52095,7 @@ function defaultIsPidAlive(pid) {
|
|
|
52050
52095
|
}
|
|
52051
52096
|
function defaultReadPidFile(file) {
|
|
52052
52097
|
try {
|
|
52053
|
-
return
|
|
52098
|
+
return import_node_fs32.default.readFileSync(file, "utf8");
|
|
52054
52099
|
} catch {
|
|
52055
52100
|
return null;
|
|
52056
52101
|
}
|
|
@@ -52090,7 +52135,7 @@ async function killStaleFrpc(deps) {
|
|
|
52090
52135
|
}
|
|
52091
52136
|
if (victims.size === 0) {
|
|
52092
52137
|
try {
|
|
52093
|
-
|
|
52138
|
+
import_node_fs32.default.unlinkSync(pidFile);
|
|
52094
52139
|
} catch {
|
|
52095
52140
|
}
|
|
52096
52141
|
return;
|
|
@@ -52101,7 +52146,7 @@ async function killStaleFrpc(deps) {
|
|
|
52101
52146
|
}
|
|
52102
52147
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
52103
52148
|
try {
|
|
52104
|
-
|
|
52149
|
+
import_node_fs32.default.unlinkSync(pidFile);
|
|
52105
52150
|
} catch {
|
|
52106
52151
|
}
|
|
52107
52152
|
}
|
|
@@ -52276,12 +52321,12 @@ var TunnelManager = class {
|
|
|
52276
52321
|
localPort,
|
|
52277
52322
|
logLevel: "info"
|
|
52278
52323
|
});
|
|
52279
|
-
await
|
|
52324
|
+
await import_node_fs33.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
52280
52325
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
52281
52326
|
stdio: ["ignore", "pipe", "pipe"]
|
|
52282
52327
|
});
|
|
52283
52328
|
const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
|
|
52284
|
-
const logStream =
|
|
52329
|
+
const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
52285
52330
|
logStream.on("error", () => {
|
|
52286
52331
|
});
|
|
52287
52332
|
const tee = (chunk) => {
|
|
@@ -52363,14 +52408,14 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52363
52408
|
}
|
|
52364
52409
|
|
|
52365
52410
|
// src/tunnel/device-key.ts
|
|
52366
|
-
var
|
|
52411
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
52367
52412
|
var import_node_path34 = __toESM(require("path"), 1);
|
|
52368
52413
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
52369
52414
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
52370
52415
|
function deriveStableDeviceKey(opts = {}) {
|
|
52371
|
-
const hostname = opts.hostname ??
|
|
52372
|
-
const uid = opts.uid ?? (typeof
|
|
52373
|
-
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();
|
|
52374
52419
|
const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
|
|
52375
52420
|
const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
|
|
52376
52421
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
@@ -52379,7 +52424,7 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
52379
52424
|
}
|
|
52380
52425
|
|
|
52381
52426
|
// src/auth-store.ts
|
|
52382
|
-
var
|
|
52427
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
52383
52428
|
var import_node_path35 = __toESM(require("path"), 1);
|
|
52384
52429
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
52385
52430
|
var AUTH_FILE_NAME = "auth.json";
|
|
@@ -52420,7 +52465,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
52420
52465
|
}
|
|
52421
52466
|
function readAuthFile(file) {
|
|
52422
52467
|
try {
|
|
52423
|
-
const raw =
|
|
52468
|
+
const raw = import_node_fs34.default.readFileSync(file, "utf8");
|
|
52424
52469
|
const parsed = JSON.parse(raw);
|
|
52425
52470
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
52426
52471
|
return null;
|
|
@@ -52440,25 +52485,25 @@ function readAuthFile(file) {
|
|
|
52440
52485
|
}
|
|
52441
52486
|
}
|
|
52442
52487
|
function writeAuthFile(file, content) {
|
|
52443
|
-
|
|
52444
|
-
|
|
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 });
|
|
52445
52490
|
try {
|
|
52446
|
-
|
|
52491
|
+
import_node_fs34.default.chmodSync(file, 384);
|
|
52447
52492
|
} catch {
|
|
52448
52493
|
}
|
|
52449
52494
|
}
|
|
52450
52495
|
|
|
52451
52496
|
// src/owner-profile.ts
|
|
52452
|
-
var
|
|
52453
|
-
var
|
|
52497
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
52498
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
52454
52499
|
var import_node_path36 = __toESM(require("path"), 1);
|
|
52455
52500
|
var PROFILE_FILENAME = "profile.json";
|
|
52456
52501
|
function loadOwnerDisplayName(dataDir) {
|
|
52457
|
-
const fallback =
|
|
52502
|
+
const fallback = import_node_os14.default.userInfo().username;
|
|
52458
52503
|
const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
|
|
52459
52504
|
let raw;
|
|
52460
52505
|
try {
|
|
52461
|
-
raw =
|
|
52506
|
+
raw = import_node_fs35.default.readFileSync(profilePath, "utf8");
|
|
52462
52507
|
} catch {
|
|
52463
52508
|
return fallback;
|
|
52464
52509
|
}
|
|
@@ -52481,7 +52526,7 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
52481
52526
|
}
|
|
52482
52527
|
|
|
52483
52528
|
// src/feishu-auth/owner-identity-store.ts
|
|
52484
|
-
var
|
|
52529
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
52485
52530
|
var import_node_path37 = __toESM(require("path"), 1);
|
|
52486
52531
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
52487
52532
|
var OwnerIdentityStore = class {
|
|
@@ -52492,7 +52537,7 @@ var OwnerIdentityStore = class {
|
|
|
52492
52537
|
read() {
|
|
52493
52538
|
let raw;
|
|
52494
52539
|
try {
|
|
52495
|
-
raw =
|
|
52540
|
+
raw = import_node_fs36.default.readFileSync(this.file, "utf8");
|
|
52496
52541
|
} catch {
|
|
52497
52542
|
return null;
|
|
52498
52543
|
}
|
|
@@ -52520,16 +52565,16 @@ var OwnerIdentityStore = class {
|
|
|
52520
52565
|
};
|
|
52521
52566
|
}
|
|
52522
52567
|
write(record) {
|
|
52523
|
-
|
|
52524
|
-
|
|
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 });
|
|
52525
52570
|
try {
|
|
52526
|
-
|
|
52571
|
+
import_node_fs36.default.chmodSync(this.file, 384);
|
|
52527
52572
|
} catch {
|
|
52528
52573
|
}
|
|
52529
52574
|
}
|
|
52530
52575
|
clear() {
|
|
52531
52576
|
try {
|
|
52532
|
-
|
|
52577
|
+
import_node_fs36.default.unlinkSync(this.file);
|
|
52533
52578
|
} catch (err) {
|
|
52534
52579
|
const code = err?.code;
|
|
52535
52580
|
if (code !== "ENOENT") throw err;
|
|
@@ -52794,7 +52839,7 @@ function verifyConnectToken(args) {
|
|
|
52794
52839
|
}
|
|
52795
52840
|
|
|
52796
52841
|
// src/feishu-auth/server-key.ts
|
|
52797
|
-
var
|
|
52842
|
+
var fs46 = __toESM(require("fs"), 1);
|
|
52798
52843
|
var path46 = __toESM(require("path"), 1);
|
|
52799
52844
|
var FILE_NAME2 = "server-signing-key.json";
|
|
52800
52845
|
var ServerKeyStore = class {
|
|
@@ -52808,7 +52853,7 @@ var ServerKeyStore = class {
|
|
|
52808
52853
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
52809
52854
|
read() {
|
|
52810
52855
|
try {
|
|
52811
|
-
const raw =
|
|
52856
|
+
const raw = fs46.readFileSync(this.filePath(), "utf8");
|
|
52812
52857
|
const parsed = JSON.parse(raw);
|
|
52813
52858
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
52814
52859
|
return parsed.publicKeyPem;
|
|
@@ -52823,12 +52868,12 @@ var ServerKeyStore = class {
|
|
|
52823
52868
|
publicKeyPem,
|
|
52824
52869
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
52825
52870
|
};
|
|
52826
|
-
|
|
52827
|
-
|
|
52871
|
+
fs46.mkdirSync(this.dataDir, { recursive: true });
|
|
52872
|
+
fs46.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
52828
52873
|
}
|
|
52829
52874
|
clear() {
|
|
52830
52875
|
try {
|
|
52831
|
-
|
|
52876
|
+
fs46.unlinkSync(this.filePath());
|
|
52832
52877
|
} catch {
|
|
52833
52878
|
}
|
|
52834
52879
|
}
|
|
@@ -52841,12 +52886,12 @@ init_protocol();
|
|
|
52841
52886
|
init_protocol();
|
|
52842
52887
|
|
|
52843
52888
|
// src/session/fork.ts
|
|
52844
|
-
var
|
|
52845
|
-
var
|
|
52889
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
52890
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
52846
52891
|
var import_node_path38 = __toESM(require("path"), 1);
|
|
52847
52892
|
init_claude_history();
|
|
52848
52893
|
function readJsonlEntries(file) {
|
|
52849
|
-
const raw =
|
|
52894
|
+
const raw = import_node_fs37.default.readFileSync(file, "utf8");
|
|
52850
52895
|
const out = [];
|
|
52851
52896
|
for (const line of raw.split("\n")) {
|
|
52852
52897
|
const t = line.trim();
|
|
@@ -52859,10 +52904,10 @@ function readJsonlEntries(file) {
|
|
|
52859
52904
|
return out;
|
|
52860
52905
|
}
|
|
52861
52906
|
function forkSession(input) {
|
|
52862
|
-
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");
|
|
52863
52908
|
const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
52864
52909
|
const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
52865
|
-
if (!
|
|
52910
|
+
if (!import_node_fs37.default.existsSync(sourceFile)) {
|
|
52866
52911
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
52867
52912
|
}
|
|
52868
52913
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -52893,8 +52938,8 @@ function forkSession(input) {
|
|
|
52893
52938
|
forkedLines.push(JSON.stringify(forked));
|
|
52894
52939
|
}
|
|
52895
52940
|
const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
52896
|
-
|
|
52897
|
-
|
|
52941
|
+
import_node_fs37.default.mkdirSync(projectDir, { recursive: true });
|
|
52942
|
+
import_node_fs37.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
52898
52943
|
return { forkedToolSessionId, forkedFilePath };
|
|
52899
52944
|
}
|
|
52900
52945
|
|
|
@@ -53415,7 +53460,7 @@ function buildHistoryHandlers(deps) {
|
|
|
53415
53460
|
|
|
53416
53461
|
// src/handlers/workspace.ts
|
|
53417
53462
|
var path50 = __toESM(require("path"), 1);
|
|
53418
|
-
var
|
|
53463
|
+
var os15 = __toESM(require("os"), 1);
|
|
53419
53464
|
init_protocol();
|
|
53420
53465
|
init_protocol();
|
|
53421
53466
|
function buildEnabledPluginNames(personaManager, personaId) {
|
|
@@ -53455,7 +53500,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
53455
53500
|
const list = async (frame, _client, ctx) => {
|
|
53456
53501
|
const args = WorkspaceListArgs.parse(frame);
|
|
53457
53502
|
const isGuest = ctx?.principal.kind === "guest";
|
|
53458
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
53503
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
|
|
53459
53504
|
const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
|
|
53460
53505
|
const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
53461
53506
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
@@ -53511,14 +53556,14 @@ init_protocol();
|
|
|
53511
53556
|
|
|
53512
53557
|
// src/workspace/git.ts
|
|
53513
53558
|
var import_node_child_process10 = require("child_process");
|
|
53514
|
-
var
|
|
53559
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53515
53560
|
var import_node_path39 = __toESM(require("path"), 1);
|
|
53516
53561
|
var import_node_util = require("util");
|
|
53517
53562
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
53518
53563
|
function normalizePath(p2) {
|
|
53519
53564
|
const resolved = import_node_path39.default.resolve(p2);
|
|
53520
53565
|
try {
|
|
53521
|
-
return
|
|
53566
|
+
return import_node_fs38.default.realpathSync(resolved);
|
|
53522
53567
|
} catch {
|
|
53523
53568
|
return resolved;
|
|
53524
53569
|
}
|
|
@@ -53714,7 +53759,8 @@ function buildInboxHandlers(deps) {
|
|
|
53714
53759
|
senderDeviceId: ctx.principal.id,
|
|
53715
53760
|
text: args.text,
|
|
53716
53761
|
id: args.id,
|
|
53717
|
-
createdAt: args.createdAt
|
|
53762
|
+
createdAt: args.createdAt,
|
|
53763
|
+
origin: args.origin
|
|
53718
53764
|
});
|
|
53719
53765
|
return {
|
|
53720
53766
|
response: { type: "inbox:postMessage:ok", message }
|
|
@@ -53753,8 +53799,104 @@ function buildInboxHandlers(deps) {
|
|
|
53753
53799
|
}
|
|
53754
53800
|
};
|
|
53755
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
|
+
d?.logger?.warn("inbox.sendDm.rejected", { reason: "missing-session-id" });
|
|
53810
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "inbox:sendDm requires sessionId");
|
|
53811
|
+
}
|
|
53812
|
+
const scope = d.getSessionScope(sessionId);
|
|
53813
|
+
d.logger?.info("inbox.sendDm.received", {
|
|
53814
|
+
sessionId,
|
|
53815
|
+
scopeKind: scope?.kind ?? "null",
|
|
53816
|
+
mode: scope && scope.kind === "persona" ? scope.mode : void 0,
|
|
53817
|
+
personaId: scope && scope.kind === "persona" ? scope.personaId : void 0,
|
|
53818
|
+
hasPeerDeviceId: Boolean(args.peerDeviceId),
|
|
53819
|
+
textLen: args.text.length
|
|
53820
|
+
});
|
|
53821
|
+
if (!scope || scope.kind !== "persona") {
|
|
53822
|
+
d.logger?.warn("inbox.sendDm.rejected", { sessionId, reason: "not-persona-session", scopeKind: scope?.kind ?? "null" });
|
|
53823
|
+
throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "inbox:sendDm requires a persona session");
|
|
53824
|
+
}
|
|
53825
|
+
const origin = { kind: "persona", personaId: scope.personaId };
|
|
53826
|
+
const id = d.genId();
|
|
53827
|
+
const createdAt = d.now();
|
|
53828
|
+
if (scope.mode === "guest") {
|
|
53829
|
+
if (args.peerDeviceId && args.peerDeviceId !== d.ownerPrincipalId) {
|
|
53830
|
+
d.logger?.warn("inbox.sendDm.rejected", {
|
|
53831
|
+
sessionId,
|
|
53832
|
+
reason: "guest-non-owner-target",
|
|
53833
|
+
personaId: scope.personaId,
|
|
53834
|
+
target: args.peerDeviceId
|
|
53835
|
+
});
|
|
53836
|
+
throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "guest-driven persona may only DM the owner");
|
|
53837
|
+
}
|
|
53838
|
+
const message2 = manager.postMessage({
|
|
53839
|
+
peerDeviceId: scope.capId,
|
|
53840
|
+
senderDeviceId: scope.capId,
|
|
53841
|
+
text: args.text,
|
|
53842
|
+
id,
|
|
53843
|
+
createdAt,
|
|
53844
|
+
origin
|
|
53845
|
+
});
|
|
53846
|
+
d.logger?.info("inbox.sendDm.delivered", { sessionId, mode: "guest", personaId: scope.personaId, peerDeviceId: scope.capId, id });
|
|
53847
|
+
return { response: { type: "inbox:sendDm:ok", message: message2 } };
|
|
53848
|
+
}
|
|
53849
|
+
if (!args.peerDeviceId) {
|
|
53850
|
+
d.logger?.warn("inbox.sendDm.rejected", { sessionId, reason: "owner-missing-peer", personaId: scope.personaId });
|
|
53851
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "owner-driven sendDm requires peerDeviceId");
|
|
53852
|
+
}
|
|
53853
|
+
const contact = d.getContact(args.peerDeviceId);
|
|
53854
|
+
if (!contact) {
|
|
53855
|
+
d.logger?.warn("inbox.sendDm.rejected", {
|
|
53856
|
+
sessionId,
|
|
53857
|
+
reason: "unknown-contact",
|
|
53858
|
+
personaId: scope.personaId,
|
|
53859
|
+
peerDeviceId: args.peerDeviceId
|
|
53860
|
+
});
|
|
53861
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `unknown contact: ${args.peerDeviceId}`);
|
|
53862
|
+
}
|
|
53863
|
+
const fwd = await d.forwardInboxPostToPeer({
|
|
53864
|
+
contact: { remoteUrl: contact.remoteUrl, connectToken: contact.connectToken },
|
|
53865
|
+
id,
|
|
53866
|
+
text: args.text,
|
|
53867
|
+
createdAt,
|
|
53868
|
+
origin
|
|
53869
|
+
});
|
|
53870
|
+
if (!fwd.ok) {
|
|
53871
|
+
d.logger?.warn("inbox.sendDm.forward-failed", {
|
|
53872
|
+
sessionId,
|
|
53873
|
+
personaId: scope.personaId,
|
|
53874
|
+
peerDeviceId: args.peerDeviceId,
|
|
53875
|
+
id,
|
|
53876
|
+
error: fwd.error ?? "unknown"
|
|
53877
|
+
});
|
|
53878
|
+
throw new ClawdError(ERROR_CODES.INTERNAL, `deliver to peer failed: ${fwd.error ?? "unknown"}`);
|
|
53879
|
+
}
|
|
53880
|
+
const message = manager.postMessage({
|
|
53881
|
+
peerDeviceId: args.peerDeviceId,
|
|
53882
|
+
senderDeviceId: d.ownerPrincipalId,
|
|
53883
|
+
text: args.text,
|
|
53884
|
+
id,
|
|
53885
|
+
createdAt,
|
|
53886
|
+
origin
|
|
53887
|
+
});
|
|
53888
|
+
d.logger?.info("inbox.sendDm.delivered", {
|
|
53889
|
+
sessionId,
|
|
53890
|
+
mode: "owner",
|
|
53891
|
+
personaId: scope.personaId,
|
|
53892
|
+
peerDeviceId: args.peerDeviceId,
|
|
53893
|
+
id
|
|
53894
|
+
});
|
|
53895
|
+
return { response: { type: "inbox:sendDm:ok", message } };
|
|
53896
|
+
};
|
|
53756
53897
|
return {
|
|
53757
53898
|
"inbox:postMessage": postMessage,
|
|
53899
|
+
"inbox:sendDm": sendDm,
|
|
53758
53900
|
"inbox:list": list,
|
|
53759
53901
|
"inbox:markRead": markRead
|
|
53760
53902
|
};
|
|
@@ -53981,7 +54123,7 @@ function buildDeviceHandlers(deps) {
|
|
|
53981
54123
|
}
|
|
53982
54124
|
|
|
53983
54125
|
// src/handlers/meta.ts
|
|
53984
|
-
var
|
|
54126
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
53985
54127
|
init_protocol();
|
|
53986
54128
|
|
|
53987
54129
|
// src/version.ts
|
|
@@ -54013,7 +54155,7 @@ function buildReadyFrame(deps, client) {
|
|
|
54013
54155
|
return {
|
|
54014
54156
|
version,
|
|
54015
54157
|
protocolVersion: PROTOCOL_VERSION,
|
|
54016
|
-
hostname:
|
|
54158
|
+
hostname: import_node_os16.default.hostname(),
|
|
54017
54159
|
os: process.platform,
|
|
54018
54160
|
tools,
|
|
54019
54161
|
runningSessions: info.runningSessions,
|
|
@@ -54383,15 +54525,15 @@ function computePublishCheck(args) {
|
|
|
54383
54525
|
// src/extension/install-flow.ts
|
|
54384
54526
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
54385
54527
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
54386
|
-
var
|
|
54528
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
54387
54529
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
54388
54530
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
54389
54531
|
|
|
54390
54532
|
// src/extension/paths.ts
|
|
54391
|
-
var
|
|
54533
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
54392
54534
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
54393
54535
|
function clawdHomeRoot(override) {
|
|
54394
|
-
return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(
|
|
54536
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os17.default.homedir(), ".clawd");
|
|
54395
54537
|
}
|
|
54396
54538
|
function extensionsRoot(override) {
|
|
54397
54539
|
return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
|
|
@@ -54473,7 +54615,7 @@ async function installFromChannel(args, deps) {
|
|
|
54473
54615
|
);
|
|
54474
54616
|
}
|
|
54475
54617
|
const stage = await import_promises6.default.mkdtemp(
|
|
54476
|
-
import_node_path43.default.join(
|
|
54618
|
+
import_node_path43.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
54477
54619
|
);
|
|
54478
54620
|
try {
|
|
54479
54621
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
@@ -54504,7 +54646,7 @@ async function installFromChannel(args, deps) {
|
|
|
54504
54646
|
// src/extension/update-flow.ts
|
|
54505
54647
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
54506
54648
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
54507
|
-
var
|
|
54649
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
54508
54650
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
54509
54651
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
54510
54652
|
var UpdateError = class extends Error {
|
|
@@ -54592,7 +54734,7 @@ async function updateFromChannel(args, deps) {
|
|
|
54592
54734
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
54593
54735
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
54594
54736
|
const stage = await import_promises7.default.mkdtemp(
|
|
54595
|
-
import_node_path44.default.join(
|
|
54737
|
+
import_node_path44.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
54596
54738
|
);
|
|
54597
54739
|
try {
|
|
54598
54740
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
@@ -54974,7 +55116,7 @@ function buildExtensionHandlers(deps) {
|
|
|
54974
55116
|
}
|
|
54975
55117
|
|
|
54976
55118
|
// src/app-builder/project-store.ts
|
|
54977
|
-
var
|
|
55119
|
+
var import_node_fs39 = require("fs");
|
|
54978
55120
|
var import_node_child_process11 = require("child_process");
|
|
54979
55121
|
var import_node_path46 = require("path");
|
|
54980
55122
|
init_protocol();
|
|
@@ -55002,7 +55144,7 @@ var ProjectStore = class {
|
|
|
55002
55144
|
async list() {
|
|
55003
55145
|
let entries;
|
|
55004
55146
|
try {
|
|
55005
|
-
entries = await
|
|
55147
|
+
entries = await import_node_fs39.promises.readdir(this.projectsRoot());
|
|
55006
55148
|
} catch (err) {
|
|
55007
55149
|
if (err.code === "ENOENT") return [];
|
|
55008
55150
|
throw err;
|
|
@@ -55010,7 +55152,7 @@ var ProjectStore = class {
|
|
|
55010
55152
|
const out = [];
|
|
55011
55153
|
for (const name of entries) {
|
|
55012
55154
|
try {
|
|
55013
|
-
const raw = await
|
|
55155
|
+
const raw = await import_node_fs39.promises.readFile(this.metaPath(name), "utf8");
|
|
55014
55156
|
const json = JSON.parse(raw);
|
|
55015
55157
|
let migrated = false;
|
|
55016
55158
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -55021,7 +55163,7 @@ var ProjectStore = class {
|
|
|
55021
55163
|
if (parsed.success) {
|
|
55022
55164
|
out.push(parsed.data);
|
|
55023
55165
|
if (migrated) {
|
|
55024
|
-
void
|
|
55166
|
+
void import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
55025
55167
|
});
|
|
55026
55168
|
}
|
|
55027
55169
|
}
|
|
@@ -55065,8 +55207,8 @@ var ProjectStore = class {
|
|
|
55065
55207
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
55066
55208
|
}
|
|
55067
55209
|
const dir = this.projectDir(name);
|
|
55068
|
-
await
|
|
55069
|
-
await
|
|
55210
|
+
await import_node_fs39.promises.mkdir(dir, { recursive: true });
|
|
55211
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
55070
55212
|
return meta;
|
|
55071
55213
|
}
|
|
55072
55214
|
/**
|
|
@@ -55109,7 +55251,7 @@ var ProjectStore = class {
|
|
|
55109
55251
|
}
|
|
55110
55252
|
async delete(name) {
|
|
55111
55253
|
const dir = this.projectDir(name);
|
|
55112
|
-
await
|
|
55254
|
+
await import_node_fs39.promises.rm(dir, { recursive: true, force: true });
|
|
55113
55255
|
}
|
|
55114
55256
|
async updatePort(name, newPort) {
|
|
55115
55257
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -55125,7 +55267,7 @@ var ProjectStore = class {
|
|
|
55125
55267
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
55126
55268
|
}
|
|
55127
55269
|
const updated = { ...target, port: newPort };
|
|
55128
|
-
await
|
|
55270
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
55129
55271
|
return updated;
|
|
55130
55272
|
}
|
|
55131
55273
|
/**
|
|
@@ -55142,7 +55284,7 @@ var ProjectStore = class {
|
|
|
55142
55284
|
if (!validated.success) {
|
|
55143
55285
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
55144
55286
|
}
|
|
55145
|
-
await
|
|
55287
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
55146
55288
|
return validated.data;
|
|
55147
55289
|
}
|
|
55148
55290
|
/**
|
|
@@ -55163,7 +55305,7 @@ var ProjectStore = class {
|
|
|
55163
55305
|
if (!validated.success) {
|
|
55164
55306
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
55165
55307
|
}
|
|
55166
|
-
await
|
|
55308
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
55167
55309
|
return validated.data;
|
|
55168
55310
|
}
|
|
55169
55311
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -55178,7 +55320,7 @@ var ProjectStore = class {
|
|
|
55178
55320
|
if (!validated.success) {
|
|
55179
55321
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
55180
55322
|
}
|
|
55181
|
-
await
|
|
55323
|
+
await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
55182
55324
|
return validated.data;
|
|
55183
55325
|
}
|
|
55184
55326
|
};
|
|
@@ -55299,7 +55441,7 @@ var PublishJobRegistry = class {
|
|
|
55299
55441
|
|
|
55300
55442
|
// src/app-builder/publish-job-runner.ts
|
|
55301
55443
|
var import_node_child_process13 = require("child_process");
|
|
55302
|
-
var
|
|
55444
|
+
var import_node_fs40 = require("fs");
|
|
55303
55445
|
var import_node_path47 = require("path");
|
|
55304
55446
|
|
|
55305
55447
|
// src/app-builder/publish-stage-parser.ts
|
|
@@ -55335,7 +55477,7 @@ async function startPublishJob(deps, args) {
|
|
|
55335
55477
|
const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
|
|
55336
55478
|
let logStream = null;
|
|
55337
55479
|
try {
|
|
55338
|
-
logStream = (0,
|
|
55480
|
+
logStream = (0, import_node_fs40.createWriteStream)(logPath, { flags: "w" });
|
|
55339
55481
|
} catch {
|
|
55340
55482
|
logStream = null;
|
|
55341
55483
|
}
|
|
@@ -55593,7 +55735,7 @@ async function recoverInterruptedJobs(deps) {
|
|
|
55593
55735
|
// src/handlers/app-builder.ts
|
|
55594
55736
|
init_protocol();
|
|
55595
55737
|
var import_node_path48 = require("path");
|
|
55596
|
-
var
|
|
55738
|
+
var import_node_fs41 = require("fs");
|
|
55597
55739
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
55598
55740
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
55599
55741
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -55674,7 +55816,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
55674
55816
|
async function listAllUsersProjects() {
|
|
55675
55817
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
55676
55818
|
const getStore = deps.getStore;
|
|
55677
|
-
const userIds = await
|
|
55819
|
+
const userIds = await import_node_fs41.promises.readdir(deps.usersRoot).catch(() => []);
|
|
55678
55820
|
const perUser = await Promise.all(
|
|
55679
55821
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
55680
55822
|
);
|
|
@@ -56225,6 +56367,7 @@ async function uninstall(deps) {
|
|
|
56225
56367
|
}
|
|
56226
56368
|
|
|
56227
56369
|
// src/handlers/index.ts
|
|
56370
|
+
var import_node_crypto17 = require("crypto");
|
|
56228
56371
|
function buildMethodHandlers(deps) {
|
|
56229
56372
|
return {
|
|
56230
56373
|
...buildSessionHandlers({
|
|
@@ -56249,7 +56392,19 @@ function buildMethodHandlers(deps) {
|
|
|
56249
56392
|
manager: deps.capabilityManager
|
|
56250
56393
|
}),
|
|
56251
56394
|
...buildInboxHandlers({
|
|
56252
|
-
manager: deps.inboxManager
|
|
56395
|
+
manager: deps.inboxManager,
|
|
56396
|
+
sendDmDeps: {
|
|
56397
|
+
ownerPrincipalId: deps.ownerPrincipalId,
|
|
56398
|
+
getSessionScope: deps.getSessionScope,
|
|
56399
|
+
getContact: (deviceId) => {
|
|
56400
|
+
const c = deps.contactStore.get(deviceId);
|
|
56401
|
+
return c ? { deviceId: c.deviceId, remoteUrl: c.remoteUrl, connectToken: c.connectToken } : null;
|
|
56402
|
+
},
|
|
56403
|
+
genId: () => (0, import_node_crypto17.randomUUID)(),
|
|
56404
|
+
now: () => Date.now(),
|
|
56405
|
+
forwardInboxPostToPeer,
|
|
56406
|
+
logger: deps.logger
|
|
56407
|
+
}
|
|
56253
56408
|
}),
|
|
56254
56409
|
...buildContactHandlers({
|
|
56255
56410
|
store: deps.contactStore,
|
|
@@ -57137,7 +57292,7 @@ async function startDaemon(config) {
|
|
|
57137
57292
|
},
|
|
57138
57293
|
source: "daemon",
|
|
57139
57294
|
sampling: logShippingCfg.sampling,
|
|
57140
|
-
homeDir:
|
|
57295
|
+
homeDir: import_node_os20.default.homedir()
|
|
57141
57296
|
});
|
|
57142
57297
|
const logger = createLogger({
|
|
57143
57298
|
level: config.logLevel,
|
|
@@ -57309,7 +57464,7 @@ async function startDaemon(config) {
|
|
|
57309
57464
|
import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
57310
57465
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
57311
57466
|
];
|
|
57312
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
57467
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57313
57468
|
let dispatchMcpConfigPath2;
|
|
57314
57469
|
if (dispatchServerScriptPath) {
|
|
57315
57470
|
const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
@@ -57332,7 +57487,7 @@ async function startDaemon(config) {
|
|
|
57332
57487
|
import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
|
|
57333
57488
|
import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
57334
57489
|
];
|
|
57335
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
57490
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57336
57491
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
57337
57492
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
57338
57493
|
let ticketMcpConfigPath2;
|
|
@@ -57361,7 +57516,7 @@ async function startDaemon(config) {
|
|
|
57361
57516
|
import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
|
|
57362
57517
|
import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
57363
57518
|
];
|
|
57364
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
57519
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57365
57520
|
let shiftMcpConfigPath2;
|
|
57366
57521
|
if (shiftServerScriptPath) {
|
|
57367
57522
|
const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
|
|
@@ -57381,6 +57536,27 @@ async function startDaemon(config) {
|
|
|
57381
57536
|
{ tried: shiftServerCandidates }
|
|
57382
57537
|
);
|
|
57383
57538
|
}
|
|
57539
|
+
const inboxServerCandidates = [
|
|
57540
|
+
import_node_path54.default.join(here, "inbox", "mcp-server.cjs"),
|
|
57541
|
+
import_node_path54.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
57542
|
+
];
|
|
57543
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
|
|
57544
|
+
let inboxMcpConfigPath2;
|
|
57545
|
+
if (inboxServerScriptPath) {
|
|
57546
|
+
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
57547
|
+
dataDir: config.dataDir,
|
|
57548
|
+
serverScriptPath: inboxServerScriptPath
|
|
57549
|
+
});
|
|
57550
|
+
logger.info("inbox.mcp.json written", {
|
|
57551
|
+
path: inboxMcpConfigPath2,
|
|
57552
|
+
server: inboxServerScriptPath
|
|
57553
|
+
});
|
|
57554
|
+
} else {
|
|
57555
|
+
logger.warn(
|
|
57556
|
+
"inbox-mcp-server.cjs not found; sendDm MCP tool disabled (dev tsx \u6A21\u5F0F\u4E0B\u9700\u5148\u8DD1\u8FC7 build)",
|
|
57557
|
+
{ tried: inboxServerCandidates }
|
|
57558
|
+
);
|
|
57559
|
+
}
|
|
57384
57560
|
const shiftStore = createShiftStore({
|
|
57385
57561
|
filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
|
|
57386
57562
|
ownerIdProvider: () => ownerPrincipalId,
|
|
@@ -57422,6 +57598,8 @@ async function startDaemon(config) {
|
|
|
57422
57598
|
// shift v1:所有 persona session 都挂 shift.mcp.json(不做 persona gating)。
|
|
57423
57599
|
// 缺省 = shift-mcp-server.cjs 没 build 出来,cc 看不到 shift tool 但 scheduler 仍跑。
|
|
57424
57600
|
shiftMcpConfigPath: shiftMcpConfigPath2,
|
|
57601
|
+
// sendDm MCP tool:所有 persona session 都挂 inbox.mcp.json(无 gating)。
|
|
57602
|
+
inboxMcpConfigPath: inboxMcpConfigPath2,
|
|
57425
57603
|
broadcastFrame: (frame, target) => {
|
|
57426
57604
|
if (target === "all") {
|
|
57427
57605
|
transport?.broadcastAll(frame);
|
|
@@ -57444,7 +57622,7 @@ async function startDaemon(config) {
|
|
|
57444
57622
|
const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
|
|
57445
57623
|
let size = 0;
|
|
57446
57624
|
try {
|
|
57447
|
-
size =
|
|
57625
|
+
size = import_node_fs42.default.statSync(absPath).size;
|
|
57448
57626
|
} catch (err) {
|
|
57449
57627
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
57450
57628
|
sessionId: input.sessionId,
|
|
@@ -57666,6 +57844,8 @@ async function startDaemon(config) {
|
|
|
57666
57844
|
inboxStore,
|
|
57667
57845
|
// 联系人列表 store(device:connect / 自动反向落同一 store)
|
|
57668
57846
|
contactStore,
|
|
57847
|
+
// inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
|
|
57848
|
+
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
57669
57849
|
// contact:removed broadcast;复用 capability:tokenIssued 同款通路
|
|
57670
57850
|
broadcastToOwners: (frame) => wsServer?.broadcastToOwners(frame),
|
|
57671
57851
|
// extension runtime (v1: local-mode only). Instance owned by daemon top
|
|
@@ -57801,7 +57981,7 @@ async function startDaemon(config) {
|
|
|
57801
57981
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
57802
57982
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
57803
57983
|
sourceJsonlPath = import_node_path54.default.join(
|
|
57804
|
-
|
|
57984
|
+
import_node_os20.default.homedir(),
|
|
57805
57985
|
".claude",
|
|
57806
57986
|
"projects",
|
|
57807
57987
|
cwdToHashDir(sourceFile.cwd),
|
|
@@ -58115,7 +58295,7 @@ ${bar}
|
|
|
58115
58295
|
`);
|
|
58116
58296
|
try {
|
|
58117
58297
|
const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
|
|
58118
|
-
|
|
58298
|
+
import_node_fs42.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
58119
58299
|
} catch {
|
|
58120
58300
|
}
|
|
58121
58301
|
} catch (err) {
|
|
@@ -58189,7 +58369,7 @@ ${bar}
|
|
|
58189
58369
|
function migrateDropPersonsDir(dataDir) {
|
|
58190
58370
|
const dir = import_node_path54.default.join(dataDir, "persons");
|
|
58191
58371
|
try {
|
|
58192
|
-
|
|
58372
|
+
import_node_fs42.default.rmSync(dir, { recursive: true, force: true });
|
|
58193
58373
|
} catch {
|
|
58194
58374
|
}
|
|
58195
58375
|
}
|