






















@@ -3,10 +3,7 @@ import os from "node:os";
33import path from "node:path";
44import type { AuthProfileStore } from "../agents/auth-profiles/types.js";
55import { formatCliCommand } from "../cli/command-format.js";
6-import {
7-collectDurableServiceEnvVars,
8-readStateDirDotEnvVars,
9-} from "../config/state-dir-dotenv.js";
6+import { collectDurableServiceEnvVarSources } from "../config/state-dir-dotenv.js";
107import type { OpenClawConfig } from "../config/types.js";
118import { resolveSecretInputRef } from "../config/types.secrets.js";
129import { resolveGatewayLaunchAgentLabel } from "../daemon/constants.js";
@@ -16,11 +13,16 @@ import {
1613resolveGatewayProgramArguments,
1714resolveOpenClawWrapperPath,
1815} from "../daemon/program-args.js";
16+import {
17+addServiceEnvPlanEntries,
18+compactServiceEnvPlanValueSources,
19+createMutableServiceEnvPlan,
20+} from "../daemon/service-env-plan.js";
21+import { applyManagedServiceEnvRenderPolicy } from "../daemon/service-env-render-policy.js";
1922import { buildServiceEnvironment } from "../daemon/service-env.js";
2023import {
2124formatManagedServiceEnvKeys,
2225readManagedServiceEnvKeysFromEnvironment,
23-writeManagedServiceEnvKeysToEnvironment,
2426} from "../daemon/service-managed-env.js";
2527import { isNonMinimalServicePathEntry } from "../daemon/service-path-policy.js";
2628import type { GatewayServiceEnvironmentValueSource } from "../daemon/service-types.js";
@@ -395,35 +397,6 @@ function resolveGatewayInstallWorkingDirectory(params: {
395397return resolveGatewayStateDir(params.env);
396398}
397399398-function retainLaunchAgentManagedServiceEnvValues(params: {
399-environment: Record<string, string | undefined>;
400-durableEnvironment: Record<string, string | undefined>;
401-managedServiceEnvKeys: string | undefined;
402-stateDirDotEnvEnvironment: Record<string, string | undefined>;
403-serviceEnvironment: Record<string, string | undefined>;
404-platform: NodeJS.Platform;
405-}): void {
406-if (params.platform !== "darwin" || !params.serviceEnvironment.OPENCLAW_LAUNCHD_LABEL?.trim()) {
407-return;
408-}
409-const managedKeys = readManagedServiceEnvKeysFromEnvironment({
410-OPENCLAW_SERVICE_MANAGED_ENV_KEYS: params.managedServiceEnvKeys,
411-});
412-if (managedKeys.size === 0) {
413-return;
414-}
415-for (const [rawKey, value] of Object.entries(params.stateDirDotEnvEnvironment)) {
416-const key = normalizeEnvVarKey(rawKey, { portable: true })?.toUpperCase();
417-if (!key || !managedKeys.has(key) || typeof value !== "string" || !value.trim()) {
418-continue;
419-}
420-if (params.durableEnvironment[rawKey] !== value) {
421-continue;
422-}
423-params.environment[rawKey] = value;
424-}
425-}
426-427400async function buildGatewayInstallEnvironment(params: {
428401env: Record<string, string | undefined>;
429402config?: OpenClawConfig;
@@ -440,11 +413,11 @@ async function buildGatewayInstallEnvironment(params: {
440413environment: Record<string, string | undefined>;
441414environmentValueSources: Record<string, GatewayServiceEnvironmentValueSource | undefined>;
442415}> {
443-const stateDirDotEnvEnvironment = readStateDirDotEnvVars(params.env);
444-const durableEnvironment = collectDurableServiceEnvVars({
445-env: params.env,
446-config: params.config,
447-});
416+const { stateDirDotEnvEnvironment, configEnvironment, durableEnvironment } =
417+ collectDurableServiceEnvVarSources({
418+ env: params.env,
419+ config: params.config,
420+ });
448421const configSecretRefEnvironment = collectConfigSecretRefServiceEnvVars({
449422env: params.env,
450423config: params.config,
@@ -466,67 +439,48 @@ async function buildGatewayInstallEnvironment(params: {
466439params.existingEnvironment,
467440readManagedServiceEnvKeysFromEnvironment(params.existingEnvironment),
468441);
469-const environment: Record<string, string | undefined> = {
470- ...preservedExistingEnvironment,
471- ...durableEnvironment,
472- ...configSecretRefEnvironment,
473- ...execSecretRefPassEnvEnvironment,
474- ...authProfileEnvironment,
475-};
476-const environmentValueSources: Record<string, GatewayServiceEnvironmentValueSource | undefined> =
477-{};
478-for (const rawKey of Object.keys(preservedExistingEnvironment)) {
479-const normalizedKey = normalizeEnvVarKey(rawKey, { portable: true })?.toUpperCase();
480-environmentValueSources[rawKey] = normalizedKey
481- ? (readExistingEnvironmentValueSource({
482-existingEnvironmentValueSources: params.existingEnvironmentValueSources,
483- normalizedKey,
484-}) ?? "inline")
485- : "inline";
486-}
487-for (const key of Object.keys({
488- ...durableEnvironment,
489- ...configSecretRefEnvironment,
490- ...execSecretRefPassEnvEnvironment,
491- ...authProfileEnvironment,
492-})) {
493-environmentValueSources[key] = "inline";
494-}
442+const plan = createMutableServiceEnvPlan();
443+addServiceEnvPlanEntries(plan, preservedExistingEnvironment, {
444+source: "existing-preserved",
445+valueSource: ({ normalizedKey }) =>
446+readExistingEnvironmentValueSource({
447+existingEnvironmentValueSources: params.existingEnvironmentValueSources,
448+ normalizedKey,
449+}) ?? "inline",
450+});
451+addServiceEnvPlanEntries(plan, stateDirDotEnvEnvironment, { source: "state-dotenv" });
452+addServiceEnvPlanEntries(plan, configEnvironment, { source: "config-env" });
453+addServiceEnvPlanEntries(plan, configSecretRefEnvironment, { source: "config-secretref-env" });
454+addServiceEnvPlanEntries(plan, execSecretRefPassEnvEnvironment, { source: "exec-passenv" });
455+addServiceEnvPlanEntries(plan, authProfileEnvironment, { source: "auth-profile-env" });
495456const managedServiceEnvKeys = formatManagedServiceEnvKeys(durableEnvironment, {
496457omitKeys: Object.keys(params.serviceEnvironment),
497458});
498-writeManagedServiceEnvKeysToEnvironment(environment, managedServiceEnvKeys);
499-retainLaunchAgentManagedServiceEnvValues({
500- environment,
501- durableEnvironment,
459+applyManagedServiceEnvRenderPolicy({
460+ plan,
502461 managedServiceEnvKeys,
503- stateDirDotEnvEnvironment,
504462serviceEnvironment: params.serviceEnvironment,
505463platform: params.platform,
506464});
507-if (environment.OPENCLAW_SERVICE_MANAGED_ENV_KEYS) {
508-environmentValueSources.OPENCLAW_SERVICE_MANAGED_ENV_KEYS = "inline";
509-}
510-Object.assign(environment, params.serviceEnvironment);
511-for (const key of Object.keys(params.serviceEnvironment)) {
512-environmentValueSources[key] = "inline";
513-}
465+addServiceEnvPlanEntries(plan, params.serviceEnvironment, {
466+source: "service-generated",
467+includeRawKeys: true,
468+});
514469const mergedPath = mergeServicePath(
515470params.serviceEnvironment.PATH,
516471params.existingEnvironment?.PATH,
517472params.serviceEnvironment.TMPDIR,
518473params.platform,
519474);
520475if (mergedPath) {
521-environment.PATH = mergedPath;
522-environmentValueSources.PATH = "inline";
476+plan.environment.PATH = mergedPath;
477+plan.environmentValueSources.PATH = "inline";
523478}
524-for (const key of Object.keys(environmentValueSources)) {
525-if (!Object.hasOwn(environment, key)) {
526-delete environmentValueSources[key];
527-}
528-}
529-return { environment, environmentValueSources };
479+compactServiceEnvPlanValueSources(plan);
480+return {
481+environment: plan.environment,
482+environmentValueSources: plan.environmentValueSources,
483+};
530484}
531485532486export async function buildGatewayInstallPlan(params: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。