@fungi.computer/oyster 0.2.0 → 0.3.1
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 +396 -72
- package/dist/agents.d.ts +3 -2
- package/dist/agents.js +4 -2
- package/dist/app-builds.d.ts +81 -8
- package/dist/app-builds.js +213 -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 +20 -6
- package/dist/apps/gate.js +42 -16
- package/dist/apps/index.d.ts +3 -1
- package/dist/apps/index.js +3 -1
- package/dist/apps/installation.d.ts +132 -51
- package/dist/apps/installation.js +176 -70
- 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 +8375 -334
- 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.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 +102 -4
- package/dist/frame-binding-wire-script.js +1 -1
- package/dist/frame-binding-wire.js +4 -2
- package/dist/git-auth.d.ts +0 -2
- package/dist/git-auth.js +0 -2
- 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 +25 -15
- package/dist/index.js +39 -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/older-oyster-store-refusal.d.ts +4 -0
- package/dist/older-oyster-store-refusal.js +18 -0
- package/dist/older-oyster-store.d.ts +21 -0
- package/dist/older-oyster-store.js +43 -0
- 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 -3
- 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 +68 -9
- package/dist/standalone/agents.js +428 -56
- package/dist/standalone/app-builds-binding.d.ts +20 -2
- package/dist/standalone/app-builds-binding.js +147 -23
- package/dist/standalone/app-set.d.ts +5 -2
- package/dist/standalone/app-set.js +186 -144
- 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 +129 -22
- 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 +37 -10
- package/dist/standalone/registry.d.ts +151 -9
- package/dist/standalone/registry.js +305 -8
- package/dist/standalone/worker.d.ts +19 -5
- package/dist/standalone/worker.js +90 -54
- package/dist/standalone/workflow-binding.d.ts +18 -22
- package/dist/standalone/workflow-binding.js +18 -18
- 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 +162 -161
- package/dist/standalone/workflow-host.js +101 -21
- 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 +65 -5
- 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 +140 -43
- 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 +64 -52
- package/dist/workers.d.ts +226 -13
- package/dist/workers.js +363 -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 +1594 -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 -71
- package/dist/installation-consent.d.ts +0 -81
- package/dist/installation-consent.js +0 -84
- package/dist/shell/app-directory.d.ts +0 -542
- package/dist/shell/app-directory.js +0 -196
- 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 -128
- package/dist/shell/window-manager.js +0 -730
- 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 -352
- package/dist/shell/workbench-model.d.ts +0 -194
- 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
package/README.md
CHANGED
|
@@ -37,6 +37,9 @@ Computer.
|
|
|
37
37
|
- [Prints](https://github.com/fungi-computer/prints) generates images and video
|
|
38
38
|
with Workers AI.
|
|
39
39
|
|
|
40
|
+
Stage is not published or included in the 0.3 starter set. It appears as a
|
|
41
|
+
glowing ember swarm and directs animated scenes and cards as an agent answers.
|
|
42
|
+
|
|
40
43
|
<table>
|
|
41
44
|
<tr>
|
|
42
45
|
<td width="50%"><img alt="Bonsai's koi-pond repository: a network graph with one lane per agent fork, its three open Changes and the live activity feed" src="https://raw.githubusercontent.com/fungi-computer/oyster/main/docs/media/bonsai-koi-pond.png"><br><b>Bonsai</b>: a repository three agents build together</td>
|
|
@@ -61,25 +64,38 @@ Workers AI, Workflows and media.
|
|
|
61
64
|
|
|
62
65
|
You need:
|
|
63
66
|
|
|
64
|
-
- a Cloudflare account on Workers Paid, with Containers, Artifacts, Workers AI
|
|
65
|
-
and
|
|
67
|
+
- a Cloudflare account on Workers Paid, with Containers, Artifacts, Workers AI,
|
|
68
|
+
Workflows and Browser Rendering (now called Browser Run) enabled;
|
|
66
69
|
- Docker, which Wrangler uses to build the Computer's container image;
|
|
67
|
-
- Node 24, pnpm
|
|
70
|
+
- Node 24, pnpm 11 or newer and Git.
|
|
68
71
|
|
|
69
72
|
The first install takes about 15 to 20 minutes, most of it the seven App builds
|
|
70
73
|
on the Computer, one after another. Start a project, add Oyster, its Computer
|
|
71
|
-
and Wrangler, and copy the example Worker out of the package
|
|
74
|
+
and Wrangler, and copy the example Worker out of the package. The local pnpm
|
|
75
|
+
policy allows esbuild and workerd to install their native binaries and disables
|
|
76
|
+
unneeded optional dependency scripts, so a fresh install exits successfully:
|
|
72
77
|
|
|
73
78
|
```sh
|
|
74
79
|
mkdir my-oyster && cd my-oyster
|
|
75
|
-
|
|
80
|
+
cat > pnpm-workspace.yaml <<'YAML'
|
|
81
|
+
allowBuilds:
|
|
82
|
+
"@google/genai": false
|
|
83
|
+
"@mongodb-js/zstd": false
|
|
84
|
+
esbuild: true
|
|
85
|
+
exifreader: false
|
|
86
|
+
node-liblzma: false
|
|
87
|
+
protobufjs: false
|
|
88
|
+
workerd: true
|
|
89
|
+
YAML
|
|
90
|
+
pnpm add @fungi.computer/oyster @fungi.computer/computer react@^19.2.0 react-dom@^19.2.0
|
|
76
91
|
pnpm add -D wrangler
|
|
77
92
|
cp node_modules/@fungi.computer/oyster/examples/standalone/{worker.ts,wrangler.jsonc} .
|
|
78
93
|
```
|
|
79
94
|
|
|
80
|
-
pnpm
|
|
81
|
-
|
|
82
|
-
|
|
95
|
+
If `pnpm add` reports `ERR_PNPM_IGNORED_BUILDS`, check that the policy file
|
|
96
|
+
above exists before installing. If it names a new dependency not listed there,
|
|
97
|
+
stop and review that package before allowing its scripts. Do not treat exit 1 as
|
|
98
|
+
success.
|
|
83
99
|
|
|
84
100
|
`worker.ts` re-exports the whole host:
|
|
85
101
|
|
|
@@ -90,10 +106,15 @@ export { default } from "@fungi.computer/oyster/standalone";
|
|
|
90
106
|
|
|
91
107
|
`wrangler.jsonc` names the Worker `oyster`, its Release bucket `oyster-releases`
|
|
92
108
|
and its Artifacts namespace `oyster`, and runs the Computer from
|
|
93
|
-
`node_modules/@fungi.computer/computer/Dockerfile`.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
`node_modules/@fungi.computer/computer/Dockerfile`. Its
|
|
110
|
+
`"browser": { "binding": "BROWSER" }` enables Cloudflare Browser Rendering for
|
|
111
|
+
the zero-grant UI boot check and for Agents' browser tool. Without the binding
|
|
112
|
+
the UI of a Release is reported `not_checked` with
|
|
113
|
+
`code: "boot_browser_binding_missing"`; the install still proceeds.
|
|
114
|
+
|
|
115
|
+
Create the bucket and deploy. Your Worker's address is
|
|
116
|
+
`https://oyster.<your-subdomain>.workers.dev`; your workers.dev subdomain is on
|
|
117
|
+
the Workers & Pages overview in the Cloudflare dashboard.
|
|
97
118
|
|
|
98
119
|
```sh
|
|
99
120
|
npx wrangler login
|
|
@@ -105,7 +126,76 @@ npx wrangler deploy --var OYSTER_ORIGIN:$OYSTER_URL
|
|
|
105
126
|
Set `OYSTER_ORIGIN` in `wrangler.jsonc` instead if you deploy again later; every
|
|
106
127
|
deploy replaces the Worker's variables.
|
|
107
128
|
|
|
108
|
-
|
|
129
|
+
### API-token permissions and teardown
|
|
130
|
+
|
|
131
|
+
For an API token instead of `wrangler login`, load `CLOUDFLARE_API_TOKEN` into
|
|
132
|
+
your shell without committing it. Set `CLOUDFLARE_ACCOUNT_ID` (or `account_id`
|
|
133
|
+
in `wrangler.jsonc`) explicitly, and skip the login command. Use Wrangler
|
|
134
|
+
4.135.0 or newer; record `npx wrangler --version` for deployment and teardown.
|
|
135
|
+
|
|
136
|
+
The [Cloudflare API specification](https://github.com/cloudflare/api-schemas)
|
|
137
|
+
names these account-scoped permission groups for the deployment and resource
|
|
138
|
+
deletion operations:
|
|
139
|
+
|
|
140
|
+
| Permission group | Used for |
|
|
141
|
+
| ------------------------ | ----------------------------------------------------------- |
|
|
142
|
+
| Workers Scripts Write | Deploy, secrets, Worker deletion and Workflow deletion |
|
|
143
|
+
| Workers R2 Storage Write | Release bucket creation, object cleanup and bucket deletion |
|
|
144
|
+
| Workers Containers Write | Computer container application management |
|
|
145
|
+
| Artifacts Edit | Artifacts namespace and repository management |
|
|
146
|
+
|
|
147
|
+
Browser Rendering through the Workers `BROWSER` binding
|
|
148
|
+
[needs no additional API-token permission](https://developers.cloudflare.com/browser-run/quick-actions/).
|
|
149
|
+
The separate Browser Rendering Write permission is for its REST API, which this
|
|
150
|
+
quick start does not use. Workers Paid entitlement is still required.
|
|
151
|
+
|
|
152
|
+
For stream-rehearsal diagnostics, include **Browser Rendering (Read)** in the
|
|
153
|
+
account-scoped token checklist: it permits REST session inspection, separate
|
|
154
|
+
from the `BROWSER` binding's boot operation. Use the documented
|
|
155
|
+
`/browser-rendering/devtools/session` list and `devtools/session/{session_id}`
|
|
156
|
+
details operations; a session's `endTime`, not its connection end time, reports
|
|
157
|
+
closure. A plain 404 from another route does not establish a missing permission.
|
|
158
|
+
If inspection is unavailable, record **UNAVAILABLE**, not confirmed cleanup. Do
|
|
159
|
+
not broaden an existing token automatically.
|
|
160
|
+
|
|
161
|
+
With an explicit account ID, user/account discovery is unnecessary. Do not add
|
|
162
|
+
Workers KV Storage Read, User Details Read or Memberships Read just for that
|
|
163
|
+
discovery. Wrangler 4.135.0 treats denied legacy-Sites KV inspection during
|
|
164
|
+
`wrangler delete` as a warning, not a reason to broaden this token. AI Gateway
|
|
165
|
+
Read/Edit permissions are not needed for this deploy or a teardown before any
|
|
166
|
+
media ran; inspect that additional resource if media has created a gateway.
|
|
167
|
+
|
|
168
|
+
`npx wrangler delete` deletes the Worker, not the entire Oyster. For a throwaway
|
|
169
|
+
deployment, also empty and delete the Release bucket, delete the Computer's
|
|
170
|
+
container application, delete the Workflow, and delete the Artifacts
|
|
171
|
+
repositories and namespace. Use the configured resource names and confirm each
|
|
172
|
+
is gone through Cloudflare's dashboard or API. Capture teardown errors and the
|
|
173
|
+
Wrangler version rather than silently adding unrelated token permissions.
|
|
174
|
+
|
|
175
|
+
### Upgrading from Oyster 0.2 or earlier
|
|
176
|
+
|
|
177
|
+
Oyster 0.3 does not read data created by Oyster 0.1 or 0.2, and it does not
|
|
178
|
+
convert it. An Oyster deployed on 0.2 and redeployed on 0.3 answers every
|
|
179
|
+
request with `409` and `{"error": "store_from_older_oyster", ...}` (a short
|
|
180
|
+
explanation page in a browser), and `oyster install-apps` prints the same
|
|
181
|
+
message. Old data is left untouched, so redeploying 0.2.x brings the Oyster back
|
|
182
|
+
exactly as it was.
|
|
183
|
+
|
|
184
|
+
To move to 0.3, start from a fresh store. The smallest way is to deploy under
|
|
185
|
+
new names, leaving the old Oyster in place until you no longer need it. In
|
|
186
|
+
`wrangler.jsonc`, rename `name`, both `bucket_name` values,
|
|
187
|
+
`artifacts.namespace` and every `workflows[].name`; create the new release
|
|
188
|
+
bucket; then run the quick start again. To reuse the names instead, tear the old
|
|
189
|
+
Oyster down as in the teardown steps above (delete the Worker, which deletes its
|
|
190
|
+
Durable Object data; empty and delete the release bucket; delete the Computer's
|
|
191
|
+
container application, the Workflow, and the Artifacts repositories and
|
|
192
|
+
namespace), then deploy 0.3 and reinstall the Apps. Data in the old Oyster, such
|
|
193
|
+
as Apps' stored data, is not carried over.
|
|
194
|
+
|
|
195
|
+
### Set the Oyster owner key
|
|
196
|
+
|
|
197
|
+
Choose an owner key (separate from the Cloudflare API token) and store it as a
|
|
198
|
+
secret:
|
|
109
199
|
|
|
110
200
|
```sh
|
|
111
201
|
export OYSTER_OWNER_KEY=$(openssl rand -hex 24)
|
|
@@ -532,13 +622,16 @@ returns an `AdmittedGit`; the door forwards reads to `.read` and pushes to
|
|
|
532
622
|
builds these ports from `host.auth`, `host.installations` and `host.git`, so
|
|
533
623
|
most hosts set `host.git` and never call `createGitDoor` directly.
|
|
534
624
|
|
|
535
|
-
A host
|
|
536
|
-
`oysterGitRoot` or `oysterWorkerGit` options.
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
625
|
+
A host whose Workflow run owner issues Workflow Git credentials supplies
|
|
626
|
+
`workflowGitPass` in `oysterGitRoot` or `oysterWorkerGit` options. The run owner
|
|
627
|
+
issues one credential per native command of an admitted Git step and gives it
|
|
628
|
+
only to that command's Git environment. It travels only as an
|
|
629
|
+
`Authorization: Bearer` header starting with Braid's `workflowGitPassPrefix`
|
|
630
|
+
(`wgp.`) on the ordinary credential-free door URL; it is never part of a URL.
|
|
631
|
+
That header is admitted only by the port, for one repository and scope, as the
|
|
632
|
+
arming member under the Workflow's branch grant, and never as a session or key.
|
|
633
|
+
It stops working when its command closes or its run ends. Pushes outside those
|
|
634
|
+
branches are refused before the App's push policy runs.
|
|
542
635
|
|
|
543
636
|
### Provide App capabilities
|
|
544
637
|
|
|
@@ -684,6 +777,33 @@ disconnects one. These routes are owner-direct and reject an App installation
|
|
|
684
777
|
header. A server that is down or refuses the token is left out of that run and
|
|
685
778
|
the others stay available. OAuth sign-in is not offered yet.
|
|
686
779
|
|
|
780
|
+
### Give an Agent a browser
|
|
781
|
+
|
|
782
|
+
Declare a Cloudflare Browser Rendering binding and every Agent gets a
|
|
783
|
+
`cloudBrowser` tool for public pages: `open` a driven session (optionally at a
|
|
784
|
+
URL), `navigate`, read it with `snapshot` (a bounded accessibility-tree
|
|
785
|
+
summary), `click`, `type`, `press`, `scroll`, and `close` it.
|
|
786
|
+
|
|
787
|
+
```jsonc
|
|
788
|
+
// wrangler.jsonc
|
|
789
|
+
"browser": { "binding": "BROWSER" }
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
Every URL the Agent supplies must be http(s), carry no credentials and resolve
|
|
793
|
+
to a public address; anything else is refused before the browser sees it. A
|
|
794
|
+
standalone Oyster allows two open sessions at once, closes one after 5 idle
|
|
795
|
+
minutes or 30 minutes in all, and is billed by Cloudflare to the owner's
|
|
796
|
+
account. Without the binding the tool is absent.
|
|
797
|
+
|
|
798
|
+
Hosts compose the same module, `@fungi.computer/oyster/browser`, behind one port
|
|
799
|
+
(`BrowserHost`): a provider (`bindingSessions(env.BROWSER)`, or
|
|
800
|
+
`browserRunSessions` with a Browser Run account token, which also enables the
|
|
801
|
+
`markdown`/`links`/`scrape`/`extract` Quick Reads), a required metering owner
|
|
802
|
+
and an event sink. `createBrowser` owns lease ownership, the URL policy, reaping
|
|
803
|
+
and billing order; `browserCapabilitySource` is the Agent tool. The Agent never
|
|
804
|
+
reaches raw CDP or runs script in the page. See the
|
|
805
|
+
[API reference](docs/api/browser.md).
|
|
806
|
+
|
|
687
807
|
### Pack an App
|
|
688
808
|
|
|
689
809
|
`packRelease` composes `oyster/build`'s source capture, candidate preparer,
|
|
@@ -748,50 +868,35 @@ install-or-select owner installs it (201) or, when the installation already
|
|
|
748
868
|
exists, switches it to that Release (200); the App keeps its state, and every
|
|
749
869
|
other refusal is returned unchanged.
|
|
750
870
|
|
|
871
|
+
Pending installation commands retain their exact baseline, reduced plan and
|
|
872
|
+
preparation evidence for recovery. Settlement replaces those payloads with the
|
|
873
|
+
request's input digest, correlation, settlement time and recorded outcome. The
|
|
874
|
+
existing Registry alarm deletes superseded settled journal entries in bounded
|
|
875
|
+
batches after 90 days from their own settlement. The latest settled entry per
|
|
876
|
+
effective installation is always pinned, including while newer work is pending.
|
|
877
|
+
Indexed durable deadlines re-arm the same alarm when idle; pending recovery is
|
|
878
|
+
never age-deleted. Expiry removes App journal history, not canonical
|
|
879
|
+
installations, Releases, artifact bytes or Watchdog's private job history. An
|
|
880
|
+
expired operation is no longer readable; re-admitting its ID is refused as
|
|
881
|
+
`unavailable` when Watchdog still retains that job, rather than creating pending
|
|
882
|
+
work that cannot execute. A new intent needs a new request ID.
|
|
883
|
+
|
|
884
|
+
A retained successful receipt keeps its original generation, instance and
|
|
885
|
+
authority-version reference. Its `installation` is resolved only from the exact
|
|
886
|
+
current canonical selection; after removal, generation change or selection drift
|
|
887
|
+
it is `null`, while the original success remains recorded. Completion helpers
|
|
888
|
+
return `409 installation_result_unavailable` in that case, and the standalone
|
|
889
|
+
installer does not approve defaults from historical success. Settled history is
|
|
890
|
+
never an executable recovery command. Stores containing superseded preview
|
|
891
|
+
journal shapes require separately authorized current-contract republishing, not
|
|
892
|
+
an in-place conversion.
|
|
893
|
+
|
|
751
894
|
## Build a shell
|
|
752
895
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
| Entry | Contract |
|
|
758
|
-
| ------------------------ | ----------------------------------------------------------------------------------- |
|
|
759
|
-
| `./shell/workbench` | Workbench host contract, shared child-window host, Gill layout and arranger shapes. |
|
|
760
|
-
| `./shell/command-host` | A Whistle graph that admits mounted commands against verified Release declarations. |
|
|
761
|
-
| `./shell/keys` | DOM key dispatch and shared chord matching. |
|
|
762
|
-
| `./shell/commands` | Window, App picker and command palette declarations over host callbacks. |
|
|
763
|
-
| `./shell/window-manager` | Window generations, visibility, navigation, cancellation and disposal. |
|
|
764
|
-
| `./shell/app-directory` | App addresses, reusable directory rows and catalog metadata. |
|
|
765
|
-
|
|
766
|
-
`./shell/shell-module` is the contract between a host and the shell it runs, and
|
|
767
|
-
is imported on its own rather than through `./shell`. A shell Release exports
|
|
768
|
-
`mountShell(root, input)` (`MountShell`); `input` (`ShellMountInput`) carries
|
|
769
|
-
the workbench handle, the shell installation's `AppStorage` and
|
|
770
|
-
`methods.call(method, input)` for its declared backend methods, which takes the
|
|
771
|
-
input as JSON text and resolves with the decoded JSON result.
|
|
772
|
-
`importShellModule(moduleUrl, hostOrigin)` imports the picked shell's module
|
|
773
|
-
from the host's own origin, checks that it exports `mountShell`, and rejects
|
|
774
|
-
with `ShellModuleError` otherwise. The host never bundles a shell.
|
|
775
|
-
|
|
776
|
-
Supply your own mount adapter to `createWindowManager`. It receives the
|
|
777
|
-
container, launch descriptor, cancellation signal and navigation callbacks; its
|
|
778
|
-
returned handle owns visibility, reconfiguration and disposal. The manager
|
|
779
|
-
disposes stale mounts and serializes changes to each window. It neither picks
|
|
780
|
-
Apps nor grants capabilities.
|
|
781
|
-
|
|
782
|
-
`createAppSurfaceCommandHost` owns command contribution and focus. Give
|
|
783
|
-
`mount(id, declarations)` the verified Release's declarations and pass the
|
|
784
|
-
returned handlers to Agar's `connectAppHost`. A mounted App cannot introduce an
|
|
785
|
-
undeclared command or claim the reserved shell chord. Dispose its command mount
|
|
786
|
-
when its iframe closes, and dispose the command host with the shell.
|
|
787
|
-
`installShellKeys` attaches DOM listeners only when called; its return value
|
|
788
|
-
removes them. Terminal shells can use the command and window owners without a
|
|
789
|
-
DOM.
|
|
790
|
-
|
|
791
|
-
Directory metadata is not launch authority. A host extends the public row schema
|
|
792
|
-
with its own permission model and admits each mount itself. Fungi's Team
|
|
793
|
-
directory, Team settings capability and signed Hub/host protocol live in its
|
|
794
|
-
private consumers; the public shell imports none of them.
|
|
896
|
+
The shell client lives in its own package,
|
|
897
|
+
[`@fungi.computer/nacre`](../nacre/README.md): workbench host, command host,
|
|
898
|
+
keys, commands, window manager, App directory rows and the shell-module
|
|
899
|
+
contract. Oyster's page uses it; a shell imports it directly.
|
|
795
900
|
|
|
796
901
|
`@fungi.computer/oyster/page` mounts one installed App's page and connects its
|
|
797
902
|
sandboxed frame with that installation's admitted slots. That page is only the
|
|
@@ -894,6 +999,57 @@ table names.
|
|
|
894
999
|
|
|
895
1000
|
### Durable Object composition
|
|
896
1001
|
|
|
1002
|
+
Activation is host-gated before selection writes or aborting the old version.
|
|
1003
|
+
The candidate backend loads in a unique isolate over one bounded disposable
|
|
1004
|
+
sibling facet, `candidate`, with denied test bindings and no outbound network.
|
|
1005
|
+
The lifecycle supplies its already-read prior state schema: first activation
|
|
1006
|
+
uses empty SQLite; an initialized Instance requires the native facets API to
|
|
1007
|
+
copy `app` into `candidate` before construction. A host without clone support
|
|
1008
|
+
refuses that check rather than substituting fresh storage. Cleanup aborts and
|
|
1009
|
+
deletes the sibling, and Instance purge also deletes that known name. The copy
|
|
1010
|
+
is a construction test, not a backup or data rollback. It cannot become the live
|
|
1011
|
+
facet and contains no supervisor selection, authority, Team App storage, or live
|
|
1012
|
+
bindings. Native copying and isolation require the qualified runtime proof; the
|
|
1013
|
+
fresh-SQLite Node adapter is not that proof. The host also checks the immutable
|
|
1014
|
+
UI entry in a zero-grant browser session (`reportBootPage` with
|
|
1015
|
+
`checkBootPage`): the page opens the pinned `/_boot/<release>/` route on the
|
|
1016
|
+
host's own origin (https, or http only on loopback) with a short-lived
|
|
1017
|
+
capability, and every request to any other origin is blocked. The UI result is
|
|
1018
|
+
reported, never authority: a page that did not mount is `failed`, and a missing
|
|
1019
|
+
browser, a timeout, unconfirmed cleanup or an unavailable runner is
|
|
1020
|
+
`not_checked`. An App manifest, callback or healthy flag cannot supply the
|
|
1021
|
+
verdict. This is construction and UI-mount qualification, not an HTTP request
|
|
1022
|
+
smoke, execution against live storage, or a data rewind.
|
|
1023
|
+
|
|
1024
|
+
Each check owns one provider session and confirms it closed before reporting;
|
|
1025
|
+
unconfirmed closure reports `boot_cleanup_failed`, and Browser Run's
|
|
1026
|
+
`keep_alive` remains the backstop.
|
|
1027
|
+
|
|
1028
|
+
`pnpm run test:recovery-copy:celld` exercises the actual construction helper
|
|
1029
|
+
with synthetic App state, a successful copy and a constructor refusal. It checks
|
|
1030
|
+
live state preservation, denied bindings/outbound access, supervisor separation
|
|
1031
|
+
and empty storage on reopening the cleaned sibling. It does not prove physical
|
|
1032
|
+
file/stream deletion, restart recovery, or owner selection.
|
|
1033
|
+
|
|
1034
|
+
The disposable both-host proof is
|
|
1035
|
+
`bash apps/hub/scripts/check-app-boot-native.sh` from the repository root, after
|
|
1036
|
+
the affected dependency and Oyster builds. It requires Linux network namespaces,
|
|
1037
|
+
passwordless local `sudo`, the pinned celld binary and provisioned Playwright
|
|
1038
|
+
Chromium. Inside an unnamed private network it drives a local Chromium through
|
|
1039
|
+
the same `checkBootPage` both hosts use (a test-only provider in Browser Run's
|
|
1040
|
+
devtools API shape) and fresh local fixture storage; it does not install a
|
|
1041
|
+
service, contact a live host or exercise an App's HTTP handler. It checks real
|
|
1042
|
+
construction and ordinary Agar UI mounting through each host's `/_boot/` route,
|
|
1043
|
+
native facet cleanup, closed browser sessions, retained selections on refusal,
|
|
1044
|
+
forged verdicts, wrapper tampering and browser unavailability.
|
|
1045
|
+
|
|
1046
|
+
The Hub's real Team default-provisioning selection path is qualified separately
|
|
1047
|
+
with `bash apps/hub/scripts/check-app-boot-native.sh --publication`, under the
|
|
1048
|
+
same prerequisites. Its five host-dependent cases use fresh native resources,
|
|
1049
|
+
the maintained artifact writer/readback and immutable R2 object versions. Other
|
|
1050
|
+
domain-test metadata seeds are not host proof. This leg qualifies selection
|
|
1051
|
+
admission, not downstream projection delivery or deployment.
|
|
1052
|
+
|
|
897
1053
|
`createCloudflareAppInstance` keeps supervisor state in a SQLite Durable Object
|
|
898
1054
|
and runs the backend in a named `app` facet loaded through the Worker Loader.
|
|
899
1055
|
Supervisor metadata and the backend's database are separate, and a new Release
|
|
@@ -1050,14 +1206,133 @@ capture does not rebase paths to the App directory. The nearest `package.json`
|
|
|
1050
1206
|
above the entry supplies `fungi.app`, plus `fungi.backendDefinition` for an API
|
|
1051
1207
|
derived from the compiled backend.
|
|
1052
1208
|
|
|
1209
|
+
An App owns its recipe in `package.json#fungi.build`, alongside its existing
|
|
1210
|
+
page policy (`react`, `stylesheets`, and dependency build declarations). Recipe
|
|
1211
|
+
paths in that metadata are relative to the App's own directory. The Node-only
|
|
1212
|
+
`readBuildManifest(packageJson)` decodes that one strict contract;
|
|
1213
|
+
`appBuildRecipe(manifest, directory)` roots the recipe for a captured checkout,
|
|
1214
|
+
or accepts `""` for an App at the repository root. Dependency-only metadata is
|
|
1215
|
+
still valid but cannot supply an App recipe. Unknown build fields are refused.
|
|
1216
|
+
|
|
1217
|
+
The starter installer reads metadata with `git show` from the selected commit,
|
|
1218
|
+
not from dirty checkout files. Its roster owns only App identity and source
|
|
1219
|
+
locations. The scaffold's `npm run build` deliberately reads saved working
|
|
1220
|
+
metadata before capturing those same saved files. Its template declares the
|
|
1221
|
+
ordinary npm recipe as `kind: "source-html"`, including the backend entry and
|
|
1222
|
+
asset bounds; the command does not carry another copy of that recipe.
|
|
1223
|
+
|
|
1224
|
+
**Breaking recipe contract:** `@fungi.computer/oyster/standalone/app-set` no
|
|
1225
|
+
longer exposes `StarterApp.recipe` or recipe values on `standaloneAppSet`.
|
|
1226
|
+
Callers read the selected source's `package.json` with `readBuildManifest` and
|
|
1227
|
+
materialize it with `appBuildRecipe`, both exported from
|
|
1228
|
+
`@fungi.computer/oyster/build`. The workspace metadata policy advances from
|
|
1229
|
+
`package-json-fungi-build-v3` to `package-json-fungi-build-v4`; builders refuse
|
|
1230
|
+
missing or superseded policy metadata rather than guessing a recipe.
|
|
1231
|
+
|
|
1232
|
+
**Breaking repository-registration contract:** the public
|
|
1233
|
+
`PUT /api/apps/:appId/build-source` route, which accepted an App identity in the
|
|
1234
|
+
path and caller-supplied installation, repository, and recipe fields, has been
|
|
1235
|
+
removed. Use repo-only `APPS.register({ repo })`, exposed by Bonsai as
|
|
1236
|
+
`apps.register({ repo })`. The host reads App identity and `fungi.build` recipe
|
|
1237
|
+
from the immutable main commit's root `package.json` through the shared manifest
|
|
1238
|
+
reader; callers cannot override identity or recipe. An existing repository
|
|
1239
|
+
registration retains its App identity on replay. Registration returns the App ID
|
|
1240
|
+
and exact commit without starting a build or installing a Release. No
|
|
1241
|
+
compatibility route or shim remains.
|
|
1242
|
+
|
|
1243
|
+
### Local Release installation
|
|
1244
|
+
|
|
1245
|
+
```sh
|
|
1246
|
+
export OYSTER_URL=https://your-oyster.example
|
|
1247
|
+
export OYSTER_OWNER_KEY='<your owner key>'
|
|
1248
|
+
oyster install ./dist --installation-id my-app
|
|
1249
|
+
# Or name the same Release's manifest:
|
|
1250
|
+
oyster install ./dist/release.json --installation-id my-app
|
|
1251
|
+
```
|
|
1252
|
+
|
|
1253
|
+
The CLI delegates to `installRelease` from `@fungi.computer/oyster/pack`, using
|
|
1254
|
+
the same uploader as programmatic clients. Artifacts must upload before
|
|
1255
|
+
`POST /api/installations`. Upload refusal, missing files, and non-OK
|
|
1256
|
+
installation responses exit nonzero. No key is discovered from your home
|
|
1257
|
+
directory, and this command does not provision a Computer or deploy an Oyster.
|
|
1258
|
+
|
|
1259
|
+
For repository authoring, use Bonsai's repository Settings **Make this an App**
|
|
1260
|
+
(or `apps.register({ repo })`). Commit the root `package.json#fungi.build`
|
|
1261
|
+
recipe first; dirty metadata is not registration input. The readonly App ID and
|
|
1262
|
+
editable revision/name come from registration or the latest recorded build.
|
|
1263
|
+
Status can be read using `APPS.buildStatus({ repo })` in the captured Git
|
|
1264
|
+
installation; Settings uses that selector after reload. No job returns `null`.
|
|
1265
|
+
Workflow callers use `APPS.buildStatus({ jobId })` for the particular job they
|
|
1266
|
+
started.
|
|
1267
|
+
|
|
1268
|
+
### Accepted main builds and approval-bounded installation
|
|
1269
|
+
|
|
1270
|
+
The standalone Instance's accepted-ref journal delivers the host-attested main
|
|
1271
|
+
push to Bonsai. For a registered repository, Bonsai requests the retained
|
|
1272
|
+
Trellis build-on-merge template through WORKFLOWS. Its published run owns the
|
|
1273
|
+
build, exact-source verification and installation steps and their result cards.
|
|
1274
|
+
An App's change/merge payload is not push authority. The host's Workflow-node
|
|
1275
|
+
idempotency key reuses a build job on retry or restart. A local-only Computer
|
|
1276
|
+
returns typed no_backend before creating a new job or starting a machine.
|
|
1277
|
+
|
|
1278
|
+
Only an admitted Workflow-node APPS call can install its matching successful
|
|
1279
|
+
build's recorded Release at the recorded target. Ordinary App-origin
|
|
1280
|
+
installation remains refused. Existing grants may be reused, but new permissions
|
|
1281
|
+
or anonymous exposure return needs_consent without changing the running Release.
|
|
1282
|
+
Registering a repository as an App (**Make this an App**) is the owner's consent
|
|
1283
|
+
for its merge Workflow to create that App's installation when none exists yet. A
|
|
1284
|
+
Workflow-created installation is private, with no grants and no anonymous
|
|
1285
|
+
methods. Later Workflows reuse exactly that approval and can never widen it;
|
|
1286
|
+
every grant still needs the owner's explicit consent. The build row records the
|
|
1287
|
+
outcome; status reads are read-only and no native alarm resumes installation.
|
|
1288
|
+
Workflow execution owns retries. This template has no review step, review
|
|
1289
|
+
configuration or separate consent ledger.
|
|
1290
|
+
|
|
1291
|
+
**Breaking installation contract:** Bonsai apps.install and APPS.select require
|
|
1292
|
+
the successful build's jobId alongside installationId and release. The host
|
|
1293
|
+
compares all recorded Release metadata and the target before installation.
|
|
1294
|
+
|
|
1295
|
+
**Breaking build-port contract:** consumers of
|
|
1296
|
+
`@fungi.computer/oyster/app-builds` must provide
|
|
1297
|
+
`OysterBuildComputer.buildBackend()`, returning `{ kind: "hosted" }` or
|
|
1298
|
+
`{ kind: "no_backend" }`, alongside `runBuild`. The preflight reads routing
|
|
1299
|
+
without starting a machine. The build owner's `install(jobId, decide)` invokes
|
|
1300
|
+
the host decision only for a successful job with a verified Release and pending
|
|
1301
|
+
installation target; it records that decision on the same job. Terminal
|
|
1302
|
+
installation decisions are not invoked again on replay.
|
|
1303
|
+
|
|
1304
|
+
For a source HTML build, that nearest package must itself be a pnpm workspace
|
|
1305
|
+
member, or the root package of a standalone App repository. A nested package
|
|
1306
|
+
outside the workspace inventory fails with `WorkspaceBuildError` code
|
|
1307
|
+
`non_workspace_package`; it never inherits the host package's dependency
|
|
1308
|
+
closure. Notes is an explicit workspace member with its own Agar and Zod
|
|
1309
|
+
dependencies and the builder's pinned Vite toolchain, separate from Oyster's
|
|
1310
|
+
host runtime.
|
|
1311
|
+
|
|
1312
|
+
The other tracked nested manifests are separate source inputs, not App HTML
|
|
1313
|
+
builds inside their parent workspace:
|
|
1314
|
+
|
|
1315
|
+
- `apps/bonsai/demo/koi-pond`: copied into its own demo Git repository.
|
|
1316
|
+
- `packages/create-fungi-app/template`: copied to the generated App's root.
|
|
1317
|
+
- `services/app-publisher/test/fixtures/size-hello`: a backend-only emission
|
|
1318
|
+
fixture, not a workspace HTML build.
|
|
1319
|
+
- `apps/tui/test/fixtures/fairy-ring-extension` and
|
|
1320
|
+
`runtimes/local/test/fixtures/{extension-compactor,extension-counter}`:
|
|
1321
|
+
installed extension fixtures, not App source builds.
|
|
1322
|
+
- `packages/computer/container` and
|
|
1323
|
+
`packages/cordyceps/upstream/{computerd,dofs,rpc}`: container/vendored package
|
|
1324
|
+
inputs, not App source entries.
|
|
1325
|
+
- `templates/vishnu-starter`: a standalone project template outside the pnpm
|
|
1326
|
+
workspace.
|
|
1327
|
+
|
|
1053
1328
|
A captured UI bundle uses `kind: "bundled-html"`, an `entry` ending in
|
|
1054
1329
|
`/index.html`, `assetBase: "./"`, and an explicit `assets` policy with
|
|
1055
1330
|
`maxManifestBytes`, `maxObjects`, `maxObjectBytes`, and `maxTotalBytes`. Set
|
|
1056
1331
|
`backend: null` for UI only, or supply a repository-relative `backend.entry`
|
|
1057
1332
|
with the backend runtime, export name, and compatibility date. The compiler
|
|
1058
1333
|
joins both outputs from that same snapshot. A backend-only recipe uses its
|
|
1059
|
-
Worker entry as `entry` and omits `backend.entry`.
|
|
1060
|
-
|
|
1334
|
+
Worker entry as `entry` and omits `backend.entry`. First-party HTML recipes
|
|
1335
|
+
retain their catalog-owned compilation steps.
|
|
1061
1336
|
|
|
1062
1337
|
For UI source, omit `kind` and use a closed HTML recipe entry, such as
|
|
1063
1338
|
`ui/index.html` for Notes at its repository root. It requires `assets` and
|
|
@@ -1077,9 +1352,19 @@ implicit install. Only the Computer build (`buildTeamCandidate`, composed with
|
|
|
1077
1352
|
arbitrary package code, isolated by that admitted Computer. Every other
|
|
1078
1353
|
composition, including `packRelease` and `create-fungi-app`, refuses such a
|
|
1079
1354
|
source before installing. Unknown `fungi.build` fields are refused. The policy
|
|
1080
|
-
is pinned as `package-json-fungi-build-
|
|
1355
|
+
is pinned as `package-json-fungi-build-v4` in the recipe toolchain; an executor
|
|
1081
1356
|
refuses a recipe pinned under another policy.
|
|
1082
1357
|
|
|
1358
|
+
The App's HTML module scripts, shell module and selected backend select its
|
|
1359
|
+
workspace compile roots. The maintained HTML parser and esbuild follow local
|
|
1360
|
+
runtime imports; erased type imports and authoring scripts do not pull a host
|
|
1361
|
+
package into that compilation. Declared package stylesheets are also roots. The
|
|
1362
|
+
planning pass follows code imports only; the actual Vite build retains ownership
|
|
1363
|
+
of asset loading, validation and emission. Each selected workspace package still
|
|
1364
|
+
builds its full declared products and runtime workspace dependency closure, in
|
|
1365
|
+
dependency order. Dependency manifests, hydration and the Computer-only
|
|
1366
|
+
package-script guard are unchanged.
|
|
1367
|
+
|
|
1083
1368
|
`createLocalArtifactWriter(directory, recipe.assets)` writes the App root and
|
|
1084
1369
|
all referenced UI/backend objects. It uses the supplied asset bounds and
|
|
1085
1370
|
maintained MIME metadata. Bundled UI plus a backend may hydrate a captured
|
|
@@ -1116,6 +1401,33 @@ selected tenant. Canonical member roles remain distinct from owner authority.
|
|
|
1116
1401
|
Public App reads remain available; unknown origins and policy refusals fail
|
|
1117
1402
|
closed. `ownerOrKeyTenancy` is the single-tenant case.
|
|
1118
1403
|
|
|
1404
|
+
## Machine link protocol
|
|
1405
|
+
|
|
1406
|
+
`@fungi.computer/seam/machine-link-protocol` exposes the bounded read/leave
|
|
1407
|
+
decoder and `createMachineLinkPostChannel`. The channel transports ordinary
|
|
1408
|
+
Carrier Post envelopes and their receiver receipts without rewriting cargo. The
|
|
1409
|
+
host supplies frame-byte, in-flight and acknowledgment-time limits.
|
|
1410
|
+
|
|
1411
|
+
`machineLinkDialUrl(issuer, teamId, deviceId)` and
|
|
1412
|
+
`machineLinkAudience(teamId, deviceId)` give both hosts the same GET path and
|
|
1413
|
+
Seam audience. Enrollment is separately authorized by the account owner; a
|
|
1414
|
+
native dial proves possession of the enrolled device key, not command
|
|
1415
|
+
acceptance.
|
|
1416
|
+
|
|
1417
|
+
The host still owns authenticated native sockets, currentness and connection
|
|
1418
|
+
lifetime. Call `close()` when a connection is lost; create a new channel for its
|
|
1419
|
+
successor. A closed channel, timeout or capacity failure rejects pending I/O
|
|
1420
|
+
without asserting command refusal or custody. Carrier remains the durable outbox
|
|
1421
|
+
and retry owner. In-flight state is not a persistent mailbox or a Capnweb
|
|
1422
|
+
capability table.
|
|
1423
|
+
|
|
1424
|
+
A Post acknowledgment is not Shiitake command acceptance. The Hub's home-aware
|
|
1425
|
+
Agent mail route still requires the recipient's actual Accepted receipt. Focused
|
|
1426
|
+
channel and route tests do not qualify native transport, reconnect, Hub restart
|
|
1427
|
+
or Agent execution. The rebuild now wires Local service, Team native receiver
|
|
1428
|
+
and hosted actual-home consumers together; their whole-bundle native
|
|
1429
|
+
qualification and production activation remain separate claims.
|
|
1430
|
+
|
|
1119
1431
|
## Approve an installed App's permissions
|
|
1120
1432
|
|
|
1121
1433
|
After selecting a new Release, the owner can open **App access** beside the App
|
|
@@ -1126,10 +1438,22 @@ preserved; a newly selected capability is approved within this Oyster's scope.
|
|
|
1126
1438
|
This updates the installation without reinstalling the App or changing its data.
|
|
1127
1439
|
|
|
1128
1440
|
The page sends an owner-only `PUT` to the same path, carrying the captured
|
|
1129
|
-
`authorityVersion`, Release `artifactDigest`, and
|
|
1130
|
-
`{kind:"
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1441
|
+
`storeGeneration`, `authorityVersion`, Release `artifactDigest`, and a bounded
|
|
1442
|
+
`{kind:"change-grants",changes:[{capability,grant}]}` command. Each grant
|
|
1443
|
+
contains `operations` and `resources`; `null` revokes that capability. Unnamed
|
|
1444
|
+
approvals retain their existing operation and resource ceilings. Agents, keys,
|
|
1445
|
+
visitors and App-origin requests cannot approve. A replaced store, stale
|
|
1446
|
+
Release/version or concurrent approval returns `409`; the page refreshes the
|
|
1447
|
+
facts and rebases touched edits for review. The required `InstallationStore`
|
|
1448
|
+
exposes its durable `generation()` and
|
|
1449
|
+
`compareAndPut(record, expectedVersion, expectedGeneration)`. The latter returns
|
|
1450
|
+
a serializable commit/refusal result across Durable Object RPC and checks both
|
|
1451
|
+
pins in the existing commit transaction.
|
|
1452
|
+
|
|
1453
|
+
## Breaking App send contract
|
|
1454
|
+
|
|
1455
|
+
App `AGENTS.send` requires a caller-owned `requestId`, minted once per user
|
|
1456
|
+
intent and reused unchanged on retry after an UNKNOWN outcome. The standalone
|
|
1457
|
+
adapter no longer generates a replacement. See the
|
|
1458
|
+
[App Agent send API reference](docs/overview.md#app-agent-send-api--breaking-change)
|
|
1459
|
+
for the complete input and migration note.
|
package/dist/agents.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* the App page calls. Apps reach agents through Agar's `agent.list`,
|
|
4
4
|
* `agent.manage`, `agent.read` and `agent.send` contracts, so an App written
|
|
5
5
|
* for the Hub (Grove) runs unchanged. Each agent's own transport is
|
|
6
|
-
* Shiitake's HTTP routes (`/sessions…`, `/acp`)
|
|
6
|
+
* Shiitake's HTTP routes (`/sessions…`, `/acp`) and Knapsack's Session browser
|
|
7
|
+
* transport (`/browser/…`), served by the adapter behind the same App grants.
|
|
7
8
|
*/
|
|
8
9
|
import { Hono } from "hono";
|
|
9
10
|
import type { AppToolPolicy } from "./apps/tools.js";
|
|
@@ -104,7 +105,7 @@ export type OysterAgents = Readonly<{
|
|
|
104
105
|
addMcpServer(agentId: string, input: AgentMcpServerInput): Promise<AgentMcpServer | AgentMcpServerRefusal>;
|
|
105
106
|
/** Disconnect one MCP server; `false` when the Agent or server is unknown. */
|
|
106
107
|
removeMcpServer(agentId: string, serverId: string): Promise<boolean>;
|
|
107
|
-
/** Serve
|
|
108
|
+
/** Serve this Agent's Shiitake and Knapsack Session browser transports. */
|
|
108
109
|
fetch(agentId: string, request: Request): Promise<Response | null>;
|
|
109
110
|
/** This member's Session and Workflow review rows, admitted by the host. */
|
|
110
111
|
inbox(): Promise<OysterInbox>;
|
package/dist/agents.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* the App page calls. Apps reach agents through Agar's `agent.list`,
|
|
4
4
|
* `agent.manage`, `agent.read` and `agent.send` contracts, so an App written
|
|
5
5
|
* for the Hub (Grove) runs unchanged. Each agent's own transport is
|
|
6
|
-
* Shiitake's HTTP routes (`/sessions…`, `/acp`)
|
|
6
|
+
* Shiitake's HTTP routes (`/sessions…`, `/acp`) and Knapsack's Session browser
|
|
7
|
+
* transport (`/browser/…`), served by the adapter behind the same App grants.
|
|
7
8
|
*/
|
|
8
9
|
import { Hono } from "hono";
|
|
9
10
|
import * as Schema from "effect/Schema";
|
|
@@ -205,7 +206,8 @@ function createAgentRoutes(agents) {
|
|
|
205
206
|
const path = url.pathname.slice(`/agents/${agentId}`.length);
|
|
206
207
|
if (!(path === "/acp" ||
|
|
207
208
|
path === "/sessions" ||
|
|
208
|
-
path.startsWith("/sessions/")
|
|
209
|
+
path.startsWith("/sessions/") ||
|
|
210
|
+
path.startsWith("/browser/")))
|
|
209
211
|
return refusal(404, "Not found");
|
|
210
212
|
const length = Number(incoming.headers.get("content-length") ?? "0");
|
|
211
213
|
if (length > maxAgentRequestBytes)
|