@e2edev/e2e 0.4.0 → 0.5.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.
Files changed (256) hide show
  1. package/README.md +41 -15
  2. package/dist/agent/act.d.ts +1 -1
  3. package/dist/agent/act.js +12 -36
  4. package/dist/agent/act.js.map +1 -1
  5. package/dist/agent/actions.d.ts +2 -2
  6. package/dist/agent/actions.d.ts.map +1 -1
  7. package/dist/agent/actions.js +1 -1
  8. package/dist/agent/default-agent.d.ts +3 -29
  9. package/dist/agent/default-agent.d.ts.map +1 -1
  10. package/dist/agent/default-agent.js +4 -11
  11. package/dist/agent/default-agent.js.map +1 -1
  12. package/dist/agent/error.d.ts +0 -2
  13. package/dist/agent/error.d.ts.map +1 -1
  14. package/dist/agent/error.js +1 -3
  15. package/dist/agent/error.js.map +1 -1
  16. package/dist/agent/executor.d.ts +15 -49
  17. package/dist/agent/executor.d.ts.map +1 -1
  18. package/dist/agent/executor.js +0 -1
  19. package/dist/agent/executor.js.map +1 -1
  20. package/dist/agent/index.js +2 -2
  21. package/dist/agent/invocation.d.ts +6 -4
  22. package/dist/agent/invocation.d.ts.map +1 -1
  23. package/dist/agent/invocation.js +2 -2
  24. package/dist/agent/invocation.js.map +1 -1
  25. package/dist/agent/ledger.d.ts +16 -11
  26. package/dist/agent/ledger.d.ts.map +1 -1
  27. package/dist/agent/ledger.js +5 -8
  28. package/dist/agent/ledger.js.map +1 -1
  29. package/dist/agent/observation.d.ts +6 -6
  30. package/dist/agent/observation.d.ts.map +1 -1
  31. package/dist/agent/observation.js +5 -5
  32. package/dist/agent/observation.js.map +1 -1
  33. package/dist/agent/phases.d.ts +3 -3
  34. package/dist/agent/phases.d.ts.map +1 -1
  35. package/dist/agent/phases.js +4 -4
  36. package/dist/agent/phases.js.map +1 -1
  37. package/dist/agent/primitives.d.ts +4 -25
  38. package/dist/agent/primitives.d.ts.map +1 -1
  39. package/dist/agent/primitives.js +3 -36
  40. package/dist/agent/primitives.js.map +1 -1
  41. package/dist/agent/protocol.d.ts +1 -1
  42. package/dist/agent/protocol.js +1 -1
  43. package/dist/agent/public.d.ts +7 -9
  44. package/dist/agent/public.d.ts.map +1 -1
  45. package/dist/agent/public.js +6 -7
  46. package/dist/agent/public.js.map +1 -1
  47. package/dist/agent/replay.d.ts +1 -1
  48. package/dist/agent/replay.d.ts.map +1 -1
  49. package/dist/agent/secrets.d.ts +2 -2
  50. package/dist/agent/secrets.d.ts.map +1 -1
  51. package/dist/agent/secrets.js +3 -3
  52. package/dist/agent/secrets.js.map +1 -1
  53. package/dist/agent/tool-loop.d.ts +2 -30
  54. package/dist/agent/tool-loop.d.ts.map +1 -1
  55. package/dist/agent/tool-loop.js +9 -33
  56. package/dist/agent/tool-loop.js.map +1 -1
  57. package/dist/agent/tool.d.ts +4 -5
  58. package/dist/agent/tool.d.ts.map +1 -1
  59. package/dist/agent/tool.js +2 -7
  60. package/dist/agent/tool.js.map +1 -1
  61. package/dist/cache/anchors.d.ts +1 -1
  62. package/dist/cache/anchors.d.ts.map +1 -1
  63. package/dist/cache/identity.d.ts +8 -8
  64. package/dist/cache/identity.d.ts.map +1 -1
  65. package/dist/cache/identity.js +5 -5
  66. package/dist/cache/identity.js.map +1 -1
  67. package/dist/cache/relocate.d.ts +1 -1
  68. package/dist/cache/relocate.d.ts.map +1 -1
  69. package/dist/cli/index.js +3 -3
  70. package/dist/cli/index.js.map +1 -1
  71. package/dist/cli/init/{backends.d.ts → engines.d.ts} +12 -13
  72. package/dist/cli/init/engines.d.ts.map +1 -0
  73. package/dist/cli/init/{backends.js → engines.js} +13 -14
  74. package/dist/cli/init/engines.js.map +1 -0
  75. package/dist/cli/init/scaffold.d.ts +3 -3
  76. package/dist/cli/init/scaffold.d.ts.map +1 -1
  77. package/dist/cli/init/scaffold.js +9 -9
  78. package/dist/cli/init/scaffold.js.map +1 -1
  79. package/dist/cli/init.d.ts.map +1 -1
  80. package/dist/cli/init.js +11 -10
  81. package/dist/cli/init.js.map +1 -1
  82. package/dist/cli/signals.d.ts +1 -1
  83. package/dist/cli/signals.d.ts.map +1 -1
  84. package/dist/cli/signals.js +1 -1
  85. package/dist/cli/signals.js.map +1 -1
  86. package/dist/collect/collect.d.ts +32 -3
  87. package/dist/collect/collect.d.ts.map +1 -1
  88. package/dist/collect/collect.js +95 -17
  89. package/dist/collect/collect.js.map +1 -1
  90. package/dist/collect/registry.js +1 -1
  91. package/dist/collect/registry.js.map +1 -1
  92. package/dist/collect/select.d.ts.map +1 -1
  93. package/dist/collect/select.js +9 -5
  94. package/dist/collect/select.js.map +1 -1
  95. package/dist/config/app.d.ts +76 -19
  96. package/dist/config/app.d.ts.map +1 -1
  97. package/dist/config/app.js +157 -102
  98. package/dist/config/app.js.map +1 -1
  99. package/dist/config/resolve.d.ts +6 -5
  100. package/dist/config/resolve.d.ts.map +1 -1
  101. package/dist/config/resolve.js +35 -32
  102. package/dist/config/resolve.js.map +1 -1
  103. package/dist/{backend → engine}/contract.d.ts +26 -18
  104. package/dist/engine/contract.d.ts.map +1 -0
  105. package/dist/{backend → engine}/contract.js +18 -18
  106. package/dist/engine/contract.js.map +1 -0
  107. package/dist/{backend → engine}/index.d.ts +141 -79
  108. package/dist/engine/index.d.ts.map +1 -0
  109. package/dist/{backend → engine}/index.js +60 -35
  110. package/dist/engine/index.js.map +1 -0
  111. package/dist/engine/session.d.ts +23 -0
  112. package/dist/engine/session.d.ts.map +1 -0
  113. package/dist/{backend → engine}/session.js +55 -51
  114. package/dist/engine/session.js.map +1 -0
  115. package/dist/{backend → engine}/surface.d.ts +11 -11
  116. package/dist/engine/surface.d.ts.map +1 -0
  117. package/dist/{backend → engine}/surface.js +2 -2
  118. package/dist/engine/surface.js.map +1 -0
  119. package/dist/engine/timing.d.ts.map +1 -0
  120. package/dist/engine/timing.js +8 -0
  121. package/dist/engine/timing.js.map +1 -0
  122. package/dist/expect/index.js +1 -1
  123. package/dist/index.d.ts +3 -2
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +1 -1
  126. package/dist/index.js.map +1 -1
  127. package/dist/internal/brands.d.ts +1 -1
  128. package/dist/internal/brands.d.ts.map +1 -1
  129. package/dist/internal/brands.js +1 -1
  130. package/dist/internal/brands.js.map +1 -1
  131. package/dist/internal/errors.d.ts +16 -16
  132. package/dist/internal/errors.d.ts.map +1 -1
  133. package/dist/internal/errors.js +39 -39
  134. package/dist/internal/errors.js.map +1 -1
  135. package/dist/internal/objects.d.ts +21 -0
  136. package/dist/internal/objects.d.ts.map +1 -0
  137. package/dist/internal/objects.js +14 -0
  138. package/dist/internal/objects.js.map +1 -0
  139. package/dist/internal/urls.d.ts +1 -1
  140. package/dist/internal/urls.d.ts.map +1 -1
  141. package/dist/internal/urls.js +6 -1
  142. package/dist/internal/urls.js.map +1 -1
  143. package/dist/locator/engine.d.ts +6 -6
  144. package/dist/locator/engine.d.ts.map +1 -1
  145. package/dist/locator/engine.js +13 -13
  146. package/dist/locator/engine.js.map +1 -1
  147. package/dist/locator/expression.d.ts +4 -2
  148. package/dist/locator/expression.d.ts.map +1 -1
  149. package/dist/locator/expression.js +24 -4
  150. package/dist/locator/expression.js.map +1 -1
  151. package/dist/locator/screen.d.ts +1 -1
  152. package/dist/locator/screen.d.ts.map +1 -1
  153. package/dist/locator/screen.js +2 -2
  154. package/dist/locator/screen.js.map +1 -1
  155. package/dist/report/build.d.ts +9 -8
  156. package/dist/report/build.d.ts.map +1 -1
  157. package/dist/report/build.js +21 -18
  158. package/dist/report/build.js.map +1 -1
  159. package/dist/report/code-frame.d.ts +8 -4
  160. package/dist/report/code-frame.d.ts.map +1 -1
  161. package/dist/report/code-frame.js +23 -18
  162. package/dist/report/code-frame.js.map +1 -1
  163. package/dist/report/debug-steps.js +1 -1
  164. package/dist/report/debug-steps.js.map +1 -1
  165. package/dist/report/format.d.ts +73 -0
  166. package/dist/report/format.d.ts.map +1 -0
  167. package/dist/report/format.js +147 -0
  168. package/dist/report/format.js.map +1 -0
  169. package/dist/report/list.d.ts +96 -47
  170. package/dist/report/list.d.ts.map +1 -1
  171. package/dist/report/list.js +485 -244
  172. package/dist/report/list.js.map +1 -1
  173. package/dist/report/live-window.d.ts +28 -0
  174. package/dist/report/live-window.d.ts.map +1 -0
  175. package/dist/report/live-window.js +102 -0
  176. package/dist/report/live-window.js.map +1 -0
  177. package/dist/run/declared-processes.d.ts +30 -0
  178. package/dist/run/declared-processes.d.ts.map +1 -0
  179. package/dist/run/declared-processes.js +61 -0
  180. package/dist/run/declared-processes.js.map +1 -0
  181. package/dist/run/events.d.ts +30 -2
  182. package/dist/run/events.d.ts.map +1 -1
  183. package/dist/run/events.js.map +1 -1
  184. package/dist/run/execute.d.ts +17 -13
  185. package/dist/run/execute.d.ts.map +1 -1
  186. package/dist/run/execute.js +61 -62
  187. package/dist/run/execute.js.map +1 -1
  188. package/dist/run/fixture-recording.d.ts +10 -4
  189. package/dist/run/fixture-recording.d.ts.map +1 -1
  190. package/dist/run/fixture-recording.js +19 -6
  191. package/dist/run/fixture-recording.js.map +1 -1
  192. package/dist/run/fixtures.d.ts +1 -1
  193. package/dist/run/fixtures.d.ts.map +1 -1
  194. package/dist/run/fixtures.js +33 -41
  195. package/dist/run/fixtures.js.map +1 -1
  196. package/dist/run/in-process.d.ts +1 -1
  197. package/dist/run/in-process.js +1 -1
  198. package/dist/run/managed-process.d.ts +39 -9
  199. package/dist/run/managed-process.d.ts.map +1 -1
  200. package/dist/run/managed-process.js +102 -34
  201. package/dist/run/managed-process.js.map +1 -1
  202. package/dist/run/runner.d.ts +1 -1
  203. package/dist/run/runner.d.ts.map +1 -1
  204. package/dist/run/runner.js +67 -31
  205. package/dist/run/runner.js.map +1 -1
  206. package/dist/run/scheduler.d.ts +4 -3
  207. package/dist/run/scheduler.d.ts.map +1 -1
  208. package/dist/run/scheduler.js +5 -4
  209. package/dist/run/scheduler.js.map +1 -1
  210. package/dist/run/serial.d.ts +9 -1
  211. package/dist/run/serial.d.ts.map +1 -1
  212. package/dist/run/serial.js +2 -0
  213. package/dist/run/serial.js.map +1 -1
  214. package/dist/run/sessions.d.ts +9 -9
  215. package/dist/run/sessions.d.ts.map +1 -1
  216. package/dist/run/sessions.js +10 -10
  217. package/dist/run/sessions.js.map +1 -1
  218. package/dist/run/steps.d.ts +1 -1
  219. package/dist/run/steps.d.ts.map +1 -1
  220. package/dist/run/worker/entry.d.ts +1 -1
  221. package/dist/run/worker/entry.js +2 -2
  222. package/dist/run/worker/entry.js.map +1 -1
  223. package/dist/run/worker/protocol.d.ts +18 -6
  224. package/dist/run/worker/protocol.d.ts.map +1 -1
  225. package/dist/run/worker/protocol.js +1 -1
  226. package/dist/run/worker/protocol.js.map +1 -1
  227. package/dist/run/worker/session.d.ts +2 -2
  228. package/dist/run/worker/session.d.ts.map +1 -1
  229. package/dist/run/worker/session.js +5 -3
  230. package/dist/run/worker/session.js.map +1 -1
  231. package/dist/types.d.ts +36 -37
  232. package/dist/types.d.ts.map +1 -1
  233. package/package.json +5 -5
  234. package/dist/backend/contract.d.ts.map +0 -1
  235. package/dist/backend/contract.js.map +0 -1
  236. package/dist/backend/index.d.ts.map +0 -1
  237. package/dist/backend/index.js.map +0 -1
  238. package/dist/backend/session.d.ts +0 -23
  239. package/dist/backend/session.d.ts.map +0 -1
  240. package/dist/backend/session.js.map +0 -1
  241. package/dist/backend/surface.d.ts.map +0 -1
  242. package/dist/backend/surface.js.map +0 -1
  243. package/dist/backend/timing.d.ts.map +0 -1
  244. package/dist/backend/timing.js +0 -8
  245. package/dist/backend/timing.js.map +0 -1
  246. package/dist/cli/init/backends.d.ts.map +0 -1
  247. package/dist/cli/init/backends.js.map +0 -1
  248. package/dist/report/live-status.d.ts +0 -51
  249. package/dist/report/live-status.d.ts.map +0 -1
  250. package/dist/report/live-status.js +0 -163
  251. package/dist/report/live-status.js.map +0 -1
  252. package/dist/run/fixture-legacy.d.ts +0 -36
  253. package/dist/run/fixture-legacy.d.ts.map +0 -1
  254. package/dist/run/fixture-legacy.js +0 -143
  255. package/dist/run/fixture-legacy.js.map +0 -1
  256. /package/dist/{backend → engine}/timing.d.ts +0 -0
