@arcships/morula-runtime 0.1.0-alpha.2 → 0.1.0-alpha.20

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.
@@ -0,0 +1,1756 @@
1
+ # 命令参考
2
+
3
+ > **生成区段**(全局参数 + 各 resource 的命令面)由 CLI SPEC 渲染,不要手改:
4
+ > `pnpm --filter @arcships/morula-runtime gen:cli-skill`。
5
+ > `prompt-cli-consistency` 守卫会把本文件与 SPEC 重渲染结果逐字比对,手改生成区段会红。
6
+ >
7
+ > **手写区段**(`<!-- hand:start <key> -->` … `<!-- hand:end <key> -->`,key = resource 名或 `global`)
8
+ > 放 SPEC 表达不了的补充:风险等级、Flag → API 字段映射、返回结构示例、退出码语义。
9
+ > 生成器逐字保留区段内容;区段外的手写内容会被覆盖。
10
+
11
+ ## 全局参数
12
+
13
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
14
+ |---|---|---|---|---|---|
15
+ | `--env <context>` | string | - | - | - | select test or a saved context |
16
+ | `--url <baseUrl>` | string | - | - | - | override API base URL |
17
+ | `--token <token>` | string | - | - | - | override token for this invocation (not persisted) |
18
+ | `--help` | boolean | - | - | - | print this machine-readable command surface |
19
+ | `--version` | boolean | - | - | - | print version JSON |
20
+ | `--json` | boolean | - | - | - | no-op: output is always JSON (accepted for familiarity) |
21
+
22
+ <!-- hand:start global -->
23
+ ### 退出码速查(Agent 行为)
24
+
25
+ | 退出码 | 含义 | Agent 行为 |
26
+ |---|---|---|
27
+ | 0 | 成功 | 按「结果呈现」规则格式化输出(stdout 为 JSON) |
28
+ | 1 | 未分类错误 | 展示错误信息(stderr JSON 的 `message`) |
29
+ | 2 | 参数错误 | 修正参数后重试(对照本文件与 `--help`) |
30
+ | 3 | 资源不存在 | 确认 ID 是否正确(用对应 `list` 重新查询) |
31
+ | 4 | 未认证 | 执行 `morula auth login --env {{DEFAULT_CONTEXT}}` |
32
+ | 5 | 无权限 | 告知用户权限不足 |
33
+ | 6 | 冲突 | 重新查询最新数据后谨慎重试 |
34
+ | 7 | 网络/服务端错误 | 指数退避重试(1s→2s→4s,最多 3 次);持续失败告知用户稍后再试 |
35
+
36
+ 退出码语义与 137(SIGKILL)诊断见 SKILL.md「退出码」章节。
37
+ <!-- hand:end global -->
38
+
39
+ ---
40
+
41
+ ## `morula auth`
42
+
43
+ SkyDoor authentication (shared config with morula-runtime)
44
+
45
+ ### `morula auth login`
46
+
47
+ **用法**:`morula auth login [--url <baseUrl>]`
48
+
49
+ browser SkyDoor SSO using PKCE and loopback callback (writes ~/.morula-cli/config.yaml)
50
+
51
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
52
+ |---|---|---|---|---|---|
53
+ | `--url <baseUrl>` | string | - | - | - | server base URL to log in to |
54
+
55
+ **示例**
56
+
57
+ ```bash
58
+ morula auth login
59
+ ```
60
+
61
+ > `writes: local` · `interactive: yes` · `idempotent: no` · `emits: loggedIn, context, baseUrl, expiresIn`
62
+
63
+ ### `morula auth logout`
64
+
65
+ **用法**:`morula auth logout`
66
+
67
+ remove the current context token
68
+
69
+ **示例**
70
+
71
+ ```bash
72
+ morula auth logout
73
+ ```
74
+
75
+ > `writes: local` · `interactive: no` · `idempotent: yes` · `emits: loggedIn, context`
76
+
77
+ ### `morula auth status`
78
+
79
+ **用法**:`morula auth status`
80
+
81
+ show context, endpoint, and authentication state
82
+
83
+ **示例**
84
+
85
+ ```bash
86
+ morula auth status
87
+ ```
88
+
89
+ > `writes: none` · `interactive: no` · `idempotent: yes` · `emits: loggedIn, context, baseUrl, user, expired`
90
+
91
+ <!-- hand:start auth -->
92
+ ### 手写补充:风险等级与返回示例
93
+
94
+ **风险等级 / 审批**:`login` / `status` = `read_only`(自动);`logout` = `write_internal`(**需确认**,会撤销服务端 Token 并清除本地配置)。
95
+
96
+ **登录细节**:`auth login` 走 OAuth2 PKCE S256 + loopback 回调(本机随机端口),默认超时 5 分钟,可用 `MORULA_LOGIN_TIMEOUT_MS` 覆盖。凭据存于 `~/.morula-cli/config.yaml`(0600),可重复执行——新 Token 覆盖旧 Token。
97
+
98
+ **返回示例**:
99
+
100
+ ```json
101
+ {"loggedIn": true, "context": "test", "baseUrl": "https://morula.basecastle.com/api", "expiresIn": 15552000}
102
+ ```
103
+
104
+ `auth status` 未登录时:
105
+
106
+ ```json
107
+ {"loggedIn": false, "context": "test", "baseUrl": "https://morula.basecastle.com/api"}
108
+ ```
109
+
110
+ 已登录时另含 `user`(`{ "displayName": "张三", "username": "zhangsan" }`)。
111
+ <!-- hand:end auth -->
112
+
113
+ ---
114
+
115
+ ## `morula task`
116
+
117
+ task (business Object) read/write + AgentTask machine protocol (branch/state/analysis-verdict/inbox)
118
+
119
+ ### `morula task list`
120
+
121
+ **用法**:`morula task list [--space <id>] [--mine] [--assignee <principalId>] [--principal <id>] [--page <n>] [--page-size <n>] [--search <text>] [--priority <low|medium|high|urgent>] [--state <id>] [--sort <field>] [--order <asc|desc>] [--field key=value[,key=value]]`
122
+
123
+ list tasks (--mine: 仅我负责的;--field key=value 自定义字段筛选,需 --space)
124
+
125
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
126
+ |---|---|---|---|---|---|
127
+ | `--space <id>` | string | - | - | - | space id |
128
+ | `--mine` | boolean | - | - | - | 仅我负责的(与 --assignee 互斥) |
129
+ | `--assignee <principalId>` | string | - | - | - | 按负责人过滤 |
130
+ | `--principal <id>` | string | - | - | - | 按创建人过滤 |
131
+ | `--page <n>` | number | - | - | - | 页码 |
132
+ | `--page-size <n>` | number | - | - | - | 每页条数 |
133
+ | `--search <text>` | string | - | - | - | 关键词搜索 |
134
+ | `--priority <low\|medium\|high\|urgent>` | string | - | `low` `medium` `high` `urgent` | - | 优先级过滤 |
135
+ | `--state <id>` | string | - | - | - | 状态过滤 |
136
+ | `--sort <field>` | string | - | - | - | 排序字段 |
137
+ | `--order <asc\|desc>` | string | - | `asc` `desc` | - | 排序方向 |
138
+ | `--field key=value[,key=value]` | string | - | - | - | 自定义字段等值筛选(多条件 AND;需 --space 解析字段模板) |
139
+
140
+ **示例**
141
+
142
+ ```bash
143
+ morula task list --space <id>
144
+ morula task list --mine
145
+ morula task list --space <id> --field priority=p1
146
+ ```
147
+
148
+ > `writes: none` · `interactive: no` · `idempotent: yes`
149
+
150
+ ### `morula task create`
151
+
152
+ **用法**:`morula task create [--space <id>] [--title <text>] [--description <text>] [--priority <low|medium|high|urgent>] [--state <id>] [--owner <principalId>] [--assignee <principalId>] [--visibility <value>] [--estimate-hours <n>] [--schema <id>] [--sort-order <n>] [--field key=value[,key=value]]`
153
+
154
+ create task (必填 --space/--title;落 backlog 由服务端决定初始状态)
155
+
156
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
157
+ |---|---|---|---|---|---|
158
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
159
+ | `--title <text>` | string | 是 | - | - | 标题(必填) |
160
+ | `--description <text>` | string | - | - | - | 描述(格式自动检测) |
161
+ | `--priority <low\|medium\|high\|urgent>` | string | - | `low` `medium` `high` `urgent` | - | 优先级 |
162
+ | `--state <id>` | string | - | - | - | 初始状态(业务 Object state id) |
163
+ | `--owner <principalId>` | string | - | - | - | 负责人(仅创建时) |
164
+ | `--assignee <principalId>` | string | - | - | - | 经办人 |
165
+ | `--visibility <value>` | string | - | - | - | 可见性 |
166
+ | `--estimate-hours <n>` | number | - | - | - | 预估工时 |
167
+ | `--schema <id>` | string | - | - | - | 字段模板 |
168
+ | `--sort-order <n>` | number | - | - | - | 排序号 |
169
+ | `--field key=value[,key=value]` | string | - | - | - | 自定义字段 upsert(创建后写入) |
170
+
171
+ **示例**
172
+
173
+ ```bash
174
+ morula task create --space <id> --title <text>
175
+ ```
176
+
177
+ > `writes: remote` · `interactive: no` · `idempotent: no`
178
+
179
+ ### `morula task get`
180
+
181
+ **用法**:`morula task get [<objectId>]`
182
+
183
+ get task details. No argument = the current AgentTask (id resolved from MORULA_TASK_ID / .morula/checkout.json). With an id = the business Object (title/description)
184
+
185
+ | 位置参数 | 必填 | 说明 |
186
+ |---|---|---|
187
+ | `<objectId>` | - | 业务任务(Object)ID;省略 = 当前 AgentTask 详情 |
188
+
189
+ **示例**
190
+
191
+ ```bash
192
+ morula task get
193
+ morula task get <objectId>
194
+ ```
195
+
196
+ > `writes: none` · `interactive: no` · `idempotent: yes`
197
+
198
+ ### `morula task update`
199
+
200
+ **用法**:`morula task update <id> [--title <text>] [--description <text>] [--priority <low|medium|high|urgent>] [--state <id>] [--assignee <principalId>] [--visibility <value>] [--estimate-hours <n>] [--schema <id>] [--sort-order <n>] [--field key=value[,key=value]]`
201
+
202
+ update task (--state here is the business Object state id, NOT the AgentTask state code — see `task state`)
203
+
204
+ | 位置参数 | 必填 | 说明 |
205
+ |---|---|---|
206
+ | `<id>` | 是 | 任务(Object)ID |
207
+
208
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
209
+ |---|---|---|---|---|---|
210
+ | `--title <text>` | string | - | - | - | 标题 |
211
+ | `--description <text>` | string | - | - | - | 描述 |
212
+ | `--priority <low\|medium\|high\|urgent>` | string | - | `low` `medium` `high` `urgent` | - | 优先级 |
213
+ | `--state <id>` | string | - | - | - | 状态(业务 Object state id) |
214
+ | `--assignee <principalId>` | string | - | - | - | 经办人 |
215
+ | `--visibility <value>` | string | - | - | - | 可见性 |
216
+ | `--estimate-hours <n>` | number | - | - | - | 预估工时 |
217
+ | `--schema <id>` | string | - | - | - | 字段模板 |
218
+ | `--sort-order <n>` | number | - | - | - | 排序号 |
219
+ | `--field key=value[,key=value]` | string | - | - | - | 自定义字段 upsert(空 value = 清空) |
220
+
221
+ **示例**
222
+
223
+ ```bash
224
+ morula task update <id> --title <text>
225
+ ```
226
+
227
+ > `writes: remote` · `interactive: no` · `idempotent: no`
228
+
229
+ ### `morula task delete`
230
+
231
+ **用法**:`morula task delete <id>`
232
+
233
+ hard delete task
234
+
235
+ | 位置参数 | 必填 | 说明 |
236
+ |---|---|---|
237
+ | `<id>` | 是 | 任务(Object)ID |
238
+
239
+ **示例**
240
+
241
+ ```bash
242
+ morula task delete <id>
243
+ ```
244
+
245
+ > `writes: remote` · `interactive: no` · `idempotent: no`
246
+
247
+ ### `morula task branch`
248
+
249
+ **用法**:`morula task branch <taskId> [--name <branch>] [--repo <owner/name>]`
250
+
251
+ report the final branch name for an agent task (machine protocol; agent naming, runtimeId from env; --repo: secondary repo in a multi-repo task)
252
+
253
+ | 位置参数 | 必填 | 说明 |
254
+ |---|---|---|
255
+ | `<taskId>` | 是 | 本任务 AgentTask UUID(morula task get 无参返回的 id) |
256
+
257
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
258
+ |---|---|---|---|---|---|
259
+ | `--name <branch>` | string | 是 | - | - | 分支名(必填) |
260
+ | `--repo <owner/name>` | string | - | - | - | 次仓库(多仓库任务的分支逐仓上报) |
261
+
262
+ **示例**
263
+
264
+ ```bash
265
+ morula task branch <taskId> --name <type>/<slug>
266
+ ```
267
+
268
+ > `writes: remote` · `interactive: no` · `idempotent: no`
269
+
270
+ ### `morula task state`
271
+
272
+ **用法**:`morula task state <taskId> [--state <in_progress|review>] [--reason <text>]`
273
+
274
+ self-transition task state (machine protocol; agent drives todo→in_progress→review; review→in_progress = 退回开发,平台自动派修复轮次)
275
+
276
+ | 位置参数 | 必填 | 说明 |
277
+ |---|---|---|
278
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
279
+
280
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
281
+ |---|---|---|---|---|---|
282
+ | `--state <in_progress\|review>` | string | 是 | `in_progress` `review` | - | 目标状态 code(必填);review→in_progress = 退回开发(自动派修复,不需要再自己 @ 开发执行器) |
283
+ | `--reason <text>` | string | - | - | - | 流转原因(退回开发时写进轮次记账与修复任务 prompt) |
284
+
285
+ **示例**
286
+
287
+ ```bash
288
+ morula task state <taskId> --state in_progress
289
+ morula task state <taskId> --state in_progress --reason <退回原因>
290
+ ```
291
+
292
+ > `writes: remote` · `interactive: no` · `idempotent: no`
293
+
294
+ ### `morula task assign`
295
+
296
+ **用法**:`morula task assign <taskId> [--to <principalId>]`
297
+
298
+ assign the task owner (machine protocol; target = space member or stage executor principal)
299
+
300
+ | 位置参数 | 必填 | 说明 |
301
+ |---|---|---|
302
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
303
+
304
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
305
+ |---|---|---|---|---|---|
306
+ | `--to <principalId>` | string | 是 | - | - | 目标负责人 principal UUID(本空间成员或阶段执行器;不存在/不在本空间会显式报错) |
307
+
308
+ **示例**
309
+
310
+ ```bash
311
+ morula task assign <taskId> --to <principalId>
312
+ ```
313
+
314
+ > `writes: remote` · `interactive: no` · `idempotent: no`
315
+
316
+ ### `morula task analysis-verdict`
317
+
318
+ **用法**:`morula task analysis-verdict <taskId> [--verdict <ready|blocked>] [--reason <text>]`
319
+
320
+ report the task-analysis verdict (machine protocol; ready → platform auto-starts development, blocked → task stays in analysis)
321
+
322
+ | 位置参数 | 必填 | 说明 |
323
+ |---|---|---|
324
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
325
+
326
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
327
+ |---|---|---|---|---|---|
328
+ | `--verdict <ready\|blocked>` | string | 是 | `ready` `blocked` | - | 分析结论(必填;仅任务分析任务可上报) |
329
+ | `--reason <text>` | string | - | - | - | blocked 时的阻塞/待澄清原因 |
330
+
331
+ **示例**
332
+
333
+ ```bash
334
+ morula task analysis-verdict <taskId> --verdict ready
335
+ ```
336
+
337
+ > `writes: remote` · `interactive: no` · `idempotent: no`
338
+
339
+ ### `morula task inbox`
340
+
341
+ **用法**:`morula task inbox [--peek] [--after-seq <n>]`
342
+
343
+ checkpoint: pull this thread's unconsumed messages into the current turn (machine protocol; --peek reads without marking them consumed)
344
+
345
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
346
+ |---|---|---|---|---|---|
347
+ | `--peek` | boolean | - | - | - | 只读,不标记消费 |
348
+ | `--after-seq <n>` | number | - | - | - | 从该 seq 之后拉取 |
349
+
350
+ **示例**
351
+
352
+ ```bash
353
+ morula task inbox
354
+ morula task inbox --peek
355
+ ```
356
+
357
+ > `writes: remote` · `interactive: no` · `idempotent: no`
358
+
359
+ ### `morula task agent-tasks`
360
+
361
+ **用法**:`morula task agent-tasks [--object <objectId>] [--status <queued|dispatched|running|awaiting_approval|completed|failed|cancelled>] [--page <n>] [--page-size <n>]`
362
+
363
+ list the AgentTask executions of a business task (Object). AgentTask UUID ≠ 业务任务 id — cancel/rerun 要的是这里的 id
364
+
365
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
366
+ |---|---|---|---|---|---|
367
+ | `--object <objectId>` | string | 是 | - | - | 业务任务(Object)ID(必填) |
368
+ | `--status <queued\|dispatched\|running\|awaiting_approval\|completed\|failed\|cancelled>` | string | - | `queued` `dispatched` `running` `awaiting_approval` `completed` `failed` `cancelled` | - | 按单个状态过滤(缺省 = 全部;服务端不做枚举校验,非法值只返回空) |
369
+ | `--page <n>` | number | - | - | - | 页码 |
370
+ | `--page-size <n>` | number | - | - | - | 每页条数(服务端缺省 20) |
371
+
372
+ **示例**
373
+
374
+ ```bash
375
+ morula task agent-tasks --object <objectId>
376
+ morula task agent-tasks --object <objectId> --status failed
377
+ ```
378
+
379
+ > `writes: none` · `interactive: no` · `idempotent: yes`
380
+
381
+ ### `morula task cancel`
382
+
383
+ **用法**:`morula task cancel <taskId>`
384
+
385
+ cancel a running execution (POST /agent-tasks/:id/cancel). queued/dispatched/running/awaiting_approval/failed 可取消;completed/cancelled 不可(409 CONFLICT);任务不存在 404 NOT_FOUND。成功返回 { ok: true }——**非零退出即未取消**,不要向用户汇报「已停掉」
386
+
387
+ | 位置参数 | 必填 | 说明 |
388
+ |---|---|---|
389
+ | `<taskId>` | 是 | AgentTask UUID(来自 morula task agent-tasks) |
390
+
391
+ **示例**
392
+
393
+ ```bash
394
+ morula task cancel <taskId>
395
+ ```
396
+
397
+ > `writes: remote` · `interactive: no` · `idempotent: no`
398
+
399
+ ### `morula task rerun`
400
+
401
+ **用法**:`morula task rerun <taskId>`
402
+
403
+ rerun a failed/cancelled execution (POST /agent-tasks/:id/rerun; copies the task and re-queues it → returns a NEW taskId). 仅 failed/cancelled 可重跑,其他状态 ok:false + code CONFLICT;10s 内已有活跃重跑为 ALREADY_QUEUED
404
+
405
+ | 位置参数 | 必填 | 说明 |
406
+ |---|---|---|
407
+ | `<taskId>` | 是 | AgentTask UUID(来自 morula task agent-tasks) |
408
+
409
+ **示例**
410
+
411
+ ```bash
412
+ morula task rerun <taskId>
413
+ ```
414
+
415
+ > `writes: remote` · `interactive: no` · `idempotent: no`
416
+
417
+ <!-- hand:start task -->
418
+ ### 手写补充:风险等级 / Flag → API 字段映射 / 返回结构
419
+
420
+ **风险等级 / 审批**(机器维度见上方生成区段的 `writes`):
421
+
422
+ | Action | 风险 | 审批 |
423
+ |---|---|---|
424
+ | `list` / `get` / `agent-tasks` | `read_only` | 自动 |
425
+ | `create` / `update` | `write_internal` | **需确认**(写前向用户确认 spaceId + title / taskId + 修改内容) |
426
+ | `cancel` / `rerun` | `destructive`(干预正在跑的 agent) | **需确认**(先 `task agent-tasks --object <id>` 展示目标执行;`cancel` 停掉在跑执行、`rerun` 会新建一条执行) |
427
+ | `delete` | `destructive` | **需预演 + 确认**(先 `task get <id>` 展示标题与空间;硬删除,数据不可恢复,不可自动重试) |
428
+
429
+ **id 口径**:`<id>`(`list` / `get` / `update` / `delete`)= 业务任务(Object)ID;`<taskId>`(`agent-tasks` / `cancel` / `rerun`)= AgentTask UUID。两者**不可互换**——干预执行前先 `morula task agent-tasks --object <objectId>` 拿 UUID。
430
+
431
+ **`cancel` 的失败语义**(2026-09-20 起):任务不存在 → **404 `NOT_FOUND`**;状态不允许(已完成/已取消)→ **409 `CONFLICT`**;成功 → 200 `{ ok: true, message: 'Task cancelled' }`。即**非零退出就是没取消成功**(不再有「失败也是 200」的假成功),不要只凭「命令返回了」就汇报已停掉。
432
+
433
+ **幂等性**:`list` / `get` ✅ 安全重试;`create` ⚠️ 重试可能重复创建(401/5xx 时先 `task list` 检查是否已创建);`update` ✅ 覆盖更新(至少传一个可选 flag)。
434
+
435
+ **Flag → API 字段映射**(`list` / `create` / `update`):
436
+
437
+ | Flag | API 字段 |
438
+ |---|---|
439
+ | `--space` | `spaceId`(从 `space list` 获取) |
440
+ | `--title` | `title` |
441
+ | `--description` | `description`(rich HTML) |
442
+ | `--priority` | `priority`(`create` 缺省 `medium`) |
443
+ | `--state` | `currentStateId`(状态 ID) |
444
+ | `--assignee` | `assigneePrincipalId`(负责人主体 ID) |
445
+ | `--mine` | 解析为 `assigneePrincipalId`(经 `auth status` 自动解析,与 `--assignee` 互斥) |
446
+ | `--principal` | `principalId`(同时匹配负责人和报告人) |
447
+ | `--owner` | `ownerPrincipalId`(仅 `create`) |
448
+ | `--visibility` | `visibility`(`create` 缺省 `space`) |
449
+ | `--estimate-hours` | `estimateHours` |
450
+ | `--schema` | `schemaId`(字段模板 ID) |
451
+ | `--sort-order` | `sortOrder`(仅 `update`) |
452
+ | `--field` | `list` → `fieldFilters`;`create` / `update` → `POST /object-field-values` upsert(空 value 清空) |
453
+
454
+ **返回结构**:
455
+
456
+ - `list`:`{ data: [...], total, page, pageSize }`;列表项含 `id`、`title`、`priority`、`currentStateId`、`assigneePrincipalId`、`spaceId`、`fieldValues`、`schemaFields`。
457
+ - `get`:另含 `description`、`estimateHours`、`visibility`、`schemaId`、`createdAt`、`updatedAt`、`participants`、`comments`。
458
+ - `create`:新任务完整信息,含 `id` + `code`(如 `TASK-042`)。
459
+ - `update`:返回更新后的字段值(确认与输入一致)。
460
+ <!-- hand:end task -->
461
+
462
+ ---
463
+
464
+ ## `morula space`
465
+
466
+ space (project) read/write
467
+
468
+ ### `morula space list`
469
+
470
+ **用法**:`morula space list [--page <n>] [--page-size <n>] [--keyword <text>]`
471
+
472
+ list visible spaces
473
+
474
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
475
+ |---|---|---|---|---|---|
476
+ | `--page <n>` | number | - | - | - | 页码 |
477
+ | `--page-size <n>` | number | - | - | - | 每页条数 |
478
+ | `--keyword <text>` | string | - | - | - | 关键词 |
479
+
480
+ **示例**
481
+
482
+ ```bash
483
+ morula space list
484
+ ```
485
+
486
+ > `writes: none` · `interactive: no` · `idempotent: yes`
487
+
488
+ ### `morula space get`
489
+
490
+ **用法**:`morula space get <id>`
491
+
492
+ get space details
493
+
494
+ | 位置参数 | 必填 | 说明 |
495
+ |---|---|---|
496
+ | `<id>` | 是 | 空间 ID |
497
+
498
+ **示例**
499
+
500
+ ```bash
501
+ morula space get <id>
502
+ ```
503
+
504
+ > `writes: none` · `interactive: no` · `idempotent: yes`
505
+
506
+ ### `morula space create`
507
+
508
+ **用法**:`morula space create [--name <text>] [--description <text>] [--code <code>] [--visibility <private|internal|public>]`
509
+
510
+ create space (project)
511
+
512
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
513
+ |---|---|---|---|---|---|
514
+ | `--name <text>` | string | 是 | - | - | 空间名称(必填) |
515
+ | `--description <text>` | string | - | - | - | 描述 |
516
+ | `--code <code>` | string | - | - | - | 空间编号(缺省由服务端生成) |
517
+ | `--visibility <private\|internal\|public>` | string | - | `private` `internal` `public` | - | 可见性 |
518
+
519
+ **示例**
520
+
521
+ ```bash
522
+ morula space create --name <text>
523
+ ```
524
+
525
+ > `writes: remote` · `interactive: no` · `idempotent: no`
526
+
527
+ ### `morula space update`
528
+
529
+ **用法**:`morula space update <id> [--name <text>] [--description <text>] [--visibility <private|internal|public>]`
530
+
531
+ update space (至少一个字段旗标)
532
+
533
+ | 位置参数 | 必填 | 说明 |
534
+ |---|---|---|
535
+ | `<id>` | 是 | 空间 ID |
536
+
537
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
538
+ |---|---|---|---|---|---|
539
+ | `--name <text>` | string | - | - | - | 空间名称 |
540
+ | `--description <text>` | string | - | - | - | 描述 |
541
+ | `--visibility <private\|internal\|public>` | string | - | `private` `internal` `public` | - | 可见性 |
542
+
543
+ **示例**
544
+
545
+ ```bash
546
+ morula space update <id> --name <text>
547
+ ```
548
+
549
+ > `writes: remote` · `interactive: no` · `idempotent: no`
550
+
551
+ ### `morula space delete`
552
+
553
+ **用法**:`morula space delete <id>`
554
+
555
+ delete space
556
+
557
+ | 位置参数 | 必填 | 说明 |
558
+ |---|---|---|
559
+ | `<id>` | 是 | 空间 ID |
560
+
561
+ **示例**
562
+
563
+ ```bash
564
+ morula space delete <id>
565
+ ```
566
+
567
+ > `writes: remote` · `interactive: no` · `idempotent: no`
568
+
569
+ <!-- hand:start space -->
570
+ ### 手写补充:风险等级与返回结构
571
+
572
+ **风险等级 / 审批**:`list` / `get` = `read_only`(自动);`create` / `update` / `delete` 写平台(见上方生成区段的 `writes`),按 SKILL.md「审批规则」在写前向用户确认。
573
+
574
+ **返回结构**:
575
+
576
+ - `list`:`{ data: [{ id, name, description, objectCount, memberCount }], total, page, pageSize }`。
577
+ - `get`:含 `name`、`description`、`visibility`、`ownerPrincipalId`、`members`(含 roleCode)、`workflowId`、`schemaId`、`objectCount`、`createdAt`、`updatedAt`。
578
+ <!-- hand:end space -->
579
+
580
+ ---
581
+
582
+ ## `morula space-member`
583
+
584
+ space member management (admin operations)
585
+
586
+ ### `morula space-member list`
587
+
588
+ **用法**:`morula space-member list [--space <id>]`
589
+
590
+ list space members
591
+
592
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
593
+ |---|---|---|---|---|---|
594
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
595
+
596
+ **示例**
597
+
598
+ ```bash
599
+ morula space-member list --space <id>
600
+ ```
601
+
602
+ > `writes: none` · `interactive: no` · `idempotent: yes`
603
+
604
+ ### `morula space-member add`
605
+
606
+ **用法**:`morula space-member add [--space <id>] [--principal <id>] [--role <admin|member>]`
607
+
608
+ add member to space
609
+
610
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
611
+ |---|---|---|---|---|---|
612
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
613
+ | `--principal <id>` | string | 是 | - | - | 成员 principalId(必填) |
614
+ | `--role <admin\|member>` | string | - | `admin` `member` | - | 角色(缺省 member) |
615
+
616
+ **示例**
617
+
618
+ ```bash
619
+ morula space-member add --space <id> --principal <id>
620
+ ```
621
+
622
+ > `writes: remote` · `interactive: no` · `idempotent: no`
623
+
624
+ ### `morula space-member update`
625
+
626
+ **用法**:`morula space-member update <memberId> [--role <admin|member>]`
627
+
628
+ update member role
629
+
630
+ | 位置参数 | 必填 | 说明 |
631
+ |---|---|---|
632
+ | `<memberId>` | 是 | 成员行 ID |
633
+
634
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
635
+ |---|---|---|---|---|---|
636
+ | `--role <admin\|member>` | string | 是 | `admin` `member` | - | 新角色(必填) |
637
+
638
+ **示例**
639
+
640
+ ```bash
641
+ morula space-member update <memberId> --role admin
642
+ ```
643
+
644
+ > `writes: remote` · `interactive: no` · `idempotent: no`
645
+
646
+ ### `morula space-member remove`
647
+
648
+ **用法**:`morula space-member remove <memberId>`
649
+
650
+ remove member from space
651
+
652
+ | 位置参数 | 必填 | 说明 |
653
+ |---|---|---|
654
+ | `<memberId>` | 是 | 成员行 ID |
655
+
656
+ **示例**
657
+
658
+ ```bash
659
+ morula space-member remove <memberId>
660
+ ```
661
+
662
+ > `writes: remote` · `interactive: no` · `idempotent: no`
663
+
664
+ <!-- hand:start space-member -->
665
+ ### 手写补充:风险等级 / 幂等性 / Flag → API 字段映射
666
+
667
+ **风险等级 / 审批**:`list` = `read_only`(自动);`add` / `update` / `remove` = `identity_access`(**需确认**)。
668
+
669
+ **幂等性**:`list` / `update` ✅ 安全重试;`add` ⚠️ 重复添加可能 409;`remove` ⚠️ 404 = 已移除(非错误)。
670
+
671
+ **Flag → API 字段映射**(`add` / `update`):`--space` → `spaceId`;`--principal` → `principalId`;`--role` → `roleCode`(缺省 `member`)。
672
+ <!-- hand:end space-member -->
673
+
674
+ ---
675
+
676
+ ## `morula steward`
677
+
678
+ space steward (project-level agent): read takeover state / dispatch a task with an explicit target state
679
+
680
+ ### `morula steward get`
681
+
682
+ **用法**:`morula steward get [--space <id>]`
683
+
684
+ get the steward record of a space (null = 未接管)
685
+
686
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
687
+ |---|---|---|---|---|---|
688
+ | `--space <id>` | string | 是 | - | - | 空间(项目)ID(必填) |
689
+
690
+ **示例**
691
+
692
+ ```bash
693
+ morula steward get --space <id>
694
+ ```
695
+
696
+ > `writes: none` · `interactive: no` · `idempotent: yes`
697
+
698
+ ### `morula steward dispatch`
699
+
700
+ **用法**:`morula steward dispatch [--space <id>] [--title <text>] [--description <text>] [--state <backlog|todo|in_progress>] [--assignee <principalId>] [--repo <owner/name>] [--client-message-id <id>]`
701
+
702
+ dispatch a task: create the task and hand it to the pipeline. --state backlog = 落待规划(不派发执行,服务端不建 AgentTask);缺省 todo(待分析)
703
+
704
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
705
+ |---|---|---|---|---|---|
706
+ | `--space <id>` | string | 是 | - | - | 空间(项目)ID(必填) |
707
+ | `--title <text>` | string | 是 | - | - | 任务标题(必填) |
708
+ | `--description <text>` | string | - | - | - | 任务描述 |
709
+ | `--state <backlog\|todo\|in_progress>` | string | - | `backlog` `todo` `in_progress` | - | 目标初始状态(缺省 todo) |
710
+ | `--assignee <principalId>` | string | - | - | - | 指定执行者 |
711
+ | `--repo <owner/name>` | string | - | - | - | 多仓库空间:指定目标仓库(缺省由服务端解析) |
712
+ | `--client-message-id <id>` | string | - | - | - | 幂等键:同一键重复派单返回原结果 |
713
+
714
+ **示例**
715
+
716
+ ```bash
717
+ morula steward dispatch --space <id> --title <text>
718
+ morula steward dispatch --space <id> --title <text> --state backlog
719
+ ```
720
+
721
+ > `writes: remote` · `interactive: no` · `idempotent: no`
722
+
723
+ <!-- hand:start steward -->
724
+ <!-- hand:end steward -->
725
+
726
+ ---
727
+
728
+ ## `morula autopilot`
729
+
730
+ agent autopilots (scheduled/webhook-triggered automated runs; list only shows your own)
731
+
732
+ ### `morula autopilot list`
733
+
734
+ **用法**:`morula autopilot list [--space <id>] [--page <n>] [--page-size <n>]`
735
+
736
+ list autopilots created by the current user
737
+
738
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
739
+ |---|---|---|---|---|---|
740
+ | `--space <id>` | string | - | - | - | 按空间过滤 |
741
+ | `--page <n>` | number | - | - | - | 页码 |
742
+ | `--page-size <n>` | number | - | - | - | 每页条数 |
743
+
744
+ **示例**
745
+
746
+ ```bash
747
+ morula autopilot list
748
+ morula autopilot list --space <id>
749
+ ```
750
+
751
+ > `writes: none` · `interactive: no` · `idempotent: yes`
752
+
753
+ ### `morula autopilot create`
754
+
755
+ **用法**:`morula autopilot create [--space <id>] [--name <text>] [--runbook <text>] [--executor <key>] [--description <text>] [--cron <expr>] [--vcs-connection <id>]`
756
+
757
+ create an autopilot (--executor is a runtime key from the built-in catalog or one your tenant has reported)
758
+
759
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
760
+ |---|---|---|---|---|---|
761
+ | `--space <id>` | string | 是 | - | - | 归属空间 ID(必填) |
762
+ | `--name <text>` | string | 是 | - | - | 名称(同租户唯一,必填) |
763
+ | `--runbook <text>` | string | 是 | - | - | Runbook:每次触发给运行时的目标/背景/步骤(必填) |
764
+ | `--executor <key>` | string | 是 | - | - | 执行者运行时 key(必填;内置 dim / claude / codex 或本租户已上报的 provider) |
765
+ | `--description <text>` | string | - | - | - | 描述 |
766
+ | `--cron <expr>` | string | - | - | - | cron 表达式(5 字段);缺省 = 仅 webhook 触发 |
767
+ | `--vcs-connection <id>` | string | - | - | - | 限定仓库连接(缺省不限) |
768
+
769
+ **示例**
770
+
771
+ ```bash
772
+ morula autopilot create --space <id> --name <text> --runbook <text> --executor dim
773
+ ```
774
+
775
+ > `writes: remote` · `interactive: no` · `idempotent: no`
776
+
777
+ <!-- hand:start autopilot -->
778
+ <!-- hand:end autopilot -->
779
+
780
+ ---
781
+
782
+ ## `morula dashboard`
783
+
784
+ space dashboard / statistics / member workload (read-only aggregates)
785
+
786
+ ### `morula dashboard get`
787
+
788
+ **用法**:`morula dashboard get [--space <id>]`
789
+
790
+ get the space dashboard aggregate
791
+
792
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
793
+ |---|---|---|---|---|---|
794
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
795
+
796
+ **示例**
797
+
798
+ ```bash
799
+ morula dashboard get --space <id>
800
+ ```
801
+
802
+ > `writes: none` · `interactive: no` · `idempotent: yes`
803
+
804
+ ### `morula dashboard statistics`
805
+
806
+ **用法**:`morula dashboard statistics [--space <id>]`
807
+
808
+ get space task statistics
809
+
810
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
811
+ |---|---|---|---|---|---|
812
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
813
+
814
+ **示例**
815
+
816
+ ```bash
817
+ morula dashboard statistics --space <id>
818
+ ```
819
+
820
+ > `writes: none` · `interactive: no` · `idempotent: yes`
821
+
822
+ ### `morula dashboard workload`
823
+
824
+ **用法**:`morula dashboard workload [--space <id>]`
825
+
826
+ get per-member workload in a space
827
+
828
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
829
+ |---|---|---|---|---|---|
830
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
831
+
832
+ **示例**
833
+
834
+ ```bash
835
+ morula dashboard workload --space <id>
836
+ ```
837
+
838
+ > `writes: none` · `interactive: no` · `idempotent: yes`
839
+
840
+ <!-- hand:start dashboard -->
841
+ <!-- hand:end dashboard -->
842
+
843
+ ---
844
+
845
+ ## `morula object-meta`
846
+
847
+ task-level agent metadata (D-06 high-signal keys only)
848
+
849
+ ### `morula object-meta get`
850
+
851
+ **用法**:`morula object-meta get [--object <id>]`
852
+
853
+ read all agent metadata of a task
854
+
855
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
856
+ |---|---|---|---|---|---|
857
+ | `--object <id>` | string | 是 | - | - | 任务(Object)ID(必填) |
858
+
859
+ **示例**
860
+
861
+ ```bash
862
+ morula object-meta get --object <id>
863
+ ```
864
+
865
+ > `writes: none` · `interactive: no` · `idempotent: yes`
866
+
867
+ ### `morula object-meta set`
868
+
869
+ **用法**:`morula object-meta set [--object <id>] [--key <key>] [--value <text>]`
870
+
871
+ write one agent metadata key. Key must be in the high-signal whitelist: pr_url / pr_number / pipeline_status / deploy_url / waiting_on / blocked_reason / decision
872
+
873
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
874
+ |---|---|---|---|---|---|
875
+ | `--object <id>` | string | 是 | - | - | 任务(Object)ID(必填) |
876
+ | `--key <key>` | string | 是 | - | - | 元数据键(必填,白名单) |
877
+ | `--value <text>` | string | 是 | - | - | 值(必填,非空) |
878
+
879
+ **示例**
880
+
881
+ ```bash
882
+ morula object-meta set --object <id> --key pr_url --value <url>
883
+ ```
884
+
885
+ > `writes: remote` · `interactive: no` · `idempotent: no`
886
+
887
+ <!-- hand:start object-meta -->
888
+ <!-- hand:end object-meta -->
889
+
890
+ ---
891
+
892
+ ## `morula document`
893
+
894
+ document artifacts (ag_artifact; id is a numeric auto-increment id, not a uuid)
895
+
896
+ ### `morula document list`
897
+
898
+ **用法**:`morula document list [--page <n>] [--page-size <n>]`
899
+
900
+ list document artifacts
901
+
902
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
903
+ |---|---|---|---|---|---|
904
+ | `--page <n>` | number | - | - | - | 页码 |
905
+ | `--page-size <n>` | number | - | - | - | 每页条数 |
906
+
907
+ **示例**
908
+
909
+ ```bash
910
+ morula document list
911
+ ```
912
+
913
+ > `writes: none` · `interactive: no` · `idempotent: yes`
914
+
915
+ ### `morula document get`
916
+
917
+ **用法**:`morula document get <id>`
918
+
919
+ get document metadata (不含完整正文)
920
+
921
+ | 位置参数 | 必填 | 说明 |
922
+ |---|---|---|
923
+ | `<id>` | 是 | 文档 ID(数字,来自 document list) |
924
+
925
+ **示例**
926
+
927
+ ```bash
928
+ morula document get <id>
929
+ ```
930
+
931
+ > `writes: none` · `interactive: no` · `idempotent: yes`
932
+
933
+ ### `morula document artifacts`
934
+
935
+ **用法**:`morula document artifacts <id>`
936
+
937
+ read the parsed document content (markdown)
938
+
939
+ | 位置参数 | 必填 | 说明 |
940
+ |---|---|---|
941
+ | `<id>` | 是 | 文档 ID(数字,来自 document list) |
942
+
943
+ **示例**
944
+
945
+ ```bash
946
+ morula document artifacts <id>
947
+ ```
948
+
949
+ > `writes: none` · `interactive: no` · `idempotent: yes`
950
+
951
+ <!-- hand:start document -->
952
+ <!-- hand:end document -->
953
+
954
+ ---
955
+
956
+ ## `morula comment`
957
+
958
+ object comments (agent summaries live here)
959
+
960
+ ### `morula comment list`
961
+
962
+ **用法**:`morula comment list [--object <id>]`
963
+
964
+ list comments for an object
965
+
966
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
967
+ |---|---|---|---|---|---|
968
+ | `--object <id>` | string | 是 | - | - | 对象 ID(必填) |
969
+
970
+ **示例**
971
+
972
+ ```bash
973
+ morula comment list --object <id>
974
+ ```
975
+
976
+ > `writes: none` · `interactive: no` · `idempotent: yes`
977
+
978
+ ### `morula comment get`
979
+
980
+ **用法**:`morula comment get <id>`
981
+
982
+ get comment details
983
+
984
+ | 位置参数 | 必填 | 说明 |
985
+ |---|---|---|
986
+ | `<id>` | 是 | 评论 ID |
987
+
988
+ **示例**
989
+
990
+ ```bash
991
+ morula comment get <id>
992
+ ```
993
+
994
+ > `writes: none` · `interactive: no` · `idempotent: yes`
995
+
996
+ ### `morula comment add`
997
+
998
+ **用法**:`morula comment add [--object <id>] [--content <text>] [--parent <id>] [--format <markdown|plain|richtext>] [--mention <principalId[,principalId]>] [--mention-agent <stageExecutorId[,stageExecutorId]>] [--final]`
999
+
1000
+ add comment (format auto-detected; use markdown for agent final summaries). --final 发任务最终总结(同任务只保留一条);--mention 可 @ 人、--mention-agent 可 @ 阶段运行时(触发派发)
1001
+
1002
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1003
+ |---|---|---|---|---|---|
1004
+ | `--object <id>` | string | 是 | - | - | 对象 ID(必填) |
1005
+ | `--content <text>` | string | 是 | - | - | 评论内容(必填) |
1006
+ | `--parent <id>` | string | - | - | - | 父评论(回复) |
1007
+ | `--format <markdown\|plain\|richtext>` | string | - | `markdown` `plain` `richtext` | - | 内容格式(缺省自动检测) |
1008
+ | `--mention <principalId[,principalId]>` | string | - | - | - | @ 人:被提及者的 principalId,可重复传或逗号分隔(合并去重保序) |
1009
+ | `--mention-agent <stageExecutorId[,stageExecutorId]>` | string | - | - | - | @ 阶段运行时:空间「阶段 → 运行时」槽位的 stageExecutorId,可重复传或逗号分隔;触发该执行器在任务上干活(评论 @ 派发) |
1010
+ | `--final` | boolean | - | - | - | 标记本条为任务最终总结(仅任务级凭证可用;同一任务只保留一条,重复发会被服务端拒绝——收尾时先发 final 再上报结果) |
1011
+
1012
+ **示例**
1013
+
1014
+ ```bash
1015
+ morula comment add --object <id> --content <text>
1016
+ morula comment add --object <id> --content <text> --final
1017
+ morula comment add --object <id> --content <text> --mention-agent <stageExecutorId>
1018
+ morula comment add --object <id> --content <text> --mention <principalId>
1019
+ ```
1020
+
1021
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1022
+
1023
+ ### `morula comment update`
1024
+
1025
+ **用法**:`morula comment update <id> [--content <text>]`
1026
+
1027
+ update comment
1028
+
1029
+ | 位置参数 | 必填 | 说明 |
1030
+ |---|---|---|
1031
+ | `<id>` | 是 | 评论 ID |
1032
+
1033
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1034
+ |---|---|---|---|---|---|
1035
+ | `--content <text>` | string | 是 | - | - | 新内容(必填) |
1036
+
1037
+ **示例**
1038
+
1039
+ ```bash
1040
+ morula comment update <id> --content <text>
1041
+ ```
1042
+
1043
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1044
+
1045
+ ### `morula comment delete`
1046
+
1047
+ **用法**:`morula comment delete <id>`
1048
+
1049
+ hard delete comment
1050
+
1051
+ | 位置参数 | 必填 | 说明 |
1052
+ |---|---|---|
1053
+ | `<id>` | 是 | 评论 ID |
1054
+
1055
+ **示例**
1056
+
1057
+ ```bash
1058
+ morula comment delete <id>
1059
+ ```
1060
+
1061
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1062
+
1063
+ <!-- hand:start comment -->
1064
+ ### 手写补充:风险等级 / 幂等性 / Flag → API 字段映射
1065
+
1066
+ **风险等级 / 审批**:`list` / `get` = `read_only`(自动);`add` / `update` = `write_internal`(**需确认**);`delete` = `destructive`(先 `comment get <id>` 展示评论内容,确认后执行;硬删除,数据不可恢复)。
1067
+
1068
+ **幂等性**:`list` / `get` / `update` ✅ 安全重试;`add` ⚠️ 重试可能重复创建。
1069
+
1070
+ **Flag → API 字段映射**:`--object` → `objectId`(任务 ID);`--content` → `content`;`--parent` → `parentCommentId`;`--format` → 内容格式(缺省自动检测);`--mention <principalId>[,<principalId>]` → `mentions: [{ type: 'member', principalId }]`(多个逗号分隔、重复去重;服务端按 member 提及发通知——只支持 @ 人,@ 运行时/智能体不支持)。
1071
+ <!-- hand:end comment -->
1072
+
1073
+ ---
1074
+
1075
+ ## `morula review`
1076
+
1077
+ Code Review verdict submission (review task machine protocol)
1078
+
1079
+ ### `morula review submit`
1080
+
1081
+ **用法**:`morula review submit <objectId> [--verdict <approved|changes_requested|commented>] [--details <text>] [--pr-number <n>]`
1082
+
1083
+ submit Code Review verdict (machine protocol; review task token)
1084
+
1085
+ | 位置参数 | 必填 | 说明 |
1086
+ |---|---|---|
1087
+ | `<objectId>` | 是 | 评审对象 ID(系统提示「评审对象」) |
1088
+
1089
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1090
+ |---|---|---|---|---|---|
1091
+ | `--verdict <approved\|changes_requested\|commented>` | string | 是 | `approved` `changes_requested` `commented` | - | 评审结论(必填) |
1092
+ | `--details <text>` | string | - | - | - | 评审意见(changes_requested 必填:文件/行/问题/建议) |
1093
+ | `--pr-number <n>` | number | - | - | - | 评审对象的 PR 编号(有则填) |
1094
+
1095
+ **示例**
1096
+
1097
+ ```bash
1098
+ morula review submit <objectId> --verdict approved
1099
+ ```
1100
+
1101
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1102
+
1103
+ <!-- hand:start review -->
1104
+ <!-- hand:end review -->
1105
+
1106
+ ---
1107
+
1108
+ ## `morula report`
1109
+
1110
+ autopilot reports (conclusion-heavy output of automated runs)
1111
+
1112
+ ### `morula report create`
1113
+
1114
+ **用法**:`morula report create [--title <text>] [--content <markdown>] [--content-file <path>] [--space <id>] [--autopilot <id>]`
1115
+
1116
+ create an autopilot report (正文二选一:--content 短正文 / --content-file 长 Markdown;--autopilot 省略时按当前任务反查所属自动化)
1117
+
1118
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1119
+ |---|---|---|---|---|---|
1120
+ | `--title <text>` | string | 是 | - | - | 标题(必填) |
1121
+ | `--content <markdown>` | string | - | - | - | 短正文(与 --content-file 二选一) |
1122
+ | `--content-file <path>` | string | - | - | - | 长 Markdown 报告文件(与 --content 二选一) |
1123
+ | `--space <id>` | string | - | - | - | 归属空间 |
1124
+ | `--autopilot <id>` | string | - | - | - | 所属自动化(省略时按当前任务反查) |
1125
+
1126
+ **示例**
1127
+
1128
+ ```bash
1129
+ morula report create --title <t> --content-file <path>
1130
+ ```
1131
+
1132
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1133
+
1134
+ ### `morula report get`
1135
+
1136
+ **用法**:`morula report get <id>`
1137
+
1138
+ get report details (含 Markdown 正文)
1139
+
1140
+ | 位置参数 | 必填 | 说明 |
1141
+ |---|---|---|
1142
+ | `<id>` | 是 | 报告 ID |
1143
+
1144
+ **示例**
1145
+
1146
+ ```bash
1147
+ morula report get <id>
1148
+ ```
1149
+
1150
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1151
+
1152
+ ### `morula report list`
1153
+
1154
+ **用法**:`morula report list [--autopilot <id>] [--page <n>] [--page-size <n>]`
1155
+
1156
+ list reports of an autopilot
1157
+
1158
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1159
+ |---|---|---|---|---|---|
1160
+ | `--autopilot <id>` | string | 是 | - | - | 自动化 ID(必填) |
1161
+ | `--page <n>` | number | - | - | - | 页码 |
1162
+ | `--page-size <n>` | number | - | - | - | 每页条数 |
1163
+
1164
+ **示例**
1165
+
1166
+ ```bash
1167
+ morula report list --autopilot <id>
1168
+ ```
1169
+
1170
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1171
+
1172
+ <!-- hand:start report -->
1173
+ ### 手写补充:风险等级 / 何时产出 / 返回结构
1174
+
1175
+ **风险等级 / 审批**:`get` / `list` = `read_only`(自动);`create` = `write_internal`,但审批为**自动**——写平台产出域,不改动用户已有资源,不需要用户确认。
1176
+
1177
+ **何时用**(`create`):一次执行得出的**结论型重内容**——扫描/巡检结果、审查结论、分析摘要、对比清单、需要留档的建议。过程性进度、寒暄、需要人立刻拍板的一句话走评论/收件箱;正文为 Markdown,人从所属自动化卡片的「报告」入口查看——不进任务看板、不占任务编号。详见 SKILL.md「何时产出报告」。
1178
+
1179
+ **幂等性**:`get` / `list` ✅ 安全重试;`create` ⚠️ 重试会重复产出(先查再决定是否重试)。
1180
+
1181
+ **Flag → API 字段映射**(`create`):`--title` → `title`(必填);`--content` / `--content-file` → `content`(二选一,长报告用文件,超长正文不要塞进 `--content`);`--space` → `spaceId`;`--autopilot` → `autopilotId`(缺省由服务端按当前执行上下文反查 taskId → runId → 自动化并绑定 `runId`)。
1182
+
1183
+ **返回结构**:`create` → `{ id, tenantId, autopilotId, runId, spaceId, title, status: "ready", createdBy, createdAt, updatedAt }`;`list` → `{ data, total, page, pageSize }`;`get` 含 Markdown 正文 `content`。
1184
+
1185
+ **错误**(`create`):退出码 2 — `title/content 不能为空`、`报告必须归属于某个自动化:当前执行上下文未关联自动化,请显式传 --autopilot`;退出码 3 — `Autopilot 不存在`(`--autopilot` 值不对)。
1186
+ <!-- hand:end report -->
1187
+
1188
+ ---
1189
+
1190
+ ## `morula repo`
1191
+
1192
+ task-space VCS repos: materialize checkout / MR read & comment (server channel; never approves/merges)
1193
+
1194
+ > mr 是多级子命令形态(action=mr、子命令位在 positionals[0]):契约按子命令拆分声明(mr create / mr list / ...),严格校验只对单级 action 生效
1195
+
1196
+ ### `morula repo list`
1197
+
1198
+ **用法**:`morula repo list [--space <id>]`
1199
+
1200
+ list task-space VCS connections (the space repo list — the task prompt does NOT list repos; query this when a task may span multiple repos)
1201
+
1202
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1203
+ |---|---|---|---|---|---|
1204
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
1205
+
1206
+ **示例**
1207
+
1208
+ ```bash
1209
+ morula repo list --space <id>
1210
+ ```
1211
+
1212
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1213
+
1214
+ ### `morula repo checkout`
1215
+
1216
+ **用法**:`morula repo checkout <taskId> <repoFullName> [--ref <branch|sha>]`
1217
+
1218
+ materialize a repo into the task workdir (local daemon endpoint preferred, works same-turn; falls back to server machine protocol which resolves scope + workContext)
1219
+
1220
+ | 位置参数 | 必填 | 说明 |
1221
+ |---|---|---|
1222
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
1223
+ | `<repoFullName>` | 是 | 仓库全名(owner/name) |
1224
+
1225
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1226
+ |---|---|---|---|---|---|
1227
+ | `--ref <branch\|sha>` | string | - | `branch` `sha` | - | 检出引用(缺省 = 绑定分支) |
1228
+
1229
+ **示例**
1230
+
1231
+ ```bash
1232
+ morula repo checkout <taskId> <owner/name>
1233
+ ```
1234
+
1235
+ > `writes: local` · `interactive: no` · `idempotent: yes`
1236
+
1237
+ ### `morula repo prepare`
1238
+
1239
+ **用法**:`morula repo prepare <taskId> <repoFullName>`
1240
+
1241
+ materialize a secondary repo into the task workdir (same level as the primary repo dir)
1242
+
1243
+ | 位置参数 | 必填 | 说明 |
1244
+ |---|---|---|
1245
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
1246
+ | `<repoFullName>` | 是 | 次仓库全名(owner/name) |
1247
+
1248
+ **示例**
1249
+
1250
+ ```bash
1251
+ morula repo prepare <taskId> <owner/name>
1252
+ ```
1253
+
1254
+ > `writes: local` · `interactive: no` · `idempotent: yes`
1255
+
1256
+ ### `morula repo files`
1257
+
1258
+ **用法**:`morula repo files [--space <id>] [--repo <owner/name>] [--path <path>] [--ref <branch|sha>]`
1259
+
1260
+ list files in a space repo via the server (read-only, non-task: no local checkout, no AgentTask context)
1261
+
1262
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1263
+ |---|---|---|---|---|---|
1264
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
1265
+ | `--repo <owner/name>` | string | - | - | - | 仓库全名(缺省 = 空间主仓库) |
1266
+ | `--path <path>` | string | - | - | - | 目录路径(缺省 = 仓库根) |
1267
+ | `--ref <branch\|sha>` | string | - | `branch` `sha` | - | 分支 / tag / commit(缺省 = 默认分支) |
1268
+
1269
+ **示例**
1270
+
1271
+ ```bash
1272
+ morula repo files --space <id>
1273
+ morula repo files --space <id> --path src
1274
+ ```
1275
+
1276
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1277
+
1278
+ ### `morula repo read`
1279
+
1280
+ **用法**:`morula repo read [--space <id>] [--path <path>] [--repo <owner/name>] [--ref <branch|sha>]`
1281
+
1282
+ read a single file from a space repo via the server (read-only, non-task)
1283
+
1284
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1285
+ |---|---|---|---|---|---|
1286
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
1287
+ | `--path <path>` | string | 是 | - | - | 文件路径(必填) |
1288
+ | `--repo <owner/name>` | string | - | - | - | 仓库全名(缺省 = 空间主仓库) |
1289
+ | `--ref <branch\|sha>` | string | - | `branch` `sha` | - | 分支 / tag / commit(缺省 = 默认分支) |
1290
+
1291
+ **示例**
1292
+
1293
+ ```bash
1294
+ morula repo read --space <id> --path src/index.ts
1295
+ ```
1296
+
1297
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1298
+
1299
+ ### `morula repo mr create`
1300
+
1301
+ **用法**:`morula repo mr create <repoFullName> [--branch <branch>] [--base <base>] [--task-code <code>]`
1302
+
1303
+ create a GitLab MR for the task via the server channel (target project forced to the bound repo, PR linked immediately; push the branch first)
1304
+
1305
+ | 位置参数 | 必填 | 说明 |
1306
+ |---|---|---|
1307
+ | `<repoFullName>` | 是 | 仓库全名(owner/name) |
1308
+
1309
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1310
+ |---|---|---|---|---|---|
1311
+ | `--branch <branch>` | string | 是 | - | - | 源分支(必填) |
1312
+ | `--base <base>` | string | - | - | - | 目标分支(缺省 MORULA_BASE_BRANCH / main) |
1313
+ | `--task-code <code>` | string | - | - | - | 任务编号(MR 标题/正文回链) |
1314
+
1315
+ **示例**
1316
+
1317
+ ```bash
1318
+ morula repo mr create <owner/name> --branch <b> --task-code <code>
1319
+ ```
1320
+
1321
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1322
+
1323
+ ### `morula repo mr list`
1324
+
1325
+ **用法**:`morula repo mr list <taskId> [--state <opened|closed|merged>] [--limit <n>] [--author <username>] [--repo <owner/name>]`
1326
+
1327
+ list the task-space repos' merge requests (read-only; includes createdAt/updatedAt/author; never approves/merges)
1328
+
1329
+ | 位置参数 | 必填 | 说明 |
1330
+ |---|---|---|
1331
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
1332
+
1333
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1334
+ |---|---|---|---|---|---|
1335
+ | `--state <opened\|closed\|merged>` | string | - | `opened` `closed` `merged` | - | MR 状态过滤(缺省 opened) |
1336
+ | `--limit <n>` | number | - | - | - | 条数上限 |
1337
+ | `--author <username>` | string | - | - | - | 按作者过滤 |
1338
+ | `--repo <owner/name>` | string | - | - | - | 多仓库空间:目标仓库(缺省主仓库) |
1339
+
1340
+ **示例**
1341
+
1342
+ ```bash
1343
+ morula repo mr list <taskId> --state opened
1344
+ ```
1345
+
1346
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1347
+
1348
+ ### `morula repo mr comment`
1349
+
1350
+ **用法**:`morula repo mr comment <taskId> [--mr <iid>] [--repo <owner/name>] [--connection <id>] [--content <text>] [--content-file <path>]`
1351
+
1352
+ write a review comment on an MR/PR (write-only: never approves or merges). 写之前必须先 `morula repo mr get <taskId> --mr <iid> --notes` 读已有讨论:若本自动化已就同一问题留过结论且结论未变,不要再评论。内容为结论 + 关键问题(文件:行 + 建议),末尾加署名行;长内容写成报告后用摘要引用(morula report create → 评论里给要点)
1353
+
1354
+ | 位置参数 | 必填 | 说明 |
1355
+ |---|---|---|
1356
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
1357
+
1358
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1359
+ |---|---|---|---|---|---|
1360
+ | `--mr <iid>` | number | 是 | - | - | MR 编号(必填) |
1361
+ | `--repo <owner/name>` | string | - | - | - | 多仓库空间:目标仓库(缺省主仓库) |
1362
+ | `--connection <id>` | string | - | - | - | 连接 ID(多连接场景) |
1363
+ | `--content <text>` | string | - | - | - | 评论正文(与 --content-file 二选一) |
1364
+ | `--content-file <path>` | string | - | - | - | 评论正文文件(与 --content 二选一) |
1365
+
1366
+ **示例**
1367
+
1368
+ ```bash
1369
+ morula repo mr comment <taskId> --mr <iid> --content-file <path>
1370
+ ```
1371
+
1372
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1373
+
1374
+ ### `morula repo mr get`
1375
+
1376
+ **用法**:`morula repo mr get <taskId> [--mr <iid>] [--repo <owner/name>] [--ci] [--notes]`
1377
+
1378
+ get a single MR detail (read-only; --ci attaches pipeline status where none = no pipeline, not an error; --notes attaches existing comments — read this before writing a comment to avoid duplicates)
1379
+
1380
+ | 位置参数 | 必填 | 说明 |
1381
+ |---|---|---|
1382
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
1383
+
1384
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1385
+ |---|---|---|---|---|---|
1386
+ | `--mr <iid>` | number | 是 | - | - | MR 编号(必填) |
1387
+ | `--repo <owner/name>` | string | - | - | - | 多仓库空间:目标仓库(缺省主仓库) |
1388
+ | `--ci` | boolean | - | - | - | 附带 pipeline 状态 |
1389
+ | `--notes` | boolean | - | - | - | 附带已有评论(写评论前先读,防重复) |
1390
+
1391
+ **示例**
1392
+
1393
+ ```bash
1394
+ morula repo mr get <taskId> --mr <iid> --notes
1395
+ ```
1396
+
1397
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1398
+
1399
+ ### `morula repo mr diff`
1400
+
1401
+ **用法**:`morula repo mr diff <taskId> [--mr <iid>] [--repo <owner/name>] [--max-files <n>] [--max-chars <n>]`
1402
+
1403
+ read an MR diff via the server (read-only; works without a local checkout; truncated flag is set when output was capped)
1404
+
1405
+ | 位置参数 | 必填 | 说明 |
1406
+ |---|---|---|
1407
+ | `<taskId>` | 是 | 本任务 AgentTask UUID |
1408
+
1409
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1410
+ |---|---|---|---|---|---|
1411
+ | `--mr <iid>` | number | 是 | - | - | MR 编号(必填) |
1412
+ | `--repo <owner/name>` | string | - | - | - | 多仓库空间:目标仓库(缺省主仓库) |
1413
+ | `--max-files <n>` | number | - | - | - | 文件数上限 |
1414
+ | `--max-chars <n>` | number | - | - | - | 字符数上限 |
1415
+
1416
+ **示例**
1417
+
1418
+ ```bash
1419
+ morula repo mr diff <taskId> --mr <iid>
1420
+ ```
1421
+
1422
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1423
+
1424
+ <!-- hand:start repo -->
1425
+ <!-- hand:end repo -->
1426
+
1427
+ ---
1428
+
1429
+ ## `morula ci`
1430
+
1431
+ CI/CD pipeline facts + write operations: pipeline runs / job logs / deployments / failed test cases / trigger pipeline / retry / play manual job. Read faces share one command surface — task face `<taskId>` (AgentTask credential, self-check your MR pipeline) vs space face `--space <spaceId>` (steward/session credential, space-wide inspection); the two are mutually exclusive. Write ops (trigger / retry / play) are ONLY open on the space face (not task face); agent_session tokens are read-only for CI (AgentSessionScopeGuard does not whitelist these endpoints). D2: retry of the newest FAILED run is the default when --run is omitted
1432
+
1433
+ > 两个面(任务面 <taskId> / 空间面 --space <spaceId>)互斥:同时给 → usage error(2),都不给同样 usage error。凭证与作用域不同,猜错会变成静默越权或静默失败
1434
+ > D2 写操作(trigger / play / retry)只在空间面开放:agent_session 凭证(管理员)权限只读,不登记 AgentSessionScopeGuard 写面白名单——retry 走管家 elicitation 确认卡,play 仅在 web 人面使用
1435
+ > 服务端业务失败是 HTTP 200 + `{ ok:false, code, message }`:CI_JOB_NOT_FOUND / CI_RUN_NOT_FOUND / TASK_NOT_FOUND / OBJECT_NOT_FOUND → exit 3;CAPABILITY_UNSUPPORTED / NO_CONNECTION / 其余 → exit 1
1436
+
1437
+ ### `morula ci status`
1438
+
1439
+ **用法**:`morula ci status [<taskId>] [--space <id>] [--repo <owner/name>] [--ref <branch>] [--failed] [--limit <n>]`
1440
+
1441
+ pipeline runs + deployments for a task (or a space); hasCiConfig:false comes with a notice explaining the repo has no CI config (not an error); on the space face repos[] answers per repo (a multi-repo space never answers hasCiConfig for "the space" — it is null there); on the task face --repo filters runs client-side by repoFullName and echoes repoFilter (the server does NOT support repo filtering)
1442
+
1443
+ | 位置参数 | 必填 | 说明 |
1444
+ |---|---|---|
1445
+ | `<taskId>` | - | 本任务 AgentTask UUID(与 --space 互斥) |
1446
+
1447
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1448
+ |---|---|---|---|---|---|
1449
+ | `--space <id>` | string | - | - | - | 空间 ID(管家/空间面;与 <taskId> 互斥) |
1450
+ | `--repo <owner/name>` | string | - | - | - | 多仓库空间:只看该仓库的运行(任务面专用,客户端过滤) |
1451
+ | `--ref <branch>` | string | - | - | - | 按分支/tag 过滤(空间面专用) |
1452
+ | `--failed` | boolean | - | - | - | 只看失败的运行(空间面专用) |
1453
+ | `--limit <n>` | number | - | - | - | 运行条数上限(服务端默认 20,上限 100) |
1454
+
1455
+ **示例**
1456
+
1457
+ ```bash
1458
+ morula ci status <taskId>
1459
+ morula ci status --space <id> --failed
1460
+ ```
1461
+
1462
+ > `writes: none` · `interactive: no` · `idempotent: yes` · `emits: ok, taskId, spaceId, runs, deployments, repos, hasCiConfig, notice, repoFilter`
1463
+
1464
+ ### `morula ci log`
1465
+
1466
+ **用法**:`morula ci log [<taskId>] [--space <id>] [--job <jobId>] [--tail <n>]`
1467
+
1468
+ job log by job id (the server resolves the owning run; both faces use this same endpoint — the task/space flag only declares which face you are calling from). `truncated:true` means the log was tail-cut, not complete
1469
+
1470
+ | 位置参数 | 必填 | 说明 |
1471
+ |---|---|---|
1472
+ | `<taskId>` | - | 本任务 AgentTask UUID(与 --space 互斥) |
1473
+
1474
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1475
+ |---|---|---|---|---|---|
1476
+ | `--space <id>` | string | - | - | - | 空间 ID(管家/空间面;与 <taskId> 互斥) |
1477
+ | `--job <jobId>` | string | 是 | - | - | job ID(必填;来自 ci status 的 jobs[].id) |
1478
+ | `--tail <n>` | number | - | - | - | 保留的日志尾部字节数(服务端默认 64KB) |
1479
+
1480
+ **示例**
1481
+
1482
+ ```bash
1483
+ morula ci log <taskId> --job <jobId> --tail 20000
1484
+ ```
1485
+
1486
+ > `writes: none` · `interactive: no` · `idempotent: yes` · `emits: ok, runId, jobId, log, truncated`
1487
+
1488
+ ### `morula ci deployments`
1489
+
1490
+ **用法**:`morula ci deployments [<taskId>] [--space <id>]`
1491
+
1492
+ deployment records for a task (or a space) — display only: deployments do NOT drive lifecycle state (released is driven solely by a successful production-branch pipeline run)
1493
+
1494
+ | 位置参数 | 必填 | 说明 |
1495
+ |---|---|---|
1496
+ | `<taskId>` | - | 本任务 AgentTask UUID(与 --space 互斥) |
1497
+
1498
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1499
+ |---|---|---|---|---|---|
1500
+ | `--space <id>` | string | - | - | - | 空间 ID(管家/空间面;与 <taskId> 互斥) |
1501
+
1502
+ **示例**
1503
+
1504
+ ```bash
1505
+ morula ci deployments <taskId>
1506
+ ```
1507
+
1508
+ > `writes: none` · `interactive: no` · `idempotent: yes` · `emits: ok, spaceId, deployments`
1509
+
1510
+ ### `morula ci test-report`
1511
+
1512
+ **用法**:`morula ci test-report [<taskId>] [--space <id>] [--run <runId>]`
1513
+
1514
+ failed test cases of a run; --run omitted resolves to the newest run in the CI view — no run at all is CI_RUN_NOT_FOUND (exit 3), never an empty report; provider without this capability (GitHub) returns CAPABILITY_UNSUPPORTED
1515
+
1516
+ | 位置参数 | 必填 | 说明 |
1517
+ |---|---|---|
1518
+ | `<taskId>` | - | 本任务 AgentTask UUID(与 --space 互斥) |
1519
+
1520
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1521
+ |---|---|---|---|---|---|
1522
+ | `--space <id>` | string | - | - | - | 空间 ID(管家/空间面;与 <taskId> 互斥) |
1523
+ | `--run <runId>` | string | - | - | - | 运行 ID(缺省 = CI 视图里最新一条运行) |
1524
+
1525
+ **示例**
1526
+
1527
+ ```bash
1528
+ morula ci test-report <taskId>
1529
+ ```
1530
+
1531
+ > `writes: none` · `interactive: no` · `idempotent: yes` · `emits: ok, runId, report`
1532
+
1533
+ ### `morula ci trigger`
1534
+
1535
+ **用法**:`morula ci trigger [--space <id>] [--ref <ref>]`
1536
+
1537
+ trigger a new pipeline on the space's first active connection for the given ref (space face ONLY; ref must be in the connection's integration branch or production branches, or the server rejects with CI_REF_NOT_ALLOWED; NOT idempotent)
1538
+
1539
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1540
+ |---|---|---|---|---|---|
1541
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
1542
+ | `--ref <ref>` | string | 是 | - | - | 要触发流水线的分支名(必填) |
1543
+
1544
+ **示例**
1545
+
1546
+ ```bash
1547
+ morula ci trigger --space <id> --ref dev
1548
+ ```
1549
+
1550
+ > `writes: remote` · `interactive: no` · `idempotent: no` · `emits: ok, action, runId, jobId, externalId, ref, webUrl, acceptedAt`
1551
+
1552
+ ### `morula ci play`
1553
+
1554
+ **用法**:`morula ci play [--job <jobId>]`
1555
+
1556
+ trigger a manual job (space face ONLY — job id lookup is stateless; NOT idempotent; only manual jobs — status=manual — can be played, others get CI_JOB_NOT_MANUAL)
1557
+
1558
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1559
+ |---|---|---|---|---|---|
1560
+ | `--job <jobId>` | string | 是 | - | - | 平台 job ID(必填;来自 ci status 的 jobs[].id,须为手动 job) |
1561
+
1562
+ **示例**
1563
+
1564
+ ```bash
1565
+ morula ci play --job <jobId>
1566
+ ```
1567
+
1568
+ > `writes: remote` · `interactive: no` · `idempotent: no` · `emits: ok, action, runId, jobId, externalId, ref, acceptedAt`
1569
+
1570
+ ### `morula ci retry`
1571
+
1572
+ **用法**:`morula ci retry [--space <id>] [--run <runId>] [--job <jobId>]`
1573
+
1574
+ re-run a failed pipeline (space face ONLY — a positional <taskId> is a usage error, retry is not open to the task face; person + steward, and a steward must go through an elicitation confirm card). Omit both --run and --job to retry the newest FAILED run of the space (no failed run at all → CI_RUN_NOT_FOUND exit 3). Only failure/cancelled runs or jobs can be retried (CI_RETRY_NOT_ALLOWED exit 6). NOT idempotent: every call starts another platform re-run
1575
+
1576
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1577
+ |---|---|---|---|---|---|
1578
+ | `--space <id>` | string | 是 | - | - | 空间 ID(必填) |
1579
+ | `--run <runId>` | string | - | - | - | 要重跑的运行 ID(与 --job 互斥;缺省 = 该空间最新一条失败运行) |
1580
+ | `--job <jobId>` | string | - | - | - | 要重跑的单个 job ID(与 --run 互斥;来自 ci status 的 jobs[].id) |
1581
+
1582
+ **示例**
1583
+
1584
+ ```bash
1585
+ morula ci retry --space <id>
1586
+ morula ci retry --space <id> --job <jobId>
1587
+ ```
1588
+
1589
+ > `writes: remote` · `interactive: no` · `idempotent: no` · `emits: ok, action, runId, jobId, externalId, ref, acceptedAt`
1590
+
1591
+ <!-- hand:start ci -->
1592
+ <!-- hand:end ci -->
1593
+
1594
+ ---
1595
+
1596
+ ## `morula obs`
1597
+
1598
+ observability runtime environment ONLY — this is not a query surface. It hands this machine the gateway entry (GRAFANA_SERVER) + a 30-minute, space-scoped, read-only token (GRAFANA_TOKEN) + minimal context (current source + every usable source of the space), so the agent queries line-side facts DIRECTLY with the runtime-managed engine (gcx) through the platform gateway; write paths are refused by the gateway with 403. The platform defines no query command surface: the engine owns the commands and the syntax (gcx --help / gcx commands). Task face by default (task credential, space inferred); --space <spaceId> for the user face
1599
+
1600
+ > 只交付运行环境,不是查询命令面:查询由 agent 直接用受管引擎(`gcx`)发起——命令与语法是引擎的运行期资产(`gcx --help` / `gcx commands`),平台不列举、不代理
1601
+ > 只读边界在平台网关(写方法一律 403),不在 CLI:本 resource 没有写操作,也没有 raw / 透传子命令
1602
+ > **不写任何文件**、无副作用:令牌只打印,不进 argv、不进日志、不落盘
1603
+ > 没有可用源(未配置 / 全部停用 / 没有默认源 / 指定源已停用)→ 200 + `server` / `token` 为 null + `notice`:默认输出只给注释(人话 + 可执行下一步),**退出码 3(not found)**
1604
+ > 退出码:缺身份面 / 两面同时给 → 2;没有可用运行环境、`--source` 不存在 → 3;换取 401 → 4;换取 403 → 5;网络 / 上游 → 7(都带可执行 hint)
1605
+
1606
+ ### `morula obs env`
1607
+
1608
+ **用法**:`morula obs env [--source <name|id>] [--space <spaceId>] [--json]`
1609
+
1610
+ exchange the running environment. Default output is a shell export you can `eval` directly (GRAFANA_SERVER / GRAFANA_TOKEN / GRAFANA_ORG_ID); --json returns the raw response (server / token / expiresAt / context / notice). The env is issued PER SOURCE (server carries the sourceId), so switching sources or renewing the 30-minute token means calling this again with --source <name|id>. Nothing is written to disk (the token never touches a file)
1611
+
1612
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1613
+ |---|---|---|---|---|---|
1614
+ | `--source <name\|id>` | string | - | `name` `id` | - | 数据源 name 或 id(缺省用空间默认源;env 按源签发,换源请重新调用) |
1615
+ | `--space <spaceId>` | string | - | - | - | 空间 ID(用户身份;缺省走任务面,空间由任务凭证推断;与任务面互斥) |
1616
+ | `--json` | boolean | - | - | - | 输出运行环境接口的原始响应 JSON(server / token / expiresAt / context / notice),而不是可 eval 的 shell export |
1617
+
1618
+ **示例**
1619
+
1620
+ ```bash
1621
+ eval "$(morula obs env)"
1622
+ morula obs env --source staging --json
1623
+ ```
1624
+
1625
+ > `writes: none` · `interactive: no` · `idempotent: yes` · `emits: server, token, expiresAt, context, notice`
1626
+
1627
+ <!-- hand:start obs -->
1628
+ <!-- hand:end obs -->
1629
+
1630
+ ---
1631
+
1632
+ ## `morula attachment`
1633
+
1634
+ file attachments for objects / comments / chat messages (local file upload)
1635
+
1636
+ ### `morula attachment upload`
1637
+
1638
+ **用法**:`morula attachment upload <file> [--object <id>] [--comment <id>] [--ag-message] [--task <agentTaskId>] [--inline]`
1639
+
1640
+ upload a local file and attach it to a task (--object) / comment (--comment) / chat message (--ag-message); for pure chat tasks pass --task <agentTaskId> to attach to the chat session; omit target to auto-merge (object if bound, else chat message)
1641
+
1642
+ | 位置参数 | 必填 | 说明 |
1643
+ |---|---|---|
1644
+ | `<file>` | 是 | 本地文件路径 |
1645
+
1646
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1647
+ |---|---|---|---|---|---|
1648
+ | `--object <id>` | string | - | - | - | 挂到对象 |
1649
+ | `--comment <id>` | string | - | - | - | 挂到评论 |
1650
+ | `--ag-message` | boolean | - | - | - | 挂到 Chat 会话最新消息 |
1651
+ | `--task <agentTaskId>` | string | - | - | - | 纯 Chat 任务归并到会话消息 |
1652
+ | `--inline` | boolean | - | - | - | 内联附件 |
1653
+
1654
+ **示例**
1655
+
1656
+ ```bash
1657
+ morula attachment upload <file> --object <id>
1658
+ ```
1659
+
1660
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1661
+
1662
+ ### `morula attachment list`
1663
+
1664
+ **用法**:`morula attachment list [--object <id>]`
1665
+
1666
+ list attachments for an object
1667
+
1668
+ | Flag | 类型 | 必填 | 取值 | 默认 | 说明 |
1669
+ |---|---|---|---|---|---|
1670
+ | `--object <id>` | string | 是 | - | - | 对象 ID(必填) |
1671
+
1672
+ **示例**
1673
+
1674
+ ```bash
1675
+ morula attachment list --object <id>
1676
+ ```
1677
+
1678
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1679
+
1680
+ ### `morula attachment get`
1681
+
1682
+ **用法**:`morula attachment get <id>`
1683
+
1684
+ get attachment details
1685
+
1686
+ | 位置参数 | 必填 | 说明 |
1687
+ |---|---|---|
1688
+ | `<id>` | 是 | 附件 ID |
1689
+
1690
+ **示例**
1691
+
1692
+ ```bash
1693
+ morula attachment get <id>
1694
+ ```
1695
+
1696
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1697
+
1698
+ ### `morula attachment download-url`
1699
+
1700
+ **用法**:`morula attachment download-url <id>`
1701
+
1702
+ get signed download URL for an attachment
1703
+
1704
+ | 位置参数 | 必填 | 说明 |
1705
+ |---|---|---|
1706
+ | `<id>` | 是 | 附件 ID |
1707
+
1708
+ **示例**
1709
+
1710
+ ```bash
1711
+ morula attachment download-url <id>
1712
+ ```
1713
+
1714
+ > `writes: none` · `interactive: no` · `idempotent: yes`
1715
+
1716
+ ### `morula attachment delete`
1717
+
1718
+ **用法**:`morula attachment delete <id>`
1719
+
1720
+ delete attachment
1721
+
1722
+ | 位置参数 | 必填 | 说明 |
1723
+ |---|---|---|
1724
+ | `<id>` | 是 | 附件 ID |
1725
+
1726
+ **示例**
1727
+
1728
+ ```bash
1729
+ morula attachment delete <id>
1730
+ ```
1731
+
1732
+ > `writes: remote` · `interactive: no` · `idempotent: no`
1733
+
1734
+ <!-- hand:start attachment -->
1735
+ ### 手写补充:风险等级 / 归并语义 / 返回结构
1736
+
1737
+ **风险等级 / 审批**:`list` / `get` / `content` / `download-url` = `read_only`(自动);`upload` = `write_internal`(**需确认**);`delete` = `destructive`。
1738
+
1739
+ **幂等性**:`upload` ⚠️ 重试会重复创建附件;读取类 ✅ 安全重试。
1740
+
1741
+ **Flag → API 字段映射**(`upload`):
1742
+
1743
+ | Flag | API 字段 |
1744
+ |---|---|
1745
+ | `--object` | `resourceId`(`resourceType=object`)——挂到任务对象附件 |
1746
+ | `--comment` | `resourceId`(`resourceType=comment`)——挂到评论附件 |
1747
+ | `--ag-message` | `resourceType=ag_message`——挂到 Chat 会话最新消息附件 |
1748
+ | `--task` | `taskId`(AgentTask 任务 ID,从 task-context.md 读;纯 Chat 任务上传时用于归并到会话消息) |
1749
+ | `--inline` | `isInline`(仅正文内嵌,不进附件列表) |
1750
+
1751
+ **返回**:`{ id, resourceType, resourceId, fileUrl, fileName, fileType, fileSize, downloadUrl }`。`downloadUrl` 为签名下载链接,可写进交付评论供用户访问。
1752
+
1753
+ **智能归并**:`--object` / `--comment` / `--ag-message` 三选一互斥;全不传时服务端按任务绑定对象自动决定——有 object 挂 object;**纯对话(无对象)任务必须带 `--task <AgentTaskID>`**,服务端据此挂到该 Chat 会话最新消息(ag_message)。
1754
+
1755
+ **注意**:文件类型不限(服务端放开到通用类型),单文件上限 20MB;挂 `object` / `comment` 时 agent_task 作用域要求落在任务绑定对象内。
1756
+ <!-- hand:end attachment -->