@lark-apaas/miaoda-cli 0.1.1 → 0.1.2-alpha.b2b5ae5

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.
Files changed (64) hide show
  1. package/dist/api/app/api.js +25 -0
  2. package/dist/api/app/index.js +15 -0
  3. package/dist/api/app/schemas.js +79 -0
  4. package/dist/api/app/types.js +58 -0
  5. package/dist/api/db/api.js +83 -6
  6. package/dist/api/db/client.js +40 -29
  7. package/dist/api/db/parsers.js +33 -20
  8. package/dist/api/db/sql-keywords.js +123 -0
  9. package/dist/api/deploy/api.js +60 -0
  10. package/dist/api/deploy/index.js +16 -0
  11. package/dist/api/deploy/schemas.js +103 -0
  12. package/dist/api/deploy/types.js +22 -0
  13. package/dist/api/file/api.js +78 -24
  14. package/dist/api/file/client.js +1 -5
  15. package/dist/api/file/parsers.js +1 -5
  16. package/dist/api/index.js +7 -1
  17. package/dist/api/observability/api.js +52 -0
  18. package/dist/api/observability/index.js +16 -0
  19. package/dist/api/observability/schemas.js +39 -0
  20. package/dist/api/observability/types.js +27 -0
  21. package/dist/api/plugin/api.js +8 -3
  22. package/dist/cli/commands/app/index.js +62 -0
  23. package/dist/cli/commands/db/index.js +1 -0
  24. package/dist/cli/commands/deploy/index.js +139 -0
  25. package/dist/cli/commands/index.js +6 -0
  26. package/dist/cli/commands/observability/index.js +227 -0
  27. package/dist/cli/commands/plugin/index.js +18 -6
  28. package/dist/cli/commands/shared.js +38 -6
  29. package/dist/cli/handlers/app/get.js +48 -0
  30. package/dist/cli/handlers/app/index.js +7 -0
  31. package/dist/cli/handlers/app/update.js +59 -0
  32. package/dist/cli/handlers/db/data.js +22 -2
  33. package/dist/cli/handlers/db/schema.js +22 -8
  34. package/dist/cli/handlers/db/sql.js +304 -16
  35. package/dist/cli/handlers/deploy/deploy.js +83 -0
  36. package/dist/cli/handlers/deploy/error-log.js +61 -0
  37. package/dist/cli/handlers/deploy/get.js +70 -0
  38. package/dist/cli/handlers/deploy/helpers.js +41 -0
  39. package/dist/cli/handlers/deploy/history.js +70 -0
  40. package/dist/cli/handlers/deploy/index.js +14 -0
  41. package/dist/cli/handlers/deploy/polling.js +139 -0
  42. package/dist/cli/handlers/file/cp.js +39 -17
  43. package/dist/cli/handlers/file/ls.js +1 -3
  44. package/dist/cli/handlers/file/rm.js +4 -3
  45. package/dist/cli/handlers/observability/analytics.js +189 -0
  46. package/dist/cli/handlers/observability/helpers.js +66 -0
  47. package/dist/cli/handlers/observability/index.js +12 -0
  48. package/dist/cli/handlers/observability/log.js +94 -0
  49. package/dist/cli/handlers/observability/metric.js +208 -0
  50. package/dist/cli/handlers/observability/trace.js +102 -0
  51. package/dist/cli/handlers/plugin/plugin-local.js +23 -9
  52. package/dist/cli/handlers/plugin/plugin.js +21 -7
  53. package/dist/cli/help.js +5 -2
  54. package/dist/utils/colors.js +98 -0
  55. package/dist/utils/devops-error.js +28 -0
  56. package/dist/utils/error.js +11 -0
  57. package/dist/utils/fuzzy-match.js +91 -0
  58. package/dist/utils/git.js +29 -0
  59. package/dist/utils/http.js +32 -0
  60. package/dist/utils/index.js +13 -1
  61. package/dist/utils/output.js +397 -12
  62. package/dist/utils/render.js +61 -41
  63. package/dist/utils/time.js +132 -0
  64. package/package.json +16 -6
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerDeployCommands = registerDeployCommands;
4
+ const commander_1 = require("commander");
5
+ const shared_1 = require("../../../cli/commands/shared");
6
+ const index_1 = require("../../../cli/handlers/deploy/index");
7
+ const COMMON_TIME_HELP = `
8
+ 时间格式:
9
+ - 相对时间:1h(1 小时前)、2d(2 天前)、1w(1 周前)、30m(30 分钟前)
10
+ - 日期:2026-04-01(按当日 00:00:00 UTC)
11
+ - ISO 8601:2026-04-01T10:00:00Z
12
+ `;
13
+ function registerDeployCommands(program) {
14
+ // PRD:`miaoda deploy` 自身即为触发发布;get / history / error-log 是子命令
15
+ const deployCmd = program
16
+ .command("deploy")
17
+ .description("触发发布;支持 --wait 阻塞到终态。子命令:get / history / error-log")
18
+ .addOption((0, shared_1.appIdOption)().hideHelp())
19
+ .addOption((0, shared_1.branchOption)().hideHelp())
20
+ .option("--wait", "阻塞直到流水线终态", false)
21
+ .option("--timeout <sec>", "--wait 最长等待秒数(默认 300)", parseTimeout, 300)
22
+ .addHelpText("after", `
23
+ JSON 输出
24
+ 不带 --wait:{"data": {"pipelineTaskID": "..."}}(pipelineTaskID 即 deploy-id)
25
+ 带 --wait:data 额外包含 detail(pipeline 终态)
26
+
27
+ 示例
28
+ $ miaoda deploy
29
+ $ miaoda deploy --wait --timeout 600
30
+ $ miaoda deploy get 12345
31
+ $ miaoda deploy history --status failed
32
+ `);
33
+ deployCmd.action((0, shared_1.withHelp)(deployCmd, async (rawOpts) => {
34
+ (0, shared_1.rejectCliOverride)(deployCmd, "appId", "branch");
35
+ await (0, index_1.handleDeploy)({
36
+ appId: rawOpts.appId,
37
+ branch: rawOpts.branch,
38
+ wait: rawOpts.wait,
39
+ timeout: rawOpts.timeout,
40
+ });
41
+ }));
42
+ registerDeployGet(deployCmd);
43
+ registerDeployHistory(deployCmd);
44
+ registerDeployErrorLog(deployCmd);
45
+ }
46
+ function registerDeployGet(parent) {
47
+ const cmd = parent
48
+ .command("get")
49
+ .description("查看指定发布单的详情")
50
+ .argument("<deploy-id>", "发布单 ID")
51
+ .addOption((0, shared_1.appIdOption)().hideHelp())
52
+ .addHelpText("after", `
53
+ JSON 输出
54
+ {"data": {"ID": ..., "status": ..., "creator": "...", "createdAt": ..., "updatedAt": ..., ...}, "next_cursor": null, "has_more": false}
55
+ ID 即 deploy-id(== pipelineTaskID)
56
+
57
+ 示例
58
+ $ miaoda deploy get 12345
59
+ `);
60
+ cmd.action((0, shared_1.withHelp)(cmd, async (deployId, rawOpts) => {
61
+ (0, shared_1.rejectCliOverride)(cmd, "appId");
62
+ await (0, index_1.handleDeployGet)({
63
+ deployId,
64
+ appId: rawOpts.appId,
65
+ });
66
+ }));
67
+ }
68
+ function registerDeployHistory(parent) {
69
+ const cmd = parent
70
+ .command("history")
71
+ .description("查询发布历史(按时间倒序,分页)")
72
+ .addOption((0, shared_1.appIdOption)().hideHelp())
73
+ .addOption(new commander_1.Option("--status <status>", "状态过滤(pipeline 节点状态)").choices([
74
+ "todo",
75
+ "running",
76
+ "success",
77
+ "failed",
78
+ "canceled",
79
+ "hold_on",
80
+ ]))
81
+ .option("--since <time>", "起始时间")
82
+ .option("--until <time>", "截止时间")
83
+ .option("--limit <n>", "返回条数上限(1~100)", parseLimit, 50)
84
+ .option("--cursor <token>", "下一页游标")
85
+ .addHelpText("after", `${COMMON_TIME_HELP}
86
+ JSON 输出
87
+ {"data": [...], "next_cursor": "...", "has_more": true|false}
88
+
89
+ 示例
90
+ $ miaoda deploy history --status failed
91
+ $ miaoda deploy history --since 7d
92
+ `);
93
+ cmd.action((0, shared_1.withHelp)(cmd, async (rawOpts) => {
94
+ (0, shared_1.rejectCliOverride)(cmd, "appId");
95
+ await (0, index_1.handleDeployHistory)({
96
+ appId: rawOpts.appId,
97
+ status: rawOpts.status,
98
+ since: rawOpts.since,
99
+ until: rawOpts.until,
100
+ limit: rawOpts.limit,
101
+ cursor: rawOpts.cursor,
102
+ });
103
+ }));
104
+ }
105
+ function registerDeployErrorLog(parent) {
106
+ const cmd = parent
107
+ .command("error-log")
108
+ .description("查询指定发布的错误日志")
109
+ .argument("<deploy-id>", "发布单 ID")
110
+ .addOption((0, shared_1.appIdOption)().hideHelp())
111
+ .addHelpText("after", `
112
+ JSON 输出
113
+ {"data": [{"jobID": ..., "componentName": ..., "errorMsg": ...}], "next_cursor": null, "has_more": false}
114
+
115
+ 示例
116
+ $ miaoda deploy error-log 12345 --json
117
+ `);
118
+ cmd.action((0, shared_1.withHelp)(cmd, async (deployId, rawOpts) => {
119
+ (0, shared_1.rejectCliOverride)(cmd, "appId");
120
+ await (0, index_1.handleDeployErrorLog)({
121
+ deployId,
122
+ appId: rawOpts.appId,
123
+ });
124
+ }));
125
+ }
126
+ function parseLimit(value) {
127
+ const n = Number(value);
128
+ if (!Number.isFinite(n)) {
129
+ throw new Error(`--limit 必须是数字,收到 '${value}'`);
130
+ }
131
+ return n;
132
+ }
133
+ function parseTimeout(value) {
134
+ const n = Number(value);
135
+ if (!Number.isFinite(n) || n <= 0) {
136
+ throw new Error(`--timeout 必须是正数,收到 '${value}'`);
137
+ }
138
+ return n;
139
+ }
@@ -4,8 +4,14 @@ exports.registerCommands = registerCommands;
4
4
  const index_1 = require("../../cli/commands/plugin/index");
