aig-mcp-server 1.0.2 → 1.2.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/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # aig-mcp-server
2
+
3
+ > **让 AI 编程助手在修改代码时,像专业工程师一样管理 Git 记录。**
4
+
5
+ 配置此 MCP Server 后,AI 会在每次修改代码前自动存档,出错时一键回滚,任务完成后将碎片提交压缩为整洁的正式记录。
6
+
7
+ ## 工具一览
8
+
9
+ | 工具 | 时机 | 作用 |
10
+ | ------------ | ---------- | --------------------------------------- |
11
+ | `aig_status` | 任意时刻 | 查看当前 Git 状态快照 |
12
+ | `aig_save` | 每次修改前 | 创建 Git Checkpoint |
13
+ | `aig_undo` | 修改报错时 | 回滚到上一个 Checkpoint |
14
+ | `aig_squash` | 任务完成时 | 将碎片 Checkpoint 压缩为一个正式 Commit |
15
+
16
+ ---
17
+
18
+ ## 工具详情
19
+
20
+ ### `aig_status` — 状态快照
21
+
22
+ 在操作前调用,帮助 AI 了解当前 Git 状态,避免盲目操作。
23
+
24
+ **返回内容:** 当前分支、未提交文件列表、待合并 Checkpoint 数量、最近 5 条提交记录。
25
+
26
+ ---
27
+
28
+ ### `aig_save` — 碎片存档
29
+
30
+ 在每一步修改代码**前**调用,创建可回溯的 Checkpoint。
31
+
32
+ | 参数 | 类型 | 必填 | 说明 |
33
+ | --------- | ------ | ---- | ---------------------- |
34
+ | `message` | string | ✅ | 简述接下来要修改的内容 |
35
+
36
+ ```
37
+ ✅ 存档成功!记录: 🤖 [AI Checkpoint] 重构登录逻辑 (10:30:00)
38
+ ⚠️ 工作区无任何变更,跳过本次存档。 ← 空提交保护
39
+ ```
40
+
41
+ ---
42
+
43
+ ### `aig_undo` — 回滚
44
+
45
+ 代码修改失败或需要撤销时调用,支持多步回滚。
46
+
47
+ | 参数 | 类型 | 必填 | 说明 |
48
+ | ------- | ------ | ---- | ------------------------- |
49
+ | `steps` | number | ❌ | 回滚步数,默认 1,最大 20 |
50
+
51
+ ```
52
+ ⏪ 已回滚 2 步!所有相关修改已撤销。
53
+ ```
54
+
55
+ ---
56
+
57
+ ### `aig_squash` — 压缩收尾
58
+
59
+ 任务完成后调用,自动统计连续 AI Checkpoint 数量并软回滚压缩为一条整洁的正式 Commit。
60
+
61
+ **建议先用 `preview: true` 确认,再正式执行。**
62
+
63
+ | 参数 | 类型 | 必填 | 说明 |
64
+ | --------- | ------- | ---- | -------------------------------------- |
65
+ | `summary` | string | ✅ | 正式提交总结,如:`feat: 重构登录模块` |
66
+ | `preview` | boolean | ❌ | `true` 仅预览不执行,默认 `false` |
67
+
68
+ ```
69
+ # preview: true
70
+ 🔍 预览:以下 3 个 AI Checkpoint 将被压缩合并为:
71
+ "✨ feat: 拆分 Vue 组件并增加 TS 类型"
72
+ 1. a1b2c3d 🤖 [AI Checkpoint] 拆分组件
73
+ 2. d4e5f6a 🤖 [AI Checkpoint] 增加 TS 类型
74
+ 3. 7g8h9i0 🤖 [AI Checkpoint] 调整样式
75
+
76
+ # preview: false(正式执行)
77
+ 🎉 完美收官!已将 3 个 AI 碎片存档压缩合并为 1 个正式提交:
78
+ "✨ feat: 拆分 Vue 组件并增加 TS 类型"
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 安装配置
84
+
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "aig-mcp-server": {
89
+ "command": "npx",
90
+ "args": ["-y", "aig-mcp-server"]
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ > **前提条件:** 项目目录必须是 Git 仓库(已执行 `git init`)
97
+
98
+ ---
99
+
100
+ ## 让 AI 自动遵守工作流
101
+
102
+ 在项目中创建规则文件,AI 编辑器读取后会自动遵守 3 阶段工作流。
103
+
104
+ **文件路径(按编辑器选择):**
105
+
106
+ - Claude Desktop → `CLAUDE.md`
107
+ - Cursor → `.cursor/rules/aig.mdc`
108
+
109
+ **文件内容:**
110
+
111
+ ```markdown
112
+ # Agent 核心防腐与交付规则
113
+
114
+ 当你为我开发功能或重构代码时,必须严格遵守以下 Git 工作流:
115
+
116
+ 1. **开始任务前:** 调用 `aig_status` 了解当前状态。
117
+ 2. **每步修改前:** 主动调用 `aig_save` 进行临时存档。
118
+ 3. **代码报错时:** 立即调用 `aig_undo` 回滚。
119
+ 4. **任务完成时:** 先调用 `aig_squash(preview:true)` 预览,确认后再调用 `aig_squash(preview:false)` 压缩提交。
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 完整工作流示例
125
+
126
+ ```
127
+ 你:帮我把这个 Vue 组件拆成 3 个子组件。
128
+ → AI: aig_status(了解现状)
129
+ → AI: aig_save("拆分组件") → 修改代码
130
+
131
+ 你:顺便加一下 TS 类型。
132
+ → AI: aig_save("增加 TS 类型") → 修改代码
133
+
134
+ 你:样式用 Tailwind 调一下。
135
+ → AI: aig_save("调整样式") → 修改代码
136
+
137
+ 你:没问题,收尾吧。
138
+ → AI: aig_squash(summary="feat: 拆分组件并增加 TS 类型", preview=true)
139
+ ← AI 展示预览,等你确认
140
+ → AI: aig_squash(summary="feat: 拆分组件并增加 TS 类型", preview=false)
141
+ ← 3 个碎片 Checkpoint 压缩为 1 个整洁 Commit ✨
142
+ ```
143
+
144
+ ---
145
+
146
+ ## 本地开发
147
+
148
+ ```bash
149
+ pnpm install
150
+ pnpm dev # watch 模式
151
+ pnpm build # 构建 → dist/index.js
152
+ ```
153
+
154
+ ## License
155
+
156
+ ISC
package/dist/index.js CHANGED
@@ -7,60 +7,235 @@ import {
7
7
  CallToolRequestSchema,
8
8
  ListToolsRequestSchema
9
9
  } from "@modelcontextprotocol/sdk/types.js";
