kiro-gateway-cli 1.0.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.
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # Kiro Gateway CLI(Node.js)
2
+
3
+ [English](README_EN.md) | [简体中文](README.md)
4
+
5
+ 一个用 Node.js 实现的 Kiro Gateway——一个透明代理,把 Kiro API(Amazon Q Developer / AWS CodeWhisperer)以 OpenAI 兼容和 Anthropic 兼容的接口暴露出来。
6
+
7
+ ## 环境要求
8
+
9
+ - Node.js >= 23.4(使用内置的 `node:sqlite` 模块)
10
+ - npm
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ cd kiro-gateway-cli
16
+ npm install
17
+ ```
18
+
19
+ ## 用法
20
+
21
+ ```bash
22
+ # 使用默认配置启动(host: 0.0.0.0, port: 8000)
23
+ npm start
24
+
25
+ # 显式使用 serve 子命令(与默认行为相同)
26
+ kiro-gateway serve
27
+
28
+ # 自定义端口 / 主机
29
+ kiro-gateway serve --port 9000
30
+ kiro-gateway serve --host 127.0.0.1 --port 9000
31
+ node bin/kiro-gateway.js serve --port 9000
32
+ node bin/kiro-gateway.js --host 127.0.0.1 --port 9000
33
+
34
+ # 后台运行(守护进程)——立即返回
35
+ kiro-gateway serve --background
36
+ kiro-gateway serve -b --port 9000
37
+
38
+ # 停止后台服务器(需在同一个目录下运行)
39
+ kiro-gateway stop
40
+
41
+ # 全局安装(添加 kiro-gateway 命令)
42
+ npm link
43
+ kiro-gateway serve --port 9000
44
+ ```
45
+
46
+ ### 通过 CLI 参数进行常用配置
47
+
48
+ 最常见的配置项可以作为 CLI 参数传入(优先级最高——会覆盖 `.env` 和环境变量):
49
+
50
+ ```bash
51
+ kiro-gateway serve \
52
+ -k my-super-secret-key \ # PROXY_API_KEY(可选;不设置 = 无认证)
53
+ -t your_refresh_token \ # REFRESH_TOKEN(或者改用 -f / -d)
54
+ -f ~/.aws/sso/cache/kiro-auth-token.json # KIRO_CREDS_FILE(JSON 凭据)
55
+ -d ~/.local/share/kiro-cli/data.sqlite3 # KIRO_CLI_DB_FILE(kiro-cli SQLite)
56
+ -r us-east-1 \ # KIRO_REGION
57
+ --api-region eu-central-1 \ # KIRO_API_REGION 覆盖
58
+ --profile-arn arn:aws:codewhisperer:... \ # PROFILE_ARN
59
+ --log-level DEBUG \ # LOG_LEVEL
60
+ --proxy-url http://127.0.0.1:7890 \ # VPN_PROXY_URL(HTTP/HTTPS/SOCKS5)
61
+ --proxy-url socks5h://127.0.0.1:1080 \ # SOCKS5,代理侧解析 DNS(socks5h)
62
+ --proxy-url socks5://127.0.0.1:1080 \ # SOCKS5,客户端侧解析 DNS(socks5)
63
+ --account-system \ # 启用多账号故障切换
64
+ -H 0.0.0.0 -p 8000 # 服务器监听地址
65
+ ```
66
+
67
+ 运行 `kiro-gateway --help` 查看完整列表。
68
+
69
+ 配置优先级(从高到低):
70
+ 1. CLI 参数(`--api-key`、`--port`……)
71
+ 2. 环境变量(`.env` 文件 / 进程环境变量)
72
+ 3. 默认值(`0.0.0.0:8000`,凭据:`~/.aws/sso/cache/kiro-auth-token.json`)
73
+
74
+ `serve` 子命令是可选的——直接运行 `kiro-gateway`(不带参数)也会以相同方式启动服务器。
75
+
76
+ ### 后台运行
77
+
78
+ `serve --background`(或 `-b`)会把服务器作为分离的守护进程启动,然后立即返回。父进程会等待服务器健康检查通过(/health 端点)并打印结果。
79
+
80
+ ```bash
81
+ kiro-gateway serve --background --port 9000
82
+ # Starting server in the background (pid 12345)...
83
+ # Server is running in the background: http://127.0.0.1:9000/health
84
+ # Stop it with: kiro-gateway stop
85
+
86
+ kiro-gateway stop
87
+ # Background server stopped (pid 12345).
88
+ ```
89
+
90
+ 守护进程状态文件(相对于工作目录,所以 `stop` 必须在启动 `serve --background` 的同一个目录下运行):
91
+
92
+ - `.kiro-gateway.pid` - 后台服务器的 PID(可用 `KIRO_PID_FILE` 覆盖)
93
+ - `kiro-gateway.log` - 守护进程输出日志(可用 `KIRO_LOG_FILE` 覆盖)
94
+
95
+ 启动前 CLI 会检查目标端口是否空闲,如果已有其他服务在监听,会报错并给出可操作的提示。如果后台服务器在启动过程中退出(凭据错误、端口冲突等),CLI 会报告失败并显示日志末尾几行。
96
+
97
+ ### Windows 平台说明
98
+
99
+ 后台运行在 Windows 上同样可用:子进程以无控制台窗口(`windowsHide`)方式启动,并自行把输出重定向到日志文件(Win32 不能通过 `stdio` 继承任意文件描述符)。一个注意点:Windows 没有 POSIX 信号,所以 `kiro-gateway stop` 会直接终止后台进程,而不会触发它的优雅退出处理器。pid 文件仍由 `stop` 清理,且每次 `start`/`stop` 都会校验 pid 文件对应的进程状态,非优雅终止也是安全的。
100
+
101
+ ## 配置
102
+
103
+ 复制根目录的 `.env.example` 为 `.env`(放在 `kiro-gateway-cli` 旁边),或者使用环境变量:
104
+
105
+ | 变量 | 说明 |
106
+ | --- | --- |
107
+ | `PROXY_API_KEY` | 客户端必须携带的 API 密钥(可选;为空/未设置 = 关闭认证) |
108
+ | `REFRESH_TOKEN` | Kiro 刷新令牌(方式二) |
109
+ | `KIRO_CREDS_FILE` | Kiro IDE 凭据 JSON 的路径(方式一,推荐;默认:`~/.aws/sso/cache/kiro-auth-token.json`) |
110
+ | `KIRO_CLI_DB_FILE` | kiro-cli SQLite 数据库路径(方式三,AWS SSO) |
111
+ | `KIRO_REGION` | SSO/认证区域(默认:`us-east-1`) |
112
+ | `KIRO_API_REGION` | 覆盖 Q API 区域 |
113
+ | `PROFILE_ARN` | AWS CodeWhisperer 配置文件的 ARN 覆盖 |
114
+ | `SERVER_HOST` / `SERVER_PORT` | 服务器监听地址 |
115
+ | `VPN_PROXY_URL` | 受限网络下的代理:HTTP/HTTPS 或 SOCKS(`socks5://`、代理侧 DNS 用 `socks5h://`、`socks4a://`) |
116
+ | `LOG_LEVEL` | `DEBUG`、`INFO`、`WARNING`、`ERROR`(默认:`INFO`) |
117
+ | `KIRO_PID_FILE` | `--background` 模式的 PID 文件(默认:`.kiro-gateway.pid`) |
118
+ | `KIRO_LOG_FILE` | `--background` 模式的日志文件(默认:`kiro-gateway.log`) |
119
+ | `ACCOUNT_SYSTEM` | 启用多账号故障切换(`true`/`false`) |
120
+ | `FAKE_REASONING` | 通过标签注入实现扩展思考(默认:启用) |
121
+ | `FIRST_TOKEN_TIMEOUT` | 重试前等待首个 token 的时间(默认:15 秒) |
122
+
123
+ ### 凭据(多账号)
124
+
125
+ 可以在 CLI 旁边放一个 `credentials.json`,用账号数组提供凭据:
126
+
127
+ ```json
128
+ [
129
+ { "type": "json", "path": "~/.aws/sso/cache/kiro-auth-token.json", "region": "us-east-1" },
130
+ { "type": "refresh_token", "refresh_token": "your-token" },
131
+ { "type": "sqlite", "path": "~/.local/share/kiro-cli/data.sqlite3" }
132
+ ]
133
+ ```
134
+
135
+ 如果 `credentials.json` 不存在,CLI 会从旧的 `.env` 变量(`KIRO_CREDS_FILE` > `REFRESH_TOKEN` > `KIRO_CLI_DB_FILE`)一次性生成它。
136
+
137
+ ## API 端点
138
+
139
+ | 端点 | 认证 | 说明 |
140
+ | --- | --- | --- |
141
+ | `GET /` | 无 | 健康检查 |
142
+ | `GET /health` | 无 | 详细健康检查 |
143
+ | `GET /v1/models` | `Authorization: Bearer {PROXY_API_KEY}`(仅当配置了密钥时) | 列出模型 |
144
+ | `POST /v1/chat/completions` | Bearer(仅当配置了密钥时) | OpenAI 对话(流式 + 非流式) |
145
+ | `POST /v1/messages` | `x-api-key` 或 Bearer(仅当配置了密钥时) | Anthropic messages(流式 + 非流式) |
146
+ | `POST /v1/messages/count_tokens` | `x-api-key`(仅当配置了密钥时) | token 估算 |
147
+
148
+ ### 示例
149
+
150
+ 设置 `PROXY_API_KEY` 后,客户端必须携带它:
151
+
152
+ ```bash
153
+ curl http://localhost:8000/v1/chat/completions \
154
+ -H "Authorization: Bearer your-api-key" \
155
+ -H "Content-Type: application/json" \
156
+ -d '{"model": "claude-sonnet-4.5", "messages": [{"role": "user", "content": "Hello"}]}'
157
+ ```
158
+
159
+ 如果没有设置 `PROXY_API_KEY`,则无需认证,可以省略 `Authorization` 头。
160
+
161
+ ## 移植了哪些功能
162
+
163
+ - **认证**:Kiro Desktop 刷新、AWS SSO OIDC(kiro-cli)、JSON 凭据(包括 Enterprise `clientIdHash` 设备注册)、SQLite 读取 + 读-合并-写令牌刷新
164
+ - **模型解析**:四层管线(别名 → 规范化 → 缓存/隐藏 → 透传)
165
+ - **转换器**:完整的 OpenAI/Anthropic → Kiro 管线(系统提示词、工具、工具调用/结果、图片、相邻消息合并、角色交替、思考标签注入、JSON schema 清洗)
166
+ - **流式**:AWS 事件流解析器、思考块有限状态机、带重试的首 token 超时、OpenAI `chat.completion.chunk` SSE 和 Anthropic Messages SSE 格式
167
+ - **HTTP 客户端**:403 令牌刷新重试、429/5xx 指数退避、网络错误分类、客户端断开时按请求中止
168
+ - **账号系统**:带粘性索引和熔断器的多账号故障切换、惰性初始化
169
+
170
+ ## 测试
171
+
172
+ ```bash
173
+ npm test
174
+ ```
175
+
176
+ 测试覆盖解析器、思考解析器、模型解析、转换器、错误分类、认证、HTTP 客户端重试、流式格式,以及完整的端到端服务器行为。无需联网。
package/README_EN.md ADDED
@@ -0,0 +1,208 @@
1
+ # Kiro Gateway CLI (Node.js)
2
+
3
+ [English](README_EN.md) | [简体中文](README.md)
4
+
5
+ A Node.js implementation of the Kiro Gateway — a transparent proxy that exposes
6
+ the Kiro API (Amazon Q Developer / AWS CodeWhisperer) as OpenAI-compatible and
7
+ Anthropic-compatible endpoints.
8
+
9
+ ## Requirements
10
+
11
+ - Node.js >= 23.4 (uses the built-in `node:sqlite` module)
12
+ - npm
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ cd kiro-gateway-cli
18
+ npm install
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ # Start with defaults (host: 0.0.0.0, port: 8000)
25
+ npm start
26
+
27
+ # Explicit serve subcommand (same as the default behavior)
28
+ kiro-gateway serve
29
+
30
+ # Custom port / host
31
+ kiro-gateway serve --port 9000
32
+ kiro-gateway serve --host 127.0.0.1 --port 9000
33
+ node bin/kiro-gateway.js serve --port 9000
34
+ node bin/kiro-gateway.js --host 127.0.0.1 --port 9000
35
+
36
+ # Run in the background (daemon) - returns immediately
37
+ kiro-gateway serve --background
38
+ kiro-gateway serve -b --port 9000
39
+
40
+ # Stop the background server (run from the same directory)
41
+ kiro-gateway stop
42
+
43
+ # Global install (adds the `kiro-gateway` command)
44
+ npm link
45
+ kiro-gateway serve --port 9000
46
+ ```
47
+
48
+ ### Common configuration via CLI flags
49
+
50
+ The most common configuration items can be passed as CLI arguments
51
+ (highest priority - they override `.env` and environment variables):
52
+
53
+ ```bash
54
+ kiro-gateway serve \
55
+ -k my-super-secret-key \ # PROXY_API_KEY (optional; unset = no auth)
56
+ -t your_refresh_token \ # REFRESH_TOKEN (or -f / -d instead)
57
+ -f ~/.aws/sso/cache/kiro-auth-token.json # KIRO_CREDS_FILE (JSON credentials)
58
+ -d ~/.local/share/kiro-cli/data.sqlite3 # KIRO_CLI_DB_FILE (kiro-cli SQLite)
59
+ -r us-east-1 \ # KIRO_REGION
60
+ --api-region eu-central-1 \ # KIRO_API_REGION override
61
+ --profile-arn arn:aws:codewhisperer:... \ # PROFILE_ARN
62
+ --log-level DEBUG \ # LOG_LEVEL
63
+ --proxy-url http://127.0.0.1:7890 \ # VPN_PROXY_URL (HTTP/HTTPS/SOCKS5)
64
+ --proxy-url socks5h://127.0.0.1:1080 \ # SOCKS5 with proxy-side DNS (socks5h)
65
+ --proxy-url socks5://127.0.0.1:1080 \ # SOCKS5 with client-side DNS (socks5)
66
+ --account-system \ # enable multi-account failover
67
+ -H 0.0.0.0 -p 8000 # server binding
68
+ ```
69
+
70
+ Run `kiro-gateway --help` for the full list.
71
+
72
+ Configuration priority (highest to lowest):
73
+ 1. CLI arguments (`--api-key`, `--port`, ...)
74
+ 2. Environment variables (`.env` file / process env)
75
+ 3. Default values (`0.0.0.0:8000`, credentials: `~/.aws/sso/cache/kiro-auth-token.json`)
76
+
77
+ The `serve` subcommand is optional - running `kiro-gateway` with no arguments
78
+ starts the server the same way.
79
+
80
+ ### Running in the background
81
+
82
+ `serve --background` (or `-b`) starts the server as a detached daemon and
83
+ returns immediately. The parent waits for the server to become healthy
84
+ (health endpoint) and prints the result.
85
+
86
+ ```bash
87
+ kiro-gateway serve --background --port 9000
88
+ # Starting server in the background (pid 12345)...
89
+ # Server is running in the background: http://127.0.0.1:9000/health
90
+ # Stop it with: kiro-gateway stop
91
+
92
+ kiro-gateway stop
93
+ # Background server stopped (pid 12345).
94
+ ```
95
+
96
+ Daemon state files (relative to the working directory, so `stop` must be run
97
+ from the same directory as `serve --background`):
98
+
99
+ - `.kiro-gateway.pid` - PID of the background server (override: `KIRO_PID_FILE`)
100
+ - `kiro-gateway.log` - daemon output (override: `KIRO_LOG_FILE`)
101
+
102
+ Before starting, the CLI checks that the target port is free and aborts with
103
+ an actionable message when another service is already listening there. If the
104
+ background server exits during startup (bad credentials, port conflict), the
105
+ CLI reports the failure and shows the last log lines.
106
+
107
+ ### Platform notes (Windows)
108
+
109
+ The daemon works on Windows too: the child is spawned without a console
110
+ window (`windowsHide`) and redirects its output to the log file itself
111
+ (Win32 cannot inherit arbitrary file descriptors via `stdio`). One caveat:
112
+ Windows has no POSIX signals, so `kiro-gateway stop` terminates the
113
+ background process directly instead of triggering its graceful shutdown
114
+ handler. The pid file is still cleaned up by `stop`, and ungraceful
115
+ termination is safe because the pid file is validated against the process
116
+ state on every `start`/`stop`.
117
+
118
+ ## Configuration
119
+
120
+ Copy the root `.env.example` to `.env` (next to `kiro-gateway-cli`) or use
121
+ environment variables:
122
+
123
+ | Variable | Description |
124
+ | --- | --- |
125
+ | `PROXY_API_KEY` | API key clients must send (optional; empty/unset = authentication disabled) |
126
+ | `REFRESH_TOKEN` | Kiro refresh token (Option 2) |
127
+ | `KIRO_CREDS_FILE` | Path to Kiro IDE credentials JSON (Option 1, recommended; default: `~/.aws/sso/cache/kiro-auth-token.json`) |
128
+ | `KIRO_CLI_DB_FILE` | Path to kiro-cli SQLite database (Option 3, AWS SSO) |
129
+ | `KIRO_REGION` | SSO/auth region (default: `us-east-1`) |
130
+ | `KIRO_API_REGION` | Override the Q API region |
131
+ | `PROFILE_ARN` | AWS CodeWhisperer profile ARN override |
132
+ | `SERVER_HOST` / `SERVER_PORT` | Server binding |
133
+ | `VPN_PROXY_URL` | Proxy for restricted networks: HTTP/HTTPS or SOCKS (`socks5://`, `socks5h://` for proxy-side DNS, `socks4a://`) |
134
+ | `LOG_LEVEL` | `DEBUG`, `INFO`, `WARNING`, `ERROR` (default: `INFO`) |
135
+ | `KIRO_PID_FILE` | PID file for `--background` mode (default: `.kiro-gateway.pid`) |
136
+ | `KIRO_LOG_FILE` | Log file for `--background` mode (default: `kiro-gateway.log`) |
137
+ | `ACCOUNT_SYSTEM` | Enable multi-account failover (`true`/`false`) |
138
+ | `FAKE_REASONING` | Extended thinking via tag injection (default: enabled) |
139
+ | `FIRST_TOKEN_TIMEOUT` | First-token wait before retry (default: 15s) |
140
+
141
+ ### Credentials (multi-account)
142
+
143
+ Credentials can be provided as `credentials.json` (next to the CLI) with an
144
+ array of accounts:
145
+
146
+ ```json
147
+ [
148
+ { "type": "json", "path": "~/.aws/sso/cache/kiro-auth-token.json", "region": "us-east-1" },
149
+ { "type": "refresh_token", "refresh_token": "your-token" },
150
+ { "type": "sqlite", "path": "~/.local/share/kiro-cli/data.sqlite3" }
151
+ ]
152
+ ```
153
+
154
+ If `credentials.json` does not exist, the CLI creates it once from the legacy
155
+ `.env` variables (`KIRO_CREDS_FILE` > `REFRESH_TOKEN` > `KIRO_CLI_DB_FILE`).
156
+
157
+ ## API Endpoints
158
+
159
+ | Endpoint | Auth | Description |
160
+ | --- | --- | --- |
161
+ | `GET /` | none | Health check |
162
+ | `GET /health` | none | Detailed health check |
163
+ | `GET /v1/models` | `Authorization: Bearer {PROXY_API_KEY}` (only if a key is configured) | List models |
164
+ | `POST /v1/chat/completions` | Bearer (only if a key is configured) | OpenAI chat (streaming + non-streaming) |
165
+ | `POST /v1/messages` | `x-api-key` or Bearer (only if a key is configured) | Anthropic messages (streaming + non-streaming) |
166
+ | `POST /v1/messages/count_tokens` | `x-api-key` (only if a key is configured) | Token estimation |
167
+
168
+ ### Example
169
+
170
+ When `PROXY_API_KEY` is set, clients must send it:
171
+
172
+ ```bash
173
+ curl http://localhost:8000/v1/chat/completions \
174
+ -H "Authorization: Bearer your-api-key" \
175
+ -H "Content-Type: application/json" \
176
+ -d '{"model": "claude-sonnet-4.5", "messages": [{"role": "user", "content": "Hello"}]}'
177
+ ```
178
+
179
+ If `PROXY_API_KEY` is left unset, no authentication is required and the
180
+ `Authorization` header can be omitted.
181
+
182
+ ## What is ported
183
+
184
+ - **Auth**: Kiro Desktop refresh, AWS SSO OIDC (kiro-cli), JSON credentials
185
+ (including Enterprise `clientIdHash` device registration), SQLite read +
186
+ read-merge-write token refresh
187
+ - **Model resolution**: 4-layer pipeline (alias → normalize → cache/hidden →
188
+ pass-through)
189
+ - **Converters**: full OpenAI/Anthropic → Kiro pipeline (system prompt,
190
+ tools, tool calls/results, images, adjacent-message merging, role
191
+ alternation, thinking tag injection, JSON schema sanitization)
192
+ - **Streaming**: AWS event stream parser, thinking-block FSM, first-token
193
+ timeout with retry, OpenAI `chat.completion.chunk` SSE and Anthropic
194
+ Messages SSE formats
195
+ - **HTTP client**: 403 token-refresh retry, 429/5xx exponential backoff,
196
+ network error classification, per-request abort on client disconnect
197
+ - **Account system**: multi-account failover with sticky index and circuit
198
+ breaker, lazy initialization
199
+
200
+ ## Tests
201
+
202
+ ```bash
203
+ npm test
204
+ ```
205
+
206
+ Tests cover parsers, thinking parser, model resolver, converters, error
207
+ classification, auth, HTTP client retries, streaming formats, and full
208
+ end-to-end server behavior (with mocked upstream). No network access needed.