@ats-cx/cx-cli 0.1.0
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/.env.example +8 -0
- package/README.md +119 -0
- package/bin/cx-cli.cjs +90 -0
- package/config/apm-provider.json +7 -0
- package/config/apm-provider.template.jsonc +48 -0
- package/config/diagnostic-rules.json +54 -0
- package/config/diagnostic-rules.template.jsonc +82 -0
- package/config/event-semantics.json +828 -0
- package/config/event-semantics.template.jsonc +13 -0
- package/config/toolkit.json +3 -0
- package/dist/apm-help.d.ts +5 -0
- package/dist/apm-help.js +108 -0
- package/dist/apm-output.d.ts +49 -0
- package/dist/apm-output.js +115 -0
- package/dist/budget.d.ts +14 -0
- package/dist/budget.js +16 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.js +596 -0
- package/dist/context.d.ts +12 -0
- package/dist/context.js +20 -0
- package/dist/contract.d.ts +11 -0
- package/dist/contract.js +4 -0
- package/dist/errors.d.ts +4 -0
- package/dist/errors.js +8 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/dist/init.d.ts +17 -0
- package/dist/init.js +194 -0
- package/dist/output.d.ts +7 -0
- package/dist/output.js +7 -0
- package/dist/project-pull.d.ts +32 -0
- package/dist/project-pull.js +81 -0
- package/dist/report.d.ts +3 -0
- package/dist/report.js +42 -0
- package/dist/skills.d.ts +12 -0
- package/dist/skills.js +430 -0
- package/dist/tools/apm-tools.d.ts +115 -0
- package/dist/tools/apm-tools.js +329 -0
- package/dist/tools/conclusion-tools.d.ts +24 -0
- package/dist/tools/conclusion-tools.js +61 -0
- package/dist/tools/create-run.d.ts +61 -0
- package/dist/tools/create-run.js +273 -0
- package/dist/tools/log-tools.d.ts +68 -0
- package/dist/tools/log-tools.js +116 -0
- package/dist/tools/project-tools.d.ts +82 -0
- package/dist/tools/project-tools.js +139 -0
- package/dist/workspace.d.ts +51 -0
- package/dist/workspace.js +104 -0
- package/package.json +37 -0
- package/skills/apm-query/SKILL.md +304 -0
- package/skills/apm-query/agents/openai.yaml +10 -0
- package/skills/cx-cli-setup/SKILL.md +120 -0
- package/skills/cx-cli-setup/agents/openai.yaml +11 -0
- package/skills/editor-diagnostic/SKILL.md +255 -0
- package/skills/editor-diagnostic/agents/openai.yaml +13 -0
- package/skills/semantics-curation/SKILL.md +151 -0
- package/skills/semantics-curation/agents/openai.yaml +12 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: editor-diagnostic
|
|
3
|
+
description: >-
|
|
4
|
+
用 cx-cli 下载编辑器 project 快照 / 拉全量历史 / 诊断客诉。
|
|
5
|
+
当用户给出 projectId 要求「下载项目」「拉历史数据」,
|
|
6
|
+
或抱怨「保存没生效」「改完又变回去」「刷新后丢失」「裁剪切页后状态不对」时使用。
|
|
7
|
+
安装走 cx-cli-setup skill;不建 run 的临时取数走 apm-query skill。
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Editor Diagnostic(cx-cli)
|
|
11
|
+
|
|
12
|
+
先判断用户意图,选对走法:
|
|
13
|
+
|
|
14
|
+
| 意图 | 典型说法 | 走法 |
|
|
15
|
+
|------|----------|------|
|
|
16
|
+
| 下载 project | 「下载 6345434」「把这个项目拉下来」 | §2,一条命令 |
|
|
17
|
+
| 拉取项目历史 | 「拉全量历史」「要所有版本」 | §2,一条命令 |
|
|
18
|
+
| 分析客诉 | 「保存丢了」「行为诡异」「帮我查一下」 | §3,诊断主流程 |
|
|
19
|
+
|
|
20
|
+
## 1. 前提检查
|
|
21
|
+
|
|
22
|
+
**cx-cli 可用性**:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cx-cli --version
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
不可用,或当前编辑器仓库还没有 `.cx-cli/` 工作区时,交给 **cx-cli-setup skill**(机器级安装 +
|
|
29
|
+
项目级 `cx-cli init` 的统一入口);不要手工复刻安装步骤。
|
|
30
|
+
|
|
31
|
+
**配置目录**:优先级 `--config <目录>` > cwd 向上发现的 `.cx-cli/` 工作区 > `$CX_CLI_CONFIG_DIR` >
|
|
32
|
+
工具箱 `config/`。
|
|
33
|
+
|
|
34
|
+
在已 init 的编辑器源码仓库里工作时(日常情形),**所有命令都不用带 `--config`**:命令自己从 cwd
|
|
35
|
+
向上发现工作区,快照落 `.cx-cli/data/`、产物落 `.cx-cli/runs/`、源码三仓按宿主仓库自动绑定。
|
|
36
|
+
只有在工具箱仓库里跑 fixture 演练等场景才需要显式 `--config`——诊断命令的 `--config` 写在命令名
|
|
37
|
+
前后都行,`project pull` 只认写在命令名**之前**的(`cx-cli --config <目录> project pull <projectId>`)。
|
|
38
|
+
|
|
39
|
+
**`.env`(仅 `project pull` 需要)**:工作区 `.cx-cli/.env`(无工作区时回落 `~/.config/cx-cli/.env`),
|
|
40
|
+
明文五键 `DB_HOST` / `DB_USER` / `DB_PASSWORD` / `DB_NAME` / `DB_PORT`;`cx-cli init` 会生成模板并
|
|
41
|
+
列出缺哪些键,凭据向团队获取——**只提示用户填,不代填、不入库**。`--env <文件>` 可指定其他路径。
|
|
42
|
+
诊断命令不触碰 DB,不需要 `.env`;apm 组与 `run new` 拉日志也不读 `.env`。
|
|
43
|
+
|
|
44
|
+
**共享配置文件**(住工具箱根 `config/`,工作区读正在运行的 cx-cli 自身那份;相对路径均相对配置文件所在目录解析):
|
|
45
|
+
|
|
46
|
+
| 文件 | 说明 |
|
|
47
|
+
|------|------|
|
|
48
|
+
| `toolkit.json` + `toolkit.local.json` | runs 目录、project 快照库(projectHistoryDir)、日志源;工作区模式下前两项由工作区接管 |
|
|
49
|
+
| `apm-provider.json` + `apm-provider.local.json` | 线上 APM 网页端接口,零凭据;站点地址经本机覆盖提供,未配置时报 `unconfigured`,交 cx-cli-setup skill;local 只改值(站点 host / 业务线 / 取数页 / 超时) |
|
|
50
|
+
| `diagnostic-rules.json` | 可疑信号规则 |
|
|
51
|
+
|
|
52
|
+
**事件语义表**:工作区模式只读宿主仓库的 `.cx-cli/event-semantics.json`,不回落工具箱种子表;工具箱 `config/event-semantics.json` 只供 `cx-cli init` 首次复制。
|
|
53
|
+
|
|
54
|
+
若命令在 stderr 警告「工作区下日志源仍是本地文件」,说明机器级
|
|
55
|
+
`~/.config/cx-cli/toolkit.local.json` 或工具箱 `config/toolkit.local.json` 被自测配置污染,此时**结论会建立在
|
|
56
|
+
fixture 假数据上**:先让用户删掉那里的 `logSource`,再重跑。
|
|
57
|
+
|
|
58
|
+
## 2. 轻量场景:下载 project / 拉取历史
|
|
59
|
+
|
|
60
|
+
一条命令完成,落盘 `<projectHistoryDir>/<projectId>/<projectId>_<时间>.json`
|
|
61
|
+
(XML 自动转 JSON):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# 场景 1:下载 project(每项目最新一条快照)
|
|
65
|
+
cx-cli project pull 6345434
|
|
66
|
+
|
|
67
|
+
# 场景 2:拉取全量历史
|
|
68
|
+
cx-cli project pull 6345434 --history
|
|
69
|
+
|
|
70
|
+
# 多项目,各拉最新一条
|
|
71
|
+
cx-cli project pull 6345434 6351428
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
完成后向用户报告落盘路径与快照数量即可,**不要**顺手创建诊断 run。
|
|
75
|
+
|
|
76
|
+
## 3. 诊断主流程(分析客诉)
|
|
77
|
+
|
|
78
|
+
### 3.0 先拉数据,再建 run
|
|
79
|
+
|
|
80
|
+
`run new` 只读本地快照库。诊断前先刷新全量历史(diff 需要多版本):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cx-cli project pull <projectId> --history
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
DB 不可用而本地已有快照时可跳过此步,但须在结论中声明数据可能不新鲜。
|
|
87
|
+
若 `run new` 报「未找到本地快照」,按报错提示执行上面的 pull 命令。
|
|
88
|
+
|
|
89
|
+
`run new` 要抓 APM 日志并预计算全量 diff,历史版本多时可能跑几分钟,属正常,不要中途重试。
|
|
90
|
+
要收窄时间窗、换表或使用网页同款三列 OR,先执行 `cx-cli apm query … --out f`,再执行
|
|
91
|
+
`cx-cli run new --projectId <projectId> --logs f …`;`run new` 本身不增加这些过滤参数。
|
|
92
|
+
|
|
93
|
+
`--complaint` 照录客诉原文(工单描述或用户原话)。它会原样进 `report.md` 的「用户反馈」,你的判断写进
|
|
94
|
+
`hypothesis` / 结论,两边分开,读报告的人才能分清哪句是用户说的。
|
|
95
|
+
|
|
96
|
+
### 3.1 方法论
|
|
97
|
+
|
|
98
|
+
> **本节与 `docs/methodology.md` 同源,修改时两处同步。**
|
|
99
|
+
|
|
100
|
+
#### 诊断心智模型
|
|
101
|
+
|
|
102
|
+
编辑器问题排查的本质是**证据检索 + 假设检验**,不是凭直觉猜根因。
|
|
103
|
+
|
|
104
|
+
- 工具层负责整理事实:日志归一化、语义标注、规则信号、project diff;源码归因由你自带的检索/读取工具在宿主仓库里做。
|
|
105
|
+
- Agent 层负责提出假设、交叉验证、排序置信度。
|
|
106
|
+
- **结论只能建立在证据 ID 之上**(如 `log:s-1:42`、`diff:v1-v2:page2`、`src:src/editor/save.ts#L920`、`apm:query.error.20260829-120000.k3f9.json:7`)。没有证据支撑的断言只能作为假设记录,不能写入 `confirmed` 结论。
|
|
107
|
+
|
|
108
|
+
#### 标准流程
|
|
109
|
+
|
|
110
|
+
1. **`run new`**:创建 run,拉取日志与 project 快照,预计算 session、语义、规则信号、diff 索引与源码 commit 快照;读取 **case brief**。先看 brief 的 `logSource`,确认日志来自 APM 直拉还是 `--logs` 文件,以及有多少行匹配本项目;再拿 `logTimeRange` 对照客诉发生时段:盖不住,说明事发会话根本不在日志源里,此项直接记入 `missingEvidence`。要收窄时间窗、换表或使用网页同款三列 OR,先执行 `cx-cli apm query … --out f`,再执行 `cx-cli run new --projectId <projectId> --logs f …`;`run new` 本身不增加这些过滤参数。
|
|
111
|
+
2. **选调查路径**:根据 brief 中的可疑信号决定先查时间线、diff 还是源码。
|
|
112
|
+
3. **还原行为**:先 `sessions` 分人——用 `userIds` / `devices` / `startedAt` 对照工单里的客户账号、地区、设备,把客户本人的会话与客服/研发的复现会话分开;复现会话只能证明「现状」,证明不了「事发经过」。再用 `timeline` / `search-logs` 重建关键会话的操作时间线,要看 payload 取值时加 `--payload`。
|
|
113
|
+
4. **验证状态是否落盘**:用 `diff-project` 对比事发前后 project 快照。
|
|
114
|
+
5. **定位代码归因**:用你自带的文件检索/读取工具,在宿主仓库(`.cx-cli` 所在的编辑器源码仓库)里查埋点定义与业务逻辑;路径相对宿主仓库根写成 `src:<路径>#L<行>` 作为证据 ID。`source-versions.json` 显示宿主 checkout 在非发布分支或 `dirty` 时,关键行再对照事发日的发布分支(`git rev-list -1 --before='<事发日>' origin/<发布分支>` 取 commit,`git show <commit>:<路径>` 核对),结论里写明事发版本的该段逻辑是否一致。
|
|
115
|
+
6. **记录假设**:用 `hypothesis` 写入每个可检验推断。
|
|
116
|
+
7. **提交结论**:证据充分后 `finalize`;不足则保持 `likely` / `inconclusive`。
|
|
117
|
+
|
|
118
|
+
#### 证据纪律
|
|
119
|
+
|
|
120
|
+
- **`confirmed` 必须有证据引用**;校验失败时修正后重提。
|
|
121
|
+
- **证据不足时降级**为 `likely` / `inconclusive`,并列出 `missingEvidence`。
|
|
122
|
+
- **声明版本漂移**:源码 commit 与事发时间不一致时必须在结论中声明。
|
|
123
|
+
|
|
124
|
+
#### 输出预算
|
|
125
|
+
|
|
126
|
+
- 先用 `brief` + `sessions` 选出关键 session 与版本对,再 `timeline` / `diff-project` 逐个下钻。全部 session 时间线加全部相邻版本 diff 一次拉完会撑爆上下文(真实 case 里 6 个 session + 6 组 diff 就是 4 万字符)。
|
|
127
|
+
- 默认摘要 + 分页;见 `truncated: true` 时按 `hint` 下钻,不要盲目翻页。
|
|
128
|
+
- 完整 artifact 在 `runs/<runId>/artifacts/` 内读取。
|
|
129
|
+
|
|
130
|
+
#### 安全边界
|
|
131
|
+
|
|
132
|
+
- 只读业务数据;只写 `runs/<runId>/`。
|
|
133
|
+
- 不把 run 产物整包粘贴到外部系统;对外只输出结构化结论摘要。
|
|
134
|
+
- DB 凭据只放 `.env`(优先工作区 `.cx-cli/.env`);APM 网页端接口零凭据,配置文件不引用环境变量。绝不代填、不入库。
|
|
135
|
+
|
|
136
|
+
### 3.2 命令速查
|
|
137
|
+
|
|
138
|
+
所有命令支持 `--json`(稳定 JSON 输出)。在已 init 的编辑器源码仓库里无需 `--config`
|
|
139
|
+
(下表示例即按此写);示例统一使用 projectId `6345434`。
|
|
140
|
+
|
|
141
|
+
| 命令 | 用途 | 示例 |
|
|
142
|
+
|------|------|------|
|
|
143
|
+
| `project pull` | 拉取项目快照(唯一直连 DB 的命令) | `cx-cli project pull 6345434 --history` |
|
|
144
|
+
| `run new` | 创建 run + 预计算 | `cx-cli run new --projectId 6345434 --complaint "保存后重进数据丢失" --json` |
|
|
145
|
+
| `apm query / project --run` | 把诊断中的临时 APM 数据落进 run | `cx-cli apm query --type error --project 6345434 --from <事发日> --run <runId> --json`(行证据 `apm:<文件名>:<下标>`;`apm project 6345434 --run <runId>` 的整文件证据为 `apm:<文件名>`) |
|
|
146
|
+
| `brief` | 读取 case 摘要 | `cx-cli brief --run <runId> --json` |
|
|
147
|
+
| `sessions` | 列出 session(按 startedAt 升序,含 `userIds` / `devices` / `routes`) | `cx-cli sessions --run <runId> --json` |
|
|
148
|
+
| `timeline` | session 事件时间线(`--payload` 附带 payload 原文) | `cx-cli timeline --run <runId> --session <sessionId> --json` |
|
|
149
|
+
| `search-logs` | 跨 session 检索日志(`--payload` 同上) | `cx-cli search-logs --run <runId> --event saveProject --payload --json` |
|
|
150
|
+
| `snapshot` | 读取 project 快照 | `cx-cli snapshot --run <runId> --version v1 --detail summary --json` |
|
|
151
|
+
| `diff-project` | 对比两版本 | `cx-cli diff-project --run <runId> --before v1 --after v2 --json` |
|
|
152
|
+
| `hypothesis` | 记录假设 | `cx-cli hypothesis --run <runId> --file hypothesis.json --json` |
|
|
153
|
+
| `finalize` | 提交结论 | `cx-cli finalize --run <runId> --file conclusion.json --json` |
|
|
154
|
+
| `report` | 输出 report.md | `cx-cli report --run <runId> --json` |
|
|
155
|
+
|
|
156
|
+
退出码:`0` 成功 / `1` 业务失败 / `2` 参数错误。
|
|
157
|
+
|
|
158
|
+
`snapshot` / `diff-project` 的版本名 = 快照文件名去掉 `.json`,从 `brief` 输出的
|
|
159
|
+
`projectVersions` 里取(真实项目形如 `6478815_2026-07-16_20-19-24`,上表 `v1`/`v2` 为示意)。
|
|
160
|
+
|
|
161
|
+
**时间口径**——各来源的时间戳不在同一时区,跨来源比先后要先统一换成 epoch / UTC(`date -r <秒> -u`),并在结论里写明所用时区:
|
|
162
|
+
|
|
163
|
+
| 时间 | 时区 |
|
|
164
|
+
|------|------|
|
|
165
|
+
| 快照文件名里的 `<YYYY-MM-DD>_<HH-MM-SS>` | DB 记录 `CREATE_TIME`,DB 服务器时区(实测美西 UTC−7,数值比北京时间小 15 小时) |
|
|
166
|
+
| project JSON 的 `createdDate` / `updatedDate` | 写入方客户端的本地时间(德国客户是 CEST,国内客服改数据就是北京时间) |
|
|
167
|
+
| `images[].uploadTime`、元素 `lastModified` | epoch 毫秒,绝对时间,可作换算基准 |
|
|
168
|
+
| APM 日志 `logTime` / `sessions` 的 `startedAt` | 客户端本地钟(实测与 `received_time` 差数小时,也可能钟偏到未来);`received_time` 才是服务器钟,两钟中位差直接看 `brief` 的 `clockSkew` 提示(整小时 ≈ 时区差);`logTimestamp` 与 `search-logs --from/--to` 按本机时区解析 |
|
|
169
|
+
|
|
170
|
+
需要找回历史 run 时直接读 runs 目录:工作区模式下是宿主仓库根的 `.cx-cli/runs/`,
|
|
171
|
+
否则取 `toolkit.json` 的 `runsDir`(默认 `~/.config/cx-cli/runs/`)。
|
|
172
|
+
|
|
173
|
+
`brief` 的 `semanticsCoverage` 是本次 run 的待策展队列:`unknown` 是三级解析落底的事件名,
|
|
174
|
+
`inferred` 是靠事件名或 payload 形状兜底推断的(可能猜错类别,比 unknown 更危险)。同一事件名在两个
|
|
175
|
+
清单里各出现一次,说明它的解析结果随 payload 分叉。清单非空说明语义表没覆盖这些
|
|
176
|
+
埋点、规则引擎对它们近乎失明——要补表走 **semantics-curation skill**(离线策展:依源码与 payload
|
|
177
|
+
证据出提案 → 人审 → 写回工作区 `.cx-cli/event-semantics.json`),不要在诊断中途手改表。
|
|
178
|
+
|
|
179
|
+
### 3.3 结论 JSON 模板
|
|
180
|
+
|
|
181
|
+
将以下内容保存为 `conclusion.json`,把 `runId` 替换为当前 run,再执行 `finalize`:
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"projectId": "6345434",
|
|
186
|
+
"runId": "<runId>",
|
|
187
|
+
"status": "completed",
|
|
188
|
+
"diagnosisStatus": "likely",
|
|
189
|
+
"rootCauses": [
|
|
190
|
+
{
|
|
191
|
+
"description": "保存后重进读到旧版本",
|
|
192
|
+
"confidence": "likely",
|
|
193
|
+
"evidenceRefs": ["diff:v1-v2"]
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"confirmedFacts": [
|
|
197
|
+
{
|
|
198
|
+
"description": "v1→v2 project 快照存在几何字段差异",
|
|
199
|
+
"evidenceRefs": ["diff:v1-v2"]
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
"hypothesesRejected": [
|
|
203
|
+
{
|
|
204
|
+
"description": "自动保存被节流,用户以为已保存",
|
|
205
|
+
"reason": "日志中每次自动保存都有成功广播且版本号连续,节流未发生"
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"missingEvidence": [],
|
|
209
|
+
"recommendedNextActions": ["核对保存接口响应"],
|
|
210
|
+
"evidenceRefs": ["diff:v1-v2"]
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
`hypothesis.json` 单条示例(供 `hypothesis --file` 使用):
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"description": "自动保存被节流,用户以为已保存",
|
|
219
|
+
"confidence": "likely",
|
|
220
|
+
"evidenceRefs": ["log:s-1:1"],
|
|
221
|
+
"missingEvidence": ["保存接口 HTTP 响应"]
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 3.4 推荐调查顺序
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
PROJECT_ID=6345434 # 换成用户给的 projectId
|
|
229
|
+
|
|
230
|
+
# 0. 先刷新本地快照库
|
|
231
|
+
cx-cli project pull $PROJECT_ID --history
|
|
232
|
+
|
|
233
|
+
# 1. 创建 run(--complaint 照录客诉原文)
|
|
234
|
+
OUT=$(cx-cli run new --projectId $PROJECT_ID --complaint "保存丢失" --json)
|
|
235
|
+
RUN_ID=$(node -pe 'JSON.parse(process.argv[1]).runId' "$OUT")
|
|
236
|
+
|
|
237
|
+
# 2. 读 brief(核 logTimeRange 是否盖住事发时段)与 sessions(按 userIds/devices 分清客户与复现会话)
|
|
238
|
+
cx-cli brief --run $RUN_ID --json
|
|
239
|
+
cx-cli sessions --run $RUN_ID --json
|
|
240
|
+
|
|
241
|
+
# 3. 调查(SESSION 取 sessions 输出里客户本人的那条 sessionId)
|
|
242
|
+
SESSION=$(node -pe 'JSON.parse(process.argv[1]).sessions[0].sessionId' "$( cx-cli sessions --run $RUN_ID --json )")
|
|
243
|
+
cx-cli timeline --run $RUN_ID --session $SESSION --json
|
|
244
|
+
cx-cli search-logs --run $RUN_ID --event saveProject --payload --json # 要看 payload 取值时
|
|
245
|
+
cx-cli apm query --type error --project $PROJECT_ID --from <事发日> --run $RUN_ID --json # 可选:把前端报错落进 run 证据
|
|
246
|
+
# v1/v2 换成 brief 里的真实版本名
|
|
247
|
+
cx-cli diff-project --run $RUN_ID --before v1 --after v2 --json
|
|
248
|
+
# 需要看源码时用你自带的检索/读取工具,直接在当前仓库里查
|
|
249
|
+
|
|
250
|
+
# 4. 写 conclusion.json 后 finalize
|
|
251
|
+
cx-cli finalize --run $RUN_ID --file conclusion.json --json
|
|
252
|
+
cx-cli report --run $RUN_ID --json
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
产物目录:工作区模式下是 `.cx-cli/runs/<runId>/`(含 `trace.jsonl`、`result.json`、`report.md`)。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Codex / ChatGPT 桌面端的可选元数据(Claude Code 忽略本文件)。
|
|
2
|
+
# 字段集见 https://learn.chatgpt.com/docs/build-skills 的 Optional metadata。
|
|
3
|
+
# 未声明 icon_small / icon_large:仓库不放图标资源,Codex CLI 也不渲染图标。
|
|
4
|
+
# 未声明 dependencies.tools:cx-cli 是本机全局命令,不是 MCP server,装法走 cx-cli-setup。
|
|
5
|
+
interface:
|
|
6
|
+
display_name: "编辑器诊断(cx-cli)"
|
|
7
|
+
short_description: "拉取编辑器 project 快照与历史,按证据 ID 诊断保存丢失一类客诉"
|
|
8
|
+
brand_color: "#2F6FEB"
|
|
9
|
+
default_prompt: "帮我诊断这个编辑器客诉:projectId = <projectId>,现象是 <用户描述>"
|
|
10
|
+
|
|
11
|
+
policy:
|
|
12
|
+
# 默认即 true,这里显式声明:客诉类请求必须能按 description 隐式命中
|
|
13
|
+
allow_implicit_invocation: true
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: semantics-curation
|
|
3
|
+
description: >-
|
|
4
|
+
策展编辑器事件语义表 .cx-cli/event-semantics.json。
|
|
5
|
+
当 brief 的 semanticsCoverage 出现 unknown / inferred,
|
|
6
|
+
用户说「补语义表」「这些事件没语义」「unknown 太多」「策展」,
|
|
7
|
+
或现有条目与源码/payload 证据冲突时使用。离线维护流程,不是诊断流程。
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# 语义表策展(semantics-curation)
|
|
11
|
+
|
|
12
|
+
这是离线维护流程,不是诊断流程。运行时解析不调用 LLM;策展只为编辑器宿主仓库的工作区语义表产出可审、可追溯的条目。日常问题诊断走 `editor-diagnostic` skill。
|
|
13
|
+
|
|
14
|
+
## 前提与边界
|
|
15
|
+
|
|
16
|
+
- 当前 cwd 必须在已执行 `cx-cli init` 的**编辑器源码仓库**内,并存在 `.cx-cli/event-semantics.json`。否则先用 `cx-cli-setup` skill;不要向工具箱种子表写入宿主专属结论。
|
|
17
|
+
- 生产表是 `.cx-cli/event-semantics.json`,每个宿主仓库独立演进。工具箱 `config/event-semantics.json` 只用于 init 的种子;fixture 表、其他工作区和历史 run 不是镜像,均不随手同步。
|
|
18
|
+
- 不改运行时解析逻辑、诊断规则或 run 产物。新增条目只影响后续 `run new`,不会重算历史 run。
|
|
19
|
+
|
|
20
|
+
## 1. 取得待策展事件
|
|
21
|
+
|
|
22
|
+
从 run 的覆盖统计读取队列:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cx-cli brief --run <runId> --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
读取 `semanticsCoverage`:
|
|
29
|
+
|
|
30
|
+
| 字段 | 含义与处置 |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `unknown[]` | 三级解析落底;规则引擎对其近乎失明。 |
|
|
33
|
+
| `inferred[]` | 事件名或 payload 形状(如 `elementId` / `sheetIndex`)兜底推断命中,可能猜错类别;优先级高于 unknown。 |
|
|
34
|
+
| `explicitEventCount` | 已命中显式表的去重事件数,不是策展对象。 |
|
|
35
|
+
|
|
36
|
+
`semanticsCoverage` 只为 `unknown[]` 与 `inferred[]` 列出事件明细;显式命中的事件只有
|
|
37
|
+
`explicitEventCount`,不会出现在待策展队列。队列项为 `{ eventName, count, category, payloadKeys }`。
|
|
38
|
+
`category` 是当前实际解析类别;inferred 项带它意味着该推断有误分级风险。
|
|
39
|
+
|
|
40
|
+
覆盖统计按 `(事件名, 解析来源)` 分桶,**同一事件名可能同时出现在 `inferred[]` 与 `unknown[]`**:
|
|
41
|
+
它不是两个事件,而是同一埋点在不同 payload 下解析结果分叉(例如带 `elementId` 时被推断成 mutation、
|
|
42
|
+
不带时落 unknown)。遇到这种分叉,两条的 `payloadKeys` 要合起来看,条目按最坏情况定;
|
|
43
|
+
只盯其中一条会漏掉该事件的另一半形态。同理,单条的 `count` 不是该事件在本次 run 的总次数。
|
|
44
|
+
|
|
45
|
+
用户可直接指定事件名跳过本步骤;若该事件已显式命中,先从 `.cx-cli/event-semantics.json` 读取现行条目,
|
|
46
|
+
再收集 source / log 证据,而不是期待它出现在 `semanticsCoverage`。
|
|
47
|
+
|
|
48
|
+
## 2. 逐事件收集证据
|
|
49
|
+
|
|
50
|
+
优先在宿主源码中用 Grep / Read 查事件名及其调用上下文;CLI 不代查源码。宿主常有两套埋点管线,同一动作也可能各发一个真实事件:
|
|
51
|
+
|
|
52
|
+
- `window.logger?.track('xxx', ...)`:camelCase,通常是 APM 日志来源;
|
|
53
|
+
- `window.logEvent.addPageEvent('Xxx', ...)`:老管线,常用 PascalCase 或 `Click_` 前缀。
|
|
54
|
+
|
|
55
|
+
因此 `saveProject` 与 `SaveProject` 一类大小写双胞胎不能合并。真实 payload 可从 `<workspace>/runs/<runId>/artifacts/logs.normalized.json` 读取,或查询:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cx-cli search-logs --run <runId> --event <事件名> --json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
提案中使用稳定证据 ID:源码为 `src:<相对宿主仓库根的路径>#L<行号>`,日志为 `log:<sessionId>:<originalIndex>`。不要把证据、`confidence` 或 `note` 字段写入语义表 JSON;证据属于提案文件。
|
|
62
|
+
|
|
63
|
+
## 3. 证据门槛与保守归类
|
|
64
|
+
|
|
65
|
+
| 风险 | 判据 | 最低门槛 |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| 高 | `stateChange` 为 `definite` 或 `commit`,或 `category` 为 `persistence` / `error` | **每个条目必须附至少一条 `src:` 源码证据**。 |
|
|
68
|
+
| 低 | `category` 为 `workflow` / `navigation` 且 `stateChange: none` | 可仅依 payload 与命名提出,不强制源码证据。 |
|
|
69
|
+
| 中间 | 例如 `mutation` + `possible` | 按高风险处理。 |
|
|
70
|
+
|
|
71
|
+
低风险不得伪造源码锚点;高风险也不能因名字、payload 或时间压力省略源码。若同名事件在不同调用点语义冲突,不要硬塞强断言:降级 `stateChange`,或在提案中记录冲突并留待人审裁决。
|
|
72
|
+
|
|
73
|
+
## 4. 创建一批提案
|
|
74
|
+
|
|
75
|
+
创建 `.cx-cli/curation/YYYY-MM-DD-<批次slug>.md`(目录不存在时创建)。一批策展对应一个文件和一个提交边界,不追加到旧清单。提案文件头必须有来源 runId、摘要表和批次状态;每个事件一节。
|
|
76
|
+
|
|
77
|
+
````markdown
|
|
78
|
+
# 语义提案:2026-08-21 首批策展
|
|
79
|
+
|
|
80
|
+
**队列来源**:run `r-20260821-134121-l7s5` 的 semanticsCoverage
|
|
81
|
+
**批次状态**:待审
|
|
82
|
+
|
|
83
|
+
## 摘要
|
|
84
|
+
|
|
85
|
+
| # | 事件名 | 操作 | 风险 | 审定 |
|
|
86
|
+
|---|---|---|---|---|
|
|
87
|
+
| 1 | `selectBottomTab` | 新增 | 低 | 待审 |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 1. `selectBottomTab` — 新增 · 低风险
|
|
92
|
+
|
|
93
|
+
**风险级别**:低(navigation + stateChange: none → 允许仅凭 payload 与命名)
|
|
94
|
+
**审定**:待审
|
|
95
|
+
|
|
96
|
+
**证据**:
|
|
97
|
+
|
|
98
|
+
- log:1aaec11c-...:10 — payload `{ "tab": "Layouts" }`,会话内底部面板切换
|
|
99
|
+
- 频次:本次 run 370 次,payload 恒为单键 `tab`
|
|
100
|
+
|
|
101
|
+
**推理**:与现表 `ChangeTab` 同族——会话内面板导航,payload 无状态变更迹象。
|
|
102
|
+
|
|
103
|
+
**提案条目**:
|
|
104
|
+
|
|
105
|
+
```jsonc
|
|
106
|
+
"selectBottomTab": {
|
|
107
|
+
"category": "navigation",
|
|
108
|
+
"action": "select_bottom_tab",
|
|
109
|
+
"entityType": "session",
|
|
110
|
+
"stateChange": "none",
|
|
111
|
+
"tags": ["panel_navigation"]
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
````
|
|
115
|
+
|
|
116
|
+
修改既有条目时,本节须以“现行条目 / 提案条目”逐字段对照,并在注释中说明修改理由。删除条目时,写明联动项:例如工具箱共享校验的空白键白名单是否可收缩;它属于工具箱侧的另一个变更,且收缩前必须确认没有其他宿主工作区表仍持有该键。
|
|
117
|
+
|
|
118
|
+
## 5. 人审与提交边界
|
|
119
|
+
|
|
120
|
+
把摘要和每节提案交用户逐条审阅,并把每项“审定”从 `待审` 更新为 `通过`、`改后通过` 或 `否决`。否决项仍保留在提案中,作为该项的出处记录;表内不保存 provenance 字段。
|
|
121
|
+
|
|
122
|
+
审定前绝不写 `.cx-cli/event-semantics.json`,也不提交提案;待审提案留在工作树供人审。审定结果写回
|
|
123
|
+
提案后,这一批只提交一次:
|
|
124
|
+
|
|
125
|
+
- 有 `通过` 或 `改后通过` 项时,语义表与本批提案文件在**同一 commit** 提交;
|
|
126
|
+
- 全部 `否决` 时,只提交最终提案文件,作为该批唯一 commit。
|
|
127
|
+
|
|
128
|
+
不要借此写入任何未通过表项,也不得让同一批提案跨两个 commit。
|
|
129
|
+
|
|
130
|
+
## 6. 落表与验证
|
|
131
|
+
|
|
132
|
+
仅把通过或改后通过的条目写进工作区表。每项仅使用共享 schema 允许的字段:
|
|
133
|
+
|
|
134
|
+
- 必填:`category`、`action`、`entityType`、`stateChange`、`tags`;
|
|
135
|
+
- `category: lifecycle` 当且仅当存在 `lifecycleStage`(`enter` / `leave`);
|
|
136
|
+
- `category: persistence` 当且仅当存在 `persistenceStage: save`;
|
|
137
|
+
- 其他未知字段会被严格校验拒绝,尤其不要写 `confidence`、`evidence`、`note` 或包装成 `{ eventName: ... }` 的对象。
|
|
138
|
+
|
|
139
|
+
值域、事件名空白规则和大小写冲突登记以 `packages/core/src/semantics/table-schema.ts` 的共享校验为准。落表后运行任一读表命令:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
cx-cli brief --run <runId> --json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
若报“未通过校验”,按错误点名的键和规则修正,不要绕过。必要时重新 `run new` 检查新条目是否命中。
|
|
146
|
+
|
|
147
|
+
## 常见坑
|
|
148
|
+
|
|
149
|
+
- 尾部带空格的事件名(如 `"addVarnishingText "`)可能是宿主真实埋点笔误;运行时精确匹配。源码未修复前不能去掉。
|
|
150
|
+
- payload 含 `message` / `stack` 的事件可能被解析器补为 `error`,但仍是 unknown,通常应优先策展。
|
|
151
|
+
- 名称相近、大小写不同或不同管线的事件不是自动同义词;分别收集证据。
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Codex / ChatGPT 桌面端的可选元数据(Claude Code 忽略本文件)。
|
|
2
|
+
# 字段集见 https://learn.chatgpt.com/docs/build-skills 的 Optional metadata。
|
|
3
|
+
interface:
|
|
4
|
+
display_name: "事件语义表策展"
|
|
5
|
+
short_description: "为 unknown / inferred 埋点出可审提案,人审通过后写回工作区语义表"
|
|
6
|
+
brand_color: "#2F6FEB"
|
|
7
|
+
default_prompt: "根据 run <runId> 的 semanticsCoverage 策展一批事件语义提案,先出提案给我审"
|
|
8
|
+
|
|
9
|
+
policy:
|
|
10
|
+
# 默认即 true:brief 里 unknown / inferred 堆积时应能被隐式命中;
|
|
11
|
+
# 写表与提交仍受 SKILL.md 的人审门槛约束,不会因隐式触发而跳过。
|
|
12
|
+
allow_implicit_invocation: true
|