markstar 1.0.0 → 1.1.1
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/README.md
CHANGED
|
@@ -15,6 +15,7 @@ npx markstar
|
|
|
15
15
|
| 技能 | 命令 | 说明 |
|
|
16
16
|
|------|------|------|
|
|
17
17
|
| **data-to-chart** | `/data-to-chart` | 智能图表生成,自动选择 ECharts 图表类型并生成可交互 HTML。支持大屏/仪表盘模式。 |
|
|
18
|
+
| **maven-pilot** | `/maven-pilot` | Maven 依赖冲突检测与自动修复。check 只检测,fix 检测+修复,也支持自然语言对话。零第三方依赖。 |
|
|
18
19
|
|
|
19
20
|
## 卸载
|
|
20
21
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markstar",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=16.0.0"
|
|
6
6
|
},
|
|
7
|
-
"description": "MarkStar — AI 编程技能集合。智能图表生成(data-to-chart)等 Claude Code skills,一行 npx 安装",
|
|
7
|
+
"description": "MarkStar — AI 编程技能集合。智能图表生成(data-to-chart)、Maven 依赖冲突检测与修复(maven-pilot)等 Claude Code skills,一行 npx 安装",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"bin": {
|
|
10
10
|
"markstar": "bin/markstar.js"
|
|
@@ -22,7 +22,13 @@
|
|
|
22
22
|
"visualization",
|
|
23
23
|
"dashboard",
|
|
24
24
|
"data-to-chart",
|
|
25
|
-
"data-viz"
|
|
25
|
+
"data-viz",
|
|
26
|
+
"maven",
|
|
27
|
+
"dependency-management",
|
|
28
|
+
"conflict-detection",
|
|
29
|
+
"auto-fix",
|
|
30
|
+
"pom.xml",
|
|
31
|
+
"java"
|
|
26
32
|
],
|
|
27
33
|
"repository": {
|
|
28
34
|
"type": "git",
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: maven-pilot
|
|
3
|
+
description: Maven 依赖冲突检测与自动修复。检测当前项目的依赖版本冲突,AI 分析冲突影响和修复方案,用户确认后自动修改 pom.xml。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# maven-pilot — Maven 依赖冲突检测与自动修复
|
|
7
|
+
|
|
8
|
+
在 Claude Code 中一行命令检测并修复 Maven 依赖版本冲突。不依赖第三方插件,仅使用 Maven 内置的 `dependency:tree`。
|
|
9
|
+
|
|
10
|
+
## 核心原则
|
|
11
|
+
|
|
12
|
+
- **安全优先**:不升级大版本、不改源代码、diff 预览 + 用户确认后才 apply
|
|
13
|
+
- **零依赖**:仅需 `mvn`,不需要额外 Maven 插件
|
|
14
|
+
|
|
15
|
+
## 执行流程
|
|
16
|
+
|
|
17
|
+
### 入口路由
|
|
18
|
+
|
|
19
|
+
收到用户输入 `args` 后,按优先级依次判断:
|
|
20
|
+
|
|
21
|
+
**分支 1:精确匹配 check**
|
|
22
|
+
- args 完全等于 `check`
|
|
23
|
+
- 只检测不修复
|
|
24
|
+
|
|
25
|
+
**分支 2:精确匹配 fix**
|
|
26
|
+
- args 完全等于 `fix`
|
|
27
|
+
- 检测 + 修复全量冲突
|
|
28
|
+
|
|
29
|
+
**分支 3:自然语言或无参数**
|
|
30
|
+
- args 为空,或不为 check/fix
|
|
31
|
+
- AI 从自然语言识别意图:
|
|
32
|
+
- 包含"检查/检测/看看/有没有/扫描"等 → 走 Check 流程
|
|
33
|
+
- 包含"修/修复/解决/处理/改"等 → 走 Fix 流程
|
|
34
|
+
- 指定某个依赖("跳过 guava""只修 logback")→ 记录排除/包含规则
|
|
35
|
+
- 其他 → 默认走 Check 流程
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### Check 流程(检测 + 分析)
|
|
40
|
+
|
|
41
|
+
#### Step 1: 环境检测
|
|
42
|
+
|
|
43
|
+
1. 从当前目录逐级向上查找 `pom.xml`(最多 5 级)
|
|
44
|
+
2. 运行 `mvn --version` 确认 Maven 可用
|
|
45
|
+
|
|
46
|
+
任一条件不满足 → 输出错误信息并停止:
|
|
47
|
+
- "未在当前目录或其父目录中找到 pom.xml"
|
|
48
|
+
- "Maven (mvn) 未安装或不在 PATH 中"
|
|
49
|
+
|
|
50
|
+
#### Step 2: 运行 dependency:tree
|
|
51
|
+
|
|
52
|
+
1. **首次尝试**:先执行 `mvn dependency:tree -Dverbose`,捕获 stdout
|
|
53
|
+
- 如果成功输出且包含 `omitted for conflict` 或 `version managed from` 标记,继续
|
|
54
|
+
- 如果命令失败或输出中无冲突标记,回退
|
|
55
|
+
2. **回退**:执行 `mvn dependency:tree`,捕获 stdout
|
|
56
|
+
3. **非 verbose 输出解析**(dependency-plugin 3.x 无冲突标记时):
|
|
57
|
+
- 遍历树中每个 `groupId:artifactId:version` 出现
|
|
58
|
+
- 对每个 groupId:artifactId,记录(树深度, 版本)对
|
|
59
|
+
- 当同一 groupId:artifactId 在树中出现 N≥2 次时,版本差异即冲突
|
|
60
|
+
- 按 Maven 最短路径规则判定获胜版本(深度最小者;同深度先声明者获胜)
|
|
61
|
+
- 对每个可疑冲突,用 `mvn dependency:tree -Dincludes=<groupId>:<artifactId>` 验证实际使用版本
|
|
62
|
+
4. 参考 `reference/dependency-tree-output.md` 了解输出格式
|
|
63
|
+
|
|
64
|
+
#### Step 3: AI 分析冲突
|
|
65
|
+
|
|
66
|
+
扫描输出,识别所有冲突条目:
|
|
67
|
+
|
|
68
|
+
**识别冲突标记:**
|
|
69
|
+
- `(omitted for conflict with X.X.X)` — 此版本被跳过,选择了 X.X.X
|
|
70
|
+
- `(version managed from X.X.X)` — 被 dependencyManagement 管理
|
|
71
|
+
|
|
72
|
+
**对每个冲突构建分析信息:**
|
|
73
|
+
- `groupId:artifactId`(依赖标识)
|
|
74
|
+
- 冲突的版本列表
|
|
75
|
+
- 每个版本由谁引入(从树缩进推断传递路径)
|
|
76
|
+
- 当前运行时使用的版本(即获胜版本)
|
|
77
|
+
- 推荐保留版本 + 理由
|
|
78
|
+
|
|
79
|
+
**输出格式示例:**
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
发现 2 个依赖冲突:
|
|
83
|
+
|
|
84
|
+
1. com.google.guava:guava
|
|
85
|
+
- 30.1-jre ← (当前使用,由 my-app → A → guava 30.1 引入)
|
|
86
|
+
- 32.0.1-jre ← (由 my-app → spring-boot → guava 32.0 引入)
|
|
87
|
+
- 建议:锁定 30.1-jre(当前运行版本,API 兼容)
|
|
88
|
+
- 影响:低风险
|
|
89
|
+
|
|
90
|
+
2. ch.qos.logback:logback-classic
|
|
91
|
+
- 1.2.11 ← (当前使用,由 my-app → A → logback 1.2.11 引入)
|
|
92
|
+
- 1.4.14 ← (由 my-app → spring-boot → logback 1.4.14 引入)
|
|
93
|
+
- 建议:锁定 1.4.14(包含安全修复,1.4.x 兼容 1.2.x)
|
|
94
|
+
- 影响:低风险
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### Fix 流程(在前面的 Check 流程基础上)
|
|
100
|
+
|
|
101
|
+
#### Step 4: 修复冲突
|
|
102
|
+
|
|
103
|
+
1. **为每个冲突生成 pom.xml 修改方案:**
|
|
104
|
+
|
|
105
|
+
**类型 A:在 `<dependencyManagement>` 中锁定版本**
|
|
106
|
+
- 检查 pom.xml 中是否已有 `<dependencyManagement>`
|
|
107
|
+
- 有 → 在现有 `<dependencies>` 中追加 `<dependency><groupId/><artifactId/><version/></dependency>`
|
|
108
|
+
- 无 → 在 `<project>` 下创建 `<dependencyManagement><dependencies>...</dependencies></dependencyManagement>`
|
|
109
|
+
- **必须遵守的安全约束:**
|
|
110
|
+
- 不修改 `<dependencies>` 中已声明的 `<version>`
|
|
111
|
+
- 不修改 Java 源文件
|
|
112
|
+
- 锁定当前 Maven 实际使用的版本(除非有 CVE)
|
|
113
|
+
- 有 CVE 时才升级到同一小版本线的安全补丁版本
|
|
114
|
+
|
|
115
|
+
**类型 B:添加 `<exclusion>`**
|
|
116
|
+
- 在引入旧/多余版本的依赖上添加 `<exclusions><exclusion><groupId/><artifactId/></exclusion></exclusions>`
|
|
117
|
+
|
|
118
|
+
2. **生成 unified diff 展示给用户:**
|
|
119
|
+
|
|
120
|
+
```diff
|
|
121
|
+
+ <dependencyManagement>
|
|
122
|
+
+ <dependencies>
|
|
123
|
+
+ <dependency>
|
|
124
|
+
+ <groupId>com.google.guava</groupId>
|
|
125
|
+
+ <artifactId>guava</artifactId>
|
|
126
|
+
+ <version>30.1-jre</version>
|
|
127
|
+
+ </dependency>
|
|
128
|
+
+ </dependencies>
|
|
129
|
+
+ </dependencyManagement>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
3. **等待用户确认:** "以上是 pom.xml 的修改方案,确认 apply 吗?(yes/no)"
|
|
133
|
+
4. **用户确认后** → 使用 Edit 工具修改 pom.xml
|
|
134
|
+
5. **用户拒绝** → "修复已取消,未做任何修改"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Maven 依赖冲突解决策略
|
|
2
|
+
|
|
3
|
+
## 冲突来源
|
|
4
|
+
|
|
5
|
+
| 冲突类型 | 后果 | 示例 |
|
|
6
|
+
|---------|------|------|
|
|
7
|
+
| 版本冲突 | NoSuchMethodError | Guava 30.1 vs 32.0 |
|
|
8
|
+
| 重复依赖 | 冗余、潜在冲突 | 同一 jar 被多次声明 |
|
|
9
|
+
| 作用域冲突 | ClassNotFoundException | compile vs provided |
|
|
10
|
+
|
|
11
|
+
## 解决方案
|
|
12
|
+
|
|
13
|
+
### 方案 A:在 `<dependencyManagement>` 中锁定版本
|
|
14
|
+
|
|
15
|
+
```xml
|
|
16
|
+
<dependencyManagement>
|
|
17
|
+
<dependencies>
|
|
18
|
+
<dependency>
|
|
19
|
+
<groupId>com.google.guava</groupId>
|
|
20
|
+
<artifactId>guava</artifactId>
|
|
21
|
+
<version>32.0.1-jre</version>
|
|
22
|
+
</dependency>
|
|
23
|
+
</dependencies>
|
|
24
|
+
</dependencyManagement>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**何时用:** 父 pom 可对所有子模块统一控制版本。如果父 pom 没有 `<dependencyManagement>`,直接创建。
|
|
28
|
+
|
|
29
|
+
### 方案 B:使用 `<exclusion>` 排除传递依赖
|
|
30
|
+
|
|
31
|
+
```xml
|
|
32
|
+
<dependency>
|
|
33
|
+
<groupId>org.example</groupId>
|
|
34
|
+
<artifactId>example-lib</artifactId>
|
|
35
|
+
<exclusions>
|
|
36
|
+
<exclusion>
|
|
37
|
+
<groupId>com.google.guava</groupId>
|
|
38
|
+
<artifactId>guava</artifactId>
|
|
39
|
+
</exclusion>
|
|
40
|
+
</exclusions>
|
|
41
|
+
</dependency>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**何时用:** 某个依赖带入了不需要的旧版本,而其他路径已经有新版本时。
|
|
45
|
+
|
|
46
|
+
**scope 注意**:排除 `provided` 或 `test` scope 的传递依赖有风险——这些依赖仍出现在编译/测试类路径上,排除可能导致 ClassNotFoundException。对 provided/test scope 的冲突,优先用 dependencyManagement 锁定版本,而非 exclusion。
|
|
47
|
+
|
|
48
|
+
## 修复安全约束(硬性规则)
|
|
49
|
+
|
|
50
|
+
1. **优先锁定当前使用的版本** — 选择 Maven 最短路径获胜的版本(即实际运行中的版本)
|
|
51
|
+
2. **不改变原代码** — 不改 `<dependencies>` 中已声明的版本号,不改 Java 源文件
|
|
52
|
+
3. **安全例外** — 仅当前版本有已知高危 CVE 时,升级到同一小版本线的安全补丁
|
|
53
|
+
4. **仅做排除** — 不动功能代码
|
|
54
|
+
5. **用户确认** — 所有修改先展示 diff,用户确认后才 apply
|
|
55
|
+
|
|
56
|
+
## 根据错误信息判断冲突
|
|
57
|
+
|
|
58
|
+
| 错误 | 原因 |
|
|
59
|
+
|------|------|
|
|
60
|
+
| NoSuchMethodError | 方法不存在于当前版本的 jar 中 |
|
|
61
|
+
| ClassNotFoundException | 整个类都不存在 |
|
|
62
|
+
| AbstractMethodError | 接口新增了方法但 jar 里的类没实现 |
|
|
63
|
+
| ClassCastException | 同一个类来自两个不同的 jar |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Maven dependency:tree 输出参考
|
|
2
|
+
|
|
3
|
+
## 基本命令
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# 检测当前项目的依赖树(含冲突标记 — maven-dependency-plugin 2.x)
|
|
7
|
+
mvn dependency:tree -Dverbose
|
|
8
|
+
|
|
9
|
+
# 如果 -Dverbose 不支持(3.x 已移除),回退到:
|
|
10
|
+
mvn dependency:tree
|
|
11
|
+
|
|
12
|
+
# 查看特定依赖
|
|
13
|
+
mvn dependency:tree -Dincludes=com.google.guava:*
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 输出格式
|
|
17
|
+
|
|
18
|
+
### 带 -Dverbose(2.x 版本)
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
[INFO] com.example:my-app:jar:1.0.0
|
|
22
|
+
[INFO] +- com.google.guava:guava:jar:30.1-jre:compile
|
|
23
|
+
[INFO] | \- org.checkerframework:checker-qual:jar:3.21.0:compile
|
|
24
|
+
[INFO] \- org.springframework.boot:spring-boot-starter:jar:3.2.0:compile
|
|
25
|
+
[INFO] \- com.google.guava:guava:jar:32.0.1-jre:compile (omitted for conflict with 30.1-jre)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
关键标记说明:
|
|
29
|
+
- `(omitted for conflict with X)` — 该版本因冲突被跳过。后面是被选中的版本
|
|
30
|
+
- `(version managed from X)` — 该版本被 `<dependencyManagement>` 覆盖
|
|
31
|
+
- `(omitted for duplicate)` — 同一版本被多次引入,只保留一个
|
|
32
|
+
|
|
33
|
+
### 不带 -Dverbose(3.x 版本)
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
[INFO] com.example:my-app:jar:1.0.0
|
|
37
|
+
[INFO] +- com.google.guava:guava:jar:30.1-jre:compile
|
|
38
|
+
[INFO] \- org.springframework.boot:spring-boot-starter:jar:3.2.0:compile
|
|
39
|
+
[INFO] \- com.google.guava:guava:jar:32.0.1-jre:compile
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
3.x 版本默认不显示冲突标记。此时需要按以下步骤推断冲突:
|
|
43
|
+
|
|
44
|
+
1. **遍历所有 `groupId:artifactId:version` 出现**,记录每个出现的树深度(`+-` 缩进层级)和版本号
|
|
45
|
+
2. **发现重复 groupId:artifactId**:当同一 groupId:artifactId 在树中出现 ≥2 次且版本不同 → 即冲突
|
|
46
|
+
3. **判定获胜版本**:按 Maven 最短路径规则
|
|
47
|
+
- 深度小的获胜(根 pom 直接依赖深度=1,传递依赖深度≥2)
|
|
48
|
+
- 同深度时,先声明的获胜(xml 顺序)
|
|
49
|
+
4. **验证**:用 `mvn dependency:tree -Dincludes=<groupId>:<artifactId>` 确认实际使用版本
|
|
50
|
+
|
|
51
|
+
### 冲突检测规则
|
|
52
|
+
|
|
53
|
+
Maven 的"最短路径获胜"规则:
|
|
54
|
+
- 根 pom 的依赖深度 = 1
|
|
55
|
+
- 传递依赖深度 = 2+
|
|
56
|
+
- 同深度的先声明者获胜
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
根 pom (my-app)
|
|
60
|
+
│
|
|
61
|
+
├─ A → Guava 30.1 (深度 2)
|
|
62
|
+
│
|
|
63
|
+
└─ B → C → Guava 32.0 (深度 3)
|
|
64
|
+
|
|
65
|
+
结果:Guava 30.1 获胜(深度 2 < 深度 3)
|
|
66
|
+
```
|