@heybox/hb-sdk 0.5.18 → 0.6.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 (48) hide show
  1. package/README.md +29 -25
  2. package/dist/cli-chunks/{create-OZOIdeBz.cjs → create-DYb53EQ-.cjs} +1 -1
  3. package/dist/cli-chunks/{dev-DXz8izSJ.cjs → dev-CPKTuA6q.cjs} +35 -6
  4. package/dist/cli-chunks/{doctor-DjMSJoQ5.cjs → doctor-TshFvqHC.cjs} +1 -1
  5. package/dist/cli-chunks/{index-CsOcGUzF.cjs → index-CCeHouBU.cjs} +21 -16
  6. package/dist/cli-chunks/{index-Cl5HFTBW.cjs → index-NOO3q8_C.cjs} +3 -3
  7. package/dist/cli-chunks/{login-Ct-46gLx.cjs → login-DtXHSm8R.cjs} +2 -2
  8. package/dist/cli-chunks/remote-BWfn7qIN.cjs +9915 -0
  9. package/dist/cli-chunks/{context-CKJlNcSN.cjs → sdk-version-policy-B1CFC1Dk.cjs} +122 -1
  10. package/dist/cli-chunks/{session-dRGPpyS1.cjs → session-DIcRjyDY.cjs} +2 -1
  11. package/dist/cli.cjs +1 -1
  12. package/dist/devtools/mock-host/index.html +40 -0
  13. package/dist/devtools/mock-host/main.js +85 -0
  14. package/dist/index.cjs.js +232 -4
  15. package/dist/index.esm.js +233 -3
  16. package/dist/miniapp-publish.cjs.js +4 -0
  17. package/dist/miniapp-publish.esm.js +4 -1
  18. package/dist/protocol.cjs.js +9 -0
  19. package/dist/protocol.esm.js +7 -1
  20. package/dist/vite.cjs.js +9159 -22
  21. package/dist/vite.esm.js +9159 -23
  22. package/package.json +19 -7
  23. package/skill/SKILL.md +23 -23
  24. package/skill/references/api-protocol.md +11 -2
  25. package/skill/references/api-root.md +145 -19
  26. package/skill/references/cli.md +13 -15
  27. package/skill/references/recipes.md +12 -44
  28. package/skill/references/safety-boundaries.md +1 -2
  29. package/skill/scripts/sync-references.mjs +2 -2
  30. package/skill/skill.json +4 -4
  31. package/types/cli/auth/base-url.d.ts +20 -0
  32. package/types/cli/config.d.ts +11 -0
  33. package/types/core/client.d.ts +7 -0
  34. package/types/core/csp-violation.d.ts +5 -0
  35. package/types/core/history-observer.d.ts +4 -0
  36. package/types/core/version.d.ts +2 -0
  37. package/types/index.d.ts +0 -2
  38. package/types/miniapp-manifest/schema.d.ts +6 -1
  39. package/types/miniapp-manifest/sdk-version-policy.d.ts +9 -0
  40. package/types/miniapp-publish/index.d.ts +1 -0
  41. package/types/protocol/constants.d.ts +6 -0
  42. package/types/protocol/types.d.ts +45 -0
  43. package/types/protocol.d.ts +2 -2
  44. package/types/vite/html-policy.d.ts +4 -0
  45. package/types/vite/index.d.ts +23 -3
  46. package/types/vite/runtime-gate.d.ts +5 -0
  47. package/types/vite/sdk-version-gate.d.ts +8 -0
  48. package/dist/cli-chunks/remote-C77axNSw.cjs +0 -1604
package/package.json CHANGED
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk",
3
- "version": "0.5.18",
3
+ "version": "0.6.0",
4
+ "sideEffects": [
5
+ "./src/index.ts",
6
+ "./src/core/singleton.ts",
7
+ "./dist/index.esm.js",
8
+ "./dist/index.cjs.js"
9
+ ],
4
10
  "description": "",
