@heybox/hb-sdk 0.9.2-alpha.6 → 0.9.2-alpha.7

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 (29) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/dist/cli-chunks/{build-ffQNXsFk.cjs → build-Do22AWbq.cjs} +5 -5
  4. package/dist/cli-chunks/{context-DlFt5Q7p.cjs → context-DQhjWa7X.cjs} +2 -2
  5. package/dist/cli-chunks/{create-BtmA7deR.cjs → create-QuI_mw8x.cjs} +1 -1
  6. package/dist/cli-chunks/{dev-CNDIlDmL.cjs → dev-KAhj5UTy.cjs} +75 -66
  7. package/dist/cli-chunks/{doctor-BkFUZH17.cjs → doctor-DNoQWBpo.cjs} +1 -1
  8. package/dist/cli-chunks/{index-DrlSotEe.cjs → index-DZUYwb3h.cjs} +1 -1
  9. package/dist/cli-chunks/{index-CN_l895H.cjs → index-bZIxID9N.cjs} +16 -16
  10. package/dist/cli-chunks/{index.esm-mmJekGrr.cjs → index.esm-EWleN3S5.cjs} +6 -6
  11. package/dist/cli-chunks/{login-qupR7tLT.cjs → login-BYM3Nwau.cjs} +1 -1
  12. package/dist/cli-chunks/{project-vite-CNubrzp5.cjs → project-vite-6eLmb4Em.cjs} +1 -1
  13. package/dist/cli-chunks/{remote-CbZlAq6Z.cjs → remote-dvOjaxJu.cjs} +6 -6
  14. package/dist/cli-chunks/{runtime-gate-BcKHky95.cjs → runtime-gate-BKc2zPV-.cjs} +2 -2
  15. package/dist/cli-chunks/{runtime-permission-env-BQ7lPfhg.cjs → runtime-permission-env-B9SqoP85.cjs} +2 -2
  16. package/dist/cli-chunks/{skill-KmRvlkMJ.cjs → skill-DFXZ0SK_.cjs} +2 -2
  17. package/dist/cli-chunks/{version-ai8lcNbJ.cjs → version-CwEOrhL1.cjs} +1 -1
  18. package/dist/cli.cjs +1 -1
  19. package/dist/devtools/browser-dev-host/assets/{browser-dev-host-DIkT9EVT.js → browser-dev-host-BitDUIsy.js} +1 -1
  20. package/dist/devtools/browser-dev-host/assets/{desktop-app-launch-CXLBQXPW.js → desktop-app-launch-B0yrI7xe.js} +1 -1
  21. package/dist/devtools/browser-dev-host/assets/{index-Dn9OFySi.js → index-D_mC4Hvt.js} +3 -3
  22. package/dist/devtools/browser-dev-host/index.html +2 -2
  23. package/dist/index.cjs.js +1 -1
  24. package/dist/index.esm.js +1 -1
  25. package/dist/vite.cjs.js +1 -1
  26. package/dist/vite.esm.js +1 -1
  27. package/docs/runtime-host-migration.md +1 -1
  28. package/package.json +4 -4
  29. package/skill/skill.json +4 -4
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  本文件随 `@heybox/hb-sdk` npm 包公开分发,只记录外部小程序开发者可观察到的变化。
4
4
 
5
+ ## 0.9.2-alpha.7 - 2026-10-20
6
+
7
+ ### 行为调整
8
+
9
+ - `hb-sdk dev` 启动前要求 CLI 已登录、项目已绑定小程序且远端配置校验通过;失败时提供修复指引并退出,不再自动进入匿名 Browser Mock。临时网络异常和短期限流仅重试一次,启动后的签票失败或临时断网仍保留浏览器调试服务。
10
+
5
11
  ## 0.9.2-alpha.6
6
12
 
7
13
  ### 新增能力
package/README.md CHANGED
@@ -26,7 +26,7 @@ npm run dev
26
26
 
27
27
  脚手架已包含 SDK、Vite 配置和常用开发命令。浏览器调试通过后,再从调试台的二维码入口使用手机小黑盒 APP 验收。
28
28
 
29
- 手机二维码的短链先打开普通中间页,再进入专用 dev-shell。最终 `openWindow` 协议会把 CLI 校验后的用户小程序字符串 ID(UUID)写入根字段 `user_miniprogram_id`;原生不会从 URL 查询参数补读,也不能用传统小程序数字 ID 代替。匿名调试不生成小程序 ID,原生未开放的横屏能力仍返回 `supported: false`。入口排查与验证记录见 [Android 396 入口审计](./docs/android-396-launch-identity.md)。
29
+ 手机二维码的短链先打开普通中间页,再进入专用 dev-shell。最终 `openWindow` 协议会把 CLI 校验后的用户小程序字符串 ID(UUID)写入根字段 `user_miniprogram_id`;原生不会从 URL 查询参数补读,也不能用传统小程序数字 ID 代替。原生未开放的横屏能力仍返回 `supported: false`。入口排查与验证记录见 [Android 396 入口审计](./docs/android-396-launch-identity.md)。
30
30
 
31
31
  创建命令使用 `@latest`,实际安装版本以 npm 的 `latest` 为准。
32
32
 
@@ -498,7 +498,7 @@ CLI 会复用已验证产物、跳过该 ZIP 的网络上传;Web 文件及发
498
498
 
