@heybox/hb-sdk 0.8.0-alpha → 0.8.0-alpha.3

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 (64) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/README.md +87 -14
  3. package/THIRD_PARTY_NOTICES.md +1755 -0
  4. package/dist/cli-chunks/{build-DJWFSM1B.cjs → build-qWzAbpS7.cjs} +2 -2
  5. package/dist/cli-chunks/{context-DV2UK1Nz.cjs → context-CtS2Thp0.cjs} +1 -26
  6. package/dist/cli-chunks/{create-2HfoB48V.cjs → create-PV5ua977.cjs} +1 -1
  7. package/dist/cli-chunks/{dev-Dgt2zS9k.cjs → dev-CwKbAm_H.cjs} +337 -522
  8. package/dist/cli-chunks/doctor-tJUGOYrm.cjs +65 -0
  9. package/dist/cli-chunks/{index-BjoSXl8C.cjs → index-DVuD75Hr.cjs} +1 -1
  10. package/dist/cli-chunks/{index-D62ANeBv.cjs → index-De687C6-.cjs} +33 -24
  11. package/dist/cli-chunks/{index.esm-CigcxJ2B.cjs → index.esm-B-4yrLNm.cjs} +6 -5
  12. package/dist/cli-chunks/{login-Cumknwdx.cjs → login-DolpqD8K.cjs} +2 -2
  13. package/dist/cli-chunks/{project-vite-CcE-HMmd.cjs → project-vite-1rvkK-M8.cjs} +1 -1
  14. package/dist/cli-chunks/{remote-DDdP3xcE.cjs → remote-rIAQE_G2.cjs} +4 -4
  15. package/dist/cli-chunks/{session-BDi_AZSv.cjs → session-CzaM2Cq3.cjs} +1 -1
  16. package/dist/cli-chunks/skill-CM40_9WH.cjs +83 -0
  17. package/dist/cli-chunks/version-Bz-AfXQU.cjs +8 -0
  18. package/dist/cli.cjs +1 -1
  19. package/dist/devtools/browser-dev-host/assets/browser-dev-host-uq-Wac6k.js +97 -0
  20. package/dist/devtools/browser-dev-host/assets/heybox-logo-CogNENsk.svg +6 -0
  21. package/dist/devtools/browser-dev-host/assets/index-CeP6SLB3.js +567 -0
  22. package/dist/devtools/browser-dev-host/assets/index-KD2f3Jdz.css +1 -0
  23. package/dist/devtools/browser-dev-host/assets/workbench-state-D-1U0JRq.js +5 -0
  24. package/dist/devtools/browser-dev-host/index.html +6 -435
  25. package/dist/index.cjs.js +924 -28
  26. package/dist/index.esm.js +924 -29
  27. package/dist/protocol.cjs.js +208 -6
  28. package/dist/protocol.esm.js +182 -7
  29. package/dist/vite.cjs.js +1 -1
  30. package/dist/vite.esm.js +1 -1
  31. package/package.json +29 -10
  32. package/skill/SKILL.md +16 -13
  33. package/skill/references/api-protocol.md +100 -4
  34. package/skill/references/api-root.md +142 -15
  35. package/skill/references/cli.md +27 -22
  36. package/skill/references/examples.md +30 -1
  37. package/skill/references/llms-index.md +1 -1
  38. package/skill/references/recipes.md +106 -2
  39. package/skill/references/safety-boundaries.md +12 -1
  40. package/skill/skill.json +10 -5
  41. package/types/core/client.d.ts +17 -1
  42. package/types/core/sdk.d.ts +3 -0
  43. package/types/core/singleton.d.ts +3 -0
  44. package/types/index.d.ts +4 -2
  45. package/types/modules/files/index.d.ts +5 -0
  46. package/types/modules/files/registry.d.ts +35 -0
  47. package/types/modules/files/types.d.ts +159 -0
  48. package/types/modules/network/index.d.ts +50 -3
  49. package/types/protocol/capabilities.d.ts +2 -2
  50. package/types/protocol/constants.d.ts +1 -1
  51. package/types/protocol/guards.d.ts +1 -1
  52. package/types/protocol/types.d.ts +1 -1
  53. package/types/protocol.d.ts +4 -3
  54. package/types/skill-metadata.d.ts +0 -4
  55. package/dist/cli-chunks/doctor-C95gIao_.cjs +0 -204
  56. package/dist/devtools/browser-dev-host/main.js +0 -12263
  57. package/skill/scripts/check-references.mjs +0 -14
  58. package/skill/scripts/markdown-sections.mjs +0 -36
  59. package/skill/scripts/package-skill.mjs +0 -60
  60. package/skill/scripts/package-skill.sh +0 -6
  61. package/skill/scripts/skill-metadata.mjs +0 -77
  62. package/skill/scripts/sync-agent-skills-payload.mjs +0 -359
  63. package/skill/scripts/sync-references.mjs +0 -794
  64. package/skill/scripts/validate-skill.mjs +0 -263
