阿加尔语( Agar)@fungi.computer/agar(中文(简体) )
Agar是建造一个在真菌上运行的 App 的合同,或者你自己的 牡蛎您定义 App 的后端 方法与 Zod; 相同的方法返回 App 自己的 UI 并成为 键入给代理商的主机要约的工具。 App的前端连接它的主机和 要求它需要什么,例如计算机、代理或图像生成方面的文件, 和东道方给予,否定或取消每一种能力.
要运行 Apps 而不是构建它们,首先 牡蛎。要运行代理,请从 Shi。 。 。 .
安装
npm install @fungi.computer/agar zod
Agar是无害环境管理,需要节点24或更新型来构建一个App. 反应切入点
带 react, (中文(简体) ), react-dom 财务报告和审定财务报表 @tanstack/react-query 作为可选同伴
核心SDK和后端入站点不需要它们.
快开始
定义 App 后端一次 。 它的 Zod 计划给处理器类型脚本 签约并制作JSON Schema API作为工具给代理商的主持人节目. 这个 示例在平原节点运行;不需要主机来定义或调用方法.
import * as z from "zod";
import {
defineAppBackend,
defineAppMethod,
} from "@fungi.computer/agar/backend-definition";
import { buildAppApi } from "@fungi.computer/agar/backend-declaration";
const notes = new Map<string, string>();
const appBackend = defineAppBackend({
methods: {
saveNote: defineAppMethod({
description: "Save a note under a title",
effect: "write",
requires: [],
input: z.object({ title: z.string().min(1), text: z.string() }),
output: z.object({ saved: z.boolean() }),
handler: ({ title, text }) => {
notes.set(title, text);
return { saved: true };
},
}),
},
});
const api = buildAppApi(appBackend);
console.log(Object.keys(api.methods)); // ["saveNote"]
const result = await appBackend.call(
"saveNote",
{ title: "hello", text: "from Agar" },
undefined,
{ computerId: null, actor: { kind: "member", memberId: "member_example" } },
);
console.log(result); // { saved: true }
要将它变成可安装的 App, 请复制
说明示例 App
运行 npm create fungi-app@latest my-app并安装在牡蛎上.
后端方法
点 fungi.backendDefinition 在应用程序 package.json 运行时间中和
模块,例如 backend/methods.ts 出口额
appBackend = defineAppBackend({ methods })。该建筑获得 App 的 API
从这个定义和清单中声明 fungi.app
(能力、命令、储存和 backend.bindings);您写出否
声明模块和无 fungi.app.api 页:1 一种要求
app不声明的能力在构建时被拒绝.
每个方法都宣布 Zod input 财务报告和审定财务报表 output页:1 description,一个 effect,则
能力 requires 键入 handler。调用解析输入和
输出,所以处理器不能返回其方案拒绝的数据。 其他选项:
hidden: true保持维持方法远离工作流程和物剂发现; 直通电话仍然需要他们的许可.pending: true让一个长期方法返回pending(5000)从@fungi.computer/agar/backend-definition虽然它工作, 所以一个东道民意测验 和同一种能力键。 延迟为1000至60,000毫秒.events打开defineAppBackend命名 App 发送到的事件EVENTS.emit,每个带description和整个Zod计划{ type, timestamp, data }载荷.
通过导出后端的持久对象面类
appBackend.implement(YourFacetClass),生成宣告的方法.
拒绝采用手写或未申报的方法。 保留 cloudflare:workers节点
定义模块外的评估时间内置和网络呼叫;
网络工作属于内部处理者.
连接前端
connectApp({ host: "parent", signal }) 从 @fungi.computer/agar 连接一个
App页面通过母框的握手方式到其主机. 返回一个
请求 :
| 表面 | 目的 |
|---|---|
identity | 主机发布App,放出和地表ID. |
context, (中文(简体) ), theme, (中文(简体) ), lifecycle | 当前快照和订阅主机事实. |
capabilities | 处理当前允许的操作. |
ui | 主机同意,导航,计费和通知. |
commands, (中文(简体) ), window | 指挥注册,密切磋商和退后. |
dispose() | 释放挂载连接及其手柄. |
反应 App 挂载 mountApp 从 @fungi.computer/agar/react,运行中
握手, 应用主机的主题, 并在卸载上清理 :
import { mountApp } from "@fungi.computer/agar/react";
const dispose = mountApp(root, { name: "Bazaar" }, ({ app }) => (
<MarketplaceApp app={app} />
));
import.meta.hot?.dispose(dispose);
它的渲染回调收到 connecting, (中文(简体) ), live, (中文(简体) ), standalone (最高一级)
发射, not-hosted (初始连接失败)或 ended; 仅 live
带AppRoot。 过 queryClient 将 App 包入 QueryClientProvider。 。 。 .
useAppContext(app), (中文(简体) ), useComputerId(app), (中文(简体) ), useStore(store) 财务报告和审定财务报表
useAppCommandCatalog 读取主机状态并注册命令.
用 CSP 服务 App 文件 frame-ancestors 被钉入主机; 真菌
牡蛎在他们的App路线上这样做。 普通顶级页面没有主机
连接到 。 在集成测试或独立框架中执行应用程序
页 次, connectAppHost 从 @fungi.computer/agar/host 是对应方: 您
传递儿童窗口、其来源、发射背景和只传递能力
您的页面可以授权.
请求能力
先问成员,再用手柄:
import { listComputerFiles } from "@fungi.computer/agar/computer";
const outcome = await root.ui.requestAppPermissions({
computers: ["computer.list"],
});
if (outcome === "granted") {
const files = await listComputerFiles(root.capabilities, {
path: "/workspace",
limit: 50,
offset: 0,
});
}
请求也可指明 git (单位:千美元)git.repository, (中文(简体) ), workflows
(单位:千美元)workflow.publish, (中文(简体) ), workflow.arm, (中文(简体) ), workflow.run, (中文(简体) ), events
(单位:千美元)app.events.emit和 generation (单位:千美元)llm.generation, (中文(简体) ), media.generation, (中文(简体) ),
media.share)权利,使用赠款目录本身的名称.
declined 财务报告和审定财务报表 customize 是普通的结果。 主办方同意
App的"发布声明",资源对每个请求都会重新检查权限.
浏览器获得能力控件, 绝不是 Team cookie 、 命名空间绑定或
提供者密钥.
能力客户居住在自己的子路径中: ./computer (档案,终端,
在主机所选计算机上的程序和端口, ./agents, (中文(简体) ), ./apps, (中文(简体) ),
./media, (中文(简体) ), ./media-library, (中文(简体) ), ./inference, (中文(简体) ), ./channels, (中文(简体) ), ./inbox, (中文(简体) ),
./marketplace, (中文(简体) ), ./game-servers 财务报告和审定财务报表 ./world。它们只会对宿主不利
像真菌队. appBackend 从 ./backend 呼唤
App的自己承认的后端.
先检查设置
一个知道安装什么的主机发布 context.setup (单位:千美元)models, (中文(简体) ),
media, (中文(简体) ), git数字 : ready | missing | unknown· ; terminal数字 :
ready | exec-only | missing | unknown)并更新其活性. 一个有主机
不发布它省略了字段,所以将缺席视为 unknown 继续尝试.
当事情是 missing电话
root.ui.openSetup("model" | "media" | "git" | "computer")它决定
opened 或者说 unavailable (没有这种表面的主机); App 保留自己的
第二件案子的简单解释.
context.permissions 上面写着App现在所宣称的权利
(单位:千美元)granted 或者说 missing,按下目录中的名称,例如
git.repository),这样它就可以在前面提供"证明权限". 一个主机更新它
之后 requestAppPermissions; App 不声明的权利,或主机
不发布, 将密钥忽略( 处理为未知 ) .
App 可以标记状态项目 priority: "low";主机在
整个酒吧的窗户太窄了.
存储 App 自己的数据
声明范围 storage 应用程序版中的密钥和主机报价
app.storage 未经许可即刻。 每一个键决定呼叫
队员的私人控制, 否则团队默认, 否则
source: "none"。 。 。 .
import { appStorage } from "@fungi.computer/agar/storage";
const storage = root.capabilities.require(appStorage);
const desktop = await storage.watch("desktop");
const initial = desktop.get();
watch 在读取真实的快照后解决,并跟踪随后的修改,
包括写入其他窗口; 关闭 desktop.close()。 。 。 . read(key)
返回两层及其修改,以及 write 财务报告和审定财务报表 reset 比较
层的修订版( e)basedOn) (中文(简体) ). 只有团队主写团队层.
AppStorageError.code 实值 invalid, (中文(简体) ), undeclared_key, (中文(简体) ), scope_not_declared, (中文(简体) ),
owner_required, (中文(简体) ), too_large, (中文(简体) ), quota_exceeded, (中文(简体) ), conflict 或者说 unavailable打开
冲突,再读一次,然后让成员决定;永远不要用发明来重试
修订.
回到了窗户上
一个主机一次显示多个 App 窗口, 所以一个 App 路径关于内存历史和
报告 回到主机,显示在窗口的标题栏.
useHostNavigation 从 ./react 使用 TanStack 执行此程序
路由器 :
const router = useRouter();
const canGoBack = useCanGoBack();
useHostNavigation(app?.window.navigation, {
canGoBack,
title: currentPageTitle,
onBack: () => {
if (!router.history.canGoBack()) return false;
router.history.back();
return true;
},
});
没有反应,就打电话 root.window.navigation.publish({ canGoBack, title }) 财务报告和审定财务报表
root.window.navigation.onBack(handler)。连接也转动
浏览器的后键和鼠标按钮在 App 内部输入 App 后键,所以一个出错
按钮从不浏览工作空间页面.
桌面吉尔
Gills是App对桌面和终端的紧凑视图. 以
defineAppGill 从 @fungi.computer/agar/gills 旁边 defineAppMethod
他们诵读而传诵 gills 改为 defineAppBackend; 构建生成
它们的释放元数据。 每个 Gill 名称 一个宣布的读取方法和一个页面
limit 从1到200, 向方法前进, 并预测其行数
没有任何下降。 虽然App上架了,
await app.ui.openDesktopSettings() 请主机建议添加一个
成员点击更改桌面.
错误
能力操作失败 AppError,其中包含一个键入 code 还有一个
明确 retryable 旗帜。 处理拒绝、撤销、选择变更和
在受影响的操作旁断开, 并且永远不要将失败的请求变成
一个空洞的成功. describeAppError 将失败转换为已核准的 UI 副本 :
import { describeAppError } from "@fungi.computer/agar/errors";
const description = describeAppError(cause);
// Render description.title and description.message beside the failed operation.
// Keep the original cause for diagnostics; it is never included in the copy.
结果是 title, (中文(简体) ), message, (中文(简体) ), retryable 和可选 grant, (中文(简体) ),
retry, (中文(简体) ), reconnect 或者说 billing 提示; 呼叫者执行任何动作 。 仅
SDK 解码 AppError 实例. INSUFFICIENT_CREDIT 提议
billing打开 app.ui.openTeamBilling()。 。 。 .
API 参考
生成的 API 参考 船在包裹。 这个
覆盖 App 作者的表面: 根连接和共享类型,
./react, (中文(简体) ), ./query, (中文(简体) ), ./errors, (中文(简体) ), ./rpc, (中文(简体) ), ./backend, (中文(简体) ), ./backend-definition, (中文(简体) ),
./backend-declaration, (中文(简体) ), ./files 财务报告和审定财务报表 ./storage,并记录主机侧
(二) 合同的履行:
元数据和计算机结果。 该能力客户端尚未生成
参考页面; 把它们视为不稳定.
实例
快速启动定义后端, 构建其 App API 并调用一个不使用的方法 主持人。 这个 说明示例 App 是一个完整的App,具有UI,后端方法和SQLite. 在存储器中 连接和处置套件对真实的MessagePort进行两侧的操作.
限制和错误
普通顶级页面没有主机可连接; connectApp 需要一个
主机挂载的 Iframe. 已键入的能力操作失败 AppError 代码
主机否认、取消或缺乏能力。 方法方案验证输入
并在每个呼叫中输出。 存储值必须是 JSON 在已声明的字节内
约束和深度32.
贡献和许可证
运行 pnpm --filter @fungi.computer/agar test 用于SDK套房和
pnpm --filter @fungi.computer/agar build 来编译软件包。 包裹
使用麻省理工学院许可证 LICENSE。 。 。 .