Metadata-Version: 2.4
Name: bensz-router
Version: 1.1.8
Summary: Public CLI and Harness adapters for the bensz-router Agent Workflow API
Author: bensz-router contributors
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: keyring>=24
Provides-Extra: test
Requires-Dist: build>=1; extra == "test"
Requires-Dist: keyring>=24; extra == "test"

<div align="center">

# bensz-router Python 客户端

[![Python](https://img.shields.io/badge/Python-3.9%2B-blue?style=flat-square)](https://pypi.org/project/bensz-router/1.1.8/) [![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)](https://pypi.org/project/bensz-router/1.1.8/)

**在自己的 Codex 或 Claude Code 中发现并执行版本化工作流。**

[English](README_EN.md) · [PyPI](https://pypi.org/project/bensz-router/1.1.8/) · [Skill 指南](skills/bensz-router/README.md)

</div>

`bensz-router` 1.1.8 提供 Python SDK、CLI、Harness adapter 与公开 Agent Skill，可从 PyPI 安装。服务端负责目录、设备授权和步骤契约；客户端在自己的 Codex 或 Claude Code 中使用本地工具与模型执行。需要 Python 3.9+ 和可用的系统 keyring。

1.1.8 是与服务端 `2.5.10` 对齐的维护版本，SDK、CLI、adapter 与公开 Skill 行为不变；默认 `native` 提醒、按需激活、一会话一次预检、一次提醒输出及失败开放边界保持原样。合成传输检查不能代替实际 IDE 可见性验收。

从安装到首次任务的完整说明见[使用教程](https://router.benszresearch.com/tutorial.zh-CN.md)；自建站点使用同站点的教程地址。


原生通知在部分宿主中不可见。若用户接受提醒进入模型上下文，可在原 scope 显式安装 `--notice-channel assistant`：hook 只在首次有效送达时要求 AI 在下一条进度消息中原样展示一次，之后继续任务。默认 `native` 保持隔离，升级保留通道，不自动切换、不在同会话补发。`--notice-language off` 对两种通道均生效。提醒展示必须在实际目标 IDE 验收；配置注册、函数返回、模型自报和合成模型输出均不能证明用户已看到。

## 安装与登录

```bash
python3 -m pip install --upgrade bensz-router==1.1.8
bensz-router --version
bensz-router skill sync --harness all
bensz-router skill status --harness all --json
bensz-router hooks install --harness codex --scope user
bensz-router hooks doctor --harness codex --scope user --json
bensz-router login --harness codex
bensz-router catalog --json
```

设备登录打开浏览器授权页，批准后把短期 `brw_` Token 保存到系统 keyring。Claude Code 用户使用 `--harness claude-code`。CLI 默认地址为 `https://router.benszresearch.com`；`--server <地址>` 优先于 `BENSZ_ROUTER_URL`，登录和预检须使用同一站点。

也可运行 `uv tool install bensz-router==1.1.8`。在 Harness 的 Shell 中执行 `command -v bensz-router` 检查路径；macOS 图形界面启动的 Harness 可能缺少终端 PATH，Skill 会有界检查用户级与 Homebrew 命令目录。keyring 不可用时命令明确失败，不保存明文凭据。

`bensz-router --version`（或 `-V`）无需登录或联网，预期输出 `bensz-router 1.1.8`。持有源码的开发者也可在仓库根目录使用 `uv tool install --force ./packages/bensz-router` 安装本地版本。

安装后执行 `bensz-router skill status --harness all --json`，确认 Codex 与 Claude Code 的公开 Skill 状态均为 `synced`。

## 发现与预检

```bash
bensz-router catalog --json
bensz-router profiles --json
# AI 根据公开元数据选择模板，再提交 ID；不传用户 Prompt
bensz-router preflight --harness codex --selected-template-id software-development --manifest
bensz-router workflow list
bensz-router workflow hide <workflow-id>
bensz-router workflow show <workflow-id>
```

AI 在默认智能方案候选范围内本地选择工作流，服务器复核权限、依赖、冲突与版本。`--manifest` 提供可见应用清单，`--json` 用于机器读取；同时指定时 manifest 优先。模板 ID 必须来自当前目录。 提醒、清单标题及结束标记使用管理员配置的站点名称（服务端响应的 `site_name`）；旧服务端缺少名称时显示“工作流服务”。

新增要求从完整契约有效进入当前任务上下文后约束后续相关动作，以消息顺序判断；首次落实不追溯判错，回读、恢复或重复送达不重置边界，不抹去真实遗漏。既有持续约束和安全授权保留，缺失现实前置条件不得伪造补齐。首次衔接可复用生效前准确 Skill 名称与本任务用途完整的说明，生效后新说明仍按列表格式。目录候选、激活回执、预检命中和 hook 输出不单独证明宿主接收，普通 stdout 不构成受管注入；时序或证据不足标为未验证。

成功命中的预检记录表示契约已返回，不证明任务完成。Harness 应逐项执行、核对证据；无匹配、无权限或远程不可用时有界停止并继续原任务。客户端拒绝 HTTP 重定向，不转发凭据。

## Harness 接入与恢复

自 1.1.5 起支持以下激活策略；升级保留旧安装的全局模式。新 hooks 安装默认采用按需模式 `on-demand`：普通聊天、名称提及、原理咨询、维护本项目、引用示例或否定使用均不激活；只有明确调用 Skill（如 `$bensz-router`）或要求 router 参与当前任务时，才开始工作流发现。未激活时不读取 keyring、不请求远程目录、不预检或提醒。MCP 先调用空参 `activate()`；Shell hooks 先独立执行 `bensz-router session activate --harness codex`（Claude 改为 `claude-code`）。工具仅返回本地请求回执，PostToolUse 根据真实宿主事件建立绑定并提供原样 `session_ref`；回执不代表绑定、命中或正文送达。缺少可信引用时停止受管增强并继续原任务；无 hooks 的基础 CLI 不制造引用。

希望会话自动预检时，在原 scope 显式运行 `bensz-router hooks install --harness codex --scope project --activation-mode global`；切回按需使用 `--activation-mode on-demand`。模式与 `transport=mcp|shell`、`scope=user|project` 独立；不传参数时保留同 scope 已保存选择，有所有权但未记录模式的旧安装兼容为 `global`，全新安装才默认按需。另一 scope 已有 router 注册时报告冲突；在原 scope 操作，不自动修改另一 scope 或覆盖第三方配置。重载后的新会话采用新模式；旧上下文无法清除，同会话仍至多一次预检，明确结束或切换后不能重新激活路由。

1.1.2 起 Codex 自动接入已内置：运行 `hooks install` 即可补齐缺失的固定名称 MCP，以当前环境绝对入口验证本地启动及全部所需工具后再安装 hooks；重复安装幂等，`--dry-run --json` 仅预演，已有禁用、过滤、站点/入口冲突配置保留并明确报告。`hooks doctor` 的 `mcp.status` 区分未注册、已禁用、配置冲突、工具过滤与启动失败，缺失或失败返回非零，并提示 IDE 重载。配置通过后仍须重启 Codex；IDE 用 `Restart extension` 或 `Developer: Reload Window`，再新建会话核验工具。1.1.1 及更早版仍需下面的独立注册步骤。

自动注册不适用（例如非标准环境）或使用 1.1.1 及更早版时，可手动注册固定服务名 `bensz_router`：

```bash
codex mcp add bensz_router -- bensz-router --server https://router.benszresearch.com mcp --harness codex
```

然后安装 hooks、在 `/hooks` 审核信任，并新建会话在 `/mcp` 核对工具。MCP 注册是用户级配置；不要在参数中写凭据。AI 在按需激活并取得可信引用后使用专用 `catalog`、`profiles`、`preflight` 工具，以原样 `session_ref` 选择一次工作流；PostToolUse 只匹配该服务的受管工具，普通 Shell 不触发 router。生命周期和子代理隔离 hooks 保留。受保护步骤用同名 `run`、`current`、`advance` 工具，结束或切换任务用 `release`；工具仍遵守宿主审批。

Claude 沿用 Shell 接入；Codex 显式加 `--transport shell` 可回退。下述独立单行 CLI 规则仅适用于 Shell 模式，MCP 模式无需在普通工具前后检查 router。已有 hooks 必须在原 scope 重复安装，避免旧用户级 Bash hooks 继续触发；配置注册不证明 MCP 可用或正文已送达。

```bash
bensz-router hooks install --harness codex --scope project --dry-run --json
bensz-router hooks install --harness codex --scope project
bensz-router hooks doctor --harness codex --scope project --json
```

Codex 需通过 `/hooks` 信任。hooks 提供跨进程单次预检、认证/项目/子代理隔离和当前契约恢复；全局 SessionStart 或按需激活 PostToolUse 给出的 `--session-ref` 必须原样传入受管命令。Codex 接入 developer 上下文，Claude hooks 接入 system reminder。配置注册不代表实际送达或执行完成。

每个受管 `session activate`、`preflight`、`run`、`current`、`advance` 或 `session release` 必须是一次 Shell 调用中的唯一单行命令，使用确认过的 CLI 路径、字面参数并保留完整输出。组合 `cd`、变量、管道、重定向或其他命令会阻断 hook 桥接核验。

Codex 的受管上下文 handler 设置 `additionalContextLimit: 0`，完整传入正文，adapter 不设正文长度上限。更新包后按原 scope 重复执行 `hooks install` 并在 `/hooks` 审核新定义，已有配置才会获得该设置。Claude 上下文仍限制为 9,000 字符，超限明确降级。

受保护工作流必须以预检的 `resolution_id` 启动，再读取或显式推进本人运行：

```bash
bensz-router run <workflow-id> --harness codex --resolution-id <resolution-id>
bensz-router current <run-id>
bensz-router advance <run-id> <step-id> --outcome completed
```

受管命令另加 `--session-ref <session-ref>`；任务结束或切换用 `session release`，本地文件条件用 `session verify --require-file <项目内相对文件>`。这些检查不替代质量判断。`claude-start` 只用于新会话的固定 system 快照；hooks 无法删除宿主历史指令。详见 [Harness 接入](https://github.com/huangwb8/bensz-router/blob/main/docs/harness-hooks.md)（需要私有仓库访问权限）。


客户端支持 Claude Code 可选 MCP 接入，直接从 PyPI 安装即可使用。在用户级注册固定名称 `bensz_router` 的服务，并切换同一 scope 的 hooks：

```bash
claude mcp add --scope user --transport stdio bensz_router -- bensz-router --server https://router.benszresearch.com mcp --harness claude-code
bensz-router hooks install --harness claude-code --scope user --transport mcp
```

新建 Claude 会话后在 `/mcp` 确认连接。Claude 的默认接入仍为 Shell；选择 MCP 后普通 Shell 不触发 router，正文仍通过 system reminder 送达并保留 9,000 字符预算。

### 工作流提醒通道

默认 `native` 模式的工作流提醒由 hooks 的 `systemMessage` 输出，执行正文保留在 `additionalContext`；AI 不补播提醒。按原 scope 安装 hooks 时可设置 `--notice-language zh-CN|en|off`，升级保留选择，默认中文。同会话同解析只记录一次通知输出尝试，不能证明用户已看到。Codex CLI 0.153.4 的 `exec --json` 未呈现通知；Claude Code 2.1.205 仅 startup 通知事件可见，PostToolUse 通知未呈现，实际 IDE 可见性需独立验证。旧会话的提醒不能删除，新配置需在新会话加载。

## 管理自动化与安全

```bash
bensz-router automation login
bensz-router automation capabilities --json
bensz-router automation validate workflow.json --json
bensz-router automation save-draft workflow.json --base-revision 3 --json
bensz-router automation approve brp_example --json
bensz-router automation batch-approve brp_first brp_second --json
```

管理员在管理台“API 密钥”创建 `brm_`，由隐藏输入保存到独立 keyring 并交换短期 `bra_`。默认 Workflow 预检不使用管理凭据；管理失败立即停止，候选版本不会自动激活。 工作流审批只走管理员 API，不使用浏览器 Cookie/CSRF；授予 `proposals:approve`，或保留已有完整写权限组合 `workflows:versions:publish`、`proposals:create` 和 `proposals:read`。管理协议与审批见 [管理自动化](https://github.com/huangwb8/bensz-router/blob/main/docs/workflow-management-automation.md)（需要私有仓库访问权限）。

默认不上传用户 Prompt、历史上下文或本地文件正文；服务端只记录低敏状态。已下发正文可能保存在宿主历史。外部副作用始终需人工确认；`bug-report --scan` 仅在明确授权时上传同目录配对的 `bug-context.json` 与 `BUG_REPORT.md` 脱敏记录。

## 开发与许可证

持有源码的开发者在包目录执行：

```bash
uv sync --frozen
uv run python -m pytest tests -q
```

Skill 源码位于 `skills/bensz-router`，随包分发；`skill sync` 支持首次安装、更新和 `--dry-run`，`skill status --json` 检查漂移。SDK 入口为 `bensz_router.client.WorkflowClient`。本包采用 MIT License。
