@fungi.computer/agar 0.0.0-stage → 0.0.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/LICENSE +21 -0
- package/README.md +766 -2
- package/dist/agent-message-meta.d.ts +74 -0
- package/dist/agent-message-meta.js +63 -0
- package/dist/agents.d.ts +170 -0
- package/dist/agents.js +218 -0
- package/dist/app-build-contract.d.ts +43 -0
- package/dist/app-build-contract.js +24 -0
- package/dist/apps.d.ts +66 -0
- package/dist/apps.js +47 -0
- package/dist/backend-declaration.d.ts +6 -0
- package/dist/backend-declaration.js +65 -0
- package/dist/backend-definition.d.ts +88 -0
- package/dist/backend-definition.js +158 -0
- package/dist/backend-refusal.d.ts +10 -0
- package/dist/backend-refusal.js +10 -0
- package/dist/backend.d.ts +30 -0
- package/dist/backend.js +28 -0
- package/dist/capabilities.d.ts +30 -0
- package/dist/capabilities.js +50 -0
- package/dist/channels.d.ts +142 -0
- package/dist/channels.js +97 -0
- package/dist/commands.d.ts +33 -0
- package/dist/commands.js +46 -0
- package/dist/computer-contracts.d.ts +73 -0
- package/dist/computer-contracts.js +57 -0
- package/dist/computer.d.ts +294 -0
- package/dist/computer.js +319 -0
- package/dist/connect.d.ts +11 -0
- package/dist/connect.js +211 -0
- package/dist/errors.d.ts +34 -0
- package/dist/errors.js +106 -0
- package/dist/failure.d.ts +2 -0
- package/dist/failure.js +9 -0
- package/dist/files.d.ts +25 -0
- package/dist/files.js +84 -0
- package/dist/game-servers.d.ts +530 -0
- package/dist/game-servers.js +244 -0
- package/dist/gills.d.ts +43 -0
- package/dist/gills.js +174 -0
- package/dist/git-commit.d.ts +143 -0
- package/dist/git-commit.js +251 -0
- package/dist/git-rpc.d.ts +310 -0
- package/dist/git-rpc.js +166 -0
- package/dist/git-steps.d.ts +579 -0
- package/dist/git-steps.js +804 -0
- package/dist/git-wire.d.ts +33 -0
- package/dist/git-wire.js +240 -0
- package/dist/git.d.ts +322 -0
- package/dist/git.js +98 -0
- package/dist/host.d.ts +97 -0
- package/dist/host.js +732 -0
- package/dist/inbox.d.ts +99 -0
- package/dist/inbox.js +184 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +15 -0
- package/dist/inference.d.ts +17 -0
- package/dist/inference.js +115 -0
- package/dist/internal/app-error.d.ts +8 -0
- package/dist/internal/app-error.js +36 -0
- package/dist/internal/app-session.d.ts +8 -0
- package/dist/internal/app-session.js +551 -0
- package/dist/internal/back-inputs.d.ts +22 -0
- package/dist/internal/back-inputs.js +93 -0
- package/dist/internal/browser-bridge.d.ts +30 -0
- package/dist/internal/browser-bridge.js +203 -0
- package/dist/internal/capabilities.d.ts +13 -0
- package/dist/internal/capabilities.js +138 -0
- package/dist/internal/commands.d.ts +9 -0
- package/dist/internal/commands.js +257 -0
- package/dist/internal/disconnect-host.d.ts +7 -0
- package/dist/internal/disconnect-host.js +19 -0
- package/dist/internal/git-edit-tree.d.ts +6 -0
- package/dist/internal/git-edit-tree.js +46 -0
- package/dist/internal/memory-fs.d.ts +39 -0
- package/dist/internal/memory-fs.js +154 -0
- package/dist/internal/protocol.d.ts +116 -0
- package/dist/internal/protocol.js +6 -0
- package/dist/internal/query-feed.d.ts +23 -0
- package/dist/internal/query-feed.js +111 -0
- package/dist/internal/result.d.ts +22 -0
- package/dist/internal/result.js +61 -0
- package/dist/internal/rpc-contract.d.ts +24 -0
- package/dist/internal/rpc-contract.js +78 -0
- package/dist/internal/schemas.d.ts +307 -0
- package/dist/internal/schemas.js +524 -0
- package/dist/internal/store.d.ts +8 -0
- package/dist/internal/store.js +30 -0
- package/dist/internal/terminal-gate.d.ts +17 -0
- package/dist/internal/terminal-gate.js +94 -0
- package/dist/lifecycle.d.ts +44 -0
- package/dist/lifecycle.js +1 -0
- package/dist/marketplace.d.ts +159 -0
- package/dist/marketplace.js +102 -0
- package/dist/media-json.d.ts +181 -0
- package/dist/media-json.js +204 -0
- package/dist/media-library.d.ts +11 -0
- package/dist/media-library.js +15 -0
- package/dist/media-request-id.d.ts +7 -0
- package/dist/media-request-id.js +16 -0
- package/dist/media.d.ts +354 -0
- package/dist/media.js +654 -0
- package/dist/method-refusal.d.ts +64 -0
- package/dist/method-refusal.js +48 -0
- package/dist/pending.d.ts +10 -0
- package/dist/pending.js +10 -0
- package/dist/query.d.ts +76 -0
- package/dist/query.js +195 -0
- package/dist/react-mount.d.ts +23 -0
- package/dist/react-mount.js +108 -0
- package/dist/react.d.ts +41 -0
- package/dist/react.js +111 -0
- package/dist/read-copy.d.ts +103 -0
- package/dist/read-copy.js +195 -0
- package/dist/roles/files.d.ts +295 -0
- package/dist/roles/files.js +184 -0
- package/dist/root.d.ts +21 -0
- package/dist/root.js +1 -0
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.js +1 -0
- package/dist/status.d.ts +17 -0
- package/dist/status.js +50 -0
- package/dist/storage-wire.d.ts +167 -0
- package/dist/storage-wire.js +115 -0
- package/dist/storage.d.ts +72 -0
- package/dist/storage.js +143 -0
- package/dist/store.d.ts +11 -0
- package/dist/store.js +1 -0
- package/dist/test-kit/git.d.ts +31 -0
- package/dist/test-kit/git.js +174 -0
- package/dist/ui.d.ts +169 -0
- package/dist/ui.js +10 -0
- package/dist/window.d.ts +41 -0
- package/dist/window.js +15 -0
- package/dist/world.d.ts +16 -0
- package/dist/world.js +17 -0
- package/docs/api/README.md +28 -0
- package/docs/api/app-build-contract.md +113 -0
- package/docs/api/backend-declaration.md +62 -0
- package/docs/api/backend-definition.md +215 -0
- package/docs/api/backend.md +269 -0
- package/docs/api/errors.md +169 -0
- package/docs/api/files.md +91 -0
- package/docs/api/gills.md +164 -0
- package/docs/api/git-commit.md +279 -0
- package/docs/api/git-rpc.md +243 -0
- package/docs/api/git-steps.md +1010 -0
- package/docs/api/git-wire.md +197 -0
- package/docs/api/git.md +579 -0
- package/docs/api/index.md +2880 -0
- package/docs/api/media-json.md +507 -0
- package/docs/api/media-request-id.md +32 -0
- package/docs/api/modules.md +32 -0
- package/docs/api/query.md +253 -0
- package/docs/api/react.md +216 -0
- package/docs/api/read-copy.md +204 -0
- package/docs/api/rpc.md +128 -0
- package/docs/api/storage.md +620 -0
- package/package.json +197 -3
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
3
|
+
import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import * as z from "zod";
|
|
7
|
+
/** Real smart HTTP writes and git plumbing reads in one disposable bare repository. */
|
|
8
|
+
export function realGit() {
|
|
9
|
+
const root = mkdtempSync(join(tmpdir(), "agar-real-git-"));
|
|
10
|
+
const run = (name, ...args) => execFileSync("git", [`--git-dir=${join(root, `${name}.git`)}`, ...args], {
|
|
11
|
+
encoding: "utf8",
|
|
12
|
+
}).trim();
|
|
13
|
+
const info = (name) => existsSync(join(root, `${name}.git`))
|
|
14
|
+
? { name, defaultBranch: "main", lastPushAt: null, source: null }
|
|
15
|
+
: null;
|
|
16
|
+
const readCommit = (name, hash) => {
|
|
17
|
+
const found = spawnSync("git", [`--git-dir=${join(root, `${name}.git`)}`, "cat-file", "-t", hash], { encoding: "utf8" });
|
|
18
|
+
if (found.status !== 0 || found.stdout.trim() !== "commit")
|
|
19
|
+
return null;
|
|
20
|
+
const [oid, treeHash, parents, authorName, authorEmail, committerName, committerEmail, authoredAt, committedAt, message,] = z
|
|
21
|
+
.tuple([
|
|
22
|
+
z.string(),
|
|
23
|
+
z.string(),
|
|
24
|
+
z.string(),
|
|
25
|
+
z.string(),
|
|
26
|
+
z.string(),
|
|
27
|
+
z.string(),
|
|
28
|
+
z.string(),
|
|
29
|
+
z.string(),
|
|
30
|
+
z.string(),
|
|
31
|
+
z.string(),
|
|
32
|
+
])
|
|
33
|
+
.parse(run(name, "show", "-s", "--format=%H%x00%T%x00%P%x00%an%x00%ae%x00%cn%x00%ce%x00%at%x00%ct%x00%B", hash).split("\0"));
|
|
34
|
+
return {
|
|
35
|
+
hash: oid,
|
|
36
|
+
treeHash,
|
|
37
|
+
parents: parents ? parents.split(" ") : [],
|
|
38
|
+
author: { name: authorName, email: authorEmail },
|
|
39
|
+
committer: { name: committerName, email: committerEmail },
|
|
40
|
+
authoredAt: Number(authoredAt),
|
|
41
|
+
committedAt: Number(committedAt),
|
|
42
|
+
message,
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
const git = {
|
|
46
|
+
cloneUrl: (name) => {
|
|
47
|
+
if (info(name) === null)
|
|
48
|
+
return Promise.reject(new Error("Repository unavailable"));
|
|
49
|
+
return Promise.resolve(pathToFileURL(join(root, `${name}.git`)).href);
|
|
50
|
+
},
|
|
51
|
+
info: (name) => Promise.resolve(info(name)),
|
|
52
|
+
create: (name, options) => {
|
|
53
|
+
if (!info(name)) {
|
|
54
|
+
execFileSync("git", [
|
|
55
|
+
"init",
|
|
56
|
+
"--bare",
|
|
57
|
+
"-q",
|
|
58
|
+
"-b",
|
|
59
|
+
options?.defaultBranch ?? "main",
|
|
60
|
+
`${name}.git`,
|
|
61
|
+
], { cwd: root });
|
|
62
|
+
run(name, "config", "http.receivepack", "true");
|
|
63
|
+
}
|
|
64
|
+
const created = info(name);
|
|
65
|
+
if (!created)
|
|
66
|
+
throw new Error("Repository creation failed");
|
|
67
|
+
return Promise.resolve(created);
|
|
68
|
+
},
|
|
69
|
+
fork: () => Promise.reject(new Error("Unexpected fork")),
|
|
70
|
+
delete: (name) => {
|
|
71
|
+
const existed = info(name) !== null;
|
|
72
|
+
rmSync(join(root, `${name}.git`), { recursive: true, force: true });
|
|
73
|
+
return Promise.resolve(existed);
|
|
74
|
+
},
|
|
75
|
+
readCommit: (name, hash) => Promise.resolve(readCommit(name, hash)),
|
|
76
|
+
log: (name, { ref, limit = 50, offset = 0 }) => {
|
|
77
|
+
if (!readCommit(name, ref))
|
|
78
|
+
return Promise.resolve([]);
|
|
79
|
+
return Promise.resolve(run(name, "rev-list", "--first-parent", `--max-count=${String(limit)}`, `--skip=${String(offset)}`, ref)
|
|
80
|
+
.split("\n")
|
|
81
|
+
.filter(Boolean)
|
|
82
|
+
.map((hash) => {
|
|
83
|
+
const commit = readCommit(name, hash);
|
|
84
|
+
if (!commit)
|
|
85
|
+
throw new Error("Commit disappeared");
|
|
86
|
+
return commit;
|
|
87
|
+
}));
|
|
88
|
+
},
|
|
89
|
+
readTree: (name, hash) => Promise.resolve(run(name, "ls-tree", "-z", hash)
|
|
90
|
+
.split("\0")
|
|
91
|
+
.filter(Boolean)
|
|
92
|
+
.map((line) => {
|
|
93
|
+
const [head, entryName] = z
|
|
94
|
+
.tuple([z.string(), z.string()])
|
|
95
|
+
.parse(line.split("\t"));
|
|
96
|
+
const [mode, type, oid] = z
|
|
97
|
+
.tuple([
|
|
98
|
+
z.string(),
|
|
99
|
+
z.enum(["tree", "blob", "commit"]),
|
|
100
|
+
z.string(),
|
|
101
|
+
])
|
|
102
|
+
.parse(head.split(" "));
|
|
103
|
+
return { name: entryName, mode, type, hash: oid };
|
|
104
|
+
})),
|
|
105
|
+
readBlob: (name, hash) => Promise.resolve(new Uint8Array(execFileSync("git", [
|
|
106
|
+
`--git-dir=${join(root, `${name}.git`)}`,
|
|
107
|
+
"cat-file",
|
|
108
|
+
"blob",
|
|
109
|
+
hash,
|
|
110
|
+
]))),
|
|
111
|
+
refs: (name) => Promise.resolve(info(name)
|
|
112
|
+
? run(name, "for-each-ref", "--format=%(refname) %(objectname)")
|
|
113
|
+
.split("\n")
|
|
114
|
+
.filter(Boolean)
|
|
115
|
+
.map((line) => {
|
|
116
|
+
const [ref, hash] = z
|
|
117
|
+
.tuple([z.string(), z.string()])
|
|
118
|
+
.parse(line.split(" "));
|
|
119
|
+
return { name: ref, hash };
|
|
120
|
+
})
|
|
121
|
+
: []),
|
|
122
|
+
exchange: (name, request) => {
|
|
123
|
+
const result = spawnSync("git", ["http-backend"], {
|
|
124
|
+
input: request.body ?? new Uint8Array(),
|
|
125
|
+
// A whole App source pack is far over spawnSync's 1 MiB default.
|
|
126
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
127
|
+
env: {
|
|
128
|
+
...process.env,
|
|
129
|
+
GIT_PROJECT_ROOT: root,
|
|
130
|
+
GIT_HTTP_EXPORT_ALL: "1",
|
|
131
|
+
PATH_INFO: request.phase === "advertise"
|
|
132
|
+
? `/${name}.git/info/refs`
|
|
133
|
+
: `/${name}.git/git-${request.service}`,
|
|
134
|
+
REQUEST_METHOD: request.phase === "advertise" ? "GET" : "POST",
|
|
135
|
+
QUERY_STRING: request.phase === "advertise"
|
|
136
|
+
? `service=git-${request.service}`
|
|
137
|
+
: "",
|
|
138
|
+
CONTENT_TYPE: request.headers["content-type"] ?? "",
|
|
139
|
+
GIT_PROTOCOL: request.headers["git-protocol"] ?? "",
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
if (result.status !== 0)
|
|
143
|
+
throw new Error("git http-backend failed");
|
|
144
|
+
const output = Buffer.from(result.stdout);
|
|
145
|
+
const split = output.indexOf("\r\n\r\n");
|
|
146
|
+
const headers = {};
|
|
147
|
+
let status = 200;
|
|
148
|
+
for (const line of output
|
|
149
|
+
.subarray(0, split)
|
|
150
|
+
.toString("utf8")
|
|
151
|
+
.split("\r\n")) {
|
|
152
|
+
const colon = line.indexOf(":");
|
|
153
|
+
const key = line.slice(0, colon).toLowerCase();
|
|
154
|
+
const value = line.slice(colon + 1).trim();
|
|
155
|
+
if (key === "status")
|
|
156
|
+
status = Number(value.split(" ")[0]);
|
|
157
|
+
else
|
|
158
|
+
headers[key] = value;
|
|
159
|
+
}
|
|
160
|
+
return Promise.resolve({
|
|
161
|
+
status,
|
|
162
|
+
headers,
|
|
163
|
+
body: new Uint8Array(result.stdout.subarray(split + 4)),
|
|
164
|
+
});
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
return {
|
|
168
|
+
git,
|
|
169
|
+
run,
|
|
170
|
+
close: () => {
|
|
171
|
+
rmSync(root, { recursive: true });
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/** Deliberately narrow shell affordances; domain work belongs to capabilities. */
|
|
2
|
+
export type HostUi = {
|
|
3
|
+
/** Open the host-owned Computer picker; selection arrives through App context. */
|
|
4
|
+
requestComputerChoice(): Promise<void>;
|
|
5
|
+
/** Request a host browser action from a fresh user click in this App. */
|
|
6
|
+
requestBrowserAction(input: AppBrowserAction): Promise<AppBrowserActionOutcome>;
|
|
7
|
+
/**
|
|
8
|
+
* Ask the trusted host for App rights. The host, never the App, renders the
|
|
9
|
+
* consent and writes any grant; an empty request opens App permissions.
|
|
10
|
+
*/
|
|
11
|
+
requestAppPermissions(input: AppPermissionRequest): Promise<AppPermissionOutcome>;
|
|
12
|
+
/** Ask the host to open an already admitted Computer file. */
|
|
13
|
+
openNavigation(input: FileNavigationInput): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Declare this window's status bar items, such as "2 documents" or a Ports
|
|
16
|
+
* button. The host renders them beside the Computer it owns; the newest
|
|
17
|
+
* report wins and an empty list clears them.
|
|
18
|
+
*/
|
|
19
|
+
reportStatus(items: readonly AppStatusItem[]): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Hear the person use one of this window's declared status items. One
|
|
22
|
+
* owner at a time; the host never renders App UI in its chrome.
|
|
23
|
+
*/
|
|
24
|
+
onStatusAction(handler: AppStatusActionHandler): () => void;
|
|
25
|
+
/** Leave the App for the host's Billing page for this Team. */
|
|
26
|
+
openTeamBilling(): Promise<void>;
|
|
27
|
+
/** Suggest this App's desktop Gills while focused with browser activation.
|
|
28
|
+
* The host shows a notice; the member must choose Review to open Settings.
|
|
29
|
+
* The App receives no layout or placement authority. */
|
|
30
|
+
openDesktopSettings(): Promise<void>;
|
|
31
|
+
/** Tell the host which Agent conversation this App currently has
|
|
32
|
+
* selected, or null when none is selected. */
|
|
33
|
+
reportAgentSessionSelection(selection: AgentSessionSelection | null): Promise<void>;
|
|
34
|
+
/** Ask the host to show a transient toast notification. */
|
|
35
|
+
showToast(input: ToastInput): Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
/** The most readouts one App window's status bar shows. */
|
|
38
|
+
export declare const APP_STATUS_ITEMS_MAX = 6;
|
|
39
|
+
/** The longest readout a window's status bar shows. */
|
|
40
|
+
export declare const APP_STATUS_TEXT_MAX = 80;
|
|
41
|
+
/** The most choices one status menu offers. */
|
|
42
|
+
export declare const APP_STATUS_OPTIONS_MAX = 16;
|
|
43
|
+
/** The marks a host can draw before a status button's label. */
|
|
44
|
+
export type AppStatusIcon = "folder" | "ports" | "processes" | "access";
|
|
45
|
+
/** A readout's live state, shown as a small light before its text. */
|
|
46
|
+
export type AppStatusTone = "neutral" | "success" | "warning" | "error";
|
|
47
|
+
/** One choice in a status menu, such as a folder or a port. */
|
|
48
|
+
export type AppStatusOption = Readonly<{
|
|
49
|
+
id: string;
|
|
50
|
+
text: string;
|
|
51
|
+
/** Marks the current choice in a picker-style menu. */
|
|
52
|
+
checked?: boolean;
|
|
53
|
+
disabled?: boolean;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* One item an App declares for its window's status bar, as data: a readout,
|
|
57
|
+
* a button, a toggle, or a menu of choices. Using one delivers an
|
|
58
|
+
* {@link AppStatusAction} back to the App.
|
|
59
|
+
*/
|
|
60
|
+
export type AppStatusItem = Readonly<{
|
|
61
|
+
id: string;
|
|
62
|
+
text: string;
|
|
63
|
+
/** Hold this item at the bar's far end, like a save state. */
|
|
64
|
+
end?: boolean;
|
|
65
|
+
kind: "text";
|
|
66
|
+
tone?: AppStatusTone;
|
|
67
|
+
}> | Readonly<{
|
|
68
|
+
id: string;
|
|
69
|
+
text: string;
|
|
70
|
+
/** Hold this item at the bar's far end, like a save state. */
|
|
71
|
+
end?: boolean;
|
|
72
|
+
kind: "button";
|
|
73
|
+
/** A host-drawn mark before the label. */
|
|
74
|
+
icon?: AppStatusIcon;
|
|
75
|
+
/** A positive count after the label; zero is hidden. */
|
|
76
|
+
count?: number;
|
|
77
|
+
/** A longer description, such as a full folder path. */
|
|
78
|
+
title?: string;
|
|
79
|
+
disabled?: boolean;
|
|
80
|
+
/** The button opens App UI: a tray or a dialog. */
|
|
81
|
+
opens?: "dialog";
|
|
82
|
+
/** Whether the UI this button opens is open now. */
|
|
83
|
+
expanded?: boolean;
|
|
84
|
+
}> | Readonly<{
|
|
85
|
+
id: string;
|
|
86
|
+
text: string;
|
|
87
|
+
/** Hold this item at the bar's far end, like a save state. */
|
|
88
|
+
end?: boolean;
|
|
89
|
+
kind: "toggle";
|
|
90
|
+
pressed: boolean;
|
|
91
|
+
}> | Readonly<{
|
|
92
|
+
id: string;
|
|
93
|
+
text: string;
|
|
94
|
+
/** Hold this item at the bar's far end, like a save state. */
|
|
95
|
+
end?: boolean;
|
|
96
|
+
kind: "menu";
|
|
97
|
+
count?: number;
|
|
98
|
+
title?: string;
|
|
99
|
+
options: readonly AppStatusOption[];
|
|
100
|
+
}>;
|
|
101
|
+
/**
|
|
102
|
+
* The person used a status item; `optionId` names a chosen menu option.
|
|
103
|
+
* `anchor` is where the item sits along the App's surface, in CSS pixels from
|
|
104
|
+
* its inline start, so App UI it opens can sit above it.
|
|
105
|
+
*/
|
|
106
|
+
export type AppStatusAction = Readonly<{
|
|
107
|
+
itemId: string;
|
|
108
|
+
optionId?: string;
|
|
109
|
+
anchor?: Readonly<{
|
|
110
|
+
start: number;
|
|
111
|
+
width: number;
|
|
112
|
+
}>;
|
|
113
|
+
}>;
|
|
114
|
+
/** Handles one status action; `true` when the App acted on it. */
|
|
115
|
+
export type AppStatusActionHandler = (action: AppStatusAction) => boolean | Promise<boolean>;
|
|
116
|
+
/** Exact Agent conversation selected by an App for the authenticated shell. */
|
|
117
|
+
export type AgentSessionSelection = Readonly<{
|
|
118
|
+
agentId: string;
|
|
119
|
+
sessionId: string;
|
|
120
|
+
}>;
|
|
121
|
+
/** A presentation-neutral request to open an already admitted Computer file. */
|
|
122
|
+
export type FileNavigationInput = {
|
|
123
|
+
readonly computerId: string;
|
|
124
|
+
readonly path: string;
|
|
125
|
+
};
|
|
126
|
+
/** A transient notification an App asks its host to show. */
|
|
127
|
+
export type ToastInput = {
|
|
128
|
+
readonly message: string;
|
|
129
|
+
readonly tone?: "error" | "info" | "success" | "warning";
|
|
130
|
+
};
|
|
131
|
+
/** Agent rights an App may ask its host to grant through consent. */
|
|
132
|
+
export type AgentAccessOperation = "agent.list" | "agent.manage" | "agent.read" | "agent.send";
|
|
133
|
+
/** Computer rights an App may ask its host to grant through consent. */
|
|
134
|
+
export type ComputerAccessOperation = "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute";
|
|
135
|
+
/** The rights an App asks for; the host bounds them by its declared ceiling. */
|
|
136
|
+
export type AppPermissionRequest = Readonly<{
|
|
137
|
+
agents?: readonly AgentAccessOperation[];
|
|
138
|
+
computers?: readonly ComputerAccessOperation[];
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* `granted`: the host saved a grant covering the request. `declined`: the user
|
|
142
|
+
* said not now. `customize`: the host opened its full permission settings.
|
|
143
|
+
*/
|
|
144
|
+
export type AppPermissionOutcome = "granted" | "declined" | "customize";
|
|
145
|
+
/** Maximum file size sent through the user-initiated host browser door. */
|
|
146
|
+
export declare const APP_BROWSER_SAVE_MAX_BYTES: number;
|
|
147
|
+
/** Maximum UTF-8 text size sent to the host clipboard. */
|
|
148
|
+
export declare const APP_BROWSER_COPY_MAX_BYTES: number;
|
|
149
|
+
/** Data only; browser authority and the gesture check belong to the host. */
|
|
150
|
+
export type AppBrowserAction = Readonly<{
|
|
151
|
+
kind: "saveFile";
|
|
152
|
+
name: string;
|
|
153
|
+
mime: string;
|
|
154
|
+
bytes: Uint8Array;
|
|
155
|
+
}> | Readonly<{
|
|
156
|
+
kind: "copyText";
|
|
157
|
+
text: string;
|
|
158
|
+
}>;
|
|
159
|
+
/** A browser action can be refused without disconnecting the App. */
|
|
160
|
+
export type AppBrowserActionRefusal = Readonly<{
|
|
161
|
+
kind: "refused";
|
|
162
|
+
reason: "no-user-gesture" | "too-large" | "invalid-request" | "unavailable" | "denied" | "busy";
|
|
163
|
+
}>;
|
|
164
|
+
/** Saved means a browser download was initiated, not a confirmed disk write. */
|
|
165
|
+
export type AppBrowserActionOutcome = Readonly<{
|
|
166
|
+
kind: "saved";
|
|
167
|
+
}> | Readonly<{
|
|
168
|
+
kind: "copied";
|
|
169
|
+
}> | AppBrowserActionRefusal;
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The most readouts one App window's status bar shows. */
|
|
2
|
+
export const APP_STATUS_ITEMS_MAX = 6;
|
|
3
|
+
/** The longest readout a window's status bar shows. */
|
|
4
|
+
export const APP_STATUS_TEXT_MAX = 80;
|
|
5
|
+
/** The most choices one status menu offers. */
|
|
6
|
+
export const APP_STATUS_OPTIONS_MAX = 16;
|
|
7
|
+
/** Maximum file size sent through the user-initiated host browser door. */
|
|
8
|
+
export const APP_BROWSER_SAVE_MAX_BYTES = 32 * 1024 * 1024;
|
|
9
|
+
/** Maximum UTF-8 text size sent to the host clipboard. */
|
|
10
|
+
export const APP_BROWSER_COPY_MAX_BYTES = 1024 * 1024;
|
package/dist/window.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Disposer } from "./store.js";
|
|
2
|
+
/** Consulted before the person closes the App's window; return (or
|
|
3
|
+
* resolve) `true` to allow the close. */
|
|
4
|
+
export type BeforeAppClose = () => boolean | Promise<boolean>;
|
|
5
|
+
/**
|
|
6
|
+
* Version of the navigation contract an App publishes. The host rejects any
|
|
7
|
+
* other version, so a future shape can never be misread as this one.
|
|
8
|
+
*/
|
|
9
|
+
export declare const APP_NAVIGATION_CONTRACT_VERSION: 1;
|
|
10
|
+
/** The longest page title a host shows beside the App's own name. */
|
|
11
|
+
export declare const APP_NAVIGATION_TITLE_MAX = 80;
|
|
12
|
+
/**
|
|
13
|
+
* What the App's own router can do right now. The App owns its history; the
|
|
14
|
+
* host only offers a Back affordance and relays the person's request.
|
|
15
|
+
*/
|
|
16
|
+
export type AppNavigationState = Readonly<{
|
|
17
|
+
canGoBack: boolean;
|
|
18
|
+
/** The current page's title, shown after the App name in window chrome. */
|
|
19
|
+
title?: string;
|
|
20
|
+
}>;
|
|
21
|
+
/** Go back one step in the App's own history; `true` when it moved. */
|
|
22
|
+
export type AppBackHandler = () => boolean | Promise<boolean>;
|
|
23
|
+
/** The App's half of the host navigation contract. */
|
|
24
|
+
export type HostNavigation = Readonly<{
|
|
25
|
+
/** Report the latest navigation state; the newest report wins. */
|
|
26
|
+
publish(state: AppNavigationState): Promise<void>;
|
|
27
|
+
/** Own the host's Back requests; one owner at a time. */
|
|
28
|
+
onBack(handler: AppBackHandler): Disposer;
|
|
29
|
+
}>;
|
|
30
|
+
/** App-owned presentation policy consulted before a user closes its window. */
|
|
31
|
+
export type AppWindow = Readonly<{
|
|
32
|
+
/** Register a close-guard handler; one owner at a time. Call the
|
|
33
|
+
* returned Disposer to withdraw it. */
|
|
34
|
+
onBeforeClose(handler: BeforeAppClose): Disposer;
|
|
35
|
+
navigation: HostNavigation;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Navigation for a root with no host chrome, such as a workbench fixture: it
|
|
39
|
+
* accepts every report and never asks the App to go back.
|
|
40
|
+
*/
|
|
41
|
+
export declare const inertHostNavigation: HostNavigation;
|
package/dist/window.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version of the navigation contract an App publishes. The host rejects any
|
|
3
|
+
* other version, so a future shape can never be misread as this one.
|
|
4
|
+
*/
|
|
5
|
+
export const APP_NAVIGATION_CONTRACT_VERSION = 1;
|
|
6
|
+
/** The longest page title a host shows beside the App's own name. */
|
|
7
|
+
export const APP_NAVIGATION_TITLE_MAX = 80;
|
|
8
|
+
/**
|
|
9
|
+
* Navigation for a root with no host chrome, such as a workbench fixture: it
|
|
10
|
+
* accepts every report and never asks the App to go back.
|
|
11
|
+
*/
|
|
12
|
+
export const inertHostNavigation = Object.freeze({
|
|
13
|
+
publish: () => Promise.resolve(),
|
|
14
|
+
onBack: () => () => undefined,
|
|
15
|
+
});
|
package/dist/world.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Public MCP world-seat vocabulary, independent of any engine or host. */
|
|
2
|
+
export declare const worldToolNames: Readonly<{
|
|
3
|
+
readonly observe: "world_observe";
|
|
4
|
+
readonly command: "world_command";
|
|
5
|
+
readonly explain: "world_explain";
|
|
6
|
+
readonly say: "world_say";
|
|
7
|
+
readonly snapshot: "world_snapshot";
|
|
8
|
+
readonly advance: "world_advance";
|
|
9
|
+
}>;
|
|
10
|
+
export declare const worldMcpManifest: Readonly<{
|
|
11
|
+
id: "world-mcp-v1";
|
|
12
|
+
module: "world";
|
|
13
|
+
tools: Readonly<{
|
|
14
|
+
[k: string]: string;
|
|
15
|
+
}>;
|
|
16
|
+
}>;
|
package/dist/world.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Public MCP world-seat vocabulary, independent of any engine or host. */
|
|
2
|
+
export const worldToolNames = Object.freeze({
|
|
3
|
+
observe: "world_observe",
|
|
4
|
+
command: "world_command",
|
|
5
|
+
explain: "world_explain",
|
|
6
|
+
say: "world_say",
|
|
7
|
+
snapshot: "world_snapshot",
|
|
8
|
+
advance: "world_advance",
|
|
9
|
+
});
|
|
10
|
+
export const worldMcpManifest = Object.freeze({
|
|
11
|
+
id: "world-mcp-v1",
|
|
12
|
+
module: "world",
|
|
13
|
+
tools: Object.freeze(Object.fromEntries(Object.entries(worldToolNames).map(([operation, name]) => [
|
|
14
|
+
name,
|
|
15
|
+
operation,
|
|
16
|
+
]))),
|
|
17
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
|
|
2
|
+
|
|
3
|
+
**@fungi.computer/agar**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Agar API overview
|
|
8
|
+
|
|
9
|
+
| Import | Export | Purpose |
|
|
10
|
+
| ------------------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
|
|
11
|
+
| `@fungi.computer/agar` | `connectApp` | Connect a host-mounted App frontend and receive its context and grants. |
|
|
12
|
+
| `@fungi.computer/agar` | `defineCapability`, `AppError` | Declare a typed host capability; the SDK's one typed failure. |
|
|
13
|
+
| `@fungi.computer/agar/host` | `connectAppHost` | Mount an App in an author-owned iframe test or standalone page. |
|
|
14
|
+
| `@fungi.computer/agar/react` | `mountApp`, `useAppContext` | Mount a React App and read its host context. |
|
|
15
|
+
| `@fungi.computer/agar/query` | `queryKeys` | TanStack Query keys and live feeds for host data. |
|
|
16
|
+
| `@fungi.computer/agar/errors` | `describeAppError` | Turn a failure into approved, action-hinted UI copy. |
|
|
17
|
+
| `@fungi.computer/agar/backend-definition` | `defineAppBackend`, `defineAppMethod` | Define typed backend methods once, with Zod input and output. |
|
|
18
|
+
| `@fungi.computer/agar/backend-declaration` | `buildAppApi`, `buildAppDeclaration` | Project the backend definition to the JSON Schema App API at build time. |
|
|
19
|
+
| `@fungi.computer/agar/backend` | `appBackend` | Call the App's own backend from its frontend. |
|
|
20
|
+
| `@fungi.computer/agar/rpc` | `rpcHandleSchema`, `rpcMethod` | Validate object-capability handles received over Cap'n Web. |
|
|
21
|
+
| `@fungi.computer/agar/files` | `readAppFile`, `writeAppFile` | Turn a host-owned file read or write handle into a `File` or an upload. |
|
|
22
|
+
| `@fungi.computer/agar/storage` | `appStorage` | Read, write and watch the App's own member and Team data. |
|
|
23
|
+
| `@fungi.computer/agar/computer-contracts` | `workflowGitPassResultSchema`, `WorkflowGitPassResult` | Validate host-issued, credential-free Workflow pass metadata without granting authority. |
|
|
24
|
+
|
|
25
|
+
A host decides what an App may do: the frontend asks for a capability and the
|
|
26
|
+
host grants, denies or revokes it. The backend definition is runtime-neutral;
|
|
27
|
+
the same methods back the App's own UI and, through the generated App API, the
|
|
28
|
+
tools a host offers to Agents. The generated module pages below list every type.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
|
|
2
|
+
|
|
3
|
+
[**@fungi.computer/agar**](README.md)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
[@fungi.computer/agar](modules.md) / app-build-contract
|
|
8
|
+
|
|
9
|
+
# app-build-contract
|
|
10
|
+
|
|
11
|
+
## Variables
|
|
12
|
+
|
|
13
|
+
### teamAppBuildFailureCodeSchema
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const teamAppBuildFailureCodeSchema: ZodEnum<{
|
|
17
|
+
unavailable: "unavailable";
|
|
18
|
+
denied: "denied";
|
|
19
|
+
invalid: "invalid";
|
|
20
|
+
conflict: "conflict";
|
|
21
|
+
build_failed: "build_failed";
|
|
22
|
+
}>;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Refusals emitted by the Team App build owner.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
### appBuildReplySchema
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const appBuildReplySchema: ZodUnion<
|
|
33
|
+
readonly [
|
|
34
|
+
ZodObject<
|
|
35
|
+
{
|
|
36
|
+
kind: ZodLiteral<"pending">;
|
|
37
|
+
retryAfterMs: ZodNumber;
|
|
38
|
+
},
|
|
39
|
+
$strict
|
|
40
|
+
>,
|
|
41
|
+
ZodObject<
|
|
42
|
+
{
|
|
43
|
+
releaseId: ZodString;
|
|
44
|
+
previewUrl: ZodURL;
|
|
45
|
+
},
|
|
46
|
+
$strict
|
|
47
|
+
>,
|
|
48
|
+
ZodObject<
|
|
49
|
+
{
|
|
50
|
+
error: ZodEnum<{
|
|
51
|
+
unavailable: "unavailable";
|
|
52
|
+
denied: "denied";
|
|
53
|
+
invalid: "invalid";
|
|
54
|
+
conflict: "conflict";
|
|
55
|
+
build_failed: "build_failed";
|
|
56
|
+
}>;
|
|
57
|
+
},
|
|
58
|
+
$strict
|
|
59
|
+
>,
|
|
60
|
+
]
|
|
61
|
+
>;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Pending, completed or failed reply from the App build owner.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### appBuildBrokerResultSchema
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const appBuildBrokerResultSchema: ZodUnion<
|
|
72
|
+
readonly [
|
|
73
|
+
ZodUnion<
|
|
74
|
+
readonly [
|
|
75
|
+
ZodObject<
|
|
76
|
+
{
|
|
77
|
+
kind: ZodLiteral<"pending">;
|
|
78
|
+
retryAfterMs: ZodNumber;
|
|
79
|
+
},
|
|
80
|
+
$strict
|
|
81
|
+
>,
|
|
82
|
+
ZodObject<
|
|
83
|
+
{
|
|
84
|
+
releaseId: ZodString;
|
|
85
|
+
previewUrl: ZodURL;
|
|
86
|
+
},
|
|
87
|
+
$strict
|
|
88
|
+
>,
|
|
89
|
+
ZodObject<
|
|
90
|
+
{
|
|
91
|
+
error: ZodEnum<{
|
|
92
|
+
unavailable: "unavailable";
|
|
93
|
+
denied: "denied";
|
|
94
|
+
invalid: "invalid";
|
|
95
|
+
conflict: "conflict";
|
|
96
|
+
build_failed: "build_failed";
|
|
97
|
+
}>;
|
|
98
|
+
},
|
|
99
|
+
$strict
|
|
100
|
+
>,
|
|
101
|
+
]
|
|
102
|
+
>,
|
|
103
|
+
ZodObject<
|
|
104
|
+
{
|
|
105
|
+
error: ZodString;
|
|
106
|
+
},
|
|
107
|
+
$strict
|
|
108
|
+
>,
|
|
109
|
+
]
|
|
110
|
+
>;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Complete App build binding reply, including broker admission failures.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
|
|
2
|
+
|
|
3
|
+
[**@fungi.computer/agar**](README.md)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
[@fungi.computer/agar](modules.md) / backend-declaration
|
|
8
|
+
|
|
9
|
+
# backend-declaration
|
|
10
|
+
|
|
11
|
+
## Functions
|
|
12
|
+
|
|
13
|
+
### buildAppApi()
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
function buildAppApi<Context>(backend): AppApi;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Build-only API projection from the schemas used by runtime calls.
|
|
20
|
+
|
|
21
|
+
#### Type Parameters
|
|
22
|
+
|
|
23
|
+
| Type Parameter |
|
|
24
|
+
| -------------- |
|
|
25
|
+
| `Context` |
|
|
26
|
+
|
|
27
|
+
#### Parameters
|
|
28
|
+
|
|
29
|
+
| Parameter | Type |
|
|
30
|
+
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `backend` | `Pick`\<[`AppBackendDefinition`](backend-definition.md#appbackenddefinition)\<`Context`\>, `"methods"` \| `"events"` \| `"toolFamily"`\> |
|
|
32
|
+
|
|
33
|
+
#### Returns
|
|
34
|
+
|
|
35
|
+
`AppApi`
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### buildAppDeclaration()
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
function buildAppDeclaration<Context>(backend, declaration): AppDeclaration;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Strict build-only declaration generation; Workers never import this module.
|
|
46
|
+
|
|
47
|
+
#### Type Parameters
|
|
48
|
+
|
|
49
|
+
| Type Parameter |
|
|
50
|
+
| -------------- |
|
|
51
|
+
| `Context` |
|
|
52
|
+
|
|
53
|
+
#### Parameters
|
|
54
|
+
|
|
55
|
+
| Parameter | Type |
|
|
56
|
+
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
57
|
+
| `backend` | `Pick`\<[`AppBackendDefinition`](backend-definition.md#appbackenddefinition)\<`Context`\>, `"methods"` \| `"events"` \| `"gills"` \| `"sync"` \| `"toolFamily"`\> |
|
|
58
|
+
| `declaration` | `unknown` |
|
|
59
|
+
|
|
60
|
+
#### Returns
|
|
61
|
+
|
|
62
|
+
`AppDeclaration`
|