@fungi.computer/oyster 0.0.1 → 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 (171) hide show
  1. package/README.md +228 -176
  2. package/dist/app-builds.d.ts +76 -17
  3. package/dist/app-builds.js +207 -63
  4. package/dist/app-sources.d.ts +7 -22
  5. package/dist/app-sources.js +49 -14
  6. package/dist/build/artifact-writer.d.ts +40 -0
  7. package/dist/build/artifact-writer.js +181 -0
  8. package/dist/build/build-jobs.js +7 -1
  9. package/dist/build/build-policy.d.ts +10 -0
  10. package/dist/build/build-policy.js +10 -0
  11. package/dist/build/build-step.d.ts +12 -1
  12. package/dist/build/build-step.js +9 -1
  13. package/dist/build/candidate-builder.d.ts +68 -0
  14. package/dist/build/candidate-builder.js +91 -0
  15. package/dist/build/candidate-cli.d.ts +1 -0
  16. package/dist/build/candidate-cli.js +119 -0
  17. package/dist/build/candidate-cli.mjs +28170 -0
  18. package/dist/build/content-objects.d.ts +37 -0
  19. package/dist/build/content-objects.js +53 -0
  20. package/dist/build/effect.d.ts +18 -0
  21. package/dist/build/effect.js +52 -12
  22. package/dist/build/git-environment.d.ts +3 -0
  23. package/dist/build/git-environment.js +21 -9
  24. package/dist/build/local-build.d.ts +13 -3
  25. package/dist/build/local-build.js +149 -99
  26. package/dist/build/snapshot-package-store.d.ts +10 -0
  27. package/dist/build/snapshot-package-store.js +15 -0
  28. package/dist/build/snapshot-program-scripts.js +1 -1
  29. package/dist/build/snapshot-programs/snapshot-path.d.ts +2 -0
  30. package/dist/build/snapshot-programs/snapshot-path.js +6 -0
  31. package/dist/build/submission-contract.d.ts +461 -17
  32. package/dist/build/submission-contract.js +136 -26
  33. package/dist/build/workspace-build.d.ts +7 -2
  34. package/dist/build/workspace-build.js +55 -11
  35. package/dist/build-contract.d.ts +3 -0
  36. package/dist/build-contract.js +3 -0
  37. package/dist/build-egress.d.ts +62 -0
  38. package/dist/build-egress.js +148 -0
  39. package/dist/build.d.ts +1 -0
  40. package/dist/build.js +1 -0
  41. package/dist/mcp-owner.js +20 -8
  42. package/dist/pack.d.ts +6 -3
  43. package/dist/pack.js +28 -11
  44. package/dist/page/gill-observation.d.ts +4 -0
  45. package/dist/page/gill-observation.js +31 -0
  46. package/dist/page/window-launch.d.ts +18 -0
  47. package/dist/page/window-launch.js +11 -0
  48. package/dist/page-script.js +2 -2
  49. package/dist/release.d.ts +11 -0
  50. package/dist/release.js +4 -1
  51. package/dist/shell/app-directory.d.ts +13 -8
  52. package/dist/shell/app-directory.js +4 -0
  53. package/dist/shell/shell-module.d.ts +26 -2
  54. package/dist/shell/shell-module.js +51 -2
  55. package/dist/shell/workbench-directory.d.ts +332 -0
  56. package/dist/shell/workbench-directory.js +35 -0
  57. package/dist/source/index.d.ts +6 -7
  58. package/dist/source/index.js +6 -7
  59. package/dist/source/template-push.d.ts +33 -0
  60. package/dist/source/template-push.js +223 -0
  61. package/dist/source/template-repository.d.ts +2 -0
  62. package/dist/source/template-repository.js +13 -0
  63. package/dist/source/{template-write.d.ts → template-seed.d.ts} +19 -20
  64. package/dist/source/template-seed.js +80 -0
  65. package/dist/standalone/agent-directory.d.ts +4 -0
  66. package/dist/standalone/agent-directory.js +4 -0
  67. package/dist/standalone/agents.d.ts +220 -0
  68. package/dist/standalone/agents.js +795 -0
  69. package/dist/standalone/app-builds-binding.d.ts +36 -0
  70. package/dist/standalone/app-builds-binding.js +119 -0
  71. package/dist/standalone/app-set.d.ts +91 -0
  72. package/dist/standalone/app-set.js +395 -0
  73. package/dist/standalone/app-source.d.ts +41 -0
  74. package/dist/standalone/app-source.js +59 -0
  75. package/dist/standalone/builds.d.ts +18 -0
  76. package/dist/standalone/builds.js +101 -0
  77. package/dist/standalone/computer-egress.d.ts +37 -0
  78. package/dist/standalone/computer-egress.js +111 -0
  79. package/dist/standalone/computer.d.ts +122 -0
  80. package/dist/standalone/computer.js +714 -0
  81. package/dist/standalone/install-apps-cli.d.ts +2 -0
  82. package/dist/standalone/install-apps-cli.js +126 -0
  83. package/dist/standalone/instance.d.ts +35 -0
  84. package/dist/standalone/instance.js +74 -0
  85. package/dist/standalone/media.d.ts +76 -0
  86. package/dist/standalone/media.js +227 -0
  87. package/dist/standalone/preview.d.ts +51 -0
  88. package/dist/standalone/preview.js +167 -0
  89. package/dist/standalone/registry.d.ts +102 -0
  90. package/dist/standalone/registry.js +193 -0
  91. package/dist/standalone/tenancy.d.ts +42 -0
  92. package/dist/standalone/tenancy.js +241 -0
  93. package/dist/standalone/worker.d.ts +55 -0
  94. package/dist/standalone/worker.js +147 -0
  95. package/dist/standalone/workflow-authority-readers.d.ts +16 -0
  96. package/dist/standalone/workflow-authority-readers.js +35 -0
  97. package/dist/standalone/workflow-binding.d.ts +216 -0
  98. package/dist/standalone/workflow-binding.js +217 -0
  99. package/dist/standalone/workflow-events.d.ts +46 -0
  100. package/dist/standalone/workflow-events.js +39 -0
  101. package/dist/standalone/workflow-git-capture.d.ts +7 -0
  102. package/dist/standalone/workflow-git-capture.js +62 -0
  103. package/dist/standalone/workflow-host.d.ts +931 -0
  104. package/dist/standalone/workflow-host.js +751 -0
  105. package/dist/standalone/workflow-node-capture.d.ts +13 -0
  106. package/dist/standalone/workflow-node-capture.js +72 -0
  107. package/dist/standalone/workflow-root-authority.d.ts +27 -0
  108. package/dist/standalone/workflow-root-authority.js +87 -0
  109. package/dist/standalone/workflow-schedules.d.ts +52 -0
  110. package/dist/standalone/workflow-schedules.js +40 -0
  111. package/dist/standalone/workflow-trigger-host.d.ts +1694 -0
  112. package/dist/standalone/workflow-trigger-host.js +52 -0
  113. package/dist/standalone/workflows.d.ts +657 -0
  114. package/dist/standalone/workflows.js +554 -0
  115. package/dist/tenancy/auth0.d.ts +64 -0
  116. package/dist/tenancy/auth0.js +198 -0
  117. package/dist/tenancy/cloudflare/rate-limit.d.ts +8 -0
  118. package/dist/tenancy/cloudflare/rate-limit.js +19 -0
  119. package/dist/tenancy/cloudflare/registry.d.ts +50 -0
  120. package/dist/tenancy/cloudflare/registry.js +301 -0
  121. package/dist/tenancy/cloudflare.d.ts +2 -0
  122. package/dist/tenancy/cloudflare.js +2 -0
  123. package/dist/tenancy/cold-directory.d.ts +13 -0
  124. package/dist/tenancy/cold-directory.js +43 -0
  125. package/dist/tenancy/contracts.d.ts +195 -0
  126. package/dist/tenancy/contracts.js +1 -0
  127. package/dist/tenancy/index.d.ts +19 -0
  128. package/dist/tenancy/index.js +156 -0
  129. package/dist/tenancy/owner-key.d.ts +26 -0
  130. package/dist/tenancy/owner-key.js +63 -0
  131. package/dist/tenancy/oyster.d.ts +4 -0
  132. package/dist/tenancy/oyster.js +25 -0
  133. package/dist/tenancy/registry-record.d.ts +7 -0
  134. package/dist/tenancy/registry-record.js +44 -0
  135. package/dist/tenancy/registry.d.ts +27 -0
  136. package/dist/tenancy/registry.js +138 -0
  137. package/dist/tenancy/resolve.d.ts +7 -0
  138. package/dist/tenancy/resolve.js +64 -0
  139. package/dist/workers.d.ts +2 -2
  140. package/dist/workers.js +3 -1
  141. package/docs/api/build-contract.md +829 -32
  142. package/docs/api/build.md +253 -17
  143. package/docs/api/modules.md +40 -32
  144. package/docs/api/pack.md +6 -3
  145. package/docs/api/shell/app-directory.md +267 -0
  146. package/docs/api/shell/shell-module.md +64 -3
  147. package/docs/api/shell/workbench-directory.md +119 -0
  148. package/docs/api/shell/workbench.md +19 -0
  149. package/docs/api/shell.md +127 -0
  150. package/docs/api/tenancy/auth0.md +110 -0
  151. package/docs/api/tenancy/cloudflare.md +221 -0
  152. package/docs/api/tenancy/cold-directory.md +46 -0
  153. package/docs/api/tenancy/owner-key.md +63 -0
  154. package/docs/api/tenancy/registry.md +77 -0
  155. package/docs/api/tenancy/resolve.md +69 -0
  156. package/docs/api/tenancy.md +430 -0
  157. package/docs/api/workers-git.md +140 -21
  158. package/docs/api/workers.md +15 -2
  159. package/docs/site/agent-quickstart.mdx +52 -55
  160. package/examples/standalone/worker.ts +7 -14
  161. package/examples/standalone/wrangler.jsonc +67 -6
  162. package/package.json +72 -21
  163. package/dist/build/r2-artifact-writer.d.ts +0 -31
  164. package/dist/build/r2-artifact-writer.js +0 -179
  165. package/dist/source/template-write.js +0 -344
  166. package/docs/media/architecture.mmd +0 -32
  167. package/docs/media/architecture.png +0 -0
  168. package/docs/media/bonsai-network.png +0 -0
  169. package/docs/media/bonsai-repository.png +0 -0
  170. package/examples/git/worker.ts +0 -39
  171. package/examples/git/wrangler.jsonc +0 -32
