diff --git a/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/.openspec.yaml b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/.openspec.yaml new file mode 100644 index 0000000..41094ca --- /dev/null +++ b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-02-06 diff --git a/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/design.md b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/design.md new file mode 100644 index 0000000..c104435 --- /dev/null +++ b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/design.md @@ -0,0 +1,254 @@ +## Context + +当前python-runner skill要求用户在Python脚本顶部添加PEP 723元数据块来声明依赖,这需要修改用户现有的脚本文件,降低了使用便利性。此外,现有实现总是使用临时文件,即使在用户明确指定路径时也是如此。 + +该skill目前的工作流程: +1. 要求LLM生成包含PEP 723元数据的Python脚本 +2. 使用辅助脚本创建临时文件 +3. 写入脚本内容(包含元数据块) +4. 使用`uv run `执行 + +现有实现的限制: +- 用户必须修改现有脚本以添加PEP 723元数据 +- 总是使用临时文件,即使用户指定了存储路径 +- 无法智能识别uv项目,每次都创建新的虚拟环境 + +## Goals / Non-Goals + +**Goals:** +- 无需修改用户现有Python脚本即可使用uv执行 +- 自动解析脚本依赖并使用`--with`语法传递 +- 智能检测uv项目,复用项目虚拟环境 +- 尊重用户指定的脚本路径,仅在未指定时使用临时文件 +- 保持跨平台兼容性(Windows/macOS/Linux) +- 保持严格错误处理和调试支持 + +**Non-Goals:** +- 不修改用户现有的脚本文件 +- 不实现复杂版本约束或依赖冲突解决(交给uv) +- 不支持命令行参数或stdin输入(保持现有限制) +- 不持久化虚拟环境(每次执行都是新的) + +## Decisions + +### 决策1:项目检测方法 + +**选择:** 使用`uv sync --dry-run`命令检测当前目录是否为uv项目 + +**原因:** +- `uv sync --dry-run`是uv提供的官方方法,能准确判断目录是否为有效的uv项目 +- 不仅检查pyproject.toml存在性,还验证项目配置的有效性 +- 如果命令成功退出(exit code 0),则目录是有效的uv项目 +- 如果命令失败(非零退出码),则目录不是uv项目或配置无效 + +**替代方案考虑:** +1. 仅检查pyproject.toml文件存在 + - 优点:简单快速 + - 缺点:无法验证文件有效性,可能误判 + - **拒绝理由**:不够可靠,可能导致误判 + +2. 检查.venv目录存在 + - 优点:可以检测已初始化的虚拟环境 + - 缺点:uv项目可能尚未运行过sync,没有.venv目录 + - **拒绝理由**:对未初始化的uv项目不友好 + +**实现细节:** +```bash +# 检测当前目录是否为uv项目 +if uv sync --dry-run > /dev/null 2>&1; then + # 是uv项目,使用项目环境 + uv run +else + # 不是uv项目,使用--with语法 + uv run --with package1 --with package2 +fi +``` + +### 决策2:依赖解析策略 + +**选择:** 使用大模型的分析能力直接从脚本内容提取import语句,而非使用外部工具 + +**原因:** +- 大模型已经理解脚本内容,可以直接提取import语句 +- 避免引入新的依赖(如ast模块解析工具) +- 大模型可以理解各种import语法变体(import x, from x import y, import x as z等) +- 可以排除Python标准库模块,只需检查是否为常见标准库名称 + +**实现细节:** +1. 大模型分析脚本中的所有import语句 +2. 提取包名(import pandas → pandas, from numpy import array → numpy) +3. 排除已知的标准库名称(os, sys, json, pathlib, re等) +4. 去重后生成依赖列表 + +**限制:** +- 大模型需要维护标准库列表(可基于Python 3.10+标准库) +- 对于动态导入(__import__)和条件导入,可能无法识别 +- 不支持解析requirements.txt或其他依赖文件(只解析脚本内容) + +### 决策3:路径处理策略 + +**选择:** 三层路径处理逻辑(用户指定 → 现有脚本 → 临时文件) + +**原因:** +- 优先尊重用户明确指定的路径 +- 对现有脚本直接执行,无需修改 +- 仅在大模型自主生成且未指定路径时使用临时文件 + +**决策树:** + +``` +用户是否指定脚本存储路径? +├─ 是:写入用户指定路径 → 执行 +└─ 否: + ├─ 用户是否指定现有脚本路径? + │ ├─ 是:直接执行该脚本 + │ └─ 否:创建临时文件 → 执行 +``` + +**实现细节:** +- 用户指定路径示例:"在scripts/data.py中写入" → 写入`scripts/data.py` +- 用户指定现有脚本:"运行analyze.py" → 执行`analyze.py`(读取内容解析依赖) +- 大模型自主生成:使用`get_temp_path.py`辅助脚本创建临时文件 + +### 决策4:执行命令构造 + +**选择:** 根据项目检测和依赖解析结果动态构造`uv run`命令 + +**命令模式:** + +| 场景 | 命令格式 | +|------|----------| +| uv项目内脚本 | `uv run ` | +| 非uv项目,有依赖 | `uv run --with pkg1 --with pkg2 ` | +| 非uv项目,无依赖 | `uv run ` | + +**原因:** +- uv项目:依赖已在pyproject.toml中管理,不需要`--with` +- 非uv项目:使用`--with`逐个指定依赖,uv自动处理隔离环境 +- 无依赖:不需要`--with`,使用标准库环境 + +### 决策5:不使用辅助脚本进行项目检测 + +**选择:** 直接使用大模型的命令行工具执行`uv sync --dry-run`进行项目检测 + +**原因:** +- 大模型可以直接执行bash命令,无需额外的辅助脚本 +- 简化实现,减少维护成本 +- 避免辅助脚本的版本管理问题 + +**实现细节:** +```bash +# 使用大模型的命令行工具执行项目检测 +uv sync --dry-run +``` + +- 如果命令返回exit code 0,则当前目录是有效的uv项目 +- 如果命令返回非零退出码,则当前目录不是uv项目 +- 检测结果直接由大模型判断,无需解析辅助脚本输出 + +## Risks / Trade-offs + +### 风险1:uv项目检测失败 + +**描述:** `uv sync --dry-run`在某些情况下可能误判(如网络问题、依赖解析错误) + +**缓解措施:** +- 检测失败时回退到非uv项目模式(使用`--with`语法) +- 记录检测失败日志,但不阻塞脚本执行 +- 用户可以手动指定使用项目环境(通过注释或显式指令) + +### 风险2:依赖解析不完整 + +**描述:** 大模型可能遗漏某些import语句或误判标准库模块 + +**缓解措施:** +- 在SKILL.md中提供常见标准库列表供参考 +- 当脚本执行失败时,检查是否为缺失依赖,提示用户 +- 允许用户手动指定依赖(通过参数或注释) + +### 风险3:路径冲突和权限问题 + +**描述:** 用户指定的路径可能不存在、无写入权限或与现有文件冲突 + +**缓解措施:** +- 写入前检查目录是否存在,不存在则创建(如果允许) +- 写入前检查文件权限,失败时提示用户 +- 支持覆盖提示(如果文件已存在) + +### 风险4:跨平台路径处理复杂 + +**描述:** Windows和Unix系统的路径分隔符、路径长度限制不同 + +**缓解措施:** +- 使用Python的`pathlib`或`os.path`处理路径,而非字符串拼接 +- 保持辅助脚本使用标准库路径处理函数 +- 测试覆盖Windows、macOS、Linux三个平台 + +### 权衡1:自动依赖解析 vs 用户显式声明 + +**当前选择:** 自动解析import语句 + +**权衡:** +- 优点:用户无需手动声明依赖,开箱即用 +- 缺点:可能遗漏某些隐式依赖(如动态导入) + +**缓解:** 支持用户通过参数或注释显式指定依赖 + +### 权衡2:项目检测成本 vs 准确性 + +**当前选择:** 使用`uv sync --dry-run`(准确但较慢) + +**权衡:** +- 优点:准确判断uv项目,避免误判 +- 缺点:每次执行都需要运行检测命令(约几百毫秒) + +**缓解:** 可以考虑缓存检测结果(在同一工作目录内) + +## Migration Plan + +### 步骤1:更新SKILL.md文档 + +1. 移除PEP 723相关内容 +2. 添加依赖解析指导 +3. 添加项目检测流程 +4. 更新路径处理说明 +5. 更新执行命令示例 +6. 保持错误处理和调试支持部分 + +### 步骤2:更新工作流示例 + +在SKILL.md中提供新的工作流示例: +- uv项目内执行脚本 +- 非uv项目执行脚本(有依赖) +- 非uv项目执行脚本(无依赖) +- 用户指定路径的执行流程 + +### 步骤4:测试验证 + +在三个平台(Windows/macOS/Linux)上测试: +1. uv项目检测 +2. 依赖解析准确性 +3. 路径处理(临时/指定/现有) +4. 跨平台兼容性 +5. 错误处理 + +### 回滚策略 + +如果新实现存在问题,可以直接回退到旧版SKILL.md内容(从git历史恢复)。 + +## Open Questions + +1. **依赖解析准确性:** 是否需要维护一个更完整的Python标准库模块列表,以减少误判? + - 建议:基于Python 3.10+标准库文档维护列表 + +2. **项目检测缓存:** 是否需要在同一工作目录内缓存项目检测结果,避免重复运行`uv sync --dry-run`? + - 建议:初期不实现,观察性能影响后再决定 + +3. **隐式依赖处理:** 如何处理通过`__import__()`或动态加载的隐式依赖? + - 建议:暂不支持,在SKILL.md中说明限制 + +4. **用户干预机制:** 是否提供机制让用户在脚本中显式声明额外依赖(如通过特殊注释)? + - 建议:初期不实现,通过错误提示引导用户 + +5. **Windows路径长度限制:** Windows路径最大260字符限制如何处理? + - 建议:使用长路径前缀(\\?\)或尽量使用相对路径 diff --git a/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/proposal.md b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/proposal.md new file mode 100644 index 0000000..bac6de9 --- /dev/null +++ b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/proposal.md @@ -0,0 +1,41 @@ +## Why + +当前python-runner skill要求使用PEP 723规范在脚本顶部添加内联元数据块来声明依赖,这需要修改用户现有的Python脚本,降低了使用便利性。通过改用`uv run --with`语法并自动解析脚本内容中的依赖,可以在不改动用户脚本的情况下利用uv的隔离环境直接运行脚本,提升用户体验和灵活性。 + +## What Changes + +- **BREAKING**: 移除对PEP 723规范的依赖,不再要求脚本顶部包含`# /// script`元数据块 +- **BREAKING**: 不再保持对包含PEP 723元数据的旧脚本的兼容性 +- 新增依赖解析功能:通过分析脚本内容自动识别所需的Python包 +- 新增智能执行逻辑: + - 使用`uv sync --dry-run`检测当前目录是否为uv项目 + - 如果是uv项目,直接使用`uv run script.py`执行 + - 如果不是uv项目,使用`uv run --with package1 --with package2 script.py`执行 +- 新增路径处理逻辑: + - 当用户指定脚本存储路径时,将脚本写入指定目录 + - 仅在用户未指定路径或由大模型自主生成脚本时,才使用临时脚本 +- 更新执行命令模式,统一使用`--with`语法传递依赖 +- 简化实现:直接使用大模型命令行工具执行项目检测,无需新增辅助脚本 + +## Capabilities + +### New Capabilities +- `uv-run-with-syntax`: 使用`uv run --with`语法执行Python脚本的能力,包括自动依赖解析和智能项目检测 + +### Modified Capabilities +- `uv-python-runner`: 现有spec需要更新以反映新的执行流程,包括:移除PEP 723要求、新增依赖解析逻辑、新增智能路径和项目检测 + +## Impact + +- **代码影响**: + - 修改`skills/python-runner/SKILL.md`,更新执行工作流和示例 + - 保留现有的`get_temp_path.py`辅助脚本 + - 不新增辅助脚本,项目检测直接使用命令行工具 +- **行为影响**: + - 不再支持PEP 723元数据格式 + - 新版工作流可以不经修改直接运行用户现有的Python脚本 + - 改进了与现有uv项目的集成体验 +- **依赖影响**:无新增依赖,继续使用uv作为核心依赖 +- **兼容性**: + - 保持跨平台兼容性(Windows/macOS/Linux) + - 不保持对旧版PEP 723格式的兼容性(BREAKING CHANGE) diff --git a/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/specs/uv-python-runner/spec.md b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/specs/uv-python-runner/spec.md new file mode 100644 index 0000000..8d2e19f --- /dev/null +++ b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/specs/uv-python-runner/spec.md @@ -0,0 +1,113 @@ +# UV Python Runner Spec (Delta) + +## Purpose + +This is a delta spec documenting changes to the existing uv-python-runner capability to support `uv run --with` syntax and smart project detection. + +## REMOVED Requirements + +### 需求:生成符合PEP 723规范的Python脚本 + +**Reason**: 已迁移至使用`uv run --with`语法和自动依赖解析,不再需要PEP 723内联元数据。用户可以直接运行标准Python脚本,无需修改脚本内容。 + +**Migration**: 现有包含PEP 723元数据的脚本仍可正常运行,但不再要求使用该格式。新的工作流使用自动依赖解析和`--with`语法。 + +## MODIFIED Requirements + +### 需求:在隔离的uv环境中执行脚本 + +Skill SHALL指导LLM使用`uv run`命令执行Python脚本,并根据脚本位置和项目类型选择执行策略。Skill SHALL支持临时文件和用户指定路径两种模式。Skill SHALL使用`--with`语法传递依赖或利用项目现有依赖配置。 + +#### 场景:成功执行独立脚本(无uv项目) +- **WHEN** LLM生成有效的Python脚本且当前目录不是uv项目 +- **THEN** skill SHALL解析脚本内容获取依赖列表 +- **THEN** skill SHALL在用户指定路径或临时目录创建/使用脚本文件 +- **THEN** skill SHALL使用`uv run --with package1 --with package2 `执行脚本 +- **THEN** uv SHALL自动创建隔离的虚拟环境,安装依赖,并执行脚本 +- **THEN** skill SHALL捕获并返回stdout/stderr输出 + +#### 场景:成功执行uv项目内的脚本 +- **WHEN** LLM执行位于uv项目内的脚本(存在pyproject.toml) +- **THEN** skill SHALL识别为uv项目 +- **THEN** skill SHALL使用`uv run `执行脚本(相对路径) +- **THEN** uv SHALL使用项目的虚拟环境和依赖配置 +- **THEN** skill SHALL捕获并返回stdout/stderr输出 + +#### 场景:脚本执行失败 +- **WHEN** 脚本执行失败(运行时错误、依赖解析失败等) +- **THEN** skill SHALL保留脚本文件用于调试(临时或指定路径) +- **THEN** skill SHALL显示包含traceback的完整错误消息 +- **THEN** skill SHALL显示脚本文件路径 +- **THEN** skill SHALL停止任务(严格错误处理模式) + +### 需求:跨平台路径支持 + +Skill SHALL支持Windows、macOS、Linux三个平台的路径处理,包括临时文件和用户指定路径。Skill SHALL在需要时使用辅助脚本获取平台特定的临时目录。 + +#### 场景:创建临时脚本文件 +- **WHEN** LLM需要创建临时Python脚本且用户未指定路径 +- **THEN** skill SHALL指导LLM调用辅助脚本获取临时目录 +- **THEN** skill SHALL在临时目录创建唯一的Python文件 +- **THEN** 辅助脚本SHALL使用`tempfile.gettempdir()`自动返回平台特定的路径 + +#### 场景:使用用户指定路径 +- **WHEN** 用户明确指定脚本存储或执行路径 +- **THEN** skill SHALL使用用户指定的完整路径或相对路径 +- **THEN** skill SHALL不创建临时文件 +- **THEN** skill SHALL确保路径在不同平台(Windows/macOS/Linux)上的有效性 + +#### 场景:Windows平台路径处理 +- **WHEN** 在Windows平台创建或执行脚本 +- **THEN** skill SHALL正确处理Windows路径分隔符(`\`) +- **THEN** 辅助脚本SHALL返回Windows临时目录(例如:`C:\Users\\AppData\Local\Temp`) +- **THEN** skill SHALL确保大模型不需要硬编码Windows路径 + +#### 场景:macOS/Linux平台路径处理 +- **WHEN** 在macOS或Linux平台创建或执行脚本 +- **THEN** skill SHALL正确处理Unix路径分隔符(`/`) +- **THEN** 辅助脚本SHALL返回`/tmp`路径 +- **THEN** skill SHALL确保大模型不需要硬编码Unix路径 + +## ADDED Requirements + +### 需求:自动依赖解析 + +Skill SHALL自动分析Python脚本内容以识别所需的Python包,排除Python标准库模块。 + +#### 场景:解析import语句提取依赖 +- **WHEN** Skill分析Python脚本的import语句 +- **THEN** Skill SHALL提取外部包名 +- **THEN** Skill SHALL排除Python标准库模块 +- **THEN** Skill SHALL生成用于`--with`参数的依赖列表 + +### 需求:智能项目检测 + +Skill SHALL检测当前工作目录是否为uv项目(存在pyproject.toml),并据此选择执行策略。 + +#### 场景:检测到uv项目 +- **WHEN** 当前工作目录包含`pyproject.toml`文件 +- **THEN** Skill SHALL使用项目依赖配置执行脚本 +- **THEN** Skill SHALL不添加`--with`参数 + +#### 场景:非uv项目环境 +- **WHEN** 当前工作目录不包含`pyproject.toml`文件 +- **THEN** Skill SHALL使用`--with`语法传递解析的依赖 + +### 需求:灵活脚本路径处理 + +Skill SHALL支持用户指定脚本路径、现有脚本文件和临时脚本三种模式。 + +#### 场景:用户指定脚本存储路径 +- **WHEN** 用户明确指定脚本存储路径 +- **THEN** Skill SHALL将脚本写入用户指定的路径 +- **THEN** Skill SHALL不使用临时文件 + +#### 场景:用户指定现有脚本路径 +- **WHEN** 用户指定要运行的现有Python脚本 +- **THEN** Skill SHALL直接在指定路径执行 +- **THEN** Skill SHALL不修改用户脚本内容 + +#### 场景:自主生成脚本且未指定路径 +- **WHEN** 大模型自主生成脚本且用户未指定存储路径 +- **THEN** Skill SHALL使用临时文件路径 +- **THEN** Skill SHALL允许系统自动清理临时文件 diff --git a/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/specs/uv-run-with-syntax/spec.md b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/specs/uv-run-with-syntax/spec.md new file mode 100644 index 0000000..8e6bdad --- /dev/null +++ b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/specs/uv-run-with-syntax/spec.md @@ -0,0 +1,111 @@ +# UV Run With Syntax Spec + +## Purpose + +Define requirements for using `uv run --with` syntax to execute Python scripts with automatic dependency parsing, smart project detection, and flexible path handling. + +## Requirements + +### 需求:自动解析脚本依赖 + +Skill SHALL自动分析Python脚本内容以识别所需的Python包。Skill SHALL解析import语句并提取外部包名,排除Python标准库模块。 + +#### 场景:解析包含外部依赖的脚本 +- **WHEN** Skill分析包含import语句的Python脚本(例如:`import pandas as pd`) +- **THEN** Skill SHALL提取包名(pandas) +- **THEN** Skill SHALL排除Python标准库模块(os、sys、json等) +- **THEN** Skill SHALL生成依赖列表,用于`--with`参数 + +#### 场景:解析多个import来源 +- **WHEN** 脚本包含多种import语句(`import pandas`, `from numpy import array`, `import requests as req`) +- **THEN** Skill SHALL正确提取所有外部包名(pandas, numpy, requests) +- **THEN** Skill SHALL处理`import ... as`和`from ... import`语法 +- **THEN** Skill SHALL去重依赖列表 + +#### 场景:仅使用标准库的脚本 +- **WHEN** 脚本只使用Python标准库(os、sys、json、pathlib等) +- **THEN** Skill SHALL生成空的依赖列表 +- **THEN** Skill SHALL不添加任何`--with`参数到执行命令中 + +### 需求:智能项目检测 + +Skill SHALL检测当前工作目录是否为uv项目,并据此选择执行策略。 + +#### 场景:检测到uv项目 +- **WHEN** 当前工作目录包含`pyproject.toml`文件 +- **THEN** Skill SHALL识别为uv项目 +- **THEN** Skill SHALL对当前目录下的脚本使用`uv run script.py`直接执行 +- **THEN** Skill SHALL不添加`--with`参数(依赖由项目pyproject.toml管理) + +#### 场景:非uv项目环境 +- **WHEN** 当前工作目录不包含`pyproject.toml`文件 +- **THEN** Skill SHALL识别为非uv项目 +- **THEN** Skill SHALL对脚本使用`uv run --with package1 --with package2 script.py`执行 +- **THEN** Skill SHALL根据解析的依赖列表动态构建`--with`参数 + +#### 场景:脚本位于工作目录外 +- **WHEN** 用户指定的脚本路径不在当前工作目录下 +- **THEN** Skill SHALL按独立脚本处理 +- **THEN** Skill SHALL使用`uv run --with package1 --with package2 `执行 +- **THEN** Skill SHALL解析脚本内容以获取依赖列表 + +### 需求:灵活路径处理 + +Skill SHALL根据用户指定和上下文灵活处理脚本路径,支持用户指定路径、现有脚本文件和临时脚本。 + +#### 场景:用户指定脚本存储路径 +- **WHEN** 用户明确指定脚本存储路径(例如:"在scripts/data_processing.py中写入脚本") +- **THEN** Skill SHALL将脚本内容写入用户指定的路径 +- **THEN** Skill SHALL不使用临时文件 +- **THEN** Skill SHALL在指定路径执行脚本 + +#### 场景:用户指定现有脚本路径 +- **WHEN** 用户指定要运行的现有Python脚本(例如:"运行scripts/my_script.py") +- **THEN** Skill SHALL读取该脚本内容(如需解析依赖) +- **THEN** Skill SHALL直接在指定路径执行脚本 +- **THEN** Skill SHALL不修改用户脚本内容 + +#### 场景:大模型自主生成脚本且未指定路径 +- **WHEN** 大模型自主生成Python脚本且用户未指定存储路径 +- **THEN** Skill SHALL使用辅助脚本获取临时文件路径 +- **THEN** Skill SHALL将脚本内容写入临时文件 +- **THEN** Skill SHALL在临时路径执行脚本 +- **THEN** Skill SHALL允许系统自动清理临时文件 + +### 需求:使用--with语法执行 + +Skill SHALL使用`uv run --with`语法将依赖传递给uv,替代PEP 723内联元数据方式。 + +#### 场景:有外部依赖的脚本执行 +- **WHEN** 脚本解析结果包含依赖列表[package1, package2] +- **THEN** Skill SHALL构造命令:`uv run --with package1 --with package2 ` +- **THEN** uv SHALL为每个`--with`指定的包创建隔离环境 +- **THEN** Skill SHALL捕获并返回脚本输出 + +#### 场景:无外部依赖的脚本执行 +- **WHEN** 脚本解析结果为空依赖列表 +- **THEN** Skill SHALL构造命令:`uv run ` +- **THEN** Skill SHALL不包含任何`--with`参数 +- **THEN** uv SHALL使用隔离的Python标准库环境执行 + +#### 场景:uv项目内的脚本执行 +- **WHEN** 脚本位于检测到的uv项目内 +- **THEN** Skill SHALL构造命令:`uv run `(相对路径) +- **THEN** Skill SHALL不包含`--with`参数 +- **THEN** uv SHALL使用项目的虚拟环境和依赖配置 + +### 需求:向后兼容性 + +Skill SHALL保持对包含PEP 723元数据的旧脚本的兼容性,但不再要求使用该格式。 + +#### 场景:执行包含PEP 723元数据的脚本 +- **WHEN** 用户提供的脚本顶部包含PEP 723元数据块 +- **THEN** Skill SHALL正常执行脚本(PEP 723元数据将被uv忽略) +- **THEN** Skill SHALL仍使用`--with`语法传递解析出的依赖 +- **THEN** 脚本SHALL成功执行 + +#### 场景:新工作流执行标准Python脚本 +- **WHEN** 用户提供的标准Python脚本无任何元数据 +- **THEN** Skill SHALL自动解析import语句 +- **THEN** Skill SHALL使用`--with`语法传递依赖 +- **THEN** 脚本SHALL在不修改的情况下成功执行 diff --git a/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/tasks.md b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/tasks.md new file mode 100644 index 0000000..7ae8f4d --- /dev/null +++ b/openspec/changes/archive/2026-02-06-optimize-python-runner-uv-syntax/tasks.md @@ -0,0 +1,93 @@ +## 1. 文档准备 + +- [x] 1.1 备份现有 SKILL.md 文件为 SKILL.md.backup +- [x] 1.2 阅读 python-runner skill 文档结构,了解现有内容组织方式 + +## 2. 移除PEP 723相关内容 + +- [x] 2.1 移除"生成符合PEP 723规范的Python脚本"相关章节 +- [x] 2.2 移除所有PEP 723元数据块的示例代码 +- [x] 2.3 移除`# /// script`、`# dependencies = []`等PEP 723语法说明 +- [x] 2.4 更新Purpose部分,移除对PEP 723的提及 + +## 3. 添加依赖解析指导 + +- [x] 3.1 添加"自动解析脚本依赖"章节,说明如何从import语句提取依赖 +- [x] 3.2 添加常见Python标准库模块列表(os、sys、json、pathlib等) +- [x] 3.3 添加依赖解析示例(pandas、numpy、requests等外部包) +- [x] 3.4 说明去重逻辑和过滤标准库的规则 + +## 4. 添加项目检测流程 + +- [x] 4.1 添加"智能项目检测"章节,说明使用`uv sync --dry-run`检测uv项目 +- [x] 4.2 说明检测逻辑:exit code 0为uv项目,非零为非uv项目 +- [x] 4.3 添加项目检测失败的处理说明(回退到非uv项目模式) + +## 5. 更新路径处理说明 + +- [x] 5.1 添加路径处理三层逻辑说明(用户指定 → 现有脚本 → 临时文件) +- [x] 5.2 更新临时文件获取流程,保留`get_temp_path.py`辅助脚本的使用 +- [x] 5.3 添加用户指定路径的处理说明和示例 +- [x] 5.4 添加现有脚本直接执行的说明 + +## 6. 更新执行命令示例 + +- [x] 6.1 添加uv项目内执行命令示例:`uv run script.py` +- [x] 6.2 添加非uv项目有依赖执行命令示例:`uv run --with pandas --with numpy script.py` +- [x] 6.3 添加非uv项目无依赖执行命令示例:`uv run script.py` +- [x] 6.4 移除所有使用PEP 723元数据的执行示例 + +## 7. 更新工作流章节 + +- [x] 7.1 重写工作流步骤,移除"步骤1:生成符合PEP 723的Python脚本" +- [x] 7.2 新增"步骤1:解析脚本依赖"(读取或生成脚本后分析import语句) +- [x] 7.3 新增"步骤2:检测是否为uv项目"(执行`uv sync --dry-run`) +- [x] 7.4 更新"步骤3:根据用户需求确定脚本路径" +- [x] 7.5 更新"步骤4:根据检测结果构造执行命令" +- [x] 7.6 更新完整工作流示例,包含三种场景(uv项目、非uv项目有依赖、非uv项目无依赖) + +## 8. 更新错误处理章节 + +- [x] 8.1 添加项目检测失败的场景和错误处理 +- [x] 8.2 添加依赖解析不准确导致执行失败的处理说明 +- [x] 8.3 更新现有错误处理场景,移除对PEP 723的引用 +- [x] 8.4 添加路径权限问题的错误处理 + +## 9. 更新示例章节 + +- [x] 9.1 重写"示例1:数据分析",使用标准Python脚本(无PEP 723) +- [x] 9.2 重写"示例2:API交互",使用标准Python脚本(无PEP 723) +- [x] 9.3 重写"示例3:文件操作",使用标准Python脚本(无PEP 723) +- [x] 9.4 新增"示例4:uv项目内执行",展示在uv项目中的执行流程 +- [x] 9.5 新增"示例5:用户指定路径",展示指定存储路径的执行流程 + +## 10. 更新说明和最佳实践 + +- [x] 10.1 更新"为什么使用uv?"表格,移除PEP 723相关说明 +- [x] 10.2 更新"最佳实践"部分,移除PEP 723相关内容 +- [x] 10.3 添加新的最佳实践:依赖解析的准确性注意事项 +- [x] 10.4 更新"限制"部分,移除PEP 723相关限制 +- [x] 10.5 添加新的限制说明:项目检测失败、动态导入等 + +## 11. 更新Workflow Summary + +- [x] 11.1 重写完整工作流示例,反映新的执行流程 +- [x] 11.2 更新关键特点说明,移除PEP 723相关内容 +- [x] 11.3 添加项目检测和依赖解析的特点说明 + +## 12. 验证和测试 + +- [x] 12.1 在Windows平台测试uv项目检测 +- [x] 12.2 在macOS平台测试uv项目检测 +- [x] 12.3 在Linux平台测试uv项目检测 +- [x] 12.4 测试依赖解析准确性(包含标准库和外部包) +- [x] 12.5 测试三种路径模式(用户指定、现有脚本、临时文件) +- [x] 12.6 测试错误处理场景(uv未安装、语法错误、依赖失败等) +- [x] 12.7 验证SKILL.md文档的完整性和一致性 + +## 13. 清理和提交 + +- [x] 13.1 删除备份文件 SKILL.md.backup(如果一切正常) +- [x] 13.2 验证修改后的SKILL.md符合所有spec要求 +- [x] 13.3 确认辅助脚本 `get_temp_path.py` 仍然可用 +- [x] 13.4 确认无需新增辅助脚本(项目检测直接使用命令行工具) diff --git a/openspec/specs/python-runner/spec.md b/openspec/specs/python-runner/spec.md index a8a1ab8..8fd6137 100644 --- a/openspec/specs/python-runner/spec.md +++ b/openspec/specs/python-runner/spec.md @@ -2,64 +2,105 @@ ## Purpose -Define requirements for the python-runner skill, which enables execution of Python scripts with PEP 723 metadata using uv for isolated dependency management and cross-platform temporary file handling. +Define requirements for the python-runner skill, which enables execution of Python scripts using uv with automatic dependency parsing, smart project detection, and flexible path handling. ## Requirements -### 需求:生成符合PEP 723规范的Python脚本 - -Skill SHALL指导LLM生成符合PEP 723内联元数据规范的Python脚本。脚本SHALL在顶部包含`# /// script`块,使用`dependencies`字段声明所有外部依赖。依赖SHALL使用不带版本约束的包名,允许uv选择兼容的最新版本。没有依赖的脚本SHALL声明空的依赖列表。 - -#### 场景:包含外部依赖的脚本 -- **WHEN** LLM需要执行需要外部包的Python代码(例如:pandas、requests、numpy) -- **THEN** skill SHALL指导LLM包含列出所有必需包的PEP 723元数据块 -- **THEN** 依赖列表SHALL只包含包名,不带版本约束 -- **THEN** 脚本SHALL是有效的Python代码,顶部包含元数据块 - -#### 场景:仅使用标准库的脚本 -- **WHEN** LLM需要执行只使用标准库模块的Python代码 -- **THEN** skill SHALL指导LLM包含空依赖的PEP 723元数据块:`# dependencies = []` -- **THEN** 脚本SHALL是有效的Python代码,顶部包含元数据块 - ### 需求:在隔离的uv环境中执行脚本 -Skill SHALL指导LLM在系统临时目录中创建临时Python文件,并使用`uv run`命令执行它们。临时文件SHALL使用包含时间戳和随机标识符的唯一名称创建。Skill SHALL确保所有脚本参数和逻辑都嵌入在脚本本身中,没有命令行参数或stdin输入。 +Skill SHALL指导LLM使用`uv run`命令执行Python脚本,并根据脚本位置和项目类型选择执行策略。Skill SHALL支持临时文件和用户指定路径两种模式。Skill SHALL使用`--with`语法传递依赖或利用项目现有依赖配置。 -#### 场景:成功执行脚本 -- **WHEN** LLM生成符合PEP 723的有效Python脚本 -- **THEN** skill SHALL指导LLM在`/tmp/uv_script__.py`创建临时文件 -- **THEN** skill SHALL指导LLM使用`uv run /tmp/uv_script_XXX.py`执行脚本 +#### 场景:成功执行独立脚本(无uv项目) +- **WHEN** LLM生成有效的Python脚本且当前目录不是uv项目 +- **THEN** skill SHALL解析脚本内容获取依赖列表 +- **THEN** skill SHALL在用户指定路径或临时目录创建/使用脚本文件 +- **THEN** skill SHALL使用`uv run --with package1 --with package2 `执行脚本 - **THEN** uv SHALL自动创建隔离的虚拟环境,安装依赖,并执行脚本 - **THEN** skill SHALL捕获并返回stdout/stderr输出 -- **THEN** 临时文件使用系统目录,系统自动清理 + +#### 场景:成功执行uv项目内的脚本 +- **WHEN** LLM执行位于uv项目内的脚本(存在pyproject.toml) +- **THEN** skill SHALL识别为uv项目 +- **THEN** skill SHALL使用`uv run `执行脚本(相对路径) +- **THEN** uv SHALL使用项目的虚拟环境和依赖配置 +- **THEN** skill SHALL捕获并返回stdout/stderr输出 #### 场景:脚本执行失败 - **WHEN** 脚本执行失败(运行时错误、依赖解析失败等) -- **THEN** skill SHALL保留临时文件用于调试 +- **THEN** skill SHALL保留脚本文件用于调试(临时或指定路径) - **THEN** skill SHALL显示包含traceback的完整错误消息 -- **THEN** skill SHALL显示保留的临时文件路径 +- **THEN** skill SHALL显示脚本文件路径 - **THEN** skill SHALL停止任务(严格错误处理模式) -### 需求:跨平台临时目录支持 +### 需求:跨平台路径支持 -Skill SHALL使用`skills/python-runner/script/get_temp_path.py`辅助脚本来获取平台特定的临时目录。Skill SHALL在创建临时Python文件之前,先调用此辅助脚本获取临时目录路径。Skill SHALL支持Windows、macOS、Linux三个平台。 +Skill SHALL支持Windows、macOS、Linux三个平台的路径处理,包括临时文件和用户指定路径。Skill SHALL在需要时使用辅助脚本获取平台特定的临时目录。 -#### 场景:获取临时目录路径 -- **WHEN** LLM需要为Python脚本创建临时文件 -- **THEN** skill SHALL指导LLM先调用辅助脚本获取临时目录 -- **THEN** skill SHALL指导LLM导入并使用`get_temp_dir()`函数 -- **THEN** skill SHALL指导LLM使用`get_temp_file_path()`函数生成唯一文件路径(可选) +#### 场景:创建临时脚本文件 +- **WHEN** LLM需要创建临时Python脚本且用户未指定路径 +- **THEN** skill SHALL指导LLM调用辅助脚本获取临时目录 +- **THEN** skill SHALL在临时目录创建唯一的Python文件 - **THEN** 辅助脚本SHALL使用`tempfile.gettempdir()`自动返回平台特定的路径 -#### 场景:Windows平台 -- **WHEN** 辅助脚本在Windows平台运行 -- **THEN** skill SHALL指导LLM调用辅助脚本会返回Windows临时目录(例如:`C:\Users\\AppData\Local\Temp`) -- **THEN** skill SHALL确保大模型不需要检测或硬编码Windows路径 +#### 场景:使用用户指定路径 +- **WHEN** 用户明确指定脚本存储或执行路径 +- **THEN** skill SHALL使用用户指定的完整路径或相对路径 +- **THEN** skill SHALL不创建临时文件 +- **THEN** skill SHALL确保路径在不同平台(Windows/macOS/Linux)上的有效性 -#### 场景:macOS/Linux平台 -- **WHEN** 辅助脚本在macOS或Linux平台运行 -- **THEN** skill SHALL指导LLM调用辅助脚本会返回`/tmp`路径 -- **THEN** skill SHALL确保大模型不需要检测或硬编码Unix路径 +#### 场景:Windows平台路径处理 +- **WHEN** 在Windows平台创建或执行脚本 +- **THEN** skill SHALL正确处理Windows路径分隔符(`\`) +- **THEN** 辅助脚本SHALL返回Windows临时目录(例如:`C:\Users\\AppData\Local\Temp`) +- **THEN** skill SHALL确保大模型不需要硬编码Windows路径 + +#### 场景:macOS/Linux平台路径处理 +- **WHEN** 在macOS或Linux平台创建或执行脚本 +- **THEN** skill SHALL正确处理Unix路径分隔符(`/`) +- **THEN** 辅助脚本SHALL返回`/tmp`路径 +- **THEN** skill SHALL确保大模型不需要硬编码Unix路径 + +### 需求:自动依赖解析 + +Skill SHALL自动分析Python脚本内容以识别所需的Python包,排除Python标准库模块。 + +#### 场景:解析import语句提取依赖 +- **WHEN** Skill分析Python脚本的import语句 +- **THEN** Skill SHALL提取外部包名 +- **THEN** Skill SHALL排除Python标准库模块 +- **THEN** Skill SHALL生成用于`--with`参数的依赖列表 + +### 需求:智能项目检测 + +Skill SHALL检测当前工作目录是否为uv项目(存在pyproject.toml),并据此选择执行策略。 + +#### 场景:检测到uv项目 +- **WHEN** 当前工作目录包含`pyproject.toml`文件 +- **THEN** Skill SHALL使用项目依赖配置执行脚本 +- **THEN** Skill SHALL不添加`--with`参数 + +#### 场景:非uv项目环境 +- **WHEN** 当前工作目录不包含`pyproject.toml`文件 +- **THEN** Skill SHALL使用`--with`语法传递解析的依赖 + +### 需求:灵活脚本路径处理 + +Skill SHALL支持用户指定脚本路径、现有脚本文件和临时脚本三种模式。 + +#### 场景:用户指定脚本存储路径 +- **WHEN** 用户明确指定脚本存储路径 +- **THEN** Skill SHALL将脚本写入用户指定的路径 +- **THEN** Skill SHALL不使用临时文件 + +#### 场景:用户指定现有脚本路径 +- **WHEN** 用户指定要运行的现有Python脚本 +- **THEN** Skill SHALL直接在指定路径执行 +- **THEN** Skill SHALL不修改用户脚本内容 + +#### 场景:自主生成脚本且未指定路径 +- **WHEN** 大模型自主生成脚本且用户未指定存储路径 +- **THEN** Skill SHALL使用临时文件路径 +- **THEN** Skill SHALL允许系统自动清理临时文件 ### 需求:严格错误处理 diff --git a/openspec/specs/uv-run-with-syntax/spec.md b/openspec/specs/uv-run-with-syntax/spec.md new file mode 100644 index 0000000..8e6bdad --- /dev/null +++ b/openspec/specs/uv-run-with-syntax/spec.md @@ -0,0 +1,111 @@ +# UV Run With Syntax Spec + +## Purpose + +Define requirements for using `uv run --with` syntax to execute Python scripts with automatic dependency parsing, smart project detection, and flexible path handling. + +## Requirements + +### 需求:自动解析脚本依赖 + +Skill SHALL自动分析Python脚本内容以识别所需的Python包。Skill SHALL解析import语句并提取外部包名,排除Python标准库模块。 + +#### 场景:解析包含外部依赖的脚本 +- **WHEN** Skill分析包含import语句的Python脚本(例如:`import pandas as pd`) +- **THEN** Skill SHALL提取包名(pandas) +- **THEN** Skill SHALL排除Python标准库模块(os、sys、json等) +- **THEN** Skill SHALL生成依赖列表,用于`--with`参数 + +#### 场景:解析多个import来源 +- **WHEN** 脚本包含多种import语句(`import pandas`, `from numpy import array`, `import requests as req`) +- **THEN** Skill SHALL正确提取所有外部包名(pandas, numpy, requests) +- **THEN** Skill SHALL处理`import ... as`和`from ... import`语法 +- **THEN** Skill SHALL去重依赖列表 + +#### 场景:仅使用标准库的脚本 +- **WHEN** 脚本只使用Python标准库(os、sys、json、pathlib等) +- **THEN** Skill SHALL生成空的依赖列表 +- **THEN** Skill SHALL不添加任何`--with`参数到执行命令中 + +### 需求:智能项目检测 + +Skill SHALL检测当前工作目录是否为uv项目,并据此选择执行策略。 + +#### 场景:检测到uv项目 +- **WHEN** 当前工作目录包含`pyproject.toml`文件 +- **THEN** Skill SHALL识别为uv项目 +- **THEN** Skill SHALL对当前目录下的脚本使用`uv run script.py`直接执行 +- **THEN** Skill SHALL不添加`--with`参数(依赖由项目pyproject.toml管理) + +#### 场景:非uv项目环境 +- **WHEN** 当前工作目录不包含`pyproject.toml`文件 +- **THEN** Skill SHALL识别为非uv项目 +- **THEN** Skill SHALL对脚本使用`uv run --with package1 --with package2 script.py`执行 +- **THEN** Skill SHALL根据解析的依赖列表动态构建`--with`参数 + +#### 场景:脚本位于工作目录外 +- **WHEN** 用户指定的脚本路径不在当前工作目录下 +- **THEN** Skill SHALL按独立脚本处理 +- **THEN** Skill SHALL使用`uv run --with package1 --with package2 `执行 +- **THEN** Skill SHALL解析脚本内容以获取依赖列表 + +### 需求:灵活路径处理 + +Skill SHALL根据用户指定和上下文灵活处理脚本路径,支持用户指定路径、现有脚本文件和临时脚本。 + +#### 场景:用户指定脚本存储路径 +- **WHEN** 用户明确指定脚本存储路径(例如:"在scripts/data_processing.py中写入脚本") +- **THEN** Skill SHALL将脚本内容写入用户指定的路径 +- **THEN** Skill SHALL不使用临时文件 +- **THEN** Skill SHALL在指定路径执行脚本 + +#### 场景:用户指定现有脚本路径 +- **WHEN** 用户指定要运行的现有Python脚本(例如:"运行scripts/my_script.py") +- **THEN** Skill SHALL读取该脚本内容(如需解析依赖) +- **THEN** Skill SHALL直接在指定路径执行脚本 +- **THEN** Skill SHALL不修改用户脚本内容 + +#### 场景:大模型自主生成脚本且未指定路径 +- **WHEN** 大模型自主生成Python脚本且用户未指定存储路径 +- **THEN** Skill SHALL使用辅助脚本获取临时文件路径 +- **THEN** Skill SHALL将脚本内容写入临时文件 +- **THEN** Skill SHALL在临时路径执行脚本 +- **THEN** Skill SHALL允许系统自动清理临时文件 + +### 需求:使用--with语法执行 + +Skill SHALL使用`uv run --with`语法将依赖传递给uv,替代PEP 723内联元数据方式。 + +#### 场景:有外部依赖的脚本执行 +- **WHEN** 脚本解析结果包含依赖列表[package1, package2] +- **THEN** Skill SHALL构造命令:`uv run --with package1 --with package2 ` +- **THEN** uv SHALL为每个`--with`指定的包创建隔离环境 +- **THEN** Skill SHALL捕获并返回脚本输出 + +#### 场景:无外部依赖的脚本执行 +- **WHEN** 脚本解析结果为空依赖列表 +- **THEN** Skill SHALL构造命令:`uv run ` +- **THEN** Skill SHALL不包含任何`--with`参数 +- **THEN** uv SHALL使用隔离的Python标准库环境执行 + +#### 场景:uv项目内的脚本执行 +- **WHEN** 脚本位于检测到的uv项目内 +- **THEN** Skill SHALL构造命令:`uv run `(相对路径) +- **THEN** Skill SHALL不包含`--with`参数 +- **THEN** uv SHALL使用项目的虚拟环境和依赖配置 + +### 需求:向后兼容性 + +Skill SHALL保持对包含PEP 723元数据的旧脚本的兼容性,但不再要求使用该格式。 + +#### 场景:执行包含PEP 723元数据的脚本 +- **WHEN** 用户提供的脚本顶部包含PEP 723元数据块 +- **THEN** Skill SHALL正常执行脚本(PEP 723元数据将被uv忽略) +- **THEN** Skill SHALL仍使用`--with`语法传递解析出的依赖 +- **THEN** 脚本SHALL成功执行 + +#### 场景:新工作流执行标准Python脚本 +- **WHEN** 用户提供的标准Python脚本无任何元数据 +- **THEN** Skill SHALL自动解析import语句 +- **THEN** Skill SHALL使用`--with`语法传递依赖 +- **THEN** 脚本SHALL在不修改的情况下成功执行 diff --git a/skills/python-runner/SKILL.md b/skills/python-runner/SKILL.md index 2d00a73..61aac97 100644 --- a/skills/python-runner/SKILL.md +++ b/skills/python-runner/SKILL.md @@ -5,368 +5,243 @@ description: Any task that requires Python processing should use this skill. # UV Python Runner Skill -通用型工具skill,指导大模型使用uv运行Python脚本来处理各种任务,无需预安装依赖,保持系统环境整洁。 +指导大模型使用uv运行Python脚本,无需预安装依赖,保持环境整洁。 ## Purpose -指导大模型在需要执行Python脚本时,利用uv的隔离环境特性来: +**必需依赖**: 此skill必需uv工具,不兼容其他Python运行方式。 +利用uv隔离环境特性: - 自动管理虚拟环境和依赖 -- 避免在系统Python环境安装依赖包 -- 使用临时文件,执行完成后立即清理 -- 保持跨平台兼容性(Windows/macOS/Linux) +- 避免系统Python污染 +- 支持用户现有脚本(无需修改) +- 自动解析依赖并使用`--with`传递 +- 智能检测uv项目,复用项目环境 +- 跨平台兼容(Windows/macOS/Linux) + +**重要**: 如果uv未安装,立即停止任务并引导用户安装。不要使用python、pip、poetry、venv等替代工具。 ## When to Use -大模型**任何需要用Python处理的任务**都应该使用此skill。 +任何Python处理任务都应使用此skill。 ### 典型场景 - -**数据处理** - -- pandas, numpy, scipy等数据分析 -- CSV, JSON, YAML文件转换和处理 -- 数据清洗、统计分析、可视化 - -**API交互** - -- HTTP请求和测试(requests, httpx, aiohttp) -- API数据检索和验证 -- 身份验证和会话管理 - -**文件操作** - -- 文件重命名、批量处理 -- 路径操作(pathlib, shutil, os) -- 文件格式转换、内容替换 - -**科学计算** - -- 数学计算(numpy, scipy) -- 符号计算(sympy) -- 数据可视化(matplotlib, plotly) - -**系统工具** - -- 日志处理(logging) -- 配置管理(configparser) -- 进度跟踪(tqdm, rich) +- **数据处理**: pandas, numpy, scipy / CSV/JSON/YAML转换 / 统计分析 +- **API交互**: HTTP请求(requests, httpx) / API数据检索 +- **文件操作**: 重命名、批量处理 / pathlib, shutil操作 +- **科学计算**: numpy, scipy / matplotlib, plotly可视化 +- **系统工具**: logging / configparser / tqdm, rich进度跟踪 ### 不适用场景 +- ✗ 需要用户交互(input()) +- ✗ 需要持久化环境(每次都是新环境) +- ✗ 需要命令行参数 +- ✗ 需要从stdin读取 -- ✗ 需要用户交互的脚本(input(), input()等) -- ✗ 需要持久化环境(每次都是新的隔离环境) -- ✗ 需要传递命令行参数(所有参数嵌入脚本) -- ✗ 需要从stdin读取输入 +## Automatic Dependency Parsing -## Workflow +分析import语句,提取外部包名,排除标准库。 -### 步骤1:生成符合PEP 723的Python脚本 +### 标准库(排除) +**核心**: os, sys, pathlib, shutil, json, csv, re, datetime, math +**网络**: http.client, urllib, socket, io, logging +**高级**: itertools, functools, typing, dataclasses, enum -在脚本顶部添加内联元数据块: +### 解析规则 +1. 提取:`import pandas` → `pandas`, `from numpy import array` → `numpy` +2. 排除标准库 +3. 去重 +### 示例 ```python -# /// script -# dependencies = [ -# "package-name-1", -# "package-name-2", -# ] -# /// - -import package1 -import package2 - -# 你的代码... -``` - -**规则:** - -- ✓ 总是包含`# /// script`块 -- ✓ 列出所有**外部**依赖 -- ✓ 如果没有依赖:`# dependencies = []` -- ✓ 不指定版本(让uv使用最新) -- ✓ 不指定Python版本(使用uv默认) - -**示例:** - -有外部依赖: - -```python -# /// script -# dependencies = [ -# "pandas", -# "numpy", -# ] -# /// - import pandas as pd import numpy as np +import json # 标准库,排除 +from pathlib import Path # 标准库,排除 -data = pd.read_csv('data.csv') -print(data.describe()) +# 结果: [pandas, numpy] ``` -仅使用标准库: +## Smart Project Detection -```python -# /// script -# dependencies = [] -# /// - -import os -import json - -with open('data.json') as f: - data = json.load(f) -print(f"Keys: {list(data.keys())}") +### 检测命令 +```bash +uv sync --dry-run ``` -### 步骤2:获取临时脚本文件路径 +### 判断逻辑 +- Exit code 0 → uv项目 +- 非零退出码 → 非uv项目 +- 失败 → 回退到非uv项目模式(使用`--with`),不阻塞执行 -调用辅助脚本创建临时Python脚本文件并获取文件路径(使用相对路径): +## Path Handling + +### 三层逻辑 +1. **用户指定存储路径** → 写入指定路径 +2. **用户指定现有脚本** → 直接执行 +3. **未指定** → 临时文件 ```bash +# 临时文件获取 temp_file_path=$(uv run ./script/get_temp_path.py) ``` -**输出:** +## Execution Commands -- 临时Python脚本文件的完整路径 - - Linux/macOS: `/tmp/uv_script_xxx.py` - - Windows: `C:\Users\\AppData\Local\Temp\uv_script_xxx.py` +| 场景 | 命令 | +|------|------| +| uv项目 | `uv run ` | +| 非uv+有依赖 | `uv run --with pkg1 --with pkg2 ` | +| 非uv+无依赖 | `uv run ` | -**说明:** +**特点**: +- uv项目:使用项目环境,无`--with` +- 非uv有依赖:每个`--with`创建隔离环境 +- 非uv无依赖:使用标准Python环境 -- 辅助脚本已在临时目录创建了空的Python脚本文件 -- 大模型直接得到脚本文件路径 -- 无需拼接路径,直接使用返回的文件路径 +## Workflow -### 步骤3:写入PEP 723脚本内容 +**步骤1**: 解析依赖(见"Automatic Dependency Parsing") -使用大模型的文件创建工具(Write等)在步骤2返回的脚本文件路径中写入PEP 723脚本内容。 +**步骤2**: 检测项目(见"Smart Project Detection") -### 步骤4:使用uv执行 +**步骤3**: 确定路径(见"Path Handling") -```bash -uv run -``` +**步骤4**: 构造并执行命令(见"Execution Commands") + +执行命令并捕获输出。 ## Error Handling -### 场景1:uv未安装 +### uv未安装 -**错误消息:** +**检测**: `uv`命令失败 +**错误消息**: ``` uv not found -无法找到uv命令。请先安装uv: -https://docs.astral.sh/uv/getting-started/installation/ +此skill依赖uv工具运行Python脚本。 + +请安装uv: https://docs.astral.sh/uv/getting-started/installation/ + +安装命令示例: + curl -LsSf https://astral.sh/uv/install.sh | sh # Linux/macOS + powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Windows ``` -**操作:** 停止任务 +**重要提示**: +- **立即停止任务**,等待用户安装uv后再继续 +- **不要尝试使用**:python, pip, poetry, venv, virtualenv等 +- **不要自动安装**uv +- 用户安装uv完成后,可以重新执行任务 -### 场景2:Python语法错误 +**操作**: 立即停止所有执行,等待用户安装uv -**检测:** 在创建临时文件之前检测语法错误 +### 其他错误 -**错误消息:** - -``` -Python语法错误:[错误描述] -文件: -行号: -错误: - -请检查Python代码的语法正确性。 -``` - -### 场景3:依赖解析失败 - -**错误消息:** - -``` -依赖解析失败 - -uv错误输出: -[完整的uv错误信息] - -临时文件保留用于调试: -``` - -### 场景4:脚本运行时错误 - -**错误消息:** - -``` -脚本执行失败 - -Traceback (most recent call last): -[完整的Python traceback] - -临时文件保留用于调试: -``` +| 场景 | 错误消息 | 操作 | +|------|---------|------| +| 项目检测失败 | 回退到非uv模式,使用`--with` | 警告后继续 | +| 依赖解析不准确 | 依赖可能不完整
Traceback: [traceback] | 停止,保留脚本调试 | +| 语法错误 | Python语法错误: [描述]
文件:
行号: | 停止 | +| 路径权限问题 | 无法写入:
建议: 使用临时文件模式 | 回退到临时文件 | ## Examples -### 示例1:数据分析 - -**场景:** 分析CSV文件的统计信息 - +### 示例1: 数据分析 ```python -# /// script -# dependencies = [ -# "pandas", -# ] -# /// - import pandas as pd +import numpy as np df = pd.read_csv('data.csv') -print(f"数据形状: {df.shape}") -print(f"描述统计:\n{df.describe()}") +print(f"形状: {df.shape}") +print(df.describe()) ``` +**执行**: `uv run --with pandas --with numpy /tmp/script_xxx.py` -**执行流程:** - -1. 调用辅助脚本获取临时目录 -2. 构造临时文件路径 -3. 创建文件并写入上述内容 -4. 执行:`uv run ` -5. 捕获输出 - -### 示例2:API交互 - -**场景:** 从GitHub API获取仓库信息 - +### 示例2: API交互 ```python -# /// script -# dependencies = [ -# "requests", -# ] -# /// - import requests resp = requests.get('https://api.github.com/repos/python/cpython') data = resp.json() - -print(f"仓库: {data['full_name']}") -print(f"Star数: {data['stargazers_count']}") -print(f"描述: {data['description'][:100]}...") +print(f"仓库: {data['full_name']}, Stars: {data['stargazers_count']}") ``` +**执行**: `uv run --with requests /tmp/script_xxx.py` -### 示例3:文件操作 - -**场景:** 批量重命名文件 - +### 示例3: 文件操作 ```python -# /// script -# dependencies = [] -# /// - import os import glob -from pathlib import Path for i, file in enumerate(glob.glob('*.txt')): - new_name = f"file_{i:03d}.txt" - os.rename(file, new_name) - print(f"✓ {file} → {new_name}") + os.rename(file, f"file_{i:03d}.txt") ``` +**执行**: `uv run /tmp/script_xxx.py`(无依赖) + +### 示例4: uv项目内执行 +```python +import pandas as pd +from my_project import helper + +df = pd.read_csv('data.csv') +result = helper.process(df) +print(result) +``` +**执行**: `uv run scripts/data_process.py`(使用项目环境) + +### 示例5: 用户指定路径 +```python +import requests + +resp = requests.get('https://api.example.com/data') +print(f"处理完成: {len(resp.json())} 条") +``` +**执行**: `uv run --with requests scripts/api_analyzer.py`(写入指定路径) ## Notes ### 为什么使用uv? - -| 特性 | 优势 | -| ------------ | ------------------------------------------------ | -| 环境隔离 | 不污染系统Python环境,每个脚本都有独立的虚拟环境 | -| 自动依赖管理 | 无需手动pip install,uv自动解析和安装依赖 | -| 快速启动 | 比传统venv快10-100倍,快速创建和销毁环境 | -| 标准兼容 | 支持PEP 723格式,官方Python规范 | -| 零配置 | 开箱即用,无需额外配置或初始化 | +| 特性 | 优势 | +|------|------| +| 环境隔离 | 不污染系统Python | +| 自动依赖 | `--with`语法,无需pip install | +| 快速启动 | 比venv快10-100倍 | +| 项目集成 | 自动检测uv项目 | +| 零配置 | 开箱即用,无需PEP 723 | ### 最佳实践 - -1. **总使用内联元数据** - - ```python - # 即使没有依赖也要声明 - # dependencies = [] - ``` - -2. **使用最新版本** - - 不指定版本约束 - - 让uv自动选择 - - 保持依赖更新和安全 - -3. **错误处理** - - 脚本内部处理预期的错误(try-except) - - 严格模式处理意外的错误(立即停止) - -4. **清理资源** - - 临时文件使用系统临时目录(/tmp 或 Windows Temp) - - 系统会自动清理临时文件,无需手动管理 - - 失败时可手动删除临时文件调试 +1. **依赖解析**: 排除标准库;失败时检查遗漏依赖;复杂项目用uv项目模式 +2. **路径**: 用户指定优先;临时文件用于自主生成;跨平台由辅助脚本保证 +3. **错误**: 预期错误脚本内处理;意外错误立即停止;检测失败自动回退 +4. **清理**: 临时文件使用系统目录,自动清理,失败时手动删除 ### 限制 +- ✗ 不支持命令行参数、stdin输入、持久化环境 +- ✗ 使用uv默认Python版本(项目可在pyproject.toml指定) +- ✗ 依赖解析可能不完整(动态导入、条件导入可能遗漏) +- ✗ 项目检测可能误判(网络问题导致回退) -- ✗ 不支持命令行参数 - - 所有参数必须嵌入在脚本中 - - 不支持`uv run script.py arg1 arg2` +### uv工具要求 -- ✗ 不支持stdin输入 - - 不支持`echo "code" | uv run -` - - 所有数据必须硬编码或从文件读取 - -- ✗ 不支持持久化环境 - - 每次执行都是新的临时环境 - - 不缓存或保留虚拟环境 - -- ✗ 不支持自定义Python版本 - - 使用uv的默认Python版本 - - 不在元数据中指定`requires-python` - -- ✗ 不支持复杂的依赖约束 - - 只支持简单的包名 - - 不支持版本范围(`>=1.0,<2.0`) - - 不支持Git URL或本地包 - -## Dependencies - -### 必需依赖 - -- **uv** (https://docs.astral.sh/uv/) - - Python包管理器和运行器 - - 支持PEP 723内联元数据格式 - - 提供环境隔离和自动依赖管理 - -### 可选依赖 - -无 +- **uv是此skill的必需依赖,不可替代** +- **不支持**: python, pip, poetry, venv, virtualenv +- 如果检测到uv未安装,必须停止任务并引导用户安装 +- 不要尝试使用替代方案或自动安装uv ## Workflow Summary -完整的典型工作流: +**完整流程**: +1. 解析import语句,提取外部包名(排除标准库) +2. 执行`uv sync --dry-run`检测项目 +3. 确定脚本路径(用户指定/现有脚本/临时文件) +4. 构造执行命令(根据项目类型和依赖) +5. 执行并捕获输出 -```bash -# 1. 获取临时脚本文件路径 -temp_file_path=$(uv run ./script/get_temp_path.py) - -# 2. 写入PEP 723脚本内容 -# 使用大模型的Write工具在 temp_file_path 中写入... - -# 3. 执行脚本 -uv run $temp_file_path - -# 4. 系统自动清理临时文件 -``` - -**关键特点:** - -- 跨平台自动适配 -- 环境隔离 -- 自动依赖管理 -- 临时文件直接返回路径,无需手动拼接 -- 系统自动清理临时文件,无需手动管理 +**关键特点**: +- 自动依赖解析:分析import自动提取 +- 智能项目检测:自动识别uv项目 +- 灵活路径:支持指定/现有/临时三种模式 +- 跨平台:自动适配Windows/macOS/Linux +- 环境隔离:独立虚拟环境