10
- import { execSync } from "child_process";
11
- var server = new Server(
12
- { name: "aig-mcp-server", version: "1.0.2" },
13
- { capabilities: { tools: {} } }
14
- );
15
- var runSync = (cmd) => execSync(cmd, { stdio: "pipe", encoding: "utf-8" });
16
- server.setRequestHandler(ListToolsRequestSchema, async () => {
17
- return {
18
- tools: [
19
- {
20
- name: "aig_save",
21
- description: "\u5728\u8FDB\u884C\u4EE3\u7801\u4FEE\u6539\u524D\uFF0C\u5F3A\u5236\u8C03\u7528\u6B64\u5DE5\u5177\u8FDB\u884C Git \u5B58\u6863\u3002",
22
- inputSchema: {
23
- type: "object",
24
- properties: {
25
- message: {
26
- type: "string",
27
- description: "\u5B58\u6863\u5907\u6CE8\uFF0C\u7B80\u8FF0\u63A5\u4E0B\u6765\u8981\u4FEE\u6539\u7684\u5185\u5BB9"
28
- }
29
- },
30
- required: ["message"]
10
+
11
+ // src/utils/git.ts
12
+ import { execFileSync } from "child_process";
13
+ function git(...args) {
14
+ return execFileSync("git", args, { stdio: "pipe", encoding: "utf-8" }).trim();
15
+ }
16
+ function assertGitRepo() {
17
+ try {
18
+ git("rev-parse", "--is-inside-work-tree");
19
+ } catch {
20
+ throw new Error("\u5F53\u524D\u76EE\u5F55\u4E0D\u662F Git \u4ED3\u5E93\uFF0C\u8BF7\u5148\u6267\u884C git init");
21
+ }
22
+ }
23
+
24
+ // src/tools/aig_save.ts
25
+ var aigSave = {
26
+ definition: {
27
+ name: "aig_save",
28
+ description: "\u5728\u8FDB\u884C\u4EE3\u7801\u4FEE\u6539\u524D\uFF0C\u5F3A\u5236\u8C03\u7528\u6B64\u5DE5\u5177\u8FDB\u884C Git \u788E\u7247\u5B58\u6863\uFF08Checkpoint\uFF09\u3002",
29
+ inputSchema: {
30
+ type: "object",
31
+ properties: {
32
+ message: {
33
+ type: "string",
34
+ description: "\u5B58\u6863\u5907\u6CE8\uFF0C\u7B80\u8FF0\u63A5\u4E0B\u6765\u8981\u4FEE\u6539\u7684\u5185\u5BB9"
31
35
  }
32
36
  },
33
- {
34
- name: "aig_undo",
35
- description: "\u4EE3\u7801\u4FEE\u6539\u5931\u8D25\u3001\u62A5\u9519\uFF0C\u6216\u7528\u6237\u8981\u6C42\u64A4\u9500\u65F6\uFF0C\u8C03\u7528\u6B64\u5DE5\u5177\u5C06\u4EE3\u7801\u56DE\u6EDA\u3002",
36
- inputSchema: {
37
- type: "object",
38
- properties: {}
37
+ required: ["message"]
38
+ }
39
+ },
40
+ async handler(args) {
41
+ const { message } = args;
42
+ git("add", ".");
43
+ const staged = git("status", "--porcelain");
44
+ if (!staged) {
45
+ return {
46
+ content: [
47
+ {
48
+ type: "text",
49
+ text: "\u26A0\uFE0F \u5DE5\u4F5C\u533A\u65E0\u4EFB\u4F55\u53D8\u66F4\uFF0C\u8DF3\u8FC7\u672C\u6B21\u5B58\u6863\uFF0C\u8BF7\u5148\u4FEE\u6539\u4EE3\u7801\u518D\u5B58\u6863\u3002"
50
+ }
51
+ ]
52
+ };
53
+ }
54
+ const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
55
+ const msg = `\u{1F916} [AI Checkpoint] ${message} (${timestamp})`;
56
+ git("commit", "-m", msg);
57
+ return {
58
+ content: [{ type: "text", text: `\u2705 \u5B58\u6863\u6210\u529F\uFF01\u8BB0\u5F55: ${msg}` }]
59
+ };
60
+ }
61
+ };
62
+
63
+ // src/tools/aig_squash.ts
64
+ var aigSquash = {
65
+ definition: {
66
+ name: "aig_squash",
67
+ description: "\u5F53\u6574\u4E2A\u9700\u6C42\u6216\u4E00\u4E2A\u9636\u6BB5\u7684\u4EFB\u52A1\u5168\u90E8\u5B8C\u6210\u540E\uFF0C\u8C03\u7528\u6B64\u5DE5\u5177\u3002\u5B83\u4F1A\u81EA\u52A8\u8BC6\u522B\u5E76\u628A\u4E4B\u524D\u4EA7\u751F\u7684\u6240\u6709\u8FDE\u7EED AI Checkpoint \u788E\u7247\u63D0\u4EA4\uFF0C\u538B\u7F29\u5408\u5E76\u6210\u4E00\u4E2A\u6B63\u5F0F\u7684\u3001\u6574\u6D01\u7684 Git \u63D0\u4EA4\u8BB0\u5F55\u3002\u5EFA\u8BAE\u5148\u7528 preview: true \u9884\u89C8\uFF0C\u786E\u8BA4\u540E\u518D\u6B63\u5F0F\u6267\u884C\u3002",
68
+ inputSchema: {
69
+ type: "object",
70
+ properties: {
71
+ summary: {
72
+ type: "string",
73
+ description: "\u9AD8\u5EA6\u6982\u62EC\u672C\u6B21\u5B8C\u6210\u7684\u5185\u5BB9\uFF0C\u683C\u5F0F\u5EFA\u8BAE\uFF1A'feat: \u91CD\u6784\u591A\u79DF\u6237\u62E6\u622A\u5668\u5E76\u589E\u52A0\u8868\u5355\u6821\u9A8C'"
74
+ },
75
+ preview: {
76
+ type: "boolean",
77
+ description: "\u662F\u5426\u4EC5\u9884\u89C8\u5C06\u88AB\u5408\u5E76\u7684 Checkpoint \u5217\u8868\uFF08\u4E0D\u6267\u884C\u5B9E\u9645\u5408\u5E76\uFF09\u3002\u9ED8\u8BA4 false\u3002\u5EFA\u8BAE\u5148\u4F20 true \u786E\u8BA4\u5185\u5BB9\uFF0C\u518D\u4F20 false \u6B63\u5F0F\u6267\u884C\u3002"
39
78
  }
79
+ },
80
+ required: ["summary"]
81
+ }
82
+ },
83
+ async handler(args) {
84
+ const { summary, preview = false } = args;
85
+ const logOutput = git("log", "--format=%h|%s", "-n", "100");
86
+ const lines = logOutput.split("\n").filter(Boolean);
87
+ let count = 0;
88
+ const checkpoints = [];
89
+ for (const line of lines) {
90
+ const [hash, ...msgParts] = line.split("|");
91
+ const msg = msgParts.join("|");
92
+ if (msg.includes("[AI Checkpoint]")) {
93
+ count++;
94
+ checkpoints.push(` ${count}. ${hash} ${msg}`);
95
+ } else {
96
+ break;
40
97
  }
41
- ]
42
- };
43
- });
44
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
45
- const { name, arguments: args } = request.params;
46
- try {
47
- if (name === "aig_save") {
48
- const message = args.message;
49
- runSync("git add .");
50
- const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
51
- const msg = `\u{1F916} [AI Checkpoint] ${message} (${timestamp})`;
52
- runSync(`git commit -m "${msg}"`);
98
+ }
99
+ if (count === 0) {
53
100
  return {
54
- content: [{ type: "text", text: `\u2705 \u5B58\u6863\u6210\u529F\uFF01\u8BB0\u5F55: ${msg}` }]
101
+ content: [
102
+ {
103
+ type: "text",
104
+ text: "\u26A0\uFE0F \u6CA1\u6709\u627E\u5230\u8FDE\u7EED\u7684 AI Checkpoint\uFF0C\u65E0\u9700\u5408\u5E76\u3002\u5F53\u524D Git \u5386\u53F2\u5DF2\u7ECF\u5F88\u6574\u6D01\u4E86\uFF01"
105
+ }
106
+ ]
55
107
  };
56
108
  }
57
- if (name === "aig_undo") {
58
- runSync("git reset --hard HEAD~1");
109
+ if (preview) {
110
+ const previewText = [
111
+ `\u{1F50D} \u9884\u89C8\uFF1A\u4EE5\u4E0B ${count} \u4E2A AI Checkpoint \u5C06\u88AB\u538B\u7F29\u5408\u5E76\u4E3A\uFF1A`,
112
+ ` "\u2728 ${summary}"`,
113
+ "",
114
+ ...checkpoints,
115
+ "",
116
+ "\u786E\u8BA4\u65E0\u8BEF\u540E\uFF0C\u8BF7\u4EE5 preview: false \u91CD\u65B0\u8C03\u7528 aig_squash \u6267\u884C\u5408\u5E76\u3002"
117
+ ].join("\n");
59
118
  return {
60
- content: [{ type: "text", text: "\u23EA \u5DF2\u5B8C\u7F8E\u56DE\u6EDA\uFF01\u521A\u624D\u7684\u4FEE\u6539\u5DF2\u64A4\u9500\u3002" }]
119
+ content: [{ type: "text", text: previewText }]
61
120
  };
62
121
  }
63
- throw new Error("\u672A\u77E5\u7684\u5DE5\u5177\u8C03\u7528");
122
+ git("reset", "--soft", `HEAD~${count}`);
123
+ const finalMsg = `\u2728 ${summary}`;
124
+ git("commit", "-m", finalMsg);
125
+ return {
126
+ content: [
127
+ {
128
+ type: "text",
129
+ text: count === 1 ? `\u{1F389} \u5DF2\u5C06 1 \u4E2A AI \u5B58\u6863\u91CD\u547D\u540D\u4E3A\u6B63\u5F0F\u63D0\u4EA4\uFF1A
130
+ "${finalMsg}"` : `\u{1F389} \u5B8C\u7F8E\u6536\u5B98\uFF01\u5DF2\u5C06 ${count} \u4E2A AI \u788E\u7247\u5B58\u6863\u538B\u7F29\u5408\u5E76\u4E3A 1 \u4E2A\u6B63\u5F0F\u63D0\u4EA4\uFF1A
131
+ "${finalMsg}"`
132
+ }
133
+ ]
134
+ };
135
+ }
136
+ };
137
+
138
+ // src/tools/aig_status.ts
139
+ var aigStatus = {
140
+ definition: {
141
+ name: "aig_status",
142
+ description: "\u67E5\u770B\u5F53\u524D Git \u72B6\u6001\u5FEB\u7167\uFF1A\u5206\u652F\u3001\u5DE5\u4F5C\u533A\u53D8\u66F4\u3001\u5F85\u5408\u5E76\u7684 AI Checkpoint \u6570\u91CF\u53CA\u6700\u8FD1\u63D0\u4EA4\u8BB0\u5F55\u3002\u5728\u6267\u884C aig_save / aig_squash \u524D\u8C03\u7528\uFF0C\u53EF\u5E2E\u52A9 AI \u4E86\u89E3\u5F53\u524D\u72B6\u6001\u3002",
143
+ inputSchema: {
144
+ type: "object",
145
+ properties: {}
146
+ }
147
+ },
148
+ async handler() {
149
+ const branch = git("rev-parse", "--abbrev-ref", "HEAD");
150
+ const statusRaw = git("status", "--porcelain");
151
+ const changedFiles = statusRaw ? statusRaw.split("\n").filter(Boolean) : [];
152
+ const workingTreeStatus = changedFiles.length === 0 ? "\u2705 \u5DE5\u4F5C\u533A\u5E72\u51C0\uFF0C\u65E0\u672A\u63D0\u4EA4\u53D8\u66F4" : `\u26A0\uFE0F \u6709 ${changedFiles.length} \u4E2A\u6587\u4EF6\u672A\u63D0\u4EA4\uFF1A
153
+ ${changedFiles.map((f) => ` ${f}`).join("\n")}`;
154
+ const logOutput = git("log", "--format=%s", "-n", "100");
155
+ const lines = logOutput.split("\n").filter(Boolean);
156
+ let checkpointCount = 0;
157
+ for (const msg of lines) {
158
+ if (msg.includes("[AI Checkpoint]"))
159
+ checkpointCount++;
160
+ else break;
161
+ }
162
+ const checkpointStatus = checkpointCount === 0 ? "\u2705 \u65E0\u5F85\u5408\u5E76\u7684 AI Checkpoint" : `\u{1F4E6} \u6709 ${checkpointCount} \u4E2A\u8FDE\u7EED AI Checkpoint \u5F85\u5408\u5E76\uFF08\u53EF\u8C03\u7528 aig_squash \u538B\u7F29\uFF09`;
163
+ const recentLog = git("log", "--format=%h %s", "-n", "5");
164
+ const recentCommits = recentLog.split("\n").filter(Boolean).map((line, i) => ` ${i + 1}. ${line}`).join("\n");
165
+ const report = [
166
+ `\u{1F33F} \u5F53\u524D\u5206\u652F\uFF1A${branch}`,
167
+ "",
168
+ workingTreeStatus,
169
+ "",
170
+ checkpointStatus,
171
+ "",
172
+ "\u{1F4CB} \u6700\u8FD1\u63D0\u4EA4\u8BB0\u5F55\uFF1A",
173
+ recentCommits || " \uFF08\u6682\u65E0\u63D0\u4EA4\uFF09"
174
+ ].join("\n");
175
+ return {
176
+ content: [{ type: "text", text: report }]
177
+ };
178
+ }
179
+ };
180
+
181
+ // src/tools/aig_undo.ts
182
+ var aigUndo = {
183
+ definition: {
184
+ name: "aig_undo",
185
+ description: "\u4EE3\u7801\u4FEE\u6539\u5931\u8D25\u3001\u62A5\u9519\uFF0C\u6216\u7528\u6237\u8981\u6C42\u64A4\u9500\u65F6\uFF0C\u8C03\u7528\u6B64\u5DE5\u5177\u5C06\u4EE3\u7801\u56DE\u6EDA\u3002\u652F\u6301\u591A\u6B65\u56DE\u6EDA\u3002",
186
+ inputSchema: {
187
+ type: "object",
188
+ properties: {
189
+ steps: {
190
+ type: "number",
191
+ description: "\u56DE\u6EDA\u6B65\u6570\uFF0C\u9ED8\u8BA4\u4E3A 1\uFF08\u64A4\u9500\u6700\u8FD1\u4E00\u6B21\u4FEE\u6539\uFF09\uFF0C\u586B 2 \u5219\u64A4\u9500\u6700\u8FD1\u4E24\u6B21\uFF0C\u4EE5\u6B64\u7C7B\u63A8"
192
+ }
193
+ }
194
+ }
195
+ },
196
+ async handler(args) {
197
+ const { steps = 1 } = args;
198
+ if (!Number.isInteger(steps) || steps < 1 || steps > 20) {
199
+ return {
200
+ content: [
201
+ {
202
+ type: "text",
203
+ text: "\u274C steps \u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u4F20\u5165 1~20 \u4E4B\u95F4\u7684\u6574\u6570\u3002"
204
+ }
205
+ ],
206
+ isError: true
207
+ };
208
+ }
209
+ git("reset", "--hard", `HEAD~${steps}`);
210
+ return {
211
+ content: [
212
+ {
213
+ type: "text",
214
+ text: `\u23EA \u5DF2\u56DE\u6EDA ${steps} \u6B65\uFF01\u6240\u6709\u76F8\u5173\u4FEE\u6539\u5DF2\u64A4\u9500\u3002`
215
+ }
216
+ ]
217
+ };
218
+ }
219
+ };
220
+
221
+ // src/index.ts
222
+ var tools = [aigStatus, aigSave, aigUndo, aigSquash];
223
+ var toolMap = new Map(tools.map((t) => [t.definition.name, t]));
224
+ var server = new Server(
225
+ { name: "aig-mcp-server", version: "1.2.0" },
226
+ { capabilities: { tools: {} } }
227
+ );
228
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
229
+ tools: tools.map((t) => t.definition)
230
+ }));
231
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
232
+ const { name, arguments: args } = request.params;
233
+ try {
234
+ assertGitRepo();
235
+ const tool = toolMap.get(name);
236
+ if (!tool)
237
+ throw new Error(`\u672A\u77E5\u7684\u5DE5\u5177\u8C03\u7528: ${name}`);
238
+ return await tool.handler(args ?? {});
64
239
  } catch (error) {
65
240
  const errMsg = error instanceof Error ? error.message : String(error);
66
241
  return {
@@ -69,6 +244,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
69
244
  };
70
245
  }
71
246
  });
72
- var transport = new StdioServerTransport();
73
- await server.connect(transport);
247
+ async function main() {
248
+ const transport = new StdioServerTransport();
249
+ await server.connect(transport);
250
+ }
251
+ main();
74
252
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport {\r\n CallToolRequestSchema,\r\n ListToolsRequestSchema,\r\n} from \"@modelcontextprotocol/sdk/types.js\";\r\nimport { execSync } from \"child_process\";\r\n\r\n// 初始化 MCP Server\r\nconst server = new Server(\r\n { name: \"aig-mcp-server\", version: \"1.0.2\" },\r\n { capabilities: { tools: {} } },\r\n);\r\n\r\nconst runSync = (cmd: string): string =>\r\n execSync(cmd, { stdio: \"pipe\", encoding: \"utf-8\" });\r\n\r\n// 1. 注册工具\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\r\n return {\r\n tools: [\r\n {\r\n name: \"aig_save\",\r\n description: \"在进行代码修改前,强制调用此工具进行 Git 存档。\",\r\n inputSchema: {\r\n type: \"object\" as const,\r\n properties: {\r\n message: {\r\n type: \"string\",\r\n description: \"存档备注,简述接下来要修改的内容\",\r\n },\r\n },\r\n required: [\"message\"],\r\n },\r\n },\r\n {\r\n name: \"aig_undo\",\r\n description:\r\n \"代码修改失败、报错,或用户要求撤销时,调用此工具将代码回滚。\",\r\n inputSchema: {\r\n type: \"object\" as const,\r\n properties: {},\r\n },\r\n },\r\n ],\r\n };\r\n});\r\n\r\n// 2. 执行工具\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n const { name, arguments: args } = request.params;\r\n\r\n try {\r\n if (name === \"aig_save\") {\r\n const message = (args as { message: string }).message;\r\n runSync(\"git add .\");\r\n const timestamp = new Date().toLocaleTimeString();\r\n const msg = `🤖 [AI Checkpoint] ${message} (${timestamp})`;\r\n runSync(`git commit -m \"${msg}\"`);\r\n return {\r\n content: [{ type: \"text\", text: `✅ 存档成功!记录: ${msg}` }],\r\n };\r\n }\r\n\r\n if (name === \"aig_undo\") {\r\n runSync(\"git reset --hard HEAD~1\");\r\n return {\r\n content: [{ type: \"text\", text: \"⏪ 已完美回滚!刚才的修改已撤销。\" }],\r\n };\r\n }\r\n\r\n throw new Error(\"未知的工具调用\");\r\n } catch (error) {\r\n const errMsg = error instanceof Error ? error.message : String(error);\r\n return {\r\n content: [{ type: \"text\", text: `❌ 失败: ${errMsg}` }],\r\n isError: true,\r\n };\r\n }\r\n});\r\n\r\n// 3. 启动 Server\r\nconst transport = new StdioServerTransport();\r\nawait server.connect(transport);\r\n"],"mappings":";;;AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB;AAGzB,IAAM,SAAS,IAAI;AAAA,EACjB,EAAE,MAAM,kBAAkB,SAAS,QAAQ;AAAA,EAC3C,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,EAAE;AAChC;AAEA,IAAM,UAAU,CAAC,QACf,SAAS,KAAK,EAAE,OAAO,QAAQ,UAAU,QAAQ,CAAC;AAGpD,OAAO,kBAAkB,wBAAwB,YAAY;AAC3D,SAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,aAAa;AAAA,QACb,aAAa;AAAA,UACX,MAAM;AAAA,UACN,YAAY;AAAA,YACV,SAAS;AAAA,cACP,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA,UAAU,CAAC,SAAS;AAAA,QACtB;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,QACF,aAAa;AAAA,UACX,MAAM;AAAA,UACN,YAAY,CAAC;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAGD,OAAO,kBAAkB,uBAAuB,OAAO,YAAY;AACjE,QAAM,EAAE,MAAM,WAAW,KAAK,IAAI,QAAQ;AAE1C,MAAI;AACF,QAAI,SAAS,YAAY;AACvB,YAAM,UAAW,KAA6B;AAC9C,cAAQ,WAAW;AACnB,YAAM,aAAY,oBAAI,KAAK,GAAE,mBAAmB;AAChD,YAAM,MAAM,6BAAsB,OAAO,KAAK,SAAS;AACvD,cAAQ,kBAAkB,GAAG,GAAG;AAChC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,sDAAc,GAAG,GAAG,CAAC;AAAA,MACvD;AAAA,IACF;AAEA,QAAI,SAAS,YAAY;AACvB,cAAQ,yBAAyB;AACjC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,oGAAoB,CAAC;AAAA,MACvD;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,4CAAS;AAAA,EAC3B,SAAS,OAAO;AACd,UAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACpE,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,wBAAS,MAAM,GAAG,CAAC;AAAA,MACnD,SAAS;AAAA,IACX;AAAA,EACF;AACF,CAAC;AAGD,IAAM,YAAY,IAAI,qBAAqB;AAC3C,MAAM,OAAO,QAAQ,SAAS;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/git.ts","../src/tools/aig_save.ts","../src/tools/aig_squash.ts","../src/tools/aig_status.ts","../src/tools/aig_undo.ts"],"sourcesContent":["import type { Tool } from './types.js'\r\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js'\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\r\nimport {\r\n CallToolRequestSchema,\r\n ListToolsRequestSchema,\r\n} from '@modelcontextprotocol/sdk/types.js'\r\nimport { aigSave } from './tools/aig_save.js'\r\nimport { aigSquash } from './tools/aig_squash.js'\r\nimport { aigStatus } from './tools/aig_status.js'\r\nimport { aigUndo } from './tools/aig_undo.js'\r\nimport { assertGitRepo } from './utils/git.js'\r\n\r\n// 注册所有工具\r\nconst tools: Tool[] = [aigStatus, aigSave, aigUndo, aigSquash]\r\nconst toolMap = new Map(tools.map(t => [t.definition.name, t]))\r\n\r\nconst server = new Server(\r\n { name: 'aig-mcp-server', version: '1.2.0' },\r\n { capabilities: { tools: {} } },\r\n)\r\n\r\n// 列举工具\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({\r\n tools: tools.map(t => t.definition),\r\n}))\r\n\r\n// 路由工具调用\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n const { name, arguments: args } = request.params\r\n\r\n try {\r\n assertGitRepo()\r\n\r\n const tool = toolMap.get(name)\r\n if (!tool)\r\n throw new Error(`未知的工具调用: ${name}`)\r\n\r\n return await tool.handler((args ?? {}) as Record<string, unknown>)\r\n }\r\n catch (error) {\r\n const errMsg = error instanceof Error ? error.message : String(error)\r\n return {\r\n content: [{ type: 'text' as const, text: `❌ 失败: ${errMsg}` }],\r\n isError: true,\r\n }\r\n }\r\n})\r\n\r\nasync function main(): Promise<void> {\r\n const transport = new StdioServerTransport()\r\n await server.connect(transport)\r\n}\r\n\r\nmain()\r\n","import { execFileSync } from 'node:child_process'\r\n\r\n/**\r\n * 安全执行 git 命令(参数数组形式,防止 Shell 注入)\r\n */\r\nexport function git(...args: string[]): string {\r\n return execFileSync('git', args, { stdio: 'pipe', encoding: 'utf-8' }).trim()\r\n}\r\n\r\n/**\r\n * 检查当前目录是否是 Git 仓库,不是则抛出友好错误\r\n */\r\nexport function assertGitRepo(): void {\r\n try {\r\n git('rev-parse', '--is-inside-work-tree')\r\n }\r\n catch {\r\n throw new Error('当前目录不是 Git 仓库,请先执行 git init')\r\n }\r\n}\r\n","import type { CallToolResult, Tool } from '../types.js'\r\nimport { git } from '../utils/git.js'\r\n\r\nexport const aigSave: Tool = {\r\n definition: {\r\n name: 'aig_save',\r\n description:\r\n '在进行代码修改前,强制调用此工具进行 Git 碎片存档(Checkpoint)。',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n message: {\r\n type: 'string',\r\n description: '存档备注,简述接下来要修改的内容',\r\n },\r\n },\r\n required: ['message'],\r\n },\r\n },\r\n\r\n async handler(args): Promise<CallToolResult> {\r\n const { message } = args as { message: string }\r\n\r\n git('add', '.')\r\n\r\n // 空提交保护:暂存区无变更则跳过\r\n const staged = git('status', '--porcelain')\r\n if (!staged) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: '⚠️ 工作区无任何变更,跳过本次存档,请先修改代码再存档。',\r\n },\r\n ],\r\n }\r\n }\r\n\r\n const timestamp = new Date().toLocaleTimeString()\r\n const msg = `🤖 [AI Checkpoint] ${message} (${timestamp})`\r\n git('commit', '-m', msg)\r\n\r\n return {\r\n content: [{ type: 'text', text: `✅ 存档成功!记录: ${msg}` }],\r\n }\r\n },\r\n}\r\n","import type { CallToolResult, Tool } from '../types.js'\r\nimport { git } from '../utils/git.js'\r\n\r\nexport const aigSquash: Tool = {\r\n definition: {\r\n name: 'aig_squash',\r\n description:\r\n '当整个需求或一个阶段的任务全部完成后,调用此工具。它会自动识别并把之前产生的所有连续 AI Checkpoint 碎片提交,压缩合并成一个正式的、整洁的 Git 提交记录。建议先用 preview: true 预览,确认后再正式执行。',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n summary: {\r\n type: 'string',\r\n description:\r\n '高度概括本次完成的内容,格式建议:\\'feat: 重构多租户拦截器并增加表单校验\\'',\r\n },\r\n preview: {\r\n type: 'boolean',\r\n description:\r\n '是否仅预览将被合并的 Checkpoint 列表(不执行实际合并)。默认 false。建议先传 true 确认内容,再传 false 正式执行。',\r\n },\r\n },\r\n required: ['summary'],\r\n },\r\n },\r\n\r\n async handler(args): Promise<CallToolResult> {\r\n const { summary, preview = false } = args as {\r\n summary: string\r\n preview?: boolean\r\n }\r\n\r\n // 获取最近 100 条提交信息(含 hash 用于展示)\r\n const logOutput = git('log', '--format=%h|%s', '-n', '100')\r\n const lines = logOutput.split('\\n').filter(Boolean)\r\n\r\n // 统计连续的 [AI Checkpoint] 数量\r\n let count = 0\r\n const checkpoints: string[] = []\r\n for (const line of lines) {\r\n const [hash, ...msgParts] = line.split('|')\r\n const msg = msgParts.join('|')\r\n if (msg.includes('[AI Checkpoint]')) {\r\n count++\r\n checkpoints.push(` ${count}. ${hash} ${msg}`)\r\n }\r\n else {\r\n break\r\n }\r\n }\r\n\r\n if (count === 0) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: '⚠️ 没有找到连续的 AI Checkpoint,无需合并。当前 Git 历史已经很整洁了!',\r\n },\r\n ],\r\n }\r\n }\r\n\r\n // 预览模式:只展示将被合并的 Checkpoint,不执行\r\n if (preview) {\r\n const previewText = [\r\n `🔍 预览:以下 ${count} 个 AI Checkpoint 将被压缩合并为:`,\r\n ` \"✨ ${summary}\"`,\r\n '',\r\n ...checkpoints,\r\n '',\r\n '确认无误后,请以 preview: false 重新调用 aig_squash 执行合并。',\r\n ].join('\\n')\r\n\r\n return {\r\n content: [{ type: 'text', text: previewText }],\r\n }\r\n }\r\n\r\n // 正式执行:软回滚,抹掉碎片 commit,保留代码变更\r\n git('reset', '--soft', `HEAD~${count}`)\r\n\r\n const finalMsg = `✨ ${summary}`\r\n git('commit', '-m', finalMsg)\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text:\r\n count === 1\r\n ? `🎉 已将 1 个 AI 存档重命名为正式提交:\\n\"${finalMsg}\"`\r\n : `🎉 完美收官!已将 ${count} 个 AI 碎片存档压缩合并为 1 个正式提交:\\n\"${finalMsg}\"`,\r\n },\r\n ],\r\n }\r\n },\r\n}\r\n","import type { CallToolResult, Tool } from '../types.js'\r\nimport { git } from '../utils/git.js'\r\n\r\nexport const aigStatus: Tool = {\r\n definition: {\r\n name: 'aig_status',\r\n description:\r\n '查看当前 Git 状态快照:分支、工作区变更、待合并的 AI Checkpoint 数量及最近提交记录。在执行 aig_save / aig_squash 前调用,可帮助 AI 了解当前状态。',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {},\r\n },\r\n },\r\n\r\n async handler(): Promise<CallToolResult> {\r\n // 当前分支\r\n const branch = git('rev-parse', '--abbrev-ref', 'HEAD')\r\n\r\n // 工作区状态\r\n const statusRaw = git('status', '--porcelain')\r\n const changedFiles = statusRaw ? statusRaw.split('\\n').filter(Boolean) : []\r\n const workingTreeStatus\r\n = changedFiles.length === 0\r\n ? '✅ 工作区干净,无未提交变更'\r\n : `⚠️ 有 ${changedFiles.length} 个文件未提交:\\n${changedFiles.map(f => ` ${f}`).join('\\n')}`\r\n\r\n // 统计连续 AI Checkpoint 数量\r\n const logOutput = git('log', '--format=%s', '-n', '100')\r\n const lines = logOutput.split('\\n').filter(Boolean)\r\n let checkpointCount = 0\r\n for (const msg of lines) {\r\n if (msg.includes('[AI Checkpoint]'))\r\n checkpointCount++\r\n else break\r\n }\r\n\r\n const checkpointStatus\r\n = checkpointCount === 0\r\n ? '✅ 无待合并的 AI Checkpoint'\r\n : `📦 有 ${checkpointCount} 个连续 AI Checkpoint 待合并(可调用 aig_squash 压缩)`\r\n\r\n // 最近 5 条提交\r\n const recentLog = git('log', '--format=%h %s', '-n', '5')\r\n const recentCommits = recentLog\r\n .split('\\n')\r\n .filter(Boolean)\r\n .map((line, i) => ` ${i + 1}. ${line}`)\r\n .join('\\n')\r\n\r\n const report = [\r\n `🌿 当前分支:${branch}`,\r\n '',\r\n workingTreeStatus,\r\n '',\r\n checkpointStatus,\r\n '',\r\n '📋 最近提交记录:',\r\n recentCommits || ' (暂无提交)',\r\n ].join('\\n')\r\n\r\n return {\r\n content: [{ type: 'text', text: report }],\r\n }\r\n },\r\n}\r\n","import type { CallToolResult, Tool } from '../types.js'\r\nimport { git } from '../utils/git.js'\r\n\r\nexport const aigUndo: Tool = {\r\n definition: {\r\n name: 'aig_undo',\r\n description:\r\n '代码修改失败、报错,或用户要求撤销时,调用此工具将代码回滚。支持多步回滚。',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n steps: {\r\n type: 'number',\r\n description:\r\n '回滚步数,默认为 1(撤销最近一次修改),填 2 则撤销最近两次,以此类推',\r\n },\r\n },\r\n },\r\n },\r\n\r\n async handler(args): Promise<CallToolResult> {\r\n const { steps = 1 } = args as { steps?: number }\r\n\r\n if (!Number.isInteger(steps) || steps < 1 || steps > 20) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: '❌ steps 参数无效,请传入 1~20 之间的整数。',\r\n },\r\n ],\r\n isError: true,\r\n }\r\n }\r\n\r\n git('reset', '--hard', `HEAD~${steps}`)\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `⏪ 已回滚 ${steps} 步!所有相关修改已撤销。`,\r\n },\r\n ],\r\n }\r\n },\r\n}\r\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aig-mcp-server",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "AI Git checkpoint MCP server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,21 +10,22 @@
10
10
  "files": [
11
11
  "dist"
12
12
  ],
13
- "scripts": {
14
- "dev": "tsup --watch",
15
- "build": "tsup",
16
- "start": "node dist/index.js"
17
- },
18
13
  "keywords": [],
19
14
  "author": "",
20
15
  "license": "ISC",
21
- "packageManager": "pnpm@10.28.2",
22
16
  "dependencies": {
23
17
  "@modelcontextprotocol/sdk": "^1.0.0"
24
18
  },
25
19
  "devDependencies": {
26
20
  "@types/node": "^22.0.0",
27
21
  "tsup": "^8.0.0",
28
- "typescript": "^5.0.0"
22
+ "typescript": "^5.0.0",
23
+ "@antfu/eslint-config": "^7.6.1",
24
+ "eslint": "^10.0.2"
25
+ },
26
+ "scripts": {
27
+ "dev": "tsup --watch",
28
+ "build": "tsup",
29
+ "start": "node dist/index.js"
29
30
  }
30
- }
31
+ }