@heybox/hb-sdk 0.2.0-alpha.1 → 0.3.1

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.
package/dist/index.esm.js CHANGED
@@ -236,8 +236,9 @@ class MiniProgramBridgeClient {
236
236
  this.eventBus.off(eventName, handler);
237
237
  }
238
238
  /** 调用父容器开放能力。 */
239
- async request(method, payload) {
239
+ async request(method, ...args) {
240
240
  await this.ready();
241
+ const payload = args[0];
241
242
  const id = createMessageId();
242
243
  const message = {
243
244
  namespace: MINI_PROGRAM_MESSAGE_NAMESPACE,
@@ -884,4 +885,4 @@ const hbSDK = {
884
885
  network,
885
886
  };
886
887
 
887
- export { AUTH_LOGIN_METHOD, HbMiniProgramNetworkError, HbMiniProgramSDKError, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MiniProgramSDK, NETWORK_REQUEST_METHOD, SDK_HANDSHAKE_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, USER_GET_INFO_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, auth, createMiniProgramSDK, hbSDK as default, isMiniProgramBridgeMessage, network, off, on, ready, share, storage, user, viewport };
888
+ export { HbMiniProgramNetworkError, HbMiniProgramSDKError, MiniProgramSDK, auth, createMiniProgramSDK, hbSDK as default, network, off, on, ready, share, storage, user, viewport };
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ const PUBLISH_VERSION_RE = /^\d+\.\d+\.\d+$/;
4
+ function isValidMiniappManifestVersion(version) {
5
+ return PUBLISH_VERSION_RE.test(String(version || '').trim());
6
+ }
7
+
8
+ const MINIAPP_UPLOAD_SCOPE = 'activity';
9
+ const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
10
+ const PUBLISH_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/publish';
11
+ const FNV_OFFSET = 0x811c9dc5;
12
+ const FNV_PRIME = 0x01000193;
13
+ function normalizeRelativePath(relativePath) {
14
+ return String(relativePath || '')
15
+ .replace(/\\/g, '/')
16
+ .replace(/^\/+/, '')
17
+ .replace(/\/+/g, '/');
18
+ }
19
+ function relativePathContainsNodeModulesSegment(relativePath) {
20
+ return normalizeRelativePath(relativePath)
21
+ .split('/')
22
+ .some((segment) => segment.length > 0 && segment.toLowerCase() === 'node_modules');
23
+ }
24
+ function getMiniProgramUploadAlias(miniProgramId) {
25
+ let hash = FNV_OFFSET;
26
+ const input = String(miniProgramId || '');
27
+ for (let i = 0; i < input.length; i += 1) {
28
+ hash ^= input.charCodeAt(i);
29
+ hash = Math.imul(hash, FNV_PRIME) >>> 0;
30
+ }
31
+ return hash.toString(36);
32
+ }
33
+ function getMiniappUploadKey(input) {
34
+ const alias = getMiniProgramUploadAlias(input.miniProgramId);
35
+ const normalized = normalizeRelativePath(input.relativePath);
36
+ return `/u/${alias}/${input.version}/${normalized}`;
37
+ }
38
+ function validateUploadPaths(items, options) {
39
+ const limit = options.maxLength ?? ACTIVITY_UPLOAD_KEY_MAX_LENGTH;
40
+ for (const item of items) {
41
+ const key = getMiniappUploadKey({
42
+ miniProgramId: options.miniProgramId,
43
+ version: options.version,
44
+ relativePath: item.relativePath,
45
+ });
46
+ if (key.length > limit) {
47
+ return `文件路径过长,请缩短构建产物文件名或目录层级:${item.relativePath}`;
48
+ }
49
+ }
50
+ return undefined;
51
+ }
52
+ function shouldUploadDistFile(relativePath) {
53
+ const normalized = normalizeRelativePath(relativePath);
54
+ if (!normalized) {
55
+ return false;
56
+ }
57
+ if (normalized === 'manifest.json') {
58
+ return false;
59
+ }
60
+ if (normalized === '.DS_Store' || normalized.endsWith('/.DS_Store')) {
61
+ return false;
62
+ }
63
+ if (normalized.toLowerCase().endsWith('.map')) {
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+
69
+ exports.ACTIVITY_UPLOAD_KEY_MAX_LENGTH = ACTIVITY_UPLOAD_KEY_MAX_LENGTH;
70
+ exports.MINIAPP_UPLOAD_SCOPE = MINIAPP_UPLOAD_SCOPE;
71
+ exports.PUBLISH_USER_MINIPROGRAM_API_PATH = PUBLISH_USER_MINIPROGRAM_API_PATH;
72
+ exports.getMiniProgramUploadAlias = getMiniProgramUploadAlias;
73
+ exports.getMiniappUploadKey = getMiniappUploadKey;
74
+ exports.isValidVersion = isValidMiniappManifestVersion;
75
+ exports.normalizeRelativePath = normalizeRelativePath;
76
+ exports.relativePathContainsNodeModulesSegment = relativePathContainsNodeModulesSegment;
77
+ exports.shouldUploadDistFile = shouldUploadDistFile;
78
+ exports.validateUploadPaths = validateUploadPaths;
@@ -0,0 +1,67 @@
1
+ const PUBLISH_VERSION_RE = /^\d+\.\d+\.\d+$/;
2
+ function isValidMiniappManifestVersion(version) {
3
+ return PUBLISH_VERSION_RE.test(String(version || '').trim());
4
+ }
5
+
6
+ const MINIAPP_UPLOAD_SCOPE = 'activity';
7
+ const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
8
+ const PUBLISH_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/publish';
9
+ const FNV_OFFSET = 0x811c9dc5;
10
+ const FNV_PRIME = 0x01000193;
11
+ function normalizeRelativePath(relativePath) {
12
+ return String(relativePath || '')
13
+ .replace(/\\/g, '/')
14
+ .replace(/^\/+/, '')
15
+ .replace(/\/+/g, '/');
16
+ }
17
+ function relativePathContainsNodeModulesSegment(relativePath) {
18
+ return normalizeRelativePath(relativePath)
19
+ .split('/')
20
+ .some((segment) => segment.length > 0 && segment.toLowerCase() === 'node_modules');
21
+ }
22
+ function getMiniProgramUploadAlias(miniProgramId) {
23
+ let hash = FNV_OFFSET;
24
+ const input = String(miniProgramId || '');
25
+ for (let i = 0; i < input.length; i += 1) {
26
+ hash ^= input.charCodeAt(i);
27
+ hash = Math.imul(hash, FNV_PRIME) >>> 0;
28
+ }
29
+ return hash.toString(36);
30
+ }
31
+ function getMiniappUploadKey(input) {
32
+ const alias = getMiniProgramUploadAlias(input.miniProgramId);
33
+ const normalized = normalizeRelativePath(input.relativePath);
34
+ return `/u/${alias}/${input.version}/${normalized}`;
35
+ }
36
+ function validateUploadPaths(items, options) {
37
+ const limit = options.maxLength ?? ACTIVITY_UPLOAD_KEY_MAX_LENGTH;
38
+ for (const item of items) {
39
+ const key = getMiniappUploadKey({
40
+ miniProgramId: options.miniProgramId,
41
+ version: options.version,
42
+ relativePath: item.relativePath,
43
+ });
44
+ if (key.length > limit) {
45
+ return `文件路径过长,请缩短构建产物文件名或目录层级:${item.relativePath}`;
46
+ }
47
+ }
48
+ return undefined;
49
+ }
50
+ function shouldUploadDistFile(relativePath) {
51
+ const normalized = normalizeRelativePath(relativePath);
52
+ if (!normalized) {
53
+ return false;
54
+ }
55
+ if (normalized === 'manifest.json') {
56
+ return false;
57
+ }
58
+ if (normalized === '.DS_Store' || normalized.endsWith('/.DS_Store')) {
59
+ return false;
60
+ }
61
+ if (normalized.toLowerCase().endsWith('.map')) {
62
+ return false;
63
+ }
64
+ return true;
65
+ }
66
+
67
+ export { ACTIVITY_UPLOAD_KEY_MAX_LENGTH, MINIAPP_UPLOAD_SCOPE, PUBLISH_USER_MINIPROGRAM_API_PATH, getMiniProgramUploadAlias, getMiniappUploadKey, isValidMiniappManifestVersion as isValidVersion, normalizeRelativePath, relativePathContainsNodeModulesSegment, shouldUploadDistFile, validateUploadPaths };
@@ -10,12 +10,14 @@ npm run dev
10
10
  npm run typecheck
11
11
  npm run test:unit
12
12
  npm run build
13
+ npm run deploy
13
14
  ```
14
15
 
15
16
  ## 开发模式
16
17
 
17
18
  - `npm run dev`:启动本地 Vite 服务和 `hb-sdk` 内置 mock runtime host,适合本地调试 SDK 能力;调试页内可点击按钮在 Mac 版 APP 中启动同一页面。
18
19
  - `npm run build`:先执行 TypeScript 检查,再构建生产产物。
20
+ - `npm run deploy`:构建并发布当前小程序。发布前需要先把 `package.json` 中的 `heybox.miniProgramId` 改成后台分配的真实小程序 id,并执行过 `npx hb-sdk login`。
19
21
 
20
22
  ## 更多能力
21
23
 
@@ -3,8 +3,13 @@
3
3
  "version": "0.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
+ "heybox": {
7
+ "miniProgramId": ""
8
+ },
6
9
  "scripts": {
10
+ "hb-sdk": "hb-sdk",
7
11
  "dev": "hb-sdk dev",
12
+ "deploy": "hb-sdk deploy",
8
13
  "build": "vue-tsc --noEmit && vite build",
9
14
  "preview": "vite preview",
10
15
  "typecheck": "vue-tsc --noEmit",
@@ -1,6 +1,7 @@
1
1
  import vue from '@vitejs/plugin-vue';
2
+ import { miniappManifest } from '@heybox/hb-sdk/vite';
2
3
  import { defineConfig } from 'vite';
3
4
 
4
5
  export default defineConfig({
5
- plugins: [vue()],
6
+ plugins: [vue(), miniappManifest()],
6
7
  });
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ var node_fs = require('node:fs');
4
+ var path = require('node:path');
5
+
6
+ const MINIAPP_TEMPLATE_VERSION = '0.0.0';
7
+ const BUILD_VERSION_RE = /^\d+\.\d+\.\d+(?:[-+].*)?$/;
8
+ function getMiniappManifestBuildWarning(version) {
9
+ if (version === MINIAPP_TEMPLATE_VERSION) {
10
+ return '@heybox/hb-sdk 提示:package.json.version 仍是模板默认的 0.0.0;manifest 会写入,但发布前必须改成实际 x.y.z 版本';
11
+ }
12
+ if (!BUILD_VERSION_RE.test(version)) {
13
+ return `package.json.version "${version}" 不是标准 semver,仍会写入 manifest.json`;
14
+ }
15
+ return undefined;
16
+ }
17
+ function renderMiniappManifest(manifest) {
18
+ return `${JSON.stringify({ version: manifest.version }, null, 2)}\n`;
19
+ }
20
+
21
+ function findNearestPackageJsonPath(startDir) {
22
+ let current = path.resolve(startDir);
23
+ while (true) {
24
+ const packageJsonPath = path.join(current, 'package.json');
25
+ if (node_fs.existsSync(packageJsonPath)) {
26
+ return packageJsonPath;
27
+ }
28
+ const parent = path.dirname(current);
29
+ if (parent === current) {
30
+ return path.join(path.resolve(startDir), 'package.json');
31
+ }
32
+ current = parent;
33
+ }
34
+ }
35
+ function readMiniappVersionFromPackageJson(root) {
36
+ const packageJsonPath = findNearestPackageJsonPath(root);
37
+ let content;
38
+ try {
39
+ content = node_fs.readFileSync(packageJsonPath, 'utf8');
40
+ }
41
+ catch (error) {
42
+ throw new Error(`@heybox/hb-sdk 读取 package.json 失败:${formatReason(error)}`);
43
+ }
44
+ let packageJson;
45
+ try {
46
+ packageJson = JSON.parse(content);
47
+ }
48
+ catch (error) {
49
+ throw new Error(`@heybox/hb-sdk 解析 package.json 失败:${formatReason(error)}`);
50
+ }
51
+ if (typeof packageJson.version !== 'string' || packageJson.version.trim() === '') {
52
+ throw new Error('@heybox/hb-sdk 提示:package.json.version 必须是非空字符串');
53
+ }
54
+ return packageJson.version.trim();
55
+ }
56
+ function formatReason(error) {
57
+ if (error instanceof Error && error.message) {
58
+ return error.message;
59
+ }
60
+ return String(error);
61
+ }
62
+
63
+ function miniappManifest() {
64
+ let root = process.cwd();
65
+ let outDir = 'dist';
66
+ return {
67
+ name: 'heybox-miniapp-manifest',
68
+ apply: 'build',
69
+ configResolved(resolved) {
70
+ root = resolved.root;
71
+ outDir = resolved.build.outDir;
72
+ },
73
+ writeBundle() {
74
+ const version = readMiniappVersionFromPackageJson(root);
75
+ const warning = getMiniappManifestBuildWarning(version);
76
+ if (warning) {
77
+ this.warn(warning);
78
+ }
79
+ const manifestPath = path.resolve(root, outDir, 'manifest.json');
80
+ node_fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
81
+ node_fs.writeFileSync(manifestPath, renderMiniappManifest({ version }));
82
+ },
83
+ };
84
+ }
85
+
86
+ exports.miniappManifest = miniappManifest;
@@ -0,0 +1,84 @@
1
+ import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ const MINIAPP_TEMPLATE_VERSION = '0.0.0';
5
+ const BUILD_VERSION_RE = /^\d+\.\d+\.\d+(?:[-+].*)?$/;
6
+ function getMiniappManifestBuildWarning(version) {
7
+ if (version === MINIAPP_TEMPLATE_VERSION) {
8
+ return '@heybox/hb-sdk 提示:package.json.version 仍是模板默认的 0.0.0;manifest 会写入,但发布前必须改成实际 x.y.z 版本';
9
+ }
10
+ if (!BUILD_VERSION_RE.test(version)) {
11
+ return `package.json.version "${version}" 不是标准 semver,仍会写入 manifest.json`;
12
+ }
13
+ return undefined;
14
+ }
15
+ function renderMiniappManifest(manifest) {
16
+ return `${JSON.stringify({ version: manifest.version }, null, 2)}\n`;
17
+ }
18
+
19
+ function findNearestPackageJsonPath(startDir) {
20
+ let current = path.resolve(startDir);
21
+ while (true) {
22
+ const packageJsonPath = path.join(current, 'package.json');
23
+ if (existsSync(packageJsonPath)) {
24
+ return packageJsonPath;
25
+ }
26
+ const parent = path.dirname(current);
27
+ if (parent === current) {
28
+ return path.join(path.resolve(startDir), 'package.json');
29
+ }
30
+ current = parent;
31
+ }
32
+ }
33
+ function readMiniappVersionFromPackageJson(root) {
34
+ const packageJsonPath = findNearestPackageJsonPath(root);
35
+ let content;
36
+ try {
37
+ content = readFileSync(packageJsonPath, 'utf8');
38
+ }
39
+ catch (error) {
40
+ throw new Error(`@heybox/hb-sdk 读取 package.json 失败:${formatReason(error)}`);
41
+ }
42
+ let packageJson;
43
+ try {
44
+ packageJson = JSON.parse(content);
45
+ }
46
+ catch (error) {
47
+ throw new Error(`@heybox/hb-sdk 解析 package.json 失败:${formatReason(error)}`);
48
+ }
49
+ if (typeof packageJson.version !== 'string' || packageJson.version.trim() === '') {
50
+ throw new Error('@heybox/hb-sdk 提示:package.json.version 必须是非空字符串');
51
+ }
52
+ return packageJson.version.trim();
53
+ }
54
+ function formatReason(error) {
55
+ if (error instanceof Error && error.message) {
56
+ return error.message;
57
+ }
58
+ return String(error);
59
+ }
60
+
61
+ function miniappManifest() {
62
+ let root = process.cwd();
63
+ let outDir = 'dist';
64
+ return {
65
+ name: 'heybox-miniapp-manifest',
66
+ apply: 'build',
67
+ configResolved(resolved) {
68
+ root = resolved.root;
69
+ outDir = resolved.build.outDir;
70
+ },
71
+ writeBundle() {
72
+ const version = readMiniappVersionFromPackageJson(root);
73
+ const warning = getMiniappManifestBuildWarning(version);
74
+ if (warning) {
75
+ this.warn(warning);
76
+ }
77
+ const manifestPath = path.resolve(root, outDir, 'manifest.json');
78
+ mkdirSync(path.dirname(manifestPath), { recursive: true });
79
+ writeFileSync(manifestPath, renderMiniappManifest({ version }));
80
+ },
81
+ };
82
+ }
83
+
84
+ export { miniappManifest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk",
3
- "version": "0.2.0-alpha.1",
3
+ "version": "0.3.1",
4
4
  "description": "",
5
5
  "exports": {
6
6
  ".": {
@@ -16,6 +16,19 @@
16
16
  "node": "./dist/protocol.cjs.js",
17
17
  "browser": "./dist/protocol.esm.js",
18
18
  "default": "./dist/protocol.esm.js"
19
+ },
20
+ "./miniapp-publish": {
21
+ "types": "./types/miniapp-publish/index.d.ts",
22
+ "heybox": "./src/miniapp-publish/index.ts",
23
+ "node": "./dist/miniapp-publish.cjs.js",
24
+ "browser": "./dist/miniapp-publish.esm.js",
25
+ "default": "./dist/miniapp-publish.esm.js"
26
+ },
27
+ "./vite": {
28
+ "types": "./types/vite/index.d.ts",
29
+ "import": "./dist/vite.esm.js",
30
+ "require": "./dist/vite.cjs.js",
31
+ "default": "./dist/vite.esm.js"
19
32
  }
20
33
  },
21
34
  "bin": {
@@ -30,6 +43,15 @@
30
43
  "keywords": [],
31
44
  "author": "",
32
45
  "license": "ISC",
46
+ "dependencies": {},
47
+ "peerDependencies": {
48
+ "vite": ">=5"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "vite": {
52
+ "optional": true
53
+ }
54
+ },
33
55
  "devDependencies": {
34
56
  "@rollup/plugin-commonjs": "^28.0.6",
35
57
  "@rollup/plugin-json": "^6.1.0",
@@ -42,6 +64,7 @@
42
64
  "@types/node": "24.10.1",
43
65
  "@vitest/coverage-v8": "^3.2.4",
44
66
  "commander": "^12.1.0",
67
+ "cos-nodejs-sdk-v5": "2.15.4",
45
68
  "ejs": "^3.1.10",
46
69
  "env-paths": "^2.2.1",
47
70
  "fs-extra": "^11.3.0",
@@ -53,6 +76,7 @@
53
76
  "rollup": "^4.52.4",
54
77
  "typescript": "^5.9.3",
55
78
  "vue": "2.7.16",
79
+ "vite": "^8.0.12",
56
80
  "vitest": "^3.2.4"
57
81
  },
58
82
  "publishConfig": {
@@ -86,9 +110,11 @@
86
110
  "build:templates": "node scripts/copy-cli-templates.cjs",
87
111
  "build:types": "tsc -p tsconfig.dts.json",
88
112
  "check:boundary": "node scripts/check-boundary.cjs",
113
+ "check:docs-sync": "node scripts/check-docs-sync.cjs",
89
114
  "clean": "rimraf ./dist && rimraf ./types",
90
115
  "test:unit": "NODE_OPTIONS='--conditions=heybox' vitest run",
91
116
  "test:unit:coverage": "NODE_OPTIONS='--conditions=heybox' vitest run --coverage",
117
+ "test:vite": "vitest run --config vitest.vite.config.ts",
92
118
  "test:watch": "NODE_OPTIONS='--conditions=heybox' vitest"
93
119
  }
94
120
  }
package/skill/SKILL.md CHANGED
@@ -22,9 +22,10 @@ Apply these instructions when writing, reviewing, or debugging code that consume
22
22
  3. For common business flows, read `references/recipes.md`.
23
23
  4. For CLI commands, local mock runtime, generated templates, CLI login cache, Agent Skill doctor, and update reminders, read `references/cli.md`.
24
24
  5. For allowed/forbidden capabilities and security boundaries, read `references/safety-boundaries.md`.
25
- 6. For generated documentation provenance and deeper API lookup paths, read `references/llms-index.md`.
26
- 7. For smoke-test expectations, positive examples, and anti-examples, read `references/examples.md`.
27
- 8. For evaluating whether another agent followed this skill, read `references/smoke-evaluation.md`.
25
+ 6. For Vite build manifest behavior, read `references/api-root.md` and `references/safety-boundaries.md`.
26
+ 7. For generated documentation provenance and deeper API lookup paths, read `references/llms-index.md`.
27
+ 8. For smoke-test expectations, positive examples, and anti-examples, read `references/examples.md`.
28
+ 9. For evaluating whether another agent followed this skill, read `references/smoke-evaluation.md`.
28
29
 
29
30
  ## Step 3: Follow import rules
30
31
 
@@ -47,14 +48,18 @@ Apply these instructions when writing, reviewing, or debugging code that consume
47
48
 
48
49
  1. Use `hb-sdk create <project-name>` to scaffold a standalone external mini-program template.
49
50
  2. Use `hb-sdk dev` for local browser debugging through the built-in mock runtime host.
50
- 3. Use the Mock runtime host's "在 Mac APP 中启动" button when the page needs to be loaded by the real Heybox mini-program container.
51
- 4. Use `--port`, `--mock-port`, `--host`, and `--no-open` when the default Vite/mock ports, host, or browser opening behavior need to be controlled.
52
- 5. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for the CLI's own Heybox auth cache.
53
- 6. Use `hb-sdk doctor` to diagnose whether the local `hb-sdk` skill matches the installed SDK and remote latest skill metadata.
54
- 7. 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`.
55
- 8. If doctor reports `SDK_MISMATCH`, upgrade `@heybox/hb-sdk@latest` before reinstalling the skill.
56
- 9. 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.
57
- 10. Keep the CLI and mock runtime under `@heybox/hb-sdk`; do not create or revive a separate mock runtime package.
51
+ 3. Use `hb-sdk deploy` to build and publish the current project. It reads `package.json.heybox.miniProgramId`, runs the project's `build` script via the package manager auto-detected by lockfile, then uploads `dist/` to CDN (skipping `manifest.json`, `.DS_Store`, `.map`) and calls the publish API.
52
+ 4. Use `hb-sdk deploy --skip-build` only when the `dist/` directory is already prepared by an upstream CI stage. Missing `dist/manifest.json` or `dist/index.html` aborts the run.
53
+ 5. Use the Mock runtime host's "在 Mac APP 中启动" button when the page needs to be loaded by the real Heybox mini-program container.
54
+ 6. Use `--port`, `--mock-port`, `--host`, and `--no-open` when the default Vite/mock ports, host, or browser opening behavior need to be controlled.
55
+ 7. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for the CLI's own Heybox auth cache.
56
+ 8. Use `hb-sdk doctor` to diagnose whether the local `hb-sdk` skill matches the installed SDK and remote latest skill metadata.
57
+ 9. 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`.
58
+ 10. If doctor reports `SDK_MISMATCH`, upgrade `@heybox/hb-sdk@latest` before reinstalling the skill.
59
+ 11. 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.
60
+ 12. Keep the CLI and mock runtime under `@heybox/hb-sdk`; do not create or revive a separate mock runtime package.
61
+ 13. Do not pass `mini_program_id` as a CLI flag or environment variable; it must come from `package.json.heybox.miniProgramId`.
62
+ 14. Do not import deploy / upload internals from outside the CLI; the only externally consumable subpath for publishing is `@heybox/hb-sdk/miniapp-publish`.
58
63
 
59
64
  ## Step 6: Preserve capability boundaries
60
65
 
@@ -65,6 +70,7 @@ For iframe mini-program business code:
65
70
  3. Do not use unsupported storage operations such as delete, clear, info listing, or global client storage access.
66
71
  4. Do not pass raw host protocol fields through `network.request`; use only the public axios-like request config.
67
72
  5. Do not construct bridge envelopes, nonce logic, or raw `postMessage` calls.
73
+ 6. Build artifacts may include `dist/manifest.json`; business code should not fetch a deployed manifest directly because it is not a CDN asset.
68
74
 
69
75
  For CLI and local development:
70
76
 
@@ -81,15 +87,20 @@ For host/runtime/protocol-maintenance code:
81
87
  ## Step 7: Validate changes
82
88
 
83
89
  1. Run the nearest package tests and builds with repo-native commands when editing this repository.
84
- 2. When modifying this repo's source skill at `packages/hb-sdk/skill`, run:
85
- - `node packages/hb-sdk/skill/scripts/check-references.mjs`
86
- - `node packages/hb-sdk/skill/scripts/validate-skill.mjs`
90
+ 2. When modifying docs, skill instructions, CLI guidance, or public agent-skill sync points, start with:
91
+ - `pnpm --filter @heybox/hb-sdk run check:docs-sync`
92
+ - `cat packages/hb-sdk/DOC_SYNC_CHECKLIST.md`
93
+ 3. When modifying this repo's source skill at `packages/hb-sdk/skill` and preparing distributable artifacts, also run:
87
94
  - `node packages/hb-sdk/skill/scripts/package-skill.mjs`
88
- 3. When modifying CLI, mock runtime, package exports, or package dependency direction, also run:
95
+ 4. When modifying CLI, mock runtime, package exports, or package dependency direction, also run:
89
96
  - `pnpm --filter @heybox/hb-sdk run check:boundary`
90
97
  - `pnpm --filter @heybox/hb-sdk run test:unit`
91
- 4. Inspect the generated zip before distribution:
98
+ 5. Inspect the generated zip before distribution:
92
99
  - `unzip -l packages/hb-sdk/hb-sdk.zip | sed -n '1,120p'`
93
- 5. Verify public payload sync before publishing:
100
+ 6. When adding or modifying the deploy command or its upload pipeline, also run:
101
+ - `pnpm --filter @heybox/hb-sdk run check:boundary`
102
+ - `pnpm --filter @heybox/hb-sdk run test:unit`
103
+ - Verify `dist/cli.cjs` does not have any `require('cos-nodejs-sdk-v5')` left after `build:cli`; the boundary check enforces this automatically.
104
+ 6. Verify public payload sync before publishing:
94
105
  - `pnpm --filter @heybox-spa/open run sync:agent-skills`
95
106
  - `pnpm --filter @heybox-spa/open run check:agent-skills`