@@ -1,24 +1,24 @@
1
1
  /**
2
- * The backend contract (RFC0002): the typed, model-free body of one target.
2
+ * The engine contract (RFC0002): the typed, model-free body of one target.
3
3
  *
4
- * A backend never talks to a model. It declares capabilities - observation,
4
+ * An engine never talks to a model. It declares capabilities - observation,
5
5
  * actions, location, state, artifacts, contributed fixtures - and the harness
6
- * grades what a target can do from what its backend declares: observation
6
+ * grades what a target can do from what its engine declares: observation
7
7
  * unlocks the judgment tier and prompt snapshots, `perform` unlocks the
8
8
  * harness-routed node actions (the agent's grammar verbs and the `screen`
9
9
  * tier's actions alike), location unlocks `screen`/`expect`. Every piece of
10
10
  * model-facing vocabulary is an agent-side `defineTool`; a target with no
11
- * backend at all is valid and simply runs everything opaque.
11
+ * engine at all is valid and simply runs everything opaque.
12
12
  *
13
- * Core knows this contract and never a backend's internals: no platform noun
14
- * appears here. A document backend, a simulator backend, and a desktop backend
13
+ * Core knows this contract and never an engine's internals: no platform noun
14
+ * appears here. A document engine, a simulator engine, and a desktop engine
15
15
  * fill in the same members with different bodies.
16
16
  *
17
- * `defineBackend` is the loud manifest: capability detection happens here,
18
- * synchronously, at config load - a malformed backend fails the run instead
17
+ * `defineEngine` is the loud manifest: capability detection happens here,
18
+ * synchronously, at config load - a malformed engine fails the run instead
19
19
  * of silently demoting itself to a lower tier.
20
20
  */