package/dist/release.d.ts CHANGED
@@ -9,6 +9,17 @@ export type ArtifactStore = Readonly<{
9
9
  /** Store bytes under `artifactRef`; the caller has verified the digest. */
10
10
  put: (artifactRef: ArtifactRef, bytes: Uint8Array) => Promise<void>;
11
11
  }>;
12
+ /** What a store knows of one object without reading it. */
13
+ export type ArtifactHead = Readonly<{
14
+ byteLength: number;
15
+ /** The digest the store verified when it took the bytes, if it did. */
16
+ digest: Sha256Digest | null;
17
+ }>;
18
+ /** A store that can describe an object without reading its bytes. */
19
+ export type ArtifactHeads = Readonly<{
20
+ /** Describe the object at `artifactRef`, or `null` when absent. */
21
+ head: (artifactRef: ArtifactRef) => Promise<ArtifactHead | null>;
22
+ }>;
12
23
  /** Why a Release could not be read; the host maps it to an HTTP refusal. */
13
24
  export declare class ReleaseError extends Error {
14
25
  readonly code: "artifact_missing" | "digest_mismatch" | "invalid_release" | "asset_missing";
package/dist/release.js CHANGED
@@ -79,8 +79,11 @@ readAssets = true) {
79
79
  catch (cause) {
80
80
  throw new ReleaseError("invalid_release", "Invalid assets", { cause });
81
81
  }
82
+ // One asset at a time: a Release's assets together can exceed an
83
+ // isolate's memory, each alone is bounded by its policy.
82
84
  if (readAssets)
83
- await Promise.all(assets.assets.map((asset) => readVerified(store, asset.artifactRef, asset.digest)));
85
+ for (const asset of assets.assets)
86
+ await readVerified(store, asset.artifactRef, asset.digest);
84
87
  ui = { kind: "assets", build: assets };
85
88
  }
