@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/dist/release.d.ts
CHANGED
|
@@ -9,6 +9,17 @@ export type ArtifactStore = Readonly<{
|
|
|
9
9
|
/** Store bytes under `artifactRef`; the caller has verified the digest. */
|
|
10
10
|
put: (artifactRef: ArtifactRef, bytes: Uint8Array) => Promise<void>;
|
|
11
11
|
}>;
|
|
12
|
+
/** What a store knows of one object without reading it. */
|
|
13
|
+
export type ArtifactHead = Readonly<{
|
|
14
|
+
byteLength: number;
|
|
15
|
+
/** The digest the store verified when it took the bytes, if it did. */
|
|
16
|
+
digest: Sha256Digest | null;
|
|
17
|
+
}>;
|
|
18
|
+
/** A store that can describe an object without reading its bytes. */
|
|
19
|
+
export type ArtifactHeads = Readonly<{
|
|
20
|
+
/** Describe the object at `artifactRef`, or `null` when absent. */
|
|
21
|
+
head: (artifactRef: ArtifactRef) => Promise<ArtifactHead | null>;
|
|
22
|
+
}>;
|
|
12
23
|
/** Why a Release could not be read; the host maps it to an HTTP refusal. */
|
|
13
24
|
export declare class ReleaseError extends Error {
|
|
14
25
|
readonly code: "artifact_missing" | "digest_mismatch" | "invalid_release" | "asset_missing";
|
package/dist/release.js
CHANGED
|
@@ -79,8 +79,11 @@ readAssets = true) {
|
|
|
79
79
|
catch (cause) {
|
|
80
80
|
throw new ReleaseError("invalid_release", "Invalid assets", { cause });
|
|
81
81
|
}
|
|
82
|
+
// One asset at a time: a Release's assets together can exceed an
|
|
83
|
+
// isolate's memory, each alone is bounded by its policy.
|
|
82
84
|
if (readAssets)
|
|
83
|
-
|
|
85
|
+
for (const asset of assets.assets)
|
|
86
|
+
await readVerified(store, asset.artifactRef, asset.digest);
|
|
84
87
|
ui = { kind: "assets", build: assets };
|
|
85
88
|
}
|
|
86
89
|
else
|
|
@@ -2,23 +2,23 @@ import * as Schema from "effect/Schema";
|
|
|
2
2
|
import { appDeclaredGillSchema } from "@fungi.computer/gills";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
/** An App address selects a host default or a specific installation. */
|
|
5
|
-
export declare const appAddressSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
5
|
+
export declare const appAddressSchema: z.ZodLazy<z.ZodUnion<readonly [z.ZodObject<{
|
|
6
6
|
kind: z.ZodLiteral<"default">;
|
|
7
7
|
appId: z.ZodString;
|
|
8
8
|
}, z.core.$strict>, z.ZodObject<{
|
|
9
9
|
kind: z.ZodLiteral<"installation">;
|
|
10
10
|
installationId: z.ZodString;
|
|
11
|
-
}, z.core.$strict>]
|
|
11
|
+
}, z.core.$strict>]>>;
|
|
12
12
|
/** Host-reported progress of applying a revised App authority version. */
|
|
13
|
-
export declare const appAuthorityEnforcementSchema: z.ZodObject<{
|
|
13
|
+
export declare const appAuthorityEnforcementSchema: z.ZodLazy<z.ZodObject<{
|
|
14
14
|
requestId: z.ZodString;
|
|
15
|
-
address: z.ZodUnion<readonly [z.ZodObject<{
|
|
15
|
+
address: z.ZodLazy<z.ZodUnion<readonly [z.ZodObject<{
|
|
16
16
|
kind: z.ZodLiteral<"default">;
|
|
17
17
|
appId: z.ZodString;
|
|
18
18
|
}, z.core.$strict>, z.ZodObject<{
|
|
19
19
|
kind: z.ZodLiteral<"installation">;
|
|
20
20
|
installationId: z.ZodString;
|
|
21
|
-
}, z.core.$strict>]
|
|
21
|
+
}, z.core.$strict>]>>;
|
|
22
22
|
authorityVersion: z.ZodNumber;
|
|
23
23
|
state: z.ZodEnum<{
|
|
24
24
|
unaffected: "unaffected";
|
|
@@ -27,7 +27,7 @@ export declare const appAuthorityEnforcementSchema: z.ZodObject<{
|
|
|
27
27
|
expired: "expired";
|
|
28
28
|
}>;
|
|
29
29
|
outstanding: z.ZodNumber;
|
|
30
|
-
}, z.core.$strict
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
31
|
/** Decoded address of a default App or an installation. */
|
|
32
32
|
export type AppAddress = z.output<typeof appAddressSchema>;
|
|
33
33
|
/** Stable identity of one App address across directory and settings views. */
|
|
@@ -43,13 +43,13 @@ export type AppDirectoryGill = {
|
|
|
43
43
|
};
|
|
44
44
|
/** Reusable App metadata supplied by an embedding host; it conveys no permissions. */
|
|
45
45
|
export declare const appDirectoryEntrySchema: z.ZodObject<{
|
|
46
|
-
address: z.ZodUnion<readonly [z.ZodObject<{
|
|
46
|
+
address: z.ZodLazy<z.ZodUnion<readonly [z.ZodObject<{
|
|
47
47
|
kind: z.ZodLiteral<"default">;
|
|
48
48
|
appId: z.ZodString;
|
|
49
49
|
}, z.core.$strict>, z.ZodObject<{
|
|
50
50
|
kind: z.ZodLiteral<"installation">;
|
|
51
51
|
installationId: z.ZodString;
|
|
52
|
-
}, z.core.$strict>]
|
|
52
|
+
}, z.core.$strict>]>>;
|
|
53
53
|
installationId: z.ZodNullable<z.ZodString>;
|
|
54
54
|
surfaceId: z.ZodString;
|
|
55
55
|
appId: z.ZodString;
|
|
@@ -57,15 +57,15 @@ export declare const appDirectoryEntrySchema: z.ZodObject<{
|
|
|
57
57
|
icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
58
58
|
releaseId: z.ZodNullable<z.ZodString>;
|
|
59
59
|
authorityVersion: z.ZodNumber;
|
|
60
|
-
enforcement: z.ZodNullable<z.ZodObject<{
|
|
60
|
+
enforcement: z.ZodNullable<z.ZodLazy<z.ZodObject<{
|
|
61
61
|
requestId: z.ZodString;
|
|
62
|
-
address: z.ZodUnion<readonly [z.ZodObject<{
|
|
62
|
+
address: z.ZodLazy<z.ZodUnion<readonly [z.ZodObject<{
|
|
63
63
|
kind: z.ZodLiteral<"default">;
|
|
64
64
|
appId: z.ZodString;
|
|
65
65
|
}, z.core.$strict>, z.ZodObject<{
|
|
66
66
|
kind: z.ZodLiteral<"installation">;
|
|
67
67
|
installationId: z.ZodString;
|
|
68
|
-
}, z.core.$strict>]
|
|
68
|
+
}, z.core.$strict>]>>;
|
|
69
69
|
authorityVersion: z.ZodNumber;
|
|
70
70
|
state: z.ZodEnum<{
|
|
71
71
|
unaffected: "unaffected";
|
|
@@ -74,7 +74,7 @@ export declare const appDirectoryEntrySchema: z.ZodObject<{
|
|
|
74
74
|
expired: "expired";
|
|
75
75
|
}>;
|
|
76
76
|
outstanding: z.ZodNumber;
|
|
77
|
-
}, z.core.$strict
|
|
77
|
+
}, z.core.$strict>>>;
|
|
78
78
|
handlers: z.ZodArray<z.ZodLiteral<"file.open">>;
|
|
79
79
|
roles: z.ZodArray<z.ZodString>;
|
|
80
80
|
declaredCapabilities: z.ZodArray<z.ZodString>;
|
|
@@ -132,14 +132,8 @@ export declare const appRoleSelectionSchema: z.ZodObject<{
|
|
|
132
132
|
surfaceId: z.ZodNullable<z.ZodString>;
|
|
133
133
|
chosen: z.ZodBoolean;
|
|
134
134
|
}, z.core.$strict>;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"computer.readFile": "computer.readFile";
|
|
138
|
-
"computer.writeFile": "computer.writeFile";
|
|
139
|
-
"computer.execute": "computer.execute";
|
|
140
|
-
}>;
|
|
141
|
-
export type AppComputerOperation = z.output<typeof appComputerOperationSchema>;
|
|
142
|
-
export declare const appComputerPermissionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
135
|
+
/** App Computer permissions limited to selected Computers or the Team's Computers. */
|
|
136
|
+
export declare const appComputerPermissionSchema: z.ZodDiscriminatedUnion<[z.ZodLazy<z.ZodObject<{
|
|
143
137
|
kind: z.ZodLiteral<"selected-computers">;
|
|
144
138
|
computers: z.ZodArray<z.ZodObject<{
|
|
145
139
|
computerId: z.ZodString;
|
|
@@ -150,7 +144,7 @@ export declare const appComputerPermissionSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
150
144
|
"computer.execute": "computer.execute";
|
|
151
145
|
}>>;
|
|
152
146
|
}, z.core.$strict>>;
|
|
153
|
-
}, z.core.$strict
|
|
147
|
+
}, z.core.$strict>>, z.ZodLazy<z.ZodObject<{
|
|
154
148
|
kind: z.ZodLiteral<"all-team-computers">;
|
|
155
149
|
operations: z.ZodArray<z.ZodEnum<{
|
|
156
150
|
"computer.list": "computer.list";
|
|
@@ -158,8 +152,14 @@ export declare const appComputerPermissionSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
158
152
|
"computer.writeFile": "computer.writeFile";
|
|
159
153
|
"computer.execute": "computer.execute";
|
|
160
154
|
}>>;
|
|
161
|
-
}, z.core.$strict
|
|
155
|
+
}, z.core.$strict>>], "kind">;
|
|
156
|
+
/** One operation an App may request for a Computer. */
|
|
157
|
+
export type AppComputerOperation = Extract<z.output<typeof appComputerPermissionSchema>, {
|
|
158
|
+
kind: "all-team-computers";
|
|
159
|
+
}>["operations"][number];
|
|
160
|
+
/** Decoded Computer permission scope attached to an App directory entry. */
|
|
162
161
|
export type AppComputerPermission = z.output<typeof appComputerPermissionSchema>;
|
|
162
|
+
/** Agent directory and session operations an App may request from its host. */
|
|
163
163
|
export declare const appAgentPermissionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
164
164
|
kind: z.ZodLiteral<"all-team-agents">;
|
|
165
165
|
directoryOperations: z.ZodArray<z.ZodEnum<{
|
|
@@ -184,23 +184,28 @@ export declare const appAgentPermissionSchema: z.ZodDiscriminatedUnion<[z.ZodObj
|
|
|
184
184
|
}>>;
|
|
185
185
|
}, z.core.$strict>>;
|
|
186
186
|
}, z.core.$strict>], "kind">;
|
|
187
|
+
/** Decoded Agent permission scope attached to an App directory entry. */
|
|
187
188
|
export type AppAgentPermission = z.output<typeof appAgentPermissionSchema>;
|
|
189
|
+
/** Whether an App may use language-model and media generation services. */
|
|
188
190
|
export declare const appGenerationPermissionsSchema: z.ZodObject<{
|
|
189
191
|
llm: z.ZodBoolean;
|
|
190
192
|
media: z.ZodBoolean;
|
|
191
193
|
}, z.core.$strict>;
|
|
194
|
+
/** Decoded generation permissions attached to an App directory entry. */
|
|
192
195
|
export type AppGenerationPermissions = z.output<typeof appGenerationPermissionsSchema>;
|
|
196
|
+
/** Whether an App may browse, buy, or install free marketplace entries. */
|
|
193
197
|
export declare const appMarketplacePermissionsSchema: z.ZodObject<{
|
|
194
198
|
browse: z.ZodBoolean;
|
|
195
199
|
purchase: z.ZodBoolean;
|
|
196
200
|
installFree: z.ZodBoolean;
|
|
197
201
|
}, z.core.$strict>;
|
|
202
|
+
/** Decoded marketplace permissions attached to an App directory entry. */
|
|
198
203
|
export type AppMarketplacePermissions = z.output<typeof appMarketplacePermissionsSchema>;
|
|
199
204
|
/**
|
|
200
205
|
* A host's Team App directory with its permission projection, parsed strictly
|
|
201
206
|
* by every consumer: an unknown field is a contract change both sides make.
|
|
202
207
|
*/
|
|
203
|
-
export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
208
|
+
export declare const appDirectoryResponseSchema: z.ZodLazy<z.ZodObject<{
|
|
204
209
|
actorIsTeamOwner: z.ZodBoolean;
|
|
205
210
|
needsUpdate: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
206
211
|
installationId: z.ZodNullable<z.ZodString>;
|
|
@@ -208,13 +213,13 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
|
208
213
|
displayName: z.ZodString;
|
|
209
214
|
}, z.core.$strict>>>;
|
|
210
215
|
apps: z.ZodArray<z.ZodObject<{
|
|
211
|
-
address: z.ZodUnion<readonly [z.ZodObject<{
|
|
216
|
+
address: z.ZodLazy<z.ZodUnion<readonly [z.ZodObject<{
|
|
212
217
|
kind: z.ZodLiteral<"default">;
|
|
213
218
|
appId: z.ZodString;
|
|
214
219
|
}, z.core.$strict>, z.ZodObject<{
|
|
215
220
|
kind: z.ZodLiteral<"installation">;
|
|
216
221
|
installationId: z.ZodString;
|
|
217
|
-
}, z.core.$strict>]
|
|
222
|
+
}, z.core.$strict>]>>;
|
|
218
223
|
installationId: z.ZodNullable<z.ZodString>;
|
|
219
224
|
surfaceId: z.ZodString;
|
|
220
225
|
appId: z.ZodString;
|
|
@@ -222,15 +227,15 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
|
222
227
|
icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
223
228
|
releaseId: z.ZodNullable<z.ZodString>;
|
|
224
229
|
authorityVersion: z.ZodNumber;
|
|
225
|
-
enforcement: z.ZodNullable<z.ZodObject<{
|
|
230
|
+
enforcement: z.ZodNullable<z.ZodLazy<z.ZodObject<{
|
|
226
231
|
requestId: z.ZodString;
|
|
227
|
-
address: z.ZodUnion<readonly [z.ZodObject<{
|
|
232
|
+
address: z.ZodLazy<z.ZodUnion<readonly [z.ZodObject<{
|
|
228
233
|
kind: z.ZodLiteral<"default">;
|
|
229
234
|
appId: z.ZodString;
|
|
230
235
|
}, z.core.$strict>, z.ZodObject<{
|
|
231
236
|
kind: z.ZodLiteral<"installation">;
|
|
232
237
|
installationId: z.ZodString;
|
|
233
|
-
}, z.core.$strict>]
|
|
238
|
+
}, z.core.$strict>]>>;
|
|
234
239
|
authorityVersion: z.ZodNumber;
|
|
235
240
|
state: z.ZodEnum<{
|
|
236
241
|
unaffected: "unaffected";
|
|
@@ -239,7 +244,7 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
|
239
244
|
expired: "expired";
|
|
240
245
|
}>;
|
|
241
246
|
outstanding: z.ZodNumber;
|
|
242
|
-
}, z.core.$strict
|
|
247
|
+
}, z.core.$strict>>>;
|
|
243
248
|
handlers: z.ZodArray<z.ZodLiteral<"file.open">>;
|
|
244
249
|
roles: z.ZodArray<z.ZodString>;
|
|
245
250
|
declaredCapabilities: z.ZodArray<z.ZodString>;
|
|
@@ -298,7 +303,7 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
|
298
303
|
operation: z.ZodString;
|
|
299
304
|
resourceId: z.ZodString;
|
|
300
305
|
}, z.core.$strict>>;
|
|
301
|
-
computerPermission: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
306
|
+
computerPermission: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodLazy<z.ZodObject<{
|
|
302
307
|
kind: z.ZodLiteral<"selected-computers">;
|
|
303
308
|
computers: z.ZodArray<z.ZodObject<{
|
|
304
309
|
computerId: z.ZodString;
|
|
@@ -309,7 +314,7 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
|
309
314
|
"computer.execute": "computer.execute";
|
|
310
315
|
}>>;
|
|
311
316
|
}, z.core.$strict>>;
|
|
312
|
-
}, z.core.$strict
|
|
317
|
+
}, z.core.$strict>>, z.ZodLazy<z.ZodObject<{
|
|
313
318
|
kind: z.ZodLiteral<"all-team-computers">;
|
|
314
319
|
operations: z.ZodArray<z.ZodEnum<{
|
|
315
320
|
"computer.list": "computer.list";
|
|
@@ -317,7 +322,7 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
|
317
322
|
"computer.writeFile": "computer.writeFile";
|
|
318
323
|
"computer.execute": "computer.execute";
|
|
319
324
|
}>>;
|
|
320
|
-
}, z.core.$strict
|
|
325
|
+
}, z.core.$strict>>], "kind">>>;
|
|
321
326
|
generationPermissions: z.ZodObject<{
|
|
322
327
|
llm: z.ZodBoolean;
|
|
323
328
|
media: z.ZodBoolean;
|
|
@@ -356,7 +361,8 @@ export declare const appDirectoryResponseSchema: z.ZodObject<{
|
|
|
356
361
|
surfaceId: z.ZodNullable<z.ZodString>;
|
|
357
362
|
chosen: z.ZodBoolean;
|
|
358
363
|
}, z.core.$strict>>;
|
|
359
|
-
}, z.core.$strict
|
|
364
|
+
}, z.core.$strict>>;
|
|
365
|
+
/** The host-resolved Team App directory and its permission projections. */
|
|
360
366
|
export type AppDirectory = z.output<typeof appDirectoryResponseSchema>;
|
|
361
367
|
/** Read-only catalog metadata for one App, without host-specific role policy. */
|
|
362
368
|
export declare const appCatalogEntrySchema: z.ZodObject<{
|
|
@@ -366,7 +372,7 @@ export declare const appCatalogEntrySchema: z.ZodObject<{
|
|
|
366
372
|
gills: z.ZodArray<z.ZodObject<{
|
|
367
373
|
id: z.ZodString;
|
|
368
374
|
title: z.ZodString;
|
|
369
|
-
params: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
375
|
+
params: z.ZodOptional<z.ZodLazy<z.ZodArray<z.ZodObject<{
|
|
370
376
|
key: z.ZodString;
|
|
371
377
|
label: z.ZodString;
|
|
372
378
|
kind: z.ZodEnum<{
|
|
@@ -400,7 +406,7 @@ export declare const appCatalogEntrySchema: z.ZodObject<{
|
|
|
400
406
|
kind: "computer" | "repository" | "branch";
|
|
401
407
|
required: boolean;
|
|
402
408
|
options?: string | undefined;
|
|
403
|
-
}[]
|
|
409
|
+
}[]>>>>;
|
|
404
410
|
desktop: z.ZodOptional<z.ZodObject<{
|
|
405
411
|
sizes: z.ZodArray<z.ZodEnum<{
|
|
406
412
|
S: "S";
|
|
@@ -411,7 +417,7 @@ export declare const appCatalogEntrySchema: z.ZodObject<{
|
|
|
411
417
|
}, z.core.$strict>>;
|
|
412
418
|
}, z.core.$strict>;
|
|
413
419
|
/** Read-only desktop metadata; identities are surface addresses, never launch authority. */
|
|
414
|
-
export declare const appCatalogResponseSchema: z.ZodObject<{
|
|
420
|
+
export declare const appCatalogResponseSchema: z.ZodLazy<z.ZodObject<{
|
|
415
421
|
apps: z.ZodArray<z.ZodObject<{
|
|
416
422
|
appId: z.ZodString;
|
|
417
423
|
surfaceId: z.ZodString;
|
|
@@ -419,7 +425,7 @@ export declare const appCatalogResponseSchema: z.ZodObject<{
|
|
|
419
425
|
gills: z.ZodArray<z.ZodObject<{
|
|
420
426
|
id: z.ZodString;
|
|
421
427
|
title: z.ZodString;
|
|
422
|
-
params: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
428
|
+
params: z.ZodOptional<z.ZodLazy<z.ZodArray<z.ZodObject<{
|
|
423
429
|
key: z.ZodString;
|
|
424
430
|
label: z.ZodString;
|
|
425
431
|
kind: z.ZodEnum<{
|
|
@@ -453,7 +459,7 @@ export declare const appCatalogResponseSchema: z.ZodObject<{
|
|
|
453
459
|
kind: "computer" | "repository" | "branch";
|
|
454
460
|
required: boolean;
|
|
455
461
|
options?: string | undefined;
|
|
456
|
-
}[]
|
|
462
|
+
}[]>>>>;
|
|
457
463
|
desktop: z.ZodOptional<z.ZodObject<{
|
|
458
464
|
sizes: z.ZodArray<z.ZodEnum<{
|
|
459
465
|
S: "S";
|
|
@@ -469,11 +475,11 @@ export declare const appCatalogResponseSchema: z.ZodObject<{
|
|
|
469
475
|
chosen: z.ZodBoolean;
|
|
470
476
|
}, z.core.$strict>>;
|
|
471
477
|
}, z.core.$strict>;
|
|
472
|
-
}, z.core.$strict
|
|
478
|
+
}, z.core.$strict>>;
|
|
473
479
|
/** Parsed metadata returned by the read-only APPS.catalog binding. */
|
|
474
480
|
export type AppCatalog = z.output<typeof appCatalogResponseSchema>;
|
|
475
481
|
/** Complete APPS.catalog reply, including broker admission failures. */
|
|
476
|
-
export declare const appCatalogBrokerResultSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
482
|
+
export declare const appCatalogBrokerResultSchema: z.ZodLazy<z.ZodUnion<readonly [z.ZodLazy<z.ZodObject<{
|
|
477
483
|
apps: z.ZodArray<z.ZodObject<{
|
|
478
484
|
appId: z.ZodString;
|
|
479
485
|
surfaceId: z.ZodString;
|
|
@@ -481,7 +487,7 @@ export declare const appCatalogBrokerResultSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
481
487
|
gills: z.ZodArray<z.ZodObject<{
|
|
482
488
|
id: z.ZodString;
|
|
483
489
|
title: z.ZodString;
|
|
484
|
-
params: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
490
|
+
params: z.ZodOptional<z.ZodLazy<z.ZodArray<z.ZodObject<{
|
|
485
491
|
key: z.ZodString;
|
|
486
492
|
label: z.ZodString;
|
|
487
493
|
kind: z.ZodEnum<{
|
|
@@ -515,7 +521,7 @@ export declare const appCatalogBrokerResultSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
515
521
|
kind: "computer" | "repository" | "branch";
|
|
516
522
|
required: boolean;
|
|
517
523
|
options?: string | undefined;
|
|
518
|
-
}[]
|
|
524
|
+
}[]>>>>;
|
|
519
525
|
desktop: z.ZodOptional<z.ZodObject<{
|
|
520
526
|
sizes: z.ZodArray<z.ZodEnum<{
|
|
521
527
|
S: "S";
|
|
@@ -531,7 +537,6 @@ export declare const appCatalogBrokerResultSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
531
537
|
chosen: z.ZodBoolean;
|
|
532
538
|
}, z.core.$strict>>;
|
|
533
539
|
}, z.core.$strict>;
|
|
534
|
-
}, z.core.$strict
|
|
540
|
+
}, z.core.$strict>>, z.ZodObject<{
|
|
535
541
|
error: z.ZodString;
|
|
536
|
-
}, z.core.$strict>]
|
|
537
|
-
export {};
|
|
542
|
+
}, z.core.$strict>]>>;
|
|
@@ -3,7 +3,7 @@ import { appDeclaredCommandSchema, appCallsSchema, } from "@fungi.computer/puffb
|
|
|
3
3
|
import { appDeclaredGillSchema, appGillParamsSchema, } from "@fungi.computer/gills";
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
/** An App address selects a host default or a specific installation. */
|
|
6
|
-
export const appAddressSchema = z.union([
|
|
6
|
+
export const appAddressSchema = z.lazy(() => z.union([
|
|
7
7
|
z.strictObject({
|
|
8
8
|
kind: z.literal("default"),
|
|
9
9
|
appId: z.string().min(1),
|
|
@@ -12,15 +12,15 @@ export const appAddressSchema = z.union([
|
|
|
12
12
|
kind: z.literal("installation"),
|
|
13
13
|
installationId: z.string().min(1),
|
|
14
14
|
}),
|
|
15
|
-
]);
|
|
15
|
+
]));
|
|
16
16
|
/** Host-reported progress of applying a revised App authority version. */
|
|
17
|
-
export const appAuthorityEnforcementSchema = z.strictObject({
|
|
17
|
+
export const appAuthorityEnforcementSchema = z.lazy(() => z.strictObject({
|
|
18
18
|
requestId: z.string().min(1),
|
|
19
19
|
address: appAddressSchema,
|
|
20
20
|
authorityVersion: z.number().int().positive(),
|
|
21
21
|
state: z.enum(["unaffected", "pending", "applied", "expired"]),
|
|
22
22
|
outstanding: z.number().int().nonnegative(),
|
|
23
|
-
});
|
|
23
|
+
}));
|
|
24
24
|
/** Stable identity of one App address across directory and settings views. */
|
|
25
25
|
export const addressKey = (address) => address.kind === "default"
|
|
26
26
|
? `default:${address.appId}`
|
|
@@ -69,17 +69,18 @@ const appComputerOperationSchema = z.enum([
|
|
|
69
69
|
"computer.writeFile",
|
|
70
70
|
"computer.execute",
|
|
71
71
|
]);
|
|
72
|
-
const selectedComputerPermissionSchema = z.strictObject({
|
|
72
|
+
const selectedComputerPermissionSchema = z.lazy(() => z.strictObject({
|
|
73
73
|
kind: z.literal("selected-computers"),
|
|
74
74
|
computers: z.array(z.strictObject({
|
|
75
75
|
computerId: z.string().min(1),
|
|
76
76
|
operations: z.array(appComputerOperationSchema),
|
|
77
77
|
})),
|
|
78
|
-
});
|
|
79
|
-
const allTeamComputersPermissionSchema = z.strictObject({
|
|
78
|
+
}));
|
|
79
|
+
const allTeamComputersPermissionSchema = z.lazy(() => z.strictObject({
|
|
80
80
|
kind: z.literal("all-team-computers"),
|
|
81
81
|
operations: z.array(appComputerOperationSchema),
|
|
82
|
-
});
|
|
82
|
+
}));
|
|
83
|
+
/** App Computer permissions limited to selected Computers or the Team's Computers. */
|
|
83
84
|
export const appComputerPermissionSchema = z.discriminatedUnion("kind", [
|
|
84
85
|
selectedComputerPermissionSchema,
|
|
85
86
|
allTeamComputersPermissionSchema,
|
|
@@ -90,6 +91,7 @@ const agentSessionOperationSchema = z.enum([
|
|
|
90
91
|
"agent.send",
|
|
91
92
|
"agent.manage",
|
|
92
93
|
]);
|
|
94
|
+
/** Agent directory and session operations an App may request from its host. */
|
|
93
95
|
export const appAgentPermissionSchema = z.discriminatedUnion("kind", [
|
|
94
96
|
z.strictObject({
|
|
95
97
|
kind: z.literal("all-team-agents"),
|
|
@@ -105,10 +107,12 @@ export const appAgentPermissionSchema = z.discriminatedUnion("kind", [
|
|
|
105
107
|
})),
|
|
106
108
|
}),
|
|
107
109
|
]);
|
|
110
|
+
/** Whether an App may use language-model and media generation services. */
|
|
108
111
|
export const appGenerationPermissionsSchema = z.strictObject({
|
|
109
112
|
llm: z.boolean(),
|
|
110
113
|
media: z.boolean(),
|
|
111
114
|
});
|
|
115
|
+
/** Whether an App may browse, buy, or install free marketplace entries. */
|
|
112
116
|
export const appMarketplacePermissionsSchema = z.strictObject({
|
|
113
117
|
browse: z.boolean(),
|
|
114
118
|
purchase: z.boolean(),
|
|
@@ -118,7 +122,7 @@ export const appMarketplacePermissionsSchema = z.strictObject({
|
|
|
118
122
|
* A host's Team App directory with its permission projection, parsed strictly
|
|
119
123
|
* by every consumer: an unknown field is a contract change both sides make.
|
|
120
124
|
*/
|
|
121
|
-
export const appDirectoryResponseSchema = z.strictObject({
|
|
125
|
+
export const appDirectoryResponseSchema = z.lazy(() => z.strictObject({
|
|
122
126
|
actorIsTeamOwner: z.boolean(),
|
|
123
127
|
needsUpdate: z
|
|
124
128
|
.array(z.strictObject({
|
|
@@ -146,9 +150,9 @@ export const appDirectoryResponseSchema = z.strictObject({
|
|
|
146
150
|
})),
|
|
147
151
|
/** The Team's effective App per role, owned and resolved by the host. */
|
|
148
152
|
roles: z.record(z.string().min(1), appRoleSelectionSchema),
|
|
149
|
-
});
|
|
153
|
+
}));
|
|
150
154
|
/** Desktop metadata is a method result, distinct from the full Release Gill declaration. */
|
|
151
|
-
const catalogGillParamsSchema = z
|
|
155
|
+
const catalogGillParamsSchema = z.lazy(() => z
|
|
152
156
|
.array(z.strictObject({
|
|
153
157
|
key: z.string().max(64),
|
|
154
158
|
label: z.string().max(256),
|
|
@@ -158,7 +162,7 @@ const catalogGillParamsSchema = z
|
|
|
158
162
|
}))
|
|
159
163
|
.max(4)
|
|
160
164
|
// The wire shape is representable; Gill owns its domain refinements.
|
|
161
|
-
.refine(Schema.is(appGillParamsSchema), "Invalid Gill placement parameters");
|
|
165
|
+
.refine(Schema.is(appGillParamsSchema), "Invalid Gill placement parameters"));
|
|
162
166
|
const catalogGillSchema = z.strictObject({
|
|
163
167
|
id: z.string().trim().min(1).max(256),
|
|
164
168
|
title: z.string().trim().min(1).max(256),
|
|
@@ -182,14 +186,11 @@ export const appCatalogEntrySchema = appDirectoryEntrySchema
|
|
|
182
186
|
})
|
|
183
187
|
.extend({ gills: z.array(catalogGillSchema).max(16) });
|
|
184
188
|
/** Read-only desktop metadata; identities are surface addresses, never launch authority. */
|
|
185
|
-
export const appCatalogResponseSchema = z.strictObject({
|
|
189
|
+
export const appCatalogResponseSchema = z.lazy(() => z.strictObject({
|
|
186
190
|
apps: z.array(appCatalogEntrySchema).max(50),
|
|
187
191
|
roles: z.strictObject({
|
|
188
192
|
inbox: appRoleSelectionSchema.optional(),
|
|
189
193
|
}),
|
|
190
|
-
});
|
|
194
|
+
}));
|
|
191
195
|
/** Complete APPS.catalog reply, including broker admission failures. */
|
|
192
|
-
export const appCatalogBrokerResultSchema = z.union([
|
|
193
|
-
appCatalogResponseSchema,
|
|
194
|
-
z.strictObject({ error: z.string() }),
|
|
195
|
-
]);
|
|
196
|
+
export const appCatalogBrokerResultSchema = z.lazy(() => z.union([appCatalogResponseSchema, z.strictObject({ error: z.string() })]));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AppStorage } from "@fungi.computer/agar/storage";
|
|
2
2
|
import type { WhistleJsonValue } from "@fungi.computer/whistle";
|
|
3
3
|
import type { TeamWorkbenchHostHandle } from "./workbench-contract.js";
|
|
4
|
+
import type { WorkbenchHostControls } from "./workbench-host-types.js";
|
|
4
5
|
/**
|
|
5
6
|
* What a host hands the shell a Team picked. The host composes that shell into
|
|
6
7
|
* its own top-level document, so it runs with the host's escalated
|
|
@@ -20,12 +21,35 @@ export type ShellMountInput = Readonly<{
|
|
|
20
21
|
* function that removes it again. The shell loads its own code and styles.
|
|
21
22
|
*/
|
|
22
23
|
export type MountShell = (root: HTMLElement, input: ShellMountInput) => Promise<() => void>;
|
|
24
|
+
/**
|
|
25
|
+
* Settings a shell renders for a host that has none of its own, such as a
|
|
26
|
+
* standalone Oyster: the shell draws them into `root`, and the host hands
|
|
27
|
+
* `controls` to its workbench so Apps and the dashboard can open them.
|
|
28
|
+
*/
|
|
29
|
+
export type ShellPlatformControls = Readonly<{
|
|
30
|
+
controls: WorkbenchHostControls;
|
|
31
|
+
/** A child App suggested desktop Settings for one of its surfaces. */
|
|
32
|
+
suggestDesktopSettings(surfaceId: string): void;
|
|
33
|
+
/** Remove the rendered Settings. */
|
|
34
|
+
dispose(): void;
|
|
35
|
+
}>;
|
|
36
|
+
/** Render the shell's own Settings into `root` for the host at `teamId`. */
|
|
37
|
+
export type MountPlatformControls = (root: HTMLElement, input: Readonly<{
|
|
38
|
+
teamId: string;
|
|
39
|
+
}>) => Promise<ShellPlatformControls>;
|
|
40
|
+
/** What a host gets from a picked shell Release's module. */
|
|
41
|
+
export type ShellModule = Readonly<{
|
|
42
|
+
mountShell: MountShell;
|
|
43
|
+
/** Absent when the shell renders no Settings of its own. */
|
|
44
|
+
mountPlatformControls: MountPlatformControls | null;
|
|
45
|
+
}>;
|
|
23
46
|
/** The picked shell's module could not be loaded or does not fit the contract. */
|
|
24
47
|
export declare class ShellModuleError extends Error {
|
|
25
48
|
readonly name = "ShellModuleError";
|
|
26
49
|
}
|
|
27
50
|
/**
|
|
28
51
|
* Import the picked shell Release's module from the host's own origin and
|
|
29
|
-
* check that it exports `mountShell
|
|
52
|
+
* check that it exports `mountShell`, and `mountPlatformControls` when it
|
|
53
|
+
* offers its own Settings. The host never bundles a shell.
|
|
30
54
|
*/
|
|
31
|
-
export declare function importShellModule(moduleUrl: URL, hostOrigin: string): Promise<
|
|
55
|
+
export declare function importShellModule(moduleUrl: URL, hostOrigin: string): Promise<ShellModule>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
+
const unsubscribe = () => z.function({ input: [], output: z.void() });
|
|
2
3
|
/** The module namespace a shell Release must export; built on first use,
|
|
3
4
|
* since only a browser has `HTMLElement`. */
|
|
4
5
|
const shellModuleSchema = () => z.object({
|
|
@@ -7,6 +8,50 @@ const shellModuleSchema = () => z.object({
|
|
|
7
8
|
input: [z.instanceof(HTMLElement), z.unknown()],
|
|
8
9
|
output: z.promise(z.function({ input: [], output: z.void() })),
|
|
9
10
|
}),
|
|
11
|
+
mountPlatformControls: z
|
|
12
|
+
.function({
|
|
13
|
+
input: [
|
|
14
|
+
z.instanceof(HTMLElement),
|
|
15
|
+
z.object({ teamId: z.string() }).readonly(),
|
|
16
|
+
],
|
|
17
|
+
output: z.promise(z.object({
|
|
18
|
+
controls: z.object({
|
|
19
|
+
sections: z.array(z.string()).readonly().optional(),
|
|
20
|
+
// The host passes the workbench's own values; the shell
|
|
21
|
+
// parses what it reads.
|
|
22
|
+
parseSettings: z.function({
|
|
23
|
+
input: [z.unknown()],
|
|
24
|
+
output: z.json(),
|
|
25
|
+
}),
|
|
26
|
+
openSettings: z.function({
|
|
27
|
+
input: [z.unknown(), z.object({ restoreFocus: z.boolean() })],
|
|
28
|
+
output: z.void(),
|
|
29
|
+
}),
|
|
30
|
+
subscribeSettingsClosed: z.function({
|
|
31
|
+
input: [unsubscribe()],
|
|
32
|
+
output: unsubscribe(),
|
|
33
|
+
}),
|
|
34
|
+
subscribeChanges: z.function({
|
|
35
|
+
input: [unsubscribe()],
|
|
36
|
+
output: unsubscribe(),
|
|
37
|
+
}),
|
|
38
|
+
attachDesktopSettings: z.function({
|
|
39
|
+
input: [z.unknown()],
|
|
40
|
+
output: unsubscribe(),
|
|
41
|
+
}),
|
|
42
|
+
requestAppAccess: z.function({
|
|
43
|
+
input: [z.unknown(), z.unknown()],
|
|
44
|
+
output: z.promise(z.enum(["granted", "declined", "customize"])),
|
|
45
|
+
}),
|
|
46
|
+
}),
|
|
47
|
+
suggestDesktopSettings: z.function({
|
|
48
|
+
input: [z.string()],
|
|
49
|
+
output: z.void(),
|
|
50
|
+
}),
|
|
51
|
+
dispose: unsubscribe(),
|
|
52
|
+
})),
|
|
53
|
+
})
|
|
54
|
+
.optional(),
|
|
10
55
|
});
|
|
11
56
|
/** The picked shell's module could not be loaded or does not fit the contract. */
|
|
12
57
|
export class ShellModuleError extends Error {
|
|
@@ -14,7 +59,8 @@ export class ShellModuleError extends Error {
|
|
|
14
59
|
}
|
|
15
60
|
/**
|
|
16
61
|
* Import the picked shell Release's module from the host's own origin and
|
|
17
|
-
* check that it exports `mountShell
|
|
62
|
+
* check that it exports `mountShell`, and `mountPlatformControls` when it
|
|
63
|
+
* offers its own Settings. The host never bundles a shell.
|
|
18
64
|
*/
|
|
19
65
|
export async function importShellModule(moduleUrl, hostOrigin) {
|
|
20
66
|
if (moduleUrl.origin !== hostOrigin || moduleUrl.hash !== "")
|
|
@@ -33,5 +79,8 @@ export async function importShellModule(moduleUrl, hostOrigin) {
|
|
|
33
79
|
throw new ShellModuleError("The picked shell does not export mountShell", {
|
|
34
80
|
cause: decoded.error,
|
|
35
81
|
});
|
|
36
|
-
return
|
|
82
|
+
return {
|
|
83
|
+
mountShell: decoded.data.mountShell,
|
|
84
|
+
mountPlatformControls: decoded.data.mountPlatformControls ?? null,
|
|
85
|
+
};
|
|
37
86
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppNavigationState, type AppStatusAction, type AppStatusItem } from "@fungi.computer/agar";
|
|
1
|
+
import { type AppNavigationActivation, type AppNavigationState, type AppStatusAction, type AppStatusItem } from "@fungi.computer/agar";
|
|
2
2
|
/** Minimum identity required to own a window across mount generations. */
|
|
3
3
|
export type WindowLaunch = Readonly<{
|
|
4
4
|
windowId: string;
|
|
@@ -15,6 +15,8 @@ export type WindowHost<Launch extends WindowLaunch> = Readonly<{
|
|
|
15
15
|
requestClose?: () => boolean | Promise<boolean>;
|
|
16
16
|
/** Ask the mounted App to go back in its own history; `true` when it did. */
|
|
17
17
|
requestBack?: () => boolean | Promise<boolean>;
|
|
18
|
+
/** Deliver the person's use of a crumb or header command; `true` when the App acted. */
|
|
19
|
+
activateNavigation?: (activation: AppNavigationActivation) => boolean | Promise<boolean>;
|
|
18
20
|
/** Deliver the person's use of a status item; `true` when the App acted. */
|
|
19
21
|
activateStatus?: (action: AppStatusAction) => boolean | Promise<boolean>;
|
|
20
22
|
/** Release the current mount and its host resources. */
|
|
@@ -79,6 +81,8 @@ export type WindowManager<Launch extends WindowLaunch, Container> = Readonly<{
|
|
|
79
81
|
replace: (windowId: string, launch: Launch) => Promise<void>;
|
|
80
82
|
/** Ask a ready window's App to go back; `false` when it cannot. */
|
|
81
83
|
back: (windowId: string) => Promise<boolean>;
|
|
84
|
+
/** Deliver a crumb or header command to a ready window's App; `false` when it cannot. */
|
|
85
|
+
activateNavigation: (windowId: string, activation: AppNavigationActivation) => Promise<boolean>;
|
|
82
86
|
/** Deliver a status item action to a ready window's App; `false` when it cannot. */
|
|
83
87
|
activateStatus: (windowId: string, action: AppStatusAction) => Promise<boolean>;
|
|
84
88
|
/** Register the current window generation's host-owned picker. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Redacted from "effect/Redacted";
|
|
2
|
-
import { AppError, statusActionAllowed, } from "@fungi.computer/agar";
|
|
2
|
+
import { AppError, navigationActivationAllowed, statusActionAllowed, } from "@fungi.computer/agar";
|
|
3
3
|
/**
|
|
4
4
|
* Shared window lifetime owner for browser and terminal shells.
|
|
5
5
|
*
|
|
@@ -18,7 +18,14 @@ function sameStatusItems(current, next) {
|
|
|
18
18
|
function sameNavigation(current, next) {
|
|
19
19
|
if (current === null || next === null)
|
|
20
20
|
return current === next;
|
|
21
|
-
return current.canGoBack === next.canGoBack &&
|
|
21
|
+
return (current.canGoBack === next.canGoBack &&
|
|
22
|
+
current.title === next.title &&
|
|
23
|
+
JSON.stringify([
|
|
24
|
+
current.crumbs,
|
|
25
|
+
current.primary,
|
|
26
|
+
current.menu,
|
|
27
|
+
current.status,
|
|
28
|
+
]) === JSON.stringify([next.crumbs, next.primary, next.menu, next.status]));
|
|
22
29
|
}
|
|
23
30
|
/** Whether any projected App window is still visible in the workspace. */
|
|
24
31
|
export function hasVisibleWindows(projection) {
|
|
@@ -626,6 +633,17 @@ export function createWindowManager(options) {
|
|
|
626
633
|
const requestBack = record.host?.requestBack;
|
|
627
634
|
return requestBack ? await requestBack() : false;
|
|
628
635
|
};
|
|
636
|
+
const activateNavigation = async (windowId, activation) => {
|
|
637
|
+
const record = records.get(windowId);
|
|
638
|
+
if (!record || !isActive(record) || record.status !== "ready")
|
|
639
|
+
return false;
|
|
640
|
+
// Only a crumb or enabled command the App currently publishes.
|
|
641
|
+
if (record.navigation === null ||
|
|
642
|
+
!navigationActivationAllowed(record.navigation, activation))
|
|
643
|
+
return false;
|
|
644
|
+
const deliver = record.host?.activateNavigation;
|
|
645
|
+
return deliver ? await deliver(activation) : false;
|
|
646
|
+
};
|
|
629
647
|
const activateStatus = async (windowId, action) => {
|
|
630
648
|
const record = records.get(windowId);
|
|
631
649
|
if (!record || !isActive(record) || record.status !== "ready")
|
|
@@ -697,6 +715,7 @@ export function createWindowManager(options) {
|
|
|
697
715
|
close,
|
|
698
716
|
reconfigure,
|
|
699
717
|
update,
|
|
718
|
+
activateNavigation,
|
|
700
719
|
activateStatus,
|
|
701
720
|
registerComputerChoice,
|
|
702
721
|
replace,
|