dsh-ios-webview-app-control 0.0.0-stage → 0.2.2

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.md +250 -2
  4. package/THIRD_PARTY_NOTICES.md +42 -0
  5. package/cordis.patch.yml +20 -0
  6. package/docs/installation.md +68 -0
  7. package/docs/new-session-prompt.md +29 -0
  8. package/docs/runtime-environment.md +40 -0
  9. package/docs/sdk-contract.md +79 -0
  10. package/docs/verification.md +64 -0
  11. package/icon.svg +8 -0
  12. package/lib/cli.mjs +51 -0
  13. package/lib/client.js +223 -0
  14. package/lib/core/dom.mjs +26 -0
  15. package/lib/core/leases.mjs +31 -0
  16. package/lib/core/protocol.mjs +101 -0
  17. package/lib/core/python.mjs +47 -0
  18. package/lib/core/service.mjs +122 -0
  19. package/lib/host/environment-service.mjs +175 -0
  20. package/lib/host/subprocess-runner.mjs +34 -0
  21. package/lib/plugin.mjs +303 -0
  22. package/lib/runtime/environment-manager.mjs +544 -0
  23. package/lib/runtime/errors.mjs +33 -0
  24. package/lib/runtime/runner.mjs +75 -0
  25. package/lib/runtime/safe-tar.mjs +179 -0
  26. package/lib/typert-environment.mjs +103 -0
  27. package/locale/en.json +6 -0
  28. package/locale/zh.json +6 -0
  29. package/package.json +72 -4
  30. package/requirements.txt +1 -0
  31. package/resources/notices/PBS-LICENSE.bdb.txt +126 -0
  32. package/resources/notices/PBS-LICENSE.bzip2.txt +37 -0
  33. package/resources/notices/PBS-LICENSE.cpython.txt +771 -0
  34. package/resources/notices/PBS-LICENSE.expat.txt +21 -0
  35. package/resources/notices/PBS-LICENSE.libX11.txt +942 -0
  36. package/resources/notices/PBS-LICENSE.libXau.txt +21 -0
  37. package/resources/notices/PBS-LICENSE.libedit.txt +29 -0
  38. package/resources/notices/PBS-LICENSE.libffi.txt +21 -0
  39. package/resources/notices/PBS-LICENSE.liblzma.txt +13 -0
  40. package/resources/notices/PBS-LICENSE.libuuid.txt +27 -0
  41. package/resources/notices/PBS-LICENSE.libxcb.txt +30 -0
  42. package/resources/notices/PBS-LICENSE.mpdecimal.txt +24 -0
  43. package/resources/notices/PBS-LICENSE.ncurses.txt +29 -0
  44. package/resources/notices/PBS-LICENSE.openssl-3.txt +177 -0
  45. package/resources/notices/PBS-LICENSE.sqlite.txt +23 -0
  46. package/resources/notices/PBS-LICENSE.tcl.txt +40 -0
  47. package/resources/notices/PBS-LICENSE.tix.txt +54 -0
  48. package/resources/notices/PBS-LICENSE.zlib-ng.txt +19 -0
  49. package/resources/notices/PBS-LICENSE.zlib.txt +21 -0
  50. package/resources/notices/PBS-LICENSE.zstd.txt +30 -0
  51. package/resources/notices/PYMOBILEDEVICE3-LICENSE.txt +674 -0
  52. package/resources/notices/PYTHON-LICENSE.txt +277 -0
  53. package/resources/notices/provenance.json +134 -0
  54. package/resources/runtime-lock.json +4252 -0
  55. package/scripts/manage-desktop.ps1 +56 -0
  56. package/scripts/package-validation.mjs +223 -0
  57. package/scripts/verify-package.mjs +13 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,41 @@
