@fungi.computer/oyster 0.6.0 → 0.7.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 (163) hide show
  1. package/README.md +132 -78
  2. package/dist/agent-archive-projection.d.ts +8 -0
  3. package/dist/agent-archive-projection.js +49 -0
  4. package/dist/agent-schedules.d.ts +50 -0
  5. package/dist/agent-schedules.js +17 -0
  6. package/dist/agents.d.ts +35 -14
  7. package/dist/agents.js +93 -144
  8. package/dist/app-builds.d.ts +7 -2
  9. package/dist/app-builds.js +19 -2
  10. package/dist/approval-capability.d.ts +1 -1
  11. package/dist/approval-capability.js +11 -16
  12. package/dist/approval-home.d.ts +2 -1
  13. package/dist/approval-home.js +5 -3
  14. package/dist/apps/catalog.js +1 -1
  15. package/dist/apps/gate.d.ts +4 -7
  16. package/dist/apps/gate.js +14 -29
  17. package/dist/apps/index.d.ts +1 -1
  18. package/dist/apps/installation.d.ts +4 -42
  19. package/dist/apps/installation.js +7 -75
  20. package/dist/apps/operations.js +0 -10
  21. package/dist/apps/permissions.d.ts +18 -8
  22. package/dist/apps/permissions.js +7 -1
  23. package/dist/auth.d.ts +1 -24
  24. package/dist/auth.js +9 -39
  25. package/dist/authorization.d.ts +307 -0
  26. package/dist/authorization.js +542 -0
  27. package/dist/boot-host-script.js +1 -1
  28. package/dist/build/build-jobs.d.ts +2 -2
  29. package/dist/build/candidate-builder.d.ts +2 -0
  30. package/dist/build/candidate-builder.js +5 -1
  31. package/dist/build/candidate-cli.js +3 -0
  32. package/dist/build/candidate-cli.mjs +59 -21
  33. package/dist/build/job-log.d.ts +23 -0
  34. package/dist/build/job-log.js +88 -0
  35. package/dist/build/local-build.d.ts +2 -0
  36. package/dist/build/local-build.js +11 -9
  37. package/dist/cloudflare.d.ts +4 -1
  38. package/dist/cloudflare.js +1 -1
  39. package/dist/files.js +9 -8
  40. package/dist/git-admission.d.ts +3 -3
  41. package/dist/git-admission.js +4 -6
  42. package/dist/git-door.d.ts +8 -7
  43. package/dist/git-door.js +18 -17
  44. package/dist/git.d.ts +1 -1
  45. package/dist/host.d.ts +33 -40
  46. package/dist/host.js +153 -272
  47. package/dist/installation-execution.js +10 -5
  48. package/dist/installation-operations.d.ts +4 -180
  49. package/dist/installation-operations.js +1 -5
  50. package/dist/installation-store-generation.d.ts +4 -1
  51. package/dist/installation-store-generation.js +59 -6
  52. package/dist/internal/delivery.js +0 -1
  53. package/dist/internal/host-gate.d.ts +3 -2
  54. package/dist/internal/host-gate.js +5 -18
  55. package/dist/internal/invocation-timing.d.ts +16 -0
  56. package/dist/internal/invocation-timing.js +23 -0
  57. package/dist/internal/registry-installations.js +1 -0
  58. package/dist/invocation.d.ts +15 -14
  59. package/dist/invocation.js +58 -26
  60. package/dist/keys.d.ts +2 -19
  61. package/dist/keys.js +1 -37
  62. package/dist/mcp.d.ts +15 -27
  63. package/dist/mcp.js +105 -155
  64. package/dist/page/agent-browser.d.ts +15 -0
  65. package/dist/page/agent-browser.js +162 -0
  66. package/dist/page/app-permissions-port.d.ts +3 -0
  67. package/dist/page/app-permissions-port.js +43 -0
  68. package/dist/page/app-permissions.d.ts +11 -0
  69. package/dist/page/app-permissions.js +296 -0
  70. package/dist/page/isolated-page-theme.d.ts +2 -0
  71. package/dist/page/isolated-page-theme.js +11 -0
  72. package/dist/page/mount.d.ts +2 -13
  73. package/dist/page/mount.js +7 -93
  74. package/dist/page-script.d.ts +0 -3
  75. package/dist/page-script.js +3 -4
  76. package/dist/standalone/agent-archive-owner.d.ts +42 -0
  77. package/dist/standalone/agent-archive-owner.js +116 -0
  78. package/dist/standalone/agent-archive-schedules.d.ts +6 -0
  79. package/dist/standalone/agent-archive-schedules.js +76 -0
  80. package/dist/standalone/agent-archive.d.ts +31 -0
  81. package/dist/standalone/agent-archive.js +67 -0
  82. package/dist/standalone/agent-computers.d.ts +7 -6
  83. package/dist/standalone/agent-computers.js +4 -7
  84. package/dist/standalone/agent-mail.d.ts +2 -2
  85. package/dist/standalone/agents.d.ts +157 -20
  86. package/dist/standalone/agents.js +234 -30
  87. package/dist/standalone/app-builds-binding.js +1 -1
  88. package/dist/standalone/app-set.js +2 -54
  89. package/dist/standalone/app-source.d.ts +3 -4
  90. package/dist/standalone/app-source.js +12 -9
  91. package/dist/standalone/builds.d.ts +2 -14
  92. package/dist/standalone/builds.js +15 -13
  93. package/dist/standalone/computer-fleet.d.ts +4 -4
  94. package/dist/standalone/computer-fleet.js +13 -42
  95. package/dist/standalone/computer.d.ts +4 -3
  96. package/dist/standalone/computer.js +52 -53
  97. package/dist/standalone/dashboard-approval.d.ts +10 -0
  98. package/dist/standalone/dashboard-approval.js +66 -0
  99. package/dist/standalone/machine-link.d.ts +4 -221
  100. package/dist/standalone/machine-link.js +21 -15
  101. package/dist/standalone/media.d.ts +1 -0
  102. package/dist/standalone/media.js +20 -14
  103. package/dist/standalone/owner-routes.d.ts +16 -0
  104. package/dist/standalone/owner-routes.js +21 -0
  105. package/dist/standalone/permission-resources.d.ts +5 -0
  106. package/dist/standalone/permission-resources.js +31 -0
  107. package/dist/standalone/registry.d.ts +7 -0
  108. package/dist/standalone/registry.js +3 -0
  109. package/dist/standalone/tenancy.d.ts +0 -3
  110. package/dist/standalone/tenancy.js +2 -5
  111. package/dist/standalone/worker-routes.d.ts +19 -0
  112. package/dist/standalone/worker-routes.js +9 -0
  113. package/dist/standalone/worker.d.ts +1 -1
  114. package/dist/standalone/worker.js +27 -35
  115. package/dist/standalone/workflow-binding.d.ts +8 -3
  116. package/dist/standalone/workflow-binding.js +14 -5
  117. package/dist/standalone/workflow-git-capture.js +2 -1
  118. package/dist/standalone/workflow-host.d.ts +8 -103
  119. package/dist/standalone/workflow-host.js +1 -1
  120. package/dist/standalone/workflow-node-capture.js +2 -2
  121. package/dist/standalone/workflow-root-authority.d.ts +1 -1
  122. package/dist/standalone/workflow-root-authority.js +1 -1
  123. package/dist/standalone/workflow-schedules.d.ts +14 -5
  124. package/dist/standalone/workflow-schedules.js +11 -5
  125. package/dist/standalone/workflow-webhooks.d.ts +4 -18
  126. package/dist/standalone/workflow-webhooks.js +5 -5
  127. package/dist/standalone/workflows.d.ts +36 -28
  128. package/dist/standalone/workflows.js +6 -3
  129. package/dist/storage-frame.d.ts +6 -6
  130. package/dist/testing/capabilities.d.ts +7 -6
  131. package/dist/testing/capabilities.js +3 -6
  132. package/dist/testing/installation.d.ts +0 -1
  133. package/dist/testing/installation.js +2 -5
  134. package/dist/workers-git.d.ts +12 -4
  135. package/dist/workers-git.js +38 -35
  136. package/dist/workers.d.ts +9 -1
  137. package/dist/workers.js +44 -8
  138. package/dist/workflows.d.ts +2 -0
  139. package/dist/workflows.js +1 -0
  140. package/docs/api/README.md +7 -0
  141. package/docs/api/agent-schedules.md +175 -0
  142. package/docs/api/agents.md +34 -13
  143. package/docs/api/app-storage.md +1 -1
  144. package/docs/api/apps.md +323 -225
  145. package/docs/api/auth.md +0 -55
  146. package/docs/api/authorization.md +1300 -0
  147. package/docs/api/build.md +40 -37
  148. package/docs/api/cloudflare.md +3 -3
  149. package/docs/api/git.md +20 -11
  150. package/docs/api/host.md +64 -192
  151. package/docs/api/index.md +1 -1
  152. package/docs/api/invocation.md +14 -14
  153. package/docs/api/keys.md +1 -98
  154. package/docs/api/mcp.md +43 -40
  155. package/docs/api/modules.md +2 -0
  156. package/docs/api/page/mount.md +16 -19
  157. package/docs/api/workers-git.md +46 -12
  158. package/docs/api/workers.md +124 -235
  159. package/package.json +39 -20
  160. package/dist/page/computer-target.d.ts +0 -3
  161. package/dist/page/computer-target.js +0 -9
  162. package/dist/standalone/channel-session-door.d.ts +0 -4
  163. package/dist/standalone/channel-session-door.js +0 -72