499
499
  右上角的桌面图标与二维码按钮使用相同样式。桌面图标只在该项目于 `package.json#heybox.platforms` 声明了桌面平台(`windows`、`macos` 或 `linux`)时展示,未声明桌面平台的项目不显示该入口。点击桌面图标后选择小黑盒正式版或 Debug 版,选择会立即请求客户端打开当前本地页面并在本地记忆,不需要二次确认。桌面端只接受无凭据的 `http://127.0.0.1:<port>`,拒绝 `localhost`、IPv6 和 LAN 地址,不提供地址选择或手工 URL;手机二维码继续独立选择局域网地址。入口在项目已绑定且本地调试启动票有效时可用,统一 URI 只携带 `mini_program_id` 和 `mini_url`,启动票继续由 detail 从同源 `launch.json` 发现并交给后端验证。浏览器无法确认客户端是否真正打开,因此调试台只记录“已请求打开”,不会自动切换正式版或 Debug 版。
500
500
 
501
- `hb-sdk dev` 在未登录、未绑定或远端不可用时仍启动 Browser Mock;真实手机/PC 入口须有有效启动票。CLI 自动从本地声明生成普通 `network` / `companion` 的临时批准缺口,不提供第二套权限开关。调试台顶部的“查看全部权限申请”在新标签页打开当前小程序的权限列表;尚未获批的 Network、Companion 单项提供“去申请”,直接打开对应申请表单。未获取到小程序 ID 时先选择小程序,再进入对应权限;已获批或审核中的权限不重复打开申请表单。真实 Host 每次打开会话确认临时权限,拒绝后仍可按线上批准基线打开;官方域名始终只认声明与线上批准的交集。手机真机 Dev Session 仅将目标 hostname 为 `localhost` 或 `127.0.0.*` 的公开 `network.request()` 交给开发机 HTTP 代理转发,因此这些地址指向开发机;其它域名、LAN 地址和其它 IP 使用设备自身网络;代理不管理独立租约,不判断黑盒域名或改写应用层凭据。正式版本和 Runtime 私有请求仍走 Host 网络。CLI 连续失联约 30 秒、期限或快照变化会销毁旧 Runtime,并清理临时 Companion 进程树;恢复后重新确认。手机验收统一从右上角二维码进入并选择可达的局域网网卡。调试会话、权限刷新与完整操作见 [CLI 指南](https://docs.xiaoheihe.cn/hb_sdk/guide/cli),实现与安全边界由 [Runtime Host 迁移](./docs/runtime-host-migration.md) 维护。
501
+ `hb-sdk dev` 启动前要求 CLI 已登录、项目已绑定小程序,并成功校验远端配置;未满足时直接退出,不启动服务或打开浏览器。网络或服务临时异常等待 1 秒后重试一次;限流仅在服务端给出的等待窗口不超过 30 秒时重试一次,仍失败则退出并保留绑定。启动后,真实手机/PC 入口须有有效启动票,签票失败不阻断 Browser Mock,运行中的临时网络故障也不关闭浏览器服务。CLI 自动从本地声明生成普通 `network` / `companion` 的临时批准缺口,不提供第二套权限开关。调试台顶部的“查看全部权限申请”在新标签页打开当前小程序的权限列表;尚未获批的 Network、Companion 单项提供“去申请”,直接打开对应申请表单。未获取到小程序 ID 时先选择小程序,再进入对应权限;已获批或审核中的权限不重复打开申请表单。真实 Host 每次打开会话确认临时权限,拒绝后仍可按线上批准基线打开;官方域名始终只认声明与线上批准的交集。手机真机 Dev Session 仅将目标 hostname 为 `localhost` 或 `127.0.0.*` 的公开 `network.request()` 交给开发机 HTTP 代理转发,因此这些地址指向开发机;其它域名、LAN 地址和其它 IP 使用设备自身网络;代理不管理独立租约,不判断黑盒域名或改写应用层凭据。正式版本和 Runtime 私有请求仍走 Host 网络。CLI 连续失联约 30 秒、期限或快照变化会销毁旧 Runtime,并清理临时 Companion 进程树;恢复后重新确认。手机验收统一从右上角二维码进入并选择可达的局域网网卡。调试会话、权限刷新与完整操作见 [CLI 指南](https://docs.xiaoheihe.cn/hb_sdk/guide/cli),实现与安全边界由 [Runtime Host 迁移](./docs/runtime-host-migration.md) 维护。
502
502
 
503
503
  开发上下文按需读取并默认缓存 30 秒;重新打开真机会话时,过期缓存会刷新。权限刷新遇到临时故障或限流会按退避自动重试,恢复前暂停签发新启动票。真机按确认后的有效网络权限选择身份模式;身份上下文读取失败会提示重试,不会静默切换旧身份模式。
504
504
 
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var runtimeGate = require('./runtime-gate-BcKHky95.cjs');
3
+ var runtimeGate = require('./runtime-gate-BKc2zPV-.cjs');
4
4
  var fs$1 = require('node:fs');
5
5
  var fs = require('node:fs/promises');
6
6
  var path = require('node:path');
7
- var runtimePermissionEnv = require('./runtime-permission-env-BQ7lPfhg.cjs');
8
- var index = require('./index-CN_l895H.cjs');
7
+ var runtimePermissionEnv = require('./runtime-permission-env-B9SqoP85.cjs');
8
+ var index = require('./index-bZIxID9N.cjs');
9
9
  require('node:crypto');
10
10
  require('node:zlib');
11
- var projectVite = require('./project-vite-CNubrzp5.cjs');
11
+ var projectVite = require('./project-vite-6eLmb4Em.cjs');
12
12
  require('node:module');
13
13
  require('node:url');
14
14
  require('./_commonjs-dynamic-modules-DUamuDzp.cjs');
@@ -16,7 +16,7 @@ require('fs');
16
16
  require('path');
17
17
  require('os');
18
18
  require('inspector');
19
- require('./version-ai8lcNbJ.cjs');
19
+ require('./version-CwEOrhL1.cjs');
20
20
  require('node:async_hooks');
21
21
  require('readline');
22
22
  require('tty');
@@ -3,10 +3,10 @@
3
3
  var node_crypto = require('node:crypto');
4
4
  var fs = require('node:fs/promises');
5
5
  var path = require('node:path');
6
- var runtimePermissionEnv = require('./runtime-permission-env-BQ7lPfhg.cjs');
6
+ var runtimePermissionEnv = require('./runtime-permission-env-B9SqoP85.cjs');
7
7
  var fs$1 = require('node:fs');
8
8
  var sharp = require('sharp');
9
- var index = require('./index-CN_l895H.cjs');
9
+ var index = require('./index-bZIxID9N.cjs');
10
10
 
11
11
  async function inspectBasicInfoImage(bytes, sourcePath, kind) {
12
12
  const inspected = await inspectDecodedBasicInfoImage(bytes, kind);
@@ -5,7 +5,7 @@ var fs = require('node:fs/promises');
5
5
  var path = require('node:path');
6
6
  var require$$0 = require('fs');
7
7
  var require$$1 = require('path');
8
- var index = require('./index-CN_l895H.cjs');
8
+ var index = require('./index-bZIxID9N.cjs');
9
9
  require('node:module');
10
10
  require('readline');
11
11
  require('os');
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-CN_l895H.cjs');
4
- var context = require('./context-DlFt5Q7p.cjs');
3
+ var index = require('./index-bZIxID9N.cjs');
4
+ var context = require('./context-DQhjWa7X.cjs');
5
5
  var node_crypto = require('node:crypto');
6
6
  var fs = require('node:fs');
7
- var runtimePermissionEnv = require('./runtime-permission-env-BQ7lPfhg.cjs');
7
+ var runtimePermissionEnv = require('./runtime-permission-env-B9SqoP85.cjs');
8
8
  var os = require('node:os');
9
9
  var path = require('node:path');
10
10
  var net = require('node:net');
@@ -16,8 +16,8 @@ var fs$1 = require('node:fs/promises');
16
16
  var require$$0$1 = require('crypto');
17
17
  var require$$0 = require('buffer');
18
18
  var browser = require('./browser-RAy8e8cV.cjs');
19
- var projectVite = require('./project-vite-CNubrzp5.cjs');
20
- var version = require('./version-ai8lcNbJ.cjs');
19
+ var projectVite = require('./project-vite-6eLmb4Em.cjs');
20
+ var version = require('./version-CwEOrhL1.cjs');
21
21
  require('node:zlib');
22
22
 
23
23
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -1995,8 +1995,8 @@ const DEFAULT_CHANNEL_TRANSPORT = {
1995
1995
  };
1996
1996
  const IPV4_LOOPBACK_ADDRESSES = new net.BlockList();
1997
1997
  IPV4_LOOPBACK_ADDRESSES.addSubnet('127.0.0.0', 8, 'ipv4');
1998
- const { WebSocket, WebSocketServer } = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/dev-CNDIlDmL.cjs', document.baseURI).href)))('ws');
1999
- const { parse: parseHtml } = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/dev-CNDIlDmL.cjs', document.baseURI).href)))('parse5');
1998
+ const { WebSocket, WebSocketServer } = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/dev-KAhj5UTy.cjs', document.baseURI).href)))('ws');
1999
+ const { parse: parseHtml } = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/dev-KAhj5UTy.cjs', document.baseURI).href)))('parse5');
2000
2000
  const BROWSER_DEV_HOST_ROOT_CANDIDATES = [
2001
2001
  path.resolve(__dirname, 'devtools/browser-dev-host'),
2002
2002
  path.resolve(__dirname, '../devtools/browser-dev-host'),
@@ -11100,7 +11100,7 @@ function assertNodeRuntimeCapabilities(ctx, settings) {
11100
11100
  function createNodeRealtimeDriverRegistry() {
11101
11101
  const registry = createRuntimeRealtimeDriverRegistry();
11102
11102
  registry.registerLazy('node-websocket', async () => {
11103
- const mod = await Promise.resolve().then(function () { return require('./index.esm-mmJekGrr.cjs'); });
11103
+ const mod = await Promise.resolve().then(function () { return require('./index.esm-EWleN3S5.cjs'); });
11104
11104
  return mod.createNodeWebSocketRuntimeDriver();
11105
11105
  });
11106
11106
  return registry;
@@ -15584,21 +15584,6 @@ async function runDevCommand(options, runtime = {}) {
15584
15584
  const logger = runtime.logger ?? index.createCliLogger();
15585
15585
  const fetchImpl = runtime.fetchImpl ?? fetch;
15586
15586
  const openUrl = runtime.openExternalUrl ?? browser.openExternalUrl;
15587
- const networkInterfaceSnapshot = (runtime.networkInterfaces ?? os.networkInterfaces)();
15588
- const getPortImpl = runtime.getPort ?? getPorts;
15589
- const requestedAppPort = options.port ?? DEFAULT_APP_PORT;
15590
- const appPort = await selectAvailableVitePort({
15591
- getPort: getPortImpl,
15592
- isPortListening: runtime.isTcpPortListening ?? isTcpPortListening,
15593
- startPort: requestedAppPort,
15594
- });
15595
- if (appPort !== requestedAppPort)
15596
- logger.warn(`端口 ${requestedAppPort} 已被占用,已自动切换到 ${appPort}`);
15597
- const resolvedOptions = {
15598
- ...options,
15599
- hmrHost: createLanInterfaceCandidates(networkInterfaceSnapshot)[0]?.address,
15600
- port: appPort,
15601
- };
15602
15587
  const projectRoot = projectVite.findProjectRoot(runtime.cwd ?? process.cwd());
15603
15588
  const workspaceCardsDeclared = runtimePermissionEnv.readMiniappWorkspaceCardsFromPackageJson(projectRoot).declaration !== undefined;
15604
15589
  const companionArtifactAccessToken = (runtime.randomBytes ?? node_crypto.randomBytes)(32).toString('base64url');
@@ -15608,7 +15593,8 @@ async function runDevCommand(options, runtime = {}) {
15608
15593
  const miniProgramPlatforms = runtimePermissionEnv.readMiniappPlatformsFromPackageJson(projectRoot);
15609
15594
  // A1:Dev Context 结果缓存。启动读取、设备会话读取和权限刷新共用同一份结果,
15610
15595
  // 手机端重连不再 1:1 产生远端 `detail` 请求;限流时按网关建议时长延长压制。
15611
- const defaultSleep = (ms) => new Promise(resolve => { setTimeout(resolve, ms).unref?.(); });
15596
+ // 启动等待期间尚无监听服务,定时器必须保持进程存活。
15597
+ const defaultSleep = (ms) => new Promise(resolve => { setTimeout(resolve, ms); });
15612
15598
  const devContextCache = createDevContextCache({
15613
15599
  load: () => loadDevLaunchContext({
15614
15600
  env: runtime.env,
@@ -15632,9 +15618,9 @@ async function runDevCommand(options, runtime = {}) {
15632
15618
  const key = `${projectRoot}\0${boundMiniProgramId ?? ''}`;
15633
15619
  return devContextCache.read(key);
15634
15620
  };
15635
- let { context: devLaunchContext, miniProgram } = await readDevLaunchContext();
15621
+ let startup = await readDevLaunchContext();
15636
15622
  let lastRateLimitHint = '';
15637
- // A3:提示只在内容变化时输出一次,避免手机端反复重连刷屏。
15623
+ // 提示只在内容变化时输出一次,避免手机端反复重连刷屏。
15638
15624
  const reportRateLimitOnce = (state) => {
15639
15625
  const hint = index.formatCliRateLimitHint(state);
15640
15626
  if (hint === lastRateLimitHint)
@@ -15642,29 +15628,40 @@ async function runDevCommand(options, runtime = {}) {
15642
15628
  lastRateLimitHint = hint;
15643
15629
  reportDevContextRateLimit(logger, state, runtime.env);
15644
15630
  };
15645
- if (devLaunchContext.rateLimit?.limited)
15646
- reportRateLimitOnce(devLaunchContext.rateLimit);
15647
- // 启动即被限流时 `miniProgramId` 缺失,后面不会创建 token session,也就没有任何刷新路径
15648
- // (三条读取入口都以 `source === 'remote'` 为前提),开发者只能重启 CLI。这里先等网关窗口
15649
- // 过去再重试一次:窗口短就自动恢复,窗口长(例如封禁 24h)则不再空等,转为按限流原因阻塞
15650
- // 真机调试,而不是误报「未登录 / 未绑定」。
15651
- const startupRateLimit = devLaunchContext.rateLimit;
15652
- if (!devLaunchContext.miniProgramId && startupRateLimit?.limited) {
15653
- const windowMs = startupRateLimit.retryAfterMs;
15654
- if (windowMs !== undefined && windowMs <= DEV_CONTEXT_STARTUP_RATE_LIMIT_WAIT_MAX_MS) {
15655
- logger.warn(`已被网关限流,等待 ${Math.round(windowMs / 1000)} 秒后重试一次…`);
15656
- await (runtime.sleep ?? defaultSleep)(windowMs);
15657
- // 限流结果在缓存里最多压制 300s,重试前必须先失效,否则读到的还是同一条。
15658
- devContextCache.invalidate();
15659
- const retried = await readDevLaunchContext();
15660
- if (retried.context.miniProgramId) {
15661
- devLaunchContext = retried.context;
15662
- miniProgram = retried.miniProgram;
15663
- // 已恢复正常:允许后续再次限流时重新提示。
15664
- lastRateLimitHint = '';
15665
- }
15666
- }
15667
- }
15631
+ const startupRateLimit = startup.context.rateLimit;
15632
+ if (startupRateLimit?.limited)
15633
+ reportRateLimitOnce(startupRateLimit);
15634
+ // 首次启动只对临时错误重试一次;限流必须遵守服务端窗口,不能用普通退避绕过。
15635
+ const retryDelay = startupRateLimit?.limited
15636
+ ? startupRateLimit.retryAfterMs
15637
+ : startup.retryable ? DEFAULT_DEV_CONTEXT_BACKOFF_START_MS : undefined;
15638
+ if (startup.error && retryDelay !== undefined && retryDelay <= DEV_CONTEXT_STARTUP_RATE_LIMIT_WAIT_MAX_MS) {
15639
+ logger.warn(`${startupRateLimit?.limited ? '已被网关限流' : '远端配置暂不可用'},等待 ${Math.round(retryDelay / 1000)} 秒后重试一次…`);
15640
+ await (runtime.sleep ?? defaultSleep)(retryDelay);
15641
+ devContextCache.invalidate();
15642
+ startup = await readDevLaunchContext();
15643
+ }
15644
+ if (startup.error) {
15645
+ throw new index.CliError(`无法启动调试:${startup.error.message}`, startup.error.verboseMessage, { httpStatus: startup.error.httpStatus });
15646
+ }
15647
+ const { context: devLaunchContext, miniProgram } = startup;
15648
+ lastRateLimitHint = '';
15649
+ // 完成项目身份与配置校验后,才选择端口、创建服务和打开浏览器。
15650
+ const networkInterfaceSnapshot = (runtime.networkInterfaces ?? os.networkInterfaces)();
15651
+ const getPortImpl = runtime.getPort ?? getPorts;
15652
+ const requestedAppPort = options.port ?? DEFAULT_APP_PORT;
15653
+ const appPort = await selectAvailableVitePort({
15654
+ getPort: getPortImpl,
15655
+ isPortListening: runtime.isTcpPortListening ?? isTcpPortListening,
15656
+ startPort: requestedAppPort,
15657
+ });
15658
+ if (appPort !== requestedAppPort)
15659
+ logger.warn(`端口 ${requestedAppPort} 已被占用,已自动切换到 ${appPort}`);
15660
+ const resolvedOptions = {
15661
+ ...options,
15662
+ hmrHost: createLanInterfaceCandidates(networkInterfaceSnapshot)[0]?.address,
15663
+ port: appPort,
15664
+ };
15668
15665
  let currentDevContext = devLaunchContext;
15669
15666
  // 候选输入不对真机公开;签票成功后才替换整份运行上下文。
15670
15667
  let candidateDevContext = devLaunchContext;
@@ -15933,6 +15930,8 @@ async function runDevCommand(options, runtime = {}) {
15933
15930
  if (refreshed.context.rateLimit?.limited) {
15934
15931
  throw index.createCliRateLimitedErrorFromState(refreshed.context.rateLimit);
15935
15932
  }
15933
+ if (refreshed.error)
15934
+ throw refreshed.error;
15936
15935
  if (refreshed.context.miniProgramId !== devLaunchContext.miniProgramId)
15937
15936
  throw new Error('项目绑定已变更,请重新启动调试');
15938
15937
  if (refreshed.context.source !== 'remote')
@@ -16085,17 +16084,20 @@ function runDevStartupTask(logger, text, action, successText) {
16085
16084
  return logger.task(text, () => action(), { successText });
16086
16085
  }
16087
16086
  async function loadDevLaunchContext(options) {
16088
- // 声明错误始终阻断;远端不可用只影响真实 Host。
16087
+ // 声明错误始终阻断;远端失败保留结构化原因,启动与运行阶段分别处理。
16089
16088
  const localPermissions = runtimePermissionEnv.readMiniappPermissionsFromPackageJson(options.projectRoot, runtimePermissionEnv.resolveMiniappSdkVersion());
16090
16089
  const platforms = runtimePermissionEnv.readMiniappPlatformsFromPackageJson(options.projectRoot);
16091
- const anonymous = (warning) => ({ context: { source: 'anonymous', warning,
16090
+ const unavailable = (message, error = new index.CliError(message), retryable = false) => ({
16091
+ context: { source: 'anonymous', warning: message,
16092
16092
  declaredPermissions: localPermissions.permissions ?? {}, platforms,
16093
- runtimePermissions: runtimePermissionEnv.composeMiniappRuntimePermissions(localPermissions, undefined).runtimePermissions }, miniProgram: null });
16094
- if (!(await index.readHeyboxAuthSession({ env: options.env })))
16095
- return anonymous('尚未登录 CLI,真实手机和 PC 调试不可用');
16093
+ runtimePermissions: runtimePermissionEnv.composeMiniappRuntimePermissions(localPermissions, undefined).runtimePermissions },
16094
+ miniProgram: null, error, retryable,
16095
+ });
16096
16096
  const miniProgramId = await context.readBoundMiniProgramId(options.projectRoot);
16097
16097
  if (!miniProgramId)
16098
- return anonymous('尚未绑定小程序,真实手机和 PC 调试不可用');
16098
+ return unavailable('当前项目尚未绑定小程序。请先运行 hb-sdk remote create 或 hb-sdk remote bind <mini-program-id>,完成后重新运行 hb-sdk dev。');
16099
+ if (!(await index.readHeyboxAuthSession({ env: options.env })))
16100
+ return unavailable('尚未登录 CLI。请先运行 hb-sdk login,完成后重新运行 hb-sdk dev。');
16099
16101
  let migratingProfile = false;
16100
16102
  try {
16101
16103
  const { detail, miniProgramId: verifiedMiniProgramId } = await runDevStartupTask(options.logger, '正在读取远端小程序权限', () => loadRemoteDevContextWithTimeout({
@@ -16113,7 +16115,7 @@ async function loadDevLaunchContext(options) {
16113
16115
  if (migration.changed)
16114
16116
  options.logger.info('已迁移当前正式发布名称与图片,继续启动开发环境');
16115
16117
  if (!runtimePermissionEnv.parseMiniProgramRuntimePermissions(detail.runtime_permissions).valid)
16116
- return anonymous('线上权限快照无效,真实手机和 PC 调试不可用');
16118
+ return unavailable('线上权限快照无效,请稍后重试;持续失败时请联系平台支持。');
16117
16119
  const effectivePermissions = runtimePermissionEnv.composeMiniappRuntimePermissions(localPermissions, detail.runtime_permissions, detail.party_type).runtimePermissions;
16118
16120
  return {
16119
16121
  context: {
@@ -16132,18 +16134,25 @@ async function loadDevLaunchContext(options) {
16132
16134
  throw new Error(`版本资料配置失败:${index.readRedactedErrorMessage(error)}。请配置 heybox.name/icon/coverImages 后重试。`, { cause: error });
16133
16135
  if (error instanceof context.MiniProgramProjectBindingError && error.code.startsWith('PACKAGE_JSON_'))
16134
16136
  throw error;
16135
- // A3:限流要作为结构化状态继续透出;不能和其它错误一样只报「未连接线上上下文」。
16136
16137
  const rateLimitState = index.readCliRateLimitState(error);
16137
16138
  if (rateLimitState) {
16138
- return {
16139
- context: {
16140
- ...anonymous(index.formatCliRateLimitHint(rateLimitState)).context,
16141
- rateLimit: rateLimitState,
16142
- },
16143
- miniProgram: null,
16144
- };
16145
- }
16146
- return anonymous('未连接线上上下文,请检查 CLI 登录态、项目绑定和网络');
16139
+ const failure = unavailable(index.formatCliRateLimitHint(rateLimitState));
16140
+ failure.context.rateLimit = rateLimitState;
16141
+ return failure;
16142
+ }
16143
+ const status = error instanceof index.CliError ? error.httpStatus : undefined;
16144
+ const reason = status === 401
16145
+ ? 'CLI 登录态已失效,请运行 hb-sdk login 后重试。'
16146
+ : status === 403 || status === 404
16147
+ ? '无法访问已绑定的小程序,请检查当前账号的管理权限和小程序是否存在,必要时运行 hb-sdk remote bind <mini-program-id> 重新绑定。'
16148
+ : error instanceof context.MiniProgramProjectBindingError
16149
+ ? `${index.readRedactedErrorMessage(error)}。请运行 hb-sdk remote create 或 hb-sdk remote bind <mini-program-id> 后重试。`
16150
+ : `读取远端小程序配置失败:${index.readRedactedErrorMessage(error)}。请检查网络或稍后重试,当前项目绑定已保留。`;
16151
+ const retryable = error instanceof TypeError
16152
+ || (error instanceof Error && error.message === 'dev context timeout')
16153
+ || status === 408
16154
+ || (status !== undefined && status >= 500);
16155
+ return unavailable(reason, new index.CliError(reason, undefined, { httpStatus: status }), retryable);
16147
16156
  }
16148
16157
  }
16149
16158
  /**
@@ -3,7 +3,7 @@
3
3
  var fs = require('node:fs/promises');
4
4
  var os = require('node:os');
5
5
  var path = require('node:path');
6
- var index = require('./index-CN_l895H.cjs');
6
+ var index = require('./index-bZIxID9N.cjs');
7
7
  require('node:module');
8
8
  require('readline');
9
9
  require('os');
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index$2 = require('./index-CN_l895H.cjs');
3
+ var index$2 = require('./index-bZIxID9N.cjs');
4
4
  var require$$0$3 = require('fs');
5
5
  var require$$0$2 = require('crypto');
6
6
  var require$$1$2 = require('path');
@@ -238,19 +238,19 @@ function requireArgument () {
238
238
 
239
239
  var command = {};
240
240
 
241
- const require$5 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-CN_l895H.cjs', document.baseURI).href)));
241
+ const require$5 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-bZIxID9N.cjs', document.baseURI).href)));
242
242
  function __require$4() { return require$5("node:events"); }
243
243
 
244
- const require$4 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-CN_l895H.cjs', document.baseURI).href)));
244
+ const require$4 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-bZIxID9N.cjs', document.baseURI).href)));
245
245
  function __require$3() { return require$4("node:child_process"); }
246
246
 
247
- const require$3 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-CN_l895H.cjs', document.baseURI).href)));
247
+ const require$3 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-bZIxID9N.cjs', document.baseURI).href)));
248
248
  function __require$2() { return require$3("node:path"); }
249
249
 
250
- const require$2 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-CN_l895H.cjs', document.baseURI).href)));
250
+ const require$2 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-bZIxID9N.cjs', document.baseURI).href)));
251
251
  function __require$1() { return require$2("node:fs"); }
252
252
 
253
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-CN_l895H.cjs', document.baseURI).href)));
253
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-bZIxID9N.cjs', document.baseURI).href)));
254
254
  function __require() { return require$1("node:process"); }
255
255
 
256
256
  var help = {};
@@ -17249,7 +17249,7 @@ async function inspectFeedbackLog(file, size) {
17249
17249
  return { mimeType: 'text/plain', width: 0, height: 0 };
17250
17250
  }
17251
17251
  async function createFeedbackCosClient(getToken) {
17252
- const { default: COS } = await Promise.resolve().then(function () { return require('./index-DrlSotEe.cjs'); }).then(function (n) { return n.index; });
17252
+ const { default: COS } = await Promise.resolve().then(function () { return require('./index-DZUYwb3h.cjs'); }).then(function (n) { return n.index; });
17253
17253
  const cos = new COS({
17254
17254
  getAuthorization(_options, callback) {
17255
17255
  void getToken().then((token) => callback({
@@ -20900,7 +20900,7 @@ function readEnvNameArgFromArgv(argv) {
20900
20900
  }
20901
20901
 
20902
20902
  const CLI_VERSION_PLACEHOLDER = ['__HB', 'SDK', 'CLI', 'VERSION__'].join('_');
20903
- const BUILT_CLI_VERSION = '0.9.2-alpha.6';
20903
+ const BUILT_CLI_VERSION = '0.9.2-alpha.7';
20904
20904
  const PACKAGE_JSON_CANDIDATES = [
20905
20905
  path.resolve(__dirname, '..', '..', 'package.json'),
20906
20906
  path.resolve(__dirname, '..', 'package.json'),
@@ -21269,39 +21269,39 @@ function createCommandLoggerResolver(options) {
21269
21269
  };
21270
21270
  }
21271
21271
  const defaultClearLoginStatus = async (...args) => {
21272
- const { clearLoginStatus } = await Promise.resolve().then(function () { return require('./login-qupR7tLT.cjs'); });
21272
+ const { clearLoginStatus } = await Promise.resolve().then(function () { return require('./login-BYM3Nwau.cjs'); });
21273
21273
  return clearLoginStatus(...args);
21274
21274
  };
21275
21275
  const defaultLoginToHeybox = async (...args) => {
21276
- const { loginToHeybox } = await Promise.resolve().then(function () { return require('./login-qupR7tLT.cjs'); });
21276
+ const { loginToHeybox } = await Promise.resolve().then(function () { return require('./login-BYM3Nwau.cjs'); });
21277
21277
  return loginToHeybox(...args);
21278
21278
  };
21279
21279
  const defaultPrintLoginStatus = async (...args) => {
21280
- const { printLoginStatus } = await Promise.resolve().then(function () { return require('./login-qupR7tLT.cjs'); });
21280
+ const { printLoginStatus } = await Promise.resolve().then(function () { return require('./login-BYM3Nwau.cjs'); });
21281
21281
  return printLoginStatus(...args);
21282
21282
  };
21283
21283
  const defaultRunBuildCommand = async (...args) => {
21284
- const { runBuildCommand } = await Promise.resolve().then(function () { return require('./build-ffQNXsFk.cjs'); });
21284
+ const { runBuildCommand } = await Promise.resolve().then(function () { return require('./build-Do22AWbq.cjs'); });
21285
21285
  return runBuildCommand(...args);
21286
21286
  };
21287
21287
  const defaultRunCreateCommand = async (...args) => {
21288
- const { runCreateCommand } = await Promise.resolve().then(function () { return require('./create-BtmA7deR.cjs'); });
21288
+ const { runCreateCommand } = await Promise.resolve().then(function () { return require('./create-QuI_mw8x.cjs'); });
21289
21289
  return runCreateCommand(...args);
21290
21290
  };
21291
21291
  const defaultRunDevCommand = async (...args) => {
21292
- const { runDevCommand } = await Promise.resolve().then(function () { return require('./dev-CNDIlDmL.cjs'); }).then(function (n) { return n.dev; });
21292
+ const { runDevCommand } = await Promise.resolve().then(function () { return require('./dev-KAhj5UTy.cjs'); }).then(function (n) { return n.dev; });
21293
21293
  return runDevCommand(...args);
21294
21294
  };
21295
21295
  const defaultRunDoctorCommand = async (...args) => {
21296
- const { runDoctorCommand } = await Promise.resolve().then(function () { return require('./doctor-BkFUZH17.cjs'); });
21296
+ const { runDoctorCommand } = await Promise.resolve().then(function () { return require('./doctor-DNoQWBpo.cjs'); });
21297
21297
  return runDoctorCommand(...args);
21298
21298
  };
21299
21299
  const defaultRunSkillInstallCommand = async (...args) => {
21300
- const { runSkillInstallCommand } = await Promise.resolve().then(function () { return require('./skill-KmRvlkMJ.cjs'); });
21300
+ const { runSkillInstallCommand } = await Promise.resolve().then(function () { return require('./skill-DFXZ0SK_.cjs'); });
21301
21301
  return runSkillInstallCommand(...args);
21302
21302
  };
21303
21303
  const defaultRunRemoteCommand = async (...args) => {
21304
- const { runRemoteCommand } = await Promise.resolve().then(function () { return require('./remote-CbZlAq6Z.cjs'); });
21304
+ const { runRemoteCommand } = await Promise.resolve().then(function () { return require('./remote-dvOjaxJu.cjs'); });
21305
21305
  return runRemoteCommand(...args);
21306
21306
  };
21307
21307
  function resolveStandaloneLogger(options, verbose) {
@@ -11,8 +11,8 @@ var require$$0$3 = require('url');
11
11
  var require$$5 = require('zlib');
12
12
  var require$$0 = require('buffer');
13
13
  var require$$1 = require('util');
14
- var index = require('./index-CN_l895H.cjs');
15
- var dev = require('./dev-CNDIlDmL.cjs');
14
+ var index = require('./index-bZIxID9N.cjs');
15
+ var dev = require('./dev-KAhj5UTy.cjs');
16
16
  require('node:module');
17
17
  require('readline');
18
18
  require('os');
@@ -26,9 +26,9 @@ require('constants');
26
26
  require('node:fs');
27
27
  require('node:fs/promises');
28
28
  require('node:zlib');
29
- require('./context-DlFt5Q7p.cjs');
30
- require('./runtime-permission-env-BQ7lPfhg.cjs');
31
- require('./version-ai8lcNbJ.cjs');
29
+ require('./context-DQhjWa7X.cjs');
30
+ require('./runtime-permission-env-B9SqoP85.cjs');
31
+ require('./version-CwEOrhL1.cjs');
32
32
  require('node:async_hooks');
33
33
  require('sharp');
34
34
  require('node:os');
@@ -42,7 +42,7 @@ require('node:buffer');
42
42
  require('node:url');
43
43
  require('node:util');
44
44
  require('node:child_process');
45
- require('./project-vite-CNubrzp5.cjs');
45
+ require('./project-vite-6eLmb4Em.cjs');
46
46
 
47
47
  var bufferUtil = {exports: {}};
48
48
 
@@ -3,7 +3,7 @@
3
3
  var promises = require('node:readline/promises');
4
4
  var node_crypto = require('node:crypto');
5
5
  var node_http = require('node:http');
6
- var index = require('./index-CN_l895H.cjs');
6
+ var index = require('./index-bZIxID9N.cjs');
7
7
  var browser = require('./browser-RAy8e8cV.cjs');
8
8
  require('node:module');
9
9
  require('readline');
@@ -5,7 +5,7 @@ var fs$1 = require('node:fs/promises');
5
5
  var node_module = require('node:module');
6
6
  var path = require('node:path');
7
7
  var node_url = require('node:url');
8
- var index = require('./index-CN_l895H.cjs');
8
+ var index = require('./index-bZIxID9N.cjs');
9
9
 
10
10
  function findProjectRoot(startDir) {
11
11
  let current = path.resolve(startDir);
@@ -1,17 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var runtimePermissionEnv = require('./runtime-permission-env-BQ7lPfhg.cjs');
4
- var context = require('./context-DlFt5Q7p.cjs');
3
+ var runtimePermissionEnv = require('./runtime-permission-env-B9SqoP85.cjs');
4
+ var context = require('./context-DQhjWa7X.cjs');
5
5
  var promises = require('node:readline/promises');
6
- var index = require('./index-CN_l895H.cjs');
7
- var runtimeGate = require('./runtime-gate-BcKHky95.cjs');
6
+ var index = require('./index-bZIxID9N.cjs');
7
+ var runtimeGate = require('./runtime-gate-BKc2zPV-.cjs');
8
8
  var childProcess = require('node:child_process');
9
9
  var fs = require('node:fs');
10
10
  var fs$1 = require('node:fs/promises');
11
11
  var path = require('node:path');
12
12
  var node_crypto = require('node:crypto');
13
13
  require('node:zlib');
14
- require('./version-ai8lcNbJ.cjs');
14
+ require('./version-CwEOrhL1.cjs');
15
15
  require('node:async_hooks');
16
16
  require('sharp');
17
17
  require('node:module');
@@ -286,7 +286,7 @@ function createDefaultCosClient(uploadToken, COS) {
286
286
  };
287
287
  }
288
288
  async function loadCosConstructor() {
289
- const cosModule = await Promise.resolve().then(function () { return require('./index-DrlSotEe.cjs'); }).then(function (n) { return n.index; });
289
+ const cosModule = await Promise.resolve().then(function () { return require('./index-DZUYwb3h.cjs'); }).then(function (n) { return n.index; });
290
290
  return cosModule.default;
291
291
  }
292
292
  function formatSize(bytes) {
@@ -5,8 +5,8 @@ require('node:module');
5
5
  require('node:url');
6
6
  var fs = require('node:fs');
7
7
  var path = require('node:path');
8
- var runtimePermissionEnv = require('./runtime-permission-env-BQ7lPfhg.cjs');
9
- var index = require('./index-CN_l895H.cjs');
8
+ var runtimePermissionEnv = require('./runtime-permission-env-B9SqoP85.cjs');
9
+ var index = require('./index-bZIxID9N.cjs');
10
10
  var _commonjsDynamicModules = require('./_commonjs-dynamic-modules-DUamuDzp.cjs');
11
11
  var require$$0$1 = require('fs');
12
12
  var require$$1 = require('path');
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-CN_l895H.cjs');
3
+ var index = require('./index-bZIxID9N.cjs');
4
4
  var fs = require('node:fs');
5
5
  var path = require('node:path');
6
- var version$1 = require('./version-ai8lcNbJ.cjs');
6
+ var version$1 = require('./version-CwEOrhL1.cjs');
7
7
  require('node:crypto');
8
8
  var node_async_hooks = require('node:async_hooks');
9
9
 
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var version = require('./version-ai8lcNbJ.cjs');
3
+ var version = require('./version-CwEOrhL1.cjs');
4
4
  var fs = require('node:fs/promises');
5
5
  var path = require('node:path');
6
6
  var childProcess = require('node:child_process');
7
- var index = require('./index-CN_l895H.cjs');
7
+ var index = require('./index-bZIxID9N.cjs');
8
8
  require('node:module');
9
9
  require('readline');
10
10
  require('os');
@@ -3,6 +3,6 @@
3
3
  /** 构建时替换为当前发布包的实际版本。 */
4
4
  const HB_SDK_VERSION = typeof undefined === 'string'
5
5
  ? undefined
6
- : '0.9.2-alpha.6';
6
+ : '0.9.2-alpha.7';
7
7
 
8
8
  exports.HB_SDK_VERSION = HB_SDK_VERSION;
package/dist/cli.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./cli-chunks/index-CN_l895H.cjs');
3
+ var index = require('./cli-chunks/index-bZIxID9N.cjs');
4
4
  require('node:module');
5
5
  require('readline');
6
6
  require('os');