@spotpatch/vite 1.0.0 → 1.1.0

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/index.d.cts CHANGED
@@ -1,8 +1,19 @@
1
1
  import { Plugin } from 'vite';
2
- import { ContextBudget, SpotPatchLocalePreference, ResolvedAiOptions, AiOptions } from '@spotpatch/shared';
3
- export { AgentApplyMode, AgentCheckDefinition, AgentLimits, AiExecutionOptions, AiModelProfile, AiOptions, AiProviderProtocol, ContextBudget, DEFAULT_AGENT_LIMITS, OpenAICompatibleProviderOptions } from '@spotpatch/shared';
2
+ import { ContextBudget, SpotPatchLocalePreference, ResolvedAiOptions, AiProviderProtocol, AiProviderAuthentication, AiExecutionOptions, AiOptions } from '@spotpatch/shared';
3
+ export { AgentApplyMode, AgentCheckDefinition, AgentLimits, AiExecutionOptions, AiModelProfile, AiOptions, AiProviderAuthentication, AiProviderProtocol, ContextBudget, DEFAULT_AGENT_LIMITS, OpenAICompatibleProviderOptions } from '@spotpatch/shared';
4
4
 
5
5
  type FilterEntry = string | RegExp;
6
+ interface SimpleAiOptions {
7
+ readonly baseURL: string;
8
+ readonly model: string;
9
+ readonly apiKeyEnv?: string;
10
+ readonly protocol?: AiProviderProtocol;
11
+ readonly authentication?: AiProviderAuthentication;
12
+ readonly providerLabel?: string;
13
+ readonly modelLabel?: string;
14
+ readonly execution?: AiExecutionOptions;
15
+ }
16
+ type SpotPatchAiOptions = false | SimpleAiOptions | AiOptions;
6
17
  interface SpotPatchOptions {
7
18
  readonly enabled?: boolean;
8
19
  readonly include?: readonly FilterEntry[];
@@ -15,7 +26,7 @@ interface SpotPatchOptions {
15
26
  readonly debug?: boolean;
16
27
  readonly locale?: SpotPatchLocalePreference;
17
28
  readonly maxTargets?: number;
18
- readonly ai?: false | AiOptions;
29
+ readonly ai?: SpotPatchAiOptions;
19
30
  }
20
31
  interface ResolvedSpotPatchOptions {
21
32
  readonly enabled: boolean;
@@ -52,8 +63,8 @@ declare const DEFAULT_OPTIONS: Readonly<{
52
63
  maxTargets: number;
53
64
  ai: false;
54
65
  }>;
55
- declare function resolveOptions(options?: SpotPatchOptions): ResolvedSpotPatchOptions;
66
+ declare function resolveOptions(options?: SpotPatchOptions, environmentAi?: false | SimpleAiOptions): ResolvedSpotPatchOptions;
56
67
 
57
68
  declare function spotPatch(userOptions?: SpotPatchOptions): Plugin[];
58
69
 
59
- export { DEFAULT_OPTIONS, type ResolvedSpotPatchOptions, type SpotPatchOptions, resolveOptions, spotPatch };
70
+ export { DEFAULT_OPTIONS, type ResolvedSpotPatchOptions, type SimpleAiOptions, type SpotPatchAiOptions, type SpotPatchOptions, resolveOptions, spotPatch };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,19 @@
1
1
  import { Plugin } from 'vite';
2
- import { ContextBudget, SpotPatchLocalePreference, ResolvedAiOptions, AiOptions } from '@spotpatch/shared';
3
- export { AgentApplyMode, AgentCheckDefinition, AgentLimits, AiExecutionOptions, AiModelProfile, AiOptions, AiProviderProtocol, ContextBudget, DEFAULT_AGENT_LIMITS, OpenAICompatibleProviderOptions } from '@spotpatch/shared';
2
+ import { ContextBudget, SpotPatchLocalePreference, ResolvedAiOptions, AiProviderProtocol, AiProviderAuthentication, AiExecutionOptions, AiOptions } from '@spotpatch/shared';
3
+ export { AgentApplyMode, AgentCheckDefinition, AgentLimits, AiExecutionOptions, AiModelProfile, AiOptions, AiProviderAuthentication, AiProviderProtocol, ContextBudget, DEFAULT_AGENT_LIMITS, OpenAICompatibleProviderOptions } from '@spotpatch/shared';
4
4
 
5
5
  type FilterEntry = string | RegExp;
6
+ interface SimpleAiOptions {
7
+ readonly baseURL: string;
8
+ readonly model: string;
9
+ readonly apiKeyEnv?: string;
10
+ readonly protocol?: AiProviderProtocol;
11
+ readonly authentication?: AiProviderAuthentication;
12
+ readonly providerLabel?: string;
13
+ readonly modelLabel?: string;
14
+ readonly execution?: AiExecutionOptions;
15
+ }
16
+ type SpotPatchAiOptions = false | SimpleAiOptions | AiOptions;
6
17
  interface SpotPatchOptions {
7
18
  readonly enabled?: boolean;
8
19
  readonly include?: readonly FilterEntry[];
@@ -15,7 +26,7 @@ interface SpotPatchOptions {
15
26
  readonly debug?: boolean;
16
27
  readonly locale?: SpotPatchLocalePreference;
17
28
  readonly maxTargets?: number;
18
- readonly ai?: false | AiOptions;
29
+ readonly ai?: SpotPatchAiOptions;
19
30
  }
20
31
  interface ResolvedSpotPatchOptions {
21
32
  readonly enabled: boolean;
@@ -52,8 +63,8 @@ declare const DEFAULT_OPTIONS: Readonly<{
52
63
  maxTargets: number;
53
64
  ai: false;
54
65
  }>;
55
- declare function resolveOptions(options?: SpotPatchOptions): ResolvedSpotPatchOptions;
66
+ declare function resolveOptions(options?: SpotPatchOptions, environmentAi?: false | SimpleAiOptions): ResolvedSpotPatchOptions;
56
67
 
57
68
  declare function spotPatch(userOptions?: SpotPatchOptions): Plugin[];
58
69
 
59
- export { DEFAULT_OPTIONS, type ResolvedSpotPatchOptions, type SpotPatchOptions, resolveOptions, spotPatch };
70
+ export { DEFAULT_OPTIONS, type ResolvedSpotPatchOptions, type SimpleAiOptions, type SpotPatchAiOptions, type SpotPatchOptions, resolveOptions, spotPatch };
package/dist/index.js CHANGED
@@ -1,3 +1,68 @@
1
+ // src/plugin.ts
2
+ import path10 from "path";
3
+ import { loadEnv } from "vite";
4
+
5
+ // src/environment-ai.ts
6
+ var AI_ENVIRONMENT_NAMES = Object.freeze({
7
+ authentication: "SPOTPATCH_AI_AUTHENTICATION",
8
+ baseURL: "SPOTPATCH_AI_BASE_URL",
9
+ credential: "SPOTPATCH_AI_API_KEY",
10
+ model: "SPOTPATCH_AI_MODEL",
11
+ protocol: "SPOTPATCH_AI_PROTOCOL"
12
+ });
13
+ function normalizedValue(environment, name) {
14
+ const value = environment[name];
15
+ if (value === void 0 || value.trim().length === 0) {
16
+ return void 0;
17
+ }
18
+ return value.trim();
19
+ }
20
+ function resolveEnvironmentAiConfiguration(environment) {
21
+ const baseURL = normalizedValue(environment, AI_ENVIRONMENT_NAMES.baseURL);
22
+ const model = normalizedValue(environment, AI_ENVIRONMENT_NAMES.model);
23
+ const credential = normalizedValue(environment, AI_ENVIRONMENT_NAMES.credential);
24
+ const protocol = normalizedValue(environment, AI_ENVIRONMENT_NAMES.protocol);
25
+ const authentication = normalizedValue(
26
+ environment,
27
+ AI_ENVIRONMENT_NAMES.authentication
28
+ );
29
+ const configuredValues = [baseURL, model, credential, protocol, authentication];
30
+ if (configuredValues.every((value) => value === void 0)) {
31
+ return Object.freeze({ ai: false });
32
+ }
33
+ const missing = [
34
+ [AI_ENVIRONMENT_NAMES.baseURL, baseURL],
35
+ [AI_ENVIRONMENT_NAMES.model, model],
36
+ [AI_ENVIRONMENT_NAMES.credential, credential]
37
+ ].filter((entry) => entry[1] === void 0).map(([name]) => name);
38
+ if (missing.length > 0) {
39
+ throw new RangeError(
40
+ `SpotPatch AI environment configuration is incomplete; missing ${missing.join(", ")}.`
41
+ );
42
+ }
43
+ if (baseURL === void 0 || model === void 0 || credential === void 0) {
44
+ throw new RangeError("SpotPatch AI environment configuration is incomplete.");
45
+ }
46
+ if (protocol !== void 0 && protocol !== "responses" && protocol !== "chat-completions") {
47
+ throw new RangeError(
48
+ "SpotPatch SPOTPATCH_AI_PROTOCOL must be responses or chat-completions."
49
+ );
50
+ }
51
+ if (authentication !== void 0 && authentication !== "bearer" && authentication !== "x-api-key") {
52
+ throw new RangeError(
53
+ "SpotPatch SPOTPATCH_AI_AUTHENTICATION must be bearer or x-api-key."
54
+ );
55
+ }
56
+ return Object.freeze({
57
+ ai: Object.freeze({
58
+ baseURL,
59
+ model,
60
+ ...protocol === void 0 ? {} : { protocol },
61
+ ...authentication === void 0 ? {} : { authentication }
62
+ })
63
+ });
64
+ }
65
+
1
66
  // src/options.ts
2
67
  import {
3
68
  DEFAULT_AGENT_LIMITS,
@@ -66,6 +131,7 @@ var aiOptionsSchema = z.strictObject({
66
131
  type: z.literal("openai-compatible"),
67
132
  label: z.string(),
68
133
  protocol: z.enum(["responses", "chat-completions"]),
134
+ authentication: z.enum(["bearer", "x-api-key"]).optional(),
69
135
  baseURL: z.string(),
70
136
  apiKeyEnv: z.string(),
71
137
  models: z.record(
@@ -83,6 +149,16 @@ var aiOptionsSchema = z.strictObject({
83
149
  limits: agentLimitsSchema
84
150
  }).optional()
85
151
  });
152
+ var simpleAiOptionsSchema = z.strictObject({
153
+ baseURL: z.string(),
154
+ model: z.string(),
155
+ apiKeyEnv: z.string().optional(),
156
+ protocol: z.enum(["responses", "chat-completions"]).optional(),
157
+ authentication: z.enum(["bearer", "x-api-key"]).optional(),
158
+ providerLabel: z.string().optional(),
159
+ modelLabel: z.string().optional(),
160
+ execution: aiOptionsSchema.shape.execution
161
+ });
86
162
  function assertIdentifier(value, label) {
87
163
  if (!PROFILE_ID_PATTERN.test(value)) {
88
164
  throw new RangeError(
@@ -182,6 +258,7 @@ function resolveProviders(providers) {
182
258
  type: provider.type,
183
259
  label: nonEmpty(provider.label, "provider label", 100),
184
260
  protocol: provider.protocol,
261
+ authentication: provider.authentication ?? "bearer",
185
262
  baseURL: normalizeProviderBaseURL(provider.baseURL),
186
263
  apiKeyEnv: provider.apiKeyEnv,
187
264
  models,
@@ -225,7 +302,36 @@ function resolveAiOptions(options) {
225
302
  if (options === void 0 || options === false) {
226
303
  return false;
227
304
  }
228
- const parsed = aiOptionsSchema.safeParse(options);
305
+ const expanded = "providers" in options ? options : (() => {
306
+ const simple = simpleAiOptionsSchema.safeParse(options);
307
+ if (!simple.success) {
308
+ throw new RangeError("SpotPatch AI configuration is invalid.");
309
+ }
310
+ const providerId = "default";
311
+ const modelId = "default";
312
+ return {
313
+ providers: {
314
+ [providerId]: {
315
+ type: "openai-compatible",
316
+ label: simple.data.providerLabel ?? "AI provider",
317
+ protocol: simple.data.protocol ?? "chat-completions",
318
+ authentication: simple.data.authentication ?? "bearer",
319
+ baseURL: simple.data.baseURL,
320
+ apiKeyEnv: simple.data.apiKeyEnv ?? "SPOTPATCH_AI_API_KEY",
321
+ models: {
322
+ [modelId]: {
323
+ label: simple.data.modelLabel ?? "AI model",
324
+ model: simple.data.model
325
+ }
326
+ },
327
+ defaultModel: modelId
328
+ }
329
+ },
330
+ defaultProvider: providerId,
331
+ ...simple.data.execution === void 0 ? {} : { execution: simple.data.execution }
332
+ };
333
+ })();
334
+ const parsed = aiOptionsSchema.safeParse(expanded);
229
335
  if (!parsed.success) {
230
336
  throw new RangeError("SpotPatch AI configuration is invalid.");
231
337
  }
@@ -285,7 +391,7 @@ function assertPositiveBudget(budget) {
285
391
  }
286
392
  }
287
393
  }
288
- function resolveOptions(options = {}) {
394
+ function resolveOptions(options = {}, environmentAi) {
289
395
  const budget = Object.freeze({
290
396
  ...DEFAULT_OPTIONS.budget,
291
397
  ...options.budget
@@ -313,7 +419,7 @@ function resolveOptions(options = {}) {
313
419
  debug: options.debug ?? DEFAULT_OPTIONS.debug,
314
420
  locale,
315
421
  maxTargets,
316
- ai: resolveAiOptions(options.ai)
422
+ ai: resolveAiOptions(options.ai ?? environmentAi)
317
423
  };
318
424
  if (resolved.shortcut.trim().length === 0) {
319
425
  throw new RangeError("SpotPatch shortcut cannot be empty.");
@@ -370,7 +476,7 @@ import path2 from "path";
370
476
  // package.json
371
477
  var package_default = {
372
478
  name: "@spotpatch/vite",
373
- version: "1.0.0",
479
+ version: "1.1.0",
374
480
  description: "Vite development plugin for SpotPatch.",
375
481
  license: "MIT",
376
482
  repository: {
@@ -462,15 +568,16 @@ function readConsumerViteVersion(root) {
462
568
  return VITE_VERSION;
463
569
  }
464
570
  function createClientModule(input, clientBundle, viteVersion) {
571
+ const options = input.context.getOptions();
465
572
  const runtimeConfig = {
466
- ai: createRuntimeAiConfig(input.options.ai),
467
- budget: input.options.budget,
468
- debug: input.options.debug,
469
- locale: input.options.locale,
470
- maxTargets: input.options.maxTargets,
471
- redact: input.options.redact,
573
+ ai: createRuntimeAiConfig(options.ai),
574
+ budget: options.budget,
575
+ debug: options.debug,
576
+ locale: options.locale,
577
+ maxTargets: options.maxTargets,
578
+ redact: options.redact,
472
579
  sessionToken: input.session.token,
473
- shortcut: input.options.shortcut,
580
+ shortcut: options.shortcut,
474
581
  spotPatchVersion: package_default.version,
475
582
  viteVersion
476
583
  };
@@ -602,7 +709,7 @@ function snapshot(job) {
602
709
  );
603
710
  }
604
711
  function capabilityCacheKey(provider, model) {
605
- const configurationDigest = createHash("sha256").update(provider.baseURL).update("\0").update(provider.protocol).digest("hex");
712
+ const configurationDigest = createHash("sha256").update(provider.baseURL).update("\0").update(provider.protocol).update("\0").update(provider.authentication).digest("hex");
606
713
  return `${provider.id}:${model.id}:${configurationDigest}`;
607
714
  }
608
715
  function freezeEvent(event) {
@@ -1550,18 +1657,18 @@ var EVENT_STREAM_END_STATUSES = /* @__PURE__ */ new Set([
1550
1657
  "reverted",
1551
1658
  "failed"
1552
1659
  ]);
1553
- function matchAgentRequestPath(path10) {
1554
- if (path10 === SPOTPATCH_ENDPOINTS.agentCapability) {
1660
+ function matchAgentRequestPath(path11) {
1661
+ if (path11 === SPOTPATCH_ENDPOINTS.agentCapability) {
1555
1662
  return Object.freeze({ kind: "capability" });
1556
1663
  }
1557
- if (path10 === SPOTPATCH_ENDPOINTS.agentJobs) {
1664
+ if (path11 === SPOTPATCH_ENDPOINTS.agentJobs) {
1558
1665
  return Object.freeze({ kind: "create-job" });
1559
1666
  }
1560
1667
  const prefix = `${SPOTPATCH_ENDPOINTS.agentJobs}/`;
1561
- if (!path10.startsWith(prefix)) {
1668
+ if (!path11.startsWith(prefix)) {
1562
1669
  return void 0;
1563
1670
  }
1564
- const segments = path10.slice(prefix.length).split("/");
1671
+ const segments = path11.slice(prefix.length).split("/");
1565
1672
  const jobId = segments[0];
1566
1673
  const action = segments[1];
1567
1674
  if (segments.length !== 2 || jobId === void 0 || !AGENT_JOB_ID_PATTERN.test(jobId) || action === void 0 || !AGENT_JOB_ACTIONS.has(action)) {
@@ -1903,9 +2010,9 @@ async function handleOpenEditor(request, options) {
1903
2010
  }
1904
2011
  function createSpotPatchMiddleware(options) {
1905
2012
  return (request, response, next) => {
1906
- const path10 = requestPath(request);
1907
- const agentRoute = matchAgentRequestPath(path10);
1908
- if (path10 !== SPOTPATCH_ENDPOINTS2.sourceContext && path10 !== SPOTPATCH_ENDPOINTS2.openEditor && agentRoute === void 0 && !path10.startsWith(`${SPOTPATCH_API_BASE}/`)) {
2013
+ const path11 = requestPath(request);
2014
+ const agentRoute = matchAgentRequestPath(path11);
2015
+ if (path11 !== SPOTPATCH_ENDPOINTS2.sourceContext && path11 !== SPOTPATCH_ENDPOINTS2.openEditor && agentRoute === void 0 && !path11.startsWith(`${SPOTPATCH_API_BASE}/`)) {
1909
2016
  next();
1910
2017
  return;
1911
2018
  }
@@ -1914,7 +2021,7 @@ function createSpotPatchMiddleware(options) {
1914
2021
  allowLan: options.options.allowLan,
1915
2022
  sessionToken: options.session.token
1916
2023
  });
1917
- if (path10 === SPOTPATCH_ENDPOINTS2.sourceContext) {
2024
+ if (path11 === SPOTPATCH_ENDPOINTS2.sourceContext) {
1918
2025
  if (request.method !== "POST") {
1919
2026
  throw new SpotPatchError8(ERROR_CODES8.INVALID_REQUEST);
1920
2027
  }
@@ -1922,7 +2029,7 @@ function createSpotPatchMiddleware(options) {
1922
2029
  writeJson(response, 200, { ok: true, data });
1923
2030
  return;
1924
2031
  }
1925
- if (path10 === SPOTPATCH_ENDPOINTS2.openEditor) {
2032
+ if (path11 === SPOTPATCH_ENDPOINTS2.openEditor) {
1926
2033
  if (request.method !== "POST") {
1927
2034
  throw new SpotPatchError8(ERROR_CODES8.INVALID_REQUEST);
1928
2035
  }
@@ -1970,11 +2077,16 @@ function createServerPlugin(input) {
1970
2077
  throw new Error("SpotPatch server initialized before Vite config resolution.");
1971
2078
  }
1972
2079
  const root = path6.resolve(config.root);
1973
- agentManager = input.options.ai === false ? void 0 : createAgentJobManager({ ai: input.options.ai, root });
2080
+ const options = input.context.getOptions();
2081
+ agentManager = options.ai === false ? void 0 : createAgentJobManager({
2082
+ ai: options.ai,
2083
+ environment: input.context.getCredentialEnvironment(),
2084
+ root
2085
+ });
1974
2086
  server.middlewares.use(
1975
2087
  createSpotPatchMiddleware({
1976
2088
  ...agentManager === void 0 ? {} : { agentManager },
1977
- options: input.options,
2089
+ options,
1978
2090
  registry: input.registry,
1979
2091
  root,
1980
2092
  session: input.session,
@@ -1985,7 +2097,7 @@ function createServerPlugin(input) {
1985
2097
  void closeResources();
1986
2098
  });
1987
2099
  config.logger.info(
1988
- `[spotpatch:vite] Ready. Toggle picker with ${input.options.shortcut}.`
2100
+ `[spotpatch:vite] Ready. Toggle picker with ${options.shortcut}.`
1989
2101
  );
1990
2102
  },
1991
2103
  async closeBundle() {
@@ -2180,7 +2292,7 @@ function getDisplayPath(root, id) {
2180
2292
  }
2181
2293
  function createTransformPlugin(input) {
2182
2294
  let root = process.cwd();
2183
- let filter = createTransformFilter(root, input.options);
2295
+ let filter = createTransformFilter(root, input.context.getOptions());
2184
2296
  let logger;
2185
2297
  const warnedFiles = /* @__PURE__ */ new Set();
2186
2298
  const cache = /* @__PURE__ */ new Map();
@@ -2188,9 +2300,12 @@ function createTransformPlugin(input) {
2188
2300
  name: "spotpatch:transform",
2189
2301
  apply: "serve",
2190
2302
  enforce: "pre",
2303
+ config(config, environment) {
2304
+ input.configure?.(config, environment);
2305
+ },
2191
2306
  configResolved(config) {
2192
2307
  root = path9.resolve(config.root);
2193
- filter = createTransformFilter(root, input.options);
2308
+ filter = createTransformFilter(root, input.context.getOptions());
2194
2309
  logger = config.logger;
2195
2310
  },
2196
2311
  transform(code, id) {
@@ -2203,6 +2318,7 @@ function createTransformPlugin(input) {
2203
2318
  return cache.get(cacheKey) ?? null;
2204
2319
  }
2205
2320
  const startedAt = performance.now();
2321
+ const options = input.context.getOptions();
2206
2322
  try {
2207
2323
  const result = injectSourceMarkers({
2208
2324
  code,
@@ -2220,7 +2336,7 @@ function createTransformPlugin(input) {
2220
2336
  map: result.map.toString()
2221
2337
  });
2222
2338
  cache.set(cacheKey, output);
2223
- if (input.options.debug) {
2339
+ if (options.debug) {
2224
2340
  const elapsed = performance.now() - startedAt;
2225
2341
  logger?.info(
2226
2342
  `[spotpatch:transform] ${getDisplayPath(root, id)} ${elapsed.toFixed(2)}ms`
@@ -2230,7 +2346,7 @@ function createTransformPlugin(input) {
2230
2346
  } catch (error) {
2231
2347
  if (!warnedFiles.has(cleanId)) {
2232
2348
  warnedFiles.add(cleanId);
2233
- const detail = input.options.debug && error instanceof Error ? `: ${error.message}` : "";
2349
+ const detail = options.debug && error instanceof Error ? `: ${error.message}` : "";
2234
2350
  logger?.warn(
2235
2351
  `[spotpatch:transform] Failed to transform ${getDisplayPath(root, id)}; using original module${detail}`
2236
2352
  );
@@ -2243,16 +2359,46 @@ function createTransformPlugin(input) {
2243
2359
 
2244
2360
  // src/plugin.ts
2245
2361
  function spotPatch(userOptions = {}) {
2246
- const options = resolveOptions(userOptions);
2362
+ let options = resolveOptions(userOptions);
2363
+ let credentialEnvironment = Object.freeze({});
2247
2364
  if (!options.enabled) {
2248
2365
  return [];
2249
2366
  }
2250
2367
  const registry = createSourceRegistry();
2251
2368
  const session = createSession();
2369
+ const context = Object.freeze({
2370
+ getCredentialEnvironment: () => credentialEnvironment,
2371
+ getOptions: () => options
2372
+ });
2373
+ const configure = (config, environment) => {
2374
+ const root = path10.resolve(process.cwd(), config.root ?? ".");
2375
+ const loadedEnvironment = config.envDir === false ? process.env : loadEnv(environment.mode, path10.resolve(root, config.envDir ?? "."), "");
2376
+ const environmentAi = userOptions.ai === void 0 ? resolveEnvironmentAiConfiguration(loadedEnvironment).ai : false;
2377
+ options = resolveOptions(userOptions, environmentAi);
2378
+ if (options.ai === false) {
2379
+ credentialEnvironment = Object.freeze({});
2380
+ return;
2381
+ }
2382
+ const names = new Set(
2383
+ Object.values(options.ai.providers).map((provider) => provider.apiKeyEnv)
2384
+ );
2385
+ const missing = [...names].filter((name) => {
2386
+ const value = loadedEnvironment[name];
2387
+ return value === void 0 || value.trim().length === 0;
2388
+ });
2389
+ if (missing.length > 0) {
2390
+ throw new RangeError(
2391
+ `SpotPatch AI credential environment is missing ${missing.join(", ")}.`
2392
+ );
2393
+ }
2394
+ credentialEnvironment = Object.freeze(
2395
+ Object.fromEntries([...names].map((name) => [name, loadedEnvironment[name]]))
2396
+ );
2397
+ };
2252
2398
  return [
2253
- createTransformPlugin({ options, registry }),
2254
- createRuntimeInjectionPlugin({ options, session }),
2255
- createServerPlugin({ options, registry, session })
2399
+ createTransformPlugin({ configure, context, registry }),
2400
+ createRuntimeInjectionPlugin({ context, session }),
2401
+ createServerPlugin({ context, registry, session })
2256
2402
  ];
2257
2403
  }
2258
2404