@unfenced-ai/sdk 0.1.0

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 (59) hide show
  1. package/LICENSE +30 -0
  2. package/README.md +171 -0
  3. package/dist/client.d.ts +385 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +349 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/credentials.d.ts +14 -0
  8. package/dist/credentials.d.ts.map +1 -0
  9. package/dist/credentials.js +17 -0
  10. package/dist/credentials.js.map +1 -0
  11. package/dist/fetch.d.ts +16 -0
  12. package/dist/fetch.d.ts.map +1 -0
  13. package/dist/fetch.js +387 -0
  14. package/dist/fetch.js.map +1 -0
  15. package/dist/http.d.ts +76 -0
  16. package/dist/http.d.ts.map +1 -0
  17. package/dist/http.js +250 -0
  18. package/dist/http.js.map +1 -0
  19. package/dist/index.d.ts +53 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +41 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/library.d.ts +17 -0
  24. package/dist/library.d.ts.map +1 -0
  25. package/dist/library.js +25 -0
  26. package/dist/library.js.map +1 -0
  27. package/dist/memory.d.ts +13 -0
  28. package/dist/memory.d.ts.map +1 -0
  29. package/dist/memory.js +45 -0
  30. package/dist/memory.js.map +1 -0
  31. package/dist/permissions.d.ts +29 -0
  32. package/dist/permissions.d.ts.map +1 -0
  33. package/dist/permissions.js +69 -0
  34. package/dist/permissions.js.map +1 -0
  35. package/dist/protocol.d.ts +296 -0
  36. package/dist/protocol.d.ts.map +1 -0
  37. package/dist/protocol.js +89 -0
  38. package/dist/protocol.js.map +1 -0
  39. package/dist/session.d.ts +97 -0
  40. package/dist/session.d.ts.map +1 -0
  41. package/dist/session.js +88 -0
  42. package/dist/session.js.map +1 -0
  43. package/dist/sessions.d.ts +131 -0
  44. package/dist/sessions.d.ts.map +1 -0
  45. package/dist/sessions.js +197 -0
  46. package/dist/sessions.js.map +1 -0
  47. package/dist/token-usage.d.ts +11 -0
  48. package/dist/token-usage.d.ts.map +1 -0
  49. package/dist/token-usage.js +34 -0
  50. package/dist/token-usage.js.map +1 -0
  51. package/dist/types.d.ts +1409 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/url-identity.d.ts +8 -0
  56. package/dist/url-identity.d.ts.map +1 -0
  57. package/dist/url-identity.js +18 -0
  58. package/dist/url-identity.js.map +1 -0
  59. package/package.json +44 -0
