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,105 @@
1
+ import type { PageLike } from "../types.js";
2
+ import { type BrowserResourceKey, type CoordinatorAcquisitionContext, type CoordinatorOwner, type CoordinatorPriority, type CoordinatorResourceKind, type ProcessTabCoordinator, type TabResourceKey } from "../runtime/tab-coordinator.js";
3
+ import type { OperationRuntimeCapabilities } from "../runtime/operation-context.js";
4
+ import type { OperationTargetBindingV1, OperationTargetLifecycle } from "./types.js";
5
+ import type { OwnershipTargetEvidence } from "./turn-ownership.js";
6
+ /** A target HMAC implementation must be keyed by the journal/runtime secret. */
7
+ export type BrowserTargetEvidenceDigest = (domain: string, material: unknown) => string | Promise<string>;
8
+ /**
9
+ * Provider claims are intentionally separate from the browser-observation
10
+ * target. Observation exposes only the opaque token; the epoch is retained
11
+ * here for fencing and is never written into user-visible diagnostics.
12
+ */
13
+ export type BrowserTargetClaim = Readonly<{
14
+ token: string;
15
+ epoch: number;
16
+ }>;
17
+ /**
18
+ * The capability matrix is conservative by construction. Missing fields are
19
+ * false, so an older provider can never accidentally advertise concurrent-tab
20
+ * or cross-process safety.
21
+ */
22
+ export type BrowserTargetCapabilities = Readonly<OperationRuntimeCapabilities>;
23
+ export type BrowserTargetBindingInput<Page extends PageLike = PageLike> = Readonly<{
24
+ /** An explicit page captured by the caller; never read from RuntimeEnv. */
25
+ page: Readonly<Page>;
26
+ /** The normalized target from `observeBrowserPage(...).snapshot.target`. */
27
+ evidence: OwnershipTargetEvidence;
28
+ /** Fixed is the compatibility default; new_pending carries a blank-task anchor. */
29
+ targetLifecycle?: OperationTargetLifecycle;
30
+ /** Required keyed evidence for a pending new-task anchor. */
31
+ newTargetAnchorDigest?: string;
32
+ blankTaskEvidenceDigest?: string;
33
+ /** Optional provider claim/fencing evidence. Omission means process scope. */
34
+ authoritativeClaim?: BrowserTargetClaim;
35
+ capabilities?: Partial<BrowserTargetCapabilities>;
36
+ evidenceDigest: BrowserTargetEvidenceDigest;
37
+ owner: CoordinatorOwner;
38
+ coordinator: ProcessTabCoordinator;
39
+ userTurnBaselineDigest?: string;
40
+ assistantTurnBaselineDigest?: string;
41
+ configurationReceiptDigest?: string;
42
+ }>;
43
+ export type BrowserTargetResource = Readonly<{
44
+ /** `provider` is reserved for validated provider claim + advertised overlap. */
45
+ scope: OperationTargetBindingV1["coordinationScope"];
46
+ resourceKind: CoordinatorResourceKind;
47
+ resourceKey: BrowserResourceKey | TabResourceKey;
48
+ /** True only when different tabs may use independent coordinator actors. */
49
+ concurrentTabs: boolean;
50
+ authoritativeClaimValidated: boolean;
51
+ }>;
52
+ export type BrowserTargetTransactionOptions = Readonly<{
53
+ priority?: CoordinatorPriority;
54
+ signal?: AbortSignal;
55
+ deadlineAt?: number;
56
+ timeoutMs?: number;
57
+ label?: string;
58
+ }>;
59
+ export type BrowserTargetTransactionContext<Page extends PageLike = PageLike> = Readonly<{
60
+ page: Readonly<Page>;
61
+ target: OperationTargetBindingV1;
62
+ acquisition: CoordinatorAcquisitionContext;
63
+ /**
64
+ * Validate a fresh read-only observation before any mutation. The read and
65
+ * mutation should remain one short transaction; polling/sleeping belongs
66
+ * after the promise returned by `withTabTransaction` settles.
67
+ */
68
+ assertCurrent: (evidence: OwnershipTargetEvidence, claim?: BrowserTargetClaim, allowNewTargetEstablishment?: boolean) => void;
69
+ }>;
70
+ export type BrowserTargetBinding<Page extends PageLike = PageLike> = Readonly<{
71
+ page: Readonly<Page>;
72
+ target: OperationTargetBindingV1;
73
+ /**
74
+ * Evidence for this live observation only. This is deliberately distinct
75
+ * from the journal's canonical targetBindingDigest, which is computed from
76
+ * the complete durable OperationTargetBindingV1 by OperationJournal.
77
+ */
78
+ targetEvidenceDigest: string;
79
+ evidence: OwnershipTargetEvidence;
80
+ capabilities: BrowserTargetCapabilities;
81
+ resource: BrowserTargetResource;
82
+ owner: CoordinatorOwner;
83
+ assertPage: (page: unknown) => void;
84
+ assertCurrent: (evidence: OwnershipTargetEvidence, claim?: BrowserTargetClaim, allowNewTargetEstablishment?: boolean) => void;
85
+ /** Internal one-way latch set after a post-Send identity proof. */
86
+ markTargetEstablished?: (establishment: Readonly<{
87
+ conversationId: string;
88
+ canonicalThreadUrl: string;
89
+ }>) => void;
90
+ withTabTransaction: <T>(options: BrowserTargetTransactionOptions, callback: (context: BrowserTargetTransactionContext<Page>) => T | PromiseLike<T>) => Promise<T>;
91
+ }>;
92
+ export type BrowserTargetErrorCode = "invalid_target_evidence" | "invalid_capabilities" | "invalid_claim" | "invalid_owner" | "invalid_digest" | "navigation_mismatch" | "claim_mismatch" | "page_mismatch";
93
+ /** Errors intentionally contain no caller-controlled IDs, URLs, or digests. */
94
+ export declare class BrowserTargetError extends Error {
95
+ readonly code: BrowserTargetErrorCode;
96
+ constructor(code: BrowserTargetErrorCode, message: string);
97
+ }
98
+ /**
99
+ * Bind one explicit page and one normalized observation to an immutable target.
100
+ * This adapter is deliberately browser-agnostic: it never reads or mutates a
101
+ * legacy `RuntimeEnv`, and it never performs polling or sleeps itself.
102
+ */
103
+ export declare function bindBrowserTarget<Page extends PageLike = PageLike>(input: BrowserTargetBindingInput<Page>): BrowserTargetBinding<Page>;
104
+ /** Bind the same immutable target while its journal authority signs remotely. */
105
+ export declare function bindBrowserTargetAsync<Page extends PageLike = PageLike>(input: BrowserTargetBindingInput<Page>): Promise<BrowserTargetBinding<Page>>;
@@ -0,0 +1,531 @@
1
+ import { types as nodeTypes } from "node:util";
2
+ import { createBrowserResourceKey, createTabResourceKey } from "../runtime/tab-coordinator.js";
3
+ /** The exact digest shape accepted by every target-evidence boundary. */
4
+ const DIGEST_PATTERN = /^hmac-sha256:[0-9a-f]{64}$/;
5
+ /** Keep IDs opaque: the adapter never interprets provider-specific semantics. */
6
+ const OPAQUE_ID_PATTERN = /^[A-Za-z0-9._:-]{1,512}$/;
7
+ /** `browser-observation.ts` deliberately emits this non-routable URL identity. */
8
+ const OPAQUE_THREAD_URL_PATTERN = /^https:\/\/opaque\.invalid\/thread\/[0-9a-f]{64}$/;
9
+ const INVALID_ID_VALUES = new Set(["unknown", "undefined", "null", "n/a", "na"]);
10
+ const TARGET_EVIDENCE_DIGEST_DOMAIN = "codex-chatgpt-control/operation-target-evidence/v1";
11
+ const CLAIM_EVIDENCE_DIGEST_DOMAIN = "codex-chatgpt-control/tab-claim-evidence/v1";
12
+ /** Errors intentionally contain no caller-controlled IDs, URLs, or digests. */
13
+ export class BrowserTargetError extends Error {
14
+ code;
15
+ constructor(code, message) {
16
+ super(message);
17
+ this.name = "BrowserTargetError";
18
+ this.code = code;
19
+ }
20
+ }
21
+ function isPlainRecord(value) {
22
+ if (value === null || typeof value !== "object" || Array.isArray(value))
23
+ return false;
24
+ try {
25
+ const prototype = Object.getPrototypeOf(value);
26
+ if (prototype !== Object.prototype && prototype !== null)
27
+ return false;
28
+ for (const key of Object.keys(value)) {
29
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
30
+ if (descriptor?.get !== undefined || descriptor?.set !== undefined)
31
+ return false;
32
+ }
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ function fail(code, message) {
40
+ throw new BrowserTargetError(code, message);
41
+ }
42
+ function assertPlainRecord(value, code, message) {
43
+ if (!isPlainRecord(value))
44
+ fail(code, message);
45
+ }
46
+ function assertExactKeys(value, keys, code) {
47
+ const allowed = new Set(keys);
48
+ try {
49
+ for (const key of Object.keys(value)) {
50
+ if (!allowed.has(key))
51
+ fail(code, "Unsupported target field.");
52
+ }
53
+ }
54
+ catch (error) {
55
+ if (error instanceof BrowserTargetError)
56
+ throw error;
57
+ fail(code, "Unsupported target field.");
58
+ }
59
+ }
60
+ function stableId(value, code = "invalid_target_evidence") {
61
+ if (typeof value !== "string")
62
+ fail(code, "Stable target identity is invalid.");
63
+ const normalized = value.trim();
64
+ if (normalized !== value
65
+ ||
66
+ normalized.length === 0
67
+ || normalized.length > 512
68
+ || INVALID_ID_VALUES.has(normalized.toLowerCase())
69
+ || !OPAQUE_ID_PATTERN.test(normalized)) {
70
+ fail(code, "Stable target identity is invalid.");
71
+ }
72
+ return normalized;
73
+ }
74
+ function digest(value, code = "invalid_digest") {
75
+ if (typeof value !== "string" || !DIGEST_PATTERN.test(value))
76
+ fail(code, "Target evidence digest is invalid.");
77
+ return value;
78
+ }
79
+ function normalizeIdentity(value, label, required) {
80
+ assertPlainRecord(value, "invalid_target_evidence", "Target identity evidence is invalid.");
81
+ assertExactKeys(value, ["status", "value", "reason"], "invalid_target_evidence");
82
+ if (value.status === "available") {
83
+ if (value.value === undefined)
84
+ fail("invalid_target_evidence", "Required target identity is unavailable.");
85
+ return Object.freeze({ status: "available", value: stableId(value.value) });
86
+ }
87
+ if (value.status === "unavailable") {
88
+ if (required)
89
+ fail("invalid_target_evidence", `Required ${label} evidence is unavailable.`);
90
+ if (value.reason !== "not_exposed" && value.reason !== "not_observed" && value.reason !== "redacted") {
91
+ fail("invalid_target_evidence", "Target identity evidence is invalid.");
92
+ }
93
+ return Object.freeze({ status: "unavailable", reason: value.reason });
94
+ }
95
+ fail("invalid_target_evidence", "Target identity evidence is invalid.");
96
+ }
97
+ function normalizeCanonicalThreadUrl(value, required = true) {
98
+ assertPlainRecord(value, "invalid_target_evidence", "Canonical thread evidence is invalid.");
99
+ assertExactKeys(value, ["status", "value", "reason"], "invalid_target_evidence");
100
+ if (value.status === "unavailable" && !required) {
101
+ if (value.reason !== "not_exposed" && value.reason !== "not_observed" && value.reason !== "redacted") {
102
+ fail("invalid_target_evidence", "Canonical thread evidence is invalid.");
103
+ }
104
+ return Object.freeze({ status: "unavailable", reason: value.reason });
105
+ }
106
+ if (value.status !== "available" || typeof value.value !== "string" || !OPAQUE_THREAD_URL_PATTERN.test(value.value)) {
107
+ fail("invalid_target_evidence", "Opaque canonical thread evidence is required.");
108
+ }
109
+ return Object.freeze({ status: "available", value: value.value });
110
+ }
111
+ function normalizeTargetEvidence(value, allowPendingIdentity = false) {
112
+ assertPlainRecord(value, "invalid_target_evidence", "Target evidence is invalid.");
113
+ assertExactKeys(value, ["provider", "browser", "tab", "thread", "conversation", "canonicalThreadUrl", "authoritativeTabClaim", "coordinationScope"], "invalid_target_evidence");
114
+ if (value.coordinationScope !== "process" && value.coordinationScope !== "provider") {
115
+ fail("invalid_target_evidence", "Target coordination scope is invalid.");
116
+ }
117
+ const provider = normalizeIdentity(value.provider, "provider", true);
118
+ const browser = normalizeIdentity(value.browser, "browser", true);
119
+ const tab = normalizeIdentity(value.tab, "tab", true);
120
+ const thread = normalizeIdentity(value.thread, "thread", !allowPendingIdentity);
121
+ const conversation = normalizeIdentity(value.conversation, "conversation", !allowPendingIdentity);
122
+ const canonicalThreadUrl = normalizeCanonicalThreadUrl(value.canonicalThreadUrl, !allowPendingIdentity);
123
+ const authoritativeTabClaim = normalizeIdentity(value.authoritativeTabClaim, "authoritative tab claim", false);
124
+ return Object.freeze({
125
+ provider,
126
+ browser,
127
+ tab,
128
+ thread,
129
+ conversation,
130
+ canonicalThreadUrl,
131
+ authoritativeTabClaim,
132
+ coordinationScope: value.coordinationScope
133
+ });
134
+ }
135
+ function normalizeClaim(value) {
136
+ if (value === undefined)
137
+ return undefined;
138
+ assertPlainRecord(value, "invalid_claim", "Authoritative claim is invalid.");
139
+ assertExactKeys(value, ["token", "epoch"], "invalid_claim");
140
+ const token = stableId(value.token, "invalid_claim");
141
+ if (!Number.isSafeInteger(value.epoch) || value.epoch < 0) {
142
+ fail("invalid_claim", "Authoritative claim is invalid.");
143
+ }
144
+ return Object.freeze({ token, epoch: value.epoch });
145
+ }
146
+ function normalizeCapabilities(value) {
147
+ if (value === undefined) {
148
+ return Object.freeze({
149
+ stableProviderId: false,
150
+ stableBrowserId: false,
151
+ stableTabId: false,
152
+ authoritativeTabClaim: false,
153
+ concurrentTabs: false
154
+ });
155
+ }
156
+ assertPlainRecord(value, "invalid_capabilities", "Target capabilities are invalid.");
157
+ assertExactKeys(value, ["stableProviderId", "stableBrowserId", "stableTabId", "authoritativeTabClaim", "concurrentTabs"], "invalid_capabilities");
158
+ const result = {
159
+ stableProviderId: value.stableProviderId === undefined ? false : value.stableProviderId,
160
+ stableBrowserId: value.stableBrowserId === undefined ? false : value.stableBrowserId,
161
+ stableTabId: value.stableTabId === undefined ? false : value.stableTabId,
162
+ authoritativeTabClaim: value.authoritativeTabClaim === undefined ? false : value.authoritativeTabClaim,
163
+ concurrentTabs: value.concurrentTabs === undefined ? false : value.concurrentTabs
164
+ };
165
+ if (Object.values(result).some(item => typeof item !== "boolean")) {
166
+ fail("invalid_capabilities", "Target capabilities are invalid.");
167
+ }
168
+ return Object.freeze(result);
169
+ }
170
+ function normalizeOwner(value) {
171
+ assertPlainRecord(value, "invalid_owner", "Coordinator owner is invalid.");
172
+ assertExactKeys(value, ["backendSessionId", "ownerId", "operationId"], "invalid_owner");
173
+ const backendSessionId = stableId(value.backendSessionId, "invalid_owner");
174
+ const ownerId = value.ownerId === undefined ? undefined : stableId(value.ownerId, "invalid_owner");
175
+ const operationId = value.operationId === undefined ? undefined : stableId(value.operationId, "invalid_owner");
176
+ return Object.freeze({
177
+ backendSessionId,
178
+ ...(ownerId === undefined ? {} : { ownerId }),
179
+ ...(operationId === undefined ? {} : { operationId })
180
+ });
181
+ }
182
+ function assertPageLike(value) {
183
+ if (value === null
184
+ || typeof value !== "object"
185
+ || Array.isArray(value)
186
+ || typeof value.evaluate !== "function") {
187
+ fail("invalid_target_evidence", "An explicit page is required.");
188
+ }
189
+ }
190
+ function availableValue(identity, label) {
191
+ if (identity.status !== "available")
192
+ fail("invalid_target_evidence", `${label} evidence is unavailable.`);
193
+ return identity.value;
194
+ }
195
+ function claimEvidenceValue(target) {
196
+ return target.authoritativeTabClaim.status === "available" ? target.authoritativeTabClaim.value : undefined;
197
+ }
198
+ function validateDigestFunction(fn) {
199
+ if (typeof fn !== "function")
200
+ fail("invalid_digest", "Target evidence digest function is required.");
201
+ }
202
+ function* targetDigest(fn, domain, material) {
203
+ return yield { fn, domain, material };
204
+ }
205
+ function validateTargetDigest(value) {
206
+ try {
207
+ return digest(value);
208
+ }
209
+ catch {
210
+ fail("invalid_digest", "Target evidence digest is invalid.");
211
+ }
212
+ }
213
+ /**
214
+ * Stable identities plus the provider's explicit concurrent-tab capability
215
+ * are sufficient for independent actors inside this SDK process. This does
216
+ * not make the key a cross-process lock: ProcessTabCoordinator is deliberately
217
+ * process-local, and a provider claim is still required before upgrading the
218
+ * durable target to provider scope.
219
+ */
220
+ function supportsProcessTabConcurrency(capabilities) {
221
+ return capabilities.stableProviderId
222
+ && capabilities.stableBrowserId
223
+ && capabilities.stableTabId
224
+ && capabilities.concurrentTabs;
225
+ }
226
+ function supportsProviderTabConcurrency(capabilities, claimValidated) {
227
+ return supportsProcessTabConcurrency(capabilities)
228
+ && claimValidated
229
+ && capabilities.authoritativeTabClaim;
230
+ }
231
+ function computeResource(target, capabilities, claimValidated) {
232
+ if (supportsProviderTabConcurrency(capabilities, claimValidated)) {
233
+ return Object.freeze({
234
+ scope: "provider",
235
+ resourceKind: "tab",
236
+ resourceKey: createTabResourceKey(target.providerId, target.browserId, target.tabId),
237
+ concurrentTabs: true,
238
+ authoritativeClaimValidated: true
239
+ });
240
+ }
241
+ if (supportsProcessTabConcurrency(capabilities)) {
242
+ return Object.freeze({
243
+ scope: "process",
244
+ resourceKind: "tab",
245
+ resourceKey: createTabResourceKey(target.providerId, target.browserId, target.tabId),
246
+ concurrentTabs: true,
247
+ authoritativeClaimValidated: claimValidated
248
+ });
249
+ }
250
+ // Without provider fencing, serialize the whole browser actor in this
251
+ // process. A per-tab key is safe only when stable identities and the
252
+ // provider's concurrentTabs capability are both present.
253
+ return Object.freeze({
254
+ scope: "process",
255
+ resourceKind: "browser",
256
+ resourceKey: createBrowserResourceKey(target.providerId, target.browserId),
257
+ concurrentTabs: false,
258
+ authoritativeClaimValidated: claimValidated
259
+ });
260
+ }
261
+ function targetMaterial(evidence, target, claim) {
262
+ return {
263
+ provider: evidence.provider,
264
+ browser: evidence.browser,
265
+ tab: evidence.tab,
266
+ thread: evidence.thread,
267
+ conversation: evidence.conversation,
268
+ canonicalThreadUrl: evidence.canonicalThreadUrl,
269
+ authoritativeTabClaim: evidence.authoritativeTabClaim,
270
+ coordinationScope: target.coordinationScope,
271
+ ...(claim === undefined ? {} : { claimEpoch: claim.epoch })
272
+ };
273
+ }
274
+ function compareAvailable(expected, observed, code) {
275
+ const expectedValue = availableValue(expected, "Bound target");
276
+ if (observed.status !== "available" || expectedValue !== observed.value) {
277
+ fail(code, code === "claim_mismatch" ? "Authoritative claim changed." : "Observed target changed.");
278
+ }
279
+ }
280
+ function compareAvailableIdentityValue(expected, observed, code) {
281
+ if (expected === undefined || observed.status !== "available" || observed.value !== expected) {
282
+ fail(code, code === "claim_mismatch" ? "Authoritative claim changed." : "Observed target changed.");
283
+ }
284
+ }
285
+ function makeTransactionOptions(owner, options) {
286
+ const result = {
287
+ owner,
288
+ priority: options.priority ?? "mutation"
289
+ };
290
+ if (options.signal !== undefined)
291
+ result.signal = options.signal;
292
+ if (options.deadlineAt !== undefined)
293
+ result.deadlineAt = options.deadlineAt;
294
+ if (options.timeoutMs !== undefined)
295
+ result.timeoutMs = options.timeoutMs;
296
+ if (options.label !== undefined)
297
+ result.label = options.label;
298
+ return Object.freeze(result);
299
+ }
300
+ /**
301
+ * Bind one explicit page and one normalized observation to an immutable target.
302
+ * This adapter is deliberately browser-agnostic: it never reads or mutates a
303
+ * legacy `RuntimeEnv`, and it never performs polling or sleeps itself.
304
+ */
305
+ export function bindBrowserTarget(input) {
306
+ const steps = bindBrowserTargetSteps(input);
307
+ let step = steps.next();
308
+ while (!step.done) {
309
+ let value;
310
+ try {
311
+ value = step.value.fn(step.value.domain, step.value.material);
312
+ }
313
+ catch {
314
+ fail("invalid_digest", "Target evidence digest is invalid.");
315
+ }
316
+ // Preserve this established synchronous API. Async authorities use the
317
+ // explicit variant below; absorb rejection before failing closed here.
318
+ if (nodeTypes.isPromise(value)) {
319
+ void value.catch(() => undefined);
320
+ fail("invalid_digest", "Use asynchronous target binding for an asynchronous authority.");
321
+ }
322
+ step = steps.next(validateTargetDigest(value));
323
+ }
324
+ return step.value;
325
+ }
326
+ /** Bind the same immutable target while its journal authority signs remotely. */
327
+ export async function bindBrowserTargetAsync(input) {
328
+ const steps = bindBrowserTargetSteps(input);
329
+ let step = steps.next();
330
+ while (!step.done) {
331
+ let value;
332
+ try {
333
+ value = await step.value.fn(step.value.domain, step.value.material);
334
+ }
335
+ catch {
336
+ fail("invalid_digest", "Target evidence digest is invalid.");
337
+ }
338
+ step = steps.next(validateTargetDigest(value));
339
+ }
340
+ return step.value;
341
+ }
342
+ function* bindBrowserTargetSteps(input) {
343
+ assertPlainRecord(input, "invalid_target_evidence", "Target binding input is invalid.");
344
+ assertExactKeys(input, ["page", "evidence", "targetLifecycle", "newTargetAnchorDigest", "blankTaskEvidenceDigest", "authoritativeClaim", "capabilities", "evidenceDigest", "owner", "coordinator", "userTurnBaselineDigest", "assistantTurnBaselineDigest", "configurationReceiptDigest"], "invalid_target_evidence");
345
+ // All later reads cross asynchronous signing boundaries in the async
346
+ // variant. Capture scalar fields and opaque capabilities before yielding.
347
+ input = Object.freeze({ ...input });
348
+ assertPageLike(input.page);
349
+ validateDigestFunction(input.evidenceDigest);
350
+ if (input.coordinator === null
351
+ || typeof input.coordinator !== "object"
352
+ || typeof input.coordinator.withTabTransaction !== "function"
353
+ || typeof input.coordinator.withBrowserAcquisition !== "function") {
354
+ fail("invalid_target_evidence", "A process tab coordinator is required.");
355
+ }
356
+ const targetLifecycle = input.targetLifecycle ?? "fixed";
357
+ if (targetLifecycle !== "fixed" && targetLifecycle !== "new_pending" && targetLifecycle !== "new_established") {
358
+ fail("invalid_target_evidence", "Target lifecycle is invalid.");
359
+ }
360
+ const pending = targetLifecycle === "new_pending";
361
+ const evidence = normalizeTargetEvidence(input.evidence, pending);
362
+ const claim = normalizeClaim(input.authoritativeClaim);
363
+ const capabilities = normalizeCapabilities(input.capabilities);
364
+ const owner = normalizeOwner(input.owner);
365
+ const providerId = availableValue(evidence.provider, "Provider");
366
+ const browserId = availableValue(evidence.browser, "Browser");
367
+ const tabId = availableValue(evidence.tab, "Tab");
368
+ const conversationId = pending ? undefined : availableValue(evidence.conversation, "Conversation");
369
+ const canonicalThreadUrl = pending ? undefined : availableValue(evidence.canonicalThreadUrl, "Canonical thread URL");
370
+ const observedClaim = claimEvidenceValue(evidence);
371
+ if (claim !== undefined && observedClaim !== claim.token) {
372
+ fail("claim_mismatch", "Authoritative claim does not match the observed target.");
373
+ }
374
+ const claimValidated = claim !== undefined && observedClaim === claim.token;
375
+ for (const value of [input.userTurnBaselineDigest, input.assistantTurnBaselineDigest, input.configurationReceiptDigest]) {
376
+ if (value !== undefined)
377
+ digest(value);
378
+ }
379
+ if (pending) {
380
+ if (evidence.thread.status !== "unavailable"
381
+ || evidence.conversation.status !== "unavailable"
382
+ || evidence.canonicalThreadUrl.status !== "unavailable") {
383
+ fail("invalid_target_evidence", "A pending new target cannot contain provider conversation identity.");
384
+ }
385
+ if (input.newTargetAnchorDigest === undefined || input.blankTaskEvidenceDigest === undefined) {
386
+ fail("invalid_digest", "A pending new target requires blank-task anchor evidence.");
387
+ }
388
+ digest(input.newTargetAnchorDigest);
389
+ digest(input.blankTaskEvidenceDigest);
390
+ }
391
+ else if (input.newTargetAnchorDigest !== undefined || input.blankTaskEvidenceDigest !== undefined) {
392
+ fail("invalid_target_evidence", "Blank-task anchor evidence is only valid for a pending new target.");
393
+ }
394
+ const providerScope = supportsProviderTabConcurrency(capabilities, claimValidated);
395
+ const targetWithoutDigest = Object.freeze({
396
+ providerId,
397
+ browserId,
398
+ tabId,
399
+ coordinationScope: providerScope ? "provider" : "process",
400
+ ...(claimValidated ? {
401
+ tabClaimEvidenceDigest: yield* targetDigest(input.evidenceDigest, CLAIM_EVIDENCE_DIGEST_DOMAIN, {
402
+ token: claim?.token,
403
+ epoch: claim?.epoch
404
+ })
405
+ } : {}),
406
+ ...(canonicalThreadUrl === undefined ? {} : { canonicalThreadUrl }),
407
+ ...(conversationId === undefined ? {} : { conversationId }),
408
+ ...(input.userTurnBaselineDigest === undefined ? {} : { userTurnBaselineDigest: input.userTurnBaselineDigest }),
409
+ ...(input.assistantTurnBaselineDigest === undefined ? {} : { assistantTurnBaselineDigest: input.assistantTurnBaselineDigest }),
410
+ ...(input.configurationReceiptDigest === undefined ? {} : { configurationReceiptDigest: input.configurationReceiptDigest }),
411
+ evidenceProfile: Object.freeze({
412
+ providerIdentity: "required",
413
+ stableTabId: "required",
414
+ stableConversationId: pending ? "unavailable" : "required",
415
+ // Turn IDs are established by the subsequent ownership observation;
416
+ // target binding stores only their baseline evidence digests.
417
+ stableUserTurnId: "unavailable",
418
+ authoritativeTabClaim: providerScope ? "required" : "unavailable",
419
+ replacementTabRecovery: false
420
+ }),
421
+ ...(pending ? {
422
+ targetLifecycle: "new_pending",
423
+ newTargetAnchorDigest: input.newTargetAnchorDigest,
424
+ blankTaskEvidenceDigest: input.blankTaskEvidenceDigest
425
+ } : {})
426
+ });
427
+ const targetEvidenceDigest = yield* targetDigest(input.evidenceDigest, TARGET_EVIDENCE_DIGEST_DOMAIN, targetMaterial(evidence, targetWithoutDigest, claim));
428
+ const target = Object.freeze({ ...targetWithoutDigest });
429
+ let activeTarget = target;
430
+ const resource = computeResource(target, capabilities, claimValidated);
431
+ const page = input.page;
432
+ const coordinator = input.coordinator;
433
+ let targetEstablished = false;
434
+ const assertPage = (observedPage) => {
435
+ if (observedPage !== page)
436
+ fail("page_mismatch", "The supplied page is not the bound operation page.");
437
+ };
438
+ const assertCurrent = (current, currentClaim, allowNewTargetEstablishment = false) => {
439
+ const observed = normalizeTargetEvidence(current, pending);
440
+ compareAvailable(evidence.provider, observed.provider, "navigation_mismatch");
441
+ compareAvailable(evidence.browser, observed.browser, "navigation_mismatch");
442
+ compareAvailable(evidence.tab, observed.tab, "navigation_mismatch");
443
+ if (!pending || targetEstablished) {
444
+ if (!targetEstablished)
445
+ compareAvailable(evidence.thread, observed.thread, "navigation_mismatch");
446
+ if (targetEstablished) {
447
+ compareAvailableIdentityValue(activeTarget.conversationId, observed.conversation, "navigation_mismatch");
448
+ compareAvailableIdentityValue(activeTarget.canonicalThreadUrl, observed.canonicalThreadUrl, "navigation_mismatch");
449
+ }
450
+ else {
451
+ compareAvailable(evidence.conversation, observed.conversation, "navigation_mismatch");
452
+ compareAvailable(evidence.canonicalThreadUrl, observed.canonicalThreadUrl, "navigation_mismatch");
453
+ }
454
+ }
455
+ else {
456
+ const identities = [observed.thread, observed.conversation, observed.canonicalThreadUrl];
457
+ const availableCount = identities.filter(identity => identity.status === "available").length;
458
+ if (availableCount !== 0 && availableCount !== identities.length) {
459
+ fail("navigation_mismatch", "Observed new-target identity is incomplete.");
460
+ }
461
+ }
462
+ if (claimValidated) {
463
+ compareAvailable(evidence.authoritativeTabClaim, observed.authoritativeTabClaim, "claim_mismatch");
464
+ const normalizedCurrentClaim = normalizeClaim(currentClaim);
465
+ if (normalizedCurrentClaim === undefined
466
+ || normalizedCurrentClaim.token !== claim?.token
467
+ || normalizedCurrentClaim.epoch !== claim?.epoch) {
468
+ fail("claim_mismatch", "Authoritative claim changed.");
469
+ }
470
+ }
471
+ };
472
+ const withTabTransaction = async (options, callback) => {
473
+ if (typeof callback !== "function")
474
+ fail("invalid_target_evidence", "A transaction callback is required.");
475
+ if (!isPlainRecord(options))
476
+ fail("invalid_target_evidence", "Transaction options are invalid.");
477
+ assertExactKeys(options, ["priority", "signal", "deadlineAt", "timeoutMs", "label"], "invalid_target_evidence");
478
+ const requestOptions = makeTransactionOptions(owner, options);
479
+ const run = (acquisition) => callback(Object.freeze({
480
+ page,
481
+ target: activeTarget,
482
+ acquisition,
483
+ assertCurrent
484
+ }));
485
+ if (resource.resourceKind === "tab") {
486
+ return coordinator.withTabTransaction(resource.resourceKey, requestOptions, run);
487
+ }
488
+ return coordinator.withBrowserAcquisition(resource.resourceKey, requestOptions, run);
489
+ };
490
+ const binding = {
491
+ page,
492
+ get target() { return activeTarget; },
493
+ targetEvidenceDigest,
494
+ evidence,
495
+ capabilities,
496
+ resource,
497
+ owner,
498
+ assertPage,
499
+ assertCurrent,
500
+ ...(pending ? {
501
+ markTargetEstablished: (establishment) => {
502
+ if (!isPlainRecord(establishment)
503
+ || typeof establishment.conversationId !== "string"
504
+ || !OPAQUE_ID_PATTERN.test(establishment.conversationId)
505
+ || typeof establishment.canonicalThreadUrl !== "string"
506
+ || !OPAQUE_THREAD_URL_PATTERN.test(establishment.canonicalThreadUrl))
507
+ return;
508
+ activeTarget = Object.freeze({
509
+ providerId: target.providerId,
510
+ browserId: target.browserId,
511
+ tabId: target.tabId,
512
+ coordinationScope: target.coordinationScope,
513
+ ...(target.tabClaimEvidenceDigest === undefined ? {} : { tabClaimEvidenceDigest: target.tabClaimEvidenceDigest }),
514
+ canonicalThreadUrl: establishment.canonicalThreadUrl,
515
+ conversationId: establishment.conversationId,
516
+ ...(target.userTurnBaselineDigest === undefined ? {} : { userTurnBaselineDigest: target.userTurnBaselineDigest }),
517
+ ...(target.assistantTurnBaselineDigest === undefined ? {} : { assistantTurnBaselineDigest: target.assistantTurnBaselineDigest }),
518
+ ...(target.configurationReceiptDigest === undefined ? {} : { configurationReceiptDigest: target.configurationReceiptDigest }),
519
+ evidenceProfile: Object.freeze({
520
+ ...target.evidenceProfile,
521
+ stableConversationId: "required",
522
+ stableUserTurnId: "required"
523
+ })
524
+ });
525
+ targetEstablished = true;
526
+ }
527
+ } : {}),
528
+ withTabTransaction
529
+ };
530
+ return Object.freeze(binding);
531
+ }
@@ -0,0 +1,4 @@
1
+ import type { OperationRequestIdentityInput } from "./types.js";
2
+ export declare function canonicalJson(value: unknown): string;
3
+ export declare function hmacDigest(key: Uint8Array, domain: string, value: unknown): string;
4
+ export declare function operationRequestDigest(key: Uint8Array, input: OperationRequestIdentityInput): string;