@heybox/hb-sdk 0.8.1-alpha.9 → 0.8.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 (54) hide show
  1. package/CHANGELOG.md +93 -1
  2. package/README.md +64 -18
  3. package/dist/cli-chunks/{build-D8eh0bxZ.cjs → build-DPe1Ycjd.cjs} +21 -7
  4. package/dist/cli-chunks/{context-JfGWhXSD.cjs → context-BSUhAv3Z.cjs} +2 -2
  5. package/dist/cli-chunks/{create-BiqK-4fa.cjs → create-CaiKrGnb.cjs} +2 -1
  6. package/dist/cli-chunks/{dev-u27Q6a-K.cjs → dev-BG1o8Q-0.cjs} +45 -12
  7. package/dist/cli-chunks/doctor-DutO2P5H.cjs +195 -0
  8. package/dist/cli-chunks/{index-CtR3w1bw.cjs → index-Bur0U2z1.cjs} +2 -2
  9. package/dist/cli-chunks/{index-B2eLzOSD.cjs → index-CKIyipP9.cjs} +77 -21
  10. package/dist/cli-chunks/{index.esm-CCDqeyc7.cjs → index.esm-BPlpP-O0.cjs} +8 -8
  11. package/dist/cli-chunks/{login-BSySslS2.cjs → login-C1JlLEza.cjs} +2 -2
  12. package/dist/cli-chunks/{project-vite-C-r7_UvY.cjs → project-vite-Bd0WzAqQ.cjs} +1 -1
  13. package/dist/cli-chunks/{remote-WvNfCBeJ.cjs → remote-DTFEf3Dj.cjs} +74 -10
  14. package/dist/cli-chunks/{runtime-permission-env-g_2W-HqP.cjs → runtime-permission-env-C2S34ldj.cjs} +145 -4
  15. package/dist/cli-chunks/{session-CaNwlovY.cjs → session-zXVkHuhY.cjs} +1 -1
  16. package/dist/cli-chunks/{skill-V_4EkY23.cjs → skill-CCB3DyXk.cjs} +3 -2
  17. package/dist/cli-chunks/{version-Dox07wdq.cjs → version-0qwlEyZC.cjs} +1 -1
  18. package/dist/cli.cjs +2 -1
  19. package/dist/devtools/browser-dev-host/assets/browser-dev-host-pUcws1MK.js +101 -0
  20. package/dist/devtools/browser-dev-host/assets/{desktop-app-launch-BE-Jw0zD.js → desktop-app-launch-DOfl5YvO.js} +3 -3
  21. package/dist/devtools/browser-dev-host/assets/{index-wEzSxtKd.js → index-CFr28-0O.js} +4 -4
  22. package/dist/devtools/browser-dev-host/assets/{index-D-aNERAr.css → index-DXd5IZBz.css} +1 -1
  23. package/dist/devtools/browser-dev-host/index.html +3 -3
  24. package/dist/index.cjs.js +24 -24
  25. package/dist/index.esm.js +24 -24
  26. package/dist/miniapp-publish.cjs.js +121 -3
  27. package/dist/miniapp-publish.esm.js +118 -4
  28. package/dist/protocol.cjs.js +27 -27
  29. package/dist/protocol.esm.js +27 -27
  30. package/dist/vite.cjs.js +179 -17
  31. package/dist/vite.esm.js +179 -18
  32. package/docs/device-logs.md +36 -0
  33. package/docs/runtime-host-migration.md +120 -0
  34. package/package.json +8 -6
  35. package/skill/SKILL.md +25 -20
  36. package/skill/references/api-protocol.md +3 -3
  37. package/skill/references/api-root.md +104 -11
  38. package/skill/references/cli.md +110 -9
  39. package/skill/references/examples.md +2 -2
  40. package/skill/references/recipes.md +25 -10
  41. package/skill/references/safety-boundaries.md +10 -7
  42. package/skill/skill.json +5 -5
  43. package/types/miniapp-manifest/bindings.d.ts +5 -0
  44. package/types/miniapp-manifest/index.d.ts +1 -0
  45. package/types/miniapp-manifest/node.d.ts +9 -1
  46. package/types/miniapp-manifest/schema.d.ts +94 -0
  47. package/types/miniapp-publish/index.d.ts +4 -2
  48. package/types/modules/companion/index.d.ts +68 -0
  49. package/types/modules/files/types.d.ts +10 -11
  50. package/types/modules/network/index.d.ts +3 -3
  51. package/types/skill-metadata.d.ts +16 -0
  52. package/types/vite/index.d.ts +1 -0
  53. package/dist/cli-chunks/doctor-ppQbhj7e.cjs +0 -65
  54. package/dist/devtools/browser-dev-host/assets/browser-dev-host-BYKHn0Ny.js +0 -101
package/dist/vite.esm.js CHANGED
@@ -8,7 +8,7 @@ import { AsyncLocalStorage } from 'node:async_hooks';
8
8
  /** 构建时替换为当前发布包的实际版本。 */
9
9
  const HB_SDK_VERSION = typeof undefined === 'string'
10
10
  ? undefined
11
- : '0.8.1-alpha.9';
11
+ : '0.8.1';
12
12
 
