@mercuryo-ai/agentbrowse 0.2.60 → 0.2.63

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 (105) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/README.md +132 -14
  3. package/dist/browser-session-state.d.ts +40 -10
  4. package/dist/browser-session-state.d.ts.map +1 -1
  5. package/dist/browser-session-state.js +63 -5
  6. package/dist/commands/act.d.ts.map +1 -1
  7. package/dist/commands/act.js +548 -535
  8. package/dist/commands/attach.d.ts +1 -3
  9. package/dist/commands/attach.d.ts.map +1 -1
  10. package/dist/commands/attach.js +5 -12
  11. package/dist/commands/browser-connection-failure.d.ts +9 -0
  12. package/dist/commands/browser-connection-failure.d.ts.map +1 -0
  13. package/dist/commands/browser-connection-failure.js +15 -0
  14. package/dist/commands/browser-status.d.ts +0 -2
  15. package/dist/commands/browser-status.d.ts.map +1 -1
  16. package/dist/commands/browser-status.js +27 -37
  17. package/dist/commands/close.d.ts.map +1 -1
  18. package/dist/commands/close.js +5 -0
  19. package/dist/commands/extract.d.ts.map +1 -1
  20. package/dist/commands/extract.js +147 -144
  21. package/dist/commands/interaction-kernel.d.ts +1 -1
  22. package/dist/commands/interaction-kernel.d.ts.map +1 -1
  23. package/dist/commands/interaction-kernel.js +1 -1
  24. package/dist/commands/launch.d.ts +0 -1
  25. package/dist/commands/launch.d.ts.map +1 -1
  26. package/dist/commands/launch.js +11 -12
  27. package/dist/commands/navigate.d.ts.map +1 -1
  28. package/dist/commands/navigate.js +79 -73
  29. package/dist/commands/observe-accessibility.d.ts.map +1 -1
  30. package/dist/commands/observe-accessibility.js +36 -2
  31. package/dist/commands/observe-inventory.d.ts +50 -7
  32. package/dist/commands/observe-inventory.d.ts.map +1 -1
  33. package/dist/commands/observe-inventory.js +822 -99
  34. package/dist/commands/observe-persistence.d.ts.map +1 -1
  35. package/dist/commands/observe-persistence.js +49 -6
  36. package/dist/commands/observe-projection.d.ts +6 -2
  37. package/dist/commands/observe-projection.d.ts.map +1 -1
  38. package/dist/commands/observe-projection.js +251 -27
  39. package/dist/commands/observe-semantics.d.ts +1 -0
  40. package/dist/commands/observe-semantics.d.ts.map +1 -1
  41. package/dist/commands/observe-semantics.js +541 -135
  42. package/dist/commands/observe-signals.d.ts +4 -4
  43. package/dist/commands/observe-signals.d.ts.map +1 -1
  44. package/dist/commands/observe-signals.js +2 -2
  45. package/dist/commands/observe-surfaces.d.ts +2 -1
  46. package/dist/commands/observe-surfaces.d.ts.map +1 -1
  47. package/dist/commands/observe-surfaces.js +143 -45
  48. package/dist/commands/observe.d.ts +5 -1
  49. package/dist/commands/observe.d.ts.map +1 -1
  50. package/dist/commands/observe.js +266 -274
  51. package/dist/commands/screenshot.d.ts.map +1 -1
  52. package/dist/commands/screenshot.js +50 -64
  53. package/dist/commands/semantic-observe.d.ts.map +1 -1
  54. package/dist/commands/semantic-observe.js +43 -0
  55. package/dist/library.d.ts +3 -1
  56. package/dist/library.d.ts.map +1 -1
  57. package/dist/library.js +3 -1
  58. package/dist/match-resolve-fill.d.ts +196 -0
  59. package/dist/match-resolve-fill.d.ts.map +1 -0
  60. package/dist/match-resolve-fill.js +700 -0
  61. package/dist/match-resolve-fill.test-support.d.ts +34 -0
  62. package/dist/match-resolve-fill.test-support.d.ts.map +1 -0
  63. package/dist/match-resolve-fill.test-support.js +81 -0
  64. package/dist/protected-fill.d.ts.map +1 -1
  65. package/dist/protected-fill.js +46 -7
  66. package/dist/runtime-protected-state.d.ts.map +1 -1
  67. package/dist/runtime-protected-state.js +12 -0
  68. package/dist/runtime-state.d.ts +6 -0
  69. package/dist/runtime-state.d.ts.map +1 -1
  70. package/dist/runtime-state.js +6 -0
  71. package/dist/secrets/form-matcher.d.ts.map +1 -1
  72. package/dist/secrets/form-matcher.js +76 -27
  73. package/dist/secrets/protected-exact-value-redaction.d.ts.map +1 -1
  74. package/dist/secrets/protected-exact-value-redaction.js +6 -0
  75. package/dist/secrets/protected-fill.js +3 -3
  76. package/dist/session.d.ts +3 -3
  77. package/dist/session.d.ts.map +1 -1
  78. package/dist/session.js +2 -2
  79. package/dist/solver/browser-launcher.d.ts.map +1 -1
  80. package/dist/solver/browser-launcher.js +2 -1
  81. package/dist/sticky-owner-host-entry.d.ts +2 -0
  82. package/dist/sticky-owner-host-entry.d.ts.map +1 -0
  83. package/dist/sticky-owner-host-entry.js +97 -0
  84. package/dist/sticky-owner.d.ts +15 -0
  85. package/dist/sticky-owner.d.ts.map +1 -0
  86. package/dist/sticky-owner.js +431 -0
  87. package/dist/testing.d.ts +1 -0
  88. package/dist/testing.d.ts.map +1 -1
  89. package/dist/testing.js +1 -0
  90. package/docs/README.md +28 -11
  91. package/docs/api-reference.md +311 -19
  92. package/docs/assistive-runtime.md +41 -16
  93. package/docs/configuration.md +36 -4
  94. package/docs/getting-started.md +73 -5
  95. package/docs/integration-checklist.md +32 -3
  96. package/docs/match-resolve-fill.md +699 -0
  97. package/docs/protected-fill.md +373 -91
  98. package/docs/testing.md +147 -15
  99. package/docs/troubleshooting.md +47 -6
  100. package/examples/README.md +7 -0
  101. package/examples/match-resolve-fill.ts +107 -0
  102. package/package.json +4 -2
  103. package/dist/protected-fill-browser.d.ts +0 -22
  104. package/dist/protected-fill-browser.d.ts.map +0 -1
  105. package/dist/protected-fill-browser.js +0 -52
