@heybox/hb-sdk 0.9.1-alpha.3 → 0.9.1-alpha.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.
Files changed (110) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/README.md +11 -0
  3. package/dist/card-controller.cjs.js +194 -0
  4. package/dist/card-controller.esm.js +159 -0
  5. package/dist/cli-chunks/{build-CXfLIArV.cjs → build-D91J_GAa.cjs} +13 -7
  6. package/dist/cli-chunks/{context-28ngGR4F.cjs → context-Xdd45FFd.cjs} +4 -4
  7. package/dist/cli-chunks/{create-5YcojPd6.cjs → create-BzpdRC5r.cjs} +1 -1
  8. package/dist/cli-chunks/{dev-BeFMlbOR.cjs → dev-C7acO3Kt.cjs} +56 -10
  9. package/dist/cli-chunks/{doctor-CqadEn3n.cjs → doctor-BgHRDQmG.cjs} +1 -1
  10. package/dist/cli-chunks/{index-GE8dMvDl.cjs → index-CjhQXbxy.cjs} +4 -7
  11. package/dist/cli-chunks/{index-Dexro5MZ.cjs → index-TQwjvNjL.cjs} +33 -17
  12. package/dist/cli-chunks/{index.esm-BjCGi12Z.cjs → index.esm-dgqkvowo.cjs} +7 -7
  13. package/dist/cli-chunks/{login-D4RB9Ben.cjs → login-B14iGXHh.cjs} +2 -2
  14. package/dist/cli-chunks/{project-vite-7ns71VB6.cjs → project-vite-CN6mMjzX.cjs} +1 -1
  15. package/dist/cli-chunks/{remote-DMxbElj_.cjs → remote-C9RUiZxK.cjs} +25 -17
  16. package/dist/cli-chunks/runtime-gate-CfAkz0p-.cjs +201950 -0
  17. package/dist/cli-chunks/{runtime-permission-env-CHeBjX3l.cjs → runtime-permission-env-L7OfyRcl.cjs} +7295 -812
  18. package/dist/cli-chunks/{session-B3q86WA5.cjs → session-DZrr6RYK.cjs} +2 -1
  19. package/dist/cli-chunks/{skill-CnjlGsLj.cjs → skill-BHTVho1a.cjs} +2 -2
  20. package/dist/cli-chunks/{version-BnnLp_km.cjs → version-C_NaCZ8O.cjs} +1 -1
  21. package/dist/cli.cjs +1 -1
  22. package/dist/devtools/browser-dev-host/assets/browser-dev-host-KPFU0Lsa.js +102 -0
  23. package/dist/devtools/browser-dev-host/assets/{desktop-app-launch-e2ZHzPgD.js → desktop-app-launch-BNF9Yk4P.js} +3 -3
  24. package/dist/devtools/browser-dev-host/assets/{index-ClSYpidU.css → index-BRxbUJVN.css} +1 -1
  25. package/dist/devtools/browser-dev-host/assets/{index-D9bz_RbJ.js → index-DRRtB9Nm.js} +4 -4
  26. package/dist/devtools/browser-dev-host/index.html +3 -3
  27. package/dist/index.cjs.js +6252 -279
  28. package/dist/index.esm.js +6252 -280
  29. package/dist/miniapp-publish.cjs.js +6612 -157
  30. package/dist/miniapp-publish.esm.js +6612 -158
  31. package/dist/protocol.cjs.js +5815 -0
  32. package/dist/protocol.esm.js +5815 -1
  33. package/dist/vite.cjs.js +7475 -206
  34. package/dist/vite.esm.js +7474 -207
  35. package/dist/workspace-card-build-sandbox-worker.mjs +72 -0
  36. package/package.json +25 -11
  37. package/skill/skill.json +4 -4
  38. package/types/card-controller.d.ts +3682 -0
  39. package/types/index.d.ts +7532 -35
  40. package/types/miniapp-publish/index.d.ts +542 -64
  41. package/types/protocol.d.ts +2083 -9
  42. package/types/vite/index.d.ts +25 -12
  43. package/dist/cli-chunks/runtime-gate-C__ySQYU.cjs +0 -65
  44. package/dist/devtools/browser-dev-host/assets/browser-dev-host-DBjCd6Dd.js +0 -102
  45. package/types/core/client.d.ts +0 -108
  46. package/types/core/csp-violation.d.ts +0 -5
  47. package/types/core/errors.d.ts +0 -78
  48. package/types/core/event-bus.d.ts +0 -11
  49. package/types/core/handshake-state.d.ts +0 -54
  50. package/types/core/history-observer.d.ts +0 -4
  51. package/types/core/mini-dev-console.d.ts +0 -36
  52. package/types/core/network-sanitize.d.ts +0 -31
  53. package/types/core/sdk.d.ts +0 -104
  54. package/types/core/singleton.d.ts +0 -372
  55. package/types/core/utils.d.ts +0 -10
  56. package/types/core/version.d.ts +0 -2
  57. package/types/devtools/device-logs.d.ts +0 -48
  58. package/types/miniapp-manifest/basic-info-browser.d.ts +0 -37
  59. package/types/miniapp-manifest/basic-info-image-header.d.ts +0 -6
  60. package/types/miniapp-manifest/basic-info-node.d.ts +0 -17
  61. package/types/miniapp-manifest/basic-info-placeholder.d.ts +0 -1
  62. package/types/miniapp-manifest/basic-info.d.ts +0 -33
  63. package/types/miniapp-manifest/bindings.d.ts +0 -70
  64. package/types/miniapp-manifest/category.d.ts +0 -11
  65. package/types/miniapp-manifest/companion-directory.d.ts +0 -2
  66. package/types/miniapp-manifest/companion-executable.d.ts +0 -4
  67. package/types/miniapp-manifest/companion-types.d.ts +0 -63
  68. package/types/miniapp-manifest/companions.d.ts +0 -17
  69. package/types/miniapp-manifest/index.d.ts +0 -7
  70. package/types/miniapp-manifest/node.d.ts +0 -22
  71. package/types/miniapp-manifest/permissions.d.ts +0 -48
  72. package/types/miniapp-manifest/runtime-gate.d.ts +0 -12
  73. package/types/miniapp-manifest/schema.d.ts +0 -302
  74. package/types/modules/auth/index.d.ts +0 -204
  75. package/types/modules/cloud/index.d.ts +0 -669
  76. package/types/modules/companion/index.d.ts +0 -1619
  77. package/types/modules/device/index.d.ts +0 -193
  78. package/types/modules/environment/index.d.ts +0 -238
  79. package/types/modules/files/index.d.ts +0 -5
  80. package/types/modules/files/registry.d.ts +0 -35
  81. package/types/modules/files/types.d.ts +0 -1548
  82. package/types/modules/navigation/app-pages/index.d.ts +0 -4
  83. package/types/modules/navigation/app-pages/types.d.ts +0 -135
  84. package/types/modules/navigation/index.d.ts +0 -312
  85. package/types/modules/network/index.d.ts +0 -457
  86. package/types/modules/network/observability.d.ts +0 -38
  87. package/types/modules/network/request-shape.d.ts +0 -44
  88. package/types/modules/share/copy-link.d.ts +0 -46
  89. package/types/modules/share/extra.d.ts +0 -5
  90. package/types/modules/share/index.d.ts +0 -294
  91. package/types/modules/share/screenshot.d.ts +0 -34
  92. package/types/modules/share/show-share-menu.d.ts +0 -29
  93. package/types/modules/share/types.d.ts +0 -201
  94. package/types/modules/storage/index.d.ts +0 -214
  95. package/types/modules/ui/index.d.ts +0 -315
  96. package/types/modules/user/get-info.d.ts +0 -44
  97. package/types/modules/user/index.d.ts +0 -245
  98. package/types/modules/user/revoke-authorization.d.ts +0 -31
  99. package/types/modules/user/steam-game-list.d.ts +0 -153
  100. package/types/modules/user/types.d.ts +0 -2
  101. package/types/modules/viewport/index.d.ts +0 -319
  102. package/types/protocol/capabilities.d.ts +0 -2
  103. package/types/protocol/constants.d.ts +0 -1
  104. package/types/protocol/dev-session.d.ts +0 -74
  105. package/types/protocol/guards.d.ts +0 -1
  106. package/types/protocol/runtime-permissions.d.ts +0 -2
  107. package/types/protocol/types.d.ts +0 -22
  108. package/types/skill-metadata.d.ts +0 -18
  109. package/types/vite/html-policy.d.ts +0 -6
  110. package/types/vite/runtime-permission-env.d.ts +0 -9
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  本文件随 `@heybox/hb-sdk` npm 包公开分发,只记录外部小程序开发者可观察到的变化。
4
4
 
