@unotest/web 0.42.0 → 0.43.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.
@@ -4,8 +4,8 @@ import { Matcher, RegexLiteral, JudgeRequest, JudgeVerdict, SoftFailureRecord }
4
4
  import { ExecutionWalker, ExecutionEvent, RunResult, RunOptions } from '@unotest/dsl/executor';
5
5
  export { ExecutionError, ExecutionEvent, RunOptions, RunResult } from '@unotest/dsl/executor';
6
6
  import { SandboxConfig } from '../config/schema.js';
7
- import { RuntimeExecState } from '@unotest/core';
8
- export { L as LintDiagnostic, b as LintOptions, a as LintSeverity, l as lintAst } from '../linter-Yf4gPe5J.js';
7
+ import { UnotestError, RuntimeExecState } from '@unotest/core';
8
+ export { L as LintDiagnostic, b as LintOptions, a as LintSeverity, l as lintAst } from '../linter-BWSAYBQy.js';
9
9
  import 'zod';
10
10
  import '@unotest/dsl';
11
11
 
@@ -69,6 +69,50 @@ declare function chainGetByTitle(loc: LocatorValue, text: Matcher, options?: {
69
69
  exact?: boolean;
70
70
  }): LocatorValue;
71
71
 
72
+ /** Configuration invalid or missing. Surfaces during config load / validation. */
73
+ declare class ConfigError extends UnotestError {
74
+ }
75
+ /** A host the run would reach came from the BASE `.env` while a named
76
+ * environment is active (#199). Silence here is the whole defect: the
77
+ * overlay says "dev", the request goes to the production host the base
78
+ * file names, and nothing in the output says which host was used. The
79
+ * message names the variable, BOTH files, and the two ways out. */
80
+ declare class EnvOverlayHostError extends ConfigError {
81
+ constructor(context: {
82
+ name: string;
83
+ /** Where the name becomes a host, quoted as the author wrote it —
84
+ * `apiCall {base: "API_BASE_CHAT"}`, `goto(APP_URL)`, `baseUrl`. */
85
+ usage: string;
86
+ envName: string;
87
+ /** Project-relative file the value actually came from. */
88
+ baseFile: string;
89
+ /** The overlay that does NOT set it — where it belongs. */
90
+ overlayFile: string;
91
+ });
92
+ }
93
+
94
+ /**
95
+ * What a host-using call site may ask. A narrow port (ISP) so the linter
96
+ * and the DSL runtime depend on the QUESTION, not on the config layer:
97
+ * `rejectAsHost` answers with the refusal message, or undefined when the
98
+ * name is fine to use as a host here.
99
+ */
100
+ interface HostVariableCheck {
101
+ rejectAsHost(name: string, usage: string): EnvOverlayHostError | undefined;
102
+ }
103
+ /** The policy as the places that switch environments need it: the same
104
+ * question, plus "the same rule, for a different environment". `forEnv`
105
+ * carries the config-derived `shared` list ACROSS, which is why the MCP
106
+ * server and the child it spawns cannot end up with different lists. */
107
+ interface HostPolicy extends HostVariableCheck {
108
+ forEnv(envName?: string): HostPolicy;
109
+ /** The base-URL variable is a host by construction — `APP_BASE_URL`
110
+ * becomes `config.baseUrl`, which every relative `goto` resolves
111
+ * against. Asked without naming it, so no consumer keeps a second
112
+ * literal of the name. */
113
+ rejectBaseUrl(usage: string): EnvOverlayHostError | undefined;
114
+ }
115
+
72
116
  interface Logger {
73
117
  info(msg: string, ...rest: unknown[]): void;
74
118
  warn(msg: string, ...rest: unknown[]): void;
@@ -82,6 +126,12 @@ interface Logger {
82
126
  interface VariableStore {
83
127
  has(name: string): boolean;
84
128
  get(name: string): string | undefined;
129
+ /** Host policy for the environment this store resolves against (#199).
130
+ * Optional like `describeSources`: a store built without a project
131
+ * behind it (test fakes, ad-hoc runtimes) carries none and the rule is
132
+ * then off. `withHostPolicy` (config/env-host-guard.ts) is what puts
133
+ * one on a store. */
134
+ hostPolicy?: HostPolicy;
85
135
  /** One-line, human/agent-readable summary of WHERE lookups searched
86
136
  * (active environment + layer files, missing ones flagged). Optional so
87
137
  * test fakes stay two-method; consumed by "variable not found" errors. */
@@ -197,6 +247,11 @@ declare class TestRuntime {
197
247
  enterCall(maxCallDepth: number): void;
198
248
  exitCall(): void;
199
249
  get callDepth(): number;
250
+ /** Host policy of this run — read off the variable store, which is
251
+ * where the project's environment already lives (#199). Deliberately
252
+ * NOT a separate injected field: a field the two runtime-building
253
+ * sites could forget to pass is a rule that switches itself off. */
254
+ get hostPolicy(): HostPolicy | undefined;
200
255
  setVar(name: string, value: DslValue): void;
201
256
  getVar(name: string): DslValue;
202
257
  hasVar(name: string): boolean;
@@ -289,6 +344,8 @@ interface ActiveRuntime {
289
344
  createdAt: number;
290
345
  /** Active TTL timer (only when state is paused-failure). */
291
346
  ttlTimer: NodeJS.Timeout | null;
347
+ /** The runtime's own last-rites hook — see `register`. */
348
+ onAbort?: () => Promise<void>;
292
349
  }
293
350
  interface RuntimeSummary {
294
351
  id: string;
@@ -336,6 +393,13 @@ declare class TestRuntimeManager {
336
393
  testRuntime: TestRuntime;
337
394
  generator: AsyncGenerator<ExecutionEvent, RunResult>;
338
395
  runOptions: RunOptions;
396
+ /** Last thing this runtime gets to do when it is aborted, awaited
397
+ * inside `abort()`. It exists because an abort on a PAUSE never comes
398
+ * back through the orchestrator: the CLI kills the process right
399
+ * after `abort` resolves (a paused executor cannot unwind itself), so
400
+ * anything the run still owes the disk has to be settled here (#194
401
+ * tail). */
402
+ onAbort?: () => Promise<void>;
339
403
  }): string;
340
404
  pump(id: string): Promise<ExecutionEvent | RunResult>;
341
405
  /** The run's verdict — the executor's own, corrected for the one thing