5
5
  const index_2 = require("../../cli/commands/file/index");
6
6
  const index_3 = require("../../cli/commands/db/index");
7
+ const index_4 = require("../../cli/commands/observability/index");
8
+ const index_5 = require("../../cli/commands/app/index");
9
+ const index_6 = require("../../cli/commands/deploy/index");
7
10
  function registerCommands(program) {
8
11
  (0, index_1.registerPluginCommands)(program);
9
12
  (0, index_2.registerFileCommands)(program);
10
13
  (0, index_3.registerDbCommands)(program);
14
+ (0, index_4.registerObservabilityCommands)(program);
15
+ (0, index_5.registerAppCommands)(program);
16
+ (0, index_6.registerDeployCommands)(program);
11
17
  }
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerObservabilityCommands = registerObservabilityCommands;
4
+ const commander_1 = require("commander");
5
+ const shared_1 = require("../../../cli/commands/shared");
6
+ const index_1 = require("../../../cli/handlers/observability/index");
7
+ const COMMON_TIME_HELP = `
8
+ 时间格式:
9
+ - 相对时间:1h(1 小时前)、2d(2 天前)、1w(1 周前)、30m(30 分钟前)
10
+ - 日期:2026-04-01(按当日 00:00:00 UTC)
11
+ - ISO 8601:2026-04-01T10:00:00Z
12
+ `;
13
+ function registerObservabilityCommands(program) {
14
+ const obCmd = program
15
+ .command("observability")
16
+ .description("可观测性:查询线上日志、链路、监控指标、运营指标");
17
+ obCmd.action(() => {
18
+ obCmd.outputHelp();
19
+ });
20
+ obCmd.addHelpText("after", `
21
+ 作用范围
22
+ 仅供 Agent 在妙搭沙箱内调用,查询当前应用的线上观测数据。所有命令为只读。
23
+ 应用上下文:--app-id <id> 或环境变量 MIAODA_APP_ID。
24
+
25
+ 应用环境
26
+ log/trace 命令需要 --env <dev|online>,默认 online,可设置 MIAODA_APP_ENV 覆盖。
27
+ metric/analytics 不需要 --env。
28
+ `);
29
+ registerLog(obCmd);
30
+ registerTrace(obCmd);
31
+ registerMetric(obCmd);
32
+ registerAnalytics(obCmd);
33
+ }
34
+ // ── log ──
35
+ function registerLog(parent) {
36
+ const cmd = parent
37
+ .command("log")
38
+ .description("查询线上运行日志(按时间倒序,分页)")
39
+ .addOption((0, shared_1.appIdOption)().hideHelp())
40
+ .addOption(new commander_1.Option("--level <level>", "日志级别").choices(["DEBUG", "INFO", "WARN", "ERROR"]))
41
+ .option("--since <time>", "开始时间")
42
+ .option("--until <time>", "截止时间")
43
+ .option("--trace-id <id>", "按 trace ID 过滤")
44
+ .option("--grep <pattern>", "按关键字模糊搜索 body")
45
+ .option("--module <name>", "按模块名过滤")
46
+ .option("--user-id <user-id>", "按触发用户 ID 过滤")
47
+ .option("--page <path>", "按页面路径过滤")
48
+ .option("--api <path>", "按接口路径过滤")
49
+ .option("--min-duration <ms>", "最小耗时过滤(毫秒)")
50
+ .option("--max-duration <ms>", "最大耗时过滤(毫秒)")
51
+ .option("--limit <n>", "返回条数上限(1~100)", parseLimit, 50)
52
+ .option("--cursor <token>", "下一页游标,从上一次返回的 next_cursor 取值")
53
+ .addHelpText("after", `${COMMON_TIME_HELP}
54
+ JSON 输出
55
+ {"data": [...], "next_cursor": "...", "has_more": true|false}
56
+
57
+ 示例
58
+ $ miaoda observability log --since 1h --level error --json
59
+ $ miaoda observability log --trace-id 140ebb5ac9b... --json
60
+ $ miaoda observability log --api /api/orders --min-duration 200 --json
61
+ `);
62
+ cmd.action((0, shared_1.withHelp)(cmd, async (rawOpts) => {
63
+ (0, shared_1.rejectCliOverride)(cmd, "appId");
64
+ await (0, index_1.handleObservabilityLog)({
65
+ appId: rawOpts.appId,
66
+ level: rawOpts.level,
67
+ since: rawOpts.since,
68
+ until: rawOpts.until,
69
+ traceId: rawOpts.traceId,
70
+ grep: rawOpts.grep,
71
+ module: rawOpts.module,
72
+ userId: rawOpts.userId,
73
+ page: rawOpts.page,
74
+ api: rawOpts.api,
75
+ minDuration: rawOpts.minDuration,
76
+ maxDuration: rawOpts.maxDuration,
77
+ limit: rawOpts.limit,
78
+ cursor: rawOpts.cursor,
79
+ });
80
+ }));
81
+ }
82
+ // ── trace ──
83
+ function registerTrace(parent) {
84
+ const traceCmd = parent.command("trace").description("链路追踪:列表 / 详情");
85
+ traceCmd.action(() => {
86
+ traceCmd.outputHelp();
87
+ });
88
+ const listCmd = traceCmd
89
+ .command("list")
90
+ .description("查询线上链路列表(按链路时间倒序,分页)")
91
+ .addOption((0, shared_1.appIdOption)().hideHelp())
92
+ .option("--since <time>", "开始时间")
93
+ .option("--until <time>", "截止时间")
94
+ .option("--trace-id <id>", "按 trace ID 过滤")
95
+ .option("--root-span <span-name>", "按入口节点关键词过滤")
96
+ .option("--user-id <user-id>", "按触发用户 ID 过滤")
97
+ .option("--limit <n>", "返回条数上限(1~100)", parseLimit, 50)
98
+ .option("--cursor <token>", "下一页游标")
99
+ .addHelpText("after", `${COMMON_TIME_HELP}
100
+ JSON 输出
101
+ {"data": [...], "next_cursor": "...", "has_more": true|false}
102
+
103
+ 示例
104
+ $ miaoda observability trace list --since 1h --json
105
+ $ miaoda observability trace list --root-span api-gateway --limit 20 --json
106
+ `);
107
+ listCmd.action((0, shared_1.withHelp)(listCmd, async (rawOpts) => {
108
+ (0, shared_1.rejectCliOverride)(listCmd, "appId");
109
+ await (0, index_1.handleObservabilityTraceList)({
110
+ appId: rawOpts.appId,
111
+ since: rawOpts.since,
112
+ until: rawOpts.until,
113
+ traceId: rawOpts.traceId,
114
+ rootSpan: rawOpts.rootSpan,
115
+ userId: rawOpts.userId,
116
+ limit: rawOpts.limit,
117
+ cursor: rawOpts.cursor,
118
+ });
119
+ }));
120
+ const getCmd = traceCmd
121
+ .command("get")
122
+ .description("查询指定链路的完整详情")
123
+ .argument("<trace-id>", "链路 ID")
124
+ .addOption((0, shared_1.appIdOption)().hideHelp())
125
+ .option("--with-log-severity-count", "返回每个 Span 各日志级别的数量", false)
126
+ .addHelpText("after", `
127
+ JSON 输出
128
+ {"data": {"spans": [...], "isBreak": false}}
129
+
130
+ 示例
131
+ $ miaoda observability trace get 140ebb5ac9b55ed50d6ed1090cad4d --json
132
+
133
+ # 报错:链路不存在
134
+ $ miaoda observability trace get not-exist
135
+ Error: Failed to get trace: 500 ...
136
+ hint: 检查 trace-id 是否正确,或链路已超出保留时长
137
+ `);
138
+ getCmd.action((0, shared_1.withHelp)(getCmd, async (traceId, rawOpts) => {
139
+ (0, shared_1.rejectCliOverride)(getCmd, "appId");
140
+ await (0, index_1.handleObservabilityTraceGet)({
141
+ traceId,
142
+ appId: rawOpts.appId,
143
+ withLogSeverityCount: rawOpts.withLogSeverityCount,
144
+ });
145
+ }));
146
+ }
147
+ // ── metric ──
148
+ function registerMetric(parent) {
149
+ const cmd = parent
150
+ .command("metric")
151
+ .description("查询监控指标:requests / latency / cpu / memory")
152
+ .argument("<metric-name>", "指标名:requests | latency | cpu | memory")
153
+ .addOption((0, shared_1.appIdOption)().hideHelp())
154
+ .option("--page <path>", "按页面路径过滤(仅对 requests/latency 生效)")
155
+ .option("--api <path>", "按接口路径过滤(仅对 requests/latency 生效)")
156
+ .option("--series <name>", "过滤图表中的某条线:latency 取 p50/p99;requests 取 total/error;缺省返回所有相关线")
157
+ .option("--since <time>", "开始时间")
158
+ .option("--until <time>", "截止时间")
159
+ .addOption(new commander_1.Option("--down-sample <duration>", "降采样粒度(1m=1分钟 / 1h=1小时 / 1d=1天)")
160
+ .choices(["1m", "1h", "1d"])
161
+ .default("1h"))
162
+ .addHelpText("after", `${COMMON_TIME_HELP}
163
+ JSON 输出
164
+ {"data": [{"metricName": "...", "dimensions": {...}, "dataPoints": [...]}], "next_cursor": null, "has_more": false}
165
+
166
+ 示例
167
+ $ miaoda observability metric latency --since 1h --json
168
+ $ miaoda observability metric latency --since 1h --series p99 --json
169
+ $ miaoda observability metric requests --api /api/users --json
170
+ $ miaoda observability metric cpu --since 1d --down-sample 1d --json
171
+ `);
172
+ cmd.action((0, shared_1.withHelp)(cmd, async (metricName, rawOpts) => {
173
+ (0, shared_1.rejectCliOverride)(cmd, "appId");
174
+ await (0, index_1.handleObservabilityMetric)({
175
+ metricName,
176
+ appId: rawOpts.appId,
177
+ page: rawOpts.page,
178
+ api: rawOpts.api,
179
+ series: rawOpts.series,
180
+ since: rawOpts.since,
181
+ until: rawOpts.until,
182
+ downSample: rawOpts.downSample,
183
+ });
184
+ }));
185
+ }
186
+ // ── analytics ──
187
+ function registerAnalytics(parent) {
188
+ const cmd = parent
189
+ .command("analytics")
190
+ .description("查询运营指标:users(用户数)/ page-view(页面访问)")
191
+ .argument("<analytics-name>", "指标名:users | page-view")
192
+ .addOption((0, shared_1.appIdOption)().hideHelp())
193
+ .option("--page <path>", "按页面路径过滤(仅对 page-view 生效)")
194
+ .option("--series <name>", "过滤图表中的某条线:users 取 active-users/new-users/total-users;page-view 取 all-view/desktop-view/mobile-view;缺省返回所有相关线")
195
+ .option("--since <time>", "开始时间")
196
+ .option("--until <time>", "截止时间")
197
+ .option("--granularity <duration>", "时间粒度:day | week | month", "day")
198
+ .addHelpText("after", `${COMMON_TIME_HELP}
199
+ JSON 输出
200
+ {"data": [{"metricType": "...", "points": [{"timestampNs": "...", "value": ..., "dimensions": {...}}]}], "next_cursor": null, "has_more": false}
201
+
202
+ 示例
203
+ $ miaoda observability analytics users --json # 同时返回 active/new/total 三条线
204
+ $ miaoda observability analytics users --series new-users --since 7d --json
205
+ $ miaoda observability analytics page-view --granularity week --json
206
+ `);
207
+ cmd.action((0, shared_1.withHelp)(cmd, async (analyticsName, rawOpts) => {
208
+ (0, shared_1.rejectCliOverride)(cmd, "appId");
209
+ await (0, index_1.handleObservabilityAnalytics)({
210
+ analyticsName,
211
+ appId: rawOpts.appId,
212
+ env: rawOpts.env,
213
+ page: rawOpts.page,
214
+ series: rawOpts.series,
215
+ since: rawOpts.since,
216
+ until: rawOpts.until,
217
+ granularity: rawOpts.granularity,
218
+ });
219
+ }));
220
+ }
221
+ function parseLimit(value) {
222
+ const n = Number(value);
223
+ if (!Number.isFinite(n)) {
224
+ throw new Error(`--limit 必须是数字,收到 '${value}'`);
225
+ }
226
+ return n;
227
+ }
@@ -58,7 +58,9 @@ JSON 输出
58
58
  Error: Invalid plugin name format: bad-name. Expected: @scope/name or @scope/name@version