5
11
  "exports": {
6
12
  ".": {
@@ -44,7 +50,9 @@
44
50
  "keywords": [],
45
51
  "author": "",
46
52
  "license": "ISC",
47
- "dependencies": {},
53
+ "dependencies": {
54
+ "parse5": "^7.3.0"
55
+ },
48
56
  "peerDependencies": {
49
57
  "vite": ">=5"
50
58
  },
@@ -83,7 +91,8 @@
83
91
  "typescript": "^5.9.3",
84
92
  "vue": "^2.7.16",
85
93
  "vite": "^8.0.12",
86
- "vitest": "^3.2.4"
94
+ "vitest": "^3.2.4",
95
+ "@heybox/hb-api": "~1.25.0"
87
96
  },
88
97
  "publishConfig": {
89
98
  "registry": "https://registry.npmjs.org/",
@@ -108,10 +117,13 @@
108
117
  },
109
118
  "scripts": {
110
119
  "dev": "vite",
111
- "build:package": "nx exec -- sh -c \"pnpm run clean && pnpm run build:lib && pnpm run build:cli && pnpm run build:templates && pnpm run build:types\"",
120
+ "build:package": "nx exec -- sh -c \"pnpm run clean && pnpm run build:lib:bundle && pnpm run build:cli:bundle && pnpm run build:templates && pnpm run build:types\"",
112
121
  "build:watch": "pnpm run build:lib -w & pnpm run build:types -w",
113
- "build:lib": "rollup -c rollup.config.ts --configPlugin 'typescript={\"tsconfig\":\"tsconfig.build.json\"}'",
114
- "build:cli": "rollup -c rollup.config.ts --environment HB_SDK_BUILD:cli --configPlugin 'typescript={\"tsconfig\":\"tsconfig.build.json\"}' && pnpm run build:mock-host",
122
+ "build:hb-api-contract": "pnpm --dir ../hb-api run build:lib",
123
+ "build:lib": "pnpm run build:hb-api-contract && pnpm run build:lib:bundle",
124
+ "build:lib:bundle": "rollup -c rollup.config.ts --configPlugin 'typescript={\"tsconfig\":\"tsconfig.build.json\"}'",
125
+ "build:cli": "pnpm run build:hb-api-contract && pnpm run build:cli:bundle",
126
+ "build:cli:bundle": "rollup -c rollup.config.ts --environment HB_SDK_BUILD:cli --configPlugin 'typescript={\"tsconfig\":\"tsconfig.build.json\"}' && pnpm run build:mock-host",
115
127
  "build:mock-host": "node scripts/copy-mock-host.cjs",
116
128
  "build:templates": "node scripts/copy-cli-templates.cjs",
117
129
  "build:types": "tsc -p tsconfig.dts.json",
@@ -120,7 +132,7 @@
120
132
  "clean": "rimraf ./dist && rimraf ./types",
121
133
  "test:unit": "NODE_OPTIONS='--conditions=heybox' vitest run",
122
134
  "test:unit:coverage": "NODE_OPTIONS='--conditions=heybox' vitest run --coverage",
123
- "test:vite": "vitest run --config vitest.vite.config.ts",
135
+ "test:vite": "pnpm run build:hb-api-contract && vitest run --config vitest.vite.config.ts",
124
136
  "test:watch": "NODE_OPTIONS='--conditions=heybox' vitest",
125
137
  "changelog:draft": "node scripts/changelog-draft.cjs",
126
138
  "check:changelog": "node scripts/check-changelog.cjs",
package/skill/SKILL.md CHANGED
@@ -44,7 +44,7 @@ Apply these instructions when writing, reviewing, or debugging code that consume
44
44
  4. Handle `HbMiniProgramSDKError` for bridge/runtime/protocol failures.
45
45
  5. Handle `HbMiniProgramNetworkError` separately when HTTP completed but `validateStatus` rejected the status.
46
46
  6. Cancel lifecycle/event subscriptions returned by `on()` when the page or component unmounts.
47
- 7. Call `destroy()` on independent instances created by `createMiniProgramSDK()` when they are no longer needed.
47
+ 7. Import the root package eagerly; version 0.6 exposes only the unique default SDK instance and starts its handshake as a required import side effect.
48
48
 
49
49
  ## Step 5: Use CLI workflows
50
50
 
@@ -54,28 +54,27 @@ Apply these instructions when writing, reviewing, or debugging code that consume
54
54
  4. Use `hb-sdk remote entity list`, `hb-sdk remote entity current`, and `hb-sdk remote entity switch <entity-id>` to inspect or change the developer platform server-side current entity before remote management commands.
55
55
  5. Use `hb-sdk remote create` to create a remote mini-program under the server-side current entity and bind the returned id into `package.json.heybox.miniProgramId`; use `hb-sdk remote bind <mini-program-id>` to bind an existing remote mini-program after current-entity manageability is verified. Mini-program name, icon, and cover images belong in `package.json.heybox.miniProgramProfile` and are submitted with version audit.
56
56
  6. 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 read/basic/preview management workflows. Mini-program name and image changes must go through version audit, so the CLI must not expose a basic-info update command.
57
- 7. Use `hb-sdk remote deploy --release-note <text>` to build, upload, and submit the current project for audit. It reads `package.json.heybox.miniProgramId`, validates that the bound mini-program belongs to the server-side current entity before precheck/build/upload, prechecks `package.json.version` before build, runs the project's `build` script via the package manager auto-detected by lockfile, uploads `dist/` to CDN (skipping `manifest.json`, `.DS_Store`, `.map`), then calls the submit-audit API. The deploy upload pipeline rejects actual upload artifacts over 100MiB before any upload request, processes CDN upload metadata and callback confirmation at 50 files per batch, keeps 4-way upload concurrency within each batch, and validates CDN-returned keys exactly against the local expected upload keys.
58
- 8. Use `hb-sdk remote deploy --skip-build --release-note <text>` only when the `dist/` directory is already prepared by an upstream CI stage. In this mode the CLI reads `dist/manifest.json.version` before precheck. Missing `dist/manifest.json` or `dist/index.html` aborts the run.
59
- 9. Use `hb-sdk remote deploy --from-version <version> --release-note <text>` to reuse a previously uploaded remote version artifact and submit a new audit version without reading local `dist/`, building, or uploading. Do not combine `--from-version` with `--skip-build`.
60
- 10. Always provide a concise release note before deploy. Non-interactive environments must pass `--release-note`; interactive terminals may prompt for it. The default is manual release after approval with `hb-sdk remote release <version>`; use `--auto-publish` when the audited version should automatically release after approval.
61
- 11. Use `hb-sdk remote release <version>`, `hb-sdk remote withdraw <version>`, `hb-sdk remote take-down`, and `hb-sdk remote reopen` for dangerous remote changes. Interactive terminals should confirm after showing enough context; non-interactive environments must pass `--yes`.
62
- 12. For internal test/staging backend operations, use origin-only custom URLs: `HB_SDK_API_BASE_URL` or `hb-sdk remote ... --api-base-url <url>` for remote platform APIs, and `HB_SDK_LOGIN_BASE_URL` or `hb-sdk login --login-base-url <url>` for browser login. CLI flags override env vars. API base URLs must be Heybox trusted HTTPS origins by default; use `--allow-unsafe-api-base-url` or `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` only for local backend debugging. Do not include path, query, or hash in these URLs.
63
- 13. For development routing or gray validation, configure `packages/hb-sdk/src/cli/config.ts` with `@heybox/hb-types` `RylaiServiceTagConfig` (`default_tag` / path-specific `special_tag`) to attach `x-rylai-service-tag` and the matching `special_tag` query parameter to Heybox backend API requests.
64
- 14. If a remote command targets a custom login environment, pass the same `--login-base-url` or `HB_SDK_LOGIN_BASE_URL` used for `hb-sdk login`; remote commands reject cached CLI login state from a different login origin.
65
- 15. Add `--verbose` / `-v` only when diagnosing failures; default CLI errors are intentionally concise, while verbose output includes backend envelope, HTTP status, trace fields, raw body, or original submit-audit failure details.
66
- 16. Use `--json` for script consumption of `hb-sdk remote` commands. With `--json`, stdout must contain exactly one JSON object; progress, warnings, update reminders, and verbose diagnostics must not pollute stdout.
67
- 17. Do not expect custom base URLs to affect `hb-sdk doctor`, npm latest checks, or mock-host `network.request()`.
68
- 18. Use the Mock runtime host's "在 Mac APP 中启动" button for Mac App debugging, or the "Mobile App" QR code after selecting a LAN interface for phone App debugging; the phone must be on the same LAN and use a Heybox App version that supports the mini-program dev shell.
69
- 19. Use `--port`, `--mock-port`, and `--no-open` when the default Vite/mock ports or browser opening behavior need to be controlled.
70
- 20. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for the CLI's own Heybox auth cache. Keep `hb-sdk login` top-level; it is not a remote mini-program command.
71
- 21. Treat `selectedEntity` in the CLI auth cache as a non-authoritative hint snapshot only. Every remote command must use the server-side current entity as the source of truth.
72
- 22. Use `hb-sdk doctor` to diagnose whether the local `hb-sdk` skill matches the installed SDK and remote latest skill metadata.
73
- 23. 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`.
74
- 24. If doctor reports `SDK_MISMATCH`, upgrade `@heybox/hb-sdk@latest` before reinstalling the skill.
75
- 25. Do not treat CLI login cache as iframe SDK login state; it does not change `auth.login()`, `user.getInfo()`, `network.request()`, or mock-user behavior.
76
- 26. Keep the CLI and mock runtime under `@heybox/hb-sdk`; do not create or revive a separate mock runtime package.
77
- 27. Do not pass `mini_program_id` or `entity_id` as general CLI flags or environment variables; the mini-program id must come from `package.json.heybox.miniProgramId`, and the entity must come from the server-side current entity.
78
- 28. Do not import deploy / upload internals from outside the CLI; the only externally consumable subpath for publish-pipeline helpers is `@heybox/hb-sdk/miniapp-publish`.
57
+ 7. Use `hb-sdk remote deploy --release-note <text>` to build, upload, and submit the current project for audit. It reads `package.json.heybox.miniProgramId`, validates that the bound mini-program belongs to the server-side current entity before precheck/build/upload, prechecks `package.json.version` before build, runs the project's `build` script via the package manager auto-detected by lockfile, uploads `dist/` to CDN (skipping `manifest.json`, `.DS_Store`, `.map`), then calls the submit-audit API. When `--env <name>` or `HB_SDK_ENV=<name>` selects an environment preset, deploy also passes the same name to the project build as its Vite mode. The deploy upload pipeline rejects actual upload artifacts over 100MiB before any upload request, processes CDN upload metadata and callback confirmation at 50 files per batch, keeps 4-way upload concurrency within each batch, and validates CDN-returned keys exactly against the local expected upload keys.
58
+ 8. Use `hb-sdk remote deploy --from-version <version> --release-note <text>` to reuse a previously uploaded remote version artifact and submit a new audit version without reading local `dist`, building, or uploading.
59
+ 9. Always provide a concise release note before deploy. Non-interactive environments must pass `--release-note`; interactive terminals may prompt for it. The default is manual release after approval with `hb-sdk remote release <version>`; use `--auto-publish` when the audited version should automatically release after approval.
60
+ 10. Use `hb-sdk remote release <version>`, `hb-sdk remote withdraw <version>`, `hb-sdk remote take-down`, and `hb-sdk remote reopen` for dangerous remote changes. Interactive terminals should confirm after showing enough context; non-interactive environments must pass `--yes`.
61
+ 11. For internal test/staging backend operations, use origin-only custom URLs: `HB_SDK_API_BASE_URL` or `hb-sdk remote ... --api-base-url <url>` for remote platform APIs, and `HB_SDK_LOGIN_BASE_URL` or `hb-sdk login --login-base-url <url>` for browser login. CLI flags override env vars. API base URLs must be Heybox trusted HTTPS origins by default; use `--allow-unsafe-api-base-url` or `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` only for local backend debugging. Do not include path, query, or hash in these URLs.
62
+ 12. For development routing or gray validation, use `HB_SDK_SERVICE_TAG` to attach `x-rylai-service-tag` and the matching `special_tag` query parameter to CLI backend requests and the Vite minimum-SDK-version gate. Repository-local path-specific routing can still be configured in `packages/hb-sdk/src/cli/config.ts` with `@heybox/hb-types` `RylaiServiceTagConfig` (`default_tag` / path-specific `special_tag`).
63
+ 13. If a remote command targets a custom login environment, pass the same `--login-base-url` or `HB_SDK_LOGIN_BASE_URL` used for `hb-sdk login`; remote commands reject cached CLI login state from a different login origin.
64
+ 14. Add `--verbose` / `-v` only when diagnosing failures; default CLI errors are intentionally concise, while verbose output includes backend envelope, HTTP status, trace fields, raw body, or original submit-audit failure details.
65
+ 15. Use `--json` for script consumption of `hb-sdk remote` commands. With `--json`, stdout must contain exactly one JSON object; progress, warnings, update reminders, and verbose diagnostics must not pollute stdout.
66
+ 16. Do not expect custom base URLs to affect `hb-sdk doctor`, npm latest checks, or mock-host `network.request()`.
67
+ 17. Use the Mock runtime host's "在 Mac APP 中启动" button for Mac App debugging, or the "Mobile App" QR code after selecting a LAN interface for phone App debugging; the phone must be on the same LAN and use a Heybox App version that supports the mini-program dev shell.
68
+ 18. Use `--port`, `--mock-port`, and `--no-open` when the default Vite/mock ports or browser opening behavior need to be controlled.
69
+ 19. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for the CLI's own Heybox auth cache. Keep `hb-sdk login` top-level; it is not a remote mini-program command.
70
+ 20. Treat `selectedEntity` in the CLI auth cache as a non-authoritative hint snapshot only. Every remote command must use the server-side current entity as the source of truth.
71
+ 21. Use `hb-sdk doctor` to diagnose whether the local `hb-sdk` skill matches the installed SDK and remote latest skill metadata.
72
+ 22. 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`.
73
+ 23. If doctor reports `SDK_MISMATCH`, upgrade `@heybox/hb-sdk@latest` before reinstalling the skill.
74
+ 24. Do not treat CLI login cache as iframe SDK login state; it does not change `auth.login()`, `user.getInfo()`, `network.request()`, or mock-user behavior.
75
+ 25. Keep the CLI and mock runtime under `@heybox/hb-sdk`; do not create or revive a separate mock runtime package.
76
+ 26. Do not pass `mini_program_id` or `entity_id` as general CLI flags or environment variables; the mini-program id must come from `package.json.heybox.miniProgramId`, and the entity must come from the server-side current entity.
77
+ 27. Do not import deploy / upload internals from outside the CLI; the only externally consumable subpath for publish-pipeline helpers is `@heybox/hb-sdk/miniapp-publish`.
79
78
 
80
79
  ## Step 6: Preserve capability boundaries
81
80
 
@@ -93,6 +92,7 @@ For CLI and local development:
93
92
  1. Do not print, persist in templates, or pass through pkey, cookies, tokens, or private credentials.
94
93
  2. Do not use `hb-sdk login` as a workaround for iframe SDK authentication.
95
94
  3. Do not bypass `hb-sdk dev` by adding a second browser mock host.
95
+ 4. Keep the Vite `miniappManifest()` plugin enabled so builds only start in a compatible APP Runtime. Normal deploy always runs the project build.
96
96
 
97
97
  For host/runtime/protocol-maintenance code:
98
98
 
@@ -25,7 +25,10 @@ export {
25
25
  MINI_PROGRAM_BRIDGE_NONCE_PARAM,
26
26
  MINI_PROGRAM_MESSAGE_NAMESPACE,
27
27
  MINI_PROGRAM_MESSAGE_VERSION,
28
+ RUNTIME_LOCATION_PROBE_METHOD,
29
+ SDK_CSP_VIOLATION_METHOD,
28
30
  SDK_HANDSHAKE_METHOD,
31
+ SDK_LOCATION_REPORT_METHOD,
29
32
  } from './protocol/constants';
30
33
  export { isMiniProgramBridgeMessage } from './protocol/guards';
31
34
  export type {
@@ -35,6 +38,12 @@ export type {
35
38
  MiniProgramEventHandler,
36
39
  MiniProgramEventName,
37
40
  MiniProgramEventPayloadMap,
41
+ RuntimeLocationProbePayload,
42
+ SDKCSPBlockedResourceType,
43
+ SDKCSPViolationPayload,
44
+ SDKHandshakePayload,
45
+ SDKLocationReportPayload,
46
+ SDKLocationReportTrigger,
38
47
  } from './protocol/types';
39
48
  export {
40
49
  AUTH_LOGIN_METHOD,
@@ -214,5 +223,5 @@ Reference 由 `@heybox/hb-sdk` 的公开导出与源码注释自动生成,不
214
223
 
215
224
  | 导出面 | Classes | Functions | Interfaces | Types | Constants |
216
225
  | --- | ---: | ---: | ---: | ---: | ---: |
217
- | Root API | 3 | 4 | 67 | 57 | 4 |
218
- | Protocol API | 0 | 1 | 39 | 66 | 32 |
226
+ | Root API | 2 | 3 | 66 | 57 | 4 |
227
+ | Protocol API | 0 | 1 | 43 | 68 | 35 |
@@ -19,7 +19,7 @@
19
19
  ## Package metadata
20
20
 
21
21
  - Package: `@heybox/hb-sdk`
22
- - Version at generation time: `0.5.17`
22
+ - Version at generation time: `0.6.0`
23
23
  - Public root export: `@heybox/hb-sdk`
24
24
  - Protocol export: `@heybox/hb-sdk/protocol`
25
25
  - Vite plugin export: `@heybox/hb-sdk/vite`
@@ -27,9 +27,7 @@
27
27
  ## Public root entrypoint
28
28
 
29
29
  ```ts
30
- export { createMiniProgramSDK, MiniProgramSDK } from './core/sdk';
31
30
  export { HbMiniProgramSDKError, HbMiniProgramNetworkError } from './core/errors';
32
- export type { MiniProgramSDKOptions } from './core/client';
33
31
  export { ready, on, off, auth, user, share, viewport, storage, network, ui, device, navigation, cloud } from './core/singleton';
34
32
  export type {
35
33
  MiniProgramEventHandler,
@@ -199,24 +197,37 @@ export default hbSDK;
199
197
  Use `@heybox/hb-sdk/vite` only in `vite.config.ts`. Do not import it from iframe mini-program business code.
200
198
 
201
199
  ```ts
202
- import { mkdirSync, writeFileSync } from 'node:fs';
200
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
203
201
  import path from 'node:path';
202
+ import { HB_SDK_VERSION } from '../core/version';
204
203
  import {
205
204
  renderMiniappManifest,
206
205
  validateMiniappPackageVersionForBuild,
207
206
  } from '../miniapp-manifest/schema';
208
207
  import { readMiniappVersionFromPackageJson } from '../miniapp-manifest/node';
208
+ import { enforceMiniappHtmlPolicy } from './html-policy';
209
+ import { enforceViteSdkVersion as defaultEnforceRemoteSdkVersion } from './sdk-version-gate';
210
+ import { resolveHeyboxApiBaseUrl } from '../cli/auth/base-url';
209
211
 
210
212
  type MiniappManifestPlugin = {
211
213
  name: string;
212
- apply: 'build';
213
214
  config: (config: MiniappManifestUserConfig) => MiniappManifestUserConfig | void;
214
215
  configResolved: (resolved: MiniappManifestResolvedConfig) => void;
215
- writeBundle: (this: MiniappManifestPluginContext) => void;
216
+ buildStart: () => Promise<void>;
217
+ /** Rollup 在构建失败后仍会跑 closeBundle;用 buildEnd 记录真实错误,避免二次校验掩盖原因。 */
218
+ buildEnd: (error?: Error) => void;
219
+ transformIndexHtml: (html: string) => string;
220
+ closeBundle: (this: MiniappManifestPluginContext) => Promise<void>;
216
221
  };
217
222
 
223
+ export interface MiniappManifestOptions {
224
+ /** 仅供平台测试和自托管 Remote Environment adapter 使用。 */
225
+ enforceSdkVersion?: typeof defaultEnforceRemoteSdkVersion;
226
+ }
227
+
218
228
  interface MiniappManifestUserConfig {
219
229
  base?: string;
230
+ define?: Record<string, string>;
220
231
  }
221
232
 
222
233
  interface MiniappManifestPluginContext {
@@ -225,36 +236,144 @@ interface MiniappManifestPluginContext {
225
236
 
226
237
  interface MiniappManifestResolvedConfig {
227
238
  root: string;
239
+ command: 'build' | 'serve';
228
240
  build: {
229
241
  outDir: string;
230
242
  };
243
+ server: {
244
+ host?: string | boolean;
245
+ port?: number;
246
+ hmr?: boolean | {
247
+ clientPort?: number;
248
+ host?: string;
249
+ port?: number;
250
+ protocol?: 'ws' | 'wss';
251
+ };
252
+ };
231
253
  }
232
254
 
233
- export function miniappManifest(): MiniappManifestPlugin {
255
+ const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
256
+ const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
257
+
258
+ export function miniappManifest(options: MiniappManifestOptions = {}): MiniappManifestPlugin {
234
259
  let root = process.cwd();
235
260
  let outDir = 'dist';
261
+ let command: 'build' | 'serve' = 'build';
262
+ let hmrWebSocketUrl: string | undefined;
263
+ /** 构建链路中更早的失败原因;closeBundle 不得再用产物校验覆盖它。 */
264
+ let priorBuildError: Error | undefined;
236
265
 
237
266
  return {
238
267
  name: 'heybox-miniapp-manifest',
239
- apply: 'build',
240
268
  config(config) {
241
- if (config.base === undefined) {
242
- return { base: './' };
243
- }
269
+ assertMiniappViteBase(config.base);
270
+ return {
271
+ ...(config.base === undefined ? { base: './' } : {}),
272
+ define: {
273
+ [sdkVersionBuildConstant]: JSON.stringify(resolveSdkVersion()),
274
+ },
275
+ };
244
276
  },
245
277
  configResolved(resolved) {
246
278
  root = resolved.root;
247
279
  outDir = resolved.build.outDir;
280
+ command = resolved.command;
281
+ hmrWebSocketUrl = resolveHmrWebSocketUrl(resolved);
282
+ },
283
+ async buildStart() {
284
+ if (command !== 'build') return;
285
+ try {
286
+ await (options.enforceSdkVersion ?? defaultEnforceRemoteSdkVersion)({
287
+ sdkVersion: resolveSdkVersion(),
288
+ environment: resolveHeyboxApiBaseUrl({ env: process.env }),
289
+ serviceTag: process.env.HB_SDK_SERVICE_TAG,
290
+ allowPrerelease: true,
291
+ });
292
+ } catch (error) {
293
+ priorBuildError = toError(error);
294
+ throw priorBuildError;
295
+ }
248
296
  },
249
- writeBundle() {
297
+ buildEnd(error) {
298
+ if (error) {
299
+ priorBuildError = priorBuildError ?? toError(error);
300
+ }
301
+ },
302
+ transformIndexHtml(html) {
303
+ return enforceMiniappHtmlPolicy(html, command === 'serve' ? { hmrWebSocketUrl } : undefined);
304
+ },
305
+ async closeBundle() {
306
+ // Rollup 在 buildStart/transform 失败后仍会调用 closeBundle。
307
+ // 若此时再抛「缺 index.html」等二次错误,会掩盖真实失败原因。
308
+ if (priorBuildError) {
309
+ throw priorBuildError;
310
+ }
311
+
250
312
  const version = validateMiniappPackageVersionForBuild(readMiniappVersionFromPackageJson(root));
313
+ const sdkVersion = resolveSdkVersion();
314
+ const outputRoot = path.resolve(root, outDir);
315
+ const htmlFiles = collectHtmlFiles(outputRoot);
316
+ const unexpectedHtmlFiles = htmlFiles.filter(file => path.relative(outputRoot, file) !== 'index.html');
317
+ if (unexpectedHtmlFiles.length > 0) {
318
+ throw new Error(
319
+ `工坊小程序只支持单页应用,构建产物不允许额外 HTML:${unexpectedHtmlFiles
320
+ .map(file => path.relative(outputRoot, file).split(path.sep).join('/'))
321
+ .join(', ')}`,
322
+ );
323
+ }
324
+ const indexHtmlPath = path.join(outputRoot, 'index.html');
325
+ if (!htmlFiles.includes(indexHtmlPath)) {
326
+ throw new Error('构建产物必须包含入口 dist/index.html');
327
+ }
328
+ writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(readFileSync(indexHtmlPath, 'utf8')));
251
329
 
252
- const manifestPath = path.resolve(root, outDir, 'manifest.json');
330
+ const manifestPath = path.join(outputRoot, 'manifest.json');
253
331
  mkdirSync(path.dirname(manifestPath), { recursive: true });
254
- writeFileSync(manifestPath, renderMiniappManifest({ version }));
332
+ writeFileSync(manifestPath, renderMiniappManifest({ version, sdkVersion }));
255
333
  },
256
334
  };
257
335
  }
336
+
337
+ function assertMiniappViteBase(base: string | undefined) {
338
+ if (base !== undefined && base !== '' && base !== './') {
339
+ throw new Error(`工坊小程序 Vite base 仅支持空字符串或 "./",当前值:${base}`);
340
+ }
341
+ }
342
+
343
+ function toError(error: unknown): Error {
344
+ return error instanceof Error ? error : new Error(String(error));
345
+ }
346
+
347
+ function collectHtmlFiles(root: string) {
348
+ const files: string[] = [];
349
+ if (!existsSync(root)) return files;
350
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
351
+ const fullPath = path.join(root, entry.name);
352
+ if (entry.isDirectory()) files.push(...collectHtmlFiles(fullPath));
353
+ else if (entry.isFile() && path.extname(entry.name).toLowerCase() === '.html') files.push(fullPath);
354
+ }
355
+ return files;
356
+ }
357
+
358
+ function resolveSdkVersion() {
359
+ if (HB_SDK_VERSION !== sdkVersionPlaceholder) return HB_SDK_VERSION;
360
+ const packageJson = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf8')) as { version?: unknown };
361
+ if (typeof packageJson.version !== 'string' || !packageJson.version) {
362
+ throw new Error('未能读取 @heybox/hb-sdk 当前版本号');
363
+ }
364
+ return packageJson.version;
365
+ }
366
+
367
+ function resolveHmrWebSocketUrl(resolved: MiniappManifestResolvedConfig) {
368
+ const hmr = resolved.server.hmr;
369
+ if (hmr === false) return undefined;
370
+ const options = typeof hmr === 'object' ? hmr : {};
371
+ const protocol = options.protocol ?? 'ws';
372
+ const configuredHost = options.host ?? resolved.server.host;
373
+ const host = typeof configuredHost === 'string' && configuredHost !== '0.0.0.0' ? configuredHost : '127.0.0.1';
374
+ const port = options.clientPort ?? options.port ?? resolved.server.port;
375
+ return `${protocol}://${host}${port ? `:${port}` : ''}`;
376
+ }
258
377
  ```
259
378
 
260
379
  ## Manifest
@@ -263,11 +382,12 @@ export function miniappManifest(): MiniappManifestPlugin {
263
382
 
264
383
  ```json
265
384
  {
266
- "version": "1.2.3"
385
+ "version": "1.2.3",
386
+ "sdkVersion": "0.6.0"
267
387
  }
268
388
  ```
269
389
 
270
- `version` 来自小程序项目自身的 `package.json.version`。`hb-sdk create` 生成的模板默认已注册插件;现有 Vite 项目可以在 `vite.config.ts` 中手动接入:
390
+ `version` 来自小程序项目自身的 `package.json.version`,`sdkVersion` 来自当前安装 SDK 的构建版本且不能由业务覆盖。`hb-sdk create` 生成的模板默认已注册插件;现有 Vite 项目可以在 `vite.config.ts` 中手动接入:
271
391
 
272
392
  ```ts
273
393
  import { miniappManifest } from '@heybox/hb-sdk/vite';
@@ -281,12 +401,18 @@ export default defineConfig({
281
401
 
282
402
  `base: './'` 用于让构建产物里的 JS/CSS/图片资源以 `./assets/...` 相对路径引用,避免小程序资源目录不是站点根路径时访问 `/assets/...` 失败。若没有显式配置 `base`,`miniappManifest()` 也会在 build 时默认补成 `./`。
283
403
 
404
+ 工坊小程序构建产物只能在兼容的小黑盒 Runtime 中启动。普通浏览器直接打开时不会执行标准业务脚本,并会提示在小黑盒 APP 内打开。项目应使用标准 Vite module 入口。
405
+
406
+ 插件只接受单页应用:输出目录只能存在入口 `index.html`。build 会用结构化 HTML parser 校验入口,并把平台 CSP 插入 `<head>` 首位;已有 CSP 会原样保留,两份策略按浏览器交集生效。正式策略禁止 `fetch`、XHR、WebSocket、EventSource、Beacon、Worker、iframe、表单和对象加载等浏览器原生出口;业务网络请求应使用 `network.request()`。dev 使用相同策略,只额外放行当前 Vite 的精确 HMR WebSocket 地址。
407
+
408
+ meta refresh、外部 anchor、`dns-prefetch`、`preconnect`、`prerender`、外部资源 URL 和额外 HTML 会使 build 失败。内联 script/style 允许,但 `unsafe-eval` 不允许。`dev`、build 和 deploy 会读取 `/user_miniprogram/public/sdk_config` 的 `minimumSdkVersion`;最新请求失败时只回退当前 Remote Environment 下 24 小时内的有效缓存,无缓存则默认阻断并提示升级 `@heybox/hb-sdk@latest`。
409
+
284
410
  失败与警告语义:
285
411
 
286
412
  - 读取 `package.json` 失败或 JSON 解析失败:`vite build` 直接失败,并输出具体原因。
287
413
  - `package.json.version` 不是非空字符串:`vite build` 直接失败。
288
- - `package.json.version` 仍是模板默认值 `0.0.0`:`vite build` 输出 warning 并写入 manifest;`hb-sdk remote deploy` 会拒绝发布,必须改成实际 `x.y.z` 版本。
289
- - 版本号不满足极简 semver 形态 `x.y.z`:只输出 Rollup/Vite warning,仍会写入 manifest。
414
+ - `package.json.version` 仍是模板默认值 `0.0.0`:`vite build` 直接失败,必须改成实际 SemVer。
415
+ - 版本号不是严格 SemVer、包含 build metadata 或缺少 `sdkVersion`:build/deploy 直接失败。
290
416
 
291
417
  `manifest.json` 不部署到 CDN,只交给发布流水线读取后上送后台;Host 通过后台 API 间接读取版本信息。第一阶段只支持 Vite 项目,非 Vite 打包器未来通过其他子入口扩展。
292
418
 
@@ -642,7 +768,7 @@ await network.request({
642
768
 
643
769
  ## 生命周期事件
644
770
 
645
- SDK 实例创建后会自动开始与父容器握手。使用 `on()` 监听父容器派发的小程序事件时,默认单例会被懒创建并自动开始握手;`on()` 会返回取消监听函数,组件卸载或页面销毁时应及时调用。
771
+ 导入 SDK 根包时会 eager 创建唯一默认实例并立即开始与父容器握手。使用 `on()` 监听父容器派发的小程序事件时不会创建第二个实例;`on()` 会返回取消监听函数,组件卸载或页面销毁时应及时调用。
646
772
 
647
773
  ```ts
648
774
  import { on } from '@heybox/hb-sdk';
@@ -56,7 +56,7 @@ hb-sdk remote allowlist list
56
56
  hb-sdk remote allowlist add <heybox-id...>
57
57
  hb-sdk remote allowlist remove <heybox-id...>
58
58
  hb-sdk remote allowlist set <heybox-id...>
59
- hb-sdk remote deploy --release-note <text> [--skip-build | --from-version <version>] [--auto-publish]
59
+ hb-sdk remote deploy --release-note <text> [--from-version <version>] [--auto-publish]
60
60
  hb-sdk remote versions
61
61
  hb-sdk remote preview <version>
62
62
  hb-sdk remote release <version> [--yes]
@@ -131,7 +131,6 @@ Use `hb-sdk dev` for local browser SDK debugging. Use the Mock runtime host's "
131
131
  ```bash
132
132
  hb-sdk remote deploy --release-note "修复登录状态展示,补充异常提示"
133
133
  hb-sdk remote deploy --release-note "审核通过后自动发布" --auto-publish
134
- hb-sdk remote deploy --skip-build --release-note "复用已有 dist 构建产物"
135
134
  hb-sdk remote deploy --from-version 1.2.3 --release-note "复用 1.2.3 历史产物"
136
135
  hb-sdk remote deploy --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "测试环境验证"
137
136
  hb-sdk remote deploy --verbose --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "排查预检失败"
@@ -145,15 +144,14 @@ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://12
145
144
  3. 如果需要以公司的名义发布小程序,需先找 @秦浩东 申请小程序开发权限。
146
145
  4. 读取并校验 `--release-note`;TTY 环境缺失时会提示输入,CI / 非 TTY 环境缺失时直接失败。建议让 AI 生成 1-5 条简短发布日志。
147
146
  5. 普通 remote deploy 先读取 `package.json.version`,登录后、build 前调用版本预检接口;预检通过后才执行 `<pm> run build`。
148
- 6. `--skip-build` 跳过构建,但会先读取已有 `dist/manifest.json.version`,再调用版本预检接口。
149
- 7. `--from-version <version>` 跳过本地构建、`dist/` 读取和上传,复用指定历史版本产物提交审核;它与 `--skip-build` 互斥。
150
- 8. 解析 `dist/manifest.json`,自动剥离 BOM,并校验 `version` 是合法 SemVer:允许 prerelease,例如 `1.2.3-rc.1`;拒绝 build metadata,例如 `1.2.3+build.1`;拒绝 `0.0.0`。
151
- 9. 普通 remote deploy `dist/manifest.json.version` 必须与预检使用的 `package.json.version` 一致,否则失败且不上传。
152
- 10. 遍历 `dist/` 文件,过滤掉 `manifest.json`、`.DS_Store`、`*.map`;遇到 symbolic link 或 `node_modules` 路径直接报错。
153
- 11. 校验上传路径长度不超过 64,并在任何上传请求发生前限制实际上传产物总大小不超过 100MiB。错误提示中使用 `100MB`,方便开发者理解。
154
- 12. 上传信息、上传凭证和上传回调按批次执行,每批最多 50 个文件;批次串行,批内保持 4 并发上传到 CDN。CLI 会校验 CDN 上传信息接口返回的 key 与本地期望 key 完全一致,异常时停止后续批次且不提交审核。
155
- 13. 默认只展示上传阶段和文件总数,例如 `正在上传 137/244 个文件`;`--verbose` 会展示并发数、批次数、当前批次、bucket / region 和逐文件结果,但不会输出 keys、签名、cookie、pkey、token 或临时密钥。
156
- 14. 全部上传成功后调用提交审核接口;`--from-version` 路径会直接提交 `source_version`。CLI 输出提交审核成功、发布策略和可用的 preview URL。
147
+ 6. `--from-version <version>` 跳过本地构建、`dist/` 读取和上传,复用指定历史版本产物提交审核。
148
+ 7. 解析 `dist/manifest.json`,自动剥离 BOM,并校验 `version` 是合法 SemVer:允许 prerelease,例如 `1.2.3-rc.1`;拒绝 build metadata,例如 `1.2.3+build.1`;拒绝 `0.0.0`。
149
+ 8. 普通 remote deploy 的 `dist/manifest.json.version` 必须与预检使用的 `package.json.version` 一致,否则失败且不上传。
150
+ 9. 遍历 `dist/` 文件,过滤掉 `manifest.json`、`.DS_Store`、`*.map`;遇到 symbolic link 或 `node_modules` 路径直接报错。
151
+ 10. 校验上传路径长度不超过 64,并在任何上传请求发生前限制实际上传产物总大小不超过 100MiB。错误提示中使用 `100MB`,方便开发者理解。
152
+ 11. 上传信息、上传凭证和上传回调按批次执行,每批最多 50 个文件;批次串行,批内保持 4 并发上传到 CDN。CLI 会校验 CDN 上传信息接口返回的 key 与本地期望 key 完全一致,异常时停止后续批次且不提交审核。
153
+ 12. 默认只展示上传阶段和文件总数,例如 `正在上传 137/244 个文件`;`--verbose` 会展示并发数、批次数、当前批次、bucket / region 和逐文件结果,但不会输出 keys、签名、cookie、pkey、token 或临时密钥。
154
+ 13. 全部上传成功后调用提交审核接口;`--from-version` 路径会直接提交 `source_version`。CLI 输出提交审核成功、发布策略和可用的 preview URL。
157
155
 
158
156
  `mini_program_id` 没有 CLI flag,必须落在 `package.json` 里:
159
157
 
@@ -165,15 +163,15 @@ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://12
165
163
  }
166
164
  ```
167
165
 
168
- `manifest.json` 仅作为提交审核接口的 `manifest` 字段提交,不会上传到 CDN。Vite 项目通过 `miniappManifest()` 插件生成;CLI 不会自动注入插件,请在 `vite.config.ts` 中显式挂载。小程序构建产物需要使用相对资源路径;`hb-sdk create` 模板会显式配置 `base: './'`,未配置 `base` 的项目也会由 `miniappManifest()` 在 build 时默认补成 `./`。
166
+ `manifest.json` 仅作为提交审核接口的 `manifest` 字段提交,不会上传到 CDN。Vite 项目通过 `miniappManifest()` 插件生成;CLI 不会自动注入插件,请在 `vite.config.ts` 中显式挂载。小程序构建产物需要使用相对资源路径;`hb-sdk create` 模板会显式配置 `base: './'`,未配置 `base` 的项目也会由 `miniappManifest()` 在 build 时默认补成 `./`。构建产物只能在兼容的小黑盒 Runtime 中启动,普通浏览器直接打开时不会执行标准业务脚本。
169
167
 
170
168
  默认发布策略是 `auto_publish=false`:运营审核通过后使用 `hb-sdk remote versions` 查看版本状态,再用 `hb-sdk remote release <version>` 发布。需要审核通过后自动发布并下架旧线上版本时,使用 `--auto-publish`。如需让指定用户预览未发布候选版本,使用 `hb-sdk remote allowlist add <heybox_id>` 管理预览白名单。
171
169
 
172
- 内部测试或预发环境可通过 `HB_SDK_API_BASE_URL` / `HB_SDK_LOGIN_BASE_URL` 设置默认后台环境,也可以用 `--api-base-url` / `--login-base-url` 覆盖单次命令。自定义地址只接受 origin,不允许包含 path、query 或 hash;API origin 默认还必须是 Heybox 受信 HTTPS 域名,只有本地联调等场景可显式使用 `--allow-unsafe-api-base-url` 或 `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` 放开。`apiBaseUrl` 影响 `hb-sdk remote` 里的远端平台后台 API,包括预检、CDN 上传凭证/回调、提交审核、版本、发布、撤回、下架、重新上架、详情和白名单等调用;`loginBaseUrl` 用于 `hb-sdk login` 的登录入口,以及 remote 命令前校验当前 CLI 登录态是否属于同一个登录环境。开发环境如需给后台请求带 `x-rylai-service-tag` 和 `special_tag`,优先用 `--service-tag <tag>` 或 `HB_SDK_SERVICE_TAG`;path-prefix 级 `special_tag` 仍可在 `packages/hb-sdk/src/cli/config.ts` 里按 `@heybox/hb-types` 的 `RylaiServiceTagConfig` 配置。日志只输出 origin,不输出带身份和签名参数的完整请求 URL。
170
+ 内部测试或预发环境可通过 `HB_SDK_API_BASE_URL` / `HB_SDK_LOGIN_BASE_URL` 设置默认后台环境,也可以用 `--api-base-url` / `--login-base-url` 覆盖单次命令。自定义地址只接受 origin,不允许包含 path、query 或 hash;API origin 默认还必须是 Heybox 受信 HTTPS 域名,只有本地联调等场景可显式使用 `--allow-unsafe-api-base-url` 或 `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` 放开。`apiBaseUrl` 影响 `hb-sdk remote` 里的远端平台后台 API,包括预检、CDN 上传凭证/回调、提交审核、版本、发布、撤回、下架、重新上架、详情和白名单等调用;`loginBaseUrl` 用于 `hb-sdk login` 的登录入口,以及 remote 命令前校验当前 CLI 登录态是否属于同一个登录环境。开发环境如需给后台请求带 `x-rylai-service-tag` 和 `special_tag`,优先用 `--service-tag <tag>` 或 `HB_SDK_SERVICE_TAG`;deploy 子构建会继承 `.env.<name>` 中的 `HB_SDK_SERVICE_TAG`,Vite 最低 SDK 版本门禁请求也会同时携带该 header 和 query。path-prefix 级 `special_tag` 仍可在 `packages/hb-sdk/src/cli/config.ts` 里按 `@heybox/hb-types` 的 `RylaiServiceTagConfig` 配置。日志只输出 origin,不输出带身份和签名参数的完整请求 URL。
173
171
 
174
172
  `hb-sdk doctor`、npm latest 检查、mock host 的 `network.request()` 不受这些配置影响。
175
173
 
176
- 切换测试环境时往往需要同时配置后台 host、登录 host 和 service tag。CLI 支持加载 `.env.<name>` 预设,把其中的 `HB_SDK_*` 变量一次性注入当前进程(不覆盖已有值):`--env <name>` 读取项目根下的 `.env.<name>`,`--env-file <path>` 显式指定路径且优先级更高,也可用 `HB_SDK_ENV=<name>` 触发。文件仅支持 `KEY=VALUE`、空行和 `#` 注释,不做变量插值;文件不存在时静默跳过。
174
+ 切换测试环境时往往需要同时配置后台 host、登录 host 和 service tag。CLI 支持加载 `.env.<name>` 预设,把其中的 `HB_SDK_*` 变量一次性注入当前进程(不覆盖已有值):`--env <name>` 读取项目根下的 `.env.<name>`,`--env-file <path>` 显式指定路径且优先级更高,也可用 `HB_SDK_ENV=<name>` 触发。使用 `--env <name>` 或 `HB_SDK_ENV=<name>` 执行 `remote deploy` 时,CLI 还会把同一个 `name` 作为 `--mode <name>` 传给项目 build,使 CLI 后端环境与 Vite mode 保持一致。文件仅支持 `KEY=VALUE`、空行和 `#` 注释,不做变量插值;文件不存在时静默跳过。
177
175
 
178
176
  ```bash
179
177
  # 项目根准备 .env.test
@@ -195,7 +193,7 @@ Before precheck, build, upload, or submit audit, `hb-sdk remote deploy` must ver
195
193
  Agent rules:
196
194
 
197
195
  - Use `hb-sdk remote deploy --release-note <text>` for normal build, upload, and submit-audit flows.
198
- - Use `hb-sdk remote deploy --from-version <version> --release-note <text>` to reuse a remote history artifact. Do not combine `--from-version` with `--skip-build`.
196
+ - Use `hb-sdk remote deploy --from-version <version> --release-note <text>` to reuse a remote history artifact.
199
197
  - Verify remote deploy guidance says current-entity mismatch fails before precheck/build/upload/submit and never auto-switches the developer entity.
200
198
  - Never recommend top-level `hb-sdk deploy`; it has been removed rather than retained as a compatibility alias.
201
199
  - After non-auto deploy succeeds, suggest `hb-sdk remote versions` and then `hb-sdk remote release <version>` after approval. Do not send the user to Open for manual publish when the CLI command exists.
@@ -76,7 +76,7 @@ stopAuthChange()
76
76
 
77
77
  默认单例适合一个页面只有一个 SDK 上下文的情况。大多数小程序页面都应该使用默认单例,因为它可以避免重复握手和重复维护事件监听。
78
78
 
79
- 需要控制 `timeout`、注入测试 window 或隔离多个上下文时,再使用 [独立实例](#custom-instance-recipe)。
79
+ 0.6 起根入口只提供唯一默认实例并在导入时立即握手,不再允许业务创建独立实例。测试需要隔离 bridge 时应在应用边界替换公开模块。
80
80
 
81
81
  ## User and login
82
82
 
@@ -260,15 +260,7 @@ function reportSDKError(code: string, message: string, data?: unknown) {
260
260
 
261
261
  ## 超时时间
262
262
 
263
- 默认超时时间是 10000ms。需要调整时,使用独立实例:
264
-
265
- ```ts
266
- import { createMiniProgramSDK } from '@heybox/hb-sdk'
267
-
268
- const sdk = createMiniProgramSDK({
269
- timeout: 15000,
270
- })
271
- ```
263
+ 默认握手超时时间是 10000ms。0.6 起业务不能通过独立实例修改该值;超时应作为 Host/Runtime 启动异常处理。
272
264
 
273
265
  ## Login gate recipe
274
266
 
@@ -325,50 +317,26 @@ async function handleSubmit() {
325
317
  ## Custom instance recipe
326
318
 
327
319
 
328
- # 独立 SDK 实例
320
+ # 默认 SDK 单例
329
321
 
330
- 大多数业务页使用默认单例即可。只有在需要隔离上下文时,再创建独立实例。
322
+ 0.6 起 SDK 根入口会 eager 创建唯一默认实例并立即握手,不再公开独立实例工厂。
331
323
 
332
- ## 自定义 timeout
324
+ ## 业务接入
333
325
 
334
326
  ```ts
335
- import { createMiniProgramSDK } from '@heybox/hb-sdk'
336
-
337
- const sdk = createMiniProgramSDK({
338
- timeout: 15000,
339
- })
327
+ import hbSDK from '@heybox/hb-sdk'
340
328
 
341
- await sdk.ready()
329
+ await hbSDK.ready()
342
330
  ```
343
331
 
344
332
  ## 测试环境注入 window
345
333
 
346
- 单元测试可以注入 `selfWindow`、`targetWindow` `nonce`,避免依赖真实 iframe。
347
-
348
- ```ts
349
- import { createMiniProgramSDK } from '@heybox/hb-sdk'
350
-
351
- const sdk = createMiniProgramSDK({
352
- nonce: 'test_nonce',
353
- selfWindow: window,
354
- targetWindow: null,
355
- })
356
-
357
- sdk.destroy()
358
- ```
359
-
360
- ## 清理实例
361
-
362
- 独立实例不再使用时调用 `destroy`。
334
+ 测试需要替换 bridge window 时,应在应用测试边界 mock `@heybox/hb-sdk` 公开模块,不要从业务代码访问内部构造器。
363
335
 
364
336
  ```ts
365
- const sdk = createMiniProgramSDK()
366
-
367
- try {
368
- await sdk.ready()
369
- } finally {
370
- sdk.destroy()
371
- }
337
+ vi.mock('@heybox/hb-sdk', () => ({
338
+ default: { ready: vi.fn(async () => undefined) },
339
+ }))
372
340
  ```
373
341
 
374
- `destroy` 会移除 message 监听,并拒绝尚未完成的请求。销毁后不要继续复用该实例。
342
+ 默认实例由页面生命周期管理,业务不调用 `destroy()`。
@@ -10,14 +10,13 @@
10
10
 
11
11
  ## 能力边界
12
12
 
13
- - SDK 实例创建后会自动开始握手;默认单例仍按需懒创建,`ready()`、`on()` 或任意模块能力调用都会创建默认单例并开始握手。
13
+ - 导入 SDK 根包时会 eager 创建唯一默认实例并立即开始握手;`ready()` 只等待这次握手结果。
14
14
  - `ready()` 只等待已有握手结果,不主动触发新的握手;调用模块能力前会自动等待 `ready()`,但业务仍建议在页面启动阶段显式 `await ready()`,便于集中处理握手失败。
15
15
  - `user.getInfo()`、`user.getCurrentUserDetail()`、`user.getCurrentUserProfile()`、`user.getPlatformAccountOverview()`、`user.getPlatformAccountInfo(platform)` 和 `user.getSteamGameList(options)` 不会触发登录;登录必须由业务在用户操作后调用 `auth.login()`。
16
16
  - 当前用户详情和平台账号 API 只允许读取当前登录用户,不支持传入 `userid` 查询其他人,也不透传 `/account/home_v2/` 原始响应。
17
17
  - 分享、截图、UI、设备、导航、storage 和网络请求只开放稳定窄接口,不透传黑盒客户端内部协议参数。
18
18
  - `network.request()` 的 `validateStatus` 只在 SDK 本地执行,不会被序列化给父容器。
19
19
  - `on()` 返回取消监听函数;组件卸载或页面销毁时应主动取消监听。
20
- - 使用 `createMiniProgramSDK()` 创建独立实例后,不再需要时应调用 `destroy()`。
21
20
  - 构建产物可以包含 `dist/manifest.json`,业务代码不应自行 fetch 已部署的 manifest;这个文件由发布流水线读取并上送后台。
22
21
 
23
22
  ## Agent rules