@clawos-dev/clawd 0.2.590 → 0.2.592
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 +64 -3
- package/dist/cli.cjs +1103 -647
- package/dist/cloud-persona-conversations.html +26 -26
- package/dist/cloud-persona-metrics.html +1 -1
- package/dist/dispatch/mcp-server.cjs +64 -3
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +64 -3
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +64 -3
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/guest-BSZiAW_A.css +32 -0
- package/dist/share-ui/assets/{guest-lVfeCzyH.js → guest-XBkJIDIi.js} +128 -128
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-Bw0Z9Ope.css +0 -32
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: path105, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path105, ...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, path105, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path105;
|
|
770
770
|
this._key = key;
|
|
771
771
|
}
|
|
772
772
|
get path() {
|
|
@@ -5769,6 +5769,70 @@ var init_esm = __esm({
|
|
|
5769
5769
|
}
|
|
5770
5770
|
});
|
|
5771
5771
|
|
|
5772
|
+
// ../protocol/src/subscription-channel.ts
|
|
5773
|
+
function maskApiKey(key) {
|
|
5774
|
+
const trimmed = key.trim();
|
|
5775
|
+
if (!trimmed) return "";
|
|
5776
|
+
if (trimmed.length <= 8) return "****";
|
|
5777
|
+
return `${trimmed.slice(0, 3)}****${trimmed.slice(-4)}`;
|
|
5778
|
+
}
|
|
5779
|
+
function toChannelView(channel) {
|
|
5780
|
+
return {
|
|
5781
|
+
id: channel.id,
|
|
5782
|
+
name: channel.name,
|
|
5783
|
+
baseUrl: channel.baseUrl,
|
|
5784
|
+
...channel.remark ? { remark: channel.remark } : {},
|
|
5785
|
+
keyMasked: maskApiKey(channel.apiKey),
|
|
5786
|
+
hasKey: Boolean(channel.apiKey.trim()),
|
|
5787
|
+
createdAt: channel.createdAt,
|
|
5788
|
+
updatedAt: channel.updatedAt
|
|
5789
|
+
};
|
|
5790
|
+
}
|
|
5791
|
+
var SubscriptionChannelSchema, SubscriptionChannelViewSchema, SubscriptionChannelsStateSchema, SubscriptionChannelGetArgsSchema, SubscriptionChannelSaveArgsSchema, SubscriptionChannelDeleteArgsSchema, SubscriptionChannelActivateArgsSchema;
|
|
5792
|
+
var init_subscription_channel = __esm({
|
|
5793
|
+
"../protocol/src/subscription-channel.ts"() {
|
|
5794
|
+
"use strict";
|
|
5795
|
+
init_zod();
|
|
5796
|
+
SubscriptionChannelSchema = external_exports.object({
|
|
5797
|
+
id: external_exports.string().min(1),
|
|
5798
|
+
name: external_exports.string().min(1),
|
|
5799
|
+
baseUrl: external_exports.string().min(1),
|
|
5800
|
+
apiKey: external_exports.string().min(1),
|
|
5801
|
+
remark: external_exports.string().optional(),
|
|
5802
|
+
createdAt: external_exports.number(),
|
|
5803
|
+
updatedAt: external_exports.number()
|
|
5804
|
+
}).strict();
|
|
5805
|
+
SubscriptionChannelViewSchema = external_exports.object({
|
|
5806
|
+
id: external_exports.string().min(1),
|
|
5807
|
+
name: external_exports.string().min(1),
|
|
5808
|
+
baseUrl: external_exports.string().min(1),
|
|
5809
|
+
remark: external_exports.string().optional(),
|
|
5810
|
+
keyMasked: external_exports.string(),
|
|
5811
|
+
hasKey: external_exports.boolean(),
|
|
5812
|
+
createdAt: external_exports.number(),
|
|
5813
|
+
updatedAt: external_exports.number()
|
|
5814
|
+
}).strict();
|
|
5815
|
+
SubscriptionChannelsStateSchema = external_exports.object({
|
|
5816
|
+
activeChannelId: external_exports.string().nullable(),
|
|
5817
|
+
channels: external_exports.array(SubscriptionChannelViewSchema)
|
|
5818
|
+
}).strict();
|
|
5819
|
+
SubscriptionChannelGetArgsSchema = external_exports.object({}).strict();
|
|
5820
|
+
SubscriptionChannelSaveArgsSchema = external_exports.object({
|
|
5821
|
+
id: external_exports.string().min(1).optional(),
|
|
5822
|
+
name: external_exports.string().min(1),
|
|
5823
|
+
baseUrl: external_exports.string().min(1),
|
|
5824
|
+
apiKey: external_exports.string().optional(),
|
|
5825
|
+
remark: external_exports.string().optional()
|
|
5826
|
+
}).strict();
|
|
5827
|
+
SubscriptionChannelDeleteArgsSchema = external_exports.object({
|
|
5828
|
+
id: external_exports.string().min(1)
|
|
5829
|
+
}).strict();
|
|
5830
|
+
SubscriptionChannelActivateArgsSchema = external_exports.object({
|
|
5831
|
+
id: external_exports.string().min(1).nullable()
|
|
5832
|
+
}).strict();
|
|
5833
|
+
}
|
|
5834
|
+
});
|
|
5835
|
+
|
|
5772
5836
|
// ../protocol/src/attachment-schemas.ts
|
|
5773
5837
|
var TOKEN_ROLES, GROUP_FILE_SOURCES, GroupFileEntrySchema, AttachmentSignUrlArgs, AttachmentSignUrlResponseSchema, AttachmentGroupAddArgs, AttachmentGroupAddResponseSchema, AttachmentGroupRemoveArgs, AttachmentGroupRemoveResponseSchema, AttachmentGroupListArgs, AttachmentGroupListResponseSchema, AttachmentUploadResponseSchema;
|
|
5774
5838
|
var init_attachment_schemas = __esm({
|
|
@@ -6386,8 +6450,11 @@ var init_deploy_schemas = __esm({
|
|
|
6386
6450
|
}).strict();
|
|
6387
6451
|
DeploySetEngineAuthArgsSchema = external_exports.object({
|
|
6388
6452
|
personaId: external_exports.string().min(1),
|
|
6389
|
-
|
|
6390
|
-
|
|
6453
|
+
channelId: external_exports.string().min(1).optional(),
|
|
6454
|
+
auth: external_exports.object({ baseUrl: external_exports.string(), apiKey: external_exports.string() }).strict().nullable().optional()
|
|
6455
|
+
}).strict().refine((data) => data.channelId !== void 0 || data.auth !== void 0, {
|
|
6456
|
+
message: "Either channelId or auth must be provided"
|
|
6457
|
+
});
|
|
6391
6458
|
DeployRerunJobArgsSchema = external_exports.object({
|
|
6392
6459
|
personaId: external_exports.string().min(1),
|
|
6393
6460
|
/** GitHub 的 job databaseId。**是数字**——字符串会在拼命令时静默出错 */
|
|
@@ -8943,6 +9010,7 @@ var init_methods = __esm({
|
|
|
8943
9010
|
"use strict";
|
|
8944
9011
|
init_zod();
|
|
8945
9012
|
init_esm();
|
|
9013
|
+
init_subscription_channel();
|
|
8946
9014
|
init_attachment_schemas();
|
|
8947
9015
|
init_contact_handshake();
|
|
8948
9016
|
init_deploy_schemas();
|
|
@@ -9172,7 +9240,10 @@ var init_methods = __esm({
|
|
|
9172
9240
|
},
|
|
9173
9241
|
"deploy:setEngineAuth": {
|
|
9174
9242
|
summary: "\u6A21\u578B\u8BA2\u9605\uFF08\u4E91\u4E0A\u8DD1\u8FD9\u4E2A persona \u82B1\u8C01\u7684\u6A21\u578B\u989D\u5EA6\uFF09\uFF1Aauth = { baseUrl, apiKey } \u5199\u8FDB\u4ED3\u5E93 GitHub Secrets \u7684 CLAWD_ENGINE_BASE_URL / CLAWD_ENGINE_API_KEY\uFF08\u5730\u5740\u89C4\u8303\u6210 \u2026/v1\uFF09\uFF0Cnull = \u5220\u8FD9\u4E24\u6761\u3001\u6539\u56DE\u5E73\u53F0\u9ED8\u8BA4\u3002\u4E0B\u6B21\u53D1\u5E03\u751F\u6548\u3002\u540C putSecret \u7684\u7EAA\u5F8B\uFF1A\u5165\u53C2\u4E0D\u8FDB\u65E5\u5FD7\u3001\u54CD\u5E94\u4E0D\u56DE\u663E\u503C\u3001\u672C\u673A\u4E0D\u843D\u76D8\uFF1B\u56DE deploy:get \u540C\u5F62\u7684\u72B6\u6001\uFF1Bowner-only\u3001human-only",
|
|
9175
|
-
args: DeploySetEngineAuthArgsSchema
|
|
9243
|
+
args: DeploySetEngineAuthArgsSchema,
|
|
9244
|
+
argsConstraints: {
|
|
9245
|
+
anyOf: [{ required: ["channelId"] }, { required: ["auth"] }]
|
|
9246
|
+
}
|
|
9176
9247
|
},
|
|
9177
9248
|
"deploy:reportFinding": {
|
|
9178
9249
|
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\uFF08cli / secret / asset\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u9875\u9762\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\u3002owner-only\u2014\u2014butler \u4F1A\u8BDD\u672C\u8EAB\u8DD1\u5728 owner \u6A21\u5F0F",
|
|
@@ -9417,6 +9488,22 @@ var init_methods = __esm({
|
|
|
9417
9488
|
summary: "\u67D0\u4E2A\u5F15\u64CE\uFF08claude / codex / pi\uFF09\u7684\u5B89\u88C5\u72B6\u6001 + \u8BA2\u9605 / \u767B\u5F55\u60C5\u51B5\uFF08claude auth status\u3001codex account/read + rateLimits\u3001pi auth.json \u51ED\u636E\u7C7B\u578B\uFF09+ \u6A21\u578B\u8868\u52A0\u8F7D\u65F6\u95F4\u3002\u4E00\u5F8B\u4E0D\u5E26 key / token \u503C\u3002owner-only",
|
|
9418
9489
|
args: EngineStatusArgs
|
|
9419
9490
|
},
|
|
9491
|
+
"subscriptionChannel:get": {
|
|
9492
|
+
summary: "\u83B7\u53D6\u672C\u5730\u4FDD\u5B58\u7684\u6240\u6709\u6A21\u578B\u8BA2\u9605\u901A\u9053\u53CA\u5F53\u524D\u6FC0\u6D3B\u901A\u9053\u3002owner-only",
|
|
9493
|
+
args: SubscriptionChannelGetArgsSchema
|
|
9494
|
+
},
|
|
9495
|
+
"subscriptionChannel:save": {
|
|
9496
|
+
summary: "\u521B\u5EFA\u6216\u7F16\u8F91\u6A21\u578B\u8BA2\u9605\u901A\u9053\uFF08\u540D\u79F0\u3001URL\u3001Key\u3001\u5907\u6CE8\uFF09\u3002owner-only",
|
|
9497
|
+
args: SubscriptionChannelSaveArgsSchema
|
|
9498
|
+
},
|
|
9499
|
+
"subscriptionChannel:delete": {
|
|
9500
|
+
summary: "\u5220\u9664\u6307\u5B9A\u7684\u6A21\u578B\u8BA2\u9605\u901A\u9053\u3002owner-only",
|
|
9501
|
+
args: SubscriptionChannelDeleteArgsSchema
|
|
9502
|
+
},
|
|
9503
|
+
"subscriptionChannel:activate": {
|
|
9504
|
+
summary: "\u5207\u6362\u5F53\u524D\u6FC0\u6D3B\u7684\u6A21\u578B\u8BA2\u9605\u901A\u9053\uFF08\u5199 config.toml \u5E76\u5237\u65B0\u6A21\u578B\u8868\uFF09\u3002owner-only",
|
|
9505
|
+
args: SubscriptionChannelActivateArgsSchema
|
|
9506
|
+
},
|
|
9420
9507
|
"engine:connectPool": {
|
|
9421
9508
|
summary: "\u63A5\u5165\u53F7\u6C60\uFF1A\u62FF\u81EA\u52A9\u53F0\u53D1\u7684\u4E2A\u4EBA key\uFF0C\u62C9\u53F7\u6C60 setup.sh \u8DD1\u4E00\u904D\uFF08\u5199 ~/.codex/config.toml \u6307\u5411 CLIProxyAPI \u4EE3\u7406\uFF09\uFF0C\u518D\u5237 codex \u6A21\u578B\u8868\u9A8C\u8BC1\u3002\u6210\u529F\u56DE { ok:true }\uFF1B\u62FF\u4E0D\u5230\u811A\u672C / \u811A\u672C\u62A5\u9519 / \u8D85\u65F6 / 401 \u4E00\u5F8B reject \u5E26\u4EBA\u8BDD\u3002\u53EA\u7BA1 codex\uFF1B\u672C\u673A\u6CA1\u88C5 codex \u62A5 INVALID_PARAM\u3002owner-only",
|
|
9422
9509
|
args: EngineConnectPoolArgs
|
|
@@ -9963,6 +10050,7 @@ var init_runtime = __esm({
|
|
|
9963
10050
|
init_onboarding_schemas();
|
|
9964
10051
|
init_engine_schemas();
|
|
9965
10052
|
init_tool_family();
|
|
10053
|
+
init_subscription_channel();
|
|
9966
10054
|
}
|
|
9967
10055
|
});
|
|
9968
10056
|
|
|
@@ -10237,8 +10325,8 @@ var require_req = __commonJS({
|
|
|
10237
10325
|
if (req.originalUrl) {
|
|
10238
10326
|
_req.url = req.originalUrl;
|
|
10239
10327
|
} else {
|
|
10240
|
-
const
|
|
10241
|
-
_req.url = typeof
|
|
10328
|
+
const path105 = req.path;
|
|
10329
|
+
_req.url = typeof path105 === "string" ? path105 : req.url ? req.url.path || req.url : void 0;
|
|
10242
10330
|
}
|
|
10243
10331
|
if (req.query) {
|
|
10244
10332
|
_req.query = req.query;
|
|
@@ -10403,14 +10491,14 @@ var require_redact = __commonJS({
|
|
|
10403
10491
|
}
|
|
10404
10492
|
return obj;
|
|
10405
10493
|
}
|
|
10406
|
-
function parsePath(
|
|
10494
|
+
function parsePath(path105) {
|
|
10407
10495
|
const parts = [];
|
|
10408
10496
|
let current = "";
|
|
10409
10497
|
let inBrackets = false;
|
|
10410
10498
|
let inQuotes = false;
|
|
10411
10499
|
let quoteChar = "";
|
|
10412
|
-
for (let i2 = 0; i2 <
|
|
10413
|
-
const char =
|
|
10500
|
+
for (let i2 = 0; i2 < path105.length; i2++) {
|
|
10501
|
+
const char = path105[i2];
|
|
10414
10502
|
if (!inBrackets && char === ".") {
|
|
10415
10503
|
if (current) {
|
|
10416
10504
|
parts.push(current);
|
|
@@ -10541,10 +10629,10 @@ var require_redact = __commonJS({
|
|
|
10541
10629
|
return current;
|
|
10542
10630
|
}
|
|
10543
10631
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
10544
|
-
for (const
|
|
10545
|
-
const parts = parsePath(
|
|
10632
|
+
for (const path105 of paths) {
|
|
10633
|
+
const parts = parsePath(path105);
|
|
10546
10634
|
if (parts.includes("*")) {
|
|
10547
|
-
redactWildcardPath(obj, parts, censor,
|
|
10635
|
+
redactWildcardPath(obj, parts, censor, path105, remove);
|
|
10548
10636
|
} else {
|
|
10549
10637
|
if (remove) {
|
|
10550
10638
|
removeKey(obj, parts);
|
|
@@ -10629,8 +10717,8 @@ var require_redact = __commonJS({
|
|
|
10629
10717
|
}
|
|
10630
10718
|
} else {
|
|
10631
10719
|
if (afterWildcard.includes("*")) {
|
|
10632
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10633
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
10720
|
+
const wrappedCensor = typeof censor === "function" ? (value, path105) => {
|
|
10721
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path105];
|
|
10634
10722
|
return censor(value, fullPath);
|
|
10635
10723
|
} : censor;
|
|
10636
10724
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -10665,8 +10753,8 @@ var require_redact = __commonJS({
|
|
|
10665
10753
|
return null;
|
|
10666
10754
|
}
|
|
10667
10755
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
10668
|
-
for (const
|
|
10669
|
-
const parts = parsePath(
|
|
10756
|
+
for (const path105 of pathsToClone) {
|
|
10757
|
+
const parts = parsePath(path105);
|
|
10670
10758
|
let current = pathStructure;
|
|
10671
10759
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
10672
10760
|
const part = parts[i2];
|
|
@@ -10718,24 +10806,24 @@ var require_redact = __commonJS({
|
|
|
10718
10806
|
}
|
|
10719
10807
|
return cloneSelectively(obj, pathStructure);
|
|
10720
10808
|
}
|
|
10721
|
-
function validatePath(
|
|
10722
|
-
if (typeof
|
|
10809
|
+
function validatePath(path105) {
|
|
10810
|
+
if (typeof path105 !== "string") {
|
|
10723
10811
|
throw new Error("Paths must be (non-empty) strings");
|
|
10724
10812
|
}
|
|
10725
|
-
if (
|
|
10813
|
+
if (path105 === "") {
|
|
10726
10814
|
throw new Error("Invalid redaction path ()");
|
|
10727
10815
|
}
|
|
10728
|
-
if (
|
|
10729
|
-
throw new Error(`Invalid redaction path (${
|
|
10816
|
+
if (path105.includes("..")) {
|
|
10817
|
+
throw new Error(`Invalid redaction path (${path105})`);
|
|
10730
10818
|
}
|
|
10731
|
-
if (
|
|
10732
|
-
throw new Error(`Invalid redaction path (${
|
|
10819
|
+
if (path105.includes(",")) {
|
|
10820
|
+
throw new Error(`Invalid redaction path (${path105})`);
|
|
10733
10821
|
}
|
|
10734
10822
|
let bracketCount = 0;
|
|
10735
10823
|
let inQuotes = false;
|
|
10736
10824
|
let quoteChar = "";
|
|
10737
|
-
for (let i2 = 0; i2 <
|
|
10738
|
-
const char =
|
|
10825
|
+
for (let i2 = 0; i2 < path105.length; i2++) {
|
|
10826
|
+
const char = path105[i2];
|
|
10739
10827
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
10740
10828
|
if (!inQuotes) {
|
|
10741
10829
|
inQuotes = true;
|
|
@@ -10749,20 +10837,20 @@ var require_redact = __commonJS({
|
|
|
10749
10837
|
} else if (char === "]" && !inQuotes) {
|
|
10750
10838
|
bracketCount--;
|
|
10751
10839
|
if (bracketCount < 0) {
|
|
10752
|
-
throw new Error(`Invalid redaction path (${
|
|
10840
|
+
throw new Error(`Invalid redaction path (${path105})`);
|
|
10753
10841
|
}
|
|
10754
10842
|
}
|
|
10755
10843
|
}
|
|
10756
10844
|
if (bracketCount !== 0) {
|
|
10757
|
-
throw new Error(`Invalid redaction path (${
|
|
10845
|
+
throw new Error(`Invalid redaction path (${path105})`);
|
|
10758
10846
|
}
|
|
10759
10847
|
}
|
|
10760
10848
|
function validatePaths(paths) {
|
|
10761
10849
|
if (!Array.isArray(paths)) {
|
|
10762
10850
|
throw new TypeError("paths must be an array");
|
|
10763
10851
|
}
|
|
10764
|
-
for (const
|
|
10765
|
-
validatePath(
|
|
10852
|
+
for (const path105 of paths) {
|
|
10853
|
+
validatePath(path105);
|
|
10766
10854
|
}
|
|
10767
10855
|
}
|
|
10768
10856
|
function slowRedact(options = {}) {
|
|
@@ -10930,8 +11018,8 @@ var require_redaction = __commonJS({
|
|
|
10930
11018
|
if (shape[k3] === null) {
|
|
10931
11019
|
o2[k3] = (value) => topCensor(value, [k3]);
|
|
10932
11020
|
} else {
|
|
10933
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10934
|
-
return censor(value, [k3, ...
|
|
11021
|
+
const wrappedCensor = typeof censor === "function" ? (value, path105) => {
|
|
11022
|
+
return censor(value, [k3, ...path105]);
|
|
10935
11023
|
} : censor;
|
|
10936
11024
|
o2[k3] = Redact({
|
|
10937
11025
|
paths: shape[k3],
|
|
@@ -11149,10 +11237,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
11149
11237
|
var require_sonic_boom = __commonJS({
|
|
11150
11238
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
11151
11239
|
"use strict";
|
|
11152
|
-
var
|
|
11240
|
+
var fs95 = require("fs");
|
|
11153
11241
|
var EventEmitter2 = require("events");
|
|
11154
11242
|
var inherits = require("util").inherits;
|
|
11155
|
-
var
|
|
11243
|
+
var path105 = require("path");
|
|
11156
11244
|
var sleep2 = require_atomic_sleep();
|
|
11157
11245
|
var assert = require("assert");
|
|
11158
11246
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -11206,20 +11294,20 @@ var require_sonic_boom = __commonJS({
|
|
|
11206
11294
|
const mode = sonic.mode;
|
|
11207
11295
|
if (sonic.sync) {
|
|
11208
11296
|
try {
|
|
11209
|
-
if (sonic.mkdir)
|
|
11210
|
-
const fd =
|
|
11297
|
+
if (sonic.mkdir) fs95.mkdirSync(path105.dirname(file), { recursive: true });
|
|
11298
|
+
const fd = fs95.openSync(file, flags, mode);
|
|
11211
11299
|
fileOpened(null, fd);
|
|
11212
11300
|
} catch (err) {
|
|
11213
11301
|
fileOpened(err);
|
|
11214
11302
|
throw err;
|
|
11215
11303
|
}
|
|
11216
11304
|
} else if (sonic.mkdir) {
|
|
11217
|
-
|
|
11305
|
+
fs95.mkdir(path105.dirname(file), { recursive: true }, (err) => {
|
|
11218
11306
|
if (err) return fileOpened(err);
|
|
11219
|
-
|
|
11307
|
+
fs95.open(file, flags, mode, fileOpened);
|
|
11220
11308
|
});
|
|
11221
11309
|
} else {
|
|
11222
|
-
|
|
11310
|
+
fs95.open(file, flags, mode, fileOpened);
|
|
11223
11311
|
}
|
|
11224
11312
|
}
|
|
11225
11313
|
function SonicBoom(opts) {
|
|
@@ -11260,8 +11348,8 @@ var require_sonic_boom = __commonJS({
|
|
|
11260
11348
|
this.flush = flushBuffer;
|
|
11261
11349
|
this.flushSync = flushBufferSync;
|
|
11262
11350
|
this._actualWrite = actualWriteBuffer;
|
|
11263
|
-
fsWriteSync = () =>
|
|
11264
|
-
fsWrite = () =>
|
|
11351
|
+
fsWriteSync = () => fs95.writeSync(this.fd, this._writingBuf);
|
|
11352
|
+
fsWrite = () => fs95.write(this.fd, this._writingBuf, this.release);
|
|
11265
11353
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
11266
11354
|
this._writingBuf = "";
|
|
11267
11355
|
this.write = write;
|
|
@@ -11270,15 +11358,15 @@ var require_sonic_boom = __commonJS({
|
|
|
11270
11358
|
this._actualWrite = actualWrite;
|
|
11271
11359
|
fsWriteSync = () => {
|
|
11272
11360
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11273
|
-
return
|
|
11361
|
+
return fs95.writeSync(this.fd, this._writingBuf);
|
|
11274
11362
|
}
|
|
11275
|
-
return
|
|
11363
|
+
return fs95.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11276
11364
|
};
|
|
11277
11365
|
fsWrite = () => {
|
|
11278
11366
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11279
|
-
return
|
|
11367
|
+
return fs95.write(this.fd, this._writingBuf, this.release);
|
|
11280
11368
|
}
|
|
11281
|
-
return
|
|
11369
|
+
return fs95.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
11282
11370
|
};
|
|
11283
11371
|
} else {
|
|
11284
11372
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -11335,7 +11423,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11335
11423
|
}
|
|
11336
11424
|
}
|
|
11337
11425
|
if (this._fsync) {
|
|
11338
|
-
|
|
11426
|
+
fs95.fsyncSync(this.fd);
|
|
11339
11427
|
}
|
|
11340
11428
|
const len = this._len;
|
|
11341
11429
|
if (this._reopening) {
|
|
@@ -11449,7 +11537,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11449
11537
|
const onDrain = () => {
|
|
11450
11538
|
if (!this._fsync) {
|
|
11451
11539
|
try {
|
|
11452
|
-
|
|
11540
|
+
fs95.fsync(this.fd, (err) => {
|
|
11453
11541
|
this._flushPending = false;
|
|
11454
11542
|
cb(err);
|
|
11455
11543
|
});
|
|
@@ -11551,7 +11639,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11551
11639
|
const fd = this.fd;
|
|
11552
11640
|
this.once("ready", () => {
|
|
11553
11641
|
if (fd !== this.fd) {
|
|
11554
|
-
|
|
11642
|
+
fs95.close(fd, (err) => {
|
|
11555
11643
|
if (err) {
|
|
11556
11644
|
return this.emit("error", err);
|
|
11557
11645
|
}
|
|
@@ -11600,7 +11688,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11600
11688
|
buf = this._bufs[0];
|
|
11601
11689
|
}
|
|
11602
11690
|
try {
|
|
11603
|
-
const n2 = Buffer.isBuffer(buf) ?
|
|
11691
|
+
const n2 = Buffer.isBuffer(buf) ? fs95.writeSync(this.fd, buf) : fs95.writeSync(this.fd, buf, "utf8");
|
|
11604
11692
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
|
|
11605
11693
|
buf = releasedBufObj.writingBuf;
|
|
11606
11694
|
this._len = releasedBufObj.len;
|
|
@@ -11616,7 +11704,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11616
11704
|
}
|
|
11617
11705
|
}
|
|
11618
11706
|
try {
|
|
11619
|
-
|
|
11707
|
+
fs95.fsyncSync(this.fd);
|
|
11620
11708
|
} catch {
|
|
11621
11709
|
}
|
|
11622
11710
|
}
|
|
@@ -11637,7 +11725,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11637
11725
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
11638
11726
|
}
|
|
11639
11727
|
try {
|
|
11640
|
-
const n2 =
|
|
11728
|
+
const n2 = fs95.writeSync(this.fd, buf);
|
|
11641
11729
|
buf = buf.subarray(n2);
|
|
11642
11730
|
this._len = Math.max(this._len - n2, 0);
|
|
11643
11731
|
if (buf.length <= 0) {
|
|
@@ -11665,13 +11753,13 @@ var require_sonic_boom = __commonJS({
|
|
|
11665
11753
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
11666
11754
|
if (this.sync) {
|
|
11667
11755
|
try {
|
|
11668
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
11756
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs95.writeSync(this.fd, this._writingBuf) : fs95.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11669
11757
|
release2(null, written);
|
|
11670
11758
|
} catch (err) {
|
|
11671
11759
|
release2(err);
|
|
11672
11760
|
}
|
|
11673
11761
|
} else {
|
|
11674
|
-
|
|
11762
|
+
fs95.write(this.fd, this._writingBuf, release2);
|
|
11675
11763
|
}
|
|
11676
11764
|
}
|
|
11677
11765
|
function actualWriteBuffer() {
|
|
@@ -11680,7 +11768,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11680
11768
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
11681
11769
|
if (this.sync) {
|
|
11682
11770
|
try {
|
|
11683
|
-
const written =
|
|
11771
|
+
const written = fs95.writeSync(this.fd, this._writingBuf);
|
|
11684
11772
|
release2(null, written);
|
|
11685
11773
|
} catch (err) {
|
|
11686
11774
|
release2(err);
|
|
@@ -11689,7 +11777,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11689
11777
|
if (kCopyBuffer) {
|
|
11690
11778
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
11691
11779
|
}
|
|
11692
|
-
|
|
11780
|
+
fs95.write(this.fd, this._writingBuf, release2);
|
|
11693
11781
|
}
|
|
11694
11782
|
}
|
|
11695
11783
|
function actualClose(sonic) {
|
|
@@ -11705,12 +11793,12 @@ var require_sonic_boom = __commonJS({
|
|
|
11705
11793
|
sonic._lens = [];
|
|
11706
11794
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
11707
11795
|
try {
|
|
11708
|
-
|
|
11796
|
+
fs95.fsync(sonic.fd, closeWrapped);
|
|
11709
11797
|
} catch {
|
|
11710
11798
|
}
|
|
11711
11799
|
function closeWrapped() {
|
|
11712
11800
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
11713
|
-
|
|
11801
|
+
fs95.close(sonic.fd, done);
|
|
11714
11802
|
} else {
|
|
11715
11803
|
done();
|
|
11716
11804
|
}
|
|
@@ -14074,7 +14162,7 @@ var require_multistream = __commonJS({
|
|
|
14074
14162
|
var require_pino = __commonJS({
|
|
14075
14163
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
14076
14164
|
"use strict";
|
|
14077
|
-
var
|
|
14165
|
+
var os37 = require("os");
|
|
14078
14166
|
var stdSerializers = require_pino_std_serializers();
|
|
14079
14167
|
var caller = require_caller();
|
|
14080
14168
|
var redaction = require_redaction();
|
|
@@ -14121,7 +14209,7 @@ var require_pino = __commonJS({
|
|
|
14121
14209
|
} = symbols;
|
|
14122
14210
|
var { epochTime, nullTime } = time;
|
|
14123
14211
|
var { pid } = process;
|
|
14124
|
-
var hostname =
|
|
14212
|
+
var hostname = os37.hostname();
|
|
14125
14213
|
var defaultErrorSerializer = stdSerializers.err;
|
|
14126
14214
|
var defaultOptions2 = {
|
|
14127
14215
|
level: "info",
|
|
@@ -14845,11 +14933,11 @@ var init_lib = __esm({
|
|
|
14845
14933
|
}
|
|
14846
14934
|
}
|
|
14847
14935
|
},
|
|
14848
|
-
addToPath: function addToPath(
|
|
14849
|
-
var last =
|
|
14936
|
+
addToPath: function addToPath(path105, added, removed, oldPosInc, options) {
|
|
14937
|
+
var last = path105.lastComponent;
|
|
14850
14938
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14851
14939
|
return {
|
|
14852
|
-
oldPos:
|
|
14940
|
+
oldPos: path105.oldPos + oldPosInc,
|
|
14853
14941
|
lastComponent: {
|
|
14854
14942
|
count: last.count + 1,
|
|
14855
14943
|
added,
|
|
@@ -14859,7 +14947,7 @@ var init_lib = __esm({
|
|
|
14859
14947
|
};
|
|
14860
14948
|
} else {
|
|
14861
14949
|
return {
|
|
14862
|
-
oldPos:
|
|
14950
|
+
oldPos: path105.oldPos + oldPosInc,
|
|
14863
14951
|
lastComponent: {
|
|
14864
14952
|
count: 1,
|
|
14865
14953
|
added,
|
|
@@ -15441,10 +15529,10 @@ function attachmentToHistoryMessage(o2, ts) {
|
|
|
15441
15529
|
const memories = raw.map((m3) => {
|
|
15442
15530
|
if (!m3 || typeof m3 !== "object") return null;
|
|
15443
15531
|
const rec6 = m3;
|
|
15444
|
-
const
|
|
15532
|
+
const path105 = typeof rec6.path === "string" ? rec6.path : null;
|
|
15445
15533
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
15446
|
-
if (!
|
|
15447
|
-
const entry = { path:
|
|
15534
|
+
if (!path105 || content == null) return null;
|
|
15535
|
+
const entry = { path: path105, content };
|
|
15448
15536
|
if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
|
|
15449
15537
|
return entry;
|
|
15450
15538
|
}).filter((m3) => m3 !== null);
|
|
@@ -16310,10 +16398,10 @@ function parseAttachment(obj) {
|
|
|
16310
16398
|
const memories = raw.map((m3) => {
|
|
16311
16399
|
if (!m3 || typeof m3 !== "object") return null;
|
|
16312
16400
|
const rec6 = m3;
|
|
16313
|
-
const
|
|
16401
|
+
const path105 = typeof rec6.path === "string" ? rec6.path : null;
|
|
16314
16402
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
16315
|
-
if (!
|
|
16316
|
-
const out = { path:
|
|
16403
|
+
if (!path105 || content == null) return null;
|
|
16404
|
+
const out = { path: path105, content };
|
|
16317
16405
|
if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
|
|
16318
16406
|
return out;
|
|
16319
16407
|
}).filter((m3) => m3 !== null);
|
|
@@ -37287,8 +37375,8 @@ var require_utils = __commonJS({
|
|
|
37287
37375
|
var result = transform[inputType][outputType](input);
|
|
37288
37376
|
return result;
|
|
37289
37377
|
};
|
|
37290
|
-
exports2.resolve = function(
|
|
37291
|
-
var parts =
|
|
37378
|
+
exports2.resolve = function(path105) {
|
|
37379
|
+
var parts = path105.split("/");
|
|
37292
37380
|
var result = [];
|
|
37293
37381
|
for (var index = 0; index < parts.length; index++) {
|
|
37294
37382
|
var part = parts[index];
|
|
@@ -43141,18 +43229,18 @@ var require_object = __commonJS({
|
|
|
43141
43229
|
var object = new ZipObject(name, zipObjectContent, o2);
|
|
43142
43230
|
this.files[name] = object;
|
|
43143
43231
|
};
|
|
43144
|
-
var parentFolder = function(
|
|
43145
|
-
if (
|
|
43146
|
-
|
|
43232
|
+
var parentFolder = function(path105) {
|
|
43233
|
+
if (path105.slice(-1) === "/") {
|
|
43234
|
+
path105 = path105.substring(0, path105.length - 1);
|
|
43147
43235
|
}
|
|
43148
|
-
var lastSlash =
|
|
43149
|
-
return lastSlash > 0 ?
|
|
43236
|
+
var lastSlash = path105.lastIndexOf("/");
|
|
43237
|
+
return lastSlash > 0 ? path105.substring(0, lastSlash) : "";
|
|
43150
43238
|
};
|
|
43151
|
-
var forceTrailingSlash = function(
|
|
43152
|
-
if (
|
|
43153
|
-
|
|
43239
|
+
var forceTrailingSlash = function(path105) {
|
|
43240
|
+
if (path105.slice(-1) !== "/") {
|
|
43241
|
+
path105 += "/";
|
|
43154
43242
|
}
|
|
43155
|
-
return
|
|
43243
|
+
return path105;
|
|
43156
43244
|
};
|
|
43157
43245
|
var folderAdd = function(name, createFolders) {
|
|
43158
43246
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -44154,7 +44242,7 @@ var require_lib3 = __commonJS({
|
|
|
44154
44242
|
// src/run-case/recorder.ts
|
|
44155
44243
|
function startRunCaseRecorder(opts) {
|
|
44156
44244
|
const now = opts.now ?? Date.now;
|
|
44157
|
-
const dir =
|
|
44245
|
+
const dir = import_node_path84.default.dirname(opts.recordPath);
|
|
44158
44246
|
let stream = null;
|
|
44159
44247
|
let closing = false;
|
|
44160
44248
|
let closedSettled = false;
|
|
@@ -44168,8 +44256,8 @@ function startRunCaseRecorder(opts) {
|
|
|
44168
44256
|
});
|
|
44169
44257
|
const ensureStream = () => {
|
|
44170
44258
|
if (stream) return stream;
|
|
44171
|
-
|
|
44172
|
-
stream =
|
|
44259
|
+
import_node_fs66.default.mkdirSync(dir, { recursive: true });
|
|
44260
|
+
stream = import_node_fs66.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
44173
44261
|
stream.on("close", () => closedResolve());
|
|
44174
44262
|
return stream;
|
|
44175
44263
|
};
|
|
@@ -44194,12 +44282,12 @@ function startRunCaseRecorder(opts) {
|
|
|
44194
44282
|
};
|
|
44195
44283
|
return { tap, close, closed };
|
|
44196
44284
|
}
|
|
44197
|
-
var
|
|
44285
|
+
var import_node_fs66, import_node_path84;
|
|
44198
44286
|
var init_recorder = __esm({
|
|
44199
44287
|
"src/run-case/recorder.ts"() {
|
|
44200
44288
|
"use strict";
|
|
44201
|
-
|
|
44202
|
-
|
|
44289
|
+
import_node_fs66 = __toESM(require("fs"), 1);
|
|
44290
|
+
import_node_path84 = __toESM(require("path"), 1);
|
|
44203
44291
|
}
|
|
44204
44292
|
});
|
|
44205
44293
|
|
|
@@ -44242,7 +44330,7 @@ var init_wire = __esm({
|
|
|
44242
44330
|
// src/run-case/controller.ts
|
|
44243
44331
|
async function runController(opts) {
|
|
44244
44332
|
const now = opts.now ?? Date.now;
|
|
44245
|
-
const cwd = opts.cwd ?? (0,
|
|
44333
|
+
const cwd = opts.cwd ?? (0, import_node_fs67.mkdtempSync)(import_node_path85.default.join(import_node_os33.default.tmpdir(), "clawd-runcase-"));
|
|
44246
44334
|
const ownsCwd = opts.cwd === void 0;
|
|
44247
44335
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
44248
44336
|
const spawnCtx = { cwd };
|
|
@@ -44403,19 +44491,19 @@ async function runController(opts) {
|
|
|
44403
44491
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
44404
44492
|
if (ownsCwd) {
|
|
44405
44493
|
try {
|
|
44406
|
-
(0,
|
|
44494
|
+
(0, import_node_fs67.rmSync)(cwd, { recursive: true, force: true });
|
|
44407
44495
|
} catch {
|
|
44408
44496
|
}
|
|
44409
44497
|
}
|
|
44410
44498
|
return exitCode ?? 0;
|
|
44411
44499
|
}
|
|
44412
|
-
var
|
|
44500
|
+
var import_node_fs67, import_node_os33, import_node_path85;
|
|
44413
44501
|
var init_controller = __esm({
|
|
44414
44502
|
"src/run-case/controller.ts"() {
|
|
44415
44503
|
"use strict";
|
|
44416
|
-
|
|
44417
|
-
|
|
44418
|
-
|
|
44504
|
+
import_node_fs67 = require("fs");
|
|
44505
|
+
import_node_os33 = __toESM(require("os"), 1);
|
|
44506
|
+
import_node_path85 = __toESM(require("path"), 1);
|
|
44419
44507
|
init_claude();
|
|
44420
44508
|
init_stdout_splitter();
|
|
44421
44509
|
init_permission_stdio();
|
|
@@ -44687,9 +44775,9 @@ Env (advanced):
|
|
|
44687
44775
|
`;
|
|
44688
44776
|
|
|
44689
44777
|
// src/index.ts
|
|
44690
|
-
var
|
|
44691
|
-
var
|
|
44692
|
-
var
|
|
44778
|
+
var import_node_path83 = __toESM(require("path"), 1);
|
|
44779
|
+
var import_node_fs65 = __toESM(require("fs"), 1);
|
|
44780
|
+
var import_node_os32 = __toESM(require("os"), 1);
|
|
44693
44781
|
var import_node_crypto26 = require("crypto");
|
|
44694
44782
|
var import_node_url6 = require("url");
|
|
44695
44783
|
|
|
@@ -52435,9 +52523,9 @@ var CentralClientError = class extends Error {
|
|
|
52435
52523
|
cause;
|
|
52436
52524
|
status;
|
|
52437
52525
|
};
|
|
52438
|
-
async function centralRequest(opts,
|
|
52526
|
+
async function centralRequest(opts, path105, init) {
|
|
52439
52527
|
const f2 = opts.fetchImpl ?? globalThis.fetch;
|
|
52440
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52528
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path105}`;
|
|
52441
52529
|
const ctrl = new AbortController();
|
|
52442
52530
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
52443
52531
|
let res;
|
|
@@ -53471,8 +53559,8 @@ function turnStartInput(text, resolveImage) {
|
|
|
53471
53559
|
const items = [];
|
|
53472
53560
|
let leftover = text;
|
|
53473
53561
|
for (const m3 of text.matchAll(SKILL_RE)) {
|
|
53474
|
-
const [marker, name,
|
|
53475
|
-
items.push({ type: "skill", name, path:
|
|
53562
|
+
const [marker, name, path105] = m3;
|
|
53563
|
+
items.push({ type: "skill", name, path: path105 });
|
|
53476
53564
|
leftover = leftover.replace(marker, "");
|
|
53477
53565
|
}
|
|
53478
53566
|
for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -56775,9 +56863,15 @@ function createShiftSpawnFn(deps) {
|
|
|
56775
56863
|
}
|
|
56776
56864
|
|
|
56777
56865
|
// src/handlers/types.ts
|
|
56866
|
+
init_zod();
|
|
56778
56867
|
init_protocol();
|
|
56779
56868
|
function parseArgs2(schema, frame, what, code = ERROR_CODES.VALIDATION_ERROR) {
|
|
56780
|
-
|
|
56869
|
+
let effective = schema;
|
|
56870
|
+
if (typeof schema.strip === "function") {
|
|
56871
|
+
effective = schema.strip();
|
|
56872
|
+
} else if (schema instanceof external_exports.ZodEffects && typeof schema._def?.schema?.strip === "function") {
|
|
56873
|
+
effective = new external_exports.ZodEffects({ ...schema._def, schema: schema._def.schema.strip() });
|
|
56874
|
+
}
|
|
56781
56875
|
const r2 = effective.safeParse(frame);
|
|
56782
56876
|
if (!r2.success) throw new ClawdError(code, `${what}: ${r2.error.message}`);
|
|
56783
56877
|
return r2.data;
|
|
@@ -60839,10 +60933,10 @@ function createGithubApi(args) {
|
|
|
60839
60933
|
const doFetch = args.fetch ?? fetch;
|
|
60840
60934
|
const seal = args.seal ?? sealWithSodium;
|
|
60841
60935
|
const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
|
|
60842
|
-
async function request(method,
|
|
60936
|
+
async function request(method, path105, body) {
|
|
60843
60937
|
let res;
|
|
60844
60938
|
try {
|
|
60845
|
-
res = await doFetch(`${API}${
|
|
60939
|
+
res = await doFetch(`${API}${path105}`, {
|
|
60846
60940
|
method,
|
|
60847
60941
|
headers: {
|
|
60848
60942
|
Authorization: `Bearer ${args.token}`,
|
|
@@ -60867,8 +60961,8 @@ function createGithubApi(args) {
|
|
|
60867
60961
|
}
|
|
60868
60962
|
return { status: res.status, json };
|
|
60869
60963
|
}
|
|
60870
|
-
async function must(method,
|
|
60871
|
-
const r2 = await request(method,
|
|
60964
|
+
async function must(method, path105, what, body) {
|
|
60965
|
+
const r2 = await request(method, path105, body);
|
|
60872
60966
|
if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
|
|
60873
60967
|
return r2.json;
|
|
60874
60968
|
}
|
|
@@ -60913,9 +61007,9 @@ function createGithubApi(args) {
|
|
|
60913
61007
|
return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
|
|
60914
61008
|
});
|
|
60915
61009
|
},
|
|
60916
|
-
async getJson(
|
|
61010
|
+
async getJson(path105) {
|
|
60917
61011
|
try {
|
|
60918
|
-
const r2 = await request("GET",
|
|
61012
|
+
const r2 = await request("GET", path105);
|
|
60919
61013
|
return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
|
|
60920
61014
|
} catch {
|
|
60921
61015
|
return void 0;
|
|
@@ -61903,15 +61997,21 @@ function buildDeployHandlers(deps) {
|
|
|
61903
61997
|
ensureOwner(ctx);
|
|
61904
61998
|
const args = parseArgs2(DeploySetEngineAuthArgsSchema, frame, "deploy:setEngineAuth");
|
|
61905
61999
|
const dir = mustPersona(args.personaId);
|
|
62000
|
+
let auth = args.auth;
|
|
62001
|
+
if (args.channelId) {
|
|
62002
|
+
const channel = deps.channelStore?.get(args.channelId);
|
|
62003
|
+
if (!channel) throw invalid(`\u672A\u627E\u5230 ID \u4E3A ${args.channelId} \u7684\u8BA2\u9605\u901A\u9053`);
|
|
62004
|
+
auth = { baseUrl: channel.baseUrl, apiKey: channel.apiKey };
|
|
62005
|
+
}
|
|
61906
62006
|
let writes;
|
|
61907
|
-
if (
|
|
62007
|
+
if (auth) {
|
|
61908
62008
|
let baseUrl;
|
|
61909
62009
|
try {
|
|
61910
|
-
baseUrl = normalizeEngineBaseUrl(
|
|
62010
|
+
baseUrl = normalizeEngineBaseUrl(auth.baseUrl);
|
|
61911
62011
|
} catch (err) {
|
|
61912
62012
|
throw invalid(err instanceof Error ? err.message : String(err));
|
|
61913
62013
|
}
|
|
61914
|
-
const apiKey =
|
|
62014
|
+
const apiKey = auth.apiKey.trim();
|
|
61915
62015
|
if (!apiKey) throw invalid("key \u4E0D\u80FD\u662F\u7A7A\u7684");
|
|
61916
62016
|
if (/[\s\p{Cc}]/u.test(apiKey)) throw invalid("key \u91CC\u4E0D\u80FD\u6709\u7A7A\u767D\u6216\u63A7\u5236\u5B57\u7B26\uFF08\u591A\u534A\u662F\u7C98\u8D34\u65F6\u5E26\u8FDB\u4E86\u6362\u884C\u6216\u7A7A\u683C\uFF09");
|
|
61917
62017
|
writes = [[ENGINE_AUTH_SECRETS.apiKey, apiKey], [ENGINE_AUTH_SECRETS.baseUrl, baseUrl]];
|
|
@@ -62166,6 +62266,188 @@ function buildDeployHandlers(deps) {
|
|
|
62166
62266
|
};
|
|
62167
62267
|
}
|
|
62168
62268
|
|
|
62269
|
+
// src/tools/subscription-channels-store.ts
|
|
62270
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
62271
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
62272
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
62273
|
+
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
|
+
var SubscriptionChannelStore = class {
|
|
62290
|
+
filePath;
|
|
62291
|
+
codexHome;
|
|
62292
|
+
constructor(options) {
|
|
62293
|
+
this.filePath = import_node_path40.default.join(options.dataDir, CHANNELS_FILE_NAME);
|
|
62294
|
+
this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path40.default.join(import_node_os12.default.homedir(), ".codex");
|
|
62295
|
+
}
|
|
62296
|
+
/** 获取列表与激活通道 ID(Key 经脱敏掩码) */
|
|
62297
|
+
list() {
|
|
62298
|
+
const data = this.readOrCreate();
|
|
62299
|
+
return {
|
|
62300
|
+
activeChannelId: data.activeChannelId,
|
|
62301
|
+
channels: data.channels.map(toChannelView)
|
|
62302
|
+
};
|
|
62303
|
+
}
|
|
62304
|
+
/** 获取通道原始实体(含明文 Key,供配置应用与部署写入使用) */
|
|
62305
|
+
get(id) {
|
|
62306
|
+
const data = this.readOrCreate();
|
|
62307
|
+
return data.channels.find((c2) => c2.id === id) ?? null;
|
|
62308
|
+
}
|
|
62309
|
+
/** 获取当前激活的通道实体 */
|
|
62310
|
+
getActive() {
|
|
62311
|
+
const data = this.readOrCreate();
|
|
62312
|
+
if (!data.activeChannelId) return null;
|
|
62313
|
+
return data.channels.find((c2) => c2.id === data.activeChannelId) ?? null;
|
|
62314
|
+
}
|
|
62315
|
+
/** 保存(新增或更新)通道 */
|
|
62316
|
+
save(input) {
|
|
62317
|
+
const name = input.name.trim();
|
|
62318
|
+
if (!name) throw new Error("\u901A\u9053\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
62319
|
+
let baseUrl;
|
|
62320
|
+
try {
|
|
62321
|
+
baseUrl = normalizeEngineBaseUrl(input.baseUrl);
|
|
62322
|
+
} catch (err) {
|
|
62323
|
+
throw new Error(err instanceof Error ? err.message : String(err));
|
|
62324
|
+
}
|
|
62325
|
+
const data = this.readOrCreate();
|
|
62326
|
+
const now = Date.now();
|
|
62327
|
+
if (input.id) {
|
|
62328
|
+
const idx = data.channels.findIndex((c2) => c2.id === input.id);
|
|
62329
|
+
if (idx === -1) throw new Error(`\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u901A\u9053`);
|
|
62330
|
+
const existing = data.channels[idx];
|
|
62331
|
+
const apiKey2 = input.apiKey && input.apiKey.trim() ? input.apiKey.trim() : existing.apiKey;
|
|
62332
|
+
const updated = {
|
|
62333
|
+
...existing,
|
|
62334
|
+
name,
|
|
62335
|
+
baseUrl,
|
|
62336
|
+
apiKey: apiKey2,
|
|
62337
|
+
...input.remark !== void 0 ? { remark: input.remark.trim() || void 0 } : {},
|
|
62338
|
+
updatedAt: now
|
|
62339
|
+
};
|
|
62340
|
+
data.channels[idx] = updated;
|
|
62341
|
+
this.write(data);
|
|
62342
|
+
return updated;
|
|
62343
|
+
}
|
|
62344
|
+
const apiKey = input.apiKey?.trim();
|
|
62345
|
+
if (!apiKey) throw new Error("\u65B0\u5EFA\u901A\u9053\u5FC5\u987B\u586B\u5199 API Key");
|
|
62346
|
+
const newId = `chan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
|
|
62347
|
+
const newChannel = {
|
|
62348
|
+
id: newId,
|
|
62349
|
+
name,
|
|
62350
|
+
baseUrl,
|
|
62351
|
+
apiKey,
|
|
62352
|
+
...input.remark && input.remark.trim() ? { remark: input.remark.trim() } : {},
|
|
62353
|
+
createdAt: now,
|
|
62354
|
+
updatedAt: now
|
|
62355
|
+
};
|
|
62356
|
+
data.channels.push(newChannel);
|
|
62357
|
+
if (data.channels.length === 1 && !data.activeChannelId) {
|
|
62358
|
+
data.activeChannelId = newChannel.id;
|
|
62359
|
+
}
|
|
62360
|
+
this.write(data);
|
|
62361
|
+
return newChannel;
|
|
62362
|
+
}
|
|
62363
|
+
/** 删除通道 */
|
|
62364
|
+
delete(id) {
|
|
62365
|
+
const data = this.readOrCreate();
|
|
62366
|
+
const filtered = data.channels.filter((c2) => c2.id !== id);
|
|
62367
|
+
if (filtered.length === data.channels.length) return;
|
|
62368
|
+
data.channels = filtered;
|
|
62369
|
+
if (data.activeChannelId === id) {
|
|
62370
|
+
data.activeChannelId = data.channels.length > 0 ? data.channels[0].id : null;
|
|
62371
|
+
}
|
|
62372
|
+
this.write(data);
|
|
62373
|
+
}
|
|
62374
|
+
/** 设置当前激活通道(id 为 null 表示停用所有通道) */
|
|
62375
|
+
setActive(id) {
|
|
62376
|
+
const data = this.readOrCreate();
|
|
62377
|
+
if (id === null) {
|
|
62378
|
+
data.activeChannelId = null;
|
|
62379
|
+
this.write(data);
|
|
62380
|
+
return null;
|
|
62381
|
+
}
|
|
62382
|
+
const target = data.channels.find((c2) => c2.id === id);
|
|
62383
|
+
if (!target) throw new Error(`\u901A\u9053 ${id} \u4E0D\u5B58\u5728`);
|
|
62384
|
+
data.activeChannelId = id;
|
|
62385
|
+
this.write(data);
|
|
62386
|
+
return target;
|
|
62387
|
+
}
|
|
62388
|
+
readOrCreate() {
|
|
62389
|
+
if (import_node_fs35.default.existsSync(this.filePath)) {
|
|
62390
|
+
try {
|
|
62391
|
+
const raw = JSON.parse(import_node_fs35.default.readFileSync(this.filePath, "utf8"));
|
|
62392
|
+
if (raw && Array.isArray(raw.channels)) {
|
|
62393
|
+
return {
|
|
62394
|
+
activeChannelId: typeof raw.activeChannelId === "string" ? raw.activeChannelId : null,
|
|
62395
|
+
channels: raw.channels
|
|
62396
|
+
};
|
|
62397
|
+
}
|
|
62398
|
+
} catch {
|
|
62399
|
+
}
|
|
62400
|
+
}
|
|
62401
|
+
const migrated = this.tryMigrateFromCodexConfig();
|
|
62402
|
+
const initial = migrated ?? {
|
|
62403
|
+
activeChannelId: null,
|
|
62404
|
+
channels: []
|
|
62405
|
+
};
|
|
62406
|
+
this.write(initial);
|
|
62407
|
+
return initial;
|
|
62408
|
+
}
|
|
62409
|
+
tryMigrateFromCodexConfig() {
|
|
62410
|
+
try {
|
|
62411
|
+
const configPath = import_node_path40.default.join(this.codexHome, "config.toml");
|
|
62412
|
+
if (!import_node_fs35.default.existsSync(configPath)) return null;
|
|
62413
|
+
const content = import_node_fs35.default.readFileSync(configPath, "utf8");
|
|
62414
|
+
if (!content.includes('model_provider = "cliproxyapi"')) return null;
|
|
62415
|
+
const section = providerSection(content);
|
|
62416
|
+
if (!section) return null;
|
|
62417
|
+
const urlMatch = /^\s*base_url\s*=\s*["']([^"']+)["']/m.exec(section);
|
|
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 id = "default-pool";
|
|
62424
|
+
const channel = {
|
|
62425
|
+
id,
|
|
62426
|
+
name: "\u9ED8\u8BA4\u56E2\u961F\u53F7\u6C60",
|
|
62427
|
+
baseUrl: normalizeEngineBaseUrl(urlMatch[1]),
|
|
62428
|
+
apiKey: key,
|
|
62429
|
+
remark: "\u4ECE\u672C\u673A\u5DF2\u63A5\u5165\u7684\u53F7\u6C60\u914D\u7F6E\u81EA\u52A8\u8FC1\u79FB",
|
|
62430
|
+
createdAt: Date.now(),
|
|
62431
|
+
updatedAt: Date.now()
|
|
62432
|
+
};
|
|
62433
|
+
return {
|
|
62434
|
+
activeChannelId: id,
|
|
62435
|
+
channels: [channel]
|
|
62436
|
+
};
|
|
62437
|
+
}
|
|
62438
|
+
} catch {
|
|
62439
|
+
}
|
|
62440
|
+
return null;
|
|
62441
|
+
}
|
|
62442
|
+
write(data) {
|
|
62443
|
+
const dir = import_node_path40.default.dirname(this.filePath);
|
|
62444
|
+
import_node_fs35.default.mkdirSync(dir, { recursive: true });
|
|
62445
|
+
const tmp = `${this.filePath}.tmp.${Date.now()}`;
|
|
62446
|
+
import_node_fs35.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
62447
|
+
import_node_fs35.default.renameSync(tmp, this.filePath);
|
|
62448
|
+
}
|
|
62449
|
+
};
|
|
62450
|
+
|
|
62169
62451
|
// src/deploy/local-probe.ts
|
|
62170
62452
|
function pickVersion(s2) {
|
|
62171
62453
|
return /(\d+)\.(\d+)(?:\.(\d+))?/.exec(s2)?.[0];
|
|
@@ -62214,18 +62496,18 @@ async function probeLocalVersion(exec, pkg) {
|
|
|
62214
62496
|
|
|
62215
62497
|
// src/tools/shell-path.ts
|
|
62216
62498
|
var import_node_child_process10 = require("child_process");
|
|
62217
|
-
var
|
|
62499
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
62218
62500
|
function refreshPathFromLoginShell() {
|
|
62219
62501
|
if (process.platform === "win32") return;
|
|
62220
|
-
const shell = process.env.SHELL ??
|
|
62502
|
+
const shell = process.env.SHELL ?? import_node_os13.default.userInfo().shell ?? "/bin/zsh";
|
|
62221
62503
|
try {
|
|
62222
62504
|
const out = (0, import_node_child_process10.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
|
|
62223
62505
|
encoding: "utf8",
|
|
62224
62506
|
timeout: 3e3,
|
|
62225
62507
|
stdio: ["ignore", "pipe", "ignore"]
|
|
62226
62508
|
});
|
|
62227
|
-
const
|
|
62228
|
-
if (
|
|
62509
|
+
const path105 = out.trim();
|
|
62510
|
+
if (path105) process.env.PATH = path105;
|
|
62229
62511
|
} catch {
|
|
62230
62512
|
}
|
|
62231
62513
|
}
|
|
@@ -62763,15 +63045,15 @@ async function refreshTunnelUrlOnStartup(deps) {
|
|
|
62763
63045
|
}
|
|
62764
63046
|
|
|
62765
63047
|
// src/lark-bot-connector/binding-store.ts
|
|
62766
|
-
var
|
|
62767
|
-
var
|
|
63048
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
63049
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
62768
63050
|
function createLarkBotBindingStore(personaRoot) {
|
|
62769
|
-
const filePath = (personaId2) =>
|
|
63051
|
+
const filePath = (personaId2) => import_node_path41.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
|
|
62770
63052
|
const read = (personaId2) => {
|
|
62771
63053
|
const file = filePath(personaId2);
|
|
62772
|
-
if (!
|
|
63054
|
+
if (!import_node_fs36.default.existsSync(file)) return null;
|
|
62773
63055
|
try {
|
|
62774
|
-
const raw = JSON.parse(
|
|
63056
|
+
const raw = JSON.parse(import_node_fs36.default.readFileSync(file, "utf8"));
|
|
62775
63057
|
if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
|
|
62776
63058
|
return raw;
|
|
62777
63059
|
} catch {
|
|
@@ -62780,16 +63062,16 @@ function createLarkBotBindingStore(personaRoot) {
|
|
|
62780
63062
|
};
|
|
62781
63063
|
const write = (personaId2, meta) => {
|
|
62782
63064
|
const file = filePath(personaId2);
|
|
62783
|
-
|
|
63065
|
+
import_node_fs36.default.mkdirSync(import_node_path41.default.dirname(file), { recursive: true });
|
|
62784
63066
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
62785
|
-
|
|
62786
|
-
|
|
63067
|
+
import_node_fs36.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
|
|
63068
|
+
import_node_fs36.default.renameSync(tmp, file);
|
|
62787
63069
|
};
|
|
62788
63070
|
return {
|
|
62789
63071
|
read,
|
|
62790
63072
|
write,
|
|
62791
63073
|
remove(personaId2) {
|
|
62792
|
-
|
|
63074
|
+
import_node_fs36.default.rmSync(filePath(personaId2), { force: true });
|
|
62793
63075
|
},
|
|
62794
63076
|
addRemovedChat(personaId2, chatId) {
|
|
62795
63077
|
const meta = read(personaId2);
|
|
@@ -62941,8 +63223,8 @@ function createLarkBotCloudClient(opts) {
|
|
|
62941
63223
|
}
|
|
62942
63224
|
|
|
62943
63225
|
// src/lark-bot-connector/chat-router.ts
|
|
62944
|
-
var
|
|
62945
|
-
var
|
|
63226
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
63227
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
62946
63228
|
init_protocol();
|
|
62947
63229
|
var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
|
|
62948
63230
|
var LOCAL_TURN_RETRIES = 2;
|
|
@@ -63020,9 +63302,9 @@ function createLarkChatRouter(deps) {
|
|
|
63020
63302
|
continue;
|
|
63021
63303
|
}
|
|
63022
63304
|
const dir = deps.mediaRootFor(env.chatId);
|
|
63023
|
-
|
|
63024
|
-
const p3 =
|
|
63025
|
-
|
|
63305
|
+
import_node_fs37.default.mkdirSync(dir, { recursive: true });
|
|
63306
|
+
const p3 = import_node_path42.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
|
|
63307
|
+
import_node_fs37.default.writeFileSync(p3, r2.data);
|
|
63026
63308
|
lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
63027
63309
|
} catch (err) {
|
|
63028
63310
|
deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
|
|
@@ -63043,9 +63325,9 @@ function createLarkChatRouter(deps) {
|
|
|
63043
63325
|
continue;
|
|
63044
63326
|
}
|
|
63045
63327
|
const dir = deps.mediaRootFor(env.chatId);
|
|
63046
|
-
|
|
63047
|
-
const p3 =
|
|
63048
|
-
|
|
63328
|
+
import_node_fs37.default.mkdirSync(dir, { recursive: true });
|
|
63329
|
+
const p3 = import_node_path42.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
|
|
63330
|
+
import_node_fs37.default.writeFileSync(p3, r2.data);
|
|
63049
63331
|
lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
63050
63332
|
} catch (err) {
|
|
63051
63333
|
deps.logger?.warn(`larkBot file fetch failed ${f2.key}: ${err.message}`);
|
|
@@ -64241,7 +64523,7 @@ function openHttpLineStream(opts) {
|
|
|
64241
64523
|
init_protocol();
|
|
64242
64524
|
|
|
64243
64525
|
// src/tools/codex-cloud-session.ts
|
|
64244
|
-
var
|
|
64526
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
64245
64527
|
function cloudThreadParams(ctx, paths) {
|
|
64246
64528
|
const { model: _model, ...base } = threadStartParams(ctx);
|
|
64247
64529
|
const developerInstructions = [ctx.extraSystemPrompt, workDirPrompt(paths.workDir, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
|
|
@@ -64298,7 +64580,7 @@ function cloudImageInput(deps) {
|
|
|
64298
64580
|
const mime = lookupMime(p3);
|
|
64299
64581
|
if (!mime.startsWith("image/")) return null;
|
|
64300
64582
|
try {
|
|
64301
|
-
const bytes = (deps.readFile ??
|
|
64583
|
+
const bytes = (deps.readFile ?? import_node_fs38.default.readFileSync)(p3);
|
|
64302
64584
|
return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
|
|
64303
64585
|
} catch (e) {
|
|
64304
64586
|
deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
|
|
@@ -64432,7 +64714,7 @@ init_protocol();
|
|
|
64432
64714
|
|
|
64433
64715
|
// src/tools/pi.ts
|
|
64434
64716
|
var import_node_child_process12 = require("child_process");
|
|
64435
|
-
var
|
|
64717
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
64436
64718
|
init_protocol();
|
|
64437
64719
|
|
|
64438
64720
|
// src/tools/pi-rpc-client.ts
|
|
@@ -64533,8 +64815,8 @@ var PiRpcClient = class {
|
|
|
64533
64815
|
// src/tools/pi-session.ts
|
|
64534
64816
|
var import_node_child_process11 = require("child_process");
|
|
64535
64817
|
var import_node_crypto12 = require("crypto");
|
|
64536
|
-
var
|
|
64537
|
-
var
|
|
64818
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
64819
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
64538
64820
|
|
|
64539
64821
|
// src/tools/pi-events.ts
|
|
64540
64822
|
init_protocol();
|
|
@@ -64806,8 +65088,8 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
|
|
|
64806
65088
|
function createPiSession(ctx, sink, deps = {}) {
|
|
64807
65089
|
const cmd = process.env.PI_BIN ?? "pi";
|
|
64808
65090
|
const sessionId = ctx.toolSessionId ?? (0, import_node_crypto12.randomUUID)();
|
|
64809
|
-
const skillsDir =
|
|
64810
|
-
const exists = deps.skillsDirExists ?? ((d2) =>
|
|
65091
|
+
const skillsDir = import_node_path43.default.join(ctx.cwd, ".claude", "skills");
|
|
65092
|
+
const exists = deps.skillsDirExists ?? ((d2) => import_node_fs39.default.existsSync(d2));
|
|
64811
65093
|
const args = buildPiArgs(ctx, {
|
|
64812
65094
|
sessionId,
|
|
64813
65095
|
skillsDir: exists(skillsDir) ? skillsDir : void 0,
|
|
@@ -64869,10 +65151,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
|
|
|
64869
65151
|
};
|
|
64870
65152
|
var PI_FULL_ACCESS = { id: "never", label: "Full Access", description: "pi \u65E0\u5BA1\u6279\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
|
|
64871
65153
|
async function probePi(env = process.env) {
|
|
64872
|
-
if (env.PI_BIN &&
|
|
65154
|
+
if (env.PI_BIN && import_node_fs40.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
|
|
64873
65155
|
try {
|
|
64874
65156
|
const out = (0, import_node_child_process12.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
|
|
64875
|
-
if (out &&
|
|
65157
|
+
if (out && import_node_fs40.default.existsSync(out)) return { available: true, path: out };
|
|
64876
65158
|
} catch {
|
|
64877
65159
|
}
|
|
64878
65160
|
return { available: false };
|
|
@@ -65159,7 +65441,7 @@ var CloudPiAdapter = class {
|
|
|
65159
65441
|
init_protocol();
|
|
65160
65442
|
|
|
65161
65443
|
// src/tools/codex-skills.ts
|
|
65162
|
-
var
|
|
65444
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
65163
65445
|
function str4(v3) {
|
|
65164
65446
|
return typeof v3 === "string" ? v3 : void 0;
|
|
65165
65447
|
}
|
|
@@ -65174,13 +65456,13 @@ function mapSkillsListResponse(res) {
|
|
|
65174
65456
|
const r2 = s2 ?? {};
|
|
65175
65457
|
const name = str4(r2.name);
|
|
65176
65458
|
if (!name) continue;
|
|
65177
|
-
const
|
|
65459
|
+
const path105 = str4(r2.path);
|
|
65178
65460
|
const description = str4(r2.description);
|
|
65179
65461
|
const isPlugin = name.includes(":");
|
|
65180
65462
|
out.push({
|
|
65181
65463
|
name,
|
|
65182
65464
|
source: isPlugin ? "plugin" : "project",
|
|
65183
|
-
...
|
|
65465
|
+
...path105 ? { path: path105 } : {},
|
|
65184
65466
|
...description ? { description } : {},
|
|
65185
65467
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
65186
65468
|
});
|
|
@@ -65196,7 +65478,7 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
65196
65478
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
65197
65479
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
65198
65480
|
beforeRequest: (client) => {
|
|
65199
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
65481
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path44.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
65200
65482
|
}
|
|
65201
65483
|
});
|
|
65202
65484
|
return mapSkillsListResponse(res);
|
|
@@ -65270,23 +65552,23 @@ function rec4(v3) {
|
|
|
65270
65552
|
}
|
|
65271
65553
|
|
|
65272
65554
|
// src/workspace/browser.ts
|
|
65273
|
-
var
|
|
65274
|
-
var
|
|
65275
|
-
var
|
|
65555
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
65556
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
65557
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
65276
65558
|
init_protocol();
|
|
65277
65559
|
var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
|
|
65278
65560
|
function resolveInsideCwd(cwd, subpath) {
|
|
65279
|
-
const absCwd =
|
|
65280
|
-
const joined =
|
|
65281
|
-
const rel =
|
|
65282
|
-
if (rel.startsWith("..") ||
|
|
65561
|
+
const absCwd = import_node_path45.default.resolve(cwd);
|
|
65562
|
+
const joined = import_node_path45.default.resolve(absCwd, subpath ?? ".");
|
|
65563
|
+
const rel = import_node_path45.default.relative(absCwd, joined);
|
|
65564
|
+
if (rel.startsWith("..") || import_node_path45.default.isAbsolute(rel)) {
|
|
65283
65565
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
65284
65566
|
}
|
|
65285
65567
|
return joined;
|
|
65286
65568
|
}
|
|
65287
65569
|
function ensureCwd(cwd) {
|
|
65288
65570
|
try {
|
|
65289
|
-
const stat =
|
|
65571
|
+
const stat = import_node_fs41.default.statSync(cwd);
|
|
65290
65572
|
if (!stat.isDirectory()) {
|
|
65291
65573
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
65292
65574
|
}
|
|
@@ -65297,10 +65579,10 @@ function ensureCwd(cwd) {
|
|
|
65297
65579
|
}
|
|
65298
65580
|
var WorkspaceBrowser = class {
|
|
65299
65581
|
list(args) {
|
|
65300
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
65582
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os14.default.homedir();
|
|
65301
65583
|
ensureCwd(cwd);
|
|
65302
65584
|
const full = resolveInsideCwd(cwd, args.path);
|
|
65303
|
-
const dirents =
|
|
65585
|
+
const dirents = import_node_fs41.default.readdirSync(full, { withFileTypes: true });
|
|
65304
65586
|
const entries = [];
|
|
65305
65587
|
for (const d2 of dirents) {
|
|
65306
65588
|
if (!args.showHidden && d2.name.startsWith(".")) continue;
|
|
@@ -65310,7 +65592,7 @@ var WorkspaceBrowser = class {
|
|
|
65310
65592
|
mtime: ""
|
|
65311
65593
|
};
|
|
65312
65594
|
try {
|
|
65313
|
-
const st2 =
|
|
65595
|
+
const st2 = import_node_fs41.default.statSync(import_node_path45.default.join(full, d2.name));
|
|
65314
65596
|
entry.mtime = new Date(st2.mtimeMs).toISOString();
|
|
65315
65597
|
if (d2.isFile()) entry.size = st2.size;
|
|
65316
65598
|
} catch {
|
|
@@ -65326,14 +65608,14 @@ var WorkspaceBrowser = class {
|
|
|
65326
65608
|
read(args) {
|
|
65327
65609
|
ensureCwd(args.cwd);
|
|
65328
65610
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
65329
|
-
const st2 =
|
|
65611
|
+
const st2 = import_node_fs41.default.statSync(full);
|
|
65330
65612
|
if (!st2.isFile()) {
|
|
65331
65613
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
65332
65614
|
}
|
|
65333
65615
|
if (st2.size > MAX_FILE_BYTES2) {
|
|
65334
65616
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
|
|
65335
65617
|
}
|
|
65336
|
-
const buf =
|
|
65618
|
+
const buf = import_node_fs41.default.readFileSync(full);
|
|
65337
65619
|
const isBinary = buf.includes(0);
|
|
65338
65620
|
if (isBinary) {
|
|
65339
65621
|
return {
|
|
@@ -65355,20 +65637,20 @@ var WorkspaceBrowser = class {
|
|
|
65355
65637
|
};
|
|
65356
65638
|
|
|
65357
65639
|
// src/skills/agents-scanner.ts
|
|
65358
|
-
var
|
|
65359
|
-
var
|
|
65360
|
-
var
|
|
65640
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
65641
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
65642
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
65361
65643
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
65362
65644
|
function isDirLikeSync2(p3) {
|
|
65363
65645
|
try {
|
|
65364
|
-
return
|
|
65646
|
+
return import_node_fs42.default.statSync(p3).isDirectory();
|
|
65365
65647
|
} catch {
|
|
65366
65648
|
return false;
|
|
65367
65649
|
}
|
|
65368
65650
|
}
|
|
65369
65651
|
function fileExistsSync(p3) {
|
|
65370
65652
|
try {
|
|
65371
|
-
return
|
|
65653
|
+
return import_node_fs42.default.statSync(p3).isFile();
|
|
65372
65654
|
} catch {
|
|
65373
65655
|
return false;
|
|
65374
65656
|
}
|
|
@@ -65376,7 +65658,7 @@ function fileExistsSync(p3) {
|
|
|
65376
65658
|
function parseAgentFile(filePath) {
|
|
65377
65659
|
let content;
|
|
65378
65660
|
try {
|
|
65379
|
-
content =
|
|
65661
|
+
content = import_node_fs42.default.readFileSync(filePath, "utf8");
|
|
65380
65662
|
} catch {
|
|
65381
65663
|
return {};
|
|
65382
65664
|
}
|
|
@@ -65389,16 +65671,16 @@ function parseAgentFile(filePath) {
|
|
|
65389
65671
|
function scanAgentsDir(dir, source, seen, out) {
|
|
65390
65672
|
let entries;
|
|
65391
65673
|
try {
|
|
65392
|
-
entries =
|
|
65674
|
+
entries = import_node_fs42.default.readdirSync(dir, { withFileTypes: true });
|
|
65393
65675
|
} catch {
|
|
65394
65676
|
return;
|
|
65395
65677
|
}
|
|
65396
65678
|
for (const ent of entries) {
|
|
65397
65679
|
if (!ent.name.endsWith(".md")) continue;
|
|
65398
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
65680
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path46.default.join(dir, ent.name)))) {
|
|
65399
65681
|
continue;
|
|
65400
65682
|
}
|
|
65401
|
-
const filePath =
|
|
65683
|
+
const filePath = import_node_path46.default.join(dir, ent.name);
|
|
65402
65684
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
65403
65685
|
if (seen.has(baseName)) continue;
|
|
65404
65686
|
seen.add(baseName);
|
|
@@ -65416,12 +65698,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
65416
65698
|
function walk2(dir, namespaces) {
|
|
65417
65699
|
let entries;
|
|
65418
65700
|
try {
|
|
65419
|
-
entries =
|
|
65701
|
+
entries = import_node_fs42.default.readdirSync(dir, { withFileTypes: true });
|
|
65420
65702
|
} catch {
|
|
65421
65703
|
return;
|
|
65422
65704
|
}
|
|
65423
65705
|
for (const ent of entries) {
|
|
65424
|
-
const childPath =
|
|
65706
|
+
const childPath = import_node_path46.default.join(dir, ent.name);
|
|
65425
65707
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
65426
65708
|
walk2(childPath, [...namespaces, ent.name]);
|
|
65427
65709
|
continue;
|
|
@@ -65446,13 +65728,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
65446
65728
|
walk2(root, []);
|
|
65447
65729
|
}
|
|
65448
65730
|
function readInstalledPlugins2(home) {
|
|
65449
|
-
const pluginsDir =
|
|
65450
|
-
const v22 =
|
|
65451
|
-
const v1 =
|
|
65731
|
+
const pluginsDir = import_node_path46.default.join(home, ".claude", "plugins");
|
|
65732
|
+
const v22 = import_node_path46.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
65733
|
+
const v1 = import_node_path46.default.join(pluginsDir, "installed_plugins.json");
|
|
65452
65734
|
let raw = null;
|
|
65453
65735
|
for (const candidate of [v22, v1]) {
|
|
65454
65736
|
try {
|
|
65455
|
-
raw =
|
|
65737
|
+
raw = import_node_fs42.default.readFileSync(candidate, "utf8");
|
|
65456
65738
|
break;
|
|
65457
65739
|
} catch {
|
|
65458
65740
|
}
|
|
@@ -65477,19 +65759,19 @@ function readInstalledPlugins2(home) {
|
|
|
65477
65759
|
return out;
|
|
65478
65760
|
}
|
|
65479
65761
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
65480
|
-
let cur =
|
|
65481
|
-
const fsRoot =
|
|
65762
|
+
let cur = import_node_path46.default.resolve(startCwd);
|
|
65763
|
+
const fsRoot = import_node_path46.default.parse(cur).root;
|
|
65482
65764
|
while (true) {
|
|
65483
|
-
scanAgentsDir(
|
|
65765
|
+
scanAgentsDir(import_node_path46.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
65484
65766
|
let hasGit = false;
|
|
65485
65767
|
try {
|
|
65486
|
-
hasGit =
|
|
65768
|
+
hasGit = import_node_fs42.default.existsSync(import_node_path46.default.join(cur, ".git"));
|
|
65487
65769
|
} catch {
|
|
65488
65770
|
}
|
|
65489
65771
|
if (hasGit) return;
|
|
65490
65772
|
if (cur === home) return;
|
|
65491
65773
|
if (cur === fsRoot) return;
|
|
65492
|
-
const parent =
|
|
65774
|
+
const parent = import_node_path46.default.dirname(cur);
|
|
65493
65775
|
if (parent === cur) return;
|
|
65494
65776
|
cur = parent;
|
|
65495
65777
|
}
|
|
@@ -65499,7 +65781,7 @@ var AgentsScanner = class {
|
|
|
65499
65781
|
extraPluginRoots;
|
|
65500
65782
|
policyDir;
|
|
65501
65783
|
constructor(opts = {}) {
|
|
65502
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
65784
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os15.default.homedir();
|
|
65503
65785
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
65504
65786
|
if (opts.policyDir !== void 0) {
|
|
65505
65787
|
this.policyDir = opts.policyDir;
|
|
@@ -65524,7 +65806,7 @@ var AgentsScanner = class {
|
|
|
65524
65806
|
}
|
|
65525
65807
|
const fsBlock = [];
|
|
65526
65808
|
scanAgentsDir(
|
|
65527
|
-
|
|
65809
|
+
import_node_path46.default.join(this.home, ".claude", "agents"),
|
|
65528
65810
|
"global",
|
|
65529
65811
|
seen,
|
|
65530
65812
|
fsBlock
|
|
@@ -65538,7 +65820,7 @@ var AgentsScanner = class {
|
|
|
65538
65820
|
...this.extraPluginRoots
|
|
65539
65821
|
];
|
|
65540
65822
|
for (const { name, root } of plugins) {
|
|
65541
|
-
const agentsRoot =
|
|
65823
|
+
const agentsRoot = import_node_path46.default.join(root, "agents");
|
|
65542
65824
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
65543
65825
|
}
|
|
65544
65826
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -65546,28 +65828,28 @@ var AgentsScanner = class {
|
|
|
65546
65828
|
};
|
|
65547
65829
|
|
|
65548
65830
|
// src/observer/session-observer.ts
|
|
65549
|
-
var
|
|
65550
|
-
var
|
|
65551
|
-
var
|
|
65831
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
65832
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
65833
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
65552
65834
|
init_claude_history();
|
|
65553
65835
|
|
|
65554
65836
|
// src/observer/subagent-meta-observer.ts
|
|
65555
|
-
var
|
|
65556
|
-
var
|
|
65557
|
-
var
|
|
65837
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
65838
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
65839
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
65558
65840
|
init_claude_history();
|
|
65559
65841
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
65560
65842
|
var SubagentMetaObserver = class {
|
|
65561
65843
|
constructor(opts) {
|
|
65562
65844
|
this.opts = opts;
|
|
65563
|
-
this.home = opts.home ??
|
|
65845
|
+
this.home = opts.home ?? import_node_os16.default.homedir();
|
|
65564
65846
|
}
|
|
65565
65847
|
opts;
|
|
65566
65848
|
home;
|
|
65567
65849
|
watches = /* @__PURE__ */ new Map();
|
|
65568
65850
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
65569
65851
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
65570
|
-
return
|
|
65852
|
+
return import_node_path47.default.join(
|
|
65571
65853
|
this.home,
|
|
65572
65854
|
".claude",
|
|
65573
65855
|
"projects",
|
|
@@ -65597,7 +65879,7 @@ var SubagentMetaObserver = class {
|
|
|
65597
65879
|
attachWatcher(w3) {
|
|
65598
65880
|
if (w3.watcher) return;
|
|
65599
65881
|
try {
|
|
65600
|
-
w3.watcher =
|
|
65882
|
+
w3.watcher = import_node_fs43.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
|
|
65601
65883
|
if (!name) return;
|
|
65602
65884
|
const m3 = META_RE.exec(String(name));
|
|
65603
65885
|
if (!m3) return;
|
|
@@ -65609,7 +65891,7 @@ var SubagentMetaObserver = class {
|
|
|
65609
65891
|
scan(w3) {
|
|
65610
65892
|
let entries;
|
|
65611
65893
|
try {
|
|
65612
|
-
entries =
|
|
65894
|
+
entries = import_node_fs43.default.readdirSync(w3.dirPath);
|
|
65613
65895
|
} catch {
|
|
65614
65896
|
return;
|
|
65615
65897
|
}
|
|
@@ -65623,10 +65905,10 @@ var SubagentMetaObserver = class {
|
|
|
65623
65905
|
if (!m3) return;
|
|
65624
65906
|
const agentId = m3[1];
|
|
65625
65907
|
if (w3.emitted.has(agentId)) return;
|
|
65626
|
-
const file =
|
|
65908
|
+
const file = import_node_path47.default.join(w3.dirPath, name);
|
|
65627
65909
|
let raw;
|
|
65628
65910
|
try {
|
|
65629
|
-
raw =
|
|
65911
|
+
raw = import_node_fs43.default.readFileSync(file, "utf8");
|
|
65630
65912
|
} catch {
|
|
65631
65913
|
return;
|
|
65632
65914
|
}
|
|
@@ -65671,7 +65953,7 @@ var SubagentMetaObserver = class {
|
|
|
65671
65953
|
var SessionObserver = class {
|
|
65672
65954
|
constructor(opts) {
|
|
65673
65955
|
this.opts = opts;
|
|
65674
|
-
this.home = opts.home ??
|
|
65956
|
+
this.home = opts.home ?? import_node_os17.default.homedir();
|
|
65675
65957
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
65676
65958
|
}
|
|
65677
65959
|
opts;
|
|
@@ -65683,14 +65965,14 @@ var SessionObserver = class {
|
|
|
65683
65965
|
metaObserver;
|
|
65684
65966
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
65685
65967
|
if (override) return override;
|
|
65686
|
-
return
|
|
65968
|
+
return import_node_path48.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
65687
65969
|
}
|
|
65688
65970
|
start(args) {
|
|
65689
65971
|
this.stop(args.sessionId);
|
|
65690
65972
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
65691
65973
|
let size = 0;
|
|
65692
65974
|
try {
|
|
65693
|
-
size =
|
|
65975
|
+
size = import_node_fs44.default.statSync(filePath).size;
|
|
65694
65976
|
} catch {
|
|
65695
65977
|
}
|
|
65696
65978
|
const w3 = {
|
|
@@ -65703,16 +65985,16 @@ var SessionObserver = class {
|
|
|
65703
65985
|
adapter: args.adapter,
|
|
65704
65986
|
prevIsRejectSentinel: false,
|
|
65705
65987
|
toolSessionId: args.toolSessionId,
|
|
65706
|
-
sawFile:
|
|
65988
|
+
sawFile: import_node_fs44.default.existsSync(filePath),
|
|
65707
65989
|
lastRelocateScanMs: 0,
|
|
65708
65990
|
pendingCwdDerive: false,
|
|
65709
65991
|
lastDeriveMs: 0
|
|
65710
65992
|
};
|
|
65711
65993
|
try {
|
|
65712
|
-
|
|
65994
|
+
import_node_fs44.default.mkdirSync(import_node_path48.default.dirname(filePath), { recursive: true });
|
|
65713
65995
|
} catch {
|
|
65714
65996
|
}
|
|
65715
|
-
w3.watcher =
|
|
65997
|
+
w3.watcher = import_node_fs44.default.watch(import_node_path48.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
65716
65998
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
65717
65999
|
this.poll(w3);
|
|
65718
66000
|
});
|
|
@@ -65735,7 +66017,7 @@ var SessionObserver = class {
|
|
|
65735
66017
|
// 异常静默吞,不阻塞 watcher 启动
|
|
65736
66018
|
hydrateMetaTail(w3, maxLines = 200) {
|
|
65737
66019
|
try {
|
|
65738
|
-
const raw =
|
|
66020
|
+
const raw = import_node_fs44.default.readFileSync(w3.filePath, "utf8");
|
|
65739
66021
|
if (!raw) return;
|
|
65740
66022
|
const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
|
|
65741
66023
|
if (allLines.length === 0) return;
|
|
@@ -65759,7 +66041,7 @@ var SessionObserver = class {
|
|
|
65759
66041
|
poll(w3) {
|
|
65760
66042
|
let size = 0;
|
|
65761
66043
|
try {
|
|
65762
|
-
size =
|
|
66044
|
+
size = import_node_fs44.default.statSync(w3.filePath).size;
|
|
65763
66045
|
} catch {
|
|
65764
66046
|
if (w3.sawFile) this.maybeRelocate(w3);
|
|
65765
66047
|
return;
|
|
@@ -65770,11 +66052,11 @@ var SessionObserver = class {
|
|
|
65770
66052
|
w3.buf = "";
|
|
65771
66053
|
}
|
|
65772
66054
|
if (size === w3.lastSize) return;
|
|
65773
|
-
const fd =
|
|
66055
|
+
const fd = import_node_fs44.default.openSync(w3.filePath, "r");
|
|
65774
66056
|
try {
|
|
65775
66057
|
const len = size - w3.lastSize;
|
|
65776
66058
|
const buf = Buffer.alloc(len);
|
|
65777
|
-
|
|
66059
|
+
import_node_fs44.default.readSync(fd, buf, 0, len, w3.lastSize);
|
|
65778
66060
|
w3.lastSize = size;
|
|
65779
66061
|
w3.buf += buf.toString("utf8");
|
|
65780
66062
|
let newlineIndex;
|
|
@@ -65797,7 +66079,7 @@ var SessionObserver = class {
|
|
|
65797
66079
|
}
|
|
65798
66080
|
}
|
|
65799
66081
|
} finally {
|
|
65800
|
-
|
|
66082
|
+
import_node_fs44.default.closeSync(fd);
|
|
65801
66083
|
}
|
|
65802
66084
|
if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
|
|
65803
66085
|
}
|
|
@@ -65809,7 +66091,7 @@ var SessionObserver = class {
|
|
|
65809
66091
|
const now = Date.now();
|
|
65810
66092
|
if (now - w3.lastRelocateScanMs < 1e3) return;
|
|
65811
66093
|
w3.lastRelocateScanMs = now;
|
|
65812
|
-
const projectsRoot =
|
|
66094
|
+
const projectsRoot = import_node_path48.default.join(this.home, ".claude", "projects");
|
|
65813
66095
|
const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
|
|
65814
66096
|
if (!found || found === w3.filePath) return;
|
|
65815
66097
|
try {
|
|
@@ -65818,7 +66100,7 @@ var SessionObserver = class {
|
|
|
65818
66100
|
}
|
|
65819
66101
|
w3.filePath = found;
|
|
65820
66102
|
try {
|
|
65821
|
-
w3.watcher =
|
|
66103
|
+
w3.watcher = import_node_fs44.default.watch(import_node_path48.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
65822
66104
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
65823
66105
|
this.poll(w3);
|
|
65824
66106
|
});
|
|
@@ -65940,9 +66222,9 @@ function listRegistered() {
|
|
|
65940
66222
|
// src/tools/title-generator.ts
|
|
65941
66223
|
var import_node_child_process13 = require("child_process");
|
|
65942
66224
|
init_protocol();
|
|
65943
|
-
var
|
|
65944
|
-
var
|
|
65945
|
-
var
|
|
66225
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
66226
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
66227
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
65946
66228
|
var TITLE_GEN_DIR_PREFIX = "clawd-title-";
|
|
65947
66229
|
var TITLE_MODEL_BY_TOOL = {
|
|
65948
66230
|
claude: "haiku",
|
|
@@ -66013,21 +66295,21 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
66013
66295
|
if (!text) return null;
|
|
66014
66296
|
let workDir;
|
|
66015
66297
|
try {
|
|
66016
|
-
workDir =
|
|
66298
|
+
workDir = import_node_fs45.default.mkdtempSync(import_node_path49.default.join(import_node_os18.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
|
|
66017
66299
|
} catch {
|
|
66018
66300
|
return null;
|
|
66019
66301
|
}
|
|
66020
66302
|
const cleanupWorkDir = () => {
|
|
66021
66303
|
try {
|
|
66022
|
-
|
|
66304
|
+
import_node_fs45.default.rmSync(workDir, { recursive: true, force: true });
|
|
66023
66305
|
} catch {
|
|
66024
66306
|
}
|
|
66025
66307
|
};
|
|
66026
|
-
const outFile =
|
|
66027
|
-
const schemaFile =
|
|
66308
|
+
const outFile = import_node_path49.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
|
|
66309
|
+
const schemaFile = import_node_path49.default.join(workDir, "title-schema.json");
|
|
66028
66310
|
if (isCodexFamily(tool)) {
|
|
66029
66311
|
try {
|
|
66030
|
-
|
|
66312
|
+
import_node_fs45.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
|
|
66031
66313
|
} catch {
|
|
66032
66314
|
cleanupWorkDir();
|
|
66033
66315
|
return null;
|
|
@@ -66077,7 +66359,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
66077
66359
|
if (tool === "claude") return finish(parseTitleJson(stdout));
|
|
66078
66360
|
let fileText = "";
|
|
66079
66361
|
try {
|
|
66080
|
-
fileText =
|
|
66362
|
+
fileText = import_node_fs45.default.readFileSync(outFile, "utf8");
|
|
66081
66363
|
} catch {
|
|
66082
66364
|
return finish(null);
|
|
66083
66365
|
}
|
|
@@ -66722,8 +67004,8 @@ async function authenticate(token, deps) {
|
|
|
66722
67004
|
}
|
|
66723
67005
|
|
|
66724
67006
|
// src/legacy-cleanup.ts
|
|
66725
|
-
var
|
|
66726
|
-
var
|
|
67007
|
+
var fs56 = __toESM(require("fs/promises"), 1);
|
|
67008
|
+
var path57 = __toESM(require("path"), 1);
|
|
66727
67009
|
var LEGACY_FILES = [
|
|
66728
67010
|
"personal-capability.json",
|
|
66729
67011
|
"received-capabilities.json",
|
|
@@ -66732,9 +67014,9 @@ var LEGACY_FILES = [
|
|
|
66732
67014
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
66733
67015
|
const removed = [];
|
|
66734
67016
|
for (const name of LEGACY_FILES) {
|
|
66735
|
-
const p3 =
|
|
67017
|
+
const p3 = path57.join(dataDir, name);
|
|
66736
67018
|
try {
|
|
66737
|
-
await
|
|
67019
|
+
await fs56.unlink(p3);
|
|
66738
67020
|
removed.push(name);
|
|
66739
67021
|
logger.debug("legacy capability file removed", { file: name });
|
|
66740
67022
|
} catch (err) {
|
|
@@ -66746,13 +67028,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
66746
67028
|
}
|
|
66747
67029
|
|
|
66748
67030
|
// src/inbox/inbox-store.ts
|
|
66749
|
-
var
|
|
66750
|
-
var
|
|
67031
|
+
var fs57 = __toESM(require("fs"), 1);
|
|
67032
|
+
var path58 = __toESM(require("path"), 1);
|
|
66751
67033
|
var INBOX_SUBDIR = "inbox";
|
|
66752
67034
|
var InboxStore = class {
|
|
66753
67035
|
constructor(dataDir) {
|
|
66754
67036
|
this.dataDir = dataDir;
|
|
66755
|
-
|
|
67037
|
+
fs57.mkdirSync(this.dirPath(), { recursive: true });
|
|
66756
67038
|
}
|
|
66757
67039
|
dataDir;
|
|
66758
67040
|
/**
|
|
@@ -66764,7 +67046,7 @@ var InboxStore = class {
|
|
|
66764
67046
|
const file = this.filePath(peerDeviceId);
|
|
66765
67047
|
let raw;
|
|
66766
67048
|
try {
|
|
66767
|
-
raw =
|
|
67049
|
+
raw = fs57.readFileSync(file, "utf8");
|
|
66768
67050
|
} catch (err) {
|
|
66769
67051
|
if (err?.code === "ENOENT") return [];
|
|
66770
67052
|
return [];
|
|
@@ -66780,7 +67062,7 @@ var InboxStore = class {
|
|
|
66780
67062
|
const dir = this.dirPath();
|
|
66781
67063
|
let entries;
|
|
66782
67064
|
try {
|
|
66783
|
-
entries =
|
|
67065
|
+
entries = fs57.readdirSync(dir);
|
|
66784
67066
|
} catch (err) {
|
|
66785
67067
|
if (err?.code === "ENOENT") return [];
|
|
66786
67068
|
return [];
|
|
@@ -66796,9 +67078,9 @@ var InboxStore = class {
|
|
|
66796
67078
|
if (existing.some((m3) => m3.id === message.id)) return;
|
|
66797
67079
|
const file = this.filePath(message.peerDeviceId);
|
|
66798
67080
|
const line = JSON.stringify(message) + "\n";
|
|
66799
|
-
|
|
67081
|
+
fs57.appendFileSync(file, line, { mode: 384 });
|
|
66800
67082
|
try {
|
|
66801
|
-
|
|
67083
|
+
fs57.chmodSync(file, 384);
|
|
66802
67084
|
} catch {
|
|
66803
67085
|
}
|
|
66804
67086
|
}
|
|
@@ -66828,7 +67110,7 @@ var InboxStore = class {
|
|
|
66828
67110
|
removeByPeerDeviceId(peerDeviceId) {
|
|
66829
67111
|
const file = this.filePath(peerDeviceId);
|
|
66830
67112
|
try {
|
|
66831
|
-
|
|
67113
|
+
fs57.unlinkSync(file);
|
|
66832
67114
|
} catch (err) {
|
|
66833
67115
|
if (err?.code === "ENOENT") return;
|
|
66834
67116
|
}
|
|
@@ -66837,18 +67119,18 @@ var InboxStore = class {
|
|
|
66837
67119
|
const file = this.filePath(peerDeviceId);
|
|
66838
67120
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
66839
67121
|
const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
66840
|
-
|
|
66841
|
-
|
|
67122
|
+
fs57.writeFileSync(tmp, content, { mode: 384 });
|
|
67123
|
+
fs57.renameSync(tmp, file);
|
|
66842
67124
|
try {
|
|
66843
|
-
|
|
67125
|
+
fs57.chmodSync(file, 384);
|
|
66844
67126
|
} catch {
|
|
66845
67127
|
}
|
|
66846
67128
|
}
|
|
66847
67129
|
dirPath() {
|
|
66848
|
-
return
|
|
67130
|
+
return path58.join(this.dataDir, INBOX_SUBDIR);
|
|
66849
67131
|
}
|
|
66850
67132
|
filePath(peerDeviceId) {
|
|
66851
|
-
return
|
|
67133
|
+
return path58.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
66852
67134
|
}
|
|
66853
67135
|
};
|
|
66854
67136
|
function parseAllLines(raw) {
|
|
@@ -66936,8 +67218,8 @@ var InboxManager = class {
|
|
|
66936
67218
|
};
|
|
66937
67219
|
|
|
66938
67220
|
// src/state/contact-store.ts
|
|
66939
|
-
var
|
|
66940
|
-
var
|
|
67221
|
+
var fs58 = __toESM(require("fs"), 1);
|
|
67222
|
+
var path59 = __toESM(require("path"), 1);
|
|
66941
67223
|
var FILE_NAME = "contacts.json";
|
|
66942
67224
|
var ContactStore = class {
|
|
66943
67225
|
constructor(dataDir) {
|
|
@@ -66947,10 +67229,10 @@ var ContactStore = class {
|
|
|
66947
67229
|
contacts = /* @__PURE__ */ new Map();
|
|
66948
67230
|
load() {
|
|
66949
67231
|
this.contacts.clear();
|
|
66950
|
-
const file =
|
|
67232
|
+
const file = path59.join(this.dataDir, FILE_NAME);
|
|
66951
67233
|
let raw;
|
|
66952
67234
|
try {
|
|
66953
|
-
raw =
|
|
67235
|
+
raw = fs58.readFileSync(file, "utf8");
|
|
66954
67236
|
} catch (err) {
|
|
66955
67237
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
66956
67238
|
return;
|
|
@@ -67031,20 +67313,20 @@ var ContactStore = class {
|
|
|
67031
67313
|
return true;
|
|
67032
67314
|
}
|
|
67033
67315
|
flush() {
|
|
67034
|
-
const file =
|
|
67316
|
+
const file = path59.join(this.dataDir, FILE_NAME);
|
|
67035
67317
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
67036
67318
|
const content = JSON.stringify(
|
|
67037
67319
|
{ contacts: Array.from(this.contacts.values()) },
|
|
67038
67320
|
null,
|
|
67039
67321
|
2
|
|
67040
67322
|
);
|
|
67041
|
-
|
|
67042
|
-
|
|
67043
|
-
|
|
67323
|
+
fs58.mkdirSync(this.dataDir, { recursive: true });
|
|
67324
|
+
fs58.writeFileSync(tmp, content, { mode: 384 });
|
|
67325
|
+
fs58.renameSync(tmp, file);
|
|
67044
67326
|
}
|
|
67045
67327
|
renameBak(file) {
|
|
67046
67328
|
try {
|
|
67047
|
-
|
|
67329
|
+
fs58.renameSync(file, `${file}.bak`);
|
|
67048
67330
|
} catch {
|
|
67049
67331
|
}
|
|
67050
67332
|
}
|
|
@@ -67152,61 +67434,61 @@ async function connectRemote(args) {
|
|
|
67152
67434
|
}
|
|
67153
67435
|
|
|
67154
67436
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
67155
|
-
var
|
|
67156
|
-
var
|
|
67437
|
+
var fs59 = __toESM(require("fs"), 1);
|
|
67438
|
+
var path60 = __toESM(require("path"), 1);
|
|
67157
67439
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
67158
67440
|
function migrateFlattenSessions(opts) {
|
|
67159
67441
|
const dataDir = opts.dataDir;
|
|
67160
67442
|
const now = opts.now ?? Date.now;
|
|
67161
|
-
const sessionsDir =
|
|
67162
|
-
const flagPath =
|
|
67443
|
+
const sessionsDir = path60.join(dataDir, "sessions");
|
|
67444
|
+
const flagPath = path60.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
67163
67445
|
if (existsSync3(flagPath)) {
|
|
67164
67446
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
67165
67447
|
}
|
|
67166
67448
|
let movedBare = 0;
|
|
67167
67449
|
let movedVmOwner = 0;
|
|
67168
67450
|
let archivedListener = 0;
|
|
67169
|
-
const defaultDir =
|
|
67451
|
+
const defaultDir = path60.join(sessionsDir, "default");
|
|
67170
67452
|
if (existsSync3(defaultDir)) {
|
|
67171
67453
|
for (const entry of readdirSafe(defaultDir)) {
|
|
67172
67454
|
if (!entry.endsWith(".json")) continue;
|
|
67173
|
-
const src =
|
|
67174
|
-
const dst =
|
|
67175
|
-
|
|
67455
|
+
const src = path60.join(defaultDir, entry);
|
|
67456
|
+
const dst = path60.join(sessionsDir, entry);
|
|
67457
|
+
fs59.renameSync(src, dst);
|
|
67176
67458
|
movedBare += 1;
|
|
67177
67459
|
}
|
|
67178
67460
|
rmdirIfEmpty(defaultDir);
|
|
67179
67461
|
}
|
|
67180
67462
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
67181
|
-
const personaDir =
|
|
67463
|
+
const personaDir = path60.join(sessionsDir, pid);
|
|
67182
67464
|
if (!isDir(personaDir)) continue;
|
|
67183
67465
|
if (pid === "default") continue;
|
|
67184
|
-
const ownerSrc =
|
|
67466
|
+
const ownerSrc = path60.join(personaDir, "owner");
|
|
67185
67467
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
67186
|
-
const ownerDst =
|
|
67187
|
-
|
|
67468
|
+
const ownerDst = path60.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
67469
|
+
fs59.mkdirSync(ownerDst, { recursive: true });
|
|
67188
67470
|
for (const file of readdirSafe(ownerSrc)) {
|
|
67189
67471
|
if (!file.endsWith(".json")) continue;
|
|
67190
|
-
|
|
67472
|
+
fs59.renameSync(path60.join(ownerSrc, file), path60.join(ownerDst, file));
|
|
67191
67473
|
movedVmOwner += 1;
|
|
67192
67474
|
}
|
|
67193
67475
|
rmdirIfEmpty(ownerSrc);
|
|
67194
67476
|
}
|
|
67195
|
-
const listenerSrc =
|
|
67477
|
+
const listenerSrc = path60.join(personaDir, "listener");
|
|
67196
67478
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
67197
|
-
const archiveDst =
|
|
67198
|
-
|
|
67479
|
+
const archiveDst = path60.join(dataDir, ".legacy", `listener-${pid}`);
|
|
67480
|
+
fs59.mkdirSync(archiveDst, { recursive: true });
|
|
67199
67481
|
for (const file of readdirSafe(listenerSrc)) {
|
|
67200
67482
|
if (!file.endsWith(".json")) continue;
|
|
67201
|
-
|
|
67483
|
+
fs59.renameSync(path60.join(listenerSrc, file), path60.join(archiveDst, file));
|
|
67202
67484
|
archivedListener += 1;
|
|
67203
67485
|
}
|
|
67204
67486
|
rmdirIfEmpty(listenerSrc);
|
|
67205
67487
|
}
|
|
67206
67488
|
rmdirIfEmpty(personaDir);
|
|
67207
67489
|
}
|
|
67208
|
-
|
|
67209
|
-
|
|
67490
|
+
fs59.mkdirSync(sessionsDir, { recursive: true });
|
|
67491
|
+
fs59.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
67210
67492
|
return {
|
|
67211
67493
|
skipped: false,
|
|
67212
67494
|
flagWritten: true,
|
|
@@ -67217,7 +67499,7 @@ function migrateFlattenSessions(opts) {
|
|
|
67217
67499
|
}
|
|
67218
67500
|
function existsSync3(p3) {
|
|
67219
67501
|
try {
|
|
67220
|
-
|
|
67502
|
+
fs59.statSync(p3);
|
|
67221
67503
|
return true;
|
|
67222
67504
|
} catch {
|
|
67223
67505
|
return false;
|
|
@@ -67225,62 +67507,62 @@ function existsSync3(p3) {
|
|
|
67225
67507
|
}
|
|
67226
67508
|
function isDir(p3) {
|
|
67227
67509
|
try {
|
|
67228
|
-
return
|
|
67510
|
+
return fs59.statSync(p3).isDirectory();
|
|
67229
67511
|
} catch {
|
|
67230
67512
|
return false;
|
|
67231
67513
|
}
|
|
67232
67514
|
}
|
|
67233
67515
|
function readdirSafe(p3) {
|
|
67234
67516
|
try {
|
|
67235
|
-
return
|
|
67517
|
+
return fs59.readdirSync(p3);
|
|
67236
67518
|
} catch {
|
|
67237
67519
|
return [];
|
|
67238
67520
|
}
|
|
67239
67521
|
}
|
|
67240
67522
|
function rmdirIfEmpty(p3) {
|
|
67241
67523
|
try {
|
|
67242
|
-
|
|
67524
|
+
fs59.rmdirSync(p3);
|
|
67243
67525
|
} catch {
|
|
67244
67526
|
}
|
|
67245
67527
|
}
|
|
67246
67528
|
|
|
67247
67529
|
// src/migrations/2026-08-18-drop-seeded-projects.ts
|
|
67248
|
-
var
|
|
67249
|
-
var
|
|
67530
|
+
var fs60 = __toESM(require("fs"), 1);
|
|
67531
|
+
var path61 = __toESM(require("path"), 1);
|
|
67250
67532
|
var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
|
|
67251
67533
|
function dropSeededProjects(opts) {
|
|
67252
|
-
|
|
67253
|
-
const flag =
|
|
67254
|
-
if (
|
|
67255
|
-
const file =
|
|
67534
|
+
fs60.mkdirSync(opts.dataDir, { recursive: true });
|
|
67535
|
+
const flag = path61.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
|
|
67536
|
+
if (fs60.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
|
|
67537
|
+
const file = path61.join(opts.dataDir, "projects.json");
|
|
67256
67538
|
let raw = null;
|
|
67257
67539
|
let dropped = 0;
|
|
67258
67540
|
try {
|
|
67259
|
-
raw =
|
|
67541
|
+
raw = fs60.readFileSync(file, "utf8");
|
|
67260
67542
|
dropped = JSON.parse(raw).projects?.length ?? 0;
|
|
67261
67543
|
} catch {
|
|
67262
67544
|
}
|
|
67263
67545
|
let backup = null;
|
|
67264
67546
|
if (raw != null && dropped > 0) {
|
|
67265
|
-
const dir =
|
|
67266
|
-
|
|
67267
|
-
backup =
|
|
67268
|
-
|
|
67547
|
+
const dir = path61.join(opts.dataDir, "backups");
|
|
67548
|
+
fs60.mkdirSync(dir, { recursive: true });
|
|
67549
|
+
backup = path61.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
|
|
67550
|
+
fs60.writeFileSync(backup, raw);
|
|
67269
67551
|
}
|
|
67270
67552
|
if (raw != null || dropped > 0) {
|
|
67271
|
-
|
|
67553
|
+
fs60.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
|
|
67272
67554
|
}
|
|
67273
|
-
|
|
67555
|
+
fs60.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
|
|
67274
67556
|
return { skipped: false, dropped, backup };
|
|
67275
67557
|
}
|
|
67276
67558
|
|
|
67277
67559
|
// src/transport/http-router.ts
|
|
67278
|
-
var
|
|
67279
|
-
var
|
|
67560
|
+
var import_node_fs47 = __toESM(require("fs"), 1);
|
|
67561
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
67280
67562
|
|
|
67281
67563
|
// src/attachment/upload.ts
|
|
67282
|
-
var
|
|
67283
|
-
var
|
|
67564
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
67565
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
67284
67566
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
67285
67567
|
var import_promises8 = require("stream/promises");
|
|
67286
67568
|
var UploadError = class extends Error {
|
|
@@ -67292,22 +67574,22 @@ var UploadError = class extends Error {
|
|
|
67292
67574
|
code;
|
|
67293
67575
|
};
|
|
67294
67576
|
function assertValidFileName(fileName) {
|
|
67295
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
67577
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path50.default.basename(fileName)) {
|
|
67296
67578
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
67297
67579
|
}
|
|
67298
67580
|
}
|
|
67299
67581
|
var HASH_PREFIX_LEN = 16;
|
|
67300
67582
|
async function writeUploadedAttachment(args) {
|
|
67301
67583
|
assertValidFileName(args.fileName);
|
|
67302
|
-
const attachmentsRoot =
|
|
67584
|
+
const attachmentsRoot = import_node_path50.default.join(args.baseDir, ".attachments");
|
|
67303
67585
|
try {
|
|
67304
|
-
|
|
67586
|
+
import_node_fs46.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
67305
67587
|
} catch (err) {
|
|
67306
67588
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
67307
67589
|
}
|
|
67308
67590
|
const hasher = import_node_crypto15.default.createHash("sha256");
|
|
67309
67591
|
let actualSize = 0;
|
|
67310
|
-
const tmpPath =
|
|
67592
|
+
const tmpPath = import_node_path50.default.join(
|
|
67311
67593
|
attachmentsRoot,
|
|
67312
67594
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto15.default.randomBytes(4).toString("hex")}`
|
|
67313
67595
|
);
|
|
@@ -67322,18 +67604,18 @@ async function writeUploadedAttachment(args) {
|
|
|
67322
67604
|
yield buf;
|
|
67323
67605
|
}
|
|
67324
67606
|
},
|
|
67325
|
-
|
|
67607
|
+
import_node_fs46.default.createWriteStream(tmpPath, { mode: 384 })
|
|
67326
67608
|
);
|
|
67327
67609
|
} catch (err) {
|
|
67328
67610
|
try {
|
|
67329
|
-
|
|
67611
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67330
67612
|
} catch {
|
|
67331
67613
|
}
|
|
67332
67614
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
67333
67615
|
}
|
|
67334
67616
|
if (actualSize !== args.contentLength) {
|
|
67335
67617
|
try {
|
|
67336
|
-
|
|
67618
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67337
67619
|
} catch {
|
|
67338
67620
|
}
|
|
67339
67621
|
throw new UploadError(
|
|
@@ -67342,34 +67624,34 @@ async function writeUploadedAttachment(args) {
|
|
|
67342
67624
|
);
|
|
67343
67625
|
}
|
|
67344
67626
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
67345
|
-
const hashDir =
|
|
67627
|
+
const hashDir = import_node_path50.default.join(attachmentsRoot, attachmentId);
|
|
67346
67628
|
let finalFileName;
|
|
67347
67629
|
let hashDirExists = false;
|
|
67348
67630
|
try {
|
|
67349
|
-
hashDirExists =
|
|
67631
|
+
hashDirExists = import_node_fs46.default.statSync(hashDir).isDirectory();
|
|
67350
67632
|
} catch {
|
|
67351
67633
|
}
|
|
67352
67634
|
if (hashDirExists) {
|
|
67353
|
-
const existing =
|
|
67635
|
+
const existing = import_node_fs46.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
|
|
67354
67636
|
finalFileName = existing[0] ?? args.fileName;
|
|
67355
67637
|
try {
|
|
67356
|
-
|
|
67638
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67357
67639
|
} catch {
|
|
67358
67640
|
}
|
|
67359
67641
|
} else {
|
|
67360
67642
|
try {
|
|
67361
|
-
|
|
67643
|
+
import_node_fs46.default.mkdirSync(hashDir, { recursive: true });
|
|
67362
67644
|
finalFileName = args.fileName;
|
|
67363
|
-
|
|
67645
|
+
import_node_fs46.default.renameSync(tmpPath, import_node_path50.default.join(hashDir, finalFileName));
|
|
67364
67646
|
} catch (err) {
|
|
67365
67647
|
try {
|
|
67366
|
-
|
|
67648
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67367
67649
|
} catch {
|
|
67368
67650
|
}
|
|
67369
67651
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
67370
67652
|
}
|
|
67371
67653
|
}
|
|
67372
|
-
const absPath =
|
|
67654
|
+
const absPath = import_node_path50.default.join(hashDir, finalFileName);
|
|
67373
67655
|
const relPath = absPath;
|
|
67374
67656
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
67375
67657
|
relPath: absPath,
|
|
@@ -67384,8 +67666,8 @@ async function writeUploadedAttachment(args) {
|
|
|
67384
67666
|
|
|
67385
67667
|
// src/extension/import.ts
|
|
67386
67668
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
67387
|
-
var
|
|
67388
|
-
var
|
|
67669
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
67670
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
67389
67671
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
67390
67672
|
var ImportError = class extends Error {
|
|
67391
67673
|
constructor(code, message) {
|
|
@@ -67402,7 +67684,7 @@ async function importZip(buf, root) {
|
|
|
67402
67684
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
67403
67685
|
}
|
|
67404
67686
|
for (const name of Object.keys(zip.files)) {
|
|
67405
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
67687
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path51.default.isAbsolute(name)) {
|
|
67406
67688
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
67407
67689
|
}
|
|
67408
67690
|
}
|
|
@@ -67435,7 +67717,7 @@ async function importZip(buf, root) {
|
|
|
67435
67717
|
);
|
|
67436
67718
|
}
|
|
67437
67719
|
}
|
|
67438
|
-
const destDir =
|
|
67720
|
+
const destDir = import_node_path51.default.join(root, manifest.id);
|
|
67439
67721
|
let destExists = false;
|
|
67440
67722
|
try {
|
|
67441
67723
|
await import_promises9.default.access(destDir);
|
|
@@ -67445,15 +67727,15 @@ async function importZip(buf, root) {
|
|
|
67445
67727
|
if (destExists) {
|
|
67446
67728
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
67447
67729
|
}
|
|
67448
|
-
const stage = await import_promises9.default.mkdtemp(
|
|
67730
|
+
const stage = await import_promises9.default.mkdtemp(import_node_path51.default.join(import_node_os19.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
67449
67731
|
try {
|
|
67450
67732
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
67451
|
-
const dest =
|
|
67733
|
+
const dest = import_node_path51.default.join(stage, name);
|
|
67452
67734
|
if (entry.dir) {
|
|
67453
67735
|
await import_promises9.default.mkdir(dest, { recursive: true });
|
|
67454
67736
|
continue;
|
|
67455
67737
|
}
|
|
67456
|
-
await import_promises9.default.mkdir(
|
|
67738
|
+
await import_promises9.default.mkdir(import_node_path51.default.dirname(dest), { recursive: true });
|
|
67457
67739
|
const content = await entry.async("nodebuffer");
|
|
67458
67740
|
await import_promises9.default.writeFile(dest, content);
|
|
67459
67741
|
}
|
|
@@ -67507,7 +67789,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
67507
67789
|
".wasm": "application/wasm"
|
|
67508
67790
|
};
|
|
67509
67791
|
function shareUiAssetMime(filePath) {
|
|
67510
|
-
const ext =
|
|
67792
|
+
const ext = import_node_path52.default.extname(filePath).toLowerCase();
|
|
67511
67793
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
67512
67794
|
}
|
|
67513
67795
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -67606,7 +67888,7 @@ function isValidUploadFileName(fileName) {
|
|
|
67606
67888
|
if (fileName === "." || fileName === "..") return false;
|
|
67607
67889
|
if (fileName.startsWith(".")) return false;
|
|
67608
67890
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
67609
|
-
return fileName ===
|
|
67891
|
+
return fileName === import_node_path52.default.basename(fileName);
|
|
67610
67892
|
}
|
|
67611
67893
|
function createHttpRouter(deps) {
|
|
67612
67894
|
return async (req, res) => {
|
|
@@ -67690,7 +67972,7 @@ function createHttpRouter(deps) {
|
|
|
67690
67972
|
}
|
|
67691
67973
|
let buf;
|
|
67692
67974
|
try {
|
|
67693
|
-
buf = await
|
|
67975
|
+
buf = await import_node_fs47.default.promises.readFile(abs);
|
|
67694
67976
|
} catch {
|
|
67695
67977
|
sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
67696
67978
|
return true;
|
|
@@ -67836,7 +68118,7 @@ function createHttpRouter(deps) {
|
|
|
67836
68118
|
sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
|
|
67837
68119
|
return true;
|
|
67838
68120
|
}
|
|
67839
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
68121
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path52.default.basename(r2.absPath)));
|
|
67840
68122
|
return true;
|
|
67841
68123
|
}
|
|
67842
68124
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -67957,7 +68239,7 @@ function createHttpRouter(deps) {
|
|
|
67957
68239
|
return true;
|
|
67958
68240
|
}
|
|
67959
68241
|
let absPath;
|
|
67960
|
-
if (
|
|
68242
|
+
if (import_node_path52.default.isAbsolute(pathParam)) {
|
|
67961
68243
|
absPath = pathParam;
|
|
67962
68244
|
} else if (deps.sessionStore) {
|
|
67963
68245
|
const file = deps.sessionStore.read(sid);
|
|
@@ -67965,7 +68247,7 @@ function createHttpRouter(deps) {
|
|
|
67965
68247
|
sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
67966
68248
|
return true;
|
|
67967
68249
|
}
|
|
67968
|
-
absPath =
|
|
68250
|
+
absPath = import_node_path52.default.join(file.cwd, pathParam);
|
|
67969
68251
|
} else {
|
|
67970
68252
|
sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
67971
68253
|
return true;
|
|
@@ -68049,7 +68331,7 @@ function withCtx(ctx, body) {
|
|
|
68049
68331
|
function streamFile(res, absPath, logger) {
|
|
68050
68332
|
let stat;
|
|
68051
68333
|
try {
|
|
68052
|
-
stat =
|
|
68334
|
+
stat = import_node_fs47.default.statSync(absPath);
|
|
68053
68335
|
} catch (err) {
|
|
68054
68336
|
const code = err?.code;
|
|
68055
68337
|
if (code === "ENOENT") {
|
|
@@ -68064,7 +68346,7 @@ function streamFile(res, absPath, logger) {
|
|
|
68064
68346
|
return;
|
|
68065
68347
|
}
|
|
68066
68348
|
const mime = lookupMime(absPath);
|
|
68067
|
-
const basename2 =
|
|
68349
|
+
const basename2 = import_node_path52.default.basename(absPath);
|
|
68068
68350
|
res.writeHead(200, {
|
|
68069
68351
|
"Content-Type": mime,
|
|
68070
68352
|
"Content-Length": String(stat.size),
|
|
@@ -68072,7 +68354,7 @@ function streamFile(res, absPath, logger) {
|
|
|
68072
68354
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
68073
68355
|
"X-Content-Type-Options": "nosniff"
|
|
68074
68356
|
});
|
|
68075
|
-
const stream =
|
|
68357
|
+
const stream = import_node_fs47.default.createReadStream(absPath);
|
|
68076
68358
|
stream.on("error", (err) => {
|
|
68077
68359
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
68078
68360
|
res.destroy();
|
|
@@ -68081,8 +68363,8 @@ function streamFile(res, absPath, logger) {
|
|
|
68081
68363
|
}
|
|
68082
68364
|
|
|
68083
68365
|
// src/attachment/gc.ts
|
|
68084
|
-
var
|
|
68085
|
-
var
|
|
68366
|
+
var import_node_fs48 = __toESM(require("fs"), 1);
|
|
68367
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
68086
68368
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
68087
68369
|
function runAttachmentGc(args) {
|
|
68088
68370
|
const now = (args.now ?? Date.now)();
|
|
@@ -68091,12 +68373,12 @@ function runAttachmentGc(args) {
|
|
|
68091
68373
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
68092
68374
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
68093
68375
|
if (entry.stale) continue;
|
|
68094
|
-
if (
|
|
68376
|
+
if (import_node_path53.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
68095
68377
|
}
|
|
68096
68378
|
}
|
|
68097
68379
|
const visited = /* @__PURE__ */ new Set();
|
|
68098
68380
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
68099
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
68381
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path53.default.join(
|
|
68100
68382
|
args.dataDir,
|
|
68101
68383
|
"sessions",
|
|
68102
68384
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -68109,28 +68391,28 @@ function runAttachmentGc(args) {
|
|
|
68109
68391
|
return true;
|
|
68110
68392
|
});
|
|
68111
68393
|
for (const rootDir of roots) {
|
|
68112
|
-
const attRoot =
|
|
68394
|
+
const attRoot = import_node_path53.default.join(rootDir, ".attachments");
|
|
68113
68395
|
let hashDirs;
|
|
68114
68396
|
try {
|
|
68115
|
-
hashDirs =
|
|
68397
|
+
hashDirs = import_node_fs48.default.readdirSync(attRoot);
|
|
68116
68398
|
} catch (err) {
|
|
68117
68399
|
if (err.code === "ENOENT") continue;
|
|
68118
68400
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
68119
68401
|
continue;
|
|
68120
68402
|
}
|
|
68121
68403
|
for (const hashDir of hashDirs) {
|
|
68122
|
-
const hashDirAbs =
|
|
68404
|
+
const hashDirAbs = import_node_path53.default.join(attRoot, hashDir);
|
|
68123
68405
|
let files;
|
|
68124
68406
|
try {
|
|
68125
|
-
files =
|
|
68407
|
+
files = import_node_fs48.default.readdirSync(hashDirAbs);
|
|
68126
68408
|
} catch {
|
|
68127
68409
|
continue;
|
|
68128
68410
|
}
|
|
68129
68411
|
for (const name of files) {
|
|
68130
|
-
const file =
|
|
68412
|
+
const file = import_node_path53.default.join(hashDirAbs, name);
|
|
68131
68413
|
let stat;
|
|
68132
68414
|
try {
|
|
68133
|
-
stat =
|
|
68415
|
+
stat = import_node_fs48.default.statSync(file);
|
|
68134
68416
|
} catch {
|
|
68135
68417
|
continue;
|
|
68136
68418
|
}
|
|
@@ -68139,18 +68421,18 @@ function runAttachmentGc(args) {
|
|
|
68139
68421
|
if (age < ttlMs) continue;
|
|
68140
68422
|
if (liveAbs.has(file)) continue;
|
|
68141
68423
|
try {
|
|
68142
|
-
|
|
68424
|
+
import_node_fs48.default.unlinkSync(file);
|
|
68143
68425
|
} catch (err) {
|
|
68144
68426
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
68145
68427
|
}
|
|
68146
68428
|
}
|
|
68147
68429
|
try {
|
|
68148
|
-
if (
|
|
68430
|
+
if (import_node_fs48.default.readdirSync(hashDirAbs).length === 0) import_node_fs48.default.rmdirSync(hashDirAbs);
|
|
68149
68431
|
} catch {
|
|
68150
68432
|
}
|
|
68151
68433
|
}
|
|
68152
68434
|
try {
|
|
68153
|
-
if (
|
|
68435
|
+
if (import_node_fs48.default.readdirSync(attRoot).length === 0) import_node_fs48.default.rmdirSync(attRoot);
|
|
68154
68436
|
} catch {
|
|
68155
68437
|
}
|
|
68156
68438
|
}
|
|
@@ -68158,8 +68440,8 @@ function runAttachmentGc(args) {
|
|
|
68158
68440
|
}
|
|
68159
68441
|
|
|
68160
68442
|
// src/attachment/group.ts
|
|
68161
|
-
var
|
|
68162
|
-
var
|
|
68443
|
+
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
68444
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
68163
68445
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
68164
68446
|
init_protocol();
|
|
68165
68447
|
var GroupFileStore = class {
|
|
@@ -68171,11 +68453,11 @@ var GroupFileStore = class {
|
|
|
68171
68453
|
this.logger = opts.logger;
|
|
68172
68454
|
}
|
|
68173
68455
|
rootForScope(scope) {
|
|
68174
|
-
return
|
|
68456
|
+
return import_node_path54.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
68175
68457
|
}
|
|
68176
68458
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
68177
68459
|
filePath(scope, sessionId) {
|
|
68178
|
-
return
|
|
68460
|
+
return import_node_path54.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
68179
68461
|
}
|
|
68180
68462
|
cacheKey(scope, sessionId) {
|
|
68181
68463
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -68184,7 +68466,7 @@ var GroupFileStore = class {
|
|
|
68184
68466
|
readFile(scope, sessionId) {
|
|
68185
68467
|
const file = this.filePath(scope, sessionId);
|
|
68186
68468
|
try {
|
|
68187
|
-
const raw =
|
|
68469
|
+
const raw = import_node_fs49.default.readFileSync(file, "utf8");
|
|
68188
68470
|
const parsed = JSON.parse(raw);
|
|
68189
68471
|
if (!Array.isArray(parsed)) {
|
|
68190
68472
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -68210,10 +68492,10 @@ var GroupFileStore = class {
|
|
|
68210
68492
|
}
|
|
68211
68493
|
writeFile(scope, sessionId, entries) {
|
|
68212
68494
|
const file = this.filePath(scope, sessionId);
|
|
68213
|
-
|
|
68495
|
+
import_node_fs49.default.mkdirSync(import_node_path54.default.dirname(file), { recursive: true });
|
|
68214
68496
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
68215
|
-
|
|
68216
|
-
|
|
68497
|
+
import_node_fs49.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
68498
|
+
import_node_fs49.default.renameSync(tmp, file);
|
|
68217
68499
|
}
|
|
68218
68500
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
68219
68501
|
list(scope, sessionId) {
|
|
@@ -68305,7 +68587,7 @@ var GroupFileStore = class {
|
|
|
68305
68587
|
*/
|
|
68306
68588
|
deleteSession(scope, sessionId) {
|
|
68307
68589
|
try {
|
|
68308
|
-
|
|
68590
|
+
import_node_fs49.default.unlinkSync(this.filePath(scope, sessionId));
|
|
68309
68591
|
} catch (err) {
|
|
68310
68592
|
if (err?.code !== "ENOENT") throw err;
|
|
68311
68593
|
}
|
|
@@ -68318,7 +68600,7 @@ var GroupFileStore = class {
|
|
|
68318
68600
|
* 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
|
|
68319
68601
|
*/
|
|
68320
68602
|
deletePersona(personaId2) {
|
|
68321
|
-
|
|
68603
|
+
import_node_fs49.default.rmSync(import_node_path54.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
|
|
68322
68604
|
const prefix = `persona:${personaId2}:`;
|
|
68323
68605
|
for (const key of this.cache.keys()) {
|
|
68324
68606
|
if (key.startsWith(prefix)) this.cache.delete(key);
|
|
@@ -68327,10 +68609,10 @@ var GroupFileStore = class {
|
|
|
68327
68609
|
};
|
|
68328
68610
|
|
|
68329
68611
|
// src/discovery/state-file.ts
|
|
68330
|
-
var
|
|
68331
|
-
var
|
|
68612
|
+
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
68613
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
68332
68614
|
function defaultStateFilePath(dataDir) {
|
|
68333
|
-
return
|
|
68615
|
+
return import_node_path55.default.join(dataDir, "state.json");
|
|
68334
68616
|
}
|
|
68335
68617
|
function isPidAlive(pid) {
|
|
68336
68618
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -68352,7 +68634,7 @@ var StateFileManager = class {
|
|
|
68352
68634
|
}
|
|
68353
68635
|
read() {
|
|
68354
68636
|
try {
|
|
68355
|
-
const raw =
|
|
68637
|
+
const raw = import_node_fs50.default.readFileSync(this.file, "utf8");
|
|
68356
68638
|
const parsed = JSON.parse(raw);
|
|
68357
68639
|
return parsed;
|
|
68358
68640
|
} catch {
|
|
@@ -68366,20 +68648,20 @@ var StateFileManager = class {
|
|
|
68366
68648
|
return { status: "stale", existing };
|
|
68367
68649
|
}
|
|
68368
68650
|
write(state) {
|
|
68369
|
-
|
|
68651
|
+
import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(this.file), { recursive: true });
|
|
68370
68652
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
68371
|
-
|
|
68372
|
-
|
|
68653
|
+
import_node_fs50.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
68654
|
+
import_node_fs50.default.renameSync(tmp, this.file);
|
|
68373
68655
|
if (process.platform !== "win32") {
|
|
68374
68656
|
try {
|
|
68375
|
-
|
|
68657
|
+
import_node_fs50.default.chmodSync(this.file, 384);
|
|
68376
68658
|
} catch {
|
|
68377
68659
|
}
|
|
68378
68660
|
}
|
|
68379
68661
|
}
|
|
68380
68662
|
delete() {
|
|
68381
68663
|
try {
|
|
68382
|
-
|
|
68664
|
+
import_node_fs50.default.unlinkSync(this.file);
|
|
68383
68665
|
} catch {
|
|
68384
68666
|
}
|
|
68385
68667
|
}
|
|
@@ -68393,14 +68675,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
68393
68675
|
}
|
|
68394
68676
|
|
|
68395
68677
|
// src/tunnel/tunnel-manager.ts
|
|
68396
|
-
var
|
|
68397
|
-
var
|
|
68678
|
+
var import_node_fs54 = __toESM(require("fs"), 1);
|
|
68679
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
68398
68680
|
var import_node_crypto17 = __toESM(require("crypto"), 1);
|
|
68399
68681
|
var import_node_child_process16 = require("child_process");
|
|
68400
68682
|
|
|
68401
68683
|
// src/tunnel/tunnel-store.ts
|
|
68402
|
-
var
|
|
68403
|
-
var
|
|
68684
|
+
var import_node_fs51 = __toESM(require("fs"), 1);
|
|
68685
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
68404
68686
|
var TunnelStore = class {
|
|
68405
68687
|
constructor(filePath) {
|
|
68406
68688
|
this.filePath = filePath;
|
|
@@ -68408,7 +68690,7 @@ var TunnelStore = class {
|
|
|
68408
68690
|
filePath;
|
|
68409
68691
|
async get() {
|
|
68410
68692
|
try {
|
|
68411
|
-
const raw = await
|
|
68693
|
+
const raw = await import_node_fs51.default.promises.readFile(this.filePath, "utf8");
|
|
68412
68694
|
const obj = JSON.parse(raw);
|
|
68413
68695
|
if (!isPersistedTunnel(obj)) return null;
|
|
68414
68696
|
return obj;
|
|
@@ -68419,22 +68701,22 @@ var TunnelStore = class {
|
|
|
68419
68701
|
}
|
|
68420
68702
|
}
|
|
68421
68703
|
async set(v3) {
|
|
68422
|
-
const dir =
|
|
68423
|
-
await
|
|
68704
|
+
const dir = import_node_path56.default.dirname(this.filePath);
|
|
68705
|
+
await import_node_fs51.default.promises.mkdir(dir, { recursive: true });
|
|
68424
68706
|
const data = JSON.stringify(v3, null, 2);
|
|
68425
68707
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
68426
|
-
await
|
|
68708
|
+
await import_node_fs51.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
68427
68709
|
if (process.platform !== "win32") {
|
|
68428
68710
|
try {
|
|
68429
|
-
await
|
|
68711
|
+
await import_node_fs51.default.promises.chmod(tmp, 384);
|
|
68430
68712
|
} catch {
|
|
68431
68713
|
}
|
|
68432
68714
|
}
|
|
68433
|
-
await
|
|
68715
|
+
await import_node_fs51.default.promises.rename(tmp, this.filePath);
|
|
68434
68716
|
}
|
|
68435
68717
|
async clear() {
|
|
68436
68718
|
try {
|
|
68437
|
-
await
|
|
68719
|
+
await import_node_fs51.default.promises.unlink(this.filePath);
|
|
68438
68720
|
} catch (err) {
|
|
68439
68721
|
const code = err?.code;
|
|
68440
68722
|
if (code !== "ENOENT") throw err;
|
|
@@ -68529,9 +68811,9 @@ function escape2(v3) {
|
|
|
68529
68811
|
}
|
|
68530
68812
|
|
|
68531
68813
|
// src/tunnel/frpc-binary.ts
|
|
68532
|
-
var
|
|
68533
|
-
var
|
|
68534
|
-
var
|
|
68814
|
+
var import_node_fs52 = __toESM(require("fs"), 1);
|
|
68815
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
68816
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
68535
68817
|
var import_node_child_process14 = require("child_process");
|
|
68536
68818
|
var import_node_stream4 = require("stream");
|
|
68537
68819
|
var import_promises10 = require("stream/promises");
|
|
@@ -68563,20 +68845,20 @@ function frpcDownloadUrl(version2, p3) {
|
|
|
68563
68845
|
}
|
|
68564
68846
|
async function ensureFrpcBinary(opts) {
|
|
68565
68847
|
if (opts.override) {
|
|
68566
|
-
if (!
|
|
68848
|
+
if (!import_node_fs52.default.existsSync(opts.override)) {
|
|
68567
68849
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
68568
68850
|
}
|
|
68569
68851
|
return opts.override;
|
|
68570
68852
|
}
|
|
68571
68853
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
68572
68854
|
const platform = opts.platform ?? detectPlatform();
|
|
68573
|
-
const binDir =
|
|
68574
|
-
|
|
68855
|
+
const binDir = import_node_path57.default.join(opts.dataDir, "bin");
|
|
68856
|
+
import_node_fs52.default.mkdirSync(binDir, { recursive: true });
|
|
68575
68857
|
cleanupStaleArtifacts(binDir);
|
|
68576
|
-
const stableBin =
|
|
68577
|
-
if (
|
|
68858
|
+
const stableBin = import_node_path57.default.join(binDir, "frpc");
|
|
68859
|
+
if (import_node_fs52.default.existsSync(stableBin)) return stableBin;
|
|
68578
68860
|
const partialBin = `${stableBin}.partial`;
|
|
68579
|
-
const tarballPath =
|
|
68861
|
+
const tarballPath = import_node_path57.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
68580
68862
|
try {
|
|
68581
68863
|
const url = frpcDownloadUrl(version2, platform);
|
|
68582
68864
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -68585,8 +68867,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
68585
68867
|
} else {
|
|
68586
68868
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
68587
68869
|
}
|
|
68588
|
-
|
|
68589
|
-
|
|
68870
|
+
import_node_fs52.default.chmodSync(partialBin, 493);
|
|
68871
|
+
import_node_fs52.default.renameSync(partialBin, stableBin);
|
|
68590
68872
|
} finally {
|
|
68591
68873
|
safeUnlink(tarballPath);
|
|
68592
68874
|
safeUnlink(partialBin);
|
|
@@ -68596,15 +68878,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
68596
68878
|
function cleanupStaleArtifacts(binDir) {
|
|
68597
68879
|
let entries;
|
|
68598
68880
|
try {
|
|
68599
|
-
entries =
|
|
68881
|
+
entries = import_node_fs52.default.readdirSync(binDir);
|
|
68600
68882
|
} catch {
|
|
68601
68883
|
return;
|
|
68602
68884
|
}
|
|
68603
68885
|
for (const name of entries) {
|
|
68604
68886
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
68605
|
-
const full =
|
|
68887
|
+
const full = import_node_path57.default.join(binDir, name);
|
|
68606
68888
|
try {
|
|
68607
|
-
|
|
68889
|
+
import_node_fs52.default.rmSync(full, { recursive: true, force: true });
|
|
68608
68890
|
} catch {
|
|
68609
68891
|
}
|
|
68610
68892
|
}
|
|
@@ -68612,7 +68894,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
68612
68894
|
}
|
|
68613
68895
|
function safeUnlink(p3) {
|
|
68614
68896
|
try {
|
|
68615
|
-
|
|
68897
|
+
import_node_fs52.default.unlinkSync(p3);
|
|
68616
68898
|
} catch {
|
|
68617
68899
|
}
|
|
68618
68900
|
}
|
|
@@ -68623,13 +68905,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
68623
68905
|
if (!res.ok || !res.body) {
|
|
68624
68906
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
68625
68907
|
}
|
|
68626
|
-
const out =
|
|
68908
|
+
const out = import_node_fs52.default.createWriteStream(dest);
|
|
68627
68909
|
const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
|
|
68628
68910
|
await (0, import_promises10.pipeline)(nodeStream, out);
|
|
68629
68911
|
}
|
|
68630
68912
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
68631
|
-
const work =
|
|
68632
|
-
|
|
68913
|
+
const work = import_node_path57.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
68914
|
+
import_node_fs52.default.mkdirSync(work, { recursive: true });
|
|
68633
68915
|
try {
|
|
68634
68916
|
await new Promise((resolve9, reject) => {
|
|
68635
68917
|
const proc = (0, import_node_child_process14.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -68637,32 +68919,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
68637
68919
|
proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
|
|
68638
68920
|
});
|
|
68639
68921
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
68640
|
-
const src =
|
|
68641
|
-
if (!
|
|
68922
|
+
const src = import_node_path57.default.join(work, dirName, "frpc");
|
|
68923
|
+
if (!import_node_fs52.default.existsSync(src)) {
|
|
68642
68924
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
68643
68925
|
}
|
|
68644
|
-
|
|
68926
|
+
import_node_fs52.default.copyFileSync(src, destBin);
|
|
68645
68927
|
} finally {
|
|
68646
|
-
|
|
68928
|
+
import_node_fs52.default.rmSync(work, { recursive: true, force: true });
|
|
68647
68929
|
}
|
|
68648
68930
|
}
|
|
68649
68931
|
|
|
68650
68932
|
// src/tunnel/frpc-process.ts
|
|
68651
|
-
var
|
|
68652
|
-
var
|
|
68933
|
+
var import_node_fs53 = __toESM(require("fs"), 1);
|
|
68934
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
68653
68935
|
var import_node_child_process15 = require("child_process");
|
|
68654
68936
|
function frpcPidFilePath(dataDir) {
|
|
68655
|
-
return
|
|
68937
|
+
return import_node_path58.default.join(dataDir, "frpc.pid");
|
|
68656
68938
|
}
|
|
68657
68939
|
function writeFrpcPid(dataDir, pid) {
|
|
68658
68940
|
try {
|
|
68659
|
-
|
|
68941
|
+
import_node_fs53.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
68660
68942
|
} catch {
|
|
68661
68943
|
}
|
|
68662
68944
|
}
|
|
68663
68945
|
function clearFrpcPid(dataDir) {
|
|
68664
68946
|
try {
|
|
68665
|
-
|
|
68947
|
+
import_node_fs53.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
68666
68948
|
} catch {
|
|
68667
68949
|
}
|
|
68668
68950
|
}
|
|
@@ -68678,7 +68960,7 @@ function defaultIsPidAlive(pid) {
|
|
|
68678
68960
|
}
|
|
68679
68961
|
function defaultReadPidFile(file) {
|
|
68680
68962
|
try {
|
|
68681
|
-
return
|
|
68963
|
+
return import_node_fs53.default.readFileSync(file, "utf8");
|
|
68682
68964
|
} catch {
|
|
68683
68965
|
return null;
|
|
68684
68966
|
}
|
|
@@ -68694,7 +68976,7 @@ function defaultSleep2(ms) {
|
|
|
68694
68976
|
}
|
|
68695
68977
|
async function killStaleFrpc(deps) {
|
|
68696
68978
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
68697
|
-
const tomlPath =
|
|
68979
|
+
const tomlPath = import_node_path58.default.join(deps.dataDir, "frpc.toml");
|
|
68698
68980
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
68699
68981
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
68700
68982
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -68718,7 +69000,7 @@ async function killStaleFrpc(deps) {
|
|
|
68718
69000
|
}
|
|
68719
69001
|
if (victims.size === 0) {
|
|
68720
69002
|
try {
|
|
68721
|
-
|
|
69003
|
+
import_node_fs53.default.unlinkSync(pidFile);
|
|
68722
69004
|
} catch {
|
|
68723
69005
|
}
|
|
68724
69006
|
return;
|
|
@@ -68729,7 +69011,7 @@ async function killStaleFrpc(deps) {
|
|
|
68729
69011
|
}
|
|
68730
69012
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
68731
69013
|
try {
|
|
68732
|
-
|
|
69014
|
+
import_node_fs53.default.unlinkSync(pidFile);
|
|
68733
69015
|
} catch {
|
|
68734
69016
|
}
|
|
68735
69017
|
}
|
|
@@ -68766,7 +69048,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
68766
69048
|
var TunnelManager = class {
|
|
68767
69049
|
constructor(deps) {
|
|
68768
69050
|
this.deps = deps;
|
|
68769
|
-
this.store = deps.store ?? new TunnelStore(
|
|
69051
|
+
this.store = deps.store ?? new TunnelStore(import_node_path59.default.join(deps.dataDir, "tunnel.json"));
|
|
68770
69052
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
68771
69053
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
68772
69054
|
}
|
|
@@ -68893,7 +69175,7 @@ var TunnelManager = class {
|
|
|
68893
69175
|
dataDir: this.deps.dataDir,
|
|
68894
69176
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
68895
69177
|
});
|
|
68896
|
-
const tomlPath =
|
|
69178
|
+
const tomlPath = import_node_path59.default.join(this.deps.dataDir, "frpc.toml");
|
|
68897
69179
|
const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto17.default.randomBytes(3).toString("hex")}`;
|
|
68898
69180
|
const toml = buildFrpcToml({
|
|
68899
69181
|
serverAddr: t2.frpsHost,
|
|
@@ -68904,14 +69186,14 @@ var TunnelManager = class {
|
|
|
68904
69186
|
localPort,
|
|
68905
69187
|
logLevel: "info"
|
|
68906
69188
|
});
|
|
68907
|
-
await
|
|
69189
|
+
await import_node_fs54.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
68908
69190
|
const proc = (this.deps.spawnImpl ?? import_node_child_process16.spawn)(frpcBin, ["-c", tomlPath], {
|
|
68909
69191
|
stdio: ["ignore", "pipe", "pipe"]
|
|
68910
69192
|
});
|
|
68911
|
-
const logDir =
|
|
68912
|
-
|
|
68913
|
-
const logFilePath =
|
|
68914
|
-
const logStream =
|
|
69193
|
+
const logDir = import_node_path59.default.join(this.deps.dataDir, "log");
|
|
69194
|
+
import_node_fs54.default.mkdirSync(logDir, { recursive: true });
|
|
69195
|
+
const logFilePath = import_node_path59.default.join(logDir, "frpc.log");
|
|
69196
|
+
const logStream = import_node_fs54.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
68915
69197
|
logStream.on("error", () => {
|
|
68916
69198
|
});
|
|
68917
69199
|
const tee = (chunk) => {
|
|
@@ -68993,28 +69275,28 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
68993
69275
|
}
|
|
68994
69276
|
|
|
68995
69277
|
// src/tunnel/device-key.ts
|
|
68996
|
-
var
|
|
68997
|
-
var
|
|
69278
|
+
var import_node_os21 = __toESM(require("os"), 1);
|
|
69279
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
68998
69280
|
var import_node_crypto18 = __toESM(require("crypto"), 1);
|
|
68999
69281
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
69000
69282
|
function deriveStableDeviceKey(opts = {}) {
|
|
69001
|
-
const hostname = opts.hostname ??
|
|
69002
|
-
const uid = opts.uid ?? (typeof
|
|
69003
|
-
const home = opts.home ??
|
|
69004
|
-
const defaultDataDir =
|
|
69005
|
-
const normalizedDataDir = opts.dataDir ?
|
|
69283
|
+
const hostname = opts.hostname ?? import_node_os21.default.hostname();
|
|
69284
|
+
const uid = opts.uid ?? (typeof import_node_os21.default.userInfo === "function" ? import_node_os21.default.userInfo().uid : 0);
|
|
69285
|
+
const home = opts.home ?? import_node_os21.default.homedir();
|
|
69286
|
+
const defaultDataDir = import_node_path60.default.resolve(import_node_path60.default.join(home, ".clawd"));
|
|
69287
|
+
const normalizedDataDir = opts.dataDir ? import_node_path60.default.resolve(opts.dataDir) : null;
|
|
69006
69288
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
69007
69289
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
69008
69290
|
return import_node_crypto18.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
69009
69291
|
}
|
|
69010
69292
|
|
|
69011
69293
|
// src/auth-store.ts
|
|
69012
|
-
var
|
|
69013
|
-
var
|
|
69294
|
+
var import_node_fs55 = __toESM(require("fs"), 1);
|
|
69295
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
69014
69296
|
var import_node_crypto19 = __toESM(require("crypto"), 1);
|
|
69015
69297
|
var AUTH_FILE_NAME = "auth.json";
|
|
69016
69298
|
function authFilePath(dataDir) {
|
|
69017
|
-
return
|
|
69299
|
+
return import_node_path61.default.join(dataDir, AUTH_FILE_NAME);
|
|
69018
69300
|
}
|
|
69019
69301
|
function loadOrCreateAuthFile(opts) {
|
|
69020
69302
|
const file = authFilePath(opts.dataDir);
|
|
@@ -69055,7 +69337,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
69055
69337
|
}
|
|
69056
69338
|
function readAuthFile(file) {
|
|
69057
69339
|
try {
|
|
69058
|
-
const raw =
|
|
69340
|
+
const raw = import_node_fs55.default.readFileSync(file, "utf8");
|
|
69059
69341
|
const parsed = JSON.parse(raw);
|
|
69060
69342
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
69061
69343
|
return null;
|
|
@@ -69076,26 +69358,26 @@ function readAuthFile(file) {
|
|
|
69076
69358
|
}
|
|
69077
69359
|
}
|
|
69078
69360
|
function writeAuthFile(file, content) {
|
|
69079
|
-
|
|
69080
|
-
|
|
69361
|
+
import_node_fs55.default.mkdirSync(import_node_path61.default.dirname(file), { recursive: true });
|
|
69362
|
+
import_node_fs55.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
69081
69363
|
try {
|
|
69082
|
-
|
|
69364
|
+
import_node_fs55.default.chmodSync(file, 384);
|
|
69083
69365
|
} catch {
|
|
69084
69366
|
}
|
|
69085
69367
|
}
|
|
69086
69368
|
|
|
69087
69369
|
// src/owner-profile.ts
|
|
69088
|
-
var
|
|
69089
|
-
var
|
|
69090
|
-
var
|
|
69370
|
+
var import_node_fs56 = __toESM(require("fs"), 1);
|
|
69371
|
+
var import_node_os22 = __toESM(require("os"), 1);
|
|
69372
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
69091
69373
|
var PROFILE_FILENAME = "profile.json";
|
|
69092
69374
|
function profilePath(dataDir) {
|
|
69093
|
-
return
|
|
69375
|
+
return import_node_path62.default.join(dataDir, PROFILE_FILENAME);
|
|
69094
69376
|
}
|
|
69095
69377
|
function loadOwnerProfile(dataDir) {
|
|
69096
69378
|
let raw;
|
|
69097
69379
|
try {
|
|
69098
|
-
raw =
|
|
69380
|
+
raw = import_node_fs56.default.readFileSync(profilePath(dataDir), "utf8");
|
|
69099
69381
|
} catch {
|
|
69100
69382
|
return {};
|
|
69101
69383
|
}
|
|
@@ -69111,11 +69393,11 @@ function loadOwnerProfile(dataDir) {
|
|
|
69111
69393
|
}
|
|
69112
69394
|
function patchOwnerProfile(dataDir, patch) {
|
|
69113
69395
|
const merged = { ...loadOwnerProfile(dataDir), ...patch };
|
|
69114
|
-
|
|
69396
|
+
import_node_fs56.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
|
|
69115
69397
|
return merged;
|
|
69116
69398
|
}
|
|
69117
69399
|
function loadOwnerDisplayName(dataDir) {
|
|
69118
|
-
const fallback =
|
|
69400
|
+
const fallback = import_node_os22.default.userInfo().username;
|
|
69119
69401
|
const displayName = loadOwnerProfile(dataDir).displayName;
|
|
69120
69402
|
if (typeof displayName !== "string" || displayName.length === 0) {
|
|
69121
69403
|
if (displayName !== void 0) {
|
|
@@ -69127,18 +69409,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
69127
69409
|
}
|
|
69128
69410
|
|
|
69129
69411
|
// src/feishu-auth/owner-identity-store.ts
|
|
69130
|
-
var
|
|
69131
|
-
var
|
|
69412
|
+
var import_node_fs57 = __toESM(require("fs"), 1);
|
|
69413
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
69132
69414
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
69133
69415
|
var OwnerIdentityStore = class {
|
|
69134
69416
|
file;
|
|
69135
69417
|
constructor(dataDir) {
|
|
69136
|
-
this.file =
|
|
69418
|
+
this.file = import_node_path63.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
69137
69419
|
}
|
|
69138
69420
|
read() {
|
|
69139
69421
|
let raw;
|
|
69140
69422
|
try {
|
|
69141
|
-
raw =
|
|
69423
|
+
raw = import_node_fs57.default.readFileSync(this.file, "utf8");
|
|
69142
69424
|
} catch {
|
|
69143
69425
|
return null;
|
|
69144
69426
|
}
|
|
@@ -69165,16 +69447,16 @@ var OwnerIdentityStore = class {
|
|
|
69165
69447
|
};
|
|
69166
69448
|
}
|
|
69167
69449
|
write(record4) {
|
|
69168
|
-
|
|
69169
|
-
|
|
69450
|
+
import_node_fs57.default.mkdirSync(import_node_path63.default.dirname(this.file), { recursive: true });
|
|
69451
|
+
import_node_fs57.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
|
|
69170
69452
|
try {
|
|
69171
|
-
|
|
69453
|
+
import_node_fs57.default.chmodSync(this.file, 384);
|
|
69172
69454
|
} catch {
|
|
69173
69455
|
}
|
|
69174
69456
|
}
|
|
69175
69457
|
clear() {
|
|
69176
69458
|
try {
|
|
69177
|
-
|
|
69459
|
+
import_node_fs57.default.unlinkSync(this.file);
|
|
69178
69460
|
} catch (err) {
|
|
69179
69461
|
const code = err?.code;
|
|
69180
69462
|
if (code !== "ENOENT") throw err;
|
|
@@ -69670,8 +69952,8 @@ function verifyConnectToken(args) {
|
|
|
69670
69952
|
}
|
|
69671
69953
|
|
|
69672
69954
|
// src/feishu-auth/server-key.ts
|
|
69673
|
-
var
|
|
69674
|
-
var
|
|
69955
|
+
var fs74 = __toESM(require("fs"), 1);
|
|
69956
|
+
var path76 = __toESM(require("path"), 1);
|
|
69675
69957
|
var FILE_NAME2 = "server-signing-key.json";
|
|
69676
69958
|
var ServerKeyStore = class {
|
|
69677
69959
|
constructor(dataDir) {
|
|
@@ -69679,12 +69961,12 @@ var ServerKeyStore = class {
|
|
|
69679
69961
|
}
|
|
69680
69962
|
dataDir;
|
|
69681
69963
|
filePath() {
|
|
69682
|
-
return
|
|
69964
|
+
return path76.join(this.dataDir, FILE_NAME2);
|
|
69683
69965
|
}
|
|
69684
69966
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
69685
69967
|
read() {
|
|
69686
69968
|
try {
|
|
69687
|
-
const raw =
|
|
69969
|
+
const raw = fs74.readFileSync(this.filePath(), "utf8");
|
|
69688
69970
|
const parsed = JSON.parse(raw);
|
|
69689
69971
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
69690
69972
|
return parsed.publicKeyPem;
|
|
@@ -69699,12 +69981,12 @@ var ServerKeyStore = class {
|
|
|
69699
69981
|
publicKeyPem,
|
|
69700
69982
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
69701
69983
|
};
|
|
69702
|
-
|
|
69703
|
-
|
|
69984
|
+
fs74.mkdirSync(this.dataDir, { recursive: true });
|
|
69985
|
+
fs74.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
69704
69986
|
}
|
|
69705
69987
|
clear() {
|
|
69706
69988
|
try {
|
|
69707
|
-
|
|
69989
|
+
fs74.unlinkSync(this.filePath());
|
|
69708
69990
|
} catch {
|
|
69709
69991
|
}
|
|
69710
69992
|
}
|
|
@@ -69714,19 +69996,19 @@ var ServerKeyStore = class {
|
|
|
69714
69996
|
init_protocol();
|
|
69715
69997
|
|
|
69716
69998
|
// src/handlers/index.ts
|
|
69717
|
-
var
|
|
69999
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
69718
70000
|
|
|
69719
70001
|
// src/handlers/session.ts
|
|
69720
70002
|
init_protocol();
|
|
69721
70003
|
|
|
69722
70004
|
// src/session/fork.ts
|
|
69723
|
-
var
|
|
69724
|
-
var
|
|
69725
|
-
var
|
|
70005
|
+
var import_node_fs58 = __toESM(require("fs"), 1);
|
|
70006
|
+
var import_node_os23 = __toESM(require("os"), 1);
|
|
70007
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
69726
70008
|
var import_node_crypto21 = require("crypto");
|
|
69727
70009
|
init_claude_history();
|
|
69728
70010
|
function readJsonlEntries(file) {
|
|
69729
|
-
const raw =
|
|
70011
|
+
const raw = import_node_fs58.default.readFileSync(file, "utf8");
|
|
69730
70012
|
const out = [];
|
|
69731
70013
|
for (const line of raw.split("\n")) {
|
|
69732
70014
|
const t2 = line.trim();
|
|
@@ -69739,19 +70021,19 @@ function readJsonlEntries(file) {
|
|
|
69739
70021
|
return out;
|
|
69740
70022
|
}
|
|
69741
70023
|
function forkSession(input) {
|
|
69742
|
-
const baseDir = input.baseDir ??
|
|
69743
|
-
let projectDir =
|
|
69744
|
-
let sourceFile =
|
|
69745
|
-
if (!
|
|
70024
|
+
const baseDir = input.baseDir ?? import_node_path64.default.join(import_node_os23.default.homedir(), ".claude");
|
|
70025
|
+
let projectDir = import_node_path64.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
70026
|
+
let sourceFile = import_node_path64.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
70027
|
+
if (!import_node_fs58.default.existsSync(sourceFile)) {
|
|
69746
70028
|
const found = findTranscriptByToolSessionId(
|
|
69747
|
-
|
|
70029
|
+
import_node_path64.default.join(baseDir, "projects"),
|
|
69748
70030
|
input.toolSessionId
|
|
69749
70031
|
);
|
|
69750
70032
|
if (!found) {
|
|
69751
70033
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
69752
70034
|
}
|
|
69753
70035
|
sourceFile = found;
|
|
69754
|
-
projectDir =
|
|
70036
|
+
projectDir = import_node_path64.default.dirname(found);
|
|
69755
70037
|
}
|
|
69756
70038
|
const entries = readJsonlEntries(sourceFile);
|
|
69757
70039
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -69780,27 +70062,27 @@ function forkSession(input) {
|
|
|
69780
70062
|
}
|
|
69781
70063
|
forkedLines.push(JSON.stringify(forked));
|
|
69782
70064
|
}
|
|
69783
|
-
const outDir = input.targetCwd ?
|
|
69784
|
-
const forkedFilePath =
|
|
69785
|
-
|
|
69786
|
-
|
|
70065
|
+
const outDir = input.targetCwd ? import_node_path64.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
70066
|
+
const forkedFilePath = import_node_path64.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
70067
|
+
import_node_fs58.default.mkdirSync(outDir, { recursive: true });
|
|
70068
|
+
import_node_fs58.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
69787
70069
|
return { forkedToolSessionId, forkedFilePath };
|
|
69788
70070
|
}
|
|
69789
70071
|
|
|
69790
70072
|
// src/session/external-scan.ts
|
|
69791
|
-
var
|
|
70073
|
+
var import_node_fs59 = __toESM(require("fs"), 1);
|
|
69792
70074
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
69793
|
-
var
|
|
69794
|
-
var
|
|
70075
|
+
var import_node_os24 = __toESM(require("os"), 1);
|
|
70076
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
69795
70077
|
var import_node_module = require("module");
|
|
69796
70078
|
var import_node_child_process17 = require("child_process");
|
|
69797
70079
|
var import_meta7 = {};
|
|
69798
70080
|
function defaultRoots() {
|
|
69799
|
-
const home =
|
|
70081
|
+
const home = import_node_os24.default.homedir();
|
|
69800
70082
|
return {
|
|
69801
|
-
claudeProjectsDir:
|
|
69802
|
-
codexDir:
|
|
69803
|
-
clawdDir:
|
|
70083
|
+
claudeProjectsDir: import_node_path65.default.join(home, ".claude", "projects"),
|
|
70084
|
+
codexDir: import_node_path65.default.join(home, ".codex"),
|
|
70085
|
+
clawdDir: import_node_path65.default.join(home, ".clawd")
|
|
69804
70086
|
};
|
|
69805
70087
|
}
|
|
69806
70088
|
function width(s2) {
|
|
@@ -69851,7 +70133,7 @@ function userText(msg) {
|
|
|
69851
70133
|
}
|
|
69852
70134
|
function isDir2(p3) {
|
|
69853
70135
|
try {
|
|
69854
|
-
return
|
|
70136
|
+
return import_node_fs59.default.statSync(p3).isDirectory();
|
|
69855
70137
|
} catch {
|
|
69856
70138
|
return false;
|
|
69857
70139
|
}
|
|
@@ -69860,7 +70142,7 @@ async function scanClaude(roots) {
|
|
|
69860
70142
|
const out = [];
|
|
69861
70143
|
let dirs;
|
|
69862
70144
|
try {
|
|
69863
|
-
dirs =
|
|
70145
|
+
dirs = import_node_fs59.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
|
|
69864
70146
|
} catch {
|
|
69865
70147
|
return out;
|
|
69866
70148
|
}
|
|
@@ -69868,16 +70150,16 @@ async function scanClaude(roots) {
|
|
|
69868
70150
|
if (!d2.isDirectory()) continue;
|
|
69869
70151
|
let files;
|
|
69870
70152
|
try {
|
|
69871
|
-
files =
|
|
70153
|
+
files = import_node_fs59.default.readdirSync(import_node_path65.default.join(roots.claudeProjectsDir, d2.name));
|
|
69872
70154
|
} catch {
|
|
69873
70155
|
continue;
|
|
69874
70156
|
}
|
|
69875
70157
|
for (const name of files) {
|
|
69876
70158
|
if (!name.endsWith(".jsonl")) continue;
|
|
69877
|
-
const file =
|
|
70159
|
+
const file = import_node_path65.default.join(roots.claudeProjectsDir, d2.name, name);
|
|
69878
70160
|
let st2;
|
|
69879
70161
|
try {
|
|
69880
|
-
st2 =
|
|
70162
|
+
st2 = import_node_fs59.default.statSync(file);
|
|
69881
70163
|
} catch {
|
|
69882
70164
|
continue;
|
|
69883
70165
|
}
|
|
@@ -69930,7 +70212,7 @@ async function scanClaude(roots) {
|
|
|
69930
70212
|
return out;
|
|
69931
70213
|
}
|
|
69932
70214
|
async function countCodexTurns(rolloutPath) {
|
|
69933
|
-
if (!rolloutPath || !
|
|
70215
|
+
if (!rolloutPath || !import_node_fs59.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
|
|
69934
70216
|
let turns = 0;
|
|
69935
70217
|
let first = "";
|
|
69936
70218
|
for await (const rec6 of jsonLines(rolloutPath)) {
|
|
@@ -70004,7 +70286,7 @@ async function codexFromRows(rows) {
|
|
|
70004
70286
|
async function scanCodex(roots) {
|
|
70005
70287
|
let dbs = [];
|
|
70006
70288
|
try {
|
|
70007
|
-
dbs =
|
|
70289
|
+
dbs = import_node_fs59.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path65.default.join(roots.codexDir, n2));
|
|
70008
70290
|
} catch {
|
|
70009
70291
|
}
|
|
70010
70292
|
if (!dbs.length) return [];
|
|
@@ -70013,14 +70295,14 @@ async function scanCodex(roots) {
|
|
|
70013
70295
|
}
|
|
70014
70296
|
async function scanExternalSessions(rootsIn) {
|
|
70015
70297
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
70016
|
-
const personaRoot =
|
|
70298
|
+
const personaRoot = import_node_path65.default.join(roots.clawdDir, "personas");
|
|
70017
70299
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
70018
70300
|
const out = [];
|
|
70019
70301
|
for (const c2 of all) {
|
|
70020
70302
|
if (c2.skip) continue;
|
|
70021
70303
|
if (c2.turns < 1) continue;
|
|
70022
70304
|
if (!c2.cwd || !isDir2(c2.cwd)) continue;
|
|
70023
|
-
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot +
|
|
70305
|
+
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path65.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path65.default.sep)) {
|
|
70024
70306
|
continue;
|
|
70025
70307
|
}
|
|
70026
70308
|
out.push({
|
|
@@ -70037,13 +70319,13 @@ async function scanExternalSessions(rootsIn) {
|
|
|
70037
70319
|
}
|
|
70038
70320
|
|
|
70039
70321
|
// src/session/import-ledger.ts
|
|
70040
|
-
var
|
|
70041
|
-
var
|
|
70322
|
+
var import_node_fs60 = __toESM(require("fs"), 1);
|
|
70323
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
70042
70324
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
70043
70325
|
function readImportLedger(dataDir) {
|
|
70044
70326
|
try {
|
|
70045
70327
|
const parsed = JSON.parse(
|
|
70046
|
-
|
|
70328
|
+
import_node_fs60.default.readFileSync(import_node_path66.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
70047
70329
|
);
|
|
70048
70330
|
return Array.isArray(parsed) ? parsed : [];
|
|
70049
70331
|
} catch {
|
|
@@ -70051,10 +70333,10 @@ function readImportLedger(dataDir) {
|
|
|
70051
70333
|
}
|
|
70052
70334
|
}
|
|
70053
70335
|
function appendImportLedger(dataDir, entry) {
|
|
70054
|
-
const file =
|
|
70336
|
+
const file = import_node_path66.default.join(dataDir, LEDGER_FILENAME);
|
|
70055
70337
|
const entries = readImportLedger(dataDir);
|
|
70056
70338
|
entries.push(entry);
|
|
70057
|
-
|
|
70339
|
+
import_node_fs60.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
70058
70340
|
}
|
|
70059
70341
|
|
|
70060
70342
|
// src/handlers/session.ts
|
|
@@ -70587,7 +70869,7 @@ function buildPermissionHandlers(deps) {
|
|
|
70587
70869
|
}
|
|
70588
70870
|
|
|
70589
70871
|
// src/handlers/history.ts
|
|
70590
|
-
var
|
|
70872
|
+
var path81 = __toESM(require("path"), 1);
|
|
70591
70873
|
init_protocol();
|
|
70592
70874
|
|
|
70593
70875
|
// src/session/recent-dirs.ts
|
|
@@ -70605,7 +70887,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
70605
70887
|
}
|
|
70606
70888
|
|
|
70607
70889
|
// src/permission/persona-paths.ts
|
|
70608
|
-
var
|
|
70890
|
+
var path80 = __toESM(require("path"), 1);
|
|
70609
70891
|
function getAllowedPersonaIds(grants, action) {
|
|
70610
70892
|
const ids = /* @__PURE__ */ new Set();
|
|
70611
70893
|
for (const g3 of grants) {
|
|
@@ -70618,42 +70900,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
70618
70900
|
return ids;
|
|
70619
70901
|
}
|
|
70620
70902
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
70621
|
-
const target =
|
|
70903
|
+
const target = path80.resolve(absPath);
|
|
70622
70904
|
if (userWorkDir) {
|
|
70623
|
-
const u2 =
|
|
70624
|
-
const usep = u2.endsWith(
|
|
70905
|
+
const u2 = path80.resolve(userWorkDir);
|
|
70906
|
+
const usep = u2.endsWith(path80.sep) ? "" : path80.sep;
|
|
70625
70907
|
if (target === u2 || target.startsWith(u2 + usep)) return true;
|
|
70626
70908
|
}
|
|
70627
|
-
const root =
|
|
70628
|
-
const sep4 = root.endsWith(
|
|
70909
|
+
const root = path80.resolve(personaRoot);
|
|
70910
|
+
const sep4 = root.endsWith(path80.sep) ? "" : path80.sep;
|
|
70629
70911
|
if (!target.startsWith(root + sep4)) return false;
|
|
70630
|
-
const rel =
|
|
70912
|
+
const rel = path80.relative(root, target);
|
|
70631
70913
|
if (!rel || rel.startsWith("..")) return false;
|
|
70632
|
-
const personaId2 = rel.split(
|
|
70914
|
+
const personaId2 = rel.split(path80.sep)[0];
|
|
70633
70915
|
if (!personaId2) return false;
|
|
70634
70916
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
70635
70917
|
if (allowed === "*") return true;
|
|
70636
70918
|
return allowed.has(personaId2);
|
|
70637
70919
|
}
|
|
70638
70920
|
function personaIdFromPath(absPath, personaRoot) {
|
|
70639
|
-
const root =
|
|
70640
|
-
const target =
|
|
70641
|
-
const sep4 = root.endsWith(
|
|
70921
|
+
const root = path80.resolve(personaRoot);
|
|
70922
|
+
const target = path80.resolve(absPath);
|
|
70923
|
+
const sep4 = root.endsWith(path80.sep) ? "" : path80.sep;
|
|
70642
70924
|
if (!target.startsWith(root + sep4)) return null;
|
|
70643
|
-
const rel =
|
|
70925
|
+
const rel = path80.relative(root, target);
|
|
70644
70926
|
if (!rel || rel.startsWith("..")) return null;
|
|
70645
|
-
const id = rel.split(
|
|
70927
|
+
const id = rel.split(path80.sep)[0];
|
|
70646
70928
|
return id || null;
|
|
70647
70929
|
}
|
|
70648
70930
|
function isPathWithin(dir, absPath) {
|
|
70649
|
-
const d2 =
|
|
70650
|
-
const t2 =
|
|
70651
|
-
const sep4 = d2.endsWith(
|
|
70931
|
+
const d2 = path80.resolve(dir);
|
|
70932
|
+
const t2 = path80.resolve(absPath);
|
|
70933
|
+
const sep4 = d2.endsWith(path80.sep) ? "" : path80.sep;
|
|
70652
70934
|
return t2 === d2 || t2.startsWith(d2 + sep4);
|
|
70653
70935
|
}
|
|
70654
70936
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
70655
70937
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
70656
|
-
return personaIdFromPath(
|
|
70938
|
+
return personaIdFromPath(path80.resolve(absPath), personaRoot) === personaId2;
|
|
70657
70939
|
}
|
|
70658
70940
|
|
|
70659
70941
|
// src/handlers/history.ts
|
|
@@ -70706,7 +70988,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70706
70988
|
if (!pid) return false;
|
|
70707
70989
|
return isGuestPathAllowed(
|
|
70708
70990
|
ctx.grants,
|
|
70709
|
-
|
|
70991
|
+
path81.join(personaRoot, pid),
|
|
70710
70992
|
personaRoot,
|
|
70711
70993
|
"read",
|
|
70712
70994
|
userWorkDir
|
|
@@ -70718,7 +71000,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70718
71000
|
};
|
|
70719
71001
|
const list = async (frame, _client, ctx) => {
|
|
70720
71002
|
const args = HistoryListArgs.parse(frame);
|
|
70721
|
-
assertGuestPath(ctx,
|
|
71003
|
+
assertGuestPath(ctx, path81.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
70722
71004
|
const sessions = await history.listSessions(args);
|
|
70723
71005
|
return { response: { type: "history:list", sessions } };
|
|
70724
71006
|
};
|
|
@@ -70766,14 +71048,14 @@ function buildHistoryHandlers(deps) {
|
|
|
70766
71048
|
};
|
|
70767
71049
|
const subagents = async (frame, _client, ctx) => {
|
|
70768
71050
|
const args = HistorySubagentsArgs.parse(frame);
|
|
70769
|
-
assertGuestPath(ctx,
|
|
71051
|
+
assertGuestPath(ctx, path81.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
70770
71052
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
70771
71053
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
70772
71054
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
70773
71055
|
};
|
|
70774
71056
|
const subagentRead = async (frame, _client, ctx) => {
|
|
70775
71057
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
70776
|
-
assertGuestPath(ctx,
|
|
71058
|
+
assertGuestPath(ctx, path81.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
70777
71059
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
70778
71060
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
70779
71061
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -70783,7 +71065,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70783
71065
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
70784
71066
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
70785
71067
|
const filtered = dirs.filter(
|
|
70786
|
-
(d2) => isGuestPathAllowed(ctx.grants,
|
|
71068
|
+
(d2) => isGuestPathAllowed(ctx.grants, path81.resolve(d2.cwd), personaRoot, "read", userWorkDir)
|
|
70787
71069
|
);
|
|
70788
71070
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
70789
71071
|
}
|
|
@@ -70800,17 +71082,17 @@ function buildHistoryHandlers(deps) {
|
|
|
70800
71082
|
}
|
|
70801
71083
|
|
|
70802
71084
|
// src/handlers/projects.ts
|
|
70803
|
-
var
|
|
70804
|
-
var
|
|
70805
|
-
var
|
|
71085
|
+
var fs78 = __toESM(require("fs"), 1);
|
|
71086
|
+
var os26 = __toESM(require("os"), 1);
|
|
71087
|
+
var path82 = __toESM(require("path"), 1);
|
|
70806
71088
|
var import_node_child_process18 = require("child_process");
|
|
70807
71089
|
init_protocol();
|
|
70808
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
71090
|
+
var DEFAULT_PROJECTS_ROOT = path82.join(os26.homedir(), "Documents", "ChatGPT");
|
|
70809
71091
|
function allocateDir(root, name) {
|
|
70810
|
-
let candidate =
|
|
71092
|
+
let candidate = path82.join(root, name);
|
|
70811
71093
|
let n2 = 2;
|
|
70812
|
-
while (
|
|
70813
|
-
candidate =
|
|
71094
|
+
while (fs78.existsSync(candidate)) {
|
|
71095
|
+
candidate = path82.join(root, `${name} ${n2}`);
|
|
70814
71096
|
n2 += 1;
|
|
70815
71097
|
}
|
|
70816
71098
|
return candidate;
|
|
@@ -70838,7 +71120,7 @@ function buildProjectHandlers(deps) {
|
|
|
70838
71120
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
70839
71121
|
}
|
|
70840
71122
|
try {
|
|
70841
|
-
if (!
|
|
71123
|
+
if (!fs78.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
70842
71124
|
} catch {
|
|
70843
71125
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
70844
71126
|
}
|
|
@@ -70854,7 +71136,7 @@ function buildProjectHandlers(deps) {
|
|
|
70854
71136
|
let target;
|
|
70855
71137
|
if (args.path) {
|
|
70856
71138
|
try {
|
|
70857
|
-
if (!
|
|
71139
|
+
if (!fs78.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
70858
71140
|
} catch {
|
|
70859
71141
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
70860
71142
|
}
|
|
@@ -70862,15 +71144,15 @@ function buildProjectHandlers(deps) {
|
|
|
70862
71144
|
} else {
|
|
70863
71145
|
const name = args.name;
|
|
70864
71146
|
try {
|
|
70865
|
-
|
|
71147
|
+
fs78.mkdirSync(root, { recursive: true });
|
|
70866
71148
|
target = allocateDir(root, name);
|
|
70867
|
-
|
|
71149
|
+
fs78.mkdirSync(target);
|
|
70868
71150
|
} catch (err) {
|
|
70869
71151
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
70870
71152
|
}
|
|
70871
71153
|
const git2 = (0, import_node_child_process18.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
70872
71154
|
if (git2.status !== 0) {
|
|
70873
|
-
|
|
71155
|
+
fs78.rmSync(target, { recursive: true, force: true });
|
|
70874
71156
|
throw new ClawdError(
|
|
70875
71157
|
ERROR_CODES.INVALID_CWD,
|
|
70876
71158
|
`git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
|
|
@@ -70895,9 +71177,9 @@ function buildProjectHandlers(deps) {
|
|
|
70895
71177
|
}
|
|
70896
71178
|
|
|
70897
71179
|
// src/handlers/workspace.ts
|
|
70898
|
-
var
|
|
71180
|
+
var path83 = __toESM(require("path"), 1);
|
|
70899
71181
|
init_protocol();
|
|
70900
|
-
var
|
|
71182
|
+
var os27 = __toESM(require("os"), 1);
|
|
70901
71183
|
init_protocol();
|
|
70902
71184
|
init_protocol();
|
|
70903
71185
|
function buildEnabledPluginNames(personaManager, personaId2) {
|
|
@@ -70937,23 +71219,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
70937
71219
|
const list = async (frame, _client, ctx) => {
|
|
70938
71220
|
const args = WorkspaceListArgs.parse(frame);
|
|
70939
71221
|
const isGuest = ctx?.principal.kind === "guest";
|
|
70940
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
70941
|
-
const resolvedCwd =
|
|
70942
|
-
const target = args.path ?
|
|
71222
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os27.homedir();
|
|
71223
|
+
const resolvedCwd = path83.resolve(args.cwd ?? fallbackCwd);
|
|
71224
|
+
const target = args.path ? path83.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
70943
71225
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
70944
71226
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
70945
71227
|
return { response: { type: "workspace:list", ...res } };
|
|
70946
71228
|
};
|
|
70947
71229
|
const read = async (frame, _client, ctx) => {
|
|
70948
71230
|
const args = WorkspaceReadArgs.parse(frame);
|
|
70949
|
-
const target =
|
|
71231
|
+
const target = path83.isAbsolute(args.path) ? path83.resolve(args.path) : path83.resolve(args.cwd, args.path);
|
|
70950
71232
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
70951
71233
|
const res = workspace.read(args);
|
|
70952
71234
|
return { response: { type: "workspace:read", ...res } };
|
|
70953
71235
|
};
|
|
70954
71236
|
const skillsList = async (frame, _client, ctx) => {
|
|
70955
71237
|
const args = SkillsListArgs.parse(frame);
|
|
70956
|
-
const cwdAbs =
|
|
71238
|
+
const cwdAbs = path83.resolve(args.cwd);
|
|
70957
71239
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
70958
71240
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
70959
71241
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -70965,7 +71247,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
70965
71247
|
};
|
|
70966
71248
|
const agentsList = async (frame, _client, ctx) => {
|
|
70967
71249
|
const args = AgentsListArgs.parse(frame);
|
|
70968
|
-
const cwdAbs =
|
|
71250
|
+
const cwdAbs = path83.resolve(args.cwd);
|
|
70969
71251
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
70970
71252
|
if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
|
|
70971
71253
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -70987,20 +71269,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
70987
71269
|
}
|
|
70988
71270
|
|
|
70989
71271
|
// src/handlers/git.ts
|
|
70990
|
-
var
|
|
71272
|
+
var path85 = __toESM(require("path"), 1);
|
|
70991
71273
|
init_protocol();
|
|
70992
71274
|
init_protocol();
|
|
70993
71275
|
|
|
70994
71276
|
// src/workspace/git.ts
|
|
70995
71277
|
var import_node_child_process19 = require("child_process");
|
|
70996
|
-
var
|
|
70997
|
-
var
|
|
71278
|
+
var import_node_fs61 = __toESM(require("fs"), 1);
|
|
71279
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
70998
71280
|
var import_node_util2 = require("util");
|
|
70999
71281
|
var pexec = (0, import_node_util2.promisify)(import_node_child_process19.execFile);
|
|
71000
71282
|
function normalizePath(p3) {
|
|
71001
|
-
const resolved =
|
|
71283
|
+
const resolved = import_node_path67.default.resolve(p3);
|
|
71002
71284
|
try {
|
|
71003
|
-
return
|
|
71285
|
+
return import_node_fs61.default.realpathSync(resolved);
|
|
71004
71286
|
} catch {
|
|
71005
71287
|
return resolved;
|
|
71006
71288
|
}
|
|
@@ -71074,7 +71356,7 @@ async function listGitBranches(cwd) {
|
|
|
71074
71356
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
71075
71357
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
71076
71358
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
71077
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
71359
|
+
if (!isGuestPathAllowed(ctx.grants, path85.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
71078
71360
|
throw new ClawdError(
|
|
71079
71361
|
ERROR_CODES.UNAUTHORIZED,
|
|
71080
71362
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -71331,12 +71613,12 @@ async function queryCodexAccount(deps = {}) {
|
|
|
71331
71613
|
}
|
|
71332
71614
|
|
|
71333
71615
|
// src/tools/pi-account.ts
|
|
71334
|
-
var
|
|
71335
|
-
var
|
|
71616
|
+
var import_node_fs62 = __toESM(require("fs"), 1);
|
|
71617
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
71336
71618
|
function readPiCredentials(agentDir) {
|
|
71337
71619
|
let raw;
|
|
71338
71620
|
try {
|
|
71339
|
-
raw = JSON.parse(
|
|
71621
|
+
raw = JSON.parse(import_node_fs62.default.readFileSync(import_node_path68.default.join(agentDir, "auth.json"), "utf8"));
|
|
71340
71622
|
} catch {
|
|
71341
71623
|
return {};
|
|
71342
71624
|
}
|
|
@@ -71419,6 +71701,171 @@ function buildEngineHandlers(deps, overrides = {}) {
|
|
|
71419
71701
|
return { "engine:status": status, "engine:connectPool": connectPool };
|
|
71420
71702
|
}
|
|
71421
71703
|
|
|
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
|
+
// src/tools/subscription-channels-apply.ts
|
|
71710
|
+
var import_node_fs63 = __toESM(require("fs"), 1);
|
|
71711
|
+
var import_node_os25 = __toESM(require("os"), 1);
|
|
71712
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
71713
|
+
var TABLE_HEADER = /^\s*\[\[?\s*([A-Za-z0-9_.-]+)\s*\]\]?\s*(?:#.*)?$/;
|
|
71714
|
+
var KEY_LINE = /^\s*([A-Za-z0-9_.-]+)\s*=/;
|
|
71715
|
+
function stripCodexProvider(text) {
|
|
71716
|
+
const out = [];
|
|
71717
|
+
let inProviderSection = false;
|
|
71718
|
+
for (const line of text.split("\n")) {
|
|
71719
|
+
const headerMatch = TABLE_HEADER.exec(line);
|
|
71720
|
+
if (headerMatch) {
|
|
71721
|
+
const section = headerMatch[1].trim();
|
|
71722
|
+
inProviderSection = section === "model_providers" || section.startsWith("model_providers.");
|
|
71723
|
+
if (inProviderSection) continue;
|
|
71724
|
+
out.push(line);
|
|
71725
|
+
continue;
|
|
71726
|
+
}
|
|
71727
|
+
if (inProviderSection) continue;
|
|
71728
|
+
const keyMatch = KEY_LINE.exec(line);
|
|
71729
|
+
if (keyMatch) {
|
|
71730
|
+
const key = keyMatch[1].trim();
|
|
71731
|
+
if (key === "model_provider" || key.startsWith("model_providers.")) {
|
|
71732
|
+
continue;
|
|
71733
|
+
}
|
|
71734
|
+
}
|
|
71735
|
+
out.push(line);
|
|
71736
|
+
}
|
|
71737
|
+
return out.join("\n").trim();
|
|
71738
|
+
}
|
|
71739
|
+
function applyCodexSubscriptionChannel(opts) {
|
|
71740
|
+
const codexHome = opts.codexHome || process.env.CODEX_HOME || import_node_path69.default.join(import_node_os25.default.homedir(), ".codex");
|
|
71741
|
+
import_node_fs63.default.mkdirSync(codexHome, { recursive: true });
|
|
71742
|
+
const configFile = import_node_path69.default.join(codexHome, "config.toml");
|
|
71743
|
+
const original = import_node_fs63.default.existsSync(configFile) ? import_node_fs63.default.readFileSync(configFile, "utf8") : "";
|
|
71744
|
+
const rest = stripCodexProvider(original);
|
|
71745
|
+
let content;
|
|
71746
|
+
if (opts.channel) {
|
|
71747
|
+
const ch = opts.channel;
|
|
71748
|
+
content = [
|
|
71749
|
+
'model_provider = "cliproxyapi"',
|
|
71750
|
+
...rest ? ["", rest] : [],
|
|
71751
|
+
"",
|
|
71752
|
+
"[model_providers.cliproxyapi]",
|
|
71753
|
+
'name = "cliproxyapi"',
|
|
71754
|
+
`base_url = ${JSON.stringify(ch.baseUrl)}`,
|
|
71755
|
+
'wire_api = "responses"',
|
|
71756
|
+
`auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
|
|
71757
|
+
""
|
|
71758
|
+
].join("\n");
|
|
71759
|
+
} else {
|
|
71760
|
+
content = [
|
|
71761
|
+
'model_provider = "openai"',
|
|
71762
|
+
...rest ? ["", rest] : [],
|
|
71763
|
+
""
|
|
71764
|
+
].join("\n");
|
|
71765
|
+
}
|
|
71766
|
+
const tmpFile = `${configFile}.tmp.${Date.now()}`;
|
|
71767
|
+
import_node_fs63.default.writeFileSync(tmpFile, content, { mode: 384 });
|
|
71768
|
+
import_node_fs63.default.renameSync(tmpFile, configFile);
|
|
71769
|
+
}
|
|
71770
|
+
function applyPiSubscriptionChannel(opts) {
|
|
71771
|
+
const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path69.default.join(import_node_os25.default.homedir(), ".pi", "agent");
|
|
71772
|
+
if (!import_node_fs63.default.existsSync(agentDir)) return false;
|
|
71773
|
+
const configFile = import_node_path69.default.join(agentDir, "cliproxyapi.json");
|
|
71774
|
+
if (opts.channel) {
|
|
71775
|
+
const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
|
|
71776
|
+
const tmp = `${configFile}.tmp.${Date.now()}`;
|
|
71777
|
+
import_node_fs63.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
71778
|
+
import_node_fs63.default.renameSync(tmp, configFile);
|
|
71779
|
+
return true;
|
|
71780
|
+
}
|
|
71781
|
+
return false;
|
|
71782
|
+
}
|
|
71783
|
+
|
|
71784
|
+
// 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
|
+
function buildChannelsHandlers(deps) {
|
|
71798
|
+
let activationQueue = Promise.resolve();
|
|
71799
|
+
const get = async () => {
|
|
71800
|
+
return { response: deps.store.list() };
|
|
71801
|
+
};
|
|
71802
|
+
const save = async (frame) => {
|
|
71803
|
+
const args = parseArgs2(SubscriptionChannelSaveArgsSchema, frame, "subscriptionChannel:save");
|
|
71804
|
+
const channel = deps.store.save(args);
|
|
71805
|
+
const state = deps.store.list();
|
|
71806
|
+
if (state.activeChannelId === channel.id) {
|
|
71807
|
+
applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
|
|
71808
|
+
applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
|
|
71809
|
+
await deps.manager.getCapabilities("codex", { refresh: true });
|
|
71810
|
+
}
|
|
71811
|
+
return { response: deps.store.list() };
|
|
71812
|
+
};
|
|
71813
|
+
const del = async (frame) => {
|
|
71814
|
+
const args = parseArgs2(SubscriptionChannelDeleteArgsSchema, frame, "subscriptionChannel:delete");
|
|
71815
|
+
const wasActive = deps.store.list().activeChannelId === args.id;
|
|
71816
|
+
deps.store.delete(args.id);
|
|
71817
|
+
if (wasActive) {
|
|
71818
|
+
const newActive = deps.store.getActive();
|
|
71819
|
+
applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel: newActive });
|
|
71820
|
+
applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel: newActive });
|
|
71821
|
+
if (newActive) {
|
|
71822
|
+
await deps.manager.getCapabilities("codex", { refresh: true });
|
|
71823
|
+
}
|
|
71824
|
+
}
|
|
71825
|
+
return { response: { ok: true } };
|
|
71826
|
+
};
|
|
71827
|
+
const activate = async (frame, context) => {
|
|
71828
|
+
const run = activationQueue.then(() => activateChannel(frame, context));
|
|
71829
|
+
activationQueue = run.then(() => {
|
|
71830
|
+
}, () => {
|
|
71831
|
+
});
|
|
71832
|
+
return run;
|
|
71833
|
+
};
|
|
71834
|
+
const activateChannel = async (frame) => {
|
|
71835
|
+
const args = parseArgs2(SubscriptionChannelActivateArgsSchema, frame, "subscriptionChannel:activate");
|
|
71836
|
+
const channel = args.id === null ? null : deps.store.get(args.id);
|
|
71837
|
+
if (args.id !== null && !channel) throw new Error(`\u901A\u9053 ${args.id} \u4E0D\u5B58\u5728`);
|
|
71838
|
+
const codexHome = deps.codexHome || process.env.CODEX_HOME || import_node_path70.default.join(import_node_os26.default.homedir(), ".codex");
|
|
71839
|
+
const agentDir = deps.agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path70.default.join(import_node_os26.default.homedir(), ".pi", "agent");
|
|
71840
|
+
const restoreCodex = snapshotFile(import_node_path70.default.join(codexHome, "config.toml"));
|
|
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;
|
|
71858
|
+
}
|
|
71859
|
+
return { response: { ok: true } };
|
|
71860
|
+
};
|
|
71861
|
+
return {
|
|
71862
|
+
"subscriptionChannel:get": get,
|
|
71863
|
+
"subscriptionChannel:save": save,
|
|
71864
|
+
"subscriptionChannel:delete": del,
|
|
71865
|
+
"subscriptionChannel:activate": activate
|
|
71866
|
+
};
|
|
71867
|
+
}
|
|
71868
|
+
|
|
71422
71869
|
// src/handlers/inbox.ts
|
|
71423
71870
|
init_protocol();
|
|
71424
71871
|
function resolvePeerDeviceId(ctx, argsPeerDeviceId) {
|
|
@@ -72053,7 +72500,7 @@ function buildDashboardHandlers(deps) {
|
|
|
72053
72500
|
}
|
|
72054
72501
|
|
|
72055
72502
|
// src/handlers/meta.ts
|
|
72056
|
-
var
|
|
72503
|
+
var import_node_os27 = __toESM(require("os"), 1);
|
|
72057
72504
|
init_protocol();
|
|
72058
72505
|
|
|
72059
72506
|
// src/handlers/method-grants.ts
|
|
@@ -72252,6 +72699,10 @@ var METHOD_GRANT_MAP = {
|
|
|
72252
72699
|
"engine:status": ADMIN_ANY,
|
|
72253
72700
|
// engine:connectPool(接入号池,spec 2026-09-17-onboarding-pool-key):改本机 ~/.codex/config.toml,owner-only
|
|
72254
72701
|
"engine:connectPool": ADMIN_ANY,
|
|
72702
|
+
"subscriptionChannel:get": ADMIN_ANY,
|
|
72703
|
+
"subscriptionChannel:save": ADMIN_ANY,
|
|
72704
|
+
"subscriptionChannel:delete": ADMIN_ANY,
|
|
72705
|
+
"subscriptionChannel:activate": ADMIN_ANY,
|
|
72255
72706
|
"persona:create": ADMIN_ANY,
|
|
72256
72707
|
// persona:list / persona:get 下沉到 CAPABILITY_SCOPED:guest 调用合法
|
|
72257
72708
|
// (list 用于 People 面板展开对方分享的 personas;get 用于 guest 视角下
|
|
@@ -72369,21 +72820,21 @@ function computeMethodAccess(args) {
|
|
|
72369
72820
|
}
|
|
72370
72821
|
|
|
72371
72822
|
// src/version.ts
|
|
72372
|
-
var version = "0.2.
|
|
72823
|
+
var version = "0.2.592".length > 0 ? "0.2.592" : "dev";
|
|
72373
72824
|
|
|
72374
72825
|
// src/cli-probe/probe.ts
|
|
72375
|
-
var
|
|
72376
|
-
var
|
|
72826
|
+
var fs83 = __toESM(require("fs"), 1);
|
|
72827
|
+
var path89 = __toESM(require("path"), 1);
|
|
72377
72828
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
72378
72829
|
var BIN_NAME = "clawd";
|
|
72379
72830
|
var MAX_PARENT_HOPS = 5;
|
|
72380
72831
|
function probeGlobalCli(pathEnv) {
|
|
72381
72832
|
if (!pathEnv) return null;
|
|
72382
|
-
for (const dir of pathEnv.split(
|
|
72833
|
+
for (const dir of pathEnv.split(path89.delimiter)) {
|
|
72383
72834
|
if (!dir) continue;
|
|
72384
72835
|
let real;
|
|
72385
72836
|
try {
|
|
72386
|
-
real =
|
|
72837
|
+
real = fs83.realpathSync(path89.join(dir, BIN_NAME));
|
|
72387
72838
|
} catch {
|
|
72388
72839
|
continue;
|
|
72389
72840
|
}
|
|
@@ -72393,15 +72844,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
72393
72844
|
return null;
|
|
72394
72845
|
}
|
|
72395
72846
|
function readOwnPackageVersion(entryPath) {
|
|
72396
|
-
let dir =
|
|
72847
|
+
let dir = path89.dirname(entryPath);
|
|
72397
72848
|
for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
|
|
72398
72849
|
try {
|
|
72399
|
-
const raw =
|
|
72850
|
+
const raw = fs83.readFileSync(path89.join(dir, "package.json"), "utf8");
|
|
72400
72851
|
const pkg = JSON.parse(raw);
|
|
72401
72852
|
if (pkg.name !== PKG_NAME) return null;
|
|
72402
72853
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
72403
72854
|
} catch {
|
|
72404
|
-
const parent =
|
|
72855
|
+
const parent = path89.dirname(dir);
|
|
72405
72856
|
if (parent === dir) return null;
|
|
72406
72857
|
dir = parent;
|
|
72407
72858
|
}
|
|
@@ -72437,7 +72888,7 @@ function buildReadyFrame(deps, client) {
|
|
|
72437
72888
|
return {
|
|
72438
72889
|
version,
|
|
72439
72890
|
protocolVersion: PROTOCOL_VERSION,
|
|
72440
|
-
hostname:
|
|
72891
|
+
hostname: import_node_os27.default.hostname(),
|
|
72441
72892
|
os: process.platform,
|
|
72442
72893
|
tools,
|
|
72443
72894
|
runningSessions: info.runningSessions,
|
|
@@ -72577,7 +73028,7 @@ function buildPersonaHandlers(deps) {
|
|
|
72577
73028
|
}
|
|
72578
73029
|
|
|
72579
73030
|
// src/handlers/attachment.ts
|
|
72580
|
-
var
|
|
73031
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
72581
73032
|
init_protocol();
|
|
72582
73033
|
init_protocol();
|
|
72583
73034
|
function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
|
|
@@ -72656,12 +73107,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
72656
73107
|
`session ${args.sessionId} scope unresolved`
|
|
72657
73108
|
);
|
|
72658
73109
|
}
|
|
72659
|
-
const cwdAbs =
|
|
72660
|
-
const candidateAbs =
|
|
73110
|
+
const cwdAbs = import_node_path71.default.resolve(sessionFile.cwd);
|
|
73111
|
+
const candidateAbs = import_node_path71.default.isAbsolute(args.relPath) ? import_node_path71.default.resolve(args.relPath) : import_node_path71.default.resolve(cwdAbs, args.relPath);
|
|
72661
73112
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
72662
73113
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
72663
73114
|
const entry = entries.find((e) => {
|
|
72664
|
-
const storedAbs =
|
|
73115
|
+
const storedAbs = import_node_path71.default.isAbsolute(e.relPath) ? import_node_path71.default.resolve(e.relPath) : import_node_path71.default.resolve(cwdAbs, e.relPath);
|
|
72665
73116
|
return storedAbs === candidateAbs && !e.stale;
|
|
72666
73117
|
});
|
|
72667
73118
|
if (!entry) {
|
|
@@ -72685,7 +73136,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
72685
73136
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
72686
73137
|
const f2 = deps.sessionStore.read(sessionId);
|
|
72687
73138
|
if (!f2) return;
|
|
72688
|
-
assertGuestAttachmentPath(ctx,
|
|
73139
|
+
assertGuestAttachmentPath(ctx, import_node_path71.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
72689
73140
|
}
|
|
72690
73141
|
const groupAdd = async (frame, _client, ctx) => {
|
|
72691
73142
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -72700,8 +73151,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
72700
73151
|
if (!scope) {
|
|
72701
73152
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
72702
73153
|
}
|
|
72703
|
-
const cwdAbs =
|
|
72704
|
-
const candidateAbs =
|
|
73154
|
+
const cwdAbs = import_node_path71.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
73155
|
+
const candidateAbs = import_node_path71.default.isAbsolute(args.relPath) ? import_node_path71.default.resolve(args.relPath) : import_node_path71.default.resolve(cwdAbs, args.relPath);
|
|
72705
73156
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
72706
73157
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
72707
73158
|
const size = 0;
|
|
@@ -72760,19 +73211,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
72760
73211
|
|
|
72761
73212
|
// src/handlers/extension.ts
|
|
72762
73213
|
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
72763
|
-
var
|
|
73214
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
72764
73215
|
init_protocol();
|
|
72765
73216
|
|
|
72766
73217
|
// src/extension/bundle-zip.ts
|
|
72767
73218
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
72768
|
-
var
|
|
73219
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
72769
73220
|
var import_node_crypto22 = __toESM(require("crypto"), 1);
|
|
72770
73221
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
72771
73222
|
async function bundleExtensionDir(dir) {
|
|
72772
73223
|
const entries = await listFilesSorted(dir);
|
|
72773
73224
|
const zip = new import_jszip2.default();
|
|
72774
73225
|
for (const rel of entries) {
|
|
72775
|
-
const abs =
|
|
73226
|
+
const abs = import_node_path72.default.join(dir, rel);
|
|
72776
73227
|
const content = await import_promises12.default.readFile(abs);
|
|
72777
73228
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
72778
73229
|
}
|
|
@@ -72793,7 +73244,7 @@ async function listFilesSorted(rootDir) {
|
|
|
72793
73244
|
return out;
|
|
72794
73245
|
}
|
|
72795
73246
|
async function walk(absRoot, relPrefix, out) {
|
|
72796
|
-
const dirAbs =
|
|
73247
|
+
const dirAbs = import_node_path72.default.join(absRoot, relPrefix);
|
|
72797
73248
|
const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
|
|
72798
73249
|
for (const e of entries) {
|
|
72799
73250
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -72847,25 +73298,25 @@ function computePublishCheck(args) {
|
|
|
72847
73298
|
|
|
72848
73299
|
// src/extension/install-flow.ts
|
|
72849
73300
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
72850
|
-
var
|
|
72851
|
-
var
|
|
73301
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
73302
|
+
var import_node_os29 = __toESM(require("os"), 1);
|
|
72852
73303
|
var import_node_crypto23 = __toESM(require("crypto"), 1);
|
|
72853
73304
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
72854
73305
|
|
|
72855
73306
|
// src/extension/paths.ts
|
|
72856
|
-
var
|
|
72857
|
-
var
|
|
73307
|
+
var import_node_os28 = __toESM(require("os"), 1);
|
|
73308
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
72858
73309
|
function clawdHomeRoot(override) {
|
|
72859
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
73310
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path73.default.join(import_node_os28.default.homedir(), ".clawd");
|
|
72860
73311
|
}
|
|
72861
73312
|
function extensionsRoot(override) {
|
|
72862
|
-
return
|
|
73313
|
+
return import_node_path73.default.join(clawdHomeRoot(override), "extensions");
|
|
72863
73314
|
}
|
|
72864
73315
|
function publishedChannelsFile(override) {
|
|
72865
|
-
return
|
|
73316
|
+
return import_node_path73.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
72866
73317
|
}
|
|
72867
73318
|
function bundleCacheRoot(override) {
|
|
72868
|
-
return
|
|
73319
|
+
return import_node_path73.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
72869
73320
|
}
|
|
72870
73321
|
|
|
72871
73322
|
// src/extension/install-flow.ts
|
|
@@ -72892,7 +73343,7 @@ async function installFromChannel(args, deps) {
|
|
|
72892
73343
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
72893
73344
|
}
|
|
72894
73345
|
for (const name of Object.keys(zip.files)) {
|
|
72895
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73346
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path74.default.isAbsolute(name)) {
|
|
72896
73347
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
72897
73348
|
}
|
|
72898
73349
|
}
|
|
@@ -72924,7 +73375,7 @@ async function installFromChannel(args, deps) {
|
|
|
72924
73375
|
);
|
|
72925
73376
|
}
|
|
72926
73377
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
72927
|
-
const destDir =
|
|
73378
|
+
const destDir = import_node_path74.default.join(deps.extensionsRoot, localExtId);
|
|
72928
73379
|
let destExists = false;
|
|
72929
73380
|
try {
|
|
72930
73381
|
await import_promises13.default.access(destDir);
|
|
@@ -72938,16 +73389,16 @@ async function installFromChannel(args, deps) {
|
|
|
72938
73389
|
);
|
|
72939
73390
|
}
|
|
72940
73391
|
const stage = await import_promises13.default.mkdtemp(
|
|
72941
|
-
|
|
73392
|
+
import_node_path74.default.join(import_node_os29.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
72942
73393
|
);
|
|
72943
73394
|
try {
|
|
72944
73395
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
72945
|
-
const dest =
|
|
73396
|
+
const dest = import_node_path74.default.join(stage, name);
|
|
72946
73397
|
if (entry.dir) {
|
|
72947
73398
|
await import_promises13.default.mkdir(dest, { recursive: true });
|
|
72948
73399
|
continue;
|
|
72949
73400
|
}
|
|
72950
|
-
await import_promises13.default.mkdir(
|
|
73401
|
+
await import_promises13.default.mkdir(import_node_path74.default.dirname(dest), { recursive: true });
|
|
72951
73402
|
if (name === "manifest.json") {
|
|
72952
73403
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
72953
73404
|
await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -72968,8 +73419,8 @@ async function installFromChannel(args, deps) {
|
|
|
72968
73419
|
|
|
72969
73420
|
// src/extension/update-flow.ts
|
|
72970
73421
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
72971
|
-
var
|
|
72972
|
-
var
|
|
73422
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
73423
|
+
var import_node_os30 = __toESM(require("os"), 1);
|
|
72973
73424
|
var import_node_crypto24 = __toESM(require("crypto"), 1);
|
|
72974
73425
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
72975
73426
|
var UpdateError = class extends Error {
|
|
@@ -72985,11 +73436,11 @@ async function updateFromChannel(args, deps) {
|
|
|
72985
73436
|
channelRef.extId,
|
|
72986
73437
|
channelRef.ownerPrincipalId
|
|
72987
73438
|
);
|
|
72988
|
-
const liveDir =
|
|
73439
|
+
const liveDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
|
|
72989
73440
|
const prevDir = `${liveDir}.prev`;
|
|
72990
73441
|
let existingVersion;
|
|
72991
73442
|
try {
|
|
72992
|
-
const raw = await import_promises14.default.readFile(
|
|
73443
|
+
const raw = await import_promises14.default.readFile(import_node_path75.default.join(liveDir, "manifest.json"), "utf8");
|
|
72993
73444
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
72994
73445
|
if (!parsed2.success) {
|
|
72995
73446
|
throw new UpdateError(
|
|
@@ -73022,7 +73473,7 @@ async function updateFromChannel(args, deps) {
|
|
|
73022
73473
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
73023
73474
|
}
|
|
73024
73475
|
for (const name of Object.keys(zip.files)) {
|
|
73025
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73476
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
|
|
73026
73477
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
73027
73478
|
}
|
|
73028
73479
|
}
|
|
@@ -73057,16 +73508,16 @@ async function updateFromChannel(args, deps) {
|
|
|
73057
73508
|
await import_promises14.default.rm(prevDir, { recursive: true, force: true });
|
|
73058
73509
|
await import_promises14.default.rename(liveDir, prevDir);
|
|
73059
73510
|
const stage = await import_promises14.default.mkdtemp(
|
|
73060
|
-
|
|
73511
|
+
import_node_path75.default.join(import_node_os30.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
73061
73512
|
);
|
|
73062
73513
|
try {
|
|
73063
73514
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
73064
|
-
const dest =
|
|
73515
|
+
const dest = import_node_path75.default.join(stage, name);
|
|
73065
73516
|
if (entry.dir) {
|
|
73066
73517
|
await import_promises14.default.mkdir(dest, { recursive: true });
|
|
73067
73518
|
continue;
|
|
73068
73519
|
}
|
|
73069
|
-
await import_promises14.default.mkdir(
|
|
73520
|
+
await import_promises14.default.mkdir(import_node_path75.default.dirname(dest), { recursive: true });
|
|
73070
73521
|
if (name === "manifest.json") {
|
|
73071
73522
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
73072
73523
|
await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -73133,7 +73584,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73133
73584
|
);
|
|
73134
73585
|
}
|
|
73135
73586
|
}
|
|
73136
|
-
const manifestPath =
|
|
73587
|
+
const manifestPath = import_node_path76.default.join(root, extId, "manifest.json");
|
|
73137
73588
|
const manifest = await readManifest(root, extId);
|
|
73138
73589
|
const next = { ...manifest, version: newVersion };
|
|
73139
73590
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -73141,7 +73592,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73141
73592
|
await import_promises15.default.rename(tmp, manifestPath);
|
|
73142
73593
|
}
|
|
73143
73594
|
async function readManifest(root, extId) {
|
|
73144
|
-
const file =
|
|
73595
|
+
const file = import_node_path76.default.join(root, extId, "manifest.json");
|
|
73145
73596
|
let raw;
|
|
73146
73597
|
try {
|
|
73147
73598
|
raw = await import_promises15.default.readFile(file, "utf8");
|
|
@@ -73225,7 +73676,7 @@ function buildExtensionHandlers(deps) {
|
|
|
73225
73676
|
};
|
|
73226
73677
|
async function buildSnapshotMeta(extId) {
|
|
73227
73678
|
const manifest = await readManifest(deps.root, extId);
|
|
73228
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
73679
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path76.default.join(deps.root, extId));
|
|
73229
73680
|
return { manifest, contentHash: sha256, buffer };
|
|
73230
73681
|
}
|
|
73231
73682
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -74053,7 +74504,7 @@ function buildVisitorHandlers(deps) {
|
|
|
74053
74504
|
|
|
74054
74505
|
// src/extension/registry.ts
|
|
74055
74506
|
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
74056
|
-
var
|
|
74507
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
74057
74508
|
async function loadAll(root) {
|
|
74058
74509
|
let entries;
|
|
74059
74510
|
try {
|
|
@@ -74066,13 +74517,13 @@ async function loadAll(root) {
|
|
|
74066
74517
|
for (const ent of entries) {
|
|
74067
74518
|
if (!ent.isDirectory()) continue;
|
|
74068
74519
|
if (ent.name.startsWith(".")) continue;
|
|
74069
|
-
records.push(await loadOne(
|
|
74520
|
+
records.push(await loadOne(import_node_path77.default.join(root, ent.name), ent.name));
|
|
74070
74521
|
}
|
|
74071
74522
|
records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
|
|
74072
74523
|
return records;
|
|
74073
74524
|
}
|
|
74074
74525
|
async function loadOne(dir, dirName) {
|
|
74075
|
-
const manifestPath =
|
|
74526
|
+
const manifestPath = import_node_path77.default.join(dir, "manifest.json");
|
|
74076
74527
|
let raw;
|
|
74077
74528
|
try {
|
|
74078
74529
|
raw = await import_promises17.default.readFile(manifestPath, "utf8");
|
|
@@ -74117,7 +74568,7 @@ async function loadOne(dir, dirName) {
|
|
|
74117
74568
|
|
|
74118
74569
|
// src/extension/uninstall.ts
|
|
74119
74570
|
var import_promises18 = __toESM(require("fs/promises"), 1);
|
|
74120
|
-
var
|
|
74571
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
74121
74572
|
var UninstallError = class extends Error {
|
|
74122
74573
|
constructor(code, message) {
|
|
74123
74574
|
super(message);
|
|
@@ -74126,7 +74577,7 @@ var UninstallError = class extends Error {
|
|
|
74126
74577
|
code;
|
|
74127
74578
|
};
|
|
74128
74579
|
async function uninstall(deps) {
|
|
74129
|
-
const dir =
|
|
74580
|
+
const dir = import_node_path78.default.join(deps.root, deps.extId);
|
|
74130
74581
|
try {
|
|
74131
74582
|
await import_promises18.default.access(dir);
|
|
74132
74583
|
} catch {
|
|
@@ -74144,14 +74595,14 @@ init_protocol();
|
|
|
74144
74595
|
|
|
74145
74596
|
// src/peer-ops/run-command.ts
|
|
74146
74597
|
var import_node_child_process23 = require("child_process");
|
|
74147
|
-
var
|
|
74598
|
+
var import_node_os31 = __toESM(require("os"), 1);
|
|
74148
74599
|
var DEFAULT_TIMEOUT_MS6 = 3e4;
|
|
74149
74600
|
var MAX_TIMEOUT_MS = 3e5;
|
|
74150
74601
|
var MAX_OUTPUT_BYTES = 1048576;
|
|
74151
74602
|
function runCommand2(command, opts = {}) {
|
|
74152
74603
|
const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6, MAX_TIMEOUT_MS);
|
|
74153
74604
|
return new Promise((resolve9) => {
|
|
74154
|
-
const child = (0, import_node_child_process23.spawn)("bash", ["-c", command], { cwd:
|
|
74605
|
+
const child = (0, import_node_child_process23.spawn)("bash", ["-c", command], { cwd: import_node_os31.default.homedir() });
|
|
74155
74606
|
const out = [];
|
|
74156
74607
|
const err = [];
|
|
74157
74608
|
let outBytes = 0;
|
|
@@ -74264,7 +74715,9 @@ function ensureGuest(ctx) {
|
|
|
74264
74715
|
|
|
74265
74716
|
// src/handlers/index.ts
|
|
74266
74717
|
function buildMethodHandlers(deps) {
|
|
74718
|
+
const channelStore = deps.subscriptionChannelStore ?? new SubscriptionChannelStore({ dataDir: deps.dataDir ?? deps.masterDataDir });
|
|
74267
74719
|
const handlers = {
|
|
74720
|
+
...buildChannelsHandlers({ store: channelStore, manager: deps.manager }),
|
|
74268
74721
|
...buildSessionHandlers({
|
|
74269
74722
|
...deps,
|
|
74270
74723
|
getTunnelUrl: deps.getTunnelUrl,
|
|
@@ -74342,7 +74795,7 @@ function buildMethodHandlers(deps) {
|
|
|
74342
74795
|
broadcast: deps.broadcastToOwners
|
|
74343
74796
|
}),
|
|
74344
74797
|
...buildMasterHandlers({
|
|
74345
|
-
authorityTablePath:
|
|
74798
|
+
authorityTablePath: import_node_path79.default.join(deps.masterDataDir, "master-authority.json")
|
|
74346
74799
|
}),
|
|
74347
74800
|
...buildTopicHandlers({
|
|
74348
74801
|
topicStore: deps.topicStore,
|
|
@@ -74485,7 +74938,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
74485
74938
|
|
|
74486
74939
|
// src/extension/runtime.ts
|
|
74487
74940
|
var import_node_child_process24 = require("child_process");
|
|
74488
|
-
var
|
|
74941
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
74489
74942
|
var import_promises19 = require("timers/promises");
|
|
74490
74943
|
|
|
74491
74944
|
// src/extension/port-allocator.ts
|
|
@@ -74586,7 +75039,7 @@ var Runtime = class {
|
|
|
74586
75039
|
/\$CLAWOS_EXT_PORT/g,
|
|
74587
75040
|
String(port)
|
|
74588
75041
|
);
|
|
74589
|
-
const dir =
|
|
75042
|
+
const dir = import_node_path80.default.join(this.root, extId);
|
|
74590
75043
|
const env = {
|
|
74591
75044
|
...process.env,
|
|
74592
75045
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -74698,7 +75151,7 @@ ${handle.stderrTail}`
|
|
|
74698
75151
|
|
|
74699
75152
|
// src/extension/published-channels.ts
|
|
74700
75153
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
74701
|
-
var
|
|
75154
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
74702
75155
|
init_zod();
|
|
74703
75156
|
var PublishedChannelsError = class extends Error {
|
|
74704
75157
|
constructor(code, message) {
|
|
@@ -74797,7 +75250,7 @@ var PublishedChannelStore = class {
|
|
|
74797
75250
|
)
|
|
74798
75251
|
};
|
|
74799
75252
|
const tmp = `${this.filePath}.tmp`;
|
|
74800
|
-
await import_promises20.default.mkdir(
|
|
75253
|
+
await import_promises20.default.mkdir(import_node_path81.default.dirname(this.filePath), { recursive: true });
|
|
74801
75254
|
await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
74802
75255
|
await import_promises20.default.rename(tmp, this.filePath);
|
|
74803
75256
|
}
|
|
@@ -74805,7 +75258,7 @@ var PublishedChannelStore = class {
|
|
|
74805
75258
|
|
|
74806
75259
|
// src/extension/bundle-cache.ts
|
|
74807
75260
|
var import_promises21 = __toESM(require("fs/promises"), 1);
|
|
74808
|
-
var
|
|
75261
|
+
var import_node_path82 = __toESM(require("path"), 1);
|
|
74809
75262
|
var BundleCache = class {
|
|
74810
75263
|
constructor(rootDir) {
|
|
74811
75264
|
this.rootDir = rootDir;
|
|
@@ -74814,14 +75267,14 @@ var BundleCache = class {
|
|
|
74814
75267
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
74815
75268
|
async write(snapshotHash, buffer) {
|
|
74816
75269
|
await import_promises21.default.mkdir(this.rootDir, { recursive: true });
|
|
74817
|
-
const file =
|
|
75270
|
+
const file = import_node_path82.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
74818
75271
|
const tmp = `${file}.tmp`;
|
|
74819
75272
|
await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
|
|
74820
75273
|
await import_promises21.default.rename(tmp, file);
|
|
74821
75274
|
}
|
|
74822
75275
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
74823
75276
|
async read(snapshotHash) {
|
|
74824
|
-
const file =
|
|
75277
|
+
const file = import_node_path82.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
74825
75278
|
try {
|
|
74826
75279
|
return await import_promises21.default.readFile(file);
|
|
74827
75280
|
} catch (e) {
|
|
@@ -74831,7 +75284,7 @@ var BundleCache = class {
|
|
|
74831
75284
|
}
|
|
74832
75285
|
/** Idempotent — missing file is not an error. */
|
|
74833
75286
|
async delete(snapshotHash) {
|
|
74834
|
-
const file =
|
|
75287
|
+
const file = import_node_path82.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
74835
75288
|
await import_promises21.default.rm(file, { force: true });
|
|
74836
75289
|
}
|
|
74837
75290
|
};
|
|
@@ -74852,26 +75305,26 @@ async function startDaemon(config) {
|
|
|
74852
75305
|
},
|
|
74853
75306
|
source: "daemon",
|
|
74854
75307
|
sampling: logShippingCfg.sampling,
|
|
74855
|
-
homeDir:
|
|
75308
|
+
homeDir: import_node_os32.default.homedir()
|
|
74856
75309
|
});
|
|
74857
|
-
const logDir =
|
|
74858
|
-
|
|
75310
|
+
const logDir = import_node_path83.default.join(config.dataDir, "log");
|
|
75311
|
+
import_node_fs65.default.mkdirSync(logDir, { recursive: true });
|
|
74859
75312
|
const logger = createLogger({
|
|
74860
75313
|
level: config.logLevel,
|
|
74861
|
-
file:
|
|
75314
|
+
file: import_node_path83.default.join(logDir, "clawd.log"),
|
|
74862
75315
|
logClient
|
|
74863
75316
|
});
|
|
74864
75317
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
74865
75318
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
74866
|
-
file:
|
|
75319
|
+
file: import_node_path83.default.join(logDir, "screen-idle-probe.log"),
|
|
74867
75320
|
level: "debug"
|
|
74868
75321
|
});
|
|
74869
75322
|
logger.info("screen-idle probe logger enabled", {
|
|
74870
|
-
file:
|
|
75323
|
+
file: import_node_path83.default.join(logDir, "screen-idle-probe.log")
|
|
74871
75324
|
});
|
|
74872
75325
|
const CAP_TARGETS = [
|
|
74873
|
-
|
|
74874
|
-
|
|
75326
|
+
import_node_path83.default.join(logDir, "clawd.log"),
|
|
75327
|
+
import_node_path83.default.join(logDir, "screen-idle-probe.log")
|
|
74875
75328
|
];
|
|
74876
75329
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
74877
75330
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -74993,8 +75446,9 @@ async function startDaemon(config) {
|
|
|
74993
75446
|
const agents = new AgentsScanner();
|
|
74994
75447
|
const history = new ClaudeHistoryReader();
|
|
74995
75448
|
let transport = null;
|
|
74996
|
-
const personaStore = new PersonaStore(
|
|
74997
|
-
const
|
|
75449
|
+
const personaStore = new PersonaStore(import_node_path83.default.join(config.dataDir, "personas"));
|
|
75450
|
+
const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
|
|
75451
|
+
const usersRoot = import_node_path83.default.join(config.dataDir, "users");
|
|
74998
75452
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
74999
75453
|
if (defaultsRoot) {
|
|
75000
75454
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -75011,7 +75465,7 @@ async function startDaemon(config) {
|
|
|
75011
75465
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
75012
75466
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
75013
75467
|
const dispatchStore = createDispatchStore({
|
|
75014
|
-
filePath:
|
|
75468
|
+
filePath: import_node_path83.default.join(config.dataDir, "dispatch.json"),
|
|
75015
75469
|
now: () => Date.now(),
|
|
75016
75470
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
75017
75471
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -75020,7 +75474,7 @@ async function startDaemon(config) {
|
|
|
75020
75474
|
await dispatchStore.load();
|
|
75021
75475
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
75022
75476
|
const channelStore = createChannelStore({
|
|
75023
|
-
filePath:
|
|
75477
|
+
filePath: import_node_path83.default.join(config.dataDir, "channels.json"),
|
|
75024
75478
|
now: () => Date.now(),
|
|
75025
75479
|
genId: () => `ch-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75026
75480
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
@@ -75029,7 +75483,7 @@ async function startDaemon(config) {
|
|
|
75029
75483
|
});
|
|
75030
75484
|
await channelStore.load();
|
|
75031
75485
|
const topicStore = createTopicStore({
|
|
75032
|
-
filePath:
|
|
75486
|
+
filePath: import_node_path83.default.join(config.dataDir, "topics.json"),
|
|
75033
75487
|
now: () => Date.now(),
|
|
75034
75488
|
genId: () => `tp-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75035
75489
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
@@ -75056,12 +75510,12 @@ async function startDaemon(config) {
|
|
|
75056
75510
|
});
|
|
75057
75511
|
}
|
|
75058
75512
|
});
|
|
75059
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
75513
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path83.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
|
|
75060
75514
|
const mcpConfigs = [];
|
|
75061
75515
|
const secretsBundleRoot = findSecretsBundleRoot(logger);
|
|
75062
|
-
const localSecretsDir =
|
|
75516
|
+
const localSecretsDir = import_node_path83.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
75063
75517
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
75064
|
-
const githubTokenFile =
|
|
75518
|
+
const githubTokenFile = import_node_path83.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
|
|
75065
75519
|
const githubIdentity = createGithubIdentity({
|
|
75066
75520
|
resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
|
|
75067
75521
|
store: (token) => storeGithubAuth({
|
|
@@ -75099,22 +75553,22 @@ async function startDaemon(config) {
|
|
|
75099
75553
|
void githubIdentity.refresh();
|
|
75100
75554
|
return renderPersonaMcpSecrets({
|
|
75101
75555
|
personaId: personaId2,
|
|
75102
|
-
personaDir:
|
|
75556
|
+
personaDir: import_node_path83.default.join(config.dataDir, "personas", personaId2),
|
|
75103
75557
|
secrets,
|
|
75104
|
-
outDir:
|
|
75558
|
+
outDir: import_node_path83.default.join(config.dataDir, "persona-mcp"),
|
|
75105
75559
|
logger
|
|
75106
75560
|
});
|
|
75107
75561
|
};
|
|
75108
75562
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
75109
75563
|
const dispatchServerCandidates = [
|
|
75110
|
-
|
|
75564
|
+
import_node_path83.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
75111
75565
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
75112
|
-
|
|
75566
|
+
import_node_path83.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
75113
75567
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
75114
75568
|
];
|
|
75115
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) =>
|
|
75569
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75116
75570
|
if (dispatchServerScriptPath) {
|
|
75117
|
-
const dispatchLogPath =
|
|
75571
|
+
const dispatchLogPath = import_node_path83.default.join(logDir, "dispatch-mcp-server.log");
|
|
75118
75572
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
75119
75573
|
dataDir: config.dataDir,
|
|
75120
75574
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -75134,12 +75588,12 @@ async function startDaemon(config) {
|
|
|
75134
75588
|
});
|
|
75135
75589
|
}
|
|
75136
75590
|
const ticketServerCandidates = [
|
|
75137
|
-
|
|
75138
|
-
|
|
75591
|
+
import_node_path83.default.join(here, "ticket", "mcp-server.cjs"),
|
|
75592
|
+
import_node_path83.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
75139
75593
|
];
|
|
75140
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p3) =>
|
|
75594
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75141
75595
|
if (ticketServerScriptPath) {
|
|
75142
|
-
const ticketLogPath =
|
|
75596
|
+
const ticketLogPath = import_node_path83.default.join(logDir, "ticket-mcp-server.log");
|
|
75143
75597
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
75144
75598
|
dataDir: config.dataDir,
|
|
75145
75599
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -75161,12 +75615,12 @@ async function startDaemon(config) {
|
|
|
75161
75615
|
});
|
|
75162
75616
|
}
|
|
75163
75617
|
const shiftServerCandidates = [
|
|
75164
|
-
|
|
75165
|
-
|
|
75618
|
+
import_node_path83.default.join(here, "shift", "mcp-server.cjs"),
|
|
75619
|
+
import_node_path83.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
75166
75620
|
];
|
|
75167
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p3) =>
|
|
75621
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75168
75622
|
if (shiftServerScriptPath) {
|
|
75169
|
-
const shiftLogPath =
|
|
75623
|
+
const shiftLogPath = import_node_path83.default.join(logDir, "shift-mcp-server.log");
|
|
75170
75624
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
75171
75625
|
dataDir: config.dataDir,
|
|
75172
75626
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -75187,12 +75641,12 @@ async function startDaemon(config) {
|
|
|
75187
75641
|
);
|
|
75188
75642
|
}
|
|
75189
75643
|
const inboxServerCandidates = [
|
|
75190
|
-
|
|
75191
|
-
|
|
75644
|
+
import_node_path83.default.join(here, "inbox", "mcp-server.cjs"),
|
|
75645
|
+
import_node_path83.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
75192
75646
|
];
|
|
75193
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p3) =>
|
|
75647
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75194
75648
|
if (inboxServerScriptPath) {
|
|
75195
|
-
const inboxLogPath =
|
|
75649
|
+
const inboxLogPath = import_node_path83.default.join(logDir, "inbox-mcp-server.log");
|
|
75196
75650
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
75197
75651
|
dataDir: config.dataDir,
|
|
75198
75652
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -75213,10 +75667,10 @@ async function startDaemon(config) {
|
|
|
75213
75667
|
);
|
|
75214
75668
|
}
|
|
75215
75669
|
const peerOpsServerCandidates = [
|
|
75216
|
-
|
|
75217
|
-
|
|
75670
|
+
import_node_path83.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
75671
|
+
import_node_path83.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
75218
75672
|
];
|
|
75219
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) =>
|
|
75673
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75220
75674
|
if (peerOpsServerScriptPath) {
|
|
75221
75675
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
75222
75676
|
dataDir: config.dataDir,
|
|
@@ -75236,12 +75690,12 @@ async function startDaemon(config) {
|
|
|
75236
75690
|
);
|
|
75237
75691
|
}
|
|
75238
75692
|
const rpcToolServerCandidates = [
|
|
75239
|
-
|
|
75240
|
-
|
|
75693
|
+
import_node_path83.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
75694
|
+
import_node_path83.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
75241
75695
|
];
|
|
75242
|
-
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) =>
|
|
75696
|
+
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75243
75697
|
if (rpcToolServerScriptPath) {
|
|
75244
|
-
const rpcToolLogPath =
|
|
75698
|
+
const rpcToolLogPath = import_node_path83.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
75245
75699
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
75246
75700
|
dataDir: config.dataDir,
|
|
75247
75701
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -75262,7 +75716,7 @@ async function startDaemon(config) {
|
|
|
75262
75716
|
);
|
|
75263
75717
|
}
|
|
75264
75718
|
const shiftStore = createShiftStore({
|
|
75265
|
-
filePath:
|
|
75719
|
+
filePath: import_node_path83.default.join(config.dataDir, "shift.json"),
|
|
75266
75720
|
ownerIdProvider: () => ownerPrincipalId,
|
|
75267
75721
|
now: () => Date.now()
|
|
75268
75722
|
});
|
|
@@ -75284,7 +75738,7 @@ async function startDaemon(config) {
|
|
|
75284
75738
|
getAdapter,
|
|
75285
75739
|
historyReader: history,
|
|
75286
75740
|
dataDir: config.dataDir,
|
|
75287
|
-
personaRoot:
|
|
75741
|
+
personaRoot: import_node_path83.default.join(config.dataDir, "personas"),
|
|
75288
75742
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
75289
75743
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
75290
75744
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
@@ -75341,10 +75795,10 @@ async function startDaemon(config) {
|
|
|
75341
75795
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
75342
75796
|
attachmentGroup: {
|
|
75343
75797
|
onFileEdit: (input) => {
|
|
75344
|
-
const absPath =
|
|
75798
|
+
const absPath = import_node_path83.default.isAbsolute(input.relPath) ? input.relPath : import_node_path83.default.join(input.cwd, input.relPath);
|
|
75345
75799
|
let size = 0;
|
|
75346
75800
|
try {
|
|
75347
|
-
size =
|
|
75801
|
+
size = import_node_fs65.default.statSync(absPath).size;
|
|
75348
75802
|
} catch (err) {
|
|
75349
75803
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
75350
75804
|
sessionId: input.sessionId,
|
|
@@ -75385,9 +75839,9 @@ async function startDaemon(config) {
|
|
|
75385
75839
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
75386
75840
|
}
|
|
75387
75841
|
const projectsStore = new ProjectsStore({
|
|
75388
|
-
file:
|
|
75842
|
+
file: import_node_path83.default.join(config.dataDir, "projects.json"),
|
|
75389
75843
|
clawdDir: config.dataDir,
|
|
75390
|
-
codexStateFile:
|
|
75844
|
+
codexStateFile: import_node_path83.default.join(import_node_os32.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
75391
75845
|
logger
|
|
75392
75846
|
});
|
|
75393
75847
|
const observer = new SessionObserver({
|
|
@@ -75452,13 +75906,13 @@ async function startDaemon(config) {
|
|
|
75452
75906
|
logger
|
|
75453
75907
|
});
|
|
75454
75908
|
registerAdapter("claude", claudeAdapter);
|
|
75455
|
-
const codexIsolatedHome =
|
|
75909
|
+
const codexIsolatedHome = import_node_path83.default.join(config.dataDir, "codex-home");
|
|
75456
75910
|
try {
|
|
75457
|
-
|
|
75911
|
+
import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
75458
75912
|
for (const f2 of ["auth.json", "config.toml"]) {
|
|
75459
|
-
const link =
|
|
75460
|
-
const target =
|
|
75461
|
-
if (!
|
|
75913
|
+
const link = import_node_path83.default.join(codexIsolatedHome, f2);
|
|
75914
|
+
const target = import_node_path83.default.join(import_node_os32.default.homedir(), ".codex", f2);
|
|
75915
|
+
if (!import_node_fs65.default.existsSync(link) && import_node_fs65.default.existsSync(target)) import_node_fs65.default.symlinkSync(target, link);
|
|
75462
75916
|
}
|
|
75463
75917
|
} catch (err) {
|
|
75464
75918
|
logger.warn("codex isolated home setup failed", { err: String(err) });
|
|
@@ -75469,17 +75923,17 @@ async function startDaemon(config) {
|
|
|
75469
75923
|
logger,
|
|
75470
75924
|
historyReader: new CodexHistoryReader({
|
|
75471
75925
|
roots: codexRolloutRoots(config.dataDir),
|
|
75472
|
-
sharedHome:
|
|
75926
|
+
sharedHome: import_node_path83.default.join(import_node_os32.default.homedir(), ".codex"),
|
|
75473
75927
|
logger
|
|
75474
75928
|
}),
|
|
75475
75929
|
// projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
|
|
75476
75930
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
75477
75931
|
cwd,
|
|
75478
|
-
personaRoot:
|
|
75932
|
+
personaRoot: import_node_path83.default.join(config.dataDir, "personas"),
|
|
75479
75933
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
75480
75934
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
75481
75935
|
projectPaths: projectsStore.listMerged().map((x2) => x2.path),
|
|
75482
|
-
sharedHome:
|
|
75936
|
+
sharedHome: import_node_path83.default.join(import_node_os32.default.homedir(), ".codex"),
|
|
75483
75937
|
isolatedHome: codexIsolatedHome
|
|
75484
75938
|
}),
|
|
75485
75939
|
// 附件图片验签:与 http-router /files 路由同一把 secret
|
|
@@ -75504,10 +75958,10 @@ async function startDaemon(config) {
|
|
|
75504
75958
|
);
|
|
75505
75959
|
registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
|
|
75506
75960
|
const piMcpBridgeCandidates = [
|
|
75507
|
-
|
|
75508
|
-
|
|
75961
|
+
import_node_path83.default.join(here, "pi-mcp-bridge", "extension.cjs"),
|
|
75962
|
+
import_node_path83.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
|
|
75509
75963
|
];
|
|
75510
|
-
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) =>
|
|
75964
|
+
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
75511
75965
|
if (piMcpBridgePath) {
|
|
75512
75966
|
logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
|
|
75513
75967
|
} else {
|
|
@@ -75724,6 +76178,7 @@ async function startDaemon(config) {
|
|
|
75724
76178
|
topicStore,
|
|
75725
76179
|
dispatchStore,
|
|
75726
76180
|
masterDataDir: config.dataDir,
|
|
76181
|
+
subscriptionChannelStore,
|
|
75727
76182
|
// 建话题即起该话题的 Master session(1:1)。走与 session:create 同一条 manager.create
|
|
75728
76183
|
// 链路,不复制会话创建逻辑;creatorPrincipalId 用本机 deviceId(owner ctx 的 principal.id)。
|
|
75729
76184
|
createMasterSession: ({ label }) => {
|
|
@@ -75802,11 +76257,11 @@ async function startDaemon(config) {
|
|
|
75802
76257
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
75803
76258
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
75804
76259
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
75805
|
-
personaRoot:
|
|
76260
|
+
personaRoot: import_node_path83.default.join(config.dataDir, "personas"),
|
|
75806
76261
|
usersRoot
|
|
75807
76262
|
},
|
|
75808
76263
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
75809
|
-
personaRoot:
|
|
76264
|
+
personaRoot: import_node_path83.default.join(config.dataDir, "personas"),
|
|
75810
76265
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
75811
76266
|
usersRoot,
|
|
75812
76267
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -75952,7 +76407,7 @@ async function startDaemon(config) {
|
|
|
75952
76407
|
sourceSessionId: args.sourceSessionId
|
|
75953
76408
|
});
|
|
75954
76409
|
const sourceFile = manager.findOwnedSession(args.sourceSessionId);
|
|
75955
|
-
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile,
|
|
76410
|
+
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os32.default.homedir());
|
|
75956
76411
|
logger.info("dispatch.spawnB.source-resolved", {
|
|
75957
76412
|
dispatchId: args.dispatchId,
|
|
75958
76413
|
sourceJsonlPath,
|
|
@@ -76027,6 +76482,7 @@ async function startDaemon(config) {
|
|
|
76027
76482
|
}
|
|
76028
76483
|
let lastPathRefresh = 0;
|
|
76029
76484
|
const deployHandlers = buildDeployHandlers({
|
|
76485
|
+
channelStore: subscriptionChannelStore,
|
|
76030
76486
|
hasPersona: (personaId2) => personaStore.has(personaId2),
|
|
76031
76487
|
personaDir: (personaId2) => personaStore.personaDirPath(personaId2),
|
|
76032
76488
|
// 发布前落闸要看它现在配的引擎和模型(云上只跑 codex / pi,且模型跟着这次发布走)
|
|
@@ -76111,7 +76567,7 @@ async function startDaemon(config) {
|
|
|
76111
76567
|
});
|
|
76112
76568
|
shiftScheduler.start();
|
|
76113
76569
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
76114
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
76570
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path83.default.join(config.dataDir, "personas"));
|
|
76115
76571
|
const larkBotCloud = createLarkBotCloudClient({
|
|
76116
76572
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
76117
76573
|
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
|
|
@@ -76123,7 +76579,7 @@ async function startDaemon(config) {
|
|
|
76123
76579
|
store: larkBotStore,
|
|
76124
76580
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
76125
76581
|
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
76126
|
-
mediaRootFor: (chatId) =>
|
|
76582
|
+
mediaRootFor: (chatId) => import_node_path83.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
76127
76583
|
isShuttingDown: () => larkDraining,
|
|
76128
76584
|
logger: {
|
|
76129
76585
|
warn: (msg) => logger.warn(msg),
|
|
@@ -76423,8 +76879,8 @@ async function startDaemon(config) {
|
|
|
76423
76879
|
const lines = [
|
|
76424
76880
|
`Tunnel: ${r2.url}`,
|
|
76425
76881
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
76426
|
-
`Frpc config: ${
|
|
76427
|
-
`Frpc log: ${
|
|
76882
|
+
`Frpc config: ${import_node_path83.default.join(config.dataDir, "frpc.toml")}`,
|
|
76883
|
+
`Frpc log: ${import_node_path83.default.join(logDir, "frpc.log")}`
|
|
76428
76884
|
];
|
|
76429
76885
|
const width2 = Math.max(...lines.map((l2) => l2.length));
|
|
76430
76886
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -76437,8 +76893,8 @@ ${bar}
|
|
|
76437
76893
|
|
|
76438
76894
|
`);
|
|
76439
76895
|
try {
|
|
76440
|
-
const connectPath =
|
|
76441
|
-
|
|
76896
|
+
const connectPath = import_node_path83.default.join(config.dataDir, "connect.txt");
|
|
76897
|
+
import_node_fs65.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
76442
76898
|
} catch {
|
|
76443
76899
|
}
|
|
76444
76900
|
} catch (err) {
|
|
@@ -76536,9 +76992,9 @@ ${bar}
|
|
|
76536
76992
|
};
|
|
76537
76993
|
}
|
|
76538
76994
|
function migrateDropPersonsDir(dataDir) {
|
|
76539
|
-
const dir =
|
|
76995
|
+
const dir = import_node_path83.default.join(dataDir, "persons");
|
|
76540
76996
|
try {
|
|
76541
|
-
|
|
76997
|
+
import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
|
|
76542
76998
|
} catch {
|
|
76543
76999
|
}
|
|
76544
77000
|
}
|