@omercnet/paseo-omp 0.4.0-next.134.1 → 0.4.0-next.138.1

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/README.md CHANGED
@@ -86,12 +86,12 @@ Provider functionality outside the capability flags is tracked separately:
86
86
  | Provider SDK surface | Completeness | Implementation |
87
87
  | --- | ---: | --- |
88
88
  | Registration metadata and sanitized SVG icon | **100%** | Stable `omp-plugin` identity, label, description, and bundled icon. |
89
- | Strict `providerOptionsSchema` | **100%** | Command, literal and names-only inherited environment, output-redaction mode, session directory, RPC timeout, and role-model options are validated and normalized. |
89
+ | Strict `providerOptionsSchema` | **100%** | Command, literal environment, names-only profile inherited environment, output-redaction mode, session directory, RPC timeout, and role-model options are validated and normalized. Host-wide inherited names are separately persisted and merged at launch. |
90
90
  | Availability diagnostics | **100%** | Bounded checks distinguish missing, unrunnable, incompatible, and available OMP runtimes. |
91
- | Catalog cache identity | **100%** | Hash includes effective options, configured inherited-environment names, settings, scope, cwd, and default command, but never resolves or fingerprints inherited values. |
91
+ | Catalog cache identity | **100%** | Hash includes effective options, merged host/profile inherited-environment names, settings, scope, cwd, and default command, but never resolves or fingerprints inherited values. |
92
92
  | Models, modes, and thinking catalog | **100%** | Native catalog is mapped to opaque public model IDs with committed defaults and permission-gated modes. |
93
93
  | Connection `send` / `onEvent` / `close` lifecycle | **100%** | Request correlation, multi-session ownership, process recovery, teardown, and provider reload/removal are covered. |
94
- | Session launch: cwd, env, system prompt, title, and persistence | **100%** | Complete launch configuration is bounded, validated, forwarded, and re-read on recovery; selected daemon environment values are resolved only when catalog and session children spawn. |
94
+ | Session launch: cwd, env, system prompt, title, and persistence | **100%** | Complete launch configuration is bounded, validated, forwarded, and re-read on recovery; selected host and profile daemon environment values are resolved only when catalog and session children spawn. |
95
95
  | MCP server forwarding and host tools | **100%** | Configured MCP tools are discovered, namespaced, labeled, executed, canceled, and bounded. Caller-scoped Paseo orchestration tools retain their native names, such as `create_agent` and `list_profiles`, so OMP skills can invoke them directly. The MCP composer control delegates native server management to OMP instead of duplicating its profile and workspace precedence. Exact `toolPolicy` remains the separate 0% capability above. |
96
96
  | Denied native tools | **100%** | `disallowedTools` becomes an explicit OMP allow-list; unknown names fail closed. |
97
97
  | Commands and committed session state events | **100%** | Publishes `session.commands`, `session.opened`, `session.config`, `session.ready`, and request completion in protocol order. |
@@ -121,7 +121,7 @@ Install, update, disable, or remove `paseo-omp` independently of the bundled pro
121
121
 
122
122
  The plugin validates OMP protocol data and bounds public strings and structured values. It does not heuristically redact or rewrite content produced by native OMP, models, or tools. Do not put credentials in prompts or tool output, because that content may be published unchanged after validation and bounding.
123
123
 
124
- `providerOptions.outputRedaction` defaults to `none`, preserving native content subject to those bounds. `configured-values` provides best-effort literal replacement for explicitly supplied credential values and every non-empty daemon value selected through `inheritEnv`, regardless of its name. It does not detect generated secrets or encoded, transformed, or independently streamed fragments of configured values. Centralized Paseo policy is required when a deployment needs redaction guarantees.
124
+ `providerOptions.outputRedaction` defaults to `none`, preserving native content subject to those bounds. `configured-values` provides best-effort literal replacement for explicitly supplied credential values and every non-empty daemon value selected through host or profile `inheritEnv`, regardless of its name. It does not detect generated secrets or encoded, transformed, or independently streamed fragments of configured values. Centralized Paseo policy is required when a deployment needs redaction guarantees.
125
125
 
