@my-life-buddies/cli 0.27.1-dev.2 → 0.28.0-dev.2
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 +11 -21
- package/dist/bin/buddy.js +11 -37
- package/dist/bin/buddy.js.map +2 -2
- package/dist/bin/core.js +108 -186
- package/dist/bin/core.js.map +4 -4
- package/dist/bin/preview.js +2 -57
- package/dist/bin/preview.js.map +3 -3
- package/package.json +7 -8
- package/resources/brand/README.md +1 -1
- package/dist/web/app.css +0 -758
- package/dist/web/app.js +0 -1155
- package/dist/web/assets/developer-platform-icon.png.base64 +0 -1
- package/dist/web/brand.css +0 -100
- package/dist/web/chat-markdown.js +0 -181
- package/dist/web/diagnostics.js +0 -193
- package/dist/web/index.html +0 -268
- package/dist/web/products.css +0 -19
- package/dist/web/products.js +0 -104
- package/dist/web/tokens.css +0 -15
- package/dist/web/tool-inventory.js +0 -94
- package/dist/web/widgets.css +0 -62
- package/dist/web/widgets.js +0 -317
- /package/dist/{web → bin/resources}/widget-document.js +0 -0
package/README.md
CHANGED
|
@@ -344,7 +344,9 @@ buddy-cli-sit meta update --intro "根据食材、人数和口味推荐菜谱"
|
|
|
344
344
|
buddy-cli-sit meta update --avatar ./avatar.png
|
|
345
345
|
```
|
|
346
346
|
|
|
347
|
-
`meta` 只读,修改时必须带 `update` 并至少提供一个字段。多个修改参数可以组合,未传字段保持原样,包括云端已有的扩展资料。文字字段不能为空,名称最多 60 字,一句话介绍最多 200 字,完整介绍最多 10000 字。头像只上传替换,不提供清除选项;支持静态 PNG、JPEG、WebP
|
|
347
|
+
`meta` 只读,修改时必须带 `update` 并至少提供一个字段。多个修改参数可以组合,未传字段保持原样,包括云端已有的扩展资料。文字字段不能为空,名称最多 60 字,一句话介绍最多 200 字,完整介绍最多 10000 字。头像只上传替换,不提供清除选项;支持静态 PNG、JPEG、WebP,原图最大 5 MiB、宽高不超过 4096 px。Server 校验图片并生成地址,处理失败时保留原头像。
|
|
348
|
+
|
|
349
|
+
头像上传请求最多等待 5 分钟,适用于首次登记、替换头像以及同时修改文字和头像。CLI 上传前按服务端规则居中裁切至 512×512,编码为无损 WebP,保留颜色和透明度;原始文件与本地原图草稿不变;查询、仅文字更新和兼容命令清除头像仍使用 30 秒超时。
|
|
348
350
|
|
|
349
351
|
默认向上寻找 `package.json.buddyId`,也可用 `--directory ./cooking-buddy` 指定工程;图片路径始终相对执行命令的当前目录。创作阶段只有身份清单时也能使用,无需安装或启动 Runtime。工程外可直接指定平台 ID:
|
|
350
352
|
|
|
@@ -414,13 +416,13 @@ CLI 将文件原样放入源码包,启动入口只调用 `BuddyServer.start(cr
|
|
|
414
416
|
|
|
415
417
|
## 在模拟器里聊一次
|
|
416
418
|
|
|
417
|
-
CLI 0.13.0 起,默认预览 UI 由后台提供。后台「获取连接指令」返回 `buddy-cli-sit preview --buddy-id <id> --developer-web <后台 URL> --app-server <平台 URL> --no-open`;请在对应工程目录执行。CLI 0.17.7 起支持 `--no-open`,只连接工程,返回原调试页即可,不重复打开网页;页面已关闭时可打开终端打印的地址。直接执行 `buddy-cli-sit preview`
|
|
419
|
+
CLI 0.13.0 起,默认预览 UI 由后台提供。后台「获取连接指令」返回 `buddy-cli-sit preview --buddy-id <id> --developer-web <后台 URL> --app-server <平台 URL> --no-open`;请在对应工程目录执行。CLI 0.17.7 起支持 `--no-open`,只连接工程,返回原调试页即可,不重复打开网页;页面已关闭时可打开终端打印的地址。直接执行 `buddy-cli-sit preview` 仍自动打开后台。
|
|
418
420
|
|
|
419
421
|
CLI 校验工程身份,后台验证账号与搭子归属。同一电脑、同一工程已有连接时,新命令复用它并退出,由原 CLI 继续维持连接;请保持原终端运行。连接其他电脑或工程前,请先退出原 CLI。
|
|
420
422
|
|
|
421
423
|
后台显示「未连接本地工程」「已连接但 DEV 未启动」「DEV 运行中」。CLI 主动发起 HTTPS 连接,后台通过受限调试接口控制本机 Runtime,浏览器不需访问 localhost。工程路径用于显示连接身份,源码不会经调试通道上传。连接每 500 ms 交换待处理请求;持续中断 10 秒停止 DEV,后台最迟约 17 秒显示断开;短暂断网恢复后手动启动 DEV;若后台已结束或撤销连接,CLI 会退出,需要重新执行连接指令。页面刷新只恢复状态,CLI 退出停止 DEV 并断开。
|
|
422
424
|
|
|
423
|
-
|
|
425
|
+
CLI 0.28.0-dev.1 起,调试页面完全由后台维护,安装包不再包含独立本地网页。`--local`、`--port` 已停用,使用旧参数会提示改用 `buddy-cli-sit preview`。本地连接不需要公网隧道;DEV、日志、消息、小挂件和商品调试接口继续保留,预览不会提审或发布。
|
|
424
426
|
|
|
425
427
|
以下两个命令按需选择,不必同时启动同一个工程:
|
|
426
428
|
|
|
@@ -517,27 +519,15 @@ buddy-cli-sit products submit --resume <submissionId>
|
|
|
517
519
|
|
|
518
520
|
提交结果包含准确的审核快照 ID。只有曾上架商品(包括已下架商品)才可独立选择已有版本提交修改;当前线上代码支持本次修改时,可以选择当前已发布版本,之后单独发布修改。首次商品仅可通过此命令恢复原上传的商品提交失败,仍须与关联搭子版本一起发布。
|
|
519
521
|
|
|
520
|
-
###
|
|
521
|
-
|
|
522
|
-
```bash
|
|
523
|
-
buddy-cli-sit release --from-push <pushId>
|
|
524
|
-
buddy-cli-sit release --from-submission <submissionId>
|
|
525
|
-
buddy-cli-sit release --from-submission <submissionId> --products-only
|
|
526
|
-
buddy-cli-sit release --version <版本> --code-only
|
|
527
|
-
```
|
|
522
|
+
### 在后台确认发布
|
|
528
523
|
|
|
529
|
-
|
|
524
|
+
CLI 负责上传代码、提交明确选中的商品以及查询或恢复这些操作。上传、审核和构建成功后,在开发者后台“版本与发布”核对本次版本与获批商品快照,再确认发布;CLI 不提供最终发布命令。
|
|
530
525
|
|
|
531
|
-
|
|
532
|
-
buddy-cli-sit release --status <releaseId>
|
|
533
|
-
buddy-cli-sit release --resume <releaseId>
|
|
534
|
-
buddy-cli-sit release --retry <releaseId>
|
|
535
|
-
buddy-cli-sit release --cancel <releaseId>
|
|
536
|
-
```
|
|
526
|
+
首次商品必须随关联搭子版本一起发布。曾上架商品的修改可以在当前线上代码支持时,从后台单独发布;已下架商品发布修改后仍保持下架。只希望更新代码时,在后台明确选择仅发布代码,商品内容保持原样。
|
|
537
527
|
|
|
538
|
-
|
|
528
|
+
发布任务的状态查询、重试和取消也在后台操作。取消阻止本任务后续激活商品,但不回滚已经开始的代码部署。后台显示发布成功后,仍需确认实际服务体验。下架仍在后台操作。
|
|
539
529
|
|
|
540
|
-
|
|
530
|
+
CLI 的上传和商品补提恢复记录按平台、账号、搭子隔离,保存在本机私有操作目录;记录不包含登录凭据,恢复使用当前账号重新鉴权。
|
|
541
531
|
|
|
542
532
|
### 上传前检查
|
|
543
533
|
|
|
@@ -639,6 +629,6 @@ unset BUDDY_CLI_PIN_VERSION
|
|
|
639
629
|
|
|
640
630
|
SIT 平台固定为 `https://buddies.sit.dots.chat`。CLI 地址约束是客户端防误连机制;服务端仍须独立校验身份、Token 和权限,不是完整的服务端安全隔离。
|
|
641
631
|
|
|
642
|
-
SIT `push` 触发异步构建,显示 `building/ready/failed` 及失败原因,最多等待一分钟;仍在构建时用 `buddy-cli-sit status`
|
|
632
|
+
SIT `push` 触发异步构建,显示 `building/ready/failed` 及失败原因,最多等待一分钟;仍在构建时用 `buddy-cli-sit status` 查询,不能重复上传当作查询。审核通过、构建就绪和线上发布是不同状态;确认上传回执中的版本与商品快照后,在开发者后台“版本与发布”确认发布,并核对实际服务体验。
|
|
643
633
|
|
|
644
634
|
DEV 要同时看到 Runtime 初始化完成和服务端在线后才就绪。后台的 Widget 编辑需配套 Server 和 Web 部署,只开放 `operations.userUI` 授权的记录操作,并遵守字段只读限制;409 冲突需重读核对,不能自动覆盖。图片上传与关闭后的聚合通知、API 和错误处理见 [Widget 指南](../../docs/preview/widgets.md)。目标 App 仍需提供编辑桥接并单独验收,后台预览成功不代表手机端已支持。记录编辑不代表多人实时同步、玩家身份认证或同一 Widget 内的玩家私有数据隔离;付费服务不在此范围。
|
package/dist/bin/buddy.js
CHANGED
|
@@ -96,7 +96,6 @@ import {
|
|
|
96
96
|
} from "./preview.js";
|
|
97
97
|
var PREVIEW_COMMAND_HELP = `\u7528\u6CD5:
|
|
98
98
|
buddy-cli-sit preview [--directory <\u9879\u76EE\u76EE\u5F55>] [--buddy-id <\u642D\u5B50 ID>] [--developer-web <\u540E\u53F0 URL>] [--app-server <App Server URL>] [--no-open]
|
|
99
|
-
buddy-cli-sit preview --local [--directory <\u9879\u76EE\u76EE\u5F55>] [--port <\u672C\u5730\u7AEF\u53E3>]
|
|
100
99
|
|
|
101
100
|
\u8BF4\u660E:
|
|
102
101
|
\u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u642D\u5B50\u7684\u521B\u9020\u8005\u540E\u53F0\u300C\u5F00\u53D1\u8C03\u8BD5\u300D\uFF0C\u8FDE\u63A5\u672C\u5730\u5DE5\u7A0B\uFF1B\u5728\u540E\u53F0\u542F\u52A8/\u505C\u6B62 DEV\u3001\u8BD5\u804A\u3001\u67E5\u770B Widget\u3001\u65F6\u95F4\u7EBF\u4E0E\u534F\u8BAE\u65E5\u5FD7\u3001\u771F\u673A\u9884\u89C8\u3002
|
|
@@ -104,8 +103,7 @@ var PREVIEW_COMMAND_HELP = `\u7528\u6CD5:
|
|
|
104
103
|
\u540E\u53F0\u590D\u5236\u7684\u547D\u4EE4\u5E26 --no-open\uFF0C\u53EA\u8FDE\u63A5\u5DE5\u7A0B\uFF0C\u539F\u8C03\u8BD5\u9875\u81EA\u52A8\u63A5\u5165\uFF0C\u4E0D\u91CD\u590D\u6253\u5F00\u7F51\u9875\uFF1B\u9875\u9762\u5173\u95ED\u540E\u53EF\u6253\u5F00\u7EC8\u7AEF\u4E2D\u7684\u5730\u5740\u3002
|
|
105
104
|
\u8FDE\u63A5\u540E\u5373\u53EF\u67E5\u770B\u5DE5\u7A0B\u6A21\u578B\u548C\u5DE5\u5177\u5217\u8868\uFF0C\u65E0\u9700\u53D1\u9001\u6D88\u606F\uFF1BCLI \u53EA\u8BFB\u73B0\u6709\u6E90\u4EE3\u7801\uFF0C\u52A8\u6001\u914D\u7F6E\u6807\u6CE8\u5F85\u786E\u8BA4\uFF0C\u4FDD\u5B58\u540E\u81EA\u52A8\u5237\u65B0\u3002
|
|
106
105
|
\u4E0D\u6267\u884C\u4E1A\u52A1\u5DE5\u5382\u6765\u63A2\u6D4B\u914D\u7F6E\uFF0C\u4E0D\u65B0\u589E\u5DE5\u7A0B\u914D\u7F6E\u6587\u4EF6\uFF0C\u4E5F\u4E0D\u8981\u6C42\u4E3A\u6B64\u5347\u7EA7 Runtime\u3002\u6BCF\u6B21\u8C03\u7528\u7684\u5B9E\u9645\u6A21\u578B\u4E0E\u5DE5\u5177\u4EE5\u6A21\u578B\u8C03\u7528\u65E5\u5FD7\u4E3A\u51C6\u3002
|
|
107
|
-
|
|
108
|
-
--local \u662F\u540E\u53F0\u4E0D\u53EF\u7528\u65F6\u7684\u72EC\u7ACB\u672C\u5730\u9884\u89C8\u5907\u7528\u5165\u53E3\uFF0C--port \u4EC5\u4E0E --local \u4E00\u8D77\u4F7F\u7528\u3002
|
|
106
|
+
\u8C03\u8BD5\u9875\u9762\u7531\u521B\u9020\u8005\u540E\u53F0\u63D0\u4F9B\uFF1BCLI \u53EA\u8FDE\u63A5\u548C\u8FD0\u884C\u672C\u5730\u5DE5\u7A0B\uFF0C\u4E0D\u63D0\u4F9B\u72EC\u7ACB\u672C\u5730\u7F51\u9875\u3002
|
|
109
107
|
\u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1BCtrl+C \u6216\u5173\u95ED\u7EC8\u7AEF\u4F1A\u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\uFF0C\u5237\u65B0\u540E\u53F0\u4E0D\u4F1A\u81EA\u52A8\u542F\u52A8 DEV\u3002
|
|
110
108
|
DEV \u5931\u8D25\u5148\u67E5\u770B\u5177\u4F53\u9519\u8BEF\u548C\u8FD0\u884C\u65E5\u5FD7\uFF1B\u5347\u7EA7 CLI \u540E\u9000\u51FA\u65E7 preview \u8FDB\u7A0B\u5E76\u91CD\u65B0\u8FDE\u63A5\uFF0C\u518D\u542F\u52A8 DEV\u3002
|
|
111
109
|
\u540E\u53F0\u53EF\u5F3A\u5236\u65AD\u8FDE\uFF1B\u672C\u673A\u505C\u6B62\u672A\u786E\u8BA4\u65F6\uFF0C\u5728\u539F\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C buddy-cli-sit dev stop\u3002\u8BE5\u547D\u4EE4\u4E0D\u91CD\u8FDE\u3001\u4E0D\u91CD\u542F\u3002
|
|
@@ -133,9 +131,7 @@ function parsePreviewArguments(args) {
|
|
|
133
131
|
let directory = ".";
|
|
134
132
|
let directorySet = false;
|
|
135
133
|
let appServer;
|
|
136
|
-
let port;
|
|
137
134
|
let help = false;
|
|
138
|
-
let local = false;
|
|
139
135
|
let noOpen = false;
|
|
140
136
|
let refreshToken = false;
|
|
141
137
|
let buddyId;
|
|
@@ -152,11 +148,7 @@ function parsePreviewArguments(args) {
|
|
|
152
148
|
help = true;
|
|
153
149
|
continue;
|
|
154
150
|
}
|
|
155
|
-
if (flag === "--local") {
|
|
156
|
-
if (local) throw new Error("--local \u4E0D\u80FD\u91CD\u590D");
|
|
157
|
-
local = true;
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
151
|
+
if (flag === "--local" || flag === "--port") throw new Error(`${flag} \u5DF2\u505C\u7528\uFF1B\u8BF7\u8FD0\u884C buddy-cli-sit preview\uFF0C\u5728\u521B\u9020\u8005\u540E\u53F0\u5F00\u53D1\u8C03\u8BD5\u3002`);
|
|
160
152
|
if (flag === "--no-open") {
|
|
161
153
|
if (noOpen) throw new Error("--no-open \u4E0D\u80FD\u91CD\u590D");
|
|
162
154
|
noOpen = true;
|
|
@@ -177,10 +169,6 @@ function parsePreviewArguments(args) {
|
|
|
177
169
|
directory = value;
|
|
178
170
|
directorySet = true;
|
|
179
171
|
break;
|
|
180
|
-
case "--port":
|
|
181
|
-
if (port !== void 0 || !/^\d+$/u.test(value) || Number(value) < 1 || Number(value) > 65535) throw new Error("--port \u5FC5\u987B\u662F 1\u201365535 \u7684\u7AEF\u53E3\u4E14\u4E0D\u80FD\u91CD\u590D");
|
|
182
|
-
port = Number(value);
|
|
183
|
-
break;
|
|
184
172
|
case "--app-server":
|
|
185
173
|
appServer = setOnce(appServer, value, flag);
|
|
186
174
|
break;
|
|
@@ -188,16 +176,7 @@ function parsePreviewArguments(args) {
|
|
|
188
176
|
throw new Error(`\u672A\u77E5 preview \u53C2\u6570 ${flag ?? ""}`);
|
|
189
177
|
}
|
|
190
178
|
}
|
|
191
|
-
|
|
192
|
-
if (local && developerWeb) throw new Error("--local \u4E0D\u9700\u8981 --developer-web");
|
|
193
|
-
if (local && noOpen) throw new Error("--no-open \u4EC5\u7528\u4E8E\u540E\u53F0\u9884\u89C8\uFF0C\u4E0D\u80FD\u548C --local \u4E00\u8D77\u4F7F\u7528");
|
|
194
|
-
return Object.freeze({ directory, appServer, help, local, buddyId, developerWeb, ...port === void 0 ? {} : { port }, ...refreshToken ? { refreshToken: true } : {}, ...noOpen ? { noOpen: true } : {} });
|
|
195
|
-
}
|
|
196
|
-
function waitForAbort(signal) {
|
|
197
|
-
if (signal.aborted) return Promise.resolve();
|
|
198
|
-
return new Promise((resolveWait) => {
|
|
199
|
-
signal.addEventListener("abort", () => resolveWait(), { once: true });
|
|
200
|
-
});
|
|
179
|
+
return Object.freeze({ directory, appServer, help, buddyId, developerWeb, ...refreshToken ? { refreshToken: true } : {}, ...noOpen ? { noOpen: true } : {} });
|
|
201
180
|
}
|
|
202
181
|
function previewHandle(handle) {
|
|
203
182
|
return Object.freeze({
|
|
@@ -312,12 +291,12 @@ var BuddyPlatformHost = class {
|
|
|
312
291
|
}
|
|
313
292
|
});
|
|
314
293
|
await controller.refreshInspection();
|
|
315
|
-
const serverHandle = await startPreviewControlServer({ controller
|
|
294
|
+
const serverHandle = await startPreviewControlServer({ controller });
|
|
316
295
|
let bridge;
|
|
317
296
|
try {
|
|
318
297
|
const pageUrl = new URL(webUrl);
|
|
319
298
|
pageUrl.hash = `/buddy/${encodeURIComponent(manifest.buddyId)}/debug`;
|
|
320
|
-
|
|
299
|
+
bridge = await connectPreviewBridge({
|
|
321
300
|
webUrl,
|
|
322
301
|
platformOrigin: baseUrl.origin,
|
|
323
302
|
buddyId: manifest.buddyId,
|
|
@@ -330,10 +309,10 @@ var BuddyPlatformHost = class {
|
|
|
330
309
|
});
|
|
331
310
|
if (parsed.noOpen) io.write(`\u8BF7\u8FD4\u56DE\u539F\u540E\u53F0\u8C03\u8BD5\u9875\uFF0C\u9875\u9762\u4F1A\u81EA\u52A8\u63A5\u5165\u672C\u5730\u5DE5\u7A0B\u3002\u9875\u9762\u5730\u5740\uFF1A${pageUrl.href}`);
|
|
332
311
|
else {
|
|
333
|
-
await this.#openUrl(
|
|
334
|
-
io.write(`\u642D\u642D
|
|
312
|
+
await this.#openUrl(pageUrl);
|
|
313
|
+
io.write(`\u642D\u642D\u540E\u53F0\u5F00\u53D1\u8C03\u8BD5\u9875\u9762\u5DF2\u6253\u5F00\uFF1A${pageUrl.href}`);
|
|
335
314
|
}
|
|
336
|
-
|
|
315
|
+
io.write(`${bridge?.reused ? "\u5DF2\u590D\u7528" : "\u5DF2\u8FDE\u63A5"}\u672C\u5730\u5DE5\u7A0B\uFF1A${projectRoot}\uFF08${manifest.buddyId}\uFF09\uFF0C\u8BF7\u5728\u540E\u53F0\u67E5\u770B DEV \u72B6\u6001\u3002`);
|
|
337
316
|
io.write("\u5728\u9875\u9762\u4E2D\u542F\u52A8 DEV\uFF1B\u6D88\u606F\u4F1A\u7ECF\u8FC7 DEV App Server\uFF0C\u4E0D\u4F1A\u4ECE\u6D4F\u89C8\u5668\u76F4\u8FDE Agent\u3002");
|
|
338
317
|
if (bridge?.reused) {
|
|
339
318
|
io.write("\u8FDE\u63A5\u7531\u539F CLI \u7EF4\u6301\uFF0C\u8BF7\u4FDD\u6301\u539F\u7EC8\u7AEF\u8FD0\u884C\uFF1B\u5F53\u524D\u547D\u4EE4\u5DF2\u5B8C\u6210\u3002");
|
|
@@ -341,7 +320,7 @@ var BuddyPlatformHost = class {
|
|
|
341
320
|
}
|
|
342
321
|
io.write("\u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1BCtrl+C \u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\u3002");
|
|
343
322
|
if (signal.aborted) return { exitCode: 130, route: "preview" };
|
|
344
|
-
await
|
|
323
|
+
await bridge.completion;
|
|
345
324
|
return { exitCode: 130, route: "preview" };
|
|
346
325
|
} finally {
|
|
347
326
|
await bridge?.close().catch(() => void 0);
|
|
@@ -475,6 +454,7 @@ import { readFile } from "node:fs/promises";
|
|
|
475
454
|
import { homedir as homedir2 } from "node:os";
|
|
476
455
|
import { join as join3 } from "node:path";
|
|
477
456
|
import { promisify } from "node:util";
|
|
457
|
+
import { npmPackageManifest } from "./core.js";
|
|
478
458
|
|
|
479
459
|
// apps/cli/src/update-lock.ts
|
|
480
460
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
@@ -625,13 +605,7 @@ async function latestVersion(options) {
|
|
|
625
605
|
const timeout = AbortSignal.timeout(1e4);
|
|
626
606
|
const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
|
|
627
607
|
try {
|
|
628
|
-
const
|
|
629
|
-
signal,
|
|
630
|
-
headers: { Accept: "application/json" },
|
|
631
|
-
redirect: "error"
|
|
632
|
-
});
|
|
633
|
-
if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);
|
|
634
|
-
const metadata = await response.json();
|
|
608
|
+
const metadata = await npmPackageManifest(PACKAGE, "dev", { fetch: options.fetch, signal });
|
|
635
609
|
if (metadata?.name !== PACKAGE) throw new Error("npm \u8FD4\u56DE\u7684\u5305\u540D\u4E0D\u5339\u914D");
|
|
636
610
|
parseVersion(metadata.version);
|
|
637
611
|
if (typeof metadata.version !== "string" || !/^\d+\.\d+\.\d+-dev\.\d+$/.test(metadata.version)) throw new Error("npm dev \u672A\u6307\u5411 x.y.z-dev.N \u7248\u672C\uFF1BSIT CLI \u4E0D\u4F1A\u8DE8\u6E20\u9053\u66F4\u65B0\uFF0C\u8BF7\u8054\u7CFB\u53D1\u5E03\u8005\u4FEE\u6B63 dev \u6807\u7B7E");
|