1
0

优化js-runner命令

This commit is contained in:
2026-02-06 14:53:55 +08:00
parent 260b8966ed
commit 1726616c48
8 changed files with 426 additions and 60 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-06

View File

@@ -0,0 +1,100 @@
## Context
js-runner 技能目前的标准流程假设所有脚本都需要通过临时文件执行。这种设计确保了脚本的隔离性和自动清理,但牺牲了灵活性。用户可能希望:
1. 执行已存在的脚本文件
2. 将脚本持久化到项目中的特定位置
3. 利用大模型已有的文件操作工具Write直接创建脚本
当前实现强制所有场景都通过 `get_temp_path.js` 生成临时路径,限制了这些使用场景。
## Goals / Non-Goals
**Goals:**
- 在文档中增加条件判断逻辑,根据用户输入选择不同的执行路径
- 保持向后兼容未指定路径时仍使用临时文件路径场景3
- 支持直接执行已存在的脚本文件场景1
- 支持使用大模型工具在指定路径创建脚本场景2
**Non-Goals:**
- 不修改 `get_temp_path.js` 的实现
- 不改变 Bun 运行时的行为
- 不增加新的辅助脚本或工具
## Decisions
### 决策1文档驱动的实现方案
**决策选择:** 通过更新 SKILL.md 文档来定义新的使用流程,而不是修改代码实现。
**理由:**
- js-runner 的核心功能(脚本执行)已经完全由 Bun 运行时提供
- 大模型根据 SKILL.md 的描述来选择操作方式
- 当前代码(`get_temp_path.js`)在临时路径场景下已经完全满足需求
- 直接使用大模型的 Write 工具创建文件比通过辅助脚本更灵活
**替代方案考虑:**
- 方案A修改 `get_temp_path.js` 增加路径参数 → 拒绝,因为增加了不必要的复杂性,大模型已有 Write 工具
- 方案B创建新的辅助脚本用于自定义路径 → 拒绝,重复造轮子,大模型工具已覆盖此需求
### 决策2场景优先级的设计
**决策选择:** 在文档中将场景分为明确的优先级,确保大模型在处理用户请求时有清晰的决策树。
**决策树:**
1. 用户是否提供了要执行的脚本文件路径?
- 是 → 直接执行场景1
- 否 → 进入下一步
2. 用户是否指定了脚本的生成路径?
- 是 → 用 Write 工具在指定路径创建脚本然后执行场景2
- 否 → 使用 `get_temp_path.js` 生成临时路径创建脚本执行场景3
**理由:**
- 优先处理用户明确指定的意图(已有脚本或自定义路径)
- 临时路径作为兜底方案,确保未指定路径时仍能工作
- 决策树简单清晰,大模型易于理解和执行
### 决策3保持 `get_temp_path.js` 不变
**决策选择:** 不修改任何现有代码,仅更新文档。
**理由:**
- 临时路径生成逻辑在场景3中仍然必需
- 增加参数会增加代码维护成本
- 文档更新比代码修改更容易审查和回滚
## Risks / Trade-offs
### 风险1大模型可能不理解优先级逻辑
**风险:** 如果文档描述不够清晰,大模型可能在场景选择上出错。
**缓解措施:**
- 在文档中使用明确的"决策树"或"流程图"形式
- 为每个场景提供清晰的示例代码
- 在 SKILL.md 顶部使用简洁的"快速参考"部分总结三种场景
### 权衡:文档复杂度 vs 灵活性
**权衡:** 增加文档的复杂度来提供更高的灵活性。
**说明:**
- 用户获得了更多控制权(直接指定路径)
- 文档需要更详细地解释不同场景
- 但这符合 js-runner 作为"技能工具"的定位——为大模型提供灵活的执行选项
## Migration Plan
本变更仅涉及文档更新,无需代码迁移或部署步骤。
**更新步骤:**
1. 更新 `skills/js-runner/SKILL.md`,增加三种使用场景的说明
2. 更新 `openspec/specs/js-runner/spec.md`,增加新的需求场景
3. 验证文档描述是否清晰,易于理解和执行
**回滚策略:**
- 使用 git 版本控制可以轻松回滚文档修改
- 不涉及代码修改,回滚风险极低
## Open Questions
无。本变更的范围明确,技术实现路径清晰。

