@mearl/client 2.20.6 → 2.21.0

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 (105) hide show
  1. package/README.md +122 -2
  2. package/dist/cli.js +10 -5
  3. package/dist/commands.d.ts +14 -5
  4. package/dist/commands.js +21 -2
  5. package/dist/generated-browser-action-protocol.d.ts +11 -1
  6. package/dist/generated-browser-action-protocol.js +3 -0
  7. package/dist/generated-plugin-diagnostics.d.ts +110 -0
  8. package/dist/generated-plugin-diagnostics.js +1 -0
  9. package/dist/generated-plugin-execution.d.ts +27 -0
  10. package/dist/generated-plugin-execution.js +1 -0
  11. package/dist/generated-plugin-models.d.ts +64 -0
  12. package/dist/generated-plugin-models.js +1 -0
  13. package/dist/generated-plugin-pages.d.ts +76 -0
  14. package/dist/generated-plugin-pages.js +59 -0
  15. package/dist/generated-plugin-recovery.d.ts +32 -0
  16. package/dist/generated-plugin-recovery.js +1 -0
  17. package/dist/generated-plugin-state.d.ts +50 -0
  18. package/dist/generated-plugin-state.js +1 -0
  19. package/dist/generated-plugin-tasks.d.ts +74 -0
  20. package/dist/generated-plugin-tasks.js +7 -0
  21. package/dist/generated-toolbox-icon.d.ts +10 -0
  22. package/dist/generated-toolbox-icon.js +37 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.js +6 -0
  25. package/dist/plugin-task-host.d.ts +1 -0
  26. package/dist/plugin-task-host.js +14 -0
  27. package/dist/plugin-worker.d.ts +1 -0
  28. package/dist/plugin-worker.js +17 -0
  29. package/dist/plugin.d.ts +57 -4
  30. package/dist/plugin.js +296 -15
  31. package/dist/pluginCliOutput.d.ts +2 -0
  32. package/dist/pluginCliOutput.js +7 -0
  33. package/dist/pluginCommandWorker.d.ts +2 -0
  34. package/dist/pluginCommandWorker.js +174 -0
  35. package/dist/pluginDiagnostics.d.ts +26 -0
  36. package/dist/pluginDiagnostics.js +309 -0
  37. package/dist/pluginExecution.d.ts +21 -0
  38. package/dist/pluginExecution.js +43 -0
  39. package/dist/pluginExecutor.d.ts +29 -0
  40. package/dist/pluginExecutor.js +223 -0
  41. package/dist/pluginExecutorProtocol.d.ts +55 -0
  42. package/dist/pluginExecutorProtocol.js +47 -0
  43. package/dist/pluginExecutorSupervisor.d.ts +4 -0
  44. package/dist/pluginExecutorSupervisor.js +63 -0
  45. package/dist/pluginHost.d.ts +20 -0
  46. package/dist/pluginHost.js +53 -0
  47. package/dist/pluginHostConnection.d.ts +35 -0
  48. package/dist/pluginHostConnection.js +257 -0
  49. package/dist/pluginHostFiles.d.ts +1 -0
  50. package/dist/pluginHostFiles.js +21 -0
  51. package/dist/pluginHostPaths.d.ts +11 -0
  52. package/dist/pluginHostPaths.js +22 -0
  53. package/dist/pluginHostServer.d.ts +7 -0
  54. package/dist/pluginHostServer.js +252 -0
  55. package/dist/pluginModelCatalog.d.ts +14 -0
  56. package/dist/pluginModelCatalog.js +51 -0
  57. package/dist/pluginModelDefinition.d.ts +6 -0
  58. package/dist/pluginModelDefinition.js +75 -0
  59. package/dist/pluginModelSessionWorker.d.ts +23 -0
  60. package/dist/pluginModelSessionWorker.js +60 -0
  61. package/dist/pluginModelSessions.d.ts +16 -0
  62. package/dist/pluginModelSessions.js +234 -0
  63. package/dist/pluginModels.d.ts +17 -0
  64. package/dist/pluginModels.js +47 -0
  65. package/dist/pluginPageBundle.js +74 -17
  66. package/dist/pluginPageDefinition.d.ts +3 -0
  67. package/dist/pluginPageDefinition.js +62 -0
  68. package/dist/pluginPageManager.d.ts +57 -0
  69. package/dist/pluginPageManager.js +877 -0
  70. package/dist/pluginPages.d.ts +21 -0
  71. package/dist/pluginPages.js +46 -0
  72. package/dist/pluginProcessTree.d.ts +2 -0
  73. package/dist/pluginProcessTree.js +31 -0
  74. package/dist/pluginRecoveryDefinition.d.ts +3 -0
  75. package/dist/pluginRecoveryDefinition.js +56 -0
  76. package/dist/pluginRegistry.d.ts +2 -3
  77. package/dist/pluginRegistry.js +14 -13
  78. package/dist/pluginRevision.d.ts +14 -0
  79. package/dist/pluginRevision.js +227 -0
  80. package/dist/pluginRuntimeCleanup.d.ts +2 -0
  81. package/dist/pluginRuntimeCleanup.js +55 -0
  82. package/dist/pluginState.d.ts +26 -0
  83. package/dist/pluginState.js +28 -0
  84. package/dist/pluginStateDefinition.d.ts +4 -0
  85. package/dist/pluginStateDefinition.js +68 -0
  86. package/dist/pluginStateManager.d.ts +24 -0
  87. package/dist/pluginStateManager.js +132 -0
  88. package/dist/pluginStateStore.d.ts +57 -0
  89. package/dist/pluginStateStore.js +396 -0
  90. package/dist/pluginTaskManager.d.ts +92 -0
  91. package/dist/pluginTaskManager.js +1080 -0
  92. package/dist/pluginTaskProtocol.d.ts +47 -0
  93. package/dist/pluginTaskProtocol.js +1 -0
  94. package/dist/pluginTaskStore.d.ts +53 -0
  95. package/dist/pluginTaskStore.js +319 -0
  96. package/dist/pluginTaskWire.d.ts +4 -0
  97. package/dist/pluginTaskWire.js +42 -0
  98. package/dist/pluginTasks.d.ts +51 -0
  99. package/dist/pluginTasks.js +181 -0
  100. package/dist/pythonPlugin.d.ts +13 -2
  101. package/dist/pythonPlugin.js +235 -30
  102. package/dist/socket.js +5 -2
  103. package/dist/unified.d.ts +1 -0
  104. package/dist/unified.js +81 -0
  105. package/package.json +7 -3
package/README.md CHANGED
@@ -137,10 +137,19 @@ npx @mearl/setup provider uninstall brow
137
137
  | `--payload <json>` | 直接传入 JSON 参数 |
