@heybox/hb-sdk 0.4.4 → 0.4.5

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.
@@ -20,6 +20,7 @@
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
22
  - [Deploy and backend operations](#deploy-and-backend-operations)
23
+ - [Remote management commands](#remote-management-commands)
23
24
  - [CLI login cache](#cli-login-cache)
24
25
  - [Agent Skill doctor](#agent-skill-doctor)
25
26
  - [Update reminders](#update-reminders)
@@ -35,341 +36,36 @@ The CLI, templates, and mock host are owned by `@heybox/hb-sdk`. Do not create a
35
36
 
36
37
  ## Command surface
37
38
 
38
- ```ts
39
- import { Command, CommanderError, InvalidArgumentError } from 'commander';
40
- import { printUpdateReminder as defaultPrintUpdateReminder } from './update-check';
41
- import { printError as defaultPrintError } from './utils/errors';
42
- import { createCliLogger, type CliLogger } from './utils/logger';
43
- import { getCliVersion } from './version';
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
-
53
- export interface CliCommandHandlers {
54
- clearLoginStatus: ClearLoginStatus;
55
- loginToHeybox: LoginToHeybox;
56
- printLoginStatus: PrintLoginStatus;
57
- printUpdateReminder: typeof defaultPrintUpdateReminder;
58
- runCreateCommand: RunCreateCommand;
59
- runDeployCommand: RunDeployCommand;
60
- runDevCommand: RunDevCommand;
61
- runDoctorCommand: RunDoctorCommand;
62
- }
63
-
64
- export interface CliRuntimeOptions extends Partial<CliCommandHandlers> {
65
- argv?: string[];
66
- createLogger?: (options: { verbose: boolean }) => CliLogger;
67
- logger?: CliLogger;
68
- printError?: typeof defaultPrintError;
69
- process?: Pick<NodeJS.Process, 'exit'>;
70
- }
71
-
72
- export async function runCli(options: CliRuntimeOptions = {}) {
73
- const processLike = options.process ?? process;
74
- const argv = options.argv ?? process.argv;
75
- const verbose = hasVerboseArg(argv);
76
-
77
- try {
78
- await createCliProgram(options).parseAsync(argv);
79
- } catch (error) {
80
- if (error instanceof CommanderError && error.exitCode === 0) {
81
- processLike.exit(0);
82
- return;
83
- }
84
-
85
- if (!(error instanceof CommanderError)) {
86
- (options.printError ?? defaultPrintError)(error, { logger: resolveStandaloneLogger(options, verbose), verbose });
87
- }
88
-
89
- processLike.exit(error instanceof CommanderError ? error.exitCode : 1);
90
- }
91
- }
92
-
93
- export function createCliProgram(overrides: Partial<CliCommandHandlers> & Pick<CliRuntimeOptions, 'createLogger' | 'logger'> = {}) {
94
- const handlers: CliCommandHandlers = {
95
- clearLoginStatus: defaultClearLoginStatus,
96
- loginToHeybox: defaultLoginToHeybox,
97
- printLoginStatus: defaultPrintLoginStatus,
98
- printUpdateReminder: defaultPrintUpdateReminder,
99
- runCreateCommand: defaultRunCreateCommand,
100
- runDeployCommand: defaultRunDeployCommand,
101
- runDevCommand: defaultRunDevCommand,
102
- runDoctorCommand: defaultRunDoctorCommand,
103
- ...overrides,
104
- };
105
- const program = new Command();
106
- const resolveLogger = createCommandLoggerResolver(overrides);
107
-
108
- program
109
- .name('hb-sdk')
110
- .description('hb-sdk developer tools')
111
- .version(getCliVersion())
112
- .option('-v, --verbose', '输出详细调试信息')
113
- .showHelpAfterError()
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
- );
229
-
230
- return program;
231
- }
232
-
233
- function addVerboseOption<T extends Command>(command: T): T {
234
- return command.option('-v, --verbose', '输出详细调试信息') as T;
235
- }
236
-
237
- function hasVerboseArg(argv: string[]) {
238
- return argv.includes('--verbose') || argv.includes('-v');
239
- }
240
-
241
- type ResolveCommandLogger = (commandOrVerbose?: Command | boolean) => CliLogger;
242
-
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);
345
- }
346
-
347
- function withUpdateReminder<Args extends unknown[]>(
348
- action: (...args: Args) => Promise<void>,
349
- printUpdateReminder: typeof defaultPrintUpdateReminder,
350
- resolveLogger: ResolveCommandLogger,
351
- ) {
352
- return async (...args: Args) => {
353
- await action(...args);
354
- await printUpdateReminder({ logger: resolveLogger(readCommandFromActionArgs(args)) });
355
- };
356
- }
357
-
358
- function readCommandFromActionArgs(args: unknown[]) {
359
- const lastArg = args[args.length - 1];
360
- return lastArg instanceof Command ? lastArg : undefined;
361
- }
362
-
363
- function parsePositivePort(value: string) {
364
- const parsed = Number(value);
365
- if (!Number.isInteger(parsed) || parsed <= 0) {
366
- throw new InvalidArgumentError('必须是正整数端口号');
367
- }
368
-
369
- return parsed;
370
- }
39
+ ```text
40
+ hb-sdk create <project-name>
41
+ hb-sdk dev [--port <port>] [--mock-port <port>] [--runtime-url <url>] [--no-open]
42
+ hb-sdk login [--login-base-url <url>]
43
+ hb-sdk login status
44
+ hb-sdk login clear
45
+ hb-sdk doctor
46
+ hb-sdk remote access
47
+ hb-sdk remote list [--status <status>] [--keyword <text>]
48
+ hb-sdk remote create --name <name> [--preview-image-url <url>] [--force-bind]
49
+ hb-sdk remote bind <mini-program-id> [--force]
50
+ hb-sdk remote info
51
+ hb-sdk remote update [--name <name>] [--preview-image-url <url>]
52
+ hb-sdk remote allowlist list
53
+ hb-sdk remote allowlist add <heybox-id...>
54
+ hb-sdk remote allowlist remove <heybox-id...>
55
+ hb-sdk remote allowlist set <heybox-id...>
56
+ hb-sdk remote deploy --release-note <text> [--skip-build] [--auto-publish]
57
+ hb-sdk remote versions
58
+ hb-sdk remote preview <version>
59
+ hb-sdk remote release <version> [--yes]
60
+ hb-sdk remote withdraw <version> [--yes] [--reason <text>]
61
+ hb-sdk remote take-down [--yes]
62
+ hb-sdk remote reopen [--yes]
63
+
64
+ Removed: hb-sdk deploy
371
65
  ```
372
66
 
67
+ Top-level `hb-sdk deploy` has been hard-cut and must not be documented as a valid compatibility alias. Keep `hb-sdk login` top-level because it manages CLI login state, not a specific remote mini-program.
68
+
373
69
  ## Create a mini-program template
374
70
 
375
71
  ## 创建外部小程序模板
@@ -428,24 +124,24 @@ Use `hb-sdk dev` for local browser SDK debugging. Use the Mock runtime host's "
428
124
  ## 部署发布
429
125
 
430
126
  ```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 "本地后台联调"
127
+ hb-sdk remote deploy --release-note "修复登录状态展示,补充异常提示"
128
+ hb-sdk remote deploy --release-note "审核通过后自动发布" --auto-publish
129
+ hb-sdk remote deploy --skip-build --release-note "复用已有 dist 构建产物"
130
+ hb-sdk remote deploy --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "测试环境验证"
131
+ hb-sdk remote deploy --verbose --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "排查预检失败"
132
+ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://127.0.0.1:8080 --release-note "本地后台联调"
437
133
  ```
438
134
 
439
- `hb-sdk deploy` 把预检、构建、上传和提交审核串成一条命令:
135
+ `hb-sdk remote deploy` 把预检、构建、上传和提交审核串成一条命令。顶层 `hb-sdk deploy` 已硬切删除,不再作为兼容别名保留:
440
136
 
441
137
  1. 读取 `package.json.heybox.miniProgramId`,缺失即报错。
442
138
  2. 校验登录态,需先 `hb-sdk login`。
443
139
  3. 如果需要以公司的名义发布小程序,需先找 @秦浩东 申请小程序开发权限。
444
140
  4. 读取并校验 `--release-note`;TTY 环境缺失时会提示输入,CI / 非 TTY 环境缺失时直接失败。建议让 AI 生成 1-5 条简短发布日志。
445
- 5. 普通 deploy 先读取 `package.json.version`,登录后、build 前调用版本预检接口;预检通过后才执行 `<pm> run build`。
141
+ 5. 普通 remote deploy 先读取 `package.json.version`,登录后、build 前调用版本预检接口;预检通过后才执行 `<pm> run build`。
446
142
  6. `--skip-build` 跳过构建,但会先读取已有 `dist/manifest.json.version`,再调用版本预检接口。
447
143
  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` 一致,否则失败且不上传。
144
+ 8. 普通 remote deploy 的 `dist/manifest.json.version` 必须与预检使用的 `package.json.version` 一致,否则失败且不上传。
449
145
  9. 遍历 `dist/` 文件,过滤掉 `manifest.json`、`.DS_Store`、`*.map`;遇到 symbolic link 或 `node_modules` 路径直接报错。
450
146
  10. 4 并发把文件上传到 CDN,默认只展示上传阶段和文件总数;`--verbose` 会展示并发数、bucket / region 和逐文件结果,但不会输出 keys、签名、cookie 或 token。
451
147
  11. 全部上传成功后调用提交审核接口,CLI 输出提交审核成功、发布策略和可用的 preview URL。
@@ -462,22 +158,63 @@ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk deploy --api-base-url http://127.0.0.1
462
158
 
463
159
  `manifest.json` 仅作为提交审核接口的 `manifest` 字段提交,不会上传到 CDN。Vite 项目通过 `miniappManifest()` 插件生成;CLI 不会自动注入插件,请在 `vite.config.ts` 中显式挂载。小程序构建产物需要使用相对资源路径;`hb-sdk create` 模板会显式配置 `base: './'`,未配置 `base` 的项目也会由 `miniappManifest()` 在 build 时默认补成 `./`。
464
160
 
465
- 默认发布策略是 `auto_publish=false`:运营审核通过后需在开放平台手动发布。需要审核通过后自动发布并下架旧线上版本时,使用 `--auto-publish`。
161
+ 默认发布策略是 `auto_publish=false`:运营审核通过后使用 `hb-sdk remote versions` 查看版本状态,再用 `hb-sdk remote release <version>` 发布。需要审核通过后自动发布并下架旧线上版本时,使用 `--auto-publish`。如需让指定用户预览未发布候选版本,使用 `hb-sdk remote allowlist add <heybox_id>` 管理预览白名单。
466
162
 
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。
163
+ 内部测试或预发环境可通过 `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`,可在 `packages/hb-sdk/src/cli/config.ts` 里按 `@heybox/hb-types` 的 `RylaiServiceTagConfig` 配置 `default_tag` 或 path-prefix 级 `special_tag`。日志只输出 origin,不输出带身份和签名参数的完整请求 URL。
468
164
 
469
165
  `hb-sdk doctor`、npm latest 检查、mock host 的 `network.request()` 不受这些配置影响。
470
166
 
471
167
  Agent rules:
472
168
 
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.
169
+ - Use `hb-sdk remote deploy --release-note <text>` for normal build, upload, and submit-audit flows.
170
+ - Never recommend top-level `hb-sdk deploy`; it has been removed rather than retained as a compatibility alias.
171
+ - 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.
172
+ - Use `hb-sdk remote allowlist add <heybox_id>` when preview access needs to be granted.
173
+ - Use `--api-base-url <url>` or `HB_SDK_API_BASE_URL` for remote platform backend APIs.
475
174
  - 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.
175
+ - Use `--login-base-url <url>` or `HB_SDK_LOGIN_BASE_URL` for CLI browser login and remote command login-environment validation.
477
176
  - 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
177
  - 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
178
  - Do not expect custom base URLs to affect `hb-sdk doctor`, npm latest checks, or mock-host `network.request()`.
480
179
 
180
+ ## Remote management commands
181
+
182
+ ## 远端管理命令
183
+
184
+ 远端平台操作统一放在 `hb-sdk remote` 命令组下,默认作用于当前项目绑定的小程序,也就是 `package.json.heybox.miniProgramId`。`remote list` 只用于发现可管理的小程序;会改变远端状态的命令仍然只操作当前绑定的小程序,不接受临时 `mini_program_id` 参数。
185
+
186
+ 常用命令:
187
+
188
+ ```bash
189
+ hb-sdk remote access
190
+ hb-sdk remote list
191
+ hb-sdk remote create --name "我的小程序"
192
+ hb-sdk remote bind mp_xxxxxxxx
193
+ hb-sdk remote info
194
+ hb-sdk remote update --name "新名称"
195
+ hb-sdk remote allowlist add 12345678
196
+ hb-sdk remote versions
197
+ hb-sdk remote preview 1.2.3
198
+ hb-sdk remote release 1.2.3
199
+ hb-sdk remote withdraw 1.2.3 --reason "需要修复说明"
200
+ hb-sdk remote take-down
201
+ hb-sdk remote reopen
202
+ ```
203
+
204
+ `hb-sdk remote create` 会创建远端用户小程序并写入当前项目绑定;已有绑定时必须传 `--force-bind` 才能覆盖。`hb-sdk remote bind <mini-program-id>` 会先校验当前 CLI 用户可管理目标小程序,再写入本地配置;`--force` 只允许覆盖本地绑定,不跳过远端校验。
205
+
206
+ `hb-sdk remote release`、`hb-sdk remote withdraw`、`hb-sdk remote take-down` 和 `hb-sdk remote reopen` 会改变审核、发布或用户侧可见状态。交互式终端会展示小程序 id、名称、当前状态、目标版本和操作,再要求确认;非 TTY 环境必须传 `--yes`。
207
+
208
+ 所有 `hb-sdk remote` 子命令都支持 `--json`。开启后 stdout 只输出一个 JSON 对象;进度、警告、版本提醒和 verbose 诊断不能污染 stdout。
209
+
210
+ Agent rules:
211
+
212
+ - Use `hb-sdk remote create --name <name>` for create-and-bind and `hb-sdk remote bind <mini-program-id>` for binding an existing manageable remote mini-program.
213
+ - Use `hb-sdk remote info`, `hb-sdk remote update`, `hb-sdk remote access`, `hb-sdk remote list`, `hb-sdk remote versions`, `hb-sdk remote preview <version>`, and `hb-sdk remote allowlist ...` instead of sending users to Open when a matching CLI command exists.
214
+ - Treat `hb-sdk remote list` as discovery only. Dangerous write commands still target the bound mini-program from `package.json.heybox.miniProgramId`.
215
+ - Require confirmation or `--yes` for `hb-sdk remote release`, `hb-sdk remote withdraw`, `hb-sdk remote take-down`, and `hb-sdk remote reopen`.
216
+ - Use `--json` for script consumption and keep stdout as exactly one JSON object.
217
+
481
218
  ## CLI login cache
482
219
 
483
220
  ## CLI 登录态
@@ -542,7 +279,7 @@ Agent rules:
542
279
 
543
280
  ## 版本提醒
544
281
 
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` 禁用检查。
282
+ `hb-sdk create`、`hb-sdk dev`、`hb-sdk remote ...`、`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` 会直接请求 npm registry 获取 latest,不读取本地缓存;stdout 只输出版本号,升级提醒继续按 warn 级别写到 stderr。本地可通过 `HB_SDK_NO_UPDATE_CHECK=1` 禁用检查。
546
283
 
547
284
  ## Repository validation commands
548
285
 
@@ -585,7 +322,7 @@ npm run deploy
585
322
 
586
323
  - `npm run dev`:启动本地 Vite 服务和 `hb-sdk` 内置 mock runtime host,适合本地调试 SDK 能力;调试页内可点击按钮在 Mac 版 APP 中启动同一页面,也可以选择局域网网卡后用手机小黑盒 APP 扫码调试。手机需要与电脑处在同一局域网,并使用支持小程序调试壳的新版小黑盒 APP。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP,需要时请在系统浏览器中打开同一个调试页后重试。
587
324
  - `npm run build`:先执行 TypeScript 检查,再构建生产产物。
588
- - `npm run deploy -- --release-note "..."`:构建、上传并提交当前小程序版本审核。部署前需要先把 `package.json` 中的 `heybox.miniProgramId` 改成后台分配的真实小程序 id,并执行过 `npx hb-sdk login`;默认审核通过后需在开放平台手动发布,如需审核通过后自动发布可追加 `--auto-publish`。
325
+ - `npm run deploy -- --release-note "..."`:运行 `hb-sdk remote deploy`,构建、上传并提交当前小程序版本审核。部署前需要先通过 `hb-sdk remote create --name "..."` 创建并绑定远端小程序,或用 `hb-sdk remote bind <mini-program-id>` 绑定已有小程序,并执行过 `npx hb-sdk login`;默认审核通过后用 `hb-sdk remote versions` 查看状态,再用 `hb-sdk remote release <version>` 发布,如需审核通过后自动发布可追加 `--auto-publish`。顶层 `hb-sdk deploy` 已删除,不再作为兼容别名保留。
589
326
 
590
327
  ## 更多能力
591
328
 
@@ -203,9 +203,35 @@ const cliDevSection = [
203
203
  extractSection(cliGuide, '## Mock runtime 边界'),
204
204
  ].filter(Boolean).join('\n\n');
205
205
  const cliDeploySection = extractSection(cliGuide, '## 部署发布');
206
+ const cliRemoteSection = extractSection(cliGuide, '## 远端管理命令');
206
207
  const cliLoginSection = extractSection(cliGuide, '## CLI 登录态');
207
208
  const cliDoctorSection = extractSection(cliGuide, '## Agent Skill doctor');
208
209
  const cliUpdateSection = extractSection(cliGuide, '## 版本提醒');
210
+ const cliCommandSurface = `hb-sdk create <project-name>
211
+ hb-sdk dev [--port <port>] [--mock-port <port>] [--runtime-url <url>] [--no-open]
212
+ hb-sdk login [--login-base-url <url>]
213
+ hb-sdk login status
214
+ hb-sdk login clear
215
+ hb-sdk doctor
216
+ hb-sdk remote access
217
+ hb-sdk remote list [--status <status>] [--keyword <text>]
218
+ hb-sdk remote create --name <name> [--preview-image-url <url>] [--force-bind]
219
+ hb-sdk remote bind <mini-program-id> [--force]
220
+ hb-sdk remote info
221
+ hb-sdk remote update [--name <name>] [--preview-image-url <url>]
222
+ hb-sdk remote allowlist list
223
+ hb-sdk remote allowlist add <heybox-id...>
224
+ hb-sdk remote allowlist remove <heybox-id...>
225
+ hb-sdk remote allowlist set <heybox-id...>
226
+ hb-sdk remote deploy --release-note <text> [--skip-build] [--auto-publish]
227
+ hb-sdk remote versions
228
+ hb-sdk remote preview <version>
229
+ hb-sdk remote release <version> [--yes]
230
+ hb-sdk remote withdraw <version> [--yes] [--reason <text>]
231
+ hb-sdk remote take-down [--yes]
232
+ hb-sdk remote reopen [--yes]
233
+
234
+ Removed: hb-sdk deploy`;
209
235
 
210
236
  const files = new Map();
211
237
 
@@ -296,6 +322,7 @@ files.set('cli.md', `${header('CLI reference', [
296
322
  ['Create a mini-program template', 'create-a-mini-program-template'],
297
323
  ['Local dev and mock runtime', 'local-dev-and-mock-runtime'],
298
324
  ['Deploy and backend operations', 'deploy-and-backend-operations'],
325
+ ['Remote management commands', 'remote-management-commands'],
299
326
  ['CLI login cache', 'cli-login-cache'],
300
327
  ['Agent Skill doctor', 'agent-skill-doctor'],
301
328
  ['Update reminders', 'update-reminders'],
@@ -311,7 +338,9 @@ The CLI, templates, and mock host are owned by \`${packageJson.name}\`. Do not c
311
338
 
312
339
  ## Command surface
313
340
 
314
- ${fenced('ts', cliEntry)}
341
+ ${fenced('text', cliCommandSurface)}
342
+
343
+ Top-level \`hb-sdk deploy\` has been hard-cut and must not be documented as a valid compatibility alias. Keep \`hb-sdk login\` top-level because it manages CLI login state, not a specific remote mini-program.
315
344
 
316
345
  ## Create a mini-program template
317
346
 
@@ -336,14 +365,29 @@ ${cliDeploySection}
336
365
 
337
366
  Agent rules:
338
367
 
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.
368
+ - Use \`hb-sdk remote deploy --release-note <text>\` for normal build, upload, and submit-audit flows.
369
+ - Never recommend top-level \`hb-sdk deploy\`; it has been removed rather than retained as a compatibility alias.
370
+ - 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.
371
+ - Use \`hb-sdk remote allowlist add <heybox_id>\` when preview access needs to be granted.
372
+ - Use \`--api-base-url <url>\` or \`HB_SDK_API_BASE_URL\` for remote platform backend APIs.
341
373
  - 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.
374
+ - Use \`--login-base-url <url>\` or \`HB_SDK_LOGIN_BASE_URL\` for CLI browser login and remote command login-environment validation.
343
375
  - 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
376
  - 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
377
  - Do not expect custom base URLs to affect \`hb-sdk doctor\`, npm latest checks, or mock-host \`network.request()\`.
346
378
 
379
+ ## Remote management commands
380
+
381
+ ${cliRemoteSection}
382
+
383
+ Agent rules:
384
+
385
+ - Use \`hb-sdk remote create --name <name>\` for create-and-bind and \`hb-sdk remote bind <mini-program-id>\` for binding an existing manageable remote mini-program.
386
+ - Use \`hb-sdk remote info\`, \`hb-sdk remote update\`, \`hb-sdk remote access\`, \`hb-sdk remote list\`, \`hb-sdk remote versions\`, \`hb-sdk remote preview <version>\`, and \`hb-sdk remote allowlist ...\` instead of sending users to Open when a matching CLI command exists.
387
+ - Treat \`hb-sdk remote list\` as discovery only. Dangerous write commands still target the bound mini-program from \`package.json.heybox.miniProgramId\`.
388
+ - Require confirmation or \`--yes\` for \`hb-sdk remote release\`, \`hb-sdk remote withdraw\`, \`hb-sdk remote take-down\`, and \`hb-sdk remote reopen\`.
389
+ - Use \`--json\` for script consumption and keep stdout as exactly one JSON object.
390
+
347
391
  ## CLI login cache
348
392
 
349
393
  ${cliLoginSection}
package/skill/skill.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "hb-sdk",
3
- "skillVersion": "0.4.4+skill.77f95b6757e8",
3
+ "skillVersion": "0.4.5+skill.f7eeb07997a5",
4
4
  "sdk": {
5
5
  "package": "@heybox/hb-sdk",
6
- "version": "0.4.4",
7
- "compatibility": "0.4.4"
6
+ "version": "0.4.5",
7
+ "compatibility": "0.4.5"
8
8
  },
9
9
  "source": "https://open.xiaoheihe.cn/agent-skills/hb-sdk",
10
- "integrity": "sha256-77f95b6757e86f4fd6ec2bc865bab4a3781403d5e1db9b3e729407a7fbd7f01a"
10
+ "integrity": "sha256-f7eeb07997a5926a9f1d636d9e4d46ad412635a66da4a444095970ed17857c0e"
11
11
  }
@@ -1,7 +1,20 @@
1
1
  export declare const MINIAPP_UPLOAD_SCOPE = "activity";
2
2
  export declare const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
3
+ export declare const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = "/mall/developer/user_miniprogram/access_status";
4
+ export declare const LIST_USER_MINIPROGRAM_API_PATH = "/mall/developer/user_miniprogram/list";
5
+ export declare const CREATE_USER_MINIPROGRAM_API_PATH = "/mall/developer/user_miniprogram/create";
6
+ export declare const UPDATE_USER_MINIPROGRAM_API_PATH = "/mall/developer/user_miniprogram/update";
7
+ export declare const DETAIL_USER_MINIPROGRAM_API_PATH = "/mall/developer/user_miniprogram/detail";
8
+ export declare const USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH = "/mall/developer/user_miniprogram/preview_allowlist";
9
+ export declare const UPDATE_USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH = "/mall/developer/user_miniprogram/preview_allowlist/update";
3
10
  export declare const PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH = "/mall/developer/user_miniprogram/version/precheck";
4
11
  export declare const SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH = "/mall/developer/user_miniprogram/version/submit_audit";
12
+ export declare const USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH = "/mall/developer/user_miniprogram/version/preview_info";
13
+ export declare const WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH = "/mall/developer/user_miniprogram/version/withdraw";
14
+ export declare const RELEASE_USER_MINIPROGRAM_VERSION_API_PATH = "/mall/developer/user_miniprogram/version/release";
15
+ export declare const TAKE_DOWN_USER_MINIPROGRAM_API_PATH = "/mall/developer/user_miniprogram/take_down";
16
+ export declare const REOPEN_USER_MINIPROGRAM_API_PATH = "/mall/developer/user_miniprogram/reopen";
17
+ export declare const LIST_USER_MINIPROGRAM_VERSION_API_PATH = "/mall/developer/user_miniprogram/version/list";
5
18
  export { isValidMiniappManifestVersion as isValidVersion } from '../miniapp-manifest/schema';
6
19
  export declare function normalizeRelativePath(relativePath: string): string;
7
20
  export declare function relativePathContainsNodeModulesSegment(relativePath: string): boolean;