@loomcycle/client 1.125.0 → 1.127.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/README.md +158 -0
- package/dist/cjs/client-tools.js +28 -5
- package/dist/cjs/client.js +239 -9
- package/dist/cjs/device-login.js +146 -0
- package/dist/cjs/errors.js +40 -1
- package/dist/cjs/fetch-helpers.js +31 -0
- package/dist/cjs/index.js +35 -1
- package/dist/cjs/oauth.js +400 -0
- package/dist/client-tools.d.ts +6 -2
- package/dist/client-tools.js +28 -5
- package/dist/client.d.ts +196 -3
- package/dist/client.js +240 -10
- package/dist/device-login.d.ts +12 -0
- package/dist/device-login.js +143 -0
- package/dist/errors.d.ts +36 -0
- package/dist/errors.js +37 -0
- package/dist/fetch-helpers.d.ts +8 -0
- package/dist/fetch-helpers.js +30 -0
- package/dist/index.d.ts +31 -2
- package/dist/index.js +29 -1
- package/dist/oauth.d.ts +131 -0
- package/dist/oauth.js +393 -0
- package/dist/types.d.ts +512 -11
- package/package.json +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @internal — reached through LoomcycleClient.deviceLogin().
|
|
4
|
+
*
|
|
5
|
+
* The client side of loomcycle's device login (RFC 8628, a `kind: device`
|
|
6
|
+
* sign-in gate): ask the server for a code pair, show the person the short
|
|
7
|
+
* code, poll until they approve it in a signed-in Web UI session, and return
|
|
8
|
+
* the token issued to them. Both requests are unauthenticated — the device
|
|
9
|
+
* code is the credential — so no bearer the client holds is sent with them.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.deviceLogin = deviceLogin;
|
|
13
|
+
const errors_js_1 = require("./errors.js");
|
|
14
|
+
const GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
|
|
15
|
+
/** RFC 8628 §3.5: a slow_down lengthens this and every later poll by 5 s. */
|
|
16
|
+
const SLOW_DOWN_STEP_MS = 5_000;
|
|
17
|
+
const DEFAULT_INTERVAL_S = 5;
|
|
18
|
+
/** The server issues codes for ten minutes; a longer claim is not trusted. */
|
|
19
|
+
const DEFAULT_EXPIRES_S = 600;
|
|
20
|
+
const MAX_EXPIRES_S = 3_600;
|
|
21
|
+
async function postForm(ctx, path, form, signal) {
|
|
22
|
+
const res = await ctx.fetchImpl(`${ctx.baseUrl}${path}`, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { Accept: "application/json", "Content-Type": "application/x-www-form-urlencoded" },
|
|
25
|
+
body: new URLSearchParams(form).toString(),
|
|
26
|
+
signal,
|
|
27
|
+
});
|
|
28
|
+
const text = await res.text();
|
|
29
|
+
let body = {};
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(text);
|
|
32
|
+
if (parsed && typeof parsed === "object")
|
|
33
|
+
body = parsed;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// A non-JSON answer is reported by status below.
|
|
37
|
+
}
|
|
38
|
+
return { status: res.status, body, text };
|
|
39
|
+
}
|
|
40
|
+
function sleep(ms, signal) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
if (signal?.aborted) {
|
|
43
|
+
reject(signal.reason ?? new Error("aborted"));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const t = setTimeout(() => {
|
|
47
|
+
signal?.removeEventListener("abort", onAbort);
|
|
48
|
+
resolve();
|
|
49
|
+
}, ms);
|
|
50
|
+
const onAbort = () => {
|
|
51
|
+
clearTimeout(t);
|
|
52
|
+
reject(signal?.reason ?? new Error("aborted"));
|
|
53
|
+
};
|
|
54
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/** A string shown to a person must not carry control characters a hostile
|
|
58
|
+
* server could use to rewrite what they see. */
|
|
59
|
+
function printable(s, max) {
|
|
60
|
+
return typeof s === "string" && s.length > 0 && s.length <= max && /^[\x20-\x7e]+$/.test(s);
|
|
61
|
+
}
|
|
62
|
+
function httpURL(s) {
|
|
63
|
+
if (!printable(s, 2048))
|
|
64
|
+
return false;
|
|
65
|
+
try {
|
|
66
|
+
const u = new URL(s);
|
|
67
|
+
return u.protocol === "https:" || u.protocol === "http:";
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function positiveInt(v) {
|
|
74
|
+
return typeof v === "number" && Number.isInteger(v) && v > 0 ? v : undefined;
|
|
75
|
+
}
|
|
76
|
+
async function deviceLogin(ctx, opts) {
|
|
77
|
+
const clientId = opts.clientId ?? "loomcycle-ts";
|
|
78
|
+
const start = await postForm(ctx, "/v1/_auth/device", { client_id: clientId }, opts.signal);
|
|
79
|
+
if (start.status !== 200) {
|
|
80
|
+
const code = typeof start.body.code === "string" ? start.body.code : undefined;
|
|
81
|
+
throw new errors_js_1.DeviceLoginError(`the server refused to start a device login (HTTP ${start.status})`, {
|
|
82
|
+
status: start.status,
|
|
83
|
+
bodyText: start.text.slice(0, 1024),
|
|
84
|
+
code,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const da = start.body;
|
|
88
|
+
if (typeof da.device_code !== "string" || da.device_code === "" ||
|
|
89
|
+
!printable(da.user_code, 32) || !httpURL(da.verification_uri)) {
|
|
90
|
+
throw new errors_js_1.DeviceLoginError("the server's device-login answer is malformed", { status: start.status });
|
|
91
|
+
}
|
|
92
|
+
const deviceCode = da.device_code;
|
|
93
|
+
let expiresIn = positiveInt(da.expires_in) ?? DEFAULT_EXPIRES_S;
|
|
94
|
+
if (expiresIn > MAX_EXPIRES_S)
|
|
95
|
+
expiresIn = DEFAULT_EXPIRES_S;
|
|
96
|
+
await opts.onPrompt({
|
|
97
|
+
userCode: da.user_code,
|
|
98
|
+
verificationUri: da.verification_uri,
|
|
99
|
+
verificationUriComplete: httpURL(da.verification_uri_complete) ? da.verification_uri_complete : undefined,
|
|
100
|
+
expiresIn,
|
|
101
|
+
});
|
|
102
|
+
let intervalMs = (positiveInt(da.interval) ?? DEFAULT_INTERVAL_S) * 1000;
|
|
103
|
+
// A little past the code's own expiry, so the server's expired_token is
|
|
104
|
+
// what ends a login nobody approved.
|
|
105
|
+
const deadline = Date.now() + expiresIn * 1000 + 30_000;
|
|
106
|
+
for (;;) {
|
|
107
|
+
await sleep(intervalMs, opts.signal);
|
|
108
|
+
if (Date.now() > deadline) {
|
|
109
|
+
throw new errors_js_1.DeviceLoginError("the code expired before it was approved", { code: "expired_token" });
|
|
110
|
+
}
|
|
111
|
+
const res = await postForm(ctx, "/v1/_auth/device/token", { grant_type: GRANT_TYPE, device_code: deviceCode, client_id: clientId }, opts.signal);
|
|
112
|
+
const tok = res.body;
|
|
113
|
+
if (res.status === 200 && typeof tok.access_token === "string" && tok.access_token !== "") {
|
|
114
|
+
return {
|
|
115
|
+
accessToken: tok.access_token,
|
|
116
|
+
tokenType: typeof tok.token_type === "string" ? tok.token_type : "Bearer",
|
|
117
|
+
expiresIn: positiveInt(tok.expires_in),
|
|
118
|
+
scope: typeof tok.scope === "string" && tok.scope !== "" ? tok.scope.split(" ") : undefined,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
switch (tok.error) {
|
|
122
|
+
case "authorization_pending":
|
|
123
|
+
continue;
|
|
124
|
+
case "slow_down":
|
|
125
|
+
intervalMs += SLOW_DOWN_STEP_MS;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// RFC 8628 refusals carry the code in `error`; loomcycle's own refusals
|
|
129
|
+
// (device_login_disabled, …) carry it in `code` and a message in `error`.
|
|
130
|
+
const code = typeof res.body.code === "string" ? res.body.code : typeof tok.error === "string" ? tok.error : undefined;
|
|
131
|
+
const why = code === "access_denied"
|
|
132
|
+
? "the login was denied, or its approval no longer holds"
|
|
133
|
+
: code === "expired_token"
|
|
134
|
+
? "the code expired before it was approved"
|
|
135
|
+
: typeof tok.error_description === "string"
|
|
136
|
+
? tok.error_description
|
|
137
|
+
: `the server refused the login (HTTP ${res.status})`;
|
|
138
|
+
// A refusal's body carries no token. A 200 without a usable one is
|
|
139
|
+
// malformed, and its body is not echoed, in case it holds one anyway.
|
|
140
|
+
throw new errors_js_1.DeviceLoginError(why, {
|
|
141
|
+
status: res.status,
|
|
142
|
+
bodyText: res.status === 200 ? undefined : res.text.slice(0, 1024),
|
|
143
|
+
code,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
package/dist/cjs/errors.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* to raise typed errors via `raiseFromResponse`.
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.SubstrateToolRefusedError = exports.ChannelCursorRegressionError = exports.SnapshotVersionError = exports.PromptTooLargeError = exports.RequestTooLargeError = exports.SnapshotTooLargeError = exports.SnapshotNotFoundError = exports.NotPausedError = exports.AlreadyPausingError = exports.PauseNotConfiguredError = exports.InvalidArgumentError = exports.UnavailableError = exports.AclDeniedError = exports.InsufficientScopeError = exports.AuthError = exports.PerUserQuotaExhaustedError = exports.TokenLimitExceededError = exports.RateLimitedError = exports.BackpressureError = exports.AgentIDInUseError = exports.SessionBusyError = exports.SessionNotFoundError = exports.AgentNotFoundError = exports.NotFoundError = exports.LoomcycleError = void 0;
|
|
22
|
+
exports.DeviceLoginError = exports.OAuthError = exports.SubstrateToolRefusedError = exports.ChannelCursorRegressionError = exports.SnapshotVersionError = exports.PromptTooLargeError = exports.RequestTooLargeError = exports.SnapshotTooLargeError = exports.SnapshotNotFoundError = exports.NotPausedError = exports.AlreadyPausingError = exports.PauseNotConfiguredError = exports.InvalidArgumentError = exports.UnavailableError = exports.AclDeniedError = exports.InsufficientScopeError = exports.AuthError = exports.PerUserQuotaExhaustedError = exports.TokenLimitExceededError = exports.RateLimitedError = exports.BackpressureError = exports.AgentIDInUseError = exports.SessionBusyError = exports.SessionNotFoundError = exports.AgentNotFoundError = exports.NotFoundError = exports.LoomcycleError = void 0;
|
|
23
23
|
class LoomcycleError extends Error {
|
|
24
24
|
status;
|
|
25
25
|
bodyText;
|
|
@@ -455,3 +455,42 @@ class SubstrateToolRefusedError extends LoomcycleError {
|
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
457
|
exports.SubstrateToolRefusedError = SubstrateToolRefusedError;
|
|
458
|
+
/** An app sign-in (RFC FL) failed. `code` is the OAuth error code: one the
|
|
459
|
+
* server sent (`invalid_grant`, `invalid_client`, `access_denied`,
|
|
460
|
+
* `temporarily_unavailable`, …, RFC 6749 §4.1.2.1 / §5.2), or one the client
|
|
461
|
+
* decided on before trusting a response:
|
|
462
|
+
* - `state_mismatch`: the redirect's `state` is not the one this sign-in
|
|
463
|
+
* sent — a forged or crossed response; nothing was exchanged.
|
|
464
|
+
* - `issuer_mismatch`: the redirect's `iss` names another server (RFC 9207).
|
|
465
|
+
* - `invalid_response`: the server's answer is not a token response.
|
|
466
|
+
* - `signed_out`: the sign-in ended (its refresh token was refused); sign in
|
|
467
|
+
* again.
|
|
468
|
+
* `invalid_grant` on a refresh means the same: the sign-in is over. */
|
|
469
|
+
class OAuthError extends LoomcycleError {
|
|
470
|
+
/** The server's `error_description`, when it sent one. */
|
|
471
|
+
errorDescription;
|
|
472
|
+
constructor(code, opts) {
|
|
473
|
+
super(opts?.errorDescription ? `loomcycle sign-in: ${code}: ${opts.errorDescription}` : `loomcycle sign-in: ${code}`, { status: opts?.status, bodyText: opts?.bodyText, code });
|
|
474
|
+
this.name = "OAuthError";
|
|
475
|
+
this.errorDescription = opts?.errorDescription;
|
|
476
|
+
}
|
|
477
|
+
/** `temporarily_unavailable` (and a 429 throttle) clear on their own; every
|
|
478
|
+
* other sign-in failure needs the person or the app to act. */
|
|
479
|
+
get retryable() {
|
|
480
|
+
return this.code === "temporarily_unavailable";
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
exports.OAuthError = OAuthError;
|
|
484
|
+
/** A device login ({@link LoomcycleClient.deviceLogin}) that ended without a
|
|
485
|
+
* token. `code` is the server's RFC 8628 error: `access_denied` (the person
|
|
486
|
+
* denied it, or the approval no longer holds — the approving session ended
|
|
487
|
+
* or its credential was retired), `expired_token` (nobody approved it in
|
|
488
|
+
* time), or another refusal. Start a new login; the same one never
|
|
489
|
+
* succeeds. */
|
|
490
|
+
class DeviceLoginError extends LoomcycleError {
|
|
491
|
+
constructor(message, opts) {
|
|
492
|
+
super(message, opts);
|
|
493
|
+
this.name = "DeviceLoginError";
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
exports.DeviceLoginError = DeviceLoginError;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* the boring fetch + error-translation machinery lives here.
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.authorizedFetch = authorizedFetch;
|
|
14
15
|
exports.authHeaders = authHeaders;
|
|
15
16
|
exports.jsonFetch = jsonFetch;
|
|
16
17
|
exports.postJSON = postJSON;
|
|
@@ -20,6 +21,36 @@ exports.deleteRequest = deleteRequest;
|
|
|
20
21
|
exports.deleteJSON = deleteJSON;
|
|
21
22
|
exports.raiseFromResponse = raiseFromResponse;
|
|
22
23
|
const errors_js_1 = require("./errors.js");
|
|
24
|
+
/** authorizedFetch wraps a fetch so every request carries the provider's
|
|
25
|
+
* current bearer (replacing whatever Authorization the caller set), and a
|
|
26
|
+
* 401 is retried once with the token `onUnauthorized` hands back — never
|
|
27
|
+
* twice, so a token the server keeps refusing cannot loop. A request whose
|
|
28
|
+
* body is a stream is not retried: the stream was consumed by the first
|
|
29
|
+
* send. */
|
|
30
|
+
function authorizedFetch(inner, provider) {
|
|
31
|
+
return async (input, init) => {
|
|
32
|
+
const token = await provider.getToken();
|
|
33
|
+
const first = await inner(input, withBearer(init, token));
|
|
34
|
+
if (first.status !== 401 || !provider.onUnauthorized || !replayableBody(init?.body))
|
|
35
|
+
return first;
|
|
36
|
+
const fresh = await provider.onUnauthorized(token);
|
|
37
|
+
if (!fresh || fresh === token)
|
|
38
|
+
return first;
|
|
39
|
+
await first.body?.cancel().catch(() => undefined);
|
|
40
|
+
return inner(input, withBearer(init, fresh));
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function withBearer(init, token) {
|
|
44
|
+
const headers = new Headers(init?.headers);
|
|
45
|
+
if (token)
|
|
46
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
47
|
+
else
|
|
48
|
+
headers.delete("Authorization");
|
|
49
|
+
return { ...init, headers };
|
|
50
|
+
}
|
|
51
|
+
function replayableBody(body) {
|
|
52
|
+
return !(typeof ReadableStream !== "undefined" && body instanceof ReadableStream);
|
|
53
|
+
}
|
|
23
54
|
/** authHeaders builds the standard request header set: JSON Accept
|
|
24
55
|
* + Bearer token when the client was constructed with one. The
|
|
25
56
|
* caller adds Content-Type when posting a body. */
|
package/dist/cjs/index.js
CHANGED
|
@@ -28,6 +28,20 @@
|
|
|
28
28
|
* mintUserToken(subject, opts?): Promise<MintedUserToken> // delegated token
|
|
29
29
|
* listUserTokens(subject, opts?): Promise<ListUserTokensResponse>
|
|
30
30
|
* revokeUserToken(subject, defId, opts?): Promise<{def_id, retired_at}>
|
|
31
|
+
* approveUser(subject, opts?): Promise<UserRecord> // pending → active (RFC FA)
|
|
32
|
+
* listUserIdentities(subject, opts?): Promise<UserIdentitiesResponse>
|
|
33
|
+
* unlinkUserIdentity(subject, gate, opts?): Promise<void>
|
|
34
|
+
*
|
|
35
|
+
* // Sign-in gates + the password gate's management API (RFC FA)
|
|
36
|
+
* listAuthGates(opts?): Promise<AuthGateListResponse> // admin token only
|
|
37
|
+
* createInvite(gate, body, opts?): Promise<CreatedInvite> // one-time link, shown once
|
|
38
|
+
* listInvites(gate, opts?): Promise<AuthInviteListResponse>
|
|
39
|
+
* revokeInvite(gate, inviteId, opts?): Promise<void>
|
|
40
|
+
* createPasswordReset(gate, subject, opts?): Promise<CreatedPasswordReset>
|
|
41
|
+
* removeGateCredentials(gate, subject, opts?): Promise<void>
|
|
42
|
+
* renameGateLogin(gate, subject, login, opts?): Promise<{subject, login}>
|
|
43
|
+
* listGateIdentities(gate, subject, opts?): Promise<GateIdentitiesResponse>
|
|
44
|
+
* getGateTenantStatus(gate, opts?): Promise<GateTenantStatus>
|
|
31
45
|
* runnableAgents(opts?): Promise<RunnableAgentsResponse> // RFC BY (v1.51.0) — agents I can run
|
|
32
46
|
* whoami(): Promise<WhoamiResponse> // RFC L principal (v0.17.0)
|
|
33
47
|
*
|
|
@@ -116,6 +130,19 @@
|
|
|
116
130
|
* listVolumes(): Promise<PersistentVolumesResponse>
|
|
117
131
|
* listEphemeralVolumes(): Promise<EphemeralVolumesResponse>
|
|
118
132
|
*
|
|
133
|
+
* // App clients (RFC FL ClientDef; tenant operator or admin)
|
|
134
|
+
* clientDef(input): Promise<unknown> // POST /v1/_clientdef
|
|
135
|
+
* createClientDef / updateClientDef(name, client, opts?): Promise<ClientDefRecord>
|
|
136
|
+
* getClientDef({name | def_id}): Promise<AppClientEntry>
|
|
137
|
+
* listClientDefs(opts?): Promise<ClientDefListResponse>
|
|
138
|
+
* retireClientDef(name): Promise<ClientDefRetireResult>
|
|
139
|
+
* verifyClientDef(name, {contentSha256}?): Promise<ClientDefVerifyResult>
|
|
140
|
+
* listClientDefNames(opts?): Promise<ClientDefNamesResponse> // GET /v1/_clientdef/names
|
|
141
|
+
*
|
|
142
|
+
* // App sign-in (RFC FL) — also standalone as `new LoomcycleOAuth(...)`
|
|
143
|
+
* oauth: LoomcycleOAuth // beginAuthorize / completeAuthorize / refresh / revoke / discover
|
|
144
|
+
* new LoomcycleClient({ tokenProvider: new OAuthTokenProvider(...) }) // refreshes on its own
|
|
145
|
+
*
|
|
119
146
|
* // Agent Teams (RFC AP — TeamDef substrate; tenant-confined)
|
|
120
147
|
* listTeams(): Promise<ListTeamsResponse>
|
|
121
148
|
* renderTeamDiagram(name, opts?): Promise<TeamDiagram>
|
|
@@ -182,7 +209,7 @@
|
|
|
182
209
|
* See `adapters/ts/README.md` for usage examples.
|
|
183
210
|
*/
|
|
184
211
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
185
|
-
exports.UnavailableError = exports.TokenLimitExceededError = exports.SubstrateToolRefusedError = exports.SnapshotVersionError = exports.SnapshotTooLargeError = exports.SnapshotNotFoundError = exports.SessionNotFoundError = exports.SessionBusyError = exports.RequestTooLargeError = exports.RateLimitedError = exports.PromptTooLargeError = exports.PerUserQuotaExhaustedError = exports.PauseNotConfiguredError = exports.NotPausedError = exports.LoomcycleError = exports.ChannelCursorRegressionError = exports.InvalidArgumentError = exports.InsufficientScopeError = exports.NotFoundError = exports.BackpressureError = exports.AuthError = exports.AlreadyPausingError = exports.AgentNotFoundError = exports.AgentIDInUseError = exports.AclDeniedError = exports.CLIENT_TOOL_SUBPROTOCOL = exports.clientToolsURL = exports.ClientToolHost = exports.verifyLoomcycleDelivery = exports.verifyLoomcycleSignature = exports.InteractiveSession = exports.LoomcycleClient = void 0;
|
|
212
|
+
exports.UnavailableError = exports.TokenLimitExceededError = exports.SubstrateToolRefusedError = exports.SnapshotVersionError = exports.SnapshotTooLargeError = exports.SnapshotNotFoundError = exports.SessionNotFoundError = exports.SessionBusyError = exports.RequestTooLargeError = exports.RateLimitedError = exports.PromptTooLargeError = exports.PerUserQuotaExhaustedError = exports.PauseNotConfiguredError = exports.OAuthError = exports.NotPausedError = exports.LoomcycleError = exports.ChannelCursorRegressionError = exports.InvalidArgumentError = exports.InsufficientScopeError = exports.NotFoundError = exports.DeviceLoginError = exports.BackpressureError = exports.AuthError = exports.AlreadyPausingError = exports.AgentNotFoundError = exports.AgentIDInUseError = exports.AclDeniedError = exports.pkceChallenge = exports.parseAuthorizeResponse = exports.OAuthTokenProvider = exports.LoomcycleOAuth = exports.CLIENT_TOOL_SUBPROTOCOL = exports.clientToolsURL = exports.ClientToolHost = exports.verifyLoomcycleDelivery = exports.verifyLoomcycleSignature = exports.InteractiveSession = exports.LoomcycleClient = void 0;
|
|
186
213
|
var client_js_1 = require("./client.js");
|
|
187
214
|
Object.defineProperty(exports, "LoomcycleClient", { enumerable: true, get: function () { return client_js_1.LoomcycleClient; } });
|
|
188
215
|
var interactive_js_1 = require("./interactive.js");
|
|
@@ -194,6 +221,11 @@ var client_tools_js_1 = require("./client-tools.js");
|
|
|
194
221
|
Object.defineProperty(exports, "ClientToolHost", { enumerable: true, get: function () { return client_tools_js_1.ClientToolHost; } });
|
|
195
222
|
Object.defineProperty(exports, "clientToolsURL", { enumerable: true, get: function () { return client_tools_js_1.clientToolsURL; } });
|
|
196
223
|
Object.defineProperty(exports, "CLIENT_TOOL_SUBPROTOCOL", { enumerable: true, get: function () { return client_tools_js_1.CLIENT_TOOL_SUBPROTOCOL; } });
|
|
224
|
+
var oauth_js_1 = require("./oauth.js");
|
|
225
|
+
Object.defineProperty(exports, "LoomcycleOAuth", { enumerable: true, get: function () { return oauth_js_1.LoomcycleOAuth; } });
|
|
226
|
+
Object.defineProperty(exports, "OAuthTokenProvider", { enumerable: true, get: function () { return oauth_js_1.OAuthTokenProvider; } });
|
|
227
|
+
Object.defineProperty(exports, "parseAuthorizeResponse", { enumerable: true, get: function () { return oauth_js_1.parseAuthorizeResponse; } });
|
|
228
|
+
Object.defineProperty(exports, "pkceChallenge", { enumerable: true, get: function () { return oauth_js_1.pkceChallenge; } });
|
|
197
229
|
var errors_js_1 = require("./errors.js");
|
|
198
230
|
Object.defineProperty(exports, "AclDeniedError", { enumerable: true, get: function () { return errors_js_1.AclDeniedError; } });
|
|
199
231
|
Object.defineProperty(exports, "AgentIDInUseError", { enumerable: true, get: function () { return errors_js_1.AgentIDInUseError; } });
|
|
@@ -201,12 +233,14 @@ Object.defineProperty(exports, "AgentNotFoundError", { enumerable: true, get: fu
|
|
|
201
233
|
Object.defineProperty(exports, "AlreadyPausingError", { enumerable: true, get: function () { return errors_js_1.AlreadyPausingError; } });
|
|
202
234
|
Object.defineProperty(exports, "AuthError", { enumerable: true, get: function () { return errors_js_1.AuthError; } });
|
|
203
235
|
Object.defineProperty(exports, "BackpressureError", { enumerable: true, get: function () { return errors_js_1.BackpressureError; } });
|
|
236
|
+
Object.defineProperty(exports, "DeviceLoginError", { enumerable: true, get: function () { return errors_js_1.DeviceLoginError; } });
|
|
204
237
|
Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_js_1.NotFoundError; } });
|
|
205
238
|
Object.defineProperty(exports, "InsufficientScopeError", { enumerable: true, get: function () { return errors_js_1.InsufficientScopeError; } });
|
|
206
239
|
Object.defineProperty(exports, "InvalidArgumentError", { enumerable: true, get: function () { return errors_js_1.InvalidArgumentError; } });
|
|
207
240
|
Object.defineProperty(exports, "ChannelCursorRegressionError", { enumerable: true, get: function () { return errors_js_1.ChannelCursorRegressionError; } });
|
|
208
241
|
Object.defineProperty(exports, "LoomcycleError", { enumerable: true, get: function () { return errors_js_1.LoomcycleError; } });
|
|
209
242
|
Object.defineProperty(exports, "NotPausedError", { enumerable: true, get: function () { return errors_js_1.NotPausedError; } });
|
|
243
|
+
Object.defineProperty(exports, "OAuthError", { enumerable: true, get: function () { return errors_js_1.OAuthError; } });
|
|
210
244
|
Object.defineProperty(exports, "PauseNotConfiguredError", { enumerable: true, get: function () { return errors_js_1.PauseNotConfiguredError; } });
|
|
211
245
|
Object.defineProperty(exports, "PerUserQuotaExhaustedError", { enumerable: true, get: function () { return errors_js_1.PerUserQuotaExhaustedError; } });
|
|
212
246
|
Object.defineProperty(exports, "PromptTooLargeError", { enumerable: true, get: function () { return errors_js_1.PromptTooLargeError; } });
|