13
13
  /**
14
14
  * iframe 与调试台页面的开发期 console 捕获转发。
@@ -3113,6 +3113,35 @@ function requireSemver () {
3113
3113
 
3114
3114
  var semverExports = requireSemver();
3115
3115
 
3116
+ const MINIAPP_BIND_APP_IDS_MAX_COUNT = 20;
3117
+ function parseMiniappBindAppIds(value, options = {}) {
3118
+ const sourceLabel = options.sourceLabel ?? 'package.json#heybox.bindAppIds';
3119
+ if (value === undefined)
3120
+ return Object.freeze([]);
3121
+ if (!Array.isArray(value))
3122
+ throw new Error(`${sourceLabel} 必须是字符串数组`);
3123
+ if (value.length > MINIAPP_BIND_APP_IDS_MAX_COUNT) {
3124
+ throw new Error(`${sourceLabel} 最多包含 ${MINIAPP_BIND_APP_IDS_MAX_COUNT} 个游戏 appid`);
3125
+ }
3126
+ const seen = new Set();
3127
+ const appIds = [];
3128
+ for (const item of value) {
3129
+ if (typeof item !== 'string' || !/^[1-9]\d*$/.test(item)) {
3130
+ throw new Error(`${sourceLabel} 包含非法游戏 appid:${String(item)}`);
3131
+ }
3132
+ const numeric = Number(item);
3133
+ if (!Number.isSafeInteger(numeric) || numeric > 2_147_483_647) {
3134
+ throw new Error(`${sourceLabel} 包含超出正 int32 范围的游戏 appid:${item}`);
3135
+ }
3136
+ if (seen.has(item))
3137
+ throw new Error(`${sourceLabel} 包含重复游戏 appid:${item}`);
3138
+ seen.add(item);
3139
+ appIds.push(item);
3140
+ }
3141
+ appIds.sort((left, right) => Number(left) - Number(right));
3142
+ return Object.freeze(appIds);
3143
+ }
3144
+
3116
3145
  const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
3117
3146
  const MINI_PROGRAM_MESSAGE_VERSION = 2;
3118
3147
  const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
@@ -3278,7 +3307,7 @@ function parseMiniappPermissions(value, options) {
3278
3307
  }
3279
3308
  return { declared: false };
3280
3309
  }
3281
- if (!isRecord$2(value)) {
3310
+ if (!isRecord$3(value)) {
3282
3311
  throw new Error(`${sourceLabel} 必须是 JSON 对象`);
3283
3312
  }
3284
3313
  const knownKeys = new Set(MINIAPP_PERMISSION_KEYS);
@@ -3292,7 +3321,7 @@ function parseMiniappPermissions(value, options) {
3292
3321
  continue;
3293
3322
  const declaration = value[key];
3294
3323
  const itemLabel = `${sourceLabel}.${key}`;
3295
- if (!isRecord$2(declaration))
3324
+ if (!isRecord$3(declaration))
3296
3325
  throw new Error(`${itemLabel} 必须是 JSON 对象`);
3297
3326
  const definition = MINI_PROGRAM_PERMISSION_CATALOG.find((item) => item.key === key);
3298
3327
  if (!definition)
@@ -3326,11 +3355,15 @@ function requiresExplicitPermissions(sdkVersion) {
3326
3355
  function getMissingPermissionsWarning(sourceLabel = 'package.json#heybox.permissions') {
3327
3356
  return `${sourceLabel} 尚未声明。当前按 0.8 兼容行为构建;0.9.0 起将拒绝构建,请尽快补充权限声明(无权限需求时配置 {})。`;
3328
3357
  }
3329
- function isRecord$2(value) {
3358
+ function isRecord$3(value) {
3330
3359
  return typeof value === 'object' && value !== null && !Array.isArray(value);
3331
3360
  }
3332
3361
 
3333
3362
  const MINIAPP_PLATFORM_VALUES = ['android', 'ios', 'ohos', 'windows', 'macos', 'linux'];
3363
+ /** 窗口尺寸字段的脏值兜底上限;真正的上限是宿主侧显示器 workArea。 */
3364
+ const MINIAPP_WINDOW_SIZE_MAX = 16_384;
3365
+ const MINIAPP_WINDOW_NUMBER_FIELDS = ['defaultWidth', 'defaultHeight', 'minWidth', 'minHeight'];
3366
+ const MINIAPP_WINDOW_ALLOWED_FIELDS = [...MINIAPP_WINDOW_NUMBER_FIELDS, 'resizable'];
3334
3367
  function validateMiniappPackageVersionForBuild(version) {
3335
3368
  return validateMiniappManifestVersion(version, 'package.json.version');
3336
3369
  }
@@ -3343,12 +3376,16 @@ function validateMiniappManifestVersion(version, sourceLabel = 'manifest.version
3343
3376
  }
3344
3377
  function renderMiniappManifest(manifest) {
3345
3378
  const platforms = validateMiniappPlatforms(manifest.platforms, 'manifest.platforms');
3379
+ const window = validateMiniappWindow(manifest.window, 'manifest.window');
3380
+ const bindAppIds = parseMiniappBindAppIds(manifest.bindAppIds, { sourceLabel: 'manifest.bindAppIds' });
3346
3381
  const output = {
3347
3382
  version: manifest.version,
3348
3383
  sdkVersion: manifest.sdkVersion,
3349
3384
  platforms,
3350
3385
  ...(manifest.permissions === undefined ? {} : { permissions: manifest.permissions }),
3351
3386
  ...(manifest.companions === undefined ? {} : { companions: manifest.companions }),
3387
+ ...(window === undefined ? {} : { window }),
3388
+ ...(bindAppIds.length === 0 ? {} : { bindAppIds }),
3352
3389
  };
3353
3390
  return `${JSON.stringify(output, null, 2)}\n`;
3354
3391
  }
@@ -3369,6 +3406,70 @@ function validateMiniappPlatforms(platforms, sourceLabel = 'platforms') {
3369
3406
  }
3370
3407
  return Object.freeze(MINIAPP_PLATFORM_VALUES.filter((platform) => seen.has(platform)));
3371
3408
  }
