@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.
@@ -0,0 +1,37 @@
1
+ import type { JsonValue } from './contract.ts';
2
+ export declare const GUEST_POPOVER_ID: RegExp;
3
+ export declare const GUEST_POPOVER_COORDINATE_MAX = 100000;
4
+ export declare const GUEST_POPOVER_WIDTH_MIN = 160;
5
+ export declare const GUEST_POPOVER_WIDTH_MAX = 640;
6
+ export declare const GUEST_POPOVER_HEIGHT_MIN = 48;
7
+ export declare const GUEST_POPOVER_HEIGHT_MAX = 480;
8
+ export declare const GUEST_POPOVER_DATA_MAX = 16000;
9
+ export declare const GUEST_POPOVER_DATA_DEPTH_MAX = 32;
10
+ export declare const GUEST_POPOVER_SIDES: readonly ["left", "right", "top", "bottom"];
11
+ export type GuestPopoverSide = (typeof GUEST_POPOVER_SIDES)[number];
12
+ export type GuestPopoverAnchor = {
13
+ x: number;
14
+ y: number;
15
+ width: number;
16
+ height: number;
17
+ };
18
+ export type GuestPopoverRequest = {
19
+ id: string;
20
+ anchor: GuestPopoverAnchor;
21
+ width: number;
22
+ height: number;
23
+ side?: GuestPopoverSide;
24
+ focus?: boolean;
25
+ data: JsonValue;
26
+ };
27
+ export type GuestPopoverContext = {
28
+ id: string;
29
+ data: JsonValue;
30
+ };
31
+ export declare const GUEST_POPOVER_CLOSE_REASONS: readonly ["escape", "outside", "anchor", "owner", "closed", "replaced"];
32
+ export type GuestPopoverClosedEvent = {
33
+ id: string;
34
+ reason: (typeof GUEST_POPOVER_CLOSE_REASONS)[number];
35
+ };
36
+ /** Guest-side fast-fail guard. The host schema remains authoritative for untyped callers. */
37
+ export declare const isGuestPopoverRequest: (request: GuestPopoverRequest) => boolean;
@@ -0,0 +1,57 @@
1
+ export const GUEST_POPOVER_ID = /^[A-Za-z0-9_-]{1,80}$/;
2
+ export const GUEST_POPOVER_COORDINATE_MAX = 100_000;
3
+ export const GUEST_POPOVER_WIDTH_MIN = 160;
4
+ export const GUEST_POPOVER_WIDTH_MAX = 640;
5
+ export const GUEST_POPOVER_HEIGHT_MIN = 48;
6
+ export const GUEST_POPOVER_HEIGHT_MAX = 480;
7
+ export const GUEST_POPOVER_DATA_MAX = 16_000;
8
+ export const GUEST_POPOVER_DATA_DEPTH_MAX = 32;
9
+ export const GUEST_POPOVER_SIDES = ['left', 'right', 'top', 'bottom'];
10
+ export const GUEST_POPOVER_CLOSE_REASONS = ['escape', 'outside', 'anchor', 'owner', 'closed', 'replaced'];
11
+ const hasBoundedJsonTree = (value, depth = 0, budget = { remaining: GUEST_POPOVER_DATA_MAX }) => {
12
+ if (--budget.remaining < 0 || depth >= GUEST_POPOVER_DATA_DEPTH_MAX)
13
+ return false;
14
+ if (value === null)
15
+ return true;
16
+ const children = Array.isArray(value) ? value : Object(value) === value ? Object.values(value) : [];
17
+ for (const item of children) {
18
+ if (!hasBoundedJsonTree(item, depth + 1, budget))
19
+ return false;
20
+ }
21
+ return true;
22
+ };
23
+ // Used only after the depth bound above, including for JavaScript consumers
24
+ // whose values need not satisfy the public JsonValue type.
25
+ const isFiniteJson = (value) => {
26
+ if (value === null || value === true || value === false)
27
+ return true;
28
+ if (Array.isArray(value))
29
+ return Object.keys(value).every((key) => /^(0|[1-9]\d*)$/.test(key) && Number(key) < value.length)
30
+ && value.every(isFiniteJson);
31
+ if (Object(value) === value) {
32
+ const prototype = Object.getPrototypeOf(value);
33
+ return (prototype === null || prototype === Object.prototype) && Object.values(value).every(isFiniteJson);
34
+ }
35
+ return String(value) === value || Number.isFinite(value);
36
+ };
37
+ /** Guest-side fast-fail guard. The host schema remains authoritative for untyped callers. */
38
+ export const isGuestPopoverRequest = (request) => {
39
+ try {
40
+ if (String(request.id) !== request.id || !GUEST_POPOVER_ID.test(request.id)
41
+ || !Number.isFinite(request.anchor.x) || Math.abs(request.anchor.x) > GUEST_POPOVER_COORDINATE_MAX
42
+ || !Number.isFinite(request.anchor.y) || Math.abs(request.anchor.y) > GUEST_POPOVER_COORDINATE_MAX
43
+ || !Number.isFinite(request.anchor.width) || !Number.isFinite(request.anchor.height)
44
+ || request.anchor.width <= 0 || request.anchor.height <= 0
45
+ || request.anchor.width > GUEST_POPOVER_COORDINATE_MAX || request.anchor.height > GUEST_POPOVER_COORDINATE_MAX
46
+ || !Number.isInteger(request.width) || request.width < GUEST_POPOVER_WIDTH_MIN || request.width > GUEST_POPOVER_WIDTH_MAX
47
+ || !Number.isInteger(request.height) || request.height < GUEST_POPOVER_HEIGHT_MIN || request.height > GUEST_POPOVER_HEIGHT_MAX
48
+ || (request.side !== undefined && !GUEST_POPOVER_SIDES.includes(request.side))
49
+ || (request.focus !== undefined && request.focus !== true && request.focus !== false)
50
+ || !hasBoundedJsonTree(request.data) || !isFiniteJson(request.data))
51
+ return false;
52
+ return JSON.stringify(request.data).length <= GUEST_POPOVER_DATA_MAX;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ };
@@ -92,6 +92,48 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
92
92
  }, z.core.$strip>;
