AGENTS.md · diff
git:20260904.2b5be60 to git:20260904.6c22f12
2 added, 2 removed. Audit B to B.
# OpenYida — AI Agent 开发指引
本文件为 AI 编程助手(Codex、Claude Code、Cursor、OpenCode、Qoder 等)提供项目上下文,帮助 AI 更准确地理解项目结构和开发规范。
## 项目简介
OpenYida 是一个 CLI 工具,让开发者通过 AI 对话驱动宜搭低代码平台,实现应用的创建、表单管理、页面发布等全流程操作。
**核心定位**:AI 编程工具 × 宜搭低代码平台 的桥接层。
## 项目结构
```
openyida/
├── bin/
│ └── yida.js # CLI 入口,解析命令并路由到 lib/
├── lib/
│ ├── core/ # 核心基础模块
│ │ ├── utils.js # 公共工具函数(Token、HTTP、路径等)
│ │ ├── chalk.js # 终端彩色输出公共样式模块(统一 chalk 风格)
│ │ ├── i18n.js # 国际化支持
│ │ ├── locales/ # 语言包(zh、en、zh-HK、ja、ko、fr、de、es、pt、ar、hi、vi)
│ │ ├── env.js # 检测 AI 工具环境(Codex/Claude/Cursor/Copilot/Qoder/千问办公 等)
│ │ ├── env-cmd.js # env 命令入口(显示当前环境信息)
│ │ ├── env-manager.js # 多环境配置管理(私有化部署多环境切换)
│ │ ├── copy.js # 初始化 project 工作目录
│ │ ├── sample.js # sample 命令(输出代码示例到工作目录)
│ │ ├── check-update.js # npm registry 版本查询与 SemVer 比较
│ │ ├── check-data.js # 数据异常检测(流程表单数据校验)
│ │ ├── update.js # npm 全局安装的 24h 自动更新与手动 self-update
│ │ ├── doctor.js # 环境诊断与自动修复
│ │ ├── query-data.js # 统一数据管理命令(表单/流程/任务/子表单)
│ │ ├── task-center.js # 全局任务中心(待办/我创建的/我已处理/抄送/代提交)
│ │ └── babel-transform/ # Babel 编译器(用于自定义页面)
│ ├── auth/ # 登录认证模块
│ │ ├── token-auth.js # OAuth loopback + token 登录态管理
│ │ ├── token-store.js # 本地 token session 存储
│ │ ├── oauth-loopback.js # OAuth 回调监听与授权码换取
│ │ └── org.js # 组织管理(列出/切换组织)
│ ├── basic-info/ # 企业基础信息查询(版本 / 授权 / 域名)
│ │ └── basic-info.js # 企业版本、授权信息与域名管理
│ ├── bridge/ # 浏览器桥接服务(本地 HTTP 代理连接宜搭页面)
│ │ └── bridge.js # Bridge HTTP 服务器(本地代理 + 页面唤起)
│ ├── samples/ # 代码示例/模板(通过 openyida sample 命令输出到工作目录)
│ │ ├── yida-chart/ # ECharts 图表示例(7个)
│ │ ├── yida-custom-page/ # 自定义页面模板(2个)
│ │ ├── yida-create-app/ # 应用创建模板(1个)
│ │ ├── yida-data-management/ # 表单字段模板(1个)
│ │ ├── yida-density/ # 密度切换示例(1个)
│ │ └── yida-table-form/ # 表格表单示例(1个)
│ ├── a2a/ # A2A 协议服务器(Agent-to-Agent HTTP 通信)
│ │ ├── cmd.js # a2a 命令入口(参数解析与启动)
│ │ └── server.js # A2A HTTP 服务实现(JSON-RPC 路由)
│ ├── agent-center/ # 智能代理任务中心(代理人任务管理)
│ │ ├── agent-center.js # 代理人任务命令(创建/更新/取消/查询)
│ │ └── api.js # 代理人 API 请求封装
│ ├── aggregate-table/ # 聚合表管理(虚拟视图 / 聚合表单)
│ │ └── aggregate-table.js # 聚合表创建与配置
│ ├── ai/ # AI 能力(文生文 / 识图)
│ │ └── ai.js # AI 命令入口(txtFromAI / 图片识别)
│ ├── app/ # 应用 / 表单 / 页面管理
│ │ ├── app-list.js # yida-app-list:查询我的应用列表(名称/appType/地址)
│ │ ├── create-app.js # 创建宜搭应用
│ │ ├── create-page.js # 创建自定义展示页面
│ │ ├── create-form.js # 创建 / 更新表单页面
│ │ ├── get-schema.js # 获取表单 Schema
│ │ ├── generate-page.js # 基于模板生成自定义页面源码
│ │ ├── check-page.js # 自定义页面规范检查
│ │ ├── compile.js # 本地编译自定义页面
│ │ ├── publish.js # 编译并发布自定义页面(Babel 转译)
│ │ ├── export-app.js # 导出应用(生成迁移包)
│ │ ├── import-app.js # 导入迁移包,重建应用
│ │ └── update-form-config.js # 更新表单配置
│ ├── app-permission/ # 应用权限管理(管理员角色配置)
│ │ └── app-permission.js # 应用管理员角色分配(主管理/数据/应用管理员)
│ ├── page-config/ # 页面公开访问 / 分享配置
│ │ ├── verify-short-url.js # 验证短链接 URL
│ │ ├── save-share-config.js # 保存公开访问 / 分享配置
│ │ └── get-page-config.js # 查询页面公开访问 / 分享配置
│ ├── permission/ # 表单权限管理
│ │ ├── get-permission.js # 查询表单权限配置
│ │ └── save-permission.js # 保存表单权限配置
│ ├── process/ # 流程管理
│ │ ├── configure-process.js # 配置并发布流程规则
│ │ ├── create-process.js # 创建流程表单(一体化)
│ │ └── preview-process.js # 流程预览(可视化流程图 + 高亮当前节点)
│ ├── conversation/ # AI 对话管理
│ │ ├── collector.js # 对话记录收集
│ │ ├── formatter.js # 对话格式化
│ │ └── export-conversation.js # 导出对话记录
│ ├── feedback/ # 体验反馈收集(表单化反馈提交)
│ │ └── feedback.js # 反馈表单创建与提交(自动检测 AI 工具环境)
│ ├── flash-note/ # 闪记转 PRD
│ │ └── flash-to-prd.js # 闪记转高质量 prompt(支持会议识别)
│ ├── formula/ # 公式求值引擎(宜搭公式本地计算)
│ │ └── evaluate.js # 宜搭公式解析与求值(支持 60+ 内置函数)
│ ├── dingtalk/ # 钉钉链接生成(AppLink / 页面链接构建)
│ │ └── dingtalk-link.js # 钉钉 AppLink URL 与页面链接生成
│ ├── dws/ # 钉钉 CLI 集成
│ │ └── dws-wrapper.js # 钉钉 CLI 包装器(通讯录/日历/待办/审批等)
│ ├── i18n-management/ # 应用多语言管理(语言包配置)
│ │ └── i18n-management.js # 应用级多语言资源管理(12 种语言)
│ ├── integration/ # 集成 & 自动化
│ │ └── integration-create.js # 创建集成逻辑流
│ ├── connector/ # HTTP 连接器管理
│ │ ├── api.js # 连接器 API 请求封装
│ │ ├── connector-list.js
│ │ ├── connector-create.js
│ │ ├── connector-detail.js
│ │ ├── connector-delete.js
│ │ ├── connector-add-action.js
│ │ ├── connector-list-actions.js
│ │ ├── connector-delete-action.js
│ │ ├── connector-test.js
│ │ ├── connector-list-connections.js
│ │ ├── connector-create-connection.js
│ │ ├── connector-smart-create.js
│ │ ├── connector-parse-api.js
│ │ ├── connector-gen-template.js
│ │ ├── curl-parser.js # cURL 命令解析
│ │ ├── doc-parser.js # API 文档解析
│ │ ├── response-parser.js # 响应结构解析
│ │ ├── action-generator.js # Action 自动生成
│ │ └── desc-generator.js # 描述自动生成
│ ├── corp-efficiency/ # 企业效能分析(平台管理效能指标)
│ │ └── corp-efficiency.js # 效能概览 / 详情 / 分组 / 通知
│ ├── corp-manager/ # 平台权限管理(管理员 / 通讯录可见性)
│ │ ├── api.js # 管理员与通讯录 API 封装
│ │ └── corp-manager.js # 管理员增删查 / 通讯录可见性配置
│ ├── cdn/ # CDN / OSS 管理
│ │ ├── cdn-config.js # CDN 配置读写
│ │ ├── cdn-config-cmd.js # CDN 配置命令
│ │ ├── cdn-upload.js # 上传图片到 OSS/CDN
│ │ └── cdn-refresh.js # 刷新 CDN 缓存
│ ├── mcp/ # MCP 协议服务器(Model Context Protocol)
│ │ └── server.js # MCP JSON-RPC 服务实现(工具注册与调用)
│ ├── report/ # 宜搭报表管理
│ │ ├── create-report.js # 创建报表(入口)
│ │ ├── index.js # 创建报表主流程
│ │ ├── append.js # 向已有报表追加图表
│ │ ├── chart-builder.js # 图表 Schema 构建
│ │ ├── http.js # 报表 HTTP 请求封装
│ │ └── constants.js # 常量与 ID 生成工具
│ ├── db/ # 数据库工具
│ │ └── db-seq-fix.js # PostgreSQL Sequence 自动修复(解决主键序列漂移)
├── project/
│ ├── config.json # 应用配置(appType、pageId 等)
│ └── pages/ # 自定义页面源码目录
├── yida-skills/
│ ├── SKILL.md # 源码态技能入口(索引表,列出所有子技能)
│ ├── skills/ # 子技能目录(每个 skill 自包含 SKILL.md + references/)
│ └── references/ # 跨 skill 共享参考文档(yida-api、model-api、query-condition-guide)
└── scripts/
├── postinstall.js # 安装后脚本(环境检测 + 配置注入)
├── e2e-real/ # 真实环境确定性 CLI 链路测试(runner/full-runner/skill-coverage/cleanup)
├── eval/ # Skill 测评 harness(路由测评 + 端到端截图打分),见下文
├── validate-ci.sh # CI 校验脚本
└── validate-structure.js # 项目结构校验
```
### Skill 测评 Harness(scripts/eval/)
`e2e-real/` 验证 CLI 链路是否跑通;`eval/` 验证**改动 `yida-skills/SKILL.md` 后 agent 的路由与产出是否变好**,是 harness engineering 的反馈闭环。
- `config.js`:解析配置,优先级 `CLI flag > env(OPENYIDA_EVAL_*) > eval.config.json > 默认`;`--skill` 经 `SKILL_COVERAGE` 矩阵反查 stages。
- `agent.js`:唯一的 headless agent 封装(`claude -p --output-format json`),路由测评与截图打分共用;CLI 缺失时返回 `available:false` 优雅降级。
- `routing.js` + `scenarios/`:**路由测评(选对子技能吗)**——把自然语言 prompt 跑一遍,比对选中的子技能与 golden 集,算命中率/混淆对。无副作用、不建资源。
- `generate.js` + `scenarios/generation/`:**真实生成(自然语言建应用)**——把「帮我创建一个订单管理系统」这类自然语言喂给 `claude -p`,让它**自主读技能 + 真的执行 CLI** 产出真实应用,再复用截图 + 打分 + 报告链路。测「端到端:一句话能否真生成可用应用」。与「工具管道基线」(确定性 CLI、固定命名、不经过 agent)的区别是 agent 自主编排。agent 运行器可注入,单测永不碰真实 CLI/不建资源。
- `guardrail.js`:纯函数护栏——任何资源变更命令出现前必须先有成功的 `login --check-only`,否则红线 fail。
- `screenshot.js`:动态解析 Playwright(软依赖),注入 token session 截发布页;缺失则跳过。
- `score.js`:调本地多模态 `claude -p` 对截图按 rubric 打分;不开自动分则只生成 `scoring.md` 人工模板。
- `report.js`:把护栏 + 截图 + 打分渲染成自包含 `eval-report.html`(截图 base64 内联,单文件可分享),与 `scoring.md` 并列产出。
- `manifest.js` + `runner.js`:把 eval 结果**增量回写**进现有 `acceptance-manifest.json` 的 `eval` 段,不另起产物;真实生成产物落 `project/.cache/eval/generate/gen-<时间戳>/`。其中 `runner.js` 的「工具管道基线(端到端)」用固定命令验证「建应用→截图→打分」管道本身健康,是排查 agent vs 工具问题的对照基线。
- `dashboard/`:零依赖本地控制台(`npm run eval:dashboard` → `http://127.0.0.1:4500`),按钮触发 + SSE 实时流式输出,首页「ℹ︎ 测评思路」概览讲清各任务目的,「📊 查看最新报告」打开最新 `eval-report.html`。
命令:`npm run eval:routing`、`npm run eval:e2e`、`npm run eval:generate`、`npm run eval:all`、`npm run eval:dashboard`(端到端 / 生成需 `OPENYIDA_E2E=1` + 有效 token session + 已认证 agent)。`all` = 路由测评 + 工具管道基线 + 真实生成。纯函数逻辑由 `tests/eval-*.test.js` 覆盖,进 CI。
## 关键约定
### Git 分支操作
- 任何需要修改仓库文件的任务,开始编辑前必须先执行 `git branch --show-current` 确认当前分支。
- 禁止直接在 `main` 或 `master` 分支修改文件;若当前位于这两个分支,必须先创建或切换到与任务对应的新分支(默认使用 `feat/`、`fix/` 等语义化前缀)再开始编辑。
- 如果已经误在 `main` 或 `master` 产生未提交改动,应立即创建新分支并将现有工作区改动原样带过去,再继续后续工作;不得在 `main` 或 `master` 上提交这些改动。
- 创建或切换分支不等于授权提交或推送;只有用户明确要求时才执行 commit 或 push。
### 命令实现规范
- 每个 CLI 命令对应 `lib/` 下一个独立的 `.js` 文件
- 所有命令通过 `bin/yida.js` 统一路由,新增命令需在命令清单和路由中注册
- 命令函数导出为 `module.exports = async function commandName(args) {}` 或 `{ run }`
- 错误处理:新增/改造的业务模块应抛出 `CliError` 或普通 `Error`,由 `bin/yida.js` 统一处理退出码;不要在可复用业务模块里新增 `process.exit(...)`
### 宜搭 API 调用
- 所有宜搭 API 调用需通过 `loadAuthData` / `createAuthRef` 读取 token session,并由 HTTP 工具自动注入 `Authorization: Bearer <access_token>`
- API 基础路径:`https://www.aliwork.com`
- 参考 `yida-skills/references/yida-api.md` 了解完整 API 列表
### 环境检测
- `lib/core/env.js` 负责检测当前运行的 AI 工具环境
- 支持环境:Codex、Claude Code、Cursor、OpenCode、QwenWork、Qoder、Qoder IDE、QoderWork
- Qoder 与 Qoder IDE 共用 `.qoder` 配置目录,以 `qoder_app` / `qoder_ide` subtype 区分;QoderWork 是独立产品,继续使用 `.qoderwork`
- 不同环境会影响工作区路径、浏览器可用性和 agent 能力;登录态统一走 OAuth token session,不再依赖 Cookie 提取
### Codex 特殊说明
- Codex 环境下 `openyida login` 仍使用 OAuth loopback + token session;登录完成后用 `openyida login --check-only --json` 或 `openyida auth status` 验证
- 不要引导用户导出浏览器 Cookie、使用旧二维码 handoff,或手写 `.cache/cookies.json`
- 多组织账号测试时,优先传入 `--corp-id <corpId>`,不要由 AI 代理代替用户选择组织
### 自定义页面
- 源码位于 `project/pages/src/`,使用 React + 宜搭 SDK
- 发布前通过 `lib/babel-transform/` 进行 Babel 编译
- 编译产物输出到 `project/pages/dist/`
### yida-skills 架构规范
- **源码目录** 保持为 `yida-skills/`,便于与历史安装路径和 Codex/OpenYida 插件兼容
- **入口文件** `yida-skills/SKILL.md` 是索引表,列出所有子技能和共享参考文档
- **每个子技能**位于 `yida-skills/skills/<skill-name>/` 目录下,包含独立的 `SKILL.md`
- **专属参考文档**放在各 skill 的 `references/` 目录下(复数形式),实现自包含
- **跨 skill 共享文档**保留在 `yida-skills/references/` 目录下(`yida-api.md`、`model-api.md`、`query-condition-guide.md`)
- 新增子技能时,同步更新 `yida-skills/SKILL.md` 的索引表
- 修改技能结构后运行 `npm run check:skills`,确认源码态正确
### yida-skills 技能路由规则(Agent 必读)
完整应用在 `yida-app` Step 2 按 `yida-design/references/design-mode.md` 选择一次 Fast / Plan。Fast 沿用下方需求分析和并行生成流程;Plan 只在用户确认当前版本后交接派生文件,不再运行 Fast。
- **当用户首次创建完整应用/系统/平台时,AI agent 必须加载 `yida-app` 子技能作为唯一编排入口**,由 `yida-app` 按阶段调度 `yida-design`(PRD 设计)、`yida-create-app`、`yida-create-form-page`、`yida-canvas-custom-page`、`yida-publish-page` 等子技能。
+ **当用户首次创建完整应用/系统/平台时,AI agent 必须加载 `yida-app` 子技能作为唯一编排入口**,由 `yida-app` 按阶段调度 `yida-prd`(业务 PRD)、`yida-design`(视觉设计)、`yida-create-app`、`yida-create-form-page`、`yida-canvas-custom-page`、`yida-publish-page` 等子技能。
| 禁止(NEVER DO) | 正确做法(MUST DO) |
|------|------|
| 首次搭建应用时直接调用 `openyida create-app` 然后手动拼接 create-form / create-page / publish | 首次搭建时加载 `yida-app` 子技能,由它按标准编排流程执行 |
- | 跳过 PRD 设计阶段,凭感觉定义字段和页面结构 | 先由 `yida-design` 输出 `prd/<项目名>.md`,再按 PRD 创建资源 |
+ | 跳过 PRD 设计阶段,凭感觉定义字段和页面结构 | 先由 `yida-prd` 规划业务并输出 `prd/<项目名>/prd.md`,再按 PRD 创建资源;Plan 从业务源事实物化,同样遵守此契约 |
| 把 `yida-create-app` 当作“搭建应用”的入口 | `yida-create-app` 只是 `yida-app` 编排流程中的一个阶段步骤 |
触发条件:用户消息包含“搭建应用”“创建系统”“做一个管理系统”“从零创建应用”“build an app”等完整应用构建意图,必须路由到 `yida-app`。完整路由规则详见 `yida-skills/SKILL.md` 的"第二步:意图路由"章节。
## 开发注意事项
1. **不要修改 `yida-skills/` 下的文档**,除非是在更新技能描述
2. **新增 CLI 命令**时,同步更新 `README.md` 的命令一览表
3. **登录态**存储在本地缓存,不要在代码中硬编码任何凭证
4. **测试**:优先运行 `npm run check:ci`,窄范围修改可先运行相关 Jest 用例
5. **JS 语法检查**:`node --check <file>` 验证语法正确性
6. **终端输出样式**:统一使用 `lib/core/chalk.js` 提供的公共样式模块,不要在各命令文件中单独 `require('chalk')` 并自定义颜色
7. **国际化**:新增用户可见的文案时,需以 `zh` 为基准同步到 `lib/core/locales/` 下所有 12 个语言包(至少补齐 `en`,它是运行时缺失兜底链 `当前语言 → en → zh` 的中转轴)。CI 通过 `npm run check:i18n`(棘轮模式)拦截**新增**漂移;本地可用 `npm run check:i18n:audit` 看完整缺失清单,补齐后运行 `npm run check:i18n:baseline` 收紧基线(`scripts/i18n-baseline.json`)
8. **私有化部署**:多环境配置通过 `lib/core/env-manager.js` 管理,不要在命令文件中硬编码 API 域名
## 常见任务示例
### 添加新 CLI 命令
1. 在 `lib/` 下创建 `new-command.js`
2. 在 `bin/yida.js` 中注册命令路由
3. 在 `README.md` 的 CLI 命令一览表中添加说明
4. 在 `yida-skills/SKILL.md` 中更新技能描述(索引表中添加新行)
### 添加新子技能
1. 在 `yida-skills/skills/` 下创建 `<skill-name>/SKILL.md`
2. 若有专属参考文档,放在 `<skill-name>/references/` 目录下
3. 在 `yida-skills/SKILL.md` 的索引表中添加新行
4. 在 `AGENTS.md` 中无需额外更新(索引表自动覆盖)
### 调试登录问题
- 检查 `lib/auth/token-auth.js`、`lib/auth/token-store.js`、`lib/auth/oauth-loopback.js` 中的 OAuth token 登录与缓存逻辑
- 使用 `openyida env`、`openyida login --check-only --json` 或 `openyida auth status` 确认当前环境与 token session 是否正确