@@ -1,794 +0,0 @@
1
- #!/usr/bin/env node
2
- import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import process from 'node:process';
6
- import ts from 'typescript';
7
- import { extractSection, replaceRequiredSection } from './markdown-sections.mjs';
8
- import { createSkillContentHash, createSkillManifest, normalizeSkillManifest } from './skill-metadata.mjs';
9
-
10
- const scriptDir = path.dirname(fileURLToPath(import.meta.url));
11
- const skillRoot = path.resolve(scriptDir, '..');
12
- const referencesRoot = path.join(skillRoot, 'references');
13
- const repoRoot = findRepoRoot(process.cwd()) ?? findRepoRoot(skillRoot);
14
- const checkMode = process.argv.includes('--check');
15
- const TEXT_FILE_RE = /\.(?:md|mjs|js|cjs|ts|tsx|json|txt|sh|yaml|yml)$/i;
16
-
17
- if (!repoRoot) {
18
- console.error(
19
- 'Cannot sync hb-sdk references outside the heybox-webapp repository. Run this script from a checkout that contains packages/hb-sdk/package.json.',
20
- );
21
- process.exit(1);
22
- }
23
-
24
- function findRepoRoot(startDir) {
25
- let dir = path.resolve(startDir);
26
- while (true) {
27
- if (existsSync(path.join(dir, 'package.json')) && existsSync(path.join(dir, 'packages/hb-sdk/package.json'))) {
28
- return dir;
29
- }
30
- const parent = path.dirname(dir);
31
- if (parent === dir) return null;
32
- dir = parent;
33
- }
34
- }
35
-
36
- function read(relativePath) {
37
- return readFileSync(path.join(repoRoot, relativePath), 'utf8').trimEnd();
38
- }
39
-
40
- function fenced(language, value) {
41
- const content = value.trimEnd();
42
- const longestFence = Math.max(2, ...Array.from(content.matchAll(/`{3,}/g), (match) => match[0].length));
43
- const fence = '`'.repeat(longestFence + 1);
44
- return `${fence}${language}\n${content}\n${fence}`;
45
- }
46
-
47
- function header(title, sources) {
48
- return [
49
- `# ${title}`,
50
- '',
51
- '> Generated by `node packages/hb-sdk/skill/scripts/sync-references.mjs` from the public hb-sdk source/docs. Do not edit by hand; update sources or this generator instead.',
52
- '',
53
- '## Sources',
54
- '',
55
- ...sources.map((source) => `- ${source}`),
56
- '',
57
- ].join('\n');
58
- }
59
-
60
- function frontmatterless(markdown) {
61
- return markdown.replace(/^---\n[\s\S]*?\n---\n/, '').trimEnd();
62
- }
63
-
64
- function rewriteBundledRecipeLinks(markdown) {
65
- return markdown
66
- .replaceAll('(../recipes/custom-instance)', '(#custom-instance-recipe)')
67
- .replaceAll('(../reference/protocol/interfaces/MiniProgramEventPayloadMap)', '(api-root.md)')
68
- .replaceAll('(../reference/protocol/types/#miniprogrameventname)', '(api-root.md)')
69
- .replaceAll('(../reference/root/classes/HbMiniProgramSDKError)', '(api-root.md)')
70
- .replaceAll('(../reference/root/classes/HbMiniProgramNetworkError)', '(api-root.md)');
71
- }
72
-
73
- function rewriteBundledCliLinks(markdown) {
74
- return markdown.replaceAll('(./mini-program-publishing-rules)', '(https://docs.xiaoheihe.cn/hb_sdk/guide/mini-program-publishing-rules)');
75
- }
76
-
77
- function rewriteBundledProtocolIndexLinks(markdown) {
78
- return markdown
79
- .replaceAll('(./root/)', '(api-root.md)')
80
- .replaceAll('(./protocol/)', '(#public-protocol-entrypoint)')
81
- .replaceAll('(./compatibility)', '(https://docs.xiaoheihe.cn/hb_sdk/reference/compatibility)')
82
- .replaceAll('](/reference/', '](https://docs.xiaoheihe.cn/hb_sdk/reference/')
83
- .replaceAll('(./miniapp-publish/)', '(https://open.xiaoheihe.cn/docs/hb_sdk/reference/miniapp-publish/)')
84
- .replaceAll('(./vite/)', '(https://open.xiaoheihe.cn/docs/hb_sdk/reference/vite/)')
85
- .replaceAll('(./runtime/)', '(https://docs.xiaoheihe.cn/hb_sdk/reference/runtime/)')
86
- .replaceAll('(../guide/)', '(recipes.md)');
87
- }
88
-
89
- const INTERNAL_PROTOCOL_DIAGNOSTIC_EXPORTS = new Set([
90
- 'RUNTIME_LOCATION_PROBE_METHOD',
91
- 'RuntimeLocationProbePayload',
92
- 'SDK_CSP_VIOLATION_METHOD',
93
- 'SDK_LOCATION_REPORT_METHOD',
94
- 'SDKCSPBlockedResourceType',
95
- 'SDKCSPViolationPayload',
96
- 'SDKLocationReportPayload',
97
- 'SDKLocationReportTrigger',
98
- ]);
99
-
100
- function omitNamedExports(source, omittedNames) {
101
- const sourceFile = ts.createSourceFile('protocol.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
102
- const lineStarts = sourceFile.getLineStarts();
103
- const removals = [];
104
-
105
- for (const statement of sourceFile.statements) {
106
- if (!ts.isExportDeclaration(statement) || !statement.exportClause || !ts.isNamedExports(statement.exportClause)) {
107
- continue;
108
- }
109
-
110
- for (const element of statement.exportClause.elements) {
111
- if (!omittedNames.has(element.name.text)) continue;
112
-
113
- const { line } = sourceFile.getLineAndCharacterOfPosition(element.getStart(sourceFile));
114
- const start = lineStarts[line];
115
- const end = lineStarts[line + 1] ?? source.length;
116
- const lineText = source.slice(start, end).trim();
117
- const elementText = element.getText(sourceFile);
118
-
119
- if (lineText !== `${elementText},` && lineText !== elementText) {
120
- throw new Error(`Internal protocol export must occupy its own line: ${element.name.text}`);
121
- }
122
- removals.push({ start, end });
123
- }
124
- }
125
-
126
- return removals
127
- .sort((left, right) => right.start - left.start)
128
- .reduce((result, { start, end }) => `${result.slice(0, start)}${result.slice(end)}`, source);
129
- }
130
-
131
- function contents(items) {
132
- return ['', '## Contents', '', ...items.map(([title, anchor]) => `- [${title}](#${anchor})`), ''].join('\n');
133
- }
134
-
135
- function toPosix(value) {
136
- return value.split(path.sep).join('/');
137
- }
138
-
139
- function walkDistributableSkillFiles(dir, relativeBase = '') {
140
- const out = [];
141
-
142
- if (!existsSync(dir)) {
143
- return out;
144
- }
145
-
146
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
147
- if (entry.name.startsWith('.')) {
148
- continue;
149
- }
150
-
151
- const fullPath = path.join(dir, entry.name);
152
- const relativePath = toPosix(path.join(relativeBase, entry.name));
153
-
154
- if (entry.isDirectory()) {
155
- out.push(...walkDistributableSkillFiles(fullPath, relativePath));
156
- continue;
157
- }
158
-
159
- if (!entry.isFile()) {
160
- continue;
161
- }
162
-
163
- if (relativePath === 'skill.json' || /\.zip$/i.test(relativePath) || !TEXT_FILE_RE.test(relativePath)) {
164
- continue;
165
- }
166
-
167
- out.push(relativePath);
168
- }
169
-
170
- return out;
171
- }
172
-
173
- function readGeneratedOrDiskSkillFile(relativePath, generatedReferences) {
174
- if (relativePath.startsWith('references/')) {
175
- const generated = generatedReferences.get(relativePath.slice('references/'.length));
176
-
177
- if (generated !== undefined) {
178
- return `${generated.trimEnd()}\n`;
179
- }
180
- }
181
-
182
- return readFileSync(path.join(skillRoot, ...relativePath.split('/')));
183
- }
184
-
185
- function createCurrentSkillManifest(generatedReferences) {
186
- const distributableFiles = [
187
- 'SKILL.md',
188
- ...walkDistributableSkillFiles(path.join(skillRoot, 'references'), 'references'),
189
- ...walkDistributableSkillFiles(path.join(skillRoot, 'scripts'), 'scripts'),
190
- ...walkDistributableSkillFiles(path.join(skillRoot, 'assets'), 'assets'),
191
- ];
192
- const fileEntries = Array.from(new Set(distributableFiles))
193
- .sort((left, right) => left.localeCompare(right))
194
- .map((relativePath) => ({
195
- path: relativePath,
196
- content: readGeneratedOrDiskSkillFile(relativePath, generatedReferences),
197
- }));
198
-
199
- return createSkillManifest({
200
- contentHash: createSkillContentHash(fileEntries),
201
- sdkVersion: packageJson.version,
202
- });
203
- }
204
-
205
- const packageJson = JSON.parse(read('packages/hb-sdk/package.json'));
206
- const rootEntry = read('packages/hb-sdk/src/index.ts');
207
- const protocolEntry = read('packages/hb-sdk/src/protocol.ts');
208
- const viteEntry = read('packages/hb-sdk/src/vite/index.ts');
209
- const cliEntry = read('packages/hb-sdk/src/cli/index.ts');
210
- const readme = read('packages/hb-sdk/README.md');
211
- const cliGuide = frontmatterless(read('apps/docs/hb-sdk/guide/cli.md'));
212
- const quickStart = frontmatterless(read('apps/docs/hb-sdk/guide/quick-start.md'));
213
- const authGuide = frontmatterless(read('apps/docs/hb-sdk/guide/auth.md'));
214
- const authGuideForSkill = replaceRequiredSection(
215
- authGuide,
216
- '## 后端 OpenAPI',
217
- [
218
- '## 后端 OpenAPI',
219
- '',
220
- '开发者服务端按[在线用户身份与登录文档](https://docs.xiaoheihe.cn/hb_sdk/guide/auth)完成授权码交换和用户读取。小程序页面只提交 `auth.login()` 返回的短期 code,不持有服务端密钥、access token 或认证 header;Agent Skill 不分发服务端凭据操作示例。',
221
- ].join('\n'),
222
- );
223
- const lifecycleGuide = frontmatterless(read('apps/docs/hb-sdk/guide/lifecycle.md'));
224
- const errorGuide = frontmatterless(read('apps/docs/hb-sdk/guide/error-handling.md'));
225
- const loginGate = frontmatterless(read('apps/docs/hb-sdk/recipes/login-gate.md'));
226
- const communityShare = frontmatterless(read('apps/docs/hb-sdk/recipes/community-share.md'));
227
- const customInstance = frontmatterless(read('apps/docs/hb-sdk/recipes/custom-instance.md'));
228
- const referenceHome = frontmatterless(read('apps/docs/hb-sdk/reference/index.md'));
229
- const publicCapabilities = extractSection(readme, '## 能力概览');
230
- const capabilityBoundaries = extractSection(readme, '## 关键约束');
231
- const leaderboardSection = extractSection(readme, '## 云端排行榜');
232
- const publicProtocolEntry = omitNamedExports(protocolEntry, INTERNAL_PROTOCOL_DIAGNOSTIC_EXPORTS);
233
- const manifestSection = extractSection(cliGuide, '## 生产构建');
234
- const cliCreateSection = extractSection(cliGuide, '## 创建工坊小程序');
235
- const cliDevSection = extractSection(cliGuide, '## 推荐调试流程');
236
- const cliBuildSection = extractSection(cliGuide, '## 生产构建');
237
- const cliDeploySection = extractSection(cliGuide, '## 部署发布');
238
- const cliRemoteSection = extractSection(cliGuide, '## 远端管理命令');
239
- const cliLoginSection = extractSection(cliGuide, '## CLI 登录态');
240
- const cliDoctorSection = extractSection(cliGuide, '## Agent Skill doctor');
241
- const cliUpdateSection = extractSection(cliGuide, '## 版本提醒');
242
- const cliCommandSurface = `hb-sdk create <project-name>
243
- hb-sdk dev [--port <port>] [--browser-dev-host-port <port>] [--no-open]
244
- hb-sdk build [--env <name>] [--verbose]
245
- hb-sdk login
246
- hb-sdk login status
247
- hb-sdk login clear
248
- hb-sdk doctor
249
- hb-sdk remote access
250
- hb-sdk remote entity list
251
- hb-sdk remote entity current
252
- hb-sdk remote entity switch <entity-id>
253
- hb-sdk remote list [--status <status>] [--keyword <text>]
254
- hb-sdk remote create [--yes] [--force-bind]
255
- hb-sdk remote bind <mini-program-id> [--force]
256
- hb-sdk remote info
257
- hb-sdk remote allowlist list
258
- hb-sdk remote allowlist add <heybox-id...>
259
- hb-sdk remote allowlist remove <heybox-id...>
260
- hb-sdk remote allowlist set <heybox-id...>
261
- hb-sdk remote deploy --release-note <text> [--from-version <version>] [--auto-publish]
262
- hb-sdk remote versions
263
- hb-sdk remote preview <version>
264
- hb-sdk remote release <version> [--yes]
265
- hb-sdk remote withdraw <version> [--yes] [--reason <text>]
266
- hb-sdk remote take-down [--yes]
267
- hb-sdk remote reopen [--yes]
268
- hb-sdk remote square hide [--yes]
269
- hb-sdk remote square show
270
-
271
- Removed: hb-sdk deploy`;
272
-
273
- const cliRemoteEntitySection = `Developer account selection lives under \`hb-sdk remote entity\`:
274
-
275
- ${fenced(
276
- 'bash',
277
- `hb-sdk remote entity list
278
- hb-sdk remote entity current
279
- hb-sdk remote entity switch <entity-id>`,
280
- )}
281
-
282
- Remote management commands use the current developer account. Use \`current\` to confirm it and \`switch\` to change it before creating, binding, or publishing a mini-program.`;
283
-
284
- const cliRemoteEntityDeploySection = `Before publishing, \`hb-sdk remote deploy\` verifies that the bound mini-program belongs to the current developer account. If it does not, the command stops and asks the user to switch accounts.`;
285
-
286
- const files = new Map();
287
-
288
- files.set(
289
- 'api-root.md',
290
- `${header('Root API reference', [
291
- 'packages/hb-sdk/package.json',
292
- 'packages/hb-sdk/src/index.ts',
293
- 'packages/hb-sdk/src/vite/index.ts',
294
- 'packages/hb-sdk/README.md',
295
- 'apps/docs/hb-sdk/guide/quick-start.md',
296
- 'apps/docs/hb-sdk/guide/error-handling.md',
297
- 'apps/docs/hb-sdk/guide/lifecycle.md',
298
- 'apps/docs/hb-sdk/guide/cli.md',
299
- ])}${contents([
300
- ['Package metadata', 'package-metadata'],
301
- ['Public root entrypoint', 'public-root-entrypoint'],
302
- ['Vite plugin export', 'vite-plugin-export'],
303
- ['App-facing concepts', 'app-facing-concepts'],
304
- ['Public modules', 'public-modules'],
305
- ['Cloud leaderboard', 'cloud-leaderboard'],
306
- ])}## Package metadata
307
-
308
- - Package: \`${packageJson.name}\`
309
- - Version at generation time: \`${packageJson.version}\`
310
- - Public root export: \`@heybox/hb-sdk\`
311
- - Protocol export: \`@heybox/hb-sdk/protocol\`
312
- - Vite plugin export: \`@heybox/hb-sdk/vite\`
313
-
314
- ## Public root entrypoint
315
-
316
- ${fenced('ts', rootEntry)}
317
-
318
- ## Vite plugin export
319
-
320
- Use \`@heybox/hb-sdk/vite\` only in \`vite.config.ts\`. Do not import it from iframe mini-program business code.
321
-
322
- ${fenced('ts', viteEntry)}
323
-
324
- ${manifestSection}
325
-
326
- ## App-facing concepts
327
-
328
- ${quickStart}
329
-
330
- ${rewriteBundledRecipeLinks(errorGuide)}
331
-
332
- ## Public modules
333
-
334
- ${publicCapabilities}
335
-
336
- ${rewriteBundledRecipeLinks(lifecycleGuide)}
337
-
338
- ${leaderboardSection}
339
- `,
340
- );
341
-
342
- files.set(
343
- 'api-protocol.md',
344
- `${header('Protocol API reference', ['packages/hb-sdk/src/protocol.ts', 'apps/docs/hb-sdk/reference/index.md'])}${contents([
345
- ['Host/runtime-only warning', 'hostruntime-only-warning'],
346
- ['Public protocol entrypoint', 'public-protocol-entrypoint'],
347
- ['Generated reference index', 'generated-reference-index'],
348
- ])}## Host/runtime-only warning
349
-
350
- New parent-container Host, \`@heybox/hb-sdk-runtime\`, bridge-server, and protocol-contract maintenance must import wire contracts directly from \`@heybox/hb-sdk-protocol\`. Use \`@heybox/hb-sdk/protocol\` only for explicitly retained existing compatibility consumers. Iframe mini-program business code must use root SDK APIs and must not construct bridge envelopes, nonce handling, or raw \`postMessage\` flows.
351
-
352
- ## Public protocol entrypoint
353
-
354
- ${fenced('ts', publicProtocolEntry)}
355
-
356
- ## Generated reference index
357
-
358
- ${rewriteBundledProtocolIndexLinks(referenceHome)}
359
- `,
360
- );
361
-
362
- files.set(
363
- 'cli.md',
364
- `${header('CLI reference', [
365
- 'packages/hb-sdk/package.json',
366
- 'packages/hb-sdk/src/cli/index.ts',
367
- 'packages/hb-sdk/src/cli/commands/create.ts',
368
- 'packages/hb-sdk/src/cli/commands/dev.ts',
369
- 'packages/hb-sdk/src/cli/commands/build.ts',
370
- 'packages/hb-sdk/src/cli/commands/login.ts',
371
- 'apps/docs/hb-sdk/guide/cli.md',
372
- ])}${contents([
373
- ['When to use the CLI', 'when-to-use-the-cli'],
374
- ['Command surface', 'command-surface'],
375
- ['Create a mini-program template', 'create-a-mini-program-template'],
376
- ['Local debugging', 'local-debugging'],
377
- ['Production build', 'production-build'],
378
- ['Deploy and publish', 'deploy-and-publish'],
379
- ['Developer account scope', 'developer-account-scope'],
380
- ['Remote management commands', 'remote-management-commands'],
381
- ['CLI login', 'cli-login'],
382
- ['Agent Skill doctor', 'agent-skill-doctor'],
383
- ['Update reminders', 'update-reminders'],
384
- ])}## When to use the CLI
385
-
386
- Use the bundled \`hb-sdk\` CLI to create a workshop mini-program, open the local debugging page, test in the Heybox Mac or mobile App, or manage and publish a remote mini-program.
387
-
388
- \`hb-sdk login\` is for development and publishing commands only. It does not authorize mini-program users and does not change \`auth.login()\`, \`user.getInfo()\`, or \`network.request()\` inside a mini-program.
389
-
390
- ## Command surface
391
-
392
- ${fenced('text', cliCommandSurface)}
393
-
394
- Top-level \`hb-sdk deploy\` has been hard-cut and must not be documented as a valid compatibility alias. Keep \`hb-sdk login\` top-level because it manages CLI login state, not a specific remote mini-program.
395
-
396
- ## Create a mini-program template
397
-
398
- ${cliCreateSection}
399
-
400
- Agent rules:
401
-
402
- - Prefer \`hb-sdk create <project-name>\` for a new workshop mini-program.
403
- - After creation, the expected next steps are \`npm install\` and \`npm run dev\`.
404
- - Do not claim the CLI installs dependencies, initializes git, opens an editor, or overwrites non-empty directories.
405
- - Treat \`project-name\` as an unscoped npm package name and project directory.
406
-
407
- ## Local debugging
408
-
409
- ${cliDevSection}
410
-
411
- Use \`hb-sdk dev\` to open the local debugging page after CLI login and project binding are complete. Missing login, binding, or remote Dev Context stops before Vite and the debugging services start. The "Mobile App" QR code opens it in the phone App after a LAN interface is selected. The phone and computer must be on the same LAN.
412
-
413
- Browser Mock uses the Node \`hb-sdk login\` session to send Host \`heybox-session\` requests. Mini-program code must still call \`auth.login()\`; the debug page only shows an authorization dialog. Never copy pkey, cookies, tokens, or credential-bearing URLs into page JavaScript or logs. Phone debugging continues to use the App login, not the CLI session.
414
-
415
- ## Production build
416
-
417
- ${cliBuildSection}
418
-
419
- Agent rules:
420
-
421
- - Use \`hb-sdk build [--env <name>] [--verbose]\` as the recommended production build entry.
422
- - Require explicit \`miniappManifest()\` configuration and keep typechecking in the project's \`scripts.build\`.
423
- - Do not claim \`hb-sdk build\` needs login, binding, or network access, and do not invent unsupported build flags.
424
- - Existing \`vite build\` projects remain compatible and must not be auto-migrated.
425
-
426
- ## Deploy and publish
427
-
428
- ${rewriteBundledCliLinks(cliDeploySection)}
429
-
430
- ${cliRemoteEntityDeploySection}
431
-
432
- Agent rules:
433
-
434
- - Use \`hb-sdk remote deploy --release-note <text>\` for normal build, upload, and submit-audit flows.
435
- - Use \`hb-sdk remote deploy --from-version <version> --release-note <text>\` to reuse a remote history artifact.
436
- - If the bound mini-program does not belong to the current developer account, stop and ask the user to switch accounts.
437
- - Never recommend top-level \`hb-sdk deploy\`; it has been removed rather than retained as a compatibility alias.
438
- - After non-auto deploy succeeds, suggest \`hb-sdk remote versions\` and then \`hb-sdk remote release <version>\` after approval. Do not send the user to Open for manual publish when the CLI command exists.
439
- - Use \`hb-sdk remote allowlist add <heybox_id>\` when preview access needs to be granted.
440
-
441
- ## Developer account scope
442
-
443
- ${cliRemoteEntitySection}
444
-
445
- Agent rules:
446
-
447
- - Treat the current developer account as the scope for remote create, bind, deploy, list, access, versions, preview, release, withdraw, take-down, reopen, and square-display workflows.
448
- - Use \`hb-sdk remote entity current\` when a user needs to confirm which entity create/deploy will use.
449
- - Use \`hb-sdk remote entity switch <entity-id>\` to change entity scope. Do not recommend \`--entity-id\` or an environment variable as a remote command override.
450
- - \`hb-sdk remote list\` lists mini-programs in the current entity scope only; do not promise cross-entity aggregation.
451
-
452
- ## Remote management commands
453
-
454
- ${cliRemoteSection}
455
-
456
- Agent rules:
457
-
458
- - Use \`hb-sdk remote entity list/current/switch\` for developer entity inspection and switching.
459
- - Use \`hb-sdk remote create\` for create-and-bind and \`hb-sdk remote bind <mini-program-id>\` for binding an existing manageable remote mini-program.
460
- - Do not require or submit mini-program name/icon/cover from CLI; maintain them on Open version publish. CLI project configuration contains only \`package.json.heybox.miniProgramId\`.
461
- - Explain that \`remote create\` creates under the current entity and that multi-entity non-TTY usage must confirm with \`--yes\`; \`--yes\` confirms current-entity usage but does not switch entities.
462
- - Explain that \`remote bind\` verifies the mini-program is manageable by the current entity and does not write \`package.json.heybox.miniProgramId\` on entity mismatch.
463
- - Use \`hb-sdk remote info\`, \`hb-sdk remote access\`, \`hb-sdk remote list\`, \`hb-sdk remote versions\`, \`hb-sdk remote preview <version>\`, \`hb-sdk remote square show/hide\`, and \`hb-sdk remote allowlist ...\` instead of sending users to Open when a matching CLI command exists.
464
- - Do not expose a CLI basic-info update command; mini-program name and image changes must go through version audit.
465
- - Treat \`hb-sdk remote list\` as discovery only. Dangerous write commands still target the bound mini-program from \`package.json.heybox.miniProgramId\`.
466
- - Require confirmation or \`--yes\` for \`hb-sdk remote release\`, \`hb-sdk remote withdraw\`, \`hb-sdk remote take-down\`, \`hb-sdk remote reopen\`, and \`hb-sdk remote square hide\`.
467
- - Use \`--json\` for script consumption and keep stdout as exactly one JSON object.
468
-
469
- ## CLI login
470
-
471
- ${cliLoginSection}
472
-
473
- Agent rules:
474
-
475
- - Keep CLI login separate from the mini-program user login state.
476
- - It is correct to say status output is redacted.
477
- - Do not expose or template pkey, cookie, token, or private credential values.
478
- - Use \`hb-sdk login clear\` only to clear the \`hb-sdk\` CLI namespace.
479
-
480
- ## Agent Skill doctor
481
-
482
- ${cliDoctorSection}
483
-
484
- Agent rules:
485
-
486
- - Use \`hb-sdk doctor\` for read-only diagnosis of local SDK, remote latest skill metadata, and local skill metadata.
487
- - Do not use \`hb-sdk doctor\` to auto-install skills; when installation or refresh is needed, tell the user to run \`npx skills add https://open.xiaoheihe.cn/agent-skills/hb-sdk\`.
488
- - If doctor reports \`SDK_MISMATCH\`, tell the user to upgrade \`${packageJson.name}@latest\` before reinstalling the skill.
489
-
490
- ## Update reminders
491
-
492
- ${cliUpdateSection}
493
-
494
- `,
495
- );
496
-
497
- files.set(
498
- 'recipes.md',
499
- `${header('Recipes', [
500
- 'apps/docs/hb-sdk/guide/quick-start.md',
501
- 'apps/docs/hb-sdk/guide/auth.md',
502
- 'apps/docs/hb-sdk/guide/lifecycle.md',
503
- 'apps/docs/hb-sdk/guide/error-handling.md',
504
- 'apps/docs/hb-sdk/recipes/login-gate.md',
505
- 'apps/docs/hb-sdk/recipes/community-share.md',
506
- 'apps/docs/hb-sdk/recipes/custom-instance.md',
507
- ])}${contents([
508
- ['Quick start', 'quick-start'],
509
- ['User and login', 'user-and-login'],
510
- ['Lifecycle events', 'lifecycle-events'],
511
- ['Error handling', 'error-handling'],
512
- ['Login gate recipe', 'login-gate-recipe'],
513
- ['Community share recipe', 'community-share-recipe'],
514
- ['Custom instance recipe', 'custom-instance-recipe'],
515
- ])}## Quick start
516
-
517
- ${rewriteBundledRecipeLinks(quickStart)}
518
-
519
- ## User and login
520
-
521
- ${rewriteBundledRecipeLinks(authGuideForSkill)}
522
-
523
- ## Lifecycle events
524
-
525
- ${rewriteBundledRecipeLinks(lifecycleGuide)}
526
-
527
- ## Error handling
528
-
529
- ${rewriteBundledRecipeLinks(errorGuide)}
530
-
531
- ## Login gate recipe
532
-
533
- ${rewriteBundledRecipeLinks(loginGate)}
534
-
535
- ## Community share recipe
536
-
537
- ${rewriteBundledRecipeLinks(communityShare)}
538
-
539
- ## Custom instance recipe
540
-
541
- ${rewriteBundledRecipeLinks(customInstance)}
542
- `,
543
- );
544
-
545
- files.set(
546
- 'safety-boundaries.md',
547
- `${header('Safety boundaries', ['packages/hb-sdk/README.md', 'apps/docs/hb-sdk/guide/auth.md'])}## Required boundaries
548
-
549
- ${capabilityBoundaries}
550
-
551
- ## Agent rules
552
-
553
- - Do not instruct mini-program code to read, extract, forward, store, or depend on token, cookie, phone number, or private credentials.
554
- - Negative safety statements that explain the SDK does not expose token/cookie/private credentials are correct and should be preserved.
555
- - Do not use raw share protocol fields, JS callbacks, activity reporting, direct post publishing, custom buttons, or upload-only flows. Public \`share.*({ post })\` options only preset an editable client post flow.
556
- - Do not use storage delete, clear, info listing, or global Heybox client storage access.
557
- - Do not pass host-only protocol fields through \`network.request\`.
558
- - Do not build raw \`postMessage\` bridge flows in iframe business code.
559
- - Do not fetch deployed \`dist/manifest.json\` from business code; it is a build artifact for the release pipeline, not a CDN runtime asset.
560
- - Do not import from internal hb-sdk implementation paths; only use documented package entrypoints.
561
- - Browser Dev Host may use the Node \`hb-sdk login\` session to send Host \`heybox-session\` requests. Never expose pkey, cookies, tokens, or credential-bearing URLs to browser JavaScript, page UI, or logs. Mini-program code must still call \`auth.login()\`.
562
- `,
563
- );
564
-
565
- files.set(
566
- 'llms-index.md',
567
- `${header('LLM documentation index', [
568
- 'apps/docs/hb-sdk/guide/**',
569
- 'apps/docs/hb-sdk/recipes/**',
570
- 'apps/docs/hb-sdk/reference/**',
571
- 'packages/hb-sdk/src/**',
572
- ])}## Offline references
573
-
574
- The bundled references are generated directly from hand-maintained docs, generated API owner sources, and SDK/CLI sources. They do not depend on the docs site's \`.vitepress/public/llms\` mirrors.
575
-
576
- - Root SDK and Vite API: \`references/api-root.md\`
577
- - Host/runtime protocol API: \`references/api-protocol.md\`
578
- - CLI and local development: \`references/cli.md\`
579
- - Common flows: \`references/recipes.md\`
580
- - Security and capability limits: \`references/safety-boundaries.md\`
581
- - Examples and evaluation: \`references/examples.md\`, \`references/smoke-evaluation.md\`
582
-
583
- ## Online supplement
584
-
585
- Online \`llms.txt\` and markdown mirrors are optional supplements, not prerequisites for offline Skill use. Their canonical public URL is not frozen: on 2026-07-10 \`https://docs.xiaoheihe.cn/hb_sdk/llms.txt\` returned 404 and the legacy URL fetch timed out. Do not claim either endpoint is available without a fresh successful response.
586
- `,
587
- );
588
-
589
- files.set(
590
- 'examples.md',
591
- `${header('Smoke examples and anti-examples', [
592
- 'packages/hb-sdk/README.md',
593
- 'apps/docs/hb-sdk/guide/**',
594
- 'apps/docs/hb-sdk/recipes/**',
595
- ])}## Positive examples
596
-
597
- ### Gesture-gated control handshake state
598
-
599
- ${fenced(
600
- 'ts',
601
- `import hbSDK, { type MiniProgramSDKHandshakeState } from '@heybox/hb-sdk';
602
-
603
- let handshakeState: MiniProgramSDKHandshakeState = hbSDK.getHandshakeState();
604
- const stopHandshakeState = hbSDK.onHandshakeStateChange((state) => {
605
- handshakeState = state;
606
- setLoginButtonDisabled(state.status !== 'ready');
607
- });
608
-
609
- export function disposePage() {
610
- stopHandshakeState();
611
- }
612
-
613
- export async function loginFromUserAction() {
614
- if (handshakeState.status !== 'ready') return;
615
- return hbSDK.auth.login();
616
- }
617
-
618
- function setLoginButtonDisabled(disabled: boolean) {
619
- document.querySelector('button')?.toggleAttribute('disabled', disabled);
620
- }`,
621
- )}
622
-
623
- ### Current user for a network-disabled mini-program
624
-
625
- ${fenced(
626
- 'ts',
627
- `import { user } from '@heybox/hb-sdk';
628
-
629
- export async function getCurrentUser() {
630
- const result = await user.getInfo();
631
- return result.userInfo?.app_user_id;
632
- }`,
633
- )}
634
-
635
- ### Developer server session for a network-enabled mini-program
636
-
637
- ${fenced(
638
- 'ts',
639
- `import { auth, network, HbMiniProgramSDKError } from '@heybox/hb-sdk';
640
-
641
- export async function createServerSessionFromUserAction() {
642
- try {
643
- const result = await auth.login({ scopes: ['profile'] });
644
- await exchangeCodeWithDeveloperServer(result.code);
645
- return { status: 'ready' as const };
646
- } catch (error) {
647
- if (error instanceof HbMiniProgramSDKError && error.code === 'AUTHORIZATION_CANCELLED') {
648
- return { status: 'cancelled' as const };
649
- }
650
- throw error;
651
- }
652
- }
653
-
654
- async function exchangeCodeWithDeveloperServer(code: string) {
655
- await network.request({
656
- url: 'https://api.example.com/session/heybox',
657
- method: 'POST',
658
- data: { code },
659
- });
660
- }`,
661
- )}
662
-
663
- ### Network request
664
-
665
- ${fenced(
666
- 'ts',
667
- `import { network, HbMiniProgramNetworkError, HbMiniProgramSDKError } from '@heybox/hb-sdk';
668
-
669
- try {
670
- const response = await network.request<{ ok: boolean }>({
671
- url: 'https://api.example.com/demo',
672
- method: 'GET',
673
- validateStatus: status => status >= 200 && status < 400,
674
- });
675
- console.log(response.data.ok);
676
-
677
- // form POST only: App Host does not support multipart/form-data
678
- await network.request({
679
- url: 'https://api.example.com/form',
680
- method: 'POST',
681
- headers: {
682
- 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
683
- },
684
- data: new URLSearchParams({ gameId: '3', roleId: '1' }).toString(),
685
- });
686
- } catch (error) {
687
- if (error instanceof HbMiniProgramNetworkError) {
688
- // Target HTTP non-2xx, or host-side network_error (message says so)
689
- console.warn(error.status, error.message, error.data);
690
- } else if (error instanceof HbMiniProgramSDKError) {
691
- // e.g. INVALID_PARAMS for unsupported multipart shape
692
- console.warn(error.code, error.message);
693
- }
694
- }`,
695
- )}
696
-
697
- ### Host/runtime protocol import
698
-
699
- ${fenced(
700
- 'ts',
701
- `import { NETWORK_REQUEST_METHOD, type NetworkRequestPayload } from '@heybox/hb-sdk-protocol';
702
-
703
- // New Host/runtime integration only. Existing released consumers may retain @heybox/hb-sdk/protocol until explicitly migrated.
704
- export function canHandleNetwork(method: string): method is typeof NETWORK_REQUEST_METHOD {
705
- return method === NETWORK_REQUEST_METHOD;
706
- }`,
707
- )}
708
-
709
- ### CLI local mock development
710
-
711
- ${fenced(
712
- 'bash',
713
- `hb-sdk create my-miniapp
714
- cd my-miniapp
715
- npm install
716
- npm run dev
717
-
718
- # In an existing project:
719
- hb-sdk dev`,
720
- )}
721
-
722
- ### CLI login cache
723
-
724
- ${fenced(
725
- 'bash',
726
- `hb-sdk login
727
- hb-sdk login status
728
- hb-sdk login clear`,
729
- )}
730
-
731
- ### Vite manifest plugin
732
-
733
- ${fenced(
734
- 'ts',
735
- `import { miniappManifest } from '@heybox/hb-sdk/vite';
736
- import { defineConfig } from 'vite';
737
-
738
- export default defineConfig({
739
- base: './',
740
- plugins: [miniappManifest({ platforms: ['android', 'ios', 'ohos'] })],
741
- });`,
742
- )}
743
-
744
- ## Negative examples
745
-
746
- - Do not import from internal hb-sdk implementation paths.
747
- - The non-replayed \`ready\` lifecycle event is only an edge notification. After a duplicate handshake it may repeat; never treat it as current state, and query or subscribe to the persistent state APIs instead.
748
- - Do not wait for handshake inside a gesture-gated click handler; keep the control disabled until the persistent state is \`ready\`.
749
- - Do not read cookies, tokens, phone numbers, or private credentials.
750
- - Do not create raw \`postMessage\` bridge envelopes in business pages.
751
- - Do not call unsupported storage delete/clear/info operations.
752
- - Do not pass raw internal share/network protocol fields from mini-program code.
753
- - Do not send \`multipart/form-data\` (or handcrafted multipart bodies) through \`network.request\`; use form-urlencoded string body or a dedicated upload capability.
754
- - Do not treat \`hb-sdk login\` as iframe SDK authentication state.
755
- - Do not create a second mock runtime package when \`hb-sdk dev\` is the supported local mock workflow.
756
- - Do not import \`@heybox/hb-sdk/vite\` from iframe business code or fetch a deployed \`manifest.json\` directly.
757
- `,
758
- );
759
-
760
- const skillManifest = normalizeSkillManifest(createCurrentSkillManifest(files));
761
-
762
- if (!existsSync(referencesRoot)) mkdirSync(referencesRoot, { recursive: true });
763
-
764
- let changed = false;
765
- for (const [fileName, content] of files.entries()) {
766
- const target = path.join(referencesRoot, fileName);
767
- const normalized = `${content.trimEnd()}\n`;
768
- const current = existsSync(target) ? readFileSync(target, 'utf8') : '';
769
- if (current !== normalized) {
770
- changed = true;
771
- if (!checkMode) writeFileSync(target, normalized);
772
- console.error(`${checkMode ? 'outdated' : 'updated'} ${path.relative(repoRoot, target)}`);
773
- }
774
- }
775
-
776
- const skillManifestPath = path.join(skillRoot, 'skill.json');
777
- const currentSkillManifest = existsSync(skillManifestPath) ? readFileSync(skillManifestPath, 'utf8') : '';
778
- if (currentSkillManifest !== skillManifest) {
779
- changed = true;
780
- if (!checkMode) writeFileSync(skillManifestPath, skillManifest);
781
- console.error(`${checkMode ? 'outdated' : 'updated'} ${path.relative(repoRoot, skillManifestPath)}`);
782
- }
783
-
784
- if (checkMode && changed) {
785
- console.error(
786
- `hb-sdk skill references are out of date. Run \`node ${path
787
- .relative(repoRoot, fileURLToPath(import.meta.url))
788
- .split(path.sep)
789
- .join('/')}\`.`,
790
- );
791
- process.exit(1);
792
- }
793
-
794
- console.log(JSON.stringify({ ok: true, changed, references: [...files.keys()], skillVersion: JSON.parse(skillManifest).skillVersion }));