runcc 0.1.5 → 0.1.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/CHANGELOG.md +5 -0
- package/README.md +12 -0
- package/dist/index.js +98 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.6] - 2026-01-26
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Added token set/clean commands for managing provider tokens
|
|
12
|
+
|
|
8
13
|
## [0.1.5] - 2026-01-23
|
|
9
14
|
|
|
10
15
|
### Fixed
|
package/README.md
CHANGED
|
@@ -48,6 +48,8 @@ runcc
|
|
|
48
48
|
| `runcc list` | 列出所有 endpoints |
|
|
49
49
|
| `runcc add <name> <endpoint> [token]` | 添加自定义 endpoint |
|
|
50
50
|
| `runcc remove <name>` | 删除自定义 endpoint |
|
|
51
|
+
| `runcc token set <provider> [token]` | 设置指定 provider 的 token |
|
|
52
|
+
| `runcc token clean <provider>` | 清除指定 provider 的 token(`clean`/`clear` 均可) |
|
|
51
53
|
|
|
52
54
|
### 原生命令配置(持久化)
|
|
53
55
|
|
|
@@ -181,6 +183,16 @@ $ runcc glm
|
|
|
181
183
|
|
|
182
184
|
Token 会被保存到 `~/.runcc/config.json`,下次使用时无需再次输入。
|
|
183
185
|
|
|
186
|
+
也可以通过命令行直接设置或清除:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# 设置/覆盖 token(不传 token 会交互输入)
|
|
190
|
+
runcc token set glm sk-xxxx
|
|
191
|
+
|
|
192
|
+
# 清除 token
|
|
193
|
+
runcc token clean glm
|
|
194
|
+
```
|
|
195
|
+
|
|
184
196
|
## 开发
|
|
185
197
|
|
|
186
198
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -1995,6 +1995,33 @@ function saveToken(provider, token) {
|
|
|
1995
1995
|
config.tokens[provider] = token;
|
|
1996
1996
|
writeConfig(config);
|
|
1997
1997
|
}
|
|
1998
|
+
function clearToken(provider) {
|
|
1999
|
+
const config = readConfig();
|
|
2000
|
+
if (!config.tokens || !(provider in config.tokens)) {
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
2003
|
+
delete config.tokens[provider];
|
|
2004
|
+
writeConfig(config);
|
|
2005
|
+
}
|
|
2006
|
+
function setCustomEndpointToken(name, token) {
|
|
2007
|
+
const config = readConfig();
|
|
2008
|
+
if (!config.endpoints) {
|
|
2009
|
+
return false;
|
|
2010
|
+
}
|
|
2011
|
+
const existingIndex = config.endpoints.findIndex((ep) => ep.name === name);
|
|
2012
|
+
if (existingIndex === -1) {
|
|
2013
|
+
return false;
|
|
2014
|
+
}
|
|
2015
|
+
const endpoint = config.endpoints[existingIndex];
|
|
2016
|
+
if (token === undefined) {
|
|
2017
|
+
delete endpoint.token;
|
|
2018
|
+
} else {
|
|
2019
|
+
endpoint.token = token;
|
|
2020
|
+
}
|
|
2021
|
+
config.endpoints[existingIndex] = endpoint;
|
|
2022
|
+
writeConfig(config);
|
|
2023
|
+
return true;
|
|
2024
|
+
}
|
|
1998
2025
|
function setLastUsed(provider) {
|
|
1999
2026
|
const config = readConfig();
|
|
2000
2027
|
config.lastUsed = provider;
|
|
@@ -2097,8 +2124,70 @@ function remove(name) {
|
|
|
2097
2124
|
}
|
|
2098
2125
|
}
|
|
2099
2126
|
|
|
2100
|
-
// src/commands/
|
|
2127
|
+
// src/commands/token.ts
|
|
2101
2128
|
import { createInterface as createInterface2 } from "node:readline";
|
|
2129
|
+
function isCustomEndpoint(name) {
|
|
2130
|
+
const endpoints = getCustomEndpoints();
|
|
2131
|
+
return endpoints.some((ep) => ep.name === name);
|
|
2132
|
+
}
|
|
2133
|
+
function assertProviderExists(name) {
|
|
2134
|
+
if (isBuiltinEndpoint(name) || isCustomEndpoint(name)) {
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
console.error(`错误: 未找到 endpoint "${name}"`);
|
|
2138
|
+
console.log('使用 "runcc list" 查看可用的 endpoints');
|
|
2139
|
+
process.exit(1);
|
|
2140
|
+
}
|
|
2141
|
+
async function promptToken(providerName) {
|
|
2142
|
+
const rl = createInterface2({
|
|
2143
|
+
input: process.stdin,
|
|
2144
|
+
output: process.stdout
|
|
2145
|
+
});
|
|
2146
|
+
return new Promise((resolve) => {
|
|
2147
|
+
rl.question(`请输入 ${providerName} 的 API Token: `, (answer) => {
|
|
2148
|
+
rl.close();
|
|
2149
|
+
resolve(answer.trim());
|
|
2150
|
+
});
|
|
2151
|
+
});
|
|
2152
|
+
}
|
|
2153
|
+
async function tokenSet(provider, token) {
|
|
2154
|
+
assertProviderExists(provider);
|
|
2155
|
+
let finalToken = token;
|
|
2156
|
+
if (!finalToken) {
|
|
2157
|
+
finalToken = await promptToken(provider);
|
|
2158
|
+
}
|
|
2159
|
+
if (isBuiltinEndpoint(provider)) {
|
|
2160
|
+
saveToken(provider, finalToken);
|
|
2161
|
+
} else {
|
|
2162
|
+
setCustomEndpointToken(provider, finalToken);
|
|
2163
|
+
}
|
|
2164
|
+
console.log(`已保存 ${provider} 的 token`);
|
|
2165
|
+
}
|
|
2166
|
+
function tokenClean(provider) {
|
|
2167
|
+
assertProviderExists(provider);
|
|
2168
|
+
if (isBuiltinEndpoint(provider)) {
|
|
2169
|
+
const existing = getToken(provider);
|
|
2170
|
+
if (existing) {
|
|
2171
|
+
clearToken(provider);
|
|
2172
|
+
console.log(`已清除 ${provider} 的 token`);
|
|
2173
|
+
} else {
|
|
2174
|
+
console.log(`未配置 ${provider} 的 token`);
|
|
2175
|
+
}
|
|
2176
|
+
return;
|
|
2177
|
+
}
|
|
2178
|
+
const endpoints = getCustomEndpoints();
|
|
2179
|
+
const endpoint = endpoints.find((ep) => ep.name === provider);
|
|
2180
|
+
const hadToken = !!endpoint?.token;
|
|
2181
|
+
setCustomEndpointToken(provider, undefined);
|
|
2182
|
+
if (hadToken) {
|
|
2183
|
+
console.log(`已清除 ${provider} 的 token`);
|
|
2184
|
+
} else {
|
|
2185
|
+
console.log(`未配置 ${provider} 的 token`);
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
// src/commands/proxy.ts
|
|
2190
|
+
import { createInterface as createInterface3 } from "node:readline";
|
|
2102
2191
|
|
|
2103
2192
|
// src/utils/claude-settings.ts
|
|
2104
2193
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
@@ -2270,7 +2359,7 @@ function proxyHelp() {
|
|
|
2270
2359
|
`);
|
|
2271
2360
|
}
|
|
2272
2361
|
async function promptProxyUrl() {
|
|
2273
|
-
const rl =
|
|
2362
|
+
const rl = createInterface3({
|
|
2274
2363
|
input: process.stdin,
|
|
2275
2364
|
output: process.stdout
|
|
2276
2365
|
});
|
|
@@ -2283,7 +2372,7 @@ async function promptProxyUrl() {
|
|
|
2283
2372
|
}
|
|
2284
2373
|
|
|
2285
2374
|
// src/commands/run.ts
|
|
2286
|
-
import { createInterface as
|
|
2375
|
+
import { createInterface as createInterface4 } from "node:readline";
|
|
2287
2376
|
|
|
2288
2377
|
// src/utils/launcher.ts
|
|
2289
2378
|
import { spawn } from "node:child_process";
|
|
@@ -2387,7 +2476,7 @@ async function runProvider(providerName, configureClaude, passthroughArgs = [])
|
|
|
2387
2476
|
}
|
|
2388
2477
|
let token = endpoint.token || getToken(providerName);
|
|
2389
2478
|
if (!token) {
|
|
2390
|
-
token = await
|
|
2479
|
+
token = await promptToken2(providerName);
|
|
2391
2480
|
saveToken(providerName, token);
|
|
2392
2481
|
}
|
|
2393
2482
|
setLastUsed(providerName);
|
|
@@ -2439,8 +2528,8 @@ function getEndpointConfig(name) {
|
|
|
2439
2528
|
const custom = getCustomEndpoints();
|
|
2440
2529
|
return custom.find((ep) => ep.name === name);
|
|
2441
2530
|
}
|
|
2442
|
-
async function
|
|
2443
|
-
const rl =
|
|
2531
|
+
async function promptToken2(providerName) {
|
|
2532
|
+
const rl = createInterface4({
|
|
2444
2533
|
input: process.stdin,
|
|
2445
2534
|
output: process.stdout
|
|
2446
2535
|
});
|
|
@@ -2508,6 +2597,9 @@ program2.name("runcc").description("Claude 启动器 - 支持切换不同的 API
|
|
|
2508
2597
|
program2.command("list").description("列出所有可用的 endpoints").action(list);
|
|
2509
2598
|
program2.command("add").description("添加自定义 endpoint").argument("<name>", "endpoint 名称").argument("<endpoint>", "API 地址").action(add);
|
|
2510
2599
|
program2.command("remove").description("删除自定义 endpoint").argument("<name>", "endpoint 名称").action(remove);
|
|
2600
|
+
var tokenCmd = program2.command("token").description("token 管理");
|
|
2601
|
+
tokenCmd.command("set").description("设置 token").argument("<provider>", "provider 名称 (glm, deepseek, minimax 或自定义)").argument("[token]", "API Token(可选,不传则交互输入)").action(tokenSet);
|
|
2602
|
+
tokenCmd.command("clean").alias("clear").description("清除 token").argument("<provider>", "provider 名称 (glm, deepseek, minimax 或自定义)").action(tokenClean);
|
|
2511
2603
|
var proxyCmd = program2.command("proxy").description("代理管理");
|
|
2512
2604
|
proxyCmd.command("on").description("开启代理").action(proxyOn);
|
|
2513
2605
|
proxyCmd.command("off").description("关闭代理").action(proxyOff);
|