codex-chatgpt-control 0.5.1-alpha.2 → 0.5.1-alpha.4

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 (231) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +43 -0
  3. package/contracts/v1/fixtures/backend-capabilities.json +40 -1
  4. package/contracts/v1/fixtures/backend-compatibility.json +21 -0
  5. package/contracts/v1/fixtures/backend-version.json +6 -1
  6. package/contracts/v1/fixtures/download-blocked-by-browser.json +22 -0
  7. package/contracts/v1/fixtures/download-receipt-failed.json +22 -0
  8. package/contracts/v1/fixtures/download-receipt-timeout.json +22 -0
  9. package/contracts/v1/fixtures/journal-rpc-indeterminate.json +32 -0
  10. package/contracts/v1/fixtures/journal-rpc-unsupported-platform.json +32 -0
  11. package/contracts/v1/fixtures/journal-runtime-unavailable.json +32 -0
  12. package/contracts/v1/fixtures/operation-action-prepared-event.json +42 -0
  13. package/contracts/v1/fixtures/operation-action.json +13 -0
  14. package/contracts/v1/fixtures/operation-artifact-receipt.json +14 -0
  15. package/contracts/v1/fixtures/operation-artifact-transfer-intent-event.json +24 -0
  16. package/contracts/v1/fixtures/operation-artifact-transfer-receipt-event.json +26 -0
  17. package/contracts/v1/fixtures/operation-artifact-transfer-state.json +178 -0
  18. package/contracts/v1/fixtures/operation-blocker.json +10 -0
  19. package/contracts/v1/fixtures/operation-collect-request.json +17 -0
  20. package/contracts/v1/fixtures/operation-collect-result.json +42 -0
  21. package/contracts/v1/fixtures/operation-control-receipt.json +13 -0
  22. package/contracts/v1/fixtures/operation-control-request.json +18 -0
  23. package/contracts/v1/fixtures/operation-control-result.json +31 -0
  24. package/contracts/v1/fixtures/operation-event.json +18 -0
  25. package/contracts/v1/fixtures/operation-handle.json +10 -0
  26. package/contracts/v1/fixtures/operation-inspect-request.json +13 -0
  27. package/contracts/v1/fixtures/operation-inspect-result.json +205 -0
  28. package/contracts/v1/fixtures/operation-ownership-baseline-event.json +34 -0
  29. package/contracts/v1/fixtures/operation-receipt.json +32 -0
  30. package/contracts/v1/fixtures/operation-recovery-decision.json +7 -0
  31. package/contracts/v1/fixtures/operation-recovery-observation.json +12 -0
  32. package/contracts/v1/fixtures/operation-request.json +33 -0
  33. package/contracts/v1/fixtures/operation-state.json +144 -0
  34. package/contracts/v1/fixtures/operation-submission-witness-event.json +20 -0
  35. package/contracts/v1/fixtures/operation-submission-witness.json +11 -0
  36. package/contracts/v1/fixtures/operation-submit-result.json +16 -0
  37. package/contracts/v1/fixtures/operation-target-established-event.json +21 -0
  38. package/contracts/v1/manifest.json +185 -1
  39. package/contracts/v1/parity-suite.json +106 -8
  40. package/contracts/v1/schemas/backend-compatibility.schema.json +65 -0
  41. package/contracts/v1/schemas/backend-request.schema.json +8 -2
  42. package/contracts/v1/schemas/capabilities.schema.json +81 -1
  43. package/contracts/v1/schemas/manifest.schema.json +57 -0
  44. package/contracts/v1/schemas/operation-action.schema.json +155 -0
  45. package/contracts/v1/schemas/operation-artifact-receipt.schema.json +89 -0
  46. package/contracts/v1/schemas/operation-blocker.schema.json +70 -0
  47. package/contracts/v1/schemas/operation-collect-request.schema.json +46 -0
  48. package/contracts/v1/schemas/operation-collect-result.schema.json +74 -0
  49. package/contracts/v1/schemas/operation-control-receipt.schema.json +108 -0
  50. package/contracts/v1/schemas/operation-control-request.schema.json +111 -0
  51. package/contracts/v1/schemas/operation-control-result.schema.json +112 -0
  52. package/contracts/v1/schemas/operation-event.schema.json +756 -0
  53. package/contracts/v1/schemas/operation-handle.schema.json +55 -0
  54. package/contracts/v1/schemas/operation-inspect-request.schema.json +42 -0
  55. package/contracts/v1/schemas/operation-inspect-result.schema.json +1662 -0
  56. package/contracts/v1/schemas/operation-receipt.schema.json +153 -0
  57. package/contracts/v1/schemas/operation-recovery.schema.json +314 -0
  58. package/contracts/v1/schemas/operation-request.schema.json +158 -0
  59. package/contracts/v1/schemas/operation-state.schema.json +691 -0
  60. package/contracts/v1/schemas/operation-submission-witness.schema.json +48 -0
  61. package/contracts/v1/schemas/operation-submit-result.schema.json +94 -0
  62. package/contracts/v1/surface-drift-policy.json +50 -0
  63. package/contracts/v1/vectors/operation-request-digest-v1.json +43 -0
  64. package/dist/codex-chatgpt-control-backend.mjs +45882 -9361
  65. package/dist/codex-chatgpt-control-journal.mjs +5547 -0
  66. package/dist/codex-chatgpt-control-live-smoke.bundle.mjs +51677 -0
  67. package/dist/codex-chatgpt-control-release-canary.bundle.mjs +52104 -0
  68. package/dist/codex-chatgpt-control.bundle.mjs +48392 -10260
  69. package/dist/src/backend/client.d.ts +103 -2
  70. package/dist/src/backend/client.js +1436 -97
  71. package/dist/src/backend/compatibility.d.ts +12 -0
  72. package/dist/src/backend/compatibility.js +208 -0
  73. package/dist/src/backend/protocol.d.ts +84 -1
  74. package/dist/src/backend/protocol.js +31 -5
  75. package/dist/src/backend/runtime-identity.d.ts +10 -0
  76. package/dist/src/backend/runtime-identity.js +141 -0
  77. package/dist/src/backend/session.d.ts +10 -2
  78. package/dist/src/backend/session.js +478 -7
  79. package/dist/src/backend/stdio-server.d.ts +4 -1
  80. package/dist/src/backend/stdio-server.js +240 -28
  81. package/dist/src/browser/active-composer-file-input.d.ts +9 -0
  82. package/dist/src/browser/active-composer-file-input.js +33 -0
  83. package/dist/src/browser/attach.d.ts +4 -1
  84. package/dist/src/browser/attach.js +136 -28
  85. package/dist/src/browser/chatgpt-url.d.ts +2 -0
  86. package/dist/src/browser/chatgpt-url.js +9 -0
  87. package/dist/src/browser/downloads.d.ts +17 -1
  88. package/dist/src/browser/downloads.js +150 -28
  89. package/dist/src/browser/page-state.js +6 -0
  90. package/dist/src/client.d.ts +43 -0
  91. package/dist/src/client.js +1279 -59
  92. package/dist/src/commands/artifacts.js +6 -4
  93. package/dist/src/commands/chat-popover.d.ts +37 -0
  94. package/dist/src/commands/chat-popover.js +537 -0
  95. package/dist/src/commands/configuration.d.ts +5 -0
  96. package/dist/src/commands/configuration.js +134 -21
  97. package/dist/src/commands/context.js +10 -3
  98. package/dist/src/commands/doctor.d.ts +1 -1
  99. package/dist/src/commands/doctor.js +27 -4
  100. package/dist/src/commands/experience.d.ts +5 -0
  101. package/dist/src/commands/experience.js +104 -21
  102. package/dist/src/commands/files.js +14 -33
  103. package/dist/src/commands/modes.js +85 -21
  104. package/dist/src/commands/power-discovery.d.ts +130 -0
  105. package/dist/src/commands/power-discovery.js +669 -0
  106. package/dist/src/commands/project-sources.js +325 -31
  107. package/dist/src/commands/sequence.js +59 -32
  108. package/dist/src/commands/session.js +19 -6
  109. package/dist/src/commands/work.js +31 -0
  110. package/dist/src/dom/composer-text.d.ts +6 -0
  111. package/dist/src/dom/composer-text.js +85 -0
  112. package/dist/src/errors.d.ts +9 -0
  113. package/dist/src/errors.js +22 -0
  114. package/dist/src/index.d.ts +6 -0
  115. package/dist/src/index.js +9 -0
  116. package/dist/src/operations/artifact-output.d.ts +69 -0
  117. package/dist/src/operations/artifact-output.js +1748 -0
  118. package/dist/src/operations/artifact-stream.d.ts +19 -0
  119. package/dist/src/operations/artifact-stream.js +35 -0
  120. package/dist/src/operations/artifact-transfer.d.ts +149 -0
  121. package/dist/src/operations/artifact-transfer.js +1312 -0
  122. package/dist/src/operations/browser-adapter.d.ts +167 -0
  123. package/dist/src/operations/browser-adapter.js +2103 -0
  124. package/dist/src/operations/browser-observation.d.ts +110 -0
  125. package/dist/src/operations/browser-observation.js +1256 -0
  126. package/dist/src/operations/browser-target.d.ts +105 -0
  127. package/dist/src/operations/browser-target.js +531 -0
  128. package/dist/src/operations/canonical.d.ts +4 -0
  129. package/dist/src/operations/canonical.js +412 -0
  130. package/dist/src/operations/chatgpt-runtime.d.ts +72 -0
  131. package/dist/src/operations/chatgpt-runtime.js +1232 -0
  132. package/dist/src/operations/client.d.ts +138 -0
  133. package/dist/src/operations/client.js +1145 -0
  134. package/dist/src/operations/collector.d.ts +195 -0
  135. package/dist/src/operations/collector.js +1039 -0
  136. package/dist/src/operations/configuration-routing.d.ts +4 -0
  137. package/dist/src/operations/configuration-routing.js +14 -0
  138. package/dist/src/operations/control.d.ts +372 -0
  139. package/dist/src/operations/control.js +1498 -0
  140. package/dist/src/operations/file-identity.d.ts +33 -0
  141. package/dist/src/operations/file-identity.js +153 -0
  142. package/dist/src/operations/handle.d.ts +19 -0
  143. package/dist/src/operations/handle.js +727 -0
  144. package/dist/src/operations/index.d.ts +25 -0
  145. package/dist/src/operations/index.js +25 -0
  146. package/dist/src/operations/journal-authority.d.ts +12 -0
  147. package/dist/src/operations/journal-authority.js +1 -0
  148. package/dist/src/operations/journal-rpc-client.d.ts +12 -0
  149. package/dist/src/operations/journal-rpc-client.js +225 -0
  150. package/dist/src/operations/journal-rpc-protocol.d.ts +32 -0
  151. package/dist/src/operations/journal-rpc-protocol.js +214 -0
  152. package/dist/src/operations/journal-rpc-server.d.ts +15 -0
  153. package/dist/src/operations/journal-rpc-server.js +272 -0
  154. package/dist/src/operations/journal.d.ts +143 -0
  155. package/dist/src/operations/journal.js +1957 -0
  156. package/dist/src/operations/production-attachments.d.ts +118 -0
  157. package/dist/src/operations/production-attachments.js +1035 -0
  158. package/dist/src/operations/production-chatgpt-artifacts.d.ts +74 -0
  159. package/dist/src/operations/production-chatgpt-artifacts.js +1146 -0
  160. package/dist/src/operations/production-chatgpt-attachments.d.ts +80 -0
  161. package/dist/src/operations/production-chatgpt-attachments.js +1639 -0
  162. package/dist/src/operations/production-configuration.d.ts +42 -0
  163. package/dist/src/operations/production-configuration.js +1544 -0
  164. package/dist/src/operations/production-primitives.d.ts +53 -0
  165. package/dist/src/operations/production-primitives.js +856 -0
  166. package/dist/src/operations/production-work-steer.d.ts +203 -0
  167. package/dist/src/operations/production-work-steer.js +1218 -0
  168. package/dist/src/operations/recovery.d.ts +80 -0
  169. package/dist/src/operations/recovery.js +174 -0
  170. package/dist/src/operations/runtime-adapter.d.ts +126 -0
  171. package/dist/src/operations/runtime-adapter.js +802 -0
  172. package/dist/src/operations/send-once.d.ts +224 -0
  173. package/dist/src/operations/send-once.js +1081 -0
  174. package/dist/src/operations/service.d.ts +286 -0
  175. package/dist/src/operations/service.js +2831 -0
  176. package/dist/src/operations/staging.d.ts +136 -0
  177. package/dist/src/operations/staging.js +630 -0
  178. package/dist/src/operations/state-machine.d.ts +29 -0
  179. package/dist/src/operations/state-machine.js +2047 -0
  180. package/dist/src/operations/submission.d.ts +423 -0
  181. package/dist/src/operations/submission.js +1676 -0
  182. package/dist/src/operations/transactional-chat-power.d.ts +17 -0
  183. package/dist/src/operations/transactional-chat-power.js +212 -0
  184. package/dist/src/operations/turn-ownership.d.ts +202 -0
  185. package/dist/src/operations/turn-ownership.js +700 -0
  186. package/dist/src/operations/types.d.ts +454 -0
  187. package/dist/src/operations/types.js +20 -0
  188. package/dist/src/operations/wire-requests.d.ts +21 -0
  189. package/dist/src/operations/wire-requests.js +396 -0
  190. package/dist/src/operations/wire-results.d.ts +97 -0
  191. package/dist/src/operations/wire-results.js +818 -0
  192. package/dist/src/runner/responses.d.ts +3 -1
  193. package/dist/src/runner/responses.js +19 -1
  194. package/dist/src/runner/result.js +227 -55
  195. package/dist/src/runner/types.d.ts +12 -0
  196. package/dist/src/runtime/command-routing.d.ts +149 -0
  197. package/dist/src/runtime/command-routing.js +431 -0
  198. package/dist/src/runtime/coordinated-browser.d.ts +24 -0
  199. package/dist/src/runtime/coordinated-browser.js +315 -0
  200. package/dist/src/runtime/coordinated-page.d.ts +41 -0
  201. package/dist/src/runtime/coordinated-page.js +651 -0
  202. package/dist/src/runtime/operation-context.d.ts +142 -0
  203. package/dist/src/runtime/operation-context.js +410 -0
  204. package/dist/src/runtime/runtime-session.d.ts +95 -0
  205. package/dist/src/runtime/runtime-session.js +314 -0
  206. package/dist/src/runtime/tab-coordinator.d.ts +200 -0
  207. package/dist/src/runtime/tab-coordinator.js +1200 -0
  208. package/dist/src/runtime/value-boundaries.d.ts +18 -0
  209. package/dist/src/runtime/value-boundaries.js +49 -0
  210. package/dist/src/safety/blockers.js +8 -1
  211. package/dist/src/safety/untrusted-output.js +2 -1
  212. package/dist/src/scripts/backend-server.js +4 -1
  213. package/dist/src/scripts/capture-surface-profile.js +7 -2
  214. package/dist/src/scripts/journal-server.d.ts +2 -0
  215. package/dist/src/scripts/journal-server.js +37 -0
  216. package/dist/src/scripts/live-smoke/harness.js +79 -7
  217. package/dist/src/scripts/live-smoke/scenarios.d.ts +42 -1
  218. package/dist/src/scripts/live-smoke/scenarios.js +147 -30
  219. package/dist/src/scripts/live-smoke/transactional.d.ts +17 -0
  220. package/dist/src/scripts/live-smoke/transactional.js +254 -0
  221. package/dist/src/scripts/live-smoke/types.d.ts +3 -0
  222. package/dist/src/scripts/release-canary-module.js +17 -4
  223. package/dist/src/types.d.ts +38 -1
  224. package/package.json +8 -3
  225. package/references/2026-08-16-transactional-operations.md +459 -0
  226. package/references/2026-09-06-journal-service.md +140 -0
  227. package/references/agents-runner.md +34 -0
  228. package/references/backend-protocol.md +176 -0
  229. package/references/python-parity.md +137 -0
  230. package/references/responses-adapter.md +19 -0
  231. package/references/streaming.md +6 -0
