free-coding-models 0.3.37 → 0.3.41
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 -1800
- package/README.md +10 -1
- package/bin/free-coding-models.js +8 -0
- package/package.json +13 -3
- package/src/app.js +30 -0
- package/src/cli-help.js +2 -0
- package/src/command-palette.js +3 -0
- package/src/config.js +7 -0
- package/src/endpoint-installer.js +1 -1
- package/src/key-handler.js +27 -1
- package/src/overlays.js +11 -1
- package/src/shell-env.js +393 -0
- package/src/tool-bootstrap.js +41 -0
- package/src/tool-launchers.js +166 -1
- package/src/tool-metadata.js +12 -0
- package/src/utils.js +12 -0
- package/web/app.legacy.js +900 -0
- package/web/index.html +20 -0
- package/web/server.js +443 -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
|
|
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, 🛠️ Xcode, π Pi, 🦘 Rovo or ♊ Gemini in one keystroke</sub>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
|
|
@@ -159,6 +159,9 @@ free-coding-models --goose --tier S
|
|
|
159
159
|
# "I want NVIDIA's top models only"
|
|
160
160
|
free-coding-models --origin nvidia --tier S
|
|
161
161
|
|
|
162
|
+
# "I want the local web dashboard"
|
|
163
|
+
free-coding-models --web
|
|
164
|
+
|
|
162
165
|
# "Start with an elite-focused preset, then adjust filters live"
|
|
163
166
|
free-coding-models --premium
|
|
164
167
|
|
|
@@ -169,6 +172,8 @@ free-coding-models --tier S --json | jq -r '.[0].modelId'
|
|
|
169
172
|
free-coding-models --openclaw --origin groq
|
|
170
173
|
```
|
|
171
174
|
|
|
175
|
+
When launching the web dashboard, `free-coding-models` prefers `http://localhost:3333`. If that port is already used by another app, it now auto-picks the next free local port and prints the exact URL to open.
|
|
176
|
+
|
|
172
177
|
### Tool launcher flags
|
|
173
178
|
|
|
174
179
|
| Flag | Launches |
|
|
@@ -182,6 +187,10 @@ free-coding-models --openclaw --origin groq
|
|
|
182
187
|
| `--qwen` | 🐉 Qwen Code |
|
|
183
188
|
| `--openhands` | 🤲 OpenHands |
|
|
184
189
|
| `--amp` | ⚡ Amp |
|
|
190
|
+
| `--hermes` | 🔮 Hermes |
|
|
191
|
+
| `--continue` | ▶️ Continue CLI |
|
|
192
|
+
| `--cline` | 🧠 Cline |
|
|
193
|
+
| `--xcode` | 🛠️ Xcode Intelligence |
|
|
185
194
|
| `--pi` | π Pi |
|
|
186
195
|
| `--rovo` | 🦘 Rovo Dev CLI |
|
|
187
196
|
| `--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.41",
|
|
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
|
@@ -114,6 +114,7 @@ import { parseTelemetryEnv, isTelemetryDebugEnabled, telemetryDebug, ensureTelem
|
|
|
114
114
|
import { ensureFavoritesConfig, toFavoriteKey, syncFavoriteFlags, toggleFavoriteModel } from '../src/favorites.js'
|
|
115
115
|
import { checkForUpdateDetailed, checkForUpdate, runUpdate, promptUpdateNotification, fetchLastReleaseDate } from './updater.js'
|
|
116
116
|
import { promptApiKey } from '../src/setup.js'
|
|
117
|
+
import { syncShellEnv, ensureShellRcSource, promptShellEnvMigration, removeShellEnv } from '../src/shell-env.js'
|
|
117
118
|
import { stripAnsi, maskApiKey, displayWidth, padEndDisplay, tintOverlayLines, keepOverlayTargetVisible, sliceOverlayLines, calculateViewport, sortResultsWithPinnedFavorites, adjustScrollOffset } from '../src/render-helpers.js'
|
|
118
119
|
import { renderTable, PROVIDER_COLOR } from '../src/render-table.js'
|
|
119
120
|
import { setOpenCodeModelData, startOpenCode, startOpenCodeDesktop } from '../src/opencode.js'
|
|
@@ -215,6 +216,31 @@ export async function runApp(cliArgs, config) {
|
|
|
215
216
|
console.log()
|
|
216
217
|
process.exit(1)
|
|
217
218
|
}
|
|
219
|
+
// 📖 New users get shell env enabled by default
|
|
220
|
+
if (config.settings.shellEnvEnabled === undefined) {
|
|
221
|
+
config.settings.shellEnvEnabled = true
|
|
222
|
+
saveConfig(config)
|
|
223
|
+
syncShellEnv(config)
|
|
224
|
+
ensureShellRcSource()
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// 📖 Shell env migration popup for existing users who haven't been asked yet
|
|
229
|
+
// 📖 Only show when user has keys but shellEnvEnabled is still undefined (never prompted)
|
|
230
|
+
if (hasAnyKey && config.settings.shellEnvEnabled === undefined) {
|
|
231
|
+
const choice = await promptShellEnvMigration(config)
|
|
232
|
+
if (choice === 'enable') {
|
|
233
|
+
if (!config.settings) config.settings = {}
|
|
234
|
+
config.settings.shellEnvEnabled = true
|
|
235
|
+
saveConfig(config)
|
|
236
|
+
syncShellEnv(config)
|
|
237
|
+
ensureShellRcSource()
|
|
238
|
+
} else if (choice === 'never') {
|
|
239
|
+
if (!config.settings) config.settings = {}
|
|
240
|
+
config.settings.shellEnvEnabled = false
|
|
241
|
+
saveConfig(config)
|
|
242
|
+
}
|
|
243
|
+
// 📖 'skip' leaves shellEnvEnabled undefined — will prompt again next launch
|
|
218
244
|
}
|
|
219
245
|
|
|
220
246
|
// 📖 Default mode: use the last persisted launcher choice when valid,
|
|
@@ -233,6 +259,10 @@ export async function runApp(cliArgs, config) {
|
|
|
233
259
|
qwen: cliArgs.qwenMode,
|
|
234
260
|
openhands: cliArgs.openHandsMode,
|
|
235
261
|
amp: cliArgs.ampMode,
|
|
262
|
+
hermes: cliArgs.hermesMode,
|
|
263
|
+
'continue': cliArgs.continueMode,
|
|
264
|
+
cline: cliArgs.clineMode,
|
|
265
|
+
xcode: cliArgs.xcodeMode,
|
|
236
266
|
pi: cliArgs.piMode,
|
|
237
267
|
rovo: cliArgs.rovoMode,
|
|
238
268
|
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
|
}
|
package/src/config.js
CHANGED
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, unlinkSync, renameSync } from 'node:fs'
|
|
103
103
|
import { homedir } from 'node:os'
|
|
104
104
|
import { join } from 'node:path'
|
|
105
|
+
import { syncShellEnv } from './shell-env.js'
|
|
105
106
|
|
|
106
107
|
// 📖 New JSON config path — stores all providers' API keys + enabled state
|
|
107
108
|
export const CONFIG_PATH = join(homedir(), '.free-coding-models.json')
|
|
@@ -484,6 +485,12 @@ export function saveConfig(config, options = {}) {
|
|
|
484
485
|
}
|
|
485
486
|
|
|
486
487
|
replaceConfigContents(config, persistedConfig)
|
|
488
|
+
|
|
489
|
+
// 📖 Keep shell env file in sync when enabled
|
|
490
|
+
if (persistedConfig.settings?.shellEnvEnabled) {
|
|
491
|
+
try { syncShellEnv(persistedConfig) } catch { /* non-critical */ }
|
|
492
|
+
}
|
|
493
|
+
|
|
487
494
|
return { success: true, backupCreated }
|
|
488
495
|
} catch (verifyError) {
|
|
489
496
|
// 📖 Verification failed - this is critical!
|
|
@@ -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/key-handler.js
CHANGED
|
@@ -33,6 +33,7 @@ import { loadConfig, replaceConfigContents } from './config.js'
|
|
|
33
33
|
import { cleanupLegacyProxyArtifacts } from './legacy-proxy-cleanup.js'
|
|
34
34
|
import { getLastLayout, COLUMN_SORT_MAP } from './render-table.js'
|
|
35
35
|
import { cycleThemeSetting, detectActiveTheme } from './theme.js'
|
|
36
|
+
import { syncShellEnv, ensureShellRcSource, removeShellEnv } from './shell-env.js'
|
|
36
37
|
import { buildCommandPaletteTree, flattenCommandTree, filterCommandPaletteEntries } from './command-palette.js'
|
|
37
38
|
import { WIDTH_WARNING_MIN_COLS } from './constants.js'
|
|
38
39
|
import { scanAllToolConfigs, softDeleteModel } from './installed-models-manager.js'
|
|
@@ -553,6 +554,19 @@ export function createKeyHandler(ctx) {
|
|
|
553
554
|
applyThemeSetting(cycleThemeSetting(currentTheme))
|
|
554
555
|
}
|
|
555
556
|
|
|
557
|
+
function toggleShellEnv() {
|
|
558
|
+
if (!state.config.settings) state.config.settings = {}
|
|
559
|
+
const currentlyEnabled = state.config.settings.shellEnvEnabled === true
|
|
560
|
+
state.config.settings.shellEnvEnabled = !currentlyEnabled
|
|
561
|
+
saveConfig(state.config)
|
|
562
|
+
if (!currentlyEnabled) {
|
|
563
|
+
syncShellEnv(state.config)
|
|
564
|
+
ensureShellRcSource()
|
|
565
|
+
} else {
|
|
566
|
+
removeShellEnv()
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
556
570
|
function resetInstallEndpointsOverlay() {
|
|
557
571
|
state.installEndpointsOpen = false
|
|
558
572
|
state.installEndpointsPhase = 'providers'
|
|
@@ -1828,8 +1842,9 @@ export function createKeyHandler(ctx) {
|
|
|
1828
1842
|
const favoritesModeRowIdx = themeRowIdx + 1
|
|
1829
1843
|
const cleanupLegacyProxyRowIdx = favoritesModeRowIdx + 1
|
|
1830
1844
|
const changelogViewRowIdx = cleanupLegacyProxyRowIdx + 1
|
|
1845
|
+
const shellEnvRowIdx = changelogViewRowIdx + 1
|
|
1831
1846
|
// 📖 Profile system removed - API keys now persist permanently across all sessions
|
|
1832
|
-
const maxRowIdx =
|
|
1847
|
+
const maxRowIdx = shellEnvRowIdx
|
|
1833
1848
|
|
|
1834
1849
|
// 📖 Edit/Add-key mode: capture typed characters for the API key
|
|
1835
1850
|
if (state.settingsEditMode || state.settingsAddKeyMode) {
|
|
@@ -1993,6 +2008,12 @@ export function createKeyHandler(ctx) {
|
|
|
1993
2008
|
return
|
|
1994
2009
|
}
|
|
1995
2010
|
|
|
2011
|
+
// 📖 Shell env row: Enter → toggle shell env export
|
|
2012
|
+
if (state.settingsCursor === shellEnvRowIdx) {
|
|
2013
|
+
toggleShellEnv()
|
|
2014
|
+
return
|
|
2015
|
+
}
|
|
2016
|
+
|
|
1996
2017
|
// 📖 Profile system removed - API keys now persist permanently across all sessions
|
|
1997
2018
|
|
|
1998
2019
|
// 📖 Enter edit mode for the selected provider's key
|
|
@@ -2010,6 +2031,11 @@ export function createKeyHandler(ctx) {
|
|
|
2010
2031
|
|| state.settingsCursor === cleanupLegacyProxyRowIdx
|
|
2011
2032
|
|| state.settingsCursor === changelogViewRowIdx
|
|
2012
2033
|
) return
|
|
2034
|
+
// 📖 Shell env toggle
|
|
2035
|
+
if (state.settingsCursor === shellEnvRowIdx) {
|
|
2036
|
+
toggleShellEnv()
|
|
2037
|
+
return
|
|
2038
|
+
}
|
|
2013
2039
|
// 📖 Theme configuration cycle inside settings
|
|
2014
2040
|
if (state.settingsCursor === themeRowIdx) {
|
|
2015
2041
|
cycleGlobalTheme()
|
package/src/overlays.js
CHANGED
|
@@ -120,6 +120,7 @@ export function createOverlayRenderers(state, deps) {
|
|
|
120
120
|
const favoritesModeRowIdx = themeRowIdx + 1
|
|
121
121
|
const cleanupLegacyProxyRowIdx = favoritesModeRowIdx + 1
|
|
122
122
|
const changelogViewRowIdx = cleanupLegacyProxyRowIdx + 1
|
|
123
|
+
const shellEnvRowIdx = changelogViewRowIdx + 1
|
|
123
124
|
const EL = '\x1b[K'
|
|
124
125
|
const lines = []
|
|
125
126
|
const cursorLineByRow = {}
|
|
@@ -272,6 +273,15 @@ export function createOverlayRenderers(state, deps) {
|
|
|
272
273
|
cursorLineByRow[changelogViewRowIdx] = lines.length
|
|
273
274
|
lines.push(state.settingsCursor === changelogViewRowIdx ? themeColors.bgCursorSettingsList(changelogViewRow) : changelogViewRow)
|
|
274
275
|
|
|
276
|
+
// 📖 Shell env toggle — expose API keys as shell environment variables
|
|
277
|
+
const shellEnvEnabled = state.config.settings?.shellEnvEnabled === true
|
|
278
|
+
const shellEnvStatus = shellEnvEnabled
|
|
279
|
+
? themeColors.successBold('✅ Enabled — keys available in shell')
|
|
280
|
+
: themeColors.dim('❌ Disabled')
|
|
281
|
+
const shellEnvRow = `${bullet(state.settingsCursor === shellEnvRowIdx)}${themeColors.textBold('Shell Env Export').padEnd(44)} ${shellEnvStatus}`
|
|
282
|
+
cursorLineByRow[shellEnvRowIdx] = lines.length
|
|
283
|
+
lines.push(state.settingsCursor === shellEnvRowIdx ? themeColors.bgCursorSettingsList(shellEnvRow) : shellEnvRow)
|
|
284
|
+
|
|
275
285
|
// 📖 Profile system removed - API keys now persist permanently across all sessions
|
|
276
286
|
|
|
277
287
|
lines.push('')
|
|
@@ -313,7 +323,7 @@ export function createOverlayRenderers(state, deps) {
|
|
|
313
323
|
// 📖 Mouse support: record layout so click handler can map Y → settingsCursor
|
|
314
324
|
overlayLayout.settingsCursorToLine = { ...cursorLineByRow }
|
|
315
325
|
overlayLayout.settingsScrollOffset = offset
|
|
316
|
-
overlayLayout.settingsMaxRow =
|
|
326
|
+
overlayLayout.settingsMaxRow = shellEnvRowIdx
|
|
317
327
|
|
|
318
328
|
const tintedLines = tintOverlayLines(visible, themeColors.overlayBgSettings, state.terminalCols)
|
|
319
329
|
const cleared = tintedLines.map(l => l + EL)
|