@apteva/web-sdk 0.5.4 → 0.6.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 — 2026-09-07
4
+
5
+ - Add typed app-owned extensions through `defineAppExtension` and `client.use`.
6
+ - Add project/install-scoped app handles, HTTP/MCP request options, and app SSE subscriptions sharing live client credentials.
7
+ - Add framework-independent component references, manifest metadata types and a local export registry.
8
+ - Expose installed-app discovery and explicit metadata/version compatibility checks.
9
+ - Fix caller cancellation being overridden by request timeouts; retain cancellation and timeouts through response-body reads.
10
+ - Add abortable fetch subscriptions with SSE resume IDs, optional cursor queries, bounded opt-in deduplication, configurable reconnect delay and terminal auth handling.
11
+ - Add coordinated host-owned access-token renewal without automatically replaying HTTP requests.
12
+ - Preserve legacy Channel Chat APIs; app-specific extensions and UI stay in app-owned packages.
13
+
14
+ ## 0.5.5 — 2026-08-15
15
+
16
+ - Add a generic, opaque `accessToken` credential to `AptevaClient`, including
17
+ runtime `setAccessToken(...)` and `getAccessToken()` helpers. The SDK is not
18
+ coupled to Auth or any other token issuer.
19
+ - Give `accessToken` precedence over `apiKey`, send it only in the Bearer
20
+ header, omit cookies, and force authenticated fetch streaming for SSE.
21
+ - Keep legacy `apiKey: "uk_…"` behavior as a compatibility fallback while
22
+ removing token-prefix inference from the recommended integration.
23
+ - Deprecate the Channel Chat-specific `client.delegatedUsers.create(...)`
24
+ flow in favor of server-policy-controlled application-user tokens.
25
+
3
26
  ## 0.5.4 — 2026-08-13
4
27
 
