@arcships/morula-runtime 0.1.0-alpha.17 → 0.1.0-alpha.19

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,406 +1,19 @@
1
1
  ---
2
2
  name: morula-working-on-issues
3
- description: "Use when working on a Morula task after the daemon has provided the trigger context — to apply the product contracts the runtime brief does not encode: CLI-only platform interaction, PR linking vs close intent, how to read a linked PR's real state, task-number routing, status side effects, and final-comment delivery discipline."
3
+ description: "Superseded by the morula-platform skill — load that instead. This stub only records where the Morula task contracts moved to."
4
4
  user-invocable: false
5
5
  allowed-tools: Bash(morula *), Bash(git *), Bash(gh *)
6
6
  ---
7
7
 
8
- > 本文件是随 CLI 插件分发的**文档副本**。daemon 执行任务时会按平台在任务工作区
9
- > `.agents/skills/morula-working-on-issues/SKILL.md` 注入**权威版本**(GitLab 任务会附带 GitLab 平台说明段),
10
- > 两者正文同源。命令细节以工作区内注入的那份与 `morula <resource> --help` 为准。
8
+ # Moved into `morula-platform`
11
9
 
12
- # Working on Morula issues(协作契约)
10
+ Morula 的任务协作契约已并入 `morula-platform` skill(开篇分工 + Routing + 按域手册):
13
11
 