@@ -0,0 +1,802 @@
1
+ import { OperationRuntimeContext } from "../runtime/operation-context.js";
2
+ import { createOperationBrowserAdapter, OperationBrowserAdapterError } from "./browser-adapter.js";
3
+ import { CONTROL_POSTCONDITION_RETRY_POLICY } from "./control.js";
4
+ /** Stable, redacted error boundary for a request-scoped runtime adapter. */
5
+ export class OperationRuntimeAdapterError extends Error {
6
+ code;
7
+ constructor(code) {
8
+ super("The operation browser runtime could not prove the requested action safely.");
9
+ this.name = "OperationRuntimeAdapterError";
10
+ this.code = code;
11
+ }
12
+ }
13
+ /**
14
+ * This is the generic adapter's injection inventory, retained for compatibility
15
+ * with integrations that assemble their own provider runtime. It does not
16
+ * describe the default ChatGPT composite: `chatgpt-runtime.ts` injects the
17
+ * proven production modules for these seams. The generic adapter itself never
18
+ * guesses selectors or routes legacy polling helpers through a tab actor.
19
+ */
20
+ export const UNWIRED_OPERATION_RUNTIME_PRIMITIVES = Object.freeze([
21
+ "new_thread_creation",
22
+ "configuration_set",
23
+ "tool_selection",
24
+ "composer_population",
25
+ "file_chooser_handoff",
26
+ "send_activation",
27
+ "stop_activation",
28
+ "work_steer_activation"
29
+ ]);
30
+ function isAbsolutePath(value) {
31
+ return value.startsWith("/")
32
+ || /^[A-Za-z]:[\\/]/u.test(value)
33
+ || value.startsWith("\\\\");
34
+ }
35
+ /**
36
+ * Compose one lazy runtime capture over the existing operation browser
37
+ * adapter. The returned object is intentionally request-scoped: a caller
38
+ * should construct it in `OperationClient.adapterFactory` and retain it only
39
+ * for the resulting operation handle.
40
+ */
41
+ export function createRuntimeOperationBrowserAdapter(options) {
42
+ options = normalizeRuntimeAdapterOptions(options);
43
+ let capturePromise;
44
+ let innerPromise;
45
+ let captureIdentity;
46
+ const exposeStaging = options.exposeStaging ?? options.primitives?.staging !== undefined;
47
+ const exposeControl = options.exposeControl ?? (options.primitives?.control !== undefined || options.recovery !== undefined);
48
+ const exposeArtifacts = options.exposeArtifacts === true && options.recovery === undefined;
49
+ const captureOnce = (request) => {
50
+ if (captureIdentity !== undefined
51
+ && (captureIdentity.operationId !== request.operationId
52
+ || captureIdentity.requestDigest !== request.requestDigest
53
+ || captureIdentity.surface !== request.surface)) {
54
+ return Promise.reject(new OperationRuntimeAdapterError("capture_incomplete"));
55
+ }
56
+ assertNativeAbortSignal(request.signal);
57
+ captureIdentity ??= Object.freeze({
58
+ operationId: request.operationId,
59
+ requestDigest: request.requestDigest,
60
+ surface: request.surface
61
+ });
62
+ capturePromise ??= Promise.resolve()
63
+ .then(() => options.capture(Object.freeze({
64
+ operationId: request.operationId,
65
+ requestDigest: request.requestDigest,
66
+ surface: request.surface,
67
+ target: request.target,
68
+ signal: request.signal
69
+ })))
70
+ .then(capture => normalizeCapture(capture, options.primitives, options.recovery !== undefined))
71
+ .catch(error => {
72
+ if (error instanceof OperationRuntimeAdapterError)
73
+ throw error;
74
+ throw new OperationRuntimeAdapterError(captureErrorCode(error));
75
+ });
76
+ return capturePromise;
77
+ };
78
+ const initialize = async (request) => {
79
+ if (options.recovery !== undefined
80
+ && (request.operationId !== options.recovery.operationId
81
+ || request.requestDigest !== options.recovery.requestDigest
82
+ || request.surface !== options.recovery.surface
83
+ || !sameTargetRequest(request.target, options.recovery.targetRequest))) {
84
+ throw new OperationRuntimeAdapterError("target_binding_mismatch");
85
+ }
86
+ innerPromise ??= captureOnce(request).then(captured => {
87
+ const adapterOptions = {
88
+ page: captured.page,
89
+ ...(captured.runtimeContext === undefined ? {} : { runtimeContext: captured.runtimeContext }),
90
+ owner: options.owner,
91
+ ...(options.coordinator === undefined ? {} : { coordinator: options.coordinator }),
92
+ evidenceDigest: options.evidenceDigest,
93
+ ...(captured.targetEvidence === undefined ? {} : { targetEvidence: captured.targetEvidence }),
94
+ ...(captured.resolveTargetEvidence === undefined ? {} : { resolveTargetEvidence: captured.resolveTargetEvidence }),
95
+ ...(captured.observeCurrentTarget === undefined ? {} : { observeCurrentTarget: captured.observeCurrentTarget }),
96
+ ...(captured.capabilities === undefined ? {} : { capabilities: captured.capabilities }),
97
+ ...(captured.newTargetAnchorDigest === undefined ? {} : { newTargetAnchorDigest: captured.newTargetAnchorDigest }),
98
+ ...(captured.blankTaskEvidenceDigest === undefined ? {} : { blankTaskEvidenceDigest: captured.blankTaskEvidenceDigest }),
99
+ ...(captured.authoritativeClaim === undefined ? {} : { authoritativeClaim: captured.authoritativeClaim }),
100
+ ...(options.transactionTimeoutMs === undefined ? {} : { transactionTimeoutMs: options.transactionTimeoutMs }),
101
+ ...(options.files === undefined ? {} : { files: options.files }),
102
+ ...(options.fileManifestDigest === undefined ? {} : { fileManifestDigest: options.fileManifestDigest }),
103
+ ...(captured.primitives.submission === undefined ? {} : { submission: captured.primitives.submission }),
104
+ ...(captured.primitives.staging === undefined ? {} : { staging: captured.primitives.staging }),
105
+ ...(captured.primitives.collector === undefined ? {} : { collector: captured.primitives.collector }),
106
+ ...(captured.primitives.control === undefined ? {} : { control: captured.primitives.control }),
107
+ ...(captured.primitives.artifacts === undefined ? {} : { artifacts: captured.primitives.artifacts }),
108
+ ...(captured.outputDirectory === undefined ? {} : { outputDirectory: captured.outputDirectory }),
109
+ ...(options.recovery === undefined ? {} : {
110
+ recovery: Object.freeze({
111
+ operationId: options.recovery.operationId,
112
+ requestDigest: options.recovery.requestDigest,
113
+ surface: options.recovery.surface,
114
+ target: options.recovery.target,
115
+ signal: request.signal
116
+ })
117
+ })
118
+ };
119
+ try {
120
+ return createOperationBrowserAdapter(adapterOptions);
121
+ }
122
+ catch (error) {
123
+ if (error instanceof OperationBrowserAdapterError) {
124
+ throw new OperationRuntimeAdapterError(mapAdapterError(error.code));
125
+ }
126
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
127
+ }
128
+ });
129
+ return await innerPromise;
130
+ };
131
+ const ensureRecovered = (operationId, requestDigest, signal) => {
132
+ const recovery = options.recovery;
133
+ if (recovery === undefined) {
134
+ return Promise.reject(new OperationRuntimeAdapterError("not_initialized"));
135
+ }
136
+ if (operationId !== recovery.operationId || requestDigest !== recovery.requestDigest) {
137
+ return Promise.reject(new OperationRuntimeAdapterError("capture_incomplete"));
138
+ }
139
+ assertNativeAbortSignal(signal);
140
+ return initialize({
141
+ operationId: recovery.operationId,
142
+ requestDigest: recovery.requestDigest,
143
+ surface: recovery.surface,
144
+ target: recovery.targetRequest,
145
+ signal
146
+ });
147
+ };
148
+ const resolveTarget = async (request) => {
149
+ const adapter = await initialize(request);
150
+ try {
151
+ return await adapter.resolveTarget(request);
152
+ }
153
+ catch (error) {
154
+ if (error instanceof OperationRuntimeAdapterError)
155
+ throw error;
156
+ if (error instanceof OperationBrowserAdapterError) {
157
+ throw new OperationRuntimeAdapterError(mapAdapterError(error.code));
158
+ }
159
+ throw new OperationRuntimeAdapterError("target_evidence_unavailable");
160
+ }
161
+ };
162
+ // Phase ports remain usable after a process/backend restart. In that case
163
+ // the lazy inner adapter has not been initialized by resolveTarget; recover
164
+ // the authenticated target first, then delegate the exact phase. Normal
165
+ // submit calls use the already-composed adapter. Every unavailable path
166
+ // returns a protocol-shaped redacted result rather than routing through the
167
+ // compatibility-only final transaction port.
168
+ const delegateSubmissionPhase = (request, callback, fallback) => {
169
+ if (options.recovery === undefined) {
170
+ return delegateSubmission(innerPromise, callback, fallback);
171
+ }
172
+ const signal = request.signal ?? new AbortController().signal;
173
+ return ensureRecovered(request.operationId, request.requestDigest, signal)
174
+ .then(callback)
175
+ .catch(() => fallback);
176
+ };
177
+ let recoveredCollector;
178
+ const submission = Object.freeze({
179
+ ...(options.recoverAuthenticatedSend === undefined ? {} : { recoverAuthenticatedSend: async (request) => {
180
+ if (innerPromise !== undefined) {
181
+ return await (await innerPromise).submission.recoverSend(request);
182
+ }
183
+ const recovered = await options.recoverAuthenticatedSend(request);
184
+ if (recovered.result.status === "submitted" || recovered.result.status === "already_submitted") {
185
+ recoveredCollector = recovered.collector;
186
+ }
187
+ return recovered.result;
188
+ } }),
189
+ observeStaging: request => delegateSubmission(innerPromise, adapter => adapter.submission.observeStaging(request), unavailableStage()),
190
+ executeFileHandoffOnce: request => delegateSubmission(innerPromise, adapter => adapter.submission.executeFileHandoffOnce(request), unavailableHandoff()),
191
+ observeAttachments: request => delegateSubmission(innerPromise, adapter => adapter.submission.observeAttachments(request), { status: "unavailable" }),
192
+ prepareSend: request => delegateSubmissionPhase(request, adapter => adapter.submission.prepareSend(request), unavailablePrepareSend()),
193
+ executePreparedSend: request => delegateSubmissionPhase(request, adapter => adapter.submission.executePreparedSend(request), unavailableExecutePreparedSend()),
194
+ verifyPreparedSend: request => delegateSubmissionPhase(request, adapter => adapter.submission.verifyPreparedSend(request), unavailableFinalTransaction()),
195
+ recoverSend: request => delegateSubmissionPhase(request, adapter => adapter.submission.recoverSend(request), unavailableFinalTransaction()),
196
+ executeFinalTabTransaction: request => delegateSubmission(innerPromise, adapter => adapter.submission.executeFinalTabTransaction(request), { status: "blocked", blockerCode: "target_evidence_unavailable" })
197
+ });
198
+ const delegateRecovered = (operationId, requestDigest, signal, callback) => {
199
+ if (options.recovery === undefined)
200
+ return requireDelegate(innerPromise, callback);
201
+ return ensureRecovered(operationId, requestDigest, signal)
202
+ .then(callback)
203
+ .catch(error => {
204
+ if (error instanceof OperationRuntimeAdapterError)
205
+ throw error;
206
+ throw new OperationRuntimeAdapterError("target_evidence_unavailable");
207
+ });
208
+ };
209
+ const delegateRecoveredControl = (operationId, requestDigest, signal, callback, fallback) => {
210
+ if (options.recovery === undefined)
211
+ return delegateControl(innerPromise, callback, fallback);
212
+ return ensureRecovered(operationId, requestDigest, signal)
213
+ .then(adapter => callback(adapter) ?? fallback)
214
+ .catch(() => fallback);
215
+ };
216
+ const collector = Object.freeze({
217
+ readContext: request => recoveredCollector !== undefined ? recoveredCollector.readContext(request) : delegateRecovered(request.operationId, request.requestDigest, request.signal, adapter => adapter.collector.readContext(request)),
218
+ observe: request => recoveredCollector !== undefined ? recoveredCollector.observe(request) : delegateRecovered(request.operationId, request.requestDigest, request.signal, adapter => adapter.collector.observe(request)),
219
+ sleep: (milliseconds, signal) => recoveredCollector !== undefined ? recoveredCollector.sleep(milliseconds, signal) : requireDelegate(innerPromise, adapter => adapter.collector.sleep(milliseconds, signal))
220
+ });
221
+ const staging = Object.freeze({
222
+ readCurrent: request => delegateStaging(innerPromise, adapter => adapter.staging?.readCurrent(request), unavailableStaging(request)),
223
+ mutateOnce: request => delegateStagingMutation(innerPromise, adapter => adapter.staging?.mutateOnce(request)),
224
+ observe: request => delegateStaging(innerPromise, adapter => adapter.staging?.observe(request), unavailableStaging(request))
225
+ });
226
+ const control = Object.freeze({
227
+ postconditionRetry: CONTROL_POSTCONDITION_RETRY_POLICY,
228
+ observeTurn: request => delegateRecoveredControl(request.operationId, request.parentRequestDigest, request.signal, adapter => adapter.control?.observeTurn(request), { status: "uncertain", reason: "unavailable" }),
229
+ executeOnce: request => delegateRecoveredControl(request.operationId, request.parentRequestDigest, request.signal, adapter => adapter.control?.executeOnce(request), { status: "uncertain", blockerCode: "send_control_unavailable" }),
230
+ observePostcondition: request => delegateRecoveredControl(request.operationId, request.parentRequestDigest, request.signal, adapter => adapter.control?.observePostcondition(request), { status: "uncertain", blockerCode: "send_control_unavailable" }),
231
+ prepareSteer: request => delegateRecoveredControl(request.parentOperationId, request.parentRequestDigest, request.signal, adapter => adapter.control?.prepareSteer?.(request), unavailableSteerPhase(request, "prepare")),
232
+ executeSteerPrepared: request => delegateRecoveredControl(request.prepared.parentOperationId, request.prepared.parentRequestDigest, request.signal, adapter => adapter.control?.executeSteerPrepared?.(request), unavailableSteerPhase(request, "execute_prepared")),
233
+ verifySteer: request => delegateRecoveredControl(request.prepared.parentOperationId, request.prepared.parentRequestDigest, request.signal, adapter => adapter.control?.verifySteer?.(request), unavailableSteerPhase(request, "verify")),
234
+ recoverSteer: request => delegateRecoveredControl(request.prepared.parentOperationId, request.prepared.parentRequestDigest, request.signal, adapter => adapter.control?.recoverSteer?.(request), unavailableSteerPhase(request, "recovery"))
235
+ });
236
+ const artifacts = exposeArtifacts
237
+ ? Object.freeze({
238
+ transfer: request => {
239
+ if (innerPromise === undefined) {
240
+ return Promise.reject(new OperationRuntimeAdapterError("not_initialized"));
241
+ }
242
+ return innerPromise.then(adapter => {
243
+ if (adapter.artifacts === undefined) {
244
+ throw new OperationRuntimeAdapterError("unsupported_browser_primitive");
245
+ }
246
+ return adapter.artifacts.transfer(request);
247
+ }).catch(error => {
248
+ if (error instanceof OperationRuntimeAdapterError)
249
+ throw error;
250
+ throw new OperationRuntimeAdapterError("target_evidence_unavailable");
251
+ });
252
+ }
253
+ })
254
+ : undefined;
255
+ const adapter = {
256
+ resolveTarget,
257
+ submission,
258
+ collector,
259
+ ...(exposeStaging ? { staging } : {}),
260
+ ...(exposeControl ? { control } : {}),
261
+ ...(artifacts === undefined ? {} : { artifacts })
262
+ };
263
+ return Object.freeze(adapter);
264
+ }
265
+ /** Alias for callers that put the runtime qualifier first. */
266
+ export const createOperationRuntimeAdapter = createRuntimeOperationBrowserAdapter;
267
+ function normalizeRuntimeAdapterOptions(value) {
268
+ if (!isPlainDataRecord(value))
269
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
270
+ try {
271
+ const owner = readOwnData(value, "owner");
272
+ const evidenceDigest = readOwnData(value, "evidenceDigest");
273
+ const capture = readOwnData(value, "capture");
274
+ const primitives = readOwnData(value, "primitives");
275
+ const exposeStaging = readOwnData(value, "exposeStaging");
276
+ const exposeControl = readOwnData(value, "exposeControl");
277
+ const exposeArtifacts = readOwnData(value, "exposeArtifacts");
278
+ const coordinator = readOwnData(value, "coordinator");
279
+ const transactionTimeoutMs = readOwnData(value, "transactionTimeoutMs");
280
+ const files = readOwnData(value, "files");
281
+ const fileManifestDigest = readOwnData(value, "fileManifestDigest");
282
+ const recovery = readOwnData(value, "recovery");
283
+ const recoverAuthenticatedSend = readOwnData(value, "recoverAuthenticatedSend");
284
+ const normalizedRecovery = recovery === undefined
285
+ ? undefined
286
+ : (() => {
287
+ validateRecoveryContext(recovery);
288
+ return normalizeRecoveryContext(recovery);
289
+ })();
290
+ const snapshot = {
291
+ owner: cloneFrozenData(owner),
292
+ evidenceDigest,
293
+ capture,
294
+ primitives: primitives === undefined ? undefined : cloneFrozenProviderValue(primitives),
295
+ exposeStaging,
296
+ exposeControl,
297
+ exposeArtifacts,
298
+ coordinator,
299
+ transactionTimeoutMs,
300
+ files: files === undefined ? undefined : cloneFrozenData(files),
301
+ fileManifestDigest,
302
+ recovery: normalizedRecovery,
303
+ recoverAuthenticatedSend
304
+ };
305
+ const normalized = Object.freeze(snapshot);
306
+ validateOptions(normalized);
307
+ return normalized;
308
+ }
309
+ catch (error) {
310
+ if (error instanceof OperationRuntimeAdapterError)
311
+ throw error;
312
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
313
+ }
314
+ }
315
+ function validateOptions(options) {
316
+ if (!isPlainDataRecord(options)) {
317
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
318
+ }
319
+ if (typeof options.capture !== "function" || typeof options.evidenceDigest !== "function") {
320
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
321
+ }
322
+ if (options.recoverAuthenticatedSend !== undefined && typeof options.recoverAuthenticatedSend !== "function") {
323
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
324
+ }
325
+ if (options.owner === null || typeof options.owner !== "object" || typeof options.owner.backendSessionId !== "string") {
326
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
327
+ }
328
+ if (options.files !== undefined && !Array.isArray(options.files)) {
329
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
330
+ }
331
+ if (options.exposeStaging !== undefined && typeof options.exposeStaging !== "boolean") {
332
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
333
+ }
334
+ if (options.exposeControl !== undefined && typeof options.exposeControl !== "boolean") {
335
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
336
+ }
337
+ if (options.exposeArtifacts !== undefined && typeof options.exposeArtifacts !== "boolean") {
338
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
339
+ }
340
+ if (options.recovery !== undefined && options.exposeArtifacts === true) {
341
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
342
+ }
343
+ if (options.recovery !== undefined)
344
+ validateRecoveryContext(options.recovery);
345
+ }
346
+ function validateRecoveryContext(value) {
347
+ if (!isPlainDataRecord(value))
348
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
349
+ const operationId = readOwnData(value, "operationId");
350
+ const requestDigest = readOwnData(value, "requestDigest");
351
+ const surface = readOwnData(value, "surface");
352
+ const target = readOwnData(value, "target");
353
+ const targetRequest = readOwnData(value, "targetRequest");
354
+ if (typeof operationId !== "string"
355
+ || !/^[A-Za-z0-9._:-]{1,512}$/u.test(operationId)
356
+ || typeof requestDigest !== "string"
357
+ || !/^hmac-sha256:[0-9a-f]{64}$/u.test(requestDigest)
358
+ || (surface !== "chat" && surface !== "work")
359
+ || !isPlainDataRecord(target)
360
+ || !isPlainDataRecord(targetRequest)
361
+ || !isSafeDataGraph(target)
362
+ || !isSafeDataGraph(targetRequest)) {
363
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
364
+ }
365
+ const lifecycle = readOwnData(target, "targetLifecycle");
366
+ if (lifecycle === "new_pending") {
367
+ throw new OperationRuntimeAdapterError("target_binding_mismatch");
368
+ }
369
+ if (lifecycle !== undefined && lifecycle !== "fixed" && lifecycle !== "new_established") {
370
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
371
+ }
372
+ const targetType = readOwnData(targetRequest, "type");
373
+ if (targetType !== "new"
374
+ && targetType !== "selected_tab"
375
+ && targetType !== "tab_id"
376
+ && targetType !== "conversation_id"
377
+ && targetType !== "url") {
378
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
379
+ }
380
+ }
381
+ function normalizeRecoveryContext(value) {
382
+ try {
383
+ const record = value;
384
+ const operationId = readOwnData(record, "operationId");
385
+ const requestDigest = readOwnData(record, "requestDigest");
386
+ const surface = readOwnData(record, "surface");
387
+ const targetValue = readOwnData(record, "target");
388
+ const targetRequestValue = readOwnData(record, "targetRequest");
389
+ if (targetValue === undefined || targetRequestValue === undefined)
390
+ throw new Error("incomplete recovery context");
391
+ const target = cloneFrozenData(targetValue);
392
+ const targetRequest = cloneFrozenData(targetRequestValue);
393
+ return Object.freeze({
394
+ operationId: operationId,
395
+ requestDigest: requestDigest,
396
+ surface: surface,
397
+ target,
398
+ targetRequest
399
+ });
400
+ }
401
+ catch {
402
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
403
+ }
404
+ }
405
+ function sameTargetRequest(left, right) {
406
+ const leftType = readOwnData(left, "type");
407
+ const rightType = readOwnData(right, "type");
408
+ if (leftType !== rightType)
409
+ return false;
410
+ switch (leftType) {
411
+ case "tab_id":
412
+ case "conversation_id":
413
+ case "url":
414
+ return readOwnData(left, leftType === "tab_id" ? "tabId" : leftType === "conversation_id" ? "conversationId" : "url")
415
+ === readOwnData(right, leftType === "tab_id" ? "tabId" : leftType === "conversation_id" ? "conversationId" : "url");
416
+ case "new":
417
+ case "selected_tab":
418
+ return true;
419
+ default:
420
+ return false;
421
+ }
422
+ }
423
+ function cloneFrozenData(value, seen = new Set()) {
424
+ if (value === null || typeof value !== "object") {
425
+ if (typeof value === "function" || typeof value === "symbol" || typeof value === "bigint")
426
+ throw new Error("unsupported value");
427
+ return value;
428
+ }
429
+ if (seen.has(value))
430
+ throw new Error("cyclic value");
431
+ seen.add(value);
432
+ try {
433
+ if (Array.isArray(value)) {
434
+ const result = value.map(item => cloneFrozenData(item, seen));
435
+ seen.delete(value);
436
+ return Object.freeze(result);
437
+ }
438
+ const prototype = Object.getPrototypeOf(value);
439
+ if (prototype !== Object.prototype && prototype !== null)
440
+ throw new Error("non-plain value");
441
+ const descriptors = Object.getOwnPropertyDescriptors(value);
442
+ // Keep descriptor reads side-effect free and define keys explicitly: an
443
+ // assignment to `__proto__` on a normal object invokes the legacy setter
444
+ // and silently drops the caller's own data property.
445
+ const result = Object.create(null);
446
+ for (const key of Object.keys(descriptors)) {
447
+ const descriptor = descriptors[key];
448
+ if (descriptor === undefined || !("value" in descriptor) || descriptor.get !== undefined || descriptor.set !== undefined)
449
+ throw new Error("accessor value");
450
+ Object.defineProperty(result, key, {
451
+ value: cloneFrozenData(descriptor.value, seen),
452
+ enumerable: descriptor.enumerable ?? false,
453
+ writable: true,
454
+ configurable: true
455
+ });
456
+ }
457
+ seen.delete(value);
458
+ return Object.freeze(result);
459
+ }
460
+ catch (error) {
461
+ seen.delete(value);
462
+ throw error;
463
+ }
464
+ }
465
+ /** Clone callback/primitive records through descriptors, never through gets. */
466
+ function cloneFrozenProviderValue(value, seen = new Set()) {
467
+ if (value === null || typeof value !== "object")
468
+ return value;
469
+ if (seen.has(value))
470
+ throw new Error("cyclic provider value");
471
+ seen.add(value);
472
+ try {
473
+ if (Array.isArray(value)) {
474
+ const result = value.map(item => cloneFrozenProviderValue(item, seen));
475
+ seen.delete(value);
476
+ return Object.freeze(result);
477
+ }
478
+ const prototype = Object.getPrototypeOf(value);
479
+ if (prototype !== Object.prototype && prototype !== null)
480
+ throw new Error("non-plain provider value");
481
+ const descriptors = Object.getOwnPropertyDescriptors(value);
482
+ const result = Object.create(null);
483
+ for (const key of Object.keys(descriptors)) {
484
+ const descriptor = descriptors[key];
485
+ if (descriptor === undefined || !("value" in descriptor) || descriptor.get !== undefined || descriptor.set !== undefined)
486
+ throw new Error("accessor provider value");
487
+ Object.defineProperty(result, key, {
488
+ value: cloneFrozenProviderValue(descriptor.value, seen),
489
+ enumerable: descriptor.enumerable ?? false,
490
+ writable: true,
491
+ configurable: true
492
+ });
493
+ }
494
+ seen.delete(value);
495
+ return Object.freeze(result);
496
+ }
497
+ catch (error) {
498
+ seen.delete(value);
499
+ throw error;
500
+ }
501
+ }
502
+ function assertNativeAbortSignal(value) {
503
+ if (value === null || typeof value !== "object" || typeof AbortSignal !== "function") {
504
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
505
+ }
506
+ const getter = Object.getOwnPropertyDescriptor(AbortSignal.prototype, "aborted")?.get;
507
+ if (getter === undefined)
508
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
509
+ try {
510
+ if (typeof Reflect.apply(getter, value, []) !== "boolean")
511
+ throw new Error("invalid signal");
512
+ }
513
+ catch {
514
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
515
+ }
516
+ }
517
+ function normalizeCapture(value, configuredPrimitives, recoveryCapture = false) {
518
+ if (!isPlainDataRecord(value)) {
519
+ throw new OperationRuntimeAdapterError("capture_incomplete");
520
+ }
521
+ const page = readOwnData(value, "page");
522
+ const runtimeContext = readOwnData(value, "runtimeContext");
523
+ const targetEvidence = readOwnData(value, "targetEvidence");
524
+ const authoritativeClaim = readOwnData(value, "authoritativeClaim");
525
+ const capabilities = readOwnData(value, "capabilities");
526
+ const newTargetAnchorDigest = readOwnData(value, "newTargetAnchorDigest");
527
+ const blankTaskEvidenceDigest = readOwnData(value, "blankTaskEvidenceDigest");
528
+ const resolveTargetEvidence = readOwnData(value, "resolveTargetEvidence");
529
+ const observeCurrentTarget = readOwnData(value, "observeCurrentTarget");
530
+ const primitivesValue = readOwnData(value, "primitives");
531
+ if (page === undefined || page === null || typeof page !== "object" || Array.isArray(page)) {
532
+ throw new OperationRuntimeAdapterError("capture_incomplete");
533
+ }
534
+ if (runtimeContext !== undefined && !(runtimeContext instanceof OperationRuntimeContext)) {
535
+ throw new OperationRuntimeAdapterError("capture_incomplete");
536
+ }
537
+ if (typeof resolveTargetEvidence !== "function" && targetEvidence === undefined && !recoveryCapture) {
538
+ throw new OperationRuntimeAdapterError("target_evidence_unavailable");
539
+ }
540
+ if (resolveTargetEvidence !== undefined && typeof resolveTargetEvidence !== "function") {
541
+ throw new OperationRuntimeAdapterError("capture_incomplete");
542
+ }
543
+ if (observeCurrentTarget !== undefined && typeof observeCurrentTarget !== "function") {
544
+ throw new OperationRuntimeAdapterError("capture_incomplete");
545
+ }
546
+ if (recoveryCapture && typeof observeCurrentTarget !== "function") {
547
+ throw new OperationRuntimeAdapterError("target_evidence_unavailable");
548
+ }
549
+ if (primitivesValue !== undefined && !isPlainDataRecord(primitivesValue)) {
550
+ throw new OperationRuntimeAdapterError("capture_incomplete");
551
+ }
552
+ const primitives = (primitivesValue === undefined
553
+ ? {}
554
+ : cloneFrozenProviderValue(primitivesValue));
555
+ if (configuredPrimitives !== undefined && !isPlainDataRecord(configuredPrimitives)) {
556
+ throw new OperationRuntimeAdapterError("adapter_incomplete");
557
+ }
558
+ const mergedPrimitives = {};
559
+ const configuredSubmission = configuredPrimitives === undefined
560
+ ? undefined
561
+ : readOwnData(configuredPrimitives, "submission");
562
+ const configuredStaging = configuredPrimitives === undefined
563
+ ? undefined
564
+ : readOwnData(configuredPrimitives, "staging");
565
+ const configuredCollector = configuredPrimitives === undefined
566
+ ? undefined
567
+ : readOwnData(configuredPrimitives, "collector");
568
+ const configuredControl = configuredPrimitives === undefined
569
+ ? undefined
570
+ : readOwnData(configuredPrimitives, "control");
571
+ const configuredArtifacts = configuredPrimitives === undefined
572
+ ? undefined
573
+ : readOwnData(configuredPrimitives, "artifacts");
574
+ const submission = (readOwnData(primitives, "submission") ?? configuredSubmission);
575
+ if (submission !== undefined)
576
+ mergedPrimitives.submission = submission;
577
+ const staging = (readOwnData(primitives, "staging") ?? configuredStaging);
578
+ if (staging !== undefined)
579
+ mergedPrimitives.staging = staging;
580
+ const collector = (readOwnData(primitives, "collector") ?? configuredCollector);
581
+ if (collector !== undefined)
582
+ mergedPrimitives.collector = collector;
583
+ const control = (readOwnData(primitives, "control") ?? configuredControl);
584
+ if (control !== undefined)
585
+ mergedPrimitives.control = control;
586
+ // A restart capture never supplies request-local artifact primitives. Do not
587
+ // resurrect an artifact source from static options or durable state.
588
+ if (!recoveryCapture) {
589
+ const artifacts = (readOwnData(primitives, "artifacts") ?? configuredArtifacts);
590
+ if (artifacts !== undefined)
591
+ mergedPrimitives.artifacts = artifacts;
592
+ }
593
+ const outputDirectory = readOwnData(value, "outputDirectory");
594
+ if (outputDirectory !== undefined
595
+ && (typeof outputDirectory !== "string" || outputDirectory.length === 0 || outputDirectory.length > 4096
596
+ || !isAbsolutePath(outputDirectory) || /[\u0000-\u001f\u007f]/u.test(outputDirectory))) {
597
+ throw new OperationRuntimeAdapterError("capture_incomplete");
598
+ }
599
+ if (recoveryCapture && outputDirectory !== undefined) {
600
+ throw new OperationRuntimeAdapterError("capture_incomplete");
601
+ }
602
+ const normalizedTargetEvidence = targetEvidence === undefined ? undefined : cloneFrozenData(targetEvidence);
603
+ const normalizedClaim = authoritativeClaim === undefined ? undefined : cloneFrozenData(authoritativeClaim);
604
+ const normalizedCapabilities = capabilities === undefined ? undefined : cloneFrozenData(capabilities);
605
+ return Object.freeze({
606
+ page: page,
607
+ ...(runtimeContext === undefined ? {} : { runtimeContext }),
608
+ ...(normalizedTargetEvidence === undefined ? {} : { targetEvidence: normalizedTargetEvidence }),
609
+ ...(normalizedClaim === undefined ? {} : { authoritativeClaim: normalizedClaim }),
610
+ ...(normalizedCapabilities === undefined ? {} : { capabilities: normalizedCapabilities }),
611
+ ...(newTargetAnchorDigest === undefined ? {} : { newTargetAnchorDigest: newTargetAnchorDigest }),
612
+ ...(blankTaskEvidenceDigest === undefined ? {} : { blankTaskEvidenceDigest: blankTaskEvidenceDigest }),
613
+ ...(resolveTargetEvidence === undefined ? {} : { resolveTargetEvidence: resolveTargetEvidence }),
614
+ ...(observeCurrentTarget === undefined ? {} : { observeCurrentTarget: observeCurrentTarget }),
615
+ ...(outputDirectory === undefined ? {} : { outputDirectory }),
616
+ primitives: Object.freeze(mergedPrimitives)
617
+ });
618
+ }
619
+ function isPlainDataRecord(value) {
620
+ if (value === null || typeof value !== "object" || Array.isArray(value))
621
+ return false;
622
+ try {
623
+ const prototype = Object.getPrototypeOf(value);
624
+ if (prototype !== Object.prototype && prototype !== null)
625
+ return false;
626
+ for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(value))) {
627
+ if (!("value" in descriptor) || descriptor.get !== undefined || descriptor.set !== undefined)
628
+ return false;
629
+ }
630
+ return true;
631
+ }
632
+ catch {
633
+ return false;
634
+ }
635
+ }
636
+ function unavailableSteerPhase(request, phase) {
637
+ const identity = "prepared" in request ? request.prepared : request;
638
+ return Object.freeze({
639
+ schemaVersion: request.schemaVersion,
640
+ phase,
641
+ parentOperationId: identity.parentOperationId,
642
+ parentRequestDigest: identity.parentRequestDigest,
643
+ parentTargetBindingDigest: identity.parentTargetBindingDigest,
644
+ controlActionId: identity.controlActionId,
645
+ action: "steer",
646
+ requestDigest: identity.requestDigest,
647
+ expectedAssistantTurnId: identity.expectedAssistantTurnId,
648
+ ...("prepared" in request ? {
649
+ assistantBranchId: request.prepared.assistantBranchId,
650
+ assistantParentTurnId: request.prepared.assistantParentTurnId,
651
+ baselineSnapshotDigest: request.prepared.baselineSnapshotDigest,
652
+ preparedDigest: request.prepared.preparedDigest
653
+ } : {}),
654
+ status: "blocked",
655
+ blockerCode: "backend_unavailable",
656
+ observationRequired: phase === "prepare" ? false : true,
657
+ mutationBoundary: phase === "prepare" ? "none" : "control_may_have_occurred"
658
+ });
659
+ }
660
+ function isSafeDataGraph(value, seen = new Set(), depth = 0) {
661
+ if (value === null || (typeof value !== "object" && typeof value !== "function"))
662
+ return true;
663
+ if (typeof value === "function")
664
+ return false;
665
+ if (depth > 16 || seen.has(value))
666
+ return false;
667
+ seen.add(value);
668
+ try {
669
+ const prototype = Object.getPrototypeOf(value);
670
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null)
671
+ return false;
672
+ const descriptors = Object.getOwnPropertyDescriptors(value);
673
+ if (Object.keys(descriptors).length > 1024)
674
+ return false;
675
+ for (const descriptor of Object.values(descriptors)) {
676
+ if (!("value" in descriptor) || descriptor.get !== undefined || descriptor.set !== undefined)
677
+ return false;
678
+ if (!isSafeDataGraph(descriptor.value, seen, depth + 1))
679
+ return false;
680
+ }
681
+ return true;
682
+ }
683
+ catch {
684
+ return false;
685
+ }
686
+ }
687
+ function readOwnData(value, key) {
688
+ try {
689
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
690
+ return descriptor !== undefined && "value" in descriptor && descriptor.get === undefined && descriptor.set === undefined
691
+ ? descriptor.value
692
+ : undefined;
693
+ }
694
+ catch {
695
+ return undefined;
696
+ }
697
+ }
698
+ function mapAdapterError(code) {
699
+ switch (code) {
700
+ case "adapter_incomplete": return "adapter_incomplete";
701
+ case "page_affinity_mismatch": return "page_affinity_mismatch";
702
+ case "target_evidence_unavailable": return "target_evidence_unavailable";
703
+ case "browser_bridge_unavailable": return "browser_bridge_unavailable";
704
+ case "unsupported_browser_primitive": return "unsupported_browser_primitive";
705
+ case "target_binding_mismatch": return "target_binding_mismatch";
706
+ case "input_file_changed": return "unsupported_browser_primitive";
707
+ }
708
+ }
709
+ function captureErrorCode(error) {
710
+ if (error === null || (typeof error !== "object" && typeof error !== "function"))
711
+ return "capture_failed";
712
+ const descriptor = Object.getOwnPropertyDescriptor(error, "code");
713
+ const code = descriptor !== undefined && "value" in descriptor && typeof descriptor.value === "string"
714
+ ? descriptor.value
715
+ : undefined;
716
+ switch (code) {
717
+ case "backend_unavailable":
718
+ case "browser_bridge_unavailable":
719
+ case "login_required":
720
+ case "captcha":
721
+ case "rate_limited":
722
+ case "permission_required":
723
+ case "needs_confirmation":
724
+ case "runtime_incompatible":
725
+ case "target_evidence_unavailable":
726
+ case "target_binding_mismatch":
727
+ case "page_affinity_mismatch":
728
+ return code;
729
+ case "rate_limit":
730
+ return "rate_limited";
731
+ default:
732
+ return "capture_failed";
733
+ }
734
+ }
735
+ function requireDelegate(innerPromise, callback) {
736
+ if (innerPromise === undefined)
737
+ return Promise.reject(new OperationRuntimeAdapterError("not_initialized"));
738
+ return innerPromise
739
+ .then(callback)
740
+ .catch(error => {
741
+ if (error instanceof OperationRuntimeAdapterError)
742
+ throw error;
743
+ throw new OperationRuntimeAdapterError("target_evidence_unavailable");
744
+ });
745
+ }
746
+ function delegateSubmission(innerPromise, callback, fallback) {
747
+ if (innerPromise === undefined)
748
+ return Promise.resolve(fallback);
749
+ return innerPromise.then(callback).catch(() => fallback);
750
+ }
751
+ function delegateStaging(innerPromise, callback, fallback) {
752
+ if (innerPromise === undefined)
753
+ return Promise.resolve(fallback);
754
+ return innerPromise.then(adapter => callback(adapter) ?? fallback).catch(() => fallback);
755
+ }
756
+ function delegateStagingMutation(innerPromise, callback) {
757
+ if (innerPromise === undefined)
758
+ return Promise.reject(new OperationRuntimeAdapterError("not_initialized"));
759
+ return innerPromise.then(adapter => {
760
+ const result = callback(adapter);
761
+ if (result === undefined)
762
+ throw new OperationRuntimeAdapterError("unsupported_browser_primitive");
763
+ return result;
764
+ }).catch(error => {
765
+ if (error instanceof OperationRuntimeAdapterError)
766
+ throw error;
767
+ throw new OperationRuntimeAdapterError("target_evidence_unavailable");
768
+ });
769
+ }
770
+ function delegateControl(innerPromise, callback, fallback) {
771
+ if (innerPromise === undefined)
772
+ return Promise.resolve(fallback);
773
+ return innerPromise.then(adapter => callback(adapter) ?? fallback).catch(() => fallback);
774
+ }
775
+ function unavailableStage() {
776
+ return { status: "unavailable", reason: "unknown" };
777
+ }
778
+ function unavailableHandoff() {
779
+ return { status: "not_satisfied", blockerCode: "target_evidence_unavailable" };
780
+ }
781
+ function unavailablePrepareSend() {
782
+ return {
783
+ status: "blocked",
784
+ result: { status: "blocked", blockerCode: "target_evidence_unavailable" }
785
+ };
786
+ }
787
+ function unavailableExecutePreparedSend() {
788
+ return {
789
+ status: "blocked",
790
+ result: { status: "blocked", blockerCode: "target_evidence_unavailable" }
791
+ };
792
+ }
793
+ function unavailableFinalTransaction() {
794
+ return { status: "blocked", blockerCode: "target_evidence_unavailable" };
795
+ }
796
+ function unavailableStaging(request) {
797
+ return {
798
+ status: "unavailable",
799
+ desiredStateDigest: request.desiredStateDigest,
800
+ blockerCode: "target_evidence_unavailable"
801
+ };
802
+ }