@fungi.computer/oyster 0.0.1 → 0.2.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 +228 -176
- package/dist/agent-avatars.d.ts +103 -0
- package/dist/agent-avatars.js +66 -0
- package/dist/agents.d.ts +12 -2
- package/dist/agents.js +39 -2
- package/dist/app-builds.d.ts +76 -17
- package/dist/app-builds.js +207 -63
- package/dist/app-sources.d.ts +7 -22
- package/dist/app-sources.js +49 -14
- package/dist/apps/gate.d.ts +7 -7
- package/dist/apps/gate.js +6 -6
- package/dist/apps/installation.d.ts +35 -35
- package/dist/apps/installation.js +20 -19
- package/dist/build/artifact-writer.d.ts +40 -0
- package/dist/build/artifact-writer.js +181 -0
- package/dist/build/build-jobs.js +7 -1
- package/dist/build/build-policy.d.ts +10 -0
- package/dist/build/build-policy.js +10 -0
- package/dist/build/build-step.d.ts +12 -1
- package/dist/build/build-step.js +9 -1
- package/dist/build/candidate-builder.d.ts +68 -0
- package/dist/build/candidate-builder.js +91 -0
- package/dist/build/candidate-cli.d.ts +1 -0
- package/dist/build/candidate-cli.js +119 -0
- package/dist/build/candidate-cli.mjs +28220 -0
- package/dist/build/content-objects.d.ts +37 -0
- package/dist/build/content-objects.js +53 -0
- package/dist/build/effect.d.ts +18 -0
- package/dist/build/effect.js +52 -12
- package/dist/build/git-environment.d.ts +3 -0
- package/dist/build/git-environment.js +21 -9
- package/dist/build/local-build.d.ts +13 -3
- package/dist/build/local-build.js +149 -99
- package/dist/build/snapshot-package-store.d.ts +10 -0
- package/dist/build/snapshot-package-store.js +15 -0
- package/dist/build/snapshot-program-scripts.js +1 -1
- package/dist/build/snapshot-programs/snapshot-path.d.ts +2 -0
- package/dist/build/snapshot-programs/snapshot-path.js +6 -0
- package/dist/build/submission-contract.d.ts +461 -17
- package/dist/build/submission-contract.js +136 -26
- package/dist/build/workspace-build.d.ts +7 -2
- package/dist/build/workspace-build.js +55 -11
- package/dist/build-contract.d.ts +3 -0
- package/dist/build-contract.js +3 -0
- package/dist/build-egress.d.ts +62 -0
- package/dist/build-egress.js +148 -0
- package/dist/build.d.ts +1 -0
- package/dist/build.js +1 -0
- package/dist/cloudflare.js +4 -4
- package/dist/frame-binding-wire-script.js +1 -1
- package/dist/frame-binding-wire.d.ts +1 -1
- package/dist/frame-binding-wire.js +1 -1
- package/dist/git-journal.js +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/installation-consent.d.ts +3 -1
- package/dist/installation-consent.js +2 -0
- package/dist/mcp-owner.js +20 -8
- package/dist/pack.d.ts +6 -3
- package/dist/pack.js +28 -11
- package/dist/page/gill-observation.d.ts +4 -0
- package/dist/page/gill-observation.js +31 -0
- package/dist/page/mount.d.ts +4 -8
- package/dist/page/window-launch.d.ts +18 -0
- package/dist/page/window-launch.js +11 -0
- package/dist/page-script.js +4 -4
- package/dist/release.d.ts +11 -0
- package/dist/release.js +4 -1
- package/dist/shell/app-directory.d.ts +50 -45
- package/dist/shell/app-directory.js +19 -18
- package/dist/shell/shell-module.d.ts +26 -2
- package/dist/shell/shell-module.js +51 -2
- package/dist/shell/window-manager.d.ts +5 -1
- package/dist/shell/window-manager.js +21 -2
- package/dist/shell/workbench-directory.d.ts +332 -0
- package/dist/shell/workbench-directory.js +35 -0
- package/dist/shell/workbench-host-types.d.ts +1 -1
- package/dist/shell/workbench-host.js +5 -0
- package/dist/shell/workbench-model.d.ts +3 -1
- package/dist/source/index.d.ts +6 -7
- package/dist/source/index.js +6 -7
- package/dist/source/template-push.d.ts +33 -0
- package/dist/source/template-push.js +223 -0
- package/dist/source/template-repository.d.ts +2 -0
- package/dist/source/template-repository.js +13 -0
- package/dist/source/{template-write.d.ts → template-seed.d.ts} +19 -20
- package/dist/source/template-seed.js +80 -0
- package/dist/standalone/agent-directory.d.ts +4 -0
- package/dist/standalone/agent-directory.js +4 -0
- package/dist/standalone/agents.d.ts +227 -0
- package/dist/standalone/agents.js +834 -0
- package/dist/standalone/app-builds-binding.d.ts +36 -0
- package/dist/standalone/app-builds-binding.js +119 -0
- package/dist/standalone/app-set.d.ts +91 -0
- package/dist/standalone/app-set.js +395 -0
- package/dist/standalone/app-source.d.ts +41 -0
- package/dist/standalone/app-source.js +59 -0
- package/dist/standalone/builds.d.ts +18 -0
- package/dist/standalone/builds.js +101 -0
- package/dist/standalone/computer-egress.d.ts +37 -0
- package/dist/standalone/computer-egress.js +111 -0
- package/dist/standalone/computer.d.ts +122 -0
- package/dist/standalone/computer.js +714 -0
- package/dist/standalone/install-apps-cli.d.ts +2 -0
- package/dist/standalone/install-apps-cli.js +126 -0
- package/dist/standalone/instance.d.ts +35 -0
- package/dist/standalone/instance.js +74 -0
- package/dist/standalone/media.d.ts +76 -0
- package/dist/standalone/media.js +227 -0
- package/dist/standalone/preview.d.ts +51 -0
- package/dist/standalone/preview.js +167 -0
- package/dist/standalone/registry.d.ts +102 -0
- package/dist/standalone/registry.js +193 -0
- package/dist/standalone/tenancy.d.ts +42 -0
- package/dist/standalone/tenancy.js +241 -0
- package/dist/standalone/worker.d.ts +55 -0
- package/dist/standalone/worker.js +147 -0
- package/dist/standalone/workflow-authority-readers.d.ts +16 -0
- package/dist/standalone/workflow-authority-readers.js +35 -0
- package/dist/standalone/workflow-binding.d.ts +216 -0
- package/dist/standalone/workflow-binding.js +217 -0
- package/dist/standalone/workflow-events.d.ts +46 -0
- package/dist/standalone/workflow-events.js +39 -0
- package/dist/standalone/workflow-git-capture.d.ts +7 -0
- package/dist/standalone/workflow-git-capture.js +62 -0
- package/dist/standalone/workflow-host.d.ts +955 -0
- package/dist/standalone/workflow-host.js +778 -0
- package/dist/standalone/workflow-node-capture.d.ts +13 -0
- package/dist/standalone/workflow-node-capture.js +72 -0
- package/dist/standalone/workflow-root-authority.d.ts +27 -0
- package/dist/standalone/workflow-root-authority.js +87 -0
- package/dist/standalone/workflow-schedules.d.ts +52 -0
- package/dist/standalone/workflow-schedules.js +40 -0
- package/dist/standalone/workflow-trigger-host.d.ts +1716 -0
- package/dist/standalone/workflow-trigger-host.js +52 -0
- package/dist/standalone/workflows.d.ts +713 -0
- package/dist/standalone/workflows.js +554 -0
- package/dist/tenancy/auth0.d.ts +64 -0
- package/dist/tenancy/auth0.js +198 -0
- package/dist/tenancy/cloudflare/rate-limit.d.ts +8 -0
- package/dist/tenancy/cloudflare/rate-limit.js +19 -0
- package/dist/tenancy/cloudflare/registry.d.ts +50 -0
- package/dist/tenancy/cloudflare/registry.js +301 -0
- package/dist/tenancy/cloudflare.d.ts +2 -0
- package/dist/tenancy/cloudflare.js +2 -0
- package/dist/tenancy/cold-directory.d.ts +13 -0
- package/dist/tenancy/cold-directory.js +43 -0
- package/dist/tenancy/contracts.d.ts +195 -0
- package/dist/tenancy/contracts.js +1 -0
- package/dist/tenancy/index.d.ts +19 -0
- package/dist/tenancy/index.js +156 -0
- package/dist/tenancy/owner-key.d.ts +26 -0
- package/dist/tenancy/owner-key.js +63 -0
- package/dist/tenancy/oyster.d.ts +4 -0
- package/dist/tenancy/oyster.js +25 -0
- package/dist/tenancy/registry-record.d.ts +7 -0
- package/dist/tenancy/registry-record.js +44 -0
- package/dist/tenancy/registry.d.ts +27 -0
- package/dist/tenancy/registry.js +138 -0
- package/dist/tenancy/resolve.d.ts +7 -0
- package/dist/tenancy/resolve.js +64 -0
- package/dist/workers-git.js +1 -4
- package/dist/workers.d.ts +2 -2
- package/dist/workers.js +3 -1
- package/docs/api/build-contract.md +829 -32
- package/docs/api/build.md +253 -17
- package/docs/api/modules.md +40 -32
- package/docs/api/pack.md +6 -3
- package/docs/api/shell/app-directory.md +267 -0
- package/docs/api/shell/shell-module.md +64 -3
- package/docs/api/shell/workbench-directory.md +119 -0
- package/docs/api/shell/workbench.md +19 -0
- package/docs/api/shell.md +127 -0
- package/docs/api/tenancy/auth0.md +110 -0
- package/docs/api/tenancy/cloudflare.md +221 -0
- package/docs/api/tenancy/cold-directory.md +46 -0
- package/docs/api/tenancy/owner-key.md +63 -0
- package/docs/api/tenancy/registry.md +77 -0
- package/docs/api/tenancy/resolve.md +69 -0
- package/docs/api/tenancy.md +430 -0
- package/docs/api/workers-git.md +140 -21
- package/docs/api/workers.md +15 -2
- package/docs/site/agent-quickstart.mdx +52 -55
- package/examples/standalone/worker.ts +7 -14
- package/examples/standalone/wrangler.jsonc +67 -6
- package/package.json +78 -25
- package/dist/build/r2-artifact-writer.d.ts +0 -31
- package/dist/build/r2-artifact-writer.js +0 -179
- package/dist/source/template-write.js +0 -344
- package/docs/media/architecture.mmd +0 -32
- package/docs/media/architecture.png +0 -0
- package/docs/media/bonsai-network.png +0 -0
- package/docs/media/bonsai-repository.png +0 -0
- package/examples/git/worker.ts +0 -39
- package/examples/git/wrangler.jsonc +0 -32
package/docs/api/workers-git.md
CHANGED
|
@@ -234,39 +234,75 @@ unknown, revoked, expired or suspended key.
|
|
|
234
234
|
|
|
235
235
|
### OysterWebhooks
|
|
236
236
|
|
|
237
|
-
|
|
237
|
+
The tenant's App event delivery owner: webhook subscriptions with signed,
|
|
238
|
+
retried deliveries, and host recipients with durable per-recipient records. An
|
|
239
|
+
emit commits here and returns; every delivery happens on the alarm.
|
|
238
240
|
|
|
239
241
|
#### Extends
|
|
240
242
|
|
|
241
|
-
- `DurableObject
|
|
243
|
+
- `DurableObject`\<`Env`\>
|
|
244
|
+
|
|
245
|
+
#### Type Parameters
|
|
246
|
+
|
|
247
|
+
| Type Parameter | Default type |
|
|
248
|
+
| ------------------------------------------------- | --------------------------------- |
|
|
249
|
+
| `Env` _extends_ [`OysterKeysEnv`](#oysterkeysenv) | [`OysterKeysEnv`](#oysterkeysenv) |
|
|
242
250
|
|
|
243
251
|
#### Constructors
|
|
244
252
|
|
|
245
253
|
##### Constructor
|
|
246
254
|
|
|
247
255
|
```ts
|
|
248
|
-
new OysterWebhooks(ctx, env): OysterWebhooks
|
|
256
|
+
new OysterWebhooks<Env>(ctx, env): OysterWebhooks<Env>;
|
|
249
257
|
```
|
|
250
258
|
|
|
251
259
|
###### Parameters
|
|
252
260
|
|
|
253
|
-
| Parameter | Type
|
|
254
|
-
| --------- |
|
|
255
|
-
| `ctx` | `DurableObjectState`
|
|
256
|
-
| `env` |
|
|
261
|
+
| Parameter | Type |
|
|
262
|
+
| --------- | -------------------- |
|
|
263
|
+
| `ctx` | `DurableObjectState` |
|
|
264
|
+
| `env` | `Env` |
|
|
257
265
|
|
|
258
266
|
###### Returns
|
|
259
267
|
|
|
260
|
-
[`OysterWebhooks`](#oysterwebhooks)
|
|
268
|
+
[`OysterWebhooks`](#oysterwebhooks)\<`Env`\>
|
|
261
269
|
|
|
262
270
|
###### Overrides
|
|
263
271
|
|
|
264
272
|
```ts
|
|
265
|
-
DurableObject<
|
|
273
|
+
DurableObject<Env>.constructor
|
|
266
274
|
```
|
|
267
275
|
|
|
268
276
|
#### Methods
|
|
269
277
|
|
|
278
|
+
##### recipientDeliveries()
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
recipientDeliveries(recipient): Readonly<{
|
|
282
|
+
recipient: string;
|
|
283
|
+
eventId: string;
|
|
284
|
+
type: string;
|
|
285
|
+
state: "pending" | "failed" | "delivered";
|
|
286
|
+
attempts: number;
|
|
287
|
+
lastError: string | null;
|
|
288
|
+
updatedAt: number;
|
|
289
|
+
}>[];
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Recent deliveries to one host recipient, newest first.
|
|
293
|
+
|
|
294
|
+
###### Parameters
|
|
295
|
+
|
|
296
|
+
| Parameter | Type |
|
|
297
|
+
| ----------- | -------- |
|
|
298
|
+
| `recipient` | `string` |
|
|
299
|
+
|
|
300
|
+
###### Returns
|
|
301
|
+
|
|
302
|
+
`Readonly`\<\{ `recipient`: `string`; `eventId`: `string`; `type`: `string`;
|
|
303
|
+
`state`: `"pending"` \| `"failed"` \| `"delivered"`; `attempts`: `number`;
|
|
304
|
+
`lastError`: `string` \| `null`; `updatedAt`: `number`; \}\>[]
|
|
305
|
+
|
|
270
306
|
##### subscribe()
|
|
271
307
|
|
|
272
308
|
```ts
|
|
@@ -358,25 +394,29 @@ Recent deliveries for one subscription, newest first.
|
|
|
358
394
|
|
|
359
395
|
```ts
|
|
360
396
|
enqueue(
|
|
361
|
-
|
|
397
|
+
source,
|
|
362
398
|
payload,
|
|
363
|
-
eventId
|
|
364
|
-
|
|
399
|
+
eventId,
|
|
400
|
+
recipients
|
|
401
|
+
): Promise<number>;
|
|
365
402
|
```
|
|
366
403
|
|
|
367
|
-
|
|
404
|
+
Accept an emitted event: queue it for every matching subscription and every
|
|
405
|
+
named host recipient (idempotent per event id). Nothing is delivered before this
|
|
406
|
+
returns, so no recipient can fail the emitter's write.
|
|
368
407
|
|
|
369
408
|
###### Parameters
|
|
370
409
|
|
|
371
|
-
| Parameter
|
|
372
|
-
|
|
|
373
|
-
| `
|
|
374
|
-
| `payload`
|
|
375
|
-
| `eventId`
|
|
410
|
+
| Parameter | Type |
|
|
411
|
+
| ------------ | --------------------------------------------------------- |
|
|
412
|
+
| `source` | [`HostEventSource`](#hosteventsource) |
|
|
413
|
+
| `payload` | [`StandardWebhookPayload`](git.md#standardwebhookpayload) |
|
|
414
|
+
| `eventId` | `string` |
|
|
415
|
+
| `recipients` | readonly `string`[] |
|
|
376
416
|
|
|
377
417
|
###### Returns
|
|
378
418
|
|
|
379
|
-
`number
|
|
419
|
+
`Promise`\<`number`\>
|
|
380
420
|
|
|
381
421
|
##### alarm()
|
|
382
422
|
|
|
@@ -384,7 +424,7 @@ Queue an event for every matching subscription (idempotent per event id).
|
|
|
384
424
|
alarm(): Promise<void>;
|
|
385
425
|
```
|
|
386
426
|
|
|
387
|
-
Deliver due webhooks, then schedule the next retry.
|
|
427
|
+
Deliver due webhooks and recipient rows, then schedule the next retry.
|
|
388
428
|
|
|
389
429
|
###### Returns
|
|
390
430
|
|
|
@@ -1015,6 +1055,57 @@ host handle decodes.
|
|
|
1015
1055
|
|
|
1016
1056
|
## Type Aliases
|
|
1017
1057
|
|
|
1058
|
+
### HostEventSource
|
|
1059
|
+
|
|
1060
|
+
```ts
|
|
1061
|
+
type HostEventSource = Readonly<{
|
|
1062
|
+
installationId: string;
|
|
1063
|
+
appId: string;
|
|
1064
|
+
releaseId: string;
|
|
1065
|
+
}>;
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
The emitting installation as the host attested it on the emit's frame.
|
|
1069
|
+
|
|
1070
|
+
---
|
|
1071
|
+
|
|
1072
|
+
### HostRecipientEvent
|
|
1073
|
+
|
|
1074
|
+
```ts
|
|
1075
|
+
type HostRecipientEvent = Readonly<{
|
|
1076
|
+
source: HostEventSource;
|
|
1077
|
+
type: string;
|
|
1078
|
+
eventId: string;
|
|
1079
|
+
payload: Readonly<{
|
|
1080
|
+
type: string;
|
|
1081
|
+
timestamp: string;
|
|
1082
|
+
data: unknown;
|
|
1083
|
+
}>;
|
|
1084
|
+
}>;
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
One accepted event, as a host recipient receives it.
|
|
1088
|
+
|
|
1089
|
+
---
|
|
1090
|
+
|
|
1091
|
+
### RecipientDelivery
|
|
1092
|
+
|
|
1093
|
+
```ts
|
|
1094
|
+
type RecipientDelivery = Readonly<{
|
|
1095
|
+
recipient: string;
|
|
1096
|
+
eventId: string;
|
|
1097
|
+
type: string;
|
|
1098
|
+
state: "pending" | "delivered" | "failed";
|
|
1099
|
+
attempts: number;
|
|
1100
|
+
lastError: string | null;
|
|
1101
|
+
updatedAt: number;
|
|
1102
|
+
}>;
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
One recipient's delivery record for one event.
|
|
1106
|
+
|
|
1107
|
+
---
|
|
1108
|
+
|
|
1018
1109
|
### ArtifactsGit
|
|
1019
1110
|
|
|
1020
1111
|
```ts
|
|
@@ -1288,7 +1379,7 @@ One live guest frame's Git custody; never a guest argument.
|
|
|
1288
1379
|
const eventsBinding: OysterBindingRow<OysterGitWorkerEnv>;
|
|
1289
1380
|
```
|
|
1290
1381
|
|
|
1291
|
-
EVENTS
|
|
1382
|
+
EVENTS for a host with webhook subscribers only.
|
|
1292
1383
|
|
|
1293
1384
|
---
|
|
1294
1385
|
|
|
@@ -1347,6 +1438,34 @@ The Artifacts namespace: the binding when present, else the REST API.
|
|
|
1347
1438
|
|
|
1348
1439
|
---
|
|
1349
1440
|
|
|
1441
|
+
### eventsBindingFor()
|
|
1442
|
+
|
|
1443
|
+
```ts
|
|
1444
|
+
function eventsBindingFor<Env>(recipients): OysterBindingRow<Env>;
|
|
1445
|
+
```
|
|
1446
|
+
|
|
1447
|
+
EVENTS: commit the emit to this tenant's delivery owner and return. Webhook
|
|
1448
|
+
subscribers and the host recipients a root names are delivered afterwards, so a
|
|
1449
|
+
subscriber outage never fails the emitting App's write.
|
|
1450
|
+
|
|
1451
|
+
#### Type Parameters
|
|
1452
|
+
|
|
1453
|
+
| Type Parameter |
|
|
1454
|
+
| ----------------------------------------------------------- |
|
|
1455
|
+
| `Env` _extends_ [`OysterGitWorkerEnv`](#oystergitworkerenv) |
|
|
1456
|
+
|
|
1457
|
+
#### Parameters
|
|
1458
|
+
|
|
1459
|
+
| Parameter | Type |
|
|
1460
|
+
| ------------ | -------------------------------------------------------- |
|
|
1461
|
+
| `recipients` | (`context`, `frame`) => `Promise`\<readonly `string`[]\> |
|
|
1462
|
+
|
|
1463
|
+
#### Returns
|
|
1464
|
+
|
|
1465
|
+
[`OysterBindingRow`](workers.md#oysterbindingrow)\<`Env`\>
|
|
1466
|
+
|
|
1467
|
+
---
|
|
1468
|
+
|
|
1350
1469
|
### gitAdminRoutes()
|
|
1351
1470
|
|
|
1352
1471
|
```ts
|
package/docs/api/workers.md
CHANGED
|
@@ -1557,7 +1557,16 @@ Files in an R2 bucket under `prefix` (one workspace per prefix).
|
|
|
1557
1557
|
### r2ArtifactStore()
|
|
1558
1558
|
|
|
1559
1559
|
```ts
|
|
1560
|
-
function r2ArtifactStore(bucket):
|
|
1560
|
+
function r2ArtifactStore(bucket): Readonly<{
|
|
1561
|
+
get: (artifactRef) => Promise<Uint8Array<ArrayBufferLike> | null>;
|
|
1562
|
+
put: (artifactRef, bytes) => Promise<void>;
|
|
1563
|
+
}> &
|
|
1564
|
+
Readonly<{
|
|
1565
|
+
head: (artifactRef) => Promise<Readonly<{
|
|
1566
|
+
byteLength: number;
|
|
1567
|
+
digest: Sha256Digest | null;
|
|
1568
|
+
}> | null>;
|
|
1569
|
+
}>;
|
|
1561
1570
|
```
|
|
1562
1571
|
|
|
1563
1572
|
Store Release artifacts in an R2 bucket.
|
|
@@ -1570,7 +1579,11 @@ Store Release artifacts in an R2 bucket.
|
|
|
1570
1579
|
|
|
1571
1580
|
#### Returns
|
|
1572
1581
|
|
|
1573
|
-
|
|
1582
|
+
`Readonly`\<\{ `get`: (`artifactRef`) =>
|
|
1583
|
+
`Promise`\<`Uint8Array`\<`ArrayBufferLike`\> \| `null`\>; `put`: (`artifactRef`,
|
|
1584
|
+
`bytes`) => `Promise`\<`void`\>; \}\> & `Readonly`\<\{ `head`: (`artifactRef`)
|
|
1585
|
+
=> `Promise`\< \| `Readonly`\<\{ `byteLength`: `number`; `digest`:
|
|
1586
|
+
`Sha256Digest` \| `null`; \}\> \| `null`\>; \}\>
|
|
1574
1587
|
|
|
1575
1588
|
---
|
|
1576
1589
|
|
|
@@ -23,7 +23,8 @@ read the "If it fails" notes under it before trying anything else.
|
|
|
23
23
|
## 1. Check prerequisites
|
|
24
24
|
|
|
25
25
|
You need Node 24 or newer, pnpm, Git, curl and openssl. You do not need a
|
|
26
|
-
Cloudflare account until step 7
|
|
26
|
+
Cloudflare account until step 7. Docker is needed only in step 7, where Wrangler
|
|
27
|
+
builds the Computer's container image.
|
|
27
28
|
|
|
28
29
|
```sh
|
|
29
30
|
node --version
|
|
@@ -43,13 +44,13 @@ If it fails:
|
|
|
43
44
|
|
|
44
45
|
## 2. Create a project
|
|
45
46
|
|
|
46
|
-
Make a new directory, install Oyster and Wrangler, and copy the
|
|
47
|
+
Make a new directory, install Oyster, its Computer and Wrangler, and copy the
|
|
47
48
|
example Worker out of the package:
|
|
48
49
|
|
|
49
50
|
```sh
|
|
50
51
|
mkdir my-oyster
|
|
51
52
|
cd my-oyster
|
|
52
|
-
pnpm add @fungi.computer/oyster
|
|
53
|
+
pnpm add @fungi.computer/oyster @fungi.computer/computer
|
|
53
54
|
pnpm add -D wrangler
|
|
54
55
|
cp node_modules/@fungi.computer/oyster/examples/standalone/worker.ts .
|
|
55
56
|
cp node_modules/@fungi.computer/oyster/examples/standalone/wrangler.jsonc .
|
|
@@ -67,26 +68,30 @@ If it fails:
|
|
|
67
68
|
`protobufjs`: pnpm installed them without running their install scripts, and
|
|
68
69
|
nothing in this guide needs those scripts. Go on.
|
|
69
70
|
- `cp: cannot stat …/examples/standalone/…`: the install did not finish. Run
|
|
70
|
-
`pnpm add @fungi.computer/oyster` again and read its
|
|
71
|
+
`pnpm add @fungi.computer/oyster @fungi.computer/computer` again and read its
|
|
72
|
+
first error.
|
|
71
73
|
|
|
72
74
|
## 3. Run a local Oyster
|
|
73
75
|
|
|
74
|
-
`worker.ts` and `wrangler.jsonc` are
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
`worker.ts` and `wrangler.jsonc` are the whole Oyster. Run it under
|
|
77
|
+
`wrangler dev` on your machine, without its Computer container. Oyster serves an
|
|
78
|
+
HTTPS origin; `--local-upstream` presents your loopback requests to it at
|
|
79
|
+
`https://oyster.test`. Choose an owner key and keep this terminal open:
|
|
77
80
|
|
|
78
81
|
```sh
|
|
79
82
|
export OYSTER_OWNER_KEY=$(openssl rand -hex 24)
|
|
80
83
|
export OYSTER_URL=http://127.0.0.1:8787
|
|
81
84
|
echo "$OYSTER_OWNER_KEY" > .oyster-owner-key
|
|
82
|
-
npx wrangler dev --local --ip 127.0.0.1 --port 8787 \
|
|
83
|
-
--
|
|
85
|
+
npx wrangler dev --local --enable-containers=false --ip 127.0.0.1 --port 8787 \
|
|
86
|
+
--local-upstream oyster.test --upstream-protocol https \
|
|
87
|
+
--var OYSTER_OWNER_KEY:$OYSTER_OWNER_KEY --var OYSTER_ORIGIN:https://oyster.test
|
|
84
88
|
```
|
|
85
89
|
|
|
86
|
-
Expected output:
|
|
87
|
-
`env.REGISTRY (OysterRegistry)`,
|
|
88
|
-
`env.
|
|
89
|
-
`Ready on http://127.0.0.1:8787`.
|
|
90
|
+
Expected output: warnings that the AI and Artifacts bindings reach remote
|
|
91
|
+
resources, a bindings table listing `env.REGISTRY (OysterRegistry)`,
|
|
92
|
+
`env.INSTANCES (StandaloneInstance)`, `env.COMPUTER (ComputerDO)` and the rest,
|
|
93
|
+
then `Ready on http://127.0.0.1:8787`. Locally there is no Computer, git storage
|
|
94
|
+
or Workers AI; steps 3 to 5 need none of them.
|
|
90
95
|
|
|
91
96
|
Keep it running. Open a second terminal in `my-oyster`, set the same two
|
|
92
97
|
variables there, and check that Oyster answers:
|
|
@@ -114,8 +119,9 @@ If it fails:
|
|
|
114
119
|
`/login` check prints `200`:
|
|
115
120
|
|
|
116
121
|
```sh
|
|
117
|
-
npx wrangler dev --local --ip 127.0.0.1 --port 8787 \
|
|
118
|
-
--
|
|
122
|
+
npx wrangler dev --local --enable-containers=false --ip 127.0.0.1 --port 8787 \
|
|
123
|
+
--local-upstream oyster.test --upstream-protocol https \
|
|
124
|
+
--var OYSTER_OWNER_KEY:$OYSTER_OWNER_KEY --var OYSTER_ORIGIN:https://oyster.test \
|
|
119
125
|
> oyster-dev.log 2>&1 &
|
|
120
126
|
```
|
|
121
127
|
|
|
@@ -265,29 +271,10 @@ If it fails:
|
|
|
265
271
|
|
|
266
272
|
## 6. Add Git
|
|
267
273
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
is deployed in step 7. To use it, copy it over the standalone files:
|
|
273
|
-
|
|
274
|
-
```sh
|
|
275
|
-
cp node_modules/@fungi.computer/oyster/examples/git/worker.ts .
|
|
276
|
-
cp node_modules/@fungi.computer/oyster/examples/git/wrangler.jsonc .
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
Compared with `examples/standalone`, `examples/git/worker.ts` builds one
|
|
280
|
-
`oysterGitRoot` with `ownerOrKeyTenancy` and adds:
|
|
281
|
-
|
|
282
|
-
- the git door, mounted by `createOysterGitWorker(root)`;
|
|
283
|
-
- owner and named keys that sign in to git, plus `/api/keys` and
|
|
284
|
-
`/api/webhooks`;
|
|
285
|
-
- `OysterGitInstance` as `OysterInstance`, which hands Apps `env.GIT` and
|
|
286
|
-
`env.EVENTS`;
|
|
287
|
-
- the `ARTIFACTS` binding and the `KEYS` and `WEBHOOKS` Durable Objects in its
|
|
288
|
-
`wrangler.jsonc`, which names the Worker `oyster-git`.
|
|
289
|
-
|
|
290
|
-
With the Git worker deployed, give each agent its own key:
|
|
274
|
+
Git is already part of the host: people and agents `clone`, `fetch` and `push`
|
|
275
|
+
App repositories with ordinary `git` at `/git/<installation>/<repo>.git`, with
|
|
276
|
+
repositories in Cloudflare Artifacts. Artifacts runs only once the Worker is
|
|
277
|
+
deployed in step 7. There, give each agent its own key:
|
|
291
278
|
|
|
292
279
|
```sh
|
|
293
280
|
curl -s -X POST -H "Authorization: Bearer $OYSTER_OWNER_KEY" \
|
|
@@ -299,20 +286,15 @@ curl -s -X POST -H "Authorization: Bearer $OYSTER_OWNER_KEY" \
|
|
|
299
286
|
Expected output: JSON with a `plaintext` field starting `oyk_`. Oyster shows it
|
|
300
287
|
once; that key signs in to `git` and to `/mcp`.
|
|
301
288
|
|
|
302
|
-
If it fails:
|
|
303
|
-
|
|
304
|
-
- `404`: the deployed Worker is the standalone one. Copy the `examples/git`
|
|
305
|
-
files and deploy again.
|
|
306
|
-
|
|
307
289
|
## 7. Deploy to Cloudflare Workers
|
|
308
290
|
|
|
309
|
-
This step needs a Cloudflare account on Workers Paid
|
|
310
|
-
|
|
291
|
+
This step needs a Cloudflare account on Workers Paid with Containers, Artifacts,
|
|
292
|
+
Workers AI and Workflows enabled, and Docker running on this machine. Ask the
|
|
293
|
+
person before you deploy anything.
|
|
311
294
|
|
|
312
|
-
`wrangler.jsonc` names the Worker
|
|
313
|
-
|
|
314
|
-
`https
|
|
315
|
-
the standalone Worker:
|
|
295
|
+
`wrangler.jsonc` names the Worker `oyster`, its R2 bucket `oyster-releases` and
|
|
296
|
+
its Artifacts namespace `oyster`. The Worker's address is
|
|
297
|
+
`https://oyster.<your-subdomain>.workers.dev`, or a custom domain:
|
|
316
298
|
|
|
317
299
|
```sh
|
|
318
300
|
npx wrangler login
|
|
@@ -322,9 +304,21 @@ npx wrangler deploy --var OYSTER_ORIGIN:$OYSTER_URL
|
|
|
322
304
|
printf '%s' "$OYSTER_OWNER_KEY" | npx wrangler secret put OYSTER_OWNER_KEY
|
|
323
305
|
```
|
|
324
306
|
|
|
325
|
-
Expected output: `wrangler deploy`
|
|
326
|
-
`wrangler secret put` reports the secret
|
|
327
|
-
|
|
307
|
+
Expected output: `wrangler deploy` builds the Computer image, uploads it and
|
|
308
|
+
prints the deployed `https://` URL, and `wrangler secret put` reports the secret
|
|
309
|
+
uploaded.
|
|
310
|
+
|
|
311
|
+
Then install Fungi's seven starter Apps, each built on this Oyster's Computer
|
|
312
|
+
from its own repository:
|
|
313
|
+
|
|
314
|
+
```sh
|
|
315
|
+
npx oyster install-apps
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Expected output: a `source recorded` line per App, `Building … on the Computer`
|
|
319
|
+
and `Installed …` lines (two builds at a time, Tourtois first), a timing table,
|
|
320
|
+
and `Installed 7 Apps`. Open `$OYSTER_URL/login` with the owner key to see the
|
|
321
|
+
Tourtois desktop.
|
|
328
322
|
|
|
329
323
|
To keep `OYSTER_ORIGIN` across later deploys, set `vars.OYSTER_ORIGIN` in
|
|
330
324
|
`wrangler.jsonc`; every deploy replaces the Worker's variables.
|
|
@@ -336,14 +330,17 @@ If it fails:
|
|
|
336
330
|
- A secret prompt on stdin: pipe the key as shown; never type it into a log.
|
|
337
331
|
- Bindings or migrations refused: deploy the copied `wrangler.jsonc` unchanged
|
|
338
332
|
except for `vars` and the bucket name.
|
|
333
|
+
- `docker` not found or not running: start Docker; Wrangler builds the Computer
|
|
334
|
+
image from `node_modules/@fungi.computer/computer/Dockerfile`.
|
|
335
|
+
- A build `failed` in `install-apps`: run it again; finished Apps are kept and
|
|
336
|
+
replaced in place.
|
|
339
337
|
|
|
340
338
|
## Where to go next
|
|
341
339
|
|
|
342
340
|
- The Oyster README (`node_modules/@fungi.computer/oyster/README.md`) explains
|
|
343
341
|
the host, Apps, capabilities, MCP and the shell in depth.
|
|
344
|
-
- [oyster.shiit.app](https://oyster.shiit.app/)
|
|
345
|
-
|
|
346
|
-
media.
|
|
342
|
+
- [oyster.shiit.app](https://oyster.shiit.app/) runs this same host with the
|
|
343
|
+
seven starter Apps.
|
|
347
344
|
- Oyster is built from the other Fungi packages, each its own repository under
|
|
348
345
|
[github.com/fungi-computer](https://github.com/fungi-computer) and on npm as
|
|
349
346
|
`@fungi.computer/<name>`. The README's "Part of Fungi" section lists them.
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
OysterBinding,
|
|
9
|
-
OysterInstance,
|
|
10
|
-
OysterRegistry,
|
|
11
|
-
OysterMcp,
|
|
12
|
-
} from "@fungi.computer/oyster/workers";
|
|
13
|
-
|
|
14
|
-
export default createOysterWorker();
|
|
1
|
+
// The whole Oyster: Apps installed from Releases, each with its own Durable
|
|
2
|
+
// Object and SQLite; git through Artifacts; a Computer in a Cloudflare
|
|
3
|
+
// Container that builds App sources and runs terminals and files; Agents on
|
|
4
|
+
// Workers AI; Workflows; and media. Runs on Cloudflare Workers
|
|
5
|
+
// (`wrangler deploy`) and on celld from the same code.
|
|
6
|
+
export * from "@fungi.computer/oyster/standalone";
|
|
7
|
+
export { default } from "@fungi.computer/oyster/standalone";
|
|
@@ -1,21 +1,82 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "./node_modules/wrangler/config-schema.json",
|
|
3
|
+
// The whole Oyster. Copy it beside worker.ts, set OYSTER_ORIGIN, and deploy.
|
|
3
4
|
"name": "oyster",
|
|
4
5
|
"main": "worker.ts",
|
|
5
6
|
"compatibility_date": "2026-09-04",
|
|
6
7
|
"compatibility_flags": ["nodejs_compat"],
|
|
7
|
-
"
|
|
8
|
+
"workers_dev": true,
|
|
9
|
+
"preview_urls": false,
|
|
10
|
+
"observability": { "enabled": true },
|
|
11
|
+
"workflows": [
|
|
12
|
+
{
|
|
13
|
+
"binding": "GRAPH_WORKFLOWS",
|
|
14
|
+
"name": "oyster-graphs",
|
|
15
|
+
"class_name": "StandaloneGraphWorkflow",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
8
18
|
"worker_loaders": [{ "binding": "LOADER" }],
|
|
9
|
-
"
|
|
19
|
+
"containers": [
|
|
20
|
+
{
|
|
21
|
+
"class_name": "ComputerDO",
|
|
22
|
+
"image": "./node_modules/@fungi.computer/computer/Dockerfile",
|
|
23
|
+
"instance_type": "standard-4",
|
|
24
|
+
"max_instances": 1,
|
|
25
|
+
"rollout_active_grace_period": 0,
|
|
26
|
+
"rollout_step_percentage": [100],
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
"ai": { "binding": "AI" },
|
|
30
|
+
"images": { "binding": "IMAGES" },
|
|
31
|
+
"r2_buckets": [
|
|
32
|
+
{ "binding": "RELEASES", "bucket_name": "oyster-releases" },
|
|
33
|
+
{ "binding": "APP_ARTIFACTS", "bucket_name": "oyster-releases" },
|
|
34
|
+
],
|
|
35
|
+
"artifacts": [{ "binding": "ARTIFACTS", "namespace": "oyster" }],
|
|
36
|
+
"vars": {
|
|
37
|
+
"OYSTER_COMPUTER_ID": "workspace",
|
|
38
|
+
"OYSTER_HOME_INSTALLATION": "tourtois",
|
|
39
|
+
"OYSTER_ORIGIN": "https://oyster.example",
|
|
40
|
+
"OYSTER_OWNER_NAME": "owner",
|
|
41
|
+
// Names the AI Gateway that Prints' third-party models (GPT Image 2,
|
|
42
|
+
// Seedance, Veo) and the background media retry owner route through.
|
|
43
|
+
// Not a secret: Cloudflare creates the gateway by this id on first use.
|
|
44
|
+
"AI_GATEWAY_ID": "oyster",
|
|
45
|
+
},
|
|
10
46
|
"durable_objects": {
|
|
11
47
|
"bindings": [
|
|
48
|
+
{ "name": "TENANTS", "class_name": "StandaloneTenants" },
|
|
12
49
|
{ "name": "MCP", "class_name": "OysterMcp" },
|
|
50
|
+
|
|
13
51
|
{ "name": "REGISTRY", "class_name": "OysterRegistry" },
|
|
14
|
-
{ "name": "
|
|
52
|
+
{ "name": "WORKFLOW_RUNS", "class_name": "StandaloneWorkflowRuns" },
|
|
53
|
+
{ "name": "INSTANCES", "class_name": "StandaloneInstance" },
|
|
54
|
+
{ "name": "COMPUTER", "class_name": "ComputerDO" },
|
|
55
|
+
{ "name": "KEYS", "class_name": "OysterKeys" },
|
|
56
|
+
{ "name": "WEBHOOKS", "class_name": "OysterWebhooks" },
|
|
57
|
+
{ "name": "AGENTS", "class_name": "StandaloneAgent" },
|
|
58
|
+
{ "name": "AGENT_DIRECTORY", "class_name": "AgentDirectory" },
|
|
59
|
+
{ "name": "MEDIA_OPERATION", "class_name": "MediaOperationDO" },
|
|
15
60
|
],
|
|
16
61
|
},
|
|
62
|
+
// One initial tag: pre-launch history was collapsed (Levi 10-14, data wipe
|
|
63
|
+
// authorized), so a fresh Worker creates every bound class at once.
|
|
17
64
|
"migrations": [
|
|
18
|
-
{
|
|
19
|
-
|
|
65
|
+
{
|
|
66
|
+
"tag": "oyster-v1",
|
|
67
|
+
"new_sqlite_classes": [
|
|
68
|
+
"StandaloneTenants",
|
|
69
|
+
"OysterMcp",
|
|
70
|
+
"OysterRegistry",
|
|
71
|
+
"StandaloneWorkflowRuns",
|
|
72
|
+
"StandaloneInstance",
|
|
73
|
+
"ComputerDO",
|
|
74
|
+
"OysterKeys",
|
|
75
|
+
"OysterWebhooks",
|
|
76
|
+
"StandaloneAgent",
|
|
77
|
+
"AgentDirectory",
|
|
78
|
+
"MediaOperationDO",
|
|
79
|
+
],
|
|
80
|
+
},
|
|
20
81
|
],
|
|
21
82
|
}
|