ai-project-manage-cli 3.0.1 → 3.0.2
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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { readFileSync as readFileSync5 } from "fs";
|
|
5
|
-
import { dirname as dirname2, join as
|
|
5
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
6
6
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
|
|
@@ -411,9 +411,11 @@ async function runPull(requirementId) {
|
|
|
411
411
|
|
|
412
412
|
// src/commands/refine.ts
|
|
413
413
|
import { readFileSync as readFileSync4 } from "fs";
|
|
414
|
-
|
|
414
|
+
import { join as join5 } from "path";
|
|
415
|
+
async function runRefine(requirementId) {
|
|
415
416
|
const cfg = await ensureLoggedConfig();
|
|
416
|
-
const
|
|
417
|
+
const filePath = join5(WORKSPACE_APM_DIR, "workitems", requirementId, "prd.md");
|
|
418
|
+
const content = readFileSync4(filePath, "utf8");
|
|
417
419
|
const api = createApmApiClient(cfg);
|
|
418
420
|
const data = await api.cliRequirements.refine({ requirementId, content });
|
|
419
421
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -445,7 +447,7 @@ async function runUpdateStatus(requirementId, status) {
|
|
|
445
447
|
function readCliVersion() {
|
|
446
448
|
try {
|
|
447
449
|
const dir = dirname2(fileURLToPath2(import.meta.url));
|
|
448
|
-
const pkgPath =
|
|
450
|
+
const pkgPath = join6(dir, "..", "package.json");
|
|
449
451
|
const pkg = JSON.parse(readFileSync5(pkgPath, "utf8"));
|
|
450
452
|
return pkg.version ?? "0.0.0";
|
|
451
453
|
} catch {
|
|
@@ -479,8 +481,8 @@ function buildProgram() {
|
|
|
479
481
|
await runComment(requirementId, options.file, options.model);
|
|
480
482
|
}
|
|
481
483
|
);
|
|
482
|
-
program.command("refine").description("POST /api/cli/requirements/refine\uFF08\u6B63\u6587\u6765\u81EA\u6587\u4EF6\uFF09").argument("<requirementId>", "\u9700\u6C42 ID").
|
|
483
|
-
await runRefine(requirementId
|
|
484
|
+
program.command("refine").description("POST /api/cli/requirements/refine\uFF08\u6B63\u6587\u6765\u81EA\u6587\u4EF6\uFF09").argument("<requirementId>", "\u9700\u6C42 ID").action(async (requirementId) => {
|
|
485
|
+
await runRefine(requirementId);
|
|
484
486
|
});
|
|
485
487
|
program.command("update-status").description("POST /api/cli/requirements/update-status").argument("<requirementId>", "\u9700\u6C42 ID").requiredOption("--status <RequirementStatus>", "\u9700\u6C42\u72B6\u6001\u679A\u4E3E\u503C").action(async (requirementId, options) => {
|
|
486
488
|
await runUpdateStatus(requirementId, options.status);
|
package/package.json
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apm-review
|
|
3
|
+
description: 根据需求 ID 读取工作项 prd.md,对照代码做需求评审;评审立场依可见代码而定(仅前台 / 仅后台 / 全栈);提交到评论的正文用 Markdown 拉出层次与重点,业务白话、避免代码与工程术语;结合代码交付面过滤与现状无关的空头边界质疑,当用户在对话中 @ 本技能时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# APM 需求评审(对照代码)
|
|
7
|
+
|
|
8
|
+
用户仅提供 **需求 ID**(workitem id)。缺 ID 时索要,不猜测。
|
|
9
|
+
|
|
10
|
+
**评审规范与评审模板**(受众与用语、立场与范围、书写约束、正文示例等)见同目录 **[apm-review-reference.md](./apm-review-reference.md)**;执行本技能时须按该文件撰写评审正文。
|
|
11
|
+
|
|
12
|
+
## 强制执行顺序(三步)
|
|
13
|
+
|
|
14
|
+
### 步骤 1:读取 `prd.md`
|
|
15
|
+
|
|
16
|
+
1. 使用 **Read** 读取 `.apm/workitems/<需求ID>/prd.md`。
|
|
17
|
+
2. 若 Read **失败**(文件不存在或无法读取):本步骤记为失败,**终止**,不执行步骤 2、3。
|
|
18
|
+
|
|
19
|
+
### 步骤 2:撰写评审、落盘、推送、清理
|
|
20
|
+
|
|
21
|
+
1. 使用 **Read** 读取 [apm-review-reference.md](./apm-review-reference.md)(与 `SKILL.md` 同目录),并依其中规范对照代码撰写 **Markdown 评审正文**:**只写确实存在的问题**;用「需求背景 / 需求范围 / 交互与功能要求第 X 节 / 非目标」等文档自有结构**点名条款**,不先单独铺一节「对用户意图的理解」。撰写前须完成代码检索并锁定本轮**评审立场**(见 reference 中「评审立场」),正文内容与措辞须与该立场一致,**不得超越可见范围下断定**。
|
|
22
|
+
2. 使用 **Write** 将正文写入**临时文件**,路径建议使用**绝对路径**,例如 `/tmp/apm-review-<需求ID>.md`(避免与相对 cwd 混淆)。
|
|
23
|
+
3. 在项目根目录下执行:`apm comment <需求ID> --file=<临时文件绝对路径> --model=<评论使用的模型名称>`。
|
|
24
|
+
4. 命令结束后 **删除临时文件**(**Delete** 工具或 `rm`),无论命令成功或失败都尽量清理(失败时保留文件仅供用户排错——技能默认仍删除,若需保留应在表格备注中说明)。
|
|
25
|
+
|
|
26
|
+
### 步骤 3:回复用户
|
|
27
|
+
|
|
28
|
+
对用户可见回复 **仅限一张 Markdown 表格**,汇总三步的**结果**(成功/失败、摘要信息)。**不得**在表格外输出任何其他内容(不在对话中粘贴完整评审正文;正文已通过 `apm comment` 提交)。
|
|
29
|
+
|
|
30
|
+
建议表头:
|
|
31
|
+
|
|
32
|
+
| 步骤 | 结果 | 说明 |
|
|
33
|
+
|------|------|------|
|
|
34
|
+
| 1. 读取 prd.md | 成功 / 失败 | 例如实际读取路径;失败时写错误原因 |
|
|
35
|
+
| 2. 评审与 comment | 成功 / 失败 | 临时文件路径(已删可写「已清理」);`apm comment` 退出情况或 API 返回摘要;**建议**注明本轮评审立场(仅前台 / 仅后台 / 全栈) |
|
|
36
|
+
| 3. 清理临时文件 | 成功 / 失败 | — |
|
|
37
|
+
|
|
38
|
+
内部编排:**通读 prd → 检索并对照与需求相关的代码 → 判定本轮可见范围(仅前台 / 仅后台 / 全栈)并选定评审立场 → 将技术发现改写为业务白话 → 只输出有问题之处**;唯**对用户输出**遵守上表约束。
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# APM 需求评审规范与模板
|
|
2
|
+
|
|
3
|
+
> 供 `apm-review` 技能使用:撰写并落盘到临时文件的评审正文时,遵守本节全文。
|
|
4
|
+
|
|
5
|
+
## 评论受众与用语(写入 `apm comment` 的正文)
|
|
6
|
+
|
|
7
|
+
- **读者**:产品经理与业务方为主;评论会作为协作记录,应**全程可读、可转发**,不假设读者会写代码或熟悉工程名词。
|
|
8
|
+
- **禁止出现在评论正文里**:代码片段、文件路径、类名/函数名/接口名、库名、数据库表字段名、配置项名、命令行等与实现绑定的符号;也避免堆叠「中间件、DTO、ORM、幂等、熔断」等纯工程术语(除非已在 `prd.md` 里作为约定用语出现且别无说法)。
|
|
9
|
+
- **推荐写法**:用日常中文说明「用户会看到什么」「缺了哪条规则大家会各猜各的」「和现有能力会不会打架」等;若必须指向实现,只说「与当前后台/前台的既有能力有关」或「需要和技术同事确认某某板块是否已有」,**不把符号留给 PM 去对号入座**。
|
|
10
|
+
- **立场声明(业务白话,一两句即可)**:若本轮仅为**单侧**对照(只看清浏览器端或只看清服务端),正文**开头**用不加术语的一句话标明**评审视角**(例如「本轮主要对照当前浏览器里可见的界面与流程」或「本轮主要对照当前服务端已暴露的能力与数据边界」),让读者知道评论**不是**全链路结论;**两侧均已实质核对**时,可写一句「前后台实现均已对照」或省略。**禁止**用「从前端角度」「站在后端」等角色标签式套话堆砌,一句说清范围即可。
|
|
11
|
+
- **内部核对**:Agent 读代码时仍可自用路径与符号做推理;**落盘到临时文件、提交评论前**须把「代码依据」改写成上述白话,不复制粘贴技术标识符。
|
|
12
|
+
|
|
13
|
+
## 正文形态与语气(写入临时文件的评审)
|
|
14
|
+
|
|
15
|
+
- **像真人写的**:自然段落或简短条目均可;**禁止**行政腔、教程腔套话,例如「请先确认」「建议补一句」「会上拍板」「建议各方对齐」等指向「写作动作」的提示——只陈述**文档里哪里不顺、会导致什么后果**。
|
|
16
|
+
- **直入问题**:不写「对用户意图的理解」这类总起段;意图若与某条缺陷强相关,**并入该条一句带过**即可。
|
|
17
|
+
- **只写有内容的条目**:某类问题不存在则**整段不写**;**禁止**用「未发现矛盾」「未见明显问题」「在已对照范围内无……」等否定句凑篇幅。若通读后没有可写问题:正文可仅为一两句说明「按当前正文暂无新增评审意见」,**仍不写**空洞分类标题。
|
|
18
|
+
- **Markdown 结构与可读性(写入评论的正文)**:平台讨论区按 Markdown 渲染。正文宜用 **`##` 二级标题**按条拆分(标题里点明文档位置),条内可用 **「要点 / 后果」** 或等价两项列表;**关键短语加粗**,必要时用 `---` 分隔大段,避免「一整块纯叙述」难以扫读。结构服从内容:**没有问题则不硬凑条目**。
|
|
19
|
+
|
|
20
|
+
## 评审立场(依可见代码)
|
|
21
|
+
|
|
22
|
+
对照需求完成检索后,根据**本轮实际读过、且作为依据写入评论的代码范围**选定立场;**评论写什么、写到哪一层,以该可见范围为上限**。
|
|
23
|
+
|
|
24
|
+
| 可见范围 | 评审立场 | 写入评论时的要求 |
|
|
25
|
+
| -------------------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| 主要只见 **浏览器端 / 前台界面与交互** | **前台视角** | 只评界面入口、流程、状态与交互缺口;涉及持久化、权限、接口形态时,用白话写成「须与服务端/后台约定」「单凭当前界面看不出是否已有支撑」,**不下「后台一定如何」的断定**。 |
|
|
27
|
+
| 主要只见 **服务端 / API 与数据层** | **后台视角** | 只评服务能力、数据含义、权限与边界;涉及页面怎么摆、按钮文案时,用「展示层须另侧对齐」一类表述,**不代替产品写 UI 细则**。 |
|
|
28
|
+
| **前台与后台均已就本需求相关链路核对** | **全栈视角** | 可写前后衔接断层、端到端验收风险(仍用业务白话、禁止符号)。 |
|
|
29
|
+
|
|
30
|
+
**禁止**:只读过一侧却在评论中写超出该侧可见范围的**全称断定**(例如仅对照前台却断言「库里不会有某类数据」)。单侧视角下若发现需求显然依赖另一侧而未写明,应写「文档未约定与后台/前台的衔接点,易导致联调分歧」,而非编造另一侧实现细节。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 立场:专业评审,而非复述原文
|
|
35
|
+
|
|
36
|
+
- `prd.md` 可能口语化、不完整;正文用**清晰、可决策**的语言(业务名词与文档对齐),**对准具体条款**写缺口或风险。
|
|
37
|
+
- **禁止**空洞表态(例如「技术上都能做」);谈可行性须**建立在已读相关代码与模块边界之上**(且不超过上文「评审立场」准许的范围),说明与**现有能力划分、数据含义、产品约定**的关系及**后续改版成本**,用语落在「需求若坚持某种表述会带来何种**产品规则或协作上的代价**」,而非教人怎么写代码。
|
|
38
|
+
|
|
39
|
+
## 评审范围
|
|
40
|
+
|
|
41
|
+
### 要做(需求侧 + 基于代码的落地风险)
|
|
42
|
+
|
|
43
|
+
| 类别 | 说明 |
|
|
44
|
+
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| **意图与表述** | 业务目标、约束、成功画面是否可从文中唯一推断;关键名词是否需统一 |
|
|
46
|
+
| **歧义** | 多种合理解读并存 |
|
|
47
|
+
| **遗漏 / 不完整** | 边界、异常、权限、状态组合未写清;代码已覆盖场景文档未提 |
|
|
48
|
+
| **矛盾** | 章节或枚举互斥 |
|
|
49
|
+
| **不可验收** | 缺可观测判据或主语不明 |
|
|
50
|
+
| **与现状冲突 / 迭代风险** | **须在读完相关代码后**再写,且**不超出**上文「评审立场」准许的范围:与现有能力划分、数据含义、权限或流程约定抵触,或大牵连、难演进——**需求层取舍提醒**;正文只用**白话概括依据**,不写路径与符号(见「评论受众与用语」),非代码好坏评判 |
|
|
51
|
+
|
|
52
|
+
### 不要做
|
|
53
|
+
|
|
54
|
+
代码风格与微重构、与需求清晰度无关的性能闲话、替写完整正式 PRD(除非用户明确要求)、长篇复述 `prd.md` 全文。
|
|
55
|
+
|
|
56
|
+
若「实现与文档不一致」,表述落在**需求如何写清或与现状对齐**,不指责实现错误。
|
|
57
|
+
|
|
58
|
+
**与代码交付面脱节的「空头边界」**:对照代码后若已能判断**实际交付仅为 Web**(仓库无独立 App、小程序等其它端实现),且 `prd.md` **已写明**某条范围或非目标(例如「本期不考虑移动端 ×× 适配」),则**不再**单独写「未界定移动端是否包含窄屏桌面浏览器、平板横竖屏」等与**当前单一 Web 交付**无实质冲突、也不会改变验收判据的抠字条款——除非文档与「仅 Web」或验收环境约定**明显矛盾**,或 PRD 自己承诺了多终端却与代码不符。
|
|
59
|
+
|
|
60
|
+
## 书写约束(针对写入文件的评审正文)
|
|
61
|
+
|
|
62
|
+
- 每条问题须说清「指向文档哪一句 / 哪一节」+「会卡在哪」。篇幅上**优先简洁**:段落式宜控制在**两三句话量级**;若采用 **Markdown 分条**,每条下的「要点 / 后果」也各自保持简短,**禁止**为套模板而重复空话。
|
|
63
|
+
- 引用需求文档用章节名、小节编号或口语转述条款;**不写**代码或工程标识符,技术边界用「评论受众与用语」中的白话改写。
|
|
64
|
+
- **简洁优先**:宁可少写几条,也不要为显得「全面」而重复或空话。
|
|
65
|
+
- 不对「业务价值高低」做主观评判;可说明「需求未定义清楚会导致何种决策瘫痪或返工风险」。
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 评审模板(写入临时文件的正文示例,结构仅供参考)
|
|
70
|
+
|
|
71
|
+
按问题组织,**每条尽量点明文档位置**(章节名、小节编号、列表要点均可)。可读性要求高时优先采用 **Markdown 分条 + 要点/后果**(见上文「正文形态与语气」)。
|
|
72
|
+
|
|
73
|
+
**示例(标题 + 要点/后果 + 加粗):**
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
## 「需求范围」第三条:主链路落在哪一屏没说死
|
|
77
|
+
|
|
78
|
+
- **要点**:……
|
|
79
|
+
- **后果**:……
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 「交互与功能要求」第 4 节:类型认定规则缺失
|
|
84
|
+
|
|
85
|
+
- **要点**:……
|
|
86
|
+
- **后果**:……
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
(以上为示例:实际只保留**本轮确有依据**的条目;没有问题则不硬写。)
|