@clawos-dev/clawd 0.2.732 → 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.
@@ -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
- secrets: external_exports.array(EnvSecretSchema),
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
- * 不复用 secrets:那段说的是「需要一份值,由部署者填」;连接器的凭据谁出是单据上点出来的,
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' / 'secret:aliyun-ak' / 'connector:feishu'
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", "secret", "connector"]),
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\uFF08cli / secret / asset\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u9875\u9762\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\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",
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.secrets.flatMap((s2) => s2.env), ...sharedConnectorSecrets(m3).flatMap((s2) => s2.env)])];
6177
+ return [.../* @__PURE__ */ new Set([...m3.envVars.flatMap((s2) => s2.env), ...sharedConnectorSecrets(m3).flatMap((s2) => s2.env)])];
6178
6178
  }
6179
- 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, GO_SPEC_RE, GO_MOVING_REFS, normalizeLegacyManifest, PUBLISHER_TEST_NOTE_PREFIX, PublisherTestSchema, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
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
- secrets: external_exports.array(EnvSecretSchema),
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
- * 不复用 secrets:那段说的是「需要一份值,由部署者填」;连接器的凭据谁出是单据上点出来的,
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' / 'secret:aliyun-ak' / 'connector:feishu'
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", "secret", "connector"]),
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\uFF08cli / secret / asset\uFF09\u3002**\u8FB9\u626B\u8FB9\u62A5**\uFF0C\u9875\u9762\u968F\u4E4B\u4E00\u70B9\u70B9\u586B\u5145\uFF1B\u540C (kind,name) \u91CD\u590D\u4E0A\u62A5\u5373\u8986\u76D6\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",
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
- return target.startsWith("cli:") ? { ...e, target: `package:${target.slice("cli:".length)}` } : e;
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: [], secrets: [], connectors: [] } };
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
- secret: EnvSecretSchema,
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" : "secrets";
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);
@@ -64606,8 +64646,8 @@ function buildDeployHandlers(deps) {
64606
64646
  const args = parseArgs2(DeployPutSecretArgsSchema, frame, "deploy:putSecret");
64607
64647
  const dir = mustPersona(args.personaId);
64608
64648
  const { manifest } = mustScan(await readHistory(dir), args.scanId);
64609
- const declared = [...manifest.secrets, ...sharedConnectorSecrets(manifest)].find((s2) => s2.name === args.name);
64610
- if (!declared) throw invalid(`\u6E05\u5355\u91CC\u6CA1\u6709\u53EB\u300C${args.name}\u300D\u7684\u51ED\u636E`);
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`);
64611
64651
  const allowed = new Set(declared.env);
64612
64652
  for (const key of Object.keys(args.values)) {
64613
64653
  if (!allowed.has(key)) throw invalid(`\u300C${args.name}\u300D\u6CA1\u6709\u58F0\u660E\u73AF\u5883\u53D8\u91CF ${key}`);
@@ -64893,6 +64933,7 @@ function buildDeployHandlers(deps) {
64893
64933
  if (missing.length > 0) blockers.push(`${missing.join(" / ")} \u8FD8\u6CA1\u586B`);
64894
64934
  if (engineAuthState(secrets) === "partial") blockers.push(ENGINE_AUTH_PARTIAL_BLOCKER);
64895
64935
  for (const c2 of entry.manifest.connectors) blockers.push(...connectorBlockers(c2));
64936
+ blockers.push(...envVarBlockers(entry.manifest));
64896
64937
  for (const p3 of entry.manifest.packages) blockers.push(...packageBlockers(p3));
64897
64938
  const cloudEngine = cloudEngineSettings(deps.personaEngine(personaId2) ?? {});
64898
64939
  if (!cloudEngine.model) {
@@ -76181,7 +76222,7 @@ function computeMethodAccess(args) {
76181
76222
  }
76182
76223
 
76183
76224
  // src/version.ts
76184
- var version = "0.2.732".length > 0 ? "0.2.732" : "dev";
76225
+ var version = "0.2.733".length > 0 ? "0.2.733" : "dev";
76185
76226
 
76186
76227
  // src/cli-probe/probe.ts
76187
76228
  var fs87 = __toESM(require("fs"), 1);
@@ -78961,6 +79002,23 @@ async function startDaemon(config) {
78961
79002
  logger
78962
79003
  });
78963
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
+ };
78964
79022
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
78965
79023
  const dispatchServerCandidates = [
78966
79024
  import_node_path90.default.join(here, "dispatch", "mcp-server.cjs"),
@@ -79152,6 +79210,7 @@ async function startDaemon(config) {
79152
79210
  mcpConfigs,
79153
79211
  // Render MCP configs outside the pure reducer because rendering performs filesystem IO.
79154
79212
  resolvePersonaMcpConfig,
79213
+ resolvePersonaEnvVars,
79155
79214
  generateTitle: (file, firstMessage, signal) => generateSessionTitle(file, firstMessage, {
79156
79215
  logger,
79157
79216
  signal,