@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
package/dist/parse.d.ts
CHANGED
|
@@ -118,7 +118,9 @@ export declare const openChamberManifestSchema: z.ZodObject<{
|
|
|
118
118
|
}>>>;
|
|
119
119
|
provides: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
120
120
|
browser: "browser";
|
|
121
|
+
notifications: "notifications";
|
|
121
122
|
"source-control": "source-control";
|
|
123
|
+
tracker: "tracker";
|
|
122
124
|
}>>>;
|
|
123
125
|
surface: z.ZodOptional<z.ZodLiteral<true>>;
|
|
124
126
|
}, z.core.$strip>>;
|
|
@@ -284,6 +286,97 @@ export declare const openChamberManifestSchema: z.ZodObject<{
|
|
|
284
286
|
changeRequestTemplates: z.ZodArray<z.ZodString>;
|
|
285
287
|
}, z.core.$strict>;
|
|
286
288
|
}, z.core.$strict>>;
|
|
289
|
+
sessionEvents: z.ZodOptional<z.ZodObject<{
|
|
290
|
+
events: z.ZodArray<z.ZodEnum<{
|
|
291
|
+
"permission-asked": "permission-asked";
|
|
292
|
+
"question-asked": "question-asked";
|
|
293
|
+
"turn-failed": "turn-failed";
|
|
294
|
+
"turn-finished": "turn-finished";
|
|
295
|
+
}>>;
|
|
296
|
+
content: z.ZodOptional<z.ZodLiteral<true>>;
|
|
297
|
+
}, z.core.$strict>>;
|
|
298
|
+
notifications: z.ZodOptional<z.ZodObject<{
|
|
299
|
+
label: z.ZodString;
|
|
300
|
+
instances: z.ZodUnion<readonly [z.ZodObject<{
|
|
301
|
+
kind: z.ZodLiteral<"fixed">;
|
|
302
|
+
origin: z.ZodString;
|
|
303
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
304
|
+
kind: z.ZodLiteral<"user">;
|
|
305
|
+
label: z.ZodString;
|
|
306
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
307
|
+
}, z.core.$strict>]>;
|
|
308
|
+
token: z.ZodObject<{
|
|
309
|
+
header: z.ZodEnum<{
|
|
310
|
+
authorization: "authorization";
|
|
311
|
+
"private-token": "private-token";
|
|
312
|
+
}>;
|
|
313
|
+
scheme: z.ZodEnum<{
|
|
314
|
+
basic: "basic";
|
|
315
|
+
bearer: "bearer";
|
|
316
|
+
none: "none";
|
|
317
|
+
token: "token";
|
|
318
|
+
}>;
|
|
319
|
+
username: z.ZodOptional<z.ZodBoolean>;
|
|
320
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
321
|
+
createPath: z.ZodOptional<z.ZodString>;
|
|
322
|
+
}, z.core.$strict>;
|
|
323
|
+
}, z.core.$strict>>;
|
|
324
|
+
tracker: z.ZodOptional<z.ZodObject<{
|
|
325
|
+
wire: z.ZodLiteral<1>;
|
|
326
|
+
label: z.ZodString;
|
|
327
|
+
instances: z.ZodUnion<readonly [z.ZodObject<{
|
|
328
|
+
kind: z.ZodLiteral<"fixed">;
|
|
329
|
+
origin: z.ZodString;
|
|
330
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
331
|
+
kind: z.ZodLiteral<"user">;
|
|
332
|
+
label: z.ZodString;
|
|
333
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
334
|
+
}, z.core.$strict>]>;
|
|
335
|
+
auth: z.ZodObject<{
|
|
336
|
+
token: z.ZodOptional<z.ZodObject<{
|
|
337
|
+
header: z.ZodEnum<{
|
|
338
|
+
authorization: "authorization";
|
|
339
|
+
"private-token": "private-token";
|
|
340
|
+
}>;
|
|
341
|
+
scheme: z.ZodEnum<{
|
|
342
|
+
basic: "basic";
|
|
343
|
+
bearer: "bearer";
|
|
344
|
+
none: "none";
|
|
345
|
+
token: "token";
|
|
346
|
+
}>;
|
|
347
|
+
username: z.ZodOptional<z.ZodBoolean>;
|
|
348
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
349
|
+
createPath: z.ZodOptional<z.ZodString>;
|
|
350
|
+
}, z.core.$strict>>;
|
|
351
|
+
oauth: z.ZodOptional<z.ZodObject<{
|
|
352
|
+
authorizeUrl: z.ZodString;
|
|
353
|
+
tokenUrl: z.ZodString;
|
|
354
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
355
|
+
}, z.core.$strict>>;
|
|
356
|
+
}, z.core.$strict>;
|
|
357
|
+
capabilities: z.ZodObject<{
|
|
358
|
+
multipleAccounts: z.ZodDefault<z.ZodBoolean>;
|
|
359
|
+
stateUpdate: z.ZodDefault<z.ZodBoolean>;
|
|
360
|
+
children: z.ZodDefault<z.ZodBoolean>;
|
|
361
|
+
labels: z.ZodDefault<z.ZodBoolean>;
|
|
362
|
+
priority: z.ZodDefault<z.ZodBoolean>;
|
|
363
|
+
filters: z.ZodDefault<z.ZodObject<{
|
|
364
|
+
people: z.ZodDefault<z.ZodBoolean>;
|
|
365
|
+
priority: z.ZodDefault<z.ZodBoolean>;
|
|
366
|
+
}, z.core.$strict>>;
|
|
367
|
+
projectMapping: z.ZodDefault<z.ZodBoolean>;
|
|
368
|
+
sessionComments: z.ZodDefault<z.ZodBoolean>;
|
|
369
|
+
}, z.core.$strict>;
|
|
370
|
+
stateFilters: z.ZodArray<z.ZodString>;
|
|
371
|
+
identifier: z.ZodEnum<{
|
|
372
|
+
"key-number": "key-number";
|
|
373
|
+
number: "number";
|
|
374
|
+
"short-code": "short-code";
|
|
375
|
+
}>;
|
|
376
|
+
urls: z.ZodObject<{
|
|
377
|
+
item: z.ZodArray<z.ZodString>;
|
|
378
|
+
}, z.core.$strict>;
|
|
379
|
+
}, z.core.$strict>>;
|
|
287
380
|
}, z.core.$strip>;
|
|
288
381
|
}, z.core.$strip>;
|
|
289
382
|
export declare const PACKAGE_VERSION_PATTERN: RegExp;
|
|
@@ -407,7 +500,9 @@ export declare const packageManifestSchema: z.ZodObject<{
|
|
|
407
500
|
}>>>;
|
|
408
501
|
provides: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
409
502
|
browser: "browser";
|
|
503
|
+
notifications: "notifications";
|
|
410
504
|
"source-control": "source-control";
|
|
505
|
+
tracker: "tracker";
|
|
411
506
|
}>>>;
|
|
412
507
|
surface: z.ZodOptional<z.ZodLiteral<true>>;
|
|
413
508
|
}, z.core.$strip>>;
|
|
@@ -573,6 +668,97 @@ export declare const packageManifestSchema: z.ZodObject<{
|
|
|
573
668
|
changeRequestTemplates: z.ZodArray<z.ZodString>;
|
|
574
669
|
}, z.core.$strict>;
|
|
575
670
|
}, z.core.$strict>>;
|
|
671
|
+
sessionEvents: z.ZodOptional<z.ZodObject<{
|
|
672
|
+
events: z.ZodArray<z.ZodEnum<{
|
|
673
|
+
"permission-asked": "permission-asked";
|
|
674
|
+
"question-asked": "question-asked";
|
|
675
|
+
"turn-failed": "turn-failed";
|
|
676
|
+
"turn-finished": "turn-finished";
|
|
677
|
+
}>>;
|
|
678
|
+
content: z.ZodOptional<z.ZodLiteral<true>>;
|
|
679
|
+
}, z.core.$strict>>;
|
|
680
|
+
notifications: z.ZodOptional<z.ZodObject<{
|
|
681
|
+
label: z.ZodString;
|
|
682
|
+
instances: z.ZodUnion<readonly [z.ZodObject<{
|
|
683
|
+
kind: z.ZodLiteral<"fixed">;
|
|
684
|
+
origin: z.ZodString;
|
|
685
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
686
|
+
kind: z.ZodLiteral<"user">;
|
|
687
|
+
label: z.ZodString;
|
|
688
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
689
|
+
}, z.core.$strict>]>;
|
|
690
|
+
token: z.ZodObject<{
|
|
691
|
+
header: z.ZodEnum<{
|
|
692
|
+
authorization: "authorization";
|
|
693
|
+
"private-token": "private-token";
|
|
694
|
+
}>;
|
|
695
|
+
scheme: z.ZodEnum<{
|
|
696
|
+
basic: "basic";
|
|
697
|
+
bearer: "bearer";
|
|
698
|
+
none: "none";
|
|
699
|
+
token: "token";
|
|
700
|
+
}>;
|
|
701
|
+
username: z.ZodOptional<z.ZodBoolean>;
|
|
702
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
703
|
+
createPath: z.ZodOptional<z.ZodString>;
|
|
704
|
+
}, z.core.$strict>;
|
|
705
|
+
}, z.core.$strict>>;
|
|
706
|
+
tracker: z.ZodOptional<z.ZodObject<{
|
|
707
|
+
wire: z.ZodLiteral<1>;
|
|
708
|
+
label: z.ZodString;
|
|
709
|
+
instances: z.ZodUnion<readonly [z.ZodObject<{
|
|
710
|
+
kind: z.ZodLiteral<"fixed">;
|
|
711
|
+
origin: z.ZodString;
|
|
712
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
713
|
+
kind: z.ZodLiteral<"user">;
|
|
714
|
+
label: z.ZodString;
|
|
715
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
716
|
+
}, z.core.$strict>]>;
|
|
717
|
+
auth: z.ZodObject<{
|
|
718
|
+
token: z.ZodOptional<z.ZodObject<{
|
|
719
|
+
header: z.ZodEnum<{
|
|
720
|
+
authorization: "authorization";
|
|
721
|
+
"private-token": "private-token";
|
|
722
|
+
}>;
|
|
723
|
+
scheme: z.ZodEnum<{
|
|
724
|
+
basic: "basic";
|
|
725
|
+
bearer: "bearer";
|
|
726
|
+
none: "none";
|
|
727
|
+
token: "token";
|
|
728
|
+
}>;
|
|
729
|
+
username: z.ZodOptional<z.ZodBoolean>;
|
|
730
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
731
|
+
createPath: z.ZodOptional<z.ZodString>;
|
|
732
|
+
}, z.core.$strict>>;
|
|
733
|
+
oauth: z.ZodOptional<z.ZodObject<{
|
|
734
|
+
authorizeUrl: z.ZodString;
|
|
735
|
+
tokenUrl: z.ZodString;
|
|
736
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
737
|
+
}, z.core.$strict>>;
|
|
738
|
+
}, z.core.$strict>;
|
|
739
|
+
capabilities: z.ZodObject<{
|
|
740
|
+
multipleAccounts: z.ZodDefault<z.ZodBoolean>;
|
|
741
|
+
stateUpdate: z.ZodDefault<z.ZodBoolean>;
|
|
742
|
+
children: z.ZodDefault<z.ZodBoolean>;
|
|
743
|
+
labels: z.ZodDefault<z.ZodBoolean>;
|
|
744
|
+
priority: z.ZodDefault<z.ZodBoolean>;
|
|
745
|
+
filters: z.ZodDefault<z.ZodObject<{
|
|
746
|
+
people: z.ZodDefault<z.ZodBoolean>;
|
|
747
|
+
priority: z.ZodDefault<z.ZodBoolean>;
|
|
748
|
+
}, z.core.$strict>>;
|
|
749
|
+
projectMapping: z.ZodDefault<z.ZodBoolean>;
|
|
750
|
+
sessionComments: z.ZodDefault<z.ZodBoolean>;
|
|
751
|
+
}, z.core.$strict>;
|
|
752
|
+
stateFilters: z.ZodArray<z.ZodString>;
|
|
753
|
+
identifier: z.ZodEnum<{
|
|
754
|
+
"key-number": "key-number";
|
|
755
|
+
number: "number";
|
|
756
|
+
"short-code": "short-code";
|
|
757
|
+
}>;
|
|
758
|
+
urls: z.ZodObject<{
|
|
759
|
+
item: z.ZodArray<z.ZodString>;
|
|
760
|
+
}, z.core.$strict>;
|
|
761
|
+
}, z.core.$strict>>;
|
|
576
762
|
}, z.core.$strip>;
|
|
577
763
|
}, z.core.$strip>;
|
|
578
764
|
}, z.core.$strip>;
|
package/dist/parse.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { OPENCHAMBER_SDK_MANIFEST_API_VERSIONS } from './api-version.js';
|
|
3
3
|
import { OPENCHAMBER_ENGINE_PATTERN } from './host-version.js';
|
|
4
|
-
import { DECLARED_GUEST_CAPABILITIES, GUEST_ACTIONS_MAX, GUEST_ACTION_LABEL_MAX, GUEST_COMMANDS_MAX, GUEST_COMMAND_DESCRIPTION_MAX, GUEST_COMMAND_NAME, GUEST_FILESYSTEM_PATTERNS_MAX, GUEST_FILESYSTEM_PATTERN_MAX, GUEST_ORIGINS_MAX, GUEST_SERVICE_PROVIDES, GUEST_TOOLS_MAX, GUEST_TOOL_COLUMNS_MAX, GUEST_TOOL_COLUMN_MAX, GUEST_TOOL_LANGUAGE_MAX, GUEST_TOOL_MATCH, GUEST_TOOL_MATCH_MAX, GUEST_TOOL_NAME_MAX, GUEST_TOOL_OUTPUTS, GUEST_TOOL_TEMPLATE_MAX, PANEL_ID, hasGuestPage, isGuestFilesystemPattern, isGuestPackageSvgIcon, isSafeAssetPath, resolveIntegrationAuth, GUEST_SURFACE_DOCKS, GUEST_SURFACE_DOCK_SIZE_MAX, GUEST_SURFACE_DOCK_SIZE_MIN, GUEST_STATUS_SECTION_HEIGHT_MAX, GUEST_STATUS_SECTION_HEIGHT_MIN, GUEST_STATUS_SECTION_TITLE_MAX, SOURCE_CONTROL_DEFAULT_INSTANCES_MAX, SOURCE_CONTROL_GUEST_ID_MAX, SOURCE_CONTROL_URL_TEMPLATES_MAX, SOURCE_CONTROL_URL_TEMPLATE_MAX, SOURCE_CONTROL_URL_TOKENS, } from './manifest.js';
|
|
4
|
+
import { DECLARED_GUEST_CAPABILITIES, GUEST_ACTIONS_MAX, GUEST_ACTION_LABEL_MAX, GUEST_COMMANDS_MAX, GUEST_COMMAND_DESCRIPTION_MAX, GUEST_COMMAND_NAME, GUEST_FILESYSTEM_PATTERNS_MAX, GUEST_FILESYSTEM_PATTERN_MAX, GUEST_ORIGINS_MAX, GUEST_SERVICE_PROVIDES, GUEST_TOOLS_MAX, GUEST_TOOL_COLUMNS_MAX, GUEST_TOOL_COLUMN_MAX, GUEST_TOOL_LANGUAGE_MAX, GUEST_TOOL_MATCH, GUEST_TOOL_MATCH_MAX, GUEST_TOOL_NAME_MAX, GUEST_TOOL_OUTPUTS, GUEST_TOOL_TEMPLATE_MAX, PANEL_ID, hasGuestPage, isGuestFilesystemPattern, isGuestPackageSvgIcon, isSafeAssetPath, resolveIntegrationAuth, GUEST_SURFACE_DOCKS, GUEST_SURFACE_DOCK_SIZE_MAX, GUEST_SURFACE_DOCK_SIZE_MIN, GUEST_STATUS_SECTION_HEIGHT_MAX, GUEST_STATUS_SECTION_HEIGHT_MIN, GUEST_STATUS_SECTION_TITLE_MAX, NOTIFICATIONS_GUEST_ID_MAX, SOURCE_CONTROL_DEFAULT_INSTANCES_MAX, SOURCE_CONTROL_GUEST_ID_MAX, SOURCE_CONTROL_URL_TEMPLATES_MAX, SOURCE_CONTROL_URL_TEMPLATE_MAX, SOURCE_CONTROL_URL_TOKENS, TRACKER_BASE_STATE_FILTERS, TRACKER_GUEST_ID_MAX, TRACKER_IDENTIFIER_KINDS, TRACKER_STATE_FILTERS_MAX, TRACKER_URL_TEMPLATES_MAX, TRACKER_URL_TOKENS, isTrackerUrlTemplate, } from './manifest.js';
|
|
5
5
|
import { isGuestRequestPath } from './contract.js';
|
|
6
|
+
import { GUEST_SESSION_EVENT_TYPES } from './session-events.js';
|
|
6
7
|
import { GUEST_STATUS_SOURCE_INTERVAL_MAX, GUEST_STATUS_SOURCE_INTERVAL_MIN } from './status-view.js';
|
|
7
8
|
import { GUEST_FILE_EDITORS_MAX, GUEST_FILE_EDITOR_PATTERNS_MAX, GUEST_FILE_EDITOR_TITLE_MAX, isFileEditorPattern, } from './file-editor.js';
|
|
8
9
|
const isPanelIcon = (value) => (PANEL_ID.test(value) || isGuestPackageSvgIcon(value));
|
|
@@ -300,7 +301,88 @@ const sourceControlSchema = z.object({
|
|
|
300
301
|
});
|
|
301
302
|
});
|
|
302
303
|
});
|
|
304
|
+
// The token block of a notification channel follows the Git host's rules: a
|
|
305
|
+
// bare token travels only as `private-token`, and `basic` needs the login.
|
|
306
|
+
const notificationsTokenSchema = z.object({
|
|
307
|
+
header: z.enum(['authorization', 'private-token']),
|
|
308
|
+
scheme: z.enum(['bearer', 'token', 'basic', 'none']),
|
|
309
|
+
username: z.boolean().optional(),
|
|
310
|
+
scopes: z.array(z.string().trim().min(1).max(64)).max(32).optional(),
|
|
311
|
+
createPath: z.string().trim().max(256).refine(isSafeApiPath, { message: 'must be a path on the instance starting with "/", with no "." or ".." segment' }).optional(),
|
|
312
|
+
}).strict().refine((token) => (token.header === 'private-token') === (token.scheme === 'none'), { message: 'private-token takes the bare token; authorization takes a bearer, token or basic scheme' }).refine((token) => (token.scheme === 'basic') === (token.username === true), { message: 'the basic scheme needs username: true, and username is only for the basic scheme' });
|
|
313
|
+
const notificationsSchema = z.object({
|
|
314
|
+
label: literalSchema,
|
|
315
|
+
instances: z.union([
|
|
316
|
+
z.object({
|
|
317
|
+
kind: z.literal('fixed'),
|
|
318
|
+
origin: z.string().trim().refine(isHttpsOrigin, { message: 'must be an https origin with no path, like https://slack.com' }),
|
|
319
|
+
}).strict(),
|
|
320
|
+
z.object({
|
|
321
|
+
kind: z.literal('user'),
|
|
322
|
+
label: literalSchema,
|
|
323
|
+
placeholder: z.string().trim().max(256).optional(),
|
|
324
|
+
}).strict(),
|
|
325
|
+
]),
|
|
326
|
+
token: notificationsTokenSchema,
|
|
327
|
+
}).strict();
|
|
303
328
|
const uniqueBy = (items, key) => (new Set(items.map(key)).size === items.length);
|
|
329
|
+
// A state filter id: the neutral categories and a tracker's own (`inReview`).
|
|
330
|
+
const TRACKER_STATE_FILTER = /^[a-z][a-zA-Z0-9-]{0,31}$/;
|
|
331
|
+
const trackerTokenSchema = notificationsTokenSchema;
|
|
332
|
+
// An OAuth endpoint: an https URL, or a path on the instance the user names.
|
|
333
|
+
const trackerOauthEndpointSchema = z.string().trim().min(1).max(2_048).refine((value) => isHttpsUrl(value) || isSafeApiPath(value), { message: 'must be an https URL, or a path on the instance starting with "/"' });
|
|
334
|
+
const trackerSchema = z.object({
|
|
335
|
+
wire: z.literal(1),
|
|
336
|
+
label: literalSchema,
|
|
337
|
+
instances: z.union([
|
|
338
|
+
z.object({
|
|
339
|
+
kind: z.literal('fixed'),
|
|
340
|
+
origin: z.string().trim().refine(isHttpsOrigin, { message: 'must be an https origin with no path, like https://tracker.example.com' }),
|
|
341
|
+
}).strict(),
|
|
342
|
+
z.object({
|
|
343
|
+
kind: z.literal('user'),
|
|
344
|
+
label: literalSchema,
|
|
345
|
+
placeholder: z.string().trim().max(256).optional(),
|
|
346
|
+
}).strict(),
|
|
347
|
+
]),
|
|
348
|
+
auth: z.object({
|
|
349
|
+
token: trackerTokenSchema.optional(),
|
|
350
|
+
oauth: z.object({
|
|
351
|
+
authorizeUrl: trackerOauthEndpointSchema,
|
|
352
|
+
tokenUrl: trackerOauthEndpointSchema,
|
|
353
|
+
scopes: z.array(z.string().trim().min(1).max(64)).max(32).optional(),
|
|
354
|
+
}).strict().optional(),
|
|
355
|
+
}).strict().refine((auth) => auth.token !== undefined || auth.oauth !== undefined, { message: 'declare token, oauth or both' }),
|
|
356
|
+
capabilities: z.object({
|
|
357
|
+
multipleAccounts: z.boolean().default(false),
|
|
358
|
+
stateUpdate: z.boolean().default(false),
|
|
359
|
+
children: z.boolean().default(false),
|
|
360
|
+
labels: z.boolean().default(false),
|
|
361
|
+
priority: z.boolean().default(false),
|
|
362
|
+
filters: z.object({ people: z.boolean().default(false), priority: z.boolean().default(false) }).strict().default({ people: false, priority: false }),
|
|
363
|
+
projectMapping: z.boolean().default(false),
|
|
364
|
+
sessionComments: z.boolean().default(false),
|
|
365
|
+
}).strict(),
|
|
366
|
+
stateFilters: z.array(z.string().trim().regex(TRACKER_STATE_FILTER)).min(TRACKER_BASE_STATE_FILTERS.length).max(TRACKER_STATE_FILTERS_MAX)
|
|
367
|
+
.refine((filters) => new Set(filters).size === filters.length, { message: 'state filters must be unique' })
|
|
368
|
+
.refine((filters) => TRACKER_BASE_STATE_FILTERS.every((filter, index) => filters[index] === filter), {
|
|
369
|
+
message: `state filters start with ${TRACKER_BASE_STATE_FILTERS.map((filter) => `"${filter}"`).join(', ')}`,
|
|
370
|
+
}),
|
|
371
|
+
identifier: z.enum(TRACKER_IDENTIFIER_KINDS),
|
|
372
|
+
urls: z.object({
|
|
373
|
+
item: z.array(z.string().trim().min(1)).min(1).max(TRACKER_URL_TEMPLATES_MAX)
|
|
374
|
+
.refine((templates) => new Set(templates).size === templates.length, { message: 'link templates must be unique' }),
|
|
375
|
+
}).strict(),
|
|
376
|
+
}).strict().superRefine((value, ctx) => {
|
|
377
|
+
value.urls.item.forEach((template, index) => {
|
|
378
|
+
if (isTrackerUrlTemplate(template))
|
|
379
|
+
return;
|
|
380
|
+
ctx.addIssue({
|
|
381
|
+
code: 'custom', path: ['urls', 'item', index],
|
|
382
|
+
message: `templates start with "/" and use literal segments and ${TRACKER_URL_TOKENS.join(', ')}, with {id} once, in the path or as "?name={id}".`,
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
});
|
|
304
386
|
// `roles` only means something on a message action and `payload` only on a
|
|
305
387
|
// session action; a dead field is a misconfiguration and fails closed.
|
|
306
388
|
const actionSchema = z.object({
|
|
@@ -378,6 +460,13 @@ const contributesSchema = z.object({
|
|
|
378
460
|
tools: toolsSchema.optional(),
|
|
379
461
|
fileEditors: fileEditorsSchema.optional(),
|
|
380
462
|
sourceControl: sourceControlSchema.optional(),
|
|
463
|
+
sessionEvents: z.object({
|
|
464
|
+
events: z.array(z.enum(GUEST_SESSION_EVENT_TYPES)).min(1).max(GUEST_SESSION_EVENT_TYPES.length)
|
|
465
|
+
.refine((events) => new Set(events).size === events.length, { message: 'event types must be unique' }),
|
|
466
|
+
content: z.literal(true).optional(),
|
|
467
|
+
}).strict().optional(),
|
|
468
|
+
notifications: notificationsSchema.optional(),
|
|
469
|
+
tracker: trackerSchema.optional(),
|
|
381
470
|
});
|
|
382
471
|
/**
|
|
383
472
|
* Contributions that need either the panel or background execution frame.
|
|
@@ -396,11 +485,11 @@ const runtimeContributions = (contributes) => {
|
|
|
396
485
|
declared.push('capabilities');
|
|
397
486
|
if (contributes.integration !== undefined)
|
|
398
487
|
declared.push('integration');
|
|
399
|
-
// A service the host starts itself (it provides a role or a surface
|
|
400
|
-
// no frame; one that only answers a panel's
|
|
401
|
-
// without one.
|
|
488
|
+
// A service the host starts itself (it provides a role or a surface, or
|
|
489
|
+
// receives session events) needs no frame; one that only answers a panel's
|
|
490
|
+
// `serviceRequest` has no caller without one.
|
|
402
491
|
if (contributes.service !== undefined && !contributes.service.provides?.length && !contributes.service.surface
|
|
403
|
-
&& !hasStatusSource(contributes))
|
|
492
|
+
&& !hasStatusSource(contributes) && contributes.sessionEvents === undefined)
|
|
404
493
|
declared.push('service');
|
|
405
494
|
if (contributes.filesystem !== undefined)
|
|
406
495
|
declared.push('filesystem');
|
|
@@ -435,6 +524,47 @@ export const openChamberManifestSchema = z.object({
|
|
|
435
524
|
});
|
|
436
525
|
return;
|
|
437
526
|
}
|
|
527
|
+
// The notification channel and the role that serves it come together, named `ext-<panel.id>` as well.
|
|
528
|
+
const providesNotifications = contributes.service?.provides?.includes('notifications') === true;
|
|
529
|
+
if (providesNotifications !== (contributes.notifications !== undefined)) {
|
|
530
|
+
ctx.addIssue({
|
|
531
|
+
code: 'custom', path: ['service', 'provides'],
|
|
532
|
+
message: 'service.provides "notifications" and contributes.notifications come together: declare both or neither.',
|
|
533
|
+
});
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (providesNotifications && contributes.panel.id.length > NOTIFICATIONS_GUEST_ID_MAX) {
|
|
537
|
+
ctx.addIssue({
|
|
538
|
+
code: 'custom', path: ['service', 'provides'],
|
|
539
|
+
message: `A notifications extension's panel.id is at most ${NOTIFICATIONS_GUEST_ID_MAX} characters: OpenChamber names its channel "ext-<panel.id>".`,
|
|
540
|
+
});
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
// The tracker and the role that serves it come together, named `ext-<panel.id>` as well.
|
|
544
|
+
const providesTracker = contributes.service?.provides?.includes('tracker') === true;
|
|
545
|
+
if (providesTracker !== (contributes.tracker !== undefined)) {
|
|
546
|
+
ctx.addIssue({
|
|
547
|
+
code: 'custom', path: ['service', 'provides'],
|
|
548
|
+
message: 'service.provides "tracker" and contributes.tracker come together: declare both or neither.',
|
|
549
|
+
});
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (providesTracker && contributes.panel.id.length > TRACKER_GUEST_ID_MAX) {
|
|
553
|
+
ctx.addIssue({
|
|
554
|
+
code: 'custom', path: ['service', 'provides'],
|
|
555
|
+
message: `A tracker extension's panel.id is at most ${TRACKER_GUEST_ID_MAX} characters: OpenChamber names its tracker "ext-<panel.id>".`,
|
|
556
|
+
});
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
// Tracker and Git host ids share one namespace (tracked items, the read
|
|
560
|
+
// cache, session links), and both would be `ext-<panel.id>`.
|
|
561
|
+
if (providesTracker && providesSourceControl) {
|
|
562
|
+
ctx.addIssue({
|
|
563
|
+
code: 'custom', path: ['service', 'provides'],
|
|
564
|
+
message: 'An extension is a Git host ("source-control") or a tracker ("tracker"), never both: the two roles would share the id "ext-<panel.id>".',
|
|
565
|
+
});
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
438
568
|
// Docking only means something for a page beside a shared surface.
|
|
439
569
|
const docked = contributes.panel.dock !== undefined || contributes.panel.size !== undefined;
|
|
440
570
|
if (docked && !(contributes.service?.surface && hasGuestPage(contributes))) {
|
|
@@ -460,6 +590,14 @@ export const openChamberManifestSchema = z.object({
|
|
|
460
590
|
});
|
|
461
591
|
return;
|
|
462
592
|
}
|
|
593
|
+
// Session events are posted to the extension's service; without one there is nothing to post to.
|
|
594
|
+
if (contributes.sessionEvents !== undefined && !contributes.service) {
|
|
595
|
+
ctx.addIssue({
|
|
596
|
+
code: 'custom', path: ['sessionEvents'],
|
|
597
|
+
message: 'contributes.sessionEvents are posted to the extension\'s service; declare contributes.service.',
|
|
598
|
+
});
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
463
601
|
if (hasGuestPage(contributes))
|
|
464
602
|
return;
|
|
465
603
|
if (contributes.background) {
|
|
@@ -606,6 +744,11 @@ const failureFromIssue = (issue) => {
|
|
|
606
744
|
if (path.startsWith('contributes.fileEditors')) {
|
|
607
745
|
return fail('invalid-file-editors', `contributes.fileEditors lists 1 to ${GUEST_FILE_EDITORS_MAX} editors with a unique kebab-case id, a title of 1 to ${GUEST_FILE_EDITOR_TITLE_MAX} characters, match: 1 to ${GUEST_FILE_EDITOR_PATTERNS_MAX} file-name patterns (no "/", not only wildcards, like "*.excalidraw"), an entry ending in .html inside the package, and optional content "text" or "binary".`);
|
|
608
746
|
}
|
|
747
|
+
if (path === 'contributes.sessionEvents' || path.startsWith('contributes.sessionEvents.')) {
|
|
748
|
+
return fail('invalid-session-events', issue.code === 'custom' && path === 'contributes.sessionEvents'
|
|
749
|
+
? issue.message
|
|
750
|
+
: `contributes.sessionEvents is { events: [1 to ${GUEST_SESSION_EVENT_TYPES.length} distinct of ${GUEST_SESSION_EVENT_TYPES.map((type) => `"${type}"`).join(', ')}], content?: true }.`);
|
|
751
|
+
}
|
|
609
752
|
if (path.startsWith('contributes.integration')) {
|
|
610
753
|
return fail('invalid-integration', 'contributes.integration needs a name, description, and oauth, token, or host.');
|
|
611
754
|
}
|
|
@@ -616,10 +759,22 @@ const failureFromIssue = (issue) => {
|
|
|
616
759
|
? `${field}: ${issue.message}`
|
|
617
760
|
: `${field} is invalid: see "contributes.sourceControl" in GUEST_SERVICES.md for every field.`);
|
|
618
761
|
}
|
|
762
|
+
if (path.startsWith('contributes.notifications')) {
|
|
763
|
+
const field = fieldPath(issue.path);
|
|
764
|
+
return fail('invalid-service', issue.code === 'custom'
|
|
765
|
+
? `${field}: ${issue.message}`
|
|
766
|
+
: `${field} is invalid: see "contributes.notifications" in GUEST_SERVICES.md for every field.`);
|
|
767
|
+
}
|
|
768
|
+
if (path.startsWith('contributes.tracker')) {
|
|
769
|
+
const field = fieldPath(issue.path);
|
|
770
|
+
return fail('invalid-service', issue.code === 'custom'
|
|
771
|
+
? `${field}: ${issue.message}`
|
|
772
|
+
: `${field} is invalid: see "contributes.tracker" in GUEST_SERVICES.md for every field.`);
|
|
773
|
+
}
|
|
619
774
|
if (path.startsWith('contributes.service')) {
|
|
620
775
|
return fail('invalid-service', issue.code === 'custom'
|
|
621
776
|
? issue.message
|
|
622
|
-
: 'contributes.service needs entry, runtime "host", optional permissions, optional provides ("browser", "source-control"), and optional surface (true).');
|
|
777
|
+
: 'contributes.service needs entry, runtime "host", optional permissions, optional provides ("browser", "source-control", "notifications", "tracker"), and optional surface (true).');
|
|
623
778
|
}
|
|
624
779
|
return fail('missing-panel', 'contributes.panel is required.');
|
|
625
780
|
};
|
package/dist/protocol.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
58
58
|
title: z.ZodString;
|
|
59
59
|
projectId: z.ZodString;
|
|
60
60
|
directory: z.ZodString;
|
|
61
|
+
agent: z.ZodOptional<z.ZodString>;
|
|
61
62
|
parentId: z.ZodNullable<z.ZodString>;
|
|
62
63
|
createdAt: z.ZodNumber;
|
|
63
64
|
updatedAt: z.ZodNumber;
|
|
@@ -481,6 +482,7 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
481
482
|
title: z.ZodString;
|
|
482
483
|
projectId: z.ZodString;
|
|
483
484
|
directory: z.ZodString;
|
|
485
|
+
agent: z.ZodOptional<z.ZodString>;
|
|
484
486
|
parentId: z.ZodNullable<z.ZodString>;
|
|
485
487
|
createdAt: z.ZodNumber;
|
|
486
488
|
updatedAt: z.ZodNumber;
|
|
@@ -647,6 +649,7 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
647
649
|
title: string;
|
|
648
650
|
projectId: string;
|
|
649
651
|
directory: string;
|
|
652
|
+
agent?: string | undefined;
|
|
650
653
|
parentId: string | null;
|
|
651
654
|
createdAt: number;
|
|
652
655
|
updatedAt: number;
|
|
@@ -796,6 +799,7 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
796
799
|
title: string;
|
|
797
800
|
projectId: string;
|
|
798
801
|
directory: string;
|
|
802
|
+
agent?: string | undefined;
|
|
799
803
|
parentId: string | null;
|
|
800
804
|
createdAt: number;
|
|
801
805
|
updatedAt: number;
|
package/dist/schemas.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ export { guestStatusControlsSchema, guestStatusControlEventSchema } from './stat
|
|
|
5
5
|
export { guestStatusViewSchema } from './status-view-schemas.ts';
|
|
6
6
|
export { guestPopoverClosedEventSchema, guestPopoverRequestSchema } from './popover-schemas.ts';
|
|
7
7
|
export { guestMessageSchema, hostMessageSchema, parseGuestMessage, parseHostMessage, } from './protocol.ts';
|
|
8
|
-
export { browserControlActionSchema, browserProviderResultSchema, sourceControlProviderMethodSchema, sourceControlProviderSchemasV1, } from './service-provider-schemas.ts';
|
|
8
|
+
export { browserControlActionSchema, browserProviderResultSchema, notificationsProviderMethodSchema, notificationsProviderSchemasV1, sessionEventResultSchema, sourceControlProviderMethodSchema, sourceControlProviderSchemasV1, trackerProviderMethodSchema, trackerProviderSchemasV1, } from './service-provider-schemas.ts';
|
|
9
9
|
export { surfaceClipboardAnswerSchema, surfaceControllerSchema, surfaceHostMessageSchema, surfaceInputEventSchema, surfaceResizeAnswerSchema, surfaceViewerMessageSchema, } from './service-surface-schemas.ts';
|
|
10
10
|
export type { SurfaceHostMessage, SurfaceViewerMessage } from './service-surface-schemas.ts';
|
package/dist/schemas.js
CHANGED
|
@@ -7,5 +7,5 @@ export { guestStatusControlsSchema, guestStatusControlEventSchema } from './stat
|
|
|
7
7
|
export { guestStatusViewSchema } from './status-view-schemas.js';
|
|
8
8
|
export { guestPopoverClosedEventSchema, guestPopoverRequestSchema } from './popover-schemas.js';
|
|
9
9
|
export { guestMessageSchema, hostMessageSchema, parseGuestMessage, parseHostMessage, } from './protocol.js';
|
|
10
|
-
export { browserControlActionSchema, browserProviderResultSchema, sourceControlProviderMethodSchema, sourceControlProviderSchemasV1, } from './service-provider-schemas.js';
|
|
10
|
+
export { browserControlActionSchema, browserProviderResultSchema, notificationsProviderMethodSchema, notificationsProviderSchemasV1, sessionEventResultSchema, sourceControlProviderMethodSchema, sourceControlProviderSchemasV1, trackerProviderMethodSchema, trackerProviderSchemasV1, } from './service-provider-schemas.js';
|
|
11
11
|
export { surfaceClipboardAnswerSchema, surfaceControllerSchema, surfaceHostMessageSchema, surfaceInputEventSchema, surfaceResizeAnswerSchema, surfaceViewerMessageSchema, } from './service-surface-schemas.js';
|