5
+ ## 0.9.1-alpha.5
6
+
7
+ - 工作区卡片 Controller v2 支持在本地开发入口调试,并校验控制器依赖、权限及卡片参数。
8
+ - 旧 Host 不支持工作区卡片时,能力错误保留原始错误数据和原因,便于诊断。
9
+
10
+ ## 0.9.1-alpha.4 - 2026-10-14
11
+
12
+ ### 新增能力
13
+
14
+ - 预留 `hbSDK.device.executeProtocol()`(暂不对外开放):在获得平台批准的 `appProtocol` 权限后执行任意小黑盒协议,支持完整协议字符串与 JSON 协议对象;返回 `Promise<void>`,成功只表示已投递,不转发协议业务返回值或回调。
15
+ - 预留最高危险等级权限 `appProtocol`(暂不对外开放,不提供开发者申请入口):批准后该入口可执行任意协议,并绕过其他 SDK 能力权限及其专用授权流程;该总授权只作用于 `device.executeProtocol()`,其他 SDK 方法仍执行各自权限与授权规则。
16
+ - `hb-sdk dev` 支持为已声明但未获线上批准的 `appProtocol` 生成当前 Dev Session 的本地临时授权;浏览器调试台记录协议类型并以 Mock 投递成功,不模拟真实协议效果。
17
+
18
+ ### 问题修复
19
+
20
+ - 协议执行收到取消后停止尚未投递的后续动作;调用超时或 SDK 销毁时通知 Host 取消,已投递的系统动作不会撤销。
21
+ - 协议对象中的函数、Symbol 等无法发送的参数统一返回 `INVALID_PARAMS`,保留原始原因供排查。
22
+
23
+ ### 文档与工具
24
+
25
+ - 权限指南、API Reference、CLI 调试说明与 `hb-sdk remote permission apply` 同步 `appProtocol` 与 `device.executeProtocol`。
26
+
5
27
  ## 0.9.1-alpha.3 - 2026-10-14
6
28
 
7
29
  ### 问题修复
@@ -135,7 +157,7 @@
135
157
 
136
158
  > 影响级别:常规
137
159
  > 开发者动作:升级至 `0.9.0-alpha.0` 并重新运行 `hb-sdk dev`;运行期间在后台调整权限后,请重启 CLI 同步。
138
- > 兼容范围:公开 SDK API 不变;调整本地真实客户端调试的详情读取与启动票可用条件。
160
+ > 兼容范围:既有公开 SDK API 保持兼容;新增工作区卡片入口,并调整本地真实客户端调试的详情读取与启动票可用条件。
139
161
 
140
162
  ### 行为调整
141
163
 
@@ -148,6 +170,9 @@
148
170
  - 修复声明连续变化时,旧详情、产物摘要或启动票覆盖最新调试状态的问题。
