@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.
- package/LICENSE +21 -0
- package/README.md +326 -0
- package/app/cli/cli.js +17 -0
- package/app/cli/commands/start.js +20 -0
- package/app/cli/index.js +37 -0
- package/app/cli/support/argv.js +7 -0
- package/app/cli/support/signals.js +34 -0
- package/app/desktop/assets/icon.png +0 -0
- package/app/desktop/main.js +496 -0
- package/app/desktop/package-lock.json +4091 -0
- package/app/desktop/package.json +63 -0
- package/examples/prompts/developer/code-review.yaml +32 -0
- package/examples/prompts/developer/code_refactoring.yaml +31 -0
- package/examples/prompts/developer/doc-generator.yaml +36 -0
- package/examples/prompts/developer/error-code-fixer.yaml +35 -0
- package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +117 -0
- package/examples/prompts/generator/gen_3d_webpage_html.yaml +75 -0
- package/examples/prompts/generator/gen_bento_grid_html.yaml +112 -0
- package/examples/prompts/generator/gen_html_web_page.yaml +88 -0
- package/examples/prompts/generator/gen_knowledge_card_html.yaml +83 -0
- package/examples/prompts/generator/gen_magazine_card_html.yaml +82 -0
- package/examples/prompts/generator/gen_mimeng_headline_title.yaml +71 -0
- package/examples/prompts/generator/gen_podcast_script.yaml +69 -0
- package/examples/prompts/generator/gen_prd_prototype_html.yaml +175 -0
- package/examples/prompts/generator/gen_summarize.yaml +157 -0
- package/examples/prompts/generator/gen_title.yaml +119 -0
- package/examples/prompts/generator/others/api_documentation.yaml +32 -0
- package/examples/prompts/generator/others/build_mcp_server.yaml +26 -0
- package/examples/prompts/generator/others/project_architecture.yaml +31 -0
- package/examples/prompts/generator/others/test_case_generator.yaml +30 -0
- package/examples/prompts/generator/others/writing_assistant.yaml +72 -0
- package/package.json +54 -0
- package/packages/admin-ui/admin.html +4959 -0
- package/packages/admin-ui/css/codemirror-theme_xq-light.css +43 -0
- package/packages/admin-ui/css/codemirror.css +344 -0
- package/packages/admin-ui/js/closebrackets.min.js +8 -0
- package/packages/admin-ui/js/codemirror.min.js +8 -0
- package/packages/admin-ui/js/js-yaml.min.js +2 -0
- package/packages/admin-ui/js/markdown.min.js +8 -0
- package/packages/server/config.js +283 -0
- package/packages/server/logger.js +55 -0
- package/packages/server/manager.js +473 -0
- package/packages/server/mcp.js +234 -0
- package/packages/server/mcpManager.js +205 -0
- package/packages/server/server.js +1001 -0
- 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
|
+
[](https://www.npmjs.com/package/@becrafter/prompt-manager)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](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;
|
package/app/cli/index.js
ADDED
|
@@ -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
|