feat: 实现扩展模块和设置命令

This commit is contained in:
2025-12-14 07:35:29 +08:00
parent f016b51709
commit a48fbb5fae
19 changed files with 1415 additions and 255 deletions

View File

@@ -1,8 +1,9 @@
# Aide 默认配置(由 aide init 生成) # Aide 默认配置(由 aide init 生成)
# runtime: aide 自身运行要求 # runtime: aide 自身运行要求
# task: 任务文档路径 # task: 任务文档路径
# env: 虚拟环境与依赖配置 # env: 环境模块配置
# flow: 环节名称列表,供流程校验使用 # flow: 环节名称列表,供流程校验使用
[runtime] [runtime]
python_min = "3.11" python_min = "3.11"
use_uv = true use_uv = true
@@ -12,8 +13,20 @@ source = "task-now.md"
spec = "task-spec.md" spec = "task-spec.md"
[env] [env]
venv = ".venv" # 启用的模块列表
requirements = "requirements.txt" modules = ["python", "uv", "venv", "requirements"]
# Python 版本要求(可选,默认使用 runtime.python_min
# [env.python]
# min_version = "3.11"
# 虚拟环境配置类型B模块必须配置
[env.venv]
path = ".venv"
# 依赖文件配置类型B模块必须配置
[env.requirements]
path = "requirements.txt"
[flow] [flow]
phases = ["task-optimize", "flow-design", "impl", "verify", "docs", "finish"] phases = ["task-optimize", "flow-design", "impl", "verify", "docs", "finish"]

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ anthropic-agent-skills/
__pycache__/ __pycache__/
.venv/ .venv/
test-cache/ test-cache/
.aide/

View File