149
171
  - 修复详情校验失败后仍能通过本地启动入口获取续签票据的问题。
150
172
 
173
+ - 新增 `@heybox/hb-sdk/card-controller` 公开入口,用于声明工作区卡片 Controller 和卡片视图。
174
+ - 新增 `workspaceCards.requestRefresh()`、`getLaunchContext()` 和 `onLaunchContextChange()`,用于在支持工作区卡片的桌面 Host 中刷新卡片和读取启动上下文。
175
+
151
176
  ## 0.8.5 - 2026-10-02
152
177
 
153
178
  > 影响级别:必须操作
@@ -332,7 +357,6 @@
332
357
 
333
358
  - 补充游戏详情页资源位申请规则、图标制作规范和申请流程说明。
334
359
 
335
-
336
360
  ## 0.8.2 - 2026-09-21
337
361
 
338
362
  > 摘要:版本名称与图片改由项目维护,新增 Steam 账号授权,并调整部署与用户数据边界。
@@ -551,6 +575,7 @@
551
575
 
552
576
  - 目标平台声明统一迁移到 `package.json#heybox.platforms`;`miniappManifest()` 恢复无参调用,并在构建时将该声明写入 `dist/manifest.json`。
553
577
  - `hb-sdk dev`、`hb-sdk build` 和普通 `hb-sdk remote deploy` 会拒绝缺失或非法的平台声明;build/deploy 也会拒绝与项目配置不一致的 Manifest。已有项目升级时需把原 Vite 参数中的 `platforms` 移入 `package.json#heybox`。
578
+
554
579
  ## 0.8.1-alpha.2
555
580
 
556
581
  - 新增 `environment.getInfo()` 与 `environment.getInfoSync()`,用于读取运行模式、小黑盒 App 版本、canonical 小程序 ID/版本、操作系统和 SDK 版本的冻结快照。
