@fungi.computer/oyster 0.5.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 (185) hide show
  1. package/README.md +155 -63
  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 +97 -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.js +9 -1
  24. package/dist/authorization.d.ts +307 -0
  25. package/dist/authorization.js +542 -0
  26. package/dist/boot-host-script.js +1 -1
  27. package/dist/build/build-jobs.d.ts +2 -2
  28. package/dist/build/candidate-builder.d.ts +2 -0
  29. package/dist/build/candidate-builder.js +5 -1
  30. package/dist/build/candidate-cli.js +3 -0
  31. package/dist/build/candidate-cli.mjs +67 -22
  32. package/dist/build/job-log.d.ts +23 -0
  33. package/dist/build/job-log.js +88 -0
  34. package/dist/build/local-build.d.ts +2 -0
  35. package/dist/build/local-build.js +11 -9
  36. package/dist/channels/binding.d.ts +8 -1
  37. package/dist/channels/binding.js +12 -0
  38. package/dist/channels/conversations.d.ts +16 -5
  39. package/dist/channels/visitor-channel.d.ts +53 -0
  40. package/dist/channels/visitor-channel.js +124 -0
  41. package/dist/channels/visitor-edge.d.ts +115 -0
  42. package/dist/channels/visitor-edge.js +582 -0
  43. package/dist/channels/visitor-request.d.ts +7 -0
  44. package/dist/channels/visitor-request.js +17 -0
  45. package/dist/channels/visitor-stream-slots.d.ts +2 -0
  46. package/dist/channels/visitor-stream-slots.js +33 -0
  47. package/dist/channels/visitors.d.ts +47 -0
  48. package/dist/channels/visitors.js +181 -0
  49. package/dist/cloudflare.d.ts +11 -2
  50. package/dist/cloudflare.js +27 -1
  51. package/dist/{page/computer-target.d.ts → computer-target.d.ts} +2 -0
  52. package/dist/{page/computer-target.js → computer-target.js} +3 -1
  53. package/dist/files.js +9 -8
  54. package/dist/git-admission.d.ts +3 -3
  55. package/dist/git-admission.js +4 -6
  56. package/dist/git-door.d.ts +8 -7
  57. package/dist/git-door.js +18 -17
  58. package/dist/git.d.ts +1 -1
  59. package/dist/host.d.ts +38 -42
  60. package/dist/host.js +182 -239
  61. package/dist/installation-execution.js +10 -5
  62. package/dist/installation-operations.d.ts +4 -180
  63. package/dist/installation-operations.js +1 -5
  64. package/dist/installation-store-generation.d.ts +4 -1
  65. package/dist/installation-store-generation.js +59 -6
  66. package/dist/internal/delivery.js +0 -1
  67. package/dist/internal/host-gate.d.ts +9 -6
  68. package/dist/internal/host-gate.js +19 -25
  69. package/dist/internal/invocation-timing.d.ts +16 -0
  70. package/dist/internal/invocation-timing.js +23 -0
  71. package/dist/internal/registry-installations.js +1 -0
  72. package/dist/invocation.d.ts +19 -11
  73. package/dist/invocation.js +171 -96
  74. package/dist/keys.d.ts +2 -19
  75. package/dist/keys.js +1 -37
  76. package/dist/mcp.d.ts +15 -27
  77. package/dist/mcp.js +105 -155
  78. package/dist/page/agent-browser.d.ts +15 -0
  79. package/dist/page/agent-browser.js +162 -0
  80. package/dist/page/app-permissions-port.d.ts +3 -0
  81. package/dist/page/app-permissions-port.js +43 -0
  82. package/dist/page/app-permissions.d.ts +11 -0
  83. package/dist/page/app-permissions.js +296 -0
  84. package/dist/page/capabilities.js +1 -1
  85. package/dist/page/child-selection.d.ts +27 -0
  86. package/dist/page/child-selection.js +38 -0
  87. package/dist/page/isolated-page-theme.d.ts +2 -0
  88. package/dist/page/isolated-page-theme.js +11 -0
  89. package/dist/page/mount.d.ts +2 -13
  90. package/dist/page/mount.js +8 -94
  91. package/dist/page-script.d.ts +0 -3
  92. package/dist/page-script.js +3 -4
  93. package/dist/release.d.ts +13 -0
  94. package/dist/release.js +10 -0
  95. package/dist/request-origin.d.ts +4 -0
  96. package/dist/request-origin.js +10 -0
  97. package/dist/standalone/agent-archive-owner.d.ts +42 -0
  98. package/dist/standalone/agent-archive-owner.js +116 -0
  99. package/dist/standalone/agent-archive-schedules.d.ts +6 -0
  100. package/dist/standalone/agent-archive-schedules.js +76 -0
  101. package/dist/standalone/agent-archive.d.ts +31 -0
  102. package/dist/standalone/agent-archive.js +67 -0
  103. package/dist/standalone/agent-computers.d.ts +7 -6
  104. package/dist/standalone/agent-computers.js +4 -7
  105. package/dist/standalone/agent-mail.d.ts +2 -2
  106. package/dist/standalone/agents.d.ts +157 -20
  107. package/dist/standalone/agents.js +242 -38
  108. package/dist/standalone/app-builds-binding.js +1 -1
  109. package/dist/standalone/app-set.js +2 -54
  110. package/dist/standalone/app-source.d.ts +3 -4
  111. package/dist/standalone/app-source.js +12 -9
  112. package/dist/standalone/builds.d.ts +2 -14
  113. package/dist/standalone/builds.js +15 -13
  114. package/dist/standalone/computer-fleet.d.ts +4 -4
  115. package/dist/standalone/computer-fleet.js +20 -43
  116. package/dist/standalone/computer.d.ts +4 -3
  117. package/dist/standalone/computer.js +52 -53
  118. package/dist/standalone/dashboard-approval.d.ts +10 -0
  119. package/dist/standalone/dashboard-approval.js +66 -0
  120. package/dist/standalone/machine-link.d.ts +4 -221
  121. package/dist/standalone/machine-link.js +21 -15
  122. package/dist/standalone/media.d.ts +1 -0
  123. package/dist/standalone/media.js +20 -14
  124. package/dist/standalone/owner-routes.d.ts +16 -0
  125. package/dist/standalone/owner-routes.js +21 -0
  126. package/dist/standalone/permission-resources.d.ts +5 -0
  127. package/dist/standalone/permission-resources.js +31 -0
  128. package/dist/standalone/registry.d.ts +7 -0
  129. package/dist/standalone/registry.js +3 -0
  130. package/dist/standalone/tenancy.js +3 -1
  131. package/dist/standalone/worker-routes.d.ts +19 -0
  132. package/dist/standalone/worker-routes.js +9 -0
  133. package/dist/standalone/worker.d.ts +1 -1
  134. package/dist/standalone/worker.js +27 -35
  135. package/dist/standalone/workflow-binding.d.ts +8 -3
  136. package/dist/standalone/workflow-binding.js +14 -5
  137. package/dist/standalone/workflow-git-capture.js +2 -1
  138. package/dist/standalone/workflow-host.d.ts +8 -103
  139. package/dist/standalone/workflow-host.js +1 -1
  140. package/dist/standalone/workflow-node-capture.js +2 -2
  141. package/dist/standalone/workflow-root-authority.d.ts +1 -1
  142. package/dist/standalone/workflow-root-authority.js +1 -1
  143. package/dist/standalone/workflow-schedules.d.ts +14 -5
  144. package/dist/standalone/workflow-schedules.js +11 -5
  145. package/dist/standalone/workflow-webhooks.d.ts +4 -18
  146. package/dist/standalone/workflow-webhooks.js +5 -5
  147. package/dist/standalone/workflows.d.ts +36 -28
  148. package/dist/standalone/workflows.js +6 -3
  149. package/dist/storage-frame.d.ts +6 -6
  150. package/dist/testing/capabilities.d.ts +7 -6
  151. package/dist/testing/capabilities.js +3 -6
  152. package/dist/testing/installation.d.ts +0 -1
  153. package/dist/testing/installation.js +2 -5
  154. package/dist/turnstile.d.ts +27 -0
  155. package/dist/turnstile.js +51 -0
  156. package/dist/workers-git.d.ts +12 -4
  157. package/dist/workers-git.js +58 -36
  158. package/dist/workers.d.ts +9 -1
  159. package/dist/workers.js +59 -20
  160. package/dist/workflows.d.ts +2 -0
  161. package/dist/workflows.js +1 -0
  162. package/docs/api/README.md +7 -0
  163. package/docs/api/agent-schedules.md +175 -0
  164. package/docs/api/agents.md +34 -13
  165. package/docs/api/app-storage.md +1 -1
  166. package/docs/api/apps.md +323 -225
  167. package/docs/api/authorization.md +1300 -0
  168. package/docs/api/build-contract.md +2 -2
  169. package/docs/api/build.md +40 -37
  170. package/docs/api/cloudflare.md +27 -2
  171. package/docs/api/git.md +20 -11
  172. package/docs/api/host.md +80 -199
  173. package/docs/api/index.md +1 -1
  174. package/docs/api/invocation.md +15 -11
  175. package/docs/api/keys.md +1 -98
  176. package/docs/api/mcp.md +43 -40
  177. package/docs/api/modules.md +2 -0
  178. package/docs/api/page/mount.md +16 -19
  179. package/docs/api/workers-git.md +46 -12
  180. package/docs/api/workers.md +125 -235
  181. package/docs/site/agent-quickstart.mdx +6 -2
  182. package/examples/standalone/wrangler.celld.jsonc +66 -0
  183. package/package.json +64 -21
  184. package/dist/standalone/channel-session-door.d.ts +0 -4
  185. package/dist/standalone/channel-session-door.js +0 -42