93
93
  channel: z.ZodLiteral<"openchamber.sdk">;
94
94
  v: z.ZodLiteral<1>;
95
+ }, z.core.$strip>, z.ZodObject<{
96
+ type: z.ZodLiteral<"shells">;
97
+ payload: z.ZodObject<{
98
+ subscriptionId: z.ZodString;
99
+ snapshot: z.ZodObject<{
100
+ kind: z.ZodLiteral<"shells">;
101
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
102
+ kind: z.ZodLiteral<"session">;
103
+ sessionId: z.ZodString;
104
+ }, z.core.$strict>, z.ZodObject<{
105
+ kind: z.ZodLiteral<"project">;
106
+ projectId: z.ZodString;
107
+ }, z.core.$strict>, z.ZodObject<{
108
+ kind: z.ZodLiteral<"global">;
109
+ }, z.core.$strict>], "kind">;
110
+ shells: z.ZodArray<z.ZodObject<{
111
+ id: z.ZodString;
112
+ sessionID: z.ZodString;
113
+ command: z.ZodString;
114
+ startedAt: z.ZodNumber;
115
+ background: z.ZodBoolean;
116
+ }, z.core.$strict>>;
117
+ ended: z.ZodArray<z.ZodObject<{
118
+ id: z.ZodString;
119
+ sessionID: z.ZodString;
120
+ command: z.ZodString;
121
+ startedAt: z.ZodNumber;
122
+ background: z.ZodBoolean;
123
+ status: z.ZodEnum<{
124
+ exited: "exited";
125
+ timeout: "timeout";
126
+ killed: "killed";
127
+ stopped: "stopped";
128
+ unknown: "unknown";
129
+ }>;
130
+ exit: z.ZodOptional<z.ZodNumber>;
131
+ endedAt: z.ZodNumber;
132
+ }, z.core.$strict>>;
133
+ }, z.core.$strict>;
134
+ }, z.core.$strip>;
135
+ channel: z.ZodLiteral<"openchamber.sdk">;
136
+ v: z.ZodLiteral<1>;
95
137
  }, z.core.$strip>, z.ZodObject<{
96
138
  type: z.ZodLiteral<"ready">;
97
139
  payload: z.ZodObject<{
@@ -128,6 +170,14 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
128
170
  font: z.ZodString;
129
171
  mono: z.ZodString;
130
172
  radius: z.ZodString;
173
+ syntaxKeyword: z.ZodOptional<z.ZodString>;
174
+ syntaxString: z.ZodOptional<z.ZodString>;
175
+ syntaxNumber: z.ZodOptional<z.ZodString>;
176
+ syntaxFunction: z.ZodOptional<z.ZodString>;
177
+ syntaxType: z.ZodOptional<z.ZodString>;
178
+ syntaxComment: z.ZodOptional<z.ZodString>;
179
+ syntaxVariable: z.ZodOptional<z.ZodString>;
180
+ syntaxOperator: z.ZodOptional<z.ZodString>;
131
181
  }, z.core.$strip>;
132
182
  }, z.core.$strip>;
133
183
  locale: z.ZodString;
@@ -146,6 +196,7 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
146
196
  background: "background";
147
197
  status: "status";
148
198
  file: "file";
199
+ popover: "popover";
149
200
  }>;
150
201
  connection: z.ZodObject<{
151
202
  connected: z.ZodBoolean;
@@ -197,6 +248,15 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
197
248
  }, z.core.$strip>>;
198
249
  data: z.ZodOptional<z.ZodJSONSchema>;
199
250
  }, z.core.$strip>]>>;
