@openchamber/sdk 2.5.3 → 2.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/API.md +13 -2
- package/DOCUMENTATION.md +60 -4
- package/GUEST_SERVICES.md +187 -4
- package/README.md +2 -2
- package/dist/host.d.ts +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +3 -2
- package/dist/manifest.d.ts +232 -6
- package/dist/manifest.js +110 -4
- package/dist/parse.d.ts +186 -0
- package/dist/parse.js +161 -6
- package/dist/protocol.d.ts +4 -0
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/dist/service-provider-schemas.d.ts +978 -0
- package/dist/service-provider-schemas.js +159 -1
- package/dist/service-providers.d.ts +422 -1
- package/dist/service-providers.js +311 -37
- package/dist/service-surface-schemas.d.ts +2 -0
- package/dist/service-surface-schemas.js +1 -0
- package/dist/service-surface.d.ts +5 -0
- package/dist/service-surface.js +5 -1
- package/dist/session-events.d.ts +161 -0
- package/dist/session-events.js +108 -0
- package/dist/ui/progress.d.ts +4 -0
- package/dist/ui/progress.js +17 -4
- package/dist/ui/style.js +23 -16
- package/dist/workspace-schemas.d.ts +1 -0
- package/dist/workspace-schemas.js +3 -1
- package/dist/workspace.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { BROWSER_CONTROL_ACTIONS, SOURCE_CONTROL_OUTBOUND_BODY_MAX, SOURCE_CONTROL_OUTBOUND_METHODS, SOURCE_CONTROL_OUTBOUND_REQUEST_HEADERS, SOURCE_CONTROL_PROVIDER_ERROR_MESSAGE_MAX, SOURCE_CONTROL_PROVIDER_METHODS, SOURCE_CONTROL_PROVIDER_RESPONSE_MAX, SOURCE_CONTROL_PROVIDER_TARGET_MAX, } from './service-providers.js';
|
|
2
|
+
import { BROWSER_CONTROL_ACTIONS, NOTIFICATIONS_PROVIDER_METHODS, SOURCE_CONTROL_OUTBOUND_BODY_MAX, SOURCE_CONTROL_OUTBOUND_METHODS, SOURCE_CONTROL_OUTBOUND_REQUEST_HEADERS, SOURCE_CONTROL_PROVIDER_ERROR_MESSAGE_MAX, SOURCE_CONTROL_PROVIDER_METHODS, SOURCE_CONTROL_PROVIDER_RESPONSE_MAX, SOURCE_CONTROL_PROVIDER_TARGET_MAX, TRACKER_PROVIDER_CONTAINERS_MAX, TRACKER_PROVIDER_LIST_MAX, TRACKER_PROVIDER_LIVE_SUMMARIES_MAX, TRACKER_PROVIDER_METHODS, } from './service-providers.js';
|
|
3
|
+
import { SESSION_EVENT_ERROR_MAX } from './session-events.js';
|
|
3
4
|
/**
|
|
4
5
|
* Host-side parse of what a browser provider answers. `data` stays whatever
|
|
5
6
|
* the service produced: the host hands it to the agent as is, and only
|
|
@@ -9,6 +10,19 @@ export const browserProviderResultSchema = z.union([
|
|
|
9
10
|
z.object({ ok: z.literal(true), data: z.object({}).passthrough() }),
|
|
10
11
|
z.object({ ok: z.literal(false), error: z.string().min(1).max(2_000) }),
|
|
11
12
|
]);
|
|
13
|
+
/**
|
|
14
|
+
* Host-side parse of what a service answers a session event with. OpenChamber
|
|
15
|
+
* acts on nothing in it beyond logging a failure's `error`; an answer that does
|
|
16
|
+
* not parse is a failed delivery, never a delivered one.
|
|
17
|
+
*/
|
|
18
|
+
export const sessionEventResultSchema = z.union([
|
|
19
|
+
z.object({ ok: z.literal(true) }).strict(),
|
|
20
|
+
z.object({ ok: z.literal(false), error: z.string().min(1).max(SESSION_EVENT_ERROR_MAX) }).strict(),
|
|
21
|
+
]);
|
|
22
|
+
const assertSessionEventResultParsed = (value) => value;
|
|
23
|
+
const assertSessionEventResultContract = (value) => value;
|
|
24
|
+
void assertSessionEventResultParsed;
|
|
25
|
+
void assertSessionEventResultContract;
|
|
12
26
|
export const browserControlActionSchema = z.enum(BROWSER_CONTROL_ACTIONS);
|
|
13
27
|
/*
|
|
14
28
|
* Host-side parse of what a source-control provider answers. Every answer is
|
|
@@ -230,3 +244,147 @@ export const sourceControlProviderSchemasV1 = {
|
|
|
230
244
|
data: dataSchemas,
|
|
231
245
|
};
|
|
232
246
|
export const sourceControlProviderMethodSchema = z.enum(SOURCE_CONTROL_PROVIDER_METHODS);
|
|
247
|
+
/*
|
|
248
|
+
* Host-side parse of what a notifications provider answers. The envelope and
|
|
249
|
+
* the error are the Git host's: `ok: true` with `data`, or `ok: false` with
|
|
250
|
+
* `{ message, status?, code? }`, and a 401 writes the account off only when
|
|
251
|
+
* OpenChamber's proxy saw the channel's server answer it.
|
|
252
|
+
*/
|
|
253
|
+
const notificationsAccountSchema = z.object({
|
|
254
|
+
account: z.object({
|
|
255
|
+
id: z.string().min(1).max(256),
|
|
256
|
+
login: z.string().min(1).max(256),
|
|
257
|
+
name: optionalText,
|
|
258
|
+
}),
|
|
259
|
+
});
|
|
260
|
+
const notificationsNotifySchema = z.object({ delivered: z.literal(true) }).strict();
|
|
261
|
+
const notificationsDataSchemas = {
|
|
262
|
+
'auth.verify': notificationsAccountSchema,
|
|
263
|
+
'auth.probe': probeSchema,
|
|
264
|
+
notify: notificationsNotifySchema,
|
|
265
|
+
};
|
|
266
|
+
/** Wire 1 of the notifications role, as the host parses it. `data[method]` checks an `ok: true` answer's `data`. */
|
|
267
|
+
export const notificationsProviderSchemasV1 = {
|
|
268
|
+
envelope: envelopeSchema,
|
|
269
|
+
error: errorSchema,
|
|
270
|
+
account: notificationsAccountSchema,
|
|
271
|
+
probe: probeSchema,
|
|
272
|
+
notify: notificationsNotifySchema,
|
|
273
|
+
outboundRequest: outboundRequestSchema,
|
|
274
|
+
data: notificationsDataSchemas,
|
|
275
|
+
};
|
|
276
|
+
export const notificationsProviderMethodSchema = z.enum(NOTIFICATIONS_PROVIDER_METHODS);
|
|
277
|
+
/*
|
|
278
|
+
* Host-side parse of what a tracker answers. The envelope and the error are
|
|
279
|
+
* the Git host's. Every item is checked in the neutral shapes before the host
|
|
280
|
+
* hands it to the UI, bounded in count and length, and asserted against the
|
|
281
|
+
* TypeScript types the service writes against, so the two cannot drift. A
|
|
282
|
+
* failed parse is a malformed answer, never an empty list.
|
|
283
|
+
*/
|
|
284
|
+
const trackerText = z.string().min(1).max(1_024);
|
|
285
|
+
const trackerTitle = z.string().max(4_096);
|
|
286
|
+
// An item's link is opened and drawn as a link in the app: http(s) only, so an answer cannot hand the UI a `javascript:` URL.
|
|
287
|
+
const trackerUrl = z.string().min(1).max(2_048).refine((value) => /^https?:\/\//i.test(value) && URL.canParse(value), { message: 'must be an http(s) URL' });
|
|
288
|
+
const trackerCategory = z.enum(['triage', 'backlog', 'todo', 'in-progress', 'done', 'canceled']);
|
|
289
|
+
const trackerPriority = z.enum(['none', 'urgent', 'high', 'medium', 'low']);
|
|
290
|
+
const trackerPerson = z.object({ name: z.string().max(256).nullable(), avatarUrl: z.string().max(2_048).nullable() }).strict();
|
|
291
|
+
const trackerContainer = z.object({ id: trackerText, key: z.string().max(64).nullable(), name: z.string().min(1).max(256) }).strict();
|
|
292
|
+
const trackerState = z.object({ id: trackerText.nullable(), name: z.string().max(256), category: trackerCategory.nullable() }).strict();
|
|
293
|
+
const trackerItemFields = {
|
|
294
|
+
id: trackerText,
|
|
295
|
+
identifier: z.string().min(1).max(128),
|
|
296
|
+
title: trackerTitle,
|
|
297
|
+
url: trackerUrl,
|
|
298
|
+
state: trackerState.nullable(),
|
|
299
|
+
priority: trackerPriority.nullable().optional(),
|
|
300
|
+
labels: z.array(z.object({ id: trackerText, name: z.string().min(1).max(256), color: z.string().max(32).nullable() }).strict()).max(TRACKER_PROVIDER_LIST_MAX).optional(),
|
|
301
|
+
assignee: trackerPerson.nullable().optional(),
|
|
302
|
+
container: trackerContainer.nullable().optional(),
|
|
303
|
+
progress: z.object({ total: z.number().int().nonnegative(), done: z.number().int().nonnegative(), more: z.boolean() }).strict().nullable().optional(),
|
|
304
|
+
updatedAt: z.string().max(64).nullable().optional(),
|
|
305
|
+
};
|
|
306
|
+
/** A related item (a parent, a child): one level deep, naming no parent of its own (`null` at most). */
|
|
307
|
+
const trackerRelatedItemSchema = z.object({ ...trackerItemFields, parent: z.null().optional() }).strict();
|
|
308
|
+
const trackerItemSummarySchema = z.object({ ...trackerItemFields, parent: trackerRelatedItemSchema.nullable().optional() }).strict();
|
|
309
|
+
const trackerCommentSchema = z.object({
|
|
310
|
+
id: trackerText,
|
|
311
|
+
body: z.string().max(65_536),
|
|
312
|
+
createdAt: z.string().max(64).nullable(),
|
|
313
|
+
author: trackerPerson.nullable(),
|
|
314
|
+
}).strict();
|
|
315
|
+
const trackerItemSchema = trackerItemSummarySchema.extend({
|
|
316
|
+
description: z.string().max(262_144).nullable().optional(),
|
|
317
|
+
comments: z.array(trackerCommentSchema).max(TRACKER_PROVIDER_LIST_MAX).optional(),
|
|
318
|
+
children: z.array(trackerRelatedItemSchema).max(TRACKER_PROVIDER_LIST_MAX).optional(),
|
|
319
|
+
childrenMore: z.boolean().optional(),
|
|
320
|
+
}).strict();
|
|
321
|
+
const trackerAccountSchema = z.object({
|
|
322
|
+
account: z.object({
|
|
323
|
+
id: z.string().min(1).max(256),
|
|
324
|
+
login: z.string().min(1).max(256).nullable(),
|
|
325
|
+
name: optionalText,
|
|
326
|
+
avatarUrl: z.string().max(2_048).optional(),
|
|
327
|
+
}).strict(),
|
|
328
|
+
}).strict();
|
|
329
|
+
const trackerListSchema = z.object({
|
|
330
|
+
items: z.array(trackerItemSummarySchema).max(TRACKER_PROVIDER_LIST_MAX),
|
|
331
|
+
cursor: z.string().min(1).max(2_048).nullable(),
|
|
332
|
+
hasMore: z.boolean(),
|
|
333
|
+
}).strict();
|
|
334
|
+
const trackerItemDataSchema = z.object({ item: trackerItemSchema.nullable() }).strict();
|
|
335
|
+
const trackerStatesSchema = z.object({
|
|
336
|
+
states: z.array(z.object({ id: trackerText, name: z.string().min(1).max(256), category: trackerCategory.nullable(), position: z.number() }).strict()).max(TRACKER_PROVIDER_LIST_MAX * 2),
|
|
337
|
+
}).strict();
|
|
338
|
+
const trackerLiveSummariesSchema = z.object({
|
|
339
|
+
items: z.array(z.object({
|
|
340
|
+
identifier: z.string().min(1).max(128),
|
|
341
|
+
title: trackerTitle,
|
|
342
|
+
state: z.object({ name: z.string().max(256), category: trackerCategory }).strict(),
|
|
343
|
+
}).strict()).max(TRACKER_PROVIDER_LIVE_SUMMARIES_MAX),
|
|
344
|
+
}).strict();
|
|
345
|
+
const trackerContainersSchema = z.object({ containers: z.array(trackerContainer).max(TRACKER_PROVIDER_CONTAINERS_MAX) }).strict();
|
|
346
|
+
const trackerCommentDataSchema = z.object({ comment: z.object({ id: trackerText }).strict().nullable() }).strict();
|
|
347
|
+
const assertTrackerSummary = (value) => value;
|
|
348
|
+
const assertTrackerItem = (value) => value;
|
|
349
|
+
const assertTrackerAccount = (value) => value;
|
|
350
|
+
const assertTrackerList = (value) => value;
|
|
351
|
+
const assertTrackerItemData = (value) => value;
|
|
352
|
+
const assertTrackerStates = (value) => value;
|
|
353
|
+
const assertTrackerLive = (value) => value;
|
|
354
|
+
const assertTrackerContainers = (value) => value;
|
|
355
|
+
void assertTrackerSummary;
|
|
356
|
+
void assertTrackerItem;
|
|
357
|
+
void assertTrackerAccount;
|
|
358
|
+
void assertTrackerList;
|
|
359
|
+
void assertTrackerItemData;
|
|
360
|
+
void assertTrackerStates;
|
|
361
|
+
void assertTrackerLive;
|
|
362
|
+
void assertTrackerContainers;
|
|
363
|
+
const trackerDataSchemas = {
|
|
364
|
+
'auth.probe': probeSchema,
|
|
365
|
+
'auth.verify': trackerAccountSchema,
|
|
366
|
+
'items.list': trackerListSchema,
|
|
367
|
+
'items.get': trackerItemDataSchema,
|
|
368
|
+
'items.updateState': trackerItemDataSchema,
|
|
369
|
+
'items.liveSummaries': trackerLiveSummariesSchema,
|
|
370
|
+
'states.list': trackerStatesSchema,
|
|
371
|
+
'containers.list': trackerContainersSchema,
|
|
372
|
+
'comments.create': trackerCommentDataSchema,
|
|
373
|
+
};
|
|
374
|
+
/** Wire 1 of the tracker role, as the host parses it. `data[method]` checks an `ok: true` answer's `data`. */
|
|
375
|
+
export const trackerProviderSchemasV1 = {
|
|
376
|
+
envelope: envelopeSchema,
|
|
377
|
+
error: errorSchema,
|
|
378
|
+
account: trackerAccountSchema,
|
|
379
|
+
probe: probeSchema,
|
|
380
|
+
itemSummary: trackerItemSummarySchema,
|
|
381
|
+
item: trackerItemSchema,
|
|
382
|
+
list: trackerListSchema,
|
|
383
|
+
states: trackerStatesSchema,
|
|
384
|
+
liveSummaries: trackerLiveSummariesSchema,
|
|
385
|
+
containers: trackerContainersSchema,
|
|
386
|
+
comment: trackerCommentDataSchema,
|
|
387
|
+
outboundRequest: outboundRequestSchema,
|
|
388
|
+
data: trackerDataSchemas,
|
|
389
|
+
};
|
|
390
|
+
export const trackerProviderMethodSchema = z.enum(TRACKER_PROVIDER_METHODS);
|
|
@@ -308,7 +308,8 @@ export declare const sourceControlProviderTimeoutMs: (method: SourceControlProvi
|
|
|
308
308
|
/**
|
|
309
309
|
* Environment variable with the base URL of OpenChamber's callback listener
|
|
310
310
|
* (`http://127.0.0.1:<port>`). Set only for a service that provides
|
|
311
|
-
* `source-control
|
|
311
|
+
* `source-control`, `notifications` or `tracker`; `createSourceControlForge`,
|
|
312
|
+
* `createNotificationsOutbound` and `createTrackerOutbound` read it.
|
|
312
313
|
*/
|
|
313
314
|
export declare const OPENCHAMBER_HOST_CALLBACK_URL = "OPENCHAMBER_HOST_CALLBACK_URL";
|
|
314
315
|
/** Route on the callback listener a service sends a forge request to. */
|
|
@@ -622,4 +623,424 @@ export type SourceControlForge = {
|
|
|
622
623
|
export declare const createSourceControlForge: ({ env }: {
|
|
623
624
|
env: Record<string, string | undefined>;
|
|
624
625
|
}) => SourceControlForge;
|
|
626
|
+
/** Route on the service loopback OpenChamber posts every notifications call to. */
|
|
627
|
+
export declare const NOTIFICATIONS_PROVIDER_PATH = "/notifications";
|
|
628
|
+
/** The `v` of every request; a service answers a version it does not know with HTTP 400. */
|
|
629
|
+
export declare const NOTIFICATIONS_PROVIDER_WIRE_VERSION = 1;
|
|
630
|
+
/**
|
|
631
|
+
* `auth.verify` reads who a candidate token belongs to, `auth.probe` whether
|
|
632
|
+
* an instance is this channel's server, `notify` delivers one notification.
|
|
633
|
+
*/
|
|
634
|
+
export declare const NOTIFICATIONS_PROVIDER_METHODS: readonly ['auth.verify', 'auth.probe', 'notify'];
|
|
635
|
+
export type NotificationsProviderMethod = (typeof NOTIFICATIONS_PROVIDER_METHODS)[number];
|
|
636
|
+
/** A notification is delivered within this deadline; a slower service drops it. */
|
|
637
|
+
export declare const NOTIFICATIONS_PROVIDER_NOTIFY_TIMEOUT_MS = 10000;
|
|
638
|
+
export declare const NOTIFICATIONS_PROVIDER_AUTH_TIMEOUT_MS = 15000;
|
|
639
|
+
/** Bytes of an answer OpenChamber reads. */
|
|
640
|
+
export declare const NOTIFICATIONS_PROVIDER_RESPONSE_MAX = 16000;
|
|
641
|
+
/** Characters of `error.message` OpenChamber reads. */
|
|
642
|
+
export declare const NOTIFICATIONS_PROVIDER_ERROR_MESSAGE_MAX = 2000;
|
|
643
|
+
/** No call for this long stops the service; the next call starts it again. */
|
|
644
|
+
export declare const NOTIFICATIONS_PROVIDER_IDLE_MS: number;
|
|
645
|
+
/** Route on the callback listener a service sends the channel's requests to. */
|
|
646
|
+
export declare const NOTIFICATIONS_OUTBOUND_PATH = "/notifications/outbound";
|
|
647
|
+
/** One outbound request may take this long; the call's own deadline may end it sooner. */
|
|
648
|
+
export declare const NOTIFICATIONS_OUTBOUND_TIMEOUT_MS = 20000;
|
|
649
|
+
export declare const notificationsProviderTimeoutMs: (method: NotificationsProviderMethod) => number;
|
|
650
|
+
/**
|
|
651
|
+
* The kinds OpenChamber notifies about. `ready`: the agent finished; `error`:
|
|
652
|
+
* the turn failed; `question` and `permission`: the agent waits for the user;
|
|
653
|
+
* `review`: an auto-review ended; the `goal_*` kinds: a session goal settled.
|
|
654
|
+
* Which kinds reach a channel follows the user's own notification toggles.
|
|
655
|
+
*/
|
|
656
|
+
export declare const GUEST_NOTIFICATION_KINDS: readonly ['ready', 'error', 'question', 'permission', 'review', 'goal_complete', 'goal_blocked', 'goal_budget'];
|
|
657
|
+
export type GuestNotificationKind = (typeof GUEST_NOTIFICATION_KINDS)[number];
|
|
658
|
+
/**
|
|
659
|
+
* One notification as OpenChamber shows it, after the user's templates. In
|
|
660
|
+
* enterprise mode `title` is the kind's generic title and `body`,
|
|
661
|
+
* `sessionName` and `directory` are empty, as they are for the phone.
|
|
662
|
+
*/
|
|
663
|
+
export type GuestNotification = {
|
|
664
|
+
kind: GuestNotificationKind;
|
|
665
|
+
title: string;
|
|
666
|
+
body: string;
|
|
667
|
+
/** Groups repeats of one thing (`ready-<sessionId>`): a later one may replace an earlier one where the channel can. */
|
|
668
|
+
tag: string;
|
|
669
|
+
/** Epoch milliseconds. */
|
|
670
|
+
at: number;
|
|
671
|
+
sessionId: string | null;
|
|
672
|
+
sessionName: string | null;
|
|
673
|
+
directory: string | null;
|
|
674
|
+
/** The link that opens the session in OpenChamber, when there is one. */
|
|
675
|
+
url: string | null;
|
|
676
|
+
};
|
|
677
|
+
/** The connected account a call acts as; `null` in `auth.verify` and `auth.probe`, before one exists. */
|
|
678
|
+
export type NotificationsProviderAccount = {
|
|
679
|
+
id: string;
|
|
680
|
+
login: string | null;
|
|
681
|
+
};
|
|
682
|
+
/**
|
|
683
|
+
* Who a call is for. `instance` is the account's origin (`https://slack.com`,
|
|
684
|
+
* a Matrix homeserver). `handle` is the capability for this one call: pass it
|
|
685
|
+
* to `createNotificationsOutbound(...).request`. It stops working when the
|
|
686
|
+
* call ends; never store it.
|
|
687
|
+
*/
|
|
688
|
+
export type NotificationsProviderSession = {
|
|
689
|
+
instance: string;
|
|
690
|
+
handle: string;
|
|
691
|
+
account: NotificationsProviderAccount | null;
|
|
692
|
+
};
|
|
693
|
+
/** What each method's `input` holds. */
|
|
694
|
+
export type NotificationsProviderInputs = {
|
|
695
|
+
'auth.verify': Record<string, never>;
|
|
696
|
+
'auth.probe': Record<string, never>;
|
|
697
|
+
notify: {
|
|
698
|
+
notification: GuestNotification;
|
|
699
|
+
};
|
|
700
|
+
};
|
|
701
|
+
/**
|
|
702
|
+
* One call, as OpenChamber posts it. `provider` is the id OpenChamber gave
|
|
703
|
+
* this channel (`ext-<panel.id>`). `input` was built by OpenChamber; its shape
|
|
704
|
+
* per method is `NotificationsProviderInputs`.
|
|
705
|
+
*/
|
|
706
|
+
export type NotificationsProviderRequest = {
|
|
707
|
+
v: typeof NOTIFICATIONS_PROVIDER_WIRE_VERSION;
|
|
708
|
+
requestId: string;
|
|
709
|
+
method: NotificationsProviderMethod;
|
|
710
|
+
provider: string;
|
|
711
|
+
session: NotificationsProviderSession;
|
|
712
|
+
input: SourceControlJsonObject;
|
|
713
|
+
};
|
|
714
|
+
/** Who the candidate token belongs to; OpenChamber stores the account under `id`. */
|
|
715
|
+
export type NotificationsAccountData = {
|
|
716
|
+
account: {
|
|
717
|
+
id: string;
|
|
718
|
+
login: string;
|
|
719
|
+
name?: string;
|
|
720
|
+
};
|
|
721
|
+
};
|
|
722
|
+
export type NotificationsProbeData = {
|
|
723
|
+
supported: boolean;
|
|
724
|
+
message?: string;
|
|
725
|
+
};
|
|
726
|
+
export type NotificationsNotifyData = {
|
|
727
|
+
delivered: true;
|
|
728
|
+
};
|
|
729
|
+
/**
|
|
730
|
+
* An answer. `error.status` is the HTTP status OpenChamber should treat the
|
|
731
|
+
* failure as; a 401 writes the account off only when OpenChamber's proxy saw
|
|
732
|
+
* the channel's server answer 401 itself. `error.code` is `[A-Z_]{1,64}`.
|
|
733
|
+
*/
|
|
734
|
+
export type NotificationsProviderError = SourceControlProviderError;
|
|
735
|
+
export type NotificationsProviderResult = {
|
|
736
|
+
ok: true;
|
|
737
|
+
data: SourceControlJson;
|
|
738
|
+
} | {
|
|
739
|
+
ok: false;
|
|
740
|
+
error: NotificationsProviderError;
|
|
741
|
+
};
|
|
742
|
+
export declare const isNotificationsProviderMethod: (value: string) => value is NotificationsProviderMethod;
|
|
743
|
+
/**
|
|
744
|
+
* A service's read of the body OpenChamber posted to
|
|
745
|
+
* `NOTIFICATIONS_PROVIDER_PATH`. OpenChamber built `input`, so this checks the
|
|
746
|
+
* envelope, not every field, and the service bundle needs no schema library.
|
|
747
|
+
* `null` is a body that is not a notifications call of this wire version;
|
|
748
|
+
* answer it with HTTP 400.
|
|
749
|
+
*/
|
|
750
|
+
export declare const readNotificationsProviderRequest: (body: string) => NotificationsProviderRequest | null;
|
|
751
|
+
/**
|
|
752
|
+
* OpenChamber refused the request (an expired handle, a path off the
|
|
753
|
+
* instance, a body too large), could not reach the channel's server, or did
|
|
754
|
+
* not answer. `status` is the callback listener's HTTP status, `0` when it
|
|
755
|
+
* gave none; `code` is its error code (`HOST_UNAVAILABLE` when there was no
|
|
756
|
+
* usable answer).
|
|
757
|
+
*/
|
|
758
|
+
export declare class NotificationsOutboundError extends Error {
|
|
759
|
+
readonly code: string;
|
|
760
|
+
readonly status: number;
|
|
761
|
+
constructor(message: string, code: string, status: number);
|
|
762
|
+
}
|
|
763
|
+
export type NotificationsOutbound = {
|
|
764
|
+
/** Sends `request` to the server of the account `handle` belongs to, with the stored token when the call has one. */
|
|
765
|
+
request(handle: string, request: SourceControlOutboundRequest): Promise<SourceControlOutboundResponse>;
|
|
766
|
+
};
|
|
767
|
+
/**
|
|
768
|
+
* The service's way to the channel's server: OpenChamber's callback listener
|
|
769
|
+
* (`OPENCHAMBER_HOST_CALLBACK_URL`), which checks the handle, keeps the
|
|
770
|
+
* request on the account's origin and adds the token. Plain `fetch`, no
|
|
771
|
+
* dependencies. Throws `NotificationsOutboundError` when OpenChamber refuses
|
|
772
|
+
* the request; an answer of any status from the server resolves.
|
|
773
|
+
*/
|
|
774
|
+
export declare const createNotificationsOutbound: ({ env }: {
|
|
775
|
+
env: Record<string, string | undefined>;
|
|
776
|
+
}) => NotificationsOutbound;
|
|
777
|
+
/** Route on the service loopback OpenChamber posts every tracker call to. */
|
|
778
|
+
export declare const TRACKER_PROVIDER_PATH = "/tracker";
|
|
779
|
+
/** The `v` of every request; a service answers a version it does not know with HTTP 400. */
|
|
780
|
+
export declare const TRACKER_PROVIDER_WIRE_VERSION = 1;
|
|
781
|
+
/**
|
|
782
|
+
* Every call OpenChamber forwards. `auth.probe` asks whether an instance is
|
|
783
|
+
* this tracker's server, `auth.verify` who a credential belongs to (the handle
|
|
784
|
+
* carries a pasted token or an OAuth access token); the reads answer in the
|
|
785
|
+
* neutral shapes; `items.updateState` and `comments.create` are the two
|
|
786
|
+
* writes, the only calls whose handle may send anything but `GET`.
|
|
787
|
+
*/
|
|
788
|
+
export declare const TRACKER_PROVIDER_METHODS: readonly ['auth.probe', 'auth.verify', 'items.list', 'items.get', 'items.updateState', 'items.liveSummaries', 'states.list', 'containers.list', 'comments.create'];
|
|
789
|
+
export type TrackerProviderMethod = (typeof TRACKER_PROVIDER_METHODS)[number];
|
|
790
|
+
/** The calls that change something on the tracker. */
|
|
791
|
+
export declare const TRACKER_PROVIDER_WRITE_METHODS: readonly ["items.updateState", "comments.create"];
|
|
792
|
+
export declare const TRACKER_PROVIDER_AUTH_TIMEOUT_MS = 15000;
|
|
793
|
+
export declare const TRACKER_PROVIDER_READ_TIMEOUT_MS = 20000;
|
|
794
|
+
export declare const TRACKER_PROVIDER_WRITE_TIMEOUT_MS = 30000;
|
|
795
|
+
/** Bytes of an answer OpenChamber reads: a page of items with their labels and people. */
|
|
796
|
+
export declare const TRACKER_PROVIDER_RESPONSE_MAX = 2000000;
|
|
797
|
+
/** Characters of `error.message` OpenChamber reads. */
|
|
798
|
+
export declare const TRACKER_PROVIDER_ERROR_MESSAGE_MAX = 2000;
|
|
799
|
+
/** No call for this long stops the service; the next call starts it again. */
|
|
800
|
+
export declare const TRACKER_PROVIDER_IDLE_MS: number;
|
|
801
|
+
/** Items in one `items.list` page, children or comments of one item, states of one container. */
|
|
802
|
+
export declare const TRACKER_PROVIDER_LIST_MAX = 100;
|
|
803
|
+
/** Identifiers in one `items.liveSummaries` call. */
|
|
804
|
+
export declare const TRACKER_PROVIDER_LIVE_SUMMARIES_MAX = 50;
|
|
805
|
+
/** Containers in one `containers.list` answer. */
|
|
806
|
+
export declare const TRACKER_PROVIDER_CONTAINERS_MAX = 500;
|
|
807
|
+
/** Route on the callback listener a service sends the tracker's requests to. */
|
|
808
|
+
export declare const TRACKER_OUTBOUND_PATH = "/tracker/outbound";
|
|
809
|
+
/** One outbound request may take this long; the call's own deadline may end it sooner. */
|
|
810
|
+
export declare const TRACKER_OUTBOUND_TIMEOUT_MS = 20000;
|
|
811
|
+
export declare const isTrackerProviderWriteMethod: (method: TrackerProviderMethod) => boolean;
|
|
812
|
+
/** How long OpenChamber waits for the service to answer `method`. */
|
|
813
|
+
export declare const trackerProviderTimeoutMs: (method: TrackerProviderMethod) => number;
|
|
814
|
+
export type TrackerProviderStateCategory = 'triage' | 'backlog' | 'todo' | 'in-progress' | 'done' | 'canceled';
|
|
815
|
+
export type TrackerProviderPriority = 'none' | 'urgent' | 'high' | 'medium' | 'low';
|
|
816
|
+
export type TrackerProviderPerson = {
|
|
817
|
+
name: string | null;
|
|
818
|
+
avatarUrl: string | null;
|
|
819
|
+
};
|
|
820
|
+
export type TrackerProviderItemState = {
|
|
821
|
+
id: string | null;
|
|
822
|
+
name: string;
|
|
823
|
+
category: TrackerProviderStateCategory | null;
|
|
824
|
+
};
|
|
825
|
+
export type TrackerProviderContainer = {
|
|
826
|
+
id: string;
|
|
827
|
+
key: string | null;
|
|
828
|
+
name: string;
|
|
829
|
+
};
|
|
830
|
+
export type TrackerProviderLabel = {
|
|
831
|
+
id: string;
|
|
832
|
+
name: string;
|
|
833
|
+
color: string | null;
|
|
834
|
+
};
|
|
835
|
+
/** Only the first few children are counted; `more` says there are others. */
|
|
836
|
+
export type TrackerProviderProgress = {
|
|
837
|
+
total: number;
|
|
838
|
+
done: number;
|
|
839
|
+
more: boolean;
|
|
840
|
+
};
|
|
841
|
+
/** One item in a list, or a related item (a parent, a child), which carries no labels or progress of its own. */
|
|
842
|
+
export type TrackerProviderItemSummary = {
|
|
843
|
+
/** The tracker's stable id; what `items.get` and `items.updateState` take. */
|
|
844
|
+
id: string;
|
|
845
|
+
/** Human key (`PROJ-42`), the shape `contributes.tracker.identifier` declares; compared case-insensitively. */
|
|
846
|
+
identifier: string;
|
|
847
|
+
title: string;
|
|
848
|
+
url: string;
|
|
849
|
+
state: TrackerProviderItemState | null;
|
|
850
|
+
priority?: TrackerProviderPriority | null;
|
|
851
|
+
labels?: TrackerProviderLabel[];
|
|
852
|
+
assignee?: TrackerProviderPerson | null;
|
|
853
|
+
container?: TrackerProviderContainer | null;
|
|
854
|
+
parent?: TrackerProviderItemSummary | null;
|
|
855
|
+
progress?: TrackerProviderProgress | null;
|
|
856
|
+
/** ISO 8601. */
|
|
857
|
+
updatedAt?: string | null;
|
|
858
|
+
};
|
|
859
|
+
export type TrackerProviderComment = {
|
|
860
|
+
id: string;
|
|
861
|
+
body: string;
|
|
862
|
+
createdAt: string | null;
|
|
863
|
+
author: TrackerProviderPerson | null;
|
|
864
|
+
};
|
|
865
|
+
export type TrackerProviderItem = TrackerProviderItemSummary & {
|
|
866
|
+
description?: string | null;
|
|
867
|
+
comments?: TrackerProviderComment[];
|
|
868
|
+
/** The first page of children in the tracker's order; `childrenMore` says there are others. */
|
|
869
|
+
children?: TrackerProviderItemSummary[];
|
|
870
|
+
childrenMore?: boolean;
|
|
871
|
+
};
|
|
872
|
+
export type TrackerProviderWorkflowState = {
|
|
873
|
+
id: string;
|
|
874
|
+
name: string;
|
|
875
|
+
category: TrackerProviderStateCategory | null;
|
|
876
|
+
position: number;
|
|
877
|
+
};
|
|
878
|
+
export type TrackerProviderLiveSummary = {
|
|
879
|
+
identifier: string;
|
|
880
|
+
title: string;
|
|
881
|
+
state: {
|
|
882
|
+
name: string;
|
|
883
|
+
category: TrackerProviderStateCategory;
|
|
884
|
+
};
|
|
885
|
+
};
|
|
886
|
+
/** The connected account a call acts as; `null` in `auth.verify` and `auth.probe`, before one exists. */
|
|
887
|
+
export type TrackerProviderAccount = {
|
|
888
|
+
id: string;
|
|
889
|
+
login: string | null;
|
|
890
|
+
};
|
|
891
|
+
/**
|
|
892
|
+
* Who a call is for. `instance` is the account's origin (the tracker's one
|
|
893
|
+
* address, or the server the user typed). `handle` is the capability for this
|
|
894
|
+
* one call: pass it to `createTrackerOutbound(...).request`. It stops working
|
|
895
|
+
* when the call ends; never store it.
|
|
896
|
+
*/
|
|
897
|
+
export type TrackerProviderSession = {
|
|
898
|
+
instance: string;
|
|
899
|
+
handle: string;
|
|
900
|
+
account: TrackerProviderAccount | null;
|
|
901
|
+
};
|
|
902
|
+
/** What each method's `input` holds. OpenChamber built and checked every field. */
|
|
903
|
+
export type TrackerProviderInputs = {
|
|
904
|
+
'auth.probe': Record<string, never>;
|
|
905
|
+
'auth.verify': Record<string, never>;
|
|
906
|
+
'items.list': {
|
|
907
|
+
query?: string;
|
|
908
|
+
cursor?: string;
|
|
909
|
+
/** One of the manifest's `stateFilters`. */
|
|
910
|
+
state: string;
|
|
911
|
+
people: 'any' | 'me' | 'created';
|
|
912
|
+
priority: 'all' | TrackerProviderPriority;
|
|
913
|
+
containerId: string | null;
|
|
914
|
+
};
|
|
915
|
+
'items.get': {
|
|
916
|
+
id: string;
|
|
917
|
+
};
|
|
918
|
+
'items.updateState': {
|
|
919
|
+
id: string;
|
|
920
|
+
stateId: string;
|
|
921
|
+
};
|
|
922
|
+
'items.liveSummaries': {
|
|
923
|
+
identifiers: string[];
|
|
924
|
+
};
|
|
925
|
+
'states.list': {
|
|
926
|
+
containerId: string;
|
|
927
|
+
};
|
|
928
|
+
'containers.list': Record<string, never>;
|
|
929
|
+
/** `body` is Markdown OpenChamber wrote: "OpenChamber session completed" with a link to the session. */
|
|
930
|
+
'comments.create': {
|
|
931
|
+
identifier: string;
|
|
932
|
+
body: string;
|
|
933
|
+
};
|
|
934
|
+
};
|
|
935
|
+
/**
|
|
936
|
+
* One call, as OpenChamber posts it. `provider` is the id OpenChamber gave
|
|
937
|
+
* this tracker (`ext-<panel.id>`). `input` was built by OpenChamber; its shape
|
|
938
|
+
* per method is `TrackerProviderInputs`.
|
|
939
|
+
*/
|
|
940
|
+
export type TrackerProviderRequest = {
|
|
941
|
+
v: typeof TRACKER_PROVIDER_WIRE_VERSION;
|
|
942
|
+
requestId: string;
|
|
943
|
+
method: TrackerProviderMethod;
|
|
944
|
+
provider: string;
|
|
945
|
+
session: TrackerProviderSession;
|
|
946
|
+
input: SourceControlJsonObject;
|
|
947
|
+
};
|
|
948
|
+
/** Who the credential belongs to; OpenChamber stores the account under `id` and shows `name`. */
|
|
949
|
+
export type TrackerProviderAccountData = {
|
|
950
|
+
account: {
|
|
951
|
+
id: string;
|
|
952
|
+
login: string | null;
|
|
953
|
+
name?: string;
|
|
954
|
+
avatarUrl?: string;
|
|
955
|
+
};
|
|
956
|
+
};
|
|
957
|
+
export type TrackerProviderProbeData = {
|
|
958
|
+
supported: boolean;
|
|
959
|
+
message?: string;
|
|
960
|
+
};
|
|
961
|
+
export type TrackerProviderListData = {
|
|
962
|
+
items: TrackerProviderItemSummary[];
|
|
963
|
+
cursor: string | null;
|
|
964
|
+
hasMore: boolean;
|
|
965
|
+
};
|
|
966
|
+
/** `item` is null when the tracker has no such item. */
|
|
967
|
+
export type TrackerProviderItemData = {
|
|
968
|
+
item: TrackerProviderItem | null;
|
|
969
|
+
};
|
|
970
|
+
export type TrackerProviderStatesData = {
|
|
971
|
+
states: TrackerProviderWorkflowState[];
|
|
972
|
+
};
|
|
973
|
+
/** Identifiers the tracker does not know are left out. */
|
|
974
|
+
export type TrackerProviderLiveSummariesData = {
|
|
975
|
+
items: TrackerProviderLiveSummary[];
|
|
976
|
+
};
|
|
977
|
+
export type TrackerProviderContainersData = {
|
|
978
|
+
containers: TrackerProviderContainer[];
|
|
979
|
+
};
|
|
980
|
+
/** `comment` is null when the item was not found. */
|
|
981
|
+
export type TrackerProviderCommentData = {
|
|
982
|
+
comment: {
|
|
983
|
+
id: string;
|
|
984
|
+
} | null;
|
|
985
|
+
};
|
|
986
|
+
/** What each method answers in `data`. */
|
|
987
|
+
export type TrackerProviderDataByMethod = {
|
|
988
|
+
'auth.probe': TrackerProviderProbeData;
|
|
989
|
+
'auth.verify': TrackerProviderAccountData;
|
|
990
|
+
'items.list': TrackerProviderListData;
|
|
991
|
+
'items.get': TrackerProviderItemData;
|
|
992
|
+
'items.updateState': TrackerProviderItemData;
|
|
993
|
+
'items.liveSummaries': TrackerProviderLiveSummariesData;
|
|
994
|
+
'states.list': TrackerProviderStatesData;
|
|
995
|
+
'containers.list': TrackerProviderContainersData;
|
|
996
|
+
'comments.create': TrackerProviderCommentData;
|
|
997
|
+
};
|
|
998
|
+
/**
|
|
999
|
+
* An answer. `error.status` is the HTTP status OpenChamber should treat the
|
|
1000
|
+
* failure as; a 401 writes the account off only when OpenChamber's proxy saw
|
|
1001
|
+
* the tracker's server answer 401 itself. `error.code` is `[A-Z_]{1,64}`.
|
|
1002
|
+
*/
|
|
1003
|
+
export type TrackerProviderError = SourceControlProviderError;
|
|
1004
|
+
export type TrackerProviderResult = {
|
|
1005
|
+
ok: true;
|
|
1006
|
+
data: SourceControlJson;
|
|
1007
|
+
} | {
|
|
1008
|
+
ok: false;
|
|
1009
|
+
error: TrackerProviderError;
|
|
1010
|
+
};
|
|
1011
|
+
export declare const isTrackerProviderMethod: (value: string) => value is TrackerProviderMethod;
|
|
1012
|
+
/**
|
|
1013
|
+
* A service's read of the body OpenChamber posted to `TRACKER_PROVIDER_PATH`.
|
|
1014
|
+
* OpenChamber built `input`, so this checks the envelope, not every field, and
|
|
1015
|
+
* the service bundle needs no schema library. `null` is a body that is not a
|
|
1016
|
+
* tracker call of this wire version; answer it with HTTP 400.
|
|
1017
|
+
*/
|
|
1018
|
+
export declare const readTrackerProviderRequest: (body: string) => TrackerProviderRequest | null;
|
|
1019
|
+
/**
|
|
1020
|
+
* OpenChamber refused the request (an expired handle, a path off the
|
|
1021
|
+
* instance, a body too large, a write through a read's handle), could not
|
|
1022
|
+
* reach the tracker's server, or did not answer. `status` is the callback
|
|
1023
|
+
* listener's HTTP status, `0` when it gave none; `code` is its error code
|
|
1024
|
+
* (`HOST_UNAVAILABLE` when there was no usable answer).
|
|
1025
|
+
*/
|
|
1026
|
+
export declare class TrackerOutboundError extends Error {
|
|
1027
|
+
readonly code: string;
|
|
1028
|
+
readonly status: number;
|
|
1029
|
+
constructor(message: string, code: string, status: number);
|
|
1030
|
+
}
|
|
1031
|
+
export type TrackerOutbound = {
|
|
1032
|
+
/** Sends `request` to the server of the account `handle` belongs to, with the stored credential when the call has one. */
|
|
1033
|
+
request(handle: string, request: SourceControlOutboundRequest): Promise<SourceControlOutboundResponse>;
|
|
1034
|
+
};
|
|
1035
|
+
/**
|
|
1036
|
+
* The service's way to the tracker's server: OpenChamber's callback listener
|
|
1037
|
+
* (`OPENCHAMBER_HOST_CALLBACK_URL`), which checks the handle, keeps the
|
|
1038
|
+
* request on the account's origin and adds the credential. Plain `fetch`, no
|
|
1039
|
+
* dependencies. Throws `TrackerOutboundError` when OpenChamber refuses the
|
|
1040
|
+
* request; an answer of any status from the server resolves. A read's handle
|
|
1041
|
+
* sends `GET` only; `items.updateState` and `comments.create` may send writes.
|
|
1042
|
+
*/
|
|
1043
|
+
export declare const createTrackerOutbound: ({ env }: {
|
|
1044
|
+
env: Record<string, string | undefined>;
|
|
1045
|
+
}) => TrackerOutbound;
|
|
625
1046
|
export {};
|