@@ -5,8 +5,9 @@
5
5
  */
6
6
  import { createOysterGitWorker, createOysterGitMcpOwner, oysterGitRoot, } from "../workers-git.js";
7
7
  import { defaultTenant, tenantScope } from "../tenant.js";
8
- import { oysterPrincipalIsOwner } from "../host.js";
8
+ import { oysterPrincipalIsOwner } from "../authorization.js";
9
9
  import { standaloneComputerControl } from "./computer-control.js";
10
+ import { standalonePermissionResources } from "./permission-resources.js";
10
11
  import { onBoxVmIngress } from "@fungi.computer/computer";
11
12
  import { WorkerEntrypoint } from "cloudflare:workers";
12
13
  import { installationWorkerEntrypoint } from "../installation-execution.js";
@@ -25,15 +26,13 @@ import { standalonePreviewRequest } from "./preview.js";
25
26
  import { standaloneMachineLinkRoutes, } from "./machine-link.js";
26
27
  export { MachineLinkDO } from "./machine-link.js";
27
28
  import { standaloneWorkflowControl } from "./workflow-control.js";
28
- import { standaloneWorkflowWebhookRoutes, standaloneWorkflowWebhookControls, } from "./workflow-webhooks.js";
29
- import { Hono } from "hono";
29
+ import { standaloneWorkflowWebhookRoutes } from "./workflow-webhooks.js";
30
+ import { serveDoors } from "../authorization.js";
31
+ import { standaloneWorkerRoutes } from "./worker-routes.js";
30
32
  import { HTTPException } from "hono/http-exception";
