@clawos-dev/clawd 0.2.593 → 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 +691 -635
- 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],
|
|
@@ -11240,7 +11250,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11240
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,7 +11304,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11294
11304
|
const mode = sonic.mode;
|
|
11295
11305
|
if (sonic.sync) {
|
|
11296
11306
|
try {
|
|
11297
|
-
if (sonic.mkdir) fs95.mkdirSync(
|
|
11307
|
+
if (sonic.mkdir) fs95.mkdirSync(path106.dirname(file), { recursive: true });
|
|
11298
11308
|
const fd = fs95.openSync(file, flags, mode);
|
|
11299
11309
|
fileOpened(null, fd);
|
|
11300
11310
|
} catch (err) {
|
|
@@ -11302,7 +11312,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11302
11312
|
throw err;
|
|
11303
11313
|
}
|
|
11304
11314
|
} else if (sonic.mkdir) {
|
|
11305
|
-
fs95.mkdir(
|
|
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
|
});
|
|
@@ -14162,7 +14172,7 @@ var require_multistream = __commonJS({
|
|
|
14162
14172
|
var require_pino = __commonJS({
|
|
14163
14173
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
14164
14174
|
"use strict";
|
|
14165
|
-
var
|
|
14175
|
+
var os36 = require("os");
|
|
14166
14176
|
var stdSerializers = require_pino_std_serializers();
|
|
14167
14177
|
var caller = require_caller();
|
|
14168
14178
|
var redaction = require_redaction();
|
|
@@ -14209,7 +14219,7 @@ var require_pino = __commonJS({
|
|
|
14209
14219
|
} = symbols;
|
|
14210
14220
|
var { epochTime, nullTime } = time;
|
|
14211
14221
|
var { pid } = process;
|
|
14212
|
-
var hostname =
|
|
14222
|
+
var hostname = os36.hostname();
|
|
14213
14223
|
var defaultErrorSerializer = stdSerializers.err;
|
|
14214
14224
|
var defaultOptions2 = {
|
|
14215
14225
|
level: "info",
|
|
@@ -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;
|
|
@@ -44282,12 +44292,12 @@ function startRunCaseRecorder(opts) {
|
|
|
44282
44292
|
};
|
|
44283
44293
|
return { tap, close, closed };
|
|
44284
44294
|
}
|
|
44285
|
-
var import_node_fs66,
|
|
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
44299
|
import_node_fs66 = __toESM(require("fs"), 1);
|
|
44290
|
-
|
|
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, import_node_fs67.mkdtempSync)(
|
|
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 };
|
|
@@ -44497,13 +44507,13 @@ async function runController(opts) {
|
|
|
44497
44507
|
}
|
|
44498
44508
|
return exitCode ?? 0;
|
|
44499
44509
|
}
|
|
44500
|
-
var import_node_fs67,
|
|
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
|
-
|
|
44506
|
-
|
|
44515
|
+
import_node_os32 = __toESM(require("os"), 1);
|
|
44516
|
+
import_node_path86 = __toESM(require("path"), 1);
|
|
44507
44517
|
init_claude();
|
|
44508
44518
|
init_stdout_splitter();
|
|
44509
44519
|
init_permission_stdio();
|
|
@@ -44775,9 +44785,9 @@ Env (advanced):
|
|
|
44775
44785
|
`;
|
|
44776
44786
|
|
|
44777
44787
|
// src/index.ts
|
|
44778
|
-
var
|
|
44788
|
+
var import_node_path84 = __toESM(require("path"), 1);
|
|
44779
44789
|
var import_node_fs65 = __toESM(require("fs"), 1);
|
|
44780
|
-
var
|
|
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");
|
|
44783
44793
|
|
|
@@ -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;
|
|
@@ -62271,21 +62294,6 @@ var import_node_fs35 = __toESM(require("fs"), 1);
|
|
|
62271
62294
|
var import_node_os12 = __toESM(require("os"), 1);
|
|
62272
62295
|
var import_node_path40 = __toESM(require("path"), 1);
|
|
62273
62296
|
var CHANNELS_FILE_NAME = "subscription-channels.json";
|
|
62274
|
-
function providerSection(content) {
|
|
62275
|
-
const header = /^\[model_providers\.cliproxyapi\][^\n]*(?:\n|$)/m.exec(content);
|
|
62276
|
-
if (!header) return null;
|
|
62277
|
-
const body = content.slice(header.index + header[0].length);
|
|
62278
|
-
const nextHeader = body.search(/^\[/m);
|
|
62279
|
-
return nextHeader < 0 ? body : body.slice(0, nextHeader);
|
|
62280
|
-
}
|
|
62281
|
-
function readAuthKey2(codexHome) {
|
|
62282
|
-
try {
|
|
62283
|
-
const key = JSON.parse(import_node_fs35.default.readFileSync(import_node_path40.default.join(codexHome, "auth.json"), "utf8")).OPENAI_API_KEY;
|
|
62284
|
-
return typeof key === "string" && key ? key : null;
|
|
62285
|
-
} catch {
|
|
62286
|
-
return null;
|
|
62287
|
-
}
|
|
62288
|
-
}
|
|
62289
62297
|
var SubscriptionChannelStore = class {
|
|
62290
62298
|
filePath;
|
|
62291
62299
|
codexHome;
|
|
@@ -62412,20 +62420,15 @@ var SubscriptionChannelStore = class {
|
|
|
62412
62420
|
if (!import_node_fs35.default.existsSync(configPath)) return null;
|
|
62413
62421
|
const content = import_node_fs35.default.readFileSync(configPath, "utf8");
|
|
62414
62422
|
if (!content.includes('model_provider = "cliproxyapi"')) return null;
|
|
62415
|
-
const
|
|
62416
|
-
|
|
62417
|
-
|
|
62418
|
-
const echoKey = /^\s*auth\s*=\s*\{\s*command\s*=\s*["']echo["']\s*,\s*args\s*=\s*\[\s*["']([^"']+)["']\s*\]/m.exec(section)?.[1];
|
|
62419
|
-
const inlineKey = /^\s*experimental_bearer_token\s*=\s*["']([^"']+)["']/m.exec(section)?.[1];
|
|
62420
|
-
const envKey = /^\s*env_key\s*=\s*["']([^"']+)["']/m.exec(section)?.[1];
|
|
62421
|
-
const key = echoKey ?? inlineKey ?? (envKey ? process.env[envKey] : !/^\s*auth\s*=/m.test(section) ? readAuthKey2(this.codexHome) : null);
|
|
62422
|
-
if (urlMatch && key) {
|
|
62423
|
+
const urlMatch = /base_url\s*=\s*["']([^"']+)["']/.exec(content);
|
|
62424
|
+
const keyMatch = /args\s*=\s*\[\s*["']([^"']+)["']\s*\]/.exec(content) || /experimental_bearer_token\s*=\s*["']([^"']+)["']/.exec(content);
|
|
62425
|
+
if (urlMatch && keyMatch) {
|
|
62423
62426
|
const id = "default-pool";
|
|
62424
62427
|
const channel = {
|
|
62425
62428
|
id,
|
|
62426
62429
|
name: "\u9ED8\u8BA4\u56E2\u961F\u53F7\u6C60",
|
|
62427
62430
|
baseUrl: normalizeEngineBaseUrl(urlMatch[1]),
|
|
62428
|
-
apiKey:
|
|
62431
|
+
apiKey: keyMatch[1],
|
|
62429
62432
|
remark: "\u4ECE\u672C\u673A\u5DF2\u63A5\u5165\u7684\u53F7\u6C60\u914D\u7F6E\u81EA\u52A8\u8FC1\u79FB",
|
|
62430
62433
|
createdAt: Date.now(),
|
|
62431
62434
|
updatedAt: Date.now()
|
|
@@ -62506,8 +62509,8 @@ function refreshPathFromLoginShell() {
|
|
|
62506
62509
|
timeout: 3e3,
|
|
62507
62510
|
stdio: ["ignore", "pipe", "ignore"]
|
|
62508
62511
|
});
|
|
62509
|
-
const
|
|
62510
|
-
if (
|
|
62512
|
+
const path106 = out.trim();
|
|
62513
|
+
if (path106) process.env.PATH = path106;
|
|
62511
62514
|
} catch {
|
|
62512
62515
|
}
|
|
62513
62516
|
}
|
|
@@ -65456,13 +65459,13 @@ function mapSkillsListResponse(res) {
|
|
|
65456
65459
|
const r2 = s2 ?? {};
|
|
65457
65460
|
const name = str4(r2.name);
|
|
65458
65461
|
if (!name) continue;
|
|
65459
|
-
const
|
|
65462
|
+
const path106 = str4(r2.path);
|
|
65460
65463
|
const description = str4(r2.description);
|
|
65461
65464
|
const isPlugin = name.includes(":");
|
|
65462
65465
|
out.push({
|
|
65463
65466
|
name,
|
|
65464
65467
|
source: isPlugin ? "plugin" : "project",
|
|
65465
|
-
...
|
|
65468
|
+
...path106 ? { path: path106 } : {},
|
|
65466
65469
|
...description ? { description } : {},
|
|
65467
65470
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
65468
65471
|
});
|
|
@@ -69996,7 +69999,7 @@ var ServerKeyStore = class {
|
|
|
69996
69999
|
init_protocol();
|
|
69997
70000
|
|
|
69998
70001
|
// src/handlers/index.ts
|
|
69999
|
-
var
|
|
70002
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
70000
70003
|
|
|
70001
70004
|
// src/handlers/session.ts
|
|
70002
70005
|
init_protocol();
|
|
@@ -70069,20 +70072,83 @@ function forkSession(input) {
|
|
|
70069
70072
|
return { forkedToolSessionId, forkedFilePath };
|
|
70070
70073
|
}
|
|
70071
70074
|
|
|
70072
|
-
// src/
|
|
70075
|
+
// src/tools/codex-fork.ts
|
|
70076
|
+
var import_node_child_process17 = require("child_process");
|
|
70073
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);
|
|
70074
70140
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
70075
70141
|
var import_node_os24 = __toESM(require("os"), 1);
|
|
70076
|
-
var
|
|
70142
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
70077
70143
|
var import_node_module = require("module");
|
|
70078
|
-
var
|
|
70144
|
+
var import_node_child_process18 = require("child_process");
|
|
70079
70145
|
var import_meta7 = {};
|
|
70080
70146
|
function defaultRoots() {
|
|
70081
70147
|
const home = import_node_os24.default.homedir();
|
|
70082
70148
|
return {
|
|
70083
|
-
claudeProjectsDir:
|
|
70084
|
-
codexDir:
|
|
70085
|
-
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")
|
|
70086
70152
|
};
|
|
70087
70153
|
}
|
|
70088
70154
|
function width(s2) {
|
|
@@ -70133,7 +70199,7 @@ function userText(msg) {
|
|
|
70133
70199
|
}
|
|
70134
70200
|
function isDir2(p3) {
|
|
70135
70201
|
try {
|
|
70136
|
-
return
|
|
70202
|
+
return import_node_fs60.default.statSync(p3).isDirectory();
|
|
70137
70203
|
} catch {
|
|
70138
70204
|
return false;
|
|
70139
70205
|
}
|
|
@@ -70142,7 +70208,7 @@ async function scanClaude(roots) {
|
|
|
70142
70208
|
const out = [];
|
|
70143
70209
|
let dirs;
|
|
70144
70210
|
try {
|
|
70145
|
-
dirs =
|
|
70211
|
+
dirs = import_node_fs60.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
|
|
70146
70212
|
} catch {
|
|
70147
70213
|
return out;
|
|
70148
70214
|
}
|
|
@@ -70150,16 +70216,16 @@ async function scanClaude(roots) {
|
|
|
70150
70216
|
if (!d2.isDirectory()) continue;
|
|
70151
70217
|
let files;
|
|
70152
70218
|
try {
|
|
70153
|
-
files =
|
|
70219
|
+
files = import_node_fs60.default.readdirSync(import_node_path66.default.join(roots.claudeProjectsDir, d2.name));
|
|
70154
70220
|
} catch {
|
|
70155
70221
|
continue;
|
|
70156
70222
|
}
|
|
70157
70223
|
for (const name of files) {
|
|
70158
70224
|
if (!name.endsWith(".jsonl")) continue;
|
|
70159
|
-
const file =
|
|
70225
|
+
const file = import_node_path66.default.join(roots.claudeProjectsDir, d2.name, name);
|
|
70160
70226
|
let st2;
|
|
70161
70227
|
try {
|
|
70162
|
-
st2 =
|
|
70228
|
+
st2 = import_node_fs60.default.statSync(file);
|
|
70163
70229
|
} catch {
|
|
70164
70230
|
continue;
|
|
70165
70231
|
}
|
|
@@ -70212,7 +70278,7 @@ async function scanClaude(roots) {
|
|
|
70212
70278
|
return out;
|
|
70213
70279
|
}
|
|
70214
70280
|
async function countCodexTurns(rolloutPath) {
|
|
70215
|
-
if (!rolloutPath || !
|
|
70281
|
+
if (!rolloutPath || !import_node_fs60.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
|
|
70216
70282
|
let turns = 0;
|
|
70217
70283
|
let first = "";
|
|
70218
70284
|
for await (const rec6 of jsonLines(rolloutPath)) {
|
|
@@ -70243,14 +70309,14 @@ function readCodexThreads(db) {
|
|
|
70243
70309
|
} catch {
|
|
70244
70310
|
}
|
|
70245
70311
|
try {
|
|
70246
|
-
const info = (0,
|
|
70312
|
+
const info = (0, import_node_child_process18.spawnSync)("sqlite3", [db, "PRAGMA table_info(threads);"], { encoding: "utf8" });
|
|
70247
70313
|
if (info.status !== 0) return null;
|
|
70248
70314
|
const have = new Set(
|
|
70249
70315
|
info.stdout.split("\n").map((l2) => l2.split("|")[1]).filter(Boolean)
|
|
70250
70316
|
);
|
|
70251
70317
|
if (!["id", "cwd", "updated_at", "thread_source"].every((c2) => have.has(c2))) return null;
|
|
70252
70318
|
const sel = COLS.map((c2) => have.has(c2) ? c2 : `NULL AS ${c2}`).join(", ");
|
|
70253
|
-
const res = (0,
|
|
70319
|
+
const res = (0, import_node_child_process18.spawnSync)("sqlite3", ["-json", db, `SELECT ${sel} FROM threads;`], {
|
|
70254
70320
|
encoding: "utf8",
|
|
70255
70321
|
maxBuffer: 64 * 1024 * 1024
|
|
70256
70322
|
});
|
|
@@ -70286,7 +70352,7 @@ async function codexFromRows(rows) {
|
|
|
70286
70352
|
async function scanCodex(roots) {
|
|
70287
70353
|
let dbs = [];
|
|
70288
70354
|
try {
|
|
70289
|
-
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));
|
|
70290
70356
|
} catch {
|
|
70291
70357
|
}
|
|
70292
70358
|
if (!dbs.length) return [];
|
|
@@ -70295,14 +70361,14 @@ async function scanCodex(roots) {
|
|
|
70295
70361
|
}
|
|
70296
70362
|
async function scanExternalSessions(rootsIn) {
|
|
70297
70363
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
70298
|
-
const personaRoot =
|
|
70364
|
+
const personaRoot = import_node_path66.default.join(roots.clawdDir, "personas");
|
|
70299
70365
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
70300
70366
|
const out = [];
|
|
70301
70367
|
for (const c2 of all) {
|
|
70302
70368
|
if (c2.skip) continue;
|
|
70303
70369
|
if (c2.turns < 1) continue;
|
|
70304
70370
|
if (!c2.cwd || !isDir2(c2.cwd)) continue;
|
|
70305
|
-
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)) {
|
|
70306
70372
|
continue;
|
|
70307
70373
|
}
|
|
70308
70374
|
out.push({
|
|
@@ -70319,13 +70385,13 @@ async function scanExternalSessions(rootsIn) {
|
|
|
70319
70385
|
}
|
|
70320
70386
|
|
|
70321
70387
|
// src/session/import-ledger.ts
|
|
70322
|
-
var
|
|
70323
|
-
var
|
|
70388
|
+
var import_node_fs61 = __toESM(require("fs"), 1);
|
|
70389
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
70324
70390
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
70325
70391
|
function readImportLedger(dataDir) {
|
|
70326
70392
|
try {
|
|
70327
70393
|
const parsed = JSON.parse(
|
|
70328
|
-
|
|
70394
|
+
import_node_fs61.default.readFileSync(import_node_path67.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
70329
70395
|
);
|
|
70330
70396
|
return Array.isArray(parsed) ? parsed : [];
|
|
70331
70397
|
} catch {
|
|
@@ -70333,14 +70399,15 @@ function readImportLedger(dataDir) {
|
|
|
70333
70399
|
}
|
|
70334
70400
|
}
|
|
70335
70401
|
function appendImportLedger(dataDir, entry) {
|
|
70336
|
-
const file =
|
|
70402
|
+
const file = import_node_path67.default.join(dataDir, LEDGER_FILENAME);
|
|
70337
70403
|
const entries = readImportLedger(dataDir);
|
|
70338
70404
|
entries.push(entry);
|
|
70339
|
-
|
|
70405
|
+
import_node_fs61.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
70340
70406
|
}
|
|
70341
70407
|
|
|
70342
70408
|
// src/handlers/session.ts
|
|
70343
70409
|
init_protocol();
|
|
70410
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
70344
70411
|
function canReadSearchHit(ctx, file) {
|
|
70345
70412
|
if (!ctx || ctx.principal.kind === "owner") return true;
|
|
70346
70413
|
return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
|
|
@@ -70608,8 +70675,12 @@ ${attribution}` } : args;
|
|
|
70608
70675
|
};
|
|
70609
70676
|
const fork = async (frame, _client, ctx) => {
|
|
70610
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
|
+
}
|
|
70611
70682
|
if (ctx && ctx.principal.kind === "guest") {
|
|
70612
|
-
const src = store.list().find((s2) => s2.toolSessionId === args.toolSessionId);
|
|
70683
|
+
const src = source ?? store.list().find((s2) => s2.toolSessionId === args.toolSessionId);
|
|
70613
70684
|
const ok = src != null && canAccessPersona(ctx.grants, src.ownerPersonaId, "read") && src.creatorPrincipalId === ctx.principal.id;
|
|
70614
70685
|
if (!ok) {
|
|
70615
70686
|
throw new ClawdError(
|
|
@@ -70617,8 +70688,33 @@ ${attribution}` } : args;
|
|
|
70617
70688
|
`principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
|
|
70618
70689
|
);
|
|
70619
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
|
+
}
|
|
70620
70694
|
}
|
|
70621
|
-
|
|
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");
|
|
70706
|
+
}
|
|
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
|
+
});
|
|
70622
70718
|
deps.logger?.info("session-fork.done", {
|
|
70623
70719
|
argCwd: args.cwd,
|
|
70624
70720
|
sourceToolSessionId: args.toolSessionId,
|
|
@@ -70869,7 +70965,7 @@ function buildPermissionHandlers(deps) {
|
|
|
70869
70965
|
}
|
|
70870
70966
|
|
|
70871
70967
|
// src/handlers/history.ts
|
|
70872
|
-
var
|
|
70968
|
+
var path83 = __toESM(require("path"), 1);
|
|
70873
70969
|
init_protocol();
|
|
70874
70970
|
|
|
70875
70971
|
// src/session/recent-dirs.ts
|
|
@@ -70887,7 +70983,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
70887
70983
|
}
|
|
70888
70984
|
|
|
70889
70985
|
// src/permission/persona-paths.ts
|
|
70890
|
-
var
|
|
70986
|
+
var path82 = __toESM(require("path"), 1);
|
|
70891
70987
|
function getAllowedPersonaIds(grants, action) {
|
|
70892
70988
|
const ids = /* @__PURE__ */ new Set();
|
|
70893
70989
|
for (const g3 of grants) {
|
|
@@ -70900,42 +70996,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
70900
70996
|
return ids;
|
|
70901
70997
|
}
|
|
70902
70998
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
70903
|
-
const target =
|
|
70999
|
+
const target = path82.resolve(absPath);
|
|
70904
71000
|
if (userWorkDir) {
|
|
70905
|
-
const u2 =
|
|
70906
|
-
const usep = u2.endsWith(
|
|
71001
|
+
const u2 = path82.resolve(userWorkDir);
|
|
71002
|
+
const usep = u2.endsWith(path82.sep) ? "" : path82.sep;
|
|
70907
71003
|
if (target === u2 || target.startsWith(u2 + usep)) return true;
|
|
70908
71004
|
}
|
|
70909
|
-
const root =
|
|
70910
|
-
const sep4 = root.endsWith(
|
|
71005
|
+
const root = path82.resolve(personaRoot);
|
|
71006
|
+
const sep4 = root.endsWith(path82.sep) ? "" : path82.sep;
|
|
70911
71007
|
if (!target.startsWith(root + sep4)) return false;
|
|
70912
|
-
const rel =
|
|
71008
|
+
const rel = path82.relative(root, target);
|
|
70913
71009
|
if (!rel || rel.startsWith("..")) return false;
|
|
70914
|
-
const personaId2 = rel.split(
|
|
71010
|
+
const personaId2 = rel.split(path82.sep)[0];
|
|
70915
71011
|
if (!personaId2) return false;
|
|
70916
71012
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
70917
71013
|
if (allowed === "*") return true;
|
|
70918
71014
|
return allowed.has(personaId2);
|
|
70919
71015
|
}
|
|
70920
71016
|
function personaIdFromPath(absPath, personaRoot) {
|
|
70921
|
-
const root =
|
|
70922
|
-
const target =
|
|
70923
|
-
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;
|
|
70924
71020
|
if (!target.startsWith(root + sep4)) return null;
|
|
70925
|
-
const rel =
|
|
71021
|
+
const rel = path82.relative(root, target);
|
|
70926
71022
|
if (!rel || rel.startsWith("..")) return null;
|
|
70927
|
-
const id = rel.split(
|
|
71023
|
+
const id = rel.split(path82.sep)[0];
|
|
70928
71024
|
return id || null;
|
|
70929
71025
|
}
|
|
70930
71026
|
function isPathWithin(dir, absPath) {
|
|
70931
|
-
const d2 =
|
|
70932
|
-
const t2 =
|
|
70933
|
-
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;
|
|
70934
71030
|
return t2 === d2 || t2.startsWith(d2 + sep4);
|
|
70935
71031
|
}
|
|
70936
71032
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
70937
71033
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
70938
|
-
return personaIdFromPath(
|
|
71034
|
+
return personaIdFromPath(path82.resolve(absPath), personaRoot) === personaId2;
|
|
70939
71035
|
}
|
|
70940
71036
|
|
|
70941
71037
|
// src/handlers/history.ts
|
|
@@ -70961,6 +71057,7 @@ function slimHistoryMessages(messages) {
|
|
|
70961
71057
|
if (m3.isSidechain !== void 0) out.isSidechain = m3.isSidechain;
|
|
70962
71058
|
if (m3.askQuestionAnswers !== void 0) out.askQuestionAnswers = m3.askQuestionAnswers;
|
|
70963
71059
|
if (m3.durationMs !== void 0) out.durationMs = m3.durationMs;
|
|
71060
|
+
if (m3.turnId !== void 0) out.turnId = m3.turnId;
|
|
70964
71061
|
const isErrorPair = m3.toolUseId !== void 0 && errorToolUseIds.has(m3.toolUseId);
|
|
70965
71062
|
if (m3.kind === "tool_call" && isErrorPair && m3.input !== void 0) out.input = m3.input;
|
|
70966
71063
|
if (m3.kind === "tool_result" && m3.error !== void 0 && m3.output !== void 0) out.output = m3.output;
|
|
@@ -70988,7 +71085,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70988
71085
|
if (!pid) return false;
|
|
70989
71086
|
return isGuestPathAllowed(
|
|
70990
71087
|
ctx.grants,
|
|
70991
|
-
|
|
71088
|
+
path83.join(personaRoot, pid),
|
|
70992
71089
|
personaRoot,
|
|
70993
71090
|
"read",
|
|
70994
71091
|
userWorkDir
|
|
@@ -71000,7 +71097,7 @@ function buildHistoryHandlers(deps) {
|
|
|
71000
71097
|
};
|
|
71001
71098
|
const list = async (frame, _client, ctx) => {
|
|
71002
71099
|
const args = HistoryListArgs.parse(frame);
|
|
71003
|
-
assertGuestPath(ctx,
|
|
71100
|
+
assertGuestPath(ctx, path83.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
71004
71101
|
const sessions = await history.listSessions(args);
|
|
71005
71102
|
return { response: { type: "history:list", sessions } };
|
|
71006
71103
|
};
|
|
@@ -71048,14 +71145,14 @@ function buildHistoryHandlers(deps) {
|
|
|
71048
71145
|
};
|
|
71049
71146
|
const subagents = async (frame, _client, ctx) => {
|
|
71050
71147
|
const args = HistorySubagentsArgs.parse(frame);
|
|
71051
|
-
assertGuestPath(ctx,
|
|
71148
|
+
assertGuestPath(ctx, path83.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
71052
71149
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
71053
71150
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
71054
71151
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
71055
71152
|
};
|
|
71056
71153
|
const subagentRead = async (frame, _client, ctx) => {
|
|
71057
71154
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
71058
|
-
assertGuestPath(ctx,
|
|
71155
|
+
assertGuestPath(ctx, path83.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
71059
71156
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
71060
71157
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
71061
71158
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -71065,7 +71162,7 @@ function buildHistoryHandlers(deps) {
|
|
|
71065
71162
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
71066
71163
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
71067
71164
|
const filtered = dirs.filter(
|
|
71068
|
-
(d2) => isGuestPathAllowed(ctx.grants,
|
|
71165
|
+
(d2) => isGuestPathAllowed(ctx.grants, path83.resolve(d2.cwd), personaRoot, "read", userWorkDir)
|
|
71069
71166
|
);
|
|
71070
71167
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
71071
71168
|
}
|
|
@@ -71082,17 +71179,17 @@ function buildHistoryHandlers(deps) {
|
|
|
71082
71179
|
}
|
|
71083
71180
|
|
|
71084
71181
|
// src/handlers/projects.ts
|
|
71085
|
-
var
|
|
71182
|
+
var fs79 = __toESM(require("fs"), 1);
|
|
71086
71183
|
var os26 = __toESM(require("os"), 1);
|
|
71087
|
-
var
|
|
71088
|
-
var
|
|
71184
|
+
var path84 = __toESM(require("path"), 1);
|
|
71185
|
+
var import_node_child_process19 = require("child_process");
|
|
71089
71186
|
init_protocol();
|
|
71090
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
71187
|
+
var DEFAULT_PROJECTS_ROOT = path84.join(os26.homedir(), "Documents", "ChatGPT");
|
|
71091
71188
|
function allocateDir(root, name) {
|
|
71092
|
-
let candidate =
|
|
71189
|
+
let candidate = path84.join(root, name);
|
|
71093
71190
|
let n2 = 2;
|
|
71094
|
-
while (
|
|
71095
|
-
candidate =
|
|
71191
|
+
while (fs79.existsSync(candidate)) {
|
|
71192
|
+
candidate = path84.join(root, `${name} ${n2}`);
|
|
71096
71193
|
n2 += 1;
|
|
71097
71194
|
}
|
|
71098
71195
|
return candidate;
|
|
@@ -71120,11 +71217,11 @@ function buildProjectHandlers(deps) {
|
|
|
71120
71217
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
71121
71218
|
}
|
|
71122
71219
|
try {
|
|
71123
|
-
if (!
|
|
71220
|
+
if (!fs79.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
71124
71221
|
} catch {
|
|
71125
71222
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
71126
71223
|
}
|
|
71127
|
-
const r2 = (0,
|
|
71224
|
+
const r2 = (0, import_node_child_process19.spawnSync)("open", ["-R", args.path], { stdio: "ignore" });
|
|
71128
71225
|
if (r2.status !== 0) {
|
|
71129
71226
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `open -R \u5931\u8D25: exit ${r2.status}`);
|
|
71130
71227
|
}
|
|
@@ -71136,7 +71233,7 @@ function buildProjectHandlers(deps) {
|
|
|
71136
71233
|
let target;
|
|
71137
71234
|
if (args.path) {
|
|
71138
71235
|
try {
|
|
71139
|
-
if (!
|
|
71236
|
+
if (!fs79.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
71140
71237
|
} catch {
|
|
71141
71238
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
71142
71239
|
}
|
|
@@ -71144,15 +71241,15 @@ function buildProjectHandlers(deps) {
|
|
|
71144
71241
|
} else {
|
|
71145
71242
|
const name = args.name;
|
|
71146
71243
|
try {
|
|
71147
|
-
|
|
71244
|
+
fs79.mkdirSync(root, { recursive: true });
|
|
71148
71245
|
target = allocateDir(root, name);
|
|
71149
|
-
|
|
71246
|
+
fs79.mkdirSync(target);
|
|
71150
71247
|
} catch (err) {
|
|
71151
71248
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
71152
71249
|
}
|
|
71153
|
-
const git2 = (0,
|
|
71250
|
+
const git2 = (0, import_node_child_process19.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
71154
71251
|
if (git2.status !== 0) {
|
|
71155
|
-
|
|
71252
|
+
fs79.rmSync(target, { recursive: true, force: true });
|
|
71156
71253
|
throw new ClawdError(
|
|
71157
71254
|
ERROR_CODES.INVALID_CWD,
|
|
71158
71255
|
`git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
|
|
@@ -71177,7 +71274,7 @@ function buildProjectHandlers(deps) {
|
|
|
71177
71274
|
}
|
|
71178
71275
|
|
|
71179
71276
|
// src/handlers/workspace.ts
|
|
71180
|
-
var
|
|
71277
|
+
var path85 = __toESM(require("path"), 1);
|
|
71181
71278
|
init_protocol();
|
|
71182
71279
|
var os27 = __toESM(require("os"), 1);
|
|
71183
71280
|
init_protocol();
|
|
@@ -71220,22 +71317,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
71220
71317
|
const args = WorkspaceListArgs.parse(frame);
|
|
71221
71318
|
const isGuest = ctx?.principal.kind === "guest";
|
|
71222
71319
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os27.homedir();
|
|
71223
|
-
const resolvedCwd =
|
|
71224
|
-
const target = args.path ?
|
|
71320
|
+
const resolvedCwd = path85.resolve(args.cwd ?? fallbackCwd);
|
|
71321
|
+
const target = args.path ? path85.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
71225
71322
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
71226
71323
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
71227
71324
|
return { response: { type: "workspace:list", ...res } };
|
|
71228
71325
|
};
|
|
71229
71326
|
const read = async (frame, _client, ctx) => {
|
|
71230
71327
|
const args = WorkspaceReadArgs.parse(frame);
|
|
71231
|
-
const target =
|
|
71328
|
+
const target = path85.isAbsolute(args.path) ? path85.resolve(args.path) : path85.resolve(args.cwd, args.path);
|
|
71232
71329
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
71233
71330
|
const res = workspace.read(args);
|
|
71234
71331
|
return { response: { type: "workspace:read", ...res } };
|
|
71235
71332
|
};
|
|
71236
71333
|
const skillsList = async (frame, _client, ctx) => {
|
|
71237
71334
|
const args = SkillsListArgs.parse(frame);
|
|
71238
|
-
const cwdAbs =
|
|
71335
|
+
const cwdAbs = path85.resolve(args.cwd);
|
|
71239
71336
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
71240
71337
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
71241
71338
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -71247,7 +71344,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
71247
71344
|
};
|
|
71248
71345
|
const agentsList = async (frame, _client, ctx) => {
|
|
71249
71346
|
const args = AgentsListArgs.parse(frame);
|
|
71250
|
-
const cwdAbs =
|
|
71347
|
+
const cwdAbs = path85.resolve(args.cwd);
|
|
71251
71348
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
71252
71349
|
if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
|
|
71253
71350
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -71269,20 +71366,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
71269
71366
|
}
|
|
71270
71367
|
|
|
71271
71368
|
// src/handlers/git.ts
|
|
71272
|
-
var
|
|
71369
|
+
var path87 = __toESM(require("path"), 1);
|
|
71273
71370
|
init_protocol();
|
|
71274
71371
|
init_protocol();
|
|
71275
71372
|
|
|
71276
71373
|
// src/workspace/git.ts
|
|
71277
|
-
var
|
|
71278
|
-
var
|
|
71279
|
-
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);
|
|
71280
71377
|
var import_node_util2 = require("util");
|
|
71281
|
-
var pexec = (0, import_node_util2.promisify)(
|
|
71378
|
+
var pexec = (0, import_node_util2.promisify)(import_node_child_process20.execFile);
|
|
71282
71379
|
function normalizePath(p3) {
|
|
71283
|
-
const resolved =
|
|
71380
|
+
const resolved = import_node_path69.default.resolve(p3);
|
|
71284
71381
|
try {
|
|
71285
|
-
return
|
|
71382
|
+
return import_node_fs62.default.realpathSync(resolved);
|
|
71286
71383
|
} catch {
|
|
71287
71384
|
return resolved;
|
|
71288
71385
|
}
|
|
@@ -71356,7 +71453,7 @@ async function listGitBranches(cwd) {
|
|
|
71356
71453
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
71357
71454
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
71358
71455
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
71359
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
71456
|
+
if (!isGuestPathAllowed(ctx.grants, path87.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
71360
71457
|
throw new ClawdError(
|
|
71361
71458
|
ERROR_CODES.UNAUTHORIZED,
|
|
71362
71459
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -71408,7 +71505,7 @@ function buildCapabilitiesHandlers(deps) {
|
|
|
71408
71505
|
init_protocol();
|
|
71409
71506
|
|
|
71410
71507
|
// src/tools/version-probe.ts
|
|
71411
|
-
var
|
|
71508
|
+
var import_node_child_process21 = require("child_process");
|
|
71412
71509
|
init_claude();
|
|
71413
71510
|
init_protocol();
|
|
71414
71511
|
function parseVersionOutput(out) {
|
|
@@ -71416,7 +71513,7 @@ function parseVersionOutput(out) {
|
|
|
71416
71513
|
}
|
|
71417
71514
|
function execVersion(bin) {
|
|
71418
71515
|
return new Promise((resolve9, reject) => {
|
|
71419
|
-
(0,
|
|
71516
|
+
(0, import_node_child_process21.execFile)(bin, ["--version"], { timeout: 5e3 }, (err, stdout) => {
|
|
71420
71517
|
if (err) reject(err);
|
|
71421
71518
|
else resolve9(String(stdout));
|
|
71422
71519
|
});
|
|
@@ -71449,7 +71546,7 @@ async function probeToolVersions(opts = {}) {
|
|
|
71449
71546
|
}
|
|
71450
71547
|
|
|
71451
71548
|
// src/tools/pool-connect.ts
|
|
71452
|
-
var
|
|
71549
|
+
var import_node_child_process22 = require("child_process");
|
|
71453
71550
|
init_protocol();
|
|
71454
71551
|
var POOL_SETUP_SCRIPT_PATH = "/api/setup.sh";
|
|
71455
71552
|
var POOL_SCRIPT_FETCH_TIMEOUT_MS = 5e3;
|
|
@@ -71475,7 +71572,7 @@ async function fetchScript(deps) {
|
|
|
71475
71572
|
}
|
|
71476
71573
|
function runScript(script, apiKey, deps) {
|
|
71477
71574
|
return new Promise((resolve9, reject) => {
|
|
71478
|
-
const proc = (0,
|
|
71575
|
+
const proc = (0, import_node_child_process22.spawn)("bash", ["-s"], {
|
|
71479
71576
|
env: { ...deps.env ?? process.env, CPA_KEY: apiKey, CPA_MODE: "api" },
|
|
71480
71577
|
stdio: ["pipe", "pipe", "pipe"]
|
|
71481
71578
|
});
|
|
@@ -71520,7 +71617,7 @@ function runScript(script, apiKey, deps) {
|
|
|
71520
71617
|
}
|
|
71521
71618
|
|
|
71522
71619
|
// src/tools/claude-auth-status.ts
|
|
71523
|
-
var
|
|
71620
|
+
var import_node_child_process23 = require("child_process");
|
|
71524
71621
|
var str5 = (v3) => typeof v3 === "string" && v3 ? v3 : void 0;
|
|
71525
71622
|
function mapClaudeAuthStatus(raw) {
|
|
71526
71623
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
@@ -71543,7 +71640,7 @@ function mapClaudeAuthStatus(raw) {
|
|
|
71543
71640
|
};
|
|
71544
71641
|
}
|
|
71545
71642
|
async function queryClaudeAuthStatus(deps = {}) {
|
|
71546
|
-
const run = deps.execFileImpl ??
|
|
71643
|
+
const run = deps.execFileImpl ?? import_node_child_process23.execFile;
|
|
71547
71644
|
const env = deps.env ?? process.env;
|
|
71548
71645
|
const bin = env.CLAUDE_BIN ?? "claude";
|
|
71549
71646
|
const stdout = await new Promise((resolve9, reject) => {
|
|
@@ -71613,12 +71710,12 @@ async function queryCodexAccount(deps = {}) {
|
|
|
71613
71710
|
}
|
|
71614
71711
|
|
|
71615
71712
|
// src/tools/pi-account.ts
|
|
71616
|
-
var
|
|
71617
|
-
var
|
|
71713
|
+
var import_node_fs63 = __toESM(require("fs"), 1);
|
|
71714
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
71618
71715
|
function readPiCredentials(agentDir) {
|
|
71619
71716
|
let raw;
|
|
71620
71717
|
try {
|
|
71621
|
-
raw = JSON.parse(
|
|
71718
|
+
raw = JSON.parse(import_node_fs63.default.readFileSync(import_node_path70.default.join(agentDir, "auth.json"), "utf8"));
|
|
71622
71719
|
} catch {
|
|
71623
71720
|
return {};
|
|
71624
71721
|
}
|
|
@@ -71701,15 +71798,10 @@ function buildEngineHandlers(deps, overrides = {}) {
|
|
|
71701
71798
|
return { "engine:status": status, "engine:connectPool": connectPool };
|
|
71702
71799
|
}
|
|
71703
71800
|
|
|
71704
|
-
// src/handlers/channels.ts
|
|
71705
|
-
var import_node_fs64 = __toESM(require("fs"), 1);
|
|
71706
|
-
var import_node_os26 = __toESM(require("os"), 1);
|
|
71707
|
-
var import_node_path70 = __toESM(require("path"), 1);
|
|
71708
|
-
|
|
71709
71801
|
// src/tools/subscription-channels-apply.ts
|
|
71710
|
-
var
|
|
71802
|
+
var import_node_fs64 = __toESM(require("fs"), 1);
|
|
71711
71803
|
var import_node_os25 = __toESM(require("os"), 1);
|
|
71712
|
-
var
|
|
71804
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
71713
71805
|
var TABLE_HEADER = /^\s*\[\[?\s*([A-Za-z0-9_.-]+)\s*\]\]?\s*(?:#.*)?$/;
|
|
71714
71806
|
var KEY_LINE = /^\s*([A-Za-z0-9_.-]+)\s*=/;
|
|
71715
71807
|
function stripCodexProvider(text) {
|
|
@@ -71737,10 +71829,10 @@ function stripCodexProvider(text) {
|
|
|
71737
71829
|
return out.join("\n").trim();
|
|
71738
71830
|
}
|
|
71739
71831
|
function applyCodexSubscriptionChannel(opts) {
|
|
71740
|
-
const codexHome = opts.codexHome || process.env.CODEX_HOME ||
|
|
71741
|
-
|
|
71742
|
-
const configFile =
|
|
71743
|
-
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") : "";
|
|
71744
71836
|
const rest = stripCodexProvider(original);
|
|
71745
71837
|
let content;
|
|
71746
71838
|
if (opts.channel) {
|
|
@@ -71764,38 +71856,25 @@ function applyCodexSubscriptionChannel(opts) {
|
|
|
71764
71856
|
].join("\n");
|
|
71765
71857
|
}
|
|
71766
71858
|
const tmpFile = `${configFile}.tmp.${Date.now()}`;
|
|
71767
|
-
|
|
71768
|
-
|
|
71859
|
+
import_node_fs64.default.writeFileSync(tmpFile, content, { mode: 384 });
|
|
71860
|
+
import_node_fs64.default.renameSync(tmpFile, configFile);
|
|
71769
71861
|
}
|
|
71770
71862
|
function applyPiSubscriptionChannel(opts) {
|
|
71771
|
-
const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR ||
|
|
71772
|
-
if (!
|
|
71773
|
-
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");
|
|
71774
71866
|
if (opts.channel) {
|
|
71775
71867
|
const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
|
|
71776
71868
|
const tmp = `${configFile}.tmp.${Date.now()}`;
|
|
71777
|
-
|
|
71778
|
-
|
|
71869
|
+
import_node_fs64.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
71870
|
+
import_node_fs64.default.renameSync(tmp, configFile);
|
|
71779
71871
|
return true;
|
|
71780
71872
|
}
|
|
71781
71873
|
return false;
|
|
71782
71874
|
}
|
|
71783
71875
|
|
|
71784
71876
|
// src/handlers/channels.ts
|
|
71785
|
-
function snapshotFile(file) {
|
|
71786
|
-
const original = import_node_fs64.default.existsSync(file) ? import_node_fs64.default.readFileSync(file) : null;
|
|
71787
|
-
return () => {
|
|
71788
|
-
if (original === null) {
|
|
71789
|
-
import_node_fs64.default.rmSync(file, { force: true });
|
|
71790
|
-
} else {
|
|
71791
|
-
const tmp = `${file}.tmp.${Date.now()}`;
|
|
71792
|
-
import_node_fs64.default.writeFileSync(tmp, original, { mode: 384 });
|
|
71793
|
-
import_node_fs64.default.renameSync(tmp, file);
|
|
71794
|
-
}
|
|
71795
|
-
};
|
|
71796
|
-
}
|
|
71797
71877
|
function buildChannelsHandlers(deps) {
|
|
71798
|
-
let activationQueue = Promise.resolve();
|
|
71799
71878
|
const get = async () => {
|
|
71800
71879
|
return { response: deps.store.list() };
|
|
71801
71880
|
};
|
|
@@ -71824,37 +71903,13 @@ function buildChannelsHandlers(deps) {
|
|
|
71824
71903
|
}
|
|
71825
71904
|
return { response: { ok: true } };
|
|
71826
71905
|
};
|
|
71827
|
-
const activate = async (frame
|
|
71828
|
-
const run = activationQueue.then(() => activateChannel(frame, context));
|
|
71829
|
-
activationQueue = run.then(() => {
|
|
71830
|
-
}, () => {
|
|
71831
|
-
});
|
|
71832
|
-
return run;
|
|
71833
|
-
};
|
|
71834
|
-
const activateChannel = async (frame) => {
|
|
71906
|
+
const activate = async (frame) => {
|
|
71835
71907
|
const args = parseArgs2(SubscriptionChannelActivateArgsSchema, frame, "subscriptionChannel:activate");
|
|
71836
|
-
const channel =
|
|
71837
|
-
|
|
71838
|
-
|
|
71839
|
-
|
|
71840
|
-
|
|
71841
|
-
const restorePi = import_node_fs64.default.existsSync(agentDir) ? snapshotFile(import_node_path70.default.join(agentDir, "cliproxyapi.json")) : null;
|
|
71842
|
-
let refreshed = false;
|
|
71843
|
-
try {
|
|
71844
|
-
applyCodexSubscriptionChannel({ codexHome, channel });
|
|
71845
|
-
if (channel) await deps.manager.getCapabilities("codex", { refresh: true });
|
|
71846
|
-
refreshed = Boolean(channel);
|
|
71847
|
-
applyPiSubscriptionChannel({ agentDir, channel });
|
|
71848
|
-
deps.store.setActive(args.id);
|
|
71849
|
-
} catch (err) {
|
|
71850
|
-
restoreCodex();
|
|
71851
|
-
restorePi?.();
|
|
71852
|
-
if (refreshed) await deps.manager.getCapabilities("codex", { refresh: true }).catch(() => {
|
|
71853
|
-
});
|
|
71854
|
-
if (channel?.id === "default-pool" && err instanceof Error && /HTTP 401/.test(err.message)) {
|
|
71855
|
-
throw new Error("\u9ED8\u8BA4\u53F7\u6C60\u8BA4\u8BC1\u5931\u8D25\uFF08HTTP 401\uFF09\uFF1A\u8BF7\u7F16\u8F91\u300C\u9ED8\u8BA4\u56E2\u961F\u53F7\u6C60\u300D\u5E76\u91CD\u65B0\u586B\u5199\u53F7\u6C60 API Key\uFF0C\u518D\u8BBE\u4E3A\u5F53\u524D\u3002");
|
|
71856
|
-
}
|
|
71857
|
-
throw err;
|
|
71908
|
+
const channel = deps.store.setActive(args.id);
|
|
71909
|
+
applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
|
|
71910
|
+
applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
|
|
71911
|
+
if (channel) {
|
|
71912
|
+
await deps.manager.getCapabilities("codex", { refresh: true });
|
|
71858
71913
|
}
|
|
71859
71914
|
return { response: { ok: true } };
|
|
71860
71915
|
};
|
|
@@ -72500,7 +72555,7 @@ function buildDashboardHandlers(deps) {
|
|
|
72500
72555
|
}
|
|
72501
72556
|
|
|
72502
72557
|
// src/handlers/meta.ts
|
|
72503
|
-
var
|
|
72558
|
+
var import_node_os26 = __toESM(require("os"), 1);
|
|
72504
72559
|
init_protocol();
|
|
72505
72560
|
|
|
72506
72561
|
// src/handlers/method-grants.ts
|
|
@@ -72820,21 +72875,21 @@ function computeMethodAccess(args) {
|
|
|
72820
72875
|
}
|
|
72821
72876
|
|
|
72822
72877
|
// src/version.ts
|
|
72823
|
-
var version = "0.2.
|
|
72878
|
+
var version = "0.2.595".length > 0 ? "0.2.595" : "dev";
|
|
72824
72879
|
|
|
72825
72880
|
// src/cli-probe/probe.ts
|
|
72826
72881
|
var fs83 = __toESM(require("fs"), 1);
|
|
72827
|
-
var
|
|
72882
|
+
var path90 = __toESM(require("path"), 1);
|
|
72828
72883
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
72829
72884
|
var BIN_NAME = "clawd";
|
|
72830
72885
|
var MAX_PARENT_HOPS = 5;
|
|
72831
72886
|
function probeGlobalCli(pathEnv) {
|
|
72832
72887
|
if (!pathEnv) return null;
|
|
72833
|
-
for (const dir of pathEnv.split(
|
|
72888
|
+
for (const dir of pathEnv.split(path90.delimiter)) {
|
|
72834
72889
|
if (!dir) continue;
|
|
72835
72890
|
let real;
|
|
72836
72891
|
try {
|
|
72837
|
-
real = fs83.realpathSync(
|
|
72892
|
+
real = fs83.realpathSync(path90.join(dir, BIN_NAME));
|
|
72838
72893
|
} catch {
|
|
72839
72894
|
continue;
|
|
72840
72895
|
}
|
|
@@ -72844,15 +72899,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
72844
72899
|
return null;
|
|
72845
72900
|
}
|
|
72846
72901
|
function readOwnPackageVersion(entryPath) {
|
|
72847
|
-
let dir =
|
|
72902
|
+
let dir = path90.dirname(entryPath);
|
|
72848
72903
|
for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
|
|
72849
72904
|
try {
|
|
72850
|
-
const raw = fs83.readFileSync(
|
|
72905
|
+
const raw = fs83.readFileSync(path90.join(dir, "package.json"), "utf8");
|
|
72851
72906
|
const pkg = JSON.parse(raw);
|
|
72852
72907
|
if (pkg.name !== PKG_NAME) return null;
|
|
72853
72908
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
72854
72909
|
} catch {
|
|
72855
|
-
const parent =
|
|
72910
|
+
const parent = path90.dirname(dir);
|
|
72856
72911
|
if (parent === dir) return null;
|
|
72857
72912
|
dir = parent;
|
|
72858
72913
|
}
|
|
@@ -72888,7 +72943,7 @@ function buildReadyFrame(deps, client) {
|
|
|
72888
72943
|
return {
|
|
72889
72944
|
version,
|
|
72890
72945
|
protocolVersion: PROTOCOL_VERSION,
|
|
72891
|
-
hostname:
|
|
72946
|
+
hostname: import_node_os26.default.hostname(),
|
|
72892
72947
|
os: process.platform,
|
|
72893
72948
|
tools,
|
|
72894
72949
|
runningSessions: info.runningSessions,
|
|
@@ -73028,7 +73083,7 @@ function buildPersonaHandlers(deps) {
|
|
|
73028
73083
|
}
|
|
73029
73084
|
|
|
73030
73085
|
// src/handlers/attachment.ts
|
|
73031
|
-
var
|
|
73086
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
73032
73087
|
init_protocol();
|
|
73033
73088
|
init_protocol();
|
|
73034
73089
|
function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
|
|
@@ -73107,12 +73162,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
73107
73162
|
`session ${args.sessionId} scope unresolved`
|
|
73108
73163
|
);
|
|
73109
73164
|
}
|
|
73110
|
-
const cwdAbs =
|
|
73111
|
-
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);
|
|
73112
73167
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
73113
73168
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
73114
73169
|
const entry = entries.find((e) => {
|
|
73115
|
-
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);
|
|
73116
73171
|
return storedAbs === candidateAbs && !e.stale;
|
|
73117
73172
|
});
|
|
73118
73173
|
if (!entry) {
|
|
@@ -73136,7 +73191,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
73136
73191
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
73137
73192
|
const f2 = deps.sessionStore.read(sessionId);
|
|
73138
73193
|
if (!f2) return;
|
|
73139
|
-
assertGuestAttachmentPath(ctx,
|
|
73194
|
+
assertGuestAttachmentPath(ctx, import_node_path72.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
73140
73195
|
}
|
|
73141
73196
|
const groupAdd = async (frame, _client, ctx) => {
|
|
73142
73197
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -73151,8 +73206,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
73151
73206
|
if (!scope) {
|
|
73152
73207
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
73153
73208
|
}
|
|
73154
|
-
const cwdAbs =
|
|
73155
|
-
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);
|
|
73156
73211
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
73157
73212
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
73158
73213
|
const size = 0;
|
|
@@ -73211,19 +73266,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
73211
73266
|
|
|
73212
73267
|
// src/handlers/extension.ts
|
|
73213
73268
|
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
73214
|
-
var
|
|
73269
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
73215
73270
|
init_protocol();
|
|
73216
73271
|
|
|
73217
73272
|
// src/extension/bundle-zip.ts
|
|
73218
73273
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
73219
|
-
var
|
|
73274
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
73220
73275
|
var import_node_crypto22 = __toESM(require("crypto"), 1);
|
|
73221
73276
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
73222
73277
|
async function bundleExtensionDir(dir) {
|
|
73223
73278
|
const entries = await listFilesSorted(dir);
|
|
73224
73279
|
const zip = new import_jszip2.default();
|
|
73225
73280
|
for (const rel of entries) {
|
|
73226
|
-
const abs =
|
|
73281
|
+
const abs = import_node_path73.default.join(dir, rel);
|
|
73227
73282
|
const content = await import_promises12.default.readFile(abs);
|
|
73228
73283
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
73229
73284
|
}
|
|
@@ -73244,7 +73299,7 @@ async function listFilesSorted(rootDir) {
|
|
|
73244
73299
|
return out;
|
|
73245
73300
|
}
|
|
73246
73301
|
async function walk(absRoot, relPrefix, out) {
|
|
73247
|
-
const dirAbs =
|
|
73302
|
+
const dirAbs = import_node_path73.default.join(absRoot, relPrefix);
|
|
73248
73303
|
const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
|
|
73249
73304
|
for (const e of entries) {
|
|
73250
73305
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -73298,25 +73353,25 @@ function computePublishCheck(args) {
|
|
|
73298
73353
|
|
|
73299
73354
|
// src/extension/install-flow.ts
|
|
73300
73355
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
73301
|
-
var
|
|
73302
|
-
var
|
|
73356
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
73357
|
+
var import_node_os28 = __toESM(require("os"), 1);
|
|
73303
73358
|
var import_node_crypto23 = __toESM(require("crypto"), 1);
|
|
73304
73359
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
73305
73360
|
|
|
73306
73361
|
// src/extension/paths.ts
|
|
73307
|
-
var
|
|
73308
|
-
var
|
|
73362
|
+
var import_node_os27 = __toESM(require("os"), 1);
|
|
73363
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
73309
73364
|
function clawdHomeRoot(override) {
|
|
73310
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
73365
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path74.default.join(import_node_os27.default.homedir(), ".clawd");
|
|
73311
73366
|
}
|
|
73312
73367
|
function extensionsRoot(override) {
|
|
73313
|
-
return
|
|
73368
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extensions");
|
|
73314
73369
|
}
|
|
73315
73370
|
function publishedChannelsFile(override) {
|
|
73316
|
-
return
|
|
73371
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
73317
73372
|
}
|
|
73318
73373
|
function bundleCacheRoot(override) {
|
|
73319
|
-
return
|
|
73374
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
73320
73375
|
}
|
|
73321
73376
|
|
|
73322
73377
|
// src/extension/install-flow.ts
|
|
@@ -73343,7 +73398,7 @@ async function installFromChannel(args, deps) {
|
|
|
73343
73398
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
73344
73399
|
}
|
|
73345
73400
|
for (const name of Object.keys(zip.files)) {
|
|
73346
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73401
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
|
|
73347
73402
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
73348
73403
|
}
|
|
73349
73404
|
}
|
|
@@ -73375,7 +73430,7 @@ async function installFromChannel(args, deps) {
|
|
|
73375
73430
|
);
|
|
73376
73431
|
}
|
|
73377
73432
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
73378
|
-
const destDir =
|
|
73433
|
+
const destDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
|
|
73379
73434
|
let destExists = false;
|
|
73380
73435
|
try {
|
|
73381
73436
|
await import_promises13.default.access(destDir);
|
|
@@ -73389,16 +73444,16 @@ async function installFromChannel(args, deps) {
|
|
|
73389
73444
|
);
|
|
73390
73445
|
}
|
|
73391
73446
|
const stage = await import_promises13.default.mkdtemp(
|
|
73392
|
-
|
|
73447
|
+
import_node_path75.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
73393
73448
|
);
|
|
73394
73449
|
try {
|
|
73395
73450
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
73396
|
-
const dest =
|
|
73451
|
+
const dest = import_node_path75.default.join(stage, name);
|
|
73397
73452
|
if (entry.dir) {
|
|
73398
73453
|
await import_promises13.default.mkdir(dest, { recursive: true });
|
|
73399
73454
|
continue;
|
|
73400
73455
|
}
|
|
73401
|
-
await import_promises13.default.mkdir(
|
|
73456
|
+
await import_promises13.default.mkdir(import_node_path75.default.dirname(dest), { recursive: true });
|
|
73402
73457
|
if (name === "manifest.json") {
|
|
73403
73458
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
73404
73459
|
await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -73419,8 +73474,8 @@ async function installFromChannel(args, deps) {
|
|
|
73419
73474
|
|
|
73420
73475
|
// src/extension/update-flow.ts
|
|
73421
73476
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
73422
|
-
var
|
|
73423
|
-
var
|
|
73477
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
73478
|
+
var import_node_os29 = __toESM(require("os"), 1);
|
|
73424
73479
|
var import_node_crypto24 = __toESM(require("crypto"), 1);
|
|
73425
73480
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
73426
73481
|
var UpdateError = class extends Error {
|
|
@@ -73436,11 +73491,11 @@ async function updateFromChannel(args, deps) {
|
|
|
73436
73491
|
channelRef.extId,
|
|
73437
73492
|
channelRef.ownerPrincipalId
|
|
73438
73493
|
);
|
|
73439
|
-
const liveDir =
|
|
73494
|
+
const liveDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
|
|
73440
73495
|
const prevDir = `${liveDir}.prev`;
|
|
73441
73496
|
let existingVersion;
|
|
73442
73497
|
try {
|
|
73443
|
-
const raw = await import_promises14.default.readFile(
|
|
73498
|
+
const raw = await import_promises14.default.readFile(import_node_path76.default.join(liveDir, "manifest.json"), "utf8");
|
|
73444
73499
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
73445
73500
|
if (!parsed2.success) {
|
|
73446
73501
|
throw new UpdateError(
|
|
@@ -73473,7 +73528,7 @@ async function updateFromChannel(args, deps) {
|
|
|
73473
73528
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
73474
73529
|
}
|
|
73475
73530
|
for (const name of Object.keys(zip.files)) {
|
|
73476
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73531
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
|
|
73477
73532
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
73478
73533
|
}
|
|
73479
73534
|
}
|
|
@@ -73508,16 +73563,16 @@ async function updateFromChannel(args, deps) {
|
|
|
73508
73563
|
await import_promises14.default.rm(prevDir, { recursive: true, force: true });
|
|
73509
73564
|
await import_promises14.default.rename(liveDir, prevDir);
|
|
73510
73565
|
const stage = await import_promises14.default.mkdtemp(
|
|
73511
|
-
|
|
73566
|
+
import_node_path76.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
73512
73567
|
);
|
|
73513
73568
|
try {
|
|
73514
73569
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
73515
|
-
const dest =
|
|
73570
|
+
const dest = import_node_path76.default.join(stage, name);
|
|
73516
73571
|
if (entry.dir) {
|
|
73517
73572
|
await import_promises14.default.mkdir(dest, { recursive: true });
|
|
73518
73573
|
continue;
|
|
73519
73574
|
}
|
|
73520
|
-
await import_promises14.default.mkdir(
|
|
73575
|
+
await import_promises14.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
|
|
73521
73576
|
if (name === "manifest.json") {
|
|
73522
73577
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
73523
73578
|
await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -73584,7 +73639,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73584
73639
|
);
|
|
73585
73640
|
}
|
|
73586
73641
|
}
|
|
73587
|
-
const manifestPath =
|
|
73642
|
+
const manifestPath = import_node_path77.default.join(root, extId, "manifest.json");
|
|
73588
73643
|
const manifest = await readManifest(root, extId);
|
|
73589
73644
|
const next = { ...manifest, version: newVersion };
|
|
73590
73645
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -73592,7 +73647,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73592
73647
|
await import_promises15.default.rename(tmp, manifestPath);
|
|
73593
73648
|
}
|
|
73594
73649
|
async function readManifest(root, extId) {
|
|
73595
|
-
const file =
|
|
73650
|
+
const file = import_node_path77.default.join(root, extId, "manifest.json");
|
|
73596
73651
|
let raw;
|
|
73597
73652
|
try {
|
|
73598
73653
|
raw = await import_promises15.default.readFile(file, "utf8");
|
|
@@ -73676,7 +73731,7 @@ function buildExtensionHandlers(deps) {
|
|
|
73676
73731
|
};
|
|
73677
73732
|
async function buildSnapshotMeta(extId) {
|
|
73678
73733
|
const manifest = await readManifest(deps.root, extId);
|
|
73679
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
73734
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path77.default.join(deps.root, extId));
|
|
73680
73735
|
return { manifest, contentHash: sha256, buffer };
|
|
73681
73736
|
}
|
|
73682
73737
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -74504,7 +74559,7 @@ function buildVisitorHandlers(deps) {
|
|
|
74504
74559
|
|
|
74505
74560
|
// src/extension/registry.ts
|
|
74506
74561
|
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
74507
|
-
var
|
|
74562
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
74508
74563
|
async function loadAll(root) {
|
|
74509
74564
|
let entries;
|
|
74510
74565
|
try {
|
|
@@ -74517,13 +74572,13 @@ async function loadAll(root) {
|
|
|
74517
74572
|
for (const ent of entries) {
|
|
74518
74573
|
if (!ent.isDirectory()) continue;
|
|
74519
74574
|
if (ent.name.startsWith(".")) continue;
|
|
74520
|
-
records.push(await loadOne(
|
|
74575
|
+
records.push(await loadOne(import_node_path78.default.join(root, ent.name), ent.name));
|
|
74521
74576
|
}
|
|
74522
74577
|
records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
|
|
74523
74578
|
return records;
|
|
74524
74579
|
}
|
|
74525
74580
|
async function loadOne(dir, dirName) {
|
|
74526
|
-
const manifestPath =
|
|
74581
|
+
const manifestPath = import_node_path78.default.join(dir, "manifest.json");
|
|
74527
74582
|
let raw;
|
|
74528
74583
|
try {
|
|
74529
74584
|
raw = await import_promises17.default.readFile(manifestPath, "utf8");
|
|
@@ -74568,7 +74623,7 @@ async function loadOne(dir, dirName) {
|
|
|
74568
74623
|
|
|
74569
74624
|
// src/extension/uninstall.ts
|
|
74570
74625
|
var import_promises18 = __toESM(require("fs/promises"), 1);
|
|
74571
|
-
var
|
|
74626
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
74572
74627
|
var UninstallError = class extends Error {
|
|
74573
74628
|
constructor(code, message) {
|
|
74574
74629
|
super(message);
|
|
@@ -74577,7 +74632,7 @@ var UninstallError = class extends Error {
|
|
|
74577
74632
|
code;
|
|
74578
74633
|
};
|
|
74579
74634
|
async function uninstall(deps) {
|
|
74580
|
-
const dir =
|
|
74635
|
+
const dir = import_node_path79.default.join(deps.root, deps.extId);
|
|
74581
74636
|
try {
|
|
74582
74637
|
await import_promises18.default.access(dir);
|
|
74583
74638
|
} catch {
|
|
@@ -74594,15 +74649,15 @@ var import_node_crypto25 = require("crypto");
|
|
|
74594
74649
|
init_protocol();
|
|
74595
74650
|
|
|
74596
74651
|
// src/peer-ops/run-command.ts
|
|
74597
|
-
var
|
|
74598
|
-
var
|
|
74652
|
+
var import_node_child_process24 = require("child_process");
|
|
74653
|
+
var import_node_os30 = __toESM(require("os"), 1);
|
|
74599
74654
|
var DEFAULT_TIMEOUT_MS6 = 3e4;
|
|
74600
74655
|
var MAX_TIMEOUT_MS = 3e5;
|
|
74601
74656
|
var MAX_OUTPUT_BYTES = 1048576;
|
|
74602
74657
|
function runCommand2(command, opts = {}) {
|
|
74603
74658
|
const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6, MAX_TIMEOUT_MS);
|
|
74604
74659
|
return new Promise((resolve9) => {
|
|
74605
|
-
const child = (0,
|
|
74660
|
+
const child = (0, import_node_child_process24.spawn)("bash", ["-c", command], { cwd: import_node_os30.default.homedir() });
|
|
74606
74661
|
const out = [];
|
|
74607
74662
|
const err = [];
|
|
74608
74663
|
let outBytes = 0;
|
|
@@ -74795,7 +74850,7 @@ function buildMethodHandlers(deps) {
|
|
|
74795
74850
|
broadcast: deps.broadcastToOwners
|
|
74796
74851
|
}),
|
|
74797
74852
|
...buildMasterHandlers({
|
|
74798
|
-
authorityTablePath:
|
|
74853
|
+
authorityTablePath: import_node_path80.default.join(deps.masterDataDir, "master-authority.json")
|
|
74799
74854
|
}),
|
|
74800
74855
|
...buildTopicHandlers({
|
|
74801
74856
|
topicStore: deps.topicStore,
|
|
@@ -74937,8 +74992,8 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
74937
74992
|
}
|
|
74938
74993
|
|
|
74939
74994
|
// src/extension/runtime.ts
|
|
74940
|
-
var
|
|
74941
|
-
var
|
|
74995
|
+
var import_node_child_process25 = require("child_process");
|
|
74996
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
74942
74997
|
var import_promises19 = require("timers/promises");
|
|
74943
74998
|
|
|
74944
74999
|
// src/extension/port-allocator.ts
|
|
@@ -75039,13 +75094,13 @@ var Runtime = class {
|
|
|
75039
75094
|
/\$CLAWOS_EXT_PORT/g,
|
|
75040
75095
|
String(port)
|
|
75041
75096
|
);
|
|
75042
|
-
const dir =
|
|
75097
|
+
const dir = import_node_path81.default.join(this.root, extId);
|
|
75043
75098
|
const env = {
|
|
75044
75099
|
...process.env,
|
|
75045
75100
|
CLAWOS_EXT_PORT: String(port),
|
|
75046
75101
|
CLAWOS_EXT_ID: extId
|
|
75047
75102
|
};
|
|
75048
|
-
const child = (0,
|
|
75103
|
+
const child = (0, import_node_child_process25.spawn)("sh", ["-c", cmd], {
|
|
75049
75104
|
cwd: dir,
|
|
75050
75105
|
env,
|
|
75051
75106
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -75151,7 +75206,7 @@ ${handle.stderrTail}`
|
|
|
75151
75206
|
|
|
75152
75207
|
// src/extension/published-channels.ts
|
|
75153
75208
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
75154
|
-
var
|
|
75209
|
+
var import_node_path82 = __toESM(require("path"), 1);
|
|
75155
75210
|
init_zod();
|
|
75156
75211
|
var PublishedChannelsError = class extends Error {
|
|
75157
75212
|
constructor(code, message) {
|
|
@@ -75250,7 +75305,7 @@ var PublishedChannelStore = class {
|
|
|
75250
75305
|
)
|
|
75251
75306
|
};
|
|
75252
75307
|
const tmp = `${this.filePath}.tmp`;
|
|
75253
|
-
await import_promises20.default.mkdir(
|
|
75308
|
+
await import_promises20.default.mkdir(import_node_path82.default.dirname(this.filePath), { recursive: true });
|
|
75254
75309
|
await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
75255
75310
|
await import_promises20.default.rename(tmp, this.filePath);
|
|
75256
75311
|
}
|
|
@@ -75258,7 +75313,7 @@ var PublishedChannelStore = class {
|
|
|
75258
75313
|
|
|
75259
75314
|
// src/extension/bundle-cache.ts
|
|
75260
75315
|
var import_promises21 = __toESM(require("fs/promises"), 1);
|
|
75261
|
-
var
|
|
75316
|
+
var import_node_path83 = __toESM(require("path"), 1);
|
|
75262
75317
|
var BundleCache = class {
|
|
75263
75318
|
constructor(rootDir) {
|
|
75264
75319
|
this.rootDir = rootDir;
|
|
@@ -75267,14 +75322,14 @@ var BundleCache = class {
|
|
|
75267
75322
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
75268
75323
|
async write(snapshotHash, buffer) {
|
|
75269
75324
|
await import_promises21.default.mkdir(this.rootDir, { recursive: true });
|
|
75270
|
-
const file =
|
|
75325
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
75271
75326
|
const tmp = `${file}.tmp`;
|
|
75272
75327
|
await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
|
|
75273
75328
|
await import_promises21.default.rename(tmp, file);
|
|
75274
75329
|
}
|
|
75275
75330
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
75276
75331
|
async read(snapshotHash) {
|
|
75277
|
-
const file =
|
|
75332
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
75278
75333
|
try {
|
|
75279
75334
|
return await import_promises21.default.readFile(file);
|
|
75280
75335
|
} catch (e) {
|
|
@@ -75284,7 +75339,7 @@ var BundleCache = class {
|
|
|
75284
75339
|
}
|
|
75285
75340
|
/** Idempotent — missing file is not an error. */
|
|
75286
75341
|
async delete(snapshotHash) {
|
|
75287
|
-
const file =
|
|
75342
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
75288
75343
|
await import_promises21.default.rm(file, { force: true });
|
|
75289
75344
|
}
|
|
75290
75345
|
};
|
|
@@ -75305,26 +75360,26 @@ async function startDaemon(config) {
|
|
|
75305
75360
|
},
|
|
75306
75361
|
source: "daemon",
|
|
75307
75362
|
sampling: logShippingCfg.sampling,
|
|
75308
|
-
homeDir:
|
|
75363
|
+
homeDir: import_node_os31.default.homedir()
|
|
75309
75364
|
});
|
|
75310
|
-
const logDir =
|
|
75365
|
+
const logDir = import_node_path84.default.join(config.dataDir, "log");
|
|
75311
75366
|
import_node_fs65.default.mkdirSync(logDir, { recursive: true });
|
|
75312
75367
|
const logger = createLogger({
|
|
75313
75368
|
level: config.logLevel,
|
|
75314
|
-
file:
|
|
75369
|
+
file: import_node_path84.default.join(logDir, "clawd.log"),
|
|
75315
75370
|
logClient
|
|
75316
75371
|
});
|
|
75317
75372
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
75318
75373
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
75319
|
-
file:
|
|
75374
|
+
file: import_node_path84.default.join(logDir, "screen-idle-probe.log"),
|
|
75320
75375
|
level: "debug"
|
|
75321
75376
|
});
|
|
75322
75377
|
logger.info("screen-idle probe logger enabled", {
|
|
75323
|
-
file:
|
|
75378
|
+
file: import_node_path84.default.join(logDir, "screen-idle-probe.log")
|
|
75324
75379
|
});
|
|
75325
75380
|
const CAP_TARGETS = [
|
|
75326
|
-
|
|
75327
|
-
|
|
75381
|
+
import_node_path84.default.join(logDir, "clawd.log"),
|
|
75382
|
+
import_node_path84.default.join(logDir, "screen-idle-probe.log")
|
|
75328
75383
|
];
|
|
75329
75384
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
75330
75385
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -75446,9 +75501,9 @@ async function startDaemon(config) {
|
|
|
75446
75501
|
const agents = new AgentsScanner();
|
|
75447
75502
|
const history = new ClaudeHistoryReader();
|
|
75448
75503
|
let transport = null;
|
|
75449
|
-
const personaStore = new PersonaStore(
|
|
75504
|
+
const personaStore = new PersonaStore(import_node_path84.default.join(config.dataDir, "personas"));
|
|
75450
75505
|
const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
|
|
75451
|
-
const usersRoot =
|
|
75506
|
+
const usersRoot = import_node_path84.default.join(config.dataDir, "users");
|
|
75452
75507
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
75453
75508
|
if (defaultsRoot) {
|
|
75454
75509
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -75465,7 +75520,7 @@ async function startDaemon(config) {
|
|
|
75465
75520
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
75466
75521
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
75467
75522
|
const dispatchStore = createDispatchStore({
|
|
75468
|
-
filePath:
|
|
75523
|
+
filePath: import_node_path84.default.join(config.dataDir, "dispatch.json"),
|
|
75469
75524
|
now: () => Date.now(),
|
|
75470
75525
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
75471
75526
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -75474,7 +75529,7 @@ async function startDaemon(config) {
|
|
|
75474
75529
|
await dispatchStore.load();
|
|
75475
75530
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
75476
75531
|
const channelStore = createChannelStore({
|
|
75477
|
-
filePath:
|
|
75532
|
+
filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
|
|
75478
75533
|
now: () => Date.now(),
|
|
75479
75534
|
genId: () => `ch-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75480
75535
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
@@ -75483,7 +75538,7 @@ async function startDaemon(config) {
|
|
|
75483
75538
|
});
|
|
75484
75539
|
await channelStore.load();
|
|
75485
75540
|
const topicStore = createTopicStore({
|
|
75486
|
-
filePath:
|
|
75541
|
+
filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
|
|
75487
75542
|
now: () => Date.now(),
|
|
75488
75543
|
genId: () => `tp-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75489
75544
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
@@ -75510,12 +75565,12 @@ async function startDaemon(config) {
|
|
|
75510
75565
|
});
|
|
75511
75566
|
}
|
|
75512
75567
|
});
|
|
75513
|
-
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));
|
|
75514
75569
|
const mcpConfigs = [];
|
|
75515
75570
|
const secretsBundleRoot = findSecretsBundleRoot(logger);
|
|
75516
|
-
const localSecretsDir =
|
|
75571
|
+
const localSecretsDir = import_node_path84.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
75517
75572
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
75518
|
-
const githubTokenFile =
|
|
75573
|
+
const githubTokenFile = import_node_path84.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
|
|
75519
75574
|
const githubIdentity = createGithubIdentity({
|
|
75520
75575
|
resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
|
|
75521
75576
|
store: (token) => storeGithubAuth({
|
|
@@ -75553,22 +75608,22 @@ async function startDaemon(config) {
|
|
|
75553
75608
|
void githubIdentity.refresh();
|
|
75554
75609
|
return renderPersonaMcpSecrets({
|
|
75555
75610
|
personaId: personaId2,
|
|
75556
|
-
personaDir:
|
|
75611
|
+
personaDir: import_node_path84.default.join(config.dataDir, "personas", personaId2),
|
|
75557
75612
|
secrets,
|
|
75558
|
-
outDir:
|
|
75613
|
+
outDir: import_node_path84.default.join(config.dataDir, "persona-mcp"),
|
|
75559
75614
|
logger
|
|
75560
75615
|
});
|
|
75561
75616
|
};
|
|
75562
75617
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
75563
75618
|
const dispatchServerCandidates = [
|
|
75564
|
-
|
|
75619
|
+
import_node_path84.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
75565
75620
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
75566
|
-
|
|
75621
|
+
import_node_path84.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
75567
75622
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
75568
75623
|
];
|
|
75569
75624
|
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75570
75625
|
if (dispatchServerScriptPath) {
|
|
75571
|
-
const dispatchLogPath =
|
|
75626
|
+
const dispatchLogPath = import_node_path84.default.join(logDir, "dispatch-mcp-server.log");
|
|
75572
75627
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
75573
75628
|
dataDir: config.dataDir,
|
|
75574
75629
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -75588,12 +75643,12 @@ async function startDaemon(config) {
|
|
|
75588
75643
|
});
|
|
75589
75644
|
}
|
|
75590
75645
|
const ticketServerCandidates = [
|
|
75591
|
-
|
|
75592
|
-
|
|
75646
|
+
import_node_path84.default.join(here, "ticket", "mcp-server.cjs"),
|
|
75647
|
+
import_node_path84.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
75593
75648
|
];
|
|
75594
75649
|
const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75595
75650
|
if (ticketServerScriptPath) {
|
|
75596
|
-
const ticketLogPath =
|
|
75651
|
+
const ticketLogPath = import_node_path84.default.join(logDir, "ticket-mcp-server.log");
|
|
75597
75652
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
75598
75653
|
dataDir: config.dataDir,
|
|
75599
75654
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -75615,12 +75670,12 @@ async function startDaemon(config) {
|
|
|
75615
75670
|
});
|
|
75616
75671
|
}
|
|
75617
75672
|
const shiftServerCandidates = [
|
|
75618
|
-
|
|
75619
|
-
|
|
75673
|
+
import_node_path84.default.join(here, "shift", "mcp-server.cjs"),
|
|
75674
|
+
import_node_path84.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
75620
75675
|
];
|
|
75621
75676
|
const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75622
75677
|
if (shiftServerScriptPath) {
|
|
75623
|
-
const shiftLogPath =
|
|
75678
|
+
const shiftLogPath = import_node_path84.default.join(logDir, "shift-mcp-server.log");
|
|
75624
75679
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
75625
75680
|
dataDir: config.dataDir,
|
|
75626
75681
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -75641,12 +75696,12 @@ async function startDaemon(config) {
|
|
|
75641
75696
|
);
|
|
75642
75697
|
}
|
|
75643
75698
|
const inboxServerCandidates = [
|
|
75644
|
-
|
|
75645
|
-
|
|
75699
|
+
import_node_path84.default.join(here, "inbox", "mcp-server.cjs"),
|
|
75700
|
+
import_node_path84.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
75646
75701
|
];
|
|
75647
75702
|
const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75648
75703
|
if (inboxServerScriptPath) {
|
|
75649
|
-
const inboxLogPath =
|
|
75704
|
+
const inboxLogPath = import_node_path84.default.join(logDir, "inbox-mcp-server.log");
|
|
75650
75705
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
75651
75706
|
dataDir: config.dataDir,
|
|
75652
75707
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -75667,8 +75722,8 @@ async function startDaemon(config) {
|
|
|
75667
75722
|
);
|
|
75668
75723
|
}
|
|
75669
75724
|
const peerOpsServerCandidates = [
|
|
75670
|
-
|
|
75671
|
-
|
|
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")
|
|
75672
75727
|
];
|
|
75673
75728
|
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75674
75729
|
if (peerOpsServerScriptPath) {
|
|
@@ -75690,12 +75745,12 @@ async function startDaemon(config) {
|
|
|
75690
75745
|
);
|
|
75691
75746
|
}
|
|
75692
75747
|
const rpcToolServerCandidates = [
|
|
75693
|
-
|
|
75694
|
-
|
|
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")
|
|
75695
75750
|
];
|
|
75696
75751
|
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75697
75752
|
if (rpcToolServerScriptPath) {
|
|
75698
|
-
const rpcToolLogPath =
|
|
75753
|
+
const rpcToolLogPath = import_node_path84.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
75699
75754
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
75700
75755
|
dataDir: config.dataDir,
|
|
75701
75756
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -75716,7 +75771,7 @@ async function startDaemon(config) {
|
|
|
75716
75771
|
);
|
|
75717
75772
|
}
|
|
75718
75773
|
const shiftStore = createShiftStore({
|
|
75719
|
-
filePath:
|
|
75774
|
+
filePath: import_node_path84.default.join(config.dataDir, "shift.json"),
|
|
75720
75775
|
ownerIdProvider: () => ownerPrincipalId,
|
|
75721
75776
|
now: () => Date.now()
|
|
75722
75777
|
});
|
|
@@ -75738,7 +75793,7 @@ async function startDaemon(config) {
|
|
|
75738
75793
|
getAdapter,
|
|
75739
75794
|
historyReader: history,
|
|
75740
75795
|
dataDir: config.dataDir,
|
|
75741
|
-
personaRoot:
|
|
75796
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
75742
75797
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
75743
75798
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
75744
75799
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
@@ -75795,7 +75850,7 @@ async function startDaemon(config) {
|
|
|
75795
75850
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
75796
75851
|
attachmentGroup: {
|
|
75797
75852
|
onFileEdit: (input) => {
|
|
75798
|
-
const absPath =
|
|
75853
|
+
const absPath = import_node_path84.default.isAbsolute(input.relPath) ? input.relPath : import_node_path84.default.join(input.cwd, input.relPath);
|
|
75799
75854
|
let size = 0;
|
|
75800
75855
|
try {
|
|
75801
75856
|
size = import_node_fs65.default.statSync(absPath).size;
|
|
@@ -75839,9 +75894,9 @@ async function startDaemon(config) {
|
|
|
75839
75894
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
75840
75895
|
}
|
|
75841
75896
|
const projectsStore = new ProjectsStore({
|
|
75842
|
-
file:
|
|
75897
|
+
file: import_node_path84.default.join(config.dataDir, "projects.json"),
|
|
75843
75898
|
clawdDir: config.dataDir,
|
|
75844
|
-
codexStateFile:
|
|
75899
|
+
codexStateFile: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
75845
75900
|
logger
|
|
75846
75901
|
});
|
|
75847
75902
|
const observer = new SessionObserver({
|
|
@@ -75906,12 +75961,12 @@ async function startDaemon(config) {
|
|
|
75906
75961
|
logger
|
|
75907
75962
|
});
|
|
75908
75963
|
registerAdapter("claude", claudeAdapter);
|
|
75909
|
-
const codexIsolatedHome =
|
|
75964
|
+
const codexIsolatedHome = import_node_path84.default.join(config.dataDir, "codex-home");
|
|
75910
75965
|
try {
|
|
75911
75966
|
import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
75912
75967
|
for (const f2 of ["auth.json", "config.toml"]) {
|
|
75913
|
-
const link =
|
|
75914
|
-
const target =
|
|
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);
|
|
75915
75970
|
if (!import_node_fs65.default.existsSync(link) && import_node_fs65.default.existsSync(target)) import_node_fs65.default.symlinkSync(target, link);
|
|
75916
75971
|
}
|
|
75917
75972
|
} catch (err) {
|
|
@@ -75923,19 +75978,20 @@ async function startDaemon(config) {
|
|
|
75923
75978
|
logger,
|
|
75924
75979
|
historyReader: new CodexHistoryReader({
|
|
75925
75980
|
roots: codexRolloutRoots(config.dataDir),
|
|
75926
|
-
sharedHome:
|
|
75981
|
+
sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
75927
75982
|
logger
|
|
75928
75983
|
}),
|
|
75929
75984
|
// projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
|
|
75930
75985
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
75931
75986
|
cwd,
|
|
75932
|
-
personaRoot:
|
|
75987
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
75933
75988
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
75934
75989
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
75935
75990
|
projectPaths: projectsStore.listMerged().map((x2) => x2.path),
|
|
75936
|
-
sharedHome:
|
|
75991
|
+
sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
75937
75992
|
isolatedHome: codexIsolatedHome
|
|
75938
75993
|
}),
|
|
75994
|
+
codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
|
|
75939
75995
|
// 附件图片验签:与 http-router /files 路由同一把 secret
|
|
75940
75996
|
getSignSecret: () => authFile.token
|
|
75941
75997
|
})
|
|
@@ -75958,8 +76014,8 @@ async function startDaemon(config) {
|
|
|
75958
76014
|
);
|
|
75959
76015
|
registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
|
|
75960
76016
|
const piMcpBridgeCandidates = [
|
|
75961
|
-
|
|
75962
|
-
|
|
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")
|
|
75963
76019
|
];
|
|
75964
76020
|
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75965
76021
|
if (piMcpBridgePath) {
|
|
@@ -76257,11 +76313,11 @@ async function startDaemon(config) {
|
|
|
76257
76313
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
76258
76314
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
76259
76315
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
76260
|
-
personaRoot:
|
|
76316
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
76261
76317
|
usersRoot
|
|
76262
76318
|
},
|
|
76263
76319
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
76264
|
-
personaRoot:
|
|
76320
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
76265
76321
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
76266
76322
|
usersRoot,
|
|
76267
76323
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -76407,7 +76463,7 @@ async function startDaemon(config) {
|
|
|
76407
76463
|
sourceSessionId: args.sourceSessionId
|
|
76408
76464
|
});
|
|
76409
76465
|
const sourceFile = manager.findOwnedSession(args.sourceSessionId);
|
|
76410
|
-
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile,
|
|
76466
|
+
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os31.default.homedir());
|
|
76411
76467
|
logger.info("dispatch.spawnB.source-resolved", {
|
|
76412
76468
|
dispatchId: args.dispatchId,
|
|
76413
76469
|
sourceJsonlPath,
|
|
@@ -76567,7 +76623,7 @@ async function startDaemon(config) {
|
|
|
76567
76623
|
});
|
|
76568
76624
|
shiftScheduler.start();
|
|
76569
76625
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
76570
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
76626
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path84.default.join(config.dataDir, "personas"));
|
|
76571
76627
|
const larkBotCloud = createLarkBotCloudClient({
|
|
76572
76628
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
76573
76629
|
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
|
|
@@ -76579,7 +76635,7 @@ async function startDaemon(config) {
|
|
|
76579
76635
|
store: larkBotStore,
|
|
76580
76636
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
76581
76637
|
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
76582
|
-
mediaRootFor: (chatId) =>
|
|
76638
|
+
mediaRootFor: (chatId) => import_node_path84.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
76583
76639
|
isShuttingDown: () => larkDraining,
|
|
76584
76640
|
logger: {
|
|
76585
76641
|
warn: (msg) => logger.warn(msg),
|
|
@@ -76879,8 +76935,8 @@ async function startDaemon(config) {
|
|
|
76879
76935
|
const lines = [
|
|
76880
76936
|
`Tunnel: ${r2.url}`,
|
|
76881
76937
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
76882
|
-
`Frpc config: ${
|
|
76883
|
-
`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")}`
|
|
76884
76940
|
];
|
|
76885
76941
|
const width2 = Math.max(...lines.map((l2) => l2.length));
|
|
76886
76942
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -76893,7 +76949,7 @@ ${bar}
|
|
|
76893
76949
|
|
|
76894
76950
|
`);
|
|
76895
76951
|
try {
|
|
76896
|
-
const connectPath =
|
|
76952
|
+
const connectPath = import_node_path84.default.join(config.dataDir, "connect.txt");
|
|
76897
76953
|
import_node_fs65.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
76898
76954
|
} catch {
|
|
76899
76955
|
}
|
|
@@ -76992,7 +77048,7 @@ ${bar}
|
|
|
76992
77048
|
};
|
|
76993
77049
|
}
|
|
76994
77050
|
function migrateDropPersonsDir(dataDir) {
|
|
76995
|
-
const dir =
|
|
77051
|
+
const dir = import_node_path84.default.join(dataDir, "persons");
|
|
76996
77052
|
try {
|
|
76997
77053
|
import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
|
|
76998
77054
|
} catch {
|