tokenmix 0.2.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/LICENSE +21 -0
- package/README.md +72 -0
- package/bin/tokenmix.js +12 -0
- package/dist/agents/aider.js +58 -0
- package/dist/agents/aider.js.map +1 -0
- package/dist/agents/claude.js +82 -0
- package/dist/agents/claude.js.map +1 -0
- package/dist/agents/kilo.js +47 -0
- package/dist/agents/kilo.js.map +1 -0
- package/dist/agents/opencode.js +91 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/registry.js +15 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/api/client.js +128 -0
- package/dist/api/client.js.map +1 -0
- package/dist/cli.js +54 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agent-runner.js +84 -0
- package/dist/commands/agent-runner.js.map +1 -0
- package/dist/commands/balance.js +17 -0
- package/dist/commands/balance.js.map +1 -0
- package/dist/commands/doctor.js +48 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/list.js +23 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.js +114 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +7 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/models.js +52 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/topup.js +8 -0
- package/dist/commands/topup.js.map +1 -0
- package/dist/config/paths.js +17 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/store.js +41 -0
- package/dist/config/store.js.map +1 -0
- package/dist/utils/browser.js +5 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/exec.js +22 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/logger.js +23 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/prompt.js +30 -0
- package/dist/utils/prompt.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { readConfig, apiBaseUrl } from '../config/store.js';
|
|
3
|
+
import { confirm } from '../utils/prompt.js';
|
|
4
|
+
import { AGENTS } from '../agents/registry.js';
|
|
5
|
+
const DEFAULT_MODEL = 'claude-sonnet-4.6';
|
|
6
|
+
export function registerAgentCommands(program) {
|
|
7
|
+
for (const agent of AGENTS) {
|
|
8
|
+
if (agent.registerCommand) {
|
|
9
|
+
agent.registerCommand(program);
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
program
|
|
13
|
+
.command(`${agent.id} [args...]`)
|
|
14
|
+
.description(`Configure and launch ${agent.displayName} via TokenMix`)
|
|
15
|
+
.allowUnknownOption(true)
|
|
16
|
+
.action(async (args = []) => {
|
|
17
|
+
await runAgent(agent, args);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async function runAgent(agent, args) {
|
|
22
|
+
const cfg = await readConfig();
|
|
23
|
+
if (!cfg.apiKey) {
|
|
24
|
+
logger.error('Not logged in. Run `tokenmix login` first.');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const baseUrl = apiBaseUrl(cfg);
|
|
28
|
+
const defaultModel = cfg.defaultModel || DEFAULT_MODEL;
|
|
29
|
+
// 1. Check install status.
|
|
30
|
+
const status = await agent.installCheck();
|
|
31
|
+
if (!status.installed) {
|
|
32
|
+
if (agent.install) {
|
|
33
|
+
const shouldInstall = await confirm(`${agent.displayName} is not installed. Install now?`, true);
|
|
34
|
+
if (!shouldInstall) {
|
|
35
|
+
if (status.hint)
|
|
36
|
+
logger.warn(status.hint);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
logger.step(`Installing ${agent.displayName} ...`);
|
|
40
|
+
await agent.install();
|
|
41
|
+
logger.success(`${agent.displayName} installed.`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
logger.warn(status.hint || `${agent.displayName} is not installable from the CLI.`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// 2. Configure with tokenmix credentials.
|
|
49
|
+
logger.step(`Configuring ${agent.displayName} ...`);
|
|
50
|
+
const result = await agent.configure(cfg.apiKey, baseUrl, defaultModel);
|
|
51
|
+
if (result.configPath) {
|
|
52
|
+
logger.success(`Wrote ${result.configPath}`);
|
|
53
|
+
}
|
|
54
|
+
if (result.notes && result.notes.length > 0) {
|
|
55
|
+
for (const note of result.notes) {
|
|
56
|
+
if (note === '')
|
|
57
|
+
console.log();
|
|
58
|
+
else
|
|
59
|
+
console.log(` ${note}`);
|
|
60
|
+
}
|
|
61
|
+
console.log();
|
|
62
|
+
}
|
|
63
|
+
// 3. Launch (or stop if the agent has no CLI launcher).
|
|
64
|
+
if (!agent.launch) {
|
|
65
|
+
logger.info(`${agent.displayName} configuration ready.`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
logger.step(`Launching ${agent.displayName} ...`);
|
|
69
|
+
const env = {
|
|
70
|
+
...(result.envVars ?? {}),
|
|
71
|
+
TOKENMIX_DEFAULT_MODEL: defaultModel,
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
await agent.launch(args, env);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const e = err;
|
|
78
|
+
if (typeof e.exitCode === 'number' && e.exitCode !== 0) {
|
|
79
|
+
process.exit(e.exitCode);
|
|
80
|
+
}
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=agent-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../../src/commands/agent-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { openInBrowser } from '../utils/browser.js';
|
|
3
|
+
import { readConfig } from '../config/store.js';
|
|
4
|
+
// v0.1: balance lookup over API requires a user JWT, which we do not yet have
|
|
5
|
+
// (the CLI uses an API Key today). We open the dashboard instead.
|
|
6
|
+
// Once the device-flow login lands in the backend, this will hit /api/user/wallet directly.
|
|
7
|
+
const DASHBOARD_URL = 'https://tokenmix.ai/dashboard';
|
|
8
|
+
export async function balanceCommand() {
|
|
9
|
+
const cfg = await readConfig();
|
|
10
|
+
if (!cfg.apiKey) {
|
|
11
|
+
logger.error('Not logged in. Run `tokenmix login` first.');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
logger.step(`Opening dashboard to view balance: ${DASHBOARD_URL}`);
|
|
15
|
+
await openInBrowser(DASHBOARD_URL);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=balance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,8EAA8E;AAC9E,kEAAkE;AAClE,4FAA4F;AAC5F,MAAM,aAAa,GAAG,+BAA+B,CAAA;AAErD,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,GAAG,GAAG,MAAM,UAAU,EAAE,CAAA;IAC9B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAA;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,sCAAsC,aAAa,EAAE,CAAC,CAAA;IAClE,MAAM,aAAa,CAAC,aAAa,CAAC,CAAA;AACpC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
import { readConfig, apiBaseUrl } from '../config/store.js';
|
|
4
|
+
import { verifyApiKey } from '../api/client.js';
|
|
5
|
+
import { AGENTS } from '../agents/registry.js';
|
|
6
|
+
function maskKey(key) {
|
|
7
|
+
if (key.length <= 12)
|
|
8
|
+
return key;
|
|
9
|
+
return `${key.slice(0, 8)}${'*'.repeat(8)}${key.slice(-4)}`;
|
|
10
|
+
}
|
|
11
|
+
export async function doctorCommand() {
|
|
12
|
+
console.log();
|
|
13
|
+
console.log(chalk.bold('TokenMix CLI diagnostic'));
|
|
14
|
+
console.log();
|
|
15
|
+
const cfg = await readConfig();
|
|
16
|
+
console.log(chalk.bold('Credentials:'));
|
|
17
|
+
if (cfg.apiKey) {
|
|
18
|
+
logger.success(`API key: ${chalk.cyan(maskKey(cfg.apiKey))}`);
|
|
19
|
+
logger.success(`API base: ${chalk.cyan(apiBaseUrl(cfg))}`);
|
|
20
|
+
const ok = await verifyApiKey(cfg.apiKey, apiBaseUrl(cfg));
|
|
21
|
+
if (ok) {
|
|
22
|
+
logger.success('API key is valid.');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
logger.error('API key did NOT validate. Run `tokenmix login` again.');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
logger.warn('Not logged in. Run `tokenmix login`.');
|
|
30
|
+
}
|
|
31
|
+
console.log();
|
|
32
|
+
console.log(chalk.bold('Agent install status:'));
|
|
33
|
+
for (const a of AGENTS) {
|
|
34
|
+
const r = await a.installCheck();
|
|
35
|
+
if (r.installed) {
|
|
36
|
+
logger.success(`${a.displayName.padEnd(14)} installed${r.version ? ` (${chalk.dim(r.version)})` : ''}`);
|
|
37
|
+
if (r.hint)
|
|
38
|
+
console.log(` ${chalk.dim(r.hint)}`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
logger.warn(`${a.displayName.padEnd(14)} not installed`);
|
|
42
|
+
if (r.hint)
|
|
43
|
+
console.log(` ${chalk.dim(r.hint)}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
console.log();
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,GAAG,CAAA;IAChC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAA;IAClD,OAAO,CAAC,GAAG,EAAE,CAAA;IAEb,MAAM,GAAG,GAAG,MAAM,UAAU,EAAE,CAAA;IAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAA;IACvC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,CAAC,OAAO,CAAC,eAAe,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAA;QAChE,MAAM,CAAC,OAAO,CAAC,eAAe,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAA;QAC5D,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1D,IAAI,EAAE,EAAE,CAAC;YACP,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;QACrC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAA;QACvE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAA;IACrD,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAA;IAChD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,YAAY,EAAE,CAAA;QAChC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAChB,MAAM,CAAC,OAAO,CACZ,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACxF,CAAA;YACD,IAAI,CAAC,CAAC,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAA;YACxD,IAAI,CAAC,CAAC,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACrD,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { AGENTS } from '../agents/registry.js';
|
|
3
|
+
const MODE_LABEL = {
|
|
4
|
+
'auto-npm': 'auto (npm)',
|
|
5
|
+
'auto-pip': 'semi (pip)',
|
|
6
|
+
'manual-vscode': 'config-only (VSCode)',
|
|
7
|
+
manual: 'manual',
|
|
8
|
+
};
|
|
9
|
+
export async function listCommand() {
|
|
10
|
+
console.log();
|
|
11
|
+
console.log(chalk.bold('Supported agents:'));
|
|
12
|
+
console.log();
|
|
13
|
+
for (const a of AGENTS) {
|
|
14
|
+
const id = chalk.cyan(a.id.padEnd(10));
|
|
15
|
+
const mode = chalk.dim(`[${MODE_LABEL[a.installMode] ?? a.installMode}]`);
|
|
16
|
+
console.log(` ${id} ${a.displayName.padEnd(14)} ${mode}`);
|
|
17
|
+
console.log(` ${chalk.dim(a.description)}`);
|
|
18
|
+
}
|
|
19
|
+
console.log();
|
|
20
|
+
console.log(chalk.dim('Usage: tokenmix <agent> [args...]'));
|
|
21
|
+
console.log();
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,MAAM,UAAU,GAA2B;IACzC,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,eAAe,EAAE,sBAAsB;IACvC,MAAM,EAAE,QAAQ;CACjB,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAC5C,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAA;QACzE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;QAC1D,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAA;IAC3D,OAAO,CAAC,GAAG,EAAE,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
import { promptApiKey, confirm } from '../utils/prompt.js';
|
|
4
|
+
import { openInBrowser } from '../utils/browser.js';
|
|
5
|
+
import { verifyApiKey, startDeviceAuthorization, pollDeviceToken, DeviceFlowError, } from '../api/client.js';
|
|
6
|
+
import { readConfig, updateConfig, apiBaseUrl } from '../config/store.js';
|
|
7
|
+
export async function loginCommand(opts) {
|
|
8
|
+
const cfg = await readConfig();
|
|
9
|
+
const baseUrl = opts.url || apiBaseUrl(cfg);
|
|
10
|
+
// 显式 --key 走老路径(适合 CI/无浏览器环境)
|
|
11
|
+
if (opts.key) {
|
|
12
|
+
await loginByKey(opts.key, baseUrl);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
// 显式 --paste 让用户手动粘贴
|
|
16
|
+
if (opts.paste) {
|
|
17
|
+
const entered = await promptApiKey();
|
|
18
|
+
if (!entered) {
|
|
19
|
+
logger.error('No API key provided.');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
await loginByKey(entered, baseUrl);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// 默认走 device flow(浏览器扫码授权)
|
|
26
|
+
await loginByDeviceFlow(baseUrl);
|
|
27
|
+
}
|
|
28
|
+
async function loginByKey(apiKey, baseUrl) {
|
|
29
|
+
if (!apiKey.startsWith('sk-tm-')) {
|
|
30
|
+
logger.error('API key should start with sk-tm-');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
logger.step(`Verifying API key against ${baseUrl} ...`);
|
|
34
|
+
const ok = await verifyApiKey(apiKey, baseUrl);
|
|
35
|
+
if (!ok) {
|
|
36
|
+
logger.error('API key verification failed. Double-check at https://tokenmix.ai/dashboard/keys');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
await updateConfig({ apiKey, apiBaseUrl: baseUrl });
|
|
40
|
+
logger.success('Logged in. Try `tokenmix opencode` to launch your first agent.');
|
|
41
|
+
}
|
|
42
|
+
async function loginByDeviceFlow(baseUrl) {
|
|
43
|
+
logger.step('Requesting device authorization ...');
|
|
44
|
+
let auth;
|
|
45
|
+
try {
|
|
46
|
+
auth = await startDeviceAuthorization(baseUrl);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
50
|
+
logger.error(`Could not start device authorization: ${msg}`);
|
|
51
|
+
logger.info('Falling back to manual paste. Get an API key at https://tokenmix.ai/dashboard/keys');
|
|
52
|
+
const entered = await promptApiKey();
|
|
53
|
+
if (!entered)
|
|
54
|
+
process.exit(1);
|
|
55
|
+
await loginByKey(entered, baseUrl);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Display user_code prominently
|
|
59
|
+
console.log();
|
|
60
|
+
console.log(' ' + chalk.dim('Open the link below and confirm this code:'));
|
|
61
|
+
console.log();
|
|
62
|
+
console.log(' ' + chalk.bold.cyan(auth.user_code));
|
|
63
|
+
console.log();
|
|
64
|
+
console.log(' ' + chalk.dim('Link:'));
|
|
65
|
+
console.log(' ' + chalk.underline(auth.verification_uri_complete));
|
|
66
|
+
console.log();
|
|
67
|
+
// Try to open browser, but proceed even if it fails (headless / SSH)
|
|
68
|
+
try {
|
|
69
|
+
await openInBrowser(auth.verification_uri_complete);
|
|
70
|
+
logger.dim(' (browser opened; if nothing happens, copy the link above)');
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
logger.dim(' (could not open browser; copy the link above into one)');
|
|
74
|
+
}
|
|
75
|
+
console.log();
|
|
76
|
+
logger.step(`Waiting for authorization (expires in ${auth.expires_in}s, polling every ${auth.interval}s) ...`);
|
|
77
|
+
let lastReported = -1;
|
|
78
|
+
try {
|
|
79
|
+
const result = await pollDeviceToken(baseUrl, auth, (secondsRemaining) => {
|
|
80
|
+
// Print a heartbeat at most every 15s so the terminal isn't silent
|
|
81
|
+
if (lastReported < 0 || lastReported - secondsRemaining >= 15) {
|
|
82
|
+
lastReported = secondsRemaining;
|
|
83
|
+
logger.dim(` ... still waiting (${secondsRemaining}s remaining)`);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
await updateConfig({ apiKey: result.apiKey, apiBaseUrl: baseUrl });
|
|
87
|
+
console.log();
|
|
88
|
+
if (result.userEmail) {
|
|
89
|
+
logger.success(`Logged in as ${chalk.bold(result.userEmail)} (API key #${result.apiKeyId})`);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
logger.success(`Logged in (API key #${result.apiKeyId})`);
|
|
93
|
+
}
|
|
94
|
+
logger.info('Try `tokenmix opencode` to launch your first agent.');
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
console.log();
|
|
98
|
+
if (err instanceof DeviceFlowError) {
|
|
99
|
+
logger.error(err.message);
|
|
100
|
+
if (err.code === 'expired_token' || err.code === 'timeout') {
|
|
101
|
+
const retry = await confirm('Try again?', true);
|
|
102
|
+
if (retry) {
|
|
103
|
+
await loginByDeviceFlow(baseUrl);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
110
|
+
}
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { clearConfig } from '../config/store.js';
|
|
3
|
+
export async function logoutCommand() {
|
|
4
|
+
await clearConfig();
|
|
5
|
+
logger.success('Logged out. Credentials removed from this machine.');
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,WAAW,EAAE,CAAA;IACnB,MAAM,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAA;AACtE,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
import { listPublicModels } from '../api/client.js';
|
|
4
|
+
const TYPE_LABEL = {
|
|
5
|
+
chat: 'Chat',
|
|
6
|
+
embedding: 'Embedding',
|
|
7
|
+
image: 'Image',
|
|
8
|
+
audio: 'Audio',
|
|
9
|
+
video: 'Video',
|
|
10
|
+
completion: 'Completion',
|
|
11
|
+
};
|
|
12
|
+
// Match the platform-wide formatter: 6 decimals, trim trailing zeros.
|
|
13
|
+
function formatPrice(p) {
|
|
14
|
+
if (!p)
|
|
15
|
+
return '-';
|
|
16
|
+
return p.toFixed(6).replace(/\.?0+$/, '');
|
|
17
|
+
}
|
|
18
|
+
export async function modelsCommand(opts) {
|
|
19
|
+
const all = await listPublicModels();
|
|
20
|
+
const filtered = opts.type ? all.filter((m) => m.model_type === opts.type) : all;
|
|
21
|
+
if (filtered.length === 0) {
|
|
22
|
+
logger.warn('No models match the filter.');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const grouped = new Map();
|
|
26
|
+
for (const m of filtered) {
|
|
27
|
+
const list = grouped.get(m.model_type) ?? [];
|
|
28
|
+
list.push(m);
|
|
29
|
+
grouped.set(m.model_type, list);
|
|
30
|
+
}
|
|
31
|
+
for (const [type, list] of grouped) {
|
|
32
|
+
console.log();
|
|
33
|
+
console.log(chalk.bold(`${TYPE_LABEL[type] ?? type} (${list.length})`));
|
|
34
|
+
for (const m of list) {
|
|
35
|
+
const id = chalk.cyan(m.short_id || m.model_id);
|
|
36
|
+
const priceParts = [];
|
|
37
|
+
if (type === 'chat' || type === 'embedding' || type === 'audio' || type === 'completion') {
|
|
38
|
+
priceParts.push(`in $${formatPrice(m.input_price)}/M`);
|
|
39
|
+
priceParts.push(`out $${formatPrice(m.output_price)}/M`);
|
|
40
|
+
}
|
|
41
|
+
else if (type === 'image') {
|
|
42
|
+
priceParts.push(`$${formatPrice(m.image_price)}/img`);
|
|
43
|
+
}
|
|
44
|
+
else if (type === 'video') {
|
|
45
|
+
priceParts.push(`$${formatPrice(m.video_price)}/s`);
|
|
46
|
+
}
|
|
47
|
+
console.log(` ${id} ${chalk.dim(priceParts.join(' · '))}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
console.log();
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/commands/models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { openInBrowser } from '../utils/browser.js';
|
|
3
|
+
const TOPUP_URL = 'https://tokenmix.ai/dashboard/credits';
|
|
4
|
+
export async function topupCommand() {
|
|
5
|
+
logger.step(`Opening top-up page: ${TOPUP_URL}`);
|
|
6
|
+
await openInBrowser(TOPUP_URL);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=topup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topup.js","sourceRoot":"","sources":["../../src/commands/topup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,SAAS,GAAG,uCAAuC,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,CAAC,IAAI,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAA;IAChD,MAAM,aAAa,CAAC,SAAS,CAAC,CAAA;AAChC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
// Per-platform config directory for tokenmix CLI itself.
|
|
4
|
+
// Distinct from per-agent config (e.g. ~/.config/opencode/opencode.json).
|
|
5
|
+
export function configDir() {
|
|
6
|
+
if (process.platform === 'darwin') {
|
|
7
|
+
return path.join(os.homedir(), 'Library', 'Application Support', 'tokenmix');
|
|
8
|
+
}
|
|
9
|
+
if (process.platform === 'win32') {
|
|
10
|
+
return path.join(process.env.APPDATA || os.homedir(), 'tokenmix');
|
|
11
|
+
}
|
|
12
|
+
return path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'), 'tokenmix');
|
|
13
|
+
}
|
|
14
|
+
export function configFile() {
|
|
15
|
+
return path.join(configDir(), 'config.json');
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/config/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,yDAAyD;AACzD,0EAA0E;AAC1E,MAAM,UAAU,SAAS;IACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAA;IAC9E,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;IACnE,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,CAAA;AACjG,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAA;AAC9C,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { configDir, configFile } from './paths.js';
|
|
3
|
+
const DEFAULT_API_BASE = 'https://api.tokenmix.ai';
|
|
4
|
+
export async function readConfig() {
|
|
5
|
+
try {
|
|
6
|
+
const raw = await fs.readFile(configFile(), 'utf-8');
|
|
7
|
+
return JSON.parse(raw);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function writeConfig(cfg) {
|
|
14
|
+
await fs.ensureDir(configDir());
|
|
15
|
+
await fs.writeFile(configFile(), JSON.stringify(cfg, null, 2));
|
|
16
|
+
// Restrict to owner read/write only (best-effort on Windows).
|
|
17
|
+
try {
|
|
18
|
+
await fs.chmod(configFile(), 0o600);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// ignore on filesystems that don't support chmod
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function updateConfig(patch) {
|
|
25
|
+
const current = await readConfig();
|
|
26
|
+
const next = { ...current, ...patch };
|
|
27
|
+
await writeConfig(next);
|
|
28
|
+
return next;
|
|
29
|
+
}
|
|
30
|
+
export async function clearConfig() {
|
|
31
|
+
try {
|
|
32
|
+
await fs.remove(configFile());
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// ignore
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function apiBaseUrl(cfg) {
|
|
39
|
+
return cfg?.apiBaseUrl || DEFAULT_API_BASE;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/config/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAUlD,MAAM,gBAAgB,GAAG,yBAAyB,CAAA;AAElD,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAA;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAe;IAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAA;IAC/B,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9D,8DAA8D;IAC9D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAA0B;IAC3D,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAA;IAClC,MAAM,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,CAAA;IACrC,MAAM,WAAW,CAAC,IAAI,CAAC,CAAA;IACvB,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAoC;IAC7D,OAAO,GAAG,EAAE,UAAU,IAAI,gBAAgB,CAAA;AAC5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW;IAC7C,MAAM,IAAI,CAAC,GAAG,CAAC,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import which from 'which';
|
|
3
|
+
export async function commandExists(cmd) {
|
|
4
|
+
try {
|
|
5
|
+
return await which(cmd);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export async function run(cmd, args, opts = {}) {
|
|
12
|
+
await execa(cmd, args, {
|
|
13
|
+
stdio: opts.stdio ?? 'inherit',
|
|
14
|
+
env: { ...process.env, ...(opts.env ?? {}) },
|
|
15
|
+
cwd: opts.cwd,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export async function captureRun(cmd, args) {
|
|
19
|
+
const r = await execa(cmd, args, { stdio: 'pipe' });
|
|
20
|
+
return { stdout: r.stdout?.toString() ?? '', stderr: r.stderr?.toString() ?? '' };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW;IAC7C,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,GAAW,EAAE,IAAc,EAAE,OAAmB,EAAE;IAC1E,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;QAC9B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;QAC5C,GAAG,EAAE,IAAI,CAAC,GAAG;KACd,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,IAAc;IAC1D,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACnD,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAA;AACnF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
// Minimal CLI logger. Symbols are ASCII-friendly Unicode, not emoji.
|
|
3
|
+
export const logger = {
|
|
4
|
+
info(msg) {
|
|
5
|
+
console.log(msg);
|
|
6
|
+
},
|
|
7
|
+
success(msg) {
|
|
8
|
+
console.log(chalk.green('✓'), msg);
|
|
9
|
+
},
|
|
10
|
+
warn(msg) {
|
|
11
|
+
console.log(chalk.yellow('!'), msg);
|
|
12
|
+
},
|
|
13
|
+
error(msg) {
|
|
14
|
+
console.error(chalk.red('✗'), msg);
|
|
15
|
+
},
|
|
16
|
+
step(msg) {
|
|
17
|
+
console.log(chalk.cyan('→'), msg);
|
|
18
|
+
},
|
|
19
|
+
dim(msg) {
|
|
20
|
+
console.log(chalk.dim(msg));
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,qEAAqE;AACrE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAClB,CAAC;IACD,OAAO,CAAC,GAAW;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IACD,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACrC,CAAC;IACD,KAAK,CAAC,GAAW;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IACD,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACnC,CAAC;IACD,GAAG,CAAC,GAAW;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7B,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
export async function promptApiKey() {
|
|
3
|
+
const r = await prompts({
|
|
4
|
+
type: 'password',
|
|
5
|
+
name: 'apiKey',
|
|
6
|
+
message: 'Paste your TokenMix API key (sk-tm-...)',
|
|
7
|
+
validate: (v) => v && v.startsWith('sk-tm-') ? true : 'API key should start with sk-tm-',
|
|
8
|
+
});
|
|
9
|
+
const key = r.apiKey?.trim();
|
|
10
|
+
return key || null;
|
|
11
|
+
}
|
|
12
|
+
export async function confirm(message, initial = true) {
|
|
13
|
+
const r = await prompts({
|
|
14
|
+
type: 'confirm',
|
|
15
|
+
name: 'ok',
|
|
16
|
+
message,
|
|
17
|
+
initial,
|
|
18
|
+
});
|
|
19
|
+
return Boolean(r.ok);
|
|
20
|
+
}
|
|
21
|
+
export async function select(message, choices) {
|
|
22
|
+
const r = await prompts({
|
|
23
|
+
type: 'select',
|
|
24
|
+
name: 'value',
|
|
25
|
+
message,
|
|
26
|
+
choices,
|
|
27
|
+
});
|
|
28
|
+
return r.value ?? null;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC;QACtB,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,yCAAyC;QAClD,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CACtB,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kCAAkC;KAC1E,CAAC,CAAA;IACF,MAAM,GAAG,GAAI,CAAC,CAAC,MAA6B,EAAE,IAAI,EAAE,CAAA;IACpD,OAAO,GAAG,IAAI,IAAI,CAAA;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAe,EAAE,UAAmB,IAAI;IACpE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC;QACtB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,IAAI;QACV,OAAO;QACP,OAAO;KACR,CAAC,CAAA;IACF,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACtB,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAe,EACf,OAA0B;IAE1B,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC;QACtB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO;QACb,OAAO;QACP,OAAO;KACR,CAAC,CAAA;IACF,OAAQ,CAAC,CAAC,KAAW,IAAI,IAAI,CAAA;AAC/B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tokenmix",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Zero-config CLI to use any open-source coding agent with TokenMix as the unified LLM backend.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"tokenmix": "./bin/tokenmix.js"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"tokenmix",
|
|
14
|
+
"ai",
|
|
15
|
+
"agent",
|
|
16
|
+
"cli",
|
|
17
|
+
"opencode",
|
|
18
|
+
"claude-code",
|
|
19
|
+
"aider",
|
|
20
|
+
"kilo",
|
|
21
|
+
"coding-agent"
|
|
22
|
+
],
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"homepage": "https://tokenmix.ai",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/tokenmix/tokenmix-cli.git"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin",
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"axios": "^1.7.7",
|
|
37
|
+
"chalk": "^5.3.0",
|
|
38
|
+
"commander": "^12.1.0",
|
|
39
|
+
"execa": "^9.5.1",
|
|
40
|
+
"fs-extra": "^11.2.0",
|
|
41
|
+
"open": "^10.1.0",
|
|
42
|
+
"prompts": "^2.4.2",
|
|
43
|
+
"which": "^5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/fs-extra": "^11.0.4",
|
|
47
|
+
"@types/node": "^22.9.0",
|
|
48
|
+
"@types/prompts": "^2.4.9",
|
|
49
|
+
"@types/which": "^3.0.4",
|
|
50
|
+
"tsx": "^4.19.2",
|
|
51
|
+
"typescript": "^5.6.3"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc",
|
|
55
|
+
"dev": "tsx src/cli.ts",
|
|
56
|
+
"start": "node bin/tokenmix.js",
|
|
57
|
+
"typecheck": "tsc --noEmit"
|
|
58
|
+
}
|
|
59
|
+
}
|