package/docs/testing.md CHANGED
@@ -1,30 +1,36 @@
1
1
  # AgentBrowse Testing Guide
2
2
 
3
- Use the published testing subpath when your package wraps AgentBrowse and you
4
- need a stable assistive-runtime helper in tests.
3
+ Use the published `/testing` subpath when your package wraps AgentBrowse
4
+ and needs a stable, typed set of testing helpers. The subpath covers two
5
+ separate testing concerns: the assistive runtime (needed by
6
+ `extract(...)` and goal-based `observe(...)` callers) and the
7
+ `match` / `resolve` / `fill` primitives.
5
8
 
6
9
  ## Testing Export
7
10
 
8
11
  ```ts
9
12
  import {
13
+ // Match / resolve / fill fixtures
14
+ createFixtureMatchStore,
15
+ createFixtureGroupStore,
16
+ createFixtureResolver,
17
+ fixtureResolvedValue,
18
+ fixtureResolvedArtifact,
19
+ // Assistive runtime fixture
10
20
  installFetchBackedTestAssistiveRuntime,
11
21
  uninstallTestAssistiveRuntime,
12
22
  } from '@mercuryo-ai/agentbrowse/testing';
13
23
  ```
14
24
 
15
- ## What It Does
25
+ All exports are stable across minor versions within the package. Rely on
26
+ them instead of reaching into `src/**/*.test-support.ts` files
27
+ directly — those are implementation detail.
16
28
 
17
- `installFetchBackedTestAssistiveRuntime(...)` installs a process-global
18
- assistive runtime that sends structured chat requests over `fetch`.
29
+ ## Assistive Runtime Fixture
19
30
 
