@heybox/hb-sdk 0.7.5-alpha.0 → 0.8.0-alpha.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 (76) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +69 -16
  3. package/THIRD_PARTY_NOTICES.md +1755 -0
  4. package/dist/cli-chunks/{build-V1YBdpzY.cjs → build-CCLWgXyA.cjs} +6 -5
  5. package/dist/cli-chunks/{context-Ba1Je-wT.cjs → context-Brh56h56.cjs} +2 -27
  6. package/dist/cli-chunks/{create-CKGjqo9E.cjs → create-BZ-hi2s1.cjs} +1 -1
  7. package/dist/cli-chunks/{dev-XopYKLYZ.cjs → dev-CoSXtEYa.cjs} +336 -517
  8. package/dist/cli-chunks/{doctor-BHbrYQqT.cjs → doctor-EsCYJGhV.cjs} +1 -1
  9. package/dist/cli-chunks/{index-C9mpajVG.cjs → index-BL5eEPap.cjs} +14 -14
  10. package/dist/cli-chunks/{index-DKWfX6Ut.cjs → index-CS6Q0o5C.cjs} +2 -2
  11. package/dist/cli-chunks/{index.esm-SXAQ3WVR.cjs → index.esm-BoBHPfpq.cjs} +6 -6
  12. package/dist/cli-chunks/{login-BVWicWqe.cjs → login-CILLxGuf.cjs} +2 -2
  13. package/dist/cli-chunks/{project-vite-CBb38HJ3.cjs → project-vite-Qu6Xe9Dn.cjs} +1 -1
  14. package/dist/cli-chunks/{remote-BG1u0NKT.cjs → remote-DRuTQ51u.cjs} +10 -8
  15. package/dist/cli-chunks/{runtime-gate-CtV7rWyX.cjs → runtime-gate-DFjw66kF.cjs} +20 -1
  16. package/dist/cli-chunks/{runtime-permission-env-D-8_jPG3.cjs → runtime-permission-env-CjsCe5bp.cjs} +13 -13
  17. package/dist/cli-chunks/{session-CJS_SEp9.cjs → session-D-_N3WVL.cjs} +1 -1
  18. package/dist/cli.cjs +1 -1
  19. package/dist/devtools/browser-dev-host/assets/browser-dev-host-uq-Wac6k.js +97 -0
  20. package/dist/devtools/browser-dev-host/assets/heybox-logo-CogNENsk.svg +6 -0
  21. package/dist/devtools/browser-dev-host/assets/index-CeP6SLB3.js +567 -0
  22. package/dist/devtools/browser-dev-host/assets/index-KD2f3Jdz.css +1 -0
  23. package/dist/devtools/browser-dev-host/assets/workbench-state-D-1U0JRq.js +5 -0
  24. package/dist/devtools/browser-dev-host/index.html +6 -435
  25. package/dist/index.cjs.js +1036 -90
  26. package/dist/index.esm.js +1036 -91
  27. package/dist/miniapp-publish.cjs.js +13 -13
  28. package/dist/miniapp-publish.esm.js +13 -13
  29. package/dist/protocol.cjs.js +208 -6
  30. package/dist/protocol.esm.js +182 -7
  31. package/dist/templates/vue3-vite-ts/README.md.ejs +2 -0
  32. package/dist/templates/vue3-vite-ts/vite.config.ts +1 -1
  33. package/dist/vite.cjs.js +31 -4
  34. package/dist/vite.esm.js +31 -5
  35. package/package.json +28 -11
  36. package/skill/SKILL.md +9 -5
  37. package/skill/references/api-protocol.md +111 -3
  38. package/skill/references/api-root.md +170 -22
  39. package/skill/references/cli.md +21 -17
  40. package/skill/references/examples.md +30 -1
  41. package/skill/references/recipes.md +105 -1
  42. package/skill/references/safety-boundaries.md +12 -1
  43. package/skill/scripts/sync-references.mjs +37 -3
  44. package/skill/skill.json +4 -4
  45. package/types/core/client.d.ts +17 -1
  46. package/types/core/errors.d.ts +5 -5
  47. package/types/core/sdk.d.ts +8 -5
  48. package/types/core/singleton.d.ts +59 -6
  49. package/types/index.d.ts +4 -2
  50. package/types/miniapp-manifest/schema.d.ts +5 -0
  51. package/types/miniapp-publish/index.d.ts +8 -8
  52. package/types/modules/auth/index.d.ts +15 -1
  53. package/types/modules/cloud/index.d.ts +75 -5
  54. package/types/modules/device/index.d.ts +31 -3
  55. package/types/modules/files/index.d.ts +5 -0
  56. package/types/modules/files/registry.d.ts +35 -0
  57. package/types/modules/files/types.d.ts +159 -0
  58. package/types/modules/navigation/index.d.ts +46 -4
  59. package/types/modules/network/index.d.ts +72 -14
  60. package/types/modules/share/copy-link.d.ts +3 -3
  61. package/types/modules/share/index.d.ts +61 -5
  62. package/types/modules/share/screenshot.d.ts +3 -3
  63. package/types/modules/share/show-share-menu.d.ts +3 -3
  64. package/types/modules/storage/index.d.ts +38 -10
  65. package/types/modules/ui/index.d.ts +46 -4
  66. package/types/modules/user/get-info.d.ts +1 -1
  67. package/types/modules/user/index.d.ts +46 -4
  68. package/types/modules/user/steam-game-list.d.ts +2 -2
  69. package/types/modules/viewport/index.d.ts +36 -8
  70. package/types/protocol/capabilities.d.ts +2 -2
  71. package/types/protocol/constants.d.ts +1 -1
  72. package/types/protocol/guards.d.ts +1 -1
  73. package/types/protocol/types.d.ts +1 -1
  74. package/types/protocol.d.ts +4 -3
  75. package/types/vite/index.d.ts +15 -7
  76. package/dist/devtools/browser-dev-host/main.js +0 -12158