86
89
  else
@@ -132,13 +132,7 @@ export declare const appRoleSelectionSchema: z.ZodObject<{
132
132
  surfaceId: z.ZodNullable<z.ZodString>;
133
133
  chosen: z.ZodBoolean;
134
134
  }, z.core.$strict>;
135
- declare const appComputerOperationSchema: z.ZodEnum<{
136
- "computer.list": "computer.list";
137
- "computer.readFile": "computer.readFile";
138
- "computer.writeFile": "computer.writeFile";
139
- "computer.execute": "computer.execute";
140
- }>;
141
- export type AppComputerOperation = z.output<typeof appComputerOperationSchema>;
135
+ /** App Computer permissions limited to selected Computers or the Team's Computers. */
142
136
  export declare const appComputerPermissionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
143
137
  kind: z.ZodLiteral<"selected-computers">;
144
138
  computers: z.ZodArray<z.ZodObject<{
@@ -159,7 +153,13 @@ export declare const appComputerPermissionSchema: z.ZodDiscriminatedUnion<[z.Zod
159
153
  "computer.execute": "computer.execute";
160
154
  }>>;
161
155
  }, z.core.$strict>], "kind">;
156
+ /** One operation an App may request for a Computer. */
157
+ export type AppComputerOperation = Extract<z.output<typeof appComputerPermissionSchema>, {
158
+ kind: "all-team-computers";
159
+ }>["operations"][number];
160
+ /** Decoded Computer permission scope attached to an App directory entry. */
162
161
  export type AppComputerPermission = z.output<typeof appComputerPermissionSchema>;
162
+ /** Agent directory and session operations an App may request from its host. */
163
163
  export declare const appAgentPermissionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
164
164
  kind: z.ZodLiteral<"all-team-agents">;
165
165
  directoryOperations: z.ZodArray<z.ZodEnum<{
@@ -184,17 +184,22 @@ export declare const appAgentPermissionSchema: z.ZodDiscriminatedUnion<[z.ZodObj
184
184
  }>>;
185
185
  }, z.core.$strict>>;
