grok-cli-to-openai-compatible 1.7.4 → 1.7.5

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/CHANGELOG.md ADDED
@@ -0,0 +1,328 @@
1
+ # Changelog
2
+
3
+ [中文](./CHANGELOG.zh.md)
4
+
5
+ Newest first. Each version is grouped by category. Empty categories are omitted.
6
+
7
+ Categories: **New features**, **Improvements**, **Fixes**, **Security**, **Dependency upgrades**, **Internal/CI**.
8
+
9
+ [README.md](./README.md) and [README-ZH.md](./README-ZH.md) list only the latest three versions. This file is the full history.
10
+
11
+ Entries come from git history, tags, and [GitHub Releases](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases). A version that appears in `package.json` history but was never published to npm is marked. npm dates are the registry publish time in Hong Kong (UTC+8). Commit subjects are not rewritten into claims the commits do not make.
12
+
13
+ ## [1.7.5] - 2026-10-05
14
+
15
+ ### Improvements
16
+
17
+ - README links the product page ([ysk.hk/products/gctoac](https://ysk.hk/products/gctoac), English: [ysk.hk/en/products/gctoac](https://ysk.hk/en/products/gctoac)). (`ac63380`)
18
+
19
+ ### Internal/CI
20
+
21
+ - Publish from a pushed `vX.Y.Z` tag with `.github/workflows/release.yml`. Authentication is npm Trusted Publishing (OIDC) with provenance. The workflow does not use an npm token or a GitHub environment.
22
+ - A re-run skips `npm publish` when that version is already on the registry, checks `npm view grok-cli-to-openai-compatible@<version>`, and creates the GitHub Release only when it is missing.
23
+ - CI `actions/checkout` and `actions/setup-node` move from v4 to v7. The publish job uses Node 24 so the bundled npm is 11.5.1 or newer.
24
+ - Changelogs: the READMEs keep the latest three versions, by category. Older versions live in this file and `CHANGELOG.zh.md`.
25
+
26
+ ## [1.7.4] - 2026-08-14
27
+
28
+ Tag [`v1.7.4`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.4). Published to npm.
29
+
30
+ ### Fixes
31
+
32
+ - `/v1/images/generations` returns the Imagine image when Grok CLI exits 1 after the file was written (`maxTurns` / failed `use_tool` copies). 1.7.3 harvested session `images/` only after a clean stream, so the error was thrown before collect. The gateway recovers this run’s session images and sandbox `output.*`, polls and copies during the stream, and for `n=1` stops the process once a file is in hand. (`caadf98`)
33
+
34
+ ### Internal/CI
35
+
36
+ - Rebuild `public/admin/boot.js` for the v1.7.3 i18n strings. (`922a5f1`)
37
+
38
+ ## [1.7.3] - 2026-08-14
39
+
40
+ Tag [`v1.7.3`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.3). Published to npm.
41
+
42
+ ### Fixes
43
+
44
+ - `/v1/images/generations` returns the image when Grok Imagine wrote it only under this run’s `~/.grok/sessions/<encoded-cwd>/<uuid>/images/` and the sandbox has no `output.png`. The media-run agent has no bash to copy the file. The gateway copies the newest file for this run into sandbox `output.*`. Collect order stays sandbox-root `output.*`, then the sandbox, then this run’s session `images/`. A 502 `no_image_in_sandbox` happens only when nothing was written. (`e4efd6f`)
45
+
46
+ ### Improvements
47
+
48
+ - README and README-ZH document the images request, the harvest path, and `/v1/images/*` plus `/v1/media/assets/*`. (`634acfb`)
49
+
50
+ ## [1.7.2] - 2026-08-13
51
+
52
+ Tag [`v1.7.2`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.2). Published to npm.
53
+
54
+ ### Fixes
55
+
56
+ - Generate and edit pass a tools allowlist (`image_gen` / `image_edit`) so the agent cannot `web_fetch` or call `image_edit` first. The collector walks the sandbox, prefers `output.png`, and still returns `refs/*.jpg` when the root file is missing. (`5213dd4`)
57
+ - Let `readdir` infer `Dirent` so `tsc` can publish. (`91babc6`)
58
+
59
+ ## [1.7.1] - 2026-08-13
60
+
61
+ Tag [`v1.7.1`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.1). Published to npm.
62
+
63
+ ### Fixes
64
+
65
+ - Admin data tables become labeled cards on narrow screens. Dashboard KPI, safety, and runtime values and shortcut buttons no longer clip. Playground settings collapse so the transcript stays visible and the composer stays at the bottom. (`d23ab46`, `d9d2a06`)
66
+ - `gctoac restart` falls back from PM2 when `pm2` is not on `PATH`. (`6c62299`)
67
+
68
+ ### Internal/CI
69
+
70
+ - Tests refuse a live `POST /admin/api/system/update` when `NODE_ENV=test` or Vitest is running, so `npm install` / `prisma generate` cannot break Vitest workers. Vitest workers are stabilized. (`6c62299`, `be2ad7a`)
71
+
72
+ ## [1.7.0] - 2026-08-13
73
+
74
+ Tag [`v1.7.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.0). Published to npm.
75
+
76
+ ### New features
77
+
78
+ - Admin → Support page: GitHub Sponsors, Linktree, crypto addresses, YSK Limited, and `mailto:email@ysk.hk`. Static page, no new API. (`4b49034`)
79
+
80
+ ### Improvements
81
+
82
+ - Admin and README zh-Hant copy is Hong Kong written Chinese. (`83a1be0`)
83
+ - Document Grok 1.0.3 Admin and API surfaces in English and Chinese. (`787bcfb`)
84
+
85
+ ### Fixes
86
+
87
+ - Replace the DOM `RequestRedirect` type so `tsc` can publish. (`2f1a12d`)
88
+
89
+ ### Security
90
+
91
+ - Safe mode no longer accepts client `tools`, `allow`, `permission`, `sandbox`, or `agent`. Vision fetch blocks private and metadata hosts and does not follow open redirects. Default agent cwd is `storage/workspaces/default`; the cwd allowlist uses `realpath`. The Grok child environment is a whitelist. The Admin API is rate-limited. OTP is single-use. Git `gctoac update` installs production dependencies unless `GCTOAC_UPDATE_DEV=1`. (`0274353`)
92
+ - `resume` is tenant-scoped, the video IDOR fallback is removed, and the Grok cwd is pinned. (`f183ae9`)
93
+ - OTP-created rows stay on an admin key. The last admin cannot be revoked. (`babec8b`)
94
+ - Ignore a spoofed `CF-Connecting-IP` behind nginx. (`385176c`)
95
+
96
+ ## [1.6.1] - 2026-08-13
97
+
98
+ Tag [`v1.6.1`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.6.1). Published to npm.
99
+
100
+ ### Fixes
101
+
102
+ - Git-channel `gctoac update` installs devDependencies so the build can compile. `.env` sets `NODE_ENV=production`, which had omitted `@types/*` and Vite. (`017cf6d`)
103
+ - Admin → System: Grok inspect cards line up, and the Grok sessions tab always shows the session count. (`f01df63`)
104
+
105
+ ## [1.6.0] - 2026-08-13
106
+
107
+ Tag [`v1.6.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.6.0). Published to npm.
108
+
109
+ ### New features
110
+
111
+ - Align the gateway with Grok Build 1.0.3. Session create is once, then `--resume`. Dropped `--best-of-n` and `--check`. Client `session_id` is mapped per API key. ACP events and cost are parsed. Default model is `grok-4.6`. Inspect, effort, 1–15s video, and URL vision are exposed. (`4c5d2a2`)
112
+ - List and delete local Grok Build sessions. (`c67f3a8`)
113
+ - Playground: Grok session resume and fork, and tool chips. (`989447a`)
114
+ - `reference_to_video` with preset voices. (`73f6daa`)
115
+ - Stream Grok `tool_call` and `plan` events on the OpenAI SSE stream. (`ea2de7d`)
116
+ - Playground memory, plan, and permission controls. (`d9443f0`)
117
+
118
+ ### Fixes
119
+
120
+ - `gctoac update` always runs `gctoac migrate`, including when the update errors. (`cf04ae3`)
121
+
122
+ ## [1.5.2] - 2026-07-18
123
+
124
+ Tag [`v1.5.2`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.5.2). Published to npm.
125
+
126
+ ### New features
127
+
128
+ - Admin list tables sort on the API with `sortBy` / `sortDir`. The default is time descending. Covers chats, API keys, documents, audit logs, media assets and jobs, chat queue jobs, usage, and DDoS live connections, blacklist, and events. The Admin SPA gets clickable column headers. (`4c247ff`)
129
+
130
+ ## [1.5.1] - 2026-07-16
131
+
132
+ Tag [`v1.5.1`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.5.1). Published to npm.
133
+
134
+ ### Fixes
135
+
136
+ - Queue purge deletes every dead-letter job immediately. Succeeded, failed, and cancelled jobs still purge only when they finished more than 24 hours ago. (`dc74ae2`)
137
+ - The Admin purge dialog shows the deleted count and clearer confirm labels, and the click handler stays stable. (`3777612`)
138
+
139
+ ## [1.5.0] - 2026-07-16
140
+
141
+ Tag [`v1.5.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.5.0). Published to npm.
142
+
143
+ ### New features
144
+
145
+ - Durable chat queue: every chat completion is enqueued (`ChatJob` in SQLite, in-process worker with leases, fair round-robin, pause / drain / DLQ). Admin SPA login is a one-time OTP (`gctoac admin otp`). API keys move to scrypt, and legacy SHA-256 rows migrate on verify. (`85f8176`)
146
+ - OpenAI-shaped media (`/v1/images`, files, videos, audio), admin media library, hash-routed Admin panel built from `admin/src`, API feature flags, assistants / responses / Anthropic routes, and expanded `gctoac` commands. (`2f6494e`)
147
+ - Admin tabbed pages (Queue, Media, System, PM2, DDoS, API Features) with KPI strips. Media studio: generate, edit, and video. Preview lightbox. (`efa9931`)
148
+
149
+ ### Improvements
150
+
151
+ - Localized API errors and queue offline stream collect when there is no live Response. (`efa9931`)
152
+
153
+ ### Internal/CI
154
+
155
+ - Restore `.github/workflows/ci.yml` so the README badge resolves. (`385449c`)
156
+ - CI uses a valid 32-byte `ENCRYPTION_KEY`. (`e38bab2`)
157
+
158
+ ## [1.4.0] - 2026-07-15
159
+
160
+ Tag [`v1.4.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.4.0). Published to npm. The tag commit only bumps the version from 1.3.1. (`89b3eb7`)
161
+
162
+ The GitHub Release (published 2026-07-16) highlights durable chat queue, Admin OTP, scrypt keys, DDoS policy, the CSP Admin SPA, and docs/CLI alignment. Those commits are listed under 1.3.1 and 1.5.0, which is where they landed relative to the tags.
163
+
164
+ ### Internal/CI
165
+
166
+ - Version bump and npm publish of the 1.3.1 tree.
167
+
168
+ ## [1.3.1] - 2026-07-15
169
+
170
+ Published to npm. No git tag.
171
+
172
+ ### New features
173
+
174
+ - `gctoac update` shows a live progress UI. (`a27fe72`)
175
+ - Admin DDoS center, reverse-proxy client IP, chat history, and CLI ops. Runtime DDoS/abuse policy with auto-ban presets, nginx/Cloudflare client IP, multi-turn conversations, document safety sniffing, PM2 port control, and log clear / auto-trim. (`f9bee14`)
176
+
177
+ ### Improvements
178
+
179
+ - Minimal centered Admin login with a copy-key command. (`f97bbc2`)
180
+
181
+ ### Fixes
182
+
183
+ - `gctoac update` auto-migrates the database and always exits. (`e889245`)
184
+ - Admin blank page syntax error; update exits after restart. (`54b5965`)
185
+ - DDoS scroll, admin auth, pm2 install, and chat playground. (`5d633d0`)
186
+ - Free orphan processes on the port during stop/start. (`0b34f4f`)
187
+ - `gctoac update` step counter includes pm2. (`7a05d5e`)
188
+ - PM2 `EADDRINUSE` crash loop and conflict UX. (`b9392c7`)
189
+ - Restore the Admin SPA under CSP (`boot.js` and Google Fonts). (`d4fc0e5`)
190
+
191
+ ### Security
192
+
193
+ - Harden client-IP trust and load bans at bootstrap. (`54ff3b7`)
194
+
195
+ ### Internal/CI
196
+
197
+ - Stop tracking `.github` in the repository. (`e279c60`)
198
+
199
+ ## [1.3.0] - 2026-07-14
200
+
201
+ `package.json` only. Not published to npm as 1.3.0 (the next registry publish is 1.3.1).
202
+
203
+ ### New features
204
+
205
+ - Admin panel: full-height layout, i18n, chat filters, usage, and models. (`d8a158a`)
206
+ - Full i18n, API-key IP whitelist, DDoS center, and PM2 control. (`b0f2cd6`)
207
+
208
+ ### Improvements
209
+
210
+ - Restyle the Admin panel to match ysk.hk branding. (`c396946`)
211
+
212
+ ### Internal/CI
213
+
214
+ - npm-only install. Stop tracking `dist` in git. (`cf55a46`)
215
+
216
+ ## [1.2.7] - 2026-07-14
217
+
218
+ Published to npm. No git tag.
219
+
220
+ ### Fixes
221
+
222
+ - `gctoac update` exits after it finishes displaying output, without waiting for Ctrl+C. (`8c23d48`)
223
+
224
+ ## [1.2.6] - 2026-07-14
225
+
226
+ `package.json` only. Not published to npm as 1.2.6.
227
+
228
+ ### New features
229
+
230
+ - `gctoac key create`, `list`, and `revoke` for admin API keys. (`22a5715`)
231
+
232
+ ## [1.2.5] - 2026-07-14
233
+
234
+ Published to npm. No git tag.
235
+
236
+ ### Fixes
237
+
238
+ - Pin `execa@5` so the CommonJS server can start. (`0f8f2bd`)
239
+
240
+ ### Internal/CI
241
+
242
+ - Ignore the `gctoac.pid` runtime file. (`38461bf`)
243
+
244
+ ## [1.2.4] - 2026-07-14
245
+
246
+ Published to npm. No git tag.
247
+
248
+ ### Fixes
249
+
250
+ - `gctoac setup` works without the broken `npx prisma` invocation. (`f9a4c03`)
251
+
252
+ ## [1.2.3] - 2026-07-14
253
+
254
+ Published to npm. No git tag.
255
+
256
+ ### Fixes
257
+
258
+ - Stable global install without a Prisma runtime dependency. (`da963a1`)
259
+ - `version` and `doctor` do not require `.env`. (`e5fe74a`)
260
+ - `install.sh` keeps a permanent `~/.gctoac/src` for `npm link`. (`c42ed4d`)
261
+
262
+ ### Improvements
263
+
264
+ - Docs recommend `install.sh` or clone-and-link instead of `npm install` from GitHub. (`3cf6c3e`)
265
+ - Rewrite the English and Chinese READMEs around npm install, then polish the quick start. (`158a008`, `2182c81`)
266
+
267
+ ## [1.2.2] - 2026-07-14
268
+
269
+ `package.json` only. Not published to npm as 1.2.2.
270
+
271
+ ### Fixes
272
+
273
+ - Global GitHub install works without the Prisma CLI. (`a8a85e4`)
274
+
275
+ ## [1.2.1] - 2026-07-14
276
+
277
+ `package.json` only. Not published to npm as 1.2.1.
278
+
279
+ ### Fixes
280
+
281
+ - Reliable global install from GitHub (prebuilt `dist` and `prepare`). (`13bf46e`)
282
+
283
+ ## [1.2.0] - 2026-07-14
284
+
285
+ Published to npm. No git tag. First version on the registry (`1.0.0` and `1.1.0` were not published).
286
+
287
+ ### New features
288
+
289
+ - `gctoac update` self-update and Admin one-click update. (`86b4e7b`)
290
+
291
+ ### Improvements
292
+
293
+ - Add `README.md` and `README-ZH.md`. (`87ee7f4`)
294
+
295
+ ### Internal/CI
296
+
297
+ - Remove an accidental self-dependency from `package-lock.json`. (`f977019`)
298
+
299
+ ## [1.1.0] - 2026-07-14
300
+
301
+ `package.json` only. Not published to npm.
302
+
303
+ ### New features
304
+
305
+ - Default port `3847`. npm package bins `gctoac` and `gcoa`. (`b87b702`)
306
+
307
+ ## [1.0.0] - 2026-07-14
308
+
309
+ `package.json` only. Not published to npm. Includes the first commit (`cc9eae5`).
310
+
311
+ ### New features
312
+
313
+ - OpenAI-compatible Grok CLI gateway: Express/TypeScript, Prisma/MySQL at this commit, AES-256-GCM, API-key auth, audit logging, documents, PM2, Vitest, and GitHub Actions CI. (`936cd7b`)
314
+ - Thinking is exposed as DeepSeek `reasoning_content` plus Grok metadata. (`fd77604`)
315
+ - Per-key safe/agent policy and the Admin panel (`/admin` and `/admin/api` for dashboard, chats, keys, documents, audit, and settings). (`0a80d09`)
316
+
317
+ ### Improvements
318
+
319
+ - Rewrite the README. (`8c237d6`)
320
+
321
+ ### Fixes
322
+
323
+ - Store the SQLite database under the project-root `data/` directory. (`54258f0`)
324
+
325
+ ### Internal/CI
326
+
327
+ - Switch the database from MySQL to SQLite. (`cbb4c81`)
328
+ - Polish the Admin UI and add Admin API integration tests. (`23782b5`)
@@ -0,0 +1,328 @@
1
+ # 更新日誌
2
+
3
+ [English](./CHANGELOG.md)
4
+
5
+ 由新到舊。每個版本按類別分組。沒有變更的類別略去。
6
+
7
+ 類別:**新功能**、**改進**、**修正**、**安全**、**依賴升級**、**內部/CI**。
8
+
9
+ [README.md](./README.md) 與 [README-ZH.md](./README-ZH.md) 只列最近三個版本。本檔是完整記錄。
10
+
11
+ 條目來自 git 歷史、標籤,以及 [GitHub Releases](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases)。`package.json` 有過、但未曾發佈到 npm 的版本會註明。npm 日期是登錄庫發佈時間(香港時間,UTC+8)。沒有把 commit 說明改寫成 commit 本身沒有的說法。
12
+
13
+ ## [1.7.5] - 2026-10-05
14
+
15
+ ### 改進
16
+
17
+ - README 加上產品頁連結([ysk.hk/products/gctoac](https://ysk.hk/products/gctoac),英文:[ysk.hk/en/products/gctoac](https://ysk.hk/en/products/gctoac))。(`ac63380`)
18
+
19
+ ### 內部/CI
20
+
21
+ - 推送 `vX.Y.Z` 標籤後,由 `.github/workflows/release.yml` 發佈。認證只用 npm 受信任發佈(OIDC),並附來源證明(provenance)。工作流程不使用 npm token,也不使用 GitHub environment。
22
+ - 重新執行時,若該版本已在登錄庫,就跳過 `npm publish`,再執行 `npm view grok-cli-to-openai-compatible@<version>`;GitHub Release 只在尚未建立時才建立。
23
+ - CI 的 `actions/checkout` 與 `actions/setup-node` 由 v4 改為 v7。發佈 job 使用 Node 24,以便內建 npm 為 11.5.1 或更新。
24
+ - 更新日誌:兩份 README 只保留最近三個版本,並按類別分組。較舊版本在本檔與 `CHANGELOG.md`。
25
+
26
+ ## [1.7.4] - 2026-08-14
27
+
28
+ 標籤 [`v1.7.4`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.4)。已發佈到 npm。
29
+
30
+ ### 修正
31
+
32
+ - Grok CLI 在檔案寫好之後以 exit `1` 結束時(`maxTurns`/失敗的 `use_tool` 複製),`/v1/images/generations` 仍交回 Imagine 圖片。1.7.3 只在串流正常結束後才收 session `images/`,錯誤會在收集之前拋出。Gateway 會取回今次 run 的 session 圖片與沙箱 `output.*`,串流期間輪詢並複製;`n=1` 一拿到檔案就停止行程。(`caadf98`)
33
+
34
+ ### 內部/CI
35
+
36
+ - 為 v1.7.3 的 i18n 字串重新建置 `public/admin/boot.js`。(`922a5f1`)
37
+
38
+ ## [1.7.3] - 2026-08-14
39
+
40
+ 標籤 [`v1.7.3`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.3)。已發佈到 npm。
41
+
42
+ ### 修正
43
+
44
+ - Grok Imagine 只把圖寫到今次 run 的 `~/.grok/sessions/<encoded-cwd>/<uuid>/images/`、沙箱沒有 `output.png` 時,`/v1/images/generations` 仍交回圖片。media-run 的 agent 沒有 bash,不能自己複製。Gateway 把今次 run 最新一張複製到沙箱 `output.*`。收圖順序仍是沙箱根目錄 `output.*`、沙箱、今次 session 的 `images/`。只有完全沒有檔案時才回 502 `no_image_in_sandbox`。(`e4efd6f`)
45
+
46
+ ### 改進
47
+
48
+ - README 與 README-ZH 寫明圖片請求、收圖路徑,以及 `/v1/images/*` 與 `/v1/media/assets/*`。(`634acfb`)
49
+
50
+ ## [1.7.2] - 2026-08-13
51
+
52
+ 標籤 [`v1.7.2`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.2)。已發佈到 npm。
53
+
54
+ ### 修正
55
+
56
+ - 生成與編輯傳入工具允許清單(`image_gen`/`image_edit`),避免 agent 先 `web_fetch` 或先呼叫 `image_edit`。收集器會走遍沙箱,優先 `output.png`;根目錄沒有檔案時仍交回 `refs/*.jpg`。(`5213dd4`)
57
+ - `readdir` 改為推斷 `Dirent`,`tsc` 才可以發佈。(`91babc6`)
58
+
59
+ ## [1.7.1] - 2026-08-13
60
+
61
+ 標籤 [`v1.7.1`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.1)。已發佈到 npm。
62
+
63
+ ### 修正
64
+
65
+ - 窄螢幕上 Admin 資料表改為帶標籤的卡片。Dashboard 的 KPI、安全與運行數值,以及捷徑按鈕不再被裁切。Playground 設定收成一行,對話紀錄保持可見,輸入列留在底部。(`d23ab46`、`d9d2a06`)
66
+ - `pm2` 不在 `PATH` 時,`gctoac restart` 由 PM2 退回 gctoac。(`6c62299`)
67
+
68
+ ### 內部/CI
69
+
70
+ - `NODE_ENV=test` 或正在跑 Vitest 時,測試拒絕真正的 `POST /admin/api/system/update`,避免 `npm install`/`prisma generate` 弄壞 Vitest worker。同時穩定 Vitest worker。(`6c62299`、`be2ad7a`)
71
+
72
+ ## [1.7.0] - 2026-08-13
73
+
74
+ 標籤 [`v1.7.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.7.0)。已發佈到 npm。
75
+
76
+ ### 新功能
77
+
78
+ - Admin → 支持頁:GitHub Sponsors、Linktree、加密貨幣地址、YSK Limited,以及 `mailto:email@ysk.hk`。靜態頁,沒有新 API。(`4b49034`)
79
+
80
+ ### 改進
81
+
82
+ - Admin 與 README 的繁體中文改為香港書面語。(`83a1be0`)
83
+ - 以中英文記錄 Grok 1.0.3 的 Admin 與 API 介面。(`787bcfb`)
84
+
85
+ ### 修正
86
+
87
+ - 替換 DOM `RequestRedirect` 型別,`tsc` 才可以發佈。(`2f1a12d`)
88
+
89
+ ### 安全
90
+
91
+ - Safe mode 不再接受客戶端的 `tools`、`allow`、`permission`、`sandbox` 或 `agent`。遠端圖片擷取封鎖私有位址與 metadata 主機,並且不跟隨開放重新導向。預設 agent 工作目錄是 `storage/workspaces/default`;允許清單用 `realpath`。Grok 子行程環境變數是白名單。Admin API 有速率限制。OTP 只用一次。除非 `GCTOAC_UPDATE_DEV=1`,git 頻道的 `gctoac update` 安裝生產依賴。(`0274353`)
92
+ - `resume` 按租戶隔離,移除影片 IDOR 後備路徑,並釘死 Grok 工作目錄。(`f183ae9`)
93
+ - OTP 建立的列留在 admin 金鑰上。最後一個 admin 不能撤銷。(`babec8b`)
94
+ - 在 nginx 後面忽略偽造的 `CF-Connecting-IP`。(`385176c`)
95
+
96
+ ## [1.6.1] - 2026-08-13
97
+
98
+ 標籤 [`v1.6.1`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.6.1)。已發佈到 npm。
99
+
100
+ ### 修正
101
+
102
+ - git 頻道的 `gctoac update` 會安裝 devDependencies,建置才編譯得到。`.env` 設了 `NODE_ENV=production`,之前因此漏了 `@types/*` 與 Vite。(`017cf6d`)
103
+ - Admin → 系統:Grok inspect 卡片對齊,Grok sessions 分頁一律顯示工作階段數量。(`f01df63`)
104
+
105
+ ## [1.6.0] - 2026-08-13
106
+
107
+ 標籤 [`v1.6.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.6.0)。已發佈到 npm。
108
+
109
+ ### 新功能
110
+
111
+ - 對齊 Grok Build 1.0.3。工作階段只建立一次,其後用 `--resume`。移除 `--best-of-n` 與 `--check`。客戶端 `session_id` 按 API 金鑰對應。解析 ACP 事件與費用。預設模型是 `grok-4.6`。提供 inspect、effort、1–15 秒影片,以及 URL 視覺。(`4c5d2a2`)
112
+ - 列出並刪除本機 Grok Build 工作階段。(`c67f3a8`)
113
+ - Playground:Grok 工作階段 resume/fork,以及工具 chips。(`989447a`)
114
+ - `reference_to_video` 支援預設聲線。(`73f6daa`)
115
+ - 在 OpenAI SSE 串流上送出 Grok `tool_call` 與 `plan` 事件。(`ea2de7d`)
116
+ - Playground 的記憶、計劃與權限控制。(`d9443f0`)
117
+
118
+ ### 修正
119
+
120
+ - `gctoac update` 即使更新出錯,也會執行 `gctoac migrate`。(`cf04ae3`)
121
+
122
+ ## [1.5.2] - 2026-07-18
123
+
124
+ 標籤 [`v1.5.2`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.5.2)。已發佈到 npm。
125
+
126
+ ### 新功能
127
+
128
+ - Admin 列表在 API 端以 `sortBy`/`sortDir` 排序,預設時間由新到舊。涵蓋對話、API 金鑰、文件、稽核日誌、媒體資產與工作、對話佇列、用量,以及 DDoS 即時連線、黑名單與事件。Admin SPA 的欄位標題可點擊排序。(`4c247ff`)
129
+
130
+ ## [1.5.1] - 2026-07-16
131
+
132
+ 標籤 [`v1.5.1`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.5.1)。已發佈到 npm。
133
+
134
+ ### 修正
135
+
136
+ - 佇列清除會立即刪除全部 dead-letter 工作。成功、失敗、已取消的工作仍只在完成超過 24 小時後才清除。(`dc74ae2`)
137
+ - Admin 清除對話框顯示刪除數量與更清楚的確認文字,點擊處理保持穩定。(`3777612`)
138
+
139
+ ## [1.5.0] - 2026-07-16
140
+
141
+ 標籤 [`v1.5.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.5.0)。已發佈到 npm。
142
+
143
+ ### 新功能
144
+
145
+ - 持久化對話佇列:每次 chat completion 都入隊(SQLite `ChatJob`、行程內 worker,含租約、公平輪替、暫停/排空/DLQ)。Admin SPA 以一次性 OTP 登入(`gctoac admin otp`)。API 金鑰改為 scrypt,舊的 SHA-256 列在驗證時遷移。(`85f8176`)
146
+ - OpenAI 形狀的媒體(`/v1/images`、files、videos、audio)、Admin 媒體庫、由 `admin/src` 建置的 hash 路由 Admin 面板、API 功能開關、assistants/responses/Anthropic 路由,以及擴充的 `gctoac` 指令。(`2f6494e`)
147
+ - Admin 分頁(佇列、媒體、系統、PM2、DDoS、API 功能)與 KPI 列。媒體工作室:生成、編輯、影片。預覽燈箱。(`efa9931`)
148
+
149
+ ### 改進
150
+
151
+ - API 錯誤本地化;沒有即時 Response 時,佇列離線收集串流。(`efa9931`)
152
+
153
+ ### 內部/CI
154
+
155
+ - 恢復 `.github/workflows/ci.yml`,README 徽章才連得到。(`385449c`)
156
+ - CI 使用合法的 32-byte `ENCRYPTION_KEY`。(`e38bab2`)
157
+
158
+ ## [1.4.0] - 2026-07-15
159
+
160
+ 標籤 [`v1.4.0`](https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible/releases/tag/v1.4.0)。已發佈到 npm。標籤 commit 只把版本從 1.3.1 提升。(`89b3eb7`)
161
+
162
+ GitHub Release(2026-07-16 發佈)提到持久化對話佇列、Admin OTP、scrypt 金鑰、DDoS 策略、CSP 下的 Admin SPA,以及文件/CLI 對齊。這些 commit 相對標籤落在 1.3.1 與 1.5.0,記錄在該兩節。
163
+
164
+ ### 內部/CI
165
+
166
+ - 版本號提升,並把 1.3.1 的樹發佈到 npm。
167
+
168
+ ## [1.3.1] - 2026-07-15
169
+
170
+ 已發佈到 npm。沒有 git 標籤。
171
+
172
+ ### 新功能
173
+
174
+ - `gctoac update` 顯示即時進度。(`a27fe72`)
175
+ - Admin DDoS 中心、反向代理客戶端 IP、對話紀錄與 CLI 維運。運行時 DDoS/濫用策略與自動封鎖預設、nginx/Cloudflare 客戶端 IP、多輪對話、文件安全檢查、PM2 port 控制,以及日誌清除/自動裁剪。(`f9bee14`)
176
+
177
+ ### 改進
178
+
179
+ - 簡潔置中的 Admin 登入,並可複製金鑰指令。(`f97bbc2`)
180
+
181
+ ### 修正
182
+
183
+ - `gctoac update` 自動遷移資料庫,並且一定會結束行程。(`e889245`)
184
+ - Admin 空白頁語法錯誤;更新在重啟後結束。(`54b5965`)
185
+ - DDoS 捲動、admin 認證、pm2 安裝,以及 chat playground。(`5d633d0`)
186
+ - stop/start 時釋放佔用 port 的孤兒行程。(`0b34f4f`)
187
+ - `gctoac update` 的步驟計數包含 pm2。(`7a05d5e`)
188
+ - PM2 `EADDRINUSE` 崩潰迴圈與衝突提示。(`b9392c7`)
189
+ - 在 CSP 下恢復 Admin SPA(`boot.js` 與 Google Fonts)。(`d4fc0e5`)
190
+
191
+ ### 安全
192
+
193
+ - 收緊客戶端 IP 信任,並在啟動時載入封鎖名單。(`54ff3b7`)
194
+
195
+ ### 內部/CI
196
+
197
+ - 倉庫不再追蹤 `.github`。(`e279c60`)
198
+
199
+ ## [1.3.0] - 2026-07-14
200
+
201
+ 只在 `package.json`。未曾以 1.3.0 發佈到 npm(登錄庫下一版是 1.3.1)。
202
+
203
+ ### 新功能
204
+
205
+ - Admin 面板:全高版面、i18n、對話篩選、用量與模型。(`d8a158a`)
206
+ - 完整 i18n、API 金鑰 IP 白名單、DDoS 中心與 PM2 控制。(`b0f2cd6`)
207
+
208
+ ### 改進
209
+
210
+ - Admin 面板改成 ysk.hk 的視覺。(`c396946`)
211
+
212
+ ### 內部/CI
213
+
214
+ - 只經 npm 安裝。git 不再追蹤 `dist`。(`cf55a46`)
215
+
216
+ ## [1.2.7] - 2026-07-14
217
+
218
+ 已發佈到 npm。沒有 git 標籤。
219
+
220
+ ### 修正
221
+
222
+ - `gctoac update` 顯示完即結束,不用再按 Ctrl+C。(`8c23d48`)
223
+
224
+ ## [1.2.6] - 2026-07-14
225
+
226
+ 只在 `package.json`。未曾以 1.2.6 發佈到 npm。
227
+
228
+ ### 新功能
229
+
230
+ - `gctoac key create`、`list`、`revoke`,用來管理 admin API 金鑰。(`22a5715`)
231
+
232
+ ## [1.2.5] - 2026-07-14
233
+
234
+ 已發佈到 npm。沒有 git 標籤。
235
+
236
+ ### 修正
237
+
238
+ - 釘選 `execa@5`,CommonJS 伺服器才啟動得到。(`0f8f2bd`)
239
+
240
+ ### 內部/CI
241
+
242
+ - 忽略運行時檔案 `gctoac.pid`。(`38461bf`)
243
+
244
+ ## [1.2.4] - 2026-07-14
245
+
246
+ 已發佈到 npm。沒有 git 標籤。
247
+
248
+ ### 修正
249
+
250
+ - `gctoac setup` 不再依賴會失敗的 `npx prisma`。(`f9a4c03`)
251
+
252
+ ## [1.2.3] - 2026-07-14
253
+
254
+ 已發佈到 npm。沒有 git 標籤。
255
+
256
+ ### 修正
257
+
258
+ - 穩定的全域安裝,不再依賴 Prisma runtime。(`da963a1`)
259
+ - `version` 與 `doctor` 不需要 `.env`。(`e5fe74a`)
260
+ - `install.sh` 保留永久的 `~/.gctoac/src` 供 `npm link`。(`c42ed4d`)
261
+
262
+ ### 改進
263
+
264
+ - 文件改為建議 `install.sh` 或 clone 後 link,而不是從 GitHub `npm install`。(`3cf6c3e`)
265
+ - 重寫中英文 README,以 npm 安裝為主,並整理快速開始。(`158a008`、`2182c81`)
266
+
267
+ ## [1.2.2] - 2026-07-14
268
+
269
+ 只在 `package.json`。未曾以 1.2.2 發佈到 npm。
270
+
271
+ ### 修正
272
+
273
+ - 從 GitHub 做全域安裝時不需要 Prisma CLI。(`a8a85e4`)
274
+
275
+ ## [1.2.1] - 2026-07-14
276
+
277
+ 只在 `package.json`。未曾以 1.2.1 發佈到 npm。
278
+
279
+ ### 修正
280
+
281
+ - 從 GitHub 做可靠的全域安裝(預先建置的 `dist` 與 `prepare`)。(`13bf46e`)
282
+
283
+ ## [1.2.0] - 2026-07-14
284
+
285
+ 已發佈到 npm。沒有 git 標籤。登錄庫上的第一個版本(`1.0.0` 與 `1.1.0` 沒有發佈)。
286
+
287
+ ### 新功能
288
+
289
+ - `gctoac update` 自我更新,以及 Admin 一鍵更新。(`86b4e7b`)
290
+
291
+ ### 改進
292
+
293
+ - 加入 `README.md` 與 `README-ZH.md`。(`87ee7f4`)
294
+
295
+ ### 內部/CI
296
+
297
+ - 從 `package-lock.json` 移除意外的自我依賴。(`f977019`)
298
+
299
+ ## [1.1.0] - 2026-07-14
300
+
301
+ 只在 `package.json`。未曾發佈到 npm。
302
+
303
+ ### 新功能
304
+
305
+ - 預設 port `3847`。npm 套件的 bin 為 `gctoac` 與 `gcoa`。(`b87b702`)
306
+
307
+ ## [1.0.0] - 2026-07-14
308
+
309
+ 只在 `package.json`。未曾發佈到 npm。包含第一次 commit(`cc9eae5`)。
310
+
311
+ ### 新功能
312
+
313
+ - OpenAI 相容的 Grok CLI gateway:Express/TypeScript、此 commit 時的 Prisma/MySQL、AES-256-GCM、API 金鑰認證、稽核日誌、文件、PM2、Vitest,以及 GitHub Actions CI。(`936cd7b`)
314
+ - Thinking 以 DeepSeek `reasoning_content` 加上 Grok metadata 露出。(`fd77604`)
315
+ - 按金鑰的 safe/agent 政策,以及 Admin 面板(`/admin` 與 `/admin/api`:儀表板、對話、金鑰、文件、稽核、設定)。(`0a80d09`)
316
+
317
+ ### 改進
318
+
319
+ - 重寫 README。(`8c237d6`)
320
+
321
+ ### 修正
322
+
323
+ - SQLite 資料庫改放在專案根目錄的 `data/`。(`54258f0`)
324
+
325
+ ### 內部/CI
326
+
327
+ - 資料庫由 MySQL 改為 SQLite。(`cbb4c81`)
328
+ - 整理 Admin UI,並加入 Admin API 整合測試。(`23782b5`)
package/README-ZH.md CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  **語言:** [English](./README.md) · 中文
10
10
 
11
+ **產品頁:** [ysk.hk/products/gctoac](https://ysk.hk/products/gctoac) · EN:[ysk.hk/en/products/gctoac](https://ysk.hk/en/products/gctoac)
12
+
11
13
  將本機 **[Grok CLI](https://x.ai)**(`grok -p` headless)包裝成可上線的 **OpenAI 相容 HTTP API**。
12
14
 
13
15
  | | |
@@ -725,12 +727,52 @@ gctoac setup|start|status|stop|doctor|logs|update
725
727
 
726
728
  ### 發佈到 npm(維護者)
727
729
 
728
- `prepublishOnly` 會跑 `npm run build`,tarball 一定包含 `dist/`。
730
+ 在 `main` 推送附註標籤 `vX.Y.Z` 後,由 [`.github/workflows/release.yml`](./.github/workflows/release.yml) 發佈。認證只用 npm 受信任發佈(OIDC),並附來源證明(provenance)。沒有 npm token。
729
731
 
730
- ```bash
731
- npm login
732
- npm publish --access public --otp=<2FA六位碼>
733
- ```
732
+ `prepublishOnly` 仍會跑 `npm run build`,tarball 一定包含 `dist/`。工作流程會跑測試;該版本尚未在 npm 時才發佈;然後執行 `npm view grok-cli-to-openai-compatible@<version>`,並建立一個 GitHub Release。重新執行不會發佈第二次。
733
+
734
+ 更新日誌規則與完整步驟見 [CONTRIBUTING.md](./CONTRIBUTING.md)。
735
+
736
+ ---
737
+
738
+ ## 更新日誌
739
+
740
+ 這裡只列最近三個版本。較舊的版本在 [CHANGELOG.zh.md](./CHANGELOG.zh.md)。
741
+
742
+ ### 1.7.5 — 2026-10-05
743
+
744
+ #### 改進
745
+
746
+ - README 加上產品頁連結([ysk.hk/products/gctoac](https://ysk.hk/products/gctoac),英文:[ysk.hk/en/products/gctoac](https://ysk.hk/en/products/gctoac))。
747
+
748
+ #### 內部/CI
749
+
750
+ - 推送 `vX.Y.Z` 標籤後,由 `.github/workflows/release.yml` 發佈。認證只用 npm 受信任發佈(OIDC),並附來源證明。工作流程不使用 npm token,也不使用 GitHub environment。
751
+ - 重新執行時,若該版本已在登錄庫,就跳過 `npm publish`,再執行 `npm view grok-cli-to-openai-compatible@<version>`;GitHub Release 只在尚未建立時才建立。
752
+ - CI 的 `actions/checkout` 與 `actions/setup-node` 由 v4 改為 v7。發佈 job 使用 Node 24,以便內建 npm 為 11.5.1 或更新。
753
+ - 兩份 README 只保留最近三個版本,並按類別分組。完整記錄在 `CHANGELOG.md` 與 `CHANGELOG.zh.md`。
754
+
755
+ ### 1.7.4 — 2026-08-14
756
+
757
+ #### 修正
758
+
759
+ - Grok CLI 在檔案寫好之後以 exit `1` 結束時(`maxTurns`/失敗的 `use_tool` 複製),`/v1/images/generations` 仍交回 Imagine 圖片。Gateway 會取回今次 run 的 session 圖片與沙箱 `output.*`,串流期間輪詢並複製;`n=1` 一拿到檔案就停止行程。
760
+
761
+ #### 內部/CI
762
+
763
+ - 為 v1.7.3 的 i18n 字串重新建置 `public/admin/boot.js`。
764
+
765
+ ### 1.7.3 — 2026-08-14
766
+
767
+ #### 修正
768
+
769
+ - Grok Imagine 只把圖寫到今次 run 的 session `images/`、沙箱沒有 `output.png` 時,`/v1/images/generations` 仍交回圖片。Gateway 把今次 run 最新一張複製到沙箱 `output.*`。只有完全沒有檔案時才回 502 `no_image_in_sandbox`。
770
+
771
+ #### 改進
772
+
773
+ - README 與 README-ZH 寫明圖片請求、收圖路徑,以及 `/v1/images/*` 與 `/v1/media/assets/*`。
774
+
775
+ [完整更新日誌](./CHANGELOG.zh.md)
734
776
 
735
777
  ---
736
778
 
@@ -752,7 +794,7 @@ npm publish --access public --otp=<2FA六位碼>
752
794
 
753
795
  **Ki (yanshekki)** — 全端工程師、量化交易者,[YSK Limited](https://ysk.hk/) 創辦人。
754
796
 
755
- 🌐 [linktr.ee/yanshekki](https://linktr.ee/yanshekki) · 🏢 [ysk.hk](https://ysk.hk/)
797
+ 🌐 [linktr.ee/yanshekki](https://linktr.ee/yanshekki) · 📄 [產品頁](https://ysk.hk/products/gctoac) · 🏢 [ysk.hk](https://ysk.hk/)
756
798
 
757
799
  ### ☕ 支持 / 打賞
758
800
 
package/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  **Languages:** English · [中文](./README-ZH.md)
10
10
 
11
+ **Product page:** [ysk.hk/products/gctoac](https://ysk.hk/products/gctoac) · EN: [ysk.hk/en/products/gctoac](https://ysk.hk/en/products/gctoac)
12
+
11
13
  Production OpenAI-compatible HTTP gateway for local **[Grok CLI](https://x.ai)** (`grok -p`).
12
14
 
13
15
  | | |
@@ -788,12 +790,52 @@ gctoac setup|start|status|stop|doctor|logs|update
788
790
 
789
791
  ### Publish (maintainers)
790
792
 
791
- `prepublishOnly` runs `npm run build` so the tarball includes `dist/`.
793
+ Releases are published by [`.github/workflows/release.yml`](./.github/workflows/release.yml) when an annotated `vX.Y.Z` tag is pushed to `main`. Authentication is npm Trusted Publishing (OIDC) with provenance. There is no npm token.
792
794
 
793
- ```bash
794
- npm login
795
- npm publish --access public --otp=<2FA_CODE>
796
- ```
795
+ `prepublishOnly` still runs `npm run build`, so the tarball includes `dist/`. The workflow runs the tests, publishes only if that version is not already on npm, checks `npm view grok-cli-to-openai-compatible@<version>`, and opens one GitHub Release. Re-running it does not publish a second time.
796
+
797
+ The changelog rule and the full steps are in [CONTRIBUTING.md](./CONTRIBUTING.md).
798
+
799
+ ---
800
+
801
+ ## Changelog
802
+
803
+ Only the latest three versions are listed here. Older releases are in [CHANGELOG.md](./CHANGELOG.md).
804
+
805
+ ### 1.7.5 — 2026-10-05
806
+
807
+ #### Improvements
808
+
809
+ - README links the product page ([ysk.hk/products/gctoac](https://ysk.hk/products/gctoac), English: [ysk.hk/en/products/gctoac](https://ysk.hk/en/products/gctoac)).
810
+
811
+ #### Internal/CI
812
+
813
+ - Publish from a pushed `vX.Y.Z` tag with `.github/workflows/release.yml`. Authentication is npm Trusted Publishing (OIDC) with provenance. The workflow does not use an npm token or a GitHub environment.
814
+ - A re-run skips `npm publish` when that version is already on the registry, checks `npm view grok-cli-to-openai-compatible@<version>`, and creates the GitHub Release only when it is missing.
815
+ - CI `actions/checkout` and `actions/setup-node` move from v4 to v7. The publish job uses Node 24 so the bundled npm is 11.5.1 or newer.
816
+ - READMEs keep the latest three versions, by category. The full history is in `CHANGELOG.md` and `CHANGELOG.zh.md`.
817
+
818
+ ### 1.7.4 — 2026-08-14
819
+
820
+ #### Fixes
821
+
822
+ - `/v1/images/generations` returns the Imagine image when Grok CLI exits 1 after the file was written (`maxTurns` / failed `use_tool` copies). The gateway recovers this run’s session images and sandbox `output.*`, polls and copies during the stream, and for `n=1` stops the process once a file is in hand.
823
+
824
+ #### Internal/CI
825
+
826
+ - Rebuild `public/admin/boot.js` for the v1.7.3 i18n strings.
827
+
828
+ ### 1.7.3 — 2026-08-14
829
+
830
+ #### Fixes
831
+
832
+ - `/v1/images/generations` returns the image when Grok Imagine wrote it only under this run’s session `images/` and the sandbox has no `output.png`. The gateway copies the newest file for this run into sandbox `output.*`. A 502 `no_image_in_sandbox` happens only when nothing was written.
833
+
834
+ #### Improvements
835
+
836
+ - README and README-ZH document the images request, the harvest path, and `/v1/images/*` plus `/v1/media/assets/*`.
837
+
838
+ [Full changelog](./CHANGELOG.md)
797
839
 
798
840
  ---
799
841
 
@@ -815,7 +857,7 @@ npm publish --access public --otp=<2FA_CODE>
815
857
 
816
858
  **Ki (yanshekki)** — Full-stack developer, quant trader, founder of [YSK Limited](https://ysk.hk/).
817
859
 
818
- 🌐 [linktr.ee/yanshekki](https://linktr.ee/yanshekki) · 🏢 [ysk.hk](https://ysk.hk/)
860
+ 🌐 [linktr.ee/yanshekki](https://linktr.ee/yanshekki) · 📄 [Product page](https://ysk.hk/products/gctoac) · 🏢 [ysk.hk](https://ysk.hk/)
819
861
 
820
862
  ### ☕ Support / Donate
821
863
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grok-cli-to-openai-compatible",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
4
4
  "description": "OpenAI-compatible API gateway for Grok CLI — with Admin panel, safe mode, and gctoac CLI",
5
5
  "keywords": [
6
6
  "grok",
@@ -34,9 +34,15 @@
34
34
  "scripts",
35
35
  "README.md",
36
36
  "README-ZH.md",
37
+ "CHANGELOG.md",
38
+ "CHANGELOG.zh.md",
37
39
  "LICENSE",
38
40
  ".env.example"
39
41
  ],
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "provenance": true
45
+ },
40
46
  "scripts": {
41
47
  "dev": "tsx watch src/server.ts",
42
48
  "dev:admin": "vite --config admin/vite.config.ts",
@@ -1,34 +0,0 @@
1
- import type { NextFunction, Request, Response } from 'express';
2
- import type { TrackedConnection } from '../interfaces/tracked-connection.interface';
3
- export type { TrackedConnection } from '../interfaces/tracked-connection.interface';
4
- export declare function connectionTrackerMiddleware(req: Request, res: Response, next: NextFunction): void;
5
- export declare function getConnectionsSnapshot(): {
6
- active: {
7
- id: string;
8
- ip: string;
9
- method: string;
10
- path: string;
11
- userAgent: string;
12
- startedAt: number;
13
- finishedAt?: number;
14
- durationMs?: number;
15
- statusCode?: number;
16
- apiKeyId?: string;
17
- apiKeyPrefix?: string;
18
- apiKeyName?: string;
19
- state: "active" | "finished";
20
- }[];
21
- recent: TrackedConnection[];
22
- counts: {
23
- active: number;
24
- recent: number;
25
- rateLimitedHits: number;
26
- blockedHits: number;
27
- };
28
- };
29
- export declare function recordBlockedHit(): void;
30
- export declare function getAbuseCounters(): {
31
- rateLimitedHits: number;
32
- blockedHits: number;
33
- };
34
- //# sourceMappingURL=connection-tracker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connection-tracker.d.ts","sourceRoot":"","sources":["../../src/middlewares/connection-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAKpF,YAAY,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAYpF,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAmEN;AAED,wBAAgB,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;EAYrC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wBAAgB,gBAAgB;;;EAE/B"}
@@ -1,99 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.connectionTrackerMiddleware = connectionTrackerMiddleware;
4
- exports.getConnectionsSnapshot = getConnectionsSnapshot;
5
- exports.recordBlockedHit = recordBlockedHit;
6
- exports.getAbuseCounters = getAbuseCounters;
7
- const node_crypto_1 = require("node:crypto");
8
- const client_ip_1 = require("../utils/client-ip");
9
- const abuse_guard_service_1 = require("../services/abuse-guard.service");
10
- const exception_factory_1 = require("../exceptions/exception.factory");
11
- const MAX_RECENT = 200;
12
- const active = new Map();
13
- const recent = [];
14
- let blockedHits = 0;
15
- let rateLimitedHits = 0;
16
- function clientIp(req) {
17
- return req.clientIp || (0, client_ip_1.getClientIp)(req);
18
- }
19
- function connectionTrackerMiddleware(req, res, next) {
20
- // Skip static admin assets noise
21
- const url = req.originalUrl || req.url || '';
22
- if (url.startsWith('/admin/') &&
23
- !url.startsWith('/admin/api') &&
24
- (url.includes('.') || url === '/admin/' || url === '/admin')) {
25
- next();
26
- return;
27
- }
28
- if (url === '/health' || url === '/ready') {
29
- next();
30
- return;
31
- }
32
- const pathOnly = url.split('?')[0] || '/';
33
- const ip = clientIp(req);
34
- const { overConcurrent } = abuse_guard_service_1.abuseGuardService.onRequestStart(ip, pathOnly);
35
- if (overConcurrent) {
36
- // End tracking immediately (do not pass 429 — that would double-count rate-abuse)
37
- abuse_guard_service_1.abuseGuardService.onRequestEnd(ip, pathOnly);
38
- next(exception_factory_1.ExceptionFactory.rateLimited('Too many concurrent connections from this IP'));
39
- return;
40
- }
41
- const id = (0, node_crypto_1.randomUUID)();
42
- const entry = {
43
- id,
44
- ip,
45
- method: req.method,
46
- path: pathOnly,
47
- userAgent: String(req.headers['user-agent'] || '').slice(0, 200),
48
- startedAt: Date.now(),
49
- state: 'active',
50
- };
51
- active.set(id, entry);
52
- let finished = false;
53
- const finish = () => {
54
- if (finished)
55
- return;
56
- finished = true;
57
- if (!active.has(id))
58
- return;
59
- active.delete(id);
60
- entry.finishedAt = Date.now();
61
- entry.durationMs = entry.finishedAt - entry.startedAt;
62
- entry.statusCode = res.statusCode;
63
- entry.state = 'finished';
64
- if (req.apiKey) {
65
- entry.apiKeyId = req.apiKey.id;
66
- entry.apiKeyPrefix = req.apiKey.keyPrefix;
67
- entry.apiKeyName = req.apiKey.name;
68
- }
69
- if (res.statusCode === 429)
70
- rateLimitedHits += 1;
71
- abuse_guard_service_1.abuseGuardService.onRequestEnd(ip, pathOnly, res.statusCode);
72
- recent.unshift({ ...entry });
73
- if (recent.length > MAX_RECENT)
74
- recent.length = MAX_RECENT;
75
- };
76
- res.on('finish', finish);
77
- res.on('close', finish);
78
- next();
79
- }
80
- function getConnectionsSnapshot() {
81
- const activeList = Array.from(active.values()).map((e) => ({ ...e }));
82
- return {
83
- active: activeList,
84
- recent: recent.slice(0, 100),
85
- counts: {
86
- active: activeList.length,
87
- recent: recent.length,
88
- rateLimitedHits,
89
- blockedHits,
90
- },
91
- };
92
- }
93
- function recordBlockedHit() {
94
- blockedHits += 1;
95
- }
96
- function getAbuseCounters() {
97
- return { rateLimitedHits, blockedHits };
98
- }
99
- //# sourceMappingURL=connection-tracker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connection-tracker.js","sourceRoot":"","sources":["../../src/middlewares/connection-tracker.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- // Cache-bust: load app.js with the same ?v= as this script (server-injected).
2
- const V = new URL(import.meta.url).searchParams.get('v') || '1';
3
- await import(`/admin/app.js?v=${V}`);