@@ -10,6 +10,22 @@ const VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = 'viewport.setNavigationBarStyle
10
10
  const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage';
11
11
  const STORAGE_SET_STORAGE_METHOD = 'storage.setStorage';
12
12
  const NETWORK_REQUEST_METHOD = 'network.request';
13
+ const NETWORK_DOWNLOAD_METHOD = 'network.download';
14
+ const FILES_PICK_FILES_METHOD = 'files.pickFiles';
15
+ const FILES_PICK_DIRECTORY_METHOD = 'files.pickDirectory';
16
+ const FILES_SAVE_FILE_METHOD = 'files.saveFile';
17
+ const FILE_CREATE_METHOD = 'file.create';
18
+ const FILE_REMOVE_METHOD = 'file.remove';
19
+ const FILE_EXISTS_METHOD = 'file.exists';
20
+ const FILE_READ_TEXT_METHOD = 'file.readText';
21
+ const FILE_WRITE_TEXT_METHOD = 'file.writeText';
22
+ const FILE_READ_BYTES_METHOD = 'file.readBytes';
23
+ const FILE_WRITE_BYTES_METHOD = 'file.writeBytes';
24
+ const FILE_STAT_METHOD = 'file.stat';
25
+ const DIRECTORY_CREATE_METHOD = 'directory.create';
26
+ const DIRECTORY_REMOVE_METHOD = 'directory.remove';
27
+ const DIRECTORY_EXISTS_METHOD = 'directory.exists';
28
+ const DIRECTORY_LIST_METHOD = 'directory.list';
13
29
  const UI_SHOW_TOAST_METHOD = 'ui.showToast';
14
30
  const UI_SHOW_LOADING_METHOD = 'ui.showLoading';
15
31
  const UI_HIDE_LOADING_METHOD = 'ui.hideLoading';
