@openchamber/sdk 2.1.0 → 2.2.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 +51 -8
- package/DOCUMENTATION.md +16 -5
- package/README.md +13 -1
- package/dist/contract.d.ts +59 -5
- package/dist/contract.js +2 -0
- package/dist/host-version.d.ts +2 -1
- package/dist/host.d.ts +22 -5
- package/dist/host.js +203 -6
- package/dist/index.d.ts +9 -3
- package/dist/index.js +4 -1
- package/dist/manifest.d.ts +6 -4
- package/dist/manifest.js +4 -4
- package/dist/parse.d.ts +12 -6
- package/dist/parse.js +2 -0
- package/dist/popover-schemas.d.ts +33 -0
- package/dist/popover-schemas.js +74 -0
- package/dist/popover.d.ts +37 -0
- package/dist/popover.js +57 -0
- package/dist/protocol.d.ts +232 -4
- package/dist/protocol.js +75 -1
- package/dist/schemas.d.ts +2 -0
- package/dist/schemas.js +2 -0
- package/dist/shells.d.ts +69 -0
- package/dist/shells.js +4 -0
- package/dist/status-control-schemas.d.ts +21 -0
- package/dist/status-control-schemas.js +29 -0
- package/dist/status-controls.d.ts +31 -0
- package/dist/status-controls.js +48 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/ui/popover-anchor.d.ts +16 -0
- package/dist/ui/popover-anchor.js +198 -0
- package/dist/ui/theme.js +15 -0
- package/dist/workspace-schemas.d.ts +16 -0
- package/dist/workspace-schemas.js +4 -4
- package/dist/workspace.d.ts +10 -4
- package/dist/workspace.js +2 -0
- package/package.json +1 -1
package/dist/host.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { OPENCHAMBER_SDK_API_VERSION, OPENCHAMBER_SDK_CHANNEL } from "./api-version.js";
|
|
2
2
|
import { GUEST_STORAGE_KEY_MAX, GUEST_STORAGE_VALUE_BYTES } from "./workspace.js";
|
|
3
|
+
import { isGuestStatusControls } from "./status-controls.js";
|
|
4
|
+
import { isGuestPopoverRequest } from "./popover.js";
|
|
3
5
|
import { GUEST_FILE_EDITOR_CONTENT_MAX, GUEST_FILE_EDITOR_VERSION_MAX, fileEditorPayloadSize, sameFileEditorDocument, } from "./file-editor.js";
|
|
4
6
|
import { GUEST_FILE_CONTENT_MAX, GUEST_CLIPBOARD_TEXT_MAX, GUEST_TOAST_MAX, GUEST_FILE_PATH_MAX, GUEST_GENERATE_OUTPUT_TOKENS_MAX, GUEST_GENERATE_PROMPT_MAX, GUEST_GENERATE_SYSTEM_MAX, GUEST_GENERATE_TIMEOUT_MS, GUEST_REQUEST_TIMEOUT_MS, GUEST_RESOLVE_ERROR_MAX, isGuestFilePath, isGuestRequestPath, clampAttachRequest, clampBadgeCount, clampFrameHeight, isGuestCommitSha, clampPromptRequest, clampStartSessionRequest, readHostMessage, isGenerateResult, isFileListResult, isFileReadResult, isFileStatResult, isJsonValue, isFileWriteResult, isServiceStatusResult, isGuestRequestResult, isPromptResult, isStartSessionResult, } from "./contract.js";
|
|
7
|
+
import { GUEST_SHELL_ID_MAX, GUEST_SHELL_OUTPUT_TAIL_MAX } from "./shells.js";
|
|
5
8
|
// Structural, not `instanceof KeyboardEvent`: the frame's own realm owns that
|
|
6
9
|
// constructor, and non-browser runtimes have none.
|
|
7
10
|
const isKeyEvent = (event) => 'key' in event && 'metaKey' in event && 'ctrlKey' in event;
|
|
@@ -18,6 +21,16 @@ export class HostRequestError extends Error {
|
|
|
18
21
|
// path would otherwise surface only as HOST_TIMEOUT twenty seconds later.
|
|
19
22
|
const rejectBadPath = () => Promise.reject(new HostRequestError('BAD_PATH', 'Request path must start with "/" and stay on the declared origin.'));
|
|
20
23
|
const rejectBadFilePath = () => Promise.reject(new HostRequestError('BAD_PATH', `File path must be 1 to ${GUEST_FILE_PATH_MAX} characters without NUL or backslash.`));
|
|
24
|
+
const deviceStorageScope = (options) => {
|
|
25
|
+
// Typed callers supply GuestStorageOptions, but extensions may call this JavaScript API without TypeScript.
|
|
26
|
+
if (options === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
if (Object(options) !== options || Array.isArray(options)
|
|
29
|
+
|| (options.scope !== undefined && options.scope !== 'instance' && options.scope !== 'device')) {
|
|
30
|
+
throw new HostRequestError('HOST_REJECTED', 'Storage scope must be "instance" or "device".');
|
|
31
|
+
}
|
|
32
|
+
return options.scope === 'device' ? 'device' : undefined;
|
|
33
|
+
};
|
|
21
34
|
const nextId = (n) => {
|
|
22
35
|
n.value += 1;
|
|
23
36
|
return `oc-${n.value}`;
|
|
@@ -36,6 +49,8 @@ export const connectHost = (options = {}) => {
|
|
|
36
49
|
const connectionListeners = new Set();
|
|
37
50
|
const settingsListeners = new Set();
|
|
38
51
|
const itemListeners = new Set();
|
|
52
|
+
const statusControlListeners = new Set();
|
|
53
|
+
const popoverClosedListeners = new Set();
|
|
39
54
|
let resolveHandler = null;
|
|
40
55
|
let actionHandler = null;
|
|
41
56
|
const fileOpenListeners = new Set();
|
|
@@ -45,10 +60,14 @@ export const connectHost = (options = {}) => {
|
|
|
45
60
|
let saveShortcutInstalled = false;
|
|
46
61
|
const pending = new Map();
|
|
47
62
|
const workspaceListeners = new Map();
|
|
63
|
+
const shellsListeners = new Map();
|
|
48
64
|
let disposed = false;
|
|
49
65
|
const ids = { value: 0 };
|
|
50
66
|
let lastReady = null;
|
|
51
67
|
let lastLifecycle = null;
|
|
68
|
+
let popoverPointerActive = false;
|
|
69
|
+
let popoverFocusActive = false;
|
|
70
|
+
let popoverActivityReported = null;
|
|
52
71
|
const lifecycleFromSession = (session) => {
|
|
53
72
|
if (!session)
|
|
54
73
|
return null;
|
|
@@ -86,6 +105,12 @@ export const connectHost = (options = {}) => {
|
|
|
86
105
|
emit([listener], message.payload.snapshot);
|
|
87
106
|
return;
|
|
88
107
|
}
|
|
108
|
+
if (message.type === 'shells') {
|
|
109
|
+
const listener = shellsListeners.get(message.payload.subscriptionId);
|
|
110
|
+
if (listener)
|
|
111
|
+
emit([listener], message.payload.snapshot);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
89
114
|
if (message.type === 'ready') {
|
|
90
115
|
lastReady = message.payload;
|
|
91
116
|
lastLifecycle = lifecycleFromSession(message.payload.session);
|
|
@@ -146,6 +171,14 @@ export const connectHost = (options = {}) => {
|
|
|
146
171
|
emit(itemListeners, message.payload.item);
|
|
147
172
|
return;
|
|
148
173
|
}
|
|
174
|
+
if (message.type === 'status-control-event') {
|
|
175
|
+
emit(statusControlListeners, message.payload);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (message.type === 'popover-closed') {
|
|
179
|
+
emit(popoverClosedListeners, message.payload);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
149
182
|
if (message.type === 'action') {
|
|
150
183
|
const answer = (payload) => {
|
|
151
184
|
if (!disposed)
|
|
@@ -274,6 +307,46 @@ export const connectHost = (options = {}) => {
|
|
|
274
307
|
event.preventDefault();
|
|
275
308
|
requestFileSave();
|
|
276
309
|
};
|
|
310
|
+
const onPopoverEscape = (event) => {
|
|
311
|
+
if (!isKeyEvent(event) || event.key !== 'Escape' || lastReady?.surface !== 'popover' || !lastReady.popover)
|
|
312
|
+
return;
|
|
313
|
+
event.preventDefault();
|
|
314
|
+
void closePopover(lastReady.popover.id, 'escape').catch(() => undefined);
|
|
315
|
+
};
|
|
316
|
+
const reportPopoverActivity = () => {
|
|
317
|
+
const popover = lastReady?.surface === 'popover' ? lastReady.popover : undefined;
|
|
318
|
+
if (!popover)
|
|
319
|
+
return;
|
|
320
|
+
const active = popoverPointerActive || popoverFocusActive;
|
|
321
|
+
if (popoverActivityReported === active)
|
|
322
|
+
return;
|
|
323
|
+
popoverActivityReported = active;
|
|
324
|
+
void setPopoverAnchorActive(popover.id, active).catch(() => undefined);
|
|
325
|
+
};
|
|
326
|
+
const onPopoverPointerOver = () => {
|
|
327
|
+
if (lastReady?.surface !== 'popover' || popoverPointerActive)
|
|
328
|
+
return;
|
|
329
|
+
popoverPointerActive = true;
|
|
330
|
+
reportPopoverActivity();
|
|
331
|
+
};
|
|
332
|
+
const onPopoverPointerOut = (event) => {
|
|
333
|
+
if (lastReady?.surface !== 'popover' || event.relatedTarget !== null || !popoverPointerActive)
|
|
334
|
+
return;
|
|
335
|
+
popoverPointerActive = false;
|
|
336
|
+
reportPopoverActivity();
|
|
337
|
+
};
|
|
338
|
+
const onPopoverFocus = () => {
|
|
339
|
+
if (lastReady?.surface !== 'popover' || popoverFocusActive)
|
|
340
|
+
return;
|
|
341
|
+
popoverFocusActive = true;
|
|
342
|
+
reportPopoverActivity();
|
|
343
|
+
};
|
|
344
|
+
const onPopoverBlur = () => {
|
|
345
|
+
if (lastReady?.surface !== 'popover' || !popoverFocusActive)
|
|
346
|
+
return;
|
|
347
|
+
popoverFocusActive = false;
|
|
348
|
+
reportPopoverActivity();
|
|
349
|
+
};
|
|
277
350
|
const requireIdentity = (value, maximum = 1024) => {
|
|
278
351
|
if (!value.trim() || value.length > maximum)
|
|
279
352
|
throw new HostRequestError('HOST_REJECTED', `Identity must contain 1 to ${maximum} characters.`);
|
|
@@ -307,6 +380,28 @@ export const connectHost = (options = {}) => {
|
|
|
307
380
|
post({ ...envelope, type: 'workspace-unsubscribe', id: nextId(ids), payload: { subscriptionId } });
|
|
308
381
|
};
|
|
309
382
|
};
|
|
383
|
+
const subscribeShells = async (scope, listener) => {
|
|
384
|
+
if (scope.kind === 'session')
|
|
385
|
+
requireIdentity(scope.sessionId);
|
|
386
|
+
if (scope.kind === 'project')
|
|
387
|
+
requireIdentity(scope.projectId);
|
|
388
|
+
const subscriptionId = nextId(ids);
|
|
389
|
+
shellsListeners.set(subscriptionId, listener);
|
|
390
|
+
try {
|
|
391
|
+
await request({ ...envelope, type: 'shells-subscribe', id: nextId(ids), payload: { subscriptionId, scope } });
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
shellsListeners.delete(subscriptionId);
|
|
395
|
+
if (!disposed)
|
|
396
|
+
post({ ...envelope, type: 'shells-unsubscribe', id: nextId(ids), payload: { subscriptionId } });
|
|
397
|
+
throw error;
|
|
398
|
+
}
|
|
399
|
+
return () => {
|
|
400
|
+
if (!shellsListeners.delete(subscriptionId) || disposed)
|
|
401
|
+
return;
|
|
402
|
+
post({ ...envelope, type: 'shells-unsubscribe', id: nextId(ids), payload: { subscriptionId } });
|
|
403
|
+
};
|
|
404
|
+
};
|
|
310
405
|
const storage = async (payload) => {
|
|
311
406
|
if ('key' in payload && (payload.key.length === 0 || payload.key.length > GUEST_STORAGE_KEY_MAX)) {
|
|
312
407
|
throw new HostRequestError('HOST_REJECTED', 'Storage key must contain 1 to 128 characters.');
|
|
@@ -317,11 +412,26 @@ export const connectHost = (options = {}) => {
|
|
|
317
412
|
if (payload.op === 'set' && new TextEncoder().encode(JSON.stringify(payload.value)).length > GUEST_STORAGE_VALUE_BYTES) {
|
|
318
413
|
throw new HostRequestError('HOST_REJECTED', 'Storage value exceeds 64 KiB.');
|
|
319
414
|
}
|
|
415
|
+
if (payload.scope === 'device' && lastReady?.features?.deviceStorage !== true) {
|
|
416
|
+
throw new HostRequestError('UNSUPPORTED', 'This host does not support device storage.');
|
|
417
|
+
}
|
|
320
418
|
const result = await send({ ...envelope, type: 'storage', id: nextId(ids), payload });
|
|
321
419
|
if (!result || !('storage' in result) || result.op !== payload.op)
|
|
322
420
|
throw new HostRequestError('HOST_REJECTED', 'Host did not return storage data.');
|
|
323
421
|
return result;
|
|
324
422
|
};
|
|
423
|
+
const closePopover = (id, reason) => (lastReady?.features?.popovers !== true && !(lastReady?.surface === 'popover' && lastReady.popover?.id === id)
|
|
424
|
+
? Promise.reject(new HostRequestError('UNSUPPORTED', 'This host does not support popovers.'))
|
|
425
|
+
: request({ ...envelope, type: 'popover-close', id: nextId(ids), payload: reason ? { id, reason } : { id } }));
|
|
426
|
+
const setPopoverAnchorActive = (id, active) => (lastReady?.features?.popovers !== true && !(lastReady?.surface === 'popover' && lastReady.popover?.id === id)
|
|
427
|
+
? Promise.reject(new HostRequestError('UNSUPPORTED', 'This host does not support popovers.'))
|
|
428
|
+
: request({ ...envelope, type: 'popover-anchor', id: nextId(ids), payload: { id, active } }));
|
|
429
|
+
target.addEventListener('keydown', onPopoverEscape, true);
|
|
430
|
+
target.addEventListener('pointerover', onPopoverPointerOver);
|
|
431
|
+
target.addEventListener('pointermove', onPopoverPointerOver);
|
|
432
|
+
target.addEventListener('pointerout', onPopoverPointerOut);
|
|
433
|
+
target.addEventListener('focus', onPopoverFocus);
|
|
434
|
+
target.addEventListener('blur', onPopoverBlur);
|
|
325
435
|
return {
|
|
326
436
|
onAction: (handler) => {
|
|
327
437
|
actionHandler = handler;
|
|
@@ -352,19 +462,64 @@ export const connectHost = (options = {}) => {
|
|
|
352
462
|
listener(snapshot); }),
|
|
353
463
|
onSessions: (projectId, listener) => subscribeWorkspace({ kind: 'sessions', projectId }, (snapshot) => { if (snapshot.kind === 'sessions')
|
|
354
464
|
listener(snapshot); }),
|
|
465
|
+
onRunningShells: (scope, listener) => subscribeShells(scope, listener),
|
|
466
|
+
readShellOutput: async (shellId, options) => {
|
|
467
|
+
requireIdentity(shellId, GUEST_SHELL_ID_MAX);
|
|
468
|
+
const cursor = options?.cursor;
|
|
469
|
+
if (cursor !== undefined && (!Number.isInteger(cursor) || cursor < 0)) {
|
|
470
|
+
throw new HostRequestError('HOST_REJECTED', 'Shell output cursor must be a non-negative integer.');
|
|
471
|
+
}
|
|
472
|
+
const tailBytes = options?.tailBytes;
|
|
473
|
+
if (tailBytes !== undefined && (!Number.isInteger(tailBytes) || tailBytes < 1 || tailBytes > GUEST_SHELL_OUTPUT_TAIL_MAX)) {
|
|
474
|
+
throw new HostRequestError('HOST_REJECTED', `Shell output tailBytes must be an integer between 1 and ${GUEST_SHELL_OUTPUT_TAIL_MAX}.`);
|
|
475
|
+
}
|
|
476
|
+
const result = await send({ ...envelope, type: 'shell-output', id: nextId(ids), payload: { shellId, cursor, tailBytes } });
|
|
477
|
+
const output = result;
|
|
478
|
+
if (!output || typeof output.output !== 'string' || !Number.isFinite(output.cursor)) {
|
|
479
|
+
throw new HostRequestError('HOST_REJECTED', 'Host did not return shell output.');
|
|
480
|
+
}
|
|
481
|
+
return output;
|
|
482
|
+
},
|
|
483
|
+
stopShell: async (shellId) => {
|
|
484
|
+
requireIdentity(shellId, GUEST_SHELL_ID_MAX);
|
|
485
|
+
const result = (await send({ ...envelope, type: 'shell-stop', id: nextId(ids), payload: { shellId } }));
|
|
486
|
+
if (result?.stopped !== true)
|
|
487
|
+
throw new HostRequestError('HOST_REJECTED', 'Host did not stop the shell.');
|
|
488
|
+
return { stopped: true };
|
|
489
|
+
},
|
|
355
490
|
openSession: async (sessionId) => {
|
|
356
491
|
requireIdentity(sessionId);
|
|
357
492
|
await request({ ...envelope, type: 'open-session', id: nextId(ids), payload: { sessionId } });
|
|
358
493
|
},
|
|
359
494
|
storage: {
|
|
360
|
-
get: async (key) => {
|
|
361
|
-
const
|
|
495
|
+
get: async (key, options) => {
|
|
496
|
+
const scope = deviceStorageScope(options);
|
|
497
|
+
const payload = { op: 'get', key };
|
|
498
|
+
if (scope)
|
|
499
|
+
payload.scope = scope;
|
|
500
|
+
const result = await storage(payload);
|
|
362
501
|
return result.op === 'get' && result.found ? result.value : undefined;
|
|
363
502
|
},
|
|
364
|
-
set: async (key, value) => {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
503
|
+
set: async (key, value, options) => {
|
|
504
|
+
const scope = deviceStorageScope(options);
|
|
505
|
+
const payload = { op: 'set', key, value };
|
|
506
|
+
if (scope)
|
|
507
|
+
payload.scope = scope;
|
|
508
|
+
await storage(payload);
|
|
509
|
+
},
|
|
510
|
+
delete: async (key, options) => {
|
|
511
|
+
const scope = deviceStorageScope(options);
|
|
512
|
+
const payload = { op: 'delete', key };
|
|
513
|
+
if (scope)
|
|
514
|
+
payload.scope = scope;
|
|
515
|
+
await storage(payload);
|
|
516
|
+
},
|
|
517
|
+
keys: async (options) => {
|
|
518
|
+
const scope = deviceStorageScope(options);
|
|
519
|
+
const payload = { op: 'keys' };
|
|
520
|
+
if (scope)
|
|
521
|
+
payload.scope = scope;
|
|
522
|
+
const result = await storage(payload);
|
|
368
523
|
if (result.op !== 'keys')
|
|
369
524
|
throw new HostRequestError('HOST_REJECTED', 'Expected storage keys.');
|
|
370
525
|
return result.keys;
|
|
@@ -426,6 +581,36 @@ export const connectHost = (options = {}) => {
|
|
|
426
581
|
itemListeners.delete(listener);
|
|
427
582
|
};
|
|
428
583
|
},
|
|
584
|
+
onStatusControl: (listener) => {
|
|
585
|
+
statusControlListeners.add(listener);
|
|
586
|
+
return () => {
|
|
587
|
+
statusControlListeners.delete(listener);
|
|
588
|
+
};
|
|
589
|
+
},
|
|
590
|
+
onPopoverClosed: (listener) => {
|
|
591
|
+
popoverClosedListeners.add(listener);
|
|
592
|
+
return () => { popoverClosedListeners.delete(listener); };
|
|
593
|
+
},
|
|
594
|
+
setStatusControls: (controls) => {
|
|
595
|
+
if (lastReady?.features?.statusControls !== true) {
|
|
596
|
+
return Promise.reject(new HostRequestError('UNSUPPORTED', 'This host does not support status controls.'));
|
|
597
|
+
}
|
|
598
|
+
if (!isGuestStatusControls(controls)) {
|
|
599
|
+
return Promise.reject(new HostRequestError('HOST_REJECTED', 'Status controls must have unique bounded ids and valid selected options.'));
|
|
600
|
+
}
|
|
601
|
+
return request({ ...envelope, type: 'status-controls', id: nextId(ids), payload: { controls } });
|
|
602
|
+
},
|
|
603
|
+
openPopover: (payload) => {
|
|
604
|
+
if (lastReady?.features?.popovers !== true) {
|
|
605
|
+
return Promise.reject(new HostRequestError('UNSUPPORTED', 'This host does not support popovers.'));
|
|
606
|
+
}
|
|
607
|
+
if (!isGuestPopoverRequest(payload)) {
|
|
608
|
+
return Promise.reject(new HostRequestError('HOST_REJECTED', 'Popover requests need bounded geometry and JSON data.'));
|
|
609
|
+
}
|
|
610
|
+
return request({ ...envelope, type: 'popover-open', id: nextId(ids), payload });
|
|
611
|
+
},
|
|
612
|
+
closePopover,
|
|
613
|
+
setPopoverAnchorActive,
|
|
429
614
|
onResolve: (handler) => {
|
|
430
615
|
resolveHandler = handler;
|
|
431
616
|
return () => {
|
|
@@ -726,6 +911,10 @@ export const connectHost = (options = {}) => {
|
|
|
726
911
|
post({ ...envelope, type: 'workspace-unsubscribe', id: nextId(ids), payload: { subscriptionId } });
|
|
727
912
|
}
|
|
728
913
|
workspaceListeners.clear();
|
|
914
|
+
for (const subscriptionId of shellsListeners.keys()) {
|
|
915
|
+
post({ ...envelope, type: 'shells-unsubscribe', id: nextId(ids), payload: { subscriptionId } });
|
|
916
|
+
}
|
|
917
|
+
shellsListeners.clear();
|
|
729
918
|
disposed = true;
|
|
730
919
|
resolveHandler = null;
|
|
731
920
|
actionHandler = null;
|
|
@@ -735,6 +924,12 @@ export const connectHost = (options = {}) => {
|
|
|
735
924
|
if (saveShortcutInstalled)
|
|
736
925
|
target.removeEventListener('keydown', onSaveShortcut, true);
|
|
737
926
|
target.removeEventListener('message', onMessage);
|
|
927
|
+
target.removeEventListener('keydown', onPopoverEscape, true);
|
|
928
|
+
target.removeEventListener('pointerover', onPopoverPointerOver);
|
|
929
|
+
target.removeEventListener('pointermove', onPopoverPointerOver);
|
|
930
|
+
target.removeEventListener('pointerout', onPopoverPointerOut);
|
|
931
|
+
target.removeEventListener('focus', onPopoverFocus);
|
|
932
|
+
target.removeEventListener('blur', onPopoverBlur);
|
|
738
933
|
for (const waiter of pending.values()) {
|
|
739
934
|
clearTimeout(waiter.timer);
|
|
740
935
|
waiter.reject(new HostRequestError('HOST_UNAVAILABLE', 'Host client was disposed.'));
|
|
@@ -747,6 +942,8 @@ export const connectHost = (options = {}) => {
|
|
|
747
942
|
connectionListeners.clear();
|
|
748
943
|
settingsListeners.clear();
|
|
749
944
|
itemListeners.clear();
|
|
945
|
+
statusControlListeners.clear();
|
|
946
|
+
popoverClosedListeners.clear();
|
|
750
947
|
},
|
|
751
948
|
};
|
|
752
949
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export { OPENCHAMBER_SDK_API_VERSION, OPENCHAMBER_SDK_CHANNEL, OPENCHAMBER_SDK_MANIFEST_API_VERSIONS } from './api-version.ts';
|
|
2
2
|
export { GUEST_SCROLLBAR_CSS, GUEST_SCROLLBAR_SCRIPT } from './scrollbar-style.ts';
|
|
3
3
|
export { guestFramePolicy } from './frame-policy.ts';
|
|
4
|
-
export type { GuestLoadState, GuestProject, GuestWorktree, GuestSessionActivity, GuestSessionRecord, GuestDirectoryCoverage, GuestProjectsSnapshot, GuestWorktreesSnapshot, GuestSessionsSnapshot, GuestWorkspaceSnapshot, GuestWorkspaceQuery, GuestWorkspaceSubscription, GuestWorkspaceUpdate, GuestStorageRequest, GuestStorageResult, GuestSessionWorktree } from './workspace.ts';
|
|
5
|
-
export { GUEST_STORAGE_KEY_MAX, GUEST_STORAGE_KEYS_MAX, GUEST_STORAGE_VALUE_BYTES, GUEST_STORAGE_TOTAL_BYTES } from './workspace.ts';
|
|
4
|
+
export type { GuestLoadState, GuestProject, GuestWorktree, GuestSessionActivity, GuestSessionRecord, GuestDirectoryCoverage, GuestProjectsSnapshot, GuestWorktreesSnapshot, GuestSessionsSnapshot, GuestWorkspaceSnapshot, GuestWorkspaceQuery, GuestWorkspaceSubscription, GuestWorkspaceUpdate, GuestStorageRequest, GuestStorageResult, GuestStorageOptions, GuestStorageScope, GuestSessionWorktree } from './workspace.ts';
|
|
5
|
+
export { GUEST_STORAGE_KEY_MAX, GUEST_STORAGE_KEYS_MAX, GUEST_STORAGE_VALUE_BYTES, GUEST_STORAGE_TOTAL_BYTES, GUEST_DEVICE_STORAGE_TOTAL_BYTES } from './workspace.ts';
|
|
6
|
+
export type { GuestRunningShell, GuestEndedShell, GuestShellEndStatus, GuestRunningShellsSnapshot, GuestShellsScope, GuestShellsSubscription, GuestShellOutputRequest, GuestShellOutputResult, GuestShellStopResult, } from './shells.ts';
|
|
7
|
+
export { GUEST_SHELL_END_STATUSES, GUEST_SHELL_ID_MAX, GUEST_SHELLS_MAX, GUEST_SHELL_OUTPUT_TAIL_MAX, } from './shells.ts';
|
|
8
|
+
export { GUEST_STATUS_CONTROLS_MAX, GUEST_STATUS_CONTROL_ID, GUEST_STATUS_CONTROL_LABEL_MAX, GUEST_STATUS_CONTROL_OPTIONS_MAX, GUEST_STATUS_CONTROL_VALUE_MAX } from './status-controls.ts';
|
|
9
|
+
export type { GuestStatusControl, GuestStatusControlEvent, GuestStatusControlOption } from './status-controls.ts';
|
|
6
10
|
export type { OpenChamberManifestApiVersion } from './api-version.ts';
|
|
7
11
|
export { compareOpenChamberVersions, hostMeetsOpenChamberEngine, openChamberEngineMinimum, OPENCHAMBER_ENGINE_PATTERN, parseOpenChamberVersion, } from './host-version.ts';
|
|
8
12
|
export { DECLARED_GUEST_CAPABILITIES, GUEST_ACTIONS_MAX, GUEST_ACTION_LABEL_MAX, GUEST_CAPABILITIES, GUEST_COMMANDS_MAX, GUEST_COMMAND_DESCRIPTION_MAX, GUEST_COMMAND_NAME, 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, GUEST_TOOL_TEMPLATE_VALUE_MAX, guestActionsNeedConversation, GUEST_FILESYSTEM_PATTERN_MAX, GUEST_FILESYSTEM_PATTERNS_MAX, GUEST_ORIGINS_MAX, GUEST_SERVICE_PROVIDES, GUEST_SURFACE_DOCKS, GUEST_SURFACE_DOCK_DEFAULT, GUEST_SURFACE_DOCK_SIZE_DEFAULT, GUEST_SURFACE_DOCK_SIZE_MAX, GUEST_SURFACE_DOCK_SIZE_MIN, GUEST_STATUS_SECTION_HEIGHT_DEFAULT, GUEST_STATUS_SECTION_HEIGHT_MAX, GUEST_STATUS_SECTION_HEIGHT_MIN, GUEST_STATUS_SECTION_TITLE_MAX, clampStatusSectionHeight, HOST_LINEAR_API_ORIGIN, isGuestFilesystemPattern, hasGuestCapability, hasGuestPage, isGuestApproved, isGuestPackageSvgIcon, requestedGuestCapabilities, resolveAttachEntry, resolvePageEntry, resolveStatusSectionEntry, resolveAttachMode, resolveIntegrationApi, resolveIntegrationAuth, serviceProvides, toPublicService, toPublicIntegration, } from './manifest.ts';
|
|
@@ -11,8 +15,10 @@ export { GUEST_FILE_EDITORS_MAX, GUEST_FILE_EDITOR_CONTENT_MAX, GUEST_FILE_EDITO
|
|
|
11
15
|
export type { FileEditorChange, FileEditorContentKind, FileEditorContribution, FileEditorDocument, FileEditorSnapshot, FileSnapshotPurpose, FileSnapshotRequest, FileSnapshotResultPayload, } from './file-editor.ts';
|
|
12
16
|
export { connectHost, HostRequestError } from './host.ts';
|
|
13
17
|
export type { HostClient, HostClientOptions, HostFrame } from './host.ts';
|
|
18
|
+
export { GUEST_POPOVER_COORDINATE_MAX, GUEST_POPOVER_DATA_DEPTH_MAX, GUEST_POPOVER_DATA_MAX, GUEST_POPOVER_HEIGHT_MAX, GUEST_POPOVER_HEIGHT_MIN, GUEST_POPOVER_ID, GUEST_POPOVER_SIDES, GUEST_POPOVER_WIDTH_MAX, GUEST_POPOVER_WIDTH_MIN, GUEST_POPOVER_CLOSE_REASONS, isGuestPopoverRequest, } from './popover.ts';
|
|
19
|
+
export type { GuestPopoverAnchor, GuestPopoverClosedEvent, GuestPopoverContext, GuestPopoverRequest, GuestPopoverSide } from './popover.ts';
|
|
14
20
|
export { clampAttachRequest, clampBadgeCount, clampFrameHeight, isGuestCommitSha, GUEST_COMMIT_SHA, clampPromptRequest, clampStartSessionRequest, guestFileScope, isAttachData, isJsonValue, isFileListResult, isFileReadResult, isFileStatResult, isGenerateResult, isFileWriteResult, isGuestFilePath, isGuestAttachItem, isGuestMessageItem, isGuestSessionItem, isServiceStatusResult, isGuestRequestPath, isGuestRequestResult, isHostRequestErrorCode, isPromptResult, isStartSessionResult, readHostMessage, resolveHostRequestErrorCode, } from './contract.ts';
|
|
15
|
-
export type { BadgeRequest, ActionResultPayload, GuestActionItem, GuestActionResultMessage, HostActionMessage, HostFileOpenMessage, HostFileSnapshotMessage, HostFileSavedMessage, GuestFileSnapshotResultMessage, GuestFileChangeMessage, GuestFileSaveMessage, GuestFileUnsupportedMessage, GuestBadgeMessage, GuestResizeMessage, GuestOpenCommitMessage, OpenCommitRequest, ResizeRequest, GuestItem, GuestItemRole, GuestMessageItem, GuestResolveResultMessage, GuestSessionItem, GuestSessionItemMessage, HostResolveMessage, ResolveRequest, ResolveResultPayload, FileListEntry, FileListRequest, FileListResult, FileReadRequest, FileReadResult, FileStatRequest, FileStatResult, FileWriteRequest, FileWriteResult, GenerateRequest, GenerateResult, GuestFileEntryKind, GuestFileListMessage, GuestFileReadMessage, GuestFileScope, GuestFileStatKind, GuestFileStatMessage, GuestGenerateMessage, GuestFileWriteMessage, ServiceStatus, ServiceStatusResult, HostRequestErrorCode, AttachBranches, AttachIssueRequest, AttachThreadKind, JsonValue, HostResultPayload, PromptRequest, PromptResult, SessionLifecycleEvent, SessionLifecyclePhase, StartSessionRequest, StartSessionResult, StartSessionSent, ComposeRequest, GuestServiceRequestMessage, GuestServiceStatusMessage, GuestAttachMessage, GuestClipboardWriteMessage, GuestCloseMessage, GuestComposeMessage, GuestConnection, GuestHelloMessage, GuestMessage, GuestOauthDisconnectMessage, GuestOauthStartMessage, GuestOpenSurfaceMessage, GuestOpenUrlMessage, GuestRequest, GuestRequestMessage, GuestRequestMethod, GuestPromptMessage, GuestSessionLinkMessage, GuestStartSessionMessage, GuestRequestResult, GuestSettings, GuestToastMessage, GuestHostSurface, HostConnectionMessage, HostDirectoryMessage, HostItemMessage, HostMessage, HostReadyContext, HostReadyMessage, HostResultMessage, HostSessionLifecycleMessage, HostSessionMessage, HostSettingsMessage, HostTheme, HostThemeMode, HostThemeTokens, SessionSnapshot, ToastKind, ToastRequest, } from './contract.ts';
|
|
21
|
+
export type { BadgeRequest, ActionResultPayload, GuestActionItem, GuestActionResultMessage, HostActionMessage, HostFileOpenMessage, HostFileSnapshotMessage, HostFileSavedMessage, GuestFileSnapshotResultMessage, GuestFileChangeMessage, GuestFileSaveMessage, GuestFileUnsupportedMessage, GuestBadgeMessage, GuestResizeMessage, GuestOpenCommitMessage, GuestStatusControlsMessage, GuestPopoverAnchorMessage, GuestPopoverCloseMessage, GuestPopoverOpenMessage, OpenCommitRequest, ResizeRequest, GuestItem, GuestItemRole, GuestMessageItem, GuestResolveResultMessage, GuestSessionItem, GuestSessionItemMessage, HostResolveMessage, ResolveRequest, ResolveResultPayload, FileListEntry, FileListRequest, FileListResult, FileReadRequest, FileReadResult, FileStatRequest, FileStatResult, FileWriteRequest, FileWriteResult, GenerateRequest, GenerateResult, GuestFileEntryKind, GuestFileListMessage, GuestFileReadMessage, GuestFileScope, GuestFileStatKind, GuestFileStatMessage, GuestGenerateMessage, GuestFileWriteMessage, ServiceStatus, ServiceStatusResult, HostRequestErrorCode, AttachBranches, AttachIssueRequest, AttachThreadKind, JsonValue, HostResultPayload, PromptRequest, PromptResult, SessionLifecycleEvent, SessionLifecyclePhase, StartSessionRequest, StartSessionResult, StartSessionSent, ComposeRequest, GuestServiceRequestMessage, GuestServiceStatusMessage, GuestShellOutputMessage, GuestShellsSubscribeMessage, GuestShellsUnsubscribeMessage, GuestShellStopMessage, GuestAttachMessage, GuestClipboardWriteMessage, GuestCloseMessage, GuestComposeMessage, GuestConnection, GuestHelloMessage, GuestMessage, GuestOauthDisconnectMessage, GuestOauthStartMessage, GuestOpenSurfaceMessage, GuestOpenUrlMessage, GuestRequest, GuestRequestMessage, GuestRequestMethod, GuestPromptMessage, GuestSessionLinkMessage, GuestStartSessionMessage, GuestRequestResult, GuestSettings, GuestToastMessage, GuestHostSurface, HostConnectionMessage, HostDirectoryMessage, HostItemMessage, HostStatusControlEventMessage, HostPopoverClosedMessage, HostMessage, HostReadyContext, HostReadyMessage, HostResultMessage, HostSessionLifecycleMessage, HostSessionMessage, HostSettingsMessage, HostShellsMessage, HostTheme, HostThemeMode, HostThemeTokens, SessionSnapshot, ToastKind, ToastRequest, } from './contract.ts';
|
|
16
22
|
export { EMPTY_GUEST_CONNECTION, GUEST_BADGE_MAX, GUEST_FRAME_HEIGHT_MAX, GUEST_ITEM_MESSAGE_TEXT_MAX, GUEST_ITEM_SESSION_MAX, GUEST_RESOLVE_ERROR_MAX, GUEST_FILE_CONTENT_MAX, GUEST_FILE_ENTRY_KINDS, GUEST_FILE_LIST_MAX, GUEST_FILE_PATH_MAX, GUEST_GENERATE_OUTPUT_TOKENS_MAX, GUEST_GENERATE_PROMPT_MAX, GUEST_GENERATE_SYSTEM_MAX, GUEST_GENERATE_TEXT_MAX, GUEST_GENERATE_TIMEOUT_MS, GUEST_FILE_STAT_KINDS, SERVICE_STATUS_VALUES, HOST_REQUEST_ERROR_CODES, SESSION_LIFECYCLE_PHASES, START_SESSION_SENT, GUEST_ACCOUNT_MAX, GUEST_SESSION_AGENT_MAX, GUEST_SESSION_MODEL_MAX, GUEST_ATTACH_AUTHOR_MAX, GUEST_ATTACH_BRANCH_MAX, GUEST_ATTACH_DATA_MAX, GUEST_ATTACH_ID_MAX, GUEST_ATTACH_TEXT_MAX, GUEST_ATTACH_TITLE_MAX, GUEST_ATTACH_URL_MAX, GUEST_CLIPBOARD_TEXT_MAX, GUEST_TOAST_MAX, GUEST_COMPOSE_TEXT_MAX, GUEST_REQUEST_BODY_MAX, GUEST_REQUEST_PATH_MAX, GUEST_REQUEST_RESPONSE_MAX, GUEST_REQUEST_TIMEOUT_MS, GUEST_SETTING_VALUE_MAX, } from './contract.ts';
|
|
17
23
|
export { BROWSER_CONTROL_ACTIONS, BROWSER_PROVIDER_ACTION_TIMEOUT_MS, BROWSER_PROVIDER_IDLE_MS, BROWSER_PROVIDER_OPEN_TIMEOUT_MS, BROWSER_PROVIDER_PATH, BROWSER_PROVIDER_RESPONSE_MAX, BROWSER_SCROLL_DIRECTIONS, BROWSER_VIEWPORT_MODES, isBrowserControlAction, readBrowserProviderRequest, } from './service-providers.ts';
|
|
18
24
|
export type { BrowserCaptureData, BrowserCaptureParameters, BrowserClickData, BrowserClickParameters, BrowserConsoleProblem, BrowserControlAction, BrowserElementBounds, BrowserInspectData, BrowserInspectParameters, BrowserNavigationData, BrowserOpenData, BrowserOpenParameters, BrowserProviderContext, BrowserProviderData, BrowserProviderRequest, BrowserProviderResult, BrowserResizeData, BrowserResizeParameters, BrowserScrollData, BrowserScrollDirection, BrowserScrollParameters, BrowserSnapshotData, BrowserSnapshotElement, BrowserSnapshotParameters, BrowserTab, BrowserTabTarget, BrowserTypeData, BrowserTypeParameters, BrowserViewportMode, BrowserViewportSummary, } from './service-providers.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
export { OPENCHAMBER_SDK_API_VERSION, OPENCHAMBER_SDK_CHANNEL, OPENCHAMBER_SDK_MANIFEST_API_VERSIONS } from "./api-version.js";
|
|
2
2
|
export { GUEST_SCROLLBAR_CSS, GUEST_SCROLLBAR_SCRIPT } from "./scrollbar-style.js";
|
|
3
3
|
export { guestFramePolicy } from "./frame-policy.js";
|
|
4
|
-
export { GUEST_STORAGE_KEY_MAX, GUEST_STORAGE_KEYS_MAX, GUEST_STORAGE_VALUE_BYTES, GUEST_STORAGE_TOTAL_BYTES } from "./workspace.js";
|
|
4
|
+
export { GUEST_STORAGE_KEY_MAX, GUEST_STORAGE_KEYS_MAX, GUEST_STORAGE_VALUE_BYTES, GUEST_STORAGE_TOTAL_BYTES, GUEST_DEVICE_STORAGE_TOTAL_BYTES } from "./workspace.js";
|
|
5
|
+
export { GUEST_SHELL_END_STATUSES, GUEST_SHELL_ID_MAX, GUEST_SHELLS_MAX, GUEST_SHELL_OUTPUT_TAIL_MAX, } from "./shells.js";
|
|
6
|
+
export { GUEST_STATUS_CONTROLS_MAX, GUEST_STATUS_CONTROL_ID, GUEST_STATUS_CONTROL_LABEL_MAX, GUEST_STATUS_CONTROL_OPTIONS_MAX, GUEST_STATUS_CONTROL_VALUE_MAX } from "./status-controls.js";
|
|
5
7
|
export { compareOpenChamberVersions, hostMeetsOpenChamberEngine, openChamberEngineMinimum, OPENCHAMBER_ENGINE_PATTERN, parseOpenChamberVersion, } from "./host-version.js";
|
|
6
8
|
export { DECLARED_GUEST_CAPABILITIES, GUEST_ACTIONS_MAX, GUEST_ACTION_LABEL_MAX, GUEST_CAPABILITIES, GUEST_COMMANDS_MAX, GUEST_COMMAND_DESCRIPTION_MAX, GUEST_COMMAND_NAME, 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, GUEST_TOOL_TEMPLATE_VALUE_MAX, guestActionsNeedConversation, GUEST_FILESYSTEM_PATTERN_MAX, GUEST_FILESYSTEM_PATTERNS_MAX, GUEST_ORIGINS_MAX, GUEST_SERVICE_PROVIDES, GUEST_SURFACE_DOCKS, GUEST_SURFACE_DOCK_DEFAULT, GUEST_SURFACE_DOCK_SIZE_DEFAULT, GUEST_SURFACE_DOCK_SIZE_MAX, GUEST_SURFACE_DOCK_SIZE_MIN, GUEST_STATUS_SECTION_HEIGHT_DEFAULT, GUEST_STATUS_SECTION_HEIGHT_MAX, GUEST_STATUS_SECTION_HEIGHT_MIN, GUEST_STATUS_SECTION_TITLE_MAX, clampStatusSectionHeight, HOST_LINEAR_API_ORIGIN, isGuestFilesystemPattern, hasGuestCapability, hasGuestPage, isGuestApproved, isGuestPackageSvgIcon, requestedGuestCapabilities, resolveAttachEntry, resolvePageEntry, resolveStatusSectionEntry, resolveAttachMode, resolveIntegrationApi, resolveIntegrationAuth, serviceProvides, toPublicService, toPublicIntegration, } from "./manifest.js";
|
|
7
9
|
export { GUEST_FILE_EDITORS_MAX, GUEST_FILE_EDITOR_CONTENT_MAX, GUEST_FILE_EDITOR_PATTERNS_MAX, GUEST_FILE_EDITOR_PATTERN_MAX, GUEST_FILE_EDITOR_TITLE_MAX, GUEST_FILE_EDITOR_VERSION_MAX, createFileSaveTracker, fileEditorPayloadSize, isFileEditorPattern, matchesFileEditorPattern, } from "./file-editor.js";
|
|
8
10
|
export { connectHost, HostRequestError } from "./host.js";
|
|
11
|
+
export { GUEST_POPOVER_COORDINATE_MAX, GUEST_POPOVER_DATA_DEPTH_MAX, GUEST_POPOVER_DATA_MAX, GUEST_POPOVER_HEIGHT_MAX, GUEST_POPOVER_HEIGHT_MIN, GUEST_POPOVER_ID, GUEST_POPOVER_SIDES, GUEST_POPOVER_WIDTH_MAX, GUEST_POPOVER_WIDTH_MIN, GUEST_POPOVER_CLOSE_REASONS, isGuestPopoverRequest, } from "./popover.js";
|
|
9
12
|
export { clampAttachRequest, clampBadgeCount, clampFrameHeight, isGuestCommitSha, GUEST_COMMIT_SHA, clampPromptRequest, clampStartSessionRequest, guestFileScope, isAttachData, isJsonValue, isFileListResult, isFileReadResult, isFileStatResult, isGenerateResult, isFileWriteResult, isGuestFilePath, isGuestAttachItem, isGuestMessageItem, isGuestSessionItem, isServiceStatusResult, isGuestRequestPath, isGuestRequestResult, isHostRequestErrorCode, isPromptResult, isStartSessionResult, readHostMessage, resolveHostRequestErrorCode, } from "./contract.js";
|
|
10
13
|
export { EMPTY_GUEST_CONNECTION, GUEST_BADGE_MAX, GUEST_FRAME_HEIGHT_MAX, GUEST_ITEM_MESSAGE_TEXT_MAX, GUEST_ITEM_SESSION_MAX, GUEST_RESOLVE_ERROR_MAX, GUEST_FILE_CONTENT_MAX, GUEST_FILE_ENTRY_KINDS, GUEST_FILE_LIST_MAX, GUEST_FILE_PATH_MAX, GUEST_GENERATE_OUTPUT_TOKENS_MAX, GUEST_GENERATE_PROMPT_MAX, GUEST_GENERATE_SYSTEM_MAX, GUEST_GENERATE_TEXT_MAX, GUEST_GENERATE_TIMEOUT_MS, GUEST_FILE_STAT_KINDS, SERVICE_STATUS_VALUES, HOST_REQUEST_ERROR_CODES, SESSION_LIFECYCLE_PHASES, START_SESSION_SENT, GUEST_ACCOUNT_MAX, GUEST_SESSION_AGENT_MAX, GUEST_SESSION_MODEL_MAX, GUEST_ATTACH_AUTHOR_MAX, GUEST_ATTACH_BRANCH_MAX, GUEST_ATTACH_DATA_MAX, GUEST_ATTACH_ID_MAX, GUEST_ATTACH_TEXT_MAX, GUEST_ATTACH_TITLE_MAX, GUEST_ATTACH_URL_MAX, GUEST_CLIPBOARD_TEXT_MAX, GUEST_TOAST_MAX, GUEST_COMPOSE_TEXT_MAX, GUEST_REQUEST_BODY_MAX, GUEST_REQUEST_PATH_MAX, GUEST_REQUEST_RESPONSE_MAX, GUEST_REQUEST_TIMEOUT_MS, GUEST_SETTING_VALUE_MAX, } from "./contract.js";
|
|
11
14
|
export { BROWSER_CONTROL_ACTIONS, BROWSER_PROVIDER_ACTION_TIMEOUT_MS, BROWSER_PROVIDER_IDLE_MS, BROWSER_PROVIDER_OPEN_TIMEOUT_MS, BROWSER_PROVIDER_PATH, BROWSER_PROVIDER_RESPONSE_MAX, BROWSER_SCROLL_DIRECTIONS, BROWSER_VIEWPORT_MODES, isBrowserControlAction, readBrowserProviderRequest, } from "./service-providers.js";
|
package/dist/manifest.d.ts
CHANGED
|
@@ -60,6 +60,8 @@ export type StatusSectionContribution = true | {
|
|
|
60
60
|
entry: string;
|
|
61
61
|
title?: string;
|
|
62
62
|
height?: number;
|
|
63
|
+
defaultExpanded?: boolean;
|
|
64
|
+
requiresProject?: boolean;
|
|
63
65
|
};
|
|
64
66
|
/** Characters in a status section title. */
|
|
65
67
|
export declare const GUEST_STATUS_SECTION_TITLE_MAX = 60;
|
|
@@ -271,15 +273,15 @@ export declare const serviceProvides: (service: Pick<ServiceContribution, "provi
|
|
|
271
273
|
/**
|
|
272
274
|
* What a guest may do beyond drawing its own panel. The user approves the
|
|
273
275
|
* full list once, when the package is installed; a later package that asks
|
|
274
|
-
* for more is re-approved. `prompt`, `sessions`, `files`,
|
|
275
|
-
* declared under `contributes.capabilities`; `service`, `network`,
|
|
276
|
+
* for more is re-approved. `prompt`, `sessions`, `files`, `model`, and
|
|
277
|
+
* `shells` are declared under `contributes.capabilities`; `service`, `network`,
|
|
276
278
|
* `filesystem` and `origins` follow from `contributes.service`,
|
|
277
279
|
* `contributes.integration`, `contributes.filesystem` and `contributes.origins`. `model` is one-off text generation with the
|
|
278
280
|
* user's Small Model (`host.generate`), outside any session.
|
|
279
281
|
*/
|
|
280
|
-
export declare const GUEST_CAPABILITIES: readonly ["prompt", "sessions", "files", "model", "conversation", "service", "network", "filesystem", "origins"];
|
|
282
|
+
export declare const GUEST_CAPABILITIES: readonly ["prompt", "sessions", "files", "model", "shells", "conversation", "service", "network", "filesystem", "origins"];
|
|
281
283
|
export type GuestCapability = (typeof GUEST_CAPABILITIES)[number];
|
|
282
|
-
export declare const DECLARED_GUEST_CAPABILITIES: readonly ["prompt", "sessions", "files", "model"];
|
|
284
|
+
export declare const DECLARED_GUEST_CAPABILITIES: readonly ["prompt", "sessions", "files", "model", "shells"];
|
|
283
285
|
/** The capabilities a manifest may ask for directly. */
|
|
284
286
|
export type DeclaredGuestCapability = (typeof DECLARED_GUEST_CAPABILITIES)[number];
|
|
285
287
|
/** How many `contributes.origins` a package may declare. */
|
package/dist/manifest.js
CHANGED
|
@@ -96,14 +96,14 @@ export const serviceProvides = (service, role) => Boolean(service?.provides?.inc
|
|
|
96
96
|
/**
|
|
97
97
|
* What a guest may do beyond drawing its own panel. The user approves the
|
|
98
98
|
* full list once, when the package is installed; a later package that asks
|
|
99
|
-
* for more is re-approved. `prompt`, `sessions`, `files`,
|
|
100
|
-
* declared under `contributes.capabilities`; `service`, `network`,
|
|
99
|
+
* for more is re-approved. `prompt`, `sessions`, `files`, `model`, and
|
|
100
|
+
* `shells` are declared under `contributes.capabilities`; `service`, `network`,
|
|
101
101
|
* `filesystem` and `origins` follow from `contributes.service`,
|
|
102
102
|
* `contributes.integration`, `contributes.filesystem` and `contributes.origins`. `model` is one-off text generation with the
|
|
103
103
|
* user's Small Model (`host.generate`), outside any session.
|
|
104
104
|
*/
|
|
105
|
-
export const GUEST_CAPABILITIES = ['prompt', 'sessions', 'files', 'model', 'conversation', 'service', 'network', 'filesystem', 'origins'];
|
|
106
|
-
export const DECLARED_GUEST_CAPABILITIES = ['prompt', 'sessions', 'files', 'model'];
|
|
105
|
+
export const GUEST_CAPABILITIES = ['prompt', 'sessions', 'files', 'model', 'shells', 'conversation', 'service', 'network', 'filesystem', 'origins'];
|
|
106
|
+
export const DECLARED_GUEST_CAPABILITIES = ['prompt', 'sessions', 'files', 'model', 'shells'];
|
|
107
107
|
/** How many `contributes.origins` a package may declare. */
|
|
108
108
|
export const GUEST_ORIGINS_MAX = 8;
|
|
109
109
|
/** How many `contributes.filesystem` patterns a package may declare. */
|
package/dist/parse.d.ts
CHANGED
|
@@ -12,10 +12,10 @@ export declare const openChamberManifestSchema: z.ZodObject<{
|
|
|
12
12
|
icon: z.ZodString;
|
|
13
13
|
entry: z.ZodOptional<z.ZodString>;
|
|
14
14
|
dock: z.ZodOptional<z.ZodEnum<{
|
|
15
|
-
top: "top";
|
|
16
|
-
bottom: "bottom";
|
|
17
15
|
left: "left";
|
|
18
16
|
right: "right";
|
|
17
|
+
top: "top";
|
|
18
|
+
bottom: "bottom";
|
|
19
19
|
}>>;
|
|
20
20
|
size: z.ZodOptional<z.ZodNumber>;
|
|
21
21
|
}, z.core.$strip>;
|
|
@@ -40,8 +40,11 @@ export declare const openChamberManifestSchema: z.ZodObject<{
|
|
|
40
40
|
entry: z.ZodString;
|
|
41
41
|
title: z.ZodOptional<z.ZodString>;
|
|
42
42
|
height: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
defaultExpanded: z.ZodOptional<z.ZodBoolean>;
|
|
44
|
+
requiresProject: z.ZodOptional<z.ZodBoolean>;
|
|
43
45
|
}, z.core.$strip>]>>;
|
|
44
46
|
capabilities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
47
|
+
shells: "shells";
|
|
45
48
|
sessions: "sessions";
|
|
46
49
|
prompt: "prompt";
|
|
47
50
|
files: "files";
|
|
@@ -121,8 +124,8 @@ export declare const openChamberManifestSchema: z.ZodObject<{
|
|
|
121
124
|
label: z.ZodString;
|
|
122
125
|
icon: z.ZodOptional<z.ZodString>;
|
|
123
126
|
where: z.ZodEnum<{
|
|
124
|
-
message: "message";
|
|
125
127
|
session: "session";
|
|
128
|
+
message: "message";
|
|
126
129
|
}>;
|
|
127
130
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
128
131
|
background: "background";
|
|
@@ -184,10 +187,10 @@ export declare const packageManifestSchema: z.ZodObject<{
|
|
|
184
187
|
icon: z.ZodString;
|
|
185
188
|
entry: z.ZodOptional<z.ZodString>;
|
|
186
189
|
dock: z.ZodOptional<z.ZodEnum<{
|
|
187
|
-
top: "top";
|
|
188
|
-
bottom: "bottom";
|
|
189
190
|
left: "left";
|
|
190
191
|
right: "right";
|
|
192
|
+
top: "top";
|
|
193
|
+
bottom: "bottom";
|
|
191
194
|
}>>;
|
|
192
195
|
size: z.ZodOptional<z.ZodNumber>;
|
|
193
196
|
}, z.core.$strip>;
|
|
@@ -212,8 +215,11 @@ export declare const packageManifestSchema: z.ZodObject<{
|
|
|
212
215
|
entry: z.ZodString;
|
|
213
216
|
title: z.ZodOptional<z.ZodString>;
|
|
214
217
|
height: z.ZodOptional<z.ZodNumber>;
|
|
218
|
+
defaultExpanded: z.ZodOptional<z.ZodBoolean>;
|
|
219
|
+
requiresProject: z.ZodOptional<z.ZodBoolean>;
|
|
215
220
|
}, z.core.$strip>]>>;
|
|
216
221
|
capabilities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
222
|
+
shells: "shells";
|
|
217
223
|
sessions: "sessions";
|
|
218
224
|
prompt: "prompt";
|
|
219
225
|
files: "files";
|
|
@@ -293,8 +299,8 @@ export declare const packageManifestSchema: z.ZodObject<{
|
|
|
293
299
|
label: z.ZodString;
|
|
294
300
|
icon: z.ZodOptional<z.ZodString>;
|
|
295
301
|
where: z.ZodEnum<{
|
|
296
|
-
message: "message";
|
|
297
302
|
session: "session";
|
|
303
|
+
message: "message";
|
|
298
304
|
}>;
|
|
299
305
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
300
306
|
background: "background";
|
package/dist/parse.js
CHANGED
|
@@ -215,6 +215,8 @@ const contributesSchema = z.object({
|
|
|
215
215
|
entry: z.string().trim().refine((value) => isSafeAssetPath(value) && value.toLowerCase().endsWith('.html')),
|
|
216
216
|
title: z.string().trim().min(1).max(GUEST_STATUS_SECTION_TITLE_MAX).optional(),
|
|
217
217
|
height: z.number().int().min(GUEST_STATUS_SECTION_HEIGHT_MIN).max(GUEST_STATUS_SECTION_HEIGHT_MAX).optional(),
|
|
218
|
+
defaultExpanded: z.boolean().optional(),
|
|
219
|
+
requiresProject: z.boolean().optional(),
|
|
218
220
|
})]).optional(),
|
|
219
221
|
capabilities: z.array(z.enum(DECLARED_GUEST_CAPABILITIES)).max(8).optional(),
|
|
220
222
|
integration: integrationSchema.optional(),
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { JsonValue } from './contract.ts';
|
|
3
|
+
export declare const guestPopoverDataSchema: z.ZodCustom<JsonValue, JsonValue>;
|
|
4
|
+
export declare const guestPopoverRequestSchema: z.ZodObject<{
|
|
5
|
+
id: z.ZodString;
|
|
6
|
+
anchor: z.ZodObject<{
|
|
7
|
+
x: z.ZodNumber;
|
|
8
|
+
y: z.ZodNumber;
|
|
9
|
+
width: z.ZodNumber;
|
|
10
|
+
height: z.ZodNumber;
|
|
11
|
+
}, z.core.$strict>;
|
|
12
|
+
width: z.ZodNumber;
|
|
13
|
+
height: z.ZodNumber;
|
|
14
|
+
side: z.ZodOptional<z.ZodEnum<{
|
|
15
|
+
left: "left";
|
|
16
|
+
right: "right";
|
|
17
|
+
top: "top";
|
|
18
|
+
bottom: "bottom";
|
|
19
|
+
}>>;
|
|
20
|
+
focus: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
+
data: z.ZodCustom<JsonValue, JsonValue>;
|
|
22
|
+
}, z.core.$strict>;
|
|
23
|
+
export declare const guestPopoverClosedEventSchema: z.ZodObject<{
|
|
24
|
+
id: z.ZodString;
|
|
25
|
+
reason: z.ZodEnum<{
|
|
26
|
+
escape: "escape";
|
|
27
|
+
outside: "outside";
|
|
28
|
+
anchor: "anchor";
|
|
29
|
+
owner: "owner";
|
|
30
|
+
closed: "closed";
|
|
31
|
+
replaced: "replaced";
|
|
32
|
+
}>;
|
|
33
|
+
}, z.core.$strict>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { GUEST_POPOVER_CLOSE_REASONS, GUEST_POPOVER_COORDINATE_MAX, GUEST_POPOVER_DATA_MAX, GUEST_POPOVER_DATA_DEPTH_MAX, GUEST_POPOVER_HEIGHT_MAX, GUEST_POPOVER_HEIGHT_MIN, GUEST_POPOVER_ID, GUEST_POPOVER_SIDES, GUEST_POPOVER_WIDTH_MAX, GUEST_POPOVER_WIDTH_MIN, } from "./popover.js";
|
|
3
|
+
const jsonPrimitive = z.union([z.string().max(GUEST_POPOVER_DATA_MAX), z.number(), z.boolean(), z.null()]);
|
|
4
|
+
const jsonRecord = z.record(z.string().max(GUEST_POPOVER_DATA_MAX), z.unknown());
|
|
5
|
+
// Parse one level at a time: recursive z.json() would traverse a hostile cycle
|
|
6
|
+
// or deeply nested structured-clone payload before its size/depth refinement.
|
|
7
|
+
export const guestPopoverDataSchema = z.custom((value) => {
|
|
8
|
+
const pending = [{ value, depth: 0 }];
|
|
9
|
+
let size = 0;
|
|
10
|
+
while (pending.length > 0) {
|
|
11
|
+
const current = pending.pop();
|
|
12
|
+
if (!current)
|
|
13
|
+
break;
|
|
14
|
+
const item = current.value;
|
|
15
|
+
if (current.depth >= GUEST_POPOVER_DATA_DEPTH_MAX)
|
|
16
|
+
return false;
|
|
17
|
+
if (Array.isArray(item)) {
|
|
18
|
+
if (item.length > GUEST_POPOVER_DATA_MAX)
|
|
19
|
+
return false;
|
|
20
|
+
if (Object.keys(item).some((key) => !/^(0|[1-9]\d*)$/.test(key) || Number(key) >= item.length))
|
|
21
|
+
return false;
|
|
22
|
+
size += 2 + Math.max(0, item.length - 1);
|
|
23
|
+
for (const child of item)
|
|
24
|
+
pending.push({ value: child, depth: current.depth + 1 });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const primitive = jsonPrimitive.safeParse(item);
|
|
28
|
+
if (primitive.success) {
|
|
29
|
+
size += JSON.stringify(primitive.data).length;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const record = jsonRecord.safeParse(item);
|
|
33
|
+
if (!record.success)
|
|
34
|
+
return false;
|
|
35
|
+
const prototype = Object.getPrototypeOf(item);
|
|
36
|
+
if (prototype !== null && prototype !== Object.prototype)
|
|
37
|
+
return false;
|
|
38
|
+
// z.record normalizes prototype-named keys. Validate the original
|
|
39
|
+
// structured-clone values so those keys cannot escape the budget.
|
|
40
|
+
const entries = Object.entries(Object.getOwnPropertyDescriptors(item)).filter(([, descriptor]) => descriptor.enumerable);
|
|
41
|
+
size += 2 + Math.max(0, entries.length - 1);
|
|
42
|
+
for (const [key, descriptor] of entries) {
|
|
43
|
+
if (!('value' in descriptor))
|
|
44
|
+
return false;
|
|
45
|
+
size += JSON.stringify(key).length + 1;
|
|
46
|
+
if (size > GUEST_POPOVER_DATA_MAX)
|
|
47
|
+
return false;
|
|
48
|
+
pending.push({ value: descriptor.value, depth: current.depth + 1 });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (size > GUEST_POPOVER_DATA_MAX)
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}, 'Popover data must be finite JSON within its size and depth limits.');
|
|
57
|
+
export const guestPopoverRequestSchema = z.object({
|
|
58
|
+
id: z.string().regex(GUEST_POPOVER_ID),
|
|
59
|
+
anchor: z.object({
|
|
60
|
+
x: z.number().finite().min(-GUEST_POPOVER_COORDINATE_MAX).max(GUEST_POPOVER_COORDINATE_MAX),
|
|
61
|
+
y: z.number().finite().min(-GUEST_POPOVER_COORDINATE_MAX).max(GUEST_POPOVER_COORDINATE_MAX),
|
|
62
|
+
width: z.number().finite().positive().max(GUEST_POPOVER_COORDINATE_MAX),
|
|
63
|
+
height: z.number().finite().positive().max(GUEST_POPOVER_COORDINATE_MAX),
|
|
64
|
+
}).strict(),
|
|
65
|
+
width: z.number().int().min(GUEST_POPOVER_WIDTH_MIN).max(GUEST_POPOVER_WIDTH_MAX),
|
|
66
|
+
height: z.number().int().min(GUEST_POPOVER_HEIGHT_MIN).max(GUEST_POPOVER_HEIGHT_MAX),
|
|
67
|
+
side: z.enum(GUEST_POPOVER_SIDES).optional(),
|
|
68
|
+
focus: z.boolean().optional(),
|
|
69
|
+
data: guestPopoverDataSchema,
|
|
70
|
+
}).strict();
|
|
71
|
+
export const guestPopoverClosedEventSchema = z.object({
|
|
72
|
+
id: z.string().regex(GUEST_POPOVER_ID),
|
|
73
|
+
reason: z.enum(GUEST_POPOVER_CLOSE_REASONS),
|
|
74
|
+
}).strict();
|