grok-cli-to-openai-compatible 1.2.7 → 1.4.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.
Files changed (221) hide show
  1. package/.env.example +25 -3
  2. package/README-ZH.md +179 -56
  3. package/README.md +186 -63
  4. package/dist/app.d.ts.map +1 -1
  5. package/dist/app.js +204 -12
  6. package/dist/app.js.map +1 -1
  7. package/dist/cli/commands/admin-panel.d.ts +13 -0
  8. package/dist/cli/commands/admin-panel.d.ts.map +1 -0
  9. package/dist/cli/commands/admin-panel.js +98 -0
  10. package/dist/cli/commands/admin-panel.js.map +1 -0
  11. package/dist/cli/commands/doctor.d.ts +1 -0
  12. package/dist/cli/commands/doctor.d.ts.map +1 -1
  13. package/dist/cli/commands/doctor.js +74 -8
  14. package/dist/cli/commands/doctor.js.map +1 -1
  15. package/dist/cli/commands/logs.d.ts +10 -0
  16. package/dist/cli/commands/logs.d.ts.map +1 -0
  17. package/dist/cli/commands/logs.js +83 -0
  18. package/dist/cli/commands/logs.js.map +1 -0
  19. package/dist/cli/commands/open.d.ts +1 -0
  20. package/dist/cli/commands/open.d.ts.map +1 -1
  21. package/dist/cli/commands/open.js +1 -1
  22. package/dist/cli/commands/open.js.map +1 -1
  23. package/dist/cli/commands/restart.d.ts +1 -0
  24. package/dist/cli/commands/restart.d.ts.map +1 -1
  25. package/dist/cli/commands/restart.js +17 -1
  26. package/dist/cli/commands/restart.js.map +1 -1
  27. package/dist/cli/commands/setup.d.ts.map +1 -1
  28. package/dist/cli/commands/setup.js +12 -0
  29. package/dist/cli/commands/setup.js.map +1 -1
  30. package/dist/cli/commands/start.d.ts +2 -0
  31. package/dist/cli/commands/start.d.ts.map +1 -1
  32. package/dist/cli/commands/start.js +50 -8
  33. package/dist/cli/commands/start.js.map +1 -1
  34. package/dist/cli/commands/status.d.ts +1 -0
  35. package/dist/cli/commands/status.d.ts.map +1 -1
  36. package/dist/cli/commands/status.js +39 -14
  37. package/dist/cli/commands/status.js.map +1 -1
  38. package/dist/cli/commands/stop.d.ts +1 -0
  39. package/dist/cli/commands/stop.d.ts.map +1 -1
  40. package/dist/cli/commands/stop.js +30 -5
  41. package/dist/cli/commands/stop.js.map +1 -1
  42. package/dist/cli/commands/update.d.ts +1 -0
  43. package/dist/cli/commands/update.d.ts.map +1 -1
  44. package/dist/cli/commands/update.js +127 -20
  45. package/dist/cli/commands/update.js.map +1 -1
  46. package/dist/cli/index.js +67 -5
  47. package/dist/cli/index.js.map +1 -1
  48. package/dist/cli/lib/env-file.d.ts +7 -0
  49. package/dist/cli/lib/env-file.d.ts.map +1 -1
  50. package/dist/cli/lib/env-file.js +62 -17
  51. package/dist/cli/lib/env-file.js.map +1 -1
  52. package/dist/cli/lib/pm2-runner.d.ts +14 -0
  53. package/dist/cli/lib/pm2-runner.d.ts.map +1 -0
  54. package/dist/cli/lib/pm2-runner.js +179 -0
  55. package/dist/cli/lib/pm2-runner.js.map +1 -0
  56. package/dist/cli/lib/process-mgr.d.ts +15 -0
  57. package/dist/cli/lib/process-mgr.d.ts.map +1 -1
  58. package/dist/cli/lib/process-mgr.js +111 -22
  59. package/dist/cli/lib/process-mgr.js.map +1 -1
  60. package/dist/cli/lib/runner-info.d.ts +20 -0
  61. package/dist/cli/lib/runner-info.d.ts.map +1 -0
  62. package/dist/cli/lib/runner-info.js +120 -0
  63. package/dist/cli/lib/runner-info.js.map +1 -0
  64. package/dist/cli/lib/spinner.d.ts +20 -0
  65. package/dist/cli/lib/spinner.d.ts.map +1 -0
  66. package/dist/cli/lib/spinner.js +72 -0
  67. package/dist/cli/lib/spinner.js.map +1 -0
  68. package/dist/config/constants.d.ts +31 -0
  69. package/dist/config/constants.d.ts.map +1 -1
  70. package/dist/config/constants.js +103 -2
  71. package/dist/config/constants.js.map +1 -1
  72. package/dist/config/cors.js +1 -1
  73. package/dist/config/cors.js.map +1 -1
  74. package/dist/config/env.d.ts +11 -1
  75. package/dist/config/env.d.ts.map +1 -1
  76. package/dist/config/env.js +43 -3
  77. package/dist/config/env.js.map +1 -1
  78. package/dist/controllers/admin.controller.d.ts +35 -0
  79. package/dist/controllers/admin.controller.d.ts.map +1 -1
  80. package/dist/controllers/admin.controller.js +599 -18
  81. package/dist/controllers/admin.controller.js.map +1 -1
  82. package/dist/controllers/api-key.controller.d.ts.map +1 -1
  83. package/dist/controllers/api-key.controller.js +4 -3
  84. package/dist/controllers/api-key.controller.js.map +1 -1
  85. package/dist/controllers/chat.controller.d.ts.map +1 -1
  86. package/dist/controllers/chat.controller.js +2 -1
  87. package/dist/controllers/chat.controller.js.map +1 -1
  88. package/dist/controllers/document.controller.d.ts.map +1 -1
  89. package/dist/controllers/document.controller.js +3 -2
  90. package/dist/controllers/document.controller.js.map +1 -1
  91. package/dist/dto/admin.dto.d.ts +36 -1
  92. package/dist/dto/admin.dto.d.ts.map +1 -1
  93. package/dist/dto/admin.dto.js +23 -1
  94. package/dist/dto/admin.dto.js.map +1 -1
  95. package/dist/dto/chat.dto.d.ts +73 -0
  96. package/dist/dto/chat.dto.d.ts.map +1 -1
  97. package/dist/dto/chat.dto.js +5 -1
  98. package/dist/dto/chat.dto.js.map +1 -1
  99. package/dist/dto/conversation.dto.d.ts +286 -0
  100. package/dist/dto/conversation.dto.d.ts.map +1 -0
  101. package/dist/dto/conversation.dto.js +62 -0
  102. package/dist/dto/conversation.dto.js.map +1 -0
  103. package/dist/dto/ddos.dto.d.ts +191 -0
  104. package/dist/dto/ddos.dto.d.ts.map +1 -0
  105. package/dist/dto/ddos.dto.js +57 -0
  106. package/dist/dto/ddos.dto.js.map +1 -0
  107. package/dist/entities/api-key.entity.d.ts +2 -0
  108. package/dist/entities/api-key.entity.d.ts.map +1 -1
  109. package/dist/interfaces/auth.interface.d.ts +1 -0
  110. package/dist/interfaces/auth.interface.d.ts.map +1 -1
  111. package/dist/interfaces/express.interface.d.ts +2 -0
  112. package/dist/interfaces/express.interface.d.ts.map +1 -1
  113. package/dist/middlewares/auth.middleware.d.ts.map +1 -1
  114. package/dist/middlewares/auth.middleware.js +30 -3
  115. package/dist/middlewares/auth.middleware.js.map +1 -1
  116. package/dist/middlewares/client-ip.middleware.d.ts +11 -0
  117. package/dist/middlewares/client-ip.middleware.d.ts.map +1 -0
  118. package/dist/middlewares/client-ip.middleware.js +19 -0
  119. package/dist/middlewares/client-ip.middleware.js.map +1 -0
  120. package/dist/middlewares/connection-tracker.d.ts +47 -0
  121. package/dist/middlewares/connection-tracker.d.ts.map +1 -0
  122. package/dist/middlewares/connection-tracker.js +99 -0
  123. package/dist/middlewares/connection-tracker.js.map +1 -0
  124. package/dist/middlewares/rate-limit.middleware.d.ts +9 -2
  125. package/dist/middlewares/rate-limit.middleware.d.ts.map +1 -1
  126. package/dist/middlewares/rate-limit.middleware.js +116 -32
  127. package/dist/middlewares/rate-limit.middleware.js.map +1 -1
  128. package/dist/routes/admin.routes.d.ts.map +1 -1
  129. package/dist/routes/admin.routes.js +38 -0
  130. package/dist/routes/admin.routes.js.map +1 -1
  131. package/dist/routes/v1/chat.routes.d.ts.map +1 -1
  132. package/dist/routes/v1/chat.routes.js +1 -1
  133. package/dist/routes/v1/chat.routes.js.map +1 -1
  134. package/dist/server.js +53 -0
  135. package/dist/server.js.map +1 -1
  136. package/dist/services/abuse-guard.service.d.ts +27 -0
  137. package/dist/services/abuse-guard.service.d.ts.map +1 -0
  138. package/dist/services/abuse-guard.service.js +243 -0
  139. package/dist/services/abuse-guard.service.js.map +1 -0
  140. package/dist/services/api-key.service.d.ts +18 -1
  141. package/dist/services/api-key.service.d.ts.map +1 -1
  142. package/dist/services/api-key.service.js +79 -11
  143. package/dist/services/api-key.service.js.map +1 -1
  144. package/dist/services/chat-admin.service.d.ts +11 -0
  145. package/dist/services/chat-admin.service.d.ts.map +1 -1
  146. package/dist/services/chat-admin.service.js +61 -9
  147. package/dist/services/chat-admin.service.js.map +1 -1
  148. package/dist/services/conversation.service.d.ts +104 -0
  149. package/dist/services/conversation.service.d.ts.map +1 -0
  150. package/dist/services/conversation.service.js +232 -0
  151. package/dist/services/conversation.service.js.map +1 -0
  152. package/dist/services/ddos-policy.service.d.ts +40 -0
  153. package/dist/services/ddos-policy.service.d.ts.map +1 -0
  154. package/dist/services/ddos-policy.service.js +257 -0
  155. package/dist/services/ddos-policy.service.js.map +1 -0
  156. package/dist/services/document.service.d.ts.map +1 -1
  157. package/dist/services/document.service.js +21 -11
  158. package/dist/services/document.service.js.map +1 -1
  159. package/dist/services/ip-blacklist.service.d.ts +40 -0
  160. package/dist/services/ip-blacklist.service.d.ts.map +1 -0
  161. package/dist/services/ip-blacklist.service.js +126 -0
  162. package/dist/services/ip-blacklist.service.js.map +1 -0
  163. package/dist/services/models.service.d.ts +8 -1
  164. package/dist/services/models.service.d.ts.map +1 -1
  165. package/dist/services/models.service.js +18 -3
  166. package/dist/services/models.service.js.map +1 -1
  167. package/dist/services/pm2-config.d.ts +34 -0
  168. package/dist/services/pm2-config.d.ts.map +1 -0
  169. package/dist/services/pm2-config.js +156 -0
  170. package/dist/services/pm2-config.js.map +1 -0
  171. package/dist/services/pm2.service.d.ts +197 -0
  172. package/dist/services/pm2.service.d.ts.map +1 -0
  173. package/dist/services/pm2.service.js +776 -0
  174. package/dist/services/pm2.service.js.map +1 -0
  175. package/dist/services/stats.service.d.ts +36 -0
  176. package/dist/services/stats.service.d.ts.map +1 -1
  177. package/dist/services/stats.service.js +67 -2
  178. package/dist/services/stats.service.js.map +1 -1
  179. package/dist/services/system-health.service.d.ts +30 -0
  180. package/dist/services/system-health.service.d.ts.map +1 -0
  181. package/dist/services/system-health.service.js +234 -0
  182. package/dist/services/system-health.service.js.map +1 -0
  183. package/dist/services/update.service.d.ts +32 -0
  184. package/dist/services/update.service.d.ts.map +1 -1
  185. package/dist/services/update.service.js +176 -41
  186. package/dist/services/update.service.js.map +1 -1
  187. package/dist/services/usage.service.d.ts +43 -0
  188. package/dist/services/usage.service.d.ts.map +1 -0
  189. package/dist/services/usage.service.js +163 -0
  190. package/dist/services/usage.service.js.map +1 -0
  191. package/dist/utils/client-ip.d.ts +41 -0
  192. package/dist/utils/client-ip.d.ts.map +1 -0
  193. package/dist/utils/client-ip.js +172 -0
  194. package/dist/utils/client-ip.js.map +1 -0
  195. package/dist/utils/file-sniff.d.ts +16 -0
  196. package/dist/utils/file-sniff.d.ts.map +1 -0
  197. package/dist/utils/file-sniff.js +151 -0
  198. package/dist/utils/file-sniff.js.map +1 -0
  199. package/dist/utils/ip-match.d.ts +15 -0
  200. package/dist/utils/ip-match.d.ts.map +1 -0
  201. package/dist/utils/ip-match.js +133 -0
  202. package/dist/utils/ip-match.js.map +1 -0
  203. package/dist/utils/stream.d.ts.map +1 -1
  204. package/dist/utils/stream.js +40 -1
  205. package/dist/utils/stream.js.map +1 -1
  206. package/package.json +1 -1
  207. package/prisma/migrations/20260714120000_ip_whitelist_blacklist/migration.sql +19 -0
  208. package/prisma/migrations/20260714220000_chat_conversations/migration.sql +22 -0
  209. package/prisma/migrations/20260714230000_conversation_context/migration.sql +6 -0
  210. package/prisma/schema.prisma +52 -3
  211. package/public/admin/app.js +5696 -375
  212. package/public/admin/assets/logo.svg +37 -0
  213. package/public/admin/boot.js +3 -0
  214. package/public/admin/disabled.html +131 -0
  215. package/public/admin/i18n.js +1567 -0
  216. package/public/admin/index.html +16 -3
  217. package/public/admin/styles.css +3507 -190
  218. package/public/admin/vendor/marked.min.js +6 -0
  219. package/public/admin/vendor/purify.min.js +3 -0
  220. package/scripts/install.sh +8 -27
  221. package/scripts/prepare.cjs +11 -8
