@fungi.computer/oyster 0.2.0 → 0.3.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 (287) hide show
  1. package/README.md +376 -72
  2. package/dist/agents.d.ts +3 -2
  3. package/dist/agents.js +4 -2
  4. package/dist/app-builds.d.ts +81 -8
  5. package/dist/app-builds.js +210 -60
  6. package/dist/app-storage.d.ts +3 -3
  7. package/dist/approval-capability.d.ts +5 -0
  8. package/dist/approval-capability.js +46 -0
  9. package/dist/approval-home.d.ts +51 -0
  10. package/dist/approval-home.js +226 -0
  11. package/dist/apps/catalog.d.ts +335 -0
  12. package/dist/apps/catalog.js +46 -0
  13. package/dist/apps/gate.d.ts +20 -6
  14. package/dist/apps/gate.js +42 -16
  15. package/dist/apps/index.d.ts +3 -1
  16. package/dist/apps/index.js +3 -1
  17. package/dist/apps/installation.d.ts +132 -51
  18. package/dist/apps/installation.js +176 -70
  19. package/dist/apps/permissions.d.ts +247 -0
  20. package/dist/apps/permissions.js +255 -0
  21. package/dist/boot-capability-route.d.ts +15 -0
  22. package/dist/boot-capability-route.js +196 -0
  23. package/dist/boot-capability.d.ts +103 -0
  24. package/dist/boot-capability.js +141 -0
  25. package/dist/boot-construction.d.ts +12 -0
  26. package/dist/boot-construction.js +175 -0
  27. package/dist/boot-gate.d.ts +267 -0
  28. package/dist/boot-gate.js +236 -0
  29. package/dist/boot-host-script.d.ts +2 -0
  30. package/dist/boot-host-script.js +1 -0
  31. package/dist/boot-mount.d.ts +21 -0
  32. package/dist/boot-mount.js +65 -0
  33. package/dist/browser/boot.d.ts +73 -0
  34. package/dist/browser/boot.js +502 -0
  35. package/dist/browser/browser.d.ts +104 -0
  36. package/dist/browser/browser.js +374 -0
  37. package/dist/browser/capability-source.d.ts +76 -0
  38. package/dist/browser/capability-source.js +338 -0
  39. package/dist/browser/cdp-client.d.ts +56 -0
  40. package/dist/browser/cdp-client.js +184 -0
  41. package/dist/browser/errors.d.ts +79 -0
  42. package/dist/browser/errors.js +32 -0
  43. package/dist/browser/index.d.ts +16 -0
  44. package/dist/browser/index.js +14 -0
  45. package/dist/browser/lease-registry.d.ts +61 -0
  46. package/dist/browser/lease-registry.js +101 -0
  47. package/dist/browser/operations.d.ts +225 -0
  48. package/dist/browser/operations.js +137 -0
  49. package/dist/browser/page.d.ts +25 -0
  50. package/dist/browser/page.js +172 -0
  51. package/dist/browser/quick-reads.d.ts +29 -0
  52. package/dist/browser/quick-reads.js +160 -0
  53. package/dist/browser/sessions.d.ts +52 -0
  54. package/dist/browser/sessions.js +118 -0
  55. package/dist/browser/url-policy.d.ts +18 -0
  56. package/dist/browser/url-policy.js +58 -0
  57. package/dist/build/app-imports.d.ts +12 -0
  58. package/dist/build/app-imports.js +105 -0
  59. package/dist/build/build-policy.d.ts +5 -3
  60. package/dist/build/build-policy.js +5 -3
  61. package/dist/build/candidate-builder.d.ts +1 -1
  62. package/dist/build/candidate-cli.mjs +8375 -334
  63. package/dist/build/local-build.d.ts +2 -0
  64. package/dist/build/local-build.js +28 -6
  65. package/dist/build/snapshot-package-store.d.ts +1 -1
  66. package/dist/build/snapshot-package-store.js +7 -2
  67. package/dist/build/workspace-build.d.ts +92 -5
  68. package/dist/build/workspace-build.js +93 -19
  69. package/dist/build.d.ts +1 -1
  70. package/dist/build.js +1 -1
  71. package/dist/catalog-frame.js +1 -1
  72. package/dist/cloudflare.d.ts +13 -3
  73. package/dist/cloudflare.js +102 -4
  74. package/dist/frame-binding-wire-script.js +1 -1
  75. package/dist/frame-binding-wire.js +4 -2
  76. package/dist/git-auth.d.ts +0 -2
  77. package/dist/git-auth.js +0 -2
  78. package/dist/git.d.ts +0 -1
  79. package/dist/git.js +0 -2
  80. package/dist/host.d.ts +39 -13
  81. package/dist/host.js +268 -142
  82. package/dist/index.d.ts +25 -15
  83. package/dist/index.js +39 -16
  84. package/dist/install-release-cli.d.ts +2 -0
  85. package/dist/install-release-cli.js +46 -0
  86. package/dist/installation-client.d.ts +43 -0
  87. package/dist/installation-client.js +178 -0
  88. package/dist/installation-execution.d.ts +11 -0
  89. package/dist/installation-execution.js +184 -0
  90. package/dist/installation-operations.d.ts +1437 -0
  91. package/dist/installation-operations.js +664 -0
  92. package/dist/installation-store-generation.d.ts +3 -0
  93. package/dist/installation-store-generation.js +16 -0
  94. package/dist/instance-id.d.ts +10 -0
  95. package/dist/instance-id.js +10 -0
  96. package/dist/instance-refusal.d.ts +11 -0
  97. package/dist/instance-refusal.js +21 -0
  98. package/dist/internal/delivery.js +4 -2
  99. package/dist/internal/host-gate.js +7 -1
  100. package/dist/internal/registry-installations.js +4 -4
  101. package/dist/keys.d.ts +5 -1
  102. package/dist/keys.js +10 -2
  103. package/dist/machine-link/authority.d.ts +89 -0
  104. package/dist/machine-link/authority.js +37 -0
  105. package/dist/machine-link/client.d.ts +66 -0
  106. package/dist/machine-link/client.js +94 -0
  107. package/dist/machine-link/delivery.d.ts +18 -0
  108. package/dist/machine-link/delivery.js +55 -0
  109. package/dist/machine-link/enrollment.d.ts +111 -0
  110. package/dist/machine-link/enrollment.js +286 -0
  111. package/dist/machine-link/fences.d.ts +37 -0
  112. package/dist/machine-link/fences.js +166 -0
  113. package/dist/machine-link/home.d.ts +20 -0
  114. package/dist/machine-link/home.js +24 -0
  115. package/dist/machine-link/host.d.ts +43 -0
  116. package/dist/machine-link/host.js +189 -0
  117. package/dist/machine-link/index.d.ts +15 -0
  118. package/dist/machine-link/index.js +15 -0
  119. package/dist/machine-link/link.d.ts +48 -0
  120. package/dist/machine-link/link.js +223 -0
  121. package/dist/machine-link/presence.d.ts +10 -0
  122. package/dist/machine-link/presence.js +25 -0
  123. package/dist/machine-link/workers.d.ts +6 -0
  124. package/dist/machine-link/workers.js +6 -0
  125. package/dist/mcp-owner.d.ts +2 -2
  126. package/dist/mcp-owner.js +41 -33
  127. package/dist/mcp.d.ts +15 -3
  128. package/dist/mcp.js +146 -25
  129. package/dist/pack.d.ts +14 -3
  130. package/dist/pack.js +44 -19
  131. package/dist/page/app-access.d.ts +7 -0
  132. package/dist/page/app-access.js +75 -0
  133. package/dist/page/boot-host.js +57 -0
  134. package/dist/page/capabilities.d.ts +3 -3
  135. package/dist/page/capabilities.js +16 -12
  136. package/dist/page/computer-handles.d.ts +3 -3
  137. package/dist/page/computer-target.d.ts +3 -0
  138. package/dist/page/computer-target.js +9 -0
  139. package/dist/page/mount.d.ts +23 -3
  140. package/dist/page/mount.js +152 -16
  141. package/dist/page-assets.d.ts +22 -0
  142. package/dist/page-assets.js +28 -0
  143. package/dist/page-script.d.ts +3 -0
  144. package/dist/page-script.js +5 -4
  145. package/dist/release.d.ts +13 -6
  146. package/dist/release.js +10 -7
  147. package/dist/root-data.d.ts +16 -6
  148. package/dist/root-data.js +2 -2
  149. package/dist/source/index.d.ts +1 -1
  150. package/dist/source/team-source.d.ts +20 -8
  151. package/dist/source/team-source.js +39 -10
  152. package/dist/source/template-seed.d.ts +2 -2
  153. package/dist/standalone/agent-mail.d.ts +24 -0
  154. package/dist/standalone/agent-mail.js +62 -0
  155. package/dist/standalone/agent-store.d.ts +9 -0
  156. package/dist/standalone/agent-store.js +30 -0
  157. package/dist/standalone/agents.d.ts +68 -9
  158. package/dist/standalone/agents.js +428 -56
  159. package/dist/standalone/app-builds-binding.d.ts +20 -2
  160. package/dist/standalone/app-builds-binding.js +147 -23
  161. package/dist/standalone/app-set.d.ts +5 -2
  162. package/dist/standalone/app-set.js +174 -143
  163. package/dist/standalone/browser.d.ts +11 -0
  164. package/dist/standalone/browser.js +72 -0
  165. package/dist/standalone/builds.d.ts +13 -4
  166. package/dist/standalone/builds.js +28 -44
  167. package/dist/standalone/computer-egress.d.ts +2 -0
  168. package/dist/standalone/computer-egress.js +13 -4
  169. package/dist/standalone/computer-fleet.d.ts +43 -0
  170. package/dist/standalone/computer-fleet.js +200 -0
  171. package/dist/standalone/computer.d.ts +44 -9
  172. package/dist/standalone/computer.js +129 -22
  173. package/dist/standalone/install-apps-cli.js +43 -6
  174. package/dist/standalone/instance.d.ts +2 -2
  175. package/dist/standalone/instance.js +8 -11
  176. package/dist/standalone/machine-link.d.ts +354 -0
  177. package/dist/standalone/machine-link.js +368 -0
  178. package/dist/standalone/media.d.ts +2 -2
  179. package/dist/standalone/media.js +19 -16
  180. package/dist/standalone/preview.d.ts +2 -2
  181. package/dist/standalone/preview.js +37 -10
  182. package/dist/standalone/registry.d.ts +149 -9
  183. package/dist/standalone/registry.js +299 -8
  184. package/dist/standalone/worker.d.ts +19 -5
  185. package/dist/standalone/worker.js +90 -54
  186. package/dist/standalone/workflow-binding.d.ts +18 -22
  187. package/dist/standalone/workflow-binding.js +18 -18
  188. package/dist/standalone/workflow-control.d.ts +4 -0
  189. package/dist/standalone/workflow-control.js +40 -0
  190. package/dist/standalone/workflow-events.d.ts +2 -2
  191. package/dist/standalone/workflow-events.js +9 -10
  192. package/dist/standalone/workflow-git-capture.js +4 -3
  193. package/dist/standalone/workflow-host.d.ts +162 -161
  194. package/dist/standalone/workflow-host.js +101 -21
  195. package/dist/standalone/workflow-node-capture.js +11 -4
  196. package/dist/standalone/workflow-schedules.d.ts +5 -2
  197. package/dist/standalone/workflow-schedules.js +9 -10
  198. package/dist/standalone/workflow-trigger-host.d.ts +65 -5
  199. package/dist/standalone/workflow-trigger-host.js +2 -2
  200. package/dist/standalone/workflow-webhooks.d.ts +22 -0
  201. package/dist/standalone/workflow-webhooks.js +39 -0
  202. package/dist/standalone/workflows.d.ts +140 -43
  203. package/dist/standalone/workflows.js +198 -39
  204. package/dist/storage-frame.d.ts +6 -6
  205. package/dist/testing/capabilities.js +14 -3
  206. package/dist/testing/installation.js +26 -2
  207. package/dist/testing/worker.js +1 -1
  208. package/dist/testing/workers-runtime.d.ts +8 -2
  209. package/dist/testing/workers-runtime.js +20 -2
  210. package/dist/webhook-abuse.d.ts +25 -0
  211. package/dist/webhook-abuse.js +54 -0
  212. package/dist/webhook-custody.d.ts +144 -0
  213. package/dist/webhook-custody.js +222 -0
  214. package/dist/webhook-ingress.d.ts +36 -0
  215. package/dist/webhook-ingress.js +146 -0
  216. package/dist/webhooks.d.ts +111 -0
  217. package/dist/webhooks.js +189 -0
  218. package/dist/workers-git.d.ts +12 -17
  219. package/dist/workers-git.js +60 -52
  220. package/dist/workers.d.ts +224 -13
  221. package/dist/workers.js +351 -51
  222. package/dist/workflow-agent-authority.d.ts +8 -0
  223. package/dist/workflow-agent-authority.js +42 -0
  224. package/dist/workflows.d.ts +66 -0
  225. package/dist/workflows.js +97 -0
  226. package/docs/api/README.md +63 -37
  227. package/docs/api/agents.md +17 -0
  228. package/docs/api/app-storage.md +1 -1
  229. package/docs/api/apps.md +1394 -543
  230. package/docs/api/browser/boot.md +132 -0
  231. package/docs/api/browser.md +1440 -0
  232. package/docs/api/build-contract.md +38 -25
  233. package/docs/api/build.md +263 -84
  234. package/docs/api/cloudflare.md +93 -7
  235. package/docs/api/git.md +3 -13
  236. package/docs/api/host.md +944 -118
  237. package/docs/api/index.md +320 -18
  238. package/docs/api/keys.md +24 -1
  239. package/docs/api/mcp.md +59 -12
  240. package/docs/api/modules.md +33 -40
  241. package/docs/api/pack.md +57 -8
  242. package/docs/api/page/mount.md +92 -4
  243. package/docs/api/workers-git.md +103 -24
  244. package/docs/api/workers.md +1581 -244
  245. package/docs/site/agent-quickstart.mdx +28 -14
  246. package/examples/standalone/worker.ts +3 -1
  247. package/examples/standalone/wrangler.jsonc +2 -0
  248. package/package.json +73 -71
  249. package/dist/installation-consent.d.ts +0 -81
  250. package/dist/installation-consent.js +0 -84
  251. package/dist/shell/app-directory.d.ts +0 -542
  252. package/dist/shell/app-directory.js +0 -196
  253. package/dist/shell/browser-actions.d.ts +0 -7
  254. package/dist/shell/browser-actions.js +0 -56
  255. package/dist/shell/command-host.d.ts +0 -112
  256. package/dist/shell/command-host.js +0 -502
  257. package/dist/shell/commands.d.ts +0 -25
  258. package/dist/shell/commands.js +0 -78
  259. package/dist/shell/index.d.ts +0 -8
  260. package/dist/shell/index.js +0 -8
  261. package/dist/shell/keys.d.ts +0 -41
  262. package/dist/shell/keys.js +0 -134
  263. package/dist/shell/shell-module.d.ts +0 -55
  264. package/dist/shell/shell-module.js +0 -86
  265. package/dist/shell/window-manager.d.ts +0 -128
  266. package/dist/shell/window-manager.js +0 -730
  267. package/dist/shell/workbench-contract.d.ts +0 -68
  268. package/dist/shell/workbench-directory.d.ts +0 -332
  269. package/dist/shell/workbench-directory.js +0 -35
  270. package/dist/shell/workbench-host-types.d.ts +0 -96
  271. package/dist/shell/workbench-host-types.js +0 -1
  272. package/dist/shell/workbench-host.d.ts +0 -34
  273. package/dist/shell/workbench-host.js +0 -352
  274. package/dist/shell/workbench-model.d.ts +0 -194
  275. package/dist/shell/workbench-model.js +0 -53
  276. package/dist/shell/workbench.d.ts +0 -4
  277. package/dist/shell/workbench.js +0 -2
  278. package/docs/api/shell/app-directory.md +0 -599
  279. package/docs/api/shell/command-host.md +0 -224
  280. package/docs/api/shell/commands.md +0 -197
  281. package/docs/api/shell/keys.md +0 -183
  282. package/docs/api/shell/shell-module.md +0 -204
  283. package/docs/api/shell/window-manager.md +0 -267
  284. package/docs/api/shell/workbench-directory.md +0 -119
  285. package/docs/api/shell/workbench.md +0 -205
  286. package/docs/api/shell.md +0 -1915
  287. /package/dist/{shell/workbench-contract.js → page/boot-host.d.ts} +0 -0
