omp packages

pi-subagent-permission-compat0.1.0

Parent-session compatibility and cwd permission checks for almost any Pi subagent extension with @gotgenes/pi-permission-system

gszj2018 Published 1 month ago MIT ~217 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-subagent-permission-compat

English | 简体中文

一个面向第三方子智能体(subagent)扩展的 Pi Coding Agent 兼容性补丁包,提供两项彼此独立的能力:

  1. 父会话环境兼容 —— 为根会话进程写入 PI_SUBAGENT_PARENT_SESSION,使继承该环境的子智能体子进程能够将权限询问回传到父会话。
  2. 子智能体 cwd 防护 —— 检查子智能体工具调用输入中的 cwd 值,当某个值与当前工作目录不一致时,请求一次性批准。

权限扩展兼容性

  • 本扩展用于兼容 @gotgenes/pi-permission-system:它会写入上述 PI_SUBAGENT_PARENT_SESSION 变量。详见其子智能体集成文档。
  • 简言之,对于未自行遵守该约定的子智能体扩展,本扩展提供兼容性补丁。
  • 本包不安装、不导入、也不查询该权限扩展,cwd 防护也不以其为前提。
  • 只有该权限扩展自身已安装并启用时,这种配合才会实际生效。

两项能力始终开启且无需配置:本包不新增任何命令、工具、配置文件或持久化规则。

功能

1. 父会话环境兼容

在 session_start 时,如果当前进程是根会话,扩展会写入:

PI_SUBAGENT_PARENT_SESSION=<当前会话 ID>

继承该环境的子进程据此可以定位父会话。

出现以下任一情况时跳过写入:

  • 环境中已存在第三方子智能体标记,说明当前进程本身就是子智能体子进程。
  • 环境中已声明父会话。

该值会在 session_shutdown(例如 /new、/resume、fork 或 /reload)时移除,避免会话切换后残留旧会话 ID。只有本扩展写入的值才会被移除;由其它组件设置或改写过的值保持不变。

确切的常量清单见可识别的环境变量。

2. 子智能体 cwd 防护

工具名中包含 subagent、delegate、spawn 或 agent(不区分大小写)的工具调用会被检查,输入树中任意位置发现的每个 cwd 字段都会被判定:

cwd 值 结果
缺失、null 或 "" 直接放行
与当前目录完全相同的非空字符串 直接放行
与当前目录不同的非空字符串 弹出批准提示(Deny / Allow once)
其它类型(数字、布尔值、对象、数组等) 弹出批准提示(Deny / Allow once)
无法安全扫描的输入 硬性拦截,用户无法批准

行为说明:

  • 比较方式为原始字符串严格相等:工具输入与当前目录均不做 trim、归一化或改写。详见注意事项与限制。
  • 一次提示覆盖整个工具调用,并列出所有发现的 cwd,包括嵌套位置,例如 $["tasks"][0]["cwd"]。
  • 批准仅对当次调用有效。不写入任何规则、不持久化,因此下次相同调用仍会再次询问。
  • 只有精确选择 Allow once 才算批准。选择 Deny、取消提示、提示被关闭、返回未知响应或提示本身出错,都会拦截该调用。
  • 没有交互 UI 时(print/JSON 模式,或无 UI 的子智能体),任何 ask 都会直接拦截而不弹窗。
  • 批量或链式子智能体参数会作为一个调用整体判定:只要有一个 cwd 未获批准,整个调用即被拦截。

安装

作为 Pi 包安装:

# 从 npm 安装
pi install npm:pi-subagent-permission-compat

# 从本 GitHub 仓库安装
pi install git:github.com/gszj2018/pi-subagent-permission-compat

使用

安装后两项功能即自动生效,无需按会话启用,也无需任何配置。

  • 父会话环境兼容 —— 无需配置。若同时使用权限扩展,参见上文说明。
  • 子智能体 cwd 防护 —— 无需配置。在交互式会话中,若子智能体工具调用使用的工作目录不同,会逐次询问,由你选择 Allow once 或 Deny。

可识别的环境变量

确切的变量列表由 extensions/parent-session-env.ts 中导出的常量定义:

  • THIRD_PARTY_SUBAGENT_ENV_HINTS —— 第三方子智能体扩展在子进程内写入的标记,任一项存在即视为子智能体子进程并跳过写入。
  • SUBAGENT_PARENT_SESSION_ENV_CANDIDATES —— 已携带父会话声明的变量,任一项存在时本扩展不改动环境。
  • PARENT_SESSION_ENV_VAR —— 本扩展唯一写入的变量。

"存在"指变量已被定义:空字符串、空白、"0"、"false" 都视为已设置,因此既有声明始终优先,本扩展不会改写它们。

如果宿主提供的会话 ID 为空白等不可用值,扩展会给出警告通知且不写入变量,cwd 防护继续正常工作。

注意事项与限制

  • cwd 防护不是沙箱。它只检查当次工具调用输入中可见的 cwd 字段,无法限制子智能体后续的行为。
  • 工具名采用宽松匹配。名称中仅含 agent 的无关工具也可能被检查,而名称不含这些关键字的子智能体启动工具则不会被检查。
  • 智能体配置中的默认工作目录、工具内部创建的 worktree、后续目录变更以及包装器内部的调用均不在覆盖范围内。
  • 比较是原始字符串严格相等,而不是"相同真实目录"。大小写差异、尾部分隔符或重复分隔符、./.. 段、反斜杠与斜杠差异、首尾空白、相对与绝对写法都会触发提示而不会被自动放行;link/.. 这类路径也不会被静默接受。若两侧字节完全相同,即使是非规范字符串也会放行。
  • cwd 缺失、为 null 或 "" 时按设计放行。这是便利性处理,不能证明调用方确实使用了当前目录。
  • 无法安全扫描的输入——嵌套超过 10 层容器、不是普通 JSON 对象或数组的容器、异常的数组键或不可读成员——一律硬性拦截,用户无法批准。
  • 没有交互 UI 时(print/JSON 模式或无 UI 的子智能体)不会弹出询问,而是直接拦截;本扩展没有其它批准途径。
  • 批准是一次性的,且仅存在于本扩展内:不在会话内缓存、不向其它扩展共享。其它扩展仍可能拒绝同一个调用。
  • 环境写入只覆盖继承环境的子进程(例如直接 spawn/fork)。替换过环境的进程、常驻守护进程、远程启动,以及共享同一 process.env 的进程内子智能体均不在覆盖范围内。

开发

# 安装依赖
npm install

# 运行测试
npm test

# 类型检查
npm run typecheck

如需在本地开发时直接加载扩展(无需打包),请在仓库根目录运行:

pi -e ./extensions/index.ts

项目使用 TypeScript 编写,测试采用 Node.js 内置测试运行器。

项目结构

pi-subagent-permission-compat/
├── extensions/
│   ├── index.ts                   # 扩展入口(仅做组合装配)
│   ├── extension-meta.ts          # 公共扩展标识
│   ├── feature-parent-session.ts  # 父会话生命周期注册
│   ├── feature-cwd-guard.ts       # 工具调用注册与批准流程
│   ├── parent-session-env.ts      # 环境检测与 owned-value 清理
│   ├── cwd-ident.ts               # 工具名匹配
│   ├── cwd-inspection.ts          # cwd 收集
│   ├── cwd-guard.ts               # 逐值判定与拦截决策
│   ├── cwd-prompt.ts              # 提示格式化与 select 批准
│   └── diagnostics.ts             # 安全的值/错误展示辅助
└── tests/                         # 单元测试与集成测试

开源许可

MIT