package/README.md CHANGED
@@ -15,15 +15,17 @@ Production OpenAI-compatible HTTP gateway for local **[Grok CLI](https://x.ai)**
15
15
  | **npm** | [`grok-cli-to-openai-compatible`](https://www.npmjs.com/package/grok-cli-to-openai-compatible) |
16
16
  | **CLI** | `gctoac` · alias `gcoa` |
17
17
  | **Default port** | **`3847`** |
18
+ | **NODE_ENV default** | **`production`** (set `development` only for local coding) |
18
19
 
19
20
  **What you get**
20
21
 
21
22
  - OpenAI-compatible `POST /v1/chat/completions` (stream + non-stream)
22
23
  - Thinking / `reasoning_content` (DeepSeek-style + Grok `thought`)
23
- - Per-key **safe** / **agent** policy
24
+ - Per-key **safe** / **agent** policy + global safety overrides
24
25
  - AES-256-GCM encryption + full chat audit
25
- - Admin Panel at `/admin` (decrypted prompt I/O, keys, one-click update)
26
- - Control CLI: `gctoac setup | start | stop | status | update`
26
+ - **Admin Panel** dashboard, chats, keys, documents, audit, usage, **DDoS center**, PM2, system update
27
+ - **DDoS / abuse protection** configurable rate limits, multi-rule auto-ban, reverse-proxy client IP (nginx / Cloudflare)
28
+ - Control CLI: setup, start/stop/restart, status, doctor, logs, update, keys, admin on/off
27
29
 
28
30
  ```text
29
31
  Client (OpenAI SDK / curl / Open WebUI)
@@ -31,6 +33,7 @@ Client (OpenAI SDK / curl / Open WebUI)
31
33
 
32
34
  Express Gateway :3847
33
35
  · Auth · rate limit · safe/agent
36
+ · Proxy-aware client IP · auto-ban
34
37
  · Encrypted audit · Admin /admin
35
38
  · gctoac start | stop | status | update
36
39
 
@@ -58,10 +61,10 @@ grok --version
58
61
  ```bash
59
62
  npm install -g grok-cli-to-openai-compatible
60
63
 
61
- gctoac doctor # check Node / Grok / env
62
- gctoac setup # ~/.gctoac, .env, DB, admin API key
64
+ gctoac doctor # Node / Grok / env / runner / proxy checks
65
+ gctoac setup # data home, .env (NODE_ENV=production), DB, admin API key
63
66
  gctoac start # http://127.0.0.1:3847
64
- gctoac status
67
+ gctoac status # runner, port, proxy, health
65
68
  ```
66
69
 
67
70
  Open Admin (paste an **admin API key**):
@@ -70,7 +73,7 @@ Open Admin (paste an **admin API key**):
70
73
  http://127.0.0.1:3847/admin/
71
74
  ```
72
75
 
73
- If you lost the setup key, create a new one anytime:
76
+ If you lost the setup key:
74
77
 
75
78
  ```bash
76
79
  gctoac key create # prints plaintext once
@@ -96,15 +99,21 @@ curl -s http://127.0.0.1:3847/v1/chat/completions \
96
99
 
97
100
  ---
98
101
 
99
- ## Install options
102
+ ## Install
100
103
 
101
- ### Global (recommended)
104
+ **Supported path:** install from the **npm registry** only.
102
105
 
103
106
  ```bash
104
107
  npm install -g grok-cli-to-openai-compatible
105
108
  ```
106
109
 
107
- ### As a project dependency
110
+ Optional helper:
111
+
112
+ ```bash
113
+ curl -fsSL https://raw.githubusercontent.com/yanshekki/Grok-Cli-to-OpenAI-compatible/main/scripts/install.sh | bash
114
+ ```
115
+
116
+ ### Project dependency
108
117
 
109
118
  ```bash
110
119
  npm install grok-cli-to-openai-compatible
@@ -112,7 +121,9 @@ npx gctoac setup
112
121
  npx gctoac start --foreground
113
122
  ```
114
123
 
115
- ### From source
124
+ ### Develop from source (contributors)
125
+
126
+ `dist/` is **not** committed. Build after clone:
116
127
 
117
128
  ```bash
118
129
  git clone https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible.git
@@ -120,28 +131,21 @@ cd Grok-Cli-to-OpenAI-compatible
120
131
  npm install
121
132
  npm run build
122
133
  npm link # optional: put gctoac on PATH
123
- gctoac setup
124
- gctoac start
125
134
  ```
126
135
 
127
- One-shot install script (clones into `~/.gctoac/src` + `npm link`):
128
-
129
- ```bash
130
- curl -fsSL https://raw.githubusercontent.com/yanshekki/Grok-Cli-to-OpenAI-compatible/main/scripts/install.sh | bash
131
- ```
132
-
133
- > Prefer **`npm install -g grok-cli-to-openai-compatible`**.
134
- > Avoid `npm install -g github:yanshekki/...` — it fails on some npm versions.
136
+ > Do **not** use `npm install -g github:…` — unsupported.
135
137
 
136
138
  ### Update
137
139
 
138
140
  ```bash
139
- gctoac update # update package + restart
141
+ npm install -g grok-cli-to-openai-compatible@latest
142
+ # or
143
+ gctoac update # self-update + schedule restart
140
144
  gctoac update --check # check only
141
- gctoac update --no-restart # update without restart
145
+ gctoac update --no-restart
142
146
  ```
143
147
 
144
- Or in Admin → **System** → one-click update.
148
+ Or Admin → **System** → one-click update.
145
149
 
146
150
  ---
147
151
 
@@ -153,39 +157,56 @@ Or in Admin → **System** → one-click update.
153
157
  | `http://127.0.0.1:3847/admin/` | Admin Panel |
154
158
  | `http://127.0.0.1:3847/health` | Health check |
155
159
 
156
- Override with `PORT=` in `.env`, or:
160
+ Change the listen port (persists to `.env`, restarts runner when done from Admin):
157
161
 
158
162
  ```bash
159
- gctoac --port 3847 start
163
+ # CLI writes PORT to .env and starts
164
+ gctoac --port 4000 start
165
+ gctoac --port 4000 start --pm2
166
+
167
+ # or edit .env
168
+ PORT=4000
160
169
  ```
161
170
 
171
+ **Admin → PM2 → Listen port** — default **3847**, save & restart. After change, open Admin on the **new** port (e.g. `http://127.0.0.1:4000/admin/`).
172
+
162
173
  ---
163
174
 
164
175
  ## CLI (`gctoac` / `gcoa`)
165
176
 
177
+ Global options: `--home <path>`, `--port <n>` (default **3847**).
178
+
166
179
  | Command | Description |
167
180
  |---------|-------------|
168
- | `gctoac setup` | Create dirs, `.env`, migrate DB, seed admin key |
169
- | `gctoac start` | Start gateway (background) |
170
- | `gctoac start -f` | Start in foreground |
171
- | `gctoac stop` | Stop background process |
172
- | `gctoac restart` | Restart |
173
- | `gctoac status` | PID + health |
174
- | `gctoac migrate` | Run Prisma migrations |
175
- | `gctoac seed` | Seed admin API key (if missing) |
176
- | `gctoac key` / `gctoac key create` | **Create API key** (prints plaintext once) |
181
+ | `gctoac setup` | Create dirs, `.env`, migrate DB, seed admin key, install pm2 if possible |
182
+ | `gctoac start` | Start gateway (detached gctoac) |
183
+ | `gctoac start -f` | Foreground |
184
+ | `gctoac start --pm2` | Start under PM2 |
185
+ | `gctoac stop` | Stop gctoac + PM2 app + free port orphans |
186
+ | `gctoac restart` | Restart; respects **preferred runner** (PM2 if last used) |
187
+ | `gctoac restart --pm2` | Force restart under PM2 |
188
+ | `gctoac status` | Runner, NODE_ENV, port, trust proxy / IP source, health |
189
+ | `gctoac doctor` | Full env check (proxy, dual-runner, port conflicts, logs size) |
190
+ | `gctoac logs` / `logs show` | Tail pm2 + gctoac log files |
191
+ | `gctoac logs clear` | Truncate log files (same set as Admin clear) |
192
+ | `gctoac admin status` | Admin panel on/off |
193
+ | `gctoac admin on` / `off` | Enable/disable Admin (DB; **only CLI can turn it back on**) |
194
+ | `gctoac migrate` | Prisma migrate deploy |
195
+ | `gctoac seed` | Seed admin API key if missing |
196
+ | `gctoac key` / `key create` | Create API key (plaintext once) |
177
197
  | `gctoac key list` | List keys (prefix only) |
178
198
  | `gctoac key revoke <id>` | Revoke a key |
179
- | `gctoac doctor` | Environment checks |
180
- | `gctoac update` | Self-update then restart |
181
- | `gctoac update --check` | Check for updates only |
199
+ | `gctoac update` | Self-update + restart |
200
+ | `gctoac update --check` | Check only |
182
201
  | `gctoac update --no-restart` | Update without restart |
183
202
  | `gctoac open` | Print API / Admin URLs |
184
- | `gctoac version` | Show version |
203
+ | `gctoac version` | Package version |
185
204
 
186
205
  ```bash
187
206
  gctoac --home ~/.gctoac-alt setup
188
207
  gctoac --port 3847 start
208
+ gctoac status
209
+ gctoac logs clear
189
210
  ```
190
211
 
191
212
  ---
@@ -196,12 +217,15 @@ gctoac --port 3847 start
196
217
  |---------|---------|
197
218
  | OpenAI API | `POST /v1/chat/completions` (stream + non-stream), `GET /v1/models` |
198
219
  | Thinking | `reasoning_content` + Grok `thought` + `grok.*` meta |
199
- | Documents | Encrypted upload; attach via `document_ids` |
220
+ | Documents | Type-sniffed upload, encrypted storage (DB or filesystem), download |
200
221
  | Safe / Agent | Per-key policy; optional global force-safe |
201
222
  | Encryption | AES-256-GCM for prompts, responses, files |
202
- | Admin Panel | Dashboard, decrypted chat I/O, keys, docs, audit, settings, update |
203
- | CLI | Lifecycle + self-update |
204
- | Ops | SQLite, PM2, GitHub Actions CI |
223
+ | Chat history | Multi-turn conversations, context modes (full / summary / recent) |
224
+ | Admin Panel | Dashboard, chats, keys, docs, audit, usage, DDoS, PM2, system |
225
+ | DDoS center | Live connections, blacklist, auto-ban rules, presets, runtime policy |
226
+ | Reverse proxy | Trust hops + CF / nginx / X-Forwarded-For client IP |
227
+ | CLI | Lifecycle, preferred runner, logs, self-update |
228
+ | Ops | SQLite, PM2, log auto-trim (>5 MB), GitHub Actions CI |
205
229
 
206
230
  ---
207
231
 
@@ -284,6 +308,7 @@ console.log(res.choices[0].message.content);
284
308
  | POST | `/v1/documents` | Upload (`file` field) |
285
309
  | GET/DELETE | `/v1/documents`… | List / soft-delete |
286
310
  | POST/GET/DELETE | `/v1/api-keys`… | Admin key management |
311
+ | * | `/admin/api/*` | Admin JSON API (`role=admin`) |
287
312
 
288
313
  ---
289
314
 
@@ -294,7 +319,7 @@ console.log(res.choices[0].message.content);
294
319
  | **`safe`** (default for clients) | External apps | Sandbox cwd, no always-approve, restricted tools, shorter timeout |
295
320
  | **`agent`** | Trusted / internal | Full CLI tools (optional always-approve); cwd still allowlisted |
296
321
 
297
- - Force all keys safe: `GROK_SAFE_MODE=true` or Admin → Safety
322
+ - Force all keys safe: `GROK_SAFE_MODE=true` or Admin → **Safety**
298
323
  - Clients **cannot** escalate via request body
299
324
  - Do **not** expose `agent` keys on the public internet
300
325
 
@@ -308,25 +333,67 @@ http://127.0.0.1:3847/admin/
308
333
 
309
334
  | Page | Features |
310
335
  |------|----------|
311
- | Dashboard | Stats, recent chats, concurrency |
312
- | Chats | Full **decrypted** prompt / reasoning / response |
313
- | API Keys | Create, edit mode/role/rate limit, revoke |
314
- | Documents | List, decrypt preview, delete |
315
- | Audit Logs | Action history |
316
- | Safety | Global safe mode, tools, timeouts |
317
- | System | Health, versions, **one-click update & restart** |
336
+ | **Dashboard** | 24h KPIs, success rate, protection snapshot, models, runtime (port / encryption) |
337
+ | **Chat** | Multi-turn playground, history, context modes, attachments |
338
+ | **Chat logs** | Search / filter / pager; full **decrypted** prompt / reasoning / response |
339
+ | **API Keys** | Create / edit mode / role / rate limit / IP whitelist; revoke |
340
+ | **Documents** | Search / filter / pager; preview, download, delete; storage DB vs filesystem |
341
+ | **Audit Logs** | Search / filter / pager; human-readable actions |
342
+ | **Usage & limits** | 24h stats, by-model / by-key tabs, gateway limit summary |
343
+ | **DDoS center** | Live connections, blacklist, auto-ban events, **runtime protection policy** (presets: relaxed / balanced / strict / custom), reverse-proxy IP settings |
344
+ | **Safety** | Global safe mode, tools, timeouts |
345
+ | **PM2** | Runner switch (gctoac ↔ PM2), **listen port** (default 3847), config, **clear logs** + auto-trim |
346
+ | **System** | Health, software checks, one-click update & restart |
318
347
 
319
348
  Admin API: `/admin/api/*` (requires `role=admin`).
320
349
 
350
+ ### DDoS / abuse (runtime)
351
+
352
+ Policy is stored in the database (Admin → DDoS). Env values are **initial defaults** only; after first save, Admin is authoritative. Reset via **Reset to env defaults**.
353
+
354
+ | Capability | Notes |
355
+ |------------|--------|
356
+ | Rate limits | Window, max per key, max per IP, chat burst |
357
+ | Auto-ban rules | Failed auth, repeated 429, concurrent flood, request velocity, escalation |
358
+ | Presets | Relaxed / Balanced / Strict / Custom (auto-detected) |
359
+ | Whitelist | Never auto-banned (e.g. `127.0.0.1`) |
360
+ | Manual ban | TTL or permanent |
361
+
362
+ ### Reverse proxy / CDN (client IP)
363
+
364
+ Behind **nginx** or **Cloudflare**, configure so bans, rate limits, and audit use the **real client IP**:
365
+
366
+ | Setting | Typical value |
367
+ |---------|----------------|
368
+ | Trust proxy hops | `1` = nginx or CF→app; `2` = CF→nginx→app; `0` = direct only |
369
+ | IP source | `auto` (recommended), `cloudflare`, `nginx`, `x-forwarded-for`, `socket` |
370
+
371
+ Set in **Admin → DDoS → Reverse proxy**, or env:
372
+
373
+ ```env
374
+ TRUST_PROXY=1
375
+ PROXY_IP_SOURCE=auto
376
+ ```
377
+
378
+ Example nginx:
379
+
380
+ ```nginx
381
+ proxy_set_header Host $host;
382
+ proxy_set_header X-Real-IP $remote_addr;
383
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
384
+ proxy_set_header X-Forwarded-Proto $scheme;
385
+ ```
386
+
321
387
  ---
322
388
 
323
389
  ## Environment variables
324
390
 
325
- See [`.env.example`](./.env.example).
391
+ See [`.env.example`](./.env.example). Fresh `gctoac setup` writes **`NODE_ENV=production`**.
326
392
 
327
393
  | Variable | Description |
328
394
  |----------|-------------|
329
- | `PORT` | Default **`3847`** |
395
+ | `NODE_ENV` | Default **`production`**. Use `development` only for local coding (pretty logs) |
396
+ | `PORT` | Default **`3847`** (also editable in Admin → PM2) |
330
397
  | `DATABASE_URL` | SQLite, e.g. `file:../data/gateway.db` (relative to `prisma/`) |
331
398
  | `ENCRYPTION_KEY` | 32-byte key: `openssl rand -base64 32` |
332
399
  | `GROK_BIN` | Default `grok` |
@@ -335,16 +402,35 @@ See [`.env.example`](./.env.example).
335
402
  | `GROK_ALWAYS_APPROVE` | Agent only; off in safe mode |
336
403
  | `GROK_SAFE_MODE` | Force all keys to safe |
337
404
  | `GROK_MAX_CONCURRENT` | Max parallel Grok processes |
338
- | `ADMIN_PANEL_ENABLED` | Toggle `/admin` |
339
- | `CORS_ORIGINS` | Comma-separated origins |
405
+ | `ADMIN_PANEL_ENABLED` | Hard off for `/admin` (env; restart). Runtime: `gctoac admin on\|off` |
406
+ | `PM2_ADMIN_ENABLED` | Allow Admin PM2 controls |
407
+ | `CORS_ORIGINS` | Comma-separated origins (update when changing `PORT`) |
408
+ | `RATE_LIMIT_*` / `CHAT_BURST_MAX` / `BLOCK_*` | Initial rate-limit / auto-auth defaults (overridden by DDoS policy after save) |
409
+ | `TRUST_PROXY` | Proxy hops: `0` / `1` / `2`… (`true`→1, `false`→0) |
410
+ | `PROXY_IP_SOURCE` | `auto` \| `cloudflare` \| `nginx` \| `x-forwarded-for` \| `socket` |
340
411
  | `GCTOAC_HOME` | CLI data home (default `~/.gctoac`) |
341
- | `STORAGE_DIR` | Encrypted files + sandboxes |
412
+ | `STORAGE_DIR` | Encrypted large files + sandboxes |
413
+ | `UPLOAD_MAX_BYTES` / `DOCUMENT_DB_MAX_BYTES` | Upload / DB vs filesystem threshold |
342
414
 
343
415
  **Back up `ENCRYPTION_KEY`.** If lost, historical data cannot be decrypted.
344
416
 
345
417
  ---
346
418
 
347
- ## Production (PM2)
419
+ ## Production
420
+
421
+ ### Recommended: CLI
422
+
423
+ ```bash
424
+ gctoac setup
425
+ gctoac start # detached gctoac
426
+ # or
427
+ gctoac start --pm2 # under PM2
428
+ gctoac status
429
+ ```
430
+
431
+ `gctoac restart` follows the last **preferred runner** (gctoac or PM2).
432
+
433
+ ### PM2 ecosystem
348
434
 
349
435
  ```bash
350
436
  npm run build
@@ -352,7 +438,21 @@ pm2 start ecosystem.config.cjs
352
438
  pm2 logs grok-openai-gateway
353
439
  ```
354
440
 
355
- Or simply: `gctoac start` (background; pid under data home).
441
+ ### Logs
442
+
443
+ - Files under `logs/` (or data home): `pm2-error.log`, `pm2-out.log`, `gctoac.*.log`
444
+ - **Admin → PM2 → Clear logs**, or `gctoac logs clear`
445
+ - **Auto-trim:** each log read trims files **> 5 MB** down to the last ~512 KB
446
+
447
+ ### Avoid EADDRINUSE
448
+
449
+ Only one runner should bind the port. If both gctoac and PM2 race:
450
+
451
+ ```bash
452
+ gctoac stop
453
+ gctoac start # or: gctoac start --pm2
454
+ gctoac doctor # flags mixed runners
455
+ ```
356
456
 
357
457
  ---
358
458
 
@@ -362,7 +462,7 @@ Or simply: `gctoac start` (background; pid under data home).
362
462
  src/ TypeScript (app, routes, services, cli)
363
463
  public/admin/ Admin SPA
364
464
  prisma/ Schema, migrations, seed
365
- dist/ Built JS (published on npm)
465
+ dist/ Built JS (gitignored; created by npm run build / prepublishOnly)
366
466
  scripts/ prepare, install.sh
367
467
  tests/ Vitest
368
468
  ```
@@ -372,19 +472,20 @@ tests/ Vitest
372
472
  ## Scripts
373
473
 
374
474
  ```bash
375
- npm run dev # development
376
- npm run build # compile + prisma generate
475
+ npm run dev # development (tsx watch)
476
+ npm run build # prisma generate + tsc
377
477
  npm start # node dist/server.js
378
478
  npm test # unit + integration
379
479
  npm run db:setup # migrate + seed
380
- gctoac setup|start|status|stop|doctor|update
480
+ gctoac setup|start|status|stop|doctor|logs|update
381
481
  ```
382
482
 
383
483
  ### Publish (maintainers)
384
484
 
485
+ `prepublishOnly` runs `npm run build` so the tarball includes `dist/`.
486
+
385
487
  ```bash
386
488
  npm login
387
- npm run build
388
489
  npm publish --access public --otp=<2FA_CODE>
389
490
  ```
390
491
 
@@ -395,7 +496,29 @@ npm publish --access public --otp=<2FA_CODE>
395
496
  - API keys stored as **SHA-256 hashes** only
396
497
  - Chat + documents encrypted at rest with **AES-256-GCM**
397
498
  - Prefer **`safe`** keys for any external client
499
+ - **Client IP:** `CF-Connecting-IP` / `X-Real-IP` / `X-Forwarded-For` are trusted **only** when the TCP peer is in **Trusted proxy IPs** (default `127.0.0.1`). Direct clients cannot spoof headers to bypass rate limits or ban others.
500
+ - Expose Admin only on localhost/VPN; admin bearer lives in `sessionStorage` (XSS = full takeover)
398
501
  - Never commit `.env` or share admin keys
502
+ - Admin can be fully disabled: `gctoac admin off` (re-enable only via `gctoac admin on`)
503
+ - One-click update / PM2 / port change require admin role (treat admin keys as root)
504
+
505
+ ---
506
+
507
+ ## 👤 Creator
508
+
509
+ **Ki (yanshekki)** — Full-stack developer, quant trader, founder of [YSK Limited](https://ysk.hk/).
510
+
511
+ 🌐 [linktr.ee/yanshekki](https://linktr.ee/yanshekki) · 🏢 [ysk.hk](https://ysk.hk/)
512
+
513
+ ### ☕ Support / Donate
514
+
515
+ If this Grok → OpenAI gateway helps your work, consider buying me a coffee!
516
+
517
+ | Network | Address |
518
+ | --- | --- |
519
+ | **EVM** (ETH/BSC/AVAX) | `yanshekki.eth` |
520
+ | **NEAR** | `yanshekki.near` |
521
+ | **ADA** (Cardano) | `$yanshekki` |
399
522
 
400
523
  ---
401
524
 
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAaA,OAAO,gCAAgC,CAAC;AAExC,wBAAgB,SAAS,gDAyDxB"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AA4BA,OAAO,gCAAgC,CAAC;AAwCxC,wBAAgB,SAAS,gDAkLxB"}