@@ -0,0 +1,307 @@
1
+ /**
2
+ * Oyster's one authorization owner. Every Oyster HTTP route is registered
3
+ * through {@link routes} with a typed {@link Requirement}; a table's `serve`
4
+ * is the only place those declarations become a Hono router, so an undeclared
5
+ * route cannot be served and a declared one cannot skip its decision.
6
+ *
7
+ * Who may reach what is decided here once, from one {@link Authority}: the
8
+ * owner reaches everything; a named key reaches exactly its Ear Tag grants
9
+ * (Apps, Agents, the Computer); an Agent reaches its App tool policy. An
10
+ * anonymous request reaches only the public routes: sign-in, robots.txt and
11
+ * digest-pinned assets. The App gate
12
+ * (`apps/gate.ts`) still owns App-declaration rules; it asks this module for a
13
+ * principal's App reach.
14
+ */
15
+ import { Hono, type Context, type Env, type ErrorHandler } from "hono";
16
+ import type { MiddlewareHandler } from "hono/types";
17
+ import * as Schema from "effect/Schema";
18
+ import type { HostActor } from "@fungi.computer/puffball/app";
19
+ import type { AppToolPolicy } from "./apps/tools.js";
20
+ import { type LiveOysterKey } from "./keys.js";
21
+ import type { CapabilityEnv, OysterAuthResult, OysterHost } from "./host.js";
22
+ import type { TenantPrincipal } from "./tenant.js";
23
+ /**
24
+ * One live key's access to one installation: `write` when its grants admit
25
+ * `apps.use` there, `read` when they admit `apps.read`, otherwise `null` --
26
+ * including for an installation added after the key was issued, unless the
27
+ * key holds "All Apps" (`targets: {kind: "all"}`). The same shape as an
28
+ * Agent's stored {@link AppToolPolicy}; its caller adds `bindingName` (which
29
+ * varies by caller: the plain installation id for the gate, the uppercased
30
+ * binding name for MCP) to reach the full `AppToolAccess`.
31
+ */
32
+ export declare function keyAppAccess(key: LiveOysterKey, installationId: string): AppToolPolicy | null;
33
+ /** Agent access is scoped to the granted Agent ids, never inferred from App grants. */
34
+ export declare function keyAgentAccess(key: LiveOysterKey, agentId: string): boolean;
35
+ /** Whether a live key's own grants turn its Computer access on. Off by default. */
36
+ export declare function keyAllowsComputerUse(key: LiveOysterKey): boolean;
37
+ /** The owner, as every owner route receives it. */
38
+ export type OwnerPrincipal = Readonly<{
39
+ actor: Extract<HostActor, {
40
+ kind: "member";
41
+ }>;
42
+ role: "owner";
43
+ }>;
44
+ /** True only for a member admitted with the owner role. */
45
+ export declare function oysterPrincipalIsOwner(principal: TenantPrincipal): principal is OwnerPrincipal;
46
+ /** A member, owner or not, as member routes receive it. */
47
+ export type MemberPrincipal = Extract<TenantPrincipal, {
48
+ role: "owner" | "member";
49
+ }>;
50
+ /** The live facts this module reads to decide; every host supplies the same ports. */
51
+ export type AuthorityPorts = Readonly<{
52
+ /** One key's live grants; `null` for an unknown, revoked, expired or suspended key. */
53
+ liveKey: (keyId: string) => Promise<LiveOysterKey | null>;
54
+ /** An Agent's host-attested App tool policy; `null` grants no App reach. */
55
+ appToolPolicy: (actor: Extract<HostActor, {
56
+ kind: "agent";
57
+ }>) => AppToolPolicy | null | Promise<AppToolPolicy | null>;
58
+ }>;
59
+ /** A host's own ports: its key store's liveness and its Agents' tool policy. */
60
+ export declare function hostAuthorityPorts(host: Pick<OysterHost, "keys" | "appToolPolicy">): AuthorityPorts;
61
+ /**
62
+ * One request's authority, resolved once from its principal. A key carries
63
+ * its live grants, or `null` once it is no longer live, which reaches nothing.
64
+ */
65
+ export type Authority = Readonly<{
66
+ kind: "owner";
67
+ principal: OwnerPrincipal;
68
+ }> | Readonly<{
69
+ kind: "member";
70
+ principal: MemberPrincipal;
71
+ }> | Readonly<{
72
+ kind: "key";
73
+ principal: TenantPrincipal;
74
+ key: LiveOysterKey | null;
75
+ }> | Readonly<{
76
+ kind: "agent";
77
+ principal: TenantPrincipal;
78
+ actor: Extract<HostActor, {
79
+ kind: "agent";
80
+ }>;
81
+ }>;
82
+ /** Resolve one principal's authority through the live key port. */
83
+ export declare function authorityOf(principal: TenantPrincipal, ports: AuthorityPorts): Promise<Authority>;
84
+ /** Whether this authority reaches one Agent and its Sessions. Only the owner and granted keys do. */
85
+ export declare function reachesAgent(authority: Authority, agentId: string): boolean;
86
+ /**
87
+ * Whether this authority reaches the host's Computer, its workspace files and
88
+ * the media written there. Members do; a key only with `computer.use`;
89
+ * Agents reach a Computer only through their own attachment owner.
90
+ */
91
+ export declare function reachesComputer(authority: Authority): boolean;
92
+ /**
93
+ * A key's or Agent's tool access to one installation, in the App gate's
94
+ * policy shape; `null` when it reaches none. Members and the owner hold
95
+ * no tool policy: the App gate decides them by role.
96
+ */
97
+ export declare function appToolAccess(authority: Authority, installationId: string, ports: AuthorityPorts): Promise<AppToolPolicy | null>;
98
+ /** One installation as reach decisions see it. */
99
+ export type ReachableInstallation = Readonly<{
100
+ installationId: string;
101
+ }>;
102
+ /**
103
+ * Whether this authority may see or open one installation at all (the home
104
+ * list, Git). A key needs `apps.read` there; `use` needs `apps.use`.
105
+ * Nothing anonymous reaches one.
106
+ */
107
+ export declare function reachesInstallation(authority: Authority, installation: ReachableInstallation, access: "read" | "use", ports: AuthorityPorts): Promise<boolean>;
108
+ /** Whether a live key's grants permit a one-use device enrollment. */
109
+ export declare function allowsMachineEnrollment(key: LiveOysterKey): boolean;
110
+ /** The request facts a requirement reads. */
111
+ export type RequestFacts = Readonly<{
112
+ /** The incoming request. */
113
+ request: Request;
114
+ /** One path parameter of the matched route. */
115
+ param: (name: string) => string | undefined;
116
+ /** Decode the JSON body (shared with the handler's own read); `null` when it does not match. */
117
+ body: <T>(schema: Schema.Decoder<T>) => Promise<T | null>;
118
+ /** The request's principal, authenticated once by the serving table. */
119
+ principal: () => Promise<OysterAuthResult>;
120
+ /** Whether an App sent this request (the page bridge, or any capability call). */
121
+ mediated: boolean;
122
+ ports: AuthorityPorts;
123
+ }>;
124
+ /** Every requirement kind; the law test proves each has both outcomes. */
125
+ export type RequirementKind = "public" | "door" | "owner" | "member" | "app" | "apps" | "agent" | "agents" | "computer";
126
+ /** How the law and the host table read one route's requirement. */
127
+ export type DeclaredRequirement = Readonly<{
128
+ kind: RequirementKind;
129
+ /** An owner route's reach: `direct` refuses App-mediated requests. */
130
+ via?: "direct" | "direct-or-app";
131
+ /** Why a route needs no Oyster principal (`public`, `door`). */
132
+ reason?: string;
133
+ }>;
134
+ /**
135
+ * One route's declared requirement: an opaque, frozen value only this module
136
+ * mints. Its label and decision live in private fields that only this module
137
+ * reads, so a copy, a look-alike, an overridden method or a relabelled field
138
+ * changes nothing a route serves, and registering a non-minted value throws.
139
+ */
140
+ export declare class Requirement<Admitted> {
141
+ #private;
142
+ /** Type-only: what the requirement admits. Never present at run time. */
143
+ readonly admitted?: Admitted;
144
+ /** Module-private: use the requirement constructors below. */
145
+ constructor(token: symbol, declared: DeclaredRequirement, admit: (facts: RequestFacts) => Promise<Admitted | Response>);
146
+ }
147
+ /** A browser page asks to sign in; every other refused request gets its status. */
148
+ export declare function unauthenticated(request: Request, result: Extract<OysterAuthResult, {
149
+ kind: "refused";
150
+ }>): Response;
151
+ /** Served without any principal: sandboxed App bytes, page assets, sign-in. */
152
+ export declare function publicRoute(reason: string): Requirement<null>;
153
+ /**
154
+ * The route verifies its own credential (MCP, Git, signed webhook delivery,
155
+ * device enrollment); `reason` names that credential. A door that reads an
156
+ * Oyster principal decides its reach through this module's functions.
157
+ */
158
+ export declare function door(reason: string): Requirement<null>;
159
+ /** Where an owner request came from: the owner directly, or an App acting through the shell. */
160
+ export type OwnerOrigin = "owner-direct" | "app";
161
+ /** What an owner route receives. */
162
+ export type OwnerAdmission = Readonly<{
163
+ principal: OwnerPrincipal;
164
+ origin: OwnerOrigin;
165
+ }>;
166
+ /**
167
+ * The owner only. `direct` also refuses an App-mediated request (one the
168
+ * page bridge sends with `X-Oyster-Installation`, and every request a
169
+ * capability table serves): consent and secrets never ride an App.
170
+ */
171
+ export declare function owner(via: "direct" | "direct-or-app"): Requirement<OwnerAdmission>;
172
+ /**
173
+ * Any member, owner or not; never a key or Agent. `deny` shapes the
174
+ * refusal for a contract whose wire already names one.
175
+ */
176
+ export declare function member(deny?: () => Response): Requirement<Readonly<{
177
+ principal: MemberPrincipal;
178
+ }>>;
179
+ /**
180
+ * An App route: any signed-in principal, decided per call by the App gate,
181
+ * which reads this module's {@link appToolAccess}.
182
+ */
183
+ export declare function app(): Requirement<Readonly<{
184
+ principal: TenantPrincipal;
185
+ }>>;
186
+ /** What a collection route receives: the authority and its reach over each item. */
187
+ export type CollectionAdmission<Item> = Readonly<{
188
+ authority: Authority;
189
+ /** Whether this authority may see one item of the collection. */
190
+ reaches: (item: Item) => Promise<boolean>;
191
+ }>;
192
+ /** The installation list (the home page): the owner sees all, keys their granted ones. */
193
+ export declare function apps(): Requirement<CollectionAdmission<ReachableInstallation>>;
194
+ /** What an Agent route receives. */
195
+ export type AgentAdmission = Readonly<{
196
+ authority: Authority;
197
+ principal: TenantPrincipal;
198
+ agentId: string;
199
+ }>;
200
+ /**
201
+ * One Agent, named by the route's `:agentId` (or by `id` from the request):
202
+ * the owner, or a key granted `agents.use` for that Agent id.
203
+ */
204
+ export declare function agent(id?: (facts: RequestFacts) => Promise<string | null>): Requirement<AgentAdmission>;
205
+ /** Agents (and their inbox rows): the owner sees all, a key its granted Agents. */
206
+ export declare function agents(): Requirement<CollectionAdmission<string>>;
207
+ /** The host's Computer, its workspace files and media: see {@link reachesComputer}. */
208
+ export declare function computer(): Requirement<Readonly<{
209
+ principal: TenantPrincipal;
210
+ }>>;
211
+ /** An HTTP method a route may declare. */
212
+ export type Method = "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE";
213
+ /** One declared route, as the law test and the host's table read it. */
214
+ export type RouteDeclaration = Readonly<{
215
+ methods: readonly Method[] | "ALL";
216
+ path: string;
217
+ requirement: DeclaredRequirement;
218
+ }>;
219
+ /** A handler receives the request and exactly what its requirement admitted. */
220
+ export type Handler<E extends Env, P extends string, Admitted> = (context: Context<E, P>, admitted: Admitted) => Response | Promise<Response>;
221
+ /** Per-route options; middleware runs after the requirement admits. */
222
+ export type RouteOptions<E extends Env, P extends string> = Readonly<{
223
+ middleware?: readonly MiddlewareHandler<E, P>[];
224
+ }>;
225
+ /**
226
+ * A declared route table: a frozen, opaque value only {@link routes} builds.
227
+ * Its routes live in a private record; including or serving reads only that
228
+ * record, never a method a copy could override. A table cannot serve itself:
229
+ * only {@link serveHost}, {@link serveDoors} and {@link serveCapability} do,
230
+ * each with the principal its composition root admits. There is no `use`: a
231
+ * path-wide middleware could serve a path no route declares.
232
+ */
233
+ export declare class Routes<E extends Env> {
234
+ #private;
235
+ /** Module-private: use {@link routes}. */
236
+ constructor(token: symbol);
237
+ /** Register one GET route. */
238
+ get<P extends string, A>(path: P, requirement: Requirement<A>, handler: Handler<E, P, A>, options?: RouteOptions<E, NoInfer<P>>): this;
239
+ /** Register one POST route. */
240
+ post<P extends string, A>(path: P, requirement: Requirement<A>, handler: Handler<E, P, A>, options?: RouteOptions<E, NoInfer<P>>): this;
241
+ /** Register one PUT route. */
242
+ put<P extends string, A>(path: P, requirement: Requirement<A>, handler: Handler<E, P, A>, options?: RouteOptions<E, NoInfer<P>>): this;
243
+ /** Register one DELETE route. */
244
+ delete<P extends string, A>(path: P, requirement: Requirement<A>, handler: Handler<E, P, A>, options?: RouteOptions<E, NoInfer<P>>): this;
245
+ /** Register one route for every method. */
246
+ all<P extends string, A>(path: P, requirement: Requirement<A>, handler: Handler<E, P, A>, options?: RouteOptions<E, NoInfer<P>>): this;
247
+ /** Register one route for several methods. */
248
+ on<P extends string, A>(methods: readonly Method[], path: P, requirement: Requirement<A>, handler: Handler<E, P, A>, options?: RouteOptions<E, NoInfer<P>>): this;
249
+ /** Serve another table's routes at this position, keeping its own error handler. */
250
+ include(other: Routes<E>): this;
251
+ /** Answer an error thrown by this table's own handlers. */
252
+ onError(handler: ErrorHandler<E>): this;
253
+ /** Every route this table and its included tables declare, in serving order. */
254
+ declarations(): readonly RouteDeclaration[];
255
+ }
256
+ /** Start a declared route table. */
257
+ export declare function routes<E extends Env>(): Routes<E>;
258
+ /** What a header hook may read of a finished response: never its body or request. */
259
+ export type ResponseView = Readonly<{
260
+ status: number;
261
+ /** A copy: changing it changes nothing served. */
262
+ headers: Headers;
263
+ }>;
264
+ /** One header hook: the headers to add to a finished response, if any. */
265
+ export type ResponseHeaders = (response: ResponseView) => Readonly<Record<string, string>> | null;
266
+ /** How the host table is served beyond its principal and ports. */
267
+ export type HostServeOptions = Readonly<{
268
+ /**
269
+ * Headers to add to every finished response (never an upgraded socket).
270
+ * Each hook sees only a read-only view of the response the route answered
271
+ * with, after its requirement decided, and can only add headers.
272
+ */
273
+ headers?: readonly ResponseHeaders[];
274
+ /** Record Server-Timing through Hono's own `timing` middleware. */
275
+ serverTiming?: Readonly<{
276
+ totalDescription: string;
277
+ }>;
278
+ }>;
279
+ /** A served table: it answers requests and names what it serves, and is never a router. */
280
+ export type ServedTable<E extends Env> = Readonly<{
281
+ /** Answer one request. */
282
+ fetch: (...request: Parameters<Hono<E>["fetch"]>) => Promise<Response>;
283
+ /** Answer one request built from a path or URL (tests and composition). */
284
+ request: (...request: Parameters<Hono<E>["request"]>) => Promise<Response>;
285
+ /** Every path the router answers, for the law test. */
286
+ servedPaths: () => readonly string[];
287
+ }>;
288
+ /**
289
+ * Serve a tenant host's table: the composition root (`oysterRouteTable`)
290
+ * supplies how a request authenticates. An option this function does not
291
+ * know is refused rather than ignored.
292
+ */
293
+ export declare function serveHost<E extends Env>(table: Routes<E>, authenticate: (request: Request) => Promise<OysterAuthResult>, ports: AuthorityPorts, options?: HostServeOptions): ServedTable<E>;
294
+ /**
295
+ * Serve a table of doors and public routes only (a Worker's top-level
296
+ * dispatch, before any tenant is selected): a route that needs an Oyster
297
+ * principal is refused, never admitted.
298
+ */
299
+ export declare function serveDoors<E extends Env>(table: Routes<E>): ServedTable<E>;
300
+ /**
301
+ * Serve one capability's declared table under the host dispatcher's
302
+ * admission, read from `c.env`: the App already holds the capability, and
303
+ * each route still decides its own resource. Every request here is
304
+ * App-mediated, however it was admitted (a header or a browser socket's
305
+ * query), so `owner("direct")` always refuses inside a capability.
306
+ */
307
+ export declare function serveCapability(table: Routes<CapabilityEnv>, ports: AuthorityPorts): ServedTable<CapabilityEnv>;