59
59
  hint: 示例:@demo/example-plugin 或 @demo/example-plugin@1.2.3
60
60
  `)
61
- .action(async (names) => { await (0, index_1.handlePluginInstall)({ names }); });
61
+ .action(async (names) => {
62
+ await (0, index_1.handlePluginInstall)({ names });
63
+ });
62
64
  pluginCmd
63
65
  .command("update")
64
66
  .description("把已安装插件升级到 latest 版本")
@@ -91,7 +93,9 @@ JSON 输出
91
93
  $ miaoda plugin update @demo/not-installed --json
92
94
  {"updated":[],"skipped":[],"notInstalled":["@demo/not-installed"],"failed":[]}
93
95
  `)
94
- .action(async (names) => { await (0, index_1.handlePluginUpdate)({ names }); });
96
+ .action(async (names) => {
97
+ await (0, index_1.handlePluginUpdate)({ names });
98
+ });
95
99
  pluginCmd
96
100
  .command("remove")
97
101
  .description("从当前项目移除一个已安装的插件")
@@ -115,7 +119,9 @@ JSON 输出
115
119
  Error: Plugin @demo/not-installed is not installed
116
120
  hint: 运行 miaoda plugin list-packages 查看已安装插件
117
121
  `)
118
- .action((name) => { (0, index_1.handlePluginRemove)({ name }); });
122
+ .action((name) => {
123
+ (0, index_1.handlePluginRemove)({ name });
124
+ });
119
125
  pluginCmd
120
126
  .command("init")
121
127
  .description("按 package.json 的 actionPlugins 批量安装所有插件")
@@ -146,7 +152,9 @@ JSON 输出
146
152
  Error: package.json not found in current directory
147
153
  hint: 在应用项目根目录运行
148
154
  `)
