@fungi.computer/oyster 0.0.0-stage → 0.0.1

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 (242) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1082 -2
  3. package/dist/agents.d.ts +114 -0
  4. package/dist/agents.js +322 -0
  5. package/dist/app-builds.d.ts +151 -0
  6. package/dist/app-builds.js +355 -0
  7. package/dist/app-sandbox.d.ts +2 -0
  8. package/dist/app-sandbox.js +2 -0
  9. package/dist/app-sources.d.ts +46 -0
  10. package/dist/app-sources.js +335 -0
  11. package/dist/app-storage.d.ts +141 -0
  12. package/dist/app-storage.js +281 -0
  13. package/dist/apps/gate.d.ts +105 -0
  14. package/dist/apps/gate.js +273 -0
  15. package/dist/apps/index.d.ts +5 -0
  16. package/dist/apps/index.js +5 -0
  17. package/dist/apps/installation.d.ts +248 -0
  18. package/dist/apps/installation.js +307 -0
  19. package/dist/apps/operations.d.ts +8 -0
  20. package/dist/apps/operations.js +98 -0
  21. package/dist/apps/tools.d.ts +33 -0
  22. package/dist/apps/tools.js +17 -0
  23. package/dist/auth.d.ts +11 -0
  24. package/dist/auth.js +93 -0
  25. package/dist/backend-request.d.ts +3 -0
  26. package/dist/backend-request.js +53 -0
  27. package/dist/build/build-jobs.d.ts +128 -0
  28. package/dist/build/build-jobs.js +197 -0
  29. package/dist/build/build-step.d.ts +26 -0
  30. package/dist/build/build-step.js +20 -0
  31. package/dist/build/bundled-html.d.ts +7 -0
  32. package/dist/build/bundled-html.js +64 -0
  33. package/dist/build/definition-emission.d.ts +34 -0
  34. package/dist/build/definition-emission.js +201 -0
  35. package/dist/build/effect.d.ts +231 -0
  36. package/dist/build/effect.js +396 -0
  37. package/dist/build/git-environment.d.ts +6 -0
  38. package/dist/build/git-environment.js +48 -0
  39. package/dist/build/html-recipe.d.ts +20 -0
  40. package/dist/build/html-recipe.js +51 -0
  41. package/dist/build/local-build.d.ts +57 -0
  42. package/dist/build/local-build.js +1078 -0
  43. package/dist/build/r2-artifact-writer.d.ts +31 -0
  44. package/dist/build/r2-artifact-writer.js +179 -0
  45. package/dist/build/snapshot-package-store.d.ts +2 -0
  46. package/dist/build/snapshot-package-store.js +21 -0
  47. package/dist/build/snapshot-program-scripts.d.ts +6 -0
  48. package/dist/build/snapshot-program-scripts.js +2 -0
  49. package/dist/build/submission-contract.d.ts +384 -0
  50. package/dist/build/submission-contract.js +70 -0
  51. package/dist/build/workspace-build.d.ts +50 -0
  52. package/dist/build/workspace-build.js +156 -0
  53. package/dist/build-contract.d.ts +4 -0
  54. package/dist/build-contract.js +4 -0
  55. package/dist/build-jobs.d.ts +2 -0
  56. package/dist/build-jobs.js +2 -0
  57. package/dist/build.d.ts +11 -0
  58. package/dist/build.js +13 -0
  59. package/dist/capability-descriptor.d.ts +46 -0
  60. package/dist/capability-descriptor.js +51 -0
  61. package/dist/catalog-frame.d.ts +39 -0
  62. package/dist/catalog-frame.js +72 -0
  63. package/dist/cause-class.d.ts +19 -0
  64. package/dist/cause-class.js +54 -0
  65. package/dist/cloudflare.d.ts +123 -0
  66. package/dist/cloudflare.js +391 -0
  67. package/dist/computer-terminal.d.ts +38 -0
  68. package/dist/computer-terminal.js +410 -0
  69. package/dist/computer.d.ts +60 -0
  70. package/dist/computer.js +33 -0
  71. package/dist/event-recipients.d.ts +57 -0
  72. package/dist/event-recipients.js +144 -0
  73. package/dist/facet-invocation.d.ts +4 -0
  74. package/dist/facet-invocation.js +45 -0
  75. package/dist/files.d.ts +42 -0
  76. package/dist/files.js +123 -0
  77. package/dist/frame-binding-wire-script.d.ts +2 -0
  78. package/dist/frame-binding-wire-script.js +1 -0
  79. package/dist/frame-binding-wire.d.ts +28 -0
  80. package/dist/frame-binding-wire.js +54 -0
  81. package/dist/git-admission.d.ts +52 -0
  82. package/dist/git-admission.js +188 -0
  83. package/dist/git-auth.d.ts +11 -0
  84. package/dist/git-auth.js +27 -0
  85. package/dist/git-door.d.ts +35 -0
  86. package/dist/git-door.js +108 -0
  87. package/dist/git-journal.d.ts +31 -0
  88. package/dist/git-journal.js +188 -0
  89. package/dist/git.d.ts +31 -0
  90. package/dist/git.js +64 -0
  91. package/dist/guest-policy.d.ts +9 -0
  92. package/dist/guest-policy.js +13 -0
  93. package/dist/host.d.ts +244 -0
  94. package/dist/host.js +1043 -0
  95. package/dist/index.d.ts +166 -0
  96. package/dist/index.js +320 -0
  97. package/dist/installation-consent.d.ts +79 -0
  98. package/dist/installation-consent.js +82 -0
  99. package/dist/internal/background-origins.d.ts +3 -0
  100. package/dist/internal/background-origins.js +8 -0
  101. package/dist/internal/delivery.d.ts +12 -0
  102. package/dist/internal/delivery.js +167 -0
  103. package/dist/internal/host-gate.d.ts +14 -0
  104. package/dist/internal/host-gate.js +62 -0
  105. package/dist/internal/registry-installations.d.ts +6 -0
  106. package/dist/internal/registry-installations.js +12 -0
  107. package/dist/invocation.d.ts +251 -0
  108. package/dist/invocation.js +377 -0
  109. package/dist/keys.d.ts +48 -0
  110. package/dist/keys.js +52 -0
  111. package/dist/mcp-owner.d.ts +27 -0
  112. package/dist/mcp-owner.js +143 -0
  113. package/dist/mcp.d.ts +89 -0
  114. package/dist/mcp.js +429 -0
  115. package/dist/media.d.ts +23 -0
  116. package/dist/media.js +12 -0
  117. package/dist/pack.d.ts +76 -0
  118. package/dist/pack.js +134 -0
  119. package/dist/page/capabilities.d.ts +23 -0
  120. package/dist/page/capabilities.js +256 -0
  121. package/dist/page/computer-handles.d.ts +79 -0
  122. package/dist/page/computer-handles.js +44 -0
  123. package/dist/page/lifetime.d.ts +6 -0
  124. package/dist/page/lifetime.js +19 -0
  125. package/dist/page/mount.d.ts +163 -0
  126. package/dist/page/mount.js +390 -0
  127. package/dist/page/storage.d.ts +3 -0
  128. package/dist/page/storage.js +82 -0
  129. package/dist/page/terminal.d.ts +5 -0
  130. package/dist/page/terminal.js +7 -0
  131. package/dist/page-script.d.ts +14 -0
  132. package/dist/page-script.js +5 -0
  133. package/dist/r2-files.d.ts +3 -0
  134. package/dist/r2-files.js +79 -0
  135. package/dist/release.d.ts +72 -0
  136. package/dist/release.js +164 -0
  137. package/dist/root-data.d.ts +86 -0
  138. package/dist/root-data.js +69 -0
  139. package/dist/shell/app-directory.d.ts +537 -0
  140. package/dist/shell/app-directory.js +195 -0
  141. package/dist/shell/browser-actions.d.ts +7 -0
  142. package/dist/shell/browser-actions.js +56 -0
  143. package/dist/shell/command-host.d.ts +112 -0
  144. package/dist/shell/command-host.js +502 -0
  145. package/dist/shell/commands.d.ts +25 -0
  146. package/dist/shell/commands.js +78 -0
  147. package/dist/shell/index.d.ts +8 -0
  148. package/dist/shell/index.js +8 -0
  149. package/dist/shell/keys.d.ts +41 -0
  150. package/dist/shell/keys.js +134 -0
  151. package/dist/shell/shell-module.d.ts +31 -0
  152. package/dist/shell/shell-module.js +37 -0
  153. package/dist/shell/window-manager.d.ts +124 -0
  154. package/dist/shell/window-manager.js +711 -0
  155. package/dist/shell/workbench-contract.d.ts +68 -0
  156. package/dist/shell/workbench-contract.js +1 -0
  157. package/dist/shell/workbench-host-types.d.ts +96 -0
  158. package/dist/shell/workbench-host-types.js +1 -0
  159. package/dist/shell/workbench-host.d.ts +34 -0
  160. package/dist/shell/workbench-host.js +347 -0
  161. package/dist/shell/workbench-model.d.ts +192 -0
  162. package/dist/shell/workbench-model.js +53 -0
  163. package/dist/shell/workbench.d.ts +4 -0
  164. package/dist/shell/workbench.js +2 -0
  165. package/dist/source/fork.d.ts +27 -0
  166. package/dist/source/fork.js +46 -0
  167. package/dist/source/index.d.ts +11 -0
  168. package/dist/source/index.js +11 -0
  169. package/dist/source/seed-receipt.d.ts +53 -0
  170. package/dist/source/seed-receipt.js +18 -0
  171. package/dist/source/team-source.d.ts +32 -0
  172. package/dist/source/team-source.js +42 -0
  173. package/dist/source/template-repository.d.ts +2 -0
  174. package/dist/source/template-repository.js +8 -0
  175. package/dist/source/template-write.d.ts +69 -0
  176. package/dist/source/template-write.js +344 -0
  177. package/dist/storage-frame.d.ts +64 -0
  178. package/dist/storage-frame.js +28 -0
  179. package/dist/tenant.d.ts +81 -0
  180. package/dist/tenant.js +71 -0
  181. package/dist/testing/capabilities.d.ts +29 -0
  182. package/dist/testing/capabilities.js +130 -0
  183. package/dist/testing/catalog.d.ts +3 -0
  184. package/dist/testing/catalog.js +53 -0
  185. package/dist/testing/index.d.ts +10 -0
  186. package/dist/testing/index.js +10 -0
  187. package/dist/testing/installation.d.ts +11 -0
  188. package/dist/testing/installation.js +25 -0
  189. package/dist/testing/native-worker.d.ts +21 -0
  190. package/dist/testing/native-worker.js +106 -0
  191. package/dist/testing/worker.d.ts +18 -0
  192. package/dist/testing/worker.js +67 -0
  193. package/dist/testing/workers-runtime.d.ts +24 -0
  194. package/dist/testing/workers-runtime.js +33 -0
  195. package/dist/webhook-delivery.d.ts +14 -0
  196. package/dist/webhook-delivery.js +17 -0
  197. package/dist/workers-git.d.ts +285 -0
  198. package/dist/workers-git.js +1174 -0
  199. package/dist/workers.d.ts +352 -0
  200. package/dist/workers.js +866 -0
  201. package/docs/api/README.md +82 -0
  202. package/docs/api/agents.md +332 -0
  203. package/docs/api/app-storage.md +209 -0
  204. package/docs/api/apps.md +1375 -0
  205. package/docs/api/auth.md +63 -0
  206. package/docs/api/build-contract.md +507 -0
  207. package/docs/api/build.md +1476 -0
  208. package/docs/api/cloudflare.md +421 -0
  209. package/docs/api/computer.md +203 -0
  210. package/docs/api/files.md +117 -0
  211. package/docs/api/git.md +470 -0
  212. package/docs/api/host.md +1328 -0
  213. package/docs/api/index.md +430 -0
  214. package/docs/api/invocation.md +738 -0
  215. package/docs/api/keys.md +175 -0
  216. package/docs/api/mcp.md +301 -0
  217. package/docs/api/media.md +40 -0
  218. package/docs/api/modules.md +42 -0
  219. package/docs/api/pack.md +138 -0
  220. package/docs/api/page/mount.md +298 -0
  221. package/docs/api/root-data.md +111 -0
  222. package/docs/api/shell/app-directory.md +332 -0
  223. package/docs/api/shell/command-host.md +224 -0
  224. package/docs/api/shell/commands.md +197 -0
  225. package/docs/api/shell/keys.md +183 -0
  226. package/docs/api/shell/shell-module.md +143 -0
  227. package/docs/api/shell/window-manager.md +267 -0
  228. package/docs/api/shell/workbench.md +186 -0
  229. package/docs/api/shell.md +1788 -0
  230. package/docs/api/tenant.md +194 -0
  231. package/docs/api/workers-git.md +1527 -0
  232. package/docs/api/workers.md +1678 -0
  233. package/docs/media/architecture.mmd +32 -0
  234. package/docs/media/architecture.png +0 -0
  235. package/docs/media/bonsai-network.png +0 -0
  236. package/docs/media/bonsai-repository.png +0 -0
  237. package/docs/site/agent-quickstart.mdx +349 -0
  238. package/examples/git/worker.ts +39 -0
  239. package/examples/git/wrangler.jsonc +32 -0
  240. package/examples/standalone/worker.ts +14 -0
  241. package/examples/standalone/wrangler.jsonc +21 -0
  242. package/package.json +249 -3
