@hachej/boring-workspace 0.1.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/dist/CodeEditor-DQqOn4xz.js +266 -0
  4. package/dist/CommandPalette-aM61U-b0.js +5229 -0
  5. package/dist/FileTree-DRq_bfue.js +245 -0
  6. package/dist/MarkdownEditor-DjiHxnRv.js +349 -0
  7. package/dist/WorkspaceLoadingState-By0dZoPD.js +568 -0
  8. package/dist/agent-tool-NvxKfist.d.ts +28 -0
  9. package/dist/app-front.d.ts +485 -0
  10. package/dist/app-front.js +452 -0
  11. package/dist/app-server.d.ts +53 -0
  12. package/dist/app-server.js +769 -0
  13. package/dist/bootstrapServer-BRUqUpVW.d.ts +66 -0
  14. package/dist/boring-workspace.css +1 -0
  15. package/dist/charts.d.ts +114 -0
  16. package/dist/charts.js +143 -0
  17. package/dist/events.d.ts +178 -0
  18. package/dist/events.js +88 -0
  19. package/dist/explorer-DtLUnuah.d.ts +129 -0
  20. package/dist/panel-DnvDNQac.js +6 -0
  21. package/dist/server.d.ts +84 -0
  22. package/dist/server.js +811 -0
  23. package/dist/shared.d.ts +113 -0
  24. package/dist/shared.js +11 -0
  25. package/dist/testing-e2e.d.ts +68 -0
  26. package/dist/testing-e2e.js +45 -0
  27. package/dist/testing.d.ts +464 -0
  28. package/dist/testing.js +10984 -0
  29. package/dist/utils-B6yFEsav.js +8 -0
  30. package/dist/workspace.css +5780 -0
  31. package/dist/workspace.d.ts +2119 -0
  32. package/dist/workspace.js +1884 -0
  33. package/docs/INTERFACES.md +58 -0
  34. package/docs/PLUGIN_STRUCTURE.md +162 -0
  35. package/docs/README.md +19 -0
  36. package/docs/bridge.md +135 -0
  37. package/docs/panels.md +102 -0
  38. package/docs/plans/GENERIC_EXPLORER_PLUGIN_PLAN.md +455 -0
  39. package/docs/plans/MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md +962 -0
  40. package/docs/plans/PLUGIN_OUTPUTS_ISOLATION_PLAN.md +301 -0
  41. package/docs/plans/README.md +9 -0
  42. package/docs/plans/UI_BRIDGE_OWNERSHIP_REFACTOR.md +303 -0
  43. package/docs/plans/archive/CODE_OWNERSHIP_CLEANUP_PLAN.md +387 -0
  44. package/docs/plans/archive/COMMAND_PALETTE_REGISTRY.md +814 -0
  45. package/docs/plans/archive/DECLARATIVE_LAYOUT_MIGRATION.md +277 -0
  46. package/docs/plans/archive/PLUGIN_MODEL.md +3674 -0
  47. package/docs/plans/archive/SRC_FOLDER_REORG_PLAN.md +307 -0
  48. package/docs/plans/archive/UNIFIED_EVENT_BUS.md +647 -0
  49. package/docs/plans/archive/WORKSPACE_V2_PLAN.md +2489 -0
  50. package/docs/plugins.md +158 -0
  51. package/package.json +164 -0