View File

@@ -0,0 +1,27 @@
## Why
当前 js-runner 技能的标准流程中,所有脚本执行都必须使用 `get_temp_path.js` 生成临时文件路径。这导致当用户想要运行已存在的脚本文件或希望将脚本持久化到特定位置时,流程不够灵活。大模型已经拥有可以直接创建文件的工具(如 Write 工具),不需要强制通过临时路径生成脚本。
## What Changes
- 增加条件判断逻辑:只有当用户没有指定脚本文件或没有指定脚本生成路径时,才使用 `get_temp_path.js` 生成临时路径
- 增加直接执行已存在脚本文件的使用场景
- 增加使用大模型工具在指定路径创建脚本的使用场景
- 保持向后兼容:不提供路径或脚本时,仍使用原有的临时文件路径生成逻辑
## Capabilities
### New Capabilities
无 - 本变更是在现有 js-runner 技能基础上的增强
### Modified Capabilities
- `js-runner`: 增加条件性使用临时路径的需求。这将修改现有的"文档描述完整调用流程"需求,增加新的场景:
- 场景1用户提供已存在的脚本文件路径 → 直接执行
- 场景2用户提供脚本生成路径 → 用大模型工具创建脚本到指定路径,然后执行
- 场景3用户未提供任何路径信息 → 使用 `get_temp_path.js` 生成临时路径(现有流程)
## Impact
- **文档更新**: `skills/js-runner/SKILL.md` 需要重新组织调用流程说明,增加条件判断逻辑和新的使用场景
- **规范更新**: `openspec/specs/js-runner/spec.md` 需要增加新的需求场景,描述不同条件下的执行路径选择
- **代码**: `get_temp_path.js` 保持不变,仅在未提供路径时调用

View File

