@heybox/hb-sdk 0.3.3 → 0.4.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.
Files changed (35) hide show
  1. package/README.md +63 -28
  2. package/dist/cli-chunks/browser-RAy8e8cV.cjs +635 -0
  3. package/dist/cli-chunks/create-Ds8A82lV.cjs +1376 -0
  4. package/dist/cli-chunks/deploy-D4uxwB2W.cjs +3730 -0
  5. package/dist/cli-chunks/dev-v-tcA7mM.cjs +955 -0
  6. package/dist/cli-chunks/doctor-C8NP7bow.cjs +186 -0
  7. package/dist/cli-chunks/index-BWrMUHh9.cjs +64023 -0
  8. package/dist/cli-chunks/index-DDqd9qAR.cjs +13348 -0
  9. package/dist/cli-chunks/login-BJVOo-hq.cjs +193 -0
  10. package/dist/cli-chunks/session-Iyxc2AGl.cjs +3040 -0
  11. package/dist/cli.cjs +19 -77707
  12. package/dist/devtools/mock-host/index.html +62 -2
  13. package/dist/devtools/mock-host/main.js +3246 -20
  14. package/dist/index.cjs.js +20 -0
  15. package/dist/index.esm.js +20 -0
  16. package/dist/miniapp-publish.cjs.js +2810 -4
  17. package/dist/miniapp-publish.esm.js +2809 -4
  18. package/dist/protocol.cjs.js +15 -0
  19. package/dist/protocol.esm.js +15 -1
  20. package/dist/templates/vue3-vite-ts/README.md.ejs +6 -2
  21. package/dist/vite.cjs.js +2814 -14
  22. package/dist/vite.esm.js +2814 -14
  23. package/package.json +6 -1
  24. package/skill/SKILL.md +19 -13
  25. package/skill/references/api-protocol.md +7 -2
  26. package/skill/references/api-root.md +24 -13
  27. package/skill/references/cli.md +339 -104
  28. package/skill/scripts/sync-references.mjs +17 -1
  29. package/skill/skill.json +4 -4
  30. package/types/index.d.ts +1 -1
  31. package/types/miniapp-manifest/schema.d.ts +2 -1
  32. package/types/miniapp-publish/index.d.ts +2 -1
  33. package/types/modules/viewport/index.d.ts +33 -0
  34. package/types/protocol/capabilities.d.ts +17 -2
  35. package/types/protocol.d.ts +2 -2
