@vornrun/connector-sdk 0.7.0-beta.16 → 0.7.0-beta.18

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/README.md CHANGED
@@ -202,6 +202,25 @@ Two rules make a pull trigger reliable, and the SDK enforces both:
202
202
  it. Use `>=` when filtering on `since` and sort ascending; returning a few
203
203
  items again is free, because the SDK drops anything already delivered.
204
204
 
205
+ ## Act through a signed-in window
206
+
207
+ A service with no API to key can still be reached as the person using it. Declare the `browser` rung with the page to sign in on, the origins the connector may act on, and a check that answers 2xx only while someone is signed in:
208
+
209
+ ```ts
210
+ auth: {
211
+ rung: 'browser',
212
+ browser: {
213
+ signInUrl: 'https://example.com/login',
214
+ origins: ['https://example.com', 'https://*.example.com'],
215
+ check: { url: 'https://example.com/api/me', identity: ['name', 'handle'] }
216
+ }
217
+ }
218
+ ```
219
+
220
+ Vorn opens a window on a browser profile that belongs to one connection, and the person signs in there. The connector's code then gets `ctx.session.fetch` beside `ctx.fetch`. A call through `ctx.session.fetch` runs inside that signed-in window as a same-origin request, so the service sees its own page asking and no cookie reaches the connector. Calls outside `origins` are refused. `ctx.fetch` stays a plain fetch for public reads, such as a feed, which work before anyone signs in. A `browser` connector's declared `request` actions go through the window.
221
+
222
+ `--mock` serves signed-in calls from the same routes as every other call. A `--live` run from a terminal has no window, so it skips them.
223
+
205
224
  ## Dedupe strategies
206
225
 
207
226
  `dedupe` tells the SDK how to recognize new items, and it then owns the cursor
@@ -73,6 +73,8 @@ interface PollContext {
73
73
  now(): string;
74
74
  /** Fetch with the SDK's retry and backoff applied. A poll is always a read. */
75
75
  fetch: typeof fetch;
76
+ /** Present only when the connector signs in through a Vorn window. */
77
+ session?: SessionContext;
76
78
  }
77
79
  interface PollOutcome {
78
80
  items: ConnectorItem[];
@@ -114,6 +116,8 @@ interface FetchContext {
114
116
  now(): string;
115
117
  /** Fetch with the SDK's retry and backoff applied. A fetch is always a read. */
116
118
  fetch: typeof fetch;
119
+ /** Present only when the connector signs in through a Vorn window. */
120
+ session?: SessionContext;
117
121
  }
118
122
  /**
119
123
  * What an upstream state should become when an item is imported as a task.
@@ -227,6 +231,8 @@ interface ActionContext {
227
231
  * same resilience a declared request does, and tests can replace it.
228
232
  */
229
233
  fetch: typeof fetch;
234
+ /** Present only when the connector signs in through a Vorn window. */
235
+ session?: SessionContext;
230
236
  }
231
237
  /**
232
238
  * One step of reshaping a response.
@@ -369,9 +375,27 @@ interface PreflightResult {
369
375
  * `none` needs nothing — installing it is the whole setup. `cli` borrows a
370
376
  * login that already works on the machine, which is the rung to prefer
371
377
  * whenever a mature tool is signed in anyway. `key` asks for a credential.
378
+ * `browser` signs in through a Vorn window for a service with no API to key.
372
379
  * `oauth` is declared but not yet carried by the host.
373
380
  */
374
- type AuthRung = 'none' | 'cli' | 'key' | 'oauth';
381
+ type AuthRung = 'none' | 'cli' | 'key' | 'browser' | 'oauth';
382
+ /** How a `browser` connector signs in, and the only origins its calls may reach. */
383
+ interface BrowserSignIn {
384
+ /** The page the Vorn window opens for signing in. */
385
+ signInUrl: string;
386
+ /** `https://host` or `https://*.host`; the sign-in page and the check must sit inside them. */
387
+ origins: string[];
388
+ /** Answers 2xx only when signed in; `identity` names the fields of its JSON that say who. */
389
+ check: {
390
+ url: string;
391
+ identity: string[];
392
+ };
393
+ }
394
+ /** The signed-in window, offered to a `browser` connector's code. */
395
+ interface SessionContext {
396
+ /** Runs the request inside the connection's signed-in window; cookies never reach the connector. */
397
+ fetch: typeof fetch;
398
+ }
375
399
  /**
376
400
  * What a connector needs before it can talk to anything.
377
401
  *
@@ -408,6 +432,8 @@ interface ConnectorAuth {
408
432
  };
409
433
  /** Config field keys holding the credential. Required for `key`. */
410
434
  keys?: string[];
435
+ /** Required for `browser`. */
436
+ browser?: BrowserSignIn;
411
437
  }
412
438
  /** What an options set is given to work out its choices. */