21
- import { backendBrand } from '../internal/brands.ts';
21
+ import { engineBrand } from '../internal/brands.ts';
22
22
  export { ConfigurationError, InfrastructureError, TestError } from '../internal/errors.ts';
23
23
  export { validateJsonValue, type JsonValueRules } from '../internal/json-value.ts';
24
24
  export { describePattern, matchesText, toTextPattern } from '../internal/text.ts';
@@ -26,23 +26,83 @@ export type { TextMatch } from '../types.ts';
26
26
  export { raceAbort } from './timing.ts';
27
27
  export { Deadline, pollCondition, withTimeout, withinCleanupBudget, type PollConditionOptions } from '../internal/time.ts';
28
28
  export { urlMatches } from '../internal/urls.ts';
29
- import type { Expectable, Locator, Momentum, Screen, ScrollDirection } from '../types.ts';
30
- import { type BackendSpiVersion, type LocatorAction, type LocatorExpression, type NodeRef, type ObservationPixels, type OperationContext, type SemanticNode } from './contract.ts';
29
+ export { obj, type WithoutUndefined } from '../internal/objects.ts';
30
+ import type { CommandConfig, Expectable, Locator, Momentum, Screen, ScrollDirection, ServiceConfig } from '../types.ts';
31
+ import { type EngineSpiVersion, type LocatorAction, type LocatorExpression, type NodeRef, type ObservationPixels, type OperationContext, type SemanticNode } from './contract.ts';
31
32
  export type * from './contract.ts';
32
- export { BACKEND_ERROR_CODES, BACKEND_SPI_VERSION, BackendError, OBSERVED_NAME_LIMIT, OBSERVED_TEXT_LIMIT, RETRYABLE_BACKEND_ERROR_CODES, } from './contract.ts';
33
- export type { Expectable, JsonValue, Locator, Momentum, Platform, Screen, ScrollDirection, SelectOption, } from '../types.ts';
33
+ export { ENGINE_ERROR_CODES, ENGINE_SPI_VERSION, EngineError, OBSERVED_NAME_LIMIT, OBSERVED_TEXT_LIMIT, RETRYABLE_ENGINE_ERROR_CODES, } from './contract.ts';
34
+ export type { CommandConfig, ServiceConfig, Expectable, JsonValue, Locator, Momentum, Platform, Screen, ScrollDirection, SelectOption, } from '../types.ts';
34
35
  /**
35
36
  * Capability names: the closed harness capabilities plus one name per
36
37
  * contributed fixture. `actions` is `perform`; `location` is `locate`. Both
37
38
  * require observation, because their refs live in the observation's id space.
38
39
  */