251
+ popover: z.ZodOptional<z.ZodObject<{
252
+ id: z.ZodString;
253
+ data: z.ZodCustom<import("./contract.ts").JsonValue, import("./contract.ts").JsonValue>;
254
+ }, z.core.$strict>>;
255
+ features: z.ZodOptional<z.ZodObject<{
256
+ deviceStorage: z.ZodOptional<z.ZodLiteral<true>>;
257
+ statusControls: z.ZodOptional<z.ZodLiteral<true>>;
258
+ popovers: z.ZodOptional<z.ZodLiteral<true>>;
259
+ }, z.core.$strip>>;
200
260
  }, z.core.$strip>;
201
261
  channel: z.ZodLiteral<"openchamber.sdk">;
202
262
  v: z.ZodLiteral<1>;
@@ -300,6 +360,29 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
300
360
  }, z.core.$strip>;
301
361
  channel: z.ZodLiteral<"openchamber.sdk">;
302
362
  v: z.ZodLiteral<1>;
363
+ }, z.core.$strip>, z.ZodObject<{
364
+ type: z.ZodLiteral<"status-control-event">;
365
+ payload: z.ZodObject<{
366
+ id: z.ZodString;
367
+ value: z.ZodOptional<z.ZodString>;
368
+ }, z.core.$strict>;
369
+ channel: z.ZodLiteral<"openchamber.sdk">;
370
+ v: z.ZodLiteral<1>;
371
+ }, z.core.$strip>, z.ZodObject<{
372
+ type: z.ZodLiteral<"popover-closed">;
373
+ payload: z.ZodObject<{
374
+ id: z.ZodString;
375
+ reason: z.ZodEnum<{
376
+ escape: "escape";
377
+ outside: "outside";
378
+ anchor: "anchor";
379
+ owner: "owner";
380
+ closed: "closed";
381
+ replaced: "replaced";
382
+ }>;
383
+ }, z.core.$strict>;
384
+ channel: z.ZodLiteral<"openchamber.sdk">;
385
+ v: z.ZodLiteral<1>;
303
386
  }, z.core.$strip>, z.ZodObject<{
304
387
  type: z.ZodLiteral<"resolve">;
305
388
  id: z.ZodString;
@@ -418,7 +501,13 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
418
501
  data: z.ZodOptional<z.ZodJSONSchema>;
419
502
  }, z.core.$strip>>;
420
503
  }, z.core.$strip>>;
421
- }, z.core.$strip>], "kind">, z.ZodUnion<readonly [z.ZodObject<{
504
+ }, z.core.$strip>], "kind">, z.ZodObject<{
505
+ output: z.ZodString;
506
+ cursor: z.ZodNumber;
507
+ skipped: z.ZodBoolean;
508
+ }, z.core.$strip>, z.ZodObject<{
509
+ stopped: z.ZodLiteral<true>;
510
+ }, z.core.$strip>, z.ZodUnion<readonly [z.ZodObject<{
422
511
  sessionId: z.ZodString;
423
512
  sent: z.ZodEnum<{
424
513
  failed: "failed";
@@ -470,9 +559,9 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
470
559
  }>;
471
560
  }, z.core.$strip>, z.ZodObject<{
472
561
  status: z.ZodEnum<{
562
+ stopped: "stopped";
473
563
  ready: "ready";
474
564
  failed: "failed";
475
- stopped: "stopped";
476
565
  starting: "starting";
477
566
  }>;
478
567
  }, z.core.$strip>, z.ZodObject<{
@@ -600,7 +689,7 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
600
689
  } | {
601
690
  sent: "failed" | "sent" | "no-model" | "skipped";
602
691
  } | {
603
- status: "ready" | "failed" | "stopped" | "starting";
692
+ status: "stopped" | "ready" | "failed" | "starting";
604
693
  } | {
605
694
  content: string;
606
695
  } | {
@@ -616,6 +705,12 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
616
705
  mtime: number;
617
706
  } | {
618
707
  text: string;
708
+ } | {
709
+ output: string;
710
+ cursor: number;
711
+ skipped: boolean;
712
+ } | {
713
+ stopped: true;
619
714
  };
620
715
  error?: undefined;
621
716
  code?: undefined;
@@ -737,7 +832,7 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
737
832
  } | {
738
833
  sent: "failed" | "sent" | "no-model" | "skipped";
739
834
  } | {
740
- status: "ready" | "failed" | "stopped" | "starting";
835
+ status: "stopped" | "ready" | "failed" | "starting";
741
836
  } | {
742
837
  content: string;
743
838
  } | {
@@ -753,6 +848,12 @@ export declare const hostMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
753
848
  mtime: number;
754
849
  } | {
755
850
  text: string;
851
+ } | {
852
+ output: string;
853
+ cursor: number;
854
+ skipped: boolean;
855
+ } | {
856
+ stopped: true;
756
857
  } | undefined;