149
- .action(async () => { await (0, index_1.handlePluginInit)(); });
155
+ .action(async () => {
156
+ await (0, index_1.handlePluginInit)();
157
+ });
150
158
  pluginCmd
151
159
  .command("list")
152
160
  .description("列出当前项目的 capability 实例(./server/capabilities/*.json)")
@@ -178,7 +186,9 @@ JSON 输出
178
186
  Error: server/capabilities directory not found
179
187
  hint: 当前目录必须是含 server/capabilities/ 的应用项目
180
188
  `)
181
- .action(async (opts) => { await (0, index_1.handlePluginList)(opts); });
189
+ .action(async (opts) => {
190
+ await (0, index_1.handlePluginList)(opts);
191
+ });
182
192
  pluginCmd
183
193
  .command("list-packages")
184
194
  .description("列出 package.json actionPlugins 里已声明的插件包")
@@ -201,5 +211,7 @@ JSON 输出
201
211
  Error: package.json not found in current directory
202
212
  hint: 在应用项目根目录运行
203
213
  `)
204
- .action(() => { (0, index_1.handlePluginListPlugins)(); });
214
+ .action(() => {
215
+ (0, index_1.handlePluginListPlugins)();
216
+ });
205
217
  }
@@ -1,11 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.appIdOption = appIdOption;
4
+ exports.branchOption = branchOption;
3
5
  exports.softRequiredOption = softRequiredOption;
