@heybox/hb-sdk 0.5.8 → 0.5.10
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 +10 -7
- package/dist/cli-chunks/{create-DxRc3VpZ.cjs → create-D1W2pkHZ.cjs} +1 -1
- package/dist/cli-chunks/{dev-C9Jkdl7Y.cjs → dev-DwbE-c1x.cjs} +1 -1
- package/dist/cli-chunks/{doctor-DoiRoJd5.cjs → doctor-Bx71WFjM.cjs} +1 -1
- package/dist/cli-chunks/{index-Dyn_R89O.cjs → index-BBatNb1l.cjs} +15 -13
- package/dist/cli-chunks/{index-DLZbkW1t.cjs → index-D5bZjpH9.cjs} +2 -2
- package/dist/cli-chunks/{login-Dwx2nD5p.cjs → login-BX0YmVyi.cjs} +2 -2
- package/dist/cli-chunks/{remote-C5pPFOvG.cjs → remote-YDmSxyYi.cjs} +81 -45
- package/dist/cli-chunks/{session-tV_vO27h.cjs → session-BxZBXDZ-.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/package.json +3 -1
- package/skill/SKILL.md +25 -22
- package/skill/references/api-root.md +1 -1
- package/skill/references/cli.md +11 -8
- package/skill/references/llms-index.md +1 -0
- package/skill/scripts/sync-agent-skills-payload.mjs +359 -0
- package/skill/scripts/sync-references.mjs +2 -1
- package/skill/skill.json +4 -4
package/README.md
CHANGED
|
@@ -345,7 +345,7 @@ try {
|
|
|
345
345
|
| `hb-sdk remote bind <mini-program-id> [--force]` | 校验当前 CLI 用户可管理目标小程序后,再把它绑定到当前项目。 |
|
|
346
346
|
| `hb-sdk remote info` | 查看当前项目绑定的小程序详情。 |
|
|
347
347
|
| `hb-sdk remote allowlist list/add/remove/set ...` | 管理绑定小程序的预览白名单。 |
|
|
348
|
-
| `hb-sdk remote deploy --release-note <text> [--skip-build] [--auto-publish]`
|
|
348
|
+
| `hb-sdk remote deploy --release-note <text> [--skip-build \| --from-version <version>] [--auto-publish]` | 构建、上传并提交当前小程序版本审核;`--skip-build` 跳过 build 直接上传 `dist/`,`--from-version` 复用指定历史版本产物。 |
|
|
349
349
|
| `hb-sdk remote versions` | 列出绑定小程序的远端版本。 |
|
|
350
350
|
| `hb-sdk remote preview <version>` | 查看指定版本的远端预览入口。 |
|
|
351
351
|
| `hb-sdk remote release <version> [--yes]` | 发布审核通过的版本;非 TTY 环境必须传 `--yes`。 |
|
|
@@ -389,16 +389,19 @@ try {
|
|
|
389
389
|
4. 触发 `<pm> run build`,除非使用 `--skip-build`。
|
|
390
390
|
5. 解析 `dist/manifest.json`,校验 `version` 为 `x.y.z`,自动剥离 BOM;普通 remote deploy 要求该版本与 precheck 使用的 `package.json.version` 一致。
|
|
391
391
|
6. `--skip-build` 会先读取已有 `dist/manifest.json.version`,再调用 precheck。
|
|
392
|
-
7.
|
|
393
|
-
8.
|
|
394
|
-
9.
|
|
395
|
-
10.
|
|
396
|
-
11.
|
|
392
|
+
7. `--from-version <version>` 会跳过本地 build、`dist/` 读取和 CDN 上传,直接让远端复用指定历史版本产物提交审核;它与 `--skip-build` 互斥。
|
|
393
|
+
8. 遍历 `dist/` 文件,跳过 `manifest.json`、`.DS_Store`、`.map`;遇到 symlink 或 `node_modules` 直接报错。
|
|
394
|
+
9. 校验所有上传路径长度不超过 64,并在任何上传请求发生前限制实际上传产物总大小不超过 100MiB。错误提示中使用 `100MB`,方便开发者理解。
|
|
395
|
+
10. 上传信息、上传凭证和上传回调按批次执行,每批最多 50 个文件;批次串行,批内保持 4 并发上传到 COS。CLI 会校验 CDN 上传信息接口返回的 key 与本地期望 key 完全一致,异常时停止后续批次且不提交审核。
|
|
396
|
+
11. 默认只展示上传阶段和文件总数,例如 `正在上传 137/244 个文件`;`--verbose` 会展示并发数、批次数、当前批次、bucket / region 和逐文件结果,但不会输出 keys、签名、cookie、pkey、token 或临时密钥。
|
|
397
|
+
12. 全部上传成功后调用 `/mall/developer/user_miniprogram/version/submit_audit`;`--from-version` 路径会直接调用提交审核接口并传入 `source_version`。CLI 输出提交审核成功、发布策略和可用的 preview URL;后端原始失败细节只在 `--verbose` 下展示。
|
|
397
398
|
|
|
398
399
|
默认 `auto_publish=false`,审核通过后使用 `hb-sdk remote versions` 查看版本状态,再用 `hb-sdk remote release <version>` 发布;使用 `--auto-publish` 时提交 `auto_publish=true`,审核通过后自动发布。未发布候选版本可通过 `hb-sdk remote allowlist add <heybox_id>` 加入预览白名单,让指定用户在广场看到;正式入口使用 `mini_program_id`,`mini_url` 仅用于本地调试。
|
|
399
400
|
|
|
400
401
|
`--skip-build` 用于 CI 双阶段:上一步已经 build 完缓存好了 `dist/`,本步只做预检、上传和提交审核。`dist/manifest.json` 或 `dist/index.html` 缺失会立即报错。
|
|
401
402
|
|
|
403
|
+
`--from-version <version>` 用于复用已经上传过的远端历史版本产物提交新一轮审核。该模式不读取本地 `dist/`,也不会执行 build 或上传;目标审核版本由服务端根据版本表最高 SemVer 自动派生。不要和 `--skip-build` 同时使用。
|
|
404
|
+
|
|
402
405
|
`manifest.json` 不会上传到 CDN,只作为 submit audit 请求的 `manifest` 字段提交。这与 Vite 插件文档中的契约一致。名称、icon 和介绍图从 `package.json.heybox.miniProgramProfile` 读取,并随 precheck 和 submit audit 一起提交:
|
|
403
406
|
|
|
404
407
|
```json
|
|
@@ -448,7 +451,7 @@ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://12
|
|
|
448
451
|
| `hb-sdk remote allowlist add <heybox-id...>` | 添加十进制 Heybox ID 到预览白名单。 |
|
|
449
452
|
| `hb-sdk remote allowlist remove <heybox-id...>` | 从预览白名单移除非 owner 条目。 |
|
|
450
453
|
| `hb-sdk remote allowlist set <heybox-id...>` | 替换非 owner 白名单条目,并保留平台返回的 owner 语义。 |
|
|
451
|
-
| `hb-sdk remote deploy --release-note <text> [--skip-build] [--auto-publish]`
|
|
454
|
+
| `hb-sdk remote deploy --release-note <text> [--skip-build \| --from-version <version>] [--auto-publish]` | 构建、上传或复用历史产物并提交当前版本审核。 |
|
|
452
455
|
| `hb-sdk remote versions` | 列出当前绑定小程序的远端版本。 |
|
|
453
456
|
| `hb-sdk remote preview <version>` | 查看指定版本的远端预览入口。 |
|
|
454
457
|
| `hb-sdk remote release <version> [--yes]` | 发布审核通过的版本;交互式终端会确认,非 TTY 必须传 `--yes`。 |
|
|
@@ -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-
|
|
8
|
+
var index = require('./index-BBatNb1l.cjs');
|
|
9
9
|
require('node:module');
|
|
10
10
|
require('os');
|
|
11
11
|
require('readline');
|
|
@@ -9,7 +9,7 @@ var node_url = require('node:url');
|
|
|
9
9
|
var net = require('node:net');
|
|
10
10
|
var node_http = require('node:http');
|
|
11
11
|
var browser = require('./browser-RAy8e8cV.cjs');
|
|
12
|
-
var index = require('./index-
|
|
12
|
+
var index = require('./index-BBatNb1l.cjs');
|
|
13
13
|
require('node:process');
|
|
14
14
|
require('node:buffer');
|
|
15
15
|
require('node:util');
|
|
@@ -4,7 +4,7 @@ var fs$1 = require('node:fs');
|
|
|
4
4
|
var fs = require('node:fs/promises');
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var path = require('node:path');
|
|
7
|
-
var index = require('./index-
|
|
7
|
+
var index = require('./index-BBatNb1l.cjs');
|
|
8
8
|
require('node:module');
|
|
9
9
|
require('path');
|
|
10
10
|
require('os');
|
|
@@ -234,19 +234,19 @@ function requireArgument () {
|
|
|
234
234
|
|
|
235
235
|
var command = {};
|
|
236
236
|
|
|
237
|
-
const require$5 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
237
|
+
const require$5 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-BBatNb1l.cjs', document.baseURI).href)));
|
|
238
238
|
function __require$4() { return require$5("node:events"); }
|
|
239
239
|
|
|
240
|
-
const require$4 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
240
|
+
const require$4 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-BBatNb1l.cjs', document.baseURI).href)));
|
|
241
241
|
function __require$3() { return require$4("node:child_process"); }
|
|
242
242
|
|
|
243
|
-
const require$3 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
243
|
+
const require$3 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-BBatNb1l.cjs', document.baseURI).href)));
|
|
244
244
|
function __require$2() { return require$3("node:path"); }
|
|
245
245
|
|
|
246
|
-
const require$2 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
246
|
+
const require$2 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-BBatNb1l.cjs', document.baseURI).href)));
|
|
247
247
|
function __require$1() { return require$2("node:fs"); }
|
|
248
248
|
|
|
249
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
249
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-BBatNb1l.cjs', document.baseURI).href)));
|
|
250
250
|
function __require() { return require$1("node:process"); }
|
|
251
251
|
|
|
252
252
|
var help = {};
|
|
@@ -13094,7 +13094,7 @@ function readErrorMessage(error, options = {}) {
|
|
|
13094
13094
|
}
|
|
13095
13095
|
|
|
13096
13096
|
const CLI_VERSION_PLACEHOLDER = ['__HB', 'SDK', 'CLI', 'VERSION__'].join('_');
|
|
13097
|
-
const BUILT_CLI_VERSION = '0.5.
|
|
13097
|
+
const BUILT_CLI_VERSION = '0.5.10';
|
|
13098
13098
|
const PACKAGE_JSON_CANDIDATES = [
|
|
13099
13099
|
path.resolve(__dirname, '..', '..', 'package.json'),
|
|
13100
13100
|
path.resolve(__dirname, '..', 'package.json'),
|
|
@@ -13263,11 +13263,13 @@ function installRemoteCommands(program, handlers, resolveLogger) {
|
|
|
13263
13263
|
.command('deploy')
|
|
13264
13264
|
.description('构建并提交当前小程序版本审核')
|
|
13265
13265
|
.option('--skip-build', '跳过 build,直接读 dist 目录上传并提交审核')
|
|
13266
|
+
.option('--from-version <version>', '复用指定历史版本产物提交审核')
|
|
13266
13267
|
.option('--release-note <text>', '发布日志,提交审核必填')
|
|
13267
13268
|
.option('--auto-publish', '审核通过后自动发布;默认需在 CLI 中手动发布')).action(createRemoteAction(handlers, resolveLogger, 'deploy', (command) => {
|
|
13268
13269
|
const options = readCommandOptionsWithAncestors(command);
|
|
13269
13270
|
return {
|
|
13270
13271
|
autoPublish: Boolean(options.autoPublish),
|
|
13272
|
+
fromVersion: readStringOption(options.fromVersion),
|
|
13271
13273
|
releaseNote: readStringOption(options.releaseNote),
|
|
13272
13274
|
skipBuild: Boolean(options.skipBuild),
|
|
13273
13275
|
};
|
|
@@ -13372,31 +13374,31 @@ function createCommandLoggerResolver(options) {
|
|
|
13372
13374
|
};
|
|
13373
13375
|
}
|
|
13374
13376
|
const defaultClearLoginStatus = async (...args) => {
|
|
13375
|
-
const { clearLoginStatus } = await Promise.resolve().then(function () { return require('./login-
|
|
13377
|
+
const { clearLoginStatus } = await Promise.resolve().then(function () { return require('./login-BX0YmVyi.cjs'); });
|
|
13376
13378
|
return clearLoginStatus(...args);
|
|
13377
13379
|
};
|
|
13378
13380
|
const defaultLoginToHeybox = async (...args) => {
|
|
13379
|
-
const { loginToHeybox } = await Promise.resolve().then(function () { return require('./login-
|
|
13381
|
+
const { loginToHeybox } = await Promise.resolve().then(function () { return require('./login-BX0YmVyi.cjs'); });
|
|
13380
13382
|
return loginToHeybox(...args);
|
|
13381
13383
|
};
|
|
13382
13384
|
const defaultPrintLoginStatus = async (...args) => {
|
|
13383
|
-
const { printLoginStatus } = await Promise.resolve().then(function () { return require('./login-
|
|
13385
|
+
const { printLoginStatus } = await Promise.resolve().then(function () { return require('./login-BX0YmVyi.cjs'); });
|
|
13384
13386
|
return printLoginStatus(...args);
|
|
13385
13387
|
};
|
|
13386
13388
|
const defaultRunCreateCommand = async (...args) => {
|
|
13387
|
-
const { runCreateCommand } = await Promise.resolve().then(function () { return require('./create-
|
|
13389
|
+
const { runCreateCommand } = await Promise.resolve().then(function () { return require('./create-D1W2pkHZ.cjs'); });
|
|
13388
13390
|
return runCreateCommand(...args);
|
|
13389
13391
|
};
|
|
13390
13392
|
const defaultRunDevCommand = async (...args) => {
|
|
13391
|
-
const { runDevCommand } = await Promise.resolve().then(function () { return require('./dev-
|
|
13393
|
+
const { runDevCommand } = await Promise.resolve().then(function () { return require('./dev-DwbE-c1x.cjs'); });
|
|
13392
13394
|
return runDevCommand(...args);
|
|
13393
13395
|
};
|
|
13394
13396
|
const defaultRunDoctorCommand = async (...args) => {
|
|
13395
|
-
const { runDoctorCommand } = await Promise.resolve().then(function () { return require('./doctor-
|
|
13397
|
+
const { runDoctorCommand } = await Promise.resolve().then(function () { return require('./doctor-Bx71WFjM.cjs'); });
|
|
13396
13398
|
return runDoctorCommand(...args);
|
|
13397
13399
|
};
|
|
13398
13400
|
const defaultRunRemoteCommand = async (...args) => {
|
|
13399
|
-
const { runRemoteCommand } = await Promise.resolve().then(function () { return require('./remote-
|
|
13401
|
+
const { runRemoteCommand } = await Promise.resolve().then(function () { return require('./remote-YDmSxyYi.cjs'); }).then(function (n) { return n.remote; });
|
|
13400
13402
|
return runRemoteCommand(...args);
|
|
13401
13403
|
};
|
|
13402
13404
|
function resolveStandaloneLogger(options, verbose) {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index$2 = require('./index-
|
|
3
|
+
var index$2 = require('./index-BBatNb1l.cjs');
|
|
4
4
|
var require$$0$2 = require('fs');
|
|
5
5
|
var require$$2$1 = require('crypto');
|
|
6
6
|
var require$$1$2 = require('path');
|
|
7
7
|
var require$$0$3 = require('assert');
|
|
8
8
|
var require$$4$2 = require('events');
|
|
9
9
|
var require$$1$1 = require('util');
|
|
10
|
-
var remote = require('./remote-
|
|
10
|
+
var remote = require('./remote-YDmSxyYi.cjs');
|
|
11
11
|
var require$$0$5 = require('net');
|
|
12
12
|
var require$$0$4 = require('url');
|
|
13
13
|
var require$$2$2 = require('http');
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
var promises = require('node:readline/promises');
|
|
4
4
|
var node_crypto = require('node:crypto');
|
|
5
5
|
var node_http = require('node:http');
|
|
6
|
-
var session = require('./session-
|
|
6
|
+
var session = require('./session-BxZBXDZ-.cjs');
|
|
7
7
|
var browser = require('./browser-RAy8e8cV.cjs');
|
|
8
|
-
var index = require('./index-
|
|
8
|
+
var index = require('./index-BBatNb1l.cjs');
|
|
9
9
|
require('node:path');
|
|
10
10
|
require('fs');
|
|
11
11
|
require('constants');
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var promises = require('node:readline/promises');
|
|
4
|
-
var session = require('./session-
|
|
4
|
+
var session = require('./session-BxZBXDZ-.cjs');
|
|
5
5
|
var childProcess = require('node:child_process');
|
|
6
6
|
var fs = require('node:fs');
|
|
7
7
|
var fs$1 = require('node:fs/promises');
|
|
8
8
|
var path = require('node:path');
|
|
9
|
-
var index = require('./index-
|
|
9
|
+
var index = require('./index-BBatNb1l.cjs');
|
|
10
10
|
|
|
11
11
|
var re = {exports: {}};
|
|
12
12
|
|
|
@@ -3111,7 +3111,7 @@ async function createDefaultCosClient(uploadToken) {
|
|
|
3111
3111
|
};
|
|
3112
3112
|
}
|
|
3113
3113
|
async function loadCosConstructor() {
|
|
3114
|
-
const cosModule = await Promise.resolve().then(function () { return require('./index-
|
|
3114
|
+
const cosModule = await Promise.resolve().then(function () { return require('./index-D5bZjpH9.cjs'); }).then(function (n) { return n.index; });
|
|
3115
3115
|
return cosModule.default;
|
|
3116
3116
|
}
|
|
3117
3117
|
function formatSize(bytes) {
|
|
@@ -3159,7 +3159,8 @@ async function precheckUserMiniprogramVersion$1(options, runtime = {}) {
|
|
|
3159
3159
|
name: options.name,
|
|
3160
3160
|
icon_url: options.iconUrl,
|
|
3161
3161
|
cover_image_urls: options.coverImageUrls.join(','),
|
|
3162
|
-
version: options.version,
|
|
3162
|
+
...(options.version ? { version: options.version } : {}),
|
|
3163
|
+
...(options.source_version ? { source_version: options.source_version } : {}),
|
|
3163
3164
|
release_note: options.releaseNote,
|
|
3164
3165
|
auto_publish: String(options.autoPublish),
|
|
3165
3166
|
}, runtime);
|
|
@@ -3169,7 +3170,8 @@ async function submitUserMiniprogramAudit$1(options, runtime = {}) {
|
|
|
3169
3170
|
name: options.name,
|
|
3170
3171
|
icon_url: options.iconUrl,
|
|
3171
3172
|
cover_image_urls: options.coverImageUrls.join(','),
|
|
3172
|
-
manifest: JSON.stringify(options.manifest),
|
|
3173
|
+
...(options.manifest ? { manifest: JSON.stringify(options.manifest) } : {}),
|
|
3174
|
+
...(options.source_version ? { source_version: options.source_version } : {}),
|
|
3173
3175
|
release_note: options.releaseNote,
|
|
3174
3176
|
auto_publish: String(options.autoPublish),
|
|
3175
3177
|
}, runtime);
|
|
@@ -3231,12 +3233,28 @@ async function runDeployCommand(options, runtime = {}) {
|
|
|
3231
3233
|
throw new Error('未在 package.json 中找到 heybox.miniProgramId,请先配置 mini program id');
|
|
3232
3234
|
}
|
|
3233
3235
|
const miniProgramProfile = readMiniProgramVersionProfile(packageJson);
|
|
3236
|
+
const fromVersion = options.fromVersion?.trim();
|
|
3237
|
+
if (fromVersion && options.skipBuild) {
|
|
3238
|
+
throw new Error('--from-version 与 --skip-build 不能同时使用:--from-version 会复用远端历史产物,不读取本地 dist/');
|
|
3239
|
+
}
|
|
3234
3240
|
const releaseNote = await resolveDeployReleaseNote(options, runtime);
|
|
3235
3241
|
const session$1 = await logger.task('正在校验 Heybox 登录态', () => (runtime.requireAuthSession ?? session.requireHeyboxAuthSession)({ loginBaseUrl }), { successText: 'Heybox 登录态有效' });
|
|
3236
3242
|
logger.debug(`Heybox API: ${apiBaseUrl}`);
|
|
3237
3243
|
let precheckVersion;
|
|
3238
3244
|
let parsedManifest;
|
|
3239
|
-
|
|
3245
|
+
const historyArtifact = fromVersion ? { source_version: fromVersion } : {};
|
|
3246
|
+
if (fromVersion) {
|
|
3247
|
+
const precheck = await runVersionPrecheck({
|
|
3248
|
+
session: session$1,
|
|
3249
|
+
miniProgramId,
|
|
3250
|
+
...miniProgramProfile,
|
|
3251
|
+
...historyArtifact,
|
|
3252
|
+
releaseNote,
|
|
3253
|
+
autoPublish,
|
|
3254
|
+
}, runtime, apiBaseUrl, projectRoot, logger);
|
|
3255
|
+
precheckVersion = precheck.version || precheck.version_normalized || fromVersion;
|
|
3256
|
+
}
|
|
3257
|
+
else if (!options.skipBuild) {
|
|
3240
3258
|
if (typeof packageJson.scripts?.build !== 'string') {
|
|
3241
3259
|
throw new Error('package.json scripts.build 未定义,请添加 build 脚本或使用 --skip-build 跳过构建');
|
|
3242
3260
|
}
|
|
@@ -3269,44 +3287,61 @@ async function runDeployCommand(options, runtime = {}) {
|
|
|
3269
3287
|
autoPublish,
|
|
3270
3288
|
}, runtime, apiBaseUrl, projectRoot, logger);
|
|
3271
3289
|
}
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
if (
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
if (blocked) {
|
|
3282
|
-
throw new Error(`dist 目录含 node_modules:${blocked.relativePath}`);
|
|
3290
|
+
let submitAuditResult;
|
|
3291
|
+
let version = precheckVersion;
|
|
3292
|
+
let manifest;
|
|
3293
|
+
if (!fromVersion) {
|
|
3294
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
3295
|
+
parsedManifest ??= await readDeployManifest(projectRoot, logger);
|
|
3296
|
+
({ manifest, version } = parsedManifest);
|
|
3297
|
+
if (version !== precheckVersion) {
|
|
3298
|
+
throw new Error(`dist/manifest.json.version (${version}) 与预检版本 (${precheckVersion}) 不一致,请重新 build 后再 deploy`);
|
|
3283
3299
|
}
|
|
3284
|
-
const
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3300
|
+
const uploadFiles = await logger.task('正在校验 dist 上传文件', async () => {
|
|
3301
|
+
const allFiles = await walkDistFiles(distDir);
|
|
3302
|
+
const blocked = allFiles.find((entry) => relativePathContainsNodeModulesSegment(entry.relativePath));
|
|
3303
|
+
if (blocked) {
|
|
3304
|
+
throw new Error(`dist 目录含 node_modules:${blocked.relativePath}`);
|
|
3305
|
+
}
|
|
3306
|
+
const files = allFiles.filter((entry) => shouldUploadDistFile(entry.relativePath));
|
|
3307
|
+
const pathError = validateUploadPaths(files, { miniProgramId, version, maxLength: ACTIVITY_UPLOAD_KEY_MAX_LENGTH });
|
|
3308
|
+
if (pathError) {
|
|
3309
|
+
throw new Error(pathError);
|
|
3310
|
+
}
|
|
3311
|
+
const sizeError = validateUploadTotalSize(files);
|
|
3312
|
+
if (sizeError) {
|
|
3313
|
+
throw new Error(sizeError);
|
|
3314
|
+
}
|
|
3315
|
+
logger.debug(`待上传文件数: ${files.length}`);
|
|
3316
|
+
return files;
|
|
3317
|
+
}, { successText: 'dist 上传文件校验完成' });
|
|
3318
|
+
try {
|
|
3319
|
+
await (runtime.runUpload ?? runUpload)({ session: session$1, miniProgramId, version, files: uploadFiles }, { baseUrl: apiBaseUrl, fetchImpl: runtime.fetchImpl, logger });
|
|
3288
3320
|
}
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
throw new Error(sizeError);
|
|
3321
|
+
catch (error) {
|
|
3322
|
+
throw translateHeyboxDeployError(error, { projectRoot, stage: 'upload', version });
|
|
3292
3323
|
}
|
|
3293
|
-
logger.debug(`待上传文件数: ${files.length}`);
|
|
3294
|
-
return files;
|
|
3295
|
-
}, { successText: 'dist 上传文件校验完成' });
|
|
3296
|
-
let submitAuditResult;
|
|
3297
|
-
try {
|
|
3298
|
-
await (runtime.runUpload ?? runUpload)({ session: session$1, miniProgramId, version, files: uploadFiles }, { baseUrl: apiBaseUrl, fetchImpl: runtime.fetchImpl, logger });
|
|
3299
|
-
}
|
|
3300
|
-
catch (error) {
|
|
3301
|
-
throw translateHeyboxDeployError(error, { projectRoot, stage: 'upload', version });
|
|
3302
3324
|
}
|
|
3303
3325
|
try {
|
|
3304
|
-
|
|
3326
|
+
const submitOptions = fromVersion
|
|
3327
|
+
? { session: session$1, miniProgramId, ...miniProgramProfile, ...historyArtifact, releaseNote, autoPublish }
|
|
3328
|
+
: { session: session$1, miniProgramId, ...miniProgramProfile, manifest, releaseNote, autoPublish };
|
|
3329
|
+
submitAuditResult = await logger.task('正在提交审核', () => (runtime.submitUserMiniprogramAudit ?? submitUserMiniprogramAudit$1)(submitOptions, {
|
|
3330
|
+
baseUrl: apiBaseUrl,
|
|
3331
|
+
fetchImpl: runtime.fetchImpl,
|
|
3332
|
+
}), { successText: '审核提交完成' });
|
|
3305
3333
|
}
|
|
3306
3334
|
catch (error) {
|
|
3307
3335
|
throw translateHeyboxDeployError(error, { projectRoot, stage: 'submitAudit', version });
|
|
3308
3336
|
}
|
|
3309
|
-
printDeploySuccess({
|
|
3337
|
+
printDeploySuccess({
|
|
3338
|
+
autoPublish,
|
|
3339
|
+
logger,
|
|
3340
|
+
miniProgramId,
|
|
3341
|
+
mode: options.successOutputMode ?? 'legacy',
|
|
3342
|
+
protocolString: submitAuditResult.protocol_string,
|
|
3343
|
+
version,
|
|
3344
|
+
});
|
|
3310
3345
|
return {
|
|
3311
3346
|
autoPublish,
|
|
3312
3347
|
changed: true,
|
|
@@ -3375,9 +3410,7 @@ function readCoverImageUrls(value) {
|
|
|
3375
3410
|
if (!Array.isArray(value)) {
|
|
3376
3411
|
throw new Error('heybox.miniProgramProfile.coverImageUrls 至少配置 1 张 HTTPS 图片');
|
|
3377
3412
|
}
|
|
3378
|
-
const urls = value
|
|
3379
|
-
.map((item) => (typeof item === 'string' ? item.trim() : ''))
|
|
3380
|
-
.filter(Boolean);
|
|
3413
|
+
const urls = value.map((item) => (typeof item === 'string' ? item.trim() : '')).filter(Boolean);
|
|
3381
3414
|
if (urls.length === 0) {
|
|
3382
3415
|
throw new Error('heybox.miniProgramProfile.coverImageUrls 至少配置 1 张 HTTPS 图片');
|
|
3383
3416
|
}
|
|
@@ -3446,13 +3479,14 @@ async function maybePromptReleaseNote(runtime) {
|
|
|
3446
3479
|
}
|
|
3447
3480
|
async function runVersionPrecheck(options, runtime, apiBaseUrl, projectRoot, logger) {
|
|
3448
3481
|
try {
|
|
3449
|
-
|
|
3482
|
+
const label = options.version ?? options.source_version ?? '';
|
|
3483
|
+
return await logger.task(`正在预检版本 ${label}`, () => (runtime.precheckUserMiniprogramVersion ?? precheckUserMiniprogramVersion$1)(options, {
|
|
3450
3484
|
baseUrl: apiBaseUrl,
|
|
3451
3485
|
fetchImpl: runtime.fetchImpl,
|
|
3452
|
-
}), { successText: `版本 ${
|
|
3486
|
+
}), { successText: `版本 ${label} 预检通过` });
|
|
3453
3487
|
}
|
|
3454
3488
|
catch (error) {
|
|
3455
|
-
throw translateHeyboxDeployError(error, { projectRoot, stage: 'precheck', version: options.version });
|
|
3489
|
+
throw translateHeyboxDeployError(error, { projectRoot, stage: 'precheck', version: options.version ?? options.source_version ?? '' });
|
|
3456
3490
|
}
|
|
3457
3491
|
}
|
|
3458
3492
|
function detectPackageManager(projectRoot) {
|
|
@@ -3632,10 +3666,11 @@ async function precheckUserMiniprogramVersion(options, runtime) {
|
|
|
3632
3666
|
return remotePostForm(PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
|
|
3633
3667
|
}
|
|
3634
3668
|
async function submitUserMiniprogramAudit(options, runtime) {
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
}
|
|
3669
|
+
const form = { ...options };
|
|
3670
|
+
if (form.manifest && typeof form.manifest !== 'string') {
|
|
3671
|
+
form.manifest = JSON.stringify(form.manifest);
|
|
3672
|
+
}
|
|
3673
|
+
return remotePostForm(SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, form, runtime);
|
|
3639
3674
|
}
|
|
3640
3675
|
async function getVersionPreviewInfo(options, runtime) {
|
|
3641
3676
|
return remoteGet(USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH, {
|
|
@@ -3897,6 +3932,7 @@ async function runRemoteDeployCommand(options, runtime) {
|
|
|
3897
3932
|
apiBaseUrl: options.apiBaseUrl,
|
|
3898
3933
|
autoPublish: options.autoPublish,
|
|
3899
3934
|
env: options.env,
|
|
3935
|
+
fromVersion: options.fromVersion,
|
|
3900
3936
|
loginBaseUrl: options.loginBaseUrl,
|
|
3901
3937
|
releaseNote: options.releaseNote,
|
|
3902
3938
|
skipBuild: options.skipBuild,
|
package/dist/cli.cjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heybox/hb-sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.10",
|
|
4
4
|
"description": "",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -117,6 +117,8 @@
|
|
|
117
117
|
"build:types": "tsc -p tsconfig.dts.json",
|
|
118
118
|
"check:boundary": "node scripts/check-boundary.cjs",
|
|
119
119
|
"check:docs-sync": "node scripts/check-docs-sync.cjs",
|
|
120
|
+
"sync:agent-skills-payload": "node skill/scripts/sync-agent-skills-payload.mjs",
|
|
121
|
+
"check:agent-skills-payload": "node skill/scripts/sync-agent-skills-payload.mjs --check",
|
|
120
122
|
"clean": "rimraf ./dist && rimraf ./types",
|
|
121
123
|
"test:unit": "NODE_OPTIONS='--conditions=heybox' vitest run",
|
|
122
124
|
"test:unit:coverage": "NODE_OPTIONS='--conditions=heybox' vitest run --coverage",
|
package/skill/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hb-sdk
|
|
3
|
-
description: Uses @heybox/hb-sdk and its hb-sdk CLI for Heybox external mini-program iframe pages, local mock development, template creation, skill version checks,
|
|
3
|
+
description: Uses @heybox/hb-sdk and its hb-sdk CLI for Heybox external mini-program iframe pages, local mock development, template creation, skill version checks, host/runtime protocol integration, and mini-program listing/audit/compliance review. Use for ready/auth/user/share/viewport/storage/network APIs, lifecycle events, hb-sdk create/dev/login/doctor, mock runtime debugging, custom SDK instances, or @heybox/hb-sdk/protocol contracts. Don't use for raw postMessage bridge construction in app code, direct cookie/token access, internal Heybox client protocols, separate mock runtimes, or non-Heybox SDKs.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# hb-sdk Agent Procedure
|
|
@@ -12,8 +12,9 @@ Apply these instructions when writing, reviewing, or debugging code that consume
|
|
|
12
12
|
1. If the task is iframe 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
14
|
3. If the task is project scaffolding, local Vite startup, browser mock runtime, CLI login cache, Agent Skill version diagnosis, or CLI troubleshooting, use the `hb-sdk` CLI workflow.
|
|
15
|
-
4. If the task
|
|
16
|
-
5. If the task
|
|
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
|
+
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
|
+
6. If the task is not about Heybox external mini-program SDK usage, CLI usage, mock runtime, protocol contracts, or mini-program listing/audit/compliance review, do not apply this skill.
|
|
17
18
|
|
|
18
19
|
## Step 2: Load only the needed reference
|
|
19
20
|
|
|
@@ -26,6 +27,7 @@ Apply these instructions when writing, reviewing, or debugging code that consume
|
|
|
26
27
|
7. For generated documentation provenance and deeper API lookup paths, read `references/llms-index.md`.
|
|
27
28
|
8. For smoke-test expectations, positive examples, and anti-examples, read `references/examples.md`.
|
|
28
29
|
9. For evaluating whether another agent followed this skill, read `references/smoke-evaluation.md`.
|
|
30
|
+
10. For mini-program listing/audit/compliance review, fetch the online rules Markdown from `https://open.xiaoheihe.cn/docs/hb_sdk/llms/guide/mini-program-publishing-rules.md`. Do not rely on a bundled `references/` copy of this document; if the URL is unavailable or returns the docs app shell instead of Markdown, report that the online rules are unavailable and do not complete the review from stale local text.
|
|
29
31
|
|
|
30
32
|
## Step 3: Follow import rules
|
|
31
33
|
|
|
@@ -54,25 +56,26 @@ Apply these instructions when writing, reviewing, or debugging code that consume
|
|
|
54
56
|
6. 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 read/basic/preview management workflows. Mini-program name and image changes must go through version audit, so the CLI must not expose a basic-info update command.
|
|
55
57
|
7. Use `hb-sdk remote deploy --release-note <text>` to build, upload, and submit the current project for audit. It reads `package.json.heybox.miniProgramId`, validates that the bound mini-program belongs to the server-side current entity before precheck/build/upload, prechecks `package.json.version` before build, runs the project's `build` script via the package manager auto-detected by lockfile, uploads `dist/` to CDN (skipping `manifest.json`, `.DS_Store`, `.map`), then calls the submit-audit API. The deploy upload pipeline rejects actual upload artifacts over 100MiB before any upload request, processes CDN upload metadata and callback confirmation at 50 files per batch, keeps 4-way upload concurrency within each batch, and validates CDN-returned keys exactly against the local expected upload keys.
|
|
56
58
|
8. Use `hb-sdk remote deploy --skip-build --release-note <text>` only when the `dist/` directory is already prepared by an upstream CI stage. In this mode the CLI reads `dist/manifest.json.version` before precheck. Missing `dist/manifest.json` or `dist/index.html` aborts the run.
|
|
57
|
-
9.
|
|
58
|
-
10.
|
|
59
|
-
11.
|
|
60
|
-
12. For
|
|
61
|
-
13.
|
|
62
|
-
14.
|
|
63
|
-
15.
|
|
64
|
-
16.
|
|
65
|
-
17.
|
|
66
|
-
18. Use
|
|
67
|
-
19. Use
|
|
68
|
-
20.
|
|
69
|
-
21.
|
|
70
|
-
22.
|
|
71
|
-
23.
|
|
72
|
-
24.
|
|
73
|
-
25.
|
|
74
|
-
26.
|
|
75
|
-
27. Do not
|
|
59
|
+
9. Use `hb-sdk remote deploy --from-version <version> --release-note <text>` to reuse a previously uploaded remote version artifact and submit a new audit version without reading local `dist/`, building, or uploading. Do not combine `--from-version` with `--skip-build`.
|
|
60
|
+
10. Always provide a concise release note before deploy. Non-interactive environments must pass `--release-note`; interactive terminals may prompt for it. The default is manual release after approval with `hb-sdk remote release <version>`; use `--auto-publish` when the audited version should automatically release after approval.
|
|
61
|
+
11. Use `hb-sdk remote release <version>`, `hb-sdk remote withdraw <version>`, `hb-sdk remote take-down`, and `hb-sdk remote reopen` for dangerous remote changes. Interactive terminals should confirm after showing enough context; non-interactive environments must pass `--yes`.
|
|
62
|
+
12. For internal test/staging backend operations, use origin-only custom URLs: `HB_SDK_API_BASE_URL` or `hb-sdk remote ... --api-base-url <url>` for remote platform APIs, and `HB_SDK_LOGIN_BASE_URL` or `hb-sdk login --login-base-url <url>` for browser login. CLI flags override env vars. API base URLs must be Heybox trusted HTTPS origins by default; use `--allow-unsafe-api-base-url` or `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` only for local backend debugging. Do not include path, query, or hash in these URLs.
|
|
63
|
+
13. For development routing or gray validation, configure `packages/hb-sdk/src/cli/config.ts` with `@heybox/hb-types` `RylaiServiceTagConfig` (`default_tag` / path-specific `special_tag`) to attach `x-rylai-service-tag` and the matching `special_tag` query parameter to Heybox backend API requests.
|
|
64
|
+
14. If a remote command targets a custom login environment, pass the same `--login-base-url` or `HB_SDK_LOGIN_BASE_URL` used for `hb-sdk login`; remote commands reject cached CLI login state from a different login origin.
|
|
65
|
+
15. Add `--verbose` / `-v` only when diagnosing failures; default CLI errors are intentionally concise, while verbose output includes backend envelope, HTTP status, trace fields, raw body, or original submit-audit failure details.
|
|
66
|
+
16. Use `--json` for script consumption of `hb-sdk remote` commands. With `--json`, stdout must contain exactly one JSON object; progress, warnings, update reminders, and verbose diagnostics must not pollute stdout.
|
|
67
|
+
17. Do not expect custom base URLs to affect `hb-sdk doctor`, npm latest checks, or mock-host `network.request()`.
|
|
68
|
+
18. Use the Mock runtime host's "在 Mac 版 APP 中启动" button for Mac App debugging, or the "Mobile App" QR code after selecting a LAN interface for phone App debugging; the phone must be on the same LAN and use a Heybox App version that supports the mini-program dev shell.
|
|
69
|
+
19. Use `--port`, `--mock-port`, and `--no-open` when the default Vite/mock ports or browser opening behavior need to be controlled.
|
|
70
|
+
20. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for the CLI's own Heybox auth cache. Keep `hb-sdk login` top-level; it is not a remote mini-program command.
|
|
71
|
+
21. Treat `selectedEntity` in the CLI auth cache as a non-authoritative hint snapshot only. Every remote command must use the server-side current entity as the source of truth.
|
|
72
|
+
22. Use `hb-sdk doctor` to diagnose whether the local `hb-sdk` skill matches the installed SDK and remote latest skill metadata.
|
|
73
|
+
23. 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`.
|
|
74
|
+
24. If doctor reports `SDK_MISMATCH`, upgrade `@heybox/hb-sdk@latest` before reinstalling the skill.
|
|
75
|
+
25. Do not treat CLI login cache as iframe SDK login state; it does not change `auth.login()`, `user.getInfo()`, `network.request()`, or mock-user behavior.
|
|
76
|
+
26. Keep the CLI and mock runtime under `@heybox/hb-sdk`; do not create or revive a separate mock runtime package.
|
|
77
|
+
27. Do not pass `mini_program_id` or `entity_id` as general CLI flags or environment variables; the mini-program id must come from `package.json.heybox.miniProgramId`, and the entity must come from the server-side current entity.
|
|
78
|
+
28. Do not import deploy / upload internals from outside the CLI; the only externally consumable subpath for publish-pipeline helpers is `@heybox/hb-sdk/miniapp-publish`.
|
|
76
79
|
|
|
77
80
|
## Step 6: Preserve capability boundaries
|
|
78
81
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
## Package metadata
|
|
20
20
|
|
|
21
21
|
- Package: `@heybox/hb-sdk`
|
|
22
|
-
- Version at generation time: `0.5.
|
|
22
|
+
- Version at generation time: `0.5.9`
|
|
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`
|
package/skill/references/cli.md
CHANGED
|
@@ -56,7 +56,7 @@ hb-sdk remote allowlist list
|
|
|
56
56
|
hb-sdk remote allowlist add <heybox-id...>
|
|
57
57
|
hb-sdk remote allowlist remove <heybox-id...>
|
|
58
58
|
hb-sdk remote allowlist set <heybox-id...>
|
|
59
|
-
hb-sdk remote deploy --release-note <text> [--skip-build] [--auto-publish]
|
|
59
|
+
hb-sdk remote deploy --release-note <text> [--skip-build | --from-version <version>] [--auto-publish]
|
|
60
60
|
hb-sdk remote versions
|
|
61
61
|
hb-sdk remote preview <version>
|
|
62
62
|
hb-sdk remote release <version> [--yes]
|
|
@@ -132,6 +132,7 @@ Use `hb-sdk dev` for local browser SDK debugging. Use the Mock runtime host's "
|
|
|
132
132
|
hb-sdk remote deploy --release-note "修复登录状态展示,补充异常提示"
|
|
133
133
|
hb-sdk remote deploy --release-note "审核通过后自动发布" --auto-publish
|
|
134
134
|
hb-sdk remote deploy --skip-build --release-note "复用已有 dist 构建产物"
|
|
135
|
+
hb-sdk remote deploy --from-version 1.2.3 --release-note "复用 1.2.3 历史产物"
|
|
135
136
|
hb-sdk remote deploy --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "测试环境验证"
|
|
136
137
|
hb-sdk remote deploy --verbose --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "排查预检失败"
|
|
137
138
|
HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://127.0.0.1:8080 --release-note "本地后台联调"
|
|
@@ -145,13 +146,14 @@ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://12
|
|
|
145
146
|
4. 读取并校验 `--release-note`;TTY 环境缺失时会提示输入,CI / 非 TTY 环境缺失时直接失败。建议让 AI 生成 1-5 条简短发布日志。
|
|
146
147
|
5. 普通 remote deploy 先读取 `package.json.version`,登录后、build 前调用版本预检接口;预检通过后才执行 `<pm> run build`。
|
|
147
148
|
6. `--skip-build` 跳过构建,但会先读取已有 `dist/manifest.json.version`,再调用版本预检接口。
|
|
148
|
-
7.
|
|
149
|
-
8.
|
|
150
|
-
9.
|
|
151
|
-
10.
|
|
152
|
-
11.
|
|
153
|
-
12.
|
|
154
|
-
13.
|
|
149
|
+
7. `--from-version <version>` 跳过本地构建、`dist/` 读取和上传,复用指定历史版本产物提交审核;它与 `--skip-build` 互斥。
|
|
150
|
+
8. 解析 `dist/manifest.json`,自动剥离 BOM,并校验 `version` 是合法 SemVer:允许 prerelease,例如 `1.2.3-rc.1`;拒绝 build metadata,例如 `1.2.3+build.1`;拒绝 `0.0.0`。
|
|
151
|
+
9. 普通 remote deploy 的 `dist/manifest.json.version` 必须与预检使用的 `package.json.version` 一致,否则失败且不上传。
|
|
152
|
+
10. 遍历 `dist/` 文件,过滤掉 `manifest.json`、`.DS_Store`、`*.map`;遇到 symbolic link 或 `node_modules` 路径直接报错。
|
|
153
|
+
11. 校验上传路径长度不超过 64,并在任何上传请求发生前限制实际上传产物总大小不超过 100MiB。错误提示中使用 `100MB`,方便开发者理解。
|
|
154
|
+
12. 上传信息、上传凭证和上传回调按批次执行,每批最多 50 个文件;批次串行,批内保持 4 并发上传到 CDN。CLI 会校验 CDN 上传信息接口返回的 key 与本地期望 key 完全一致,异常时停止后续批次且不提交审核。
|
|
155
|
+
13. 默认只展示上传阶段和文件总数,例如 `正在上传 137/244 个文件`;`--verbose` 会展示并发数、批次数、当前批次、bucket / region 和逐文件结果,但不会输出 keys、签名、cookie、pkey、token 或临时密钥。
|
|
156
|
+
14. 全部上传成功后调用提交审核接口;`--from-version` 路径会直接提交 `source_version`。CLI 输出提交审核成功、发布策略和可用的 preview URL。
|
|
155
157
|
|
|
156
158
|
`mini_program_id` 没有 CLI flag,必须落在 `package.json` 里:
|
|
157
159
|
|
|
@@ -176,6 +178,7 @@ Before precheck, build, upload, or submit audit, `hb-sdk remote deploy` must ver
|
|
|
176
178
|
Agent rules:
|
|
177
179
|
|
|
178
180
|
- Use `hb-sdk remote deploy --release-note <text>` for normal build, upload, and submit-audit flows.
|
|
181
|
+
- Use `hb-sdk remote deploy --from-version <version> --release-note <text>` to reuse a remote history artifact. Do not combine `--from-version` with `--skip-build`.
|
|
179
182
|
- Verify remote deploy guidance says current-entity mismatch fails before precheck/build/upload/submit and never auto-switches the developer entity.
|
|
180
183
|
- Never recommend top-level `hb-sdk deploy`; it has been removed rather than retained as a compatibility alias.
|
|
181
184
|
- 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.
|
|
@@ -35,6 +35,7 @@ This site documents the iframe-side SDK for external mini programs. For AI retri
|
|
|
35
35
|
- [错误处理](./llms/guide/error-handling.md): SDK 对外抛出的标准错误类型是 `HbMiniProgramSDKError`。
|
|
36
36
|
- [安装与运行环境](./llms/guide/installation.md): 如果工坊小程序只是普通展示页面,不调用黑盒开放能力,也不监听 SDK 生命周期事件,可以不安装、不引用、不初始化 `@heybox/hb-sdk`。父容器仍可能在 URL 上注入 `hb_mini_bridge_nonce`,业务页可以直接忽略。
|
|
37
37
|
- [事件与生命周期](./llms/guide/lifecycle.md): SDK 通过 `on` 监听父容器派发的小程序生命周期和业务事件。
|
|
38
|
+
- [小程序工坊上架规则 v2(试行)](./llms/guide/mini-program-publishing-rules.md): 本规则用于说明小程序工坊的小程序发布、上架和持续在线要求。通过审核不等于获得推荐或公开展示;工坊广场、推荐位、搜索等流量分发规则另行制定。
|
|
38
39
|
- [快速开始](./llms/guide/quick-start.md): 如果页面不需要黑盒开放能力,可以不接入 SDK。这是一条需要用户能力时的最短接入路径:等待 SDK 完成握手,然后读取当前用户登录态。
|
|
39
40
|
## Recipes
|
|
40
41
|
- [独立 SDK 实例](./llms/recipes/custom-instance.md): 大多数业务页使用默认单例即可。只有在需要隔离上下文时,再创建独立实例。
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Buffer } from 'node:buffer';
|
|
3
|
+
import { promises as fs } from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
|
+
import { HB_SDK_PACKAGE_NAME } from './skill-metadata.mjs';
|
|
7
|
+
|
|
8
|
+
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const HB_SDK_ROOT = path.resolve(SCRIPT_DIR, '../..');
|
|
10
|
+
const REPO_ROOT = path.resolve(HB_SDK_ROOT, '../..');
|
|
11
|
+
const WELL_KNOWN_ROOT = path.join('.well-known', 'agent-skills');
|
|
12
|
+
const AGENT_SKILL_PACKAGES = [
|
|
13
|
+
{
|
|
14
|
+
packageName: HB_SDK_PACKAGE_NAME,
|
|
15
|
+
skillDir: 'skill',
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n?/;
|
|
20
|
+
const TEXT_FILE_RE = /\.(?:md|mjs|js|cjs|ts|tsx|json|txt|sh|yaml|yml)$/i;
|
|
21
|
+
const PREFERRED_ORDER = new Map([
|
|
22
|
+
['SKILL.md', 0],
|
|
23
|
+
['skill.json', 1],
|
|
24
|
+
['references/api-root.md', 100],
|
|
25
|
+
['references/api-protocol.md', 101],
|
|
26
|
+
['references/cli.md', 102],
|
|
27
|
+
['references/recipes.md', 103],
|
|
28
|
+
['references/safety-boundaries.md', 104],
|
|
29
|
+
['references/llms-index.md', 105],
|
|
30
|
+
['references/examples.md', 106],
|
|
31
|
+
['references/smoke-evaluation.md', 107],
|
|
32
|
+
['scripts/sync-references.mjs', 200],
|
|
33
|
+
['scripts/check-references.mjs', 201],
|
|
34
|
+
['scripts/validate-skill.mjs', 202],
|
|
35
|
+
['scripts/package-skill.mjs', 203],
|
|
36
|
+
['scripts/package-skill.sh', 204],
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
function parseCliArgs(argv) {
|
|
40
|
+
const args = argv.slice(2);
|
|
41
|
+
let outDir = path.resolve(process.cwd(), '.agent-skills-payload');
|
|
42
|
+
let check = false;
|
|
43
|
+
|
|
44
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
45
|
+
const arg = args[index];
|
|
46
|
+
if (arg === '--check') {
|
|
47
|
+
check = true;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (arg === '--out-dir') {
|
|
51
|
+
const value = args[index + 1];
|
|
52
|
+
if (!value) {
|
|
53
|
+
throw new Error('--out-dir requires a path argument');
|
|
54
|
+
}
|
|
55
|
+
outDir = path.resolve(process.cwd(), value);
|
|
56
|
+
index += 1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { outDir, check };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function toPosixPath(value) {
|
|
64
|
+
return value.split(path.sep).join('/');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function assertSafeRelativePath(relativePath, context) {
|
|
68
|
+
const normalized = path.posix.normalize(relativePath);
|
|
69
|
+
|
|
70
|
+
if (path.isAbsolute(relativePath) || normalized.startsWith('../') || normalized === '..') {
|
|
71
|
+
throw new Error(`${context} has unsafe path: ${relativePath}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (normalized !== relativePath) {
|
|
75
|
+
throw new Error(`${context} must be normalized: ${relativePath}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (relativePath.includes('/../') || relativePath.endsWith('/..')) {
|
|
79
|
+
throw new Error(`${context} cannot contain parent traversal: ${relativePath}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (/\.zip$/i.test(relativePath)) {
|
|
83
|
+
throw new Error(`${context} must not include zip archives: ${relativePath}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function parseFrontmatter(skillText, skillPath) {
|
|
88
|
+
const match = skillText.match(FRONTMATTER_RE);
|
|
89
|
+
if (!match) {
|
|
90
|
+
throw new Error(`${skillPath} is missing YAML frontmatter`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const metadata = {};
|
|
94
|
+
for (const rawLine of match[1].split('\n')) {
|
|
95
|
+
const line = rawLine.trim();
|
|
96
|
+
if (!line || line.startsWith('#') || line.startsWith('metadata:')) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const keyValue = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
101
|
+
if (!keyValue) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const [, key, rawValue] = keyValue;
|
|
106
|
+
metadata[key] = rawValue.replace(/^['"]|['"]$/g, '').trim();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return metadata;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function exists(filePath) {
|
|
113
|
+
try {
|
|
114
|
+
await fs.access(filePath);
|
|
115
|
+
return true;
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function readJsonFile(filePath) {
|
|
122
|
+
return JSON.parse(await fs.readFile(filePath, 'utf8'));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function resolvePackageRoot(packageSource) {
|
|
126
|
+
if (packageSource.packageName !== HB_SDK_PACKAGE_NAME) {
|
|
127
|
+
throw new Error(`Unsupported agent skill package: ${packageSource.packageName}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!(await exists(path.join(HB_SDK_ROOT, 'package.json')))) {
|
|
131
|
+
throw new Error(`Cannot resolve ${packageSource.packageName}: missing package root at ${toPosixPath(HB_SDK_ROOT)}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return HB_SDK_ROOT;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function listFilesRecursive(rootDir, relativeBase = '', options = {}) {
|
|
138
|
+
if (!(await exists(rootDir))) {
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const entries = await fs.readdir(rootDir, { withFileTypes: true });
|
|
143
|
+
const files = [];
|
|
144
|
+
|
|
145
|
+
for (const entry of entries) {
|
|
146
|
+
if (!options.includeHidden && entry.name.startsWith('.')) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const absolutePath = path.join(rootDir, entry.name);
|
|
151
|
+
const relativePath = path.posix.join(relativeBase, entry.name);
|
|
152
|
+
|
|
153
|
+
if (entry.isDirectory()) {
|
|
154
|
+
files.push(...(await listFilesRecursive(absolutePath, relativePath, options)));
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (entry.isFile()) {
|
|
159
|
+
files.push(relativePath);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return files;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function sortSkillFiles(files) {
|
|
167
|
+
return [...files].sort((left, right) => {
|
|
168
|
+
const leftOrder = PREFERRED_ORDER.get(left) ?? 10_000;
|
|
169
|
+
const rightOrder = PREFERRED_ORDER.get(right) ?? 10_000;
|
|
170
|
+
return leftOrder - rightOrder || left.localeCompare(right);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function discoverSkill(packageSource) {
|
|
175
|
+
const packageRoot = await resolvePackageRoot(packageSource);
|
|
176
|
+
const skillDir = path.join(packageRoot, packageSource.skillDir);
|
|
177
|
+
const skillMarkdownPath = path.join(skillDir, 'SKILL.md');
|
|
178
|
+
|
|
179
|
+
if (!(await exists(skillMarkdownPath))) {
|
|
180
|
+
throw new Error(`${packageSource.packageName} must provide ${packageSource.skillDir}/SKILL.md.`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const skillMarkdown = await fs.readFile(skillMarkdownPath, 'utf8');
|
|
184
|
+
const frontmatter = parseFrontmatter(skillMarkdown, skillMarkdownPath);
|
|
185
|
+
const skillName = frontmatter.name;
|
|
186
|
+
|
|
187
|
+
if (!skillName) {
|
|
188
|
+
throw new Error(`${skillMarkdownPath} frontmatter must include name`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!frontmatter.description) {
|
|
192
|
+
throw new Error(`${skillMarkdownPath} frontmatter must include description`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const files = ['SKILL.md'];
|
|
196
|
+
const skillJsonPath = path.join(skillDir, 'skill.json');
|
|
197
|
+
let metadata = null;
|
|
198
|
+
|
|
199
|
+
if (await exists(skillJsonPath)) {
|
|
200
|
+
const relativeFile = 'skill.json';
|
|
201
|
+
assertSafeRelativePath(relativeFile, `${skillName} source file`);
|
|
202
|
+
files.push(relativeFile);
|
|
203
|
+
metadata = await readJsonFile(skillJsonPath);
|
|
204
|
+
if (metadata.name !== skillName) {
|
|
205
|
+
throw new Error(`${skillJsonPath} name (${metadata.name}) must match SKILL.md frontmatter (${skillName})`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
for (const topLevelDir of ['references', 'scripts', 'assets']) {
|
|
210
|
+
const nestedFiles = await listFilesRecursive(path.join(skillDir, topLevelDir), topLevelDir);
|
|
211
|
+
for (const relativeFile of nestedFiles) {
|
|
212
|
+
if (!TEXT_FILE_RE.test(relativeFile)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
assertSafeRelativePath(relativeFile, `${skillName} source file`);
|
|
216
|
+
files.push(relativeFile);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
sourceDir: skillDir,
|
|
222
|
+
name: skillName,
|
|
223
|
+
description: frontmatter.description,
|
|
224
|
+
files: sortSkillFiles(files),
|
|
225
|
+
metadata,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function discoverSkills() {
|
|
230
|
+
const skills = [];
|
|
231
|
+
|
|
232
|
+
for (const packageSource of AGENT_SKILL_PACKAGES) {
|
|
233
|
+
skills.push(await discoverSkill(packageSource));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (skills.length === 0) {
|
|
237
|
+
throw new Error('No configured agent skills found.');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return skills;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function createSkillIndex(skills) {
|
|
244
|
+
return {
|
|
245
|
+
skills: skills.map((skill) => ({
|
|
246
|
+
name: skill.name,
|
|
247
|
+
description: skill.description,
|
|
248
|
+
...(skill.metadata
|
|
249
|
+
? {
|
|
250
|
+
version: skill.metadata.skillVersion,
|
|
251
|
+
sdk: skill.metadata.sdk,
|
|
252
|
+
source: skill.metadata.source,
|
|
253
|
+
integrity: skill.metadata.integrity,
|
|
254
|
+
}
|
|
255
|
+
: {}),
|
|
256
|
+
files: skill.files,
|
|
257
|
+
})),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async function addIndexFile(outputFiles, baseDir, skills) {
|
|
262
|
+
const indexPath = path.join(baseDir, WELL_KNOWN_ROOT, 'index.json');
|
|
263
|
+
const index = createSkillIndex(skills);
|
|
264
|
+
|
|
265
|
+
outputFiles.set(indexPath, Buffer.from(`${JSON.stringify(index, null, 2)}\n`, 'utf8'));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function addSkillFiles(outputFiles, baseDir, skills) {
|
|
269
|
+
for (const skill of skills) {
|
|
270
|
+
for (const relativeFile of skill.files) {
|
|
271
|
+
assertSafeRelativePath(relativeFile, `${skill.name} generated file`);
|
|
272
|
+
const sourcePath = path.join(skill.sourceDir, ...relativeFile.split('/'));
|
|
273
|
+
const targetPath = path.join(baseDir, WELL_KNOWN_ROOT, skill.name, ...relativeFile.split('/'));
|
|
274
|
+
outputFiles.set(targetPath, await fs.readFile(sourcePath));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async function buildExpectedOutput(skills, targetRoot) {
|
|
280
|
+
const outputFiles = new Map();
|
|
281
|
+
|
|
282
|
+
await addIndexFile(outputFiles, targetRoot, skills);
|
|
283
|
+
await addSkillFiles(outputFiles, targetRoot, skills);
|
|
284
|
+
|
|
285
|
+
return outputFiles;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async function listExistingGeneratedFiles(targetRoot) {
|
|
289
|
+
if (!(await exists(targetRoot))) {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const relativeFiles = await listFilesRecursive(targetRoot, '', { includeHidden: true });
|
|
294
|
+
return relativeFiles.map((relativeFile) => path.join(targetRoot, ...relativeFile.split('/')));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async function syncFiles(expectedOutput, targetRoot) {
|
|
298
|
+
await fs.rm(targetRoot, { recursive: true, force: true });
|
|
299
|
+
|
|
300
|
+
for (const [targetPath, content] of [...expectedOutput.entries()].sort(([left], [right]) => left.localeCompare(right))) {
|
|
301
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
302
|
+
await fs.writeFile(targetPath, content);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async function checkFiles(expectedOutput, targetRoot) {
|
|
307
|
+
const expectedPaths = new Set(expectedOutput.keys());
|
|
308
|
+
const existingPaths = new Set(await listExistingGeneratedFiles(targetRoot));
|
|
309
|
+
const problems = [];
|
|
310
|
+
|
|
311
|
+
for (const expectedPath of [...expectedPaths].sort()) {
|
|
312
|
+
if (!existingPaths.has(expectedPath)) {
|
|
313
|
+
problems.push(`missing ${path.relative(REPO_ROOT, expectedPath)}`);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const actual = await fs.readFile(expectedPath);
|
|
318
|
+
const expected = expectedOutput.get(expectedPath);
|
|
319
|
+
if (!actual.equals(expected)) {
|
|
320
|
+
problems.push(`stale ${path.relative(REPO_ROOT, expectedPath)}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
for (const existingPath of [...existingPaths].sort()) {
|
|
325
|
+
if (!expectedPaths.has(existingPath)) {
|
|
326
|
+
problems.push(`extra ${path.relative(REPO_ROOT, existingPath)}`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (problems.length > 0) {
|
|
331
|
+
throw new Error(`Agent skills payload is out of sync:\n${problems.map((problem) => `- ${problem}`).join('\n')}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
async function main() {
|
|
336
|
+
const { outDir, check } = parseCliArgs(process.argv);
|
|
337
|
+
const skills = await discoverSkills();
|
|
338
|
+
const expectedOutput = await buildExpectedOutput(skills, outDir);
|
|
339
|
+
|
|
340
|
+
if (check) {
|
|
341
|
+
await checkFiles(expectedOutput, outDir);
|
|
342
|
+
console.log(
|
|
343
|
+
`Agent skills payload is in sync at ${toPosixPath(path.relative(REPO_ROOT, outDir))} (${expectedOutput.size} files, ${skills.length} skills).`,
|
|
344
|
+
);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
await syncFiles(expectedOutput, outDir);
|
|
349
|
+
console.log(
|
|
350
|
+
`Synced ${skills.length} skills to ${toPosixPath(path.relative(REPO_ROOT, outDir))} (${expectedOutput.size} files).`,
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
355
|
+
main().catch((error) => {
|
|
356
|
+
console.error(error.message);
|
|
357
|
+
process.exitCode = 1;
|
|
358
|
+
});
|
|
359
|
+
}
|
|
@@ -225,7 +225,7 @@ hb-sdk remote allowlist list
|
|
|
225
225
|
hb-sdk remote allowlist add <heybox-id...>
|
|
226
226
|
hb-sdk remote allowlist remove <heybox-id...>
|
|
227
227
|
hb-sdk remote allowlist set <heybox-id...>
|
|
228
|
-
hb-sdk remote deploy --release-note <text> [--skip-build] [--auto-publish]
|
|
228
|
+
hb-sdk remote deploy --release-note <text> [--skip-build | --from-version <version>] [--auto-publish]
|
|
229
229
|
hb-sdk remote versions
|
|
230
230
|
hb-sdk remote preview <version>
|
|
231
231
|
hb-sdk remote release <version> [--yes]
|
|
@@ -385,6 +385,7 @@ ${cliRemoteEntityDeploySection}
|
|
|
385
385
|
Agent rules:
|
|
386
386
|
|
|
387
387
|
- Use \`hb-sdk remote deploy --release-note <text>\` for normal build, upload, and submit-audit flows.
|
|
388
|
+
- Use \`hb-sdk remote deploy --from-version <version> --release-note <text>\` to reuse a remote history artifact. Do not combine \`--from-version\` with \`--skip-build\`.
|
|
388
389
|
- Verify remote deploy guidance says current-entity mismatch fails before precheck/build/upload/submit and never auto-switches the developer entity.
|
|
389
390
|
- Never recommend top-level \`hb-sdk deploy\`; it has been removed rather than retained as a compatibility alias.
|
|
390
391
|
- 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.
|
package/skill/skill.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hb-sdk",
|
|
3
|
-
"skillVersion": "0.5.
|
|
3
|
+
"skillVersion": "0.5.9+skill.02be68ce07ce",
|
|
4
4
|
"sdk": {
|
|
5
5
|
"package": "@heybox/hb-sdk",
|
|
6
|
-
"version": "0.5.
|
|
7
|
-
"compatibility": "0.5.
|
|
6
|
+
"version": "0.5.9",
|
|
7
|
+
"compatibility": "0.5.9"
|
|
8
8
|
},
|
|
9
9
|
"source": "https://open.xiaoheihe.cn/agent-skills/hb-sdk",
|
|
10
|
-
"integrity": "sha256-
|
|
10
|
+
"integrity": "sha256-02be68ce07ce1cf0ecba354d764a47977e4fc3c189b5e4aed3cee1f844fddfd4"
|
|
11
11
|
}
|