free-coding-models 0.3.37 → 0.3.40
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 +10 -1794
- package/README.md +4 -1
- package/bin/free-coding-models.js +8 -0
- package/package.json +13 -3
- package/src/app.js +3 -0
- package/src/cli-help.js +2 -0
- package/src/command-palette.js +3 -0
- package/src/endpoint-installer.js +1 -1
- package/src/tool-bootstrap.js +34 -0
- package/src/tool-launchers.js +137 -1
- package/src/tool-metadata.js +9 -0
- package/src/utils.js +10 -0
- package/web/app.legacy.js +900 -0
- package/web/index.html +20 -0
- package/web/server.js +382 -0
- package/web/src/App.jsx +150 -0
- package/web/src/components/analytics/AnalyticsView.jsx +109 -0
- package/web/src/components/analytics/AnalyticsView.module.css +186 -0
- package/web/src/components/atoms/Sparkline.jsx +44 -0
- package/web/src/components/atoms/StabilityCell.jsx +18 -0
- package/web/src/components/atoms/StabilityCell.module.css +8 -0
- package/web/src/components/atoms/StatusDot.jsx +10 -0
- package/web/src/components/atoms/StatusDot.module.css +17 -0
- package/web/src/components/atoms/TierBadge.jsx +10 -0
- package/web/src/components/atoms/TierBadge.module.css +18 -0
- package/web/src/components/atoms/Toast.jsx +25 -0
- package/web/src/components/atoms/Toast.module.css +35 -0
- package/web/src/components/atoms/ToastContainer.jsx +16 -0
- package/web/src/components/atoms/ToastContainer.module.css +10 -0
- package/web/src/components/atoms/VerdictBadge.jsx +13 -0
- package/web/src/components/atoms/VerdictBadge.module.css +19 -0
- package/web/src/components/dashboard/DetailPanel.jsx +131 -0
- package/web/src/components/dashboard/DetailPanel.module.css +99 -0
- package/web/src/components/dashboard/ExportModal.jsx +79 -0
- package/web/src/components/dashboard/ExportModal.module.css +99 -0
- package/web/src/components/dashboard/FilterBar.jsx +73 -0
- package/web/src/components/dashboard/FilterBar.module.css +43 -0
- package/web/src/components/dashboard/ModelTable.jsx +86 -0
- package/web/src/components/dashboard/ModelTable.module.css +46 -0
- package/web/src/components/dashboard/StatsBar.jsx +40 -0
- package/web/src/components/dashboard/StatsBar.module.css +28 -0
- package/web/src/components/layout/Footer.jsx +19 -0
- package/web/src/components/layout/Footer.module.css +10 -0
- package/web/src/components/layout/Header.jsx +38 -0
- package/web/src/components/layout/Header.module.css +73 -0
- package/web/src/components/layout/Sidebar.jsx +41 -0
- package/web/src/components/layout/Sidebar.module.css +76 -0
- package/web/src/components/settings/SettingsView.jsx +264 -0
- package/web/src/components/settings/SettingsView.module.css +377 -0
- package/web/src/global.css +199 -0
- package/web/src/hooks/useFilter.js +83 -0
- package/web/src/hooks/useSSE.js +49 -0
- package/web/src/hooks/useTheme.js +27 -0
- package/web/src/main.jsx +15 -0
- package/web/src/utils/download.js +15 -0
- package/web/src/utils/format.js +42 -0
- package/web/src/utils/ranks.js +37 -0
- package/web/styles.legacy.css +963 -0
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
16
|
<strong>Find the fastest free coding model in seconds</strong><br>
|
|
17
|
-
<sub>Ping 238 models across 25 AI Free providers in real-time </sub><br><sub> Install Free API endpoints to your favorite AI coding tool: <br>📦 OpenCode, 🦞 OpenClaw, 💘 Crush, 🪿 Goose, 🛠 Aider, 🐉 Qwen Code, 🤲 OpenHands, ⚡ Amp, π Pi, 🦘 Rovo or ♊ Gemini in one keystroke</sub>
|
|
17
|
+
<sub>Ping 238 models across 25 AI Free providers in real-time </sub><br><sub> Install Free API endpoints to your favorite AI coding tool: <br>📦 OpenCode, 🦞 OpenClaw, 💘 Crush, 🪿 Goose, 🛠 Aider, 🐉 Qwen Code, 🤲 OpenHands, ⚡ Amp, 🔮 Hermes, ▶️ Continue, 🧠 Cline, π Pi, 🦘 Rovo or ♊ Gemini in one keystroke</sub>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
|
|
@@ -182,6 +182,9 @@ free-coding-models --openclaw --origin groq
|
|
|
182
182
|
| `--qwen` | 🐉 Qwen Code |
|
|
183
183
|
| `--openhands` | 🤲 OpenHands |
|
|
184
184
|
| `--amp` | ⚡ Amp |
|
|
185
|
+
| `--hermes` | 🔮 Hermes |
|
|
186
|
+
| `--continue` | ▶️ Continue CLI |
|
|
187
|
+
| `--cline` | 🧠 Cline |
|
|
185
188
|
| `--pi` | π Pi |
|
|
186
189
|
| `--rovo` | 🦘 Rovo Dev CLI |
|
|
187
190
|
| `--gemini` | ♊ Gemini CLI |
|
|
@@ -46,6 +46,14 @@ async function main() {
|
|
|
46
46
|
process.exit(1);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// 📖 --web mode: launch the web dashboard instead of the TUI
|
|
50
|
+
if (cliArgs.webMode) {
|
|
51
|
+
const { startWebServer } = await import('../web/server.js')
|
|
52
|
+
const port = parseInt(process.env.FCM_PORT || '3333', 10)
|
|
53
|
+
await startWebServer(port, { open: true })
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
49
57
|
// 📖 Load JSON config
|
|
50
58
|
const config = loadConfig();
|
|
51
59
|
ensureTelemetryConfig(config);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.40",
|
|
4
4
|
"description": "Find the fastest coding LLM models in seconds — ping free models from multiple providers, pick the best one for OpenCode, Cursor, or any AI coding assistant.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nvidia",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"files": [
|
|
42
42
|
"bin/",
|
|
43
43
|
"src/",
|
|
44
|
+
"web/",
|
|
44
45
|
"sources.js",
|
|
45
46
|
"patch-openclaw.js",
|
|
46
47
|
"patch-openclaw-models.js",
|
|
@@ -51,16 +52,25 @@
|
|
|
51
52
|
"scripts": {
|
|
52
53
|
"start": "node bin/free-coding-models.js",
|
|
53
54
|
"test": "node --test test/test.js",
|
|
55
|
+
"dev:web": "node scripts/dev-web.mjs",
|
|
56
|
+
"build:web": "vite build",
|
|
57
|
+
"preview:web": "vite preview",
|
|
54
58
|
"test:fcm": "node scripts/testfcm-runner.mjs",
|
|
55
59
|
"test:fcm:mock": "node scripts/testfcm-runner.mjs --tool crush --tool-bin-dir test/fixtures/mock-bin"
|
|
56
60
|
},
|
|
57
61
|
"dependencies": {
|
|
58
|
-
"chalk": "^5.
|
|
62
|
+
"chalk": "^5.6.2"
|
|
59
63
|
},
|
|
64
|
+
"packageManager": "pnpm@10.24.0",
|
|
60
65
|
"engines": {
|
|
61
66
|
"node": ">=18.0.0"
|
|
62
67
|
},
|
|
63
68
|
"devDependencies": {
|
|
64
|
-
"@
|
|
69
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
70
|
+
"agent-tui": "^1.0.1",
|
|
71
|
+
"react": "^19.2.4",
|
|
72
|
+
"react-dom": "^19.2.4",
|
|
73
|
+
"vite": "^8.0.5",
|
|
74
|
+
"vite-plus": "^0.1.16"
|
|
65
75
|
}
|
|
66
76
|
}
|
package/src/app.js
CHANGED
|
@@ -233,6 +233,9 @@ export async function runApp(cliArgs, config) {
|
|
|
233
233
|
qwen: cliArgs.qwenMode,
|
|
234
234
|
openhands: cliArgs.openHandsMode,
|
|
235
235
|
amp: cliArgs.ampMode,
|
|
236
|
+
hermes: cliArgs.hermesMode,
|
|
237
|
+
'continue': cliArgs.continueMode,
|
|
238
|
+
cline: cliArgs.clineMode,
|
|
236
239
|
pi: cliArgs.piMode,
|
|
237
240
|
rovo: cliArgs.rovoMode,
|
|
238
241
|
gemini: cliArgs.geminiMode,
|
package/src/cli-help.js
CHANGED
|
@@ -36,12 +36,14 @@ const ANALYSIS_FLAGS = [
|
|
|
36
36
|
]
|
|
37
37
|
|
|
38
38
|
const CONFIG_FLAGS = [
|
|
39
|
+
{ flag: '--web', description: 'Launch the web dashboard in your browser' },
|
|
39
40
|
{ flag: '--no-telemetry', description: 'Disable anonymous telemetry for this run' },
|
|
40
41
|
{ flag: '--help, -h', description: 'Print this help and exit' },
|
|
41
42
|
]
|
|
42
43
|
|
|
43
44
|
const EXAMPLES = [
|
|
44
45
|
'free-coding-models --help',
|
|
46
|
+
'free-coding-models --web',
|
|
45
47
|
'free-coding-models --openclaw --tier S',
|
|
46
48
|
"free-coding-models --json | jq '.[0]'",
|
|
47
49
|
]
|
package/src/command-palette.js
CHANGED
|
@@ -28,6 +28,9 @@ const TOOL_MODE_DESCRIPTIONS = {
|
|
|
28
28
|
qwen: 'Launch Qwen Code using the selected provider model.',
|
|
29
29
|
openhands: 'Launch OpenHands with the selected model endpoint.',
|
|
30
30
|
amp: 'Launch Amp with this model as active target.',
|
|
31
|
+
hermes: 'Launch Hermes Agent with the selected model.',
|
|
32
|
+
'continue': 'Launch Continue CLI with the selected model.',
|
|
33
|
+
cline: 'Launch Cline CLI with the selected model.',
|
|
31
34
|
rovo: 'Rovo Dev CLI model (launch with Rovo tool only).',
|
|
32
35
|
gemini: 'Gemini CLI model (launch with Gemini tool only).',
|
|
33
36
|
}
|
|
@@ -52,7 +52,7 @@ import { getToolMeta } from './tool-metadata.js'
|
|
|
52
52
|
const DIRECT_INSTALL_UNSUPPORTED_PROVIDERS = new Set(['replicate', 'zai', 'rovo', 'gemini', 'opencode-zen'])
|
|
53
53
|
// 📖 Install Endpoints only lists tools whose persisted config shape is actually supported here.
|
|
54
54
|
// 📖 Claude Code, Codex, and Gemini stay out while their dedicated bridges are being rebuilt.
|
|
55
|
-
const INSTALL_TARGET_MODES = ['opencode', 'opencode-desktop', 'openclaw', 'crush', 'goose', 'pi', 'aider', 'qwen', 'openhands', 'amp']
|
|
55
|
+
const INSTALL_TARGET_MODES = ['opencode', 'opencode-desktop', 'openclaw', 'crush', 'goose', 'pi', 'aider', 'qwen', 'openhands', 'amp', 'hermes', 'continue', 'cline']
|
|
56
56
|
|
|
57
57
|
function getDefaultPaths() {
|
|
58
58
|
const home = homedir()
|
package/src/tool-bootstrap.js
CHANGED
|
@@ -228,6 +228,40 @@ export const TOOL_BOOTSTRAP_METADATA = {
|
|
|
228
228
|
},
|
|
229
229
|
},
|
|
230
230
|
},
|
|
231
|
+
'continue': {
|
|
232
|
+
binary: 'cn',
|
|
233
|
+
docsUrl: 'https://docs.continue.dev/cli/overview',
|
|
234
|
+
install: {
|
|
235
|
+
default: {
|
|
236
|
+
shellCommand: 'npm install -g @continuedev/cli',
|
|
237
|
+
summary: 'Install Continue CLI globally via npm.',
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
cline: {
|
|
242
|
+
binary: 'cline',
|
|
243
|
+
docsUrl: 'https://docs.cline.bot/cline-cli/overview',
|
|
244
|
+
install: {
|
|
245
|
+
default: {
|
|
246
|
+
shellCommand: 'npm install -g cline',
|
|
247
|
+
summary: 'Install Cline CLI globally via npm.',
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
hermes: {
|
|
252
|
+
binary: 'hermes',
|
|
253
|
+
docsUrl: 'https://github.com/NousResearch/hermes-agent',
|
|
254
|
+
install: {
|
|
255
|
+
default: {
|
|
256
|
+
shellCommand: 'curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash',
|
|
257
|
+
summary: 'Install Hermes Agent via the official Nous Research installer.',
|
|
258
|
+
note: 'Hermes requires Python 3.11+ and git. The installer handles everything else automatically.',
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
installUnsupported: {
|
|
262
|
+
win32: 'Hermes Agent does not support native Windows. Use WSL2 instead.',
|
|
263
|
+
},
|
|
264
|
+
},
|
|
231
265
|
gemini: {
|
|
232
266
|
binary: 'gemini',
|
|
233
267
|
docsUrl: 'https://github.com/google-gemini/gemini-cli',
|
package/src/tool-launchers.js
CHANGED
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
* 📖 Crush: writes crush.json with provider config + models.large/small defaults
|
|
18
18
|
* 📖 Pi: uses --provider/--model CLI flags for guaranteed auto-selection
|
|
19
19
|
* 📖 Aider: writes ~/.aider.conf.yml + passes --model flag
|
|
20
|
+
* 📖 Hermes: uses `hermes config set` CLI commands + `hermes gateway restart` before launching `hermes chat`
|
|
21
|
+
* 📖 Continue: writes ~/.continue/config.yaml with provider: openai + apiBase
|
|
22
|
+
* 📖 Cline: writes ~/.cline/globalState.json with openai-compatible provider config
|
|
20
23
|
*
|
|
21
24
|
* @functions
|
|
22
25
|
* → `resolveLauncherModelId` — choose the provider-specific id for a launch
|
|
@@ -36,7 +39,7 @@ import chalk from 'chalk'
|
|
|
36
39
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from 'fs'
|
|
37
40
|
import { homedir } from 'os'
|
|
38
41
|
import { dirname, join } from 'path'
|
|
39
|
-
import { spawn } from 'child_process'
|
|
42
|
+
import { spawn, spawnSync } from 'child_process'
|
|
40
43
|
import { sources } from '../sources.js'
|
|
41
44
|
import { PROVIDER_COLOR } from './render-table.js'
|
|
42
45
|
import { getApiKey } from './config.js'
|
|
@@ -73,6 +76,9 @@ function getDefaultToolPaths(homeDir = homedir()) {
|
|
|
73
76
|
piModelsPath: join(homeDir, '.pi', 'agent', 'models.json'),
|
|
74
77
|
piSettingsPath: join(homeDir, '.pi', 'agent', 'settings.json'),
|
|
75
78
|
openHandsEnvPath: join(homeDir, '.fcm-openhands-env'),
|
|
79
|
+
hermesConfigPath: join(homeDir, '.hermes', 'config.yaml'),
|
|
80
|
+
continueConfigPath: join(homeDir, '.continue', 'config.yaml'),
|
|
81
|
+
clineConfigPath: join(homeDir, '.cline', 'globalState.json'),
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
|
|
@@ -401,6 +407,80 @@ function writeRovoConfig(model, configPath = join(homedir(), '.rovodev', 'config
|
|
|
401
407
|
return { filePath: configPath, backupPath }
|
|
402
408
|
}
|
|
403
409
|
|
|
410
|
+
// 📖 writeContinueConfig — write ~/.continue/config.yaml with the selected model.
|
|
411
|
+
// 📖 Continue CLI uses YAML config with `provider: openai` for OpenAI-compatible endpoints.
|
|
412
|
+
function writeContinueConfig(model, apiKey, baseUrl, paths = getDefaultToolPaths()) {
|
|
413
|
+
const filePath = paths.continueConfigPath
|
|
414
|
+
const backupPath = backupIfExists(filePath)
|
|
415
|
+
// 📖 Write a minimal config.yaml that Continue CLI can parse directly
|
|
416
|
+
const content = [
|
|
417
|
+
'# 📖 Managed by free-coding-models',
|
|
418
|
+
'name: FCM Config',
|
|
419
|
+
'version: 0.0.1',
|
|
420
|
+
'schema: v1',
|
|
421
|
+
'models:',
|
|
422
|
+
' - name: ' + (model.label || model.modelId),
|
|
423
|
+
' provider: openai',
|
|
424
|
+
' model: ' + model.modelId,
|
|
425
|
+
...(baseUrl ? [' apiBase: ' + baseUrl] : []),
|
|
426
|
+
...(apiKey ? [' apiKey: ' + apiKey] : []),
|
|
427
|
+
' roles:',
|
|
428
|
+
' - chat',
|
|
429
|
+
' - edit',
|
|
430
|
+
' - apply',
|
|
431
|
+
'',
|
|
432
|
+
].join('\n')
|
|
433
|
+
ensureDir(filePath)
|
|
434
|
+
writeFileSync(filePath, content)
|
|
435
|
+
return { filePath, backupPath }
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// 📖 writeClineConfig — write ~/.cline/globalState.json with the selected model.
|
|
439
|
+
// 📖 Cline CLI stores provider config in globalState.json under apiConfiguration.
|
|
440
|
+
function writeClineConfig(model, apiKey, baseUrl, paths = getDefaultToolPaths()) {
|
|
441
|
+
const filePath = paths.clineConfigPath
|
|
442
|
+
const backupPath = backupIfExists(filePath)
|
|
443
|
+
const config = readJson(filePath, {})
|
|
444
|
+
// 📖 Set the API provider to "openai-compatible" and configure the endpoint
|
|
445
|
+
config.apiConfiguration = {
|
|
446
|
+
...(config.apiConfiguration || {}),
|
|
447
|
+
apiProvider: 'openai-compatible',
|
|
448
|
+
openAiCompatibleApiModelId: model.modelId,
|
|
449
|
+
...(baseUrl ? { openAiCompatibleApiBaseUrl: baseUrl } : {}),
|
|
450
|
+
...(apiKey ? { openAiCompatibleApiKey: apiKey } : {}),
|
|
451
|
+
}
|
|
452
|
+
writeJson(filePath, config)
|
|
453
|
+
return { filePath, backupPath }
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// 📖 writeHermesConfig — configure Hermes Agent via its own `hermes config set` CLI.
|
|
457
|
+
// 📖 This avoids YAML parsing and uses Hermes's native config management.
|
|
458
|
+
// 📖 Sets model name, base_url (OpenAI-compatible endpoint), and api_key.
|
|
459
|
+
function writeHermesConfig(model, apiKey, baseUrl, paths = getDefaultToolPaths()) {
|
|
460
|
+
const configPath = paths.hermesConfigPath
|
|
461
|
+
const backupPath = backupIfExists(configPath)
|
|
462
|
+
const hermesBin = resolveToolBinaryPath('hermes') || 'hermes'
|
|
463
|
+
|
|
464
|
+
// 📖 Use `hermes config set` for each field — robust and dependency-free
|
|
465
|
+
spawnSync(hermesBin, ['config', 'set', 'model', model.modelId], { stdio: 'ignore' })
|
|
466
|
+
spawnSync(hermesBin, ['config', 'set', 'model.provider', 'custom'], { stdio: 'ignore' })
|
|
467
|
+
if (baseUrl) {
|
|
468
|
+
spawnSync(hermesBin, ['config', 'set', 'model.base_url', baseUrl], { stdio: 'ignore' })
|
|
469
|
+
}
|
|
470
|
+
if (apiKey) {
|
|
471
|
+
spawnSync(hermesBin, ['config', 'set', 'model.api_key', apiKey], { stdio: 'ignore' })
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return { filePath: configPath, backupPath }
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// 📖 restartHermesGateway — restart the Hermes messaging gateway after config changes.
|
|
478
|
+
// 📖 Non-blocking: if gateway is not running, this is a no-op.
|
|
479
|
+
function restartHermesGateway() {
|
|
480
|
+
const hermesBin = resolveToolBinaryPath('hermes') || 'hermes'
|
|
481
|
+
spawnSync(hermesBin, ['gateway', 'restart'], { stdio: 'ignore', timeout: 10000 })
|
|
482
|
+
}
|
|
483
|
+
|
|
404
484
|
/**
|
|
405
485
|
* 📖 buildGeminiEnv - Build environment variables for Gemini CLI
|
|
406
486
|
*
|
|
@@ -597,6 +677,45 @@ export function prepareExternalToolLaunch(mode, model, config, options = {}) {
|
|
|
597
677
|
}
|
|
598
678
|
}
|
|
599
679
|
|
|
680
|
+
if (mode === 'hermes') {
|
|
681
|
+
const result = writeHermesConfig(model, apiKey, baseUrl, paths)
|
|
682
|
+
return {
|
|
683
|
+
command: 'hermes',
|
|
684
|
+
args: ['chat'],
|
|
685
|
+
env,
|
|
686
|
+
apiKey,
|
|
687
|
+
baseUrl,
|
|
688
|
+
meta,
|
|
689
|
+
configArtifacts: [{ path: result.filePath, backupPath: result.backupPath, label: 'config' }],
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
if (mode === 'continue') {
|
|
694
|
+
const result = writeContinueConfig(model, apiKey, baseUrl, paths)
|
|
695
|
+
return {
|
|
696
|
+
command: 'cn',
|
|
697
|
+
args: [],
|
|
698
|
+
env,
|
|
699
|
+
apiKey,
|
|
700
|
+
baseUrl,
|
|
701
|
+
meta,
|
|
702
|
+
configArtifacts: [{ path: result.filePath, backupPath: result.backupPath, label: 'config' }],
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (mode === 'cline') {
|
|
707
|
+
const result = writeClineConfig(model, apiKey, baseUrl, paths)
|
|
708
|
+
return {
|
|
709
|
+
command: 'cline',
|
|
710
|
+
args: [],
|
|
711
|
+
env,
|
|
712
|
+
apiKey,
|
|
713
|
+
baseUrl,
|
|
714
|
+
meta,
|
|
715
|
+
configArtifacts: [{ path: result.filePath, backupPath: result.backupPath, label: 'config' }],
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
600
719
|
if (mode === 'rovo') {
|
|
601
720
|
const result = writeRovoConfig(model, join(homedir(), '.rovodev', 'config.yml'), paths)
|
|
602
721
|
console.log(chalk.dim(` 📖 Rovo Dev CLI configured with model: ${model.modelId}`))
|
|
@@ -679,6 +798,23 @@ export async function startExternalTool(mode, model, config) {
|
|
|
679
798
|
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
|
680
799
|
}
|
|
681
800
|
|
|
801
|
+
if (mode === 'hermes') {
|
|
802
|
+
// 📖 Restart the Hermes gateway so the new model config takes effect immediately
|
|
803
|
+
restartHermesGateway()
|
|
804
|
+
console.log(chalk.dim(` 📖 Hermes Agent configured with model: ${model.modelId}`))
|
|
805
|
+
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
if (mode === 'continue') {
|
|
809
|
+
console.log(chalk.dim(` 📖 Continue CLI configured with model: ${model.modelId}`))
|
|
810
|
+
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
if (mode === 'cline') {
|
|
814
|
+
console.log(chalk.dim(` 📖 Cline configured with model: ${model.modelId}`))
|
|
815
|
+
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
|
816
|
+
}
|
|
817
|
+
|
|
682
818
|
if (mode === 'rovo') {
|
|
683
819
|
console.log(chalk.dim(` 📖 Launching Rovo Dev CLI in interactive mode...`))
|
|
684
820
|
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
package/src/tool-metadata.js
CHANGED
|
@@ -36,6 +36,9 @@ export const TOOL_METADATA = {
|
|
|
36
36
|
qwen: { label: 'Qwen Code', emoji: '🐉', flag: '--qwen', color: [255, 213, 128] },
|
|
37
37
|
openhands: { label: 'OpenHands', emoji: '🤲', flag: '--openhands', color: [228, 191, 239] },
|
|
38
38
|
amp: { label: 'Amp', emoji: '⚡', flag: '--amp', color: [255, 232, 98] },
|
|
39
|
+
hermes: { label: 'Hermes', emoji: '🔮', flag: '--hermes', color: [200, 160, 255] },
|
|
40
|
+
'continue': { label: 'Continue CLI', emoji: '▶️', flag: '--continue', color: [255, 100, 100] },
|
|
41
|
+
cline: { label: 'Cline', emoji: '🧠', flag: '--cline', color: [100, 220, 180] },
|
|
39
42
|
rovo: { label: 'Rovo Dev CLI', emoji: '🦘', flag: '--rovo', color: [148, 163, 184], cliOnly: true },
|
|
40
43
|
gemini: { label: 'Gemini CLI', emoji: '♊', flag: '--gemini', color: [66, 165, 245], cliOnly: true },
|
|
41
44
|
}
|
|
@@ -53,6 +56,9 @@ export const COMPAT_COLUMN_SLOTS = [
|
|
|
53
56
|
{ emoji: '🐉', toolKeys: ['qwen'], color: [255, 213, 128] },
|
|
54
57
|
{ emoji: '🤲', toolKeys: ['openhands'], color: [228, 191, 239] },
|
|
55
58
|
{ emoji: '⚡', toolKeys: ['amp'], color: [255, 232, 98] },
|
|
59
|
+
{ emoji: '🔮', toolKeys: ['hermes'], color: [200, 160, 255] },
|
|
60
|
+
{ emoji: '▶️', toolKeys: ['continue'], color: [255, 100, 100] },
|
|
61
|
+
{ emoji: '🧠', toolKeys: ['cline'], color: [100, 220, 180] },
|
|
56
62
|
{ emoji: '🦘', toolKeys: ['rovo'], color: [148, 163, 184] },
|
|
57
63
|
{ emoji: '♊', toolKeys: ['gemini'], color: [66, 165, 245] },
|
|
58
64
|
]
|
|
@@ -68,6 +74,9 @@ export const TOOL_MODE_ORDER = [
|
|
|
68
74
|
'qwen',
|
|
69
75
|
'openhands',
|
|
70
76
|
'amp',
|
|
77
|
+
'hermes',
|
|
78
|
+
'continue',
|
|
79
|
+
'cline',
|
|
71
80
|
'rovo',
|
|
72
81
|
'gemini',
|
|
73
82
|
]
|
package/src/utils.js
CHANGED
|
@@ -455,12 +455,18 @@ export function parseArgs(argv) {
|
|
|
455
455
|
const ampMode = flags.includes('--amp')
|
|
456
456
|
const piMode = flags.includes('--pi')
|
|
457
457
|
const rovoMode = flags.includes('--rovo')
|
|
458
|
+
const hermesMode = flags.includes('--hermes')
|
|
459
|
+
const continueMode = flags.includes('--continue')
|
|
460
|
+
const clineMode = flags.includes('--cline')
|
|
458
461
|
const geminiMode = flags.includes('--gemini')
|
|
459
462
|
const noTelemetry = flags.includes('--no-telemetry')
|
|
460
463
|
const jsonMode = flags.includes('--json')
|
|
461
464
|
const helpMode = flags.includes('--help') || flags.includes('-h')
|
|
462
465
|
const premiumMode = flags.includes('--premium')
|
|
463
466
|
|
|
467
|
+
// 📖 --web / --gui / web subcommand — launch the web dashboard instead of the TUI
|
|
468
|
+
const webMode = flags.includes('--web') || flags.includes('--gui') || args[0] === 'web'
|
|
469
|
+
|
|
464
470
|
// New boolean flags
|
|
465
471
|
const sortDesc = flags.includes('--desc')
|
|
466
472
|
const sortAscFlag = flags.includes('--asc')
|
|
@@ -492,6 +498,9 @@ export function parseArgs(argv) {
|
|
|
492
498
|
openHandsMode,
|
|
493
499
|
ampMode,
|
|
494
500
|
piMode,
|
|
501
|
+
hermesMode,
|
|
502
|
+
continueMode,
|
|
503
|
+
clineMode,
|
|
495
504
|
rovoMode,
|
|
496
505
|
geminiMode,
|
|
497
506
|
noTelemetry,
|
|
@@ -505,6 +514,7 @@ export function parseArgs(argv) {
|
|
|
505
514
|
hideUnconfigured,
|
|
506
515
|
showUnconfigured,
|
|
507
516
|
premiumMode,
|
|
517
|
+
webMode,
|
|
508
518
|
// 📖 Profile system removed - API keys now persist permanently across all sessions
|
|
509
519
|
recommendMode,
|
|
510
520
|
}
|