1
0
Files
Skill/openspec/changes/archive/2026-02-05-bun-js-runner/design.md

144 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context背景
本项目在 `skills/` 目录下开发用于大模型工具的技能skills每个子目录代表一个技能。目前项目已经有一个 `python-runner` 技能,它使用 `uv` 提供了隔离的 Python 执行环境,支持依赖管理和临时文件隔离。
`js-runner/` 目录已存在但未完成,只包含一个测试文件(`test/axios.js`)。目前项目中还没有功能完整的 JavaScript/TypeScript 执行能力。
**当前状态:**
- `python-runner` 技能已完整实现(基于 uv 的隔离)
- `js-runner` 目录骨架存在但缺少实现
- 没有 JavaScript/TypeScript 的依赖管理机制
- 没有 JS/TS 脚本的临时文件生命周期管理
**约束条件:**
- 必须保持环境隔离(不污染系统包)
- 应遵循 `python-runner` 建立的模式以保持一致性
- 技能结构必须符合项目规范(`skills/<skill-name>/`
- 必须同时支持 JavaScript 和 TypeScript 执行
## Goals / Non-Goals目标 / 非目标)
**目标:**
- 提供辅助脚本供大模型调用(使用 JavaScript 编写,与 skill 主题一致)
- 在 SKILL.md 中清晰描述完整的调用流程
- 利用 Bun 的自动依赖管理能力
- 匹配 `python-runner` 的工作流程和用户体验,保持一致性
**非目标:**
- 提供完整的 IDE 或开发环境
- 脚本的长期存储或持久化
- 超越 JavaScript/TypeScript 的多语言支持
- 替换或修改现有的 `python-runner` 技能
- 构建自定义的 Bun 运行时包装器(直接使用 Bun
## Decisions技术决策
### 1. 使用 Bun 作为 JavaScript 运行时
**理由:** Bun 相比替代方案具有显著优势:
- **Bun** 比 Node.js 快约 100 倍的冷启动内置包管理器bun install原生 TypeScript 支持,兼容 Node.js API
- **Node.js + npm/yarn** 启动慢,需要外部包管理器,没有原生 TypeScript 支持
- **Deno** 不同的 API 表面(不兼容 Node.js生态系统较小Node.js 用户学习曲线陡峭
**考虑的替代方案:**
- **Node.js with npm** 因启动速度慢且无原生 TypeScript 支持而被拒绝
- **Deno** 因 API 与 Node.js 生态不兼容且包管理不熟悉而被拒绝
### 2. 基于临时文件的执行模型
**理由:** 遵循 `python-runner` 的模式,在临时文件中执行脚本可以:
- 在执行之间保持干净的隔离
- 自动清理产物
- 不需要跨运行的状态管理
- 比内存执行实现更简单
**考虑的替代方案:**
- **通过 Bun 的 `Bun.transpileString()` 进行内存执行:** 因对模块导入和外部依赖支持不好而被拒绝
- **持久化目录结构:** 因避免执行之间的状态泄漏而被拒绝
### 3. 使用 Bun 的自动依赖管理
**理由:** Bun 可以直接运行脚本并自动处理依赖:
- **自动依赖解析:** 当脚本使用 `import``require` 引入外部包时Bun 自动下载并缓存该包
- **无需手动安装:** 不需要手动运行 `bun install`Bun 在运行时自动处理
- **智能缓存:** Bun 全局缓存已下载的包,后续运行无需重复下载
- **简化实现:** 不需要生成临时的 `package.json`,也不需要管理 `node_modules`
**工作流程:**
1. 用户直接运行脚本(内联或从文件)
2. 脚本中使用 `import``require` 引入依赖(如 `import axios from 'axios'`
3. Bun 自动检测到未安装的依赖
4. Bun 下载并缓存依赖到 Bun 的全局缓存(`~/.bun/install/cache`
5. 执行脚本
6. 清理临时脚本文件Bun 的缓存保持不变)
**考虑的替代方案:**
- **手动 package.json + bun install** 因 Bun 已经提供自动依赖处理而被拒绝(过度设计)
- **要求用户提供 package.json** 因增加用户负担而被拒绝
### 4. 用于路径管理的辅助脚本
**理由:** `get_temp_path.js` 辅助脚本将:
- 为脚本生成唯一的临时文件路径
- 遵循特定于操作系统的临时目录约定
- 使用 JavaScript 编写,与 js-runner 主题一致
- 使用 Bun 运行(已确保环境就绪)
**实现方式:**
```javascript
import { tmpdir } from "os";
import { join } from "path";
export function getTempPath(extension) {
const timestamp = Date.now();
const random = Math.random().toString(36).substring(7);
return join(tmpdir(), `js-runner-${timestamp}-${random}.${extension}`);
}
```
## Risks / Trade-offs风险 / 权衡)
### 风险:需要安装 Bun
**风险:** 用户必须单独安装 Bun这增加了设置障碍。
**缓解措施:**
- 在 SKILL.md 中清晰记录安装过程(`curl -fsSL https://bun.sh/install | bash`
- 如果未找到 Bun提供有用的错误消息
- 考虑添加 "check" 命令来验证 Bun 安装
## Migration Plan迁移计划
由于这是一个没有现有生产使用的新技能:
1. **第一阶段:实现**
- 创建 `scripts/get_temp_path.js` 辅助脚本(使用 JavaScript 编写)
- 编写完整的 `SKILL.md` 文档,包含必要的 frontmatter
- 描述完整调用流程
2. **第二阶段:验证**
- 验证 `get_temp_path.js` 辅助脚本工作正常
- 验证 SKILL.md 格式符合 Agent Skills 规范
- 验证 SKILL.md 中的调用流程准确无误
3. **第三阶段:文档**
- 确保 SKILL.md 涵盖所有用例
- 为常见场景提供示例
- 记录错误处理和故障排除
**回滚策略:**
- 如果实现有问题,删除 `skills/js-runner/` 目录
- 对项目其他部分无影响,因为这是一个新的隔离技能
## Open Questions待解决的问题
1. **我们是否应该支持持久化项目目录?**
- 当前方法:只有临时文件
- 考虑:允许用户指定工作目录
- 决策:推迟到未来增强;首先专注于简单的脚本执行
2. **需要什么级别的错误报告?**
- 当前计划:按原样转发 Bun 的 stderr 输出
- 考虑:解析并美化常见错误
- 决策:从原始输出开始,根据用户需求增强