@heybox/hb-sdk 0.8.1-alpha.2 → 0.8.1-alpha.6
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/CHANGELOG.md +41 -0
- package/README.md +58 -4
- package/dist/cli-chunks/{build-FQoALfGC.cjs → build-B0X9pazW.cjs} +16 -10
- package/dist/cli-chunks/{context-CA_Q1lyH.cjs → context-DVfWZ6d1.cjs} +8 -3
- package/dist/cli-chunks/{create-BjIl4hy4.cjs → create-CyQWVxCA.cjs} +1 -1
- package/dist/cli-chunks/{dev-CiPQYsW_.cjs → dev-DP7WtQOo.cjs} +465 -117
- package/dist/cli-chunks/{doctor-CS6c3n-W.cjs → doctor-D6l-ONq-.cjs} +1 -1
- package/dist/cli-chunks/{index-BEn7WaqA.cjs → index-CDwwaNvP.cjs} +87 -15
- package/dist/cli-chunks/{index-CsP_x6y6.cjs → index-DvOPzPxS.cjs} +2 -2
- package/dist/cli-chunks/{index.esm-DeEc_-uV.cjs → index.esm-B8pX0BrZ.cjs} +9 -8
- package/dist/cli-chunks/{login-BENCVgaQ.cjs → login-Dt-FHzpL.cjs} +2 -2
- package/dist/cli-chunks/{project-vite-BO8oOfcs.cjs → project-vite-CE7kyqxl.cjs} +1 -1
- package/dist/cli-chunks/{remote-IiVCXcSq.cjs → remote-Be6PeR-n.cjs} +41 -28
- package/dist/cli-chunks/{runtime-gate-BMSY22AL.cjs → runtime-gate-BWb8QIcX.cjs} +0 -107
- package/dist/cli-chunks/{runtime-permission-env-BPRwn4Yc.cjs → runtime-permission-env-DWSscWBT.cjs} +304 -23
- package/dist/cli-chunks/{session-C0eIKZ6V.cjs → session-DZXRQ4Dp.cjs} +1 -1
- package/dist/cli-chunks/{skill-DpInwbiA.cjs → skill-B8GWL2KT.cjs} +83 -27
- package/dist/cli-chunks/{version-BONZQWPR.cjs → version-D19lZmYN.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/browser-dev-host/assets/browser-dev-host-Bb43BPMS.js +101 -0
- package/dist/devtools/browser-dev-host/assets/desktop-app-launch-DnPRjCa3.js +6 -0
- package/dist/devtools/browser-dev-host/assets/index-D-aNERAr.css +1 -0
- package/dist/devtools/browser-dev-host/assets/index-Dh5wRj5c.js +567 -0
- package/dist/devtools/browser-dev-host/index.html +3 -3
- package/dist/index.cjs.js +1893 -1562
- package/dist/index.esm.js +1893 -1563
- package/dist/miniapp-publish.cjs.js +61 -0
- package/dist/miniapp-publish.esm.js +59 -1
- package/dist/protocol.cjs.js +64 -13
- package/dist/protocol.esm.js +64 -13
- package/dist/templates/vanilla-vite-js/README.md.ejs +1 -1
- package/dist/templates/vanilla-vite-js/package.json.ejs +1 -0
- package/dist/templates/vanilla-vite-js/vite.config.js +1 -1
- package/dist/vite.cjs.js +1333 -18
- package/dist/vite.esm.js +1334 -20
- package/package.json +8 -8
- package/skill/SKILL.md +10 -5
- package/skill/references/api-protocol.md +3 -3
- package/skill/references/api-root.md +225 -210
- package/skill/references/cli.md +9 -3
- package/skill/references/examples.md +13 -1
- package/skill/references/recipes.md +161 -0
- package/skill/references/safety-boundaries.md +7 -1
- package/skill/skill.json +5 -5
- package/types/core/client.d.ts +2 -0
- package/types/core/sdk.d.ts +3 -0
- package/types/core/singleton.d.ts +3 -0
- package/types/devtools/device-logs.d.ts +48 -0
- package/types/index.d.ts +3 -1
- package/types/miniapp-manifest/companion-directory.d.ts +2 -0
- package/types/miniapp-manifest/companion-executable.d.ts +4 -0
- package/types/miniapp-manifest/companion-types.d.ts +38 -0
- package/types/miniapp-manifest/companions.d.ts +17 -0
- package/types/miniapp-manifest/index.d.ts +2 -0
- package/types/miniapp-manifest/node.d.ts +9 -0
- package/types/miniapp-manifest/permissions.d.ts +1 -1
- package/types/miniapp-manifest/schema.d.ts +5 -1
- package/types/miniapp-publish/index.d.ts +17 -2
- package/types/modules/companion/index.d.ts +57 -0
- package/types/protocol/dev-session.d.ts +6 -0
- package/types/vite/index.d.ts +11 -4
- package/dist/devtools/browser-dev-host/assets/browser-dev-host-DzEst9n7.js +0 -99
- package/dist/devtools/browser-dev-host/assets/index-B-NHlLsr.js +0 -567
- package/dist/devtools/browser-dev-host/assets/index-P-ra4m1y.css +0 -1
- package/dist/devtools/browser-dev-host/assets/workbench-state-BwV7bm4n.js +0 -5
package/dist/cli-chunks/{runtime-permission-env-BPRwn4Yc.cjs → runtime-permission-env-DWSscWBT.cjs}
RENAMED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('node:fs');
|
|
4
4
|
var path = require('node:path');
|
|
5
|
-
var version = require('./version-
|
|
5
|
+
var version = require('./version-D19lZmYN.cjs');
|
|
6
|
+
require('node:crypto');
|
|
6
7
|
var node_async_hooks = require('node:async_hooks');
|
|
7
8
|
|
|
8
9
|
var re = {exports: {}};
|
|
@@ -2799,6 +2800,7 @@ const MINI_PROGRAM_PERMISSION_KEYS = [
|
|
|
2799
2800
|
'clipboard',
|
|
2800
2801
|
'leaderboard',
|
|
2801
2802
|
'network',
|
|
2803
|
+
'companion',
|
|
2802
2804
|
];
|
|
2803
2805
|
const MINI_PROGRAM_PERMISSION_CATALOG = [
|
|
2804
2806
|
{
|
|
@@ -2911,6 +2913,29 @@ const MINI_PROGRAM_PERMISSION_CATALOG = [
|
|
|
2911
2913
|
methods: ['network.request', 'network.download'],
|
|
2912
2914
|
conditions: ['声明后仍需平台批准,并继续执行网络安全策略。'],
|
|
2913
2915
|
},
|
|
2916
|
+
{
|
|
2917
|
+
key: 'companion',
|
|
2918
|
+
name: '桌面辅助应用',
|
|
2919
|
+
description: '下载、准备并运行随当前小程序版本发布的受管桌面程序。',
|
|
2920
|
+
access: 'platform-approval',
|
|
2921
|
+
risk: 'high',
|
|
2922
|
+
config: {},
|
|
2923
|
+
methods: [
|
|
2924
|
+
'companion.getInfo',
|
|
2925
|
+
'companion.getPreparationStatus',
|
|
2926
|
+
'companion.prepare',
|
|
2927
|
+
'companion.cancelPreparation',
|
|
2928
|
+
'companion.getActiveSession',
|
|
2929
|
+
'companion.launch',
|
|
2930
|
+
'companion.session.write',
|
|
2931
|
+
'companion.session.closeStdin',
|
|
2932
|
+
'companion.session.terminate',
|
|
2933
|
+
'companion.session.ackOutput',
|
|
2934
|
+
'companion.openAttachment',
|
|
2935
|
+
'companion.showNotification',
|
|
2936
|
+
],
|
|
2937
|
+
conditions: ['声明后仍需平台批准,并继续执行可信用户手势、Host 能力和当前版本 Manifest 校验。'],
|
|
2938
|
+
},
|
|
2914
2939
|
];
|
|
2915
2940
|
new Set(MINI_PROGRAM_PERMISSION_KEYS);
|
|
2916
2941
|
|
|
@@ -2919,7 +2944,7 @@ function isManagedMiniProgramRuntimePermissionKey(key) {
|
|
|
2919
2944
|
return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
|
|
2920
2945
|
}
|
|
2921
2946
|
function parseMiniProgramRuntimePermissions(snapshot) {
|
|
2922
|
-
if (!isRecord$
|
|
2947
|
+
if (!isRecord$4(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
|
|
2923
2948
|
return { valid: false, permissions: {} };
|
|
2924
2949
|
}
|
|
2925
2950
|
if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
|
|
@@ -2928,7 +2953,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
2928
2953
|
const seenKeys = new Set();
|
|
2929
2954
|
const permissions = {};
|
|
2930
2955
|
for (const rawEntry of snapshot.entries) {
|
|
2931
|
-
if (!isRecord$
|
|
2956
|
+
if (!isRecord$4(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
|
|
2932
2957
|
return { valid: false, permissions: {} };
|
|
2933
2958
|
}
|
|
2934
2959
|
const inputKey = rawEntry.key.trim();
|
|
@@ -2938,13 +2963,13 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
2938
2963
|
}
|
|
2939
2964
|
seenKeys.add(key);
|
|
2940
2965
|
if (!isManagedMiniProgramRuntimePermissionKey(key)) {
|
|
2941
|
-
|
|
2942
|
-
|
|
2966
|
+
// 未知权限必须忽略,不能让 config:null / 缺字段把已认识的批准一起否掉。
|
|
2967
|
+
// 服务端会对无 config 的 message 字段输出 null(Rylai EmitUnpopulated)。
|
|
2943
2968
|
continue;
|
|
2944
2969
|
}
|
|
2945
2970
|
if (key === 'network') {
|
|
2946
2971
|
const config = rawEntry.config;
|
|
2947
|
-
if (!isRecord$
|
|
2972
|
+
if (!isRecord$4(config) || typeof config.useOfficialDomain !== 'boolean') {
|
|
2948
2973
|
return { valid: false, permissions: {} };
|
|
2949
2974
|
}
|
|
2950
2975
|
permissions[key] = {
|
|
@@ -2954,7 +2979,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
2954
2979
|
};
|
|
2955
2980
|
continue;
|
|
2956
2981
|
}
|
|
2957
|
-
if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord$
|
|
2982
|
+
if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord$4(rawEntry.config) || Object.keys(rawEntry.config).length > 0)) {
|
|
2958
2983
|
return { valid: false, permissions: {} };
|
|
2959
2984
|
}
|
|
2960
2985
|
permissions[key] = {
|
|
@@ -2965,7 +2990,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
2965
2990
|
}
|
|
2966
2991
|
return { valid: true, permissions };
|
|
2967
2992
|
}
|
|
2968
|
-
function isRecord$
|
|
2993
|
+
function isRecord$4(value) {
|
|
2969
2994
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
2970
2995
|
}
|
|
2971
2996
|
|
|
@@ -2978,7 +3003,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
2978
3003
|
}
|
|
2979
3004
|
return { declared: false };
|
|
2980
3005
|
}
|
|
2981
|
-
if (!isRecord$
|
|
3006
|
+
if (!isRecord$3(value)) {
|
|
2982
3007
|
throw new Error(`${sourceLabel} 必须是 JSON 对象`);
|
|
2983
3008
|
}
|
|
2984
3009
|
const knownKeys = new Set(MINIAPP_PERMISSION_KEYS);
|
|
@@ -2992,7 +3017,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
2992
3017
|
continue;
|
|
2993
3018
|
const declaration = value[key];
|
|
2994
3019
|
const itemLabel = `${sourceLabel}.${key}`;
|
|
2995
|
-
if (!isRecord$
|
|
3020
|
+
if (!isRecord$3(declaration))
|
|
2996
3021
|
throw new Error(`${itemLabel} 必须是 JSON 对象`);
|
|
2997
3022
|
const definition = MINI_PROGRAM_PERMISSION_CATALOG.find((item) => item.key === key);
|
|
2998
3023
|
if (!definition)
|
|
@@ -3028,7 +3053,7 @@ function getMissingPermissionsWarning(sourceLabel = 'package.json#heybox.permiss
|
|
|
3028
3053
|
}
|
|
3029
3054
|
function composeMiniappRuntimePermissions(local, approvals) {
|
|
3030
3055
|
const parsedApprovals = parseMiniProgramRuntimePermissions(approvals);
|
|
3031
|
-
const approvalRevision = isRecord$
|
|
3056
|
+
const approvalRevision = isRecord$3(approvals) && Number.isInteger(approvals.revision) ? approvals.revision : undefined;
|
|
3032
3057
|
const views = [];
|
|
3033
3058
|
const entries = [];
|
|
3034
3059
|
for (const definition of MINI_PROGRAM_PERMISSION_CATALOG) {
|
|
@@ -3042,9 +3067,22 @@ function composeMiniappRuntimePermissions(local, approvals) {
|
|
|
3042
3067
|
}
|
|
3043
3068
|
const approval = parsedApprovals.valid ? parsedApprovals.permissions[definition.key] : undefined;
|
|
3044
3069
|
const approved = approval?.status === 'enabled';
|
|
3070
|
+
const effective = declared && approved;
|
|
3071
|
+
if (definition.key !== 'network') {
|
|
3072
|
+
views.push({
|
|
3073
|
+
key: definition.key,
|
|
3074
|
+
access: definition.access,
|
|
3075
|
+
declared,
|
|
3076
|
+
approved,
|
|
3077
|
+
effective,
|
|
3078
|
+
});
|
|
3079
|
+
if (declared) {
|
|
3080
|
+
entries.push({ key: definition.key, status: effective ? 'enabled' : 'disabled', config: {} });
|
|
3081
|
+
}
|
|
3082
|
+
continue;
|
|
3083
|
+
}
|
|
3045
3084
|
const requestedOfficialDomain = declaration?.enabled === true && 'useOfficialDomain' in declaration && declaration.useOfficialDomain;
|
|
3046
3085
|
const approvedOfficialDomain = approval?.config.useOfficialDomain === true;
|
|
3047
|
-
const effective = declared && approved;
|
|
3048
3086
|
const effectiveOfficialDomain = effective && (local.declared ? requestedOfficialDomain : true) && approvedOfficialDomain;
|
|
3049
3087
|
views.push({
|
|
3050
3088
|
key: definition.key,
|
|
@@ -3065,14 +3103,180 @@ function composeMiniappRuntimePermissions(local, approvals) {
|
|
|
3065
3103
|
views,
|
|
3066
3104
|
};
|
|
3067
3105
|
}
|
|
3068
|
-
function isRecord$
|
|
3106
|
+
function isRecord$3(value) {
|
|
3069
3107
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3070
3108
|
}
|
|
3071
3109
|
|
|
3110
|
+
const MINIAPP_PLATFORM_VALUES = ['android', 'ios', 'ohos', 'windows', 'macos', 'linux'];
|
|
3111
|
+
function isValidMiniappManifestVersion(version) {
|
|
3112
|
+
return getMiniappManifestVersionError(version) === undefined;
|
|
3113
|
+
}
|
|
3114
|
+
function validateMiniappManifestVersion(version, sourceLabel = 'manifest.version') {
|
|
3115
|
+
const error = getMiniappManifestVersionError(version);
|
|
3116
|
+
if (error) {
|
|
3117
|
+
throw new Error(`${sourceLabel} ${error}`);
|
|
3118
|
+
}
|
|
3119
|
+
return String(version).trim();
|
|
3120
|
+
}
|
|
3121
|
+
function parseMiniappManifestJson(raw, sourceLabel = 'manifest.json') {
|
|
3122
|
+
const hadBom = raw.charCodeAt(0) === 0xfeff;
|
|
3123
|
+
const text = hadBom ? raw.slice(1) : raw;
|
|
3124
|
+
let parsed;
|
|
3125
|
+
try {
|
|
3126
|
+
parsed = JSON.parse(text);
|
|
3127
|
+
}
|
|
3128
|
+
catch (error) {
|
|
3129
|
+
throw new Error(`${sourceLabel} 不是合法 JSON:${formatReason$1(error)}`);
|
|
3130
|
+
}
|
|
3131
|
+
if (!isManifestRecord(parsed)) {
|
|
3132
|
+
throw new Error(`${sourceLabel} 必须是 JSON 对象`);
|
|
3133
|
+
}
|
|
3134
|
+
return {
|
|
3135
|
+
manifest: parsed,
|
|
3136
|
+
hadBom,
|
|
3137
|
+
};
|
|
3138
|
+
}
|
|
3139
|
+
function validateMiniappManifestForDeploy(manifest) {
|
|
3140
|
+
const version = validateMiniappManifestVersion(manifest.version, 'manifest.version');
|
|
3141
|
+
const sdkVersion = validateSdkVersion(manifest.sdkVersion, 'manifest.sdkVersion');
|
|
3142
|
+
const permissions = parseMiniappPermissions(manifest.permissions, {
|
|
3143
|
+
present: Object.prototype.hasOwnProperty.call(manifest, 'permissions'),
|
|
3144
|
+
sdkVersion,
|
|
3145
|
+
sourceLabel: 'manifest.permissions',
|
|
3146
|
+
});
|
|
3147
|
+
const companions = validateGeneratedCompanions(manifest.companions);
|
|
3148
|
+
return {
|
|
3149
|
+
version,
|
|
3150
|
+
sdkVersion,
|
|
3151
|
+
platforms: validateMiniappPlatforms(manifest.platforms, 'manifest.platforms'),
|
|
3152
|
+
...(permissions.permissions === undefined ? {} : { permissions: permissions.permissions }),
|
|
3153
|
+
...(companions === undefined ? {} : { companions }),
|
|
3154
|
+
};
|
|
3155
|
+
}
|
|
3156
|
+
function validateGeneratedCompanions(value) {
|
|
3157
|
+
if (value === undefined)
|
|
3158
|
+
return undefined;
|
|
3159
|
+
if (!isRecord$2(value) || Object.keys(value).length === 0)
|
|
3160
|
+
throw new Error('manifest.companions 必须是非空对象');
|
|
3161
|
+
for (const [alias, definition] of Object.entries(value)) {
|
|
3162
|
+
if (!/^[a-z][a-z0-9-]{0,31}$/.test(alias) ||
|
|
3163
|
+
!isRecord$2(definition) ||
|
|
3164
|
+
typeof definition.displayName !== 'string' ||
|
|
3165
|
+
!definition.displayName ||
|
|
3166
|
+
Array.from(definition.displayName).length > 120 ||
|
|
3167
|
+
!Array.isArray(definition.capabilities) ||
|
|
3168
|
+
definition.capabilities.some((capability) => capability !== 'stdio' && capability !== 'attachments' && capability !== 'notifications') ||
|
|
3169
|
+
new Set(definition.capabilities).size !== definition.capabilities.length ||
|
|
3170
|
+
!isRecord$2(definition.targets) ||
|
|
3171
|
+
Object.keys(definition.targets).length === 0)
|
|
3172
|
+
throw new Error(`manifest.companions.${alias} 不合法`);
|
|
3173
|
+
for (const [target, artifact] of Object.entries(definition.targets)) {
|
|
3174
|
+
if (isRecord$2(artifact) && artifact.elevation === 'required') {
|
|
3175
|
+
throw new Error(`manifest.companions.${alias}.targets.${target}.elevation V1 仅支持 none,暂不支持管理员权限启动`);
|
|
3176
|
+
}
|
|
3177
|
+
if ((target !== 'windows-x64' && target !== 'macos-arm64') ||
|
|
3178
|
+
!isRecord$2(artifact) ||
|
|
3179
|
+
artifact.path !== `companions/${alias}/${target}.zip` ||
|
|
3180
|
+
!Number.isSafeInteger(artifact.size) ||
|
|
3181
|
+
Number(artifact.size) <= 0 ||
|
|
3182
|
+
typeof artifact.sha256 !== 'string' ||
|
|
3183
|
+
!/^[a-f0-9]{64}$/.test(artifact.sha256) ||
|
|
3184
|
+
!isRecord$2(artifact.entrypoint) ||
|
|
3185
|
+
(artifact.entrypoint.kind !== 'executable' && artifact.entrypoint.kind !== 'app-bundle') ||
|
|
3186
|
+
typeof artifact.entrypoint.path !== 'string' ||
|
|
3187
|
+
!artifact.entrypoint.path ||
|
|
3188
|
+
artifact.elevation !== 'none' ||
|
|
3189
|
+
!isValidGeneratedCompanionArgs(artifact.args)) {
|
|
3190
|
+
throw new Error(`manifest.companions.${alias}.targets.${target} 不合法`);
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
return value;
|
|
3195
|
+
}
|
|
3196
|
+
function isValidGeneratedCompanionArgs(value) {
|
|
3197
|
+
if (!Array.isArray(value) || value.length > 64)
|
|
3198
|
+
return false;
|
|
3199
|
+
let totalBytes = 0;
|
|
3200
|
+
for (const arg of value) {
|
|
3201
|
+
if (typeof arg !== 'string' || /[\u0000\r\n]/.test(arg))
|
|
3202
|
+
return false;
|
|
3203
|
+
const bytes = Buffer.byteLength(arg, 'utf8');
|
|
3204
|
+
if (bytes > 1024)
|
|
3205
|
+
return false;
|
|
3206
|
+
totalBytes += bytes;
|
|
3207
|
+
}
|
|
3208
|
+
return totalBytes <= 16_384;
|
|
3209
|
+
}
|
|
3210
|
+
function validateMiniappPlatforms(platforms, sourceLabel = 'platforms') {
|
|
3211
|
+
if (!Array.isArray(platforms) || platforms.length === 0) {
|
|
3212
|
+
throw new Error(`${sourceLabel} 必须是非空平台数组`);
|
|
3213
|
+
}
|
|
3214
|
+
const allowedPlatforms = new Set(MINIAPP_PLATFORM_VALUES);
|
|
3215
|
+
const seen = new Set();
|
|
3216
|
+
for (const platform of platforms) {
|
|
3217
|
+
if (typeof platform !== 'string' || !allowedPlatforms.has(platform)) {
|
|
3218
|
+
throw new Error(`${sourceLabel} 包含不支持的平台:${String(platform)}`);
|
|
3219
|
+
}
|
|
3220
|
+
if (seen.has(platform)) {
|
|
3221
|
+
throw new Error(`${sourceLabel} 包含重复平台:${platform}`);
|
|
3222
|
+
}
|
|
3223
|
+
seen.add(platform);
|
|
3224
|
+
}
|
|
3225
|
+
return Object.freeze(MINIAPP_PLATFORM_VALUES.filter((platform) => seen.has(platform)));
|
|
3226
|
+
}
|
|
3227
|
+
function areMiniappPlatformsEqual(left, right) {
|
|
3228
|
+
return left.length === right.length && left.every((platform, index) => platform === right[index]);
|
|
3229
|
+
}
|
|
3230
|
+
function validateSdkVersion(version, sourceLabel = 'sdkVersion') {
|
|
3231
|
+
if (typeof version !== 'string' || version.trim() === '') {
|
|
3232
|
+
throw new Error(`${sourceLabel} 必须是合法 SemVer:${String(version)}`);
|
|
3233
|
+
}
|
|
3234
|
+
const normalized = version.trim();
|
|
3235
|
+
const parsed = semverExports.parse(normalized);
|
|
3236
|
+
if (!parsed || parsed.version !== normalized || parsed.build.length > 0) {
|
|
3237
|
+
throw new Error(`${sourceLabel} 必须是合法 SemVer:${normalized}`);
|
|
3238
|
+
}
|
|
3239
|
+
return normalized;
|
|
3240
|
+
}
|
|
3241
|
+
function isManifestRecord(value) {
|
|
3242
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3243
|
+
}
|
|
3244
|
+
function isRecord$2(value) {
|
|
3245
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3246
|
+
}
|
|
3247
|
+
function getMiniappManifestVersionError(version) {
|
|
3248
|
+
if (typeof version !== 'string' || version.trim() === '') {
|
|
3249
|
+
return `必须是合法 SemVer:${String(version)}`;
|
|
3250
|
+
}
|
|
3251
|
+
const normalized = version.trim();
|
|
3252
|
+
const parsed = semverExports.parse(normalized);
|
|
3253
|
+
if (!parsed) {
|
|
3254
|
+
return `必须是合法 SemVer:${normalized}`;
|
|
3255
|
+
}
|
|
3256
|
+
if (parsed.build.length > 0) {
|
|
3257
|
+
return `不能包含 build metadata:${normalized}`;
|
|
3258
|
+
}
|
|
3259
|
+
if (parsed.version !== normalized) {
|
|
3260
|
+
return `必须是合法 SemVer:${normalized}`;
|
|
3261
|
+
}
|
|
3262
|
+
if (parsed.major === 0 && parsed.minor === 0 && parsed.patch === 0) {
|
|
3263
|
+
return '不能是模板默认版本 0.0.0';
|
|
3264
|
+
}
|
|
3265
|
+
return undefined;
|
|
3266
|
+
}
|
|
3267
|
+
function formatReason$1(error) {
|
|
3268
|
+
if (error instanceof Error && error.message) {
|
|
3269
|
+
return error.message;
|
|
3270
|
+
}
|
|
3271
|
+
return String(error);
|
|
3272
|
+
}
|
|
3273
|
+
|
|
3072
3274
|
const MINIAPP_UPLOAD_SCOPE = 'activity';
|
|
3073
3275
|
const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
|
|
3074
3276
|
const MINIAPP_UPLOAD_BATCH_SIZE = 50;
|
|
3075
3277
|
const MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
|
|
3278
|
+
/** Phase 0 尚未冻结;当前仅作为可单点替换、可测试的保守临时上限。 */
|
|
3279
|
+
const MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES = 2 * 1024 * 1024 * 1024;
|
|
3076
3280
|
const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = '/mall/developer/user_miniprogram/access_status';
|
|
3077
3281
|
const DEVELOPER_ENTITY_LIST_API_PATH = '/mall/developer/entity/list';
|
|
3078
3282
|
const DEVELOPER_ENTITY_SWITCH_API_PATH = '/mall/developer/entity/switch';
|
|
@@ -3132,6 +3336,18 @@ function validateUploadTotalSize(items, options = {}) {
|
|
|
3132
3336
|
}
|
|
3133
3337
|
return undefined;
|
|
3134
3338
|
}
|
|
3339
|
+
function validateMiniappUploadSizeBudgets(items, options = {}) {
|
|
3340
|
+
const companionItems = items.filter((item) => normalizeRelativePath(item.relativePath).startsWith('companions/'));
|
|
3341
|
+
const webItems = items.filter((item) => !normalizeRelativePath(item.relativePath).startsWith('companions/'));
|
|
3342
|
+
const webError = validateUploadTotalSize(webItems, { limitBytes: options.webLimitBytes ?? MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES });
|
|
3343
|
+
if (webError)
|
|
3344
|
+
return webError;
|
|
3345
|
+
const companionTotal = companionItems.reduce((sum, item) => sum + (Number.isFinite(item.size) && item.size > 0 ? item.size : 0), 0);
|
|
3346
|
+
const companionLimit = options.companionLimitBytes ?? MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES;
|
|
3347
|
+
if (companionTotal > companionLimit)
|
|
3348
|
+
return 'Companion 归档总大小超过当前 2GiB 临时上限,请缩减归档后重新 deploy';
|
|
3349
|
+
return undefined;
|
|
3350
|
+
}
|
|
3135
3351
|
function shouldUploadDistFile(relativePath) {
|
|
3136
3352
|
const normalized = normalizeRelativePath(relativePath);
|
|
3137
3353
|
if (!normalized) {
|
|
@@ -3230,6 +3446,7 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
|
|
|
3230
3446
|
}
|
|
3231
3447
|
const mappings = new Map();
|
|
3232
3448
|
const serverSizes = new Map();
|
|
3449
|
+
const serverHashes = new Map();
|
|
3233
3450
|
const knownKeys = new Set();
|
|
3234
3451
|
for (const serverFile of serverFiles) {
|
|
3235
3452
|
const relativePath = normalizeMiniappArtifactRelativePath(serverFile.relative_path);
|
|
@@ -3247,8 +3464,13 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
|
|
|
3247
3464
|
if (!Number.isSafeInteger(size) || size < 0) {
|
|
3248
3465
|
throw new Error(`上传会话返回文件大小异常:${relativePath}`);
|
|
3249
3466
|
}
|
|
3467
|
+
const sha256 = String(serverFile.sha256 || '');
|
|
3468
|
+
if (!/^[a-f0-9]{64}$/.test(sha256)) {
|
|
3469
|
+
throw new Error(`上传会话返回文件 SHA-256 异常:${relativePath}`);
|
|
3470
|
+
}
|
|
3250
3471
|
mappings.set(relativePath, key);
|
|
3251
3472
|
serverSizes.set(relativePath, size);
|
|
3473
|
+
serverHashes.set(relativePath, sha256);
|
|
3252
3474
|
knownKeys.add(key);
|
|
3253
3475
|
}
|
|
3254
3476
|
const files = preparedFiles.map((file) => {
|
|
@@ -3259,6 +3481,9 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
|
|
|
3259
3481
|
if (serverSizes.get(file.relativePath) !== file.size) {
|
|
3260
3482
|
throw new Error(`上传会话文件大小与本地构建不一致:${file.relativePath}`);
|
|
3261
3483
|
}
|
|
3484
|
+
if (!('sha256' in file) || serverHashes.get(file.relativePath) !== file.sha256) {
|
|
3485
|
+
throw new Error(`上传会话文件 SHA-256 与本地构建不一致:${file.relativePath}`);
|
|
3486
|
+
}
|
|
3262
3487
|
return { file, key };
|
|
3263
3488
|
});
|
|
3264
3489
|
const completed = new Set();
|
|
@@ -3275,6 +3500,41 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
|
|
|
3275
3500
|
uploadedKeys: [...completed],
|
|
3276
3501
|
};
|
|
3277
3502
|
}
|
|
3503
|
+
/** 校验 Manifest 中所有 Companion 归档都精确属于当前上传 receipt。 */
|
|
3504
|
+
function validateMiniappCompanionFileReceipts(companions, files) {
|
|
3505
|
+
const companionFiles = new Map(files.filter((file) => file.relativePath.startsWith('companions/')).map((file) => [file.relativePath, file]));
|
|
3506
|
+
if (companions === undefined) {
|
|
3507
|
+
if (companionFiles.size > 0)
|
|
3508
|
+
throw new Error('dist 包含未被 manifest.companions 引用的 Companion 归档');
|
|
3509
|
+
return;
|
|
3510
|
+
}
|
|
3511
|
+
if (!isRecord$1(companions))
|
|
3512
|
+
throw new Error('manifest.companions 必须是对象');
|
|
3513
|
+
const referenced = new Set();
|
|
3514
|
+
for (const definition of Object.values(companions)) {
|
|
3515
|
+
if (!isRecord$1(definition) || !isRecord$1(definition.targets))
|
|
3516
|
+
throw new Error('manifest.companions targets 不合法');
|
|
3517
|
+
for (const artifact of Object.values(definition.targets)) {
|
|
3518
|
+
if (!isRecord$1(artifact) || typeof artifact.path !== 'string' || typeof artifact.size !== 'number' || typeof artifact.sha256 !== 'string') {
|
|
3519
|
+
throw new Error('manifest.companions artifact 不合法');
|
|
3520
|
+
}
|
|
3521
|
+
const file = companionFiles.get(artifact.path);
|
|
3522
|
+
if (!file)
|
|
3523
|
+
throw new Error(`manifest.companions 引用的归档不在当前上传 receipt:${artifact.path}`);
|
|
3524
|
+
if (file.size !== artifact.size)
|
|
3525
|
+
throw new Error(`Companion 归档大小与 manifest 不一致:${artifact.path}`);
|
|
3526
|
+
if (file.sha256 !== artifact.sha256)
|
|
3527
|
+
throw new Error(`Companion 归档 SHA-256 与 manifest 不一致:${artifact.path}`);
|
|
3528
|
+
referenced.add(artifact.path);
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
const extra = [...companionFiles.keys()].find((relativePath) => !referenced.has(relativePath));
|
|
3532
|
+
if (extra)
|
|
3533
|
+
throw new Error(`Companion 归档未被 manifest.companions 引用:${extra}`);
|
|
3534
|
+
}
|
|
3535
|
+
function isRecord$1(value) {
|
|
3536
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3537
|
+
}
|
|
3278
3538
|
function normalizeMiniappArtifactRelativePath(relativePath) {
|
|
3279
3539
|
const value = String(relativePath || '');
|
|
3280
3540
|
if (!value) {
|
|
@@ -3359,14 +3619,16 @@ function findNearestPackageJsonPath(startDir) {
|
|
|
3359
3619
|
current = parent;
|
|
3360
3620
|
}
|
|
3361
3621
|
}
|
|
3622
|
+
function readMiniappPlatformsFromPackageJson(root) {
|
|
3623
|
+
const { packageJson } = readMiniappPackageJson(root);
|
|
3624
|
+
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3625
|
+
return validateMiniappPlatforms(heybox?.platforms, 'package.json#heybox.platforms');
|
|
3626
|
+
}
|
|
3362
3627
|
function readMiniappPermissionsFromPackageJson(root, sdkVersion) {
|
|
3363
3628
|
const { packageJson } = readMiniappPackageJson(root);
|
|
3364
|
-
const heybox = packageJson
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
}
|
|
3368
|
-
const present = isRecord(heybox) && Object.prototype.hasOwnProperty.call(heybox, 'permissions');
|
|
3369
|
-
return parseMiniappPermissions(isRecord(heybox) ? heybox.permissions : undefined, {
|
|
3629
|
+
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3630
|
+
const present = heybox !== undefined && Object.prototype.hasOwnProperty.call(heybox, 'permissions');
|
|
3631
|
+
return parseMiniappPermissions(heybox?.permissions, {
|
|
3370
3632
|
present,
|
|
3371
3633
|
sdkVersion,
|
|
3372
3634
|
});
|
|
@@ -3395,7 +3657,15 @@ function readMiniappPackageJson(root, requireVersion) {
|
|
|
3395
3657
|
catch (error) {
|
|
3396
3658
|
throw new Error(`@heybox/hb-sdk 解析 package.json 失败:${formatReason(error)}`);
|
|
3397
3659
|
}
|
|
3398
|
-
return { packageJson, version: typeof packageJson.version === 'string' ? packageJson.version.trim() : '' };
|
|
3660
|
+
return { packageJson, packageJsonPath, version: typeof packageJson.version === 'string' ? packageJson.version.trim() : '' };
|
|
3661
|
+
}
|
|
3662
|
+
function readMiniappHeyboxConfig(packageJson) {
|
|
3663
|
+
if (packageJson.heybox === undefined)
|
|
3664
|
+
return undefined;
|
|
3665
|
+
if (!isRecord(packageJson.heybox)) {
|
|
3666
|
+
throw new Error('@heybox/hb-sdk 提示:package.json#heybox 必须是 JSON 对象');
|
|
3667
|
+
}
|
|
3668
|
+
return packageJson.heybox;
|
|
3399
3669
|
}
|
|
3400
3670
|
function isRecord(value) {
|
|
3401
3671
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -3407,6 +3677,13 @@ function formatReason(error) {
|
|
|
3407
3677
|
return String(error);
|
|
3408
3678
|
}
|
|
3409
3679
|
|
|
3680
|
+
Array.from({ length: 256 }, (_, value) => {
|
|
3681
|
+
let crc = value;
|
|
3682
|
+
for (let bit = 0; bit < 8; bit++)
|
|
3683
|
+
crc = (crc >>> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
|
|
3684
|
+
return crc >>> 0;
|
|
3685
|
+
});
|
|
3686
|
+
|
|
3410
3687
|
const HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN_ENV = 'HB_SDK_RUNTIME_USE_OFFICIAL_DOMAIN';
|
|
3411
3688
|
const HB_SDK_RUNTIME_PERMISSION_CONTEXT_ENV = 'HB_SDK_RUNTIME_PERMISSION_CONTEXT';
|
|
3412
3689
|
const VERIFIED_RUNTIME_PERMISSION_CONTEXT = 'verified';
|
|
@@ -3498,23 +3775,27 @@ exports.USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = USER_MINIPROGRAM_ACCESS_STATUS
|
|
|
3498
3775
|
exports.USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH = USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH;
|
|
3499
3776
|
exports.USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH = USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH;
|
|
3500
3777
|
exports.WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH = WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH;
|
|
3778
|
+
exports.areMiniappPlatformsEqual = areMiniappPlatformsEqual;
|
|
3501
3779
|
exports.composeMiniappRuntimePermissions = composeMiniappRuntimePermissions;
|
|
3502
3780
|
exports.createMiniappArtifactFileHeader = createMiniappArtifactFileHeader;
|
|
3503
3781
|
exports.createMiniappArtifactSignatureHeader = createMiniappArtifactSignatureHeader;
|
|
3504
3782
|
exports.createMiniappPlatformCspEnv = createMiniappPlatformCspEnv;
|
|
3505
3783
|
exports.getMissingPermissionsWarning = getMissingPermissionsWarning;
|
|
3784
|
+
exports.isValidMiniappManifestVersion = isValidMiniappManifestVersion;
|
|
3506
3785
|
exports.normalizeRelativePath = normalizeRelativePath;
|
|
3507
3786
|
exports.parseMiniProgramRuntimePermissions = parseMiniProgramRuntimePermissions;
|
|
3508
|
-
exports.
|
|
3787
|
+
exports.parseMiniappManifestJson = parseMiniappManifestJson;
|
|
3509
3788
|
exports.prepareMiniappArtifactFiles = prepareMiniappArtifactFiles;
|
|
3510
3789
|
exports.readMiniappPermissionsFromPackageJson = readMiniappPermissionsFromPackageJson;
|
|
3790
|
+
exports.readMiniappPlatformsFromPackageJson = readMiniappPlatformsFromPackageJson;
|
|
3511
3791
|
exports.relativePathContainsNodeModulesSegment = relativePathContainsNodeModulesSegment;
|
|
3512
3792
|
exports.requireSemver = requireSemver;
|
|
3513
3793
|
exports.resolveMiniappSdkVersion = resolveMiniappSdkVersion;
|
|
3514
3794
|
exports.resolveMiniappUploadSessionFiles = resolveMiniappUploadSessionFiles;
|
|
3515
|
-
exports.semverExports = semverExports;
|
|
3516
3795
|
exports.shouldSkipMiniappPlatformCspFromEnv = shouldSkipMiniappPlatformCspFromEnv;
|
|
3517
3796
|
exports.shouldUploadDistFile = shouldUploadDistFile;
|
|
3797
|
+
exports.validateMiniappCompanionFileReceipts = validateMiniappCompanionFileReceipts;
|
|
3798
|
+
exports.validateMiniappManifestForDeploy = validateMiniappManifestForDeploy;
|
|
3518
3799
|
exports.validateMiniappUploadPathLengths = validateMiniappUploadPathLengths;
|
|
3519
|
-
exports.
|
|
3800
|
+
exports.validateMiniappUploadSizeBudgets = validateMiniappUploadSizeBudgets;
|
|
3520
3801
|
exports.withMiniappPlatformCspEnv = withMiniappPlatformCspEnv;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var version = require('./version-D19lZmYN.cjs');
|
|
4
|
+
var fs = require('node:fs/promises');
|
|
3
5
|
var path = require('node:path');
|
|
4
|
-
var version = require('./version-BONZQWPR.cjs');
|
|
5
6
|
var childProcess = require('node:child_process');
|
|
6
|
-
var
|
|
7
|
-
var index = require('./index-BEn7WaqA.cjs');
|
|
7
|
+
var index = require('./index-CDwwaNvP.cjs');
|
|
8
8
|
require('node:module');
|
|
9
9
|
require('node:fs');
|
|
10
10
|
require('path');
|
|
@@ -17,26 +17,6 @@ require('stream');
|
|
|
17
17
|
require('buffer');
|
|
18
18
|
require('util');
|
|
19
19
|
|
|
20
|
-
function installSkill(options) {
|
|
21
|
-
const binary = require.resolve('skills/bin/cli.mjs');
|
|
22
|
-
const args = ['add', path.join(options.packageRoot, 'skill'), '--copy'];
|
|
23
|
-
if (options.global)
|
|
24
|
-
args.push('--global');
|
|
25
|
-
if (options.allAgents)
|
|
26
|
-
args.push('--agent', '*');
|
|
27
|
-
else if (options.agents?.length)
|
|
28
|
-
args.push('--agent', ...options.agents);
|
|
29
|
-
if (options.force)
|
|
30
|
-
args.push('--force');
|
|
31
|
-
const env = { ...process.env, ...options.env, DISABLE_TELEMETRY: '1', DO_NOT_TRACK: '1' };
|
|
32
|
-
const run = options.spawnImpl ?? childProcess.spawn;
|
|
33
|
-
return new Promise((resolve, reject) => {
|
|
34
|
-
const child = run(process.execPath, [binary, ...args], { cwd: options.cwd, env, stdio: 'inherit' });
|
|
35
|
-
child.on('error', reject);
|
|
36
|
-
child.on('close', (code) => resolve({ code: code ?? 1 }));
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
20
|
async function findProjectPackageJson(cwd = process.cwd()) {
|
|
41
21
|
let current = path.resolve(cwd);
|
|
42
22
|
while (true) {
|
|
@@ -45,7 +25,45 @@ async function findProjectPackageJson(cwd = process.cwd()) {
|
|
|
45
25
|
await fs.access(candidate);
|
|
46
26
|
return candidate;
|
|
47
27
|
}
|
|
48
|
-
catch {
|
|
28
|
+
catch {
|
|
29
|
+
/* continue */
|
|
30
|
+
}
|
|
31
|
+
const parent = path.dirname(current);
|
|
32
|
+
if (parent === current)
|
|
33
|
+
return undefined;
|
|
34
|
+
current = parent;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function findSdkPackageRoot(startDir) {
|
|
38
|
+
let current = path.resolve(startDir);
|
|
39
|
+
while (true) {
|
|
40
|
+
const candidate = path.join(current, 'package.json');
|
|
41
|
+
try {
|
|
42
|
+
const pkg = JSON.parse(await fs.readFile(candidate, 'utf8'));
|
|
43
|
+
if (pkg.name === '@heybox/hb-sdk')
|
|
44
|
+
return current;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
/* continue */
|
|
48
|
+
}
|
|
49
|
+
const parent = path.dirname(current);
|
|
50
|
+
if (parent === current)
|
|
51
|
+
return undefined;
|
|
52
|
+
current = parent;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function readInstalledProjectSdkVersion(projectPackageJson) {
|
|
56
|
+
let current = path.dirname(projectPackageJson);
|
|
57
|
+
while (true) {
|
|
58
|
+
const candidate = path.join(current, 'node_modules', '@heybox', 'hb-sdk', 'package.json');
|
|
59
|
+
try {
|
|
60
|
+
const pkg = JSON.parse(await fs.readFile(candidate, 'utf8'));
|
|
61
|
+
if (pkg.name === '@heybox/hb-sdk' && typeof pkg.version === 'string' && pkg.version)
|
|
62
|
+
return pkg.version;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
/* continue */
|
|
66
|
+
}
|
|
49
67
|
const parent = path.dirname(current);
|
|
50
68
|
if (parent === current)
|
|
51
69
|
return undefined;
|
|
@@ -60,20 +78,58 @@ async function verifyProjectSdk(cwd, version) {
|
|
|
60
78
|
const declared = pkg.dependencies?.['@heybox/hb-sdk'] ?? pkg.devDependencies?.['@heybox/hb-sdk'];
|
|
61
79
|
if (!declared)
|
|
62
80
|
throw new Error('项目缺少 @heybox/hb-sdk 依赖');
|
|
63
|
-
|
|
81
|
+
const declaredVersion = String(declared);
|
|
82
|
+
if (declaredVersion.startsWith('workspace:')) {
|
|
83
|
+
const installedVersion = await readInstalledProjectSdkVersion(file);
|
|
84
|
+
if (installedVersion === version)
|
|
85
|
+
return;
|
|
86
|
+
if (installedVersion) {
|
|
87
|
+
throw new Error(`项目 @heybox/hb-sdk 版本 ${declaredVersion}(实际 ${installedVersion})与 CLI ${version} 不一致`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (declared !== version && !declaredVersion.includes(version)) {
|
|
64
91
|
throw new Error(`项目 @heybox/hb-sdk 版本 ${declared} 与 CLI ${version} 不一致`);
|
|
65
92
|
}
|
|
66
93
|
}
|
|
67
94
|
|
|
95
|
+
function installSkill(options) {
|
|
96
|
+
const binary = require.resolve('skills/bin/cli.mjs');
|
|
97
|
+
const args = ['add', path.join(options.packageRoot, 'skill'), '--copy'];
|
|
98
|
+
if (options.global)
|
|
99
|
+
args.push('--global');
|
|
100
|
+
if (options.allAgents)
|
|
101
|
+
args.push('--agent', '*');
|
|
102
|
+
else if (options.agents?.length)
|
|
103
|
+
args.push('--agent', ...options.agents);
|
|
104
|
+
if (options.force)
|
|
105
|
+
args.push('--force');
|
|
106
|
+
const env = { ...process.env, ...options.env, DISABLE_TELEMETRY: '1', DO_NOT_TRACK: '1' };
|
|
107
|
+
const run = options.spawnImpl ?? childProcess.spawn;
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
const child = run(process.execPath, [binary, ...args], { cwd: options.cwd, env, stdio: 'inherit' });
|
|
110
|
+
child.on('error', reject);
|
|
111
|
+
child.on('close', (code) => resolve({ code: code ?? 1 }));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
68
115
|
async function runSkillInstallCommand(options = {}) {
|
|
69
116
|
if (options.agent?.length && options.allAgents)
|
|
70
117
|
throw new Error('--agent 与 --all-agents 互斥');
|
|
71
118
|
const logger = options.logger ?? index.createCliLogger();
|
|
72
|
-
const packageRoot = options.packageRoot ??
|
|
119
|
+
const packageRoot = options.packageRoot ?? (await findSdkPackageRoot(__dirname));
|
|
120
|
+
if (!packageRoot)
|
|
121
|
+
throw new Error('未找到 @heybox/hb-sdk 包目录');
|
|
73
122
|
const cwd = options.cwd ?? process.cwd();
|
|
74
123
|
if (!options.global)
|
|
75
124
|
await verifyProjectSdk(cwd, version.HB_SDK_VERSION);
|
|
76
|
-
const result = await installSkill({
|
|
125
|
+
const result = await installSkill({
|
|
126
|
+
packageRoot,
|
|
127
|
+
cwd,
|
|
128
|
+
global: options.global,
|
|
129
|
+
agents: options.agent,
|
|
130
|
+
allAgents: options.allAgents,
|
|
131
|
+
force: options.force,
|
|
132
|
+
});
|
|
77
133
|
if (result.code !== 0)
|
|
78
134
|
throw new Error(`Skill 安装失败(退出码 ${result.code})`);
|
|
79
135
|
logger.success('hb-sdk Skill 安装完成');
|