4
6
  exports.resolveAppId = resolveAppId;
5
7
  exports.withHelp = withHelp;
6
8
  exports.failArgs = failArgs;
9
+ exports.rejectCliOverride = rejectCliOverride;
7
10
  const commander_1 = require("commander");
8
11
  const error_1 = require("../../utils/error");
12
+ /** --app-id option,需要应用上下文的命令自行 .addOption(appIdOption()) */
13
+ function appIdOption() {
14
+ return new commander_1.Option("--app-id <id>", "指定目标应用").env("MIAODA_APP_ID");
15
+ }
16
+ function branchOption() {
17
+ return new commander_1.Option("--branch <branch>", "分支(优先级:--branch > 当前仓库 HEAD 分支;非 git 目录回退应用默认分支)").env("LOCAL_MOCK_MIAODA_DEPLOY_BRANCH");
18
+ }
9
19
  /**
10
20
  * soft-required: Commander 类型上 optional,runtime 校验必填。
11
21
  */
@@ -22,18 +32,20 @@ function resolveAppId(opts) {
22
32
  const id = opts.appId ?? process.env.MIAODA_APP_ID ?? process.env.app_id;
23
33
  if (!id) {
24
34
  throw new error_1.AppError("APP_ID_MISSING", "未指定应用", {
25
- next_actions: [
26
- "设置 export MIAODA_APP_ID=<id>",
27
- ],
35
+ next_actions: ["设置 export MIAODA_APP_ID=<id>"],
28
36
  });
29
37
  }
30
38
  return id;
31
39
  }
