ai-project-manage-cli 5.0.15 → 5.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -108,6 +108,12 @@ function sessionDocsDir(sessionId, apmRoot) {
108
108
  function sessionRulePath(sessionId, apmRoot) {
109
109
  return join2(sessionDir(sessionId, apmRoot), "RULE.md");
110
110
  }
111
+ function sessionTaskPath(sessionId, apmRoot) {
112
+ return join2(sessionDir(sessionId, apmRoot), "TASK.md");
113
+ }
114
+ function sessionLogPath(sessionId, apmRoot) {
115
+ return join2(sessionDir(sessionId, apmRoot), "LOG.md");
116
+ }
111
117
  function sessionYamlPath(sessionId, apmRoot) {
112
118
  return join2(sessionDir(sessionId, apmRoot), "session.yaml");
113
119
  }
@@ -243,7 +249,7 @@ var requestConfig = {
243
249
  }),
244
250
  branchBaseline: defineEndpoint({
245
251
  method: "GET",
246
- path: "/cli/requirements/branch-baseline"
252
+ path: "/cli/tasks/branch-baseline"
247
253
  }),
248
254
  listSkills: defineEndpoint({
249
255
  method: "GET",
@@ -620,6 +626,12 @@ async function runPull(sessionId, apmRoot) {
620
626
  detail.description ?? "",
621
627
  "utf8"
622
628
  );
629
+ writeFileSync4(
630
+ sessionTaskPath(trimmedId, apmRoot),
631
+ detail.task.description ?? "",
632
+ "utf8"
633
+ );
634
+ writeFileSync4(sessionLogPath(trimmedId, apmRoot), detail.log ?? "", "utf8");
623
635
  for (const doc of documents) {
624
636
  const fileName = documentLocalFileName(doc.name);
625
637
  writeFileSync4(join5(docsDir, fileName), doc.content ?? "", "utf8");
@@ -627,14 +639,14 @@ async function runPull(sessionId, apmRoot) {
627
639
  const sessionYaml = yamlStringify(
628
640
  {
629
641
  name: detail.title,
630
- description: "./RULE.md",
642
+ task: "./TASK.md",
643
+ log: "./LOG.md",
644
+ rule: "./RULE.md",
631
645
  members: members.map((m) => ({
632
646
  name: m.displayName,
633
647
  expert: m.expert,
634
- system_persona: m.systemPersona,
635
- skills: []
648
+ description: m.description ?? ""
636
649
  })),
637
- skills: [],
638
650
  attachments: attachments.map((a) => ({ name: a.name }))
639
651
  },
640
652
  { lineWidth: 0 }
@@ -751,6 +763,7 @@ import {
751
763
  import { join as join7 } from "path";
752
764
  var AGENTS_TEMPLATE_PATH = join7(CLI_TEMPLATE_DIR, "AGENTS.md");
753
765
  var BASE_SKILLS_TEMPLATE_DIR = join7(CLI_TEMPLATE_DIR, "skills");
766
+ var BASE_RULES_TEMPLATE_DIR = join7(CLI_TEMPLATE_DIR, "rules");
754
767
  function sanitizeSkillDirName(name) {
755
768
  const trimmed = name.trim();
756
769
  if (!trimmed) return "skill";
@@ -769,6 +782,23 @@ function syncAgentsGuide(apmDir) {
769
782
  copyFileSync(AGENTS_TEMPLATE_PATH, join7(apmDir, "AGENTS.md"));
770
783
  return true;
771
784
  }
785
+ function listBaseRuleFileNames() {
786
+ if (!existsSync3(BASE_RULES_TEMPLATE_DIR)) return [];
787
+ return readdirSync2(BASE_RULES_TEMPLATE_DIR).filter((name) => {
788
+ const path8 = join7(BASE_RULES_TEMPLATE_DIR, name);
789
+ return statSync2(path8).isFile();
790
+ });
791
+ }
792
+ function syncBaseRules(rulesDir) {
793
+ mkdirSync3(rulesDir, { recursive: true });
794
+ const names = listBaseRuleFileNames();
795
+ for (const name of names) {
796
+ const src = join7(BASE_RULES_TEMPLATE_DIR, name);
797
+ const dest = join7(rulesDir, name);
798
+ copyFileSync(src, dest);
799
+ }
800
+ return names;
801
+ }
772
802
  function syncBaseSkills(skillsDir) {
773
803
  mkdirSync3(skillsDir, { recursive: true });
774
804
  const names = listBaseSkillDirNames();
@@ -826,6 +856,11 @@ async function runUpdateSkills() {
826
856
  if (syncAgentsGuide(apmDir)) {
827
857
  console.log("[apm] \u5DF2\u540C\u6B65 APM \u6307\u5357: .apm/AGENTS.md");
828
858
  }
859
+ const rulesDir = join8(apmDir, "rules");
860
+ const ruleNames = syncBaseRules(rulesDir);
861
+ for (const name of ruleNames) {
862
+ console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u89C4\u5219: rules/${name}`);
863
+ }
829
864
  const skillsDir = join8(apmDir, "skills");
830
865
  mkdirSync4(skillsDir, { recursive: true });
831
866
  const baseNames = syncBaseSkills(skillsDir);
@@ -848,7 +883,7 @@ async function runUpdateSkills() {
848
883
  console.log(`[apm] \u5DF2\u79FB\u9664\u5DF2\u4E0B\u7EBF\u7684\u8865\u5145\u6280\u80FD: skills/${name}/`);
849
884
  }
850
885
  console.log(
851
- `[apm] \u6280\u80FD\u540C\u6B65\u5B8C\u6210\uFF1A${baseNames.length} \u4E2A\u57FA\u7840\u6280\u80FD\uFF0C${written.length} \u4E2A\u8865\u5145\u6280\u80FD`
886
+ `[apm] \u540C\u6B65\u5B8C\u6210\uFF1A${ruleNames.length} \u4E2A\u57FA\u7840\u89C4\u5219\uFF0C${baseNames.length} \u4E2A\u57FA\u7840\u6280\u80FD\uFF0C${written.length} \u4E2A\u8865\u5145\u6280\u80FD`
852
887
  );
853
888
  }
854
889
 
@@ -2206,16 +2241,16 @@ function buildProgram() {
2206
2241
  await runUpdate();
2207
2242
  });
2208
2243
  program.command("update-skills").description(
2209
- "\u540C\u6B65\u6280\u80FD\u5230 .apm/skills/\uFF1A\u57FA\u7840\u6280\u80FD\u6765\u81EA CLI \u6A21\u677F\uFF0C\u8865\u5145\u6280\u80FD\u6765\u81EA\u5E73\u53F0"
2244
+ "\u540C\u6B65 .apm/ \u4E0B\u7684\u89C4\u5219\u4E0E\u6280\u80FD\uFF1A\u57FA\u7840\u5185\u5BB9\u6765\u81EA CLI \u6A21\u677F\uFF0C\u8865\u5145\u6280\u80FD\u6765\u81EA\u5E73\u53F0"
2210
2245
  ).action(async () => {
2211
2246
  await runUpdateSkills();
2212
2247
  });
2213
2248
  program.command("pull").description(
2214
- "\u62C9\u53D6\u6C9F\u901A\u7FA4\u6570\u636E\u5230 .apm/sessions/<sessionId>/\uFF08session.yaml\u3001RULE.md\u3001docs\u3001attachments\uFF09"
2249
+ "\u62C9\u53D6\u6C9F\u901A\u7FA4\u6570\u636E\u5230 .apm/sessions/<sessionId>/\uFF08session.yaml\u3001RULE.md\u3001TASK.md\u3001LOG.md\u3001docs\u3001attachments\uFF09"
2215
2250
  ).argument("<sessionId>", "\u6C9F\u901A\u7FA4 ID").action(async (sessionId) => {
2216
2251
  await runPull(sessionId);
2217
2252
  });
2218
- program.command("sync-document").description("\u5C06\u672C\u5730 Markdown \u8986\u76D6\u5F0F upsert \u5230\u5E73\u53F0\u9700\u6C42\u6587\u6863").argument("<sessionId>", "\u6C9F\u901A\u7FA4 ID").requiredOption(
2253
+ program.command("sync-document").description("\u5C06\u672C\u5730 Markdown \u8986\u76D6\u5F0F upsert \u5230\u5E73\u53F0\u4EFB\u52A1\u6587\u6863").argument("<sessionId>", "\u6C9F\u901A\u7FA4 ID").requiredOption(
2219
2254
  "--file <name>",
2220
2255
  "\u6587\u6863\u540D\u79F0\uFF08\u5982 PRD \u6216 PRD.md\uFF09\uFF0C\u8BFB\u53D6 .apm/sessions/<sessionId>/docs/ \u4E0B\u5BF9\u5E94\u6587\u4EF6"
2221
2256
  ).action(async (sessionId, opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "5.0.15",
3
+ "version": "5.0.17",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,
@@ -1,29 +1,27 @@
1
1
  ## APM 指南
2
2
 
3
- ### 回复消息命令
4
-
5
- - 命令: `apm append-message --id=<消息ID> --content=<消息内容>`
6
- - 注意事项:
7
- - 如果消息内容中包含文档地址,不要把前缀也写出来,直接用文档名称即可,并且文档名称要用倒引号包裹
8
- - 这个是补充消息内容,只要消息没有结束,都可以用这个命令来继续补充发言。
9
-
10
- ### 创建/更新群文档命令
11
-
12
- - 命令: `apm sync-document <会话ID> --file <文档名称>`
13
- - 注意事项:`apm sync-document` 的 `--file` 为**文档名称**(如 `PRD.md`),对应磁盘路径 `.apm/sessions/<会话ID>/docs/PRD.md`(群文档在 `docs/` 下)。
14
-
15
- ## 工作流程
3
+ ### 工作流程
16
4
 
17
5
  1. 读取 `.apm/sessions/<会话ID>/session.yaml`,必要时读取`messages.xml` 了解当前会话状态与历史消息
18
- 2. 根据你的名字从 session.yaml 中找到你对应的人设(system_persona)
19
- 3. 根据人设完成用户指定的任务
20
- 4. 任务有阶段行进展或者任务完成后必须使用 `apm append-message` 回复消息,回复要求简洁不用对本轮工作进行总结
21
- 5. 工作日志放到 `.apm/sessions/<会话ID>/docs/<expert>.md` 中,并执行`apm sync-document <会话ID> --file=<expert>`同步到远程
22
-
23
- ## 目录声明
24
-
25
- - APM 指南: `.apm/AGENTS.md`
26
- - 技能: `.apm/skills/<技能名称>/SKILL.md`,当 `system_persona` 依赖相关技能时可以在这里按需查找
27
- - 群文档: `.apm/sessions/<会话 ID>/docs/xxxx.md`,当需要相关上下文可以在这里查找
28
- - 协作规则: `.apm/sessions/<会话 ID>/RULE.md`,在这里可以看到不同成员的协作规则
29
- - 历史消息记录: `.apm/sessions/<会话 ID>/message.xml`,当需要查看历史消息记录时可以阅读这个文档
6
+ 2. 根据你的名字从 `session.yaml` 的 `members` 中找到你对应的 **description**(专家描述,非人设提示词)
7
+ 3. 根据角色描述完成用户指定的任务
8
+ 4. 任务有阶段行进展或者任务完成后必须回复消息(具体见规则 `reply.md`)
9
+ 5. 写工作日志(具体见规则 `write_doc.md`)
10
+
11
+ ### 目录指引
12
+
13
+ - 全局文档指引(.apm/\*)
14
+
15
+ - 技能: `.apm/skills/<技能名称>/SKILL.md`,一些常用的工作方法,根据你当前的角色按需阅读
16
+ - 规则: `.apm/rules/*`
17
+ - reply.md:当需要回复消息时需要读取这个文档,记住回复规则
18
+ - write_doc.md:当需要写文档时需要读取这个文档,记住写文档的规则
19
+
20
+ - 本轮任务需要关注的文档指引(.apm/sessions/<会话 ID>/\*):
21
+ - 本轮会话状态: `session.yaml`,从这里可以看到每个成员的信息,找到可以协助你一起解决问题的人,可以结合 `RULE.md`一起看
22
+ - 群文档: `docs/xxxx.md`,当需要相关上下文可以在这里查找,按需阅读
23
+ - 附件列表: `attachments/*`,当有文档中提及附件时,从这里查找
24
+ - 协作规则: `RULE.md`,在这里可以看到不同成员的协作规则,从而找其他成员协助你一起解决问题,按需阅读
25
+ - 团队日志: `LOG.md`,在这里可以看到之前每个成员都做了什么,按需阅读
26
+ - 历史消息记录: `message.xml`,历史消息列表,数据量很大,按需阅读
27
+ - 初始目标: `TASK.md`,最初的目标,不一定具体,团队成员会有人负责让这个任务变得具体,仅供参考。如果你是相关的角色,则你需要先读取这个目标,然后规划接下来的动作。
@@ -0,0 +1,15 @@
1
+ ## 群内回复规则
2
+
3
+ 1. 如果回复的内容包含文档地址,不要把前缀也写出来,直接用文档名称即可。例如: 我已经把待处理的内容更新到了 `PRD.md` 中,请查阅。
4
+ 2. 回复的内容并非对你工作的总结,要尽可能简洁,不要长篇大论,如果同步的内容确实较多,你可以先写文档,然后指引用户去阅读你写的文档。
5
+ 3. 只要你有任何进展都想都可以调用下面的命令进行回复,你可以一直补充内容。
6
+
7
+ ## 执行回复的方法
8
+
9
+ 命令: `apm append-message --id=<消息ID> --content=<你要回复的消息内容>`
10
+
11
+ 示例: apm append-message --id=xxxxx --content="我已经把待处理的内容更新到了 `PRD.md`,请查阅"
12
+
13
+ ## 写文档的方法
14
+
15
+ 如果知道写文档的方法,可以阅读 `./write_doc.md`
@@ -0,0 +1,30 @@
1
+ ## 写工作日志
2
+
3
+ 命名方式: <你的名字>-工作日志.md
4
+ 保存位置: .apm/sessions/<会话 ID>/docs/<文件名>
5
+ 日志格式:见如下 markdown 中间的内容
6
+
7
+ ```markdown
8
+ ## <简要总结本轮干了什么>
9
+
10
+ <内容>
11
+ ```
12
+
13
+ ## 写其他文件
14
+
15
+ 命名方式: <你的名字>-<主题>.md
16
+ 保存位置: .apm/sessions/<会话 ID>/docs/<文件名>
17
+ 文档内容格式: 根据你的主题来,不限制,禁止记流水账。
18
+
19
+ ## 在保存完成之后需要同步到远程
20
+
21
+ 同步命令: `apm sync-document <会话 ID> --file=<文档名称>
22
+
23
+ 示例: `apm sync-document <会话ID> --file=张三.md`
24
+
25
+ ## 注意事项
26
+
27
+ 1. 文档内容可以被其他团队成员看到,要有价值,禁止记流水账
28
+ 2. 你可以根据你的名字查到自己写的文档,并且禁止更改其他人写的文档
29
+ 3. 不要随便创建新文档,可以在已有文档的基础上添加内容
30
+ 4. 文档不可删除,不可更新文档名称,在写入时要谨慎
@@ -1,178 +1,116 @@
1
- # APM 工作项:按任务实现
1
+ ## 文档说明
2
2
 
3
- 根据工作项目录下的 **`tasks.md`** 驱动实现:**读规划 → 做代码 → 对账元数据 → 勾选 → 单独 commit**,直至全部完成或遇硬阻塞;上下文以 **`.apm/sessions/<sessionId>/`** 内文件为准。
3
+ 按工作项中的 **`plans/tasks.md`** 驱动实现:**读规划 → 写代码 → 对账元数据 → 勾选 → 单独 commit**,直至全部完成、**停止执行**或硬阻塞。
4
4
 
5
- ---
6
-
7
- ## 输入
8
-
9
- 若本轮未提供 `sessionId`:
10
-
11
- 1. 若对话中已能**唯一**确定工作项目录名,则用之。
12
- 2. 否则直接停止工作即可,**不要**调用 AskUserQuestion,**不要**停下来让用户当场选择。
13
-
14
- ## 停止执行(优先于继续推进)
15
-
16
- 若在实施过程中**发现**任一情况,**立即停止**本技能所驱动的后续实现与勾选(不再继续下一项任务),仅在会话中输出:
17
-
18
- 1. **客观事实**:已读到的文件/路径、与代码或任务条目的**具体矛盾点**(可摘引,避免主观评价)。
19
- 2. **当前进度**:处理到 `tasks.md` 的哪一条、仓库是否已有未提交改动(若有,说明范围)。
20
- 3. **需要用户提供什么**:为继续推进所**缺的信息或决策**(例如:以何者为准、是否接受某类改动、需确认的业务口径)。用**清单**列出,**一句一项**。
21
-
22
- **禁止**:给出「建议你先改 A / 再改 B」「可选方案 1/2/3」「宜采用…」等**替用户决策**或**行动建议**;不指导用户如何改文档、不预设优先级。
5
+ **工作项根目录**:`.apm/sessions/<sessionId>/`(下文路径均相对该目录)
23
6
 
24
- **允许**:描述「若不补充某信息则无法继续」的**逻辑关系**(仍不展开成方案)。
7
+ | 文件 | 路径 | 用途 |
8
+ | ----------------- | ------------------- | ----------------------------------------------------------------------------------------- |
9
+ | tasks(**驱动**) | `plans/tasks.md` | 唯一进度来源(`- [ ]` / `- [x]`);缺文件、无待办 → 阻塞,须先 **apm-propose** 或手工补齐 |
10
+ | PRD | `docs/PRD.md` | 范围与验收 |
11
+ | proposal | `plans/proposal.md` | 变更背景(按需) |
12
+ | design | `plans/design.md` | **改哪里**、技术决策(按任务引用) |
13
+ | specs | `plans/specs/*.md` | **做什么**(按任务 **需求编号** 引用) |
25
14
 
26
- ---
27
-
28
- ## 工作项路径与必备文件
29
-
30
- - **根路径**:**`.apm/sessions/<sessionId>/`**
31
- - **必备**:**`tasks.md`**(含 `- [ ]` / `- [x]` 待办)。若不存在或无可执行条目:**阻塞**,说明须先完成 **apm-propose**(或手工补齐 `tasks.md`)。
32
- - **强烈建议读**:**`docs/PRD.md`**(`.apm/sessions/<sessionId>/docs/PRD.md`,范围与验收);实现时按需 **Read** **`proposal.md`**、**`design.md`**、**`specs/`**(与 **`tasks-instruction.md`** 中每条任务的元数据一致)。
33
- - **进度**:仅由 **`tasks.md`** 中复选框统计「已完成 / 总数」。
15
+ **前置**:`plans/tasks.md` 须由 **apm-propose** 生成,格式见 `.apm/skills/apm-propose/tasks.md`(`- [ ]`、元数据子列表等)。
34
16
 
35
- ### 单会话读取(可选减负)
17
+ **sessionId**:若本轮未提供——对话中能**唯一**确定 `.apm/sessions/` 下目录名则用之,否则**停止**(不 AskUserQuestion)。确定后于**首次回复**写明 **使用工作项:`<sessionId>`** 即可,不必单独成步。
36
18
 
37
- 同一轮连续执行多项任务时:**`docs/PRD.md` / `design.md` / spec** 若已在会话内读过且无疑虑,不必每个任务重复全文 Read;以**当前任务行**及元数据指向的 spec/设计段落为准,必要时对文件 **Read(偏移)** 或再读全文。
19
+ **单任务循环**:说明当前项 → 最小实现 → 对账(需求编号 / 预期与实际路径 / 完成标准)→ `- [x]` **一项待办 = 一个 commit**。
38
20
 
39
21
  ---
40
22
 
41
- ## Steps
23
+ ## 停止执行(优先于继续推进)
42
24
 
43
- ### 1. 锚定工作项
25
+ 发现规划与代码**严重不一致**、需用户做产品/架构**决策**、或环境/权限等**硬阻塞**时:**不再**处理下一项、**不**勾选完成,仅输出:
44
26
 
45
- 确定 **`sessionId`** 与工作项根路径;声明 **使用工作项:`<sessionId>`**(若依上节规则自动选定,须说明如何覆盖)。
27
+ 1. **客观事实**:已读路径、与任务/代码的**具体矛盾**(可摘引)。
28
+ 2. **当前进度**:`plans/tasks.md` 处理到哪一条;未提交改动范围(若有)。
29
+ 3. **需要用户提供什么**:清单,一句一项。
46
30
 
47
- ### 2. 读取 `tasks.md` 并判断状态
31
+ **禁止**:替用户决策、给「建议先改 A/B」、可选方案、排障命令(除非任务/文档已写明须执行的命令)。
48
32
 
49
- - **Read** **`.apm/sessions/<sessionId>/tasks.md`**。
50
- - 若文件缺失、为空、或无任何 `- [ ]`:**停止**,提示先具备可执行 `tasks`(规划阶段)。
51
- - 若全部已为 `- [x]`:**可**直接汇报「已全部完成」(仅作事实陈述,不建议是否提交或发 MR)。
33
+ **允许**:说明「缺某信息则无法继续」的逻辑关系(不展开成方案)。
52
34
 
53
- ### 3. 读取实现上下文(按任务需要)
35
+ **仍可继续**:任务略含糊,但在 PRD / design / specs / tasks 已有文字内可**自洽**完成;若有**假设**须写清。一旦假设触及「以谁为准」→ 转 **停止执行**。
54
36
 
55
- 开始**第一个**未勾选任务前,至少 **Read**:
37
+ ---
56
38
 
57
- - **`docs/PRD.md`**(`.apm/sessions/<sessionId>/docs/PRD.md`;若存在,与验收相关条款)
58
- - 与任务相关的 **`design.md`** 片段、**`specs/`** 下对应文件(见任务条目的 **需求编号** / 描述)
39
+ ## 工作流程
59
40
 
60
- 不要求每次任务都重读全部规划文件;以 **`tasks.md` 当前项** + **缺口再 Read** 为准。
41
+ ### 步骤 1:读取 `plans/tasks.md` 并判断状态
61
42
 
62
- ### 4. 展示当前进度
43
+ 1. **Read** `plans/tasks.md`。
44
+ 2. 缺失、为空或无 `- [ ]` → **停止**,提示先具备可执行 tasks。
45
+ 3. 若全部为 `- [x]` → 仅陈述「已全部完成」(不建议是否提交/MR)。
63
46
 
64
- 在对话中简要展示:
47
+ ### 步骤 2:读取实现上下文
65
48
 
66
- - **工作项**:`sessionId`
67
- - **进度**:「N/M 个任务已完成」(由 `tasks.md` 勾选统计)
68
- - **当前将处理**:下一条 `- [ ]` 的摘要(含组号/编号如 `2.1`)
49
+ 开始**第一个**未勾选任务前,至少 **Read** `docs/PRD.md` 及当前项所需的 `plans/design.md` / `plans/specs/` 片段(见任务 **需求编号**)。不要求每项任务重读全部规划;以**当前任务行** + 缺口再 Read 为准。
69
50
 
70
- ### 5. 实现任务(循环直至完成或阻塞)
51
+ #### 单会话读取策略
71
52
 
72
- 对每一条 **未勾选** 任务(建议按 `tasks.md` 自上而下顺序):
53
+ | 文件 | 建议 |
54
+ | ---------------------------------- | -------------------------------------------------------------------------------- |
55
+ | `docs/PRD.md` | 本会话首次实现前至少读一次 |
56
+ | `plans/design.md` / `plans/specs/` | 连续多项时,已读过且无疑虑可不重复全文;按任务元数据 **Read(偏移)** 或再读全文 |
73
57
 
74
- 1. **说明**正在处理哪一项(编号 + 简述)。
75
- 2. **实现**所需代码/配置/迁移等;改动保持**最小**、与该项描述一致。
76
- 3. **标记完成前**在回复或备注中收集依据(与 **`tasks-instruction.md`** 子列表字段对齐即可):
77
- - **需求编号**:本实现对应 specs / tasks 中的哪条需求或场景。
78
- - **预期改动路径** 与 **实际改动文件**:若有合理偏差,简要说明原因。
79
- - **验证用例编号**(若任务中有)。
80
- - **验证结果** / **完成标准**:如何确认本项已达成(可简短)。
81
- 4. 仅在依据已齐、且自洽通过后,将 **`tasks.md`** 中对应行 **`- [ ]` 改为 `- [x]`**。
82
- 5. **Git**:本待办对应的**实现 + 勾选**等改动,**单独 `git commit` 一次**(**一项待办 = 一个 commit**;勿把多项待办混在同一 commit)。提交信息建议包含 `requirementId` 与任务编号或简述。
58
+ ### 步骤 3:展示进度并开始循环
83
59
 
84
- **何时停止(不继续下一项)**——与上文 **「停止执行」** 一致:
60
+ 展示 **工作项**、**N/M 已完成**(由勾选统计)、**当前将处理**的下一条 `- [ ]`(含编号如 `2.1`)。
85
61
 
86
- - **`design` / `specs` / `tasks` 与当前代码或彼此严重不一致**,以致无法按任务字面含义在**不臆造**的前提下完成 → **按「停止执行」输出**(事实 + 需用户提供的材料),**不**建议先改哪份文档、不改哪些。
87
- - 命令失败、环境错误、权限等**硬阻塞** → 说明原因、失败点、已执行步骤;**不**给排障步骤或替代命令建议(除非任务本身要求执行某命令且该命令已写在任务/文档中)。
88
- - 用户中断。
62
+ 对每条未勾选任务(建议自上而下):
89
63
 
90
- **何时仍可继续**(仅当满足):任务表述略含糊,但可在 **docs/PRD.md / design / specs / tasks** 已有文字内**自洽**完成;若有**假设**,在回复中写清**假设**(仍不反问)。一旦假设会触及「以谁为准」的**产品/架构决策**,转 **「停止执行」**。
64
+ 1. 说明正在处理的编号与简述。
65
+ 2. **最小**改动实现;与该项描述一致。
66
+ 3. **勾选前**对账(与 `plans/tasks.md` 子列表字段一致):
67
+ - **需求编号**、**预期改动路径** vs **实际改动文件**(偏差须简述)
68
+ - **验证用例编号**(若有)、**完成标准** / 验证结果
69
+ 4. 依据齐且自洽后,将对应行改为 `- [x]`,**立即**单独 `git commit`(信息含任务编号或简述)。
91
70
 
92
- ### 6. 完成或暂停时展示状态
71
+ ### 步骤 4:收尾
93
72
 
94
- - **本会话**完成了哪些任务(可列勾选项摘要)。
95
- - **总体进度**:「N/M 个任务已完成」。
96
- - 若**全部完成**:仅陈述事实(进度与勾选状态),**不**建议后续流程(MR/发布/归档等)。
97
- - 若**暂停**:按 **「停止执行」** 或硬阻塞格式输出,**无**「可选后续」或方案建议。
73
+ - **全部完成**:进度 N/M、本会话已完成项摘要;**不**建议 MR/发布等后续流程。
74
+ - **暂停**:按 **停止执行** 三节输出;无「可选后续」。
98
75
 
99
76
  ---
100
77
 
101
- ## 实现过程中的输出(示例)
78
+ ## 会话输出(示例)
79
+
80
+ **进行中**
102
81
 
103
82
  ```
104
83
  ## 正在实施:<sessionId>
105
84
 
106
85
  处理任务 3/7:2.1 实现导出接口
107
- [...实现过程...]
108
86
  ✓ 任务完成 · commit <short-sha> <subject>
109
-
110
- 处理任务 4/7:2.2 …
111
87
  ```
112
88
 
113
- ---
114
-
115
- ## 全部完成时的输出(示例)
89
+ **全部完成**
116
90
 
117
91
  ```
118
92
  ## 实现完成
119
-
120
- **工作项:** <sessionId>
121
- **进度:** 7/7 个任务已完成 ✓
122
-
123
- ### 本会话已完成
124
- - [x] …
125
- - [x] …
126
-
93
+ **工作项:** <sessionId> · **进度:** 7/7 ✓
127
94
  (每项待办均已对应独立 commit。)
128
95
  ```
129
96
 
130
- ---
131
-
132
- ## 暂停时的输出(示例)
97
+ **暂停**
133
98
 
134
99
  ```
135
100
  ## 实现已暂停
136
-
137
- **工作项:** <sessionId>
138
- **进度:** 4/7 个任务已完成
139
-
101
+ **进度:** 4/7
140
102
  ### 事实与原因
141
- <客观描述:文件/行/与任务或代码的矛盾点>
142
-
103
+
143
104
  ### 需要用户提供(或决策)
144
105
  - …
145
- - …
146
106
  ```
147
107
 
148
- (无方案列表、无「建议」;用户补充信息后可再次运行本技能。)
149
-
150
- ---
151
-
152
- ## 约束
153
-
154
- - 持续执行待办直至完成、**停止执行**或硬阻塞。
155
- - 开始前须已能对照 **`tasks.md`** 与 **`docs/PRD.md`**(及任务所需的 design/spec);**不要**在未读清当前任务依赖时盲改。
156
- - 任务表述有歧义时,仅在**无需用户决策**的前提下依据 **specs / design / docs/PRD.md** 推断;一旦涉及**以谁为准**或**严重不一致**,**停止执行**(见上文)。
157
- - **不**因「发现规划与代码不符」而**主动建议**修改 `design.md` / `specs/` / `tasks.md`;**停止**并说明事实与需用户提供的材料即可。
158
- - 代码改动保持最小、与**当前任务**范围一致。
159
- - 未完成需求/验证对账前,**不要**将任务勾为完成。
160
- - 验证失败或依据不足时,保持 **`- [ ]`**,并明确写出缺口。
161
- - 若任务元数据缺失(需求编号、预期改动路径、完成标准等),在可能范围内于实现前**补全或按 tasks 模板推断**,并在说明中注明。
162
- - 每完成一项任务并记录依据后,**立即**更新勾选并**随即**单独 `git commit`。
163
- - 遇硬阻塞时暂停并说明原因(**不**给出替代命令或排查建议,除非任务/文档已写明);
164
- - 需求不清且无法自洽推断时,**停止执行**并列出需用户提供的材料;**不反问用户**。
165
-
166
- ---
167
-
168
- ## 与规划流程的衔接
169
-
170
- - **`tasks.md`** 须由 **apm-propose**(或等价流程)生成并符合 **`tasks-instruction.md`** 格式(`- [ ]`、元数据子列表等),否则本技能无法可靠追踪。
171
- - 若执行中发现 **`design` / `specs` 与代码严重不一致**:**停止执行**,按上文输出事实与**需用户提供**的决策/信息;**不**建议先改哪类工件、不代用户排优先级。
172
-
173
108
  ---
174
109
 
175
- ## 流动工作流
110
+ ## Guardrails
176
111
 
177
- - **可分段调用**:可在部分任务完成后结束会话,下次同一工作项继续。
178
- - **规划修订**:由用户在**流程外**修订 `design.md` / `specs/` / `tasks.md` 后,再触发本技能;本技能执行中**不因发现不符**而主动改规划文件或提出修改方案。
112
+ - 持续执行待办,直至完成、**停止执行**或硬阻塞。
113
+ - 未读清当前任务依赖前**不要**盲改;未对账前**不要**勾选完成。
114
+ - 验证失败或依据不足时保持 `- [ ]` 并写明缺口;元数据缺失时在实现前尽量补全或按 tasks 模板推断并注明。
115
+ - **不要**因发现规划与代码不符而主动改 `plans/` 下规划文件或建议改哪份;**停止**并交还用户。
116
+ - **可分段调用**:部分完成后结束会话,下次同一工作项继续;规划修订由用户在流程外完成后再运行本技能。
@@ -1,21 +1,10 @@
1
1
  ## 工作流程
2
2
 
3
3
  ### 步骤1: 阅读部署文档
4
+ 使用**Read**工具阅读 `.apm/deploy/README.md`
4
5
 
5
- 使用**Read**工具阅读 `.apm/deploy/README.md`(这个目录可能被忽略了,也可能不存在)
6
+ ### 步骤2: 按照文档执行部署命令,禁止猜测参数
6
7
 
7
- ### 步骤2: 判断能否部署
8
-
9
- 遇到以下情况拒绝部署,直接退出即可
8
+ 如果遇到以下情况则无需部署,直接退出部署流程
10
9
  1. 没有找到部署文档,或者部署文档没有可执行的部署命令(或者说部署不可执行)
11
- 2. 用户没有明确部署环境
12
-
13
- ### 步骤3: 按照文档执行部署
14
-
15
- **严格对照** README:顺序、工作目录(若文档指定 `cd`)、环境变量、所用 CLI(如 `rush`、`docker`、`kubectl` 等)均以文档为准;将步骤 3 得到的 **`env` 等**按 README 约定注入命令或环境(禁止凭猜测填值)。**默认在 `<repoRoot>` 执行**;
16
-
17
- ## Guardrails
18
-
19
- - **gitignore 不等于不存在**:`.apm` 下文件可能不入 Git 索引;**禁止**用「搜索无结果」代替 **Read** 或磁盘校验。
20
- - **不臆造**:README 未写的命令、环境、目标集群/命名空间,**不补充**;工作项 YAML **未提供**的字段**不得**编造。
21
- - **不报假成功**:命令失败或未完成 README 目标时,结论必须为「否」或等价表述。
10
+ 2. 用户没有明确部署环境
@@ -1,11 +1,27 @@
1
1
  ## 工作流程
2
2
 
3
- 1. 选择开发模式:**Quick/Spec**
3
+ ### 步骤 1: 获取当前版本 PRD 的内容以及协作内容
4
4
 
5
- **Quick 开发**(满足越多越适用): - 影响范围局部:少量文件或单一层次(例如仅前端组件、或仅一个后端模块小改)。 - 无新表结构/大规模迁移/权限模型变更。 - PRD 验收点清晰且数量少(经验上 **≤3** 条独立验收维度)。 - 不需要跨多服务的架构裁定即可开工。
6
- **Spec 开发**:(命中任一条即可): - 前后端联动、多包改造或新公共抽象。 - 新数据模型、迁移、或安全/审计/权限相关。 - PRD 范围大、条款多,或存在明显「待确认/多方案」需先规划。 - 评估认为不先产出 **proposal / design / specs / tasks** 不宜直接编码。
5
+ 1. **Read** 工具阅读 `.apm/sessions/<会话ID>/docs/PRD.md`,如果不存在则开发失败,退出流程。
6
+ 2. 按需阅读 `.apm/sessions/<会话ID>/docs`下的其他文档,比如前后端联调的文档
7
7
 
8
- 2. 如果为 **Quick 开发**(子 Agent 中)执行:
8
+ ### 步骤 2: 明确开发模式
9
+
10
+ **Quick 开发**(满足越多越适用):
11
+
12
+ - 影响范围局部:少量文件或单一层次(例如仅前端组件、或仅一个后端模块小改)。
13
+ - 无新表结构/大规模迁移/权限模型变更。
14
+ - PRD 验收点清晰且数量少(经验上 **≤3** 条独立验收维度)。
15
+ - 不需要跨多服务的架构裁定即可开工。
16
+
17
+ **Spec 开发**:(命中任一条即可):
18
+
19
+ - 前后端联动、多包改造或新公共抽象。
20
+ - 新数据模型、迁移、或安全/审计/权限相关。
21
+ - PRD 范围大、条款多,或存在明显「待确认/多方案」需先规划。
22
+ - 评估认为不先产出 **proposal / design / specs / tasks** 不宜直接编码。
23
+
24
+ ### 步骤 3: 如果前一步判定为 **Quick 开发** 才(在子 Agent 中)执行本步骤,否则执行下一步:
9
25
 
10
26
  - 父 Agent 已通过 **Read** 掌握 `PRD.md`;若启动新子 Agent,在委派提示中写明会话 ID、消息 ID、工作项路径、以及「实现须严格对照 PRD,改动范围最小化;完成后若有代码改动须单独 `git commit`」。
11
27
  - 使用 **Task** 工具,`subagent_type: generalPurpose`,**readonly: false**,委派子 Agent:
@@ -14,14 +30,14 @@
14
30
  - **Git**:实现与自洽验收通过后,若有代码改动,**立即 `git add` + `git commit` 一次**(Quick 通常为单次交付,**一次实现 = 一个 commit**;勿拆成无意义碎 commit)。提交信息建议包含 `seesionId`(可从 `session.yaml` 或 PRD 获取)与 PRD 摘要或验收点简述。
15
31
  - 完成后在返回中说明:改了哪些路径、如何对照验收、是否通过本地可执行的检查(若子 Agent 跑了 `rushx build` / 测试等则写明结果);若有 commit,写明 **short-sha** 与 **subject**,无代码改动则注明跳过 commit。
16
32
 
17
- 3. 如果为 **Spec 开发** (子 Agent 中)执行:
33
+ ### 步骤 4: 如果前一步判定为 **Spec 开发** 才(在子 Agent 中)执行本步骤,否则执行下一步:
18
34
 
19
- - 父 Agent **Read** **apm-propose**、**apm-apply-change** 的 `SKILL.md`(**仅** `.apm/skills/` 下路径,见上节)。
20
- - **子 Agent A(规划)**:Task `generalPurpose`,提示其自行 **Read** `.apm/skills/apm-propose/SKILL.md` 并完整遵循:在 `.apm/sessions/<sessionId>/` 生成 **proposal、design、specs、tasks** 等工件(顺序与依赖以 SKILL 为准)。
21
- - **子 Agent B(实现)**:待 A 成功落盘后,再 Task `generalPurpose`,提示其自行 **Read** `.apm/skills/apm-apply-change/SKILL.md` 并完整遵循:按 **`tasks.md`** 驱动实现与勾选;遵守该技能中的停止条件与 commit 约定。
22
- - 若 **apm-propose** 未产出可用 **`tasks.md`**,不得强行进入 **apm-apply-change**;表格中标记阻塞原因。
35
+ 1. 父 Agent **Read** `.apm/skills/apm-propose/SKILL.md` 和 `.apm/skills/apm-apply-change/SKILL.md`
36
+ 2. **子 Agent A(规划)**:Task `generalPurpose`,提示其自行 **Read** `.apm/skills/apm-propose/SKILL.md` 并完整遵循:在 `plans/` 下生成 **proposal、design、specs、tasks** 等工件。
37
+ 3. **子 Agent B(实现)**:待 A 成功落盘后,再 Task `generalPurpose`,提示其自行 **Read** `.apm/skills/apm-apply-change/SKILL.md` 并完整遵循:按 **`plans/tasks.md`** 驱动实现与勾选;遵守该技能中的停止条件与 commit 约定。
38
+ 4. 若 **apm-propose** 未产出可用 **`plans/tasks.md`**,不得强行进入 **apm-apply-change**;表格中标记阻塞原因。
23
39
 
24
- 4. 提交并 push 代码
40
+ ### 步骤 5: 提交并 push 代码,保证工作区干净
25
41
 
26
42
  - Quick / Spec 子 Agent 完成且本地已有 commit 时,父 Agent **立即 `git push`**(当前分支首次 push 用 `git push -u origin HEAD`)。
27
43
  - 无本地 commit、无远程或未配置 upstream 时说明原因,勿强行 push。
@@ -1,191 +1,52 @@
1
- # APM 工作项:规划工件
1
+ ## 文档说明
2
2
 
3
- `.apm/sessions/<sessionId>/docs/PRD.md` 上生成 **proposal design / specs → tasks** 四类规划工件。各工件写什么、依赖谁,见下方对应章节;**不要**把 SKILL 说明或内部推理写进产出文件。
3
+ **PRD** 为事实来源,在 `plans/` 下产出四份规划工件(`docs/PRD.md` 除外),供 **apm-apply-change** `plans/tasks.md` 勾选推进实现。
4
4
 
5
- ---
6
-
7
- ## 输入
8
-
9
- | 字段 | 规则 |
10
- | --------------- | ------------------------------------------------------ |
11
- | **`sessionId`** | **必填**。与 `.apm/sessions/<sessionId>/` 目录名一致。 |
12
- | **需求正文** | **唯一权威**:`.apm/sessions/<sessionId>/docs/PRD.md`。 |
13
-
14
- 用户补充仅在与 PRD 兼容时写入,并标注 **「会话补充(PRD 未载明)」**。PRD 未写明的**不反问用户**,写入后续工件的假设 / 待确认。
15
-
16
- ---
17
-
18
- ## 流程
19
-
20
- **顺序**:`proposal` → `design` 与 `specs`(可并行,均依赖 proposal;specs 不依赖 design)→ `tasks`(依赖 design 与 specs 均已落盘)。
21
-
22
- 用 **TodoWrite** 跟踪四工件(`ready` / `blocked` / `done`),**每完成一工件即落盘并标 `done`**;依赖未满足时**不得**写下一工件。
23
-
24
- 1. **Read `docs/PRD.md` 全文**(路径:`.apm/sessions/<sessionId>/docs/PRD.md`);必要时 **SemanticSearch** / **Read** 仓库代码,便于 tasks 中 **预期改动路径** 可落地。
25
- 2. 按解锁顺序撰写各工件(见下方章节)。
26
- 3. 全部完成后汇总:工作项路径、已创建文件、PRD 与各工件的对应关系(一两句);回复含各工件一句话用途。
27
-
28
- ### 单会话读取策略
29
-
30
- 同一会话连续跑完时,可省略重复 Read,但**不得**省略依赖关系;断点续写或新会话须按各工件「依赖」重新 Read 磁盘文件。
31
-
32
- | 文件 | 建议 |
33
- | ---------------------- | ----------------------------------------------------------------- |
34
- | `docs/PRD.md` | 进入流程时至少读一次全文;后续按需再读。 |
35
- | `proposal.md` | 落盘后写 design/specs 时,若会话内已有刚写入的全文可不重复 Read。 |
36
- | `design.md` / `specs/` | 写 tasks 时若无可靠记忆须 Read;以落盘文件为准。 |
37
-
38
- ---
39
-
40
- ## proposal 工件
41
-
42
- **路径**:`.apm/sessions/<sessionId>/proposal.md`
5
+ **工作项根目录**:`.apm/sessions/<sessionId>/`(下文路径均相对该目录)
43
6
 
44
- **依赖**:`docs/PRD.md`(全文)
7
+ | 工件 | 落盘路径 | 作用 | 依赖 | 撰写规范 |
8
+ | ----------- | ----------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------------ |
9
+ | PRD(输入) | `docs/PRD.md` | 需求与验收的事实来源 | — | — |
10
+ | proposal | `plans/proposal.md` | **Why / What**;**Capabilities** 与 `plans/specs/` 的契约;不写实现细节 | PRD | **Read** `./proposal.md` |
11
+ | design | `plans/design.md` | **How**:架构与决策;不写逐行代码,不替代 `plans/tasks.md` | PRD、proposal | **Read** `./design.md` |
12
+ | specs | `plans/specs/<name>.md` | 系统**应做什么**;与 **Capabilities** 逐条对齐,不得虚构 PRD/proposal 未出现的能力 | PRD、proposal(**不**依赖 design) | **Read** `./specs.md` |
13
+ | tasks | `plans/tasks.md` | 将 specs + design 拆为 `- [ ]` 可勾选任务 | PRD、proposal、design、specs(至少 1 个 `.md`) | **Read** `./tasks.md` |
45
14
 
46
- PRD 为事实来源写变更提案(**Why**,不写实现细节)。精短即可。
47
-
48
- **Capabilities** 是 proposal 与 specs 的契约:每一项须在后续 `specs/` 可追溯。
49
-
50
- - **New Capabilities**:每条对应 `specs/<kebab-name>.md`(如 `user-auth`)。
51
- - **Modified Capabilities**:规格层行为变更;无则写「无」。
52
-
53
- ```markdown
54
- ## Why
55
-
56
- <!-- 1~2 句:解决什么、为何是现在 -->
57
-
58
- ## What Changes
59
-
60
- <!-- 变更要点;破坏性变更标注 BREAKING -->
61
-
62
- ## Capabilities
63
-
64
- ### New Capabilities
65
-
66
- - `<name>`: <brief description>
67
-
68
- ### Modified Capabilities
69
-
70
- - `<existing-name>`: <what requirement behavior changes> <!-- 无则写 无 -->
71
-
72
- ## Impact
73
-
74
- <!-- 受影响代码、API、依赖、系统 -->
75
- ```
15
+ **撰写顺序**:`proposal` `design` 与 `specs`(可并行)→ `tasks`(须等 design 与 specs 均已落盘)。
76
16
 
77
17
  ---
78
18
 
79
- ## design 工件
80
-
81
- **路径**:`.apm/sessions/<sessionId>/design.md`
82
-
83
- **依赖**:`docs/PRD.md`、`proposal.md`
84
-
85
- 说明 **如何实现**(HOW):架构与决策,不写逐行代码,不替代 tasks 里的步骤枚举。
86
-
87
- 跨模块、新依赖、安全/性能/迁移复杂或方案待拍板时写完整版;否则可精简,但保留 **Context** 与 **Decisions**。
19
+ ## 工作流程
88
20
 
89
- ```markdown
90
- ## Context
91
-
92
- ## Goals / Non-Goals
93
-
94
- **Goals:**
95
- **Non-Goals:**
96
-
97
- ## Decisions
98
-
99
- <!-- 每项:备选 + 取舍理由 -->
100
-
101
- ## Risks / Trade-offs
102
-
103
- <!-- [风险] → 缓解 -->
104
-
105
- ## Migration Plan
106
-
107
- <!-- 无则写 无 / 不适用 -->
108
-
109
- ## Open Questions
110
-
111
- <!-- 无则写 无 -->
112
- ```
113
-
114
- ---
115
-
116
- ## specs 工件
117
-
118
- **路径**:`.apm/sessions/<sessionId>/specs/`
119
-
120
- **依赖**:`docs/PRD.md`、`proposal.md`(不依赖 design)
121
-
122
- 定义系统 **应做什么**;与 proposal **Capabilities** 逐条对齐,**不得**虚构 PRD/proposal 未出现的能力。
123
-
124
- **文件组织**:一能力一文件 `specs/<短横线名称>.md`(或 `specs/<名称>/规格.md`,同一工作项内择一,勿混用)。
125
-
126
- **结构**:
127
-
128
- - 分块(`##`):**新增需求** / **变更需求** / **移除需求** / **重命名需求**(按需组合;纯新增只用「新增需求」)。
129
- - 需求:`**### 需求:<名称>**`;行为用 **须、必须**。
130
- - 场景:`**#### 场景:<名称>**`(固定四个 `#`);正文 `- **当** …` / `- **则** …`。
131
- - **每条需求至少一个场景**;变更需求须写**完整替换段落**(从需求到全部场景),禁止只贴片段。
132
-
133
- ```markdown
134
- ## 新增需求
135
-
136
- ### 需求:<名称>
137
-
138
- 系统须 …
139
-
140
- #### 场景:<名称>
141
-
142
- - **当** …
143
- - **则** …
144
-
145
- ## 变更需求
146
-
147
- <!-- 完整替换后的需求 + 全部场景 -->
148
-
149
- ## 移除需求
150
-
151
- ### 需求:<名称>
152
-
153
- **原因**:… **迁移说明**:…
154
-
155
- ## 重命名需求
156
-
157
- - **原名称:** … **新名称:** …
158
- ```
159
-
160
- ---
21
+ ### 步骤 1:读取 PRD 与协作上下文
161
22
 
162
- ## tasks 工件
23
+ 1. **Read** `docs/PRD.md`;不存在则失败并退出。
24
+ 2. 按需 **Read** `docs/` 下其他文档(如联调说明)。
163
25
 
164
- **路径**:`.apm/sessions/<sessionId>/tasks.md`
26
+ ### 步骤 2:按顺序落盘四工件
165
27
 
166
- **依赖**:`docs/PRD.md`、`proposal.md`、`design.md`、`specs/`
28
+ 遵循上表**撰写顺序**与**依赖**;每完成一工件即写入对应**落盘路径**。
167
29
 
168
- 拆成可勾选待办;**apm-apply-change** 依赖 `- [ ]` / `- [x]` 推进。
30
+ ### 步骤 3:跟踪与收尾
169
31
 
170
- **格式**:
32
+ 1. 用 **TodoWrite** 跟踪四工件(`ready` / `blocked` / `done`);依赖未满足时**不得**写下一工件。
33
+ 2. 撰写前 **Read** 依赖项及该工件**撰写规范**列中的 `./*.md`;写 `tasks` 前必要时 **SemanticSearch** / **Read** 仓库代码,使**预期改动路径**可落地。
34
+ 3. 全部完成后汇总:工作项路径、已创建文件、PRD 与各工件对应关系(一两句);回复含各工件一句话用途。
171
35
 
172
- - 行首 **`- [ ]`**;分组 **`## 1. 名称`**;编号 **`- [ ] 1.1 说明`**(组号.序号)。
173
- - 每项下方缩进子列表:**需求编号**(对应 specs 中需求/场景)、**预期改动路径**、**验证用例编号**(可选)、**完成标准**。
174
- - **做什么**以 specs 为准,**改哪里**以 design 为准;按技术依赖排序。
36
+ #### 单会话读取策略
175
37
 
176
- ```markdown
177
- ## 1. 数据层
38
+ 同一会话连续跑完时可省略重复 Read,但**不得**省略依赖关系;断点续写或新会话须按上表**依赖**列重新 Read 磁盘文件。
178
39
 
179
- - [ ] 1.1 新增合同状态字段
180
- - **需求编号**:需求:合同状态同步(见 specs/contract.md)
181
- - **预期改动路径**:`servers/be/prisma/schema.prisma`
182
- - **完成标准**:迁移可执行;已有合同默认状态正确
183
- ```
40
+ | 文件 | 建议 |
41
+ | ---------------------------------- | ----------------------------------------------------- |
42
+ | `docs/PRD.md` | 进入流程时至少读一次全文 |
43
+ | `plans/proposal.md` | 写 design/specs 时,若本会话刚写入全文可不重复 Read |
44
+ | `plans/design.md` / `plans/specs/` | 写 `plans/tasks.md` 时若无可靠记忆须 Read;以落盘为准 |
184
45
 
185
46
  ---
186
47
 
187
48
  ## Guardrails
188
49
 
189
50
  - 后写须与 PRD 及已落盘前序文件一致。
190
- - 四个工件缺一不可(specs 至少一个 `.md`);落盘非空后再进下一工件。
51
+ - 四工件缺一不可(`plans/specs/` 至少一个 `.md`);落盘非空后再进下一工件。
191
52
  - **默认不覆盖**已有规划文件;用户明确要求「整目录覆盖重生成」时除外。
@@ -0,0 +1,37 @@
1
+ ## 撰写说明
2
+
3
+ 跨模块、新依赖、安全/性能/迁移复杂或方案待拍板时写完整版;否则可精简,但保留 **Context** 与 **Decisions**。
4
+
5
+ ## 模板
6
+
7
+ ```markdown
8
+ ## Context
9
+
10
+ <!-- 背景、约束、与 PRD / proposal 的衔接 -->
11
+
12
+ ## Goals / Non-Goals
13
+
14
+ **Goals:**
15
+
16
+ <!-- 本设计要达成的目标 -->
17
+
18
+ **Non-Goals:**
19
+
20
+ <!-- 明确不在本设计范围内的事项 -->
21
+
22
+ ## Decisions
23
+
24
+ <!-- 每项:备选 + 取舍理由 -->
25
+
26
+ ## Risks / Trade-offs
27
+
28
+ <!-- [风险] → 缓解 -->
29
+
30
+ ## Migration Plan
31
+
32
+ <!-- 无则写 无 / 不适用 -->
33
+
34
+ ## Open Questions
35
+
36
+ <!-- 无则写 无 -->
37
+ ```
@@ -0,0 +1,31 @@
1
+ ## 模板
2
+
3
+ ```markdown
4
+ ## Why
5
+
6
+ <!-- 1~2 句:解决什么、为何是现在 -->
7
+
8
+ ## What Changes
9
+
10
+ <!-- 变更要点;破坏性变更标注 BREAKING -->
11
+
12
+ ## Capabilities
13
+
14
+ <!-- proposal 与 specs 的契约:每一项须在后续 `plans/specs/` 可追溯 -->
15
+
16
+ ### New Capabilities
17
+
18
+ <!-- 每条对应 `plans/specs/<kebab-name>.md`(如 `user-auth`)。 -->
19
+
20
+ - `<name>`: <brief description>
21
+
22
+ ### Modified Capabilities
23
+
24
+ <!-- 规格层行为变更;无则写「无」 -->
25
+
26
+ - `<existing-name>`: <what requirement behavior changes>
27
+
28
+ ## Impact
29
+
30
+ <!-- 受影响代码、API、依赖、系统 -->
31
+ ```
@@ -0,0 +1,39 @@
1
+ ## 文件组织
2
+
3
+ 一能力一文件 `plans/specs/<短横线名称>.md`(或 `plans/specs/<名称>/规格.md`,同一工作项内择一,勿混用)。
4
+
5
+ ## 结构约定
6
+
7
+ - 分块(`##`):**新增需求** / **变更需求** / **移除需求** / **重命名需求**(按需组合;纯新增只用「新增需求」)。
8
+ - 需求:`**### 需求:<名称>**`;行为用 **须、必须**。
9
+ - 场景:`**#### 场景:<名称>**`(固定四个 `#`);正文 `- **当** …` / `- **则** …`。
10
+ - **每条需求至少一个场景**;变更需求须写**完整替换段落**(从需求到全部场景),禁止只贴片段。
11
+
12
+ ## 模板
13
+
14
+ ```markdown
15
+ ## 新增需求
16
+
17
+ ### 需求:<名称>
18
+
19
+ 系统须 …
20
+
21
+ #### 场景:<名称>
22
+
23
+ - **当** …
24
+ - **则** …
25
+
26
+ ## 变更需求
27
+
28
+ <!-- 完整替换后的需求 + 全部场景 -->
29
+
30
+ ## 移除需求
31
+
32
+ ### 需求:<名称>
33
+
34
+ **原因**:… **迁移说明**:…
35
+
36
+ ## 重命名需求
37
+
38
+ - **原名称:** … **新名称:** …
39
+ ```
@@ -0,0 +1,16 @@
1
+ ## 格式约定
2
+
3
+ - 行首 **`- [ ]`**;分组 **`## 1. 名称`**;编号 **`- [ ] 1.1 说明`**(组号.序号)。
4
+ - 每项下方缩进子列表:**需求编号**(对应 specs 中需求/场景)、**预期改动路径**、**验证用例编号**(可选)、**完成标准**。
5
+ - **做什么**以 specs 为准,**改哪里**以 design 为准;按技术依赖排序。
6
+
7
+ ## 示例
8
+
9
+ ```markdown
10
+ ## 1. 数据层
11
+
12
+ - [ ] 1.1 新增合同状态字段
13
+ - **需求编号**:需求:合同状态同步(见 plans/specs/contract.md)
14
+ - **预期改动路径**:`servers/be/prisma/schema.prisma`
15
+ - **完成标准**:迁移可执行;已有合同默认状态正确
16
+ ```
@@ -1,12 +1,16 @@
1
- ## 输入
1
+ ## 工作流程
2
+
3
+ ### 步骤 1: 获取当前版本 PRD 的内容
2
4
 
3
- 需求文档:使用 **Read** 工具读 `.apm/sessions/<sessionId>/docs/PRD.md`;若文档存在才进行下面的需求评审流程,否则直接退出并输出:没有看到需求内容。
5
+ 先用 **Read** 工具阅读 `.apm/sessions/<会话ID>/docs/PRD.md`,如果存在则这个目录下的内容为需求文档,否则用 **Read** 工具阅读 `.apm/sessions/<会话ID>/TASK.md`,并把这个文件里面的内容视为需求文档
4
6
 
5
- ## 评审目标
7
+ ### 步骤 2: 理解代码,给出评审意见,具体要求如下:
8
+
9
+ #### 评审目标如下:
6
10
 
7
11
  1. 梳理需求边界:发现文档中未写清的口径
8
12
  2. 调研实现难度:在实现难度较高时给出提示
9
- 3. 禁止为了凑问题而提问,当 PRD 已足够清晰且无高难度改造时,可直接说此需求没问题
13
+ 3. 禁止为了凑问题而提问,当 PRD 已足够清晰且无高难度改造时,可直接说此任务没问题
10
14
  4. 你只需要站在自己的角度去评审,禁止站在全局思考问题。结合代码进行评审即可:
11
15
  - 前端关注 UI 交互还原,交互逻辑的各种边界,不考虑一些与后端接口之类的问题
12
16
  - 后端则关注数据表设计,需求对应的数据接口是否合理,能否获取
@@ -14,17 +18,9 @@
14
18
 
15
19
  **难度高的定义**:预估改动的文件可能比较多,超过 10 个;或者改动逻辑比较复杂;
16
20
 
17
- ## 表达规范
21
+ #### 表达规范如下
18
22
 
19
23
  1. **产品语言优先**:页面定位用「医德考评弹窗」「行风办审批页」等说法;**禁止**用文件路径、组件名、函数名作为论据主体。
20
24
  2. **后端可略宽**:必要时可写**表名 / 主表字段名**帮助产品理解数据口径,但仍避免贴大段代码或接口路径。
21
- 3. **锚定 PRD**:当需要引用到需求文档中的某一条时可以直接说行号,比如:需求原文[1-3]说 xxx;
25
+ 3. **锚定 PRD**:当需要引用到任务文档中的某一条时可以直接说行号,比如:需求原文[1-3]说 xxx;
22
26
  4. **问题 = 文档缺口**:只写 PRD **未写清**且**影响本端理解边界**的点。已写清楚的规则不要重复质疑。
23
-
24
- ## 工作流程
25
-
26
- ### 步骤 1: 读取 PRD 内容,具体见第一节输入输入
27
-
28
- ### 步骤 2: 理解代码,评估 PRD
29
-
30
- ### 步骤 3: 回复用户
@@ -1,69 +1,16 @@
1
- ## 输入
2
- 1. 口头需求要求:如果是用户口头需求要求则根据下面需求模板编写PRD
3
- 2. 已有PRD+用户提要求:这个场景是润色现有的PRD文档,一般是原有PRD中的一些问题被解决了
4
-
5
- **注意**:
6
- - 编写/润色PRD时禁止提出额外的问题,一切以用户要求为准。
7
- - 已有PRD的地址为: `../../sessions/<需求ID>/docs/PRD.md`,可用 **Read** 工具读取。
8
- - 需求要始终保持干净,模板规定以外的,比如历史沟通记录不需要
9
-
10
1
  ## 工作流程
11
- ### 步骤1: 读取PRD
12
- ### 步骤2: 按照下面的模板要求编写PRD
13
- ### 步骤3: 同步PRD到远程
14
-
15
-
16
- ## 需求模板
17
- ### 正文骨架
18
- ```markdown
19
- ## 背景
20
- (1 ~ 3 句:业务背景、要解决的问题、预期效果,如果没有可空着,不要强行编)
21
-
22
- ## 范围
23
- - **包含**:…
24
- - **不包含**:…
25
-
26
- ## 需求说明
27
-
28
- ### 需求点 1:[简短名称]
29
- - …
30
- - …
31
-
32
- ### 需求点 2:…
33
- ```
34
-
35
- ### 需求点编写规范
36
-
37
- 每条 bullet 写清一个可验收点,优先覆盖:
38
-
39
- | 类型 | 写法要点 |
40
- | --------- | ------------------------------------------------------ |
41
- | 展示/选项 | 展示或隐藏;保留/去掉哪些选项;新建默认值 |
42
- | 文案 | 原名称 → 新名称;界面、提示、校验文案一并统一 |
43
- | 按钮 | 场景 + 按钮名 + 行为(对照哪个既有按钮、是否仅改文案) |
44
- | 校验 | 场景 + 字段展示条件 + 必填时机(暂存 / 提交分别怎样) |
45
- | 边界 | **不考虑** …(历史数据、迁移、导出等明确排除项) |
46
2
 
47
- 材料中的技术名可译为业务表述,例如:`audit1` 一级审批;保存不推进流程 **暂存**;办理并推进流程 → **提交**。
3
+ ### 步骤 1: 获取当前版本 PRD 的内容
48
4
 
49
- 编写示例如下:
5
+ 先用 **Read** 工具阅读 `.apm/sessions/<会话ID>/docs/PRD.md`,如果存在,则这个目录下的内容为需求文档,否则用 **Read** 工具阅读 `.apm/sessions/<会话ID>/TASK.md`,并把这个文件里面的内容视为需求文档
50
6
 
51
- ```markdown
52
- ### 需求点 2:新增/编辑弹窗底部操作
7
+ ### 步骤 2: 按照下面的模板要求编写 PRD
53
8
 
54
- - 在**新增、编辑**场景下,弹窗底部新增 **「暂存」** 按钮。
55
- - **「暂存」**:沿用原 **「确定」** 按钮的业务逻辑(含校验与保存/流程行为),**仅将按钮展示文案改为「暂存」**。
9
+ 用 **Read** 工具阅读 `.apm/skills/apm-write-prd/template.md`,按照模板来写,写完保存到 `.apm/sessions/<会话ID>/docs/PRD.md`
56
10
 
57
- ### 需求点 3:「科室医德考评小组人员名单」字段
11
+ 内容要求如下:
12
+ **不管是第几版需求,都要当成第一版来看,禁止有历史版本或者修订版本或者第几版更新的字样**
58
13
 
59
- - 原字段展示名 **「科室医德考评人员名单」** 统一改为 **「科室医德考评小组人员名单」**;凡界面、提示、校验文案等涉及该名称处**一并修改**。
60
- - 当流程处于 **一级审批** 且该字段**展示**时,须校验为**必填**(在展示场景下触发,而非所有保存入口一律校验)。
61
- ```
14
+ ### 步骤 3: 同步 PRD 到远程
62
15
 
63
- ### 自检列表
64
- - [ ] 含 **背景与目标、范围、需求说明** 三章,叙述完整
65
- - [ ] 2 分钟内可通读;每个需求点 2 ~ 5 条 bullet,一层列表
66
- - [ ] 场景、按钮行为、校验时机表述清楚,前后一致
67
- - [ ] 「范围」与需求点中的 **「不考虑」** 口径一致
68
- - [ ] 全文使用业务语言,术语统一
69
- - [ ] 仅材料明确涉及时才有「非功能」「待确认」
16
+ 执行命令:`apm sync-document <会话 ID> --file=PRD.md`
@@ -0,0 +1,55 @@
1
+
2
+ ## 需求模板
3
+ ### 正文骨架
4
+ ```markdown
5
+ ## 背景
6
+ (1 ~ 3 句:业务背景、要解决的问题、预期效果,如果没有可空着,不要强行编)
7
+
8
+ ## 范围
9
+ - **包含**:…
10
+ - **不包含**:…
11
+
12
+ ## 需求说明
13
+
14
+ ### 需求点 1:[简短名称]
15
+ - …
16
+ - …
17
+
18
+ ### 需求点 2:…
19
+ ```
20
+
21
+ ### 需求点编写规范
22
+
23
+ 每条 bullet 写清一个可验收点,优先覆盖:
24
+
25
+ | 类型 | 写法要点 |
26
+ | --------- | ------------------------------------------------------ |
27
+ | 展示/选项 | 展示或隐藏;保留/去掉哪些选项;新建默认值 |
28
+ | 文案 | 原名称 → 新名称;界面、提示、校验文案一并统一 |
29
+ | 按钮 | 场景 + 按钮名 + 行为(对照哪个既有按钮、是否仅改文案) |
30
+ | 校验 | 场景 + 字段展示条件 + 必填时机(暂存 / 提交分别怎样) |
31
+ | 边界 | **不考虑** …(历史数据、迁移、导出等明确排除项) |
32
+
33
+ 材料中的技术名可译为业务表述,例如:`audit1` → 一级审批;保存不推进流程 → **暂存**;办理并推进流程 → **提交**。
34
+
35
+ 编写示例如下:
36
+
37
+ ```markdown
38
+ ### 需求点 2:新增/编辑弹窗底部操作
39
+
40
+ - 在**新增、编辑**场景下,弹窗底部新增 **「暂存」** 按钮。
41
+ - **「暂存」**:沿用原 **「确定」** 按钮的业务逻辑(含校验与保存/流程行为),**仅将按钮展示文案改为「暂存」**。
42
+
43
+ ### 需求点 3:「科室医德考评小组人员名单」字段
44
+
45
+ - 原字段展示名 **「科室医德考评人员名单」** 统一改为 **「科室医德考评小组人员名单」**;凡界面、提示、校验文案等涉及该名称处**一并修改**。
46
+ - 当流程处于 **一级审批** 且该字段**展示**时,须校验为**必填**(在展示场景下触发,而非所有保存入口一律校验)。
47
+ ```
48
+
49
+ ### 自检列表
50
+ - [ ] 含 **背景与目标、范围、需求说明** 三章,叙述完整
51
+ - [ ] 2 分钟内可通读;每个需求点 2 ~ 5 条 bullet,一层列表
52
+ - [ ] 场景、按钮行为、校验时机表述清楚,前后一致
53
+ - [ ] 「范围」与需求点中的 **「不考虑」** 口径一致
54
+ - [ ] 全文使用业务语言,术语统一
55
+ - [ ] 仅材料明确涉及时才有「非功能」「待确认」