31
- import { standaloneBuildRoutes } from "./builds.js";
32
- import { standaloneComputerFleetRoutes, standaloneComputerSelection, } from "./computer-fleet.js";
33
- import { standaloneAgentComputerRoutes } from "./agent-computers.js";
34
- import { agentDirectoryForScope } from "./agent-directory.js";
33
+ import { standaloneOwnerRoutes } from "./owner-routes.js";
34
+ import { standaloneComputerSelection } from "./computer-fleet.js";
35
35
  import { serveOysterComputerEgress, } from "./computer-egress.js";
36
- import { appSourceOwnerRoutes, } from "./app-source.js";
37
36
  export { StandaloneGraphWorkflow } from "./workflows.js";
38
37
  export { MediaOperationDO } from "@fungi.computer/darkroom/cloudflare";
39
38
  /** A tenant's registry: it owns that tenant's installations and App builds. */
@@ -68,13 +67,17 @@ const standaloneRoot = (selectComputer) => {
68
67
  }),
69
68
  homeInstallationId: (env) => env.OYSTER_HOME_INSTALLATION,
70
69
  agents: standaloneAgents,
70
+ permissionResources: (env, scope) => standalonePermissionResources({
71
+ // Acquire the registry stub only when owner inventory is requested.
72
+ computerFleet: (memberId, request) => tenantRegistry(env, scope).computerFleet(memberId, request),
73
+ }, standaloneAgents(env, scope)),
71
74
  workflows: standaloneWorkflowControl,
72
75
  computerControl: (env, scope) => (principal) => oysterPrincipalIsOwner(principal)
73
76
  ? standaloneComputerControl(tenantRegistry(env, scope), principal.actor.memberId)
74
77
  : null,
75
78
  workspace: async (env, keysLive, scope, request) => standaloneWorkspace(env, keysLive, await selectComputer(tenantRegistry(env, scope), request)),
76
- capabilities: (env, workspace, keysLive) => [
77
- ...standaloneComputerCapabilities(env, workspace, keysLive),
79
+ capabilities: (env, workspace) => [
80
+ ...standaloneComputerCapabilities(env, workspace),
78
81
  ...workersMedia(env, workspace),
79
82
  ],
80
83
  // A presented bearer names the library that issued it; only that
@@ -101,15 +104,7 @@ const standaloneRoot = (selectComputer) => {
101
104
  };
102
105
  },
103
106
  // Operator source seeding and owner builds share the one owner guard.
104
- ownerRoutes: (env, scope) => appSourceOwnerRoutes(env, scope)
105
- .route("/", standaloneBuildRoutes(() => tenantRegistry(env, scope)))
106
- .route("/", standaloneComputerFleetRoutes(() => tenantRegistry(env, scope)))
107
- .route("/", standaloneAgentComputerRoutes({
108
- attach: (principal, command) => agentDirectoryForScope(env, scope).attachComputer(command, principal, scope.tenantId),
109
- detach: (principal, command) => agentDirectoryForScope(env, scope).detachComputer(command, principal, scope.tenantId),
110
- read: (principal, agentId) => agentDirectoryForScope(env, scope).readAgentComputers(agentId, principal, scope.tenantId),
111
- }))
112
- .route("/", standaloneWorkflowWebhookControls(env, () => root.hostFor(env, scope))),
107
+ ownerRoutes: (env, scope) => standaloneOwnerRoutes(env, scope, () => root.hostFor(env, scope)),
113
108
  });
114
109
  return root;
115
110
  };
@@ -190,21 +185,18 @@ export default {
190
185
  const fetchOyster = oyster.fetch;
191
186
  if (fetchOyster === undefined)
192
187
  throw new Error("Oyster fetch handler is missing");
193
- return new Hono()
194
- .onError(standaloneWorkerErrorHandler)
195
- .all("/local/mesh/join", () => standaloneMachineLinkRoutes(env)
196
- .onError(standaloneWorkerErrorHandler)
197
- .fetch(request, env, context))
198
- .all("/api/teams/:teamId/local/mesh/:deviceId/connect", () => standaloneMachineLinkRoutes(env)
199
- .onError(standaloneWorkerErrorHandler)
200
- .fetch(request, env, context))
201
- .route("/", standaloneWorkflowWebhookRoutes(env, async (incoming) => {
202
- const admitted = await oysterRoot.admit(env, incoming);
203
- return admitted === null
204
- ? null
205
- : oysterRoot.hostFor(env, admitted.scope);
206
- }))
207
- .all("*", () => fetchOyster(request, env, context))
208
- .fetch(request, env, context);
188
+ // Doors before any tenant is selected; every other path reaches the
189
+ // tenant host's own declared table.
190
+ return serveDoors(standaloneWorkerRoutes({
191
+ machineLink: (incoming) => serveDoors(standaloneMachineLinkRoutes(env).onError(standaloneWorkerErrorHandler)).fetch(incoming, env, context),
192
+ workflowWebhooks: standaloneWorkflowWebhookRoutes(env, async (incoming) => {
193
+ const admitted = await oysterRoot.admit(env, incoming);
194
+ return admitted === null
195
+ ? null
196
+ : oysterRoot.hostFor(env, admitted.scope);
197
+ }),
198
+ // The tenant table answers the Worker's own incoming request.
199
+ tenant: async () => fetchOyster(request, env, context),
200
+ }).onError(standaloneWorkerErrorHandler)).fetch(request, env, context);
209
201
  },
