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 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/proxy.ts
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 = createInterface2({
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 createInterface3 } from "node:readline";
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 promptToken(providerName);
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 promptToken(providerName) {
2443
- const rl = createInterface3({
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcc",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "CC launcher with endpoint switching support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",