@becrafter/prompt-manager 0.0.8

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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +326 -0
  3. package/app/cli/cli.js +17 -0
  4. package/app/cli/commands/start.js +20 -0
  5. package/app/cli/index.js +37 -0
  6. package/app/cli/support/argv.js +7 -0
  7. package/app/cli/support/signals.js +34 -0
  8. package/app/desktop/assets/icon.png +0 -0
  9. package/app/desktop/main.js +496 -0
  10. package/app/desktop/package-lock.json +4091 -0
  11. package/app/desktop/package.json +63 -0
  12. package/examples/prompts/developer/code-review.yaml +32 -0
  13. package/examples/prompts/developer/code_refactoring.yaml +31 -0
  14. package/examples/prompts/developer/doc-generator.yaml +36 -0
  15. package/examples/prompts/developer/error-code-fixer.yaml +35 -0
  16. package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +117 -0
  17. package/examples/prompts/generator/gen_3d_webpage_html.yaml +75 -0
  18. package/examples/prompts/generator/gen_bento_grid_html.yaml +112 -0
  19. package/examples/prompts/generator/gen_html_web_page.yaml +88 -0
  20. package/examples/prompts/generator/gen_knowledge_card_html.yaml +83 -0
  21. package/examples/prompts/generator/gen_magazine_card_html.yaml +82 -0
  22. package/examples/prompts/generator/gen_mimeng_headline_title.yaml +71 -0
  23. package/examples/prompts/generator/gen_podcast_script.yaml +69 -0
  24. package/examples/prompts/generator/gen_prd_prototype_html.yaml +175 -0
  25. package/examples/prompts/generator/gen_summarize.yaml +157 -0
  26. package/examples/prompts/generator/gen_title.yaml +119 -0
  27. package/examples/prompts/generator/others/api_documentation.yaml +32 -0
  28. package/examples/prompts/generator/others/build_mcp_server.yaml +26 -0
  29. package/examples/prompts/generator/others/project_architecture.yaml +31 -0
  30. package/examples/prompts/generator/others/test_case_generator.yaml +30 -0
  31. package/examples/prompts/generator/others/writing_assistant.yaml +72 -0
  32. package/package.json +54 -0
  33. package/packages/admin-ui/admin.html +4959 -0
  34. package/packages/admin-ui/css/codemirror-theme_xq-light.css +43 -0
  35. package/packages/admin-ui/css/codemirror.css +344 -0
  36. package/packages/admin-ui/js/closebrackets.min.js +8 -0
  37. package/packages/admin-ui/js/codemirror.min.js +8 -0
  38. package/packages/admin-ui/js/js-yaml.min.js +2 -0
  39. package/packages/admin-ui/js/markdown.min.js +8 -0
  40. package/packages/server/config.js +283 -0
  41. package/packages/server/logger.js +55 -0
  42. package/packages/server/manager.js +473 -0
  43. package/packages/server/mcp.js +234 -0
  44. package/packages/server/mcpManager.js +205 -0
  45. package/packages/server/server.js +1001 -0
  46. package/scripts/postinstall.js +34 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Smartisan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,326 @@
