@fungi.computer/oyster 0.6.0 → 0.8.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 +133 -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 +61 -0
  5. package/dist/agent-schedules.js +19 -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 +70 -22
  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 +9 -1
  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 +156 -275
  47. package/dist/installation-execution.js +14 -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 +186 -20
  86. package/dist/standalone/agents.js +251 -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 +10 -3
  116. package/dist/standalone/workflow-binding.js +22 -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 +31 -4
  124. package/dist/standalone/workflow-schedules.js +18 -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 +53 -27
  128. package/dist/standalone/workflows.js +9 -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 +4 -0
  139. package/dist/workflows.js +2 -0
  140. package/docs/api/README.md +7 -0
  141. package/docs/api/agent-schedules.md +176 -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 +42 -38
  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 +111 -222
  159. package/package.json +41 -22
  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
@@ -5,10 +5,10 @@ import { GraphWorkflow, type GraphRunEnding, type GraphWorkflowBindings } from "
5
5
  import { type GraphReview, type GraphParams, type NodeCall, type NodeEvent, type NodeDispatcher } from "@fungi.computer/braid";
6
6
  import { type StandaloneTenancyEnv } from "./tenancy.js";
7
7
  import type { AppEventFact } from "@fungi.computer/puffball/app-event-facts";
8
+ import { type ScheduleListInput } from "@fungi.computer/workflows-wire";
8
9
  import type { InvocationFacts } from "../invocation.js";
9
- import type { OysterPrincipal } from "../host.js";
10
10
  import type { OysterGitWorkerEnv, OysterGitWorkerHost } from "../workers-git.js";
11
- import { type TenantScope } from "../tenant.js";
11
+ import { type TenantPrincipal, type TenantScope } from "../tenant.js";
12
12
  import type { GitWriter, RepositoryRef } from "@fungi.computer/agar/git";
13
13
  import { type WorkflowGitCredential, type WorkflowGitPassGrant } from "@fungi.computer/braid/runtime";
14
14
  import { reviewKey, type EventDisarmInput, type WorkflowGitPassRequest, type TriggerArmTarget, type ScheduleDisarmInput } from "./workflow-binding.js";
@@ -86,20 +86,46 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
86
86
  } | {
87
87
  error: string;
88
88
  }>;
