@heybox/hb-sdk 0.6.8-alpha.1 → 0.6.8

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 (35) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +2 -0
  3. package/dist/cli-chunks/{build-Do18KfQL.cjs → build-D4crgajb.cjs} +29 -25
  4. package/dist/cli-chunks/{context-CQ5481xZ.cjs → context-fRWWSXDj.cjs} +122 -23
  5. package/dist/cli-chunks/{create-BU7nViJ9.cjs → create-BU_EFgDz.cjs} +1 -1
  6. package/dist/cli-chunks/{dev-DJY-_cK4.cjs → dev-BrkChQ7v.cjs} +142 -108
  7. package/dist/cli-chunks/{doctor-BduOKHnV.cjs → doctor-DZXVO4rL.cjs} +1 -1
  8. package/dist/cli-chunks/{index-e2GK8bAH.cjs → index-CSjJrnkO.cjs} +14 -14
  9. package/dist/cli-chunks/{index-BVNo9ygg.cjs → index-DxH41nsb.cjs} +3 -3
  10. package/dist/cli-chunks/{login-C2wtKo_W.cjs → login-DLVozxrs.cjs} +2 -2
  11. package/dist/cli-chunks/{project-vite-D769ezhw.cjs → project-vite-CwmMfCk3.cjs} +1 -1
  12. package/dist/cli-chunks/{remote-Cf4i1DSL.cjs → remote-CfpkkC9I.cjs} +40 -22
  13. package/dist/cli-chunks/{runtime-gate-DfMJQGH9.cjs → runtime-gate-CgN_v4Te.cjs} +3 -3
  14. package/dist/cli-chunks/{index-v4-6fbXX.cjs → runtime-permission-env-B0jK9Rt1.cjs} +71 -0
  15. package/dist/cli-chunks/{session-z1D8xVrB.cjs → session-DB7ARwm4.cjs} +1 -1
  16. package/dist/cli.cjs +1 -1
  17. package/dist/devtools/mock-host/main.js +609 -6
  18. package/dist/index.cjs.js +403 -7
  19. package/dist/index.esm.js +403 -7
  20. package/dist/vite.cjs.js +17 -2
  21. package/dist/vite.esm.js +17 -2
  22. package/package.json +2 -2
  23. package/skill/SKILL.md +7 -6
  24. package/skill/references/api-root.md +7 -2
  25. package/skill/references/cli.md +4 -0
  26. package/skill/references/examples.md +17 -2
  27. package/skill/references/safety-boundaries.md +2 -0
  28. package/skill/scripts/sync-references.mjs +17 -2
  29. package/skill/skill.json +4 -4
  30. package/types/core/network-sanitize.d.ts +31 -0
  31. package/types/modules/network/index.d.ts +2 -0
  32. package/types/modules/network/observability.d.ts +39 -0
  33. package/types/modules/network/request-shape.d.ts +44 -0
  34. package/types/vite/html-policy.d.ts +1 -0
  35. package/types/vite/runtime-permission-env.d.ts +9 -0
@@ -106,6 +106,8 @@ CLI 会启动页面服务并自动打开本地调试页。调试页会展示小
106
106
 
107
107
  未登录或未绑定小程序时,浏览器、Mac 和手机调试入口仍然可用,但受管能力会默认拒绝。登录并绑定后,调试页才能根据当前小程序的线上配置提示差异。
108
108
 
109
+ `hb-sdk dev` 会在启动 Vite 前读取远端权限。只有远端权限快照有效、`network.request.status=enabled` 且 `useOfficialDomain=true` 时才跳过平台 CSP;未登录、未绑定、读取失败、非法快照或仅在 Dev Context 中开启本地权限覆盖时都继续注入 CSP。
110
+
109
111
  ### 2. 先用浏览器 Mock 验收
110
112
 
111
113
  浏览器 Mock 支持热更新,适合快速检查:
@@ -152,6 +154,8 @@ hb-sdk build [--env <name>] [--verbose]
152
154
 