@@ -0,0 +1,384 @@
1
+ import * as Schema from "effect/Schema";
2
+ /** The largest Team App candidate submission request body, in bytes. */
3
+ export declare const TEAM_APP_SUBMISSION_MAX_REQUEST_BYTES: number;
4
+ /** Exact submitted output and provenance before the Team assigns a stable Release ID. */
5
+ export declare const teamAppCandidateSubmissionSchema: Schema.Struct<{
6
+ appId: Schema.refine<import("@fungi.computer/puffball").AppId, Schema.String>;
7
+ output: Schema.Union<readonly [Schema.Struct<{
8
+ readonly declaration: Schema.optionalKey<Schema.Codec<Readonly<{
9
+ api?: import("@fungi.computer/puffball").AppApi;
10
+ displayName?: string | undefined;
11
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
12
+ calls?: readonly Readonly<{
13
+ appId: string;
14
+ methods: readonly string[];
15
+ }>[] | undefined;
16
+ guidance?: string | undefined;
17
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
18
+ receives?: readonly "git.push"[] | undefined;
19
+ icon?: string;
20
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
21
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
22
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
23
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
24
+ backend?: Readonly<{
25
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
26
+ sync?: Readonly<{
27
+ method: string;
28
+ }>;
29
+ }> | undefined;
30
+ }>, Readonly<{
31
+ api?: import("@fungi.computer/puffball").AppApi;
32
+ displayName?: string | undefined;
33
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
34
+ calls?: readonly Readonly<{
35
+ appId: string;
36
+ methods: readonly string[];
37
+ }>[] | undefined;
38
+ guidance?: string | undefined;
39
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
40
+ receives?: readonly "git.push"[] | undefined;
41
+ icon?: string;
42
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
43
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
44
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
45
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
46
+ backend?: Readonly<{
47
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
48
+ sync?: Readonly<{
49
+ method: string;
50
+ }>;
51
+ }> | undefined;
52
+ }>, never, never>>;
53
+ readonly kind: Schema.Literal<"ui">;
54
+ readonly ui: Schema.Union<readonly [Schema.Struct<{
55
+ readonly mediaType: Schema.Literal<"text/html; charset=utf-8">;
56
+ readonly content: Schema.Struct<{
57
+ readonly kind: Schema.Literal<"html">;
58
+ readonly bytes: Schema.Uint8ArrayFromBase64;
59
+ }>;
60
+ }>, Schema.Struct<{
61
+ readonly mediaType: Schema.Literal<"application/vnd.fungi.app-assets+json">;
62
+ readonly content: Schema.Struct<{
63
+ readonly kind: Schema.Literal<"assets">;
64
+ readonly base: Schema.String;
65
+ readonly assets: Schema.$Array<Schema.Struct<{
66
+ readonly path: Schema.String;
67
+ readonly bytes: Schema.Uint8ArrayFromBase64;
68
+ }>>;
69
+ }>;
70
+ }>]>;
71
+ }>, Schema.Struct<{
72
+ readonly declaration: Schema.optionalKey<Schema.Codec<Readonly<{
73
+ api?: import("@fungi.computer/puffball").AppApi;
74
+ displayName?: string | undefined;
75
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
76
+ calls?: readonly Readonly<{
77
+ appId: string;
78
+ methods: readonly string[];
79
+ }>[] | undefined;
80
+ guidance?: string | undefined;
81
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
82
+ receives?: readonly "git.push"[] | undefined;
83
+ icon?: string;
84
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
85
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
86
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
87
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
88
+ backend?: Readonly<{
89
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
90
+ sync?: Readonly<{
91
+ method: string;
92
+ }>;
93
+ }> | undefined;
94
+ }>, Readonly<{
95
+ api?: import("@fungi.computer/puffball").AppApi;
96
+ displayName?: string | undefined;
97
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
98
+ calls?: readonly Readonly<{
99
+ appId: string;
100
+ methods: readonly string[];
101
+ }>[] | undefined;
102
+ guidance?: string | undefined;
103
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
104
+ receives?: readonly "git.push"[] | undefined;
105
+ icon?: string;
106
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
107
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
108
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
109
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
110
+ backend?: Readonly<{
111
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
112
+ sync?: Readonly<{
113
+ method: string;
114
+ }>;
115
+ }> | undefined;
116
+ }>, never, never>>;
117
+ readonly kind: Schema.Literal<"backend">;
118
+ readonly backend: Schema.Uint8ArrayFromBase64;
119
+ }>, Schema.Struct<{
120
+ readonly declaration: Schema.optionalKey<Schema.Codec<Readonly<{
121
+ api?: import("@fungi.computer/puffball").AppApi;
122
+ displayName?: string | undefined;
123
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
124
+ calls?: readonly Readonly<{
125
+ appId: string;
126
+ methods: readonly string[];
127
+ }>[] | undefined;
128
+ guidance?: string | undefined;
129
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
130
+ receives?: readonly "git.push"[] | undefined;
131
+ icon?: string;
132
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
133
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
134
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
135
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
136
+ backend?: Readonly<{
137
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
138
+ sync?: Readonly<{
139
+ method: string;
140
+ }>;
141
+ }> | undefined;
142
+ }>, Readonly<{
143
+ api?: import("@fungi.computer/puffball").AppApi;
144
+ displayName?: string | undefined;
145
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
146
+ calls?: readonly Readonly<{
147
+ appId: string;
148
+ methods: readonly string[];
149
+ }>[] | undefined;
150
+ guidance?: string | undefined;
151
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
152
+ receives?: readonly "git.push"[] | undefined;
153
+ icon?: string;
154
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
155
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
156
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
157
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
158
+ backend?: Readonly<{
159
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
160
+ sync?: Readonly<{
161
+ method: string;
162
+ }>;
163
+ }> | undefined;
164
+ }>, never, never>>;
165
+ readonly kind: Schema.Literal<"app">;
166
+ readonly ui: Schema.Union<readonly [Schema.Struct<{
167
+ readonly mediaType: Schema.Literal<"text/html; charset=utf-8">;
168
+ readonly content: Schema.Struct<{
169
+ readonly kind: Schema.Literal<"html">;
170
+ readonly bytes: Schema.Uint8ArrayFromBase64;
171
+ }>;
172
+ }>, Schema.Struct<{
173
+ readonly mediaType: Schema.Literal<"application/vnd.fungi.app-assets+json">;
174
+ readonly content: Schema.Struct<{
175
+ readonly kind: Schema.Literal<"assets">;
176
+ readonly base: Schema.String;
177
+ readonly assets: Schema.$Array<Schema.Struct<{
178
+ readonly path: Schema.String;
179
+ readonly bytes: Schema.Uint8ArrayFromBase64;
180
+ }>>;
181
+ }>;
182
+ }>]>;
183
+ readonly backend: Schema.Uint8ArrayFromBase64;
184
+ }>]>;
185
+ provenance: Schema.Struct<{
186
+ readonly sourceRevision: Schema.refine<import("@fungi.computer/puffball").SourceRevision, Schema.String>;
187
+ readonly sourceTreeDigest: Schema.refine<import("@fungi.computer/puffball").Sha256Digest, Schema.String>;
188
+ readonly buildRecipeDigest: Schema.refine<import("@fungi.computer/puffball").Sha256Digest, Schema.String>;
189
+ }>;
190
+ }>;
191
+ /** Publisher persistence input after TeamDO reserves retry-stable identities. */
192
+ export declare const preparedCandidateSchema: Schema.Struct<{
193
+ readonly releaseId: Schema.refine<import("@fungi.computer/puffball").ReleaseId, Schema.String>;
194
+ readonly appId: Schema.refine<import("@fungi.computer/puffball").AppId, Schema.String>;
195
+ readonly output: Schema.Union<readonly [Schema.Struct<{
196
+ readonly declaration: Schema.optionalKey<Schema.Codec<Readonly<{
197
+ api?: import("@fungi.computer/puffball").AppApi;
198
+ displayName?: string | undefined;
199
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
200
+ calls?: readonly Readonly<{
201
+ appId: string;
202
+ methods: readonly string[];
203
+ }>[] | undefined;
204
+ guidance?: string | undefined;
205
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
206
+ receives?: readonly "git.push"[] | undefined;
207
+ icon?: string;
208
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
209
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
210
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
211
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
212
+ backend?: Readonly<{
213
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
214
+ sync?: Readonly<{
215
+ method: string;
216
+ }>;
217
+ }> | undefined;
218
+ }>, Readonly<{
219
+ api?: import("@fungi.computer/puffball").AppApi;
220
+ displayName?: string | undefined;
221
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
222
+ calls?: readonly Readonly<{
223
+ appId: string;
224
+ methods: readonly string[];
225
+ }>[] | undefined;
226
+ guidance?: string | undefined;
227
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
228
+ receives?: readonly "git.push"[] | undefined;
229
+ icon?: string;
230
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
231
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
232
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
233
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
234
+ backend?: Readonly<{
235
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
236
+ sync?: Readonly<{
237
+ method: string;
238
+ }>;
239
+ }> | undefined;
240
+ }>, never, never>>;
241
+ readonly kind: Schema.Literal<"ui">;
242
+ readonly ui: Schema.Union<readonly [Schema.Struct<{
243
+ readonly mediaType: Schema.Literal<"text/html; charset=utf-8">;
244
+ readonly content: Schema.Struct<{
245
+ readonly kind: Schema.Literal<"html">;
246
+ readonly bytes: Schema.Uint8ArrayFromBase64;
247
+ }>;
248
+ }>, Schema.Struct<{
249
+ readonly mediaType: Schema.Literal<"application/vnd.fungi.app-assets+json">;
250
+ readonly content: Schema.Struct<{
251
+ readonly kind: Schema.Literal<"assets">;
252
+ readonly base: Schema.String;
253
+ readonly assets: Schema.$Array<Schema.Struct<{
254
+ readonly path: Schema.String;
255
+ readonly bytes: Schema.Uint8ArrayFromBase64;
256
+ }>>;
257
+ }>;
258
+ }>]>;
259
+ }>, Schema.Struct<{
260
+ readonly declaration: Schema.optionalKey<Schema.Codec<Readonly<{
261
+ api?: import("@fungi.computer/puffball").AppApi;
262
+ displayName?: string | undefined;
263
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
264
+ calls?: readonly Readonly<{
265
+ appId: string;
266
+ methods: readonly string[];
267
+ }>[] | undefined;
268
+ guidance?: string | undefined;
269
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
270
+ receives?: readonly "git.push"[] | undefined;
271
+ icon?: string;
272
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
273
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
274
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
275
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
276
+ backend?: Readonly<{
277
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
278
+ sync?: Readonly<{
279
+ method: string;
280
+ }>;
281
+ }> | undefined;
282
+ }>, Readonly<{
283
+ api?: import("@fungi.computer/puffball").AppApi;
284
+ displayName?: string | undefined;
285
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
286
+ calls?: readonly Readonly<{
287
+ appId: string;
288
+ methods: readonly string[];
289
+ }>[] | undefined;
290
+ guidance?: string | undefined;
291
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
292
+ receives?: readonly "git.push"[] | undefined;
293
+ icon?: string;
294
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
295
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
296
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
297
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
298
+ backend?: Readonly<{
299
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
300
+ sync?: Readonly<{
301
+ method: string;
302
+ }>;
303
+ }> | undefined;
304
+ }>, never, never>>;
305
+ readonly kind: Schema.Literal<"backend">;
306
+ readonly backend: Schema.Uint8ArrayFromBase64;
307
+ }>, Schema.Struct<{
308
+ readonly declaration: Schema.optionalKey<Schema.Codec<Readonly<{
309
+ api?: import("@fungi.computer/puffball").AppApi;
310
+ displayName?: string | undefined;
311
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
312
+ calls?: readonly Readonly<{
313
+ appId: string;
314
+ methods: readonly string[];
315
+ }>[] | undefined;
316
+ guidance?: string | undefined;
317
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
318
+ receives?: readonly "git.push"[] | undefined;
319
+ icon?: string;
320
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
321
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
322
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
323
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
324
+ backend?: Readonly<{
325
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
326
+ sync?: Readonly<{
327
+ method: string;
328
+ }>;
329
+ }> | undefined;
330
+ }>, Readonly<{
331
+ api?: import("@fungi.computer/puffball").AppApi;
332
+ displayName?: string | undefined;
333
+ capabilities: readonly import("@fungi.computer/puffball").AppCapabilityId[];
334
+ calls?: readonly Readonly<{
335
+ appId: string;
336
+ methods: readonly string[];
337
+ }>[] | undefined;
338
+ guidance?: string | undefined;
339
+ handlers: readonly import("@fungi.computer/puffball").AppHandler[];
340
+ receives?: readonly "git.push"[] | undefined;
341
+ icon?: string;
342
+ roles: readonly import("@fungi.computer/puffball").AppRole[];
343
+ storage?: readonly import("@fungi.computer/puffball").AppStorageKey[] | undefined;
344
+ commands?: readonly import("@fungi.computer/puffball").AppDeclaredCommand[] | undefined;
345
+ gills?: readonly import("@fungi.computer/gills").AppDeclaredGill[] | undefined;
346
+ backend?: Readonly<{
347
+ bindings: readonly import("@fungi.computer/puffball").AppBackendBinding[];
348
+ sync?: Readonly<{
349
+ method: string;
350
+ }>;
351
+ }> | undefined;
352
+ }>, never, never>>;
353
+ readonly kind: Schema.Literal<"app">;
354
+ readonly ui: Schema.Union<readonly [Schema.Struct<{
355
+ readonly mediaType: Schema.Literal<"text/html; charset=utf-8">;
356
+ readonly content: Schema.Struct<{
357
+ readonly kind: Schema.Literal<"html">;
358
+ readonly bytes: Schema.Uint8ArrayFromBase64;
359
+ }>;
360
+ }>, Schema.Struct<{
361
+ readonly mediaType: Schema.Literal<"application/vnd.fungi.app-assets+json">;
362
+ readonly content: Schema.Struct<{
363
+ readonly kind: Schema.Literal<"assets">;
364
+ readonly base: Schema.String;
365
+ readonly assets: Schema.$Array<Schema.Struct<{
366
+ readonly path: Schema.String;
367
+ readonly bytes: Schema.Uint8ArrayFromBase64;
368
+ }>>;
369
+ }>;
370
+ }>]>;
371
+ readonly backend: Schema.Uint8ArrayFromBase64;
372
+ }>]>;
373
+ readonly provenance: Schema.Struct<{
374
+ readonly sourceRevision: Schema.refine<import("@fungi.computer/puffball").SourceRevision, Schema.String>;
375
+ readonly sourceTreeDigest: Schema.refine<import("@fungi.computer/puffball").Sha256Digest, Schema.String>;
376
+ readonly buildRecipeDigest: Schema.refine<import("@fungi.computer/puffball").Sha256Digest, Schema.String>;
377
+ }>;
378
+ }>;
379
+ /** One submitted Team App candidate. */
380
+ export type TeamAppCandidateSubmission = Schema.Schema.Type<typeof teamAppCandidateSubmissionSchema>;
381
+ /** One Team App candidate with its reserved Release ID. */
382
+ export type PreparedTeamAppCandidate = Schema.Schema.Type<typeof preparedCandidateSchema>;
383
+ /** Canonical wire bytes make TeamDO's same-request digest independent of JSON spacing. */
384
+ export declare function encodeTeamAppCandidateSubmission(input: TeamAppCandidateSubmission): string;
@@ -0,0 +1,70 @@
1
+ import { assetBaseSchema, assetPathSchema, } from "@fungi.computer/puffball/assets";
2
+ import { appIdSchema, releaseIdSchema, sha256DigestSchema, sourceRevisionSchema, } from "@fungi.computer/puffball/effect";
3
+ import { appDeclarationSchema } from "@fungi.computer/puffball/app";
4
+ import { backendJsonSchema } from "@fungi.computer/puffball/backend";
5
+ import * as Schema from "effect/Schema";
6
+ import { isSigilName } from "@fungi.computer/sigils";
7
+ /** The largest Team App candidate submission request body, in bytes. */
8
+ export const TEAM_APP_SUBMISSION_MAX_REQUEST_BYTES = 24 * 1024 * 1024;
9
+ /** One uploaded byte string; the enclosing HTTP request has a separate total bound. */
10
+ const bytesSchema = Schema.Uint8ArrayFromBase64.pipe(Schema.check(Schema.makeFilter((bytes) => bytes.byteLength <= 16 * 1024 * 1024)));
11
+ const backendBytesSchema = bytesSchema.pipe(Schema.check(Schema.makeFilter((bytes) => Schema.decodeUnknownResult(backendJsonSchema)(new TextDecoder().decode(bytes), { onExcessProperty: "error" })._tag === "Success")));
12
+ const uiOutputSchema = Schema.Union([
13
+ Schema.Struct({
14
+ mediaType: Schema.Literal("text/html; charset=utf-8"),
15
+ content: Schema.Struct({
16
+ kind: Schema.Literal("html"),
17
+ bytes: bytesSchema,
18
+ }),
19
+ }),
20
+ Schema.Struct({
21
+ mediaType: Schema.Literal("application/vnd.fungi.app-assets+json"),
22
+ content: Schema.Struct({
23
+ kind: Schema.Literal("assets"),
24
+ base: assetBaseSchema,
25
+ assets: Schema.Array(Schema.Struct({ path: assetPathSchema, bytes: bytesSchema })),
26
+ }),
27
+ }),
28
+ ]);
29
+ /** A request only; the Team's installation grants remain the authority. */
30
+ const declaration = {
31
+ declaration: Schema.optionalKey(appDeclarationSchema.check(Schema.makeFilter((declaration) => declaration.icon === undefined || isSigilName(declaration.icon), { message: "App icon must name a registered Sigil" }))),
32
+ };
33
+ const outputSchema = Schema.Union([
34
+ Schema.Struct({
35
+ kind: Schema.Literal("ui"),
36
+ ui: uiOutputSchema,
37
+ ...declaration,
38
+ }),
39
+ Schema.Struct({
40
+ kind: Schema.Literal("backend"),
41
+ backend: backendBytesSchema,
42
+ ...declaration,
43
+ }),
44
+ Schema.Struct({
45
+ kind: Schema.Literal("app"),
46
+ ui: uiOutputSchema,
47
+ backend: backendBytesSchema,
48
+ ...declaration,
49
+ }),
50
+ ]);
51
+ const candidateFields = {
52
+ appId: appIdSchema,
53
+ output: outputSchema,
54
+ provenance: Schema.Struct({
55
+ sourceRevision: sourceRevisionSchema,
56
+ sourceTreeDigest: sha256DigestSchema,
57
+ buildRecipeDigest: sha256DigestSchema,
58
+ }),
59
+ };
60
+ /** Exact submitted output and provenance before the Team assigns a stable Release ID. */
61
+ export const teamAppCandidateSubmissionSchema = Schema.Struct(candidateFields);
62
+ /** Publisher persistence input after TeamDO reserves retry-stable identities. */
63
+ export const preparedCandidateSchema = Schema.Struct({
64
+ ...candidateFields,
65
+ releaseId: releaseIdSchema,
66
+ });
67
+ /** Canonical wire bytes make TeamDO's same-request digest independent of JSON spacing. */
68
+ export function encodeTeamAppCandidateSubmission(input) {
69
+ return JSON.stringify(Schema.encodeUnknownSync(teamAppCandidateSubmissionSchema)(input));
70
+ }
@@ -0,0 +1,50 @@
1
+ import * as Schema from "effect/Schema";
2
+ import type { WorkspaceBuildStep } from "./build-step.js";
3
+ /**
4
+ * `package.json#fungi.build`. An App manifest (the manifest nearest the
5
+ * entry) declares how its page builds: `react`, `shellEntry`, the workspace
6
+ * packages whose declared stylesheets compile first (`packageStylesheets`)
7
+ * and its own `stylesheets`, compiled in place, in order. A workspace
8
+ * package declares its build products: extra TypeScript configs compiled
9
+ * after its `tsconfig.build.json`, and its stylesheet input and output.
10
+ * Every path is relative to the manifest that declares it.
11
+ */
12
+ export declare const workspaceBuildPolicySchema: Schema.Struct<{
13
+ readonly react: Schema.optional<Schema.Boolean>;
14
+ readonly shellEntry: Schema.optional<Schema.String>;
15
+ readonly packageStylesheets: Schema.optional<Schema.$Array<Schema.String>>;
16
+ readonly stylesheets: Schema.optional<Schema.$Array<Schema.String>>;
17
+ readonly typescript: Schema.optional<Schema.$Array<Schema.String>>;
18
+ readonly stylesheet: Schema.optional<Schema.Struct<{
19
+ readonly input: Schema.String;
20
+ readonly output: Schema.String;
21
+ }>>;
22
+ }>;
23
+ /** The build policy one manifest declares. */
24
+ export type WorkspaceBuildPolicy = Schema.Schema.Type<typeof workspaceBuildPolicySchema>;
25
+ /** The pnpm arguments that list a source tree's workspace projects. */
26
+ export declare const workspaceProjectsArguments: readonly string[];
27
+ /** One App page build derived from its manifests and package graph. */
28
+ export type WorkspaceBuild = Readonly<{
29
+ /** The pnpm workspace that owns the entry, relative to the source root. */
30
+ directory: string;
31
+ packageName: string;
32
+ react: boolean;
33
+ /** A shell module entry, relative to `directory`. */
34
+ shellEntry?: string;
35
+ /** The workspace's runtime workspace dependencies, dependencies first. */
36
+ dependencies: readonly string[];
37
+ steps: readonly WorkspaceBuildStep[];
38
+ }>;
39
+ /**
40
+ * Derive one App's page build from the captured source alone: the manifest
41
+ * nearest `entry` declares the App policy, the owning pnpm workspace's
42
+ * runtime `workspace:` dependencies give the compile order, and each
43
+ * dependency's manifest declares its own extra build products.
44
+ */
45
+ export declare function resolveWorkspaceBuild(options: {
46
+ readonly root: string;
47
+ readonly entry: string;
48
+ /** `pnpm ls -r --depth -1 --json` output for the same source tree. */
49
+ readonly projects: string;
50
+ }): Promise<WorkspaceBuild>;
@@ -0,0 +1,156 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import * as Schema from "effect/Schema";
4
+ const manifestPathSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((path) => path.length > 0 &&
5
+ !path.startsWith("/") &&
6
+ !path.includes("\\") &&
7
+ path
8
+ .split("/")
9
+ .every((part) => part !== "" && part !== "." && part !== ".."))));
10
+ /**
11
+ * `package.json#fungi.build`. An App manifest (the manifest nearest the
12
+ * entry) declares how its page builds: `react`, `shellEntry`, the workspace
13
+ * packages whose declared stylesheets compile first (`packageStylesheets`)
14
+ * and its own `stylesheets`, compiled in place, in order. A workspace
15
+ * package declares its build products: extra TypeScript configs compiled
16
+ * after its `tsconfig.build.json`, and its stylesheet input and output.
17
+ * Every path is relative to the manifest that declares it.
18
+ */
19
+ export const workspaceBuildPolicySchema = Schema.Struct({
20
+ react: Schema.optional(Schema.Boolean),
21
+ shellEntry: Schema.optional(manifestPathSchema),
22
+ packageStylesheets: Schema.optional(Schema.Array(Schema.String)),
23
+ stylesheets: Schema.optional(Schema.Array(manifestPathSchema)),
24
+ typescript: Schema.optional(Schema.Array(manifestPathSchema)),
25
+ stylesheet: Schema.optional(Schema.Struct({ input: manifestPathSchema, output: manifestPathSchema })),
26
+ });
27
+ const manifestSchema = Schema.fromJsonString(Schema.Struct({
28
+ name: Schema.optional(Schema.String),
29
+ dependencies: Schema.optional(Schema.Record(Schema.String, Schema.String)),
30
+ fungi: Schema.optional(Schema.Struct({ build: Schema.optional(workspaceBuildPolicySchema) })),
31
+ }));
32
+ /** One pnpm workspace project, as `pnpm ls -r --depth -1 --json` lists it. */
33
+ const workspaceProjectsSchema = Schema.fromJsonString(Schema.Array(Schema.Struct({
34
+ name: Schema.String.pipe(Schema.check(Schema.isMinLength(1))),
35
+ path: Schema.String.pipe(Schema.check(Schema.isMinLength(1))),
36
+ })));
37
+ /** The pnpm arguments that list a source tree's workspace projects. */
38
+ export const workspaceProjectsArguments = Object.freeze([
39
+ "ls",
40
+ "--recursive",
41
+ "--depth",
42
+ "-1",
43
+ "--json",
44
+ ]);
45
+ function within(root, path) {
46
+ const relativePath = relative(root, resolve(root, path));
47
+ if (relativePath === ".." ||
48
+ relativePath.startsWith(`..${sep}`) ||
49
+ isAbsolute(relativePath))
50
+ throw new Error(`Build input escapes the captured source: ${path}`);
51
+ return relativePath.split(sep).join("/");
52
+ }
53
+ async function exists(path) {
54
+ return access(path).then(() => true, () => false);
55
+ }
56
+ /**
57
+ * Derive one App's page build from the captured source alone: the manifest
58
+ * nearest `entry` declares the App policy, the owning pnpm workspace's
59
+ * runtime `workspace:` dependencies give the compile order, and each
60
+ * dependency's manifest declares its own extra build products.
61
+ */
62
+ export async function resolveWorkspaceBuild(options) {
63
+ const root = resolve(options.root);
64
+ const entry = within(root, options.entry);
65
+ const manifests = new Map();
66
+ const manifest = async (directory) => {
67
+ const known = manifests.get(directory);
68
+ if (known)
69
+ return known;
70
+ const decoded = Schema.decodeUnknownSync(manifestSchema)(await readFile(join(root, directory, "package.json"), "utf8"));
71
+ manifests.set(directory, decoded);
72
+ return decoded;
73
+ };
74
+ const projects = new Map();
75
+ for (const project of Schema.decodeUnknownSync(workspaceProjectsSchema)(options.projects)) {
76
+ const directory = within(root, project.path);
77
+ if (directory === "")
78
+ continue;
79
+ if (projects.has(project.name))
80
+ throw new Error(`Workspace package name repeats: ${project.name}`);
81
+ projects.set(project.name, directory);
82
+ }
83
+ const owners = [...projects]
84
+ .filter(([, directory]) => entry.startsWith(`${directory}/`))
85
+ .sort(([, left], [, right]) => right.length - left.length);
86
+ const owner = owners[0];
87
+ if (!owner)
88
+ throw new Error(`No workspace package owns ${entry}`);
89
+ const [packageName, directory] = owner;
90
+ let appDirectory = dirname(entry);
91
+ while (appDirectory !== directory &&
92
+ !(await exists(join(root, appDirectory, "package.json"))))
93
+ appDirectory = dirname(appDirectory);
94
+ const policy = (await manifest(appDirectory)).fungi?.build ?? {};
95
+ const dependencies = [];
96
+ const visiting = new Set([directory]);
97
+ const visit = async (from) => {
98
+ for (const [name, range] of Object.entries((await manifest(from)).dependencies ?? {})) {
99
+ if (!range.startsWith("workspace:"))
100
+ continue;
101
+ const dependency = projects.get(name);
102
+ if (dependency === undefined)
103
+ throw new Error(`${from} depends on an unlisted workspace ${name}`);
104
+ if (dependencies.includes(dependency))
105
+ continue;
106
+ if (visiting.has(dependency))
107
+ throw new Error(`Workspace dependency cycle through ${name}`);
108
+ visiting.add(dependency);
109
+ await visit(dependency);
110
+ visiting.delete(dependency);
111
+ dependencies.push(dependency);
112
+ }
113
+ };
114
+ await visit(directory);
115
+ const steps = [];
116
+ for (const dependency of dependencies) {
117
+ if (await exists(join(root, dependency, "tsconfig.build.json")))
118
+ steps.push({
119
+ kind: "typescript",
120
+ config: `${dependency}/tsconfig.build.json`,
121
+ });
122
+ for (const config of (await manifest(dependency)).fungi?.build
123
+ ?.typescript ?? [])
124
+ steps.push({ kind: "typescript", config: `${dependency}/${config}` });
125
+ }
126
+ for (const name of policy.packageStylesheets ?? []) {
127
+ const owner = projects.get(name);
128
+ if (owner === undefined || !dependencies.includes(owner))
129
+ throw new Error(`Stylesheet package ${name} is not a workspace dependency`);
130
+ const declared = (await manifest(owner)).fungi?.build?.stylesheet;
131
+ if (!declared)
132
+ throw new Error(`${name} declares no stylesheet`);
133
+ steps.push({
134
+ kind: "tailwind",
135
+ input: `${owner}/${declared.input}`,
136
+ output: `${owner}/${declared.output}`,
137
+ });
138
+ }
139
+ for (const stylesheet of policy.stylesheets ?? []) {
140
+ const path = within(root, join(appDirectory, stylesheet));
141
+ steps.push({ kind: "tailwind", input: path, output: path });
142
+ }
143
+ const build = {
144
+ directory,
145
+ packageName,
146
+ react: policy.react === true,
147
+ dependencies: Object.freeze(dependencies),
148
+ steps: Object.freeze(steps),
149
+ };
150
+ if (policy.shellEntry === undefined)
151
+ return Object.freeze(build);
152
+ const shellEntry = relative(join(root, directory), join(root, appDirectory, policy.shellEntry))
153
+ .split(sep)
154
+ .join("/");
155
+ return Object.freeze({ ...build, shellEntry });
156
+ }
@@ -0,0 +1,4 @@
1
+ /** Provider-neutral App build recipes and candidate orchestration. */
2
+ export * from "./build/effect.js";
3
+ /** Team App candidate wire contract: submission schema and codec. */
4
+ export * from "./build/submission-contract.js";