89
- schedules(facts: InvocationFacts): Promise<{
89
+ pauseSchedule(facts: InvocationFacts, input: {
90
+ scheduleId: string;
91
+ }): Promise<{
92
+ kind: "not_found";
93
+ } | {
94
+ kind: "paused";
95
+ } | {
90
96
  error: string;
91
- schedules?: undefined;
97
+ }>;
98
+ resumeSchedule(facts: InvocationFacts, input: {
99
+ scheduleId: string;
100
+ }): Promise<{
101
+ kind: "not_found";
102
+ reason?: never;
92
103
  } | {
104
+ kind: "refused";
105
+ reason: string;
106
+ } | {
107
+ kind: "resumed";
108
+ reason?: never;
109
+ } | {
110
+ error: string;
111
+ }>;
112
+ schedules(facts: InvocationFacts, input: ScheduleListInput): Promise<{
93
113
  schedules: {
94
114
  scheduleId: string;
95
115
  installationId: string;
96
116
  workflowId: string;
97
117
  triggerId: string;
118
+ cron: {
119
+ expression: string;
120
+ timeZone: string;
121
+ };
98
122
  nextDueAt: number;
99
123
  state: "active" | "finished" | "paused" | "cancelled";
100
124
  lastError: string | null;
101
125
  }[];
102
- error?: undefined;
126
+ nextCursor: string | null;
127
+ } | {
128
+ error: string;
103
129
  }>;
104
130
  armEventTrigger(facts: InvocationFacts, input: TriggerArmTarget): Promise<{
105
131
  kind: "armed";
@@ -143,7 +169,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
143
169
  runId: string;
144
170
  workflowId: string | undefined;
145
171
  commit: string | undefined;
146
- source: "key" | "manual" | "agent" | "event" | "schedule";
172
+ source: "key" | "manual" | "agent" | "schedule" | "event";
147
173
  initiatedBy: Readonly<{
148
174
  kind: "member";
149
175
  memberId: string;
@@ -162,7 +188,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
162
188
  runId: string;
163
189
  workflowId: string | undefined;
164
190
  commit: string | undefined;
165
- source: "key" | "manual" | "agent" | "event" | "schedule";
191
+ source: "key" | "manual" | "agent" | "schedule" | "event";
166
192
  initiatedBy: Readonly<{
167
193
  kind: "member";
168
194
  memberId: string;
@@ -183,7 +209,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
183
209
  /** Signed traffic uses the native fetch interface; no sender principal is accepted. */
184
210
  fetch(request: Request): Promise<Response>;
185
211
  /** Root-authenticated owner RPC; command data cannot nominate an actor or pin. */
186
- webhookControl(principal: OysterPrincipal, installationId: string, raw: unknown): Promise<Response>;
212
+ webhookControl(principal: TenantPrincipal, installationId: string, raw: unknown): Promise<Response>;
187
213
  /**
188
214
  * The emitting App's Instance delivers each accepted event here. The
189
215
  * emitter's live Release must declare the event and its payload schema
@@ -271,13 +297,13 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
271
297
  readonly input: {
272
298
  readonly [x: string]: S.Json;
273
299
  };
300
+ readonly title: string;
274
301
  readonly apps: {
275
302
  readonly [x: string]: {
276
303
  readonly appId: string;
277
304
  readonly role?: string | undefined;
278
305
  };
279
306
  };
280
- readonly title: string;
281
307
  readonly nodes: readonly ({
282
308
  readonly id: string;
283
309
  readonly kind: "code";
@@ -315,19 +341,19 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
315
341
  } | {
316
342
  readonly id: string;
317
343
  readonly kind: "review";
318
- readonly timeout: number;
319
344
  readonly title: string;
345
+ readonly timeout: number;
320
346
  readonly reviewers: "runner" | "owners";
321
347
  readonly show: readonly {
322
348
  readonly node: string;
323
349
  readonly port: string;
324
350
  }[];
351
+ readonly detail?: string | undefined;
325
352
  readonly choices?: readonly {
326
353
  readonly label: string;
327
354
  readonly id: string;
328
355
  readonly description?: string | undefined;
329
356
  }[] | undefined;
330
- readonly detail?: string | undefined;
331
357
  } | {
332
358
  readonly id: string;
333
359
  readonly kind: "condition";
@@ -412,19 +438,19 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
412
438
  } | {
413
439
  readonly id: string;
414
440
  readonly kind: "review";
415
- readonly timeout: number;
416
441
  readonly title: string;
442
+ readonly timeout: number;
417
443
  readonly reviewers: "runner" | "owners";
418
444
  readonly show: readonly {
419
445
  readonly node: string;
420
446
  readonly port: string;
421
447
  }[];
448
+ readonly detail?: string | undefined;
422
449
  readonly choices?: readonly {
423
450
  readonly label: string;
424
451
  readonly id: string;
425
452
  readonly description?: string | undefined;
426
453
  }[] | undefined;
427
- readonly detail?: string | undefined;
428
454
  } | {
429
455
  readonly id: string;
430
456
  readonly kind: "condition";
@@ -477,10 +503,10 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
477
503
  readonly triggers?: readonly ({
478
504
  readonly id: string;
479
505
  readonly on: "webhook";
506
+ readonly when?: import("@fungi.computer/braid").Predicate | undefined;
480
507
  readonly input?: {
481
508
  readonly [x: string]: import("@fungi.computer/braid").Mapping;
482
509
  } | undefined;
483
- readonly when?: import("@fungi.computer/braid").Predicate | undefined;
484
510
  readonly title?: string | undefined;
485
511
  } | {
486
512
  readonly id: string;
@@ -495,14 +521,14 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
495
521
  readonly title?: string | undefined;
496
522
  } | {
497
523
  readonly id: string;
524
+ readonly app: string;
498
525
  readonly on: "event";
499
526
  readonly event: string;
500
- readonly app: string;
501
527
  readonly eventDigest: string;
528
+ readonly when?: import("@fungi.computer/braid").Predicate | undefined;
502
529
  readonly input?: {
503
530
  readonly [x: string]: import("@fungi.computer/braid").Mapping;
504
531
  } | undefined;
505
- readonly when?: import("@fungi.computer/braid").Predicate | undefined;
506
532
  readonly repository?: import("@fungi.computer/braid").Mapping | undefined;
507
533
  readonly title?: string | undefined;
508
534
  })[] | undefined;
@@ -581,7 +607,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
581
607
  readonly title: string;
582
608
  readonly status?: {
583
609
  readonly label: string;
584
- readonly tone: "success" | "error" | "info" | "warning" | "neutral" | "primary" | "secondary" | "accent";
610
+ readonly tone: "success" | "error" | "neutral" | "primary" | "secondary" | "accent" | "info" | "warning";
585
611
  } | undefined;
586
612
  readonly media?: {
587
613
  readonly path: string;
@@ -594,7 +620,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
594
620
  }[];
595
621
  } | undefined;
596
622
  readonly detail?: string | undefined;
597
- readonly tone?: "error" | "running" | "settled" | "attention" | "muted" | undefined;
623
+ readonly tone?: "error" | "attention" | "running" | "settled" | "muted" | undefined;
598
624
  } | undefined;
599
625
  } | {
600
626
  readonly kind: "refused";
@@ -628,8 +654,8 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
628
654
  outcome: "active" | "terminal" | "cancelled" | null;
629
655
  events: readonly {
630
656
  readonly runId: string;
631
- readonly state: "skipped" | "queued" | "running" | "failed" | "complete" | "waiting";
632
657
  readonly nodeId: string;
658
+ readonly state: "failed" | "running" | "complete" | "skipped" | "queued" | "waiting";
633
659
  readonly iteration: string;
634
660
  readonly attempt: number;
635
661
  readonly output?: {
@@ -647,7 +673,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
647
673
  readonly title: string;
648
674
  readonly status?: {
649
675
  readonly label: string;
650
- readonly tone: "success" | "error" | "info" | "warning" | "neutral" | "primary" | "secondary" | "accent";
676
+ readonly tone: "success" | "error" | "neutral" | "primary" | "secondary" | "accent" | "info" | "warning";
651
677
  } | undefined;
652
678
  readonly media?: {
653
679
  readonly path: string;
@@ -660,7 +686,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
660
686
  }[];
661
687
  } | undefined;
662
688
  readonly detail?: string | undefined;
663
- readonly tone?: "error" | "running" | "settled" | "attention" | "muted" | undefined;
689
+ readonly tone?: "error" | "attention" | "running" | "settled" | "muted" | undefined;
664
690
  } | undefined;
665
691
  readonly graphId?: string | undefined;
666
692
  readonly poll?: number | undefined;
@@ -693,7 +719,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
693
719
  openedAt: number;
694
720
  expiresAt: number;
695
721
  }[];
696
- status: "unknown" | "paused" | "queued" | "running" | "errored" | "terminated" | "complete" | "waiting" | "waitingForPause";
722
+ status: "unknown" | "running" | "complete" | "paused" | "queued" | "errored" | "terminated" | "waiting" | "waitingForPause";
697
723
  output: {} | null;
698
724
  error: {
699
725
  name: string;
@@ -712,15 +738,15 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
712
738
  reason: string;
713
739
  }>;
714
740
  /** Host-only MCP control reopens the configured owner's authority on every call. */
715
- control(principal: OysterPrincipal, operation: "status" | "cancel", runId: string): Promise<{
741
+ control(principal: TenantPrincipal, operation: "status" | "cancel", runId: string): Promise<{
716
742
  runId: string;
717
743
  planDigest: string;
718
744
  title: string;
719
745
  outcome: "active" | "terminal" | "cancelled" | null;
720
746
  events: readonly {
721
747
  readonly runId: string;
722
- readonly state: "skipped" | "queued" | "running" | "failed" | "complete" | "waiting";
723
748
  readonly nodeId: string;
749
+ readonly state: "failed" | "running" | "complete" | "skipped" | "queued" | "waiting";
724
750
  readonly iteration: string;
725
751
  readonly attempt: number;
726
752
  readonly output?: {
@@ -738,7 +764,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
738
764
  readonly title: string;
739
765
  readonly status?: {
740
766
  readonly label: string;
741
- readonly tone: "success" | "error" | "info" | "warning" | "neutral" | "primary" | "secondary" | "accent";
767
+ readonly tone: "success" | "error" | "neutral" | "primary" | "secondary" | "accent" | "info" | "warning";
742
768
  } | undefined;
743
769
  readonly media?: {
744
770
  readonly path: string;
@@ -751,7 +777,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
751
777
  }[];
752
778
  } | undefined;
753
779
  readonly detail?: string | undefined;
754
- readonly tone?: "error" | "running" | "settled" | "attention" | "muted" | undefined;
780
+ readonly tone?: "error" | "attention" | "running" | "settled" | "muted" | undefined;
755
781
  } | undefined;
756
782
  readonly graphId?: string | undefined;
757
783
  readonly poll?: number | undefined;
@@ -784,7 +810,7 @@ export declare abstract class StandaloneWorkflowRunsBase<Env extends StandaloneW
784
810
  openedAt: number;
785
811
  expiresAt: number;
786
812
  }[];
787
- status: "unknown" | "paused" | "queued" | "running" | "errored" | "terminated" | "complete" | "waiting" | "waitingForPause";
813
+ status: "unknown" | "running" | "complete" | "paused" | "queued" | "errored" | "terminated" | "waiting" | "waitingForPause";
788
814
  output: {} | null;
789
815
  error: {
790
816
  name: string;
@@ -11,7 +11,7 @@ import { createStandaloneWorkflowEvents, } from "./workflow-events.js";
11
11
  import { createStandaloneWorkflowTriggerHost, standaloneTriggerErrors, } from "./workflow-trigger-host.js";
12
12
  import { createWorkflowPublishedDefinitionPort, readPublishedWorkflow, } from "@fungi.computer/workflows-wire";
13
13
  import { workflowAgentAuthority } from "../workflow-agent-authority.js";
14
- import { defaultTenant, tenantScope } from "../tenant.js";
14
+ import { defaultTenant, tenantScope, } from "../tenant.js";
15
15
  import { AppInstanceError } from "../index.js";
16
16
  import { createWorkflowGitPasses, createWorkflowGitPassStore, workflowGitPassWriter, workflowRunReport, wireRunInitiator, } from "@fungi.computer/braid/runtime";
17
17
  import { canonicalJson } from "@fungi.computer/braid";
@@ -403,8 +403,14 @@ export class StandaloneWorkflowRunsBase extends DurableObject {
403
403
  async disarmSchedule(facts, input) {
404
404
  return (await this.library(facts, "disarmSchedule")).schedules.disarm(facts, input);
405
405
  }
406
- async schedules(facts) {
407
- return (await this.library(facts, "schedules")).schedules.list(facts);
406
+ async pauseSchedule(facts, input) {
407
+ return (await this.library(facts, "pauseSchedule")).schedules.pause(facts, input);
408
+ }
409
+ async resumeSchedule(facts, input) {
410
+ return (await this.library(facts, "resumeSchedule")).schedules.resume(facts, input);
411
+ }
412
+ async schedules(facts, input) {
413
+ return (await this.library(facts, "schedules")).schedules.list(facts, input);
408
414
  }
409
415
  async armEventTrigger(facts, input) {
410
416
  return (await this.library(facts, "armEventTrigger")).events.arm(facts, input);
@@ -8,7 +8,7 @@ export declare const storageFrameMethods: {
8
8
  readonly kind: "accepted";
9
9
  readonly value: {
10
10
  readonly value: Schema.Json;
11
- readonly source: "member" | "team" | "none";
11
+ readonly source: "team" | "member" | "none";
12
12
  readonly team: {
13
13
  readonly value: Schema.Json;
14
14
  readonly revision: number;
@@ -21,7 +21,7 @@ export declare const storageFrameMethods: {
21
21
  };
22
22
  } | {
23
23
  readonly kind: "rejected";
24
- readonly code: "unavailable" | "conflict" | "invalid" | "undeclared_key" | "scope_not_declared" | "owner_required" | "too_large" | "quota_exceeded";
24
+ readonly code: "unavailable" | "invalid" | "conflict" | "undeclared_key" | "scope_not_declared" | "owner_required" | "too_large" | "quota_exceeded";
25
25
  };
26
26
  requiredOperations: () => string[];
27
27
  };
@@ -29,7 +29,7 @@ export declare const storageFrameMethods: {
29
29
  decodeArgs: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => readonly [{
30
30
  readonly value: Schema.Json;
31
31
  readonly key: string;
32
- readonly scope: "member" | "team";
32
+ readonly scope: "team" | "member";
33
33
  readonly basedOn: number | null;
34
34
  }];
35
35
  decodeResult: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => {
@@ -39,14 +39,14 @@ export declare const storageFrameMethods: {
39
39
  };
40
40
  } | {
41
41
  readonly kind: "rejected";
42
- readonly code: "unavailable" | "conflict" | "invalid" | "undeclared_key" | "scope_not_declared" | "owner_required" | "too_large" | "quota_exceeded";
42
+ readonly code: "unavailable" | "invalid" | "conflict" | "undeclared_key" | "scope_not_declared" | "owner_required" | "too_large" | "quota_exceeded";
43
43
  };
44
44
  requiredOperations: () => string[];
45
45
  };
46
46
  reset: {
47
47
  decodeArgs: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => readonly [{
48
48
  readonly key: string;
49
- readonly scope: "member" | "team";
49
+ readonly scope: "team" | "member";
50
50
  readonly basedOn: number | null;
51
51
  }];
52
52
  decodeResult: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => {
@@ -56,7 +56,7 @@ export declare const storageFrameMethods: {
56
56
  };
57
57
  } | {
58
58
  readonly kind: "rejected";
59
- readonly code: "unavailable" | "conflict" | "invalid" | "undeclared_key" | "scope_not_declared" | "owner_required" | "too_large" | "quota_exceeded";
59
+ readonly code: "unavailable" | "invalid" | "conflict" | "undeclared_key" | "scope_not_declared" | "owner_required" | "too_large" | "quota_exceeded";
60
60
  };
61
61
  requiredOperations: () => string[];
62
62
  };
@@ -1,4 +1,3 @@
1
- import { Hono } from "hono";
2
1
  import { type AppCapabilityId } from "@fungi.computer/puffball/app";
3
2
  import { type OysterAgents } from "../agents.js";
4
3
  import type { LiveOysterKey } from "../keys.js";
@@ -16,16 +15,18 @@ export type CapabilityFixtureOptions = Readonly<{
16
15
  fileSource?: FileSource;
17
16
  /** `false` clears the owner's approval after install. */
18
17
  admitted?: boolean;
19
- /** Serve a public installation to an anonymous visitor. */
20
- visitor?: boolean;
21
18
  authenticate?: (request: Request) => Promise<OysterAuthResult>;
22
19
  agents?: OysterAgents;
23
20
  liveKey?: (keyId: string) => Promise<LiveOysterKey | null>;
24
21
  }>;
25
22
  /** One Oyster host with a single installation whose capability grants the options shape. */
26
23
  export declare function capabilityFixture(options?: CapabilityFixtureOptions): Promise<{
27
- app: Hono<import("../host.js").OysterEnv, import("hono/types").BlankSchema, "/">;
28
- page: () => Response | Promise<Response>;
29
- request: () => Response | Promise<Response>;
24
+ app: Readonly<{
25
+ fetch: (request: Request<unknown, CfProperties<unknown>>, env?: unknown, executionCtx?: import("hono").ExecutionContext | undefined) => Promise<Response>;
26
+ request: (input: string | Request<unknown, CfProperties<unknown>> | URL, requestInit?: RequestInit<CfProperties<unknown>> | undefined, Env?: unknown, executionCtx?: import("hono").ExecutionContext | undefined) => Promise<Response>;
27
+ servedPaths: () => readonly string[];
28
+ }>;
29
+ page: () => Promise<Response>;
30
+ request: () => Promise<Response>;
30
31
  removeDeclaration(): Promise<void>;
31
32
  }>;
@@ -1,4 +1,4 @@
1
- import { Hono } from "hono";
1
+ import { computer, routes as routeTable } from "../authorization.js";
2
2
  import * as Schema from "effect/Schema";
3
3
  import { releaseSchema } from "@fungi.computer/puffball/effect";
4
4
  import { parseArtifactRef, parseSha256Digest } from "@fungi.computer/puffball";
@@ -43,7 +43,7 @@ export async function capabilityFixture(options = {}) {
43
43
  },
44
44
  });
45
45
  }
46
- const routes = new Hono().post("/list", (context) => context.json({ entries: [] }));
46
+ const routes = routeTable().post("/list", computer(), (context) => context.json({ entries: [] }));
47
47
  const capabilities = options.adapters ??
48
48
  (options.fileSource
49
49
  ? fileCapabilities(options.fileSource)
@@ -80,16 +80,13 @@ export async function capabilityFixture(options = {}) {
80
80
  approval: null,
81
81
  },
82
82
  };
83
- // An anonymous reader reaches only a public App, as the host's visitor.
84
- if (options.visitor)
85
- installation = { ...installation, visibility: "public" };
86
83
  const readOnly = () => Promise.reject(new Error("Fixture installations are read-only"));
87
84
  let base = {
88
85
  bootUi: () => Promise.resolve({ kind: "passed" }),
89
86
  auth: {
90
87
  resolve: () => Promise.reject(new Error("Capability fixture resolves no actor")),
91
88
  authenticate: options.authenticate ??
92
- ((request) => Promise.resolve(options.visitor || request.headers.get("x-who") === "visitor"
89
+ ((request) => Promise.resolve(request.headers.get("x-who") === "anonymous"
93
90
  ? { kind: "refused", status: 401 }
94
91
  : {
95
92
  kind: "admitted",
@@ -7,5 +7,4 @@ export declare function approvedInstallation(input: Readonly<{
7
7
  installationId: string;
8
8
  instanceId: Installation["instanceId"];
9
9
  descriptors?: readonly CapabilityOperationDescriptor[];
10
- visibility?: Installation["visibility"];
11
10
  }>): Promise<Installation>;
@@ -30,7 +30,7 @@ export async function approvedInstallation(input) {
30
30
  grant: { operations, resources: "tenant-scope" },
31
31
  }));
32
32
  if (changes.length === 0)
33
- return { ...installed, visibility: input.visibility ?? "private" };
33
+ return installed;
34
34
  const approved = applyInstallationCommand(installed, { kind: "change-grants", changes }, {
35
35
  by: { kind: "member", memberId: "fixture-owner" },
36
36
  role: "owner",
@@ -42,8 +42,5 @@ export async function approvedInstallation(input) {
42
42
  });
43
43
  if (Result.isFailure(approved))
44
44
  throw new Error(approved.failure.code);
45
- return {
46
- ...approved.success.next,
47
- visibility: input.visibility ?? "private",
48
- };
45
+ return approved.success.next;
49
46
  }
@@ -6,7 +6,6 @@ import { type OysterTenancy, type ResolvedTenant, type TenantScope } from "./ten
6
6
  */
7
7
  import { DurableObject } from "cloudflare:workers";
8
8
  import { type InvocationFrame } from "./invocation.js";
9
- import { Hono } from "hono";
10
9
  import { type GitBinding } from "@fungi.computer/agar/git";
11
10
  import { type GitDoorTarget, type StandardWebhookPayload } from "./git.js";
12
11
  import { type KeyStore } from "@fungi.computer/ear-tag/keys";
@@ -17,6 +16,7 @@ import { type ArtifactsNamespace } from "@fungi.computer/burrow";
17
16
  import { type HostEventSource, type HostRecipientEvent, type RecipientDelivery } from "./event-recipients.js";
18
17
  export type { HostEventSource, HostRecipientEvent, RecipientDelivery, } from "./event-recipients.js";
19
18
  import { type OysterAuth, type OysterCapability, type OysterEnv, type OysterGitHost, type OysterHost } from "./host.js";
19
+ import { type Routes } from "./authorization.js";
20
20
  import type { GitWriter } from "@fungi.computer/agar/git";
21
21
  import { OysterInstance, type OysterBindingContext, type OysterBindingRow, type OysterBindingTable, type OysterWorkspace, type OysterWorkerEnv, type OysterInvocationHost } from "./workers.js";
22
22
  /** The GIT binding plus the credential only the host's git door may use. */
@@ -167,7 +167,7 @@ declare const OysterBinding_base: abstract new (ctx: ExecutionContext, env: Oyst
167
167
  export declare class OysterBinding extends OysterBinding_base {
168
168
  }
169
169
  /** Owner routes for keys and webhooks; `createOyster` mounts them owner-only. */
170
- export declare function gitAdminRoutes(env: OysterGitEnv, scope: TenantScope): Hono<OysterEnv>;
170
+ export declare function gitAdminRoutes(env: OysterGitEnv, scope: TenantScope): Routes<OysterEnv>;
171
171
  /** A standalone Oyster Worker that also hosts git Apps. */
172
172
  export type OysterGitWorkerEnv = OysterWorkerEnv & OysterGitEnv & Readonly<{
173
173
  /** This Oyster's public origin, for clone URLs (e.g. https://oyster.example). */
@@ -191,6 +191,8 @@ export declare abstract class OysterGitInstance<Env extends OysterGitWorkerEnv =
191
191
  * `oysterGitRoot(options).hostFor`.
192
192
  */
193
193
  export type OysterGitWorkerOptions<Env extends OysterGitWorkerEnv> = Readonly<{
194
+ /** Picker facts through this host's existing, owner-admitted directories. */
195
+ permissionResources?: (env: Env, scope: TenantScope) => NonNullable<OysterHost["permissionResources"]>;
194
196
  /** Host-owned fleet control, admitted on every invocation by its durable owner. */
195
197
  computerControl?: (env: Env, scope: TenantScope) => NonNullable<OysterHost["computerControl"]>;
196
198
  /** Workflow controls supplied by the host's existing run owner. */
@@ -216,7 +218,7 @@ export type OysterGitWorkerOptions<Env extends OysterGitWorkerEnv> = Readonly<{
216
218
  auth: OysterAuth;
217
219
  }>) => OysterWorkspace | Promise<OysterWorkspace>;
218
220
  /** Additional capabilities share the exact workspace selected for the base host. */
219
- capabilities?: (env: Env, workspace: OysterWorkspace, keysLive: OysterKeysLivePort) => readonly OysterCapability[];
221
+ capabilities?: (env: Env, workspace: OysterWorkspace) => readonly OysterCapability[];
220
222
  /** Admit a presented Workflow Git credential for one repository and scope;
221
223
  * omit when this host issues no Workflow Git credentials. */
222
224
  workflowGitPass?: (env: Env, scope: TenantScope, pass: string, target: GitDoorTarget) => Promise<Extract<GitWriter, {
@@ -227,7 +229,7 @@ export type OysterGitWorkerOptions<Env extends OysterGitWorkerEnv> = Readonly<{
227
229
  kind: "actor";
228
230
  }> | null>;
229
231
  /** Further owner-only routes this host serves, after the owner guard. */
230
- ownerRoutes?: (env: Env, scope: TenantScope) => Hono<OysterEnv>;
232
+ ownerRoutes?: (env: Env, scope: TenantScope) => Routes<OysterEnv>;
231
233
  }>;
232
234
  /** A tenant's whole Git host: the App server, `host.git` and the owner routes. */
233
235
  export type OysterGitWorkerHost = OysterHost & Readonly<{
@@ -278,5 +280,11 @@ export declare function oysterWorkerGit<Env extends OysterGitWorkerEnv>(env: Env
278
280
  * `oysterGitRoot(options).hostFor`; a cold directory passes its own resolved tenant.
279
281
  */
280
282
  export declare function oysterGitWorkerHost<Env extends OysterGitWorkerEnv>(env: Env, options: OysterGitWorkerOptions<Env>, selected: ResolvedTenant, request?: Request): Promise<OysterGitWorkerHost>;
283
+ /**
284
+ * A Git host's whole owner table: keys and webhooks, the root's own owner
285
+ * routes, and Agent approval and MCP server custody. The host and the
286
+ * authorization law both compose it here.
287
+ */
288
+ export declare function oysterGitOwnerRoutes(env: OysterGitEnv, scope: TenantScope, hostOwnerRoutes: Routes<OysterEnv> | undefined, agents: OysterAgents | undefined): Routes<OysterEnv>;
281
289
  /** Deploy the MCP owner from the same root as createOysterGitWorker. */
282
290
  export declare function createOysterGitMcpOwner<Env extends OysterGitWorkerEnv>(root: OysterGitRoot<Env>): new (ctx: DurableObjectState, env: Env) => import("./mcp-owner.js").OysterMcpOwner<Env>;