@heybox/hb-sdk 0.8.0-alpha → 0.8.0-alpha.10

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 (94) hide show
  1. package/CHANGELOG.md +92 -396
  2. package/README.md +101 -24
  3. package/THIRD_PARTY_NOTICES.md +1755 -0
  4. package/dist/cli-chunks/{build-DJWFSM1B.cjs → build-aDJbiFqF.cjs} +8 -5
  5. package/dist/cli-chunks/{context-DV2UK1Nz.cjs → context-Dp36pZ9a.cjs} +39 -81
  6. package/dist/cli-chunks/{create-2HfoB48V.cjs → create-P3g0ricz.cjs} +2 -2
  7. package/dist/cli-chunks/{dev-Dgt2zS9k.cjs → dev-CisJkXuQ.cjs} +396 -576
  8. package/dist/cli-chunks/doctor-B-LF5-uj.cjs +65 -0
  9. package/dist/cli-chunks/{index-D62ANeBv.cjs → index-BDaeBI_B.cjs} +50 -30
  10. package/dist/cli-chunks/{index-BjoSXl8C.cjs → index-CZGkk7fQ.cjs} +2 -2
  11. package/dist/cli-chunks/{index.esm-CigcxJ2B.cjs → index.esm-NNLG29Tt.cjs} +8 -7
  12. package/dist/cli-chunks/{login-Cumknwdx.cjs → login-DTY5GolC.cjs} +2 -2
  13. package/dist/cli-chunks/{project-vite-CcE-HMmd.cjs → project-vite-DlCjHlu_.cjs} +1 -1
  14. package/dist/cli-chunks/{remote-DDdP3xcE.cjs → remote-BBMr7j8W.cjs} +57 -25
  15. package/dist/cli-chunks/{runtime-gate-DFjw66kF.cjs → runtime-gate-BppCl1r3.cjs} +11 -3
  16. package/dist/cli-chunks/{runtime-permission-env-CjsCe5bp.cjs → runtime-permission-env-CqsTHeas.cjs} +351 -0
  17. package/dist/cli-chunks/{session-BDi_AZSv.cjs → session-CnGeZCRZ.cjs} +1 -1
  18. package/dist/cli-chunks/skill-B0yAnPOJ.cjs +83 -0
  19. package/dist/cli-chunks/version-DN5jrixS.cjs +8 -0
  20. package/dist/cli.cjs +1 -1
  21. package/dist/devtools/browser-dev-host/assets/browser-dev-host-BhZGUyYw.js +97 -0
  22. package/dist/devtools/browser-dev-host/assets/heybox-logo-CogNENsk.svg +6 -0
  23. package/dist/devtools/browser-dev-host/assets/index-DJFB5ySU.css +1 -0
  24. package/dist/devtools/browser-dev-host/assets/index-Dh9H1JOm.js +567 -0
  25. package/dist/devtools/browser-dev-host/assets/workbench-state-wHgWRb7I.js +5 -0
  26. package/dist/devtools/browser-dev-host/index.html +6 -435
  27. package/dist/index.cjs.js +939 -29
  28. package/dist/index.esm.js +939 -30
  29. package/dist/protocol.cjs.js +381 -37
  30. package/dist/protocol.esm.js +355 -38
  31. package/dist/templates/{vue3-vite-ts → vanilla-vite-js}/.gitignore.ejs +0 -1
  32. package/dist/templates/vanilla-vite-js/README.md.ejs +14 -0
  33. package/dist/templates/vanilla-vite-js/index.html.ejs +20 -0
  34. package/dist/templates/vanilla-vite-js/package.json.ejs +22 -0
  35. package/dist/templates/vanilla-vite-js/src/assets/heybox-logo.svg +8 -0
  36. package/dist/templates/vanilla-vite-js/src/main.js +39 -0
  37. package/dist/templates/vanilla-vite-js/src/styles.css +155 -0
  38. package/dist/templates/{vue3-vite-ts/vite.config.ts → vanilla-vite-js/vite.config.js} +1 -2
  39. package/dist/vite.cjs.js +228 -9
  40. package/dist/vite.esm.js +228 -9
  41. package/package.json +36 -13
  42. package/skill/SKILL.md +22 -20
  43. package/skill/references/api-protocol.md +100 -6
  44. package/skill/references/api-root.md +166 -23
  45. package/skill/references/cli.md +41 -24
  46. package/skill/references/examples.md +30 -1
  47. package/skill/references/llms-index.md +1 -1
  48. package/skill/references/recipes.md +139 -36
  49. package/skill/references/safety-boundaries.md +14 -5
  50. package/skill/skill.json +10 -5
  51. package/types/core/client.d.ts +17 -1
  52. package/types/core/sdk.d.ts +3 -0
  53. package/types/core/singleton.d.ts +3 -0
  54. package/types/index.d.ts +4 -2
  55. package/types/miniapp-manifest/index.d.ts +1 -0
  56. package/types/miniapp-manifest/node.d.ts +3 -0
  57. package/types/miniapp-manifest/permissions.d.ts +37 -0
  58. package/types/miniapp-manifest/schema.d.ts +5 -0
  59. package/types/modules/files/index.d.ts +5 -0
  60. package/types/modules/files/registry.d.ts +35 -0
  61. package/types/modules/files/types.d.ts +159 -0
  62. package/types/modules/network/index.d.ts +50 -3
  63. package/types/modules/share/index.d.ts +1 -1
  64. package/types/modules/share/show-share-menu.d.ts +1 -1
  65. package/types/modules/share/types.d.ts +2 -4
  66. package/types/protocol/capabilities.d.ts +2 -2
  67. package/types/protocol/constants.d.ts +1 -1
  68. package/types/protocol/guards.d.ts +1 -1
  69. package/types/protocol/types.d.ts +1 -1
  70. package/types/protocol.d.ts +4 -3
  71. package/types/skill-metadata.d.ts +0 -4
  72. package/dist/cli-chunks/doctor-C95gIao_.cjs +0 -204
  73. package/dist/devtools/browser-dev-host/main.js +0 -12263
  74. package/dist/templates/vue3-vite-ts/README.md.ejs +0 -47
  75. package/dist/templates/vue3-vite-ts/index.html.ejs +0 -12
  76. package/dist/templates/vue3-vite-ts/package.json.ejs +0 -33
  77. package/dist/templates/vue3-vite-ts/src/App.vue +0 -78
  78. package/dist/templates/vue3-vite-ts/src/__tests__/App.spec.ts +0 -148
  79. package/dist/templates/vue3-vite-ts/src/auth-handoff.ts +0 -46
  80. package/dist/templates/vue3-vite-ts/src/main.ts +0 -5
  81. package/dist/templates/vue3-vite-ts/src/styles.css +0 -60
  82. package/dist/templates/vue3-vite-ts/src/vite-env.d.ts +0 -1
  83. package/dist/templates/vue3-vite-ts/tsconfig.app.json +0 -17
  84. package/dist/templates/vue3-vite-ts/tsconfig.json +0 -11
  85. package/dist/templates/vue3-vite-ts/tsconfig.node.json +0 -11
  86. package/dist/templates/vue3-vite-ts/vitest.config.ts +0 -10
  87. package/skill/scripts/check-references.mjs +0 -14
  88. package/skill/scripts/markdown-sections.mjs +0 -36
  89. package/skill/scripts/package-skill.mjs +0 -60
  90. package/skill/scripts/package-skill.sh +0 -6
  91. package/skill/scripts/skill-metadata.mjs +0 -77
  92. package/skill/scripts/sync-agent-skills-payload.mjs +0 -359
  93. package/skill/scripts/sync-references.mjs +0 -794
  94. package/skill/scripts/validate-skill.mjs +0 -263