757
858
  }>>, z.ZodObject<{
758
859
  type: z.ZodLiteral<"action">;
@@ -874,24 +975,151 @@ export declare const guestMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
874
975
  }, z.core.$strip>;
875
976
  channel: z.ZodLiteral<"openchamber.sdk">;
876
977
  v: z.ZodLiteral<1>;
978
+ }, z.core.$strip>, z.ZodObject<{
979
+ type: z.ZodLiteral<"shells-subscribe">;
980
+ id: z.ZodString;
981
+ payload: z.ZodObject<{
982
+ subscriptionId: z.ZodString;
983
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
984
+ kind: z.ZodLiteral<"session">;
985
+ sessionId: z.ZodString;
986
+ }, z.core.$strict>, z.ZodObject<{
987
+ kind: z.ZodLiteral<"project">;
988
+ projectId: z.ZodString;
989
+ }, z.core.$strict>, z.ZodObject<{
990
+ kind: z.ZodLiteral<"global">;
991
+ }, z.core.$strict>], "kind">;
992
+ }, z.core.$strict>;
993
+ channel: z.ZodLiteral<"openchamber.sdk">;
994
+ v: z.ZodLiteral<1>;
995
+ }, z.core.$strip>, z.ZodObject<{
996
+ type: z.ZodLiteral<"shells-unsubscribe">;
997
+ id: z.ZodString;
998
+ payload: z.ZodObject<{
999
+ subscriptionId: z.ZodString;
1000
+ }, z.core.$strict>;
1001
+ channel: z.ZodLiteral<"openchamber.sdk">;
1002
+ v: z.ZodLiteral<1>;
1003
+ }, z.core.$strip>, z.ZodObject<{
1004
+ type: z.ZodLiteral<"shell-output">;
1005
+ id: z.ZodString;
1006
+ payload: z.ZodObject<{
1007
+ shellId: z.ZodString;
1008
+ cursor: z.ZodOptional<z.ZodNumber>;
1009
+ tailBytes: z.ZodOptional<z.ZodNumber>;
1010
+ }, z.core.$strict>;
1011
+ channel: z.ZodLiteral<"openchamber.sdk">;
1012
+ v: z.ZodLiteral<1>;
1013
+ }, z.core.$strip>, z.ZodObject<{
1014
+ type: z.ZodLiteral<"shell-stop">;
1015
+ id: z.ZodString;
1016
+ payload: z.ZodObject<{
1017
+ shellId: z.ZodString;
1018
+ }, z.core.$strict>;
1019
+ channel: z.ZodLiteral<"openchamber.sdk">;
1020
+ v: z.ZodLiteral<1>;
877
1021
  }, z.core.$strip>, z.ZodObject<{
878
1022
  type: z.ZodLiteral<"storage">;
879
1023
  id: z.ZodString;
880
1024
  payload: z.ZodDiscriminatedUnion<[z.ZodObject<{
881
1025
  op: z.ZodLiteral<"get">;
882
1026
  key: z.ZodString;
1027
+ scope: z.ZodOptional<z.ZodEnum<{
1028
+ instance: "instance";
1029
+ device: "device";
1030
+ }>>;
883
1031
  }, z.core.$strict>, z.ZodObject<{
884
1032
  op: z.ZodLiteral<"delete">;
885
1033
  key: z.ZodString;
1034
+ scope: z.ZodOptional<z.ZodEnum<{
1035
+ instance: "instance";
1036
+ device: "device";
1037
+ }>>;
886
1038
  }, z.core.$strict>, z.ZodObject<{
887
1039
  op: z.ZodLiteral<"set">;
888
1040
  key: z.ZodString;
889
1041
  value: z.ZodJSONSchema;
1042
+ scope: z.ZodOptional<z.ZodEnum<{
1043
+ instance: "instance";
1044
+ device: "device";
1045
+ }>>;
890
1046
  }, z.core.$strict>, z.ZodObject<{
891
1047
  op: z.ZodLiteral<"keys">;
1048
+ scope: z.ZodOptional<z.ZodEnum<{
1049
+ instance: "instance";
1050
+ device: "device";
1051
+ }>>;
892
1052
  }, z.core.$strict>], "op">;
893
1053
  channel: z.ZodLiteral<"openchamber.sdk">;
894
1054
  v: z.ZodLiteral<1>;
1055
+ }, z.core.$strip>, z.ZodObject<{
1056
+ type: z.ZodLiteral<"status-controls">;
1057
+ id: z.ZodString;
1058
+ payload: z.ZodObject<{
1059
+ controls: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1060
+ kind: z.ZodLiteral<"button">;
1061
+ id: z.ZodString;
1062
+ label: z.ZodString;
1063
+ disabled: z.ZodOptional<z.ZodBoolean>;
1064
+ }, z.core.$strict>, z.ZodObject<{
1065
+ kind: z.ZodLiteral<"select">;
1066
+ id: z.ZodString;
1067
+ label: z.ZodString;
1068
+ value: z.ZodString;
1069
+ options: z.ZodArray<z.ZodObject<{
1070
+ value: z.ZodString;
1071
+ label: z.ZodString;
1072
+ }, z.core.$strict>>;
1073
+ disabled: z.ZodOptional<z.ZodBoolean>;
1074
+ }, z.core.$strict>], "kind">>;
1075
+ }, z.core.$strict>;
1076
+ channel: z.ZodLiteral<"openchamber.sdk">;
1077
+ v: z.ZodLiteral<1>;
1078
+ }, z.core.$strip>, z.ZodObject<{
1079
+ type: z.ZodLiteral<"popover-open">;
1080
+ id: z.ZodString;
1081
+ payload: z.ZodObject<{
1082
+ id: z.ZodString;
1083
+ anchor: z.ZodObject<{
1084
+ x: z.ZodNumber;
1085
+ y: z.ZodNumber;
1086
+ width: z.ZodNumber;
1087
+ height: z.ZodNumber;
1088
+ }, z.core.$strict>;
1089
+ width: z.ZodNumber;
1090
+ height: z.ZodNumber;
1091
+ side: z.ZodOptional<z.ZodEnum<{
1092
+ left: "left";
1093
+ right: "right";
1094
+ top: "top";
1095
+ bottom: "bottom";
1096
+ }>>;
1097
+ focus: z.ZodOptional<z.ZodBoolean>;
1098
+ data: z.ZodCustom<import("./contract.ts").JsonValue, import("./contract.ts").JsonValue>;
1099
+ }, z.core.$strict>;
1100
+ channel: z.ZodLiteral<"openchamber.sdk">;
1101
+ v: z.ZodLiteral<1>;
1102
+ }, z.core.$strip>, z.ZodObject<{
1103
+ type: z.ZodLiteral<"popover-close">;
1104
+ id: z.ZodString;
1105
+ payload: z.ZodObject<{
1106
+ id: z.ZodString;
1107
+ reason: z.ZodOptional<z.ZodEnum<{
1108
+ escape: "escape";
1109
+ closed: "closed";
1110
+ }>>;
1111
+ }, z.core.$strict>;
1112
+ channel: z.ZodLiteral<"openchamber.sdk">;
1113
+ v: z.ZodLiteral<1>;
1114
+ }, z.core.$strip>, z.ZodObject<{
1115
+ type: z.ZodLiteral<"popover-anchor">;
1116
+ id: z.ZodString;
1117
+ payload: z.ZodObject<{
1118
+ id: z.ZodString;
1119
+ active: z.ZodBoolean;
1120
+ }, z.core.$strict>;
1121
+ channel: z.ZodLiteral<"openchamber.sdk">;
1122
+ v: z.ZodLiteral<1>;
895
1123
  }, z.core.$strip>, z.ZodObject<{
896
1124
  type: z.ZodLiteral<"open-session">;
897
1125
  id: z.ZodString;
package/dist/protocol.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { guestSessionWorktreeSchema, guestStorageRequestSchema, guestStorageResultSchema, guestWorkspaceQuerySchema, guestWorkspaceSnapshotSchema } from "./workspace-schemas.js";
3
+ import { guestStatusControlEventSchema, guestStatusControlsSchema } from "./status-control-schemas.js";
4
+ import { guestPopoverClosedEventSchema, guestPopoverDataSchema, guestPopoverRequestSchema } from "./popover-schemas.js";
5
+ import { GUEST_SHELL_END_STATUSES, GUEST_SHELL_ID_MAX, GUEST_SHELLS_MAX, GUEST_SHELL_OUTPUT_TAIL_MAX } from "./shells.js";
3
6
  import { OPENCHAMBER_SDK_API_VERSION, OPENCHAMBER_SDK_CHANNEL } from "./api-version.js";
4
7
  import { SERVICE_STATUS_VALUES, ATTACH_PROVIDER_ID, GUEST_ACCOUNT_MAX, GUEST_ATTACH_AUTHOR_MAX, GUEST_BADGE_MAX, GUEST_FRAME_HEIGHT_MAX, GUEST_COMMIT_SHA, GUEST_ITEM_MESSAGE_TEXT_MAX, GUEST_ITEM_SESSION_MAX, GUEST_RESOLVE_ERROR_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_COMPOSE_TEXT_MAX, GUEST_FILE_CONTENT_MAX, GUEST_FILE_ENTRY_KINDS, GUEST_FILE_LIST_MAX, GUEST_GENERATE_OUTPUT_TOKENS_MAX, GUEST_GENERATE_PROMPT_MAX, GUEST_GENERATE_SYSTEM_MAX, GUEST_GENERATE_TEXT_MAX, GUEST_FILE_PATH_MAX, GUEST_FILE_STAT_KINDS, GUEST_REQUEST_BODY_MAX, GUEST_REQUEST_PATH_MAX, GUEST_REQUEST_RESPONSE_MAX, GUEST_SESSION_AGENT_MAX, GUEST_SESSION_MODEL_MAX, GUEST_SETTING_VALUE_MAX, GUEST_TOAST_MAX, SESSION_LIFECYCLE_PHASES, SETTING_KEY, START_SESSION_SENT, isGuestFilePath, isGuestRequestPath, resolveHostRequestErrorCode, } from "./contract.js";
5
8
  import { GUEST_FILE_EDITOR_CONTENT_MAX, GUEST_FILE_EDITOR_VERSION_MAX } from "./file-editor.js";
@@ -39,6 +42,14 @@ const themeTokensSchema = z.object({
39
42
  font: z.string().min(1),
40
43
  mono: z.string().min(1),
41
44
  radius: z.string().min(1),
45
+ syntaxKeyword: z.string().min(1).optional(),
46
+ syntaxString: z.string().min(1).optional(),
47
+ syntaxNumber: z.string().min(1).optional(),
48
+ syntaxFunction: z.string().min(1).optional(),
49
+ syntaxType: z.string().min(1).optional(),
50
+ syntaxComment: z.string().min(1).optional(),
51
+ syntaxVariable: z.string().min(1).optional(),
52
+ syntaxOperator: z.string().min(1).optional(),
42
53
  });
43
54
  const sessionSnapshotSchema = z.object({
44
55
  id: z.string().min(1),
@@ -88,9 +99,19 @@ const fileStatResultPayloadSchema = z.object({
88
99
  const generateResultPayloadSchema = z.object({
89
100
  text: z.string().max(GUEST_GENERATE_TEXT_MAX),
90
101
  });
102
+ const shellOutputResultPayloadSchema = z.object({
103
+ output: z.string(),
104
+ cursor: z.number(),
105
+ skipped: z.boolean(),
106
+ });
107
+ const shellStopResultPayloadSchema = z.object({
108
+ stopped: z.literal(true),
109
+ });
91
110
  const hostResultPayloadSchema = z.union([
92
111
  guestStorageResultSchema,
93
112
  guestWorkspaceSnapshotSchema,
113
+ shellOutputResultPayloadSchema,
114
+ shellStopResultPayloadSchema,
94
115
  startSessionResultPayloadSchema,
95
116
  requestResultPayloadSchema,
96
117
  promptResultPayloadSchema,
@@ -151,10 +172,16 @@ const readyPayloadSchema = z.object({
151
172
  locale: z.string().min(1),
152
173
  directory: z.string().nullable(),
153
174
  session: sessionSnapshotSchema,
154
- surface: z.enum(['panel', 'dialog', 'page', 'background', 'status', 'file']),
175
+ surface: z.enum(['panel', 'dialog', 'page', 'background', 'status', 'file', 'popover']),
155
176
  connection: guestConnectionSchema,
156
177
  settings: guestSettingsSchema,
157
178
  item: guestItemSchema,
179
+ popover: z.object({ id: z.string().min(1).max(80), data: guestPopoverDataSchema }).strict().optional(),
180
+ features: z.object({
181
+ deviceStorage: z.literal(true).optional(),
182
+ statusControls: z.literal(true).optional(),
183
+ popovers: z.literal(true).optional(),
184
+ }).optional(),
158
185
  });
159
186
  const hostResultSchema = z.object({
160
187
  ...envelope,
@@ -198,8 +225,36 @@ const hostResultSchema = z.object({
198
225
  code: resolveHostRequestErrorCode(message.code),
199
226
  };
200
227
  });
228
+ const guestRunningShellSchema = z.object({
229
+ id: z.string().min(1).max(GUEST_SHELL_ID_MAX),
230
+ sessionID: z.string().min(1).max(1024),
231
+ command: z.string(),
232
+ startedAt: z.number().nonnegative(),
233
+ background: z.boolean(),
234
+ }).strict();
235
+ const guestEndedShellSchema = guestRunningShellSchema.extend({
236
+ status: z.enum(GUEST_SHELL_END_STATUSES),
237
+ exit: z.number().int().optional(),
238
+ endedAt: z.number().nonnegative(),
239
+ }).strict();
240
+ const guestShellsScopeSchema = z.discriminatedUnion('kind', [
241
+ z.object({ kind: z.literal('session'), sessionId: z.string().min(1).max(1024) }).strict(),
242
+ z.object({ kind: z.literal('project'), projectId: z.string().min(1).max(1024) }).strict(),
243
+ z.object({ kind: z.literal('global') }).strict(),
244
+ ]);
245
+ const guestRunningShellsSnapshotSchema = z.object({
246
+ kind: z.literal('shells'),
247
+ scope: guestShellsScopeSchema,
248
+ shells: z.array(guestRunningShellSchema).max(GUEST_SHELLS_MAX),
249
+ ended: z.array(guestEndedShellSchema).max(GUEST_SHELLS_MAX),
250
+ }).strict();
201
251
  export const hostMessageSchema = z.union([
202
252
  z.object({ ...envelope, type: z.literal('workspace'), payload: z.object({ subscriptionId: z.string().min(1).max(128), snapshot: guestWorkspaceSnapshotSchema }) }),
253
+ z.object({
254
+ ...envelope,
255
+ type: z.literal('shells'),
256
+ payload: z.object({ subscriptionId: z.string().min(1).max(128), snapshot: guestRunningShellsSnapshotSchema }),
257
+ }),
203
258
  z.object({
204
259
  ...envelope,
205
260
  type: z.literal('ready'),
@@ -248,6 +303,12 @@ export const hostMessageSchema = z.union([
248
303
  item: guestItemSchema,
249
304
  }),
250
305
  }),
306
+ z.object({
307
+ ...envelope,
308
+ type: z.literal('status-control-event'),
309
+ payload: guestStatusControlEventSchema,
310
+ }),
311
+ z.object({ ...envelope, type: z.literal('popover-closed'), payload: guestPopoverClosedEventSchema }),
251
312
  z.object({
252
313
  ...envelope,
253
314
  type: z.literal('resolve'),
@@ -310,7 +371,20 @@ export const guestMessageSchema = z.discriminatedUnion('type', [
310
371
  z.object({ ...envelope, type: z.literal('workspace-read'), id: z.string().min(1), payload: guestWorkspaceQuerySchema }),
311
372
  z.object({ ...envelope, type: z.literal('workspace-subscribe'), id: z.string().min(1), payload: z.object({ subscriptionId: z.string().min(1).max(128), query: guestWorkspaceQuerySchema }) }),
312
373
  z.object({ ...envelope, type: z.literal('workspace-unsubscribe'), id: z.string().min(1), payload: z.object({ subscriptionId: z.string().min(1).max(128) }) }),
374
+ z.object({ ...envelope, type: z.literal('shells-subscribe'), id: z.string().min(1), payload: z.object({ subscriptionId: z.string().min(1).max(128), scope: guestShellsScopeSchema }).strict() }),
375
+ z.object({ ...envelope, type: z.literal('shells-unsubscribe'), id: z.string().min(1), payload: z.object({ subscriptionId: z.string().min(1).max(128) }).strict() }),
376
+ z.object({ ...envelope, type: z.literal('shell-output'), id: z.string().min(1), payload: z.object({ shellId: z.string().min(1).max(GUEST_SHELL_ID_MAX), cursor: z.number().int().nonnegative().optional(), tailBytes: z.number().int().positive().max(GUEST_SHELL_OUTPUT_TAIL_MAX).optional() }).strict() }),
377
+ z.object({ ...envelope, type: z.literal('shell-stop'), id: z.string().min(1), payload: z.object({ shellId: z.string().min(1).max(GUEST_SHELL_ID_MAX) }).strict() }),
313
378
  z.object({ ...envelope, type: z.literal('storage'), id: z.string().min(1), payload: guestStorageRequestSchema }),
379
+ z.object({
380
+ ...envelope,
381
+ type: z.literal('status-controls'),
382
+ id: z.string().min(1),
383
+ payload: z.object({ controls: guestStatusControlsSchema }).strict(),
384
+ }),
385
+ z.object({ ...envelope, type: z.literal('popover-open'), id: z.string().min(1), payload: guestPopoverRequestSchema }),
386
+ z.object({ ...envelope, type: z.literal('popover-close'), id: z.string().min(1), payload: z.object({ id: z.string().min(1).max(80), reason: z.enum(['closed', 'escape']).optional() }).strict() }),
387
+ z.object({ ...envelope, type: z.literal('popover-anchor'), id: z.string().min(1), payload: z.object({ id: z.string().min(1).max(80), active: z.boolean() }).strict() }),
314
388
  z.object({ ...envelope, type: z.literal('open-session'), id: z.string().min(1), payload: z.object({ sessionId: z.string().min(1).max(1024) }) }),
315
389
  z.object({
316
390
  ...envelope,
package/dist/schemas.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export { openChamberManifestSchema, PACKAGE_VERSION_PATTERN, packageManifestSchema, parseManifest, parseManifestJson, } from './parse.ts';
2
2
  export type { ManifestDocument } from './parse.ts';
3
3
  export { guestStorageRequestSchema, guestStorageResultSchema, guestWorkspaceSnapshotSchema } from './workspace-schemas.ts';
4
+ export { guestStatusControlsSchema, guestStatusControlEventSchema } from './status-control-schemas.ts';
5
+ export { guestPopoverClosedEventSchema, guestPopoverRequestSchema } from './popover-schemas.ts';
4
6
  export { guestMessageSchema, hostMessageSchema, parseGuestMessage, parseHostMessage, } from './protocol.ts';
5
7
  export { browserControlActionSchema, browserProviderResultSchema } from './service-provider-schemas.ts';
6
8
  export { surfaceClipboardAnswerSchema, surfaceControllerSchema, surfaceHostMessageSchema, surfaceInputEventSchema, surfaceResizeAnswerSchema, surfaceViewerMessageSchema, } from './service-surface-schemas.ts';
package/dist/schemas.js CHANGED
@@ -3,6 +3,8 @@
3
3
  // `@openchamber/sdk`, which carries no schema library.
4
4
  export { openChamberManifestSchema, PACKAGE_VERSION_PATTERN, packageManifestSchema, parseManifest, parseManifestJson, } from "./parse.js";
5
5
  export { guestStorageRequestSchema, guestStorageResultSchema, guestWorkspaceSnapshotSchema } from "./workspace-schemas.js";
6
+ export { guestStatusControlsSchema, guestStatusControlEventSchema } from "./status-control-schemas.js";
7
+ export { guestPopoverClosedEventSchema, guestPopoverRequestSchema } from "./popover-schemas.js";
6
8
  export { guestMessageSchema, hostMessageSchema, parseGuestMessage, parseHostMessage, } from "./protocol.js";
7
9
  export { browserControlActionSchema, browserProviderResultSchema } from "./service-provider-schemas.js";
8
10
  export { surfaceClipboardAnswerSchema, surfaceControllerSchema, surfaceHostMessageSchema, surfaceInputEventSchema, surfaceResizeAnswerSchema, surfaceViewerMessageSchema, } from "./service-surface-schemas.js";
@@ -0,0 +1,69 @@
1
+ export declare const GUEST_SHELL_ID_MAX = 128;
2
+ export declare const GUEST_SHELLS_MAX = 200;
3
+ export declare const GUEST_SHELL_OUTPUT_TAIL_MAX = 65536;
4
+ /** A shell command still running on behalf of a session. */
5
+ export type GuestRunningShell = {
6
+ id: string;
7
+ sessionID: string;
8
+ command: string;
9
+ startedAt: number;
10
+ /** True for a job the turn does not wait for; false while the turn that ran it is blocked on it. */
11
+ background: boolean;
12
+ };
13
+ export declare const GUEST_SHELL_END_STATUSES: readonly ["exited", "timeout", "killed", "stopped", "unknown"];
14
+ /**
15
+ * How a shell command ended: `exited` on its own (see `exit`), `timeout`,
16
+ * `killed` by a signal, `stopped` by a user (Stop, or aborting the turn that
17
+ * waited on it), or `unknown` when
18
+ * OpenChamber missed the end (a reconnect) and only saw the command gone.
19
+ */
20
+ export type GuestShellEndStatus = (typeof GUEST_SHELL_END_STATUSES)[number];
21
+ /** A shell command OpenChamber saw running that has since ended. */
22
+ export type GuestEndedShell = GuestRunningShell & {
23
+ status: GuestShellEndStatus;
24
+ /** Exit code, when the command exited and OpenCode reported one. */
25
+ exit?: number;
26
+ endedAt: number;
27
+ };
28
+ /**
29
+ * Which running shells a subscription covers: one session and its subagents,
30
+ * every session of a registered project, or every session the app sees.
31
+ */
32
+ export type GuestShellsScope = {
33
+ kind: 'session';
34
+ sessionId: string;
35
+ } | {
36
+ kind: 'project';
37
+ projectId: string;
38
+ } | {
39
+ kind: 'global';
40
+ };
41
+ export type GuestRunningShellsSnapshot = {
42
+ kind: 'shells';
43
+ /** Echo of the scope the subscription asked for. */
44
+ scope: GuestShellsScope;
45
+ shells: GuestRunningShell[];
46
+ /**
47
+ * Commands in scope that ended since OpenChamber started watching, oldest
48
+ * end first. Kept in memory only: empty after an app reload or runtime
49
+ * switch, and capped at `GUEST_SHELLS_MAX`, newest kept.
50
+ */
51
+ ended: GuestEndedShell[];
52
+ };
53
+ export type GuestShellsSubscription = {
54
+ subscriptionId: string;
55
+ scope: GuestShellsScope;
56
+ };
57
+ export type GuestShellOutputRequest = {
58
+ shellId: string;
59
+ cursor?: number;
60
+ tailBytes?: number;
61
+ };
62
+ export type GuestShellOutputResult = {
63
+ output: string;
64
+ cursor: number;
65
+ skipped: boolean;
66
+ };
67
+ export type GuestShellStopResult = {
68
+ stopped: true;
69
+ };
package/dist/shells.js ADDED
@@ -0,0 +1,4 @@
1
+ export const GUEST_SHELL_ID_MAX = 128;
2
+ export const GUEST_SHELLS_MAX = 200;
3
+ export const GUEST_SHELL_OUTPUT_TAIL_MAX = 65536;
4
+ export const GUEST_SHELL_END_STATUSES = ['exited', 'timeout', 'killed', 'stopped', 'unknown'];