39
- export type BackendCapability = 'observation' | 'actions' | 'location' | 'state' | 'artifacts' | (string & {});
40
- /** The app under test as the harness resolved it, shared with every backend. */
41
- export interface BackendAppInfo {
40
+ export type EngineCapability = 'observation' | 'actions' | 'location' | 'state' | 'artifacts' | (string & {});
41
+ /**
42
+ * What an engine declares about the app it drives (RFC0002 step 7b). The app
43
+ * under test is the engine's to describe: a browser engine names a URL, a
44
+ * device engine a bundle id. The harness resolves the declaration once per
45
+ * target and owns everything built on it - navigation and origin policy,
46
+ * cache and session identity, the report's target record, and the app
47
+ * process it starts before the run.
48
+ */
49
+ export interface EngineAppDeclaration {
50
+ /**
51
+ * Base URL of an addressable app: `app.open()` opens it and relative
52
+ * navigation resolves against it. WHATWG-normalized; no userinfo, query, or
53
+ * fragment; a missing scheme becomes `https://`, or `http://` for a
54
+ * loopback host. Plain HTTP is accepted for loopback hosts only.
55
+ */
56
+ readonly url?: string;
57
+ /**
58
+ * Origins navigation and secret fills admit; each entry a serialized
59
+ * origin. Defaults to the URL's origin, or to none without a URL.
60
+ */
61
+ readonly allowedOrigins?: readonly string[];
62
+ /**
63
+ * Labels the target in the report and joins the cache and session identity
64
+ * digest; never gates a run. Defaults to `test` for loopback, `.localhost`,
65
+ * and `.test` hosts and for a surface without a URL, `production` otherwise.
66
+ */
67
+ readonly environment?: 'test' | 'staging' | 'production';
68
+ /**
69
+ * Stable logical identity of the app under test, keying trace cache and
70
+ * session entries. Defaults to the URL's origin and base path, so an
71
+ * ephemeral per-deploy origin (a PR preview) cold-starts every entry; an
72
+ * explicit identity keys them by what the app *is* instead of where it is
73
+ * served this run. A surface without a URL has no default: declare one
74
+ * (a bundle id, say) or entries key on the target alone. Never share one
75
+ * identity across genuinely different apps: recorded traces would replay
76
+ * across them.
77
+ */
78
+ readonly identity?: string;
79
+ /**
80
+ * Process the runner starts before the first test and stops on every exit
81
+ * path (a dev server). Structured, never shell-interpreted; the child
82
+ * inherits only `PATH`, `HOME`, the temp-directory variables, and
83
+ * `command.env`. Targets declaring the same command share one process,
84
+ * probed at the first declaring target's `readyUrl`.
85
+ */
86
+ readonly command?: CommandConfig;
87
+ /** URL polled until `command` is ready (a 200-499 status); defaults to `url`. */
88
+ readonly readyUrl?: string;
89
+ /**
90
+ * Dependency processes the app needs before it can boot (a database
91
+ * container, a migration step), started in declaration order before any
92
+ * app command and torn down in reverse after it. Valid without `command`:
93
+ * the app may already be running, or be one of the services itself.
94
+ * Services declared identically by several targets start once; shared
95
+ * services must be declared in one order, and an explicit `name` must mean
96
+ * one process across the run.
97
+ */
98
+ readonly services?: readonly ServiceConfig[];
99
+ }
100
+ /** The app under test as the harness resolved the engine's declaration, handed back at init. */
101
+ export interface EngineAppInfo {
42
102
  /**
43
103
  * Normalized base URL; the target of `app.open()` with no path. Absent when
44
- * the project configured no app URL: a surface that needs one then fails
45
- * the call that needs it, and never navigates to a placeholder.
104
+ * the engine declared no `url`: a surface that needs one then fails the
105
+ * call that needs it, and never navigates to a placeholder.
46
106
  */
47
107
  readonly baseUrl?: string;
48
108
  /** Origins navigation and cookie policy admit. */
@@ -62,14 +122,14 @@ export type FixtureOperations<T extends object> = {
62
122
  readonly [Key in keyof T]?: T[Key] extends (...args: infer Args) => Promise<unknown> ? FixtureOperation<Args> : T[Key] extends object ? FixtureOperations<T[Key]> : never;
63
123
  };
64
124
  /** Context handed to a contributed fixture factory, once per attempt. */
65
- export interface BackendFixtureContext {
125
+ export interface EngineFixtureContext {
66
126
  readonly targetName: string;
67
127
  /** Records the declared operations before invoking them; undeclared accessors retain their identity. */
68
128
  fixture<T extends object>(name: string, surface: T, operations: FixtureOperations<T>): T;
69
- readonly app: BackendAppInfo & {
129
+ readonly app: EngineAppInfo & {
70
130
  /**
71
131
  * Resolves a navigation target against the base URL and the origin
72
- * policy. Throws `APP_URL_REQUIRED` when no app URL is configured and
132
+ * policy. Throws `APP_URL_REQUIRED` when the engine declared no URL and
73
133
  * `POLICY_DENIED` for a disallowed origin or scheme, so a fixture never
74
134
  * re-implements the policy the harness owns.
75
135
  */
@@ -111,22 +171,22 @@ export interface BackendFixtureContext {
111
171
  }
112
172
  /**
113
173
  * A contributed fixture: any record of async methods, sync accessors, and
114
- * nested namespaces. Declare recorded methods with context.fixture; their
115
- * metadata controls labels, deadlines and verification. Plain surfaces remain
116
- * supported through the legacy adapter for existing backend factories.
174
+ * nested namespaces, declared through context.fixture so its metadata controls
175
+ * labels, deadlines and verification. The factory must return the declared
176
+ * surface; a plain one is rejected with INVALID_CONFIG.
117
177
  */
118
- export type BackendFixtureFactory = (context: BackendFixtureContext) => object;
178
+ export type EngineFixtureFactory = (context: EngineFixtureContext) => object;
119
179
  /**
120
- * An opaque, restorable snapshot of a backend's state. `data` is JSON the
180
+ * An opaque, restorable snapshot of an engine's state. `data` is JSON the
121
181
  * harness never inspects - a document platform's storage state, a device's app state, a
122
182
  * desktop's window state all satisfy it identically. `format`/`version` let a
123
- * backend reject a snapshot it can no longer read.
183
+ * engine reject a snapshot it can no longer read.
124
184
  */
125
- export interface BackendState {
185
+ export interface EngineState {
126
186
  readonly format: string;
127
187
  readonly version: number;
128
188
  readonly data: unknown;
129
- /** Earliest moment the state is known to be invalid, if the backend knows one. */
189
+ /** Earliest moment the state is known to be invalid, if the engine knows one. */
130
190
  readonly expiresAt?: string;
131
191
  }
132
192
  /**
@@ -137,23 +197,23 @@ export interface BackendState {
137
197
  * the app under test. The duties split at the seam. The harness owns the
138
198
  * snapshot from the moment `capture` returns: it encrypts it at rest with a
139
199
  * per-run AES-256-GCM key that never touches disk, stores it under the run's
140
- * private session directory, binds it to the run, target, backend, and app
200
+ * private session directory, binds it to the run, target, engine, and app
141
201
  * identity, and deletes it when the run ends; it never logs it, reports it,
142
- * digests it, or sends it to a model. A backend MUST NOT persist, cache, or
202
+ * digests it, or sends it to a model. An engine MUST NOT persist, cache, or
143
203
  * log a snapshot on its own, MUST NOT echo snapshot contents in an error
144
204
  * message, and MUST treat `restore` as a replacement of the surface's whole
145
205
  * persisted state, never a merge, so a restored session cannot leak into the
146
206
  * next attempt.
147
207
  */
148
- export interface BackendStateCapability {
149
- capture(context: OperationContext): Promise<BackendState>;
150
- restore(state: BackendState, context: OperationContext): Promise<void>;
208
+ export interface EngineStateCapability {
209
+ capture(context: OperationContext): Promise<EngineState>;
210
+ restore(state: EngineState, context: OperationContext): Promise<void>;
151
211
  }
152
212
  /**
153
213
  * Evidence capture. Paths are relative to the attempt artifact directory the
154
- * backend received in `startAttempt`.
214
+ * engine received in `startAttempt`.
155
215
  */
156
- export interface BackendArtifacts {
216
+ export interface EngineArtifacts {
157
217
  /** Captures a redacted screenshot; secure fields are masked at the source. */
158
218
  screenshot(label: string | undefined, context: OperationContext): Promise<string>;
159
219
  /** Starts recording an execution trace for the attempt. */
@@ -162,10 +222,12 @@ export interface BackendArtifacts {
162
222
  stopTrace?(context: OperationContext): Promise<string>;
163
223
  }
164
224
  /**
165
- * App-level hooks behind the universal `app` fixture and the agent's
166
- * `navigate` verb. Node actions never live here; they are `perform`.
225
+ * The app under test: what the engine declares about it
226
+ * (`EngineAppDeclaration`) and the app-level hooks behind the universal
227
+ * `app` fixture and the agent's `navigate` verb. Node actions never live
228
+ * here; they are `perform`.
167
229
  */
168
- export interface BackendApp {
230
+ export interface EngineApp extends EngineAppDeclaration {
169
231
  /**
170
232
  * Opens one URL the harness already resolved against the base URL and the
171
233
  * origin policy. Absent on a surface without addressable locations.
@@ -182,7 +244,7 @@ export interface BackendApp {
182
244
  * Facts handed to `prepare`, once per run and target in the runner process,
183
245
  * before any worker exists.
184
246
  */
185
- export interface BackendPrepareInfo {
247
+ export interface EnginePrepareInfo {
186
248
  readonly runId: string;
187
249
  readonly targetName: string;
188
250
  /**
@@ -207,17 +269,17 @@ export interface BackendPrepareInfo {
207
269
  readonly log: (line: string) => void;
208
270
  }
209
271
  /** Run identity and harness-resolved facts handed to `init`, once per worker before the first step. */
210
- export interface BackendInitInfo {
272
+ export interface EngineInitInfo {
211
273
  readonly runId: string;
212
274
  readonly targetName: string;
213
275
  /**
214
276
  * Directory relative paths in the config resolve against: the config file's
215
- * directory, or the run's `cwd` for a programmatic config. A backend option
277
+ * directory, or the run's `cwd` for a programmatic config. An engine option
216
278
  * naming a file (a build to install) resolves here, never against
217
279
  * `process.cwd()`, which an in-process run does not change.
218
280
  */
219
281
  readonly projectRoot: string;
220
- readonly app: BackendAppInfo;
282
+ readonly app: EngineAppInfo;
221
283
  /** Attribute the `testId` query resolves against. */
222
284
  readonly testIdAttribute: string;
223
285
  /** Whether the run asked for a visible surface (`--headed`). */
@@ -226,11 +288,11 @@ export interface BackendInitInfo {
226
288
  readonly signal: AbortSignal;
227
289
  }
228
290
  /**
229
- * Per-attempt isolation context. A backend that must give each test a fresh
291
+ * Per-attempt isolation context. An engine that must give each test a fresh
230
292
  * surface (a fresh isolated context per test, a reset device) sets it up in
231
293
  * `startAttempt` and tears it down in `endAttempt`.
232
294
  */
233
- export interface BackendAttemptContext {
295
+ export interface EngineAttemptContext {
234
296
  readonly attemptId: string;
235
297
  /** Absolute directory every artifact of this attempt is written under. */
236
298
  readonly artifactsDir: string;
@@ -246,22 +308,22 @@ export interface BackendAttemptContext {
246
308
  * the budget is exhausted, so a hook that cannot finish in time stops instead
247
309
  * of running on into the next attempt's setup.
248
310
  */
249
- export interface BackendCleanupContext {
311
+ export interface EngineCleanupContext {
250
312
  readonly signal: AbortSignal;
251
313
  /** Remaining cleanup budget when the call starts. */
252
314
  readonly timeoutMs: number;
253
315
  }
254
- export interface BackendObserveOptions {
316
+ export interface EngineObserveOptions {
255
317
  /** Requests masked viewport pixels for the same revision as the tree. */
256
318
  readonly pixels?: boolean;
257
319
  }
258
320
  /**
259
321
  * One fresh semantic snapshot of the surface under test. The harness owns
260
322
  * everything downstream: revision minting, secret redaction, and the
261
- * observation byte budget apply to every backend equally.
323
+ * observation byte budget apply to every engine equally.
262
324
  */
263
- export interface BackendSnapshot {
264
- /** Location captured with this tree, when the backend can provide it. */
325
+ export interface EngineSnapshot {
326
+ /** Location captured with this tree, when the engine can provide it. */
265
327
  readonly url?: string;
266
328
  readonly nodes: readonly SemanticNode[];
267
329
  readonly viewport?: {
@@ -275,24 +337,24 @@ export interface BackendSnapshot {
275
337
  readonly maskedRegionCount?: number;
276
338
  }
277
339
  /** The body of one target: typed, model-free, capability-graded. */
278
- export interface Backend {
340
+ export interface Engine {
279
341
  readonly name: string;
280
342
  /**
281
343
  * Implementation version, recorded as provenance and part of the trace
282
- * cache identity: a backend that resolves nodes differently must not replay
283
- * another version's traces, so an unversioned backend is not accepted.
344
+ * cache identity: an engine that resolves nodes differently must not replay
345
+ * another version's traces, so an unversioned engine is not accepted.
284
346
  */
285
347
  readonly version: string;
286
348
  /**
287
349
  * Contract version literal. Additive optional members never bump it;
288
350
  * changed required semantics do.
289
351
  */
290
- readonly spiVersion: BackendSpiVersion;
352
+ readonly spiVersion: EngineSpiVersion;
291
353
  /** capability: observation. */
292
- observe?(context: OperationContext, options?: BackendObserveOptions): Promise<BackendSnapshot>;
354
+ observe?(context: OperationContext, options?: EngineObserveOptions): Promise<EngineSnapshot>;
293
355
  /**
294
356
  * capability: actions - requires observation. Performs exactly one action
295
- * on a ref this backend minted, from the newest observation or from
357
+ * on a ref this engine minted, from the newest observation or from
296
358
  * `locate` (both live in one id space), with the platform's actionability
297
359
  * checks. The agent's grammar verbs (tap, type, press, select, node scroll)
298
360
  * and the `screen` tier's actions both bottom out here, so a surface
@@ -308,7 +370,7 @@ export interface Backend {
308
370
  * capability: location - requires observation. Deterministic locator
309
371
  * resolution for the `screen`/`expect` tier: resolve one expression to the
310
372
  * nodes it currently matches. The harness owns polling, strictness, and
311
- * staleness; a backend resolves once, immediately.
373
+ * staleness; an engine resolves once, immediately.
312
374
  */
313
375
  locate?(expression: LocatorExpression, context: OperationContext): Promise<readonly SemanticNode[]>;
314
376
  /**
@@ -317,17 +379,17 @@ export interface Backend {
317
379
  */
318
380
  swipe?(direction: ScrollDirection, momentum: Momentum | undefined, context: OperationContext): Promise<void>;
319
381
  /**
320
- * Named deterministic surfaces this backend contributes to TestFixtures
382
+ * Named deterministic surfaces this engine contributes to TestFixtures
321
383
  * (a device fixture, a document fixture - anything). Keys become fixture and
322
384
  * capability names; `requires: ['<name>']` gates at selection.
323
385
  */
324
- readonly fixtures?: Readonly<Record<string, BackendFixtureFactory>>;
386
+ readonly fixtures?: Readonly<Record<string, EngineFixtureFactory>>;
325
387
  /** capability: state - opaque snapshot capture/restore for session reuse. */
326
- readonly state?: BackendStateCapability;
388
+ readonly state?: EngineStateCapability;
327
389
  /** capability: artifacts - screenshots and traces under the attempt directory. */
328
- readonly artifacts?: BackendArtifacts;
329
- /** App-level hooks: navigate, back, restart, clearState. */
330
- readonly app?: BackendApp;
390
+ readonly artifacts?: EngineArtifacts;
391
+ /** The app under test: its declaration (url, identity, command...) and hooks (navigate, back, restart, clearState). */
392
+ readonly app?: EngineApp;
331
393
  /**
332
394
  * Current top-level URL of the surface, when the platform has one. Enables
333
395
  * trace start anchors and the secret-fill origin check.
@@ -335,40 +397,40 @@ export interface Backend {
335
397
  url?(context: OperationContext): Promise<string>;
336
398
  /**
337
399
  * Once per run and target, in the runner process, before any worker starts
338
- * and outside every launch budget. Provision what the backend needs on this
400
+ * and outside every launch budget. Provision what the engine needs on this
339
401
  * machine here (a first-run browser download, a toolchain fetch), so it
340
402
  * happens once instead of per worker and its progress reaches the reporter
341
403
  * through `info.log`. Failure is infrastructure and ends the run before any
342
404
  * test executes.
343
405
  */
344
- prepare?(info: BackendPrepareInfo): Promise<void>;
406
+ prepare?(info: EnginePrepareInfo): Promise<void>;
345
407
  /**
346
408
  * Once per worker, before the first step; boot devices here, not in a step
347
409
  * budget. The same handle can be booted again after `dispose`: a config-held
348
410
  * handle outlives an in-process worker, so init MUST work on a disposed
349
- * backend as it does on a fresh one.
411
+ * engine as it does on a fresh one.
350
412
  */
351
- init?(info: BackendInitInfo): Promise<void>;
413
+ init?(info: EngineInitInfo): Promise<void>;
352
414
  /** Before each attempt: set up per-test isolation. */
353
- startAttempt?(context: BackendAttemptContext): Promise<void>;
415
+ startAttempt?(context: EngineAttemptContext): Promise<void>;
354
416
  /**
355
417
  * After each attempt, within the cleanup budget: tear that isolation down.
356
418
  * MUST be idempotent, and safe to call after a failed `startAttempt`.
357
419
  */
358
- endAttempt?(context: BackendCleanupContext): Promise<void>;
420
+ endAttempt?(context: EngineCleanupContext): Promise<void>;
359
421
  /**
360
422
  * Worker shutdown, within the cleanup budget; failure is a run error. Runs
361
- * whether or not `init` ran, so it MUST tolerate a cold backend.
423
+ * whether or not `init` ran, so it MUST tolerate a cold engine.
362
424
  */
363
- dispose?(context: BackendCleanupContext): Promise<void>;
425
+ dispose?(context: EngineCleanupContext): Promise<void>;
364
426
  }
365
- /** A validated backend: branded, frozen, capabilities computed. */
366
- export interface BackendHandle extends Backend {
367
- readonly [backendBrand]: true;
368
- readonly capabilities: ReadonlySet<BackendCapability>;
427
+ /** A validated engine: branded, frozen, capabilities computed. */
428
+ export interface EngineHandle extends Engine {
429
+ readonly [engineBrand]: true;
430
+ readonly capabilities: ReadonlySet<EngineCapability>;
369
431
  }
370
432
  /**
371
- * Validates a backend and computes its capability set. Runs synchronously at
433
+ * Validates an engine and computes its capability set. Runs synchronously at
372
434
  * config load and fails loud: a misspelled member or an undeclared dependency
373
435
  * is `INVALID_CONFIG`, never a silent demotion to a lower tier.
374
436
  *
@@ -376,7 +438,7 @@ export interface BackendHandle extends Backend {
376
438
  * through the prototype chain and binding every function to the spec, so a
377
439
  * class instance (own state fields included) is as valid a body as a literal.
378
440
  */
379
- export declare function defineBackend(spec: Backend): BackendHandle;
380
- /** True for a defineBackend-branded handle, across realms. */
381
- export declare function isBackendHandle(value: unknown): value is BackendHandle;
441
+ export declare function defineEngine(spec: Engine): EngineHandle;
442
+ /** True for a defineEngine-branded handle, across realms. */
443
+ export declare function isEngineHandle(value: unknown): value is EngineHandle;
382
444
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAQpD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAClF,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3H,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,OAAO,EACP,QAAQ,EACR,MAAM,EACN,eAAe,EACf,aAAa,EACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAEvB,mBAAmB,eAAe,CAAC;AACnC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,SAAS,EACT,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,eAAe,EACf,YAAY,GACb,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,SAAS,GACT,UAAU,GACV,OAAO,GACP,WAAW,GACX,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;IACzD;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC9C;AAED,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAED,0GAA0G;AAC1G,MAAM,WAAW,gBAAgB,CAAC,IAAI,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE;IAClE,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IAC3C,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5E,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,uFAAuF;AACvF,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,MAAM,IAAI;IAChD,QAAQ,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,GAChF,gBAAgB,CAAC,IAAI,CAAC,GACtB,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK;CAC9D,CAAC;AAEF,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wGAAwG;IACxG,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACzF,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG;QAC5B;;;;;WAKG;QACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACjC,CAAC;IACF,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,kGAAkG;IAClG,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAChD,uFAAuF;IACvF,cAAc,CACZ,IAAI,EAAE,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,EAC3D,YAAY,EAAE,MAAM,GACnB,IAAI,CAAC;IACR,yDAAyD;IACzD,cAAc,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,+EAA+E;IAC/E,OAAO,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAChD,6FAA6F;IAC7F,MAAM,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,iBAAiB,GAAG,MAAM,CAAC;IAC5E;;;;OAIG;IACH,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;CAChG;AAED;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClF,2DAA2D;IAC3D,UAAU,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,qDAAqD;IACrD,SAAS,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxD;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAU,SAAQ,oBAAoB;IACrD;;;OAGG;IACH,QAAQ,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,oDAAoD;IACpD,IAAI,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,gFAAgF;IAChF,OAAO,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,oDAAoD;IACpD,UAAU,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,uGAAuG;AACvG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAChG,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC,kFAAkF;IAClF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,oEAAoE;AACpE,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,+BAA+B;IAC/B,OAAO,CAAC,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7F;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF;;;;;OAKG;IACH,MAAM,CAAC,CACL,UAAU,EAAE,iBAAiB,EAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;IACpC;;;OAGG;IACH,KAAK,CAAC,CACJ,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACnE,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC;IACvC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IACrC,uHAAuH;IACvH,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;IACzB;;;OAGG;IACH,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD;;;;;OAKG;IACH,IAAI,CAAC,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,sDAAsD;IACtD,YAAY,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D;;;OAGG;IACH,UAAU,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D;;;OAGG;IACH,OAAO,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;CACtD;AA+GD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAuGvD;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAMpE"}
@@ -1,27 +1,27 @@
1
1
  /**
2
- * The backend contract (RFC0002): the typed, model-free body of one target.
2
+ * The engine contract (RFC0002): the typed, model-free body of one target.
3
3
  *
4
- * A backend never talks to a model. It declares capabilities - observation,
4
+ * An engine never talks to a model. It declares capabilities - observation,
5
5
  * actions, location, state, artifacts, contributed fixtures - and the harness
6
- * grades what a target can do from what its backend declares: observation
6
+ * grades what a target can do from what its engine declares: observation
7
7
  * unlocks the judgment tier and prompt snapshots, `perform` unlocks the
8
8
  * harness-routed node actions (the agent's grammar verbs and the `screen`
9
9
  * tier's actions alike), location unlocks `screen`/`expect`. Every piece of
10
10
  * model-facing vocabulary is an agent-side `defineTool`; a target with no
11
- * backend at all is valid and simply runs everything opaque.
11
+ * engine at all is valid and simply runs everything opaque.
12
12
  *
13
- * Core knows this contract and never a backend's internals: no platform noun
14
- * appears here. A document backend, a simulator backend, and a desktop backend
13
+ * Core knows this contract and never an engine's internals: no platform noun
14
+ * appears here. A document engine, a simulator engine, and a desktop engine
15
15
  * fill in the same members with different bodies.
16
16
  *
17
- * `defineBackend` is the loud manifest: capability detection happens here,
18
- * synchronously, at config load - a malformed backend fails the run instead
17
+ * `defineEngine` is the loud manifest: capability detection happens here,
18
+ * synchronously, at config load - a malformed engine fails the run instead
19
19
  * of silently demoting itself to a lower tier.
20
20
  */
21
- import { backendBrand } from '../internal/brands.js';
21
+ import { engineBrand } from '../internal/brands.js';
22
22
  import { ConfigurationError } from '../internal/errors.js';
23
- // Semantics the spec requires every backend and contributed fixture to
24
- // reproduce exactly, exported so a backend never carries its own copy: the
23
+ // Semantics the spec requires every engine and contributed fixture to
24
+ // reproduce exactly, exported so an engine never carries its own copy: the
25
25
  // runner error taxonomy (06-cli.md), text-pattern matching (04-locators.md),
26
26
  // URL matching (03-assertions.md), assertion polling (03-assertions.md), and
27
27
  // the JSON-value rules for data a fixture returns.
@@ -31,9 +31,10 @@ export { describePattern, matchesText, toTextPattern } from '../internal/text.js
31
31
  export { raceAbort } from './timing.js';
32
32
  export { Deadline, pollCondition, withTimeout, withinCleanupBudget } from '../internal/time.js';
33
33
  export { urlMatches } from '../internal/urls.js';
34
- import { BACKEND_SPI_VERSION, } from './contract.js';
35
- export { BACKEND_ERROR_CODES, BACKEND_SPI_VERSION, BackendError, OBSERVED_NAME_LIMIT, OBSERVED_TEXT_LIMIT, RETRYABLE_BACKEND_ERROR_CODES, } from './contract.js';
36
- /** Every key a backend may declare; anything else is rejected at config load. */
34
+ export { obj } from '../internal/objects.js';
35
+ import { ENGINE_SPI_VERSION, } from './contract.js';
36
+ export { ENGINE_ERROR_CODES, ENGINE_SPI_VERSION, EngineError, OBSERVED_NAME_LIMIT, OBSERVED_TEXT_LIMIT, RETRYABLE_ENGINE_ERROR_CODES, } from './contract.js';
37
+ /** Every key an engine may declare; anything else is rejected at config load. */
37
38
  const KNOWN_KEYS = [
38
39
  'name',
39
40
  'version',
@@ -59,6 +60,20 @@ const NESTED_KEYS = {
59
60
  artifacts: ['screenshot', 'startTrace', 'stopTrace'],
60
61
  app: ['navigate', 'back', 'restart', 'clearState'],
61
62
  };
63
+ /**
64
+ * Declarative members of the `app` manifest: facts about the app under test,
65
+ * copied through as data. Their values are validated when the config resolves
66
+ * the target, where an error can name it.
67
+ */
68
+ const APP_DECLARATION_KEYS = [
69
+ 'url',
70
+ 'allowedOrigins',
71
+ 'environment',
72
+ 'identity',
73
+ 'command',
74
+ 'readyUrl',
75
+ 'services',
76
+ ];
62
77
  const FUNCTION_MEMBERS = [
63
78
  'observe',
64
79
  'locate',
@@ -75,26 +90,36 @@ const FUNCTION_MEMBERS = [
75
90
  const RESERVED_FIXTURES = new Set(['agent', 'app', 'screen', 'platform', 'session']);
76
91
  const FIXTURE_NAME_PATTERN = /^[a-z][A-Za-z0-9]*$/;
77
92
  function invalid(name, detail) {
78
- return new ConfigurationError('INVALID_CONFIG', `backend "${name}": ${detail}`);
93
+ return new ConfigurationError('INVALID_CONFIG', `engine "${name}": ${detail}`);
79
94
  }
80
95
  /**
81
96
  * Validates one nested manifest (`state`, `artifacts`, `app`): a plain object
82
- * whose keys are closed and whose declared members are functions. Returns a
83
- * copy with every member bound to the manifest, so class-based bodies work.
97
+ * whose keys are closed and whose declared members are functions, except the
98
+ * `app` declaration's data members, which are copied through. Returns a copy
99
+ * with every function bound to the manifest, so class-based bodies work.
84
100
  */
85
101
  function nestedManifest(name, key, value, required = []) {
86
- if (typeof value !== 'object' || value === null) {
102
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
87
103
  throw invalid(name, `${key} must be an object`);
88
104
  }
89
- const allowed = NESTED_KEYS[key];
105
+ const hooks = NESTED_KEYS[key];
106
+ const data = key === 'app' ? APP_DECLARATION_KEYS : [];
90
107
  const source = value;
91
108
  for (const member of Object.keys(source)) {
92
- if (!allowed.includes(member)) {
93
- throw invalid(name, `${key} has unknown key "${member}"; expected one of ${allowed.join(', ')}`);
109
+ if (!hooks.includes(member) && !data.includes(member)) {
110
+ throw invalid(name, `${key} has unknown key "${member}"; expected one of ${[...data, ...hooks].join(', ')}`);
94
111
  }
95
112
  }
96
113
  const bound = {};
97
- for (const member of allowed) {
114
+ for (const member of data) {
115
+ const fact = source[member];
116
+ if (fact === undefined)
117
+ continue;
118
+ if (typeof fact === 'function')
119
+ throw invalid(name, `${key}.${member} is a declaration, not a hook`);
120
+ bound[member] = fact;
121
+ }
122
+ for (const member of hooks) {
98
123
  const fn = source[member];
99
124
  if (fn === undefined) {
100
125
  if (required.includes(member))
@@ -108,7 +133,7 @@ function nestedManifest(name, key, value, required = []) {
108
133
  return bound;
109
134
  }
110
135
  /**
111
- * Validates a backend and computes its capability set. Runs synchronously at
136
+ * Validates an engine and computes its capability set. Runs synchronously at
112
137
  * config load and fails loud: a misspelled member or an undeclared dependency
113
138
  * is `INVALID_CONFIG`, never a silent demotion to a lower tier.
114
139
  *
@@ -116,19 +141,19 @@ function nestedManifest(name, key, value, required = []) {
116
141
  * through the prototype chain and binding every function to the spec, so a
117
142
  * class instance (own state fields included) is as valid a body as a literal.
118
143
  */
119
- export function defineBackend(spec) {
144
+ export function defineEngine(spec) {
120
145
  if (typeof spec !== 'object' || spec === null) {
121
- throw new ConfigurationError('INVALID_CONFIG', 'defineBackend requires a backend object');
146
+ throw new ConfigurationError('INVALID_CONFIG', 'defineEngine requires an engine object');
122
147
  }
123
148
  if (typeof spec.name !== 'string' || spec.name.trim() === '') {
124
- throw new ConfigurationError('INVALID_CONFIG', 'backend.name must be a non-empty string');
149
+ throw new ConfigurationError('INVALID_CONFIG', 'engine.name must be a non-empty string');
125
150
  }
126
151
  const name = spec.name;
127
152
  if (typeof spec.version !== 'string' || spec.version.trim() === '') {
128
153
  throw invalid(name, 'version must be a non-empty string; it is provenance and keys the trace cache');
129
154
  }
130
- if (spec.spiVersion !== BACKEND_SPI_VERSION) {
131
- throw invalid(name, `declares spiVersion ${String(spec.spiVersion)}; this runner supports ${BACKEND_SPI_VERSION}`);
155
+ if (spec.spiVersion !== ENGINE_SPI_VERSION) {
156
+ throw invalid(name, `declares spiVersion ${String(spec.spiVersion)}; this runner supports ${ENGINE_SPI_VERSION}`);
132
157
  }
133
158
  // A literal's unknown key is a misspelling or a misplaced tool; a class
134
159
  // instance's own fields are its state, so only literals are checked.
@@ -136,7 +161,7 @@ export function defineBackend(spec) {
136
161
  const known = KNOWN_KEYS;
137
162
  for (const key of Object.keys(spec)) {
138
163
  if (!known.includes(key)) {
139
- throw invalid(name, `unknown key "${key}" - tools belong on the agent, not the backend`);
164
+ throw invalid(name, `unknown key "${key}" - tools belong on the agent, not the engine`);
140
165
  }
141
166
  }
142
167
  }
@@ -185,7 +210,7 @@ export function defineBackend(spec) {
185
210
  }
186
211
  capabilities.add(fixture);
187
212
  }
188
- // Bound like every other member, so a class-based backend keeps `this`
213
+ // Bound like every other member, so a class-based engine keeps `this`
189
214
  // in its fixture factories too.
190
215
  handle['fixtures'] = Object.freeze(Object.fromEntries(Object.entries(spec.fixtures).map(([fixture, factory]) => [
191
216
  fixture,
@@ -206,17 +231,17 @@ export function defineBackend(spec) {
206
231
  }
207
232
  if (spec.app !== undefined)
208
233
  handle['app'] = nestedManifest(name, 'app', spec.app);
209
- // Assembled key by key above, so the record is a Backend by construction.
234
+ // Assembled key by key above, so the record is an Engine by construction.
210
235
  return Object.freeze({
211
236
  ...handle,
212
- [backendBrand]: true,
237
+ [engineBrand]: true,
213
238
  capabilities,
214
239
  });
215
240
  }
216
- /** True for a defineBackend-branded handle, across realms. */
217
- export function isBackendHandle(value) {
241
+ /** True for a defineEngine-branded handle, across realms. */
242
+ export function isEngineHandle(value) {
218
243
  return (typeof value === 'object' &&
219
244
  value !== null &&
220
- value[backendBrand] === true);
245
+ value[engineBrand] === true);
221
246
  }
222
247
  //# sourceMappingURL=index.js.map