138
138
  | `--payload-file <path>` | 从文件读取 JSON 参数 |
139
139
  | `--timeout <seconds>` | 请求超时时间 |
140
- | `--compact` | stdout 紧凑输出 |
140
+ | `--compact` | 强制 stdout 紧凑输出 |
141
141
  | `--output <path>` | 将结果写入文件(如截图) |
142
142
  | `--browser <id\|名称>` | 指定目标浏览器 |
143
143
 
144
+ CLI、SDK、MCP 使用同一返回结构。快照中的 `@eN` 可直接用于操作,内部节点映射只保存在运行时。
145
+ 常规响应的 `session` 包含会话 ID、浏览器、传输、状态和代次;标签页清单通过 `tab_list` 查询,
146
+ `browser_control` 的交接结果还包含会话页面的 `tabs`。`run_actions` 的步骤使用各 action 的返回结构。
147
+ stdout 在管道或重定向时默认输出紧凑 JSON,在交互终端默认美化;`--compact` 可强制紧凑排版,不改变返回字段和值。快照会折叠无名称、无 ref 且无状态的分组,控件状态与文本内容完整保留。
148
+
149
+ `get_requests` 指定非空 `fields` 时默认省略请求体和响应体,只返回提取字段及请求元数据;
150
+ 需要同时读取全文时显式传 `includeBody:true`。省略正文时不返回 `postData` / `responseBody` 字段;
151
+ 未指定字段时默认返回正文。
152
+
144
153
  Mearl 默认聚合当前机器和已配置 cloud-server 下的浏览器,并通过 `browser_list` 返回的全局
145
154
  `browserId` 自动路由。以下覆盖参数仅在限定宿主或连接、传输排障时使用,因此不出现在默认 help:
146
155
 
