ROADMAP —— Agentaily
能力粒度的地图。设计见 ARCHITECTURE.md;form 内容文档的 schema 在 verticals/form/schema/(一个 zod schema —— 唯一真相源);域名体系(官网 / 应用 / UGC 制品 三层 + cutover)见 DOMAINS.md。
✅ 已完成
接缝(the seam)
- Studio Protocol(已冻结) —— 垂直无关的契约:通用 op 基座 +
describe+invoke+version/乐观并发 +StudioDiagnostic,外加setRenderer/getRenderer(renderer 是一个 LLM 生成的、自包含的 index.html)。@agentaily/studio-protocol。 - Studio 客户端 SDK ——
connectStudio(),带一个防竞态的ready()握手。@agentaily/studio-client。
垂直(万物)
- Form —— JSON 原生(原型):一份由唯一一个 zod schema 校验的 JSON document(校验 + 类型 + emit 一个 JSON Schema;无手写文法)+ 可嵌入 Studio(整套协议、自截图、 跨源安全)。
@agentaily/form-schema·@agentaily/form-studio。 - Slides —— 第二个垂直(一个
deck,含若干slide),JSON 原生(与 form 同样的 zod-schema 模式); 验证了协议无需改动;document 是一个完整的内容模型。@agentaily/slides-schema·@agentaily/slides-studio。
Agent(Tier 1)
- Agent 运行时 —— loop · 通用的协议包装工具 · skill loader · memory。
@agentaily/agent。 - 多模态视觉 ——
studio_screenshot,模型能「看见」(以一个视觉模型把关);已 live 验证。 - 多 provider LLM 网关 —— 一个
Provider接口 + DeepSeek / 百炼·Qwen / 火山·Doubao / Anthropic / mock,共享一个 OpenAI 兼容的 base。BYOK,在 CORS 允许处浏览器直连 (Ark 走代理)。@agentaily/llm。 - 基于设计系统的产品壳 ——
apps/web是基于@agentaily/design-system的 React:一个 项目管理器门面(创建/打开/删除 form 或 PPT 项目,存在 localStorage; 一个项目 = 一个垂直实例)→ 一个每项目工作区(DesignerShell:chat | live studio), Composer/Message、provider + model 选择器,以及一个 Settings sheet,含每 provider 的 BYOK key + 一个 skills inspector(已加载的垂直 skill,完整指令可展开)+ 一个 memory inspector (agent 的持久笔记,存在 localStorage,跨项目全局)。
仓库
- 一个 monorepo —— 一切都在单一仓库;设计系统(
@agentaily/design-system, 120 组件 + Storybook)和官网(@agentaily/website,apps/website—— 双语营销落地页)都从各自的仓库折叠进来作为 workspace 包(npm 发布已暂停;官网现经workspace:*消费 DS)。就地编辑;无发布循环。 旧的多仓舰队正在退役。 - pnpm + Turbo —— 包管理器是 pnpm(workspaces、
workspace:*依赖、strict node_modules); Turbo 编排build/typecheck(按依赖顺序 + 缓存);test是一次根 Vitest projects 运行(DS 在 jsdom,其余在 Node)。工具链保持最新:Vite 8、plugin-react 6、Vitest 4、TS 6。 - Storybook 评审 addon(devx) —
@agentaily/storybook-addon-review(根级 workspace 包,接进 DS 的 Storybook): 评审模式下在预览里 hover 选元素 + 写评论 + 一键开评审 PR(本地 dev;preset 经 server channel 用 git plumbing 非破坏式造提交 +gh开 PR,PR 只含一份reviews/*.md)。静态/线上无 Node 时优雅降级(仅查看)。线上建 PR 的 CF Worker 后端为 TODO。详见包内 README + skillagentaily-storybook-addon-review。 - 在线评审 widget + 反馈 Worker(devx) —
@agentaily/feedback-widget(可发布 React 组件)+agentaily-feedbackWorker(apps/feedback):任意 React 站点(官网 / chatapp)挂 widget → 开评审模式 hover 选元素 + 写意见 + 提交 → Worker 用 GitHub REST 在agentaily/agentaily开 PR(reviews/<ts>.md)。是 addon 的线上版(HTTP→REST, 而非 channel→git CLI),补上了上面那条的「线上建 PR Worker」。已接进apps/web(VITE_FEEDBACK_ENDPOINT配了才挂)。 待 ops:Workerwrangler deploy+wrangler secret put GITHUB_TOKEN(fine-grained PAT);官网仓单独接入。 React 仅 peerDep、不依赖 DS。详见包内 README + skillagentaily-feedback-widget。 - 统一标注/评审核心(devx) —
@agentaily/annotate(根级 workspace 包):把上面两者(addon / feedback-widget) 各自重复的「选元素 + 写 + 提交」交互抽成一份框架无关 vanilla 核心createAnnotator+ 薄 React 包装<Annotate />(Vue/vanilla 走核心入口)。回调式onSubmit(annotation)、不内置后端;主题走 DS CSS token(自动双主题、不再用 借来的 geek-blue)。定位器逻辑(buildLocator)是这套的单一收口。DS Storybook 有Review/Annotatestory。 已落地:独立包 + story,不改现有消费者;截图(选中元素自动html2canvas→ 缩略图 + 重截/删除 + 评论框粘贴剪贴板图片,失败优雅降级为纯文字)→annotation.screenshot(PNG data URL,captureScreenshot可关)。 后续刀:把 addon / feedback-widget / 文档站 / 预览工作台切到本包(收敛)。详见包内 README + skillagentaily-annotate。
渲染层(一个已发布接口,其余由 LLM 生成 —— 见 ARCHITECTURE.md)
- 内容 / renderer —— 在聊天中经
studio_set_document/studio_set_renderer设置。垂直 只 ship ① Schema 接口(一个 zod schema);renderer 永远是 LLM 生成的数据 —— 没有 内置 renderer,外观就活在 renderer 里(无单独的 theme)。 - 受约束的
set_document—— 产品把垂直的 JSON Schema(来自getSchema())接进studio_set_document的document参数,于是模型 emit 一个合规对象(受约束解码), 而不是自由打 JSON、猜字段名。实测(qwen3-vl-plus,同一 prompt):form 从 3 次set_document尝试 + 一次 skill 查询 → 1 次,没有 validate 重试循环。studioTools({ documentSchema })。 - renderer 即数据 —— 一个 renderer 是一份完整、自包含的
index.html(结构 + 内联 CSS + 内联 JS;可引用 CDN 库/字体),由 LLM 编写,跑在一个内层 iframe 里。它在运行时从一个 注入的<script id="agentaily-doc">占位读取 document(doc 变化 → 重注入- reload)。无内置默认:一个全新项目是空白的,直到 LLM 生成一个。
- Preset 市场 —— 一个 preset 是一份自包含 renderer(
{ indexHtml, contract }),每个垂直 一个市场(无单独的 theme 市场、无内置条目 —— 随用户发布而填充)。 浏览 / 应用(setRenderer)/ 发布当前 renderer。@agentaily/presets。 - Schema 版本化 + LLM 驱动迁移 —— 每个垂直的 schema 带一个单调递增的
SCHEMA_VERSION+ 作者手写的SCHEMA_CHANGELOG。制品记录schemaVersion(renderer/preset + 项目);getState暴露 current vs builtFor → 陈旧性。新 opgetSchemaDiff(from)(+ 工具studio_schema_diff)把 change-list 喂给 agent(以及一个给人看的 banner);若陈旧,agent 可 升级 —— 重写 renderer + 迁移 doc(复用 set_renderer/set_document)。见 ARCHITECTURE.md。 - 数据接口(提交投影) —— document 的第二个投影。协议类型
DataInterface<Doc>({collects:false}|{collects:true, recordSchema(doc), checkRecord(doc,record)})。@agentaily/form-schema从一个 form 的 fields 派生其提交 JSON Schema(recordSchema)+ 一个 服务端门(checkRecord)→formDataInterface;@agentaily/slides-schema声明{collects:false}。这是后端将据以存储的契约(记录打上schemaVersion)。 见 SPEC.md §2.1。
质量
- Evals —— 任务完成度评测:真 agent + 真模型 headless 地构建制品, 对结构化 schema 断言;以
EVAL_KEY把关。@agentaily/eval。
架构收敛(REFACTOR)— 本轮 ship 的能力(#1–#23)
REFACTOR.md(市场为核心 · AML+Cloudflare 为基建)M0–M8 的落地;REFACTOR.md 是当前重构的活进度真相源,完整工单 / 分层 / 安全模型见那里。本轮 PR 把 M1–M6 的地基与主业务闭环首刀落了下来(M1–M6 全程 additive),随后 M7 清旧已完成 —— 旧 Studio/verticals 主线已拆。
- AML DSL(基建叶子) —
@agentaily/aml:声明式后端数据模型 DSL(参考 Prisma,不重名);emit()产{ tables, sql(CREATE TABLE), api(ApiDescriptor) },升为后端数据的唯一真相源引擎(基本不动,等被 runtime 消费)。 - db:AML 建表引擎(M1) —
@agentaily/db在旧 JSON-Schema 路线之外新增 AML 引擎:amlCompiler/amlTable吃aml.emit()→ D1 表 provisioning + 变更 diff 迁移。详见db/README.md。 - db:scoped 数据引擎(M2) —
amlDataCompiler/amlDataEngine从ApiDescriptor派生 scoped/authed insert/query:服务端强制注入project_id谓词(前端传的 id 被忽略),跨 project 隔离已测。 - 市场数据层 + 服务端存储(M3) —
@agentaily/presets(→@agentaily/market):AppEntry{ id, name, description, aml, files, preview, author, forkedFrom, tags }+list/get/search/fork(扁平市场、无 vertical、无内置条目);演进成多文件 VFS(files: Record<path, content>,additive 保留indexHtml);服务端 D1 store 落地(market_apps表 + 端点 +D1AppStorefetch 适配器),不再只 localStorage。 - agent 持久化层
@agentaily/agent-store(§8) — 抽出SkillStore(useSkillTool)+MemoryStore(InMemory/LocalStorage +rememberTool)+ConversationStore(补 session 跨会话持久化);职责从 loop 分离。 - loop 接 store + 子 agent + 压缩(§8.1) — loop 改依赖 agent-store 接口(
messages经ConversationStore注入 + 可 rehydrate);新增 sub-agent(agent-as-tool,独立上下文)+ 服务端上下文压缩(Anthropic compaction,opt-in)。 - 会话上云 — D1
conversations/messages表 + 端点 +D1ConversationStore适配器(owner-scoped,会话升一等公民)。 - 造 app 工具集(M5 keystone) —
@agentaily/agent新增write_aml+ VFSwrite_file/read_file/list_files+market_search/market_preview/market_fork(fork 载入整组文件),additive 接进 toolset;新系统提示APP_BUILDER_SYSTEM引导零构建 VFS(见下)。 - 零构建 VFS 文件模型(§9) — 一个 app = 一组静态文件(1 个
index.html入口 + 按需.css/.js(ESM)/.json/资源),沙箱 iframe 直接 serve、运行时无构建;第三方库走 import map → CDN ESM + htm(JSX 式手感),禁.jsx/.tsx/构建步骤。APP_BUILDER_SYSTEM据此教模型。 - 安全(M4) — 数据读端点补 session 鉴权 + owner scope(堵「open for now」裸洞);
persistencecookie host-scope 加固(平台会话禁.agentaily.com父域 cookie → UGC 子域读不到平台会话;会话本身是 Bearer/localStorage,审计无泄漏)。 - theme / persistence 抽成独立包 —
@agentaily/persistence(零依赖、framework-free 的跨子域偏好持久化原语)抽出;@agentaily/theme改为依赖它(不再 vendored);均已注册进 workspace。 - 主业务闭环首刀(M6,additive) — AppEditor 组件(VFS 文件面板 + 沙箱内联预览)· apps/publish
/a/:appId(独立源沙箱 serve 整组 VFS 文件,数据取自market_apps)·/(及别名/build)AppBuilder 视图(聊天造 app → 编辑器 → 市场发布/fork → 会话持久化)。form / slides 各补aml+index.html两件套,作市场种子料。 - M7 清旧(✅ 完成) —
/=AppBuilder 成主入口(#32)、backend/eval 去 vertical(#33)后,删掉已 orphan 的旧主线:旧App.tsx(990 行 studio 工作台)+ 其专用core/{projectClient,dataTool};@agentaily/studio-protocol/studio-client、verticals/*(form/slides schema+studio)、@agentaily/agent-ui七个包;agent 的studioTools/ studioDEFAULT_SYSTEM(loop fallback 改通用最小提示);scripts/assemble-pages.mjs退役(零构建 VFS 无 studio 可汇入,pnpm build=turbo run build)。全仓typecheck/test/build仍绿。@agentaily/agent-react(替 agent-ui)留待后续(REFACTOR §8.1)。 - 主应用重做为 ChatApp(✅ 完成,给不懂代码的人用) —
/由旧/build三栏 AppBuilder(AML 面板 + 代码编辑器 + srcdoc 预览)重做为 DS<ChatApp>壳(ChatWorkbench):左对话列表 + 中<ConversationThread>+ 右 预览工作台(会话绑定,布局用 DS<DocsLayout>workbench 模式:文件侧栏开关 + header 文件下拉 + flush 纯预览,绝不示码 / AML;assembleFilePreview拼srcdoc喂sandboxiframe)。AppBuilder 真实逻辑(agent loop、会话 store/rehydrate/新建/切换、双级模型、per-会话草稿、publish)整体迁入。 - 市场收为弹窗 + 删独立
apps/market(✅ 完成) — 原独立apps/market门面 SPA 删除;其浏览 UI(列表/卡片/搜索/详情/fork)搬进apps/web以 DS<Dialog size="xl">弹窗呈现(market/MarketModal),fork 载入当前对话(取代旧?fork跨源跳转,仍兼容入站?fork=)。市场端点用 apps/web 自有functions/api/market/*。 - theme/locale cookie + 防 FOUC(✅ 完成) — apps/web 整树包
@agentaily/themeThemeProvider+ 本地LocaleProvider(均 cookie 持久化),index.html<head>内联themeInitScript()防主题闪烁;账户菜单内主题/语言切换。会话/平台态仍 Bearer/localStorage,绝不设父域 cookie(REFACTOR §5 铁律)。 - DS seam(✅ 完成) —
<DocsLayout>加collapsed/flush/toc=[]去 TOC /brand={null}(workbench 模式);<Dialog>加size(sm/md/lg/xl+ body 滚动)。组件数不变(仅加 prop),.d.ts/.prompt.md同步。
闭环现状:主业务闭环代码完成,go-live 待迁移。 聊天造 app → 编辑器 → 沙箱预览 → 市场发布/fork → 会话持久化整链在
/build视图跑通(additive,与旧 App.tsx 流程并存)。本轮新增的公开端点契约(publish 数据桥window.agentaily+/a/:appId/_data*、市场/api/market*、会话/api/conversations*、/api/data·/api/forms/:id/submissions读端点鉴权加固)已登记进SPEC.md§0「已落地的新端点契约」。go-live 还差两步 ops: ① 把应用 D1 迁移 0004/0005 应用到生产;②/build接 LLM key(平台 edge 注入)。M7 清旧已完成(砍 verticals/studio-protocol/client/agent-ui + 旧 App.tsx,见上);再往后:M8 文档对齐(重写ARCHITECTURE.md/SPEC.md到终态、各包 README)+ 打磨(preview 截图、per-会话草稿、AppMarket 异步类型)。详见REFACTOR.md§7(M8)。
🚧 接下来 —— Cloudflare 集成(user态 + 托管 + 数据后端)
2026-06-19 定:部署在 Cloudflare 上,用一层薄边缘(Pages + Pages Functions),保持纯 SPA。 作者登录;应答者匿名提交。无数据迁移(还没有用户 —— 干净起步)。
- schema 里的数据接口 —— ✅ 已落地(见上文「已完成」)。最先排定;下面一切都建在它之上。
- 把数据接口贯穿整条栈暴露出来 —— 协议
datacapability +getRecordSchemaop;接线 studio → client → agent;renderer 获得一个window.agentaily.submit(record)桥,这样一个已发布的 form 就能 POST 一份提交。 - LLM 代理(Pages Function
/api/llm/*) —— ✅ 已落地并 live 验证:catch-allfunctions/api/llm/[[path]].ts把/<provider>/<...>转发到真实上游(bailian/deepseek/ volcengine),key 从一个 edge secret(BAILIAN_KEY等)注入,流式回传响应。 已对 bailian/qwen3-vl-plus 用一个本地.dev.varskey 确认 —— 请求不带 key,真实 200 completion 返回。key 永不到达 bundle;并吸收了旧的 Volcengine 浏览器 CORS 缺口。 ✅ SPA 已接线(7ef68fd):App.tsx 把每个 provider 的 baseUrl 指向/api/llm/<provider>,且ensureAgent不再要求用户 key(edge 注入平台 key);本地已验证 ——/api/llm/bailian/chat/completions不带客户端 key 也返回真实 completion。 - 提交后端 —— ✅ 纯逻辑(
@agentaily/backend:submitRecord经checkRecord把关 + 打schemaVersion;listSubmissions;collectsData)+ ✅ D1 适配器 & Pages Functions,在一个 LOCAL D1 上 端到端验证:apps/web/functions/=PUT/GET /api/projects/:id(持久化一个 form,好让 门有它的 document)+POST /api/forms/:id/submissions(匿名,201/422 带 diagnostics —— 坏 记录永不入库)+GET …(列表)。存储接缝由@agentaily/db实现(拆成 自己的包 —— 职责分离):Drizzle 是 FIXED 表的唯一真相源,drizzle-kit生成迁移(进apps/web/migrations—— Pages wrangler 忽略自定义的migrations_dir),D1 支撑的 store 实现@agentaily/backend的接缝。✅ 提交落进一张 真实的 per-form D1 表:@agentaily/db的 field→table 编译器(compiler.ts,垂直无关 ——recordSchemaJSON Schema → 真实的有类型列 + 一个迁移 diff)为每个项目 provision/迁移一张data_<id>表 (项目 PUT 时ensureDataTable;项目持久化其recordSchema),记录作为受checkRecord把关的 结构化行插入(不是一个 JSON blob)。在 LOCAL D1 上 e2e 验证:form 字段 →c_name TEXT/c_age REAL,结构化行读回。✅ 派生数据 API/api/data/:id—— GET = introspection(recordSchema),POST = 类型化查询(where/select/limit/orderBy,跑在真实 列上,不是 blob 扫描)—— e2e 验证。见db/DESIGN.md;wrangler.toml(Topology A,同源)。✅ owner-scoped + SPA 已接线(7ef68fd):ProjectStore新增delete;端点GET /api/projects(列表,鉴权,按 session.sub)+PUT/DELETE /api/projects/:id(鉴权,ownerId 钉到 session,跨 owner → 403);GET /api/projects/:id对 form 运行时保持公开。 SPA(core/projectClient.ts+ App.tsx)针对服务端 load/save/delete(D1 = 真相源;localStorage = 离线缓存)。端到端验证(本地 D1 + 浏览器 UI)。✅ 已发布 form 的公开运行时/f/:id(functions/f/[id].ts+assemblePublicRuntime):serve LLM 编写的 renderer + 注入的 document + 一个window.agentailysubmit/query 桥;renderer 持久化在项目上(projects.renderer)。已在一个真实浏览器里端到端验证:renderer 渲染了 fields,填写 + 提交命中checkRecord→ 真实的 per-form 表,且window.agentaily.query读回了结构化行。✅ SPA 已接线:renderer 在保存时被捕获(studio.getRenderer()→projects.renderer→ PUT),于是/f/:id对真实 UI 搭建的项目可用;工作台有一个 「分享」 控件(一个 DropdownMenu,直接基于@agentaily/design-system搭),在 renderer 存在后暴露公开的/f/:id链接 (复制 / 打开)。✅ LLM 数据工具data_query(apps/web/src/core/dataTool.ts, 包装 POST/api/data/:id)已并入 agent 的 toolset —— 聊天能查询已采集的记录。 (设计现直接基于自家 DS —— Claude Design / design-sync 工作流已退役。) ✅ Host 路由的 publish 运行时(apps/publish/→ Workeragentaily-publish):在一个独立源上 serve UGC 制品的生产模型(DOMAINS.md③)—— 把请求的Host解析到项目,经<slug>.agentaily.com(projects.slug)或一个用户自己的域名(custom_hostnames表,Cloudflare for SaaS);自包含 page + submit + query,使桥同源工作。 在一个本地 D1 上 e2e 验证(子域 & 自定义 hostname serve;平台子域/apex 404;同源 submit 201)。⏳ 基建:*.agentaily.comwildcard + for-SaaS 绑定 + 一个 publish UI 来设 slug。 - Auth(user态) —— ✅ 自建 email+password(PBKDF2 + session JWT,verify-first)+ Google OAuth,不是 Cloudflare Access。后端 ✅(
@agentaily/backend/auth/*纯逻辑 +functions/api/auth/*D1 上的 Pages Functions,本地 D1 端到端)。前端 ✅ Commit 4(0713b4b):apps/web/src/{core/ apiClient,core/auth,signin,auth-gate,auth.css}——AuthGatepage-guard 包住整个工作台 (/api/auth/me→ checking/authed/denied/error),/signin独立页(DSSignInPage+ 内置onSSOslot →/api/auth/google/start),email/pw + 找回密码 +?reset_token=设新密码 + verify-first 「查收验证邮件」态;account control(email / logout / resend-verification)在App里。浏览器 UI 已验证。 作者拥有其项目 + 提交。⏳ 剩余:把 SPA 项目存储绑定到已鉴权的 owner。 - 存储 —— D1(users / projects / submissions)、KV(presets)、R2(file-field 上传)。localStorage 成为离线兜底,不是真相源。
- Repo + CI/CD —— ✅ 已推到
github.com/agentaily/agentaily(私有)。CI(.github/workflows/ci.yml): push/PR 上 install + typecheck + test + build —— 绿。两个 CD workflow,在CLOUDFLARE_API_TOKEN+CLOUDFLARE_ACCOUNT_IDrepo secret + Pages 项目存在之前都惰性 (其间 skip 且保持绿):deploy.yml→ 应用(apps/web→ 项目agentaily),deploy-website.yml→ 营销 站(apps/website→ 项目official-website,根域)。无舰队(已退役)。旧的独立agentaily/official-website仓可归档(它的 Pages 项目现从这里驱动)。 - Studio 在子路径下 —— ✅ 已落地(
a1de8cb):verticals/{form,slides}/studio用 vitebase=/studio/<v>/构建;scripts/assemble-pages.mjs在turbo run build后把它们的 dist 折叠进apps/web/dist/studio/<v>/;App.tsx在 prod 里 iframe/studio/<v>/(dev 里 localhost:4174/4175)。本地验证 (浏览器从子路径同源加载 Studio,零 localhost 请求)。 - 部署 —— ✅ LIVE 在 https://agentaily.pages.dev(
9290861),在 yarnbcoder CF 账号里 (e6ce8ba3…,同 official-website/form-design)。用 vault 的 CF token 非交互式 provision (yarnbcoder 的两个 token 分开:pages-deploy=Pages,workers-deploy=D1):Pages 项目agentaily+ D1agentaily-db(idd910ce7b…,迁移已应用)+ Pages secrets(AUTHSECRET/BAILIAN_KEY/DEEPSEEK_KEY/ GOOGLE_/RESEND_API_KEY)+[vars](APP_BASE_URL、EMAIL_FROM=noreply@mail.agentaily.com,Resend 已验证)。 Google OAuth prod redirect 已加(agentaily.pages.dev/api/auth/google/callback)。Live 冒烟全绿 (signin/studio/auth-me/register/login-403/llm-proxy)。✅ CD 已接线(3f50db4):repo secret 已设 →deploy.yml(应用)+deploy-website.yml(official-website)都在 push 时自动部署,都已验证绿 (deploy-website 需要一个apps/websitewrangler devDep —— wrangler-action 在npm i wrangler与 monorepo 的workspace:_之间卡住)。✅ Google consent screen 已发布到生产(100 测试用户上限解除)。 剩余:一旦 Google 的 OAuth 配置传播完成,做一次真实 Google 登录(redirect 已加,到过 账号选择器一次,随后间歇性redirect_uri_mismatch= 最终一致性,可能要几 小时)→ 确认 edge token 交换;一次真实收件箱注册以确认 Resend 邮件能到达。
🔭 以后
- Preset 市场打磨 —— 发布时命名/预览/缩略图;一个托管的 preset store(存储 接缝是可插拔的;今天是 localStorage)。
- MCP 适配器 —— 把同一套 Studio op 经 MCP 暴露给外部 agent(
invoke ≅ tools/call)。 - Renderer 沙箱化 —— renderer 作为一份完整 index.html 跑在一个内层 iframe 里,该 iframe 今天是同源(于是 CDN 库/字体 + 截图能工作;信任模型:用户自己的项目)。 在 preset 变成可跨用户分享之前,把它隔离进一个独立的沙箱源。公开的
/f/:id运行时 serve 用户编写的 HTML/JS(backend/runtime.ts)—— 当前与应用同源(发布前 OK, 无用户)。由域名设计解决(DOMAINS.md):已发布的 UGC 制品移到一个独立的 隔离域 + 用户自己的域名经 Cloudflare for SaaS —— 那个独立的可注册源本身就是 隔离(不带任何平台存储/会话),于是同源风险消失。在那里作为 ③ 跟踪。 - 更多语言能力 —— form:分节、条件可见性、默认值;slides:更多布局。
- Eval 扩展 —— 更多 case、多模型对比、分数趋势。
🔁 架构收敛重构(2026-06-19 老板定 · 多会话逐个认领)
⚠️ 本节(R0–R8)已被 2026-06-19 晚的「市场为核心」再收敛取代 —— 当前真相源 =
REFACTOR.md(M0–M8)。 要点:不再有 verticals;app = aml+index.html;市场是核心价值;早先 R6/R7「LLM 不生成 index.html」作废(改为 LLM 生成 + fork + 预览)。下面 R0–R8 留作历史。
老板定调的一次架构收敛,不背历史包袱。本节是可认领的重构工单:老板会开多个会话,各自在自己的 git worktree 里认领一张工单、并行推进、开 PR 合并。每张工单尽量自洽、低耦合,标注产出 / 占用路径 / 依赖 / 待拍板设计点 / 协调对象。认领前先读「目标态」+「与现有实现的冲突」+「R0 设计点」。
目标态(每张工单都以此为准)
一个垂直插件 = 3 个静态产物(开发期写死,用户 / LLM 不碰),不再叫 studio:
| 产物 | 是什么 | 谁产出 |
|---|---|---|
verticals/<x>/schema | 内容 schema(zod)—— 定义聊天时 LLM 要生成的那份内容文档长啥样 | 开发期写 |
verticals/<x>/aml | 后端数据模型(@agentaily/aml DSL)—— 框架吃它 → 自动建数据表 + 自动生成 GraphQL | 开发期写 |
verticals/<x>/index.html | 静态渲染页(替代原 studio 的 LLM 生成 renderer)—— 直接调那层自动生成的 GraphQL 读写数据 | 开发期写 |
- 运行时收敛到极致:聊天中 LLM 只生成「schema 对应的内容文档」,不再生成 index.html / renderer / 页面。
- LLM 的技能(skill) = 知道当前加载的是哪个插件 / 哪种类型 + 它的 schema 契约,从而生成合规内容。
- 底层链:vertical 的
aml→(框架自动)D1 真表 + GraphQL 层 → 静态index.html调用。平台跑在 Cloudflare。 - 被收敛掉的旧机制(退役 / 改造):LLM 生成 renderer(
studio_set_renderer/getRenderer)、renderer 市场@agentaily/presets、studio 的 iframe-host-renderer 机制。
⚠️ 与现有实现的冲突(认领前必读)
现状已有一套**「派生」数据层**(db-layer 的 @agentaily/db):内容文档 recordSchema(doc) → JSON Schema → 编译器 → D1 真表 → 「GraphQL 精神」REST(/api/data/:id),静态后端固定表则在 db/src/schema.ts(中央一份 Drizzle)。这次收敛是把数据模型从**「派生 / 中央 Drizzle」改成「每个 vertical 一份手写 AML」,并把「GraphQL 精神 REST」升成自动生成的 GraphQL**。直接动 db-layer 的地盘 + 决策 db/DESIGN.md D6,必须先经 R0 拍板 + 与 db-layer 协调,不可擅自重写。
待拍板的核心设计点(R0,阻塞多数工单)
- AML ↔ form 动态字段:
form的提交表列是终端用户运行时跟 LLM 聊出来的(动态),静态 AML 怎么和它共存?(候选:AML 定固定实体 + 系统列骨架,字段级约束仍留checkRecord;或 AML 作模板、框架按文档实例化) - AML → 真表 的路径:AML AST → JSON Schema 复用现有编译器,还是 AML → DDL / Drizzle 直出?与
@agentaily/db「Drizzle 为单一真相源」如何并存 / 取代? - GraphQL 引擎:真上 graphql-yoga(introspection 生态),还是延续「GraphQL 精神」REST + 自描述契约?老板要的是「自动生成 GraphQL 接口」。
- index.html 完全静态:确认每个 vertical 的
index.html是开发期写死的静态产物(读内容文档 + 调 GraphQL),LLM 完全不生成。
工单(认领单 · 每张一个会话)
R→M 落地状态(2026-06-20 回写): 这套 R0–R8 已被
REFACTOR.md的 M0–M8 取代;下表「状态」列标注各 R 工单在新蓝图下的落地情况(✅ 已落地 · 🚧 部分 / 进行中 · ⚠️ 已作废)。
| # | 状态 | 工单 | 产出 / 范围 | 占用路径 | 依赖 | 协调 |
|---|---|---|---|---|---|---|
| R0 | ✅ 由 REFACTOR §6 取代 | 设计拍板 | 定上面 4 个设计点,并把目标态写进 ARCHITECTURE.md + db/DESIGN.md | ARCHITECTURE.md · db/DESIGN.md | — | 老板 + db-layer |
| R1 | ✅ 已落地 | AML 接线 monorepo | @agentaily/aml 进 workspace + 根 vitest(在 i18n/theme/persistence 既有注册上叠加,不抹) | pnpm-workspace.yaml · vitest.config.ts · pnpm-lock.yaml | — | db-layer / persistence-pkg(共享文件) |
| R2 | ✅ 已落地(= REFACTOR M1) | AML → 真表 桥 | 按 R0:AML → 表结构(emit JSON Schema 或 DDL),接上 @agentaily/db 编译器 | aml/**(加 emit)· db/**(协调) | R0, R1 | db-layer |
| R3 | ✅ 已落地 | form 补 aml + index.html | form 的后端数据模型 .aml + 静态 index.html(调 GraphQL) | verticals/form/** | R0, R2, R5 | — |
| R4 | ✅ 已落地 | slides 补 aml + index.html | 同上(slides;注意它 collects:false,数据模型可能极简甚至空) | verticals/slides/** | R0, R2, R5 | — |
| R5 | 🚧 部分(= REFACTOR M2) | GraphQL 自动生成层 | 从 AML / 真表自动生成 GraphQL 接口(引擎选型见 R0) | db/** 或新包 · apps/web/functions/** | R0, R2 | db-layer / cloud-deploy |
| R6 | ⚠️ 已作废(REFACTOR §6) | 运行时收敛(砍 LLM 生成页面) | set_renderer/get_renderer;系统提示改「只产内容文档」 | agent/** · apps/web/src/**(协调) | R3 / R4 | cloud-deploy |
| R7 | ⚠️ 已作废(REFACTOR §6) | 退役 renderer 生成体系 | setRenderer/getRenderer、studio iframe-host-renderer | presets/** · studio/** · verticals/*/studio→index.html | R6 | — |
| R8 | 🚧 进行中(= REFACTOR M8) | 文档全量对齐 | 把所有真相源对齐收敛态:ARCHITECTURE.md / 各 vertical README / aml/README / 项目 CLAUDE.md 一句话 | 各文档(认领时协调) | 跟随各能力落地 | — |
本 session(arch-converge)已先垫付 R8 一部分:
SPEC.md已改中文 + 对齐目标态、过时的TODO.md引用已修。ARCHITECTURE.md的深度重写归 R0 / R8(它现仍写着旧的「LLM 生成 index.html renderer / studio / preset 市场」叙事,认领 R0 / R8 时一并改)。 建议认领顺序: R0 先行(阻塞);R1 可立刻并行(小、独立);R0 落地后 R2→R5 串,R3/R4 可并行;R6→R7 收尾;R8 贯穿。