free-coding-models 0.3.12 → 0.3.13
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/bin/free-coding-models.js +7 -5
- package/package.json +1 -1
- package/src/key-handler.js +34 -6
- package/src/overlays.js +5 -3
- package/src/render-table.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## 0.3.13
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Small Width Warnings toggle actually works again**: the Settings row now shows `Small Width Warnings` with clear enabled/disabled status, the startup overlay reacts immediately to the toggle, and the narrow-terminal warning now auto-hides after 2 seconds instead of 4.
|
|
9
|
+
|
|
5
10
|
## 0.3.12
|
|
6
11
|
|
|
7
12
|
> **Proxy / bridge update:** the current legacy proxy stack is now officially discontinued while we rebuild that whole layer from zero. This cleanup is intentional: Claude Code support, a smarter router, and a much more reliable external-tools bridge are being reworked as a separate, cleaner system and will come back in a future release. In the meantime, FCM has been cleaned up and narrowed to the stable direct-launch surface so the app stays solid for day-to-day usage.
|
|
@@ -399,11 +399,11 @@ async function main() {
|
|
|
399
399
|
originFilterMode: 0, // 📖 Index into ORIGIN_CYCLE (0=All, then providers)
|
|
400
400
|
premiumMode: cliArgs.premiumMode, // 📖 Special elite-only mode: S/S+ only, Health UP only, Perfect/Normal/Slow verdict only.
|
|
401
401
|
hideUnconfiguredModels: config.settings?.hideUnconfiguredModels === true, // 📖 Hide providers with no configured API key when true.
|
|
402
|
-
disableWidthsWarning: config.settings?.disableWidthsWarning ?? false, // 📖
|
|
402
|
+
disableWidthsWarning: config.settings?.disableWidthsWarning ?? false, // 📖 Cached for runtime checks; keep it in sync with config.settings.
|
|
403
403
|
scrollOffset: 0, // 📖 First visible model index in viewport
|
|
404
404
|
terminalRows: process.stdout.rows || 24, // 📖 Current terminal height
|
|
405
405
|
terminalCols: process.stdout.columns || 80, // 📖 Current terminal width
|
|
406
|
-
widthWarningStartedAt: (process.stdout.columns || 80) < 166 ? now : null, // 📖 Start
|
|
406
|
+
widthWarningStartedAt: (process.stdout.columns || 80) < 166 && !(config.settings?.disableWidthsWarning ?? false) ? now : null, // 📖 Start immediately only when warnings are enabled in a narrow viewport.
|
|
407
407
|
widthWarningDismissed: false, // 📖 Esc hides the narrow-terminal warning early for the current narrow-width session.
|
|
408
408
|
widthWarningShowCount: 0, // 📖 Counter for how many times the narrow-terminal warning has been shown (max 2 per session).
|
|
409
409
|
// 📖 Settings screen state (P key opens it)
|
|
@@ -465,9 +465,11 @@ async function main() {
|
|
|
465
465
|
// 📖 Re-clamp viewport on terminal resize
|
|
466
466
|
process.stdout.on('resize', () => {
|
|
467
467
|
const prevCols = state.terminalCols
|
|
468
|
+
const widthsWarningDisabled = state.config.settings?.disableWidthsWarning === true
|
|
468
469
|
state.terminalRows = process.stdout.rows || 24
|
|
469
470
|
state.terminalCols = process.stdout.columns || 80
|
|
470
|
-
|
|
471
|
+
state.disableWidthsWarning = widthsWarningDisabled
|
|
472
|
+
if (state.terminalCols < 166 && !widthsWarningDisabled) {
|
|
471
473
|
if (prevCols >= 166 || state.widthWarningDismissed) {
|
|
472
474
|
state.widthWarningStartedAt = Date.now()
|
|
473
475
|
state.widthWarningDismissed = false
|
|
@@ -862,7 +864,7 @@ async function main() {
|
|
|
862
864
|
? overlays.renderHelp()
|
|
863
865
|
: state.changelogOpen
|
|
864
866
|
? overlays.renderChangelog()
|
|
865
|
-
: renderTable(state.results, state.pendingPings, state.frame, state.cursor, state.sortColumn, state.sortDirection, state.pingInterval, state.lastPingTime, state.mode, state.tierFilterMode, state.scrollOffset, state.terminalRows, state.terminalCols, state.originFilterMode, null, state.pingMode, state.pingModeSource, state.hideUnconfiguredModels, state.widthWarningStartedAt, state.widthWarningDismissed, state.widthWarningShowCount, state.settingsUpdateState, state.settingsUpdateLatestVersion, false, state.startupLatestVersion, state.versionAlertsEnabled)
|
|
867
|
+
: renderTable(state.results, state.pendingPings, state.frame, state.cursor, state.sortColumn, state.sortDirection, state.pingInterval, state.lastPingTime, state.mode, state.tierFilterMode, state.scrollOffset, state.terminalRows, state.terminalCols, state.originFilterMode, null, state.pingMode, state.pingModeSource, state.hideUnconfiguredModels, state.widthWarningStartedAt, state.widthWarningDismissed, state.widthWarningShowCount, state.settingsUpdateState, state.settingsUpdateLatestVersion, false, state.startupLatestVersion, state.versionAlertsEnabled, state.config.settings?.disableWidthsWarning ?? false)
|
|
866
868
|
process.stdout.write(ALT_HOME + content)
|
|
867
869
|
if (process.stdout.isTTY) {
|
|
868
870
|
process.stdout.flush && process.stdout.flush()
|
|
@@ -873,7 +875,7 @@ async function main() {
|
|
|
873
875
|
const initialVisible = state.results.filter(r => !r.hidden)
|
|
874
876
|
state.visibleSorted = sortResultsWithPinnedFavorites(initialVisible, state.sortColumn, state.sortDirection)
|
|
875
877
|
|
|
876
|
-
process.stdout.write(ALT_HOME + renderTable(state.results, state.pendingPings, state.frame, state.cursor, state.sortColumn, state.sortDirection, state.pingInterval, state.lastPingTime, state.mode, state.tierFilterMode, state.scrollOffset, state.terminalRows, state.terminalCols, state.originFilterMode, null, state.pingMode, state.pingModeSource, state.hideUnconfiguredModels, state.widthWarningStartedAt, state.widthWarningDismissed, state.widthWarningShowCount, state.settingsUpdateState, state.settingsUpdateLatestVersion, false, state.startupLatestVersion, state.versionAlertsEnabled))
|
|
878
|
+
process.stdout.write(ALT_HOME + renderTable(state.results, state.pendingPings, state.frame, state.cursor, state.sortColumn, state.sortDirection, state.pingInterval, state.lastPingTime, state.mode, state.tierFilterMode, state.scrollOffset, state.terminalRows, state.terminalCols, state.originFilterMode, null, state.pingMode, state.pingModeSource, state.hideUnconfiguredModels, state.widthWarningStartedAt, state.widthWarningDismissed, state.widthWarningShowCount, state.settingsUpdateState, state.settingsUpdateLatestVersion, false, state.startupLatestVersion, state.versionAlertsEnabled, state.config.settings?.disableWidthsWarning ?? false))
|
|
877
879
|
if (process.stdout.isTTY) {
|
|
878
880
|
process.stdout.flush && process.stdout.flush()
|
|
879
881
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.13",
|
|
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",
|
package/src/key-handler.js
CHANGED
|
@@ -350,6 +350,38 @@ export function createKeyHandler(ctx) {
|
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
+
// 📖 Keep the width-warning runtime state synced with the persisted Settings toggle
|
|
354
|
+
// 📖 so the overlay reacts immediately when the user enables or disables it.
|
|
355
|
+
function syncWidthsWarningState() {
|
|
356
|
+
const widthsWarningDisabled = state.config.settings?.disableWidthsWarning === true
|
|
357
|
+
state.disableWidthsWarning = widthsWarningDisabled
|
|
358
|
+
|
|
359
|
+
if (widthsWarningDisabled) {
|
|
360
|
+
state.widthWarningStartedAt = null
|
|
361
|
+
state.widthWarningDismissed = false
|
|
362
|
+
return
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
state.widthWarningShowCount = 0
|
|
366
|
+
if ((state.terminalCols || 80) < 166) {
|
|
367
|
+
state.widthWarningStartedAt = Date.now()
|
|
368
|
+
state.widthWarningDismissed = false
|
|
369
|
+
return
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
state.widthWarningStartedAt = null
|
|
373
|
+
state.widthWarningDismissed = false
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// 📖 Toggle the width-warning setting and apply the effect immediately instead
|
|
377
|
+
// 📖 of waiting for a resize or restart.
|
|
378
|
+
function toggleWidthsWarningSetting() {
|
|
379
|
+
if (!state.config.settings) state.config.settings = {}
|
|
380
|
+
state.config.settings.disableWidthsWarning = !state.config.settings.disableWidthsWarning
|
|
381
|
+
syncWidthsWarningState()
|
|
382
|
+
saveConfig(state.config)
|
|
383
|
+
}
|
|
384
|
+
|
|
353
385
|
function resetInstallEndpointsOverlay() {
|
|
354
386
|
state.installEndpointsOpen = false
|
|
355
387
|
state.installEndpointsPhase = 'providers'
|
|
@@ -1040,9 +1072,7 @@ export function createKeyHandler(ctx) {
|
|
|
1040
1072
|
|
|
1041
1073
|
// 📖 Widths Warning toggle (Enter to toggle)
|
|
1042
1074
|
if (state.settingsCursor === widthWarningRowIdx) {
|
|
1043
|
-
|
|
1044
|
-
state.config.settings.disableWidthsWarning = !state.config.settings.disableWidthsWarning
|
|
1045
|
-
saveConfig(state.config)
|
|
1075
|
+
toggleWidthsWarningSetting()
|
|
1046
1076
|
return
|
|
1047
1077
|
}
|
|
1048
1078
|
|
|
@@ -1080,9 +1110,7 @@ export function createKeyHandler(ctx) {
|
|
|
1080
1110
|
) return
|
|
1081
1111
|
// 📖 Widths Warning toggle (disable/enable)
|
|
1082
1112
|
if (state.settingsCursor === widthWarningRowIdx) {
|
|
1083
|
-
|
|
1084
|
-
state.config.settings.disableWidthsWarning = !state.config.settings.disableWidthsWarning
|
|
1085
|
-
saveConfig(state.config)
|
|
1113
|
+
toggleWidthsWarningSetting()
|
|
1086
1114
|
return
|
|
1087
1115
|
}
|
|
1088
1116
|
// 📖 Profile system removed - API keys now persist permanently across all sessions
|
package/src/overlays.js
CHANGED
|
@@ -217,11 +217,13 @@ export function createOverlayRenderers(state, deps) {
|
|
|
217
217
|
const updateRow = `${updateBullet}${chalk.bold(updateActionLabel).padEnd(44)} ${updateStatus}`
|
|
218
218
|
cursorLineByRow[updateRowIdx] = lines.length
|
|
219
219
|
lines.push(updateCursor ? chalk.bgRgb(30, 30, 60)(updateRow) : updateRow)
|
|
220
|
-
// 📖
|
|
220
|
+
// 📖 Width warning visibility row for the startup narrow-terminal overlay.
|
|
221
221
|
const disableWidthsWarning = Boolean(state.config.settings?.disableWidthsWarning)
|
|
222
222
|
const widthWarningBullet = state.settingsCursor === widthWarningRowIdx ? chalk.bold.cyan(' ❯ ') : chalk.dim(' ')
|
|
223
|
-
const widthWarningStatus = disableWidthsWarning
|
|
224
|
-
|
|
223
|
+
const widthWarningStatus = disableWidthsWarning
|
|
224
|
+
? chalk.redBright('🙈 Disabled')
|
|
225
|
+
: chalk.greenBright('👁 Enabled')
|
|
226
|
+
const widthWarningRow = `${widthWarningBullet}${chalk.bold('Small Width Warnings').padEnd(44)} ${widthWarningStatus}`
|
|
225
227
|
cursorLineByRow[widthWarningRowIdx] = lines.length
|
|
226
228
|
lines.push(state.settingsCursor === widthWarningRowIdx ? chalk.bgRgb(30, 30, 60)(widthWarningRow) : widthWarningRow)
|
|
227
229
|
if (updateState === 'error' && state.settingsUpdateError) {
|
package/src/render-table.js
CHANGED
|
@@ -181,7 +181,7 @@ export function renderTable(results, pendingPings, frame, cursor = null, sortCol
|
|
|
181
181
|
const W_TOKENS = 7
|
|
182
182
|
// const W_USAGE = 7 // Usage column removed
|
|
183
183
|
const MIN_TABLE_WIDTH = 166
|
|
184
|
-
const warningDurationMs =
|
|
184
|
+
const warningDurationMs = 2_000
|
|
185
185
|
const elapsed = widthWarningStartedAt ? Math.max(0, Date.now() - widthWarningStartedAt) : warningDurationMs
|
|
186
186
|
const remainingMs = Math.max(0, warningDurationMs - elapsed)
|
|
187
187
|
const showWidthWarning = terminalCols > 0 && terminalCols < MIN_TABLE_WIDTH && !disableWidthsWarning && !widthWarningDismissed && widthWarningShowCount < 2 && remainingMs > 0
|