153
155
  `hb-sdk build` 直接使用项目安装的 Vite,先清理再生成固定的 `dist/`,并校验小程序入口、Manifest 和可上传产物。它不执行类型检查,不要求 CLI 登录或绑定小程序,也不访问远端服务。项目必须在 `vite.config.ts` 中显式注册 `miniappManifest()`。
154
156
 
157
+ 直接运行 `hb-sdk build` 或 `vite build` 时默认注入平台 CSP。`hb-sdk remote deploy` 会在构建前读取绑定小程序的远端权限;仅当 `network.request.status=enabled` 且 `useOfficialDomain=true` 时向子构建传递已验证上下文并跳过平台 CSP。权限缺失、非法或读取失败时继续注入,Runtime Gate、Manifest 与 HTML 构建检查始终保留。
158
+
155
159
  推荐由项目的 `scripts.build` 保留类型检查:
156
160
 
157
161
  ```json
@@ -48,7 +48,7 @@ export async function ensureLogin() {
48
48
  ### Network request
49
49
 
50
50
  ```ts
51
- import { ready, network, HbMiniProgramNetworkError } from '@heybox/hb-sdk';
51
+ import { ready, network, HbMiniProgramNetworkError, HbMiniProgramSDKError } from '@heybox/hb-sdk';
52
52
 
53
53
  try {
54
54
  await ready();
@@ -59,9 +59,23 @@ try {
59
59
  validateStatus: status => status >= 200 && status < 400,
60
60
  });
61
61
  console.log(response.data.ok);
62
+
63
+ // form POST only: App Host does not support multipart/form-data
64
+ await network.request({
65
+ url: 'https://api.example.com/form',
66
+ method: 'POST',
67
+ headers: {
68
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
69
+ },
70
+ data: new URLSearchParams({ gameId: '3', roleId: '1' }).toString(),
71
+ });
62
72
  } catch (error) {
63
73
  if (error instanceof HbMiniProgramNetworkError) {
64
- console.warn(error.status, error.response?.data);
74
+ // Target HTTP non-2xx, or host-side network_error (message says so)
75
+ console.warn(error.status, error.message, error.data);
76
+ } else if (error instanceof HbMiniProgramSDKError) {
77
+ // e.g. INVALID_PARAMS for unsupported multipart shape
78
+ console.warn(error.code, error.message);
65
79
  }
66
80
  }
67
81
  ```
@@ -116,6 +130,7 @@ export default defineConfig({
116
130
  - Do not create raw `postMessage` bridge envelopes in business pages.
117
131
  - Do not call unsupported storage delete/clear/info operations.
118
132
  - Do not pass raw internal share/network protocol fields from mini-program code.
133
+ - Do not send `multipart/form-data` (or handcrafted multipart bodies) through `network.request`; use form-urlencoded string body or a dedicated upload capability.
119
134
  - Do not treat `hb-sdk login` as iframe SDK authentication state.
120
135
  - Do not create a second mock runtime package when `hb-sdk dev` is the supported local mock workflow.
121
136
  - Do not import `@heybox/hb-sdk/vite` from iframe business code or fetch a deployed `manifest.json` directly.
@@ -14,6 +14,8 @@
14
14
  - `auth.login()` 只能由明确的用户操作触发,不要在页面初始化时自动登录。
15
15
  - `on()` 返回取消监听函数,组件卸载或页面销毁时需要调用。
16
16
  - 业务网络请求使用 `network.request()`,不要依赖浏览器原生网络出口。
17
+ - `network.request` 不支持 `multipart/form-data`;App Host 仅支持 form(`application/x-www-form-urlencoded`)与 JSON。表单请用 `URLSearchParams#toString()` 作为 `data`,文件上传请走专用上传能力。
18
+ - 仅当远端已启用 `network.request` 且 `useOfficialDomain=true` 时,`hb-sdk dev` 与 `hb-sdk remote deploy` 构建才会跳过平台 CSP;其他构建继续注入平台 CSP。
17
19
  - 构建必须启用 `miniappManifest()`,推荐统一使用 `hb-sdk build`。
18
20
 
19
21
  ## Agent rules