210
202
  };
@@ -48,7 +48,7 @@ export type TriggerArmTarget = z.output<typeof triggerArmTargetSchema>;
48
48
  export type ScheduleDisarmInput = z.output<typeof scheduleDisarmInputSchema>;
49
49
  export type EventDisarmInput = z.output<typeof eventDisarmInputSchema>;
50
50
  /** The frame gate needs only these run-owner calls; it re-decodes each reply with the method's owner schema. */
51
- export type WorkflowRunCalls = Pick<StandaloneWorkflowRunsBase, "admitWorkflowGit" | "catalog" | "start" | "status" | "cancel" | "answerReview" | "armSchedule" | "disarmSchedule" | "schedules" | "armEventTrigger" | "disarmEventTrigger" | "eventTriggers" | "runs">;
51
+ export type WorkflowRunCalls = Pick<StandaloneWorkflowRunsBase, "admitWorkflowGit" | "catalog" | "start" | "status" | "cancel" | "answerReview" | "armSchedule" | "pauseSchedule" | "disarmSchedule" | "schedules" | "armEventTrigger" | "disarmEventTrigger" | "eventTriggers" | "runs">;
52
52
  export type WorkflowBindingEnv = Readonly<{
53
53
  WORKFLOW_RUNS: Readonly<{
54
54
  getByName(installationId: string): WorkflowRunCalls;
@@ -130,7 +130,12 @@ export declare const workflowFrameMethods: {
130
130
  } | undefined;
131
131
  }]) | ((args: unknown) => [{
132
132
  scheduleId: string;
133
- }]) | ((args: unknown) => [Record<string, never>]) | ((args: unknown) => [{
133
+ }]) | ((args: unknown) => [{
134
+ scheduleId: string;
135
+ }]) | ((args: unknown) => [{
136
+ limit: number;
137
+ after?: string | undefined;
138
+ }]) | ((args: unknown) => [{
134
139
  digest: string & {
135
140
  readonly appReleaseKind: "Sha256Digest";
136
141
  };
@@ -150,7 +155,7 @@ export declare const workflowFrameMethods: {
150
155
  workflowId?: string | undefined;
151
156
  }]);
152
157
  decodeResult: (value: unknown) => z.core.util.JSONType;
153
- requiredOperations: () => ("catalog" | "runGraph" | "armSchedule" | "disarmSchedule" | "schedules" | "armEventTrigger" | "disarmEventTrigger" | "eventTriggers" | "cancel" | "answerReview" | "graphStatus" | "runs")[];
158
+ requiredOperations: () => ("catalog" | "runGraph" | "armSchedule" | "disarmSchedule" | "pauseSchedule" | "schedules" | "armEventTrigger" | "disarmEventTrigger" | "eventTriggers" | "cancel" | "answerReview" | "graphStatus" | "runs")[];
154
159
  };
155
160
  };
156
161
  };
@@ -2,7 +2,7 @@ import * as S from "effect/Schema";
2
2
  import { z } from "zod";
3
3
  import { graphReviewSchema, reviewAnswerSchema } from "@fungi.computer/braid";
4
4
  import { graphStartRequestSchema, workflowTriggerTargetSchema, } from "@fungi.computer/braid/runtime";
5
- import { runReply, answerReviewReply, catalogReplySchema, statusReply, cancelReplySchema, runsReplySchema, runsInputSchema, eventArmReplySchema, eventDisarmInputSchema, eventTriggersReplySchema, scheduleArmReplySchema, scheduleDisarmInputSchema, schedulesReplySchema, triggerDisarmReplySchema, triggerListInputSchema, } from "@fungi.computer/workflows-wire";
5
+ import { runReply, answerReviewReply, catalogReplySchema, statusReply, cancelReplySchema, runsReplySchema, runsInputSchema, eventArmReplySchema, eventDisarmInputSchema, eventTriggersReplySchema, scheduleArmReplySchema, scheduleDisarmInputSchema, schedulePauseInputSchema, schedulePauseReplySchema, scheduleListInputSchema, schedulesReplySchema, triggerDisarmReplySchema, triggerListInputSchema, } from "@fungi.computer/workflows-wire";
6
6
  import { workflowAttestationSchema } from "@fungi.computer/puffball/app-method-runtime";
7
7
  import { appEventFactSchema, } from "@fungi.computer/puffball/app-event-facts";
8
8
  import { AppInstanceError } from "../index.js";