1
+ # MCP Prompt Server
2
+
3
+ [![npm version](https://badge.fury.io/js/%40becrafter%2Fprompt-manager.svg)](https://www.npmjs.com/package/@becrafter/prompt-manager)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)
6
+
7
+ 一个基于 模型上下文协议(MCP) 的 Prompt 管理服务器 。可以将分散的、静态的提示词模板,转变为一个可通过 API 调用的、可动态配置的、可复用的服务,从而更高效地管理和使用 AI 提示词。
8
+
9
+ ## 核心特性
10
+
11
+ - 🛠️ **完整接口**:提供提示词列表、处理、帮助和版本信息等接口
12
+ - 📁 **递归扫描**:自动发现子目录中的 prompt 文件
13
+ - ⚙️ **灵活配置**:支持命令行参数和环境变量配置
14
+ - 🖥️ **原生桌面壳**:内置 Electron 菜单应用,可一键启动/关闭服务,并内嵌管理后台
15
+
16
+ ## 快速开始
17
+
18
+ ### 1. 安装
19
+
20
+ ```bash
21
+ # 全局安装
22
+ npm install -g @becrafter/prompt-manager
23
+
24
+ # 或作为项目依赖安装
25
+ npm install @becrafter/prompt-manager
26
+ ```
27
+
28
+ ### 2. 启动服务器
29
+
30
+ ```bash
31
+ # 使用默认配置启动
32
+ prompt-manager
33
+
34
+ # 指定提示词目录
35
+ prompt-manager --prompts-dir ./my-prompts
36
+
37
+ # 指定端口
38
+ prompt-manager --port 5621
39
+ ```
40
+
41
+ > 默认情况下,服务会在 `~/.prompt-manager/prompts` 下创建并读取提示词目录。第一次启动会将仓库中的 `examples/prompts` 同步过去,方便快速体验。
42
+
43
+ ### 3. CLI 命令
44
+
45
+ 新版本的命令行逻辑已经集中在 `app/cli` 中,支持拓展式命令分发。常用用法保持不变:
46
+
47
+ ```bash
48
+ # 默认等价于 prompt-manager start
49
+ prompt-manager
50
+
51
+ # 显式使用 start/run 命令
52
+ prompt-manager start --port 6000
53
+ prompt-manager run --prompts-dir ./examples/prompts
54
+
55
+ # 获取帮助/版本信息
56
+ prompt-manager --help
57
+ prompt-manager --version
58
+ ```
59
+
60
+ 后续如需增加自定义子命令,只需在 `app/cli/commands` 下添加对应实现并在 `app/cli/index.js` 注册即可。
61
+
62
+ ## 桌面菜单应用(Electron)
63
+
64
+ 为了让非技术同学也能便捷地运行服务,仓库新增了一个 Electron 菜单栏应用,位于 `app/desktop`。打包后的应用会连同 Node.js 运行时、`prompt-manager` 代码以及依赖一并分发,无需再额外配置环境。
65
+
66
+ ### 目录与结构
67
+
68
+ - `app/desktop/main.js`:Electron 主进程,负责托盘 UI、服务生命周期、升级流程
69
+ - `app/desktop/assets/`:托盘、安装图标等资源
70
+ - `app/desktop/package.json`:单独的桌面工程配置与 `electron-builder` 打包描述
71
+
72
+ ### 菜单功能
73
+
74
+ - **启/停服务**:根据当前状态切换文案,直接调用服务的 `startServer/stopServer`
75
+ - **复制服务地址**:一键复制当前 `http://127.0.0.1:<port>` 地址,方便分享或调试
76
+ - **打开管理后台**:在独立窗口中嵌入服务自带的 `/admin` 前端,可直接登录管理 prompt
77
+ - **检查更新**:调用 npm Registry 获取最新版本,下载 tarball、自动安装依赖,并保留 `examples/prompts` 内的示例内容(实际数据位于 `~/.prompt-manager/prompts`,不会受影响)
78
+ - **关于服务**:展示桌面端、服务端、Electron、Chromium、Node.js 等组件版本
79
+ - **退出服务**:先平滑停止 Express 服务,再退出 Electron 进程
80
+
81
+ ### 本地开发/调试
82
+
83
+ ```bash
84
+ # 安装依赖(仓库根目录已经装好 server 依赖)
85
+ cd app/desktop
86
+ npm install
87
+
88
+ # 启动托盘应用(也可使用根目录脚本 npm run desktop:dev)
89
+ npm run dev
90
+ ```
91
+
92
+ 启动后系统托盘只会出现一个图标,所有交互都在菜单里完成。
93
+
94
+ ### 打包发布
95
+
96
+ ```bash
97
+ # 在仓库根目录执行,会调用 app/desktop 内的 electron-builder
98
+ npm run desktop:build
99
+ ```
100
+
101
+ `electron-builder` 会输出 macOS `.dmg`、Windows `.exe`(NSIS)以及 Linux `.AppImage` 安装包,`extraResources` 中包含 `prompt-manager` 的源码与依赖,从而保证离线可用。
102
+
103
+ ### 升级机制
104
+
105
+ 菜单中的 “检查更新” 会:
106
+
107
+ 1. 读取当前运行的服务版本(`app.getPath('userData')/prompt-manager/package.json`)
108
+ 2. 对比 npm Registry 上的最新版本
109
+ 3. 在用户确认后停止服务、下载最新 tarball、重新写入运行目录
110
+ 4. 通过 `npm install --omit=dev` 在沙盒目录中重新安装依赖
111
+ 5. 保留示例 `examples/prompts` 目录(若存在),用户自定义数据保存在 `~/.prompt-manager/prompts`,无需额外迁移
112
+
113
+ 整个过程无需系统层面的 Node/npm,真正实现“装上即用”。
114
+
115
+ ## 配置选项
116
+
117
+ ### 命令行参数
118
+
119
+ | 参数 | 简写 | 描述 |
120
+ |------|------|------|
121
+ | `--prompts-dir <目录>` | `-p` | 指定 prompts 文件所在目录 |
122
+ | `--port <端口>` | `-P` | 指定服务器端口 (默认: 5621) |
123
+ | `--help` | `-h` | 显示帮助信息 |
124
+ | `--version` | `-v` | 显示版本信息 |
125
+
126
+ ### 环境变量
127
+
128
+ | 环境变量 | 描述 | 默认值 |
129
+ |----------|------|--------|
130
+ | `MCP_SERVER_NAME` | 服务器名称 | `prompt-manager` |
131
+ | `SERVER_PORT` | 服务器端口 | `5621` |
132
+ | `PROMPTS_DIR` | Prompts目录路径 | `~/.prompt-manager/prompts` |
133
+ | `MCP_SERVER_VERSION` | 服务器版本 | `0.0.8` |
134
+ | `LOG_LEVEL` | 日志级别 (error, warn, info, debug) | `info` |
135
+ | `MAX_PROMPTS` | 最大prompt数量限制 | `100` |
136
+ | `RECURSIVE_SCAN` | 是否启用递归扫描子目录 | `true` |
137
+
138
+ > 安装或首次运行时,会自动将 `env.example` 内容写入 `~/.prompt-manager/.env`(如果该文件尚未存在),方便在系统范围内共享配置。
139
+
140
+ ## API 接口
141
+
142
+ ### 获取服务器信息
143
+
144
+ ```
145
+ GET /
146
+ ```
147
+
148
+ 返回服务器基本信息和可用接口列表。
149
+
150
+ ### 获取提示词列表
151
+
152
+ ```
153
+ GET /prompts
154
+ ```
155
+
156
+ 返回所有可用的提示词列表。
157
+
158
+ ### 获取单个提示词详情
159
+
160
+ ```
161
+ GET /prompts/:name
162
+ ```
163
+
164
+ 返回指定名称的提示词详细信息。
165
+
166
+ ### 创建新提示词
167
+
168
+ ```
169
+ POST /prompts
170
+ ```
171
+
172
+ 创建新的提示词文件。
173
+
174
+ 请求体示例:
175
+ ```json
176
+ {
177
+ "name": "my-prompt",
178
+ "description": "我的自定义提示词",
179
+ "messages": [
180
+ {
181
+ "role": "user",
182
+ "content": {
183
+ "text": "这是一个{{参数}}示例"
184
+ }
185
+ }
186
+ ],
187
+ "arguments": [
188
+ {
189
+ "name": "参数",
190
+ "description": "示例参数",
191
+ "type": "string",
192
+ "required": true
193
+ }
194
+ ]
195
+ }
196
+ ```
197
+
198
+ ### 更新提示词
199
+
200
+ ```
201
+ PUT /prompts/:name
202
+ ```
203
+
204
+ 更新现有的提示词文件。修改前会自动创建备份。
205
+
206
+ 请求体格式与创建相同。
207
+
208
+ ### 删除提示词
209
+
210
+ ```
211
+ DELETE /prompts/:name
212
+ ```
213
+
214
+ 删除指定的提示词文件。删除前会自动创建备份。
215
+
216
+ ### 验证YAML格式
217
+
218
+ ```
219
+ POST /prompts/validate
220
+ ```
221
+
222
+ 验证提示词YAML格式是否正确。
223
+
224
+ 请求体示例:
225
+ ```yaml
226
+ yaml: |
227
+ name: test-prompt
228
+ description: 测试提示词
229
+ messages:
230
+ - role: user
231
+ content:
232
+ text: 测试内容
233
+ ```
234
+
235
+ ### 获取备份列表
236
+
237
+ ```
238
+ GET /backups
239
+ ```
240
+
241
+ 获取所有提示词备份文件列表。
242
+
243
+ ### 处理提示词
244
+
245
+ ```
246
+ POST /process
247
+ ```
248
+
249
+ 处理指定的提示词,支持参数替换。
250
+
251
+ 请求体示例:
252
+ ```json
253
+ {
254
+ "promptName": "code-review",
255
+ "arguments": {
256
+ "language": "JavaScript",
257
+ "code": "function hello() { console.log('Hello'); }"
258
+ }
259
+ }
260
+ ```
261
+
262
+ ### 获取帮助信息
263
+
264
+ ```
265
+ GET /help
266
+ ```
267
+
268
+ 返回服务器使用帮助信息。
269
+
270
+ ### 获取版本信息
271
+
272
+ ```
273
+ GET /version
274
+ ```
275
+
276
+ 返回服务器版本信息。
277
+
278
+ ## 提示词格式
279
+
280
+ 提示词文件使用 YAML 格式,需要包含以下基本结构:
281
+
282
+ ```yaml
283
+ name: prompt-name
284
+ description: 提示词描述
285
+ messages:
286
+ - role: user
287
+ content:
288
+ text: 提示词内容,支持 {{参数名}} 格式的参数替换
289
+ ```
290
+
291
+ ## 开发
292
+
293
+ ### 项目结构
294
+
295
+ ```
296
+ prompt-manager/
297
+ ├── app/
298
+ │ ├── cli/ # 命令行命令分发与共享工具
299
+ │ └── desktop/ # Electron 菜单应用
300
+ ├── packages/
301
+ │ ├── admin-ui/ # 内置管理后台静态资源
302
+ │ └── server/ # 服务端核心逻辑
303
+ ├── examples/
304
+ │ └── prompts/ # 随包示例提示词(首次启动会同步到 ~/.prompt-manager/prompts)
305
+ ├── scripts/ # 安装/维护脚本(如 env 同步)
306
+ ├── bin/ # 可执行入口
307
+ └── package.json
308
+ ```
309
+
310
+ ### 本地开发
311
+
312
+ ```bash
313
+ # 克隆仓库
314
+ git clone https://github.com/BeCrafter/prompt-manager.git
315
+ cd prompt-manager
316
+
317
+ # 安装依赖
318
+ npm install
319
+
320
+ # 启动开发服务器
321
+ npm run dev
322
+ ```
323
+
324
+ ## 许可证
325
+
326
+ MIT License
package/app/cli/cli.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * CLI入口脚本
5
+ * 现在仅负责将请求转发到 app/cli 中的命令调度层
6
+ */
7
+
8
+ import { fileURLToPath } from 'url';
9
+ import { runPromptServerCLI } from './index.js';
10
+
11
+ const scriptPath = fileURLToPath(import.meta.url);
12
+ const args = process.argv.slice(2);
13
+
14
+ runPromptServerCLI(args, { scriptPath }).catch((error) => {
15
+ process.stderr.write('启动失败: ' + (error?.message || error) + '\n');
16
+ process.exit(1);
17
+ });
@@ -0,0 +1,20 @@
1
+ import { normalizeArgv } from '../support/argv.js';
2
+ import { registerSignalHandlers } from '../support/signals.js';
3
+
4
+ export async function startCommand(rawArgs, options = {}) {
5
+ const { scriptPath } = options;
6
+ process.argv = normalizeArgv(rawArgs, scriptPath);
7
+
8
+ const { startServer, stopServer, getServerState } = await import('../../../packages/server/server.js');
9
+
10
+ registerSignalHandlers(stopServer);
11
+
12
+ await startServer();
13
+
14
+ const state = getServerState();
15
+ console.log(`Prompt Server 已启动:${state.address}`);
16
+
17
+ return new Promise(() => {});
18
+ }
19
+
20
+ export default startCommand;
@@ -0,0 +1,37 @@
1
+ import startCommand from './commands/start.js';
2
+
3
+ const COMMANDS = {
4
+ start: startCommand,
5
+ run: startCommand
6
+ };
7
+
8
+ function printUsage() {
9
+ console.log(`Prompt Server CLI\n\n用法:\n prompt-manager [command] [options]\n\n可用命令:\n start 启动服务 (默认)\n run 启动服务 (同 start)\n\n示例:\n prompt-manager --port 6000\n prompt-manager start --prompts-dir ./examples/prompts`);
10
+ }
11
+
12
+ function isOptionToken(token) {
13
+ return token?.startsWith('-');
14
+ }
15
+
16
+ export async function runPromptServerCLI(rawArgs = process.argv.slice(2), options = {}) {
17
+ const args = Array.isArray(rawArgs) ? [...rawArgs] : [];
18
+
19
+ const [firstToken] = args;
20
+ const commandKey = firstToken && !isOptionToken(firstToken) ? firstToken.toLowerCase() : null;
21
+
22
+ if (!commandKey) {
23
+ return startCommand(args, options);
24
+ }
25
+
26
+ const command = COMMANDS[commandKey];
27
+ if (!command) {
28
+ console.error(`未知命令: ${firstToken}\n`);
29
+ printUsage();
30
+ process.exit(1);
31
+ }
32
+
33
+ const commandArgs = args.slice(1);
34
+ return command(commandArgs, options);
35
+ }
36
+
37
+ export default runPromptServerCLI;
@@ -0,0 +1,7 @@
1
+ import { fileURLToPath } from 'url';
2
+
3
+ export function normalizeArgv(rawArgs, scriptPathOverride) {
4
+ const execPath = process.execPath || 'node';
5
+ const scriptPath = scriptPathOverride ?? fileURLToPath(new URL('../index.js', import.meta.url));
6
+ return [execPath, scriptPath, ...(rawArgs || [])];
7
+ }
@@ -0,0 +1,34 @@
1
+ let isStopping = false;
2
+
3
+ export function registerSignalHandlers(stopServer) {
4
+ const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
5
+
6
+ const handle = async (signal) => {
7
+ if (isStopping) return;
8
+ isStopping = true;
9
+ try {
10
+ await stopServer();
11
+ } catch (error) {
12
+ console.error(`停止服务时发生错误: ${error?.message || error}`);
13
+ } finally {
14
+ if (signal) {
15
+ console.log(`收到 ${signal} 信号,准备退出...`);
16
+ }
17
+ process.exit(0);
18
+ }
19
+ };
20
+
21
+ signals.forEach((signal) => {
22
+ process.on(signal, () => handle(signal));
23
+ });
24
+
25
+ process.on('uncaughtException', (error) => {
26
+ console.error('未捕获的异常:', error);
27
+ handle('uncaughtException');
28
+ });
29
+
30
+ process.on('unhandledRejection', (reason) => {
31
+ console.error('未处理的 Promise 拒绝:', reason);
32
+ handle('unhandledRejection');
33
+ });
34
+ }
Binary file