20
- Use it when:
21
-
22
- - your tests wrap `extract(...)`
23
- - your tests cover goal-based `observe(session, goal)`
24
- - your package wants to exercise the current public assistive runtime
25
- shape
26
-
27
- ## Example
31
+ Installs a process-global assistive runtime that sends structured chat
32
+ requests over `fetch`. Use it when your tests wrap `extract(...)` or
33
+ goal-based `observe(session, goal)`.
28
34
 
29
35
  ```ts
30
36
  import {
@@ -45,7 +51,133 @@ afterEach(() => {
45
51
  });
46
52
  ```
47
53
 
48
- ## Scope
49
-
50
54
  This helper targets the assistive runtime only. It does not mock browser
51
55
  sessions, pages, or observed targets.
56
+
57
+ ## Match / Resolve / Fill Fixtures
58
+
59
+ Five builders let you exercise the primitives without constructing the
60
+ internal match result objects by hand (which would bypass the accessor
61
+ pattern and produce results that fail to fill). Prefer these over raw
62
+ object literals in unit tests.
63
+
64
+ ### `createFixtureMatchStore(entries)`
65
+
66
+ Builds an `AgentbrowseMatchStore` — an opaque single-field candidate
67
+ source. The store's `entries()` returns candidate metadata without
68
+ values; values are only read back through `store.read(candidateRef)`
69
+ when `match(...)` needs them. Use this when your test wants to assert
70
+ that raw values stay inside the store.
71
+
72
+ ```ts
73
+ import { match } from '@mercuryo-ai/agentbrowse';
74
+ import { createFixtureMatchStore } from '@mercuryo-ai/agentbrowse/testing';
75
+
76
+ const store = createFixtureMatchStore([
77
+ {
78
+ candidateRef: 'profile.email.primary',
79
+ fieldKey: 'email',
80
+ type: 'email',
81
+ value: 'traveler@example.com',
82
+ },
83
+ ]);
84
+
85
+ const matched = await match(emailTarget, { from: store });
86
+ // matched.kind === 'ready' — and JSON.stringify(matched) does not
87
+ // contain 'traveler@example.com'.
88
+ ```
89
+
90
+ ### `createFixtureGroupStore(entries)`
91
+
92
+ The grouped counterpart — builds an `AgentbrowseGroupMatchStore` for
93
+ whole-form candidates with artifacts. Same opacity guarantee:
94
+ artifacts only come out through `store.readArtifact(candidateRef)`.
95
+
96
+ ```ts
97
+ import { createFixtureGroupStore } from '@mercuryo-ai/agentbrowse/testing';
98
+
99
+ const store = createFixtureGroupStore([
100
+ {
101
+ candidateRef: 'vault_login_1',
102
+ itemRef: 'vault_login_1',
103
+ label: 'Airline Login',
104
+ fieldKeys: ['username', 'password'],
105
+ confidence: 'high',
106
+ artifact: {
107
+ kind: 'values',
108
+ values: { username: 'traveler@example.com', password: 'secret' },
109
+ },
110
+ },
111
+ ]);
112
+
113
+ const matched = await match(fillableForm, { from: store });
114
+ ```
115
+
116
+ ### `createFixtureResolver(resourcesByCandidateRef, { enableBatch? })`
117
+
118
+ Builds an `AgentbrowseMatchResolver` adapter that satisfies the
119
+ interface with recorded call history. Returns
120
+ `{ adapter, resolveCalls, resolveBatchCalls }`. Pass
121
+ `{ enableBatch: true }` to also wire up `resolveBatch`.
122
+
123
+ ```ts
124
+ import { resolve, fill } from '@mercuryo-ai/agentbrowse';
125
+ import {
126
+ createFixtureResolver,
127
+ fixtureResolvedValue,
128
+ } from '@mercuryo-ai/agentbrowse/testing';
129
+
130
+ const resolver = createFixtureResolver({
131
+ 'candidate:password:0': fixtureResolvedValue('top-secret-password'),
132
+ });
133
+
134
+ const ready = await resolve(pendingMatch, { with: resolver.adapter });
135
+ await fill(session, passwordTarget, ready);
136
+
137
+ expect(resolver.resolveCalls).toHaveLength(1);
138
+ expect(resolver.resolveCalls[0].candidateRef).toBe('candidate:password:0');
139
+ ```
140
+
141
+ ### `fixtureResolvedValue(value)` and `fixtureResolvedArtifact(artifact, options?)`
142
+
143
+ Typed builders for the resource shapes returned by a resolver. Use them
144
+ to avoid redeclaring `{ kind: 'value', ... }` in every fixture call.
145
+
146
+ ```ts
147
+ fixtureResolvedValue('top-secret-password');
148
+ // => { kind: 'value', value: 'top-secret-password' }
149
+
150
+ fixtureResolvedArtifact(
151
+ { kind: 'values', values: { username: '…', password: '…' } },
152
+ { itemRef: 'vault_login_1', requestId: 'req_123' },
153
+ );
154
+ // => { kind: 'artifact', artifact, itemRef, requestId }
155
+ ```
156
+
157
+ ### Typing a grouped-only handler
158
+
159
+ When a test only exercises the `ready_group` → `fill(...)` path, a
160
+ bare `{ fill }` object typed as `AgentbrowseGroupFillHandler` is
161
+ enough — no need to construct a full `AgentbrowseMatchResolver` with a
162
+ stub `resolve`:
163
+
164
+ ```ts
165
+ import type { AgentbrowseGroupFillHandler } from '@mercuryo-ai/agentbrowse';
166
+
167
+ const applier: AgentbrowseGroupFillHandler = {
168
+ fill: vi.fn(async () => ({ success: true, outcomeType: 'filled' })),
169
+ };
170
+
171
+ await fill(session, fillableForm, readyGroupMatch, { resolver: applier });
172
+ ```
173
+
174
+ ## Scope
175
+
176
+ These fixtures target two concerns only: the assistive runtime used by
177
+ `extract` and goal-based `observe`, and the `match` / `resolve` / `fill`
178
+ primitives. They do not mock browser sessions, pages, observed targets,
179
+ or the underlying `act(...)` path — build those from real `launch(...)`
180
+ sessions against a data: URL when an integration test needs them.
181
+
182
+ See the [Match / Resolve / Fill Guide](./match-resolve-fill.md) for the
183
+ full mental model of the primitives these fixtures exercise.
@@ -2,6 +2,11 @@
2
2
 
