# app_builder_cli **Repository Path**: tylw1/app_builder_cli ## Basic Information - **Project Name**: app_builder_cli - **Description**: 面向 Flutter 应用的 AI 配置与构建工具链:生成 App 配置、扫描模块清单、RAG 检索、LLM 驱动工具计划与自动打包,并提供 Web 控制台统一操作。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-28 - **Last Updated**: 2026-01-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # app_builder_cli > 面向 Flutter 应用的 AI 配置与构建工具链:生成 App 配置、扫描模块清单、RAG 检索、LLM 驱动工具计划与自动打包,并提供 Web 控制台统一操作。 ## 项目简介 `app_builder_cli` 是「蜜元 AI」工程中的工具链子项目,与 Flutter 应用 `miyuan_app_ai` 配套使用。配置目录 `ap_config` 已迁入本项目根下。它提供: - **配置生成**:将本目录下 `ap_config/app_modules.json` 校验并输出到 Flutter 的 `assets` - **模块扫描**:解析 Flutter 工程中的模块注册表,输出到本目录下 `ap_config/module_inventory.json`(或 DB) - **RAG 索引与查询**:使用 LanceDB 向量库,对源码/配置建索引并做相似度检索 - **LLM 工具计划**:根据自然语言 prompt 生成并执行「扫描 → 索引 → 生成 → 打包」等步骤,采用 **计划 ⇄ Function Calling** 循环(Agent 模式) - **代码生成**:按模板生成新模块的 Dart 页面与注册代码 - **Web 控制台**:执行 LLM 任务、查看 RAG 命中、历史记录、构建产物、时间线与归档 ## 功能概览 | 类别 | 能力 | |------------|------| | CLI | `generate` / `scan` / `rag-index` / `rag-query` / `package` / `tool-run` / `llm-run` / `web` / `codegen` | | RAG | LanceDB 向量库(数据目录可配 `LANCEDB_PATH`);可配置 Embedding API | | LLM | Function Calling(计划 ⇄ 执行循环)+ 文件类工具(read/search/patch/write/list_dir) | | Web 控制台 | 健康检查、LLM 执行(同步/流式)、配置与运行时标志、历史分页/搜索/导出/归档/恢复、构建产物列表/下载/清理/重试与队列、步骤时间线、RAG 命中高亮与复制 | | 安全与限流 | 文件访问白名单/黑名单、全局限流与 LLM/测试专用限流、Zod 校验 | ## 环境要求 - **Node.js**:推荐 18+,需支持 `fs/promises`、`fetch` - **npm**:随 Node 安装即可 - **Flutter**(若使用 `package` / `tool-run` / `llm-run` 等):已安装并可执行 `flutter analyze`、`flutter test`、`flutter build apk` - **仓库布局**:建议在仓库根下存在 `app_builder_cli/`(其内含 `ap_config/`)、`miyuan_app_ai/`,默认路径均相对于仓库根与当前工作目录推导 ## 快速开始 ```bash # 进入项目目录 cd app_builder_cli # 安装依赖 npm install # 构建 npm run build # 生成配置(本目录 ap_config/app_modules.json → miyuan_app_ai/assets/app_modules.json) npm run generate # 扫描模块清单 → 本目录 ap_config(DB 或 module_inventory.json) npm run scan # 启动 Web 控制台(默认 http://localhost:3000) npm run web ``` 若需通过 LLM 生成并执行工具计划,请先配置环境变量(或使用 Web 控制台中的 LLM 配置): ```bash export LLM_API_KEY=your_key export LLM_API_URL=https://api.openai.com/v1/chat/completions export LLM_MODEL=gpt-4o-mini npm run llm-run -- --prompt "新增导购平台并重新打包" ``` ## 项目结构 ``` app_builder_cli/ ├── ap_config/ # 配置目录(app_modules.json、llm_config.json、tools_manifest.json 等) ├── src/ │ ├── index.ts # CLI 入口,分发 generate/scan/rag-index/rag-query/package/tool-run/llm-run/web/codegen │ ├── paths.ts # 解析 ap_config 等路径(相对本包根目录) │ ├── server.ts # Web 服务与 REST API │ ├── schema.ts # app_modules 配置校验 │ ├── scan.ts # 模块扫描(module_registry.dart) │ ├── rag.ts # RAG 分块与哈希向量(供 LanceDB 等使用) │ ├── rag_embed.ts # Embedding 调用 │ ├── rag_lancedb.ts # LanceDB 向量库索引与查询 │ ├── llm.ts / llm_config.ts / llm_call_history.ts │ ├── tool_runtime.ts # 工具计划执行与日志 │ ├── runtime_flags.ts # 运行时标志(LLM 模式、文件工具开关等) │ ├── app_builder_db.ts # run_history、build_artifacts 等表的 SQLite 初始化 │ ├── history.ts # 执行历史与归档(SQLite) │ ├── artifacts.ts # 构建产物与重试队列(SQLite) │ ├── codegen.ts # 模块代码生成 │ ├── project_scanner.ts │ └── tooling/ # Function Calling 工具注册、文件工具、路径守卫 ├── public/ │ └── index.html # Web 控制台前端 ├── templates/ │ └── module_page.dart.tpl ├── package.json ├── tsconfig.json └── README.md ``` ## 技术说明 ### 总体架构 - **CLI 入口**(`index.ts`):根据子命令调用 `scan` / `generate` / `rag` / `tool_runtime` / `server` 等。 - **工具运行时**(`tool_runtime.ts`):采用计划 ⇄ Function Calling 循环:可先显式生成计划(planFirst),再进入多轮 function_calling;阶段结束或达到回合上限后可重规划(allowReplan / maxReplanRounds),再进入下一轮执行,直到任务完成。 - **RAG**:索引阶段遍历源码/配置目录、按行分块、生成向量(哈希或 Embedding API)并写入 LanceDB;查询阶段用 prompt 做向量检索,将命中的片段作为上下文传给 LLM。 - **Web 服务**(`server.ts`):对外提供 REST + SSE,LLM 执行、历史、产物、配置等均通过 API 访问;流式执行时通过 SSE 推送 `log` / `plan` / `ragHits` / `step` / `done` / `error`。 ### 时序图:Agent 主流程(计划 ⇄ Function Calling) 用户执行 `llm-run --prompt "…"` 时,进入计划 ⇄ Function Calling 循环:若 planFirst 则先生成计划,再进入多轮「请求 → 工具调用 → 结果回写」;阶段结束或达到回合上限后可重规划(allowReplan / maxReplanRounds),直到任务完成或达最大重规划轮数。 ```mermaid sequenceDiagram participant T as tool_runtime participant RAG as RAG participant Reg as ToolRegistry participant LLM as LLM API participant Exec as 工具执行(领域/文件) T->>RAG: queryLanceRag(prompt) → ragHits T->>Reg: 加载 tools_manifest,组装 getToolDefinitions() T->>LLM: callLlmWithTools(messages, tools) loop 每轮 (最多 LLM_MAX_TOOL_TURNS) LLM-->>T: choices[].message { content?, tool_calls? } alt 存在 tool_calls T->>Exec: 按 tool_calls 依次执行 Exec-->>T: tool results T->>T: 追加 role=tool 消息到 messages T->>LLM: callLlmWithTools(messages, tools) else 无 tool_calls 或 content 表示结束 T->>T: 合并 executed 为 plan.steps,结束循环 end end T-->>T: 返回 { plan, ragHits } ``` 执行异常时可由 `LLM_FALLBACK_TO_PLAN_JSON` 控制降级为「生成计划后顺序执行」(generatePlan + runToolStep)。 ### 时序图:工具链流水线(tool-run / 单步执行) `tool-run` 从本目录 `ap_config` 对应之 tool_plan(DB 或 `tool_plan.json`)读取已生成计划,按 `steps` 顺序执行;每个 `runToolStep` 对应一种领域能力。 ```mermaid sequenceDiagram participant I as index.ts participant T as tool_runtime participant Scan as scan.ts participant Gen as generate(schema) participant RAG as rag / rag_remote participant Codegen as codegen participant Flutter as flutter build I->>I: 读取 tool_plan.json I->>T: 循环 runToolStep(step) alt step.name === 'scan' T->>Scan: scanModules(projectRoot) Scan->>Scan: 解析 module_registry.dart Scan-->>T: module_inventory → 写 ap_config/(或 DB) else step.name === 'generate' T->>Gen: validateConfig + 写 assets/app_modules.json else step.name === 'rag-index' T->>RAG: indexLanceRag(rootDirs) RAG-->>T: 写入 LanceDB else step.name === 'package' T->>Flutter: flutter analyze && flutter test && flutter build apk Flutter-->>T: APK 路径 → artifacts 记录 else step.name === 'codegen' T->>Codegen: generateModule({ id, title, … }) Codegen-->>T: 生成页面 + 注册代码 end T-->>I: 所有步骤执行完毕 ``` ### 时序图:Web 流式 LLM 执行(SSE) 前端通过 `GET /api/llm-run/stream?prompt=…&run=…` 发起流式执行,服务端在同一个请求上持续推送 SSE 事件。 ```mermaid sequenceDiagram participant Browser as 前端 participant Server as server.ts participant T as tool_runtime Browser->>Server: GET /api/llm-run/stream?prompt=…&run=true Server->>Server: 创建 runId,设 SSE headers Server->>Browser: event: started, data: { runId } Server->>T: handleLlmRunWithLogs({ …, onLog, onPlan, onStep }) loop 执行过程 T->>T: 打日志 / 得到 plan 与 ragHits T->>Server: onLog(msg) Server->>Browser: event: log, data: { message } T->>Server: onPlan(plan, ragHits) Server->>Browser: event: plan / event: ragHits loop 每个工具步 T->>Server: onStep(stepLog) Server->>Browser: event: step, data: stepLog end end T-->>Server: resolve Server->>Server: 写历史、写 step_timeline Server->>Browser: event: done 或 event: error Server->>Browser: 关闭流 ``` ### 数据流简述 | 阶段 | 输入 | 输出 | |----------|------|------| | 模块扫描 | Flutter 工程 `module_registry.dart` | 本目录 `ap_config/module_inventory.json` 或 DB | | 配置生成 | 本目录 `ap_config/app_modules.json` | `miyuan_app_ai/assets/app_modules.json` | | RAG 索引 | `miyuan_app_ai/lib`、本目录 `ap_config` 等 | LanceDB(默认本目录 `ap_config/rag_lancedb`) | | RAG 查询 | LanceDB + 用户 query | 若干 `{ file, startLine, endLine, text }` 命中 | | LLM 计划 | prompt + ragHits + appModules + moduleInventory | `{ steps: [ { name, args? } ] }` 或 Function Calling 多轮结果 | | 打包 | Flutter 工程根 + mode | `build/app/outputs/.../app-*.apk` + `artifacts` 记录 | ## 使用方式 ### 构建 ```bash npm run build ``` ### 生成配置 将本目录 `ap_config/app_modules.json` 校验后输出到 Flutter assets: ```bash npm run generate # 自定义路径:--input <输入> --out <输出目录> ``` ### 扫描模块清单 输出到本目录 `ap_config/module_inventory.json`(或 DB): ```bash npm run scan # 自定义:--project --out <输出文件> ``` ### RAG 索引与查询 ```bash # 生成 RAG 索引 → LanceDB(默认本目录 ap_config/rag_lancedb) npm run rag-index # 向量检索 npm run rag-query -- --query "平台授权" ``` 可通过环境变量 `LANCEDB_PATH` 指定数据目录,`RAG_COLLECTION` 指定表名(默认 `rag_chunks`)。 ### 自动打包(Android Debug APK) ```bash npm run package # 会先执行 flutter analyze、flutter test,再 flutter build apk --debug # --project、--mode debug|release ``` ### 按计划执行工具(tool-run) 从本目录 ap_config 对应之 tool_plan(DB 或 `tool_plan.json`)读取 `{"steps":[...]}` 并依次执行各步骤: ```bash npm run tool-run # 自定义计划文件:--plan <路径> ``` ### LLM 生成并执行工具计划(llm-run) ```bash export LLM_API_KEY=your_key export LLM_API_URL=https://api.openai.com/v1/chat/completions export LLM_MODEL=gpt-4o-mini npm run llm-run -- --prompt "新增导购平台并重新打包" # --plan、--project、--mode 同前 ``` ### Web 控制台 ```bash npm run web # 默认端口 3000,可指定:--port 3000 ``` ### 模块代码生成 ```bash npm run codegen -- --id vipshop --title 唯品会 # 可选:--icon、--navVisible=false、--project ``` ### 可选参数汇总 | 参数 | 说明 | |------------|------| | `--input` | 配置输入路径(如 app_modules.json) | | `--out` | 输出路径或目录 | | `--project`| Flutter 工程根目录 | | `--plan` | 工具计划 JSON 路径 | | `--prompt` | LLM 提示词(llm-run 必填) | | `--port` | Web 服务端口 | | `--id` / `--title` | codegen 的模块 id 与标题 | ## Function Calling(计划 ⇄ 执行循环) `llm-run` 采用 **计划 ⇄ Function Calling** 循环:可先显式生成计划(planFirst),再进入多轮 function_calling;阶段结束或达到回合上限后可重规划(allowReplan / maxReplanRounds)。 ### 环境变量 - **`LLM_FALLBACK_TO_PLAN_JSON=true`**:执行异常时是否降级为「生成计划后顺序执行」(默认 true) - **`LLM_MAX_TOOL_TURNS=30`**:工具回合上限 - **`FILE_TOOLS_ENABLED=true`**:开启 `read_text` / `search_text` / `apply_patch` / `write_text` / `list_dir` - **`FILE_ROOTS_ALLOWLIST`**:逗号分隔的白名单根目录(相对仓库根),例如:`miyuan_app_ai/lib,app_builder_cli/ap_config,app_builder_cli/templates` - 未设置时默认包含 `miyuan_app_ai/lib`、`app_builder_cli/ap_config`、`app_builder_cli/templates` - 强制禁止访问 `app_builder_cli/ap_config/llm_config.json` - **黑名单(denyPaths)与 `miyuan_app_ai`**:在 Web 或 `runtime_flags.json` / `DENY_PATHS` 中若把 `miyuan_app_ai` 列为黑名单,则 `search_text`、`read_text` 等无法访问应用源码,LLM 在「新增模块并打包」流程中无法自行修复 `flutter analyze` 报错或搜索应用内实现。若需由 LLM 修改或检索应用代码,请勿将 `miyuan_app_ai` 整目录加入黑名单,可仅限制 `miyuan_app_ai/build`、`miyuan_app_ai/.dart_tool` 等子目录。 ### 示例 ```bash export LLM_MODE=function_calling export FILE_TOOLS_ENABLED=true export FILE_ROOTS_ALLOWLIST="miyuan_app_ai/lib,app_builder_cli/ap_config,app_builder_cli/templates" npm run llm-run -- --prompt "启用/禁用若干模块并重新打包" ``` ## RAG 与 Embedding - **RAG**:使用 LanceDB。数据目录由 `LANCEDB_PATH` 指定,未设置时为本目录 `ap_config/rag_lancedb`;表名由 `RAG_COLLECTION` 指定,默认 `rag_chunks`。无需单独部署远程向量服务。 - **Embedding**:通过 `EMBEDDING_API_URL`、`EMBEDDING_API_KEY`、`EMBEDDING_MODEL` 使用外部嵌入接口;未配置时使用内置哈希向量(128 维)。 ## Web API 文档 Web 控制台默认监听 `http://localhost:3000`,提供以下 REST API(均带全局限流与部分端点专用限流)。 ### 健康与版本 - **GET /api/health** — 服务状态、运行时间、版本 ### LLM 执行 - **POST /api/llm-run** — 同步执行 Body: `{ "prompt", "run?", "projectRoot?", "packageMode?" }` - **GET /api/llm-run/stream?prompt=...&run=...&packageMode=...** — SSE 流式执行 事件:`started` / `log` / `plan` / `ragHits` / `step` / `done` / `error` - **POST /api/llm-run/stop/:runId** — 停止正在进行的流式任务 ### LLM 与运行时配置 - **GET /api/llm-config** — 获取 LLM 配置 - **PUT /api/llm-config** — 更新模型列表、当前模型、默认分支等 - **POST /api/llm-config/test** — 测试连接(Body: `apiUrl`, `model`, `apiKey?`) - **GET /api/runtime-flags** — 获取运行时标志 - **PUT /api/runtime-flags** — 更新 llmMode、fileToolsEnabled、fileRootsAllowlist 等 ### 历史与归档 - **GET /api/history?limit=&offset=** — 分页列表 - **GET /api/history/:id** — 单条详情(含关联构建产物) - **GET /api/history/export?format=json|jsonl|csv** — 导出 - **DELETE /api/history** — 清空 - **POST /api/history/archive** — 归档到数据库(run_history_archive 表) - **GET /api/history/archives** — 归档列表 - **GET /api/history/archives/search?query=&limit=** — 按关键词搜归档 - **GET /api/history/archives/:name** — 下载归档 - **POST /api/history/archives/:name/restore** — 恢复到主历史 ### 构建产物与重试 - **GET /api/artifacts?limit=&offset=&runId=&status=&sort=** — 列表(支持按 runId、状态筛选,按时间/大小排序) - **GET /api/artifacts/:id** — 详情 - **GET /api/artifacts/:id/download** — 下载 APK - **POST /api/artifacts/prune** — 清理旧产物,Body: `{ "keepLatest": N }` - **POST /api/artifacts/retry** — 加入重试队列,Body: `{ "runId", "mode?", "priority?" }` - **GET /api/retry/queue** — 重试队列状态 - **GET /api/retry/queue/:runId** — 取消队列中某任务(实际为 DELETE 语义) - **POST /api/retry/queue/clear** — 清空队列 ### 模块与仓库 - **GET /api/modules/config** — 当前模块配置(app_modules) - **GET /api/modules/inventory** — 模块清单(module_inventory) - **GET /api/git/branches?projectRoot=** — Git 分支列表 - **GET /api/step-timeline/:runId** — 某次执行的步骤时间线 JSON - **GET /api/function-tools** — 当前可用 Function Calling 工具定义(含文件工具与领域工具) - **GET /api/file-access/scan-project** — 扫描项目结构 - **GET /api/file-access/scan-directory?path=** — 扫描指定目录子项 ### LLM 调用历史(调试用) - **GET /api/llm-call-history?page=&limit=** — 分页 - **GET /api/llm-call-history/stats** — 统计 - **GET /api/llm-call-history/:id** — 单条 - **DELETE /api/llm-call-history** — 清空 ### 其他 - **POST /api/generate-name** — 根据 prompt 生成分支名/项目名/组织 ID,Body: `{ "prompt", "type": "branch"|"project"|"org" }` ## 安全与限流 - **全局限流**:`/api/*` 100 次/分钟 - **LLM 执行**:`/api/llm-run` 10 次/分钟 - **连接测试**:`/api/llm-config/test` 5 次/分钟 - **校验**:请求体与查询参数均通过 Zod schema 校验 ## 环境变量 ### LLM - `LLM_API_KEY`、`LLM_API_URL`、`LLM_MODEL` - `LLM_MODE`:仅支持 `function_calling`(计划 ⇄ 执行循环) - `LLM_FALLBACK_TO_PLAN_JSON`、`LLM_MAX_TOOL_TURNS` ### 文件工具 - `FILE_TOOLS_ENABLED`、`FILE_ROOTS_ALLOWLIST` - `FILE_MAX_READ_BYTES`、`FILE_MAX_WRITE_BYTES`、`FILE_MAX_LIST_ENTRIES` - `FILE_MAX_SEARCH_FILES`、`FILE_MAX_PATCH_LINES`、`FILE_MAX_SEARCH_RESULTS`、`FILE_MAX_DIR_DEPTH` ### RAG - `LANCEDB_PATH`:LanceDB 数据目录,默认本目录 `ap_config/rag_lancedb` - `RAG_COLLECTION`:LanceDB 表名,默认 `rag_chunks` - `EMBEDDING_API_URL`、`EMBEDDING_API_KEY`、`EMBEDDING_MODEL` ### 构建与队列 - `ARTIFACT_KEEP_LATEST`、`ARTIFACT_RETRY_LIMIT`、`RETRY_CONCURRENCY` - `HISTORY_AUTO_ARCHIVE_LIMIT` ### 日志与运行 - `LOG_LEVEL`、`NODE_ENV` ## 开发 ### 本地开发(Web 热重载) ```bash npm run dev ``` ### 代码质量 ```bash npm run lint # 检查 npm run lint:fix # 自动修复 npm run format # 格式化 npm run format:check ``` ### Git Hooks 使用 husky + lint-staged,提交前会自动执行 ESLint 与 Prettier。首次安装依赖后执行: ```bash npm run prepare ``` ## 与仓库其他部分的关系 - **ap_config/**(本目录下):统一配置目录,存放 `app_modules.json`、`llm_config.json`、`tools_manifest.json`,以及运行生成的 `app_builder.db`(运行历史与构建产物记录)、`rag_lancedb/`(LanceDB 向量数据)、`step_timeline/` 等;tool_plan、module_inventory、runtime_flags 等已迁入 DB 或由 DB 持久化。 - **miyuan_app_ai/**:Flutter 应用,使用 `assets/app_modules.json` 做模块装配,模块注册表位于 `lib/app/modules/module_registry.dart`,扫描与代码生成均针对该工程。 更多交付与运行说明见仓库根目录下的 `DELIVERY.md`。