5
28
  - Add `client.delegatedUsers.create(...)` for trusted-backend minting of
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Browser SDK for calling [apteva-server](https://github.com/apteva/server). Framework-agnostic. ~3 KB minified + gzipped.
4
4
 
5
- - **Auth** — session cookies, `Authorization: Bearer`, `X-API-Key`, `?api_key=` query — pick any, the SDK handles them.
5
+ - **Auth transport** — session cookies, private API keys, and opaque application-user access tokens. The SDK does not depend on a particular token issuer.
6
6
  - **App data** — `client.app("crm").get("/contacts")` reverse-proxies through `/api/apps/<name>/*`.
7
7
  - **App tools** — `client.app("crm").tool("contacts_search", {…})` posts an MCP `tools/call`, unwraps the JSON-RPC envelope, returns the tool's natural shape.
8
8
  - **Static-app mode** — when the UI is hosted by apteva-server itself (`runtime.kind: static`), `pickBaseURL` and `pickKioskKey` read the `<script>window.__APTEVA_APP__</script>` block the server injects.
@@ -22,8 +22,7 @@ import { AptevaClient } from "@apteva/web-sdk";
22
22
 
23
23
  const apteva = new AptevaClient({
24
24
  baseURL: "https://agents.example.com",
25
- // Optional. Omit to rely on the session cookie (after auth.login).
26
- apiKey: process.env.NEXT_PUBLIC_APTEVA_KEY,
25
+ // Optional. Omit to rely on an apteva-server session cookie.
27
26
  });
28
27
 
29
28
  // Sign in (sets the session cookie on the apteva-server domain).
@@ -40,22 +39,36 @@ const { leads } = await apteva.app("flexylead").tool<{ leads: Lead[] }>(
40
39
  );
41
40
  ```
42
41
 
43
- ## Auth carriers
42
+ ## Authentication carriers
44
43
 
45
- The SDK sends `credentials: "include"` on every request, so a session cookie set by `auth.login` flows automatically — same-origin always, cross-origin when the apteva-server's `CORS_ORIGIN` allowlists your domain (the default `permissive` mode echoes any origin).
44
+ With no bearer credential, the SDK sends `credentials: "include"` so an
45
+ apteva-server session cookie flows automatically. Private platform integrations
46
+ can provide `apiKey`. Browser applications should provide an opaque
47
+ `accessToken` issued by their trusted authentication flow.
46
48
 
47
- You can layer on an API key by setting `apiKey` in the constructor or calling `client.setApiKey(...)` at runtime. Bearer-wins-over-cookie on the wire.
49
+ `accessToken` takes precedence over `apiKey`. It is sent only through the
50
+ `Authorization: Bearer` header, cookie credentials are omitted, and SSE uses
51
+ authenticated `fetch()` streaming. The SDK does not inspect its prefix or know
52
+ whether Auth, another Apteva app, or a customer service issued it.
48
53
 
49
54
  ```ts
50
55
  const apteva = new AptevaClient({
51
56
  baseURL: "...",
52
- apiKey: "sk-...", // optional
57
+ accessToken: loginResult.apteva_access_token, // application user
58
+ // apiKey: process.env.APTEVA_API_KEY, // trusted backend only
53
59
  projectId: "proj_123", // routes project-scoped app HTTP and MCP calls
54
60
  onUnauthorized: () => router.push("/login"), // fires once per 401
55
61
  timeoutMs: 30_000, // default, 0 disables
56
62
  });
63
+
64
+ // Replace an expired token without rebuilding the client.
65
+ apteva.setAccessToken(refreshed.apteva_access_token);
57
66
  ```
58
67
 
68
+ The example above deliberately leaves login outside the SDK. Auth can return
69
+ `apteva_access_token`, but the Web SDK remains decoupled and accepts any opaque
70
+ bearer token that apteva-server recognizes.
71
+
59
72
  ## App HTTP routes
60
73
 
61
74
  `client.app(name)` returns a handle with `get / post / put / patch / del` that route to `/api/apps/<name>/<path>`. Same auth, same proxy, same error model.
@@ -80,6 +93,185 @@ If the MCP call returns a JSON-RPC error, the SDK throws `AptevaError(-1, messag
80
93
 
81
94
  For lower-level usage, `client.callTool(appName, toolName, args)` and the standalone `unwrapMCP(envelope)` are both exported.
82
95
 
96
+ ## App-owned extensions and web components
97
+
98
+ Apps can publish a headless client and frontend components from their own
99
+ versioned package. The core SDK supplies transport, component references, and
100
+ metadata checks; it has no React dependency and does not import executable UI
101
+ from a server. A dashboard wrapper and an external package can share the same
102
+ component source, receiving an app handle instead of implementing authentication
103
+ and requests again.
104
+
105
+ ### Typed extensions
106
+
107
+ `defineAppExtension` preserves the extension's return type. `client.use` supplies
108
+ an authenticated app handle. Each call creates a new instance: retain it in your
109
+ host (for example with React's `useMemo`), and close subscriptions when unmounting.
110
+ An async `create` is supported; `use` then returns its Promise unchanged.
111
+
112
+ ```ts
113
+ import { AptevaClient, defineAppExtension } from "@apteva/web-sdk";
114
+
115
+ // Illustrative app-owned API. Replace routes and wire types with your app's contract.
116
+ const itemsExtension = defineAppExtension({
117
+ app: "example",
118
+ create: ({ app }) => ({
119
+ list: (signal?: AbortSignal) =>
120
+ app.get<Array<{ id: string; title: string }>>("/items", { signal }),
121
+ }),
122
+ });
123
+
124
+ const client = new AptevaClient({ baseURL: "https://agents.example.com", accessToken });
125
+ const items = client.use(itemsExtension, { projectId: "p1", installId: 42 });
126
+ const rows = await items.list(); // typed result
127
+ ```
128
+
129
+ Extensions contain the app's own business logic and API contract validation.
130
+ A Conversations extension and its chat, inbox, and approval UI belong in the
131
+ Conversations package. The existing `client.chat` remains a Channel Chat API;
132
+ it is not redirected to Conversations.
133
+
134
+ ### Shared app transport
135
+
136
+ `client.app(name, { projectId, installId })` scopes HTTP, MCP, and subscriptions
137
+ together. It exposes `name`, `projectId`, and `installId` for host context and
138
+ reads the client's current credentials on each request or reconnection.
139
+ Explicit handle scope overrides routing query parameters. With no explicit
140
+ project scope, the existing client default and query-override behavior remain.
141
+ The platform still validates the selected installation and project.
142
+
143
+ ```ts
144
+ const app = client.app("example", { projectId: "p1", installId: 42 });
145
+ const controller = new AbortController();
146
+
147
+ await app.post("/items", { title: "Hello" }, { signal: controller.signal });
148
+ await app.tool("items_list", {}, { signal: controller.signal });
149
+
150
+ const subscription = app.subscribe<{ id: string; title: string }>(
151
+ "/events",
152
+ (row, metadata) => console.log(row, metadata.event, metadata.id),
153
+ { signal: controller.signal, eventTypes: ["item.updated"] },
154
+ );
155
+ subscription.close();
156
+ ```
157
+
158
+ All HTTP helpers accept `RequestInit`; MCP accepts it as the third argument.
159
+ Cancellation works alongside the client timeout, including while reading the
160
+ response body. App paths must start with `/` and remain inside the app route.
161
+ Use the raw client methods for platform endpoints. No HTTP method is retried
162
+ automatically. Pass an app-supported idempotency header or body field explicitly
163
+ when the app contract permits a write to be retried.
164
+
165
+ ### Component exports and manifest metadata
166
+
167
+ `AppComponentReference` is the existing `{ app, name, props? }` message shape;
168
+ `ChatComponent` remains a compatible name. `AppComponentSpec` mirrors existing
169
+ `provides.ui_components` metadata, including slots, prop schemas and widget
170
+ settings. There is no second server declaration format.
171
+
172
+ `AppComponentRegistry<T>` maps those app/component names to local frontend
173
+ exports. It accepts framework-specific components or host-owned loaders without
174
+ adding a framework dependency. Registration rejects duplicate names atomically
175
+ and returns an idempotent unregister function; unknown references resolve to
176
+ `undefined` so the host can render a fallback.
177
+
178
+ ```ts
179
+ import { AppComponentRegistry } from "@apteva/web-sdk";
180
+ import { ItemCard } from "./components/ItemCard"; // or an app-owned frontend package
181
+
182
+ const components = new AppComponentRegistry<typeof ItemCard>();
183
+ const unregister = components.register("example", { "item-card": ItemCard });
184
+ const Component = components.resolve({ app: "example", name: "item-card" });
185
+ // Render Component using your framework and validated, appropriate props.
186
+ unregister();
187
+ ```
188
+
189
+ `AppComponentContext` defines a host-injected `app: AppHandle`. Pass this trusted
190
+ context separately from message data; do not let message props replace it.
191
+ The host handles rendering, slots, schema validation, loading/error boundaries,
192
+ theme and component lifecycle. Registry membership alone does not establish
193
+ installation, compatibility, identity or authorization. Existing dashboard
194
+ module loading remains a host concern; installing this SDK does not port an
195
+ existing component's fetch calls or styling automatically.
196
+
197
+ ### Installed-app discovery and compatibility
198
+
199
+ `client.apps.list({ projectId? }, requestInit?)` wraps the existing `/api/apps`
200
+ endpoint and defaults to the client's project. This endpoint retains its current
201
+ platform permissions; application-user tokens are not guaranteed access. Hosts
202
+ can instead supply metadata they have already obtained through an authorized
203
+ flow. Extension setup does not automatically perform discovery.
204
+
205
+ ```ts
206
+ import { checkAppCompatibility, assertAppCompatibility } from "@apteva/web-sdk";
207
+
208
+ const installed = (await client.apps.list()).find(app => app.install_id === 42);
209
+ const requirements = {
210
+ app: "example",
211
+ version: { description: "1.x", accepts: (version: string) => version.startsWith("1.") },
212
+ tools: ["items_list"],
213
+ components: ["item-card"],
214
+ };
215
+ const result = checkAppCompatibility(installed, requirements); // { compatible, issues }
216
+ assertAppCompatibility(installed, requirements); // AptevaError if incompatible
217
+ ```
218
+
219
+ Version policy belongs to the app package: supply a predicate (including a semver
220
+ library if needed). These checks validate advertised app identity, version,
221
+ tools and components. They do not infer API schema versions, backend health,
222
+ permissions or unadvertised capabilities. App extensions should separately
223
+ validate any app-owned versioned API contract they require.
224
+
225
+ ### Subscription recovery
226
+
227
+ Generic subscriptions accept `signal`; already-aborted signals open no connection.
228
+ Bearer credentials use authenticated fetch streaming. Cookie clients can opt into
229
+ fetch with `transport: "fetch"`. `lastEventId`, `cursorParam`, `deduplicate`, and
230
+ `reconnectDelayMs` also select fetch streaming, even if an EventSource was supplied.
231
+
232
+ ```ts
233
+ const subscription = app.subscribe("/events", onEvent, {
234
+ signal: controller.signal,
235
+ lastEventId: savedEventId,
236
+ cursorParam: "since_id", // only if this app accepts SSE IDs here
237
+ deduplicate: true, // only if the app promises unique IDs per event
238
+ deduplicationWindow: 1000,
239
+ reconnectDelayMs: 1000,
240
+ });
241
+ ```
242
+
243
+ Fetch streams preserve SSE IDs across reconnects, send `Last-Event-ID`, and
244
+ optionally send the same ID in the app's cursor query parameter. Deduplication
245
+ is opt-in and bounded to the most recent 1000 delivered IDs by default; ID-less
246
+ updates are always delivered. It does not persist across new subscriptions.
247
+ Message-row IDs and SSE IDs are not interchangeable unless the backend says so.
248
+ Named events still require `eventTypes`. Malformed JSON is skipped; a throwing
249
+ fetch-stream event/open callback is reported and closes the subscription.
250
+
251
+ Reconnect delay defaults to 1000ms. Closing or aborting cancels the active reader
252
+ and any pending reconnect. Fetch streams stop on 204 or 403, and on 401 unless
253
+ credentials can be renewed once before a successful connection. Other failures
254
+ reconnect. Native EventSource retains the browser's own reconnect behavior.
255
+ The SDK cannot supply replay, a gap-free history/live handoff, or durable delivery
256
+ unless the app backend implements those contracts.
257
+
258
+ ### Host-owned credential renewal
259
+
260
+ Configure `refreshAccessToken: async () => tokenOrUndefined` on the client to
261
+ reuse your own authentication flow. Concurrent 401s coordinate one in-flight
262
+ refresh. `client.refreshAccessToken()` can also be called proactively; it returns
263
+ whether a new token was applied. A login/logout/token replacement during a
264
+ refresh wins over the late result. An undefined result leaves credentials intact.
265
+
266
+ A failed HTTP request still throws its original 401 and triggers `onUnauthorized`
267
+ after the renewal attempt; it is never replayed. Subsequent calls use the new
268
+ token. Requests with a caller-supplied Authorization header do not trigger
269
+ renewal. Fetch SSE can reconnect once with renewed credentials; another 401
270
+ before a successful connection terminates the subscription. Automatic renewal
271
+ failure preserves the original 401; direct `refreshAccessToken()` calls expose
272
+ hook errors. The SDK transports opaque credentials and makes no identity or
273
+ permission decisions.
274
+
83
275
  ## Agents
84
276
 
85
277
  `client.agents` wraps the core `/api/agents/*` routes — the running apteva-core child processes.
@@ -149,7 +341,10 @@ sub.close();
149
341
 
150
342
  For any other SSE endpoint, `client.subscribe(path, params, onEvent, opts?)` is the generic form `telemetry.stream` is built on.
151
343
 
152
- With an API key, `subscribe`/`stream` use authenticated fetch streaming and send the key in the `Authorization` header. Cookie-authenticated clients use native `EventSource`; in runtimes without it, pass a polyfill via `opts.EventSource`.
344
+ With an API key or access token, `subscribe`/`stream` use authenticated fetch
345
+ streaming and send the credential in the `Authorization` header. Access tokens
346
+ are never placed in query strings. Cookie-authenticated clients use native
347
+ `EventSource`; in runtimes without it, pass a polyfill via `opts.EventSource`.
153
348
 
154
349
  ## Chat
155
350
 
@@ -201,27 +396,20 @@ sub.close();
201
396
 
202
397
  Always address Channel Chat with `chat.id`. `thread_id` is informational and must not be used for message delivery. `instance_id` is a legacy response alias; new code should use `agent_id`.
203
398
 
204
- For a website user who is not an Apteva account, mint a delegated credential
205
- from your trusted backend and use that short-lived token in the browser:
399
+ For a logged-in website user who is not an Apteva platform account, initialize
400
+ the SDK with the application-user token returned by the site's authentication
401
+ flow:
206
402
 
207
403
  ```ts
208
- // Customer backend only: this client holds the private sk- key.
209
- const projects = await adminClient.projects.list();
210
- const project = projects[0]; // or select one by name in your setup UI
211
- const token = await adminClient.delegatedUsers.create({
212
- projectId: project.id,
213
- subjectType: "website_user",
214
- subjectId: authenticatedSiteUser.id,
215
- agentId: 4,
216
- allowedOrigins: ["https://customer.example"],
217
- conversationDirective: "Help this visitor choose a subscription plan.",
218
- expiresIn: 3600,
219
- });
404
+ // `login` belongs to the website/Auth integration, not @apteva/web-sdk.
405
+ const login = await websiteAuth.login(email, password);
406
+ if (!login.apteva_access_token) {
407
+ throw new Error("No Apteva access policy is configured for this client");
408
+ }
220
409
 
221
- // Return token.access_token to that authenticated website user. Browser code:
222
410
  const browserClient = new AptevaClient({
223
411
  baseURL: "https://agents.example.com",
224
- apiKey: accessToken, // uk_… — never the private sk- key
412
+ accessToken: login.apteva_access_token,
225
413
  });
226
414
  const chat = await browserClient.chat.createOrResume(4, {
227
415
  title: "Customer support",
@@ -236,15 +424,16 @@ const lastMessage = history.at(-1);
236
424
  if (lastMessage) await browserClient.chat.markSeen(chat.id, lastMessage.id);
237
425
  ```
238
426
 
239
- The browser never submits `subject_id`, `project_id`, or a directive when it
240
- creates the conversation. Those trusted values come from the delegated
241
- credential. Reusing the same subject, project, agent, and `conversationKey`
242
- atomically resumes the same conversation. Delegated SSE uses authenticated
243
- `fetch()` streaming and omits cookie credentials. A resumed conversation keeps
244
- the directive established when it was first created; delegated browser clients
245
- cannot change it.
427
+ The browser never submits `subject_id`, `project_id`, scopes, or a directive
428
+ when it creates the conversation. Trusted identity comes from the credential;
429
+ server policy selects permitted apps, actions, and agent IDs; Channel Chat
430
+ enforces its chat-specific resources. Reusing the same subject, project, agent,
431
+ and `conversationKey` atomically resumes the same conversation.
432
+
433
+ `client.delegatedUsers.create(...)` remains available for older trusted-backend
434
+ integrations, but is deprecated and is no longer the recommended website flow.
246
435
 
247
- **Rendering note:** `ChatMessage.components[]` carries the agent's `respond(components=…)` attachments. The SDK hands you the data, but rendering app-provided UI components needs a dynamic-component loader the SDK doesn't include yet — third-party UIs render text + a placeholder for now.
436
+ **Rendering note:** `ChatMessage.components[]` carries the agent's `respond(components=…)` attachments. Use `AppComponentRegistry` to resolve these references against app-owned frontend exports, then render them in your host framework. The SDK does not dynamically load server-provided UI.
248
437
 
249
438
  A complete reference chat UI (message list, composer, streaming bubbles, optimistic send) lives in [`examples/dashboard/src/components/ChatCard.tsx`](./examples/dashboard/src/components/ChatCard.tsx).
250
439
 
@@ -284,7 +473,9 @@ The same code also works fine when hosted externally (Vercel, etc.) — `pickBas
284
473
 
285
474
  ## SSE transports
286
475
 
287
- Prefer `client.subscribe()` and the typed stream helpers. They select authenticated fetch streaming for API keys and credentialed native `EventSource` for cookie sessions.
476
+ Prefer `client.subscribe()` and the typed stream helpers. They select
477
+ authenticated fetch streaming for API keys and access tokens, and credentialed
478
+ native `EventSource` for cookie sessions. Access tokens never enter the URL.
288
479
 
289
480
  `sseURL()` remains available for endpoints that explicitly accept an API key in the query string, or for external clients that must construct their own `EventSource`:
290
481
 
package/dist/apps.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import type { AppComponentSpec } from "./components.js";
2
+ /** Relevant fields of the existing platform /api/apps response. */
3
+ export interface InstalledApp {
4
+ install_id: number;
5
+ name: string;
6
+ version: string;
7
+ project_id: string;
8
+ status: string;
9
+ display_name?: string;
10
+ source?: string;
11
+ ui_components?: AppComponentSpec[];
12
+ surfaces?: {
13
+ mcp_tool_names?: string[];
14
+ http_routes?: string[];
15
+ };
16
+ }
17
+ export interface AppRequirements {
18
+ app: string;
19
+ /** App packages choose their version policy; no implied wire/API version. */
20
+ version?: {
21
+ description: string;
22
+ accepts(version: string): boolean;
23
+ };
24
+ tools?: readonly string[];
25
+ components?: readonly string[];
26
+ }
27
+ export interface AppCompatibility {
28
+ compatible: boolean;
29
+ issues: string[];
30
+ }
31
+ /** Checks advertised metadata only. This never grants access to an app. */
32
+ export declare function checkAppCompatibility(installed: InstalledApp | undefined, requirements: AppRequirements): AppCompatibility;
33
+ export declare function assertAppCompatibility(installed: InstalledApp | undefined, requirements: AppRequirements): void;
34
+ //# sourceMappingURL=apps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACnC,QAAQ,CAAC,EAAE;QACT,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,OAAO,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACrE,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,2EAA2E;AAC3E,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,YAAY,GAAG,SAAS,EACnC,YAAY,EAAE,eAAe,GAC5B,gBAAgB,CAiBlB;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,YAAY,GAAG,SAAS,EACnC,YAAY,EAAE,eAAe,GAC5B,IAAI,CAGN"}
package/dist/apps.js ADDED
@@ -0,0 +1,30 @@
1
+ import { AptevaError } from "./errors.js";
2
+ /** Checks advertised metadata only. This never grants access to an app. */
3
+ export function checkAppCompatibility(installed, requirements) {
4
+ const issues = [];
5
+ if (!installed) {
6
+ issues.push(`app ${requirements.app} is not installed`);
7
+ }
8
+ else {
9
+ if (installed.name !== requirements.app)
10
+ issues.push(`expected app ${requirements.app}, got ${installed.name}`);
11
+ if (requirements.version && !requirements.version.accepts(installed.version)) {
12
+ issues.push(`version ${installed.version} does not satisfy ${requirements.version.description}`);
13
+ }
14
+ for (const tool of requirements.tools ?? []) {
15
+ if (!installed.surfaces?.mcp_tool_names?.includes(tool))
16
+ issues.push(`missing tool: ${tool}`);
17
+ }
18
+ for (const name of requirements.components ?? []) {
19
+ if (!installed.ui_components?.some((component) => component.name === name))
20
+ issues.push(`missing component: ${name}`);
21
+ }
22
+ }
23
+ return { compatible: issues.length === 0, issues };
24
+ }
25
+ export function assertAppCompatibility(installed, requirements) {
26
+ const result = checkAppCompatibility(installed, requirements);
27
+ if (!result.compatible)
28
+ throw new AptevaError(0, `incompatible app: ${result.issues.join("; ")}`);
29
+ }
30
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgC1C,2EAA2E;AAC3E,MAAM,UAAU,qBAAqB,CACnC,SAAmC,EACnC,YAA6B;IAE7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC,GAAG,mBAAmB,CAAC,CAAC;IAC1D,CAAC;SAAM,CAAC;QACN,IAAI,SAAS,CAAC,IAAI,KAAK,YAAY,CAAC,GAAG;YAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,YAAY,CAAC,GAAG,SAAS,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAChH,IAAI,YAAY,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7E,MAAM,CAAC,IAAI,CAAC,WAAW,SAAS,CAAC,OAAO,qBAAqB,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QAChG,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YACjD,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;QACxH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,SAAmC,EACnC,YAA6B;IAE7B,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,UAAU;QAAE,MAAM,IAAI,WAAW,CAAC,CAAC,EAAE,qBAAqB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACpG,CAAC"}
package/dist/client.d.ts CHANGED
@@ -1,15 +1,26 @@
1
- import type { Agent, AgentConfig, AgentCoreEvent, AgentCreateInput, AgentCreateResult, AgentDeleteResult, AgentPauseResult, AgentRestartResult, AgentStatus, AgentSystemMCPResult, AgentUpdateInput, AptevaClientOptions, AuthStatus, ChannelInfo, Chat, CreateChatOptions, CreateOrResumeChatOptions, ChatCreateResult, CreateDelegatedUserInput, DelegatedUserToken, ChatHistoryMessage, ChatMessage, ChatMessagesQuery, ChatSendInput, ChatSendOptions, ChatStreamOptions, MCPCallResponse, Project, StreamHandle, SubscribeOptions, TelemetryEvent, TelemetryPeriod, TelemetryQuery, TelemetryStats, Thread, TimelineBucket, UpdateChatOptions, User } from "./types.js";
1
+ import type { AppExtension, AppScope } from "./extensions.js";
2
+ import type { InstalledApp } from "./apps.js";
3
+ import type { Agent, AgentConfig, AgentCoreEvent, AgentCreateInput, AgentCreateResult, AgentDeleteResult, AgentPauseResult, AgentRestartResult, AgentStatus, AgentSystemMCPResult, AgentUpdateInput, AptevaClientOptions, AuthStatus, ChannelInfo, Chat, CreateChatOptions, CreateOrResumeChatOptions, ChatCreateResult, CreateDelegatedUserInput, DelegatedUserToken, ChatHistoryMessage, ChatMessage, ChatMessagesQuery, ChatSendInput, ChatSendOptions, ChatStreamOptions, MCPCallResponse, Project, StreamHandle, SubscribeOptions, SSEEventMetadata, TelemetryEvent, TelemetryPeriod, TelemetryQuery, TelemetryStats, Thread, TimelineBucket, UpdateChatOptions, User } from "./types.js";
2
4
  export declare class AptevaClient {
3
5
  private readonly baseURL;
4
6
  private apiKey?;
7
+ private accessToken?;
5
8
  private readonly projectId?;
6
9
  private readonly fetchImpl;
7
10
  private readonly onUnauthorized?;
8
11
  private readonly timeoutMs;
12
+ private readonly refreshTokenHook?;
13
+ private credentialRevision;
14
+ private pendingTokenRefresh?;
9
15
  private readonly pendingChatResolutions;
10
16
  constructor(opts: AptevaClientOptions);
11
17
  setApiKey(key: string | undefined): void;
12
18
  getApiKey(): string | undefined;
19
+ setAccessToken(token: string | undefined): void;
20
+ getAccessToken(): string | undefined;
21
+ /** Refresh once for concurrent callers. Undefined leaves credentials unchanged. */
22
+ refreshAccessToken(): Promise<boolean>;
23
+ private renewAfterUnauthorized;
13
24
  readonly auth: {
14
25
  register: (email: string, password: string, name?: string) => Promise<{
15
26
  user: User;
@@ -34,6 +45,7 @@ export declare class AptevaClient {
34
45
  list: () => Promise<Project[]>;
35
46
  get: (id: string) => Promise<Project>;
36
47
  };
48
+ /** @deprecated Prefer AptevaClient({ accessToken }). */
37
49
  readonly delegatedUsers: {
38
50
  create: (input: CreateDelegatedUserInput) => Promise<DelegatedUserToken>;
39
51
  };
@@ -57,7 +69,7 @@ export declare class AptevaClient {
57
69
  togglePause: (id: number) => Promise<AgentPauseResult>;
58
70
  event: <R = unknown>(id: number, body: Record<string, unknown>) => Promise<R>;
59
71
  control: <R = unknown>(id: number, body: Record<string, unknown>) => Promise<R>;
60
- events: <E = AgentCoreEvent>(id: number, onEvent: (event: E) => void, opts?: SubscribeOptions) => StreamHandle;
72
+ events: <E = AgentCoreEvent>(id: number, onEvent: (event: E, metadata: SSEEventMetadata) => void, opts?: SubscribeOptions) => StreamHandle;
61
73
  };
62
74
  readonly telemetry: {
63
75
  query: (q: TelemetryQuery) => Promise<TelemetryEvent[]>;
@@ -82,29 +94,40 @@ export declare class AptevaClient {
82
94
  last_seen_id: number;
83
95
  }>;
84
96
  };
85
- app<T = unknown>(name: string): AppHandle<T>;
86
- callTool<R>(appName: string, toolName: string, args: Record<string, unknown>): Promise<R>;
97
+ app<T = unknown>(name: string, scope?: AppScope): AppHandle<T>;
98
+ /** Create an extension instance. Retain it in the host; use() does not cache. */
99
+ use<T>(extension: AppExtension<T>, scope?: AppScope): T;
100
+ readonly apps: {
101
+ /** Requires the platform's existing app-list permission. No auth bypass. */
102
+ list: (scope?: Pick<AppScope, "projectId">, init?: RequestInit) => Promise<InstalledApp[]>;
103
+ };
104
+ callTool<R>(appName: string, toolName: string, args: Record<string, unknown>, init?: RequestInit): Promise<R>;
87
105
  get<R>(path: string, init?: RequestInit): Promise<R>;
88
106
  post<R>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
89
107
  put<R>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
90
108
  patch<R>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
91
109
  del<R>(path: string, init?: RequestInit): Promise<R>;
92
110
  sseURL(path: string, params?: Record<string, string | number | undefined>): string;
93
- subscribe<E>(path: string, params: Record<string, string | number | undefined> | undefined, onEvent: (event: E) => void, opts?: SubscribeOptions): StreamHandle;
111
+ subscribe<E>(path: string, params: Record<string, string | number | undefined> | undefined, onEvent: (event: E, metadata: SSEEventMetadata) => void, opts?: SubscribeOptions): StreamHandle;
94
112
  private subscribeWithFetch;
95
113
  private bindAbortSignal;
96
114
  private appPath;
115
+ private bearerToken;
116
+ private isAccessTokenCredential;
97
117
  private request;
98
118
  }
99
119
  export declare function unwrapMCP<R>(env: MCPCallResponse<unknown>): R;
100
120
  export interface AppHandle<TDefault = unknown> {
101
121
  readonly name: string;
102
- get<R = TDefault>(path: string): Promise<R>;
103
- post<R = TDefault>(path: string, body?: unknown): Promise<R>;
104
- put<R = TDefault>(path: string, body?: unknown): Promise<R>;
105
- patch<R = TDefault>(path: string, body?: unknown): Promise<R>;
106
- del<R = TDefault>(path: string): Promise<R>;
107
- tool<R = TDefault>(name: string, args?: Record<string, unknown>): Promise<R>;
122
+ readonly projectId?: string;
123
+ readonly installId?: number;
124
+ get<R = TDefault>(path: string, init?: RequestInit): Promise<R>;
125
+ post<R = TDefault>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
126
+ put<R = TDefault>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
127
+ patch<R = TDefault>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
128
+ del<R = TDefault>(path: string, init?: RequestInit): Promise<R>;
129
+ tool<R = TDefault>(name: string, args?: Record<string, unknown>, init?: RequestInit): Promise<R>;
130
+ subscribe<E>(path: string, onEvent: (event: E, metadata: SSEEventMetadata) => void, opts?: SubscribeOptions): StreamHandle;
108
131
  mcpURL(queryParams?: Record<string, string>): string;
109
132
  }
110
133
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,yBAAyB,EACzB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,iBAAiB,EAEjB,eAAe,EACf,OAAO,EAEP,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,IAAI,EACL,MAAM,YAAY,CAAC;AAIpB,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAa;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAoC;gBAE/D,IAAI,EAAE,mBAAmB;IAWrC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAIxC,SAAS,IAAI,MAAM,GAAG,SAAS;IAO/B,QAAQ,CAAC,IAAI;0BACO,MAAM,YAAY,MAAM,SAAS,MAAM;kBACrC,IAAI;;uBAET,MAAM,YAAY,MAAM;;;;kCASb,MAAM,QAAQ,MAAM;;gBAIvB,MAAM;kBAAQ,MAAM;wBAAc,MAAM;;0BAI7C,MAAM;gBACN,MAAM;iBAAO,MAAM;;wBAErB,MAAM;MACtB;IAEF,QAAQ,CAAC,QAAQ;;kBAEL,MAAM;MAChB;IAKF,QAAQ,CAAC,cAAc;wBACL,wBAAwB;MAYxC;IAKF,QAAQ,CAAC,MAAM;;wBAGG,gBAAgB;kBAGtB,MAAM;qBAEH,MAAM,SAAS,gBAAgB;qBAG/B,MAAM,QAAQ,MAAM;qBAGpB,MAAM;qBAGN,MAAM;sBAEL,MAAM;uBAEL,MAAM;0BAEH,MAAM;iBAKf,CAAC,oBAAoB,MAAM;uBAGrB,CAAC,oBAAoB,MAAM,UAAU,WAAW;wBAG/C,MAAM,QAAQ,UAAU,GAAG,iBAAiB,UAAU,OAAO;oBAUjE,MAAM;mBAGP,MAAM;sBAGH,MAAM;0BAOF,MAAM;gBAKhB,CAAC,gBAAgB,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;kBAGpD,CAAC,gBAAgB,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBAGvD,CAAC,uBACJ,MAAM,WACD,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,SACpB,gBAAgB,KACtB,YAAY;MAEf;IAIF,QAAQ,CAAC,SAAS;mBAEL,cAAc;4BAWL,MAAM,WAAU,eAAe;yBAMlC,MAAM,WAAU,eAAe;0BAUrC,MAAM,WACN,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,SACjC,gBAAgB,KACtB,YAAY;MAgBf;IAMF,QAAQ,CAAC,IAAI;wBAEK,MAAM;sBAKR,MAAM;0BAOF,MAAM,YAAY,MAAM,GAAG,iBAAiB;kCAapC,MAAM,WAAW,yBAAyB;yBASnD,MAAM,WAAW,iBAAiB;+BAa5B,MAAM,YAAY,MAAM,GAAG,iBAAiB;4BAiBlC,MAAM,UAAS,iBAAiB;2BAQhD,MAAM,UAAS,iBAAiB;2BAQhC,MAAM,SAAS,aAAa;;uBAkBnC,MAAM,kBACE,MAAM,GAAG,aAAa,YAC7B,eAAe;yBA2BT,MAAM,QAAQ,iBAAiB,KAAG,YAAY;2BAmB5C,MAAM,aAAa,MAAM;0BAChB,MAAM;;MAIlC;IAOF,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IA4BtC,QAAQ,CAAC,CAAC,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC;IAeb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGpD,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGrE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGpE,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGtE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAQpD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM;IAwBlF,SAAS,CAAC,CAAC,EACT,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,EAC/D,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAC3B,IAAI,CAAC,EAAE,gBAAgB,GACtB,YAAY;IAkDf,OAAO,CAAC,kBAAkB;IA4H1B,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,OAAO;YASD,OAAO;CAyDtB;AAgBD,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAgB7D;AAED,MAAM,WAAW,SAAS,CAAC,QAAQ,GAAG,OAAO;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7D,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D,KAAK,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;CACtD"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,yBAAyB,EACzB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,iBAAiB,EAEjB,eAAe,EACf,OAAO,EAEP,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,IAAI,EACL,MAAM,YAAY,CAAC;AAIpB,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAa;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAoC;IACtE,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,mBAAmB,CAAC,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAoC;gBAE/D,IAAI,EAAE,mBAAmB;IAarC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKxC,SAAS,IAAI,MAAM,GAAG,SAAS;IAO/B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAK/C,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,mFAAmF;IAC7E,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;YAmB9B,sBAAsB;IAcpC,QAAQ,CAAC,IAAI;0BACO,MAAM,YAAY,MAAM,SAAS,MAAM;kBACrC,IAAI;;uBAET,MAAM,YAAY,MAAM;;;;kCASb,MAAM,QAAQ,MAAM;;gBAIvB,MAAM;kBAAQ,MAAM;wBAAc,MAAM;;0BAI7C,MAAM;gBACN,MAAM;iBAAO,MAAM;;wBAErB,MAAM;MACtB;IAEF,QAAQ,CAAC,QAAQ;;kBAEL,MAAM;MAChB;IAKF,wDAAwD;IACxD,QAAQ,CAAC,cAAc;wBACL,wBAAwB;MAYxC;IAKF,QAAQ,CAAC,MAAM;;wBAGG,gBAAgB;kBAGtB,MAAM;qBAEH,MAAM,SAAS,gBAAgB;qBAG/B,MAAM,QAAQ,MAAM;qBAGpB,MAAM;qBAGN,MAAM;sBAEL,MAAM;uBAEL,MAAM;0BAEH,MAAM;iBAKf,CAAC,oBAAoB,MAAM;uBAGrB,CAAC,oBAAoB,MAAM,UAAU,WAAW;wBAG/C,MAAM,QAAQ,UAAU,GAAG,iBAAiB,UAAU,OAAO;oBAUjE,MAAM;mBAGP,MAAM;sBAGH,MAAM;0BAOF,MAAM;gBAKhB,CAAC,gBAAgB,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;kBAGpD,CAAC,gBAAgB,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBAGvD,CAAC,uBACJ,MAAM,WACD,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,KAAK,IAAI,SAChD,gBAAgB,KACtB,YAAY;MAEf;IAIF,QAAQ,CAAC,SAAS;mBAEL,cAAc;4BAWL,MAAM,WAAU,eAAe;yBAMlC,MAAM,WAAU,eAAe;0BAUrC,MAAM,WACN,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,SACjC,gBAAgB,KACtB,YAAY;MAgBf;IAMF,QAAQ,CAAC,IAAI;wBAEK,MAAM;sBAKR,MAAM;0BAOF,MAAM,YAAY,MAAM,GAAG,iBAAiB;kCAapC,MAAM,WAAW,yBAAyB;yBASnD,MAAM,WAAW,iBAAiB;+BAa5B,MAAM,YAAY,MAAM,GAAG,iBAAiB;4BAiBlC,MAAM,UAAS,iBAAiB;2BAQhD,MAAM,UAAS,iBAAiB;2BAQhC,MAAM,SAAS,aAAa;;uBAkBnC,MAAM,kBACE,MAAM,GAAG,aAAa,YAC7B,eAAe;yBA2BT,MAAM,QAAQ,iBAAiB,KAAG,YAAY;2BAmB5C,MAAM,aAAa,MAAM;0BAChB,MAAM;;MAIlC;IAOF,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,QAAa,GAAG,SAAS,CAAC,CAAC,CAAC;IAoDlE,iFAAiF;IACjF,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,CAAC;IAIvD,QAAQ,CAAC,IAAI;QACX,4EAA4E;uBAC9D,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAc,WAAW;MAKlE;IAII,QAAQ,CAAC,CAAC,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,CAAC,CAAC;IAeb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGpD,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGrE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGpE,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAGtE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAQpD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM;IAwBlF,SAAS,CAAC,CAAC,EACT,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,EAC/D,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,KAAK,IAAI,EACvD,IAAI,CAAC,EAAE,gBAAgB,GACtB,YAAY;IA2Ef,OAAO,CAAC,kBAAkB;IAmJ1B,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,uBAAuB;YAIjB,OAAO;CA4DtB;AAgBD,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAgB7D;AAED,MAAM,WAAW,SAAS,CAAC,QAAQ,GAAG,OAAO;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjF,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAChF,KAAK,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClF,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjG,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,KAAK,IAAI,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,YAAY,CAAC;IAC3H,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;CACtD"}