@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/dist/page/mount.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { appOpenInputSchema, appsCall, appsOpen, } from "@fungi.computer/agar/apps";
|
|
2
2
|
import { appApiMethodNameSchema } from "@fungi.computer/puffball/app";
|
|
3
3
|
import { appIdSchema } from "@fungi.computer/puffball/effect";
|
|
4
|
-
import { createBrowserActionHandler } from "
|
|
5
|
-
import { createAppSurfaceCommandHost } from "
|
|
4
|
+
import { createBrowserActionHandler } from "@fungi.computer/nacre";
|
|
5
|
+
import { createAppSurfaceCommandHost } from "@fungi.computer/nacre/command-host";
|
|
6
6
|
// App page: mounts one installed App's sandboxed frame and gives it the
|
|
7
7
|
// capabilities this Oyster host provides. Bundled into `shellScript`.
|
|
8
|
-
import { RpcTarget } from "@fungi.computer/capnweb";
|
|
8
|
+
import { RpcTarget, RpcStub } from "@fungi.computer/capnweb";
|
|
9
|
+
import { EventSource } from "eventsource";
|
|
10
|
+
import { connectBrowser, UiBrowserError, } from "@fungi.computer/knapsack/ui/browser";
|
|
9
11
|
import { createPageLifetime } from "./lifetime.js";
|
|
12
|
+
import { computerTargetUrl } from "./computer-target.js";
|
|
10
13
|
import * as Schema from "effect/Schema";
|
|
11
|
-
import { AppError } from "@fungi.computer/agar";
|
|
14
|
+
import { AppError, createCapabilityRegistry, } from "@fungi.computer/agar";
|
|
12
15
|
import { appStorage } from "@fungi.computer/agar/storage";
|
|
16
|
+
import { approvals } from "@fungi.computer/agar/approvals";
|
|
13
17
|
import { oysterStorageHandle } from "./storage.js";
|
|
14
18
|
import { appBackend, appMethods } from "@fungi.computer/agar/backend";
|
|
15
19
|
import { computerList, computerPorts, computerProcesses, computerReadFile, computerTerminal, computerWriteFile, } from "@fungi.computer/agar/computer";
|
|
16
|
-
import { agentList, agentManage, agentSessionRead, agentSessionWrite, } from "@fungi.computer/agar/agents";
|
|
20
|
+
import { agentList, agentManage, agentSessionRead, agentSessionWrite, openAppAgent, } from "@fungi.computer/agar/agents";
|
|
17
21
|
import { mediaGeneration } from "@fungi.computer/agar/media";
|
|
18
22
|
import { MediaGeneration, mediaGenerationDescriptionSchema, } from "@fungi.computer/agar/media-json";
|
|
19
23
|
import { registeredCapabilityHandle, } from "./capabilities.js";
|
|
@@ -23,6 +27,105 @@ import { parseJsonValue } from "@fungi.computer/whistle/wire";
|
|
|
23
27
|
import { appDeclaredCommandSchema } from "@fungi.computer/puffball/app";
|
|
24
28
|
import { TerminalCapability } from "./terminal.js";
|
|
25
29
|
import { ComputerPortsHandle, ComputerProcessesHandle, } from "./computer-handles.js";
|
|
30
|
+
/** One page-wide selected Session, using only its reporting App's admitted view. */
|
|
31
|
+
export class OysterAgentBrowserHost {
|
|
32
|
+
#active;
|
|
33
|
+
#disposed = false;
|
|
34
|
+
/** End the selected connection with the page's own lifetime. */
|
|
35
|
+
constructor(signal) {
|
|
36
|
+
if (signal.aborted)
|
|
37
|
+
this.dispose();
|
|
38
|
+
else
|
|
39
|
+
signal.addEventListener("abort", () => {
|
|
40
|
+
this.dispose();
|
|
41
|
+
}, { once: true });
|
|
42
|
+
}
|
|
43
|
+
/** A departing or deselecting mount cannot close a different active mount. */
|
|
44
|
+
release(frame) {
|
|
45
|
+
if (this.#active?.frame !== frame)
|
|
46
|
+
return;
|
|
47
|
+
const previous = this.#active;
|
|
48
|
+
this.#active = undefined;
|
|
49
|
+
previous.close();
|
|
50
|
+
}
|
|
51
|
+
/** Release the page's current selection; later reports cannot reconnect it. */
|
|
52
|
+
dispose() {
|
|
53
|
+
this.#disposed = true;
|
|
54
|
+
if (this.#active !== undefined)
|
|
55
|
+
this.release(this.#active.frame);
|
|
56
|
+
}
|
|
57
|
+
/** Bind the reporting mount's current command view to its explicitly selected Session. */
|
|
58
|
+
async report(frame, selection, capabilities, whistle) {
|
|
59
|
+
if (this.#disposed)
|
|
60
|
+
return;
|
|
61
|
+
if (selection === null) {
|
|
62
|
+
this.release(frame);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (this.#active !== undefined)
|
|
66
|
+
this.release(this.#active.frame);
|
|
67
|
+
// Read-only Apps may observe Sessions, but cannot claim or settle UI work.
|
|
68
|
+
if (!capabilities.has(agentSessionWrite) && !capabilities.has(agentManage))
|
|
69
|
+
return;
|
|
70
|
+
let transport;
|
|
71
|
+
let connection;
|
|
72
|
+
const failure = () => {
|
|
73
|
+
console.warn("Oyster Agent browser connection failed");
|
|
74
|
+
};
|
|
75
|
+
const active = {
|
|
76
|
+
frame,
|
|
77
|
+
close: () => {
|
|
78
|
+
connection?.close();
|
|
79
|
+
if (transport !== undefined)
|
|
80
|
+
void transport.close().catch(failure);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
this.#active = active;
|
|
84
|
+
try {
|
|
85
|
+
transport = await openAppAgent(capabilities, {
|
|
86
|
+
agentId: selection.agentId,
|
|
87
|
+
});
|
|
88
|
+
if (this.#active !== active) {
|
|
89
|
+
await transport.close();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const admitted = transport;
|
|
93
|
+
connection = connectBrowser({
|
|
94
|
+
baseUrl: `${admitted.baseUrl}/browser/sessions/${encodeURIComponent(selection.sessionId)}`,
|
|
95
|
+
whistle,
|
|
96
|
+
transport: {
|
|
97
|
+
fetch: admitted.fetch,
|
|
98
|
+
openEvents: (url) => new EventSource(url, { fetch: admitted.fetch }),
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
void connection.closed.catch((cause) => {
|
|
102
|
+
if (this.#active === active)
|
|
103
|
+
this.release(frame);
|
|
104
|
+
console.warn("Oyster Agent browser connection failed", cause instanceof UiBrowserError
|
|
105
|
+
? cause.message
|
|
106
|
+
: "Transport unavailable");
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (cause) {
|
|
110
|
+
if (this.#active === active)
|
|
111
|
+
this.release(frame);
|
|
112
|
+
throw cause;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function agentDirectory(capabilities) {
|
|
117
|
+
const directory = createCapabilityRegistry();
|
|
118
|
+
const read = capabilities.find(({ id, version }) => id === agentSessionRead.id && version === agentSessionRead.version);
|
|
119
|
+
const write = capabilities.find(({ id, version }) => id === agentSessionWrite.id && version === agentSessionWrite.version);
|
|
120
|
+
const manage = capabilities.find(({ id, version }) => id === agentManage.id && version === agentManage.version);
|
|
121
|
+
if (read !== undefined)
|
|
122
|
+
directory.provide(agentSessionRead, agentSessionRead.schema.parse(new RpcStub(read.handle)));
|
|
123
|
+
if (write !== undefined)
|
|
124
|
+
directory.provide(agentSessionWrite, agentSessionWrite.schema.parse(new RpcStub(write.handle)));
|
|
125
|
+
if (manage !== undefined)
|
|
126
|
+
directory.provide(agentManage, agentManage.schema.parse(new RpcStub(manage.handle)));
|
|
127
|
+
return directory;
|
|
128
|
+
}
|
|
26
129
|
/** Current server-admitted configuration for one installed App page. */
|
|
27
130
|
export const oysterAppConfigSchema = Schema.Struct({
|
|
28
131
|
workbench: Schema.Boolean,
|
|
@@ -59,15 +162,17 @@ async function answer(response) {
|
|
|
59
162
|
}
|
|
60
163
|
/** The App's typed methods, reached through this host's method route. */
|
|
61
164
|
class Methods extends RpcTarget {
|
|
165
|
+
computerTarget;
|
|
62
166
|
#url;
|
|
63
|
-
constructor(url) {
|
|
167
|
+
constructor(url, computerTarget) {
|
|
64
168
|
super();
|
|
169
|
+
this.computerTarget = computerTarget;
|
|
65
170
|
this.#url = url;
|
|
66
171
|
}
|
|
67
172
|
async call(method, input) {
|
|
68
173
|
const name = Schema.decodeUnknownSync(Schema.String.check(Schema.isPattern(/^[A-Za-z][A-Za-z0-9_.]{0,79}$/u)))(method);
|
|
69
174
|
const body = Schema.decodeUnknownSync(Schema.String)(input);
|
|
70
|
-
return answer(await fetch(`${this.#url}${name}`, {
|
|
175
|
+
return answer(await fetch(computerTargetUrl(`${this.#url}${name}`, this.computerTarget), {
|
|
71
176
|
method: "POST",
|
|
72
177
|
headers: { "Content-Type": "application/json" },
|
|
73
178
|
body,
|
|
@@ -81,10 +186,12 @@ class Methods extends RpcTarget {
|
|
|
81
186
|
class Calls extends RpcTarget {
|
|
82
187
|
base;
|
|
83
188
|
signal;
|
|
84
|
-
|
|
189
|
+
computerTarget;
|
|
190
|
+
constructor(base, signal, computerTarget) {
|
|
85
191
|
super();
|
|
86
192
|
this.base = base;
|
|
87
193
|
this.signal = signal;
|
|
194
|
+
this.computerTarget = computerTarget;
|
|
88
195
|
}
|
|
89
196
|
async call(appId, method, input) {
|
|
90
197
|
const target = Schema.decodeUnknownSync(appIdSchema)(appId);
|
|
@@ -96,7 +203,7 @@ class Calls extends RpcTarget {
|
|
|
96
203
|
retryable: false,
|
|
97
204
|
});
|
|
98
205
|
Schema.decodeUnknownSync(Schema.fromJsonString(Schema.Json))(body);
|
|
99
|
-
return answer(await fetch(`${this.base}${encodeURIComponent(target)}/${encodeURIComponent(name)}`, {
|
|
206
|
+
return answer(await fetch(computerTargetUrl(`${this.base}${encodeURIComponent(target)}/${encodeURIComponent(name)}`, this.computerTarget), {
|
|
100
207
|
method: "POST",
|
|
101
208
|
headers: { "Content-Type": "application/json" },
|
|
102
209
|
body,
|
|
@@ -205,11 +312,14 @@ export async function mountOysterPage() {
|
|
|
205
312
|
// The App's commands are still admitted against its Release declaration.
|
|
206
313
|
const commands = createAppSurfaceCommandHost();
|
|
207
314
|
const mount = commands.mount(config.installationId, config.commands);
|
|
315
|
+
const agentBrowser = new OysterAgentBrowserHost(lifetime.signal);
|
|
208
316
|
lifetime.own(() => {
|
|
209
317
|
commands.dispose();
|
|
210
318
|
});
|
|
211
319
|
return connectOysterApp({
|
|
212
320
|
config,
|
|
321
|
+
agentBrowser,
|
|
322
|
+
agentCommands: mount.agentCommands,
|
|
213
323
|
frame,
|
|
214
324
|
signal: lifetime.signal,
|
|
215
325
|
reservedChords: [],
|
|
@@ -234,6 +344,11 @@ export async function connectOysterApp(options) {
|
|
|
234
344
|
if (frame.contentWindow === null)
|
|
235
345
|
throw new Error("App frame is unavailable");
|
|
236
346
|
const capabilities = await oysterAppCapabilities(options);
|
|
347
|
+
const agents = agentDirectory(capabilities);
|
|
348
|
+
const releaseBrowser = () => {
|
|
349
|
+
options.agentBrowser.release(frame);
|
|
350
|
+
};
|
|
351
|
+
options.signal.addEventListener("abort", releaseBrowser, { once: true });
|
|
237
352
|
const host = await connectAppHost({
|
|
238
353
|
appWindow: frame.contentWindow,
|
|
239
354
|
expectedAppOrigin: "null",
|
|
@@ -261,6 +376,14 @@ export async function connectOysterApp(options) {
|
|
|
261
376
|
},
|
|
262
377
|
handlers: {
|
|
263
378
|
...options.handlers,
|
|
379
|
+
reportAgentSessionSelection: async (selection) => {
|
|
380
|
+
await options.agentBrowser.report(frame, selection, agents, options.agentCommands);
|
|
381
|
+
await options.handlers.reportAgentSessionSelection(selection);
|
|
382
|
+
},
|
|
383
|
+
onDisconnect: async () => {
|
|
384
|
+
releaseBrowser();
|
|
385
|
+
await options.handlers.onDisconnect();
|
|
386
|
+
},
|
|
264
387
|
requestBrowserAction: createBrowserActionHandler({
|
|
265
388
|
frame,
|
|
266
389
|
hostWindow: window,
|
|
@@ -305,11 +428,11 @@ export async function oysterAppCapabilities(options) {
|
|
|
305
428
|
let leaseExpiresAt = 0;
|
|
306
429
|
return new TerminalCapability((input) => transport("open", input), {
|
|
307
430
|
computerId: config.computerId,
|
|
308
|
-
terminalUrl: selected.terminalUrl,
|
|
431
|
+
terminalUrl: computerTargetUrl(selected.terminalUrl, options.computerTarget),
|
|
309
432
|
hostWindow: window,
|
|
310
433
|
mountSignal: options.signal,
|
|
311
434
|
ensureAccess: Object.assign(async (signal) => {
|
|
312
|
-
const response = await fetch(`/apps/${encodeURIComponent(config.installationId)}/`, {
|
|
435
|
+
const response = await fetch(computerTargetUrl(`/apps/${encodeURIComponent(config.installationId)}/`, options.computerTarget), {
|
|
313
436
|
headers: { Accept: "application/json" },
|
|
314
437
|
credentials: "same-origin",
|
|
315
438
|
cache: "no-store",
|
|
@@ -325,11 +448,18 @@ export async function oysterAppCapabilities(options) {
|
|
|
325
448
|
retryable: false,
|
|
326
449
|
});
|
|
327
450
|
leaseExpiresAt = Date.now() + 60_000;
|
|
328
|
-
|
|
451
|
+
const selected = terminalSelection(current);
|
|
452
|
+
return {
|
|
453
|
+
...selected,
|
|
454
|
+
terminalUrl: selected.terminalUrl === null
|
|
455
|
+
? null
|
|
456
|
+
: computerTargetUrl(selected.terminalUrl, options.computerTarget),
|
|
457
|
+
};
|
|
329
458
|
}, { leaseExpiresAt: () => leaseExpiresAt }),
|
|
330
459
|
});
|
|
331
460
|
},
|
|
332
461
|
},
|
|
462
|
+
{ contract: approvals },
|
|
333
463
|
{ contract: agentList },
|
|
334
464
|
{ contract: agentManage },
|
|
335
465
|
{ contract: agentSessionRead },
|
|
@@ -357,7 +487,7 @@ export async function oysterAppCapabilities(options) {
|
|
|
357
487
|
return [
|
|
358
488
|
Promise.resolve({
|
|
359
489
|
...appsCall,
|
|
360
|
-
handle: new Calls(base, options.signal),
|
|
490
|
+
handle: new Calls(base, options.signal, options.computerTarget),
|
|
361
491
|
}),
|
|
362
492
|
];
|
|
363
493
|
}
|
|
@@ -368,14 +498,20 @@ export async function oysterAppCapabilities(options) {
|
|
|
368
498
|
return [];
|
|
369
499
|
}
|
|
370
500
|
return [
|
|
371
|
-
registeredCapabilityHandle(registration, descriptor, config.installationId).then((handle) => ({ ...registration.contract, handle })),
|
|
501
|
+
registeredCapabilityHandle(registration, descriptor, config.installationId, options.computerTarget).then((handle) => ({ ...registration.contract, handle })),
|
|
372
502
|
];
|
|
373
503
|
}));
|
|
374
504
|
if (unknownCapabilities.length > 0)
|
|
375
505
|
document.body.dataset.oysterCapability = unknownCapabilities.join(", ");
|
|
376
506
|
const resolved = [
|
|
377
|
-
{
|
|
378
|
-
|
|
507
|
+
{
|
|
508
|
+
...appBackend,
|
|
509
|
+
handle: new Backend(computerTargetUrl(config.backendUrl, options.computerTarget)),
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
...appMethods,
|
|
513
|
+
handle: new Methods(config.methodsUrl, options.computerTarget),
|
|
514
|
+
},
|
|
379
515
|
...capabilities,
|
|
380
516
|
...(config.appsOpen && options.appOpen
|
|
381
517
|
? [{ ...appsOpen, handle: new AppOpen(options.appOpen) }]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { HTTPException } from "hono/http-exception";
|
|
2
|
+
/**
|
|
3
|
+
* Project the generated module's fields without exposing its private module name.
|
|
4
|
+
* The generated module remains the sole page-source contract.
|
|
5
|
+
* @inline
|
|
6
|
+
*/
|
|
7
|
+
export type PageAssetSources = {
|
|
8
|
+
[Key in keyof typeof import("#page-script")]: (typeof import("#page-script"))[Key];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Acquire page sources only when a host page or asset request needs them.
|
|
12
|
+
*/
|
|
13
|
+
export type PageAssetLoader = () => Promise<PageAssetSources>;
|
|
14
|
+
/** A failed acquisition refuses this request without exposing loader details. */
|
|
15
|
+
export declare class PageAssetsLoadError extends HTTPException {
|
|
16
|
+
constructor(cause: unknown);
|
|
17
|
+
getResponse(): Response;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Missing page sources must fail the request, never produce an empty script.
|
|
21
|
+
*/
|
|
22
|
+
export declare const loadPageAssets: PageAssetLoader;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { HTTPException } from "hono/http-exception";
|
|
2
|
+
/** A failed acquisition refuses this request without exposing loader details. */
|
|
3
|
+
export class PageAssetsLoadError extends HTTPException {
|
|
4
|
+
constructor(cause) {
|
|
5
|
+
super(503, { message: "Host page assets unavailable", cause });
|
|
6
|
+
}
|
|
7
|
+
getResponse() {
|
|
8
|
+
// Concurrent callers share the failure, not a one-use response body.
|
|
9
|
+
return new Response(this.message, {
|
|
10
|
+
status: this.status,
|
|
11
|
+
headers: {
|
|
12
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
13
|
+
"Cache-Control": "no-store",
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Missing page sources must fail the request, never produce an empty script.
|
|
20
|
+
*/
|
|
21
|
+
export const loadPageAssets = async () => {
|
|
22
|
+
try {
|
|
23
|
+
return await import("#page-script");
|
|
24
|
+
}
|
|
25
|
+
catch (cause) {
|
|
26
|
+
throw new PageAssetsLoadError(cause);
|
|
27
|
+
}
|
|
28
|
+
};
|
package/dist/page-script.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ export declare const publicHomeScript: string;
|
|
|
7
7
|
/** Shared host fonts, served once as a digest-pinned stylesheet. */
|
|
8
8
|
export declare const fontStyles: string;
|
|
9
9
|
|
|
10
|
+
/** The sans family alone, for the sign-in page. */
|
|
11
|
+
export declare const loginFontStyles: string;
|
|
12
|
+
|
|
10
13
|
/** Caps styles for server-rendered host pages. */
|
|
11
14
|
export declare const shellStyles: string;
|
|
12
15
|
|