@@ -67,8 +67,10 @@ ccoptimize/
│ │ ├── prep.md │ │ ├── prep.md
│ │ └── exec.md │ │ └── exec.md
│ ├── skills/ │ ├── skills/
│ │ ── aide/ │ │ ── aide/
│ │ └── SKILL.md │ │ └── SKILL.md # 基础命令指南
│ │ └── env-config/
│ │ └── SKILL.md # 环境配置详细指南(按需触发)
│ └── docs/ # 设计文档(给人) │ └── docs/ # 设计文档(给人)
│ ├── README.md │ ├── README.md
│ ├── commands/ │ ├── commands/
@@ -94,10 +96,11 @@ ccoptimize/
│ ├── registry.py # 模块注册表 │ ├── registry.py # 模块注册表
│ └── modules/ # 环境检测模块 │ └── modules/ # 环境检测模块
│ ├── base.py │ ├── base.py
│ ├── python.py │ ├── python.py, uv.py
│ ├── uv.py │ ├── rust.py, node.py, flutter.py
│ ├── venv.py │ ├── android.py, node_deps.py
── requirements.py ── venv.py, requirements.py
│ └── ...
└── docs/ # 设计文档(给人) └── docs/ # 设计文档(给人)
├── README.md ├── README.md
├── commands/ ├── commands/
@@ -121,9 +124,14 @@ ccoptimize/
| /aide:init | ✅ 设计完成 | 项目认知与环境初始化 | | /aide:init | ✅ 设计完成 | 项目认知与环境初始化 |
| /aide:prep | ✅ 设计完成 | 任务准备流程 | | /aide:prep | ✅ 设计完成 | 任务准备流程 |
| /aide:exec | ✅ 设计完成 | 任务执行流程 | | /aide:exec | ✅ 设计完成 | 任务执行流程 |
| aide skill | ✅ 设计完成 | aide 命令使用指南 | | aide skill | ✅ 设计完成 | aide 基础命令指南 |
| env-config skill | ✅ 设计完成 | 环境配置详细指南(按需触发) |
执行文件位于 `aide-marketplace/aide-plugin/commands/``skills/aide/SKILL.md` 执行文件位于 `aide-marketplace/aide-plugin/commands/``skills/`
**Skill 设计理念**
- `aide` skill始终加载提供基础命令用法
- `env-config` skill按需触发仅在 `aide env ensure` 失败时使用
### 3.2 aide-program ### 3.2 aide-program
@@ -132,6 +140,7 @@ ccoptimize/
| aide init | ✅ 已实现 | 初始化 .aide 目录和配置 | | aide init | ✅ 已实现 | 初始化 .aide 目录和配置 |
| aide env list | ✅ 已实现 | 列出所有可用模块 | | aide env list | ✅ 已实现 | 列出所有可用模块 |
| aide env ensure | ✅ 已实现 | 模块化环境检测与修复 | | aide env ensure | ✅ 已实现 | 模块化环境检测与修复 |
| aide env set | ✅ 已实现 | 设置环境配置(带验证) |
| aide env ensure --runtime | ✅ 已实现 | 运行时环境检测 | | aide env ensure --runtime | ✅ 已实现 | 运行时环境检测 |
| aide env ensure --modules | ✅ 已实现 | 指定模块检测 | | aide env ensure --modules | ✅ 已实现 | 指定模块检测 |
| aide env ensure --all | ✅ 已实现 | 全量检测(仅检查) | | aide env ensure --all | ✅ 已实现 | 全量检测(仅检查) |
@@ -148,11 +157,17 @@ ccoptimize/
|------|------|------|------| |------|------|------|------|
| python | A | check | Python 解释器版本 | | python | A | check | Python 解释器版本 |
| uv | A | check | uv 包管理器 | | uv | A | check | uv 包管理器 |
| rust | A | check | Rust 工具链rustc + cargo |
| node | A | check | Node.js 运行时 |
| flutter | A | check | Flutter SDK |
| android | A | check | Android SDK |
| venv | B | check, ensure | Python 虚拟环境 | | venv | B | check, ensure | Python 虚拟环境 |
| requirements | B | check, ensure | Python 依赖管理 | | requirements | B | check, ensure | Python 依赖管理 |
| node_deps | B | check, ensure | Node.js 项目依赖 |
- 类型A无需配置即可检测 - 类型A无需配置即可检测
- 类型B需要配置路径才能检测 - 类型B需要配置路径才能检测
- 支持模块实例化命名:`模块类型:实例名`(如 `node_deps:react`
### 3.4 设计文档 ### 3.4 设计文档
@@ -216,11 +231,11 @@ ccoptimize/
### 5.3 扩展环境模块(可选) ### 5.3 扩展环境模块(可选)
可按需添加更多环境检测模块: 可按需添加更多环境检测模块:
- node - Node.js 版本检测
- npm - npm 依赖管理
- java - Java JDK 检测 - java - Java JDK 检测
- go - Go 语言检测 - go - Go 语言检测
- rust - Rust 工具链检测 - docker - Docker 环境检测
- cargo_deps - Rust 项目依赖(类似 node_deps
- pub_deps - Flutter/Dart 项目依赖
### 5.4 整体验证 ### 5.4 整体验证
@@ -254,7 +269,11 @@ ccoptimize/
## 七、版本信息 ## 七、版本信息
- 文档版本1.1.0 - 文档版本1.2.0
- 更新日期2025-12-14 - 更新日期2025-12-14
- 项目阶段:设计完成,部分实现 - 项目阶段:设计完成,部分实现
- 最近更新:aide env 模块化重构 - 最近更新:
- aide env set 命令实现
- 新增环境模块rust, node, flutter, android, node_deps
- 支持模块实例化命名(多项目场景)
- Skill 拆分aide基础+ env-config按需

View File

@@ -57,9 +57,9 @@ aide env ensure
- 输出环境状态和配置信息 - 输出环境状态和配置信息
根据输出处理: 根据输出处理:
- `✓`:环境就绪,继续 - `✓`:环境就绪,继续到步骤 5
- `⚠`:有警告但可继续,记录并继续 - `⚠`:有警告但可继续,记录并继续
- `✗`按提示修复3次失败则告知用户 - `✗`**触发 `env-config` skill**,按指导完成配置后重试
**注意** **注意**
- 此时不带 `--runtime` 参数,会读取项目配置文件检查项目环境 - 此时不带 `--runtime` 参数,会读取项目配置文件检查项目环境

View File

@@ -82,12 +82,18 @@ Commands 只告诉 LLM
## 三、Skill 索引 ## 三、Skill 索引
| Skill | 设计文档 | 执行文件 | 职责 | | Skill | 执行文件 | 职责 | 触发时机 |
|-------|----------|----------|------| |-------|----------|------|----------|
| aide | [skill/aide.md](skill/aide.md) | [../../skills/aide/SKILL.md](../skills/aide/SKILL.md) | aide 命令行工具使用指南 | | aide | [../skills/aide/SKILL.md](../skills/aide/SKILL.md) | aide 基础命令指南 | 始终加载 |
| env-config | [../skills/env-config/SKILL.md](../skills/env-config/SKILL.md) | 环境配置详细指南 | `aide env ensure` 失败时 |
### 3.1 Skill 设计原则 ### 3.1 Skill 设计原则
**按需触发,避免信息过载**
- `aide` skill始终加载提供基础命令用法
- `env-config` skill按需触发仅在环境检测失败时使用
**纯工具说明,便于快速查阅** **纯工具说明,便于快速查阅**
Skill 只包含: Skill 只包含:
@@ -97,6 +103,20 @@ Skill 只包含:
不包含流程指导和业务逻辑。 不包含流程指导和业务逻辑。
### 3.2 Skill 触发逻辑
```
aide env ensure
├─ 全部 ✓ → 继续流程(无需额外 skill
└─ 有 ✗ → 触发 env-config skill
├─ 分析项目类型
├─ aide env set 配置
└─ 重试 aide env ensure
```
--- ---
## 四、职责边界 ## 四、职责边界
@@ -134,11 +154,13 @@ Skill 只包含:
### 5.2 修改 Skill ### 5.2 修改 Skill
1. 阅读 [skill/aide.md](skill/aide.md) 1. 确定要修改的 skillaide 或 env-config
2. 理解各子命令的接口 2. 修改对应执行文件 `../skills/<skill>/SKILL.md`
3. 修改执行文件 `../skills/aide/SKILL.md` 3. 如涉及 aide-program 变更,同步更新 [aide-program 文档](../../../aide-program/docs/README.md)
4. 更新设计文档
5. 如涉及 aide-program 变更,同步更新 [aide-program 文档](../../../aide-program/docs/README.md) **注意**
- `aide` skill 保持精简,仅包含基础命令用法
- 详细配置指导放在 `env-config` skill
### 5.3 新增 Command ### 5.3 新增 Command

View File

@@ -22,46 +22,16 @@ Aide 是一套命令行工具,用于支持 Aide 工作流体系。所有 aide
## aide env - 环境管理 ## aide env - 环境管理
### aide env list
列出所有可用的环境检测模块。
```bash
aide env list
```
**输出示例**
```
可用模块:
模块 描述 能力 需要配置
────────────────────────────────────────────────────────────
python Python 解释器版本 check 否
uv uv 包管理器 check 否
venv Python 虚拟环境 check, ensure 是 [path]
requirements Python 依赖管理 check, ensure 是 [path]
当前启用: python, uv, venv, requirements
```
### aide env ensure ### aide env ensure
检测并修复开发环境。 检测并修复开发环境。
```bash ```bash
# 检查项目开发环境(按配置启用的模块 # 检查 aide 运行时环境init 流程使用
aide env ensure
# 仅检查 aide 运行时环境(不依赖配置文件)
aide env ensure --runtime aide env ensure --runtime
# 检测指定模块 # 检查项目开发环境(按配置启用的模块
aide env ensure --modules python,uv aide env ensure
# 检测所有已启用模块(仅检查不修复)
aide env ensure --all
# 显示详细配置信息(供人工确认)
aide env ensure --verbose
``` ```
**参数** **参数**
@@ -79,27 +49,33 @@ aide env ensure --verbose
# 成功 # 成功
✓ python: 3.14.2 (>=3.11) ✓ python: 3.14.2 (>=3.11)
✓ uv: uv 0.9.16 ✓ uv: uv 0.9.16
venv: .venv 环境就绪 (python:3.14.2, uv:uv 0.9.16)
✓ requirements: requirements.txt
✓ 环境就绪 (python:3.14.2, uv:uv 0.9.16, venv:.venv, requirements:requirements.txt)
``` ```
``` ```
# 自动修复 # 失败
✓ python: 3.14.2 (>=3.11)
✓ uv: uv 0.9.16
→ venv: 虚拟环境不存在: .venv尝试修复...
✓ venv: 已创建
✓ 环境就绪 (...)
```
```
# 失败(启用模块缺少配置)
✓ python: 3.14.2 (>=3.11)
✓ uv: uv 0.9.16
✗ venv: 已启用但缺少配置项: path ✗ venv: 已启用但缺少配置项: path
``` ```
**失败处理**:当 `aide env ensure` 输出 `✗` 时,触发 `env-config` skill 获取详细配置指导。
### aide env list
列出所有可用的环境检测模块。
```bash
aide env list
```
### aide env set
设置环境配置(详细用法见 `env-config` skill
```bash
aide env set modules <模块列表>
aide env set <模块名>.<配置项> <值>
```
--- ---
## aide flow - 进度追踪 ## aide flow - 进度追踪

View File

@@ -0,0 +1,256 @@
---
name: env-config
description: 环境配置详细指南。当 aide env ensure 检测失败需要配置环境时使用。提供模块选择、配置设置、多项目场景处理等详细指导。
---
# 环境配置指南
`aide env ensure` 检测失败(输出 `✗`)时,使用本指南分析项目所需环境并完成配置。
---
## 一、问题诊断
### 1.1 常见失败原因
| 错误信息 | 原因 | 解决方案 |
|----------|------|----------|
| `已启用但缺少配置项: path` | 类型B模块未配置路径 | 使用 `aide env set` 配置 |
| `未知模块: xxx` | 启用了不存在的模块 | 检查模块名拼写 |
| `xxx 未安装` | 工具未安装 | 安装对应工具或移除该模块 |
| `node_modules 不存在` | Node.js 依赖未安装 | 配置 node_deps 模块 |
### 1.2 查看可用模块
```bash
aide env list
```
---
## 二、模块分类
### 2.1 类型A全局工具检测无需配置
| 模块 | 检测内容 |
|------|----------|
| `python` | Python 解释器版本 |
| `uv` | uv 包管理器 |
| `rust` | Rust 工具链rustc + cargo |
| `node` | Node.js 运行时 |
| `flutter` | Flutter SDK |
| `android` | Android SDKANDROID_HOME |
### 2.2 类型B项目级检测需要配置
| 模块 | 配置项 | 说明 |
|------|--------|------|
| `venv` | `path` | Python 虚拟环境目录 |
| `requirements` | `path` | Python 依赖文件路径 |
| `node_deps` | `path`, `manager`(可选) | Node.js 项目依赖 |
---
## 三、配置命令
### 3.1 aide env set
```bash
# 设置启用的模块列表
aide env set modules <模块列表>
# 设置模块配置
aide env set <模块名>.<配置项> <值>
```
### 3.2 验证规则
- 设置 `modules` 时,验证每个模块类型是否存在
- 无效模块名会报错并显示可用模块列表
```bash
# 验证失败示例
$ aide env set modules python,fortran
✗ 未知模块: fortran
→ 可用模块: python, uv, venv, requirements, rust, node, flutter, node_deps, android
```
---
## 四、项目类型配置
### 4.1 项目特征与模块映射
| 项目特征 | 推荐模块 |
|----------|----------|
| 存在 `Cargo.toml` | `rust` |
| 存在 `package.json` | `node`, `node_deps` |
| 存在 `pubspec.yaml` | `flutter` |
| 存在 `build.gradle``android/` | `android` |
| 存在 `requirements.txt``.venv` | `python`, `uv`, `venv`, `requirements` |
### 4.2 配置示例
**Rust 项目**
```bash
aide env set modules rust
```
**Node.js 项目**
```bash
aide env set modules node,node_deps
aide env set node_deps.path .
```
**Flutter 项目**
```bash
aide env set modules flutter
# 如果需要构建 Android APK
aide env set modules flutter,android
```
**Python 项目**
```bash
aide env set modules python,uv,venv,requirements
aide env set venv.path .venv
aide env set requirements.path requirements.txt
```
**混合项目**(多种技术栈):
```bash
aide env set modules rust,node,flutter,android
```
---
## 五、多项目场景
### 5.1 模块实例化命名
当工作目录下有多个同类型子项目时,使用 `模块类型:实例名` 格式:
```bash
# 多个 Node.js 项目
aide env set modules node,node_deps:frontend,node_deps:admin
aide env set node_deps:frontend.path frontend
aide env set node_deps:admin.path admin
```
### 5.2 配置文件格式
```toml
[env]
modules = ["node", "node_deps:frontend", "node_deps:admin"]
[env."node_deps:frontend"]
path = "frontend"
[env."node_deps:admin"]
path = "admin"
manager = "pnpm"
```
### 5.3 输出示例
```
✓ node: 24.11.1 (npm 11.6.2)
✓ node_deps:frontend: frontend (npm)
✓ node_deps:admin: admin (pnpm)
✓ 环境就绪 (...)
```
---
## 六、node_deps 模块详解
### 6.1 配置项
| 配置项 | 必需 | 说明 |
|--------|------|------|
| `path` | 是 | package.json 所在目录 |
| `manager` | 否 | 包管理器,默认自动检测 |
### 6.2 包管理器自动检测
根据锁文件自动判断:
| 锁文件 | 包管理器 |
|--------|----------|
| `pnpm-lock.yaml` | pnpm |
| `yarn.lock` | yarn |
| `bun.lockb` | bun |
| `package-lock.json` 或无 | npm |
### 6.3 ensure 行为
检测失败时自动运行对应的安装命令:
- npm: `npm install`
- pnpm: `pnpm install`
- yarn: `yarn install`
- bun: `bun install`
---
## 七、配置流程
### 7.1 标准流程
```bash
# 1. 查看可用模块
aide env list
# 2. 分析项目类型,设置模块
aide env set modules <根据项目选择>
# 3. 配置类型B模块如有
aide env set <模块>.<配置项> <值>
# 4. 验证配置
aide env ensure
```
### 7.2 快速配置模板
**前端项目**
```bash
aide env set modules node,node_deps
aide env set node_deps.path .
aide env ensure
```
**全栈项目**
```bash
aide env set modules node,node_deps:frontend,node_deps:backend
aide env set node_deps:frontend.path frontend
aide env set node_deps:backend.path backend
aide env ensure
```
**移动端项目**
```bash
aide env set modules flutter,android
aide env ensure
```
---
## 八、故障排除
### 8.1 模块检测失败
```bash
# 查看详细信息
aide env ensure --verbose
```
### 8.2 重置配置
直接修改 `.aide/config.toml` 或重新运行:
```bash
aide env set modules <新的模块列表>
```
### 8.3 跳过某个模块
从 modules 列表中移除该模块即可。

View File

@@ -16,6 +16,40 @@ RUNTIME_MODULES = ["python", "uv"]
DEFAULT_MODULES = ["python", "uv", "venv", "requirements"] DEFAULT_MODULES = ["python", "uv", "venv", "requirements"]
def parse_module_name(name: str) -> tuple[str, str | None]:
"""解析模块名称,支持实例化命名。
Args:
name: 模块名称,如 "node_deps""node_deps:react"
Returns:
(模块类型, 实例名) - 实例名可能为 None
"""
if ":" in name:
parts = name.split(":", 1)
return parts[0], parts[1]
return name, None
def validate_modules(module_names: list[str]) -> tuple[bool, list[str]]:
"""验证模块名称是否有效。
Args:
module_names: 要验证的模块名称列表
Returns:
(是否全部有效, 无效的模块类型列表)
"""
register_builtin_modules()
available = set(ModuleRegistry.names())
invalid = []
for name in module_names:
module_type, _ = parse_module_name(name)
if module_type not in available:
invalid.append(module_type)
return len(invalid) == 0, invalid
class EnvManager: class EnvManager:
"""环境管理器。""" """环境管理器。"""
@@ -163,12 +197,20 @@ class EnvManager:
return env_config.get("modules", DEFAULT_MODULES) return env_config.get("modules", DEFAULT_MODULES)
def _get_module_config(self, name: str, config: dict[str, Any]) -> dict[str, Any]: def _get_module_config(self, name: str, config: dict[str, Any]) -> dict[str, Any]:
"""获取模块配置。""" """获取模块配置。
支持实例化命名,如 node_deps:react 会查找 [env."node_deps:react"]
"""
env_config = config.get("env", {}) env_config = config.get("env", {})
# 尝试新格式 [env.模块名] # 支持实例化命名:先尝试完整名称(如 node_deps:react
module_config = env_config.get(name, {}) module_config = env_config.get(name, {})
# 如果没找到且是实例化命名,尝试不带引号的格式
if not module_config and ":" in name:
# TOML 中可能存储为 env."node_deps:react" 或嵌套格式
pass # 已经在上面尝试过了
# 兼容旧格式:如果值是字符串而不是字典,转换为 {"path": value} # 兼容旧格式:如果值是字符串而不是字典,转换为 {"path": value}
if isinstance(module_config, str): if isinstance(module_config, str):
module_config = {"path": module_config} module_config = {"path": module_config}
@@ -204,10 +246,15 @@ class EnvManager:
) -> tuple[bool, str]: ) -> tuple[bool, str]:
"""处理单个模块的检测/修复。 """处理单个模块的检测/修复。
支持实例化命名,如 node_deps:react
Returns: Returns:
(是否成功, 版本/路径信息) (是否成功, 版本/路径信息)
""" """
module = ModuleRegistry.get(name) # 解析模块名称,支持实例化命名
module_type, instance_name = parse_module_name(name)
module = ModuleRegistry.get(module_type)
if not module: if not module:
if is_enabled: if is_enabled:
output.err(f"{name}: 未知模块") output.err(f"{name}: 未知模块")
@@ -216,6 +263,7 @@ class EnvManager:
output.warn(f"{name}: 未知模块") output.warn(f"{name}: 未知模块")
return True, "" return True, ""
# 获取配置时使用完整名称(包含实例名)
module_config = self._get_module_config(name, config) module_config = self._get_module_config(name, config)
# verbose: 输出模块配置 # verbose: 输出模块配置
@@ -272,3 +320,54 @@ class EnvManager:
else: else:
output.warn(f"{name}: {result.message}") output.warn(f"{name}: {result.message}")
return True, "" return True, ""
def set_modules(self, module_names: list[str]) -> bool:
"""设置启用的模块列表(带验证)。
Args:
module_names: 要启用的模块名称列表
Returns:
是否设置成功
"""
# 验证模块名称
valid, invalid = validate_modules(module_names)
if not valid:
available = ModuleRegistry.names()
output.err(f"未知模块: {', '.join(invalid)}")
output.info(f"可用模块: {', '.join(available)}")
return False
# 设置配置
self.cfg.set_value("env.modules", module_names)
return True
def set_module_config(self, module_name: str, key: str, value: Any) -> bool:
"""设置模块配置(带验证)。
支持实例化命名,如 node_deps:react.path
Args:
module_name: 模块名称(可包含实例名,如 node_deps:react
key: 配置键
value: 配置值
Returns:
是否设置成功
"""
# 解析模块名称,支持实例化命名
module_type, _ = parse_module_name(module_name)
# 验证模块类型是否存在
module = ModuleRegistry.get(module_type)
if not module:
available = ModuleRegistry.names()
output.err(f"未知模块: {module_type}")
output.info(f"可用模块: {', '.join(available)}")
return False
# 设置配置,使用完整模块名(包含实例名)
# 注意TOML 中带冒号的键需要引号,但 set_value 会自动处理
config_key = f"env.{module_name}.{key}"
self.cfg.set_value(config_key, value)
return True

146
aide-program/aide/env/modules/android.py vendored Normal file
View File

@@ -0,0 +1,146 @@
"""Android 开发环境检测模块。"""
from __future__ import annotations
import os
import subprocess
from pathlib import Path
from typing import Any
from aide.env.modules.base import BaseModule, CheckResult, ModuleInfo
class AndroidModule(BaseModule):
"""Android 开发环境检测模块类型A无需配置
检测 Android SDK 和相关工具:
- ANDROID_HOME / ANDROID_SDK_ROOT 环境变量
- Android SDK 目录结构
- 关键工具adb, aapt, sdkmanager
"""
@property
def info(self) -> ModuleInfo:
return ModuleInfo(
name="android",
description="Android SDK",
capabilities=["check"],
requires_config=False,
)
def check(self, config: dict[str, Any], root: Path) -> CheckResult:
"""检测 Android 开发环境。"""
# 检测 ANDROID_HOME 或 ANDROID_SDK_ROOT
sdk_root = self._get_sdk_root()
if not sdk_root:
return CheckResult(
success=False,
message="ANDROID_HOME 或 ANDROID_SDK_ROOT 未设置",
can_ensure=False,
)
sdk_path = Path(sdk_root)
if not sdk_path.exists():
return CheckResult(
success=False,
message=f"Android SDK 目录不存在: {sdk_root}",
can_ensure=False,
)
# 检测关键目录
platform_tools = sdk_path / "platform-tools"
build_tools = sdk_path / "build-tools"
platforms = sdk_path / "platforms"
missing = []
if not platform_tools.exists():
missing.append("platform-tools")
if not build_tools.exists():
missing.append("build-tools")
if not platforms.exists():
missing.append("platforms")
if missing:
return CheckResult(
success=False,
message=f"缺少 SDK 组件: {', '.join(missing)}",
can_ensure=False,
)
# 获取版本信息
build_tools_versions = self._get_build_tools_versions(build_tools)
platform_versions = self._get_platform_versions(platforms)
# 检测 adb
adb_version = self._get_adb_version(platform_tools)
# 构建版本信息
version_info = []
if adb_version:
version_info.append(f"adb {adb_version}")
if build_tools_versions:
version_info.append(f"build-tools {build_tools_versions[0]}")
if platform_versions:
version_info.append(f"API {platform_versions[0]}")
return CheckResult(
success=True,
version=sdk_root,
message=", ".join(version_info) if version_info else None,
)
def _get_sdk_root(self) -> str | None:
"""获取 Android SDK 根目录。"""
return os.environ.get("ANDROID_HOME") or os.environ.get("ANDROID_SDK_ROOT")
def _get_adb_version(self, platform_tools: Path) -> str | None:
"""获取 adb 版本。"""
adb_path = platform_tools / "adb"
if not adb_path.exists():
return None
try:
result = subprocess.run(
[str(adb_path), "version"],
capture_output=True,
text=True,
timeout=10,
)
if result.returncode == 0:
# Android Debug Bridge version 1.0.41
lines = result.stdout.strip().split("\n")
if lines:
parts = lines[0].split()
if len(parts) >= 5:
return parts[4]
return None
except (subprocess.TimeoutExpired, Exception):
return None
def _get_build_tools_versions(self, build_tools: Path) -> list[str]:
"""获取已安装的 build-tools 版本列表(降序)。"""
if not build_tools.exists():
return []
versions = []
for item in build_tools.iterdir():
if item.is_dir() and item.name[0].isdigit():
versions.append(item.name)
return sorted(versions, reverse=True)
def _get_platform_versions(self, platforms: Path) -> list[str]:
"""获取已安装的 platform 版本列表(降序)。"""
if not platforms.exists():
return []
versions = []
for item in platforms.iterdir():
if item.is_dir() and item.name.startswith("android-"):
api_level = item.name.replace("android-", "")
versions.append(api_level)
return sorted(versions, key=lambda x: int(x) if x.isdigit() else 0, reverse=True)
module = AndroidModule()

132
aide-program/aide/env/modules/flutter.py vendored Normal file
View File

@@ -0,0 +1,132 @@
"""Flutter SDK 检测模块。"""
from __future__ import annotations
import subprocess
from pathlib import Path
from typing import Any
from aide.env.modules.base import BaseModule, CheckResult, ModuleInfo
class FlutterModule(BaseModule):
"""Flutter SDK 检测模块类型A无需配置"""
@property
def info(self) -> ModuleInfo:
return ModuleInfo(
name="flutter",
description="Flutter SDK",
capabilities=["check"],
requires_config=False,
)
def check(self, config: dict[str, Any], root: Path) -> CheckResult:
"""检测 Flutter SDK。"""
flutter_version = self._get_flutter_version()
dart_version = self._get_dart_version()
if not flutter_version:
return CheckResult(
success=False,
message="flutter 未安装",
can_ensure=False,
)
# 检查最低版本要求(如果配置了)
min_version = config.get("min_version")
if min_version:
if not self._version_satisfies(flutter_version, min_version):
return CheckResult(
success=False,
version=flutter_version,
message=f"版本不足,要求>={min_version},当前 {flutter_version}",
can_ensure=False,
)
# 构建版本信息
extra = f"dart {dart_version}" if dart_version else ""
return CheckResult(
success=True,
version=flutter_version,
message=extra,
)
def _get_flutter_version(self) -> str | None:
"""获取 Flutter 版本。"""
try:
result = subprocess.run(
["flutter", "--version", "--machine"],
capture_output=True,
text=True,
timeout=30,
)
if result.returncode == 0:
# 尝试解析 JSON 输出
import json
try:
data = json.loads(result.stdout)
return data.get("frameworkVersion")
except json.JSONDecodeError:
pass
# 回退到普通版本输出
result = subprocess.run(
["flutter", "--version"],
capture_output=True,
text=True,
timeout=30,
)
if result.returncode == 0:
# Flutter 3.16.0 • channel stable • ...
output = result.stdout.strip()
lines = output.split("\n")
if lines:
parts = lines[0].split()
if len(parts) >= 2 and parts[0] == "Flutter":
return parts[1]
return None
except (FileNotFoundError, subprocess.TimeoutExpired):
return None
def _get_dart_version(self) -> str | None:
"""获取 Dart 版本。"""
try:
result = subprocess.run(
["dart", "--version"],
capture_output=True,
text=True,
timeout=10,
)
if result.returncode == 0:
# Dart SDK version: 3.2.0 (stable) ...
output = result.stdout.strip()
if not output:
output = result.stderr.strip() # dart 有时输出到 stderr
parts = output.split()
for i, part in enumerate(parts):
if part == "version:" and i + 1 < len(parts):
return parts[i + 1]
return None
except (FileNotFoundError, subprocess.TimeoutExpired):
return None
def _version_satisfies(self, current: str, minimum: str) -> bool:
"""检查版本是否满足最低要求。"""
current_parts = self._parse_version(current)
min_parts = self._parse_version(minimum)
return current_parts >= min_parts
@staticmethod
def _parse_version(version: str) -> tuple[int, ...]:
"""解析版本号字符串。"""
parts = []
for part in version.split("."):
try:
parts.append(int(part))
except ValueError:
break
return tuple(parts)
module = FlutterModule()

93
aide-program/aide/env/modules/node.py vendored Normal file
View File

@@ -0,0 +1,93 @@
"""Node.js 环境检测模块。"""
from __future__ import annotations
import subprocess
from pathlib import Path
from typing import Any
from aide.env.modules.base import BaseModule, CheckResult, ModuleInfo
class NodeModule(BaseModule):
"""Node.js 检测模块类型A无需配置"""
@property
def info(self) -> ModuleInfo:
return ModuleInfo(
name="node",
description="Node.js 运行时",
capabilities=["check"],
requires_config=False,
)
def check(self, config: dict[str, Any], root: Path) -> CheckResult:
"""检测 Node.js 版本。"""
node_version = self._get_version("node")
npm_version = self._get_version("npm")
if not node_version:
return CheckResult(
success=False,
message="node 未安装",
can_ensure=False,
)
# 检查最低版本要求(如果配置了)
min_version = config.get("min_version")
if min_version:
if not self._version_satisfies(node_version, min_version):
return CheckResult(
success=False,
version=node_version,
message=f"版本不足,要求>={min_version},当前 {node_version}",
can_ensure=False,
)
# 构建版本信息
extra = f"npm {npm_version}" if npm_version else "npm 未安装"
return CheckResult(
success=True,
version=node_version,
message=extra,
)
def _get_version(self, cmd: str) -> str | None:
"""获取命令版本。"""
try:
result = subprocess.run(
[cmd, "--version"],
capture_output=True,
text=True,
timeout=10,
)
if result.returncode == 0:
# node: v20.10.0 -> 20.10.0
# npm: 10.2.3 -> 10.2.3
output = result.stdout.strip()
if output.startswith("v"):
output = output[1:]
return output
return None
except (FileNotFoundError, subprocess.TimeoutExpired):
return None
def _version_satisfies(self, current: str, minimum: str) -> bool:
"""检查版本是否满足最低要求。"""
current_parts = self._parse_version(current)
min_parts = self._parse_version(minimum)
return current_parts >= min_parts
@staticmethod
def _parse_version(version: str) -> tuple[int, ...]:
"""解析版本号字符串。"""
parts = []
for part in version.split("."):
try:
parts.append(int(part))
except ValueError:
break
return tuple(parts)
module = NodeModule()

View File

@@ -0,0 +1,141 @@
"""Node.js 项目依赖检测模块。"""
from __future__ import annotations
import subprocess
from pathlib import Path
from typing import Any
from aide.env.modules.base import BaseModule, CheckResult, ModuleInfo
class NodeDepsModule(BaseModule):
"""Node.js 项目依赖检测模块类型B需要配置
支持多种包管理器npm, pnpm, yarn, bun
自动根据锁文件检测包管理器类型
"""
# 锁文件到包管理器的映射
LOCK_FILES = {
"pnpm-lock.yaml": "pnpm",
"yarn.lock": "yarn",
"bun.lockb": "bun",
"package-lock.json": "npm",
}
# 包管理器安装命令
INSTALL_COMMANDS = {
"npm": ["npm", "install"],
"pnpm": ["pnpm", "install"],
"yarn": ["yarn", "install"],
"bun": ["bun", "install"],
}
@property
def info(self) -> ModuleInfo:
return ModuleInfo(
name="node_deps",
description="Node.js 项目依赖",
capabilities=["check", "ensure"],
requires_config=True,
config_keys=["path"],
)
def check(self, config: dict[str, Any], root: Path) -> CheckResult:
"""检测 Node.js 项目依赖。"""
project_path = root / config["path"]
# 检测 package.json 是否存在
package_json = project_path / "package.json"
if not package_json.exists():
return CheckResult(
success=False,
message=f"package.json 不存在: {config['path']}",
can_ensure=False,
)
# 检测 node_modules 是否存在
node_modules = project_path / "node_modules"
if not node_modules.exists():
manager = self._detect_manager(project_path, config)
return CheckResult(
success=False,
message=f"node_modules 不存在",
can_ensure=True,
)
# 检测包管理器
manager = self._detect_manager(project_path, config)
return CheckResult(
success=True,
version=config["path"],
message=manager,
)
def ensure(self, config: dict[str, Any], root: Path) -> CheckResult:
"""安装 Node.js 项目依赖。"""
project_path = root / config["path"]
manager = self._detect_manager(project_path, config)
# 检测包管理器是否已安装
if not self._is_manager_installed(manager):
return CheckResult(
success=False,
message=f"{manager} 未安装",
)
# 运行安装命令
install_cmd = self.INSTALL_COMMANDS.get(manager, ["npm", "install"])
try:
subprocess.run(
install_cmd,
cwd=project_path,
check=True,
capture_output=True,
)
return CheckResult(
success=True,
version=config["path"],
message=f"已安装 ({manager})",
)
except subprocess.CalledProcessError as exc:
error_msg = exc.stderr.decode() if exc.stderr else str(exc)
return CheckResult(
success=False,
message=f"安装失败: {error_msg[:100]}",
)
def _detect_manager(self, project_path: Path, config: dict[str, Any]) -> str:
"""检测包管理器类型。
优先使用配置指定的 manager否则根据锁文件自动检测。
"""
# 优先使用配置指定的 manager
if "manager" in config:
return config["manager"]
# 根据锁文件检测
for lock_file, manager in self.LOCK_FILES.items():
if (project_path / lock_file).exists():
return manager
# 默认使用 npm
return "npm"
def _is_manager_installed(self, manager: str) -> bool:
"""检测包管理器是否已安装。"""
try:
subprocess.run(
[manager, "--version"],
capture_output=True,
timeout=10,
)
return True
except (FileNotFoundError, subprocess.TimeoutExpired):
return False
module = NodeDepsModule()

98
aide-program/aide/env/modules/rust.py vendored Normal file
View File

@@ -0,0 +1,98 @@
"""Rust 工具链检测模块。"""
from __future__ import annotations
import subprocess
from pathlib import Path
from typing import Any
from aide.env.modules.base import BaseModule, CheckResult, ModuleInfo
class RustModule(BaseModule):
"""Rust 工具链检测模块类型A无需配置"""
@property
def info(self) -> ModuleInfo:
return ModuleInfo(
name="rust",
description="Rust 工具链",
capabilities=["check"],
requires_config=False,
)
def check(self, config: dict[str, Any], root: Path) -> CheckResult:
"""检测 Rust 工具链rustc 和 cargo"""
rustc_version = self._get_version("rustc")
cargo_version = self._get_version("cargo")
if not rustc_version:
return CheckResult(
success=False,
message="rustc 未安装",
can_ensure=False,
)
if not cargo_version:
return CheckResult(
success=False,
message="cargo 未安装",
can_ensure=False,
)
# 检查最低版本要求(如果配置了)
min_version = config.get("min_version")
if min_version:
if not self._version_satisfies(rustc_version, min_version):
return CheckResult(
success=False,
version=rustc_version,
message=f"版本不足,要求>={min_version},当前 {rustc_version}",
can_ensure=False,
)
return CheckResult(
success=True,
version=rustc_version,
message=f"cargo {cargo_version}",
)
def _get_version(self, cmd: str) -> str | None:
"""获取命令版本。"""
try:
result = subprocess.run(
[cmd, "--version"],
capture_output=True,
text=True,
timeout=10,
)
if result.returncode == 0:
# rustc 1.75.0 (xxx) -> 1.75.0
# cargo 1.75.0 (xxx) -> 1.75.0
output = result.stdout.strip()
parts = output.split()
if len(parts) >= 2:
return parts[1]
return None
except (FileNotFoundError, subprocess.TimeoutExpired):
return None
def _version_satisfies(self, current: str, minimum: str) -> bool:
"""检查版本是否满足最低要求。"""
current_parts = self._parse_version(current)
min_parts = self._parse_version(minimum)
return current_parts >= min_parts
@staticmethod
def _parse_version(version: str) -> tuple[int, ...]:
"""解析版本号字符串。"""
parts = []
for part in version.split("."):
try:
parts.append(int(part))
except ValueError:
break
return tuple(parts)
module = RustModule()

View File

@@ -43,8 +43,12 @@ class ModuleRegistry:
def register_builtin_modules() -> None: def register_builtin_modules() -> None:
"""注册内置模块。""" """注册内置模块。"""
from aide.env.modules import python, uv, venv, requirements from aide.env.modules import (
python, uv, venv, requirements,
rust, node, flutter,
node_deps, android,
)
for mod in [python, uv, venv, requirements]: for mod in [python, uv, venv, requirements, rust, node, flutter, node_deps, android]:
if hasattr(mod, "module"): if hasattr(mod, "module"):
ModuleRegistry.register(mod.module) ModuleRegistry.register(mod.module)

View File

@@ -69,6 +69,12 @@ def build_parser() -> argparse.ArgumentParser:
list_parser = env_sub.add_parser("list", help="列出所有可用模块") list_parser = env_sub.add_parser("list", help="列出所有可用模块")
list_parser.set_defaults(func=handle_env_list) list_parser.set_defaults(func=handle_env_list)
# aide env set
set_parser = env_sub.add_parser("set", help="设置环境配置(带验证)")
set_parser.add_argument("key", help="配置键modules 或 模块名.配置项")
set_parser.add_argument("value", help="配置值")
set_parser.set_defaults(func=handle_env_set)
# aide env无子命令时等同于 ensure # aide env无子命令时等同于 ensure
env_parser.set_defaults(func=handle_env_default) env_parser.set_defaults(func=handle_env_default)
@@ -137,6 +143,34 @@ def handle_env_list(args: argparse.Namespace) -> bool:
return True return True
def handle_env_set(args: argparse.Namespace) -> bool:
"""aide env set 处理。"""
root = Path.cwd()
cfg = ConfigManager(root)
manager = EnvManager(root, cfg)
key = args.key
value = args.value
if key == "modules":
# 设置启用的模块列表
module_names = [m.strip() for m in value.split(",") if m.strip()]
return manager.set_modules(module_names)
elif "." in key:
# 设置模块配置,如 venv.path
parts = key.split(".", 1)
module_name = parts[0]
config_key = parts[1]
parsed_value = _parse_value(value)
return manager.set_module_config(module_name, config_key, parsed_value)
else:
# 无效的键格式
output.err(f"无效的配置键: {key}")
output.info("用法: aide env set modules <模块列表>")
output.info(" aide env set <模块名>.<配置项> <值>")
return False
def handle_config_get(args: argparse.Namespace) -> bool: def handle_config_get(args: argparse.Namespace) -> bool:
root = Path.cwd() root = Path.cwd()
cfg = ConfigManager(root) cfg = ConfigManager(root)

View File

@@ -43,11 +43,29 @@ aide-program 是 Aide 工作流体系的命令行工具,为 aide-plugin 提供
| 子命令 | 设计文档 | 实现状态 | 职责 | | 子命令 | 设计文档 | 实现状态 | 职责 |
|--------|----------|----------|------| |--------|----------|----------|------|
| `aide init` | [commands/init.md](commands/init.md) | ✅ 已实现 | 初始化 .aide 目录 | | `aide init` | [commands/init.md](commands/init.md) | ✅ 已实现 | 初始化 .aide 目录 |
| `aide env` | [commands/env.md](commands/env.md) | ✅ 已实现 | 环境检测与修复 | | `aide env ensure` | [commands/env.md](commands/env.md) | ✅ 已实现 | 环境检测与修复 |
| `aide env list` | [commands/env.md](commands/env.md) | ✅ 已实现 | 列出可用模块 |
| `aide env set` | [commands/env.md](commands/env.md) | ✅ 已实现 | 设置环境配置(带验证) |
| `aide config` | [formats/config.md](formats/config.md) | ✅ 已实现 | 配置读写 | | `aide config` | [formats/config.md](formats/config.md) | ✅ 已实现 | 配置读写 |
| `aide flow` | [commands/flow.md](commands/flow.md) | ⏳ 待实现 | 进度追踪与 git 集成 | | `aide flow` | [commands/flow.md](commands/flow.md) | ⏳ 待实现 | 进度追踪与 git 集成 |
| `aide decide` | [commands/decide.md](commands/decide.md) | ⏳ 待实现 | 待定项 Web 确认 | | `aide decide` | [commands/decide.md](commands/decide.md) | ⏳ 待实现 | 待定项 Web 确认 |
### 2.1 环境检测模块
| 模块 | 类型 | 说明 |
|------|------|------|
| python, uv | A | Python 运行时 |
| rust | A | Rust 工具链 |
| node | A | Node.js 运行时 |
| flutter | A | Flutter SDK |
| android | A | Android SDK |
| venv, requirements | B | Python 项目依赖 |
| node_deps | B | Node.js 项目依赖 |
- 类型A无需配置即可检测
- 类型B需要配置路径
- 支持模块实例化命名:`模块类型:实例名`
--- ---
## 三、目录结构 ## 三、目录结构
@@ -71,21 +89,21 @@ aide-program/
├── __main__.py # 支持 python -m aide ├── __main__.py # 支持 python -m aide
├── main.py # CLI 解析与命令分发 ├── main.py # CLI 解析与命令分发
├── core/ ├── core/
│ ├── __init__.py
│ ├── config.py # 配置读写 │ ├── config.py # 配置读写
│ └── output.py # 输出格式(✓/⚠/✗/→) │ └── output.py # 输出格式(✓/⚠/✗/→)
├── env/ ├── env/
│ ├── __init__.py │ ├── manager.py # 环境管理器
── ensure.py # 环境检测与修复 ── registry.py # 模块注册表
│ └── modules/ # 环境检测模块
│ ├── base.py # 模块基类
│ ├── python.py, uv.py, rust.py
│ ├── node.py, flutter.py, android.py
│ ├── venv.py, requirements.py
│ └── node_deps.py
├── flow/ # 待实现 ├── flow/ # 待实现
── __init__.py ── ...
│ ├── tracker.py # 进度追踪
│ ├── git.py # git 自动提交
│ └── validator.py # 流程校验
└── decide/ # 待实现 └── decide/ # 待实现
── __init__.py ── ...
├── server.py # HTTP 服务
└── web/ # 静态前端
``` ```
--- ---

View File

@@ -28,6 +28,7 @@
aide env # 等同于 aide env ensure aide env # 等同于 aide env ensure
aide env ensure [options] # 检测并修复 aide env ensure [options] # 检测并修复
aide env list # 列出所有可用模块 aide env list # 列出所有可用模块
aide env set <key> <value> # 设置环境配置(带验证)
``` ```
### 2.1 aide env ensure ### 2.1 aide env ensure
@@ -47,6 +48,45 @@ aide env list # 列出所有可用模块
列出所有可用的环境检测模块及其状态。 列出所有可用的环境检测模块及其状态。
### 2.3 aide env set
设置环境配置,带模块名称验证。
**用法:**
```bash
aide env set modules <模块列表> # 设置启用的模块(逗号分隔)
aide env set <模块名>.<配置项> <值> # 设置模块配置
```
**示例:**
```bash
# 设置启用的模块
aide env set modules python,uv,rust,node
# 设置模块配置
aide env set venv.path .venv
aide env set requirements.path requirements.txt
# 设置实例化模块(多项目场景)
aide env set modules rust,node,flutter,android,node_deps:react
aide env set node_deps:react.path react-demo
```
**验证规则:**
- 设置 `modules` 时,验证每个模块类型是否存在
- 设置模块配置时,验证模块类型是否存在
- 无效模块名会报错并显示可用模块列表
**错误示例:**
```
✗ 未知模块: fortran, cobol
→ 可用模块: python, uv, venv, requirements, rust, node, flutter, node_deps, android
```
--- ---
## 三、模块系统 ## 三、模块系统
@@ -59,6 +99,10 @@ aide env list # 列出所有可用模块
|------|------|------| |------|------|------|
| `python` | Python 解释器版本 | check | | `python` | Python 解释器版本 | check |
| `uv` | uv 包管理器 | check | | `uv` | uv 包管理器 | check |
| `rust` | Rust 工具链rustc + cargo | check |
| `node` | Node.js 运行时 | check |
| `flutter` | Flutter SDK | check |
| `android` | Android SDK | check |
**类型B路径依赖模块必须有配置才能检测** **类型B路径依赖模块必须有配置才能检测**
@@ -66,12 +110,36 @@ aide env list # 列出所有可用模块
|------|------|------|----------| |------|------|------|----------|
| `venv` | Python 虚拟环境 | check, ensure | `path` | | `venv` | Python 虚拟环境 | check, ensure | `path` |
| `requirements` | Python 依赖管理 | check, ensure | `path` | | `requirements` | Python 依赖管理 | check, ensure | `path` |
| `node_deps` | Node.js 项目依赖 | check, ensure | `path` |
### 3.2 模块能力 ### 3.2 模块能力
- `check`:检测环境是否可用 - `check`:检测环境是否可用
- `ensure`:检测失败时尝试自动修复 - `ensure`:检测失败时尝试自动修复
### 3.3 模块实例化命名
支持 `模块类型:实例名` 格式,用于同类型多实例场景:
```toml
# 多个 Node.js 项目
modules = ["node", "node_deps:react", "node_deps:vue"]
[env."node_deps:react"]
path = "react-demo"
[env."node_deps:vue"]
path = "vue-demo"
manager = "pnpm"
```
**输出示例:**
```
✓ node: 24.11.1 (npm 11.6.2)
✓ node_deps:react: react-demo (npm)
✓ node_deps:vue: vue-demo (pnpm)
```
--- ---
## 四、配置 ## 四、配置
@@ -95,7 +163,32 @@ path = ".venv"
path = "requirements.txt" path = "requirements.txt"
``` ```
### 4.2 配置兼容性 ### 4.2 多项目配置示例
```toml
[env]
modules = ["rust", "node", "flutter", "android", "node_deps:react"]
# Node.js 项目依赖(实例化命名)
[env."node_deps:react"]
path = "react-demo"
# manager = "npm" # 可选,默认自动检测
```
### 4.3 node_deps 模块配置
| 配置项 | 必需 | 说明 |
|--------|------|------|
| `path` | 是 | package.json 所在目录 |
| `manager` | 否 | 包管理器npm/pnpm/yarn/bun默认自动检测 |
**自动检测逻辑**(按锁文件判断):
- `pnpm-lock.yaml` → pnpm
- `yarn.lock` → yarn
- `bun.lockb` → bun
- `package-lock.json` 或无锁文件 → npm
### 4.4 配置兼容性
支持旧格式配置: 支持旧格式配置:
@@ -129,88 +222,6 @@ requirements = "requirements.txt"
- 未启用模块失败 = 警告(⚠) = 可忽略 - 未启用模块失败 = 警告(⚠) = 可忽略
- 启用的B类模块无配置 = 错误(✗) = 配置错误 - 启用的B类模块无配置 = 错误(✗) = 配置错误
### 5.2 业务流程
```
@startuml
skinparam defaultFontName "PingFang SC"
start
:读取配置;
:获取启用模块列表;
if (--runtime?) then (是)
:target = [python, uv];
else if (--modules?) then (是)
:target = 指定模块;
else if (--all?) then (是)
:target = 启用模块;
:check_only = true;
else (否)
:target = 启用模块;
endif
if (verbose?) then (是)
:输出详细头部信息;
endif
:遍历 target 模块;
repeat
:获取模块实例;
:获取模块配置;
if (verbose?) then (是)
:输出模块配置详情;
endif
if (B类模块 && 无配置?) then (是)
if (在启用列表?) then (是)
:输出错误;
stop
else (否)
:输出警告,跳过;
endif
endif
:执行 check();
if (成功?) then (是)
:输出成功;
else (否)
if (check_only?) then (是)
:输出警告;
else if (可修复?) then (是)
:执行 ensure();
if (修复成功?) then (是)
:输出成功;
else (否)
if (在启用列表?) then (是)
:输出错误;
stop
else (否)
:输出警告;
endif
endif
else (否)
if (在启用列表?) then (是)
:输出错误;
stop
else (否)
:输出警告;
endif
endif
endif
repeat while (还有模块?)
:输出环境就绪;
stop
@enduml
```
--- ---
## 六、输出示例 ## 六、输出示例
@@ -225,87 +236,42 @@ stop
uv uv 包管理器 check 否 uv uv 包管理器 check 否
venv Python 虚拟环境 check, ensure 是 [path] venv Python 虚拟环境 check, ensure 是 [path]
requirements Python 依赖管理 check, ensure 是 [path] requirements Python 依赖管理 check, ensure 是 [path]
rust Rust 工具链 check 否
node Node.js 运行时 check 否
flutter Flutter SDK check 否
node_deps Node.js 项目依赖 check, ensure 是 [path]
android Android SDK check 否
当前启用: python, uv, venv, requirements 当前启用: rust, node, flutter, android, node_deps:react
``` ```
### 6.2 aide env ensure ### 6.2 aide env ensure(多项目场景)
**成功:**
```
✓ python: 3.14.2 (>=3.11)
✓ uv: uv 0.9.16
✓ venv: .venv
✓ requirements: requirements.txt
✓ 环境就绪 (python:3.14.2, uv:uv 0.9.16, venv:.venv, requirements:requirements.txt)
```
**需修复:**
```
✓ python: 3.14.2 (>=3.11)
✓ uv: uv 0.9.16
→ venv: 虚拟环境不存在: .venv尝试修复...
✓ venv: 已创建
✓ requirements: requirements.txt
✓ 环境就绪 (...)
```
**启用模块失败:**
```
✓ python: 3.14.2 (>=3.11)
✓ uv: uv 0.9.16
✗ venv: 已启用但缺少配置项: path
```
### 6.3 aide env ensure --verbose
``` ```
============================================================ ✓ rust: 1.94.0-nightly (cargo 1.94.0-nightly)
环境检测详细信息 ✓ node: 24.11.1 (npm 11.6.2)
============================================================ ✓ flutter: 3.38.4 (dart 3.10.3)
✓ android: /home/user/android-sdk (adb 1.0.41, build-tools 36.1.0, API 36)
工作目录: /home/user/myproject → node_deps:react: node_modules 不存在,尝试修复...
配置文件: /home/user/myproject/.aide/config.toml ✓ node_deps:react: 已安装 (npm)
配置存在: 是 ✓ 环境就绪 (rust:1.94.0-nightly, node:24.11.1, flutter:3.38.4, android:/home/user/android-sdk, node_deps:react:react-demo)
启用模块: python, uv, venv, requirements
目标模块: python, uv, venv, requirements
[python] 配置:
min_version: 3.11
✓ python: 3.14.2 (>=3.11)
[uv] 配置:
(无配置)
✓ uv: uv 0.9.16
[venv] 配置:
path: .venv
path (绝对): /home/user/myproject/.venv
path (存在): 是
✓ venv: .venv
[requirements] 配置:
path: requirements.txt
path (绝对): /home/user/myproject/requirements.txt
path (存在): 是
✓ requirements: requirements.txt
✓ 环境就绪 (...)
``` ```
### 6.4 aide env ensure --runtime ### 6.3 aide env set 示例
``` ```bash
✓ python: 3.14.2 (>=3.11) # 设置多种环境模块
✓ uv: uv 0.9.16 $ aide env set modules rust,node,flutter,android,node_deps:react
环境就绪 (python:3.14.2, uv:uv 0.9.16) 已更新 env.modules = ['rust', 'node', 'flutter', 'android', 'node_deps:react']
```
### 6.5 aide env ensure --all # 设置实例化模块配置
$ aide env set node_deps:react.path react-demo
✓ 已更新 env."node_deps:react".path = 'react-demo'
``` # 验证失败示例
✓ python: 3.14.2 (>=3.11) $ aide env set modules python,fortran
✓ uv: uv 0.9.16 ✗ 未知模块: fortran
✓ venv: .venv → 可用模块: python, uv, venv, requirements, rust, node, flutter, node_deps, android
✓ requirements: requirements.txt
``` ```
--- ---
@@ -323,7 +289,12 @@ aide/env/
├── python.py # Python 模块 ├── python.py # Python 模块
├── uv.py # uv 模块 ├── uv.py # uv 模块
├── venv.py # venv 模块 ├── venv.py # venv 模块
── requirements.py # requirements 模块 ── requirements.py # requirements 模块
├── rust.py # Rust 模块
├── node.py # Node.js 模块
├── flutter.py # Flutter 模块
├── node_deps.py # Node.js 项目依赖模块
└── android.py # Android SDK 模块
``` ```
### 7.1 模块基类 ### 7.1 模块基类

View File

@@ -89,10 +89,20 @@ phases = ["task-optimize", "flow-design", "impl", "verify", "docs", "finish"]
| `modules` | array | `["python", "uv", "venv", "requirements"]` | 启用的环境检测模块 | | `modules` | array | `["python", "uv", "venv", "requirements"]` | 启用的环境检测模块 |
**可用模块** **可用模块**
- `python` - Python 解释器版本检测
- `uv` - uv 包管理器检测 | 模块 | 类型 | 说明 |
- `venv` - Python 虚拟环境管理 |------|------|------|
- `requirements` - Python 依赖管理 | `python` | A | Python 解释器版本检测 |
| `uv` | A | uv 包管理器检测 |
| `rust` | A | Rust 工具链检测rustc + cargo |
| `node` | A | Node.js 运行时检测 |
| `flutter` | A | Flutter SDK 检测 |
| `android` | A | Android SDK 检测 |
| `venv` | B | Python 虚拟环境管理 |
| `requirements` | B | Python 依赖管理 |
| `node_deps` | B | Node.js 项目依赖管理 |
**模块实例化命名**:支持 `模块类型:实例名` 格式,用于同类型多实例场景。
#### 4.3.2 模块配置 #### 4.3.2 模块配置
@@ -111,6 +121,24 @@ path = ".venv" # 虚拟环境目录路径
[env.requirements] [env.requirements]
path = "requirements.txt" # 依赖文件路径 path = "requirements.txt" # 依赖文件路径
[env.node_deps]
path = "frontend" # package.json 所在目录
manager = "npm" # 可选npm/pnpm/yarn/bun默认自动检测
```
**实例化模块配置**(多项目场景):
```toml
[env]
modules = ["node", "node_deps:react", "node_deps:vue"]
[env."node_deps:react"]
path = "react-demo"
[env."node_deps:vue"]
path = "vue-demo"
manager = "pnpm"
``` ```
**使用场景** **使用场景**

109
cache/setup-test-projects.sh vendored Normal file
View File

@@ -0,0 +1,109 @@
#!/bin/bash
# 创建 aide-env-test 测试目录和项目
set -e
BASE_DIR="/home/user/temp/ccoptimize/test-cache/aide-env-test"
# 创建基础目录
mkdir -p "$BASE_DIR"
# 创建 rust-demo 项目
mkdir -p "$BASE_DIR/rust-demo/src"
cat > "$BASE_DIR/rust-demo/Cargo.toml" << 'EOF'
[package]
name = "rust-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
EOF
cat > "$BASE_DIR/rust-demo/src/main.rs" << 'EOF'
fn main() {
println!("Hello from Rust demo!");
}
EOF
# 创建 flutter-demo 项目(简化结构)
mkdir -p "$BASE_DIR/flutter-demo/lib"
cat > "$BASE_DIR/flutter-demo/pubspec.yaml" << 'EOF'
name: flutter_demo
description: A Flutter demo project for aide env testing.
version: 1.0.0
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
EOF
cat > "$BASE_DIR/flutter-demo/lib/main.dart" << 'EOF'
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: const Scaffold(
body: Center(
child: Text('Hello from Flutter demo!'),
),
),
);
}
}
EOF
# 创建 react-demo 项目(简化结构)
mkdir -p "$BASE_DIR/react-demo/src"
cat > "$BASE_DIR/react-demo/package.json" << 'EOF'
{
"name": "react-demo",
"version": "1.0.0",
"description": "A React demo project for aide env testing",
"main": "src/index.js",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"react-scripts": "5.0.1"
}
}
EOF
cat > "$BASE_DIR/react-demo/src/index.js" << 'EOF'
import React from 'react';
import ReactDOM from 'react-dom/client';
function App() {
return <h1>Hello from React demo!</h1>;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
EOF
echo "✓ 测试项目目录结构创建完成"
echo " - $BASE_DIR/rust-demo"
echo " - $BASE_DIR/flutter-demo"
echo " - $BASE_DIR/react-demo"