
































@@ -243,7 +243,7 @@ describe("buildGatewayInstallPlan", () => {
243243expect(plan.environment.OPENCLAW_WRAPPER).toBe(wrapperPath);
244244});
245245246-it("merges safe config env while dropping unsafe values and keeping service precedence", async () => {
246+it("tracks safe config env keys without embedding literal values", async () => {
247247mockNodeGatewayPlanFixture({
248248serviceEnvironment: {
249249HOME: "/Users/service",
@@ -271,16 +271,16 @@ describe("buildGatewayInstallPlan", () => {
271271},
272272});
273273274-expect(plan.environment.GOOGLE_API_KEY).toBe("test-key");
275-expect(plan.environment.CUSTOM_VAR).toBe("custom-value");
276-expect(plan.environment.SAFE_KEY).toBe("safe-value");
274+expect(plan.environment.GOOGLE_API_KEY).toBeUndefined();
275+expect(plan.environment.CUSTOM_VAR).toBeUndefined();
276+expect(plan.environment.SAFE_KEY).toBeUndefined();
277277expect(plan.environment.NODE_OPTIONS).toBeUndefined();
278278expect(plan.environment.EMPTY_KEY).toBeUndefined();
279279expect(plan.environment.TRIMMED_KEY).toBeUndefined();
280280expect(plan.environment.HOME).toBe("/Users/service");
281281expect(plan.environment.OPENCLAW_PORT).toBe("3000");
282282expect(plan.environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS).toBe(
283-"CUSTOM_VAR,GOOGLE_API_KEY,OPENCLAW_PORT,SAFE_KEY",
283+"CUSTOM_VAR,GOOGLE_API_KEY,SAFE_KEY",
284284);
285285});
286286@@ -328,6 +328,7 @@ describe("buildGatewayInstallPlan", () => {
328328});
329329330330expect(plan.environment.OPENAI_API_KEY).toBe("sk-openai-test");
331+expect(plan.environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS).toBeUndefined();
331332expect(mocks.hasAnyAuthProfileStoreSource).not.toHaveBeenCalled();
332333expect(mocks.loadAuthProfileStoreForSecretsRuntime).not.toHaveBeenCalled();
333334});
@@ -393,6 +394,7 @@ describe("buildGatewayInstallPlan", () => {
393394expect(plan.environment.MISSING_TOKEN).toBeUndefined();
394395expect(plan.environment.OPENAI_API_KEY).toBe("sk-openai-test");
395396expect(plan.environment.ANTHROPIC_TOKEN).toBe("ant-test-token");
397+expect(plan.environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS).toBeUndefined();
396398expect(warn).toHaveBeenCalledWith(expect.stringContaining("NODE_OPTIONS"), "Auth profile");
397399expect(warn).toHaveBeenCalledWith(expect.stringContaining("GIT_ASKPASS"), "Auth profile");
398400});
@@ -409,7 +411,7 @@ describe("buildGatewayInstallPlan — dotenv merge", () => {
409411fs.rmSync(tmpDir, { recursive: true, force: true });
410412});
411413412-it("merges .env vars with config and service precedence", async () => {
414+it("tracks .env vars with config while preserving service precedence", async () => {
413415await writeStateDirDotEnv(
414416"BRAVE_API_KEY=BSA-from-env\nOPENROUTER_API_KEY=or-key\nMY_KEY=from-dotenv\nHOME=/from-dotenv\n",
415417{
@@ -436,11 +438,14 @@ describe("buildGatewayInstallPlan — dotenv merge", () => {
436438},
437439});
438440439-expect(plan.environment.BRAVE_API_KEY).toBe("BSA-from-env");
440-expect(plan.environment.OPENROUTER_API_KEY).toBe("or-key");
441-expect(plan.environment.MY_KEY).toBe("from-config");
441+expect(plan.environment.BRAVE_API_KEY).toBeUndefined();
442+expect(plan.environment.OPENROUTER_API_KEY).toBeUndefined();
443+expect(plan.environment.MY_KEY).toBeUndefined();
442444expect(plan.environment.HOME).toBe("/from-service");
443445expect(plan.environment.OPENCLAW_PORT).toBe("3000");
446+expect(plan.environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS).toBe(
447+"BRAVE_API_KEY,MY_KEY,OPENROUTER_API_KEY",
448+);
444449});
445450446451it("works when .env file does not exist", async () => {
@@ -515,6 +520,66 @@ describe("buildGatewayInstallPlan — dotenv merge", () => {
515520expect(plan.environment.GOPATH).toBeUndefined();
516521expect(plan.environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS).toBeUndefined();
517522});
523+524+it("drops legacy inline env values when the key is now managed by .env", async () => {
525+await writeStateDirDotEnv("TAVILY_API_KEY=fresh-dotenv-value\n", {
526+stateDir: path.join(tmpDir, ".openclaw"),
527+});
528+mockNodeGatewayPlanFixture({
529+serviceEnvironment: {
530+HOME: "/from-service",
531+OPENCLAW_PORT: "3000",
532+},
533+});
534+535+const plan = await buildGatewayInstallPlan({
536+env: { HOME: tmpDir },
537+port: 3000,
538+runtime: "node",
539+existingEnvironment: {
540+TAVILY_API_KEY: "old-inline-value",
541+CUSTOM_TOOL_HOME: "/Users/test/.custom-tool",
542+},
543+});
544+545+expect(plan.environment.TAVILY_API_KEY).toBeUndefined();
546+expect(plan.environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS).toBe("TAVILY_API_KEY");
547+expect(plan.environment.CUSTOM_TOOL_HOME).toBe("/Users/test/.custom-tool");
548+});
549+550+it("does not embed auth-profile env refs when the key is already durable", async () => {
551+await writeStateDirDotEnv("OPENAI_API_KEY=dotenv-openai\n", {
552+stateDir: path.join(tmpDir, ".openclaw"),
553+});
554+mockNodeGatewayPlanFixture({
555+serviceEnvironment: {
556+HOME: "/from-service",
557+OPENCLAW_PORT: "3000",
558+},
559+});
560+561+const plan = await buildGatewayInstallPlan({
562+env: {
563+HOME: tmpDir,
564+OPENAI_API_KEY: "shell-openai",
565+},
566+port: 3000,
567+runtime: "node",
568+authStore: {
569+version: 1,
570+profiles: {
571+"openai:default": {
572+type: "api_key",
573+provider: "openai",
574+keyRef: { source: "env", provider: "default", id: "OPENAI_API_KEY" },
575+},
576+},
577+},
578+});
579+580+expect(plan.environment.OPENAI_API_KEY).toBeUndefined();
581+expect(plan.environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS).toBe("OPENAI_API_KEY");
582+});
518583});
519584520585describe("gatewayInstallErrorHint", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。