@heybox/hb-sdk 0.6.6-alpha.2 → 0.6.6-alpha.4
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.
- package/README.md +44 -7
- package/dist/cli-chunks/build-C54stoRf.cjs +142 -0
- package/dist/cli-chunks/context-DvTynj3F.cjs +410 -0
- package/dist/cli-chunks/{create-CxjB3oSo.cjs → create-uQS30kS_.cjs} +1 -1
- package/dist/cli-chunks/{dev-Km0or0yY.cjs → dev-1wE8dNiL.cjs} +29 -149
- package/dist/cli-chunks/{doctor-baVOqNSh.cjs → doctor-B2aCUOQ7.cjs} +1 -1
- package/dist/cli-chunks/{index-ByDy5HXi.cjs → index-19i3Dr5H.cjs} +32 -16
- package/dist/cli-chunks/{index-DCsEAuca.cjs → index-DypVMqsr.cjs} +3 -3
- package/dist/cli-chunks/{login-fNe0eDs_.cjs → login-BIIUGwoq.cjs} +2 -2
- package/dist/cli-chunks/project-vite-Dl3OoQjL.cjs +45 -0
- package/dist/cli-chunks/remote-47MjCKhu.cjs +1522 -0
- package/dist/cli-chunks/{remote-BRIlRrCG.cjs → runtime-gate--rPXjiG6.cjs} +7 -1501
- package/dist/cli-chunks/{context-CM46YbPT.cjs → runtime-permission-env-BSs4uCNa.cjs} +75 -293
- package/dist/cli-chunks/{session-CTcelATz.cjs → session-DJEuhrgq.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/mock-host/main.js +149 -3
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/templates/vue3-vite-ts/README.md.ejs +2 -2
- package/dist/templates/vue3-vite-ts/package.json.ejs +1 -1
- package/dist/vite.cjs.js +68 -4
- package/dist/vite.esm.js +68 -4
- package/package.json +2 -2
- package/skill/SKILL.md +19 -14
- package/skill/references/api-protocol.md +3 -2
- package/skill/references/api-root.md +57 -11
- package/skill/references/cli.md +33 -1
- package/skill/references/recipes.md +53 -0
- package/skill/references/safety-boundaries.md +1 -1
- package/skill/scripts/sync-references.mjs +23 -1
- package/skill/skill.json +4 -4
- package/types/index.d.ts +1 -1
- package/types/modules/share/types.d.ts +11 -0
- package/types/protocol.d.ts +1 -1
- package/types/vite/html-policy.d.ts +5 -1
- package/types/vite/index.d.ts +10 -1
- package/types/vite/runtime-permission-env.d.ts +9 -0
package/dist/vite.cjs.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
var node_fs = require('node:fs');
|
|
4
4
|
var path = require('node:path');
|
|
5
|
+
var node_async_hooks = require('node:async_hooks');
|
|
5
6
|
|
|
6
7
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
7
8
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
8
9
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
9
10
|
? undefined
|
|
10
|
-
: '0.6.6-alpha.
|
|
11
|
+
: '0.6.6-alpha.4';
|
|
11
12
|
|
|
12
13
|
var re = {exports: {}};
|
|
13
14
|
|
|
@@ -11445,7 +11446,23 @@ const URL_ATTRIBUTES = {
|
|
|
11445
11446
|
track: ['src'],
|
|
11446
11447
|
video: ['src', 'poster'],
|
|
11447
11448
|
};
|
|
11448
|
-
|
|
11449
|
+
const PRODUCTION_CSP = [
|
|
11450
|
+
"default-src 'none'",
|
|
11451
|
+
"connect-src 'none'",
|
|
11452
|
+
"script-src 'self' 'unsafe-inline'",
|
|
11453
|
+
"style-src 'self' 'unsafe-inline'",
|
|
11454
|
+
"img-src 'self' data: blob:",
|
|
11455
|
+
"font-src 'self' data:",
|
|
11456
|
+
"media-src 'self' blob:",
|
|
11457
|
+
"manifest-src 'self'",
|
|
11458
|
+
"frame-src 'none'",
|
|
11459
|
+
"child-src 'none'",
|
|
11460
|
+
"worker-src 'none'",
|
|
11461
|
+
"object-src 'none'",
|
|
11462
|
+
"form-action 'none'",
|
|
11463
|
+
"base-uri 'none'",
|
|
11464
|
+
].join('; ');
|
|
11465
|
+
function enforceMiniappHtmlPolicy(html, options = {}) {
|
|
11449
11466
|
const document = parse(html);
|
|
11450
11467
|
const htmlElement = findElement(document, 'html');
|
|
11451
11468
|
const head = findElement(htmlElement ?? document, 'head');
|
|
@@ -11455,6 +11472,25 @@ function enforceMiniappHtmlPolicy(html) {
|
|
|
11455
11472
|
removePlatformCspMarkers(document);
|
|
11456
11473
|
walk(document, element => validateElement(element));
|
|
11457
11474
|
injectMiniappRuntimeGate(document);
|
|
11475
|
+
if (options.skipPlatformCsp) {
|
|
11476
|
+
return serialize(document);
|
|
11477
|
+
}
|
|
11478
|
+
const content = options.hmrWebSocketUrl
|
|
11479
|
+
? PRODUCTION_CSP.replace("connect-src 'none'", `connect-src ${options.hmrWebSocketUrl}`)
|
|
11480
|
+
: PRODUCTION_CSP;
|
|
11481
|
+
head.childNodes.unshift({
|
|
11482
|
+
nodeName: 'meta',
|
|
11483
|
+
tagName: 'meta',
|
|
11484
|
+
attrs: [
|
|
11485
|
+
{ name: 'http-equiv', value: 'Content-Security-Policy' },
|
|
11486
|
+
{ name: 'content', value: content },
|
|
11487
|
+
{ name: 'data-heybox-platform-csp', value: '' },
|
|
11488
|
+
],
|
|
11489
|
+
namespaceURI: 'http://www.w3.org/1999/xhtml',
|
|
11490
|
+
childNodes: [],
|
|
11491
|
+
parentNode: head,
|
|
11492
|
+
sourceCodeLocation: undefined,
|
|
11493
|
+
});
|
|
11458
11494
|
return serialize(document);
|
|
11459
11495
|
}
|
|
11460
11496
|
function validateElement(element) {
|
|
@@ -11548,11 +11584,23 @@ function walk(node, visit) {
|
|
|
11548
11584
|
walk(node.content, visit);
|
|
11549
11585
|
}
|
|
11550
11586
|
|
|
11587
|
+
const HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN_ENV = 'HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN';
|
|
11588
|
+
const HB_SDK_RUNTIME_PERMISSION_CONTEXT_ENV = 'HB_SDK_RUNTIME_PERMISSION_CONTEXT';
|
|
11589
|
+
const VERIFIED_RUNTIME_PERMISSION_CONTEXT = 'verified';
|
|
11590
|
+
new node_async_hooks.AsyncLocalStorage();
|
|
11591
|
+
Promise.resolve();
|
|
11592
|
+
function shouldSkipMiniappPlatformCspFromEnv(env = process.env) {
|
|
11593
|
+
return env[HB_SDK_RUNTIME_PERMISSION_CONTEXT_ENV] === VERIFIED_RUNTIME_PERMISSION_CONTEXT && env[HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN_ENV] === '1';
|
|
11594
|
+
}
|
|
11595
|
+
|
|
11551
11596
|
const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
|
|
11552
11597
|
const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
|
|
11553
11598
|
function miniappManifest() {
|
|
11599
|
+
const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
|
|
11554
11600
|
let root = process.cwd();
|
|
11555
11601
|
let outDir = 'dist';
|
|
11602
|
+
let command = 'build';
|
|
11603
|
+
let hmrWebSocketUrl;
|
|
11556
11604
|
/** 构建链路中更早的失败原因;closeBundle 不得再用产物校验覆盖它。 */
|
|
11557
11605
|
let priorBuildError;
|
|
11558
11606
|
return {
|
|
@@ -11569,6 +11617,8 @@ function miniappManifest() {
|
|
|
11569
11617
|
configResolved(resolved) {
|
|
11570
11618
|
root = resolved.root;
|
|
11571
11619
|
outDir = resolved.build.outDir;
|
|
11620
|
+
command = resolved.command;
|
|
11621
|
+
hmrWebSocketUrl = resolveHmrWebSocketUrl(resolved);
|
|
11572
11622
|
},
|
|
11573
11623
|
buildEnd(error) {
|
|
11574
11624
|
if (error) {
|
|
@@ -11576,7 +11626,10 @@ function miniappManifest() {
|
|
|
11576
11626
|
}
|
|
11577
11627
|
},
|
|
11578
11628
|
transformIndexHtml(html) {
|
|
11579
|
-
return enforceMiniappHtmlPolicy(html
|
|
11629
|
+
return enforceMiniappHtmlPolicy(html, {
|
|
11630
|
+
...(command === 'serve' ? { hmrWebSocketUrl } : {}),
|
|
11631
|
+
skipPlatformCsp,
|
|
11632
|
+
});
|
|
11580
11633
|
},
|
|
11581
11634
|
async closeBundle() {
|
|
11582
11635
|
// Rollup 在 buildStart/transform 失败后仍会调用 closeBundle。
|
|
@@ -11598,7 +11651,7 @@ function miniappManifest() {
|
|
|
11598
11651
|
if (!htmlFiles.includes(indexHtmlPath)) {
|
|
11599
11652
|
throw new Error('构建产物必须包含入口 dist/index.html');
|
|
11600
11653
|
}
|
|
11601
|
-
node_fs.writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(node_fs.readFileSync(indexHtmlPath, 'utf8')));
|
|
11654
|
+
node_fs.writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(node_fs.readFileSync(indexHtmlPath, 'utf8'), { skipPlatformCsp }));
|
|
11602
11655
|
const manifestPath = path.join(outputRoot, 'manifest.json');
|
|
11603
11656
|
node_fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
11604
11657
|
node_fs.writeFileSync(manifestPath, renderMiniappManifest({ version, sdkVersion }));
|
|
@@ -11635,5 +11688,16 @@ function resolveSdkVersion() {
|
|
|
11635
11688
|
}
|
|
11636
11689
|
return packageJson.version;
|
|
11637
11690
|
}
|
|
11691
|
+
function resolveHmrWebSocketUrl(resolved) {
|
|
11692
|
+
const hmr = resolved.server.hmr;
|
|
11693
|
+
if (hmr === false)
|
|
11694
|
+
return undefined;
|
|
11695
|
+
const options = typeof hmr === 'object' ? hmr : {};
|
|
11696
|
+
const protocol = options.protocol ?? 'ws';
|
|
11697
|
+
const configuredHost = options.host ?? resolved.server.host;
|
|
11698
|
+
const host = typeof configuredHost === 'string' && configuredHost !== '0.0.0.0' ? configuredHost : '127.0.0.1';
|
|
11699
|
+
const port = options.clientPort ?? options.port ?? resolved.server.port;
|
|
11700
|
+
return `${protocol}://${host}${port ? `:${port}` : ''}`;
|
|
11701
|
+
}
|
|
11638
11702
|
|
|
11639
11703
|
exports.miniappManifest = miniappManifest;
|
package/dist/vite.esm.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { readFileSync, existsSync, writeFileSync, mkdirSync, readdirSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
4
|
|
|
4
5
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
5
6
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
6
7
|
? undefined
|
|
7
|
-
: '0.6.6-alpha.
|
|
8
|
+
: '0.6.6-alpha.4';
|
|
8
9
|
|
|
9
10
|
var re = {exports: {}};
|
|
10
11
|
|
|
@@ -11442,7 +11443,23 @@ const URL_ATTRIBUTES = {
|
|
|
11442
11443
|
track: ['src'],
|
|
11443
11444
|
video: ['src', 'poster'],
|
|
11444
11445
|
};
|
|
11445
|
-
|
|
11446
|
+
const PRODUCTION_CSP = [
|
|
11447
|
+
"default-src 'none'",
|
|
11448
|
+
"connect-src 'none'",
|
|
11449
|
+
"script-src 'self' 'unsafe-inline'",
|
|
11450
|
+
"style-src 'self' 'unsafe-inline'",
|
|
11451
|
+
"img-src 'self' data: blob:",
|
|
11452
|
+
"font-src 'self' data:",
|
|
11453
|
+
"media-src 'self' blob:",
|
|
11454
|
+
"manifest-src 'self'",
|
|
11455
|
+
"frame-src 'none'",
|
|
11456
|
+
"child-src 'none'",
|
|
11457
|
+
"worker-src 'none'",
|
|
11458
|
+
"object-src 'none'",
|
|
11459
|
+
"form-action 'none'",
|
|
11460
|
+
"base-uri 'none'",
|
|
11461
|
+
].join('; ');
|
|
11462
|
+
function enforceMiniappHtmlPolicy(html, options = {}) {
|
|
11446
11463
|
const document = parse(html);
|
|
11447
11464
|
const htmlElement = findElement(document, 'html');
|
|
11448
11465
|
const head = findElement(htmlElement ?? document, 'head');
|
|
@@ -11452,6 +11469,25 @@ function enforceMiniappHtmlPolicy(html) {
|
|
|
11452
11469
|
removePlatformCspMarkers(document);
|
|
11453
11470
|
walk(document, element => validateElement(element));
|
|
11454
11471
|
injectMiniappRuntimeGate(document);
|
|
11472
|
+
if (options.skipPlatformCsp) {
|
|
11473
|
+
return serialize(document);
|
|
11474
|
+
}
|
|
11475
|
+
const content = options.hmrWebSocketUrl
|
|
11476
|
+
? PRODUCTION_CSP.replace("connect-src 'none'", `connect-src ${options.hmrWebSocketUrl}`)
|
|
11477
|
+
: PRODUCTION_CSP;
|
|
11478
|
+
head.childNodes.unshift({
|
|
11479
|
+
nodeName: 'meta',
|
|
11480
|
+
tagName: 'meta',
|
|
11481
|
+
attrs: [
|
|
11482
|
+
{ name: 'http-equiv', value: 'Content-Security-Policy' },
|
|
11483
|
+
{ name: 'content', value: content },
|
|
11484
|
+
{ name: 'data-heybox-platform-csp', value: '' },
|
|
11485
|
+
],
|
|
11486
|
+
namespaceURI: 'http://www.w3.org/1999/xhtml',
|
|
11487
|
+
childNodes: [],
|
|
11488
|
+
parentNode: head,
|
|
11489
|
+
sourceCodeLocation: undefined,
|
|
11490
|
+
});
|
|
11455
11491
|
return serialize(document);
|
|
11456
11492
|
}
|
|
11457
11493
|
function validateElement(element) {
|
|
@@ -11545,11 +11581,23 @@ function walk(node, visit) {
|
|
|
11545
11581
|
walk(node.content, visit);
|
|
11546
11582
|
}
|
|
11547
11583
|
|
|
11584
|
+
const HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN_ENV = 'HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN';
|
|
11585
|
+
const HB_SDK_RUNTIME_PERMISSION_CONTEXT_ENV = 'HB_SDK_RUNTIME_PERMISSION_CONTEXT';
|
|
11586
|
+
const VERIFIED_RUNTIME_PERMISSION_CONTEXT = 'verified';
|
|
11587
|
+
new AsyncLocalStorage();
|
|
11588
|
+
Promise.resolve();
|
|
11589
|
+
function shouldSkipMiniappPlatformCspFromEnv(env = process.env) {
|
|
11590
|
+
return env[HB_SDK_RUNTIME_PERMISSION_CONTEXT_ENV] === VERIFIED_RUNTIME_PERMISSION_CONTEXT && env[HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN_ENV] === '1';
|
|
11591
|
+
}
|
|
11592
|
+
|
|
11548
11593
|
const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
|
|
11549
11594
|
const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
|
|
11550
11595
|
function miniappManifest() {
|
|
11596
|
+
const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
|
|
11551
11597
|
let root = process.cwd();
|
|
11552
11598
|
let outDir = 'dist';
|
|
11599
|
+
let command = 'build';
|
|
11600
|
+
let hmrWebSocketUrl;
|
|
11553
11601
|
/** 构建链路中更早的失败原因;closeBundle 不得再用产物校验覆盖它。 */
|
|
11554
11602
|
let priorBuildError;
|
|
11555
11603
|
return {
|
|
@@ -11566,6 +11614,8 @@ function miniappManifest() {
|
|
|
11566
11614
|
configResolved(resolved) {
|
|
11567
11615
|
root = resolved.root;
|
|
11568
11616
|
outDir = resolved.build.outDir;
|
|
11617
|
+
command = resolved.command;
|
|
11618
|
+
hmrWebSocketUrl = resolveHmrWebSocketUrl(resolved);
|
|
11569
11619
|
},
|
|
11570
11620
|
buildEnd(error) {
|
|
11571
11621
|
if (error) {
|
|
@@ -11573,7 +11623,10 @@ function miniappManifest() {
|
|
|
11573
11623
|
}
|
|
11574
11624
|
},
|
|
11575
11625
|
transformIndexHtml(html) {
|
|
11576
|
-
return enforceMiniappHtmlPolicy(html
|
|
11626
|
+
return enforceMiniappHtmlPolicy(html, {
|
|
11627
|
+
...(command === 'serve' ? { hmrWebSocketUrl } : {}),
|
|
11628
|
+
skipPlatformCsp,
|
|
11629
|
+
});
|
|
11577
11630
|
},
|
|
11578
11631
|
async closeBundle() {
|
|
11579
11632
|
// Rollup 在 buildStart/transform 失败后仍会调用 closeBundle。
|
|
@@ -11595,7 +11648,7 @@ function miniappManifest() {
|
|
|
11595
11648
|
if (!htmlFiles.includes(indexHtmlPath)) {
|
|
11596
11649
|
throw new Error('构建产物必须包含入口 dist/index.html');
|
|
11597
11650
|
}
|
|
11598
|
-
writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(readFileSync(indexHtmlPath, 'utf8')));
|
|
11651
|
+
writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(readFileSync(indexHtmlPath, 'utf8'), { skipPlatformCsp }));
|
|
11599
11652
|
const manifestPath = path.join(outputRoot, 'manifest.json');
|
|
11600
11653
|
mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
11601
11654
|
writeFileSync(manifestPath, renderMiniappManifest({ version, sdkVersion }));
|
|
@@ -11632,5 +11685,16 @@ function resolveSdkVersion() {
|
|
|
11632
11685
|
}
|
|
11633
11686
|
return packageJson.version;
|
|
11634
11687
|
}
|
|
11688
|
+
function resolveHmrWebSocketUrl(resolved) {
|
|
11689
|
+
const hmr = resolved.server.hmr;
|
|
11690
|
+
if (hmr === false)
|
|
11691
|
+
return undefined;
|
|
11692
|
+
const options = typeof hmr === 'object' ? hmr : {};
|
|
11693
|
+
const protocol = options.protocol ?? 'ws';
|
|
11694
|
+
const configuredHost = options.host ?? resolved.server.host;
|
|
11695
|
+
const host = typeof configuredHost === 'string' && configuredHost !== '0.0.0.0' ? configuredHost : '127.0.0.1';
|
|
11696
|
+
const port = options.clientPort ?? options.port ?? resolved.server.port;
|
|
11697
|
+
return `${protocol}://${host}${port ? `:${port}` : ''}`;
|
|
11698
|
+
}
|
|
11635
11699
|
|
|
11636
11700
|
export { miniappManifest };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heybox/hb-sdk",
|
|
3
|
-
"version": "0.6.6-alpha.
|
|
3
|
+
"version": "0.6.6-alpha.4",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"./src/index.ts",
|
|
6
6
|
"./src/core/singleton.ts",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"vue": "^2.7.16",
|
|
94
94
|
"vite": "^8.0.12",
|
|
95
95
|
"vitest": "^3.2.4",
|
|
96
|
-
"@heybox/hb-api": "~1.25.
|
|
96
|
+
"@heybox/hb-api": "~1.25.6"
|
|
97
97
|
},
|
|
98
98
|
"publishConfig": {
|
|
99
99
|
"registry": "https://registry.npmjs.org/",
|
package/skill/SKILL.md
CHANGED
|
@@ -11,7 +11,7 @@ Apply these instructions when writing, reviewing, or debugging code that consume
|
|
|
11
11
|
|
|
12
12
|
1. If the task is workshop mini-program business code, use the root package import path `@heybox/hb-sdk`.
|
|
13
13
|
2. If the task is parent-container runtime, bridge-server, protocol contract, or `@heybox/hb-sdk-runtime` work, use `@heybox/hb-sdk/protocol` only for shared constants and types.
|
|
14
|
-
3. If the task is project scaffolding, local startup, browser Mock, device debugging, CLI login, Agent Skill diagnosis, or CLI troubleshooting, use the `hb-sdk` CLI workflow.
|
|
14
|
+
3. If the task is project scaffolding, local startup, production build, browser Mock, device debugging, CLI login, Agent Skill diagnosis, or CLI troubleshooting, use the `hb-sdk` CLI workflow.
|
|
15
15
|
4. If the task is reviewing a mini-program for submission, listing, audit, publishing, content compliance, data/privacy compliance, runtime quality, or icon/cover design requirements, use the online publishing rules workflow.
|
|
16
16
|
5. If the task asks for direct login-state extraction, cookies, tokens, raw Heybox client protocols, or internal hb-sdk package paths, refuse that approach and use the public SDK or CLI boundary instead.
|
|
17
17
|
6. If the task is not about Heybox workshop mini-program SDK usage, CLI usage, protocol contracts, or listing/audit/compliance review, do not apply this skill.
|
|
@@ -21,7 +21,7 @@ Apply these instructions when writing, reviewing, or debugging code that consume
|
|
|
21
21
|
1. For root SDK imports, singleton usage, modules, and errors, read `references/api-root.md`.
|
|
22
22
|
2. For host/runtime protocol contracts only, read `references/api-protocol.md`. Do not use this reference for mini-program business code.
|
|
23
23
|
3. For common business flows, read `references/recipes.md`.
|
|
24
|
-
4. For CLI commands, local debugging, device debugging, CLI login, Agent Skill doctor, and update reminders, read `references/cli.md`.
|
|
24
|
+
4. For CLI commands, production builds, local debugging, device debugging, CLI login, Agent Skill doctor, and update reminders, read `references/cli.md`.
|
|
25
25
|
5. For allowed/forbidden capabilities and security boundaries, read `references/safety-boundaries.md`.
|
|
26
26
|
6. For Vite build manifest behavior, read `references/api-root.md` and `references/safety-boundaries.md`.
|
|
27
27
|
7. For generated documentation provenance and deeper API lookup paths, read `references/llms-index.md`.
|
|
@@ -45,30 +45,35 @@ Apply these instructions when writing, reviewing, or debugging code that consume
|
|
|
45
45
|
5. Handle `HbMiniProgramNetworkError` separately when HTTP completed but `validateStatus` rejected the status.
|
|
46
46
|
6. Cancel lifecycle/event subscriptions returned by `on()` when the page or component unmounts.
|
|
47
47
|
7. Use the default SDK instance exposed by the root package.
|
|
48
|
+
8. Use `share.showShareMenu({ post })` or `share.screenshot({ post })` to preset editable community destinations and topics. Pass partition IDs through `topicIds` and topic text without surrounding `#` through `topics`; do not construct the underlying client post protocol.
|
|
48
49
|
|
|
49
50
|
## Step 5: Use CLI workflows
|
|
50
51
|
|
|
51
52
|
1. Use `hb-sdk create <project-name>` to scaffold a workshop mini-program.
|
|
52
53
|
2. Use `hb-sdk dev` for browser, Mac App, or mobile App debugging. These entries remain available without CLI login or project binding, but managed capabilities are denied by default.
|
|
53
54
|
3. Use `--port`, `--mock-port`, and `--no-open` when the default local ports or browser opening behavior need to be controlled.
|
|
54
|
-
4. Use `hb-sdk
|
|
55
|
-
5.
|
|
56
|
-
6.
|
|
57
|
-
7.
|
|
58
|
-
8. Use `hb-sdk
|
|
59
|
-
9.
|
|
60
|
-
10.
|
|
61
|
-
11. Use `hb-sdk remote
|
|
62
|
-
12. Use
|
|
63
|
-
13.
|
|
64
|
-
14.
|
|
55
|
+
4. Use `hb-sdk build [--env <name>] [--verbose]` as the recommended production build entry. It directly owns the Vite build, always cleans and writes `dist/`, and works without CLI login, project binding, or network access.
|
|
56
|
+
5. Keep `miniappManifest()` explicitly enabled in `vite.config.ts`; `hb-sdk build` must fail when the required Manifest or Runtime gate output is missing.
|
|
57
|
+
6. Keep project typechecking in `scripts.build`, for example `vue-tsc --noEmit && hb-sdk build`; `hb-sdk build` does not run typechecking or invoke `scripts.build` itself.
|
|
58
|
+
7. Existing projects may continue to use `vite build`; do not auto-migrate them. Do not invent `--mode`, `--json`, config, or output-directory flags for `hb-sdk build`.
|
|
59
|
+
8. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for development and publishing commands. This login does not change the mini-program user's login state.
|
|
60
|
+
9. Use `hb-sdk remote entity current` to confirm the current developer account and `hb-sdk remote entity switch <entity-id>` to change it before remote operations.
|
|
61
|
+
10. Use `hb-sdk remote create` to create and bind a mini-program; use `hb-sdk remote bind <mini-program-id>` to bind an existing manageable mini-program.
|
|
62
|
+
11. Use `hb-sdk remote info`, `hb-sdk remote list`, `hb-sdk remote access`, `hb-sdk remote versions`, `hb-sdk remote preview <version>`, and `hb-sdk remote allowlist ...` for remote inspection and preview management.
|
|
63
|
+
12. Use `hb-sdk remote deploy --release-note <text>` to run the project's `scripts.build`, upload, and submit the current project for audit. Do not recommend the removed top-level `hb-sdk deploy` alias.
|
|
64
|
+
13. After approval, use `hb-sdk remote release <version>` for manual release or `--auto-publish` when an eligible low-risk version should release automatically.
|
|
65
|
+
14. Treat approval, release, and public display as separate states. Do not promise square, search, or recommendation visibility after release.
|
|
66
|
+
15. Use `hb-sdk remote withdraw`, `hb-sdk remote take-down`, `hb-sdk remote reopen`, and square visibility commands only after showing the target and obtaining required confirmation.
|
|
67
|
+
16. Use `--json` for remote script consumption and `--verbose` only when concise output is insufficient for diagnosis.
|
|
68
|
+
17. Use `hb-sdk doctor` to diagnose whether the local Skill matches the installed SDK; follow its output to install or refresh the Skill.
|
|
69
|
+
18. Do not print or expose cookies, tokens, private headers, or other credentials.
|
|
65
70
|
|
|
66
71
|
## Step 6: Preserve capability boundaries
|
|
67
72
|
|
|
68
73
|
For workshop mini-program business code:
|
|
69
74
|
|
|
70
75
|
1. Do not read or request tokens, cookies, phone numbers, or private credentials from the SDK.
|
|
71
|
-
2. Do not expose raw share protocol fields, JS callbacks, activity reporting, custom buttons, post publishing, or upload-only flows.
|
|
76
|
+
2. Do not expose raw share protocol fields, JS callbacks, activity reporting, custom buttons, direct post publishing, or upload-only flows. Public `share.*({ post })` options only preset an editable client post flow and never publish automatically.
|
|
72
77
|
3. Do not use unsupported storage operations such as delete, clear, info listing, or global client storage access.
|
|
73
78
|
4. Use only the public `network.request` configuration.
|
|
74
79
|
5. Do not use private package paths or client protocols.
|
|
@@ -144,6 +144,7 @@ export type {
|
|
|
144
144
|
MiniProgramScreenshotOptions,
|
|
145
145
|
MiniProgramScreenshotRect,
|
|
146
146
|
MiniProgramShareChannel,
|
|
147
|
+
MiniProgramSharePostOptions,
|
|
147
148
|
MiniProgramShowShareMenuOptions,
|
|
148
149
|
} from './modules/share';
|
|
149
150
|
export type { GetStoragePayload, GetStorageResult, SetStoragePayload } from './modules/storage';
|
|
@@ -222,7 +223,7 @@ Reference 由 `@heybox/hb-sdk` 的公开导出与源码注释自动生成,不
|
|
|
222
223
|
|
|
223
224
|
| 导出面 | Classes | Functions | Interfaces | Types | Constants |
|
|
224
225
|
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
225
|
-
| Root API | 2 | 3 |
|
|
226
|
-
| Protocol API | 0 | 3 |
|
|
226
|
+
| Root API | 2 | 3 | 67 | 57 | 0 |
|
|
227
|
+
| Protocol API | 0 | 3 | 44 | 67 | 32 |
|
|
227
228
|
| Miniapp Publish API | 0 | 5 | 2 | 0 | 0 |
|
|
228
229
|
| Vite API | 0 | 1 | 0 | 0 | 0 |
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
## Package metadata
|
|
20
20
|
|
|
21
21
|
- Package: `@heybox/hb-sdk`
|
|
22
|
-
- Version at generation time: `0.6.6-alpha.
|
|
22
|
+
- Version at generation time: `0.6.6-alpha.4`
|
|
23
23
|
- Public root export: `@heybox/hb-sdk`
|
|
24
24
|
- Protocol export: `@heybox/hb-sdk/protocol`
|
|
25
25
|
- Vite plugin export: `@heybox/hb-sdk/vite`
|
|
@@ -99,6 +99,7 @@ export type {
|
|
|
99
99
|
MiniProgramScreenshotRect,
|
|
100
100
|
MiniProgramShareChannel,
|
|
101
101
|
MiniProgramShareModule,
|
|
102
|
+
MiniProgramSharePostOptions,
|
|
102
103
|
MiniProgramShowShareMenuOptions,
|
|
103
104
|
ScreenshotPayload,
|
|
104
105
|
ScreenshotResult,
|
|
@@ -203,6 +204,7 @@ import { HB_SDK_VERSION } from '../core/version';
|
|
|
203
204
|
import { renderMiniappManifest, validateMiniappPackageVersionForBuild } from '../miniapp-manifest/schema';
|
|
204
205
|
import { readMiniappVersionFromPackageJson } from '../miniapp-manifest/node';
|
|
205
206
|
import { enforceMiniappHtmlPolicy } from './html-policy';
|
|
207
|
+
import { shouldSkipMiniappPlatformCspFromEnv } from './runtime-permission-env';
|
|
206
208
|
|
|
207
209
|
type MiniappManifestPlugin = {
|
|
208
210
|
name: string;
|
|
@@ -229,15 +231,29 @@ interface MiniappManifestResolvedConfig {
|
|
|
229
231
|
build: {
|
|
230
232
|
outDir: string;
|
|
231
233
|
};
|
|
232
|
-
server:
|
|
234
|
+
server: {
|
|
235
|
+
host?: string | boolean;
|
|
236
|
+
port?: number;
|
|
237
|
+
hmr?:
|
|
238
|
+
| boolean
|
|
239
|
+
| {
|
|
240
|
+
clientPort?: number;
|
|
241
|
+
host?: string;
|
|
242
|
+
port?: number;
|
|
243
|
+
protocol?: 'ws' | 'wss';
|
|
244
|
+
};
|
|
245
|
+
};
|
|
233
246
|
}
|
|
234
247
|
|
|
235
248
|
const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
|
|
236
249
|
const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
|
|
237
250
|
|
|
238
251
|
export function miniappManifest(): MiniappManifestPlugin {
|
|
252
|
+
const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
|
|
239
253
|
let root = process.cwd();
|
|
240
254
|
let outDir = 'dist';
|
|
255
|
+
let command: 'build' | 'serve' = 'build';
|
|
256
|
+
let hmrWebSocketUrl: string | undefined;
|
|
241
257
|
/** 构建链路中更早的失败原因;closeBundle 不得再用产物校验覆盖它。 */
|
|
242
258
|
let priorBuildError: Error | undefined;
|
|
243
259
|
|
|
@@ -255,6 +271,8 @@ export function miniappManifest(): MiniappManifestPlugin {
|
|
|
255
271
|
configResolved(resolved) {
|
|
256
272
|
root = resolved.root;
|
|
257
273
|
outDir = resolved.build.outDir;
|
|
274
|
+
command = resolved.command;
|
|
275
|
+
hmrWebSocketUrl = resolveHmrWebSocketUrl(resolved);
|
|
258
276
|
},
|
|
259
277
|
buildEnd(error) {
|
|
260
278
|
if (error) {
|
|
@@ -262,7 +280,10 @@ export function miniappManifest(): MiniappManifestPlugin {
|
|
|
262
280
|
}
|
|
263
281
|
},
|
|
264
282
|
transformIndexHtml(html) {
|
|
265
|
-
return enforceMiniappHtmlPolicy(html
|
|
283
|
+
return enforceMiniappHtmlPolicy(html, {
|
|
284
|
+
...(command === 'serve' ? { hmrWebSocketUrl } : {}),
|
|
285
|
+
skipPlatformCsp,
|
|
286
|
+
});
|
|
266
287
|
},
|
|
267
288
|
async closeBundle() {
|
|
268
289
|
// Rollup 在 buildStart/transform 失败后仍会调用 closeBundle。
|
|
@@ -287,7 +308,7 @@ export function miniappManifest(): MiniappManifestPlugin {
|
|
|
287
308
|
if (!htmlFiles.includes(indexHtmlPath)) {
|
|
288
309
|
throw new Error('构建产物必须包含入口 dist/index.html');
|
|
289
310
|
}
|
|
290
|
-
writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(readFileSync(indexHtmlPath, 'utf8')));
|
|
311
|
+
writeFileSync(indexHtmlPath, enforceMiniappHtmlPolicy(readFileSync(indexHtmlPath, 'utf8'), { skipPlatformCsp }));
|
|
291
312
|
|
|
292
313
|
const manifestPath = path.join(outputRoot, 'manifest.json');
|
|
293
314
|
mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
@@ -325,11 +346,22 @@ function resolveSdkVersion() {
|
|
|
325
346
|
}
|
|
326
347
|
return packageJson.version;
|
|
327
348
|
}
|
|
349
|
+
|
|
350
|
+
function resolveHmrWebSocketUrl(resolved: MiniappManifestResolvedConfig) {
|
|
351
|
+
const hmr = resolved.server.hmr;
|
|
352
|
+
if (hmr === false) return undefined;
|
|
353
|
+
const options = typeof hmr === 'object' ? hmr : {};
|
|
354
|
+
const protocol = options.protocol ?? 'ws';
|
|
355
|
+
const configuredHost = options.host ?? resolved.server.host;
|
|
356
|
+
const host = typeof configuredHost === 'string' && configuredHost !== '0.0.0.0' ? configuredHost : '127.0.0.1';
|
|
357
|
+
const port = options.clientPort ?? options.port ?? resolved.server.port;
|
|
358
|
+
return `${protocol}://${host}${port ? `:${port}` : ''}`;
|
|
359
|
+
}
|
|
328
360
|
```
|
|
329
361
|
|
|
330
362
|
## Manifest
|
|
331
363
|
|
|
332
|
-
`@heybox/hb-sdk/vite` 提供构建时插件 `miniappManifest()
|
|
364
|
+
`@heybox/hb-sdk/vite` 提供构建时插件 `miniappManifest()`。项目通过 `hb-sdk build` 完成生产构建后,会在固定的 `dist/` 中写入 `manifest.json`:
|
|
333
365
|
|
|
334
366
|
```json
|
|
335
367
|
{
|
|
@@ -338,7 +370,7 @@ function resolveSdkVersion() {
|
|
|
338
370
|
}
|
|
339
371
|
```
|
|
340
372
|
|
|
341
|
-
`version` 来自小程序项目自身的 `package.json.version`,`sdkVersion` 来自当前安装 SDK 的构建版本且不能由业务覆盖。`hb-sdk create`
|
|
373
|
+
`version` 来自小程序项目自身的 `package.json.version`,`sdkVersion` 来自当前安装 SDK 的构建版本且不能由业务覆盖。`hb-sdk build` 要求项目显式注册这个插件;`hb-sdk create` 生成的模板默认已注册,现有 Vite 项目可以在 `vite.config.ts` 中手动接入:
|
|
342
374
|
|
|
343
375
|
```ts
|
|
344
376
|
import { miniappManifest } from '@heybox/hb-sdk/vite';
|
|
@@ -354,15 +386,17 @@ export default defineConfig({
|
|
|
354
386
|
|
|
355
387
|
工坊小程序构建产物只能在兼容的小黑盒 Runtime 中启动。普通浏览器直接打开时不会执行标准业务脚本,并会提示在小黑盒 APP 内打开。项目应使用标准 Vite module 入口。
|
|
356
388
|
|
|
357
|
-
插件只接受单页应用:输出目录只能存在入口 `index.html
|
|
389
|
+
插件只接受单页应用:输出目录只能存在入口 `index.html`。`hb-sdk dev` 和 `hb-sdk remote deploy` 会读取绑定小程序的远端 Runtime 权限;仅当 `network.request` 已启用且 `useOfficialDomain=true` 时跳过平台 CSP,否则 build 会把平台 CSP 插入 `<head>` 首位。直接运行 `vite build`、匿名 dev、非法快照或远端权限读取失败时均继续注入。已有 CSP 始终原样保留;注入平台 CSP 时,两份策略按浏览器交集生效。
|
|
390
|
+
|
|
391
|
+
平台 CSP 会禁止 `fetch`、XHR、WebSocket、EventSource、Beacon、Worker、iframe、表单和对象加载等浏览器原生出口;dev 只额外放行当前 Vite 的精确 HMR WebSocket 地址。跳过平台 CSP 时,这些能力不再由 SDK 构建产物统一限制,但需要宿主授权的业务网络请求仍应使用 `network.request()`。本地 Mock 权限覆盖不会改变构建 CSP,构建判定始终以远端权限快照为准。
|
|
358
392
|
|
|
359
|
-
meta refresh、外部 anchor、`dns-prefetch`、`preconnect`、`prerender`、外部资源 URL 和额外 HTML
|
|
393
|
+
meta refresh、外部 anchor、`dns-prefetch`、`preconnect`、`prerender`、外部资源 URL 和额外 HTML 会使 build 失败。内联 script/style 允许,但 `unsafe-eval` 不允许。`dev`、`hb-sdk build` 和手动 Vite build 都不请求远端最低 SDK 版本;构建仍会把当前 `sdkVersion` 写入 Manifest,`hb-sdk remote deploy` 仍校验 Manifest 结构并经过服务端 precheck / submit-audit 策略。
|
|
360
394
|
|
|
361
395
|
失败与警告语义:
|
|
362
396
|
|
|
363
|
-
- 读取 `package.json` 失败或 JSON
|
|
364
|
-
- `package.json.version`
|
|
365
|
-
- `package.json.version` 仍是模板默认值 `0.0.0
|
|
397
|
+
- 读取 `package.json` 失败或 JSON 解析失败:build 直接失败,并输出具体原因。
|
|
398
|
+
- `package.json.version` 不是非空字符串:build 直接失败。
|
|
399
|
+
- `package.json.version` 仍是模板默认值 `0.0.0`:build 直接失败,必须改成实际 SemVer。
|
|
366
400
|
- 版本号不是严格 SemVer、包含 build metadata 或缺少 `sdkVersion`:build/deploy 直接失败。
|
|
367
401
|
|
|
368
402
|
`manifest.json` 不部署到 CDN,只交给发布流水线读取后上送后台;Host 通过后台 API 间接读取版本信息。第一阶段只支持 Vite 项目,非 Vite 打包器未来通过其他子入口扩展。
|
|
@@ -519,6 +553,10 @@ await share.showShareMenu({
|
|
|
519
553
|
title: '我的小程序页面',
|
|
520
554
|
desc: '来自黑盒小程序的分享',
|
|
521
555
|
imageUrl: 'https://imgheybox.max-c.com/demo.png',
|
|
556
|
+
post: {
|
|
557
|
+
topicIds: [235709],
|
|
558
|
+
topics: ['无畏契约战绩'],
|
|
559
|
+
},
|
|
522
560
|
});
|
|
523
561
|
```
|
|
524
562
|
|
|
@@ -526,15 +564,23 @@ await share.showShareMenu({
|
|
|
526
564
|
`/tools/common_share?user_miniprogram_id=...` 分享落地页。只有确实要分享外部
|
|
527
565
|
HTTP(S) 页面时才显式传 `url`。
|
|
528
566
|
|
|
567
|
+
`post` 用于给“转发到社区”预置可编辑的分区与话题。`topicIds` 接受正整数或非空字符串并按首次出现顺序去重;`topics` 只传话题内容,不要包含首尾 `#`。`showShareMenu()` 只支持一个默认分区,并且不能与 `channel` 同时使用;本地 Mock、App Dev Shell 和开发 Runtime 会直接拒绝这类错误,生产 Runtime 会过滤非法项、只取第一个分区并继续普通分享。`post: null` 等同于不配置。
|
|
568
|
+
|
|
529
569
|
截图分享:
|
|
530
570
|
|
|
531
571
|
```ts
|
|
532
572
|
await share.screenshot({
|
|
533
573
|
delay: 100,
|
|
534
574
|
saveToAlbum: true,
|
|
575
|
+
post: {
|
|
576
|
+
topicIds: [235709, 66739],
|
|
577
|
+
topics: ['无畏契约战绩'],
|
|
578
|
+
},
|
|
535
579
|
});
|
|
536
580
|
```
|
|
537
581
|
|
|
582
|
+
截图分享支持多个预置分区;分区与话题仍由用户在客户端发帖页中确认和修改,SDK 不会直接发布内容。
|
|
583
|
+
|
|
538
584
|
### 基础 UI
|
|
539
585
|
|
|
540
586
|
```ts
|
package/skill/references/cli.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
- packages/hb-sdk/src/cli/index.ts
|
|
9
9
|
- packages/hb-sdk/src/cli/commands/create.ts
|
|
10
10
|
- packages/hb-sdk/src/cli/commands/dev.ts
|
|
11
|
+
- packages/hb-sdk/src/cli/commands/build.ts
|
|
11
12
|
- packages/hb-sdk/src/cli/commands/login.ts
|
|
12
13
|
- apps/docs/hb-sdk/guide/cli.md
|
|
13
14
|
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
- [Command surface](#command-surface)
|
|
18
19
|
- [Create a mini-program template](#create-a-mini-program-template)
|
|
19
20
|
- [Local debugging](#local-debugging)
|
|
21
|
+
- [Production build](#production-build)
|
|
20
22
|
- [Deploy and publish](#deploy-and-publish)
|
|
21
23
|
- [Developer account scope](#developer-account-scope)
|
|
22
24
|
- [Remote management commands](#remote-management-commands)
|
|
@@ -34,6 +36,7 @@ Use the bundled `hb-sdk` CLI to create a workshop mini-program, open the local d
|
|
|
34
36
|
```text
|
|
35
37
|
hb-sdk create <project-name>
|
|
36
38
|
hb-sdk dev [--port <port>] [--mock-port <port>] [--no-open]
|
|
39
|
+
hb-sdk build [--env <name>] [--verbose]
|
|
37
40
|
hb-sdk login
|
|
38
41
|
hb-sdk login status
|
|
39
42
|
hb-sdk login clear
|
|
@@ -139,6 +142,35 @@ Dev Context 中调整的 `network.request` 权限不会修改线上配置,但
|
|
|
139
142
|
|
|
140
143
|
Use `hb-sdk dev` to open the local debugging page. The "在 Mac 版 APP 中启动" button opens the page in the Mac App; the "Mobile App" QR code opens it in the phone App after a LAN interface is selected. These entries remain available without CLI login or project binding, but managed capabilities are denied by default. The phone and computer must be on the same LAN. If an embedded browser cannot open the App, use the system browser.
|
|
141
144
|
|
|
145
|
+
## Production build
|
|
146
|
+
|
|
147
|
+
## 生产构建
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
hb-sdk build [--env <name>] [--verbose]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`hb-sdk build` 直接使用项目安装的 Vite,先清理再生成固定的 `dist/`,并校验小程序入口、Manifest 和可上传产物。它不执行类型检查,不要求 CLI 登录或绑定小程序,也不访问远端服务。项目必须在 `vite.config.ts` 中显式注册 `miniappManifest()`。
|
|
154
|
+
|
|
155
|
+
推荐由项目的 `scripts.build` 保留类型检查:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"scripts": {
|
|
160
|
+
"build": "vue-tsc --noEmit && hb-sdk build"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
构建命令只支持 `--env` 和 `--verbose`。已有项目继续使用 `vite build` 仍然兼容,不会自动迁移。
|
|
166
|
+
|
|
167
|
+
Agent rules:
|
|
168
|
+
|
|
169
|
+
- Use `hb-sdk build [--env <name>] [--verbose]` as the recommended production build entry.
|
|
170
|
+
- Require explicit `miniappManifest()` configuration and keep typechecking in the project's `scripts.build`.
|
|
171
|
+
- Do not claim `hb-sdk build` needs login, binding, or network access, and do not invent unsupported build flags.
|
|
172
|
+
- Existing `vite build` projects remain compatible and must not be auto-migrated.
|
|
173
|
+
|
|
142
174
|
## Deploy and publish
|
|
143
175
|
|
|
144
176
|
## 部署发布
|
|
@@ -158,7 +190,7 @@ hb-sdk remote bind mp_xxxxxxxx
|
|
|
158
190
|
hb-sdk remote deploy --release-note "修复登录状态展示"
|
|
159
191
|
```
|
|
160
192
|
|
|
161
|
-
|
|
193
|
+
这条命令会完成检查、执行项目的 `scripts.build`、上传和提交审核,因此项目定义的类型检查仍会执行。默认在审核通过后等待手动发布;普通低风险版本可以追加 `--auto-publish`。完整命令见 `hb-sdk remote --help`,提交要求见[小程序工坊上架规则](https://docs.xiaoheihe.cn/hb_sdk/guide/mini-program-publishing-rules)。
|
|
162
194
|
|
|
163
195
|
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.
|
|
164
196
|
|