@@ -60,6 +76,46 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
60
76
  { method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
61
77
  { method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
62
78
  { method: NETWORK_REQUEST_METHOD, module: 'network', capability: NETWORK_REQUEST_METHOD, permission: 'network.request', risk: 'high' },
79
+ { method: NETWORK_DOWNLOAD_METHOD, module: 'network', capability: NETWORK_DOWNLOAD_METHOD, permission: 'network.request', risk: 'high' },
80
+ { method: FILES_PICK_FILES_METHOD, module: 'files', capability: FILES_PICK_FILES_METHOD, permission: 'files.external', risk: 'high' },
81
+ {
82
+ method: FILES_PICK_DIRECTORY_METHOD,
83
+ module: 'files',
84
+ capability: FILES_PICK_DIRECTORY_METHOD,
85
+ permission: 'files.external',
86
+ risk: 'high',
87
+ },
88
+ { method: FILES_SAVE_FILE_METHOD, module: 'files', capability: FILES_SAVE_FILE_METHOD, permission: 'files.external', risk: 'high' },
89
+ { method: FILE_CREATE_METHOD, module: 'file', capability: FILE_CREATE_METHOD, permission: 'files.access', risk: 'high' },
90
+ { method: FILE_REMOVE_METHOD, module: 'file', capability: FILE_REMOVE_METHOD, permission: 'files.access', risk: 'high' },
91
+ { method: FILE_EXISTS_METHOD, module: 'file', capability: FILE_EXISTS_METHOD, permission: 'files.access', risk: 'high' },
92
+ { method: FILE_READ_TEXT_METHOD, module: 'file', capability: FILE_READ_TEXT_METHOD, permission: 'files.access', risk: 'high' },
93
+ { method: FILE_WRITE_TEXT_METHOD, module: 'file', capability: FILE_WRITE_TEXT_METHOD, permission: 'files.access', risk: 'high' },
94
+ { method: FILE_READ_BYTES_METHOD, module: 'file', capability: FILE_READ_BYTES_METHOD, permission: 'files.access', risk: 'high' },
95
+ { method: FILE_WRITE_BYTES_METHOD, module: 'file', capability: FILE_WRITE_BYTES_METHOD, permission: 'files.access', risk: 'high' },
96
+ { method: FILE_STAT_METHOD, module: 'file', capability: FILE_STAT_METHOD, permission: 'files.access', risk: 'high' },
97
+ {
98
+ method: DIRECTORY_CREATE_METHOD,
99
+ module: 'directory',
100
+ capability: DIRECTORY_CREATE_METHOD,
101
+ permission: 'files.access',
102
+ risk: 'high',
103
+ },
104
+ {
105
+ method: DIRECTORY_REMOVE_METHOD,
106
+ module: 'directory',
107
+ capability: DIRECTORY_REMOVE_METHOD,
108
+ permission: 'files.access',
109
+ risk: 'high',
110
+ },
111
+ {
112
+ method: DIRECTORY_EXISTS_METHOD,
113
+ module: 'directory',
114
+ capability: DIRECTORY_EXISTS_METHOD,
115
+ permission: 'files.access',
116
+ risk: 'high',
117
+ },
118
+ { method: DIRECTORY_LIST_METHOD, module: 'directory', capability: DIRECTORY_LIST_METHOD, permission: 'files.access', risk: 'high' },
63
119
  { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
64
120
  { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
65
121
  { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
@@ -124,15 +180,134 @@ const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
124
180
  const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
125
181
  const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
126
182
  const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
183
+ const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress';
127
184
 
128
185
  function isMiniProgramBridgeMessage(value) {
129
- if (!value || typeof value !== 'object')
186
+ if (!isRecord$1(value))
187
+ return false;
188
+ if (value.namespace !== MINI_PROGRAM_MESSAGE_NAMESPACE || (value.version !== 1 && value.version !== 2) || !isNonEmptyString(value.nonce)) {
130
189
  return false;
131
- const message = value;
132
- return (message.namespace === MINI_PROGRAM_MESSAGE_NAMESPACE &&
133
- (message.version === 1 || message.version === 2) &&
134
- typeof message.nonce === 'string' &&
135
- typeof message.type === 'string');
190
+ }
191
+ if (value.type === 'handshake') {
192
+ return isNonEmptyString(value.id) && value.method === SDK_HANDSHAKE_METHOD && value.error === undefined && isSDKHandshakePayload(value.payload);
193
+ }
194
+ if (value.type === 'request') {
195
+ return isNonEmptyString(value.id) && isNonEmptyString(value.method) && value.error === undefined;
196
+ }
197
+ if (value.type === 'response') {
198
+ return (isNonEmptyString(value.id) &&
199
+ (value.method === undefined || isNonEmptyString(value.method)) &&
200
+ (value.error === undefined || isBridgeError(value.error)));
201
+ }
202
+ if (value.type === 'event') {
203
+ if (!isNonEmptyString(value.method) || value.error !== undefined)
204
+ return false;
205
+ if (value.method === MINI_PROGRAM_OPERATION_PROGRESS_METHOD) {
206
+ return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramDownloadProgressPayload(value.payload);
207
+ }
208
+ return value.id === undefined || isNonEmptyString(value.id);
209
+ }
210
+ if (value.type === 'cancel') {
211
+ return (value.version === 2 && isNonEmptyString(value.id) && value.method === undefined && value.payload === undefined && value.error === undefined);
212
+ }
213
+ return false;
214
+ }
215
+ function isMiniProgramRelativePath(value) {
216
+ if (typeof value !== 'string' || !value || value.startsWith('/') || value.endsWith('/')) {
217
+ return false;
218
+ }
219
+ if (/[\\\u0000-\u001f\u007f]/.test(value))
220
+ return false;
221
+ return value.split('/').every((segment) => Boolean(segment) && segment !== '.' && segment !== '..');
222
+ }
223
+ function isMiniProgramPathRootRef(value) {
224
+ if (!isRecord$1(value))
225
+ return false;
226
+ if (value.kind === 'sandbox')
227
+ return hasOnlyKeys(value, ['kind']);
228
+ return value.kind === 'directory' && isNonEmptyString(value.handleId) && hasOnlyKeys(value, ['kind', 'handleId']);
229
+ }
230
+ function isMiniProgramFileRef(value) {
231
+ if (!isRecord$1(value) || value.kind !== 'file')
232
+ return false;
233
+ if (isNonEmptyString(value.handleId)) {
234
+ return hasOnlyKeys(value, ['kind', 'handleId']);
235
+ }
236
+ return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
237
+ }
238
+ function isMiniProgramDirectoryRef(value) {
239
+ if (!isRecord$1(value) || value.kind !== 'directory')
240
+ return false;
241
+ if (isNonEmptyString(value.handleId)) {
242
+ return hasOnlyKeys(value, ['kind', 'handleId']);
243
+ }
244
+ return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
245
+ }
246
+ function isMiniProgramFileDescriptor(value) {
247
+ return (isRecord$1(value) &&
248
+ value.kind === 'file' &&
249
+ isNonEmptyString(value.name) &&
250
+ isFileMode(value.mode) &&
251
+ isMiniProgramFileRef(value.ref) &&
252
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref']));
253
+ }
254
+ function isMiniProgramDirectoryDescriptor(value) {
255
+ return (isRecord$1(value) &&
256
+ value.kind === 'directory' &&
257
+ isNonEmptyString(value.name) &&
258
+ isFileMode(value.mode) &&
259
+ isMiniProgramDirectoryRef(value.ref) &&
260
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref']));
261
+ }
262
+ function isMiniProgramFileSystemEntityDescriptor(value) {
263
+ return isMiniProgramFileDescriptor(value) || isMiniProgramDirectoryDescriptor(value);
264
+ }
265
+ function isMiniProgramByteArray(value) {
266
+ return value instanceof Uint8Array && value.buffer instanceof ArrayBuffer;
267
+ }
268
+ function isMiniProgramFileStat(value) {
269
+ return (isRecord$1(value) &&
270
+ value.kind === 'file' &&
271
+ isNonNegativeSafeInteger(value.size) &&
272
+ (value.modifiedAt === undefined || isNonNegativeFiniteNumber(value.modifiedAt)) &&
273
+ (value.createdAt === undefined || isNonNegativeFiniteNumber(value.createdAt)) &&
274
+ hasOnlyKeys(value, ['kind', 'size', 'modifiedAt', 'createdAt']));
275
+ }
276
+ function isMiniProgramDownloadProgressPayload(value) {
277
+ if (!isRecord$1(value) ||
278
+ !isNonNegativeSafeInteger(value.loaded) ||
279
+ typeof value.lengthComputable !== 'boolean' ||
280
+ !hasOnlyKeys(value, ['loaded', 'total', 'lengthComputable'])) {
281
+ return false;
282
+ }
283
+ if (!value.lengthComputable)
284
+ return value.total === undefined;
285
+ return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
286
+ }
287
+ function isSDKHandshakePayload(value) {
288
+ return isRecord$1(value) && isNonEmptyString(value.href) && typeof value.userAgent === 'string' && isNonEmptyString(value.sdkVersion);
289
+ }
290
+ function isBridgeError(value) {
291
+ return isRecord$1(value) && isNonEmptyString(value.code) && typeof value.message === 'string';
292
+ }
293
+ function isFileMode(value) {
294
+ return value === 'read' || value === 'readwrite';
295
+ }
296
+ function isNonNegativeSafeInteger(value) {
297
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
298
+ }
299
+ function isNonNegativeFiniteNumber(value) {
300
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
301
+ }
302
+ function isNonEmptyString(value) {
303
+ return typeof value === 'string' && value.length > 0;
304
+ }
305
+ function hasOnlyKeys(value, allowedKeys) {
306
+ const allowed = new Set(allowedKeys);
307
+ return Object.keys(value).every((key) => allowed.has(key));
308
+ }
309
+ function isRecord$1(value) {
310
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
136
311
  }
137
312
 
138
313
  /** 当前用户信息与登录能力支持的完整 scope 目录。 */
@@ -177,4 +352,4 @@ function isRecord(value) {
177
352
  return typeof value === 'object' && value !== null && !Array.isArray(value);
178
353
  }
179
354
 
180
- export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, DEVICE_SET_CLIPBOARD_METHOD, DEVICE_VIBRATE_METHOD, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_COPY_LINK_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_INFO_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, USER_INFO_AUTHORIZATION_SCOPES, USER_REVOKE_AUTHORIZATION_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, parseMiniProgramRuntimePermissions };
355
+ export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, DEVICE_SET_CLIPBOARD_METHOD, DEVICE_VIBRATE_METHOD, DIRECTORY_CREATE_METHOD, DIRECTORY_EXISTS_METHOD, DIRECTORY_LIST_METHOD, DIRECTORY_REMOVE_METHOD, FILES_PICK_DIRECTORY_METHOD, FILES_PICK_FILES_METHOD, FILES_SAVE_FILE_METHOD, FILE_CREATE_METHOD, FILE_EXISTS_METHOD, FILE_READ_BYTES_METHOD, FILE_READ_TEXT_METHOD, FILE_REMOVE_METHOD, FILE_STAT_METHOD, FILE_WRITE_BYTES_METHOD, FILE_WRITE_TEXT_METHOD, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MINI_PROGRAM_OPERATION_PROGRESS_METHOD, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_DOWNLOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_COPY_LINK_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_INFO_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, USER_INFO_AUTHORIZATION_SCOPES, USER_REVOKE_AUTHORIZATION_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, isMiniProgramByteArray, isMiniProgramDirectoryDescriptor, isMiniProgramDirectoryRef, isMiniProgramDownloadProgressPayload, isMiniProgramFileDescriptor, isMiniProgramFileRef, isMiniProgramFileStat, isMiniProgramFileSystemEntityDescriptor, isMiniProgramPathRootRef, isMiniProgramRelativePath, parseMiniProgramRuntimePermissions };
@@ -1,5 +1,7 @@
1
1
  # <%= projectName %>
2
2
 
3
+ `vite.config.ts` 中的 `miniappManifest({ platforms })` 声明本项目承诺适配的平台。模板预填的 `android`、`ios`、`ohos` 只是初始配置;发布前请按实际目标调整,并在每个声明的平台完成真机验收。
4
+
3
5
  这是通过 `hb-sdk create` 生成的小黑盒工坊小程序模板。项目使用 Vue 3、Vite、TypeScript 和 `@heybox/hb-sdk`。
4
6
 
5
7
  ## 使用命令
@@ -4,5 +4,5 @@ import { defineConfig } from 'vite';
4
4
 
5
5
  export default defineConfig({
6
6
  base: './',
7
- plugins: [vue(), miniappManifest()],
7
+ plugins: [vue(), miniappManifest({ platforms: ['android', 'ios', 'ohos'] })],
8
8
  });
package/dist/vite.cjs.js CHANGED
@@ -8,7 +8,7 @@ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentS
8
8
  /** 构建时替换为当前发布包的实际版本。 */
9
9
  const HB_SDK_VERSION = typeof undefined === 'string'
10
10
  ? undefined
11
- : '0.7.5-alpha.0';
11
+ : '0.8.0-alpha.2';
12
12
 
13
13
  var re = {exports: {}};
14
14
 
@@ -2795,6 +2795,7 @@ function requireSemver () {
2795
2795
 
2796
2796
  var semverExports = requireSemver();
2797
2797
 
2798
+ const MINIAPP_PLATFORM_VALUES = ['android', 'ios', 'ohos', 'windows', 'macos', 'linux'];
2798
2799
  function validateMiniappPackageVersionForBuild(version) {
2799
2800
  return validateMiniappManifestVersion(version, 'package.json.version');
2800
2801
  }
@@ -2806,7 +2807,25 @@ function validateMiniappManifestVersion(version, sourceLabel = 'manifest.version
2806
2807
  return String(version).trim();
2807
2808
  }
2808
2809
  function renderMiniappManifest(manifest) {
2809
- return `${JSON.stringify({ version: manifest.version, sdkVersion: manifest.sdkVersion }, null, 2)}\n`;
2810
+ const platforms = validateMiniappPlatforms(manifest.platforms, 'manifest.platforms');
2811
+ return `${JSON.stringify({ version: manifest.version, sdkVersion: manifest.sdkVersion, platforms }, null, 2)}\n`;
2812
+ }
2813
+ function validateMiniappPlatforms(platforms, sourceLabel = 'platforms') {
2814
+ if (!Array.isArray(platforms) || platforms.length === 0) {
2815
+ throw new Error(`${sourceLabel} 必须是非空平台数组`);
2816
+ }
2817
+ const allowedPlatforms = new Set(MINIAPP_PLATFORM_VALUES);
2818
+ const seen = new Set();
2819
+ for (const platform of platforms) {
2820
+ if (typeof platform !== 'string' || !allowedPlatforms.has(platform)) {
2821
+ throw new Error(`${sourceLabel} 包含不支持的平台:${String(platform)}`);
2822
+ }
2823
+ if (seen.has(platform)) {
2824
+ throw new Error(`${sourceLabel} 包含重复平台:${platform}`);
2825
+ }
2826
+ seen.add(platform);
2827
+ }
2828
+ return Object.freeze(MINIAPP_PLATFORM_VALUES.filter((platform) => seen.has(platform)));
2810
2829
  }
2811
2830
  function getMiniappManifestVersionError(version) {
2812
2831
  if (typeof version !== 'string' || version.trim() === '') {
@@ -11629,7 +11648,8 @@ function shouldSkipMiniappPlatformCspFromEnv(env = process.env) {
11629
11648
 
11630
11649
  const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
11631
11650
  const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
11632
- function miniappManifest() {
11651
+ function miniappManifest(options) {
11652
+ const platforms = validateMiniappPlatforms(options?.platforms, 'miniappManifest().platforms');
11633
11653
  const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
11634
11654
  let root = process.cwd();
11635
11655
  let outDir = 'dist';
@@ -11649,6 +11669,12 @@ function miniappManifest() {
11649
11669
  };
11650
11670
  },
11651
11671
  configResolved(resolved) {
11672
+ if (resolved.plugins) {
11673
+ const manifestPluginCount = resolved.plugins.filter((plugin) => plugin.name === 'heybox-miniapp-manifest').length;
11674
+ if (manifestPluginCount !== 1) {
11675
+ throw new Error(`Vite 配置必须且只能包含一个 miniappManifest() 插件,当前数量:${manifestPluginCount}`);
11676
+ }
11677
+ }
11652
11678
  root = resolved.root;
11653
11679
  outDir = resolved.build.outDir;
11654
11680
  command = resolved.command;
@@ -11688,7 +11714,7 @@ function miniappManifest() {
11688
11714
  node_fs.writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(node_fs.readFileSync(indexHtmlPath, 'utf8'), { skipPlatformCsp }));
11689
11715
  const manifestPath = path.join(outputRoot, 'manifest.json');
11690
11716
  node_fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
11691
- node_fs.writeFileSync(manifestPath, renderMiniappManifest({ version, sdkVersion }));
11717
+ node_fs.writeFileSync(manifestPath, renderMiniappManifest({ version, sdkVersion, platforms }));
11692
11718
  },
11693
11719
  };
11694
11720
  }
@@ -11734,4 +11760,5 @@ function resolveHmrWebSocketUrl(resolved) {
11734
11760
  return `${protocol}://${host}${port ? `:${port}` : ''}`;
11735
11761
  }
11736
11762
 
11763
+ exports.MINIAPP_PLATFORM_VALUES = MINIAPP_PLATFORM_VALUES;
11737
11764
  exports.miniappManifest = miniappManifest;
package/dist/vite.esm.js CHANGED
@@ -5,7 +5,7 @@ import { AsyncLocalStorage } from 'node:async_hooks';
5
5
  /** 构建时替换为当前发布包的实际版本。 */
6
6
  const HB_SDK_VERSION = typeof undefined === 'string'
7
7
  ? undefined
8
- : '0.7.5-alpha.0';
8
+ : '0.8.0-alpha.2';
9
9
 
10
10
  var re = {exports: {}};
11
11
 
@@ -2792,6 +2792,7 @@ function requireSemver () {
2792
2792
 
2793
2793
  var semverExports = requireSemver();
2794
2794
 
2795
+ const MINIAPP_PLATFORM_VALUES = ['android', 'ios', 'ohos', 'windows', 'macos', 'linux'];
2795
2796
  function validateMiniappPackageVersionForBuild(version) {
2796
2797
  return validateMiniappManifestVersion(version, 'package.json.version');
2797
2798
  }
@@ -2803,7 +2804,25 @@ function validateMiniappManifestVersion(version, sourceLabel = 'manifest.version
2803
2804
  return String(version).trim();
2804
2805
  }
2805
2806
  function renderMiniappManifest(manifest) {
2806
- return `${JSON.stringify({ version: manifest.version, sdkVersion: manifest.sdkVersion }, null, 2)}\n`;
2807
+ const platforms = validateMiniappPlatforms(manifest.platforms, 'manifest.platforms');
2808
+ return `${JSON.stringify({ version: manifest.version, sdkVersion: manifest.sdkVersion, platforms }, null, 2)}\n`;
2809
+ }
2810
+ function validateMiniappPlatforms(platforms, sourceLabel = 'platforms') {
2811
+ if (!Array.isArray(platforms) || platforms.length === 0) {
2812
+ throw new Error(`${sourceLabel} 必须是非空平台数组`);
2813
+ }
2814
+ const allowedPlatforms = new Set(MINIAPP_PLATFORM_VALUES);
2815
+ const seen = new Set();
2816
+ for (const platform of platforms) {
2817
+ if (typeof platform !== 'string' || !allowedPlatforms.has(platform)) {
2818
+ throw new Error(`${sourceLabel} 包含不支持的平台:${String(platform)}`);
2819
+ }
2820
+ if (seen.has(platform)) {
2821
+ throw new Error(`${sourceLabel} 包含重复平台:${platform}`);
2822
+ }
2823
+ seen.add(platform);
2824
+ }
2825
+ return Object.freeze(MINIAPP_PLATFORM_VALUES.filter((platform) => seen.has(platform)));
2807
2826
  }
2808
2827
  function getMiniappManifestVersionError(version) {
2809
2828
  if (typeof version !== 'string' || version.trim() === '') {
@@ -11626,7 +11645,8 @@ function shouldSkipMiniappPlatformCspFromEnv(env = process.env) {
11626
11645
 
11627
11646
  const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
11628
11647
  const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
11629
- function miniappManifest() {
11648
+ function miniappManifest(options) {
11649
+ const platforms = validateMiniappPlatforms(options?.platforms, 'miniappManifest().platforms');
11630
11650
  const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
11631
11651
  let root = process.cwd();
11632
11652
  let outDir = 'dist';
@@ -11646,6 +11666,12 @@ function miniappManifest() {
11646
11666
  };
11647
11667
  },
11648
11668
  configResolved(resolved) {
11669
+ if (resolved.plugins) {
11670
+ const manifestPluginCount = resolved.plugins.filter((plugin) => plugin.name === 'heybox-miniapp-manifest').length;
11671
+ if (manifestPluginCount !== 1) {
11672
+ throw new Error(`Vite 配置必须且只能包含一个 miniappManifest() 插件,当前数量:${manifestPluginCount}`);
11673
+ }
11674
+ }
11649
11675
  root = resolved.root;
11650
11676
  outDir = resolved.build.outDir;
11651
11677
  command = resolved.command;
@@ -11685,7 +11711,7 @@ function miniappManifest() {
11685
11711
  writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(readFileSync(indexHtmlPath, 'utf8'), { skipPlatformCsp }));
11686
11712
  const manifestPath = path.join(outputRoot, 'manifest.json');
11687
11713
  mkdirSync(path.dirname(manifestPath), { recursive: true });
11688
- writeFileSync(manifestPath, renderMiniappManifest({ version, sdkVersion }));
11714
+ writeFileSync(manifestPath, renderMiniappManifest({ version, sdkVersion, platforms }));
11689
11715
  },
11690
11716
  };
11691
11717
  }
@@ -11731,4 +11757,4 @@ function resolveHmrWebSocketUrl(resolved) {
11731
11757
  return `${protocol}://${host}${port ? `:${port}` : ''}`;
11732
11758
  }
11733
11759
 
11734
- export { miniappManifest };
11760
+ export { MINIAPP_PLATFORM_VALUES, miniappManifest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk",
3
- "version": "0.7.5-alpha.0",
3
+ "version": "0.8.0-alpha.2",
4
4
  "sideEffects": [
5
5
  "./src/index.ts",
6
6
  "./src/core/singleton.ts",
@@ -44,6 +44,7 @@
44
44
  "files": [
45
45
  "README.md",
46
46
  "CHANGELOG.md",
47
+ "THIRD_PARTY_NOTICES.md",
47
48
  "bin",
48
49
  "dist",
49
50
  "skill",
@@ -57,7 +58,7 @@
57
58
  "parse5": "^7.3.0",
58
59
  "undici": "^7.28.0",
59
60
  "ws": "^8.18.0",
60
- "@heybox/hb-sdk-protocol": "0.7.5-alpha.0"
61
+ "@heybox/hb-sdk-protocol": "0.8.0-alpha.2"
61
62
  },
62
63
  "peerDependencies": {
63
64
  "vite": ">=5"
@@ -73,7 +74,8 @@
73
74
  "@rollup/plugin-node-resolve": "^16.0.1",
74
75
  "@heybox/hb-types": "^1.0.1",
75
76
  "@playwright/test": "^1.55.1",
76
- "@vitejs/plugin-vue2": "^2.3.3",
77
+ "@sneas/telephone": "1.1.2",
78
+ "@vitejs/plugin-vue": "^6.0.1",
77
79
  "@rollup/plugin-typescript": "^11.1.6",
78
80
  "@types/ejs": "^3.1.5",
79
81
  "@types/fs-extra": "^11.0.4",
@@ -82,6 +84,7 @@
82
84
  "@types/semver": "^7.7.1",
83
85
  "@types/ws": "^8.5.13",
84
86
  "@vitest/coverage-v8": "^3.2.4",
87
+ "@vue/test-utils": "^2",
85
88
  "commander": "^12.1.0",
86
89
  "cos-nodejs-sdk-v5": "2.15.4",
87
90
  "ejs": "^3.1.10",
@@ -89,22 +92,29 @@
89
92
  "fs-extra": "^11.3.0",
90
93
  "get-port": "^7.1.0",
91
94
  "happy-dom": "^19.0.2",
95
+ "lucide-vue-next": "1.0.0",
92
96
  "open": "^10.2.0",
93
97
  "ora": "^5.4.1",
94
98
  "picocolors": "^1.1.1",
95
99
  "qrcode": "^1.5.4",
96
100
  "rimraf": "^5.0.5",
101
+ "reka-ui": "2.10.4",
97
102
  "rollup": "^4.52.4",
98
103
  "semver": "^7.8.0",
104
+ "sass-embedded": "1.97.3",
105
+ "splitpanes": "^4.1.0",
99
106
  "typescript": "^5.9.3",
100
- "vue": "^2.7.16",
107
+ "vue": "^3.5.22",
108
+ "vue-tsc": "^3.3.7",
101
109
  "vite": "^8.0.12",
102
110
  "vitest": "^3.2.4",
103
- "@heybox/hb-api": "~1.25.22",
104
- "@heybox/runtime": "~0.2.0",
111
+ "@heybox-domain/heybox-vue3-ui": "~0.1.0",
112
+ "@heybox/runtime-policy": "~0.2.0",
113
+ "@heybox-domain/heybox-theme": "~0.1.0",
105
114
  "@heybox/runtime-transport-fetch": "~0.2.0",
106
- "@heybox/hb-sdk-runtime": "~0.7.5-alpha.0",
107
- "@heybox/runtime-policy": "~0.2.0"
115
+ "@heybox/hb-api": "~1.25.23",
116
+ "@heybox/runtime": "~0.2.0",
117
+ "@heybox/hb-sdk-runtime": "~0.8.0-alpha.2"
108
118
  },
109
119
  "publishConfig": {
110
120
  "registry": "https://registry.npmjs.org/",
@@ -117,6 +127,10 @@
117
127
  "{projectRoot}/src/**/*",
118
128
  "{projectRoot}/devtools/browser-dev-host/**/*",
119
129
  "{projectRoot}/scripts/copy-browser-dev-host.cjs",
130
+ "{projectRoot}/scripts/check-browser-dev-host-assets.cjs",
131
+ "{projectRoot}/scripts/generate-browser-dev-host-notices.cjs",
132
+ "{projectRoot}/licenses/**/*",
133
+ "{projectRoot}/THIRD_PARTY_NOTICES.md",
120
134
  "{projectRoot}/rollup.config.ts",
121
135
  "{projectRoot}/tsconfig*.json",
122
136
  "{workspaceRoot}/packages/hb-sdk-runtime/src/**/*",
@@ -144,15 +158,17 @@
144
158
  "build:lib:bundle": "rollup -c rollup.config.ts --configPlugin 'typescript={\"tsconfig\":\"tsconfig.build.json\"}'",
145
159
  "build:cli": "pnpm run build:hb-sdk-protocol && pnpm run build:hb-api-contract && pnpm run build:cli:bundle",
146
160
  "build:cli:bundle": "rollup -c rollup.config.ts --environment HB_SDK_BUILD:cli --configPlugin 'typescript={\"tsconfig\":\"tsconfig.build.json\"}' && pnpm run build:browser-dev-host",
147
- "build:browser-dev-host": "node scripts/copy-browser-dev-host.cjs",
161
+ "build:browser-dev-host": "vite build --config vite.browser-dev-host.config.ts && node scripts/check-browser-dev-host-assets.cjs && node scripts/generate-browser-dev-host-notices.cjs",
148
162
  "build:templates": "node scripts/copy-cli-templates.cjs",
149
163
  "build:types": "tsc -p tsconfig.dts.json",
150
164
  "check:boundary": "node scripts/check-boundary.cjs",
151
165
  "check:docs-sync": "pnpm -w exec hbexec hb-sdk check",
166
+ "check:compatibility-evidence": "node scripts/validate-compatibility-evidence.mjs",
167
+ "check:api-semver": "node ../../ops/jobs/hb-sdk-docs-contract/semantic-diff.cjs",
152
168
  "clean": "rimraf ./dist && rimraf ./types",
153
169
  "test:unit": "NODE_OPTIONS='--conditions=heybox' vitest run",
154
170
  "test:types:characterization": "tsc -p tsconfig.characterization.json --noEmit --pretty false",
155
- "test:types:browser-dev-host": "tsc -p tsconfig.browser-dev-host.json --noEmit --pretty false",
171
+ "test:types:browser-dev-host": "vue-tsc -p tsconfig.browser-dev-host.json --noEmit --pretty false",
156
172
  "test:types": "pnpm run test:types:characterization && pnpm run test:types:browser-dev-host",
157
173
  "test:e2e:browser-dev-host": "pnpm run build:browser-dev-host && NODE_OPTIONS='--conditions=heybox' vitest run --config vitest.browser-dev-host-e2e.config.ts",
158
174
  "test:unit:coverage": "NODE_OPTIONS='--conditions=heybox' vitest run --coverage",
@@ -160,7 +176,8 @@
160
176
  "test:watch": "NODE_OPTIONS='--conditions=heybox' vitest",
161
177
  "changelog:draft": "node scripts/changelog-draft.cjs",
162
178
  "check:changelog": "node scripts/check-changelog.cjs",
163
- "test:release": "node --test scripts/release-family.test.cjs ../../ops/jobs/publish-changed-packages/publish.test.cjs",
179
+ "test:release": "node --test scripts/release-family.test.cjs ../../ops/jobs/publish-changed-packages/publish.test.cjs ../../ops/jobs/release-hb-sdk/docs-release-contract.test.cjs",
180
+ "test:compatibility-evidence": "node --test scripts/validate-compatibility-evidence.test.mjs",
164
181
  "release:prepare": "node scripts/release-prepare.cjs",
165
182
  "release:tag": "node scripts/release-tag.cjs",
166
183
  "release:family:dry-run": "node ../../ops/jobs/publish-changed-packages/publish.cjs --dry-run",
package/skill/SKILL.md CHANGED
@@ -51,17 +51,19 @@ Apply these instructions when writing, reviewing, or debugging code that consume
51
51
  11. `user.getSteamGameList()` is available only to network-disabled mini-programs. In a network-enabled mini-program it returns `SERVER_API_REQUIRED`, and there is no Steam library authorization scope or OpenAPI resource. Treat `user.getInfo()` returning `SERVER_API_REQUIRED` as a server-boundary signal, not as logged-out state.
52
52
  12. Use `share.showShareMenu({ post })` or `share.screenshot({ post })` to preset editable community destinations and topics. Pass partition IDs through `topicIds` and topic text without surrounding `#` through `topics`; do not construct the underlying client post protocol.
53
53
  13. Use `share.showShareMenu({ extra })` to open the share menu or `share.copyLink({ extra })` to copy and return the default mini-program share link. Read the JSON-compatible page state synchronously with `share.getExtra()` after launch, validate the developer-defined fields, and fall back to the default page when it returns `undefined`.
54
+ 14. Treat `files` and `network.download()` as a retained public contract that is not yet enabled by a current Host. The legacy PC adapter was dropped because the new PC will implement the Host ports directly. Until then, legacy PC, Mobile, Web, and Browser Dev Host return `METHOD_FORBIDDEN` and provide no memory/Blob fallback. Once a supporting Host is available, call `files.pickFiles()` / `pickDirectory()` / `saveFile()` only from trusted user actions; `saveFile()` accepts only `suggestedName`, `remove()` only deletes sandbox objects, and non-empty directories require `remove({ recursive: true })`.
55
+ 15. Use `network.download()` only with an SDK-created File/Directory target. It is GET-only, does not follow redirects, and exposes local `AbortSignal` / progress callbacks without sending functions over the bridge. Abort is a cancellation intent; a Host commit that already won still resolves successfully.
54
56
 
55
57
  ## Step 5: Use CLI workflows
56
58
 
57
59
  1. Use `hb-sdk create <project-name>` to scaffold a workshop mini-program.
58
- 2. Use `hb-sdk dev` for Browser Mock, Mac App, or Mobile App debugging. It requires an active CLI login, a bound Mini-program, and an available remote Dev Context; it must stop before starting Vite or any debugging service when a prerequisite is missing. Mobile uses the `open_inapp` and `heybox://` `openWindow` wrapper with a LAN short URL, then opens `heybox-mini-dev://sandbox` with the complete launch context.
59
- 3. Treat debugging-page permission overrides as local development behavior; overrides do not change remote permissions. Use `--port`, `--browser-dev-host-port`, and `--no-open` to control local endpoints and browser opening. Select a Mobile network interface the device can reach. `launch.json` is a LAN discovery document, not authentication, encryption, signing, or HMAC protection.
60
+ 2. Use `hb-sdk dev` for Browser Mock and Mobile App debugging. Browser debugging can start without CLI login, project binding, or a remote Dev Context; capabilities that need those inputs fail explicitly. Mobile uses the single QR entry with the `open_inapp` and `heybox://` `openWindow` wrapper around a LAN short URL, then opens `heybox-mini-dev://sandbox` with the complete launch context.
61
+ 3. The debugging page does not edit permissions. Treat the validated remote permission snapshot as canonical Runtime input. Use `--port`, `--browser-dev-host-port`, and `--no-open` to control local endpoints and browser opening. Select a Mobile network interface the device can reach. `launch.json` is a LAN discovery document, not authentication, encryption, signing, or HMAC protection.
60
62
  4. Use `hb-sdk build [--env <name>] [--verbose]` as the recommended production build entry. It directly owns the Vite build, always cleans and writes `dist/`, and works without CLI login, project binding, or network access.
61
63
  5. Keep `miniappManifest()` explicitly enabled in `vite.config.ts`; `hb-sdk build` must fail when the required Manifest or Runtime gate output is missing.
62
64
  6. Keep project typechecking in `scripts.build`, for example `vue-tsc --noEmit && hb-sdk build`; `hb-sdk build` does not run typechecking or invoke `scripts.build` itself.
63
65
  7. Existing projects may continue to use `vite build`; do not auto-migrate them. Do not invent `--mode`, `--json`, config, or output-directory flags for `hb-sdk build`.
64
- 8. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` for development, publishing, and Browser Mock Host `heybox-session` requests. Mini-program code must still call `auth.login()`; the debug page only confirms authorization. Do not paste CLI credentials into page JavaScript. Phone debugging continues to use the App login.
66
+ 8. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` for remote management, publishing, Mobile debugging, and optional Browser Mock Host `heybox-session` requests. Browser debugging itself can start without CLI login. Mini-program code must still call `auth.login()`; the debug page only confirms authorization. Do not paste CLI credentials into page JavaScript. Phone debugging continues to use the App login.
65
67
  9. Use `hb-sdk remote entity current` to confirm the current developer account and `hb-sdk remote entity switch <entity-id>` to change it before remote operations.
66
68
  10. Use `hb-sdk remote create` to create and bind a mini-program; use `hb-sdk remote bind <mini-program-id>` to bind an existing manageable mini-program.
67
69
  11. Use `hb-sdk remote info`, `hb-sdk remote list`, `hb-sdk remote access`, `hb-sdk remote versions`, `hb-sdk remote preview <version>`, and `hb-sdk remote allowlist ...` for remote inspection and preview management.
@@ -81,11 +83,12 @@ For workshop mini-program business code:
81
83
  1. Do not read or request tokens, cookies, phone numbers, or private credentials from the SDK.
82
84
  2. Do not expose raw share protocol fields, JS callbacks, activity reporting, custom buttons, direct post publishing, or upload-only flows. Public `share.*({ post })` options only preset an editable client post flow and never publish automatically.
83
85
  3. Do not use unsupported storage operations such as delete, clear, info listing, or global client storage access.
84
- 4. Use only the public `network.request` configuration.
86
+ 4. Use only the public `network.request` / `network.download` configurations.
85
87
  5. Do not use private package paths or client protocols.
86
88
  6. Build artifacts may include `dist/manifest.json`; business code should not fetch a deployed manifest directly because it is not a CDN asset.
87
89
  7. Do not use `network.request()` to reach platform-reserved runtime auth or OpenAPI internal paths.
88
90
  8. Do not expose credentials or describe internal Host authorization state machines and routes in app-facing guidance.
91
+ 9. Do not invent string paths, File System Access API handles, Blob downloads, uploads, Range/resume, external deletion, move, append, or persistent external grants. Public file operations use only SDK-created handles; deletion is limited to SDK sandbox handles.
89
92
 
90
93
  For CLI and local development:
91
94
 
@@ -93,8 +96,9 @@ For CLI and local development:
93
96
  2. Do not skip `auth.login()` in mini-program code. Browser Mock may reuse the Node `hb-sdk login` session for Host network requests, but the page must still call `auth.login()` and handle the authorization dialog. Never paste CLI credentials into page JavaScript.
94
97
  3. Use the built-in local debugging page instead of creating another browser Mock.
95
98
  4. Keep the Vite `miniappManifest()` plugin enabled.
96
- 5. Treat permission changes made in the `hb-sdk dev` debugging page as local debugging overrides, not online configuration changes. Use the page's reset action to return to the remote baseline.
99
+ 5. Do not suggest changing or resetting permissions in the `hb-sdk dev` debugging page; that UI does not exist. Diagnose permission behavior from the remote snapshot and capability result.
97
100
  6. Treat browser Mock results as development feedback only. Validate permissions, identity flows, and user interactions again in a real Heybox client before publishing.
101
+ 7. The Browser Dev Host offers iPhone 16 Pro Max (`440 x 956`) and Pixel 9 Pro (`410 x 914`) presets. Switching a preset must preserve the iframe, Runtime session, and page state. Authorization/action dialogs, Toast, Loading, and vibration feedback render inside the preview. Use the upper-right QR popover as the only Mobile QR entry.
98
102
 
99
103
  For host/runtime/protocol-maintenance code:
100
104