@clawos-dev/clawd 0.2.589 → 0.2.591
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 +1043 -649
- 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-BQhCFqx5.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-CY5N5r-U.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: path104, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path104, ...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, path104, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path104;
|
|
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 path104 = req.path;
|
|
10329
|
+
_req.url = typeof path104 === "string" ? path104 : 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(path104) {
|
|
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 < path104.length; i2++) {
|
|
10501
|
+
const char = path104[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 path104 of paths) {
|
|
10633
|
+
const parts = parsePath(path104);
|
|
10546
10634
|
if (parts.includes("*")) {
|
|
10547
|
-
redactWildcardPath(obj, parts, censor,
|
|
10635
|
+
redactWildcardPath(obj, parts, censor, path104, 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, path104) => {
|
|
10721
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path104];
|
|
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 path104 of pathsToClone) {
|
|
10757
|
+
const parts = parsePath(path104);
|
|
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(path104) {
|
|
10810
|
+
if (typeof path104 !== "string") {
|
|
10723
10811
|
throw new Error("Paths must be (non-empty) strings");
|
|
10724
10812
|
}
|
|
10725
|
-
if (
|
|
10813
|
+
if (path104 === "") {
|
|
10726
10814
|
throw new Error("Invalid redaction path ()");
|
|
10727
10815
|
}
|
|
10728
|
-
if (
|
|
10729
|
-
throw new Error(`Invalid redaction path (${
|
|
10816
|
+
if (path104.includes("..")) {
|
|
10817
|
+
throw new Error(`Invalid redaction path (${path104})`);
|
|
10730
10818
|
}
|
|
10731
|
-
if (
|
|
10732
|
-
throw new Error(`Invalid redaction path (${
|
|
10819
|
+
if (path104.includes(",")) {
|
|
10820
|
+
throw new Error(`Invalid redaction path (${path104})`);
|
|
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 < path104.length; i2++) {
|
|
10826
|
+
const char = path104[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 (${path104})`);
|
|
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 (${path104})`);
|
|
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 path104 of paths) {
|
|
10853
|
+
validatePath(path104);
|
|
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, path104) => {
|
|
11022
|
+
return censor(value, [k3, ...path104]);
|
|
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 fs94 = require("fs");
|
|
11153
11241
|
var EventEmitter2 = require("events");
|
|
11154
11242
|
var inherits = require("util").inherits;
|
|
11155
|
-
var
|
|
11243
|
+
var path104 = 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) fs94.mkdirSync(path104.dirname(file), { recursive: true });
|
|
11298
|
+
const fd = fs94.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
|
+
fs94.mkdir(path104.dirname(file), { recursive: true }, (err) => {
|
|
11218
11306
|
if (err) return fileOpened(err);
|
|
11219
|
-
|
|
11307
|
+
fs94.open(file, flags, mode, fileOpened);
|
|
11220
11308
|
});
|
|
11221
11309
|
} else {
|
|
11222
|
-
|
|
11310
|
+
fs94.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 = () => fs94.writeSync(this.fd, this._writingBuf);
|
|
11352
|
+
fsWrite = () => fs94.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 fs94.writeSync(this.fd, this._writingBuf);
|
|
11274
11362
|
}
|
|
11275
|
-
return
|
|
11363
|
+
return fs94.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11276
11364
|
};
|
|
11277
11365
|
fsWrite = () => {
|
|
11278
11366
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11279
|
-
return
|
|
11367
|
+
return fs94.write(this.fd, this._writingBuf, this.release);
|
|
11280
11368
|
}
|
|
11281
|
-
return
|
|
11369
|
+
return fs94.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
|
+
fs94.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
|
+
fs94.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
|
+
fs94.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) ? fs94.writeSync(this.fd, buf) : fs94.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
|
+
fs94.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 = fs94.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) ? fs94.writeSync(this.fd, this._writingBuf) : fs94.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
|
+
fs94.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 = fs94.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
|
+
fs94.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
|
+
fs94.fsync(sonic.fd, closeWrapped);
|
|
11709
11797
|
} catch {
|
|
11710
11798
|
}
|
|
11711
11799
|
function closeWrapped() {
|
|
11712
11800
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
11713
|
-
|
|
11801
|
+
fs94.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 os36 = 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 = os36.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(path104, added, removed, oldPosInc, options) {
|
|
14937
|
+
var last = path104.lastComponent;
|
|
14850
14938
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14851
14939
|
return {
|
|
14852
|
-
oldPos:
|
|
14940
|
+
oldPos: path104.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: path104.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 path104 = 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 (!path104 || content == null) return null;
|
|
15535
|
+
const entry = { path: path104, 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 path104 = 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 (!path104 || content == null) return null;
|
|
16404
|
+
const out = { path: path104, 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(path104) {
|
|
37379
|
+
var parts = path104.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(path104) {
|
|
43233
|
+
if (path104.slice(-1) === "/") {
|
|
43234
|
+
path104 = path104.substring(0, path104.length - 1);
|
|
43147
43235
|
}
|
|
43148
|
-
var lastSlash =
|
|
43149
|
-
return lastSlash > 0 ?
|
|
43236
|
+
var lastSlash = path104.lastIndexOf("/");
|
|
43237
|
+
return lastSlash > 0 ? path104.substring(0, lastSlash) : "";
|
|
43150
43238
|
};
|
|
43151
|
-
var forceTrailingSlash = function(
|
|
43152
|
-
if (
|
|
43153
|
-
|
|
43239
|
+
var forceTrailingSlash = function(path104) {
|
|
43240
|
+
if (path104.slice(-1) !== "/") {
|
|
43241
|
+
path104 += "/";
|
|
43154
43242
|
}
|
|
43155
|
-
return
|
|
43243
|
+
return path104;
|
|
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_path83.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_fs65.default.mkdirSync(dir, { recursive: true });
|
|
44260
|
+
stream = import_node_fs65.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_fs65, import_node_path83;
|
|
44198
44286
|
var init_recorder = __esm({
|
|
44199
44287
|
"src/run-case/recorder.ts"() {
|
|
44200
44288
|
"use strict";
|
|
44201
|
-
|
|
44202
|
-
|
|
44289
|
+
import_node_fs65 = __toESM(require("fs"), 1);
|
|
44290
|
+
import_node_path83 = __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_fs66.mkdtempSync)(import_node_path84.default.join(import_node_os32.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_fs66.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_fs66, import_node_os32, import_node_path84;
|
|
44413
44501
|
var init_controller = __esm({
|
|
44414
44502
|
"src/run-case/controller.ts"() {
|
|
44415
44503
|
"use strict";
|
|
44416
|
-
|
|
44417
|
-
|
|
44418
|
-
|
|
44504
|
+
import_node_fs66 = require("fs");
|
|
44505
|
+
import_node_os32 = __toESM(require("os"), 1);
|
|
44506
|
+
import_node_path84 = __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_path82 = __toESM(require("path"), 1);
|
|
44779
|
+
var import_node_fs64 = __toESM(require("fs"), 1);
|
|
44780
|
+
var import_node_os31 = __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, path104, init) {
|
|
52439
52527
|
const f2 = opts.fetchImpl ?? globalThis.fetch;
|
|
52440
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52528
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path104}`;
|
|
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, path104] = m3;
|
|
53563
|
+
items.push({ type: "skill", name, path: path104 });
|
|
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, path104, body) {
|
|
60843
60937
|
let res;
|
|
60844
60938
|
try {
|
|
60845
|
-
res = await doFetch(`${API}${
|
|
60939
|
+
res = await doFetch(`${API}${path104}`, {
|
|
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, path104, what, body) {
|
|
60965
|
+
const r2 = await request(method, path104, 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(path104) {
|
|
60917
61011
|
try {
|
|
60918
|
-
const r2 = await request("GET",
|
|
61012
|
+
const r2 = await request("GET", path104);
|
|
60919
61013
|
return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
|
|
60920
61014
|
} catch {
|
|
60921
61015
|
return void 0;
|
|
@@ -61654,7 +61748,7 @@ function ensureOwner(ctx) {
|
|
|
61654
61748
|
}
|
|
61655
61749
|
var invalid = (msg) => new ClawdError(ERROR_CODES.VALIDATION_ERROR, `VALIDATION_ERROR: ${msg}`);
|
|
61656
61750
|
function wrongEngine(tool) {
|
|
61657
|
-
return cloudEngineOk(tool) ? void 0 : `\u5F15\u64CE\u662F ${tool || "claude"}\uFF0C\u4E91\u4E0A\u53EA\u8DD1 Codex \u6216 pi\u2014\u2014\
|
|
61751
|
+
return cloudEngineOk(tool) ? void 0 : `\u5F15\u64CE\u662F ${tool || "claude"}\uFF0C\u4E91\u4E0A\u53EA\u8DD1 Codex \u6216 pi\u2014\u2014\u5728\u4E0A\u4E91\u9875\u300C\u5F15\u64CE\u4E0E\u6A21\u578B\u300D\u91CC\u9009 Codex \u6216 pi\uFF0C\u518D\u9009\u4E2A\u6A21\u578B`;
|
|
61658
61752
|
}
|
|
61659
61753
|
var NO_GITHUB_AUTH = "\u8FD8\u6CA1\u5173\u8054 GitHub\uFF1A\u5728\u8BBE\u7F6E \u2192 \u8D26\u53F7\uFF08\u6216\u4E0A\u4E91\u9875\u9876\u4E0A\u90A3\u5F20\u5361\uFF09\u91CC\u70B9\u300C\u5173\u8054 GitHub\u300D";
|
|
61660
61754
|
function toClawdError(err) {
|
|
@@ -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]];
|
|
@@ -62085,7 +62185,7 @@ function buildDeployHandlers(deps) {
|
|
|
62085
62185
|
for (const c2 of entry.manifest.connectors) blockers.push(...connectorBlockers(c2));
|
|
62086
62186
|
for (const p3 of entry.manifest.packages) blockers.push(...packageBlockers(p3));
|
|
62087
62187
|
if (!deps.personaEngine(personaId2)?.model) {
|
|
62088
|
-
blockers.push("\u8FD8\u6CA1\u9009\u6A21\u578B\uFF08\u5207\u5F15\u64CE\u65F6\u4F1A\u6E05\u7A7A\uFF09\u2014\u2014\
|
|
62188
|
+
blockers.push("\u8FD8\u6CA1\u9009\u6A21\u578B\uFF08\u5207\u5F15\u64CE\u65F6\u4F1A\u6E05\u7A7A\uFF09\u2014\u2014\u5728\u4E0A\u4E91\u9875\u300C\u5F15\u64CE\u4E0E\u6A21\u578B\u300D\u91CC\u9009\u4E00\u4E2A");
|
|
62089
62189
|
}
|
|
62090
62190
|
if (blockers.length > 0) throw invalid(`\u8FD8\u5DEE\uFF1A${blockers.join("\uFF1B")}`);
|
|
62091
62191
|
const before = await readDeployFileRaw(dir);
|
|
@@ -62166,6 +62266,168 @@ 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
|
+
var SubscriptionChannelStore = class {
|
|
62275
|
+
filePath;
|
|
62276
|
+
codexHome;
|
|
62277
|
+
constructor(options) {
|
|
62278
|
+
this.filePath = import_node_path40.default.join(options.dataDir, CHANNELS_FILE_NAME);
|
|
62279
|
+
this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path40.default.join(import_node_os12.default.homedir(), ".codex");
|
|
62280
|
+
}
|
|
62281
|
+
/** 获取列表与激活通道 ID(Key 经脱敏掩码) */
|
|
62282
|
+
list() {
|
|
62283
|
+
const data = this.readOrCreate();
|
|
62284
|
+
return {
|
|
62285
|
+
activeChannelId: data.activeChannelId,
|
|
62286
|
+
channels: data.channels.map(toChannelView)
|
|
62287
|
+
};
|
|
62288
|
+
}
|
|
62289
|
+
/** 获取通道原始实体(含明文 Key,供配置应用与部署写入使用) */
|
|
62290
|
+
get(id) {
|
|
62291
|
+
const data = this.readOrCreate();
|
|
62292
|
+
return data.channels.find((c2) => c2.id === id) ?? null;
|
|
62293
|
+
}
|
|
62294
|
+
/** 获取当前激活的通道实体 */
|
|
62295
|
+
getActive() {
|
|
62296
|
+
const data = this.readOrCreate();
|
|
62297
|
+
if (!data.activeChannelId) return null;
|
|
62298
|
+
return data.channels.find((c2) => c2.id === data.activeChannelId) ?? null;
|
|
62299
|
+
}
|
|
62300
|
+
/** 保存(新增或更新)通道 */
|
|
62301
|
+
save(input) {
|
|
62302
|
+
const name = input.name.trim();
|
|
62303
|
+
if (!name) throw new Error("\u901A\u9053\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
62304
|
+
let baseUrl;
|
|
62305
|
+
try {
|
|
62306
|
+
baseUrl = normalizeEngineBaseUrl(input.baseUrl);
|
|
62307
|
+
} catch (err) {
|
|
62308
|
+
throw new Error(err instanceof Error ? err.message : String(err));
|
|
62309
|
+
}
|
|
62310
|
+
const data = this.readOrCreate();
|
|
62311
|
+
const now = Date.now();
|
|
62312
|
+
if (input.id) {
|
|
62313
|
+
const idx = data.channels.findIndex((c2) => c2.id === input.id);
|
|
62314
|
+
if (idx === -1) throw new Error(`\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u901A\u9053`);
|
|
62315
|
+
const existing = data.channels[idx];
|
|
62316
|
+
const apiKey2 = input.apiKey && input.apiKey.trim() ? input.apiKey.trim() : existing.apiKey;
|
|
62317
|
+
const updated = {
|
|
62318
|
+
...existing,
|
|
62319
|
+
name,
|
|
62320
|
+
baseUrl,
|
|
62321
|
+
apiKey: apiKey2,
|
|
62322
|
+
...input.remark !== void 0 ? { remark: input.remark.trim() || void 0 } : {},
|
|
62323
|
+
updatedAt: now
|
|
62324
|
+
};
|
|
62325
|
+
data.channels[idx] = updated;
|
|
62326
|
+
this.write(data);
|
|
62327
|
+
return updated;
|
|
62328
|
+
}
|
|
62329
|
+
const apiKey = input.apiKey?.trim();
|
|
62330
|
+
if (!apiKey) throw new Error("\u65B0\u5EFA\u901A\u9053\u5FC5\u987B\u586B\u5199 API Key");
|
|
62331
|
+
const newId = `chan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
|
|
62332
|
+
const newChannel = {
|
|
62333
|
+
id: newId,
|
|
62334
|
+
name,
|
|
62335
|
+
baseUrl,
|
|
62336
|
+
apiKey,
|
|
62337
|
+
...input.remark && input.remark.trim() ? { remark: input.remark.trim() } : {},
|
|
62338
|
+
createdAt: now,
|
|
62339
|
+
updatedAt: now
|
|
62340
|
+
};
|
|
62341
|
+
data.channels.push(newChannel);
|
|
62342
|
+
if (data.channels.length === 1 && !data.activeChannelId) {
|
|
62343
|
+
data.activeChannelId = newChannel.id;
|
|
62344
|
+
}
|
|
62345
|
+
this.write(data);
|
|
62346
|
+
return newChannel;
|
|
62347
|
+
}
|
|
62348
|
+
/** 删除通道 */
|
|
62349
|
+
delete(id) {
|
|
62350
|
+
const data = this.readOrCreate();
|
|
62351
|
+
const filtered = data.channels.filter((c2) => c2.id !== id);
|
|
62352
|
+
if (filtered.length === data.channels.length) return;
|
|
62353
|
+
data.channels = filtered;
|
|
62354
|
+
if (data.activeChannelId === id) {
|
|
62355
|
+
data.activeChannelId = data.channels.length > 0 ? data.channels[0].id : null;
|
|
62356
|
+
}
|
|
62357
|
+
this.write(data);
|
|
62358
|
+
}
|
|
62359
|
+
/** 设置当前激活通道(id 为 null 表示停用所有通道) */
|
|
62360
|
+
setActive(id) {
|
|
62361
|
+
const data = this.readOrCreate();
|
|
62362
|
+
if (id === null) {
|
|
62363
|
+
data.activeChannelId = null;
|
|
62364
|
+
this.write(data);
|
|
62365
|
+
return null;
|
|
62366
|
+
}
|
|
62367
|
+
const target = data.channels.find((c2) => c2.id === id);
|
|
62368
|
+
if (!target) throw new Error(`\u901A\u9053 ${id} \u4E0D\u5B58\u5728`);
|
|
62369
|
+
data.activeChannelId = id;
|
|
62370
|
+
this.write(data);
|
|
62371
|
+
return target;
|
|
62372
|
+
}
|
|
62373
|
+
readOrCreate() {
|
|
62374
|
+
if (import_node_fs35.default.existsSync(this.filePath)) {
|
|
62375
|
+
try {
|
|
62376
|
+
const raw = JSON.parse(import_node_fs35.default.readFileSync(this.filePath, "utf8"));
|
|
62377
|
+
if (raw && Array.isArray(raw.channels)) {
|
|
62378
|
+
return {
|
|
62379
|
+
activeChannelId: typeof raw.activeChannelId === "string" ? raw.activeChannelId : null,
|
|
62380
|
+
channels: raw.channels
|
|
62381
|
+
};
|
|
62382
|
+
}
|
|
62383
|
+
} catch {
|
|
62384
|
+
}
|
|
62385
|
+
}
|
|
62386
|
+
const migrated = this.tryMigrateFromCodexConfig();
|
|
62387
|
+
const initial = migrated ?? {
|
|
62388
|
+
activeChannelId: null,
|
|
62389
|
+
channels: []
|
|
62390
|
+
};
|
|
62391
|
+
this.write(initial);
|
|
62392
|
+
return initial;
|
|
62393
|
+
}
|
|
62394
|
+
tryMigrateFromCodexConfig() {
|
|
62395
|
+
try {
|
|
62396
|
+
const configPath = import_node_path40.default.join(this.codexHome, "config.toml");
|
|
62397
|
+
if (!import_node_fs35.default.existsSync(configPath)) return null;
|
|
62398
|
+
const content = import_node_fs35.default.readFileSync(configPath, "utf8");
|
|
62399
|
+
if (!content.includes('model_provider = "cliproxyapi"')) return null;
|
|
62400
|
+
const urlMatch = /base_url\s*=\s*["']([^"']+)["']/.exec(content);
|
|
62401
|
+
const keyMatch = /args\s*=\s*\[\s*["']([^"']+)["']\s*\]/.exec(content) || /experimental_bearer_token\s*=\s*["']([^"']+)["']/.exec(content);
|
|
62402
|
+
if (urlMatch && keyMatch) {
|
|
62403
|
+
const id = "default-pool";
|
|
62404
|
+
const channel = {
|
|
62405
|
+
id,
|
|
62406
|
+
name: "\u9ED8\u8BA4\u56E2\u961F\u53F7\u6C60",
|
|
62407
|
+
baseUrl: normalizeEngineBaseUrl(urlMatch[1]),
|
|
62408
|
+
apiKey: keyMatch[1],
|
|
62409
|
+
remark: "\u4ECE\u672C\u673A\u5DF2\u63A5\u5165\u7684\u53F7\u6C60\u914D\u7F6E\u81EA\u52A8\u8FC1\u79FB",
|
|
62410
|
+
createdAt: Date.now(),
|
|
62411
|
+
updatedAt: Date.now()
|
|
62412
|
+
};
|
|
62413
|
+
return {
|
|
62414
|
+
activeChannelId: id,
|
|
62415
|
+
channels: [channel]
|
|
62416
|
+
};
|
|
62417
|
+
}
|
|
62418
|
+
} catch {
|
|
62419
|
+
}
|
|
62420
|
+
return null;
|
|
62421
|
+
}
|
|
62422
|
+
write(data) {
|
|
62423
|
+
const dir = import_node_path40.default.dirname(this.filePath);
|
|
62424
|
+
import_node_fs35.default.mkdirSync(dir, { recursive: true });
|
|
62425
|
+
const tmp = `${this.filePath}.tmp.${Date.now()}`;
|
|
62426
|
+
import_node_fs35.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
62427
|
+
import_node_fs35.default.renameSync(tmp, this.filePath);
|
|
62428
|
+
}
|
|
62429
|
+
};
|
|
62430
|
+
|
|
62169
62431
|
// src/deploy/local-probe.ts
|
|
62170
62432
|
function pickVersion(s2) {
|
|
62171
62433
|
return /(\d+)\.(\d+)(?:\.(\d+))?/.exec(s2)?.[0];
|
|
@@ -62214,18 +62476,18 @@ async function probeLocalVersion(exec, pkg) {
|
|
|
62214
62476
|
|
|
62215
62477
|
// src/tools/shell-path.ts
|
|
62216
62478
|
var import_node_child_process10 = require("child_process");
|
|
62217
|
-
var
|
|
62479
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
62218
62480
|
function refreshPathFromLoginShell() {
|
|
62219
62481
|
if (process.platform === "win32") return;
|
|
62220
|
-
const shell = process.env.SHELL ??
|
|
62482
|
+
const shell = process.env.SHELL ?? import_node_os13.default.userInfo().shell ?? "/bin/zsh";
|
|
62221
62483
|
try {
|
|
62222
62484
|
const out = (0, import_node_child_process10.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
|
|
62223
62485
|
encoding: "utf8",
|
|
62224
62486
|
timeout: 3e3,
|
|
62225
62487
|
stdio: ["ignore", "pipe", "ignore"]
|
|
62226
62488
|
});
|
|
62227
|
-
const
|
|
62228
|
-
if (
|
|
62489
|
+
const path104 = out.trim();
|
|
62490
|
+
if (path104) process.env.PATH = path104;
|
|
62229
62491
|
} catch {
|
|
62230
62492
|
}
|
|
62231
62493
|
}
|
|
@@ -62763,15 +63025,15 @@ async function refreshTunnelUrlOnStartup(deps) {
|
|
|
62763
63025
|
}
|
|
62764
63026
|
|
|
62765
63027
|
// src/lark-bot-connector/binding-store.ts
|
|
62766
|
-
var
|
|
62767
|
-
var
|
|
63028
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
63029
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
62768
63030
|
function createLarkBotBindingStore(personaRoot) {
|
|
62769
|
-
const filePath = (personaId2) =>
|
|
63031
|
+
const filePath = (personaId2) => import_node_path41.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
|
|
62770
63032
|
const read = (personaId2) => {
|
|
62771
63033
|
const file = filePath(personaId2);
|
|
62772
|
-
if (!
|
|
63034
|
+
if (!import_node_fs36.default.existsSync(file)) return null;
|
|
62773
63035
|
try {
|
|
62774
|
-
const raw = JSON.parse(
|
|
63036
|
+
const raw = JSON.parse(import_node_fs36.default.readFileSync(file, "utf8"));
|
|
62775
63037
|
if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
|
|
62776
63038
|
return raw;
|
|
62777
63039
|
} catch {
|
|
@@ -62780,16 +63042,16 @@ function createLarkBotBindingStore(personaRoot) {
|
|
|
62780
63042
|
};
|
|
62781
63043
|
const write = (personaId2, meta) => {
|
|
62782
63044
|
const file = filePath(personaId2);
|
|
62783
|
-
|
|
63045
|
+
import_node_fs36.default.mkdirSync(import_node_path41.default.dirname(file), { recursive: true });
|
|
62784
63046
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
62785
|
-
|
|
62786
|
-
|
|
63047
|
+
import_node_fs36.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
|
|
63048
|
+
import_node_fs36.default.renameSync(tmp, file);
|
|
62787
63049
|
};
|
|
62788
63050
|
return {
|
|
62789
63051
|
read,
|
|
62790
63052
|
write,
|
|
62791
63053
|
remove(personaId2) {
|
|
62792
|
-
|
|
63054
|
+
import_node_fs36.default.rmSync(filePath(personaId2), { force: true });
|
|
62793
63055
|
},
|
|
62794
63056
|
addRemovedChat(personaId2, chatId) {
|
|
62795
63057
|
const meta = read(personaId2);
|
|
@@ -62941,8 +63203,8 @@ function createLarkBotCloudClient(opts) {
|
|
|
62941
63203
|
}
|
|
62942
63204
|
|
|
62943
63205
|
// src/lark-bot-connector/chat-router.ts
|
|
62944
|
-
var
|
|
62945
|
-
var
|
|
63206
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
63207
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
62946
63208
|
init_protocol();
|
|
62947
63209
|
var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
|
|
62948
63210
|
var LOCAL_TURN_RETRIES = 2;
|
|
@@ -63020,9 +63282,9 @@ function createLarkChatRouter(deps) {
|
|
|
63020
63282
|
continue;
|
|
63021
63283
|
}
|
|
63022
63284
|
const dir = deps.mediaRootFor(env.chatId);
|
|
63023
|
-
|
|
63024
|
-
const p3 =
|
|
63025
|
-
|
|
63285
|
+
import_node_fs37.default.mkdirSync(dir, { recursive: true });
|
|
63286
|
+
const p3 = import_node_path42.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
|
|
63287
|
+
import_node_fs37.default.writeFileSync(p3, r2.data);
|
|
63026
63288
|
lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
63027
63289
|
} catch (err) {
|
|
63028
63290
|
deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
|
|
@@ -63043,9 +63305,9 @@ function createLarkChatRouter(deps) {
|
|
|
63043
63305
|
continue;
|
|
63044
63306
|
}
|
|
63045
63307
|
const dir = deps.mediaRootFor(env.chatId);
|
|
63046
|
-
|
|
63047
|
-
const p3 =
|
|
63048
|
-
|
|
63308
|
+
import_node_fs37.default.mkdirSync(dir, { recursive: true });
|
|
63309
|
+
const p3 = import_node_path42.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
|
|
63310
|
+
import_node_fs37.default.writeFileSync(p3, r2.data);
|
|
63049
63311
|
lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
63050
63312
|
} catch (err) {
|
|
63051
63313
|
deps.logger?.warn(`larkBot file fetch failed ${f2.key}: ${err.message}`);
|
|
@@ -64241,7 +64503,7 @@ function openHttpLineStream(opts) {
|
|
|
64241
64503
|
init_protocol();
|
|
64242
64504
|
|
|
64243
64505
|
// src/tools/codex-cloud-session.ts
|
|
64244
|
-
var
|
|
64506
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
64245
64507
|
function cloudThreadParams(ctx, paths) {
|
|
64246
64508
|
const { model: _model, ...base } = threadStartParams(ctx);
|
|
64247
64509
|
const developerInstructions = [ctx.extraSystemPrompt, workDirPrompt(paths.workDir, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
|
|
@@ -64298,7 +64560,7 @@ function cloudImageInput(deps) {
|
|
|
64298
64560
|
const mime = lookupMime(p3);
|
|
64299
64561
|
if (!mime.startsWith("image/")) return null;
|
|
64300
64562
|
try {
|
|
64301
|
-
const bytes = (deps.readFile ??
|
|
64563
|
+
const bytes = (deps.readFile ?? import_node_fs38.default.readFileSync)(p3);
|
|
64302
64564
|
return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
|
|
64303
64565
|
} catch (e) {
|
|
64304
64566
|
deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
|
|
@@ -64432,7 +64694,7 @@ init_protocol();
|
|
|
64432
64694
|
|
|
64433
64695
|
// src/tools/pi.ts
|
|
64434
64696
|
var import_node_child_process12 = require("child_process");
|
|
64435
|
-
var
|
|
64697
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
64436
64698
|
init_protocol();
|
|
64437
64699
|
|
|
64438
64700
|
// src/tools/pi-rpc-client.ts
|
|
@@ -64533,8 +64795,8 @@ var PiRpcClient = class {
|
|
|
64533
64795
|
// src/tools/pi-session.ts
|
|
64534
64796
|
var import_node_child_process11 = require("child_process");
|
|
64535
64797
|
var import_node_crypto12 = require("crypto");
|
|
64536
|
-
var
|
|
64537
|
-
var
|
|
64798
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
64799
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
64538
64800
|
|
|
64539
64801
|
// src/tools/pi-events.ts
|
|
64540
64802
|
init_protocol();
|
|
@@ -64806,8 +65068,8 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
|
|
|
64806
65068
|
function createPiSession(ctx, sink, deps = {}) {
|
|
64807
65069
|
const cmd = process.env.PI_BIN ?? "pi";
|
|
64808
65070
|
const sessionId = ctx.toolSessionId ?? (0, import_node_crypto12.randomUUID)();
|
|
64809
|
-
const skillsDir =
|
|
64810
|
-
const exists = deps.skillsDirExists ?? ((d2) =>
|
|
65071
|
+
const skillsDir = import_node_path43.default.join(ctx.cwd, ".claude", "skills");
|
|
65072
|
+
const exists = deps.skillsDirExists ?? ((d2) => import_node_fs39.default.existsSync(d2));
|
|
64811
65073
|
const args = buildPiArgs(ctx, {
|
|
64812
65074
|
sessionId,
|
|
64813
65075
|
skillsDir: exists(skillsDir) ? skillsDir : void 0,
|
|
@@ -64869,10 +65131,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
|
|
|
64869
65131
|
};
|
|
64870
65132
|
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
65133
|
async function probePi(env = process.env) {
|
|
64872
|
-
if (env.PI_BIN &&
|
|
65134
|
+
if (env.PI_BIN && import_node_fs40.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
|
|
64873
65135
|
try {
|
|
64874
65136
|
const out = (0, import_node_child_process12.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
|
|
64875
|
-
if (out &&
|
|
65137
|
+
if (out && import_node_fs40.default.existsSync(out)) return { available: true, path: out };
|
|
64876
65138
|
} catch {
|
|
64877
65139
|
}
|
|
64878
65140
|
return { available: false };
|
|
@@ -65159,7 +65421,7 @@ var CloudPiAdapter = class {
|
|
|
65159
65421
|
init_protocol();
|
|
65160
65422
|
|
|
65161
65423
|
// src/tools/codex-skills.ts
|
|
65162
|
-
var
|
|
65424
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
65163
65425
|
function str4(v3) {
|
|
65164
65426
|
return typeof v3 === "string" ? v3 : void 0;
|
|
65165
65427
|
}
|
|
@@ -65174,13 +65436,13 @@ function mapSkillsListResponse(res) {
|
|
|
65174
65436
|
const r2 = s2 ?? {};
|
|
65175
65437
|
const name = str4(r2.name);
|
|
65176
65438
|
if (!name) continue;
|
|
65177
|
-
const
|
|
65439
|
+
const path104 = str4(r2.path);
|
|
65178
65440
|
const description = str4(r2.description);
|
|
65179
65441
|
const isPlugin = name.includes(":");
|
|
65180
65442
|
out.push({
|
|
65181
65443
|
name,
|
|
65182
65444
|
source: isPlugin ? "plugin" : "project",
|
|
65183
|
-
...
|
|
65445
|
+
...path104 ? { path: path104 } : {},
|
|
65184
65446
|
...description ? { description } : {},
|
|
65185
65447
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
65186
65448
|
});
|
|
@@ -65196,7 +65458,7 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
65196
65458
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
65197
65459
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
65198
65460
|
beforeRequest: (client) => {
|
|
65199
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
65461
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path44.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
65200
65462
|
}
|
|
65201
65463
|
});
|
|
65202
65464
|
return mapSkillsListResponse(res);
|
|
@@ -65270,23 +65532,23 @@ function rec4(v3) {
|
|
|
65270
65532
|
}
|
|
65271
65533
|
|
|
65272
65534
|
// src/workspace/browser.ts
|
|
65273
|
-
var
|
|
65274
|
-
var
|
|
65275
|
-
var
|
|
65535
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
65536
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
65537
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
65276
65538
|
init_protocol();
|
|
65277
65539
|
var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
|
|
65278
65540
|
function resolveInsideCwd(cwd, subpath) {
|
|
65279
|
-
const absCwd =
|
|
65280
|
-
const joined =
|
|
65281
|
-
const rel =
|
|
65282
|
-
if (rel.startsWith("..") ||
|
|
65541
|
+
const absCwd = import_node_path45.default.resolve(cwd);
|
|
65542
|
+
const joined = import_node_path45.default.resolve(absCwd, subpath ?? ".");
|
|
65543
|
+
const rel = import_node_path45.default.relative(absCwd, joined);
|
|
65544
|
+
if (rel.startsWith("..") || import_node_path45.default.isAbsolute(rel)) {
|
|
65283
65545
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
65284
65546
|
}
|
|
65285
65547
|
return joined;
|
|
65286
65548
|
}
|
|
65287
65549
|
function ensureCwd(cwd) {
|
|
65288
65550
|
try {
|
|
65289
|
-
const stat =
|
|
65551
|
+
const stat = import_node_fs41.default.statSync(cwd);
|
|
65290
65552
|
if (!stat.isDirectory()) {
|
|
65291
65553
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
65292
65554
|
}
|
|
@@ -65297,10 +65559,10 @@ function ensureCwd(cwd) {
|
|
|
65297
65559
|
}
|
|
65298
65560
|
var WorkspaceBrowser = class {
|
|
65299
65561
|
list(args) {
|
|
65300
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
65562
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os14.default.homedir();
|
|
65301
65563
|
ensureCwd(cwd);
|
|
65302
65564
|
const full = resolveInsideCwd(cwd, args.path);
|
|
65303
|
-
const dirents =
|
|
65565
|
+
const dirents = import_node_fs41.default.readdirSync(full, { withFileTypes: true });
|
|
65304
65566
|
const entries = [];
|
|
65305
65567
|
for (const d2 of dirents) {
|
|
65306
65568
|
if (!args.showHidden && d2.name.startsWith(".")) continue;
|
|
@@ -65310,7 +65572,7 @@ var WorkspaceBrowser = class {
|
|
|
65310
65572
|
mtime: ""
|
|
65311
65573
|
};
|
|
65312
65574
|
try {
|
|
65313
|
-
const st2 =
|
|
65575
|
+
const st2 = import_node_fs41.default.statSync(import_node_path45.default.join(full, d2.name));
|
|
65314
65576
|
entry.mtime = new Date(st2.mtimeMs).toISOString();
|
|
65315
65577
|
if (d2.isFile()) entry.size = st2.size;
|
|
65316
65578
|
} catch {
|
|
@@ -65326,14 +65588,14 @@ var WorkspaceBrowser = class {
|
|
|
65326
65588
|
read(args) {
|
|
65327
65589
|
ensureCwd(args.cwd);
|
|
65328
65590
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
65329
|
-
const st2 =
|
|
65591
|
+
const st2 = import_node_fs41.default.statSync(full);
|
|
65330
65592
|
if (!st2.isFile()) {
|
|
65331
65593
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
65332
65594
|
}
|
|
65333
65595
|
if (st2.size > MAX_FILE_BYTES2) {
|
|
65334
65596
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
|
|
65335
65597
|
}
|
|
65336
|
-
const buf =
|
|
65598
|
+
const buf = import_node_fs41.default.readFileSync(full);
|
|
65337
65599
|
const isBinary = buf.includes(0);
|
|
65338
65600
|
if (isBinary) {
|
|
65339
65601
|
return {
|
|
@@ -65355,20 +65617,20 @@ var WorkspaceBrowser = class {
|
|
|
65355
65617
|
};
|
|
65356
65618
|
|
|
65357
65619
|
// src/skills/agents-scanner.ts
|
|
65358
|
-
var
|
|
65359
|
-
var
|
|
65360
|
-
var
|
|
65620
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
65621
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
65622
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
65361
65623
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
65362
65624
|
function isDirLikeSync2(p3) {
|
|
65363
65625
|
try {
|
|
65364
|
-
return
|
|
65626
|
+
return import_node_fs42.default.statSync(p3).isDirectory();
|
|
65365
65627
|
} catch {
|
|
65366
65628
|
return false;
|
|
65367
65629
|
}
|
|
65368
65630
|
}
|
|
65369
65631
|
function fileExistsSync(p3) {
|
|
65370
65632
|
try {
|
|
65371
|
-
return
|
|
65633
|
+
return import_node_fs42.default.statSync(p3).isFile();
|
|
65372
65634
|
} catch {
|
|
65373
65635
|
return false;
|
|
65374
65636
|
}
|
|
@@ -65376,7 +65638,7 @@ function fileExistsSync(p3) {
|
|
|
65376
65638
|
function parseAgentFile(filePath) {
|
|
65377
65639
|
let content;
|
|
65378
65640
|
try {
|
|
65379
|
-
content =
|
|
65641
|
+
content = import_node_fs42.default.readFileSync(filePath, "utf8");
|
|
65380
65642
|
} catch {
|
|
65381
65643
|
return {};
|
|
65382
65644
|
}
|
|
@@ -65389,16 +65651,16 @@ function parseAgentFile(filePath) {
|
|
|
65389
65651
|
function scanAgentsDir(dir, source, seen, out) {
|
|
65390
65652
|
let entries;
|
|
65391
65653
|
try {
|
|
65392
|
-
entries =
|
|
65654
|
+
entries = import_node_fs42.default.readdirSync(dir, { withFileTypes: true });
|
|
65393
65655
|
} catch {
|
|
65394
65656
|
return;
|
|
65395
65657
|
}
|
|
65396
65658
|
for (const ent of entries) {
|
|
65397
65659
|
if (!ent.name.endsWith(".md")) continue;
|
|
65398
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
65660
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path46.default.join(dir, ent.name)))) {
|
|
65399
65661
|
continue;
|
|
65400
65662
|
}
|
|
65401
|
-
const filePath =
|
|
65663
|
+
const filePath = import_node_path46.default.join(dir, ent.name);
|
|
65402
65664
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
65403
65665
|
if (seen.has(baseName)) continue;
|
|
65404
65666
|
seen.add(baseName);
|
|
@@ -65416,12 +65678,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
65416
65678
|
function walk2(dir, namespaces) {
|
|
65417
65679
|
let entries;
|
|
65418
65680
|
try {
|
|
65419
|
-
entries =
|
|
65681
|
+
entries = import_node_fs42.default.readdirSync(dir, { withFileTypes: true });
|
|
65420
65682
|
} catch {
|
|
65421
65683
|
return;
|
|
65422
65684
|
}
|
|
65423
65685
|
for (const ent of entries) {
|
|
65424
|
-
const childPath =
|
|
65686
|
+
const childPath = import_node_path46.default.join(dir, ent.name);
|
|
65425
65687
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
65426
65688
|
walk2(childPath, [...namespaces, ent.name]);
|
|
65427
65689
|
continue;
|
|
@@ -65446,13 +65708,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
65446
65708
|
walk2(root, []);
|
|
65447
65709
|
}
|
|
65448
65710
|
function readInstalledPlugins2(home) {
|
|
65449
|
-
const pluginsDir =
|
|
65450
|
-
const v22 =
|
|
65451
|
-
const v1 =
|
|
65711
|
+
const pluginsDir = import_node_path46.default.join(home, ".claude", "plugins");
|
|
65712
|
+
const v22 = import_node_path46.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
65713
|
+
const v1 = import_node_path46.default.join(pluginsDir, "installed_plugins.json");
|
|
65452
65714
|
let raw = null;
|
|
65453
65715
|
for (const candidate of [v22, v1]) {
|
|
65454
65716
|
try {
|
|
65455
|
-
raw =
|
|
65717
|
+
raw = import_node_fs42.default.readFileSync(candidate, "utf8");
|
|
65456
65718
|
break;
|
|
65457
65719
|
} catch {
|
|
65458
65720
|
}
|
|
@@ -65477,19 +65739,19 @@ function readInstalledPlugins2(home) {
|
|
|
65477
65739
|
return out;
|
|
65478
65740
|
}
|
|
65479
65741
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
65480
|
-
let cur =
|
|
65481
|
-
const fsRoot =
|
|
65742
|
+
let cur = import_node_path46.default.resolve(startCwd);
|
|
65743
|
+
const fsRoot = import_node_path46.default.parse(cur).root;
|
|
65482
65744
|
while (true) {
|
|
65483
|
-
scanAgentsDir(
|
|
65745
|
+
scanAgentsDir(import_node_path46.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
65484
65746
|
let hasGit = false;
|
|
65485
65747
|
try {
|
|
65486
|
-
hasGit =
|
|
65748
|
+
hasGit = import_node_fs42.default.existsSync(import_node_path46.default.join(cur, ".git"));
|
|
65487
65749
|
} catch {
|
|
65488
65750
|
}
|
|
65489
65751
|
if (hasGit) return;
|
|
65490
65752
|
if (cur === home) return;
|
|
65491
65753
|
if (cur === fsRoot) return;
|
|
65492
|
-
const parent =
|
|
65754
|
+
const parent = import_node_path46.default.dirname(cur);
|
|
65493
65755
|
if (parent === cur) return;
|
|
65494
65756
|
cur = parent;
|
|
65495
65757
|
}
|
|
@@ -65499,7 +65761,7 @@ var AgentsScanner = class {
|
|
|
65499
65761
|
extraPluginRoots;
|
|
65500
65762
|
policyDir;
|
|
65501
65763
|
constructor(opts = {}) {
|
|
65502
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
65764
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os15.default.homedir();
|
|
65503
65765
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
65504
65766
|
if (opts.policyDir !== void 0) {
|
|
65505
65767
|
this.policyDir = opts.policyDir;
|
|
@@ -65524,7 +65786,7 @@ var AgentsScanner = class {
|
|
|
65524
65786
|
}
|
|
65525
65787
|
const fsBlock = [];
|
|
65526
65788
|
scanAgentsDir(
|
|
65527
|
-
|
|
65789
|
+
import_node_path46.default.join(this.home, ".claude", "agents"),
|
|
65528
65790
|
"global",
|
|
65529
65791
|
seen,
|
|
65530
65792
|
fsBlock
|
|
@@ -65538,7 +65800,7 @@ var AgentsScanner = class {
|
|
|
65538
65800
|
...this.extraPluginRoots
|
|
65539
65801
|
];
|
|
65540
65802
|
for (const { name, root } of plugins) {
|
|
65541
|
-
const agentsRoot =
|
|
65803
|
+
const agentsRoot = import_node_path46.default.join(root, "agents");
|
|
65542
65804
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
65543
65805
|
}
|
|
65544
65806
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -65546,28 +65808,28 @@ var AgentsScanner = class {
|
|
|
65546
65808
|
};
|
|
65547
65809
|
|
|
65548
65810
|
// src/observer/session-observer.ts
|
|
65549
|
-
var
|
|
65550
|
-
var
|
|
65551
|
-
var
|
|
65811
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
65812
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
65813
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
65552
65814
|
init_claude_history();
|
|
65553
65815
|
|
|
65554
65816
|
// src/observer/subagent-meta-observer.ts
|
|
65555
|
-
var
|
|
65556
|
-
var
|
|
65557
|
-
var
|
|
65817
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
65818
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
65819
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
65558
65820
|
init_claude_history();
|
|
65559
65821
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
65560
65822
|
var SubagentMetaObserver = class {
|
|
65561
65823
|
constructor(opts) {
|
|
65562
65824
|
this.opts = opts;
|
|
65563
|
-
this.home = opts.home ??
|
|
65825
|
+
this.home = opts.home ?? import_node_os16.default.homedir();
|
|
65564
65826
|
}
|
|
65565
65827
|
opts;
|
|
65566
65828
|
home;
|
|
65567
65829
|
watches = /* @__PURE__ */ new Map();
|
|
65568
65830
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
65569
65831
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
65570
|
-
return
|
|
65832
|
+
return import_node_path47.default.join(
|
|
65571
65833
|
this.home,
|
|
65572
65834
|
".claude",
|
|
65573
65835
|
"projects",
|
|
@@ -65597,7 +65859,7 @@ var SubagentMetaObserver = class {
|
|
|
65597
65859
|
attachWatcher(w3) {
|
|
65598
65860
|
if (w3.watcher) return;
|
|
65599
65861
|
try {
|
|
65600
|
-
w3.watcher =
|
|
65862
|
+
w3.watcher = import_node_fs43.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
|
|
65601
65863
|
if (!name) return;
|
|
65602
65864
|
const m3 = META_RE.exec(String(name));
|
|
65603
65865
|
if (!m3) return;
|
|
@@ -65609,7 +65871,7 @@ var SubagentMetaObserver = class {
|
|
|
65609
65871
|
scan(w3) {
|
|
65610
65872
|
let entries;
|
|
65611
65873
|
try {
|
|
65612
|
-
entries =
|
|
65874
|
+
entries = import_node_fs43.default.readdirSync(w3.dirPath);
|
|
65613
65875
|
} catch {
|
|
65614
65876
|
return;
|
|
65615
65877
|
}
|
|
@@ -65623,10 +65885,10 @@ var SubagentMetaObserver = class {
|
|
|
65623
65885
|
if (!m3) return;
|
|
65624
65886
|
const agentId = m3[1];
|
|
65625
65887
|
if (w3.emitted.has(agentId)) return;
|
|
65626
|
-
const file =
|
|
65888
|
+
const file = import_node_path47.default.join(w3.dirPath, name);
|
|
65627
65889
|
let raw;
|
|
65628
65890
|
try {
|
|
65629
|
-
raw =
|
|
65891
|
+
raw = import_node_fs43.default.readFileSync(file, "utf8");
|
|
65630
65892
|
} catch {
|
|
65631
65893
|
return;
|
|
65632
65894
|
}
|
|
@@ -65671,7 +65933,7 @@ var SubagentMetaObserver = class {
|
|
|
65671
65933
|
var SessionObserver = class {
|
|
65672
65934
|
constructor(opts) {
|
|
65673
65935
|
this.opts = opts;
|
|
65674
|
-
this.home = opts.home ??
|
|
65936
|
+
this.home = opts.home ?? import_node_os17.default.homedir();
|
|
65675
65937
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
65676
65938
|
}
|
|
65677
65939
|
opts;
|
|
@@ -65683,14 +65945,14 @@ var SessionObserver = class {
|
|
|
65683
65945
|
metaObserver;
|
|
65684
65946
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
65685
65947
|
if (override) return override;
|
|
65686
|
-
return
|
|
65948
|
+
return import_node_path48.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
65687
65949
|
}
|
|
65688
65950
|
start(args) {
|
|
65689
65951
|
this.stop(args.sessionId);
|
|
65690
65952
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
65691
65953
|
let size = 0;
|
|
65692
65954
|
try {
|
|
65693
|
-
size =
|
|
65955
|
+
size = import_node_fs44.default.statSync(filePath).size;
|
|
65694
65956
|
} catch {
|
|
65695
65957
|
}
|
|
65696
65958
|
const w3 = {
|
|
@@ -65703,16 +65965,16 @@ var SessionObserver = class {
|
|
|
65703
65965
|
adapter: args.adapter,
|
|
65704
65966
|
prevIsRejectSentinel: false,
|
|
65705
65967
|
toolSessionId: args.toolSessionId,
|
|
65706
|
-
sawFile:
|
|
65968
|
+
sawFile: import_node_fs44.default.existsSync(filePath),
|
|
65707
65969
|
lastRelocateScanMs: 0,
|
|
65708
65970
|
pendingCwdDerive: false,
|
|
65709
65971
|
lastDeriveMs: 0
|
|
65710
65972
|
};
|
|
65711
65973
|
try {
|
|
65712
|
-
|
|
65974
|
+
import_node_fs44.default.mkdirSync(import_node_path48.default.dirname(filePath), { recursive: true });
|
|
65713
65975
|
} catch {
|
|
65714
65976
|
}
|
|
65715
|
-
w3.watcher =
|
|
65977
|
+
w3.watcher = import_node_fs44.default.watch(import_node_path48.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
65716
65978
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
65717
65979
|
this.poll(w3);
|
|
65718
65980
|
});
|
|
@@ -65735,7 +65997,7 @@ var SessionObserver = class {
|
|
|
65735
65997
|
// 异常静默吞,不阻塞 watcher 启动
|
|
65736
65998
|
hydrateMetaTail(w3, maxLines = 200) {
|
|
65737
65999
|
try {
|
|
65738
|
-
const raw =
|
|
66000
|
+
const raw = import_node_fs44.default.readFileSync(w3.filePath, "utf8");
|
|
65739
66001
|
if (!raw) return;
|
|
65740
66002
|
const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
|
|
65741
66003
|
if (allLines.length === 0) return;
|
|
@@ -65759,7 +66021,7 @@ var SessionObserver = class {
|
|
|
65759
66021
|
poll(w3) {
|
|
65760
66022
|
let size = 0;
|
|
65761
66023
|
try {
|
|
65762
|
-
size =
|
|
66024
|
+
size = import_node_fs44.default.statSync(w3.filePath).size;
|
|
65763
66025
|
} catch {
|
|
65764
66026
|
if (w3.sawFile) this.maybeRelocate(w3);
|
|
65765
66027
|
return;
|
|
@@ -65770,11 +66032,11 @@ var SessionObserver = class {
|
|
|
65770
66032
|
w3.buf = "";
|
|
65771
66033
|
}
|
|
65772
66034
|
if (size === w3.lastSize) return;
|
|
65773
|
-
const fd =
|
|
66035
|
+
const fd = import_node_fs44.default.openSync(w3.filePath, "r");
|
|
65774
66036
|
try {
|
|
65775
66037
|
const len = size - w3.lastSize;
|
|
65776
66038
|
const buf = Buffer.alloc(len);
|
|
65777
|
-
|
|
66039
|
+
import_node_fs44.default.readSync(fd, buf, 0, len, w3.lastSize);
|
|
65778
66040
|
w3.lastSize = size;
|
|
65779
66041
|
w3.buf += buf.toString("utf8");
|
|
65780
66042
|
let newlineIndex;
|
|
@@ -65797,7 +66059,7 @@ var SessionObserver = class {
|
|
|
65797
66059
|
}
|
|
65798
66060
|
}
|
|
65799
66061
|
} finally {
|
|
65800
|
-
|
|
66062
|
+
import_node_fs44.default.closeSync(fd);
|
|
65801
66063
|
}
|
|
65802
66064
|
if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
|
|
65803
66065
|
}
|
|
@@ -65809,7 +66071,7 @@ var SessionObserver = class {
|
|
|
65809
66071
|
const now = Date.now();
|
|
65810
66072
|
if (now - w3.lastRelocateScanMs < 1e3) return;
|
|
65811
66073
|
w3.lastRelocateScanMs = now;
|
|
65812
|
-
const projectsRoot =
|
|
66074
|
+
const projectsRoot = import_node_path48.default.join(this.home, ".claude", "projects");
|
|
65813
66075
|
const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
|
|
65814
66076
|
if (!found || found === w3.filePath) return;
|
|
65815
66077
|
try {
|
|
@@ -65818,7 +66080,7 @@ var SessionObserver = class {
|
|
|
65818
66080
|
}
|
|
65819
66081
|
w3.filePath = found;
|
|
65820
66082
|
try {
|
|
65821
|
-
w3.watcher =
|
|
66083
|
+
w3.watcher = import_node_fs44.default.watch(import_node_path48.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
65822
66084
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
65823
66085
|
this.poll(w3);
|
|
65824
66086
|
});
|
|
@@ -65940,9 +66202,9 @@ function listRegistered() {
|
|
|
65940
66202
|
// src/tools/title-generator.ts
|
|
65941
66203
|
var import_node_child_process13 = require("child_process");
|
|
65942
66204
|
init_protocol();
|
|
65943
|
-
var
|
|
65944
|
-
var
|
|
65945
|
-
var
|
|
66205
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
66206
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
66207
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
65946
66208
|
var TITLE_GEN_DIR_PREFIX = "clawd-title-";
|
|
65947
66209
|
var TITLE_MODEL_BY_TOOL = {
|
|
65948
66210
|
claude: "haiku",
|
|
@@ -66013,21 +66275,21 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
66013
66275
|
if (!text) return null;
|
|
66014
66276
|
let workDir;
|
|
66015
66277
|
try {
|
|
66016
|
-
workDir =
|
|
66278
|
+
workDir = import_node_fs45.default.mkdtempSync(import_node_path49.default.join(import_node_os18.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
|
|
66017
66279
|
} catch {
|
|
66018
66280
|
return null;
|
|
66019
66281
|
}
|
|
66020
66282
|
const cleanupWorkDir = () => {
|
|
66021
66283
|
try {
|
|
66022
|
-
|
|
66284
|
+
import_node_fs45.default.rmSync(workDir, { recursive: true, force: true });
|
|
66023
66285
|
} catch {
|
|
66024
66286
|
}
|
|
66025
66287
|
};
|
|
66026
|
-
const outFile =
|
|
66027
|
-
const schemaFile =
|
|
66288
|
+
const outFile = import_node_path49.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
|
|
66289
|
+
const schemaFile = import_node_path49.default.join(workDir, "title-schema.json");
|
|
66028
66290
|
if (isCodexFamily(tool)) {
|
|
66029
66291
|
try {
|
|
66030
|
-
|
|
66292
|
+
import_node_fs45.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
|
|
66031
66293
|
} catch {
|
|
66032
66294
|
cleanupWorkDir();
|
|
66033
66295
|
return null;
|
|
@@ -66077,7 +66339,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
66077
66339
|
if (tool === "claude") return finish(parseTitleJson(stdout));
|
|
66078
66340
|
let fileText = "";
|
|
66079
66341
|
try {
|
|
66080
|
-
fileText =
|
|
66342
|
+
fileText = import_node_fs45.default.readFileSync(outFile, "utf8");
|
|
66081
66343
|
} catch {
|
|
66082
66344
|
return finish(null);
|
|
66083
66345
|
}
|
|
@@ -66722,8 +66984,8 @@ async function authenticate(token, deps) {
|
|
|
66722
66984
|
}
|
|
66723
66985
|
|
|
66724
66986
|
// src/legacy-cleanup.ts
|
|
66725
|
-
var
|
|
66726
|
-
var
|
|
66987
|
+
var fs56 = __toESM(require("fs/promises"), 1);
|
|
66988
|
+
var path57 = __toESM(require("path"), 1);
|
|
66727
66989
|
var LEGACY_FILES = [
|
|
66728
66990
|
"personal-capability.json",
|
|
66729
66991
|
"received-capabilities.json",
|
|
@@ -66732,9 +66994,9 @@ var LEGACY_FILES = [
|
|
|
66732
66994
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
66733
66995
|
const removed = [];
|
|
66734
66996
|
for (const name of LEGACY_FILES) {
|
|
66735
|
-
const p3 =
|
|
66997
|
+
const p3 = path57.join(dataDir, name);
|
|
66736
66998
|
try {
|
|
66737
|
-
await
|
|
66999
|
+
await fs56.unlink(p3);
|
|
66738
67000
|
removed.push(name);
|
|
66739
67001
|
logger.debug("legacy capability file removed", { file: name });
|
|
66740
67002
|
} catch (err) {
|
|
@@ -66746,13 +67008,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
66746
67008
|
}
|
|
66747
67009
|
|
|
66748
67010
|
// src/inbox/inbox-store.ts
|
|
66749
|
-
var
|
|
66750
|
-
var
|
|
67011
|
+
var fs57 = __toESM(require("fs"), 1);
|
|
67012
|
+
var path58 = __toESM(require("path"), 1);
|
|
66751
67013
|
var INBOX_SUBDIR = "inbox";
|
|
66752
67014
|
var InboxStore = class {
|
|
66753
67015
|
constructor(dataDir) {
|
|
66754
67016
|
this.dataDir = dataDir;
|
|
66755
|
-
|
|
67017
|
+
fs57.mkdirSync(this.dirPath(), { recursive: true });
|
|
66756
67018
|
}
|
|
66757
67019
|
dataDir;
|
|
66758
67020
|
/**
|
|
@@ -66764,7 +67026,7 @@ var InboxStore = class {
|
|
|
66764
67026
|
const file = this.filePath(peerDeviceId);
|
|
66765
67027
|
let raw;
|
|
66766
67028
|
try {
|
|
66767
|
-
raw =
|
|
67029
|
+
raw = fs57.readFileSync(file, "utf8");
|
|
66768
67030
|
} catch (err) {
|
|
66769
67031
|
if (err?.code === "ENOENT") return [];
|
|
66770
67032
|
return [];
|
|
@@ -66780,7 +67042,7 @@ var InboxStore = class {
|
|
|
66780
67042
|
const dir = this.dirPath();
|
|
66781
67043
|
let entries;
|
|
66782
67044
|
try {
|
|
66783
|
-
entries =
|
|
67045
|
+
entries = fs57.readdirSync(dir);
|
|
66784
67046
|
} catch (err) {
|
|
66785
67047
|
if (err?.code === "ENOENT") return [];
|
|
66786
67048
|
return [];
|
|
@@ -66796,9 +67058,9 @@ var InboxStore = class {
|
|
|
66796
67058
|
if (existing.some((m3) => m3.id === message.id)) return;
|
|
66797
67059
|
const file = this.filePath(message.peerDeviceId);
|
|
66798
67060
|
const line = JSON.stringify(message) + "\n";
|
|
66799
|
-
|
|
67061
|
+
fs57.appendFileSync(file, line, { mode: 384 });
|
|
66800
67062
|
try {
|
|
66801
|
-
|
|
67063
|
+
fs57.chmodSync(file, 384);
|
|
66802
67064
|
} catch {
|
|
66803
67065
|
}
|
|
66804
67066
|
}
|
|
@@ -66828,7 +67090,7 @@ var InboxStore = class {
|
|
|
66828
67090
|
removeByPeerDeviceId(peerDeviceId) {
|
|
66829
67091
|
const file = this.filePath(peerDeviceId);
|
|
66830
67092
|
try {
|
|
66831
|
-
|
|
67093
|
+
fs57.unlinkSync(file);
|
|
66832
67094
|
} catch (err) {
|
|
66833
67095
|
if (err?.code === "ENOENT") return;
|
|
66834
67096
|
}
|
|
@@ -66837,18 +67099,18 @@ var InboxStore = class {
|
|
|
66837
67099
|
const file = this.filePath(peerDeviceId);
|
|
66838
67100
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
66839
67101
|
const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
66840
|
-
|
|
66841
|
-
|
|
67102
|
+
fs57.writeFileSync(tmp, content, { mode: 384 });
|
|
67103
|
+
fs57.renameSync(tmp, file);
|
|
66842
67104
|
try {
|
|
66843
|
-
|
|
67105
|
+
fs57.chmodSync(file, 384);
|
|
66844
67106
|
} catch {
|
|
66845
67107
|
}
|
|
66846
67108
|
}
|
|
66847
67109
|
dirPath() {
|
|
66848
|
-
return
|
|
67110
|
+
return path58.join(this.dataDir, INBOX_SUBDIR);
|
|
66849
67111
|
}
|
|
66850
67112
|
filePath(peerDeviceId) {
|
|
66851
|
-
return
|
|
67113
|
+
return path58.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
66852
67114
|
}
|
|
66853
67115
|
};
|
|
66854
67116
|
function parseAllLines(raw) {
|
|
@@ -66936,8 +67198,8 @@ var InboxManager = class {
|
|
|
66936
67198
|
};
|
|
66937
67199
|
|
|
66938
67200
|
// src/state/contact-store.ts
|
|
66939
|
-
var
|
|
66940
|
-
var
|
|
67201
|
+
var fs58 = __toESM(require("fs"), 1);
|
|
67202
|
+
var path59 = __toESM(require("path"), 1);
|
|
66941
67203
|
var FILE_NAME = "contacts.json";
|
|
66942
67204
|
var ContactStore = class {
|
|
66943
67205
|
constructor(dataDir) {
|
|
@@ -66947,10 +67209,10 @@ var ContactStore = class {
|
|
|
66947
67209
|
contacts = /* @__PURE__ */ new Map();
|
|
66948
67210
|
load() {
|
|
66949
67211
|
this.contacts.clear();
|
|
66950
|
-
const file =
|
|
67212
|
+
const file = path59.join(this.dataDir, FILE_NAME);
|
|
66951
67213
|
let raw;
|
|
66952
67214
|
try {
|
|
66953
|
-
raw =
|
|
67215
|
+
raw = fs58.readFileSync(file, "utf8");
|
|
66954
67216
|
} catch (err) {
|
|
66955
67217
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
66956
67218
|
return;
|
|
@@ -67031,20 +67293,20 @@ var ContactStore = class {
|
|
|
67031
67293
|
return true;
|
|
67032
67294
|
}
|
|
67033
67295
|
flush() {
|
|
67034
|
-
const file =
|
|
67296
|
+
const file = path59.join(this.dataDir, FILE_NAME);
|
|
67035
67297
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
67036
67298
|
const content = JSON.stringify(
|
|
67037
67299
|
{ contacts: Array.from(this.contacts.values()) },
|
|
67038
67300
|
null,
|
|
67039
67301
|
2
|
|
67040
67302
|
);
|
|
67041
|
-
|
|
67042
|
-
|
|
67043
|
-
|
|
67303
|
+
fs58.mkdirSync(this.dataDir, { recursive: true });
|
|
67304
|
+
fs58.writeFileSync(tmp, content, { mode: 384 });
|
|
67305
|
+
fs58.renameSync(tmp, file);
|
|
67044
67306
|
}
|
|
67045
67307
|
renameBak(file) {
|
|
67046
67308
|
try {
|
|
67047
|
-
|
|
67309
|
+
fs58.renameSync(file, `${file}.bak`);
|
|
67048
67310
|
} catch {
|
|
67049
67311
|
}
|
|
67050
67312
|
}
|
|
@@ -67152,61 +67414,61 @@ async function connectRemote(args) {
|
|
|
67152
67414
|
}
|
|
67153
67415
|
|
|
67154
67416
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
67155
|
-
var
|
|
67156
|
-
var
|
|
67417
|
+
var fs59 = __toESM(require("fs"), 1);
|
|
67418
|
+
var path60 = __toESM(require("path"), 1);
|
|
67157
67419
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
67158
67420
|
function migrateFlattenSessions(opts) {
|
|
67159
67421
|
const dataDir = opts.dataDir;
|
|
67160
67422
|
const now = opts.now ?? Date.now;
|
|
67161
|
-
const sessionsDir =
|
|
67162
|
-
const flagPath =
|
|
67423
|
+
const sessionsDir = path60.join(dataDir, "sessions");
|
|
67424
|
+
const flagPath = path60.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
67163
67425
|
if (existsSync3(flagPath)) {
|
|
67164
67426
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
67165
67427
|
}
|
|
67166
67428
|
let movedBare = 0;
|
|
67167
67429
|
let movedVmOwner = 0;
|
|
67168
67430
|
let archivedListener = 0;
|
|
67169
|
-
const defaultDir =
|
|
67431
|
+
const defaultDir = path60.join(sessionsDir, "default");
|
|
67170
67432
|
if (existsSync3(defaultDir)) {
|
|
67171
67433
|
for (const entry of readdirSafe(defaultDir)) {
|
|
67172
67434
|
if (!entry.endsWith(".json")) continue;
|
|
67173
|
-
const src =
|
|
67174
|
-
const dst =
|
|
67175
|
-
|
|
67435
|
+
const src = path60.join(defaultDir, entry);
|
|
67436
|
+
const dst = path60.join(sessionsDir, entry);
|
|
67437
|
+
fs59.renameSync(src, dst);
|
|
67176
67438
|
movedBare += 1;
|
|
67177
67439
|
}
|
|
67178
67440
|
rmdirIfEmpty(defaultDir);
|
|
67179
67441
|
}
|
|
67180
67442
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
67181
|
-
const personaDir =
|
|
67443
|
+
const personaDir = path60.join(sessionsDir, pid);
|
|
67182
67444
|
if (!isDir(personaDir)) continue;
|
|
67183
67445
|
if (pid === "default") continue;
|
|
67184
|
-
const ownerSrc =
|
|
67446
|
+
const ownerSrc = path60.join(personaDir, "owner");
|
|
67185
67447
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
67186
|
-
const ownerDst =
|
|
67187
|
-
|
|
67448
|
+
const ownerDst = path60.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
67449
|
+
fs59.mkdirSync(ownerDst, { recursive: true });
|
|
67188
67450
|
for (const file of readdirSafe(ownerSrc)) {
|
|
67189
67451
|
if (!file.endsWith(".json")) continue;
|
|
67190
|
-
|
|
67452
|
+
fs59.renameSync(path60.join(ownerSrc, file), path60.join(ownerDst, file));
|
|
67191
67453
|
movedVmOwner += 1;
|
|
67192
67454
|
}
|
|
67193
67455
|
rmdirIfEmpty(ownerSrc);
|
|
67194
67456
|
}
|
|
67195
|
-
const listenerSrc =
|
|
67457
|
+
const listenerSrc = path60.join(personaDir, "listener");
|
|
67196
67458
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
67197
|
-
const archiveDst =
|
|
67198
|
-
|
|
67459
|
+
const archiveDst = path60.join(dataDir, ".legacy", `listener-${pid}`);
|
|
67460
|
+
fs59.mkdirSync(archiveDst, { recursive: true });
|
|
67199
67461
|
for (const file of readdirSafe(listenerSrc)) {
|
|
67200
67462
|
if (!file.endsWith(".json")) continue;
|
|
67201
|
-
|
|
67463
|
+
fs59.renameSync(path60.join(listenerSrc, file), path60.join(archiveDst, file));
|
|
67202
67464
|
archivedListener += 1;
|
|
67203
67465
|
}
|
|
67204
67466
|
rmdirIfEmpty(listenerSrc);
|
|
67205
67467
|
}
|
|
67206
67468
|
rmdirIfEmpty(personaDir);
|
|
67207
67469
|
}
|
|
67208
|
-
|
|
67209
|
-
|
|
67470
|
+
fs59.mkdirSync(sessionsDir, { recursive: true });
|
|
67471
|
+
fs59.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
67210
67472
|
return {
|
|
67211
67473
|
skipped: false,
|
|
67212
67474
|
flagWritten: true,
|
|
@@ -67217,7 +67479,7 @@ function migrateFlattenSessions(opts) {
|
|
|
67217
67479
|
}
|
|
67218
67480
|
function existsSync3(p3) {
|
|
67219
67481
|
try {
|
|
67220
|
-
|
|
67482
|
+
fs59.statSync(p3);
|
|
67221
67483
|
return true;
|
|
67222
67484
|
} catch {
|
|
67223
67485
|
return false;
|
|
@@ -67225,62 +67487,62 @@ function existsSync3(p3) {
|
|
|
67225
67487
|
}
|
|
67226
67488
|
function isDir(p3) {
|
|
67227
67489
|
try {
|
|
67228
|
-
return
|
|
67490
|
+
return fs59.statSync(p3).isDirectory();
|
|
67229
67491
|
} catch {
|
|
67230
67492
|
return false;
|
|
67231
67493
|
}
|
|
67232
67494
|
}
|
|
67233
67495
|
function readdirSafe(p3) {
|
|
67234
67496
|
try {
|
|
67235
|
-
return
|
|
67497
|
+
return fs59.readdirSync(p3);
|
|
67236
67498
|
} catch {
|
|
67237
67499
|
return [];
|
|
67238
67500
|
}
|
|
67239
67501
|
}
|
|
67240
67502
|
function rmdirIfEmpty(p3) {
|
|
67241
67503
|
try {
|
|
67242
|
-
|
|
67504
|
+
fs59.rmdirSync(p3);
|
|
67243
67505
|
} catch {
|
|
67244
67506
|
}
|
|
67245
67507
|
}
|
|
67246
67508
|
|
|
67247
67509
|
// src/migrations/2026-08-18-drop-seeded-projects.ts
|
|
67248
|
-
var
|
|
67249
|
-
var
|
|
67510
|
+
var fs60 = __toESM(require("fs"), 1);
|
|
67511
|
+
var path61 = __toESM(require("path"), 1);
|
|
67250
67512
|
var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
|
|
67251
67513
|
function dropSeededProjects(opts) {
|
|
67252
|
-
|
|
67253
|
-
const flag =
|
|
67254
|
-
if (
|
|
67255
|
-
const file =
|
|
67514
|
+
fs60.mkdirSync(opts.dataDir, { recursive: true });
|
|
67515
|
+
const flag = path61.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
|
|
67516
|
+
if (fs60.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
|
|
67517
|
+
const file = path61.join(opts.dataDir, "projects.json");
|
|
67256
67518
|
let raw = null;
|
|
67257
67519
|
let dropped = 0;
|
|
67258
67520
|
try {
|
|
67259
|
-
raw =
|
|
67521
|
+
raw = fs60.readFileSync(file, "utf8");
|
|
67260
67522
|
dropped = JSON.parse(raw).projects?.length ?? 0;
|
|
67261
67523
|
} catch {
|
|
67262
67524
|
}
|
|
67263
67525
|
let backup = null;
|
|
67264
67526
|
if (raw != null && dropped > 0) {
|
|
67265
|
-
const dir =
|
|
67266
|
-
|
|
67267
|
-
backup =
|
|
67268
|
-
|
|
67527
|
+
const dir = path61.join(opts.dataDir, "backups");
|
|
67528
|
+
fs60.mkdirSync(dir, { recursive: true });
|
|
67529
|
+
backup = path61.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
|
|
67530
|
+
fs60.writeFileSync(backup, raw);
|
|
67269
67531
|
}
|
|
67270
67532
|
if (raw != null || dropped > 0) {
|
|
67271
|
-
|
|
67533
|
+
fs60.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
|
|
67272
67534
|
}
|
|
67273
|
-
|
|
67535
|
+
fs60.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
|
|
67274
67536
|
return { skipped: false, dropped, backup };
|
|
67275
67537
|
}
|
|
67276
67538
|
|
|
67277
67539
|
// src/transport/http-router.ts
|
|
67278
|
-
var
|
|
67279
|
-
var
|
|
67540
|
+
var import_node_fs47 = __toESM(require("fs"), 1);
|
|
67541
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
67280
67542
|
|
|
67281
67543
|
// src/attachment/upload.ts
|
|
67282
|
-
var
|
|
67283
|
-
var
|
|
67544
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
67545
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
67284
67546
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
67285
67547
|
var import_promises8 = require("stream/promises");
|
|
67286
67548
|
var UploadError = class extends Error {
|
|
@@ -67292,22 +67554,22 @@ var UploadError = class extends Error {
|
|
|
67292
67554
|
code;
|
|
67293
67555
|
};
|
|
67294
67556
|
function assertValidFileName(fileName) {
|
|
67295
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
67557
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path50.default.basename(fileName)) {
|
|
67296
67558
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
67297
67559
|
}
|
|
67298
67560
|
}
|
|
67299
67561
|
var HASH_PREFIX_LEN = 16;
|
|
67300
67562
|
async function writeUploadedAttachment(args) {
|
|
67301
67563
|
assertValidFileName(args.fileName);
|
|
67302
|
-
const attachmentsRoot =
|
|
67564
|
+
const attachmentsRoot = import_node_path50.default.join(args.baseDir, ".attachments");
|
|
67303
67565
|
try {
|
|
67304
|
-
|
|
67566
|
+
import_node_fs46.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
67305
67567
|
} catch (err) {
|
|
67306
67568
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
67307
67569
|
}
|
|
67308
67570
|
const hasher = import_node_crypto15.default.createHash("sha256");
|
|
67309
67571
|
let actualSize = 0;
|
|
67310
|
-
const tmpPath =
|
|
67572
|
+
const tmpPath = import_node_path50.default.join(
|
|
67311
67573
|
attachmentsRoot,
|
|
67312
67574
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto15.default.randomBytes(4).toString("hex")}`
|
|
67313
67575
|
);
|
|
@@ -67322,18 +67584,18 @@ async function writeUploadedAttachment(args) {
|
|
|
67322
67584
|
yield buf;
|
|
67323
67585
|
}
|
|
67324
67586
|
},
|
|
67325
|
-
|
|
67587
|
+
import_node_fs46.default.createWriteStream(tmpPath, { mode: 384 })
|
|
67326
67588
|
);
|
|
67327
67589
|
} catch (err) {
|
|
67328
67590
|
try {
|
|
67329
|
-
|
|
67591
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67330
67592
|
} catch {
|
|
67331
67593
|
}
|
|
67332
67594
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
67333
67595
|
}
|
|
67334
67596
|
if (actualSize !== args.contentLength) {
|
|
67335
67597
|
try {
|
|
67336
|
-
|
|
67598
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67337
67599
|
} catch {
|
|
67338
67600
|
}
|
|
67339
67601
|
throw new UploadError(
|
|
@@ -67342,34 +67604,34 @@ async function writeUploadedAttachment(args) {
|
|
|
67342
67604
|
);
|
|
67343
67605
|
}
|
|
67344
67606
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
67345
|
-
const hashDir =
|
|
67607
|
+
const hashDir = import_node_path50.default.join(attachmentsRoot, attachmentId);
|
|
67346
67608
|
let finalFileName;
|
|
67347
67609
|
let hashDirExists = false;
|
|
67348
67610
|
try {
|
|
67349
|
-
hashDirExists =
|
|
67611
|
+
hashDirExists = import_node_fs46.default.statSync(hashDir).isDirectory();
|
|
67350
67612
|
} catch {
|
|
67351
67613
|
}
|
|
67352
67614
|
if (hashDirExists) {
|
|
67353
|
-
const existing =
|
|
67615
|
+
const existing = import_node_fs46.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
|
|
67354
67616
|
finalFileName = existing[0] ?? args.fileName;
|
|
67355
67617
|
try {
|
|
67356
|
-
|
|
67618
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67357
67619
|
} catch {
|
|
67358
67620
|
}
|
|
67359
67621
|
} else {
|
|
67360
67622
|
try {
|
|
67361
|
-
|
|
67623
|
+
import_node_fs46.default.mkdirSync(hashDir, { recursive: true });
|
|
67362
67624
|
finalFileName = args.fileName;
|
|
67363
|
-
|
|
67625
|
+
import_node_fs46.default.renameSync(tmpPath, import_node_path50.default.join(hashDir, finalFileName));
|
|
67364
67626
|
} catch (err) {
|
|
67365
67627
|
try {
|
|
67366
|
-
|
|
67628
|
+
import_node_fs46.default.unlinkSync(tmpPath);
|
|
67367
67629
|
} catch {
|
|
67368
67630
|
}
|
|
67369
67631
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
67370
67632
|
}
|
|
67371
67633
|
}
|
|
67372
|
-
const absPath =
|
|
67634
|
+
const absPath = import_node_path50.default.join(hashDir, finalFileName);
|
|
67373
67635
|
const relPath = absPath;
|
|
67374
67636
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
67375
67637
|
relPath: absPath,
|
|
@@ -67384,8 +67646,8 @@ async function writeUploadedAttachment(args) {
|
|
|
67384
67646
|
|
|
67385
67647
|
// src/extension/import.ts
|
|
67386
67648
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
67387
|
-
var
|
|
67388
|
-
var
|
|
67649
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
67650
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
67389
67651
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
67390
67652
|
var ImportError = class extends Error {
|
|
67391
67653
|
constructor(code, message) {
|
|
@@ -67402,7 +67664,7 @@ async function importZip(buf, root) {
|
|
|
67402
67664
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
67403
67665
|
}
|
|
67404
67666
|
for (const name of Object.keys(zip.files)) {
|
|
67405
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
67667
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path51.default.isAbsolute(name)) {
|
|
67406
67668
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
67407
67669
|
}
|
|
67408
67670
|
}
|
|
@@ -67435,7 +67697,7 @@ async function importZip(buf, root) {
|
|
|
67435
67697
|
);
|
|
67436
67698
|
}
|
|
67437
67699
|
}
|
|
67438
|
-
const destDir =
|
|
67700
|
+
const destDir = import_node_path51.default.join(root, manifest.id);
|
|
67439
67701
|
let destExists = false;
|
|
67440
67702
|
try {
|
|
67441
67703
|
await import_promises9.default.access(destDir);
|
|
@@ -67445,15 +67707,15 @@ async function importZip(buf, root) {
|
|
|
67445
67707
|
if (destExists) {
|
|
67446
67708
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
67447
67709
|
}
|
|
67448
|
-
const stage = await import_promises9.default.mkdtemp(
|
|
67710
|
+
const stage = await import_promises9.default.mkdtemp(import_node_path51.default.join(import_node_os19.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
67449
67711
|
try {
|
|
67450
67712
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
67451
|
-
const dest =
|
|
67713
|
+
const dest = import_node_path51.default.join(stage, name);
|
|
67452
67714
|
if (entry.dir) {
|
|
67453
67715
|
await import_promises9.default.mkdir(dest, { recursive: true });
|
|
67454
67716
|
continue;
|
|
67455
67717
|
}
|
|
67456
|
-
await import_promises9.default.mkdir(
|
|
67718
|
+
await import_promises9.default.mkdir(import_node_path51.default.dirname(dest), { recursive: true });
|
|
67457
67719
|
const content = await entry.async("nodebuffer");
|
|
67458
67720
|
await import_promises9.default.writeFile(dest, content);
|
|
67459
67721
|
}
|
|
@@ -67507,7 +67769,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
67507
67769
|
".wasm": "application/wasm"
|
|
67508
67770
|
};
|
|
67509
67771
|
function shareUiAssetMime(filePath) {
|
|
67510
|
-
const ext =
|
|
67772
|
+
const ext = import_node_path52.default.extname(filePath).toLowerCase();
|
|
67511
67773
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
67512
67774
|
}
|
|
67513
67775
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -67606,7 +67868,7 @@ function isValidUploadFileName(fileName) {
|
|
|
67606
67868
|
if (fileName === "." || fileName === "..") return false;
|
|
67607
67869
|
if (fileName.startsWith(".")) return false;
|
|
67608
67870
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
67609
|
-
return fileName ===
|
|
67871
|
+
return fileName === import_node_path52.default.basename(fileName);
|
|
67610
67872
|
}
|
|
67611
67873
|
function createHttpRouter(deps) {
|
|
67612
67874
|
return async (req, res) => {
|
|
@@ -67690,7 +67952,7 @@ function createHttpRouter(deps) {
|
|
|
67690
67952
|
}
|
|
67691
67953
|
let buf;
|
|
67692
67954
|
try {
|
|
67693
|
-
buf = await
|
|
67955
|
+
buf = await import_node_fs47.default.promises.readFile(abs);
|
|
67694
67956
|
} catch {
|
|
67695
67957
|
sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
67696
67958
|
return true;
|
|
@@ -67836,7 +68098,7 @@ function createHttpRouter(deps) {
|
|
|
67836
68098
|
sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
|
|
67837
68099
|
return true;
|
|
67838
68100
|
}
|
|
67839
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
68101
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path52.default.basename(r2.absPath)));
|
|
67840
68102
|
return true;
|
|
67841
68103
|
}
|
|
67842
68104
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -67957,7 +68219,7 @@ function createHttpRouter(deps) {
|
|
|
67957
68219
|
return true;
|
|
67958
68220
|
}
|
|
67959
68221
|
let absPath;
|
|
67960
|
-
if (
|
|
68222
|
+
if (import_node_path52.default.isAbsolute(pathParam)) {
|
|
67961
68223
|
absPath = pathParam;
|
|
67962
68224
|
} else if (deps.sessionStore) {
|
|
67963
68225
|
const file = deps.sessionStore.read(sid);
|
|
@@ -67965,7 +68227,7 @@ function createHttpRouter(deps) {
|
|
|
67965
68227
|
sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
67966
68228
|
return true;
|
|
67967
68229
|
}
|
|
67968
|
-
absPath =
|
|
68230
|
+
absPath = import_node_path52.default.join(file.cwd, pathParam);
|
|
67969
68231
|
} else {
|
|
67970
68232
|
sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
67971
68233
|
return true;
|
|
@@ -68049,7 +68311,7 @@ function withCtx(ctx, body) {
|
|
|
68049
68311
|
function streamFile(res, absPath, logger) {
|
|
68050
68312
|
let stat;
|
|
68051
68313
|
try {
|
|
68052
|
-
stat =
|
|
68314
|
+
stat = import_node_fs47.default.statSync(absPath);
|
|
68053
68315
|
} catch (err) {
|
|
68054
68316
|
const code = err?.code;
|
|
68055
68317
|
if (code === "ENOENT") {
|
|
@@ -68064,7 +68326,7 @@ function streamFile(res, absPath, logger) {
|
|
|
68064
68326
|
return;
|
|
68065
68327
|
}
|
|
68066
68328
|
const mime = lookupMime(absPath);
|
|
68067
|
-
const basename2 =
|
|
68329
|
+
const basename2 = import_node_path52.default.basename(absPath);
|
|
68068
68330
|
res.writeHead(200, {
|
|
68069
68331
|
"Content-Type": mime,
|
|
68070
68332
|
"Content-Length": String(stat.size),
|
|
@@ -68072,7 +68334,7 @@ function streamFile(res, absPath, logger) {
|
|
|
68072
68334
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
68073
68335
|
"X-Content-Type-Options": "nosniff"
|
|
68074
68336
|
});
|
|
68075
|
-
const stream =
|
|
68337
|
+
const stream = import_node_fs47.default.createReadStream(absPath);
|
|
68076
68338
|
stream.on("error", (err) => {
|
|
68077
68339
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
68078
68340
|
res.destroy();
|
|
@@ -68081,8 +68343,8 @@ function streamFile(res, absPath, logger) {
|
|
|
68081
68343
|
}
|
|
68082
68344
|
|
|
68083
68345
|
// src/attachment/gc.ts
|
|
68084
|
-
var
|
|
68085
|
-
var
|
|
68346
|
+
var import_node_fs48 = __toESM(require("fs"), 1);
|
|
68347
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
68086
68348
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
68087
68349
|
function runAttachmentGc(args) {
|
|
68088
68350
|
const now = (args.now ?? Date.now)();
|
|
@@ -68091,12 +68353,12 @@ function runAttachmentGc(args) {
|
|
|
68091
68353
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
68092
68354
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
68093
68355
|
if (entry.stale) continue;
|
|
68094
|
-
if (
|
|
68356
|
+
if (import_node_path53.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
68095
68357
|
}
|
|
68096
68358
|
}
|
|
68097
68359
|
const visited = /* @__PURE__ */ new Set();
|
|
68098
68360
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
68099
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
68361
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path53.default.join(
|
|
68100
68362
|
args.dataDir,
|
|
68101
68363
|
"sessions",
|
|
68102
68364
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -68109,28 +68371,28 @@ function runAttachmentGc(args) {
|
|
|
68109
68371
|
return true;
|
|
68110
68372
|
});
|
|
68111
68373
|
for (const rootDir of roots) {
|
|
68112
|
-
const attRoot =
|
|
68374
|
+
const attRoot = import_node_path53.default.join(rootDir, ".attachments");
|
|
68113
68375
|
let hashDirs;
|
|
68114
68376
|
try {
|
|
68115
|
-
hashDirs =
|
|
68377
|
+
hashDirs = import_node_fs48.default.readdirSync(attRoot);
|
|
68116
68378
|
} catch (err) {
|
|
68117
68379
|
if (err.code === "ENOENT") continue;
|
|
68118
68380
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
68119
68381
|
continue;
|
|
68120
68382
|
}
|
|
68121
68383
|
for (const hashDir of hashDirs) {
|
|
68122
|
-
const hashDirAbs =
|
|
68384
|
+
const hashDirAbs = import_node_path53.default.join(attRoot, hashDir);
|
|
68123
68385
|
let files;
|
|
68124
68386
|
try {
|
|
68125
|
-
files =
|
|
68387
|
+
files = import_node_fs48.default.readdirSync(hashDirAbs);
|
|
68126
68388
|
} catch {
|
|
68127
68389
|
continue;
|
|
68128
68390
|
}
|
|
68129
68391
|
for (const name of files) {
|
|
68130
|
-
const file =
|
|
68392
|
+
const file = import_node_path53.default.join(hashDirAbs, name);
|
|
68131
68393
|
let stat;
|
|
68132
68394
|
try {
|
|
68133
|
-
stat =
|
|
68395
|
+
stat = import_node_fs48.default.statSync(file);
|
|
68134
68396
|
} catch {
|
|
68135
68397
|
continue;
|
|
68136
68398
|
}
|
|
@@ -68139,18 +68401,18 @@ function runAttachmentGc(args) {
|
|
|
68139
68401
|
if (age < ttlMs) continue;
|
|
68140
68402
|
if (liveAbs.has(file)) continue;
|
|
68141
68403
|
try {
|
|
68142
|
-
|
|
68404
|
+
import_node_fs48.default.unlinkSync(file);
|
|
68143
68405
|
} catch (err) {
|
|
68144
68406
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
68145
68407
|
}
|
|
68146
68408
|
}
|
|
68147
68409
|
try {
|
|
68148
|
-
if (
|
|
68410
|
+
if (import_node_fs48.default.readdirSync(hashDirAbs).length === 0) import_node_fs48.default.rmdirSync(hashDirAbs);
|
|
68149
68411
|
} catch {
|
|
68150
68412
|
}
|
|
68151
68413
|
}
|
|
68152
68414
|
try {
|
|
68153
|
-
if (
|
|
68415
|
+
if (import_node_fs48.default.readdirSync(attRoot).length === 0) import_node_fs48.default.rmdirSync(attRoot);
|
|
68154
68416
|
} catch {
|
|
68155
68417
|
}
|
|
68156
68418
|
}
|
|
@@ -68158,8 +68420,8 @@ function runAttachmentGc(args) {
|
|
|
68158
68420
|
}
|
|
68159
68421
|
|
|
68160
68422
|
// src/attachment/group.ts
|
|
68161
|
-
var
|
|
68162
|
-
var
|
|
68423
|
+
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
68424
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
68163
68425
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
68164
68426
|
init_protocol();
|
|
68165
68427
|
var GroupFileStore = class {
|
|
@@ -68171,11 +68433,11 @@ var GroupFileStore = class {
|
|
|
68171
68433
|
this.logger = opts.logger;
|
|
68172
68434
|
}
|
|
68173
68435
|
rootForScope(scope) {
|
|
68174
|
-
return
|
|
68436
|
+
return import_node_path54.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
68175
68437
|
}
|
|
68176
68438
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
68177
68439
|
filePath(scope, sessionId) {
|
|
68178
|
-
return
|
|
68440
|
+
return import_node_path54.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
68179
68441
|
}
|
|
68180
68442
|
cacheKey(scope, sessionId) {
|
|
68181
68443
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -68184,7 +68446,7 @@ var GroupFileStore = class {
|
|
|
68184
68446
|
readFile(scope, sessionId) {
|
|
68185
68447
|
const file = this.filePath(scope, sessionId);
|
|
68186
68448
|
try {
|
|
68187
|
-
const raw =
|
|
68449
|
+
const raw = import_node_fs49.default.readFileSync(file, "utf8");
|
|
68188
68450
|
const parsed = JSON.parse(raw);
|
|
68189
68451
|
if (!Array.isArray(parsed)) {
|
|
68190
68452
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -68210,10 +68472,10 @@ var GroupFileStore = class {
|
|
|
68210
68472
|
}
|
|
68211
68473
|
writeFile(scope, sessionId, entries) {
|
|
68212
68474
|
const file = this.filePath(scope, sessionId);
|
|
68213
|
-
|
|
68475
|
+
import_node_fs49.default.mkdirSync(import_node_path54.default.dirname(file), { recursive: true });
|
|
68214
68476
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
68215
|
-
|
|
68216
|
-
|
|
68477
|
+
import_node_fs49.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
68478
|
+
import_node_fs49.default.renameSync(tmp, file);
|
|
68217
68479
|
}
|
|
68218
68480
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
68219
68481
|
list(scope, sessionId) {
|
|
@@ -68305,7 +68567,7 @@ var GroupFileStore = class {
|
|
|
68305
68567
|
*/
|
|
68306
68568
|
deleteSession(scope, sessionId) {
|
|
68307
68569
|
try {
|
|
68308
|
-
|
|
68570
|
+
import_node_fs49.default.unlinkSync(this.filePath(scope, sessionId));
|
|
68309
68571
|
} catch (err) {
|
|
68310
68572
|
if (err?.code !== "ENOENT") throw err;
|
|
68311
68573
|
}
|
|
@@ -68318,7 +68580,7 @@ var GroupFileStore = class {
|
|
|
68318
68580
|
* 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
|
|
68319
68581
|
*/
|
|
68320
68582
|
deletePersona(personaId2) {
|
|
68321
|
-
|
|
68583
|
+
import_node_fs49.default.rmSync(import_node_path54.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
|
|
68322
68584
|
const prefix = `persona:${personaId2}:`;
|
|
68323
68585
|
for (const key of this.cache.keys()) {
|
|
68324
68586
|
if (key.startsWith(prefix)) this.cache.delete(key);
|
|
@@ -68327,10 +68589,10 @@ var GroupFileStore = class {
|
|
|
68327
68589
|
};
|
|
68328
68590
|
|
|
68329
68591
|
// src/discovery/state-file.ts
|
|
68330
|
-
var
|
|
68331
|
-
var
|
|
68592
|
+
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
68593
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
68332
68594
|
function defaultStateFilePath(dataDir) {
|
|
68333
|
-
return
|
|
68595
|
+
return import_node_path55.default.join(dataDir, "state.json");
|
|
68334
68596
|
}
|
|
68335
68597
|
function isPidAlive(pid) {
|
|
68336
68598
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -68352,7 +68614,7 @@ var StateFileManager = class {
|
|
|
68352
68614
|
}
|
|
68353
68615
|
read() {
|
|
68354
68616
|
try {
|
|
68355
|
-
const raw =
|
|
68617
|
+
const raw = import_node_fs50.default.readFileSync(this.file, "utf8");
|
|
68356
68618
|
const parsed = JSON.parse(raw);
|
|
68357
68619
|
return parsed;
|
|
68358
68620
|
} catch {
|
|
@@ -68366,20 +68628,20 @@ var StateFileManager = class {
|
|
|
68366
68628
|
return { status: "stale", existing };
|
|
68367
68629
|
}
|
|
68368
68630
|
write(state) {
|
|
68369
|
-
|
|
68631
|
+
import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(this.file), { recursive: true });
|
|
68370
68632
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
68371
|
-
|
|
68372
|
-
|
|
68633
|
+
import_node_fs50.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
68634
|
+
import_node_fs50.default.renameSync(tmp, this.file);
|
|
68373
68635
|
if (process.platform !== "win32") {
|
|
68374
68636
|
try {
|
|
68375
|
-
|
|
68637
|
+
import_node_fs50.default.chmodSync(this.file, 384);
|
|
68376
68638
|
} catch {
|
|
68377
68639
|
}
|
|
68378
68640
|
}
|
|
68379
68641
|
}
|
|
68380
68642
|
delete() {
|
|
68381
68643
|
try {
|
|
68382
|
-
|
|
68644
|
+
import_node_fs50.default.unlinkSync(this.file);
|
|
68383
68645
|
} catch {
|
|
68384
68646
|
}
|
|
68385
68647
|
}
|
|
@@ -68393,14 +68655,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
68393
68655
|
}
|
|
68394
68656
|
|
|
68395
68657
|
// src/tunnel/tunnel-manager.ts
|
|
68396
|
-
var
|
|
68397
|
-
var
|
|
68658
|
+
var import_node_fs54 = __toESM(require("fs"), 1);
|
|
68659
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
68398
68660
|
var import_node_crypto17 = __toESM(require("crypto"), 1);
|
|
68399
68661
|
var import_node_child_process16 = require("child_process");
|
|
68400
68662
|
|
|
68401
68663
|
// src/tunnel/tunnel-store.ts
|
|
68402
|
-
var
|
|
68403
|
-
var
|
|
68664
|
+
var import_node_fs51 = __toESM(require("fs"), 1);
|
|
68665
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
68404
68666
|
var TunnelStore = class {
|
|
68405
68667
|
constructor(filePath) {
|
|
68406
68668
|
this.filePath = filePath;
|
|
@@ -68408,7 +68670,7 @@ var TunnelStore = class {
|
|
|
68408
68670
|
filePath;
|
|
68409
68671
|
async get() {
|
|
68410
68672
|
try {
|
|
68411
|
-
const raw = await
|
|
68673
|
+
const raw = await import_node_fs51.default.promises.readFile(this.filePath, "utf8");
|
|
68412
68674
|
const obj = JSON.parse(raw);
|
|
68413
68675
|
if (!isPersistedTunnel(obj)) return null;
|
|
68414
68676
|
return obj;
|
|
@@ -68419,22 +68681,22 @@ var TunnelStore = class {
|
|
|
68419
68681
|
}
|
|
68420
68682
|
}
|
|
68421
68683
|
async set(v3) {
|
|
68422
|
-
const dir =
|
|
68423
|
-
await
|
|
68684
|
+
const dir = import_node_path56.default.dirname(this.filePath);
|
|
68685
|
+
await import_node_fs51.default.promises.mkdir(dir, { recursive: true });
|
|
68424
68686
|
const data = JSON.stringify(v3, null, 2);
|
|
68425
68687
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
68426
|
-
await
|
|
68688
|
+
await import_node_fs51.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
68427
68689
|
if (process.platform !== "win32") {
|
|
68428
68690
|
try {
|
|
68429
|
-
await
|
|
68691
|
+
await import_node_fs51.default.promises.chmod(tmp, 384);
|
|
68430
68692
|
} catch {
|
|
68431
68693
|
}
|
|
68432
68694
|
}
|
|
68433
|
-
await
|
|
68695
|
+
await import_node_fs51.default.promises.rename(tmp, this.filePath);
|
|
68434
68696
|
}
|
|
68435
68697
|
async clear() {
|
|
68436
68698
|
try {
|
|
68437
|
-
await
|
|
68699
|
+
await import_node_fs51.default.promises.unlink(this.filePath);
|
|
68438
68700
|
} catch (err) {
|
|
68439
68701
|
const code = err?.code;
|
|
68440
68702
|
if (code !== "ENOENT") throw err;
|
|
@@ -68529,9 +68791,9 @@ function escape2(v3) {
|
|
|
68529
68791
|
}
|
|
68530
68792
|
|
|
68531
68793
|
// src/tunnel/frpc-binary.ts
|
|
68532
|
-
var
|
|
68533
|
-
var
|
|
68534
|
-
var
|
|
68794
|
+
var import_node_fs52 = __toESM(require("fs"), 1);
|
|
68795
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
68796
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
68535
68797
|
var import_node_child_process14 = require("child_process");
|
|
68536
68798
|
var import_node_stream4 = require("stream");
|
|
68537
68799
|
var import_promises10 = require("stream/promises");
|
|
@@ -68563,20 +68825,20 @@ function frpcDownloadUrl(version2, p3) {
|
|
|
68563
68825
|
}
|
|
68564
68826
|
async function ensureFrpcBinary(opts) {
|
|
68565
68827
|
if (opts.override) {
|
|
68566
|
-
if (!
|
|
68828
|
+
if (!import_node_fs52.default.existsSync(opts.override)) {
|
|
68567
68829
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
68568
68830
|
}
|
|
68569
68831
|
return opts.override;
|
|
68570
68832
|
}
|
|
68571
68833
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
68572
68834
|
const platform = opts.platform ?? detectPlatform();
|
|
68573
|
-
const binDir =
|
|
68574
|
-
|
|
68835
|
+
const binDir = import_node_path57.default.join(opts.dataDir, "bin");
|
|
68836
|
+
import_node_fs52.default.mkdirSync(binDir, { recursive: true });
|
|
68575
68837
|
cleanupStaleArtifacts(binDir);
|
|
68576
|
-
const stableBin =
|
|
68577
|
-
if (
|
|
68838
|
+
const stableBin = import_node_path57.default.join(binDir, "frpc");
|
|
68839
|
+
if (import_node_fs52.default.existsSync(stableBin)) return stableBin;
|
|
68578
68840
|
const partialBin = `${stableBin}.partial`;
|
|
68579
|
-
const tarballPath =
|
|
68841
|
+
const tarballPath = import_node_path57.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
68580
68842
|
try {
|
|
68581
68843
|
const url = frpcDownloadUrl(version2, platform);
|
|
68582
68844
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -68585,8 +68847,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
68585
68847
|
} else {
|
|
68586
68848
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
68587
68849
|
}
|
|
68588
|
-
|
|
68589
|
-
|
|
68850
|
+
import_node_fs52.default.chmodSync(partialBin, 493);
|
|
68851
|
+
import_node_fs52.default.renameSync(partialBin, stableBin);
|
|
68590
68852
|
} finally {
|
|
68591
68853
|
safeUnlink(tarballPath);
|
|
68592
68854
|
safeUnlink(partialBin);
|
|
@@ -68596,15 +68858,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
68596
68858
|
function cleanupStaleArtifacts(binDir) {
|
|
68597
68859
|
let entries;
|
|
68598
68860
|
try {
|
|
68599
|
-
entries =
|
|
68861
|
+
entries = import_node_fs52.default.readdirSync(binDir);
|
|
68600
68862
|
} catch {
|
|
68601
68863
|
return;
|
|
68602
68864
|
}
|
|
68603
68865
|
for (const name of entries) {
|
|
68604
68866
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
68605
|
-
const full =
|
|
68867
|
+
const full = import_node_path57.default.join(binDir, name);
|
|
68606
68868
|
try {
|
|
68607
|
-
|
|
68869
|
+
import_node_fs52.default.rmSync(full, { recursive: true, force: true });
|
|
68608
68870
|
} catch {
|
|
68609
68871
|
}
|
|
68610
68872
|
}
|
|
@@ -68612,7 +68874,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
68612
68874
|
}
|
|
68613
68875
|
function safeUnlink(p3) {
|
|
68614
68876
|
try {
|
|
68615
|
-
|
|
68877
|
+
import_node_fs52.default.unlinkSync(p3);
|
|
68616
68878
|
} catch {
|
|
68617
68879
|
}
|
|
68618
68880
|
}
|
|
@@ -68623,13 +68885,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
68623
68885
|
if (!res.ok || !res.body) {
|
|
68624
68886
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
68625
68887
|
}
|
|
68626
|
-
const out =
|
|
68888
|
+
const out = import_node_fs52.default.createWriteStream(dest);
|
|
68627
68889
|
const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
|
|
68628
68890
|
await (0, import_promises10.pipeline)(nodeStream, out);
|
|
68629
68891
|
}
|
|
68630
68892
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
68631
|
-
const work =
|
|
68632
|
-
|
|
68893
|
+
const work = import_node_path57.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
68894
|
+
import_node_fs52.default.mkdirSync(work, { recursive: true });
|
|
68633
68895
|
try {
|
|
68634
68896
|
await new Promise((resolve9, reject) => {
|
|
68635
68897
|
const proc = (0, import_node_child_process14.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -68637,32 +68899,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
68637
68899
|
proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
|
|
68638
68900
|
});
|
|
68639
68901
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
68640
|
-
const src =
|
|
68641
|
-
if (!
|
|
68902
|
+
const src = import_node_path57.default.join(work, dirName, "frpc");
|
|
68903
|
+
if (!import_node_fs52.default.existsSync(src)) {
|
|
68642
68904
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
68643
68905
|
}
|
|
68644
|
-
|
|
68906
|
+
import_node_fs52.default.copyFileSync(src, destBin);
|
|
68645
68907
|
} finally {
|
|
68646
|
-
|
|
68908
|
+
import_node_fs52.default.rmSync(work, { recursive: true, force: true });
|
|
68647
68909
|
}
|
|
68648
68910
|
}
|
|
68649
68911
|
|
|
68650
68912
|
// src/tunnel/frpc-process.ts
|
|
68651
|
-
var
|
|
68652
|
-
var
|
|
68913
|
+
var import_node_fs53 = __toESM(require("fs"), 1);
|
|
68914
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
68653
68915
|
var import_node_child_process15 = require("child_process");
|
|
68654
68916
|
function frpcPidFilePath(dataDir) {
|
|
68655
|
-
return
|
|
68917
|
+
return import_node_path58.default.join(dataDir, "frpc.pid");
|
|
68656
68918
|
}
|
|
68657
68919
|
function writeFrpcPid(dataDir, pid) {
|
|
68658
68920
|
try {
|
|
68659
|
-
|
|
68921
|
+
import_node_fs53.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
68660
68922
|
} catch {
|
|
68661
68923
|
}
|
|
68662
68924
|
}
|
|
68663
68925
|
function clearFrpcPid(dataDir) {
|
|
68664
68926
|
try {
|
|
68665
|
-
|
|
68927
|
+
import_node_fs53.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
68666
68928
|
} catch {
|
|
68667
68929
|
}
|
|
68668
68930
|
}
|
|
@@ -68678,7 +68940,7 @@ function defaultIsPidAlive(pid) {
|
|
|
68678
68940
|
}
|
|
68679
68941
|
function defaultReadPidFile(file) {
|
|
68680
68942
|
try {
|
|
68681
|
-
return
|
|
68943
|
+
return import_node_fs53.default.readFileSync(file, "utf8");
|
|
68682
68944
|
} catch {
|
|
68683
68945
|
return null;
|
|
68684
68946
|
}
|
|
@@ -68694,7 +68956,7 @@ function defaultSleep2(ms) {
|
|
|
68694
68956
|
}
|
|
68695
68957
|
async function killStaleFrpc(deps) {
|
|
68696
68958
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
68697
|
-
const tomlPath =
|
|
68959
|
+
const tomlPath = import_node_path58.default.join(deps.dataDir, "frpc.toml");
|
|
68698
68960
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
68699
68961
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
68700
68962
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -68718,7 +68980,7 @@ async function killStaleFrpc(deps) {
|
|
|
68718
68980
|
}
|
|
68719
68981
|
if (victims.size === 0) {
|
|
68720
68982
|
try {
|
|
68721
|
-
|
|
68983
|
+
import_node_fs53.default.unlinkSync(pidFile);
|
|
68722
68984
|
} catch {
|
|
68723
68985
|
}
|
|
68724
68986
|
return;
|
|
@@ -68729,7 +68991,7 @@ async function killStaleFrpc(deps) {
|
|
|
68729
68991
|
}
|
|
68730
68992
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
68731
68993
|
try {
|
|
68732
|
-
|
|
68994
|
+
import_node_fs53.default.unlinkSync(pidFile);
|
|
68733
68995
|
} catch {
|
|
68734
68996
|
}
|
|
68735
68997
|
}
|
|
@@ -68766,7 +69028,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
68766
69028
|
var TunnelManager = class {
|
|
68767
69029
|
constructor(deps) {
|
|
68768
69030
|
this.deps = deps;
|
|
68769
|
-
this.store = deps.store ?? new TunnelStore(
|
|
69031
|
+
this.store = deps.store ?? new TunnelStore(import_node_path59.default.join(deps.dataDir, "tunnel.json"));
|
|
68770
69032
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
68771
69033
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
68772
69034
|
}
|
|
@@ -68893,7 +69155,7 @@ var TunnelManager = class {
|
|
|
68893
69155
|
dataDir: this.deps.dataDir,
|
|
68894
69156
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
68895
69157
|
});
|
|
68896
|
-
const tomlPath =
|
|
69158
|
+
const tomlPath = import_node_path59.default.join(this.deps.dataDir, "frpc.toml");
|
|
68897
69159
|
const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto17.default.randomBytes(3).toString("hex")}`;
|
|
68898
69160
|
const toml = buildFrpcToml({
|
|
68899
69161
|
serverAddr: t2.frpsHost,
|
|
@@ -68904,14 +69166,14 @@ var TunnelManager = class {
|
|
|
68904
69166
|
localPort,
|
|
68905
69167
|
logLevel: "info"
|
|
68906
69168
|
});
|
|
68907
|
-
await
|
|
69169
|
+
await import_node_fs54.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
68908
69170
|
const proc = (this.deps.spawnImpl ?? import_node_child_process16.spawn)(frpcBin, ["-c", tomlPath], {
|
|
68909
69171
|
stdio: ["ignore", "pipe", "pipe"]
|
|
68910
69172
|
});
|
|
68911
|
-
const logDir =
|
|
68912
|
-
|
|
68913
|
-
const logFilePath =
|
|
68914
|
-
const logStream =
|
|
69173
|
+
const logDir = import_node_path59.default.join(this.deps.dataDir, "log");
|
|
69174
|
+
import_node_fs54.default.mkdirSync(logDir, { recursive: true });
|
|
69175
|
+
const logFilePath = import_node_path59.default.join(logDir, "frpc.log");
|
|
69176
|
+
const logStream = import_node_fs54.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
68915
69177
|
logStream.on("error", () => {
|
|
68916
69178
|
});
|
|
68917
69179
|
const tee = (chunk) => {
|
|
@@ -68993,28 +69255,28 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
68993
69255
|
}
|
|
68994
69256
|
|
|
68995
69257
|
// src/tunnel/device-key.ts
|
|
68996
|
-
var
|
|
68997
|
-
var
|
|
69258
|
+
var import_node_os21 = __toESM(require("os"), 1);
|
|
69259
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
68998
69260
|
var import_node_crypto18 = __toESM(require("crypto"), 1);
|
|
68999
69261
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
69000
69262
|
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 ?
|
|
69263
|
+
const hostname = opts.hostname ?? import_node_os21.default.hostname();
|
|
69264
|
+
const uid = opts.uid ?? (typeof import_node_os21.default.userInfo === "function" ? import_node_os21.default.userInfo().uid : 0);
|
|
69265
|
+
const home = opts.home ?? import_node_os21.default.homedir();
|
|
69266
|
+
const defaultDataDir = import_node_path60.default.resolve(import_node_path60.default.join(home, ".clawd"));
|
|
69267
|
+
const normalizedDataDir = opts.dataDir ? import_node_path60.default.resolve(opts.dataDir) : null;
|
|
69006
69268
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
69007
69269
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
69008
69270
|
return import_node_crypto18.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
69009
69271
|
}
|
|
69010
69272
|
|
|
69011
69273
|
// src/auth-store.ts
|
|
69012
|
-
var
|
|
69013
|
-
var
|
|
69274
|
+
var import_node_fs55 = __toESM(require("fs"), 1);
|
|
69275
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
69014
69276
|
var import_node_crypto19 = __toESM(require("crypto"), 1);
|
|
69015
69277
|
var AUTH_FILE_NAME = "auth.json";
|
|
69016
69278
|
function authFilePath(dataDir) {
|
|
69017
|
-
return
|
|
69279
|
+
return import_node_path61.default.join(dataDir, AUTH_FILE_NAME);
|
|
69018
69280
|
}
|
|
69019
69281
|
function loadOrCreateAuthFile(opts) {
|
|
69020
69282
|
const file = authFilePath(opts.dataDir);
|
|
@@ -69055,7 +69317,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
69055
69317
|
}
|
|
69056
69318
|
function readAuthFile(file) {
|
|
69057
69319
|
try {
|
|
69058
|
-
const raw =
|
|
69320
|
+
const raw = import_node_fs55.default.readFileSync(file, "utf8");
|
|
69059
69321
|
const parsed = JSON.parse(raw);
|
|
69060
69322
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
69061
69323
|
return null;
|
|
@@ -69076,26 +69338,26 @@ function readAuthFile(file) {
|
|
|
69076
69338
|
}
|
|
69077
69339
|
}
|
|
69078
69340
|
function writeAuthFile(file, content) {
|
|
69079
|
-
|
|
69080
|
-
|
|
69341
|
+
import_node_fs55.default.mkdirSync(import_node_path61.default.dirname(file), { recursive: true });
|
|
69342
|
+
import_node_fs55.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
69081
69343
|
try {
|
|
69082
|
-
|
|
69344
|
+
import_node_fs55.default.chmodSync(file, 384);
|
|
69083
69345
|
} catch {
|
|
69084
69346
|
}
|
|
69085
69347
|
}
|
|
69086
69348
|
|
|
69087
69349
|
// src/owner-profile.ts
|
|
69088
|
-
var
|
|
69089
|
-
var
|
|
69090
|
-
var
|
|
69350
|
+
var import_node_fs56 = __toESM(require("fs"), 1);
|
|
69351
|
+
var import_node_os22 = __toESM(require("os"), 1);
|
|
69352
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
69091
69353
|
var PROFILE_FILENAME = "profile.json";
|
|
69092
69354
|
function profilePath(dataDir) {
|
|
69093
|
-
return
|
|
69355
|
+
return import_node_path62.default.join(dataDir, PROFILE_FILENAME);
|
|
69094
69356
|
}
|
|
69095
69357
|
function loadOwnerProfile(dataDir) {
|
|
69096
69358
|
let raw;
|
|
69097
69359
|
try {
|
|
69098
|
-
raw =
|
|
69360
|
+
raw = import_node_fs56.default.readFileSync(profilePath(dataDir), "utf8");
|
|
69099
69361
|
} catch {
|
|
69100
69362
|
return {};
|
|
69101
69363
|
}
|
|
@@ -69111,11 +69373,11 @@ function loadOwnerProfile(dataDir) {
|
|
|
69111
69373
|
}
|
|
69112
69374
|
function patchOwnerProfile(dataDir, patch) {
|
|
69113
69375
|
const merged = { ...loadOwnerProfile(dataDir), ...patch };
|
|
69114
|
-
|
|
69376
|
+
import_node_fs56.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
|
|
69115
69377
|
return merged;
|
|
69116
69378
|
}
|
|
69117
69379
|
function loadOwnerDisplayName(dataDir) {
|
|
69118
|
-
const fallback =
|
|
69380
|
+
const fallback = import_node_os22.default.userInfo().username;
|
|
69119
69381
|
const displayName = loadOwnerProfile(dataDir).displayName;
|
|
69120
69382
|
if (typeof displayName !== "string" || displayName.length === 0) {
|
|
69121
69383
|
if (displayName !== void 0) {
|
|
@@ -69127,18 +69389,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
69127
69389
|
}
|
|
69128
69390
|
|
|
69129
69391
|
// src/feishu-auth/owner-identity-store.ts
|
|
69130
|
-
var
|
|
69131
|
-
var
|
|
69392
|
+
var import_node_fs57 = __toESM(require("fs"), 1);
|
|
69393
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
69132
69394
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
69133
69395
|
var OwnerIdentityStore = class {
|
|
69134
69396
|
file;
|
|
69135
69397
|
constructor(dataDir) {
|
|
69136
|
-
this.file =
|
|
69398
|
+
this.file = import_node_path63.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
69137
69399
|
}
|
|
69138
69400
|
read() {
|
|
69139
69401
|
let raw;
|
|
69140
69402
|
try {
|
|
69141
|
-
raw =
|
|
69403
|
+
raw = import_node_fs57.default.readFileSync(this.file, "utf8");
|
|
69142
69404
|
} catch {
|
|
69143
69405
|
return null;
|
|
69144
69406
|
}
|
|
@@ -69165,16 +69427,16 @@ var OwnerIdentityStore = class {
|
|
|
69165
69427
|
};
|
|
69166
69428
|
}
|
|
69167
69429
|
write(record4) {
|
|
69168
|
-
|
|
69169
|
-
|
|
69430
|
+
import_node_fs57.default.mkdirSync(import_node_path63.default.dirname(this.file), { recursive: true });
|
|
69431
|
+
import_node_fs57.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
|
|
69170
69432
|
try {
|
|
69171
|
-
|
|
69433
|
+
import_node_fs57.default.chmodSync(this.file, 384);
|
|
69172
69434
|
} catch {
|
|
69173
69435
|
}
|
|
69174
69436
|
}
|
|
69175
69437
|
clear() {
|
|
69176
69438
|
try {
|
|
69177
|
-
|
|
69439
|
+
import_node_fs57.default.unlinkSync(this.file);
|
|
69178
69440
|
} catch (err) {
|
|
69179
69441
|
const code = err?.code;
|
|
69180
69442
|
if (code !== "ENOENT") throw err;
|
|
@@ -69670,8 +69932,8 @@ function verifyConnectToken(args) {
|
|
|
69670
69932
|
}
|
|
69671
69933
|
|
|
69672
69934
|
// src/feishu-auth/server-key.ts
|
|
69673
|
-
var
|
|
69674
|
-
var
|
|
69935
|
+
var fs74 = __toESM(require("fs"), 1);
|
|
69936
|
+
var path76 = __toESM(require("path"), 1);
|
|
69675
69937
|
var FILE_NAME2 = "server-signing-key.json";
|
|
69676
69938
|
var ServerKeyStore = class {
|
|
69677
69939
|
constructor(dataDir) {
|
|
@@ -69679,12 +69941,12 @@ var ServerKeyStore = class {
|
|
|
69679
69941
|
}
|
|
69680
69942
|
dataDir;
|
|
69681
69943
|
filePath() {
|
|
69682
|
-
return
|
|
69944
|
+
return path76.join(this.dataDir, FILE_NAME2);
|
|
69683
69945
|
}
|
|
69684
69946
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
69685
69947
|
read() {
|
|
69686
69948
|
try {
|
|
69687
|
-
const raw =
|
|
69949
|
+
const raw = fs74.readFileSync(this.filePath(), "utf8");
|
|
69688
69950
|
const parsed = JSON.parse(raw);
|
|
69689
69951
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
69690
69952
|
return parsed.publicKeyPem;
|
|
@@ -69699,12 +69961,12 @@ var ServerKeyStore = class {
|
|
|
69699
69961
|
publicKeyPem,
|
|
69700
69962
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
69701
69963
|
};
|
|
69702
|
-
|
|
69703
|
-
|
|
69964
|
+
fs74.mkdirSync(this.dataDir, { recursive: true });
|
|
69965
|
+
fs74.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
69704
69966
|
}
|
|
69705
69967
|
clear() {
|
|
69706
69968
|
try {
|
|
69707
|
-
|
|
69969
|
+
fs74.unlinkSync(this.filePath());
|
|
69708
69970
|
} catch {
|
|
69709
69971
|
}
|
|
69710
69972
|
}
|
|
@@ -69714,19 +69976,19 @@ var ServerKeyStore = class {
|
|
|
69714
69976
|
init_protocol();
|
|
69715
69977
|
|
|
69716
69978
|
// src/handlers/index.ts
|
|
69717
|
-
var
|
|
69979
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
69718
69980
|
|
|
69719
69981
|
// src/handlers/session.ts
|
|
69720
69982
|
init_protocol();
|
|
69721
69983
|
|
|
69722
69984
|
// src/session/fork.ts
|
|
69723
|
-
var
|
|
69724
|
-
var
|
|
69725
|
-
var
|
|
69985
|
+
var import_node_fs58 = __toESM(require("fs"), 1);
|
|
69986
|
+
var import_node_os23 = __toESM(require("os"), 1);
|
|
69987
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
69726
69988
|
var import_node_crypto21 = require("crypto");
|
|
69727
69989
|
init_claude_history();
|
|
69728
69990
|
function readJsonlEntries(file) {
|
|
69729
|
-
const raw =
|
|
69991
|
+
const raw = import_node_fs58.default.readFileSync(file, "utf8");
|
|
69730
69992
|
const out = [];
|
|
69731
69993
|
for (const line of raw.split("\n")) {
|
|
69732
69994
|
const t2 = line.trim();
|
|
@@ -69739,19 +70001,19 @@ function readJsonlEntries(file) {
|
|
|
69739
70001
|
return out;
|
|
69740
70002
|
}
|
|
69741
70003
|
function forkSession(input) {
|
|
69742
|
-
const baseDir = input.baseDir ??
|
|
69743
|
-
let projectDir =
|
|
69744
|
-
let sourceFile =
|
|
69745
|
-
if (!
|
|
70004
|
+
const baseDir = input.baseDir ?? import_node_path64.default.join(import_node_os23.default.homedir(), ".claude");
|
|
70005
|
+
let projectDir = import_node_path64.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
70006
|
+
let sourceFile = import_node_path64.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
70007
|
+
if (!import_node_fs58.default.existsSync(sourceFile)) {
|
|
69746
70008
|
const found = findTranscriptByToolSessionId(
|
|
69747
|
-
|
|
70009
|
+
import_node_path64.default.join(baseDir, "projects"),
|
|
69748
70010
|
input.toolSessionId
|
|
69749
70011
|
);
|
|
69750
70012
|
if (!found) {
|
|
69751
70013
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
69752
70014
|
}
|
|
69753
70015
|
sourceFile = found;
|
|
69754
|
-
projectDir =
|
|
70016
|
+
projectDir = import_node_path64.default.dirname(found);
|
|
69755
70017
|
}
|
|
69756
70018
|
const entries = readJsonlEntries(sourceFile);
|
|
69757
70019
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -69780,27 +70042,27 @@ function forkSession(input) {
|
|
|
69780
70042
|
}
|
|
69781
70043
|
forkedLines.push(JSON.stringify(forked));
|
|
69782
70044
|
}
|
|
69783
|
-
const outDir = input.targetCwd ?
|
|
69784
|
-
const forkedFilePath =
|
|
69785
|
-
|
|
69786
|
-
|
|
70045
|
+
const outDir = input.targetCwd ? import_node_path64.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
70046
|
+
const forkedFilePath = import_node_path64.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
70047
|
+
import_node_fs58.default.mkdirSync(outDir, { recursive: true });
|
|
70048
|
+
import_node_fs58.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
69787
70049
|
return { forkedToolSessionId, forkedFilePath };
|
|
69788
70050
|
}
|
|
69789
70051
|
|
|
69790
70052
|
// src/session/external-scan.ts
|
|
69791
|
-
var
|
|
70053
|
+
var import_node_fs59 = __toESM(require("fs"), 1);
|
|
69792
70054
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
69793
|
-
var
|
|
69794
|
-
var
|
|
70055
|
+
var import_node_os24 = __toESM(require("os"), 1);
|
|
70056
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
69795
70057
|
var import_node_module = require("module");
|
|
69796
70058
|
var import_node_child_process17 = require("child_process");
|
|
69797
70059
|
var import_meta7 = {};
|
|
69798
70060
|
function defaultRoots() {
|
|
69799
|
-
const home =
|
|
70061
|
+
const home = import_node_os24.default.homedir();
|
|
69800
70062
|
return {
|
|
69801
|
-
claudeProjectsDir:
|
|
69802
|
-
codexDir:
|
|
69803
|
-
clawdDir:
|
|
70063
|
+
claudeProjectsDir: import_node_path65.default.join(home, ".claude", "projects"),
|
|
70064
|
+
codexDir: import_node_path65.default.join(home, ".codex"),
|
|
70065
|
+
clawdDir: import_node_path65.default.join(home, ".clawd")
|
|
69804
70066
|
};
|
|
69805
70067
|
}
|
|
69806
70068
|
function width(s2) {
|
|
@@ -69851,7 +70113,7 @@ function userText(msg) {
|
|
|
69851
70113
|
}
|
|
69852
70114
|
function isDir2(p3) {
|
|
69853
70115
|
try {
|
|
69854
|
-
return
|
|
70116
|
+
return import_node_fs59.default.statSync(p3).isDirectory();
|
|
69855
70117
|
} catch {
|
|
69856
70118
|
return false;
|
|
69857
70119
|
}
|
|
@@ -69860,7 +70122,7 @@ async function scanClaude(roots) {
|
|
|
69860
70122
|
const out = [];
|
|
69861
70123
|
let dirs;
|
|
69862
70124
|
try {
|
|
69863
|
-
dirs =
|
|
70125
|
+
dirs = import_node_fs59.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
|
|
69864
70126
|
} catch {
|
|
69865
70127
|
return out;
|
|
69866
70128
|
}
|
|
@@ -69868,16 +70130,16 @@ async function scanClaude(roots) {
|
|
|
69868
70130
|
if (!d2.isDirectory()) continue;
|
|
69869
70131
|
let files;
|
|
69870
70132
|
try {
|
|
69871
|
-
files =
|
|
70133
|
+
files = import_node_fs59.default.readdirSync(import_node_path65.default.join(roots.claudeProjectsDir, d2.name));
|
|
69872
70134
|
} catch {
|
|
69873
70135
|
continue;
|
|
69874
70136
|
}
|
|
69875
70137
|
for (const name of files) {
|
|
69876
70138
|
if (!name.endsWith(".jsonl")) continue;
|
|
69877
|
-
const file =
|
|
70139
|
+
const file = import_node_path65.default.join(roots.claudeProjectsDir, d2.name, name);
|
|
69878
70140
|
let st2;
|
|
69879
70141
|
try {
|
|
69880
|
-
st2 =
|
|
70142
|
+
st2 = import_node_fs59.default.statSync(file);
|
|
69881
70143
|
} catch {
|
|
69882
70144
|
continue;
|
|
69883
70145
|
}
|
|
@@ -69930,7 +70192,7 @@ async function scanClaude(roots) {
|
|
|
69930
70192
|
return out;
|
|
69931
70193
|
}
|
|
69932
70194
|
async function countCodexTurns(rolloutPath) {
|
|
69933
|
-
if (!rolloutPath || !
|
|
70195
|
+
if (!rolloutPath || !import_node_fs59.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
|
|
69934
70196
|
let turns = 0;
|
|
69935
70197
|
let first = "";
|
|
69936
70198
|
for await (const rec6 of jsonLines(rolloutPath)) {
|
|
@@ -70004,7 +70266,7 @@ async function codexFromRows(rows) {
|
|
|
70004
70266
|
async function scanCodex(roots) {
|
|
70005
70267
|
let dbs = [];
|
|
70006
70268
|
try {
|
|
70007
|
-
dbs =
|
|
70269
|
+
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
70270
|
} catch {
|
|
70009
70271
|
}
|
|
70010
70272
|
if (!dbs.length) return [];
|
|
@@ -70013,14 +70275,14 @@ async function scanCodex(roots) {
|
|
|
70013
70275
|
}
|
|
70014
70276
|
async function scanExternalSessions(rootsIn) {
|
|
70015
70277
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
70016
|
-
const personaRoot =
|
|
70278
|
+
const personaRoot = import_node_path65.default.join(roots.clawdDir, "personas");
|
|
70017
70279
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
70018
70280
|
const out = [];
|
|
70019
70281
|
for (const c2 of all) {
|
|
70020
70282
|
if (c2.skip) continue;
|
|
70021
70283
|
if (c2.turns < 1) continue;
|
|
70022
70284
|
if (!c2.cwd || !isDir2(c2.cwd)) continue;
|
|
70023
|
-
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot +
|
|
70285
|
+
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
70286
|
continue;
|
|
70025
70287
|
}
|
|
70026
70288
|
out.push({
|
|
@@ -70037,13 +70299,13 @@ async function scanExternalSessions(rootsIn) {
|
|
|
70037
70299
|
}
|
|
70038
70300
|
|
|
70039
70301
|
// src/session/import-ledger.ts
|
|
70040
|
-
var
|
|
70041
|
-
var
|
|
70302
|
+
var import_node_fs60 = __toESM(require("fs"), 1);
|
|
70303
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
70042
70304
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
70043
70305
|
function readImportLedger(dataDir) {
|
|
70044
70306
|
try {
|
|
70045
70307
|
const parsed = JSON.parse(
|
|
70046
|
-
|
|
70308
|
+
import_node_fs60.default.readFileSync(import_node_path66.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
70047
70309
|
);
|
|
70048
70310
|
return Array.isArray(parsed) ? parsed : [];
|
|
70049
70311
|
} catch {
|
|
@@ -70051,10 +70313,10 @@ function readImportLedger(dataDir) {
|
|
|
70051
70313
|
}
|
|
70052
70314
|
}
|
|
70053
70315
|
function appendImportLedger(dataDir, entry) {
|
|
70054
|
-
const file =
|
|
70316
|
+
const file = import_node_path66.default.join(dataDir, LEDGER_FILENAME);
|
|
70055
70317
|
const entries = readImportLedger(dataDir);
|
|
70056
70318
|
entries.push(entry);
|
|
70057
|
-
|
|
70319
|
+
import_node_fs60.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
70058
70320
|
}
|
|
70059
70321
|
|
|
70060
70322
|
// src/handlers/session.ts
|
|
@@ -70587,7 +70849,7 @@ function buildPermissionHandlers(deps) {
|
|
|
70587
70849
|
}
|
|
70588
70850
|
|
|
70589
70851
|
// src/handlers/history.ts
|
|
70590
|
-
var
|
|
70852
|
+
var path81 = __toESM(require("path"), 1);
|
|
70591
70853
|
init_protocol();
|
|
70592
70854
|
|
|
70593
70855
|
// src/session/recent-dirs.ts
|
|
@@ -70605,7 +70867,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
70605
70867
|
}
|
|
70606
70868
|
|
|
70607
70869
|
// src/permission/persona-paths.ts
|
|
70608
|
-
var
|
|
70870
|
+
var path80 = __toESM(require("path"), 1);
|
|
70609
70871
|
function getAllowedPersonaIds(grants, action) {
|
|
70610
70872
|
const ids = /* @__PURE__ */ new Set();
|
|
70611
70873
|
for (const g3 of grants) {
|
|
@@ -70618,42 +70880,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
70618
70880
|
return ids;
|
|
70619
70881
|
}
|
|
70620
70882
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
70621
|
-
const target =
|
|
70883
|
+
const target = path80.resolve(absPath);
|
|
70622
70884
|
if (userWorkDir) {
|
|
70623
|
-
const u2 =
|
|
70624
|
-
const usep = u2.endsWith(
|
|
70885
|
+
const u2 = path80.resolve(userWorkDir);
|
|
70886
|
+
const usep = u2.endsWith(path80.sep) ? "" : path80.sep;
|
|
70625
70887
|
if (target === u2 || target.startsWith(u2 + usep)) return true;
|
|
70626
70888
|
}
|
|
70627
|
-
const root =
|
|
70628
|
-
const sep4 = root.endsWith(
|
|
70889
|
+
const root = path80.resolve(personaRoot);
|
|
70890
|
+
const sep4 = root.endsWith(path80.sep) ? "" : path80.sep;
|
|
70629
70891
|
if (!target.startsWith(root + sep4)) return false;
|
|
70630
|
-
const rel =
|
|
70892
|
+
const rel = path80.relative(root, target);
|
|
70631
70893
|
if (!rel || rel.startsWith("..")) return false;
|
|
70632
|
-
const personaId2 = rel.split(
|
|
70894
|
+
const personaId2 = rel.split(path80.sep)[0];
|
|
70633
70895
|
if (!personaId2) return false;
|
|
70634
70896
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
70635
70897
|
if (allowed === "*") return true;
|
|
70636
70898
|
return allowed.has(personaId2);
|
|
70637
70899
|
}
|
|
70638
70900
|
function personaIdFromPath(absPath, personaRoot) {
|
|
70639
|
-
const root =
|
|
70640
|
-
const target =
|
|
70641
|
-
const sep4 = root.endsWith(
|
|
70901
|
+
const root = path80.resolve(personaRoot);
|
|
70902
|
+
const target = path80.resolve(absPath);
|
|
70903
|
+
const sep4 = root.endsWith(path80.sep) ? "" : path80.sep;
|
|
70642
70904
|
if (!target.startsWith(root + sep4)) return null;
|
|
70643
|
-
const rel =
|
|
70905
|
+
const rel = path80.relative(root, target);
|
|
70644
70906
|
if (!rel || rel.startsWith("..")) return null;
|
|
70645
|
-
const id = rel.split(
|
|
70907
|
+
const id = rel.split(path80.sep)[0];
|
|
70646
70908
|
return id || null;
|
|
70647
70909
|
}
|
|
70648
70910
|
function isPathWithin(dir, absPath) {
|
|
70649
|
-
const d2 =
|
|
70650
|
-
const t2 =
|
|
70651
|
-
const sep4 = d2.endsWith(
|
|
70911
|
+
const d2 = path80.resolve(dir);
|
|
70912
|
+
const t2 = path80.resolve(absPath);
|
|
70913
|
+
const sep4 = d2.endsWith(path80.sep) ? "" : path80.sep;
|
|
70652
70914
|
return t2 === d2 || t2.startsWith(d2 + sep4);
|
|
70653
70915
|
}
|
|
70654
70916
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
70655
70917
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
70656
|
-
return personaIdFromPath(
|
|
70918
|
+
return personaIdFromPath(path80.resolve(absPath), personaRoot) === personaId2;
|
|
70657
70919
|
}
|
|
70658
70920
|
|
|
70659
70921
|
// src/handlers/history.ts
|
|
@@ -70706,7 +70968,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70706
70968
|
if (!pid) return false;
|
|
70707
70969
|
return isGuestPathAllowed(
|
|
70708
70970
|
ctx.grants,
|
|
70709
|
-
|
|
70971
|
+
path81.join(personaRoot, pid),
|
|
70710
70972
|
personaRoot,
|
|
70711
70973
|
"read",
|
|
70712
70974
|
userWorkDir
|
|
@@ -70718,7 +70980,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70718
70980
|
};
|
|
70719
70981
|
const list = async (frame, _client, ctx) => {
|
|
70720
70982
|
const args = HistoryListArgs.parse(frame);
|
|
70721
|
-
assertGuestPath(ctx,
|
|
70983
|
+
assertGuestPath(ctx, path81.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
70722
70984
|
const sessions = await history.listSessions(args);
|
|
70723
70985
|
return { response: { type: "history:list", sessions } };
|
|
70724
70986
|
};
|
|
@@ -70766,14 +71028,14 @@ function buildHistoryHandlers(deps) {
|
|
|
70766
71028
|
};
|
|
70767
71029
|
const subagents = async (frame, _client, ctx) => {
|
|
70768
71030
|
const args = HistorySubagentsArgs.parse(frame);
|
|
70769
|
-
assertGuestPath(ctx,
|
|
71031
|
+
assertGuestPath(ctx, path81.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
70770
71032
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
70771
71033
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
70772
71034
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
70773
71035
|
};
|
|
70774
71036
|
const subagentRead = async (frame, _client, ctx) => {
|
|
70775
71037
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
70776
|
-
assertGuestPath(ctx,
|
|
71038
|
+
assertGuestPath(ctx, path81.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
70777
71039
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
70778
71040
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
70779
71041
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -70783,7 +71045,7 @@ function buildHistoryHandlers(deps) {
|
|
|
70783
71045
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
70784
71046
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
70785
71047
|
const filtered = dirs.filter(
|
|
70786
|
-
(d2) => isGuestPathAllowed(ctx.grants,
|
|
71048
|
+
(d2) => isGuestPathAllowed(ctx.grants, path81.resolve(d2.cwd), personaRoot, "read", userWorkDir)
|
|
70787
71049
|
);
|
|
70788
71050
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
70789
71051
|
}
|
|
@@ -70800,17 +71062,17 @@ function buildHistoryHandlers(deps) {
|
|
|
70800
71062
|
}
|
|
70801
71063
|
|
|
70802
71064
|
// src/handlers/projects.ts
|
|
70803
|
-
var
|
|
70804
|
-
var
|
|
70805
|
-
var
|
|
71065
|
+
var fs78 = __toESM(require("fs"), 1);
|
|
71066
|
+
var os26 = __toESM(require("os"), 1);
|
|
71067
|
+
var path82 = __toESM(require("path"), 1);
|
|
70806
71068
|
var import_node_child_process18 = require("child_process");
|
|
70807
71069
|
init_protocol();
|
|
70808
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
71070
|
+
var DEFAULT_PROJECTS_ROOT = path82.join(os26.homedir(), "Documents", "ChatGPT");
|
|
70809
71071
|
function allocateDir(root, name) {
|
|
70810
|
-
let candidate =
|
|
71072
|
+
let candidate = path82.join(root, name);
|
|
70811
71073
|
let n2 = 2;
|
|
70812
|
-
while (
|
|
70813
|
-
candidate =
|
|
71074
|
+
while (fs78.existsSync(candidate)) {
|
|
71075
|
+
candidate = path82.join(root, `${name} ${n2}`);
|
|
70814
71076
|
n2 += 1;
|
|
70815
71077
|
}
|
|
70816
71078
|
return candidate;
|
|
@@ -70838,7 +71100,7 @@ function buildProjectHandlers(deps) {
|
|
|
70838
71100
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
70839
71101
|
}
|
|
70840
71102
|
try {
|
|
70841
|
-
if (!
|
|
71103
|
+
if (!fs78.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
70842
71104
|
} catch {
|
|
70843
71105
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
70844
71106
|
}
|
|
@@ -70854,7 +71116,7 @@ function buildProjectHandlers(deps) {
|
|
|
70854
71116
|
let target;
|
|
70855
71117
|
if (args.path) {
|
|
70856
71118
|
try {
|
|
70857
|
-
if (!
|
|
71119
|
+
if (!fs78.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
70858
71120
|
} catch {
|
|
70859
71121
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
70860
71122
|
}
|
|
@@ -70862,15 +71124,15 @@ function buildProjectHandlers(deps) {
|
|
|
70862
71124
|
} else {
|
|
70863
71125
|
const name = args.name;
|
|
70864
71126
|
try {
|
|
70865
|
-
|
|
71127
|
+
fs78.mkdirSync(root, { recursive: true });
|
|
70866
71128
|
target = allocateDir(root, name);
|
|
70867
|
-
|
|
71129
|
+
fs78.mkdirSync(target);
|
|
70868
71130
|
} catch (err) {
|
|
70869
71131
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
70870
71132
|
}
|
|
70871
71133
|
const git2 = (0, import_node_child_process18.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
70872
71134
|
if (git2.status !== 0) {
|
|
70873
|
-
|
|
71135
|
+
fs78.rmSync(target, { recursive: true, force: true });
|
|
70874
71136
|
throw new ClawdError(
|
|
70875
71137
|
ERROR_CODES.INVALID_CWD,
|
|
70876
71138
|
`git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
|
|
@@ -70895,9 +71157,9 @@ function buildProjectHandlers(deps) {
|
|
|
70895
71157
|
}
|
|
70896
71158
|
|
|
70897
71159
|
// src/handlers/workspace.ts
|
|
70898
|
-
var
|
|
71160
|
+
var path83 = __toESM(require("path"), 1);
|
|
70899
71161
|
init_protocol();
|
|
70900
|
-
var
|
|
71162
|
+
var os27 = __toESM(require("os"), 1);
|
|
70901
71163
|
init_protocol();
|
|
70902
71164
|
init_protocol();
|
|
70903
71165
|
function buildEnabledPluginNames(personaManager, personaId2) {
|
|
@@ -70937,23 +71199,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
70937
71199
|
const list = async (frame, _client, ctx) => {
|
|
70938
71200
|
const args = WorkspaceListArgs.parse(frame);
|
|
70939
71201
|
const isGuest = ctx?.principal.kind === "guest";
|
|
70940
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
70941
|
-
const resolvedCwd =
|
|
70942
|
-
const target = args.path ?
|
|
71202
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os27.homedir();
|
|
71203
|
+
const resolvedCwd = path83.resolve(args.cwd ?? fallbackCwd);
|
|
71204
|
+
const target = args.path ? path83.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
70943
71205
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
70944
71206
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
70945
71207
|
return { response: { type: "workspace:list", ...res } };
|
|
70946
71208
|
};
|
|
70947
71209
|
const read = async (frame, _client, ctx) => {
|
|
70948
71210
|
const args = WorkspaceReadArgs.parse(frame);
|
|
70949
|
-
const target =
|
|
71211
|
+
const target = path83.isAbsolute(args.path) ? path83.resolve(args.path) : path83.resolve(args.cwd, args.path);
|
|
70950
71212
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
70951
71213
|
const res = workspace.read(args);
|
|
70952
71214
|
return { response: { type: "workspace:read", ...res } };
|
|
70953
71215
|
};
|
|
70954
71216
|
const skillsList = async (frame, _client, ctx) => {
|
|
70955
71217
|
const args = SkillsListArgs.parse(frame);
|
|
70956
|
-
const cwdAbs =
|
|
71218
|
+
const cwdAbs = path83.resolve(args.cwd);
|
|
70957
71219
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
70958
71220
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
70959
71221
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -70965,7 +71227,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
70965
71227
|
};
|
|
70966
71228
|
const agentsList = async (frame, _client, ctx) => {
|
|
70967
71229
|
const args = AgentsListArgs.parse(frame);
|
|
70968
|
-
const cwdAbs =
|
|
71230
|
+
const cwdAbs = path83.resolve(args.cwd);
|
|
70969
71231
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
70970
71232
|
if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
|
|
70971
71233
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -70987,20 +71249,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
70987
71249
|
}
|
|
70988
71250
|
|
|
70989
71251
|
// src/handlers/git.ts
|
|
70990
|
-
var
|
|
71252
|
+
var path85 = __toESM(require("path"), 1);
|
|
70991
71253
|
init_protocol();
|
|
70992
71254
|
init_protocol();
|
|
70993
71255
|
|
|
70994
71256
|
// src/workspace/git.ts
|
|
70995
71257
|
var import_node_child_process19 = require("child_process");
|
|
70996
|
-
var
|
|
70997
|
-
var
|
|
71258
|
+
var import_node_fs61 = __toESM(require("fs"), 1);
|
|
71259
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
70998
71260
|
var import_node_util2 = require("util");
|
|
70999
71261
|
var pexec = (0, import_node_util2.promisify)(import_node_child_process19.execFile);
|
|
71000
71262
|
function normalizePath(p3) {
|
|
71001
|
-
const resolved =
|
|
71263
|
+
const resolved = import_node_path67.default.resolve(p3);
|
|
71002
71264
|
try {
|
|
71003
|
-
return
|
|
71265
|
+
return import_node_fs61.default.realpathSync(resolved);
|
|
71004
71266
|
} catch {
|
|
71005
71267
|
return resolved;
|
|
71006
71268
|
}
|
|
@@ -71074,7 +71336,7 @@ async function listGitBranches(cwd) {
|
|
|
71074
71336
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
71075
71337
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
71076
71338
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
71077
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
71339
|
+
if (!isGuestPathAllowed(ctx.grants, path85.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
71078
71340
|
throw new ClawdError(
|
|
71079
71341
|
ERROR_CODES.UNAUTHORIZED,
|
|
71080
71342
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -71331,12 +71593,12 @@ async function queryCodexAccount(deps = {}) {
|
|
|
71331
71593
|
}
|
|
71332
71594
|
|
|
71333
71595
|
// src/tools/pi-account.ts
|
|
71334
|
-
var
|
|
71335
|
-
var
|
|
71596
|
+
var import_node_fs62 = __toESM(require("fs"), 1);
|
|
71597
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
71336
71598
|
function readPiCredentials(agentDir) {
|
|
71337
71599
|
let raw;
|
|
71338
71600
|
try {
|
|
71339
|
-
raw = JSON.parse(
|
|
71601
|
+
raw = JSON.parse(import_node_fs62.default.readFileSync(import_node_path68.default.join(agentDir, "auth.json"), "utf8"));
|
|
71340
71602
|
} catch {
|
|
71341
71603
|
return {};
|
|
71342
71604
|
}
|
|
@@ -71419,6 +71681,129 @@ function buildEngineHandlers(deps, overrides = {}) {
|
|
|
71419
71681
|
return { "engine:status": status, "engine:connectPool": connectPool };
|
|
71420
71682
|
}
|
|
71421
71683
|
|
|
71684
|
+
// src/tools/subscription-channels-apply.ts
|
|
71685
|
+
var import_node_fs63 = __toESM(require("fs"), 1);
|
|
71686
|
+
var import_node_os25 = __toESM(require("os"), 1);
|
|
71687
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
71688
|
+
var TABLE_HEADER = /^\s*\[\[?\s*([A-Za-z0-9_.-]+)\s*\]\]?\s*(?:#.*)?$/;
|
|
71689
|
+
var KEY_LINE = /^\s*([A-Za-z0-9_.-]+)\s*=/;
|
|
71690
|
+
function stripCodexProvider(text) {
|
|
71691
|
+
const out = [];
|
|
71692
|
+
let inProviderSection = false;
|
|
71693
|
+
for (const line of text.split("\n")) {
|
|
71694
|
+
const headerMatch = TABLE_HEADER.exec(line);
|
|
71695
|
+
if (headerMatch) {
|
|
71696
|
+
const section = headerMatch[1].trim();
|
|
71697
|
+
inProviderSection = section === "model_providers" || section.startsWith("model_providers.");
|
|
71698
|
+
if (inProviderSection) continue;
|
|
71699
|
+
out.push(line);
|
|
71700
|
+
continue;
|
|
71701
|
+
}
|
|
71702
|
+
if (inProviderSection) continue;
|
|
71703
|
+
const keyMatch = KEY_LINE.exec(line);
|
|
71704
|
+
if (keyMatch) {
|
|
71705
|
+
const key = keyMatch[1].trim();
|
|
71706
|
+
if (key === "model_provider" || key.startsWith("model_providers.")) {
|
|
71707
|
+
continue;
|
|
71708
|
+
}
|
|
71709
|
+
}
|
|
71710
|
+
out.push(line);
|
|
71711
|
+
}
|
|
71712
|
+
return out.join("\n").trim();
|
|
71713
|
+
}
|
|
71714
|
+
function applyCodexSubscriptionChannel(opts) {
|
|
71715
|
+
const codexHome = opts.codexHome || process.env.CODEX_HOME || import_node_path69.default.join(import_node_os25.default.homedir(), ".codex");
|
|
71716
|
+
import_node_fs63.default.mkdirSync(codexHome, { recursive: true });
|
|
71717
|
+
const configFile = import_node_path69.default.join(codexHome, "config.toml");
|
|
71718
|
+
const original = import_node_fs63.default.existsSync(configFile) ? import_node_fs63.default.readFileSync(configFile, "utf8") : "";
|
|
71719
|
+
const rest = stripCodexProvider(original);
|
|
71720
|
+
let content;
|
|
71721
|
+
if (opts.channel) {
|
|
71722
|
+
const ch = opts.channel;
|
|
71723
|
+
content = [
|
|
71724
|
+
'model_provider = "cliproxyapi"',
|
|
71725
|
+
...rest ? ["", rest] : [],
|
|
71726
|
+
"",
|
|
71727
|
+
"[model_providers.cliproxyapi]",
|
|
71728
|
+
'name = "cliproxyapi"',
|
|
71729
|
+
`base_url = ${JSON.stringify(ch.baseUrl)}`,
|
|
71730
|
+
'wire_api = "responses"',
|
|
71731
|
+
`auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
|
|
71732
|
+
""
|
|
71733
|
+
].join("\n");
|
|
71734
|
+
} else {
|
|
71735
|
+
content = [
|
|
71736
|
+
'model_provider = "openai"',
|
|
71737
|
+
...rest ? ["", rest] : [],
|
|
71738
|
+
""
|
|
71739
|
+
].join("\n");
|
|
71740
|
+
}
|
|
71741
|
+
const tmpFile = `${configFile}.tmp.${Date.now()}`;
|
|
71742
|
+
import_node_fs63.default.writeFileSync(tmpFile, content, { mode: 384 });
|
|
71743
|
+
import_node_fs63.default.renameSync(tmpFile, configFile);
|
|
71744
|
+
}
|
|
71745
|
+
function applyPiSubscriptionChannel(opts) {
|
|
71746
|
+
const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path69.default.join(import_node_os25.default.homedir(), ".pi", "agent");
|
|
71747
|
+
if (!import_node_fs63.default.existsSync(agentDir)) return false;
|
|
71748
|
+
const configFile = import_node_path69.default.join(agentDir, "cliproxyapi.json");
|
|
71749
|
+
if (opts.channel) {
|
|
71750
|
+
const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
|
|
71751
|
+
const tmp = `${configFile}.tmp.${Date.now()}`;
|
|
71752
|
+
import_node_fs63.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
71753
|
+
import_node_fs63.default.renameSync(tmp, configFile);
|
|
71754
|
+
return true;
|
|
71755
|
+
}
|
|
71756
|
+
return false;
|
|
71757
|
+
}
|
|
71758
|
+
|
|
71759
|
+
// src/handlers/channels.ts
|
|
71760
|
+
function buildChannelsHandlers(deps) {
|
|
71761
|
+
const get = async () => {
|
|
71762
|
+
return { response: deps.store.list() };
|
|
71763
|
+
};
|
|
71764
|
+
const save = async (frame) => {
|
|
71765
|
+
const args = parseArgs2(SubscriptionChannelSaveArgsSchema, frame, "subscriptionChannel:save");
|
|
71766
|
+
const channel = deps.store.save(args);
|
|
71767
|
+
const state = deps.store.list();
|
|
71768
|
+
if (state.activeChannelId === channel.id) {
|
|
71769
|
+
applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
|
|
71770
|
+
applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
|
|
71771
|
+
await deps.manager.getCapabilities("codex", { refresh: true });
|
|
71772
|
+
}
|
|
71773
|
+
return { response: deps.store.list() };
|
|
71774
|
+
};
|
|
71775
|
+
const del = async (frame) => {
|
|
71776
|
+
const args = parseArgs2(SubscriptionChannelDeleteArgsSchema, frame, "subscriptionChannel:delete");
|
|
71777
|
+
const wasActive = deps.store.list().activeChannelId === args.id;
|
|
71778
|
+
deps.store.delete(args.id);
|
|
71779
|
+
if (wasActive) {
|
|
71780
|
+
const newActive = deps.store.getActive();
|
|
71781
|
+
applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel: newActive });
|
|
71782
|
+
applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel: newActive });
|
|
71783
|
+
if (newActive) {
|
|
71784
|
+
await deps.manager.getCapabilities("codex", { refresh: true });
|
|
71785
|
+
}
|
|
71786
|
+
}
|
|
71787
|
+
return { response: { ok: true } };
|
|
71788
|
+
};
|
|
71789
|
+
const activate = async (frame) => {
|
|
71790
|
+
const args = parseArgs2(SubscriptionChannelActivateArgsSchema, frame, "subscriptionChannel:activate");
|
|
71791
|
+
const channel = deps.store.setActive(args.id);
|
|
71792
|
+
applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
|
|
71793
|
+
applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
|
|
71794
|
+
if (channel) {
|
|
71795
|
+
await deps.manager.getCapabilities("codex", { refresh: true });
|
|
71796
|
+
}
|
|
71797
|
+
return { response: { ok: true } };
|
|
71798
|
+
};
|
|
71799
|
+
return {
|
|
71800
|
+
"subscriptionChannel:get": get,
|
|
71801
|
+
"subscriptionChannel:save": save,
|
|
71802
|
+
"subscriptionChannel:delete": del,
|
|
71803
|
+
"subscriptionChannel:activate": activate
|
|
71804
|
+
};
|
|
71805
|
+
}
|
|
71806
|
+
|
|
71422
71807
|
// src/handlers/inbox.ts
|
|
71423
71808
|
init_protocol();
|
|
71424
71809
|
function resolvePeerDeviceId(ctx, argsPeerDeviceId) {
|
|
@@ -72053,7 +72438,7 @@ function buildDashboardHandlers(deps) {
|
|
|
72053
72438
|
}
|
|
72054
72439
|
|
|
72055
72440
|
// src/handlers/meta.ts
|
|
72056
|
-
var
|
|
72441
|
+
var import_node_os26 = __toESM(require("os"), 1);
|
|
72057
72442
|
init_protocol();
|
|
72058
72443
|
|
|
72059
72444
|
// src/handlers/method-grants.ts
|
|
@@ -72252,6 +72637,10 @@ var METHOD_GRANT_MAP = {
|
|
|
72252
72637
|
"engine:status": ADMIN_ANY,
|
|
72253
72638
|
// engine:connectPool(接入号池,spec 2026-09-17-onboarding-pool-key):改本机 ~/.codex/config.toml,owner-only
|
|
72254
72639
|
"engine:connectPool": ADMIN_ANY,
|
|
72640
|
+
"subscriptionChannel:get": ADMIN_ANY,
|
|
72641
|
+
"subscriptionChannel:save": ADMIN_ANY,
|
|
72642
|
+
"subscriptionChannel:delete": ADMIN_ANY,
|
|
72643
|
+
"subscriptionChannel:activate": ADMIN_ANY,
|
|
72255
72644
|
"persona:create": ADMIN_ANY,
|
|
72256
72645
|
// persona:list / persona:get 下沉到 CAPABILITY_SCOPED:guest 调用合法
|
|
72257
72646
|
// (list 用于 People 面板展开对方分享的 personas;get 用于 guest 视角下
|
|
@@ -72369,21 +72758,21 @@ function computeMethodAccess(args) {
|
|
|
72369
72758
|
}
|
|
72370
72759
|
|
|
72371
72760
|
// src/version.ts
|
|
72372
|
-
var version = "0.2.
|
|
72761
|
+
var version = "0.2.591".length > 0 ? "0.2.591" : "dev";
|
|
72373
72762
|
|
|
72374
72763
|
// src/cli-probe/probe.ts
|
|
72375
|
-
var
|
|
72376
|
-
var
|
|
72764
|
+
var fs82 = __toESM(require("fs"), 1);
|
|
72765
|
+
var path88 = __toESM(require("path"), 1);
|
|
72377
72766
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
72378
72767
|
var BIN_NAME = "clawd";
|
|
72379
72768
|
var MAX_PARENT_HOPS = 5;
|
|
72380
72769
|
function probeGlobalCli(pathEnv) {
|
|
72381
72770
|
if (!pathEnv) return null;
|
|
72382
|
-
for (const dir of pathEnv.split(
|
|
72771
|
+
for (const dir of pathEnv.split(path88.delimiter)) {
|
|
72383
72772
|
if (!dir) continue;
|
|
72384
72773
|
let real;
|
|
72385
72774
|
try {
|
|
72386
|
-
real =
|
|
72775
|
+
real = fs82.realpathSync(path88.join(dir, BIN_NAME));
|
|
72387
72776
|
} catch {
|
|
72388
72777
|
continue;
|
|
72389
72778
|
}
|
|
@@ -72393,15 +72782,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
72393
72782
|
return null;
|
|
72394
72783
|
}
|
|
72395
72784
|
function readOwnPackageVersion(entryPath) {
|
|
72396
|
-
let dir =
|
|
72785
|
+
let dir = path88.dirname(entryPath);
|
|
72397
72786
|
for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
|
|
72398
72787
|
try {
|
|
72399
|
-
const raw =
|
|
72788
|
+
const raw = fs82.readFileSync(path88.join(dir, "package.json"), "utf8");
|
|
72400
72789
|
const pkg = JSON.parse(raw);
|
|
72401
72790
|
if (pkg.name !== PKG_NAME) return null;
|
|
72402
72791
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
72403
72792
|
} catch {
|
|
72404
|
-
const parent =
|
|
72793
|
+
const parent = path88.dirname(dir);
|
|
72405
72794
|
if (parent === dir) return null;
|
|
72406
72795
|
dir = parent;
|
|
72407
72796
|
}
|
|
@@ -72437,7 +72826,7 @@ function buildReadyFrame(deps, client) {
|
|
|
72437
72826
|
return {
|
|
72438
72827
|
version,
|
|
72439
72828
|
protocolVersion: PROTOCOL_VERSION,
|
|
72440
|
-
hostname:
|
|
72829
|
+
hostname: import_node_os26.default.hostname(),
|
|
72441
72830
|
os: process.platform,
|
|
72442
72831
|
tools,
|
|
72443
72832
|
runningSessions: info.runningSessions,
|
|
@@ -72577,7 +72966,7 @@ function buildPersonaHandlers(deps) {
|
|
|
72577
72966
|
}
|
|
72578
72967
|
|
|
72579
72968
|
// src/handlers/attachment.ts
|
|
72580
|
-
var
|
|
72969
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
72581
72970
|
init_protocol();
|
|
72582
72971
|
init_protocol();
|
|
72583
72972
|
function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
|
|
@@ -72656,12 +73045,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
72656
73045
|
`session ${args.sessionId} scope unresolved`
|
|
72657
73046
|
);
|
|
72658
73047
|
}
|
|
72659
|
-
const cwdAbs =
|
|
72660
|
-
const candidateAbs =
|
|
73048
|
+
const cwdAbs = import_node_path70.default.resolve(sessionFile.cwd);
|
|
73049
|
+
const candidateAbs = import_node_path70.default.isAbsolute(args.relPath) ? import_node_path70.default.resolve(args.relPath) : import_node_path70.default.resolve(cwdAbs, args.relPath);
|
|
72661
73050
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
72662
73051
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
72663
73052
|
const entry = entries.find((e) => {
|
|
72664
|
-
const storedAbs =
|
|
73053
|
+
const storedAbs = import_node_path70.default.isAbsolute(e.relPath) ? import_node_path70.default.resolve(e.relPath) : import_node_path70.default.resolve(cwdAbs, e.relPath);
|
|
72665
73054
|
return storedAbs === candidateAbs && !e.stale;
|
|
72666
73055
|
});
|
|
72667
73056
|
if (!entry) {
|
|
@@ -72685,7 +73074,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
72685
73074
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
72686
73075
|
const f2 = deps.sessionStore.read(sessionId);
|
|
72687
73076
|
if (!f2) return;
|
|
72688
|
-
assertGuestAttachmentPath(ctx,
|
|
73077
|
+
assertGuestAttachmentPath(ctx, import_node_path70.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
72689
73078
|
}
|
|
72690
73079
|
const groupAdd = async (frame, _client, ctx) => {
|
|
72691
73080
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -72700,8 +73089,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
72700
73089
|
if (!scope) {
|
|
72701
73090
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
72702
73091
|
}
|
|
72703
|
-
const cwdAbs =
|
|
72704
|
-
const candidateAbs =
|
|
73092
|
+
const cwdAbs = import_node_path70.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
73093
|
+
const candidateAbs = import_node_path70.default.isAbsolute(args.relPath) ? import_node_path70.default.resolve(args.relPath) : import_node_path70.default.resolve(cwdAbs, args.relPath);
|
|
72705
73094
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
72706
73095
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
72707
73096
|
const size = 0;
|
|
@@ -72760,19 +73149,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
72760
73149
|
|
|
72761
73150
|
// src/handlers/extension.ts
|
|
72762
73151
|
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
72763
|
-
var
|
|
73152
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
72764
73153
|
init_protocol();
|
|
72765
73154
|
|
|
72766
73155
|
// src/extension/bundle-zip.ts
|
|
72767
73156
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
72768
|
-
var
|
|
73157
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
72769
73158
|
var import_node_crypto22 = __toESM(require("crypto"), 1);
|
|
72770
73159
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
72771
73160
|
async function bundleExtensionDir(dir) {
|
|
72772
73161
|
const entries = await listFilesSorted(dir);
|
|
72773
73162
|
const zip = new import_jszip2.default();
|
|
72774
73163
|
for (const rel of entries) {
|
|
72775
|
-
const abs =
|
|
73164
|
+
const abs = import_node_path71.default.join(dir, rel);
|
|
72776
73165
|
const content = await import_promises12.default.readFile(abs);
|
|
72777
73166
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
72778
73167
|
}
|
|
@@ -72793,7 +73182,7 @@ async function listFilesSorted(rootDir) {
|
|
|
72793
73182
|
return out;
|
|
72794
73183
|
}
|
|
72795
73184
|
async function walk(absRoot, relPrefix, out) {
|
|
72796
|
-
const dirAbs =
|
|
73185
|
+
const dirAbs = import_node_path71.default.join(absRoot, relPrefix);
|
|
72797
73186
|
const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
|
|
72798
73187
|
for (const e of entries) {
|
|
72799
73188
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -72847,25 +73236,25 @@ function computePublishCheck(args) {
|
|
|
72847
73236
|
|
|
72848
73237
|
// src/extension/install-flow.ts
|
|
72849
73238
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
72850
|
-
var
|
|
72851
|
-
var
|
|
73239
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
73240
|
+
var import_node_os28 = __toESM(require("os"), 1);
|
|
72852
73241
|
var import_node_crypto23 = __toESM(require("crypto"), 1);
|
|
72853
73242
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
72854
73243
|
|
|
72855
73244
|
// src/extension/paths.ts
|
|
72856
|
-
var
|
|
72857
|
-
var
|
|
73245
|
+
var import_node_os27 = __toESM(require("os"), 1);
|
|
73246
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
72858
73247
|
function clawdHomeRoot(override) {
|
|
72859
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
73248
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path72.default.join(import_node_os27.default.homedir(), ".clawd");
|
|
72860
73249
|
}
|
|
72861
73250
|
function extensionsRoot(override) {
|
|
72862
|
-
return
|
|
73251
|
+
return import_node_path72.default.join(clawdHomeRoot(override), "extensions");
|
|
72863
73252
|
}
|
|
72864
73253
|
function publishedChannelsFile(override) {
|
|
72865
|
-
return
|
|
73254
|
+
return import_node_path72.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
72866
73255
|
}
|
|
72867
73256
|
function bundleCacheRoot(override) {
|
|
72868
|
-
return
|
|
73257
|
+
return import_node_path72.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
72869
73258
|
}
|
|
72870
73259
|
|
|
72871
73260
|
// src/extension/install-flow.ts
|
|
@@ -72892,7 +73281,7 @@ async function installFromChannel(args, deps) {
|
|
|
72892
73281
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
72893
73282
|
}
|
|
72894
73283
|
for (const name of Object.keys(zip.files)) {
|
|
72895
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73284
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path73.default.isAbsolute(name)) {
|
|
72896
73285
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
72897
73286
|
}
|
|
72898
73287
|
}
|
|
@@ -72924,7 +73313,7 @@ async function installFromChannel(args, deps) {
|
|
|
72924
73313
|
);
|
|
72925
73314
|
}
|
|
72926
73315
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
72927
|
-
const destDir =
|
|
73316
|
+
const destDir = import_node_path73.default.join(deps.extensionsRoot, localExtId);
|
|
72928
73317
|
let destExists = false;
|
|
72929
73318
|
try {
|
|
72930
73319
|
await import_promises13.default.access(destDir);
|
|
@@ -72938,16 +73327,16 @@ async function installFromChannel(args, deps) {
|
|
|
72938
73327
|
);
|
|
72939
73328
|
}
|
|
72940
73329
|
const stage = await import_promises13.default.mkdtemp(
|
|
72941
|
-
|
|
73330
|
+
import_node_path73.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
72942
73331
|
);
|
|
72943
73332
|
try {
|
|
72944
73333
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
72945
|
-
const dest =
|
|
73334
|
+
const dest = import_node_path73.default.join(stage, name);
|
|
72946
73335
|
if (entry.dir) {
|
|
72947
73336
|
await import_promises13.default.mkdir(dest, { recursive: true });
|
|
72948
73337
|
continue;
|
|
72949
73338
|
}
|
|
72950
|
-
await import_promises13.default.mkdir(
|
|
73339
|
+
await import_promises13.default.mkdir(import_node_path73.default.dirname(dest), { recursive: true });
|
|
72951
73340
|
if (name === "manifest.json") {
|
|
72952
73341
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
72953
73342
|
await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -72968,8 +73357,8 @@ async function installFromChannel(args, deps) {
|
|
|
72968
73357
|
|
|
72969
73358
|
// src/extension/update-flow.ts
|
|
72970
73359
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
72971
|
-
var
|
|
72972
|
-
var
|
|
73360
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
73361
|
+
var import_node_os29 = __toESM(require("os"), 1);
|
|
72973
73362
|
var import_node_crypto24 = __toESM(require("crypto"), 1);
|
|
72974
73363
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
72975
73364
|
var UpdateError = class extends Error {
|
|
@@ -72985,11 +73374,11 @@ async function updateFromChannel(args, deps) {
|
|
|
72985
73374
|
channelRef.extId,
|
|
72986
73375
|
channelRef.ownerPrincipalId
|
|
72987
73376
|
);
|
|
72988
|
-
const liveDir =
|
|
73377
|
+
const liveDir = import_node_path74.default.join(deps.extensionsRoot, localExtId);
|
|
72989
73378
|
const prevDir = `${liveDir}.prev`;
|
|
72990
73379
|
let existingVersion;
|
|
72991
73380
|
try {
|
|
72992
|
-
const raw = await import_promises14.default.readFile(
|
|
73381
|
+
const raw = await import_promises14.default.readFile(import_node_path74.default.join(liveDir, "manifest.json"), "utf8");
|
|
72993
73382
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
72994
73383
|
if (!parsed2.success) {
|
|
72995
73384
|
throw new UpdateError(
|
|
@@ -73022,7 +73411,7 @@ async function updateFromChannel(args, deps) {
|
|
|
73022
73411
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
73023
73412
|
}
|
|
73024
73413
|
for (const name of Object.keys(zip.files)) {
|
|
73025
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
73414
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path74.default.isAbsolute(name)) {
|
|
73026
73415
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
73027
73416
|
}
|
|
73028
73417
|
}
|
|
@@ -73057,16 +73446,16 @@ async function updateFromChannel(args, deps) {
|
|
|
73057
73446
|
await import_promises14.default.rm(prevDir, { recursive: true, force: true });
|
|
73058
73447
|
await import_promises14.default.rename(liveDir, prevDir);
|
|
73059
73448
|
const stage = await import_promises14.default.mkdtemp(
|
|
73060
|
-
|
|
73449
|
+
import_node_path74.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
73061
73450
|
);
|
|
73062
73451
|
try {
|
|
73063
73452
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
73064
|
-
const dest =
|
|
73453
|
+
const dest = import_node_path74.default.join(stage, name);
|
|
73065
73454
|
if (entry.dir) {
|
|
73066
73455
|
await import_promises14.default.mkdir(dest, { recursive: true });
|
|
73067
73456
|
continue;
|
|
73068
73457
|
}
|
|
73069
|
-
await import_promises14.default.mkdir(
|
|
73458
|
+
await import_promises14.default.mkdir(import_node_path74.default.dirname(dest), { recursive: true });
|
|
73070
73459
|
if (name === "manifest.json") {
|
|
73071
73460
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
73072
73461
|
await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -73133,7 +73522,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73133
73522
|
);
|
|
73134
73523
|
}
|
|
73135
73524
|
}
|
|
73136
|
-
const manifestPath =
|
|
73525
|
+
const manifestPath = import_node_path75.default.join(root, extId, "manifest.json");
|
|
73137
73526
|
const manifest = await readManifest(root, extId);
|
|
73138
73527
|
const next = { ...manifest, version: newVersion };
|
|
73139
73528
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -73141,7 +73530,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
73141
73530
|
await import_promises15.default.rename(tmp, manifestPath);
|
|
73142
73531
|
}
|
|
73143
73532
|
async function readManifest(root, extId) {
|
|
73144
|
-
const file =
|
|
73533
|
+
const file = import_node_path75.default.join(root, extId, "manifest.json");
|
|
73145
73534
|
let raw;
|
|
73146
73535
|
try {
|
|
73147
73536
|
raw = await import_promises15.default.readFile(file, "utf8");
|
|
@@ -73225,7 +73614,7 @@ function buildExtensionHandlers(deps) {
|
|
|
73225
73614
|
};
|
|
73226
73615
|
async function buildSnapshotMeta(extId) {
|
|
73227
73616
|
const manifest = await readManifest(deps.root, extId);
|
|
73228
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
73617
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path75.default.join(deps.root, extId));
|
|
73229
73618
|
return { manifest, contentHash: sha256, buffer };
|
|
73230
73619
|
}
|
|
73231
73620
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -74053,7 +74442,7 @@ function buildVisitorHandlers(deps) {
|
|
|
74053
74442
|
|
|
74054
74443
|
// src/extension/registry.ts
|
|
74055
74444
|
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
74056
|
-
var
|
|
74445
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
74057
74446
|
async function loadAll(root) {
|
|
74058
74447
|
let entries;
|
|
74059
74448
|
try {
|
|
@@ -74066,13 +74455,13 @@ async function loadAll(root) {
|
|
|
74066
74455
|
for (const ent of entries) {
|
|
74067
74456
|
if (!ent.isDirectory()) continue;
|
|
74068
74457
|
if (ent.name.startsWith(".")) continue;
|
|
74069
|
-
records.push(await loadOne(
|
|
74458
|
+
records.push(await loadOne(import_node_path76.default.join(root, ent.name), ent.name));
|
|
74070
74459
|
}
|
|
74071
74460
|
records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
|
|
74072
74461
|
return records;
|
|
74073
74462
|
}
|
|
74074
74463
|
async function loadOne(dir, dirName) {
|
|
74075
|
-
const manifestPath =
|
|
74464
|
+
const manifestPath = import_node_path76.default.join(dir, "manifest.json");
|
|
74076
74465
|
let raw;
|
|
74077
74466
|
try {
|
|
74078
74467
|
raw = await import_promises17.default.readFile(manifestPath, "utf8");
|
|
@@ -74117,7 +74506,7 @@ async function loadOne(dir, dirName) {
|
|
|
74117
74506
|
|
|
74118
74507
|
// src/extension/uninstall.ts
|
|
74119
74508
|
var import_promises18 = __toESM(require("fs/promises"), 1);
|
|
74120
|
-
var
|
|
74509
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
74121
74510
|
var UninstallError = class extends Error {
|
|
74122
74511
|
constructor(code, message) {
|
|
74123
74512
|
super(message);
|
|
@@ -74126,7 +74515,7 @@ var UninstallError = class extends Error {
|
|
|
74126
74515
|
code;
|
|
74127
74516
|
};
|
|
74128
74517
|
async function uninstall(deps) {
|
|
74129
|
-
const dir =
|
|
74518
|
+
const dir = import_node_path77.default.join(deps.root, deps.extId);
|
|
74130
74519
|
try {
|
|
74131
74520
|
await import_promises18.default.access(dir);
|
|
74132
74521
|
} catch {
|
|
@@ -74144,14 +74533,14 @@ init_protocol();
|
|
|
74144
74533
|
|
|
74145
74534
|
// src/peer-ops/run-command.ts
|
|
74146
74535
|
var import_node_child_process23 = require("child_process");
|
|
74147
|
-
var
|
|
74536
|
+
var import_node_os30 = __toESM(require("os"), 1);
|
|
74148
74537
|
var DEFAULT_TIMEOUT_MS6 = 3e4;
|
|
74149
74538
|
var MAX_TIMEOUT_MS = 3e5;
|
|
74150
74539
|
var MAX_OUTPUT_BYTES = 1048576;
|
|
74151
74540
|
function runCommand2(command, opts = {}) {
|
|
74152
74541
|
const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6, MAX_TIMEOUT_MS);
|
|
74153
74542
|
return new Promise((resolve9) => {
|
|
74154
|
-
const child = (0, import_node_child_process23.spawn)("bash", ["-c", command], { cwd:
|
|
74543
|
+
const child = (0, import_node_child_process23.spawn)("bash", ["-c", command], { cwd: import_node_os30.default.homedir() });
|
|
74155
74544
|
const out = [];
|
|
74156
74545
|
const err = [];
|
|
74157
74546
|
let outBytes = 0;
|
|
@@ -74264,7 +74653,9 @@ function ensureGuest(ctx) {
|
|
|
74264
74653
|
|
|
74265
74654
|
// src/handlers/index.ts
|
|
74266
74655
|
function buildMethodHandlers(deps) {
|
|
74656
|
+
const channelStore = deps.subscriptionChannelStore ?? new SubscriptionChannelStore({ dataDir: deps.dataDir ?? deps.masterDataDir });
|
|
74267
74657
|
const handlers = {
|
|
74658
|
+
...buildChannelsHandlers({ store: channelStore, manager: deps.manager }),
|
|
74268
74659
|
...buildSessionHandlers({
|
|
74269
74660
|
...deps,
|
|
74270
74661
|
getTunnelUrl: deps.getTunnelUrl,
|
|
@@ -74342,7 +74733,7 @@ function buildMethodHandlers(deps) {
|
|
|
74342
74733
|
broadcast: deps.broadcastToOwners
|
|
74343
74734
|
}),
|
|
74344
74735
|
...buildMasterHandlers({
|
|
74345
|
-
authorityTablePath:
|
|
74736
|
+
authorityTablePath: import_node_path78.default.join(deps.masterDataDir, "master-authority.json")
|
|
74346
74737
|
}),
|
|
74347
74738
|
...buildTopicHandlers({
|
|
74348
74739
|
topicStore: deps.topicStore,
|
|
@@ -74485,7 +74876,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
74485
74876
|
|
|
74486
74877
|
// src/extension/runtime.ts
|
|
74487
74878
|
var import_node_child_process24 = require("child_process");
|
|
74488
|
-
var
|
|
74879
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
74489
74880
|
var import_promises19 = require("timers/promises");
|
|
74490
74881
|
|
|
74491
74882
|
// src/extension/port-allocator.ts
|
|
@@ -74586,7 +74977,7 @@ var Runtime = class {
|
|
|
74586
74977
|
/\$CLAWOS_EXT_PORT/g,
|
|
74587
74978
|
String(port)
|
|
74588
74979
|
);
|
|
74589
|
-
const dir =
|
|
74980
|
+
const dir = import_node_path79.default.join(this.root, extId);
|
|
74590
74981
|
const env = {
|
|
74591
74982
|
...process.env,
|
|
74592
74983
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -74698,7 +75089,7 @@ ${handle.stderrTail}`
|
|
|
74698
75089
|
|
|
74699
75090
|
// src/extension/published-channels.ts
|
|
74700
75091
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
74701
|
-
var
|
|
75092
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
74702
75093
|
init_zod();
|
|
74703
75094
|
var PublishedChannelsError = class extends Error {
|
|
74704
75095
|
constructor(code, message) {
|
|
@@ -74797,7 +75188,7 @@ var PublishedChannelStore = class {
|
|
|
74797
75188
|
)
|
|
74798
75189
|
};
|
|
74799
75190
|
const tmp = `${this.filePath}.tmp`;
|
|
74800
|
-
await import_promises20.default.mkdir(
|
|
75191
|
+
await import_promises20.default.mkdir(import_node_path80.default.dirname(this.filePath), { recursive: true });
|
|
74801
75192
|
await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
74802
75193
|
await import_promises20.default.rename(tmp, this.filePath);
|
|
74803
75194
|
}
|
|
@@ -74805,7 +75196,7 @@ var PublishedChannelStore = class {
|
|
|
74805
75196
|
|
|
74806
75197
|
// src/extension/bundle-cache.ts
|
|
74807
75198
|
var import_promises21 = __toESM(require("fs/promises"), 1);
|
|
74808
|
-
var
|
|
75199
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
74809
75200
|
var BundleCache = class {
|
|
74810
75201
|
constructor(rootDir) {
|
|
74811
75202
|
this.rootDir = rootDir;
|
|
@@ -74814,14 +75205,14 @@ var BundleCache = class {
|
|
|
74814
75205
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
74815
75206
|
async write(snapshotHash, buffer) {
|
|
74816
75207
|
await import_promises21.default.mkdir(this.rootDir, { recursive: true });
|
|
74817
|
-
const file =
|
|
75208
|
+
const file = import_node_path81.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
74818
75209
|
const tmp = `${file}.tmp`;
|
|
74819
75210
|
await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
|
|
74820
75211
|
await import_promises21.default.rename(tmp, file);
|
|
74821
75212
|
}
|
|
74822
75213
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
74823
75214
|
async read(snapshotHash) {
|
|
74824
|
-
const file =
|
|
75215
|
+
const file = import_node_path81.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
74825
75216
|
try {
|
|
74826
75217
|
return await import_promises21.default.readFile(file);
|
|
74827
75218
|
} catch (e) {
|
|
@@ -74831,7 +75222,7 @@ var BundleCache = class {
|
|
|
74831
75222
|
}
|
|
74832
75223
|
/** Idempotent — missing file is not an error. */
|
|
74833
75224
|
async delete(snapshotHash) {
|
|
74834
|
-
const file =
|
|
75225
|
+
const file = import_node_path81.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
74835
75226
|
await import_promises21.default.rm(file, { force: true });
|
|
74836
75227
|
}
|
|
74837
75228
|
};
|
|
@@ -74852,26 +75243,26 @@ async function startDaemon(config) {
|
|
|
74852
75243
|
},
|
|
74853
75244
|
source: "daemon",
|
|
74854
75245
|
sampling: logShippingCfg.sampling,
|
|
74855
|
-
homeDir:
|
|
75246
|
+
homeDir: import_node_os31.default.homedir()
|
|
74856
75247
|
});
|
|
74857
|
-
const logDir =
|
|
74858
|
-
|
|
75248
|
+
const logDir = import_node_path82.default.join(config.dataDir, "log");
|
|
75249
|
+
import_node_fs64.default.mkdirSync(logDir, { recursive: true });
|
|
74859
75250
|
const logger = createLogger({
|
|
74860
75251
|
level: config.logLevel,
|
|
74861
|
-
file:
|
|
75252
|
+
file: import_node_path82.default.join(logDir, "clawd.log"),
|
|
74862
75253
|
logClient
|
|
74863
75254
|
});
|
|
74864
75255
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
74865
75256
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
74866
|
-
file:
|
|
75257
|
+
file: import_node_path82.default.join(logDir, "screen-idle-probe.log"),
|
|
74867
75258
|
level: "debug"
|
|
74868
75259
|
});
|
|
74869
75260
|
logger.info("screen-idle probe logger enabled", {
|
|
74870
|
-
file:
|
|
75261
|
+
file: import_node_path82.default.join(logDir, "screen-idle-probe.log")
|
|
74871
75262
|
});
|
|
74872
75263
|
const CAP_TARGETS = [
|
|
74873
|
-
|
|
74874
|
-
|
|
75264
|
+
import_node_path82.default.join(logDir, "clawd.log"),
|
|
75265
|
+
import_node_path82.default.join(logDir, "screen-idle-probe.log")
|
|
74875
75266
|
];
|
|
74876
75267
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
74877
75268
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -74993,8 +75384,9 @@ async function startDaemon(config) {
|
|
|
74993
75384
|
const agents = new AgentsScanner();
|
|
74994
75385
|
const history = new ClaudeHistoryReader();
|
|
74995
75386
|
let transport = null;
|
|
74996
|
-
const personaStore = new PersonaStore(
|
|
74997
|
-
const
|
|
75387
|
+
const personaStore = new PersonaStore(import_node_path82.default.join(config.dataDir, "personas"));
|
|
75388
|
+
const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
|
|
75389
|
+
const usersRoot = import_node_path82.default.join(config.dataDir, "users");
|
|
74998
75390
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
74999
75391
|
if (defaultsRoot) {
|
|
75000
75392
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -75011,7 +75403,7 @@ async function startDaemon(config) {
|
|
|
75011
75403
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
75012
75404
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
75013
75405
|
const dispatchStore = createDispatchStore({
|
|
75014
|
-
filePath:
|
|
75406
|
+
filePath: import_node_path82.default.join(config.dataDir, "dispatch.json"),
|
|
75015
75407
|
now: () => Date.now(),
|
|
75016
75408
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
75017
75409
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -75020,7 +75412,7 @@ async function startDaemon(config) {
|
|
|
75020
75412
|
await dispatchStore.load();
|
|
75021
75413
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
75022
75414
|
const channelStore = createChannelStore({
|
|
75023
|
-
filePath:
|
|
75415
|
+
filePath: import_node_path82.default.join(config.dataDir, "channels.json"),
|
|
75024
75416
|
now: () => Date.now(),
|
|
75025
75417
|
genId: () => `ch-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75026
75418
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
@@ -75029,7 +75421,7 @@ async function startDaemon(config) {
|
|
|
75029
75421
|
});
|
|
75030
75422
|
await channelStore.load();
|
|
75031
75423
|
const topicStore = createTopicStore({
|
|
75032
|
-
filePath:
|
|
75424
|
+
filePath: import_node_path82.default.join(config.dataDir, "topics.json"),
|
|
75033
75425
|
now: () => Date.now(),
|
|
75034
75426
|
genId: () => `tp-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
|
|
75035
75427
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
@@ -75056,12 +75448,12 @@ async function startDaemon(config) {
|
|
|
75056
75448
|
});
|
|
75057
75449
|
}
|
|
75058
75450
|
});
|
|
75059
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
75451
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path82.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
|
|
75060
75452
|
const mcpConfigs = [];
|
|
75061
75453
|
const secretsBundleRoot = findSecretsBundleRoot(logger);
|
|
75062
|
-
const localSecretsDir =
|
|
75454
|
+
const localSecretsDir = import_node_path82.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
75063
75455
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
75064
|
-
const githubTokenFile =
|
|
75456
|
+
const githubTokenFile = import_node_path82.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
|
|
75065
75457
|
const githubIdentity = createGithubIdentity({
|
|
75066
75458
|
resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
|
|
75067
75459
|
store: (token) => storeGithubAuth({
|
|
@@ -75099,22 +75491,22 @@ async function startDaemon(config) {
|
|
|
75099
75491
|
void githubIdentity.refresh();
|
|
75100
75492
|
return renderPersonaMcpSecrets({
|
|
75101
75493
|
personaId: personaId2,
|
|
75102
|
-
personaDir:
|
|
75494
|
+
personaDir: import_node_path82.default.join(config.dataDir, "personas", personaId2),
|
|
75103
75495
|
secrets,
|
|
75104
|
-
outDir:
|
|
75496
|
+
outDir: import_node_path82.default.join(config.dataDir, "persona-mcp"),
|
|
75105
75497
|
logger
|
|
75106
75498
|
});
|
|
75107
75499
|
};
|
|
75108
75500
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
75109
75501
|
const dispatchServerCandidates = [
|
|
75110
|
-
|
|
75502
|
+
import_node_path82.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
75111
75503
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
75112
|
-
|
|
75504
|
+
import_node_path82.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
75113
75505
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
75114
75506
|
];
|
|
75115
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) =>
|
|
75507
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs64.default.existsSync(p3));
|
|
75116
75508
|
if (dispatchServerScriptPath) {
|
|
75117
|
-
const dispatchLogPath =
|
|
75509
|
+
const dispatchLogPath = import_node_path82.default.join(logDir, "dispatch-mcp-server.log");
|
|
75118
75510
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
75119
75511
|
dataDir: config.dataDir,
|
|
75120
75512
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -75134,12 +75526,12 @@ async function startDaemon(config) {
|
|
|
75134
75526
|
});
|
|
75135
75527
|
}
|
|
75136
75528
|
const ticketServerCandidates = [
|
|
75137
|
-
|
|
75138
|
-
|
|
75529
|
+
import_node_path82.default.join(here, "ticket", "mcp-server.cjs"),
|
|
75530
|
+
import_node_path82.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
75139
75531
|
];
|
|
75140
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p3) =>
|
|
75532
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs64.default.existsSync(p3));
|
|
75141
75533
|
if (ticketServerScriptPath) {
|
|
75142
|
-
const ticketLogPath =
|
|
75534
|
+
const ticketLogPath = import_node_path82.default.join(logDir, "ticket-mcp-server.log");
|
|
75143
75535
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
75144
75536
|
dataDir: config.dataDir,
|
|
75145
75537
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -75161,12 +75553,12 @@ async function startDaemon(config) {
|
|
|
75161
75553
|
});
|
|
75162
75554
|
}
|
|
75163
75555
|
const shiftServerCandidates = [
|
|
75164
|
-
|
|
75165
|
-
|
|
75556
|
+
import_node_path82.default.join(here, "shift", "mcp-server.cjs"),
|
|
75557
|
+
import_node_path82.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
75166
75558
|
];
|
|
75167
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p3) =>
|
|
75559
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs64.default.existsSync(p3));
|
|
75168
75560
|
if (shiftServerScriptPath) {
|
|
75169
|
-
const shiftLogPath =
|
|
75561
|
+
const shiftLogPath = import_node_path82.default.join(logDir, "shift-mcp-server.log");
|
|
75170
75562
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
75171
75563
|
dataDir: config.dataDir,
|
|
75172
75564
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -75187,12 +75579,12 @@ async function startDaemon(config) {
|
|
|
75187
75579
|
);
|
|
75188
75580
|
}
|
|
75189
75581
|
const inboxServerCandidates = [
|
|
75190
|
-
|
|
75191
|
-
|
|
75582
|
+
import_node_path82.default.join(here, "inbox", "mcp-server.cjs"),
|
|
75583
|
+
import_node_path82.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
75192
75584
|
];
|
|
75193
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p3) =>
|
|
75585
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs64.default.existsSync(p3));
|
|
75194
75586
|
if (inboxServerScriptPath) {
|
|
75195
|
-
const inboxLogPath =
|
|
75587
|
+
const inboxLogPath = import_node_path82.default.join(logDir, "inbox-mcp-server.log");
|
|
75196
75588
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
75197
75589
|
dataDir: config.dataDir,
|
|
75198
75590
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -75213,10 +75605,10 @@ async function startDaemon(config) {
|
|
|
75213
75605
|
);
|
|
75214
75606
|
}
|
|
75215
75607
|
const peerOpsServerCandidates = [
|
|
75216
|
-
|
|
75217
|
-
|
|
75608
|
+
import_node_path82.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
75609
|
+
import_node_path82.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
75218
75610
|
];
|
|
75219
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) =>
|
|
75611
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs64.default.existsSync(p3));
|
|
75220
75612
|
if (peerOpsServerScriptPath) {
|
|
75221
75613
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
75222
75614
|
dataDir: config.dataDir,
|
|
@@ -75236,12 +75628,12 @@ async function startDaemon(config) {
|
|
|
75236
75628
|
);
|
|
75237
75629
|
}
|
|
75238
75630
|
const rpcToolServerCandidates = [
|
|
75239
|
-
|
|
75240
|
-
|
|
75631
|
+
import_node_path82.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
75632
|
+
import_node_path82.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
75241
75633
|
];
|
|
75242
|
-
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) =>
|
|
75634
|
+
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs64.default.existsSync(p3));
|
|
75243
75635
|
if (rpcToolServerScriptPath) {
|
|
75244
|
-
const rpcToolLogPath =
|
|
75636
|
+
const rpcToolLogPath = import_node_path82.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
75245
75637
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
75246
75638
|
dataDir: config.dataDir,
|
|
75247
75639
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -75262,7 +75654,7 @@ async function startDaemon(config) {
|
|
|
75262
75654
|
);
|
|
75263
75655
|
}
|
|
75264
75656
|
const shiftStore = createShiftStore({
|
|
75265
|
-
filePath:
|
|
75657
|
+
filePath: import_node_path82.default.join(config.dataDir, "shift.json"),
|
|
75266
75658
|
ownerIdProvider: () => ownerPrincipalId,
|
|
75267
75659
|
now: () => Date.now()
|
|
75268
75660
|
});
|
|
@@ -75284,7 +75676,7 @@ async function startDaemon(config) {
|
|
|
75284
75676
|
getAdapter,
|
|
75285
75677
|
historyReader: history,
|
|
75286
75678
|
dataDir: config.dataDir,
|
|
75287
|
-
personaRoot:
|
|
75679
|
+
personaRoot: import_node_path82.default.join(config.dataDir, "personas"),
|
|
75288
75680
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
75289
75681
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
75290
75682
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
@@ -75341,10 +75733,10 @@ async function startDaemon(config) {
|
|
|
75341
75733
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
75342
75734
|
attachmentGroup: {
|
|
75343
75735
|
onFileEdit: (input) => {
|
|
75344
|
-
const absPath =
|
|
75736
|
+
const absPath = import_node_path82.default.isAbsolute(input.relPath) ? input.relPath : import_node_path82.default.join(input.cwd, input.relPath);
|
|
75345
75737
|
let size = 0;
|
|
75346
75738
|
try {
|
|
75347
|
-
size =
|
|
75739
|
+
size = import_node_fs64.default.statSync(absPath).size;
|
|
75348
75740
|
} catch (err) {
|
|
75349
75741
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
75350
75742
|
sessionId: input.sessionId,
|
|
@@ -75385,9 +75777,9 @@ async function startDaemon(config) {
|
|
|
75385
75777
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
75386
75778
|
}
|
|
75387
75779
|
const projectsStore = new ProjectsStore({
|
|
75388
|
-
file:
|
|
75780
|
+
file: import_node_path82.default.join(config.dataDir, "projects.json"),
|
|
75389
75781
|
clawdDir: config.dataDir,
|
|
75390
|
-
codexStateFile:
|
|
75782
|
+
codexStateFile: import_node_path82.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
75391
75783
|
logger
|
|
75392
75784
|
});
|
|
75393
75785
|
const observer = new SessionObserver({
|
|
@@ -75452,13 +75844,13 @@ async function startDaemon(config) {
|
|
|
75452
75844
|
logger
|
|
75453
75845
|
});
|
|
75454
75846
|
registerAdapter("claude", claudeAdapter);
|
|
75455
|
-
const codexIsolatedHome =
|
|
75847
|
+
const codexIsolatedHome = import_node_path82.default.join(config.dataDir, "codex-home");
|
|
75456
75848
|
try {
|
|
75457
|
-
|
|
75849
|
+
import_node_fs64.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
75458
75850
|
for (const f2 of ["auth.json", "config.toml"]) {
|
|
75459
|
-
const link =
|
|
75460
|
-
const target =
|
|
75461
|
-
if (!
|
|
75851
|
+
const link = import_node_path82.default.join(codexIsolatedHome, f2);
|
|
75852
|
+
const target = import_node_path82.default.join(import_node_os31.default.homedir(), ".codex", f2);
|
|
75853
|
+
if (!import_node_fs64.default.existsSync(link) && import_node_fs64.default.existsSync(target)) import_node_fs64.default.symlinkSync(target, link);
|
|
75462
75854
|
}
|
|
75463
75855
|
} catch (err) {
|
|
75464
75856
|
logger.warn("codex isolated home setup failed", { err: String(err) });
|
|
@@ -75469,17 +75861,17 @@ async function startDaemon(config) {
|
|
|
75469
75861
|
logger,
|
|
75470
75862
|
historyReader: new CodexHistoryReader({
|
|
75471
75863
|
roots: codexRolloutRoots(config.dataDir),
|
|
75472
|
-
sharedHome:
|
|
75864
|
+
sharedHome: import_node_path82.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
75473
75865
|
logger
|
|
75474
75866
|
}),
|
|
75475
75867
|
// projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
|
|
75476
75868
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
75477
75869
|
cwd,
|
|
75478
|
-
personaRoot:
|
|
75870
|
+
personaRoot: import_node_path82.default.join(config.dataDir, "personas"),
|
|
75479
75871
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
75480
75872
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
75481
75873
|
projectPaths: projectsStore.listMerged().map((x2) => x2.path),
|
|
75482
|
-
sharedHome:
|
|
75874
|
+
sharedHome: import_node_path82.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
75483
75875
|
isolatedHome: codexIsolatedHome
|
|
75484
75876
|
}),
|
|
75485
75877
|
// 附件图片验签:与 http-router /files 路由同一把 secret
|
|
@@ -75504,10 +75896,10 @@ async function startDaemon(config) {
|
|
|
75504
75896
|
);
|
|
75505
75897
|
registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
|
|
75506
75898
|
const piMcpBridgeCandidates = [
|
|
75507
|
-
|
|
75508
|
-
|
|
75899
|
+
import_node_path82.default.join(here, "pi-mcp-bridge", "extension.cjs"),
|
|
75900
|
+
import_node_path82.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
|
|
75509
75901
|
];
|
|
75510
|
-
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) =>
|
|
75902
|
+
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs64.default.existsSync(p3));
|
|
75511
75903
|
if (piMcpBridgePath) {
|
|
75512
75904
|
logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
|
|
75513
75905
|
} else {
|
|
@@ -75724,6 +76116,7 @@ async function startDaemon(config) {
|
|
|
75724
76116
|
topicStore,
|
|
75725
76117
|
dispatchStore,
|
|
75726
76118
|
masterDataDir: config.dataDir,
|
|
76119
|
+
subscriptionChannelStore,
|
|
75727
76120
|
// 建话题即起该话题的 Master session(1:1)。走与 session:create 同一条 manager.create
|
|
75728
76121
|
// 链路,不复制会话创建逻辑;creatorPrincipalId 用本机 deviceId(owner ctx 的 principal.id)。
|
|
75729
76122
|
createMasterSession: ({ label }) => {
|
|
@@ -75802,11 +76195,11 @@ async function startDaemon(config) {
|
|
|
75802
76195
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
75803
76196
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
75804
76197
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
75805
|
-
personaRoot:
|
|
76198
|
+
personaRoot: import_node_path82.default.join(config.dataDir, "personas"),
|
|
75806
76199
|
usersRoot
|
|
75807
76200
|
},
|
|
75808
76201
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
75809
|
-
personaRoot:
|
|
76202
|
+
personaRoot: import_node_path82.default.join(config.dataDir, "personas"),
|
|
75810
76203
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
75811
76204
|
usersRoot,
|
|
75812
76205
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -75952,7 +76345,7 @@ async function startDaemon(config) {
|
|
|
75952
76345
|
sourceSessionId: args.sourceSessionId
|
|
75953
76346
|
});
|
|
75954
76347
|
const sourceFile = manager.findOwnedSession(args.sourceSessionId);
|
|
75955
|
-
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile,
|
|
76348
|
+
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os31.default.homedir());
|
|
75956
76349
|
logger.info("dispatch.spawnB.source-resolved", {
|
|
75957
76350
|
dispatchId: args.dispatchId,
|
|
75958
76351
|
sourceJsonlPath,
|
|
@@ -76027,6 +76420,7 @@ async function startDaemon(config) {
|
|
|
76027
76420
|
}
|
|
76028
76421
|
let lastPathRefresh = 0;
|
|
76029
76422
|
const deployHandlers = buildDeployHandlers({
|
|
76423
|
+
channelStore: subscriptionChannelStore,
|
|
76030
76424
|
hasPersona: (personaId2) => personaStore.has(personaId2),
|
|
76031
76425
|
personaDir: (personaId2) => personaStore.personaDirPath(personaId2),
|
|
76032
76426
|
// 发布前落闸要看它现在配的引擎和模型(云上只跑 codex / pi,且模型跟着这次发布走)
|
|
@@ -76111,7 +76505,7 @@ async function startDaemon(config) {
|
|
|
76111
76505
|
});
|
|
76112
76506
|
shiftScheduler.start();
|
|
76113
76507
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
76114
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
76508
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path82.default.join(config.dataDir, "personas"));
|
|
76115
76509
|
const larkBotCloud = createLarkBotCloudClient({
|
|
76116
76510
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
76117
76511
|
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
|
|
@@ -76123,7 +76517,7 @@ async function startDaemon(config) {
|
|
|
76123
76517
|
store: larkBotStore,
|
|
76124
76518
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
76125
76519
|
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
76126
|
-
mediaRootFor: (chatId) =>
|
|
76520
|
+
mediaRootFor: (chatId) => import_node_path82.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
76127
76521
|
isShuttingDown: () => larkDraining,
|
|
76128
76522
|
logger: {
|
|
76129
76523
|
warn: (msg) => logger.warn(msg),
|
|
@@ -76423,8 +76817,8 @@ async function startDaemon(config) {
|
|
|
76423
76817
|
const lines = [
|
|
76424
76818
|
`Tunnel: ${r2.url}`,
|
|
76425
76819
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
76426
|
-
`Frpc config: ${
|
|
76427
|
-
`Frpc log: ${
|
|
76820
|
+
`Frpc config: ${import_node_path82.default.join(config.dataDir, "frpc.toml")}`,
|
|
76821
|
+
`Frpc log: ${import_node_path82.default.join(logDir, "frpc.log")}`
|
|
76428
76822
|
];
|
|
76429
76823
|
const width2 = Math.max(...lines.map((l2) => l2.length));
|
|
76430
76824
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -76437,8 +76831,8 @@ ${bar}
|
|
|
76437
76831
|
|
|
76438
76832
|
`);
|
|
76439
76833
|
try {
|
|
76440
|
-
const connectPath =
|
|
76441
|
-
|
|
76834
|
+
const connectPath = import_node_path82.default.join(config.dataDir, "connect.txt");
|
|
76835
|
+
import_node_fs64.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
76442
76836
|
} catch {
|
|
76443
76837
|
}
|
|
76444
76838
|
} catch (err) {
|
|
@@ -76536,9 +76930,9 @@ ${bar}
|
|
|
76536
76930
|
};
|
|
76537
76931
|
}
|
|
76538
76932
|
function migrateDropPersonsDir(dataDir) {
|
|
76539
|
-
const dir =
|
|
76933
|
+
const dir = import_node_path82.default.join(dataDir, "persons");
|
|
76540
76934
|
try {
|
|
76541
|
-
|
|
76935
|
+
import_node_fs64.default.rmSync(dir, { recursive: true, force: true });
|
|
76542
76936
|
} catch {
|
|
76543
76937
|
}
|
|
76544
76938
|
}
|