package/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ unfenced — Proprietary Software License
2
+ Copyright © 2026 timeis-art. All rights reserved.
3
+
4
+ This software, including its source code, design, documentation, and all
5
+ associated materials (the "Software"), is the proprietary and confidential
6
+ property of timeis-art. It is NOT open source.
7
+
8
+ No license, right, or permission is granted to any person or entity to use,
9
+ copy, reproduce, modify, adapt, merge, publish, distribute, transmit, display,
10
+ sublicense, sell, or create derivative works of the Software, in whole or in
11
+ part, except under a separate written agreement signed by timeis-art.
12
+
13
+ Limited client grant. The published client packages "@unfenced-ai/mcp" and
14
+ "@unfenced-ai/sdk" may be installed and used solely to connect to an authorized,
15
+ paid unfenced service. This limited grant conveys no rights to the unfenced
16
+ engine, server, or service; is personal and non-transferable; and may be
17
+ modified or revoked at any time. It does not extend to any other part of the
18
+ Software.
19
+
20
+ Unauthorized access to, use, reproduction, or distribution of the Software is
21
+ strictly prohibited and may violate applicable copyright and other laws.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
25
+ FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
26
+ HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION
27
+ OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE
28
+ SOFTWARE OR ITS USE.
29
+
30
+ For licensing inquiries, contact timeis-art.
package/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # @unfenced-ai/sdk
2
+
3
+ Typed client for [Unfenced](https://unfenced.ai) - fetch
4
+ any page as clean, agent-ready content and drive a **real browser** (observe,
5
+ click, type, extract) on the machine the server runs on, using the cookies that
6
+ server holds for your account. Which address it egresses from is that
7
+ deployment's configuration, not a property of this client.
8
+
9
+ Zero dependencies. Uses the platform `fetch`, so it runs anywhere that has one - Node 22.12
10
+ or newer, which is the floor for the `require` condition in its `exports` map.
11
+
12
+ Not from a **browser page on another origin**, though: every request carries an
13
+ `x-unfenced-client` header for attribution, which is not a CORS-safelisted header,
14
+ so a cross-origin call preflights and the worker does not answer it. Node, a
15
+ bundler, or same-origin code is the supported shape.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install @unfenced-ai/sdk
21
+ ```
22
+
23
+ > **Not on the registry yet.** `@unfenced-ai/sdk` answers 404 today; until the first
24
+ > publish this package is only reachable from a checkout. Note the scope: the bare
25
+ > `@unfenced` scope on npm belongs to somebody else and nothing there is ours - do not
26
+ > install from it.
27
+
28
+ You also need an unfenced service to point at - either the hosted endpoint from
29
+ your dashboard's **Connect** panel, or a checkout running `pnpm dev`. The server is
30
+ proprietary and not on npm; the **Connect** panel at <https://unfenced.ai> is where a
31
+ hosted endpoint and a key come from. (This file ships inside the tarball, so a link into
32
+ the repository would resolve nowhere for a reader who installed it.)
33
+
34
+ ## Fetch a page
35
+
36
+ ```ts
37
+ import { Unfenced } from "@unfenced-ai/sdk";
38
+
39
+ const ac = new Unfenced({
40
+ baseUrl: "http://127.0.0.1:8787", // where the server is
41
+ apiKey: process.env.UNFENCED_TOKEN, // required against a hosted service
42
+ });
43
+
44
+ const result = await ac.fetch("https://example.com");
45
+ if (result.outcome === "delivered") {
46
+ console.log(result.meta.tier); // 1 = HTTP, 2 = stealth browser, 3 = headed
47
+ console.log(result.doc.markdown); // clean markdown, not raw HTML
48
+ }
49
+ ```
50
+
51
+ The fetch escalates from plain HTTP to a stealth browser to a headed browser
52
+ only as far as the site forces - you always get back the same clean document.
53
+ `result.meta.omissions` names content that was left out, including hidden text,
54
+ listing prose, page limits, settling uncertainty, and byte or word caps.
55
+ An unfinished browser navigation is reported as `navigation-incomplete`, not as a byte cap.
56
+ `result.meta.totalWords` is present only when the full source was counted.
57
+ `fetch()` and batch calls accept `robots: "ignore" | "report" | "obey"` alongside
58
+ `identify` and `locale`; the SDK sends the same policy on every submitted job.
59
+
60
+ There are **four** outcomes, not two: `delivered`, `failed`, `offered`, and
61
+ `archived`. An `offered` result means the server found a door and did not open
62
+ it (a paywall, a sign-in). An `archived` result is a history receipt whose full
63
+ page content has expired; fetch the URL again to read it. There is
64
+ deliberately no `result.ok`, because a boolean would compile everywhere and
65
+ route every `offered` into whichever branch the caller already had for failure,
66
+ silently. Branch on `outcome`.
67
+
68
+ ## Drive a live browser
69
+
70
+ ```ts
71
+ const session = await ac.open("https://news.ycombinator.com");
72
+
73
+ // See what's on the page. Controls the page DECLARES carry a stable `ref`;
74
+ // things it merely draws as clickable arrive in `undeclared` with no ref, and
75
+ // are reached by their visible words instead - act({ on: "3 people" }).
76
+ const page = await session.observe();
77
+ const search = page.controls.find((c) => /search/i.test(c.name));
78
+
79
+ // Do things. A real mouse/keyboard drives it, through the same guardrails a
80
+ // human has: password fields are refused, form-submits need `confirm: true`.
81
+ if (search) {
82
+ await session.type(search.ref, "show hn", { submit: true, confirm: true });
83
+ }
84
+
85
+ // Read it clean, or watch it.
86
+ const { content } = await session.extract("markdown");
87
+ const jpeg = await session.screenshot(); // data: URI
88
+
89
+ await session.close();
90
+ ```
91
+
92
+ ### Acting needs permission
93
+
94
+ Reading a page is always allowed. **Acting** (click, type, select, keystroke)
95
+ requires the site be on the act-allowlist - a deliberate boundary so a session
96
+ holding real logins can only touch sites you named:
97
+
98
+ ```ts
99
+ await ac.permissions(); // the sites this account may act on
100
+ ```
101
+
102
+ `ac.allow()` and `ac.deny()` work only against a local checkout. On a hosted
103
+ service both answer **403** - _an API key cannot grant site permissions_ - because
104
+ deciding what an agent may click is a human control, and a key that could widen
105
+ its own reach would not be one. Grant from the dashboard, or have the agent call
106
+ `connect_site` to hand the owner a link.
107
+
108
+ Note also that `permissions()` lists only the freely-allowed sites. A host held at
109
+ _approve_ is not in it; `permissionEntries()` is the richer view that carries the
110
+ mode.
111
+
112
+ If you act on a site that isn't allowed, `act` returns
113
+ `{ ok: false, permissionRequired: "<site>" }` rather than throwing - grant it
114
+ and retry.
115
+
116
+ ## The session library
117
+
118
+ Every demo / agent / live-channel run the server records is queryable:
119
+
120
+ ```ts
121
+ const runs = await ac.sessions({ kind: "agent", q: "etsy", limit: 20 });
122
+ const detail = await ac.recordedSession(runs[0].id); // frames, trace, answer
123
+ ```
124
+
125
+ ## API
126
+
127
+ | Method | Does |
128
+ | ------------------------------------------------------- | ------------------------------------- |
129
+ | `ac.fetch(url, opts?)` | fetch one URL as clean content |
130
+ | `ac.batch(urls, opts?)` | fetch many concurrently |
131
+ | `ac.open(url, opts?)` | open a live browser → a `Session` |
132
+ | `ac.liveSessions()` | list open live sessions |
133
+ | `ac.refresh(id, opts?)` | current page plus provider continuity |
134
+ | `ac.sessions(query?)` / `ac.recordedSession(id)` | the recorded library |
135
+ | `ac.history()` / `ac.domains()` | memory |
136
+ | `ac.permissions()` / `ac.allow(site)` / `ac.deny(site)` | act-allowlist |
137
+ | `session.refresh(opts?)` | current page plus provider continuity |
138
+ | `session.observe(opts?)` | snapshot of controls/links/text |
139
+ | `session.click/type/select/press/scroll/navigate/back` | act |
140
+ | `session.extract(format?)` | clean content of the open page |
141
+ | `session.screenshot()` | JPEG data URI |
142
+ | `session.close()` | close it |
143
+
144
+ Batch methods default to eight concurrent jobs. Set `concurrency` to an integer
145
+ from 1 to 32 to tune that limit; invalid values reject before work starts. Results
146
+ retain input order and reuse duplicate URLs. `batchWithin` stops submitting queued
147
+ URLs when its shared deadline expires.
148
+
149
+ `timeoutMs` and the shared `batchWithin` deadline accept integer milliseconds
150
+ from 0 to 2147483647. Zero returns timeout results without submitting work.
151
+ Invalid durations reject with `RangeError`, including for batch calls, before
152
+ any URL is submitted.
153
+
154
+ Errors surface as `UnfencedError` (carrying `status` and `detail`) for
155
+ non-2xx responses; refusals from `act` come back as a result, not an exception.
156
+ Structured errors also preserve `code`, `remedy`, a valid nonnegative integer
157
+ `retryAfterMs` from the response body, and the original `retryAfter` header when
158
+ present. The header can contain seconds or an HTTP date; it is not automatically
159
+ converted or used to resubmit a request. Delays may exceed a runtime's timer
160
+ range, so apply your task deadline and cancellation policy before waiting.
161
+ A lost response can follow an accepted write: check the operation's state before
162
+ retrying it. Retry guidance alone does not make a write safe to repeat.
163
+
164
+ ## License
165
+
166
+ Proprietary. © 2026 timeis-art. All rights reserved. Not open source.
167
+
168
+ This client may be installed and used **solely to connect to an authorized, paid
169
+ unfenced service**. The grant is personal and non-transferable, conveys no rights
170
+ to the unfenced engine, server or service, and may be modified or revoked at any
171
+ time. See the `LICENSE` file in this package.
@@ -0,0 +1,385 @@
1
+ import type { TokenUsage } from "./token-usage.js";
2
+ import type { Session } from "./session.js";
3
+ import type { ExtractedDoc } from "./protocol.js";
4
+ import type { AccountPrefs, Action, ActResult, ActExpectation, AtAction, CredentialName, DownloadInfo, FetchOptions, FetchResult, Format, FormField, FormFillResult, MemoryEntry, MemoryRecallOptions, OnAction, PageSnapshot, PendingApproval, ProviderSessionReason, ReadPage, SeenPage, SessionDetail, SessionInfo, SessionSummary, UnfencedOptions } from "./types.js";
5
+ export declare class Unfenced {
6
+ /** The transport. Holds the base URL, the token, the fetch, and the extra
7
+ * headers — the four things every method's request needs — so the methods
8
+ * themselves carry none of it. */
9
+ private readonly http;
10
+ constructor(options?: UnfencedOptions);
11
+ /** Report counts only. Never sends tool arguments, page text, or image data. */
12
+ recordTokenUsage(usage: TokenUsage): Promise<void>;
13
+ /**
14
+ * Fetch a URL as clean content. Escalates from plain HTTP to a stealth
15
+ * browser to a headed browser only as far as the site forces, and resolves
16
+ * when the job is done.
17
+ */
18
+ fetch(url: string, options?: FetchOptions): Promise<FetchResult>;
19
+ /**
20
+ * Fetch many URLs concurrently (each escalates independently).
21
+ *
22
+ * One entry per URL, in input order, with a failed URL carrying its structured
23
+ * error in place. A single bad URL must never cost the caller the whole batch —
24
+ * an agent batching 20 URLs would otherwise lose all 20 and have to bisect to
25
+ * find the offender.
26
+ */
27
+ batch(urls: string[], options?: FetchOptions): Promise<FetchResult[]>;
28
+ /**
29
+ * The same, but it always answers.
30
+ *
31
+ * `batch` resolves when every URL has, so one slow host decides when the
32
+ * whole call returns. An external QA run watched a ten-URL batch blow its
33
+ * client's sixty-second transport timeout — which returns NOTHING: every
34
+ * sibling that had already succeeded was discarded with it, and the caller
35
+ * got an opaque transport error naming no URL, so it could not even retry
36
+ * intelligently.
37
+ *
38
+ * The per-URL error isolation this tool promises only ever covered fast
39
+ * failures. This covers slow ones. Each URL races one shared deadline;
40
+ * whatever has not arrived becomes a `timeout` entry, in input order.
41
+ *
42
+ * A partial answer is worth far more to an agent than none — it can use what
43
+ * came back and retry exactly what did not.
44
+ */
45
+ batchWithin(urls: string[], deadlineMs: number, options?: FetchOptions): Promise<FetchResult[]>;
46
+ /**
47
+ * Open a live browser session on a URL and get a handle to drive it.
48
+ *
49
+ * `account` names a sign-in account to act as (e.g. a specific one of several
50
+ * Google logins). It selects that account's isolated, stored session — so the
51
+ * page opens already signed in as that account and cookie changes persist back
52
+ * to it. Absent means the default session.
53
+ *
54
+ * A SIGN-IN ACCOUNT's name ("google", "google-2") — not a site or host, and
55
+ * not the name of a per-site login ("namecheap.com"), which is a password used
56
+ * INSIDE an account rather than an account. A credential's `site` says where a
57
+ * login is used, not what it is called, and the two sit next to each other in
58
+ * every listing; passing either opened a Chrome profile and a stored session
59
+ * that nothing else ever read, so the login was asked for again and never
60
+ * reached the next machine. The server now answers `unknown-account` (400)
61
+ * rather than quietly creating that drawer — unless the name already HAS a
62
+ * stored session, which is a drawer it opens rather than mints. A roster it
63
+ * could not read answers `accounts-unreadable` (503): retry, or omit `account`.
64
+ */
65
+ open(url: string, options?: {
66
+ headless?: boolean;
67
+ profile?: "ephemeral" | "agent";
68
+ proxy?: string;
69
+ account?: string;
70
+ /**
71
+ * What you mean to do with the page. `"act"` states that it will be
72
+ * clicked, typed into or submitted.
73
+ *
74
+ * It matters because a live browser costs a measured ~819 MB and one of the
75
+ * account's session slots, held until it idles out. A page that domain
76
+ * memory already knows a plain fetch answers, with no stored login for it,
77
+ * is refused with `use-fetch` rather than spending that on bytes
78
+ * `fetch()` returns. Passing `"act"` opens it.
79
+ */
80
+ intent?: "read" | "act";
81
+ /**
82
+ * How long to let the network go quiet after the page commits, before the
83
+ * opening snapshot is taken. Default 4000ms, maximum 15000.
84
+ *
85
+ * A different clock from the navigation's own timeout: a page that
86
+ * exceeds THIS one is read as it stands rather than refused, so raising
87
+ * it buys a more complete first reading of a page that draws from several
88
+ * slow fetches, and never turns a slow page into an error.
89
+ */
90
+ settleMs?: number;
91
+ }): Promise<Session & {
92
+ providerSession?: ProviderSessionReason;
93
+ /** True when this is a page you already had open on the host, not a new one. */
94
+ reusedExistingSession?: boolean;
95
+ /** True when that reused page was navigated to the URL you asked for. */
96
+ navigated?: boolean;
97
+ /**
98
+ * Something about THIS open worth saying, when there is anything.
99
+ *
100
+ * Two producers, one field: a reused page that was navigated, and an open
101
+ * whose settle budget ran out with the network still busy — meaning the
102
+ * snapshot beside it may not be the finished page. Both answer "what would
103
+ * you otherwise have to guess about this reading", which is why they share
104
+ * a name rather than each having one.
105
+ */
106
+ note?: string;
107
+ }>;
108
+ /**
109
+ * Switch an open session to a DIFFERENT sign-in account — "check my other
110
+ * account". An account is bound to a page's isolated profile at open, so this
111
+ * is not a live swap: the current account's jar is saved, its page closed, and
112
+ * the same SITE reopened signed in as `account`. Returns a NEW Session (a new
113
+ * id) — use it going forward; the old one is closed. A one-off that never
114
+ * changes the site's configured default.
115
+ *
116
+ * `account` is a sign-in account's NAME, never a site or host — an unknown one
117
+ * is refused with `unknown-account` (400) BEFORE the open page is torn down, so
118
+ * a bad name costs nothing and leaves the current session usable.
119
+ */
120
+ switchAccount(sessionId: string, account: string): Promise<{
121
+ session: Session;
122
+ restoredSession: boolean;
123
+ requestedAccount?: string;
124
+ observedIdentity?: string;
125
+ }>;
126
+ /**
127
+ * Which account the page is actually signed in as — the DOWNSTREAM identity (e.g.
128
+ * which ChatGPT account), not the provider login that reached it. A non-disruptive
129
+ * same-origin read, so it can confirm identity mid-task. `identity` is null when the
130
+ * site is not one the server knows how to read (then observe the account menu).
131
+ */
132
+ /**
133
+ * What the account owner has to clear before the agent can continue.
134
+ *
135
+ * Read-only, and it must stay that way: a wall is cleared by a
136
+ * human-authenticated action, never by the caller that is blocked on it. An
137
+ * agent asking this is asking "what do you need from me" on the user's behalf,
138
+ * which is worth having as a question because most people do not live in the
139
+ * dashboard and would otherwise never learn a sign-in was waiting.
140
+ *
141
+ * `clearAt` is where the person goes. Hand that over rather than describing a
142
+ * screen.
143
+ */
144
+ pendingApprovals(): Promise<{
145
+ interrupts: PendingApproval[];
146
+ clearAt: string;
147
+ }>;
148
+ whoami(sessionId: string): Promise<{
149
+ identity: string | null;
150
+ source: string | null;
151
+ }>;
152
+ /** Every live session currently open on the server. */
153
+ liveSessions(): Promise<SessionInfo[]>;
154
+ observe(id: string, opts?: {
155
+ match?: string;
156
+ maxControls?: number;
157
+ maxLinks?: number;
158
+ excerptChars?: number;
159
+ media?: boolean;
160
+ }): Promise<PageSnapshot>;
161
+ /** Read the current page together with its provider-session continuity state. */
162
+ refresh(id: string, opts?: {
163
+ match?: string;
164
+ }): Promise<{
165
+ page: PageSnapshot;
166
+ providerSession?: ProviderSessionReason;
167
+ }>;
168
+ /**
169
+ * Read a page, and receive a picture with it when the reading cannot describe
170
+ * the page on its own.
171
+ *
172
+ * `observe` above returns the snapshot alone and keeps doing so, because that
173
+ * is what its callers expect. This one hands back the whole envelope — the
174
+ * server attaches `picture` and `marks` when the reading reports `look`, and a
175
+ * projection that quietly dropped them would put the agent back where it
176
+ * started: told that something is missing and made to spend a turn asking for
177
+ * it.
178
+ */
179
+ read(id: string, opts?: {
180
+ match?: string;
181
+ maxControls?: number;
182
+ maxLinks?: number;
183
+ excerptChars?: number;
184
+ media?: boolean;
185
+ }): Promise<ReadPage>;
186
+ /**
187
+ * `opts` are OPTIONS on the call, not fields of the action — a native dialog is
188
+ * raised by the page mid-act and is not part of what was asked of it.
189
+ */
190
+ act(id: string, action: Action | OnAction | AtAction, opts?: {
191
+ acceptDialog?: boolean;
192
+ dialogText?: string;
193
+ brief?: boolean;
194
+ /**
195
+ * Return a marked picture of the page this act landed on, in the same
196
+ * reply, as `view`. `brief`'s opposite, and the same kind of option: it
197
+ * changes the shape of the ANSWER, not what the page is asked to do.
198
+ */
199
+ see?: boolean;
200
+ /**
201
+ * What the act is supposed to ACHIEVE, checked after it runs. The reply
202
+ * carries `expected: {held, waitedMs}`. This type declared that reply
203
+ * field long before anything could ask for it.
204
+ */
205
+ expect?: ActExpectation;
206
+ }): Promise<ActResult>;
207
+ extract(id: string, format?: Format, maxWords?: number): Promise<{
208
+ doc: ExtractedDoc;
209
+ content: string;
210
+ url: string;
211
+ contentTruncated?: boolean;
212
+ totalWords?: number;
213
+ }>;
214
+ screenshot(id: string): Promise<string>;
215
+ /**
216
+ * A picture of the page with everything actable outlined and numbered.
217
+ *
218
+ * Separate from `screenshot` rather than an option on it, because the two have
219
+ * different callers and different costs: `screenshot` feeds a replay stream
220
+ * many times a turn and must stay a bare frame, while this one pays for a
221
+ * snapshot in order to guarantee the boxes and the list describe one instant.
222
+ */
223
+ see(id: string, opts?: {
224
+ /** Box the links too, numbered after the controls. Off by default: a page
225
+ * with two hundred of them is papered over. */
226
+ links?: boolean;
227
+ /** Raise the 50-box cap, up to 120. Anything else falls back to 50. */
228
+ maxMarks?: number;
229
+ }): Promise<SeenPage>;
230
+ /**
231
+ * Fill several fields in one call.
232
+ *
233
+ * The saving is model round trips, not network ones. Text only and never
234
+ * submits — a password goes through `act` as a fill_secret, which is the one
235
+ * path allowed to resolve a stored value.
236
+ */
237
+ fill(id: string, fields: readonly FormField[]): Promise<FormFillResult>;
238
+ /**
239
+ * Hold a page open while something happens elsewhere.
240
+ *
241
+ * For the wait a login actually involves: a code sent to email, an approval
242
+ * in an app. Capped by the server, and a parked page still holds a real tab,
243
+ * so only a few may be parked at once.
244
+ */
245
+ park(id: string, minutes?: number, reason?: string): Promise<{
246
+ ok: boolean;
247
+ until?: string;
248
+ }>;
249
+ /** Files this session's page has handed to the browser. Names and sizes. */
250
+ downloads(id: string): Promise<{
251
+ downloads: DownloadInfo[];
252
+ }>;
253
+ /**
254
+ * Read one of them as text.
255
+ *
256
+ * A PDF goes through the same reader a fetched PDF does, so downloading a
257
+ * statement and reading it is one capability rather than two halves of one.
258
+ */
259
+ readDownload(id: string, filename: string): Promise<{
260
+ filename: string;
261
+ bytes: number;
262
+ content: string;
263
+ doc: ExtractedDoc;
264
+ }>;
265
+ /**
266
+ * Release a live page. Idempotent: closing one that has already closed — or
267
+ * idled out — succeeds and says so, because that is the state you asked for.
268
+ */
269
+ /**
270
+ * Release a page. Idempotent: closing one that is already gone is the state
271
+ * the caller asked for, so it succeeds rather than erroring — an agent
272
+ * closing in a `finally` must not be punished for a slow task.
273
+ *
274
+ * `wasOpen` says whether anything was actually released. It is false for an
275
+ * id that is not open FOR YOU, which covers a mistyped id, one that idled
276
+ * out, and one that was closed earlier — deliberately not told apart, since
277
+ * three different answers would let an 8-character id be probed for
278
+ * existence across accounts.
279
+ */
280
+ closeSession(id: string): Promise<{
281
+ alreadyClosed?: boolean;
282
+ wasOpen?: boolean;
283
+ }>;
284
+ /** Recorded runs (demo / agent / live-channel), newest first. */
285
+ sessions(query?: {
286
+ kind?: string;
287
+ q?: string;
288
+ limit?: number;
289
+ }): Promise<SessionSummary[]>;
290
+ /** A recorded session with its replay frames, tool trace, and answer. */
291
+ recordedSession(id: string): Promise<SessionDetail>;
292
+ history(limit?: number): Promise<unknown[]>;
293
+ domains(): Promise<unknown[]>;
294
+ /** Sites the agent may act on WITHOUT asking (the free bucket only). */
295
+ permissions(): Promise<string[]>;
296
+ /**
297
+ * Every saved site with its mode. This — not permissions() — is what "may I act
298
+ * here?" must read: BOTH `free` and `approve` permit acting (approve just asks
299
+ * the human per action); only `read` does not. permissions() returns free-only,
300
+ * so a site granted "Ask each time" is invisible to it — which made agents give
301
+ * up on approve-granted sites they were in fact allowed to act on.
302
+ */
303
+ /**
304
+ * The act-allowlist AND whether this key is exempt from it.
305
+ *
306
+ * `permissionEntries` returns the granted hosts and nothing else, which reads
307
+ * as "these and no others" — wrong for a key carrying any-site, whose list is
308
+ * usually empty precisely because it needs no grants. Callers that decide
309
+ * whether to ATTEMPT something must use this one; the older method stays for
310
+ * callers that only want to display the grants.
311
+ */
312
+ permissionScope(): Promise<{
313
+ entries: Array<{
314
+ host: string;
315
+ mode: "free" | "approve" | "read";
316
+ }>;
317
+ anySite: boolean;
318
+ excludedSites: string[];
319
+ allowSiteRequests?: boolean;
320
+ }>;
321
+ permissionEntries(): Promise<Array<{
322
+ host: string;
323
+ mode: "free" | "approve" | "read";
324
+ }>>;
325
+ /**
326
+ * A deep link that opens the dashboard set up to unblock a site — the Add-login
327
+ * drawer for a missing login (mode "credential", the default), or the Sites
328
+ * grant for a missing permission (mode "permission"). Hand this to a person so
329
+ * they fix it in one screen; it carries only the host, never a secret.
330
+ */
331
+ connectLink(host: string, opts?: {
332
+ label?: string;
333
+ mode?: "credential" | "permission";
334
+ }): Promise<string>;
335
+ /** Allow the agent to act on a site. Returns the host key that was stored. */
336
+ allow(site: string): Promise<string>;
337
+ /** Revoke acting on a site. */
338
+ deny(site: string): Promise<boolean>;
339
+ /**
340
+ * Jot a durable note keyed by a short label, scoped to this agent.
341
+ *
342
+ * Survives across sessions — the agent's own scratchpad for task state, not a
343
+ * secret store. Setting the same key again overwrites it. Rejected server-side
344
+ * for an empty/oversized key or value, or when the scratchpad is full.
345
+ */
346
+ remember(key: string, value: string): Promise<MemoryEntry>;
347
+ /** Every note this agent holds, newest first. */
348
+ recall(): Promise<MemoryEntry[]>;
349
+ /** A bounded/prefix-filtered list of notes, newest first. */
350
+ recall(options: MemoryRecallOptions): Promise<MemoryEntry[]>;
351
+ /** One note by key, or `undefined` when nothing is stored under it. */
352
+ recall(key: string): Promise<MemoryEntry | undefined>;
353
+ /** Forget a note. Returns whether one was actually removed. */
354
+ forget(key: string): Promise<boolean>;
355
+ /**
356
+ * Store (or rotate) a secret under a name, scoped to this account+agent.
357
+ *
358
+ * This is the HUMAN path: a person at a dashboard/CLI puts the secret in once,
359
+ * and the agent thereafter fills it by name with a `fill_secret` action,
360
+ * never seeing the value. Returns the name, the account identifier, and the
361
+ * time — never the secret. There is deliberately no method that reads a stored
362
+ * secret back.
363
+ *
364
+ * `username` is the optional account email/login this credential is for, shown
365
+ * back so a login is recognizable. OMIT it on a password rotation to preserve
366
+ * the existing identifier; pass an empty string to clear it.
367
+ *
368
+ * `kind` is "password" (default) or "totp" — for a TOTP, `secret` is the
369
+ * authenticator SEED (a base32 string or otpauth:// URI), and the agent fills
370
+ * the current code with a fill_totp action, never seeing the seed or the code.
371
+ */
372
+ storeCredential(name: string, secret: string, username?: string, kind?: "password" | "totp"): Promise<CredentialName>;
373
+ /** The NAMES of the credentials stored for this account+agent. Never values. */
374
+ credentialNames(): Promise<CredentialName[]>;
375
+ /** Delete a stored credential by name. Returns whether one was removed. */
376
+ deleteCredential(name: string): Promise<boolean>;
377
+ /**
378
+ * How this account wants the agent to choose among several sign-in accounts:
379
+ * `askMode` "always" (ask every time a provider is ambiguous) or "remember"
380
+ * (reuse a per-site choice), plus the remembered site→account map. open_page
381
+ * reads this to decide whether to ask or reuse.
382
+ */
383
+ accountPrefs(): Promise<AccountPrefs>;
384
+ }
385
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}