14
- 本 SKILL 是 Morula 平台对本地智能体(daemon 执行的 AgentTask)的行为契约。
15
- 每条契约都溯源到服务端实现,见 `references/working-on-issues-source-map.md`。
16
- 在 daemon 派发的任务中,本 SKILL 会被自动注入到工作目录 `.agents/skills/`,由 Agent CLI 自动发现。
17
-
18
- ## 0. 运行时上下文与任务详情获取(对应任务系统提示词,必须一一对应)
19
-
20
- 任务系统提示词(发给你的首条消息)只承载四样:**你的身份与边界**(阶段职责)、**你的目标**(「你的目标」段)、
21
- **钥匙**(「基本信息」段的任务 ID / 空间 ID——只是命令入参,不是任务信息)、**工作区与工具入口**(本 skill 与
22
- `morula task get` / `morula repo list` 的用法指引)。**其余上下文与任务详情一律不进提示词**,用 CLI 获取:
23
-
24
- - **当前任务详情**:`morula task get`(无参)——taskId 由执行环境提供(`MORULA_TASK_ID` env / `.morula/checkout.json`),无需也不应从别处猜。返回:`id`(本任务 AgentTask ID,UUID)、`code`(任务编号,如 `SPW299-59`)、`objectId`(关联业务任务对象)、`taskPrompt`(本次目标原文)、`contextSnapshot`、`status`。
25
- - **业务任务详情**(标题/描述):`morula task get <objectId>`;**关键评论**(用户原始诉求/分析结论):`morula comment list --object <objectId>`。
26
- - **空间仓库清单**(多仓库任务判断依据):`morula repo list --space <spaceId>`——提示词不列仓库,需要时自己查。
27
- - **「你的目标」**:系统提示「你的目标」段 = 本次任务的原始诉求,据此判断要做什么。
28
-
29
- > **调 CLI 一律用 `$MORULA_CLI`**(daemon 注入的绝对路径,指向与本次运行同源的构建;下文所有 `morula xxx`
30
- > 都按 `$MORULA_CLI xxx` 执行)。PATH 上的裸 `morula` 可能是宿主自带的旧版本(缺命令面、且不认会话/任务
31
- > 凭证 → 写操作署名错误),不要用它;`env VAR=... $MORULA_CLI xxx` 这类 env 包装下同样可用。
32
- > 仅当 `$MORULA_CLI` 为空时才退回裸 `morula`。
33
-
34
- > **工作目录 = 任务工作区根**:根下放 `AGENTS.md`(空间项目说明,已作为 project.instructions 自动加载)、
35
- > `.agents/`、`.agent_context/`、`.morula/`;**各仓库是工作区根下的子目录**(见 0.5)。
36
- > 下文的 `AGENTS.md`/`.agents/`/`.agent_context/` 路径都相对这个工作区根。
37
-
38
- > **任务上下文文件**:同一套上下文也写在工作目录 `.agent_context/task-context.md`(与首条系统提示同源)。
39
- > 需要再次确认任务边界时**读取该文件**(`cat .agent_context/task-context.md`),不要凭记忆推断。
40
-
41
- > **本契约自身的读取方式**:契约以项目级 skill 形式注入在 `.agents/skills/morula-working-on-issues/SKILL.md`。
42
- > 用 `skill` 工具按名加载**可能报 `Unknown skill`**(该工具的发现范围不含项目级目录)——此时
43
- > **直接读文件**(`cat .agents/skills/morula-working-on-issues/SKILL.md` 或 read 工具),
44
- > **不要因为加载失败就跳过契约**(issues/injected-contract-skill-not-loadable-by-skill-tool.md)。
45
-
46
- 详情见下文各节对 TaskID / 对外编号的具体用法。
47
-
48
- ## 0.1 通用行为约束
49
-
50
- 以下为所有任务(含 Chat 会话派发)恒常生效的行为约束,**无论任务是否有关联业务对象**:
51
-
52
- 1. **直接回答用户的问题**。若用户要求查任务/了解项目(如「有哪些待处理任务」「XX任务详情」),请用 `morula` CLI(`morula task list`、`morula task get`、`morula space list` 等)或对应的挂载 skill(如 `task-management` 的 `search_objects` / `get_object_detail`)查询真实数据后再答;不要凭猜测或「我没有渠道」回绝。不要执行「验证性/自证性」命令来向用户证明链路是通的(如 `morula auth status` 等)。
53
- 2. **本任务若没有关联的业务对象(objectId 为空,常见于 Chat 会话派发)**:只允许**读**业务 API;不要调用 `morula comment add/delete`(必然失败,也无需尝试),也不要主动改任务状态/指派(状态由服务端按 PR 事件自动流转)。若任务关联了业务对象,则按本 SKILL 的评论/状态纪律正常处理。
54
- 3. **回复要简洁、结论先行**:用大白话直接回答用户问题;不要写「交付清单」「完成情况」「做了什么」式汇报,不要复述你调了什么命令。
55
- 4. **仅当用户明确要求改代码/建分支/MR 时**,才按本 SKILL 的协作契约执行;否则本任务不涉及分支、PR、评论,回复里也不要出现这些章节。
56
-
57
- ## 0.2 本任务编号
58
-
59
- > **适用前提(PR/分支类契约)**:本节及后文 PR/分支/关单约定**仅当任务涉及代码改动时适用**。
60
- > 纯问答、调研、分析、本地起服务类任务:**不建分支、不提 PR、最终评论不出现 PR 章节**,直接回答用户问题。
61
-
62
- - 本任务的对外编号(在任务看板 URL / 列表可见)可能形如 `STR-101` 或 `AGENT-463963`。
63
- - **PR 关联只由平台通道产生**(2026-09-24 定案):**只有经平台通道建出来的 PR 会自动关联到任务**——
64
- `morula repo mr create`(推荐)或 `gh pr create` 后调 `report_pr` 工具上报。平台按自己的事实(哪个任务、
65
- 哪条分支、哪个 workContext)认领,**不读 PR 文本**。
66
- - **不要在 PR 标题/正文里靠任务编号「标记归属」**:服务端**不再扫描** title/branch/body 找任务编号。
67
- 人工在 GitLab/GitHub 上手工建的 PR 平台**不关联**(不进关联区、不触发自动评审、不驱动任务状态)。
68
- - **关单**:关联上的 PR 合并后,服务端按既有流程自动推进任务状态(全部 MR 合并 → 已合并;这些提交进入生产分支 → 已发布)。
69
- 不需要 `Closes` 之类关键字——**关联本身就是授权**。
70
- - 仍然建议 PR 标题以「`<任务编号>: 描述`」开头、正文写一句 `Closes <任务编号>`:**这是给人看的可读性**(平台不再依赖它),
71
- 且是任务与 PR 之间最省事的对照线索。
72
-
73
- ## 0.3 分支命名:由你(Agent)取名并上报
74
-
75
- - **任务 ID 获取**:本任务的 AgentTask ID(UUID)在系统提示「基本信息」段(也是 `morula task get`(无参)返回的 `id`,`.agent_context/task-context.md` 开头亦有)。需要调用 `morula task branch` 时用它作为 taskId。
76
- - **重要区分**:`morula task branch <taskId>` 的 taskId 用**本任务 UUID**(机器协议);MR 标题里的任务编号用**对外编号 code**(如 `AGENT-958201`)——但注意**编号只影响可读性,不再影响关联**(服务端不读 PR 文本,见第 0.2 / 2 条)。
77
- - **只有需要改代码并推分支的任务才取名**;纯问答/只读调研/本地起服务不建分支(见第 3 条决策树)。
78
- - **先检查当前分支**:若仓库已有 feature 分支(同任务/同一改动闭环的后续轮次复用),**直接继续用当前分支,不要新建**(在仓库目录内执行):
79
- ```bash
80
- cd <工作区根>/<仓库目录> && git branch --show-current # 若非空且非 main/master → 用这个分支继续改
81
- ```
82
- - 若当前为 detached HEAD(首次执行),且任务确实要改代码:
83
- 1. 创建分支。分支名**严格由以下部分依次拼成,不多不少**:`<type>` + `/` + `<slug>`
84
- - `<type>`:取下方「命名规范」清单里的一个(按任务性质选,如文档改动用 docs);
85
- - `<slug>`:具体工作事情,小写、用 `-` 连接。
86
- ```bash
87
- git switch -c <type>/<slug>
88
- ```
89
- 例:做 mention 相关的测试补全 → 分支名 `test/mention-tests`;修复登录 401 → `fix/login-401`
90
- 分支名**到 `<slug>` 为止就结束** —— slug 之后不再接任何内容。
91
- 2. **通过 CLI 把分支名上报服务端**(必须,服务端据此做 PR 关联/清理):
92
- ```bash
93
- morula task branch <taskId> --name <type>/<slug>
94
- ```
95
- - **`morula task branch` 需要 `MORULA_RUNTIME_ID`**(daemon 注入的 env,用于校验你的归属)。若你的 exec 环境没有这个 env,**从主仓库目录内的 `.morula-worktree.json` 读取 `runtimeId` 字段**(完整路径 `<工作区根>/<仓库目录>/.morula-worktree.json`;工作区根下没有这个文件),用 `env MORULA_RUNTIME_ID=<该值> morula task branch ...` 或导出后再调用(不要从别处猜)。
96
- - **命名规范**(分支名会出现在 PR、CI、历史里,必须规范):
97
- - 前缀 type 选一:`feature`(新功能)、`fix`(缺陷修复)、`hotfix`(紧急/线上)、`docs`(文档)、`refactor`(重构)、`chore`(杂务)、`test`(测试)、`perf`(性能)、`style`(样式)、`build`(构建/依赖)、`ci`(CI)、`revert`(回滚);
98
- - slug = 具体工作事情,小写、用 `-` 连接(可用英文;**不要用中文**,中文分支名不被多数 CI/工具链支持);
99
- - **只按本节规则拼,不要参考/模仿仓库里已有分支的命名**:历史分支是过往产物(可能含日期后缀、任务编号等旧形态),照着它们取名会沿用旧习惯;分支名完全由上面两段决定,与仓库现有分支无关;
100
- - **分支名到 slug 就结束**:slug 之后**不再追加任何内容**——日期、时间戳、轮次号、随机串都不要;日期不表达语义,且会让「同一件事的后续轮次复用同分支」看起来像要新建分支;
101
- - **分支名是全仓库共享的命名空间,撞名会被拒绝**:若 `morula task branch` / `morula repo mr create` 返回 `BRANCH_OWNED_BY_OTHER_TASK`(分支名已被其他任务占用),换一个更具体的 slug 重新取名、上报后再继续;
102
- - **禁止**用 `main`/`master`,禁止以 `-` 开头/结尾,长度 ≤ 255。
103
- - 如果你不改代码,**不要**创建分支,也不要调用 `morula task branch`。
104
-
105
- ## 0.4 开工前先确认工作现场
106
-
107
- - **先确认自己站在哪个目录**:工作目录是**任务工作区根**,仓库在其下的子目录(见 0.5)。`git/gh` 命令必须在**仓库目录内**执行。
108
- - **改代码前先看现场**(防止在错误的分支/目录上动手)——进入对应仓库目录后:
109
- ```bash
110
- cd <工作区根>/<仓库目录> # 主仓库目录 = 仓库全名把 / 换成 -(如 human-resources-xxx)
111
- git status # 是否有未提交改动(复用前一轮成果时正常,但要知道有什么)
112
- git branch --show-current # 当前分支;detached HEAD 表示本轮尚未取名
113
- ```
114
- - 若 `git status` 显示工作目录有**不属于本任务**的改动(如误入其他任务 worktree),**立即停止并报告**,不要继续编辑。
115
- - **不要在工作区根直接跑 git/gh**:工作区根不是 git 仓库(除仓库子目录外还有 `AGENTS.md`/`.agents/`/`.agent_context/`/`.morula/`),在根目录跑 git 只会报 `not a git repository`。`morula` CLI 反之可从工作区根**或其任意子目录**执行(它从 cwd 向上查找 `.morula/checkout.json` 凭据)。
116
- - **工作区准备(全新检出,先补环境前置再跑构建/验收命令)**:
117
- - 本工作区是全新检出,`node_modules` 不存在:先按仓库声明的包管理器安装依赖——有 `pnpm-lock.yaml` 用 `pnpm install`、`package-lock.json` 用 `npm ci`、`yarn.lock` 用 `yarn`;
118
- - 仓库使用 Prisma 时(存在 `prisma/schema.prisma`)先 `npx prisma generate`,否则 `tsc` 会报大量与本次改动无关的错误;
119
- - 验收/构建命令失败时,先区分「环境前置(依赖、生成物缺失)」与「自身改动」:环境前置先补齐再复跑,不要把环境报错当成本次改动的问题去修。
120
-
121
- ## 0.5 仓库与工作目录
122
-
123
- - **工作目录 = 任务工作区根**;仓库是它下面的**子目录**(清单里没有的仓库不在本地):
124
-
125
- ```
126
- <工作区根>/ ← 你的 cwd(pwd 就在这里)
127
- ├── AGENTS.md ← 空间项目说明(已自动加载为 project.instructions)
128
- ├── .agents/skills/ ← 协作契约 + 本任务自定义 skill
129
- ├── .agent_context/task-context.md ← 任务上下文(见 0 节)
130
- ├── .morula/checkout.json ← daemon 凭据(CLI 内部使用,不要手动读)
131
- ├── <owner>-<repo>/ ← 主仓库(已按平台解析结果物化;本地没有的仓库按需 checkout)
132
- └── <owner>-<repo2>/ ← 次仓库 / 只读检出(按需物化,与主仓库同级)
133
- ```
134
-
135
- - **git / gh 命令一律在对应仓库目录内执行**(`cd <工作区根>/<仓库目录>`,或 `git -C <仓库目录> ...`):
136
- 工作区根不是 git 仓库,在根目录跑 git 命令必然失败。`morula` CLI 可在工作区根或其任意子目录执行(见 0.4)。
137
- - **主仓库**:平台已解析出的仓库在**工作区根下就绪**(目录名 = 仓库全名把 `/` 换成 `-`,如 `human-resources/xxx` → `human-resources-xxx`);`ls` 工作区根即可看到,直接在该目录内建分支/提交/推分支/提 PR。**需要空间绑定了哪些仓库时自己查**:`morula repo list --space <spaceId>`(spaceId 见系统提示「基本信息」段)。
138
- - **⚠️ `morula repo checkout` 的语义 = 「声明/切换本任务的主仓库」**(服务端 generation+1 + daemon 物化工作区):
139
- 声明只作用于当前任务(当前阶段的执行者);**开发阶段任务不继承分析阶段的声明**——需要改代码时由你自己
140
- 按任务描述/分析结论 checkout。因此只在**判定出主仓库之后**调用,**一次任务只声明一次**(判错要纠正时才再调一次)。
141
- 不要用它「把空间里的仓库逐个逛一遍」——每调一次主仓库就跟着换一次(真机踩到:分析阶段为查证 checkout 了 3 个仓库,
142
- 主仓库最终停在最后那个「只看了一眼」的仓库上)。
143
- - **若任务需要了解仓库内容/代码/提交状态(读场景,含纯问答)**:
144
- - **首选服务端只读**(不切主仓库、不建工作上下文):`morula repo files --space <spaceId> [--repo <owner/name>] [--path <p>]` 列目录、
145
- `morula repo read --space <spaceId> --repo <owner/name> --path <p>` 读文件;
146
- - 需要 git 历史 / 分支 / 全仓检索时:只对**候选主仓库**用 `morula repo checkout <taskId> <repoFullName>`
147
- (本轮立即物化,路径通常是工作区根下的 `<仓库目录>-readonly`),然后在该路径内只读查证:
148
- `git -C <路径> log --oneline -20`、`git -C <路径> branch -a`、`rg "关键词" <路径>` 等(**只读**,不建分支、不改代码、不提 PR);
149
- 刷新远端最新:`git -C <路径> fetch origin --prune`(remote 已配置 SSH,免密)。
150
- **若为查证物化过「非结论」仓库,结论产出前必须再 `repo checkout` 一次结论仓库**,把主仓库摆正。
151
- - **本地没有 ≠ 仓库不存在**:仓库内容用 `morula repo read` / `repo files` 查(服务端读,不受本地物化状态影响);
152
- **不要**因为在 `repos/`、`worktrees/` 或常见目录搜索不到就断言「本地没有该仓库」。
153
- - **若任务需要改代码**:用 `morula repo checkout <taskId> <repoFullName>` 拉取/切换仓库(认证已由执行环境注入),
154
- 拿到返回的仓库路径后**chdir 进该仓库目录**,再按第 0.3 条建分支、第 3 条提 PR。可选 `--ref <branch|sha>` 指定检出分支。
155
- - **若任务纯问答、或空间无可用仓库**:直接回答用户问题,不构建分支/PR(见第 3 条决策树)。
156
- - **若任务涉及多个仓库(多仓库任务)**:涉及哪些仓库由**你**结合任务描述判断(任务描述里的「涉及仓库」是管家的初始判断;空间绑定了哪些仓库用 `morula repo list --space <spaceId>` 查;执行中发现还需改动其他仓库时,自行 prepare 拉取),**不需要向用户逐个确认**:
157
- 1. 主仓库:在它的子目录内直接 git 操作(工作区根不是仓库);
158
- 2. 其他仓库用 `morula repo prepare <taskId> <repoFullName>` 物化到任务工作区根下(**与主仓库同级的子目录**,本地 daemon 端点,本轮立即物化并返回路径;git 协议拉取,不走平台 API);
159
- 3. 在哪个仓库改动,就在哪个仓库内建分支(第 0.3 条命名规范)、推分支并**经平台通道建 PR/MR**(`morula repo mr create` 优先;标题带任务编号仅为可读性)。**只有经平台通道建的 PR 才会关联到本任务**(服务端不读 PR 文本,见第 2 条)。**分支名逐仓上报**:主仓库(其子目录)用 `morula task branch <taskId> --name <分支名>`;次仓库(同级子目录)用 `morula task branch <taskId> --name <分支名> --repo <owner/name>` —— 服务端据此把分支名写到该仓库的工作上下文(平台侧逐仓建 MR 兜底、交付清单都依赖它;不报则一直停在占位分支名 `morula/tmp-*`,平台找不到你的分支);
160
- 4. prepare 目录二次调用会 fetch 更新但**不动工作区**——跨轮复用时先 `git status` 确认现场。
161
- - **安全边界**:只在本任务的任务工作区根(及其仓库子目录)内操作;禁止探索/修改工作区根之外的路径(尤其 daemon 根目录下其他任务的 `repos/`、`worktrees/`、`scratch/`)。
162
- - **本地验证服务端口隔离**(issues/local-backend-watch-instability.md):若任务需要启动本地服务验证(如 `npm run dev` / `nest start` 等),**必须使用非平台占用端口**——绑定 `127.0.0.1` 的高位随机端口(如 127.0.0.1:18080+),**禁止**使用 `8080`(平台后端)及 `15173`(平台前端)等平台占用端口,也不要依赖终端会话存活(后台进程方式启动,用 `nohup`/`disown` 或 `&!` 脱离);启动后自测可用即可,不需要(也不应)让平台侧访问。云端沙箱化后由沙箱网络策略兜底。
163
-
164
- ## 1. 与平台交互:只能通过 `morula` CLI
165
-
166
- - **所有**平台资源访问(任务详情、评论、附件、状态、工作区)只通过 `morula` CLI(可从工作区根或其任意子目录执行,见 0.4/0.5)。
167
- **`<taskId>` = `morula task get`(无参)返回的 `id`**(本任务 AgentTask UUID)——下文所有机器协议命令的 id 位都用它,不要用任务编号或别的 id 替代。
168
- ```bash
169
- morula task get # 本任务详情(**无参**;返回 id / code / objectId / taskPrompt / contextSnapshot / status)
170
- morula task get <objectId> # 业务任务(Object)详情(标题/描述);注意这里要的是 objectId,不是本任务 UUID
171
- morula task branch <taskId> --name <分支名> [--repo <owner/name>] # 上报你取的分支名(见 0.3;多仓库任务的次仓库加 --repo)
172
- morula repo checkout <taskId> <repoFullName> [--ref <branch|sha>] # 拉取/切换仓库(返回物化路径,见 0.5)
173
- morula repo prepare <taskId> <repoFullName> # 多仓库任务:物化其他仓库到任务工作区根下(见 0.5)
174
- morula comment list --object <objectId> # 读评论(任务=objectId)
175
- morula comment add --object <objectId> --content <文本> # 发评论(最终总结加 --final,见第 5 条)
176
- morula task inbox [--peek] # 运行中检查点:取本线程未消费消息,纳入本回合(见 1.3)
177
- # 注:任务收尾先发 final 总结评论(morula comment add --final),再上报结果;服务端只在你没发时兜底代发一条。
178
- ```
179
- - **可用仓库清单**:系统提示**不再列出**仓库——需要枚举空间绑定的仓库时用
180
- `morula repo list --space <spaceId>`(`<spaceId>` 见系统提示「基本信息」段,或 `morula task get` 返回的 `contextSnapshot.spaceId`)。
181
- - **每个命令的完整参数以 `morula <resource> --help` 为准**(如 `morula repo --help` 只列 repo 的用法);不确定某命令支持哪些旗标时先查它,不要凭记忆拼参数。
182
- - **禁止** `curl` / `wget` 直连平台 REST API;禁止读取 `~/.morula-cli/config.yaml`、token 文件或环境变量中的密钥。
183
- - **本地 `.morula/checkout.json` 是 daemon 管理文件**(`morula repo checkout` 内部读取端口与任务凭据),**不要手动读取/复制其中的字段**;凭据由 CLI 处理,你不需要也不应当看到它。
184
- - CLI 的 `--token`/环境变量凭据已由 daemon 注入,无需(也不允许)自行登录或携带令牌。
185
- - 如果某项操作 CLI 不支持,在最终评论里说明,**不要**用绕过方式硬做。
186
-
187
- ## 1.1 生成文件必须回传平台(智能体 → 平台)
188
-
189
- 若你的交付物是**文件**(报告、文档、图表格、xlsx、图片、压缩包等),且用户需要在线查看/下载,**必须**用 `morula attachment upload` 把本机文件回传到平台,而不是在消息里给一个本地相对路径/文件名(用户打不开):
190
-
191
- - **纯 Chat 会话任务(推荐)**:本任务不关联业务对象(task-context.md 无 objectId),**必须带 `--task <AgentTaskID>`**(AgentTask ID = `morula task get`(无参)返回的 `id`(或 task-context.md 开头的 UUID)),服务端据此把文件挂到本 Chat 会话消息:
192
- ```bash
193
- morula attachment upload <file> --task <AgentTaskID>
194
- ```
195
- - **默认智能归并**(有绑定对象时):不传目标参数,服务端自动决定——有任务绑定对象挂对象:
196
- ```bash
197
- morula attachment upload <file>
198
- ```
199
- - **显式挂任务对象**(用户从任务/评论发起、任务有 objectId):
200
- ```bash
201
- morula attachment upload <file> --object <objectId>
202
- ```
203
- - **显式挂指定评论**:`morula attachment upload <file> --comment <commentId>`
204
- - **显式挂 Chat 会话消息**:`morula attachment upload <file> --ag-message --task <AgentTaskID>`
205
-
206
- **回传后**:命令输出 JSON,含 `downloadUrl` 与附件 `id`。在最终总结里**引用下载链接**(`http...` 或附件的可下载地址),并说明文件名即可——不要把本地绝对路径/相对文件名当交付物。<br>
207
- **文件类型不限**,单文件上限 20MB;超限需拆分或说明,不要硬传失败。
208
-
209
- ## 1.2 自动化的信息类产出:用 `morula report create`
210
-
211
- 当本任务是**自动化(定时/触发)派发**的,且你的产出是给人看的**信息类结果**(巡检/扫描结论、摘要、分析),用报告承载:
212
-
213
- ```bash
214
- morula report create --title "<一句话标题>" --content "<Markdown 正文>" # 正文长时用 --content-file <path>
215
- ```
216
-
217
- - 报告落在**本次执行所属自动化的「报告」入口**(不在任务看板、不占任务编号),归属由平台自动绑定,不用传;
218
- - 一次执行可产出多份(一份报告一个主题);**要建工单请用任务,不要把待办事项写进报告正文**;
219
- - 报告落库后创建者与订阅者会收到轻通知(只含标题与跳转);
220
- - 不产出也没关系:任务终态时平台会用你的最终输出兜底落一份报告(但兜底不如你主动组织的内容清晰,信息类产出**优先主动产出**)。
221
-
222
- ## 1.3 运行中反馈:检查点与打断(本回合内生效)
223
-
224
- 用户可以在**你正在运行的这一个回合内**发来意见——不必等本轮结束、也不必重开任务。你要在两处配合:
225
-
226
- **① 主动查检查点(`morula task inbox`)——只在这四个时机查,不要更频繁**
227
-
228
- ```bash
229
- morula task inbox # 取走本线程未消费的消息(服务端标记「本回合已消费」)
230
- morula task inbox --peek # 只看不取(确认有没有新意见,不标记消费)
12
+ ```text
13
+ morula-platform → SKILL.md(路由表)+ references/{workspace, git-workflow, task-protocols, delivery, observability}.md
231
14
  ```
232
15
 
233
- 四个时机(闭环枚举,**不要**每一步都查):
234
-
235
- 1. 一批文件改动**完成之后**(准备进入下一批之前);
236
- 2. `git commit` **之前**;
237
- 3. `git push` / 建 PR **之前**;
238
- 4. 收到「运行中被打断」提示时(见 ②)。
239
-
240
- 拿到消息后:
241
-
242
- - **有消息** → 逐条纳入本回合,按用户的意见调整,并在最终总结里**回执式说明**(「已按要求改为 X」);
243
- - **没有消息** → **立即继续手上的事,不要展开讨论、不要复述检查过程、不要在总结里提「检查过没有新意见」**;
244
- - 用户的意见**不得推翻它没涉及的部分**:已完成的、与意见无关的改动保留;意见与原始需求冲突时**以意见为准**并在总结里说明差异;
245
- - 不要反复轮询(一次检查就是一次工具调用,有开销)。
246
-
247
- **② 被打断时(用户按了「立即打断」)你会在同一会话收到新的指令**
248
-
249
- - 上一回合在**安全点**被中断:其中的工具进度已丢弃,**被中断的工具调用没有结果**(时间线标为已中断)——需要时重新执行,不要假定它已成功;
250
- - 新消息就是用户的最新意见:先按它调整方向,再继续完成本任务;工作区文件与 git 状态仍在,不用重做已完成的部分。
251
-
252
- **③ 用户意见与「要不要返工」由你自己判断,平台不代做**
253
-
254
- - 平台**不会**因为用户说了句话就回退阶段、改任务状态或派返工任务——**那是你的判断**:评估后认为必须推倒重做,就按你自己的协议表达(评审阶段用 `morula review submit` 给出结论;分析阶段用 `morula task analysis-verdict`),状态流转由服务端按既有规则驱动;
255
- - 你只跟**当前阶段**对话:消息就是发给当前阶段负责智能体的。**不要**因为收到意见就去操作别的阶段或别的对象的资源;
256
- - **评审阶段你只做评审**(看 diff、核对目标、出结论),**不要改代码、不要建分支/提 PR**。
257
-
258
- > 为什么是这四个时机:检查是**工具调用**,有 token 与延迟开销;「无消息立即继续」是为了不让检查点把主线带偏。
259
-
260
- ## 2. PR 关联:只走平台通道
261
-
262
- - **关联的唯一来源是平台通道**(2026-09-24 定案):`morula repo mr create`(推荐)建 PR 时服务端当场落关联;
263
- 或 `gh pr create` 之后调 `report_pr` 工具上报。**服务端不读 PR 文本**——title/branch/body 里写什么任务编号都不会关联。
264
- - **人工在 GitLab/GitHub 上手工建的 PR,平台不关联**:不进任务关联区、不触发自动评审、不驱动任务状态。
265
- 如果你希望一条 PR 关联到本任务,就必须走上面两条平台通道之一。
266
- - **关单不需要关键字**:关联上的 PR 合并后,服务端按既有流程推进任务状态
267
- (全部 MR 合并 → 已合并;这些提交进入生产分支 → 已发布)。**关联本身就是授权**。
268
- - 推荐(可读性,不是关联手段):title 以「STR-101: 描述」开头、body 写一句 `Closes STR-101`——便于人和平台日志对照。
269
-
270
- ## 3. 什么时候推分支、提 PR(决策树)
271
-
272
- 先判断**这次任务是否改了仓库里的代码**,再决定要不要分支/PR:
273
-
274
- | 任务类型 | 是否建分支/上报分支名 | 是否推分支 + 建 PR |
275
- |---|---|---|
276
- | **改了代码**(改文件、修 bug、加功能、重构) | ✅ 取名 + `morula task branch`(第 0.3 条) | ✅ 推 feature 分支 + 建 PR/MR(命令见下方「执行要点」,按平台选) |
277
- | **改了代码但被环境阻断无法建 PR**(权限/远端异常/无凭据等) | ✅ 已取名 | ⚠️ 最终总结里用文字报告阻塞原因,并带上约定关键词 **`PR_BLOCKED`**(**这不是 CLI 错误码**,只是给平台/人看的标记;daemon 也会回报交付告警) |
278
- | **只回答问题 / 调研分析**(不改仓库文件) | ❌ 不建分支 | ❌ 不推、不建 PR,直接回答用户问题(不要声明「无需 PR」等无关补充) |
279
- | **本地起服务 / 运行命令**(不落代码到仓库) | ❌ 不建分支 | ❌ 不推、不建 PR |
280
- | **改了代码但用户明确只要本地** | ✅ 可建分支 | ❌ 不推 PR,总结说明 |
281
-
282
- 执行要点:
283
-
284
- - **以下命令都在对应仓库目录内执行**(`cd <工作区根>/<仓库目录>`;工作区根不是仓库);
285
- - 修改了代码 → **推送到 feature 分支(禁止推 main/master)并确保有 PR**;
286
- - 分支用你在第 0.3 条取的名(或复用的已有分支)。**创建/更新 PR(MR) 的命令按平台选择**(本文件末尾的「GitLab 平台说明」段会覆盖此处的 GitHub 写法):
287
- - **GitHub 仓库**:先查该分支是否已有 PR:
288
- ```bash
289
- gh pr list --head <branch> --state open # 已有 → 直接 push 更新,不要重复创建
290
- ```
291
- - **已有 PR**(同一改动闭环的后续轮次)→ 只 `git push -u origin <branch>` 更新,**不要**再 `gh pr create`;
292
- - **无 PR** → 创建:
293
- ```bash
294
- git push -u origin <branch>
295
- gh pr create --base <默认分支> --head <branch> --title "<任务编号>: 描述" --body "Closes <任务编号>"
296
- ```
297
- - **GitLab 仓库**:推分支 + 建 MR 用一条平台命令(**不要**用 `gh`、不要手写 `git push -o merge_request.create`):
298
- ```bash
299
- morula repo mr create <repoFullName> --branch <branch> --base <默认分支> --task-code <任务编号>
300
- ```
301
- 该命令等价于「推分支 + 服务端建 MR」,MR 一定建在平台绑定的仓库上,详见末尾「GitLab 平台说明」段。
302
- - **不确定用哪条**:本任务的工作区来自哪个平台由「GitLab 平台说明」段是否存在决定——**存在即 GitLab**,按 GitLab 走。
303
- - 没有改代码(纯调研/问答/起服务)→ **直接回答用户问题**,不要声明「无需 PR」或「未改动任何代码」这类无关补充,也不要为了形式而建 PR;
304
- - PR 创建被阻塞(权限/测试失败/远端状态异常)→ 在最终总结中**报告阻塞原因**,不要假装任务已完成;
305
- - **不要**切回 `main` 或 `master` 直接提交。
306
-
307
- ## 4. 状态与任务操作:结论优先,动作为辅
308
-
309
- - **状态推进由结论协议与事实事件驱动**:分析任务上报 `analysis-verdict`、评审任务用 `morula review submit`、合并/发布由 PR 事件驱动——**不要**用状态动作替代结论协议。
310
- - **你可以在任务上做基础操作**(像人一样,作用域仅限本任务):
311
- - `morula task state <taskId> --state <in_progress|review> [--reason <文本>]`:在「开发中 / 待评审」范围内自推状态;**待评审 → 开发中 = 退回开发**——平台会自动回退状态、记评审轮次并派发修复任务(同一 PR 迭代),**不需要、也不应该**再自己 @ 开发执行器;`--reason` 写明退回原因(会进修复任务 prompt)。
312
- - `morula comment add`:见第 5 条评论纪律。
313
- - `morula task assign <taskId> --to <principalId>`:指派本任务负责人(本空间成员或阶段执行器;目标不存在会显式报错)。
314
- - **终态(已合并/已发布/已关闭)与需求池状态不由你声明**;同态重复推送是幂等的(无害)。
315
-
316
- ## 4.1 分析任务:必须上报分析结论(verdict)
317
-
318
- > **仅当本任务是「待分析」任务时适用**(任务停在「待分析」阶段、要求做需求分析与方案拆解、不写代码)。
319
- > 其余任务(开发 / 评审 / 调研 / 问答)跳过本节,不要调用该命令。
320
-
321
- - 分析结论分两部分,**都要给**(顺序:先发评论,再上报 verdict):
322
- 1. **人看的**:用**你自己的话**把分析结论发成最终总结评论——需求是否清晰、怎么做、范围与风险、验收点:
323
- ```bash
324
- morula comment add --object <objectId> --final --content <你的分析结论>
325
- ```
326
- 这是用户看到的分析交付:用自己的话写,不要套固定格式,更不要复述任务描述;结论先说、理由跟上。
327
- 2. **机器判定的**:执行 `morula task analysis-verdict <taskId> --verdict ready|blocked [--reason "…"]` 上报结论(`--reason` 只需一句话,详细内容在评论里)。
328
- - `<taskId>` = `morula task get`(无参)返回的 `id`(本任务 AgentTask UUID)。
329
- - **`ready`** = 需求清晰、可直接开发(`--reason` 可写一句话范围摘要);
330
- **`blocked`** = 不可做 / 需澄清(**必须**在 `--reason` 或最终输出里写清阻塞点与需要澄清的问题)。
331
- - **服务端据此自动推进,不需要任何人点确认**:`ready` → 任务自动进入「开发中」并派发开发任务;
332
- `blocked` / 未上报 → 任务**停在「待分析」**,由用户补充需求后重派分析。
333
- - **必须上报**:漏报会让任务静默停在「待分析」;同一任务只需上报一次(重复上报以首次为准,不会改写)。
334
- - 分析任务的推进由服务端按 verdict 决定——**不要用状态动作替代分析结论**(不要调 `morula task state`)。
335
-
336
- ## 4.2 评审任务:只读评审 + 必须回传结论(verdict)
337
-
338
- > **仅当本任务是「Code Review 评审任务」时适用**(系统提示出现「本任务是 **Code Review 评审任务**」;要求对开发提交的改动做评审、不写代码)。
339
- > 其余任务(开发 / 分析 / 调研 / 问答)跳过本节,不要调用该命令。
340
-
341
- - 评审是**只读**的:物化仓库后查看 PR 分支相对目标分支的**实际改动**(`git diff`),**禁止修改代码、建分支、推分支、合并 MR**。
342
- - 评审维度:正确性 / 安全性 / 代码风格 / 测试覆盖 / 是否符合原始需求;**必须读取真实 diff 后再下结论**,禁止凭空评审、编造结论。
343
- - **评审所需信息全部用工具获取**(系统提示不注入):
344
- - 评审对象:`morula task get`(无参)返回的 `objectId`(关联业务任务);
345
- - 业务任务目标(标题/描述):`morula task get <objectId>`;关键评论:`morula comment list --object <objectId>`;
346
- - PR 编号/链接:**GitLab** 用 `morula repo mr list <taskId> --state opened`(见末尾「GitLab 平台说明」段);**GitHub** 用 `gh pr list --head <branch>`;两者都可用业务对象详情里的 PR 关联兜底。
347
- - **先答「目标达成度」**:对照业务任务目标逐条给出「达成 / 部分达成 / 未达成」;**未达成目标不得判 approved**;若开发改动与业务目标不匹配(做的是另一件事),verdict 必须为 `changes_requested`,不得以「描述残留、不影响验收」为由判通过。
348
- - **必须回传结论**(机器协议),执行:
349
- ```bash
350
- morula review submit <objectId> --verdict approved|changes_requested|commented [--details <文本>] [--pr-number <PR编号>]
351
- ```
352
- - `<objectId>` = `morula task get`(无参)返回的 `objectId`;
353
- - `--verdict`:`approved`(通过)/ `changes_requested`(不通过,**必须**在 `--details` 写明具体意见:文件/行/问题/建议,否则开发无法修复)/ `commented`(有意见但不阻塞);
354
- - `--pr-number`:评审对象的 PR 编号(有则填)。
355
- - **评审任务的交付就是这份结论**:平台会按结论写权威评论(✅/💬/🔁)——**不要**再发最终总结评论(`--final` 会被服务端拒绝),也不要在评论区复述结论。
356
- - **结论新鲜度(无新提交不重复投 `approved`)**:提交结论前先核对被评审 MR 的 head commit 与上一轮结论时是否相同(`morula repo mr list` / `mr-detail`;评论区也有上一轮结论)。**相同且无新提交时不要重复投 `approved`**:本轮任务上下文里有人的新要求(如要求修复上一轮意见)→ 按人的要求处理(意见未修复就投 `changes_requested`);确实无可评审内容 → 投 `commented` 说明「无新提交」即可。复述上一轮结论对任务没有任何推进。
357
- - **禁止评审自己开发的任务**:若待评审改动由你自己提交(同一智能体既开发又评审),不下结论,直接报告该配置问题。
358
- - **必须上报**:漏报会让任务停在「待评审」,开发无法进入下一轮。
359
- - 退回开发**首选结论协议**:`--verdict changes_requested`(带具体意见)与服务端结论链路完全等价;`morula task state --state in_progress` 是等价的替代入口(见第 4 条),不是绕过。
360
-
361
- ## 4.3 在 MR/PR 上留评审意见(巡检/审查类任务,非评审任务时)
362
-
363
- > **仅当本任务是巡检/审查类(如自动化定时 PR Review),且确实发现值得提出的问题时适用**;开发/分析/问答任务跳过本节。
364
-
365
- - **正确姿势**:用 `morula repo mr comment`(服务端机器协议,只写评论:不 approve、不 merge、不 close),**一条 MR 最多一条评论**:
366
- ```bash
367
- morula repo mr get <taskId> --mr <iid> --notes # 写之前先读已有讨论(平台不做去重,重复由你避免)
368
- morula repo mr comment <taskId> --mr <iid> --content-file <path>
369
- ```
370
- - 内容为**结论 + 关键问题**(文件:行 + 问题 + 建议),不要贴大段日志或复述 diff;长内容写成报告(`morula report create`)后用摘要引用;
371
- - 末尾带署名行 `> 由自动化「<自动化名称>」于 <日期> 生成`——供人与 agent 下一轮识别这是本自动化的历史评论;
372
- - 若本自动化已就同一问题留过评论、结论与这次一致 → **不要重复评论**;
373
- - ⛔ **不要用 `morula review submit`**(那是评审任务的机器协议,会驱动业务任务状态回退)。
374
-
375
- ## 5. 评论交付纪律(最终总结由你自己发布)
376
-
377
- - **最终总结评论由你自己发布**:任务收尾时执行
378
- ```bash
379
- morula comment add --object <objectId> --final --content <结论>
380
- ```
381
- 作者=你(智能体身份);评论触发任务时服务端会**自动把它挂到触发评论下**作为回复(无需自己查评论 ID)。
382
- **先发 final 评论、再上报任务结果**——服务端在你完成时检查:没发过 final 才会兜底代发一条(同一任务只会保留一条最终总结,重复发送会被服务端拒绝,这是预期内的幂等保护)。
383
- - **例外:评审任务不需要(也不应)发 final**——你的结论已经通过 `morula review submit` 机器协议上报,平台会据此写权威结论评论(✅ 通过 / 💬 非阻塞 / 🔁 未通过);再发一条 final 总结会让同一结论在评论区**说两遍**(服务端也会拒绝评审任务的 final)。需要发 final 的是开发 / 修复 / 分析 / 问答 / 评论触发类任务——内容**用你自己的话写**,不要套模板。
384
- - **普通评论**(说明进展、@ 其他人或运行时)随时可发:
385
- ```bash
386
- morula comment add --object <objectId> --content <文本>
387
- morula comment add --object <objectId> --content <文本> --mention-agent <stageExecutorId> # @ 阶段运行时(触发该执行器在本任务上干活)
388
- ```
389
- chat 会话无 objectId 的任务(纯对话派发)不发评论——最终交付由 daemon 回填 assistant 消息。
390
- - **评论纪律:只写结论与事实**——做了什么、结果如何、用户需要知道的后续;**不写**思考过程、探索步骤、工具日志、终端输出、命令回显。用户只关心「做了什么、结果怎样」,不关心「怎么做的」。内容较多时用小标题/列表组织,结论先置顶。
391
- - **PR 汇报仅当「任务涉及代码改动」或「用户明确问到 PR/合并」时给出**;纯问答/调研类任务不要出现 PR/分支章节。
392
- - **任务结果文本同样只写结论**:上报的任务结果会被服务端用于缺失兜底与通知摘要——若结果里混入了中间过程(英文探索叙述、工具尝试记录、思考片段),**必须**在真正的总结之前插入独占一行的 `---FINAL---` 分隔符,服务端兜底时只保留它之后的内容(`---SUMMARY---` 同样兼容;不写时服务端退回「按总结类标题 / 水平线猜测」,猜不中会把过程文本一起兜底出去)。
393
- - **不要把本地绝对路径当交付物**:工作目录路径只属于执行它的机器,读者打不开;生成的文件**必须先回传平台**(见 1.1 `morula attachment upload`),交付物用平台下载链接或仓库内相对路径。
394
- - 不要包含工具调试过程、内部日志、任何凭据或 token 信息。
395
-
396
- ## 6. 禁止事项
397
-
398
- - 禁止直接调用 morula REST API / 非 CLI 方式写评论、改状态、读数据——与平台交互只走 morula CLI(评论用第 5 条的 `morula comment add`,状态用第 4 条的 `morula task state`)。
399
- - 禁止读取 `~/.morula-cli`、凭据文件、环境变量中的密钥。
400
- - 只在任务指定的工作目录与仓库内操作,不要探索工作目录之外的文件系统。
401
- - 禁止把 token、安装 ID、内部 URL 写进评论或 commit。
402
-
403
- ## 7. References
16
+ 契约核心(不变量 + 机器协议命令索引 + 手册路由)随工作区根 `AGENTS.md`「Morula 平台协作契约」段恒定生效。
17
+ 旧 brief / 旧插件副本可能仍指名本 skill——按上面的新入口读取即可,不要重复学习两份契约。
404
18
 
405
- `references/working-on-issues-source-map.md` —— 每条契约对应的服务端/CLI 实现位置
406
- (`file:line`),用于校准契约与实现一致。
19
+ > 本副本随 CLI 插件分发;daemon 注入工作区的权威版本结构相同。
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arcships/morula-runtime",
3
3
  "type": "module",
4
- "version": "0.1.0-alpha.17",
4
+ "version": "0.1.0-alpha.19",
5
5
  "description": "Device-level CLI for the Morula local agent runtime (daemon/portal/models/auth) and the Morula business CLI (morula), distributed via npm",
6
6
  "bin": {
7
7
  "morula-runtime": "./bin/morula-runtime.js",
@@ -5,6 +5,13 @@
5
5
  * 为什么放在 postinstall:用户的目标是「装一个包就能用」。skills 与 agent 执行 PATH 上的
6
6
  * `morula` 只能由 Dim 的插件根提供,所以安装时直接注册一次。
7
7
  *
8
+ * 物化范围(acp-provider-generalization U16 / D-k):**只服务 dim 插件**——
9
+ * 本脚本只写 `<DIMCODE_HOME>/plugins/morula-cli`。平台**不代装 AI CLI**(claude / codex 等
10
+ * 由用户自行安装),也**不为非 dim provider 做任何宿主侧投影**(非 dim provider 的投影只落在
11
+ * 任务工作区,见 providers/**)。因此「非 dim provider 的 CLI 缺失」不是安装问题,而是运行期
12
+ * 的可诊断结论:`morula-runtime daemon doctor --probe` 会给出 `<KEY>_CLI_NOT_FOUND` /
13
+ * `<KEY>_PROBE_FAILED` 与对应的下一步。本脚本**不得**为此新增任何向宿主写 provider 文件的行为。
14
+ *
8
15
  * 硬约束:**绝不阻断安装**。
9
16
  * - 任何失败(资产缺失、权限、非交互环境、`--ignore-scripts` 之外的意外)只 warn + exit 0;
10
17
  * - 失败后可随时手动补:`morula-runtime setup`;
@@ -28,6 +35,7 @@ try {
28
35
  const result = JSON.parse(output)
29
36
  const legacy = result.legacyRoot ? `;检测到旧插件目录 ${result.legacyRoot},建议删除(Dim 优先命中 ${result.pluginRoot})` : ''
30
37
  console.error(`[morula-runtime] 插件已注册:${result.pluginRoot}(skills: ${(result.skills ?? []).join(', ')})${legacy}`)
38
+ console.error('[morula-runtime] 只物化 Dim 插件:平台不代装 AI CLI(claude / codex 等需自行安装),也不为非 dim provider 做宿主侧投影')
31
39
  console.error('[morula-runtime] Dim 会在**新 session** 加载插件;手动重注册:morula-runtime setup')
32
40
  }
33
41
  catch (error) {