413
439
  interface OptionsContext {
@@ -415,6 +441,8 @@ interface OptionsContext {
415
441
  now(): string;
416
442
  /** Fetch with the SDK's retry and backoff applied. Listing choices is a read. */
417
443
  fetch: typeof fetch;
444
+ /** Present only when the connector signs in through a Vorn window. */
445
+ session?: SessionContext;
418
446
  }
419
447
  /**
420
448
  * Answers the question "what can this field be?" against a live connection.
@@ -725,6 +753,10 @@ interface RunPollOptions {
725
753
  now?: () => string;
726
754
  /** Replaced by the harness and by tests; defaults to the global fetch. */
727
755
  fetchImpl?: typeof fetch;
756
+ /** Replaced by the harness and by tests; defaults to the signed-in window Vorn serves. */
757
+ sessionFetchImpl?: typeof fetch;
758
+ /** The key Vorn gave this tool call, carried on each request through the window. */
759
+ sessionCall?: string;
728
760
  retry?: RetryPolicy;
729
761
  /** Replaced in tests so backoff costs no real time. */
730
762
  sleep?: (ms: number) => Promise<void>;
@@ -747,6 +779,10 @@ interface RunActionOptions {
747
779
  now?: () => string;
748
780
  /** Replaced by the harness and by tests; defaults to the global fetch. */
749
781
  fetchImpl?: typeof fetch;
782
+ /** Replaced by the harness and by tests; defaults to the signed-in window Vorn serves. */
783
+ sessionFetchImpl?: typeof fetch;
784
+ /** The key Vorn gave this tool call, carried on each request through the window. */
785
+ sessionCall?: string;
750
786
  retry?: RetryPolicy;
751
787
  /** Replaced in tests so backoff costs no real time. */
752
788
  sleep?: (ms: number) => Promise<void>;
@@ -902,6 +938,8 @@ interface HarnessOptions {
902
938
  now?: () => string;
903
939
  /** Answer the connector's calls from the test rather than the network. */
904
940
  fetchImpl?: typeof fetch;
941
+ /** Answer its signed-in calls; defaults to `fetchImpl`, so one stub serves both. */
942
+ sessionFetchImpl?: typeof fetch;
905
943
  /** Fake clock for backoff, so a retry test costs no real time. */
906
944
  sleep?: (ms: number) => Promise<void>;
907
945
  }
@@ -1096,4 +1134,4 @@ declare function runConformance(connector: Connector, options?: CheckOptions): P
1096
1134
  /** Render findings for a terminal. Returns an empty string when all clear. */
1097
1135
  declare function formatFindings(findings: CheckFinding[]): string;
1098
1136
 
1099
- export { MAX_PACK_BYTES as $, type ActionRequest as A, type BundleRequest as B, type CheckFinding as C, type ConnectorIcon as D, type ExtensionPermission as E, type ConnectorKind as F, type ConnectorManifest as G, type ConnectorVerification as H, type DedupeStrategy as I, type DefaultWorkflow as J, type ExtensionAgent as K, type ExtensionContext as L, type ExtensionContributions as M, type NormalizedItem as N, type ExtensionPlatform as O, type PollContext as P, type ExtensionUsage as Q, type ExtensionUsageWindow as R, type FetchContext as S, type TriggerDefinition as T, type FooterContribution as U, type FooterItem as V, type HarnessOptions as W, type LinkContext as X, type LinkHandled as Y, type LinkHandlerContribution as Z, MANIFEST_TOOL as _, type BundleOutput as a, MAX_POLL_PAGES as a0, type ManifestContributions as a1, type MockCall as a2, type MockHostAnswers as a3, type MockHostRun as a4, type MockRoute as a5, MockRouteMissError as a6, type MockRun as a7, OPTIONS_TOOL as a8, type OptionsContext as a9, pollToolName as aA, readNearestPackageJson as aB, resilientFetch as aC, retryAfterMs as aD, runAction as aE, runConformance as aF, runOptions as aG, runPoll as aH, withMockHttp as aI, type OptionsLoader as aa, PREFLIGHT_TOOL as ab, type PaginationStrategy as ac, type PaneContribution as ad, type PollPage as ae, type PreflightResult as af, type ResilientFetchOptions as ag, type RetryPolicy as ah, type RunActionOptions as ai, type RunPollOptions as aj, type StatusSuggestion as ak, backoffMs as al, bundleDependencyFindings as am, bundledRequireFindings as an, checkConnector as ao, connectionSetup as ap, connectorManifest as aq, createConnectorHarness as ar, drainPoll as as, esbuildBundle as at, escapedMockHttp as au, footerToolName as av, formatFindings as aw, handlerToolName as ax, lifecycleScriptFindings as ay, mockExtensionHost as az, type ExtensionHostMethod as b, type ConnectorDefinition as c, type Connector as d, type ExtensionDefinition as e, type ConnectorConfig as f, type ExtensionHost as g, type PollOutcome as h, type ConnectorItem as i, type PostReceiveOp as j, type ActionContext as k, type ActionDefinition as l, type ActionInputField as m, type ActionInputOption as n, type ActionInputType as o, type ActionOutputField as p, type ActivationPredicate as q, type AuthRung as r, CHECK_OWNERS as s, type CheckCode as t, type CheckOptions as u, type ConformanceRun as v, type ConnectionSetup as w, type ConnectorAuth as x, type ConnectorConfigField as y, type ConnectorHarness as z };
1137
+ export { MANIFEST_TOOL as $, type ActionRequest as A, type BundleRequest as B, type CheckFinding as C, type ConnectorHarness as D, type ExtensionPermission as E, type ConnectorIcon as F, type ConnectorKind as G, type ConnectorManifest as H, type ConnectorVerification as I, type DedupeStrategy as J, type DefaultWorkflow as K, type ExtensionAgent as L, type ExtensionContext as M, type NormalizedItem as N, type ExtensionContributions as O, type PollContext as P, type ExtensionPlatform as Q, type ExtensionUsage as R, type ExtensionUsageWindow as S, type TriggerDefinition as T, type FetchContext as U, type FooterContribution as V, type FooterItem as W, type HarnessOptions as X, type LinkContext as Y, type LinkHandled as Z, type LinkHandlerContribution as _, type BundleOutput as a, MAX_PACK_BYTES as a0, MAX_POLL_PAGES as a1, type ManifestContributions as a2, type MockCall as a3, type MockHostAnswers as a4, type MockHostRun as a5, type MockRoute as a6, MockRouteMissError as a7, type MockRun as a8, OPTIONS_TOOL as a9, lifecycleScriptFindings as aA, mockExtensionHost as aB, pollToolName as aC, readNearestPackageJson as aD, resilientFetch as aE, retryAfterMs as aF, runAction as aG, runConformance as aH, runOptions as aI, runPoll as aJ, withMockHttp as aK, type OptionsContext as aa, type OptionsLoader as ab, PREFLIGHT_TOOL as ac, type PaginationStrategy as ad, type PaneContribution as ae, type PollPage as af, type PreflightResult as ag, type ResilientFetchOptions as ah, type RetryPolicy as ai, type RunActionOptions as aj, type RunPollOptions as ak, type SessionContext as al, type StatusSuggestion as am, backoffMs as an, bundleDependencyFindings as ao, bundledRequireFindings as ap, checkConnector as aq, connectionSetup as ar, connectorManifest as as, createConnectorHarness as at, drainPoll as au, esbuildBundle as av, escapedMockHttp as aw, footerToolName as ax, formatFindings as ay, handlerToolName as az, type ExtensionHostMethod as b, type ConnectorDefinition as c, type Connector as d, type ExtensionDefinition as e, type ConnectorConfig as f, type ExtensionHost as g, type PollOutcome as h, type ConnectorItem as i, type PostReceiveOp as j, type ActionContext as k, type ActionDefinition as l, type ActionInputField as m, type ActionInputOption as n, type ActionInputType as o, type ActionOutputField as p, type ActivationPredicate as q, type AuthRung as r, type BrowserSignIn as s, CHECK_OWNERS as t, type CheckCode as u, type CheckOptions as v, type ConformanceRun as w, type ConnectionSetup as x, type ConnectorAuth as y, type ConnectorConfigField as z };
@@ -1,9 +1,134 @@
1
+ // src/loopback.ts
2
+ var LOOPBACK_HOSTS = ["127.0.0.1", "localhost", "[::1]"];
3
+ function loopbackEndpoint(env, names, fail = (message) => new Error(message)) {
4
+ const url = env[names.urlVar]?.trim();
5
+ const token = env[names.tokenVar]?.trim();
6
+ if (!url || !token) throw fail(names.missing);
7
+ let parsed;
8
+ try {
9
+ parsed = new URL(url);
10
+ } catch {
11
+ throw fail(`${names.urlVar} is ${JSON.stringify(url)}, which is not a URL`);
12
+ }
13
+ if (parsed.protocol !== "http:" || !LOOPBACK_HOSTS.includes(parsed.hostname)) {
14
+ throw fail(
15
+ `${names.urlVar} is ${JSON.stringify(url)}; ${names.served}, over http on ${LOOPBACK_HOSTS.join(", ")}`
16
+ );
17
+ }
18
+ return { url: url.replace(/\/$/, ""), token };
19
+ }
20
+
21
+ // src/session.ts
22
+ var BROWSER_HOST_ENV = "VORN_BROWSER_HOST";
23
+ var BROWSER_TOKEN_ENV = "VORN_BROWSER_TOKEN";
24
+ var SESSION_CALL_META = "vorn/sessionCall";
25
+ var SESSION_CALL_HEADER = "x-vorn-session-call";
26
+ var SessionUnavailableError = class extends Error {
27
+ /** Asking again cannot bring the window back, so the SDK's retries let this through at once. */
28
+ retryable = false;
29
+ constructor(message) {
30
+ super(message);
31
+ this.name = "SessionUnavailableError";
32
+ }
33
+ };
34
+ var SessionRefusedError = class extends Error {
35
+ retryable = false;
36
+ constructor(message) {
37
+ super(message);
38
+ this.name = "SessionRefusedError";
39
+ }
40
+ };
41
+ var SESSION_TIMEOUT_MS = 45e3;
42
+ var NULL_BODY_STATUSES = /* @__PURE__ */ new Set([204, 205, 304]);
43
+ function readReply(text) {
44
+ let parsed;
45
+ try {
46
+ parsed = JSON.parse(text);
47
+ } catch {
48
+ throw new Error("The signed-in window answered with a body that is not JSON");
49
+ }
50
+ const reply2 = parsed;
51
+ if (!parsed || typeof parsed !== "object" || typeof reply2.status !== "number") {
52
+ throw new Error("The signed-in window answered without a status");
53
+ }
54
+ return reply2;
55
+ }
56
+ var refusal = (text) => text.trim() || void 0;
57
+ function createSessionFetch(options = {}) {
58
+ const env = options.env ?? process.env;
59
+ const call = options.fetchImpl ?? fetch;
60
+ return (async (input, init) => {
61
+ const { url, token } = loopbackEndpoint(
62
+ env,
63
+ {
64
+ urlVar: BROWSER_HOST_ENV,
65
+ tokenVar: BROWSER_TOKEN_ENV,
66
+ missing: `This connector acts through a signed-in Vorn window; run it from Vorn, which sets ${BROWSER_HOST_ENV}`,
67
+ served: "the endpoint is served on this machine"
68
+ },
69
+ (message) => new SessionUnavailableError(message)
70
+ );
71
+ const request = new Request(input, init);
72
+ const body = request.body ? await request.text() : void 0;
73
+ const answer = await call(`${url}/fetch`, {
74
+ method: "POST",
75
+ headers: {
76
+ authorization: `Bearer ${token}`,
77
+ "content-type": "application/json",
78
+ ...options.call && { [SESSION_CALL_HEADER]: options.call }
79
+ },
80
+ body: JSON.stringify({
81
+ url: request.url,
82
+ method: request.method,
83
+ headers: Object.fromEntries(request.headers),
84
+ ...body !== void 0 && { body }
85
+ }),
86
+ signal: AbortSignal.any([request.signal, AbortSignal.timeout(SESSION_TIMEOUT_MS)])
87
+ });
88
+ const text = await answer.text();
89
+ if (answer.status === 503) {
90
+ throw new SessionUnavailableError(
91
+ refusal(text) ?? "Vorn could not reach the signed-in window"
92
+ );
93
+ }
94
+ if (!answer.ok) {
95
+ throw new SessionRefusedError(
96
+ refusal(text) ?? `The signed-in window refused the call with HTTP ${answer.status}`
97
+ );
98
+ }
99
+ const reply2 = readReply(text);
100
+ return new Response(NULL_BODY_STATUSES.has(reply2.status) ? null : reply2.body ?? "", {
101
+ status: reply2.status,
102
+ ...reply2.headers && { headers: reply2.headers }
103
+ });
104
+ });
105
+ }
106
+
107
+ // src/origins.ts
108
+ var ORIGIN_PATTERN = /^https:\/\/(\*\.)?[a-z0-9-]+(\.[a-z0-9-]+)+$/i;
109
+ function withinOrigins(origins, url) {
110
+ let parsed;
111
+ try {
112
+ parsed = new URL(url);
113
+ } catch {
114
+ return false;
115
+ }
116
+ if (parsed.protocol !== "https:" || parsed.port !== "") return false;
117
+ const target = parsed.hostname.toLowerCase();
118
+ return origins.some((origin) => {
119
+ if (!ORIGIN_PATTERN.test(origin)) return false;
120
+ const wildcard = origin.startsWith("https://*.");
121
+ const host = origin.slice(wildcard ? "https://*.".length : "https://".length).toLowerCase();
122
+ return wildcard ? target.endsWith(`.${host}`) : target === host;
123
+ });
124
+ }
125
+
1
126
  // src/define.ts
2
127
  var KEY_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
3
128
  var PATH_DATA_PATTERN = /^[MmZzLlHhVvCcSsQqTtAa0-9\s,.\-+eE]+$/;
4
129
  var VIEW_BOX_PATTERN = /^-?[\d.]+\s+-?[\d.]+\s+-?[\d.]+\s+-?[\d.]+$/;
5
130
  var DEDUPE_STRATEGIES = ["timestamp", "lastItem"];
6
- var AUTH_RUNGS = ["none", "cli", "key", "oauth"];
131
+ var AUTH_RUNGS = ["none", "cli", "key", "browser", "oauth"];
7
132
  var EXTENSION_PERMISSIONS = [
8
133
  "git.read",
9
134
  "terminal.read",
@@ -106,15 +231,46 @@ function assertAuth(definition) {
106
231
  }
107
232
  }
108
233
  }
109
- if (auth.rung === "none") {
234
+ if (auth.rung === "browser") assertBrowserSignIn(id, auth.browser);
235
+ if (auth.rung === "none" || auth.rung === "browser") {
110
236
  const secret = (definition.config ?? []).find((field) => field.secret === true);
111
237
  if (secret) {
238
+ const claim = auth.rung === "none" ? "needs no sign-in" : "signs in through a Vorn window";
112
239
  throw new Error(
113
- `Connector ${id} claims it needs no sign-in but declares secret field "${secret.key}"`
240
+ `Connector ${id} claims it ${claim} but declares secret field "${secret.key}"`
114
241
  );
115
242
  }
116
243
  }
117
244
  }
245
+ function assertBrowserSignIn(id, browser) {
246
+ if (!browser) {
247
+ throw new Error(
248
+ `Connector ${id} signs in through a Vorn window but declares no browser sign-in`
249
+ );
250
+ }
251
+ const origins = Array.isArray(browser.origins) ? browser.origins : [];
252
+ const bad = origins.find((origin) => typeof origin !== "string" || !ORIGIN_PATTERN.test(origin));
253
+ if (origins.length === 0 || bad !== void 0) {
254
+ throw new Error(
255
+ `Connector ${id} must name its origins as https://host or https://*.host` + (bad !== void 0 ? `; ${JSON.stringify(bad)} is neither` : "")
256
+ );
257
+ }
258
+ const places = [
259
+ ["sign-in page", browser.signInUrl],
260
+ ["signed-in check", browser.check?.url]
261
+ ];
262
+ for (const [what, url] of places) {
263
+ if (typeof url !== "string" || !withinOrigins(origins, url)) {
264
+ throw new Error(
265
+ `Connector ${id} puts its ${what} ${JSON.stringify(url ?? "")} outside its origins`
266
+ );
267
+ }
268
+ }
269
+ const identity = browser.check?.identity;
270
+ if (!Array.isArray(identity) || identity.some((path) => typeof path !== "string" || !path.trim())) {
271
+ throw new Error(`Connector ${id} must name its identity fields as non-empty strings`);
272
+ }
273
+ }
118
274
  function assertIdentity(kind, definition) {
119
275
  if (!KEY_PATTERN.test(definition.id ?? "")) {
120
276
  throw new Error(`${kind} id "${definition.id}" must start with a letter and be url-safe`);
@@ -909,27 +1065,13 @@ var HostReplyError = class extends Error {
909
1065
  }
910
1066
  };
911
1067
  var HOST_TIMEOUT_MS = 15e3;
912
- var LOOPBACK_HOSTS = ["127.0.0.1", "localhost", "[::1]"];
913
1068
  function endpoint(env) {
914
- const url = env[HOST_URL_ENV]?.trim();
915
- const token = env[HOST_TOKEN_ENV]?.trim();
916
- if (!url || !token) {
917
- throw new Error(
918
- `This extension was started without a host bridge; ${HOST_URL_ENV} and ${HOST_TOKEN_ENV} are set by Vorn`
919
- );
920
- }
921
- let parsed;
922
- try {
923
- parsed = new URL(url);
924
- } catch {
925
- throw new Error(`${HOST_URL_ENV} is ${JSON.stringify(url)}, which is not a URL`);
926
- }
927
- if (parsed.protocol !== "http:" || !LOOPBACK_HOSTS.includes(parsed.hostname)) {
928
- throw new Error(
929
- `${HOST_URL_ENV} is ${JSON.stringify(url)}; the bridge is served on this machine, over http on ${LOOPBACK_HOSTS.join(", ")}`
930
- );
931
- }
932
- return { url: url.replace(/\/$/, ""), token };
1069
+ return loopbackEndpoint(env, {
1070
+ urlVar: HOST_URL_ENV,
1071
+ tokenVar: HOST_TOKEN_ENV,
1072
+ missing: `This extension was started without a host bridge; ${HOST_URL_ENV} and ${HOST_TOKEN_ENV} are set by Vorn`,
1073
+ served: "the bridge is served on this machine"
1074
+ });
933
1075
  }
934
1076
  function createExtensionHost(options) {
935
1077
  const env = options.env ?? process.env;
@@ -1125,7 +1267,8 @@ async function pollWithDedupe(trigger, context) {
1125
1267
  ...state2 && { lastItemId: state2.id },
1126
1268
  ...context.limit !== void 0 && { limit: context.limit },
1127
1269
  now: context.now,
1128
- fetch: context.fetch
1270
+ fetch: context.fetch,
1271
+ ...context.session && { session: context.session }
1129
1272
  });
1130
1273
  return lastItemPoll(fetched2, state2, context, polledAt);
1131
1274
  }
@@ -1136,7 +1279,8 @@ async function pollWithDedupe(trigger, context) {
1136
1279
  ...since !== void 0 && { since },
1137
1280
  ...context.limit !== void 0 && { limit: context.limit },
1138
1281
  now: context.now,
1139
- fetch: context.fetch
1282
+ fetch: context.fetch,
1283
+ ...context.session && { session: context.session }
1140
1284
  });