1
+ # 更新记录
2
+
3
+ ## 0.2.2 — 2026-11-03
4
+
5
+ - 修复设置页环境面板在准备结束后仍挂着“步骤/字节数/进度条”的问题:只有准备进行中(busy)才输出并渲染过程信息,就绪、失败、取消后的公开状态不再保留 step/progress。
6
+ - 修复从插件列表启用后准备面板一直停留、要切换页面才消失的问题:环境达到 ready 时激活引导自动收起;失败、取消、未准备状态仍保留面板供操作。
7
+
8
+ ## 0.2.1 — 2026-10-31
9
+
10
+ - README 按 npm 包页面的阅读顺序重组,补上 npm 安装方式和可直接跑的 CLI 示例,并把验证快照与安装要求的表述分开。
11
+ - 修正模型提示词、工具/参数描述、错误、CLI、双语界面及复制提示的作用域:`ios_*` 仅描述本插件,不是 DSH 会话完整能力清单。
12
+ - 静态及连接内嵌能力新增 `source`、`scope=plugin-only`、`inventory=not-session-inventory`;保留 android/nativeTap 等原值,明确 false 不代表其它工具不存在或被禁用。
13
+ - 区分“超出本插件范围需独立核查工具”与“同一操作被审批/策略阻止后不得换道”;不扩大本插件设备范围、不削弱类型/目标绑定/租约/逐次审批门控。
14
+ - 新增防回归检查:插件能力与其它工具清单并存、静态无连接检查、跨出口说明一致及原拒绝仍零派发。
15
+
16
+ ## 0.2.0 — 2026-10-30
17
+
18
+ - 新增私有 Python 环境管理:优先检测可用宿主 CPython,在插件私有 venv 安装 `pymobiledevice3==11.45.0` 完整锁定依赖;没有合适宿主时按需使用固定 PBS CPython 3.13.18 Windows x64。
19
+ - 不修改宿主 Python、全局 site-packages、PATH、注册表或系统 VC Runtime;环境准备不连接设备、不启动 bridge,`ios_devices` 只使用已验证 venv,未就绪不会隐式安装。
20
+ - 新增 `ios_environment` 工具、严格 Host/Client Remote 合同、设置页状态/准备/取消/清理操作和中英文本地化;清理保留 active 环境、证据和租约。
21
+ - 新增完整资源锁、安全 tar 解包、哈希校验、失败保留旧 ready pointer、跨进程保守锁、第三方许可证原文和发布门禁。
22
+
23
+
24
+ ## 0.1.2 — 2026-10-30
25
+
26
+ - 针对 DSH `0.2.1-rc.5` 重新核对并验证工具、审批、提示词和 Cordis 生命周期接口。
27
+ - 修复升级阻断:旧安装包 `0.1.0` 精确要求四项 DSH peer `0.2.1-rc.3`,被新版兼容性检查拒绝加载;新版声明 `engines.dsh >=0.2.1-rc.5 <0.3.0`,四项 DSH peer 为 `^0.2.1-rc.5`。没有添加版本豁免,也不宣称兼容未测试的 alpha/0.3。
28
+ - 安装、归档校验和冒烟脚本改为从 [manifest](./package.json) 推导当前版本,拒绝版本、兼容声明、入口或分发资源不一致的旧归档,避免反复安装旧包。
29
+ - Python 定位不再猜测 Harness home/cache 内部目录:依次采用部署 `pythonPath`、`DSH_IOS_PYTHON`、显式 `DSH_PRIMARY_RUNTIME`。未配置时给出操作建议,不搜索 PATH 或自动安装运行时。
30
+ - 新增真实 DSH ToolRuntime / SystemPrompt / ApprovalService / Session 集成测试,覆盖工具发现、执行、逐次审批审计、无人应答/异常应答、never 策略、空闲会话拒绝和卸载清理。授权测试使用隔离内存会话与假设备派发,不修改真实审批策略。
31
+ - 补充中英文插件标题、描述与原创 MIT 图标,并检查打包资源。
32
+ - 更新文档,区分安装历史、验证结果与尚未授权的实机验收。
33
+
34
+ ## 0.1.1 — 未发布为安装包
35
+
36
+ - 工作区已将依赖及锁文件更新为 rc.5;安装和验证脚本仍引用 0.1.0,导致这些更新没有进入实际安装包。
37
+
38
+ ## 0.1.0 — 历史版本
39
+
40
+ - 初版纯 Host 插件,包含 12 个 iOS WebView 工具、逐次审批、会话连接/目标绑定、租约和有界 CDP 操作。
41
+ - 历史桌面部署验证基于 DSH `0.2.1-rc.3`;该记录不能当作新版运行时已加载的证明。
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,251 @@
1
- # Temporary Holding Version
1
+ # dsh-ios-webview-app-control
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 业务无关的 DSH 工具,只用于可检查的 iOS WebView / 混合应用。
4
+
5
+ > `package.json` 的 description 是这句话的英文原文,`Business-free DSH tools for inspectable iOS WebView/hybrid apps only.`
6
+
7
+ [![npm version](https://img.shields.io/npm/v/dsh-ios-webview-app-control.svg)](https://www.npmjs.com/package/dsh-ios-webview-app-control)
8
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/LICENSE)
9
+ [![Node](https://img.shields.io/badge/node-%3E%3D22.18.0-339933)](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/package.json)
10
+ [![DSH](https://img.shields.io/badge/dsh-0.2.1--rc.5%20%3C0.3.0-4B32C3)](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/package.json)
11
+ [![GitHub](https://img.shields.io/badge/GitHub-Saltedfish117%2Fdsh--ios--webview--app--control-181717?logo=github)](https://github.com/Saltedfish117/dsh-ios-webview-app-control)
12
+
13
+ ## 目录
14
+
15
+ - [安装](#安装)
16
+ - [快速开始](#快速开始)
17
+ - [核心功能](#核心功能)
18
+ - [用法与示例](#用法与示例)
19
+ - [API 参考](#api-参考)
20
+ - [故障排除](#故障排除)
21
+ - [背景与边界](#背景与边界)
22
+ - [开发与验证](#开发与验证)
23
+ - [贡献与许可证](#贡献与许可证)
24
+ - [已验证环境](#已验证环境)
25
+
26
+ ## 安装
27
+
28
+ Node 要 22.18.0 以上,DSH 在 `0.2.1-rc.5` 到 `0.3.0` 之间。这是 DSH 插件,不能当独立 Node 服务跑。
29
+
30
+ 下面这些 peer dependencies 由 DSH 宿主提供,不要单独 `npm install`。
31
+
32
+ | Peer dependency | 版本范围 |
33
+ | --- | --- |
34
+ | `@deepseek-ai/cordis` | `~4.0.5` |
35
+ | `@deepseek-ai/dsh-tools` | `^0.2.1-rc.5` |
36
+ | `@deepseek-ai/dsh-system-prompt` | `^0.2.1-rc.5` |
37
+ | `@deepseek-ai/dsh-user-approval` | `^0.2.1-rc.5` |
38
+ | `@deepseek-ai/dsh-llm` | `^0.2.1-rc.5` |
39
+ | `@deepseek-ai/dsh-typert-protocol` | `^0.2.1-rc.5` |
40
+
41
+ ### 从 npm 安装
42
+
43
+ ```bash
44
+ npm install dsh-ios-webview-app-control
45
+ ```
46
+
47
+ `npm install` 只是把文件放到本地。要真正加载插件,还得走 DSH 的插件管理入口,把 `plugin_manager install_bundle` 指向 `node_modules/dsh-ios-webview-app-control`(目录结构和仓库根一致),或者指向 `npm pack` 出来的 tgz。
48
+
49
+ ### 从仓库安装
50
+
51
+ ```bash
52
+ git clone https://github.com/Saltedfish117/dsh-ios-webview-app-control.git
53
+ cd dsh-ios-webview-app-control
54
+ npm ci --ignore-scripts
55
+ npm run build
56
+ npm pack --pack-destination artifacts
57
+ ```
58
+
59
+ 拿到 tgz 之后一样交给 `plugin_manager install_bundle`。安装、升级和生效判定见 [安装与升级指南](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/docs/installation.md)。
60
+
61
+ 安装或升级会影响同一 profile 下的所有会话,动手前先确认没有未保存的工作。
62
+
63
+ ## 快速开始
64
+
65
+ ### 先确认装上了
66
+
67
+ ```bash
68
+ npx dsh-ios-webview-app-control capabilities
69
+ npx dsh-ios-webview-app-control environment status
70
+ ```
71
+
72
+ 从仓库直接开发时,把 `npx dsh-ios-webview-app-control` 换成 `node lib/cli.mjs`。
73
+
74
+ 第一条输出里能看到 `scope: "plugin-only"` 和 `inventory: "not-session-inventory"`。`android`、`nativeTap` 这些是 `false`,说的是本插件没实现,不代表整个 DSH 会话里没有别的工具能干这些事。
75
+
76
+ 第二条只看插件私有 Python 环境到了哪一步、解释器是从哪来的,不碰设备。它输出 `phase: "unprepared"` 是正常的,说明还没跑过准备。
77
+
78
+ ### 在 DSH 会话里走一遍最小流程
79
+
80
+ 1. `ios_environment` 调 `status`,没就绪再 `prepare`。这一步不访问手机。
81
+ 2. `ios_capabilities` 看一眼,确认插件只接 iOS WebView 和 hybrid。
82
+ 3. 找操作者确认设备 UDID,以及已有的 loopback bridge 绑的是哪台设备。
83
+ 4. `ios_connect`,然后 `ios_targets`、`ios_bind_target`、`ios_acquire`。
84
+ 5. 读和截图分别调 `ios_read` 和 `ios_screenshot`,写操作另外审批。
85
+
86
+ 这些全是 DSH 工具调用,当不了 HTTP 或 JavaScript API 用。要跑通,真实的 DSH 会话、已经起来的 bridge、逐次审批,三样都得在。
87
+
88
+ ## 核心功能
89
+
90
+ - 只接操作者明确确认过的 iOS WebView 或混合应用
91
+ - 复用已经跑起来的 loopback Web Inspector bridge,插件不自己拉服务
92
+ - 发现 USB 设备、列出目标、绑定到确切的一个 target
93
+ - 有界读取 DOM 和文本,截 WebView 渲染图
94
+ - 受控的 DOM click、scroll 和普通文本输入,eval 默认关着
95
+ - 每次操作单独审批,连接归会话所有,租约和目标指纹都会校验
96
+ - 私有 Python / venv 环境,不动宿主 Python 和系统设置
97
+
98
+ ## 用法与示例
99
+
100
+ ### 设备流程
101
+
102
+ | 步骤 | 工具 | 关键要求 |
103
+ | --- | --- | --- |
104
+ | 1 | `ios_environment status` | 只读;没就绪再 `prepare` |
105
+ | 2 | `ios_devices` | 发现 USB 设备;不选择、不连接 |
106
+ | 3 | `ios_connect` | 明确 `platform=ios`、`appType=webview/hybrid`、UDID 和操作者确认的 bridge |
107
+ | 4 | `ios_targets` | 读当前的 target;不据此推断 App 类型 |
108
+ | 5 | `ios_bind_target` | 操作者确认 exact target 的 App 身份和类型后绑定 |
109
+ | 6 | `ios_acquire` | 拿本会话、本连接专属的限时租约 |
110
+ | 7 | `ios_read` / `ios_screenshot` | 每次单独审批;截图是 WebView 渲染图 |
111
+ | 8 | `ios_dom_action` / `ios_eval` | 写操作另批;eval 还要部署侧开 `allowEval` |
112
+ | 9 | `ios_release` / `ios_disconnect` | 释放租约;不停止外部 bridge |
113
+
114
+ ### 配置
115
+
116
+ ```yaml
117
+ endpoint: '' # 已有 loopback bridge;留空时 connect 必须明确给地址
118
+ pythonPath: '' # 可选,首选 base Python 的绝对路径
119
+ runtime:
120
+ autoPrepare: true # 有 subprocess 宿主时后台准备私有环境
121
+ directory: '' # 可选,插件私有运行目录
122
+ offline: false # 只用已校验过的缓存
123
+ timeoutMs: 900000 # 环境准备总超时
124
+ stateDir: '' # 证据目录;租约不受它影响
125
+ allowEval: false # 通用 JS 默认禁用
126
+ timeoutMs: 15000 # 设备 I/O 超时
127
+ maxLeaseSeconds: 120 # 租约上限
128
+ ```
129
+
130
+ | 字段 | 默认值 | 说明 |
131
+ | --- | --- | --- |
132
+ | `endpoint` | 空 | 已有 loopback bridge;不自动启动 |
133
+ | `pythonPath` | 空 | 首选 base Python;依赖始终装进私有 venv |
134
+ | `stateDir` | 空 | 证据目录;设备租约固定在用户目录 |
135
+ | `allowEval` | `false` | 开了之后还是要逐次审批 |
136
+ | `timeoutMs` | `15000` | 设备 I/O 超时,1 到 120000 ms |
137
+ | `maxLeaseSeconds` | `120` | 租约上限,5 到 600 秒 |
138
+ | `runtime.autoPrepare` | `true` | 只准备本插件环境,不访问设备 |
139
+ | `runtime.directory` | 空 | 插件私有运行目录 |
140
+ | `runtime.offline` | `false` | 禁止联网下载缺失资源 |
141
+ | `runtime.timeoutMs` | `900000` | 环境准备总超时 |
142
+
143
+ ### 环境管理
144
+
145
+ `ios_environment` 有 status、prepare、cancel、cleanup 四个动作,CLI 也能直接调。
146
+
147
+ ```bash
148
+ npx dsh-ios-webview-app-control environment status
149
+ npx dsh-ios-webview-app-control environment prepare
150
+ npx dsh-ios-webview-app-control environment cleanup --yes
151
+ ```
152
+
153
+ cleanup 只删本插件自己的闲置运行环境和缓存,宿主 Python、设备证据、租约都不动。细节见 [私有运行环境说明](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/docs/runtime-environment.md)。
154
+
155
+ 运行时锁目前只有 Windows x64 一份,覆盖 Python 3.9 到 3.13。其它平台没有锁好的依赖,私有环境准备会直接报 `unsupported_platform`。
156
+
157
+ ### 常见错误
158
+
159
+ | 错误码 | 含义与处理 |
160
+ | --- | --- |
161
+ | `unsupported_platform` / `unsupported_app_type` | 本插件拒绝这个目标;不代表会话里其它工具不可用 |
162
+ | `approval_denied` | 审批缺失、策略是 never、被拒绝或被取消;别改走别的工具做同一件事 |
163
+ | `environment_not_ready` | 私有环境没就绪;先 `ios_environment status` 再 `prepare` |
164
+ | `endpoint_required` / `device_binding_unverified` | connect 前要明确 bridge,以及操作者确认过的 UDID |
165
+ | `wrong_bridge` | 端点不是 pymobiledevice3 Web Inspector bridge |
166
+ | `lease_required` / `lease_not_owned` / `lease_expired` | 租约缺失、不归本会话,或者已经过期 |
167
+ | `device_busy` | 同一台设备已有租约或命令在跑;别抢锁 |
168
+ | `result_too_large` / `non_json_result` | 结果超出边界,或者不是无损 JSON |
169
+
170
+ ## API 参考
171
+
172
+ 完整的工具参数、审批、作用域和 SDK 合同在 [DSH SDK 合同](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/docs/sdk-contract.md)。工具定义在 `src/plugin.mjs`,运行期以 Host 实际注册的 schema 为准。
173
+
174
+ | 工具 | 作用 |
175
+ | --- | --- |
176
+ | `ios_capabilities` | 本插件的静态能力声明,不是会话工具清单 |
177
+ | `ios_environment` | 私有环境的状态与管理 |
178
+ | `ios_devices` | 发现 USB iOS 设备 |
179
+ | `ios_connect` | 附着已有 loopback bridge |
180
+ | `ios_targets` | 列出 target 元数据 |
181
+ | `ios_bind_target` | 绑定操作者确认的 exact target |
182
+ | `ios_acquire` / `ios_release` | 获取或释放会话设备租约 |
183
+ | `ios_read` | 单个 selector 的有界文本读取 |
184
+ | `ios_screenshot` | WebView 渲染截图和元数据 |
185
+ | `ios_eval` | 默认禁用的 WebView JS 执行 |
186
+ | `ios_dom_action` | 单元素 DOM click / scroll / input |
187
+ | `ios_disconnect` | 释放本连接的租约,不停止 bridge |
188
+
189
+ ## 故障排除
190
+
191
+ | 现象 | 处理 |
192
+ | --- | --- |
193
+ | 安装返回 `incompatible-version` 或 `restart-required` | 核对 `engines.dsh` 和 peers;不要加版本豁免;需要时完整重启 DSH |
194
+ | 新说明或工具行为没生效 | `applied` 不等于当前 Agent 已经加载;完整重启后再看真实工具 |
195
+ | `environment_not_ready`,或者准备下载很慢 | 先看 `ios_environment status`;查网络;失败后显式重试 |
196
+ | 设备连着却操作不了 | 核对本会话的工具范围、bridge、UDID、目标绑定和审批;连上不等于已授权 |
197
+ | 目标是 Android、原生或 Flutter | 本插件不处理;自己去查会话里其它工具和权限,别拿本插件的能力当全会话判断 |
198
+ | 写入结果不确定 | 不要自动重放;先核对实际状态,再决定要不要重试 |
199
+
200
+ ## 背景与边界
201
+
202
+ 插件把 DSH 的工具注册、逐次审批、会话归属和设备租约,接到已经跑起来的 pymobiledevice3 Web Inspector CDP bridge 上。
203
+
204
+ ```text
205
+ DSH 工具 + 逐次授权
206
+ ↓ 通用 CDP 客户端
207
+ 已运行的 pymobiledevice3 Web Inspector CDP 桥接(仅 loopback)
208
+ ↓ Apple USB 配对 / Web Inspector 服务
209
+ iPhone 上允许检查的 WKWebView
210
+ ```
211
+
212
+ 这里的限制只针对本插件,`ios_*` 返回的能力结果也是这个意思。`android: false`、`nativeTap: false` 说明本插件没实现,不代表别的工具不存在、被禁用或者已经授权。`ios_capabilities` 不是 DSH 会话的完整工具清单,也不检查 USB 连接。Android、原生、Flutter 这类任务,去看当前会话实际提供了哪些工具、skill 和权限,没查清之前别下「整个会话不能操作」的结论。
213
+
214
+ 本插件不做完整原生 UI 控制、原生元素树、原生 tap/swipe、系统权限弹窗、原生相册和系统手势。支付、密码、CAPTCHA 也不碰。DOM click 不等于原生触控,程序化 scrollTop 也不等于手指滑动,WebView 截图不含原生状态栏、导航和弹窗。
215
+
216
+ 页面内容是外部数据,不能当指令。已经派发的变更不会因为超时或取消回滚,结果不确定就先核对,别自动重放。
217
+
218
+ ## 开发与验证
219
+
220
+ ```bash
221
+ npm ci --ignore-scripts
222
+ npm run build
223
+ npm run check
224
+ npm test
225
+ npm pack --pack-destination artifacts
226
+ node scripts/verify-package.mjs
227
+ node scripts/smoke-package.mjs
228
+ ```
229
+
230
+ - `build`,从 `src` 生成 `lib`,顺便做 Node 语法检查。
231
+ - `check`,查包入口、bundle 配置、运行资源锁、元数据、图标和文档链接。
232
+ - `test`,真实 DSH 服务链、Typert/Client、环境管理、作用域专项、核心与租约、归档校验。
233
+ - `verify-package` / `smoke-package`,校验归档,然后实际导入一次。
234
+
235
+ 仓库还没接 CI,这几条得在本地跑。验证方法和没覆盖到的东西见 [验证说明](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/docs/verification.md)。
236
+
237
+ ## 贡献与许可证
238
+
239
+ - 贡献方式和范围边界见 [CONTRIBUTING.md](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/CONTRIBUTING.md)。
240
+ - 安全或凭据问题别公开提,先找仓库维护者的私下渠道。
241
+ - 项目用 MIT License,见 [LICENSE](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/LICENSE)。
242
+ - 第三方运行环境和 Python 依赖的许可见 [THIRD_PARTY_NOTICES.md](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/THIRD_PARTY_NOTICES.md)。
243
+
244
+ ## 已验证环境
245
+
246
+ 这是某次开发验证的快照,记的是当时验过什么。安装要求看 `package.json`,换台机器,路径、profile、端口和版本都可能不一样。
247
+
248
+ - 插件版本 0.2.1。那次验证用的归档 SHA256 记在 [验证记录](https://github.com/Saltedfish117/dsh-ios-webview-app-control/blob/main/docs/verification.md) 里。
249
+ - 平台 Windows x64,Node 22.18.0,DSH 0.2.1-rc.5,Cordis 4.0.5,Schemastery 3.18.5。
250
+ - 自动验证 204 项通过;tgz 解包导入 smoke 通过;完整重启后,在真实 Host 工具里确认了 `scope=plugin-only`、`inventory=not-session-inventory` 和新的作用域说明。
251
+ - 没覆盖到的是真实 iOS 手机操作、私有 Python 环境完整准备和 UI 视觉渲染。审批策略没动。
@@ -0,0 +1,42 @@
1
+ # 第三方运行环境与许可声明
2
+
3
+ 插件自己的 JavaScript 源码按 [MIT](./LICENSE) 分发。下列独立 Python 解释器与软件包不因此变更许可;不得把整个运行环境称为 MIT。
4
+
5
+ ## 按需取得的运行环境
6
+
7
+ 本 npm 包仅带代码、资源锁与许可证文本,不内置 Python 或 wheel 二进制。初始化从锁定的上游地址下载原始发布文件,校验大小和 SHA256 后,仅安装到本插件用户运行目录。运行时不替用户发布、上传或镜像这些软件。
8
+
9
+ ### Python Build Standalone / CPython
10
+
11
+ - 项目:<https://github.com/astral-sh/python-build-standalone>。
12
+ - 固定发行:20261026;备用 CPython:3.13.18 Windows x64,标准 GIL、install_only_stripped。
13
+ - 分发资产与完整性摘要记录在 [运行资源锁](./resources/runtime-lock.json)。
14
+ - Python 本体适用 PSF 及其历史许可,见 [CPython 原文](./resources/notices/PYTHON-LICENSE.txt)。PBS 构建工具仓库的 MPL-2.0 不等于其产物中所有软件的许可。
15
+ - PBS install_only 转换不会保留 full 包的额外 licenses 目录,因此本包随附同发行原文,涵盖 CPython、bzip2、Expat、libffi、liblzma、OpenSSL 3、SQLite、Tcl、Tix 与 zlib。见 [许可来源和哈希](./resources/notices/provenance.json)。已解压运行时的 LICENSE.txt、wheel 中 dist-info/licenses 均保留。
16
+ - Windows UCRT 是操作系统组件;插件不会修改或安装系统 VC Runtime。缺失 DLL 会报告准备/自检失败,不复制其它安装目录的 DLL,也不静默执行系统安装器。
17
+
18
+ ### pymobiledevice3
19
+
20
+ - 版本:11.45.0。
21
+ - 项目与对应源代码:<https://github.com/doronz88/pymobiledevice3/tree/v11.45.0>。
22
+ - 原始分发:<https://pypi.org/project/pymobiledevice3/11.45.0/>。
23
+ - 许可:**GPL-3.0-or-later**,原文见 [GPL 许可文本](./resources/notices/PYMOBILEDEVICE3-LICENSE.txt)。
24
+ - 插件通过受控子进程运行其 CLI,不修改或合并其源代码。此技术划分不代表免除适用的再分发义务。如果今后提供内置/镜像 wheel 或离线完整包,应在发布前另行提供适用的源码、许可材料及再分发审查。
25
+
26
+ ### 完整 Python 依赖
27
+
28
+ 运行资源锁针对 Windows x64 的 CPython 3.9~3.13 记录完整传递依赖、版本、wheel URL、大小和 SHA256。各软件继续适用自己的元数据/包内许可,不同依赖可能有 MIT、BSD、Apache、GPL/LGPL 或其它条款。安装保留其原始 dist-info 与许可文件,并可通过环境中的包元数据查询。
29
+
30
+ 目前 Python 3.14 的 pylzss 依赖没有满足本方案的 Windows wheel,因此不在锁中;不在用户主机源码编译,而选择经过锁定的私有备用解释器。
31
+
32
+ ## Node.js 直接依赖
33
+
34
+ `@deepseek-ai/schemastery`、`zod` 及宿主提供的 DSH/Cordis 包分别遵循各自分发文件中的许可。插件界面复用宿主 React,不附带另一份 React,也不从 CDN 下载界面脚本。
35
+
36
+ ## 构建工具
37
+
38
+ `uv` 只用于开发阶段解析多 Python ABI 的 wheel 闭包,未安装到宿主 Python,也不随插件分发。开发下载来源、版本和哈希保存在构建目录;用户初始化不下载或调用 uv。
39
+
40
+ ## 原创资源
41
+
42
+ 插件图标为本项目原创,按 MIT 分发。
@@ -0,0 +1,20 @@
1
+ # Optional profile bundle layer; this does not install itself or modify a live GUI.
2
+ # The bare package specifier resolves via package main/exports to ./lib/plugin.mjs.
3
+ # Compose after the profile's tools, approval and systemPrompt providers.
4
+ - insert:
5
+ - id: ios-webview-app-control
6
+ name: dsh-ios-webview-app-control
7
+ config:
8
+ # Existing bridge only. Empty requires an explicit endpoint at connect.
9
+ endpoint: ''
10
+ # Preferred base interpreter only; packages always live in a private venv.
11
+ pythonPath: ''
12
+ runtime:
13
+ autoPrepare: true
14
+ directory: ''
15
+ offline: false
16
+ timeoutMs: 900000
17
+ stateDir: ''
18
+ allowEval: false
19
+ timeoutMs: 15000
20
+ maxLeaseSeconds: 120
@@ -0,0 +1,68 @@
1
+ # 安装与升级指南
2
+
3
+ 这里说明怎么通过官方插件管理通道安装或升级本插件,以及怎么确认它真的生效。不同部署的 profile、DSH 版本、路径和端口不一样,示例里的占位符按实际环境替换。
4
+
5
+ ## 前置确认
6
+
7
+ 1. 确认目标 DSH 版本在 [package.json](../package.json) 的 `engines.dsh` 与 `peerDependencies` 范围内。不要用版本豁免绕过兼容检查;范围外版本未经验证。
8
+ 2. 先在项目根目录构建并校验待安装归档。
9
+
10
+ ```powershell
11
+ npm ci --ignore-scripts
12
+ npm run build
13
+ npm run check
14
+ npm test
15
+ New-Item -ItemType Directory -Path artifacts -Force | Out-Null
16
+ npm pack --pack-destination artifacts
17
+ node scripts/verify-package.mjs
18
+ node scripts/smoke-package.mjs
19
+ ```
20
+
21
+ 3. 用 `plugin_manager list_bundles` 确认目标 profile 与已安装版本,避免装错 profile 或重复安装。
22
+
23
+ ## 通过官方插件管理通道安装
24
+
25
+ 1. 使用目标 DSH 的 `plugin_manager install_bundle` 指向 `<project-root>` 或本地 tgz。不要手写 profile、不改 app.asar、不加版本豁免。
26
+ 2. 如管理器要求先移除旧版本,按提示移除后安装;安装会选中 bundle 层。
27
+ 3. 以返回的 `application` 与 `warnings` 判断应用结果;`applied` 仍需要实际核对。
28
+ 4. 返回 `restart-required` 时,保存会话工作后完整退出并重开 DSH;刷新页面不能替代 Host 模块重启。
29
+ 5. 安装或升级会影响同一 profile 的所有会话;先确认没有未保存工作。包内文档是打包时快照。
30
+
31
+ ## Desktop 部署的脚本入口
32
+
33
+ 仓库的 [Desktop 管理脚本](../scripts/manage-desktop.ps1) 仅用于 Electron Desktop 安装器部署,调用该安装器自带的官方 `dsh-desktop-host/cli.js`,不绕过 profile 保护,默认操作该 Desktop 部署的 profile。其它 profile 请使用对应插件管理入口或 CLI 显式指定。
34
+
35
+ ```powershell
36
+ pwsh -NoProfile -File scripts/manage-desktop.ps1 -Action list
37
+ pwsh -NoProfile -File scripts/manage-desktop.ps1 -Action install -CheckOnly
38
+ pwsh -NoProfile -File scripts/manage-desktop.ps1 -Action install
39
+ # 卸载(不删除证据、不终止外部 bridge)
40
+ pwsh -NoProfile -File scripts/manage-desktop.ps1 -Action remove
41
+ ```
42
+
43
+ 脚本默认归档由当前 `package.json` 版本推导;`-Archive` 可指定其它位置,但仍会校验归档名称、版本、兼容声明、入口与分发资源一致。
44
+
45
+ ## 判定安装是否生效
46
+
47
+ - Config 查询出现 `include:ios-webview-app-control`,且 schema 状态正常。
48
+ - 工具发现包含 13 个工具,其中包括 `ios_environment`。
49
+ - 0.2.1 起,`ios_capabilities` 返回 `scope=plugin-only`、`inventory=not-session-inventory`,并说明这是本插件自述、不是会话工具清单。
50
+ - 安装目录 manifest 版本与待安装归档一致;不能只看 `enabled` 或 fiber 为 active。
51
+ - 没看到这些结果,就把原始返回留下来查原因。不要为了通过验证去删环境、扩大插件范围或者改审批。
52
+
53
+ ## 失败与恢复
54
+
55
+ - 版本不兼容:按错误码处理,不在不满足范围时强行豁免。
56
+ - 安装失败或取消:按管理器的恢复结果处理,不手工修改受保护 profile。
57
+ - 环境没就绪:用 `ios_environment status` 看本插件状态。它和设备连接、其它工具、授权是三件事。
58
+ - 旧版本模块可能继续服务到进程重启;需要新说明生效时,以完整重启后的真实工具结果为准。
59
+
60
+ ## 已验证环境(仅开发环境快照)
61
+
62
+ 这是某次开发验证的快照,既不是安装要求,也不是兼容承诺或运行前提。
63
+
64
+ - 2026-10-31,Windows x64;DSH 0.2.1-rc.5;Node 22.18.0;Cordis 4.0.5;Schemastery 3.18.5。
65
+ - 通过官方管理器移除旧 0.2.0、安装固定 0.2.1 tgz,返回 `application: applied`、`version: 0.2.1`、`warnings: []`;pnpm 另有非阻断 peer 提示。
66
+ - 固定包:57 文件、163,988 字节;SHA256 `e62eae32011c1d394bbc35e94b805ceb39c55f162dbb080facb02bcf9d73d138`;204 项测试与 tgz 导入 smoke 通过。
67
+ - 重启前真实工具与描述还是旧的。完整重启后,`ios_capabilities` 才返回 `scope=plugin-only`、`inventory=not-session-inventory`,Tool Inspect 也换成新描述。所以 `applied` 不能直接当成「当前 Agent 已收到新说明」。
68
+ - 未调用真实设备操作,未修改审批策略;私有 Python 环境准备在该快照中未完成(下载阶段超时),不作为已验收项。
@@ -0,0 +1,29 @@
1
+ # 新会话复用提示词
2
+
3
+ ## 已安装此插件后的操作会话
4
+
5
+ ```text
6
+ dsh-ios-webview-app-control 仅提供自己的 ios_* 工具,不是整个 DSH 会话的能力管理器。ios_capabilities 中 android:false、nativeTap:false 等只表示本插件未实现,不代表其它工具不存在、不可用或已获授权,也不检查手机 USB 连接。
7
+ 对 Android、原生、Flutter、React Native 或其它超范围任务,不拿本插件做能力检测,不要求先准备它的 Python/bridge/租约;独立检查当前会话实际暴露的相关工具、skill 与权限。另有核实可用且已授权工具时按其合同处理;未核查前只说未知,不宣称整个会话不能操作。
8
+ 如果确实使用本插件,必须由我确认 ios + webview/hybrid、设备 UDID、已有 loopback bridge 绑定及 exact target 的 App 身份;按 connect → targets → bind_target → acquire,并逐次审批后再读/截图/DOM/eval。不能改标应用类型通过本插件校验;新 target/已知导航后重新绑定。
9
+ 审批拒绝、取消、缺失、不可用或 policy never 阻止同一操作时,不能改走 shell、CLI、核心导入或其它工具规避。判断其它平台任务是否有独立工具,不等于获得调用授权。
10
+ 只执行我随后明确的任务;不内置业务流程、不启动重复 bridge、不停止其它窗口服务,不把 DOM 事件或 WebView 渲染图当成原生触控或完整设备截图。
11
+ ```
12
+
13
+ ## 创造模式会话:继续安装和验收
14
+
15
+ ```text
16
+ 读取项目 README、SDK 合同和验证记录后核对目标 runtime/profile。先 build/check/test/pack,不修改 DSH 安装文件、受保护 profile 或业务项目。
17
+ 本插件的设备范围仍只接受操作者确认的 iOS WebView/混合应用;Android/原生/Flutter 等应由其它实际可用且已授权的工具独立评估,不能从本插件 false 标志推断全会话不支持。不要在本插件中加入替代后端或改标目标类型。
18
+ 通过官方插件管理器安装当前校验过的 tgz,按 application/warnings 判断应用状态,安装后核对 source/scope/inventory 标记及真实工具说明。环境状态只诊断本插件;真实设备操作必须另行逐次批准。没有设备/审批/GUI验收条件时准确报告未覆盖,不注册自动批准器。
19
+ ```
20
+
21
+ ## 能力判读示例
22
+
23
+ | 场景 | 正确处理 | 不应作出的结论 |
24
+ | --- | --- | --- |
25
+ | 只有本插件返回 android:false | 本插件不提供 Android 控制;其它会话工具尚未检查 | 整个 DSH 会话不能操作 Android |
26
+ | 当前会话另有独立适用工具 | 核对它的声明、目标和授权后再决定调用 | 本插件 false 会禁用其它工具,或其它工具天然已授权 |
27
+ | 手机 USB 已连接 | 将连接状态与控制工具、授权分别验证 | 已连接就一定能由 Agent 点击,或不能点击就是连接坏了 |
28
+ | 用户说另一个对话能操作 | 检查当前会话实际工具,不复制对话间权限 | 另一个对话成功就证明此处也能调用 |
29
+ | 合法 iOS 操作被审批拒绝 | 停止同一被阻止操作,不换道执行 | scope 澄清允许绕过审批 |
@@ -0,0 +1,40 @@
1
+ # 私有 Python 运行环境
2
+
3
+ `0.2.0` 不再要求用户预先安装 `pymobiledevice3`。
4
+
5
+ ## 选择与隔离
6
+
7
+ 1. 插件检测明确配置、`DSH_IOS_PYTHON`、`DSH_PRIMARY_RUNTIME`、Windows `py.exe`、标准注册记录和真实 PATH Python;跳过 Windows Store 别名。
8
+ 2. 只接受 64-bit CPython,且该 Python 的 ABI 在 [runtime-lock.json](../resources/runtime-lock.json) 中有完整、逐 wheel SHA256 锁定的依赖闭包。当前锁支持 CPython 3.9–3.13;3.14 因 `pylzss` 没有满足条件的 Windows wheel 不接受。
9
+ 3. 宿主 Python 只用作 base,不向它安装任何包。`pymobiledevice3` 和所有传递依赖安装到用户目录 `.dsh-ios-webview-app-control/runtime/generations/...` 的私有 venv,使用 `--no-index --require-hashes --only-binary :all: --require-virtualenv --no-user`。
10
+ 4. 没有合适宿主时,下载锁定的 PBS CPython 3.13.18 Windows x64,先验证大小和 SHA256,再安全解包到插件自己的 base 目录。
11
+ 5. `venv` 直接在最终 generation 路径创建,不移动。ready 指针原子发布。失败或取消不会替换上一个 ready 环境。准备锁采用保守的 fail-closed 策略,发现已有锁就不自动抢占,哪怕旧 PID 已经结束,也要后续明确清理。
12
+
13
+ 默认配置如下。
14
+
15
+ ```yaml
16
+ runtime:
17
+ autoPrepare: true # 有 subprocess 宿主时后台准备;不访问设备
18
+ directory: '' # 默认用户目录 runtime;必须是插件私有绝对目录
19
+ offline: false # 只使用已经通过哈希校验的缓存
20
+ timeoutMs: 900000 # 10,000..3,600,000 ms
21
+ ```
22
+
23
+ `autoPrepare` 只初始化本地环境,不包含 `usbmux list`、设备配对、bridge 启动或手机审批。若没有 DSH managed subprocess,插件仍可查看状态;用户可以通过 `ios_environment prepare` 或 CLI 准备。
24
+
25
+ ## 状态与操作
26
+
27
+ - `ios_environment status`:只读查看阶段、来源、ABI、私有解释器路径、下载进度和安全错误摘要。
28
+ - `ios_environment prepare`:环境已在 Full access 或一次性授权下准备;下载来源、版本、哈希由包内锁定资源决定,wire 参数不能覆盖。
29
+ - `ios_environment cancel`:取消当前准备并等待其自有子进程范围结束。
30
+ - `ios_environment cleanup`:二次确认后只删除插件拥有的闲置 generation/base/cache,保留 active ready 环境、截图证据、设备租约和宿主 Python。
31
+
32
+ 设置页提供相同状态与操作。页面只订阅 status/follow,不在挂载时自动 prepare;取消可中止进行中的 prepare。当前环境 ready 不表示手机连接、App 类型确认或设备操作授权。
33
+
34
+ ## 失败与恢复
35
+
36
+ 网络、证书、HTTP、超时、磁盘、权限、锁、哈希、归档路径、缺失 wheel、Python/DLL 和自检错误都会 fail closed。不切换未锁定版本,不关 TLS,不源码编译,也不静默安装系统 VC Runtime。准备失败会保留上一个 ready pointer,修好原因后可以重试。`requirePython()` 只返回已经验证过的私有 venv 解释器,不会在 `ios_devices` 调用里隐式安装。
37
+
38
+ ## 分发与许可证
39
+
40
+ npm 包不内置约 22 MB 的 PBS 压缩二进制或约 76 MB 的依赖 wheel;只带锁、代码和许可原文。缺少宿主时首次准备按需下载。`pymobiledevice3` 是 GPL-3.0-or-later;PBS/CPython及其内嵌库各自适用许可,完整来源见 [THIRD_PARTY_NOTICES.md](../THIRD_PARTY_NOTICES.md)。
@@ -0,0 +1,79 @@
1
+ # DSH SDK 兼容合同
2
+
3
+ ## 兼容基线
4
+
5
+ 本合同对应插件 **0.2.1**。插件声明的兼容范围以 [package.json](../package.json) 的 `engines.dsh` 与 `peerDependencies` 为准;范围内版本需按本文合同使用,范围外不作兼容承诺。
6
+
7
+ 0.1.0 曾精确要求 rc.3 的 tools/system-prompt/user-approval/llm,在 rc.5 运行时被 `incompatible-version` 拒绝,不会创建 Loader 行。0.2.x 改用 `^0.2.1-rc.5` 的 peer 范围,没有拿版本豁免绕过检查。
8
+
9
+ | 项目 | 声明范围 | 已验证版本(快照) |
10
+ | --- | --- | --- |
11
+ | Node | `>=22.18.0` | 22.18.0 |
12
+ | `engines.dsh` | `>=0.2.1-rc.5 <0.3.0` | 0.2.1-rc.5 |
13
+ | 四项 DSH peer | `^0.2.1-rc.5` | 0.2.1-rc.5 |
14
+ | Cordis | `~4.0.5` | 4.0.5 |
15
+ | Schemastery | `~3.18.5` | 3.18.5 |
16
+
17
+ 版本范围是安装约束,不等于所有版本已测试。未验证 alpha、未来 0.3 或其它 SDK;更新范围前应重新查询 Service 合同、读取目标版本说明并运行集成测试。
18
+
19
+ ## Host 适配合同
20
+
21
+ [插件入口](../src/plugin.mjs) 注册 Host 工具,并提供环境管理 Client 界面。使用具名 `name`、`inject`、`Config`、`apply` 导出,依赖 `tools`、`approval`、`systemPrompt`。这些入口已经按 SDK 说明和运行时 Inspect 核对过,快照见文末。
22
+
23
+ 1. `ctx.tools.register(defineTool({...}))` 注册 13 个工具,系统提示词自动获得可见工具 schema。`defineTool.parameters` 是每个参数带 `required: true` 的属性映射,不是根 JSON Schema。已验证版本 SDK 的隐式根对象仍开放,适配层自行拒绝额外参数,防止 caller 注入 owner、signal、后端、解释器或证据路径。
24
+ 2. `execute(args, exec)` 返回规范 JSON 值,`output.render` 产生文本内容。作者 DSL 的 `output.schema: {type:'json'}` **合法**,会编译为无约束 JSON schema `{}`,不能误改为未知 API。截图返回本地文件及元数据,而非原生截图或自动图片内容块。
25
+ 3. 必须有 `exec.agent.session.id` 和活的 `exec.signal`。owner 只能来自真实会话,不来自模型参数。精确 signal 传入核心,审批前后检查取消。
26
+ 4. 审批调用为 `ctx.approval.request({agent, toolName, callId, reason, signal})`;只接受裸字符串 `allowed-once`。`rejected`、`cancelled`、`unavailable` 或其它值均不得派发设备操作。
27
+ 5. 有效策略来自公开 `approval.overrideOf(session)`,否则 `approval.config.policy`,默认 `ask`。适配层在请求前与获得许可后检查,`never` 或未知策略拒绝操作。不得调用私有策略方法、改策略、添加自动答复器或缓存授权。
28
+ 6. 已测版本的真实 ApprovalService 要求当前有未结束的 turn,保证 `approval/asked` 与 `approval/decided` 审计成对入日志。空闲会话请求会抛错;缺失/抛错/非法答复器归一化为 unavailable。插件不得绕过审计失败。只在隔离测试中配置假答复器,绝不在真实 profile 中自动批准。
29
+ 7. `ctx.systemPrompt.section({name, order, text})` 注册补充指引,不替换整体提示词。名称为 `tool:ios-webview-app-control`,order 为 2250。
30
+ 8. 一个 `ctx.effect(function*(){...})` 组合资源:先 yield 核心 disposer,再 yield 提示词 disposer,再 yield 每个工具 disposer。逆序清理先移除工具和指引,再等待核心取消/排空;不依赖兄弟 effect 的清理顺序。
31
+ 9. 适配层将核心错误包装为真实 `HarnessError(message, code, {cause})`,保留机器错误码。操作已派发但结果未知时,固定提示人工核对后再决定重试,不泄露 token/expression 等 details。
32
+
33
+ ## 配置及运行时定位
34
+
35
+ 默认值见 [bundle patch](../cordis.patch.yml) 和 [Config](../src/plugin.mjs)。Loader 后续按 id 覆盖时替换完整 config,不是深度合并。
36
+
37
+ | 字段 | 默认值 | 含义 |
38
+ | --- | --- | --- |
39
+ | endpoint | 空字符串 | 已有 loopback HTTP bridge;留空必须在 connect 明确给出 |
40
+ | pythonPath | 空字符串 | 部署明确配置的 Python 绝对路径 |
41
+ | stateDir | 空字符串 | 证据目录,默认插件自己的用户目录 |
42
+ | allowEval | false | 任意 JS 的独立部署开关,每次仍需授权 |
43
+ | timeoutMs | 15000 | 核心 I/O 超时,整数 1..120000 |
44
+ | maxLeaseSeconds | 120 | 租约上限,整数 5..600 |
45
+
46
+ [环境管理器](../src/runtime/environment-manager.mjs) 先看 `pythonPath`、`DSH_IOS_PYTHON`、`DSH_PRIMARY_RUNTIME`,再查 launcher、标准注册记录和真实 PATH Python,跳过 Store 别名。只在插件私有目录建 venv、装锁定依赖。没有合适的 base 时,按需准备私有 Python。设备调用只会拿到已经就绪的解释器,或者报 `environment_not_ready`,不会隐式安装。这个环境状态也不诊断其它工具。详见 [私有环境说明](./runtime-environment.md)。
47
+
48
+ 宿主如果提供 `load_workspace_dependencies`,可以先拿到受支持的 Python 路径,再交给操作者配置。它不是插件里能猜名字调用的 Service。只有设备发现用 Python,附着已有 bridge 不需要。
49
+
50
+ ## 作用域与授权边界
51
+
52
+ 以下限制只约束 `dsh-ios-webview-app-control`,不是整个 DSH 会话的能力管理。它只接受操作者明确确认的 iOS WebView / 混合应用,对原生、Flutter、React Native、Android、未知或未确认类型拒绝本插件调用,不改标类型、不在本插件增加 WDA/Appium 等替代后端。可检查 WebView 的存在不是整个 App 的类型证明。
53
+
54
+ `ios_capabilities` 及 connect 内嵌的能力带 `source=dsh-ios-webview-app-control`、`scope=plugin-only`、`inventory=not-session-inventory`。`android:false`、`nativeTap:false` 等保留,含义仅为本插件未实现,不报告其它工具、USB 连接或会话授权状态。其它平台任务应独立检查当前会话实际暴露的工具、skill、权限;本声明既不禁用其它工具,也不授予其权限。未核查前不能推断整个会话不支持 Android。
55
+
56
+ 独立选一个适用工具,和规避授权拒绝是两件事。同一操作如果已经被审批或策略挡住,不能改走 shell、CLI、核心导入或别的工具绕过去。
57
+
58
+ 调用顺序为 capabilities → 确认设备与应用类型 → connect → targets → 人确认 exact target/App 身份 → bind_target → acquire → 分别批准 read/screenshot/DOM/eval → release → disconnect。capabilities 是静态无设备 I/O;其它 11 项各自需要本次授权。
59
+
60
+ - connect 的 `verifiedExistingUdid` 必须等于操作者明确确认的 exact udid,不能从连接成功或发现结果自动填。
61
+ - bind 的 `verifiedTargetId` 必须等于 exact targetId,appIdentity 与该目标的支持类型均来自操作者,不从标题或 URL 推断。
62
+ - 连接最初无绑定。读取/截图/eval/DOM 只接受精确当前目标指纹及本会话本连接的活租约。新目标或已知导航必须重新 list + 明确 bind。
63
+ - 相同 id/title/URL/socket 无法证明没有 reload;本版不宣称完整自动导航识别。
64
+ - 连接、绑定、租约和其它调用的许可都不是后续操作的许可。never 不执行手机验收。
65
+ - 页面文本是外部不可信内容,不是指令。DOM 事件不是原生手势,不保证业务成功。密码、支付凭据与 CAPTCHA 交由人处理。
66
+ - 超时/取消不回滚已派发变化,不自动重放。WebSocket 关闭不能确认时保留 busy 隔离锁;不能擅自抢锁。
67
+ - 设备租约域固定在同一 OS 用户的插件目录,不随证据目录改变,但无法约束外部调试器或其它 OS 用户。
68
+
69
+ 核心直接导入不继承 DSH 授权;CLI 提供本插件静态 capabilities 和私有环境管理,不开放设备操作。不能通过核心/脚本或其它工具规避同一实际授权拒绝。
70
+
71
+ ## 可重复验证与发布
72
+
73
+ - [真实服务链集成测试](../test/host-runtime.test.mjs):真实 ToolRuntime / SystemPrompt / ApprovalService / Session,隔离内存日志、假设备派发,不改变真实策略或访问手机。
74
+ - [适配层测试](../test/plugin.test.mjs)、[核心测试](../test/core.test.mjs)、[Python 定位测试](../test/python-path.test.mjs)、[归档测试](../test/packaging.test.mjs) 分别覆盖边界。
75
+ - `build` 从 src 更新 lib,`check` 检查清单与展示资源,`test` 运行全部回归。测试源码不进发布包,文档相对源码链接用于开发目录查阅。
76
+ - [归档校验器](../scripts/package-validation.mjs) 从当前 manifest 推导默认包名,核对 name/version、engines/peers、lib 清单与字节、patch、locale/icon 和管理脚本;拒绝旧归档,不因验收文档后续更新而误报代码变化。
77
+ - 通过官方 `plugin_manager install_bundle` 安装,读取 application/warnings;`restart-required` 不是已生效。不要用写 profile、强制版本豁免或另起服务器代替正式安装。
78
+
79
+ 实际执行状态见 [验证记录](./verification.md) 的已验证环境快照与 [安装记录](./installation.md);静态注册和隔离测试不能代替真实手机验收。