@fungi.computer/oyster 0.3.2 → 0.4.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/dist/agent-computer-source.d.ts +42 -0
- package/dist/agent-computer-source.js +88 -0
- package/dist/agent-computers.d.ts +104 -0
- package/dist/agent-computers.js +227 -0
- package/dist/agents.d.ts +10 -0
- package/dist/agents.js +33 -0
- package/dist/app-builds.d.ts +1 -1
- package/dist/app-builds.js +16 -6
- package/dist/boot-capability.d.ts +2 -1
- package/dist/boot-capability.js +7 -5
- package/dist/browser/boot.d.ts +2 -2
- package/dist/browser/boot.js +10 -3
- package/dist/browser/browser.d.ts +1 -1
- package/dist/browser/browser.js +2 -1
- package/dist/browser/cdp-client.d.ts +2 -0
- package/dist/browser/errors.d.ts +2 -2
- package/dist/browser/errors.js +2 -2
- package/dist/browser/index.d.ts +3 -2
- package/dist/browser/index.js +3 -2
- package/dist/browser/page.js +11 -4
- package/dist/browser/sessions.d.ts +7 -4
- package/dist/browser/sessions.js +159 -0
- package/dist/browser/url-policy.d.ts +4 -2
- package/dist/browser/url-policy.js +4 -2
- package/dist/build/build-jobs.d.ts +3 -3
- package/dist/build/build-jobs.js +10 -5
- package/dist/build/candidate-cli.js +5 -3
- package/dist/build/candidate-cli.mjs +223 -5
- package/dist/build/candidate-diagnostic.d.ts +2 -0
- package/dist/build/candidate-diagnostic.js +16 -0
- package/dist/computer-control-port.d.ts +26 -0
- package/dist/computer-control-port.js +1 -0
- package/dist/host.d.ts +3 -0
- package/dist/machine-link/delivery.d.ts +1 -1
- package/dist/machine-link/delivery.js +2 -3
- package/dist/machine-link/host.d.ts +37 -6
- package/dist/machine-link/host.js +209 -14
- package/dist/machine-link/link.d.ts +13 -1
- package/dist/machine-link/link.js +20 -7
- package/dist/mcp.d.ts +144 -10
- package/dist/mcp.js +130 -13
- package/dist/page/computer-handles.d.ts +3 -3
- package/dist/page-script.js +1 -1
- package/dist/standalone/agent-computers.d.ts +29 -0
- package/dist/standalone/agent-computers.js +101 -0
- package/dist/standalone/agent-mail.d.ts +41 -18
- package/dist/standalone/agent-model-choice.d.ts +29 -0
- package/dist/standalone/agent-model-choice.js +72 -0
- package/dist/standalone/agents.d.ts +44 -4
- package/dist/standalone/agents.js +502 -46
- package/dist/standalone/app-set.d.ts +8 -1
- package/dist/standalone/app-set.js +46 -31
- package/dist/standalone/computer-control.d.ts +4 -0
- package/dist/standalone/computer-control.js +62 -0
- package/dist/standalone/computer-fleet.d.ts +1 -0
- package/dist/standalone/computer-fleet.js +1 -1
- package/dist/standalone/computer.d.ts +21 -2
- package/dist/standalone/computer.js +12 -0
- package/dist/standalone/install-apps-bin.d.ts +2 -0
- package/dist/standalone/install-apps-bin.js +3 -0
- package/dist/standalone/install-apps-cli.d.ts +3 -1
- package/dist/standalone/install-apps-cli.js +27 -17
- package/dist/standalone/machine-link.d.ts +10 -0
- package/dist/standalone/machine-link.js +6 -0
- package/dist/standalone/registry.d.ts +10 -1
- package/dist/standalone/registry.js +9 -0
- package/dist/standalone/worker.js +12 -0
- package/dist/standalone/workflow-binding.d.ts +2 -2
- package/dist/standalone/workflow-host.d.ts +11 -11
- package/dist/standalone/workflows.d.ts +22 -22
- package/dist/storage-frame.d.ts +3 -3
- package/dist/workers-git.d.ts +2 -0
- package/dist/workers-git.js +2 -0
- package/dist/workers.d.ts +8 -8
- package/dist/workers.js +9 -1
- package/docs/api/agents.md +66 -0
- package/docs/api/apps.md +104 -104
- package/docs/api/build-contract.md +35 -35
- package/docs/api/build.md +12 -12
- package/docs/api/host.md +61 -61
- package/docs/api/mcp.md +127 -13
- package/docs/api/root-data.md +1 -1
- package/docs/api/tenancy.md +1 -1
- package/docs/api/workers-git.md +3 -2
- package/docs/api/workers.md +81 -83
- package/package.json +26 -18
package/dist/mcp.js
CHANGED
|
@@ -15,8 +15,86 @@ import { appToolSchemas, appToolFamilySchemas } from "@fungi.computer/forage";
|
|
|
15
15
|
import { Knapsack } from "@fungi.computer/knapsack";
|
|
16
16
|
import * as Schema from "effect/Schema";
|
|
17
17
|
import { defineIdFamily } from "@fungi.computer/cairn/id";
|
|
18
|
+
import { computerCreateRequestSchema, computerPageSchema, } from "@fungi.computer/computer/fleet/inventory-wire";
|
|
19
|
+
import { computerStateSchema } from "@fungi.computer/computer/fleet/wire";
|
|
20
|
+
import { teamComputerDirectorySchema } from "@fungi.computer/nacre/workbench";
|
|
18
21
|
import { keyAppAccess } from "./keys.js";
|
|
19
22
|
import { defaultAssetPolicy, sha256, verifyRelease, } from "./release.js";
|
|
23
|
+
const fleetIds = defineIdFamily({
|
|
24
|
+
family: "mcp-computer-control",
|
|
25
|
+
version: 1,
|
|
26
|
+
kinds: { request: { prefix: "computer_request" } },
|
|
27
|
+
});
|
|
28
|
+
const fleetComputerId = z.strictObject({
|
|
29
|
+
computerId: z.string().min(1).max(256),
|
|
30
|
+
});
|
|
31
|
+
const fleetCreate = z.strictObject({
|
|
32
|
+
name: computerCreateRequestSchema.shape.name
|
|
33
|
+
.unwrap()
|
|
34
|
+
.nullable()
|
|
35
|
+
.default(null),
|
|
36
|
+
requestId: computerCreateRequestSchema.shape.requestId
|
|
37
|
+
.nullable()
|
|
38
|
+
.default(null),
|
|
39
|
+
});
|
|
40
|
+
const fleetComputer = z.strictObject({
|
|
41
|
+
computerId: z.string(),
|
|
42
|
+
name: z.string(),
|
|
43
|
+
});
|
|
44
|
+
const fleetCreation = z.discriminatedUnion("kind", [
|
|
45
|
+
z.strictObject({
|
|
46
|
+
kind: z.literal("created"),
|
|
47
|
+
requestId: z.string(),
|
|
48
|
+
computer: fleetComputer,
|
|
49
|
+
}),
|
|
50
|
+
z.strictObject({
|
|
51
|
+
kind: z.enum(["uncertain", "denied", "conflict", "invalid"]),
|
|
52
|
+
requestId: z.string(),
|
|
53
|
+
}),
|
|
54
|
+
]);
|
|
55
|
+
/** One set of schemas and operations for MCP and direct broker invocation. */
|
|
56
|
+
export function computerControlSpecs(port) {
|
|
57
|
+
return {
|
|
58
|
+
list: {
|
|
59
|
+
replay: "safe",
|
|
60
|
+
access: "read",
|
|
61
|
+
description: "List a page of permitted Computers. Follow nextOffset for another page.",
|
|
62
|
+
input: computerPageSchema,
|
|
63
|
+
output: teamComputerDirectorySchema,
|
|
64
|
+
/** Return an admitted inventory page to MCP or the retained broker. */
|
|
65
|
+
execute: (input, context) => port.list(input, context),
|
|
66
|
+
},
|
|
67
|
+
state: {
|
|
68
|
+
replay: "safe",
|
|
69
|
+
access: "read",
|
|
70
|
+
description: "Read runtime state without waking a Computer, including its live admission queue position.",
|
|
71
|
+
input: fleetComputerId,
|
|
72
|
+
output: computerStateSchema,
|
|
73
|
+
/** Return liveness without waking the runtime. */
|
|
74
|
+
execute: (input, context) => port.state(input.computerId, context),
|
|
75
|
+
},
|
|
76
|
+
start: {
|
|
77
|
+
replay: "unsafe",
|
|
78
|
+
description: "Start a hosted Computer through ordinary admission. Waits until connected; poll computers.state while queued. Safe to retry.",
|
|
79
|
+
input: fleetComputerId,
|
|
80
|
+
output: computerStateSchema,
|
|
81
|
+
/** Admit and start this Computer. */
|
|
82
|
+
execute: (input, context) => port.start(input.computerId, context),
|
|
83
|
+
},
|
|
84
|
+
create: {
|
|
85
|
+
replay: "unsafe",
|
|
86
|
+
description: "Create a Computer with an optional friendly name. Request identity is generated automatically. If the outcome is uncertain, retry with its returned requestId and the original name input; do not start a second creation.",
|
|
87
|
+
input: fleetCreate,
|
|
88
|
+
output: fleetCreation,
|
|
89
|
+
/** Mint one identity or preserve the requestId for an uncertain retry. */
|
|
90
|
+
execute: async (input, context) => {
|
|
91
|
+
const requestId = input.requestId ?? fleetIds.request.generate();
|
|
92
|
+
const result = await port.create({ name: input.name ?? undefined, requestId }, context);
|
|
93
|
+
return { ...result, requestId };
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
20
98
|
/** Mints the requestId a tool family tool sends on the caller's behalf to its
|
|
21
99
|
* declared `call` method: each MCP call is its own independent run, never a
|
|
22
100
|
* replay the caller controls. */
|
|
@@ -372,9 +450,9 @@ export async function oysterAppMethods(host, principal, access, surfaces, preloa
|
|
|
372
450
|
}
|
|
373
451
|
/**
|
|
374
452
|
* Capture the host's fixed Computer for one caller as a Knapsack source.
|
|
375
|
-
* The host decides whether the caller holds Computer access; the
|
|
376
|
-
*
|
|
377
|
-
* has no access. Grants name
|
|
453
|
+
* The host decides whether the caller holds Computer access; the ComputerDO
|
|
454
|
+
* still checks its host-issued grant on every call. Null when the host has no
|
|
455
|
+
* Computer or the caller has no access. Grants name the captured module.
|
|
378
456
|
*/
|
|
379
457
|
export async function oysterComputerTools(host, principal) {
|
|
380
458
|
if (host.computerId === undefined || host.computer === undefined)
|
|
@@ -399,12 +477,12 @@ export async function oysterComputerTools(host, principal) {
|
|
|
399
477
|
* methods, plus the host's Computer when the caller holds Computer access.
|
|
400
478
|
* A key sees exactly the installations and levels its own grants admit, and
|
|
401
479
|
* the Computer only with its own `computer.use` grant; each App retains its
|
|
402
|
-
* own caller checks regardless.
|
|
403
|
-
* Agent's App tools
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
* still re-admits the key,
|
|
407
|
-
*
|
|
480
|
+
* own caller checks regardless. App writes use the host's approval record;
|
|
481
|
+
* stored approval of an Agent's App tools can permit headless App writes.
|
|
482
|
+
* The shared MCP server elicits consent for explicitly confirmed operations,
|
|
483
|
+
* including every advertised Workspace Computer call, even reads. Each call
|
|
484
|
+
* still re-admits the key, checks current App approval and passes the App's
|
|
485
|
+
* gate.
|
|
408
486
|
*/
|
|
409
487
|
export function oysterMcpCatalogLoad(host) {
|
|
410
488
|
const surfaces = appSurfaceCache(host);
|
|
@@ -435,6 +513,40 @@ export function oysterMcpCatalogLoad(host) {
|
|
|
435
513
|
}
|
|
436
514
|
const apps = await oysterAppMethods(host, principal, access, surfaces, installations);
|
|
437
515
|
const computer = await oysterComputerTools(host, principal);
|
|
516
|
+
const fleet = host.computerControl?.(principal) ?? null;
|
|
517
|
+
const fleetSpecs = fleet === null ? null : computerControlSpecs(fleet);
|
|
518
|
+
const fleetSource = fleetSpecs === null
|
|
519
|
+
? []
|
|
520
|
+
: [
|
|
521
|
+
{
|
|
522
|
+
id: "oyster-computer-control",
|
|
523
|
+
acquire: () => Promise.resolve({
|
|
524
|
+
snapshot: {
|
|
525
|
+
version: "team-computer-control",
|
|
526
|
+
modules: [
|
|
527
|
+
Mycelium.module({
|
|
528
|
+
id: "team-computer-control",
|
|
529
|
+
name: "computers",
|
|
530
|
+
operations: {
|
|
531
|
+
list: Mycelium.operation(fleetSpecs.list),
|
|
532
|
+
state: Mycelium.operation(fleetSpecs.state),
|
|
533
|
+
start: Mycelium.operation({
|
|
534
|
+
...fleetSpecs.start,
|
|
535
|
+
confirm: true,
|
|
536
|
+
}),
|
|
537
|
+
create: Mycelium.operation({
|
|
538
|
+
...fleetSpecs.create,
|
|
539
|
+
confirm: true,
|
|
540
|
+
}),
|
|
541
|
+
},
|
|
542
|
+
}),
|
|
543
|
+
],
|
|
544
|
+
},
|
|
545
|
+
release: () => Promise.resolve(),
|
|
546
|
+
}),
|
|
547
|
+
},
|
|
548
|
+
];
|
|
549
|
+
const fleetGrants = fleet === null ? {} : { "team-computer-control": "write" };
|
|
438
550
|
const control = await host.workflows?.(principal);
|
|
439
551
|
const workflowSources = control == null
|
|
440
552
|
? []
|
|
@@ -454,13 +566,18 @@ export function oysterMcpCatalogLoad(host) {
|
|
|
454
566
|
if (computer === null)
|
|
455
567
|
return {
|
|
456
568
|
instructions: "Installed Apps on this Oyster. Each App is env.<APP>; dotted method names are nested properties, e.g. env.BONSAI.repos.list({}). Use forage.search / forage.describe to find methods.",
|
|
457
|
-
grants: { ...apps.grants, ...workflowGrants },
|
|
458
|
-
sources: [apps, ...workflowSources],
|
|
569
|
+
grants: { ...apps.grants, ...workflowGrants, ...fleetGrants },
|
|
570
|
+
sources: [apps, ...workflowSources, ...fleetSource],
|
|
459
571
|
};
|
|
460
572
|
return {
|
|
461
573
|
instructions: 'Installed Apps and this Oyster\'s Computer. Each App is env.<APP>; dotted method names are nested properties, e.g. env.BONSAI.repos.list({}). The Computer is env.computers.workspace, e.g. env.computers.workspace.exec({command: "ls"}). Use forage.search / forage.describe to find methods.',
|
|
462
|
-
grants: {
|
|
463
|
-
|
|
574
|
+
grants: {
|
|
575
|
+
...apps.grants,
|
|
576
|
+
...computer.grants,
|
|
577
|
+
...workflowGrants,
|
|
578
|
+
...fleetGrants,
|
|
579
|
+
},
|
|
580
|
+
sources: [apps, computer, ...workflowSources, ...fleetSource],
|
|
464
581
|
};
|
|
465
582
|
};
|
|
466
583
|
}
|
|
@@ -44,7 +44,7 @@ export declare class ComputerProcessesHandle extends RpcTarget implements Handle
|
|
|
44
44
|
readonly command: string;
|
|
45
45
|
readonly cwd: string | null;
|
|
46
46
|
readonly startedAt: number;
|
|
47
|
-
readonly state: "running" | "
|
|
47
|
+
readonly state: "running" | "uncertain" | "exited";
|
|
48
48
|
readonly exitCode: number | null;
|
|
49
49
|
readonly sync: "unknown" | "pending" | "synced";
|
|
50
50
|
readonly endedAt: number | null;
|
|
@@ -56,7 +56,7 @@ export declare class ComputerProcessesHandle extends RpcTarget implements Handle
|
|
|
56
56
|
readonly command: string;
|
|
57
57
|
readonly cwd: string | null;
|
|
58
58
|
readonly startedAt: number;
|
|
59
|
-
readonly state: "running" | "
|
|
59
|
+
readonly state: "running" | "uncertain" | "exited";
|
|
60
60
|
readonly exitCode: number | null;
|
|
61
61
|
readonly sync: "unknown" | "pending" | "synced";
|
|
62
62
|
readonly endedAt: number | null;
|
|
@@ -69,7 +69,7 @@ export declare class ComputerProcessesHandle extends RpcTarget implements Handle
|
|
|
69
69
|
readonly command: string;
|
|
70
70
|
readonly cwd: string | null;
|
|
71
71
|
readonly startedAt: number;
|
|
72
|
-
readonly state: "running" | "
|
|
72
|
+
readonly state: "running" | "uncertain" | "exited";
|
|
73
73
|
readonly exitCode: number | null;
|
|
74
74
|
readonly sync: "unknown" | "pending" | "synced";
|
|
75
75
|
readonly endedAt: number | null;
|