ellm-proxy 0.0.2 → 0.0.6
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 +60 -60
- package/bin/commands/autostart.js +37 -213
- package/bin/commands/config.js +8 -8
- package/bin/commands/pm2.js +28 -28
- package/bin/commands/service.js +107 -107
- package/bin/ellm-proxy.js +61 -61
- package/dist/server.js +33 -2
- package/dist/web-ui/assets/DashboardView-BHG4xIdN.css +1 -0
- package/dist/web-ui/assets/{DashboardView-CQdlgirS.js → DashboardView-C3Hw-HpG.js} +1 -1
- package/dist/web-ui/assets/LayoutView-BUA8-IzK.css +1 -0
- package/dist/web-ui/assets/LayoutView-C9phf7in.js +1 -0
- package/dist/web-ui/assets/LoginView-DrhfslIY.css +1 -0
- package/dist/web-ui/assets/LoginView-es6pSPgt.js +1 -0
- package/dist/web-ui/assets/LogsView-BlXITEJH.js +9 -0
- package/dist/web-ui/assets/LogsView-Dl50XQhG.css +1 -0
- package/dist/web-ui/assets/{ProcessView-0x_ShSwV.js → ProcessView-Bgf7-MLQ.js} +1 -1
- package/dist/web-ui/assets/ProcessView-DK0TvDpR.css +1 -0
- package/dist/web-ui/assets/ProvidersView-Dpr8MI-p.css +1 -0
- package/dist/web-ui/assets/ProvidersView-f8aZkMdw.js +31 -0
- package/dist/web-ui/assets/SettingsView-BkwyoOUb.css +1 -0
- package/dist/web-ui/assets/SettingsView-GvAA2vLp.js +1 -0
- package/dist/web-ui/assets/config-Cs3_z63C.js +1 -0
- package/dist/web-ui/assets/{index-DFlUx18F.js → index-GohB4JDa.js} +2 -2
- package/dist/web-ui/assets/{providers-CGEmOxne.js → providers-Djtdy2tv.js} +1 -1
- package/dist/web-ui/assets/{useApi-BRPinb_2.js → useApi-D_iJ2Mca.js} +1 -1
- package/dist/web-ui/assets/useManagerApi-C1_COxKg.js +1 -0
- package/dist/web-ui/assets/{useToast-D7xlwSg6.js → useToast-C0UMTbkx.js} +1 -1
- package/dist/web-ui/config.js +10 -10
- package/dist/web-ui/index.html +13 -13
- package/docs/DESIGN.md +99 -99
- package/manager/api/harness/backup.js +20 -20
- package/manager/api/harness/claude-code.js +54 -54
- package/manager/api/harness/codex.js +123 -123
- package/manager/api/harness/dsh.js +175 -175
- package/manager/api/harness/index.js +118 -118
- package/manager/api/service-settings.js +98 -0
- package/manager/api/service.js +3 -13
- package/manager/index.js +182 -170
- package/package.json +44 -40
- package/utils/autostart.js +219 -0
- package/utils/interpreter.js +14 -14
- package/utils/paths.js +45 -44
- package/utils/pm2.js +130 -130
- package/utils/service.js +205 -189
- package/utils/updater.js +210 -0
- package/dist/web-ui/assets/DashboardView-qrQrkgLA.css +0 -1
- package/dist/web-ui/assets/LayoutView-BaY4Pz9W.js +0 -1
- package/dist/web-ui/assets/LoginView-CPvz1Ylx.js +0 -1
- package/dist/web-ui/assets/LoginView-Dg0mB6ok.css +0 -1
- package/dist/web-ui/assets/LogsView-B-bIj36j.js +0 -9
- package/dist/web-ui/assets/LogsView-Wl3_adHm.css +0 -1
- package/dist/web-ui/assets/ProcessView-DzMqBJmd.css +0 -1
- package/dist/web-ui/assets/ProvidersView-BxAxDRFH.css +0 -1
- package/dist/web-ui/assets/ProvidersView-GQENcvJS.js +0 -31
- package/dist/web-ui/assets/SettingsView-BDkymsrS.css +0 -1
- package/dist/web-ui/assets/SettingsView-BrAiaskZ.js +0 -1
- package/dist/web-ui/assets/config-DNn5cjYY.js +0 -1
- package/dist/web-ui/assets/useManagerApi-BDWJz5o6.js +0 -1
package/README.md
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
# ellm-proxy
|
|
2
|
-
|
|
3
|
-
自研 LLM 网关(行为基准 litellm 1.100.0),pm2 后台守护一键启停(跨平台)。主服务(`ellm-proxy`)单进程提供网关与管理台 API;管理服务(`ellm-proxy-manager`,端口 = 主端口 + 1)托管管理界面 web-ui 并反代 `/api/*` 到主服务,主服务停止时仍可远程拉起。
|
|
4
|
-
|
|
5
|
-
> 需求决策与架构设计详见 [docs/DESIGN.md](docs/DESIGN.md)。
|
|
6
|
-
|
|
7
|
-
- `/v1/*` — LLM 网关端点(OpenAI / Anthropic 协议互转,多供应商路由、压缩、鉴权)
|
|
8
|
-
- `/api/*` — 管理台 API(登录鉴权、配置热更新、用量/日志;主服务全局 CORS,供独立部署的 web-ui 跨源调用)
|
|
9
|
-
- `http://127.0.0.1:<主端口+1>/` — 管理界面(manager 托管 web-ui,同源反代 `/api/*`)
|
|
10
|
-
|
|
11
|
-
## 安装
|
|
12
|
-
|
|
13
|
-
要求 Node.js **>= 22.13.0**(内置 `node:sqlite`,无需 flag)。
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm i -g ellm-proxy
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## 使用
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
ellm-proxy -h # 查看帮助
|
|
23
|
-
ellm-proxy start # pm2 后台守护启动(崩溃自动重启;首次自动创建配置)
|
|
24
|
-
ellm-proxy stop # 停止服务
|
|
25
|
-
ellm-proxy restart # 重启(先 stop 后 start,保证最新参数生效,选项同 start)
|
|
26
|
-
ellm-proxy autostart on # Windows 开机自启(注册登录触发的计划任务)
|
|
27
|
-
ellm-proxy autostart off # 关闭开机自启
|
|
28
|
-
ellm-proxy config # 显示配置文件路径
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
`start/stop/restart` 基于包内自带的 pm2(局部安装,进程名 `ellm-proxy`):服务由 pm2 守护常驻,关闭终端不影响运行,崩溃自动重启(封顶 10 次,防端口占用无限循环),日志写 `<appDir>/logs/`。服务要求的 Node ≥22.13 由 CLI 解析(当前 node 满足则直接用,否则经 get-node 自动下载一次并缓存),终端默认 node 版本无关。start/stop 成功后自动 `pm2 dump`,可随时用 `pm2 resurrect` 恢复。Windows、Linux、macOS 均可用;运行状态用 `pm2 ls` 查看。
|
|
32
|
-
|
|
33
|
-
**开机自启(跨平台)**:`ellm-proxy autostart on` 注册登录触发的自启项(内容为 `pm2 resurrect`),三平台均无需管理员权限——Windows 写启动文件夹 `.cmd`、macOS 写 LaunchAgent(`launchctl load`)、Linux 写 systemd user unit(`systemctl --user enable`,WSL/无 systemd 环境会报错提示);`autostart off` 移除。
|
|
34
|
-
|
|
35
|
-
## 运行时布局(默认 `~/.ellm-proxy/`,均可被环境变量覆盖)
|
|
36
|
-
|
|
37
|
-
| 内容 | 默认路径 | 环境变量覆盖 |
|
|
38
|
-
| --- | --- | --- |
|
|
39
|
-
| 配置文件 | `~/.ellm-proxy/ellm.config.json` | `ELLM_CONFIG`(或 `start --config <path>`) |
|
|
40
|
-
| 数据目录(sqlite 日志/缓存) | `~/.ellm-proxy/data/` | `ELLM_DATA_DIR`(或 `start --data-dir <path>`) |
|
|
41
|
-
| 应用目录(配置/数据基准) | `~/.ellm-proxy/` | `ELLM_APP_DIR`(CLI 按 `--working-dir` 自动注入) |
|
|
42
|
-
| web-ui 静态资源 | 包内 `dist/web-ui/`(manager 托管) | `ELLM_WEBUI_DIR`(可选覆盖;manager 按自身位置自动推导) |
|
|
43
|
-
| 运行日志 | `~/.ellm-proxy/logs/` | `start --working-dir <path>`(见 `ellm-proxy -h`) |
|
|
44
|
-
|
|
45
|
-
所有路径均支持相对路径(按当前工作目录展开)与绝对路径。服务端自身不加载任何 `.env` 文件;`ELLM_MASTER_KEY` 等环境变量直接在会话中导出即可。
|
|
46
|
-
|
|
47
|
-
首次执行 `ellm-proxy start` 会自动创建示例配置,之后两种方式修改:
|
|
48
|
-
|
|
49
|
-
1. 直接编辑配置文件;
|
|
50
|
-
2. 启动服务后访问管理界面 `http://127.0.0.1:<主端口+1>/` 在线修改(实时热更新)。
|
|
51
|
-
|
|
52
|
-
其他环境变量:`ELLM_PORT`(网关监听端口,或 `start --port`;管理服务固定 `ELLM_PORT + 1`,可用 `ELLM_MANAGER_PORT` 覆盖)、`HOST`(监听地址)、`ELLM_MASTER_KEY`(网关主密钥,低于配置文件 `masterKey` 字段)。启动时端口若被占用会自动顺延到下一个空闲端口(仅本次运行生效,不改配置文件),顺延结果会打印在启动摘要中。
|
|
53
|
-
|
|
54
|
-
## 本地开发(仓库内)
|
|
55
|
-
|
|
56
|
-
本包是 `ellm` monorepo 的发布载体:发布版 `dist/server.js` 由 `scripts/build-server.mjs` 从 `backend` 源码直接构建(esbuild 插件在构建期把路径模块替换为 `release/runtime-dir.ts` 包模式实现,backend 源码保持单模式零分支),`web-ui` 产物由 `pnpm build:web` 生成后拷入 `dist/web-ui/`(manager 托管):
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
pnpm pack:proxy # 构建 web-ui → 构建发布版 + 聚合 → npm pack 生成 tgz
|
|
60
|
-
```
|
|
1
|
+
# ellm-proxy
|
|
2
|
+
|
|
3
|
+
自研 LLM 网关(行为基准 litellm 1.100.0),pm2 后台守护一键启停(跨平台)。主服务(`ellm-proxy`)单进程提供网关与管理台 API;管理服务(`ellm-proxy-manager`,端口 = 主端口 + 1)托管管理界面 web-ui 并反代 `/api/*` 到主服务,主服务停止时仍可远程拉起。
|
|
4
|
+
|
|
5
|
+
> 需求决策与架构设计详见 [docs/DESIGN.md](docs/DESIGN.md)。
|
|
6
|
+
|
|
7
|
+
- `/v1/*` — LLM 网关端点(OpenAI / Anthropic 协议互转,多供应商路由、压缩、鉴权)
|
|
8
|
+
- `/api/*` — 管理台 API(登录鉴权、配置热更新、用量/日志;主服务全局 CORS,供独立部署的 web-ui 跨源调用)
|
|
9
|
+
- `http://127.0.0.1:<主端口+1>/` — 管理界面(manager 托管 web-ui,同源反代 `/api/*`)
|
|
10
|
+
|
|
11
|
+
## 安装
|
|
12
|
+
|
|
13
|
+
要求 Node.js **>= 22.13.0**(内置 `node:sqlite`,无需 flag)。
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i -g ellm-proxy
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 使用
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ellm-proxy -h # 查看帮助
|
|
23
|
+
ellm-proxy start # pm2 后台守护启动(崩溃自动重启;首次自动创建配置)
|
|
24
|
+
ellm-proxy stop # 停止服务
|
|
25
|
+
ellm-proxy restart # 重启(先 stop 后 start,保证最新参数生效,选项同 start)
|
|
26
|
+
ellm-proxy autostart on # Windows 开机自启(注册登录触发的计划任务)
|
|
27
|
+
ellm-proxy autostart off # 关闭开机自启
|
|
28
|
+
ellm-proxy config # 显示配置文件路径
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`start/stop/restart` 基于包内自带的 pm2(局部安装,进程名 `ellm-proxy`):服务由 pm2 守护常驻,关闭终端不影响运行,崩溃自动重启(封顶 10 次,防端口占用无限循环),日志写 `<appDir>/logs/`。服务要求的 Node ≥22.13 由 CLI 解析(当前 node 满足则直接用,否则经 get-node 自动下载一次并缓存),终端默认 node 版本无关。start/stop 成功后自动 `pm2 dump`,可随时用 `pm2 resurrect` 恢复。Windows、Linux、macOS 均可用;运行状态用 `pm2 ls` 查看。
|
|
32
|
+
|
|
33
|
+
**开机自启(跨平台)**:`ellm-proxy autostart on` 注册登录触发的自启项(内容为 `pm2 resurrect`),三平台均无需管理员权限——Windows 写启动文件夹 `.cmd`、macOS 写 LaunchAgent(`launchctl load`)、Linux 写 systemd user unit(`systemctl --user enable`,WSL/无 systemd 环境会报错提示);`autostart off` 移除。
|
|
34
|
+
|
|
35
|
+
## 运行时布局(默认 `~/.ellm-proxy/`,均可被环境变量覆盖)
|
|
36
|
+
|
|
37
|
+
| 内容 | 默认路径 | 环境变量覆盖 |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| 配置文件 | `~/.ellm-proxy/ellm.config.json` | `ELLM_CONFIG`(或 `start --config <path>`) |
|
|
40
|
+
| 数据目录(sqlite 日志/缓存) | `~/.ellm-proxy/data/` | `ELLM_DATA_DIR`(或 `start --data-dir <path>`) |
|
|
41
|
+
| 应用目录(配置/数据基准) | `~/.ellm-proxy/` | `ELLM_APP_DIR`(CLI 按 `--working-dir` 自动注入) |
|
|
42
|
+
| web-ui 静态资源 | 包内 `dist/web-ui/`(manager 托管) | `ELLM_WEBUI_DIR`(可选覆盖;manager 按自身位置自动推导) |
|
|
43
|
+
| 运行日志 | `~/.ellm-proxy/logs/` | `start --working-dir <path>`(见 `ellm-proxy -h`) |
|
|
44
|
+
|
|
45
|
+
所有路径均支持相对路径(按当前工作目录展开)与绝对路径。服务端自身不加载任何 `.env` 文件;`ELLM_MASTER_KEY` 等环境变量直接在会话中导出即可。
|
|
46
|
+
|
|
47
|
+
首次执行 `ellm-proxy start` 会自动创建示例配置,之后两种方式修改:
|
|
48
|
+
|
|
49
|
+
1. 直接编辑配置文件;
|
|
50
|
+
2. 启动服务后访问管理界面 `http://127.0.0.1:<主端口+1>/` 在线修改(实时热更新)。
|
|
51
|
+
|
|
52
|
+
其他环境变量:`ELLM_PORT`(网关监听端口,或 `start --port`;管理服务固定 `ELLM_PORT + 1`,可用 `ELLM_MANAGER_PORT` 覆盖)、`HOST`(监听地址)、`ELLM_MASTER_KEY`(网关主密钥,低于配置文件 `masterKey` 字段)。启动时端口若被占用会自动顺延到下一个空闲端口(仅本次运行生效,不改配置文件),顺延结果会打印在启动摘要中。
|
|
53
|
+
|
|
54
|
+
## 本地开发(仓库内)
|
|
55
|
+
|
|
56
|
+
本包是 `ellm` monorepo 的发布载体:发布版 `dist/server.js` 由 `scripts/build-server.mjs` 从 `backend` 源码直接构建(esbuild 插件在构建期把路径模块替换为 `release/runtime-dir.ts` 包模式实现,backend 源码保持单模式零分支),`web-ui` 产物由 `pnpm build:web` 生成后拷入 `dist/web-ui/`(manager 托管):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pnpm pack:proxy # 构建 web-ui → 构建发布版 + 聚合 → npm pack 生成 tgz
|
|
60
|
+
```
|
|
@@ -1,213 +1,37 @@
|
|
|
1
|
-
// autostart on|off
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function windowsOn(nodePath, pm2Js) {
|
|
41
|
-
// cmd 内容全 ASCII(含中文的注释交给外部帮助输出,避免 cmd 在 GBK 代码页下乱码)
|
|
42
|
-
const body = [
|
|
43
|
-
"@echo off",
|
|
44
|
-
`rem Auto-generated by "ellm-proxy autostart on". Disable with "ellm-proxy autostart off".`,
|
|
45
|
-
`"${nodePath}" "${pm2Js}" resurrect >nul 2>&1`,
|
|
46
|
-
"",
|
|
47
|
-
].join("\r\n");
|
|
48
|
-
const { itemPath } = windowsPaths();
|
|
49
|
-
writeFileSync(itemPath, body, "utf-8");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function windowsOff() {
|
|
53
|
-
const { itemPath } = windowsPaths();
|
|
54
|
-
if (!existsSync(itemPath)) return false;
|
|
55
|
-
rmSync(itemPath, { force: true });
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// —— macOS:LaunchAgent plist ——————————————————————————————————————————
|
|
60
|
-
|
|
61
|
-
function darwinPaths() {
|
|
62
|
-
return { itemPath: join(homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`) };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async function darwinOn(nodePath, pm2Js) {
|
|
66
|
-
const { itemPath } = darwinPaths();
|
|
67
|
-
const logPath = join(defaultAppDir, "logs", "autostart.log");
|
|
68
|
-
mkdirSync(join(defaultAppDir, "logs"), { recursive: true });
|
|
69
|
-
const body = [
|
|
70
|
-
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
71
|
-
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
72
|
-
'<plist version="1.0">',
|
|
73
|
-
"<dict>",
|
|
74
|
-
` <key>Label</key><string>${PLIST_LABEL}</string>`,
|
|
75
|
-
" <key>ProgramArguments</key>",
|
|
76
|
-
" <array>",
|
|
77
|
-
` <string>${nodePath}</string>`,
|
|
78
|
-
` <string>${pm2Js}</string>`,
|
|
79
|
-
" <string>resurrect</string>",
|
|
80
|
-
" </array>",
|
|
81
|
-
" <key>RunAtLoad</key><true/>",
|
|
82
|
-
` <key>StandardOutPath</key><string>${logPath}</string>`,
|
|
83
|
-
` <key>StandardErrorPath</key><string>${logPath}</string>`,
|
|
84
|
-
"</dict>",
|
|
85
|
-
"</plist>",
|
|
86
|
-
"",
|
|
87
|
-
].join("\n");
|
|
88
|
-
writeFileSync(itemPath, body, "utf-8");
|
|
89
|
-
// 先卸载旧定义再加载(幂等;未加载过时 unload 报错属正常)
|
|
90
|
-
await runExit("launchctl", ["unload", itemPath]);
|
|
91
|
-
const code = await runExit("launchctl", ["load", itemPath]);
|
|
92
|
-
if (code !== 0) {
|
|
93
|
-
throw new Error(`launchctl load 失败(退出码 ${code})。请手动执行: launchctl load "${itemPath}"`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function darwinOff() {
|
|
98
|
-
const { itemPath } = darwinPaths();
|
|
99
|
-
if (!existsSync(itemPath)) return false;
|
|
100
|
-
await runExit("launchctl", ["unload", itemPath]);
|
|
101
|
-
rmSync(itemPath, { force: true });
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// —— Linux:systemd user unit ——————————————————————————————————————————
|
|
106
|
-
|
|
107
|
-
function linuxPaths() {
|
|
108
|
-
return { itemPath: join(homedir(), ".config", "systemd", "user", LINUX_UNIT) };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async function linuxOn(nodePath, pm2Js) {
|
|
112
|
-
const { itemPath } = linuxPaths();
|
|
113
|
-
mkdirSync(join(homedir(), ".config", "systemd", "user"), { recursive: true });
|
|
114
|
-
const body = [
|
|
115
|
-
"[Unit]",
|
|
116
|
-
"Description=ellm-proxy autostart (pm2 resurrect)",
|
|
117
|
-
"After=default.target",
|
|
118
|
-
"",
|
|
119
|
-
"[Service]",
|
|
120
|
-
"Type=oneshot",
|
|
121
|
-
`ExecStart="${nodePath}" "${pm2Js}" resurrect`,
|
|
122
|
-
"",
|
|
123
|
-
"[Install]",
|
|
124
|
-
"WantedBy=default.target",
|
|
125
|
-
"",
|
|
126
|
-
].join("\n");
|
|
127
|
-
writeFileSync(itemPath, body, "utf-8");
|
|
128
|
-
const reload = await runExit("systemctl", ["--user", "daemon-reload"]);
|
|
129
|
-
if (reload !== 0) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
`systemctl --user daemon-reload 失败(退出码 ${reload})。当前环境可能无 systemd(WSL/容器),请手动启用或删除: ${itemPath}`,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
const enable = await runExit("systemctl", ["--user", "enable", LINUX_UNIT]);
|
|
135
|
-
if (enable !== 0) {
|
|
136
|
-
throw new Error(
|
|
137
|
-
`systemctl --user enable 失败(退出码 ${enable})。请手动执行: systemctl --user enable ${LINUX_UNIT}`,
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async function linuxOff() {
|
|
143
|
-
const { itemPath } = linuxPaths();
|
|
144
|
-
if (!existsSync(itemPath)) return false;
|
|
145
|
-
await runExit("systemctl", ["--user", "disable", LINUX_UNIT]); // 容错:未启用过时报错不影响删除
|
|
146
|
-
rmSync(itemPath, { force: true });
|
|
147
|
-
await runExit("systemctl", ["--user", "daemon-reload"]);
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// —— 命令入口:平台分支 ————————————————————————————————————————————————
|
|
152
|
-
|
|
153
|
-
async function autostartOn() {
|
|
154
|
-
const nodePath = await resolveInterpreter();
|
|
155
|
-
const pm2Js = pm2BinJs();
|
|
156
|
-
let itemPath;
|
|
157
|
-
switch (platform()) {
|
|
158
|
-
case "win32":
|
|
159
|
-
itemPath = windowsPaths().itemPath;
|
|
160
|
-
await windowsOn(nodePath, pm2Js);
|
|
161
|
-
break;
|
|
162
|
-
case "darwin":
|
|
163
|
-
itemPath = darwinPaths().itemPath;
|
|
164
|
-
await darwinOn(nodePath, pm2Js);
|
|
165
|
-
break;
|
|
166
|
-
case "linux":
|
|
167
|
-
itemPath = linuxPaths().itemPath;
|
|
168
|
-
await linuxOn(nodePath, pm2Js);
|
|
169
|
-
break;
|
|
170
|
-
default:
|
|
171
|
-
throw new Error(`暂不支持的平台: ${platform()}。可改用 pm2 自带的 pm2 startup。`);
|
|
172
|
-
}
|
|
173
|
-
console.log("开机自启已开启(登录时触发):");
|
|
174
|
-
console.log(` 自启项 : ${itemPath}(pm2 resurrect 恢复服务)`);
|
|
175
|
-
console.log(" 禁用方式 : ellm-proxy autostart off");
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async function autostartOff() {
|
|
179
|
-
let removed;
|
|
180
|
-
switch (platform()) {
|
|
181
|
-
case "win32":
|
|
182
|
-
removed = await windowsOff();
|
|
183
|
-
break;
|
|
184
|
-
case "darwin":
|
|
185
|
-
removed = await darwinOff();
|
|
186
|
-
break;
|
|
187
|
-
case "linux":
|
|
188
|
-
removed = await linuxOff();
|
|
189
|
-
break;
|
|
190
|
-
default:
|
|
191
|
-
throw new Error(`暂不支持的平台: ${platform()}。可改用 pm2 自带的 pm2 startup。`);
|
|
192
|
-
}
|
|
193
|
-
if (!removed) {
|
|
194
|
-
console.log("未找到自启项(可能未开启开机自启),无需操作。");
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
console.log("开机自启已关闭(自启项已移除)。");
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export function register(cli, run) {
|
|
201
|
-
cli
|
|
202
|
-
.command(
|
|
203
|
-
"autostart <action>",
|
|
204
|
-
"开机自启(登录时触发):on=注册自启项(Win 启动文件夹/mac LaunchAgent/Linux systemd user),off=移除",
|
|
205
|
-
)
|
|
206
|
-
.action((action) => {
|
|
207
|
-
if (action !== "on" && action !== "off") {
|
|
208
|
-
console.error(`未知参数: ${action}(用法: ellm-proxy autostart on|off)`);
|
|
209
|
-
process.exit(1);
|
|
210
|
-
}
|
|
211
|
-
return run(action === "on" ? autostartOn : autostartOff);
|
|
212
|
-
});
|
|
213
|
-
}
|
|
1
|
+
// autostart on|off 命令(CLI 薄壳):平台实现与状态探测在 utils/autostart.js(被管理服务复用),
|
|
2
|
+
// 本文件只做命令装配与人读输出。
|
|
3
|
+
import { autostartStatus, enableAutostart, disableAutostart } from "../../utils/autostart.js";
|
|
4
|
+
|
|
5
|
+
async function autostartOn() {
|
|
6
|
+
const { itemPath } = await enableAutostart();
|
|
7
|
+
console.log("开机自启已开启(登录时触发):");
|
|
8
|
+
console.log(` 自启项 : ${itemPath}(pm2 resurrect 恢复服务)`);
|
|
9
|
+
console.log(" 禁用方式 : ellm-proxy autostart off");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function autostartOff() {
|
|
13
|
+
const { removed } = await disableAutostart();
|
|
14
|
+
if (!removed) {
|
|
15
|
+
console.log("未找到自启项(可能未开启开机自启),无需操作。");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
console.log("开机自启已关闭(自启项已移除)。");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function register(cli, run) {
|
|
22
|
+
cli
|
|
23
|
+
.command(
|
|
24
|
+
"autostart <action>",
|
|
25
|
+
"开机自启(登录时触发):on=注册自启项(Win 启动文件夹/mac LaunchAgent/Linux systemd user),off=移除",
|
|
26
|
+
)
|
|
27
|
+
.action((action) => {
|
|
28
|
+
if (action !== "on" && action !== "off") {
|
|
29
|
+
console.error(`未知参数: ${action}(用法: ellm-proxy autostart on|off)`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
return run(action === "on" ? autostartOn : autostartOff);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 状态探测保留导出(潜在 CLI status 输出用;当前 manager 走 utils 直连)
|
|
37
|
+
export { autostartStatus };
|
package/bin/commands/config.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// config 命令:显示配置文件路径(不存在时自动创建示例配置)。
|
|
2
|
-
import { ensureConfig } from "../../utils/paths.js";
|
|
3
|
-
|
|
4
|
-
export function register(cli) {
|
|
5
|
-
cli.command("config", "显示配置文件路径(不存在时自动创建示例配置)").action((opts) => {
|
|
6
|
-
console.log(ensureConfig(opts.config));
|
|
7
|
-
});
|
|
8
|
-
}
|
|
1
|
+
// config 命令:显示配置文件路径(不存在时自动创建示例配置)。
|
|
2
|
+
import { ensureConfig } from "../../utils/paths.js";
|
|
3
|
+
|
|
4
|
+
export function register(cli) {
|
|
5
|
+
cli.command("config", "显示配置文件路径(不存在时自动创建示例配置)").action((opts) => {
|
|
6
|
+
console.log(ensureConfig(opts.config));
|
|
7
|
+
});
|
|
8
|
+
}
|
package/bin/commands/pm2.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
// pm2 透传命令:ellm-proxy pm2 <任意 pm2 参数>(如 list/ls/logs/monit/describe/flush)。
|
|
2
|
-
// 用包内局部 pm2 执行,用户无需自装全局 pm2;stdio 直接继承,logs/monit 等交互命令可实时输出、
|
|
3
|
-
// Ctrl-C 退出。透传参数不经 cac 解析(在 CLI 入口先于 cac 拦截),pm2 的 -- 选项原样可达。
|
|
4
|
-
import { spawn } from "node:child_process";
|
|
5
|
-
import { pm2BinJs } from "../../utils/pm2.js";
|
|
6
|
-
|
|
7
|
-
/** 以包内 pm2 CLI 执行任意参数(node 版本无关紧要:pm2 bin 脚本兼容;daemon 连接与 interpreter 无关) */
|
|
8
|
-
export async function doPassthrough(args) {
|
|
9
|
-
if (args.length === 0) {
|
|
10
|
-
args = ["list"]; // 无参数 = 默认展示进程列表
|
|
11
|
-
}
|
|
12
|
-
return new Promise((resolve, reject) => {
|
|
13
|
-
const child = spawn(process.execPath, [pm2BinJs(), ...args], { stdio: "inherit", shell: false });
|
|
14
|
-
child.on("error", reject);
|
|
15
|
-
// pm2 退出码原样透传;exit 回调内 process.exit 结束进程(promise 永不 resolve)
|
|
16
|
-
child.on("exit", (code) => process.exit(code ?? 1));
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function register(cli, run) {
|
|
21
|
-
// cac 仅声明命令用于 -h 展示;实际执行走 CLI 入口的 pm2 拦截(保证 pm2 选项不被 cac 解析吞掉)
|
|
22
|
-
cli
|
|
23
|
-
.command(
|
|
24
|
-
"pm2 [args...]",
|
|
25
|
-
"透传执行包内 pm2 任意子命令(如 list/ls/logs/monit/describe/flush;pm2 的 -- 选项原样透传)",
|
|
26
|
-
)
|
|
27
|
-
.action(() => {});
|
|
28
|
-
}
|
|
1
|
+
// pm2 透传命令:ellm-proxy pm2 <任意 pm2 参数>(如 list/ls/logs/monit/describe/flush)。
|
|
2
|
+
// 用包内局部 pm2 执行,用户无需自装全局 pm2;stdio 直接继承,logs/monit 等交互命令可实时输出、
|
|
3
|
+
// Ctrl-C 退出。透传参数不经 cac 解析(在 CLI 入口先于 cac 拦截),pm2 的 -- 选项原样可达。
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { pm2BinJs } from "../../utils/pm2.js";
|
|
6
|
+
|
|
7
|
+
/** 以包内 pm2 CLI 执行任意参数(node 版本无关紧要:pm2 bin 脚本兼容;daemon 连接与 interpreter 无关) */
|
|
8
|
+
export async function doPassthrough(args) {
|
|
9
|
+
if (args.length === 0) {
|
|
10
|
+
args = ["list"]; // 无参数 = 默认展示进程列表
|
|
11
|
+
}
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const child = spawn(process.execPath, [pm2BinJs(), ...args], { stdio: "inherit", shell: false });
|
|
14
|
+
child.on("error", reject);
|
|
15
|
+
// pm2 退出码原样透传;exit 回调内 process.exit 结束进程(promise 永不 resolve)
|
|
16
|
+
child.on("exit", (code) => process.exit(code ?? 1));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function register(cli, run) {
|
|
21
|
+
// cac 仅声明命令用于 -h 展示;实际执行走 CLI 入口的 pm2 拦截(保证 pm2 选项不被 cac 解析吞掉)
|
|
22
|
+
cli
|
|
23
|
+
.command(
|
|
24
|
+
"pm2 [args...]",
|
|
25
|
+
"透传执行包内 pm2 任意子命令(如 list/ls/logs/monit/describe/flush;pm2 的 -- 选项原样透传)",
|
|
26
|
+
)
|
|
27
|
+
.action(() => {});
|
|
28
|
+
}
|