@@ -0,0 +1,77 @@
## ADDED Requirements
### Requirement: 环境检查前置条件
在任何场景执行脚本之前,大模型 MUST 先检查 Bun 运行时是否可用。
#### Scenario: 所有场景的环境检查
- **WHEN** 大模型准备执行脚本(无论使用哪种场景)
- **THEN** 必须在执行任何脚本之前先运行 `bun --version`
- **THEN** 如果 `bun --version` 失败或未找到命令,必须输出友好的错误信息
- **THEN** 错误信息必须明确说明 "Bun 运行时未安装" 或类似提示
- **THEN** 错误信息必须包含 Bun 安装说明(如 `curl -fsSL https://bun.sh/install | bash`
- **THEN** 环境检查失败时必须停止后续执行
- **THEN** 大模型禁止自动尝试使用 nodejs、npm、yarn、pnpm 等其他 JavaScript 运行时或包管理工具
- **THEN** 大模型禁止建议用户将脚本转换为其他运行时格式
- **WHEN** `bun --version` 成功
- **THEN** 可以继续执行脚本的相应场景流程
## MODIFIED Requirements
### Requirement: 文档描述完整调用流程
SKILL.md MUST 清晰描述大模型如何使用 js-runner 技能执行 JavaScript/TypeScript 脚本的完整流程,并根据用户提供的路径信息选择不同的执行方式。
#### Scenario: 执行已存在的脚本文件
- **WHEN** 用户提供已存在的脚本文件路径
- **THEN** 首先执行 `bun --version` 检查环境
- **THEN** 如果环境检查失败,输出错误信息并停止执行
- **THEN** 环境检查通过后,大模型直接使用 `bun <script-file>` 执行该脚本
- **THEN** 跳过 `get_temp_path.js` 调用
- **THEN** 不创建任何新文件
- **THEN** 使用脚本的 stdout 和 stderr 作为输出
#### Scenario: 在指定路径创建并执行脚本
- **WHEN** 用户提供脚本生成路径(但脚本文件不存在)
- **THEN** 首先执行 `bun --version` 检查环境
- **THEN** 如果环境检查失败,输出错误信息并停止执行
- **THEN** 环境检查通过后,大模型使用 Write 工具在指定路径创建脚本文件
- **THEN** 使用 `bun <specified-path>` 执行该脚本
- **THEN** 跳过 `get_temp_path.js` 调用
- **THEN** 脚本文件持久化到指定位置
#### Scenario: 使用临时路径执行脚本(默认流程)
- **WHEN** 大模型阅读 SKILL.md 且用户未提供脚本路径或生成路径
- **THEN** 文档描述以下标准流程:
1. 执行 `bun --version` 检查环境
2. 调用 `scripts/get_temp_path.js` 生成临时文件路径
3. 将脚本内容写入临时文件
4. 使用 `bun <temp-file>` 执行脚本
5. Bun 自动处理依赖和 TypeScript 转译
6. 临时文件由系统自动清理
#### Scenario: 文档包含场景选择决策树
- **WHEN** 大模型阅读 SKILL.md
- **THEN** 文档提供清晰的执行流程决策树:
1. 首先执行 `bun --version` 检查环境
- 失败 → 输出错误信息并停止
- 成功 → 进入下一步
2. 用户是否提供了已存在的脚本文件路径?
- 是 → 场景1直接执行
- 否 → 进入下一步
3. 用户是否指定了脚本的生成路径?
- 是 → 场景2在指定路径创建脚本然后执行
- 否 → 场景3使用临时路径默认
#### Scenario: 文档中的示例代码(三种场景)
- **WHEN** 大模型阅读 SKILL.md
- **THEN** 文档提供完整的示例代码,展示:
- 场景1示例直接执行已存在的脚本文件
- 场景2示例在指定路径创建脚本并执行
- 场景3示例使用临时路径执行脚本包含如何调用辅助脚本生成临时文件路径
- 如何检查 Bun 安装(`bun --version`
- 如何处理输出和错误
#### Scenario: 快速参考部分
- **WHEN** 大模型阅读 SKILL.md
- **THEN** 文档顶部包含快速参考部分
- **THEN** 快速参考简洁地总结三种使用场景的关键命令
- **THEN** 快速参考帮助大模型快速选择正确的执行方式

View File

@@ -0,0 +1,46 @@
## 1. 文档准备工作
- [x] 1.1 读取当前的 `skills/js-runner/SKILL.md` 文件,了解现有结构
- [x] 1.2 确认文档中现有的安装说明和基本使用流程
## 2. 文档结构调整
- [x] 2.1 在 SKILL.md 顶部添加"快速参考"部分,总结三种使用场景
- [x] 2.2 在"使用流程"章节添加场景选择决策树
- [x] 2.3 将原有的"完整示例"重新组织为场景3的示例临时路径
## 3. 场景1执行已存在的脚本文件
- [x] 3.1 添加场景1的使用说明章节
- [x] 3.2 编写场景1的完整示例代码包含 `bun --version` 检查)
- [x] 3.3 说明场景1不调用 `get_temp_path.js`
- [x] 3.4 说明场景1不创建新文件
## 4. 场景2在指定路径创建并执行脚本
- [x] 4.1 添加场景2的使用说明章节
- [x] 4.2 编写场景2的完整示例代码包含 `bun --version` 检查和 Write 工具使用)
- [x] 4.3 说明场景2使用大模型的 Write 工具创建文件
- [x] 4.4 说明场景2脚本持久化到指定位置
## 5. 环境检查和错误处理
- [x] 5.1 在所有场景的示例中确保第一步都是 `bun --version` 检查
- [x] 5.2 添加环境检查失败的错误处理说明
- [x] 5.3 明确说明当 Bun 未安装时的错误提示内容(包含安装命令)
- [x] 5.4 添加禁止条款:禁止使用 nodejs/npm/yarn/pnpm 等其他工具
- [x] 5.5 添加禁止条款:禁止建议用户转换为其他运行时格式
## 6. 文档验证
- [x] 6.1 验证决策树的逻辑正确性
- [x] 6.2 验证所有三个场景的示例代码完整且可执行
- [x] 6.3 验证快速参考部分简洁明了
- [x] 6.4 验证文档保持向后兼容(原有临时路径流程仍然可用)
## 7. 最终检查
- [x] 7.1 检查文档格式和排版
- [x] 7.2 确认所有章节的标题层级正确
- [x] 7.3 确认文档使用中文面向中文开发者
- [x] 7.4 验证 frontmatter 保持完整

View File

