@clawos-dev/clawd 0.2.644 → 0.2.646
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 +34 -4
- package/dist/cli.cjs +792 -698
- package/dist/cloud-persona-conversations.html +71 -71
- package/dist/cloud-persona-metrics.html +1 -1
- package/dist/dispatch/mcp-server.cjs +28 -3
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +34 -4
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +34 -4
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-NDGUa37l.js → guest-D04-QGMT.js} +135 -135
- package/dist/share-ui/assets/{guest-DQN6sKDT.css → guest-D2iDPo9c.css} +1 -1
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
|
|
|
450
450
|
init_errors();
|
|
451
451
|
init_en();
|
|
452
452
|
makeIssue = (params) => {
|
|
453
|
-
const { data, path:
|
|
454
|
-
const fullPath = [...
|
|
453
|
+
const { data, path: path108, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path108, ...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, path108, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path108;
|
|
770
770
|
this._key = key;
|
|
771
771
|
}
|
|
772
772
|
get path() {
|
|
@@ -6013,9 +6013,15 @@ var init_github_auth_schemas = __esm({
|
|
|
6013
6013
|
});
|
|
6014
6014
|
|
|
6015
6015
|
// ../protocol/src/environment-schemas.ts
|
|
6016
|
+
function isFeishuBotConnector(c2) {
|
|
6017
|
+
return c2.name === "feishu" && c2.runner === "cli" && c2.kind === "env" && c2.credentialSource === "shared";
|
|
6018
|
+
}
|
|
6016
6019
|
function connectorBlockers(c2) {
|
|
6017
6020
|
if (!c2.credentialSource) return [`\u8FDE\u63A5\u5668 ${c2.name} \u8FD8\u6CA1\u9009\u7528\u8C01\u7684\u8D26\u53F7`];
|
|
6018
6021
|
const out = [];
|
|
6022
|
+
if (isFeishuBotConnector(c2)) {
|
|
6023
|
+
return FEISHU_BOT_FIELDS.filter((f2) => !c2.fields.includes(f2)).map((f2) => `\u8FDE\u63A5\u5668 feishu \u7684 Lark App Bot \u7F3A\u5C11 ${f2 === "LARKSUITE_CLI_APP_ID" ? "App ID" : "App Secret"}`);
|
|
6024
|
+
}
|
|
6019
6025
|
if (c2.credentialSource === "personal") {
|
|
6020
6026
|
if (!c2.auth) out.push(`\u8FDE\u63A5\u5668 ${c2.name} \u8FD8\u6CA1\u9009\u7528\u6237\u600E\u4E48\u5173\u8054\u8D26\u53F7`);
|
|
6021
6027
|
else if (c2.auth === "oauth" && c2.kind === "env") out.push(`\u8FDE\u63A5\u5668 ${c2.name} \u662F\u8FDB\u7A0B\u578B\uFF08stdio MCP / CLI\uFF09\uFF0C\u53EA\u80FD\u7C98\u8D34 API key\uFF0C\u8D70\u4E0D\u4E86 OAuth`);
|
|
@@ -6037,7 +6043,7 @@ function sharedConnectorSecrets(m3) {
|
|
|
6037
6043
|
function requiredSecretEnvNames(m3) {
|
|
6038
6044
|
return [.../* @__PURE__ */ new Set([...m3.secrets.flatMap((s2) => s2.env), ...sharedConnectorSecrets(m3).flatMap((s2) => s2.env)])];
|
|
6039
6045
|
}
|
|
6040
|
-
var EnvArtifactSchema, CLOUD_DEBIAN, CLOUD_ROOT_PROVIDES, CLOUD_BASE_PROVIDES, EnvPackageSchema, EnvSecretSchema, ConnectorNameSchema, CONNECTOR_KINDS, CONNECTOR_RUNNERS, CONNECTOR_PROTOCOLS, CREDENTIAL_SOURCES, CONNECTOR_AUTHS, ConnectorFieldSchema, EnvConnectorSchema, normalizeLegacyManifest, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
|
|
6046
|
+
var EnvArtifactSchema, CLOUD_DEBIAN, CLOUD_ROOT_PROVIDES, CLOUD_BASE_PROVIDES, EnvPackageSchema, EnvSecretSchema, ConnectorNameSchema, CONNECTOR_KINDS, CONNECTOR_RUNNERS, CONNECTOR_PROTOCOLS, CREDENTIAL_SOURCES, CONNECTOR_AUTHS, ConnectorFieldSchema, EnvConnectorSchema, FEISHU_BOT_FIELDS, normalizeLegacyManifest, PUBLISHER_TEST_NOTE_PREFIX, PublisherTestSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
|
|
6041
6047
|
var init_environment_schemas = __esm({
|
|
6042
6048
|
"../protocol/src/environment-schemas.ts"() {
|
|
6043
6049
|
"use strict";
|
|
@@ -6128,6 +6134,7 @@ var init_environment_schemas = __esm({
|
|
|
6128
6134
|
fields: external_exports.array(ConnectorFieldSchema).default([]),
|
|
6129
6135
|
http: external_exports.object({ url: external_exports.string().min(1), headers: external_exports.record(external_exports.string(), external_exports.string()) }).optional()
|
|
6130
6136
|
});
|
|
6137
|
+
FEISHU_BOT_FIELDS = ["LARKSUITE_CLI_APP_ID", "LARKSUITE_CLI_APP_SECRET"];
|
|
6131
6138
|
normalizeLegacyManifest = (v3) => {
|
|
6132
6139
|
if (!v3 || typeof v3 !== "object") return v3;
|
|
6133
6140
|
let o2 = v3;
|
|
@@ -6141,7 +6148,15 @@ var init_environment_schemas = __esm({
|
|
|
6141
6148
|
}
|
|
6142
6149
|
return o2;
|
|
6143
6150
|
};
|
|
6151
|
+
PUBLISHER_TEST_NOTE_PREFIX = "Publisher test: ";
|
|
6152
|
+
PublisherTestSchema = external_exports.object({
|
|
6153
|
+
version: external_exports.literal(1),
|
|
6154
|
+
entry: external_exports.string().max(240).regex(/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*\.mjs$/).refine((value) => !value.split("/").some((segment) => [".", ".."].includes(segment))),
|
|
6155
|
+
timeoutSeconds: external_exports.number().int().min(1).max(600),
|
|
6156
|
+
checks: external_exports.array(external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/)).min(1).max(64).refine((checks) => new Set(checks).size === checks.length)
|
|
6157
|
+
}).strict();
|
|
6144
6158
|
MANIFEST_BODY = {
|
|
6159
|
+
test: PublisherTestSchema.optional(),
|
|
6145
6160
|
packages: external_exports.array(EnvPackageSchema),
|
|
6146
6161
|
secrets: external_exports.array(EnvSecretSchema),
|
|
6147
6162
|
/**
|
|
@@ -6176,11 +6191,12 @@ var init_environment_schemas = __esm({
|
|
|
6176
6191
|
});
|
|
6177
6192
|
|
|
6178
6193
|
// ../protocol/src/release-schemas.ts
|
|
6179
|
-
var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, VerificationSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
|
|
6194
|
+
var DEPLOY_ENVIRONMENTS, DeployEnvironmentSchema, ImageDigestSchema, SourceCommitSchema, IntegrationEndpointSchema, PublisherTestReceiptSchema, VerificationSchema, VerifiedPersonaReleaseSchema, VerifiedBaseReleaseSchema;
|
|
6180
6195
|
var init_release_schemas = __esm({
|
|
6181
6196
|
"../protocol/src/release-schemas.ts"() {
|
|
6182
6197
|
"use strict";
|
|
6183
6198
|
init_zod();
|
|
6199
|
+
init_environment_schemas();
|
|
6184
6200
|
DEPLOY_ENVIRONMENTS = ["integration", "production"];
|
|
6185
6201
|
DeployEnvironmentSchema = external_exports.enum(DEPLOY_ENVIRONMENTS);
|
|
6186
6202
|
ImageDigestSchema = external_exports.string().regex(/^[a-z0-9.-]+(?::[0-9]+)?\/[a-z0-9._/-]+@sha256:[a-f0-9]{64}$/);
|
|
@@ -6193,12 +6209,25 @@ var init_release_schemas = __esm({
|
|
|
6193
6209
|
return false;
|
|
6194
6210
|
}
|
|
6195
6211
|
}, "\u6D4B\u8BD5\u9A8C\u8BC1\u5730\u5740\u5FC5\u987B\u660E\u786E\u6307\u5411 int HTTPS \u73AF\u5883");
|
|
6212
|
+
PublisherTestReceiptSchema = external_exports.object({
|
|
6213
|
+
version: external_exports.literal(1),
|
|
6214
|
+
runId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
|
|
6215
|
+
status: external_exports.literal("passed"),
|
|
6216
|
+
exitCode: external_exports.literal(0),
|
|
6217
|
+
result: external_exports.object({
|
|
6218
|
+
version: external_exports.literal(1),
|
|
6219
|
+
runId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
|
|
6220
|
+
checks: external_exports.array(external_exports.object({ name: external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/), status: external_exports.literal("passed"), reason: external_exports.string().max(1024).optional() }).strict()).min(1).max(64)
|
|
6221
|
+
}).strict(),
|
|
6222
|
+
execution: external_exports.object({ image: ImageDigestSchema, imageID: external_exports.string().min(1).max(512), engine: external_exports.enum(["codex", "pi"]), podUid: external_exports.string().min(1).max(512), jobUid: external_exports.string().min(1).max(512) }).strict()
|
|
6223
|
+
}).strict();
|
|
6196
6224
|
VerificationSchema = external_exports.object({
|
|
6197
6225
|
status: external_exports.literal("passed"),
|
|
6198
6226
|
fingerprint: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
6199
6227
|
checks: external_exports.array(external_exports.string().regex(/^[a-z0-9-]+$/)),
|
|
6200
6228
|
endpoint: IntegrationEndpointSchema,
|
|
6201
|
-
verifiedAt: external_exports.string().refine((s2) => Number.isFinite(Date.parse(s2)))
|
|
6229
|
+
verifiedAt: external_exports.string().refine((s2) => Number.isFinite(Date.parse(s2))),
|
|
6230
|
+
test: PublisherTestReceiptSchema.optional()
|
|
6202
6231
|
}).strict();
|
|
6203
6232
|
VerifiedPersonaReleaseSchema = external_exports.object({
|
|
6204
6233
|
version: external_exports.literal(1),
|
|
@@ -6209,8 +6238,13 @@ var init_release_schemas = __esm({
|
|
|
6209
6238
|
baseImage: ImageDigestSchema,
|
|
6210
6239
|
pipelineCommit: SourceCommitSchema,
|
|
6211
6240
|
repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/),
|
|
6212
|
-
verification: VerificationSchema.refine((v3) => v3.checks.includes("persona-smoke"))
|
|
6213
|
-
|
|
6241
|
+
verification: VerificationSchema.refine((v3) => v3.checks.includes("persona-smoke")),
|
|
6242
|
+
test: PublisherTestSchema.optional()
|
|
6243
|
+
}).strict().refine((record4) => {
|
|
6244
|
+
if (!record4.test) return record4.verification.test === void 0;
|
|
6245
|
+
const receipt = record4.verification.test;
|
|
6246
|
+
return ["persona-dialogue", "persona-task", "persona-custom-test"].every((check) => record4.verification.checks.includes(check)) && receipt !== void 0 && receipt.execution.image === record4.image && receipt.runId === receipt.result.runId && receipt.result.checks.length === record4.test.checks.length && new Set(receipt.result.checks.map((check) => check.name)).size === record4.test.checks.length && receipt.result.checks.every((check) => record4.test.checks.includes(check.name));
|
|
6247
|
+
}, "Declared publisher acceptance requires complete candidate runtime evidence");
|
|
6214
6248
|
VerifiedBaseReleaseSchema = external_exports.object({
|
|
6215
6249
|
version: external_exports.literal(1),
|
|
6216
6250
|
environment: external_exports.literal("integration"),
|
|
@@ -10053,8 +10087,8 @@ var require_req = __commonJS({
|
|
|
10053
10087
|
if (req.originalUrl) {
|
|
10054
10088
|
_req.url = req.originalUrl;
|
|
10055
10089
|
} else {
|
|
10056
|
-
const
|
|
10057
|
-
_req.url = typeof
|
|
10090
|
+
const path108 = req.path;
|
|
10091
|
+
_req.url = typeof path108 === "string" ? path108 : req.url ? req.url.path || req.url : void 0;
|
|
10058
10092
|
}
|
|
10059
10093
|
if (req.query) {
|
|
10060
10094
|
_req.query = req.query;
|
|
@@ -10219,14 +10253,14 @@ var require_redact = __commonJS({
|
|
|
10219
10253
|
}
|
|
10220
10254
|
return obj;
|
|
10221
10255
|
}
|
|
10222
|
-
function parsePath(
|
|
10256
|
+
function parsePath(path108) {
|
|
10223
10257
|
const parts = [];
|
|
10224
10258
|
let current = "";
|
|
10225
10259
|
let inBrackets = false;
|
|
10226
10260
|
let inQuotes = false;
|
|
10227
10261
|
let quoteChar = "";
|
|
10228
|
-
for (let i2 = 0; i2 <
|
|
10229
|
-
const char =
|
|
10262
|
+
for (let i2 = 0; i2 < path108.length; i2++) {
|
|
10263
|
+
const char = path108[i2];
|
|
10230
10264
|
if (!inBrackets && char === ".") {
|
|
10231
10265
|
if (current) {
|
|
10232
10266
|
parts.push(current);
|
|
@@ -10357,10 +10391,10 @@ var require_redact = __commonJS({
|
|
|
10357
10391
|
return current;
|
|
10358
10392
|
}
|
|
10359
10393
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
10360
|
-
for (const
|
|
10361
|
-
const parts = parsePath(
|
|
10394
|
+
for (const path108 of paths) {
|
|
10395
|
+
const parts = parsePath(path108);
|
|
10362
10396
|
if (parts.includes("*")) {
|
|
10363
|
-
redactWildcardPath(obj, parts, censor,
|
|
10397
|
+
redactWildcardPath(obj, parts, censor, path108, remove);
|
|
10364
10398
|
} else {
|
|
10365
10399
|
if (remove) {
|
|
10366
10400
|
removeKey(obj, parts);
|
|
@@ -10445,8 +10479,8 @@ var require_redact = __commonJS({
|
|
|
10445
10479
|
}
|
|
10446
10480
|
} else {
|
|
10447
10481
|
if (afterWildcard.includes("*")) {
|
|
10448
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10449
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
10482
|
+
const wrappedCensor = typeof censor === "function" ? (value, path108) => {
|
|
10483
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path108];
|
|
10450
10484
|
return censor(value, fullPath);
|
|
10451
10485
|
} : censor;
|
|
10452
10486
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -10481,8 +10515,8 @@ var require_redact = __commonJS({
|
|
|
10481
10515
|
return null;
|
|
10482
10516
|
}
|
|
10483
10517
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
10484
|
-
for (const
|
|
10485
|
-
const parts = parsePath(
|
|
10518
|
+
for (const path108 of pathsToClone) {
|
|
10519
|
+
const parts = parsePath(path108);
|
|
10486
10520
|
let current = pathStructure;
|
|
10487
10521
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
10488
10522
|
const part = parts[i2];
|
|
@@ -10534,24 +10568,24 @@ var require_redact = __commonJS({
|
|
|
10534
10568
|
}
|
|
10535
10569
|
return cloneSelectively(obj, pathStructure);
|
|
10536
10570
|
}
|
|
10537
|
-
function validatePath(
|
|
10538
|
-
if (typeof
|
|
10571
|
+
function validatePath(path108) {
|
|
10572
|
+
if (typeof path108 !== "string") {
|
|
10539
10573
|
throw new Error("Paths must be (non-empty) strings");
|
|
10540
10574
|
}
|
|
10541
|
-
if (
|
|
10575
|
+
if (path108 === "") {
|
|
10542
10576
|
throw new Error("Invalid redaction path ()");
|
|
10543
10577
|
}
|
|
10544
|
-
if (
|
|
10545
|
-
throw new Error(`Invalid redaction path (${
|
|
10578
|
+
if (path108.includes("..")) {
|
|
10579
|
+
throw new Error(`Invalid redaction path (${path108})`);
|
|
10546
10580
|
}
|
|
10547
|
-
if (
|
|
10548
|
-
throw new Error(`Invalid redaction path (${
|
|
10581
|
+
if (path108.includes(",")) {
|
|
10582
|
+
throw new Error(`Invalid redaction path (${path108})`);
|
|
10549
10583
|
}
|
|
10550
10584
|
let bracketCount = 0;
|
|
10551
10585
|
let inQuotes = false;
|
|
10552
10586
|
let quoteChar = "";
|
|
10553
|
-
for (let i2 = 0; i2 <
|
|
10554
|
-
const char =
|
|
10587
|
+
for (let i2 = 0; i2 < path108.length; i2++) {
|
|
10588
|
+
const char = path108[i2];
|
|
10555
10589
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
10556
10590
|
if (!inQuotes) {
|
|
10557
10591
|
inQuotes = true;
|
|
@@ -10565,20 +10599,20 @@ var require_redact = __commonJS({
|
|
|
10565
10599
|
} else if (char === "]" && !inQuotes) {
|
|
10566
10600
|
bracketCount--;
|
|
10567
10601
|
if (bracketCount < 0) {
|
|
10568
|
-
throw new Error(`Invalid redaction path (${
|
|
10602
|
+
throw new Error(`Invalid redaction path (${path108})`);
|
|
10569
10603
|
}
|
|
10570
10604
|
}
|
|
10571
10605
|
}
|
|
10572
10606
|
if (bracketCount !== 0) {
|
|
10573
|
-
throw new Error(`Invalid redaction path (${
|
|
10607
|
+
throw new Error(`Invalid redaction path (${path108})`);
|
|
10574
10608
|
}
|
|
10575
10609
|
}
|
|
10576
10610
|
function validatePaths(paths) {
|
|
10577
10611
|
if (!Array.isArray(paths)) {
|
|
10578
10612
|
throw new TypeError("paths must be an array");
|
|
10579
10613
|
}
|
|
10580
|
-
for (const
|
|
10581
|
-
validatePath(
|
|
10614
|
+
for (const path108 of paths) {
|
|
10615
|
+
validatePath(path108);
|
|
10582
10616
|
}
|
|
10583
10617
|
}
|
|
10584
10618
|
function slowRedact(options = {}) {
|
|
@@ -10746,8 +10780,8 @@ var require_redaction = __commonJS({
|
|
|
10746
10780
|
if (shape[k3] === null) {
|
|
10747
10781
|
o2[k3] = (value) => topCensor(value, [k3]);
|
|
10748
10782
|
} else {
|
|
10749
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10750
|
-
return censor(value, [k3, ...
|
|
10783
|
+
const wrappedCensor = typeof censor === "function" ? (value, path108) => {
|
|
10784
|
+
return censor(value, [k3, ...path108]);
|
|
10751
10785
|
} : censor;
|
|
10752
10786
|
o2[k3] = Redact({
|
|
10753
10787
|
paths: shape[k3],
|
|
@@ -10965,10 +10999,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
10965
10999
|
var require_sonic_boom = __commonJS({
|
|
10966
11000
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
10967
11001
|
"use strict";
|
|
10968
|
-
var
|
|
11002
|
+
var fs97 = require("fs");
|
|
10969
11003
|
var EventEmitter2 = require("events");
|
|
10970
11004
|
var inherits = require("util").inherits;
|
|
10971
|
-
var
|
|
11005
|
+
var path108 = require("path");
|
|
10972
11006
|
var sleep2 = require_atomic_sleep();
|
|
10973
11007
|
var assert = require("assert");
|
|
10974
11008
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -11022,20 +11056,20 @@ var require_sonic_boom = __commonJS({
|
|
|
11022
11056
|
const mode = sonic.mode;
|
|
11023
11057
|
if (sonic.sync) {
|
|
11024
11058
|
try {
|
|
11025
|
-
if (sonic.mkdir)
|
|
11026
|
-
const fd =
|
|
11059
|
+
if (sonic.mkdir) fs97.mkdirSync(path108.dirname(file), { recursive: true });
|
|
11060
|
+
const fd = fs97.openSync(file, flags, mode);
|
|
11027
11061
|
fileOpened(null, fd);
|
|
11028
11062
|
} catch (err) {
|
|
11029
11063
|
fileOpened(err);
|
|
11030
11064
|
throw err;
|
|
11031
11065
|
}
|
|
11032
11066
|
} else if (sonic.mkdir) {
|
|
11033
|
-
|
|
11067
|
+
fs97.mkdir(path108.dirname(file), { recursive: true }, (err) => {
|
|
11034
11068
|
if (err) return fileOpened(err);
|
|
11035
|
-
|
|
11069
|
+
fs97.open(file, flags, mode, fileOpened);
|
|
11036
11070
|
});
|
|
11037
11071
|
} else {
|
|
11038
|
-
|
|
11072
|
+
fs97.open(file, flags, mode, fileOpened);
|
|
11039
11073
|
}
|
|
11040
11074
|
}
|
|
11041
11075
|
function SonicBoom(opts) {
|
|
@@ -11076,8 +11110,8 @@ var require_sonic_boom = __commonJS({
|
|
|
11076
11110
|
this.flush = flushBuffer;
|
|
11077
11111
|
this.flushSync = flushBufferSync;
|
|
11078
11112
|
this._actualWrite = actualWriteBuffer;
|
|
11079
|
-
fsWriteSync = () =>
|
|
11080
|
-
fsWrite = () =>
|
|
11113
|
+
fsWriteSync = () => fs97.writeSync(this.fd, this._writingBuf);
|
|
11114
|
+
fsWrite = () => fs97.write(this.fd, this._writingBuf, this.release);
|
|
11081
11115
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
11082
11116
|
this._writingBuf = "";
|
|
11083
11117
|
this.write = write;
|
|
@@ -11086,15 +11120,15 @@ var require_sonic_boom = __commonJS({
|
|
|
11086
11120
|
this._actualWrite = actualWrite;
|
|
11087
11121
|
fsWriteSync = () => {
|
|
11088
11122
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11089
|
-
return
|
|
11123
|
+
return fs97.writeSync(this.fd, this._writingBuf);
|
|
11090
11124
|
}
|
|
11091
|
-
return
|
|
11125
|
+
return fs97.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11092
11126
|
};
|
|
11093
11127
|
fsWrite = () => {
|
|
11094
11128
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11095
|
-
return
|
|
11129
|
+
return fs97.write(this.fd, this._writingBuf, this.release);
|
|
11096
11130
|
}
|
|
11097
|
-
return
|
|
11131
|
+
return fs97.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
11098
11132
|
};
|
|
11099
11133
|
} else {
|
|
11100
11134
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -11151,7 +11185,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11151
11185
|
}
|
|
11152
11186
|
}
|
|
11153
11187
|
if (this._fsync) {
|
|
11154
|
-
|
|
11188
|
+
fs97.fsyncSync(this.fd);
|
|
11155
11189
|
}
|
|
11156
11190
|
const len = this._len;
|
|
11157
11191
|
if (this._reopening) {
|
|
@@ -11265,7 +11299,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11265
11299
|
const onDrain = () => {
|
|
11266
11300
|
if (!this._fsync) {
|
|
11267
11301
|
try {
|
|
11268
|
-
|
|
11302
|
+
fs97.fsync(this.fd, (err) => {
|
|
11269
11303
|
this._flushPending = false;
|
|
11270
11304
|
cb(err);
|
|
11271
11305
|
});
|
|
@@ -11367,7 +11401,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11367
11401
|
const fd = this.fd;
|
|
11368
11402
|
this.once("ready", () => {
|
|
11369
11403
|
if (fd !== this.fd) {
|
|
11370
|
-
|
|
11404
|
+
fs97.close(fd, (err) => {
|
|
11371
11405
|
if (err) {
|
|
11372
11406
|
return this.emit("error", err);
|
|
11373
11407
|
}
|
|
@@ -11416,7 +11450,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11416
11450
|
buf = this._bufs[0];
|
|
11417
11451
|
}
|
|
11418
11452
|
try {
|
|
11419
|
-
const n2 = Buffer.isBuffer(buf) ?
|
|
11453
|
+
const n2 = Buffer.isBuffer(buf) ? fs97.writeSync(this.fd, buf) : fs97.writeSync(this.fd, buf, "utf8");
|
|
11420
11454
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
|
|
11421
11455
|
buf = releasedBufObj.writingBuf;
|
|
11422
11456
|
this._len = releasedBufObj.len;
|
|
@@ -11432,7 +11466,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11432
11466
|
}
|
|
11433
11467
|
}
|
|
11434
11468
|
try {
|
|
11435
|
-
|
|
11469
|
+
fs97.fsyncSync(this.fd);
|
|
11436
11470
|
} catch {
|
|
11437
11471
|
}
|
|
11438
11472
|
}
|
|
@@ -11453,7 +11487,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11453
11487
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
11454
11488
|
}
|
|
11455
11489
|
try {
|
|
11456
|
-
const n2 =
|
|
11490
|
+
const n2 = fs97.writeSync(this.fd, buf);
|
|
11457
11491
|
buf = buf.subarray(n2);
|
|
11458
11492
|
this._len = Math.max(this._len - n2, 0);
|
|
11459
11493
|
if (buf.length <= 0) {
|
|
@@ -11481,13 +11515,13 @@ var require_sonic_boom = __commonJS({
|
|
|
11481
11515
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
11482
11516
|
if (this.sync) {
|
|
11483
11517
|
try {
|
|
11484
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
11518
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs97.writeSync(this.fd, this._writingBuf) : fs97.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11485
11519
|
release2(null, written);
|
|
11486
11520
|
} catch (err) {
|
|
11487
11521
|
release2(err);
|
|
11488
11522
|
}
|
|
11489
11523
|
} else {
|
|
11490
|
-
|
|
11524
|
+
fs97.write(this.fd, this._writingBuf, release2);
|
|
11491
11525
|
}
|
|
11492
11526
|
}
|
|
11493
11527
|
function actualWriteBuffer() {
|
|
@@ -11496,7 +11530,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11496
11530
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
11497
11531
|
if (this.sync) {
|
|
11498
11532
|
try {
|
|
11499
|
-
const written =
|
|
11533
|
+
const written = fs97.writeSync(this.fd, this._writingBuf);
|
|
11500
11534
|
release2(null, written);
|
|
11501
11535
|
} catch (err) {
|
|
11502
11536
|
release2(err);
|
|
@@ -11505,7 +11539,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11505
11539
|
if (kCopyBuffer) {
|
|
11506
11540
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
11507
11541
|
}
|
|
11508
|
-
|
|
11542
|
+
fs97.write(this.fd, this._writingBuf, release2);
|
|
11509
11543
|
}
|
|
11510
11544
|
}
|
|
11511
11545
|
function actualClose(sonic) {
|
|
@@ -11521,12 +11555,12 @@ var require_sonic_boom = __commonJS({
|
|
|
11521
11555
|
sonic._lens = [];
|
|
11522
11556
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
11523
11557
|
try {
|
|
11524
|
-
|
|
11558
|
+
fs97.fsync(sonic.fd, closeWrapped);
|
|
11525
11559
|
} catch {
|
|
11526
11560
|
}
|
|
11527
11561
|
function closeWrapped() {
|
|
11528
11562
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
11529
|
-
|
|
11563
|
+
fs97.close(sonic.fd, done);
|
|
11530
11564
|
} else {
|
|
11531
11565
|
done();
|
|
11532
11566
|
}
|
|
@@ -14661,11 +14695,11 @@ var init_lib = __esm({
|
|
|
14661
14695
|
}
|
|
14662
14696
|
}
|
|
14663
14697
|
},
|
|
14664
|
-
addToPath: function addToPath(
|
|
14665
|
-
var last =
|
|
14698
|
+
addToPath: function addToPath(path108, added, removed, oldPosInc, options) {
|
|
14699
|
+
var last = path108.lastComponent;
|
|
14666
14700
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14667
14701
|
return {
|
|
14668
|
-
oldPos:
|
|
14702
|
+
oldPos: path108.oldPos + oldPosInc,
|
|
14669
14703
|
lastComponent: {
|
|
14670
14704
|
count: last.count + 1,
|
|
14671
14705
|
added,
|
|
@@ -14675,7 +14709,7 @@ var init_lib = __esm({
|
|
|
14675
14709
|
};
|
|
14676
14710
|
} else {
|
|
14677
14711
|
return {
|
|
14678
|
-
oldPos:
|
|
14712
|
+
oldPos: path108.oldPos + oldPosInc,
|
|
14679
14713
|
lastComponent: {
|
|
14680
14714
|
count: 1,
|
|
14681
14715
|
added,
|
|
@@ -15257,10 +15291,10 @@ function attachmentToHistoryMessage(o2, ts) {
|
|
|
15257
15291
|
const memories = raw.map((m3) => {
|
|
15258
15292
|
if (!m3 || typeof m3 !== "object") return null;
|
|
15259
15293
|
const rec6 = m3;
|
|
15260
|
-
const
|
|
15294
|
+
const path108 = typeof rec6.path === "string" ? rec6.path : null;
|
|
15261
15295
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
15262
|
-
if (!
|
|
15263
|
-
const entry = { path:
|
|
15296
|
+
if (!path108 || content == null) return null;
|
|
15297
|
+
const entry = { path: path108, content };
|
|
15264
15298
|
if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
|
|
15265
15299
|
return entry;
|
|
15266
15300
|
}).filter((m3) => m3 !== null);
|
|
@@ -16110,10 +16144,10 @@ function parseAttachment(obj) {
|
|
|
16110
16144
|
const memories = raw.map((m3) => {
|
|
16111
16145
|
if (!m3 || typeof m3 !== "object") return null;
|
|
16112
16146
|
const rec6 = m3;
|
|
16113
|
-
const
|
|
16147
|
+
const path108 = typeof rec6.path === "string" ? rec6.path : null;
|
|
16114
16148
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
16115
|
-
if (!
|
|
16116
|
-
const out = { path:
|
|
16149
|
+
if (!path108 || content == null) return null;
|
|
16150
|
+
const out = { path: path108, content };
|
|
16117
16151
|
if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
|
|
16118
16152
|
return out;
|
|
16119
16153
|
}).filter((m3) => m3 !== null);
|
|
@@ -33468,8 +33502,8 @@ var require_utils = __commonJS({
|
|
|
33468
33502
|
var result = transform[inputType][outputType](input);
|
|
33469
33503
|
return result;
|
|
33470
33504
|
};
|
|
33471
|
-
exports2.resolve = function(
|
|
33472
|
-
var parts =
|
|
33505
|
+
exports2.resolve = function(path108) {
|
|
33506
|
+
var parts = path108.split("/");
|
|
33473
33507
|
var result = [];
|
|
33474
33508
|
for (var index = 0; index < parts.length; index++) {
|
|
33475
33509
|
var part = parts[index];
|
|
@@ -39322,18 +39356,18 @@ var require_object = __commonJS({
|
|
|
39322
39356
|
var object = new ZipObject(name, zipObjectContent, o2);
|
|
39323
39357
|
this.files[name] = object;
|
|
39324
39358
|
};
|
|
39325
|
-
var parentFolder = function(
|
|
39326
|
-
if (
|
|
39327
|
-
|
|
39359
|
+
var parentFolder = function(path108) {
|
|
39360
|
+
if (path108.slice(-1) === "/") {
|
|
39361
|
+
path108 = path108.substring(0, path108.length - 1);
|
|
39328
39362
|
}
|
|
39329
|
-
var lastSlash =
|
|
39330
|
-
return lastSlash > 0 ?
|
|
39363
|
+
var lastSlash = path108.lastIndexOf("/");
|
|
39364
|
+
return lastSlash > 0 ? path108.substring(0, lastSlash) : "";
|
|
39331
39365
|
};
|
|
39332
|
-
var forceTrailingSlash = function(
|
|
39333
|
-
if (
|
|
39334
|
-
|
|
39366
|
+
var forceTrailingSlash = function(path108) {
|
|
39367
|
+
if (path108.slice(-1) !== "/") {
|
|
39368
|
+
path108 += "/";
|
|
39335
39369
|
}
|
|
39336
|
-
return
|
|
39370
|
+
return path108;
|
|
39337
39371
|
};
|
|
39338
39372
|
var folderAdd = function(name, createFolders) {
|
|
39339
39373
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -43951,7 +43985,7 @@ var require_websocket_server = __commonJS({
|
|
|
43951
43985
|
// src/run-case/recorder.ts
|
|
43952
43986
|
function startRunCaseRecorder(opts) {
|
|
43953
43987
|
const now = opts.now ?? Date.now;
|
|
43954
|
-
const dir =
|
|
43988
|
+
const dir = import_node_path87.default.dirname(opts.recordPath);
|
|
43955
43989
|
let stream = null;
|
|
43956
43990
|
let closing = false;
|
|
43957
43991
|
let closedSettled = false;
|
|
@@ -43965,8 +43999,8 @@ function startRunCaseRecorder(opts) {
|
|
|
43965
43999
|
});
|
|
43966
44000
|
const ensureStream = () => {
|
|
43967
44001
|
if (stream) return stream;
|
|
43968
|
-
|
|
43969
|
-
stream =
|
|
44002
|
+
import_node_fs68.default.mkdirSync(dir, { recursive: true });
|
|
44003
|
+
stream = import_node_fs68.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
43970
44004
|
stream.on("close", () => closedResolve());
|
|
43971
44005
|
return stream;
|
|
43972
44006
|
};
|
|
@@ -43991,12 +44025,12 @@ function startRunCaseRecorder(opts) {
|
|
|
43991
44025
|
};
|
|
43992
44026
|
return { tap, close, closed };
|
|
43993
44027
|
}
|
|
43994
|
-
var
|
|
44028
|
+
var import_node_fs68, import_node_path87;
|
|
43995
44029
|
var init_recorder = __esm({
|
|
43996
44030
|
"src/run-case/recorder.ts"() {
|
|
43997
44031
|
"use strict";
|
|
43998
|
-
|
|
43999
|
-
|
|
44032
|
+
import_node_fs68 = __toESM(require("fs"), 1);
|
|
44033
|
+
import_node_path87 = __toESM(require("path"), 1);
|
|
44000
44034
|
}
|
|
44001
44035
|
});
|
|
44002
44036
|
|
|
@@ -44039,7 +44073,7 @@ var init_wire = __esm({
|
|
|
44039
44073
|
// src/run-case/controller.ts
|
|
44040
44074
|
async function runController(opts) {
|
|
44041
44075
|
const now = opts.now ?? Date.now;
|
|
44042
|
-
const cwd = opts.cwd ?? (0,
|
|
44076
|
+
const cwd = opts.cwd ?? (0, import_node_fs69.mkdtempSync)(import_node_path88.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
|
|
44043
44077
|
const ownsCwd = opts.cwd === void 0;
|
|
44044
44078
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
44045
44079
|
const spawnCtx = { cwd };
|
|
@@ -44200,19 +44234,19 @@ async function runController(opts) {
|
|
|
44200
44234
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
44201
44235
|
if (ownsCwd) {
|
|
44202
44236
|
try {
|
|
44203
|
-
(0,
|
|
44237
|
+
(0, import_node_fs69.rmSync)(cwd, { recursive: true, force: true });
|
|
44204
44238
|
} catch {
|
|
44205
44239
|
}
|
|
44206
44240
|
}
|
|
44207
44241
|
return exitCode ?? 0;
|
|
44208
44242
|
}
|
|
44209
|
-
var
|
|
44243
|
+
var import_node_fs69, import_node_os32, import_node_path88;
|
|
44210
44244
|
var init_controller = __esm({
|
|
44211
44245
|
"src/run-case/controller.ts"() {
|
|
44212
44246
|
"use strict";
|
|
44213
|
-
|
|
44247
|
+
import_node_fs69 = require("fs");
|
|
44214
44248
|
import_node_os32 = __toESM(require("os"), 1);
|
|
44215
|
-
|
|
44249
|
+
import_node_path88 = __toESM(require("path"), 1);
|
|
44216
44250
|
init_claude();
|
|
44217
44251
|
init_stdout_splitter();
|
|
44218
44252
|
init_permission_stdio();
|
|
@@ -45831,8 +45865,8 @@ function requireEnvironmentIdentity(stores, environment) {
|
|
|
45831
45865
|
}
|
|
45832
45866
|
|
|
45833
45867
|
// src/index.ts
|
|
45834
|
-
var
|
|
45835
|
-
var
|
|
45868
|
+
var import_node_path86 = __toESM(require("path"), 1);
|
|
45869
|
+
var import_node_fs67 = __toESM(require("fs"), 1);
|
|
45836
45870
|
var import_node_os31 = __toESM(require("os"), 1);
|
|
45837
45871
|
var import_node_crypto30 = require("crypto");
|
|
45838
45872
|
var import_node_url6 = require("url");
|
|
@@ -52509,9 +52543,9 @@ var CentralClientError = class extends Error {
|
|
|
52509
52543
|
cause;
|
|
52510
52544
|
status;
|
|
52511
52545
|
};
|
|
52512
|
-
async function centralRequest(opts,
|
|
52546
|
+
async function centralRequest(opts, path108, init) {
|
|
52513
52547
|
const f2 = opts.fetchImpl ?? globalThis.fetch;
|
|
52514
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52548
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path108}`;
|
|
52515
52549
|
const ctrl = new AbortController();
|
|
52516
52550
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
52517
52551
|
let res;
|
|
@@ -53463,8 +53497,8 @@ function turnStartInput(text, resolveImage) {
|
|
|
53463
53497
|
const items = [];
|
|
53464
53498
|
let leftover = text;
|
|
53465
53499
|
for (const m3 of text.matchAll(SKILL_RE)) {
|
|
53466
|
-
const [marker, name,
|
|
53467
|
-
items.push({ type: "skill", name, path:
|
|
53500
|
+
const [marker, name, path108] = m3;
|
|
53501
|
+
items.push({ type: "skill", name, path: path108 });
|
|
53468
53502
|
leftover = leftover.replace(marker, "");
|
|
53469
53503
|
}
|
|
53470
53504
|
for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -56834,6 +56868,48 @@ function buildShiftInternalHandlers(deps) {
|
|
|
56834
56868
|
// src/handlers/deploy.ts
|
|
56835
56869
|
var import_node_crypto14 = require("crypto");
|
|
56836
56870
|
|
|
56871
|
+
// src/deploy/persona-test.ts
|
|
56872
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
56873
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
56874
|
+
init_protocol();
|
|
56875
|
+
var TEST_SCAN_NOTE_PREFIX = PUBLISHER_TEST_NOTE_PREFIX;
|
|
56876
|
+
function regularFile(root, relative5) {
|
|
56877
|
+
let current = root;
|
|
56878
|
+
for (const segment of relative5.split("/")) {
|
|
56879
|
+
current = import_node_path36.default.join(current, segment);
|
|
56880
|
+
if (import_node_fs33.default.lstatSync(current).isSymbolicLink()) throw new Error("symlink");
|
|
56881
|
+
}
|
|
56882
|
+
if (!import_node_fs33.default.statSync(current).isFile()) throw new Error("not a file");
|
|
56883
|
+
const resolved = import_node_fs33.default.realpathSync(current);
|
|
56884
|
+
if (!resolved.startsWith(root + import_node_path36.default.sep)) throw new Error("outside root");
|
|
56885
|
+
return resolved;
|
|
56886
|
+
}
|
|
56887
|
+
function discoverPublisherTest(dir) {
|
|
56888
|
+
try {
|
|
56889
|
+
const root = import_node_fs33.default.realpathSync(dir);
|
|
56890
|
+
try {
|
|
56891
|
+
import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd"));
|
|
56892
|
+
} catch (error) {
|
|
56893
|
+
if (error.code === "ENOENT") return { problems: [] };
|
|
56894
|
+
throw error;
|
|
56895
|
+
}
|
|
56896
|
+
if (import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd")).isSymbolicLink()) throw new Error("symlink");
|
|
56897
|
+
try {
|
|
56898
|
+
import_node_fs33.default.lstatSync(import_node_path36.default.join(root, ".clawd/test.json"));
|
|
56899
|
+
} catch (error) {
|
|
56900
|
+
if (error.code === "ENOENT") return { problems: [] };
|
|
56901
|
+
throw error;
|
|
56902
|
+
}
|
|
56903
|
+
const file = regularFile(root, ".clawd/test.json");
|
|
56904
|
+
if (import_node_fs33.default.statSync(file).size > 64 * 1024) throw new Error("oversized");
|
|
56905
|
+
const test = PublisherTestSchema.parse(JSON.parse(import_node_fs33.default.readFileSync(file, "utf8")));
|
|
56906
|
+
regularFile(root, test.entry);
|
|
56907
|
+
return { test, problems: [] };
|
|
56908
|
+
} catch {
|
|
56909
|
+
return { problems: [".clawd/test.json \u6216\u6D4B\u8BD5\u5165\u53E3\u65E0\u6548\u3001\u4E0D\u53EF\u8BFB\u6216\u5305\u542B\u7B26\u53F7\u94FE\u63A5\uFF1B\u4FEE\u590D\u540E\u91CD\u65B0\u626B\u63CF"] };
|
|
56910
|
+
}
|
|
56911
|
+
}
|
|
56912
|
+
|
|
56837
56913
|
// src/deploy/verified-release.ts
|
|
56838
56914
|
var import_node_crypto12 = require("crypto");
|
|
56839
56915
|
|
|
@@ -57227,19 +57303,19 @@ function openHttpTurn(opts) {
|
|
|
57227
57303
|
|
|
57228
57304
|
// src/deploy/repo.ts
|
|
57229
57305
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
57230
|
-
var
|
|
57306
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
57231
57307
|
init_protocol();
|
|
57232
57308
|
|
|
57233
57309
|
// src/deploy/deploy-file.ts
|
|
57234
57310
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
57235
|
-
var
|
|
57311
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
57236
57312
|
var import_node_crypto11 = require("crypto");
|
|
57237
57313
|
init_zod();
|
|
57238
57314
|
init_protocol();
|
|
57239
57315
|
|
|
57240
57316
|
// src/deploy/connectors.ts
|
|
57241
|
-
var
|
|
57242
|
-
var
|
|
57317
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
57318
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
57243
57319
|
init_zod();
|
|
57244
57320
|
init_protocol();
|
|
57245
57321
|
|
|
@@ -57327,11 +57403,11 @@ var PACKAGE_RUNNERS = /* @__PURE__ */ new Set(["npx", "uvx", "pnpx", "bunx"]);
|
|
|
57327
57403
|
var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "deno", "python", "python3"]);
|
|
57328
57404
|
var HOST_ARG_PLACEHOLDER = "CLAWD_PERSONA_DIR";
|
|
57329
57405
|
function scanMcpConnectors(personaDir) {
|
|
57330
|
-
const file =
|
|
57406
|
+
const file = import_node_path37.default.join(personaDir, ".mcp.json");
|
|
57331
57407
|
const out = { readable: true, connectors: [], evidence: [], warnings: [] };
|
|
57332
57408
|
let parsed;
|
|
57333
57409
|
try {
|
|
57334
|
-
parsed = JSON.parse(
|
|
57410
|
+
parsed = JSON.parse(import_node_fs34.default.readFileSync(file, "utf8"));
|
|
57335
57411
|
} catch (e) {
|
|
57336
57412
|
if (e.code === "ENOENT") return out;
|
|
57337
57413
|
out.readable = false;
|
|
@@ -57410,6 +57486,7 @@ function cliConnectorFromFinding(item) {
|
|
|
57410
57486
|
}
|
|
57411
57487
|
function mergeConnector(existing, incoming) {
|
|
57412
57488
|
if (!existing) return incoming;
|
|
57489
|
+
if (isFeishuBotConnector(existing) && incoming.name === existing.name && incoming.runner === "cli") return existing;
|
|
57413
57490
|
const reviewed = existing.credentialSource !== void 0;
|
|
57414
57491
|
return {
|
|
57415
57492
|
...incoming,
|
|
@@ -57426,8 +57503,8 @@ function mergeScannedConnectors(existing, scanned) {
|
|
|
57426
57503
|
}
|
|
57427
57504
|
|
|
57428
57505
|
// src/deploy/deploy-file.ts
|
|
57429
|
-
var DEPLOY_FILE =
|
|
57430
|
-
var SCAN_FILE =
|
|
57506
|
+
var DEPLOY_FILE = import_node_path38.default.join(".clawd", "deploy.json");
|
|
57507
|
+
var SCAN_FILE = import_node_path38.default.join(".clawd", "deploy-scan.json");
|
|
57431
57508
|
async function readJson(file) {
|
|
57432
57509
|
let raw;
|
|
57433
57510
|
try {
|
|
@@ -57443,14 +57520,14 @@ async function readJson(file) {
|
|
|
57443
57520
|
}
|
|
57444
57521
|
}
|
|
57445
57522
|
async function writeJson(file, value) {
|
|
57446
|
-
await import_promises4.default.mkdir(
|
|
57523
|
+
await import_promises4.default.mkdir(import_node_path38.default.dirname(file), { recursive: true });
|
|
57447
57524
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
57448
57525
|
await import_promises4.default.writeFile(tmp, `${JSON.stringify(value, null, 2)}
|
|
57449
57526
|
`);
|
|
57450
57527
|
await import_promises4.default.rename(tmp, file);
|
|
57451
57528
|
}
|
|
57452
57529
|
async function readDeployFile(dir) {
|
|
57453
|
-
const raw = await readJson(
|
|
57530
|
+
const raw = await readJson(import_node_path38.default.join(dir, DEPLOY_FILE));
|
|
57454
57531
|
if (raw === void 0) return void 0;
|
|
57455
57532
|
const parsed = DeployFileSchema.safeParse(raw);
|
|
57456
57533
|
if (!parsed.success) {
|
|
@@ -57460,18 +57537,18 @@ async function readDeployFile(dir) {
|
|
|
57460
57537
|
return parsed.data;
|
|
57461
57538
|
}
|
|
57462
57539
|
async function writeDeployFile(dir, file) {
|
|
57463
|
-
await writeJson(
|
|
57540
|
+
await writeJson(import_node_path38.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
|
|
57464
57541
|
}
|
|
57465
57542
|
async function readDeployFileRaw(dir) {
|
|
57466
57543
|
try {
|
|
57467
|
-
return await import_promises4.default.readFile(
|
|
57544
|
+
return await import_promises4.default.readFile(import_node_path38.default.join(dir, DEPLOY_FILE), "utf8");
|
|
57468
57545
|
} catch (err) {
|
|
57469
57546
|
if (err.code === "ENOENT") return void 0;
|
|
57470
57547
|
throw err;
|
|
57471
57548
|
}
|
|
57472
57549
|
}
|
|
57473
57550
|
async function restoreDeployFileRaw(dir, raw) {
|
|
57474
|
-
const file =
|
|
57551
|
+
const file = import_node_path38.default.join(dir, DEPLOY_FILE);
|
|
57475
57552
|
if (raw === void 0) await import_promises4.default.rm(file, { force: true });
|
|
57476
57553
|
else await import_promises4.default.writeFile(file, raw);
|
|
57477
57554
|
}
|
|
@@ -57522,7 +57599,7 @@ function normalizeLegacyScan(raw) {
|
|
|
57522
57599
|
return fix(raw);
|
|
57523
57600
|
}
|
|
57524
57601
|
async function readScanFile(dir) {
|
|
57525
|
-
const raw = normalizeLegacyScan(await readJson(
|
|
57602
|
+
const raw = normalizeLegacyScan(await readJson(import_node_path38.default.join(dir, SCAN_FILE)));
|
|
57526
57603
|
if (raw === void 0) return void 0;
|
|
57527
57604
|
const badShape = (issues) => {
|
|
57528
57605
|
const first = issues[0];
|
|
@@ -57548,7 +57625,7 @@ async function readScanFile(dir) {
|
|
|
57548
57625
|
return parsed.data;
|
|
57549
57626
|
}
|
|
57550
57627
|
async function writeScanFile(dir, file) {
|
|
57551
|
-
await writeJson(
|
|
57628
|
+
await writeJson(import_node_path38.default.join(dir, SCAN_FILE), DeployScanFileSchema.parse(file));
|
|
57552
57629
|
}
|
|
57553
57630
|
function replaceScan(file, entry) {
|
|
57554
57631
|
const idx = file.scans.findIndex((s2) => s2.id === entry.id);
|
|
@@ -61087,10 +61164,10 @@ function createGithubApi(args) {
|
|
|
61087
61164
|
const seal = args.seal ?? sealWithSodium;
|
|
61088
61165
|
const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
|
|
61089
61166
|
const secretsPath = (slug, environment) => `/repos/${slug}/${environment ? `environments/${encodeURIComponent(environment)}` : "actions"}/secrets`;
|
|
61090
|
-
async function request(method,
|
|
61167
|
+
async function request(method, path108, body) {
|
|
61091
61168
|
let res;
|
|
61092
61169
|
try {
|
|
61093
|
-
res = await doFetch(`${API}${
|
|
61170
|
+
res = await doFetch(`${API}${path108}`, {
|
|
61094
61171
|
method,
|
|
61095
61172
|
headers: {
|
|
61096
61173
|
Authorization: `Bearer ${args.token}`,
|
|
@@ -61115,8 +61192,8 @@ function createGithubApi(args) {
|
|
|
61115
61192
|
}
|
|
61116
61193
|
return { status: res.status, json };
|
|
61117
61194
|
}
|
|
61118
|
-
async function must(method,
|
|
61119
|
-
const r2 = await request(method,
|
|
61195
|
+
async function must(method, path108, what, body) {
|
|
61196
|
+
const r2 = await request(method, path108, body);
|
|
61120
61197
|
if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
|
|
61121
61198
|
return r2.json;
|
|
61122
61199
|
}
|
|
@@ -61172,16 +61249,16 @@ function createGithubApi(args) {
|
|
|
61172
61249
|
return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
|
|
61173
61250
|
});
|
|
61174
61251
|
},
|
|
61175
|
-
async getJson(
|
|
61252
|
+
async getJson(path108) {
|
|
61176
61253
|
try {
|
|
61177
|
-
const r2 = await request("GET",
|
|
61254
|
+
const r2 = await request("GET", path108);
|
|
61178
61255
|
return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
|
|
61179
61256
|
} catch {
|
|
61180
61257
|
return void 0;
|
|
61181
61258
|
}
|
|
61182
61259
|
},
|
|
61183
|
-
async getJsonStrict(
|
|
61184
|
-
return must("GET",
|
|
61260
|
+
async getJsonStrict(path108) {
|
|
61261
|
+
return must("GET", path108, "\u8BFB\u53D6\u53D1\u5E03\u8BB0\u5F55");
|
|
61185
61262
|
},
|
|
61186
61263
|
async downloadArtifact(slug, artifactId) {
|
|
61187
61264
|
if (!Number.isSafeInteger(artifactId) || artifactId <= 0) throw new GithubApiError(0, "\u5236\u54C1 ID \u65E0\u6548");
|
|
@@ -61400,6 +61477,7 @@ function renderDeployWorkflow(config) {
|
|
|
61400
61477
|
" sparse-checkout: |",
|
|
61401
61478
|
" cloud-host/pipeline",
|
|
61402
61479
|
" cloud-host/k8s",
|
|
61480
|
+
" cloud-host/src/persona-test-contract.mjs",
|
|
61403
61481
|
"",
|
|
61404
61482
|
" - name: \u8BFB\u90E8\u7F72\u6587\u4EF6",
|
|
61405
61483
|
" id: plan",
|
|
@@ -61432,6 +61510,7 @@ function renderDeployWorkflow(config) {
|
|
|
61432
61510
|
" - name: Check required credentials",
|
|
61433
61511
|
" env:",
|
|
61434
61512
|
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
61513
|
+
" CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
|
|
61435
61514
|
" run: node clawos/cloud-host/pipeline/check-secrets.mjs",
|
|
61436
61515
|
""
|
|
61437
61516
|
];
|
|
@@ -61454,8 +61533,10 @@ function renderDeployWorkflow(config) {
|
|
|
61454
61533
|
` - name: ${script === "smoke" ? "Run real int smoke" : "Register the verified image"}`,
|
|
61455
61534
|
" env:",
|
|
61456
61535
|
" CLAWD_ENV_NAMES: ${{ steps.plan.outputs.env_names }}",
|
|
61536
|
+
" CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
|
|
61457
61537
|
" run: |",
|
|
61458
|
-
`
|
|
61538
|
+
` VALIDATE_PRODUCTION=''; if [ "\${{ inputs.environment }}" = 'production' ]; then VALIDATE_PRODUCTION='--production'; fi`,
|
|
61539
|
+
" IMAGE_REF=$(node clawos/cloud-host/pipeline/release.mjs validate --file candidate-release.json --component persona $VALIDATE_PRODUCTION)",
|
|
61459
61540
|
...script === "register" ? [" node clawos/cloud-host/pipeline/persona-candidate.mjs check-source"] : [],
|
|
61460
61541
|
` node clawos/cloud-host/pipeline/${script}.mjs \\`,
|
|
61461
61542
|
' --image "$IMAGE_REF" \\',
|
|
@@ -61547,6 +61628,7 @@ function renderDeployWorkflow(config) {
|
|
|
61547
61628
|
" ALIBABA_CLOUD_ACCESS_KEY_ID: ${{ secrets.ALI_ACS_ACCESS_KEY_ID }}",
|
|
61548
61629
|
" ALIBABA_CLOUD_ACCESS_KEY_SECRET: ${{ secrets.ALI_ACS_ACCESS_KEY_SECRET }}",
|
|
61549
61630
|
" RELEASE_JSON: ${{ inputs.release_json }}",
|
|
61631
|
+
" CLAWD_PUBLISHER_TEST: ${{ steps.plan.outputs.test }}",
|
|
61550
61632
|
" run: node clawos/cloud-host/pipeline/persona-candidate.mjs",
|
|
61551
61633
|
"",
|
|
61552
61634
|
...upload("persona-candidate"),
|
|
@@ -61775,7 +61857,7 @@ var runCommand = (cmd, args, opts = {}) => new Promise((resolve9) => {
|
|
|
61775
61857
|
});
|
|
61776
61858
|
|
|
61777
61859
|
// src/deploy/repo.ts
|
|
61778
|
-
var DEPLOY_FILE_REL = DEPLOY_FILE.split(
|
|
61860
|
+
var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path39.default.sep).join("/");
|
|
61779
61861
|
var PERSONA_FILE_REL = ".clawd/persona.json";
|
|
61780
61862
|
var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL];
|
|
61781
61863
|
var RepoError = class extends Error {
|
|
@@ -61808,7 +61890,7 @@ async function prepareIntegration(exec, dir, auth) {
|
|
|
61808
61890
|
for (const name of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"]) {
|
|
61809
61891
|
const rel = await mustGit(exec, dir, ["rev-parse", "--git-path", name], "\u68C0\u67E5 Git \u64CD\u4F5C");
|
|
61810
61892
|
try {
|
|
61811
|
-
await import_promises5.default.stat(
|
|
61893
|
+
await import_promises5.default.stat(import_node_path39.default.resolve(dir, rel));
|
|
61812
61894
|
throw new RepoError("Git \u5408\u5E76\u6216\u53D8\u57FA\u8FD8\u672A\u5B8C\u6210\uFF0C\u5148\u5904\u7406\u518D\u53D1\u5E03");
|
|
61813
61895
|
} catch (err) {
|
|
61814
61896
|
if (err.code !== "ENOENT") throw err;
|
|
@@ -61869,7 +61951,7 @@ async function samePath(a2, b3) {
|
|
|
61869
61951
|
try {
|
|
61870
61952
|
return await import_promises5.default.realpath(x2);
|
|
61871
61953
|
} catch {
|
|
61872
|
-
return
|
|
61954
|
+
return import_node_path39.default.resolve(x2);
|
|
61873
61955
|
}
|
|
61874
61956
|
};
|
|
61875
61957
|
return await real(a2) === await real(b3);
|
|
@@ -61895,7 +61977,7 @@ async function identityArgs(exec, dir) {
|
|
|
61895
61977
|
return ["-c", "user.name=clawd", "-c", "user.email=clawd@clawos.local"];
|
|
61896
61978
|
}
|
|
61897
61979
|
async function writeGitignore(dir) {
|
|
61898
|
-
const gi =
|
|
61980
|
+
const gi = import_node_path39.default.join(dir, ".gitignore");
|
|
61899
61981
|
let existing;
|
|
61900
61982
|
try {
|
|
61901
61983
|
existing = await import_promises5.default.readFile(gi, "utf8");
|
|
@@ -61906,18 +61988,18 @@ async function writeGitignore(dir) {
|
|
|
61906
61988
|
}
|
|
61907
61989
|
async function writeWorkflow(dir) {
|
|
61908
61990
|
for (const [rel, body] of [[WORKFLOW_PATH, WORKFLOW_TEMPLATE], [UNPUBLISH_WORKFLOW_PATH, UNPUBLISH_WORKFLOW_TEMPLATE]]) {
|
|
61909
|
-
const wf =
|
|
61910
|
-
await import_promises5.default.mkdir(
|
|
61991
|
+
const wf = import_node_path39.default.join(dir, rel);
|
|
61992
|
+
await import_promises5.default.mkdir(import_node_path39.default.dirname(wf), { recursive: true });
|
|
61911
61993
|
await import_promises5.default.writeFile(wf, body);
|
|
61912
61994
|
}
|
|
61913
61995
|
}
|
|
61914
61996
|
async function writeDockerfile(dir, personaId2, image) {
|
|
61915
61997
|
const baseImage = image.replace("registry-vpc.cn-hangzhou.aliyuncs.com/", "registry.cn-hangzhou.aliyuncs.com/");
|
|
61916
|
-
await import_promises5.default.mkdir(
|
|
61917
|
-
await import_promises5.default.writeFile(
|
|
61998
|
+
await import_promises5.default.mkdir(import_node_path39.default.join(dir, ".clawd"), { recursive: true });
|
|
61999
|
+
await import_promises5.default.writeFile(import_node_path39.default.join(dir, ".clawd", "base-image.txt"), `${baseImage}
|
|
61918
62000
|
`);
|
|
61919
|
-
await import_promises5.default.writeFile(
|
|
61920
|
-
await import_promises5.default.writeFile(
|
|
62001
|
+
await import_promises5.default.writeFile(import_node_path39.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2, baseImage));
|
|
62002
|
+
await import_promises5.default.writeFile(import_node_path39.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
|
|
61921
62003
|
}
|
|
61922
62004
|
var RepoAlreadyExistsError = class extends RepoError {
|
|
61923
62005
|
constructor(slug) {
|
|
@@ -61956,7 +62038,7 @@ async function ensureRepo(exec, api, args) {
|
|
|
61956
62038
|
const existing = await repoInfo(exec, dir);
|
|
61957
62039
|
if (existing) return { created: false, url: existing.url };
|
|
61958
62040
|
await writeGitignore(dir);
|
|
61959
|
-
await import_promises5.default.rm(
|
|
62041
|
+
await import_promises5.default.rm(import_node_path39.default.join(dir, WORKFLOW_PATH), { force: true });
|
|
61960
62042
|
let created;
|
|
61961
62043
|
try {
|
|
61962
62044
|
created = await createOrgRepo(exec, api, { dir, org, repoName: personaId2, message: "clawd: \u4E0A\u4E91", auth: args.auth });
|
|
@@ -62056,7 +62138,8 @@ function validatePersonaRelease(raw, expected) {
|
|
|
62056
62138
|
commit: record4.commit,
|
|
62057
62139
|
baseImage: record4.baseImage,
|
|
62058
62140
|
pipelineCommit: record4.pipelineCommit,
|
|
62059
|
-
repository: record4.repository
|
|
62141
|
+
repository: record4.repository,
|
|
62142
|
+
...record4.test ? { test: record4.test } : {}
|
|
62060
62143
|
})).digest("hex");
|
|
62061
62144
|
if (record4.verification.fingerprint !== fingerprint) throw new Error("\u5236\u54C1\u5DF2\u504F\u79BB\u6D4B\u8BD5\u65F6\u7684\u7248\u672C\uFF0C\u8BF7\u91CD\u65B0\u6D4B\u8BD5");
|
|
62062
62145
|
return record4;
|
|
@@ -62084,6 +62167,7 @@ async function readVerifiedRelease(api, slug, run) {
|
|
|
62084
62167
|
}) };
|
|
62085
62168
|
}
|
|
62086
62169
|
function requireDialogueVerification(release2, run) {
|
|
62170
|
+
if (release2.test && (!release2.verification.checks.includes("persona-custom-test") || !release2.verification.test)) throw new Error("\u53D1\u5E03\u8005\u6D4B\u8BD5\u672A\u901A\u8FC7\uFF0C\u8BF7\u91CD\u65B0\u53D1\u5E03\u6D4B\u8BD5\u73AF\u5883");
|
|
62087
62171
|
if (!["persona-dialogue", "persona-task"].every((check) => release2.verification.checks.includes(check)) || !run.jobs.some((j2) => j2.key === DEPLOY_VERIFY_STAGE && j2.status === "done")) {
|
|
62088
62172
|
throw new Error("\u8FD9\u6B21\u53D1\u5E03\u8FD8\u6CA1\u6709\u901A\u8FC7\u81EA\u52A8 Conversation / Task \u9A8C\u8BC1\uFF0C\u8BF7\u91CD\u65B0\u626B\u63CF\u5E76\u53D1\u5E03\u6D4B\u8BD5\u73AF\u5883");
|
|
62089
62173
|
}
|
|
@@ -62172,9 +62256,9 @@ init_protocol();
|
|
|
62172
62256
|
|
|
62173
62257
|
// src/deploy/artifact.ts
|
|
62174
62258
|
var import_node_crypto13 = require("crypto");
|
|
62175
|
-
var
|
|
62259
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
62176
62260
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
62177
|
-
var
|
|
62261
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
62178
62262
|
var import_node_stream3 = require("stream");
|
|
62179
62263
|
var import_promises6 = require("stream/promises");
|
|
62180
62264
|
var ARTIFACT_MAX_BYTES = 200 * 1024 * 1024;
|
|
@@ -62208,8 +62292,8 @@ function downloadArtifact(exec) {
|
|
|
62208
62292
|
if (!res.ok || !res.body) throw new Error(`\u4E0B\u8F7D\u5931\u8D25 HTTP ${res.status}\uFF1A${url}`);
|
|
62209
62293
|
const declared = Number(res.headers.get("content-length") ?? 0);
|
|
62210
62294
|
if (declared > ARTIFACT_MAX_BYTES) throw new Error(`\u8D44\u4EA7 ${declared} \u5B57\u8282\uFF0C\u8D85\u8FC7\u4E0A\u9650 ${ARTIFACT_MAX_BYTES}\uFF1A${url}`);
|
|
62211
|
-
const dir = await
|
|
62212
|
-
const file =
|
|
62295
|
+
const dir = await import_node_fs35.default.promises.mkdtemp(import_node_path40.default.join(import_node_os11.default.tmpdir(), "clawd-artifact-"));
|
|
62296
|
+
const file = import_node_path40.default.join(dir, "pkg");
|
|
62213
62297
|
const hash = (0, import_node_crypto13.createHash)("sha256");
|
|
62214
62298
|
let size = 0;
|
|
62215
62299
|
const meter = new import_node_stream3.Transform({
|
|
@@ -62221,7 +62305,7 @@ function downloadArtifact(exec) {
|
|
|
62221
62305
|
}
|
|
62222
62306
|
});
|
|
62223
62307
|
try {
|
|
62224
|
-
await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter,
|
|
62308
|
+
await (0, import_promises6.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter, import_node_fs35.default.createWriteStream(file));
|
|
62225
62309
|
let entries;
|
|
62226
62310
|
if (listEntries) {
|
|
62227
62311
|
const r2 = await exec("tar", ["-tzf", file], { timeoutMs: 3e4 });
|
|
@@ -62230,7 +62314,7 @@ function downloadArtifact(exec) {
|
|
|
62230
62314
|
}
|
|
62231
62315
|
return { sha256: hash.digest("hex"), size, ...entries ? { entries } : {} };
|
|
62232
62316
|
} finally {
|
|
62233
|
-
await
|
|
62317
|
+
await import_node_fs35.default.promises.rm(dir, { recursive: true, force: true });
|
|
62234
62318
|
}
|
|
62235
62319
|
};
|
|
62236
62320
|
}
|
|
@@ -62283,12 +62367,12 @@ init_protocol();
|
|
|
62283
62367
|
// src/deploy/publishing-config.ts
|
|
62284
62368
|
async function requireIntegrationPublishingConfig(api, slug) {
|
|
62285
62369
|
const base = `/repos/${slug}`;
|
|
62286
|
-
async function rows(
|
|
62370
|
+
async function rows(path108, field, absentEnvironment = false) {
|
|
62287
62371
|
const result = [];
|
|
62288
62372
|
for (let page = 1; page <= 30; page++) {
|
|
62289
62373
|
let raw;
|
|
62290
62374
|
try {
|
|
62291
|
-
raw = await api.getJsonStrict(`${
|
|
62375
|
+
raw = await api.getJsonStrict(`${path108}?per_page=100&page=${page}`);
|
|
62292
62376
|
} catch (error) {
|
|
62293
62377
|
if (absentEnvironment && page === 1 && error instanceof GithubApiError && error.status === 404) return [];
|
|
62294
62378
|
throw error;
|
|
@@ -62796,15 +62880,17 @@ function buildDeployHandlers(deps) {
|
|
|
62796
62880
|
const lastDone = [...file.scans].reverse().find((s2) => s2.status === "done");
|
|
62797
62881
|
const seed = scanBase.kind === "soft" && releasedEntry ? releasedEntry.manifest : { ...emptyDeployFile().manifest, connectors: (lastDone?.manifest.connectors ?? []).filter((c2) => c2.runner === "mcp") };
|
|
62798
62882
|
const mcp = scanMcpConnectors(dir);
|
|
62883
|
+
const publisherTest = discoverPublisherTest(dir);
|
|
62884
|
+
const { test: _previousTest, ...seedWithoutTest } = seed;
|
|
62799
62885
|
const mcpTargets = new Set(mcp.evidence.map((e) => e.target));
|
|
62800
62886
|
const carriedEvidence = scanBase.kind === "soft" && releasedEntry ? releasedEntry.evidence : [];
|
|
62801
62887
|
const entry = {
|
|
62802
62888
|
id: newScanId(),
|
|
62803
62889
|
status: "scanning",
|
|
62804
|
-
manifest: { ...
|
|
62890
|
+
manifest: { ...seedWithoutTest, ...publisherTest.test ? { test: publisherTest.test } : {}, connectors: mcp.readable ? mergeScannedConnectors(seed.connectors, mcp.connectors) : seed.connectors },
|
|
62805
62891
|
evidence: [...carriedEvidence.filter((e) => !mcpTargets.has(e.target)), ...mcp.evidence.map(redactEvidence)],
|
|
62806
62892
|
// Notes describe this scan's unresolved work; do not carry old notes into a new scan.
|
|
62807
|
-
notes: mcp.warnings.map((w3) => `${MCP_SCAN_NOTE_PREFIX}${w3}`),
|
|
62893
|
+
notes: [...mcp.warnings.map((w3) => `${MCP_SCAN_NOTE_PREFIX}${w3}`), ...publisherTest.problems.map((problem) => TEST_SCAN_NOTE_PREFIX + problem)],
|
|
62808
62894
|
startedAt: deps.now(),
|
|
62809
62895
|
head: contentHead,
|
|
62810
62896
|
baseKind: scanBase.kind,
|
|
@@ -62983,7 +63069,11 @@ function buildDeployHandlers(deps) {
|
|
|
62983
63069
|
} catch (err) {
|
|
62984
63070
|
throw invalid(err instanceof Error ? err.message : String(err));
|
|
62985
63071
|
}
|
|
62986
|
-
if (args.kind === "connector")
|
|
63072
|
+
if (args.kind === "connector") {
|
|
63073
|
+
const incoming = cliConnectorFromFinding(item);
|
|
63074
|
+
const previous = scan.manifest.connectors.some((c2) => c2.name === incoming.name) ? void 0 : [...file.scans].reverse().find((s2) => s2.status === "done")?.manifest.connectors.find((c2) => c2.name === incoming.name && isFeishuBotConnector(c2));
|
|
63075
|
+
item = mergeConnector(previous, incoming);
|
|
63076
|
+
}
|
|
62987
63077
|
if (args.kind === "package") item = await settlePackage(item);
|
|
62988
63078
|
const target = `${args.kind}:${item.name}`;
|
|
62989
63079
|
await writeScanFile(dir, replaceScan(file, {
|
|
@@ -63004,7 +63094,7 @@ function buildDeployHandlers(deps) {
|
|
|
63004
63094
|
status: "done",
|
|
63005
63095
|
finishedAt: deps.now(),
|
|
63006
63096
|
// Redact free-text notes and preserve scanner warnings that the butler does not know about.
|
|
63007
|
-
notes: [...scan.notes.filter((n2) => n2.startsWith(MCP_SCAN_NOTE_PREFIX)), ...args.notes.map(redactSecretValues)],
|
|
63097
|
+
notes: [...scan.notes.filter((n2) => n2.startsWith(MCP_SCAN_NOTE_PREFIX) || n2.startsWith(TEST_SCAN_NOTE_PREFIX)), ...args.notes.map(redactSecretValues)],
|
|
63008
63098
|
error: void 0
|
|
63009
63099
|
}));
|
|
63010
63100
|
return view(args.personaId);
|
|
@@ -63068,6 +63158,10 @@ function buildDeployHandlers(deps) {
|
|
|
63068
63158
|
if (repo2.branch !== "integration") throw invalid("\u8BF7\u91CD\u65B0\u626B\u63CF\uFF0C\u5207\u5230\u6D4B\u8BD5\u53D1\u5E03\u5206\u652F\u540E\u518D\u53D1\u5E03");
|
|
63069
63159
|
const file = await readHistory(dir);
|
|
63070
63160
|
const entry = mustScan(file, scanId);
|
|
63161
|
+
const publisherTest = discoverPublisherTest(dir);
|
|
63162
|
+
const testBlockers = [...publisherTest.problems, ...entry.notes.filter((note) => note.startsWith(TEST_SCAN_NOTE_PREFIX))];
|
|
63163
|
+
if (JSON.stringify(publisherTest.test) !== JSON.stringify(entry.manifest.test)) testBlockers.push("\u6D4B\u8BD5\u58F0\u660E\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u626B\u63CF");
|
|
63164
|
+
if (testBlockers.length) throw invalid("\u8FD8\u5DEE\uFF1A" + testBlockers.join("\uFF1B"));
|
|
63071
63165
|
const pending = file.releases.find((r2) => r2.environment === "integration" && r2.scanId === scanId && !r2.pushed);
|
|
63072
63166
|
if (pending) {
|
|
63073
63167
|
try {
|
|
@@ -63305,14 +63399,14 @@ function buildDeployHandlers(deps) {
|
|
|
63305
63399
|
}
|
|
63306
63400
|
|
|
63307
63401
|
// src/tools/subscription-channels-store.ts
|
|
63308
|
-
var
|
|
63402
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
63309
63403
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
63310
|
-
var
|
|
63404
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
63311
63405
|
|
|
63312
63406
|
// src/tools/subscription-channels-apply.ts
|
|
63313
|
-
var
|
|
63407
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
63314
63408
|
var import_node_os12 = __toESM(require("os"), 1);
|
|
63315
|
-
var
|
|
63409
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
63316
63410
|
|
|
63317
63411
|
// src/tools/codex-config-toml.ts
|
|
63318
63412
|
function parseKey(src, start) {
|
|
@@ -63494,29 +63588,29 @@ function parseValueAt(s2, start) {
|
|
|
63494
63588
|
const bare = /^[^\s,\]}#]+/.exec(s2.slice(i2));
|
|
63495
63589
|
return bare ? { value: bare[0], end: i2 + bare[0].length } : null;
|
|
63496
63590
|
}
|
|
63497
|
-
function setPath(target,
|
|
63591
|
+
function setPath(target, path108, value) {
|
|
63498
63592
|
let node = target;
|
|
63499
|
-
for (const part of
|
|
63593
|
+
for (const part of path108.slice(0, -1)) {
|
|
63500
63594
|
const next = node[part];
|
|
63501
63595
|
if (!next || typeof next !== "object" || Array.isArray(next)) node[part] = {};
|
|
63502
63596
|
node = node[part];
|
|
63503
63597
|
}
|
|
63504
|
-
const last =
|
|
63598
|
+
const last = path108[path108.length - 1];
|
|
63505
63599
|
const existing = node[last];
|
|
63506
63600
|
if (existing && typeof existing === "object" && !Array.isArray(existing) && value && typeof value === "object" && !Array.isArray(value)) {
|
|
63507
63601
|
Object.assign(existing, value);
|
|
63508
63602
|
} else node[last] = value;
|
|
63509
63603
|
}
|
|
63510
|
-
function readTomlTable(text,
|
|
63604
|
+
function readTomlTable(text, path108) {
|
|
63511
63605
|
const result = {};
|
|
63512
63606
|
let found = false;
|
|
63513
|
-
const within = (full) => full.length >=
|
|
63607
|
+
const within = (full) => full.length >= path108.length && path108.every((part, i2) => full[i2] === part);
|
|
63514
63608
|
const lines = scanToml(text);
|
|
63515
63609
|
for (let index = 0; index < lines.length; index++) {
|
|
63516
63610
|
const line = lines[index];
|
|
63517
63611
|
if (line.kind === "header" && within(line.key)) {
|
|
63518
63612
|
found = true;
|
|
63519
|
-
if (line.key.length >
|
|
63613
|
+
if (line.key.length > path108.length) setPath(result, line.key.slice(path108.length), {});
|
|
63520
63614
|
continue;
|
|
63521
63615
|
}
|
|
63522
63616
|
if (line.kind !== "key") continue;
|
|
@@ -63528,16 +63622,16 @@ ${lines[++index].text}`;
|
|
|
63528
63622
|
const parsed = parseTomlValue(raw);
|
|
63529
63623
|
const value = parsed === void 0 ? UNREADABLE : parsed;
|
|
63530
63624
|
found = true;
|
|
63531
|
-
if (full.length ===
|
|
63625
|
+
if (full.length === path108.length) {
|
|
63532
63626
|
if (value && typeof value === "object" && !Array.isArray(value)) Object.assign(result, value);
|
|
63533
|
-
} else setPath(result, full.slice(
|
|
63627
|
+
} else setPath(result, full.slice(path108.length), value);
|
|
63534
63628
|
}
|
|
63535
63629
|
return found ? result : null;
|
|
63536
63630
|
}
|
|
63537
63631
|
|
|
63538
63632
|
// src/tools/subscription-channels-apply.ts
|
|
63539
63633
|
var PROVIDER_ID = "cliproxyapi";
|
|
63540
|
-
var isOwnProvider = (
|
|
63634
|
+
var isOwnProvider = (path108) => path108[0] === "model_providers" && path108[1] === PROVIDER_ID;
|
|
63541
63635
|
function stripCodexProvider(text) {
|
|
63542
63636
|
const out = [];
|
|
63543
63637
|
let dropping = false;
|
|
@@ -63565,31 +63659,31 @@ function stripCodexProvider(text) {
|
|
|
63565
63659
|
return out.join("\n").trim();
|
|
63566
63660
|
}
|
|
63567
63661
|
function writeFileAtomic(file, data) {
|
|
63568
|
-
const target =
|
|
63662
|
+
const target = import_node_fs36.default.existsSync(file) && import_node_fs36.default.lstatSync(file).isSymbolicLink() ? import_node_fs36.default.realpathSync(file) : file;
|
|
63569
63663
|
const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
|
|
63570
|
-
|
|
63571
|
-
|
|
63664
|
+
import_node_fs36.default.writeFileSync(tmp, data, { mode: 384 });
|
|
63665
|
+
import_node_fs36.default.renameSync(tmp, target);
|
|
63572
63666
|
}
|
|
63573
63667
|
function snapshotFile(file) {
|
|
63574
|
-
const original =
|
|
63668
|
+
const original = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
|
|
63575
63669
|
return () => {
|
|
63576
|
-
const current =
|
|
63670
|
+
const current = import_node_fs36.default.existsSync(file) ? import_node_fs36.default.readFileSync(file) : null;
|
|
63577
63671
|
if (original === null) {
|
|
63578
|
-
if (current !== null)
|
|
63672
|
+
if (current !== null) import_node_fs36.default.rmSync(file, { force: true });
|
|
63579
63673
|
return;
|
|
63580
63674
|
}
|
|
63581
63675
|
if (current !== null && current.equals(original)) return;
|
|
63582
63676
|
writeFileAtomic(file, original);
|
|
63583
63677
|
};
|
|
63584
63678
|
}
|
|
63585
|
-
var resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME ||
|
|
63586
|
-
var resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR ||
|
|
63679
|
+
var resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path41.default.join(import_node_os12.default.homedir(), ".codex");
|
|
63680
|
+
var resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os12.default.homedir(), ".pi", "agent");
|
|
63587
63681
|
var PI_SUBSCRIPTION_FILE = "cliproxyapi.json";
|
|
63588
63682
|
function applyCodexSubscriptionChannel(opts) {
|
|
63589
63683
|
const codexHome = resolveCodexHome2(opts.codexHome);
|
|
63590
|
-
|
|
63591
|
-
const configFile =
|
|
63592
|
-
const original =
|
|
63684
|
+
import_node_fs36.default.mkdirSync(codexHome, { recursive: true });
|
|
63685
|
+
const configFile = import_node_path41.default.join(codexHome, "config.toml");
|
|
63686
|
+
const original = import_node_fs36.default.existsSync(configFile) ? import_node_fs36.default.readFileSync(configFile, "utf8") : "";
|
|
63593
63687
|
const rest = stripCodexProvider(original);
|
|
63594
63688
|
let content;
|
|
63595
63689
|
if (opts.channel) {
|
|
@@ -63616,8 +63710,8 @@ function applyCodexSubscriptionChannel(opts) {
|
|
|
63616
63710
|
}
|
|
63617
63711
|
function applyPiSubscriptionChannel(opts) {
|
|
63618
63712
|
const agentDir = resolvePiAgentDir(opts.agentDir);
|
|
63619
|
-
if (!
|
|
63620
|
-
const configFile =
|
|
63713
|
+
if (!import_node_fs36.default.existsSync(agentDir)) return false;
|
|
63714
|
+
const configFile = import_node_path41.default.join(agentDir, PI_SUBSCRIPTION_FILE);
|
|
63621
63715
|
if (opts.channel) {
|
|
63622
63716
|
const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
|
|
63623
63717
|
writeFileAtomic(configFile, JSON.stringify(data, null, 2) + "\n");
|
|
@@ -63646,7 +63740,7 @@ function providerKey(provider, codexHome) {
|
|
|
63646
63740
|
}
|
|
63647
63741
|
function readAuthKey2(codexHome) {
|
|
63648
63742
|
try {
|
|
63649
|
-
const key = JSON.parse(
|
|
63743
|
+
const key = JSON.parse(import_node_fs37.default.readFileSync(import_node_path42.default.join(codexHome, "auth.json"), "utf8")).OPENAI_API_KEY;
|
|
63650
63744
|
return typeof key === "string" && key ? key : null;
|
|
63651
63745
|
} catch {
|
|
63652
63746
|
return null;
|
|
@@ -63656,8 +63750,8 @@ var SubscriptionChannelStore = class {
|
|
|
63656
63750
|
filePath;
|
|
63657
63751
|
codexHome;
|
|
63658
63752
|
constructor(options) {
|
|
63659
|
-
this.filePath =
|
|
63660
|
-
this.codexHome = options.codexHome || process.env.CODEX_HOME ||
|
|
63753
|
+
this.filePath = import_node_path42.default.join(options.dataDir, CHANNELS_FILE_NAME);
|
|
63754
|
+
this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path42.default.join(import_node_os13.default.homedir(), ".codex");
|
|
63661
63755
|
}
|
|
63662
63756
|
/** 存储文件的快照(首次初始化 / 迁移先落盘);返回的函数把它恢复成此刻的样子,通道切换失败时回滚用 */
|
|
63663
63757
|
snapshot() {
|
|
@@ -63754,9 +63848,9 @@ var SubscriptionChannelStore = class {
|
|
|
63754
63848
|
return target;
|
|
63755
63849
|
}
|
|
63756
63850
|
readOrCreate() {
|
|
63757
|
-
if (
|
|
63851
|
+
if (import_node_fs37.default.existsSync(this.filePath)) {
|
|
63758
63852
|
try {
|
|
63759
|
-
const raw = JSON.parse(
|
|
63853
|
+
const raw = JSON.parse(import_node_fs37.default.readFileSync(this.filePath, "utf8"));
|
|
63760
63854
|
if (raw && Array.isArray(raw.channels)) {
|
|
63761
63855
|
return {
|
|
63762
63856
|
activeChannelId: typeof raw.activeChannelId === "string" ? raw.activeChannelId : null,
|
|
@@ -63776,9 +63870,9 @@ var SubscriptionChannelStore = class {
|
|
|
63776
63870
|
}
|
|
63777
63871
|
tryMigrateFromCodexConfig() {
|
|
63778
63872
|
try {
|
|
63779
|
-
const configPath =
|
|
63780
|
-
if (!
|
|
63781
|
-
const content =
|
|
63873
|
+
const configPath = import_node_path42.default.join(this.codexHome, "config.toml");
|
|
63874
|
+
if (!import_node_fs37.default.existsSync(configPath)) return null;
|
|
63875
|
+
const content = import_node_fs37.default.readFileSync(configPath, "utf8");
|
|
63782
63876
|
if (readTomlTable(content, [])?.model_provider !== "cliproxyapi") return null;
|
|
63783
63877
|
const provider = readTomlTable(content, ["model_providers", "cliproxyapi"]);
|
|
63784
63878
|
if (!provider) return null;
|
|
@@ -63805,8 +63899,8 @@ var SubscriptionChannelStore = class {
|
|
|
63805
63899
|
return null;
|
|
63806
63900
|
}
|
|
63807
63901
|
write(data) {
|
|
63808
|
-
const dir =
|
|
63809
|
-
|
|
63902
|
+
const dir = import_node_path42.default.dirname(this.filePath);
|
|
63903
|
+
import_node_fs37.default.mkdirSync(dir, { recursive: true });
|
|
63810
63904
|
writeFileAtomic(this.filePath, JSON.stringify(data, null, 2) + "\n");
|
|
63811
63905
|
}
|
|
63812
63906
|
};
|
|
@@ -63869,8 +63963,8 @@ function refreshPathFromLoginShell() {
|
|
|
63869
63963
|
timeout: 3e3,
|
|
63870
63964
|
stdio: ["ignore", "pipe", "ignore"]
|
|
63871
63965
|
});
|
|
63872
|
-
const
|
|
63873
|
-
if (
|
|
63966
|
+
const path108 = out.trim();
|
|
63967
|
+
if (path108) process.env.PATH = path108;
|
|
63874
63968
|
} catch {
|
|
63875
63969
|
}
|
|
63876
63970
|
}
|
|
@@ -64663,10 +64757,10 @@ function createCloudPersonaBotClient(opts) {
|
|
|
64663
64757
|
const f2 = opts.fetchImpl ?? fetch;
|
|
64664
64758
|
const base = opts.api.replace(/\/+$/, "");
|
|
64665
64759
|
const route = (personaId2) => `/api/lark-bot/cloud/${encodeURIComponent(personaId2)}`;
|
|
64666
|
-
async function request(method,
|
|
64760
|
+
async function request(method, path108, body) {
|
|
64667
64761
|
const pass = opts.getLoginPass();
|
|
64668
64762
|
if (!pass) throw new LarkBotCloudError("\u98DE\u4E66\u767B\u5F55\u540E\u624D\u80FD\u7BA1\u7406\u4E91 Persona \u7684 Bot", 401);
|
|
64669
|
-
const response = await f2(base +
|
|
64763
|
+
const response = await f2(base + path108, {
|
|
64670
64764
|
method,
|
|
64671
64765
|
headers: { authorization: `Bearer ${pass}`, "content-type": "application/json" },
|
|
64672
64766
|
...body ? { body: JSON.stringify(body) } : {},
|
|
@@ -64675,7 +64769,7 @@ function createCloudPersonaBotClient(opts) {
|
|
|
64675
64769
|
const json = await response.json().catch(() => ({}));
|
|
64676
64770
|
if (!response.ok) {
|
|
64677
64771
|
const detail = typeof json.message === "string" ? json.message : `HTTP ${response.status}`;
|
|
64678
|
-
throw new LarkBotCloudError(`cloud bot ${method} ${
|
|
64772
|
+
throw new LarkBotCloudError(`cloud bot ${method} ${path108}: ${detail}`, response.status);
|
|
64679
64773
|
}
|
|
64680
64774
|
return json;
|
|
64681
64775
|
}
|
|
@@ -64691,15 +64785,15 @@ function createCloudPersonaBotClient(opts) {
|
|
|
64691
64785
|
}
|
|
64692
64786
|
|
|
64693
64787
|
// src/lark-bot-connector/binding-store.ts
|
|
64694
|
-
var
|
|
64695
|
-
var
|
|
64788
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
64789
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
64696
64790
|
function createLarkBotBindingStore(personaRoot) {
|
|
64697
|
-
const filePath = (personaId2) =>
|
|
64791
|
+
const filePath = (personaId2) => import_node_path43.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
|
|
64698
64792
|
const read = (personaId2) => {
|
|
64699
64793
|
const file = filePath(personaId2);
|
|
64700
|
-
if (!
|
|
64794
|
+
if (!import_node_fs38.default.existsSync(file)) return null;
|
|
64701
64795
|
try {
|
|
64702
|
-
const raw = JSON.parse(
|
|
64796
|
+
const raw = JSON.parse(import_node_fs38.default.readFileSync(file, "utf8"));
|
|
64703
64797
|
if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
|
|
64704
64798
|
return raw;
|
|
64705
64799
|
} catch {
|
|
@@ -64708,16 +64802,16 @@ function createLarkBotBindingStore(personaRoot) {
|
|
|
64708
64802
|
};
|
|
64709
64803
|
const write = (personaId2, meta) => {
|
|
64710
64804
|
const file = filePath(personaId2);
|
|
64711
|
-
|
|
64805
|
+
import_node_fs38.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
|
|
64712
64806
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
64713
|
-
|
|
64714
|
-
|
|
64807
|
+
import_node_fs38.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
|
|
64808
|
+
import_node_fs38.default.renameSync(tmp, file);
|
|
64715
64809
|
};
|
|
64716
64810
|
return {
|
|
64717
64811
|
read,
|
|
64718
64812
|
write,
|
|
64719
64813
|
remove(personaId2) {
|
|
64720
|
-
|
|
64814
|
+
import_node_fs38.default.rmSync(filePath(personaId2), { force: true });
|
|
64721
64815
|
},
|
|
64722
64816
|
addRemovedChat(personaId2, chatId) {
|
|
64723
64817
|
const meta = read(personaId2);
|
|
@@ -64730,8 +64824,8 @@ function createLarkBotBindingStore(personaRoot) {
|
|
|
64730
64824
|
}
|
|
64731
64825
|
|
|
64732
64826
|
// src/lark-bot-connector/chat-router.ts
|
|
64733
|
-
var
|
|
64734
|
-
var
|
|
64827
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
64828
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
64735
64829
|
init_protocol();
|
|
64736
64830
|
var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
|
|
64737
64831
|
var LOCAL_TURN_RETRIES = 2;
|
|
@@ -64809,9 +64903,9 @@ function createLarkChatRouter(deps) {
|
|
|
64809
64903
|
continue;
|
|
64810
64904
|
}
|
|
64811
64905
|
const dir = deps.mediaRootFor(env.chatId);
|
|
64812
|
-
|
|
64813
|
-
const p3 =
|
|
64814
|
-
|
|
64906
|
+
import_node_fs39.default.mkdirSync(dir, { recursive: true });
|
|
64907
|
+
const p3 = import_node_path44.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
|
|
64908
|
+
import_node_fs39.default.writeFileSync(p3, r2.data);
|
|
64815
64909
|
lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
64816
64910
|
} catch (err) {
|
|
64817
64911
|
deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
|
|
@@ -64832,9 +64926,9 @@ function createLarkChatRouter(deps) {
|
|
|
64832
64926
|
continue;
|
|
64833
64927
|
}
|
|
64834
64928
|
const dir = deps.mediaRootFor(env.chatId);
|
|
64835
|
-
|
|
64836
|
-
const p3 =
|
|
64837
|
-
|
|
64929
|
+
import_node_fs39.default.mkdirSync(dir, { recursive: true });
|
|
64930
|
+
const p3 = import_node_path44.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
|
|
64931
|
+
import_node_fs39.default.writeFileSync(p3, r2.data);
|
|
64838
64932
|
lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
64839
64933
|
} catch (err) {
|
|
64840
64934
|
deps.logger?.warn(`larkBot file fetch failed ${f2.key}: ${err.message}`);
|
|
@@ -65648,7 +65742,7 @@ async function forwardPeerExecToPeer(args) {
|
|
|
65648
65742
|
init_protocol();
|
|
65649
65743
|
|
|
65650
65744
|
// src/tools/codex-cloud-session.ts
|
|
65651
|
-
var
|
|
65745
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
65652
65746
|
|
|
65653
65747
|
// src/tools/cloud-portable-input.ts
|
|
65654
65748
|
async function portableCloudInput(text, resolvers) {
|
|
@@ -65803,7 +65897,7 @@ function cloudImageInput(deps) {
|
|
|
65803
65897
|
const mime = lookupMime(p3);
|
|
65804
65898
|
if (!mime.startsWith("image/")) return null;
|
|
65805
65899
|
try {
|
|
65806
|
-
const bytes = (deps.readFile ??
|
|
65900
|
+
const bytes = (deps.readFile ?? import_node_fs40.default.readFileSync)(p3);
|
|
65807
65901
|
return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
|
|
65808
65902
|
} catch (e) {
|
|
65809
65903
|
deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
|
|
@@ -65905,7 +65999,7 @@ init_protocol();
|
|
|
65905
65999
|
|
|
65906
66000
|
// src/tools/pi.ts
|
|
65907
66001
|
var import_node_child_process13 = require("child_process");
|
|
65908
|
-
var
|
|
66002
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
65909
66003
|
init_protocol();
|
|
65910
66004
|
|
|
65911
66005
|
// src/tools/pi-rpc-client.ts
|
|
@@ -66006,8 +66100,8 @@ var PiRpcClient = class {
|
|
|
66006
66100
|
// src/tools/pi-session.ts
|
|
66007
66101
|
var import_node_child_process12 = require("child_process");
|
|
66008
66102
|
var import_node_crypto17 = require("crypto");
|
|
66009
|
-
var
|
|
66010
|
-
var
|
|
66103
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
66104
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
66011
66105
|
|
|
66012
66106
|
// src/tools/pi-events.ts
|
|
66013
66107
|
init_protocol();
|
|
@@ -66288,8 +66382,8 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
|
|
|
66288
66382
|
function createPiSession(ctx, sink, deps = {}) {
|
|
66289
66383
|
const cmd = process.env.PI_BIN ?? "pi";
|
|
66290
66384
|
const sessionId = ctx.toolSessionId ?? (0, import_node_crypto17.randomUUID)();
|
|
66291
|
-
const skillsDir =
|
|
66292
|
-
const exists = deps.skillsDirExists ?? ((d2) =>
|
|
66385
|
+
const skillsDir = import_node_path45.default.join(ctx.cwd, ".claude", "skills");
|
|
66386
|
+
const exists = deps.skillsDirExists ?? ((d2) => import_node_fs41.default.existsSync(d2));
|
|
66293
66387
|
const args = buildPiArgs(ctx, {
|
|
66294
66388
|
sessionId,
|
|
66295
66389
|
skillsDir: exists(skillsDir) ? skillsDir : void 0,
|
|
@@ -66351,10 +66445,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
|
|
|
66351
66445
|
};
|
|
66352
66446
|
var PI_FULL_ACCESS = { id: "never", label: "Full Access", description: "pi \u65E0\u5BA1\u6279\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
|
|
66353
66447
|
async function probePi(env = process.env) {
|
|
66354
|
-
if (env.PI_BIN &&
|
|
66448
|
+
if (env.PI_BIN && import_node_fs42.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
|
|
66355
66449
|
try {
|
|
66356
66450
|
const out = (0, import_node_child_process13.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
|
|
66357
|
-
if (out &&
|
|
66451
|
+
if (out && import_node_fs42.default.existsSync(out)) return { available: true, path: out };
|
|
66358
66452
|
} catch {
|
|
66359
66453
|
}
|
|
66360
66454
|
return { available: false };
|
|
@@ -66644,7 +66738,7 @@ var CloudPiAdapter = class {
|
|
|
66644
66738
|
init_protocol();
|
|
66645
66739
|
|
|
66646
66740
|
// src/tools/codex-skills.ts
|
|
66647
|
-
var
|
|
66741
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
66648
66742
|
function str4(v3) {
|
|
66649
66743
|
return typeof v3 === "string" ? v3 : void 0;
|
|
66650
66744
|
}
|
|
@@ -66659,13 +66753,13 @@ function mapSkillsListResponse(res) {
|
|
|
66659
66753
|
const r2 = s2 ?? {};
|
|
66660
66754
|
const name = str4(r2.name);
|
|
66661
66755
|
if (!name) continue;
|
|
66662
|
-
const
|
|
66756
|
+
const path108 = str4(r2.path);
|
|
66663
66757
|
const description = str4(r2.description);
|
|
66664
66758
|
const isPlugin = name.includes(":");
|
|
66665
66759
|
out.push({
|
|
66666
66760
|
name,
|
|
66667
66761
|
source: isPlugin ? "plugin" : "project",
|
|
66668
|
-
...
|
|
66762
|
+
...path108 ? { path: path108 } : {},
|
|
66669
66763
|
...description ? { description } : {},
|
|
66670
66764
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
66671
66765
|
});
|
|
@@ -66681,7 +66775,7 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
66681
66775
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
66682
66776
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
66683
66777
|
beforeRequest: (client) => {
|
|
66684
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
66778
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path46.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
66685
66779
|
}
|
|
66686
66780
|
});
|
|
66687
66781
|
return mapSkillsListResponse(res);
|
|
@@ -66755,23 +66849,23 @@ function rec4(v3) {
|
|
|
66755
66849
|
}
|
|
66756
66850
|
|
|
66757
66851
|
// src/workspace/browser.ts
|
|
66758
|
-
var
|
|
66852
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
66759
66853
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
66760
|
-
var
|
|
66854
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
66761
66855
|
init_protocol();
|
|
66762
66856
|
var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
|
|
66763
66857
|
function resolveInsideCwd(cwd, subpath) {
|
|
66764
|
-
const absCwd =
|
|
66765
|
-
const joined =
|
|
66766
|
-
const rel =
|
|
66767
|
-
if (rel.startsWith("..") ||
|
|
66858
|
+
const absCwd = import_node_path47.default.resolve(cwd);
|
|
66859
|
+
const joined = import_node_path47.default.resolve(absCwd, subpath ?? ".");
|
|
66860
|
+
const rel = import_node_path47.default.relative(absCwd, joined);
|
|
66861
|
+
if (rel.startsWith("..") || import_node_path47.default.isAbsolute(rel)) {
|
|
66768
66862
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
66769
66863
|
}
|
|
66770
66864
|
return joined;
|
|
66771
66865
|
}
|
|
66772
66866
|
function ensureCwd(cwd) {
|
|
66773
66867
|
try {
|
|
66774
|
-
const stat =
|
|
66868
|
+
const stat = import_node_fs43.default.statSync(cwd);
|
|
66775
66869
|
if (!stat.isDirectory()) {
|
|
66776
66870
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
66777
66871
|
}
|
|
@@ -66785,7 +66879,7 @@ var WorkspaceBrowser = class {
|
|
|
66785
66879
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os15.default.homedir();
|
|
66786
66880
|
ensureCwd(cwd);
|
|
66787
66881
|
const full = resolveInsideCwd(cwd, args.path);
|
|
66788
|
-
const dirents =
|
|
66882
|
+
const dirents = import_node_fs43.default.readdirSync(full, { withFileTypes: true });
|
|
66789
66883
|
const entries = [];
|
|
66790
66884
|
for (const d2 of dirents) {
|
|
66791
66885
|
if (!args.showHidden && d2.name.startsWith(".")) continue;
|
|
@@ -66795,7 +66889,7 @@ var WorkspaceBrowser = class {
|
|
|
66795
66889
|
mtime: ""
|
|
66796
66890
|
};
|
|
66797
66891
|
try {
|
|
66798
|
-
const st2 =
|
|
66892
|
+
const st2 = import_node_fs43.default.statSync(import_node_path47.default.join(full, d2.name));
|
|
66799
66893
|
entry.mtime = new Date(st2.mtimeMs).toISOString();
|
|
66800
66894
|
if (d2.isFile()) entry.size = st2.size;
|
|
66801
66895
|
} catch {
|
|
@@ -66811,14 +66905,14 @@ var WorkspaceBrowser = class {
|
|
|
66811
66905
|
read(args) {
|
|
66812
66906
|
ensureCwd(args.cwd);
|
|
66813
66907
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
66814
|
-
const st2 =
|
|
66908
|
+
const st2 = import_node_fs43.default.statSync(full);
|
|
66815
66909
|
if (!st2.isFile()) {
|
|
66816
66910
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
66817
66911
|
}
|
|
66818
66912
|
if (st2.size > MAX_FILE_BYTES2) {
|
|
66819
66913
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
|
|
66820
66914
|
}
|
|
66821
|
-
const buf =
|
|
66915
|
+
const buf = import_node_fs43.default.readFileSync(full);
|
|
66822
66916
|
const isBinary = buf.includes(0);
|
|
66823
66917
|
if (isBinary) {
|
|
66824
66918
|
return {
|
|
@@ -66840,20 +66934,20 @@ var WorkspaceBrowser = class {
|
|
|
66840
66934
|
};
|
|
66841
66935
|
|
|
66842
66936
|
// src/skills/agents-scanner.ts
|
|
66843
|
-
var
|
|
66937
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
66844
66938
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
66845
|
-
var
|
|
66939
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
66846
66940
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
66847
66941
|
function isDirLikeSync2(p3) {
|
|
66848
66942
|
try {
|
|
66849
|
-
return
|
|
66943
|
+
return import_node_fs44.default.statSync(p3).isDirectory();
|
|
66850
66944
|
} catch {
|
|
66851
66945
|
return false;
|
|
66852
66946
|
}
|
|
66853
66947
|
}
|
|
66854
66948
|
function fileExistsSync(p3) {
|
|
66855
66949
|
try {
|
|
66856
|
-
return
|
|
66950
|
+
return import_node_fs44.default.statSync(p3).isFile();
|
|
66857
66951
|
} catch {
|
|
66858
66952
|
return false;
|
|
66859
66953
|
}
|
|
@@ -66861,7 +66955,7 @@ function fileExistsSync(p3) {
|
|
|
66861
66955
|
function parseAgentFile(filePath) {
|
|
66862
66956
|
let content;
|
|
66863
66957
|
try {
|
|
66864
|
-
content =
|
|
66958
|
+
content = import_node_fs44.default.readFileSync(filePath, "utf8");
|
|
66865
66959
|
} catch {
|
|
66866
66960
|
return {};
|
|
66867
66961
|
}
|
|
@@ -66874,16 +66968,16 @@ function parseAgentFile(filePath) {
|
|
|
66874
66968
|
function scanAgentsDir(dir, source, seen, out) {
|
|
66875
66969
|
let entries;
|
|
66876
66970
|
try {
|
|
66877
|
-
entries =
|
|
66971
|
+
entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
|
|
66878
66972
|
} catch {
|
|
66879
66973
|
return;
|
|
66880
66974
|
}
|
|
66881
66975
|
for (const ent of entries) {
|
|
66882
66976
|
if (!ent.name.endsWith(".md")) continue;
|
|
66883
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
66977
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path48.default.join(dir, ent.name)))) {
|
|
66884
66978
|
continue;
|
|
66885
66979
|
}
|
|
66886
|
-
const filePath =
|
|
66980
|
+
const filePath = import_node_path48.default.join(dir, ent.name);
|
|
66887
66981
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
66888
66982
|
if (seen.has(baseName)) continue;
|
|
66889
66983
|
seen.add(baseName);
|
|
@@ -66901,12 +66995,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
66901
66995
|
function walk2(dir, namespaces) {
|
|
66902
66996
|
let entries;
|
|
66903
66997
|
try {
|
|
66904
|
-
entries =
|
|
66998
|
+
entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
|
|
66905
66999
|
} catch {
|
|
66906
67000
|
return;
|
|
66907
67001
|
}
|
|
66908
67002
|
for (const ent of entries) {
|
|
66909
|
-
const childPath =
|
|
67003
|
+
const childPath = import_node_path48.default.join(dir, ent.name);
|
|
66910
67004
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
66911
67005
|
walk2(childPath, [...namespaces, ent.name]);
|
|
66912
67006
|
continue;
|
|
@@ -66931,13 +67025,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
66931
67025
|
walk2(root, []);
|
|
66932
67026
|
}
|
|
66933
67027
|
function readInstalledPlugins2(home) {
|
|
66934
|
-
const pluginsDir =
|
|
66935
|
-
const v22 =
|
|
66936
|
-
const v1 =
|
|
67028
|
+
const pluginsDir = import_node_path48.default.join(home, ".claude", "plugins");
|
|
67029
|
+
const v22 = import_node_path48.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
67030
|
+
const v1 = import_node_path48.default.join(pluginsDir, "installed_plugins.json");
|
|
66937
67031
|
let raw = null;
|
|
66938
67032
|
for (const candidate of [v22, v1]) {
|
|
66939
67033
|
try {
|
|
66940
|
-
raw =
|
|
67034
|
+
raw = import_node_fs44.default.readFileSync(candidate, "utf8");
|
|
66941
67035
|
break;
|
|
66942
67036
|
} catch {
|
|
66943
67037
|
}
|
|
@@ -66962,19 +67056,19 @@ function readInstalledPlugins2(home) {
|
|
|
66962
67056
|
return out;
|
|
66963
67057
|
}
|
|
66964
67058
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
66965
|
-
let cur =
|
|
66966
|
-
const fsRoot =
|
|
67059
|
+
let cur = import_node_path48.default.resolve(startCwd);
|
|
67060
|
+
const fsRoot = import_node_path48.default.parse(cur).root;
|
|
66967
67061
|
while (true) {
|
|
66968
|
-
scanAgentsDir(
|
|
67062
|
+
scanAgentsDir(import_node_path48.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
66969
67063
|
let hasGit = false;
|
|
66970
67064
|
try {
|
|
66971
|
-
hasGit =
|
|
67065
|
+
hasGit = import_node_fs44.default.existsSync(import_node_path48.default.join(cur, ".git"));
|
|
66972
67066
|
} catch {
|
|
66973
67067
|
}
|
|
66974
67068
|
if (hasGit) return;
|
|
66975
67069
|
if (cur === home) return;
|
|
66976
67070
|
if (cur === fsRoot) return;
|
|
66977
|
-
const parent =
|
|
67071
|
+
const parent = import_node_path48.default.dirname(cur);
|
|
66978
67072
|
if (parent === cur) return;
|
|
66979
67073
|
cur = parent;
|
|
66980
67074
|
}
|
|
@@ -67009,7 +67103,7 @@ var AgentsScanner = class {
|
|
|
67009
67103
|
}
|
|
67010
67104
|
const fsBlock = [];
|
|
67011
67105
|
scanAgentsDir(
|
|
67012
|
-
|
|
67106
|
+
import_node_path48.default.join(this.home, ".claude", "agents"),
|
|
67013
67107
|
"global",
|
|
67014
67108
|
seen,
|
|
67015
67109
|
fsBlock
|
|
@@ -67023,7 +67117,7 @@ var AgentsScanner = class {
|
|
|
67023
67117
|
...this.extraPluginRoots
|
|
67024
67118
|
];
|
|
67025
67119
|
for (const { name, root } of plugins) {
|
|
67026
|
-
const agentsRoot =
|
|
67120
|
+
const agentsRoot = import_node_path48.default.join(root, "agents");
|
|
67027
67121
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
67028
67122
|
}
|
|
67029
67123
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -67031,15 +67125,15 @@ var AgentsScanner = class {
|
|
|
67031
67125
|
};
|
|
67032
67126
|
|
|
67033
67127
|
// src/observer/session-observer.ts
|
|
67034
|
-
var
|
|
67128
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
67035
67129
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
67036
|
-
var
|
|
67130
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
67037
67131
|
init_claude_history();
|
|
67038
67132
|
|
|
67039
67133
|
// src/observer/subagent-meta-observer.ts
|
|
67040
|
-
var
|
|
67134
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
67041
67135
|
var import_node_os17 = __toESM(require("os"), 1);
|
|
67042
|
-
var
|
|
67136
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
67043
67137
|
init_claude_history();
|
|
67044
67138
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
67045
67139
|
var SubagentMetaObserver = class {
|
|
@@ -67052,7 +67146,7 @@ var SubagentMetaObserver = class {
|
|
|
67052
67146
|
watches = /* @__PURE__ */ new Map();
|
|
67053
67147
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
67054
67148
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
67055
|
-
return
|
|
67149
|
+
return import_node_path49.default.join(
|
|
67056
67150
|
this.home,
|
|
67057
67151
|
".claude",
|
|
67058
67152
|
"projects",
|
|
@@ -67081,7 +67175,7 @@ var SubagentMetaObserver = class {
|
|
|
67081
67175
|
attachWatcher(w3) {
|
|
67082
67176
|
if (w3.watcher) return;
|
|
67083
67177
|
try {
|
|
67084
|
-
w3.watcher =
|
|
67178
|
+
w3.watcher = import_node_fs45.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
|
|
67085
67179
|
if (!name) return;
|
|
67086
67180
|
const m3 = META_RE.exec(String(name));
|
|
67087
67181
|
if (!m3) return;
|
|
@@ -67093,7 +67187,7 @@ var SubagentMetaObserver = class {
|
|
|
67093
67187
|
scan(w3) {
|
|
67094
67188
|
let entries;
|
|
67095
67189
|
try {
|
|
67096
|
-
entries =
|
|
67190
|
+
entries = import_node_fs45.default.readdirSync(w3.dirPath);
|
|
67097
67191
|
} catch {
|
|
67098
67192
|
return;
|
|
67099
67193
|
}
|
|
@@ -67107,10 +67201,10 @@ var SubagentMetaObserver = class {
|
|
|
67107
67201
|
if (!m3) return;
|
|
67108
67202
|
const agentId = m3[1];
|
|
67109
67203
|
if (w3.emitted.has(agentId)) return;
|
|
67110
|
-
const file =
|
|
67204
|
+
const file = import_node_path49.default.join(w3.dirPath, name);
|
|
67111
67205
|
let raw;
|
|
67112
67206
|
try {
|
|
67113
|
-
raw =
|
|
67207
|
+
raw = import_node_fs45.default.readFileSync(file, "utf8");
|
|
67114
67208
|
} catch {
|
|
67115
67209
|
return;
|
|
67116
67210
|
}
|
|
@@ -67164,14 +67258,14 @@ var SessionObserver = class {
|
|
|
67164
67258
|
metaObserver;
|
|
67165
67259
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
67166
67260
|
if (override) return override;
|
|
67167
|
-
return
|
|
67261
|
+
return import_node_path50.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
67168
67262
|
}
|
|
67169
67263
|
start(args) {
|
|
67170
67264
|
this.stop(args.sessionId);
|
|
67171
67265
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
67172
67266
|
let size = 0;
|
|
67173
67267
|
try {
|
|
67174
|
-
size =
|
|
67268
|
+
size = import_node_fs46.default.statSync(filePath).size;
|
|
67175
67269
|
} catch {
|
|
67176
67270
|
}
|
|
67177
67271
|
const w3 = {
|
|
@@ -67184,16 +67278,16 @@ var SessionObserver = class {
|
|
|
67184
67278
|
adapter: args.adapter,
|
|
67185
67279
|
prevIsRejectSentinel: false,
|
|
67186
67280
|
toolSessionId: args.toolSessionId,
|
|
67187
|
-
sawFile:
|
|
67281
|
+
sawFile: import_node_fs46.default.existsSync(filePath),
|
|
67188
67282
|
lastRelocateScanMs: 0,
|
|
67189
67283
|
pendingCwdDerive: false,
|
|
67190
67284
|
lastDeriveMs: 0
|
|
67191
67285
|
};
|
|
67192
67286
|
try {
|
|
67193
|
-
|
|
67287
|
+
import_node_fs46.default.mkdirSync(import_node_path50.default.dirname(filePath), { recursive: true });
|
|
67194
67288
|
} catch {
|
|
67195
67289
|
}
|
|
67196
|
-
w3.watcher =
|
|
67290
|
+
w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
67197
67291
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
67198
67292
|
this.poll(w3);
|
|
67199
67293
|
});
|
|
@@ -67213,7 +67307,7 @@ var SessionObserver = class {
|
|
|
67213
67307
|
// 读取或解析失败不阻塞 watcher 启动。
|
|
67214
67308
|
hydrateMetaTail(w3, maxLines = 200) {
|
|
67215
67309
|
try {
|
|
67216
|
-
const raw =
|
|
67310
|
+
const raw = import_node_fs46.default.readFileSync(w3.filePath, "utf8");
|
|
67217
67311
|
if (!raw) return;
|
|
67218
67312
|
const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
|
|
67219
67313
|
if (allLines.length === 0) return;
|
|
@@ -67237,7 +67331,7 @@ var SessionObserver = class {
|
|
|
67237
67331
|
poll(w3) {
|
|
67238
67332
|
let size = 0;
|
|
67239
67333
|
try {
|
|
67240
|
-
size =
|
|
67334
|
+
size = import_node_fs46.default.statSync(w3.filePath).size;
|
|
67241
67335
|
} catch {
|
|
67242
67336
|
if (w3.sawFile) this.maybeRelocate(w3);
|
|
67243
67337
|
return;
|
|
@@ -67248,11 +67342,11 @@ var SessionObserver = class {
|
|
|
67248
67342
|
w3.buf = "";
|
|
67249
67343
|
}
|
|
67250
67344
|
if (size === w3.lastSize) return;
|
|
67251
|
-
const fd =
|
|
67345
|
+
const fd = import_node_fs46.default.openSync(w3.filePath, "r");
|
|
67252
67346
|
try {
|
|
67253
67347
|
const len = size - w3.lastSize;
|
|
67254
67348
|
const buf = Buffer.alloc(len);
|
|
67255
|
-
|
|
67349
|
+
import_node_fs46.default.readSync(fd, buf, 0, len, w3.lastSize);
|
|
67256
67350
|
w3.lastSize = size;
|
|
67257
67351
|
w3.buf += buf.toString("utf8");
|
|
67258
67352
|
let newlineIndex;
|
|
@@ -67275,7 +67369,7 @@ var SessionObserver = class {
|
|
|
67275
67369
|
}
|
|
67276
67370
|
}
|
|
67277
67371
|
} finally {
|
|
67278
|
-
|
|
67372
|
+
import_node_fs46.default.closeSync(fd);
|
|
67279
67373
|
}
|
|
67280
67374
|
if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
|
|
67281
67375
|
}
|
|
@@ -67285,7 +67379,7 @@ var SessionObserver = class {
|
|
|
67285
67379
|
const now = Date.now();
|
|
67286
67380
|
if (now - w3.lastRelocateScanMs < 1e3) return;
|
|
67287
67381
|
w3.lastRelocateScanMs = now;
|
|
67288
|
-
const projectsRoot =
|
|
67382
|
+
const projectsRoot = import_node_path50.default.join(this.home, ".claude", "projects");
|
|
67289
67383
|
const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
|
|
67290
67384
|
if (!found || found === w3.filePath) return;
|
|
67291
67385
|
try {
|
|
@@ -67294,7 +67388,7 @@ var SessionObserver = class {
|
|
|
67294
67388
|
}
|
|
67295
67389
|
w3.filePath = found;
|
|
67296
67390
|
try {
|
|
67297
|
-
w3.watcher =
|
|
67391
|
+
w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
67298
67392
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
67299
67393
|
this.poll(w3);
|
|
67300
67394
|
});
|
|
@@ -67414,9 +67508,9 @@ function listRegistered() {
|
|
|
67414
67508
|
// src/tools/title-generator.ts
|
|
67415
67509
|
var import_node_child_process14 = require("child_process");
|
|
67416
67510
|
init_protocol();
|
|
67417
|
-
var
|
|
67511
|
+
var import_node_fs47 = __toESM(require("fs"), 1);
|
|
67418
67512
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
67419
|
-
var
|
|
67513
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
67420
67514
|
var TITLE_GEN_DIR_PREFIX = "clawd-title-";
|
|
67421
67515
|
var TITLE_INPUT_MAX_CHARS = 400;
|
|
67422
67516
|
var DEFAULT_TITLE_GEN_TIMEOUT_MS = 45e3;
|
|
@@ -67507,21 +67601,21 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
|
|
|
67507
67601
|
}
|
|
67508
67602
|
let workDir;
|
|
67509
67603
|
try {
|
|
67510
|
-
workDir =
|
|
67604
|
+
workDir = import_node_fs47.default.mkdtempSync(import_node_path51.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
|
|
67511
67605
|
} catch {
|
|
67512
67606
|
return null;
|
|
67513
67607
|
}
|
|
67514
67608
|
const cleanupWorkDir = () => {
|
|
67515
67609
|
try {
|
|
67516
|
-
|
|
67610
|
+
import_node_fs47.default.rmSync(workDir, { recursive: true, force: true });
|
|
67517
67611
|
} catch {
|
|
67518
67612
|
}
|
|
67519
67613
|
};
|
|
67520
|
-
const outFile =
|
|
67521
|
-
const schemaFile =
|
|
67614
|
+
const outFile = import_node_path51.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
|
|
67615
|
+
const schemaFile = import_node_path51.default.join(workDir, "title-schema.json");
|
|
67522
67616
|
if (tool === "codex") {
|
|
67523
67617
|
try {
|
|
67524
|
-
|
|
67618
|
+
import_node_fs47.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
|
|
67525
67619
|
} catch {
|
|
67526
67620
|
cleanupWorkDir();
|
|
67527
67621
|
return null;
|
|
@@ -67576,7 +67670,7 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
|
|
|
67576
67670
|
if (tool === "claude" || tool === "pi") return finish(parseTitleJson(stdout));
|
|
67577
67671
|
let fileText = "";
|
|
67578
67672
|
try {
|
|
67579
|
-
fileText =
|
|
67673
|
+
fileText = import_node_fs47.default.readFileSync(outFile, "utf8");
|
|
67580
67674
|
} catch {
|
|
67581
67675
|
return finish(null);
|
|
67582
67676
|
}
|
|
@@ -68254,8 +68348,8 @@ async function authenticate(token, deps) {
|
|
|
68254
68348
|
}
|
|
68255
68349
|
|
|
68256
68350
|
// src/legacy-cleanup.ts
|
|
68257
|
-
var
|
|
68258
|
-
var
|
|
68351
|
+
var fs58 = __toESM(require("fs/promises"), 1);
|
|
68352
|
+
var path59 = __toESM(require("path"), 1);
|
|
68259
68353
|
var LEGACY_FILES = [
|
|
68260
68354
|
"personal-capability.json",
|
|
68261
68355
|
"received-capabilities.json",
|
|
@@ -68264,9 +68358,9 @@ var LEGACY_FILES = [
|
|
|
68264
68358
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
68265
68359
|
const removed = [];
|
|
68266
68360
|
for (const name of LEGACY_FILES) {
|
|
68267
|
-
const p3 =
|
|
68361
|
+
const p3 = path59.join(dataDir, name);
|
|
68268
68362
|
try {
|
|
68269
|
-
await
|
|
68363
|
+
await fs58.unlink(p3);
|
|
68270
68364
|
removed.push(name);
|
|
68271
68365
|
logger.debug("legacy capability file removed", { file: name });
|
|
68272
68366
|
} catch (err) {
|
|
@@ -68278,13 +68372,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
68278
68372
|
}
|
|
68279
68373
|
|
|
68280
68374
|
// src/inbox/inbox-store.ts
|
|
68281
|
-
var
|
|
68282
|
-
var
|
|
68375
|
+
var fs59 = __toESM(require("fs"), 1);
|
|
68376
|
+
var path60 = __toESM(require("path"), 1);
|
|
68283
68377
|
var INBOX_SUBDIR = "inbox";
|
|
68284
68378
|
var InboxStore = class {
|
|
68285
68379
|
constructor(dataDir) {
|
|
68286
68380
|
this.dataDir = dataDir;
|
|
68287
|
-
|
|
68381
|
+
fs59.mkdirSync(this.dirPath(), { recursive: true });
|
|
68288
68382
|
}
|
|
68289
68383
|
dataDir;
|
|
68290
68384
|
/** sinceCreatedAt 缺省读全量,否则仅读时间戳更大的消息;读取失败返回空数组。 */
|
|
@@ -68292,7 +68386,7 @@ var InboxStore = class {
|
|
|
68292
68386
|
const file = this.filePath(peerDeviceId);
|
|
68293
68387
|
let raw;
|
|
68294
68388
|
try {
|
|
68295
|
-
raw =
|
|
68389
|
+
raw = fs59.readFileSync(file, "utf8");
|
|
68296
68390
|
} catch (err) {
|
|
68297
68391
|
if (err?.code === "ENOENT") return [];
|
|
68298
68392
|
return [];
|
|
@@ -68305,7 +68399,7 @@ var InboxStore = class {
|
|
|
68305
68399
|
const dir = this.dirPath();
|
|
68306
68400
|
let entries;
|
|
68307
68401
|
try {
|
|
68308
|
-
entries =
|
|
68402
|
+
entries = fs59.readdirSync(dir);
|
|
68309
68403
|
} catch (err) {
|
|
68310
68404
|
if (err?.code === "ENOENT") return [];
|
|
68311
68405
|
return [];
|
|
@@ -68318,9 +68412,9 @@ var InboxStore = class {
|
|
|
68318
68412
|
if (existing.some((m3) => m3.id === message.id)) return;
|
|
68319
68413
|
const file = this.filePath(message.peerDeviceId);
|
|
68320
68414
|
const line = JSON.stringify(message) + "\n";
|
|
68321
|
-
|
|
68415
|
+
fs59.appendFileSync(file, line, { mode: 384 });
|
|
68322
68416
|
try {
|
|
68323
|
-
|
|
68417
|
+
fs59.chmodSync(file, 384);
|
|
68324
68418
|
} catch {
|
|
68325
68419
|
}
|
|
68326
68420
|
}
|
|
@@ -68343,7 +68437,7 @@ var InboxStore = class {
|
|
|
68343
68437
|
removeByPeerDeviceId(peerDeviceId) {
|
|
68344
68438
|
const file = this.filePath(peerDeviceId);
|
|
68345
68439
|
try {
|
|
68346
|
-
|
|
68440
|
+
fs59.unlinkSync(file);
|
|
68347
68441
|
} catch (err) {
|
|
68348
68442
|
if (err?.code === "ENOENT") return;
|
|
68349
68443
|
}
|
|
@@ -68352,18 +68446,18 @@ var InboxStore = class {
|
|
|
68352
68446
|
const file = this.filePath(peerDeviceId);
|
|
68353
68447
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
68354
68448
|
const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
68355
|
-
|
|
68356
|
-
|
|
68449
|
+
fs59.writeFileSync(tmp, content, { mode: 384 });
|
|
68450
|
+
fs59.renameSync(tmp, file);
|
|
68357
68451
|
try {
|
|
68358
|
-
|
|
68452
|
+
fs59.chmodSync(file, 384);
|
|
68359
68453
|
} catch {
|
|
68360
68454
|
}
|
|
68361
68455
|
}
|
|
68362
68456
|
dirPath() {
|
|
68363
|
-
return
|
|
68457
|
+
return path60.join(this.dataDir, INBOX_SUBDIR);
|
|
68364
68458
|
}
|
|
68365
68459
|
filePath(peerDeviceId) {
|
|
68366
|
-
return
|
|
68460
|
+
return path60.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
68367
68461
|
}
|
|
68368
68462
|
};
|
|
68369
68463
|
function parseAllLines(raw) {
|
|
@@ -68441,8 +68535,8 @@ var InboxManager = class {
|
|
|
68441
68535
|
};
|
|
68442
68536
|
|
|
68443
68537
|
// src/state/contact-store.ts
|
|
68444
|
-
var
|
|
68445
|
-
var
|
|
68538
|
+
var fs60 = __toESM(require("fs"), 1);
|
|
68539
|
+
var path61 = __toESM(require("path"), 1);
|
|
68446
68540
|
var FILE_NAME = "contacts.json";
|
|
68447
68541
|
var ContactStore = class {
|
|
68448
68542
|
constructor(dataDir) {
|
|
@@ -68452,10 +68546,10 @@ var ContactStore = class {
|
|
|
68452
68546
|
contacts = /* @__PURE__ */ new Map();
|
|
68453
68547
|
load() {
|
|
68454
68548
|
this.contacts.clear();
|
|
68455
|
-
const file =
|
|
68549
|
+
const file = path61.join(this.dataDir, FILE_NAME);
|
|
68456
68550
|
let raw;
|
|
68457
68551
|
try {
|
|
68458
|
-
raw =
|
|
68552
|
+
raw = fs60.readFileSync(file, "utf8");
|
|
68459
68553
|
} catch (err) {
|
|
68460
68554
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
68461
68555
|
return;
|
|
@@ -68525,20 +68619,20 @@ var ContactStore = class {
|
|
|
68525
68619
|
return true;
|
|
68526
68620
|
}
|
|
68527
68621
|
flush() {
|
|
68528
|
-
const file =
|
|
68622
|
+
const file = path61.join(this.dataDir, FILE_NAME);
|
|
68529
68623
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
68530
68624
|
const content = JSON.stringify(
|
|
68531
68625
|
{ contacts: Array.from(this.contacts.values()) },
|
|
68532
68626
|
null,
|
|
68533
68627
|
2
|
|
68534
68628
|
);
|
|
68535
|
-
|
|
68536
|
-
|
|
68537
|
-
|
|
68629
|
+
fs60.mkdirSync(this.dataDir, { recursive: true });
|
|
68630
|
+
fs60.writeFileSync(tmp, content, { mode: 384 });
|
|
68631
|
+
fs60.renameSync(tmp, file);
|
|
68538
68632
|
}
|
|
68539
68633
|
renameBak(file) {
|
|
68540
68634
|
try {
|
|
68541
|
-
|
|
68635
|
+
fs60.renameSync(file, `${file}.bak`);
|
|
68542
68636
|
} catch {
|
|
68543
68637
|
}
|
|
68544
68638
|
}
|
|
@@ -68646,61 +68740,61 @@ async function connectRemote(args) {
|
|
|
68646
68740
|
}
|
|
68647
68741
|
|
|
68648
68742
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
68649
|
-
var
|
|
68650
|
-
var
|
|
68743
|
+
var fs61 = __toESM(require("fs"), 1);
|
|
68744
|
+
var path62 = __toESM(require("path"), 1);
|
|
68651
68745
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
68652
68746
|
function migrateFlattenSessions(opts) {
|
|
68653
68747
|
const dataDir = opts.dataDir;
|
|
68654
68748
|
const now = opts.now ?? Date.now;
|
|
68655
|
-
const sessionsDir =
|
|
68656
|
-
const flagPath =
|
|
68749
|
+
const sessionsDir = path62.join(dataDir, "sessions");
|
|
68750
|
+
const flagPath = path62.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
68657
68751
|
if (existsSync3(flagPath)) {
|
|
68658
68752
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
68659
68753
|
}
|
|
68660
68754
|
let movedBare = 0;
|
|
68661
68755
|
let movedVmOwner = 0;
|
|
68662
68756
|
let archivedListener = 0;
|
|
68663
|
-
const defaultDir =
|
|
68757
|
+
const defaultDir = path62.join(sessionsDir, "default");
|
|
68664
68758
|
if (existsSync3(defaultDir)) {
|
|
68665
68759
|
for (const entry of readdirSafe(defaultDir)) {
|
|
68666
68760
|
if (!entry.endsWith(".json")) continue;
|
|
68667
|
-
const src =
|
|
68668
|
-
const dst =
|
|
68669
|
-
|
|
68761
|
+
const src = path62.join(defaultDir, entry);
|
|
68762
|
+
const dst = path62.join(sessionsDir, entry);
|
|
68763
|
+
fs61.renameSync(src, dst);
|
|
68670
68764
|
movedBare += 1;
|
|
68671
68765
|
}
|
|
68672
68766
|
rmdirIfEmpty(defaultDir);
|
|
68673
68767
|
}
|
|
68674
68768
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
68675
|
-
const personaDir =
|
|
68769
|
+
const personaDir = path62.join(sessionsDir, pid);
|
|
68676
68770
|
if (!isDir(personaDir)) continue;
|
|
68677
68771
|
if (pid === "default") continue;
|
|
68678
|
-
const ownerSrc =
|
|
68772
|
+
const ownerSrc = path62.join(personaDir, "owner");
|
|
68679
68773
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
68680
|
-
const ownerDst =
|
|
68681
|
-
|
|
68774
|
+
const ownerDst = path62.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
68775
|
+
fs61.mkdirSync(ownerDst, { recursive: true });
|
|
68682
68776
|
for (const file of readdirSafe(ownerSrc)) {
|
|
68683
68777
|
if (!file.endsWith(".json")) continue;
|
|
68684
|
-
|
|
68778
|
+
fs61.renameSync(path62.join(ownerSrc, file), path62.join(ownerDst, file));
|
|
68685
68779
|
movedVmOwner += 1;
|
|
68686
68780
|
}
|
|
68687
68781
|
rmdirIfEmpty(ownerSrc);
|
|
68688
68782
|
}
|
|
68689
|
-
const listenerSrc =
|
|
68783
|
+
const listenerSrc = path62.join(personaDir, "listener");
|
|
68690
68784
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
68691
|
-
const archiveDst =
|
|
68692
|
-
|
|
68785
|
+
const archiveDst = path62.join(dataDir, ".legacy", `listener-${pid}`);
|
|
68786
|
+
fs61.mkdirSync(archiveDst, { recursive: true });
|
|
68693
68787
|
for (const file of readdirSafe(listenerSrc)) {
|
|
68694
68788
|
if (!file.endsWith(".json")) continue;
|
|
68695
|
-
|
|
68789
|
+
fs61.renameSync(path62.join(listenerSrc, file), path62.join(archiveDst, file));
|
|
68696
68790
|
archivedListener += 1;
|
|
68697
68791
|
}
|
|
68698
68792
|
rmdirIfEmpty(listenerSrc);
|
|
68699
68793
|
}
|
|
68700
68794
|
rmdirIfEmpty(personaDir);
|
|
68701
68795
|
}
|
|
68702
|
-
|
|
68703
|
-
|
|
68796
|
+
fs61.mkdirSync(sessionsDir, { recursive: true });
|
|
68797
|
+
fs61.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
68704
68798
|
return {
|
|
68705
68799
|
skipped: false,
|
|
68706
68800
|
flagWritten: true,
|
|
@@ -68711,7 +68805,7 @@ function migrateFlattenSessions(opts) {
|
|
|
68711
68805
|
}
|
|
68712
68806
|
function existsSync3(p3) {
|
|
68713
68807
|
try {
|
|
68714
|
-
|
|
68808
|
+
fs61.statSync(p3);
|
|
68715
68809
|
return true;
|
|
68716
68810
|
} catch {
|
|
68717
68811
|
return false;
|
|
@@ -68719,62 +68813,62 @@ function existsSync3(p3) {
|
|
|
68719
68813
|
}
|
|
68720
68814
|
function isDir(p3) {
|
|
68721
68815
|
try {
|
|
68722
|
-
return
|
|
68816
|
+
return fs61.statSync(p3).isDirectory();
|
|
68723
68817
|
} catch {
|
|
68724
68818
|
return false;
|
|
68725
68819
|
}
|
|
68726
68820
|
}
|
|
68727
68821
|
function readdirSafe(p3) {
|
|
68728
68822
|
try {
|
|
68729
|
-
return
|
|
68823
|
+
return fs61.readdirSync(p3);
|
|
68730
68824
|
} catch {
|
|
68731
68825
|
return [];
|
|
68732
68826
|
}
|
|
68733
68827
|
}
|
|
68734
68828
|
function rmdirIfEmpty(p3) {
|
|
68735
68829
|
try {
|
|
68736
|
-
|
|
68830
|
+
fs61.rmdirSync(p3);
|
|
68737
68831
|
} catch {
|
|
68738
68832
|
}
|
|
68739
68833
|
}
|
|
68740
68834
|
|
|
68741
68835
|
// src/migrations/2026-08-18-drop-seeded-projects.ts
|
|
68742
|
-
var
|
|
68743
|
-
var
|
|
68836
|
+
var fs62 = __toESM(require("fs"), 1);
|
|
68837
|
+
var path63 = __toESM(require("path"), 1);
|
|
68744
68838
|
var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
|
|
68745
68839
|
function dropSeededProjects(opts) {
|
|
68746
|
-
|
|
68747
|
-
const flag =
|
|
68748
|
-
if (
|
|
68749
|
-
const file =
|
|
68840
|
+
fs62.mkdirSync(opts.dataDir, { recursive: true });
|
|
68841
|
+
const flag = path63.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
|
|
68842
|
+
if (fs62.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
|
|
68843
|
+
const file = path63.join(opts.dataDir, "projects.json");
|
|
68750
68844
|
let raw = null;
|
|
68751
68845
|
let dropped = 0;
|
|
68752
68846
|
try {
|
|
68753
|
-
raw =
|
|
68847
|
+
raw = fs62.readFileSync(file, "utf8");
|
|
68754
68848
|
dropped = JSON.parse(raw).projects?.length ?? 0;
|
|
68755
68849
|
} catch {
|
|
68756
68850
|
}
|
|
68757
68851
|
let backup = null;
|
|
68758
68852
|
if (raw != null && dropped > 0) {
|
|
68759
|
-
const dir =
|
|
68760
|
-
|
|
68761
|
-
backup =
|
|
68762
|
-
|
|
68853
|
+
const dir = path63.join(opts.dataDir, "backups");
|
|
68854
|
+
fs62.mkdirSync(dir, { recursive: true });
|
|
68855
|
+
backup = path63.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
|
|
68856
|
+
fs62.writeFileSync(backup, raw);
|
|
68763
68857
|
}
|
|
68764
68858
|
if (raw != null || dropped > 0) {
|
|
68765
|
-
|
|
68859
|
+
fs62.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
|
|
68766
68860
|
}
|
|
68767
|
-
|
|
68861
|
+
fs62.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
|
|
68768
68862
|
return { skipped: false, dropped, backup };
|
|
68769
68863
|
}
|
|
68770
68864
|
|
|
68771
68865
|
// src/transport/http-router.ts
|
|
68772
|
-
var
|
|
68773
|
-
var
|
|
68866
|
+
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
68867
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
68774
68868
|
|
|
68775
68869
|
// src/attachment/upload.ts
|
|
68776
|
-
var
|
|
68777
|
-
var
|
|
68870
|
+
var import_node_fs48 = __toESM(require("fs"), 1);
|
|
68871
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
68778
68872
|
var import_node_crypto19 = __toESM(require("crypto"), 1);
|
|
68779
68873
|
var import_promises8 = require("stream/promises");
|
|
68780
68874
|
var UploadError = class extends Error {
|
|
@@ -68786,22 +68880,22 @@ var UploadError = class extends Error {
|
|
|
68786
68880
|
code;
|
|
68787
68881
|
};
|
|
68788
68882
|
function assertValidFileName(fileName) {
|
|
68789
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
68883
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path52.default.basename(fileName)) {
|
|
68790
68884
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
68791
68885
|
}
|
|
68792
68886
|
}
|
|
68793
68887
|
var HASH_PREFIX_LEN = 16;
|
|
68794
68888
|
async function writeUploadedAttachment(args) {
|
|
68795
68889
|
assertValidFileName(args.fileName);
|
|
68796
|
-
const attachmentsRoot =
|
|
68890
|
+
const attachmentsRoot = import_node_path52.default.join(args.baseDir, ".attachments");
|
|
68797
68891
|
try {
|
|
68798
|
-
|
|
68892
|
+
import_node_fs48.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
68799
68893
|
} catch (err) {
|
|
68800
68894
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
68801
68895
|
}
|
|
68802
68896
|
const hasher = import_node_crypto19.default.createHash("sha256");
|
|
68803
68897
|
let actualSize = 0;
|
|
68804
|
-
const tmpPath =
|
|
68898
|
+
const tmpPath = import_node_path52.default.join(
|
|
68805
68899
|
attachmentsRoot,
|
|
68806
68900
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto19.default.randomBytes(4).toString("hex")}`
|
|
68807
68901
|
);
|
|
@@ -68816,18 +68910,18 @@ async function writeUploadedAttachment(args) {
|
|
|
68816
68910
|
yield buf;
|
|
68817
68911
|
}
|
|
68818
68912
|
},
|
|
68819
|
-
|
|
68913
|
+
import_node_fs48.default.createWriteStream(tmpPath, { mode: 384 })
|
|
68820
68914
|
);
|
|
68821
68915
|
} catch (err) {
|
|
68822
68916
|
try {
|
|
68823
|
-
|
|
68917
|
+
import_node_fs48.default.unlinkSync(tmpPath);
|
|
68824
68918
|
} catch {
|
|
68825
68919
|
}
|
|
68826
68920
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
68827
68921
|
}
|
|
68828
68922
|
if (actualSize !== args.contentLength) {
|
|
68829
68923
|
try {
|
|
68830
|
-
|
|
68924
|
+
import_node_fs48.default.unlinkSync(tmpPath);
|
|
68831
68925
|
} catch {
|
|
68832
68926
|
}
|
|
68833
68927
|
throw new UploadError(
|
|
@@ -68836,34 +68930,34 @@ async function writeUploadedAttachment(args) {
|
|
|
68836
68930
|
);
|
|
68837
68931
|
}
|
|
68838
68932
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
68839
|
-
const hashDir =
|
|
68933
|
+
const hashDir = import_node_path52.default.join(attachmentsRoot, attachmentId);
|
|
68840
68934
|
let finalFileName;
|
|
68841
68935
|
let hashDirExists = false;
|
|
68842
68936
|
try {
|
|
68843
|
-
hashDirExists =
|
|
68937
|
+
hashDirExists = import_node_fs48.default.statSync(hashDir).isDirectory();
|
|
68844
68938
|
} catch {
|
|
68845
68939
|
}
|
|
68846
68940
|
if (hashDirExists) {
|
|
68847
|
-
const existing =
|
|
68941
|
+
const existing = import_node_fs48.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
|
|
68848
68942
|
finalFileName = existing[0] ?? args.fileName;
|
|
68849
68943
|
try {
|
|
68850
|
-
|
|
68944
|
+
import_node_fs48.default.unlinkSync(tmpPath);
|
|
68851
68945
|
} catch {
|
|
68852
68946
|
}
|
|
68853
68947
|
} else {
|
|
68854
68948
|
try {
|
|
68855
|
-
|
|
68949
|
+
import_node_fs48.default.mkdirSync(hashDir, { recursive: true });
|
|
68856
68950
|
finalFileName = args.fileName;
|
|
68857
|
-
|
|
68951
|
+
import_node_fs48.default.renameSync(tmpPath, import_node_path52.default.join(hashDir, finalFileName));
|
|
68858
68952
|
} catch (err) {
|
|
68859
68953
|
try {
|
|
68860
|
-
|
|
68954
|
+
import_node_fs48.default.unlinkSync(tmpPath);
|
|
68861
68955
|
} catch {
|
|
68862
68956
|
}
|
|
68863
68957
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
68864
68958
|
}
|
|
68865
68959
|
}
|
|
68866
|
-
const absPath =
|
|
68960
|
+
const absPath = import_node_path52.default.join(hashDir, finalFileName);
|
|
68867
68961
|
const relPath = absPath;
|
|
68868
68962
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
68869
68963
|
relPath: absPath,
|
|
@@ -68877,7 +68971,7 @@ async function writeUploadedAttachment(args) {
|
|
|
68877
68971
|
|
|
68878
68972
|
// src/extension/import.ts
|
|
68879
68973
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
68880
|
-
var
|
|
68974
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
68881
68975
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
68882
68976
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
68883
68977
|
var ImportError = class extends Error {
|
|
@@ -68895,7 +68989,7 @@ async function importZip(buf, root) {
|
|
|
68895
68989
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
68896
68990
|
}
|
|
68897
68991
|
for (const name of Object.keys(zip.files)) {
|
|
68898
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
68992
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
|
|
68899
68993
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
68900
68994
|
}
|
|
68901
68995
|
}
|
|
@@ -68928,7 +69022,7 @@ async function importZip(buf, root) {
|
|
|
68928
69022
|
);
|
|
68929
69023
|
}
|
|
68930
69024
|
}
|
|
68931
|
-
const destDir =
|
|
69025
|
+
const destDir = import_node_path53.default.join(root, manifest.id);
|
|
68932
69026
|
let destExists = false;
|
|
68933
69027
|
try {
|
|
68934
69028
|
await import_promises9.default.access(destDir);
|
|
@@ -68938,15 +69032,15 @@ async function importZip(buf, root) {
|
|
|
68938
69032
|
if (destExists) {
|
|
68939
69033
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
68940
69034
|
}
|
|
68941
|
-
const stage = await import_promises9.default.mkdtemp(
|
|
69035
|
+
const stage = await import_promises9.default.mkdtemp(import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
68942
69036
|
try {
|
|
68943
69037
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
68944
|
-
const dest =
|
|
69038
|
+
const dest = import_node_path53.default.join(stage, name);
|
|
68945
69039
|
if (entry.dir) {
|
|
68946
69040
|
await import_promises9.default.mkdir(dest, { recursive: true });
|
|
68947
69041
|
continue;
|
|
68948
69042
|
}
|
|
68949
|
-
await import_promises9.default.mkdir(
|
|
69043
|
+
await import_promises9.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
|
|
68950
69044
|
const content = await entry.async("nodebuffer");
|
|
68951
69045
|
await import_promises9.default.writeFile(dest, content);
|
|
68952
69046
|
}
|
|
@@ -69000,7 +69094,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
69000
69094
|
".wasm": "application/wasm"
|
|
69001
69095
|
};
|
|
69002
69096
|
function shareUiAssetMime(filePath) {
|
|
69003
|
-
const ext =
|
|
69097
|
+
const ext = import_node_path54.default.extname(filePath).toLowerCase();
|
|
69004
69098
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
69005
69099
|
}
|
|
69006
69100
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -69099,7 +69193,7 @@ function isValidUploadFileName(fileName) {
|
|
|
69099
69193
|
if (fileName === "." || fileName === "..") return false;
|
|
69100
69194
|
if (fileName.startsWith(".")) return false;
|
|
69101
69195
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
69102
|
-
return fileName ===
|
|
69196
|
+
return fileName === import_node_path54.default.basename(fileName);
|
|
69103
69197
|
}
|
|
69104
69198
|
function createHttpRouter(deps) {
|
|
69105
69199
|
return async (req, res) => {
|
|
@@ -69183,7 +69277,7 @@ function createHttpRouter(deps) {
|
|
|
69183
69277
|
}
|
|
69184
69278
|
let buf;
|
|
69185
69279
|
try {
|
|
69186
|
-
buf = await
|
|
69280
|
+
buf = await import_node_fs49.default.promises.readFile(abs);
|
|
69187
69281
|
} catch {
|
|
69188
69282
|
sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
69189
69283
|
return true;
|
|
@@ -69329,7 +69423,7 @@ function createHttpRouter(deps) {
|
|
|
69329
69423
|
sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
|
|
69330
69424
|
return true;
|
|
69331
69425
|
}
|
|
69332
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
69426
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path54.default.basename(r2.absPath)));
|
|
69333
69427
|
return true;
|
|
69334
69428
|
}
|
|
69335
69429
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -69450,7 +69544,7 @@ function createHttpRouter(deps) {
|
|
|
69450
69544
|
return true;
|
|
69451
69545
|
}
|
|
69452
69546
|
let absPath;
|
|
69453
|
-
if (
|
|
69547
|
+
if (import_node_path54.default.isAbsolute(pathParam)) {
|
|
69454
69548
|
absPath = pathParam;
|
|
69455
69549
|
} else if (deps.sessionStore) {
|
|
69456
69550
|
const file = deps.sessionStore.read(sid);
|
|
@@ -69458,7 +69552,7 @@ function createHttpRouter(deps) {
|
|
|
69458
69552
|
sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
69459
69553
|
return true;
|
|
69460
69554
|
}
|
|
69461
|
-
absPath =
|
|
69555
|
+
absPath = import_node_path54.default.join(file.cwd, pathParam);
|
|
69462
69556
|
} else {
|
|
69463
69557
|
sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
69464
69558
|
return true;
|
|
@@ -69542,7 +69636,7 @@ function withCtx(ctx, body) {
|
|
|
69542
69636
|
function streamFile(res, absPath, logger) {
|
|
69543
69637
|
let stat;
|
|
69544
69638
|
try {
|
|
69545
|
-
stat =
|
|
69639
|
+
stat = import_node_fs49.default.statSync(absPath);
|
|
69546
69640
|
} catch (err) {
|
|
69547
69641
|
const code = err?.code;
|
|
69548
69642
|
if (code === "ENOENT") {
|
|
@@ -69557,7 +69651,7 @@ function streamFile(res, absPath, logger) {
|
|
|
69557
69651
|
return;
|
|
69558
69652
|
}
|
|
69559
69653
|
const mime = lookupMime(absPath);
|
|
69560
|
-
const basename2 =
|
|
69654
|
+
const basename2 = import_node_path54.default.basename(absPath);
|
|
69561
69655
|
res.writeHead(200, {
|
|
69562
69656
|
"Content-Type": mime,
|
|
69563
69657
|
"Content-Length": String(stat.size),
|
|
@@ -69565,7 +69659,7 @@ function streamFile(res, absPath, logger) {
|
|
|
69565
69659
|
// Prevent MIME sniffing; explicit HTML MIME remains renderable.
|
|
69566
69660
|
"X-Content-Type-Options": "nosniff"
|
|
69567
69661
|
});
|
|
69568
|
-
const stream =
|
|
69662
|
+
const stream = import_node_fs49.default.createReadStream(absPath);
|
|
69569
69663
|
stream.on("error", (err) => {
|
|
69570
69664
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
69571
69665
|
res.destroy();
|
|
@@ -69574,8 +69668,8 @@ function streamFile(res, absPath, logger) {
|
|
|
69574
69668
|
}
|
|
69575
69669
|
|
|
69576
69670
|
// src/attachment/gc.ts
|
|
69577
|
-
var
|
|
69578
|
-
var
|
|
69671
|
+
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
69672
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
69579
69673
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
69580
69674
|
function runAttachmentGc(args) {
|
|
69581
69675
|
const now = (args.now ?? Date.now)();
|
|
@@ -69584,12 +69678,12 @@ function runAttachmentGc(args) {
|
|
|
69584
69678
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
69585
69679
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
69586
69680
|
if (entry.stale) continue;
|
|
69587
|
-
if (
|
|
69681
|
+
if (import_node_path55.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
69588
69682
|
}
|
|
69589
69683
|
}
|
|
69590
69684
|
const visited = /* @__PURE__ */ new Set();
|
|
69591
69685
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
69592
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
69686
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path55.default.join(
|
|
69593
69687
|
args.dataDir,
|
|
69594
69688
|
"sessions",
|
|
69595
69689
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -69602,28 +69696,28 @@ function runAttachmentGc(args) {
|
|
|
69602
69696
|
return true;
|
|
69603
69697
|
});
|
|
69604
69698
|
for (const rootDir of roots) {
|
|
69605
|
-
const attRoot =
|
|
69699
|
+
const attRoot = import_node_path55.default.join(rootDir, ".attachments");
|
|
69606
69700
|
let hashDirs;
|
|
69607
69701
|
try {
|
|
69608
|
-
hashDirs =
|
|
69702
|
+
hashDirs = import_node_fs50.default.readdirSync(attRoot);
|
|
69609
69703
|
} catch (err) {
|
|
69610
69704
|
if (err.code === "ENOENT") continue;
|
|
69611
69705
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
69612
69706
|
continue;
|
|
69613
69707
|
}
|
|
69614
69708
|
for (const hashDir of hashDirs) {
|
|
69615
|
-
const hashDirAbs =
|
|
69709
|
+
const hashDirAbs = import_node_path55.default.join(attRoot, hashDir);
|
|
69616
69710
|
let files;
|
|
69617
69711
|
try {
|
|
69618
|
-
files =
|
|
69712
|
+
files = import_node_fs50.default.readdirSync(hashDirAbs);
|
|
69619
69713
|
} catch {
|
|
69620
69714
|
continue;
|
|
69621
69715
|
}
|
|
69622
69716
|
for (const name of files) {
|
|
69623
|
-
const file =
|
|
69717
|
+
const file = import_node_path55.default.join(hashDirAbs, name);
|
|
69624
69718
|
let stat;
|
|
69625
69719
|
try {
|
|
69626
|
-
stat =
|
|
69720
|
+
stat = import_node_fs50.default.statSync(file);
|
|
69627
69721
|
} catch {
|
|
69628
69722
|
continue;
|
|
69629
69723
|
}
|
|
@@ -69632,18 +69726,18 @@ function runAttachmentGc(args) {
|
|
|
69632
69726
|
if (age < ttlMs) continue;
|
|
69633
69727
|
if (liveAbs.has(file)) continue;
|
|
69634
69728
|
try {
|
|
69635
|
-
|
|
69729
|
+
import_node_fs50.default.unlinkSync(file);
|
|
69636
69730
|
} catch (err) {
|
|
69637
69731
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
69638
69732
|
}
|
|
69639
69733
|
}
|
|
69640
69734
|
try {
|
|
69641
|
-
if (
|
|
69735
|
+
if (import_node_fs50.default.readdirSync(hashDirAbs).length === 0) import_node_fs50.default.rmdirSync(hashDirAbs);
|
|
69642
69736
|
} catch {
|
|
69643
69737
|
}
|
|
69644
69738
|
}
|
|
69645
69739
|
try {
|
|
69646
|
-
if (
|
|
69740
|
+
if (import_node_fs50.default.readdirSync(attRoot).length === 0) import_node_fs50.default.rmdirSync(attRoot);
|
|
69647
69741
|
} catch {
|
|
69648
69742
|
}
|
|
69649
69743
|
}
|
|
@@ -69651,8 +69745,8 @@ function runAttachmentGc(args) {
|
|
|
69651
69745
|
}
|
|
69652
69746
|
|
|
69653
69747
|
// src/attachment/group.ts
|
|
69654
|
-
var
|
|
69655
|
-
var
|
|
69748
|
+
var import_node_fs51 = __toESM(require("fs"), 1);
|
|
69749
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
69656
69750
|
var import_node_crypto20 = __toESM(require("crypto"), 1);
|
|
69657
69751
|
init_protocol();
|
|
69658
69752
|
var GroupFileStore = class {
|
|
@@ -69664,10 +69758,10 @@ var GroupFileStore = class {
|
|
|
69664
69758
|
this.logger = opts.logger;
|
|
69665
69759
|
}
|
|
69666
69760
|
rootForScope(scope) {
|
|
69667
|
-
return
|
|
69761
|
+
return import_node_path56.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
69668
69762
|
}
|
|
69669
69763
|
filePath(scope, sessionId) {
|
|
69670
|
-
return
|
|
69764
|
+
return import_node_path56.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
69671
69765
|
}
|
|
69672
69766
|
cacheKey(scope, sessionId) {
|
|
69673
69767
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -69675,7 +69769,7 @@ var GroupFileStore = class {
|
|
|
69675
69769
|
readFile(scope, sessionId) {
|
|
69676
69770
|
const file = this.filePath(scope, sessionId);
|
|
69677
69771
|
try {
|
|
69678
|
-
const raw =
|
|
69772
|
+
const raw = import_node_fs51.default.readFileSync(file, "utf8");
|
|
69679
69773
|
const parsed = JSON.parse(raw);
|
|
69680
69774
|
if (!Array.isArray(parsed)) {
|
|
69681
69775
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -69701,10 +69795,10 @@ var GroupFileStore = class {
|
|
|
69701
69795
|
}
|
|
69702
69796
|
writeFile(scope, sessionId, entries) {
|
|
69703
69797
|
const file = this.filePath(scope, sessionId);
|
|
69704
|
-
|
|
69798
|
+
import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(file), { recursive: true });
|
|
69705
69799
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
69706
|
-
|
|
69707
|
-
|
|
69800
|
+
import_node_fs51.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
69801
|
+
import_node_fs51.default.renameSync(tmp, file);
|
|
69708
69802
|
}
|
|
69709
69803
|
list(scope, sessionId) {
|
|
69710
69804
|
const key = this.cacheKey(scope, sessionId);
|
|
@@ -69768,7 +69862,7 @@ var GroupFileStore = class {
|
|
|
69768
69862
|
/** Delete the separate manifest and cache; deleting a persona session file does not remove this store. */
|
|
69769
69863
|
deleteSession(scope, sessionId) {
|
|
69770
69864
|
try {
|
|
69771
|
-
|
|
69865
|
+
import_node_fs51.default.unlinkSync(this.filePath(scope, sessionId));
|
|
69772
69866
|
} catch (err) {
|
|
69773
69867
|
if (err?.code !== "ENOENT") throw err;
|
|
69774
69868
|
}
|
|
@@ -69776,7 +69870,7 @@ var GroupFileStore = class {
|
|
|
69776
69870
|
}
|
|
69777
69871
|
/** Remove all manifests and cache entries for this persona; these files live outside the persona directory. */
|
|
69778
69872
|
deletePersona(personaId2) {
|
|
69779
|
-
|
|
69873
|
+
import_node_fs51.default.rmSync(import_node_path56.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
|
|
69780
69874
|
const prefix = `persona:${personaId2}:`;
|
|
69781
69875
|
for (const key of this.cache.keys()) {
|
|
69782
69876
|
if (key.startsWith(prefix)) this.cache.delete(key);
|
|
@@ -69785,10 +69879,10 @@ var GroupFileStore = class {
|
|
|
69785
69879
|
};
|
|
69786
69880
|
|
|
69787
69881
|
// src/discovery/state-file.ts
|
|
69788
|
-
var
|
|
69789
|
-
var
|
|
69882
|
+
var import_node_fs52 = __toESM(require("fs"), 1);
|
|
69883
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
69790
69884
|
function defaultStateFilePath(dataDir) {
|
|
69791
|
-
return
|
|
69885
|
+
return import_node_path57.default.join(dataDir, "state.json");
|
|
69792
69886
|
}
|
|
69793
69887
|
function isPidAlive(pid) {
|
|
69794
69888
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -69810,7 +69904,7 @@ var StateFileManager = class {
|
|
|
69810
69904
|
}
|
|
69811
69905
|
read() {
|
|
69812
69906
|
try {
|
|
69813
|
-
const raw =
|
|
69907
|
+
const raw = import_node_fs52.default.readFileSync(this.file, "utf8");
|
|
69814
69908
|
const parsed = JSON.parse(raw);
|
|
69815
69909
|
return parsed;
|
|
69816
69910
|
} catch {
|
|
@@ -69824,20 +69918,20 @@ var StateFileManager = class {
|
|
|
69824
69918
|
return { status: "stale", existing };
|
|
69825
69919
|
}
|
|
69826
69920
|
write(state) {
|
|
69827
|
-
|
|
69921
|
+
import_node_fs52.default.mkdirSync(import_node_path57.default.dirname(this.file), { recursive: true });
|
|
69828
69922
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
69829
|
-
|
|
69830
|
-
|
|
69923
|
+
import_node_fs52.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
69924
|
+
import_node_fs52.default.renameSync(tmp, this.file);
|
|
69831
69925
|
if (process.platform !== "win32") {
|
|
69832
69926
|
try {
|
|
69833
|
-
|
|
69927
|
+
import_node_fs52.default.chmodSync(this.file, 384);
|
|
69834
69928
|
} catch {
|
|
69835
69929
|
}
|
|
69836
69930
|
}
|
|
69837
69931
|
}
|
|
69838
69932
|
delete() {
|
|
69839
69933
|
try {
|
|
69840
|
-
|
|
69934
|
+
import_node_fs52.default.unlinkSync(this.file);
|
|
69841
69935
|
} catch {
|
|
69842
69936
|
}
|
|
69843
69937
|
}
|
|
@@ -69851,14 +69945,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
69851
69945
|
}
|
|
69852
69946
|
|
|
69853
69947
|
// src/tunnel/tunnel-manager.ts
|
|
69854
|
-
var
|
|
69855
|
-
var
|
|
69948
|
+
var import_node_fs56 = __toESM(require("fs"), 1);
|
|
69949
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
69856
69950
|
var import_node_crypto21 = __toESM(require("crypto"), 1);
|
|
69857
69951
|
var import_node_child_process17 = require("child_process");
|
|
69858
69952
|
|
|
69859
69953
|
// src/tunnel/tunnel-store.ts
|
|
69860
|
-
var
|
|
69861
|
-
var
|
|
69954
|
+
var import_node_fs53 = __toESM(require("fs"), 1);
|
|
69955
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
69862
69956
|
var TunnelStore = class {
|
|
69863
69957
|
constructor(filePath) {
|
|
69864
69958
|
this.filePath = filePath;
|
|
@@ -69866,7 +69960,7 @@ var TunnelStore = class {
|
|
|
69866
69960
|
filePath;
|
|
69867
69961
|
async get() {
|
|
69868
69962
|
try {
|
|
69869
|
-
const raw = await
|
|
69963
|
+
const raw = await import_node_fs53.default.promises.readFile(this.filePath, "utf8");
|
|
69870
69964
|
const obj = JSON.parse(raw);
|
|
69871
69965
|
if (!isPersistedTunnel(obj)) return null;
|
|
69872
69966
|
return obj;
|
|
@@ -69877,22 +69971,22 @@ var TunnelStore = class {
|
|
|
69877
69971
|
}
|
|
69878
69972
|
}
|
|
69879
69973
|
async set(v3) {
|
|
69880
|
-
const dir =
|
|
69881
|
-
await
|
|
69974
|
+
const dir = import_node_path58.default.dirname(this.filePath);
|
|
69975
|
+
await import_node_fs53.default.promises.mkdir(dir, { recursive: true });
|
|
69882
69976
|
const data = JSON.stringify(v3, null, 2);
|
|
69883
69977
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
69884
|
-
await
|
|
69978
|
+
await import_node_fs53.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
69885
69979
|
if (process.platform !== "win32") {
|
|
69886
69980
|
try {
|
|
69887
|
-
await
|
|
69981
|
+
await import_node_fs53.default.promises.chmod(tmp, 384);
|
|
69888
69982
|
} catch {
|
|
69889
69983
|
}
|
|
69890
69984
|
}
|
|
69891
|
-
await
|
|
69985
|
+
await import_node_fs53.default.promises.rename(tmp, this.filePath);
|
|
69892
69986
|
}
|
|
69893
69987
|
async clear() {
|
|
69894
69988
|
try {
|
|
69895
|
-
await
|
|
69989
|
+
await import_node_fs53.default.promises.unlink(this.filePath);
|
|
69896
69990
|
} catch (err) {
|
|
69897
69991
|
const code = err?.code;
|
|
69898
69992
|
if (code !== "ENOENT") throw err;
|
|
@@ -69987,9 +70081,9 @@ function escape2(v3) {
|
|
|
69987
70081
|
}
|
|
69988
70082
|
|
|
69989
70083
|
// src/tunnel/frpc-binary.ts
|
|
69990
|
-
var
|
|
70084
|
+
var import_node_fs54 = __toESM(require("fs"), 1);
|
|
69991
70085
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
69992
|
-
var
|
|
70086
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
69993
70087
|
var import_node_child_process15 = require("child_process");
|
|
69994
70088
|
var import_node_stream4 = require("stream");
|
|
69995
70089
|
var import_promises10 = require("stream/promises");
|
|
@@ -70021,20 +70115,20 @@ function frpcDownloadUrl(version2, p3) {
|
|
|
70021
70115
|
}
|
|
70022
70116
|
async function ensureFrpcBinary(opts) {
|
|
70023
70117
|
if (opts.override) {
|
|
70024
|
-
if (!
|
|
70118
|
+
if (!import_node_fs54.default.existsSync(opts.override)) {
|
|
70025
70119
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
70026
70120
|
}
|
|
70027
70121
|
return opts.override;
|
|
70028
70122
|
}
|
|
70029
70123
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
70030
70124
|
const platform = opts.platform ?? detectPlatform();
|
|
70031
|
-
const binDir =
|
|
70032
|
-
|
|
70125
|
+
const binDir = import_node_path59.default.join(opts.dataDir, "bin");
|
|
70126
|
+
import_node_fs54.default.mkdirSync(binDir, { recursive: true });
|
|
70033
70127
|
cleanupStaleArtifacts(binDir);
|
|
70034
|
-
const stableBin =
|
|
70035
|
-
if (
|
|
70128
|
+
const stableBin = import_node_path59.default.join(binDir, "frpc");
|
|
70129
|
+
if (import_node_fs54.default.existsSync(stableBin)) return stableBin;
|
|
70036
70130
|
const partialBin = `${stableBin}.partial`;
|
|
70037
|
-
const tarballPath =
|
|
70131
|
+
const tarballPath = import_node_path59.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
70038
70132
|
try {
|
|
70039
70133
|
const url = frpcDownloadUrl(version2, platform);
|
|
70040
70134
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -70043,8 +70137,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
70043
70137
|
} else {
|
|
70044
70138
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
70045
70139
|
}
|
|
70046
|
-
|
|
70047
|
-
|
|
70140
|
+
import_node_fs54.default.chmodSync(partialBin, 493);
|
|
70141
|
+
import_node_fs54.default.renameSync(partialBin, stableBin);
|
|
70048
70142
|
} finally {
|
|
70049
70143
|
safeUnlink(tarballPath);
|
|
70050
70144
|
safeUnlink(partialBin);
|
|
@@ -70054,15 +70148,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
70054
70148
|
function cleanupStaleArtifacts(binDir) {
|
|
70055
70149
|
let entries;
|
|
70056
70150
|
try {
|
|
70057
|
-
entries =
|
|
70151
|
+
entries = import_node_fs54.default.readdirSync(binDir);
|
|
70058
70152
|
} catch {
|
|
70059
70153
|
return;
|
|
70060
70154
|
}
|
|
70061
70155
|
for (const name of entries) {
|
|
70062
70156
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
70063
|
-
const full =
|
|
70157
|
+
const full = import_node_path59.default.join(binDir, name);
|
|
70064
70158
|
try {
|
|
70065
|
-
|
|
70159
|
+
import_node_fs54.default.rmSync(full, { recursive: true, force: true });
|
|
70066
70160
|
} catch {
|
|
70067
70161
|
}
|
|
70068
70162
|
}
|
|
@@ -70070,7 +70164,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
70070
70164
|
}
|
|
70071
70165
|
function safeUnlink(p3) {
|
|
70072
70166
|
try {
|
|
70073
|
-
|
|
70167
|
+
import_node_fs54.default.unlinkSync(p3);
|
|
70074
70168
|
} catch {
|
|
70075
70169
|
}
|
|
70076
70170
|
}
|
|
@@ -70081,13 +70175,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
70081
70175
|
if (!res.ok || !res.body) {
|
|
70082
70176
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
70083
70177
|
}
|
|
70084
|
-
const out =
|
|
70178
|
+
const out = import_node_fs54.default.createWriteStream(dest);
|
|
70085
70179
|
const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
|
|
70086
70180
|
await (0, import_promises10.pipeline)(nodeStream, out);
|
|
70087
70181
|
}
|
|
70088
70182
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
70089
|
-
const work =
|
|
70090
|
-
|
|
70183
|
+
const work = import_node_path59.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
70184
|
+
import_node_fs54.default.mkdirSync(work, { recursive: true });
|
|
70091
70185
|
try {
|
|
70092
70186
|
await new Promise((resolve9, reject) => {
|
|
70093
70187
|
const proc = (0, import_node_child_process15.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -70095,32 +70189,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
70095
70189
|
proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
|
|
70096
70190
|
});
|
|
70097
70191
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
70098
|
-
const src =
|
|
70099
|
-
if (!
|
|
70192
|
+
const src = import_node_path59.default.join(work, dirName, "frpc");
|
|
70193
|
+
if (!import_node_fs54.default.existsSync(src)) {
|
|
70100
70194
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
70101
70195
|
}
|
|
70102
|
-
|
|
70196
|
+
import_node_fs54.default.copyFileSync(src, destBin);
|
|
70103
70197
|
} finally {
|
|
70104
|
-
|
|
70198
|
+
import_node_fs54.default.rmSync(work, { recursive: true, force: true });
|
|
70105
70199
|
}
|
|
70106
70200
|
}
|
|
70107
70201
|
|
|
70108
70202
|
// src/tunnel/frpc-process.ts
|
|
70109
|
-
var
|
|
70110
|
-
var
|
|
70203
|
+
var import_node_fs55 = __toESM(require("fs"), 1);
|
|
70204
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
70111
70205
|
var import_node_child_process16 = require("child_process");
|
|
70112
70206
|
function frpcPidFilePath(dataDir) {
|
|
70113
|
-
return
|
|
70207
|
+
return import_node_path60.default.join(dataDir, "frpc.pid");
|
|
70114
70208
|
}
|
|
70115
70209
|
function writeFrpcPid(dataDir, pid) {
|
|
70116
70210
|
try {
|
|
70117
|
-
|
|
70211
|
+
import_node_fs55.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
70118
70212
|
} catch {
|
|
70119
70213
|
}
|
|
70120
70214
|
}
|
|
70121
70215
|
function clearFrpcPid(dataDir) {
|
|
70122
70216
|
try {
|
|
70123
|
-
|
|
70217
|
+
import_node_fs55.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
70124
70218
|
} catch {
|
|
70125
70219
|
}
|
|
70126
70220
|
}
|
|
@@ -70136,7 +70230,7 @@ function defaultIsPidAlive(pid) {
|
|
|
70136
70230
|
}
|
|
70137
70231
|
function defaultReadPidFile(file) {
|
|
70138
70232
|
try {
|
|
70139
|
-
return
|
|
70233
|
+
return import_node_fs55.default.readFileSync(file, "utf8");
|
|
70140
70234
|
} catch {
|
|
70141
70235
|
return null;
|
|
70142
70236
|
}
|
|
@@ -70152,7 +70246,7 @@ function defaultSleep2(ms) {
|
|
|
70152
70246
|
}
|
|
70153
70247
|
async function killStaleFrpc(deps) {
|
|
70154
70248
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
70155
|
-
const tomlPath =
|
|
70249
|
+
const tomlPath = import_node_path60.default.join(deps.dataDir, "frpc.toml");
|
|
70156
70250
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
70157
70251
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
70158
70252
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -70176,7 +70270,7 @@ async function killStaleFrpc(deps) {
|
|
|
70176
70270
|
}
|
|
70177
70271
|
if (victims.size === 0) {
|
|
70178
70272
|
try {
|
|
70179
|
-
|
|
70273
|
+
import_node_fs55.default.unlinkSync(pidFile);
|
|
70180
70274
|
} catch {
|
|
70181
70275
|
}
|
|
70182
70276
|
return;
|
|
@@ -70187,7 +70281,7 @@ async function killStaleFrpc(deps) {
|
|
|
70187
70281
|
}
|
|
70188
70282
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
70189
70283
|
try {
|
|
70190
|
-
|
|
70284
|
+
import_node_fs55.default.unlinkSync(pidFile);
|
|
70191
70285
|
} catch {
|
|
70192
70286
|
}
|
|
70193
70287
|
}
|
|
@@ -70224,7 +70318,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
70224
70318
|
var TunnelManager = class {
|
|
70225
70319
|
constructor(deps) {
|
|
70226
70320
|
this.deps = deps;
|
|
70227
|
-
this.store = deps.store ?? new TunnelStore(
|
|
70321
|
+
this.store = deps.store ?? new TunnelStore(import_node_path61.default.join(deps.dataDir, "tunnel.json"));
|
|
70228
70322
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
70229
70323
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
70230
70324
|
}
|
|
@@ -70349,7 +70443,7 @@ var TunnelManager = class {
|
|
|
70349
70443
|
dataDir: this.deps.dataDir,
|
|
70350
70444
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
70351
70445
|
});
|
|
70352
|
-
const tomlPath =
|
|
70446
|
+
const tomlPath = import_node_path61.default.join(this.deps.dataDir, "frpc.toml");
|
|
70353
70447
|
const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto21.default.randomBytes(3).toString("hex")}`;
|
|
70354
70448
|
const toml = buildFrpcToml({
|
|
70355
70449
|
serverAddr: t2.frpsHost,
|
|
@@ -70360,14 +70454,14 @@ var TunnelManager = class {
|
|
|
70360
70454
|
localPort,
|
|
70361
70455
|
logLevel: "info"
|
|
70362
70456
|
});
|
|
70363
|
-
await
|
|
70457
|
+
await import_node_fs56.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
70364
70458
|
const proc = (this.deps.spawnImpl ?? import_node_child_process17.spawn)(frpcBin, ["-c", tomlPath], {
|
|
70365
70459
|
stdio: ["ignore", "pipe", "pipe"]
|
|
70366
70460
|
});
|
|
70367
|
-
const logDir =
|
|
70368
|
-
|
|
70369
|
-
const logFilePath =
|
|
70370
|
-
const logStream =
|
|
70461
|
+
const logDir = import_node_path61.default.join(this.deps.dataDir, "log");
|
|
70462
|
+
import_node_fs56.default.mkdirSync(logDir, { recursive: true });
|
|
70463
|
+
const logFilePath = import_node_path61.default.join(logDir, "frpc.log");
|
|
70464
|
+
const logStream = import_node_fs56.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
70371
70465
|
logStream.on("error", () => {
|
|
70372
70466
|
});
|
|
70373
70467
|
const tee = (chunk) => {
|
|
@@ -70450,27 +70544,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
70450
70544
|
|
|
70451
70545
|
// src/tunnel/device-key.ts
|
|
70452
70546
|
var import_node_os22 = __toESM(require("os"), 1);
|
|
70453
|
-
var
|
|
70547
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
70454
70548
|
var import_node_crypto22 = __toESM(require("crypto"), 1);
|
|
70455
70549
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
70456
70550
|
function deriveStableDeviceKey(opts = {}) {
|
|
70457
70551
|
const hostname = opts.hostname ?? import_node_os22.default.hostname();
|
|
70458
70552
|
const uid = opts.uid ?? (typeof import_node_os22.default.userInfo === "function" ? import_node_os22.default.userInfo().uid : 0);
|
|
70459
70553
|
const home = opts.home ?? import_node_os22.default.homedir();
|
|
70460
|
-
const defaultDataDir =
|
|
70461
|
-
const normalizedDataDir = opts.dataDir ?
|
|
70554
|
+
const defaultDataDir = import_node_path62.default.resolve(import_node_path62.default.join(home, ".clawd"));
|
|
70555
|
+
const normalizedDataDir = opts.dataDir ? import_node_path62.default.resolve(opts.dataDir) : null;
|
|
70462
70556
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
70463
70557
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
70464
70558
|
return import_node_crypto22.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
70465
70559
|
}
|
|
70466
70560
|
|
|
70467
70561
|
// src/auth-store.ts
|
|
70468
|
-
var
|
|
70469
|
-
var
|
|
70562
|
+
var import_node_fs57 = __toESM(require("fs"), 1);
|
|
70563
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
70470
70564
|
var import_node_crypto23 = __toESM(require("crypto"), 1);
|
|
70471
70565
|
var AUTH_FILE_NAME = "auth.json";
|
|
70472
70566
|
function authFilePath(dataDir) {
|
|
70473
|
-
return
|
|
70567
|
+
return import_node_path63.default.join(dataDir, AUTH_FILE_NAME);
|
|
70474
70568
|
}
|
|
70475
70569
|
function loadOrCreateAuthFile(opts) {
|
|
70476
70570
|
const file = authFilePath(opts.dataDir);
|
|
@@ -70511,7 +70605,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
70511
70605
|
}
|
|
70512
70606
|
function readAuthFile(file) {
|
|
70513
70607
|
try {
|
|
70514
|
-
const raw =
|
|
70608
|
+
const raw = import_node_fs57.default.readFileSync(file, "utf8");
|
|
70515
70609
|
const parsed = JSON.parse(raw);
|
|
70516
70610
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
70517
70611
|
return null;
|
|
@@ -70532,26 +70626,26 @@ function readAuthFile(file) {
|
|
|
70532
70626
|
}
|
|
70533
70627
|
}
|
|
70534
70628
|
function writeAuthFile(file, content) {
|
|
70535
|
-
|
|
70536
|
-
|
|
70629
|
+
import_node_fs57.default.mkdirSync(import_node_path63.default.dirname(file), { recursive: true });
|
|
70630
|
+
import_node_fs57.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
70537
70631
|
try {
|
|
70538
|
-
|
|
70632
|
+
import_node_fs57.default.chmodSync(file, 384);
|
|
70539
70633
|
} catch {
|
|
70540
70634
|
}
|
|
70541
70635
|
}
|
|
70542
70636
|
|
|
70543
70637
|
// src/owner-profile.ts
|
|
70544
|
-
var
|
|
70638
|
+
var import_node_fs58 = __toESM(require("fs"), 1);
|
|
70545
70639
|
var import_node_os23 = __toESM(require("os"), 1);
|
|
70546
|
-
var
|
|
70640
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
70547
70641
|
var PROFILE_FILENAME = "profile.json";
|
|
70548
70642
|
function profilePath(dataDir) {
|
|
70549
|
-
return
|
|
70643
|
+
return import_node_path64.default.join(dataDir, PROFILE_FILENAME);
|
|
70550
70644
|
}
|
|
70551
70645
|
function loadOwnerProfile(dataDir) {
|
|
70552
70646
|
let raw;
|
|
70553
70647
|
try {
|
|
70554
|
-
raw =
|
|
70648
|
+
raw = import_node_fs58.default.readFileSync(profilePath(dataDir), "utf8");
|
|
70555
70649
|
} catch {
|
|
70556
70650
|
return {};
|
|
70557
70651
|
}
|
|
@@ -70567,7 +70661,7 @@ function loadOwnerProfile(dataDir) {
|
|
|
70567
70661
|
}
|
|
70568
70662
|
function patchOwnerProfile(dataDir, patch) {
|
|
70569
70663
|
const merged = { ...loadOwnerProfile(dataDir), ...patch };
|
|
70570
|
-
|
|
70664
|
+
import_node_fs58.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
|
|
70571
70665
|
return merged;
|
|
70572
70666
|
}
|
|
70573
70667
|
function loadOwnerDisplayName(dataDir) {
|
|
@@ -70583,18 +70677,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
70583
70677
|
}
|
|
70584
70678
|
|
|
70585
70679
|
// src/feishu-auth/owner-identity-store.ts
|
|
70586
|
-
var
|
|
70587
|
-
var
|
|
70680
|
+
var import_node_fs59 = __toESM(require("fs"), 1);
|
|
70681
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
70588
70682
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
70589
70683
|
var OwnerIdentityStore = class {
|
|
70590
70684
|
file;
|
|
70591
70685
|
constructor(dataDir, environment = "production") {
|
|
70592
|
-
this.file =
|
|
70686
|
+
this.file = import_node_path65.default.join(dataDir, environment === "production" ? OWNER_IDENTITY_FILE_NAME : "owner-identity.integration.json");
|
|
70593
70687
|
}
|
|
70594
70688
|
read() {
|
|
70595
70689
|
let raw;
|
|
70596
70690
|
try {
|
|
70597
|
-
raw =
|
|
70691
|
+
raw = import_node_fs59.default.readFileSync(this.file, "utf8");
|
|
70598
70692
|
} catch {
|
|
70599
70693
|
return null;
|
|
70600
70694
|
}
|
|
@@ -70621,16 +70715,16 @@ var OwnerIdentityStore = class {
|
|
|
70621
70715
|
};
|
|
70622
70716
|
}
|
|
70623
70717
|
write(record4) {
|
|
70624
|
-
|
|
70625
|
-
|
|
70718
|
+
import_node_fs59.default.mkdirSync(import_node_path65.default.dirname(this.file), { recursive: true });
|
|
70719
|
+
import_node_fs59.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
|
|
70626
70720
|
try {
|
|
70627
|
-
|
|
70721
|
+
import_node_fs59.default.chmodSync(this.file, 384);
|
|
70628
70722
|
} catch {
|
|
70629
70723
|
}
|
|
70630
70724
|
}
|
|
70631
70725
|
clear() {
|
|
70632
70726
|
try {
|
|
70633
|
-
|
|
70727
|
+
import_node_fs59.default.unlinkSync(this.file);
|
|
70634
70728
|
} catch (err) {
|
|
70635
70729
|
const code = err?.code;
|
|
70636
70730
|
if (code !== "ENOENT") throw err;
|
|
@@ -71130,8 +71224,8 @@ function verifyConnectToken(args) {
|
|
|
71130
71224
|
}
|
|
71131
71225
|
|
|
71132
71226
|
// src/feishu-auth/server-key.ts
|
|
71133
|
-
var
|
|
71134
|
-
var
|
|
71227
|
+
var fs76 = __toESM(require("fs"), 1);
|
|
71228
|
+
var path78 = __toESM(require("path"), 1);
|
|
71135
71229
|
var FILE_NAME2 = "server-signing-key.json";
|
|
71136
71230
|
var ServerKeyStore = class {
|
|
71137
71231
|
constructor(dataDir) {
|
|
@@ -71139,12 +71233,12 @@ var ServerKeyStore = class {
|
|
|
71139
71233
|
}
|
|
71140
71234
|
dataDir;
|
|
71141
71235
|
filePath() {
|
|
71142
|
-
return
|
|
71236
|
+
return path78.join(this.dataDir, FILE_NAME2);
|
|
71143
71237
|
}
|
|
71144
71238
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
71145
71239
|
read() {
|
|
71146
71240
|
try {
|
|
71147
|
-
const raw =
|
|
71241
|
+
const raw = fs76.readFileSync(this.filePath(), "utf8");
|
|
71148
71242
|
const parsed = JSON.parse(raw);
|
|
71149
71243
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
71150
71244
|
return parsed.publicKeyPem;
|
|
@@ -71159,12 +71253,12 @@ var ServerKeyStore = class {
|
|
|
71159
71253
|
publicKeyPem,
|
|
71160
71254
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
71161
71255
|
};
|
|
71162
|
-
|
|
71163
|
-
|
|
71256
|
+
fs76.mkdirSync(this.dataDir, { recursive: true });
|
|
71257
|
+
fs76.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
71164
71258
|
}
|
|
71165
71259
|
clear() {
|
|
71166
71260
|
try {
|
|
71167
|
-
|
|
71261
|
+
fs76.unlinkSync(this.filePath());
|
|
71168
71262
|
} catch {
|
|
71169
71263
|
}
|
|
71170
71264
|
}
|
|
@@ -71174,19 +71268,19 @@ var ServerKeyStore = class {
|
|
|
71174
71268
|
init_protocol();
|
|
71175
71269
|
|
|
71176
71270
|
// src/handlers/index.ts
|
|
71177
|
-
var
|
|
71271
|
+
var import_node_path82 = __toESM(require("path"), 1);
|
|
71178
71272
|
|
|
71179
71273
|
// src/handlers/session.ts
|
|
71180
71274
|
init_protocol();
|
|
71181
71275
|
|
|
71182
71276
|
// src/session/fork.ts
|
|
71183
|
-
var
|
|
71277
|
+
var import_node_fs60 = __toESM(require("fs"), 1);
|
|
71184
71278
|
var import_node_os24 = __toESM(require("os"), 1);
|
|
71185
|
-
var
|
|
71279
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
71186
71280
|
var import_node_crypto25 = require("crypto");
|
|
71187
71281
|
init_claude_history();
|
|
71188
71282
|
function readJsonlEntries(file) {
|
|
71189
|
-
const raw =
|
|
71283
|
+
const raw = import_node_fs60.default.readFileSync(file, "utf8");
|
|
71190
71284
|
const out = [];
|
|
71191
71285
|
for (const line of raw.split("\n")) {
|
|
71192
71286
|
const t2 = line.trim();
|
|
@@ -71199,19 +71293,19 @@ function readJsonlEntries(file) {
|
|
|
71199
71293
|
return out;
|
|
71200
71294
|
}
|
|
71201
71295
|
function forkSession(input) {
|
|
71202
|
-
const baseDir = input.baseDir ??
|
|
71203
|
-
let projectDir =
|
|
71204
|
-
let sourceFile =
|
|
71205
|
-
if (!
|
|
71296
|
+
const baseDir = input.baseDir ?? import_node_path66.default.join(import_node_os24.default.homedir(), ".claude");
|
|
71297
|
+
let projectDir = import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
71298
|
+
let sourceFile = import_node_path66.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
71299
|
+
if (!import_node_fs60.default.existsSync(sourceFile)) {
|
|
71206
71300
|
const found = findTranscriptByToolSessionId(
|
|
71207
|
-
|
|
71301
|
+
import_node_path66.default.join(baseDir, "projects"),
|
|
71208
71302
|
input.toolSessionId
|
|
71209
71303
|
);
|
|
71210
71304
|
if (!found) {
|
|
71211
71305
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
71212
71306
|
}
|
|
71213
71307
|
sourceFile = found;
|
|
71214
|
-
projectDir =
|
|
71308
|
+
projectDir = import_node_path66.default.dirname(found);
|
|
71215
71309
|
}
|
|
71216
71310
|
const entries = readJsonlEntries(sourceFile);
|
|
71217
71311
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -71240,17 +71334,17 @@ function forkSession(input) {
|
|
|
71240
71334
|
}
|
|
71241
71335
|
forkedLines.push(JSON.stringify(forked));
|
|
71242
71336
|
}
|
|
71243
|
-
const outDir = input.targetCwd ?
|
|
71244
|
-
const forkedFilePath =
|
|
71245
|
-
|
|
71246
|
-
|
|
71337
|
+
const outDir = input.targetCwd ? import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
71338
|
+
const forkedFilePath = import_node_path66.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
71339
|
+
import_node_fs60.default.mkdirSync(outDir, { recursive: true });
|
|
71340
|
+
import_node_fs60.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
71247
71341
|
return { forkedToolSessionId, forkedFilePath };
|
|
71248
71342
|
}
|
|
71249
71343
|
|
|
71250
71344
|
// src/tools/codex-fork.ts
|
|
71251
71345
|
var import_node_child_process18 = require("child_process");
|
|
71252
|
-
var
|
|
71253
|
-
var
|
|
71346
|
+
var import_node_fs61 = __toESM(require("fs"), 1);
|
|
71347
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
71254
71348
|
function openCodexAppServer(home, cwd) {
|
|
71255
71349
|
const proc = (0, import_node_child_process18.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
|
|
71256
71350
|
cwd,
|
|
@@ -71270,7 +71364,7 @@ function openCodexAppServer(home, cwd) {
|
|
|
71270
71364
|
async function forkCodexThread(input, deps = {}) {
|
|
71271
71365
|
const source = locateCodexThread(input.roots, input.sourceThreadId);
|
|
71272
71366
|
if (!source) throw new Error(`codex fork: source thread not found: ${input.sourceThreadId}`);
|
|
71273
|
-
const rollout = parseCodexRollout(
|
|
71367
|
+
const rollout = parseCodexRollout(import_node_fs61.default.readFileSync(source.file, "utf8"));
|
|
71274
71368
|
if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
|
|
71275
71369
|
throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
|
|
71276
71370
|
}
|
|
@@ -71305,7 +71399,7 @@ async function forkCodexThread(input, deps = {}) {
|
|
|
71305
71399
|
if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
|
|
71306
71400
|
throw new Error("codex fork: app-server returned no thread id");
|
|
71307
71401
|
}
|
|
71308
|
-
const forked = locateCodexThread([
|
|
71402
|
+
const forked = locateCodexThread([import_node_path67.default.join(owner2.home, "sessions")], forkedToolSessionId);
|
|
71309
71403
|
if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
|
|
71310
71404
|
return { forkedToolSessionId, forkedFilePath: forked.file };
|
|
71311
71405
|
})()]);
|
|
@@ -71316,19 +71410,19 @@ async function forkCodexThread(input, deps = {}) {
|
|
|
71316
71410
|
}
|
|
71317
71411
|
|
|
71318
71412
|
// src/session/external-scan.ts
|
|
71319
|
-
var
|
|
71413
|
+
var import_node_fs62 = __toESM(require("fs"), 1);
|
|
71320
71414
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
71321
71415
|
var import_node_os25 = __toESM(require("os"), 1);
|
|
71322
|
-
var
|
|
71416
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
71323
71417
|
var import_node_module = require("module");
|
|
71324
71418
|
var import_node_child_process19 = require("child_process");
|
|
71325
71419
|
var import_meta7 = {};
|
|
71326
71420
|
function defaultRoots() {
|
|
71327
71421
|
const home = import_node_os25.default.homedir();
|
|
71328
71422
|
return {
|
|
71329
|
-
claudeProjectsDir:
|
|
71330
|
-
codexDir:
|
|
71331
|
-
clawdDir:
|
|
71423
|
+
claudeProjectsDir: import_node_path68.default.join(home, ".claude", "projects"),
|
|
71424
|
+
codexDir: import_node_path68.default.join(home, ".codex"),
|
|
71425
|
+
clawdDir: import_node_path68.default.join(home, ".clawd")
|
|
71332
71426
|
};
|
|
71333
71427
|
}
|
|
71334
71428
|
function width(s2) {
|
|
@@ -71379,7 +71473,7 @@ function userText(msg) {
|
|
|
71379
71473
|
}
|
|
71380
71474
|
function isDir2(p3) {
|
|
71381
71475
|
try {
|
|
71382
|
-
return
|
|
71476
|
+
return import_node_fs62.default.statSync(p3).isDirectory();
|
|
71383
71477
|
} catch {
|
|
71384
71478
|
return false;
|
|
71385
71479
|
}
|
|
@@ -71388,7 +71482,7 @@ async function scanClaude(roots) {
|
|
|
71388
71482
|
const out = [];
|
|
71389
71483
|
let dirs;
|
|
71390
71484
|
try {
|
|
71391
|
-
dirs =
|
|
71485
|
+
dirs = import_node_fs62.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
|
|
71392
71486
|
} catch {
|
|
71393
71487
|
return out;
|
|
71394
71488
|
}
|
|
@@ -71396,16 +71490,16 @@ async function scanClaude(roots) {
|
|
|
71396
71490
|
if (!d2.isDirectory()) continue;
|
|
71397
71491
|
let files;
|
|
71398
71492
|
try {
|
|
71399
|
-
files =
|
|
71493
|
+
files = import_node_fs62.default.readdirSync(import_node_path68.default.join(roots.claudeProjectsDir, d2.name));
|
|
71400
71494
|
} catch {
|
|
71401
71495
|
continue;
|
|
71402
71496
|
}
|
|
71403
71497
|
for (const name of files) {
|
|
71404
71498
|
if (!name.endsWith(".jsonl")) continue;
|
|
71405
|
-
const file =
|
|
71499
|
+
const file = import_node_path68.default.join(roots.claudeProjectsDir, d2.name, name);
|
|
71406
71500
|
let st2;
|
|
71407
71501
|
try {
|
|
71408
|
-
st2 =
|
|
71502
|
+
st2 = import_node_fs62.default.statSync(file);
|
|
71409
71503
|
} catch {
|
|
71410
71504
|
continue;
|
|
71411
71505
|
}
|
|
@@ -71458,7 +71552,7 @@ async function scanClaude(roots) {
|
|
|
71458
71552
|
return out;
|
|
71459
71553
|
}
|
|
71460
71554
|
async function countCodexTurns(rolloutPath) {
|
|
71461
|
-
if (!rolloutPath || !
|
|
71555
|
+
if (!rolloutPath || !import_node_fs62.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
|
|
71462
71556
|
let turns = 0;
|
|
71463
71557
|
let first = "";
|
|
71464
71558
|
for await (const rec6 of jsonLines(rolloutPath)) {
|
|
@@ -71532,7 +71626,7 @@ async function codexFromRows(rows) {
|
|
|
71532
71626
|
async function scanCodex(roots) {
|
|
71533
71627
|
let dbs = [];
|
|
71534
71628
|
try {
|
|
71535
|
-
dbs =
|
|
71629
|
+
dbs = import_node_fs62.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path68.default.join(roots.codexDir, n2));
|
|
71536
71630
|
} catch {
|
|
71537
71631
|
}
|
|
71538
71632
|
if (!dbs.length) return [];
|
|
@@ -71541,14 +71635,14 @@ async function scanCodex(roots) {
|
|
|
71541
71635
|
}
|
|
71542
71636
|
async function scanExternalSessions(rootsIn) {
|
|
71543
71637
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
71544
|
-
const personaRoot =
|
|
71638
|
+
const personaRoot = import_node_path68.default.join(roots.clawdDir, "personas");
|
|
71545
71639
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
71546
71640
|
const out = [];
|
|
71547
71641
|
for (const c2 of all) {
|
|
71548
71642
|
if (c2.skip) continue;
|
|
71549
71643
|
if (c2.turns < 1) continue;
|
|
71550
71644
|
if (!c2.cwd || !isDir2(c2.cwd)) continue;
|
|
71551
|
-
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot +
|
|
71645
|
+
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path68.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path68.default.sep)) {
|
|
71552
71646
|
continue;
|
|
71553
71647
|
}
|
|
71554
71648
|
out.push({
|
|
@@ -71565,13 +71659,13 @@ async function scanExternalSessions(rootsIn) {
|
|
|
71565
71659
|
}
|
|
71566
71660
|
|
|
71567
71661
|
// src/session/import-ledger.ts
|
|
71568
|
-
var
|
|
71569
|
-
var
|
|
71662
|
+
var import_node_fs63 = __toESM(require("fs"), 1);
|
|
71663
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
71570
71664
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
71571
71665
|
function readImportLedger(dataDir) {
|
|
71572
71666
|
try {
|
|
71573
71667
|
const parsed = JSON.parse(
|
|
71574
|
-
|
|
71668
|
+
import_node_fs63.default.readFileSync(import_node_path69.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
71575
71669
|
);
|
|
71576
71670
|
return Array.isArray(parsed) ? parsed : [];
|
|
71577
71671
|
} catch {
|
|
@@ -71579,15 +71673,15 @@ function readImportLedger(dataDir) {
|
|
|
71579
71673
|
}
|
|
71580
71674
|
}
|
|
71581
71675
|
function appendImportLedger(dataDir, entry) {
|
|
71582
|
-
const file =
|
|
71676
|
+
const file = import_node_path69.default.join(dataDir, LEDGER_FILENAME);
|
|
71583
71677
|
const entries = readImportLedger(dataDir);
|
|
71584
71678
|
entries.push(entry);
|
|
71585
|
-
|
|
71679
|
+
import_node_fs63.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
71586
71680
|
}
|
|
71587
71681
|
|
|
71588
71682
|
// src/handlers/session.ts
|
|
71589
71683
|
init_protocol();
|
|
71590
|
-
var
|
|
71684
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
71591
71685
|
function canReadSearchHit(ctx, file) {
|
|
71592
71686
|
if (!ctx || ctx.principal.kind === "owner") return true;
|
|
71593
71687
|
return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
|
|
@@ -71868,7 +71962,7 @@ ${attribution}` } : args;
|
|
|
71868
71962
|
`principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
|
|
71869
71963
|
);
|
|
71870
71964
|
}
|
|
71871
|
-
if (source?.tool === "codex" && args.targetCwd &&
|
|
71965
|
+
if (source?.tool === "codex" && args.targetCwd && import_node_path70.default.resolve(args.targetCwd) !== import_node_path70.default.resolve(source.cwd)) {
|
|
71872
71966
|
throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
|
|
71873
71967
|
}
|
|
71874
71968
|
}
|
|
@@ -72145,7 +72239,7 @@ function buildPermissionHandlers(deps) {
|
|
|
72145
72239
|
}
|
|
72146
72240
|
|
|
72147
72241
|
// src/handlers/history.ts
|
|
72148
|
-
var
|
|
72242
|
+
var path85 = __toESM(require("path"), 1);
|
|
72149
72243
|
init_protocol();
|
|
72150
72244
|
|
|
72151
72245
|
// src/session/recent-dirs.ts
|
|
@@ -72163,7 +72257,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
72163
72257
|
}
|
|
72164
72258
|
|
|
72165
72259
|
// src/permission/persona-paths.ts
|
|
72166
|
-
var
|
|
72260
|
+
var path84 = __toESM(require("path"), 1);
|
|
72167
72261
|
function getAllowedPersonaIds(grants, action) {
|
|
72168
72262
|
const ids = /* @__PURE__ */ new Set();
|
|
72169
72263
|
for (const g3 of grants) {
|
|
@@ -72176,42 +72270,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
72176
72270
|
return ids;
|
|
72177
72271
|
}
|
|
72178
72272
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
72179
|
-
const target =
|
|
72273
|
+
const target = path84.resolve(absPath);
|
|
72180
72274
|
if (userWorkDir) {
|
|
72181
|
-
const u2 =
|
|
72182
|
-
const usep = u2.endsWith(
|
|
72275
|
+
const u2 = path84.resolve(userWorkDir);
|
|
72276
|
+
const usep = u2.endsWith(path84.sep) ? "" : path84.sep;
|
|
72183
72277
|
if (target === u2 || target.startsWith(u2 + usep)) return true;
|
|
72184
72278
|
}
|
|
72185
|
-
const root =
|
|
72186
|
-
const sep4 = root.endsWith(
|
|
72279
|
+
const root = path84.resolve(personaRoot);
|
|
72280
|
+
const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
|
|
72187
72281
|
if (!target.startsWith(root + sep4)) return false;
|
|
72188
|
-
const rel =
|
|
72282
|
+
const rel = path84.relative(root, target);
|
|
72189
72283
|
if (!rel || rel.startsWith("..")) return false;
|
|
72190
|
-
const personaId2 = rel.split(
|
|
72284
|
+
const personaId2 = rel.split(path84.sep)[0];
|
|
72191
72285
|
if (!personaId2) return false;
|
|
72192
72286
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
72193
72287
|
if (allowed === "*") return true;
|
|
72194
72288
|
return allowed.has(personaId2);
|
|
72195
72289
|
}
|
|
72196
72290
|
function personaIdFromPath(absPath, personaRoot) {
|
|
72197
|
-
const root =
|
|
72198
|
-
const target =
|
|
72199
|
-
const sep4 = root.endsWith(
|
|
72291
|
+
const root = path84.resolve(personaRoot);
|
|
72292
|
+
const target = path84.resolve(absPath);
|
|
72293
|
+
const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
|
|
72200
72294
|
if (!target.startsWith(root + sep4)) return null;
|
|
72201
|
-
const rel =
|
|
72295
|
+
const rel = path84.relative(root, target);
|
|
72202
72296
|
if (!rel || rel.startsWith("..")) return null;
|
|
72203
|
-
const id = rel.split(
|
|
72297
|
+
const id = rel.split(path84.sep)[0];
|
|
72204
72298
|
return id || null;
|
|
72205
72299
|
}
|
|
72206
72300
|
function isPathWithin(dir, absPath) {
|
|
72207
|
-
const d2 =
|
|
72208
|
-
const t2 =
|
|
72209
|
-
const sep4 = d2.endsWith(
|
|
72301
|
+
const d2 = path84.resolve(dir);
|
|
72302
|
+
const t2 = path84.resolve(absPath);
|
|
72303
|
+
const sep4 = d2.endsWith(path84.sep) ? "" : path84.sep;
|
|
72210
72304
|
return t2 === d2 || t2.startsWith(d2 + sep4);
|
|
72211
72305
|
}
|
|
72212
72306
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
72213
72307
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
72214
|
-
return personaIdFromPath(
|
|
72308
|
+
return personaIdFromPath(path84.resolve(absPath), personaRoot) === personaId2;
|
|
72215
72309
|
}
|
|
72216
72310
|
|
|
72217
72311
|
// src/handlers/history.ts
|
|
@@ -72265,7 +72359,7 @@ function buildHistoryHandlers(deps) {
|
|
|
72265
72359
|
if (!pid) return false;
|
|
72266
72360
|
return isGuestPathAllowed(
|
|
72267
72361
|
ctx.grants,
|
|
72268
|
-
|
|
72362
|
+
path85.join(personaRoot, pid),
|
|
72269
72363
|
personaRoot,
|
|
72270
72364
|
"read",
|
|
72271
72365
|
userWorkDir
|
|
@@ -72277,7 +72371,7 @@ function buildHistoryHandlers(deps) {
|
|
|
72277
72371
|
};
|
|
72278
72372
|
const list = async (frame, _client, ctx) => {
|
|
72279
72373
|
const args = HistoryListArgs.parse(frame);
|
|
72280
|
-
assertGuestPath(ctx,
|
|
72374
|
+
assertGuestPath(ctx, path85.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
72281
72375
|
const sessions = await history.listSessions(args);
|
|
72282
72376
|
return { response: { type: "history:list", sessions } };
|
|
72283
72377
|
};
|
|
@@ -72369,14 +72463,14 @@ function buildHistoryHandlers(deps) {
|
|
|
72369
72463
|
};
|
|
72370
72464
|
const subagents = async (frame, _client, ctx) => {
|
|
72371
72465
|
const args = HistorySubagentsArgs.parse(frame);
|
|
72372
|
-
assertGuestPath(ctx,
|
|
72466
|
+
assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
72373
72467
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
72374
72468
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
72375
72469
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
72376
72470
|
};
|
|
72377
72471
|
const subagentRead = async (frame, _client, ctx) => {
|
|
72378
72472
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
72379
|
-
assertGuestPath(ctx,
|
|
72473
|
+
assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
72380
72474
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
72381
72475
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
72382
72476
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -72386,7 +72480,7 @@ function buildHistoryHandlers(deps) {
|
|
|
72386
72480
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
72387
72481
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
72388
72482
|
const filtered = dirs.filter(
|
|
72389
|
-
(d2) => isGuestPathAllowed(ctx.grants,
|
|
72483
|
+
(d2) => isGuestPathAllowed(ctx.grants, path85.resolve(d2.cwd), personaRoot, "read", userWorkDir)
|
|
72390
72484
|
);
|
|
72391
72485
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
72392
72486
|
}
|
|
@@ -72403,17 +72497,17 @@ function buildHistoryHandlers(deps) {
|
|
|
72403
72497
|
}
|
|
72404
72498
|
|
|
72405
72499
|
// src/handlers/projects.ts
|
|
72406
|
-
var
|
|
72500
|
+
var fs81 = __toESM(require("fs"), 1);
|
|
72407
72501
|
var os27 = __toESM(require("os"), 1);
|
|
72408
|
-
var
|
|
72502
|
+
var path86 = __toESM(require("path"), 1);
|
|
72409
72503
|
var import_node_child_process20 = require("child_process");
|
|
72410
72504
|
init_protocol();
|
|
72411
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
72505
|
+
var DEFAULT_PROJECTS_ROOT = path86.join(os27.homedir(), "Documents", "ChatGPT");
|
|
72412
72506
|
function allocateDir(root, name) {
|
|
72413
|
-
let candidate =
|
|
72507
|
+
let candidate = path86.join(root, name);
|
|
72414
72508
|
let n2 = 2;
|
|
72415
|
-
while (
|
|
72416
|
-
candidate =
|
|
72509
|
+
while (fs81.existsSync(candidate)) {
|
|
72510
|
+
candidate = path86.join(root, `${name} ${n2}`);
|
|
72417
72511
|
n2 += 1;
|
|
72418
72512
|
}
|
|
72419
72513
|
return candidate;
|
|
@@ -72441,7 +72535,7 @@ function buildProjectHandlers(deps) {
|
|
|
72441
72535
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
72442
72536
|
}
|
|
72443
72537
|
try {
|
|
72444
|
-
if (!
|
|
72538
|
+
if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
72445
72539
|
} catch {
|
|
72446
72540
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
72447
72541
|
}
|
|
@@ -72457,7 +72551,7 @@ function buildProjectHandlers(deps) {
|
|
|
72457
72551
|
let target;
|
|
72458
72552
|
if (args.path) {
|
|
72459
72553
|
try {
|
|
72460
|
-
if (!
|
|
72554
|
+
if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
72461
72555
|
} catch {
|
|
72462
72556
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
72463
72557
|
}
|
|
@@ -72465,15 +72559,15 @@ function buildProjectHandlers(deps) {
|
|
|
72465
72559
|
} else {
|
|
72466
72560
|
const name = args.name;
|
|
72467
72561
|
try {
|
|
72468
|
-
|
|
72562
|
+
fs81.mkdirSync(root, { recursive: true });
|
|
72469
72563
|
target = allocateDir(root, name);
|
|
72470
|
-
|
|
72564
|
+
fs81.mkdirSync(target);
|
|
72471
72565
|
} catch (err) {
|
|
72472
72566
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
72473
72567
|
}
|
|
72474
72568
|
const git2 = (0, import_node_child_process20.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
72475
72569
|
if (git2.status !== 0) {
|
|
72476
|
-
|
|
72570
|
+
fs81.rmSync(target, { recursive: true, force: true });
|
|
72477
72571
|
throw new ClawdError(
|
|
72478
72572
|
ERROR_CODES.INVALID_CWD,
|
|
72479
72573
|
`git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
|
|
@@ -72498,7 +72592,7 @@ function buildProjectHandlers(deps) {
|
|
|
72498
72592
|
}
|
|
72499
72593
|
|
|
72500
72594
|
// src/handlers/workspace.ts
|
|
72501
|
-
var
|
|
72595
|
+
var path87 = __toESM(require("path"), 1);
|
|
72502
72596
|
init_protocol();
|
|
72503
72597
|
var os28 = __toESM(require("os"), 1);
|
|
72504
72598
|
init_protocol();
|
|
@@ -72541,22 +72635,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
72541
72635
|
const args = WorkspaceListArgs.parse(frame);
|
|
72542
72636
|
const isGuest = ctx?.principal.kind === "guest";
|
|
72543
72637
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os28.homedir();
|
|
72544
|
-
const resolvedCwd =
|
|
72545
|
-
const target = args.path ?
|
|
72638
|
+
const resolvedCwd = path87.resolve(args.cwd ?? fallbackCwd);
|
|
72639
|
+
const target = args.path ? path87.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
72546
72640
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
72547
72641
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
72548
72642
|
return { response: { type: "workspace:list", ...res } };
|
|
72549
72643
|
};
|
|
72550
72644
|
const read = async (frame, _client, ctx) => {
|
|
72551
72645
|
const args = WorkspaceReadArgs.parse(frame);
|
|
72552
|
-
const target =
|
|
72646
|
+
const target = path87.isAbsolute(args.path) ? path87.resolve(args.path) : path87.resolve(args.cwd, args.path);
|
|
72553
72647
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
72554
72648
|
const res = workspace.read(args);
|
|
72555
72649
|
return { response: { type: "workspace:read", ...res } };
|
|
72556
72650
|
};
|
|
72557
72651
|
const skillsList = async (frame, _client, ctx) => {
|
|
72558
72652
|
const args = SkillsListArgs.parse(frame);
|
|
72559
|
-
const cwdAbs =
|
|
72653
|
+
const cwdAbs = path87.resolve(args.cwd);
|
|
72560
72654
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
72561
72655
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
72562
72656
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -72568,7 +72662,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
72568
72662
|
};
|
|
72569
72663
|
const agentsList = async (frame, _client, ctx) => {
|
|
72570
72664
|
const args = AgentsListArgs.parse(frame);
|
|
72571
|
-
const cwdAbs =
|
|
72665
|
+
const cwdAbs = path87.resolve(args.cwd);
|
|
72572
72666
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
72573
72667
|
if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
|
|
72574
72668
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -72590,20 +72684,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
72590
72684
|
}
|
|
72591
72685
|
|
|
72592
72686
|
// src/handlers/git.ts
|
|
72593
|
-
var
|
|
72687
|
+
var path89 = __toESM(require("path"), 1);
|
|
72594
72688
|
init_protocol();
|
|
72595
72689
|
init_protocol();
|
|
72596
72690
|
|
|
72597
72691
|
// src/workspace/git.ts
|
|
72598
72692
|
var import_node_child_process21 = require("child_process");
|
|
72599
|
-
var
|
|
72600
|
-
var
|
|
72693
|
+
var import_node_fs64 = __toESM(require("fs"), 1);
|
|
72694
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
72601
72695
|
var import_node_util2 = require("util");
|
|
72602
72696
|
var pexec = (0, import_node_util2.promisify)(import_node_child_process21.execFile);
|
|
72603
72697
|
function normalizePath(p3) {
|
|
72604
|
-
const resolved =
|
|
72698
|
+
const resolved = import_node_path71.default.resolve(p3);
|
|
72605
72699
|
try {
|
|
72606
|
-
return
|
|
72700
|
+
return import_node_fs64.default.realpathSync(resolved);
|
|
72607
72701
|
} catch {
|
|
72608
72702
|
return resolved;
|
|
72609
72703
|
}
|
|
@@ -72677,7 +72771,7 @@ async function listGitBranches(cwd) {
|
|
|
72677
72771
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
72678
72772
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
72679
72773
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
72680
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
72774
|
+
if (!isGuestPathAllowed(ctx.grants, path89.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
72681
72775
|
throw new ClawdError(
|
|
72682
72776
|
ERROR_CODES.UNAUTHORIZED,
|
|
72683
72777
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -72934,12 +73028,12 @@ async function queryCodexAccount(deps = {}) {
|
|
|
72934
73028
|
}
|
|
72935
73029
|
|
|
72936
73030
|
// src/tools/pi-account.ts
|
|
72937
|
-
var
|
|
72938
|
-
var
|
|
73031
|
+
var import_node_fs65 = __toESM(require("fs"), 1);
|
|
73032
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
72939
73033
|
function readPiCredentials(agentDir) {
|
|
72940
73034
|
let raw;
|
|
72941
73035
|
try {
|
|
72942
|
-
raw = JSON.parse(
|
|
73036
|
+
raw = JSON.parse(import_node_fs65.default.readFileSync(import_node_path72.default.join(agentDir, "auth.json"), "utf8"));
|
|
72943
73037
|
} catch {
|
|
72944
73038
|
return {};
|
|
72945
73039
|
}
|
|
@@ -73023,8 +73117,8 @@ function buildEngineHandlers(deps, overrides = {}) {
|
|
|
73023
73117
|
}
|
|
73024
73118
|
|
|
73025
73119
|
// src/handlers/channels.ts
|
|
73026
|
-
var
|
|
73027
|
-
var
|
|
73120
|
+
var import_node_fs66 = __toESM(require("fs"), 1);
|
|
73121
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
73028
73122
|
function buildChannelsHandlers(deps) {
|
|
73029
73123
|
let queue = Promise.resolve();
|
|
73030
73124
|
const serialized = (fn) => (frame, context) => {
|
|
@@ -73038,8 +73132,8 @@ function buildChannelsHandlers(deps) {
|
|
|
73038
73132
|
const codexHome = resolveCodexHome2(deps.codexHome);
|
|
73039
73133
|
const agentDir = resolvePiAgentDir(deps.agentDir);
|
|
73040
73134
|
const restoreStore = deps.store.snapshot();
|
|
73041
|
-
const restoreCodex = snapshotFile(
|
|
73042
|
-
const restorePi =
|
|
73135
|
+
const restoreCodex = snapshotFile(import_node_path73.default.join(codexHome, "config.toml"));
|
|
73136
|
+
const restorePi = import_node_fs66.default.existsSync(agentDir) ? snapshotFile(import_node_path73.default.join(agentDir, PI_SUBSCRIPTION_FILE)) : null;
|
|
73043
73137
|
let next;
|
|
73044
73138
|
try {
|
|
73045
73139
|
next = mutate();
|
|
@@ -74001,21 +74095,21 @@ function computeMethodAccess(args) {
|
|
|
74001
74095
|
}
|
|
74002
74096
|
|
|
74003
74097
|
// src/version.ts
|
|
74004
|
-
var version = "0.2.
|
|
74098
|
+
var version = "0.2.646".length > 0 ? "0.2.646" : "dev";
|
|
74005
74099
|
|
|
74006
74100
|
// src/cli-probe/probe.ts
|
|
74007
|
-
var
|
|
74008
|
-
var
|
|
74101
|
+
var fs85 = __toESM(require("fs"), 1);
|
|
74102
|
+
var path92 = __toESM(require("path"), 1);
|
|
74009
74103
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
74010
74104
|
var BIN_NAME = "clawd";
|
|
74011
74105
|
var MAX_PARENT_HOPS = 5;
|
|
74012
74106
|
function probeGlobalCli(pathEnv) {
|
|
74013
74107
|
if (!pathEnv) return null;
|
|
74014
|
-
for (const dir of pathEnv.split(
|
|
74108
|
+
for (const dir of pathEnv.split(path92.delimiter)) {
|
|
74015
74109
|
if (!dir) continue;
|
|
74016
74110
|
let real;
|
|
74017
74111
|
try {
|
|
74018
|
-
real =
|
|
74112
|
+
real = fs85.realpathSync(path92.join(dir, BIN_NAME));
|
|
74019
74113
|
} catch {
|
|
74020
74114
|
continue;
|
|
74021
74115
|
}
|
|
@@ -74025,15 +74119,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
74025
74119
|
return null;
|
|
74026
74120
|
}
|
|
74027
74121
|
function readOwnPackageVersion(entryPath) {
|
|
74028
|
-
let dir =
|
|
74122
|
+
let dir = path92.dirname(entryPath);
|
|
74029
74123
|
for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
|
|
74030
74124
|
try {
|
|
74031
|
-
const raw =
|
|
74125
|
+
const raw = fs85.readFileSync(path92.join(dir, "package.json"), "utf8");
|
|
74032
74126
|
const pkg = JSON.parse(raw);
|
|
74033
74127
|
if (pkg.name !== PKG_NAME) return null;
|
|
74034
74128
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
74035
74129
|
} catch {
|
|
74036
|
-
const parent =
|
|
74130
|
+
const parent = path92.dirname(dir);
|
|
74037
74131
|
if (parent === dir) return null;
|
|
74038
74132
|
dir = parent;
|
|
74039
74133
|
}
|
|
@@ -74206,7 +74300,7 @@ function buildPersonaHandlers(deps) {
|
|
|
74206
74300
|
}
|
|
74207
74301
|
|
|
74208
74302
|
// src/handlers/attachment.ts
|
|
74209
|
-
var
|
|
74303
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
74210
74304
|
init_protocol();
|
|
74211
74305
|
init_protocol();
|
|
74212
74306
|
function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
|
|
@@ -74285,12 +74379,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
74285
74379
|
`session ${args.sessionId} scope unresolved`
|
|
74286
74380
|
);
|
|
74287
74381
|
}
|
|
74288
|
-
const cwdAbs =
|
|
74289
|
-
const candidateAbs =
|
|
74382
|
+
const cwdAbs = import_node_path74.default.resolve(sessionFile.cwd);
|
|
74383
|
+
const candidateAbs = import_node_path74.default.isAbsolute(args.relPath) ? import_node_path74.default.resolve(args.relPath) : import_node_path74.default.resolve(cwdAbs, args.relPath);
|
|
74290
74384
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
74291
74385
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
74292
74386
|
const entry = entries.find((e) => {
|
|
74293
|
-
const storedAbs =
|
|
74387
|
+
const storedAbs = import_node_path74.default.isAbsolute(e.relPath) ? import_node_path74.default.resolve(e.relPath) : import_node_path74.default.resolve(cwdAbs, e.relPath);
|
|
74294
74388
|
return storedAbs === candidateAbs && !e.stale;
|
|
74295
74389
|
});
|
|
74296
74390
|
if (!entry) {
|
|
@@ -74314,7 +74408,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
74314
74408
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
74315
74409
|
const f2 = deps.sessionStore.read(sessionId);
|
|
74316
74410
|
if (!f2) return;
|
|
74317
|
-
assertGuestAttachmentPath(ctx,
|
|
74411
|
+
assertGuestAttachmentPath(ctx, import_node_path74.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
74318
74412
|
}
|
|
74319
74413
|
const groupAdd = async (frame, _client, ctx) => {
|
|
74320
74414
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -74329,8 +74423,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
74329
74423
|
if (!scope) {
|
|
74330
74424
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
74331
74425
|
}
|
|
74332
|
-
const cwdAbs =
|
|
74333
|
-
const candidateAbs =
|
|
74426
|
+
const cwdAbs = import_node_path74.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
74427
|
+
const candidateAbs = import_node_path74.default.isAbsolute(args.relPath) ? import_node_path74.default.resolve(args.relPath) : import_node_path74.default.resolve(cwdAbs, args.relPath);
|
|
74334
74428
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
74335
74429
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
74336
74430
|
const size = 0;
|
|
@@ -74389,19 +74483,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
74389
74483
|
|
|
74390
74484
|
// src/handlers/extension.ts
|
|
74391
74485
|
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
74392
|
-
var
|
|
74486
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
74393
74487
|
init_protocol();
|
|
74394
74488
|
|
|
74395
74489
|
// src/extension/bundle-zip.ts
|
|
74396
74490
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
74397
|
-
var
|
|
74491
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
74398
74492
|
var import_node_crypto26 = __toESM(require("crypto"), 1);
|
|
74399
74493
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
74400
74494
|
async function bundleExtensionDir(dir) {
|
|
74401
74495
|
const entries = await listFilesSorted(dir);
|
|
74402
74496
|
const zip = new import_jszip3.default();
|
|
74403
74497
|
for (const rel of entries) {
|
|
74404
|
-
const abs =
|
|
74498
|
+
const abs = import_node_path75.default.join(dir, rel);
|
|
74405
74499
|
const content = await import_promises12.default.readFile(abs);
|
|
74406
74500
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
74407
74501
|
}
|
|
@@ -74422,7 +74516,7 @@ async function listFilesSorted(rootDir) {
|
|
|
74422
74516
|
return out;
|
|
74423
74517
|
}
|
|
74424
74518
|
async function walk(absRoot, relPrefix, out) {
|
|
74425
|
-
const dirAbs =
|
|
74519
|
+
const dirAbs = import_node_path75.default.join(absRoot, relPrefix);
|
|
74426
74520
|
const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
|
|
74427
74521
|
for (const e of entries) {
|
|
74428
74522
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -74476,25 +74570,25 @@ function computePublishCheck(args) {
|
|
|
74476
74570
|
|
|
74477
74571
|
// src/extension/install-flow.ts
|
|
74478
74572
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
74479
|
-
var
|
|
74573
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
74480
74574
|
var import_node_os28 = __toESM(require("os"), 1);
|
|
74481
74575
|
var import_node_crypto27 = __toESM(require("crypto"), 1);
|
|
74482
74576
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
74483
74577
|
|
|
74484
74578
|
// src/extension/paths.ts
|
|
74485
74579
|
var import_node_os27 = __toESM(require("os"), 1);
|
|
74486
|
-
var
|
|
74580
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
74487
74581
|
function clawdHomeRoot(override) {
|
|
74488
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
74582
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path76.default.join(import_node_os27.default.homedir(), ".clawd");
|
|
74489
74583
|
}
|
|
74490
74584
|
function extensionsRoot(override) {
|
|
74491
|
-
return
|
|
74585
|
+
return import_node_path76.default.join(clawdHomeRoot(override), "extensions");
|
|
74492
74586
|
}
|
|
74493
74587
|
function publishedChannelsFile(override) {
|
|
74494
|
-
return
|
|
74588
|
+
return import_node_path76.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
74495
74589
|
}
|
|
74496
74590
|
function bundleCacheRoot(override) {
|
|
74497
|
-
return
|
|
74591
|
+
return import_node_path76.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
74498
74592
|
}
|
|
74499
74593
|
|
|
74500
74594
|
// src/extension/install-flow.ts
|
|
@@ -74521,7 +74615,7 @@ async function installFromChannel(args, deps) {
|
|
|
74521
74615
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
74522
74616
|
}
|
|
74523
74617
|
for (const name of Object.keys(zip.files)) {
|
|
74524
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
74618
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
|
|
74525
74619
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
74526
74620
|
}
|
|
74527
74621
|
}
|
|
@@ -74553,7 +74647,7 @@ async function installFromChannel(args, deps) {
|
|
|
74553
74647
|
);
|
|
74554
74648
|
}
|
|
74555
74649
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
74556
|
-
const destDir =
|
|
74650
|
+
const destDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
|
|
74557
74651
|
let destExists = false;
|
|
74558
74652
|
try {
|
|
74559
74653
|
await import_promises13.default.access(destDir);
|
|
@@ -74567,16 +74661,16 @@ async function installFromChannel(args, deps) {
|
|
|
74567
74661
|
);
|
|
74568
74662
|
}
|
|
74569
74663
|
const stage = await import_promises13.default.mkdtemp(
|
|
74570
|
-
|
|
74664
|
+
import_node_path77.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
74571
74665
|
);
|
|
74572
74666
|
try {
|
|
74573
74667
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
74574
|
-
const dest =
|
|
74668
|
+
const dest = import_node_path77.default.join(stage, name);
|
|
74575
74669
|
if (entry.dir) {
|
|
74576
74670
|
await import_promises13.default.mkdir(dest, { recursive: true });
|
|
74577
74671
|
continue;
|
|
74578
74672
|
}
|
|
74579
|
-
await import_promises13.default.mkdir(
|
|
74673
|
+
await import_promises13.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
|
|
74580
74674
|
if (name === "manifest.json") {
|
|
74581
74675
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
74582
74676
|
await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -74597,7 +74691,7 @@ async function installFromChannel(args, deps) {
|
|
|
74597
74691
|
|
|
74598
74692
|
// src/extension/update-flow.ts
|
|
74599
74693
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
74600
|
-
var
|
|
74694
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
74601
74695
|
var import_node_os29 = __toESM(require("os"), 1);
|
|
74602
74696
|
var import_node_crypto28 = __toESM(require("crypto"), 1);
|
|
74603
74697
|
var import_jszip5 = __toESM(require_lib3(), 1);
|
|
@@ -74614,11 +74708,11 @@ async function updateFromChannel(args, deps) {
|
|
|
74614
74708
|
channelRef.extId,
|
|
74615
74709
|
channelRef.ownerPrincipalId
|
|
74616
74710
|
);
|
|
74617
|
-
const liveDir =
|
|
74711
|
+
const liveDir = import_node_path78.default.join(deps.extensionsRoot, localExtId);
|
|
74618
74712
|
const prevDir = `${liveDir}.prev`;
|
|
74619
74713
|
let existingVersion;
|
|
74620
74714
|
try {
|
|
74621
|
-
const raw = await import_promises14.default.readFile(
|
|
74715
|
+
const raw = await import_promises14.default.readFile(import_node_path78.default.join(liveDir, "manifest.json"), "utf8");
|
|
74622
74716
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
74623
74717
|
if (!parsed2.success) {
|
|
74624
74718
|
throw new UpdateError(
|
|
@@ -74651,7 +74745,7 @@ async function updateFromChannel(args, deps) {
|
|
|
74651
74745
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
74652
74746
|
}
|
|
74653
74747
|
for (const name of Object.keys(zip.files)) {
|
|
74654
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
74748
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path78.default.isAbsolute(name)) {
|
|
74655
74749
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
74656
74750
|
}
|
|
74657
74751
|
}
|
|
@@ -74686,16 +74780,16 @@ async function updateFromChannel(args, deps) {
|
|
|
74686
74780
|
await import_promises14.default.rm(prevDir, { recursive: true, force: true });
|
|
74687
74781
|
await import_promises14.default.rename(liveDir, prevDir);
|
|
74688
74782
|
const stage = await import_promises14.default.mkdtemp(
|
|
74689
|
-
|
|
74783
|
+
import_node_path78.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
74690
74784
|
);
|
|
74691
74785
|
try {
|
|
74692
74786
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
74693
|
-
const dest =
|
|
74787
|
+
const dest = import_node_path78.default.join(stage, name);
|
|
74694
74788
|
if (entry.dir) {
|
|
74695
74789
|
await import_promises14.default.mkdir(dest, { recursive: true });
|
|
74696
74790
|
continue;
|
|
74697
74791
|
}
|
|
74698
|
-
await import_promises14.default.mkdir(
|
|
74792
|
+
await import_promises14.default.mkdir(import_node_path78.default.dirname(dest), { recursive: true });
|
|
74699
74793
|
if (name === "manifest.json") {
|
|
74700
74794
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
74701
74795
|
await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -74762,7 +74856,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
74762
74856
|
);
|
|
74763
74857
|
}
|
|
74764
74858
|
}
|
|
74765
|
-
const manifestPath =
|
|
74859
|
+
const manifestPath = import_node_path79.default.join(root, extId, "manifest.json");
|
|
74766
74860
|
const manifest = await readManifest(root, extId);
|
|
74767
74861
|
const next = { ...manifest, version: newVersion };
|
|
74768
74862
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -74770,7 +74864,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
74770
74864
|
await import_promises15.default.rename(tmp, manifestPath);
|
|
74771
74865
|
}
|
|
74772
74866
|
async function readManifest(root, extId) {
|
|
74773
|
-
const file =
|
|
74867
|
+
const file = import_node_path79.default.join(root, extId, "manifest.json");
|
|
74774
74868
|
let raw;
|
|
74775
74869
|
try {
|
|
74776
74870
|
raw = await import_promises15.default.readFile(file, "utf8");
|
|
@@ -74854,7 +74948,7 @@ function buildExtensionHandlers(deps) {
|
|
|
74854
74948
|
};
|
|
74855
74949
|
async function buildSnapshotMeta(extId) {
|
|
74856
74950
|
const manifest = await readManifest(deps.root, extId);
|
|
74857
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
74951
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path79.default.join(deps.root, extId));
|
|
74858
74952
|
return { manifest, contentHash: sha256, buffer };
|
|
74859
74953
|
}
|
|
74860
74954
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -75681,7 +75775,7 @@ function buildVisitorHandlers(deps) {
|
|
|
75681
75775
|
|
|
75682
75776
|
// src/extension/registry.ts
|
|
75683
75777
|
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
75684
|
-
var
|
|
75778
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
75685
75779
|
async function loadAll(root) {
|
|
75686
75780
|
let entries;
|
|
75687
75781
|
try {
|
|
@@ -75694,13 +75788,13 @@ async function loadAll(root) {
|
|
|
75694
75788
|
for (const ent of entries) {
|
|
75695
75789
|
if (!ent.isDirectory()) continue;
|
|
75696
75790
|
if (ent.name.startsWith(".")) continue;
|
|
75697
|
-
records.push(await loadOne(
|
|
75791
|
+
records.push(await loadOne(import_node_path80.default.join(root, ent.name), ent.name));
|
|
75698
75792
|
}
|
|
75699
75793
|
records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
|
|
75700
75794
|
return records;
|
|
75701
75795
|
}
|
|
75702
75796
|
async function loadOne(dir, dirName) {
|
|
75703
|
-
const manifestPath =
|
|
75797
|
+
const manifestPath = import_node_path80.default.join(dir, "manifest.json");
|
|
75704
75798
|
let raw;
|
|
75705
75799
|
try {
|
|
75706
75800
|
raw = await import_promises17.default.readFile(manifestPath, "utf8");
|
|
@@ -75745,7 +75839,7 @@ async function loadOne(dir, dirName) {
|
|
|
75745
75839
|
|
|
75746
75840
|
// src/extension/uninstall.ts
|
|
75747
75841
|
var import_promises18 = __toESM(require("fs/promises"), 1);
|
|
75748
|
-
var
|
|
75842
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
75749
75843
|
var UninstallError = class extends Error {
|
|
75750
75844
|
constructor(code, message) {
|
|
75751
75845
|
super(message);
|
|
@@ -75754,7 +75848,7 @@ var UninstallError = class extends Error {
|
|
|
75754
75848
|
code;
|
|
75755
75849
|
};
|
|
75756
75850
|
async function uninstall(deps) {
|
|
75757
|
-
const dir =
|
|
75851
|
+
const dir = import_node_path81.default.join(deps.root, deps.extId);
|
|
75758
75852
|
try {
|
|
75759
75853
|
await import_promises18.default.access(dir);
|
|
75760
75854
|
} catch {
|
|
@@ -75970,7 +76064,7 @@ function buildMethodHandlers(deps) {
|
|
|
75970
76064
|
broadcast: deps.broadcastToOwners
|
|
75971
76065
|
}),
|
|
75972
76066
|
...buildMasterHandlers({
|
|
75973
|
-
authorityTablePath:
|
|
76067
|
+
authorityTablePath: import_node_path82.default.join(deps.masterDataDir, "master-authority.json")
|
|
75974
76068
|
}),
|
|
75975
76069
|
...buildTopicHandlers({
|
|
75976
76070
|
topicStore: deps.topicStore,
|
|
@@ -76112,7 +76206,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
76112
76206
|
|
|
76113
76207
|
// src/extension/runtime.ts
|
|
76114
76208
|
var import_node_child_process26 = require("child_process");
|
|
76115
|
-
var
|
|
76209
|
+
var import_node_path83 = __toESM(require("path"), 1);
|
|
76116
76210
|
var import_promises19 = require("timers/promises");
|
|
76117
76211
|
|
|
76118
76212
|
// src/extension/port-allocator.ts
|
|
@@ -76213,7 +76307,7 @@ var Runtime = class {
|
|
|
76213
76307
|
/\$CLAWOS_EXT_PORT/g,
|
|
76214
76308
|
String(port)
|
|
76215
76309
|
);
|
|
76216
|
-
const dir =
|
|
76310
|
+
const dir = import_node_path83.default.join(this.root, extId);
|
|
76217
76311
|
const env = {
|
|
76218
76312
|
...process.env,
|
|
76219
76313
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -76325,7 +76419,7 @@ ${handle.stderrTail}`
|
|
|
76325
76419
|
|
|
76326
76420
|
// src/extension/published-channels.ts
|
|
76327
76421
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
76328
|
-
var
|
|
76422
|
+
var import_node_path84 = __toESM(require("path"), 1);
|
|
76329
76423
|
init_zod();
|
|
76330
76424
|
var PublishedChannelsError = class extends Error {
|
|
76331
76425
|
constructor(code, message) {
|
|
@@ -76422,7 +76516,7 @@ var PublishedChannelStore = class {
|
|
|
76422
76516
|
)
|
|
76423
76517
|
};
|
|
76424
76518
|
const tmp = `${this.filePath}.tmp`;
|
|
76425
|
-
await import_promises20.default.mkdir(
|
|
76519
|
+
await import_promises20.default.mkdir(import_node_path84.default.dirname(this.filePath), { recursive: true });
|
|
76426
76520
|
await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
76427
76521
|
await import_promises20.default.rename(tmp, this.filePath);
|
|
76428
76522
|
}
|
|
@@ -76430,7 +76524,7 @@ var PublishedChannelStore = class {
|
|
|
76430
76524
|
|
|
76431
76525
|
// src/extension/bundle-cache.ts
|
|
76432
76526
|
var import_promises21 = __toESM(require("fs/promises"), 1);
|
|
76433
|
-
var
|
|
76527
|
+
var import_node_path85 = __toESM(require("path"), 1);
|
|
76434
76528
|
var BundleCache = class {
|
|
76435
76529
|
constructor(rootDir) {
|
|
76436
76530
|
this.rootDir = rootDir;
|
|
@@ -76439,13 +76533,13 @@ var BundleCache = class {
|
|
|
76439
76533
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
76440
76534
|
async write(snapshotHash, buffer) {
|
|
76441
76535
|
await import_promises21.default.mkdir(this.rootDir, { recursive: true });
|
|
76442
|
-
const file =
|
|
76536
|
+
const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
76443
76537
|
const tmp = `${file}.tmp`;
|
|
76444
76538
|
await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
|
|
76445
76539
|
await import_promises21.default.rename(tmp, file);
|
|
76446
76540
|
}
|
|
76447
76541
|
async read(snapshotHash) {
|
|
76448
|
-
const file =
|
|
76542
|
+
const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
76449
76543
|
try {
|
|
76450
76544
|
return await import_promises21.default.readFile(file);
|
|
76451
76545
|
} catch (e) {
|
|
@@ -76454,7 +76548,7 @@ var BundleCache = class {
|
|
|
76454
76548
|
}
|
|
76455
76549
|
}
|
|
76456
76550
|
async delete(snapshotHash) {
|
|
76457
|
-
const file =
|
|
76551
|
+
const file = import_node_path85.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
76458
76552
|
await import_promises21.default.rm(file, { force: true });
|
|
76459
76553
|
}
|
|
76460
76554
|
};
|
|
@@ -76477,24 +76571,24 @@ async function startDaemon(config) {
|
|
|
76477
76571
|
sampling: logShippingCfg.sampling,
|
|
76478
76572
|
homeDir: import_node_os31.default.homedir()
|
|
76479
76573
|
});
|
|
76480
|
-
const logDir =
|
|
76481
|
-
|
|
76574
|
+
const logDir = import_node_path86.default.join(config.dataDir, "log");
|
|
76575
|
+
import_node_fs67.default.mkdirSync(logDir, { recursive: true });
|
|
76482
76576
|
const logger = createLogger({
|
|
76483
76577
|
level: config.logLevel,
|
|
76484
|
-
file:
|
|
76578
|
+
file: import_node_path86.default.join(logDir, "clawd.log"),
|
|
76485
76579
|
logClient
|
|
76486
76580
|
});
|
|
76487
76581
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
76488
76582
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
76489
|
-
file:
|
|
76583
|
+
file: import_node_path86.default.join(logDir, "screen-idle-probe.log"),
|
|
76490
76584
|
level: "debug"
|
|
76491
76585
|
});
|
|
76492
76586
|
logger.info("screen-idle probe logger enabled", {
|
|
76493
|
-
file:
|
|
76587
|
+
file: import_node_path86.default.join(logDir, "screen-idle-probe.log")
|
|
76494
76588
|
});
|
|
76495
76589
|
const CAP_TARGETS = [
|
|
76496
|
-
|
|
76497
|
-
|
|
76590
|
+
import_node_path86.default.join(logDir, "clawd.log"),
|
|
76591
|
+
import_node_path86.default.join(logDir, "screen-idle-probe.log")
|
|
76498
76592
|
];
|
|
76499
76593
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
76500
76594
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -76610,11 +76704,11 @@ async function startDaemon(config) {
|
|
|
76610
76704
|
const agents = new AgentsScanner();
|
|
76611
76705
|
const history = new ClaudeHistoryReader();
|
|
76612
76706
|
let transport = null;
|
|
76613
|
-
const personaStore = new PersonaStore(
|
|
76707
|
+
const personaStore = new PersonaStore(import_node_path86.default.join(config.dataDir, "personas"));
|
|
76614
76708
|
const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
|
|
76615
76709
|
const activeSubscriptionChannel = subscriptionChannelStore.getActive();
|
|
76616
76710
|
if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
|
|
76617
|
-
const usersRoot =
|
|
76711
|
+
const usersRoot = import_node_path86.default.join(config.dataDir, "users");
|
|
76618
76712
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
76619
76713
|
if (defaultsRoot) {
|
|
76620
76714
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -76631,7 +76725,7 @@ async function startDaemon(config) {
|
|
|
76631
76725
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
76632
76726
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
76633
76727
|
const dispatchStore = createDispatchStore({
|
|
76634
|
-
filePath:
|
|
76728
|
+
filePath: import_node_path86.default.join(config.dataDir, "dispatch.json"),
|
|
76635
76729
|
now: () => Date.now(),
|
|
76636
76730
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
76637
76731
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -76640,7 +76734,7 @@ async function startDaemon(config) {
|
|
|
76640
76734
|
await dispatchStore.load();
|
|
76641
76735
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
76642
76736
|
const channelStore = createChannelStore({
|
|
76643
|
-
filePath:
|
|
76737
|
+
filePath: import_node_path86.default.join(config.dataDir, "channels.json"),
|
|
76644
76738
|
now: () => Date.now(),
|
|
76645
76739
|
genId: () => `ch-${(0, import_node_crypto30.randomUUID)().slice(0, 8)}`,
|
|
76646
76740
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
@@ -76649,7 +76743,7 @@ async function startDaemon(config) {
|
|
|
76649
76743
|
});
|
|
76650
76744
|
await channelStore.load();
|
|
76651
76745
|
const topicStore = createTopicStore({
|
|
76652
|
-
filePath:
|
|
76746
|
+
filePath: import_node_path86.default.join(config.dataDir, "topics.json"),
|
|
76653
76747
|
now: () => Date.now(),
|
|
76654
76748
|
genId: () => `tp-${(0, import_node_crypto30.randomUUID)().slice(0, 8)}`,
|
|
76655
76749
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
@@ -76676,12 +76770,12 @@ async function startDaemon(config) {
|
|
|
76676
76770
|
});
|
|
76677
76771
|
}
|
|
76678
76772
|
});
|
|
76679
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
76773
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path86.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
|
|
76680
76774
|
const mcpConfigs = [];
|
|
76681
76775
|
const secretsBundleRoot = findSecretsBundleRoot(logger);
|
|
76682
|
-
const localSecretsDir =
|
|
76776
|
+
const localSecretsDir = import_node_path86.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
76683
76777
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
76684
|
-
const githubTokenFile =
|
|
76778
|
+
const githubTokenFile = import_node_path86.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
|
|
76685
76779
|
const githubIdentity = createGithubIdentity({
|
|
76686
76780
|
resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
|
|
76687
76781
|
store: (token) => storeGithubAuth({
|
|
@@ -76719,20 +76813,20 @@ async function startDaemon(config) {
|
|
|
76719
76813
|
void githubIdentity.refresh();
|
|
76720
76814
|
return renderPersonaMcpSecrets({
|
|
76721
76815
|
personaId: personaId2,
|
|
76722
|
-
personaDir:
|
|
76816
|
+
personaDir: import_node_path86.default.join(config.dataDir, "personas", personaId2),
|
|
76723
76817
|
secrets,
|
|
76724
|
-
outDir:
|
|
76818
|
+
outDir: import_node_path86.default.join(config.dataDir, "persona-mcp"),
|
|
76725
76819
|
logger
|
|
76726
76820
|
});
|
|
76727
76821
|
};
|
|
76728
76822
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
76729
76823
|
const dispatchServerCandidates = [
|
|
76730
|
-
|
|
76731
|
-
|
|
76824
|
+
import_node_path86.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
76825
|
+
import_node_path86.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
76732
76826
|
];
|
|
76733
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) =>
|
|
76827
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
|
|
76734
76828
|
if (dispatchServerScriptPath) {
|
|
76735
|
-
const dispatchLogPath =
|
|
76829
|
+
const dispatchLogPath = import_node_path86.default.join(logDir, "dispatch-mcp-server.log");
|
|
76736
76830
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
76737
76831
|
dataDir: config.dataDir,
|
|
76738
76832
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -76752,12 +76846,12 @@ async function startDaemon(config) {
|
|
|
76752
76846
|
});
|
|
76753
76847
|
}
|
|
76754
76848
|
const ticketServerCandidates = [
|
|
76755
|
-
|
|
76756
|
-
|
|
76849
|
+
import_node_path86.default.join(here, "ticket", "mcp-server.cjs"),
|
|
76850
|
+
import_node_path86.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
76757
76851
|
];
|
|
76758
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p3) =>
|
|
76852
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
|
|
76759
76853
|
if (ticketServerScriptPath) {
|
|
76760
|
-
const ticketLogPath =
|
|
76854
|
+
const ticketLogPath = import_node_path86.default.join(logDir, "ticket-mcp-server.log");
|
|
76761
76855
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
76762
76856
|
dataDir: config.dataDir,
|
|
76763
76857
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -76779,12 +76873,12 @@ async function startDaemon(config) {
|
|
|
76779
76873
|
});
|
|
76780
76874
|
}
|
|
76781
76875
|
const shiftServerCandidates = [
|
|
76782
|
-
|
|
76783
|
-
|
|
76876
|
+
import_node_path86.default.join(here, "shift", "mcp-server.cjs"),
|
|
76877
|
+
import_node_path86.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
76784
76878
|
];
|
|
76785
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p3) =>
|
|
76879
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
|
|
76786
76880
|
if (shiftServerScriptPath) {
|
|
76787
|
-
const shiftLogPath =
|
|
76881
|
+
const shiftLogPath = import_node_path86.default.join(logDir, "shift-mcp-server.log");
|
|
76788
76882
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
76789
76883
|
dataDir: config.dataDir,
|
|
76790
76884
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -76805,12 +76899,12 @@ async function startDaemon(config) {
|
|
|
76805
76899
|
);
|
|
76806
76900
|
}
|
|
76807
76901
|
const inboxServerCandidates = [
|
|
76808
|
-
|
|
76809
|
-
|
|
76902
|
+
import_node_path86.default.join(here, "inbox", "mcp-server.cjs"),
|
|
76903
|
+
import_node_path86.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
76810
76904
|
];
|
|
76811
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p3) =>
|
|
76905
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
|
|
76812
76906
|
if (inboxServerScriptPath) {
|
|
76813
|
-
const inboxLogPath =
|
|
76907
|
+
const inboxLogPath = import_node_path86.default.join(logDir, "inbox-mcp-server.log");
|
|
76814
76908
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
76815
76909
|
dataDir: config.dataDir,
|
|
76816
76910
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -76831,10 +76925,10 @@ async function startDaemon(config) {
|
|
|
76831
76925
|
);
|
|
76832
76926
|
}
|
|
76833
76927
|
const peerOpsServerCandidates = [
|
|
76834
|
-
|
|
76835
|
-
|
|
76928
|
+
import_node_path86.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
76929
|
+
import_node_path86.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
76836
76930
|
];
|
|
76837
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) =>
|
|
76931
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
|
|
76838
76932
|
if (peerOpsServerScriptPath) {
|
|
76839
76933
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
76840
76934
|
dataDir: config.dataDir,
|
|
@@ -76854,12 +76948,12 @@ async function startDaemon(config) {
|
|
|
76854
76948
|
);
|
|
76855
76949
|
}
|
|
76856
76950
|
const rpcToolServerCandidates = [
|
|
76857
|
-
|
|
76858
|
-
|
|
76951
|
+
import_node_path86.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
76952
|
+
import_node_path86.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
76859
76953
|
];
|
|
76860
|
-
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) =>
|
|
76954
|
+
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
|
|
76861
76955
|
if (rpcToolServerScriptPath) {
|
|
76862
|
-
const rpcToolLogPath =
|
|
76956
|
+
const rpcToolLogPath = import_node_path86.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
76863
76957
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
76864
76958
|
dataDir: config.dataDir,
|
|
76865
76959
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -76880,7 +76974,7 @@ async function startDaemon(config) {
|
|
|
76880
76974
|
);
|
|
76881
76975
|
}
|
|
76882
76976
|
const shiftStore = createShiftStore({
|
|
76883
|
-
filePath:
|
|
76977
|
+
filePath: import_node_path86.default.join(config.dataDir, "shift.json"),
|
|
76884
76978
|
ownerIdProvider: () => ownerPrincipalId,
|
|
76885
76979
|
now: () => Date.now()
|
|
76886
76980
|
});
|
|
@@ -76897,7 +76991,7 @@ async function startDaemon(config) {
|
|
|
76897
76991
|
getAdapter,
|
|
76898
76992
|
historyReader: history,
|
|
76899
76993
|
dataDir: config.dataDir,
|
|
76900
|
-
personaRoot:
|
|
76994
|
+
personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
|
|
76901
76995
|
// Registry defaults are read only after startup, when the later registry binding is initialized.
|
|
76902
76996
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
76903
76997
|
usersRoot,
|
|
@@ -76938,10 +77032,10 @@ async function startDaemon(config) {
|
|
|
76938
77032
|
// File edits update the group manifest without making optional stat/manifest failures fail the engine turn.
|
|
76939
77033
|
attachmentGroup: {
|
|
76940
77034
|
onFileEdit: (input) => {
|
|
76941
|
-
const absPath =
|
|
77035
|
+
const absPath = import_node_path86.default.isAbsolute(input.relPath) ? input.relPath : import_node_path86.default.join(input.cwd, input.relPath);
|
|
76942
77036
|
let size = 0;
|
|
76943
77037
|
try {
|
|
76944
|
-
size =
|
|
77038
|
+
size = import_node_fs67.default.statSync(absPath).size;
|
|
76945
77039
|
} catch (err) {
|
|
76946
77040
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
76947
77041
|
sessionId: input.sessionId,
|
|
@@ -76982,9 +77076,9 @@ async function startDaemon(config) {
|
|
|
76982
77076
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
76983
77077
|
}
|
|
76984
77078
|
const projectsStore = new ProjectsStore({
|
|
76985
|
-
file:
|
|
77079
|
+
file: import_node_path86.default.join(config.dataDir, "projects.json"),
|
|
76986
77080
|
clawdDir: config.dataDir,
|
|
76987
|
-
codexStateFile:
|
|
77081
|
+
codexStateFile: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
76988
77082
|
logger
|
|
76989
77083
|
});
|
|
76990
77084
|
const observer = new SessionObserver({
|
|
@@ -77053,13 +77147,13 @@ async function startDaemon(config) {
|
|
|
77053
77147
|
runner?.confirmCloudCancelled();
|
|
77054
77148
|
});
|
|
77055
77149
|
registerAdapter("claude", claudeAdapter);
|
|
77056
|
-
const codexIsolatedHome =
|
|
77150
|
+
const codexIsolatedHome = import_node_path86.default.join(config.dataDir, "codex-home");
|
|
77057
77151
|
try {
|
|
77058
|
-
|
|
77152
|
+
import_node_fs67.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
77059
77153
|
for (const f2 of ["auth.json", "config.toml"]) {
|
|
77060
|
-
const link =
|
|
77061
|
-
const target =
|
|
77062
|
-
if (!
|
|
77154
|
+
const link = import_node_path86.default.join(codexIsolatedHome, f2);
|
|
77155
|
+
const target = import_node_path86.default.join(import_node_os31.default.homedir(), ".codex", f2);
|
|
77156
|
+
if (!import_node_fs67.default.existsSync(link) && import_node_fs67.default.existsSync(target)) import_node_fs67.default.symlinkSync(target, link);
|
|
77063
77157
|
}
|
|
77064
77158
|
} catch (err) {
|
|
77065
77159
|
logger.warn("codex isolated home setup failed", { err: String(err) });
|
|
@@ -77070,16 +77164,16 @@ async function startDaemon(config) {
|
|
|
77070
77164
|
logger,
|
|
77071
77165
|
historyReader: new CodexHistoryReader({
|
|
77072
77166
|
roots: codexRolloutRoots(config.dataDir),
|
|
77073
|
-
sharedHome:
|
|
77167
|
+
sharedHome: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
77074
77168
|
logger
|
|
77075
77169
|
}),
|
|
77076
77170
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
77077
77171
|
cwd,
|
|
77078
|
-
personaRoot:
|
|
77172
|
+
personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
|
|
77079
77173
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
77080
77174
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
77081
77175
|
projectPaths: projectsStore.listMerged().map((x2) => x2.path),
|
|
77082
|
-
sharedHome:
|
|
77176
|
+
sharedHome: import_node_path86.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
77083
77177
|
isolatedHome: codexIsolatedHome
|
|
77084
77178
|
}),
|
|
77085
77179
|
codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
|
|
@@ -77109,10 +77203,10 @@ async function startDaemon(config) {
|
|
|
77109
77203
|
);
|
|
77110
77204
|
registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, clientForEnvironment: gatewayForEnvironment, history: cloudHistorySource, logger }));
|
|
77111
77205
|
const piMcpBridgeCandidates = [
|
|
77112
|
-
|
|
77113
|
-
|
|
77206
|
+
import_node_path86.default.join(here, "pi-mcp-bridge", "extension.cjs"),
|
|
77207
|
+
import_node_path86.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
|
|
77114
77208
|
];
|
|
77115
|
-
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) =>
|
|
77209
|
+
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs67.default.existsSync(p3));
|
|
77116
77210
|
if (piMcpBridgePath) {
|
|
77117
77211
|
logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
|
|
77118
77212
|
} else {
|
|
@@ -77427,10 +77521,10 @@ async function startDaemon(config) {
|
|
|
77427
77521
|
getSignSecret: () => authFile.token,
|
|
77428
77522
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
77429
77523
|
// Guest attachment paths are guarded against persona and caller work roots.
|
|
77430
|
-
personaRoot:
|
|
77524
|
+
personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
|
|
77431
77525
|
usersRoot
|
|
77432
77526
|
},
|
|
77433
|
-
personaRoot:
|
|
77527
|
+
personaRoot: import_node_path86.default.join(config.dataDir, "personas"),
|
|
77434
77528
|
usersRoot,
|
|
77435
77529
|
getOwnerIdentity,
|
|
77436
77530
|
ownerPrincipalId,
|
|
@@ -77717,7 +77811,7 @@ async function startDaemon(config) {
|
|
|
77717
77811
|
});
|
|
77718
77812
|
shiftScheduler.start();
|
|
77719
77813
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
77720
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
77814
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path86.default.join(config.dataDir, "personas"));
|
|
77721
77815
|
const larkBotCloud = createLarkBotCloudClient({
|
|
77722
77816
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
77723
77817
|
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
|
|
@@ -77728,7 +77822,7 @@ async function startDaemon(config) {
|
|
|
77728
77822
|
cloud: larkBotCloud,
|
|
77729
77823
|
store: larkBotStore,
|
|
77730
77824
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
77731
|
-
mediaRootFor: (chatId) =>
|
|
77825
|
+
mediaRootFor: (chatId) => import_node_path86.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
77732
77826
|
isShuttingDown: () => larkDraining,
|
|
77733
77827
|
logger: {
|
|
77734
77828
|
warn: (msg) => logger.warn(msg),
|
|
@@ -78027,8 +78121,8 @@ async function startDaemon(config) {
|
|
|
78027
78121
|
const lines = [
|
|
78028
78122
|
`Tunnel: ${r2.url}`,
|
|
78029
78123
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
78030
|
-
`Frpc config: ${
|
|
78031
|
-
`Frpc log: ${
|
|
78124
|
+
`Frpc config: ${import_node_path86.default.join(config.dataDir, "frpc.toml")}`,
|
|
78125
|
+
`Frpc log: ${import_node_path86.default.join(logDir, "frpc.log")}`
|
|
78032
78126
|
];
|
|
78033
78127
|
const width2 = Math.max(...lines.map((l2) => l2.length));
|
|
78034
78128
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -78041,8 +78135,8 @@ ${bar}
|
|
|
78041
78135
|
|
|
78042
78136
|
`);
|
|
78043
78137
|
try {
|
|
78044
|
-
const connectPath =
|
|
78045
|
-
|
|
78138
|
+
const connectPath = import_node_path86.default.join(config.dataDir, "connect.txt");
|
|
78139
|
+
import_node_fs67.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
78046
78140
|
} catch {
|
|
78047
78141
|
}
|
|
78048
78142
|
} catch (err) {
|
|
@@ -78140,9 +78234,9 @@ ${bar}
|
|
|
78140
78234
|
};
|
|
78141
78235
|
}
|
|
78142
78236
|
function migrateDropPersonsDir(dataDir) {
|
|
78143
|
-
const dir =
|
|
78237
|
+
const dir = import_node_path86.default.join(dataDir, "persons");
|
|
78144
78238
|
try {
|
|
78145
|
-
|
|
78239
|
+
import_node_fs67.default.rmSync(dir, { recursive: true, force: true });
|
|
78146
78240
|
} catch {
|
|
78147
78241
|
}
|
|
78148
78242
|
}
|