package/README.md CHANGED
@@ -501,3 +501,14 @@ Host/Runtime 集成维护者请先阅读 [`@heybox/hb-sdk-runtime` README](../hb
501
501
  ### 终端权限申请
502
502
 
503
503
  绑定小程序后,可用 `hb-sdk remote permission list` 查看平台状态和最近申请;使用 `hb-sdk remote permission apply network --reason "访问业务接口" --domains "api.example.com"` 或 `hb-sdk remote permission apply companion --reason "运行桌面辅助应用"` 提交申请。两种命令均支持 `--json`,无需上传版本;获批后仍需声明 Manifest 权限。
504
+
505
+ ### 工作区卡片(开发中)
506
+
507
+ 在支持该能力的 PC 游戏工作区展示小程序概览和操作。项目声明指定一个 Controller 文件;
508
+ Controller 使用 `@heybox/hb-sdk/card-controller` 编写,普通页面使用根 SDK 的 `workspaceCards` 模块。
509
+ 浏览器调试页只提供登录、绑定、启动和状态,不渲染卡片,须在真实 PC 验收。
510
+
511
+ 完整配置、三个示例、页面协作、调试发布与排障见 [工作区卡片指南](https://docs.xiaoheihe.cn/hb_sdk/guide/workspace-cards)。
512
+
513
+ 卡片合同只在开发构建时依赖私有 `@ai-desktop/view-contract`,发布 JS 与声明已封装所需代码和类型。
514
+ 用户安装 hb-sdk 不需要该私有包;`check:bundled-contract` 阻止未内联引用进入发布制品。
@@ -0,0 +1,194 @@
1
+ 'use strict';
2
+
3
+ /** 小程序固定受管动作入口。 */
4
+ const WORKSPACE_CARD_COMMANDS = {
5
+ invoke: 'ai-desktop.heybox-user-miniprogram.workspace-cards.invoke',
6
+ openMiniProgram: 'ai-desktop.heybox-user-miniprogram.workspace-cards.open-mini-program',
7
+ };
8
+
9
+ const VIEW_SCHEMA_VERSION = 1;
10
+ function compact(value) {
11
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
12
+ }
13
+ function vstack(children, options = {}) {
14
+ return compact({ type: "vstack", children, ...options });
15
+ }
16
+ function hstack(children, options = {}) {
17
+ return compact({ type: "hstack", children, ...options });
18
+ }
19
+ function zstack(children, options = {}) {
20
+ return compact({ type: "zstack", children, ...options });
21
+ }
22
+ function grid(columns, children, options = {}) {
23
+ return compact({ type: "grid", columns, children, ...options });
24
+ }
25
+ function carousel(id, label, children, options = {}) {
26
+ return compact({ type: "carousel", id, label, children, ...options });
27
+ }
28
+ function group(children, options = {}) {
29
+ return compact({ type: "group", children, ...options });
30
+ }
31
+ function spacer(options = {}) {
32
+ return compact({ type: "spacer", ...options });
33
+ }
34
+ function text(value, options = {}) {
35
+ return compact({ type: "text", value, ...options });
36
+ }
37
+ function image(src, options = {}) {
38
+ return compact({ type: "image", src, ...options });
39
+ }
40
+ function icon(name, options = {}) {
41
+ return compact({ type: "icon", name, ...options });
42
+ }
43
+ function fields(items, options = {}) {
44
+ return compact({ type: "fields", items, ...options });
45
+ }
46
+ function list(items, options = {}) {
47
+ return compact({ type: "list", items, ...options });
48
+ }
49
+ function badge(value, options = {}) {
50
+ return compact({ type: "badge", text: value, ...options });
51
+ }
52
+ function divider(options = {}) {
53
+ return compact({ type: "divider", ...options });
54
+ }
55
+ function button(value, options = {}) {
56
+ return compact({ type: "button", text: value, ...options });
57
+ }
58
+ function tabs(id, items, options = {}) {
59
+ return compact({ type: "tabs", id, items, ...options });
60
+ }
61
+ function textField(id, label, options = {}) {
62
+ return compact({ type: "textField", id, label, ...options });
63
+ }
64
+ function toggle(id, label, checked, options = {}) {
65
+ return compact({ type: "switch", id, label, checked, ...options });
66
+ }
67
+ function expandable(id, children, options) {
68
+ return { type: "expandable", id, children, ...options };
69
+ }
70
+ function renderer(id, rendererViewId, options = {}) {
71
+ return compact({ type: "renderer", id, rendererViewId, ...options });
72
+ }
73
+ function frame(id, frameId, options = {}) {
74
+ return compact({ type: "frame", id, frameId, ...options });
75
+ }
76
+ function meter(value, options = {}) {
77
+ return compact({ type: "meter", value, ...options });
78
+ }
79
+ function radialProgress(value, label, options = {}) {
80
+ return compact({ type: "radialProgress", value, label, ...options });
81
+ }
82
+ function barChart(label, items, options = {}) {
83
+ return compact({ type: "barChart", label, items, ...options });
84
+ }
85
+ function region(id, status, nodes = [], options = {}) {
86
+ return compact({ id, status, nodes, ...options });
87
+ }
88
+ function viewDocument(regions, options = {}) {
89
+ return compact({ schema: VIEW_SCHEMA_VERSION, regions: [...regions], ...options });
90
+ }
91
+
92
+ function defineCard(definition) { return definition; }
93
+ const actionInput = {
94
+ string: (options = {}) => ({ type: 'string', ...options }),
95
+ number: () => ({ type: 'number' }),
96
+ boolean: () => ({ type: 'boolean' }),
97
+ array: (items, options = {}) => ({ type: 'array', items, ...options }),
98
+ object: (properties) => ({
99
+ type: 'object', properties, required: Object.keys(properties), additionalProperties: false,
100
+ }),
101
+ };
102
+ function defineAction(definition) {
103
+ let actionId;
104
+ const pending = [];
105
+ const handle = ((input) => {
106
+ const value = invoke(actionId ?? '__unbound__', input);
107
+ if (!actionId)
108
+ pending.push(value);
109
+ return value;
110
+ });
111
+ handle.kind = 'invoke';
112
+ handle.input = definition.input;
113
+ handle.run = definition.run;
114
+ Object.defineProperty(handle, 'bindActionId', { value: (id) => {
115
+ if (actionId && actionId !== id)
116
+ throw new Error('Workspace Card action handle 不能绑定多个 ID');
117
+ actionId = id;
118
+ for (const value of pending)
119
+ value.input.actionId = id;
120
+ pending.length = 0;
121
+ } });
122
+ return handle;
123
+ }
124
+ function defineOpenMiniProgramAction(options = {}) {
125
+ let actionId;
126
+ const pending = [];
127
+ const handle = ((input) => {
128
+ const value = openMiniProgram(actionId ?? '__unbound__', input);
129
+ if (!actionId)
130
+ pending.push(value);
131
+ return value;
132
+ });
133
+ handle.kind = 'openMiniProgram';
134
+ handle.input = options.input;
135
+ Object.defineProperty(handle, 'bindActionId', { value: (id) => {
136
+ if (actionId && actionId !== id)
137
+ throw new Error('Workspace Card action handle 不能绑定多个 ID');
138
+ actionId = id;
139
+ for (const value of pending)
140
+ value.input.actionId = id;
141
+ pending.length = 0;
142
+ } });
143
+ return handle;
144
+ }
145
+ function defineWorkspaceCardsController(controller) {
146
+ for (const [id, action] of Object.entries(controller.actions ?? {}))
147
+ action.bindActionId?.(id);
148
+ return controller;
149
+ }
150
+ /** 定义控制器;构建器和 Host 分别验证静态 action 表。 */
151
+ function defineWorkspaceCardController(controller) { return controller; }
152
+ /** 生成固定受管 invoke 入口;身份由 Host 根据真实卡片绑定。 */
153
+ function invoke(actionId, params) {
154
+ return { commandId: WORKSPACE_CARD_COMMANDS.invoke, input: { actionId, ...(params === undefined ? {} : { params }) } };
155
+ }
156
+ /** 只允许打开当前小程序。 */
157
+ function openMiniProgram(actionId, params) {
158
+ return { commandId: WORKSPACE_CARD_COMMANDS.openMiniProgram, input: { actionId, ...(params === undefined ? {} : { params }) } };
159
+ }
160
+
161
+ exports.actionInput = actionInput;
162
+ exports.badge = badge;
163
+ exports.barChart = barChart;
164
+ exports.button = button;
165
+ exports.carousel = carousel;
166
+ exports.defineAction = defineAction;
167
+ exports.defineCard = defineCard;
168
+ exports.defineOpenMiniProgramAction = defineOpenMiniProgramAction;
169
+ exports.defineWorkspaceCardController = defineWorkspaceCardController;
170
+ exports.defineWorkspaceCardsController = defineWorkspaceCardsController;
171
+ exports.divider = divider;
172
+ exports.expandable = expandable;
173
+ exports.fields = fields;
174
+ exports.frame = frame;
175
+ exports.grid = grid;
176
+ exports.group = group;
177
+ exports.hstack = hstack;
178
+ exports.icon = icon;
179
+ exports.image = image;
180
+ exports.invoke = invoke;
181
+ exports.list = list;
182
+ exports.meter = meter;
183
+ exports.openMiniProgram = openMiniProgram;
184
+ exports.radialProgress = radialProgress;
185
+ exports.region = region;
186
+ exports.renderer = renderer;
187
+ exports.spacer = spacer;
188
+ exports.tabs = tabs;
189
+ exports.text = text;
190
+ exports.textField = textField;
191
+ exports.toggle = toggle;
192
+ exports.viewDocument = viewDocument;
193
+ exports.vstack = vstack;
194
+ exports.zstack = zstack;
@@ -0,0 +1,159 @@
1
+ /** 小程序固定受管动作入口。 */
2
+ const WORKSPACE_CARD_COMMANDS = {
3
+ invoke: 'ai-desktop.heybox-user-miniprogram.workspace-cards.invoke',
4
+ openMiniProgram: 'ai-desktop.heybox-user-miniprogram.workspace-cards.open-mini-program',
5
+ };
6
+
7
+ const VIEW_SCHEMA_VERSION = 1;
8
+ function compact(value) {
9
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
10
+ }
11
+ function vstack(children, options = {}) {
12
+ return compact({ type: "vstack", children, ...options });
13
+ }
14
+ function hstack(children, options = {}) {
15
+ return compact({ type: "hstack", children, ...options });
16
+ }
17
+ function zstack(children, options = {}) {
18
+ return compact({ type: "zstack", children, ...options });
19
+ }
20
+ function grid(columns, children, options = {}) {
21
+ return compact({ type: "grid", columns, children, ...options });
22
+ }
23
+ function carousel(id, label, children, options = {}) {
24
+ return compact({ type: "carousel", id, label, children, ...options });
25
+ }
26
+ function group(children, options = {}) {
27
+ return compact({ type: "group", children, ...options });
28
+ }
29
+ function spacer(options = {}) {
30
+ return compact({ type: "spacer", ...options });
31
+ }
32
+ function text(value, options = {}) {
33
+ return compact({ type: "text", value, ...options });
34
+ }
35
+ function image(src, options = {}) {
36
+ return compact({ type: "image", src, ...options });
37
+ }
38
+ function icon(name, options = {}) {
39
+ return compact({ type: "icon", name, ...options });
40
+ }
41
+ function fields(items, options = {}) {
42
+ return compact({ type: "fields", items, ...options });
43
+ }
44
+ function list(items, options = {}) {
45
+ return compact({ type: "list", items, ...options });
46
+ }
47
+ function badge(value, options = {}) {
48
+ return compact({ type: "badge", text: value, ...options });
49
+ }
50
+ function divider(options = {}) {
51
+ return compact({ type: "divider", ...options });
52
+ }
53
+ function button(value, options = {}) {
54
+ return compact({ type: "button", text: value, ...options });
55
+ }
56
+ function tabs(id, items, options = {}) {
57
+ return compact({ type: "tabs", id, items, ...options });
58
+ }
59
+ function textField(id, label, options = {}) {
60
+ return compact({ type: "textField", id, label, ...options });
61
+ }
62
+ function toggle(id, label, checked, options = {}) {
63
+ return compact({ type: "switch", id, label, checked, ...options });
64
+ }
65
+ function expandable(id, children, options) {
66
+ return { type: "expandable", id, children, ...options };
67
+ }
68
+ function renderer(id, rendererViewId, options = {}) {
69
+ return compact({ type: "renderer", id, rendererViewId, ...options });
70
+ }
71
+ function frame(id, frameId, options = {}) {
72
+ return compact({ type: "frame", id, frameId, ...options });
73
+ }
74
+ function meter(value, options = {}) {
75
+ return compact({ type: "meter", value, ...options });
76
+ }
77
+ function radialProgress(value, label, options = {}) {
78
+ return compact({ type: "radialProgress", value, label, ...options });
79
+ }
80
+ function barChart(label, items, options = {}) {
81
+ return compact({ type: "barChart", label, items, ...options });
82
+ }
83
+ function region(id, status, nodes = [], options = {}) {
84
+ return compact({ id, status, nodes, ...options });
85
+ }
86
+ function viewDocument(regions, options = {}) {
87
+ return compact({ schema: VIEW_SCHEMA_VERSION, regions: [...regions], ...options });
88
+ }
89
+
90
+ function defineCard(definition) { return definition; }
91
+ const actionInput = {
92
+ string: (options = {}) => ({ type: 'string', ...options }),
93
+ number: () => ({ type: 'number' }),
94
+ boolean: () => ({ type: 'boolean' }),
95
+ array: (items, options = {}) => ({ type: 'array', items, ...options }),
96
+ object: (properties) => ({
97
+ type: 'object', properties, required: Object.keys(properties), additionalProperties: false,
98
+ }),
99
+ };
100
+ function defineAction(definition) {
101
+ let actionId;
102
+ const pending = [];
103
+ const handle = ((input) => {
104
+ const value = invoke(actionId ?? '__unbound__', input);
105
+ if (!actionId)
106
+ pending.push(value);
107
+ return value;
108
+ });
109
+ handle.kind = 'invoke';
110
+ handle.input = definition.input;
111
+ handle.run = definition.run;
112
+ Object.defineProperty(handle, 'bindActionId', { value: (id) => {
113
+ if (actionId && actionId !== id)
114
+ throw new Error('Workspace Card action handle 不能绑定多个 ID');
115
+ actionId = id;
116
+ for (const value of pending)
117
+ value.input.actionId = id;
118
+ pending.length = 0;
119
+ } });
120
+ return handle;
121
+ }
122
+ function defineOpenMiniProgramAction(options = {}) {
123
+ let actionId;
124
+ const pending = [];
125
+ const handle = ((input) => {
126
+ const value = openMiniProgram(actionId ?? '__unbound__', input);
127
+ if (!actionId)
128
+ pending.push(value);
129
+ return value;
130
+ });
131
+ handle.kind = 'openMiniProgram';
132
+ handle.input = options.input;
133
+ Object.defineProperty(handle, 'bindActionId', { value: (id) => {
134
+ if (actionId && actionId !== id)
135
+ throw new Error('Workspace Card action handle 不能绑定多个 ID');
136
+ actionId = id;
137
+ for (const value of pending)
138
+ value.input.actionId = id;
139
+ pending.length = 0;
140
+ } });
141
+ return handle;
142
+ }
143
+ function defineWorkspaceCardsController(controller) {
144
+ for (const [id, action] of Object.entries(controller.actions ?? {}))
145
+ action.bindActionId?.(id);
146
+ return controller;
147
+ }
148
+ /** 定义控制器;构建器和 Host 分别验证静态 action 表。 */
149
+ function defineWorkspaceCardController(controller) { return controller; }
150
+ /** 生成固定受管 invoke 入口;身份由 Host 根据真实卡片绑定。 */
151
+ function invoke(actionId, params) {
152
+ return { commandId: WORKSPACE_CARD_COMMANDS.invoke, input: { actionId, ...(params === undefined ? {} : { params }) } };
153
+ }
154
+ /** 只允许打开当前小程序。 */
155
+ function openMiniProgram(actionId, params) {
156
+ return { commandId: WORKSPACE_CARD_COMMANDS.openMiniProgram, input: { actionId, ...(params === undefined ? {} : { params }) } };
157
+ }
158
+
159
+ export { actionInput, badge, barChart, button, carousel, defineAction, defineCard, defineOpenMiniProgramAction, defineWorkspaceCardController, defineWorkspaceCardsController, divider, expandable, fields, frame, grid, group, hstack, icon, image, invoke, list, meter, openMiniProgram, radialProgress, region, renderer, spacer, tabs, text, textField, toggle, viewDocument, vstack, zstack };
@@ -1,19 +1,22 @@
1
1
  'use strict';
2
2
 
3
+ var runtimeGate = require('./runtime-gate-CfAkz0p-.cjs');
3
4
  var fs$1 = require('node:fs');
4
5
  var fs = require('node:fs/promises');
5
6
  var path = require('node:path');
6
- var runtimePermissionEnv = require('./runtime-permission-env-CHeBjX3l.cjs');
7
+ var runtimePermissionEnv = require('./runtime-permission-env-L7OfyRcl.cjs');
7
8
  require('node:crypto');
8
9
  require('node:zlib');
9
- var runtimeGate = require('./runtime-gate-C__ySQYU.cjs');
10
- var index = require('./index-Dexro5MZ.cjs');
11
- var projectVite = require('./project-vite-7ns71VB6.cjs');
12
- require('./version-BnnLp_km.cjs');
13
- require('node:async_hooks');
10
+ var index = require('./index-TQwjvNjL.cjs');
11
+ var projectVite = require('./project-vite-CN6mMjzX.cjs');
14
12
  require('node:module');
13
+ require('node:url');
14
+ require('fs');
15
15
  require('path');
16
16
  require('os');
17
+ require('inspector');
18
+ require('./version-C_NaCZ8O.cjs');
19
+ require('node:async_hooks');
17
20
  require('readline');
18
21
  require('tty');
19
22
  require('assert');
@@ -21,7 +24,6 @@ require('events');
21
24
  require('stream');
22
25
  require('buffer');
23
26
  require('util');
24
- require('node:url');
25
27
 
26
28
  function areStringArraysEqual(left, right) {
27
29
  return left.length === right.length && left.every((value, index) => value === right[index]);
@@ -103,6 +105,10 @@ async function validateBuildOutput(projectRoot, logger, declaredPlatforms, decla
103
105
  logger.warn('dist/manifest.json 包含 BOM,已自动剥离');
104
106
  }
105
107
  const validated = runtimePermissionEnv.validateMiniappManifestForDeploy(manifest);
108
+ if (validated.workspaceCards) {
109
+ runtimeGate.verifyWorkspaceCardsSnapshot({ ...validated, bindAppIds: validated.bindAppIds ?? [], workspaceCards: validated.workspaceCards });
110
+ runtimeGate.verifyWorkspaceCardArtifacts(distDir, validated.workspaceCards);
111
+ }
106
112
  const { platforms, sdkVersion, version, permissions, window } = validated;
107
113
  const bindAppIds = validated.bindAppIds ?? [];
108
114
  if (validated.category !== declaredCategory) {
@@ -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-CHeBjX3l.cjs');
6
+ var runtimePermissionEnv = require('./runtime-permission-env-L7OfyRcl.cjs');
7
7
  var fs$1 = require('node:fs');
8
8
  var sharp = require('sharp');
9
- var session = require('./session-B3q86WA5.cjs');
9
+ var session = require('./session-DZrr6RYK.cjs');
10
10
 
11
11
  async function inspectBasicInfoImage(bytes, sourcePath, kind) {
12
12
  const inspected = await inspectDecodedBasicInfoImage(bytes, kind);
@@ -345,8 +345,8 @@ function resolveBrowserFakeContext(context, now = Date.now()) {
345
345
  runtimePermissions: context.runtimePermissions,
346
346
  revision: parsed.grant.revision,
347
347
  eligiblePermissionKeys: context.platforms?.some((platform) => ['windows', 'macos', 'linux'].includes(platform))
348
- ? ['network', 'companion']
349
- : ['network'],
348
+ ? ['network', 'companion', 'appProtocol']
349
+ : ['network', 'appProtocol'],
350
350
  }),
351
351
  };
352
352
  }
@@ -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-Dexro5MZ.cjs');
8
+ var index = require('./index-TQwjvNjL.cjs');
9
9
  require('node:module');
10
10
  require('os');
11
11
  require('node:crypto');
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var session = require('./session-B3q86WA5.cjs');
4
- var context = require('./context-28ngGR4F.cjs');
3
+ var session = require('./session-DZrr6RYK.cjs');
4
+ var context = require('./context-Xdd45FFd.cjs');
5
5
  var node_crypto = require('node:crypto');
6
6
  var fs = require('node:fs');
7
- var runtimePermissionEnv = require('./runtime-permission-env-CHeBjX3l.cjs');
7
+ var runtimePermissionEnv = require('./runtime-permission-env-L7OfyRcl.cjs');
8
8
  var os = require('node:os');
9
9
  var path = require('node:path');
10
10
  var net = require('node:net');
@@ -13,12 +13,12 @@ var node_http = require('node:http');
13
13
  var node_module = require('node:module');
14
14
  var undici = require('undici');
15
15
  var fs$1 = require('node:fs/promises');
16
- var index = require('./index-Dexro5MZ.cjs');
16
+ var index = require('./index-TQwjvNjL.cjs');
17
17
  var require$$0$1 = require('crypto');
18
18
  var require$$0 = require('buffer');
19
19
  var browser = require('./browser-RAy8e8cV.cjs');
20
- var projectVite = require('./project-vite-7ns71VB6.cjs');
21
- var version = require('./version-BnnLp_km.cjs');
20
+ var projectVite = require('./project-vite-CN6mMjzX.cjs');
21
+ var version = require('./version-C_NaCZ8O.cjs');
22
22
  require('node:zlib');
23
23
 
24
24
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -1993,8 +1993,8 @@ const DEFAULT_CHANNEL_TRANSPORT = {
1993
1993
  };
1994
1994
  const IPV4_LOOPBACK_ADDRESSES = new net.BlockList();
1995
1995
  IPV4_LOOPBACK_ADDRESSES.addSubnet('127.0.0.0', 8, 'ipv4');
1996
- 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-BeFMlbOR.cjs', document.baseURI).href)))('ws');
1997
- 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-BeFMlbOR.cjs', document.baseURI).href)))('parse5');
1996
+ 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-C7acO3Kt.cjs', document.baseURI).href)))('ws');
1997
+ 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-C7acO3Kt.cjs', document.baseURI).href)))('parse5');
1998
1998
  const BROWSER_DEV_HOST_ROOT_CANDIDATES = [
1999
1999
  path.resolve(__dirname, 'devtools/browser-dev-host'),
2000
2000
  path.resolve(__dirname, '../devtools/browser-dev-host'),
@@ -2023,10 +2023,12 @@ async function startBrowserDevHostServer(options) {
2023
2023
  csrfToken: sessionController.csrfToken,
2024
2024
  defaultLanAddressId: options.defaultLanAddressId,
2025
2025
  devContext: options.devContext,
2026
+ devSessionId: options.devSessionId,
2026
2027
  lanAddresses: options.lanAddresses ?? [],
2027
2028
  loginAvailable: options.loginService !== undefined,
2028
2029
  miniProgram: options.miniProgram,
2029
2030
  miniProgramSupportsDesktop: options.miniProgramSupportsDesktop,
2031
+ workspaceCardsEnabled: options.workspaceCardsEnabled === true,
2030
2032
  mobileLaunchRedirect: initialMobileLaunchRedirect,
2031
2033
  nativeAppLaunchUnavailableReason: options.nativeAppLaunchUnavailableReason,
2032
2034
  miniProgramManifestAccessToken: options.miniProgramManifestAccessToken,
@@ -2118,6 +2120,8 @@ async function startBrowserDevHostServer(options) {
2118
2120
  bootstrap.miniProgram = next.miniProgram;
2119
2121
  if (next.miniProgramSupportsDesktop !== undefined)
2120
2122
  bootstrap.miniProgramSupportsDesktop = next.miniProgramSupportsDesktop;
2123
+ if (next.workspaceCardsEnabled !== undefined)
2124
+ bootstrap.workspaceCardsEnabled = next.workspaceCardsEnabled;
2121
2125
  bootstrapJson = serializeBrowserDevHostBootstrap(bootstrap);
2122
2126
  },
2123
2127
  networkUrls: createBrowserDevHostNetworkUrls({
@@ -11090,7 +11094,7 @@ function assertNodeRuntimeCapabilities(ctx, settings) {
11090
11094
  function createNodeRealtimeDriverRegistry() {
11091
11095
  const registry = createRuntimeRealtimeDriverRegistry();
11092
11096
  registry.registerLazy('node-websocket', async () => {
11093
- const mod = await Promise.resolve().then(function () { return require('./index.esm-BjCGi12Z.cjs'); });
11097
+ const mod = await Promise.resolve().then(function () { return require('./index.esm-dgqkvowo.cjs'); });
11094
11098
  return mod.createNodeWebSocketRuntimeDriver();
11095
11099
  });
11096
11100
  return registry;
@@ -15402,6 +15406,9 @@ function writeResponse(response, status, body) {
15402
15406
  response.end(body === undefined ? '' : JSON.stringify(body));
15403
15407
  }
15404
15408
 
15409
+ const WORKSPACE_CARD_LOCAL_DEV_DESCRIPTOR_PATH = '/__hb_sdk__/mini-program/workspace-cards.json';
15410
+ const WORKSPACE_CARD_LOCAL_DEV_MANIFEST_TOKEN_HEADER = 'x-hb-sdk-mini-program-manifest-token';
15411
+
15405
15412
  const DEFAULT_APP_PORT = 5173;
15406
15413
  const DEFAULT_BROWSER_DEV_HOST_PORT = 5174;
15407
15414
  const DEFAULT_DEV_CONTEXT_TIMEOUT_MS = 3000;
@@ -15575,6 +15582,7 @@ async function runDevCommand(options, runtime = {}) {
15575
15582
  port: appPort,
15576
15583
  };
15577
15584
  const projectRoot = projectVite.findProjectRoot(runtime.cwd ?? process.cwd());
15585
+ const workspaceCardsDeclared = runtimePermissionEnv.readMiniappWorkspaceCardsFromPackageJson(projectRoot).declaration !== undefined;
15578
15586
  const companionArtifactAccessToken = (runtime.randomBytes ?? node_crypto.randomBytes)(32).toString('base64url');
15579
15587
  const miniProgramManifestAccessToken = (runtime.randomBytes ?? node_crypto.randomBytes)(32).toString('base64url');
15580
15588
  const devSessionId = node_crypto.randomBytes(16).toString('hex');
@@ -15658,7 +15666,7 @@ async function runDevCommand(options, runtime = {}) {
15658
15666
  const grant = runtimePermissionEnv.createMiniProgramLocalDevGrant({ declaredPermissions: currentDevContext.declaredPermissions ?? {},
15659
15667
  runtimePermissions: currentDevContext.runtimePermissions, revision: contextRevision,
15660
15668
  eligiblePermissionKeys: currentCompanionManifestSha256 && runtimePermissionEnv.hasMiniappDesktopPlatform(currentDevContext.platforms)
15661
- ? ['network', 'companion'] : ['network'] });
15669
+ ? ['network', 'companion', 'appProtocol'] : ['network', 'appProtocol'] });
15662
15670
  if (allowedTemporaryKeys)
15663
15671
  grant.entries = grant.entries.filter(entry => allowedTemporaryKeys.has(entry.key));
15664
15672
  const temporaryWarning = grant.entries.map(entry => entry.key).join('、');
@@ -15700,6 +15708,42 @@ async function runDevCommand(options, runtime = {}) {
15700
15708
  readContextPath: () => devContextPath,
15701
15709
  });
15702
15710
  const launchPlugin = createMiniProgramDevLaunchVitePlugin(readLaunchSource, async (request, response) => {
15711
+ if (request.url === WORKSPACE_CARD_LOCAL_DEV_DESCRIPTOR_PATH) {
15712
+ response.setHeader('Cache-Control', 'no-store');
15713
+ response.setHeader('X-Content-Type-Options', 'nosniff');
15714
+ if (request.method !== 'GET' && request.method !== 'HEAD') {
15715
+ response.writeHead(405, { Allow: 'GET, HEAD' }).end();
15716
+ return true;
15717
+ }
15718
+ const remote = request.socket.remoteAddress;
15719
+ const host = request.headers.host ?? '';
15720
+ const token = request.headers[WORKSPACE_CARD_LOCAL_DEV_MANIFEST_TOKEN_HEADER];
15721
+ const candidate = Buffer.alloc(43);
15722
+ if (typeof token === 'string')
15723
+ Buffer.from(token).copy(candidate, 0, 0, candidate.length);
15724
+ const tokenMatches = node_crypto.timingSafeEqual(candidate, Buffer.from(miniProgramManifestAccessToken));
15725
+ if (!tokenMatches || typeof token !== 'string' || !/^[A-Za-z0-9_-]{43}$/.test(token) ||
15726
+ !['127.0.0.1', '::1', '::ffff:127.0.0.1'].includes(remote ?? '') ||
15727
+ !/^127\.0\.0\.1:\d{1,5}$/.test(host)) {
15728
+ response.writeHead(403).end();
15729
+ return true;
15730
+ }
15731
+ const source = readLaunchSource();
15732
+ if (!source.miniProgramId || !source.localDevLaunchToken || !source.devSessionId || !source.expiresAt) {
15733
+ response.writeHead(503).end();
15734
+ return true;
15735
+ }
15736
+ const body = JSON.stringify({
15737
+ schema_version: 1,
15738
+ mini_program_id: source.miniProgramId,
15739
+ local_dev_launch_token: source.localDevLaunchToken,
15740
+ dev_session_id: source.devSessionId,
15741
+ expires_at_ms: source.expiresAt,
15742
+ });
15743
+ response.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Content-Length': Buffer.byteLength(body) });
15744
+ response.end(request.method === 'HEAD' ? undefined : body);
15745
+ return true;
15746
+ }
15703
15747
  if (await networkProxy.handle(request, response))
15704
15748
  return true;
15705
15749
  if (request.url !== MINI_PROGRAM_DEV_LAUNCH_PATH || request.headers[COMPANION_ARTIFACT_ACCESS_TOKEN_HEADER] === undefined)
@@ -15768,6 +15812,7 @@ async function runDevCommand(options, runtime = {}) {
15768
15812
  browserDevHost = await runDevStartupTask(logger, '正在启动浏览器调试页服务', () => startBrowserDevHostServer({
15769
15813
  openPlatformBaseUrl: session.resolveHeyboxOpenPlatformBaseUrl(runtime.env),
15770
15814
  appUrl,
15815
+ devSessionId,
15771
15816
  devContext: currentDevContext,
15772
15817
  fetchImpl,
15773
15818
  getPort: getPortImpl,
@@ -15779,6 +15824,7 @@ async function runDevCommand(options, runtime = {}) {
15779
15824
  miniProgram,
15780
15825
  // 只在项目声明了桌面平台时向调试台暴露「在桌面端打开」入口。
15781
15826
  miniProgramSupportsDesktop: runtimePermissionEnv.hasMiniappDesktopPlatform(miniProgramPlatforms),
15827
+ workspaceCardsEnabled: workspaceCardsDeclared,
15782
15828
  cliAuth: runtime.cliAuth ?? createBrowserDevHostCliAuth({ env: runtime.env, fetchImpl }),
15783
15829
  onMobileDevSessionCreated: ({ devContextUrl, miniUrlOrigin }) => {
15784
15830
  mobileDevContextUrlsByOrigin.set(miniUrlOrigin, devContextUrl);