@arcships/morula-runtime 0.1.0-alpha.7 → 0.1.0-alpha.8

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