126
126
  Unexpected or internal launch failures use fixed fallback messages rather than serializing the launch configuration. Explicit public validation errors may include caller-supplied configuration names or values. Deployments that require host-wide content redaction should implement it in a dedicated host or plugin layer rather than this protocol adapter.
127
127
 
@@ -63,6 +63,7 @@ import {
63
63
  summarizeProviderStatus,
64
64
  summarizeRpcUiSupport,
65
65
  } from "./provider-diagnostics-state";
66
+ import { ProviderLaunchSettingsSection } from "./provider-launch-settings";
66
67
  import {
67
68
  refreshSupportReport,
68
69
  type SupportReportCopyState,
@@ -141,8 +142,10 @@ function ProviderSetupSection({ styles }: { styles: OmpConfigStyles }) {
141
142
  return (
142
143
  <SectionCard styles={styles} title="OMP Plugin">
143
144
  <Text style={styles.muted}>
144
- Launch settings currently come from the active Paseo provider profile.
145
+ Host-wide inherited environment names apply to every OMP provider. Profile launch overrides
146
+ remain available for narrower exceptions.
145
147
  </Text>
148
+ <KeyValueRow styles={styles} label="Host policy" value="Inherited daemon environment names" />
146
149
  <KeyValueRow
147
150
  styles={styles}
148
151
  label="Per agent"
@@ -151,7 +154,7 @@ function ProviderSetupSection({ styles }: { styles: OmpConfigStyles }) {
151
154
  <KeyValueRow
152
155
  styles={styles}
153
156
  label="Provider profile"
154
- value="Command, environment, session directory, RPC timeout, role models, and denied tools"
157
+ value="Command, additional environment, session directory, RPC timeout, role models, and denied tools"
155
158
  />
156
159
  </SectionCard>
157
160
  );
@@ -162,15 +165,15 @@ function PluginConfigurationSection({ styles }: { styles: OmpConfigStyles }) {
162
165
  <>
163
166
  <SectionCard styles={styles} title="OMP Plugin launch options">
164
167
  <Text style={styles.muted}>
165
- Paseo does not expose the effective providerOptions for active launches through the plugin
166
- API. Configure these values in the provider profile; this tab documents the supported
167
- contract without claiming defaults are active.
168
+ Configure inherited daemon environment names below. Paseo does not expose effective
169
+ profile options for active launches, so this tab documents profile overrides without
170
+ claiming they are active.
168
171
  </Text>
169
172
  <KeyValueRow styles={styles} label="Command" value="Executable and argument prefix" />
170
173
  <KeyValueRow
171
174
  styles={styles}
172
175
  label="Inherited environment"
173
- value="Daemon variable names copied at OMP spawn time"
176
+ value="Additional profile names copied at OMP spawn time"
174
177
  />
175
178
  <KeyValueRow
176
179
  styles={styles}
@@ -1125,7 +1128,12 @@ function OmpConfigContent({
1125
1128
  </>
1126
1129
  ) : null}
1127
1130
 
1128
- {view === "plugin" ? <PluginConfigurationSection styles={styles} /> : null}
1131
+ {view === "plugin" ? (
1132
+ <>
1133
+ <PluginConfigurationSection styles={styles} />
1134
+ {!cwd ? <ProviderLaunchSettingsSection theme={theme} /> : null}
1135
+ </>
1136
+ ) : null}
1129
1137
 
1130
1138
  {view === "plugins" ? (
1131
1139
  <OmpPluginManagerSection theme={theme} compact={layout.compact} cwd={cwd} store={store} />
@@ -0,0 +1,118 @@
1
+ import { type PluginSurfaceProps, type SettingsState, useSettings } from "@getpaseo/plugin/client";
2
+ import {
3
+ SettingsAction,
4
+ SettingsCard,
5
+ SettingsInput,
6
+ SettingsSection,
7
+ } from "@getpaseo/plugin/client/ui";
8
+ import { useCallback, useEffect, useMemo, useState } from "react";
9
+ import { Text, View } from "react-native";
10
+ import {
11
+ providerLaunchSettings,
12
+ providerLaunchSettingsSchema,
13
+ } from "../shared/provider-launch-settings";
14
+
15
+ type ReadySettings = Extract<
16
+ SettingsState<typeof providerLaunchSettings.schema>,
17
+ { status: "ready" }
18
+ >;
19
+
20
+ function ProviderLaunchSettingsControls({ settings }: { settings: ReadySettings }) {
21
+ const savedNames = settings.values.inheritEnv.join(", ");
22
+ const [rawNames, setRawNames] = useState(() => savedNames);
23
+ useEffect(() => {
24
+ setRawNames(savedNames);
25
+ }, [savedNames]);
26
+ const inheritEnv = [
27
+ ...new Set(
28
+ rawNames
29
+ .split(",")
30
+ .map((name) => name.trim())
31
+ .filter(Boolean),
32
+ ),
33
+ ];
34
+ const next = providerLaunchSettingsSchema.safeParse({ inheritEnv });
35
+ const error = next.success
36
+ ? null
37
+ : (next.error.issues[0]?.message ?? "Enter valid variable names.");
38
+ const save = useCallback(async () => {
39
+ if (!next.success) return;
40
+ await settings.save(next.data, settings.revision);
41
+ }, [next, settings]);
42
+
43
+ return (
44
+ <View style={{ gap: 12 }}>
45
+ <SettingsSection
46
+ title="Inherited environment"
47
+ info="Applies to every OMP Plugin agent on this host. Names are stored, but values are read only from the daemon environment when OMP starts."
48
+ >
49
+ <SettingsCard>
50
+ <SettingsInput
51
+ key={savedNames}
52
+ label="Daemon variable names"
53
+ hint="Comma-separated names. Each selected value is available to OMP and its child processes."
54
+ initialValue={savedNames}
55
+ onChangeText={setRawNames}
56
+ placeholder="ACME_OMP_API_KEY, ACME_OMP_URL"
57
+ error={error ?? undefined}
58
+ disabled={settings.saving}
59
+ />
60
+ <SettingsAction
61
+ label="Save inherited environment"
62
+ hint="Profile-specific names remain additive for narrow exceptions."
63
+ actionLabel="Save"
64
+ disabled={settings.saving || rawNames === savedNames || !next.success}
65
+ onPress={() => void save()}
66
+ />
67
+ <SettingsAction
68
+ label="Clear inherited environment"
69
+ actionLabel="Clear"
70
+ disabled={settings.saving || settings.values.inheritEnv.length === 0}
71
+ onPress={async () => {
72
+ if (await settings.save({ inheritEnv: [] }, settings.revision)) setRawNames("");
73
+ }}
74
+ />
75
+ {settings.saveError ? (
76
+ <SettingsAction
77
+ label="Reload host launch settings"
78
+ error={settings.saveError}
79
+ actionLabel="Reload"
80
+ disabled={settings.saving}
81
+ onPress={settings.reload}
82
+ />
83
+ ) : null}
84
+ </SettingsCard>
85
+ </SettingsSection>
86
+ </View>
87
+ );
88
+ }
89
+
90
+ export function ProviderLaunchSettingsSection({ theme }: { theme: PluginSurfaceProps["theme"] }) {
91
+ const settings = useSettings(providerLaunchSettings);
92
+ const styles = useMemo(
93
+ () => ({
94
+ root: { gap: 12 },
95
+ text: { color: theme.colors.foreground },
96
+ error: { color: theme.colors.statusDanger },
97
+ }),
98
+ [theme],
99
+ );
100
+
101
+ if (settings.status === "loading")
102
+ return <Text style={styles.text}>Loading host launch settings…</Text>;
103
+ if (settings.status !== "ready") {
104
+ return (
105
+ <View style={styles.root}>
106
+ <Text accessibilityRole="alert" style={styles.error}>
107
+ {settings.error}
108
+ </Text>
109
+ <SettingsAction
110
+ label="Read host launch settings again"
111
+ actionLabel="Reload"
112
+ onPress={settings.reload}
113
+ />
114
+ </View>
115
+ );
116
+ }
117
+ return <ProviderLaunchSettingsControls settings={settings} />;
118
+ }
package/index.server.ts CHANGED
@@ -24,6 +24,7 @@ import {
24
24
  discoverOmpProfilesSync,
25
25
  } from "./server/provider/profile-providers";
26
26
  import { createOmpProvider } from "./server/provider/registration";
27
+ import { OmpPublicError } from "./server/provider/security";
27
28
  import { resolveGetOmpProviderHealth } from "./server/provider-diagnostics";
28
29
  import { resolveListOmpQuotas } from "./server/quota";
29
30
  import { resolveListOmpSessions } from "./server/sessions";
@@ -43,6 +44,7 @@ import {
43
44
  import { listOmpSettings, updateOmpSettings } from "./shared/omp-settings";
44
45
  import { listOmpStores, type OmpStore } from "./shared/omp-store";
45
46
  import { getOmpProviderHealth } from "./shared/provider-diagnostics";
47
+ import { providerLaunchSettings } from "./shared/provider-launch-settings";
46
48
  import { listOmpQuotas } from "./shared/quota";
47
49
  import { listOmpSessions } from "./shared/sessions";
48
50
  import { getOmpSupportReport } from "./shared/support-diagnostics";
@@ -53,6 +55,12 @@ function scoped<T extends { store?: OmpStore }, R>(handler: (input: T) => R) {
53
55
 
54
56
  export default function contribute(server: PluginServerContext) {
55
57
  server.registerSettings(composerPillSettings);
58
+ const launchSettings = server.registerSettings(providerLaunchSettings);
59
+ const resolveHostInheritEnv = async (): Promise<readonly string[]> => {
60
+ const current = await launchSettings.read();
61
+ if (current.status === "ready") return current.values.inheritEnv;
62
+ throw new OmpPublicError("OMP host launch settings are unavailable");
63
+ };
56
64
  const browserAuthorizationRegistry = new OmpBrowserAuthorizationRegistry();
57
65
  const protocolViolations = new OmpProtocolViolationCollector();
58
66
  const operationalFailures = new OmpOperationalFailureCollector();
@@ -64,6 +72,7 @@ export default function contribute(server: PluginServerContext) {
64
72
  browserAuthorizationRegistry,
65
73
  reportProtocolViolation: protocolViolations.report,
66
74
  reportOperationalFailure: operationalFailures.report,
75
+ resolveHostInheritEnv,
67
76
  }),
68
77
  );
69
78
  }
@@ -97,6 +106,7 @@ export default function contribute(server: PluginServerContext) {
97
106
  browserAuthorizationRegistry,
98
107
  reportProtocolViolation: protocolViolations.report,
99
108
  reportOperationalFailure: operationalFailures.report,
109
+ resolveHostInheritEnv,
100
110
  }),
101
111
  );
102
112
  return () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omercnet/paseo-omp",
3
- "version": "0.4.0-next.134.1",
3
+ "version": "0.4.0-next.138.1",
4
4
  "type": "module",
5
5
  "description": "Paseo integration for OMP, including its direct provider and workspace tooling.",
6
6
  "license": "MIT",
@@ -1,2 +1,2 @@
1
1
  /** Release Please keeps this bundle-safe constant aligned with package.json. */
2
- export const PASEO_OMP_PACKAGE_VERSION = "0.4.0-next.134.1"; // x-release-please-version
2
+ export const PASEO_OMP_PACKAGE_VERSION = "0.4.0-next.138.1"; // x-release-please-version
@@ -9,6 +9,7 @@ type ProviderCatalogOptionsCompat = {
9
9
  settings?: Readonly<Record<string, unknown>>;
10
10
  };
11
11
 
12
+ import { MAX_INHERITED_ENVIRONMENT_NAMES } from "../../shared/provider-launch-settings";
12
13
  import { parseOmpProviderOptions } from "./provider-options";
13
14
  import { OmpPublicError } from "./security";
14
15
  import { OmpModeSchema } from "./settings";
@@ -59,11 +60,24 @@ function allowedOmpTools(deniedTools: readonly string[] | undefined): string[] |
59
60
 
60
61
  export type NormalizedOmpStartOptions = Omit<OmpStartOptions, "environment" | "signal">;
61
62
  export type OmpRecoveryOptions = Omit<OmpStartOptions, "resumeSessionId" | "signal">;
63
+ export function mergeOmpInheritedEnvironmentNames(
64
+ hostNames: readonly string[],
65
+ profileNames: readonly string[] | undefined,
66
+ ): string[] | undefined {
67
+ const names = [...new Set([...hostNames, ...(profileNames ?? [])])];
68
+ if (names.length > MAX_INHERITED_ENVIRONMENT_NAMES) {
69
+ throw new OmpPublicError("OMP inherited environment has too many entries");
70
+ }
71
+ return names.length > 0 ? names : undefined;
72
+ }
73
+
62
74
  export function normalizeOmpCatalogOptions(
63
75
  options: ProviderCatalogOptionsCompat,
64
76
  cwd: string,
77
+ hostInheritEnv: readonly string[] = [],
65
78
  ): Omit<OmpStartOptions, "environment" | "signal"> {
66
79
  const providerOptions = parseOmpProviderOptions(options.providerOptions);
80
+ const inheritEnv = mergeOmpInheritedEnvironmentNames(hostInheritEnv, providerOptions.inheritEnv);
67
81
  const params = providerOptions.params ?? {};
68
82
  return {
69
83
  cwd,
@@ -71,7 +85,7 @@ export function normalizeOmpCatalogOptions(
71
85
  noSession: true,
72
86
  ...(providerOptions.command ? { command: providerOptions.command } : {}),
73
87
  ...(providerOptions.env ? { env: providerOptions.env } : {}),
74
- ...(providerOptions.inheritEnv ? { inheritEnv: providerOptions.inheritEnv } : {}),
88
+ ...(inheritEnv ? { inheritEnv } : {}),
75
89
  outputRedaction: providerOptions.outputRedaction,
76
90
  ...(params.sessionDir ? { sessionDir: params.sessionDir } : {}),
77
91
  ...(params.rpcTimeoutMs
@@ -103,6 +117,7 @@ export function withCommittedOmpSelection(
103
117
  export function normalizeOmpSessionConfig(
104
118
  config: ProviderSessionConfig,
105
119
  permissionSupported = false,
120
+ hostInheritEnv: readonly string[] = [],
106
121
  ): NormalizedOmpStartOptions {
107
122
  if (Object.keys(config.settings).length > 0) {
108
123
  throw new OmpPublicError("OMP does not expose live provider settings");
@@ -122,11 +137,12 @@ export function normalizeOmpSessionConfig(
122
137
  const tools = allowedOmpTools(deniedTools);
123
138
  const params = options.params ?? {};
124
139
  const env = { ...options.env, ...config.env };
140
+ const inheritEnv = mergeOmpInheritedEnvironmentNames(hostInheritEnv, options.inheritEnv);
125
141
  return {
126
142
  cwd: config.cwd,
127
143
  ...(options.command ? { command: options.command } : {}),
128
144
  ...(Object.keys(env).length > 0 ? { env } : {}),
129
- ...(options.inheritEnv ? { inheritEnv: options.inheritEnv } : {}),
145
+ ...(inheritEnv ? { inheritEnv } : {}),
130
146
  outputRedaction: options.outputRedaction,
131
147
  mode: parsedMode.data,
132
148
  thinkingOption: config.thinkingOption,
@@ -715,6 +715,7 @@ export function createOmpConnection(
715
715
  reportDiagnostic: (diagnostic: OmpConnectionDiagnostic) => void = (diagnostic) =>
716
716
  console.error("OMP provider failure", diagnostic),
717
717
  reportOperationalFailure: OmpOperationalFailureReporter = () => {},
718
+ resolveHostInheritEnv?: () => Promise<readonly string[]>,
718
719
  ): ProviderConnection {
719
720
  const errorDetails = (error: unknown, fallback: string): { message: string } => {
720
721
  if (isOmpPublicError(error)) return { message: error.message };
@@ -822,6 +823,7 @@ export function createOmpConnection(
822
823
  settings: configuredInput.settings,
823
824
  },
824
825
  input.cwd ?? homedir(),
826
+ (await resolveHostInheritEnv?.()) ?? [],
825
827
  );
826
828
  const catalog = await discoverOmpCatalog(
827
829
  runtime,
@@ -968,6 +970,7 @@ export function createOmpConnection(
968
970
  mcpConnector,
969
971
  mcpInitializationTimeoutMs,
970
972
  reportOperationalFailure,
973
+ (await resolveHostInheritEnv?.()) ?? [],
971
974
  );
972
975
  const discoveredNativeSessionId = session.persistenceSessionId;
973
976
  if (discoveredNativeSessionId) nativeSessionId = discoveredNativeSessionId;
@@ -5,6 +5,7 @@ import { z } from "zod";
5
5
  import type { OmpBrowserAuthorizationRegistry } from "../mcp-browser";
6
6
  import type { OmpOperationalFailureReporter } from "../operational-failure-diagnostics";
7
7
  import { probeOmpAvailability } from "../provider-diagnostics";
8
+ import { mergeOmpInheritedEnvironmentNames } from "./config-normalization";
8
9
  import { createOmpConnection, OmpNativeSessionReservations } from "./connection";
9
10
  import type { OmpMcpConnector } from "./host-tools";
10
11
  import { OmpRpcRuntime, type OmpRuntime } from "./omp-rpc";
@@ -74,6 +75,7 @@ export interface OmpProviderOptions {
74
75
  options: ProviderCatalogOptionsCompat,
75
76
  timeoutMs: number | undefined,
76
77
  ) => Promise<ProviderAvailabilityCompat>;
78
+ resolveHostInheritEnv?: () => Promise<readonly string[]>;
77
79
  }
78
80
 
79
81
  function stableJson(value: unknown): string {
@@ -104,6 +106,10 @@ export function createOmpProvider(options: OmpProviderOptions = {}): ProviderReg
104
106
  providerOptionsSchema: OmpProviderOptionsSchema,
105
107
  async getCatalogCacheKey(catalogOptions) {
106
108
  const providerOptions = parseOmpProviderOptions(catalogOptions.providerOptions);
109
+ const inheritEnv = mergeOmpInheritedEnvironmentNames(
110
+ (await options.resolveHostInheritEnv?.()) ?? [],
111
+ providerOptions.inheritEnv,
112
+ );
107
113
  // Profile providers cannot safely hash explicit environment values because they may be
108
114
  // credentials. Disable sharing for that case; otherwise retain every normalized option
109
115
  // that can change discovery alongside the fixed, non-secret store identity.
@@ -112,7 +118,7 @@ export function createOmpProvider(options: OmpProviderOptions = {}): ProviderReg
112
118
  scope: catalogOptions.scope,
113
119
  ...(catalogOptions.scope === "workspace" ? { cwd: catalogOptions.cwd } : {}),
114
120
  ...(options.catalogIdentity ? { store: options.catalogIdentity } : {}),
115
- providerOptions,
121
+ providerOptions: { ...providerOptions, ...(inheritEnv ? { inheritEnv } : {}) },
116
122
  settings: catalogOptions.settings ?? {},
117
123
  defaultCommand: (options.environment ?? process.env).OMP_COMMAND ?? "omp",
118
124
  };
@@ -167,6 +173,7 @@ export function createOmpProvider(options: OmpProviderOptions = {}): ProviderReg
167
173
  options.browserAuthorizationRegistry,
168
174
  undefined,
169
175
  options.reportOperationalFailure,
176
+ options.resolveHostInheritEnv,
170
177
  );
171
178
  },
172
179
  };
@@ -451,6 +451,7 @@ export class OmpProviderSession {
451
451
  mcpConnector?: OmpMcpConnector,
452
452
  mcpInitializationTimeoutMs?: number,
453
453
  reportOperationalFailure: OmpOperationalFailureReporter = () => {},
454
+ hostInheritEnv: readonly string[] = [],
454
455
  ): Promise<OmpProviderSession> {
455
456
  const resumeSessionId = ompPersistenceSessionId(input);
456
457
  if (resumeSessionId && !input.config.persist) {
@@ -466,6 +467,7 @@ export class OmpProviderSession {
466
467
  const normalizedConfig = normalizeOmpSessionConfig(
467
468
  effectiveConfig,
468
469
  capabilities.includes("permission"),
470
+ hostInheritEnv,
469
471
  );
470
472
  const configuredRedactionValues = configuredOutputRedactionValues(
471
473
  normalizedConfig.outputRedaction ?? "none",
@@ -1,11 +1,14 @@
1
1
  import { z } from "zod";
2
+ import {
3
+ environmentNameSchema,
4
+ MAX_INHERITED_ENVIRONMENT_NAMES,
5
+ } from "../../shared/provider-launch-settings";
2
6
 
3
7
  const MAX_COMMAND_PARTS = 64;
4
- const MAX_ENV_ENTRIES = 256;
5
- const MAX_TEXT_BYTES = 64 * 1024;
6
- const MAX_MODEL_SELECTOR_BYTES = 513;
7
8
  const MAX_PATH_BYTES = 4_096;
8
9
  const MAX_RPC_TIMEOUT_MS = 10 * 60 * 1_000;
10
+ const MAX_TEXT_BYTES = 64 * 1024;
11
+ const MAX_MODEL_SELECTOR_BYTES = 513;
9
12
 
10
13
  function boundedString(maxBytes: number) {
11
14
  return z
@@ -18,7 +21,7 @@ const CommandPartSchema = boundedString(MAX_PATH_BYTES).refine(
18
21
  (value) => !value.includes("\0") && !/[\r\n]/u.test(value),
19
22
  "command arguments cannot contain NUL or line breaks",
20
23
  );
21
- const EnvironmentNameSchema = z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,127}$/u);
24
+ const EnvironmentNameSchema = environmentNameSchema;
22
25
  const EnvironmentValueSchema = z
23
26
  .string()
24
27
  .refine((value) => Buffer.byteLength(value, "utf8") <= MAX_TEXT_BYTES && !value.includes("\0"));
@@ -63,7 +66,7 @@ export const OmpProviderOptionsSchema = z
63
66
  .optional(),
64
67
  inheritEnv: z
65
68
  .array(EnvironmentNameSchema)
66
- .max(MAX_ENV_ENTRIES)
69
+ .max(MAX_INHERITED_ENVIRONMENT_NAMES)
67
70
  .describe("Daemon environment variable names copied at OMP spawn time")
68
71
  .optional(),
69
72
  outputRedaction: OmpOutputRedactionSchema.describe(
@@ -0,0 +1,18 @@
1
+ import { defineSettings } from "@getpaseo/plugin";
2
+ import { z } from "zod";
3
+
4
+ export const MAX_INHERITED_ENVIRONMENT_NAMES = 256;
5
+ export const environmentNameSchema = z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,127}$/u);
6
+
7
+ export const providerLaunchSettingsSchema = z.object({
8
+ inheritEnv: z.array(environmentNameSchema).max(MAX_INHERITED_ENVIRONMENT_NAMES).default([]),
9
+ });
10
+
11
+ export type ProviderLaunchSettings = z.infer<typeof providerLaunchSettingsSchema>;
12
+
13
+ export const providerLaunchSettings = defineSettings({
14
+ id: "provider-launch",
15
+ scope: "host",
16
+ version: 1,
17
+ schema: providerLaunchSettingsSchema,
18
+ });