@@ -0,0 +1,452 @@
1
+ import { jsx as d, jsxs as Te, Fragment as x } from "react/jsx-runtime";
2
+ import { useSyncExternalStore as ze, useMemo as v, useRef as K, useState as X, useEffect as y, useCallback as P } from "react";
3
+ import { ChatPanel as Fe, useSessions as Ge } from "@hachej/boring-agent/front";
4
+ import { aj as ke, q as Ye, ak as Qe, u as Xe, al as Ze } from "./CommandPalette-aM61U-b0.js";
5
+ import { T as He, C as qe, r as Ee, w as et, W as $e } from "./WorkspaceLoadingState-By0dZoPD.js";
6
+ function tt() {
7
+ const e = `s${Date.now()}`;
8
+ return {
9
+ sessions: [{ id: e, title: "New session", updatedAt: Date.now() }],
10
+ activeId: e
11
+ };
12
+ }
13
+ function st(e, t) {
14
+ var r;
15
+ if (typeof localStorage > "u") return t();
16
+ try {
17
+ const s = localStorage.getItem(e);
18
+ if (s) {
19
+ const n = JSON.parse(s), c = Array.isArray(n.sessions) ? n.sessions : Array.isArray(n.items) ? n.items : null;
20
+ if (c)
21
+ return { sessions: c, activeId: n.activeId ?? ((r = c[0]) == null ? void 0 : r.id) ?? "" };
22
+ }
23
+ } catch {
24
+ }
25
+ return t();
26
+ }
27
+ function nt(e, t) {
28
+ if (!(typeof localStorage > "u"))
29
+ try {
30
+ localStorage.setItem(e, JSON.stringify(t));
31
+ } catch {
32
+ }
33
+ }
34
+ function rt(e = {}) {
35
+ const t = e.storageKey ?? "workspace:sessions", r = e.initial ?? tt;
36
+ let s = st(t, r);
37
+ const n = /* @__PURE__ */ new Set(), c = (a) => {
38
+ s = a, nt(t, s), n.forEach((i) => i());
39
+ };
40
+ return {
41
+ getState: () => s,
42
+ subscribe(a) {
43
+ return n.add(a), () => {
44
+ n.delete(a);
45
+ };
46
+ },
47
+ switchTo(a) {
48
+ c({ ...s, activeId: a });
49
+ },
50
+ create() {
51
+ const a = `s${Date.now()}`, i = {
52
+ id: a,
53
+ title: "New session",
54
+ updatedAt: Date.now()
55
+ };
56
+ c({ sessions: [i, ...s.sessions], activeId: a });
57
+ },
58
+ remove(a) {
59
+ var u;
60
+ const i = s.sessions.filter((p) => p.id !== a), h = s.activeId === a ? ((u = i[0]) == null ? void 0 : u.id) ?? "" : s.activeId;
61
+ c({ sessions: i, activeId: h });
62
+ }
63
+ };
64
+ }
65
+ function ot(e) {
66
+ return ze(e.subscribe, e.getState, e.getState);
67
+ }
68
+ function at(e) {
69
+ return e.type === "panel";
70
+ }
71
+ function ct(e, t) {
72
+ return e.endsWith(":surface") ? e.slice(0, -8) : t;
73
+ }
74
+ function xe(e, t, r) {
75
+ const [s, n] = X(() => Ee(e, t, r));
76
+ y(() => {
77
+ n(Ee(e, t, r));
78
+ }, [e, t, r]);
79
+ const c = P(
80
+ (a) => {
81
+ n(a), et(e, a, r);
82
+ },
83
+ [r, e]
84
+ );
85
+ return [s, c];
86
+ }
87
+ const it = {}, Ke = {
88
+ openTabs: [],
89
+ activeTab: null
90
+ };
91
+ function lt(e) {
92
+ if (!e) return "/api/v1/ui";
93
+ const t = e.replace(/\/$/, ""), r = "/api/v1/ui";
94
+ return t.endsWith(r) ? t : `${t}${r}`;
95
+ }
96
+ function ut(e) {
97
+ return `${lt(e)}/state`;
98
+ }
99
+ function ft(e) {
100
+ var s;
101
+ const t = e.openTabs.find((n) => n.id === e.activeTab), r = (s = t == null ? void 0 : t.params) == null ? void 0 : s.path;
102
+ return typeof r == "string" ? r : null;
103
+ }
104
+ function dt({
105
+ bridgeEndpoint: e,
106
+ requestHeaders: t,
107
+ navOpen: r,
108
+ surfaceOpen: s,
109
+ snapshot: n
110
+ }) {
111
+ const c = Xe(), a = K(null);
112
+ return y(() => {
113
+ var u;
114
+ if (e === null) return;
115
+ (u = a.current) == null || u.abort();
116
+ const i = new AbortController();
117
+ a.current = i;
118
+ const h = {
119
+ v: 1,
120
+ drawerOpen: r,
121
+ workbenchOpen: s,
122
+ openTabs: n.openTabs,
123
+ activeTab: n.activeTab,
124
+ activeFile: ft(n),
125
+ availablePanels: c.list().map((p) => p.id)
126
+ };
127
+ return fetch(ut(e), {
128
+ method: "PUT",
129
+ headers: { ...t, "Content-Type": "application/json" },
130
+ body: JSON.stringify({ state: h, causedBy: "user" }),
131
+ signal: i.signal
132
+ }).catch(() => {
133
+ }), () => {
134
+ i.abort();
135
+ };
136
+ }, [e, r, c, t, n, s]), null;
137
+ }
138
+ function Pt({
139
+ workspaceId: e,
140
+ chatPanel: t,
141
+ useSessions: r,
142
+ requestHeaders: s = it,
143
+ sessionStorageKey: n,
144
+ providerStorageKey: c,
145
+ surfaceStorageKey: a,
146
+ beforeShell: i,
147
+ afterShell: h,
148
+ panels: u,
149
+ commands: p,
150
+ catalogs: A,
151
+ plugins: g,
152
+ excludeDefaults: m,
153
+ capabilities: S,
154
+ apiBaseUrl: R,
155
+ authHeaders: T,
156
+ apiTimeout: j,
157
+ defaultTheme: Re,
158
+ onThemeChange: We,
159
+ persistenceEnabled: Z,
160
+ bridgeEndpoint: B,
161
+ onAuthError: Ce,
162
+ sessions: H,
163
+ activeSessionId: q,
164
+ onSwitchSession: ee,
165
+ onCreateSession: te,
166
+ onDeleteSession: se,
167
+ onActiveSessionIdChange: W,
168
+ appTitle: Oe = "Boring",
169
+ defaultSessionTitle: U = "New session",
170
+ topBarLeft: Le,
171
+ topBarRight: De,
172
+ chatParams: ne,
173
+ extraPanels: re,
174
+ extraCommands: oe,
175
+ onOpenNav: _,
176
+ onOpenSurface: M,
177
+ className: Ne
178
+ }) {
179
+ var be, we;
180
+ const J = c ?? `boring-ui-v2:layout:${e}`, f = a ?? `${J}:surface`, V = ct(
181
+ f,
182
+ J
183
+ ), z = Z !== !1, F = n ?? `boring-workspace:sessions:${e}`, C = v(
184
+ () => rt({ storageKey: F }),
185
+ [F]
186
+ ), ae = ot(C), Ie = t ?? Fe, G = r ?? (t ? void 0 : Ge), l = G == null ? void 0 : G({
187
+ requestHeaders: s,
188
+ storageKey: F
189
+ }), ce = H !== void 0 || q !== void 0 || ee !== void 0 || te !== void 0 || se !== void 0, Ae = l == null ? void 0 : l.sessions.map((o) => ({
190
+ ...o,
191
+ title: o.title ?? "New session"
192
+ })), Y = l ? Ae ?? [] : ce ? H ?? [] : ae.sessions, b = l ? l.activeSessionId ?? null : ce ? q ?? null : ae.activeId, je = (l == null ? void 0 : l.switch) ?? ee ?? C.switchTo, ie = l ? () => l.create() : te ?? C.create, Be = (l == null ? void 0 : l.delete) ?? se ?? C.remove, Ue = ((be = Y.find((o) => o.id === b)) == null ? void 0 : be.title) ?? void 0, [le, ue] = xe(
193
+ `${V}:drawer`,
194
+ !0,
195
+ z
196
+ ), [w, k] = xe(
197
+ // Key must NOT match resolvedSurfaceStorageKey (which stores the dockview
198
+ // layout JSON at the same ":surface" suffix). Writing "1"/"0" to the same
199
+ // key corrupts the JSON and drops the persisted workbench layout on reload.
200
+ `${V}:workbenchOpen`,
201
+ !1,
202
+ z
203
+ ), E = K(!1), $ = K(w), fe = K(f), de = K(null);
204
+ fe.current = f;
205
+ const [he, pe] = X(() => ({
206
+ key: f,
207
+ snapshot: Ke
208
+ })), _e = he.key === f ? he.snapshot : Ke;
209
+ y(() => {
210
+ E.current = !1;
211
+ }, [e]), y(() => {
212
+ if (!(!l || l.loading)) {
213
+ if (l.sessions.length > 0) {
214
+ E.current = !1;
215
+ return;
216
+ }
217
+ E.current || (E.current = !0, Promise.resolve(l.create({ title: U })).catch(() => {
218
+ E.current = !1;
219
+ }));
220
+ }
221
+ }, [U, l]), y(() => {
222
+ $.current = w;
223
+ }, [w]);
224
+ const me = P((o) => {
225
+ de.current = { key: f, api: o }, pe({
226
+ key: f,
227
+ snapshot: o.getSnapshot()
228
+ });
229
+ }, [f]), ye = P((o) => {
230
+ pe({
231
+ key: f,
232
+ snapshot: o
233
+ });
234
+ }, [f]), O = P(() => {
235
+ const o = de.current;
236
+ return (o == null ? void 0 : o.key) === fe.current ? o.api : null;
237
+ }, []), L = P(() => $.current, []), D = P(() => {
238
+ $.current = !0, k(!0);
239
+ }, [k]), N = v(
240
+ () => (g == null ? void 0 : g.flatMap((o) => o.outputs ?? [])) ?? [],
241
+ [g]
242
+ ), Me = v(
243
+ () => N.some((o) => o.type === "left-tab"),
244
+ [N]
245
+ ), ge = v(
246
+ () => N.filter(at).map((o) => o.panel.id),
247
+ [N]
248
+ ), ve = v(
249
+ () => [...re ?? [], ...ge],
250
+ [re, ge]
251
+ ), Se = b ?? ((we = Y[0]) == null ? void 0 : we.id) ?? "default";
252
+ y(() => {
253
+ var Pe;
254
+ const o = (I) => {
255
+ const Q = I.detail;
256
+ !Q || typeof Q != "object" || Qe(Q, {
257
+ surface: O,
258
+ isWorkbenchOpen: L,
259
+ openWorkbench: D
260
+ });
261
+ };
262
+ return (Pe = globalThis.addEventListener) == null || Pe.call(globalThis, ke, o), () => {
263
+ var I;
264
+ return (I = globalThis.removeEventListener) == null ? void 0 : I.call(globalThis, ke, o);
265
+ };
266
+ }, [O, L, D]), y(() => {
267
+ b && (W == null || W(b));
268
+ }, [b, W]);
269
+ const Je = v(
270
+ () => ({
271
+ ...ne,
272
+ sessionId: Se,
273
+ requestHeaders: s,
274
+ bridgeEndpoint: B,
275
+ getSurface: O,
276
+ isWorkbenchOpen: L,
277
+ openWorkbench: D,
278
+ extraCommands: oe
279
+ }),
280
+ [ne, Se, s, B, O, L, D, oe]
281
+ ), Ve = v(() => ({
282
+ storageKey: f,
283
+ extraPanels: ve,
284
+ onReady: me,
285
+ onChange: ye,
286
+ onClose: () => {
287
+ $.current = !1, k(!1);
288
+ }
289
+ }), [
290
+ ye,
291
+ me,
292
+ f,
293
+ ve,
294
+ k
295
+ ]);
296
+ return /* @__PURE__ */ d("div", { className: "h-full bg-background text-foreground", children: /* @__PURE__ */ Te(
297
+ Ye,
298
+ {
299
+ chatPanel: Ie,
300
+ panels: u,
301
+ commands: p,
302
+ catalogs: A,
303
+ plugins: g,
304
+ excludeDefaults: m,
305
+ capabilities: S,
306
+ apiBaseUrl: R,
307
+ authHeaders: T,
308
+ apiTimeout: j,
309
+ defaultTheme: Re,
310
+ onThemeChange: We,
311
+ workspaceId: e,
312
+ storageKey: J,
313
+ persistenceEnabled: Z,
314
+ bridgeEndpoint: null,
315
+ onAuthError: Ce,
316
+ children: [
317
+ i,
318
+ /* @__PURE__ */ d(
319
+ dt,
320
+ {
321
+ bridgeEndpoint: B,
322
+ requestHeaders: s,
323
+ navOpen: le,
324
+ surfaceOpen: w,
325
+ snapshot: _e
326
+ }
327
+ ),
328
+ /* @__PURE__ */ Te("div", { className: "flex h-full min-h-0 flex-col", children: [
329
+ /* @__PURE__ */ d(
330
+ He,
331
+ {
332
+ appTitle: Oe,
333
+ sessionTitle: Ue ?? U,
334
+ onCommandPalette: () => {
335
+ document.dispatchEvent(new KeyboardEvent("keydown", {
336
+ key: "k",
337
+ metaKey: !0,
338
+ ctrlKey: !0,
339
+ bubbles: !0,
340
+ cancelable: !0
341
+ }));
342
+ },
343
+ onNewChat: ie,
344
+ topBarLeft: Le,
345
+ topBarRight: De
346
+ }
347
+ ),
348
+ /* @__PURE__ */ d(
349
+ qe,
350
+ {
351
+ className: Ne,
352
+ nav: le ? "session-list" : null,
353
+ navParams: {
354
+ sessions: Y,
355
+ activeId: b,
356
+ onSwitch: je,
357
+ onCreate: ie,
358
+ onDelete: Be,
359
+ onClose: () => ue(!1)
360
+ },
361
+ center: "chat",
362
+ centerParams: Je,
363
+ surface: w ? "artifact-surface" : null,
364
+ surfaceParams: Ve,
365
+ sidebar: w && Me ? "workbench-left" : null,
366
+ storageKey: z ? V : void 0,
367
+ onOpenNav: () => {
368
+ ue(!0), _ == null || _();
369
+ },
370
+ onOpenSurface: () => {
371
+ $.current = !0, k(!0), M == null || M();
372
+ }
373
+ }
374
+ )
375
+ ] }),
376
+ h
377
+ ]
378
+ }
379
+ ) });
380
+ }
381
+ const ht = ["/api/v1/tree?path=.", "/api/v1/agent/sessions"];
382
+ function pt(e, t) {
383
+ return /^https?:\/\//i.test(t) || !e ? t : `${e.replace(/\/$/, "")}/${t.replace(/^\//, "")}`;
384
+ }
385
+ function mt(e) {
386
+ const t = new URL(e, "http://workspace.local");
387
+ return t.pathname !== "/api/v1/tree" ? null : t.searchParams.get("path") ?? ".";
388
+ }
389
+ function Tt({
390
+ workspaceId: e,
391
+ requestHeaders: t,
392
+ apiBaseUrl: r,
393
+ preloadPaths: s = ht,
394
+ loadingFallback: n,
395
+ errorFallback: c,
396
+ children: a
397
+ }) {
398
+ const [i, h] = X({
399
+ status: "loading",
400
+ label: "Waking workspace runtime"
401
+ });
402
+ return y(() => {
403
+ const u = new AbortController(), p = t ?? { "x-boring-workspace-id": e };
404
+ async function A(m) {
405
+ const S = await fetch(pt(r, m), {
406
+ headers: p,
407
+ signal: u.signal
408
+ });
409
+ if (!S.ok) {
410
+ const j = await S.text().catch(() => "");
411
+ throw new Error(j || `${m} failed with ${S.status}`);
412
+ }
413
+ const R = mt(m);
414
+ if (R === null) return;
415
+ const T = await S.clone().json().catch(() => null);
416
+ !T || !Array.isArray(T.entries) || Ze(r, p["x-boring-workspace-id"] ?? e, R, T.entries);
417
+ }
418
+ async function g() {
419
+ h({ status: "loading", label: "Waking workspace runtime" });
420
+ try {
421
+ await Promise.all(s.map(A)), u.signal.aborted || h({ status: "ready" });
422
+ } catch (m) {
423
+ if (u.signal.aborted) return;
424
+ h({
425
+ status: "error",
426
+ message: m instanceof Error ? m.message : "Unknown workspace boot error"
427
+ });
428
+ }
429
+ }
430
+ return g(), () => u.abort();
431
+ }, [r, s, t, e]), i.status === "ready" ? /* @__PURE__ */ d(x, { children: a }) : i.status === "error" ? typeof c == "function" ? /* @__PURE__ */ d(x, { children: c(i.message) }) : c ? /* @__PURE__ */ d(x, { children: c }) : /* @__PURE__ */ d(
432
+ $e,
433
+ {
434
+ title: "Workspace failed to open",
435
+ description: i.message,
436
+ status: "Retry by reloading the page"
437
+ }
438
+ ) : typeof n == "function" ? /* @__PURE__ */ d(x, { children: n(i.label) }) : n ? /* @__PURE__ */ d(x, { children: n }) : /* @__PURE__ */ d(
439
+ $e,
440
+ {
441
+ title: "Opening workspace",
442
+ description: "Waking the sandbox and preparing files, sessions, and layout.",
443
+ status: i.label
444
+ }
445
+ );
446
+ }
447
+ export {
448
+ Pt as WorkspaceAgentFront,
449
+ Tt as WorkspaceBootGate,
450
+ rt as createLocalStorageSessions,
451
+ ot as useLocalStorageSessions
452
+ };
@@ -0,0 +1,53 @@
1
+ import { CreateAgentAppOptions, PiPackageSource } from '@hachej/boring-agent/server';
2
+ export { PiPackageSource as WorkspacePiPackageSource } from '@hachej/boring-agent/server';
3
+ import { FastifyInstance } from 'fastify';
4
+ import { S as ServerBootstrapOptions, W as WorkspaceProvisioningContribution, a as WorkspaceRouteContribution } from './bootstrapServer-BRUqUpVW.js';
5
+ export { C as ComposeServerPluginsOptions, b as WorkspaceServerPlugin, c as composeServerPlugins, d as defineServerPlugin } from './bootstrapServer-BRUqUpVW.js';
6
+ import './agent-tool-NvxKfist.js';
7
+
8
+ /**
9
+ * Standalone workspace + agent Fastify composition.
10
+ *
11
+ * This entry intentionally imports @hachej/boring-agent/server. Browser-facing
12
+ * workspace entrypoints must not.
13
+ */
14
+
15
+ interface WorkspaceAgentResourceLoaderOptions {
16
+ noContextFiles?: boolean;
17
+ noSkills?: boolean;
18
+ additionalSkillPaths?: string[];
19
+ piPackages?: PiPackageSource[];
20
+ }
21
+ type WorkspaceAgentCreateOptions = Omit<CreateAgentAppOptions, "resourceLoaderOptions"> & {
22
+ resourceLoaderOptions?: WorkspaceAgentResourceLoaderOptions;
23
+ };
24
+ interface CreateWorkspaceAgentServerOptions extends WorkspaceAgentCreateOptions, Pick<ServerBootstrapOptions, "plugins" | "defaults" | "excludeDefaults"> {
25
+ provisionWorkspace?: boolean;
26
+ workspaceProvisioning?: {
27
+ force?: boolean;
28
+ };
29
+ /**
30
+ * Whether exec_ui should stat-check file paths against the workspaceRoot
31
+ * before queueing the command. Defaults to true in direct/local mode and
32
+ * false in vercel-sandbox (where workspace files live inside the microVM,
33
+ * not on the host server running this Fastify process).
34
+ */
35
+ validateUiPaths?: boolean;
36
+ }
37
+
38
+ interface WorkspaceAgentServerPluginCollection {
39
+ provisioningContributions: WorkspaceProvisioningContribution[];
40
+ routeContributions: WorkspaceRouteContribution[];
41
+ agentOptions: Pick<WorkspaceAgentCreateOptions, "extraTools" | "systemPromptAppend" | "resourceLoaderOptions">;
42
+ }
43
+ interface CollectWorkspaceAgentServerPluginsOptions extends Pick<WorkspaceAgentCreateOptions, "workspaceRoot" | "systemPromptAppend" | "resourceLoaderOptions">, Pick<ServerBootstrapOptions, "plugins" | "defaults" | "excludeDefaults"> {
44
+ }
45
+ declare function collectWorkspaceAgentServerPlugins(opts?: CollectWorkspaceAgentServerPluginsOptions): WorkspaceAgentServerPluginCollection;
46
+ declare function provisionWorkspaceAgentServer(opts: {
47
+ workspaceRoot: string;
48
+ provisioningContributions?: WorkspaceProvisioningContribution[];
49
+ force?: boolean;
50
+ }): Promise<void>;
51
+ declare function createWorkspaceAgentServer(opts?: CreateWorkspaceAgentServerOptions): Promise<FastifyInstance>;
52
+
53
+ export { type CollectWorkspaceAgentServerPluginsOptions, type CreateWorkspaceAgentServerOptions, type WorkspaceAgentResourceLoaderOptions, type WorkspaceAgentServerPluginCollection, WorkspaceProvisioningContribution, WorkspaceRouteContribution, collectWorkspaceAgentServerPlugins, createWorkspaceAgentServer, provisionWorkspaceAgentServer };