1141
1285
  return timestampPoll(fetched, state, context, polledAt);
1142
1286
  }
@@ -1440,6 +1584,9 @@ function backoffMs(attempt, policy = {}) {
1440
1584
  const max = policy.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
1441
1585
  return Math.min(max, base * 2 ** attempt);
1442
1586
  }
1587
+ function isFinal(error) {
1588
+ return error?.retryable === false;
1589
+ }
1443
1590
  function resilientFetch(options) {
1444
1591
  const attempts = Math.min(MAX_ATTEMPTS, Math.max(1, options.retry?.attempts ?? DEFAULT_ATTEMPTS));
1445
1592
  const sleep = options.sleep ?? wait;
@@ -1462,7 +1609,7 @@ function resilientFetch(options) {
1462
1609
  const delay = asked === void 0 ? backoffMs(attempt, options.retry) : Math.min(asked, ceiling);
1463
1610
  if (!await pause(delay)) return response;
1464
1611
  } catch (error) {
1465
- if (!options.retryable || last) throw error;
1612
+ if (!options.retryable || last || isFinal(error)) throw error;
1466
1613
  if (!await pause(backoffMs(attempt, options.retry))) throw error;
1467
1614
  }
1468
1615
  }
@@ -1472,6 +1619,19 @@ function resilientFetch(options) {
1472
1619
  }