@@ -587,7 +587,7 @@ export async function ensureLogin() {
587
587
 
588
588
  ### Network request
589
589
 
590
- ${fenced('ts', `import { ready, network, HbMiniProgramNetworkError } from '@heybox/hb-sdk';
590
+ ${fenced('ts', `import { ready, network, HbMiniProgramNetworkError, HbMiniProgramSDKError } from '@heybox/hb-sdk';
591
591
 
592
592
  try {
593
593
  await ready();
@@ -598,9 +598,23 @@ try {
598
598
  validateStatus: status => status >= 200 && status < 400,
599
599
  });
600
600
  console.log(response.data.ok);
601
+
602
+ // form POST only: App Host does not support multipart/form-data
603
+ await network.request({
604
+ url: 'https://api.example.com/form',
605
+ method: 'POST',
606
+ headers: {
607
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
608
+ },
609
+ data: new URLSearchParams({ gameId: '3', roleId: '1' }).toString(),
610
+ });
601
611
  } catch (error) {
602
612
  if (error instanceof HbMiniProgramNetworkError) {
603
- console.warn(error.status, error.response?.data);
613
+ // Target HTTP non-2xx, or host-side network_error (message says so)
614
+ console.warn(error.status, error.message, error.data);
615
+ } else if (error instanceof HbMiniProgramSDKError) {
616
+ // e.g. INVALID_PARAMS for unsupported multipart shape
617
+ console.warn(error.code, error.message);
604
618
  }
605
619
  }`)}
606
620
 
@@ -646,6 +660,7 @@ export default defineConfig({
646
660
  - Do not create raw \`postMessage\` bridge envelopes in business pages.
647
661
  - Do not call unsupported storage delete/clear/info operations.
648
662
  - Do not pass raw internal share/network protocol fields from mini-program code.
663
+ - Do not send \`multipart/form-data\` (or handcrafted multipart bodies) through \`network.request\`; use form-urlencoded string body or a dedicated upload capability.
649
664
  - Do not treat \`hb-sdk login\` as iframe SDK authentication state.
650
665
  - Do not create a second mock runtime package when \`hb-sdk dev\` is the supported local mock workflow.
651
666
  - Do not import \`@heybox/hb-sdk/vite\` from iframe business code or fetch a deployed \`manifest.json\` directly.
package/skill/skill.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "hb-sdk",
3
- "skillVersion": "0.6.8-alpha.0+skill.e34106bdd1de",
3
+ "skillVersion": "0.6.8+skill.79001ff42152",
4
4
  "sdk": {
5
5
  "package": "@heybox/hb-sdk",
6
- "version": "0.6.8-alpha.0",
7
- "compatibility": "0.6.8-alpha.0"
6
+ "version": "0.6.8",
7
+ "compatibility": "0.6.8"
8
8
  },
9
9
  "source": "https://open.xiaoheihe.cn/agent-skills/hb-sdk",
10
- "integrity": "sha256-e34106bdd1dea827b5d991d2142e079bbdfa3cb4288141e1a6c7418ec2bf8ced"
10
+ "integrity": "sha256-79001ff42152003dc0b79b0ddd0945843f7eade237defb024c609a5d5b3048c0"
11
11
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * network.request 诊断日志的纯脱敏工具。
3
+ *
4
+ * @remarks
5
+ * 放在 `core` 而非 `modules/network`:无错误类型依赖,供 SDK 错误文案、
6
+ * modules observability、devtools Mock Host / proxy 共用,并满足 boundary
7
+ *(devtools 不得直接 import runtime capability modules)。
8
+ */
9
+ export type MiniProgramNetworkHeadersLike = Record<string, string>;
10
+ /**
11
+ * 脱敏请求 URL:去掉 userinfo,并将 query / fragment 中的敏感参数值替换为 `[redacted]`。
12
+ */
13
+ export declare function sanitizeNetworkRequestUrl(url: string): string;
14
+ /**
15
+ * 脱敏请求/响应头;敏感名(含 heybox 前缀)替换为 `[redacted]`。
16
+ */
17
+ export declare function sanitizeNetworkHeaders(headers?: MiniProgramNetworkHeadersLike): MiniProgramNetworkHeadersLike;
18
+ /**
19
+ * 预览请求/响应 data:递归脱敏敏感字段,截断长文本与大数组。
20
+ */
21
+ export declare function previewNetworkData(data: unknown): unknown;
22
+ /**
23
+ * 递归脱敏日志对象(payload / result):敏感 key、headers、url 字段统一处理。
24
+ */
25
+ export declare function redactNetworkLogValue(value: unknown): unknown;
26
+ /**
27
+ * 诊断 message 中的 URL 片段做脱敏,避免 error.message 二次泄漏 query secrets。
28
+ */
29
+ export declare function sanitizeDiagnosticMessage(message: string): string;
30
+ export declare function isSensitiveNetworkHeaderName(headerName: string): boolean;
31
+ export declare function isSensitiveNetworkKey(key: string): boolean;
@@ -1,5 +1,7 @@
1
1
  import type { MiniProgramRequester } from '../../core/client';
2
2
  export { NETWORK_REQUEST_METHOD } from '../../protocol/capabilities';
3
+ export { createNetworkRequestFailureLog, formatNetworkRequestFailureMessage, logNetworkRequestFailure, previewNetworkData, sanitizeNetworkHeaders, sanitizeNetworkRequestUrl, } from './observability';
4
+ export { describeHostNetworkFailure, isMultipartContentType, isUnsupportedMultipartNetworkRequest, looksLikeMultipartBody, NETWORK_REQUEST_MULTIPART_UNSUPPORTED_MESSAGE, readNetworkContentType, } from './request-shape';
3
5
  /** `network.request` 请求头。 */
4
6
  export type MiniProgramNetworkHeaders = Record<string, string>;
5
7
  /** `network.request` 查询参数。 */
@@ -0,0 +1,39 @@
1
+ import type { MiniProgramNetworkHeaders, MiniProgramNetworkRequestConfig } from './index';
2
+ export { previewNetworkData, redactNetworkLogValue, sanitizeDiagnosticMessage, sanitizeNetworkHeaders, sanitizeNetworkRequestUrl, } from '../../core/network-sanitize';
3
+ export type NetworkRequestFailureKind = 'http_status' | 'invalid_response' | 'bridge_error' | 'unknown';
4
+ export interface NetworkRequestFailureLog {
5
+ kind: NetworkRequestFailureKind;
6
+ method: string;
7
+ url: string;
8
+ status?: number;
9
+ statusText?: string;
10
+ code?: string;
11
+ message?: string;
12
+ headers?: MiniProgramNetworkHeaders;
13
+ dataPreview?: unknown;
14
+ timeout?: number;
15
+ withCredentials?: boolean;
16
+ }
17
+ /**
18
+ * 记录 `network.request` 失败,保证异常路径在开发者控制台可观测。
19
+ *
20
+ * @remarks
21
+ * - 仅用于诊断,不改变错误抛出语义。
22
+ * - 会脱敏 token/cookie 等敏感头与字段,并截断 body 预览。
23
+ * - detail 构造与 logger 调用均包在 try 内,日志失败不得影响业务错误抛出。
24
+ */
25
+ export declare function logNetworkRequestFailure(config: MiniProgramNetworkRequestConfig, error: unknown, extras: {
26
+ kind: NetworkRequestFailureKind;
27
+ status?: number;
28
+ statusText?: string;
29
+ data?: unknown;
30
+ headers?: MiniProgramNetworkHeaders;
31
+ }): void;
32
+ export declare function createNetworkRequestFailureLog(config: MiniProgramNetworkRequestConfig, error: unknown, extras: {
33
+ kind: NetworkRequestFailureKind;
34
+ status?: number;
35
+ statusText?: string;
36
+ data?: unknown;
37
+ headers?: MiniProgramNetworkHeaders;
38
+ }): NetworkRequestFailureLog;
39
+ export declare function formatNetworkRequestFailureMessage(detail: NetworkRequestFailureLog): string;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * network.request 请求体形态校验与宿主失败诊断文案。
3
+ *
4
+ * @remarks
5
+ * App Host 的 heybox 客户端代发 transport 仅声明 form/json,不支持 multipart。
6
+ * 本地 Mock 若直接走 fetch 会“能通”,上线后却变成难以理解的 500 network_error。
7
+ * 因此在 SDK 侧统一提前拒绝 multipart,并在宿主伪装 HTTP 失败时给出可操作提示。
8
+ */
9
+ /** multipart 不被 App Host 支持时的稳定说明(开发者可见)。 */
10
+ export declare const NETWORK_REQUEST_MULTIPART_UNSUPPORTED_MESSAGE = "network.request \u4E0D\u652F\u6301 multipart/form-data\u3002App Host \u5BA2\u6237\u7AEF\u4EE3\u53D1\u4EC5\u652F\u6301 application/x-www-form-urlencoded\uFF08form\uFF09\u4E0E application/json\uFF1B\u8BF7\u5C06 data \u7F16\u7801\u4E3A form \u5B57\u7B26\u4E32\uFF08\u4F8B\u5982 new URLSearchParams({...}).toString()\uFF09\u5E76\u8BBE\u7F6E Content-Type: application/x-www-form-urlencoded\u3002\u6587\u4EF6\u4E0A\u4F20\u8BF7\u4F7F\u7528\u4E13\u7528\u4E0A\u4F20\u80FD\u529B\uFF0C\u52FF\u624B\u5199 multipart boundary\u3002";
11
+ /**
12
+ * 读取请求头中的 Content-Type(大小写不敏感)。
13
+ */
14
+ export declare function readNetworkContentType(headers: Record<string, string> | undefined): string | undefined;
15
+ /**
16
+ * 判断 Content-Type 是否声明为 multipart/form-data。
17
+ */
18
+ export declare function isMultipartContentType(contentType: string | undefined): boolean;
19
+ /**
20
+ * 判断字符串 body 是否像手写 multipart 实体。
21
+ */
22
+ export declare function looksLikeMultipartBody(data: unknown): boolean;
23
+ /**
24
+ * 判断公开请求配置是否使用了 Host 不支持的 multipart 形态。
25
+ */
26
+ export declare function isUnsupportedMultipartNetworkRequest(config: {
27
+ data?: unknown;
28
+ headers?: Record<string, string>;
29
+ }): boolean;
30
+ /**
31
+ * 从宿主返回的“完成态”响应中提取更清晰的失败原因。
32
+ *
33
+ * @remarks
34
+ * Host 可能把 transport 不支持等内部错误包装成 HTTP 500 + `{ status: 'network_error', msg }`。
35
+ * 此时 `status=500` 并不代表目标站点返回了 500。
36
+ */
37
+ export declare function describeHostNetworkFailure(response: {
38
+ config?: {
39
+ data?: unknown;
40
+ headers?: Record<string, string>;
41
+ };
42
+ data?: unknown;
43
+ status: number;
44
+ }): string | undefined;
@@ -1,4 +1,5 @@
1
1
  export declare const PRODUCTION_CSP: string;
2
2
  export declare function enforceMiniappHtmlPolicy(html: string, options?: {
3
3
  hmrWebSocketUrl?: string;
4
+ skipPlatformCsp?: boolean;
4
5
  }): string;
@@ -0,0 +1,9 @@
1
+ export declare const HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN_ENV = "HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN";
2
+ export declare const HB_SDK_RUNTIME_PERMISSION_CONTEXT_ENV = "HB_SDK_RUNTIME_PERMISSION_CONTEXT";
3
+ export declare function shouldSkipMiniappPlatformCspFromEnv(env?: NodeJS.ProcessEnv): boolean;
4
+ export declare function createMiniappPlatformCspEnv(env: NodeJS.ProcessEnv, skipPlatformCsp: boolean): {
5
+ HB_SDK_RUNTIME_PERMISSION_CONTEXT: string;
6
+ HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN: string;
7
+ TZ?: string | undefined;
8
+ };
9
+ export declare function withMiniappPlatformCspEnv<T>(skipPlatformCsp: boolean, action: () => Promise<T>, env?: NodeJS.ProcessEnv): Promise<T>;