@@ -1,6 +1,6 @@
1
1
  # CLI reference
2
2
 
3
- > Generated by `node packages/hb-sdk/skill/scripts/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
3
+ > Generated by `node packages/hb-sdk/scripts/skill/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
4
4
 
5
5
  ## Sources
6
6
 
@@ -27,7 +27,7 @@
27
27
  - [Update reminders](#update-reminders)
28
28
  ## When to use the CLI
29
29
 
30
- Use the bundled `hb-sdk` CLI to create a workshop mini-program, open the local debugging page, test in the Heybox Mac or mobile App, or manage and publish a remote mini-program.
30
+ Use the bundled `hb-sdk` CLI to create a workshop mini-program, open the local Browser debugging workbench, test in the Heybox mobile App, or manage and publish a remote mini-program.
31
31
 
32
32
  `hb-sdk login` is for development and publishing commands only. It does not authorize mini-program users and does not change `auth.login()`, `user.getInfo()`, or `network.request()` inside a mini-program.
33
33
 
@@ -40,7 +40,8 @@ hb-sdk build [--env <name>] [--verbose]
40
40
  hb-sdk login
41
41
  hb-sdk login status
42
42
  hb-sdk login clear
43
- hb-sdk doctor
43
+ hb-sdk skill install [--global] [--agent <agent>] [--all-agents] [--force]
44
+ hb-sdk doctor [--agent <agent>] [--all-agents] [--json]
44
45
  hb-sdk remote access
45
46
  hb-sdk remote entity list
46
47
  hb-sdk remote entity current
@@ -75,12 +76,16 @@ Top-level `hb-sdk deploy` has been hard-cut and must not be documented as a vali
75
76
  新项目可以直接从模板开始:
76
77
 
77
78
  ```bash
78
- npx @heybox/hb-sdk@latest create my-miniapp
79
+ npx @heybox/hb-sdk@alpha create my-miniapp
79
80
  cd my-miniapp
80
81
  npm install
81
82
  npm run dev
82
83
  ```
83
84
 
85
+ 默认产物是 Vanilla JavaScript + Vite HelloWorld,只演示一次 `ui.showToast()` 调用,并预填 `android`、`ios`、`ohos` 三个平台。Demo 可以整体删除,项目不绑定 Vue、TypeScript 或测试框架。
86
+
87
+ 当前 `0.8` 模板位于 alpha 发布线;稳定版本发布后,本页会将创建命令切回 `@latest`。
88
+
84
89
  已有项目则在项目目录运行 `npm run dev` 或 `hb-sdk dev`。
85
90
 
86
91
  Agent rules:
@@ -100,15 +105,17 @@ Agent rules:
100
105
  hb-sdk dev
101
106
  ```
102
107
 
103
- CLI 会启动页面服务并自动打开本地调试页。调试页会展示小程序、浏览器 Mock、Mac 启动入口和手机二维码。
108
+ CLI 会启动页面服务并自动打开 Vue 3 本地调试台。左侧集中放置调用日志、Storage 和问题三个诊断页签,右侧保持稳定的小程序内容与设备预览。
104
109
 
105
- <img src="https://static.max-c.com/static/heybox/webapp/heybox-docs/docs-hb_sdk/assets/local-preview-debug-page.png" alt="hb-sdk 本地调试页、浏览器 Mock 和真机调试入口" style="width: 100%; max-width: 860px;" />
110
+ 默认终端只显示启动结果、调试页地址、小程序地址和手机调试入口。排查启动问题时使用 `hb-sdk dev --verbose` 查看完整启动阶段;手机扫码调试凭证连续重试失败时,默认只在失败和恢复两次状态变化时提示。
106
111
 
107
- `hb-sdk dev` 不支持匿名调试。启动前必须先运行 `hb-sdk login`,并通过 `hb-sdk remote create` `hb-sdk remote bind <mini-program-id>` 绑定当前项目;未登录、未绑定或远端 Dev Context 不可用时,CLI 会在启动 Vite 和调试服务前终止。
112
+ <img src="/assets/browser-dev-host-workbench.png" alt="小程序工坊 Vue 3 调试台" style="width: 100%; max-width: 1120px;" />
108
113
 
109
- `hb-sdk dev` 会在启动 Vite 前读取远端权限。只有远端权限快照有效且 `network.request.status=enabled` 时才跳过平台 CSP;`useOfficialDomain` 不参与该判定。本地 Dev Context 权限覆盖不会改变 CSP 决策。
114
+ 浏览器调试入口不要求 CLI 登录或项目绑定。没有账号、绑定小程序或远端 Dev Context 时,页面和基础 Browser Mock 仍可启动;依赖这些上下文的能力会返回明确失败。远端管理、部署和发布仍要求完成登录与绑定。
110
115
 
111
- 当前调试链路不要求升级 Android、iOS Mac 客户端。Browser Mock 会自动在实时与兼容链路间切换;Mobile 使用 `open_inapp`/`openWindow` 包裹的 LAN 短链接二维码(先开普通 H5 跳转页,再进入小程序并关闭中间页);PC/Mac 行为保持不变。
116
+ `hb-sdk dev` 从项目 `package.json` 读取开发者声明,并在远端权限快照可用时读取平台批准结果。只有当前版本声明且平台已批准 `network` 时才跳过平台 CSP;`useOfficialDomain` 不参与该判定。调试台不提供权限或平台批准修改入口;快照缺失或无效时保留平台 CSP。
117
+
118
+ Browser Mock 会自动在实时与兼容链路间切换。手机调试使用 `open_inapp`/`openWindow` 包裹的 LAN 短链接二维码(先开普通 H5 跳转页,再进入小程序并关闭中间页)。
112
119
 
113
120
  ### 2. 先用浏览器 Mock 验收
114
121
 
@@ -118,13 +125,15 @@ CLI 会启动页面服务并自动打开本地调试页。调试页会展示小
118
125
  - SDK 初始化与用户身份授权流程
119
126
  - 生命周期、Storage 和排行榜等能力
120
127
 
121
- 调试页中调整的权限只影响当前本地调试,不会修改线上配置;切换权限后 Mobile App 会重生成二维码。Debug/Ad-Hoc 的本地增强不可用、过期或读取失败时继续使用原生 Host。恢复初始权限后重新按远端配置验收;工坊小程序默认不能进行网络请求,网络权限暂未开放申请,不要把本地结果当成线上能力。
128
+ 调试台提供紧凑的调用日志、当前小程序隔离作用域内的 Storage 只读快照和问题聚合。日志与网络记录只保留脱敏的诊断字段,不展示 payload、结果、查询参数、凭据或原始错误信息。工坊小程序默认不能进行网络请求,网络权限暂未开放申请,不要把本地结果当成线上能力。
129
+
130
+ 右侧可切换 iPhone 16 Pro Max(`387 x 821`)与 Pixel 9 Pro(`322 x 716`)两个设备预设。尺寸对应固定上游设备外框的真实屏幕 opening;预设同时决定外框、状态栏、安全区和 viewport。切换设备不会重新加载小程序或重启 Runtime,页面状态和调试会话保持不变。授权与操作弹窗、Toast、Loading 和振动反馈均显示在设备预览内部,不会覆盖整个调试台。
122
131
 
123
- ### 3. 再用 Mac 或手机真机验收
132
+ ### 3. 再用手机真机验收
124
133
 
125
- 需要确认真实客户端表现时,可以使用调试页提供的 Mac 启动入口;手机验收则在「Mobile App」区域选择局域网网卡,再用手机小黑盒 APP 扫码。
134
+ 需要确认真实客户端表现时,从调试台右上角唯一的二维码入口打开浮层,选择局域网网卡,再用手机小黑盒 APP 扫码。页面不再提供 Browser/Mobile 切换页签或其他二维码入口。
126
135
 
127
- 手机与电脑需要处于同一局域网。二维码走 HTTPS `open_inapp` 与 `heybox://` `openWindow`,其中 `webview.url` 是局域网短链 `http://<lan-ip>:<browser-dev-host-port>/l/<token>`。短链返回跳转页:先打开带 `mini_url`、小程序身份、启动票、SDK 版本和局域网 Dev Context 的完整 `heybox-mini-dev://sandbox` 协议,约 500ms 后再发 `closeWindow` 关掉中间页。权限、网卡或启动票变化时调试页会刷新二维码并轮换 Dev Session。多网卡时选择手机实际可达的 **Network**。发布前至少完成一次真实客户端验收。
136
+ 手机与电脑需要处于同一局域网。二维码走 HTTPS `open_inapp` 与 `heybox://` `openWindow`,其中 `webview.url` 是局域网短链 `http://<lan-ip>:<browser-dev-host-port>/l/<token>`。短链返回跳转页:先打开带 `mini_url`、小程序身份、启动票、SDK 版本和局域网 Dev Context 的完整 `heybox-mini-dev://sandbox` 协议,约 500ms 后再发 `closeWindow` 关掉中间页。网卡或启动票变化时调试台会刷新二维码并轮换 Dev Session。多网卡时选择手机实际可达的 **Network**。发布前至少完成一次真实客户端验收。
128
137
 
129
138
  ### 浏览器 Mock 的边界
130
139
 
@@ -132,14 +141,16 @@ CLI 会启动页面服务并自动打开本地调试页。调试页会展示小
132
141
 
133
142
  ### 常用参数
134
143
 
135
- | 参数 | 用途 |
136
- | -------------------------------- | ------------------------------------------------------------- |
137
- | `--port <port>` | 指定页面开发服务端口。 |
138
- | `--browser-dev-host-port <port>` | 指定 Browser Dev Host 端口。 |
139
- | `--no-open` | 启动后不自动打开浏览器。 |
140
- | `--verbose` | 出现问题时输出更详细的诊断信息。 |
144
+ | 参数 | 用途 |
145
+ | -------------------------------- | -------------------------------- |
146
+ | `--port <port>` | 指定页面开发服务端口。 |
147
+ | `--browser-dev-host-port <port>` | 指定浏览器调试页服务端口。 |
148
+ | `--no-open` | 启动后不自动打开浏览器。 |
149
+ | `--verbose` | 出现问题时输出更详细的诊断信息。 |
141
150
 
142
- Use `hb-sdk dev` to open the local debugging page after CLI login and project binding are complete. Missing login, binding, or remote Dev Context stops before Vite and the debugging services start. The "Mobile App" QR code opens it in the phone App after a LAN interface is selected. The phone and computer must be on the same LAN.
151
+ Use `hb-sdk dev` to open the local Vue 3 debugging workbench. Browser debugging can start without CLI login, project binding, or a remote Dev Context; capabilities that need them fail explicitly. The upper-right QR popover is the only Mobile entry and requires selecting a LAN interface the phone can reach.
152
+
153
+ The workbench offers iPhone 16 Pro Max (`440 x 956`) and Pixel 9 Pro (`410 x 914`) presets. Switching presets preserves the iframe, Runtime session, and page state. Authorization/action dialogs, Toast, Loading, and vibration feedback render inside the preview. Do not suggest a debugging-page permission editor; it does not exist, and the validated remote permission snapshot remains canonical.
143
154
 
144
155
  Browser Mock uses the Node `hb-sdk login` session to send Host `heybox-session` requests. Mini-program code must still call `auth.login()`; the debug page only shows an authorization dialog. Never copy pkey, cookies, tokens, or credential-bearing URLs into page JavaScript or logs. Phone debugging continues to use the App login, not the CLI session.
145
156
 
@@ -153,7 +164,7 @@ hb-sdk build [--env <name>] [--verbose]
153
164
 
154
165
  `hb-sdk build` 直接使用项目安装的 Vite,先清理再生成固定的 `dist/`,并校验小程序入口、Manifest 和可上传产物。它不执行类型检查,不要求 CLI 登录或绑定小程序,也不访问远端服务。项目必须在 `vite.config.ts` 中显式注册 `miniappManifest()`。
155
166
 
156
- 直接运行 `hb-sdk build` 或 `vite build` 时默认注入平台 CSP。`hb-sdk remote deploy` 会在构建前读取绑定小程序的远端权限;仅当 `network.request.status=enabled` 时向子构建传递已验证上下文并跳过平台 CSP,`useOfficialDomain` 不参与该判定。权限缺失、非法或读取失败时继续注入,Runtime Gate、Manifest 与 HTML 构建检查始终保留。
167
+ 直接运行 `hb-sdk build` 或 `vite build` 时默认注入平台 CSP。`hb-sdk remote deploy` 会在构建前读取绑定小程序的远端批准结果,并与当前版本声明取交集;仅当有效 `network` 权限启用时才跳过平台 CSP,`useOfficialDomain` 不参与该判定。权限缺失、非法或读取失败时继续注入,Runtime Gate、Manifest 与 HTML 构建检查始终保留。
157
168
 
158
169
  推荐由项目的 `scripts.build` 保留类型检查:
159
170
 
@@ -268,8 +279,14 @@ Agent rules:
268
279
 
269
280
  Agent rules:
270
281
 
271
- - Use `hb-sdk doctor` for read-only diagnosis of local SDK, remote latest skill metadata, and local skill metadata.
272
- - Do not use `hb-sdk doctor` to auto-install skills; when installation or refresh is needed, tell the user to run `npx skills add https://open.xiaoheihe.cn/agent-skills/hb-sdk`.
273
- - If doctor reports `SDK_MISMATCH`, tell the user to upgrade `@heybox/hb-sdk@latest` before reinstalling the skill.
282
+ - Use `hb-sdk doctor [--agent <agent>] [--all-agents] [--json]` for read-only diagnosis of the locally installed SDK and its bundled Skill.
283
+ - Use `hb-sdk skill install` to install or refresh the Skill bundled with the matching npm package. Add `--global` for user scope, `--agent <agent>` for one Agent, or `--all-agents` for every supported Agent.
284
+ - If doctor reports `SDK_MISMATCH`, upgrade the project dependency to the matching @heybox/hb-sdk version before reinstalling the skill.
274
285
 
275
286
  ## Update reminders
287
+
288
+ ## 版本提醒
289
+
290
+ CLI 会从 npm 的 `latest` 标签检查稳定版更新,发现新版本时在命令结束后输出一行提醒,包含升级命令和目标版本的[更新日志](https://docs.xiaoheihe.cn/hb_sdk/changelog/)链接。提醒最多每 24 小时检查一次,请求超时或网络异常不会影响原命令;CI 环境默认不检查。
291
+
292
+ 需要临时关闭本地检查时,设置 `HB_SDK_NO_UPDATE_CHECK=1`。版本提醒不会读取 Alpha、Beta 或 RC 等预发布标签。
@@ -1,6 +1,6 @@
1
1
  # Smoke examples and anti-examples
2
2
 
3
- > Generated by `node packages/hb-sdk/skill/scripts/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
3
+ > Generated by `node packages/hb-sdk/scripts/skill/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
4
4
 
5
5
  ## Sources
6
6
 
@@ -105,6 +105,33 @@ try {
105
105
  }
106
106
  ```
107
107
 
108
+ ### Sandbox download contract (Host pending)
109
+
110
+ ```ts
111
+ import { files, network, HbMiniProgramSDKError } from '@heybox/hb-sdk';
112
+
113
+ export async function downloadReport() {
114
+ const directory = files.sandbox.directory('exports');
115
+ await directory.create({ recursive: true });
116
+
117
+ try {
118
+ return await network.download({
119
+ url: 'https://cdn.example.com/report.json',
120
+ to: directory,
121
+ suggestedName: 'report.json',
122
+ onProgress: ({ loaded, total, lengthComputable }) => {
123
+ console.log(lengthComputable ? [loaded, total].join('/') : loaded);
124
+ },
125
+ });
126
+ } catch (error) {
127
+ if (error instanceof HbMiniProgramSDKError && error.code === 'METHOD_FORBIDDEN') {
128
+ return undefined;
129
+ }
130
+ throw error;
131
+ }
132
+ }
133
+ ```
134
+
108
135
  ### Host/runtime protocol import
109
136
 
110
137
  ```ts
@@ -158,6 +185,8 @@ export default defineConfig({
158
185
  - Do not call unsupported storage delete/clear/info operations.
159
186
  - Do not pass raw internal share/network protocol fields from mini-program code.
160
187
  - Do not send `multipart/form-data` (or handcrafted multipart bodies) through `network.request`; use form-urlencoded string body or a dedicated upload capability.
188
+ - Do not pass string paths, browser File System Access handles, Blob targets, Range/resume fields, or upload bodies to `network.download`; use SDK-created File/Directory handles after a supporting Host is available.
189
+ - Do not treat any current Host, including legacy PC or Browser Dev Host, as evidence for files/download support. They return `METHOD_FORBIDDEN` and provide no memory fallback; the new PC Host will integrate the retained contract separately.
161
190
  - Do not treat `hb-sdk login` as iframe SDK authentication state.
162
191
  - Do not create a second mock runtime package when `hb-sdk dev` is the supported local mock workflow.
163
192
  - Do not import `@heybox/hb-sdk/vite` from iframe business code or fetch a deployed `manifest.json` directly.
@@ -1,6 +1,6 @@
1
1
  # LLM documentation index
2
2
 
3
- > Generated by `node packages/hb-sdk/skill/scripts/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
3
+ > Generated by `node packages/hb-sdk/scripts/skill/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
4
4
 
5
5
  ## Sources
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Recipes
2
2
 
3
- > Generated by `node packages/hb-sdk/skill/scripts/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
3
+ > Generated by `node packages/hb-sdk/scripts/skill/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
4
4
 
5
5
  ## Sources
6
6
 
@@ -26,7 +26,9 @@
26
26
 
27
27
  # 快速开始
28
28
 
29
- 如果页面不需要小黑盒开放能力,可以不接入 SDK。SDK 导入时会自动启动握手,能力调用会自动等待;业务只需根据小程序是否开通网络权限选择身份流程。
29
+ 新项目可先运行 `hb-sdk create my-miniapp` 获得 Vanilla JavaScript + Vite HelloWorld;模板只演示 Toast,业务代码可以直接替换。
30
+
31
+ 如果页面不需要小黑盒开放能力,可以不接入 SDK。SDK 导入时会自动启动握手,能力调用会自动等待;使用受保护能力前需在 `package.json#heybox.permissions` 声明对应权限,详见[权限声明](https://docs.xiaoheihe.cn/hb_sdk/guide/permissions)。
30
32
 
31
33
  ## 交互控件与握手状态
32
34
 
@@ -37,7 +39,7 @@ import hbSDK, { type MiniProgramSDKHandshakeState } from '@heybox/hb-sdk'
37
39
  import { computed, onUnmounted, ref } from 'vue'
38
40
 
39
41
  const handshakeState = ref<MiniProgramSDKHandshakeState>(hbSDK.getHandshakeState())
40
- const stopHandshakeState = hbSDK.onHandshakeStateChange((state) => {
42
+ const stopHandshakeState = hbSDK.onHandshakeStateChange(state => {
41
43
  handshakeState.value = state
42
44
  })
43
45
  const sdkReady = computed(() => handshakeState.value.status === 'ready')
@@ -47,9 +49,9 @@ onUnmounted(stopHandshakeState)
47
49
 
48
50
  把 `sdkReady` 用作按钮的 `disabled` 条件。订阅会立即回放当前状态,因此晚挂载组件也能得到 `ready` 或 `failed` 终态。`ready` 生命周期事件只在握手成功瞬间派发且不会重放,不能作为当前状态来源。
49
51
 
50
- ## 未开通网络权限
52
+ ## 读取当前用户
51
53
 
52
- 无网络小程序可以在本地能力中使用按小程序隔离的 `app_user_id` 和公开资料:
54
+ 声明 `userInfo` 后,可以读取按小程序隔离的 `app_user_id` 和已授权资料。该能力不依赖公开 `network` 权限:
53
55
 
54
56
  ```ts
55
57
  import hbSDK from '@heybox/hb-sdk'
@@ -62,9 +64,9 @@ async function getCurrentUser() {
62
64
 
63
65
  `user.getInfo()` 不展示授权弹窗,也不要求可信用户手势。未登录时返回未登录状态;已登录时隐式授予当前本地用户 scopes(`identity`、`profile`),静默返回 `userInfo.app_user_id`、`profile.nickname` 和 `profile.avatar`。这条路径不能获取授权码或调用 OpenAPI,也不能把身份或资料发送到外部服务。
64
66
 
65
- ## 已开通网络权限
67
+ ## 获取服务端授权码
66
68
 
67
- 有网络小程序通过 `auth.login()` 获取短期授权码。登录可能展示 UI,因此应绑定到按钮点击等明确的用户操作:
69
+ 声明 `userInfo` 后,可通过 `auth.login()` 获取短期授权码。登录可能展示 UI,因此应绑定到按钮点击等明确的用户操作。该调用内部使用 Host 受信请求,不依赖公开 `network` 权限;示例中的 `network.request()` 另需声明并获得 `network` 平台批准。
68
70
 
69
71
  SDK 会自动完成握手。登录按钮应按上面的持久握手状态启用;点击回调直接调用 `auth.login()`,不要先等待其他异步任务,以免首次操作丢失可信手势。
70
72
 
@@ -93,6 +95,102 @@ async function loginFromUserAction() {
93
95
 
94
96
  返回值与边界以[用户身份与登录](https://docs.xiaoheihe.cn/hb_sdk/guide/auth)为准。页面只把 `code` 提交给自己的服务端。不要在页面初始化阶段自动调用 `auth.login()`。
95
97
 
98
+ ## 文件与下载
99
+
100
+ `files.sandbox` 是当前小程序隔离的逻辑根。`file()` / `directory()` 只创建 lazy proxy,不执行
101
+ I/O;第一次真实 I/O 仍由 Runtime 和 Host 校验当前 session、授权、mode、kind 和路径。
102
+
103
+ ```ts
104
+ import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
105
+
106
+ const exportDirectory = hbSDK.files.sandbox.directory('exports')
107
+ await exportDirectory.create({ recursive: true })
108
+
109
+ const controller = new AbortController()
110
+
111
+ try {
112
+ const file = await hbSDK.network.download({
113
+ url: 'https://cdn.example.com/report.json',
114
+ to: exportDirectory,
115
+ suggestedName: 'report.json',
116
+ overwrite: true,
117
+ maxBytes: 8 * 1024 * 1024,
118
+ signal: controller.signal,
119
+ onProgress({ loaded, total, lengthComputable }) {
120
+ console.log(lengthComputable ? `${loaded}/${total}` : loaded)
121
+ },
122
+ })
123
+
124
+ console.log(await file.readText())
125
+ } catch (error) {
126
+ if (error instanceof HbMiniProgramSDKError && error.code === 'METHOD_FORBIDDEN') {
127
+ // 当前 Host 不支持 V1 文件能力。
128
+ return
129
+ }
130
+ throw error
131
+ }
132
+ ```
133
+
134
+ 当前平台状态如下:
135
+
136
+ | Host | `files.sandbox` | 外部 picker | `network.download()` |
137
+ | ---------------- | --------------- | ----------- | -------------------- |
138
+ | 旧版 PC | 不支持 | 不支持 | 不支持 |
139
+ | Mobile | 不支持 | 不支持 | 不支持 |
140
+ | Web | 不支持 | 不支持 | 不支持 |
141
+ | Browser Dev Host | 不支持 | 不支持 | 不支持 |
142
+
143
+ 当前 Runtime 认识但 Host 未实现时返回 `METHOD_FORBIDDEN`;旧 Runtime 收到新 method 时返回
144
+ `METHOD_NOT_FOUND`。此前曾实现面向旧版小黑盒 PC 的 Host 适配;由于新版 PC 即将启用,该适配
145
+ 不再发布。文件/下载 API、协议和 Runtime 体系保持不变,后续直接按照新版 PC Host 架构接入。
146
+ 当前任何 Host 都不提供 Blob 或内存假下载。
147
+
148
+ ### 路径与创建
149
+
150
+ - 逻辑相对路径统一使用 `/`。拒绝空字符串、绝对路径、空 segment、`.`、`..`、反斜杠、尾分隔符、NUL 和控制字符。
151
+ - `create()` 的 `recursive` 与 `exclusive` 默认均为 `false`。默认行为是不截断内容的 ensure-exists;`exclusive: true` 在同名实体已存在时失败。
152
+ - `writeText()` / `writeBytes()` 可以在父目录存在时隐式创建目标,但不会自动创建父目录。
153
+ - `exists()` 在祖先/目标缺失或 kind mismatch 时返回 `false`;授权撤销、quota 与 I/O 错误仍抛出。
154
+ - `file.remove()` 与 `directory.remove()` 只删除 sandbox 对象;外部 picker/saveFile 授权调用删除时抛出 `FILE_ACCESS_DENIED`。
155
+ - 非空目录默认不能删除并抛出 `DIRECTORY_NOT_EMPTY`;确认删除整个目录树后显式调用 `directory.remove({ recursive: true })`。
156
+ - `directory.list()` 默认最多返回 1000 项,显式 `limit` 也不能超过 1000;超限抛出 `DIRECTORY_LIST_LIMIT_EXCEEDED`。
157
+ - Host 文件错误只暴露稳定 code 与 canonical 安全文案;原始 message、data、native path 和 credential 不会进入小程序。
158
+ - `FileStat.size` 是字节数;`modifiedAt` / `createdAt` 若存在,单位为 Unix epoch milliseconds。
159
+
160
+ ### 外部授权与保存
161
+
162
+ `pickFiles()`、`pickDirectory()` 和 `saveFile()` 必须直接从按钮点击等可信用户操作调用。picker
163
+ 取消会抛 `FILE_PICKER_CANCELLED`,不会返回空数组或 `undefined`。
164
+
165
+ ```ts
166
+ async function saveFromUserAction(text: string) {
167
+ const file = await hbSDK.files.saveFile({ suggestedName: 'report.json' })
168
+ await file.writeText(text)
169
+ }
170
+ ```
171
+
172
+ `saveFile()` 打开系统保存对话框并返回精确 File 授权,不会同时创建或保留 Directory
173
+ 授权。V1 不接受 `accept`;扩展名过滤只属于 `pickFiles({ accept: ['.json'] })`。外部授权仅在当前
174
+ Runtime session 有效。
175
+
176
+ `pickFiles()` / `pickDirectory()` 默认返回 `mode: 'read'` 的授权;只有显式传入
177
+ `multiple: true` 时,`pickFiles()` 才允许 Host 返回多个文件。需要修改文件、在所选目录中创建
178
+ 文件,或把外部授权用作下载目标时,必须在 picker options 中显式请求 `mode: 'readwrite'`。
179
+
180
+ 单个 Runtime session 最多保留 1024 个 picker/saveFile direct handle;整批选择超过剩余额度时抛出 `FILE_QUOTA_EXCEEDED`,不会保留部分授权。Sandbox 派生项与目录枚举结果使用逻辑引用,不持续占用该额度。
181
+
182
+ ### 下载边界
183
+
184
+ - 下载固定使用 GET,不接受 method、body、上传或 Range 字段。
185
+ - File target 必须已存在且为 `readwrite`,成功后返回同一个 File proxy;Directory target 必须存在且为 `readwrite`,成功后返回新的子 File proxy。
186
+ - Directory 默认不覆盖同名文件;只有显式 `overwrite: true` 才允许原子替换。
187
+ - Directory target 的子文件名按安全的 `Content-Disposition filename*` / `filename`、`suggestedName`、URL basename、`download.bin` 依次选择。
188
+ - `timeout` 是网络空闲超时,不是整个下载总时长。取消或失败不会改动原目标。
189
+ - `AbortSignal` 只发出取消意图并等待 Host 终态;如果 Host 已先完成原子提交,Promise 仍以成功结果 resolve,否则抛出 `DOWNLOAD_CANCELLED`。
190
+ - 公开 request 与 download 都不跟随重定向;3xx 或 partial representation 会失败。
191
+ - 进度从 `loaded: 0` 开始并单调不减;原子提交后、Promise resolve 前会再发送一次 final progress,因此空文件或 Host 已报告最终值时允许相邻值相同。只有无歧义、identity-encoded 的 `Content-Length` 才使 `lengthComputable=true`;压缩、chunked 或重复长度都视为未知 total,可信长度必须在提交前与实际字节数一致。
192
+ - `onProgress` 在本地同步执行;回调异常不会中断下载。成功时最后一次回调发生在文件提交后、Promise resolve 前。
193
+
96
194
  ## 默认单例
97
195
 
98
196
  大多数小程序页面都应该使用默认实例。0.6 起不再对业务代码提供独立实例工厂。
@@ -104,16 +202,17 @@ async function loginFromUserAction() {
104
202
 
105
203
  `app_user_id` 是平台为“用户 × 当前小程序”生成的稳定、隔离标识,不是黑盒用户 ID。它是不透明字符串,只能在当前小程序内使用,不能解析或跨小程序关联。
106
204
 
107
- 用户身份接入取决于小程序是否已开通 `network.request`。两类小程序使用不同的身份入口:
205
+ 身份能力与公开 `network` 权限相互独立。根据业务需要选择入口,并在 `package.json#heybox.permissions` 声明对应权限:
108
206
 
109
- | 小程序类型 | 身份入口 | 结果用途 |
110
- | -------------- | ------------------------- | ------------------------------------------------------ |
111
- | 已开通网络权限 | `auth.login({ scopes? })` | 获取短期授权码,由开发者服务端换取 OpenAPI token |
112
- | 未开通网络权限 | `user.getInfo()` | 静默读取隔离身份及昵称头像,隐式授予本地用户 scopes |
207
+ | 身份入口 | 权限 | 结果用途 |
208
+ | ------------------------- | -------------- | ------------------------------------------------ |
209
+ | `auth.login({ scopes? })` | `userInfo` | 获取短期授权码,由开发者服务端换取 OpenAPI token |
210
+ | `user.getInfo()` | `userInfo` | 读取当前用户的隔离身份及已授权资料 |
211
+ | `user.getSteamGameList()` | `steamLibrary` | 读取当前用户的 Steam 游戏库 |
113
212
 
114
213
  不要混用两条路径。SDK 不向小程序页面提供 token、cookie、黑盒用户 ID 或平台私有凭据。
115
214
 
116
- ## 已开通网络权限
215
+ ## 获取服务端授权码
117
216
 
118
217
  在登录、绑定账号或读取资料等明确的用户操作中调用 `auth.login()`:
119
218
 
@@ -167,9 +266,13 @@ async function loginFromUserAction() {
167
266
 
168
267
  用户已授权所需 scope 时,`auth.login()` 可以不展示 UI,静默返回新的短期授权码。业务仍应把可能出现的授权 UI 设计在明确的用户操作之后,不要在页面初始化阶段自动调用。
169
268
 
269
+ `auth.login()` 内部使用 Host 的受信请求,不会调用小程序公开的 `network.request()`,因此不要求声明 `network`。如果页面需要把 code 通过 `network.request()` 发给开发者服务端,则该请求本身仍需声明并获得 `network` 的平台批准。
270
+
271
+ OpenAPI 凭据、授权码和 access token 的生命周期也不由 `network` 权限开启或关闭。
272
+
170
273
  ## 撤销当前小程序授权
171
274
 
172
- 已开通和未开通网络权限的小程序都可以在明确的用户操作中撤销授权:
275
+ 任何小程序都可以在明确的用户操作中撤销授权;`user.revokeAuthorization()` 位于无需声明白名单:
173
276
 
174
277
  ```ts
175
278
  async function revokeAuthorizationFromUserAction() {
@@ -183,22 +286,11 @@ async function revokeAuthorizationFromUserAction() {
183
286
 
184
287
  `user.revokeAuthorization()` 不接收参数。小程序页面不能提交小程序 ID、黑盒用户 ID 或手势标记;Runtime 从 Host 启动上下文和用户操作状态注入可信值。调用缺少可信用户手势时返回 `USER_GESTURE_REQUIRED`。
185
288
 
186
- 撤销成功后,后续 `auth.login()` 会重新进入授权流程;无网络小程序再次调用 `user.getInfo()` 时会重新建立隔离身份。业务必须立即停止使用并清理此前保存的 `app_user_id`、用户资料和开发者服务端会话;SDK 不会删除业务自己的 localStorage、数据库或 cookie。
187
-
188
- ## 当前用户资料由服务端读取
189
-
190
- 已开通网络权限后,页面不再直接读取 Host 当前用户资料。`@heybox/hb-sdk` 根包实际导出的以下调用统一返回 `SERVER_API_REQUIRED`:
191
-
192
- - `user.getInfo()`
193
- - `user.getSteamGameList(options)`
289
+ 撤销成功后,后续 `auth.login()` 会重新进入授权流程;再次调用 `user.getInfo()` 时会按现有用户授权规则读取身份。业务必须立即停止使用并清理此前保存的 `app_user_id`、用户资料和开发者服务端会话;SDK 不会删除业务自己的 localStorage、数据库或 cookie。
194
290
 
195
- 其他 Host current-user capabilities 属于 Host/runtime 集成边界,不是小程序可从 SDK 根包调用的方法。需要对应数据时,先取得授权码,再由开发者服务端按后端 OpenAPI 文档换取 token 并调用对应接口。不要把 `SERVER_API_REQUIRED` 当作未登录或权限弹窗失败。
291
+ ## 读取当前用户资料
196
292
 
197
- `user.revokeAuthorization()` 是例外:它是授权变更操作,在两种网络模式下都可用,但始终要求可信用户手势。
198
-
199
- ## 未开通网络权限
200
-
201
- 未开通网络权限的小程序不走授权码流程。需要当前用户在本小程序内的稳定隔离身份和公开资料时调用:
293
+ 需要当前用户在本小程序内的稳定隔离身份和已授权资料时调用:
202
294
 
203
295
  ```ts
204
296
  import hbSDK from '@heybox/hb-sdk'
@@ -209,14 +301,16 @@ async function getCurrentUser() {
209
301
  }
210
302
  ```
211
303
 
212
- `user.getInfo()` 是静默本地用户接口,不展示授权弹窗,也不要求可信用户手势。未登录时返回 `isHeyboxAppLoggedIn: false`;已登录时隐式授予当前本地用户 scopes(`identity`、`profile`),建立并返回当前小程序隔离的 `app_user_id`、`profile.nickname` 和 `profile.avatar`。每次成功调用都会广播一次 `user_info_authorization_change`,其中 `identity` 与 `profile` 均为 `granted`,即使授权状态没有发生变化。撤销授权后再次调用仍会静默建立新的隔离身份并恢复无网络模式的隐式授权。
304
+ `user.getInfo()` 不依赖 `network`,但必须声明 `userInfo`。它延续现有交互:不展示授权弹窗,也不要求可信用户手势。未登录时返回 `isHeyboxAppLoggedIn: false`;已登录时按现有用户授权状态返回当前小程序隔离的 `app_user_id`,以及已授权的 `profile.nickname` 和 `profile.avatar` 等可用资料。用户授权与开发者权限声明是两层独立门禁,不能用声明代替用户同意。
213
305
 
214
- 这类小程序无法获取授权码,也无法调用 OpenAPI;在未开通网络权限时调用 `auth.login()` 同样返回 `SERVER_API_REQUIRED`。隐式 full-scope 仅适用于 Host 本地用户资料能力,不代表开放网络或服务端凭据;页面不能把其中的身份或资料发送到外部服务。
306
+ Steam 游戏库使用 `user.getSteamGameList(options)`,要求声明 `steamLibrary`,同样不依赖 `network`。Host current-user capabilities 的既有账号绑定和数据可用性规则保持不变。
215
307
 
216
308
  ## 网络请求边界
217
309
 
218
310
  `network.request()` 只用于访问开发者自己的业务服务。平台保留的 runtime auth 与 OpenAPI 内部路径不能通过该能力访问;身份交换必须由开发者服务端按公开后端文档完成。
219
311
 
312
+ 完整权限配置与错误区别见[权限声明](https://docs.xiaoheihe.cn/hb_sdk/guide/permissions)。
313
+
220
314
  ## CLI 登录与用户登录
221
315
 
222
316
  `hb-sdk login` 只给本地开发和远端管理命令建立 CLI 登录态,与小程序页面的 `auth.login()`、`user.getInfo()` 和用户授权完全无关。
@@ -274,7 +368,7 @@ onUnmounted(stopLifecycleEvents)
274
368
  - 当前握手状态只通过 `getHandshakeState()` 查询、通过 `onHandshakeStateChange()` 订阅;订阅会立即回放当前值并返回取消函数。
275
369
  - `ready` 事件只在握手成功瞬间派发,不会向晚订阅者重放,不能用于驱动按钮可用状态或替代握手状态 API。
276
370
  - UI 可见性相关逻辑放在 `show`、`hide`。
277
- - 使用 Host current-user APIs 的无网络小程序,可以在 `heybox_app_login_change` 后刷新本地状态。已开通网络权限的小程序使用 `auth.login()` 获取 code,并由开发者服务端维护业务会话。
371
+ - 使用 `user.getInfo()` 的小程序可以在 `heybox_app_login_change` 后刷新本地状态。需要开发者服务端会话时使用 `auth.login()` 获取 code;两者都不依赖公开 `network` 权限。
278
372
  - 组件或页面销毁时清理 `on` 注册的监听,避免重复响应。
279
373
  - 生命周期事件只派发给注册当时存在的监听器,不会重放;一次性 `launch` 信息应在页面启动阶段通过业务能力调用处理。
280
374
  - 收到 `unload` 后,当前 SDK 上下文不可恢复,未完成请求会失败;不要在同一页面上下文继续重试能力调用。
@@ -313,9 +407,15 @@ try {
313
407
 
314
408
  - 根据 `error.code` 区分运行环境、权限、超时和业务失败,不要只比对错误文案。
315
409
  - 权限失败时给出可理解的提示,不要将它当成未登录。
410
+ - `PERMISSION_NOT_DECLARED` 表示当前版本没有在 `package.json#heybox.permissions` 声明所需权限,应修改项目配置并重新构建、提交版本。
411
+ - `PERMISSION_DENIED` 表示权限已声明,但需要的平台批准缺失或批准配置不足。首期只有 `network` 需要平台批准。
316
412
  - `USER_GESTURE_REQUIRED` 表示潜在授权 UI 缺少可信用户手势,应让用户点击按钮后重试。
317
413
  - `AUTHORIZATION_CANCELLED` 表示用户取消、拒绝或关闭授权页面,应正常结束当前操作。
318
414
  - `SERVER_API_REQUIRED` 表示当前用户数据必须经开发者服务端 OpenAPI 获取,不应在页面重试对应 Host API。
415
+ - `METHOD_FORBIDDEN` 表示当前 Host 未实现或关闭对应能力。V1 files/download 在 Mobile、Web 和 Browser Dev Host 都会得到该错误。
416
+ - `FILE_PICKER_CANCELLED` 表示用户取消了外部文件或目录选择,应正常结束当前操作。
417
+ - `DOWNLOAD_CANCELLED` 表示取消意图先于 Host 提交生效;Host 已完成提交时仍返回成功。`DOWNLOAD_TIMEOUT` 表示网络空闲超时,失败不会改动原目标。
418
+ - `DOWNLOAD_HTTP_STATUS` 的 `data` 只包含脱敏后的 `status`、可选 `statusText` 和安全响应头。
319
419
  - 超时或运行环境不可用时,允许用户重试或退出当前流程。
320
420
  - 上报 `code`、`message` 和必要的业务上下文,不要上报用户凭据或敏感数据。
321
421
 
@@ -364,12 +464,16 @@ function reportSDKError(errorCode: string, message: string, data?: unknown) {
364
464
 
365
465
  授权码在取得后立即交给开发者服务端交换,不要写入页面状态、DOM、日志或持久化存储。UI 只处理服务端会话是否建立成功。
366
466
 
467
+ 文件与下载仍使用 `HbMiniProgramSDKError`,不会新增第三种错误类。业务根据 `error.code` 处理
468
+ picker 取消、授权撤销、文件缺失、quota、下载状态或取消,不依赖 `message` 文案,也不要记录
469
+ 真实路径、内部 handle 或响应凭据头。
470
+
367
471
  ## Login gate recipe
368
472
 
369
473
 
370
474
  # 服务端登录门禁
371
475
 
372
- 已开通网络权限的小程序可以把“取得授权码并交给开发者服务端”收敛成一个用户操作函数:
476
+ 声明 `userInfo` 后,小程序可以把“取得授权码并交给开发者服务端”收敛成一个用户操作函数。`auth.login()` 本身不依赖 `network`;以下示例使用 `network.request()` 传递 code,因此还需声明并获得 `network` 的平台批准:
373
477
 
374
478
  示例中的 URL 是开发者自己的后端接口,不是黑盒 OpenAPI 地址。
375
479
 
@@ -419,7 +523,7 @@ async function handleSubmit() {
419
523
 
420
524
  ## 普通分享
421
525
 
422
- 普通分享只支持一个默认分区,并且配置 `post` 时不要同时指定站外 `channel`。
526
+ 普通分享的落地页固定为当前小程序的 `common_share`,不接受自定义 `url`。普通分享只支持一个默认分区,并且配置 `post` 时不要同时指定站外 `channel`。
423
527
 
424
528
  ```ts
425
529
  import { share } from '@heybox/hb-sdk'
@@ -451,7 +555,7 @@ await share.screenshot({
451
555
 
452
556
  ## 恢复分享页面状态
453
557
 
454
- 使用默认通用分享链接时,可以通过 `extra` 携带由小程序自行定义的页面状态。分享方只负责写入状态,接收方负责决定如何使用:
558
+ 通过固定通用分享链接分享时,可以使用 `extra` 携带由小程序自行定义的页面状态。分享方只负责写入状态,接收方负责决定如何使用:
455
559
 
456
560
  ```ts
457
561
  await share.showShareMenu({
@@ -484,7 +588,7 @@ if (sharedState && typeof sharedState === 'object' && !Array.isArray(sharedState
484
588
  }
485
589
  ```
486
590
 
487
- `getExtra()` 不依赖异步请求;没有有效数据时返回 `undefined`,业务应回退到默认首页。`extra` 只支持 JSON-compatible 数据,最多 8 层,单个数组或对象最多 64 项,内容不超过 128 字节;不能与自定义 `url` 同时使用,也不要存放 token、个人信息等敏感数据。`copyLink()` 不会继承当前启动链接中的 `extra`,只携带本次显式传入的数据。
591
+ `getExtra()` 不依赖异步请求;没有有效数据时返回 `undefined`,业务应回退到默认首页。`extra` 只支持 JSON-compatible 数据,最多 8 层,单个数组或对象最多 64 项,内容不超过 128 字节,也不要存放 token、个人信息等敏感数据。`copyLink()` 不会继承当前启动链接中的 `extra`,只携带本次显式传入的数据。
488
592
 
489
593
  ## 参数边界
490
594
 
@@ -507,7 +611,6 @@ if (sharedState && typeof sharedState === 'object' && !Array.isArray(sharedState
507
611
 
508
612
  ```ts
509
613
  import hbSDK from '@heybox/hb-sdk'
510
-
511
614
  ```
512
615
 
513
616
  ## 测试环境注入 window
@@ -1,6 +1,6 @@
1
1
  # Safety boundaries
2
2
 
3
- > Generated by `node packages/hb-sdk/skill/scripts/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
3
+ > Generated by `node packages/hb-sdk/scripts/skill/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.
4
4
 
5
5
  ## Sources
6
6
 
@@ -15,15 +15,24 @@
15
15
  - `ready` 生命周期事件是不可重放的边沿通知,不代表可查询状态,也不能替代握手状态 API。
16
16
  - `auth.login({ scopes? })` 只返回 `{ code, expiresIn: 300, scopes }`;identity 隐式强制包含,code 只能提交给开发者服务端。
17
17
  - 需要授权 UI 时,`auth.login()` 必须来自可信用户手势,否则返回 `USER_GESTURE_REQUIRED`;用户取消或关闭时返回 `AUTHORIZATION_CANCELLED`。已授权时可以静默返回新 code。
18
- - `user.getSteamGameList()` 仅供未开通网络权限的小程序通过 Host 读取;已开通网络权限时返回 `SERVER_API_REQUIRED`,且授权码与 OpenAPI 不提供 Steam 游戏库 scope 或资源接口。
19
- - 已开通网络权限时,公开的 `user.getInfo()` 返回 `SERVER_API_REQUIRED`;对应身份和资料数据应由开发者服务端通过 OpenAPI 获取。
20
- - 未开通网络权限时,`user.getInfo()` 隐式授予 `identity` 与 `profile`,静默返回 `userInfo.app_user_id`、昵称和头像;这条路径仍不能获取 code 或调用 OpenAPI。
18
+ - `auth.login()`、`user.getInfo()` `user.getSteamGameList()` 的可用性不由 `network` 决定;它们分别要求 `userInfo` `steamLibrary`,并继续遵循各自的用户授权和数据规则。
21
19
  - `user.revokeAuthorization()` 在两种网络模式下都要求可信用户手势;成功后必须停止使用并清理业务缓存的旧身份、资料和服务端会话。
22
20
  - `on()` 返回取消监听函数,组件卸载或页面销毁时需要调用。
23
21
  - 业务网络请求使用 `network.request()`,不要依赖浏览器原生网络出口。
22
+ - 公开 `network.request()` 与 `network.download()` 均使用 no-follow redirect policy;3xx 不会在 Host 内静默跳转。
24
23
  - `network.request()` 不能访问平台保留的 runtime auth 与 OpenAPI 内部路径;页面不得持有或交换服务端应用凭据。
25
24
  - `network.request` 不支持 `multipart/form-data`;App Host 仅支持 form(`application/x-www-form-urlencoded`)与 JSON。表单请用 `URLSearchParams#toString()` 作为 `data`,文件上传请走专用上传能力。
26
- - 仅当远端已启用 `network.request` 时,`hb-sdk dev` `hb-sdk remote deploy` 构建才会跳过平台 CSP;其他构建继续注入平台 CSP。`useOfficialDomain` 不参与 CSP 跳过判定。
25
+ - 当前 Host(包括旧版 PC、Mobile、WebBrowser Dev Host)均未开放 `files` / `network.download()`;新版 PC 将按同一公开合同重新接入,期间不提供内存或 Blob 假实现。
26
+ - picker 必须来自可信用户手势;取消选择返回 `FILE_PICKER_CANCELLED`。`saveFile()` 只接受 `suggestedName`,不接受 `accept`。
27
+ - `pickFiles()` / `pickDirectory()` 默认只读;`pickFiles()` 仅在显式传入 `multiple: true` 时允许 Host 返回多个文件。要写入或作为下载目标时显式请求 `mode: 'readwrite'`。
28
+ - `file()` / `directory()` 只接受以 `/` 分隔的规范相对路径;拒绝绝对路径、空 segment、`.`、`..`、反斜杠、尾分隔符和控制字符。
29
+ - `create()` 的 `recursive` / `exclusive` 默认都是 `false`;`exists()` 仅把缺失祖先、缺失目标或 kind mismatch 归一为 `false`,不会吞授权和 I/O 错误。
30
+ - `remove()` 只允许删除 sandbox 对象;外部 picker/saveFile 授权返回 `FILE_ACCESS_DENIED`。非空目录默认返回 `DIRECTORY_NOT_EMPTY`,需显式调用 `remove({ recursive: true })`。
31
+ - `directory.list()` 默认最多返回 1000 项,`limit` 也不能超过 1000;超限返回 `DIRECTORY_LIST_LIMIT_EXCEEDED`。
32
+ - 单个 Runtime session 最多保留 1024 个 picker/saveFile direct handle;整批授权超限时返回 `FILE_QUOTA_EXCEEDED`,不会保留部分结果。
33
+ - Host 文件错误只保留稳定 code 与 canonical 安全文案;原始 message、data、native path 和 credential 不会进入小程序。
34
+ - `FileStat.size` 是非负 safe integer;`modifiedAt` / `createdAt` 若存在,单位为 Unix epoch milliseconds。
35
+ - 仅当当前版本声明且平台已批准 `network` 时,`hb-sdk dev` 与 `hb-sdk remote deploy` 构建才会跳过平台 CSP;其他构建继续注入平台 CSP。`useOfficialDomain` 不参与 CSP 跳过判定。
27
36
  - 构建必须启用 `miniappManifest({ platforms })` 并显式声明实际承诺适配的平台,推荐统一使用 `hb-sdk build`。新项目模板中的 `['android', 'ios', 'ohos']` 只是初始配置,不代表已经完成真机验收。
28
37
 
29
38
  ## Agent rules
package/skill/skill.json CHANGED
@@ -1,11 +1,16 @@
1
1
  {
2
2
  "name": "hb-sdk",
3
- "skillVersion": "0.8.0-alpha+skill.e73cb0ba5184",
3
+ "skillVersion": "0.8.0-alpha.10+skill.4d468f0653d9",
4
4
  "sdk": {
5
5
  "package": "@heybox/hb-sdk",
6
- "version": "0.8.0-alpha",
7
- "compatibility": "0.8.0-alpha"
6
+ "version": "0.8.0-alpha.10",
7
+ "compatibility": "0.8.0-alpha.10"
8
8
  },
9
- "source": "https://open.xiaoheihe.cn/agent-skills/hb-sdk",
10
- "integrity": "sha256-e73cb0ba518459e1b262d09fb0ead87a7163c8e5358430184a9dd4f085049357"
9
+ "distribution": {
10
+ "type": "npm",
11
+ "package": "@heybox/hb-sdk",
12
+ "version": "0.8.0-alpha.10",
13
+ "path": "skill"
14
+ },
15
+ "integrity": "sha256-4d468f0653d9f6eac9578d47d85b955c01e84dd38b91d123a2b832e60f50b34c"
11
16
  }
@@ -25,8 +25,18 @@ export interface MiniProgramRequester {
25
25
  /** 向父容器调用指定开放能力。 */
26
26
  request<Method extends MiniProgramBridgeMethod>(method: Method, ...args: MiniProgramRequesterArgs<Method>): Promise<MiniProgramCapabilityResult<Method>>;
27
27
  }
28
+ /** 长操作使用的本地 observer 与取消配置,不进入 bridge payload。 */
29
+ export interface MiniProgramOperationOptions<TProgress = unknown> {
30
+ signal?: AbortSignal;
31
+ onProgress?: (progress: TProgress) => void;
32
+ createAbortError?: () => unknown;
33
+ }
34
+ /** 支持 request-scoped progress/cancel 的 bridge requester。 */
35
+ export interface MiniProgramOperationRequester extends MiniProgramRequester {
36
+ requestOperation<Method extends MiniProgramBridgeMethod, TProgress = unknown>(method: Method, payload: MiniProgramCapabilityPayload<Method>, options?: MiniProgramOperationOptions<TProgress>): Promise<MiniProgramCapabilityResult<Method>>;
37
+ }
28
38
  /** 底层 bridge client,负责握手、请求响应、事件分发与超时清理。 */
29
- export declare class MiniProgramBridgeClient implements MiniProgramRequester {
39
+ export declare class MiniProgramBridgeClient implements MiniProgramOperationRequester {
30
40
  private readonly timeout;
31
41
  private readonly selfWindow?;
32
42
  private readonly targetWindow;
@@ -64,6 +74,9 @@ export declare class MiniProgramBridgeClient implements MiniProgramRequester {
64
74
  off<T extends MiniProgramEventName>(eventName: T, handler: MiniProgramEventHandler<T>): void;
65
75
  /** 调用父容器开放能力。 */
66
76
  request<Method extends MiniProgramBridgeMethod>(method: Method, ...args: MiniProgramRequesterArgs<Method>): Promise<MiniProgramCapabilityResult<Method>>;
77
+ /** 发起不使用固定总时长 timer 的长操作。 */
78
+ requestOperation<Method extends MiniProgramBridgeMethod, TProgress = unknown>(method: Method, payload: MiniProgramCapabilityPayload<Method>, options?: MiniProgramOperationOptions<TProgress>): Promise<MiniProgramCapabilityResult<Method>>;
79
+ private performRequest;
67
80
  /** 销毁 SDK 实例,并拒绝尚未完成的请求。 */
68
81
  destroy(): void;
69
82
  private ensureStarted;
@@ -73,6 +86,9 @@ export declare class MiniProgramBridgeClient implements MiniProgramRequester {
73
86
  private postCSPViolation;
74
87
  private handleEvent;
75
88
  private handleResponse;
89
+ private handleOperationProgress;
90
+ private sendCancel;
91
+ private cleanupPending;
76
92
  private postMessage;
77
93
  private resolveHandshakeOnce;
78
94
  private failHandshake;