personal-bot 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,229 +1,84 @@
1
- # npx 安装与升级设计
1
+ # 安装器设计
2
2
 
3
- 本页的独立 `pbot setup` 面向 Pi。dsh 使用原生 Web profile 与插件安装流程,见[dsh 使用说明](dsh.md);不增加配置同步、安装登记或工作区升级机制。
3
+ `pbot setup` 在 Linux 和 macOS 上为一个工作区安装或更新 Pi、Personal Bot 和选定插件,再启动 Pi 执行 `/pbot init`。用户命令见[项目 README](../README.zh-CN.md#安装)。dsh 使用自己的[插件与 profile 流程](dsh.md)。
4
4
 
5
- 状态:方案已确认并实现。命令需使用包含该实现的发布包;当前源码可先执行 `npm run build:cli`,再运行 `node bin/pbot.mjs setup`。验证结果与剩余验收见[验证](validation.md)。
6
-
7
- 目标是在 Linux 和 macOS 上,通过一个交互式入口安装或升级 Pi、为一个工作区安装 Personal Bot 和选定的配套插件,再启动 Pi 执行 `/pbot init`。这里的安装路径服务于 Pi 扩展;安装命令只负责环境准备和启动。
8
-
9
- ## 命令与分发
10
-
11
- npm 包继续使用 `personal-bot`,增加名为 `pbot` 的可执行入口。npm 上的 `pbot` 已属于其他项目,包名与命令名无需一致。
12
-
13
- ```bash
14
- npx personal-bot@latest setup
15
- npx personal-bot@latest setup --workspace ~/pbot-workspace
16
- ```
17
-
18
- 首次安装和后续升级使用同一个 `setup` 子命令。无子命令时显示帮助;`--workspace` 省略目录选择,但仍保留插件选择和安装计划确认。首版是终端交互流程,重定向输入时明确提示需要交互终端,不猜测选择或启动模型。
19
-
20
- 需要长期使用短命令时,用户可另行安装:
21
-
22
- ```bash
23
- npm install -g personal-bot@latest
24
- pbot setup
25
- ```
26
-
27
- npx 不自动全局安装自身。全局安装只提供命令入口,不向 Pi 注册全局 pbot 扩展。`pbot setup` 使用全局安装的安装器版本;更新此入口使用 npm,或直接运行 `npx personal-bot@latest setup` 获取最新安装器。工作区中的 pbot 扩展与全局命令副本分别更新。
28
-
29
- 首版只提供 `setup`、帮助和版本信息。以后按实际需求增加子命令。
30
-
31
- ## 范围与所有者
32
-
33
- | 对象 | 范围与责任 |
34
- | --- | --- |
35
- | Node.js/npm | 运行 npx 的前提;最低 Node.js 22.19,目标软件有更高要求时提示先升级 |
36
- | Pi 主程序 | 当前用户共用一份;首次通过 npm 安装,已有安装沿用原生升级机制 |
37
- | pbot 扩展 | 所选工作区必装;已有自定义来源可选择保留 |
38
- | 配套插件 | 维护者提供候选清单,用户选择;安装到所选工作区 |
39
- | tmux | 独立专家与团队协作的强依赖;缺失时通过已有系统包管理器安装 |
40
- | 基础 Python | 检查 Python 3.11+、venv 和 ensurepip;缺失时提供指引 |
41
- | 共享 Python venv | pbot 加载时按现有逻辑准备,安装器不维护另一份环境 |
42
- | 工作区资料 | 启动 Pi 后交给 `/pbot init` 补建;已有内容按现有命令规则保留 |
43
- | 模型、认证、项目信任 | 使用 Pi 原生流程与已有配置 |
44
- | 插件依赖的外部服务 | 由插件自己的使用与配置流程处理 |
45
-
46
- 安装器每次处理一个目录。目录选择支持当前目录、输入已有目录和创建新目录,不建立工作区列表、注册表、格式版本或启用标记。新目录可由安装器创建;其中的资料目录和资料文件由 pbot 创建。Pi 原生包管理仍可创建 `.pi/settings.json` 及其安装目录。
47
-
48
- 升级共享 Pi 会影响其他工作区后续启动。更换 pbot 版本前遵循现有规则,停止活动子会话;安装器不代替用户强行终止任务。已有资料、历史记录、源码和备份保留。
49
-
50
- ## 交互流程
5
+ ## 流程与责任
51
6
 
52
7
  ```mermaid
53
8
  flowchart TD
54
- A[运行 setup] --> B[检查平台、Node/npm 和基础 Python]
55
- B --> C[选择或创建工作区]
56
- C --> D[读取原生安装状态与来源]
57
- D --> E[选择插件与自定义来源的处理方式]
58
- E --> F[展示安装计划并确认]
59
- F --> G[补装 tmux,安装或升级 Pi]
60
- G --> H[安装或升级工作区 pbot]
61
- H --> I[逐项处理选中的配套插件]
62
- I --> J[核对实际版本与安装结果]
63
- J --> K[选择是否启动 Pi,默认启动]
64
- K --> L[Pi 原生信任与扩展加载]
65
- L --> M[执行 /pbot init,保留交互会话]
9
+ A[检查平台、Node/npm 与基础 Python] --> B[选择或创建工作区]
10
+ B --> C[读取 Pi 原生配置与包来源]
11
+ C --> D[选择插件与来源处理方式]
12
+ D --> E[展示并确认安装计划]
13
+ E --> F[补装 tmux,安装或更新 Pi]
14
+ F --> G[安装或更新工作区 pbot]
15
+ G --> H[逐项处理可选插件并汇总结果]
16
+ H --> I[选择是否启动 Pi]
17
+ I --> J[Pi 处理项目信任并执行 /pbot init]
66
18
  ```
67
19
 
68
- 基础 Python 不满足要求时,在软件变更前说明缺项并结束本次 setup。tmux 安装、Pi 或 pbot 处理失败时,不继续启动 Pi。插件失败可继续处理其他插件,汇总后让用户选择是否先进入 Pi。
69
-
70
- 安装计划展示工作区绝对路径、检测到的 Pi 可执行路径、当前版本、目标版本、选中的插件、保留的自定义来源,以及需要执行的系统软件安装。已有 Pi 的更新方式由原生 `pi update` 决定,计划不另行展示其安装渠道。用户完成一次计划确认后执行所列操作;系统提权与 Pi 信任仍使用各自原生交互。若没有 Pi、但已有原生插件声明,安装器先展示 Pi 目标版本并确认安装 Pi,再使用其原生接口读取已有来源,继续插件选择和计划确认;不猜测 Git 缓存或把已有配置当作空白。
71
-
72
- 执行结果分别说明已完成、保留、跳过和失败。退出安装阶段时不把“包安装成功”写成“模型、Python 计算或外部服务已可用”。
73
-
74
- ## 插件清单
20
+ 安装器需要交互终端。`--workspace` 省略目录选择,仍保留插件选择和计划确认。计划列出工作区、Pi 路径、当前与目标版本、插件、自定义来源及系统安装项。系统提权、项目信任、登录和模型选择使用原生交互。
75
21
 
76
- pbot 本体作为固定必需项,不混入可选插件清单。首版候选为:
77
-
78
- | 插件 | 来源 | 首次安装默认值 | 安装后的边界 |
79
- | --- | --- | --- | --- |
80
- | Task Conductor | `npm:task-conductor-plugin` | 勾选 | 安装接入插件;服务、setup 和 MCP 接入另行完成 |
81
- | Pi Web Access | `npm:pi-web-access` | 勾选 | 安装搜索与内容获取插件;复用插件默认行为及已有配置 |
82
-
83
- 维护者通过一份随包发布的静态清单调整候选项,位置为 `resources/installer/plugins.json`:
22
+ | 对象 | 处理方式 |
23
+ | --- | --- |
24
+ | Node.js/npm | 前置检查,最低 Node.js 22.19;目标软件有更高要求时先升级 |
25
+ | Pi | 当前用户共享;缺失时通过 npm 安装,已有持久安装调用原生 `pi update` |
26
+ | pbot 与可选插件 | 安装到所选工作区,使用 Pi 原生包管理 |
27
+ | tmux | 已有时复用;缺失时通过已有 Homebrew、apt、dnf、pacman、zypper 或 apk 安装 |
28
+ | Python | 检查 3.11+、venv 与 ensurepip;共享 venv 由 pbot 加载时准备 |
29
+ | 工作区资料 | 由 `/pbot init` 补建,保留已有内容 |
30
+ | 插件的外部服务 | 按对应插件的安装与配置流程处理 |
84
31
 
85
- ```json
86
- [
87
- {
88
- "id": "task-conductor",
89
- "label": "Task Conductor",
90
- "description": "周期任务、流程和 DAG 的接入与使用引导",
91
- "source": "npm:task-conductor-plugin",
92
- "defaultSelected": true
93
- },
94
- {
95
- "id": "web-access",
96
- "label": "Pi Web Access",
97
- "description": "网页搜索与内容获取",
98
- "source": "npm:pi-web-access",
99
- "defaultSelected": true
100
- }
101
- ]
102
- ```
32
+ 基础 Python 检查失败时,在软件变更前退出。系统适配器只安装 tmux,提权交给原生终端。升级共享 Pi 会影响其他工作区的后续启动;更换 pbot 版本前先停止活动专家。
103
33
 
104
- 清单只保存选择所需的元数据,不包含脚本、安装钩子、运行状态或插件专用执行逻辑。普通 npm Pi 插件只需增加清单项。安装器不提供插件市场、动态发现或用户维护清单的入口。
34
+ ## 插件选择
105
35
 
106
- 首次安装 pbot 时,两项默认勾选。已有 pbot 时,按当前实际安装情况预选;后来新增的候选不会自动加入。取消勾选已安装插件表示本次不处理,不卸载也不禁用。移出维护者清单的插件不再由安装器安装或升级,已有副本保留。
36
+ `resources/installer/plugins.json` 保存候选插件的 id、名称、说明、来源和首次默认选择。pbot 是必需项;Task Conductor 与 Pi Web Access 在首次安装时默认勾选。
107
37
 
108
- 安装状态从 Pi 原生配置和实际包中取得,不另外持久化“安装器管理过哪些插件”。无法读取配置时报告错误,不当作全新工作区。
38
+ 已有 pbot 时按实际安装情况预选。新增候选不会自动加入;取消勾选或移出候选清单均保留现有安装。配置与安装状态来自 Pi,安装器不另建注册表。
109
39
 
110
40
  ## 版本、来源与作用域
111
41
 
112
- Pi、pbot 和选中的普通 npm 插件各自采用最新稳定版,不维护经过配套验证的固定版本组合。安装时显示当前版本和实际目标版本,结束后核对真正安装的版本。网络查询失败不能解释成“已经最新”;包版本可用也不证明整个组合已通过功能验收。
42
+ Pi、pbot 和选中的普通 npm 插件使用最新稳定版,安装结束后核对实际版本。网络查询失败时报告错误。
113
43
 
114
- | 已有状态 | setup 的行为 |
44
+ | 已有来源或状态 | 行为 |
115
45
  | --- | --- |
116
- | 没有 Pi | 使用 npm 安装官方 `@earendil-works/pi-coding-agent`,核对可执行路径和版本 |
117
- | 已有持久安装的 Pi | 调用其原生 `pi update`;不支持自动更新时给出原安装方式的指引 |
118
- | 缺少工作区 pbot 或选中的插件 | 使用 Pi 原生本地安装 |
119
- | 普通 npm 来源 | 对所选工作区安装最新稳定版并核对结果 |
120
- | 本地源码、Git、固定版本或自定义版本范围 | 展示“保留”与“切换到 npm 最新稳定版”,默认保留 |
121
- | 清单外或本次未选中的插件 | 保持其原生声明,本次不安排升级或卸载 |
122
- | 配置损坏或来源无法辨认 | 在读取阶段停止 setup,保留配置并说明需修复的来源 |
123
- | 已识别包存在未解决的重复加载 | 说明冲突,停止受影响项,不自动重置配置 |
124
-
125
- Git 或本地目录来源必须存在,并能从 package.json 取得非空包名。目录缺失、包清单缺失或没有可识别包名时,无法排除它与待安装包重复,须先通过 Pi 原生配置恢复或修正来源;安装器不删除旧声明或追加 npm 来源。独立的单文件扩展按原生声明保留;npm 声明可直接提供包身份,无须预先安装。执行阶段每次重新检查来源时也应用同一规则。
46
+ | 普通 npm 来源 | 更新所选工作区的包 |
47
+ | 本地源码、Git、固定版本或自定义范围 | 默认保留,可显式选择切换到 npm 最新稳定版 |
48
+ | 未选中的插件 | 保留声明和安装 |
49
+ | 配置损坏、来源无法辨认或重复加载 | 停止受影响步骤,保留配置并给出修复入口 |
50
+ | 用户级与项目级同名 npm 包 | 遵循 Pi 原生覆盖规则,保留用户级副本 |
126
51
 
127
- “保留”表示继续使用原有来源,不宣称它已升级到最新。选择切换后,只处理已明确选定的原声明与目标声明;保留源码目录和历史数据。不能在当前工作区内完成替换时,给出 Pi 原生操作指引,避免通过修改用户级声明影响其他工作区。
52
+ Git 和本地目录必须存在,且 package.json 有有效包名;独立单文件扩展按原生声明保留。来源校验在计划和执行时都进行。切换仅修改已选定的声明,保留源码目录、历史及无关配置。
128
53
 
129
- 所有插件变更显式限定所选工作区。Pi 1.5 的 `pi update <source>` 会同时匹配用户级和工作区配置,且不支持 `--local`,因此不直接用它实现本安装器的工作区插件升级。普通 npm 包通过以下形式交给 Pi 安装:
54
+ 工作区包更新使用 `pi install --local npm:<package>@latest`。Pi 的 `pi update <source>` 同时匹配用户级和项目级配置,安装器不将它用于项目插件更新。首次用项目声明覆盖同名全局 npm 包时继承原资源过滤;已有项目过滤同样保留。
130
55
 
131
- ```bash
132
- pi install --local npm:personal-bot@latest
133
- pi install --local npm:task-conductor-plugin@latest
134
- pi install --local npm:pi-web-access@latest
135
- ```
56
+ 真实 Pi 安装须与 npx 临时缓存区分。没有 Pi 但已有包声明时,先确认安装 Pi,再使用其 SDK 读取来源。全局目录不可写、PATH 异常或无法在项目范围内切换来源时,提供原生修复步骤。
136
57
 
137
- 上述命令在所选工作区执行,并按实际选择逐项调用。`latest` 用于请求当前稳定标签,保留用户已有的资源过滤配置。首次用工作区声明覆盖同身份的全局 npm 包时,将原有资源过滤继承到工作区,全局声明保持不变。必要的来源切换使用原生设置机制,不重建整个 settings 文件。底层包管理器可能重新解析共享依赖,因此验收应检查已有声明与资源过滤保持正确,不能承诺安装目录中所有依赖文件完全不变。
58
+ ## 启动与恢复
138
59
 
139
- 同一个 npm 包同时存在于用户级与工作区时,遵循 Pi 的原生覆盖规则,不更新用户级副本。本地源码、Git 与 npm 是不同身份,切换时必须核对有效加载来源,避免同时加载两份。
60
+ 用户选择启动后,子进程以工作区为 cwd 并继承终端,执行 `pi "/pbot init"`。Pi 完成项目信任和扩展加载后分发命令,初始化结束仍留在同一交互会话。
140
61
 
141
- 安装器必须区分真实 Pi 安装与 npx 临时缓存内的可执行文件;后者不能作为已经安装了持久 Pi 的证据。npm 全局目录不可写或 PATH 无法解析目标程序时,显示明确修复指引,不隐式迁移已有安装或覆盖无关命令。
62
+ 本次启动临时加载 `setup-guard`:若 `/pbot init` 未被注册命令处理,拦截该输入并请求 Pi 关闭,避免落入模型请求。引导文件缺失时不启动 Pi。资料创建和 Python 准备仍由 pbot 各自报告。
142
63
 
143
- ## 系统依赖
144
-
145
- tmux 存在且可执行时直接复用;缺失时使用机器已有的受支持包管理器。系统包版本遵循发行版仓库,不由 pbot 维护另一套 tmux 版本。
146
-
147
- | 平台 | 自动补装渠道 |
64
+ | 情况 | 后续处理 |
148
65
  | --- | --- |
149
- | macOS | 已安装的 Homebrew |
150
- | Linux | 显式适配的 apt、dnf、pacman、zypper、apk |
151
-
152
- 适配器只执行安装 tmux 所需的命令;不安装包管理器、不添加软件源、不顺带升级系统。需要权限时交给终端原生提权。不存在支持的包管理器或安装失败时,保留已完成步骤,提示手动完成后重跑 setup。
153
-
154
- Python 检查沿用 pbot 的解释器选择方式:优先 PATH 中的 `python3`,其次 `python`,确认版本和创建 venv 所需能力。安装器不改系统 Python,不创建共享 venv。pbot 加载后使用现有共享锁、锁定依赖和失败重试逻辑准备环境。失败由 pbot 显示,可继续使用其他能力并按既有方式重试;不改成新的工作区启用条件。
66
+ | 必要环境、tmux、Pi 或 pbot 失败 | 停止依赖步骤并显示修复方法 |
67
+ | 可选插件失败 | 继续其他插件,汇总后由用户选择是否启动 Pi |
68
+ | 下载中断或用户取消 | 保留已完成步骤;重跑时重新读取实际状态 |
69
+ | Pi 启动、初始化或 Python 准备失败 | 按所属组件的错误处理,保留安装结果 |
155
70
 
156
- ## 启动与初始化
71
+ 各包管理器独立执行,安装器不做整体回滚或删除环境来重试,也不保存安装完成标记。选择进入 Pi 后,失败的可选插件仍记为失败。
157
72
 
158
- 完成安装阶段后提供“立即启动 Pi”,默认选择启动。启动时将子进程 cwd 设为所选工作区,继承终端,不试图修改父终端目录。
159
-
160
- 正常启动语义为在该目录运行:
161
-
162
- ```bash
163
- pi "/pbot init"
164
- ```
165
-
166
- Pi 先处理项目信任和扩展加载,再分发启动输入。pbot 命令成功注册时,`/pbot init` 直接执行命令处理器,不需要模型认证或模型调用。初始化完成后留在同一 Pi 交互会话,登录与模型选择交给 Pi。重复 setup 后仍使用同一命令补齐缺失资料,保留已有内容。
167
-
168
- Pi 可能把未知斜杠输入继续交给模型。本次启动显式加载一个小型引导扩展,仅拦截未被命令处理的 `/pbot init`,提示 pbot 未加载并终止该输入。Pi 原生命令分发先于 input 事件,因此正常情况仍由原有命令负责。引导扩展不创建资料、不安装软件、不取得信任或登录凭据,也不持久注册。未识别到初始化命令时请求 Pi 关闭;引导文件缺失时不启动 Pi,引导加载错误使用原生启动错误处理。
169
-
170
- 初始化与 Python 准备分别报告结果。安装器不通过等待固定时间、模拟键盘、分析提示文案或发送模型请求判断成功。用户选择暂不启动时,给出进入该目录并执行初始化的命令,不报告初始化已完成。
171
-
172
- ## 模块与发布
173
-
174
- 继续采用现有顶层分层:
73
+ ## 模块与分发
175
74
 
176
75
  | 位置 | 责任 |
177
76
  | --- | --- |
178
- | `src/extension/setup-cli.ts` | CLI 参数、依赖装配、流程入口和退出状态 |
179
- | `src/services/installation/` | 安装计划、选择规则、执行顺序和结果汇总 |
180
- | `src/integrations/installation/` | Pi/npm、系统包管理器、环境探测和子进程启动 |
181
- | `src/ui/setup.ts` | 目录输入、多选、计划确认和进度展示 |
182
- | `resources/installer/plugins.json` | 维护者提供的配套插件清单 |
183
- | `src/extension/setup-guard.ts` | 本次 Pi 启动的初始化输入保护,随 CLI 编译发布 |
184
- | `tests/installation/` | 安装计划、作用域、路径、真实进程与失败恢复验证 |
185
-
186
- 服务只接收普通数据和窄能力。CLI 不加载主扩展、创建 agent 会话或依赖预先安装的 Pi SDK。不同系统包管理器采用显式的少量适配,不引入动态插件执行框架。
187
-
188
- `package.json#bin.pbot` 指向 `bin/pbot.mjs`,再转交 `lib/extension/setup-cli.js`。`npm run build:cli` 使用现有 TypeScript 编译器和独立 tsconfig.cli.json 生成 lib,包括安装入口、原生 Pi 桥接和启动保护。扩展仍由 Pi 加载源码,dist 仍仅用于测试。npm test 的构建和 prepack 都生成 CLI;消费者无需运行构建脚本。
189
-
190
- Pi 宿主包继续作为 optional peer,不捆绑进 CLI,npx 不自动安装这些宿主依赖。CLI 入口不导入宿主;安装检查子进程在发现真实 Pi 后动态使用其公开 SDK,仅读取包配置或完成用户选择的本地来源声明替换,不创建会话、不读取认证、不启动扩展。
191
-
192
- 行为变更时同步维护中英文 README、技术设计、脚本说明、发布与验证文档,区分安装辅助命令与 Pi 中的 `/pbot` 命令。版本遵循现有发布流程,不增加存储或工作区版本计数。
193
-
194
- ## 失败、取消与重试
195
-
196
- | 情况 | 结果 |
197
- | --- | --- |
198
- | Pi、pbot、tmux 或必要环境检查失败 | 停止依赖步骤,不启动 Pi,显示修复与重试方式 |
199
- | 可选插件失败 | 继续其他独立插件,汇总后询问是否先使用 Pi |
200
- | 下载或安装中断 | 保留已完成步骤;下次重新探测原生状态,不假定原操作已完成 |
201
- | 用户取消 | 停止后续动作,保留已完成安装与已有资料 |
202
- | Pi 启动失败或 pbot 未加载 | 明确区分安装结果与启动失败,不发送模型请求代替初始化 |
203
- | pbot 初始化或 Python 准备失败 | 由 pbot 的原有命令和状态报告,不宣称环境全部就绪 |
204
-
205
- 不同包管理器不构成一个事务,不自动整体回滚,也不删除环境来重试。setup 每次重新构建计划,不建立持久执行日志或安装完成标记。进程结束时保留本次安装的失败状态;可选插件失败后选择进入 Pi,也不把该安装项改成成功。
206
-
207
- ## 验收
208
-
209
- 实现依据包括仓库代码、Pi 文档与包管理实现,以及 npm 包元数据。具体已执行检查和外部验收缺口见[验证](validation.md)。
210
-
211
- 实现至少验证以下行为:
212
-
213
- | 场景 | 验收重点 |
214
- | --- | --- |
215
- | 全新环境与 npx | 不需要预装 Pi;入口能独立运行;不会把 npx 缓存中的 peer 当作真实宿主 |
216
- | Linux 与 macOS | 真实环境中的 Pi/npm 路径、tmux 安装、交互终端和进程交接 |
217
- | 目录选择 | 当前、已有、新建、包含空格及非 ASCII 的目录;所有操作使用所选 cwd |
218
- | 首次安装与重复运行 | pbot 必装、默认插件、已安装预选、新候选不自动加入、再次执行正确重试 |
219
- | 作用域与原生配置 | 同名用户级/工作区包、资源过滤、禁用资源、无关插件与损坏配置 |
220
- | 自定义来源 | 本地源码、Git、固定版本的保留与显式切换;缺失或无法识别的目录来源阻断计划和执行;保留独立单文件扩展;无重复加载,不删除源码 |
221
- | 最新版本 | 当前版本、registry 目标与实际结果一致;查询失败和目标环境不满足时不报成功 |
222
- | 部分失败与取消 | 依赖步骤停止、独立插件继续、重跑重新探测、不自动卸载或整体回滚 |
223
- | 初始化交接 | 无模型认证也能执行 `/pbot init`;拒绝信任或扩展缺失时不落入模型输入;初始化后保留 TUI |
224
- | 数据保留 | 已有 `AGENTS.md`、资料、历史记录和备份保持原有内容 |
225
- | 打包与两种入口 | tarball 中入口和资源完整;npx 与全局 `pbot setup` 均可运行 |
226
-
227
- 测试使用实际本地文件、进程、打包产物和 Pi SDK,不使用假模型、模拟包管理器或个人凭据。测试安装目录、配置与缓存使用独立临时位置。系统包安装、联网 npm 分发与完整 TUI 在专门的 Linux/macOS 验收环境进行,不修改开发者现有环境来代替验收。
228
-
229
- 实现提交前执行 `npm run check`、`npm test`、`git diff --check` 和 `npm pack --dry-run`。本地检查不证明未来任意最新版本组合、外部服务或模型任务可用,发布记录应写明实际验收版本与剩余缺口。
77
+ | `src/extension/setup-cli.ts` | CLI 参数、装配和退出状态 |
78
+ | `src/services/installation/` | 安装计划、选择、顺序和结果 |
79
+ | `src/integrations/installation/` | Pi/npm、系统软件、探测与进程 |
80
+ | `src/ui/setup.ts` | 目录、多选、计划确认与进度 |
81
+ | `src/extension/setup-guard.ts` | 初始化输入保护 |
82
+ | `tests/installation/` | 计划、作用域、来源和失败恢复检查 |
83
+
84
+ `bin/pbot.mjs` 转交预构建的 `lib/extension/setup-cli.js`。CLI 独立启动,发现真实 Pi 后才在子进程中使用其公开 SDK 读取配置或切换来源;宿主依赖声明为 optional peer。构建与安装包检查见[维护脚本](../scripts/README.md)。
@@ -1,60 +1,46 @@
1
1
  # 模型上下文
2
2
 
3
- 本文说明 Personal Bot 提供哪些指令、由谁加载,以及本地检查能证明什么。后续修改遵循[模型指令编写原则](model-instruction-guidelines.md)。宿主自己的系统提示、用户配置和模型传输格式由 Pi 或 dsh 管理。
3
+ 本文说明 Personal Bot 的指令来源、加载时机与更新方式。编写要求见[模型指令编写原则](model-instruction-guidelines.md)。宿主系统提示、用户配置和模型传输由 Pi 或 dsh 管理。
4
4
 
5
- ## 内容取舍
5
+ ## 内容与来源
6
6
 
7
- 常驻内容说明职责、资料位置、基本操作和异常后的处理。按用户请求与已有约定推进,不为普通任务增加证据清单、独立复核或反复授权流程。只解释内部执行机制的内容放在开发文档。具体工具的参数、分页、通知领取和状态语义留在工具契约中。
8
-
9
- | 内容 | 放置位置与理由 |
7
+ | 内容 | 来源与加载条件 |
10
8
  | --- | --- |
11
- | 工作区目录用途 | 公共提示中保留完整用途表,根 AGENTS 模板保留导航;新建资料不依赖模型先选择维护技能。已有用户布局和约定优先 |
12
- | 操作结果与异常重试 | 公共提示简述查看结果、重试前查状态;异常通知提供本次故障的恢复入口 |
13
- | 协调与专家交付 | 各自角色中说明,工作区同名职责补充继续加载 |
14
- | 团队公开范围与续读 | 专家处理团队任务时加载 team-member;普通专家不常驻收到团队工作说明 |
15
- | 项目维护与工具接入 | 技能目录提供名称、用途和读取入口;正文在相应任务中读取 |
16
- | Python 与指标/回测 | 计算先读 compute;仅涉及指标或回测时再读 compute-finance,保留口径、暖机、缺失值和市场约束 |
17
- | Task Conductor | 协调者需要周期、DAG 或持久执行时读取参考及上游技能;接入按当前版本要求,不在模型资料中固定开发基线 |
18
- | 历史摘要 | 独立短提示,只处理本次历史文本;保留决定、建议、尝试、完成及不确定性的区别 |
19
-
20
- 角色和工具说明不再重复解释父聊天历史、进程、代次、结果持久化、宿主间参数转换等机制。需要模型实际执行的要求直接表达,例如委派提供目标、相关资料、约束和交付要求。异步任务要读哪个结果、分页如何继续、暂停后是否仍有在途工作会改变下一步操作,不能当作文案冗余删去。
9
+ | 公共约定、资料目录用途 | `resources/prompts/workspace.md`,主会话与专家均加载 |
10
+ | 协调者与专家职责 | `resources/agents/`,叠加原工作区 `agents/` 中的同名补充 |
11
+ | 团队目标、职责与公开范围 | 专家处理团队任务时加载 `team-member.md` 和本次团队资料 |
12
+ | 参数、分页与结果语义 | 工具契约 |
13
+ | 项目维护、工具接入 | 原生技能目录提供发现入口,正文按任务读取 |
14
+ | 计算方法 | 普通计算读取 compute;指标与回测另读 compute-finance |
15
+ | 周期、DAG 与持久任务 | 按需读取 Task Conductor 参考和上游技能 |
16
+ | 历史摘要 | 专用提示与本次问答或下层摘要 |
21
17
 
22
- 公共提示、角色、团队任务、通知及工具描述中重复的“不扩大授权”“不等于验收通过”等通用提醒已清理;角色不要求固定的证据报告或复核结论格式。需要复核时按具体问题安排。技能保留配置作用域、连接检查、计算口径和资料维护方法,不将普通操作变成审批与留证流程。目录用途、凭据引用、私人内容的公开范围及未知结果的防重复处理仍有明确操作用途。此次调整只涉及模型可见内容,不改变宿主审批、工具校验、会话与团队状态规则。
23
-
24
- 2026-11-07 审查及后续通用提醒清理后,保留目录表的包内常驻正文:公共约定加协调者由原始 2872 减至 1378 字符(约 52%),公共约定加普通专家由原始 2403 减至 1243 字符(约 48%)。这里只计文件的 UTF-16 长度,不包括宿主提示、工具 schema、用户资料与动态任务,不是 token 数或实际模型费用;首轮没有团队任务时不计 team-member。
18
+ 公共内容说明职责和日常操作,专门方法按需加载。宿主维护原生 AGENTS、技能发现和上下文去重。目录用途保留在首轮上下文中,已有用户布局与约定优先。
25
19
 
26
20
  ## Pi
27
21
 
28
- 主会话第一次任务保留 Pi 原生系统提示、工具、AGENTS 等上下文文件、技能元数据和 cwd,再增加公共约定、协调者及工作区职责补充、精简环境。专家使用通用专家角色和同名工作区补充;原生文件由专家 cwd 决定,pbot 职责补充从原工作区读取。
29
-
30
- 包内主会话技能由 package.json 的 `pi.skills` 声明,遵守原生 no-skills 和包级过滤。专家使用其显式 noSkills 选项,原生工具按宿主规则决定技能是否可见。普通任务不包含技能或提示模板正文;读取技能或展开原生模板时才加入。
22
+ 主会话保留 Pi 原生系统提示、工具、AGENTS、技能目录和 cwd,再加入公共约定、协调者职责、工作区补充和环境状态。专家使用 general-purpose 职责;原生资料由专家 cwd 决定,pbot 职责补充从原工作区读取。
31
23
 
32
- before_agent_start 完整读取公共约定及角色后更新 section。读取失败显式取消本轮,避免宿主捕获 hook 错误后继续执行。角色补充在下次工作周期读取;原生 AGENTS 和技能目录经 reload 更新。`/pbot init` 提示新建 AGENTS 的加载时机,不自动重载活动协作,也不另行复制一份根文件进提示。
24
+ 包内技能由 `package.json` 的 `pi.skills` 声明,遵守 no-skills 和包级过滤;专家使用自己的 noSkills 选项。技能与提示模板正文在读取或展开时加入。
33
25
 
34
- 未变的 section 不重复追加,变更只产生原生差量。有效系统内容仍会随宿主后续请求传递,不能把差量去重当成模型不再收到这些内容。工具声明独立于系统提示,也计入模型上下文;原来四个工具分别附加的两条公共指南已删除,原生 codemode 已说明 await、超时和结构化结果检查。
26
+ `before_agent_start` 完整读取公共约定与角色后更新 section,读取失败取消本轮。角色补充在下一工作周期刷新;原生 AGENTS 与技能目录经 `/reload` 更新。`/pbot init` 创建的根 AGENTS 在重载或下次启动后加载。
35
27
 
36
- 团队任务才增加团队目标、职责与操作说明;公共消息按 teamId/seq 和当前分支去重,后续安全边界补充未见消息。原生压缩可能移除已见原文,所需证据通过团队 read 重新读取,不为恢复原文自动重注整段历史。
28
+ 未变的 section 沿用,变更通过原生差量更新,有效系统内容随后续请求传递。团队公共消息按 teamId、seq 和当前分支去重,在安全边界补充新消息;压缩后需要的原文通过团队 read 读取。
37
29
 
38
30
  ## dsh
39
31
 
40
- 主会话使用自己的原生 preset,专家在 create/resume 时通过原生 composeFrom 应用父会话的 preset。标准 preset 提供的文件工具、AGENTS、技能发现等因而在专家首轮也可见。专家工具限制在组合后生效,保留团队通信,排除协调管理和原生 subagent_fork 等委派工具;不把工具选择称为执行隔离。
32
+ 专家在创建和恢复时通过原生 `composeFrom` 应用父会话 preset,再限制工具,保留团队通信并排除协调管理与递归委派工具。标准 preset 提供文件工具、AGENTS 与技能发现。
41
33
 
42
- 公共约定和角色在 system-prompt/assemble 当次读取,工作区角色修改在下一次实际请求中可见,不再滞后一轮。原生 complete persona 按宿主规则覆盖普通提示 section;pbot 不强制绕过。因此不能保证显式使用完整自定义 persona 的会话同时收到 pbot 公共约定和角色,选择这种 persona 时由用户维护其完整行为要求。
34
+ 公共约定和角色在 `system-prompt/assemble` 当次读取。显式 complete persona 按宿主规则覆盖普通提示 section,其完整行为要求由该 persona 提供。
43
35
 
44
- 包内技能在 Host 层用原生 SkillFilesystem 注册一次,只提供包目录。项目和用户技能交给 preset 的原生 provider,保留 `.dsh/skills`、`.agents/skills`、用户目录与包技能的原生优先级及文件更新监听。noSkills 关闭专家的模型技能目录与 skill 工具;用户显式输入 `/技能名` 仍按宿主原生手势处理。
36
+ 包内技能在 Host 层注册一次。项目和用户技能沿用原生 provider 的目录优先级与文件更新监听。noSkills 关闭专家的模型技能目录和 skill 工具;用户显式技能命令按宿主规则处理。
45
37
 
46
- 首次普通请求包含宿主系统提示、pbot 公共约定和角色、工具声明,以及原生 AGENTS、环境和技能目录消息。未变的原生内容不会在下一次输入时重复追加。工具 schema 在普通 executor 中独立提供;PTC 使用原生 run_code 和工具目录,不由 pbot 再造包装。
38
+ 普通请求包含宿主提示、pbot 约定与角色、工具声明,以及原生 AGENTS、环境与技能目录。未变的原生内容沿用;PTC 的工具目录和 run_code 由宿主管理。
47
39
 
48
- 团队简报从动态 system section 移到 pre-step 已接纳的团队上下文,与公共原文使用既有 pbot-team-context 来源。事件队列先处理 turn/start,再准备首个请求;即使没有公共消息,首轮也得到共同目标、成员职责和团队操作说明。简报每次团队发言一次,公共序号在实际消费后才确认。被原生准入拒绝的内容不标记为已读,后续明确批次仍能获取;人工输入不追加新团队内容。
40
+ 团队简报在 `pre-step` 已接纳的团队上下文中加入,每次团队发言一次。首轮即提供目标、成员职责与操作说明,公共消息序号在实际消费后确认。准入失败保留未读状态;人工输入不追加新团队内容。
49
41
 
50
42
  ## 环境与历史
51
43
 
52
- 模型环境保留 `workspaceRoot`、`resourceRoot`、`python.state` 和就绪时的 `python.directory`。实际 cwd 使用宿主上下文,Python 准备日志保留在 `/pbot status`;计算参考提供诊断和重试入口。目录位置、Python 是否就绪和完整错误分别服务于资料定位、执行选择和排障。
53
-
54
- 两种历史摘要调用都直接使用专用提示和当前问答/下层摘要,带时段和未完成标记。不加载公共约定、角色、用户职责补充、AGENTS、技能、团队或环境,不提供工具。长文本按预算分段再汇总;查询、空会话和资源加载不会自动发起摘要。完整历史原文保留。
55
-
56
- ## 验证边界
57
-
58
- 真实 SDK 检查观察首次任务准备出的系统内容、工具声明、原生消息来源与后续差量;以临时文件的路径、原文和结构化状态作断言,不对产品提示词全文或句子做快照测试。Pi 使用真实 `_prepareRun` 观察认证前的准备结果,失败取消另通过真实 custom-message run 核对原生 abort 信号。
44
+ 模型环境提供 `workspaceRoot`、`resourceRoot`、`python.state` 和就绪时的 `python.directory`。实际 cwd 由宿主提供,Python 准备日志在 `/pbot status` 查看。
59
45
 
60
- 本地上下文组装可证明资料出现的位置、时间和去重,不能证明模型理解、工具选择或专业判断。成功模型、外部服务、完整 Web/桌面及平台验收按[验证记录](validation.md)注明实际范围。用户资料、职责补充、历史与备份不因本次审查被改写。
46
+ 两种宿主的历史摘要均使用 `resources/prompts/history-summary.md` 与当前问答或下层摘要,附带时段和未完成标记。该调用不提供工具或普通会话上下文。长文本按预算分段汇总,完整原文保留;查询和资源加载不触发摘要。
@@ -44,8 +44,8 @@
44
44
 
45
45
  修改插件自身的内容与加载逻辑,保留用户资料、角色补充、历史和备份。不要为了整理提示而迁移用户布局、覆盖用户约定或改变既有执行合同。
46
46
 
47
- ## 验证与记录
47
+ ## 检查
48
48
 
49
49
  加载行为用真实宿主 SDK、本地文件和进程检查来源、首轮出现时机、后续更新、条件加载及去重。测试应覆盖具体行为,不能断言提示句子、标签或全文快照;不能为了满足文案断言反向修改提示,也不为纯文案调整新增此类测试。
50
50
 
51
- 运行适用的仓库检查,并在设计文档说明当前行为。字符数只能说明文本长度变化;本地加载检查不证明模型理解、专业结果或费用改善。真实模型效果按实际验收范围记录。
51
+ 运行适用的仓库检查。设计文档维护当前行为;本次结果与未决问题在任务或 PR 中说明。
package/docs/release.md CHANGED
@@ -40,13 +40,13 @@ npm pack
40
40
 
41
41
  prepack 依次执行 `npm run check`、`npm run build:cli`、`npm run build:dsh`。核对包清单包含 bin、lib(含 dsh Host/Web 产物)、src、resources(含 dsh bundle patch)、Python 锁文件、setup 脚本和 npm-shrinkwrap.json,排除 dist、node_modules、凭据与运行数据。核对包根与 `./dsh` 导出指向 `./lib/dsh.js`、`./client` 指向 `./lib/client.js`,以及 dsh bundle/client 元数据完整。
42
42
 
43
- Pi/dsh 宿主包保持 optional peerDependencies,避免独立 CLI 安装时隐式下载宿主 SDK。dsh SDK peer 范围为 `"*"`,最低宿主要求由 `engines.dsh` 声明;用户安装跟随 `latest`,开发依赖及锁文件保留精确版本。发布验收记录实际 dsh/pnpm 版本,不把最低版本声明视为未来版本已验收。共享契约库 TypeBox 是范围为 `"*"` 的必需 peer,开发依赖锁定版本;Pi 原生加载器提供它,dsh 安装时由包管理器补齐。另在独立 npm cache/prefix 中验证 tarball 的 npm exec 与全局 pbot --version,检查未额外安装 Pi/dsh SDK。
43
+ 依赖与产物规则见[技术设计](technical-design.md#工具与分发),安装包检查入口见[维护脚本](../scripts/README.md)。
44
44
 
45
- 在独立 Pi 配置和临时工作区验收安装;加载扩展会准备用户级 Python 环境,因此验收同时使用独立用户数据目录。再按[dsh 使用说明](dsh.md),在当前 dsh `latest` 的隔离 Web profile 中通过原生插件命令安装同一 tarball,并记录实际宿主版本,核对 Host 启用、包根 Web 客户端加载、`/pbot` 四页签及原生 Remote 查询。验证范围与剩余缺口见[验证](validation.md)。
45
+ 使用隔离的用户目录、宿主配置和临时工作区检查候选包,避免自动 Python 准备影响日常环境。Pi 检查扩展、技能、工具与初始化;dsh 检查 Host、Web 管理页和 Remote 查询。实际版本、结果与未决问题在发布 PR 或 CI 输出中说明。
46
46
 
47
47
  ## GitHub 发布
48
48
 
49
- [CI](../.github/workflows/ci.yml) 在 Node 24.x 安装完整开发依赖、执行检查和测试,再生成候选 tarball;独立 Node 22.19.0 作业安装同一 tarball,检查 CLI 不隐式安装宿主 SDK,再显式安装锁定的 Pi SDK,验证扩展、工具、技能和资料初始化。独立消费者作业仅验证 Pi/CLI,不安装 dsh 开发依赖,不调用模型;全量测试中的 dsh 本地 SDK 测试不代表候选包的包根 Web 加载和 Remote 传输已自动验收。dsh 原生安装与界面按上述步骤单独验证。[发布工作流](../.github/workflows/publish.yml)要求:
49
+ [CI](../.github/workflows/ci.yml) 在 Node 24.x 执行全量检查、构建候选包并检查 dsh 原生安装和 Host 导入;独立 Node 22.19.0 作业检查同一 tarball 的 CLI 与 Pi 加载。[发布工作流](../.github/workflows/publish.yml)要求:
50
50
 
51
51
  - tag 为 v<稳定版本>,包与锁文件版本一致。
52
52
  - 提交已进入远端默认分支。
@@ -93,8 +93,8 @@ npm view personal-bot dist-tags --json --registry=https://registry.npmjs.org
93
93
 
94
94
  在独立 npm cache/prefix 中从公开 registry 全新安装发布版本,验证 npx 入口与全局 pbot 命令。再在独立 Pi 配置和临时工作区执行 `pi install --local npm:personal-bot`,核对安装版本、扩展加载、技能发现和 /pbot status。
95
95
 
96
- 按[dsh 使用说明](dsh.md),使用当前 dsh 和 pnpm,在独立 profile 中通过原生插件命令安装公开 registry 的目标版本,记录实际宿主与插件版本,核对 Host 启用、包根 Web 客户端加载、`/pbot` 管理页及 Remote 查询。安装与无模型检查不代表成功模型工作流已验收,结果记录在[验证](validation.md)。
96
+ 按[dsh 使用说明](dsh.md),在独立 profile 安装公开 registry 的目标版本,核对 Host 启用、Web 管理页和 Remote 查询。
97
97
 
98
98
  上传结果不明时先查询 registry。若上传完成但后续查询失败,手动运行 Publish npm,选择原版本 tag 并保持 verify_only=true。该模式重新执行检查与 registry 查询,不上传;目标版本已不是 latest 时会失败。不要直接重跑原上传作业,也不要移动已发布 tag。
99
99
 
100
- 已发布版本不可覆盖。问题修复由维护者选择新版本、弃用说明或 dist-tag 调整。2026-11-06,提交 `1625a78af324de412ba12b0689de6c9ebde61698` 的 0.2.6 已通过 OIDC 发布及公开版本/latest 查询;公开 registry 只读核对确认该版本存在、latest 为 0.2.6,且包含 dsh Host/Web 入口。0.2.6 从公开 registry 全新安装的 npx、Pi 与 dsh 验收仍待完成,证据及范围见[CI 与发布记录](validation.md#ci-与发布2026-11-06)。
100
+ 已发布版本不可覆盖。问题修复由维护者选择新版本、弃用说明或 dist-tag 调整。
@@ -69,7 +69,7 @@ Pi 主会话通过包清单发现技能,遵守原生 `--no-skills` 与包级
69
69
 
70
70
  dsh 专家通过原生 composeFrom 应用父会话 preset,再限制其工具。包内技能在 Host 层注册一次,项目/用户技能与更新监听交给原生 provider;公共约定和角色在 system-prompt/assemble 当次刷新,遵守宿主 complete persona 覆盖。团队简报随首个已接纳团队上下文提供,不放在先于 pre-step 求值的动态 system section。
71
71
 
72
- 同一会话中不变的 section 由宿主沿用;这不代表后续模型请求不再携带有效系统提示。团队公共消息按结构化来源与序号去重,压缩后需要的原文通过 read 续取。目录用途常驻,维护方法、接入、计算和调度细节按需读取。具体入口与审查取舍见[模型上下文](model-context.md)。
72
+ 同一会话中不变的 section 由宿主沿用,有效系统内容随后续请求传递。团队公共消息按结构化来源与序号去重,压缩后需要的原文通过 read 续取。目录用途常驻,维护方法、接入、计算和调度细节按需读取。具体加载方式见[模型上下文](model-context.md)。
73
73
 
74
74
  公共约定说明工作方式与资料位置,角色说明分工与交付,技能提供专业方法与必要的本地操作约定,工具定义参数与结果语义。委派包含文件修改时说明范围和责任;不重复加入通用授权、证据或验收要求。工具按 action 校验必填与允许字段,返回具体参数错误;status 不读取报告正文。Pi 附件组装保留绝对来源及原生读取结果;dsh 使用原生文件存储与图片准入,Web 通用文件走原生 Session 上传凭证,命令图片使用原生编码图片输入。资料保存由模型按公共约定与维护技能处理,沉淀方法、口径与结论,可再次查询的数据按需获取。布局见[文件存储](file-storage.md)。
75
75
 
@@ -119,6 +119,8 @@ Web 拥有草稿、上传和查询;接纳后的命令归服务端。命令不
119
119
 
120
120
  Pi 将工具纳入 pbot namespace,codemode 按契约组合;dsh 注册原生工具,并在宿主可表达的 schema 之外继续校验完整领域契约。原生 CLI/MCP 与可选 Task Conductor 的接入和授权见[工具与执行](capability-design.md)。
121
121
 
122
- 扩展以 TypeScript 源码分发,由 Pi 加载;dist 仅供测试导入。安装 CLI 使用现有 TypeScript 工具链单独生成 lib,由 bin/pbot.mjs 启动,消费者无需编译或预装 Pi。dsh Host 与 Web 也编译到 lib,客户端由原生包根 Loader 发现;Pi 的入口仍由包清单明确指向 src。宿主 SDK 均为 optional peer,不捆绑另一份运行时。dsh 用户安装跟随 `latest`,`engines.dsh` 声明最低版本 `>=0.2.2-rc.1`,dsh SDK peer 范围为 `"*"`;开发依赖和锁文件仍保留精确版本,验收只证明记录中的实际版本。TypeBox 声明为范围为 `"*"` 的必需 peer:Pi 通过原生加载器提供;dsh 安装时由包管理器补齐。开发依赖锁定 TypeBox 版本,不随包捆绑。Pi/CLI 保持 Node.js 22.19+,dsh 与完整开发使用 Node.js 24.9+。安装检查子进程在发现真实宿主后使用该宿主的 SDK 读取配置和切换来源声明。发布版本以 package.json 为准,包内组件共用该版本。子会话兼容线在 1.0 前按次版本、1.0 起按主版本判断,跨线会话不能直接恢复。
122
+ Pi 入口指向 src,由宿主加载 TypeScript 源码;独立 CLI 与 dsh Host/Web 编译到 lib,dist 供测试使用。宿主 SDK 使用 optional peer,dsh SDK 范围为 "*",最低宿主版本由 engines.dsh 声明;开发依赖和锁文件保留精确版本。TypeBox 同样为 optional peer:Pi 通过宿主加载器提供,dsh 构建携带库及许可证,并保留原模块路径以定位资源。
123
123
 
124
- 开发验证见[验证](validation.md),分发流程见[npm 发布](release.md)。
124
+ Pi/CLI 支持 Node.js 22.19+,dsh 与完整开发使用 Node.js 24.9+。安装检查发现真实宿主后,在子进程中使用其 SDK 读取配置或切换来源。包内组件共用 package.json 的发布版本;子会话兼容线在 1.0 前按次版本、之后按主版本判断。
125
+
126
+ 构建与安装包检查见[维护脚本](../scripts/README.md),分发流程见[npm 发布](release.md)。
@@ -0,0 +1,23 @@
1
+ TypeBox
2
+
3
+ The MIT License (MIT)
4
+
5
+ Copyright (c) 2017-2026 Haydn Paterson
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.