1473
1620
 
1474
1621
  // src/runtime.ts
1622
+ function wrap(fetchImpl, options, retryable) {
1623
+ return resilientFetch({
1624
+ fetchImpl,
1625
+ retryable,
1626
+ ...options.retry !== void 0 && { retry: options.retry },
1627
+ ...options.sleep !== void 0 && { sleep: options.sleep }
1628
+ });
1629
+ }
1630
+ function sessionFor(connector, options, retryable) {
1631
+ if (connector.auth?.rung !== "browser") return void 0;
1632
+ const fetchImpl = options.sessionFetchImpl ?? createSessionFetch(options.sessionCall ? { call: options.sessionCall } : {});
1633
+ return { fetch: wrap(fetchImpl, options, retryable) };
1634
+ }
1475
1635
  var MAX_POLL_PAGES = 1e3;
1476
1636
  async function runPoll(connector, triggerType, options = {}) {
1477
1637
  const trigger = connector.triggers.find((entry) => entry.type === triggerType);
@@ -1480,6 +1640,7 @@ async function runPoll(connector, triggerType, options = {}) {
1480
1640
  }
1481
1641
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
1482
1642
  const polledAt = now();
1643
+ const session = sessionFor(connector, options, true);
1483
1644
  const context = {
1484
1645
  config: options.config ?? {},
1485
1646
  ...options.since !== void 0 && { since: options.since },
@@ -1487,12 +1648,8 @@ async function runPoll(connector, triggerType, options = {}) {
1487
1648
  ...options.limit !== void 0 && { limit: options.limit },
1488
1649
  now,
1489
1650
  // A poll only reads, so every failure it meets is worth trying again.
1490
- fetch: resilientFetch({
1491
- fetchImpl: options.fetchImpl ?? globalThis.fetch,
1492
- retryable: true,
1493
- ...options.retry !== void 0 && { retry: options.retry },
1494
- ...options.sleep !== void 0 && { sleep: options.sleep }
1495
- })
1651
+ fetch: wrap(options.fetchImpl ?? globalThis.fetch, options, true),
1652
+ ...session && { session }
1496
1653
  };
1497
1654
  const outcome = typeof trigger.poll === "function" ? await trigger.poll(context) : await pollWithDedupe(trigger, context);
1498
1655
  if (!outcome || !Array.isArray(outcome.items)) {
@@ -1530,15 +1687,12 @@ async function runOptions(connector, name, options = {}) {
1530
1687
  if (!loader) {
1531
1688
  throw new Error(`Connector ${connector.id} serves no options set "${name}"`);
1532
1689
  }
1690
+ const session = sessionFor(connector, options, true);
1533
1691
  const loaded = await loader({
1534
1692
  config: options.config ?? {},
1535
1693
  now: options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()),
1536
- fetch: resilientFetch({
1537
- fetchImpl: options.fetchImpl ?? globalThis.fetch,
1538
- retryable: true,
1539
- ...options.retry !== void 0 && { retry: options.retry },
1540
- ...options.sleep !== void 0 && { sleep: options.sleep }
1541
- })
1694
+ fetch: wrap(options.fetchImpl ?? globalThis.fetch, options, true),
1695
+ ...session && { session }
1542
1696
  });
1543
1697
  if (!Array.isArray(loaded)) {
1544
1698
  throw new Error(`Options set "${name}" did not return an array`);
@@ -1597,19 +1751,15 @@ async function runAction(connector, actionType, args, options = {}) {
1597
1751
  const config = options.config ?? {};
1598
1752
  const method = (action.request?.method ?? "GET").toUpperCase();
1599
1753
  const retryable = action.idempotent === true || action.request !== void 0 && SAFE_METHODS.has(method);
1600
- const fetchImpl = resilientFetch({
1601
- fetchImpl: options.fetchImpl ?? globalThis.fetch,
1602
- retryable,
1603
- ...options.retry !== void 0 && { retry: options.retry },
1604
- ...options.sleep !== void 0 && { sleep: options.sleep }
1605
- });
1754
+ const fetchImpl = wrap(options.fetchImpl ?? globalThis.fetch, options, retryable);
1755
+ const session = sessionFor(connector, options, retryable);
1606
1756
  if (action.request !== void 0) {
1607
1757
  try {
1608
1758
  return await executeRequest(
1609
1759
  action.request,
1610
1760
  action.postReceive,
1611
1761
  { args: coerced, config },
1612
- { fetchImpl }
1762
+ { fetchImpl: session?.fetch ?? fetchImpl }
1613
1763
  );
1614
1764
  } catch (error) {
1615
1765
  throw new Error(
@@ -1624,7 +1774,8 @@ async function runAction(connector, actionType, args, options = {}) {
1624
1774
  const output = await action.run(coerced, {
1625
1775
  config,
1626
1776
  now: options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()),
1627
- fetch: fetchImpl
1777
+ fetch: fetchImpl,
1778
+ ...session && { session }
1628
1779
  });
1629
1780
  return output ?? {};
1630
1781
  }
@@ -1692,10 +1843,12 @@ async function withMockHttp(routes, body) {
1692
1843
  }
1693
1844
  }
1694
1845
  function createConnectorHarness(connector, harnessOptions = {}) {
1846
+ const signedIn = harnessOptions.sessionFetchImpl ?? harnessOptions.fetchImpl;
1695
1847
  const defaults = (options = {}) => ({
1696
1848
  ...harnessOptions.config && { config: harnessOptions.config },
1697
1849
  ...harnessOptions.now && { now: harnessOptions.now },
1698
1850
  ...harnessOptions.fetchImpl && { fetchImpl: harnessOptions.fetchImpl },
1851
+ ...signedIn && { sessionFetchImpl: signedIn },
1699
1852
  ...harnessOptions.sleep && { sleep: harnessOptions.sleep },
1700
1853
  ...options
1701
1854
  });
@@ -1706,6 +1859,7 @@ function createConnectorHarness(connector, harnessOptions = {}) {
1706
1859
  ...harnessOptions.config && { config: harnessOptions.config },
1707
1860
  ...harnessOptions.now && { now: harnessOptions.now },
1708
1861
  ...harnessOptions.fetchImpl && { fetchImpl: harnessOptions.fetchImpl },
1862
+ ...signedIn && { sessionFetchImpl: signedIn },
1709
1863
  ...harnessOptions.sleep && { sleep: harnessOptions.sleep }
1710
1864
  }),
1711
1865
  manifest: () => connectorManifest(connector),
@@ -1927,7 +2081,8 @@ async function mockFindings(connector, options) {
1927
2081
  try {
1928
2082
  await runAction(connector, action.type, args, {
1929
2083
  config,
1930
- ...options.now && { now: options.now }
2084
+ ...options.now && { now: options.now },
2085
+ sessionFetchImpl: globalThis.fetch
1931
2086
  });
1932
2087
  return void 0;
1933
2088
  } catch (error) {
@@ -2116,6 +2271,9 @@ function liveRunnable(action) {
2116
2271
  function liveExamines(connector) {
2117
2272
  return connector.preflight !== void 0 || connector.actions.some(liveRunnable);
2118
2273
  }
2274
+ function needsWindow(error) {
2275
+ return error instanceof SessionUnavailableError || error instanceof Error && error.cause instanceof SessionUnavailableError;
2276
+ }
2119
2277
  async function liveFindings(connector, options) {
2120
2278
  if (!options.live) return [];
2121
2279
  const found = [];
@@ -2146,6 +2304,7 @@ async function liveFindings(connector, options) {
2146
2304
  ...options.now && { now: options.now }
2147
2305
  });
2148
2306
  } catch (error) {
2307
+ if (needsWindow(error)) continue;
2149
2308
  const reason = error instanceof Error ? error.message : String(error);
2150
2309
  found.push(
2151
2310
  finding2(
@@ -3028,6 +3187,10 @@ function scaffoldFiles(options) {
3028
3187
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3029
3188
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3030
3189
  import { z } from "zod";
3190
+ function sessionCallOf(extra) {
3191
+ const key = extra._meta?.[SESSION_CALL_META];
3192
+ return typeof key === "string" ? { sessionCall: key } : {};
3193
+ }
3031
3194
  function json(value) {
3032
3195
  return {
3033
3196
  // Vorn reads `structuredContent` to build step output and to find the
@@ -3129,12 +3292,13 @@ function createConnectorServer(connector, options = {}) {
3129
3292
  options: z.array(z.looseObject({ value: z.string(), label: z.string().optional() })).describe("The choices, each a value to send and words to show")
3130
3293
  })
3131
3294
  },
3132
- async (args) => {
3295
+ async (args, extra) => {
3133
3296
  try {
3134
3297
  return json({
3135
3298
  options: await runOptions(connector, args.name, {
3136
3299
  config: config(),
3137
- ...options.now && { now: options.now }
3300
+ ...options.now && { now: options.now },
3301
+ ...sessionCallOf(extra)
3138
3302
  })
3139
3303
  });
3140
3304
  } catch (error) {
@@ -3159,7 +3323,7 @@ function createConnectorServer(connector, options = {}) {
3159
3323
  hasMore: z.boolean().describe("Whether another page is immediately available")
3160
3324
  })
3161
3325
  },
3162
- async (args) => {
3326
+ async (args, extra) => {
3163
3327
  try {
3164
3328
  const limit = args.limit === void 0 ? void 0 : Number(args.limit);
3165
3329
  if (limit !== void 0 && !Number.isFinite(limit)) {
@@ -3171,7 +3335,8 @@ function createConnectorServer(connector, options = {}) {
3171
3335
  ...args.since !== void 0 && { since: args.since },
3172
3336
  ...args.cursor !== void 0 && { cursor: args.cursor },
3173
3337
  ...limit !== void 0 && { limit },
3174
- ...options.now && { now: options.now }
3338
+ ...options.now && { now: options.now },
3339
+ ...sessionCallOf(extra)
3175
3340
  })
3176
3341
  );
3177
3342
  } catch (error) {
@@ -3253,12 +3418,13 @@ function createConnectorServer(connector, options = {}) {
3253
3418
  inputSchema: inputShape(action.inputs ?? []),
3254
3419
  outputSchema: outputSchema(action.outputs ?? [])
3255
3420
  },
3256
- async (args) => {
3421
+ async (args, extra) => {
3257
3422
  try {
3258
3423
  return json(
3259
3424
  await runAction(connector, action.type, args, {
3260
3425
  config: config(),
3261
- ...options.now && { now: options.now }
3426
+ ...options.now && { now: options.now },
3427
+ ...sessionCallOf(extra)
3262
3428
  })
3263
3429
  );
3264
3430
  } catch (error) {
@@ -3275,6 +3441,15 @@ async function serveConnector(connector, options = {}) {
3275
3441
  }
3276
3442
 
3277
3443
  export {
3444
+ BROWSER_HOST_ENV,
3445
+ BROWSER_TOKEN_ENV,
3446
+ SESSION_CALL_META,
3447
+ SESSION_CALL_HEADER,
3448
+ SessionUnavailableError,
3449
+ SessionRefusedError,
3450
+ createSessionFetch,
3451
+ ORIGIN_PATTERN,
3452
+ withinOrigins,
3278
3453
  EXTENSION_PERMISSIONS,
3279
3454
  HOST_PERMISSIONS,
3280
3455
  envNameFor,
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { B as BundleRequest, a as BundleOutput, C as CheckFinding } from './check-Cv6UNBA4.js';
2
+ import { B as BundleRequest, a as BundleOutput, C as CheckFinding } from './check-62s2GvcO.js';
3
3
 
4
4
  interface CliDeps {
5
5
  load(modulePath: string): Promise<unknown>;
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  runPoll,
11
11
  scaffoldFiles,
12
12
  serveConnector
13
- } from "./chunk-FHGC7LE7.js";
13
+ } from "./chunk-ZKHXHE3O.js";
14
14
 
15
15
  // src/cli.ts
16
16
  import { fileURLToPath, pathToFileURL } from "url";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { E as ExtensionPermission, b as ExtensionHostMethod, c as ConnectorDefinition, d as Connector, e as ExtensionDefinition, f as ConnectorConfig, g as ExtensionHost, T as TriggerDefinition, P as PollContext, h as PollOutcome, i as ConnectorItem, N as NormalizedItem, j as PostReceiveOp, A as ActionRequest, B as BundleRequest, a as BundleOutput, C as CheckFinding } from './check-Cv6UNBA4.js';
2
- export { k as ActionContext, l as ActionDefinition, m as ActionInputField, n as ActionInputOption, o as ActionInputType, p as ActionOutputField, q as ActivationPredicate, r as AuthRung, s as CHECK_OWNERS, t as CheckCode, u as CheckOptions, v as ConformanceRun, w as ConnectionSetup, x as ConnectorAuth, y as ConnectorConfigField, z as ConnectorHarness, D as ConnectorIcon, F as ConnectorKind, G as ConnectorManifest, H as ConnectorVerification, I as DedupeStrategy, J as DefaultWorkflow, K as ExtensionAgent, L as ExtensionContext, M as ExtensionContributions, O as ExtensionPlatform, Q as ExtensionUsage, R as ExtensionUsageWindow, S as FetchContext, U as FooterContribution, V as FooterItem, W as HarnessOptions, X as LinkContext, Y as LinkHandled, Z as LinkHandlerContribution, _ as MANIFEST_TOOL, $ as MAX_PACK_BYTES, a0 as MAX_POLL_PAGES, a1 as ManifestContributions, a2 as MockCall, a3 as MockHostAnswers, a4 as MockHostRun, a5 as MockRoute, a6 as MockRouteMissError, a7 as MockRun, a8 as OPTIONS_TOOL, a9 as OptionsContext, aa as OptionsLoader, ab as PREFLIGHT_TOOL, ac as PaginationStrategy, ad as PaneContribution, ae as PollPage, af as PreflightResult, ag as ResilientFetchOptions, ah as RetryPolicy, ai as RunActionOptions, aj as RunPollOptions, ak as StatusSuggestion, al as backoffMs, am as bundleDependencyFindings, an as bundledRequireFindings, ao as checkConnector, ap as connectionSetup, aq as connectorManifest, ar as createConnectorHarness, as as drainPoll, at as esbuildBundle, au as escapedMockHttp, av as footerToolName, aw as formatFindings, ax as handlerToolName, ay as lifecycleScriptFindings, az as mockExtensionHost, aA as pollToolName, aB as readNearestPackageJson, aC as resilientFetch, aD as retryAfterMs, aE as runAction, aF as runConformance, aG as runOptions, aH as runPoll, aI as withMockHttp } from './check-Cv6UNBA4.js';
1
+ import { E as ExtensionPermission, b as ExtensionHostMethod, c as ConnectorDefinition, d as Connector, e as ExtensionDefinition, f as ConnectorConfig, g as ExtensionHost, T as TriggerDefinition, P as PollContext, h as PollOutcome, i as ConnectorItem, N as NormalizedItem, j as PostReceiveOp, A as ActionRequest, B as BundleRequest, a as BundleOutput, C as CheckFinding } from './check-62s2GvcO.js';
2
+ export { k as ActionContext, l as ActionDefinition, m as ActionInputField, n as ActionInputOption, o as ActionInputType, p as ActionOutputField, q as ActivationPredicate, r as AuthRung, s as BrowserSignIn, t as CHECK_OWNERS, u as CheckCode, v as CheckOptions, w as ConformanceRun, x as ConnectionSetup, y as ConnectorAuth, z as ConnectorConfigField, D as ConnectorHarness, F as ConnectorIcon, G as ConnectorKind, H as ConnectorManifest, I as ConnectorVerification, J as DedupeStrategy, K as DefaultWorkflow, L as ExtensionAgent, M as ExtensionContext, O as ExtensionContributions, Q as ExtensionPlatform, R as ExtensionUsage, S as ExtensionUsageWindow, U as FetchContext, V as FooterContribution, W as FooterItem, X as HarnessOptions, Y as LinkContext, Z as LinkHandled, _ as LinkHandlerContribution, $ as MANIFEST_TOOL, a0 as MAX_PACK_BYTES, a1 as MAX_POLL_PAGES, a2 as ManifestContributions, a3 as MockCall, a4 as MockHostAnswers, a5 as MockHostRun, a6 as MockRoute, a7 as MockRouteMissError, a8 as MockRun, a9 as OPTIONS_TOOL, aa as OptionsContext, ab as OptionsLoader, ac as PREFLIGHT_TOOL, ad as PaginationStrategy, ae as PaneContribution, af as PollPage, ag as PreflightResult, ah as ResilientFetchOptions, ai as RetryPolicy, aj as RunActionOptions, ak as RunPollOptions, al as SessionContext, am as StatusSuggestion, an as backoffMs, ao as bundleDependencyFindings, ap as bundledRequireFindings, aq as checkConnector, ar as connectionSetup, as as connectorManifest, at as createConnectorHarness, au as drainPoll, av as esbuildBundle, aw as escapedMockHttp, ax as footerToolName, ay as formatFindings, az as handlerToolName, aA as lifecycleScriptFindings, aB as mockExtensionHost, aC as pollToolName, aD as readNearestPackageJson, aE as resilientFetch, aF as retryAfterMs, aG as runAction, aH as runConformance, aI as runOptions, aJ as runPoll, aK as withMockHttp } from './check-62s2GvcO.js';
3
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
 
5
5
  /** Everything an extension may ask the host for; anything else is not grantable. */
@@ -59,6 +59,38 @@ interface HostBridgeOptions {
59
59
  /** The host as an extension process reaches it, over the bridge Vorn served it. */
60
60
  declare function createExtensionHost(options: HostBridgeOptions): ExtensionHost;
61
61
 
62
+ /** Where Vorn serves a browser-sign-in connector the window it signed in through. */
63
+ declare const BROWSER_HOST_ENV = "VORN_BROWSER_HOST";
64
+ declare const BROWSER_TOKEN_ENV = "VORN_BROWSER_TOKEN";
65
+ /** The tool call a window request belongs to, so Vorn can tell a step's own requests from another's. */
66
+ declare const SESSION_CALL_META = "vorn/sessionCall";
67
+ declare const SESSION_CALL_HEADER = "x-vorn-session-call";
68
+ /** The signed-in window could not make the call: Vorn is closed, too old, or not the caller. */
69
+ declare class SessionUnavailableError extends Error {
70
+ /** Asking again cannot bring the window back, so the SDK's retries let this through at once. */
71
+ readonly retryable = false;
72
+ constructor(message: string);
73
+ }
74
+ /** Vorn refused the call itself, for instance because it is off the connector's origins. */
75
+ declare class SessionRefusedError extends Error {
76
+ readonly retryable = false;
77
+ constructor(message: string);
78
+ }
79
+ interface SessionFetchOptions {
80
+ env?: NodeJS.ProcessEnv;
81
+ /** Replaced in tests so nothing opens a socket. */
82
+ fetchImpl?: typeof fetch;
83
+ /** The key of the tool call these requests belong to, from its MCP metadata. */
84
+ call?: string;
85
+ }
86
+ /** A fetch whose requests run inside the connection's signed-in Vorn window, so no cookie reaches this process. */
87
+ declare function createSessionFetch(options?: SessionFetchOptions): typeof fetch;
88
+
89
+ /** An origin a connector may act on: `https://host`, or `https://*.host` for every subdomain. */
90
+ declare const ORIGIN_PATTERN: RegExp;
91
+ /** Whether `url` is on one of the declared origins. */
92
+ declare function withinOrigins(origins: readonly string[], url: string): boolean;
93
+
62
94
  /**
63
95
  * Run a declarative trigger: call the author's `fetch`, then apply the chosen
64
96
  * dedupe strategy.
@@ -223,4 +255,4 @@ declare function titleCase(id: string): string;
223
255
  /** Every file a new connector or extension starts with, ready to build, check and pack. */
224
256
  declare function scaffoldFiles(options: ScaffoldOptions): ScaffoldFile[];
225
257
 
226
- export { ActionRequest, BundleOutput, BundleRequest, CheckFinding, Connector, ConnectorConfig, ConnectorDefinition, ConnectorItem, type ConnectorServerOptions, EXTENSION_PERMISSIONS, ExtensionDefinition, ExtensionHost, ExtensionHostMethod, ExtensionPermission, HOST_PERMISSIONS, HOST_TOKEN_ENV, HOST_URL_ENV, type HostBridgeOptions, MAX_REQUEST_PAGES, NormalizedItem, type PackOptions, type PackResult, PermissionDeniedError, PollContext, PollOutcome, PostReceiveOp, type RequestScope, type ResolvedRequest, type ScaffoldFile, type ScaffoldOptions, type Substitution, TriggerDefinition, applyPostReceive, asOutput, createConnectorServer, createExtensionHost, defineConnector, defineExtension, envNameFor, executeRequest, nextLink, normalizeItem, normalizeItems, packConnector, packFileName, pollWithDedupe, resolveConfig, resolveRequest, resolveTemplates, scaffoldFiles, serveConnector, titleCase, valueAt };
258
+ export { ActionRequest, BROWSER_HOST_ENV, BROWSER_TOKEN_ENV, BundleOutput, BundleRequest, CheckFinding, Connector, ConnectorConfig, ConnectorDefinition, ConnectorItem, type ConnectorServerOptions, EXTENSION_PERMISSIONS, ExtensionDefinition, ExtensionHost, ExtensionHostMethod, ExtensionPermission, HOST_PERMISSIONS, HOST_TOKEN_ENV, HOST_URL_ENV, type HostBridgeOptions, MAX_REQUEST_PAGES, NormalizedItem, ORIGIN_PATTERN, type PackOptions, type PackResult, PermissionDeniedError, PollContext, PollOutcome, PostReceiveOp, type RequestScope, type ResolvedRequest, SESSION_CALL_HEADER, SESSION_CALL_META, type ScaffoldFile, type ScaffoldOptions, type SessionFetchOptions, SessionRefusedError, SessionUnavailableError, type Substitution, TriggerDefinition, applyPostReceive, asOutput, createConnectorServer, createExtensionHost, createSessionFetch, defineConnector, defineExtension, envNameFor, executeRequest, nextLink, normalizeItem, normalizeItems, packConnector, packFileName, pollWithDedupe, resolveConfig, resolveRequest, resolveTemplates, scaffoldFiles, serveConnector, titleCase, valueAt, withinOrigins };
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import {
2
+ BROWSER_HOST_ENV,
3
+ BROWSER_TOKEN_ENV,
2
4
  CHECK_OWNERS,
3
5
  EXTENSION_PERMISSIONS,
4
6
  HOST_PERMISSIONS,
@@ -10,8 +12,13 @@ import {
10
12
  MAX_REQUEST_PAGES,
11
13
  MockRouteMissError,
12
14
  OPTIONS_TOOL,
15
+ ORIGIN_PATTERN,
13
16
  PREFLIGHT_TOOL,
14
17
  PermissionDeniedError,
18
+ SESSION_CALL_HEADER,
19
+ SESSION_CALL_META,
20
+ SessionRefusedError,
21
+ SessionUnavailableError,
15
22
  applyPostReceive,
16
23
  asOutput,
17
24
  backoffMs,
@@ -23,6 +30,7 @@ import {
23
30
  createConnectorHarness,
24
31
  createConnectorServer,
25
32
  createExtensionHost,
33
+ createSessionFetch,
26
34
  defineConnector,
27
35
  defineExtension,
28
36
  drainPoll,
@@ -56,9 +64,12 @@ import {
56
64
  serveConnector,
57
65
  titleCase,
58
66
  valueAt,
59
- withMockHttp
60
- } from "./chunk-FHGC7LE7.js";
67
+ withMockHttp,
68
+ withinOrigins
69
+ } from "./chunk-ZKHXHE3O.js";
61
70
  export {
71
+ BROWSER_HOST_ENV,
72
+ BROWSER_TOKEN_ENV,
62
73
  CHECK_OWNERS,
63
74
  EXTENSION_PERMISSIONS,
64
75
  HOST_PERMISSIONS,
@@ -70,8 +81,13 @@ export {
70
81
  MAX_REQUEST_PAGES,
71
82
  MockRouteMissError,
72
83
  OPTIONS_TOOL,
84
+ ORIGIN_PATTERN,
73
85
  PREFLIGHT_TOOL,
74
86
  PermissionDeniedError,
87
+ SESSION_CALL_HEADER,
88
+ SESSION_CALL_META,
89
+ SessionRefusedError,
90
+ SessionUnavailableError,
75
91
  applyPostReceive,
76
92
  asOutput,
77
93
  backoffMs,
@@ -83,6 +99,7 @@ export {
83
99
  createConnectorHarness,
84
100
  createConnectorServer,
85
101
  createExtensionHost,
102
+ createSessionFetch,
86
103
  defineConnector,
87
104
  defineExtension,
88
105
  drainPoll,
@@ -116,5 +133,6 @@ export {
116
133
  serveConnector,
117
134
  titleCase,
118
135
  valueAt,
119
- withMockHttp
136
+ withMockHttp,
137
+ withinOrigins
120
138
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vornrun/connector-sdk",
3
- "version": "0.7.0-beta.16",
3
+ "version": "0.7.0-beta.18",
4
4
  "description": "Build and share Vorn pull connectors as ordinary npm packages",
5
5
  "type": "module",
6
6
  "license": "MIT",