runtime-context by b-open-io/prompts
npx skills add https://github.com/b-open-io/prompts --skill runtime-context智能体运行在不同的环境中,具备不同的能力。此技能用于检测当前运行时,以便智能体能够使用正确的工具,并在缺少所需能力时清晰地报错。
| 运行时 | 如何检测 | 可用工具 | 技能调用方式 |
|---|---|---|---|
| Claude Code | 环境变量 CLAUDE_CODE=1,或存在 Skill()/Agent()/Read 工具 | 全套工具:Read、Write、Edit、Bash、Grep、Glob、Agent、Skill、WebFetch、WebSearch | Skill() 工具 |
| Vercel Sandbox | 存在 /vercel/sandbox/ 路径,环境变量 VERCEL_SANDBOX_ID 已设置 | bash-tool 三件套:bash、、,如果配置了则还有 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
readFilewriteFileskill来自 bash-tool 的 createSkillTool() |
| 本地开发 | 以上两者都不是,process.cwd() 在用户主目录或项目目录中 | 应用程序提供的任何工具(通常只有 HTTP + AI SDK) | 直接文件读取或无 |
运行 scripts/detect.sh 以获取当前环境的 JSON 摘要:
bash skills/runtime-context/scripts/detect.sh
返回:
{
"runtime": "sandbox",
"has_bash": true,
"has_skill_tool": true,
"sandbox_id": "sbx_abc123",
"working_dir": "/vercel/sandbox/bot",
"node_version": "v22.x.x",
"bun_version": "1.x.x"
}
在编写跨运行时工作的系统提示词时,请按以下结构组织:
## 环境感知
在采取行动之前,请检查您的环境:
1. 如果您拥有 `Skill()` 和 `Agent()` 工具,您处于 Claude Code 中
- 通过 `Skill(name)` 使用技能,通过 `Agent()` 委派任务
- 通过 Read/Write/Edit 拥有完整的文件访问权限
2. 如果您拥有 `bash`、`readFile`、`writeFile` 工具,您处于 Sandbox 中
- 通过 `bash` 运行脚本,通过 `readFile` 读取上下文
- 如果配置了,可以通过 `skill` 工具使用技能
3. 如果您没有任何工具,您处于纯文本模式
- 根据您的训练和系统提示词上下文进行回答
- 告诉用户如果您拥有工具会做什么
不要猜测存在哪些工具。如果工具调用失败,请说明缺少什么工具以及该工具本应提供什么能力。
在构建应利用技能的托管智能体时,请使用 bash-tool:
import {
experimental_createSkillTool as createSkillTool,
createBashTool,
} from "bash-tool";
// 技能目录与您的 bot 代码位于同一目录
const { skill, files, instructions } = await createSkillTool({
skillsDirectory: "./skills",
});
const { tools } = await createBashTool({
files,
extraInstructions: instructions,
});
// 现在您的智能体拥有 bash + readFile + writeFile + skill 工具
const result = streamText({
model: gateway("anthropic/claude-sonnet-4.6"),
tools: { skill, ...tools },
system: soulPrompt,
messages,
});
目标不是提供降级方案。目标是清晰明了。
良好示例: "我处于 Sandbox 中。我拥有 bash 和文件工具,但没有 Skill() 工具。我将直接从 ./skills/clawnet/SKILL.md 读取技能说明。"
不良示例: 先默默地尝试 Skill(),捕获错误,然后尝试 readFile,再尝试 fetch,最后在没有告知用户的情况下放弃。
在对话或任务开始时,声明您能做什么:
我运行在带有 bash、文件和技能工具的 Vercel Sandbox 中。
我可以:运行脚本、读写文件、查找技能说明。
我不可以:生成子智能体、使用 Claude Code 工具、访问主机文件系统。
这立即设定了期望。用户和编排者知道可以要求什么。
bash-tool npm 包为 AI SDK 智能体提供了与 Claude Code 原生提供的相同能力。它创建了在 Vercel Sandbox 内部工作的 bash、readFile、writeFile 和 skill 工具。
| Claude Code 工具 | bash-tool 等效工具 | 备注 |
|---|---|---|
Bash | bash | 命令行执行 |
Read | readFile | 文件读取 |
Write | writeFile | 文件写入 |
Skill() | skill | 技能发现和使用 |
Grep、Glob | 使用 grep/find 的 bash | 无专用工具 |
Agent() | 不适用 | Sandbox 是单智能体环境 |
WebFetch | 使用 curl 的 bash | 无专用工具 |
技能的声明方式因运行时不同而异:
| 运行时 | 声明方式 | 技能加载方式 |
|---|---|---|
| Claude Code | Agent 前置元数据:tools: Skill(clawnet-cli) | 插件系统在运行时提供 |
| Vercel Sandbox | bot.json:"skills": ["clawnet-cli"] | createSkillTool() 读取 ./skills/ 目录 |
| 两者 | 引用相同的 SKILL.md 文件 | 不同的加载器,相同的内容 |
bot.json 中的 skills 数组是已部署 bot 的技能清单——相当于 Sandbox 环境中 Agent 前置元数据的 Skill() 声明。
import {
experimental_createSkillTool as createSkillTool,
createBashTool,
} from "bash-tool";
import { existsSync } from "node:fs";
let agentTools = {};
let skillInstructions = "";
if (existsSync("./skills")) {
const { skill, files, instructions } = await createSkillTool({
skillsDirectory: "./skills",
});
const { tools } = await createBashTool({
files,
extraInstructions: instructions,
});
agentTools = { skill, ...tools };
skillInstructions = instructions;
}
// 传递给 streamText
streamText({
model: gateway(MODEL_ID),
system: soulPrompt + skillInstructions,
tools: agentTools,
messages,
});
| 任务 | Claude Code | Sandbox | 纯文本模式 |
|---|---|---|---|
| 搜索代码库 | Grep、Glob | 使用 grep/find 的 bash | 无法 - 询问用户 |
| 编辑文件 | Edit 工具 | writeFile 工具 | 无法 - 显示差异 |
| 运行测试 | Bash 工具 | bash 工具 | 无法 - 显示命令 |
| 安装包 | Bash 工具 | bash 工具 | 无法 - 显示命令 |
| 委派子任务 | Agent 工具 | 无法 - 单智能体 | 无法 |
| 使用技能 | Skill() 工具 | skill 工具或 readFile | 无法 |
| 网络研究 | WebFetch、WebSearch | 使用 curl 的 bash | 无法 |
每周安装量
1
仓库
GitHub 星标数
8
首次出现
1 天前
安全审计
安装于
windsurf1
amp1
cline1
opencode1
cursor1
kimi-cli1
Agents run in different environments with different capabilities. This skill detects the current runtime so agents can use the right tools and fail clearly when a required capability is missing.
| Runtime | How to detect | Tools available | Skills via |
|---|---|---|---|
| Claude Code | CLAUDE_CODE=1 env var, or Skill()/Agent()/Read tools exist | Full suite: Read, Write, Edit, Bash, Grep, Glob, Agent, Skill, WebFetch, WebSearch | Skill() tool |
| Vercel Sandbox | /vercel/sandbox/ paths exist, VERCEL_SANDBOX_ID env var set | bash-tool trio: bash, readFile, writeFile, plus skill if configured | createSkillTool() from bash-tool |
| Local dev | Neither of the above, process.cwd() is in user home or project dir | Whatever the app provides (usually just HTTP + AI SDK) | Direct file reads or none |
Run scripts/detect.sh to get a JSON summary of the current environment:
bash skills/runtime-context/scripts/detect.sh
Returns:
{
"runtime": "sandbox",
"has_bash": true,
"has_skill_tool": true,
"sandbox_id": "sbx_abc123",
"working_dir": "/vercel/sandbox/bot",
"node_version": "v22.x.x",
"bun_version": "1.x.x"
}
When writing a system prompt that works across runtimes, structure it like this:
## Environment Awareness
Before taking action, check your environment:
1. If you have `Skill()` and `Agent()` tools, you are in Claude Code
- Use skills via `Skill(name)`, delegate via `Agent()`
- Full file access via Read/Write/Edit
2. If you have `bash`, `readFile`, `writeFile` tools, you are in a Sandbox
- Run scripts via `bash`, read context via `readFile`
- Skills available via the `skill` tool if configured
3. If you have no tools, you are text-only
- Answer from your training and system prompt context
- Tell the user what you would do if you had tools
Do not guess which tools exist. If a tool call fails, state what tool
was missing and what capability it would have provided.
When building a hosted agent that should leverage skills, use bash-tool:
import {
experimental_createSkillTool as createSkillTool,
createBashTool,
} from "bash-tool";
// Skills directory lives alongside your bot code
const { skill, files, instructions } = await createSkillTool({
skillsDirectory: "./skills",
});
const { tools } = await createBashTool({
files,
extraInstructions: instructions,
});
// Now your agent has bash + readFile + writeFile + skill tools
const result = streamText({
model: gateway("anthropic/claude-sonnet-4.6"),
tools: { skill, ...tools },
system: soulPrompt,
messages,
});
The goal is NOT fallbacks. The goal is clarity.
Good: "I'm in a Sandbox. I have bash and file tools but no Skill() tool. I'll read the skill instructions directly from ./skills/clawnet/SKILL.md."
Bad: Silently trying Skill() first, catching the error, then trying readFile, then trying fetch, then giving up without telling the user.
At the start of a conversation or task, state what you can do:
I'm running in a Vercel Sandbox with bash, file, and skill tools.
I can: run scripts, read/write files, look up skill instructions.
I cannot: spawn subagents, use Claude Code tools, access the host filesystem.
This sets expectations immediately. Users and orchestrators know what to ask for.
The bash-tool npm package gives AI SDK agents the same capabilities Claude Code provides natively. It creates bash, readFile, writeFile, and skill tools that work inside Vercel Sandboxes.
| Claude Code Tool | bash-tool Equivalent | Notes |
|---|---|---|
Bash | bash | Shell execution |
Read | readFile | File reading |
Write | writeFile | File writing |
Skill() |
Skills are declared differently depending on the runtime:
| Runtime | Declaration | How skills load |
|---|---|---|
| Claude Code | Agent frontmatter: tools: Skill(clawnet-cli) | Plugin system provides at runtime |
| Vercel Sandbox | bot.json: "skills": ["clawnet-cli"] | createSkillTool() reads ./skills/ dir |
| Both | Reference same SKILL.md files |
The bot.json skills array is the deployed bot's skill manifest — the sandbox equivalent of agent frontmatter's Skill() declarations.
import {
experimental_createSkillTool as createSkillTool,
createBashTool,
} from "bash-tool";
import { existsSync } from "node:fs";
let agentTools = {};
let skillInstructions = "";
if (existsSync("./skills")) {
const { skill, files, instructions } = await createSkillTool({
skillsDirectory: "./skills",
});
const { tools } = await createBashTool({
files,
extraInstructions: instructions,
});
agentTools = { skill, ...tools };
skillInstructions = instructions;
}
// Pass to streamText
streamText({
model: gateway(MODEL_ID),
system: soulPrompt + skillInstructions,
tools: agentTools,
messages,
});
| Task | Claude Code | Sandbox | Text-only |
|---|---|---|---|
| Search codebase | Grep, Glob | bash with grep/find | Cannot - ask user |
| Edit files | Edit tool | writeFile | Cannot - show diff |
| Run tests | Bash tool | bash tool | Cannot - show command |
| Install packages | Bash tool | bash tool | Cannot - show command |
| Delegate subtasks |
Weekly Installs
1
Repository
GitHub Stars
8
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketFailSnykPass
Installed on
windsurf1
amp1
cline1
opencode1
cursor1
kimi-cli1
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
147,400 周安装
skill |
| Skill discovery and use |
Grep, Glob | bash with grep/find | No dedicated tools |
Agent() | N/A | Sandboxes are single-agent |
WebFetch | bash with curl | No dedicated tool |
| Different loaders, same content |
| Agent tool |
| Cannot - single agent |
| Cannot |
| Use skills | Skill() tool | skill tool or readFile | Cannot |
| Web research | WebFetch, WebSearch | bash with curl | Cannot |