free-coding-models 0.5.85 โ 0.5.86
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.
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog v0.5.86 - 2026-09-05
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
- ๐ฅ๏ธ Provider column in the TUI table widened from 11 to 15 characters, with automatic truncation at 14 characters (13 + ellipsis) for anything longer. Provider names like "Cloudflare AI" (13 chars) now render fully instead of pushing every following cell out of alignment. Any future provider name longer than 14 chars is truncated cleanly with an ellipsis, so a long label can never break the table layout again. The compact-mode truncation (4 chars + ellipsis on narrow terminals) is unchanged.
|
|
5
|
+
- โก Command Palette no longer paints a giant dark rectangle over the table. Each palette row used to be emitted from column 1 with a leading margin of unstyled spaces plus a trailing "erase to end of line": both inherited the still-active panel background, so the panel tint filled the entire screen width for every palette row, masking the frozen table on both sides of the modal. Rows are now positioned directly at the panel's left column and paint only the panel's own cells; the frozen table stays visible beside the palette.
|
|
6
|
+
- โจ Command Palette no longer flickers on large terminals. While the palette is open the table behind it is frozen, so repainting the full table every frame was pure waste: on a 280-column terminal the per-frame write was ~300 KB, got split into chunks, and the terminal showed the bare table for a moment before the palette painted over it, 30 times per second. The frozen table is now written once when the palette opens; after that only the palette itself is repainted (per-frame output divided by ~50).
|
|
7
|
+
- ๐งน Palette height now stays constant while typing a search. Nothing repaints the cells below the panel while it is open (the table behind is frozen), so a shrinking result list used to leave stale painted rows hanging under the panel's bottom edge. Short result lists are padded to the full body height instead.
|
|
8
|
+
|
|
9
|
+
### Tests
|
|
10
|
+
- 2 new regression tests: the palette must never emit margin filler or edge-to-edge erase codes, and the panel must keep a constant height when the result list shrinks. 883 tests passing across 11 suites.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.86",
|
|
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/tui/app.js
CHANGED
|
@@ -1075,8 +1075,15 @@ export async function runApp(cliArgs, config, startupOptions = {}) {
|
|
|
1075
1075
|
// ๐ Freeze the full table (including countdown and spinner glyphs) while
|
|
1076
1076
|
// ๐ the command palette is open so the background remains perfectly static.
|
|
1077
1077
|
state.commandPaletteFrozenTable = renderTable(tableOpts)
|
|
1078
|
+
tableContent = state.commandPaletteFrozenTable
|
|
1079
|
+
} else {
|
|
1080
|
+
// ๐ The frozen table is already on screen and cannot change while the
|
|
1081
|
+
// ๐ palette is open, so repaint the palette alone. Repainting the full
|
|
1082
|
+
// table every frame made large terminals flicker: the write gets split
|
|
1083
|
+
// into chunks, so the terminal showed the bare table for a moment
|
|
1084
|
+
// before the palette overlay painted over it, 30 times per second.
|
|
1085
|
+
tableContent = null
|
|
1078
1086
|
}
|
|
1079
|
-
tableContent = state.commandPaletteFrozenTable
|
|
1080
1087
|
} else {
|
|
1081
1088
|
state.commandPaletteFrozenTable = null
|
|
1082
1089
|
tableContent = renderTable(tableOpts)
|
|
@@ -1101,7 +1108,7 @@ export async function runApp(cliArgs, config, startupOptions = {}) {
|
|
|
1101
1108
|
: state.incompatibleFallbackOpen
|
|
1102
1109
|
? overlays.renderIncompatibleFallback()
|
|
1103
1110
|
: state.commandPaletteOpen
|
|
1104
|
-
? tableContent + overlays.renderCommandPalette()
|
|
1111
|
+
? (tableContent || '') + overlays.renderCommandPalette()
|
|
1105
1112
|
: state.recommendOpen
|
|
1106
1113
|
? overlays.renderRecommend()
|
|
1107
1114
|
: state.helpVisible
|
package/src/tui/overlays.js
CHANGED
|
@@ -856,6 +856,11 @@ export function createOverlayRenderers(state, deps) {
|
|
|
856
856
|
}
|
|
857
857
|
|
|
858
858
|
const targetLine = cursorLineByRow[state.commandPaletteCursor] ?? 0
|
|
859
|
+
// ๐ Pad short result lists up to bodyRows so the panel height stays constant
|
|
860
|
+
// ๐ while typing: nothing repaints the cells below a shrunken panel (the
|
|
861
|
+
// ๐ table behind is frozen while the palette is open), so a shrinking panel
|
|
862
|
+
// ๐ would leave stale painted rows hanging under its bottom edge.
|
|
863
|
+
while (panelLines.length < bodyRows) panelLines.push('')
|
|
859
864
|
state.commandPaletteScrollOffset = keepOverlayTargetVisible(
|
|
860
865
|
state.commandPaletteScrollOffset,
|
|
861
866
|
targetLine,
|
|
@@ -922,11 +927,16 @@ export function createOverlayRenderers(state, deps) {
|
|
|
922
927
|
return sty.overlayBgCommandPalette(padded)
|
|
923
928
|
})
|
|
924
929
|
|
|
925
|
-
// ๐ Emit each row
|
|
926
|
-
// ๐
|
|
927
|
-
// ๐
|
|
930
|
+
// ๐ Emit each row directly at the panel's left column: no margin filler and
|
|
931
|
+
// ๐ no \x1b[K. The old form (col 1 + margin spaces + \x1b[K) painted the
|
|
932
|
+
// ๐ panel tint across the full screen width because the margin spaces and
|
|
933
|
+
// ๐ the erase-to-EOL both inherit the tint background still active from the
|
|
934
|
+
// ๐ previous row. On wide terminals that grew a giant dark rectangle over
|
|
935
|
+
// ๐ the frozen table on both sides of the panel, repainted every frame.
|
|
936
|
+
// ๐ Rows are width-budgeted and the panel is screen-clamped, so a row can
|
|
937
|
+
// ๐ never overflow past the terminal edge (the real issue #169 artifact).
|
|
928
938
|
return tintedLines
|
|
929
|
-
.map((line, idx) => `\x1b[${top + idx}
|
|
939
|
+
.map((line, idx) => `\x1b[${top + idx};${left}H${line}`)
|
|
930
940
|
.join('')
|
|
931
941
|
}
|
|
932
942
|
|
package/src/tui/render-table.js
CHANGED
|
@@ -314,7 +314,13 @@ export function renderTable({
|
|
|
314
314
|
const W_RANK = 6
|
|
315
315
|
const W_TIER = 5
|
|
316
316
|
const W_CTX = 4
|
|
317
|
-
const W_SOURCE =
|
|
317
|
+
const W_SOURCE = 15
|
|
318
|
+
// ๐ Provider names are display-capped at MAX_PROVIDER_NAME_LEN chars so an
|
|
319
|
+
// ๐ over-long label can never push the following cells and desalign the
|
|
320
|
+
// ๐ whole row (Cloudflare AI at 13 chars overflowed the old 11-wide column).
|
|
321
|
+
// ๐ Anything longer is cut to 13 chars + 'โฆ' = 14 visible chars. Keep new
|
|
322
|
+
// ๐ provider names in sources.js at MAX_PROVIDER_NAME_LEN chars or less.
|
|
323
|
+
const MAX_PROVIDER_NAME_LEN = 14
|
|
318
324
|
const W_MODEL = 26
|
|
319
325
|
const W_SWE = 5
|
|
320
326
|
const W_STATUS = 17
|
|
@@ -719,11 +725,15 @@ export function renderTable({
|
|
|
719
725
|
const tier = tierFn(r.tier.padEnd(W_TIER))
|
|
720
726
|
// ๐ Keep terminal view provider-specific so each row is monitorable per provider
|
|
721
727
|
// ๐ In compact mode, truncate provider name to 4 chars + 'โฆ'
|
|
728
|
+
// ๐ In normal mode, cap names at MAX_PROVIDER_NAME_LEN chars (13 + 'โฆ')
|
|
729
|
+
// ๐ so an over-long label never shifts every cell to its right.
|
|
722
730
|
const providerNameRaw = sources[r.providerKey]?.name ?? r.providerKey ?? 'NIM'
|
|
723
731
|
const providerName = normalizeOriginLabel(providerNameRaw, r.providerKey)
|
|
724
732
|
const providerDisplay = isCompact && providerName.length > 5
|
|
725
733
|
? providerName.slice(0, 4) + 'โฆ'
|
|
726
|
-
: providerName
|
|
734
|
+
: providerName.length > MAX_PROVIDER_NAME_LEN
|
|
735
|
+
? providerName.slice(0, MAX_PROVIDER_NAME_LEN - 1).trimEnd() + 'โฆ'
|
|
736
|
+
: providerName
|
|
727
737
|
const source = themeColors.provider(r.providerKey, providerDisplay.padEnd(wSource))
|
|
728
738
|
// ๐ Prefix: โญ favorite > ๐ฏ recommended > ๐ new โ only one emoji, never shifts the line
|
|
729
739
|
const modelIsNew = isNewModel(r.addedDate)
|