@clawos-dev/clawd 0.2.731 → 0.2.733
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-builder-plugin/mcp-server.cjs +17 -12
- package/dist/cli.cjs +95 -24
- package/dist/cloud-persona-conversations.html +18 -18
- package/dist/dispatch/mcp-server.cjs +17 -12
- package/dist/owner-ui/assets/{owner-Iqmj-Nqo.js → owner-V72Fs11W.js} +201 -201
- package/dist/owner-ui/owner.html +1 -1
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +17 -12
- package/dist/persona-defaults/persona-clawd-butler/.claude/skills/scan-persona-for-deploy/SKILL.md +20 -17
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +17 -12
- package/dist/secrets/README.md +1 -1
- package/dist/share-ui/assets/{guest-BtoJZ-Uc.js → guest-DPqaHbma.js} +50 -50
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
|
@@ -31378,12 +31378,6 @@ var EnvPackageSchema = external_exports.object({
|
|
|
31378
31378
|
*/
|
|
31379
31379
|
aptVersion: external_exports.string().optional()
|
|
31380
31380
|
});
|
|
31381
|
-
var EnvSecretSchema = external_exports.object({
|
|
31382
|
-
name: external_exports.string().min(1),
|
|
31383
|
-
// 解析出的值注入到哪些环境变量。一份凭据可含多个字段(AK 是 id+secret 两个,
|
|
31384
|
-
// supabase 是 url/anon/service-role/jwt 四个),所以是数组不是单值。
|
|
31385
|
-
env: external_exports.array(external_exports.string().min(1)).min(1)
|
|
31386
|
-
});
|
|
31387
31381
|
var ConnectorNameSchema = external_exports.string().regex(/^[a-z0-9-]+$/, "\u8FDE\u63A5\u5668\u540D\u53EA\u80FD\u662F\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u77ED\u6A2A\u7EBF");
|
|
31388
31382
|
var CONNECTOR_KINDS = ["proxy", "env"];
|
|
31389
31383
|
var CONNECTOR_RUNNERS = ["mcp", "cli"];
|
|
@@ -31391,6 +31385,10 @@ var CONNECTOR_PROTOCOLS = ["bearer", "lark-sidecar"];
|
|
|
31391
31385
|
var CREDENTIAL_SOURCES = ["none", "shared", "personal"];
|
|
31392
31386
|
var CONNECTOR_AUTHS = ["oauth", "fields"];
|
|
31393
31387
|
var ConnectorFieldSchema = external_exports.string().regex(/^[A-Z][A-Z0-9_]*$/, "\u8981\u586B\u7684\u53D8\u91CF\u540D\u53EA\u80FD\u662F\u5927\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u4E0B\u5212\u7EBF\uFF0C\u4E14\u4EE5\u5B57\u6BCD\u5F00\u5934");
|
|
31388
|
+
var EnvVarSchema = external_exports.object({
|
|
31389
|
+
name: external_exports.string().min(1),
|
|
31390
|
+
env: external_exports.array(ConnectorFieldSchema).min(1)
|
|
31391
|
+
});
|
|
31394
31392
|
var EnvConnectorSchema = external_exports.object({
|
|
31395
31393
|
name: ConnectorNameSchema,
|
|
31396
31394
|
kind: external_exports.enum(CONNECTOR_KINDS),
|
|
@@ -31415,6 +31413,12 @@ var normalizeLegacyManifest = (v) => {
|
|
|
31415
31413
|
const { assets: _dropped, ...rest } = o;
|
|
31416
31414
|
o = rest;
|
|
31417
31415
|
}
|
|
31416
|
+
if ("secrets" in o && Array.isArray(o.secrets)) {
|
|
31417
|
+
const { secrets, ...rest } = o;
|
|
31418
|
+
const fields = new Set((Array.isArray(rest.connectors) ? rest.connectors : []).flatMap((c) => Array.isArray(c?.fields) ? c.fields : []));
|
|
31419
|
+
const legacy = secrets.map((g) => ({ ...g, env: Array.isArray(g?.env) ? g.env.filter((e) => !fields.has(e)) : g?.env })).filter((g) => !Array.isArray(g.env) || g.env.length > 0);
|
|
31420
|
+
o = { ...rest, envVars: [...Array.isArray(rest.envVars) ? rest.envVars : [], ...legacy] };
|
|
31421
|
+
}
|
|
31418
31422
|
return o;
|
|
31419
31423
|
};
|
|
31420
31424
|
var PublisherTestSchema = external_exports.object({
|
|
@@ -31426,12 +31430,13 @@ var PublisherTestSchema = external_exports.object({
|
|
|
31426
31430
|
var MANIFEST_BODY = {
|
|
31427
31431
|
test: PublisherTestSchema.optional(),
|
|
31428
31432
|
packages: external_exports.array(EnvPackageSchema),
|
|
31429
|
-
|
|
31433
|
+
/** 环境变量(见 `EnvVarSchema`)。缺省空:没声明就是没有。 */
|
|
31434
|
+
envVars: external_exports.array(EnvVarSchema).default([]),
|
|
31430
31435
|
/**
|
|
31431
31436
|
* 装了哪些连接器(design 2026-09-11-mcp-connector §3.1)。一条一个对象,形状见 `EnvConnectorSchema`。
|
|
31432
31437
|
*
|
|
31433
|
-
*
|
|
31434
|
-
* 三种来源里只有「共享」才落到 Secrets,而且靠 `sharedConnectorSecrets`
|
|
31438
|
+
* 凭据归连接器自己(`fields`),不进 envVars:谁出是单据上点出来的,
|
|
31439
|
+
* 三种来源里只有「共享」才落到 Secrets,而且靠 `sharedConnectorSecrets` 在消费处并入。
|
|
31435
31440
|
*
|
|
31436
31441
|
* **缺省空而不是必填**:本机上已有的单据不用为此重扫一遍;没声明就是没装。
|
|
31437
31442
|
*/
|
|
@@ -31445,7 +31450,7 @@ var EnvironmentManifestSchema = external_exports.preprocess(normalizeLegacyManif
|
|
|
31445
31450
|
...MANIFEST_BODY
|
|
31446
31451
|
}).strict());
|
|
31447
31452
|
var EnvEvidenceSchema = external_exports.object({
|
|
31448
|
-
// 这条证据支持的是哪一项:`${kind}:${name}`,如 'package:aliyun' / '
|
|
31453
|
+
// 这条证据支持的是哪一项:`${kind}:${name}`,如 'package:aliyun' / 'env:aliyun-ak' / 'connector:feishu'
|
|
31449
31454
|
target: external_exports.string().min(1),
|
|
31450
31455
|
reason: external_exports.string().min(1),
|
|
31451
31456
|
file: external_exports.string().min(1),
|
|
@@ -31950,7 +31955,7 @@ var DeployRerunJobArgsSchema = external_exports.object({
|
|
|
31950
31955
|
}).strict();
|
|
31951
31956
|
var DeployReportFindingArgsSchema = external_exports.object({
|
|
31952
31957
|
personaId: external_exports.string().min(1),
|
|
31953
|
-
kind: external_exports.enum(["package", "
|
|
31958
|
+
kind: external_exports.enum(["package", "env", "connector"]),
|
|
31954
31959
|
// 该条目在 manifest 对应数组里的内容(形状随 kind 变,handler 按 kind 收窄校验)
|
|
31955
31960
|
// connector 的 item 是 butler 报的 CLI 连接器({ name, fields? }),daemon 补齐 kind / runner / id 后落进清单;
|
|
31956
31961
|
// MCP 连接器不经这里——由 daemon 从 .mcp.json 机械列出(design 2026-09-11-mcp-connector §3.2)
|
|
@@ -34013,7 +34018,7 @@ var METHOD_DOCS = {
|
|
|
34013
34018
|
}
|
|
34014
34019
|
},
|
|
34015
34020
|
"deploy:reportFinding": {
|
|
34016
|
-
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\
|
|
34021
|
+
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\uFF08package / env / connector\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u9875\u9762\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\u3002\u53EA\u56DE\u626B\u63CF\u5386\u53F2 `scans`\uFF08\u540C deploy:patch\uFF09\uFF0C\u4E0D\u56DE\u6574\u4EFD\u72B6\u6001\uFF1Bowner-only\u2014\u2014butler \u4F1A\u8BDD\u672C\u8EAB\u8DD1\u5728 owner \u6A21\u5F0F",
|
|
34017
34022
|
args: DeployReportFindingArgsSchema
|
|
34018
34023
|
},
|
|
34019
34024
|
"deploy:finishScan": {
|
package/dist/cli.cjs
CHANGED
|
@@ -6174,9 +6174,13 @@ function sharedConnectorSecrets(m3) {
|
|
|
6174
6174
|
return m3.connectors.filter((c2) => c2.credentialSource === "shared" && c2.fields.length > 0).map((c2) => ({ name: c2.name, env: [...c2.fields] }));
|
|
6175
6175
|
}
|
|
6176
6176
|
function requiredSecretEnvNames(m3) {
|
|
6177
|
-
return [.../* @__PURE__ */ new Set([...m3.
|
|
6177
|
+
return [.../* @__PURE__ */ new Set([...m3.envVars.flatMap((s2) => s2.env), ...sharedConnectorSecrets(m3).flatMap((s2) => s2.env)])];
|
|
6178
6178
|
}
|
|
6179
|
-
|
|
6179
|
+
function envVarBlockers(m3) {
|
|
6180
|
+
const fields = new Set(m3.connectors.flatMap((c2) => c2.fields));
|
|
6181
|
+
return [...new Set(m3.envVars.flatMap((v3) => v3.env))].filter((env) => fields.has(env)).map((env) => `${env} \u540C\u65F6\u662F\u73AF\u5883\u53D8\u91CF\u548C\u8FDE\u63A5\u5668\u7684\u5B57\u6BB5\uFF0C\u53EA\u80FD\u7559\u4E00\u5904\u2014\u2014\u91CD\u65B0\u626B\u63CF`);
|
|
6182
|
+
}
|
|
6183
|
+
var EnvArtifactSchema, CLOUD_DEBIAN, CLOUD_ROOT_PROVIDES, CLOUD_BASE_PROVIDES, EnvPackageSchema, ConnectorNameSchema, CONNECTOR_KINDS, CONNECTOR_RUNNERS, CONNECTOR_PROTOCOLS, CREDENTIAL_SOURCES, CONNECTOR_AUTHS, ConnectorFieldSchema, EnvVarSchema, EnvConnectorSchema, FEISHU_BOT_FIELDS, GO_SPEC_RE, GO_MOVING_REFS, normalizeLegacyManifest, PUBLISHER_TEST_NOTE_PREFIX, PublisherTestSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
|
|
6180
6184
|
var init_environment_schemas = __esm({
|
|
6181
6185
|
"../protocol/src/environment-schemas.ts"() {
|
|
6182
6186
|
"use strict";
|
|
@@ -6246,12 +6250,6 @@ var init_environment_schemas = __esm({
|
|
|
6246
6250
|
*/
|
|
6247
6251
|
aptVersion: external_exports.string().optional()
|
|
6248
6252
|
});
|
|
6249
|
-
EnvSecretSchema = external_exports.object({
|
|
6250
|
-
name: external_exports.string().min(1),
|
|
6251
|
-
// 解析出的值注入到哪些环境变量。一份凭据可含多个字段(AK 是 id+secret 两个,
|
|
6252
|
-
// supabase 是 url/anon/service-role/jwt 四个),所以是数组不是单值。
|
|
6253
|
-
env: external_exports.array(external_exports.string().min(1)).min(1)
|
|
6254
|
-
});
|
|
6255
6253
|
ConnectorNameSchema = external_exports.string().regex(/^[a-z0-9-]+$/, "\u8FDE\u63A5\u5668\u540D\u53EA\u80FD\u662F\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u77ED\u6A2A\u7EBF");
|
|
6256
6254
|
CONNECTOR_KINDS = ["proxy", "env"];
|
|
6257
6255
|
CONNECTOR_RUNNERS = ["mcp", "cli"];
|
|
@@ -6259,6 +6257,10 @@ var init_environment_schemas = __esm({
|
|
|
6259
6257
|
CREDENTIAL_SOURCES = ["none", "shared", "personal"];
|
|
6260
6258
|
CONNECTOR_AUTHS = ["oauth", "fields"];
|
|
6261
6259
|
ConnectorFieldSchema = external_exports.string().regex(/^[A-Z][A-Z0-9_]*$/, "\u8981\u586B\u7684\u53D8\u91CF\u540D\u53EA\u80FD\u662F\u5927\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u4E0B\u5212\u7EBF\uFF0C\u4E14\u4EE5\u5B57\u6BCD\u5F00\u5934");
|
|
6260
|
+
EnvVarSchema = external_exports.object({
|
|
6261
|
+
name: external_exports.string().min(1),
|
|
6262
|
+
env: external_exports.array(ConnectorFieldSchema).min(1)
|
|
6263
|
+
});
|
|
6262
6264
|
EnvConnectorSchema = external_exports.object({
|
|
6263
6265
|
name: ConnectorNameSchema,
|
|
6264
6266
|
kind: external_exports.enum(CONNECTOR_KINDS),
|
|
@@ -6286,6 +6288,12 @@ var init_environment_schemas = __esm({
|
|
|
6286
6288
|
const { assets: _dropped, ...rest } = o2;
|
|
6287
6289
|
o2 = rest;
|
|
6288
6290
|
}
|
|
6291
|
+
if ("secrets" in o2 && Array.isArray(o2.secrets)) {
|
|
6292
|
+
const { secrets, ...rest } = o2;
|
|
6293
|
+
const fields = new Set((Array.isArray(rest.connectors) ? rest.connectors : []).flatMap((c2) => Array.isArray(c2?.fields) ? c2.fields : []));
|
|
6294
|
+
const legacy = secrets.map((g3) => ({ ...g3, env: Array.isArray(g3?.env) ? g3.env.filter((e) => !fields.has(e)) : g3?.env })).filter((g3) => !Array.isArray(g3.env) || g3.env.length > 0);
|
|
6295
|
+
o2 = { ...rest, envVars: [...Array.isArray(rest.envVars) ? rest.envVars : [], ...legacy] };
|
|
6296
|
+
}
|
|
6289
6297
|
return o2;
|
|
6290
6298
|
};
|
|
6291
6299
|
PUBLISHER_TEST_NOTE_PREFIX = "Publisher test: ";
|
|
@@ -6298,12 +6306,13 @@ var init_environment_schemas = __esm({
|
|
|
6298
6306
|
MANIFEST_BODY = {
|
|
6299
6307
|
test: PublisherTestSchema.optional(),
|
|
6300
6308
|
packages: external_exports.array(EnvPackageSchema),
|
|
6301
|
-
|
|
6309
|
+
/** 环境变量(见 `EnvVarSchema`)。缺省空:没声明就是没有。 */
|
|
6310
|
+
envVars: external_exports.array(EnvVarSchema).default([]),
|
|
6302
6311
|
/**
|
|
6303
6312
|
* 装了哪些连接器(design 2026-09-11-mcp-connector §3.1)。一条一个对象,形状见 `EnvConnectorSchema`。
|
|
6304
6313
|
*
|
|
6305
|
-
*
|
|
6306
|
-
* 三种来源里只有「共享」才落到 Secrets,而且靠 `sharedConnectorSecrets`
|
|
6314
|
+
* 凭据归连接器自己(`fields`),不进 envVars:谁出是单据上点出来的,
|
|
6315
|
+
* 三种来源里只有「共享」才落到 Secrets,而且靠 `sharedConnectorSecrets` 在消费处并入。
|
|
6307
6316
|
*
|
|
6308
6317
|
* **缺省空而不是必填**:本机上已有的单据不用为此重扫一遍;没声明就是没装。
|
|
6309
6318
|
*/
|
|
@@ -6317,7 +6326,7 @@ var init_environment_schemas = __esm({
|
|
|
6317
6326
|
...MANIFEST_BODY
|
|
6318
6327
|
}).strict());
|
|
6319
6328
|
EnvEvidenceSchema = external_exports.object({
|
|
6320
|
-
// 这条证据支持的是哪一项:`${kind}:${name}`,如 'package:aliyun' / '
|
|
6329
|
+
// 这条证据支持的是哪一项:`${kind}:${name}`,如 'package:aliyun' / 'env:aliyun-ak' / 'connector:feishu'
|
|
6321
6330
|
target: external_exports.string().min(1),
|
|
6322
6331
|
reason: external_exports.string().min(1),
|
|
6323
6332
|
file: external_exports.string().min(1),
|
|
@@ -6934,7 +6943,7 @@ var init_deploy_schemas = __esm({
|
|
|
6934
6943
|
DEPLOY_STALE_BASE_ERROR = "\u5E95\u5EA7\u5DF2\u66F4\u65B0\uFF0C\u91CD\u8BD5\u4ECD\u4F1A\u7528\u65E7\u5E95\u5EA7\u6784\u5EFA\u2014\u2014\u8BF7\u91CD\u65B0\u53D1\u5E03\u6D4B\u8BD5\u73AF\u5883";
|
|
6935
6944
|
DeployReportFindingArgsSchema = external_exports.object({
|
|
6936
6945
|
personaId: external_exports.string().min(1),
|
|
6937
|
-
kind: external_exports.enum(["package", "
|
|
6946
|
+
kind: external_exports.enum(["package", "env", "connector"]),
|
|
6938
6947
|
// 该条目在 manifest 对应数组里的内容(形状随 kind 变,handler 按 kind 收窄校验)
|
|
6939
6948
|
// connector 的 item 是 butler 报的 CLI 连接器({ name, fields? }),daemon 补齐 kind / runner / id 后落进清单;
|
|
6940
6949
|
// MCP 连接器不经这里——由 daemon 从 .mcp.json 机械列出(design 2026-09-11-mcp-connector §3.2)
|
|
@@ -9286,7 +9295,7 @@ var init_methods = __esm({
|
|
|
9286
9295
|
}
|
|
9287
9296
|
},
|
|
9288
9297
|
"deploy:reportFinding": {
|
|
9289
|
-
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\
|
|
9298
|
+
summary: "\u626B\u63CF\u4E2D\u7684 butler \u9010\u6761\u4E0A\u62A5\u4E00\u4E2A\u53D1\u73B0\uFF08package / env / connector\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u9875\u9762\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\u3002\u53EA\u56DE\u626B\u63CF\u5386\u53F2 `scans`\uFF08\u540C deploy:patch\uFF09\uFF0C\u4E0D\u56DE\u6574\u4EFD\u72B6\u6001\uFF1Bowner-only\u2014\u2014butler \u4F1A\u8BDD\u672C\u8EAB\u8DD1\u5728 owner \u6A21\u5F0F",
|
|
9290
9299
|
args: DeployReportFindingArgsSchema
|
|
9291
9300
|
},
|
|
9292
9301
|
"deploy:finishScan": {
|
|
@@ -49195,6 +49204,33 @@ function attachPersonaSecretMcp(ctx, resolve9) {
|
|
|
49195
49204
|
return { ...ctx, mcpConfigs: [...ctx.mcpConfigs ?? [], ref] };
|
|
49196
49205
|
}
|
|
49197
49206
|
|
|
49207
|
+
// src/persona/persona-env-vars.ts
|
|
49208
|
+
init_protocol();
|
|
49209
|
+
function personaEnvVars(args) {
|
|
49210
|
+
let parsed;
|
|
49211
|
+
try {
|
|
49212
|
+
parsed = DeployFileSchema.safeParse(JSON.parse(args.manifestText));
|
|
49213
|
+
} catch {
|
|
49214
|
+
throw new Error("deploy.json \u4E0D\u662F\u5408\u6CD5 JSON");
|
|
49215
|
+
}
|
|
49216
|
+
if (!parsed.success) throw new Error("deploy.json \u8BFB\u4E0D\u51FA\u6E05\u5355");
|
|
49217
|
+
const names = [...new Set(parsed.data.manifest.envVars.flatMap((v3) => v3.env))];
|
|
49218
|
+
const env = {};
|
|
49219
|
+
const missing = [];
|
|
49220
|
+
for (const name of names) {
|
|
49221
|
+
const value = args.secrets[name];
|
|
49222
|
+
if (value) env[name] = value;
|
|
49223
|
+
else missing.push(name);
|
|
49224
|
+
}
|
|
49225
|
+
return { env, missing };
|
|
49226
|
+
}
|
|
49227
|
+
function attachPersonaEnvVars(ctx, resolve9) {
|
|
49228
|
+
if (!resolve9 || !ctx.personaId) return ctx;
|
|
49229
|
+
const vars = resolve9(ctx.personaId);
|
|
49230
|
+
if (Object.keys(vars).length === 0) return ctx;
|
|
49231
|
+
return { ...ctx, env: { ...vars, ...ctx.env } };
|
|
49232
|
+
}
|
|
49233
|
+
|
|
49198
49234
|
// src/ipc-recorder.ts
|
|
49199
49235
|
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
49200
49236
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
@@ -49696,6 +49732,7 @@ var SessionRunner = class {
|
|
|
49696
49732
|
let ctx;
|
|
49697
49733
|
try {
|
|
49698
49734
|
ctx = attachPersonaSecretMcp(rawCtx, this.hooks.resolvePersonaMcpConfig);
|
|
49735
|
+
if (!this.state.file.larkChatId) ctx = attachPersonaEnvVars(ctx, this.hooks.resolvePersonaEnvVars);
|
|
49699
49736
|
} catch (err) {
|
|
49700
49737
|
const message = `persona secret mcp render failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
49701
49738
|
this.hooks.logger?.error("persona.mcp-secret.render-failed", {
|
|
@@ -50236,6 +50273,7 @@ var SessionManager = class {
|
|
|
50236
50273
|
getClawosApi: this.deps.getClawosApi,
|
|
50237
50274
|
getMcpConfigs: () => this.deps.mcpConfigs ?? [],
|
|
50238
50275
|
resolvePersonaMcpConfig: this.deps.resolvePersonaMcpConfig,
|
|
50276
|
+
resolvePersonaEnvVars: this.deps.resolvePersonaEnvVars,
|
|
50239
50277
|
// 只传人格补充层读闭包,避免把整个 store 下沉;缺 store 不追加。
|
|
50240
50278
|
readPersonalityLocal: this.deps.personaStore ? (id) => this.deps.personaStore?.readPersonalityLocal(id) ?? null : void 0,
|
|
50241
50279
|
lookupDispatchByBSessionId: this.deps.personaDispatchManager ? (bSid) => this.deps.personaDispatchManager?.lookupDispatchByBSessionId(bSid) : void 0,
|
|
@@ -58985,7 +59023,9 @@ function normalizeLegacyScan(raw) {
|
|
|
58985
59023
|
rest.evidence = rest.evidence.map((e) => {
|
|
58986
59024
|
if (!e || typeof e !== "object" || typeof e.target !== "string") return e;
|
|
58987
59025
|
const target = e.target;
|
|
58988
|
-
|
|
59026
|
+
if (target.startsWith("cli:")) return { ...e, target: `package:${target.slice("cli:".length)}` };
|
|
59027
|
+
if (target.startsWith("secret:")) return { ...e, target: `env:${target.slice("secret:".length)}` };
|
|
59028
|
+
return e;
|
|
58989
59029
|
});
|
|
58990
59030
|
}
|
|
58991
59031
|
return rest;
|
|
@@ -59029,14 +59069,14 @@ function replaceScan(file, entry) {
|
|
|
59029
59069
|
return { ...file, scans: idx === -1 ? [...file.scans, entry] : file.scans.map((s2, i2) => i2 === idx ? entry : s2) };
|
|
59030
59070
|
}
|
|
59031
59071
|
function emptyDeployFile() {
|
|
59032
|
-
return { version: 1, manifest: { version: 1, packages: [],
|
|
59072
|
+
return { version: 1, manifest: { version: 1, packages: [], envVars: [], connectors: [] } };
|
|
59033
59073
|
}
|
|
59034
59074
|
var PackageFindingSchema = EnvPackageSchema.omit({ localVersion: true, artifact: true, aptMissing: true, aptVersion: true }).extend({
|
|
59035
59075
|
artifact: external_exports.object({ url: external_exports.string().url(), bin: external_exports.string() }).strict().optional()
|
|
59036
59076
|
});
|
|
59037
59077
|
var FINDING_SCHEMAS = {
|
|
59038
59078
|
package: PackageFindingSchema,
|
|
59039
|
-
|
|
59079
|
+
env: EnvVarSchema,
|
|
59040
59080
|
// 仅收 CLI 连接器发现;MCP 由 scanMcpConnectors 从配置列出。
|
|
59041
59081
|
connector: CliConnectorFindingSchema
|
|
59042
59082
|
};
|
|
@@ -59090,7 +59130,7 @@ function upsertFinding(manifest, kind, item) {
|
|
|
59090
59130
|
const connectors = idx2 === -1 ? [...have, merged] : have.map((c2, i2) => i2 === idx2 ? merged : c2);
|
|
59091
59131
|
return { ...manifest, connectors };
|
|
59092
59132
|
}
|
|
59093
|
-
const key = kind === "package" ? "packages" : "
|
|
59133
|
+
const key = kind === "package" ? "packages" : "envVars";
|
|
59094
59134
|
const list = [...manifest[key]];
|
|
59095
59135
|
const idx = list.findIndex((x2) => x2.name === item.name);
|
|
59096
59136
|
if (idx === -1) list.push(item);
|
|
@@ -63114,6 +63154,7 @@ var UNPUBLISH_WORKFLOW_FILE = "clawd-unpublish.yml";
|
|
|
63114
63154
|
var UNPUBLISH_WORKFLOW_PATH = `.github/workflows/${UNPUBLISH_WORKFLOW_FILE}`;
|
|
63115
63155
|
var DOCKERFILE_PATH = "Dockerfile";
|
|
63116
63156
|
var DOCKERIGNORE_PATH = ".dockerignore";
|
|
63157
|
+
var INSTALL_FILE_PATH = ".clawd/deploy-install.json";
|
|
63117
63158
|
var ACR_REGISTRY = "registry.cn-hangzhou.aliyuncs.com";
|
|
63118
63159
|
var ACR_VPC_REGISTRY = "registry-vpc.cn-hangzhou.aliyuncs.com";
|
|
63119
63160
|
var ACR_NAMESPACE = "ttc-prod";
|
|
@@ -63140,6 +63181,13 @@ function mergeGitignore(existing) {
|
|
|
63140
63181
|
function personaIdOf(repoName) {
|
|
63141
63182
|
return String(repoName).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
63142
63183
|
}
|
|
63184
|
+
function renderInstallFile(deployFileRaw) {
|
|
63185
|
+
const parsed = JSON.parse(deployFileRaw);
|
|
63186
|
+
const manifest = parsed.manifest ?? parsed;
|
|
63187
|
+
const assets = Array.isArray(manifest.assets) && manifest.assets.length ? { assets: manifest.assets } : {};
|
|
63188
|
+
return `${JSON.stringify({ version: 1, manifest: { packages: manifest.packages ?? manifest.clis ?? [], ...assets } }, null, 2)}
|
|
63189
|
+
`;
|
|
63190
|
+
}
|
|
63143
63191
|
function renderDockerfile(personaId2, baseImage) {
|
|
63144
63192
|
if (typeof baseImage !== "string" || !/^[a-z0-9.-]+(?::[0-9]+)?\/[a-z0-9._/-]+@sha256:[a-f0-9]{64}$/.test(baseImage)) throw new Error("base image must be a complete digest reference");
|
|
63145
63193
|
if (!/^[a-z0-9][a-z0-9-]{0,39}$/.test(personaId2)) throw new Error(`persona id \u4E0D\u5408\u5F62\u72B6\uFF08[a-z0-9-]\uFF0C\u226440\uFF09\uFF1A${JSON.stringify(personaId2)}`);
|
|
@@ -63149,9 +63197,11 @@ function renderDockerfile(personaId2, baseImage) {
|
|
|
63149
63197
|
"# \u7531 clawd \u751F\u6210\u3001\u7531 clawd \u7EF4\u62A4\uFF1A\u6BCF\u6B21\u300C\u53D1\u5E03\u300D\u90FD\u4F1A\u7528\u5F53\u524D\u6A21\u677F\u91CD\u5199\u8FD9\u4EFD\u6587\u4EF6\u518D\u63D0\u4EA4\uFF0C\u624B\u6539\u4F1A\u88AB\u76D6\u6389\u3002",
|
|
63150
63198
|
"# \u963F\u91CC\u4E91\u5BB9\u5668\u955C\u50CF\u670D\u52A1\uFF08ACR\uFF09\u4ECE\u8FD9\u4E2A\u4ED3\u5E93\u6784 persona \u955C\u50CF\u65F6\u7528\u5B83\uFF1BGitHub \u7684 runner \u4E0D\u6784\u3001\u4E0D\u63A8\u955C\u50CF\u3002",
|
|
63151
63199
|
"# \u8981\u88C5\u4EC0\u4E48\u5199\u5728 .clawd/deploy.json \u91CC\uFF0C\u7531\u5E95\u5EA7\u81EA\u5E26\u7684\u5B89\u88C5\u5668\u5728\u6784\u5EFA\u65F6\u73B0\u88C5\u2014\u2014\u8FD9\u91CC\u4E0D\u5217\u4EFB\u4F55\u4E00\u6761\u4F9D\u8D56\uFF0C",
|
|
63152
|
-
"# \u6240\u4EE5\u6587\u4EF6\u4E0D\u968F\u6E05\u5355\u53D8\uFF1B\u5148\u53EA\u62F7\u6E05\u5355\u518D\u88C5\uFF0Cpersona \u5185\u5BB9\u6539\u4E86\u4E5F\u4E0D\u7528\u91CD\u88C5\u3002",
|
|
63200
|
+
"# \u6240\u4EE5\u6587\u4EF6\u4E0D\u968F\u6E05\u5355\u53D8\uFF1B\u5148\u53EA\u62F7\u5B89\u88C5\u6E05\u5355\uFF08deploy-install.json\uFF0C\u53EA\u542B\u8981\u88C5\u7684\u4E1C\u897F\uFF09\u518D\u88C5\uFF0Cpersona \u5185\u5BB9\u6216\u51ED\u636E\u914D\u7F6E\u6539\u4E86\u4E5F\u4E0D\u7528\u91CD\u88C5\u3002",
|
|
63201
|
+
"# deploy-install.json \u7531\u53D1\u5E03\u65F6\u4ECE deploy.json \u751F\u6210\uFF1A\u6539\u8981\u88C5\u7684\u5305\u987B\u7ECF clawd \u53D1\u5E03\uFF0C\u624B\u6539 deploy.json \u518D push \u4E0D\u4F1A\u751F\u6548\u3002",
|
|
63153
63202
|
`FROM ${fromImage}`,
|
|
63154
|
-
|
|
63203
|
+
// 拷到安装器读的位置;最后一条 COPY . 再用完整的 deploy.json 盖回来
|
|
63204
|
+
`COPY ${INSTALL_FILE_PATH} ${dir}/.clawd/deploy.json`,
|
|
63155
63205
|
`RUN node ${PERSONA_LAYER_SCRIPT} ${dir}`,
|
|
63156
63206
|
`COPY . ${dir}/`,
|
|
63157
63207
|
""
|
|
@@ -63293,7 +63343,7 @@ var runCommand = (cmd, args, opts = {}) => new Promise((resolve9) => {
|
|
|
63293
63343
|
// src/deploy/repo.ts
|
|
63294
63344
|
var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path44.default.sep).join("/");
|
|
63295
63345
|
var PERSONA_FILE_REL = ".clawd/persona.json";
|
|
63296
|
-
var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL];
|
|
63346
|
+
var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL, INSTALL_FILE_PATH];
|
|
63297
63347
|
var RepoError = class extends Error {
|
|
63298
63348
|
};
|
|
63299
63349
|
var tail = (s2, n2 = 400) => s2.trim().slice(-n2);
|
|
@@ -63452,6 +63502,8 @@ async function writeDockerfile(dir, personaId2, image) {
|
|
|
63452
63502
|
`);
|
|
63453
63503
|
await import_promises5.default.writeFile(import_node_path44.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2, baseImage));
|
|
63454
63504
|
await import_promises5.default.writeFile(import_node_path44.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
|
|
63505
|
+
const deployFile = await readDeployFileRaw(dir);
|
|
63506
|
+
if (deployFile !== void 0) await import_promises5.default.writeFile(import_node_path44.default.join(dir, INSTALL_FILE_PATH), renderInstallFile(deployFile));
|
|
63455
63507
|
}
|
|
63456
63508
|
var RepoAlreadyExistsError = class extends RepoError {
|
|
63457
63509
|
constructor(slug) {
|
|
@@ -64594,8 +64646,8 @@ function buildDeployHandlers(deps) {
|
|
|
64594
64646
|
const args = parseArgs2(DeployPutSecretArgsSchema, frame, "deploy:putSecret");
|
|
64595
64647
|
const dir = mustPersona(args.personaId);
|
|
64596
64648
|
const { manifest } = mustScan(await readHistory(dir), args.scanId);
|
|
64597
|
-
const declared = [...manifest.
|
|
64598
|
-
if (!declared) throw invalid(`\u6E05\u5355\u91CC\u6CA1\u6709\u53EB\u300C${args.name}\u300D\u7684\
|
|
64649
|
+
const declared = [...manifest.envVars, ...sharedConnectorSecrets(manifest)].find((s2) => s2.name === args.name);
|
|
64650
|
+
if (!declared) throw invalid(`\u6E05\u5355\u91CC\u6CA1\u6709\u53EB\u300C${args.name}\u300D\u7684\u73AF\u5883\u53D8\u91CF\u6216\u5171\u4EAB\u8FDE\u63A5\u5668`);
|
|
64599
64651
|
const allowed = new Set(declared.env);
|
|
64600
64652
|
for (const key of Object.keys(args.values)) {
|
|
64601
64653
|
if (!allowed.has(key)) throw invalid(`\u300C${args.name}\u300D\u6CA1\u6709\u58F0\u660E\u73AF\u5883\u53D8\u91CF ${key}`);
|
|
@@ -64881,6 +64933,7 @@ function buildDeployHandlers(deps) {
|
|
|
64881
64933
|
if (missing.length > 0) blockers.push(`${missing.join(" / ")} \u8FD8\u6CA1\u586B`);
|
|
64882
64934
|
if (engineAuthState(secrets) === "partial") blockers.push(ENGINE_AUTH_PARTIAL_BLOCKER);
|
|
64883
64935
|
for (const c2 of entry.manifest.connectors) blockers.push(...connectorBlockers(c2));
|
|
64936
|
+
blockers.push(...envVarBlockers(entry.manifest));
|
|
64884
64937
|
for (const p3 of entry.manifest.packages) blockers.push(...packageBlockers(p3));
|
|
64885
64938
|
const cloudEngine = cloudEngineSettings(deps.personaEngine(personaId2) ?? {});
|
|
64886
64939
|
if (!cloudEngine.model) {
|
|
@@ -76169,7 +76222,7 @@ function computeMethodAccess(args) {
|
|
|
76169
76222
|
}
|
|
76170
76223
|
|
|
76171
76224
|
// src/version.ts
|
|
76172
|
-
var version = "0.2.
|
|
76225
|
+
var version = "0.2.733".length > 0 ? "0.2.733" : "dev";
|
|
76173
76226
|
|
|
76174
76227
|
// src/cli-probe/probe.ts
|
|
76175
76228
|
var fs87 = __toESM(require("fs"), 1);
|
|
@@ -78949,6 +79002,23 @@ async function startDaemon(config) {
|
|
|
78949
79002
|
logger
|
|
78950
79003
|
});
|
|
78951
79004
|
};
|
|
79005
|
+
const resolvePersonaEnvVars = (personaId2) => {
|
|
79006
|
+
const file = import_node_path90.default.join(config.dataDir, "personas", personaId2, DEPLOY_FILE);
|
|
79007
|
+
let manifestText;
|
|
79008
|
+
try {
|
|
79009
|
+
manifestText = import_node_fs69.default.readFileSync(file, "utf8");
|
|
79010
|
+
} catch {
|
|
79011
|
+
return {};
|
|
79012
|
+
}
|
|
79013
|
+
try {
|
|
79014
|
+
const { env, missing } = personaEnvVars({ manifestText, secrets: readSecrets() });
|
|
79015
|
+
if (missing.length > 0) logger.warn("persona.env-vars.missing", { personaId: personaId2, names: missing });
|
|
79016
|
+
return env;
|
|
79017
|
+
} catch (err) {
|
|
79018
|
+
logger.warn("persona.env-vars.unreadable", { personaId: personaId2, message: err instanceof Error ? err.message : String(err) });
|
|
79019
|
+
return {};
|
|
79020
|
+
}
|
|
79021
|
+
};
|
|
78952
79022
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
78953
79023
|
const dispatchServerCandidates = [
|
|
78954
79024
|
import_node_path90.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
@@ -79140,6 +79210,7 @@ async function startDaemon(config) {
|
|
|
79140
79210
|
mcpConfigs,
|
|
79141
79211
|
// Render MCP configs outside the pure reducer because rendering performs filesystem IO.
|
|
79142
79212
|
resolvePersonaMcpConfig,
|
|
79213
|
+
resolvePersonaEnvVars,
|
|
79143
79214
|
generateTitle: (file, firstMessage, signal) => generateSessionTitle(file, firstMessage, {
|
|
79144
79215
|
logger,
|
|
79145
79216
|
signal,
|