free-coding-models 0.3.22 → 0.3.24
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 +48 -0
- package/README.md +76 -19
- package/package.json +1 -1
- package/sources.js +60 -0
- package/src/app.js +43 -17
- package/src/command-palette.js +103 -6
- package/src/config.js +4 -2
- package/src/endpoint-installer.js +3 -2
- package/src/key-handler.js +311 -29
- package/src/overlays.js +119 -8
- package/src/provider-metadata.js +25 -0
- package/src/render-helpers.js +15 -2
- package/src/render-table.js +81 -7
- package/src/theme.js +6 -0
- package/src/tool-bootstrap.js +22 -0
- package/src/tool-launchers.js +93 -2
- package/src/tool-metadata.js +94 -11
- package/src/utils.js +5 -1
package/src/tool-metadata.js
CHANGED
|
@@ -19,21 +19,44 @@
|
|
|
19
19
|
* → `getToolMeta` — return display metadata for one mode
|
|
20
20
|
* → `getToolModeOrder` — stable mode cycle order for the `Z` hotkey
|
|
21
21
|
*
|
|
22
|
-
* @exports TOOL_METADATA, TOOL_MODE_ORDER, getToolMeta, getToolModeOrder
|
|
22
|
+
* @exports TOOL_METADATA, TOOL_MODE_ORDER, COMPAT_COLUMN_SLOTS, getToolMeta, getToolModeOrder
|
|
23
23
|
*/
|
|
24
|
+
// 📖 Each tool has a unique `color` RGB tuple used for the "Compatible with" column
|
|
25
|
+
// 📖 and for coloring the tool name in the Z cycle header badge.
|
|
26
|
+
// 📖 `emoji` is the unique icon shown everywhere (header badge, compat column, palette, overlays).
|
|
27
|
+
// 📖 OpenCode CLI and Desktop share 📦 — they are the same platform, split only for launch logic.
|
|
24
28
|
export const TOOL_METADATA = {
|
|
25
|
-
opencode:
|
|
26
|
-
'opencode-desktop': { label: 'OpenCode Desktop', emoji: '
|
|
27
|
-
openclaw:
|
|
28
|
-
crush:
|
|
29
|
-
goose:
|
|
30
|
-
pi:
|
|
31
|
-
aider:
|
|
32
|
-
qwen:
|
|
33
|
-
openhands:
|
|
34
|
-
amp:
|
|
29
|
+
opencode: { label: 'OpenCode CLI', emoji: '📦', flag: '--opencode', color: [110, 214, 255] },
|
|
30
|
+
'opencode-desktop': { label: 'OpenCode Desktop', emoji: '📦', flag: '--opencode-desktop', color: [149, 205, 255] },
|
|
31
|
+
openclaw: { label: 'OpenClaw', emoji: '🦞', flag: '--openclaw', color: [255, 129, 129] },
|
|
32
|
+
crush: { label: 'Crush', emoji: '💘', flag: '--crush', color: [255, 168, 209] },
|
|
33
|
+
goose: { label: 'Goose', emoji: '🪿', flag: '--goose', color: [132, 235, 168] },
|
|
34
|
+
pi: { label: 'Pi', emoji: 'π', flag: '--pi', color: [173, 216, 230] },
|
|
35
|
+
aider: { label: 'Aider', emoji: '🛠', flag: '--aider', color: [255, 208, 102] },
|
|
36
|
+
qwen: { label: 'Qwen Code', emoji: '🐉', flag: '--qwen', color: [255, 213, 128] },
|
|
37
|
+
openhands: { label: 'OpenHands', emoji: '🤲', flag: '--openhands', color: [228, 191, 239] },
|
|
38
|
+
amp: { label: 'Amp', emoji: '⚡', flag: '--amp', color: [255, 232, 98] },
|
|
39
|
+
rovo: { label: 'Rovo Dev CLI', emoji: '🦘', flag: '--rovo', color: [148, 163, 184], cliOnly: true },
|
|
40
|
+
gemini: { label: 'Gemini CLI', emoji: '♊', flag: '--gemini', color: [66, 165, 245], cliOnly: true },
|
|
35
41
|
}
|
|
36
42
|
|
|
43
|
+
// 📖 Deduplicated emoji order for the "Compatible with" column.
|
|
44
|
+
// 📖 OpenCode CLI + Desktop are merged into a single 📦 slot since they share compatibility.
|
|
45
|
+
// 📖 Each slot maps to one or more toolKeys for compatibility checking.
|
|
46
|
+
export const COMPAT_COLUMN_SLOTS = [
|
|
47
|
+
{ emoji: '📦', toolKeys: ['opencode', 'opencode-desktop'], color: [110, 214, 255] },
|
|
48
|
+
{ emoji: '🦞', toolKeys: ['openclaw'], color: [255, 129, 129] },
|
|
49
|
+
{ emoji: '💘', toolKeys: ['crush'], color: [255, 168, 209] },
|
|
50
|
+
{ emoji: '🪿', toolKeys: ['goose'], color: [132, 235, 168] },
|
|
51
|
+
{ emoji: 'π', toolKeys: ['pi'], color: [173, 216, 230] },
|
|
52
|
+
{ emoji: '🛠', toolKeys: ['aider'], color: [255, 208, 102] },
|
|
53
|
+
{ emoji: '🐉', toolKeys: ['qwen'], color: [255, 213, 128] },
|
|
54
|
+
{ emoji: '🤲', toolKeys: ['openhands'], color: [228, 191, 239] },
|
|
55
|
+
{ emoji: '⚡', toolKeys: ['amp'], color: [255, 232, 98] },
|
|
56
|
+
{ emoji: '🦘', toolKeys: ['rovo'], color: [148, 163, 184] },
|
|
57
|
+
{ emoji: '♊', toolKeys: ['gemini'], color: [66, 165, 245] },
|
|
58
|
+
]
|
|
59
|
+
|
|
37
60
|
export const TOOL_MODE_ORDER = [
|
|
38
61
|
'opencode',
|
|
39
62
|
'opencode-desktop',
|
|
@@ -45,6 +68,8 @@ export const TOOL_MODE_ORDER = [
|
|
|
45
68
|
'qwen',
|
|
46
69
|
'openhands',
|
|
47
70
|
'amp',
|
|
71
|
+
'rovo',
|
|
72
|
+
'gemini',
|
|
48
73
|
]
|
|
49
74
|
|
|
50
75
|
export function getToolMeta(mode) {
|
|
@@ -54,3 +79,61 @@ export function getToolMeta(mode) {
|
|
|
54
79
|
export function getToolModeOrder() {
|
|
55
80
|
return [...TOOL_MODE_ORDER]
|
|
56
81
|
}
|
|
82
|
+
|
|
83
|
+
// 📖 Regular tools: all tools EXCEPT rovo, gemini (which are CLI-only exclusives).
|
|
84
|
+
// 📖 Used as the default compatible set for normal provider models.
|
|
85
|
+
const REGULAR_TOOLS = Object.keys(TOOL_METADATA).filter(k => !TOOL_METADATA[k].cliOnly)
|
|
86
|
+
|
|
87
|
+
// 📖 Zen-only tools: OpenCode Zen models can ONLY run on OpenCode CLI / OpenCode Desktop.
|
|
88
|
+
const ZEN_COMPATIBLE_TOOLS = ['opencode', 'opencode-desktop']
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 📖 Returns the list of tool keys a model is compatible with.
|
|
92
|
+
* - Rovo models → only 'rovo'
|
|
93
|
+
* - Gemini models → only 'gemini'
|
|
94
|
+
* - OpenCode Zen models → only 'opencode', 'opencode-desktop'
|
|
95
|
+
* - Regular models → all non-cliOnly tools
|
|
96
|
+
* @param {string} providerKey — the source key from sources.js (e.g. 'nvidia', 'rovo', 'opencode-zen')
|
|
97
|
+
* @returns {string[]} — array of compatible tool keys
|
|
98
|
+
*/
|
|
99
|
+
export function getCompatibleTools(providerKey) {
|
|
100
|
+
if (providerKey === 'rovo') return ['rovo']
|
|
101
|
+
if (providerKey === 'gemini') return ['gemini']
|
|
102
|
+
if (providerKey === 'opencode-zen') return ZEN_COMPATIBLE_TOOLS
|
|
103
|
+
return REGULAR_TOOLS
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 📖 Checks whether a model from the given provider can run on the specified tool mode.
|
|
108
|
+
* @param {string} providerKey — source key
|
|
109
|
+
* @param {string} toolMode — active tool mode
|
|
110
|
+
* @returns {boolean}
|
|
111
|
+
*/
|
|
112
|
+
export function isModelCompatibleWithTool(providerKey, toolMode) {
|
|
113
|
+
return getCompatibleTools(providerKey).includes(toolMode)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 📖 Finds compatible models with a similar SWE score to the selected one.
|
|
118
|
+
* 📖 Used by the incompatibility fallback overlay to suggest alternatives.
|
|
119
|
+
* @param {string} selectedSwe — SWE score string like '72.0%' or '-'
|
|
120
|
+
* @param {string} toolMode — current active tool mode
|
|
121
|
+
* @param {Array} allResults — the state.results array (each has .providerKey, .modelId, .label, .tier, .sweScore)
|
|
122
|
+
* @param {number} [maxResults=3] — max suggestions to return
|
|
123
|
+
* @returns {{ modelId: string, label: string, tier: string, sweScore: string, providerKey: string, sweDelta: number }[]}
|
|
124
|
+
*/
|
|
125
|
+
export function findSimilarCompatibleModels(selectedSwe, toolMode, allResults, maxResults = 3) {
|
|
126
|
+
const targetSwe = parseFloat(selectedSwe) || 0
|
|
127
|
+
return allResults
|
|
128
|
+
.filter(r => !r.hidden && isModelCompatibleWithTool(r.providerKey, toolMode))
|
|
129
|
+
.map(r => ({
|
|
130
|
+
modelId: r.modelId,
|
|
131
|
+
label: r.label,
|
|
132
|
+
tier: r.tier,
|
|
133
|
+
sweScore: r.sweScore || '-',
|
|
134
|
+
providerKey: r.providerKey,
|
|
135
|
+
sweDelta: Math.abs((parseFloat(r.sweScore) || 0) - targetSwe),
|
|
136
|
+
}))
|
|
137
|
+
.sort((a, b) => a.sweDelta - b.sweDelta)
|
|
138
|
+
.slice(0, maxResults)
|
|
139
|
+
}
|
package/src/utils.js
CHANGED
|
@@ -220,7 +220,7 @@ export const getStabilityScore = (r) => {
|
|
|
220
220
|
//
|
|
221
221
|
// 📖 Supported columns in the sorter.
|
|
222
222
|
// 📖 Most map directly to visible TUI sort hotkeys; `tier` remains available internally
|
|
223
|
-
// 📖
|
|
223
|
+
// 📖 while `Y` is used by the live UI for favorites display mode.
|
|
224
224
|
// - 'rank' (R key) — original index from sources.js
|
|
225
225
|
// - 'tier' (internal) — tier hierarchy (S+ first, C last)
|
|
226
226
|
// - 'origin' (O key) — provider name (all NIM for now, future-proofed)
|
|
@@ -454,6 +454,8 @@ export function parseArgs(argv) {
|
|
|
454
454
|
const openHandsMode = flags.includes('--openhands')
|
|
455
455
|
const ampMode = flags.includes('--amp')
|
|
456
456
|
const piMode = flags.includes('--pi')
|
|
457
|
+
const rovoMode = flags.includes('--rovo')
|
|
458
|
+
const geminiMode = flags.includes('--gemini')
|
|
457
459
|
const noTelemetry = flags.includes('--no-telemetry')
|
|
458
460
|
const jsonMode = flags.includes('--json')
|
|
459
461
|
const helpMode = flags.includes('--help') || flags.includes('-h')
|
|
@@ -490,6 +492,8 @@ export function parseArgs(argv) {
|
|
|
490
492
|
openHandsMode,
|
|
491
493
|
ampMode,
|
|
492
494
|
piMode,
|
|
495
|
+
rovoMode,
|
|
496
|
+
geminiMode,
|
|
493
497
|
noTelemetry,
|
|
494
498
|
jsonMode,
|
|
495
499
|
helpMode,
|