@@ -5,3 +5,4 @@ context: |
这个项目是专门用于开发用于大模型工具的 skill
所有开发的 skill 都放在「skills」目录下每个子目录都代表一个 skill目录名为 skill 的名称;
开发过程中的文档使用中文,面向中文开发者进行交流;
「document」下是 skill 开发的相关规范文档;

View File

@@ -6,6 +6,21 @@ Define requirements for the js-runner skill, which enables execution of JavaScri
## Requirements
### Requirement: 环境检查前置条件
在任何场景执行脚本之前,大模型 MUST 先检查 Bun 运行时是否可用。
#### Scenario: 所有场景的环境检查
- **WHEN** 大模型准备执行脚本(无论使用哪种场景)
- **THEN** 必须在执行任何脚本之前先运行 `bun --version`
- **THEN** 如果 `bun --version` 失败或未找到命令,必须输出友好的错误信息
- **THEN** 错误信息必须明确说明 "Bun 运行时未安装" 或类似提示
- **THEN** 错误信息必须包含 Bun 安装说明(如 `curl -fsSL https://bun.sh/install | bash`
- **THEN** 环境检查失败时必须停止后续执行
- **THEN** 大模型禁止自动尝试使用 nodejs、npm、yarn、pnpm 等其他 JavaScript 运行时或包管理工具
- **THEN** 大模型禁止建议用户将脚本转换为其他运行时格式
- **WHEN** `bun --version` 成功
- **THEN** 可以继续执行脚本的相应场景流程
### Requirement: 生成临时文件路径
辅助脚本 MUST 提供为脚本生成唯一临时文件路径的功能。
@@ -22,10 +37,28 @@ Define requirements for the js-runner skill, which enables execution of JavaScri
- **THEN** 文件扩展名为 `.ts`
### Requirement: 文档描述完整调用流程
SKILL.md MUST 清晰描述大模型如何使用 js-runner 技能执行 JavaScript/TypeScript 脚本的完整流程。
SKILL.md MUST 清晰描述大模型如何使用 js-runner 技能执行 JavaScript/TypeScript 脚本的完整流程,并根据用户提供的路径信息选择不同的执行方式
#### Scenario: 执行脚本的标准流程
- **WHEN** 大模型阅读 SKILL.md
#### Scenario: 执行已存在的脚本文件
- **WHEN** 用户提供已存在的脚本文件路径
- **THEN** 首先执行 `bun --version` 检查环境
- **THEN** 如果环境检查失败,输出错误信息并停止执行
- **THEN** 环境检查通过后,大模型直接使用 `bun <script-file>` 执行该脚本
- **THEN** 跳过 `get_temp_path.js` 调用
- **THEN** 不创建任何新文件
- **THEN** 使用脚本的 stdout 和 stderr 作为输出
#### Scenario: 在指定路径创建并执行脚本
- **WHEN** 用户提供脚本生成路径(但脚本文件不存在)
- **THEN** 首先执行 `bun --version` 检查环境
- **THEN** 如果环境检查失败,输出错误信息并停止执行
- **THEN** 环境检查通过后,大模型使用 Write 工具在指定路径创建脚本文件
- **THEN** 使用 `bun <specified-path>` 执行该脚本
- **THEN** 跳过 `get_temp_path.js` 调用
- **THEN** 脚本文件持久化到指定位置
#### Scenario: 使用临时路径执行脚本(默认流程)
- **WHEN** 大模型阅读 SKILL.md 且用户未提供脚本路径或生成路径
- **THEN** 文档描述以下标准流程:
1. 执行 `bun --version` 检查环境
2. 调用 `scripts/get_temp_path.js` 生成临时文件路径
@@ -34,14 +67,34 @@ SKILL.md MUST 清晰描述大模型如何使用 js-runner 技能执行 JavaScrip
5. Bun 自动处理依赖和 TypeScript 转译
6. 临时文件由系统自动清理
#### Scenario: 文档中的示例代码
#### Scenario: 文档包含场景选择决策树
- **WHEN** 大模型阅读 SKILL.md
- **THEN** 文档提供清晰的执行流程决策树:
1. 首先执行 `bun --version` 检查环境
- 失败 → 输出错误信息并停止
- 成功 → 进入下一步
2. 用户是否提供了已存在的脚本文件路径?
- 是 → 场景1直接执行
- 否 → 进入下一步
3. 用户是否指定了脚本的生成路径?
- 是 → 场景2在指定路径创建脚本然后执行
- 否 → 场景3使用临时路径默认
#### Scenario: 文档中的示例代码(三种场景)
- **WHEN** 大模型阅读 SKILL.md
- **THEN** 文档提供完整的示例代码,展示:
- 场景1示例直接执行已存在的脚本文件
- 场景2示例在指定路径创建脚本并执行
- 场景3示例使用临时路径执行脚本包含如何调用辅助脚本生成临时文件路径
- 如何检查 Bun 安装(`bun --version`
- 如何调用辅助脚本生成临时文件路径
- 如何执行脚本
- 如何处理输出和错误
#### Scenario: 快速参考部分
- **WHEN** 大模型阅读 SKILL.md
- **THEN** 文档顶部包含快速参考部分
- **THEN** 快速参考简洁地总结三种使用场景的关键命令
- **THEN** 快速参考帮助大模型快速选择正确的执行方式
### Requirement: 错误处理和诊断
系统 MUST 提供清晰的错误信息和诊断功能,帮助用户识别和解决问题。

View File

@@ -8,6 +8,18 @@ compatibility: Requires Bun runtime (https://bun.sh)
基于 Bun 的 JavaScript/TypeScript 执行技能,提供隔离的脚本执行和自动依赖管理。
## 快速参考
根据您的需求选择使用方式:
| 场景 | 描述 | 命令 |
| --------- | ------------------------ | ---------------------------------- |
| **场景1** | 直接执行已存在的脚本文件 | `bun <script-file>` |
| **场景2** | 在指定路径创建脚本并执行 | 使用 Write 工具创建 → `bun <path>` |
| **场景3** | 使用临时路径执行(默认) | 生成临时路径 → `bun <temp-file>` |
**重要提示:** 所有场景在执行脚本前都必须先检查 Bun 环境:`bun --version`
## 前置条件
### 安装 Bun
@@ -34,16 +46,74 @@ bun --version
## 使用流程
执行 JavaScript/TypeScript 脚本的完整工作流程:
**执行流程决策树:**
1. **检查环境** - 验证 Bun 是否已安装
2. **生成临时路径** - 调用辅助脚本获取唯一的临时文件路径
3. **写入脚本** - 将脚本内容保存到临时文件
4. **执行脚本** - 使用 Bun 运行脚本
5. **捕获输出** - 从执行结果读取 stdout/stderr
6. **清理** - 临时文件由系统自动处理
1. **步骤1检查 Bun 环境**
- 执行:`bun --version`
- 失败 → 输出错误信息(包含安装说明)并停止执行
- 成功 → 进入下一步
- **重要:** 禁止使用 nodejs、npm、yarn、pnpm 等其他工具
### 完整示例
2. **步骤2选择执行场景**
- 场景1用户提供了已存在的脚本文件路径
- 是 → 直接执行:`bun <script-file>`
- 否 → 进入下一步
- 场景2用户指定了脚本的生成路径
- 是 → 使用 Write 工具创建脚本,然后执行
- 否 → 进入场景3
3. **场景3默认**:使用临时路径执行
- 生成临时文件路径
- 将脚本内容写入临时文件
- 使用 Bun 运行脚本
- 临时文件由系统自动处理
---
### 场景1执行已存在的脚本文件
```bash
# 步骤 1: 检查 Bun 是否已安装
bun --version
# 步骤 2: 直接执行已存在的脚本
bun ./scripts/my-script.js
# 脚本的输出将自动显示
```
**关键特点:**
-**无需生成临时文件** - 直接执行用户提供的脚本
-**保持脚本位置** - 脚本留在原位置,不会被移动或复制
-**简洁快速** - 跳过文件生成步骤,直接执行
### 场景2在指定路径创建并执行脚本
```bash
# 步骤 1: 检查 Bun 是否已安装
bun --version
# 步骤 2: 使用 Write 工具在指定路径创建脚本
# (以下步骤由大模型使用 Write 工具完成)
# write content to "./scripts/new-script.js"
const greeting = "Hello from custom path!";
console.log(greeting);
# 步骤 3: 执行脚本
bun ./scripts/new-script.js
```
**关键特点:**
-**自定义路径** - 脚本创建到用户指定的位置
-**持久化存储** - 脚本文件保存在指定位置,不会被自动清理
-**灵活控制** - 用户可以精确控制脚本位置和命名
### 场景3使用临时路径执行默认流程
当用户未提供任何路径信息时,使用临时路径执行脚本(默认流程):
#### 基础示例
```bash
# 步骤 1: 检查 Bun 是否已安装
@@ -65,53 +135,27 @@ bun "$TEMP_FILE"
# 临时文件将由系统自动清理
```
### 使用依赖
#### TypeScript 示例
```bash
# 生成临时文件
TEMP_FILE=$(bun skills/js-runner/scripts/get_temp_path.js js)
# 写入包含外部依赖的脚本
cat <<EOF > "$TEMP_FILE"
import axios from 'axios';
const response = await axios.get('https://api.github.com');
console.log('GitHub API status:', response.status);
EOF
# 执行 - Bun 首次运行时会自动下载依赖
bun "$TEMP_FILE"
```
Bun 会自动:
- 检测 `import` 语句
- 下载并缓存依赖(到 `~/.bun/install/cache`
- 根据需要处理 TypeScript 编译
- 无需 `package.json` 或手动安装
## JavaScript 与 TypeScript
JavaScript 和 TypeScript 使用相同的工作流程:
```bash
# JavaScript
TEMP_JS=$(bun skills/js-runner/scripts/get_temp_path.js js)
cat <<EOF > "$TEMP_JS"
console.log('JavaScript execution');
EOF
bun "$TEMP_JS"
# TypeScript
# 生成 TypeScript 临时文件
TEMP_TS=$(bun skills/js-runner/scripts/get_temp_path.js ts)
# 写入 TypeScript 脚本
cat <<EOF > "$TEMP_TS"
const message: string = 'TypeScript execution';
console.log(message);
EOF
# 执行 - Bun 会自动转译 TypeScript
bun "$TEMP_TS"
```
Bun 自动即时转译 TypeScript。
**Bun 自动处理:**
- 检测 `import` 语句
- 即时转译 TypeScript
- 下载并缓存依赖(到 `~/.bun/install/cache`
- 无需 `package.json` 或手动安装
## 依赖管理
@@ -179,11 +223,27 @@ $ bun skills/js-runner/scripts/get_temp_path.js ts
### 未安装 Bun
**症状:** `command not found: bun`
**症状:** `bun --version` 失败或返回 "command not found: bun"
**解决方案:**
**错误处理:**
提示用户 Bun 没有安装,并说明安装方式,禁止直接自动安装
当检测到 Bun 未安装时,必须:
1. **停止执行** - 不进行任何后续操作
2. **输出明确错误信息** - 清晰说明 "Bun 运行时未安装" 或类似提示
3. **提供安装说明** - 参考"前置条件"章节的安装命令
**重要限制:**
-**禁止自动安装** - 不要尝试自动安装 Bun由用户自行决定
-**禁止使用其他工具** - 不要尝试使用 nodejs、npm、yarn、pnpm 等其他 JavaScript 运行时或包管理工具
-**禁止格式转换** - 不要建议用户将脚本转换为其他运行时格式
**正确做法:**
- ✅ 仅输出错误信息和安装说明
- ✅ 等待用户安装 Bun 后再继续
- ✅ 保持使用 Bun 作为唯一运行时
### 脚本语法错误
@@ -258,9 +318,9 @@ process.exit(0) // 成功
## 最佳实践
1. **始终检查 Bun 是否已安装**,然后再尝试执行脚本
2. **使用辅助脚本为每次执行生成唯一的临时路径**
3. **单独处理 stdout/stderr** 以区分输出和错误
4. **检查退出码** 以检测脚本失败
5. **使用 ESM imports** (`import from`) 编写现代 JavaScript
6. **捕获并显示错误** 以帮助用户调试问题
1. **始终检查 Bun 环境** - 所有场景第一步都执行 `bun --version`
2. **根据用户意图选择场景** - 查看快速参考选择合适的使用方式
3. **单独处理 stdout/stderr** - 以区分输出和错误
4. **检查退出码** - 以检测脚本失败
5. **使用 ESM imports** - 使用 `import from` 编写现代 JavaScript
6. **捕获并显示错误** - 以帮助用户调试问题