186
186
  }, z.core.$strict>], "kind">;
187
+ /** Decoded Agent permission scope attached to an App directory entry. */
187
188
  export type AppAgentPermission = z.output<typeof appAgentPermissionSchema>;
189
+ /** Whether an App may use language-model and media generation services. */
188
190
  export declare const appGenerationPermissionsSchema: z.ZodObject<{
189
191
  llm: z.ZodBoolean;
190
192
  media: z.ZodBoolean;
191
193
  }, z.core.$strict>;
194
+ /** Decoded generation permissions attached to an App directory entry. */
192
195
  export type AppGenerationPermissions = z.output<typeof appGenerationPermissionsSchema>;
196
+ /** Whether an App may browse, buy, or install free marketplace entries. */
193
197
  export declare const appMarketplacePermissionsSchema: z.ZodObject<{
194
198
  browse: z.ZodBoolean;
195
199
  purchase: z.ZodBoolean;
196
200
  installFree: z.ZodBoolean;
197
201
  }, z.core.$strict>;
202
+ /** Decoded marketplace permissions attached to an App directory entry. */
198
203
  export type AppMarketplacePermissions = z.output<typeof appMarketplacePermissionsSchema>;
199
204
  /**
200
205
  * A host's Team App directory with its permission projection, parsed strictly
@@ -357,6 +362,7 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
357
362
  chosen: z.ZodBoolean;
358
363
  }, z.core.$strict>>;
359
364
  }, z.core.$strict>;
365
+ /** The host-resolved Team App directory and its permission projections. */
360
366
  export type AppDirectory = z.output<typeof appDirectoryResponseSchema>;
361
367
  /** Read-only catalog metadata for one App, without host-specific role policy. */
362
368
  export declare const appCatalogEntrySchema: z.ZodObject<{
@@ -534,4 +540,3 @@ export declare const appCatalogBrokerResultSchema: z.ZodUnion<readonly [z.ZodObj
534
540
  }, z.core.$strict>, z.ZodObject<{
535
541
  error: z.ZodString;
536
542
  }, z.core.$strict>]>;
537
- export {};
@@ -80,6 +80,7 @@ const allTeamComputersPermissionSchema = z.strictObject({
80
80
  kind: z.literal("all-team-computers"),
81
81
  operations: z.array(appComputerOperationSchema),
82
82
  });