@@ -19,6 +19,7 @@
19
19
  - [Command surface](#command-surface)
20
20
  - [Create a mini-program template](#create-a-mini-program-template)
21
21
  - [Local dev and mock runtime](#local-dev-and-mock-runtime)
22
+ - [Deploy and backend operations](#deploy-and-backend-operations)
22
23
  - [CLI login cache](#cli-login-cache)
23
24
  - [Agent Skill doctor](#agent-skill-doctor)
24
25
  - [Update reminders](#update-reminders)
@@ -36,41 +37,45 @@ The CLI, templates, and mock host are owned by `@heybox/hb-sdk`. Do not create a
36
37
 
37
38
  ```ts
38
39
  import { Command, CommanderError, InvalidArgumentError } from 'commander';
39
- import { runCreateCommand as defaultRunCreateCommand } from './commands/create';
40
- import { runDeployCommand as defaultRunDeployCommand } from './commands/deploy';
41
- import { runDevCommand as defaultRunDevCommand } from './commands/dev';
42
- import { runDoctorCommand as defaultRunDoctorCommand } from './commands/doctor';
43
- import {
44
- clearLoginStatus as defaultClearLoginStatus,
45
- loginToHeybox as defaultLoginToHeybox,
46
- printLoginStatus as defaultPrintLoginStatus,
47
- } from './commands/login';
48
40
  import { printUpdateReminder as defaultPrintUpdateReminder } from './update-check';
49
41
  import { printError as defaultPrintError } from './utils/errors';
42
+ import { createCliLogger, type CliLogger } from './utils/logger';
50
43
  import { getCliVersion } from './version';
51
44
 
45
+ type ClearLoginStatus = typeof import('./commands/login').clearLoginStatus;
46
+ type LoginToHeybox = typeof import('./commands/login').loginToHeybox;
47
+ type PrintLoginStatus = typeof import('./commands/login').printLoginStatus;
48
+ type RunCreateCommand = typeof import('./commands/create').runCreateCommand;
49
+ type RunDeployCommand = typeof import('./commands/deploy').runDeployCommand;
50
+ type RunDevCommand = typeof import('./commands/dev').runDevCommand;
51
+ type RunDoctorCommand = typeof import('./commands/doctor').runDoctorCommand;
52
+
52
53
  export interface CliCommandHandlers {
53
- clearLoginStatus: typeof defaultClearLoginStatus;
54
- loginToHeybox: typeof defaultLoginToHeybox;
55
- printLoginStatus: typeof defaultPrintLoginStatus;
54
+ clearLoginStatus: ClearLoginStatus;
55
+ loginToHeybox: LoginToHeybox;
56
+ printLoginStatus: PrintLoginStatus;
56
57
  printUpdateReminder: typeof defaultPrintUpdateReminder;
57
- runCreateCommand: typeof defaultRunCreateCommand;
58
- runDeployCommand: typeof defaultRunDeployCommand;
59
- runDevCommand: typeof defaultRunDevCommand;
60
- runDoctorCommand: typeof defaultRunDoctorCommand;
58
+ runCreateCommand: RunCreateCommand;
59
+ runDeployCommand: RunDeployCommand;
60
+ runDevCommand: RunDevCommand;
61
+ runDoctorCommand: RunDoctorCommand;
61
62
  }
62
63
 
63
64
  export interface CliRuntimeOptions extends Partial<CliCommandHandlers> {
64
65
  argv?: string[];
66
+ createLogger?: (options: { verbose: boolean }) => CliLogger;
67
+ logger?: CliLogger;
65
68
  printError?: typeof defaultPrintError;
66
69
  process?: Pick<NodeJS.Process, 'exit'>;
67
70
  }
68
71
 
69
72
  export async function runCli(options: CliRuntimeOptions = {}) {
70
73
  const processLike = options.process ?? process;
74
+ const argv = options.argv ?? process.argv;
75
+ const verbose = hasVerboseArg(argv);
71
76
 
72
77
  try {
73
- await createCliProgram(options).parseAsync(options.argv ?? process.argv);
78
+ await createCliProgram(options).parseAsync(argv);
74
79
  } catch (error) {
75
80
  if (error instanceof CommanderError && error.exitCode === 0) {
76
81
  processLike.exit(0);
@@ -78,14 +83,14 @@ export async function runCli(options: CliRuntimeOptions = {}) {
78
83
  }
79
84
 
80
85
  if (!(error instanceof CommanderError)) {
81
- (options.printError ?? defaultPrintError)(error);
86
+ (options.printError ?? defaultPrintError)(error, { logger: resolveStandaloneLogger(options, verbose), verbose });
82
87
  }
83
88
 
84
89
  processLike.exit(error instanceof CommanderError ? error.exitCode : 1);
85
90
  }
86
91
  }
87
92
 
88
- export function createCliProgram(overrides: Partial<CliCommandHandlers> = {}) {
93
+ export function createCliProgram(overrides: Partial<CliCommandHandlers> & Pick<CliRuntimeOptions, 'createLogger' | 'logger'> = {}) {
89
94
  const handlers: CliCommandHandlers = {
90
95
  clearLoginStatus: defaultClearLoginStatus,
91
96
  loginToHeybox: defaultLoginToHeybox,
@@ -98,94 +103,263 @@ export function createCliProgram(overrides: Partial<CliCommandHandlers> = {}) {
98
103
  ...overrides,
99
104
  };
100
105
  const program = new Command();
106
+ const resolveLogger = createCommandLoggerResolver(overrides);
101
107
 
102
108
  program
103
109
  .name('hb-sdk')
104
110
  .description('hb-sdk developer tools')
105
111
  .version(getCliVersion())
112
+ .option('-v, --verbose', '输出详细调试信息')
106
113
  .showHelpAfterError()
107
114
  .exitOverride();
115
+ installVersionUpdateReminder(program, handlers.printUpdateReminder, resolveLogger);
116
+
117
+ addVerboseOption(
118
+ program.command('create').description('创建外部小程序项目开发模板').argument('<project-name>', '项目目录名,例如 my-miniapp'),
119
+ ).action(
120
+ withUpdateReminder(
121
+ async (projectName, _options, command: Command) => {
122
+ const logger = resolveLogger(command);
123
+ await handlers.runCreateCommand(projectName, { logger });
124
+ },
125
+ handlers.printUpdateReminder,
126
+ resolveLogger,
127
+ ),
128
+ );
129
+
130
+ addVerboseOption(
131
+ program
132
+ .command('dev')
133
+ .description('启动当前小程序项目的 Vite dev server 和浏览器 mock runtime host')
134
+ .option('--port <port>', 'App dev server 端口', parsePositivePort)
135
+ .option('--mock-port <port>', 'Mock host 端口', parsePositivePort)
136
+ .option('--runtime-url <url>', '真实客户端调试时使用的自定义 runtime 地址')
137
+ .option('--no-open', '不自动打开浏览器调试页'),
138
+ ).action(
139
+ withUpdateReminder(
140
+ async (options, command: Command) => {
141
+ const logger = resolveLogger(command);
142
+ await handlers.runDevCommand(options, { logger });
143
+ },
144
+ handlers.printUpdateReminder,
145
+ resolveLogger,
146
+ ),
147
+ );
148
+
149
+ addVerboseOption(
150
+ program
151
+ .command('deploy')
152
+ .description('构建并提交当前小程序版本审核')
153
+ .option('--skip-build', '跳过 build,直接读 dist 目录上传并提交审核')
154
+ .option('--release-note <text>', '发布日志,提交审核必填')
155
+ .option('--auto-publish', '审核通过后自动发布;默认需在开放平台手动发布')
156
+ .option('--api-base-url <url>', 'Heybox 后台 API origin,默认读取 HB_SDK_API_BASE_URL 或生产地址')
157
+ .option('--allow-unsafe-api-base-url', '允许向非 Heybox HTTPS API origin 发送登录态,仅限本地调试')
158
+ .option('--login-base-url <url>', '校验 CLI 登录态使用的登录 origin,默认读取 HB_SDK_LOGIN_BASE_URL 或生产地址'),
159
+ ).action(
160
+ withUpdateReminder(
161
+ async (options, command: Command) => {
162
+ const logger = resolveLogger(command);
163
+ await handlers.runDeployCommand(
164
+ {
165
+ allowUnsafeApiBaseUrl: Boolean(options.allowUnsafeApiBaseUrl),
166
+ apiBaseUrl: options.apiBaseUrl,
167
+ autoPublish: Boolean(options.autoPublish),
168
+ loginBaseUrl: options.loginBaseUrl,
169
+ releaseNote: options.releaseNote,
170
+ skipBuild: Boolean(options.skipBuild),
171
+ },
172
+ { logger },
173
+ );
174
+ },
175
+ handlers.printUpdateReminder,
176
+ resolveLogger,
177
+ ),
178
+ );
179
+
180
+ addVerboseOption(program.command('doctor').description('诊断 hb-sdk 本地环境和 Agent Skill 版本')).action(async (...args: unknown[]) => {
181
+ const logger = resolveLogger(readCommandFromActionArgs(args));
182
+ const result = await handlers.runDoctorCommand({ logger });
183
+
184
+ if (result.status !== 'SDK_MISMATCH') {
185
+ await handlers.printUpdateReminder({ logger });
186
+ }
187
+ });
188
+
189
+ const login = addVerboseOption(
190
+ program
191
+ .command('login')
192
+ .description('登录 Heybox 并缓存 CLI 登录态')
193
+ .option('--login-base-url <url>', 'Heybox 登录入口 origin,默认读取 HB_SDK_LOGIN_BASE_URL 或生产地址'),
194
+ ).action(
195
+ withUpdateReminder(
196
+ async (options, command: Command) => {
197
+ const logger = resolveLogger(command);
198
+ await handlers.loginToHeybox({
199
+ logger,
200
+ loginBaseUrl: options.loginBaseUrl,
201
+ });
202
+ },
203
+ handlers.printUpdateReminder,
204
+ resolveLogger,
205
+ ),
206
+ );
207
+
208
+ addVerboseOption(login.command('status').description('查看脱敏后的 Heybox 登录态')).action(
209
+ withUpdateReminder(
210
+ async (...args: unknown[]) => {
211
+ const logger = resolveLogger(readCommandFromActionArgs(args));
212
+ await handlers.printLoginStatus({ logger });
213
+ },
214
+ handlers.printUpdateReminder,
215
+ resolveLogger,
216
+ ),
217
+ );
218
+
219
+ addVerboseOption(login.command('clear').description('清理 hb-sdk 命名空间中的 Heybox 登录态')).action(
220
+ withUpdateReminder(
221
+ async (...args: unknown[]) => {
222
+ const logger = resolveLogger(readCommandFromActionArgs(args));
223
+ await handlers.clearLoginStatus({ logger });
224
+ },
225
+ handlers.printUpdateReminder,
226
+ resolveLogger,
227
+ ),
228
+ );
108
229
 
109
- program
110
- .command('create')
111
- .description('创建外部小程序项目开发模板')
112
- .argument('<project-name>', '项目目录名,例如 my-miniapp')
113
- .action(
114
- withUpdateReminder(async (projectName) => {
115
- await handlers.runCreateCommand(projectName);
116
- }, handlers.printUpdateReminder),
117
- );
230
+ return program;
231
+ }
118
232
 
119
- program
120
- .command('dev')
121
- .description('启动当前小程序项目的 Vite dev server 和浏览器 mock runtime host')
122
- .option('--port <port>', 'App dev server 端口', parsePositivePort)
123
- .option('--mock-port <port>', 'Mock host 端口', parsePositivePort)
124
- .option('--host <host>', '传给 Vite 和 mock host 的 host')
125
- .option('--no-open', '不自动打开浏览器调试页')
126
- .action(
127
- withUpdateReminder(async (options) => {
128
- await handlers.runDevCommand(options);
129
- }, handlers.printUpdateReminder),
130
- );
233
+ function addVerboseOption<T extends Command>(command: T): T {
234
+ return command.option('-v, --verbose', '输出详细调试信息') as T;
235
+ }
131
236
 
132
- program
133
- .command('deploy')
134
- .description('构建并发布当前小程序到 Heybox 后台')
135
- .option('--skip-build', '跳过 build,直接读 dist 目录上传并发布')
136
- .action(
137
- withUpdateReminder(async (options) => {
138
- await handlers.runDeployCommand({ skipBuild: Boolean(options.skipBuild) });
139
- }, handlers.printUpdateReminder),
140
- );
237
+ function hasVerboseArg(argv: string[]) {
238
+ return argv.includes('--verbose') || argv.includes('-v');
239
+ }
141
240
 
142
- program
143
- .command('doctor')
144
- .description('诊断 hb-sdk 本地环境和 Agent Skill 版本')
145
- .action(async () => {
146
- await handlers.runDoctorCommand();
147
- });
148
-
149
- const login = program
150
- .command('login')
151
- .description('登录 Heybox 并缓存 CLI 登录态')
152
- .action(
153
- withUpdateReminder(async () => {
154
- await handlers.loginToHeybox();
155
- }, handlers.printUpdateReminder),
156
- );
157
-
158
- login
159
- .command('status')
160
- .description('查看脱敏后的 Heybox 登录态')
161
- .action(
162
- withUpdateReminder(async () => {
163
- await handlers.printLoginStatus();
164
- }, handlers.printUpdateReminder),
165
- );
166
-
167
- login
168
- .command('clear')
169
- .description('清理 hb-sdk 命名空间中的 Heybox 登录态')
170
- .action(
171
- withUpdateReminder(async () => {
172
- await handlers.clearLoginStatus();
173
- }, handlers.printUpdateReminder),
174
- );
241
+ type ResolveCommandLogger = (commandOrVerbose?: Command | boolean) => CliLogger;
175
242
 
176
- return program;
243
+ function createCommandLoggerResolver(options: Pick<CliRuntimeOptions, 'createLogger' | 'logger'>): ResolveCommandLogger {
244
+ let defaultLogger: CliLogger | undefined;
245
+ let verboseLogger: CliLogger | undefined;
246
+
247
+ return (commandOrVerbose?: Command | boolean) => {
248
+ if (options.logger) {
249
+ return options.logger;
250
+ }
251
+
252
+ const verbose = typeof commandOrVerbose === 'boolean' ? commandOrVerbose : readCommandVerbose(commandOrVerbose);
253
+ if (verbose) {
254
+ verboseLogger ??= resolveStandaloneLogger(options, true);
255
+ return verboseLogger;
256
+ }
257
+
258
+ defaultLogger ??= resolveStandaloneLogger(options, false);
259
+ return defaultLogger;
260
+ };
261
+ }
262
+
263
+ const defaultClearLoginStatus: ClearLoginStatus = async (...args) => {
264
+ const { clearLoginStatus } = await import('./commands/login');
265
+ return clearLoginStatus(...args);
266
+ };
267
+
268
+ const defaultLoginToHeybox: LoginToHeybox = async (...args) => {
269
+ const { loginToHeybox } = await import('./commands/login');
270
+ return loginToHeybox(...args);
271
+ };
272
+
273
+ const defaultPrintLoginStatus: PrintLoginStatus = async (...args) => {
274
+ const { printLoginStatus } = await import('./commands/login');
275
+ return printLoginStatus(...args);
276
+ };
277
+
278
+ const defaultRunCreateCommand: RunCreateCommand = async (...args) => {
279
+ const { runCreateCommand } = await import('./commands/create');
280
+ return runCreateCommand(...args);
281
+ };
282
+
283
+ const defaultRunDeployCommand: RunDeployCommand = async (...args) => {
284
+ const { runDeployCommand } = await import('./commands/deploy');
285
+ return runDeployCommand(...args);
286
+ };
287
+
288
+ const defaultRunDevCommand: RunDevCommand = async (...args) => {
289
+ const { runDevCommand } = await import('./commands/dev');
290
+ return runDevCommand(...args);
291
+ };
292
+
293
+ const defaultRunDoctorCommand: RunDoctorCommand = async (...args) => {
294
+ const { runDoctorCommand } = await import('./commands/doctor');
295
+ return runDoctorCommand(...args);
296
+ };
297
+
298
+ function resolveStandaloneLogger(options: Pick<CliRuntimeOptions, 'createLogger' | 'logger'>, verbose: boolean) {
299
+ return options.logger ?? options.createLogger?.({ verbose }) ?? createCliLogger({ verbose });
300
+ }
301
+
302
+ function readCommandVerbose(command?: Command) {
303
+ if (!command) {
304
+ return false;
305
+ }
306
+
307
+ return Boolean(command.optsWithGlobals?.().verbose || command.opts().verbose);
308
+ }
309
+
310
+ function installVersionUpdateReminder(program: Command, printUpdateReminder: typeof defaultPrintUpdateReminder, resolveLogger: ResolveCommandLogger) {
311
+ const parseAsync = program.parseAsync.bind(program);
312
+
313
+ program.parseAsync = (async (...args: Parameters<Command['parseAsync']>) => {
314
+ const [argv, parseOptions] = args;
315
+
316
+ if (isVersionRequest(argv, parseOptions)) {
317
+ const logger = resolveLogger(hasVerboseArg(getUserArgs(argv, parseOptions)));
318
+ logger.raw(getCliVersion(), { stream: 'stdout' });
319
+ await printUpdateReminder({ logger });
320
+ throw new CommanderError(0, 'commander.version', 'version displayed');
321
+ }
322
+
323
+ return parseAsync(...args);
324
+ }) as Command['parseAsync'];
325
+ }
326
+
327
+ function isVersionRequest(argv: readonly string[] | undefined, parseOptions: { from?: string } | undefined) {
328
+ const userArgs = getUserArgs(argv, parseOptions).filter((arg) => arg !== '--verbose' && arg !== '-v');
329
+
330
+ return userArgs.length === 1 && (userArgs[0] === '--version' || userArgs[0] === '-V');
331
+ }
332
+
333
+ function getUserArgs(argv: readonly string[] | undefined, parseOptions: { from?: string } | undefined) {
334
+ const args = [...(argv ?? process.argv)];
335
+
336
+ if (parseOptions?.from === 'user') {
337
+ return args;
338
+ }
339
+
340
+ if (parseOptions?.from === 'electron') {
341
+ return args.slice(1);
342
+ }
343
+
344
+ return args.slice(2);
177
345
  }
178
346
 
179
347
  function withUpdateReminder<Args extends unknown[]>(
180
348
  action: (...args: Args) => Promise<void>,
181
349
  printUpdateReminder: typeof defaultPrintUpdateReminder,
350
+ resolveLogger: ResolveCommandLogger,
182
351
  ) {
183
352
  return async (...args: Args) => {
184
353
  await action(...args);
185
- await printUpdateReminder();
354
+ await printUpdateReminder({ logger: resolveLogger(readCommandFromActionArgs(args)) });
186
355
  };
187
356
  }
188
357
 
358
+ function readCommandFromActionArgs(args: unknown[]) {
359
+ const lastArg = args[args.length - 1];
360
+ return lastArg instanceof Command ? lastArg : undefined;
361
+ }
362
+
189
363
  function parsePositivePort(value: string) {
190
364
  const parsed = Number(value);
191
365
  if (!Number.isInteger(parsed) || parsed <= 0) {
@@ -228,26 +402,81 @@ Agent rules:
228
402
  hb-sdk dev
229
403
  ```
230
404
 
231
- `hb-sdk dev` 会从当前目录向上查找最近的 `package.json` 作为项目根目录,加载该项目安装的 `vite`,并优先使用项目内的 Vite 配置文件。命令会同时启动内置 mock runtime host 并默认打开调试页;如果需要真实黑盒小程序容器加载同一页面,点击调试页里的「在 Mac 版 APP 中启动」按钮。Codex、VSCode 等内嵌浏览器可能无法转交 `heybox://` 协议;需要从调试页唤起 Mac 版 APP 时,请先在系统浏览器中打开调试页。项目没有安装 Vite 时,命令会提示安装依赖或把 Vite 放到 `devDependencies`。
405
+ `hb-sdk dev` 会从当前目录向上查找最近的 `package.json` 作为项目根目录,加载该项目安装的 `vite`,并优先使用项目内的 Vite 配置文件。命令会同时启动内置 mock runtime host 并默认打开调试页;如果需要真实黑盒小程序容器加载同一页面,点击调试页里的「在 Mac 版 APP 中启动」按钮,或在「Mobile App」区域选择局域网网卡后用手机小黑盒 APP 扫码。手机需要与电脑处在同一局域网,并使用支持小程序调试壳的新版小黑盒 APP。Codex、VSCode 等内嵌浏览器可能无法转交 `heybox://` 协议;需要从调试页唤起 Mac 版 APP 时,请先在系统浏览器中打开调试页。项目没有安装 Vite 时,命令会提示安装依赖或把 Vite 放到 `devDependencies`。
232
406
 
233
407
  常用参数:
234
408
 
235
- | 参数 | 说明 |
236
- | --- | --- |
237
- | `--port <port>` | 指定小程序 Vite dev server 端口,默认从 `5173` 开始。 |
238
- | `--mock-port <port>` | 指定 mock host 端口,默认从 `5174` 开始。 |
239
- | `--host <host>` | 同时传给 Vite mock host host。 |
240
- | `--no-open` | 不自动打开浏览器调试页。 |
409
+ | 参数 | 说明 |
410
+ | -------------------- | ----------------------------------------------------- |
411
+ | `--port <port>` | 指定小程序 Vite dev server 端口,默认从 `5173` 开始。 |
412
+ | `--mock-port <port>` | 指定 mock host 端口,默认从 `5174` 开始。 |
413
+ | `--runtime-url <url>` | 真实客户端调试时传给 dev shell 的自定义 runtime 地址;手机扫码时 loopback host 会自动改写为所选局域网 IP。 |
414
+ | `--no-open` | 不自动打开浏览器调试页。 |
241
415
 
242
416
  ## Mock runtime 边界
243
417
 
244
- `hb-sdk dev` 会把实际小程序页面地址编码到 mock host 的 `mini_url` query 中,由 mock host iframe 加载页面并补齐小程序 bridge 环境。mock host 内置登录/登出、`show`、`hide`、在 Mac 版 APP 中启动等调试按钮,并通过同一份 devtools-only runtime adapter 处理 SDK 能力调用。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP;遇到这种情况时,请在系统浏览器中打开同一个调试页后重试。
418
+ `hb-sdk dev` 会把实际小程序页面地址编码到 mock host 的 `mini_url` query 中,由 mock host iframe 加载页面并补齐小程序 bridge 环境。mock host 内置登录/登出、`show`、`hide`、在 Mac 版 APP 中启动、手机扫码调试等调试入口,并通过同一份 devtools-only runtime adapter 处理 SDK 能力调用。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP;遇到这种情况时,请在系统浏览器中打开同一个调试页后重试。
245
419
 
246
420
  不要为了本地调试再创建独立 mock runtime 包。CLI、模板和 mock host 都归属 `@heybox/hb-sdk`。
247
421
 
248
422
  本地 mock runtime 下的 `network.request()` 会通过 `hb-sdk` 本地 mock network proxy 转发真实 HTTP(S) 请求,用于避免浏览器 CORS 影响本地调试。proxy 不会把黑盒客户端私有协议字段暴露给 iframe 业务代码。
249
423
 
250
- Use `hb-sdk dev` for local browser SDK debugging. Use the Mock runtime host's "在 Mac 版 APP 中启动" button when the page needs to be loaded by the real Heybox mini-program container. If the mock host is open inside Codex, VSCode, or another embedded browser, ask the user to open the same debug page in the system browser before retrying because embedded browsers may block the `heybox://` protocol handoff.
424
+ Use `hb-sdk dev` for local browser SDK debugging. 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. If the mock host is open inside Codex, VSCode, or another embedded browser, ask the user to open the same debug page in the system browser before retrying because embedded browsers may block the `heybox://` protocol handoff.
425
+
426
+ ## Deploy and backend operations
427
+
428
+ ## 部署发布
429
+
430
+ ```bash
431
+ hb-sdk deploy --release-note "修复登录状态展示,补充异常提示"
432
+ hb-sdk deploy --release-note "审核通过后自动发布" --auto-publish
433
+ hb-sdk deploy --skip-build --release-note "复用已有 dist 构建产物"
434
+ hb-sdk deploy --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "测试环境验证"
435
+ hb-sdk deploy --verbose --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "排查预检失败"
436
+ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk deploy --api-base-url http://127.0.0.1:8080 --release-note "本地后台联调"
437
+ ```
438
+
439
+ `hb-sdk deploy` 把预检、构建、上传和提交审核串成一条命令:
440
+
441
+ 1. 读取 `package.json.heybox.miniProgramId`,缺失即报错。
442
+ 2. 校验登录态,需先 `hb-sdk login`。
443
+ 3. 如果需要以公司的名义发布小程序,需先找 @秦浩东 申请小程序开发权限。
444
+ 4. 读取并校验 `--release-note`;TTY 环境缺失时会提示输入,CI / 非 TTY 环境缺失时直接失败。建议让 AI 生成 1-5 条简短发布日志。
445
+ 5. 普通 deploy 先读取 `package.json.version`,登录后、build 前调用版本预检接口;预检通过后才执行 `<pm> run build`。
446
+ 6. `--skip-build` 跳过构建,但会先读取已有 `dist/manifest.json.version`,再调用版本预检接口。
447
+ 7. 解析 `dist/manifest.json`,自动剥离 BOM,并校验 `version` 是合法 SemVer:允许 prerelease,例如 `1.2.3-rc.1`;拒绝 build metadata,例如 `1.2.3+build.1`;拒绝 `0.0.0`。
448
+ 8. 普通 deploy 的 `dist/manifest.json.version` 必须与预检使用的 `package.json.version` 一致,否则失败且不上传。
449
+ 9. 遍历 `dist/` 文件,过滤掉 `manifest.json`、`.DS_Store`、`*.map`;遇到 symbolic link 或 `node_modules` 路径直接报错。
450
+ 10. 4 并发把文件上传到 CDN,默认只展示上传阶段和文件总数;`--verbose` 会展示并发数、bucket / region 和逐文件结果,但不会输出 keys、签名、cookie 或 token。
451
+ 11. 全部上传成功后调用提交审核接口,CLI 输出提交审核成功、发布策略和可用的 preview URL。
452
+
453
+ `mini_program_id` 没有 CLI flag,必须落在 `package.json` 里:
454
+
455
+ ```json
456
+ {
457
+ "heybox": {
458
+ "miniProgramId": "mp_xxxxxxxx"
459
+ }
460
+ }
461
+ ```
462
+
463
+ `manifest.json` 仅作为提交审核接口的 `manifest` 字段提交,不会上传到 CDN。Vite 项目通过 `miniappManifest()` 插件生成;CLI 不会自动注入插件,请在 `vite.config.ts` 中显式挂载。
464
+
465
+ 默认发布策略是 `auto_publish=false`:运营审核通过后需在开放平台手动发布。需要审核通过后自动发布并下架旧线上版本时,使用 `--auto-publish`。
466
+
467
+ 内部测试或预发环境可通过 `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` 只影响 deploy 里的预检、CDN 上传凭证/回调、提交审核;`loginBaseUrl` 用于 `hb-sdk login` 的登录入口,以及 deploy 前校验当前 CLI 登录态是否属于同一个登录环境。开发环境如需给后台请求带 `x-rylai-service-tag` 和 `special_tag`,可在 `packages/hb-sdk/src/cli/config.ts` 里按 `@heybox/hb-types` 的 `RylaiServiceTagConfig` 配置 `default_tag` 或 path-prefix 级 `special_tag`。日志只输出 origin,不输出带身份和签名参数的完整请求 URL。
468
+
469
+ `hb-sdk doctor`、npm latest 检查、mock host 的 `network.request()` 不受这些配置影响。
470
+
471
+ Agent rules:
472
+
473
+ - Use `hb-sdk deploy --release-note <text>` for normal build, upload, and submit-audit flows.
474
+ - Use `--api-base-url <url>` or `HB_SDK_API_BASE_URL` only for deploy backend APIs.
475
+ - Use `--allow-unsafe-api-base-url` or `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` only for local backend debugging against non-Heybox or non-HTTPS API origins.
476
+ - Use `--login-base-url <url>` or `HB_SDK_LOGIN_BASE_URL` for CLI browser login and deploy login-environment validation.
477
+ - Use `packages/hb-sdk/src/cli/config.ts` with `RylaiServiceTagConfig` only when Heybox backend API requests need the development-only `x-rylai-service-tag` header and matching `special_tag` query parameter.
478
+ - Custom base URLs must be origin-only; API origins must be Heybox trusted HTTPS unless the unsafe debug switch is explicit. Do not include path, query, or hash.
479
+ - Do not expect custom base URLs to affect `hb-sdk doctor`, npm latest checks, or mock-host `network.request()`.
251
480
 
252
481
  ## CLI login cache
253
482
 
@@ -255,12 +484,14 @@ Use `hb-sdk dev` for local browser SDK debugging. Use the Mock runtime host's "
255
484
 
256
485
  ```bash
257
486
  hb-sdk login
487
+ hb-sdk login --login-base-url https://login.test.xiaoheihe.cn
258
488
  hb-sdk login status
259
489
  hb-sdk login clear
260
490
  ```
261
491
 
262
492
  - `hb-sdk login` 会打开 `login.xiaoheihe.cn`,通过本地临时回调服务接收登录结果。
263
- - `hb-sdk login status` 只展示脱敏状态、`heyboxId`、登录时间和 cache 路径,不输出 `pkey`、cookie 或完整请求头。
493
+ - `hb-sdk login --login-base-url <url>` 会打开指定登录 origin,并把该登录环境写入 CLI 登录态。
494
+ - `hb-sdk login status` 默认展示脱敏状态、`heyboxId`、`loginBaseUrl` 和登录时间;`--verbose` 额外展示 cache 路径。不输出 `pkey`、cookie 或完整请求头。
264
495
  - `hb-sdk login clear` 只清理 `hb-sdk` 自己命名空间中的 Heybox 登录态。
265
496
 
266
497
  这份 CLI 登录态不会注入 iframe SDK,也不会改变 `hb-sdk dev` 的 mock 用户、`auth.login()`、`user.getInfo()` 或 `network.request()` 行为。
@@ -284,13 +515,13 @@ hb-sdk doctor
284
515
 
285
516
  `doctor` 只诊断,不修改本地文件。需要安装或刷新 skill 时,按输出提示手动执行 `npx skills add`。
286
517
 
287
- | 状态 | 含义 |
288
- | --- | --- |
289
- | `OK` | SDK、远端 latest skill、本机 skill 全部匹配。 |
290
- | `SKILL_MISSING` | 本机没有安装 `hb-sdk` skill。 |
291
- | `SKILL_OUTDATED` | 本机 `skillVersion` 与远端 latest 不一致。 |
292
- | `SDK_MISMATCH` | 当前 SDK 版本与远端 latest skill 声明的 SDK 版本不一致。 |
293
- | `REMOTE_UNAVAILABLE` | 无法读取公开 manifest,诊断失败且不会修改本地文件。 |
518
+ | 状态 | 含义 |
519
+ | -------------------- | -------------------------------------------------------- |
520
+ | `OK` | SDK、远端 latest skill、本机 skill 全部匹配。 |
521
+ | `SKILL_MISSING` | 本机没有安装 `hb-sdk` skill。 |
522
+ | `SKILL_OUTDATED` | 本机 `skillVersion` 与远端 latest 不一致。 |
523
+ | `SDK_MISMATCH` | 当前 SDK 版本与远端 latest skill 声明的 SDK 版本不一致。 |
524
+ | `REMOTE_UNAVAILABLE` | 无法读取公开 manifest,诊断失败且不会修改本地文件。 |
294
525
 
295
526
  手动安装或刷新 skill:
296
527
 
@@ -311,7 +542,7 @@ Agent rules:
311
542
 
312
543
  ## 版本提醒
313
544
 
314
- `hb-sdk create`、`hb-sdk dev`、`hb-sdk login`、`hb-sdk login status`、`hb-sdk login clear` 会在命令成功执行后检查 npm registry 上 `@heybox/hb-sdk` 的 `latest` 版本。检查结果会缓存 24 小时;检查失败会静默跳过;`CI=true` 时会跳过检查,避免污染 CI 日志。`hb-sdk doctor` 不会附带版本提醒,避免把 skill 诊断输出和升级提示混在一起。本地可通过 `HB_SDK_NO_UPDATE_CHECK=1` 禁用检查。
545
+ `hb-sdk create`、`hb-sdk dev`、`hb-sdk deploy`、`hb-sdk login`、`hb-sdk login status`、`hb-sdk login clear`、`hb-sdk doctor` 会在命令成功执行后检查 npm registry 上 `@heybox/hb-sdk` 的 `latest` 版本。检查结果会缓存 24 小时;检查失败会静默跳过;`CI=true` 时会跳过检查,避免污染 CI 日志。`hb-sdk doctor` 已经诊断出 `SDK_MISMATCH` 时不会再追加统一提醒,避免同一次输出里重复提示升级 SDK。`hb-sdk --version` / `hb-sdk -V` 也会执行同一套检查,但 stdout 只输出版本号,升级提醒继续按 warn 级别写到 stderr。本地可通过 `HB_SDK_NO_UPDATE_CHECK=1` 禁用检查。
315
546
 
316
547
  ## Repository validation commands
317
548
 
@@ -346,11 +577,15 @@ npm run build
346
577
  npm run deploy
347
578
  ```
348
579
 
580
+ ## 依赖说明
581
+
582
+ `@heybox/hb-sdk` 是小程序页面运行时会 import 的 SDK,因此模板把它放在 `dependencies`。Vite、TypeScript、Vitest 等只参与本地开发、测试或构建的工具放在 `devDependencies`。
583
+
349
584
  ## 开发模式
350
585
 
351
- - `npm run dev`:启动本地 Vite 服务和 `hb-sdk` 内置 mock runtime host,适合本地调试 SDK 能力;调试页内可点击按钮在 Mac 版 APP 中启动同一页面。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP,需要时请在系统浏览器中打开同一个调试页后重试。
586
+ - `npm run dev`:启动本地 Vite 服务和 `hb-sdk` 内置 mock runtime host,适合本地调试 SDK 能力;调试页内可点击按钮在 Mac 版 APP 中启动同一页面,也可以选择局域网网卡后用手机小黑盒 APP 扫码调试。手机需要与电脑处在同一局域网,并使用支持小程序调试壳的新版小黑盒 APP。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP,需要时请在系统浏览器中打开同一个调试页后重试。
352
587
  - `npm run build`:先执行 TypeScript 检查,再构建生产产物。
353
- - `npm run deploy`:构建并发布当前小程序。发布前需要先把 `package.json` 中的 `heybox.miniProgramId` 改成后台分配的真实小程序 id,并执行过 `npx hb-sdk login`。
588
+ - `npm run deploy -- --release-note "..."`:构建、上传并提交当前小程序版本审核。部署前需要先把 `package.json` 中的 `heybox.miniProgramId` 改成后台分配的真实小程序 id,并执行过 `npx hb-sdk login`;默认审核通过后需在开放平台手动发布,如需审核通过后自动发布可追加 `--auto-publish`。
354
589
 
355
590
  ## 更多能力
356
591
 
@@ -202,6 +202,7 @@ const cliDevSection = [
202
202
  extractSection(cliGuide, '## 本地开发模式'),
203
203
  extractSection(cliGuide, '## Mock runtime 边界'),
204
204
  ].filter(Boolean).join('\n\n');
205
+ const cliDeploySection = extractSection(cliGuide, '## 部署发布');
205
206
  const cliLoginSection = extractSection(cliGuide, '## CLI 登录态');
206
207
  const cliDoctorSection = extractSection(cliGuide, '## Agent Skill doctor');
207
208
  const cliUpdateSection = extractSection(cliGuide, '## 版本提醒');
@@ -294,6 +295,7 @@ files.set('cli.md', `${header('CLI reference', [
294
295
  ['Command surface', 'command-surface'],
295
296
  ['Create a mini-program template', 'create-a-mini-program-template'],
296
297
  ['Local dev and mock runtime', 'local-dev-and-mock-runtime'],
298
+ ['Deploy and backend operations', 'deploy-and-backend-operations'],
297
299
  ['CLI login cache', 'cli-login-cache'],
298
300
  ['Agent Skill doctor', 'agent-skill-doctor'],
299
301
  ['Update reminders', 'update-reminders'],
@@ -326,7 +328,21 @@ Agent rules:
326
328
 
327
329
  ${cliDevSection}
328
330
 
329
- Use \`hb-sdk dev\` for local browser SDK debugging. Use the Mock runtime host's "在 Mac 版 APP 中启动" button when the page needs to be loaded by the real Heybox mini-program container. If the mock host is open inside Codex, VSCode, or another embedded browser, ask the user to open the same debug page in the system browser before retrying because embedded browsers may block the \`heybox://\` protocol handoff.
331
+ Use \`hb-sdk dev\` for local browser SDK debugging. 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. If the mock host is open inside Codex, VSCode, or another embedded browser, ask the user to open the same debug page in the system browser before retrying because embedded browsers may block the \`heybox://\` protocol handoff.
332
+
333
+ ## Deploy and backend operations
334
+
335
+ ${cliDeploySection}
336
+
337
+ Agent rules:
338
+
339
+ - Use \`hb-sdk deploy --release-note <text>\` for normal build, upload, and submit-audit flows.
340
+ - Use \`--api-base-url <url>\` or \`HB_SDK_API_BASE_URL\` only for deploy backend APIs.
341
+ - Use \`--allow-unsafe-api-base-url\` or \`HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1\` only for local backend debugging against non-Heybox or non-HTTPS API origins.
342
+ - Use \`--login-base-url <url>\` or \`HB_SDK_LOGIN_BASE_URL\` for CLI browser login and deploy login-environment validation.
343
+ - Use \`packages/hb-sdk/src/cli/config.ts\` with \`RylaiServiceTagConfig\` only when Heybox backend API requests need the development-only \`x-rylai-service-tag\` header and matching \`special_tag\` query parameter.
344
+ - Custom base URLs must be origin-only; API origins must be Heybox trusted HTTPS unless the unsafe debug switch is explicit. Do not include path, query, or hash.
345
+ - Do not expect custom base URLs to affect \`hb-sdk doctor\`, npm latest checks, or mock-host \`network.request()\`.
330
346
 
331
347
  ## CLI login cache
332
348
 
package/skill/skill.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "hb-sdk",
3
- "skillVersion": "0.3.3+skill.cb20a91e9529",
3
+ "skillVersion": "0.4.1+skill.702e134a243e",
4
4
  "sdk": {
5
5
  "package": "@heybox/hb-sdk",
6
- "version": "0.3.3",
7
- "compatibility": "0.3.3"
6
+ "version": "0.4.1",
7
+ "compatibility": "0.4.1"
8
8
  },
9
9
  "source": "https://open.xiaoheihe.cn/agent-skills/hb-sdk",
10
- "integrity": "sha256-cb20a91e95291420a1f1d1b8a1601bbf21ba8bcd4dac64265d0c033e009d9456"
10
+ "integrity": "sha256-702e134a243e9f6f9c11b9df1c5db45daebf2b98a270753a89b65afe5f52f7a2"
11
11
  }
package/types/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export type { MiniProgramEventHandler, MiniProgramEventName, MiniProgramEventPay
6
6
  export type { LoginPayload, LoginResult, MiniProgramAuthModule } from './modules/auth';
7
7
  export type { GetUserInfoPayload, GetUserInfoResult, MiniProgramUserInfo, MiniProgramUserInfoResult, MiniProgramUserModule, } from './modules/user';
8
8
  export type { MiniProgramScreenshotOptions, MiniProgramScreenshotRect, MiniProgramShareChannel, MiniProgramShareModule, MiniProgramShowShareMenuOptions, ScreenshotPayload, ScreenshotResult, ShowShareMenuPayload, ShowShareMenuResult, } from './modules/share';
9
- export type { GetWindowInfoPayload, GetWindowInfoResult, MiniProgramSafeArea, MiniProgramViewportModule, MiniProgramWindowInfoResult, } from './modules/viewport';
9
+ export type { GetWindowInfoPayload, GetWindowInfoResult, MiniProgramNavigationBarForegroundStyle, MiniProgramSafeArea, MiniProgramSetNavigationBarStyleOptions, MiniProgramViewportModule, MiniProgramWindowInfoResult, SetNavigationBarStylePayload, SetNavigationBarStyleResult, } from './modules/viewport';
10
10
  export type { GetStoragePayload, GetStorageResult, MiniProgramStorageModule, SetStoragePayload, } from './modules/storage';
11
11
  export type { MiniProgramNetworkHeaders, MiniProgramNetworkModule, MiniProgramNetworkParams, MiniProgramNetworkRequestConfig, MiniProgramNetworkRequestMethod, MiniProgramNetworkResponse, MiniProgramNetworkValidateStatus, NetworkRequestPayload, NetworkResponsePayload, } from './modules/network';
12
12
  import { off, on, ready } from './core/singleton';
@@ -8,7 +8,8 @@ export interface ParseMiniappManifestResult {
8
8
  hadBom: boolean;
9
9
  }
10
10
  export declare function isValidMiniappManifestVersion(version: string): boolean;
11
- export declare function getMiniappManifestBuildWarning(version: string): string | undefined;
11
+ export declare function validateMiniappPackageVersionForBuild(version: string): string;
12
+ export declare function validateMiniappManifestVersion(version: unknown, sourceLabel?: string): string;
12
13
  export declare function renderMiniappManifest(manifest: MiniappManifest): string;
13
14
  export declare function parseMiniappManifestJson(raw: string, sourceLabel?: string): ParseMiniappManifestResult;
14
15
  export declare function validateMiniappManifestForDeploy(manifest: MiniappManifest): string;