@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
package/dist/release.d.ts CHANGED
@@ -20,6 +20,14 @@ export type ArtifactHeads = Readonly<{
20
20
  /** Describe the object at `artifactRef`, or `null` when absent. */
21
21
  head: (artifactRef: ArtifactRef) => Promise<ArtifactHead | null>;
22
22
  }>;
23
+ /** A store that can stream immutable object bytes without materializing them. */
24
+ export type ArtifactStreams = Readonly<{
25
+ /**
26
+ * Open a one-shot byte stream, or return `null` when absent. The signal owns
27
+ * cancellation of both source opening where supported and subsequent reads.
28
+ */
29
+ stream: (artifactRef: ArtifactRef, signal?: AbortSignal) => Promise<ReadableStream<Uint8Array> | null>;
30
+ }>;
23
31
  /** Why a Release could not be read; the host maps it to an HTTP refusal. */
24
32
  export declare class ReleaseError extends Error {
25
33
  readonly code: "artifact_missing" | "digest_mismatch" | "invalid_release" | "asset_missing";
@@ -55,14 +63,13 @@ export declare function readVerified(store: ArtifactStore, artifactRef: Artifact
55
63
  /** Decode an untrusted Release record, as an install request carries it. */
56
64
  export declare function parseRelease(value: unknown): Release;
57
65
  /**
58
- * Read a Release root and verify every artifact it names: the UI document or
59
- * asset build (and each asset object), and the backend descriptor.
66
+ * Read a Release root and verify its UI build and backend descriptor.
67
+ * `readAssets` verifies UI object bodies when true. When false, it reads the
68
+ * asset manifest needed to resolve references but does not read any UI object
69
+ * body, including standalone HTML.
60
70
  */
61
71
  export declare function verifyRelease(store: ArtifactStore, release: Release, policy?: AssetBuildPolicy,
62
- /**
63
- * Read and check every UI asset now. Serving can skip this: each asset is
64
- * verified against its digest when it is read.
65
- */
72
+ /** Read and check every UI object now. Serving verifies each on demand. */
66
73
  readAssets?: boolean): Promise<VerifiedRelease>;
67
74
  /**
68
75
  * Resolve a Release to its verified durable backend without reading its UI:
package/dist/release.js CHANGED
@@ -49,14 +49,13 @@ export function parseRelease(value) {
49
49
  }
50
50
  }
51
51
  /**
52
- * Read a Release root and verify every artifact it names: the UI document or
53
- * asset build (and each asset object), and the backend descriptor.
52
+ * Read a Release root and verify its UI build and backend descriptor.
53
+ * `readAssets` verifies UI object bodies when true. When false, it reads the
54
+ * asset manifest needed to resolve references but does not read any UI object
55
+ * body, including standalone HTML.
54
56
  */
55
57
  export async function verifyRelease(store, release, policy = defaultAssetPolicy,
56
- /**
57
- * Read and check every UI asset now. Serving can skip this: each asset is
58
- * verified against its digest when it is read.
59
- */
58
+ /** Read and check every UI object now. Serving verifies each on demand. */
60
59
  readAssets = true) {
61
60
  const rootBytes = await readVerified(store, release.artifact.artifactRef, release.artifact.artifactDigest);
62
61
  let build;
@@ -70,8 +69,12 @@ readAssets = true) {
70
69
  }
71
70
  let ui = null;
72
71
  if ("ui" in build) {
73
- const bytes = await readVerified(store, build.ui.artifactRef, build.ui.digest);
72
+ const bytes = readAssets || build.ui.mediaType === assetBuildMediaType
73
+ ? await readVerified(store, build.ui.artifactRef, build.ui.digest)
74
+ : null;
74
75
  if (build.ui.mediaType === assetBuildMediaType) {
76
+ if (bytes === null)
77
+ throw new ReleaseError("invalid_release", "Asset manifest is required to verify its object references");
75
78
  let assets;
76
79
  try {
77
80
  assets = decodeAssetBuild(bytes, policy);
@@ -1,8 +1,17 @@
1
1
  import type { Release } from "@fungi.computer/puffball";
2
2
  import { createAppStorage } from "./app-storage.js";
3
3
  import type { InstallationStore, verifyRelease } from "./host.js";
4
- import { type AppDirectoryEntry } from "./shell/app-directory.js";
5
- import type { WorkbenchPlatformDestination } from "./shell/workbench-model.js";
4
+ import { type AppDirectoryEntry } from "@fungi.computer/nacre/app-directory";
5
+ /**
6
+ * A destination the host offers the dashboard. This is a structural twin of
7
+ * Nacre's `WorkbenchPlatformDestination`: importing that type would put
8
+ * Nacre's DOM-typed workbench declarations on every Worker entry that reaches
9
+ * root data.
10
+ */
11
+ type PlatformDestination = Readonly<{
12
+ id: string;
13
+ label: string;
14
+ }>;
6
15
  /** Role choices belong to the root owner, independently of Release declarations. */
7
16
  export type OysterRootRoles = Readonly<Record<string, Readonly<{
8
17
  surfaceId: string | null;
@@ -33,7 +42,7 @@ export declare function createOysterRootData(options: OysterRootDataOptions): {
33
42
  openInstallation(authorize: () => import("effect/Effect").Effect<import("./app-storage.js").AppStorageInstallationAdmission, Error>): {
34
43
  read: (key: string) => import("effect/Effect").Effect<{
35
44
  readonly value: import("effect/Schema").Json;
36
- readonly source: "team" | "member" | "none";
45
+ readonly source: "member" | "team" | "none";
37
46
  readonly team: {
38
47
  readonly value: import("effect/Schema").Json;
39
48
  readonly revision: number;
@@ -54,7 +63,7 @@ export declare function createOysterRootData(options: OysterRootDataOptions): {
54
63
  open(authorize: () => import("effect/Effect").Effect<import("./app-storage.js").AppStorageAdmission, Error>): {
55
64
  read: (key: string) => import("effect/Effect").Effect<{
56
65
  readonly value: import("effect/Schema").Json;
57
- readonly source: "team" | "member" | "none";
66
+ readonly source: "member" | "team" | "none";
58
67
  readonly team: {
59
68
  readonly value: import("effect/Schema").Json;
60
69
  readonly revision: number;
@@ -74,7 +83,7 @@ export declare function createOysterRootData(options: OysterRootDataOptions): {
74
83
  events: (key: string) => import("effect/Stream").Stream<{
75
84
  readonly appId: string;
76
85
  readonly key: string;
77
- readonly scope: "team" | "member";
86
+ readonly scope: "member" | "team";
78
87
  readonly revision: number;
79
88
  } | null, import("@fungi.computer/agar").AppStorageError, never>;
80
89
  };
@@ -82,5 +91,6 @@ export declare function createOysterRootData(options: OysterRootDataOptions): {
82
91
  /** Project the current installations without minting permissions or role choices. */
83
92
  directory(): Promise<OysterRootDirectory>;
84
93
  /** No standalone platform navigation destination is implemented yet. */
85
- platformDestinations(): readonly WorkbenchPlatformDestination[];
94
+ platformDestinations(): readonly PlatformDestination[];
86
95
  };
96
+ export {};
package/dist/root-data.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { resolveAppRoles, } from "@fungi.computer/puffball/app";
2
2
  import { createAppStorage } from "./app-storage.js";
3
- import { addressKey, appDirectoryEntrySchema, } from "./shell/app-directory.js";
3
+ import { addressKey, appDirectoryEntrySchema, } from "@fungi.computer/nacre/app-directory";
4
4
  /** Data adapters for a standalone workbench over the root's existing owners. */
5
5
  export function createOysterRootData(options) {
6
6
  const storage = createAppStorage(options);
@@ -31,7 +31,7 @@ export function createOysterRootData(options) {
31
31
  displayName: declaration?.displayName,
32
32
  icon: declaration?.icon ?? null,
33
33
  releaseId: installation.release.releaseId,
34
- authorityVersion: installation.authorityVersion,
34
+ authorityVersion: installation.authority.authorityVersion,
35
35
  enforcement: null,
36
36
  handlers: [...(declaration?.handlers ?? [])],
37
37
  roles: [...(declaration?.roles ?? [])],
@@ -5,6 +5,6 @@
5
5
  * never import it: use `@fungi.computer/oyster/source/template-push`. */
6
6
  export { templateRepositoryForApp } from "./template-repository.js";
7
7
  export { seedReceiptInputSchema, sameReceipt, type PublisherTemplateSeedReceipt, type PublisherTemplateSeedReceipts, } from "./seed-receipt.js";
8
- export { readTeamAppSeedProvenance, privateTeamBuildSource, TeamAppSourceError, } from "./team-source.js";
8
+ export { readTeamAppSeedProvenance, privateTeamBuildSource, TeamAppSourceError, type TeamAppSeedProvenance, } from "./team-source.js";
9
9
  export { parseTemplateSeedClaim, recordTemplateSeed, templateSeedClaimSchema, TEMPLATE_SEED_CLAIM_MAX_BYTES, type TemplateSeedClaim, } from "./template-seed.js";
10
10
  export { forkAppSource, type AppSourceForkResult } from "./fork.js";
@@ -4,12 +4,9 @@ export declare class TeamAppSourceError extends Error {
4
4
  readonly code: "denied" | "unavailable";
5
5
  constructor(code: "denied" | "unavailable");
6
6
  }
7
- export declare function readTeamAppSeedProvenance(options: {
8
- appId: string;
9
- teamId: string;
10
- registry: TeamAppPublisherRegistry;
11
- readSeedReceipt(appId: PublisherTemplateSeedReceipt["appId"], seedRevision: PublisherTemplateSeedReceipt["seedRevision"]): Promise<PublisherTemplateSeedReceipt | null>;
12
- }): Promise<Readonly<{
7
+ /** What a Team build runs: the App's source repository and the seed receipt
8
+ * whose recipe builds it. */
9
+ export type TeamAppSeedProvenance = Readonly<{
13
10
  appId: string;
14
11
  repository: string;
15
12
  templateSeed: Readonly<{
@@ -18,9 +15,24 @@ export declare function readTeamAppSeedProvenance(options: {
18
15
  }>;
19
16
  recipe: PublisherTemplateSeedReceipt["recipe"];
20
17
  buildRecipeDigest: PublisherTemplateSeedReceipt["buildRecipeDigest"];
18
+ }>;
19
+ /**
20
+ * Read the source revision a Team build runs and the seed receipt that builds
21
+ * it. A template App uses the receipt of the exact commit it builds, failing
22
+ * closed when that commit was never seeded; a fork uses its pinned seed.
23
+ */
24
+ export declare function readTeamAppSeedProvenance(options: {
25
+ appId: string;
26
+ teamId: string;
27
+ registry: TeamAppPublisherRegistry;
28
+ readSeedReceipt(appId: PublisherTemplateSeedReceipt["appId"], seedRevision: PublisherTemplateSeedReceipt["seedRevision"]): Promise<PublisherTemplateSeedReceipt | null>;
29
+ readDefaultBranchHead(repository: string): Promise<string | null>;
30
+ }): Promise<Readonly<{
31
+ source: TeamAppSeedProvenance;
32
+ sourceRevision: PublisherTemplateSeedReceipt["seedRevision"];
21
33
  }>>;
22
- /** A fork keeps the seed's exact builder; private UI assets use Vite's relative base. */
23
- export declare function privateTeamBuildSource(source: Awaited<ReturnType<typeof readTeamAppSeedProvenance>>): Readonly<{
34
+ /** A Team build keeps the seed's exact builder; private UI assets use Vite's relative base. */
35
+ export declare function privateTeamBuildSource(source: TeamAppSeedProvenance): Readonly<{
24
36
  appId: string;
25
37
  repository: string;
26
38
  templateSeed: Readonly<{
@@ -1,4 +1,4 @@
1
- import { parseAppId } from "@fungi.computer/puffball";
1
+ import { parseAppId, parseSourceRevision } from "@fungi.computer/puffball";
2
2
  import { digestPinnedRecipe } from "../build-contract.js";
3
3
  import { templateRepositoryForApp } from "./template-repository.js";
4
4
  export class TeamAppSourceError extends Error {
@@ -9,16 +9,42 @@ export class TeamAppSourceError extends Error {
9
9
  this.name = "TeamAppSourceError";
10
10
  }
11
11
  }
12
+ /**
13
+ * A first-party template App builds its own template, so each seeded commit
14
+ * carries its own recipe. A fork builds its own repository with the recipe of
15
+ * the seed it was forked from.
16
+ */
17
+ function seedKind(registration, templateSeed) {
18
+ return templateSeed.appId === registration.appId &&
19
+ registration.source.repository ===
20
+ templateRepositoryForApp(registration.appId)
21
+ ? "template"
22
+ : "fork";
23
+ }
24
+ /**
25
+ * Read the source revision a Team build runs and the seed receipt that builds
26
+ * it. A template App uses the receipt of the exact commit it builds, failing
27
+ * closed when that commit was never seeded; a fork uses its pinned seed.
28
+ */
12
29
  export async function readTeamAppSeedProvenance(options) {
13
30
  const appId = parseAppId(options.appId);
14
31
  const authorization = await options.registry.authorize(appId, options.teamId);
15
32
  if (authorization.kind !== "authorized")
16
33
  throw new TeamAppSourceError("denied");
17
34
  const registration = authorization.registration;
18
- const templateSeed = registration.templateSeed;
19
- if (registration.source.provider !== "artifacts" ||
20
- templateSeed === undefined)
35
+ const pinned = registration.templateSeed;
36
+ if (registration.source.provider !== "artifacts" || pinned === undefined)
37
+ throw new TeamAppSourceError("unavailable");
38
+ const head = await options.readDefaultBranchHead(registration.source.repository);
39
+ if (head === null)
21
40
  throw new TeamAppSourceError("unavailable");
41
+ const sourceRevision = parseSourceRevision(`git:${head}`);
42
+ const templateSeed = {
43
+ appId: pinned.appId,
44
+ revision: seedKind(registration, pinned) === "template"
45
+ ? sourceRevision
46
+ : pinned.revision,
47
+ };
22
48
  const receipt = await options.readSeedReceipt(parseAppId(templateSeed.appId), templateSeed.revision);
23
49
  if (receipt?.appId !== templateSeed.appId ||
24
50
  receipt.seedRevision !== templateSeed.revision ||
@@ -26,14 +52,17 @@ export async function readTeamAppSeedProvenance(options) {
26
52
  digestPinnedRecipe(receipt.recipe) !== receipt.buildRecipeDigest)
27
53
  throw new TeamAppSourceError("unavailable");
28
54
  return Object.freeze({
29
- appId,
30
- repository: registration.source.repository,
31
- templateSeed,
32
- recipe: receipt.recipe,
33
- buildRecipeDigest: receipt.buildRecipeDigest,
55
+ source: Object.freeze({
56
+ appId,
57
+ repository: registration.source.repository,
58
+ templateSeed: Object.freeze(templateSeed),
59
+ recipe: receipt.recipe,
60
+ buildRecipeDigest: receipt.buildRecipeDigest,
61
+ }),
62
+ sourceRevision,
34
63
  });
35
64
  }
36
- /** A fork keeps the seed's exact builder; private UI assets use Vite's relative base. */
65
+ /** A Team build keeps the seed's exact builder; private UI assets use Vite's relative base. */
37
66
  export function privateTeamBuildSource(source) {
38
67
  if (source.recipe.format !== "assets")
39
68
  return source;
@@ -51,7 +51,7 @@ export declare function parseTemplateSeedClaim(body: string): TemplateSeedClaim
51
51
  */
52
52
  export declare function recordTemplateSeed(receipts: PublisherTemplateSeedReceipts, artifacts: Pick<Artifacts, "readDefaultBranchHead">, rawAppId: string, claim: TemplateSeedClaim): Promise<{
53
53
  readonly kind: "conflict";
54
- readonly receipt?: undefined;
54
+ receipt?: undefined;
55
55
  } | {
56
56
  readonly kind: "recorded" | "existing";
57
57
  readonly receipt: {
@@ -64,5 +64,5 @@ export declare function recordTemplateSeed(receipts: PublisherTemplateSeedReceip
64
64
  };
65
65
  } | {
66
66
  readonly kind: "unavailable";
67
- readonly receipt?: undefined;
67
+ receipt?: undefined;
68
68
  }>;
@@ -0,0 +1,24 @@
1
+ import { AgentMail, agentMailRoute } from "@fungi.computer/shiitake/delegation";
2
+ /** Standalone borrows Shiitake's one Watchdog and Carrier's ordinary durable lane. */
3
+ export declare function agentMail(options: Omit<ConstructorParameters<typeof AgentMail>[0], "post" | "drain"> & {
4
+ namespace: Parameters<typeof agentMailRoute>[0];
5
+ }): {
6
+ host: Required<Pick<Readonly<{
7
+ meta?: import("@fungi.computer/shiitake").HostMetaOptions;
8
+ model: import("@fungi.computer/shiitake").ModelSource;
9
+ instructions: import("@fungi.computer/shiitake").InstructionSource;
10
+ tools?: readonly [] | import("@fungi.computer/shiitake/cloudflare").CloudflareShiitakeTools;
11
+ storagePressure?: import("@fungi.computer/shiitake").StoragePressureCheck;
12
+ compaction?: import("@fungi.computer/shiitake").CompactionOptions;
13
+ extensions: import("@fungi.computer/shiitake").ExtensionRosterV0;
14
+ initialize?: (agent: import("@fungi.computer/shiitake").ShiitakeOwnerAgent) => Promise<void>;
15
+ hostWork?: readonly import("@fungi.computer/shiitake/cloudflare").CloudflareHostWork[];
16
+ hostJobs?: import("@fungi.computer/shiitake/cloudflare").CloudflareHostJobs;
17
+ mailRoom?: import("@fungi.computer/bird-dog/effect").BirdDogEffect;
18
+ acp?: (agent: import("@fungi.computer/shiitake").ShiitakeOwnerAgent) => Promise<import("@fungi.computer/shiitake/cloudflare").CloudflareShiitakeAcpServer>;
19
+ }>, "mailRoom" | "hostJobs" | "hostWork">>;
20
+ deliver: (value: Parameters<AgentMail["send"]>[0]) => Promise<Readonly<{
21
+ status: "accepted";
22
+ commandId: string;
23
+ }>>;
24
+ };
@@ -0,0 +1,62 @@
1
+ import { createPost } from "@fungi.computer/carrier/post";
2
+ import { AgentMail, agentMailRoute } from "@fungi.computer/shiitake/delegation";
3
+ /** Standalone borrows Shiitake's one Watchdog and Carrier's ordinary durable lane. */
4
+ export function agentMail(options) {
5
+ const routes = {
6
+ agentMail: agentMailRoute(options.namespace, options.replySettlement),
7
+ };
8
+ let post;
9
+ let tick;
10
+ const runtime = () => {
11
+ if (post === undefined)
12
+ throw new Error("Agent Post is not open");
13
+ return post;
14
+ };
15
+ const recover = async () => {
16
+ let cursor;
17
+ do {
18
+ cursor = await runtime().enqueueDue(64, cursor);
19
+ } while (cursor !== undefined);
20
+ };
21
+ const drain = async () => {
22
+ await recover();
23
+ if (tick === undefined)
24
+ throw new Error("Agent Post lane is not open");
25
+ await tick();
26
+ };
27
+ const mail = new AgentMail({ ...options, post: runtime, drain });
28
+ const host = {
29
+ mailRoom: mail.mailRoom(),
30
+ hostJobs: {
31
+ lane: "post",
32
+ open: (owner) => {
33
+ post = createPost({
34
+ routes,
35
+ owner: options.storage,
36
+ transactional: owner.transactional,
37
+ readJob: owner.readJob,
38
+ now: Date.now,
39
+ scheduleWake: options.wake,
40
+ });
41
+ tick = owner.tickConcurrent;
42
+ return { execute: (job) => runtime().execute(job) };
43
+ },
44
+ },
45
+ hostWork: [
46
+ {
47
+ pending: () => {
48
+ const nextWakeAt = runtime().nextWake();
49
+ return {
50
+ due: nextWakeAt !== null && nextWakeAt <= Date.now(),
51
+ nextWakeAt,
52
+ };
53
+ },
54
+ run: drain,
55
+ },
56
+ ],
57
+ };
58
+ return {
59
+ host,
60
+ deliver: (value) => mail.send(value),
61
+ };
62
+ }
@@ -0,0 +1,9 @@
1
+ import type { ColdSessionPage, ColdSessionPageRequest } from "@fungi.computer/shiitake";
2
+ import type { CloudflareShiitakeOptions } from "@fungi.computer/shiitake/cloudflare";
3
+ import { type DurableObjectSizedStorage } from "@fungi.computer/zookeeper";
4
+ /**
5
+ * An Oyster Agent's store keeping: Zookeeper's admission check and patrol over
6
+ * the one Durable Object budget. Shiitake's agent pack only; the Pi Durable
7
+ * pack keeps its own store.
8
+ */
9
+ export declare function agentStoreKeeping(storage: DurableObjectSizedStorage, readColdSessions: (request: ColdSessionPageRequest) => Promise<ColdSessionPage>): Required<Pick<CloudflareShiitakeOptions, "hostWork" | "storagePressure">>;
@@ -0,0 +1,30 @@
1
+ import { durableObjectStorageBudget, openPatrol, openStoragePressure, } from "@fungi.computer/zookeeper";
2
+ /** Log what a Zookeeper patrol pass measured; a quiet store logs nothing. */
3
+ function reportPatrol(report) {
4
+ if (report.status === "quiet")
5
+ return;
6
+ if (report.status === "unavailable") {
7
+ console.warn("agent zookeeper patrol unavailable", {
8
+ stage: report.source,
9
+ code: report.failure,
10
+ });
11
+ return;
12
+ }
13
+ console.info("agent zookeeper patrol measured", {
14
+ storeBytes: report.usedBytes,
15
+ sessionBytes: report.sessionBytes,
16
+ sessionCount: report.sessions,
17
+ });
18
+ }
19
+ /**
20
+ * An Oyster Agent's store keeping: Zookeeper's admission check and patrol over
21
+ * the one Durable Object budget. Shiitake's agent pack only; the Pi Durable
22
+ * pack keeps its own store.
23
+ */
24
+ export function agentStoreKeeping(storage, readColdSessions) {
25
+ const budget = durableObjectStorageBudget(storage);
26
+ return {
27
+ hostWork: [openPatrol({ budget, readColdSessions, report: reportPatrol })],
28
+ storagePressure: openStoragePressure(budget),
29
+ };
30
+ }
@@ -1,4 +1,7 @@
1
1
  import { type StandaloneTenancyEnv } from "./tenancy.js";
2
+ import type { PostEnvelope } from "@fungi.computer/carrier/post";
3
+ import { type StandaloneMachineLinkBindings, type StandaloneMachineJoinResult } from "./machine-link.js";
4
+ import { type MachineAgentSettlementPrincipal, type MachineAgentHome, type MachineEnrollment, type MachineLinkCaller, type MachineLinkIdentity } from "../machine-link/index.js";
2
5
  import { DurableObject } from "cloudflare:workers";
3
6
  import type { StandaloneComputerEnv } from "./computer.js";
4
7
  import { ShiitakeDO } from "@fungi.computer/shiitake/cloudflare";
@@ -23,6 +26,7 @@ export type StandaloneModelSource = CloudflareShiitakeOptions["model"];
23
26
  /** One directory entry: an agent's id, display name and own avatar. */
24
27
  export type AgentEntry = Readonly<{
25
28
  agentId: string;
29
+ createdBy: string | null;
26
30
  name: string;
27
31
  avatar: Avatar;
28
32
  }>;
@@ -51,7 +55,7 @@ export type StandaloneAgentsEnv = Readonly<{
51
55
  AGENT_DIRECTORY: DurableObjectNamespace<AgentDirectory>;
52
56
  }>;
53
57
  /** An agent host's whole env: its own bindings and the Oyster's. */
54
- export type StandaloneAgentEnv = StandaloneAgentsEnv & OysterWorkerEnv & StandaloneComputerEnv;
58
+ export type StandaloneAgentEnv = StandaloneAgentsEnv & OysterWorkerEnv & StandaloneComputerEnv & StandaloneMachineLinkBindings;
55
59
  declare const policyDirectorySchema: Schema.Struct<{
56
60
  readonly directoryName: Schema.NonEmptyString;
57
61
  readonly tenantId: Schema.brand<Schema.String, "OysterTenantId">;
@@ -65,7 +69,24 @@ export type AgentInboxRows = Readonly<{
65
69
  export declare abstract class StandaloneAgentBase<Env extends StandaloneAgentEnv = StandaloneAgentEnv> extends ShiitakeDO<Env> {
66
70
  #private;
67
71
  /** The deployable root's host for this Agent's pinned tenant. */
68
- protected abstract hostFor(scope: TenantScope): OysterHost;
72
+ protected abstract hostFor(scope: TenantScope): Promise<OysterHost>;
73
+ private uiOwner;
74
+ private machineClient;
75
+ private ui;
76
+ protected hostFetch(request: Request): Promise<Response> | undefined;
77
+ protected closeShiitake(): Promise<void>;
78
+ private controlDirectory;
79
+ private delegationOwner;
80
+ private delegation;
81
+ /** Host-only mail admission; an HTTP caller never receives this binding. */
82
+ deliver(envelope: PostEnvelope): Promise<import("@fungi.computer/carrier/post").PostDeliveryResult>;
83
+ private mailOwner;
84
+ private conversationAgentsOwner;
85
+ /** The Agents each of this Agent's conversations created or sent work to. */
86
+ private conversationAgents;
87
+ private mail;
88
+ /** Undefined is disclosure refusal; unavailable evidence fails before RPC. */
89
+ settlement(principal: MachineAgentSettlementPrincipal, sessionId: string, commandId: string): Promise<string | undefined>;
69
90
  /** The root host for this Agent's pinned policy directory; unpinned Agents have no App tools. */
70
91
  private appHost;
71
92
  /** Choose this agent's model door; override to plug in another. */
@@ -87,7 +108,7 @@ export declare abstract class StandaloneAgentBase<Env extends StandaloneAgentEnv
87
108
  addMcpServer(input: AgentMcpServerInput): Promise<AgentMcpServer | AgentMcpServerRefusal>;
88
109
  /** Host-only: disconnect one MCP server. */
89
110
  removeMcpServer(serverId: string): Promise<boolean>;
90
- protected shiitakeOptions(): CloudflareShiitakeOptions;
111
+ protected shiitakeOptions(): Promise<CloudflareShiitakeOptions>;
91
112
  /** Send an installation-admitted message through fleet Session operations. */
92
113
  sendFromApp(installationId: string, sessionId: string, message: FleetMessage): Promise<{
93
114
  sessionId: string;
@@ -104,6 +125,43 @@ export declare class AgentDirectory extends DurableObject<StandaloneAgentEnv> {
104
125
  private readonly directory;
105
126
  private readonly avatars;
106
127
  private composedTenancy;
128
+ private machineEnrollmentOwner;
129
+ private machineFencesOwner;
130
+ private machineScope;
131
+ private machineEnrollment;
132
+ /** Host-only join: consumption, enrollment and directory share one commit. */
133
+ enrollMachine(keyId: string, input: MachineEnrollment): Promise<StandaloneMachineJoinResult>;
134
+ machineDevice(id: MachineLinkIdentity): Promise<import("../machine-link/authority.js").MachineLinkDeviceFacts>;
135
+ machineFence(id: MachineLinkIdentity): Promise<Readonly<{
136
+ teamId: string;
137
+ deviceId: string;
138
+ } & {
139
+ live: boolean;
140
+ fenceEpoch: number;
141
+ }> | null>;
142
+ machineDirectory(id: MachineLinkIdentity): Promise<{
143
+ agentId: import("@fungi.computer/shiitake/fleet").AgentId;
144
+ name: string;
145
+ }[]>;
146
+ machineTarget(caller: MachineLinkCaller, agentId: string, requester: string | null): Promise<Readonly<{
147
+ teamId: string;
148
+ callerAgentId: string;
149
+ targetAgentId: string;
150
+ actorAgentId: string;
151
+ callerHome: MachineAgentHome;
152
+ targetHome: MachineAgentHome;
153
+ }>>;
154
+ machineKeyRetired(deviceId: string): boolean;
155
+ /** Catalog home only; no hosted DO is opened to discover a machine home. */
156
+ agentHome(agentId: string): Promise<MachineAgentHome | null>;
157
+ private machineFences;
158
+ private armMachineFenceAlarm;
159
+ /** Only the current canonical owner can retire a device, before fence push. */
160
+ revokeMachineDevice(memberId: string, deviceId: string): Promise<{
161
+ kind: "unconfirmed" | "confirmed";
162
+ fenceEpoch: number;
163
+ } | null>;
164
+ alarm(): Promise<void>;
107
165
  private grant;
108
166
  constructor(ctx: DurableObjectState, env: StandaloneAgentEnv);
109
167
  list(): readonly AgentEntry[];
@@ -118,7 +176,7 @@ export declare class AgentDirectory extends DurableObject<StandaloneAgentEnv> {
118
176
  setAvatar(agentId: string, avatar: Avatar, principal: OysterPrincipal): AgentEntry | Readonly<{
119
177
  error: "not_found" | "not_granted";
120
178
  }>;
121
- create(name: string, requestId: string, principal: OysterPrincipal, actor: AgentPolicyActor, avatar?: Avatar): AgentEntry & {
179
+ create(name: string, requestId: string, principal: OysterPrincipal, actor: AgentPolicyActor, avatar?: Avatar, createdBy?: string | null): AgentEntry & {
122
180
  policyRevision: string | null;
123
181
  };
124
182
  private writePolicy;
@@ -160,10 +218,10 @@ export declare const agentFrameMethods: {
160
218
  decodeResult: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => {
161
219
  readonly items: readonly ({
162
220
  readonly agentId: string;
163
- readonly title: string;
164
- readonly state: "done" | "running" | "needs_you" | "errored";
165
- readonly createdAt: number;
166
221
  readonly sessionId: string;
222
+ readonly createdAt: number;
223
+ readonly title: string;
224
+ readonly state: "done" | "running" | "errored" | "needs_you";
167
225
  readonly lastActivityAt: number;
168
226
  readonly triggerId?: string | undefined;
169
227
  readonly settledAt?: number | undefined;
@@ -180,14 +238,14 @@ export declare const agentFrameMethods: {
180
238
  };
181
239
  readonly kind: "workflow-review";
182
240
  readonly installationId: string;
183
- readonly state: "pending" | "delivered" | "answered" | "timed_out" | "closed";
241
+ readonly expiresAt: number;
184
242
  readonly workflowId: string | null;
243
+ readonly state: "pending" | "delivered" | "answered" | "timed_out" | "closed";
185
244
  readonly workflowTitle: string;
186
245
  readonly reviewTitle: string;
187
246
  readonly reviewers: "runner" | "owners";
188
247
  readonly show: readonly Schema.Json[];
189
248
  readonly openedAt: number;
190
- readonly expiresAt: number;
191
249
  readonly choices?: readonly string[] | undefined;
192
250
  })[];
193
251
  readonly next: null;
@@ -211,6 +269,7 @@ export declare const agentFrameMethods: {
211
269
  decodeArgs: (raw: readonly unknown[]) => [{
212
270
  agentId: string;
213
271
  sessionId: string;
272
+ requestId: string;
214
273
  text: string;
215
274
  delivery: "followUp";
216
275
  }];