3
3
  Common failures and what to do about each.
4
4
 
5
+ For the full per-command `error` code vocabulary (with short "when /
6
+ action" notes), see
7
+ [`api-reference.md` → Error codes by command](./api-reference.md#error-codes-by-command).
8
+ This guide covers diagnosis patterns; the reference covers the codes.
9
+
5
10
  ## `launch(...)` Fails
6
11
 
7
12
  Most `launch(...)` failures come from the environment, not from AgentBrowse
@@ -23,7 +28,9 @@ Inspect the `error` and `reason` fields on the `launch(...)` failure result
23
28
  - **Unreachable CDP WebSocket URL.** Verify the URL with a simple
24
29
  WebSocket client or `curl`.
25
30
  - **Session already owned.** Some providers reject a second CDP attach for
26
- the same session.
31
+ the same session. In the sticky-owner architecture this should only happen
32
+ during the initial `attach(...)` or an explicit repair attempt after the
33
+ original owner was lost, not during every healthy command.
27
34
  - **Version mismatch.** Very old or very new Chrome versions may not match
28
35
  Playwright's expected CDP shape; `status(session)` after attach returns
29
36
  details in that case.
@@ -33,13 +40,47 @@ Inspect the `error` and `reason` fields on the `launch(...)` failure result
33
40
  A `session` handle is valid only while the underlying browser connection
34
41
  is live.
35
42
 
36
- - If the browser process died, the next `act(...)` / `observe(...)` call
37
- will fail with a connection error. Use `status(session)` to confirm, then
38
- call `launch(...)` or `attach(...)` again.
43
+ - If the detached sticky owner died but the browser is still alive,
44
+ AgentBrowse may repair ownership on the next command or explicit restore
45
+ path.
46
+ - If the detached sticky owner hit its TTL, the next browser command may
47
+ recycle the owner and continue as long as the browser session is still live.
48
+ - If the browser process or remote CDP session died, the next
49
+ `act(...)` / `observe(...)` call fails closed. Use `status(session)` to
50
+ confirm, then call `launch(...)` or `attach(...)` again.
39
51
  - If you restored a session from `loadBrowserSession()` or a custom store,
40
52
  call `status(session)` right after loading. If it reports the session is
41
- no longer reachable, discard it and start fresh.
42
- - `close(session)` called twice is safe — the second call is a no-op.
53
+ no longer reachable, or a later command fails with
54
+ `sticky_owner_unrecoverable`, discard it and start fresh.
55
+ - `close(session)` called twice is safe — the second call is a no-op, and an
56
+ already-dead owner host is treated as already closed.
57
+
58
+ ## Restored Session Loads As `null`
59
+
60
+ `loadBrowserSession()` and custom stores intentionally reject incompatible
61
+ older session records that do not contain persistable sticky-owner metadata.
62
+
63
+ If a session that used to restore now loads as `null`:
64
+
65
+ - treat it as a stale local record, not as a partial session you should patch
66
+ by hand;
67
+ - delete the old session file if it is still on disk;
68
+ - run `launch(...)` or `attach(...)` again to create a new session record.
69
+
70
+ AgentBrowse does not auto-migrate reconnect-era session files.
71
+
72
+ ## `close(session)` Seems Stuck Or The Owner Host Already Died
73
+
74
+ `close(session)` first terminates the sticky owner and then closes the managed
75
+ browser when the session owns it.
76
+
77
+ - If the owner host is already gone, close remains idempotent.
78
+ - For detached owner hosts, AgentBrowse escalates from graceful termination to
79
+ a forced kill internally; there is no separate daemon command to run.
80
+ - In CLI wrappers, a successful close also clears the locally persisted browser
81
+ session and workflow bindings.
82
+ - If closing the managed browser itself fails, AgentBrowse reports that failure
83
+ and keeps the session record so you can inspect or retry.
43
84
 
44
85
  ## Why The Package Uses Both Puppeteer And Playwright
45
86
 
@@ -15,6 +15,7 @@ Then run the examples from `packages/agentbrowse`:
15
15
  npx tsx examples/basic.ts
16
16
  npx tsx examples/attach.ts
17
17
  npx tsx examples/extract.ts
18
+ npx tsx examples/match-resolve-fill.ts
18
19
  ```
19
20
 
20
21
  Examples:
@@ -27,6 +28,12 @@ Examples:
27
28
  - `extract.ts`
28
29
  Runs structured extraction with an assistive runtime and a plain schema
29
30
  object.
31
+ - `match-resolve-fill.ts`
32
+ Demonstrates `match`, `resolve`, and `fill` against a self-contained
33
+ data: URL form: `match(...)` picks candidates, `resolve(...)` walks an
34
+ unresolved plan through a stub vault resolver, and `fill(...)` applies
35
+ both values through the browser without placing them in the match
36
+ result itself.
30
37
 
31
38
  For protected-fill usage (paying with a card, filling login credentials
32
39
  from a user's vault), see [../docs/protected-fill.md](../docs/protected-fill.md).
@@ -0,0 +1,107 @@
1
+ import {
2
+ close,
3
+ fill,
4
+ launch,
5
+ match,
6
+ observe,
7
+ resolve,
8
+ type AgentbrowseMatchResolver,
9
+ } from '@mercuryo-ai/agentbrowse';
10
+
11
+ // Self-contained data URL with two inputs — keeps the example runnable
12
+ // without depending on any external page.
13
+ const FORM_PAGE = `data:text/html;charset=utf-8,${encodeURIComponent(`
14
+ <!doctype html>
15
+ <html lang="en">
16
+ <head><meta charset="utf-8"><title>Match / Resolve / Fill demo</title></head>
17
+ <body>
18
+ <form>
19
+ <label>Email <input type="email" name="email" autocomplete="email"></label>
20
+ <label>Password <input type="password" name="password" autocomplete="current-password"></label>
21
+ </form>
22
+ </body>
23
+ </html>
24
+ `)}`;
25
+
26
+ // Fake resolver that stands in for a vault lookup. In production it would
27
+ // call MagicPay, another secret manager, or an approval backend.
28
+ const vaultResolver: AgentbrowseMatchResolver = {
29
+ async resolve(plan) {
30
+ if ('fillRef' in plan) {
31
+ throw new Error('This example does not support grouped resolution plans.');
32
+ }
33
+ if (plan.resolve.kind !== 'example_vault' || plan.resolve.key !== 'demo.password') {
34
+ throw new Error(`Unknown resolution plan: ${plan.resolve.kind} / ${plan.resolve.key}`);
35
+ }
36
+ return { kind: 'value', value: 'top-secret-password' };
37
+ },
38
+ };
39
+
40
+ const launchResult = await launch(FORM_PAGE, { headless: false });
41
+ if (!launchResult.success) {
42
+ throw new Error(launchResult.reason ?? launchResult.message);
43
+ }
44
+
45
+ const { session } = launchResult;
46
+
47
+ try {
48
+ const observed = await observe(session);
49
+ if (!observed.success) {
50
+ throw new Error(observed.reason ?? observed.message);
51
+ }
52
+
53
+ const emailTarget = observed.targets.find((target) => target.inputType === 'email');
54
+ const passwordTarget = observed.targets.find((target) => target.inputType === 'password');
55
+
56
+ if (!emailTarget || !passwordTarget) {
57
+ throw new Error('Expected email and password targets on the demo page.');
58
+ }
59
+
60
+ // ---- Simple path: match → fill ----------------------------------------
61
+ const emailMatch = await match(emailTarget, {
62
+ from: { email: 'traveler@example.com' },
63
+ });
64
+
65
+ if (emailMatch.kind !== 'ready') {
66
+ throw new Error(`Unexpected email match kind: ${emailMatch.kind}`);
67
+ }
68
+
69
+ // JSON.stringify proves the value is not in the match result itself.
70
+ console.info('email match kind:', emailMatch.kind);
71
+ console.info('email match serialised:', JSON.stringify(emailMatch));
72
+
73
+ const emailFill = await fill(session, emailTarget, emailMatch);
74
+ console.info('email fill success:', emailFill.success);
75
+
76
+ // ---- Explicit resolver path: match → resolve → fill -------------------
77
+ const passwordMatch = await match(passwordTarget, {
78
+ from: [
79
+ {
80
+ fieldKey: 'password',
81
+ type: 'secret',
82
+ resolve: { kind: 'example_vault', key: 'demo.password' },
83
+ },
84
+ ],
85
+ });
86
+
87
+ if (passwordMatch.kind !== 'needs_resolution') {
88
+ throw new Error(`Unexpected password match kind: ${passwordMatch.kind}`);
89
+ }
90
+
91
+ // The match result carries the plan, not the value. It is safe to log
92
+ // or to ship across a process boundary.
93
+ console.info('password plan:', passwordMatch.plan);
94
+
95
+ const passwordReady = await resolve(passwordMatch, { with: vaultResolver });
96
+ const passwordFill = await fill(session, passwordTarget, passwordReady);
97
+ console.info('password fill success:', passwordFill.success);
98
+
99
+ // ---- Equivalent one-call path -----------------------------------------
100
+ // `fill(...)` can do the resolve step inline when a resolver is passed:
101
+ //
102
+ // await fill(session, passwordTarget, passwordMatch, { resolver: vaultResolver });
103
+ //
104
+ // Use it when you do not need to inspect the ready match between steps.
105
+ } finally {
106
+ await close(session);
107
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mercuryo-ai/agentbrowse",
3
- "version": "0.2.60",
3
+ "version": "0.2.63",
4
4
  "type": "module",
5
5
  "description": "Browser automation primitives library for AI agents",
6
6
  "license": "MIT",
@@ -11,7 +11,8 @@
11
11
  "ai-agent",
12
12
  "browser-sdk",
13
13
  "playwright",
14
- "cdp"
14
+ "cdp",
15
+ "form-filling"
15
16
  ],
16
17
  "repository": {
17
18
  "type": "git",
@@ -81,6 +82,7 @@
81
82
  "test:e2e:autonomous": "npm run test:autonomous:scenarios",
82
83
  "test:e2e:autonomous:bare": "npm run test:autonomous:scenarios:bare",
83
84
  "check-types": "tsc --noEmit",
85
+ "check-types:examples": "npm run build && tsc -p tsconfig.examples.json",
84
86
  "lint": "biome check src docs README.md",
85
87
  "pack:verify": "node scripts/verify-pack-artifact.mjs",
86
88
  "smoke:pack-install": "node scripts/verify-pack-install-smoke.mjs"
@@ -1,22 +0,0 @@
1
- import type { BrowserSessionState } from './browser-session-state.js';
2
- import { type ProtectedFillExecutionResult } from './secrets/protected-fill.js';
3
- import type { PersistedFillableForm, StoredSecretFieldPolicies, StoredSecretFieldKey } from './secrets/types.js';
4
- export type FillProtectedFormBrowserResult = {
5
- success: true;
6
- pageRef: string;
7
- url: string;
8
- title: string;
9
- execution: ProtectedFillExecutionResult;
10
- } | {
11
- success: false;
12
- error: 'browser_connection_failed' | 'page_resolution_failed';
13
- message: string;
14
- reason: string;
15
- };
16
- export declare function fillProtectedFormBrowser(params: {
17
- session: BrowserSessionState;
18
- fillableForm: PersistedFillableForm;
19
- protectedValues: Partial<Record<StoredSecretFieldKey, string>>;
20
- fieldPolicies?: StoredSecretFieldPolicies;
21
- }): Promise<FillProtectedFormBrowserResult>;
22
- //# sourceMappingURL=protected-fill-browser.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protected-fill-browser.d.ts","sourceRoot":"","sources":["../src/protected-fill-browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAOtE,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,8BAA8B,GACtC;IACE,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,4BAA4B,CAAC;CACzC,GACD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,2BAA2B,GAAG,wBAAwB,CAAC;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,OAAO,EAAE,mBAAmB,CAAC;IAC7B,YAAY,EAAE,qBAAqB,CAAC;IACpC,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/D,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAqD1C"}
@@ -1,52 +0,0 @@
1
- import { connectPlaywright, disconnectPlaywright, resolvePageByRef, syncSessionPage, } from './playwright-runtime.js';
2
- import { executeProtectedFill, } from './secrets/protected-fill.js';
3
- export async function fillProtectedFormBrowser(params) {
4
- let browser = null;
5
- try {
6
- browser = await connectPlaywright(params.session.cdpUrl);
7
- }
8
- catch (error) {
9
- return {
10
- success: false,
11
- error: 'browser_connection_failed',
12
- message: 'Protected fill could not connect to the browser.',
13
- reason: error instanceof Error ? error.message : String(error),
14
- };
15
- }
16
- try {
17
- const page = await resolvePageByRef(browser, params.session, params.fillableForm.pageRef).catch((error) => {
18
- throw new Error(error instanceof Error ? error.message : String(error));
19
- });
20
- const { url, title } = await syncSessionPage(params.session, params.fillableForm.pageRef, page);
21
- const execution = await executeProtectedFill({
22
- session: params.session,
23
- page,
24
- fillableForm: params.fillableForm,
25
- protectedValues: Object.fromEntries(Object.entries(params.protectedValues).filter((entry) => {
26
- const value = entry[1];
27
- return typeof value === 'string' && value.length > 0;
28
- })),
29
- fieldPolicies: params.fieldPolicies,
30
- });
31
- return {
32
- success: true,
33
- pageRef: params.fillableForm.pageRef,
34
- url,
35
- title,
36
- execution,
37
- };
38
- }
39
- catch (error) {
40
- return {
41
- success: false,
42
- error: 'page_resolution_failed',
43
- message: 'Protected fill could not resolve the target page in the browser.',
44
- reason: error instanceof Error ? error.message : String(error),
45
- };
46
- }
47
- finally {
48
- if (browser) {
49
- await disconnectPlaywright(browser);
50
- }
51
- }
52
- }