@reus-able/frontend-helper-mcp 1.0.10 → 1.0.12

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
@@ -1,41 +1,90 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer as d } from "@modelcontextprotocol/sdk/server/mcp.js";
3
- import { StdioServerTransport as f } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import c from "fs/promises";
5
- import s from "path";
6
- import { fileURLToPath as w } from "url";
7
- import { ListPromptsRequestSchema as y, GetPromptRequestSchema as h, ListResourcesRequestSchema as R, ReadResourceRequestSchema as v, ListToolsRequestSchema as g, CallToolRequestSchema as S } from "@modelcontextprotocol/sdk/types.js";
8
- async function m(e) {
2
+ import { McpServer as R } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport as v } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import i from "fs/promises";
5
+ import a from "path";
6
+ import { fileURLToPath as d } from "url";
7
+ import { ListPromptsRequestSchema as h, GetPromptRequestSchema as P, ListResourcesRequestSchema as S, ReadResourceRequestSchema as g, ListToolsRequestSchema as F, CallToolRequestSchema as M } from "@modelcontextprotocol/sdk/types.js";
8
+ import q from "fs";
9
+ function x(r) {
9
10
  try {
10
- return await c.access(e), (await c.readdir(e)).filter(
11
- (o) => [".txt", ".md", ".json"].includes(s.extname(o).toLowerCase())
11
+ return q.statSync(r).isDirectory();
12
+ } catch {
13
+ return !1;
14
+ }
15
+ }
16
+ function p(r, e, o = 8) {
17
+ let t = r;
18
+ for (let n = 0; n <= o; n++) {
19
+ const s = a.resolve(t, e);
20
+ if (x(s)) return s;
21
+ const c = a.dirname(t);
22
+ if (c === t) break;
23
+ t = c;
24
+ }
25
+ }
26
+ function l() {
27
+ const r = process.env.MCP_COMMAND_PROMPTS_DIR ?? process.env.MCP_PROMPTS_DIR;
28
+ if (r) return r;
29
+ const e = a.dirname(d(import.meta.url)), o = p(
30
+ e,
31
+ "resources/command-prompts"
32
+ );
33
+ if (o) return o;
34
+ const t = p(
35
+ process.cwd(),
36
+ "resources/command-prompts"
37
+ );
38
+ return t || a.resolve(process.cwd(), "resources/command-prompts");
39
+ }
40
+ async function m(r) {
41
+ try {
42
+ return await i.access(r), (await i.readdir(r)).filter(
43
+ (o) => [".txt", ".md", ".json"].includes(a.extname(o).toLowerCase())
12
44
  );
13
- } catch (r) {
14
- return console.error(`Error accessing prompts directory ${e}:`, r), [];
45
+ } catch (e) {
46
+ return console.error(`Error accessing prompts directory ${r}:`, e), [];
15
47
  }
16
48
  }
17
- async function u(e, r) {
18
- return (await m(e)).find((t) => s.parse(t).name === r);
49
+ async function f(r, e) {
50
+ return (await m(r)).find((t) => a.parse(t).name === e);
19
51
  }
20
- function p(e) {
21
- const r = s.extname(e).toLowerCase();
22
- return r === ".md" ? "text/markdown" : r === ".json" ? "application/json" : "text/plain";
52
+ function u(r) {
53
+ const e = a.extname(r).toLowerCase();
54
+ return e === ".md" ? "text/markdown" : e === ".json" ? "application/json" : "text/plain";
23
55
  }
24
- function q(e) {
25
- const r = s.resolve(__dirname, "../../../resources/command-prompts");
26
- e.server.setRequestHandler(y, async () => {
56
+ const w = {
57
+ "code-refactor.md": {
58
+ name: "代码重构",
59
+ description: "对代码进行结构调整,不改变功能逻辑"
60
+ },
61
+ "git-commit.md": {
62
+ name: "Git提交",
63
+ description: "符合约定式提交格式的Git提交"
64
+ },
65
+ "component-refactor.md": {
66
+ name: "组件重构",
67
+ description: "对组件进行结构调整,不改变功能逻辑"
68
+ }
69
+ };
70
+ function C(r) {
71
+ const e = l();
72
+ r.server.setRequestHandler(h, async () => {
27
73
  try {
28
- return { prompts: (await m(r)).map((n) => ({
29
- name: s.parse(n).name,
30
- description: `Content of ${n}`
31
- })) };
74
+ return { prompts: (await m(e)).map((n) => {
75
+ const s = a.parse(n).name;
76
+ return {
77
+ name: s,
78
+ description: w[s]?.description || `Content of ${n}`
79
+ };
80
+ }) };
32
81
  } catch (o) {
33
82
  return console.error("Error listing prompts:", o), { prompts: [] };
34
83
  }
35
- }), e.server.setRequestHandler(h, async (o) => {
84
+ }), r.server.setRequestHandler(P, async (o) => {
36
85
  const t = o.params.name;
37
86
  try {
38
- const n = await u(r, t);
87
+ const n = await f(e, t);
39
88
  if (!n)
40
89
  throw new Error(`Prompt not found: ${t}`);
41
90
  return {
@@ -44,7 +93,7 @@ function q(e) {
44
93
  role: "user",
45
94
  content: {
46
95
  type: "text",
47
- text: await c.readFile(s.join(r, n), "utf-8")
96
+ text: await i.readFile(a.join(e, n), "utf-8")
48
97
  }
49
98
  }
50
99
  ]
@@ -54,59 +103,59 @@ function q(e) {
54
103
  }
55
104
  });
56
105
  }
57
- function x(e) {
58
- const r = s.resolve(__dirname, "../../../resources/command-prompts");
59
- e.server.setRequestHandler(R, async () => {
106
+ function T(r) {
107
+ const e = l();
108
+ r.server.setRequestHandler(S, async () => {
60
109
  try {
61
- return { resources: (await m(r)).map((n) => {
62
- const a = s.parse(n).name, i = p(n);
110
+ return { resources: (await m(e)).map((n) => {
111
+ const s = a.parse(n).name, c = u(n);
63
112
  return {
64
- uri: `prompt://${a}`,
65
- name: a,
66
- mimeType: i,
67
- description: `Content of ${n}`
113
+ uri: `prompt://${s}`,
114
+ name: s,
115
+ mimeType: c,
116
+ description: w[s]?.description || `Content of ${n}`
68
117
  };
69
118
  }) };
70
119
  } catch (o) {
71
120
  return console.error("Error listing resources:", o), { resources: [] };
72
121
  }
73
- }), e.server.setRequestHandler(
74
- v,
122
+ }), r.server.setRequestHandler(
123
+ g,
75
124
  async (o) => {
76
125
  const t = o.params.uri, n = t.replace(/^prompt:\/\//, "");
77
126
  try {
78
- const a = await u(r, n);
79
- if (!a)
127
+ const s = await f(e, n);
128
+ if (!s)
80
129
  throw new Error(`Resource not found: ${t}`);
81
- const i = await c.readFile(s.join(r, a), "utf-8"), l = p(a);
130
+ const c = await i.readFile(a.join(e, s), "utf-8"), y = u(s);
82
131
  return {
83
132
  contents: [
84
133
  {
85
134
  uri: t,
86
- mimeType: l,
87
- text: i
135
+ mimeType: y,
136
+ text: c
88
137
  }
89
138
  ]
90
139
  };
91
- } catch (a) {
92
- throw new Error(`Failed to read resource ${t}: ${a}`);
140
+ } catch (s) {
141
+ throw new Error(`Failed to read resource ${t}: ${s}`);
93
142
  }
94
143
  }
95
144
  );
96
145
  }
97
- function F(e) {
98
- e.server.setRequestHandler(g, async () => ({ tools: [] })), e.server.setRequestHandler(S, async (r) => ({
146
+ function $(r) {
147
+ r.server.setRequestHandler(F, async () => ({ tools: [] })), r.server.setRequestHandler(M, async (e) => ({
99
148
  content: [
100
149
  {
101
150
  type: "text",
102
- text: `Tool not found: ${r.params.name}`
151
+ text: `Tool not found: ${e.params.name}`
103
152
  }
104
153
  ],
105
154
  isError: !0
106
155
  }));
107
156
  }
108
- async function $() {
109
- const e = s.dirname(w(import.meta.url)), r = s.resolve(e, "../package.json"), o = JSON.parse(await c.readFile(r, "utf-8")), t = new d(
157
+ async function D() {
158
+ const r = a.dirname(d(import.meta.url)), e = a.resolve(r, "../package.json"), o = JSON.parse(await i.readFile(e, "utf-8")), t = new R(
110
159
  {
111
160
  name: o.name,
112
161
  version: o.version
@@ -119,13 +168,13 @@ async function $() {
119
168
  }
120
169
  }
121
170
  );
122
- return q(t), x(t), F(t), t;
171
+ return C(t), T(t), $(t), t;
123
172
  }
124
173
  async function H() {
125
174
  console.error("Starting MCP server serving...");
126
- const e = await $(), r = new f();
127
- await e.connect(r);
175
+ const r = await D(), e = new v();
176
+ await r.connect(e);
128
177
  }
129
- H().catch((e) => {
130
- console.error("Fatal error:", e), process.exit(1);
178
+ H().catch((r) => {
179
+ console.error("Fatal error:", r), process.exit(1);
131
180
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "description": "前端开发的一些cursor mcp工具集",
3
3
  "name": "@reus-able/frontend-helper-mcp",
4
- "version": "1.0.10",
4
+ "version": "1.0.12",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -29,6 +29,7 @@
29
29
  "scripts": {
30
30
  "build": "vite build && node -e \"require('fs').chmodSync('dist/index.js',0o755)\"",
31
31
  "typecheck": "tsc -p tsconfig.json --noEmit",
32
+ "verify:prompts": "node scripts/verify-command-prompts-path.mjs",
32
33
  "test": "echo \"Error: no test specified\" && exit 1"
33
34
  }
34
35
  }
@@ -0,0 +1,5 @@
1
+ # 项目通用规则
2
+
3
+ - 始终使用中文回复用户,但技术专有名词可保留英文(如 API、Python、DTO等)。
4
+ - 使用项目既有风格,不引入新风格,包括代码、文档或交互,默认延用项目中已有的格式、缩进、命名习惯。
5
+ - 尽可能少地输出内容,仅提供高信息密度回复,禁止无效寒暄、过度铺垫,只输出对当前任务有直接帮助的信息。
@@ -1,10 +1,46 @@
1
1
  ## 协助用户提交当前变更
2
2
 
3
- 请你帮助用户提交当前变更,并按照约定式 commit 规范进行 git commit
4
- 你只需要分析用户的变更并生成commit message并commit
5
-
6
- 要求:
7
- 1. 一般情况下不允许改动任何要提交的文件
8
- 2. 不需要手动跑lint指令,husky会处理
9
- 3. 有时提交可能会报错,你需要分析报错原因并告知用户是否进行下一步操作,如果需要改动文件(例如修复lint错误,类型错误),需要获得用户同意后进行改动
10
- 4. 如果改动了文件,需要告知用户哪里有改动,并且在用户确认后再提交
3
+ # 代码提交规范
4
+ 创建格式规范的提交记录,搭配约定式提交信息。
5
+
6
+ ## 功能特性
7
+ - 默认执行提交前检查(代码检查、项目构建、文档生成)
8
+ - 若未暂存任何文件,则自动暂存合适的文件
9
+ - 采用约定式提交格式
10
+ - 针对不同类型的修改,建议拆分提交记录
11
+
12
+ ## 提交类型
13
+ - feat: 新功能
14
+ - fix: 缺陷修复
15
+ - docs: 文档内容变更
16
+ - refactor: 代码重构(不改变功能逻辑)
17
+ - style: 代码格式调整(如补充分号等格式问题)
18
+ - perf: 性能优化
19
+ - test: 新增或修正测试用例
20
+ - chore: 工具配置、项目维护等杂项工作
21
+ - wip: 进行中的工作(未完成提交)
22
+ - remove: 移除代码或文件
23
+ - hotfix: 紧急缺陷修复
24
+ - security: 安全性优化
25
+
26
+ ## 执行流程
27
+ 1. 检查已暂存的文件变更(执行 `git status` 命令)
28
+ 2. 若未暂存任何文件,则筛选并暂存相关文件
29
+ 3. 执行提交前检查(使用 `--no-verify` 参数时跳过)
30
+ 4. 分析文件变更内容,确定对应的提交类型
31
+ 5. 生成描述清晰的提交信息
32
+ 6. 若适用,添加作用域信息,格式为:`提交类型(作用域): 描述内容`
33
+ 7. 对于复杂的变更,在提交正文部分说明修改原因
34
+ 8. 执行提交操作
35
+
36
+ ## 最佳实践
37
+ - 保持提交的原子化与目标聚焦(一个提交对应一个功能/问题)
38
+ - 提交信息使用祈使语气(例如用“新增功能”而非“已新增功能”)
39
+ - 说明修改的**原因**,而不只是修改的**内容**
40
+ - 涉及相关需求单/合并请求时,添加对应的引用链接或编号
41
+ - 将不相关的代码变更拆分为多个独立的提交
42
+
43
+ ## 关键要求
44
+ **你只需要处理commit操作**
45
+ **在任何情况下不要修改任何文件**
46
+ **如果提交出错,你只需要分析原因并告知用户,不要尝试修复**