@clawos-dev/clawd 0.2.594 → 0.2.595
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/app-builder-plugin/mcp-server.cjs +17 -7
- package/dist/cli.cjs +711 -593
- package/dist/cloud-persona-conversations.html +11 -11
- package/dist/dispatch/mcp-server.cjs +17 -7
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +17 -7
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +17 -7
- package/dist/share-ui/assets/{guest-XBkJIDIi.js → guest-DV28bddQ.js} +51 -51
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
|
|
|
450
450
|
init_errors();
|
|
451
451
|
init_en();
|
|
452
452
|
makeIssue = (params) => {
|
|
453
|
-
const { data, path:
|
|
454
|
-
const fullPath = [...
|
|
453
|
+
const { data, path: path106, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path106, ...issueData.path || []];
|
|
455
455
|
const fullIssue = {
|
|
456
456
|
...issueData,
|
|
457
457
|
path: fullPath
|
|
@@ -762,11 +762,11 @@ var init_types = __esm({
|
|
|
762
762
|
init_parseUtil();
|
|
763
763
|
init_util();
|
|
764
764
|
ParseInputLazyPath = class {
|
|
765
|
-
constructor(parent, value,
|
|
765
|
+
constructor(parent, value, path106, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path106;
|
|
770
770
|
this._key = key;
|
|
771
771
|
}
|
|
772
772
|
get path() {
|
|
@@ -8144,8 +8144,8 @@ var init_schemas = __esm({
|
|
|
8144
8144
|
tui: external_exports.boolean(),
|
|
8145
8145
|
observe: external_exports.boolean(),
|
|
8146
8146
|
fileSharing: external_exports.boolean(),
|
|
8147
|
-
// fork:
|
|
8148
|
-
//
|
|
8147
|
+
// fork:Claude 派生 transcript JSONL;本机 Codex 按已完成 turn 调原生 thread/fork。
|
|
8148
|
+
// UI 只在有有效 fork 锚点的回复气泡上显示入口。
|
|
8149
8149
|
fork: external_exports.boolean()
|
|
8150
8150
|
});
|
|
8151
8151
|
CapabilitiesResponseSchema = external_exports.object({
|
|
@@ -8489,7 +8489,9 @@ var init_schemas = __esm({
|
|
|
8489
8489
|
kind: external_exports.literal("turn_end"),
|
|
8490
8490
|
// 本轮耗时(ms)。SDK=result.duration_ms;TUI=turn_duration.durationMs;缺失时 reducer 按 turnStartedAt 兜底
|
|
8491
8491
|
durationMs: external_exports.number().int().nonnegative().optional(),
|
|
8492
|
-
reason: external_exports.enum(TURN_END_REASONS).optional()
|
|
8492
|
+
reason: external_exports.enum(TURN_END_REASONS).optional(),
|
|
8493
|
+
/** Codex 完成轮次的原生 id;用于在该轮末条回复上显示 Fork / Quick Ask。 */
|
|
8494
|
+
turnId: external_exports.string().min(1).optional()
|
|
8493
8495
|
}),
|
|
8494
8496
|
// SDK system 帧 task_started / task_progress / task_notification 的归一化产物:
|
|
8495
8497
|
// 子 agent 执行过程中实时上报 agentId / lastToolName / stats,UI pending 期就能开抽屉、看进度。
|
|
@@ -8707,7 +8709,12 @@ var init_schemas = __esm({
|
|
|
8707
8709
|
SessionForkArgs = external_exports.object({
|
|
8708
8710
|
cwd: external_exports.string().min(1),
|
|
8709
8711
|
toolSessionId: external_exports.string().min(1),
|
|
8710
|
-
|
|
8712
|
+
/** Claude 消息 UUID;Codex 改用 turnId。 */
|
|
8713
|
+
messageUuid: external_exports.string().min(1).optional(),
|
|
8714
|
+
/** Codex 原生已完成 turn ID。 */
|
|
8715
|
+
turnId: external_exports.string().min(1).optional(),
|
|
8716
|
+
/** 源 clawd session ID;Codex 必填,handler 用它校验 thread 归属。 */
|
|
8717
|
+
sourceSessionId: external_exports.string().min(1).optional(),
|
|
8711
8718
|
/**
|
|
8712
8719
|
* 派生 jsonl 的落点 cwd(缺省 = 源文件所在目录,保持老行为)。
|
|
8713
8720
|
*
|
|
@@ -8718,7 +8725,7 @@ var init_schemas = __esm({
|
|
|
8718
8725
|
* 正确编排:先 sessionCreate 拿到 daemon 定的真实 cwd,再以它作 targetCwd fork。
|
|
8719
8726
|
*/
|
|
8720
8727
|
targetCwd: external_exports.string().min(1).optional()
|
|
8721
|
-
});
|
|
8728
|
+
}).refine((args) => Boolean(args.messageUuid || args.turnId), "messageUuid or turnId required");
|
|
8722
8729
|
SessionForkResponseSchema = external_exports.object({
|
|
8723
8730
|
forkedToolSessionId: external_exports.string().min(1),
|
|
8724
8731
|
forkedFilePath: external_exports.string().min(1)
|
|
@@ -9103,8 +9110,11 @@ var init_methods = __esm({
|
|
|
9103
9110
|
args: SessionIdArgs
|
|
9104
9111
|
},
|
|
9105
9112
|
"session:fork": {
|
|
9106
|
-
summary: "\u4ECE
|
|
9107
|
-
args: SessionForkArgs
|
|
9113
|
+
summary: "\u4ECE Claude \u6D88\u606F\u6216 Codex \u5DF2\u5B8C\u6210 turn \u6D3E\u751F\u65B0\u4F1A\u8BDD\uFF0C\u8FD4\u56DE\u65B0 toolSessionId\uFF1B\u4E0D\u81EA\u52A8\u62C9\u8D77\u4F1A\u8BDD\u8FDB\u7A0B",
|
|
9114
|
+
args: SessionForkArgs,
|
|
9115
|
+
argsConstraints: {
|
|
9116
|
+
anyOf: [{ required: ["messageUuid"] }, { required: ["turnId"] }]
|
|
9117
|
+
}
|
|
9108
9118
|
},
|
|
9109
9119
|
"session:new": {
|
|
9110
9120
|
summary: "\u5728**\u5DF2\u6709**\u4F1A\u8BDD\u4E0A\u6E05\u7A7A\u4E0A\u4E0B\u6587\u5F00\u65B0\u4E00\u8F6E\uFF0C\u76F8\u5F53\u4E8E CC \u7684 /clear\uFF08\u4E0D\u662F\u5EFA\u65B0\u4F1A\u8BDD\u2014\u2014\u5EFA\u65B0\u4F1A\u8BDD\u7528 session:create\uFF09",
|
|
@@ -10325,8 +10335,8 @@ var require_req = __commonJS({
|
|
|
10325
10335
|
if (req.originalUrl) {
|
|
10326
10336
|
_req.url = req.originalUrl;
|
|
10327
10337
|
} else {
|
|
10328
|
-
const
|
|
10329
|
-
_req.url = typeof
|
|
10338
|
+
const path106 = req.path;
|
|
10339
|
+
_req.url = typeof path106 === "string" ? path106 : req.url ? req.url.path || req.url : void 0;
|
|
10330
10340
|
}
|
|
10331
10341
|
if (req.query) {
|
|
10332
10342
|
_req.query = req.query;
|
|
@@ -10491,14 +10501,14 @@ var require_redact = __commonJS({
|
|
|
10491
10501
|
}
|
|
10492
10502
|
return obj;
|
|
10493
10503
|
}
|
|
10494
|
-
function parsePath(
|
|
10504
|
+
function parsePath(path106) {
|
|
10495
10505
|
const parts = [];
|
|
10496
10506
|
let current = "";
|
|
10497
10507
|
let inBrackets = false;
|
|
10498
10508
|
let inQuotes = false;
|
|
10499
10509
|
let quoteChar = "";
|
|
10500
|
-
for (let i2 = 0; i2 <
|
|
10501
|
-
const char =
|
|
10510
|
+
for (let i2 = 0; i2 < path106.length; i2++) {
|
|
10511
|
+
const char = path106[i2];
|
|
10502
10512
|
if (!inBrackets && char === ".") {
|
|
10503
10513
|
if (current) {
|
|
10504
10514
|
parts.push(current);
|
|
@@ -10629,10 +10639,10 @@ var require_redact = __commonJS({
|
|
|
10629
10639
|
return current;
|
|
10630
10640
|
}
|
|
10631
10641
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
10632
|
-
for (const
|
|
10633
|
-
const parts = parsePath(
|
|
10642
|
+
for (const path106 of paths) {
|
|
10643
|
+
const parts = parsePath(path106);
|
|
10634
10644
|
if (parts.includes("*")) {
|
|
10635
|
-
redactWildcardPath(obj, parts, censor,
|
|
10645
|
+
redactWildcardPath(obj, parts, censor, path106, remove);
|
|
10636
10646
|
} else {
|
|
10637
10647
|
if (remove) {
|
|
10638
10648
|
removeKey(obj, parts);
|
|
@@ -10717,8 +10727,8 @@ var require_redact = __commonJS({
|
|
|
10717
10727
|
}
|
|
10718
10728
|
} else {
|
|
10719
10729
|
if (afterWildcard.includes("*")) {
|
|
10720
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10721
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
10730
|
+
const wrappedCensor = typeof censor === "function" ? (value, path106) => {
|
|
10731
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path106];
|
|
10722
10732
|
return censor(value, fullPath);
|
|
10723
10733
|
} : censor;
|
|
10724
10734
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -10753,8 +10763,8 @@ var require_redact = __commonJS({
|
|
|
10753
10763
|
return null;
|
|
10754
10764
|
}
|
|
10755
10765
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
10756
|
-
for (const
|
|
10757
|
-
const parts = parsePath(
|
|
10766
|
+
for (const path106 of pathsToClone) {
|
|
10767
|
+
const parts = parsePath(path106);
|
|
10758
10768
|
let current = pathStructure;
|
|
10759
10769
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
10760
10770
|
const part = parts[i2];
|
|
@@ -10806,24 +10816,24 @@ var require_redact = __commonJS({
|
|
|
10806
10816
|
}
|
|
10807
10817
|
return cloneSelectively(obj, pathStructure);
|
|
10808
10818
|
}
|
|
10809
|
-
function validatePath(
|
|
10810
|
-
if (typeof
|
|
10819
|
+
function validatePath(path106) {
|
|
10820
|
+
if (typeof path106 !== "string") {
|
|
10811
10821
|
throw new Error("Paths must be (non-empty) strings");
|
|
10812
10822
|
}
|
|
10813
|
-
if (
|
|
10823
|
+
if (path106 === "") {
|
|
10814
10824
|
throw new Error("Invalid redaction path ()");
|
|
10815
10825
|
}
|
|
10816
|
-
if (
|
|
10817
|
-
throw new Error(`Invalid redaction path (${
|
|
10826
|
+
if (path106.includes("..")) {
|
|
10827
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10818
10828
|
}
|
|
10819
|
-
if (
|
|
10820
|
-
throw new Error(`Invalid redaction path (${
|
|
10829
|
+
if (path106.includes(",")) {
|
|
10830
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10821
10831
|
}
|
|
10822
10832
|
let bracketCount = 0;
|
|
10823
10833
|
let inQuotes = false;
|
|
10824
10834
|
let quoteChar = "";
|
|
10825
|
-
for (let i2 = 0; i2 <
|
|
10826
|
-
const char =
|
|
10835
|
+
for (let i2 = 0; i2 < path106.length; i2++) {
|
|
10836
|
+
const char = path106[i2];
|
|
10827
10837
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
10828
10838
|
if (!inQuotes) {
|
|
10829
10839
|
inQuotes = true;
|
|
@@ -10837,20 +10847,20 @@ var require_redact = __commonJS({
|
|
|
10837
10847
|
} else if (char === "]" && !inQuotes) {
|
|
10838
10848
|
bracketCount--;
|
|
10839
10849
|
if (bracketCount < 0) {
|
|
10840
|
-
throw new Error(`Invalid redaction path (${
|
|
10850
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10841
10851
|
}
|
|
10842
10852
|
}
|
|
10843
10853
|
}
|
|
10844
10854
|
if (bracketCount !== 0) {
|
|
10845
|
-
throw new Error(`Invalid redaction path (${
|
|
10855
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10846
10856
|
}
|
|
10847
10857
|
}
|
|
10848
10858
|
function validatePaths(paths) {
|
|
10849
10859
|
if (!Array.isArray(paths)) {
|
|
10850
10860
|
throw new TypeError("paths must be an array");
|
|
10851
10861
|
}
|
|
10852
|
-
for (const
|
|
10853
|
-
validatePath(
|
|
10862
|
+
for (const path106 of paths) {
|
|
10863
|
+
validatePath(path106);
|
|
10854
10864
|
}
|
|
10855
10865
|
}
|
|
10856
10866
|
function slowRedact(options = {}) {
|
|
@@ -11018,8 +11028,8 @@ var require_redaction = __commonJS({
|
|
|
11018
11028
|
if (shape[k3] === null) {
|
|
11019
11029
|
o2[k3] = (value) => topCensor(value, [k3]);
|
|
11020
11030
|
} else {
|
|
11021
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
11022
|
-
return censor(value, [k3, ...
|
|
11031
|
+
const wrappedCensor = typeof censor === "function" ? (value, path106) => {
|
|
11032
|
+
return censor(value, [k3, ...path106]);
|
|
11023
11033
|
} : censor;
|
|
11024
11034
|
o2[k3] = Redact({
|
|
11025
11035
|
paths: shape[k3],
|
|
@@ -11237,10 +11247,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
11237
11247
|
var require_sonic_boom = __commonJS({
|
|
11238
11248
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
11239
11249
|
"use strict";
|
|
11240
|
-
var
|
|
11250
|
+
var fs95 = require("fs");
|
|
11241
11251
|
var EventEmitter2 = require("events");
|
|
11242
11252
|
var inherits = require("util").inherits;
|
|
11243
|
-
var
|
|
11253
|
+
var path106 = require("path");
|
|
11244
11254
|
var sleep2 = require_atomic_sleep();
|
|
11245
11255
|
var assert = require("assert");
|
|
11246
11256
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -11294,20 +11304,20 @@ var require_sonic_boom = __commonJS({
|
|
|
11294
11304
|
const mode = sonic.mode;
|
|
11295
11305
|
if (sonic.sync) {
|
|
11296
11306
|
try {
|
|
11297
|
-
if (sonic.mkdir)
|
|
11298
|
-
const fd =
|
|
11307
|
+
if (sonic.mkdir) fs95.mkdirSync(path106.dirname(file), { recursive: true });
|
|
11308
|
+
const fd = fs95.openSync(file, flags, mode);
|
|
11299
11309
|
fileOpened(null, fd);
|
|
11300
11310
|
} catch (err) {
|
|
11301
11311
|
fileOpened(err);
|
|
11302
11312
|
throw err;
|
|
11303
11313
|
}
|
|
11304
11314
|
} else if (sonic.mkdir) {
|
|
11305
|
-
|
|
11315
|
+
fs95.mkdir(path106.dirname(file), { recursive: true }, (err) => {
|
|
11306
11316
|
if (err) return fileOpened(err);
|
|
11307
|
-
|
|
11317
|
+
fs95.open(file, flags, mode, fileOpened);
|
|
11308
11318
|
});
|
|
11309
11319
|
} else {
|
|
11310
|
-
|
|
11320
|
+
fs95.open(file, flags, mode, fileOpened);
|
|
11311
11321
|
}
|
|
11312
11322
|
}
|
|
11313
11323
|
function SonicBoom(opts) {
|
|
@@ -11348,8 +11358,8 @@ var require_sonic_boom = __commonJS({
|
|
|
11348
11358
|
this.flush = flushBuffer;
|
|
11349
11359
|
this.flushSync = flushBufferSync;
|
|
11350
11360
|
this._actualWrite = actualWriteBuffer;
|
|
11351
|
-
fsWriteSync = () =>
|
|
11352
|
-
fsWrite = () =>
|
|
11361
|
+
fsWriteSync = () => fs95.writeSync(this.fd, this._writingBuf);
|
|
11362
|
+
fsWrite = () => fs95.write(this.fd, this._writingBuf, this.release);
|
|
11353
11363
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
11354
11364
|
this._writingBuf = "";
|
|
11355
11365
|
this.write = write;
|
|
@@ -11358,15 +11368,15 @@ var require_sonic_boom = __commonJS({
|
|
|
11358
11368
|
this._actualWrite = actualWrite;
|
|
11359
11369
|
fsWriteSync = () => {
|
|
11360
11370
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11361
|
-
return
|
|
11371
|
+
return fs95.writeSync(this.fd, this._writingBuf);
|
|
11362
11372
|
}
|
|
11363
|
-
return
|
|
11373
|
+
return fs95.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11364
11374
|
};
|
|
11365
11375
|
fsWrite = () => {
|
|
11366
11376
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11367
|
-
return
|
|
11377
|
+
return fs95.write(this.fd, this._writingBuf, this.release);
|
|
11368
11378
|
}
|
|
11369
|
-
return
|
|
11379
|
+
return fs95.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
11370
11380
|
};
|
|
11371
11381
|
} else {
|
|
11372
11382
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -11423,7 +11433,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11423
11433
|
}
|
|
11424
11434
|
}
|
|
11425
11435
|
if (this._fsync) {
|
|
11426
|
-
|
|
11436
|
+
fs95.fsyncSync(this.fd);
|
|
11427
11437
|
}
|
|
11428
11438
|
const len = this._len;
|
|
11429
11439
|
if (this._reopening) {
|
|
@@ -11537,7 +11547,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11537
11547
|
const onDrain = () => {
|
|
11538
11548
|
if (!this._fsync) {
|
|
11539
11549
|
try {
|
|
11540
|
-
|
|
11550
|
+
fs95.fsync(this.fd, (err) => {
|
|
11541
11551
|
this._flushPending = false;
|
|
11542
11552
|
cb(err);
|
|
11543
11553
|
});
|
|
@@ -11639,7 +11649,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11639
11649
|
const fd = this.fd;
|
|
11640
11650
|
this.once("ready", () => {
|
|
11641
11651
|
if (fd !== this.fd) {
|
|
11642
|
-
|
|
11652
|
+
fs95.close(fd, (err) => {
|
|
11643
11653
|
if (err) {
|
|
11644
11654
|
return this.emit("error", err);
|
|
11645
11655
|
}
|
|
@@ -11688,7 +11698,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11688
11698
|
buf = this._bufs[0];
|
|
11689
11699
|
}
|
|
11690
11700
|
try {
|
|
11691
|
-
const n2 = Buffer.isBuffer(buf) ?
|
|
11701
|
+
const n2 = Buffer.isBuffer(buf) ? fs95.writeSync(this.fd, buf) : fs95.writeSync(this.fd, buf, "utf8");
|
|
11692
11702
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
|
|
11693
11703
|
buf = releasedBufObj.writingBuf;
|
|
11694
11704
|
this._len = releasedBufObj.len;
|
|
@@ -11704,7 +11714,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11704
11714
|
}
|
|
11705
11715
|
}
|
|
11706
11716
|
try {
|
|
11707
|
-
|
|
11717
|
+
fs95.fsyncSync(this.fd);
|
|
11708
11718
|
} catch {
|
|
11709
11719
|
}
|
|
11710
11720
|
}
|
|
@@ -11725,7 +11735,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11725
11735
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
11726
11736
|
}
|
|
11727
11737
|
try {
|
|
11728
|
-
const n2 =
|
|
11738
|
+
const n2 = fs95.writeSync(this.fd, buf);
|
|
11729
11739
|
buf = buf.subarray(n2);
|
|
11730
11740
|
this._len = Math.max(this._len - n2, 0);
|
|
11731
11741
|
if (buf.length <= 0) {
|
|
@@ -11753,13 +11763,13 @@ var require_sonic_boom = __commonJS({
|
|
|
11753
11763
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
11754
11764
|
if (this.sync) {
|
|
11755
11765
|
try {
|
|
11756
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
11766
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs95.writeSync(this.fd, this._writingBuf) : fs95.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11757
11767
|
release2(null, written);
|
|
11758
11768
|
} catch (err) {
|
|
11759
11769
|
release2(err);
|
|
11760
11770
|
}
|
|
11761
11771
|
} else {
|
|
11762
|
-
|
|
11772
|
+
fs95.write(this.fd, this._writingBuf, release2);
|
|
11763
11773
|
}
|
|
11764
11774
|
}
|
|
11765
11775
|
function actualWriteBuffer() {
|
|
@@ -11768,7 +11778,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11768
11778
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
11769
11779
|
if (this.sync) {
|
|
11770
11780
|
try {
|
|
11771
|
-
const written =
|
|
11781
|
+
const written = fs95.writeSync(this.fd, this._writingBuf);
|
|
11772
11782
|
release2(null, written);
|
|
11773
11783
|
} catch (err) {
|
|
11774
11784
|
release2(err);
|
|
@@ -11777,7 +11787,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11777
11787
|
if (kCopyBuffer) {
|
|
11778
11788
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
11779
11789
|
}
|
|
11780
|
-
|
|
11790
|
+
fs95.write(this.fd, this._writingBuf, release2);
|
|
11781
11791
|
}
|
|
11782
11792
|
}
|
|
11783
11793
|
function actualClose(sonic) {
|
|
@@ -11793,12 +11803,12 @@ var require_sonic_boom = __commonJS({
|
|
|
11793
11803
|
sonic._lens = [];
|
|
11794
11804
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
11795
11805
|
try {
|
|
11796
|
-
|
|
11806
|
+
fs95.fsync(sonic.fd, closeWrapped);
|
|
11797
11807
|
} catch {
|
|
11798
11808
|
}
|
|
11799
11809
|
function closeWrapped() {
|
|
11800
11810
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
11801
|
-
|
|
11811
|
+
fs95.close(sonic.fd, done);
|
|
11802
11812
|
} else {
|
|
11803
11813
|
done();
|
|
11804
11814
|
}
|
|
@@ -14933,11 +14943,11 @@ var init_lib = __esm({
|
|
|
14933
14943
|
}
|
|
14934
14944
|
}
|
|
14935
14945
|
},
|
|
14936
|
-
addToPath: function addToPath(
|
|
14937
|
-
var last =
|
|
14946
|
+
addToPath: function addToPath(path106, added, removed, oldPosInc, options) {
|
|
14947
|
+
var last = path106.lastComponent;
|
|
14938
14948
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14939
14949
|
return {
|
|
14940
|
-
oldPos:
|
|
14950
|
+
oldPos: path106.oldPos + oldPosInc,
|
|
14941
14951
|
lastComponent: {
|
|
14942
14952
|
count: last.count + 1,
|
|
14943
14953
|
added,
|
|
@@ -14947,7 +14957,7 @@ var init_lib = __esm({
|
|
|
14947
14957
|
};
|
|
14948
14958
|
} else {
|
|
14949
14959
|
return {
|
|
14950
|
-
oldPos:
|
|
14960
|
+
oldPos: path106.oldPos + oldPosInc,
|
|
14951
14961
|
lastComponent: {
|
|
14952
14962
|
count: 1,
|
|
14953
14963
|
added,
|
|
@@ -15529,10 +15539,10 @@ function attachmentToHistoryMessage(o2, ts) {
|
|
|
15529
15539
|
const memories = raw.map((m3) => {
|
|
15530
15540
|
if (!m3 || typeof m3 !== "object") return null;
|
|
15531
15541
|
const rec6 = m3;
|
|
15532
|
-
const
|
|
15542
|
+
const path106 = typeof rec6.path === "string" ? rec6.path : null;
|
|
15533
15543
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
15534
|
-
if (!
|
|
15535
|
-
const entry = { path:
|
|
15544
|
+
if (!path106 || content == null) return null;
|
|
15545
|
+
const entry = { path: path106, content };
|
|
15536
15546
|
if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
|
|
15537
15547
|
return entry;
|
|
15538
15548
|
}).filter((m3) => m3 !== null);
|
|
@@ -16398,10 +16408,10 @@ function parseAttachment(obj) {
|
|
|
16398
16408
|
const memories = raw.map((m3) => {
|
|
16399
16409
|
if (!m3 || typeof m3 !== "object") return null;
|
|
16400
16410
|
const rec6 = m3;
|
|
16401
|
-
const
|
|
16411
|
+
const path106 = typeof rec6.path === "string" ? rec6.path : null;
|
|
16402
16412
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
16403
|
-
if (!
|
|
16404
|
-
const out = { path:
|
|
16413
|
+
if (!path106 || content == null) return null;
|
|
16414
|
+
const out = { path: path106, content };
|
|
16405
16415
|
if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
|
|
16406
16416
|
return out;
|
|
16407
16417
|
}).filter((m3) => m3 !== null);
|
|
@@ -37375,8 +37385,8 @@ var require_utils = __commonJS({
|
|
|
37375
37385
|
var result = transform[inputType][outputType](input);
|
|
37376
37386
|
return result;
|
|
37377
37387
|
};
|
|
37378
|
-
exports2.resolve = function(
|
|
37379
|
-
var parts =
|
|
37388
|
+
exports2.resolve = function(path106) {
|
|
37389
|
+
var parts = path106.split("/");
|
|
37380
37390
|
var result = [];
|
|
37381
37391
|
for (var index = 0; index < parts.length; index++) {
|
|
37382
37392
|
var part = parts[index];
|
|
@@ -43229,18 +43239,18 @@ var require_object = __commonJS({
|
|
|
43229
43239
|
var object = new ZipObject(name, zipObjectContent, o2);
|
|
43230
43240
|
this.files[name] = object;
|
|
43231
43241
|
};
|
|
43232
|
-
var parentFolder = function(
|
|
43233
|
-
if (
|
|
43234
|
-
|
|
43242
|
+
var parentFolder = function(path106) {
|
|
43243
|
+
if (path106.slice(-1) === "/") {
|
|
43244
|
+
path106 = path106.substring(0, path106.length - 1);
|
|
43235
43245
|
}
|
|
43236
|
-
var lastSlash =
|
|
43237
|
-
return lastSlash > 0 ?
|
|
43246
|
+
var lastSlash = path106.lastIndexOf("/");
|
|
43247
|
+
return lastSlash > 0 ? path106.substring(0, lastSlash) : "";
|
|
43238
43248
|
};
|
|
43239
|
-
var forceTrailingSlash = function(
|
|
43240
|
-
if (
|
|
43241
|
-
|
|
43249
|
+
var forceTrailingSlash = function(path106) {
|
|
43250
|
+
if (path106.slice(-1) !== "/") {
|
|
43251
|
+
path106 += "/";
|
|
43242
43252
|
}
|
|
43243
|
-
return
|
|
43253
|
+
return path106;
|
|
43244
43254
|
};
|
|
43245
43255
|
var folderAdd = function(name, createFolders) {
|
|
43246
43256
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -44242,7 +44252,7 @@ var require_lib3 = __commonJS({
|
|
|
44242
44252
|
// src/run-case/recorder.ts
|
|
44243
44253
|
function startRunCaseRecorder(opts) {
|
|
44244
44254
|
const now = opts.now ?? Date.now;
|
|
44245
|
-
const dir =
|
|
44255
|
+
const dir = import_node_path85.default.dirname(opts.recordPath);
|
|
44246
44256
|
let stream = null;
|
|
44247
44257
|
let closing = false;
|
|
44248
44258
|
let closedSettled = false;
|
|
@@ -44256,8 +44266,8 @@ function startRunCaseRecorder(opts) {
|
|
|
44256
44266
|
});
|
|
44257
44267
|
const ensureStream = () => {
|
|
44258
44268
|
if (stream) return stream;
|
|
44259
|
-
|
|
44260
|
-
stream =
|
|
44269
|
+
import_node_fs66.default.mkdirSync(dir, { recursive: true });
|
|
44270
|
+
stream = import_node_fs66.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
44261
44271
|
stream.on("close", () => closedResolve());
|
|
44262
44272
|
return stream;
|
|
44263
44273
|
};
|
|
@@ -44282,12 +44292,12 @@ function startRunCaseRecorder(opts) {
|
|
|
44282
44292
|
};
|
|
44283
44293
|
return { tap, close, closed };
|
|
44284
44294
|
}
|
|
44285
|
-
var
|
|
44295
|
+
var import_node_fs66, import_node_path85;
|
|
44286
44296
|
var init_recorder = __esm({
|
|
44287
44297
|
"src/run-case/recorder.ts"() {
|
|
44288
44298
|
"use strict";
|
|
44289
|
-
|
|
44290
|
-
|
|
44299
|
+
import_node_fs66 = __toESM(require("fs"), 1);
|
|
44300
|
+
import_node_path85 = __toESM(require("path"), 1);
|
|
44291
44301
|
}
|
|
44292
44302
|
});
|
|
44293
44303
|
|
|
@@ -44330,7 +44340,7 @@ var init_wire = __esm({
|
|
|
44330
44340
|
// src/run-case/controller.ts
|
|
44331
44341
|
async function runController(opts) {
|
|
44332
44342
|
const now = opts.now ?? Date.now;
|
|
44333
|
-
const cwd = opts.cwd ?? (0,
|
|
44343
|
+
const cwd = opts.cwd ?? (0, import_node_fs67.mkdtempSync)(import_node_path86.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
|
|
44334
44344
|
const ownsCwd = opts.cwd === void 0;
|
|
44335
44345
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
44336
44346
|
const spawnCtx = { cwd };
|
|
@@ -44491,19 +44501,19 @@ async function runController(opts) {
|
|
|
44491
44501
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
44492
44502
|
if (ownsCwd) {
|
|
44493
44503
|
try {
|
|
44494
|
-
(0,
|
|
44504
|
+
(0, import_node_fs67.rmSync)(cwd, { recursive: true, force: true });
|
|
44495
44505
|
} catch {
|
|
44496
44506
|
}
|
|
44497
44507
|
}
|
|
44498
44508
|
return exitCode ?? 0;
|
|
44499
44509
|
}
|
|
44500
|
-
var
|
|
44510
|
+
var import_node_fs67, import_node_os32, import_node_path86;
|
|
44501
44511
|
var init_controller = __esm({
|
|
44502
44512
|
"src/run-case/controller.ts"() {
|
|
44503
44513
|
"use strict";
|
|
44504
|
-
|
|
44514
|
+
import_node_fs67 = require("fs");
|
|
44505
44515
|
import_node_os32 = __toESM(require("os"), 1);
|
|
44506
|
-
|
|
44516
|
+
import_node_path86 = __toESM(require("path"), 1);
|
|
44507
44517
|
init_claude();
|
|
44508
44518
|
init_stdout_splitter();
|
|
44509
44519
|
init_permission_stdio();
|
|
@@ -44775,8 +44785,8 @@ Env (advanced):
|
|
|
44775
44785
|
`;
|
|
44776
44786
|
|
|
44777
44787
|
// src/index.ts
|
|
44778
|
-
var
|
|
44779
|
-
var
|
|
44788
|
+
var import_node_path84 = __toESM(require("path"), 1);
|
|
44789
|
+
var import_node_fs65 = __toESM(require("fs"), 1);
|
|
44780
44790
|
var import_node_os31 = __toESM(require("os"), 1);
|
|
44781
44791
|
var import_node_crypto26 = require("crypto");
|
|
44782
44792
|
var import_node_url6 = require("url");
|
|
@@ -50064,45 +50074,169 @@ var ProjectsStore = class {
|
|
|
50064
50074
|
|
|
50065
50075
|
// src/tools/codex-home.ts
|
|
50066
50076
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
50067
|
-
var
|
|
50068
|
-
|
|
50077
|
+
var path15 = __toESM(require("path"), 1);
|
|
50078
|
+
|
|
50079
|
+
// src/tools/transcript-search.ts
|
|
50080
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
50081
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
50082
|
+
var SNIPPET_PAD = 60;
|
|
50083
|
+
var INJECTED_ENVELOPE_RE = /^<(system-reminder|command-name|command-message|command-args|local-command-stdout|local-command-stderr|task-notification|user-prompt-submit-hook|environment_context|user_instructions)\b/;
|
|
50084
|
+
var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
|
|
50085
|
+
function asRecord(v3) {
|
|
50086
|
+
return typeof v3 === "object" && v3 !== null ? v3 : null;
|
|
50087
|
+
}
|
|
50088
|
+
function textOfBlocks(content, types) {
|
|
50089
|
+
if (!Array.isArray(content)) return null;
|
|
50090
|
+
const parts = [];
|
|
50091
|
+
for (const block of content) {
|
|
50092
|
+
const b3 = asRecord(block);
|
|
50093
|
+
if (!b3 || typeof b3.type !== "string" || !types.includes(b3.type)) continue;
|
|
50094
|
+
const text = b3.text;
|
|
50095
|
+
if (typeof text === "string" && text !== "") parts.push(text);
|
|
50096
|
+
}
|
|
50097
|
+
return parts.length > 0 ? parts.join("\n") : null;
|
|
50098
|
+
}
|
|
50099
|
+
function lineToSearchableText(raw) {
|
|
50100
|
+
const line = asRecord(raw);
|
|
50101
|
+
if (!line) return null;
|
|
50102
|
+
if (line.type === "response_item") {
|
|
50103
|
+
const payload = asRecord(line.payload);
|
|
50104
|
+
if (!payload || payload.type !== "message") return null;
|
|
50105
|
+
const role = payload.role;
|
|
50106
|
+
if (role !== "user" && role !== "assistant") return null;
|
|
50107
|
+
const text2 = textOfBlocks(payload.content, ["input_text", "output_text"]);
|
|
50108
|
+
if (text2 === null) return null;
|
|
50109
|
+
if (role !== "user") return text2;
|
|
50110
|
+
const stripped = text2.replace(CODEX_WRAPPER_RE, "").trim();
|
|
50111
|
+
if (stripped === "") return null;
|
|
50112
|
+
return INJECTED_ENVELOPE_RE.test(stripped) ? null : stripped;
|
|
50113
|
+
}
|
|
50114
|
+
if (line.type !== "user" && line.type !== "assistant") return null;
|
|
50115
|
+
const message = asRecord(line.message);
|
|
50116
|
+
if (!message) return null;
|
|
50117
|
+
const content = message.content;
|
|
50118
|
+
const text = typeof content === "string" && content !== "" ? content : textOfBlocks(content, ["text"]);
|
|
50119
|
+
if (text === null) return null;
|
|
50120
|
+
if (line.type === "user" && (line.isMeta === true || line.isSynthetic === true)) return null;
|
|
50121
|
+
if (line.type === "user" && INJECTED_ENVELOPE_RE.test(text.trimStart())) return null;
|
|
50122
|
+
return text;
|
|
50123
|
+
}
|
|
50124
|
+
function escapeRegExp(s2) {
|
|
50125
|
+
return s2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
50126
|
+
}
|
|
50127
|
+
function makeSnippet(text, at3, needleLength) {
|
|
50128
|
+
const from = Math.max(0, at3 - SNIPPET_PAD);
|
|
50129
|
+
const to = Math.min(text.length, at3 + needleLength + SNIPPET_PAD);
|
|
50130
|
+
const body = text.slice(from, to).replace(/\s+/g, " ").trim();
|
|
50131
|
+
return `${from > 0 ? "\u2026 " : ""}${body}${to < text.length ? " \u2026" : ""}`;
|
|
50132
|
+
}
|
|
50133
|
+
function searchTranscriptFile(file, query) {
|
|
50134
|
+
let buf;
|
|
50135
|
+
try {
|
|
50136
|
+
buf = import_node_fs10.default.readFileSync(file);
|
|
50137
|
+
} catch {
|
|
50138
|
+
return null;
|
|
50139
|
+
}
|
|
50140
|
+
const haystack = buf.toString("latin1");
|
|
50141
|
+
const needle = Buffer.from(query, "utf8").toString("latin1");
|
|
50142
|
+
const re2 = new RegExp(escapeRegExp(needle), "gi");
|
|
50143
|
+
let m3;
|
|
50144
|
+
while ((m3 = re2.exec(haystack)) !== null) {
|
|
50145
|
+
const lineStart = haystack.lastIndexOf("\n", m3.index) + 1;
|
|
50146
|
+
let lineEnd = haystack.indexOf("\n", m3.index);
|
|
50147
|
+
if (lineEnd < 0) lineEnd = haystack.length;
|
|
50148
|
+
re2.lastIndex = lineEnd + 1;
|
|
50149
|
+
let parsed;
|
|
50150
|
+
try {
|
|
50151
|
+
parsed = JSON.parse(Buffer.from(haystack.slice(lineStart, lineEnd), "latin1").toString("utf8"));
|
|
50152
|
+
} catch {
|
|
50153
|
+
continue;
|
|
50154
|
+
}
|
|
50155
|
+
const text = lineToSearchableText(parsed);
|
|
50156
|
+
if (text === null) continue;
|
|
50157
|
+
const at3 = text.toLowerCase().indexOf(query.toLowerCase());
|
|
50158
|
+
if (at3 < 0) continue;
|
|
50159
|
+
return makeSnippet(text, at3, query.length);
|
|
50160
|
+
}
|
|
50161
|
+
return null;
|
|
50162
|
+
}
|
|
50163
|
+
var ROLLOUT_NAME_RE = /-([0-9a-fA-F-]{36})\.jsonl$/;
|
|
50164
|
+
function createCodexRolloutLocator(roots) {
|
|
50165
|
+
let index = null;
|
|
50166
|
+
const walk2 = (dir, into) => {
|
|
50167
|
+
let entries;
|
|
50168
|
+
try {
|
|
50169
|
+
entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
|
|
50170
|
+
} catch {
|
|
50171
|
+
return;
|
|
50172
|
+
}
|
|
50173
|
+
for (const entry of entries) {
|
|
50174
|
+
const full = import_node_path10.default.join(dir, entry.name);
|
|
50175
|
+
if (entry.isDirectory()) {
|
|
50176
|
+
walk2(full, into);
|
|
50177
|
+
continue;
|
|
50178
|
+
}
|
|
50179
|
+
const matched = ROLLOUT_NAME_RE.exec(entry.name);
|
|
50180
|
+
if (matched) into.set(matched[1].toLowerCase(), full);
|
|
50181
|
+
}
|
|
50182
|
+
};
|
|
50183
|
+
return (toolSessionId) => {
|
|
50184
|
+
if (index === null) {
|
|
50185
|
+
index = /* @__PURE__ */ new Map();
|
|
50186
|
+
for (const root of roots) walk2(root, index);
|
|
50187
|
+
}
|
|
50188
|
+
return index.get(toolSessionId.toLowerCase()) ?? null;
|
|
50189
|
+
};
|
|
50190
|
+
}
|
|
50191
|
+
|
|
50192
|
+
// src/tools/codex-home.ts
|
|
50193
|
+
var norm = (p3) => path15.resolve(p3);
|
|
50069
50194
|
function resolveCodexHome(input) {
|
|
50070
50195
|
const cwd = norm(input.cwd);
|
|
50071
|
-
const rel =
|
|
50072
|
-
const isPersonaRoot = rel !== "" && !rel.startsWith("..") && !
|
|
50196
|
+
const rel = path15.relative(norm(input.personaRoot), cwd);
|
|
50197
|
+
const isPersonaRoot = rel !== "" && !rel.startsWith("..") && !path15.isAbsolute(rel) && !rel.includes(path15.sep);
|
|
50073
50198
|
if (isPersonaRoot) return input.sharedHome;
|
|
50074
50199
|
if (input.projectPaths.some((p3) => norm(p3) === cwd)) return input.sharedHome;
|
|
50075
50200
|
return input.isolatedHome;
|
|
50076
50201
|
}
|
|
50077
|
-
function codexRolloutRoots(dataDir, sharedHome =
|
|
50078
|
-
const roots = [
|
|
50079
|
-
if (dataDir) roots.push(
|
|
50202
|
+
function codexRolloutRoots(dataDir, sharedHome = path15.join(import_node_os6.default.homedir(), ".codex")) {
|
|
50203
|
+
const roots = [path15.join(sharedHome, "sessions")];
|
|
50204
|
+
if (dataDir) roots.push(path15.join(dataDir, "codex-home", "sessions"));
|
|
50080
50205
|
return roots;
|
|
50081
50206
|
}
|
|
50207
|
+
function locateCodexThread(roots, threadId) {
|
|
50208
|
+
const file = createCodexRolloutLocator(roots)(threadId);
|
|
50209
|
+
if (!file) return null;
|
|
50210
|
+
const root = roots.find((candidate) => {
|
|
50211
|
+
const relative5 = path15.relative(candidate, file);
|
|
50212
|
+
return relative5 !== "" && !relative5.startsWith("..") && !path15.isAbsolute(relative5);
|
|
50213
|
+
});
|
|
50214
|
+
return root ? { file, home: path15.dirname(root) } : null;
|
|
50215
|
+
}
|
|
50082
50216
|
|
|
50083
50217
|
// src/persona/store.ts
|
|
50084
|
-
var
|
|
50085
|
-
var
|
|
50218
|
+
var fs13 = __toESM(require("fs"), 1);
|
|
50219
|
+
var path16 = __toESM(require("path"), 1);
|
|
50086
50220
|
init_protocol();
|
|
50087
50221
|
var PersonaStore = class {
|
|
50088
50222
|
constructor(root) {
|
|
50089
50223
|
this.root = root;
|
|
50090
|
-
|
|
50224
|
+
fs13.mkdirSync(root, { recursive: true });
|
|
50091
50225
|
}
|
|
50092
50226
|
root;
|
|
50093
50227
|
personaDir(personaId2) {
|
|
50094
|
-
return
|
|
50228
|
+
return path16.join(this.root, safeFileName(personaId2));
|
|
50095
50229
|
}
|
|
50096
50230
|
metaPath(personaId2) {
|
|
50097
|
-
return
|
|
50231
|
+
return path16.join(this.personaDir(personaId2), ".clawd", "persona.json");
|
|
50098
50232
|
}
|
|
50099
50233
|
claudeMdPath(personaId2) {
|
|
50100
|
-
return
|
|
50234
|
+
return path16.join(this.personaDir(personaId2), "CLAUDE.md");
|
|
50101
50235
|
}
|
|
50102
50236
|
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
50103
50237
|
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
50104
50238
|
agentsMdPath(personaId2) {
|
|
50105
|
-
return
|
|
50239
|
+
return path16.join(this.personaDir(personaId2), "AGENTS.md");
|
|
50106
50240
|
}
|
|
50107
50241
|
/**
|
|
50108
50242
|
* persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
@@ -50111,7 +50245,7 @@ var PersonaStore = class {
|
|
|
50111
50245
|
* spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
|
|
50112
50246
|
*/
|
|
50113
50247
|
sandboxSettingsPath(personaId2) {
|
|
50114
|
-
return
|
|
50248
|
+
return path16.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
|
|
50115
50249
|
}
|
|
50116
50250
|
/**
|
|
50117
50251
|
* 人格补充层落盘路径 —— `<personaDir>/.clawd/personality.local.md`。
|
|
@@ -50126,11 +50260,11 @@ var PersonaStore = class {
|
|
|
50126
50260
|
* (见 local-personality-prompt.ts),通道唯一,不会被当第二份 CLAUDE.md 重复加载。
|
|
50127
50261
|
*/
|
|
50128
50262
|
personalityLocalPath(personaId2) {
|
|
50129
|
-
return
|
|
50263
|
+
return path16.join(this.personaDir(personaId2), ".clawd", "personality.local.md");
|
|
50130
50264
|
}
|
|
50131
50265
|
write(persona, personality) {
|
|
50132
50266
|
const dir = this.personaDir(persona.personaId);
|
|
50133
|
-
|
|
50267
|
+
fs13.mkdirSync(path16.join(dir, ".clawd"), { recursive: true });
|
|
50134
50268
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
50135
50269
|
this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
|
|
50136
50270
|
this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
|
|
@@ -50143,8 +50277,8 @@ var PersonaStore = class {
|
|
|
50143
50277
|
/** 读人格补充层正文;文件不存在返回 null(= 该 persona 没有补充,走内置人格)。 */
|
|
50144
50278
|
readPersonalityLocal(personaId2) {
|
|
50145
50279
|
const p3 = this.personalityLocalPath(personaId2);
|
|
50146
|
-
if (!
|
|
50147
|
-
return
|
|
50280
|
+
if (!fs13.existsSync(p3)) return null;
|
|
50281
|
+
return fs13.readFileSync(p3, "utf8");
|
|
50148
50282
|
}
|
|
50149
50283
|
/**
|
|
50150
50284
|
* 写人格补充层。**纯空白 = 清空**:删文件而不是留个空文件——「有没有补充」的唯一判据
|
|
@@ -50153,10 +50287,10 @@ var PersonaStore = class {
|
|
|
50153
50287
|
writePersonalityLocal(personaId2, body) {
|
|
50154
50288
|
const p3 = this.personalityLocalPath(personaId2);
|
|
50155
50289
|
if (!body.trim()) {
|
|
50156
|
-
|
|
50290
|
+
fs13.rmSync(p3, { force: true });
|
|
50157
50291
|
return;
|
|
50158
50292
|
}
|
|
50159
|
-
|
|
50293
|
+
fs13.mkdirSync(path16.dirname(p3), { recursive: true });
|
|
50160
50294
|
this.atomicWrite(p3, body);
|
|
50161
50295
|
}
|
|
50162
50296
|
/**
|
|
@@ -50168,9 +50302,9 @@ var PersonaStore = class {
|
|
|
50168
50302
|
ensureAgentsMirror(personaId2) {
|
|
50169
50303
|
const claudeMd = this.claudeMdPath(personaId2);
|
|
50170
50304
|
const agentsMd = this.agentsMdPath(personaId2);
|
|
50171
|
-
if (!
|
|
50172
|
-
if (
|
|
50173
|
-
this.atomicWrite(agentsMd,
|
|
50305
|
+
if (!fs13.existsSync(claudeMd)) return false;
|
|
50306
|
+
if (fs13.existsSync(agentsMd)) return false;
|
|
50307
|
+
this.atomicWrite(agentsMd, fs13.readFileSync(claudeMd, "utf8"));
|
|
50174
50308
|
return true;
|
|
50175
50309
|
}
|
|
50176
50310
|
/**
|
|
@@ -50220,22 +50354,22 @@ var PersonaStore = class {
|
|
|
50220
50354
|
};
|
|
50221
50355
|
}
|
|
50222
50356
|
codexSandboxSettingsPath(personaId2) {
|
|
50223
|
-
return
|
|
50357
|
+
return path16.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
|
|
50224
50358
|
}
|
|
50225
50359
|
/** 读 codex-sandbox.json;不存在/损坏 → null。 */
|
|
50226
50360
|
readCodexSandboxSettings(personaId2) {
|
|
50227
50361
|
const p3 = this.codexSandboxSettingsPath(personaId2);
|
|
50228
|
-
if (!
|
|
50362
|
+
if (!fs13.existsSync(p3)) return null;
|
|
50229
50363
|
try {
|
|
50230
|
-
return CodexSandboxSettingsSchema.parse(JSON.parse(
|
|
50364
|
+
return CodexSandboxSettingsSchema.parse(JSON.parse(fs13.readFileSync(p3, "utf8")));
|
|
50231
50365
|
} catch {
|
|
50232
50366
|
return null;
|
|
50233
50367
|
}
|
|
50234
50368
|
}
|
|
50235
50369
|
/** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
|
|
50236
50370
|
writeCodexSandboxSettings(personaId2, settings) {
|
|
50237
|
-
const dir =
|
|
50238
|
-
|
|
50371
|
+
const dir = path16.join(this.personaDir(personaId2), ".clawd");
|
|
50372
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
50239
50373
|
this.atomicWrite(this.codexSandboxSettingsPath(personaId2), JSON.stringify(settings, null, 2));
|
|
50240
50374
|
}
|
|
50241
50375
|
writeMeta(persona) {
|
|
@@ -50243,8 +50377,8 @@ var PersonaStore = class {
|
|
|
50243
50377
|
}
|
|
50244
50378
|
read(personaId2) {
|
|
50245
50379
|
const p3 = this.metaPath(personaId2);
|
|
50246
|
-
if (!
|
|
50247
|
-
const raw = JSON.parse(
|
|
50380
|
+
if (!fs13.existsSync(p3)) return null;
|
|
50381
|
+
const raw = JSON.parse(fs13.readFileSync(p3, "utf8"));
|
|
50248
50382
|
if (raw && typeof raw === "object" && "tokenMap" in raw) {
|
|
50249
50383
|
delete raw.tokenMap;
|
|
50250
50384
|
this.atomicWrite(p3, JSON.stringify(raw, null, 2));
|
|
@@ -50252,13 +50386,13 @@ var PersonaStore = class {
|
|
|
50252
50386
|
return PersonaFileSchema.parse(raw);
|
|
50253
50387
|
}
|
|
50254
50388
|
has(personaId2) {
|
|
50255
|
-
return
|
|
50389
|
+
return fs13.existsSync(this.metaPath(personaId2));
|
|
50256
50390
|
}
|
|
50257
50391
|
readPersonality(personaId2) {
|
|
50258
50392
|
const claudeMd = this.claudeMdPath(personaId2);
|
|
50259
|
-
if (
|
|
50393
|
+
if (fs13.existsSync(claudeMd)) return fs13.readFileSync(claudeMd, "utf8");
|
|
50260
50394
|
const agentsMd = this.agentsMdPath(personaId2);
|
|
50261
|
-
if (
|
|
50395
|
+
if (fs13.existsSync(agentsMd)) return fs13.readFileSync(agentsMd, "utf8");
|
|
50262
50396
|
return null;
|
|
50263
50397
|
}
|
|
50264
50398
|
/**
|
|
@@ -50267,23 +50401,23 @@ var PersonaStore = class {
|
|
|
50267
50401
|
*/
|
|
50268
50402
|
readSandboxSettings(personaId2) {
|
|
50269
50403
|
const p3 = this.sandboxSettingsPath(personaId2);
|
|
50270
|
-
if (!
|
|
50404
|
+
if (!fs13.existsSync(p3)) return null;
|
|
50271
50405
|
try {
|
|
50272
|
-
return JSON.parse(
|
|
50406
|
+
return JSON.parse(fs13.readFileSync(p3, "utf8"));
|
|
50273
50407
|
} catch {
|
|
50274
50408
|
return null;
|
|
50275
50409
|
}
|
|
50276
50410
|
}
|
|
50277
50411
|
/** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
|
|
50278
50412
|
skillsDir(personaId2) {
|
|
50279
|
-
return
|
|
50413
|
+
return path16.join(this.personaDir(personaId2), ".claude", "skills");
|
|
50280
50414
|
}
|
|
50281
50415
|
/**
|
|
50282
50416
|
* Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
|
|
50283
50417
|
* 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
|
|
50284
50418
|
*/
|
|
50285
50419
|
claudeSettingsPath(personaId2) {
|
|
50286
|
-
return
|
|
50420
|
+
return path16.join(this.personaDir(personaId2), ".claude", "settings.json");
|
|
50287
50421
|
}
|
|
50288
50422
|
/**
|
|
50289
50423
|
* 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
|
|
@@ -50298,10 +50432,10 @@ var PersonaStore = class {
|
|
|
50298
50432
|
*/
|
|
50299
50433
|
readEnabledPlugins(personaId2) {
|
|
50300
50434
|
const p3 = this.claudeSettingsPath(personaId2);
|
|
50301
|
-
if (!
|
|
50435
|
+
if (!fs13.existsSync(p3)) return [];
|
|
50302
50436
|
let raw;
|
|
50303
50437
|
try {
|
|
50304
|
-
raw = JSON.parse(
|
|
50438
|
+
raw = JSON.parse(fs13.readFileSync(p3, "utf8"));
|
|
50305
50439
|
} catch {
|
|
50306
50440
|
return [];
|
|
50307
50441
|
}
|
|
@@ -50315,22 +50449,22 @@ var PersonaStore = class {
|
|
|
50315
50449
|
return out;
|
|
50316
50450
|
}
|
|
50317
50451
|
list() {
|
|
50318
|
-
if (!
|
|
50319
|
-
return
|
|
50320
|
-
return
|
|
50452
|
+
if (!fs13.existsSync(this.root)) return [];
|
|
50453
|
+
return fs13.readdirSync(this.root).filter((name) => {
|
|
50454
|
+
return fs13.existsSync(path16.join(this.root, name, ".clawd", "persona.json"));
|
|
50321
50455
|
});
|
|
50322
50456
|
}
|
|
50323
50457
|
remove(personaId2) {
|
|
50324
50458
|
const dir = this.personaDir(personaId2);
|
|
50325
|
-
if (
|
|
50459
|
+
if (fs13.existsSync(dir)) fs13.rmSync(dir, { recursive: true, force: true });
|
|
50326
50460
|
}
|
|
50327
50461
|
personaDirPath(personaId2) {
|
|
50328
50462
|
return this.personaDir(personaId2);
|
|
50329
50463
|
}
|
|
50330
50464
|
atomicWrite(file, content) {
|
|
50331
50465
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
50332
|
-
|
|
50333
|
-
|
|
50466
|
+
fs13.writeFileSync(tmp, content, { mode: 384 });
|
|
50467
|
+
fs13.renameSync(tmp, file);
|
|
50334
50468
|
}
|
|
50335
50469
|
};
|
|
50336
50470
|
|
|
@@ -50384,8 +50518,8 @@ var PersonaRegistry = class {
|
|
|
50384
50518
|
};
|
|
50385
50519
|
|
|
50386
50520
|
// src/persona/seed.ts
|
|
50387
|
-
var
|
|
50388
|
-
var
|
|
50521
|
+
var fs14 = __toESM(require("fs"), 1);
|
|
50522
|
+
var path17 = __toESM(require("path"), 1);
|
|
50389
50523
|
var import_node_url = require("url");
|
|
50390
50524
|
init_protocol();
|
|
50391
50525
|
var import_meta = {};
|
|
@@ -50584,24 +50718,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
|
|
|
50584
50718
|
if (!argv1) return null;
|
|
50585
50719
|
let real = argv1;
|
|
50586
50720
|
try {
|
|
50587
|
-
real =
|
|
50721
|
+
real = fs14.realpathSync(argv1);
|
|
50588
50722
|
} catch {
|
|
50589
50723
|
}
|
|
50590
|
-
return
|
|
50724
|
+
return path17.resolve(path17.dirname(real), sibling);
|
|
50591
50725
|
}
|
|
50592
50726
|
function findDefaultsRoot(logger) {
|
|
50593
50727
|
const candidates = [];
|
|
50594
50728
|
try {
|
|
50595
|
-
const here =
|
|
50596
|
-
candidates.push(
|
|
50597
|
-
candidates.push(
|
|
50729
|
+
const here = path17.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
50730
|
+
candidates.push(path17.resolve(here, "defaults"));
|
|
50731
|
+
candidates.push(path17.resolve(here, "persona-defaults"));
|
|
50598
50732
|
} catch {
|
|
50599
50733
|
}
|
|
50600
50734
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
|
|
50601
50735
|
if (fromArgv) candidates.push(fromArgv);
|
|
50602
50736
|
for (const c2 of candidates) {
|
|
50603
50737
|
try {
|
|
50604
|
-
if (
|
|
50738
|
+
if (fs14.statSync(c2).isDirectory()) {
|
|
50605
50739
|
logger?.info("persona.defaults-root.resolved", { root: c2 });
|
|
50606
50740
|
return c2;
|
|
50607
50741
|
}
|
|
@@ -50618,8 +50752,8 @@ function seedDefaultPersonas(args) {
|
|
|
50618
50752
|
args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
|
|
50619
50753
|
continue;
|
|
50620
50754
|
}
|
|
50621
|
-
const bundleDir =
|
|
50622
|
-
if (!
|
|
50755
|
+
const bundleDir = path17.join(args.defaultsRoot, entry.personaId);
|
|
50756
|
+
if (!fs14.existsSync(bundleDir)) {
|
|
50623
50757
|
args.logger.warn("persona.seed.skip", {
|
|
50624
50758
|
personaId: entry.personaId,
|
|
50625
50759
|
reason: "bundle-missing",
|
|
@@ -50627,8 +50761,8 @@ function seedDefaultPersonas(args) {
|
|
|
50627
50761
|
});
|
|
50628
50762
|
continue;
|
|
50629
50763
|
}
|
|
50630
|
-
const claudeMdPath =
|
|
50631
|
-
if (!
|
|
50764
|
+
const claudeMdPath = path17.join(bundleDir, "CLAUDE.md");
|
|
50765
|
+
if (!fs14.existsSync(claudeMdPath)) {
|
|
50632
50766
|
args.logger.warn("persona.seed.skip", {
|
|
50633
50767
|
personaId: entry.personaId,
|
|
50634
50768
|
reason: "no-CLAUDE.md",
|
|
@@ -50636,7 +50770,7 @@ function seedDefaultPersonas(args) {
|
|
|
50636
50770
|
});
|
|
50637
50771
|
continue;
|
|
50638
50772
|
}
|
|
50639
|
-
const personality =
|
|
50773
|
+
const personality = fs14.readFileSync(claudeMdPath, "utf8");
|
|
50640
50774
|
const now = Date.now();
|
|
50641
50775
|
const persona = {
|
|
50642
50776
|
personaId: entry.personaId,
|
|
@@ -50663,51 +50797,51 @@ function seedDefaultPersonas(args) {
|
|
|
50663
50797
|
}
|
|
50664
50798
|
}
|
|
50665
50799
|
function skipNodeModulesUnder(srcRoot) {
|
|
50666
|
-
return (src) => !
|
|
50800
|
+
return (src) => !path17.relative(srcRoot, src).split(path17.sep).includes("node_modules");
|
|
50667
50801
|
}
|
|
50668
50802
|
function copyBundleExtras(srcDir, dstDir) {
|
|
50669
|
-
for (const entry of
|
|
50803
|
+
for (const entry of fs14.readdirSync(srcDir, { withFileTypes: true })) {
|
|
50670
50804
|
if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
|
|
50671
|
-
const srcPath =
|
|
50672
|
-
const dstPath =
|
|
50805
|
+
const srcPath = path17.join(srcDir, entry.name);
|
|
50806
|
+
const dstPath = path17.join(dstDir, entry.name);
|
|
50673
50807
|
if (entry.isDirectory()) {
|
|
50674
|
-
|
|
50808
|
+
fs14.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
50675
50809
|
} else if (entry.isFile()) {
|
|
50676
|
-
|
|
50810
|
+
fs14.copyFileSync(srcPath, dstPath);
|
|
50677
50811
|
}
|
|
50678
50812
|
}
|
|
50679
50813
|
}
|
|
50680
50814
|
var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills", ".claude/agents", "mcp"];
|
|
50681
50815
|
function replaceManagedPath(src, dst) {
|
|
50682
|
-
if (!
|
|
50683
|
-
|
|
50684
|
-
|
|
50685
|
-
|
|
50816
|
+
if (!fs14.statSync(src).isDirectory()) {
|
|
50817
|
+
fs14.mkdirSync(path17.dirname(dst), { recursive: true });
|
|
50818
|
+
fs14.rmSync(dst, { recursive: true, force: true });
|
|
50819
|
+
fs14.cpSync(src, dst, { dereference: true });
|
|
50686
50820
|
return;
|
|
50687
50821
|
}
|
|
50688
|
-
|
|
50689
|
-
for (const e of
|
|
50822
|
+
fs14.mkdirSync(dst, { recursive: true });
|
|
50823
|
+
for (const e of fs14.readdirSync(src, { withFileTypes: true })) {
|
|
50690
50824
|
if (e.name === "node_modules") continue;
|
|
50691
|
-
const child =
|
|
50692
|
-
|
|
50693
|
-
|
|
50825
|
+
const child = path17.join(dst, e.name);
|
|
50826
|
+
fs14.rmSync(child, { recursive: true, force: true });
|
|
50827
|
+
fs14.cpSync(path17.join(src, e.name), child, { recursive: true, dereference: true });
|
|
50694
50828
|
}
|
|
50695
50829
|
}
|
|
50696
50830
|
function refreshDaemonManagedDirs(args) {
|
|
50697
50831
|
const entries = args.entries ?? DEFAULT_PERSONAS;
|
|
50698
50832
|
for (const entry of entries) {
|
|
50699
|
-
const bundleDir =
|
|
50700
|
-
if (!
|
|
50833
|
+
const bundleDir = path17.join(args.defaultsRoot, entry.personaId);
|
|
50834
|
+
if (!fs14.existsSync(bundleDir)) continue;
|
|
50701
50835
|
const personaDir = args.store.personaDirPath(entry.personaId);
|
|
50702
|
-
if (!
|
|
50836
|
+
if (!fs14.existsSync(personaDir)) continue;
|
|
50703
50837
|
for (const relPath of DAEMON_MANAGED_PATHS) {
|
|
50704
|
-
const srcPath =
|
|
50705
|
-
if (!
|
|
50706
|
-
const dstPath =
|
|
50838
|
+
const srcPath = path17.join(bundleDir, relPath);
|
|
50839
|
+
if (!fs14.existsSync(srcPath)) continue;
|
|
50840
|
+
const dstPath = path17.join(personaDir, relPath);
|
|
50707
50841
|
try {
|
|
50708
50842
|
replaceManagedPath(srcPath, dstPath);
|
|
50709
50843
|
if (relPath === "CLAUDE.md") {
|
|
50710
|
-
replaceManagedPath(srcPath,
|
|
50844
|
+
replaceManagedPath(srcPath, path17.join(personaDir, "AGENTS.md"));
|
|
50711
50845
|
}
|
|
50712
50846
|
args.logger.info("persona.refresh.synced", {
|
|
50713
50847
|
personaId: entry.personaId,
|
|
@@ -50731,12 +50865,12 @@ function migratePersonalityOverlay(args) {
|
|
|
50731
50865
|
for (const entry of entries) {
|
|
50732
50866
|
const personaId2 = entry.personaId;
|
|
50733
50867
|
try {
|
|
50734
|
-
if (
|
|
50735
|
-
const bundleClaudeMd =
|
|
50736
|
-
if (!
|
|
50868
|
+
if (fs14.existsSync(args.store.personalityLocalPath(personaId2))) continue;
|
|
50869
|
+
const bundleClaudeMd = path17.join(args.defaultsRoot, personaId2, "CLAUDE.md");
|
|
50870
|
+
if (!fs14.existsSync(bundleClaudeMd)) continue;
|
|
50737
50871
|
const current = args.store.readPersonality(personaId2);
|
|
50738
50872
|
if (current === null) continue;
|
|
50739
|
-
const bundle =
|
|
50873
|
+
const bundle = fs14.readFileSync(bundleClaudeMd, "utf8");
|
|
50740
50874
|
if (current === bundle) continue;
|
|
50741
50875
|
if (!current.startsWith(bundle)) continue;
|
|
50742
50876
|
const tail2 = current.slice(bundle.length).trim();
|
|
@@ -50835,7 +50969,7 @@ function migrateSandboxAllowRead(args) {
|
|
|
50835
50969
|
for (const personaId2 of args.store.list()) {
|
|
50836
50970
|
try {
|
|
50837
50971
|
const readPath = tildePath(args.store.personaDirPath(personaId2));
|
|
50838
|
-
if (!
|
|
50972
|
+
if (!fs14.existsSync(args.store.sandboxSettingsPath(personaId2))) {
|
|
50839
50973
|
args.store.writeSandboxSettings(personaId2, buildGuestSettingsV1());
|
|
50840
50974
|
n2++;
|
|
50841
50975
|
continue;
|
|
@@ -50878,13 +51012,13 @@ var PERSONA_BUILDER_TOMBSTONE = `${PERSONA_BUILDER_TOMBSTONE_MARKER}
|
|
|
50878
51012
|
function containsAnyFile(dir) {
|
|
50879
51013
|
let entries;
|
|
50880
51014
|
try {
|
|
50881
|
-
entries =
|
|
51015
|
+
entries = fs14.readdirSync(dir, { withFileTypes: true });
|
|
50882
51016
|
} catch {
|
|
50883
51017
|
return false;
|
|
50884
51018
|
}
|
|
50885
51019
|
for (const e of entries) {
|
|
50886
51020
|
if (e.isDirectory()) {
|
|
50887
|
-
if (containsAnyFile(
|
|
51021
|
+
if (containsAnyFile(path17.join(dir, e.name))) return true;
|
|
50888
51022
|
} else {
|
|
50889
51023
|
return true;
|
|
50890
51024
|
}
|
|
@@ -50893,9 +51027,9 @@ function containsAnyFile(dir) {
|
|
|
50893
51027
|
}
|
|
50894
51028
|
function retirePersonaBuilder(args) {
|
|
50895
51029
|
const dir = args.store.personaDirPath(PERSONA_BUILDER_ID);
|
|
50896
|
-
if (!
|
|
51030
|
+
if (!fs14.existsSync(dir)) return;
|
|
50897
51031
|
try {
|
|
50898
|
-
const used = containsAnyFile(
|
|
51032
|
+
const used = containsAnyFile(path17.join(dir, ".clawd", "sessions")) || containsAnyFile(path17.join(dir, ".claude", "skills")) || containsAnyFile(path17.join(dir, "projects"));
|
|
50899
51033
|
if (!used) {
|
|
50900
51034
|
args.store.remove(PERSONA_BUILDER_ID);
|
|
50901
51035
|
args.logger.info("persona.retire-builder.removed", { personaId: PERSONA_BUILDER_ID });
|
|
@@ -50903,10 +51037,10 @@ function retirePersonaBuilder(args) {
|
|
|
50903
51037
|
}
|
|
50904
51038
|
let wrote = false;
|
|
50905
51039
|
for (const name of ["CLAUDE.md", "AGENTS.md"]) {
|
|
50906
|
-
const p3 =
|
|
50907
|
-
const cur =
|
|
51040
|
+
const p3 = path17.join(dir, name);
|
|
51041
|
+
const cur = fs14.existsSync(p3) ? fs14.readFileSync(p3, "utf8") : null;
|
|
50908
51042
|
if (cur?.startsWith(PERSONA_BUILDER_TOMBSTONE_MARKER)) continue;
|
|
50909
|
-
|
|
51043
|
+
fs14.writeFileSync(p3, PERSONA_BUILDER_TOMBSTONE);
|
|
50910
51044
|
wrote = true;
|
|
50911
51045
|
}
|
|
50912
51046
|
if (wrote) args.logger.info("persona.retire-builder.tombstoned", { personaId: PERSONA_BUILDER_ID });
|
|
@@ -50919,9 +51053,9 @@ function retirePersonaBuilder(args) {
|
|
|
50919
51053
|
}
|
|
50920
51054
|
|
|
50921
51055
|
// src/skills/scanner.ts
|
|
50922
|
-
var
|
|
51056
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
50923
51057
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
50924
|
-
var
|
|
51058
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
50925
51059
|
|
|
50926
51060
|
// src/skills/frontmatter.ts
|
|
50927
51061
|
var STRIP_QUOTES = /^["']|["']$/g;
|
|
@@ -51030,7 +51164,7 @@ function parseDescription(content) {
|
|
|
51030
51164
|
}
|
|
51031
51165
|
function isDirLikeSync(p3) {
|
|
51032
51166
|
try {
|
|
51033
|
-
return
|
|
51167
|
+
return import_node_fs11.default.statSync(p3).isDirectory();
|
|
51034
51168
|
} catch {
|
|
51035
51169
|
return false;
|
|
51036
51170
|
}
|
|
@@ -51038,19 +51172,19 @@ function isDirLikeSync(p3) {
|
|
|
51038
51172
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
51039
51173
|
let entries;
|
|
51040
51174
|
try {
|
|
51041
|
-
entries =
|
|
51175
|
+
entries = import_node_fs11.default.readdirSync(dir, { withFileTypes: true });
|
|
51042
51176
|
} catch {
|
|
51043
51177
|
return;
|
|
51044
51178
|
}
|
|
51045
51179
|
for (const ent of entries) {
|
|
51046
|
-
const entryPath =
|
|
51180
|
+
const entryPath = import_node_path11.default.join(dir, ent.name);
|
|
51047
51181
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
51048
51182
|
let content;
|
|
51049
51183
|
try {
|
|
51050
|
-
content =
|
|
51184
|
+
content = import_node_fs11.default.readFileSync(import_node_path11.default.join(entryPath, "SKILL.md"), "utf8");
|
|
51051
51185
|
} catch {
|
|
51052
51186
|
try {
|
|
51053
|
-
content =
|
|
51187
|
+
content = import_node_fs11.default.readFileSync(import_node_path11.default.join(entryPath, "skill.md"), "utf8");
|
|
51054
51188
|
} catch {
|
|
51055
51189
|
continue;
|
|
51056
51190
|
}
|
|
@@ -51074,26 +51208,26 @@ function listSkillsForDir(dir, source) {
|
|
|
51074
51208
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
51075
51209
|
let entries;
|
|
51076
51210
|
try {
|
|
51077
|
-
entries =
|
|
51211
|
+
entries = import_node_fs11.default.readdirSync(dir, { withFileTypes: true });
|
|
51078
51212
|
} catch {
|
|
51079
51213
|
return;
|
|
51080
51214
|
}
|
|
51081
51215
|
for (const ent of entries) {
|
|
51082
|
-
const entryPath =
|
|
51216
|
+
const entryPath = import_node_path11.default.join(dir, ent.name);
|
|
51083
51217
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
51084
51218
|
const ns = ent.name;
|
|
51085
51219
|
let subEntries;
|
|
51086
51220
|
try {
|
|
51087
|
-
subEntries =
|
|
51221
|
+
subEntries = import_node_fs11.default.readdirSync(entryPath, { withFileTypes: true });
|
|
51088
51222
|
} catch {
|
|
51089
51223
|
continue;
|
|
51090
51224
|
}
|
|
51091
51225
|
for (const se2 of subEntries) {
|
|
51092
51226
|
if (!se2.name.endsWith(".md")) continue;
|
|
51093
|
-
const sePath =
|
|
51227
|
+
const sePath = import_node_path11.default.join(entryPath, se2.name);
|
|
51094
51228
|
let content;
|
|
51095
51229
|
try {
|
|
51096
|
-
content =
|
|
51230
|
+
content = import_node_fs11.default.readFileSync(sePath, "utf8");
|
|
51097
51231
|
} catch {
|
|
51098
51232
|
continue;
|
|
51099
51233
|
}
|
|
@@ -51110,7 +51244,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
51110
51244
|
} else if (ent.name.endsWith(".md")) {
|
|
51111
51245
|
let content;
|
|
51112
51246
|
try {
|
|
51113
|
-
content =
|
|
51247
|
+
content = import_node_fs11.default.readFileSync(entryPath, "utf8");
|
|
51114
51248
|
} catch {
|
|
51115
51249
|
continue;
|
|
51116
51250
|
}
|
|
@@ -51126,10 +51260,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
51126
51260
|
}
|
|
51127
51261
|
}
|
|
51128
51262
|
function readInstalledPlugins(home) {
|
|
51129
|
-
const file =
|
|
51263
|
+
const file = import_node_path11.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
51130
51264
|
let raw;
|
|
51131
51265
|
try {
|
|
51132
|
-
raw =
|
|
51266
|
+
raw = import_node_fs11.default.readFileSync(file, "utf8");
|
|
51133
51267
|
} catch {
|
|
51134
51268
|
return [];
|
|
51135
51269
|
}
|
|
@@ -51177,14 +51311,14 @@ var SkillsScanner = class {
|
|
|
51177
51311
|
});
|
|
51178
51312
|
}
|
|
51179
51313
|
const fsBlock = [];
|
|
51180
|
-
scanSkillDir(
|
|
51181
|
-
scanCommandDir(
|
|
51182
|
-
scanSkillDir(
|
|
51183
|
-
scanCommandDir(
|
|
51314
|
+
scanSkillDir(import_node_path11.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
|
|
51315
|
+
scanCommandDir(import_node_path11.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
|
|
51316
|
+
scanSkillDir(import_node_path11.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
|
|
51317
|
+
scanCommandDir(import_node_path11.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
|
|
51184
51318
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
51185
51319
|
for (const { name, root } of plugins) {
|
|
51186
|
-
scanSkillDir(
|
|
51187
|
-
scanCommandDir(
|
|
51320
|
+
scanSkillDir(import_node_path11.default.join(root, "skills"), "plugin", seen, fsBlock, name);
|
|
51321
|
+
scanCommandDir(import_node_path11.default.join(root, "commands"), "plugin", seen, fsBlock, name);
|
|
51188
51322
|
}
|
|
51189
51323
|
fsBlock.sort((a2, b3) => a2.name < b3.name ? -1 : a2.name > b3.name ? 1 : 0);
|
|
51190
51324
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -51326,12 +51460,12 @@ var PersonaManager = class {
|
|
|
51326
51460
|
};
|
|
51327
51461
|
|
|
51328
51462
|
// src/share-md-viewer/load.ts
|
|
51329
|
-
var
|
|
51330
|
-
var
|
|
51463
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
51464
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
51331
51465
|
var import_node_url2 = require("url");
|
|
51332
51466
|
|
|
51333
51467
|
// src/share-md-viewer/asset-loader.ts
|
|
51334
|
-
var
|
|
51468
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
51335
51469
|
function htmlEscape(s2) {
|
|
51336
51470
|
return s2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
51337
51471
|
}
|
|
@@ -51339,12 +51473,12 @@ function createViewerAssetLoader(opts) {
|
|
|
51339
51473
|
let viewerTemplate;
|
|
51340
51474
|
let errorTemplate;
|
|
51341
51475
|
try {
|
|
51342
|
-
viewerTemplate =
|
|
51476
|
+
viewerTemplate = import_node_fs12.default.readFileSync(opts.viewerHtmlPath, "utf8");
|
|
51343
51477
|
} catch (err) {
|
|
51344
51478
|
throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
|
|
51345
51479
|
}
|
|
51346
51480
|
try {
|
|
51347
|
-
errorTemplate =
|
|
51481
|
+
errorTemplate = import_node_fs12.default.readFileSync(opts.errorHtmlPath, "utf8");
|
|
51348
51482
|
} catch (err) {
|
|
51349
51483
|
throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
|
|
51350
51484
|
}
|
|
@@ -51363,25 +51497,25 @@ var import_meta2 = {};
|
|
|
51363
51497
|
function tryLoadViewerAssets(logger) {
|
|
51364
51498
|
const candidates = [];
|
|
51365
51499
|
try {
|
|
51366
|
-
const here =
|
|
51500
|
+
const here = import_node_path12.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
51367
51501
|
candidates.push(here);
|
|
51368
|
-
candidates.push(
|
|
51369
|
-
candidates.push(
|
|
51502
|
+
candidates.push(import_node_path12.default.resolve(here, ".."));
|
|
51503
|
+
candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
|
|
51370
51504
|
} catch {
|
|
51371
51505
|
}
|
|
51372
51506
|
if (process.argv[1]) {
|
|
51373
51507
|
let real = process.argv[1];
|
|
51374
51508
|
try {
|
|
51375
|
-
real =
|
|
51509
|
+
real = import_node_fs13.default.realpathSync(process.argv[1]);
|
|
51376
51510
|
} catch {
|
|
51377
51511
|
}
|
|
51378
|
-
candidates.push(
|
|
51512
|
+
candidates.push(import_node_path12.default.dirname(real));
|
|
51379
51513
|
}
|
|
51380
51514
|
for (const root of candidates) {
|
|
51381
|
-
const viewerHtmlPath =
|
|
51382
|
-
const errorHtmlPath =
|
|
51515
|
+
const viewerHtmlPath = import_node_path12.default.join(root, "share-md-viewer.html");
|
|
51516
|
+
const errorHtmlPath = import_node_path12.default.join(root, "share-md-viewer-error.html");
|
|
51383
51517
|
try {
|
|
51384
|
-
if (
|
|
51518
|
+
if (import_node_fs13.default.statSync(viewerHtmlPath).isFile() && import_node_fs13.default.statSync(errorHtmlPath).isFile()) {
|
|
51385
51519
|
logger?.info("share-md-viewer.assets-root.resolved", { root });
|
|
51386
51520
|
return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
|
|
51387
51521
|
}
|
|
@@ -51396,25 +51530,25 @@ function tryLoadViewerAssets(logger) {
|
|
|
51396
51530
|
}
|
|
51397
51531
|
|
|
51398
51532
|
// src/dashboard/load.ts
|
|
51399
|
-
var
|
|
51400
|
-
var
|
|
51533
|
+
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
51534
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
51401
51535
|
var import_node_url3 = require("url");
|
|
51402
51536
|
init_protocol();
|
|
51403
51537
|
var import_meta3 = {};
|
|
51404
51538
|
function candidateRoots() {
|
|
51405
51539
|
const roots = [];
|
|
51406
51540
|
try {
|
|
51407
|
-
const here =
|
|
51408
|
-
roots.push(here,
|
|
51541
|
+
const here = import_node_path13.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
51542
|
+
roots.push(here, import_node_path13.default.resolve(here, ".."), import_node_path13.default.resolve(here, "..", "..", "dist"));
|
|
51409
51543
|
} catch {
|
|
51410
51544
|
}
|
|
51411
51545
|
if (process.argv[1]) {
|
|
51412
51546
|
let real = process.argv[1];
|
|
51413
51547
|
try {
|
|
51414
|
-
real =
|
|
51548
|
+
real = import_node_fs14.default.realpathSync(process.argv[1]);
|
|
51415
51549
|
} catch {
|
|
51416
51550
|
}
|
|
51417
|
-
roots.push(
|
|
51551
|
+
roots.push(import_node_path13.default.dirname(real));
|
|
51418
51552
|
}
|
|
51419
51553
|
return roots;
|
|
51420
51554
|
}
|
|
@@ -51422,10 +51556,10 @@ function loadDashboardPages(logger, roots = candidateRoots()) {
|
|
|
51422
51556
|
const pages = /* @__PURE__ */ new Map();
|
|
51423
51557
|
for (const page of DASHBOARD_PAGES) {
|
|
51424
51558
|
for (const root of roots) {
|
|
51425
|
-
const file =
|
|
51559
|
+
const file = import_node_path13.default.join(root, `${page}.html`);
|
|
51426
51560
|
try {
|
|
51427
|
-
if (
|
|
51428
|
-
pages.set(page,
|
|
51561
|
+
if (import_node_fs14.default.statSync(file).isFile()) {
|
|
51562
|
+
pages.set(page, import_node_fs14.default.readFileSync(file, "utf8"));
|
|
51429
51563
|
logger?.info("dashboard.page-asset.resolved", { page, root });
|
|
51430
51564
|
break;
|
|
51431
51565
|
}
|
|
@@ -51775,7 +51909,8 @@ function parseCodexRollout(text) {
|
|
|
51775
51909
|
kind: "turn-end",
|
|
51776
51910
|
raw: obj,
|
|
51777
51911
|
...ts ? { ts } : {},
|
|
51778
|
-
...durationMs !== void 0 ? { durationMs } : {}
|
|
51912
|
+
...durationMs !== void 0 ? { durationMs } : {},
|
|
51913
|
+
...p3.type === "task_complete" && turnId ? { turnId } : {}
|
|
51779
51914
|
});
|
|
51780
51915
|
break;
|
|
51781
51916
|
}
|
|
@@ -51843,121 +51978,6 @@ function subagentTerminalResult(started, child) {
|
|
|
51843
51978
|
// src/tools/codex-history.ts
|
|
51844
51979
|
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
51845
51980
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
51846
|
-
|
|
51847
|
-
// src/tools/transcript-search.ts
|
|
51848
|
-
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
51849
|
-
var import_node_path13 = __toESM(require("path"), 1);
|
|
51850
|
-
var SNIPPET_PAD = 60;
|
|
51851
|
-
var INJECTED_ENVELOPE_RE = /^<(system-reminder|command-name|command-message|command-args|local-command-stdout|local-command-stderr|task-notification|user-prompt-submit-hook|environment_context|user_instructions)\b/;
|
|
51852
|
-
var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
|
|
51853
|
-
function asRecord(v3) {
|
|
51854
|
-
return typeof v3 === "object" && v3 !== null ? v3 : null;
|
|
51855
|
-
}
|
|
51856
|
-
function textOfBlocks(content, types) {
|
|
51857
|
-
if (!Array.isArray(content)) return null;
|
|
51858
|
-
const parts = [];
|
|
51859
|
-
for (const block of content) {
|
|
51860
|
-
const b3 = asRecord(block);
|
|
51861
|
-
if (!b3 || typeof b3.type !== "string" || !types.includes(b3.type)) continue;
|
|
51862
|
-
const text = b3.text;
|
|
51863
|
-
if (typeof text === "string" && text !== "") parts.push(text);
|
|
51864
|
-
}
|
|
51865
|
-
return parts.length > 0 ? parts.join("\n") : null;
|
|
51866
|
-
}
|
|
51867
|
-
function lineToSearchableText(raw) {
|
|
51868
|
-
const line = asRecord(raw);
|
|
51869
|
-
if (!line) return null;
|
|
51870
|
-
if (line.type === "response_item") {
|
|
51871
|
-
const payload = asRecord(line.payload);
|
|
51872
|
-
if (!payload || payload.type !== "message") return null;
|
|
51873
|
-
const role = payload.role;
|
|
51874
|
-
if (role !== "user" && role !== "assistant") return null;
|
|
51875
|
-
const text2 = textOfBlocks(payload.content, ["input_text", "output_text"]);
|
|
51876
|
-
if (text2 === null) return null;
|
|
51877
|
-
if (role !== "user") return text2;
|
|
51878
|
-
const stripped = text2.replace(CODEX_WRAPPER_RE, "").trim();
|
|
51879
|
-
if (stripped === "") return null;
|
|
51880
|
-
return INJECTED_ENVELOPE_RE.test(stripped) ? null : stripped;
|
|
51881
|
-
}
|
|
51882
|
-
if (line.type !== "user" && line.type !== "assistant") return null;
|
|
51883
|
-
const message = asRecord(line.message);
|
|
51884
|
-
if (!message) return null;
|
|
51885
|
-
const content = message.content;
|
|
51886
|
-
const text = typeof content === "string" && content !== "" ? content : textOfBlocks(content, ["text"]);
|
|
51887
|
-
if (text === null) return null;
|
|
51888
|
-
if (line.type === "user" && (line.isMeta === true || line.isSynthetic === true)) return null;
|
|
51889
|
-
if (line.type === "user" && INJECTED_ENVELOPE_RE.test(text.trimStart())) return null;
|
|
51890
|
-
return text;
|
|
51891
|
-
}
|
|
51892
|
-
function escapeRegExp(s2) {
|
|
51893
|
-
return s2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
51894
|
-
}
|
|
51895
|
-
function makeSnippet(text, at3, needleLength) {
|
|
51896
|
-
const from = Math.max(0, at3 - SNIPPET_PAD);
|
|
51897
|
-
const to = Math.min(text.length, at3 + needleLength + SNIPPET_PAD);
|
|
51898
|
-
const body = text.slice(from, to).replace(/\s+/g, " ").trim();
|
|
51899
|
-
return `${from > 0 ? "\u2026 " : ""}${body}${to < text.length ? " \u2026" : ""}`;
|
|
51900
|
-
}
|
|
51901
|
-
function searchTranscriptFile(file, query) {
|
|
51902
|
-
let buf;
|
|
51903
|
-
try {
|
|
51904
|
-
buf = import_node_fs14.default.readFileSync(file);
|
|
51905
|
-
} catch {
|
|
51906
|
-
return null;
|
|
51907
|
-
}
|
|
51908
|
-
const haystack = buf.toString("latin1");
|
|
51909
|
-
const needle = Buffer.from(query, "utf8").toString("latin1");
|
|
51910
|
-
const re2 = new RegExp(escapeRegExp(needle), "gi");
|
|
51911
|
-
let m3;
|
|
51912
|
-
while ((m3 = re2.exec(haystack)) !== null) {
|
|
51913
|
-
const lineStart = haystack.lastIndexOf("\n", m3.index) + 1;
|
|
51914
|
-
let lineEnd = haystack.indexOf("\n", m3.index);
|
|
51915
|
-
if (lineEnd < 0) lineEnd = haystack.length;
|
|
51916
|
-
re2.lastIndex = lineEnd + 1;
|
|
51917
|
-
let parsed;
|
|
51918
|
-
try {
|
|
51919
|
-
parsed = JSON.parse(Buffer.from(haystack.slice(lineStart, lineEnd), "latin1").toString("utf8"));
|
|
51920
|
-
} catch {
|
|
51921
|
-
continue;
|
|
51922
|
-
}
|
|
51923
|
-
const text = lineToSearchableText(parsed);
|
|
51924
|
-
if (text === null) continue;
|
|
51925
|
-
const at3 = text.toLowerCase().indexOf(query.toLowerCase());
|
|
51926
|
-
if (at3 < 0) continue;
|
|
51927
|
-
return makeSnippet(text, at3, query.length);
|
|
51928
|
-
}
|
|
51929
|
-
return null;
|
|
51930
|
-
}
|
|
51931
|
-
var ROLLOUT_NAME_RE = /-([0-9a-fA-F-]{36})\.jsonl$/;
|
|
51932
|
-
function createCodexRolloutLocator(roots) {
|
|
51933
|
-
let index = null;
|
|
51934
|
-
const walk2 = (dir, into) => {
|
|
51935
|
-
let entries;
|
|
51936
|
-
try {
|
|
51937
|
-
entries = import_node_fs14.default.readdirSync(dir, { withFileTypes: true });
|
|
51938
|
-
} catch {
|
|
51939
|
-
return;
|
|
51940
|
-
}
|
|
51941
|
-
for (const entry of entries) {
|
|
51942
|
-
const full = import_node_path13.default.join(dir, entry.name);
|
|
51943
|
-
if (entry.isDirectory()) {
|
|
51944
|
-
walk2(full, into);
|
|
51945
|
-
continue;
|
|
51946
|
-
}
|
|
51947
|
-
const matched = ROLLOUT_NAME_RE.exec(entry.name);
|
|
51948
|
-
if (matched) into.set(matched[1].toLowerCase(), full);
|
|
51949
|
-
}
|
|
51950
|
-
};
|
|
51951
|
-
return (toolSessionId) => {
|
|
51952
|
-
if (index === null) {
|
|
51953
|
-
index = /* @__PURE__ */ new Map();
|
|
51954
|
-
for (const root of roots) walk2(root, index);
|
|
51955
|
-
}
|
|
51956
|
-
return index.get(toolSessionId.toLowerCase()) ?? null;
|
|
51957
|
-
};
|
|
51958
|
-
}
|
|
51959
|
-
|
|
51960
|
-
// src/tools/codex-history.ts
|
|
51961
51981
|
var CODEX_LIST_SESSIONS_LIMIT = 100;
|
|
51962
51982
|
var CODEX_LIST_SESSIONS_SCAN_CAP = 4e3;
|
|
51963
51983
|
var PEEK_BYTES = 8 * 1024;
|
|
@@ -52523,9 +52543,9 @@ var CentralClientError = class extends Error {
|
|
|
52523
52543
|
cause;
|
|
52524
52544
|
status;
|
|
52525
52545
|
};
|
|
52526
|
-
async function centralRequest(opts,
|
|
52546
|
+
async function centralRequest(opts, path106, init) {
|
|
52527
52547
|
const f2 = opts.fetchImpl ?? globalThis.fetch;
|
|
52528
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52548
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path106}`;
|
|
52529
52549
|
const ctrl = new AbortController();
|
|
52530
52550
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
52531
52551
|
let res;
|
|
@@ -53234,7 +53254,8 @@ function tokenUsage(usage) {
|
|
|
53234
53254
|
}
|
|
53235
53255
|
function turnCompleted(turn) {
|
|
53236
53256
|
if (turn?.status === "failed") return [{ kind: "error", message: str3(rec3(turn.error)?.message) ?? "codex turn failed" }, { kind: "turn_end" }];
|
|
53237
|
-
|
|
53257
|
+
const turnId = turn?.status === "completed" ? str3(turn.id) : void 0;
|
|
53258
|
+
return [{ kind: "turn_end", ...turnId ? { turnId } : {} }];
|
|
53238
53259
|
}
|
|
53239
53260
|
function rec3(v3) {
|
|
53240
53261
|
return typeof v3 === "object" && v3 !== null ? v3 : void 0;
|
|
@@ -53559,8 +53580,8 @@ function turnStartInput(text, resolveImage) {
|
|
|
53559
53580
|
const items = [];
|
|
53560
53581
|
let leftover = text;
|
|
53561
53582
|
for (const m3 of text.matchAll(SKILL_RE)) {
|
|
53562
|
-
const [marker, name,
|
|
53563
|
-
items.push({ type: "skill", name, path:
|
|
53583
|
+
const [marker, name, path106] = m3;
|
|
53584
|
+
items.push({ type: "skill", name, path: path106 });
|
|
53564
53585
|
leftover = leftover.replace(marker, "");
|
|
53565
53586
|
}
|
|
53566
53587
|
for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -54007,7 +54028,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
54007
54028
|
);
|
|
54008
54029
|
args.push(...codexAgentsCliArgs(loadCodexAgentsConfig({ cwd: ctx.cwd, logger: deps.logger })));
|
|
54009
54030
|
args.push(...codexMemoriesCliArgs(ctx));
|
|
54010
|
-
const resolvedCodexHome = deps.codexHomeFor?.(ctx.cwd);
|
|
54031
|
+
const resolvedCodexHome = (ctx.toolSessionId ? deps.codexHomeForThread?.(ctx.toolSessionId) : void 0) ?? deps.codexHomeFor?.(ctx.cwd);
|
|
54011
54032
|
const env = {
|
|
54012
54033
|
...process.env,
|
|
54013
54034
|
...resolvedCodexHome ? { CODEX_HOME: resolvedCodexHome } : {},
|
|
@@ -54294,9 +54315,8 @@ var CODEX_CAPABILITIES_BASE = {
|
|
|
54294
54315
|
tool: "codex",
|
|
54295
54316
|
toolSessionIdLabel: "Codex Thread ID",
|
|
54296
54317
|
permissionModes: CODEX_APPROVAL_PRESETS,
|
|
54297
|
-
// Codex
|
|
54298
|
-
|
|
54299
|
-
features: { rewind: false, subagents: true, tui: false, observe: false, fileSharing: false, fork: false },
|
|
54318
|
+
// 本机 Codex 支持原生 child thread、已完成 turn 的 fork;rewind / TUI / observe / 文件分享仍关闭。
|
|
54319
|
+
features: { rewind: false, subagents: true, tui: false, observe: false, fileSharing: false, fork: true },
|
|
54300
54320
|
configSchema: [
|
|
54301
54321
|
{
|
|
54302
54322
|
name: "model",
|
|
@@ -54361,6 +54381,7 @@ var CodexAdapter = class {
|
|
|
54361
54381
|
fetchImpl;
|
|
54362
54382
|
/** CODEX_HOME 归属解析(spec 2026-08-18-codex-project-alignment §3.1),由 index.ts 注入 */
|
|
54363
54383
|
codexHomeFor;
|
|
54384
|
+
codexHomeForThread;
|
|
54364
54385
|
getSignSecret;
|
|
54365
54386
|
// capabilities 的进程级 memo。**回落结果同样被缓存**——否则 codex 没装时每次开弹窗都
|
|
54366
54387
|
// spawn 一次必然失败的子进程。装好 codex / provider 加了模型后不用重启:设置 → 账号「引擎」的
|
|
@@ -54374,6 +54395,7 @@ var CodexAdapter = class {
|
|
|
54374
54395
|
this.configQueryOverride = opts.configQueryOverride;
|
|
54375
54396
|
this.fetchImpl = opts.fetchImpl;
|
|
54376
54397
|
this.codexHomeFor = opts.codexHomeFor;
|
|
54398
|
+
this.codexHomeForThread = opts.codexHomeForThread;
|
|
54377
54399
|
this.getSignSecret = opts.getSignSecret;
|
|
54378
54400
|
}
|
|
54379
54401
|
async probe() {
|
|
@@ -54446,6 +54468,7 @@ var CodexAdapter = class {
|
|
|
54446
54468
|
return createCodexSession({ ...ctx, model: sanitizeCodexModel(ctx.model) }, sink, {
|
|
54447
54469
|
logger: this.logger,
|
|
54448
54470
|
codexHomeFor: this.codexHomeFor,
|
|
54471
|
+
codexHomeForThread: this.codexHomeForThread,
|
|
54449
54472
|
getSignSecret: this.getSignSecret
|
|
54450
54473
|
});
|
|
54451
54474
|
}
|
|
@@ -56654,12 +56677,12 @@ var DEFAULT_TIMEOUT_MS2 = 15e3;
|
|
|
56654
56677
|
var MAX_BUFFER = 4 * 1024 * 1024;
|
|
56655
56678
|
function createGhRunner(defaults) {
|
|
56656
56679
|
const baseTimeoutMs = defaults?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
56657
|
-
const
|
|
56680
|
+
const spawn16 = defaults?.execFile ?? import_node_child_process8.execFile;
|
|
56658
56681
|
return {
|
|
56659
56682
|
run(args, opts) {
|
|
56660
56683
|
const token = defaults?.token?.();
|
|
56661
56684
|
return new Promise((resolve9, reject) => {
|
|
56662
|
-
|
|
56685
|
+
spawn16(
|
|
56663
56686
|
"gh",
|
|
56664
56687
|
args,
|
|
56665
56688
|
{
|
|
@@ -60933,10 +60956,10 @@ function createGithubApi(args) {
|
|
|
60933
60956
|
const doFetch = args.fetch ?? fetch;
|
|
60934
60957
|
const seal = args.seal ?? sealWithSodium;
|
|
60935
60958
|
const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
|
|
60936
|
-
async function request(method,
|
|
60959
|
+
async function request(method, path106, body) {
|
|
60937
60960
|
let res;
|
|
60938
60961
|
try {
|
|
60939
|
-
res = await doFetch(`${API}${
|
|
60962
|
+
res = await doFetch(`${API}${path106}`, {
|
|
60940
60963
|
method,
|
|
60941
60964
|
headers: {
|
|
60942
60965
|
Authorization: `Bearer ${args.token}`,
|
|
@@ -60961,8 +60984,8 @@ function createGithubApi(args) {
|
|
|
60961
60984
|
}
|
|
60962
60985
|
return { status: res.status, json };
|
|
60963
60986
|
}
|
|
60964
|
-
async function must(method,
|
|
60965
|
-
const r2 = await request(method,
|
|
60987
|
+
async function must(method, path106, what, body) {
|
|
60988
|
+
const r2 = await request(method, path106, body);
|
|
60966
60989
|
if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
|
|
60967
60990
|
return r2.json;
|
|
60968
60991
|
}
|
|
@@ -61007,9 +61030,9 @@ function createGithubApi(args) {
|
|
|
61007
61030
|
return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
|
|
61008
61031
|
});
|
|
61009
61032
|
},
|
|
61010
|
-
async getJson(
|
|
61033
|
+
async getJson(path106) {
|
|
61011
61034
|
try {
|
|
61012
|
-
const r2 = await request("GET",
|
|
61035
|
+
const r2 = await request("GET", path106);
|
|
61013
61036
|
return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
|
|
61014
61037
|
} catch {
|
|
61015
61038
|
return void 0;
|
|
@@ -62486,8 +62509,8 @@ function refreshPathFromLoginShell() {
|
|
|
62486
62509
|
timeout: 3e3,
|
|
62487
62510
|
stdio: ["ignore", "pipe", "ignore"]
|
|
62488
62511
|
});
|
|
62489
|
-
const
|
|
62490
|
-
if (
|
|
62512
|
+
const path106 = out.trim();
|
|
62513
|
+
if (path106) process.env.PATH = path106;
|
|
62491
62514
|
} catch {
|
|
62492
62515
|
}
|
|
62493
62516
|
}
|
|
@@ -65436,13 +65459,13 @@ function mapSkillsListResponse(res) {
|
|
|
65436
65459
|
const r2 = s2 ?? {};
|
|
65437
65460
|
const name = str4(r2.name);
|
|
65438
65461
|
if (!name) continue;
|
|
65439
|
-
const
|
|
65462
|
+
const path106 = str4(r2.path);
|
|
65440
65463
|
const description = str4(r2.description);
|
|
65441
65464
|
const isPlugin = name.includes(":");
|
|
65442
65465
|
out.push({
|
|
65443
65466
|
name,
|
|
65444
65467
|
source: isPlugin ? "plugin" : "project",
|
|
65445
|
-
...
|
|
65468
|
+
...path106 ? { path: path106 } : {},
|
|
65446
65469
|
...description ? { description } : {},
|
|
65447
65470
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
65448
65471
|
});
|
|
@@ -69976,7 +69999,7 @@ var ServerKeyStore = class {
|
|
|
69976
69999
|
init_protocol();
|
|
69977
70000
|
|
|
69978
70001
|
// src/handlers/index.ts
|
|
69979
|
-
var
|
|
70002
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
69980
70003
|
|
|
69981
70004
|
// src/handlers/session.ts
|
|
69982
70005
|
init_protocol();
|
|
@@ -70049,20 +70072,83 @@ function forkSession(input) {
|
|
|
70049
70072
|
return { forkedToolSessionId, forkedFilePath };
|
|
70050
70073
|
}
|
|
70051
70074
|
|
|
70052
|
-
// src/
|
|
70075
|
+
// src/tools/codex-fork.ts
|
|
70076
|
+
var import_node_child_process17 = require("child_process");
|
|
70053
70077
|
var import_node_fs59 = __toESM(require("fs"), 1);
|
|
70078
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
70079
|
+
function openCodexAppServer(home, cwd) {
|
|
70080
|
+
const proc = (0, import_node_child_process17.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
|
|
70081
|
+
cwd,
|
|
70082
|
+
env: { ...process.env, CODEX_HOME: home },
|
|
70083
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
70084
|
+
});
|
|
70085
|
+
proc.on("error", () => proc.stdout?.destroy());
|
|
70086
|
+
const stream = stdioLineStream(proc);
|
|
70087
|
+
return {
|
|
70088
|
+
stream,
|
|
70089
|
+
close: () => {
|
|
70090
|
+
stream.close();
|
|
70091
|
+
if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGTERM");
|
|
70092
|
+
}
|
|
70093
|
+
};
|
|
70094
|
+
}
|
|
70095
|
+
async function forkCodexThread(input, deps = {}) {
|
|
70096
|
+
const source = locateCodexThread(input.roots, input.sourceThreadId);
|
|
70097
|
+
if (!source) throw new Error(`codex fork: source thread not found: ${input.sourceThreadId}`);
|
|
70098
|
+
const rollout = parseCodexRollout(import_node_fs59.default.readFileSync(source.file, "utf8"));
|
|
70099
|
+
if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
|
|
70100
|
+
throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
|
|
70101
|
+
}
|
|
70102
|
+
if (!rollout.turns.some((turn) => turn.turnId === input.turnId && turn.status === "completed")) {
|
|
70103
|
+
throw new Error(`codex fork: completed turn not found: ${input.turnId}`);
|
|
70104
|
+
}
|
|
70105
|
+
const connection = (deps.open ?? openCodexAppServer)(source.home, input.targetCwd);
|
|
70106
|
+
const timeoutMs = deps.timeoutMs ?? DEFAULT_CODEX_QUERY_TIMEOUT_MS;
|
|
70107
|
+
let timer;
|
|
70108
|
+
const timeout = new Promise((_3, reject) => {
|
|
70109
|
+
timer = setTimeout(() => reject(new Error(`codex app-server thread/fork timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
70110
|
+
});
|
|
70111
|
+
try {
|
|
70112
|
+
const client = new CodexAppServerClient(connection.stream);
|
|
70113
|
+
return await Promise.race([timeout, (async () => {
|
|
70114
|
+
await client.request("initialize", {
|
|
70115
|
+
clientInfo: { name: "clawd", title: "clawd", version: "0" },
|
|
70116
|
+
capabilities: null
|
|
70117
|
+
});
|
|
70118
|
+
client.notify("initialized", {});
|
|
70119
|
+
const result = await client.request("thread/fork", {
|
|
70120
|
+
threadId: input.sourceThreadId,
|
|
70121
|
+
lastTurnId: input.turnId,
|
|
70122
|
+
cwd: input.targetCwd
|
|
70123
|
+
});
|
|
70124
|
+
const forkedToolSessionId = result?.thread?.id;
|
|
70125
|
+
if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
|
|
70126
|
+
throw new Error("codex fork: app-server returned no thread id");
|
|
70127
|
+
}
|
|
70128
|
+
const forked = locateCodexThread([import_node_path65.default.join(source.home, "sessions")], forkedToolSessionId);
|
|
70129
|
+
if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
|
|
70130
|
+
return { forkedToolSessionId, forkedFilePath: forked.file };
|
|
70131
|
+
})()]);
|
|
70132
|
+
} finally {
|
|
70133
|
+
if (timer) clearTimeout(timer);
|
|
70134
|
+
connection.close();
|
|
70135
|
+
}
|
|
70136
|
+
}
|
|
70137
|
+
|
|
70138
|
+
// src/session/external-scan.ts
|
|
70139
|
+
var import_node_fs60 = __toESM(require("fs"), 1);
|
|
70054
70140
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
70055
70141
|
var import_node_os24 = __toESM(require("os"), 1);
|
|
70056
|
-
var
|
|
70142
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
70057
70143
|
var import_node_module = require("module");
|
|
70058
|
-
var
|
|
70144
|
+
var import_node_child_process18 = require("child_process");
|
|
70059
70145
|
var import_meta7 = {};
|
|
70060
70146
|
function defaultRoots() {
|
|
70061
70147
|
const home = import_node_os24.default.homedir();
|
|
70062
70148
|
return {
|
|
70063
|
-
claudeProjectsDir:
|
|
70064
|
-
codexDir:
|
|
70065
|
-
clawdDir:
|
|
70149
|
+
claudeProjectsDir: import_node_path66.default.join(home, ".claude", "projects"),
|
|
70150
|
+
codexDir: import_node_path66.default.join(home, ".codex"),
|
|
70151
|
+
clawdDir: import_node_path66.default.join(home, ".clawd")
|
|
70066
70152
|
};
|
|
70067
70153
|
}
|
|
70068
70154
|
function width(s2) {
|
|
@@ -70113,7 +70199,7 @@ function userText(msg) {
|
|
|
70113
70199
|
}
|
|
70114
70200
|
function isDir2(p3) {
|
|
70115
70201
|
try {
|
|
70116
|
-
return
|
|
70202
|
+
return import_node_fs60.default.statSync(p3).isDirectory();
|
|
70117
70203
|
} catch {
|
|
70118
70204
|
return false;
|
|
70119
70205
|
}
|
|
@@ -70122,7 +70208,7 @@ async function scanClaude(roots) {
|
|
|
70122
70208
|
const out = [];
|
|
70123
70209
|
let dirs;
|
|
70124
70210
|
try {
|
|
70125
|
-
dirs =
|
|
70211
|
+
dirs = import_node_fs60.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
|
|
70126
70212
|
} catch {
|
|
70127
70213
|
return out;
|
|
70128
70214
|
}
|
|
@@ -70130,16 +70216,16 @@ async function scanClaude(roots) {
|
|
|
70130
70216
|
if (!d2.isDirectory()) continue;
|
|
70131
70217
|
let files;
|
|
70132
70218
|
try {
|
|
70133
|
-
files =
|
|
70219
|
+
files = import_node_fs60.default.readdirSync(import_node_path66.default.join(roots.claudeProjectsDir, d2.name));
|
|
70134
70220
|
} catch {
|
|
70135
70221
|
continue;
|
|
70136
70222
|
}
|
|
70137
70223
|
for (const name of files) {
|
|
70138
70224
|
if (!name.endsWith(".jsonl")) continue;
|
|
70139
|
-
const file =
|
|
70225
|
+
const file = import_node_path66.default.join(roots.claudeProjectsDir, d2.name, name);
|
|
70140
70226
|
let st2;
|
|
70141
70227
|
try {
|
|
70142
|
-
st2 =
|
|
70228
|
+
st2 = import_node_fs60.default.statSync(file);
|
|
70143
70229
|
} catch {
|
|
70144
70230
|
continue;
|
|
70145
70231
|
}
|
|
@@ -70192,7 +70278,7 @@ async function scanClaude(roots) {
|
|
|
70192
70278
|
return out;
|
|
70193
70279
|
}
|
|
70194
70280
|
async function countCodexTurns(rolloutPath) {
|
|
70195
|
-
if (!rolloutPath || !
|
|
70281
|
+
if (!rolloutPath || !import_node_fs60.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
|
|
70196
70282
|
let turns = 0;
|
|
70197
70283
|
let first = "";
|
|
70198
70284
|
for await (const rec6 of jsonLines(rolloutPath)) {
|
|
@@ -70223,14 +70309,14 @@ function readCodexThreads(db) {
|
|
|
70223
70309
|
} catch {
|
|
70224
70310
|
}
|
|
70225
70311
|
try {
|
|
70226
|
-
const info = (0,
|
|
70312
|
+
const info = (0, import_node_child_process18.spawnSync)("sqlite3", [db, "PRAGMA table_info(threads);"], { encoding: "utf8" });
|
|
70227
70313
|
if (info.status !== 0) return null;
|
|
70228
70314
|
const have = new Set(
|
|
70229
70315
|
info.stdout.split("\n").map((l2) => l2.split("|")[1]).filter(Boolean)
|
|
70230
70316
|
);
|
|
70231
70317
|
if (!["id", "cwd", "updated_at", "thread_source"].every((c2) => have.has(c2))) return null;
|
|
70232
70318
|
const sel = COLS.map((c2) => have.has(c2) ? c2 : `NULL AS ${c2}`).join(", ");
|
|
70233
|
-
const res = (0,
|
|
70319
|
+
const res = (0, import_node_child_process18.spawnSync)("sqlite3", ["-json", db, `SELECT ${sel} FROM threads;`], {
|
|
70234
70320
|
encoding: "utf8",
|
|
70235
70321
|
maxBuffer: 64 * 1024 * 1024
|
|
70236
70322
|
});
|
|
@@ -70266,7 +70352,7 @@ async function codexFromRows(rows) {
|
|
|
70266
70352
|
async function scanCodex(roots) {
|
|
70267
70353
|
let dbs = [];
|
|
70268
70354
|
try {
|
|
70269
|
-
dbs =
|
|
70355
|
+
dbs = import_node_fs60.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path66.default.join(roots.codexDir, n2));
|
|
70270
70356
|
} catch {
|
|
70271
70357
|
}
|
|
70272
70358
|
if (!dbs.length) return [];
|
|
@@ -70275,14 +70361,14 @@ async function scanCodex(roots) {
|
|
|
70275
70361
|
}
|
|
70276
70362
|
async function scanExternalSessions(rootsIn) {
|
|
70277
70363
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
70278
|
-
const personaRoot =
|
|
70364
|
+
const personaRoot = import_node_path66.default.join(roots.clawdDir, "personas");
|
|
70279
70365
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
70280
70366
|
const out = [];
|
|
70281
70367
|
for (const c2 of all) {
|
|
70282
70368
|
if (c2.skip) continue;
|
|
70283
70369
|
if (c2.turns < 1) continue;
|
|
70284
70370
|
if (!c2.cwd || !isDir2(c2.cwd)) continue;
|
|
70285
|
-
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot +
|
|
70371
|
+
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path66.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path66.default.sep)) {
|
|
70286
70372
|
continue;
|
|
70287
70373
|
}
|
|
70288
70374
|
out.push({
|
|
@@ -70299,13 +70385,13 @@ async function scanExternalSessions(rootsIn) {
|
|
|
70299
70385
|
}
|
|
70300
70386
|
|
|
70301
70387
|
// src/session/import-ledger.ts
|
|
70302
|
-
var
|
|
70303
|
-
var
|
|
70388
|
+
var import_node_fs61 = __toESM(require("fs"), 1);
|
|
70389
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
70304
70390
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
70305
70391
|
function readImportLedger(dataDir) {
|
|
70306
70392
|
try {
|
|
70307
70393
|
const parsed = JSON.parse(
|
|
70308
|
-
|
|
70394
|
+
import_node_fs61.default.readFileSync(import_node_path67.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
70309
70395
|
);
|
|
70310
70396
|
return Array.isArray(parsed) ? parsed : [];
|
|
70311
70397
|
} catch {
|
|
@@ -70313,14 +70399,15 @@ function readImportLedger(dataDir) {
|
|
|
70313
70399
|
}
|
|
70314
70400
|
}
|
|
70315
70401
|
function appendImportLedger(dataDir, entry) {
|
|
70316
|
-
const file =
|
|
70402
|
+
const file = import_node_path67.default.join(dataDir, LEDGER_FILENAME);
|
|
70317
70403
|
const entries = readImportLedger(dataDir);
|
|
70318
70404
|
entries.push(entry);
|
|
70319
|
-
|
|
70405
|
+
import_node_fs61.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
70320
70406
|
}
|
|
70321
70407
|
|
|
70322
70408
|
// src/handlers/session.ts
|
|
70323
70409
|
init_protocol();
|
|
70410
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
70324
70411
|
function canReadSearchHit(ctx, file) {
|
|
70325
70412
|
if (!ctx || ctx.principal.kind === "owner") return true;
|
|
70326
70413
|
return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
|
|
@@ -70588,8 +70675,12 @@ ${attribution}` } : args;
|
|
|
70588
70675
|
};
|
|
70589
70676
|
const fork = async (frame, _client, ctx) => {
|
|
70590
70677
|
const args = SessionForkArgs.parse(frame);
|
|
70678
|
+
const source = args.sourceSessionId ? manager.get({ sessionId: args.sourceSessionId }).response : null;
|
|
70679
|
+
if (source && (source.sessionId !== args.sourceSessionId || source.toolSessionId !== args.toolSessionId)) {
|
|
70680
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "fork: source thread does not match source session");
|
|
70681
|
+
}
|
|
70591
70682
|
if (ctx && ctx.principal.kind === "guest") {
|
|
70592
|
-
const src = store.list().find((s2) => s2.toolSessionId === args.toolSessionId);
|
|
70683
|
+
const src = source ?? store.list().find((s2) => s2.toolSessionId === args.toolSessionId);
|
|
70593
70684
|
const ok = src != null && canAccessPersona(ctx.grants, src.ownerPersonaId, "read") && src.creatorPrincipalId === ctx.principal.id;
|
|
70594
70685
|
if (!ok) {
|
|
70595
70686
|
throw new ClawdError(
|
|
@@ -70597,8 +70688,33 @@ ${attribution}` } : args;
|
|
|
70597
70688
|
`principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
|
|
70598
70689
|
);
|
|
70599
70690
|
}
|
|
70691
|
+
if (source?.tool === "codex" && args.targetCwd && import_node_path68.default.resolve(args.targetCwd) !== import_node_path68.default.resolve(source.cwd)) {
|
|
70692
|
+
throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
|
|
70693
|
+
}
|
|
70694
|
+
}
|
|
70695
|
+
if (source && source.tool !== void 0 && source.tool !== "claude" && source.tool !== "codex") {
|
|
70696
|
+
throw new ClawdError(ERROR_CODES.TOOL_NOT_SUPPORTED, `tool ${source.tool} does not support fork`);
|
|
70697
|
+
}
|
|
70698
|
+
if (args.turnId && source?.tool !== "codex") {
|
|
70699
|
+
throw new ClawdError(ERROR_CODES.TOOL_NOT_SUPPORTED, "fork: turnId requires a local Codex source session");
|
|
70700
|
+
}
|
|
70701
|
+
if (source?.tool === "codex" && (!args.turnId || args.messageUuid || !args.targetCwd)) {
|
|
70702
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "fork: Codex requires turnId and targetCwd");
|
|
70703
|
+
}
|
|
70704
|
+
if (source?.tool !== "codex" && !args.messageUuid) {
|
|
70705
|
+
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "fork: Claude requires messageUuid");
|
|
70600
70706
|
}
|
|
70601
|
-
const result =
|
|
70707
|
+
const result = source?.tool === "codex" ? await (deps.forkCodexThread ?? forkCodexThread)({
|
|
70708
|
+
roots: codexRolloutRoots(deps.dataDir),
|
|
70709
|
+
sourceThreadId: args.toolSessionId,
|
|
70710
|
+
turnId: args.turnId,
|
|
70711
|
+
targetCwd: args.targetCwd
|
|
70712
|
+
}) : forkSession({
|
|
70713
|
+
cwd: args.cwd,
|
|
70714
|
+
toolSessionId: args.toolSessionId,
|
|
70715
|
+
messageUuid: args.messageUuid,
|
|
70716
|
+
...args.targetCwd ? { targetCwd: args.targetCwd } : {}
|
|
70717
|
+
});
|
|
70602
70718
|
deps.logger?.info("session-fork.done", {
|
|
70603
70719
|
argCwd: args.cwd,
|
|
70604
70720
|
sourceToolSessionId: args.toolSessionId,
|
|
@@ -70849,7 +70965,7 @@ function buildPermissionHandlers(deps) {
|
|
|
70849
70965
|
}
|
|
70850
70966
|
|
|
70851
70967
|
// src/handlers/history.ts
|
|
70852
|
-
var
|
|
70968
|
+
var path83 = __toESM(require("path"), 1);
|
|
70853
70969
|
init_protocol();
|
|
70854
70970
|
|
|
70855
70971
|
// src/session/recent-dirs.ts
|
|
@@ -70867,7 +70983,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
70867
70983
|
}
|
|
70868
70984
|
|
|
70869
70985
|
// src/permission/persona-paths.ts
|
|
70870
|
-
var
|
|
70986
|
+
var path82 = __toESM(require("path"), 1);
|
|
70871
70987
|
function getAllowedPersonaIds(grants, action) {
|
|
70872
70988
|
const ids = /* @__PURE__ */ new Set();
|
|
70873
70989
|
for (const g3 of grants) {
|
|
@@ -70880,42 +70996,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
70880
70996
|
return ids;
|
|
70881
70997
|
}
|
|
70882
70998
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
70883
|
-
const target =
|
|
70999
|
+
const target = path82.resolve(absPath);
|
|
70884
71000
|
if (userWorkDir) {
|
|
70885
|
-
const u2 =
|
|
70886
|
-
const usep = u2.endsWith(
|
|
71001
|
+
const u2 = path82.resolve(userWorkDir);
|
|
71002
|
+
const usep = u2.endsWith(path82.sep) ? "" : path82.sep;
|
|
70887
71003
|
if (target === u2 || target.startsWith(u2 + usep)) return true;
|
|
70888
71004
|
}
|
|
70889
|
-
const root =
|
|
70890
|
-
const sep4 = root.endsWith(
|
|
71005
|
+
const root = path82.resolve(personaRoot);
|
|
71006
|
+
const sep4 = root.endsWith(path82.sep) ? "" : path82.sep;
|
|
70891
71007
|
if (!target.startsWith(root + sep4)) return false;
|
|
70892
|
-
const rel =
|
|
71008
|
+
const rel = path82.relative(root, target);
|
|
70893
71009
|
if (!rel || rel.startsWith("..")) return false;
|
|
70894
|
-
const personaId2 = rel.split(
|
|
71010
|
+
const personaId2 = rel.split(path82.sep)[0];
|
|
70895
71011
|
if (!personaId2) return false;
|
|
70896
71012
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
70897
71013
|
if (allowed === "*") return true;
|
|
70898
71014
|
return allowed.has(personaId2);
|
|
70899
71015
|
}
|
|
70900
71016
|
function personaIdFromPath(absPath, personaRoot) {
|
|
70901
|
-
const root =
|
|
70902
|
-
const target =
|
|
70903
|
-
const sep4 = root.endsWith(
|
|
71017
|
+
const root = path82.resolve(personaRoot);
|
|
71018
|
+
const target = path82.resolve(absPath);
|
|
71019
|
+
const sep4 = root.endsWith(path82.sep) ? "" : path82.sep;
|
|
70904
71020
|
if (!target.startsWith(root + sep4)) return null;
|
|
70905
|
-
const rel =
|
|
71021
|
+
const rel = path82.relative(root, target);
|
|
70906
71022
|
if (!rel || rel.startsWith("..")) return null;
|
|
70907
|
-
const id = rel.split(
|
|
71023
|
+
const id = rel.split(path82.sep)[0];
|
|
70908
71024
|
return id || null;
|
|
70909
71025
|
}
|
|
70910
71026
|
function isPathWithin(dir, absPath) {
|
|
70911
|
-
const d2 =
|
|
70912
|
-
const t2 =
|
|
70913
|
-
const sep4 = d2.endsWith(
|
|
71027
|
+
const d2 = path82.resolve(dir);
|
|
71028
|
+
const t2 = path82.resolve(absPath);
|
|
71029
|
+
const sep4 = d2.endsWith(path82.sep) ? "" : path82.sep;
|
|
70914
71030
|
return t2 === d2 || t2.startsWith(d2 + sep4);
|
|
70915
71031
|
}
|
|
70916
71032
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
70917
71033
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
70918
|
-
return personaIdFromPath(
|
|
71034
|
+
return personaIdFromPath(path82.resolve(absPath), personaRoot) === personaId2;
|
|
70919
71035
|
}
|
|
70920
71036
|
|
|
70921
71037
|
// src/handlers/history.ts
|
|
@@ -70941,6 +71057,7 @@ function slimHistoryMessages(messages) {
|
|
|
70941
71057
|
if (m3.isSidechain !== void 0) out.isSidechain = m3.isSidechain;
|
|
70942
71058
|
if (m3.askQuestionAnswers !== void 0) out.askQuestionAnswers = m3.askQuestionAnswers;
|
|
70943
71059
|
if (m3.durationMs !== void 0) out.durationMs = m3.durationMs;
|
|
71060
|
+
if (m3.turnId !== void 0) out.turnId = m3.turnId;
|
|
70944
71061
|
const isErrorPair = m3.toolUseId !== void 0 && errorToolUseIds.has(m3.toolUseId);
|
|
70945
71062
|
if (m3.kind === "tool_call" && isErrorPair && m3.input !== void 0) out.input = m3.input;
|
|
70946
71063
|
if (m3.kind === "tool_result" && m3.error !== void 0 && m3.output !== void 0) out.output = m3.output;
|
|
@@ -70968,7 +71085,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70968
71085
|
if (!pid) return false;
|
|
70969
71086
|
return isGuestPathAllowed(
|
|
70970
71087
|
ctx.grants,
|
|
70971
|
-
|
|
71088
|
+
path83.join(personaRoot, pid),
|
|
70972
71089
|
personaRoot,
|
|
70973
71090
|
"read",
|
|
70974
71091
|
userWorkDir
|
|
@@ -70980,7 +71097,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70980
71097
|
};
|
|
70981
71098
|
const list = async (frame, _client, ctx) => {
|
|
70982
71099
|
const args = HistoryListArgs.parse(frame);
|
|
70983
|
-
assertGuestPath(ctx,
|
|
71100
|
+
assertGuestPath(ctx, path83.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
70984
71101
|
const sessions = await history.listSessions(args);
|
|
70985
71102
|
return { response: { type: "history:list", sessions } };
|
|
70986
71103
|
};
|
|
@@ -71028,14 +71145,14 @@ function buildHistoryHandlers(deps) {
|
|
|
71028
71145
|
};
|
|
71029
71146
|
const subagents = async (frame, _client, ctx) => {
|
|
71030
71147
|
const args = HistorySubagentsArgs.parse(frame);
|
|
71031
|
-
assertGuestPath(ctx,
|
|
71148
|
+
assertGuestPath(ctx, path83.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
71032
71149
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
71033
71150
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
71034
71151
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
71035
71152
|
};
|
|
71036
71153
|
const subagentRead = async (frame, _client, ctx) => {
|
|
71037
71154
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
71038
|
-
assertGuestPath(ctx,
|
|
71155
|
+
assertGuestPath(ctx, path83.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
71039
71156
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
71040
71157
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
71041
71158
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -71045,7 +71162,7 @@ function buildHistoryHandlers(deps) {
|
|
|
71045
71162
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
71046
71163
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
71047
71164
|
const filtered = dirs.filter(
|
|
71048
|
-
(d2) => isGuestPathAllowed(ctx.grants,
|
|
71165
|
+
(d2) => isGuestPathAllowed(ctx.grants, path83.resolve(d2.cwd), personaRoot, "read", userWorkDir)
|
|
71049
71166
|
);
|
|
71050
71167
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
71051
71168
|
}
|
|
@@ -71062,17 +71179,17 @@ function buildHistoryHandlers(deps) {
|
|
|
71062
71179
|
}
|
|
71063
71180
|
|
|
71064
71181
|
// src/handlers/projects.ts
|
|
71065
|
-
var
|
|
71182
|
+
var fs79 = __toESM(require("fs"), 1);
|
|
71066
71183
|
var os26 = __toESM(require("os"), 1);
|
|
71067
|
-
var
|
|
71068
|
-
var
|
|
71184
|
+
var path84 = __toESM(require("path"), 1);
|
|
71185
|
+
var import_node_child_process19 = require("child_process");
|
|
71069
71186
|
init_protocol();
|
|
71070
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
71187
|
+
var DEFAULT_PROJECTS_ROOT = path84.join(os26.homedir(), "Documents", "ChatGPT");
|
|
71071
71188
|
function allocateDir(root, name) {
|
|
71072
|
-
let candidate =
|
|
71189
|
+
let candidate = path84.join(root, name);
|
|
71073
71190
|
let n2 = 2;
|
|
71074
|
-
while (
|
|
71075
|
-
candidate =
|
|
71191
|
+
while (fs79.existsSync(candidate)) {
|
|
71192
|
+
candidate = path84.join(root, `${name} ${n2}`);
|
|
71076
71193
|
n2 += 1;
|
|
71077
71194
|
}
|
|
71078
71195
|
return candidate;
|
|
@@ -71100,11 +71217,11 @@ function buildProjectHandlers(deps) {
|
|
|
71100
71217
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
71101
71218
|
}
|
|
71102
71219
|
try {
|
|
71103
|
-
if (!
|
|
71220
|
+
if (!fs79.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
71104
71221
|
} catch {
|
|
71105
71222
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
71106
71223
|
}
|
|
71107
|
-
const r2 = (0,
|
|
71224
|
+
const r2 = (0, import_node_child_process19.spawnSync)("open", ["-R", args.path], { stdio: "ignore" });
|
|
71108
71225
|
if (r2.status !== 0) {
|
|
71109
71226
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `open -R \u5931\u8D25: exit ${r2.status}`);
|
|
71110
71227
|
}
|
|
@@ -71116,7 +71233,7 @@ function buildProjectHandlers(deps) {
|
|
|
71116
71233
|
let target;
|
|
71117
71234
|
if (args.path) {
|
|
71118
71235
|
try {
|
|
71119
|
-
if (!
|
|
71236
|
+
if (!fs79.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
71120
71237
|
} catch {
|
|
71121
71238
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
71122
71239
|
}
|
|
@@ -71124,15 +71241,15 @@ function buildProjectHandlers(deps) {
|
|
|
71124
71241
|
} else {
|
|
71125
71242
|
const name = args.name;
|
|
71126
71243
|
try {
|
|
71127
|
-
|
|
71244
|
+
fs79.mkdirSync(root, { recursive: true });
|
|
71128
71245
|
target = allocateDir(root, name);
|
|
71129
|
-
|
|
71246
|
+
fs79.mkdirSync(target);
|
|
71130
71247
|
} catch (err) {
|
|
71131
71248
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
71132
71249
|
}
|
|
71133
|
-
const git2 = (0,
|
|
71250
|
+
const git2 = (0, import_node_child_process19.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
71134
71251
|
if (git2.status !== 0) {
|
|
71135
|
-
|
|
71252
|
+
fs79.rmSync(target, { recursive: true, force: true });
|
|
71136
71253
|
throw new ClawdError(
|
|
71137
71254
|
ERROR_CODES.INVALID_CWD,
|
|
71138
71255
|
`git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
|
|
@@ -71157,7 +71274,7 @@ function buildProjectHandlers(deps) {
|
|
|
71157
71274
|
}
|
|
71158
71275
|
|
|
71159
71276
|
// src/handlers/workspace.ts
|
|
71160
|
-
var
|
|
71277
|
+
var path85 = __toESM(require("path"), 1);
|
|
71161
71278
|
init_protocol();
|
|
71162
71279
|
var os27 = __toESM(require("os"), 1);
|
|
71163
71280
|
init_protocol();
|
|
@@ -71200,22 +71317,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
71200
71317
|
const args = WorkspaceListArgs.parse(frame);
|
|
71201
71318
|
const isGuest = ctx?.principal.kind === "guest";
|
|
71202
71319
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os27.homedir();
|
|
71203
|
-
const resolvedCwd =
|
|
71204
|
-
const target = args.path ?
|
|
71320
|
+
const resolvedCwd = path85.resolve(args.cwd ?? fallbackCwd);
|
|
71321
|
+
const target = args.path ? path85.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
71205
71322
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
71206
71323
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
71207
71324
|
return { response: { type: "workspace:list", ...res } };
|
|
71208
71325
|
};
|
|
71209
71326
|
const read = async (frame, _client, ctx) => {
|
|
71210
71327
|
const args = WorkspaceReadArgs.parse(frame);
|
|
71211
|
-
const target =
|
|
71328
|
+
const target = path85.isAbsolute(args.path) ? path85.resolve(args.path) : path85.resolve(args.cwd, args.path);
|
|
71212
71329
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
71213
71330
|
const res = workspace.read(args);
|
|
71214
71331
|
return { response: { type: "workspace:read", ...res } };
|
|
71215
71332
|
};
|
|
71216
71333
|
const skillsList = async (frame, _client, ctx) => {
|
|
71217
71334
|
const args = SkillsListArgs.parse(frame);
|
|
71218
|
-
const cwdAbs =
|
|
71335
|
+
const cwdAbs = path85.resolve(args.cwd);
|
|
71219
71336
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
71220
71337
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
71221
71338
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -71227,7 +71344,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
71227
71344
|
};
|
|
71228
71345
|
const agentsList = async (frame, _client, ctx) => {
|
|
71229
71346
|
const args = AgentsListArgs.parse(frame);
|
|
71230
|
-
const cwdAbs =
|
|
71347
|
+
const cwdAbs = path85.resolve(args.cwd);
|
|
71231
71348
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
71232
71349
|
if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
|
|
71233
71350
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -71249,20 +71366,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
71249
71366
|
}
|
|
71250
71367
|
|
|
71251
71368
|
// src/handlers/git.ts
|
|
71252
|
-
var
|
|
71369
|
+
var path87 = __toESM(require("path"), 1);
|
|
71253
71370
|
init_protocol();
|
|
71254
71371
|
init_protocol();
|
|
71255
71372
|
|
|
71256
71373
|
// src/workspace/git.ts
|
|
71257
|
-
var
|
|
71258
|
-
var
|
|
71259
|
-
var
|
|
71374
|
+
var import_node_child_process20 = require("child_process");
|
|
71375
|
+
var import_node_fs62 = __toESM(require("fs"), 1);
|
|
71376
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
71260
71377
|
var import_node_util2 = require("util");
|
|
71261
|
-
var pexec = (0, import_node_util2.promisify)(
|
|
71378
|
+
var pexec = (0, import_node_util2.promisify)(import_node_child_process20.execFile);
|
|
71262
71379
|
function normalizePath(p3) {
|
|
71263
|
-
const resolved =
|
|
71380
|
+
const resolved = import_node_path69.default.resolve(p3);
|
|
71264
71381
|
try {
|
|
71265
|
-
return
|
|
71382
|
+
return import_node_fs62.default.realpathSync(resolved);
|
|
71266
71383
|
} catch {
|
|
71267
71384
|
return resolved;
|
|
71268
71385
|
}
|
|
@@ -71336,7 +71453,7 @@ async function listGitBranches(cwd) {
|
|
|
71336
71453
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
71337
71454
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
71338
71455
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
71339
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
71456
|
+
if (!isGuestPathAllowed(ctx.grants, path87.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
71340
71457
|
throw new ClawdError(
|
|
71341
71458
|
ERROR_CODES.UNAUTHORIZED,
|
|
71342
71459
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -71388,7 +71505,7 @@ function buildCapabilitiesHandlers(deps) {
|
|
|
71388
71505
|
init_protocol();
|
|
71389
71506
|
|
|
71390
71507
|
// src/tools/version-probe.ts
|
|
71391
|
-
var
|
|
71508
|
+
var import_node_child_process21 = require("child_process");
|
|
71392
71509
|
init_claude();
|
|
71393
71510
|
init_protocol();
|
|
71394
71511
|
function parseVersionOutput(out) {
|
|
@@ -71396,7 +71513,7 @@ function parseVersionOutput(out) {
|
|
|
71396
71513
|
}
|
|
71397
71514
|
function execVersion(bin) {
|
|
71398
71515
|
return new Promise((resolve9, reject) => {
|
|
71399
|
-
(0,
|
|
71516
|
+
(0, import_node_child_process21.execFile)(bin, ["--version"], { timeout: 5e3 }, (err, stdout) => {
|
|
71400
71517
|
if (err) reject(err);
|
|
71401
71518
|
else resolve9(String(stdout));
|
|
71402
71519
|
});
|
|
@@ -71429,7 +71546,7 @@ async function probeToolVersions(opts = {}) {
|
|
|
71429
71546
|
}
|
|
71430
71547
|
|
|
71431
71548
|
// src/tools/pool-connect.ts
|
|
71432
|
-
var
|
|
71549
|
+
var import_node_child_process22 = require("child_process");
|
|
71433
71550
|
init_protocol();
|
|
71434
71551
|
var POOL_SETUP_SCRIPT_PATH = "/api/setup.sh";
|
|
71435
71552
|
var POOL_SCRIPT_FETCH_TIMEOUT_MS = 5e3;
|
|
@@ -71455,7 +71572,7 @@ async function fetchScript(deps) {
|
|
|
71455
71572
|
}
|
|
71456
71573
|
function runScript(script, apiKey, deps) {
|
|
71457
71574
|
return new Promise((resolve9, reject) => {
|
|
71458
|
-
const proc = (0,
|
|
71575
|
+
const proc = (0, import_node_child_process22.spawn)("bash", ["-s"], {
|
|
71459
71576
|
env: { ...deps.env ?? process.env, CPA_KEY: apiKey, CPA_MODE: "api" },
|
|
71460
71577
|
stdio: ["pipe", "pipe", "pipe"]
|
|
71461
71578
|
});
|
|
@@ -71500,7 +71617,7 @@ function runScript(script, apiKey, deps) {
|
|
|
71500
71617
|
}
|
|
71501
71618
|
|
|
71502
71619
|
// src/tools/claude-auth-status.ts
|
|
71503
|
-
var
|
|
71620
|
+
var import_node_child_process23 = require("child_process");
|
|
71504
71621
|
var str5 = (v3) => typeof v3 === "string" && v3 ? v3 : void 0;
|
|
71505
71622
|
function mapClaudeAuthStatus(raw) {
|
|
71506
71623
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
@@ -71523,7 +71640,7 @@ function mapClaudeAuthStatus(raw) {
|
|
|
71523
71640
|
};
|
|
71524
71641
|
}
|
|
71525
71642
|
async function queryClaudeAuthStatus(deps = {}) {
|
|
71526
|
-
const run = deps.execFileImpl ??
|
|
71643
|
+
const run = deps.execFileImpl ?? import_node_child_process23.execFile;
|
|
71527
71644
|
const env = deps.env ?? process.env;
|
|
71528
71645
|
const bin = env.CLAUDE_BIN ?? "claude";
|
|
71529
71646
|
const stdout = await new Promise((resolve9, reject) => {
|
|
@@ -71593,12 +71710,12 @@ async function queryCodexAccount(deps = {}) {
|
|
|
71593
71710
|
}
|
|
71594
71711
|
|
|
71595
71712
|
// src/tools/pi-account.ts
|
|
71596
|
-
var
|
|
71597
|
-
var
|
|
71713
|
+
var import_node_fs63 = __toESM(require("fs"), 1);
|
|
71714
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
71598
71715
|
function readPiCredentials(agentDir) {
|
|
71599
71716
|
let raw;
|
|
71600
71717
|
try {
|
|
71601
|
-
raw = JSON.parse(
|
|
71718
|
+
raw = JSON.parse(import_node_fs63.default.readFileSync(import_node_path70.default.join(agentDir, "auth.json"), "utf8"));
|
|
71602
71719
|
} catch {
|
|
71603
71720
|
return {};
|
|
71604
71721
|
}
|
|
@@ -71682,9 +71799,9 @@ function buildEngineHandlers(deps, overrides = {}) {
|
|
|
71682
71799
|
}
|
|
71683
71800
|
|
|
71684
71801
|
// src/tools/subscription-channels-apply.ts
|
|
71685
|
-
var
|
|
71802
|
+
var import_node_fs64 = __toESM(require("fs"), 1);
|
|
71686
71803
|
var import_node_os25 = __toESM(require("os"), 1);
|
|
71687
|
-
var
|
|
71804
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
71688
71805
|
var TABLE_HEADER = /^\s*\[\[?\s*([A-Za-z0-9_.-]+)\s*\]\]?\s*(?:#.*)?$/;
|
|
71689
71806
|
var KEY_LINE = /^\s*([A-Za-z0-9_.-]+)\s*=/;
|
|
71690
71807
|
function stripCodexProvider(text) {
|
|
@@ -71712,10 +71829,10 @@ function stripCodexProvider(text) {
|
|
|
71712
71829
|
return out.join("\n").trim();
|
|
71713
71830
|
}
|
|
71714
71831
|
function applyCodexSubscriptionChannel(opts) {
|
|
71715
|
-
const codexHome = opts.codexHome || process.env.CODEX_HOME ||
|
|
71716
|
-
|
|
71717
|
-
const configFile =
|
|
71718
|
-
const original =
|
|
71832
|
+
const codexHome = opts.codexHome || process.env.CODEX_HOME || import_node_path71.default.join(import_node_os25.default.homedir(), ".codex");
|
|
71833
|
+
import_node_fs64.default.mkdirSync(codexHome, { recursive: true });
|
|
71834
|
+
const configFile = import_node_path71.default.join(codexHome, "config.toml");
|
|
71835
|
+
const original = import_node_fs64.default.existsSync(configFile) ? import_node_fs64.default.readFileSync(configFile, "utf8") : "";
|
|
71719
71836
|
const rest = stripCodexProvider(original);
|
|
71720
71837
|
let content;
|
|
71721
71838
|
if (opts.channel) {
|
|
@@ -71739,18 +71856,18 @@ function applyCodexSubscriptionChannel(opts) {
|
|
|
71739
71856
|
].join("\n");
|
|
71740
71857
|
}
|
|
71741
71858
|
const tmpFile = `${configFile}.tmp.${Date.now()}`;
|
|
71742
|
-
|
|
71743
|
-
|
|
71859
|
+
import_node_fs64.default.writeFileSync(tmpFile, content, { mode: 384 });
|
|
71860
|
+
import_node_fs64.default.renameSync(tmpFile, configFile);
|
|
71744
71861
|
}
|
|
71745
71862
|
function applyPiSubscriptionChannel(opts) {
|
|
71746
|
-
const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR ||
|
|
71747
|
-
if (!
|
|
71748
|
-
const configFile =
|
|
71863
|
+
const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path71.default.join(import_node_os25.default.homedir(), ".pi", "agent");
|
|
71864
|
+
if (!import_node_fs64.default.existsSync(agentDir)) return false;
|
|
71865
|
+
const configFile = import_node_path71.default.join(agentDir, "cliproxyapi.json");
|
|
71749
71866
|
if (opts.channel) {
|
|
71750
71867
|
const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
|
|
71751
71868
|
const tmp = `${configFile}.tmp.${Date.now()}`;
|
|
71752
|
-
|
|
71753
|
-
|
|
71869
|
+
import_node_fs64.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
71870
|
+
import_node_fs64.default.renameSync(tmp, configFile);
|
|
71754
71871
|
return true;
|
|
71755
71872
|
}
|
|
71756
71873
|
return false;
|
|
@@ -72758,21 +72875,21 @@ function computeMethodAccess(args) {
|
|
|
72758
72875
|
}
|
|
72759
72876
|
|
|
72760
72877
|
// src/version.ts
|
|
72761
|
-
var version = "0.2.
|
|
72878
|
+
var version = "0.2.595".length > 0 ? "0.2.595" : "dev";
|
|
72762
72879
|
|
|
72763
72880
|
// src/cli-probe/probe.ts
|
|
72764
|
-
var
|
|
72765
|
-
var
|
|
72881
|
+
var fs83 = __toESM(require("fs"), 1);
|
|
72882
|
+
var path90 = __toESM(require("path"), 1);
|
|
72766
72883
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
72767
72884
|
var BIN_NAME = "clawd";
|
|
72768
72885
|
var MAX_PARENT_HOPS = 5;
|
|
72769
72886
|
function probeGlobalCli(pathEnv) {
|
|
72770
72887
|
if (!pathEnv) return null;
|
|
72771
|
-
for (const dir of pathEnv.split(
|
|
72888
|
+
for (const dir of pathEnv.split(path90.delimiter)) {
|
|
72772
72889
|
if (!dir) continue;
|
|
72773
72890
|
let real;
|
|
72774
72891
|
try {
|
|
72775
|
-
real =
|
|
72892
|
+
real = fs83.realpathSync(path90.join(dir, BIN_NAME));
|
|
72776
72893
|
} catch {
|
|
72777
72894
|
continue;
|
|
72778
72895
|
}
|
|
@@ -72782,15 +72899,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
72782
72899
|
return null;
|
|
72783
72900
|
}
|
|
72784
72901
|
function readOwnPackageVersion(entryPath) {
|
|
72785
|
-
let dir =
|
|
72902
|
+
let dir = path90.dirname(entryPath);
|
|
72786
72903
|
for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
|
|
72787
72904
|
try {
|
|
72788
|
-
const raw =
|
|
72905
|
+
const raw = fs83.readFileSync(path90.join(dir, "package.json"), "utf8");
|
|
72789
72906
|
const pkg = JSON.parse(raw);
|
|
72790
72907
|
if (pkg.name !== PKG_NAME) return null;
|
|
72791
72908
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
72792
72909
|
} catch {
|
|
72793
|
-
const parent =
|
|
72910
|
+
const parent = path90.dirname(dir);
|
|
72794
72911
|
if (parent === dir) return null;
|
|
72795
72912
|
dir = parent;
|
|
72796
72913
|
}
|
|
@@ -72966,7 +73083,7 @@ function buildPersonaHandlers(deps) {
|
|
|
72966
73083
|
}
|
|
72967
73084
|
|
|
72968
73085
|
// src/handlers/attachment.ts
|
|
72969
|
-
var
|
|
73086
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
72970
73087
|
init_protocol();
|
|
72971
73088
|
init_protocol();
|
|
72972
73089
|
function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
|
|
@@ -73045,12 +73162,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
73045
73162
|
`session ${args.sessionId} scope unresolved`
|
|
73046
73163
|
);
|
|
73047
73164
|
}
|
|
73048
|
-
const cwdAbs =
|
|
73049
|
-
const candidateAbs =
|
|
73165
|
+
const cwdAbs = import_node_path72.default.resolve(sessionFile.cwd);
|
|
73166
|
+
const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
|
|
73050
73167
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
73051
73168
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
73052
73169
|
const entry = entries.find((e) => {
|
|
73053
|
-
const storedAbs =
|
|
73170
|
+
const storedAbs = import_node_path72.default.isAbsolute(e.relPath) ? import_node_path72.default.resolve(e.relPath) : import_node_path72.default.resolve(cwdAbs, e.relPath);
|
|
73054
73171
|
return storedAbs === candidateAbs && !e.stale;
|
|
73055
73172
|
});
|
|
73056
73173
|
if (!entry) {
|
|
@@ -73074,7 +73191,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
73074
73191
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
73075
73192
|
const f2 = deps.sessionStore.read(sessionId);
|
|
73076
73193
|
if (!f2) return;
|
|
73077
|
-
assertGuestAttachmentPath(ctx,
|
|
73194
|
+
assertGuestAttachmentPath(ctx, import_node_path72.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
73078
73195
|
}
|
|
73079
73196
|
const groupAdd = async (frame, _client, ctx) => {
|
|
73080
73197
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -73089,8 +73206,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
73089
73206
|
if (!scope) {
|
|
73090
73207
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
73091
73208
|
}
|
|
73092
|
-
const cwdAbs =
|
|
73093
|
-
const candidateAbs =
|
|
73209
|
+
const cwdAbs = import_node_path72.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
73210
|
+
const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
|
|
73094
73211
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
73095
73212
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
73096
73213
|
const size = 0;
|
|
@@ -73149,19 +73266,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
73149
73266
|
|
|
73150
73267
|
// src/handlers/extension.ts
|
|
73151
73268
|
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
73152
|
-
var
|
|
73269
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
73153
73270
|
init_protocol();
|
|
73154
73271
|
|
|
73155
73272
|
// src/extension/bundle-zip.ts
|
|
73156
73273
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
73157
|
-
var
|
|
73274
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
73158
73275
|
var import_node_crypto22 = __toESM(require("crypto"), 1);
|
|
73159
73276
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
73160
73277
|
async function bundleExtensionDir(dir) {
|
|
73161
73278
|
const entries = await listFilesSorted(dir);
|
|
73162
73279
|
const zip = new import_jszip2.default();
|
|
73163
73280
|
for (const rel of entries) {
|
|
73164
|
-
const abs =
|
|
73281
|
+
const abs = import_node_path73.default.join(dir, rel);
|
|
73165
73282
|
const content = await import_promises12.default.readFile(abs);
|
|
73166
73283
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
73167
73284
|
}
|
|
@@ -73182,7 +73299,7 @@ async function listFilesSorted(rootDir) {
|
|
|
73182
73299
|
return out;
|
|
73183
73300
|
}
|
|
73184
73301
|
async function walk(absRoot, relPrefix, out) {
|
|
73185
|
-
const dirAbs =
|
|
73302
|
+
const dirAbs = import_node_path73.default.join(absRoot, relPrefix);
|
|
73186
73303
|
const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
|
|
73187
73304
|
for (const e of entries) {
|
|
73188
73305
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -73236,25 +73353,25 @@ function computePublishCheck(args) {
|
|
|
73236
73353
|
|
|
73237
73354
|
// src/extension/install-flow.ts
|
|
73238
73355
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
73239
|
-
var
|
|
73356
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
73240
73357
|
var import_node_os28 = __toESM(require("os"), 1);
|
|
73241
73358
|
var import_node_crypto23 = __toESM(require("crypto"), 1);
|
|
73242
73359
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
73243
73360
|
|
|
73244
73361
|
// src/extension/paths.ts
|
|
73245
73362
|
var import_node_os27 = __toESM(require("os"), 1);
|
|
73246
|
-
var
|
|
73363
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
73247
73364
|
function clawdHomeRoot(override) {
|
|
73248
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
73365
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path74.default.join(import_node_os27.default.homedir(), ".clawd");
|
|
73249
73366
|
}
|
|
73250
73367
|
function extensionsRoot(override) {
|
|
73251
|
-
return
|
|
73368
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extensions");
|
|
73252
73369
|
}
|
|
73253
73370
|
function publishedChannelsFile(override) {
|
|
73254
|
-
return
|
|
73371
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
73255
73372
|
}
|
|
73256
73373
|
function bundleCacheRoot(override) {
|
|
73257
|
-
return
|
|
73374
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
73258
73375
|
}
|
|
73259
73376
|
|
|
73260
73377
|
// src/extension/install-flow.ts
|
|
@@ -73281,7 +73398,7 @@ async function installFromChannel(args, deps) {
|
|
|
73281
73398
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
73282
73399
|
}
|
|
73283
73400
|
for (const name of Object.keys(zip.files)) {
|
|
73284
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73401
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
|
|
73285
73402
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
73286
73403
|
}
|
|
73287
73404
|
}
|
|
@@ -73313,7 +73430,7 @@ async function installFromChannel(args, deps) {
|
|
|
73313
73430
|
);
|
|
73314
73431
|
}
|
|
73315
73432
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
73316
|
-
const destDir =
|
|
73433
|
+
const destDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
|
|
73317
73434
|
let destExists = false;
|
|
73318
73435
|
try {
|
|
73319
73436
|
await import_promises13.default.access(destDir);
|
|
@@ -73327,16 +73444,16 @@ async function installFromChannel(args, deps) {
|
|
|
73327
73444
|
);
|
|
73328
73445
|
}
|
|
73329
73446
|
const stage = await import_promises13.default.mkdtemp(
|
|
73330
|
-
|
|
73447
|
+
import_node_path75.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
73331
73448
|
);
|
|
73332
73449
|
try {
|
|
73333
73450
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
73334
|
-
const dest =
|
|
73451
|
+
const dest = import_node_path75.default.join(stage, name);
|
|
73335
73452
|
if (entry.dir) {
|
|
73336
73453
|
await import_promises13.default.mkdir(dest, { recursive: true });
|
|
73337
73454
|
continue;
|
|
73338
73455
|
}
|
|
73339
|
-
await import_promises13.default.mkdir(
|
|
73456
|
+
await import_promises13.default.mkdir(import_node_path75.default.dirname(dest), { recursive: true });
|
|
73340
73457
|
if (name === "manifest.json") {
|
|
73341
73458
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
73342
73459
|
await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -73357,7 +73474,7 @@ async function installFromChannel(args, deps) {
|
|
|
73357
73474
|
|
|
73358
73475
|
// src/extension/update-flow.ts
|
|
73359
73476
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
73360
|
-
var
|
|
73477
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
73361
73478
|
var import_node_os29 = __toESM(require("os"), 1);
|
|
73362
73479
|
var import_node_crypto24 = __toESM(require("crypto"), 1);
|
|
73363
73480
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -73374,11 +73491,11 @@ async function updateFromChannel(args, deps) {
|
|
|
73374
73491
|
channelRef.extId,
|
|
73375
73492
|
channelRef.ownerPrincipalId
|
|
73376
73493
|
);
|
|
73377
|
-
const liveDir =
|
|
73494
|
+
const liveDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
|
|
73378
73495
|
const prevDir = `${liveDir}.prev`;
|
|
73379
73496
|
let existingVersion;
|
|
73380
73497
|
try {
|
|
73381
|
-
const raw = await import_promises14.default.readFile(
|
|
73498
|
+
const raw = await import_promises14.default.readFile(import_node_path76.default.join(liveDir, "manifest.json"), "utf8");
|
|
73382
73499
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
73383
73500
|
if (!parsed2.success) {
|
|
73384
73501
|
throw new UpdateError(
|
|
@@ -73411,7 +73528,7 @@ async function updateFromChannel(args, deps) {
|
|
|
73411
73528
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
73412
73529
|
}
|
|
73413
73530
|
for (const name of Object.keys(zip.files)) {
|
|
73414
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73531
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
|
|
73415
73532
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
73416
73533
|
}
|
|
73417
73534
|
}
|
|
@@ -73446,16 +73563,16 @@ async function updateFromChannel(args, deps) {
|
|
|
73446
73563
|
await import_promises14.default.rm(prevDir, { recursive: true, force: true });
|
|
73447
73564
|
await import_promises14.default.rename(liveDir, prevDir);
|
|
73448
73565
|
const stage = await import_promises14.default.mkdtemp(
|
|
73449
|
-
|
|
73566
|
+
import_node_path76.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
73450
73567
|
);
|
|
73451
73568
|
try {
|
|
73452
73569
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
73453
|
-
const dest =
|
|
73570
|
+
const dest = import_node_path76.default.join(stage, name);
|
|
73454
73571
|
if (entry.dir) {
|
|
73455
73572
|
await import_promises14.default.mkdir(dest, { recursive: true });
|
|
73456
73573
|
continue;
|
|
73457
73574
|
}
|
|
73458
|
-
await import_promises14.default.mkdir(
|
|
73575
|
+
await import_promises14.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
|
|
73459
73576
|
if (name === "manifest.json") {
|
|
73460
73577
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
73461
73578
|
await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -73522,7 +73639,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73522
73639
|
);
|
|
73523
73640
|
}
|
|
73524
73641
|
}
|
|
73525
|
-
const manifestPath =
|
|
73642
|
+
const manifestPath = import_node_path77.default.join(root, extId, "manifest.json");
|
|
73526
73643
|
const manifest = await readManifest(root, extId);
|
|
73527
73644
|
const next = { ...manifest, version: newVersion };
|
|
73528
73645
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -73530,7 +73647,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73530
73647
|
await import_promises15.default.rename(tmp, manifestPath);
|
|
73531
73648
|
}
|
|
73532
73649
|
async function readManifest(root, extId) {
|
|
73533
|
-
const file =
|
|
73650
|
+
const file = import_node_path77.default.join(root, extId, "manifest.json");
|
|
73534
73651
|
let raw;
|
|
73535
73652
|
try {
|
|
73536
73653
|
raw = await import_promises15.default.readFile(file, "utf8");
|
|
@@ -73614,7 +73731,7 @@ function buildExtensionHandlers(deps) {
|
|
|
73614
73731
|
};
|
|
73615
73732
|
async function buildSnapshotMeta(extId) {
|
|
73616
73733
|
const manifest = await readManifest(deps.root, extId);
|
|
73617
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
73734
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path77.default.join(deps.root, extId));
|
|
73618
73735
|
return { manifest, contentHash: sha256, buffer };
|
|
73619
73736
|
}
|
|
73620
73737
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -74442,7 +74559,7 @@ function buildVisitorHandlers(deps) {
|
|
|
74442
74559
|
|
|
74443
74560
|
// src/extension/registry.ts
|
|
74444
74561
|
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
74445
|
-
var
|
|
74562
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
74446
74563
|
async function loadAll(root) {
|
|
74447
74564
|
let entries;
|
|
74448
74565
|
try {
|
|
@@ -74455,13 +74572,13 @@ async function loadAll(root) {
|
|
|
74455
74572
|
for (const ent of entries) {
|
|
74456
74573
|
if (!ent.isDirectory()) continue;
|
|
74457
74574
|
if (ent.name.startsWith(".")) continue;
|
|
74458
|
-
records.push(await loadOne(
|
|
74575
|
+
records.push(await loadOne(import_node_path78.default.join(root, ent.name), ent.name));
|
|
74459
74576
|
}
|
|
74460
74577
|
records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
|
|
74461
74578
|
return records;
|
|
74462
74579
|
}
|
|
74463
74580
|
async function loadOne(dir, dirName) {
|
|
74464
|
-
const manifestPath =
|
|
74581
|
+
const manifestPath = import_node_path78.default.join(dir, "manifest.json");
|
|
74465
74582
|
let raw;
|
|
74466
74583
|
try {
|
|
74467
74584
|
raw = await import_promises17.default.readFile(manifestPath, "utf8");
|
|
@@ -74506,7 +74623,7 @@ async function loadOne(dir, dirName) {
|
|
|
74506
74623
|
|
|
74507
74624
|
// src/extension/uninstall.ts
|
|
74508
74625
|
var import_promises18 = __toESM(require("fs/promises"), 1);
|
|
74509
|
-
var
|
|
74626
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
74510
74627
|
var UninstallError = class extends Error {
|
|
74511
74628
|
constructor(code, message) {
|
|
74512
74629
|
super(message);
|
|
@@ -74515,7 +74632,7 @@ var UninstallError = class extends Error {
|
|
|
74515
74632
|
code;
|
|
74516
74633
|
};
|
|
74517
74634
|
async function uninstall(deps) {
|
|
74518
|
-
const dir =
|
|
74635
|
+
const dir = import_node_path79.default.join(deps.root, deps.extId);
|
|
74519
74636
|
try {
|
|
74520
74637
|
await import_promises18.default.access(dir);
|
|
74521
74638
|
} catch {
|
|
@@ -74532,7 +74649,7 @@ var import_node_crypto25 = require("crypto");
|
|
|
74532
74649
|
init_protocol();
|
|
74533
74650
|
|
|
74534
74651
|
// src/peer-ops/run-command.ts
|
|
74535
|
-
var
|
|
74652
|
+
var import_node_child_process24 = require("child_process");
|
|
74536
74653
|
var import_node_os30 = __toESM(require("os"), 1);
|
|
74537
74654
|
var DEFAULT_TIMEOUT_MS6 = 3e4;
|
|
74538
74655
|
var MAX_TIMEOUT_MS = 3e5;
|
|
@@ -74540,7 +74657,7 @@ var MAX_OUTPUT_BYTES = 1048576;
|
|
|
74540
74657
|
function runCommand2(command, opts = {}) {
|
|
74541
74658
|
const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6, MAX_TIMEOUT_MS);
|
|
74542
74659
|
return new Promise((resolve9) => {
|
|
74543
|
-
const child = (0,
|
|
74660
|
+
const child = (0, import_node_child_process24.spawn)("bash", ["-c", command], { cwd: import_node_os30.default.homedir() });
|
|
74544
74661
|
const out = [];
|
|
74545
74662
|
const err = [];
|
|
74546
74663
|
let outBytes = 0;
|
|
@@ -74733,7 +74850,7 @@ function buildMethodHandlers(deps) {
|
|
|
74733
74850
|
broadcast: deps.broadcastToOwners
|
|
74734
74851
|
}),
|
|
74735
74852
|
...buildMasterHandlers({
|
|
74736
|
-
authorityTablePath:
|
|
74853
|
+
authorityTablePath: import_node_path80.default.join(deps.masterDataDir, "master-authority.json")
|
|
74737
74854
|
}),
|
|
74738
74855
|
...buildTopicHandlers({
|
|
74739
74856
|
topicStore: deps.topicStore,
|
|
@@ -74875,8 +74992,8 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
74875
74992
|
}
|
|
74876
74993
|
|
|
74877
74994
|
// src/extension/runtime.ts
|
|
74878
|
-
var
|
|
74879
|
-
var
|
|
74995
|
+
var import_node_child_process25 = require("child_process");
|
|
74996
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
74880
74997
|
var import_promises19 = require("timers/promises");
|
|
74881
74998
|
|
|
74882
74999
|
// src/extension/port-allocator.ts
|
|
@@ -74977,13 +75094,13 @@ var Runtime = class {
|
|
|
74977
75094
|
/\$CLAWOS_EXT_PORT/g,
|
|
74978
75095
|
String(port)
|
|
74979
75096
|
);
|
|
74980
|
-
const dir =
|
|
75097
|
+
const dir = import_node_path81.default.join(this.root, extId);
|
|
74981
75098
|
const env = {
|
|
74982
75099
|
...process.env,
|
|
74983
75100
|
CLAWOS_EXT_PORT: String(port),
|
|
74984
75101
|
CLAWOS_EXT_ID: extId
|
|
74985
75102
|
};
|
|
74986
|
-
const child = (0,
|
|
75103
|
+
const child = (0, import_node_child_process25.spawn)("sh", ["-c", cmd], {
|
|
74987
75104
|
cwd: dir,
|
|
74988
75105
|
env,
|
|
74989
75106
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -75089,7 +75206,7 @@ ${handle.stderrTail}`
|
|
|
75089
75206
|
|
|
75090
75207
|
// src/extension/published-channels.ts
|
|
75091
75208
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
75092
|
-
var
|
|
75209
|
+
var import_node_path82 = __toESM(require("path"), 1);
|
|
75093
75210
|
init_zod();
|
|
75094
75211
|
var PublishedChannelsError = class extends Error {
|
|
75095
75212
|
constructor(code, message) {
|
|
@@ -75188,7 +75305,7 @@ var PublishedChannelStore = class {
|
|
|
75188
75305
|
)
|
|
75189
75306
|
};
|
|
75190
75307
|
const tmp = `${this.filePath}.tmp`;
|
|
75191
|
-
await import_promises20.default.mkdir(
|
|
75308
|
+
await import_promises20.default.mkdir(import_node_path82.default.dirname(this.filePath), { recursive: true });
|
|
75192
75309
|
await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
75193
75310
|
await import_promises20.default.rename(tmp, this.filePath);
|
|
75194
75311
|
}
|
|
@@ -75196,7 +75313,7 @@ var PublishedChannelStore = class {
|
|
|
75196
75313
|
|
|
75197
75314
|
// src/extension/bundle-cache.ts
|
|
75198
75315
|
var import_promises21 = __toESM(require("fs/promises"), 1);
|
|
75199
|
-
var
|
|
75316
|
+
var import_node_path83 = __toESM(require("path"), 1);
|
|
75200
75317
|
var BundleCache = class {
|
|
75201
75318
|
constructor(rootDir) {
|
|
75202
75319
|
this.rootDir = rootDir;
|
|
@@ -75205,14 +75322,14 @@ var BundleCache = class {
|
|
|
75205
75322
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
75206
75323
|
async write(snapshotHash, buffer) {
|
|
75207
75324
|
await import_promises21.default.mkdir(this.rootDir, { recursive: true });
|
|
75208
|
-
const file =
|
|
75325
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
75209
75326
|
const tmp = `${file}.tmp`;
|
|
75210
75327
|
await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
|
|
75211
75328
|
await import_promises21.default.rename(tmp, file);
|
|
75212
75329
|
}
|
|
75213
75330
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
75214
75331
|
async read(snapshotHash) {
|
|
75215
|
-
const file =
|
|
75332
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
75216
75333
|
try {
|
|
75217
75334
|
return await import_promises21.default.readFile(file);
|
|
75218
75335
|
} catch (e) {
|
|
@@ -75222,7 +75339,7 @@ var BundleCache = class {
|
|
|
75222
75339
|
}
|
|
75223
75340
|
/** Idempotent — missing file is not an error. */
|
|
75224
75341
|
async delete(snapshotHash) {
|
|
75225
|
-
const file =
|
|
75342
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
75226
75343
|
await import_promises21.default.rm(file, { force: true });
|
|
75227
75344
|
}
|
|
75228
75345
|
};
|
|
@@ -75245,24 +75362,24 @@ async function startDaemon(config) {
|
|
|
75245
75362
|
sampling: logShippingCfg.sampling,
|
|
75246
75363
|
homeDir: import_node_os31.default.homedir()
|
|
75247
75364
|
});
|
|
75248
|
-
const logDir =
|
|
75249
|
-
|
|
75365
|
+
const logDir = import_node_path84.default.join(config.dataDir, "log");
|
|
75366
|
+
import_node_fs65.default.mkdirSync(logDir, { recursive: true });
|
|
75250
75367
|
const logger = createLogger({
|
|
75251
75368
|
level: config.logLevel,
|
|
75252
|
-
file:
|
|
75369
|
+
file: import_node_path84.default.join(logDir, "clawd.log"),
|
|
75253
75370
|
logClient
|
|
75254
75371
|
});
|
|
75255
75372
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
75256
75373
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
75257
|
-
file:
|
|
75374
|
+
file: import_node_path84.default.join(logDir, "screen-idle-probe.log"),
|
|
75258
75375
|
level: "debug"
|
|
75259
75376
|
});
|
|
75260
75377
|
logger.info("screen-idle probe logger enabled", {
|
|
75261
|
-
file:
|
|
75378
|
+
file: import_node_path84.default.join(logDir, "screen-idle-probe.log")
|
|
75262
75379
|
});
|
|
75263
75380
|
const CAP_TARGETS = [
|
|
75264
|
-
|
|
75265
|
-
|
|
75381
|
+
import_node_path84.default.join(logDir, "clawd.log"),
|
|
75382
|
+
import_node_path84.default.join(logDir, "screen-idle-probe.log")
|
|
75266
75383
|
];
|
|
75267
75384
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
75268
75385
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -75384,9 +75501,9 @@ async function startDaemon(config) {
|
|
|
75384
75501
|
const agents = new AgentsScanner();
|
|
75385
75502
|
const history = new ClaudeHistoryReader();
|
|
75386
75503
|
let transport = null;
|
|
75387
|
-
const personaStore = new PersonaStore(
|
|
75504
|
+
const personaStore = new PersonaStore(import_node_path84.default.join(config.dataDir, "personas"));
|
|
75388
75505
|
const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
|
|
75389
|
-
const usersRoot =
|
|
75506
|
+
const usersRoot = import_node_path84.default.join(config.dataDir, "users");
|
|
75390
75507
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
75391
75508
|
if (defaultsRoot) {
|
|
75392
75509
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -75403,7 +75520,7 @@ async function startDaemon(config) {
|
|
|
75403
75520
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
75404
75521
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
75405
75522
|
const dispatchStore = createDispatchStore({
|
|
75406
|
-
filePath:
|
|
75523
|
+
filePath: import_node_path84.default.join(config.dataDir, "dispatch.json"),
|
|
75407
75524
|
now: () => Date.now(),
|
|
75408
75525
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
75409
75526
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -75412,7 +75529,7 @@ async function startDaemon(config) {
|
|
|
75412
75529
|
await dispatchStore.load();
|
|
75413
75530
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
75414
75531
|
const channelStore = createChannelStore({
|
|
75415
|
-
filePath:
|
|
75532
|
+
filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
|
|
75416
75533
|
now: () => Date.now(),
|
|
75417
75534
|
genId: () => `ch-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75418
75535
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
@@ -75421,7 +75538,7 @@ async function startDaemon(config) {
|
|
|
75421
75538
|
});
|
|
75422
75539
|
await channelStore.load();
|
|
75423
75540
|
const topicStore = createTopicStore({
|
|
75424
|
-
filePath:
|
|
75541
|
+
filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
|
|
75425
75542
|
now: () => Date.now(),
|
|
75426
75543
|
genId: () => `tp-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75427
75544
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
@@ -75448,12 +75565,12 @@ async function startDaemon(config) {
|
|
|
75448
75565
|
});
|
|
75449
75566
|
}
|
|
75450
75567
|
});
|
|
75451
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
75568
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path84.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
|
|
75452
75569
|
const mcpConfigs = [];
|
|
75453
75570
|
const secretsBundleRoot = findSecretsBundleRoot(logger);
|
|
75454
|
-
const localSecretsDir =
|
|
75571
|
+
const localSecretsDir = import_node_path84.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
75455
75572
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
75456
|
-
const githubTokenFile =
|
|
75573
|
+
const githubTokenFile = import_node_path84.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
|
|
75457
75574
|
const githubIdentity = createGithubIdentity({
|
|
75458
75575
|
resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
|
|
75459
75576
|
store: (token) => storeGithubAuth({
|
|
@@ -75491,22 +75608,22 @@ async function startDaemon(config) {
|
|
|
75491
75608
|
void githubIdentity.refresh();
|
|
75492
75609
|
return renderPersonaMcpSecrets({
|
|
75493
75610
|
personaId: personaId2,
|
|
75494
|
-
personaDir:
|
|
75611
|
+
personaDir: import_node_path84.default.join(config.dataDir, "personas", personaId2),
|
|
75495
75612
|
secrets,
|
|
75496
|
-
outDir:
|
|
75613
|
+
outDir: import_node_path84.default.join(config.dataDir, "persona-mcp"),
|
|
75497
75614
|
logger
|
|
75498
75615
|
});
|
|
75499
75616
|
};
|
|
75500
75617
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
75501
75618
|
const dispatchServerCandidates = [
|
|
75502
|
-
|
|
75619
|
+
import_node_path84.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
75503
75620
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
75504
|
-
|
|
75621
|
+
import_node_path84.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
75505
75622
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
75506
75623
|
];
|
|
75507
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) =>
|
|
75624
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75508
75625
|
if (dispatchServerScriptPath) {
|
|
75509
|
-
const dispatchLogPath =
|
|
75626
|
+
const dispatchLogPath = import_node_path84.default.join(logDir, "dispatch-mcp-server.log");
|
|
75510
75627
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
75511
75628
|
dataDir: config.dataDir,
|
|
75512
75629
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -75526,12 +75643,12 @@ async function startDaemon(config) {
|
|
|
75526
75643
|
});
|
|
75527
75644
|
}
|
|
75528
75645
|
const ticketServerCandidates = [
|
|
75529
|
-
|
|
75530
|
-
|
|
75646
|
+
import_node_path84.default.join(here, "ticket", "mcp-server.cjs"),
|
|
75647
|
+
import_node_path84.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
75531
75648
|
];
|
|
75532
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p3) =>
|
|
75649
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75533
75650
|
if (ticketServerScriptPath) {
|
|
75534
|
-
const ticketLogPath =
|
|
75651
|
+
const ticketLogPath = import_node_path84.default.join(logDir, "ticket-mcp-server.log");
|
|
75535
75652
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
75536
75653
|
dataDir: config.dataDir,
|
|
75537
75654
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -75553,12 +75670,12 @@ async function startDaemon(config) {
|
|
|
75553
75670
|
});
|
|
75554
75671
|
}
|
|
75555
75672
|
const shiftServerCandidates = [
|
|
75556
|
-
|
|
75557
|
-
|
|
75673
|
+
import_node_path84.default.join(here, "shift", "mcp-server.cjs"),
|
|
75674
|
+
import_node_path84.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
75558
75675
|
];
|
|
75559
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p3) =>
|
|
75676
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75560
75677
|
if (shiftServerScriptPath) {
|
|
75561
|
-
const shiftLogPath =
|
|
75678
|
+
const shiftLogPath = import_node_path84.default.join(logDir, "shift-mcp-server.log");
|
|
75562
75679
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
75563
75680
|
dataDir: config.dataDir,
|
|
75564
75681
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -75579,12 +75696,12 @@ async function startDaemon(config) {
|
|
|
75579
75696
|
);
|
|
75580
75697
|
}
|
|
75581
75698
|
const inboxServerCandidates = [
|
|
75582
|
-
|
|
75583
|
-
|
|
75699
|
+
import_node_path84.default.join(here, "inbox", "mcp-server.cjs"),
|
|
75700
|
+
import_node_path84.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
75584
75701
|
];
|
|
75585
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p3) =>
|
|
75702
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75586
75703
|
if (inboxServerScriptPath) {
|
|
75587
|
-
const inboxLogPath =
|
|
75704
|
+
const inboxLogPath = import_node_path84.default.join(logDir, "inbox-mcp-server.log");
|
|
75588
75705
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
75589
75706
|
dataDir: config.dataDir,
|
|
75590
75707
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -75605,10 +75722,10 @@ async function startDaemon(config) {
|
|
|
75605
75722
|
);
|
|
75606
75723
|
}
|
|
75607
75724
|
const peerOpsServerCandidates = [
|
|
75608
|
-
|
|
75609
|
-
|
|
75725
|
+
import_node_path84.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
75726
|
+
import_node_path84.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
75610
75727
|
];
|
|
75611
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) =>
|
|
75728
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75612
75729
|
if (peerOpsServerScriptPath) {
|
|
75613
75730
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
75614
75731
|
dataDir: config.dataDir,
|
|
@@ -75628,12 +75745,12 @@ async function startDaemon(config) {
|
|
|
75628
75745
|
);
|
|
75629
75746
|
}
|
|
75630
75747
|
const rpcToolServerCandidates = [
|
|
75631
|
-
|
|
75632
|
-
|
|
75748
|
+
import_node_path84.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
75749
|
+
import_node_path84.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
75633
75750
|
];
|
|
75634
|
-
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) =>
|
|
75751
|
+
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75635
75752
|
if (rpcToolServerScriptPath) {
|
|
75636
|
-
const rpcToolLogPath =
|
|
75753
|
+
const rpcToolLogPath = import_node_path84.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
75637
75754
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
75638
75755
|
dataDir: config.dataDir,
|
|
75639
75756
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -75654,7 +75771,7 @@ async function startDaemon(config) {
|
|
|
75654
75771
|
);
|
|
75655
75772
|
}
|
|
75656
75773
|
const shiftStore = createShiftStore({
|
|
75657
|
-
filePath:
|
|
75774
|
+
filePath: import_node_path84.default.join(config.dataDir, "shift.json"),
|
|
75658
75775
|
ownerIdProvider: () => ownerPrincipalId,
|
|
75659
75776
|
now: () => Date.now()
|
|
75660
75777
|
});
|
|
@@ -75676,7 +75793,7 @@ async function startDaemon(config) {
|
|
|
75676
75793
|
getAdapter,
|
|
75677
75794
|
historyReader: history,
|
|
75678
75795
|
dataDir: config.dataDir,
|
|
75679
|
-
personaRoot:
|
|
75796
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
75680
75797
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
75681
75798
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
75682
75799
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
@@ -75733,10 +75850,10 @@ async function startDaemon(config) {
|
|
|
75733
75850
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
75734
75851
|
attachmentGroup: {
|
|
75735
75852
|
onFileEdit: (input) => {
|
|
75736
|
-
const absPath =
|
|
75853
|
+
const absPath = import_node_path84.default.isAbsolute(input.relPath) ? input.relPath : import_node_path84.default.join(input.cwd, input.relPath);
|
|
75737
75854
|
let size = 0;
|
|
75738
75855
|
try {
|
|
75739
|
-
size =
|
|
75856
|
+
size = import_node_fs65.default.statSync(absPath).size;
|
|
75740
75857
|
} catch (err) {
|
|
75741
75858
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
75742
75859
|
sessionId: input.sessionId,
|
|
@@ -75777,9 +75894,9 @@ async function startDaemon(config) {
|
|
|
75777
75894
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
75778
75895
|
}
|
|
75779
75896
|
const projectsStore = new ProjectsStore({
|
|
75780
|
-
file:
|
|
75897
|
+
file: import_node_path84.default.join(config.dataDir, "projects.json"),
|
|
75781
75898
|
clawdDir: config.dataDir,
|
|
75782
|
-
codexStateFile:
|
|
75899
|
+
codexStateFile: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
75783
75900
|
logger
|
|
75784
75901
|
});
|
|
75785
75902
|
const observer = new SessionObserver({
|
|
@@ -75844,13 +75961,13 @@ async function startDaemon(config) {
|
|
|
75844
75961
|
logger
|
|
75845
75962
|
});
|
|
75846
75963
|
registerAdapter("claude", claudeAdapter);
|
|
75847
|
-
const codexIsolatedHome =
|
|
75964
|
+
const codexIsolatedHome = import_node_path84.default.join(config.dataDir, "codex-home");
|
|
75848
75965
|
try {
|
|
75849
|
-
|
|
75966
|
+
import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
75850
75967
|
for (const f2 of ["auth.json", "config.toml"]) {
|
|
75851
|
-
const link =
|
|
75852
|
-
const target =
|
|
75853
|
-
if (!
|
|
75968
|
+
const link = import_node_path84.default.join(codexIsolatedHome, f2);
|
|
75969
|
+
const target = import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", f2);
|
|
75970
|
+
if (!import_node_fs65.default.existsSync(link) && import_node_fs65.default.existsSync(target)) import_node_fs65.default.symlinkSync(target, link);
|
|
75854
75971
|
}
|
|
75855
75972
|
} catch (err) {
|
|
75856
75973
|
logger.warn("codex isolated home setup failed", { err: String(err) });
|
|
@@ -75861,19 +75978,20 @@ async function startDaemon(config) {
|
|
|
75861
75978
|
logger,
|
|
75862
75979
|
historyReader: new CodexHistoryReader({
|
|
75863
75980
|
roots: codexRolloutRoots(config.dataDir),
|
|
75864
|
-
sharedHome:
|
|
75981
|
+
sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
75865
75982
|
logger
|
|
75866
75983
|
}),
|
|
75867
75984
|
// projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
|
|
75868
75985
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
75869
75986
|
cwd,
|
|
75870
|
-
personaRoot:
|
|
75987
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
75871
75988
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
75872
75989
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
75873
75990
|
projectPaths: projectsStore.listMerged().map((x2) => x2.path),
|
|
75874
|
-
sharedHome:
|
|
75991
|
+
sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
75875
75992
|
isolatedHome: codexIsolatedHome
|
|
75876
75993
|
}),
|
|
75994
|
+
codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
|
|
75877
75995
|
// 附件图片验签:与 http-router /files 路由同一把 secret
|
|
75878
75996
|
getSignSecret: () => authFile.token
|
|
75879
75997
|
})
|
|
@@ -75896,10 +76014,10 @@ async function startDaemon(config) {
|
|
|
75896
76014
|
);
|
|
75897
76015
|
registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
|
|
75898
76016
|
const piMcpBridgeCandidates = [
|
|
75899
|
-
|
|
75900
|
-
|
|
76017
|
+
import_node_path84.default.join(here, "pi-mcp-bridge", "extension.cjs"),
|
|
76018
|
+
import_node_path84.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
|
|
75901
76019
|
];
|
|
75902
|
-
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) =>
|
|
76020
|
+
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75903
76021
|
if (piMcpBridgePath) {
|
|
75904
76022
|
logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
|
|
75905
76023
|
} else {
|
|
@@ -76195,11 +76313,11 @@ async function startDaemon(config) {
|
|
|
76195
76313
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
76196
76314
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
76197
76315
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
76198
|
-
personaRoot:
|
|
76316
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
76199
76317
|
usersRoot
|
|
76200
76318
|
},
|
|
76201
76319
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
76202
|
-
personaRoot:
|
|
76320
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
76203
76321
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
76204
76322
|
usersRoot,
|
|
76205
76323
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -76505,7 +76623,7 @@ async function startDaemon(config) {
|
|
|
76505
76623
|
});
|
|
76506
76624
|
shiftScheduler.start();
|
|
76507
76625
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
76508
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
76626
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path84.default.join(config.dataDir, "personas"));
|
|
76509
76627
|
const larkBotCloud = createLarkBotCloudClient({
|
|
76510
76628
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
76511
76629
|
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
|
|
@@ -76517,7 +76635,7 @@ async function startDaemon(config) {
|
|
|
76517
76635
|
store: larkBotStore,
|
|
76518
76636
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
76519
76637
|
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
76520
|
-
mediaRootFor: (chatId) =>
|
|
76638
|
+
mediaRootFor: (chatId) => import_node_path84.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
76521
76639
|
isShuttingDown: () => larkDraining,
|
|
76522
76640
|
logger: {
|
|
76523
76641
|
warn: (msg) => logger.warn(msg),
|
|
@@ -76817,8 +76935,8 @@ async function startDaemon(config) {
|
|
|
76817
76935
|
const lines = [
|
|
76818
76936
|
`Tunnel: ${r2.url}`,
|
|
76819
76937
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
76820
|
-
`Frpc config: ${
|
|
76821
|
-
`Frpc log: ${
|
|
76938
|
+
`Frpc config: ${import_node_path84.default.join(config.dataDir, "frpc.toml")}`,
|
|
76939
|
+
`Frpc log: ${import_node_path84.default.join(logDir, "frpc.log")}`
|
|
76822
76940
|
];
|
|
76823
76941
|
const width2 = Math.max(...lines.map((l2) => l2.length));
|
|
76824
76942
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -76831,8 +76949,8 @@ ${bar}
|
|
|
76831
76949
|
|
|
76832
76950
|
`);
|
|
76833
76951
|
try {
|
|
76834
|
-
const connectPath =
|
|
76835
|
-
|
|
76952
|
+
const connectPath = import_node_path84.default.join(config.dataDir, "connect.txt");
|
|
76953
|
+
import_node_fs65.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
76836
76954
|
} catch {
|
|
76837
76955
|
}
|
|
76838
76956
|
} catch (err) {
|
|
@@ -76930,9 +77048,9 @@ ${bar}
|
|
|
76930
77048
|
};
|
|
76931
77049
|
}
|
|
76932
77050
|
function migrateDropPersonsDir(dataDir) {
|
|
76933
|
-
const dir =
|
|
77051
|
+
const dir = import_node_path84.default.join(dataDir, "persons");
|
|
76934
77052
|
try {
|
|
76935
|
-
|
|
77053
|
+
import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
|
|
76936
77054
|
} catch {
|
|
76937
77055
|
}
|
|
76938
77056
|
}
|