83
+ /** App Computer permissions limited to selected Computers or the Team's Computers. */
83
84
  export const appComputerPermissionSchema = z.discriminatedUnion("kind", [
84
85
  selectedComputerPermissionSchema,
85
86
  allTeamComputersPermissionSchema,
@@ -90,6 +91,7 @@ const agentSessionOperationSchema = z.enum([
90
91
  "agent.send",
91
92
  "agent.manage",
92
93
  ]);
94
+ /** Agent directory and session operations an App may request from its host. */
93
95
  export const appAgentPermissionSchema = z.discriminatedUnion("kind", [
94
96
  z.strictObject({
95
97
  kind: z.literal("all-team-agents"),
@@ -105,10 +107,12 @@ export const appAgentPermissionSchema = z.discriminatedUnion("kind", [
105
107
  })),
106
108
  }),
107
109
  ]);
110
+ /** Whether an App may use language-model and media generation services. */
108
111
  export const appGenerationPermissionsSchema = z.strictObject({
109
112
  llm: z.boolean(),
110
113
  media: z.boolean(),
111
114
  });
115
+ /** Whether an App may browse, buy, or install free marketplace entries. */
112
116
  export const appMarketplacePermissionsSchema = z.strictObject({
113
117
  browse: z.boolean(),
114
118
  purchase: z.boolean(),
@@ -1,6 +1,7 @@
1
1
  import type { AppStorage } from "@fungi.computer/agar/storage";
2
2
  import type { WhistleJsonValue } from "@fungi.computer/whistle";
3
3
  import type { TeamWorkbenchHostHandle } from "./workbench-contract.js";
4
+ import type { WorkbenchHostControls } from "./workbench-host-types.js";
4
5
  /**
5
6
  * What a host hands the shell a Team picked. The host composes that shell into
6
7
  * its own top-level document, so it runs with the host's escalated
@@ -20,12 +21,35 @@ export type ShellMountInput = Readonly<{
20
21
  * function that removes it again. The shell loads its own code and styles.
21
22
  */
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
+ }>;
23
46
  /** The picked shell's module could not be loaded or does not fit the contract. */
24
47
  export declare class ShellModuleError extends Error {
25
48
  readonly name = "ShellModuleError";
26
49
  }
27
50
  /**
28
51
  * Import the picked shell Release's module from the host's own origin and
29
- * check that it exports `mountShell`. The host never bundles a shell.
52
+ * check that it exports `mountShell`, and `mountPlatformControls` when it
53
+ * offers its own Settings. The host never bundles a shell.
30
54
  */
31
- export declare function importShellModule(moduleUrl: URL, hostOrigin: string): Promise<MountShell>;
55
+ export declare function importShellModule(moduleUrl: URL, hostOrigin: string): Promise<ShellModule>;
@@ -1,4 +1,5 @@
1
1
  import * as z from "zod";
2
+ const unsubscribe = () => z.function({ input: [], output: z.void() });
2
3
  /** The module namespace a shell Release must export; built on first use,
3
4
  * since only a browser has `HTMLElement`. */
4
5
  const shellModuleSchema = () => z.object({
@@ -7,6 +8,50 @@ const shellModuleSchema = () => z.object({
7
8
  input: [z.instanceof(HTMLElement), z.unknown()],
8
9
  output: z.promise(z.function({ input: [], output: z.void() })),
9
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(),
10
55
  });
11
56
  /** The picked shell's module could not be loaded or does not fit the contract. */
12
57
  export class ShellModuleError extends Error {
@@ -14,7 +59,8 @@ export class ShellModuleError extends Error {
14
59
  }
15
60
  /**
16
61
  * Import the picked shell Release's module from the host's own origin and
17
- * check that it exports `mountShell`. The host never bundles a shell.
62
+ * check that it exports `mountShell`, and `mountPlatformControls` when it
63
+ * offers its own Settings. The host never bundles a shell.
18
64
  */
19
65
  export async function importShellModule(moduleUrl, hostOrigin) {
20
66
  if (moduleUrl.origin !== hostOrigin || moduleUrl.hash !== "")
@@ -33,5 +79,8 @@ export async function importShellModule(moduleUrl, hostOrigin) {
33
79
  throw new ShellModuleError("The picked shell does not export mountShell", {
34
80
  cause: decoded.error,
35
81
  });
36
- return decoded.data.mountShell;
82
+ return {
83
+ mountShell: decoded.data.mountShell,
84
+ mountPlatformControls: decoded.data.mountPlatformControls ?? null,
85
+ };
37
86
  }
@@ -0,0 +1,332 @@
1
+ import * as z from "zod";
2
+ /** Desktop metadata shared by hosts; hosted administration stays in Settings. */
3
+ export declare const workbenchDirectorySchema: z.ZodPipe<z.ZodObject<{
4
+ apps: z.ZodArray<z.ZodObject<{
5
+ address: z.ZodUnion<readonly [z.ZodObject<{
6
+ kind: z.ZodLiteral<"default">;
7
+ appId: z.ZodString;
8
+ }, z.core.$strict>, z.ZodObject<{
9
+ kind: z.ZodLiteral<"installation">;
10
+ installationId: z.ZodString;
11
+ }, z.core.$strict>]>;
12
+ installationId: z.ZodNullable<z.ZodString>;
13
+ surfaceId: z.ZodString;
14
+ appId: z.ZodString;
15
+ displayName: z.ZodOptional<z.ZodString>;
16
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
17
+ releaseId: z.ZodNullable<z.ZodString>;
18
+ authorityVersion: z.ZodNumber;
19
+ enforcement: z.ZodNullable<z.ZodObject<{
20
+ requestId: z.ZodString;
21
+ address: z.ZodUnion<readonly [z.ZodObject<{
22
+ kind: z.ZodLiteral<"default">;
23
+ appId: z.ZodString;
24
+ }, z.core.$strict>, z.ZodObject<{
25
+ kind: z.ZodLiteral<"installation">;
26
+ installationId: z.ZodString;
27
+ }, z.core.$strict>]>;
28
+ authorityVersion: z.ZodNumber;
29
+ state: z.ZodEnum<{
30
+ unaffected: "unaffected";
31
+ pending: "pending";
32
+ applied: "applied";
33
+ expired: "expired";
34
+ }>;
35
+ outstanding: z.ZodNumber;
36
+ }, z.core.$strict>>;
37
+ handlers: z.ZodArray<z.ZodLiteral<"file.open">>;
38
+ roles: z.ZodArray<z.ZodString>;
39
+ declaredCapabilities: z.ZodArray<z.ZodString>;
40
+ calls: z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodTransform<readonly {
41
+ readonly appId: string;
42
+ readonly methods: readonly string[];
43
+ }[], unknown>>>;
44
+ commands: z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<Readonly<{
45
+ id: string;
46
+ title: string;
47
+ category: string;
48
+ description?: string | undefined;
49
+ sigil?: string | undefined;
50
+ projections?: Readonly<{
51
+ bindings?: (Readonly<{
52
+ order?: number | undefined;
53
+ }> & Readonly<{
54
+ values: readonly string[];
55
+ }>) | undefined;
56
+ agent?: (Readonly<{
57
+ order?: number | undefined;
58
+ }> & Readonly<{
59
+ keybind?: string | undefined;
60
+ }>) | undefined;
61
+ help?: Readonly<{
62
+ order?: number | undefined;
63
+ }> | undefined;
64
+ menu?: Readonly<{
65
+ order?: number | undefined;
66
+ }> | undefined;
67
+ palette?: Readonly<{
68
+ order?: number | undefined;
69
+ }> | undefined;
70
+ slash?: (Readonly<{
71
+ order?: number | undefined;
72
+ }> & Readonly<{
73
+ aliases: readonly string[];
74
+ }>) | undefined;
75
+ }> | undefined;
76
+ }>[], unknown[]>>;
77
+ gills: z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<import("./app-directory.js").AppDirectoryGill[], unknown[]>>;
78
+ availability: z.ZodEnum<{
79
+ available: "available";
80
+ unavailable: "unavailable";
81
+ }>;
82
+ surface: z.ZodNullable<z.ZodObject<{
83
+ stableRoute: z.ZodString;
84
+ }, z.core.$strict>>;
85
+ surfacePath: z.ZodString;
86
+ computer: z.ZodOptional<z.ZodObject<{
87
+ computerId: z.ZodString;
88
+ name: z.ZodString;
89
+ }, z.core.$strip>>;
90
+ computerPermission: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
91
+ kind: z.ZodLiteral<"selected-computers">;
92
+ computers: z.ZodArray<z.ZodObject<{
93
+ computerId: z.ZodString;
94
+ operations: z.ZodArray<z.ZodEnum<{
95
+ "computer.list": "computer.list";
96
+ "computer.readFile": "computer.readFile";
97
+ "computer.writeFile": "computer.writeFile";
98
+ "computer.execute": "computer.execute";
99
+ }>>;
100
+ }, z.core.$strict>>;
101
+ }, z.core.$strict>, z.ZodObject<{
102
+ kind: z.ZodLiteral<"all-team-computers">;
103
+ operations: z.ZodArray<z.ZodEnum<{
104
+ "computer.list": "computer.list";
105
+ "computer.readFile": "computer.readFile";
106
+ "computer.writeFile": "computer.writeFile";
107
+ "computer.execute": "computer.execute";
108
+ }>>;
109
+ }, z.core.$strict>], "kind">>>;
110
+ }, z.core.$strip>>;
111
+ computer: z.ZodOptional<z.ZodObject<{
112
+ computerId: z.ZodString;
113
+ name: z.ZodString;
114
+ }, z.core.$strip>>;
115
+ roles: z.ZodRecord<z.ZodString, z.ZodObject<{
116
+ surfaceId: z.ZodNullable<z.ZodString>;
117
+ chosen: z.ZodBoolean;
118
+ }, z.core.$strict>>;
119
+ needsUpdate: z.ZodOptional<z.ZodArray<z.ZodObject<{
120
+ installationId: z.ZodNullable<z.ZodString>;
121
+ appId: z.ZodNullable<z.ZodString>;
122
+ displayName: z.ZodString;
123
+ }, z.core.$strict>>>;
124
+ }, z.core.$strip>, z.ZodTransform<{
125
+ apps: {
126
+ address: {
127
+ kind: "default";
128
+ appId: string;
129
+ } | {
130
+ kind: "installation";
131
+ installationId: string;
132
+ };
133
+ installationId: string | null;
134
+ surfaceId: string;
135
+ appId: string;
136
+ releaseId: string | null;
137
+ authorityVersion: number;
138
+ enforcement: {
139
+ requestId: string;
140
+ address: {
141
+ kind: "default";
142
+ appId: string;
143
+ } | {
144
+ kind: "installation";
145
+ installationId: string;
146
+ };
147
+ authorityVersion: number;
148
+ state: "unaffected" | "pending" | "applied" | "expired";
149
+ outstanding: number;
150
+ } | null;
151
+ handlers: "file.open"[];
152
+ roles: string[];
153
+ declaredCapabilities: string[];
154
+ commands: Readonly<{
155
+ id: string;
156
+ title: string;
157
+ category: string;
158
+ description?: string | undefined;
159
+ sigil?: string | undefined;
160
+ projections?: Readonly<{
161
+ bindings?: (Readonly<{
162
+ order?: number | undefined;
163
+ }> & Readonly<{
164
+ values: readonly string[];
165
+ }>) | undefined;
166
+ agent?: (Readonly<{
167
+ order?: number | undefined;
168
+ }> & Readonly<{
169
+ keybind?: string | undefined;
170
+ }>) | undefined;
171
+ help?: Readonly<{
172
+ order?: number | undefined;
173
+ }> | undefined;
174
+ menu?: Readonly<{
175
+ order?: number | undefined;
176
+ }> | undefined;
177
+ palette?: Readonly<{
178
+ order?: number | undefined;
179
+ }> | undefined;
180
+ slash?: (Readonly<{
181
+ order?: number | undefined;
182
+ }> & Readonly<{
183
+ aliases: readonly string[];
184
+ }>) | undefined;
185
+ }> | undefined;
186
+ }>[];
187
+ gills: import("./app-directory.js").AppDirectoryGill[];
188
+ availability: "available" | "unavailable";
189
+ surface: {
190
+ stableRoute: string;
191
+ } | null;
192
+ surfacePath: string;
193
+ displayName?: string | undefined;
194
+ icon?: string | null | undefined;
195
+ calls?: readonly {
196
+ readonly appId: string;
197
+ readonly methods: readonly string[];
198
+ }[] | undefined;
199
+ computer?: {
200
+ computerId: string;
201
+ name: string;
202
+ } | undefined;
203
+ computerPermission?: {
204
+ kind: "selected-computers";
205
+ computers: {
206
+ computerId: string;
207
+ operations: ("computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute")[];
208
+ }[];
209
+ } | {
210
+ kind: "all-team-computers";
211
+ operations: ("computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute")[];
212
+ } | null | undefined;
213
+ }[];
214
+ roles: Record<string, {
215
+ surfaceId: string | null;
216
+ chosen: boolean;
217
+ }>;
218
+ computer?: {
219
+ computerId: string;
220
+ name: string;
221
+ } | undefined;
222
+ needsUpdate?: {
223
+ installationId: string | null;
224
+ appId: string | null;
225
+ displayName: string;
226
+ }[] | undefined;
227
+ }, {
228
+ apps: {
229
+ address: {
230
+ kind: "default";
231
+ appId: string;
232
+ } | {
233
+ kind: "installation";
234
+ installationId: string;
235
+ };
236
+ installationId: string | null;
237
+ surfaceId: string;
238
+ appId: string;
239
+ releaseId: string | null;
240
+ authorityVersion: number;
241
+ enforcement: {
242
+ requestId: string;
243
+ address: {
244
+ kind: "default";
245
+ appId: string;
246
+ } | {
247
+ kind: "installation";
248
+ installationId: string;
249
+ };
250
+ authorityVersion: number;
251
+ state: "unaffected" | "pending" | "applied" | "expired";
252
+ outstanding: number;
253
+ } | null;
254
+ handlers: "file.open"[];
255
+ roles: string[];
256
+ declaredCapabilities: string[];
257
+ commands: Readonly<{
258
+ id: string;
259
+ title: string;
260
+ category: string;
261
+ description?: string | undefined;
262
+ sigil?: string | undefined;
263
+ projections?: Readonly<{
264
+ bindings?: (Readonly<{
265
+ order?: number | undefined;
266
+ }> & Readonly<{
267
+ values: readonly string[];
268
+ }>) | undefined;
269
+ agent?: (Readonly<{
270
+ order?: number | undefined;
271
+ }> & Readonly<{
272
+ keybind?: string | undefined;
273
+ }>) | undefined;
274
+ help?: Readonly<{
275
+ order?: number | undefined;
276
+ }> | undefined;
277
+ menu?: Readonly<{
278
+ order?: number | undefined;
279
+ }> | undefined;
280
+ palette?: Readonly<{
281
+ order?: number | undefined;
282
+ }> | undefined;
283
+ slash?: (Readonly<{
284
+ order?: number | undefined;
285
+ }> & Readonly<{
286
+ aliases: readonly string[];
287
+ }>) | undefined;
288
+ }> | undefined;
289
+ }>[];
290
+ gills: import("./app-directory.js").AppDirectoryGill[];
291
+ availability: "available" | "unavailable";
292
+ surface: {
293
+ stableRoute: string;
294
+ } | null;
295
+ surfacePath: string;
296
+ displayName?: string | undefined;
297
+ icon?: string | null | undefined;
298
+ calls?: readonly {
299
+ readonly appId: string;
300
+ readonly methods: readonly string[];
301
+ }[] | undefined;
302
+ computer?: {
303
+ computerId: string;
304
+ name: string;
305
+ } | undefined;
306
+ computerPermission?: {
307
+ kind: "selected-computers";
308
+ computers: {
309
+ computerId: string;
310
+ operations: ("computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute")[];
311
+ }[];
312
+ } | {
313
+ kind: "all-team-computers";
314
+ operations: ("computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute")[];
315
+ } | null | undefined;
316
+ }[];
317
+ roles: Record<string, {
318
+ surfaceId: string | null;
319
+ chosen: boolean;
320
+ }>;
321
+ computer?: {
322
+ computerId: string;
323
+ name: string;
324
+ } | undefined;
325
+ needsUpdate?: {
326
+ installationId: string | null;
327
+ appId: string | null;
328
+ displayName: string;
329
+ }[] | undefined;
330
+ }>>;
331
+ /** One host's current desktop rows and actual role selections. */
332
+ export type WorkbenchDirectory = z.output<typeof workbenchDirectorySchema>;
@@ -0,0 +1,35 @@
1
+ import * as z from "zod";
2
+ import { appDirectoryEntrySchema, appRoleSelectionSchema, appComputerPermissionSchema, } from "./app-directory.js";
3
+ import { teamComputerSchema } from "./workbench-model.js";
4
+ const computerChoiceSchema = teamComputerSchema
5
+ .pick({ computerId: true, name: true })
6
+ .strip();
7
+ /** Desktop metadata shared by hosts; hosted administration stays in Settings. */
8
+ export const workbenchDirectorySchema = z
9
+ .object({
10
+ apps: z.array(appDirectoryEntrySchema
11
+ .extend({
12
+ computer: computerChoiceSchema.optional(),
13
+ computerPermission: appComputerPermissionSchema.nullable().optional(),
14
+ })
15
+ .strip()),
16
+ /** Fixed standalone context, not a Team Computer permission or capability grant. */
17
+ computer: computerChoiceSchema.optional(),
18
+ roles: z.record(z.string().min(1), appRoleSelectionSchema),
19
+ needsUpdate: z
20
+ .array(z.strictObject({
21
+ installationId: z.string().min(1).nullable(),
22
+ appId: z.string().min(1).nullable(),
23
+ displayName: z.string().min(1),
24
+ }))
25
+ .optional(),
26
+ })
27
+ .transform((directory) => directory.computer === undefined
28
+ ? directory
29
+ : {
30
+ ...directory,
31
+ apps: directory.apps.map((app) => ({
32
+ ...app,
33
+ computer: directory.computer,
34
+ })),
35
+ });
@@ -1,11 +1,10 @@
1
- /** App source seed receipts and the fork algorithm, owned generically here;
2
- * the Publisher supplies D1 adapters and the retained Git admission
3
- * transport. The Node-only template writer (`memfs` + `isomorphic-git`) is
4
- * deliberately not re-exported here: it would drag that dependency into
5
- * every Worker bundle that only needs the fork/provenance reads below (team
6
- * rail's RPC surface has no use for it). Import it from
7
- * `@fungi.computer/oyster/source/template-write` instead. */
1
+ /** App source seed receipts, seed claims and the fork algorithm, owned
2
+ * generically here; the Publisher supplies D1 adapters and the retained Git
3
+ * admission transport. The operator's Node-only template push (it runs the
4
+ * `git` executable) is deliberately not re-exported here, so Worker bundles
5
+ * never import it: use `@fungi.computer/oyster/source/template-push`. */
8
6
  export { templateRepositoryForApp } from "./template-repository.js";
9
7
  export { seedReceiptInputSchema, sameReceipt, type PublisherTemplateSeedReceipt, type PublisherTemplateSeedReceipts, } from "./seed-receipt.js";
10
8
  export { readTeamAppSeedProvenance, privateTeamBuildSource, TeamAppSourceError, } from "./team-source.js";
9
+ export { parseTemplateSeedClaim, recordTemplateSeed, templateSeedClaimSchema, TEMPLATE_SEED_CLAIM_MAX_BYTES, type TemplateSeedClaim, } from "./template-seed.js";
11
10
  export { forkAppSource, type AppSourceForkResult } from "./fork.js";
@@ -1,11 +1,10 @@
1
- /** App source seed receipts and the fork algorithm, owned generically here;
2
- * the Publisher supplies D1 adapters and the retained Git admission
3
- * transport. The Node-only template writer (`memfs` + `isomorphic-git`) is
4
- * deliberately not re-exported here: it would drag that dependency into
5
- * every Worker bundle that only needs the fork/provenance reads below (team
6
- * rail's RPC surface has no use for it). Import it from
7
- * `@fungi.computer/oyster/source/template-write` instead. */
1
+ /** App source seed receipts, seed claims and the fork algorithm, owned
2
+ * generically here; the Publisher supplies D1 adapters and the retained Git
3
+ * admission transport. The operator's Node-only template push (it runs the
4
+ * `git` executable) is deliberately not re-exported here, so Worker bundles
5
+ * never import it: use `@fungi.computer/oyster/source/template-push`. */
8
6
  export { templateRepositoryForApp } from "./template-repository.js";
9
7
  export { seedReceiptInputSchema, sameReceipt, } from "./seed-receipt.js";
10
8
  export { readTeamAppSeedProvenance, privateTeamBuildSource, TeamAppSourceError, } from "./team-source.js";
9
+ export { parseTemplateSeedClaim, recordTemplateSeed, templateSeedClaimSchema, TEMPLATE_SEED_CLAIM_MAX_BYTES, } from "./template-seed.js";
11
10
  export { forkAppSource } from "./fork.js";