AGENTS.md · git:20260904.2b5be60 · 2026-09-04 · sha256 618e4f9fbb72aa02

AGENTS.md git:20260904.2b5be60B

Immutable. This exact content is served forever at /api/v1/blob/618e4f9fbb72aa02.

# 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` 等子技能。

| 禁止(NEVER DO) | 正确做法(MUST DO) |
|------|------|
| 首次搭建应用时直接调用 `openyida create-app` 然后手动拼接 create-form / create-page / publish | 首次搭建时加载 `yida-app` 子技能,由它按标准编排流程执行 |
| 跳过 PRD 设计阶段,凭感觉定义字段和页面结构 | 先由 `yida-design` 输出 `prd/<项目名>.md`,再按 PRD 创建资源 |
| 把 `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 是否正确