ai-project-manage-cli 6.0.31 → 6.0.33
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
|
@@ -238,6 +238,10 @@ var requestConfig = {
|
|
|
238
238
|
method: "PUT",
|
|
239
239
|
path: "/cli/messages/content"
|
|
240
240
|
}),
|
|
241
|
+
setMessageError: defineEndpoint({
|
|
242
|
+
method: "PUT",
|
|
243
|
+
path: "/cli/messages/error"
|
|
244
|
+
}),
|
|
241
245
|
upsertCursorMessageLog: defineEndpoint({
|
|
242
246
|
method: "PUT",
|
|
243
247
|
path: "/cli/cursor-message-logs"
|
|
@@ -496,11 +500,14 @@ import { join as join5 } from "path";
|
|
|
496
500
|
import { stringify as yamlStringify } from "yaml";
|
|
497
501
|
|
|
498
502
|
// src/session-messages-xml.ts
|
|
503
|
+
function asXmlText(value) {
|
|
504
|
+
return value ?? "";
|
|
505
|
+
}
|
|
499
506
|
function escapeXmlAttr(value) {
|
|
500
|
-
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
507
|
+
return asXmlText(value).replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
501
508
|
}
|
|
502
509
|
function wrapCdata(value) {
|
|
503
|
-
return `<![CDATA[${value.replace(/]]>/g, "]]]]><![CDATA[>")}]]>`;
|
|
510
|
+
return `<![CDATA[${asXmlText(value).replace(/]]>/g, "]]]]><![CDATA[>")}]]>`;
|
|
504
511
|
}
|
|
505
512
|
function formatSessionMessagesXml(sessionId, messages) {
|
|
506
513
|
const lines = [
|
|
@@ -1496,10 +1503,10 @@ async function updateMessageStatus(cfg, messageId, status) {
|
|
|
1496
1503
|
await api.cli.updateMessageStatus({ id: messageId, status });
|
|
1497
1504
|
console.log(`[apm] \u5DF2\u66F4\u65B0\u6D88\u606F\u72B6\u6001: ${messageId} \u2192 ${status}`);
|
|
1498
1505
|
}
|
|
1499
|
-
async function
|
|
1506
|
+
async function setMessageError(cfg, messageId, error) {
|
|
1500
1507
|
const api = createApmApiClient(cfg);
|
|
1501
|
-
await api.cli.
|
|
1502
|
-
console.log(`[apm] \u5DF2\
|
|
1508
|
+
await api.cli.setMessageError({ id: messageId, error });
|
|
1509
|
+
console.log(`[apm] \u5DF2\u8BBE\u7F6E\u6D88\u606F\u9519\u8BEF: ${messageId}`);
|
|
1503
1510
|
}
|
|
1504
1511
|
var SHUTDOWN_DRAIN_MS = 3e3;
|
|
1505
1512
|
async function handleInboundMessage(cfg, raw, signal) {
|
|
@@ -1522,48 +1529,78 @@ async function handleInboundMessage(cfg, raw, signal) {
|
|
|
1522
1529
|
}
|
|
1523
1530
|
const msg = validated.data;
|
|
1524
1531
|
const messageId = msg.messageId;
|
|
1532
|
+
const runStep = async (step, fn) => {
|
|
1533
|
+
try {
|
|
1534
|
+
return await fn();
|
|
1535
|
+
} catch (err) {
|
|
1536
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
1537
|
+
throw new Error(`[${step}] ${detail}`);
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1525
1540
|
try {
|
|
1526
1541
|
if (signal.aborted) return;
|
|
1527
|
-
await
|
|
1542
|
+
await runStep(
|
|
1543
|
+
"branch",
|
|
1544
|
+
() => runBranch(msg.sessionId, { cwd: msg.workdir })
|
|
1545
|
+
);
|
|
1528
1546
|
if (signal.aborted) return;
|
|
1529
|
-
await
|
|
1547
|
+
await runStep(
|
|
1548
|
+
"pull",
|
|
1549
|
+
() => runPull(msg.sessionId, workspaceApmDir(msg.workdir))
|
|
1550
|
+
);
|
|
1530
1551
|
if (signal.aborted) return;
|
|
1531
|
-
await
|
|
1552
|
+
await runStep(
|
|
1553
|
+
"commit-pull",
|
|
1554
|
+
() => commitWorkingTreeIfDirty(msg.workdir, "fix: apm pull")
|
|
1555
|
+
);
|
|
1532
1556
|
if (signal.aborted) return;
|
|
1533
|
-
await
|
|
1534
|
-
|
|
1535
|
-
cfg,
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1557
|
+
await runStep(
|
|
1558
|
+
"status-typing",
|
|
1559
|
+
() => updateMessageStatus(cfg, messageId, "TYPING")
|
|
1560
|
+
);
|
|
1561
|
+
await runStep(
|
|
1562
|
+
"cursor-agent",
|
|
1563
|
+
() => runCursorAgent(
|
|
1564
|
+
cfg,
|
|
1565
|
+
{
|
|
1566
|
+
messageId: msg.messageId,
|
|
1567
|
+
sessionId: msg.sessionId,
|
|
1568
|
+
prompt: msg.content,
|
|
1569
|
+
model: msg.model,
|
|
1570
|
+
apiKey: msg.apiKey,
|
|
1571
|
+
workdir: msg.workdir
|
|
1572
|
+
},
|
|
1573
|
+
{ signal }
|
|
1574
|
+
)
|
|
1545
1575
|
);
|
|
1546
|
-
await
|
|
1547
|
-
|
|
1548
|
-
msg.sessionId,
|
|
1549
|
-
workspaceApmDir(msg.workdir)
|
|
1576
|
+
await runStep(
|
|
1577
|
+
"sync-documents",
|
|
1578
|
+
() => syncSessionDocuments(cfg, msg.sessionId, workspaceApmDir(msg.workdir))
|
|
1550
1579
|
);
|
|
1551
|
-
await
|
|
1552
|
-
|
|
1553
|
-
|
|
1580
|
+
await runStep(
|
|
1581
|
+
"commit-documents",
|
|
1582
|
+
() => commitWorkingTreeIfDirty(
|
|
1583
|
+
msg.workdir,
|
|
1584
|
+
"chore(apm): sync session documents"
|
|
1585
|
+
)
|
|
1586
|
+
);
|
|
1587
|
+
await runStep(
|
|
1588
|
+
"status-success",
|
|
1589
|
+
() => updateMessageStatus(cfg, messageId, "SUCCESS")
|
|
1554
1590
|
);
|
|
1555
|
-
await updateMessageStatus(cfg, messageId, "SUCCESS");
|
|
1556
1591
|
} catch (err) {
|
|
1557
1592
|
console.error(
|
|
1558
1593
|
"[apm] \u5904\u7406\u6D88\u606F\u5931\u8D25:",
|
|
1559
1594
|
err instanceof Error ? err.message : err
|
|
1560
1595
|
);
|
|
1596
|
+
if (err instanceof Error && err.stack) {
|
|
1597
|
+
console.error(err.stack);
|
|
1598
|
+
}
|
|
1561
1599
|
try {
|
|
1562
|
-
await
|
|
1600
|
+
await setMessageError(
|
|
1563
1601
|
cfg,
|
|
1564
1602
|
messageId,
|
|
1565
|
-
|
|
1566
|
-
`
|
|
1603
|
+
err instanceof Error ? err.message : String(err)
|
|
1567
1604
|
);
|
|
1568
1605
|
await updateMessageStatus(cfg, messageId, "FAILED");
|
|
1569
1606
|
} catch (statusErr) {
|
package/package.json
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
内容要求如下:
|
|
12
12
|
**不管是第几版需求,都要当成第一版来看,禁止有历史版本或者修订版本或者第几版更新的字样**
|
|
13
13
|
|
|
14
|
+
**可读性**:信息完整保留,但避免整段只靠长句堆砌。对流程分支、状态条件、按钮对照、范围边界等多步骤/多条件内容,按模板中的「图示原则」**适当补充 Mermaid 图或简表**(每个需求点 0 ~ 1 张);图示用于快速扫读,**可验收细节仍以 bullet 为准**,不得因配图而删减文字要求。
|
|
15
|
+
|
|
14
16
|
### 步骤 3: 同步 PRD 到远程
|
|
15
17
|
|
|
16
18
|
执行命令:`apm sync-document <会话 ID> --file=PRD.md`
|
|
@@ -1,17 +1,43 @@
|
|
|
1
|
-
|
|
2
1
|
## 需求模板
|
|
2
|
+
|
|
3
|
+
### 图示原则
|
|
4
|
+
|
|
5
|
+
信息量保持完整,**文字与图示互补**:bullet 写清可验收细节,图示帮助读者快速建立整体印象。优先用 **Mermaid**(Markdown 内嵌,无需额外图片文件)。
|
|
6
|
+
|
|
7
|
+
| 场景 | 推荐图示 | 作用 |
|
|
8
|
+
| ------------------------------------------- | -------------------------------- | -------------------------- |
|
|
9
|
+
| 多步骤操作流程(审批、暂存/提交、办理路径) | `flowchart` | 一眼看清先后与分支 |
|
|
10
|
+
| 字段展示/必填随状态变化 | `flowchart` 或 `stateDiagram-v2` | 替代「当 A 且 B 时…」长句 |
|
|
11
|
+
| 弹窗/页面内区块与按钮布局 | `block-beta` 或 ASCII 框图 | 标出按钮位置与对照关系 |
|
|
12
|
+
| 多需求点关系、范围边界 | `mindmap` 或简表 | 开篇总览,再展开 bullet |
|
|
13
|
+
| 角色与系统交互时序 | `sequenceDiagram` | 仅步骤多、文字难扫读时使用 |
|
|
14
|
+
|
|
15
|
+
**图示写法**:
|
|
16
|
+
|
|
17
|
+
- 每个需求点 **0 ~ 1 张** 图即可;一张图只表达一个核心概念,节点用业务语言(如「一级审批」「暂存」)。
|
|
18
|
+
- 图 **不替代** bullet:图后仍保留 2 ~ 5 条可验收 bullet,图中未写清的细节(文案、边界、校验时机)必须在文字中写明。
|
|
19
|
+
- 图为辅助:若单条 bullet 已足够清楚,**不必强行配图**。
|
|
20
|
+
|
|
3
21
|
### 正文骨架
|
|
22
|
+
|
|
4
23
|
```markdown
|
|
5
24
|
## 背景
|
|
25
|
+
|
|
6
26
|
(1 ~ 3 句:业务背景、要解决的问题、预期效果,如果没有可空着,不要强行编)
|
|
7
27
|
|
|
8
28
|
## 范围
|
|
29
|
+
|
|
9
30
|
- **包含**:…
|
|
10
31
|
- **不包含**:…
|
|
11
32
|
|
|
33
|
+
(可选:范围较大时,用 mindmap 或简表做一页总览)
|
|
34
|
+
|
|
12
35
|
## 需求说明
|
|
13
36
|
|
|
14
37
|
### 需求点 1:[简短名称]
|
|
38
|
+
|
|
39
|
+
(可选:流程/状态/布局类需求,在此放一张 Mermaid 图)
|
|
40
|
+
|
|
15
41
|
- …
|
|
16
42
|
- …
|
|
17
43
|
|
|
@@ -42,14 +68,67 @@
|
|
|
42
68
|
|
|
43
69
|
### 需求点 3:「科室医德考评小组人员名单」字段
|
|
44
70
|
|
|
71
|
+
(本需求点适合在 bullet 前加「字段展示与校验」流程图,见下方「图示示例」)
|
|
72
|
+
|
|
45
73
|
- 原字段展示名 **「科室医德考评人员名单」** 统一改为 **「科室医德考评小组人员名单」**;凡界面、提示、校验文案等涉及该名称处**一并修改**。
|
|
46
74
|
- 当流程处于 **一级审批** 且该字段**展示**时,须校验为**必填**(在展示场景下触发,而非所有保存入口一律校验)。
|
|
47
75
|
```
|
|
48
76
|
|
|
77
|
+
### 图示示例(按需选用)
|
|
78
|
+
|
|
79
|
+
**字段展示与校验**(对应上文需求点 3):
|
|
80
|
+
|
|
81
|
+
```mermaid
|
|
82
|
+
flowchart LR
|
|
83
|
+
A[进入表单] --> B{流程处于一级审批?}
|
|
84
|
+
B -->|是| C[展示该字段]
|
|
85
|
+
B -->|否| D[按原规则展示/隐藏]
|
|
86
|
+
C --> E{用户操作}
|
|
87
|
+
E -->|暂存或提交| F[校验必填]
|
|
88
|
+
E -->|仅浏览未保存| G[不触发必填校验]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**流程分支**(暂存 vs 提交、审批节点):
|
|
92
|
+
|
|
93
|
+
```mermaid
|
|
94
|
+
flowchart TD
|
|
95
|
+
A[用户打开新增/编辑弹窗] --> B[填写表单]
|
|
96
|
+
B --> C{点击底部按钮}
|
|
97
|
+
C -->|暂存| D[沿用原「确定」逻辑:校验 + 保存,不推进流程]
|
|
98
|
+
C -->|提交| E[沿用原「办理」逻辑:校验 + 保存并推进流程]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**弹窗底部按钮布局**(对照既有按钮):
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
┌─────────────────────────────────────┐
|
|
105
|
+
│ 新增 / 编辑弹窗 │
|
|
106
|
+
│ …表单字段… │
|
|
107
|
+
├─────────────────────────────────────┤
|
|
108
|
+
│ [ 取消 ] [ 暂存 ] │ ← 暂存:原「确定」逻辑,仅改文案
|
|
109
|
+
└─────────────────────────────────────┘
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**范围总览**(需求点较多时,放在「范围」之后):
|
|
113
|
+
|
|
114
|
+
```mermaid
|
|
115
|
+
mindmap
|
|
116
|
+
root((本需求))
|
|
117
|
+
包含
|
|
118
|
+
弹窗底部操作
|
|
119
|
+
字段更名与校验
|
|
120
|
+
不包含
|
|
121
|
+
历史数据迁移
|
|
122
|
+
导出能力
|
|
123
|
+
```
|
|
124
|
+
|
|
49
125
|
### 自检列表
|
|
126
|
+
|
|
50
127
|
- [ ] 含 **背景与目标、范围、需求说明** 三章,叙述完整
|
|
51
128
|
- [ ] 2 分钟内可通读;每个需求点 2 ~ 5 条 bullet,一层列表
|
|
129
|
+
- [ ] 流程/状态/多分支类需求点有 **图示或简表** 辅助,且 bullet 仍覆盖图中未写清的细节
|
|
130
|
+
- [ ] 图示节点使用业务语言,与正文术语一致;无仅看图无法验收的遗漏
|
|
52
131
|
- [ ] 场景、按钮行为、校验时机表述清楚,前后一致
|
|
53
132
|
- [ ] 「范围」与需求点中的 **「不考虑」** 口径一致
|
|
54
133
|
- [ ] 全文使用业务语言,术语统一
|
|
55
|
-
- [ ] 仅材料明确涉及时才有「非功能」「待确认」
|
|
134
|
+
- [ ] 仅材料明确涉及时才有「非功能」「待确认」
|