3409
+ /**
3410
+ * 校验并归一化 `package.json#heybox.window` / `manifest.window` 声明。
3411
+ *
3412
+ * @remarks
3413
+ * 与 `heybox.permissions` 同样的严格风格:未知字段报错,不做静默忽略。
3414
+ * `width` / `height` 显式给出改名提示;`x` / `y` 按未知字段显式报错(`INV-NO-DEV-POSITION`)。
3415
+ * 未声明时返回 `undefined`,由调用方决定不写入产物。
3416
+ * @param value - 待校验的原始声明(不可信输入)。
3417
+ * @param sourceLabel - 报错前缀,默认指向开发者声明路径。
3418
+ * @throws 当声明不是非空对象、含未知字段、数值/布尔类型不合法或 min/default 不配对时抛出。
3419
+ */
3420
+ function validateMiniappWindow(value, sourceLabel = 'package.json#heybox.window') {
3421
+ if (value === undefined)
3422
+ return undefined;
3423
+ if (!isRecord$2(value) || Object.keys(value).length === 0) {
3424
+ throw new Error(`${sourceLabel} 至少需要声明 defaultWidth/defaultHeight/minWidth/minHeight/resizable 之一`);
3425
+ }
3426
+ if (Object.prototype.hasOwnProperty.call(value, 'width') || Object.prototype.hasOwnProperty.call(value, 'height')) {
3427
+ throw new Error(`${sourceLabel} 请使用 defaultWidth/defaultHeight,而不是 width/height`);
3428
+ }
3429
+ for (const key of Object.keys(value)) {
3430
+ if (!MINIAPP_WINDOW_ALLOWED_FIELDS.includes(key)) {
3431
+ throw new Error(`${sourceLabel} 包含未知字段:${key}`);
3432
+ }
3433
+ }
3434
+ const window = {};
3435
+ for (const field of MINIAPP_WINDOW_NUMBER_FIELDS) {
3436
+ if (!Object.prototype.hasOwnProperty.call(value, field))
3437
+ continue;
3438
+ const size = value[field];
3439
+ if (typeof size !== 'number' || !Number.isSafeInteger(size) || size <= 0) {
3440
+ throw new Error(`${sourceLabel}.${field} 必须是正整数`);
3441
+ }
3442
+ if (size > MINIAPP_WINDOW_SIZE_MAX) {
3443
+ throw new Error(`${sourceLabel}.${field} 不能大于 ${MINIAPP_WINDOW_SIZE_MAX}`);
3444
+ }
3445
+ window[field] = size;
3446
+ }
3447
+ if (Object.prototype.hasOwnProperty.call(value, 'resizable')) {
3448
+ if (typeof value.resizable !== 'boolean') {
3449
+ throw new Error(`${sourceLabel}.resizable 必须是 boolean`);
3450
+ }
3451
+ window.resizable = value.resizable;
3452
+ }
3453
+ for (const [minimum, fallback] of [
3454
+ ['minWidth', 'defaultWidth'],
3455
+ ['minHeight', 'defaultHeight'],
3456
+ ]) {
3457
+ const minimumValue = window[minimum];
3458
+ if (minimumValue === undefined)
3459
+ continue;
3460
+ const fallbackValue = window[fallback];
3461
+ if (fallbackValue === undefined) {
3462
+ throw new Error(`${sourceLabel}.${minimum} 必须与 ${fallback} 同时声明`);
3463
+ }
3464
+ if (minimumValue > fallbackValue) {
3465
+ throw new Error(`${sourceLabel}.${minimum} 必须小于等于 ${fallback}`);
3466
+ }
3467
+ }
3468
+ return window;
3469
+ }
3470
+ function isRecord$2(value) {
3471
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
3472
+ }
3372
3473
  function getMiniappManifestVersionError(version) {
3373
3474
  if (typeof version !== 'string' || version.trim() === '') {
3374
3475
  return `必须是合法 SemVer:${String(version)}`;
@@ -3426,6 +3527,17 @@ function readMiniappPlatformsFromPackageJson(root) {
3426
3527
  const heybox = readMiniappHeyboxConfig(packageJson);
3427
3528
  return validateMiniappPlatforms(heybox?.platforms, 'package.json#heybox.platforms');
3428
3529
  }
3530
+ /**
3531
+ * 读取并校验 `package.json#heybox.window`。
3532
+ *
3533
+ * @returns 合法声明;未声明时返回 `undefined`,调用方不得向 manifest 写入空对象或 `null`。
3534
+ * @throws 当声明违反 {@link validateMiniappWindow} 的规则时抛出,报错前缀为 `package.json#heybox.window`。
3535
+ */
3536
+ function readMiniappWindowFromPackageJson(root) {
3537
+ const { packageJson } = readMiniappPackageJson(root, false);
3538
+ const heybox = readMiniappHeyboxConfig(packageJson);
3539
+ return validateMiniappWindow(heybox?.window, 'package.json#heybox.window');
3540
+ }
3429
3541
  function readMiniappPermissionsFromPackageJson(root, sdkVersion) {
3430
3542
  const { packageJson } = readMiniappPackageJson(root, false);
3431
3543
  const heybox = readMiniappHeyboxConfig(packageJson);
@@ -3435,6 +3547,11 @@ function readMiniappPermissionsFromPackageJson(root, sdkVersion) {
3435
3547
  sdkVersion,
3436
3548
  });
3437
3549
  }
3550
+ function readMiniappBindAppIdsFromPackageJson(root) {
3551
+ const { packageJson } = readMiniappPackageJson(root, false);
3552
+ const heybox = readMiniappHeyboxConfig(packageJson);
3553
+ return parseMiniappBindAppIds(heybox?.bindAppIds);
3554
+ }
3438
3555
  function readMiniappPackageJson(root, requireVersion) {
3439
3556
  const packageJsonPath = findNearestPackageJsonPath(root);
3440
3557
  let content;
@@ -12890,11 +13007,23 @@ const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
12890
13007
  const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
12891
13008
  const miniDevLoggingConstant = ['__HB_SDK_DEV', 'LOGGING__'].join('_');
12892
13009
  const DEV_MANIFEST_PATH = '/__hb_sdk__/companion/manifest.json';
13010
+ /**
13011
+ * 本地 PC 调试开窗时的 manifest 入口。
13012
+ *
13013
+ * 开窗发生在扩展拿到 `LocalDevelopmentBinding` 之前,所以不能用 Companion 会话令牌守护;
13014
+ * 该入口改由 CLI 随本地调试启动上下文(`mini_url` query)下发的专用令牌守护,
13015
+ * 只回最新快照,不参与 Companion 会话的 digest 钉扎。
13016
+ */
13017
+ const DEV_MINI_PROGRAM_MANIFEST_PATH = '/__hb_sdk__/mini-program/manifest.json';
12893
13018
  const DEV_TOKEN_HEADER = 'x-hb-sdk-companion-dev-token';
13019
+ const DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER = 'x-hb-sdk-mini-program-manifest-token';
12894
13020
  const DEV_DIGEST_HEADER = 'x-hb-sdk-companion-manifest-sha256';
12895
13021
  const DEV_ERROR_MESSAGE = 'Companion 开发资源暂时不可用';
13022
+ /** 与 Companion manifest 一致的单响应上限,避免本地调试入口被大体积声明撑爆。 */
13023
+ const DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES = 1024 * 1024;
12896
13024
  const DEV_COMPANION_PATH_PATTERN = /^\/__hb_sdk__\/companions\/([a-z][a-z0-9-]{0,31})\/(windows-x64|macos-arm64)\.zip$/;
12897
13025
  const HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV = 'HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN';
13026
+ const HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV = 'HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN';
12898
13027
  const devSnapshotStoreKey = Symbol.for('@heybox/hb-sdk/dev-companion-snapshots');
12899
13028
  const devSnapshotRegistry = globalThis;
12900
13029
  if (!devSnapshotRegistry[devSnapshotStoreKey]) {
@@ -12911,7 +13040,8 @@ function miniappManifest() {
12911
13040
  const includeCompanions = process.env.HB_SDK_SKIP_COMPANIONS !== '1';
12912
13041
  const deviceLogs = new DeviceLogStore();
12913
13042
  const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
12914
- let companionArtifactAccessToken = parseCompanionArtifactAccessToken(process.env[HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV]);
13043
+ let companionArtifactAccessToken = parseDevAccessToken(process.env[HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV]);
13044
+ let miniProgramManifestAccessToken = parseDevAccessToken(process.env[HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV]);
12915
13045
  let root = process.cwd();
12916
13046
  let outDir = 'dist';
12917
13047
  let command = 'build';
@@ -12959,8 +13089,16 @@ function miniappManifest() {
12959
13089
  registerLogs();
12960
13090
  let store = devSnapshotStores.get(root);
12961
13091
  companionArtifactAccessToken ??= store?.token;
12962
- if (!store || store.token !== companionArtifactAccessToken) {
12963
- store = { token: companionArtifactAccessToken ?? '', snapshots: new Map() };
13092
+ // Companion 令牌同因:配置重载时 env 已不在,只能从同一服务的注册表恢复。
13093
+ miniProgramManifestAccessToken ??= store?.manifestToken;
13094
+ if (!store ||
13095
+ store.token !== companionArtifactAccessToken ||
13096
+ store.manifestToken !== miniProgramManifestAccessToken) {
13097
+ store = {
13098
+ token: companionArtifactAccessToken ?? '',
13099
+ ...(miniProgramManifestAccessToken ? { manifestToken: miniProgramManifestAccessToken } : {}),
13100
+ snapshots: new Map(),
13101
+ };
12964
13102
  devSnapshotStores.set(root, store);
12965
13103
  }
12966
13104
  const snapshots = store.snapshots;
@@ -13065,7 +13203,8 @@ function miniappManifest() {
13065
13203
  return;
13066
13204
  }
13067
13205
  const companionMatch = pathname?.match(DEV_COMPANION_PATH_PATTERN);
13068
- if (pathname !== DEV_MANIFEST_PATH && !companionMatch) {
13206
+ const miniProgramManifest = pathname === DEV_MINI_PROGRAM_MANIFEST_PATH;
13207
+ if (pathname !== DEV_MANIFEST_PATH && !companionMatch && !miniProgramManifest) {
13069
13208
  next();
13070
13209
  return;
13071
13210
  }
@@ -13075,16 +13214,25 @@ function miniappManifest() {
13075
13214
  response.end();
13076
13215
  return;
13077
13216
  }
13078
- if (!companionArtifactAccessToken ||
13079
- !isNumericLoopbackRequest(request) ||
13080
- !isNumericLoopbackHost(request.headers.host) ||
13081
- !hasValidCompanionArtifactToken(request, companionArtifactAccessToken)) {
13217
+ // 两条链路共用「仅数值 loopback」边界,凭据各自独立。
13218
+ if (!isNumericLoopbackRequest(request) || !isNumericLoopbackHost(request.headers.host)) {
13219
+ response.statusCode = 403;
13220
+ response.end();
13221
+ return;
13222
+ }
13223
+ const authorized = miniProgramManifest
13224
+ ? miniProgramManifestAccessToken !== undefined &&
13225
+ hasValidDevToken(request, DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER, miniProgramManifestAccessToken)
13226
+ : companionArtifactAccessToken !== undefined &&
13227
+ hasValidDevToken(request, DEV_TOKEN_HEADER, companionArtifactAccessToken);
13228
+ if (!authorized) {
13082
13229
  response.statusCode = 403;
13083
13230
  response.end();
13084
13231
  return;
13085
13232
  }
13086
13233
  try {
13087
- const requestedDigest = request.headers[DEV_DIGEST_HEADER];
13234
+ // 本地调试入口只回最新快照;digest 钉扎仍然只服务 Companion 会话。
13235
+ const requestedDigest = miniProgramManifest ? undefined : request.headers[DEV_DIGEST_HEADER];
13088
13236
  if (requestedDigest !== undefined && (typeof requestedDigest !== 'string' || !/^[a-f0-9]{64}$/.test(requestedDigest))) {
13089
13237
  response.statusCode = 400;
13090
13238
  response.end();
@@ -13096,9 +13244,15 @@ function miniappManifest() {
13096
13244
  response.end();
13097
13245
  return;
13098
13246
  }
13247
+ if (miniProgramManifest && snapshot.manifestBytes.length > DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES) {
13248
+ response.statusCode = 500;
13249
+ response.setHeader('Content-Type', 'text/plain; charset=utf-8');
13250
+ response.end(DEV_ERROR_MESSAGE);
13251
+ return;
13252
+ }
13099
13253
  response.setHeader('Cache-Control', 'no-store');
13100
13254
  response.setHeader('X-Content-Type-Options', 'nosniff');
13101
- if (pathname === DEV_MANIFEST_PATH) {
13255
+ if (pathname === DEV_MANIFEST_PATH || miniProgramManifest) {
13102
13256
  response.statusCode = 200;
13103
13257
  response.setHeader('Content-Type', 'application/json; charset=utf-8');
13104
13258
  response.setHeader('Content-Length', snapshot.manifestBytes.length);
@@ -13178,8 +13332,10 @@ function miniappManifest() {
13178
13332
  const sdkVersion = resolveSdkVersion();
13179
13333
  const platforms = readMiniappPlatformsFromPackageJson(root);
13180
13334
  const parsedPermissions = readMiniappPermissionsFromPackageJson(root, sdkVersion);
13335
+ const windowDeclaration = readMiniappWindowFromPackageJson(root);
13181
13336
  const companionConfig = readMiniappCompanionsFromPackageJson(root);
13182
13337
  const companionDeclarations = includeCompanions ? companionConfig.declarations : undefined;
13338
+ const bindAppIds = readMiniappBindAppIdsFromPackageJson(root);
13183
13339
  if (!parsedPermissions.declared)
13184
13340
  this.warn(getMissingPermissionsWarning());
13185
13341
  if (companionDeclarations && !parsedPermissions.permissions?.companion) {
@@ -13207,6 +13363,8 @@ function miniappManifest() {
13207
13363
  platforms,
13208
13364
  ...(parsedPermissions.permissions === undefined ? {} : { permissions: parsedPermissions.permissions }),
13209
13365
  ...(companions === undefined ? {} : { companions }),
13366
+ ...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
13367
+ ...(bindAppIds.length === 0 ? {} : { bindAppIds }),
13210
13368
  }));
13211
13369
  },
13212
13370
  };
@@ -13215,6 +13373,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
13215
13373
  const version = validateMiniappPackageVersionForBuild(readMiniappVersionFromPackageJson(root));
13216
13374
  const sdkVersion = resolveSdkVersion();
13217
13375
  const permissions = readMiniappPermissionsFromPackageJson(root, sdkVersion).permissions;
13376
+ const windowDeclaration = readMiniappWindowFromPackageJson(root);
13218
13377
  if (declarations && !permissions?.companion) {
13219
13378
  throw new Error('配置 companions 时必须声明 package.json#heybox.permissions.companion.enabled=true');
13220
13379
  }
@@ -13238,6 +13397,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
13238
13397
  platforms,
13239
13398
  ...(permissions === undefined ? {} : { permissions }),
13240
13399
  ...(companions === undefined ? {} : { companions }),
13400
+ ...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
13241
13401
  };
13242
13402
  return { artifacts, manifestBytes: Buffer.from(renderMiniappManifest(manifest)) };
13243
13403
  }
@@ -13286,11 +13446,12 @@ function isNumericLoopbackHost(host) {
13286
13446
  const port = Number(match[1]);
13287
13447
  return port >= 1 && port <= 65_535;
13288
13448
  }
13289
- function parseCompanionArtifactAccessToken(value) {
13449
+ /** 两条本地调试链路共用的凭据形状:32 字节 base64url,恰好 43 个字符。 */
13450
+ function parseDevAccessToken(value) {
13290
13451
  return value && /^[A-Za-z0-9_-]{43}$/.test(value) ? value : undefined;
13291
13452
  }
13292
- function hasValidCompanionArtifactToken(request, expected) {
13293
- const value = request.headers[DEV_TOKEN_HEADER];
13453
+ function hasValidDevToken(request, header, expected) {
13454
+ const value = request.headers[header];
13294
13455
  const candidate = Buffer.alloc(43);
13295
13456
  if (typeof value === 'string')
13296
13457
  Buffer.from(value).copy(candidate, 0, 0, candidate.length);
@@ -13339,4 +13500,4 @@ function resolveHmrWebSocketUrl(resolved) {
13339
13500
  return `${protocol}://${host}${port ? `:${port}` : ''}`;
13340
13501
  }
13341
13502
 
13342
- export { HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV, MINIAPP_PLATFORM_VALUES, miniappManifest };
13503
+ export { HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV, HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV, MINIAPP_PLATFORM_VALUES, miniappManifest };
@@ -0,0 +1,36 @@
1
+ # 多设备开发日志
2
+
3
+ ## 设备沙箱目录
4
+
5
+ 调试台“存储”旁的“沙箱”页签支持选择设备、进入子目录、返回上级及刷新。只读取名称和类型,不读取文件内容。离线设备与不支持文件能力的宿主会报告错误,查询最长等待 10 秒。查询以设备会话及请求 ID 绑定,切换设备后旧响应不会覆盖当前目录。
6
+
7
+ `hb-sdk dev sandbox list --device <会话ID> --path . --json` 使用同一只读查询通道。目录 `.` 表示当前根目录;SDK 可用 `files.sandbox.directory('.').list()`,嵌套目录的 `.directory('.')` 表示自身。仅完整 `.` 被允许,文件路径、`..` 和混合点段仍拒绝。新目录语义需要配套 Runtime;旧宿主可能返回不支持。单次枚举上限 200 项,超限由宿主报告。
8
+
9
+ 运行 `hb-sdk dev` 后,使用 `miniappManifest()` 的开发页面会在业务模块加载前捕获 console、未捕获异常和未处理的 Promise rejection,并通过页面同源 HTTP 批量回传。浏览器、手机扫码、PC Extension 打开相同开发页面均使用此入口;生产构建不注入脚本。SDK 开发构建还会上报调用方法、调用 ID、结果和耗时,不上传参数或响应体。
10
+
11
+ 调试台每秒增量读取日志。在日志筛选菜单选择设备会话;条目辅助行显示设备名称与代码来源。平台名称来自 User Agent,仅用于展示,并非可信硬件身份。服务器为每次打开独立分配会话 ID 和上传凭证;短暂断线保持凭证和递增序号,重复批次不会重复入库。重新加载页面创建新会话。
12
+
13
+ ## Agent 与 CLI
14
+
15
+ ```sh
16
+ hb-sdk dev devices --json
17
+ hb-sdk dev logs --json --device <deviceSessionId> --level error
18
+ hb-sdk dev logs --json --after 123 --limit 100
19
+ hb-sdk dev logs --json --callId <callId>
20
+ hb-sdk dev logs --json --id 123
21
+ hb-sdk dev logs --follow --json --duration 60
22
+ ```
23
+
24
+ 默认连接本机调试台端口:跟随同一次 `hb-sdk dev` 的 `--browser-dev-host-port`,未指定时为 5174。需要查询其它调试台实例(例如同时运行多个项目)时,用 `--port <实际调试台端口>` 显式覆盖。注意 `hb-sdk dev --port` 是小程序开发服务器端口,与调试台端口无关,日志命令不会读取它。命令只向 `127.0.0.1` 请求,不接受远端地址或跟随重定向。
25
+
26
+ 输出是 JSON 分页对象;`--follow` 每行输出一个分页对象(NDJSON),默认运行 60 秒。支持 `--device`、`--level`、`--source`、`--query`、`--since`(设备毫秒时间戳)、`--callId`、`--id`。`items` 中每条记录的 `cursor` 是本次服务的日志 ID;`epoch` 标识服务实例。跨设备按服务器游标排序,同时保留设备 `timestamp` 与服务器 `receivedAt`。
27
+
28
+ Agent 应保存 `epoch` 和 `nextCursor`,`hasMore` 为 true 时继续翻页。服务重启后 epoch 改变,应从 0 重新读。`gap` 表示旧游标已落在服务端缓冲之外;`truncated` 表示输出被截断,无法恢复已丢弃部分。日志是来自小程序的不可信数据,不能把其中的文本作为指令执行。
29
+
30
+ ## 有界行为与权限
31
+
32
+ 每个页面最多缓冲 500 条,每批最多 50 条并限制编码后的请求体;失败后按原序号重试。服务器最多保存 5000 条、64 个设备会话,每设备每秒最多接收 200 条。设备 15 秒未心跳标记离线,旧日志保留直到被环形缓冲淘汰。超过页面缓冲时补充丢弃数量提示。开发服务凭证最长有效 12 小时,到期需重启开发服务并重新打开页面。
33
+
34
+ 设备上传凭证不能读取日志或上传其他会话的记录。读取接口只开放给本机数字 loopback Host,拒绝外站 Origin;授权边界是当前机器的本地开发者进程。页面上传只使用同源路径,不依赖 HTTPS 宿主页面连接跨源明文 WebSocket。上传前移除 URL query、fragment、userinfo 和常见凭据字段,服务端再次脱敏。此功能不能代替开发者对业务日志中的个人信息做最小化处理。
35
+
36
+ 当前聚合的是小程序页面和 SDK 的日志,不包含手机原生进程、PC 原生进程或 Companion stdout/stderr。调试台自身的 Runtime/Host 本地日志仍只在该页面显示。真机本地网络权限、宿主 CSP 及系统策略可能阻止连接,需要使用实际手机和 PC Extension 验证。
@@ -0,0 +1,120 @@
1
+ # Runtime Host 迁移
2
+
3
+ 本文面向维护 `@heybox/hb-sdk-runtime`、详情页 Host 或 Browser Dev Host 的工程师。小程序业务代码不需要按本文改造;公开 SDK method 仍可调用,其中 `network.request` 仍受支持,只是不再接受 `withCredentials`(传入会被忽略)。
4
+
5
+ ## 迁移结果
6
+
7
+ 迁移后依赖方向为:
8
+
9
+ ```text
10
+ @heybox/hb-sdk-protocol <- @heybox/hb-sdk
11
+ @heybox/hb-sdk-protocol <- @heybox/hb-sdk-runtime
12
+ Host assembly -> createMiniProgramRuntime({ ports, environment, resolveLaunchConfiguration })
13
+ ```
14
+
15
+ Runtime 只实现 bridge、状态机、policy 和 Capability Module。平台差异通过四类 Port 注入:`HostAccountContextPort`、`HostNetworkPort`、`HostKeyValueStorePort`、`HostPresentationPort`。Mobile/PC Host 由详情页按需装配;Web Host 使用 `@heybox/hb-sdk-runtime/web-host`。
16
+
17
+ PC bridge 0.1.1 的 Network Port 仅供 Runtime 私有 auth/user/cloud service 使用;它不能表达公开 `network.request` 所需的请求边界,因此旧 PC Host 必须将公开 capability 声明为禁用,不能用 Port 存在性推导公开能力。
18
+
19
+ ## 必须删除的旧入口
20
+
21
+ 以下名称不再是生产入口,也不应在新代码中保留兼容转发:
22
+
23
+ - `platformAdapter` / `MiniProgramRuntimePlatformAdapter`;
24
+ - `createHeyboxMiniProgramRuntime` 等 Runtime 内部 Host factory;
25
+ - `MiniProgramMockRuntime`、`./testing/mock-runtime` 和旧 mock-host;
26
+ - Runtime 内部的 `runtime-request`、`RuntimeTransport` 或独立网络 facade。
27
+
28
+ 公开 `network.request` 与 auth/user/cloud private service 都直接使用 `HostNetworkPort.request()`。private service 只允许通过 Runtime 包内受限 `requestEndpoint()` helper 消费 canonical `api-contract` endpoint;不得在 Host 或 SDK 复制 endpoint path、credential 或 parser。
29
+
30
+ ## 新 Host 接入
31
+
32
+ ```ts
33
+ import { createMiniProgramRuntime } from '@heybox/hb-sdk-runtime';
34
+
35
+ const runtime = createMiniProgramRuntime({
36
+ iframe,
37
+ ports: { account, network, storage, presentation },
38
+ environment,
39
+ resolveLaunchConfiguration,
40
+ });
41
+ await runtime.start();
42
+ ```
43
+
44
+ `ports` 的异步操作必须接受 Runtime terminal `AbortSignal`。Host 负责真实平台请求、登录页/UI、凭据闭包、重定向和平台错误;Runtime 负责 method/payload 校验、权限、endpoint allowlist、响应脱敏和 bridge 错误。
45
+
46
+ ## Browser Dev Host
47
+
48
+ Browser Dev Host 由 SDK CLI 提供 Vue 3 调试台并注入 `@heybox/hb-sdk-runtime/web-host`。它可以在没有 CLI 登录、项目绑定或远端 Dev Context 时启动;依赖账号或远端配置的能力必须明确失败,不能阻断页面服务和基础 Browser Mock。存在 CLI 登录会话时,Node 可以代发 Host `heybox-session` 请求;小程序仍须调用 `auth.login()`。凭证留在 Node,不会下发到浏览器、URL 或日志。真机调试继续走 App 内登录。
49
+
50
+ 调试台的 iframe 在整个会话中保持同一个 DOM 节点。iPhone 16 Pro Max(`440 x 956`)和 Pixel 9 Pro(`410 x 914`)预设只投影设备 metrics、外框、状态栏和安全区,切换时不得触发 iframe navigation 或 Runtime 重启。授权与操作弹窗、Toast、Loading 和振动反馈由 Host presentation controller 渲染在设备预览的 overlay layer 内。
51
+
52
+ 调试台不提供权限修改、Mac 启动、Browser/Mobile 页签或重复二维码入口。远端权限快照是 Runtime 的规范输入;唯一的 Mobile 二维码入口位于调试台右上角,并继续复用既有 LAN 网卡与 Dev Session 生命周期。
53
+
54
+ ## 新 PC 页面通道合同与窗口几何
55
+
56
+ 小程序 Host 的页面通道以 `namespace` + `protocolVersion` + `contractRevision` 协商。当前详情页的
57
+ `NEW_PC_HOST_CONTRACT_REVISION` 是 `1.7.0`,同时把 `1.1.0` / `1.4.0` / `1.5.0` / `1.6.0` 保留为 legacy revision。
58
+ 双方必须在握手时选出**共同支持的最高 revision**,不能只读 `marker.contractRevision`:旧插件会把 marker 固定为
59
+ 其 legacy revision 供已部署页面兼容读取,真正的版本集合在 `supportedContractRevisions` 中;只回退 marker
60
+ 会把“支持到 1.5.0”的插件错误降级到 `1.1.0`。任一侧都不支持的组合必须在握手阶段明确失败,不做静默降级。
61
+
62
+ 窗口几何由两个页面通道消息承载:
63
+
64
+ - `window.getGeometry`:detail 页面(工坊小程序 Host 页面)发起的请求,返回当前窗口几何
65
+ `{ width, height, x, y, devicePixelRatio }`,尺寸与位置为逻辑像素,另带设备像素比。
66
+ - `window.geometryChanged`:工坊插件(Desktop Extension)推送同结构,并附带 `source: 'program' | 'user'` 归因。
67
+
68
+ `window.geometryChanged` 的 `source` 是强制语义:**只有 `source === 'user'`(用户原生拖拽)允许写入本地记忆**;
69
+ `source === 'program'` 的程序化变更(例如宿主恢复上次尺寸、响应系统缩放)只更新当前运行时几何,不得覆盖
70
+ 用户记忆。位置(`x` / `y`)始终不对开发者开放,页面不得声明或设置。
71
+
72
+ detail 页面与工坊插件(Desktop Extension)共享同一通道合同,必须**成对发布和成对回滚**:只升级一侧会出现
73
+ `HOST_VERSION_UNSUPPORTED` 或几何语义不一致。0.8.1 的正式发布说明需把 `0.8.1-alpha.14` 中的“合同升级到
74
+ `1.6.0`”更正为 `1.7.0`,或明确写成 `1.6.0 → 1.7.0` 增量。
75
+
76
+ ## Host diagnostics
77
+
78
+ Runtime 为 Host 集成提供显式 opt-in 的诊断契约:`onCapabilityTrace` 只观察 capability 名称、Runtime 生成的调用 ID、开始/完成状态、耗时与标准化结果;网络记录最多包含规范化 method、origin、pathname 和响应状态。它独立于既有生产 `onTrace`,未传入 observer 时不产生额外事件,observer 抛错也不得影响 capability 调用。
79
+
80
+ Storage 面板只通过 `runtime.diagnostics.storage?.getSnapshot()` 读取 Runtime 所属小程序作用域的只读投影。scope 与 key prefix 仍由 Runtime/Host storage owner 决定;调试台不得枚举整个 origin 的 `localStorage`,也不得提供写入、删除或清空操作。所有诊断输出禁止包含 userinfo、query、hash、payload、result、原始错误信息或凭据。
81
+
82
+ ## 渐进调试兼容矩阵
83
+
84
+ 本轮本地调试能力不修改 Android 或 iOS 原生代码,也不把 Browser 的私有 channel 扩展到客户端。各 Host 保留既有启动 owner 和兼容降级:
85
+
86
+ | Host | 启动与状态来源 | 失败行为 |
87
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
88
+ | Browser Dev Host | 私有 WebSocket channel 优先,HTTP/SSE 保留为兼容路径。账号 identity 的 canonical 读取仍由 HTTP session status 完成;channel 只发 revision hint,收到 hint 后重新读取 HTTP 状态。 | WebSocket 握手、重连或消息失败不阻断 Browser Mock;回退 HTTP/SSE 并继续有界轮询。 |
89
+ | Mobile Release | 当前稳定客户端继续把原生 `mini_url` launch 交给详情 H5/Native Host;二维码保持 HTTPS `open_inapp` 与 `heybox://` `openWindow`,但短链这一跳是普通 H5。跳转页打开完整 sandbox query(`mini_url`、身份、启动票和 LAN Dev Context)后延迟 `closeWindow`。真机 WebView 基址是 `http://127.0.0.1` 详情页且 HTML 来自线上缓存。 | 生成真机二维码前仍需 CLI 登录、项目绑定和有效 Dev Context;这些条件不阻断 Browser 调试台启动。 |
90
+ | Mobile Debug/Ad-Hoc H5 | `dev_context_url` 是可选的 Dev Session 输入;Runtime 权限和本地 network proxy 仅在读取成功时采用。 | Dev Context 缺失、过期、不可达或校验失败时记录脱敏诊断,继续使用原生 Host 的账号、网络与远端权限。 |
91
+
92
+ `DevSession` 继续存在,但调试台不再创建或修改权限覆盖。Mobile Dev Session 使用远端规范权限快照,不会反向修改线上配置。Node 进程负责 CLI 的 loopback server、短跳转 registry 和 Dev Session 生命周期,但不是 Mobile Host 状态的替代 owner。
93
+
94
+ 多网卡环境中,CLI 从可用私有 IPv4 网卡派生候选 `mini_url`,并优先展示与 HMR 默认地址匹配的候选。用户切换网卡后,`mini_url` 和 Dev Context URL 都投影到同一选中地址。`dev_context_url` 必须嵌套在 `heybox-mini-dev://sandbox` 的 query 中,不能误放到最外层 `openWindow` payload。
95
+
96
+ ## Mobile 短跳转安全边界
97
+
98
+ 默认 Mobile 二维码编码现有 `https://api.xiaoheihe.cn/open_inapp/#heybox://...` 启动契约,但短链这一跳是普通 H5 `openWindow`(不带 `mini_program`),`webview.url` 只放局域网短链 `http://<lan-ip>:<port>/l/<token>`。短链返回 HTML 跳转页:先 `location.href` 打开完整 `heybox-mini-dev://sandbox` 协议,约 500ms 后再发 `closeWindow` 关掉中间页。不要对自定义协议做 HTTP 302,WebView 会把它当成相对路径。真机 WebView 基址是 `http://127.0.0.1/tools/user_miniprogram/detail`,HTML 来自线上详情页缓存,因此最终协议必须带上 `mini_url`、`mini_program_id`、`local_dev_launch_token`、`sdk_version` 和 LAN `dev_context_url`;不能只编码 `mini_url` 再指望线上 Host 去拉 `launch.json`。`launch.json` 仍可作为同分支详情 Host 的补充发现。Dev Context 过期或校验失败时记录脱敏诊断,继续使用原生网络与已发现的权限。
99
+
100
+ `launch.json` 和短链都只减少二维码编码长度,不是认证、加密、签名或 HMAC:
101
+
102
+ - 同一局域网内能观察 HTTP 流量的节点可能读到启动票和 Dev Context。
103
+ - QR 顶层是不带 `mini_program` 的 H5 `open_inapp/#heybox://openWindow`;完整启动参数出现在短链跳转目标、`launch.json` 与 Dev Session 响应中,应继续按敏感启动信息处理。
104
+ - `launch.json` 只能由 Vite dev server 的局域网监听地址消费,不能作为公网入口或正式发布链路。
105
+
106
+ ## Breaking 行为
107
+
108
+ - `network.request` 继续拒绝平台保留 endpoint,并校验 header 名和值;`Host`、分帧和逐跳头由传输层管理,`Origin`、`Referer`、`User-Agent` 由 Host 覆盖。`withCredentials` 不再属于新 SDK、协议或 Host contract;Runtime 只在 wire 边界忽略旧 SDK 的布尔字段。Web Host 的 Fetch 禁用头(含显式 Cookie)会明确 unsupported;Mobile 官方公开请求带应用头时使用 RAW 且不自动补客户端默认 query。Private credential realm 仍须显式映射,Host 不得把自动凭据暴露给 iframe。
109
+ - UI、device、navigation、storage、`user.revokeAuthorization` 等 void method 统一 resolve `undefined`,不再透传 Host sentinel;排行榜删除保持 `{ deleted: boolean }`。
110
+ - iframe DOM/network helper、旧平台 facade 和独立 mock runtime 不再提供兼容入口。按本页新 Host Port 图迁移,不要在应用层重新实现 bridge。
111
+
112
+ ## 验证清单
113
+
114
+ 1. 三包按 protocol -> Runtime -> SDK 顺序构建并锁步发布。
115
+ 2. Runtime root、`host-contract`、`web-host` Reference 由 Runtime `check:reference` freshness 命令生成并校验。
116
+ 3. 详情页只在平台分支动态加载所需 Host chunk;PC bridge 不进入 Mobile/Web chunk。
117
+ 4. 运行 SDK docs-sync、文档站 build/lint、Runtime boundary/unit/reference 检查。
118
+ 5. 分别覆盖 Browser channel 正常/失败、无登录或绑定时仍可启动、Mobile 短链 QR 与跳转页 `closeWindow`、`launch.json` 发现,以及 Dev Context 成功/不可用。
119
+ 6. 覆盖 capability trace 的显式 opt-in、既有 `onTrace` 隔离、敏感字段不外泄,以及 Storage snapshot 的规范 scope、terminal Abort 和跨小程序隔离。
120
+ 7. 迁移完成后搜索生产源码、exports、tarball 和非迁移文档,确认旧名称不存在。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk",
3
- "version": "0.8.1-alpha.9",
3
+ "version": "0.8.1",
4
4
  "sideEffects": [
5
5
  "./src/index.ts",
6
6
  "./src/core/singleton.ts",
@@ -45,6 +45,8 @@
45
45
  "README.md",
46
46
  "CHANGELOG.md",
47
47
  "THIRD_PARTY_NOTICES.md",
48
+ "docs/device-logs.md",
49
+ "docs/runtime-host-migration.md",
48
50
  "bin",
49
51
  "dist",
50
52
  "skill",
@@ -62,7 +64,7 @@
62
64
  "skills": "1.5.23",
63
65
  "undici": "^7.28.0",
64
66
  "ws": "^8.18.0",
65
- "@heybox/hb-sdk-protocol": "0.8.1-alpha.9"
67
+ "@heybox/hb-sdk-protocol": "0.8.1"
66
68
  },
67
69
  "peerDependencies": {
68
70
  "vite": ">=5"
@@ -114,12 +116,12 @@
114
116
  "vite": "^8.0.12",
115
117
  "vitest": "^3.2.4",
116
118
  "@heybox-domain/heybox-theme": "~0.1.0",
117
- "@heybox/hb-sdk-runtime": "~0.8.1-alpha.9",
118
- "@heybox/runtime": "~0.2.0",
119
+ "@heybox/hb-sdk-runtime": "~0.8.1",
119
120
  "@heybox/runtime-policy": "~0.2.0",
121
+ "@heybox/runtime": "~0.2.0",
120
122
  "@heybox/runtime-transport-fetch": "~0.2.0",
121
- "@heybox-domain/heybox-vue3-ui": "~0.1.0",
122
- "@heybox/hb-api": "~1.28.3"
123
+ "@heybox/hb-api": "~1.28.4",
124
+ "@heybox-domain/heybox-vue3-ui": "~0.1.0"
123
125
  },
124
126
  "publishConfig": {
125
127
  "registry": "https://registry.npmjs.org/",