@lousy-agents /代理壳

一个用于AI代理工具使用和npm脚本执行的飞行记录器。
代理-shell记录结构化的JSONL遥测npm脚本执行(通过 script-shell shim)和AI代理工具的使用(通过Copilot生命周期挂钩)。它提供了不依赖于代理自我报告的审计跟踪。
快速入门
# Install globally
npm install -g @lousy-agents/agent-shell
# Initialize hooks and policy (interactive)
agent-shell init
# Add event storage to .gitignore
echo '.agent-shell/' >> .gitignore
# Verify it's working
agent-shell --version
agent-shell init 检测您的项目,提示启用哪些功能(飞行记录,策略阻塞),并写入Copilot钩子配置和策略文件。
注意:
agent-shell init设置Copilot钩子和策略文件,但npm脚本执行记录是单独配置的。记录npm脚本的运行和发出script_end事件,设置npmscript-shell来agent-shell(例如加上script-shell=agent-shell到你的项目.npmrc)。
为什么全球? Agent-shell被配置为npm的
script-shell作为副驾驶的挂钩命令,所以它必须可用 之前npm ci或者npm install运行。本地开发依赖会创建一个循环依赖。全局安装使其保持打开状态PATH独立的node_modules.
它是如何工作的
当npm运行一个脚本(例如: npm test),它调用已配置的 script-shell 而不是 /bin/sh. Agent-shell封装了真正的shell:
- 捕获上下文(参与者、环境、时间戳)
- 产生
/bin/sh -c <command>-你的脚本运行正常 - 用执行元数据记录JSONL事件
- 不加更改地传播退出代码
脚本的行为完全相同——相同的输出、相同的退出代码、相同的信号。Agent-shell在不改变行为的情况下增加了可观察性。
设置与 agent-shell init
这个 init 子命令是为项目配置代理-shell的推荐方法。它检测现有配置并指导您启用功能。
交互模式(TTY)
agent-shell init
当在终端运行时, init 每个功能的提示:
- 飞行记录 记录所有座席工具的使用情况
postToolUse钩 - 政策阻止 -根据允许/拒绝规则对命令进行评估
preToolUse钩
如果 hooks.json 已经存在,只会提示缺少的功能。
非交互模式(CI / Flags)
# Enable specific features
agent-shell init --flight-recorder
agent-shell init --policy
agent-shell init --flight-recorder --policy
# Disable specific features
agent-shell init --no-flight-recorder
agent-shell init --no-policy
在没有显式标志的非tty环境中,所有缺失的特性都将通过发送错误消息自动启用。
它产生了什么
| 文件 | 描述 |
|---|---|
.github/hooks/agent-shell/hooks.json | 副驾驶钩配置选定的功能 |
.github/hooks/agent-shell/policy.json | 允许/拒绝策略(仅当策略启用时) |
飞行记录 agent-shell record
这个 record 子命令是 postToolUse 钩子处理程序,将每个工具调用记录为 tool_use 遥测事件。它捕获了npm脚本之外的工具使用情况——文件编辑、代码搜索、API调用等等。
副驾驶挂钩配置
当航班记录和策略都启用时, hooks.json 看起来像这样:
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "agent-shell policy-check",
"timeoutSec": 30
}
],
"postToolUse": [
{
"type": "command",
"bash": "agent-shell record",
"timeoutSec": 30
}
]
}
}
这个 record 处理程序从Copilot的 postToolUse 通过stdin钩子。对于终端工具(bash, zsh, ash, sh)中提取命令字符串 toolArgs. 对于非终端工具,命令记录为空字符串。
遥测模式(v1)
每个事件生成一行JSON。有四种事件类型:
script_end 事件
记录在npm脚本完成时:
{
"v": 1,
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event": "script_end",
"script": "test",
"command": "vitest run",
"package": "my-app",
"package_version": "1.2.0",
"actor": "claude-code",
"exit_code": 1,
"signal": null,
"duration_ms": 3420,
"timestamp": "2026-03-08T14:32:01.000Z",
"env": {
"NODE_ENV": "test",
"CI": "true"
},
"tags": {
"pr": "1234"
}
}
tool_use 事件
由 postToolUse 当代理使用任何工具时挂钩:
{
"v": 1,
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event": "tool_use",
"tool_name": "bash",
"command": "npm test",
"actor": "copilot",
"timestamp": "2026-03-08T14:32:01.000Z",
"env": {
"CI": "true"
},
"tags": {}
}
对于非终端工具(文件编辑、搜索等), command 是空字符串和 tool_name 识别工具(例如, file_edit, curl)。
policy_decision 事件
记录时 preToolUse Policy-check钩子计算命令:
{
"v": 1,
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event": "policy_decision",
"decision": "deny",
"matched_rule": "rm -rf *",
"command": "rm -rf /",
"actor": "copilot",
"timestamp": "2026-03-08T14:32:01.000Z",
"env": {
"CI": "true"
},
"tags": {}
}
shim_error 事件
记录agent-shell遇到内部错误时的记录(例如,解析npm上下文失败):
{
"v": 1,
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event": "shim_error",
"command": "",
"actor": "copilot",
"timestamp": "2026-03-08T14:32:01.000Z",
"env": {},
"tags": {}
}
字段引用
| 场 | 类型 | 描述 |
|---|---|---|
v | 数量 | 架构版本(总是) 1) |
session_id | 字符串 | 标识会话的UUID |
event | 字符串 | script_end, tool_use, shim_error,或者 policy_decision |
script | 字符串? | NPM生命周期事件名称(例如: test, build) - - - script_end 只有 |
tool_name | 字符串? | 工具标识符(例如: bash, file_edit) - - - tool_use 只有 |
command | 字符串 | 实际执行的命令 |
package | 字符串? | 来自 package.json |
package_version | 字符串? | 包版本 |
actor | 字符串 | 谁发起的: human, ci, claude-code, copilot,或习俗 |
exit_code | 数量 | 子进程退出码 |
signal | 字符串|空 | 如果被杀死,信号名称(例如, SIGINT),否则 null |
duration_ms | 数量 | 以毫秒为单位的挂钟执行时间 |
timestamp | 字符串 | ISO 8601完成时间戳 |
env | 对象 | 捕获的环境变量(allowlisted) |
tags | 对象 | 自定义标签 AGENTSHELL_TAG_* 变量 |
字段 script, package, package_version 只有在NPM上下文中运行时才会出现。
演员检测
代理-shell对谁发起了每个脚本执行进行分类:
| 优先级 | 条件 | 演员 |
|---|---|---|
| 1 | AGENTSHELL_ACTOR 设置 | 变量的值 |
| 2 | GITHUB_ACTIONS=true | ci |
| 3 | CLAUDE_CODE 设置 | claude-code |
| 4 | COPILOT_AGENT 设置 | copilot |
| 5 | COPILOT_CLI 设置 | copilot |
| 6 | COPILOT_CLI_BINARY_VERSION 设置 | copilot |
| 7 | 不匹配 | human |
查询事件
使用 log 查询执行历史的子命令。两个 script_end 和 tool_use 事件包含在结果中:
# Show events from the most recent session
agent-shell log
# Show events from the last 2 hours
agent-shell log --last 2h
# Show only failures (script_end events with non-zero exit)
agent-shell log --failures
# Filter by actor
agent-shell log --actor claude-code
# Filter by script name (script_end events only)
agent-shell log --script test
# Combine filters
agent-shell log --actor claude-code --failures --last 2h
# Output as JSON (for scripting)
agent-shell log --json
# List all sessions
agent-shell log --list-sessions
时间格式
| 格式 | 意义 |
|---|---|
30m | 最后30分钟 |
2h | 最后2小时 |
1d | 最后1天 |
基于策略的命令阻断
代理-shell包括一个 policy-check 在执行之前根据允许/拒绝规则对shell命令进行评估的子命令。这使得存储库维护者可以通过工具使用前的钩子定义允许AI代理运行哪些命令。
它是如何工作的
policy-check命令的设计目的是 GitHub Copilot预工具使用钩子. 它从标准输出读取包含工具名称和参数的JSON请求,根据策略文件计算命令,并将权限决定写入标准输出。
仅限终端工具(bash, zsh, ash, sh)在策略文件成功加载时,根据策略规则评估它们的命令;然后允许非终端工具在没有政策评估的情况下使用。如果缺少默认策略文件,则允许使用所有工具,但如果策略文件存在且格式不正确或无效,则拒绝使用所有工具。
策略文件
缺省情况下,策略文件位于 .github/hooks/agent-shell/policy.json 相对于存储库根目录。控件覆盖该位置 AGENTSHELL_POLICY_PATH 环境变量。
{
"allow": ["npm test", "npm run lint*", "git status"],
"deny": ["npm publish", "rm -rf *"]
}
评估顺序:
- 如果命令匹配任何
deny模式→ 否认 - 如果一个
allow列表存在且命令不匹配任何模式→ 否认 - 否则→ 允许
模式支持 * 用于前缀、后缀和中缀匹配的通配符(例如: npm run * 匹配 npm run test). 当使用默认策略路径时,缺少策略文件将导致允许所有命令。当 AGENTSHELL_POLICY_PATH 如果所引用的策略文件丢失、格式不正确或无法加载,则命令被拒绝(失败关闭)。
副驾驶挂钩配置
将以下内容添加到 .github/hooks/agent-shell/hooks.json,或使用 agent-shell init 自动生成:
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"timeoutSec": 30,
"bash": "agent-shell policy-check"
}
],
"postToolUse": [
{
"type": "command",
"timeoutSec": 30,
"bash": "agent-shell record"
}
]
}
}
输入/输出格式
输入 (JSON通过stdin):
{
"toolName": "bash",
"toolArgs": "{\"command\": \"npm test\"}"
}
输出 (JSON到标准输出):
{"permissionDecision": "allow"}
或者当被拒绝时:
{
"permissionDecision": "deny",
"permissionDecisionReason": "Command 'npm publish' denied by policy rule: npm publish"
}
策略决策与常规脚本执行事件一起记录为遥测事件。
策略初始化(policy --init)
手动编写 policy.json 允许列表需要知道您的项目实际使用哪些命令。 policy --init 消除了空白页问题:它扫描您的项目并生成准备提交策略和钩子配置。
agent-shell policy --init
它产生了什么
| 文件 | 描述 |
|---|---|
.github/hooks/agent-shell/policy.json | 允许/拒绝从发现的命令派生的策略 |
.github/hooks/agent-shell/hooks.json | 副驾驶员 preToolUse 钩式进线 agent-shell policy-check |
如果其中任何一个文件已经存在,该命令将跳过写入它并通知您。这两个文件都可以安全提交,以便在整个团队范围内执行。
如何发现命令
扫描器检查三个来源:
package.json脚本 ——每个npm run <script>条目变成了一个确切的允许规则- GitHub Actions工作流文件 - - - - - -
run:命令.github/workflows/*.yml是否被提取和重复数据删除 mise.toml任务 -每个任务成为一个精确的mise run <task>允许规则(为了安全,没有通配符)
语言检测(Node.js, Python, Go, Rust, Ruby, Java)也被执行并在扫描摘要中报告。特定于语言的构建工具模式可能会在未来的版本中添加。
增高的分析
当 @github/copilot-sdk 软件包可用并经过认证, policy --init 使用GitHub Copilot AI运行第二次通过以优化生成的允许列表。AI会话连接到 @lousy-agents/mcp 作为结构化项目发现的本地MCP服务器,并暴露了两个额外的沙盒工具,用于特别探索:
| 工具 | 它是做什么的 |
|---|---|
read_project_file | 读取存储库中的文件(最大100 KB,路径遍历安全) |
validate_allow_rule | 检查提议的allow规则是否安全(无shell元字符) |
MCP服务器还提供 discover_feedback_loops 和 discover_environment 工具,使模型结构化地访问SDLC命令和运行时/工具链细节,而无需浏览原始的文件系统。
回退行为:
| 条件 | 行为 |
|---|---|
@github/copilot-sdk 没有安装 | 默默地回到静态分析;没有错误 |
| 已安装SDK,但未验证 | 默默地回到静态分析;没有错误 |
| SDK会话在分析过程中失败 | 返回到静态结果;将错误记录为错误 AGENT_SHELL_COPILOT_DEBUG 设置 |
始终生成最终的策略文件。人工智能增强是尽最大努力,不会阻碍输出。
身份验证设置
这个 @github/copilot-sdk 进行身份验证。 GitHub Copilot CLI. 您需要同时安装GitHub CLI和Copilot CLI扩展并登录。
1. 安装GitHub CLI
遵循 官方安装指南 对于您的平台,然后验证:
gh auth login
2. 安装GitHub Copilot CLI扩展
gh extension install github/gh-copilot
3. 与副驾驶进行认证
gh copilot auth
4. 安装SDK
npm install @github/copilot-sdk
一旦身份验证, policy --init 将自动检测SDK并运行ai增强分析。要调试SDK交互,请设置 AGENT_SHELL_COPILOT_DEBUG=1.
先决条件
- 必须在git存储库中运行(
git rev-parse --show-toplevel用于定位repo根目录) agent-shell必须全局安装(需要生成的钩子脚本上PATH)@github/copilot-sdk是可选的-参见 身份验证设置 以启用ai增强的分析
示例输出
Scanning project...
Discovered: 8 npm script(s), 12 workflow command(s), 3 mise task(s), 1 language(s)
Created .github/hooks/agent-shell/policy.json
Created .github/hooks/agent-shell/hooks.json
--- Proposed Policy ---
{
"allow": [
"git branch --list *",
"git branch --show-current",
"git diff *",
"git log *",
"git rev-parse *",
"git show *",
"git status *",
"npm run build",
"npm run lint",
"npm test",
"pwd"
],
"deny": [
"rm -rf *",
"sudo *"
]
}
--- Hook Configuration ---
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "agent-shell policy-check",
"timeoutSec": 30
}
]
}
}
环境变量
| 变量 | 目的 | 默认的 |
|---|---|---|
AGENTSHELL_PASSTHROUGH | 设置为 1 绕过所有仪表 | 取消设置(仪表活动) |
AGENTSHELL_ACTOR | 覆盖自动行为者检测 | 未设置(启发式检测) |
AGENTSHELL_SESSION_ID | 用于事件关联的共享会话ID | 取消设置(每次调用的新UUID) |
AGENTSHELL_LOG_DIR | 覆盖事件文件目录 | .agent-shell/events/ |
AGENTSHELL_POLICY_PATH | 覆盖策略文件位置 policy-check | .github/hooks/agent-shell/policy.json |
AGENTSHELL_TAG_<key> | 将自定义键=值元数据附加到事件 | 无 |
AGENT_SHELL_COPILOT_DEBUG | 设置为 1 启用调试日志的副驾驶SDK交互期间 policy --init | 取消设置(调试日志关闭) |
自定义标记
集 AGENTSHELL_TAG_* 附加元数据的环境变量:
AGENTSHELL_TAG_pr=1234 AGENTSHELL_TAG_task=fix-auth npm test
生产: "tags": { "pr": "1234", "task": "fix-auth" }
会话相关性
默认情况下,每个脚本调用获得一个新的会话ID。在工作流中关联事件:
export AGENTSHELL_SESSION_ID=$(uuidgen)
npm run lint && npm test && npm run build
# All three events share the same session_id
范围
- npm只 -通过
.npmrcscript-shell. 不支持其他包管理器(yarn、pnpm、bun)。 - POSIX只 —macOS和Linux。Windows需要WSL或Git Bash。
故障排除
NPM失败,提示“script-shell not found”
你的 .npmrc 参考文献 agent-shell 但它不是全球安装的:
# Fix: install the package globally
npm install -g @lousy-agents/agent-shell
# Or: bypass temporarily
AGENTSHELL_PASSTHROUGH=1 npm test
绕过所有仪表
设置直通逃生舱口-零架空,零记录:
AGENTSHELL_PASSTHROUGH=1 npm test
完全移除仪表
删除 script-shell 行 .npmrc:
# Edit .npmrc and delete this line:
# script-shell=agent-shell
# Or remove it with sed:
sed -i '' '/script-shell/d' .npmrc
然后可选卸载:
npm uninstall -g @lousy-agents/agent-shell
验证垫片是否处于活动状态
npx agent-shell --version
清理记录的事件
rm -rf .agent-shell/
.gitignore
添加 .agent-shell/ 到你的 .gitignore:
# agent-shell telemetry
.agent-shell/