32
- /** 包裹 handler,缺 soft-required 参数时打 help 并退出 */
40
+ /**
41
+ * 包裹 handler,缺 soft-required 参数 / 自定义校验失败时打 help 并退出。
42
+ *
43
+ * 兼容带位置参数的 action 签名(如 `(arg1: string, opts) => ...`)。
44
+ */
33
45
  function withHelp(cmd, handler) {
34
- return async (opts) => {
46
+ return async (...args) => {
35
47
  try {
36
- await handler(opts);
48
+ await handler(...args);
37
49
  }
38
50
  catch (err) {
39
51
  if (err instanceof error_1.AppError && err.code === "ARGS_INVALID") {
@@ -50,3 +62,23 @@ function withHelp(cmd, handler) {
50
62
  function failArgs(message) {
51
63
  throw new error_1.AppError("ARGS_INVALID", message);
52
64
  }
65
+ /**
66
+ * 拒绝 CLI 显式覆盖:用于 hideHelp() + .env() 的"沙箱注入参数"(如 --app-id / --branch)。
67
+ *
68
+ * Commander 的 getOptionValueSource() 区分来源(cli / env / default / config / undefined);
69
+ * 用户在 CLI 上显式传时 source === "cli",此时抛 ARGS_INVALID(exit 2 + help)。
70
+ *
71
+ * 用法:在 action 头部一行调用——
72
+ * cmd.action(withHelp(cmd, async (rawOpts) => {
73
+ * rejectCliOverride(cmd, "appId", "branch");
74
+ * ...
75
+ * }));
76
+ */
77
+ function rejectCliOverride(cmd, ...optNames) {
78
+ for (const name of optNames) {
79
+ if (cmd.getOptionValueSource(name) === "cli") {
80
+ const flag = "--" + name.replace(/([A-Z])/g, "-$1").toLowerCase();
81
+ failArgs(`${flag} 由沙箱/本地配置注入,不允许显式传递`);
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,48 @@
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.handleAppGet = handleAppGet;
37
+ const api = __importStar(require("../../../api/index"));
38
+ const output_1 = require("../../../utils/output");
39
+ const shared_1 = require("../../../cli/commands/shared");
40
+ const index_1 = require("../../../api/app/index");
41
+ /** miaoda app get [--app-id <id>] */
42
+ async function handleAppGet(opts) {
43
+ const appID = (0, shared_1.resolveAppId)({ appId: opts.appId });
44
+ const resp = await api.app.getAppInfo(appID);
45
+ // BAM 在 status_code=0 时 data 字段含 appInfo;不存在则 fallback 空对象
46
+ const meta = resp.appInfo?.appMeta ?? {};
47
+ (0, output_1.emit)({ data: meta, next_cursor: null, has_more: false }, index_1.appMetaSchema);
48
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleAppUpdate = exports.handleAppGet = void 0;
4
+ var get_1 = require("./get");
5
+ Object.defineProperty(exports, "handleAppGet", { enumerable: true, get: function () { return get_1.handleAppGet; } });
6
+ var update_1 = require("./update");
7
+ Object.defineProperty(exports, "handleAppUpdate", { enumerable: true, get: function () { return update_1.handleAppUpdate; } });
@@ -0,0 +1,59 @@
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.handleAppUpdate = handleAppUpdate;
37
+ const api = __importStar(require("../../../api/index"));
38
+ const output_1 = require("../../../utils/output");
39
+ const shared_1 = require("../../../cli/commands/shared");
40
+ const index_1 = require("../../../api/app/index");
41
+ /** miaoda app update [--app-id <id>] [--name <n>] [--description <d>] */
42
+ async function handleAppUpdate(opts) {
43
+ if (opts.name === undefined && opts.description === undefined) {
44
+ (0, shared_1.failArgs)("至少需要 --name 或 --description 中的一个");
45
+ }
46
+ const appID = (0, shared_1.resolveAppId)({ appId: opts.appId });
47
+ await api.app.updateAppMeta({
48
+ appID,
49
+ name: opts.name,
50
+ description: opts.description,
51
+ });
52
+ // 服务端不回写新 meta,本地再 fetch 一次拿最新值给用户
53
+ const resp = await api.app.getAppInfo(appID);
54
+ const meta = resp.appInfo?.appMeta ?? {};
55
+ if (!(0, output_1.isJsonMode)()) {
56
+ process.stdout.write("✓ App updated successfully\n");
57
+ }
58
+ (0, output_1.emit)({ data: meta, next_cursor: null, has_more: false }, index_1.appMetaSchema);
59
+ }