@@ -1,134 +0,0 @@
1
- /**
2
- * Single-chord and leader binding dispatch for the shell document. App frames
3
- * own their local key dispatch; reserved shell chords cross through the host.
4
- */
5
- /** Whistle binding prefix for a key pressed after the leader chord. */
6
- const leaderPrefix = "<leader> ";
7
- const keyNames = new Map([
8
- ["arrowleft", "left"],
9
- ["arrowright", "right"],
10
- ["arrowup", "up"],
11
- ["arrowdown", "down"],
12
- ["esc", "escape"],
13
- [" ", "space"],
14
- ]);
15
- /** Normalize a DOM key or binding key name to the binding vocabulary. */
16
- function keyName(key) {
17
- const lower = key.toLowerCase();
18
- return keyNames.get(lower) ?? lower;
19
- }
20
- /**
21
- * Parse one single-chord binding. Sequences (including `<leader> x`) and
22
- * unknown modifiers return `null`; they are never matched as one chord.
23
- */
24
- export function parseChord(binding, mac) {
25
- if (binding.trim().includes(" "))
26
- return null;
27
- const parts = binding.toLowerCase().split("+");
28
- const key = parts.pop();
29
- if (key === undefined || key.length === 0)
30
- return null;
31
- const chord = {
32
- key: keyName(key),
33
- alt: false,
34
- ctrl: false,
35
- meta: false,
36
- shift: false,
37
- };
38
- for (const modifier of parts) {
39
- if (modifier === "alt" || modifier === "option")
40
- chord.alt = true;
41
- else if (modifier === "ctrl" || modifier === "control")
42
- chord.ctrl = true;
43
- else if (modifier === "super" || modifier === "meta" || modifier === "cmd")
44
- chord.meta = true;
45
- else if (modifier === "shift")
46
- chord.shift = true;
47
- else if (modifier === "mod") {
48
- if (mac)
49
- chord.meta = true;
50
- else
51
- chord.ctrl = true;
52
- }
53
- else
54
- return null;
55
- }
56
- return chord;
57
- }
58
- /** Whether one key event is exactly this chord. */
59
- export function chordMatches(event, chord) {
60
- return (keyName(event.key) === chord.key &&
61
- event.altKey === chord.alt &&
62
- event.ctrlKey === chord.ctrl &&
63
- event.metaKey === chord.meta &&
64
- event.shiftKey === chord.shift);
65
- }
66
- /** The `<leader> x` rows of the active view, first binding per key. */
67
- export function leaderKeys(active) {
68
- const seen = new Set();
69
- const rows = [];
70
- for (const row of active.bindings) {
71
- if (!row.binding.startsWith(leaderPrefix))
72
- continue;
73
- const key = row.binding.slice(leaderPrefix.length).trim();
74
- if (key.length === 0 || key.includes(" ") || seen.has(key))
75
- continue;
76
- seen.add(key);
77
- rows.push({ ...row, key });
78
- }
79
- return rows;
80
- }
81
- /** Whether one key event (after the leader) selects this leader key. */
82
- export function leaderKeyMatches(event, key) {
83
- if (event.altKey || event.ctrlKey || event.metaKey)
84
- return false;
85
- return event.key === key || keyName(event.key) === key;
86
- }
87
- /** Whether the event started in text entry, including inside shadow roots. */
88
- function isEditing(event) {
89
- return event
90
- .composedPath()
91
- .some((node) => node instanceof HTMLElement &&
92
- (node.isContentEditable ||
93
- node.getAttribute("contenteditable") === "true" ||
94
- node.matches("input, textarea, select")));
95
- }
96
- /**
97
- * Dispatch the active view's single-chord bindings from the shell document.
98
- * Text entry is a mode: while an input is focused only Ctrl/Cmd chords fire,
99
- * so Alt-arrows keep their word-navigation meaning.
100
- */
101
- export function installShellKeys(root, host, mac) {
102
- let chords = [];
103
- const refresh = () => {
104
- chords = host.active().bindings.flatMap(({ binding, commandId }) => {
105
- const chord = parseChord(binding, mac);
106
- return chord === null ? [] : [{ commandId, chord }];
107
- });
108
- };
109
- const onKeyDown = (event) => {
110
- if (event.defaultPrevented || event.isComposing)
111
- return;
112
- const editing = isEditing(event);
113
- const match = chords.find(({ chord }) => chordMatches(event, chord) && (!editing || chord.ctrl || chord.meta));
114
- if (match === undefined)
115
- return;
116
- event.preventDefault();
117
- void host
118
- .execute(match.commandId, { origin: "keyboard" })
119
- .catch((cause) => {
120
- console.warn("Shell key command failed", cause);
121
- });
122
- };
123
- refresh();
124
- const unsubscribe = host.subscribe(refresh);
125
- root.addEventListener("keydown", onKeyDown, { capture: true });
126
- let cleaned = false;
127
- return () => {
128
- if (cleaned)
129
- return;
130
- cleaned = true;
131
- unsubscribe();
132
- root.removeEventListener("keydown", onKeyDown, { capture: true });
133
- };
134
- }
@@ -1,55 +0,0 @@
1
- import type { AppStorage } from "@fungi.computer/agar/storage";
2
- import type { WhistleJsonValue } from "@fungi.computer/whistle";
3
- import type { TeamWorkbenchHostHandle } from "./workbench-contract.js";
4
- import type { WorkbenchHostControls } from "./workbench-host-types.js";
5
- /**
6
- * What a host hands the shell a Team picked. The host composes that shell into
7
- * its own top-level document, so it runs with the host's escalated
8
- * permissions: the workbench mounts each child App in its sandboxed frame, and
9
- * `storage`/`methods` are the shell installation's own desktop data.
10
- */
11
- export type ShellMountInput = Readonly<{
12
- workbench: TeamWorkbenchHostHandle;
13
- storage: AppStorage;
14
- methods: Readonly<{
15
- /** Call one of the shell installation's declared backend methods. */
16
- call(method: string, input: string): Promise<WhistleJsonValue>;
17
- }>;
18
- }>;
19
- /**
20
- * Render the shell into `root`; resolves once it is mounted, with the
21
- * function that removes it again. The shell loads its own code and styles.
22
- */
23
- export type MountShell = (root: HTMLElement, input: ShellMountInput) => Promise<() => void>;
24
- /**
25
- * Settings a shell renders for a host that has none of its own, such as a
26
- * standalone Oyster: the shell draws them into `root`, and the host hands
27
- * `controls` to its workbench so Apps and the dashboard can open them.
28
- */
29
- export type ShellPlatformControls = Readonly<{
30
- controls: WorkbenchHostControls;
31
- /** A child App suggested desktop Settings for one of its surfaces. */
32
- suggestDesktopSettings(surfaceId: string): void;
33
- /** Remove the rendered Settings. */
34
- dispose(): void;
35
- }>;
36
- /** Render the shell's own Settings into `root` for the host at `teamId`. */
37
- export type MountPlatformControls = (root: HTMLElement, input: Readonly<{
38
- teamId: string;
39
- }>) => Promise<ShellPlatformControls>;
40
- /** What a host gets from a picked shell Release's module. */
41
- export type ShellModule = Readonly<{
42
- mountShell: MountShell;
43
- /** Absent when the shell renders no Settings of its own. */
44
- mountPlatformControls: MountPlatformControls | null;
45
- }>;
46
- /** The picked shell's module could not be loaded or does not fit the contract. */
47
- export declare class ShellModuleError extends Error {
48
- readonly name = "ShellModuleError";
49
- }
50
- /**
51
- * Import the picked shell Release's module from the host's own origin and
52
- * check that it exports `mountShell`, and `mountPlatformControls` when it
53
- * offers its own Settings. The host never bundles a shell.
54
- */
55
- export declare function importShellModule(moduleUrl: URL, hostOrigin: string): Promise<ShellModule>;
@@ -1,86 +0,0 @@
1
- import * as z from "zod";
2
- const unsubscribe = () => z.function({ input: [], output: z.void() });
3
- /** The module namespace a shell Release must export; built on first use,
4
- * since only a browser has `HTMLElement`. */
5
- const shellModuleSchema = () => z.object({
6
- mountShell: z.function({
7
- // The host supplies the input itself; the shell parses its own handles.
8
- input: [z.instanceof(HTMLElement), z.unknown()],
9
- output: z.promise(z.function({ input: [], output: z.void() })),
10
- }),
11
- mountPlatformControls: z
12
- .function({
13
- input: [
14
- z.instanceof(HTMLElement),
15
- z.object({ teamId: z.string() }).readonly(),
16
- ],
17
- output: z.promise(z.object({
18
- controls: z.object({
19
- sections: z.array(z.string()).readonly().optional(),
20
- // The host passes the workbench's own values; the shell
21
- // parses what it reads.
22
- parseSettings: z.function({
23
- input: [z.unknown()],
24
- output: z.json(),
25
- }),
26
- openSettings: z.function({
27
- input: [z.unknown(), z.object({ restoreFocus: z.boolean() })],
28
- output: z.void(),
29
- }),
30
- subscribeSettingsClosed: z.function({
31
- input: [unsubscribe()],
32
- output: unsubscribe(),
33
- }),
34
- subscribeChanges: z.function({
35
- input: [unsubscribe()],
36
- output: unsubscribe(),
37
- }),
38
- attachDesktopSettings: z.function({
39
- input: [z.unknown()],
40
- output: unsubscribe(),
41
- }),
42
- requestAppAccess: z.function({
43
- input: [z.unknown(), z.unknown()],
44
- output: z.promise(z.enum(["granted", "declined", "customize"])),
45
- }),
46
- }),
47
- suggestDesktopSettings: z.function({
48
- input: [z.string()],
49
- output: z.void(),
50
- }),
51
- dispose: unsubscribe(),
52
- })),
53
- })
54
- .optional(),
55
- });
56
- /** The picked shell's module could not be loaded or does not fit the contract. */
57
- export class ShellModuleError extends Error {
58
- name = "ShellModuleError";
59
- }
60
- /**
61
- * Import the picked shell Release's module from the host's own origin and
62
- * check that it exports `mountShell`, and `mountPlatformControls` when it
63
- * offers its own Settings. The host never bundles a shell.
64
- */
65
- export async function importShellModule(moduleUrl, hostOrigin) {
66
- if (moduleUrl.origin !== hostOrigin || moduleUrl.hash !== "")
67
- throw new ShellModuleError("The shell module must come from this host");
68
- let namespace;
69
- try {
70
- namespace = await import(/* @vite-ignore */ moduleUrl.href);
71
- }
72
- catch (cause) {
73
- throw new ShellModuleError("The picked shell could not be loaded", {
74
- cause,
75
- });
76
- }
77
- const decoded = shellModuleSchema().safeParse(namespace);
78
- if (!decoded.success)
79
- throw new ShellModuleError("The picked shell does not export mountShell", {
80
- cause: decoded.error,
81
- });
82
- return {
83
- mountShell: decoded.data.mountShell,
84
- mountPlatformControls: decoded.data.mountPlatformControls ?? null,
85
- };
86
- }
@@ -1,128 +0,0 @@
1
- import { type AppNavigationActivation, type AppNavigationState, type AppStatusAction, type AppStatusItem } from "@fungi.computer/agar";
2
- /** Minimum identity required to own a window across mount generations. */
3
- export type WindowLaunch = Readonly<{
4
- windowId: string;
5
- }>;
6
- /** Current presentation state of a managed window. */
7
- export type WindowStatus = "loading" | "ready" | "minimized" | "error";
8
- /** Mount operations supplied by the embedding host; selection and authority stay with it. */
9
- export type WindowHost<Launch extends WindowLaunch> = Readonly<{
10
- /** Show or hide the current mount without disposing it. */
11
- setVisibility: (visibility: "hidden" | "visible") => void | Promise<void>;
12
- /** Reconfigure the mounted App without replacing its iframe or root. */
13
- reconfigure: (launch: Launch, signal?: AbortSignal) => void | Promise<void>;
14
- /** Ask the mounted App whether a user initiated close may discard work. */
15
- requestClose?: () => boolean | Promise<boolean>;
16
- /** Ask the mounted App to go back in its own history; `true` when it did. */
17
- requestBack?: () => boolean | Promise<boolean>;
18
- /** Deliver the person's use of a crumb or header command; `true` when the App acted. */
19
- activateNavigation?: (activation: AppNavigationActivation) => boolean | Promise<boolean>;
20
- /** Deliver the person's use of a status item; `true` when the App acted. */
21
- activateStatus?: (action: AppStatusAction) => boolean | Promise<boolean>;
22
- /** Release the current mount and its host resources. */
23
- dispose: () => void | Promise<void>;
24
- }>;
25
- /** What a mounted App tells its window while it lives. */
26
- export type WindowEvents = Readonly<{
27
- /** Open this generation's shell-owned Computer picker. */
28
- onComputerChoice: () => Promise<void>;
29
- /** The App's latest parsed navigation state; `null` withdraws it. */
30
- onNavigationState: (state: AppNavigationState | null) => void;
31
- /** The App's latest parsed status readouts; an empty list clears them. */
32
- onStatusItems: (items: readonly AppStatusItem[]) => void;
33
- }>;
34
- /** Immutable snapshot of one window and its mount generation. */
35
- export type WindowProjection<Launch extends WindowLaunch, Container> = Readonly<{
36
- windowId: string;
37
- launch: Launch;
38
- container: Container;
39
- status: WindowStatus;
40
- generation: number;
41
- error?: unknown;
42
- cleanupError?: unknown;
43
- /** The ready App's navigation state; `null` while it reports none. */
44
- navigation: AppNavigationState | null;
45
- /** The App's status readouts for its window's status bar. */
46
- statusItems: readonly AppStatusItem[];
47
- }>;
48
- /** Current ordered collection of managed window snapshots. */
49
- export type WindowsProjection<Launch extends WindowLaunch, Container> = Readonly<{
50
- windows: readonly WindowProjection<Launch, Container>[];
51
- }>;
52
- /** Whether any projected App window is still visible in the workspace. */
53
- export declare function hasVisibleWindows<Launch extends WindowLaunch, Container>(projection: WindowsProjection<Launch, Container>): boolean;
54
- /** Create a host-owned mount in a container, observing cancellation and navigation. */
55
- export type WindowMount<Launch extends WindowLaunch, Container> = (container: Container, launch: Launch, signal: AbortSignal, events: WindowEvents) => WindowHost<Launch> | Promise<WindowHost<Launch>>;
56
- /** Own window lifetimes, visibility and serialized host mutations. */
57
- export type WindowManager<Launch extends WindowLaunch, Container> = Readonly<{
58
- /** Open a window or restore the existing window with the same identity. */
59
- open: (launch: Launch) => Promise<void>;
60
- /** Notify the manager that a waiting container is attached. */
61
- attach: (windowId: string) => void;
62
- /** Hide one window without disposing its mount. */
63
- minimize: (windowId: string) => Promise<void>;
64
- /** Show an individually hidden window. */
65
- restore: (windowId: string) => Promise<void>;
66
- /** Hide visible Apps without closing them; preserve individually minimized Apps. */
67
- hideAll: () => Promise<void>;
68
- /** Restore surviving windows from the last Show desktop operation. */
69
- restoreHidden: () => Promise<void>;
70
- /** Consult the App before disposing and removing its window. */
71
- close: (windowId: string) => Promise<void>;
72
- /** Update a mounted window through the host after validation. */
73
- reconfigure: (windowId: string, launch: Launch) => Promise<void>;
74
- /**
75
- * Reconfigure from the launch committed when the window's mutation queue
76
- * reaches this change, so it never reapplies a stale snapshot over an
77
- * earlier queued change.
78
- */
79
- update: (windowId: string, derive: (current: Launch) => Launch) => Promise<void>;
80
- /** Consult the old App, dispose it, then create a new mount generation. */
81
- replace: (windowId: string, launch: Launch) => Promise<void>;
82
- /** Ask a ready window's App to go back; `false` when it cannot. */
83
- back: (windowId: string) => Promise<boolean>;
84
- /** Deliver a crumb or header command to a ready window's App; `false` when it cannot. */
85
- activateNavigation: (windowId: string, activation: AppNavigationActivation) => Promise<boolean>;
86
- /** Deliver a status item action to a ready window's App; `false` when it cannot. */
87
- activateStatus: (windowId: string, action: AppStatusAction) => Promise<boolean>;
88
- /** Register the current window generation's host-owned picker. */
89
- registerComputerChoice: (windowId: string, handler: () => void) => () => void;
90
- /** Dispose all surviving windows and release subscriptions. */
91
- dispose: () => Promise<void>;
92
- /** Read the current immutable window projection. */
93
- read: () => WindowsProjection<Launch, Container>;
94
- /** Observe projection changes until the returned disposer is called. */
95
- subscribe: (listener: () => void) => () => void;
96
- }>;
97
- /** Host adapters used to create, attach and validate window mounts. */
98
- export type WindowManagerOptions<Launch extends WindowLaunch, Container> = Readonly<{
99
- mount: WindowMount<Launch, Container>;
100
- /** Create a container for a new window generation. */
101
- createContainer: (launch: Launch) => Container;
102
- /**
103
- * A renderer may create a projection container before attaching it. Waiting
104
- * here keeps iframe and Agar setup inside a real document tree.
105
- */
106
- waitForAttachment?: boolean;
107
- /** Observe mount or mutation failures, including failures after retirement. */
108
- onFailure?: (failure: Readonly<{
109
- windowId: string;
110
- generation: number | null;
111
- phase: "mount" | "mutation";
112
- cause: unknown;
113
- }>) => void;
114
- /** Report whether the renderer has attached a container. */
115
- isAttached?: (container: Container) => boolean;
116
- /** Reject an inadmissible launch change before it reaches the mounted host. */
117
- validateReconfiguration?: (current: Launch, next: Launch) => void;
118
- /**
119
- * Whether `next` differs from `current` only in shell chrome the mounted
120
- * App never sees. Such a change is committed without reconfiguring the App.
121
- */
122
- isChromeOnlyChange?: (current: Launch, next: Launch) => boolean;
123
- }>;
124
- /**
125
- * Owns App-window generations while leaving selection and App authority to the
126
- * caller. A stale mount is always disposed when it eventually resolves.
127
- */
128
- export declare function createWindowManager<Launch extends WindowLaunch, Container>(options: WindowManagerOptions<Launch, Container>): WindowManager<Launch, Container>;