@lark-apaas/miaoda-cli 0.1.19-alpha.7f0b693 → 0.1.19-alpha.c3da59d
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 +9 -2
- package/dist/api/comment/api.js +24 -0
- package/dist/api/comment/index.js +6 -0
- package/dist/api/comment/types.js +6 -0
- package/dist/api/index.js +3 -1
- package/dist/cli/commands/comment/index.js +55 -0
- package/dist/cli/commands/index.js +8 -2
- package/dist/cli/commands/registry/index.js +16 -4
- package/dist/cli/handlers/comment/index.js +7 -0
- package/dist/cli/handlers/comment/list.js +92 -0
- package/dist/cli/handlers/comment/resolve.js +44 -0
- package/dist/cli/handlers/registry/add.js +55 -12
- package/dist/services/deploy/modern/atoms/design-build.js +8 -0
- package/dist/services/deploy/modern/atoms/index.js +2 -1
- package/dist/services/deploy/modern/patch/source-scan.js +2 -0
- package/dist/services/deploy/modern/pipelines/design-local.js +30 -21
- package/dist/utils/http.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,12 +11,17 @@ pnpm add -g @lark-apaas/miaoda-cli
|
|
|
11
11
|
## 使用
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
#
|
|
14
|
+
# 设置默认应用(需要应用上下文的命令从 MIAODA_APP_ID 读取)
|
|
15
15
|
export MIAODA_APP_ID=app_demo_xxx
|
|
16
16
|
|
|
17
17
|
# 文件操作
|
|
18
18
|
miaoda file ls
|
|
19
19
|
miaoda file upload ./local/path
|
|
20
|
+
|
|
21
|
+
# 评论操作
|
|
22
|
+
miaoda comment list --json
|
|
23
|
+
miaoda comment list --only-unresolved --json
|
|
24
|
+
miaoda comment resolve 1703677660120110076 --json
|
|
20
25
|
```
|
|
21
26
|
|
|
22
27
|
JSON 结构化输出(Agent 推荐):
|
|
@@ -41,6 +46,7 @@ miaoda file ls --output json
|
|
|
41
46
|
| `miaoda file ...` | 文件操作:上传、下载、元数据、签名下载、批量删除 |
|
|
42
47
|
| `miaoda db ...` | 数据操作:SQL 执行、表结构查询、数据导入导出 |
|
|
43
48
|
| `miaoda observability ...` | 线上日志、链路、前端源码堆栈反查、监控指标、运营指标 |
|
|
49
|
+
| `miaoda comment ...` | 应用评论:查看评论列表、解决评论 |
|
|
44
50
|
| `miaoda registry ...` | 组件 registry:列出 / copy-in design-html SDK 文件(本地执行) |
|
|
45
51
|
|
|
46
52
|
完整命令通过 `miaoda --help` 或 `miaoda <domain> --help` 查看。
|
|
@@ -69,6 +75,7 @@ miaoda registry add deck-slide --overwrite # 目标已存在时覆盖(
|
|
|
69
75
|
- **多匹配全拉**:token 命中多个同名条目时全部 copy-in(如 `add foo` 把 `foo.jsx` + `foo.css` 一起拉),想只要其一就用完整文件名或 relPath。
|
|
70
76
|
- **拍平落地**:所有文件**拍平**到项目根(`scripts/deck-slide.js` → 项目 `deck-slide.js`,不保留子目录);闭包内同名 basename 撞车时后者覆盖前者。
|
|
71
77
|
- **skip-by-disk**:项目已有同名(拍平后的 basename)文件默认跳过,`--overwrite` 才覆盖;不写任何安装记账文件,项目文件树即状态。
|
|
78
|
+
- **add 回执带 usage**:`add` 结果的 `entries` 只列**你请求的条目**(不含被 `Depends` 传递拉进来的依赖——依赖照常落地在 `added`/`skipped`,但那是"管道"),逐条给出 `usage`(USAGE 块原文)与 `dependsOn`,Agent `add` 完即可直接读用法,无需再 `registry list`。请求的条目即使已存在被跳过也回带 usage(`status` 标 `added`/`skipped`,据此判断磁盘上是 registry 版还是你改过的旧版)。`--json` 结构为 `{registryVersion, added, skipped, dryRun, entries}`;pretty(默认)输出 `registry@<ver>` + `added:`/`skipped:` 逗号列表 + 各请求条目的 USAGE 块,稳定 label、无 JSON 数组、无截断,对 Agent 与人同样可读。
|
|
72
79
|
- `--version <ver>` 指定 registry 包版本或 dist-tag(缺省 `latest`),`--dir <path>` 指定项目目录(缺省当前目录)。
|
|
73
80
|
|
|
74
81
|
## 全局参数
|
|
@@ -82,7 +89,7 @@ miaoda registry add deck-slide --overwrite # 目标已存在时覆盖(
|
|
|
82
89
|
## 环境变量
|
|
83
90
|
|
|
84
91
|
- `MIAODA_APP_ID`:默认应用 ID,等价于 `--app-id`。
|
|
85
|
-
- `MIAODA_CANARY_HEADER`:HTTP 请求的 `x-tt-env` 小流量头取值。未设置时默认 `
|
|
92
|
+
- `MIAODA_CANARY_HEADER`:HTTP 请求的 `x-tt-env` 小流量头取值。未设置时默认 `boe_miaoda_ccm`;设为空字符串则不带该头(例:`export MIAODA_CANARY_HEADER=boe_xxx`)。值形如 `ppe_xxx` 时额外带上 `x-use-ppe: 1`。
|
|
86
93
|
|
|
87
94
|
## 输出契约
|
|
88
95
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getComments = getComments;
|
|
4
|
+
exports.resolveComment = resolveComment;
|
|
5
|
+
const http_1 = require("../../utils/http");
|
|
6
|
+
/**
|
|
7
|
+
* 评论接口走管理端 inner-api(getHttpClient + 小写 status_code 信封),与 app / deploy /
|
|
8
|
+
* observability 等域一致:统一的 verbose 请求/响应日志、错误映射、信封解析,不再域内自实现。
|
|
9
|
+
*/
|
|
10
|
+
/** GET /api/v1/studio/innerapi/apps/:appID/comments — 获取应用评论列表 */
|
|
11
|
+
async function getComments(appID, onlyUnresolved = false) {
|
|
12
|
+
let url = `/api/v1/studio/innerapi/apps/${encodeURIComponent(appID)}/comments`;
|
|
13
|
+
if (onlyUnresolved)
|
|
14
|
+
url += '?onlyUnresolved=true';
|
|
15
|
+
const body = await (0, http_1.getInnerApi)(url, {
|
|
16
|
+
errPrefix: 'Failed to list comments',
|
|
17
|
+
});
|
|
18
|
+
return body.items ?? [];
|
|
19
|
+
}
|
|
20
|
+
/** POST /api/v1/studio/innerapi/apps/:appID/comments/:commentID/resolve — 解决评论 */
|
|
21
|
+
async function resolveComment(appID, commentID) {
|
|
22
|
+
const url = `/api/v1/studio/innerapi/apps/${encodeURIComponent(appID)}/comments/${encodeURIComponent(commentID)}/resolve`;
|
|
23
|
+
await (0, http_1.postInnerApi)(url, undefined, { errPrefix: 'Failed to resolve comment' });
|
|
24
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveComment = exports.getComments = void 0;
|
|
4
|
+
var api_1 = require("./api");
|
|
5
|
+
Object.defineProperty(exports, "getComments", { enumerable: true, get: function () { return api_1.getComments; } });
|
|
6
|
+
Object.defineProperty(exports, "resolveComment", { enumerable: true, get: function () { return api_1.resolveComment; } });
|
package/dist/api/index.js
CHANGED
|
@@ -33,16 +33,18 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.deploy = exports.app = exports.observability = exports.db = exports.file = exports.plugin = void 0;
|
|
36
|
+
exports.comment = exports.deploy = exports.app = exports.observability = exports.db = exports.file = exports.plugin = void 0;
|
|
37
37
|
const _plugin = __importStar(require("../api/plugin/index"));
|
|
38
38
|
const _file = __importStar(require("../api/file/index"));
|
|
39
39
|
const _db = __importStar(require("../api/db/index"));
|
|
40
40
|
const _observability = __importStar(require("../api/observability/index"));
|
|
41
41
|
const _app = __importStar(require("../api/app/index"));
|
|
42
42
|
const _deploy = __importStar(require("../api/deploy/index"));
|
|
43
|
+
const _comment = __importStar(require("../api/comment/index"));
|
|
43
44
|
exports.plugin = { ..._plugin };
|
|
44
45
|
exports.file = { ..._file };
|
|
45
46
|
exports.db = { ..._db };
|
|
46
47
|
exports.observability = { ..._observability };
|
|
47
48
|
exports.app = { ..._app };
|
|
48
49
|
exports.deploy = { ..._deploy };
|
|
50
|
+
exports.comment = { ..._comment };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCommentCommands = registerCommentCommands;
|
|
4
|
+
const shared_1 = require("../../../cli/commands/shared");
|
|
5
|
+
const index_1 = require("../../../cli/handlers/comment/index");
|
|
6
|
+
function registerCommentCommands(program) {
|
|
7
|
+
const commentCmd = program
|
|
8
|
+
.command('comment')
|
|
9
|
+
.description('应用评论:查看评论列表、解决评论')
|
|
10
|
+
.usage('<command> [flags]');
|
|
11
|
+
commentCmd.action(() => {
|
|
12
|
+
commentCmd.outputHelp();
|
|
13
|
+
});
|
|
14
|
+
commentCmd.addHelpText('after', `
|
|
15
|
+
作用范围
|
|
16
|
+
操作当前应用的评论。应用上下文:--app-id <id> 或环境变量 MIAODA_APP_ID。
|
|
17
|
+
`);
|
|
18
|
+
const listCmd = commentCmd
|
|
19
|
+
.command('list')
|
|
20
|
+
.description('查看应用评论列表')
|
|
21
|
+
.addOption((0, shared_1.appIdOption)().hideHelp())
|
|
22
|
+
.option('--only-unresolved', '仅返回未解决的评论', false)
|
|
23
|
+
.addHelpText('after', `
|
|
24
|
+
JSON 输出
|
|
25
|
+
{"data": [{"comment_id": "...", "content": "...", "user_id": "...",
|
|
26
|
+
"finish": 0, "resolved": false, "create_time": 1700000000}]}
|
|
27
|
+
|
|
28
|
+
示例
|
|
29
|
+
$ miaoda comment list --json
|
|
30
|
+
$ miaoda comment list --only-unresolved --json
|
|
31
|
+
`);
|
|
32
|
+
listCmd.action((0, shared_1.withHelp)(listCmd, async (rawOpts) => {
|
|
33
|
+
(0, shared_1.rejectCliOverride)(listCmd, 'appId');
|
|
34
|
+
await (0, index_1.handleCommentList)({
|
|
35
|
+
appId: rawOpts.appId,
|
|
36
|
+
onlyUnresolved: rawOpts.onlyUnresolved,
|
|
37
|
+
});
|
|
38
|
+
}));
|
|
39
|
+
const resolveCmd = commentCmd
|
|
40
|
+
.command('resolve')
|
|
41
|
+
.description('把一条评论标记为已解决')
|
|
42
|
+
.argument('<commentID>', '待解决的评论 ID')
|
|
43
|
+
.addOption((0, shared_1.appIdOption)().hideHelp())
|
|
44
|
+
.addHelpText('after', `
|
|
45
|
+
JSON 输出
|
|
46
|
+
{"data": {"comment_id": "...", "resolved": true}}
|
|
47
|
+
|
|
48
|
+
示例
|
|
49
|
+
$ miaoda comment resolve 1703677660120110076 --json
|
|
50
|
+
`);
|
|
51
|
+
resolveCmd.action((0, shared_1.withHelp)(resolveCmd, async (commentId, rawOpts) => {
|
|
52
|
+
(0, shared_1.rejectCliOverride)(resolveCmd, 'appId');
|
|
53
|
+
await (0, index_1.handleCommentResolve)(commentId, { appId: rawOpts.appId });
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
@@ -9,7 +9,8 @@ const index_4 = require("../../cli/commands/app/index");
|
|
|
9
9
|
const index_5 = require("../../cli/commands/deploy/index");
|
|
10
10
|
const modern_1 = require("../../cli/commands/deploy/modern");
|
|
11
11
|
const index_6 = require("../../cli/commands/skills/index");
|
|
12
|
-
const index_7 = require("../../cli/commands/
|
|
12
|
+
const index_7 = require("../../cli/commands/comment/index");
|
|
13
|
+
const index_8 = require("../../cli/commands/registry/index");
|
|
13
14
|
// scene 跟 dispatcher(MIAODA_APP_TYPE)同语义层级 —— app 业务类型维度,
|
|
14
15
|
// 对齐后端 devops app_common.AppType 枚举:
|
|
15
16
|
// 3 = AppType_APPLICATION(全栈应用,当前仅 nestjs-react-fullstack 一个 stack)
|
|
@@ -41,11 +42,13 @@ const SCENE_REGISTRARS = {
|
|
|
41
42
|
(0, index_1.registerFileCommands)(p);
|
|
42
43
|
(0, index_3.registerObservabilityCommands)(p);
|
|
43
44
|
(0, index_6.registerSkillsCommands)(p);
|
|
45
|
+
(0, index_7.registerCommentCommands)(p);
|
|
44
46
|
},
|
|
45
47
|
modern: (p) => {
|
|
46
48
|
(0, index_4.registerAppCommands)(p, { includeInit: true });
|
|
47
49
|
(0, modern_1.registerDeployCommandsModern)(p);
|
|
48
50
|
(0, index_6.registerSkillsCommands)(p);
|
|
51
|
+
(0, index_7.registerCommentCommands)(p);
|
|
49
52
|
},
|
|
50
53
|
// application scene(AppType_APPLICATION=3):
|
|
51
54
|
// 在 default 命令集基础上加 skills(按 meta.json.stack 拉对应 stack 技能)
|
|
@@ -57,6 +60,7 @@ const SCENE_REGISTRARS = {
|
|
|
57
60
|
(0, index_1.registerFileCommands)(p);
|
|
58
61
|
(0, index_3.registerObservabilityCommands)(p);
|
|
59
62
|
(0, index_6.registerSkillsCommands)(p);
|
|
63
|
+
(0, index_7.registerCommentCommands)(p);
|
|
60
64
|
},
|
|
61
65
|
// design scene(AppType_DESIGN=4):design-stack 仅 SSR 渲染、无后端业务逻辑、
|
|
62
66
|
// 无数据库、无 UGC 文件。命令集裁掉 db / file,保留 deploy / observability / app(init) / skills。
|
|
@@ -65,6 +69,7 @@ const SCENE_REGISTRARS = {
|
|
|
65
69
|
(0, index_5.registerDeployCommands)(p);
|
|
66
70
|
(0, index_3.registerObservabilityCommands)(p);
|
|
67
71
|
(0, index_6.registerSkillsCommands)(p);
|
|
72
|
+
(0, index_7.registerCommentCommands)(p);
|
|
68
73
|
},
|
|
69
74
|
// design-html scene(AppType_DESIGN_HTML=8):buildless 静态 HTML,
|
|
70
75
|
// 命令集与 modern 一致(app init/sync + modern 拆分版 deploy + skills),不挂 db/file/observability。
|
|
@@ -73,7 +78,8 @@ const SCENE_REGISTRARS = {
|
|
|
73
78
|
(0, index_4.registerAppCommands)(p, { includeInit: true });
|
|
74
79
|
(0, modern_1.registerDeployCommandsModern)(p);
|
|
75
80
|
(0, index_6.registerSkillsCommands)(p);
|
|
76
|
-
(0,
|
|
81
|
+
(0, index_8.registerRegistryCommands)(p);
|
|
82
|
+
(0, index_7.registerCommentCommands)(p);
|
|
77
83
|
},
|
|
78
84
|
};
|
|
79
85
|
function readEnv(name) {
|
|
@@ -80,10 +80,22 @@ function registerRegistryAdd(parent) {
|
|
|
80
80
|
- skip-by-disk:目标文件已存在默认跳过;--overwrite 才覆盖
|
|
81
81
|
- 不写任何安装记账文件(项目文件树即状态)
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
输出(pretty,默认)
|
|
84
|
+
registry@<ver>
|
|
85
|
+
added: <落地 basename 逗号列表> # 含 Depends 闭包全部落地文件
|
|
86
|
+
skipped: <逗号列表> # 仅有跳过时出现
|
|
87
|
+
dry-run: true (no files written) # 仅 --dry-run 时出现
|
|
88
|
+
|
|
89
|
+
# <请求条目落地 basename>
|
|
90
|
+
<该条目 USAGE 块原文> # 只列你请求的条目,依赖不占 usage 位
|
|
91
|
+
|
|
92
|
+
JSON 输出(--json)
|
|
93
|
+
{"data": {"registryVersion": "...", "added": [...], "skipped": [...], "dryRun": false,
|
|
94
|
+
"entries": [{"name": "...", "file": "<来源 relPath>", "dest": "<落地 basename>",
|
|
95
|
+
"status": "added|skipped", "usage": "<USAGE 块原文>", "dependsOn": [...]}, ...]}}
|
|
96
|
+
(added / skipped 覆盖依赖闭包全部落地文件;entries 只列**你请求的条目**
|
|
97
|
+
(不含被 Depends 传递拉入的依赖),逐条给 usage / dependsOn,add 完直接读用法。
|
|
98
|
+
请求的条目即使已存在被 skip 也回带 usage,status 标 added / skipped)
|
|
87
99
|
|
|
88
100
|
示例
|
|
89
101
|
$ miaoda registry add deck-slide
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleCommentResolve = exports.handleCommentList = void 0;
|
|
4
|
+
var list_1 = require("./list");
|
|
5
|
+
Object.defineProperty(exports, "handleCommentList", { enumerable: true, get: function () { return list_1.handleCommentList; } });
|
|
6
|
+
var resolve_1 = require("./resolve");
|
|
7
|
+
Object.defineProperty(exports, "handleCommentResolve", { enumerable: true, get: function () { return resolve_1.handleCommentResolve; } });
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleCommentList = handleCommentList;
|
|
37
|
+
const api = __importStar(require("../../../api/index"));
|
|
38
|
+
const shared_1 = require("../../../cli/commands/shared");
|
|
39
|
+
const output_1 = require("../../../utils/output");
|
|
40
|
+
/** 单个内联元素渲染成文本:text_run 出文本、docs_link 出链接、person 出 @user。 */
|
|
41
|
+
function renderElement(el) {
|
|
42
|
+
if (el.text_run?.text)
|
|
43
|
+
return el.text_run.text;
|
|
44
|
+
if (el.docs_link?.url)
|
|
45
|
+
return el.docs_link.url;
|
|
46
|
+
if (el.person?.user_id)
|
|
47
|
+
return `@${el.person.user_id}`;
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
/** 一条 reply:正文(各 element 拼接)+ extra 图片数量标注(extra.image_list)。 */
|
|
51
|
+
function renderReply(r) {
|
|
52
|
+
const body = (r.content?.elements ?? []).map(renderElement).join('').trim();
|
|
53
|
+
const images = r.extra?.image_list;
|
|
54
|
+
const imageCount = Array.isArray(images) ? images.length : 0;
|
|
55
|
+
const parts = [body, imageCount > 0 ? `[图片×${String(imageCount)}]` : ''].filter((p) => p.length > 0);
|
|
56
|
+
return parts.join(' ');
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* pretty 的 content 列:把所有 reply 渲染后用 " | " 拼接。含 @人 / 云文档链接 / 图片标注等
|
|
60
|
+
* extra 信息。仅用于 pretty 概览;JSON 模式原样透传完整 reply_list。
|
|
61
|
+
*/
|
|
62
|
+
function commentText(c) {
|
|
63
|
+
return (c.reply_list?.replies ?? [])
|
|
64
|
+
.map(renderReply)
|
|
65
|
+
.filter((t) => t.length > 0)
|
|
66
|
+
.join(' | ');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* pretty 概览列;JSON 模式忽略 schema,原样输出完整评论结构(与 openapi file.comment 一致)。
|
|
70
|
+
* strict:pretty 只渲染这些列,不把 reply_list / quote 等嵌套字段追加成额外列。
|
|
71
|
+
*/
|
|
72
|
+
const listSchema = {
|
|
73
|
+
strict: true,
|
|
74
|
+
columns: [
|
|
75
|
+
{ key: 'comment_id', label: 'id' },
|
|
76
|
+
{ key: 'is_solved', label: 'solved' },
|
|
77
|
+
{ key: 'user_id', label: 'user' },
|
|
78
|
+
{ key: 'create_time', label: 'time', format: output_1.fmt.sec() },
|
|
79
|
+
{
|
|
80
|
+
key: 'content',
|
|
81
|
+
label: 'content',
|
|
82
|
+
derive: (row) => commentText(row),
|
|
83
|
+
format: output_1.fmt.truncate(80),
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
async function handleCommentList(opts) {
|
|
88
|
+
const appId = (0, shared_1.resolveAppId)({ appId: opts.appId });
|
|
89
|
+
const comments = await api.comment.getComments(appId, opts.onlyUnresolved ?? false);
|
|
90
|
+
// data 原样透传完整评论结构(含 reply_list / replies / reactions …),与 openapi 保持一致。
|
|
91
|
+
(0, output_1.emit)({ data: comments }, listSchema);
|
|
92
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleCommentResolve = handleCommentResolve;
|
|
37
|
+
const api = __importStar(require("../../../api/index"));
|
|
38
|
+
const shared_1 = require("../../../cli/commands/shared");
|
|
39
|
+
const output_1 = require("../../../utils/output");
|
|
40
|
+
async function handleCommentResolve(commentId, opts) {
|
|
41
|
+
const appId = (0, shared_1.resolveAppId)({ appId: opts.appId });
|
|
42
|
+
await api.comment.resolveComment(appId, commentId);
|
|
43
|
+
(0, output_1.emitOk)({ comment_id: commentId, resolved: true });
|
|
44
|
+
}
|
|
@@ -9,7 +9,6 @@ const index_1 = require("../../../services/registry/index");
|
|
|
9
9
|
const shared_1 = require("./shared");
|
|
10
10
|
const error_1 = require("../../../utils/error");
|
|
11
11
|
const output_1 = require("../../../utils/output");
|
|
12
|
-
const logger_1 = require("../../../utils/logger");
|
|
13
12
|
/**
|
|
14
13
|
* miaoda registry add <name...> [--overwrite] [--dry-run] [--dir <path>] [--version <ver>]
|
|
15
14
|
*
|
|
@@ -35,18 +34,62 @@ async function handleRegistryAdd(opts) {
|
|
|
35
34
|
overwrite: opts.overwrite === true,
|
|
36
35
|
dryRun: opts.dryRun === true,
|
|
37
36
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
// entries:**只列用户请求的条目**(opts.names 命中的),给它们的 usage / dependsOn,
|
|
38
|
+
// 让 Agent add 完直接拿到用法、无需再 `registry list`。被 Depends 传递拉进来的依赖是
|
|
39
|
+
// "管道"(照常在 added/skipped 里落地),不占 usage 位。请求的条目即使已存在被 skip
|
|
40
|
+
// 也回带 usage(status=skipped,Agent 借此判断磁盘上是 registry 版还是自己改过的旧版)。
|
|
41
|
+
const requestedRelPaths = new Set();
|
|
42
|
+
for (const token of opts.names) {
|
|
43
|
+
for (const e of plan.entries) {
|
|
44
|
+
if ((0, index_1.tokenMatches)(e, token))
|
|
45
|
+
requestedRelPaths.add(e.relPath);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// relPath → 落地的 PlannedFile(拿 dest / 落地状态)
|
|
49
|
+
const fileByRelPath = new Map(plan.files.map((f) => [f.srcRelPath, f]));
|
|
50
|
+
const addedSet = new Set(result.added);
|
|
51
|
+
const skippedSet = new Set(result.skipped);
|
|
52
|
+
const entries = plan.entries
|
|
53
|
+
.filter((e) => requestedRelPaths.has(e.relPath))
|
|
54
|
+
.map((e) => {
|
|
55
|
+
const f = fileByRelPath.get(e.relPath);
|
|
56
|
+
const dest = f?.dest ?? e.relPath.split('/').pop() ?? e.relPath;
|
|
57
|
+
const status = skippedSet.has(dest) && !addedSet.has(dest) ? 'skipped' : 'added';
|
|
58
|
+
return {
|
|
59
|
+
name: e.name,
|
|
60
|
+
file: e.relPath,
|
|
61
|
+
dest,
|
|
62
|
+
status,
|
|
63
|
+
usage: e.usage,
|
|
64
|
+
dependsOn: e.dependsOn,
|
|
65
|
+
};
|
|
49
66
|
});
|
|
67
|
+
// 只透出对 add 完的 Agent 可操作的字段:项目里实际多了什么(added)、什么没动(skipped)、
|
|
68
|
+
// 请求条目怎么用(entries)。requested(纯回显)、resolved(包内诊断路径)不透出。
|
|
69
|
+
const data = {
|
|
70
|
+
registryVersion: reg.version,
|
|
71
|
+
added: result.added,
|
|
72
|
+
skipped: result.skipped,
|
|
73
|
+
dryRun: opts.dryRun === true,
|
|
74
|
+
entries,
|
|
75
|
+
};
|
|
76
|
+
if ((0, output_1.isJsonMode)()) {
|
|
77
|
+
(0, output_1.emit)({ data });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// pretty 是 Agent 不加 --json 时的默认载荷,也要对 AI 友好:信息量与 JSON 对齐,
|
|
81
|
+
// 但换成稳定 label + 逗号列表(无 JSON 数组、无 TTY 截断、空/默认值不打印),
|
|
82
|
+
// summary 在前、各请求条目的 USAGE 块原文在后。整体走一次纯字符串 emit(不进 key-value 渲染)。
|
|
83
|
+
const summaryLines = [`registry@${reg.version}`];
|
|
84
|
+
if (opts.dryRun === true)
|
|
85
|
+
summaryLines.push('dry-run: true (no files written)');
|
|
86
|
+
if (result.added.length > 0)
|
|
87
|
+
summaryLines.push(`added: ${result.added.join(', ')}`);
|
|
88
|
+
if (result.skipped.length > 0)
|
|
89
|
+
summaryLines.push(`skipped: ${result.skipped.join(', ')}`);
|
|
90
|
+
const blocks = entries.filter((e) => e.usage !== '').map((e) => `# ${e.dest}\n${e.usage}`);
|
|
91
|
+
const parts = [summaryLines.join('\n'), ...blocks];
|
|
92
|
+
(0, output_1.emit)(parts.join('\n\n'));
|
|
50
93
|
}
|
|
51
94
|
finally {
|
|
52
95
|
reg.cleanup();
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.buildDesignOutput = buildDesignOutput;
|
|
7
|
+
exports.cleanDesignDist = cleanDesignDist;
|
|
7
8
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
10
|
const error_1 = require("../../../../utils/error");
|
|
@@ -39,3 +40,10 @@ function buildDesignOutput(opts) {
|
|
|
39
40
|
throw new error_1.AppError('DEPLOY_BUILD_FAILED', `design build failed: ${err.message}`);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* 删除 <projectDir>/dist(本地构建产物)。幂等:不存在也不报错(force)。
|
|
45
|
+
* design 部署收尾调用,部署动作结束后不在用户项目里留产物。
|
|
46
|
+
*/
|
|
47
|
+
function cleanDesignDist(projectDir) {
|
|
48
|
+
node_fs_1.default.rmSync(node_path_1.default.join(projectDir, constants_1.DIST_DIR), { recursive: true, force: true });
|
|
49
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.savePluginInstances = exports.LocalReleaseStatus = exports.finalizeLocalRelease = exports.createLocalRelease = exports.uploadArtifacts = exports.uploadDesignArtifacts = exports.buildDesignOutput = exports.runBuild = exports.preRelease = exports.prepareDeployContext = void 0;
|
|
3
|
+
exports.savePluginInstances = exports.LocalReleaseStatus = exports.finalizeLocalRelease = exports.createLocalRelease = exports.uploadArtifacts = exports.uploadDesignArtifacts = exports.cleanDesignDist = exports.buildDesignOutput = exports.runBuild = exports.preRelease = exports.prepareDeployContext = void 0;
|
|
4
4
|
var context_1 = require("./context");
|
|
5
5
|
Object.defineProperty(exports, "prepareDeployContext", { enumerable: true, get: function () { return context_1.prepareDeployContext; } });
|
|
6
6
|
var pre_release_1 = require("./pre-release");
|
|
@@ -9,6 +9,7 @@ var build_1 = require("./build");
|
|
|
9
9
|
Object.defineProperty(exports, "runBuild", { enumerable: true, get: function () { return build_1.runBuild; } });
|
|
10
10
|
var design_build_1 = require("./design-build");
|
|
11
11
|
Object.defineProperty(exports, "buildDesignOutput", { enumerable: true, get: function () { return design_build_1.buildDesignOutput; } });
|
|
12
|
+
Object.defineProperty(exports, "cleanDesignDist", { enumerable: true, get: function () { return design_build_1.cleanDesignDist; } });
|
|
12
13
|
var design_upload_1 = require("./design-upload");
|
|
13
14
|
Object.defineProperty(exports, "uploadDesignArtifacts", { enumerable: true, get: function () { return design_upload_1.uploadDesignArtifacts; } });
|
|
14
15
|
var upload_1 = require("./upload");
|
|
@@ -20,28 +20,37 @@ async function designLocalPublishPipeline(opts) {
|
|
|
20
20
|
throw new error_1.AppError('DEPLOY_PRE_RELEASE_DATA_MISSING', 'preRelease did not return a `data` map — backend tcc may not be configured for current template_key');
|
|
21
21
|
}
|
|
22
22
|
const data = pre.data;
|
|
23
|
-
|
|
24
|
-
(0, index_1.buildDesignOutput)({ projectDir: ctx.projectDir });
|
|
25
|
-
}
|
|
26
|
-
(0, logger_1.log)('deploy', 'Creating local release...');
|
|
27
|
-
const release = await (0, index_1.createLocalRelease)(ctx.appId, pre.version);
|
|
23
|
+
// dist 是本地构建产物,部署动作结束(无论成败)都清掉,不在用户项目里留产物。
|
|
28
24
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
await (0, index_1.
|
|
34
|
-
|
|
25
|
+
if (!opts.skipBuild) {
|
|
26
|
+
(0, index_1.buildDesignOutput)({ projectDir: ctx.projectDir });
|
|
27
|
+
}
|
|
28
|
+
(0, logger_1.log)('deploy', 'Creating local release...');
|
|
29
|
+
const release = await (0, index_1.createLocalRelease)(ctx.appId, pre.version, {
|
|
30
|
+
checkPointVersion: opts.checkPointVersion,
|
|
31
|
+
commitID: opts.commitID,
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
await (0, index_1.uploadDesignArtifacts)({ projectDir: ctx.projectDir, data });
|
|
35
|
+
await (0, index_1.finalizeLocalRelease)(ctx.appId, release.releaseID, index_1.LocalReleaseStatus.Finished);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
await (0, index_1.finalizeLocalRelease)(ctx.appId, release.releaseID, index_1.LocalReleaseStatus.Failed);
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
if (release.onlineUrl !== undefined && release.onlineUrl !== '') {
|
|
42
|
+
(0, spark_meta_1.writeSparkMeta)(ctx.projectDir, { appUrl: release.onlineUrl });
|
|
43
|
+
}
|
|
44
|
+
(0, logger_1.log)('deploy', 'Deployed successfully');
|
|
45
|
+
return {
|
|
46
|
+
appId: ctx.appId,
|
|
47
|
+
version: pre.version,
|
|
48
|
+
url: release.onlineUrl ?? '',
|
|
49
|
+
releaseID: release.releaseID,
|
|
50
|
+
preReleaseID: pre.preReleaseID,
|
|
51
|
+
};
|
|
35
52
|
}
|
|
36
|
-
|
|
37
|
-
(0,
|
|
53
|
+
finally {
|
|
54
|
+
(0, index_1.cleanDesignDist)(ctx.projectDir);
|
|
38
55
|
}
|
|
39
|
-
(0, logger_1.log)('deploy', 'Deployed successfully');
|
|
40
|
-
return {
|
|
41
|
-
appId: ctx.appId,
|
|
42
|
-
version: pre.version,
|
|
43
|
-
url: release.onlineUrl ?? '',
|
|
44
|
-
releaseID: release.releaseID,
|
|
45
|
-
preReleaseID: pre.preReleaseID,
|
|
46
|
-
};
|
|
47
56
|
}
|
package/dist/utils/http.js
CHANGED
|
@@ -64,7 +64,7 @@ function createClient(opts) {
|
|
|
64
64
|
* 默认灰度泳道。当前 miaoda CLI 接入的新接口(modern deploy 等)只在该泳道生效,
|
|
65
65
|
* 缺省走这个。MIAODA_CANARY_HEADER 可显式覆盖;设为空字符串则去掉头。
|
|
66
66
|
*/
|
|
67
|
-
const DEFAULT_CANARY_HEADER = '
|
|
67
|
+
const DEFAULT_CANARY_HEADER = 'boe_miaoda_ccm';
|
|
68
68
|
/**
|
|
69
69
|
* 注入 x-tt-env 小流量头:env 显式设值 > DEFAULT_CANARY_HEADER。
|
|
70
70
|
*
|