@fungi.computer/oyster 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +376 -72
- package/dist/agent-avatars.d.ts +103 -0
- package/dist/agent-avatars.js +66 -0
- package/dist/agents.d.ts +15 -4
- package/dist/agents.js +43 -4
- package/dist/app-builds.d.ts +81 -8
- package/dist/app-builds.js +210 -60
- package/dist/app-storage.d.ts +3 -3
- package/dist/approval-capability.d.ts +5 -0
- package/dist/approval-capability.js +46 -0
- package/dist/approval-home.d.ts +51 -0
- package/dist/approval-home.js +226 -0
- package/dist/apps/catalog.d.ts +335 -0
- package/dist/apps/catalog.js +46 -0
- package/dist/apps/gate.d.ts +26 -12
- package/dist/apps/gate.js +48 -22
- package/dist/apps/index.d.ts +3 -1
- package/dist/apps/index.js +3 -1
- package/dist/apps/installation.d.ts +147 -66
- package/dist/apps/installation.js +193 -86
- package/dist/apps/permissions.d.ts +247 -0
- package/dist/apps/permissions.js +255 -0
- package/dist/boot-capability-route.d.ts +15 -0
- package/dist/boot-capability-route.js +196 -0
- package/dist/boot-capability.d.ts +103 -0
- package/dist/boot-capability.js +141 -0
- package/dist/boot-construction.d.ts +12 -0
- package/dist/boot-construction.js +175 -0
- package/dist/boot-gate.d.ts +267 -0
- package/dist/boot-gate.js +236 -0
- package/dist/boot-host-script.d.ts +2 -0
- package/dist/boot-host-script.js +1 -0
- package/dist/boot-mount.d.ts +21 -0
- package/dist/boot-mount.js +65 -0
- package/dist/browser/boot.d.ts +73 -0
- package/dist/browser/boot.js +502 -0
- package/dist/browser/browser.d.ts +104 -0
- package/dist/browser/browser.js +374 -0
- package/dist/browser/capability-source.d.ts +76 -0
- package/dist/browser/capability-source.js +338 -0
- package/dist/browser/cdp-client.d.ts +56 -0
- package/dist/browser/cdp-client.js +184 -0
- package/dist/browser/errors.d.ts +79 -0
- package/dist/browser/errors.js +32 -0
- package/dist/browser/index.d.ts +16 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/lease-registry.d.ts +61 -0
- package/dist/browser/lease-registry.js +101 -0
- package/dist/browser/operations.d.ts +225 -0
- package/dist/browser/operations.js +137 -0
- package/dist/browser/page.d.ts +25 -0
- package/dist/browser/page.js +172 -0
- package/dist/browser/quick-reads.d.ts +29 -0
- package/dist/browser/quick-reads.js +160 -0
- package/dist/browser/sessions.d.ts +52 -0
- package/dist/browser/sessions.js +118 -0
- package/dist/browser/url-policy.d.ts +18 -0
- package/dist/browser/url-policy.js +58 -0
- package/dist/build/app-imports.d.ts +12 -0
- package/dist/build/app-imports.js +105 -0
- package/dist/build/build-policy.d.ts +5 -3
- package/dist/build/build-policy.js +5 -3
- package/dist/build/candidate-builder.d.ts +1 -1
- package/dist/build/candidate-cli.mjs +8428 -337
- package/dist/build/local-build.d.ts +2 -0
- package/dist/build/local-build.js +28 -6
- package/dist/build/snapshot-package-store.d.ts +1 -1
- package/dist/build/snapshot-package-store.js +7 -2
- package/dist/build/workspace-build.d.ts +92 -5
- package/dist/build/workspace-build.js +93 -19
- package/dist/build-egress.js +4 -4
- package/dist/build.d.ts +1 -1
- package/dist/build.js +1 -1
- package/dist/catalog-frame.js +1 -1
- package/dist/cloudflare.d.ts +13 -3
- package/dist/cloudflare.js +106 -8
- package/dist/frame-binding-wire-script.js +1 -1
- package/dist/frame-binding-wire.d.ts +1 -1
- package/dist/frame-binding-wire.js +5 -3
- package/dist/git-auth.d.ts +0 -2
- package/dist/git-auth.js +0 -2
- package/dist/git-journal.js +4 -4
- package/dist/git.d.ts +0 -1
- package/dist/git.js +0 -2
- package/dist/host.d.ts +39 -13
- package/dist/host.js +268 -142
- package/dist/index.d.ts +26 -15
- package/dist/index.js +40 -16
- package/dist/install-release-cli.d.ts +2 -0
- package/dist/install-release-cli.js +46 -0
- package/dist/installation-client.d.ts +43 -0
- package/dist/installation-client.js +178 -0
- package/dist/installation-execution.d.ts +11 -0
- package/dist/installation-execution.js +184 -0
- package/dist/installation-operations.d.ts +1437 -0
- package/dist/installation-operations.js +664 -0
- package/dist/installation-store-generation.d.ts +3 -0
- package/dist/installation-store-generation.js +16 -0
- package/dist/instance-id.d.ts +10 -0
- package/dist/instance-id.js +10 -0
- package/dist/instance-refusal.d.ts +11 -0
- package/dist/instance-refusal.js +21 -0
- package/dist/internal/delivery.js +4 -2
- package/dist/internal/host-gate.js +7 -1
- package/dist/internal/registry-installations.js +4 -4
- package/dist/keys.d.ts +5 -1
- package/dist/keys.js +10 -2
- package/dist/machine-link/authority.d.ts +89 -0
- package/dist/machine-link/authority.js +37 -0
- package/dist/machine-link/client.d.ts +66 -0
- package/dist/machine-link/client.js +94 -0
- package/dist/machine-link/delivery.d.ts +18 -0
- package/dist/machine-link/delivery.js +55 -0
- package/dist/machine-link/enrollment.d.ts +111 -0
- package/dist/machine-link/enrollment.js +286 -0
- package/dist/machine-link/fences.d.ts +37 -0
- package/dist/machine-link/fences.js +166 -0
- package/dist/machine-link/home.d.ts +20 -0
- package/dist/machine-link/home.js +24 -0
- package/dist/machine-link/host.d.ts +43 -0
- package/dist/machine-link/host.js +189 -0
- package/dist/machine-link/index.d.ts +15 -0
- package/dist/machine-link/index.js +15 -0
- package/dist/machine-link/link.d.ts +48 -0
- package/dist/machine-link/link.js +223 -0
- package/dist/machine-link/presence.d.ts +10 -0
- package/dist/machine-link/presence.js +25 -0
- package/dist/machine-link/workers.d.ts +6 -0
- package/dist/machine-link/workers.js +6 -0
- package/dist/mcp-owner.d.ts +2 -2
- package/dist/mcp-owner.js +41 -33
- package/dist/mcp.d.ts +15 -3
- package/dist/mcp.js +146 -25
- package/dist/pack.d.ts +14 -3
- package/dist/pack.js +44 -19
- package/dist/page/app-access.d.ts +7 -0
- package/dist/page/app-access.js +75 -0
- package/dist/page/boot-host.js +57 -0
- package/dist/page/capabilities.d.ts +3 -3
- package/dist/page/capabilities.js +16 -12
- package/dist/page/computer-handles.d.ts +3 -3
- package/dist/page/computer-target.d.ts +3 -0
- package/dist/page/computer-target.js +9 -0
- package/dist/page/mount.d.ts +23 -7
- package/dist/page/mount.js +152 -16
- package/dist/page-assets.d.ts +22 -0
- package/dist/page-assets.js +28 -0
- package/dist/page-script.d.ts +3 -0
- package/dist/page-script.js +5 -4
- package/dist/release.d.ts +13 -6
- package/dist/release.js +10 -7
- package/dist/root-data.d.ts +16 -6
- package/dist/root-data.js +2 -2
- package/dist/source/index.d.ts +1 -1
- package/dist/source/team-source.d.ts +20 -8
- package/dist/source/team-source.js +39 -10
- package/dist/source/template-seed.d.ts +2 -2
- package/dist/standalone/agent-mail.d.ts +24 -0
- package/dist/standalone/agent-mail.js +62 -0
- package/dist/standalone/agent-store.d.ts +9 -0
- package/dist/standalone/agent-store.js +30 -0
- package/dist/standalone/agents.d.ts +78 -12
- package/dist/standalone/agents.js +470 -59
- package/dist/standalone/app-builds-binding.d.ts +20 -2
- package/dist/standalone/app-builds-binding.js +151 -27
- package/dist/standalone/app-set.d.ts +5 -2
- package/dist/standalone/app-set.js +174 -143
- package/dist/standalone/browser.d.ts +11 -0
- package/dist/standalone/browser.js +72 -0
- package/dist/standalone/builds.d.ts +13 -4
- package/dist/standalone/builds.js +28 -44
- package/dist/standalone/computer-egress.d.ts +2 -0
- package/dist/standalone/computer-egress.js +13 -4
- package/dist/standalone/computer-fleet.d.ts +43 -0
- package/dist/standalone/computer-fleet.js +200 -0
- package/dist/standalone/computer.d.ts +44 -9
- package/dist/standalone/computer.js +132 -25
- package/dist/standalone/install-apps-cli.js +43 -6
- package/dist/standalone/instance.d.ts +2 -2
- package/dist/standalone/instance.js +8 -11
- package/dist/standalone/machine-link.d.ts +354 -0
- package/dist/standalone/machine-link.js +368 -0
- package/dist/standalone/media.d.ts +2 -2
- package/dist/standalone/media.js +19 -16
- package/dist/standalone/preview.d.ts +2 -2
- package/dist/standalone/preview.js +39 -12
- package/dist/standalone/registry.d.ts +149 -9
- package/dist/standalone/registry.js +299 -8
- package/dist/standalone/worker.d.ts +19 -5
- package/dist/standalone/worker.js +90 -54
- package/dist/standalone/workflow-binding.d.ts +28 -32
- package/dist/standalone/workflow-binding.js +20 -20
- package/dist/standalone/workflow-control.d.ts +4 -0
- package/dist/standalone/workflow-control.js +40 -0
- package/dist/standalone/workflow-events.d.ts +2 -2
- package/dist/standalone/workflow-events.js +9 -10
- package/dist/standalone/workflow-git-capture.js +4 -3
- package/dist/standalone/workflow-host.d.ts +177 -152
- package/dist/standalone/workflow-host.js +137 -30
- package/dist/standalone/workflow-node-capture.js +11 -4
- package/dist/standalone/workflow-schedules.d.ts +5 -2
- package/dist/standalone/workflow-schedules.js +9 -10
- package/dist/standalone/workflow-trigger-host.d.ts +88 -6
- package/dist/standalone/workflow-trigger-host.js +2 -2
- package/dist/standalone/workflow-webhooks.d.ts +22 -0
- package/dist/standalone/workflow-webhooks.js +39 -0
- package/dist/standalone/workflows.d.ts +203 -50
- package/dist/standalone/workflows.js +198 -39
- package/dist/storage-frame.d.ts +6 -6
- package/dist/testing/capabilities.js +14 -3
- package/dist/testing/installation.js +26 -2
- package/dist/testing/worker.js +1 -1
- package/dist/testing/workers-runtime.d.ts +8 -2
- package/dist/testing/workers-runtime.js +20 -2
- package/dist/webhook-abuse.d.ts +25 -0
- package/dist/webhook-abuse.js +54 -0
- package/dist/webhook-custody.d.ts +144 -0
- package/dist/webhook-custody.js +222 -0
- package/dist/webhook-ingress.d.ts +36 -0
- package/dist/webhook-ingress.js +146 -0
- package/dist/webhooks.d.ts +111 -0
- package/dist/webhooks.js +189 -0
- package/dist/workers-git.d.ts +12 -17
- package/dist/workers-git.js +60 -55
- package/dist/workers.d.ts +224 -13
- package/dist/workers.js +351 -51
- package/dist/workflow-agent-authority.d.ts +8 -0
- package/dist/workflow-agent-authority.js +42 -0
- package/dist/workflows.d.ts +66 -0
- package/dist/workflows.js +97 -0
- package/docs/api/README.md +63 -37
- package/docs/api/agents.md +17 -0
- package/docs/api/app-storage.md +1 -1
- package/docs/api/apps.md +1394 -543
- package/docs/api/browser/boot.md +132 -0
- package/docs/api/browser.md +1440 -0
- package/docs/api/build-contract.md +38 -25
- package/docs/api/build.md +263 -84
- package/docs/api/cloudflare.md +93 -7
- package/docs/api/git.md +3 -13
- package/docs/api/host.md +944 -118
- package/docs/api/index.md +320 -18
- package/docs/api/keys.md +24 -1
- package/docs/api/mcp.md +59 -12
- package/docs/api/modules.md +33 -40
- package/docs/api/pack.md +57 -8
- package/docs/api/page/mount.md +92 -4
- package/docs/api/workers-git.md +103 -24
- package/docs/api/workers.md +1581 -244
- package/docs/site/agent-quickstart.mdx +28 -14
- package/examples/standalone/worker.ts +3 -1
- package/examples/standalone/wrangler.jsonc +2 -0
- package/package.json +73 -69
- package/dist/installation-consent.d.ts +0 -79
- package/dist/installation-consent.js +0 -82
- package/dist/shell/app-directory.d.ts +0 -542
- package/dist/shell/app-directory.js +0 -199
- package/dist/shell/browser-actions.d.ts +0 -7
- package/dist/shell/browser-actions.js +0 -56
- package/dist/shell/command-host.d.ts +0 -112
- package/dist/shell/command-host.js +0 -502
- package/dist/shell/commands.d.ts +0 -25
- package/dist/shell/commands.js +0 -78
- package/dist/shell/index.d.ts +0 -8
- package/dist/shell/index.js +0 -8
- package/dist/shell/keys.d.ts +0 -41
- package/dist/shell/keys.js +0 -134
- package/dist/shell/shell-module.d.ts +0 -55
- package/dist/shell/shell-module.js +0 -86
- package/dist/shell/window-manager.d.ts +0 -124
- package/dist/shell/window-manager.js +0 -711
- package/dist/shell/workbench-contract.d.ts +0 -68
- package/dist/shell/workbench-directory.d.ts +0 -332
- package/dist/shell/workbench-directory.js +0 -35
- package/dist/shell/workbench-host-types.d.ts +0 -96
- package/dist/shell/workbench-host-types.js +0 -1
- package/dist/shell/workbench-host.d.ts +0 -34
- package/dist/shell/workbench-host.js +0 -347
- package/dist/shell/workbench-model.d.ts +0 -192
- package/dist/shell/workbench-model.js +0 -53
- package/dist/shell/workbench.d.ts +0 -4
- package/dist/shell/workbench.js +0 -2
- package/docs/api/shell/app-directory.md +0 -599
- package/docs/api/shell/command-host.md +0 -224
- package/docs/api/shell/commands.md +0 -197
- package/docs/api/shell/keys.md +0 -183
- package/docs/api/shell/shell-module.md +0 -204
- package/docs/api/shell/window-manager.md +0 -267
- package/docs/api/shell/workbench-directory.md +0 -119
- package/docs/api/shell/workbench.md +0 -205
- package/docs/api/shell.md +0 -1915
- /package/dist/{shell/workbench-contract.js → page/boot-host.d.ts} +0 -0
|
@@ -1,15 +1,19 @@
|
|
|
1
|
+
import type { Release } from "@fungi.computer/puffball";
|
|
1
2
|
import { OysterRegistry, type OysterWorkerEnv } from "../workers.js";
|
|
2
|
-
import type
|
|
3
|
+
import { type OysterHost } from "../host.js";
|
|
4
|
+
import { type TenantScope, type TenantId } from "../tenant.js";
|
|
3
5
|
import { type OysterGitEnv } from "../workers-git.js";
|
|
4
6
|
import { type AppSourceForkResult, type TemplateSeedClaim } from "../source/index.js";
|
|
5
7
|
import { type CloudflareArtifactsOptions } from "@fungi.computer/burrow/cloudflare";
|
|
6
|
-
import { type
|
|
8
|
+
import { type OysterBuildStartResult, type OysterBuildView } from "../app-builds.js";
|
|
7
9
|
import type { TeamAppCandidateManifest } from "../build-contract.js";
|
|
8
10
|
import type { BuildGitEvent } from "../build-egress.js";
|
|
9
11
|
import { type StandaloneTenancyEnv } from "./tenancy.js";
|
|
10
12
|
import type { ComputerDO } from "./computer.js";
|
|
13
|
+
import type { ComputerEnv } from "@fungi.computer/computer";
|
|
14
|
+
import { type StandaloneFleetRequest } from "./computer-fleet.js";
|
|
11
15
|
/** What the registry needs to build Apps on the standalone's one Computer. */
|
|
12
|
-
export type StandaloneRegistryEnv = OysterWorkerEnv & StandaloneTenancyEnv & OysterGitEnv & Readonly<{
|
|
16
|
+
export type StandaloneRegistryEnv = OysterWorkerEnv & Pick<ComputerEnv, "COMPUTER_VM_DEFAULT_HOST"> & StandaloneTenancyEnv & OysterGitEnv & Readonly<{
|
|
13
17
|
OYSTER_COMPUTER_ID: string;
|
|
14
18
|
COMPUTER: DurableObjectNamespace<ComputerDO>;
|
|
15
19
|
}>;
|
|
@@ -23,9 +27,75 @@ export type BuildTarget = Readonly<{
|
|
|
23
27
|
* composition may supply; absent, Git goes to the provider's own remotes. */
|
|
24
28
|
export type StandaloneRegistryGit = Pick<CloudflareArtifactsOptions, "gitFetch" | "gitHttp">;
|
|
25
29
|
/** The existing REGISTRY class identity with standalone host-owned admission. */
|
|
26
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Operations other Worker contexts call through the REGISTRY Durable Object
|
|
32
|
+
* namespace: the APPS binding (app-builds-binding.ts) and the fleet routes
|
|
33
|
+
* (computer-fleet.ts). Each is an RPC entrypoint, not an in-process helper.
|
|
34
|
+
*/
|
|
35
|
+
export type StandaloneRegistryRpc = {
|
|
36
|
+
computerFleet(memberId: string, request: StandaloneFleetRequest): ReturnType<StandaloneRegistry["computerFleet"]>;
|
|
37
|
+
registerRepositoryApp(input: Parameters<StandaloneRegistry["registerRepositoryApp"]>[0]): ReturnType<StandaloneRegistry["registerRepositoryApp"]>;
|
|
38
|
+
repositoryBuildSource(installationId: string, repository: string): ReturnType<StandaloneRegistry["repositoryBuildSource"]>;
|
|
39
|
+
readRepositoryBuild(installationId: string, repository: string): ReturnType<StandaloneRegistry["readRepositoryBuild"]>;
|
|
40
|
+
installWorkflowBuild(jobId: string, target: string, release: Release, memberId: string, callerInstallationId: string): ReturnType<StandaloneRegistry["installWorkflowBuild"]>;
|
|
41
|
+
};
|
|
42
|
+
export declare abstract class StandaloneRegistry extends OysterRegistry implements StandaloneRegistryRpc {
|
|
27
43
|
#private;
|
|
44
|
+
protected abstract hostFor(scope: TenantScope): Promise<OysterHost>;
|
|
28
45
|
constructor(state: DurableObjectState, env: StandaloneRegistryEnv, git?: StandaloneRegistryGit);
|
|
46
|
+
/** Re-admit the live owner before inventory access or a hosted start. */
|
|
47
|
+
computerFleet(memberId: string, request: StandaloneFleetRequest): Promise<Readonly<{
|
|
48
|
+
computerId: string;
|
|
49
|
+
name: string;
|
|
50
|
+
createdAt: number;
|
|
51
|
+
updatedAt: number;
|
|
52
|
+
}> | {
|
|
53
|
+
readonly computers: Readonly<{
|
|
54
|
+
computerId: string;
|
|
55
|
+
name: string;
|
|
56
|
+
createdAt: number;
|
|
57
|
+
updatedAt: number;
|
|
58
|
+
}>[];
|
|
59
|
+
readonly nextOffset: number | null;
|
|
60
|
+
} | ({
|
|
61
|
+
state: "running";
|
|
62
|
+
} & Disposable) | {
|
|
63
|
+
error: string;
|
|
64
|
+
computers?: undefined;
|
|
65
|
+
nextOffset?: undefined;
|
|
66
|
+
computerId?: undefined;
|
|
67
|
+
enabled?: undefined;
|
|
68
|
+
} | {
|
|
69
|
+
computers: ({
|
|
70
|
+
computerId: string;
|
|
71
|
+
name: string;
|
|
72
|
+
} | Readonly<{
|
|
73
|
+
computerId: string;
|
|
74
|
+
name: string;
|
|
75
|
+
createdAt: number;
|
|
76
|
+
updatedAt: number;
|
|
77
|
+
}>)[];
|
|
78
|
+
nextOffset: number | null;
|
|
79
|
+
error?: undefined;
|
|
80
|
+
computerId?: undefined;
|
|
81
|
+
enabled?: undefined;
|
|
82
|
+
} | {
|
|
83
|
+
computerId: string;
|
|
84
|
+
error?: undefined;
|
|
85
|
+
computers?: undefined;
|
|
86
|
+
nextOffset?: undefined;
|
|
87
|
+
enabled?: undefined;
|
|
88
|
+
} | {
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
error?: undefined;
|
|
91
|
+
computers?: undefined;
|
|
92
|
+
nextOffset?: undefined;
|
|
93
|
+
computerId?: undefined;
|
|
94
|
+
} | null>;
|
|
95
|
+
/** A durable selection snapshot; the configured default remains the App build Computer. */
|
|
96
|
+
selectedComputer(): Promise<string>;
|
|
97
|
+
/** Frame dispatch checks inventory ownership, not a mutable UI selection. */
|
|
98
|
+
ownsComputer(computerId: string): boolean;
|
|
29
99
|
/** One atomic registry admission proves the stored creator is still the owner. */
|
|
30
100
|
protected currentOwner(memberId: string, tenantId: TenantId): Promise<string | null>;
|
|
31
101
|
/** Operator-only: one smart-HTTP exchange with an App's template
|
|
@@ -39,7 +109,7 @@ export declare class StandaloneRegistry extends OysterRegistry {
|
|
|
39
109
|
* published seed revision builds on the Computer. */
|
|
40
110
|
publishSource(rawAppId: string, claim: TemplateSeedClaim, teamId: string): Promise<{
|
|
41
111
|
readonly kind: "conflict";
|
|
42
|
-
|
|
112
|
+
receipt?: undefined;
|
|
43
113
|
} | {
|
|
44
114
|
readonly kind: "recorded" | "existing";
|
|
45
115
|
readonly receipt: {
|
|
@@ -52,7 +122,7 @@ export declare class StandaloneRegistry extends OysterRegistry {
|
|
|
52
122
|
};
|
|
53
123
|
} | {
|
|
54
124
|
readonly kind: "unavailable";
|
|
55
|
-
|
|
125
|
+
receipt?: undefined;
|
|
56
126
|
}>;
|
|
57
127
|
/** Fork a published platform App's source into its own Team-owned App,
|
|
58
128
|
* as repository `name` of the calling installation's Git (so its owner
|
|
@@ -68,15 +138,85 @@ export declare class StandaloneRegistry extends OysterRegistry {
|
|
|
68
138
|
repositoryPrefix: string;
|
|
69
139
|
name: string;
|
|
70
140
|
}>): Promise<AppSourceForkResult>;
|
|
71
|
-
/**
|
|
72
|
-
|
|
141
|
+
/** Register the committed root App, never the installation's mutable Files projection. */
|
|
142
|
+
registerRepositoryApp(input: Readonly<{
|
|
143
|
+
memberId: string;
|
|
144
|
+
installationId: string;
|
|
145
|
+
repository: string;
|
|
146
|
+
}>): Promise<Readonly<{
|
|
147
|
+
kind: "registered";
|
|
148
|
+
appId: string;
|
|
149
|
+
sourceRevision: string;
|
|
150
|
+
}> | Readonly<{
|
|
151
|
+
kind: "unauthorized" | "invalid_app" | "conflict";
|
|
152
|
+
}>>;
|
|
73
153
|
/** Owner: start one build of an App's source at one commit; it runs on. */
|
|
74
154
|
startBuild(input: {
|
|
75
155
|
appId: string;
|
|
76
156
|
sourceRevision: string;
|
|
77
157
|
requestedBy: string;
|
|
78
|
-
|
|
158
|
+
workflow?: {
|
|
159
|
+
requestId: string;
|
|
160
|
+
/** The installation whose admitted Workflow node asks; it must own the source. */
|
|
161
|
+
callerInstallationId: string;
|
|
162
|
+
installationId?: string;
|
|
163
|
+
};
|
|
164
|
+
}): Promise<OysterBuildStartResult>;
|
|
165
|
+
/** The calling installation's existing source record, never a registration. */
|
|
166
|
+
repositoryBuildSource(installationId: string, repository: string): Promise<{
|
|
167
|
+
appId: import("@fungi.computer/puffball").AppId;
|
|
168
|
+
} | null>;
|
|
79
169
|
readBuild(jobId: string): Promise<OysterBuildView | null>;
|
|
170
|
+
/** Repository status belongs to the same captured Git owner as registration. */
|
|
171
|
+
readRepositoryBuild(installationId: string, repository: string): Promise<Readonly<{
|
|
172
|
+
jobId: string;
|
|
173
|
+
appId: string;
|
|
174
|
+
releaseId: string;
|
|
175
|
+
sourceRevision: string;
|
|
176
|
+
status: "running" | "succeeded" | "failed" | "revoked";
|
|
177
|
+
detail: string | null;
|
|
178
|
+
release: Release | null;
|
|
179
|
+
installation: import("../app-builds.js").OysterBuildInstallation | null;
|
|
180
|
+
}> | null>;
|
|
181
|
+
/** Only the APPS dispatcher of an admitted Workflow node calls this operation.
|
|
182
|
+
* Reads and alarms never choose a Release. The build row owns the decision. */
|
|
183
|
+
installWorkflowBuild(jobId: string, target: string, release: Release, memberId: string, callerInstallationId: string): Promise<{
|
|
184
|
+
status: number;
|
|
185
|
+
body: {
|
|
186
|
+
error: string;
|
|
187
|
+
installationId?: undefined;
|
|
188
|
+
status?: undefined;
|
|
189
|
+
code?: undefined;
|
|
190
|
+
pending?: undefined;
|
|
191
|
+
};
|
|
192
|
+
} | {
|
|
193
|
+
status: number;
|
|
194
|
+
body: {
|
|
195
|
+
installationId: string;
|
|
196
|
+
status: string;
|
|
197
|
+
error?: undefined;
|
|
198
|
+
code?: undefined;
|
|
199
|
+
pending?: undefined;
|
|
200
|
+
};
|
|
201
|
+
} | {
|
|
202
|
+
status: number;
|
|
203
|
+
body: {
|
|
204
|
+
code: string;
|
|
205
|
+
error: string;
|
|
206
|
+
installationId?: undefined;
|
|
207
|
+
status?: undefined;
|
|
208
|
+
pending?: undefined;
|
|
209
|
+
};
|
|
210
|
+
} | {
|
|
211
|
+
status: number;
|
|
212
|
+
body: {
|
|
213
|
+
pending: boolean;
|
|
214
|
+
error?: undefined;
|
|
215
|
+
installationId?: undefined;
|
|
216
|
+
status?: undefined;
|
|
217
|
+
code?: undefined;
|
|
218
|
+
};
|
|
219
|
+
}>;
|
|
80
220
|
/** The Computer re-admits each build execution here. */
|
|
81
221
|
admitBuildExecution(jobId: string, computerObjectId: string): Promise<boolean>;
|
|
82
222
|
/** The egress: which live job a build report from this Computer speaks for. */
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { canonicalJson } from "@fungi.computer/braid";
|
|
1
2
|
import { OysterRegistry, r2ArtifactStore, } from "../workers.js";
|
|
3
|
+
import { installOrSelect } from "../host.js";
|
|
4
|
+
import { installationOperationsPort } from "../installation-operations.js";
|
|
5
|
+
import { tenantScope } from "../tenant.js";
|
|
2
6
|
import { artifactsOf } from "../workers-git.js";
|
|
3
7
|
import { forkAppSource, recordTemplateSeed, templateRepositoryForApp, } from "../source/index.js";
|
|
4
8
|
import { exchangeOysterTemplateGit, exchangeOysterTemplateSource, } from "../app-sources.js";
|
|
@@ -7,22 +11,143 @@ import { defineIdFamily } from "@fungi.computer/cairn/id";
|
|
|
7
11
|
import * as Schema from "effect/Schema";
|
|
8
12
|
import { parseAppId } from "@fungi.computer/puffball";
|
|
9
13
|
import { appIdSchema } from "@fungi.computer/puffball/effect";
|
|
10
|
-
import { createOysterAppBuilds, } from "../app-builds.js";
|
|
14
|
+
import { createOysterAppBuilds, OysterBuildStartError, } from "../app-builds.js";
|
|
15
|
+
import { readBuildManifest, appBuildRecipe } from "../build/workspace-build.js";
|
|
11
16
|
import { standaloneTenancy } from "./tenancy.js";
|
|
17
|
+
import { createFleetComputers, ComputerInventoryError, } from "@fungi.computer/computer/fleet";
|
|
18
|
+
import { standaloneFleetRequestSchema, } from "./computer-fleet.js";
|
|
12
19
|
const standaloneAppForkIds = defineIdFamily({
|
|
13
20
|
family: "oyster-app-fork",
|
|
14
21
|
version: 1,
|
|
15
22
|
kinds: { app: { prefix: "app" } },
|
|
16
23
|
});
|
|
17
|
-
/**
|
|
24
|
+
/** Whether a registered source lives in this installation's own repository. */
|
|
25
|
+
function sourceOwnedBy(source, installationId) {
|
|
26
|
+
return (source?.location.kind === "installation" &&
|
|
27
|
+
source.location.installationId === installationId);
|
|
28
|
+
}
|
|
18
29
|
export class StandaloneRegistry extends OysterRegistry {
|
|
19
30
|
#env;
|
|
20
31
|
#git;
|
|
21
32
|
#builds;
|
|
33
|
+
#computers;
|
|
34
|
+
#fleetStorage;
|
|
22
35
|
constructor(state, env, git = {}) {
|
|
23
36
|
super(state, env);
|
|
24
37
|
this.#env = env;
|
|
25
38
|
this.#git = git;
|
|
39
|
+
this.#fleetStorage = state.storage;
|
|
40
|
+
// Native hosts own infrastructure capacity. Standalone has no Team quota.
|
|
41
|
+
this.#computers = createFleetComputers(state.storage, {
|
|
42
|
+
limit: Number.MAX_SAFE_INTEGER,
|
|
43
|
+
retryAfterSeconds: 30,
|
|
44
|
+
});
|
|
45
|
+
this.#computers.ensure();
|
|
46
|
+
}
|
|
47
|
+
/** Re-admit the live owner before inventory access or a hosted start. */
|
|
48
|
+
async computerFleet(memberId, request) {
|
|
49
|
+
const shared = await standaloneTenancy(this.#env);
|
|
50
|
+
if ((await shared.owner())?.actor.memberId !== memberId)
|
|
51
|
+
return { error: "owner_required" };
|
|
52
|
+
const input = standaloneFleetRequestSchema.parse(request);
|
|
53
|
+
switch (input.operation) {
|
|
54
|
+
case "create": {
|
|
55
|
+
const hostId = this.#env.COMPUTER_VM_DEFAULT_HOST;
|
|
56
|
+
let created;
|
|
57
|
+
try {
|
|
58
|
+
created = this.#computers.create({ kind: "owner", id: memberId }, input.request, [
|
|
59
|
+
hostId === undefined
|
|
60
|
+
? { kind: "platform-container" }
|
|
61
|
+
: { kind: "on-box-vm", hostId },
|
|
62
|
+
]).computer;
|
|
63
|
+
}
|
|
64
|
+
catch (cause) {
|
|
65
|
+
if (cause instanceof ComputerInventoryError)
|
|
66
|
+
return { error: cause.code };
|
|
67
|
+
throw cause;
|
|
68
|
+
}
|
|
69
|
+
const backings = this.#computers.readBacking(created.computerId);
|
|
70
|
+
if (backings === null)
|
|
71
|
+
throw new Error("Computer backing is missing");
|
|
72
|
+
await this.#env.COMPUTER.getByName(created.computerId).initializeFleetBackings(backings);
|
|
73
|
+
return created;
|
|
74
|
+
}
|
|
75
|
+
case "list":
|
|
76
|
+
return this.#computers.list(input.page);
|
|
77
|
+
case "choices": {
|
|
78
|
+
// The configured build Computer is an existing supported workspace,
|
|
79
|
+
// not a fabricated fleet creation receipt. Keep its UI row outside inventory.
|
|
80
|
+
const { limit, offset } = input.page;
|
|
81
|
+
const first = offset === 0;
|
|
82
|
+
const configured = {
|
|
83
|
+
computerId: this.#env.OYSTER_COMPUTER_ID,
|
|
84
|
+
name: this.#env.OYSTER_COMPUTER_ID,
|
|
85
|
+
};
|
|
86
|
+
if (first && limit === 1)
|
|
87
|
+
return {
|
|
88
|
+
computers: [configured],
|
|
89
|
+
nextOffset: this.#computers.count() > 0 ? 1 : null,
|
|
90
|
+
};
|
|
91
|
+
const page = this.#computers.list({
|
|
92
|
+
limit: limit - (first ? 1 : 0),
|
|
93
|
+
offset: Math.max(0, offset - 1),
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
computers: first ? [configured, ...page.computers] : page.computers,
|
|
97
|
+
nextOffset: page.nextOffset === null ? null : page.nextOffset + 1,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
case "read":
|
|
101
|
+
return this.#computers.read(input.computerId);
|
|
102
|
+
case "resolve":
|
|
103
|
+
// Context may name the configured build Computer, which has no fleet
|
|
104
|
+
// creation receipt. Keep canonical-owner admission above this lookup.
|
|
105
|
+
return this.ownsComputer(input.computerId)
|
|
106
|
+
? { computerId: input.computerId }
|
|
107
|
+
: null;
|
|
108
|
+
case "read-internet-access":
|
|
109
|
+
case "set-internet-access": {
|
|
110
|
+
if (this.#computers.read(input.computerId) === null)
|
|
111
|
+
return null;
|
|
112
|
+
const computer = this.#env.COMPUTER.getByName(input.computerId);
|
|
113
|
+
return {
|
|
114
|
+
enabled: await computer.internetAccess(input.operation === "set-internet-access"
|
|
115
|
+
? input.enabled
|
|
116
|
+
: undefined),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
case "select": {
|
|
120
|
+
const computer = this.#computers.read(input.computerId);
|
|
121
|
+
if (computer === null)
|
|
122
|
+
return null;
|
|
123
|
+
await this.#fleetStorage.put("selected-computer", input.computerId);
|
|
124
|
+
return computer;
|
|
125
|
+
}
|
|
126
|
+
case "start":
|
|
127
|
+
if (this.#computers.read(input.computerId) === null)
|
|
128
|
+
return null;
|
|
129
|
+
return this.#env.COMPUTER.getByName(input.computerId).startHostedComputer({
|
|
130
|
+
computerId: input.computerId,
|
|
131
|
+
actions: new Set(["start"]),
|
|
132
|
+
expiresAt: Date.now() + 60_000,
|
|
133
|
+
provenance: { actor: memberId },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** A durable selection snapshot; the configured default remains the App build Computer. */
|
|
138
|
+
async selectedComputer() {
|
|
139
|
+
const selected = await this.#fleetStorage.get("selected-computer");
|
|
140
|
+
if (selected === undefined)
|
|
141
|
+
return this.#env.OYSTER_COMPUTER_ID;
|
|
142
|
+
const computerId = Schema.decodeUnknownSync(Schema.NonEmptyString)(selected);
|
|
143
|
+
if (this.#computers.read(computerId) === null)
|
|
144
|
+
throw new Error("Selected Computer is missing");
|
|
145
|
+
return computerId;
|
|
146
|
+
}
|
|
147
|
+
/** Frame dispatch checks inventory ownership, not a mutable UI selection. */
|
|
148
|
+
ownsComputer(computerId) {
|
|
149
|
+
return (computerId === this.#env.OYSTER_COMPUTER_ID ||
|
|
150
|
+
this.#computers.read(computerId) !== null);
|
|
26
151
|
}
|
|
27
152
|
/** One atomic registry admission proves the stored creator is still the owner. */
|
|
28
153
|
async currentOwner(memberId, tenantId) {
|
|
@@ -134,6 +259,7 @@ export class StandaloneRegistry extends OysterRegistry {
|
|
|
134
259
|
name,
|
|
135
260
|
objectId: env.COMPUTER.idFromName(name).toString(),
|
|
136
261
|
port: {
|
|
262
|
+
buildBackend: () => env.COMPUTER.getByName(name).buildBackend(),
|
|
137
263
|
runBuild: (input) => env.COMPUTER.getByName(name).runBuild(input),
|
|
138
264
|
},
|
|
139
265
|
},
|
|
@@ -143,19 +269,184 @@ export class StandaloneRegistry extends OysterRegistry {
|
|
|
143
269
|
});
|
|
144
270
|
return this.#builds;
|
|
145
271
|
}
|
|
146
|
-
/**
|
|
147
|
-
async
|
|
148
|
-
|
|
272
|
+
/** Register the committed root App, never the installation's mutable Files projection. */
|
|
273
|
+
async registerRepositoryApp(input) {
|
|
274
|
+
const shared = await standaloneTenancy(this.#env);
|
|
275
|
+
if ((await shared.owner())?.actor.memberId !== input.memberId)
|
|
276
|
+
return { kind: "unauthorized" };
|
|
277
|
+
const scope = tenantScope(shared.tenantId, this.#env.OYSTER_ORIGIN);
|
|
278
|
+
const repository = await artifactsOf(this.#env).get(scope.repositoryPrefix(input.installationId) + input.repository);
|
|
279
|
+
const [head] = await repository.log({ ref: "main", limit: 1, offset: 0 });
|
|
280
|
+
if (head === undefined)
|
|
281
|
+
return { kind: "invalid_app" };
|
|
282
|
+
const tree = await repository.readTree(head.treeHash);
|
|
283
|
+
const entry = tree?.find((item) => item.name === "package.json" && item.type === "blob");
|
|
284
|
+
if (entry === undefined)
|
|
285
|
+
return { kind: "invalid_app" };
|
|
286
|
+
const blob = await repository.readBlob(entry.hash);
|
|
287
|
+
// Package metadata is a bounded input; this is not an App build-output budget.
|
|
288
|
+
if (blob === null || blob.size > 1_048_576)
|
|
289
|
+
return { kind: "invalid_app" };
|
|
290
|
+
const packageJson = await blob.text();
|
|
291
|
+
let app;
|
|
292
|
+
try {
|
|
293
|
+
const manifest = readBuildManifest(packageJson);
|
|
294
|
+
if (manifest.fungi.appId === undefined ||
|
|
295
|
+
manifest.fungi.build === undefined)
|
|
296
|
+
return { kind: "invalid_app" };
|
|
297
|
+
app = {
|
|
298
|
+
appId: manifest.fungi.appId,
|
|
299
|
+
recipe: appBuildRecipe(manifest, ""),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
catch (cause) {
|
|
303
|
+
if (Schema.isSchemaError(cause))
|
|
304
|
+
return { kind: "invalid_app" };
|
|
305
|
+
throw cause;
|
|
306
|
+
}
|
|
307
|
+
const registered = (await this.#appBuilds()).registerRepositorySource({
|
|
308
|
+
appId: app.appId,
|
|
309
|
+
location: {
|
|
310
|
+
kind: "installation",
|
|
311
|
+
installationId: input.installationId,
|
|
312
|
+
repository: input.repository,
|
|
313
|
+
},
|
|
314
|
+
recipe: app.recipe,
|
|
315
|
+
});
|
|
316
|
+
if (registered.kind === "conflict")
|
|
317
|
+
return registered;
|
|
318
|
+
return {
|
|
319
|
+
kind: "registered",
|
|
320
|
+
appId: registered.source.appId,
|
|
321
|
+
sourceRevision: "git:" + head.hash,
|
|
322
|
+
};
|
|
149
323
|
}
|
|
150
324
|
/** Owner: start one build of an App's source at one commit; it runs on. */
|
|
151
325
|
async startBuild(input) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
326
|
+
try {
|
|
327
|
+
const builds = await this.#appBuilds();
|
|
328
|
+
const request = {
|
|
329
|
+
appId: input.appId,
|
|
330
|
+
sourceRevision: input.sourceRevision,
|
|
331
|
+
requestedBy: input.requestedBy,
|
|
332
|
+
};
|
|
333
|
+
if (input.workflow !== undefined) {
|
|
334
|
+
// A Workflow builds only its own installation's registered App. A
|
|
335
|
+
// foreign App reads as unregistered, never as another's existence.
|
|
336
|
+
if (!sourceOwnedBy(builds.readSource(input.appId), input.workflow.callerInstallationId))
|
|
337
|
+
return { kind: "refused", reason: "no_source" };
|
|
338
|
+
request.requestId = input.workflow.requestId;
|
|
339
|
+
if (input.workflow.installationId !== undefined)
|
|
340
|
+
request.installAt = input.workflow.installationId;
|
|
341
|
+
}
|
|
342
|
+
const { build, run } = await builds.start(request);
|
|
343
|
+
this.ctx.waitUntil(run());
|
|
344
|
+
return { kind: "started", build };
|
|
345
|
+
}
|
|
346
|
+
catch (cause) {
|
|
347
|
+
if (cause instanceof OysterBuildStartError)
|
|
348
|
+
return { kind: "refused", reason: cause.reason };
|
|
349
|
+
throw cause;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/** The calling installation's existing source record, never a registration. */
|
|
353
|
+
async repositoryBuildSource(installationId, repository) {
|
|
354
|
+
const source = (await this.#appBuilds()).readRepositorySource(installationId, repository);
|
|
355
|
+
return source === null ? null : { appId: source.appId };
|
|
155
356
|
}
|
|
156
357
|
async readBuild(jobId) {
|
|
157
358
|
return (await this.#appBuilds()).read(jobId);
|
|
158
359
|
}
|
|
360
|
+
/** Repository status belongs to the same captured Git owner as registration. */
|
|
361
|
+
async readRepositoryBuild(installationId, repository) {
|
|
362
|
+
const latest = (await this.#appBuilds()).latestRepositoryBuild(installationId, repository);
|
|
363
|
+
return latest === null ? null : this.readBuild(latest.jobId);
|
|
364
|
+
}
|
|
365
|
+
/** Only the APPS dispatcher of an admitted Workflow node calls this operation.
|
|
366
|
+
* Reads and alarms never choose a Release. The build row owns the decision. */
|
|
367
|
+
async installWorkflowBuild(jobId, target, release, memberId, callerInstallationId) {
|
|
368
|
+
const builds = await this.#appBuilds();
|
|
369
|
+
const build = builds.read(jobId);
|
|
370
|
+
if (build === null ||
|
|
371
|
+
!sourceOwnedBy(builds.readSource(build.appId), callerInstallationId) ||
|
|
372
|
+
build.installation?.installationId !== target ||
|
|
373
|
+
build.release === null ||
|
|
374
|
+
canonicalJson(Schema.decodeUnknownSync(Schema.Json)(build.release)) !==
|
|
375
|
+
canonicalJson(Schema.decodeUnknownSync(Schema.Json)(release)))
|
|
376
|
+
return {
|
|
377
|
+
status: 409,
|
|
378
|
+
body: { error: "Release does not match this build and installation" },
|
|
379
|
+
};
|
|
380
|
+
const shared = await standaloneTenancy(this.#env);
|
|
381
|
+
if ((await shared.owner())?.actor.memberId !== memberId)
|
|
382
|
+
return { status: 403, body: { error: "Workflow authority revoked" } };
|
|
383
|
+
await builds.install(jobId, async (release, installationId) => {
|
|
384
|
+
const owner = await shared.owner();
|
|
385
|
+
if (owner?.actor.memberId !== memberId)
|
|
386
|
+
return {
|
|
387
|
+
kind: "failed",
|
|
388
|
+
installationId,
|
|
389
|
+
detail: "App owner unavailable",
|
|
390
|
+
};
|
|
391
|
+
const scope = tenantScope(shared.tenantId, this.#env.OYSTER_ORIGIN);
|
|
392
|
+
const root = await this.hostFor(scope);
|
|
393
|
+
// Use the in-process owner port; do not RPC this registry back into itself.
|
|
394
|
+
const host = {
|
|
395
|
+
...root,
|
|
396
|
+
installations: {
|
|
397
|
+
...root.installations,
|
|
398
|
+
get: (id) => Promise.resolve(this.get(id)),
|
|
399
|
+
generation: () => Promise.resolve(this.generation()),
|
|
400
|
+
// Only the owner's journal commits; nothing here writes around it.
|
|
401
|
+
compareAndPut: () => Promise.reject(new Error("Workflow installation commits only through its owner")),
|
|
402
|
+
operations: installationOperationsPort((request) => this.installationOperation(request), { tenantId: scope.tenantId, origin: scope.origin }),
|
|
403
|
+
},
|
|
404
|
+
};
|
|
405
|
+
const principal = await host.auth.resolve(owner.actor);
|
|
406
|
+
if (principal === null)
|
|
407
|
+
return {
|
|
408
|
+
kind: "failed",
|
|
409
|
+
installationId,
|
|
410
|
+
detail: "App owner unavailable",
|
|
411
|
+
};
|
|
412
|
+
const response = await installOrSelect(host, installationId, release, principal, "install-or-select", "workflow",
|
|
413
|
+
// One retained owner command per build: a retry observes it.
|
|
414
|
+
"workflow-build:" + jobId);
|
|
415
|
+
if (response.ok)
|
|
416
|
+
return { kind: "installed", installationId };
|
|
417
|
+
const body = await response.json();
|
|
418
|
+
if (Schema.is(Schema.Struct({ error: Schema.Literal("needs_consent") }))(body))
|
|
419
|
+
return { kind: "needs_consent", installationId };
|
|
420
|
+
return {
|
|
421
|
+
kind: "failed",
|
|
422
|
+
installationId,
|
|
423
|
+
detail: "Automatic installation refused (HTTP " +
|
|
424
|
+
String(response.status) +
|
|
425
|
+
")",
|
|
426
|
+
};
|
|
427
|
+
});
|
|
428
|
+
const outcome = builds.read(jobId)?.installation;
|
|
429
|
+
switch (outcome?.kind) {
|
|
430
|
+
case "installed":
|
|
431
|
+
return {
|
|
432
|
+
status: 200,
|
|
433
|
+
body: { installationId: target, status: "enabled" },
|
|
434
|
+
};
|
|
435
|
+
case "needs_consent":
|
|
436
|
+
return {
|
|
437
|
+
status: 409,
|
|
438
|
+
body: {
|
|
439
|
+
code: "needs_consent",
|
|
440
|
+
error: "New Release needs owner consent",
|
|
441
|
+
},
|
|
442
|
+
};
|
|
443
|
+
case "failed":
|
|
444
|
+
return { status: 503, body: { error: outcome.detail } };
|
|
445
|
+
default:
|
|
446
|
+
// Another installer holds this owner: the Workflow waits and retries.
|
|
447
|
+
return { status: 202, body: { pending: true } };
|
|
448
|
+
}
|
|
449
|
+
}
|
|
159
450
|
/** The Computer re-admits each build execution here. */
|
|
160
451
|
async admitBuildExecution(jobId, computerObjectId) {
|
|
161
452
|
return (await this.#appBuilds()).admitExecution(jobId, computerObjectId);
|
|
@@ -14,19 +14,27 @@ export { OysterBinding } from "./instance.js";
|
|
|
14
14
|
import { StandaloneWorkflowRunsBase, type StandaloneWorkflowEnv } from "./workflows.js";
|
|
15
15
|
import { type StandaloneTenancyEnv } from "./tenancy.js";
|
|
16
16
|
export { StandaloneTenants } from "./tenancy.js";
|
|
17
|
+
import { type StandaloneMachineLinkBindings } from "./machine-link.js";
|
|
18
|
+
export { MachineLinkDO } from "./machine-link.js";
|
|
17
19
|
import { type OysterComputerEgressProps } from "./computer-egress.js";
|
|
18
20
|
import { type AppSourceBindingEnv } from "./app-source.js";
|
|
19
21
|
export { StandaloneGraphWorkflow } from "./workflows.js";
|
|
20
22
|
export { MediaOperationDO } from "@fungi.computer/darkroom/cloudflare";
|
|
21
23
|
/** Every binding the standalone Bonsai root receives. */
|
|
22
|
-
export type StandaloneEnv = OysterGitWorkerEnv & StandaloneTenancyEnv & StandaloneComputerEnv & StandaloneAgentsEnv & OysterMediaEnv & StandaloneWorkflowEnv & AppSourceBindingEnv & {
|
|
24
|
+
export type StandaloneEnv = OysterGitWorkerEnv & StandaloneTenancyEnv & StandaloneComputerEnv & StandaloneAgentsEnv & StandaloneMachineLinkBindings & OysterMediaEnv & StandaloneWorkflowEnv & AppSourceBindingEnv & {
|
|
23
25
|
OYSTER_HOME_INSTALLATION: string;
|
|
24
26
|
/** `disabled` closes the Computer's public download lane. */
|
|
25
27
|
COMPUTER_PUBLIC_EGRESS?: string;
|
|
26
28
|
};
|
|
27
29
|
export { ComputerDO } from "./computer.js";
|
|
28
30
|
export { WorkspaceProxy, WorkspaceServiceProxy, } from "@fungi.computer/computer";
|
|
29
|
-
|
|
31
|
+
import { StandaloneRegistry as BaseRegistry, type StandaloneRegistryGit } from "./registry.js";
|
|
32
|
+
/** The registry uses the same root, with its own in-process Computer selection. */
|
|
33
|
+
export declare class OysterRegistry extends BaseRegistry {
|
|
34
|
+
#private;
|
|
35
|
+
constructor(state: DurableObjectState, env: StandaloneEnv, git?: StandaloneRegistryGit);
|
|
36
|
+
protected hostFor(scope: TenantScope): Promise<import("../workers-git.js").OysterGitWorkerHost>;
|
|
37
|
+
}
|
|
30
38
|
export { OysterKeys } from "../workers-git.js";
|
|
31
39
|
export { StandaloneEventDelivery as OysterWebhooks } from "./instance.js";
|
|
32
40
|
export { AgentDirectory } from "./agents.js";
|
|
@@ -35,15 +43,21 @@ export declare class OysterMcp extends OysterMcp_base {
|
|
|
35
43
|
}
|
|
36
44
|
/** Background wakes readmit members through this root's tenancy, as HTTP and MCP do. */
|
|
37
45
|
export declare class StandaloneInstance extends ComputerInstance<StandaloneEnv> {
|
|
38
|
-
protected hostFor(scope: TenantScope): import("../workers-git.js").OysterGitWorkerHost
|
|
46
|
+
protected hostFor(scope: TenantScope): Promise<import("../workers-git.js").OysterGitWorkerHost>;
|
|
39
47
|
}
|
|
40
48
|
/** Agent App tools derive the same catalog as HTTP and MCP for the Agent's pinned tenant. */
|
|
41
49
|
export declare class StandaloneAgent extends StandaloneAgentBase<StandaloneEnv> {
|
|
42
|
-
protected hostFor(scope: TenantScope): import("../workers-git.js").OysterGitWorkerHost
|
|
50
|
+
protected hostFor(scope: TenantScope): Promise<import("../workers-git.js").OysterGitWorkerHost>;
|
|
43
51
|
}
|
|
44
52
|
/** Workflow runs admit through the same root composition as HTTP. */
|
|
45
53
|
export declare class StandaloneWorkflowRuns extends StandaloneWorkflowRunsBase<StandaloneEnv> {
|
|
46
|
-
protected hostFor(scope: TenantScope): import("../workers-git.js").OysterGitWorkerHost
|
|
54
|
+
protected hostFor(scope: TenantScope): Promise<import("../workers-git.js").OysterGitWorkerHost>;
|
|
55
|
+
}
|
|
56
|
+
declare const OysterInstallationExecutor_base: new (ctx: ExecutionContext, env: StandaloneEnv) => WorkerEntrypoint<StandaloneEnv, unknown> & {
|
|
57
|
+
run(): Promise<import("../installation-operations.js").InstallationOutcome>;
|
|
58
|
+
};
|
|
59
|
+
/** Private loopback execution uses this root's ordinary host composition. */
|
|
60
|
+
export declare class OysterInstallationExecutor extends OysterInstallationExecutor_base {
|
|
47
61
|
}
|
|
48
62
|
/** The Computer's egress gateway: its own HTTPS Git back into this Worker. */
|
|
49
63
|
export declare class OysterComputerEgress extends WorkerEntrypoint<StandaloneEnv, OysterComputerEgressProps> {
|