@@ -26,7 +26,8 @@ const workflowArgs = {
26
26
  answerReview: effectArgs(S.Tuple([reviewKey])),
27
27
  armSchedule: (args) => z.tuple([triggerArmTargetSchema]).parse(args),
28
28
  disarmSchedule: (args) => z.tuple([scheduleDisarmInputSchema]).parse(args),
29
- schedules: (args) => z.tuple([triggerListInputSchema]).parse(args),
29
+ pauseSchedule: (args) => z.tuple([schedulePauseInputSchema]).parse(args),
30
+ schedules: (args) => z.tuple([scheduleListInputSchema]).parse(args),
30
31
  armEventTrigger: (args) => z.tuple([triggerArmTargetSchema]).parse(args),
31
32
  disarmEventTrigger: (args) => z.tuple([eventDisarmInputSchema]).parse(args),
32
33
  eventTriggers: (args) => z.tuple([triggerListInputSchema]).parse(args),
@@ -40,6 +41,7 @@ const workflowResults = {
40
41
  answerReview: answerReviewReply,
41
42
  armSchedule: scheduleArmReplySchema,
42
43
  disarmSchedule: triggerDisarmReplySchema,
44
+ pauseSchedule: schedulePauseReplySchema,
43
45
  schedules: schedulesReplySchema,
44
46
  armEventTrigger: eventArmReplySchema,
45
47
  disarmEventTrigger: triggerDisarmReplySchema,
@@ -53,6 +55,7 @@ const workflowMethod = z.enum([
53
55
  "cancel",
54
56
  "answerReview",
55
57
  "armSchedule",
58
+ "pauseSchedule",
56
59
  "disarmSchedule",
57
60
  "schedules",
58
61
  "armEventTrigger",
@@ -184,10 +187,16 @@ export async function dispatchWorkflowBinding(env, frame, props, method, args) {
184
187
  result = await runs.disarmSchedule(frame.facts, input);
185
188
  break;
186
189
  }
187
- case "schedules":
188
- workflowArgs.schedules(args);
189
- result = await runs.schedules(frame.facts);
190
+ case "pauseSchedule": {
191
+ const [input] = workflowArgs.pauseSchedule(args);
192
+ result = await runs.pauseSchedule(frame.facts, input);
190
193
  break;
194
+ }
195
+ case "schedules": {
196
+ const [input] = workflowArgs.schedules(args);
197
+ result = await runs.schedules(frame.facts, input);
198
+ break;
199
+ }
191
200
  case "armEventTrigger": {
192
201
  const [input] = workflowArgs.armEventTrigger(args);
193
202
  result = await runs.armEventTrigger(frame.facts, input);
@@ -1,7 +1,8 @@
1
1
  import { repositoryRefSchema } from "@fungi.computer/agar/git";
2
2
  import { approvedBindingGrants } from "../apps/index.js";
3
3
  import { createInstallationGitAdmission } from "../git.js";
4
- import { oysterPrincipalIsOwner, resolveBackend } from "../host.js";
4
+ import { resolveBackend } from "../host.js";
5
+ import { oysterPrincipalIsOwner } from "../authorization.js";
5
6
  import { invocationCallerContext } from "../invocation.js";
6
7
  /** Installation Git only; Team-source needs its separate authoritative namespace owner. */
7
8
  export function createStandaloneWorkflowInstallationGitCapture(options) {
@@ -127,25 +127,6 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
127
127
  }> | null;
128
128
  };
129
129
  status: "enabled" | "disabled" | "deleted";
130
- visibility: "private" | "public";
131
- approvedAnonymousMethods: readonly Readonly<{
132
- name: string;
133
- digest: import("@fungi.computer/puffball").Sha256Digest;
134
- }>[];
135
- anonymousApproval: Readonly<{
136
- by: {
137
- kind: "member";
138
- memberId: string;
139
- } | {
140
- kind: "agent";
141
- agentId: string;
142
- } | {
143
- kind: "team-key";
144
- keyId: string;
145
- };
146
- at: number;
147
- authorityVersion: number;
148
- }> | null;
149
130
  }>;
150
131
  verified: Readonly<{
151
132
  release: import("@fungi.computer/puffball").Release;
@@ -263,25 +244,6 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
263
244
  }> | null;
264
245
  };
265
246
  status: "enabled" | "disabled" | "deleted";
266
- visibility: "private" | "public";
267
- approvedAnonymousMethods: readonly Readonly<{
268
- name: string;
269
- digest: import("@fungi.computer/puffball").Sha256Digest;
270
- }>[];
271
- anonymousApproval: Readonly<{
272
- by: {
273
- kind: "member";
274
- memberId: string;
275
- } | {
276
- kind: "agent";
277
- agentId: string;
278
- } | {
279
- kind: "team-key";
280
- keyId: string;
281
- };
282
- at: number;
283
- authorityVersion: number;
284
- }> | null;
285
247
  }>;
286
248
  verified: Readonly<{
287
249
  release: import("@fungi.computer/puffball").Release;
@@ -349,25 +311,6 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
349
311
  }> | null;
350
312
  };
351
313
  status: "enabled" | "disabled" | "deleted";
352
- visibility: "private" | "public";
353
- approvedAnonymousMethods: readonly Readonly<{
354
- name: string;
355
- digest: import("@fungi.computer/puffball").Sha256Digest;
356
- }>[];
357
- anonymousApproval: Readonly<{
358
- by: {
359
- kind: "member";
360
- memberId: string;
361
- } | {
362
- kind: "agent";
363
- agentId: string;
364
- } | {
365
- kind: "team-key";
366
- keyId: string;
367
- };
368
- at: number;
369
- authorityVersion: number;
370
- }> | null;
371
314
  }>;
372
315
  pin: {
373
316
  selection: {
@@ -468,25 +411,6 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
468
411
  }> | null;
469
412
  };
470
413
  status: "enabled" | "disabled" | "deleted";
471
- visibility: "private" | "public";
472
- approvedAnonymousMethods: readonly Readonly<{
473
- name: string;
474
- digest: import("@fungi.computer/puffball").Sha256Digest;
475
- }>[];
476
- anonymousApproval: Readonly<{
477
- by: {
478
- kind: "member";
479
- memberId: string;
480
- } | {
481
- kind: "agent";
482
- agentId: string;
483
- } | {
484
- kind: "team-key";
485
- keyId: string;
486
- };
487
- at: number;
488
- authorityVersion: number;
489
- }> | null;
490
414
  }>;
491
415
  verified: Readonly<{
492
416
  release: import("@fungi.computer/puffball").Release;
@@ -568,25 +492,6 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
568
492
  }> | null;