@@ -226,6 +235,30 @@ const result = await invokePlugin(
226
235
 
227
236
  MCP Server 通过固定工具 `plugin_invoke` 接受同样的 `plugin`、`command` 和 `input`,不会把插件子命令动态扩展成 MCP 工具。SDK 与 MCP 不接受任意入口路径;调用尚未注册的 `buc`、`authx` 或 `tdbank` 时,会通过匹配当前 client 版本的 setup 自动安装并重试一次。其他未注册名称返回 `PLUGIN_NOT_REGISTERED`。
228
237
 
238
+ 长命令使用本机持久任务服务。服务按注册目录隔离并自动启动,CLI、SDK、MCP 与工具箱共享任务记录;调用方退出不取消执行。服务重启后将未完成任务标记为 `interrupted`,不自动重放。后台任务固定接受时的源码快照、工作目录与环境;静态第三方 JS 依赖需要预先打包进 Skill,状态文件放在源码目录之外。
239
+
240
+ ```ts
241
+ import { PluginTaskClient } from '@mearl/client';
242
+
243
+ const tasks = new PluginTaskClient();
244
+ try {
245
+ const accepted = await tasks.start('example', { command: 'read', input: {} }, {
246
+ executionTimeoutMs: 120000,
247
+ idempotencyKey: 'document-123',
248
+ });
249
+ const result = await tasks.wait(accepted.taskId, { timeoutMs: 30000 });
250
+ console.log(result);
251
+ } finally {
252
+ tasks.disconnect();
253
+ }
254
+ ```
255
+
256
+ `wait` 超时或其 signal 中止只结束等待;`cancel(taskId)` 才取消执行。浏览器任务需显式传 `browser`,名称会在接受前解析为固定 ID。`get/list` 返回任务快照与结果引用,`list` 返回有界分页及 `nextCursor`;`events` 返回游标、缺口标记和最新快照,`subscribe` 封装长轮询。`result(taskId)` 分块读取并校验完整业务结果,最大 64 MiB;终态记录和结果保留 7 天。
257
+
258
+ 任务能力由 SDK `PluginTaskClient` 与工具箱 `host.task.*` 使用。对外命令由具体插件按业务需要提供,CLI 使用 `mearl <plugin> <command>`,MCP 使用 `plugin_invoke`。任务、模型、状态、页面实例和宿主诊断不单独暴露为全局 CLI/MCP 命令。仅注册工具箱内部命令的插件不会列入 CLI 插件列表;直接运行其名称会提示工具的打开位置。工具页可用 `window.mearl.waitTask(taskId)`、`readTaskResult(taskId)`、`listTasks()`,范围限定为所属插件的工具箱任务。
259
+
260
+ `tasks.diagnose({ taskId?, plugin?, instanceId?, includeErrorMessages?, includeLocalPaths? })` 读取当前调用范围内的有界诊断报告。默认不包含业务输入、提示词、进度正文、检查点数据、结果正文、完整 URL、环境变量和凭证,也省略错误消息及本地路径;后两项可显式选择包含。报告的 coverage 和历史 gap 表示采集范围及保留历史限制。
261
+
229
262
  注册记录在 `~/.mearl/plugins/<name>.json`,保存入口路径和可选的简短描述;skill 业务代码原地更新直接生效,换路径或更新描述后重新注册。
230
263
  `plugin uninstall <name>` 会对 `~/.agents/skills` 中的全局 Skill 调用 `ali-skills remove --global --yes`,
231
264
  成功后清除相关注册;即使入口目录已被手动删除,也会完成 Ali Skills 跟踪记录的清理。
@@ -271,9 +304,22 @@ export default function register(app) {
271
304
  ```
272
305
 
273
306
  `app.command(signature, handler, description?, examples?)` 注册 CLI、SDK 和 Agent 可调用的业务命令。
307
+
308
+ `toolbox.icon` 支持以下字符串形式,工具列表、切换菜单与网站安装目录使用同一格式:
309
+
310
+ ```js
311
+ icon: 'git-branch' // 内置图标名称,最多 40 字符,随主题变色
312
+ icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 4h16v16H4z"/></svg>' // 单色 SVG,随主题和交互变色
313
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#2563eb" d="M4 4h16v16H4z"/></svg>'
314
+ icon: 'https://example.com/tool-icon.svg' // HTTP(S) 图片地址,支持 SVG、PNG 等图片
315
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%2F%3E'
316
+ ```
317
+
318
+ 图标字符串最多 32768 字符。SVG 源码使用 `currentColor` 时,按单色遮罩渲染,继承与内置图标相同的主题、悬停和选中颜色;建议用 `fill="none" stroke="currentColor"` 绘制线框图标。显式指定颜色的 SVG、多色 Data URL 和远程图片按原图渲染。SVG 不注入扩展 DOM。远程图片使用无 referrer 请求;不接受带账号密码的 URL,加载失败或名称未知时显示通用图标。相对文件路径不在此字段的支持范围内。
319
+
274
320
  `app.toolboxCommand(signature, handler, description?, examples?)` 注册仅供工具页面调用的命令,参数和 handler 契约相同;
275
321
  它不出现在 CLI 帮助中,CLI(包括 JSON payload)、SDK、MCP 及插件间的 `app.invoke` 都不能调用。
276
- 工具页面通过 `window.mearl.invoke(command, input)` 或 `window.mearl.invoke('host.operation.start', { command, input })` 执行;两类命令都必须显式列在 `toolbox.page.commands` 中才能供页面调用。
322
+ 工具页面通过 `window.mearl.invoke(command, input)` 或 `window.mearl.invoke('host.task.start', { command, input })` 执行;两类命令都必须显式列在 `toolbox.page.commands` 中才能供页面调用。
277
323
  注册的 `toolboxCommand` 若没有列入该白名单,插件加载会失败。分块上传、分块读取和页面临时资源释放适合使用它;
278
324
  对 Agent 有独立业务价值的查询、导入、压缩、比较等完整操作使用 `app.command`。
279
325
  Python 入口也支持 `app.toolboxCommand(...)`,包括 `@app.toolboxCommand(..., description="...")` 装饰器。
@@ -324,6 +370,7 @@ AuthX 对应 `mearl authx request <url> [audience]`,省略 `audience` 时同
324
370
  | 标签页 | `tab_open` `tab_list` `tab_close` |
325
371
  | 页面感知 | `page_snapshot` `page_inspect` `page_screenshot` `page_frames` |
326
372
  | 页面操作 | `page_click` `page_drag` `page_type` `page_hover` `page_scroll` `page_press` `page_wait` `page_navigate` `page_upload` `page_eval` |
373
+ | 页面运行时 | `page_runtime`(内部文档适配,插件使用 `app.page`) |
327
374
  | 组合调用 | `run_actions` |
328
375
  | 环境与 Cookie | `set_device_emulation` `set_app_profile` `set_timezone` `get_cookie` `set_cookie` |
329
376
  | 浏览器 | `browser_list` `browser_launch` `browser_release` `browser_close` |
@@ -382,3 +429,76 @@ pnpm typecheck # 仅类型检查
382
429
  ## License
383
430
 
384
431
  ISC
432
+
433
+ ### 插件页面实例
434
+
435
+ `PluginPageClient` 通过本地插件服务管理 attach/get/list/send/detach/events/activation。插件导出独立 `pageRuntime` 声明并用 `app.page()` 调用。扩展与纯 CDP 共用实例、事件、激活和文档运行时;实例绑定 documentId,同插件同文档的所有入口共享初始化,导航后旧实例失效,启用的激活规则负责重建。`frame` 接受 `main`、`business` 或 `page_frames` 返回的 frame ID(扩展为数字,CDP 为字符串)。外部 Provider 仍须明确声明 `page_runtime` 能力。
436
+
437
+ 显式手动 `attach` 复用自动激活的实例时,实例转为手动归属,初始化与在途任务继续复用;随后收窄自动激活范围不会清理该实例。
438
+
439
+ 独立修改匹配范围时,可传 `enabled: true, matchPatch: { add?: string[], remove?: string[] }`,与 `matches` 互斥。宿主原子增删范围,避免并发调用覆盖其他范围;删除最后一个范围会关闭自动激活,保留手动挂载的页面实例。`persistence: 'persistent'` 在浏览器重启后保留,初始化 handler 可读取最新插件偏好,不必将易变配置复制到规则 input。
440
+
441
+ ```typescript
442
+ const pages = new PluginPageClient();
443
+ try {
444
+ const page = await pages.attach('example', { tabId: 123, frame: 'business' });
445
+ await pages.send('example', page.instanceId, { type: 'read' });
446
+ } finally { pages.disconnect(); }
447
+ ```
448
+
449
+ 后台事件声明 schema 和串行、latest 合并或有限并发策略,处理器用 `app.runtimeCommand()` 注册并通过 `context.page` 访问固定文档。文档绑定任务可用 `app.page('activation')` 只读查询本插件激活规则,不允许设置或关闭规则。页面消息/结果各上限 24 MiB,宿主自动分块并校验;事件负载上限 32 KiB。工具箱使用 `host.page.*`,UI 订阅实例历史与后台执行独立。完整契约见 [插件宿主能力](../native-host/README.md#页面运行时和事件)。
450
+
451
+ Python 入口同样导出 `pageRuntime` 字典,其中 `code` 仍是运行于网页中的 JavaScript 函数字符串;后台初始化与事件处理器通过 `app.runtimeCommand(...)` 或其装饰器注册。`app.page(operation, payload)`、`context.page.send(message)` 和 `context.page.get()` 都是同步调用,后两者仅在绑定页面实例的处理器中可用。JS 和 Python 的 `context.page.send(message, {timeoutSec: 120})` 可指定单次响应超时(大于 0 且最多 300 秒,Python 使用字典);`app.page("send", {instanceId, message, timeoutSec})` 和 SDK `pages.send(plugin, instanceId, message, {timeoutSec})` 同样支持。该设置不改变其他请求,任务取消和文档解绑仍立即中断执行,传输失败也会取消对应网页请求。runtime-only 命令不出现在公开命令帮助中,也不能由 CLI 或工具箱直接执行;声明在页面事件中的普通 `app.command` 仍保留公开调用能力。
452
+
453
+ ### 模型任务与声明状态
454
+
455
+ `PluginModelClient` 使用本机 Codex,不依赖浏览器连接;模型任务和命令任务共享查询、取消与无损结果通道,分别调度。先查询 `capabilities()`;当前只支持显式只读 Agent,严格无工具生成请求会失败。
456
+
457
+ ```typescript
458
+ import { PluginModelClient, PluginStateClient } from '@mearl/client';
459
+ const models = new PluginModelClient();
460
+ try {
461
+ const result = await models.run('example', {
462
+ provider: 'codex', mode: 'agent', permissions: 'read-only', prompt: 'Return a short title.',
463
+ outputSchema: { type: 'object', properties: { title: { type: 'string' } }, required: ['title'], additionalProperties: false },
464
+ }, { signal: controller.signal });
465
+ console.log(result.output);
466
+ } finally { models.disconnect(); }
467
+ ```
468
+
469
+ `start` 返回持久 taskId;`run` 的 signal 取消模型执行并等待清理。`app.model(request, { onProgress })` / `context.model(request, { onProgress })` 可订阅当前这一次调用的 `model.delta`,并发调用的回调互相隔离;Python 使用 `context.model(request, on_progress=callback)`。增量 `data` 含 `delta/index/partial`,可用时带 `itemId/phase`;按消息隔离、跳过 commentary,序号缺失时回退到最终结果。增量只供临时展示,最终结果来自成功 turn 的完整消息并经过宿主 schema 校验;临时显示必须在失败时撤回,不能直接作为缓存或业务成功依据。模型目录与执行通过 `PluginModelClient` 或插件上下文使用。工具页使用 `host.model.capabilities/list/start` 和 `waitTask`。
470
+
471
+ 插件入口声明状态集合,然后从命令上下文访问:
472
+
473
+ ```javascript
474
+ export const stateStorage = { version: 1, collections: {
475
+ settings: { scope: 'installation', storage: 'persistent', schemaVersion: 1, schema: { type: 'object' } },
476
+ } };
477
+ export default app => app.command('save', async (input, context) => {
478
+ const previous = await context.state('settings', 'get', { key: 'config' });
479
+ return context.state('settings', 'transact', { transaction: { operations: [
480
+ { type: 'put', key: 'config', value: input, expectedVersion: previous.version },
481
+ ] } });
482
+ });
483
+ ```
484
+
485
+ SDK `PluginStateClient.get/getMany/list/transact` 与工具箱 `host.state.*` 共享集合。每次写入需 CAS,冲突后重新读取、合并再重试;`schemaVersion` 升级用显式迁移事务。浏览器会话/实例可声明 `cache` 或 `memory`,页面身份由宿主验证。`memory` 只保存在插件执行宿主进程中,支持同样的 CAS、schema、TTL 与分块值限制;刷新文档时保留浏览器会话范围,浏览器会话变化后隔离,执行宿主重启时清空。内存状态全宿主合计最多 128 MiB / 512 个集合命名空间,按需占用;单集合 `maxBytes` 最大 128 MiB,实例结束释放其内存。容量、TTL 和完整契约见[插件宿主能力](../native-host/README.md#状态和激活)。二进制资产继续使用文件或资源通道。
486
+
487
+ ### 显式任务恢复
488
+
489
+ 插件声明 `taskRecovery`(每个命令的 checkpointVersion/schema)并注册 `app.recoveryCommand(command, handler)`,命令通过 `context.checkpoint(data, expectedSequence)` 保存最多 64 KiB 的恢复依据。检查点数据、版本、宿主 schemaHash、序号和事件与任务记录原子写入;写入必须 CAS。
490
+
491
+ `tasks.checkpoint(taskId)` 读取检查点;`tasks.resume(taskId, { environment?, revision? })` 为终态根命令建立新 attempt,保持旧任务终态,固定原安装、源码快照、输入、目录和路由。默认提交调用进程的新环境,旧环境不持久化。恢复入口读取 `context.recovery`,先核对外部操作状态;宿主不重放原 handler,也不保证外部提交与检查点原子。
492
+
493
+ SDK 使用 `tasks.checkpoint(taskId)` / `tasks.resume(taskId)`。当前仅支持 public/service 根命令,拒绝模型、子任务、页面绑定和 caller 路由恢复,且必须确认原执行树已经停止。默认固定原代码;显式 `revision: 'current'` 选择请求进入时的当前快照。同格式版本需 schema 相同,跨格式版本需目标 `taskRecovery` 声明 `migrateFrom: [{ version, schema }]` 并注册隐藏 `app.checkpointMigration(command, handler)`,返回目标检查点数据。宿主先核验历史 schemaHash,禁止转换中的宿主及嵌套插件 API,以 10 秒期限管理进程;转换必须可重试、无副作用,可信代码不构成 OS 沙箱。并发恢复合并为一个转换与后继任务,旧任务和数据保持不变。完整资格与故障域见[检查点与显式恢复](../native-host/README.md#检查点与显式恢复)。
494
+
495
+ 插件 CLI 调用失败以非零退出码和 stderr JSON `{ "error": { "code", "message" } }` 返回,保留 SDK/MCP 的 code,不输出任意异常附加字段。`PLUGIN_TASK_WAIT_TIMEOUT` 仅停止等待;`PLUGIN_EXECUTION_CANCELLED` / `PLUGIN_EXECUTION_DEADLINE` 表示执行取消或到期;`PLUGIN_PAGE_TARGET_CHANGED` / `PLUGIN_PAGE_INVALIDATED` 要求重新获取页面实例;`PLUGIN_STATE_CONFLICT` 需重新读取 CAS 版本;`PLUGIN_MODEL_CAPABILITY_UNSUPPORTED` 表示声明能力不支持;`PLUGIN_INVOCATION_CYCLE` / `PLUGIN_INVOCATION_DEPTH` 拒绝循环或过深组合。进程树无法确认停止时保留失败记录并拒绝恢复。
496
+
497
+ 开发环境可运行 `pnpm verify:plugin-host:default` 验证 SDK 与 PATH CLI 在原配置、原认证和默认模型下的完整执行;原配置保持不变。工具箱内显式页面 attach 缺少站点授权时会申请权限,由用户确认后继续;后台页面运行时不会自动弹窗申请。
498
+
499
+ 模型列表可通过 SDK `PluginModelClient.list()` 或工具箱 `host.model.list` 查询。模型项携带可用时的 `reasoningEfforts` 和 `defaultReasoningEffort`,界面按模型支持范围提供思考级别。宿主合并并发发现请求,已有模型目录立即返回,过期后后台刷新;刷新失败保留可用目录并短暂退避,不创建推理会话。状态批量读取使用 `get-many` 和 `keys`(SDK `getMany`、工具箱 `host.state.getMany`),一次读取同一 revision 的最多 128 个键,含缺失键的 CAS version,结果上限 1 MiB。
500
+
501
+
502
+ 插件宿主由 `PluginHost` 组装任务、状态、页面与模型目录服务,统一关闭和诊断。`PluginTaskManager` 接收明确的服务依赖并管理执行树;页面和状态服务不反向修改调度器。SDK 的连接、服务发现、握手、重连和调用桥接由 `PluginHostConnection` 管理。需要共享连接时,在 Task/Model/State 客户端构造选项中传入 `connection`,Page 客户端通过第二个构造参数传入;注入连接由创建者关闭,各客户端的 `disconnect()` 只关闭自己创建的连接。连接始终绑定单个调用范围,不能跨插件、交互渠道或来源复用。
503
+
504
+ 后台连续模型调用可以显式传 `conversation`(1–80 个字母、数字或 `:_-`)。同名会话仅在当前页面实例或宿主管理的当前命令执行内复用;插件、版本、模型、指令、环境和调用归属分别隔离。未指定时每次调用独立。页面解除绑定或命令结束会释放会话;取消、失败和超时会销毁当前会话,空闲 5 分钟释放,每 32 轮重新建立临时会话以限制历史增长。会话仅驻留内存,不新增顶层 CLI/MCP 命令。
package/dist/cli.js CHANGED
@@ -124,7 +124,7 @@ function printUsage(commandName, version) {
124
124
  ' --payload <json> 直接传入 JSON 参数',
125
125
  ' --payload-file <path> 从文件读取整个 JSON 参数',
126
126
  ' --timeout <seconds> 超时时间(默认按 action 推导)',
127
- ' --compact stdout 输出紧凑格式 JSON',
127
+ ' --compact 强制紧凑 JSON(管道默认紧凑,交互终端默认美化)',
128
128
  ' --output <path> 保存输出或截图',
129
129
  ' --session <new|id> 首次建立或复用控制会话',
130
130
  ' --browser <id|名称> 指定 browser_list 返回的浏览器',
@@ -147,9 +147,12 @@ function printUsage(commandName, version) {
147
147
  try {
148
148
  const plugins = listPluginNames();
149
149
  if (plugins.length) {
150
- const entries = plugins.map(name => {
150
+ const entries = plugins.flatMap(name => {
151
151
  try {
152
- const description = findPluginRegistration(name)?.description;
152
+ const registration = findPluginRegistration(name);
153
+ if (registration?.hasPublicCommands === false)
154
+ return [];
155
+ const description = registration?.description;
153
156
  return description
154
157
  ? ` ${name.padEnd(TOP_LEVEL_COMMAND_NAME_WIDTH)}${description}`
155
158
  : ` ${name}`;
@@ -158,7 +161,8 @@ function printUsage(commandName, version) {
158
161
  return ` ${name}`;
159
162
  }
160
163
  });
161
- lines.push('', '已注册插件:', ...entries);
164
+ if (entries.length)
165
+ lines.push('', '已注册插件:', ...entries);
162
166
  }
163
167
  }
164
168
  catch (error) {
@@ -486,7 +490,7 @@ export function parseClientArgs(args, plugin = false) {
486
490
  payload,
487
491
  timeoutSec: parsePositiveTimeout(options.timeout, fallbackTimeout),
488
492
  ...(options.timeout !== undefined ? { timeoutOption: options.timeout } : {}),
489
- compact: options.compact === true,
493
+ compact: options.compact === true || process.stdout.isTTY !== true,
490
494
  forceCdp,
491
495
  json,
492
496
  local,
@@ -536,6 +540,7 @@ async function runPluginCli(args, commandName) {
536
540
  },
537
541
  }, {
538
542
  ...invokeOptions,
543
+ source: 'cli',
539
544
  ...(parsed.verbose
540
545
  ? {
541
546
  onProgress(progress) {
@@ -105,7 +105,7 @@ export declare const COMMANDS: readonly [{
105
105
  }, {
106
106
  readonly name: "includeBody";
107
107
  readonly type: "boolean";
108
- readonly description: "是否包含请求/响应体,默认 true";
108
+ readonly description: "是否包含请求/响应体;指定 fields 时默认 false,否则默认 true";
109
109
  }, {
110
110
  readonly name: "includeHeaders";
111
111
  readonly type: "boolean";
@@ -124,7 +124,7 @@ export declare const COMMANDS: readonly [{
124
124
  readonly description: "只返回数据结构,不返回叶子值";
125
125
  }];
126
126
  readonly notes: readonly ["流式请求开始后即进入缓冲区;页面及 App 桥代发的 MTop SSE 都归入 mtop。无法归属当前页面 target 的 Service Worker 请求不在采集范围内。"];
127
- readonly result: readonly ["nextCursor 用于同类查询续读,hasMore 表示还有数据,gap 表示缓冲区淘汰造成缺口;checkpoint cursor 可分别用于三类查询的初始边界。", "isPending 标记未完成请求;SSE 的 responseBody 保存按序到达的 event/data/timestamp/duration 分片。敏感请求头返回脱敏值。"];
127
+ readonly result: readonly ["nextCursor 用于同类查询续读,hasMore 表示还有数据,gap 表示缓冲区淘汰造成缺口;checkpoint cursor 可分别用于三类查询的初始边界。", "省略正文时不返回 postData / responseBody 字段;指定 fields 后需要同时读取全文时显式传 includeBody:true。", "isPending 标记未完成请求;SSE 的 responseBody 保存按序到达的 event/data/timestamp/duration 分片。敏感请求头返回脱敏值。"];
128
128
  readonly examples: ["get_requests --payload '{\"tabId\":12345,\"count\":5}'", "get_requests --payload '{\"tabId\":12345,\"source\":\"mtop\",\"filter\":\"cart\"}'"];
129
129
  }, {
130
130
  readonly name: "get_logs";
@@ -715,6 +715,15 @@ export declare const COMMANDS: readonly [{
715
715
  }];
716
716
  readonly result: readonly ["默认返回 { action, observation };action.success 只表示动作成功,业务效果需结合 observation 和目标状态判断。", "observe=false 且未开启 diagnostics 时返回裸动作结果(如 { clicked: true }),没有 action/observation;开启 diagnostics 时返回 { action, diagnostics }。", "包装结果中的 action.stage=precondition 表示未派发,省略 observation/diagnostics;dispatch-uncertain 表示可能已派发,先查看 action.attempt 与可用观察或最小快照核验,避免重复提交。失败以退出码 1 结束。", "observation.effects 返回通知、控件和焦点增量,可直接复用 node.ref/selector;changed=true 且 effects 为空不表示失败。", "fullSnapshotRecommended/snapshotReasons 提示是否补充快照;openedTabs 返回可继续操作的 tabId 和 ready。navigation 模式的 ready 表示新页面就绪。", "显式开启的诊断通道在 diagnostics 中返回动作期间增量,与 observe 独立。", "action.data 返回 moved、atTop/atBottom、scrollYBefore/After、maxScrollY、resolvedContainer 和 ancestorDistance;自动发现的内部容器提供可复用 containerSelector。"];
717
717
  readonly examples: ["page_scroll --payload '{\"tabId\":12345,\"direction\":\"down\"}'", "page_scroll --payload '{\"tabId\":12345,\"direction\":\"bottom\"}'", "page_scroll --payload '{\"tabId\":12345,\"selector\":\".virtual-list\",\"direction\":\"down\",\"distance\":800}'", "page_scroll --payload '{\"tabId\":12345,\"selector\":\"@e8\",\"containerPolicy\":\"nearest\",\"direction\":\"bottom\"}'"];
718
+ }, {
719
+ readonly name: "page_runtime";
720
+ readonly description: "页面运行时传输适配器;插件使用 PluginPageClient 或 app.page";
721
+ readonly params: [{
722
+ readonly name: "operation";
723
+ readonly type: "string";
724
+ readonly required: true;
725
+ readonly description: "resolve/attach/get/send/detach/activation";
726
+ }];
718
727
  }, {
719
728
  readonly name: "page_eval";
720
729
  readonly description: "在页面上下文中执行任意 JavaScript 表达式";
@@ -760,7 +769,7 @@ export declare const COMMANDS: readonly [{
760
769
  readonly examples: ["page_eval --payload '{\"tabId\":12345,\"expression\":\"document.title\"}'"];
761
770
  }, {
762
771
  readonly name: "page_inspect";
763
- readonly description: "查询 DOM 元素的数量、边框盒、计算样式、遮挡、溢出和最近滚动容器";
772
+ readonly description: "查询 DOM 元素的控件状态、数量、边框盒、计算样式、遮挡、溢出和最近滚动容器";
764
773
  readonly params: [{
765
774
  readonly name: "selector";
766
775
  readonly type: "string";
@@ -787,7 +796,7 @@ export declare const COMMANDS: readonly [{
787
796
  readonly required: true;
788
797
  readonly description: "目标标签页 ID";
789
798
  }];
790
- readonly result: readonly ["matches[] 包含 boundingBox、computedStyle、hitTest、scroll 溢出量及可用的 scrollContainer。receivesPointerEvents=false 时读取 occludedBy。", "$0 还返回 resolvedSelector、属性、XPath 和可用框架信息。"];
799
+ readonly result: readonly ["matches[] 包含 boundingBox、computedStyle、hitTest、scroll 溢出量及可用的 scrollContainer。receivesPointerEvents=false 时读取 occludedBy。", "state 返回原生/ARIA 状态及来源;缺失字段表示未知。", "$0 还返回 resolvedSelector、属性、XPath 和可用框架信息。"];
791
800
  readonly examples: ["page_inspect --payload '{\"tabId\":12345,\"selector\":\".form-field\",\"styles\":[\"display\",\"width\"]}'", "page_inspect --payload '{\"tabId\":12345,\"selector\":\"@e8\"}'", "page_inspect --payload '{\"tabId\":12345,\"selector\":\"$0\"}'", "page_inspect --payload '{\"tabId\":12345,\"filter\":\"horizontal-overflow\"}'", "page_inspect --payload '{\"tabId\":12345,\"filter\":\"scrollable\"}'"];
792
801
  }, {
793
802
  readonly name: "page_press";
@@ -947,7 +956,7 @@ export declare const COMMANDS: readonly [{
947
956
  readonly description: "目标标签页 ID";
948
957
  }];
949
958
  readonly notes: readonly ["query.text / query.role 至少提供一个;query.exact 默认 true。每次快照刷新有效 ref 集合。", "interactive 无 AX 控件时回退到 viewport,不会自动改用 dom;Canvas 内容需截图。"];
950
- readonly result: readonly ["返回 snapshot、elementCount、outputNodeCount、mode;截断时 truncated=true。", "query 返回 matches 与完整 matchCount,matches 最多 100 项,裁剪时 matchesTruncated=true。容器/iframe 的视口裁剪返回 outerViewport、contentViewport 和滚动位置。"];
959
+ readonly result: readonly ["返回 snapshot、elementCount、outputNodeCount、mode;截断时 truncated=true。", "snapshot 中的 @eN 可直接用于操作;内部节点映射仅保存在运行时。无名称、无 ref 且无状态的分组折叠到子节点。", "query 返回 matches 与完整 matchCount,matches 最多 100 项,裁剪时 matchesTruncated=true。容器/iframe 的视口裁剪返回 outerViewport、contentViewport 和滚动位置。"];
951
960
  readonly examples: ["page_snapshot --payload '{\"tabId\":12345}'", "page_snapshot --payload '{\"tabId\":1,\"mode\":\"viewport\"}'", "page_snapshot --payload '{\"tabId\":1,\"mode\":\"dom\"}'", "page_snapshot --payload '{\"tabId\":1,\"rootSelector\":\"[role=dialog]\"}'", "page_snapshot --payload '{\"tabId\":1,\"rootRef\":\"@e8\",\"ancestorDepth\":1}'", "page_snapshot --payload '{\"tabId\":1,\"query\":{\"text\":\"保存\",\"role\":\"button\"}}'"];
952
961
  }, {
953
962
  readonly name: "page_screenshot";
package/dist/commands.js CHANGED
@@ -116,7 +116,11 @@ export const COMMANDS = [
116
116
  type: 'string',
117
117
  description: '只返回指定 tab checkpoint 或同类查询 cursor 之后的请求',
118
118
  },
119
- { name: 'includeBody', type: 'boolean', description: '是否包含请求/响应体,默认 true' },
119
+ {
120
+ name: 'includeBody',
121
+ type: 'boolean',
122
+ description: '是否包含请求/响应体;指定 fields 时默认 false,否则默认 true',
123
+ },
120
124
  { name: 'includeHeaders', type: 'boolean', description: '是否包含请求/响应头,默认 false' },
121
125
  { name: 'maxBodySize', type: 'number', description: '单个请求/响应体最大字符数,默认 50000' },
122
126
  { name: 'fields', type: 'string[]', description: '从响应体提取指定字段路径,最多 100 个' },
@@ -127,6 +131,7 @@ export const COMMANDS = [
127
131
  ],
128
132
  result: [
129
133
  'nextCursor 用于同类查询续读,hasMore 表示还有数据,gap 表示缓冲区淘汰造成缺口;checkpoint cursor 可分别用于三类查询的初始边界。',
134
+ '省略正文时不返回 postData / responseBody 字段;指定 fields 后需要同时读取全文时显式传 includeBody:true。',
130
135
  'isPending 标记未完成请求;SSE 的 responseBody 保存按序到达的 event/data/timestamp/duration 分片。敏感请求头返回脱敏值。',
131
136
  ],
132
137
  examples: [
@@ -783,6 +788,18 @@ export const COMMANDS = [
783
788
  `page_scroll --payload '{"tabId":12345,"selector":"@e8","containerPolicy":"nearest","direction":"bottom"}'`,
784
789
  ],
785
790
  },
791
+ {
792
+ name: 'page_runtime',
793
+ description: '页面运行时传输适配器;插件使用 PluginPageClient 或 app.page',
794
+ params: [
795
+ {
796
+ name: 'operation',
797
+ type: 'string',
798
+ required: true,
799
+ description: 'resolve/attach/get/send/detach/activation',
800
+ },
801
+ ],
802
+ },
786
803
  {
787
804
  name: 'page_eval',
788
805
  description: '在页面上下文中执行任意 JavaScript 表达式',
@@ -834,7 +851,7 @@ export const COMMANDS = [
834
851
  },
835
852
  {
836
853
  name: 'page_inspect',
837
- description: '查询 DOM 元素的数量、边框盒、计算样式、遮挡、溢出和最近滚动容器',
854
+ description: '查询 DOM 元素的控件状态、数量、边框盒、计算样式、遮挡、溢出和最近滚动容器',
838
855
  params: [
839
856
  {
840
857
  name: 'selector',
@@ -865,6 +882,7 @@ export const COMMANDS = [
865
882
  ],
866
883
  result: [
867
884
  'matches[] 包含 boundingBox、computedStyle、hitTest、scroll 溢出量及可用的 scrollContainer。receivesPointerEvents=false 时读取 occludedBy。',
885
+ 'state 返回原生/ARIA 状态及来源;缺失字段表示未知。',
868
886
  '$0 还返回 resolvedSelector、属性、XPath 和可用框架信息。',
869
887
  ],
870
888
  examples: [
@@ -1050,6 +1068,7 @@ export const COMMANDS = [
1050
1068
  ],
1051
1069
  result: [
1052
1070
  '返回 snapshot、elementCount、outputNodeCount、mode;截断时 truncated=true。',
1071
+ 'snapshot 中的 @eN 可直接用于操作;内部节点映射仅保存在运行时。无名称、无 ref 且无状态的分组折叠到子节点。',
1053
1072
  'query 返回 matches 与完整 matchCount,matches 最多 100 项,裁剪时 matchesTruncated=true。容器/iframe 的视口裁剪返回 outerViewport、contentViewport 和滚动位置。',
1054
1073
  ],
1055
1074
  examples: [
@@ -6,6 +6,7 @@ export interface GetRequestsParams {
6
6
  since?: number;
7
7
  /** Opaque cursor returned by tab_checkpoint or a previous query. */
8
8
  after?: string;
9
+ /** Defaults to false when fields are selected, otherwise true. */
9
10
  includeBody?: boolean;
10
11
  includeHeaders?: boolean;
11
12
  maxBodySize?: number;
@@ -892,6 +893,10 @@ export interface BrowserActionMap {
892
893
  request: PageEvalParams;
893
894
  response: unknown;
894
895
  };
896
+ page_runtime: {
897
+ request: Record<string, unknown>;
898
+ response: unknown;
899
+ };
895
900
  page_inspect: {
896
901
  request: PageInspectParams;
897
902
  response: unknown;
@@ -952,7 +957,8 @@ export interface BrowserActionMap {
952
957
  export type BrowserAction = keyof BrowserActionMap;
953
958
  export type BrowserActionRequest<A extends BrowserAction> = BrowserActionMap[A]['request'];
954
959
  export type BrowserActionResponse<A extends BrowserAction> = BrowserActionMap[A]['response'] & {
955
- session?: ControlSessionInfo;
960
+ /** Routing and execution state; browser_control returns the full tab inventory. */
961
+ session?: Omit<ControlSessionInfo, 'tabs'>;
956
962
  };
957
963
  export type BrowserCommandAction = Exclude<BrowserAction, 'browser_select_browser'>;
958
964
  export type ExtensionBrowserAction = Exclude<BrowserCommandAction, 'browser_list' | 'browser_launch' | 'browser_close' | 'browser_control' | 'page_download'>;
@@ -992,6 +998,7 @@ export declare const BROWSER_ACTIONS: {
992
998
  readonly page_scroll: true;
993
999
  readonly page_hover: true;
994
1000
  readonly page_eval: true;
1001
+ readonly page_runtime: true;
995
1002
  readonly page_inspect: true;
996
1003
  readonly page_snapshot: true;
997
1004
  readonly page_press: true;
@@ -1036,6 +1043,7 @@ export declare const BROWSER_COMMAND_ACTIONS: {
1036
1043
  readonly page_scroll: true;
1037
1044
  readonly page_hover: true;
1038
1045
  readonly page_eval: true;
1046
+ readonly page_runtime: true;
1039
1047
  readonly page_inspect: true;
1040
1048
  readonly page_snapshot: true;
1041
1049
  readonly page_press: true;
@@ -1075,6 +1083,7 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
1075
1083
  readonly page_scroll: true;
1076
1084
  readonly page_hover: true;
1077
1085
  readonly page_eval: true;
1086
+ readonly page_runtime: true;
1078
1087
  readonly page_inspect: true;
1079
1088
  readonly page_snapshot: true;
1080
1089
  readonly page_press: true;
@@ -1115,6 +1124,7 @@ export declare const BROWSER_CAPABILITY_ACTIONS: {
1115
1124
  readonly page_scroll: true;
1116
1125
  readonly page_hover: true;
1117
1126
  readonly page_eval: true;
1127
+ readonly page_runtime: true;
1118
1128
  readonly page_inspect: true;
1119
1129
  readonly page_snapshot: true;
1120
1130
  readonly page_press: true;
@@ -164,6 +164,7 @@ export const BROWSER_ACTIONS = {
164
164
  page_scroll: true,
165
165
  page_hover: true,
166
166
  page_eval: true,
167
+ page_runtime: true,
167
168
  page_inspect: true,
168
169
  page_snapshot: true,
169
170
  page_press: true,
@@ -208,6 +209,7 @@ export const BROWSER_COMMAND_ACTIONS = {
208
209
  page_scroll: true,
209
210
  page_hover: true,
210
211
  page_eval: true,
212
+ page_runtime: true,
211
213
  page_inspect: true,
212
214
  page_snapshot: true,
213
215
  page_press: true,
@@ -247,6 +249,7 @@ export const EXTENSION_BROWSER_ACTIONS = {
247
249
  page_scroll: true,
248
250
  page_hover: true,
249
251
  page_eval: true,
252
+ page_runtime: true,
250
253
  page_inspect: true,
251
254
  page_snapshot: true,
252
255
  page_press: true,
@@ -0,0 +1,110 @@
1
+ import type { PluginExecutionHost, PluginInvocationSource } from './generated-plugin-execution.js';
2
+ import type { PluginTaskState, PluginTaskResultReference } from './generated-plugin-tasks.js';
3
+ import type { PluginTaskCheckpointReference } from './generated-plugin-recovery.js';
4
+ import type { PluginModelDiagnostic } from './generated-plugin-models.js';
5
+ export interface PluginDiagnosticOptions {
6
+ taskId?: string;
7
+ plugin?: string;
8
+ instanceId?: string;
9
+ includeErrorMessages?: boolean;
10
+ includeLocalPaths?: boolean;
11
+ }
12
+ export interface PluginDiagnosticPageBinding {
13
+ instanceId: string;
14
+ browserSessionId: string;
15
+ tabId: number;
16
+ frameId: string | number;
17
+ documentId: string;
18
+ }
19
+ export interface PluginTaskDiagnosticMetadata {
20
+ invocationId?: string;
21
+ page?: PluginDiagnosticPageBinding;
22
+ executorAttempted?: boolean;
23
+ executorStoppedAt?: number;
24
+ model?: PluginModelDiagnostic;
25
+ updatesDropped?: boolean;
26
+ }
27
+ export interface PluginDiagnosticFailure {
28
+ code: string;
29
+ message?: string;
30
+ messageTruncated?: boolean;
31
+ }
32
+ export interface PluginDiagnosticTask {
33
+ taskId: string;
34
+ plugin: string;
35
+ kind: 'command' | 'model';
36
+ command: string;
37
+ state: PluginTaskState;
38
+ source: PluginInvocationSource;
39
+ host: PluginExecutionHost;
40
+ installationId: string;
41
+ revision: string;
42
+ invocationId?: string;
43
+ createdAt: number;
44
+ updatedAt: number;
45
+ sequence: number;
46
+ page?: PluginDiagnosticPageBinding;
47
+ routing?: {
48
+ browser?: string;
49
+ session?: string;
50
+ connector?: string;
51
+ local?: boolean;
52
+ transport?: 'extension' | 'cdp';
53
+ };
54
+ executionTimeoutMs?: number;
55
+ executor: {
56
+ state: 'never-started' | 'observed-alive' | 'stop-confirmed' | 'unknown';
57
+ observedAt: number;
58
+ pid?: number;
59
+ stoppedAt?: number;
60
+ };
61
+ failure?: PluginDiagnosticFailure;
62
+ checkpoint?: PluginTaskCheckpointReference;
63
+ result?: PluginTaskResultReference;
64
+ model?: PluginModelDiagnostic;
65
+ metadataIncomplete: boolean;
66
+ history: {
67
+ firstRetainedSequence: number;
68
+ gap: boolean;
69
+ omitted: number;
70
+ events: Array<{
71
+ sequence: number;
72
+ time: number;
73
+ state: PluginTaskState;
74
+ type: string;
75
+ }>;
76
+ };
77
+ }
78
+ export interface PluginDiagnosticPage {
79
+ plugin: string;
80
+ installationId: string;
81
+ revision: string;
82
+ host: PluginExecutionHost;
83
+ binding: PluginDiagnosticPageBinding;
84
+ observation: 'service-snapshot' | 'historical-binding';
85
+ state?: 'active' | 'detached' | 'invalidated';
86
+ lastReceived?: number;
87
+ queued?: number;
88
+ running?: number;
89
+ failure?: PluginDiagnosticFailure;
90
+ }
91
+ export interface PluginDiagnosticReport {
92
+ version: 1;
93
+ generatedAt: number;
94
+ host: PluginExecutionHost;
95
+ protocolVersion: number;
96
+ selection: Pick<PluginDiagnosticOptions, 'taskId' | 'plugin' | 'instanceId'>;
97
+ coverage: {
98
+ scanLimited: boolean;
99
+ tasksOmitted: number;
100
+ pagesOmitted: number;
101
+ byteLimited: boolean;
102
+ };
103
+ tasks: PluginDiagnosticTask[];
104
+ pages: PluginDiagnosticPage[];
105
+ links: Array<{
106
+ from: string;
107
+ to: string;
108
+ kind: 'parent' | 'resume';
109
+ }>;
110
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import type { PluginPageBinding } from './generated-plugin-pages.js';
2
+ import type { PluginTaskRecoveryContext } from './generated-plugin-recovery.js';
3
+ /** Identifies an execution environment separately from a process incarnation. */
4
+ export interface PluginExecutionHost {
5
+ hostId: string;
6
+ epoch: string;
7
+ }
8
+ export type PluginInvocationSource = 'cli' | 'sdk' | 'mcp' | 'toolbox' | 'runtime';
9
+ /** Created by the entry point; business input cannot replace this identity. */
10
+ export interface PluginInvocationIdentity {
11
+ invocationId: string;
12
+ host: PluginExecutionHost;
13
+ source: PluginInvocationSource;
14
+ plugin: string;
15
+ parentInvocationId?: string;
16
+ taskId?: string;
17
+ installationId?: string;
18
+ revision?: string;
19
+ page?: PluginPageBinding;
20
+ recovery?: PluginTaskRecoveryContext;
21
+ }
22
+ export interface PluginExecutionError {
23
+ message: string;
24
+ code?: string;
25
+ details?: Record<string, unknown>;
26
+ metadata?: Record<string, string | number | boolean | null>;
27
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ export type PluginModelMode = 'generate' | 'agent';
2
+ export interface PluginModelRequest {
3
+ provider: string;
4
+ mode: PluginModelMode;
5
+ prompt: string;
6
+ instructions?: string;
7
+ model?: string;
8
+ reasoningEffort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
9
+ outputSchema?: Record<string, unknown>;
10
+ /** Opt-in conversation scoped to the bound document or calling command execution. */
11
+ conversation?: string;
12
+ /** Required for an agent task; never inferred from a pure-generation request. */
13
+ permissions?: 'read-only';
14
+ }
15
+ export interface PluginModelCapability {
16
+ provider: string;
17
+ modes: PluginModelMode[];
18
+ permissions: Array<'read-only'>;
19
+ structuredOutput: boolean;
20
+ streaming: boolean;
21
+ cancellation: boolean;
22
+ }
23
+ export interface PluginModelOption {
24
+ id: string;
25
+ displayName: string;
26
+ description?: string;
27
+ isDefault?: boolean;
28
+ reasoningEfforts?: NonNullable<PluginModelRequest['reasoningEffort']>[];
29
+ defaultReasoningEffort?: PluginModelRequest['reasoningEffort'];
30
+ }
31
+ export interface PluginModelList {
32
+ provider: string;
33
+ models: PluginModelOption[];
34
+ }
35
+ export interface PluginModelResult {
36
+ text: string;
37
+ output?: unknown;
38
+ provider: string;
39
+ mode: PluginModelMode;
40
+ model?: string;
41
+ }
42
+ /** Execution observations contain no prompts, account identities or credential values. */
43
+ export interface PluginModelDiagnostic {
44
+ requestedModel?: string;
45
+ selectedModel?: string;
46
+ activeModel?: string;
47
+ runtime?: {
48
+ executable?: string;
49
+ version?: string;
50
+ selection: 'explicit' | 'automatic';
51
+ started?: boolean;
52
+ };
53
+ configuration?: {
54
+ source: 'default' | 'environment';
55
+ home?: string;
56
+ filePresent: boolean;
57
+ baseProvider?: string;
58
+ credentialStore?: 'file' | 'keyring' | 'auto' | 'ephemeral' | 'unknown';
59
+ };
60
+ authentication?: 'apikey' | 'chatgpt' | 'chatgptAuthTokens' | 'unknown';
61
+ threadRestrictionsAccepted?: boolean;
62
+ turnRestrictionsAccepted?: boolean;
63
+ retryCount?: number;
64
+ }
@@ -0,0 +1 @@
1
+ export {};