569
493
  };
570
494
  status: "enabled" | "disabled" | "deleted";
571
- visibility: "private" | "public";
572
- approvedAnonymousMethods: readonly Readonly<{
573
- name: string;
574
- digest: import("@fungi.computer/puffball").Sha256Digest;
575
- }>[];
576
- anonymousApproval: Readonly<{
577
- by: {
578
- kind: "member";
579
- memberId: string;
580
- } | {
581
- kind: "agent";
582
- agentId: string;
583
- } | {
584
- kind: "team-key";
585
- keyId: string;
586
- };
587
- at: number;
588
- authorityVersion: number;
589
- }> | null;
590
495
  }>;
591
496
  verified: Readonly<{
592
497
  release: import("@fungi.computer/puffball").Release;
@@ -654,13 +559,13 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
654
559
  readonly input: {
655
560
  readonly [x: string]: S.Json;
656
561
  };
562
+ readonly title: string;
657
563
  readonly apps: {
658
564
  readonly [x: string]: {
659
565
  readonly appId: string;
660
566
  readonly role?: string | undefined;
661
567
  };
662
568
  };
663
- readonly title: string;
664
569
  readonly nodes: readonly ({
665
570
  readonly id: string;
666
571
  readonly kind: "code";
@@ -698,19 +603,19 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
698
603
  } | {
699
604
  readonly id: string;
700
605
  readonly kind: "review";
701
- readonly timeout: number;
702
606
  readonly title: string;
607
+ readonly timeout: number;
703
608
  readonly reviewers: "runner" | "owners";
704
609
  readonly show: readonly {
705
610
  readonly node: string;
706
611
  readonly port: string;
707
612
  }[];
613
+ readonly detail?: string | undefined;
708
614
  readonly choices?: readonly {
709
615
  readonly label: string;
710
616
  readonly id: string;
711
617
  readonly description?: string | undefined;
712
618
  }[] | undefined;
713
- readonly detail?: string | undefined;
714
619
  } | {
715
620
  readonly id: string;
716
621
  readonly kind: "condition";
@@ -795,19 +700,19 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
795
700
  } | {
796
701
  readonly id: string;
797
702
  readonly kind: "review";
798
- readonly timeout: number;
799
703
  readonly title: string;
704
+ readonly timeout: number;
800
705
  readonly reviewers: "runner" | "owners";
801
706
  readonly show: readonly {
802
707
  readonly node: string;
803
708
  readonly port: string;
804
709
  }[];
710
+ readonly detail?: string | undefined;
805
711
  readonly choices?: readonly {
806
712
  readonly label: string;
807
713
  readonly id: string;
808
714
  readonly description?: string | undefined;
809
715
  }[] | undefined;
810
- readonly detail?: string | undefined;
811
716
  } | {
812
717
  readonly id: string;
813
718
  readonly kind: "condition";
@@ -860,10 +765,10 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
860
765
  readonly triggers?: readonly ({
861
766
  readonly id: string;
862
767
  readonly on: "webhook";
768
+ readonly when?: import("@fungi.computer/braid").Predicate | undefined;
863
769
  readonly input?: {
864
770
  readonly [x: string]: import("@fungi.computer/braid").Mapping;
865
771
  } | undefined;
866
- readonly when?: import("@fungi.computer/braid").Predicate | undefined;
867
772
  readonly title?: string | undefined;
868
773
  } | {
869
774
  readonly id: string;
@@ -878,14 +783,14 @@ export declare function createStandaloneWorkflowHost(owner: WatchdogSqliteOwner,
878
783
  readonly title?: string | undefined;
879
784
  } | {
880
785
  readonly id: string;
786
+ readonly app: string;
881
787
  readonly on: "event";
882
788
  readonly event: string;
883
- readonly app: string;
884
789
  readonly eventDigest: string;
790
+ readonly when?: import("@fungi.computer/braid").Predicate | undefined;
885
791
  readonly input?: {
886
792
  readonly [x: string]: import("@fungi.computer/braid").Mapping;
887
793
  } | undefined;
888
- readonly when?: import("@fungi.computer/braid").Predicate | undefined;
889
794
  readonly repository?: import("@fungi.computer/braid").Mapping | undefined;
890
795
  readonly title?: string | undefined;
891
796
  })[] | undefined;
@@ -10,7 +10,7 @@ import { appCapabilityIds } from "@fungi.computer/puffball";
10
10
  import { createGraphWorkflowRuns, createTriggerRunReservations, compileForMember, graphStartRequestSchema, preparationFromRun, planNodeCall, workflowRunContextSchema, } from "@fungi.computer/braid/runtime";
11
11
  import { appMethodCallContextSchema } from "@fungi.computer/puffball/app";
12
12
  import { appEventFactSchema, } from "@fungi.computer/puffball/app-event-facts";
13
- import { keyAppAccess } from "../keys.js";
13
+ import { keyAppAccess } from "../authorization.js";
14
14
  import { Validator } from "@cfworker/json-schema";
15
15
  // Mirrors packages/oyster/src/cloudflare.ts's MAX_APP_REPLY_BYTES. That
16
16
  // module imports "cloudflare:workers" at the top level, so it cannot be
@@ -3,7 +3,8 @@ import { appBackendBindingsSchema } from "@fungi.computer/puffball/app";
3
3
  import { catalogMethods } from "@fungi.computer/braid";
4
4
  import { workflowMethodRequiresComputer, } from "@fungi.computer/braid/runtime";
5
5
  import { admitMethodMetadata, appInvocationCeiling, approvedBindingGrants, deriveDeclaredOperations, scopedBindings, } from "../apps/index.js";
6
- import { oysterPrincipalIsOwner, verifyRelease, } from "../host.js";
6
+ import { verifyRelease } from "../host.js";
7
+ import { oysterPrincipalIsOwner } from "../authorization.js";
7
8
  import { invocationCallerContext } from "../invocation.js";
8
9
  /** Capture one compiled node through the same metadata admission as ordinary App calls. */
9
10
  export function createStandaloneWorkflowNodeCapture(options) {
@@ -33,7 +34,6 @@ export function createStandaloneWorkflowNodeCapture(options) {
33
34
  principal: { actor: caller.actor, role: caller.role ?? null },
34
35
  installation: {
35
36
  status: installation.status,
36
- visibility: installation.visibility,
37
37
  instanceId: installation.instanceId,
38
38
  authority: installation.authority,
39
39
  artifactDigest: installation.release.artifact.artifactDigest,
@@ -1,7 +1,7 @@
1
1
  import { type WorkflowRunAuthority } from "@fungi.computer/braid/runtime";
2
2
  import type { RepositoryRef } from "@fungi.computer/agar/git";
3
3
  import type { AppToolPolicy } from "../apps/index.js";
4
- import { type LiveOysterKey } from "../keys.js";
4
+ import type { LiveOysterKey } from "../keys.js";
5
5
  import type { StandaloneTenancy } from "./tenancy.js";
6
6
  import { type StandaloneWorkflowNodeCaptureOptions } from "./workflow-node-capture.js";
7
7
  import type { StandaloneWorkflowAuthorityReaderOptions } from "./workflow-authority-readers.js";
@@ -1,6 +1,6 @@
1
1
  import { createWorkflowRunAuthority, createWorkflowCeilingCapture, planInstallationLevels, } from "@fungi.computer/braid/runtime";
2
2
  import { AppInstanceError } from "../index.js";
3
- import { keyAppAccess } from "../keys.js";
3
+ import { keyAppAccess } from "../authorization.js";
4
4
  import { createStandaloneWorkflowAuthorityReaders } from "./workflow-authority-readers.js";
5
5
  import { createStandaloneWorkflowNodeCapture, } from "./workflow-node-capture.js";
6
6
  import { createStandaloneWorkflowInstallationGitCapture } from "./workflow-git-capture.js";
@@ -1,6 +1,7 @@
1
1
  import { createWorkflowSchedules, type WorkflowInstallationAuthority } from "@fungi.computer/braid/runtime";
2
2
  import type { AppMethodCallContext } from "@fungi.computer/puffball/app-method-runtime";
3
3
  import type { workflowAgentAuthority } from "../workflow-agent-authority.js";
4
+ import { type ScheduleListInput } from "@fungi.computer/workflows-wire";
4
5
  import { type TriggerArmTarget, type ScheduleDisarmInput } from "./workflow-binding.js";
5
6
  /** The host supplies this result only after reopening the protected invocation. */
6
7
  export type TriggerAdmission = Readonly<{
@@ -10,7 +11,7 @@ export type TriggerAdmission = Readonly<{
10
11
  /** The admitted frame's selection and verified artifact, pinned on arm. */
11
12
  installationAuthority: WorkflowInstallationAuthority;
12
13
  }>;
13
- export type ScheduleOperation = "armSchedule" | "disarmSchedule" | "schedules";
14
+ export type ScheduleOperation = "armSchedule" | "pauseSchedule" | "disarmSchedule" | "schedules";
14
15
  /** Host controls and alarm delivery compose the shared schedule owner unchanged. */
15
16
  export declare function createStandaloneWorkflowSchedules<Frame>(options: Parameters<typeof createWorkflowSchedules>[0] & {
16
17
  admitInvocation(frame: Frame, operation: ScheduleOperation): Promise<TriggerAdmission>;
@@ -37,10 +38,16 @@ export declare function createStandaloneWorkflowSchedules<Frame>(options: Parame
37
38
  } | {
38
39
  error: string;
39
40
  }>;
40
- list(frame: Frame): Promise<{
41
- error: string;
42
- schedules?: undefined;
41
+ pause(frame: Frame, raw: {
42
+ scheduleId: string;
43
+ }): Promise<{
44
+ kind: "not_found";
43
45
  } | {
46
+ kind: "paused";
47
+ } | {
48
+ error: string;
49
+ }>;
50
+ list(frame: Frame, raw: ScheduleListInput): Promise<{
44
51
  schedules: {
45
52
  scheduleId: string;
46
53
  installationId: string;
@@ -50,6 +57,8 @@ export declare function createStandaloneWorkflowSchedules<Frame>(options: Parame
50
57
  state: "active" | "finished" | "paused" | "cancelled";
51
58
  lastError: string | null;
52
59
  }[];
53
- error?: undefined;
60
+ nextCursor: string | null;
61
+ } | {
62
+ error: string;
54
63
  }>;
55
64
  };
@@ -1,5 +1,5 @@
1
1
  import { createWorkflowSchedules, } from "@fungi.computer/braid/runtime";
2
- import { scheduleDisarmInputSchema } from "@fungi.computer/workflows-wire";
2
+ import { scheduleDisarmInputSchema, schedulePauseInputSchema, scheduleListInputSchema, } from "@fungi.computer/workflows-wire";
3
3
  import { triggerArmTargetSchema, } from "./workflow-binding.js";
4
4
  /** Host controls and alarm delivery compose the shared schedule owner unchanged. */
5
5
  export function createStandaloneWorkflowSchedules(options) {
@@ -27,13 +27,19 @@ export function createStandaloneWorkflowSchedules(options) {
27
27
  return { error: "not_granted" };
28
28
  return schedules.disarm(authority.principal, libraryId, scheduleId);
29
29
  },
30
- async list(frame) {
30
+ async pause(frame, raw) {
31
+ const { scheduleId } = schedulePauseInputSchema.parse(raw);
32
+ const { libraryId, authority } = await options.admitInvocation(frame, "pauseSchedule");
33
+ if (authority === null)
34
+ return { error: "not_granted" };
35
+ return schedules.pause(authority.principal, libraryId, scheduleId);
36
+ },
37
+ async list(frame, raw) {
38
+ const input = scheduleListInputSchema.parse(raw);
31
39
  const { libraryId, authority } = await options.admitInvocation(frame, "schedules");
32
40
  if (authority === null)
33
41
  return { error: "not_granted" };
34
- return {
35
- schedules: await schedules.list(authority.principal, libraryId),
36
- };
42
+ return schedules.list(authority.principal, libraryId, input);
37
43
  },
38
44
  };
39
45
  }
@@ -1,22 +1,8 @@
1
- import { Hono } from "hono";
1
+ import type { BlankEnv } from "hono/types";
2
+ import { type Routes } from "../authorization.js";
2
3
  import type { OysterEnv, OysterHost } from "../host.js";
3
4
  import type { StandaloneWorkflowEnv } from "./workflows.js";
4
5
  /** The root resolves the origin before this unauthenticated signed-delivery path. */
5
- export declare function standaloneWorkflowWebhookRoutes(env: Pick<StandaloneWorkflowEnv, "WORKFLOW_RUNS">, hostFor: (request: Request) => Promise<Pick<OysterHost, "installations"> | null>): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
6
- "/api/installations/:installationId/workflows/webhooks/:bindingId": {
7
- $all: {
8
- input: {
9
- param: {
10
- installationId: string;
11
- } & {
12
- bindingId: string;
13
- };
14
- };
15
- output: {};
16
- outputFormat: string;
17
- status: import("hono/utils/http-status").StatusCode;
18
- };
19
- };
20
- }, "/", "/api/installations/:installationId/workflows/webhooks/:bindingId">;
6
+ export declare function standaloneWorkflowWebhookRoutes(env: Pick<StandaloneWorkflowEnv, "WORKFLOW_RUNS">, hostFor: (request: Request) => Promise<Pick<OysterHost, "installations"> | null>): Routes<BlankEnv>;
21
7
  /** Mounted only under the root's authenticated owner routes; the DO re-admits. */
22
- export declare function standaloneWorkflowWebhookControls(env: Pick<StandaloneWorkflowEnv, "WORKFLOW_RUNS">, hostFor: () => Promise<Pick<OysterHost, "installations">>): Hono<OysterEnv>;
8
+ export declare function standaloneWorkflowWebhookControls(env: Pick<StandaloneWorkflowEnv, "WORKFLOW_RUNS">, hostFor: () => Promise<Pick<OysterHost, "installations">>): Routes<OysterEnv>;
@@ -1,4 +1,4 @@
1
- import { Hono } from "hono";
1
+ import { door, owner, routes } from "../authorization.js";
2
2
  import { bodyLimit } from "hono/body-limit";
3
3
  import * as Schema from "effect/Schema";
4
4
  import { workflowWebhookCommandSchema } from "../webhooks.js";
@@ -11,7 +11,7 @@ async function libraryExists(host, installationId) {
11
11
  }
12
12
  /** The root resolves the origin before this unauthenticated signed-delivery path. */
13
13
  export function standaloneWorkflowWebhookRoutes(env, hostFor) {
14
- return new Hono().all("/api/installations/:installationId/workflows/webhooks/:bindingId", async (context) => {
14
+ return routes().all("/api/installations/:installationId/workflows/webhooks/:bindingId", door("a signed delivery; the library's run owner verifies its signature"), async (context) => {
15
15
  const host = await hostFor(context.req.raw);
16
16
  const installationId = context.req.param("installationId");
17
17
  if (host === null || !(await libraryExists(host, installationId)))
@@ -24,7 +24,7 @@ export function standaloneWorkflowWebhookRoutes(env, hostFor) {
24
24
  }
25
25
  /** Mounted only under the root's authenticated owner routes; the DO re-admits. */
26
26
  export function standaloneWorkflowWebhookControls(env, hostFor) {
27
- return new Hono().post("/api/installations/:installationId/workflows/webhooks", bodyLimit({ maxSize: 64 * 1024, onError: refused }), async (context) => {
27
+ return routes().post("/api/installations/:installationId/workflows/webhooks", owner("direct-or-app"), async (context, { principal }) => {
28
28
  const installationId = context.req.param("installationId");
29
29
  if (!(await libraryExists(await hostFor(), installationId)))
30
30
  return refused();
@@ -34,6 +34,6 @@ export function standaloneWorkflowWebhookControls(env, hostFor) {
34
34
  const command = workflowWebhookCommandSchema.safeParse(body.success);
35
35
  if (!command.success)
36
36
  return refused();
37
- return env.WORKFLOW_RUNS.getByName(installationId).webhookControl(context.get("principal"), installationId, command.data);
38
- });
37
+ return env.WORKFLOW_RUNS.getByName(installationId).webhookControl(principal, installationId, command.data);
38
+ }, { middleware: [bodyLimit({ maxSize: 64 * 1024, onError: refused })] });
39
39
  }