free-coding-models 0.1.76 β 0.1.77
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/README.md +1 -0
- package/bin/free-coding-models.js +246 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
- **π» OpenCode integration** β Auto-detects NIM setup, sets model as default, launches OpenCode
|
|
80
80
|
- **π¦ OpenClaw integration** β Sets selected model as default provider in `~/.openclaw/openclaw.json`
|
|
81
81
|
- **π Feature Request (J key)** β Send anonymous feedback directly to the project team via a full-screen overlay with multi-line input (includes anonymous OS/terminal metadata in message footer only)
|
|
82
|
+
- **π Bug Report (I key)** β Send anonymous bug reports directly to the project team via a full-screen overlay with multi-line input (includes anonymous OS/terminal metadata in message footer only)
|
|
82
83
|
- **π¨ Clean output** β Zero scrollback pollution, interface stays open until Ctrl+C
|
|
83
84
|
- **πΆ Status indicators** β UP β
Β· No Key π Β· Timeout β³ Β· Overloaded π₯ Β· Not Found π«
|
|
84
85
|
- **π Keyless latency** β Models are pinged even without an API key β a `π NO KEY` status confirms the server is reachable with real latency shown, so you can compare providers before committing to a key
|
|
@@ -171,6 +171,54 @@ async function sendFeatureRequest(message) {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
// π Discord bug report webhook configuration (anonymous bug reports)
|
|
175
|
+
const DISCORD_BUG_WEBHOOK_URL = 'https://discord.com/api/webhooks/1476715954409963743/5cOLf7U_891f1jwxRBLIp2RIP9xYhr4rWtOhipzKKwVdFVl1Bj89X_fB6I_uGXZiGT9E'
|
|
176
|
+
const DISCORD_BUG_BOT_NAME = 'TUI Bug Report'
|
|
177
|
+
const DISCORD_BUG_EMBED_COLOR = 0xFF5733 // Rouge (RGB: 255, 87, 51)
|
|
178
|
+
|
|
179
|
+
// π sendBugReport: Send anonymous bug report to Discord via webhook
|
|
180
|
+
// π Called when user presses I key, types message, and presses Enter
|
|
181
|
+
// π Returns success/error status for UI feedback
|
|
182
|
+
async function sendBugReport(message) {
|
|
183
|
+
try {
|
|
184
|
+
// π Collect anonymous telemetry for context (no personal data)
|
|
185
|
+
const system = getTelemetrySystem()
|
|
186
|
+
const terminal = getTelemetryTerminal()
|
|
187
|
+
const nodeVersion = process.version
|
|
188
|
+
const arch = process.arch
|
|
189
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'Unknown'
|
|
190
|
+
|
|
191
|
+
// π Build Discord embed with rich metadata in footer (compact format)
|
|
192
|
+
const embed = {
|
|
193
|
+
description: message,
|
|
194
|
+
color: DISCORD_BUG_EMBED_COLOR,
|
|
195
|
+
timestamp: new Date().toISOString(),
|
|
196
|
+
footer: {
|
|
197
|
+
text: `v${LOCAL_VERSION} β’ ${system} β’ ${terminal} β’ ${nodeVersion} β’ ${arch} β’ ${timezone}`
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const response = await fetch(DISCORD_BUG_WEBHOOK_URL, {
|
|
202
|
+
method: 'POST',
|
|
203
|
+
headers: { 'content-type': 'application/json' },
|
|
204
|
+
body: JSON.stringify({
|
|
205
|
+
username: DISCORD_BUG_BOT_NAME,
|
|
206
|
+
embeds: [embed]
|
|
207
|
+
}),
|
|
208
|
+
signal: AbortSignal.timeout(10000) // π 10s timeout for webhook
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
if (!response.ok) {
|
|
212
|
+
throw new Error(`HTTP ${response.status}`)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return { success: true, error: null }
|
|
216
|
+
} catch (error) {
|
|
217
|
+
const message = error instanceof Error ? error.message : 'Unknown error'
|
|
218
|
+
return { success: false, error: message }
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
174
222
|
// π parseTelemetryEnv: Convert env var strings into booleans.
|
|
175
223
|
// π Returns true/false when value is recognized, otherwise null.
|
|
176
224
|
function parseTelemetryEnv(value) {
|
|
@@ -1338,8 +1386,8 @@ function renderTable(results, pendingPings, frame, cursor = null, sortColumn = '
|
|
|
1338
1386
|
: chalk.rgb(0, 200, 255)('EnterβOpenCode')
|
|
1339
1387
|
// π Line 1: core navigation + sorting shortcuts
|
|
1340
1388
|
lines.push(chalk.dim(` ββ Navigate β’ `) + actionHint + chalk.dim(` β’ `) + chalk.yellow('F') + chalk.dim(` Favorite β’ R/Y/O/M/L/A/S/C/H/V/B/U Sort β’ `) + chalk.yellow('T') + chalk.dim(` Tier β’ `) + chalk.yellow('N') + chalk.dim(` Origin β’ Wβ/Xβ (${intervalSec}s) β’ `) + chalk.rgb(255, 100, 50).bold('Z') + chalk.dim(` Mode β’ `) + chalk.yellow('P') + chalk.dim(` Settings β’ `) + chalk.rgb(0, 255, 80).bold('K') + chalk.dim(` Help`))
|
|
1341
|
-
// π Line 2: profiles, recommend, feature request, and extended hints β gives visibility to less-obvious features
|
|
1342
|
-
lines.push(chalk.dim(` `) + chalk.rgb(200, 150, 255).bold('β§P') + chalk.dim(` Cycle profile β’ `) + chalk.rgb(200, 150, 255).bold('β§S') + chalk.dim(` Save profile β’ `) + chalk.rgb(0, 200, 180).bold('Q') + chalk.dim(` Smart Recommend β’ `) + chalk.rgb(57, 255, 20).bold('J') + chalk.dim(` Request feature β’ `) + chalk.yellow('E') + chalk.dim(`/`) + chalk.yellow('D') + chalk.dim(` Tier ββ β’ `) + chalk.yellow('Esc') + chalk.dim(` Close overlay β’ Ctrl+C Exit`))
|
|
1389
|
+
// π Line 2: profiles, recommend, feature request, bug report, and extended hints β gives visibility to less-obvious features
|
|
1390
|
+
lines.push(chalk.dim(` `) + chalk.rgb(200, 150, 255).bold('β§P') + chalk.dim(` Cycle profile β’ `) + chalk.rgb(200, 150, 255).bold('β§S') + chalk.dim(` Save profile β’ `) + chalk.rgb(0, 200, 180).bold('Q') + chalk.dim(` Smart Recommend β’ `) + chalk.rgb(57, 255, 20).bold('J') + chalk.dim(` Request feature β’ `) + chalk.rgb(255, 87, 51).bold('I') + chalk.dim(` Report bug β’ `) + chalk.yellow('E') + chalk.dim(`/`) + chalk.yellow('D') + chalk.dim(` Tier ββ β’ `) + chalk.yellow('Esc') + chalk.dim(` Close overlay β’ Ctrl+C Exit`))
|
|
1343
1391
|
lines.push('')
|
|
1344
1392
|
lines.push(
|
|
1345
1393
|
chalk.rgb(255, 150, 200)(' Made with π & β by \x1b]8;;https://github.com/vava-nessa\x1b\\vava-nessa\x1b]8;;\x1b\\') +
|
|
@@ -2865,11 +2913,16 @@ async function main() {
|
|
|
2865
2913
|
activeProfile: getActiveProfileName(config), // π Currently loaded profile name (or null)
|
|
2866
2914
|
profileSaveMode: false, // π Whether the inline "Save profile" name input is active
|
|
2867
2915
|
profileSaveBuffer: '', // π Typed characters for the profile name being saved
|
|
2868
|
-
// π Feature Request state (
|
|
2916
|
+
// π Feature Request state (J key opens it)
|
|
2869
2917
|
featureRequestOpen: false, // π Whether the feature request overlay is active
|
|
2870
2918
|
featureRequestBuffer: '', // π Typed characters for the feature request message
|
|
2871
2919
|
featureRequestStatus: 'idle', // π 'idle'|'sending'|'success'|'error' β webhook send status
|
|
2872
2920
|
featureRequestError: null, // π Last webhook error message
|
|
2921
|
+
// π Bug Report state (I key opens it)
|
|
2922
|
+
bugReportOpen: false, // π Whether the bug report overlay is active
|
|
2923
|
+
bugReportBuffer: '', // π Typed characters for the bug report message
|
|
2924
|
+
bugReportStatus: 'idle', // π 'idle'|'sending'|'success'|'error' β webhook send status
|
|
2925
|
+
bugReportError: null, // π Last webhook error message
|
|
2873
2926
|
}
|
|
2874
2927
|
|
|
2875
2928
|
// π Re-clamp viewport on terminal resize
|
|
@@ -3147,6 +3200,7 @@ async function main() {
|
|
|
3147
3200
|
lines.push(` ${chalk.yellow('F')} Toggle favorite on selected row ${chalk.dim('(β pinned at top, persisted)')}`)
|
|
3148
3201
|
lines.push(` ${chalk.yellow('Q')} Smart Recommend ${chalk.dim('(π― find the best model for your task β questionnaire + live analysis)')}`)
|
|
3149
3202
|
lines.push(` ${chalk.rgb(57, 255, 20).bold('J')} Request Feature ${chalk.dim('(π send anonymous feedback to the project team)')}`)
|
|
3203
|
+
lines.push(` ${chalk.rgb(255, 87, 51).bold('I')} Report Bug ${chalk.dim('(π send anonymous bug report to the project team)')}`)
|
|
3150
3204
|
lines.push(` ${chalk.yellow('P')} Open settings ${chalk.dim('(manage API keys, provider toggles, analytics, manual update)')}`)
|
|
3151
3205
|
lines.push(` ${chalk.yellow('Shift+P')} Cycle config profile ${chalk.dim('(switch between saved profiles live)')}`)
|
|
3152
3206
|
lines.push(` ${chalk.yellow('Shift+S')} Save current config as a named profile ${chalk.dim('(inline prompt β type name + Enter)')}`)
|
|
@@ -3491,6 +3545,112 @@ async function main() {
|
|
|
3491
3545
|
return cleared.join('\n')
|
|
3492
3546
|
}
|
|
3493
3547
|
|
|
3548
|
+
// βββ Bug Report overlay renderer βββββββββββββββββββββββββββββββββββββββββ
|
|
3549
|
+
// π renderBugReport: Draw the overlay for anonymous Discord bug reports.
|
|
3550
|
+
// π Shows an input field where users can type bug reports, then sends to Discord webhook.
|
|
3551
|
+
function renderBugReport() {
|
|
3552
|
+
const EL = '\x1b[K'
|
|
3553
|
+
const lines = []
|
|
3554
|
+
|
|
3555
|
+
// π Calculate available space for multi-line input
|
|
3556
|
+
const maxInputWidth = OVERLAY_PANEL_WIDTH - 8 // 8 = padding (4 spaces each side)
|
|
3557
|
+
const maxInputLines = 10 // Show up to 10 lines of input
|
|
3558
|
+
|
|
3559
|
+
// π Split buffer into lines for display (with wrapping)
|
|
3560
|
+
const wrapText = (text, width) => {
|
|
3561
|
+
const words = text.split(' ')
|
|
3562
|
+
const lines = []
|
|
3563
|
+
let currentLine = ''
|
|
3564
|
+
|
|
3565
|
+
for (const word of words) {
|
|
3566
|
+
const testLine = currentLine ? currentLine + ' ' + word : word
|
|
3567
|
+
if (testLine.length <= width) {
|
|
3568
|
+
currentLine = testLine
|
|
3569
|
+
} else {
|
|
3570
|
+
if (currentLine) lines.push(currentLine)
|
|
3571
|
+
currentLine = word
|
|
3572
|
+
}
|
|
3573
|
+
}
|
|
3574
|
+
if (currentLine) lines.push(currentLine)
|
|
3575
|
+
return lines
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
const inputLines = wrapText(state.bugReportBuffer, maxInputWidth)
|
|
3579
|
+
const displayLines = inputLines.slice(0, maxInputLines)
|
|
3580
|
+
|
|
3581
|
+
// π Header
|
|
3582
|
+
lines.push('')
|
|
3583
|
+
lines.push(` ${chalk.bold.rgb(255, 87, 51)('π Bug Report')} ${chalk.dim('β send anonymous bug reports to the project team')}`)
|
|
3584
|
+
lines.push('')
|
|
3585
|
+
|
|
3586
|
+
// π Status messages (if any)
|
|
3587
|
+
if (state.bugReportStatus === 'sending') {
|
|
3588
|
+
lines.push(` ${chalk.yellow('β³ Sending...')}`)
|
|
3589
|
+
lines.push('')
|
|
3590
|
+
} else if (state.bugReportStatus === 'success') {
|
|
3591
|
+
lines.push(` ${chalk.greenBright.bold('β
Successfully sent!')} ${chalk.dim('Closing overlay in 3 seconds...')}`)
|
|
3592
|
+
lines.push('')
|
|
3593
|
+
lines.push(` ${chalk.dim('Thank you for your feedback! Your bug report has been sent to the project team.')}`)
|
|
3594
|
+
lines.push('')
|
|
3595
|
+
} else if (state.bugReportStatus === 'error') {
|
|
3596
|
+
lines.push(` ${chalk.red('β Error:')} ${chalk.yellow(state.bugReportError || 'Failed to send')}`)
|
|
3597
|
+
lines.push(` ${chalk.dim('Press Backspace to edit, or Esc to close')}`)
|
|
3598
|
+
lines.push('')
|
|
3599
|
+
} else {
|
|
3600
|
+
lines.push(` ${chalk.dim('Describe the bug you encountered. Press Enter to send, Esc to cancel.')}`)
|
|
3601
|
+
lines.push(` ${chalk.dim('Your message will be sent anonymously to the project team.')}`)
|
|
3602
|
+
lines.push('')
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3605
|
+
// π Input box with border
|
|
3606
|
+
lines.push(chalk.dim(` ββ ${chalk.cyan('Bug Details')} ${chalk.dim(`(${state.bugReportBuffer.length}/500 chars)`)} β${'β'.repeat(maxInputWidth - 24)}β`))
|
|
3607
|
+
|
|
3608
|
+
// π Display input lines (or placeholder if empty)
|
|
3609
|
+
if (displayLines.length === 0 && state.bugReportStatus === 'idle') {
|
|
3610
|
+
lines.push(chalk.dim(` β${' '.repeat(maxInputWidth)}β`))
|
|
3611
|
+
lines.push(chalk.dim(` β ${chalk.white.italic('Describe what happened...')}${' '.repeat(Math.max(0, maxInputWidth - 31))}β`))
|
|
3612
|
+
} else {
|
|
3613
|
+
for (const line of displayLines) {
|
|
3614
|
+
const padded = line.padEnd(maxInputWidth)
|
|
3615
|
+
lines.push(` β ${chalk.white(padded)} β`)
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
// π Fill remaining space if needed
|
|
3620
|
+
const linesToFill = Math.max(0, maxInputLines - Math.max(displayLines.length, 1))
|
|
3621
|
+
for (let i = 0; i < linesToFill; i++) {
|
|
3622
|
+
lines.push(chalk.dim(` β${' '.repeat(maxInputWidth)}β`))
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3625
|
+
// π Cursor indicator (only when not sending/success)
|
|
3626
|
+
if (state.bugReportStatus === 'idle' || state.bugReportStatus === 'error') {
|
|
3627
|
+
const cursorLine = inputLines.length > 0 ? inputLines.length - 1 : 0
|
|
3628
|
+
const lastDisplayLine = displayLines.length - 1
|
|
3629
|
+
// Add cursor indicator to the last line
|
|
3630
|
+
if (lines.length > 0 && displayLines.length > 0) {
|
|
3631
|
+
const lastLineIdx = lines.findIndex(l => l.includes('β ') && !l.includes('Bug Details'))
|
|
3632
|
+
if (lastLineIdx >= 0 && lastLineIdx < lines.length) {
|
|
3633
|
+
// Add cursor blink
|
|
3634
|
+
const lastLine = lines[lastLineIdx]
|
|
3635
|
+
if (lastLine.includes('β')) {
|
|
3636
|
+
lines[lastLineIdx] = lastLine.replace(/\s+β$/, chalk.rgb(255, 87, 51).bold('β') + ' β')
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
|
|
3642
|
+
lines.push(chalk.dim(` β${'β'.repeat(maxInputWidth + 2)}β`))
|
|
3643
|
+
|
|
3644
|
+
lines.push('')
|
|
3645
|
+
lines.push(chalk.dim(' Enter Send β’ Esc Cancel β’ Backspace Delete'))
|
|
3646
|
+
|
|
3647
|
+
// π Apply overlay tint and return
|
|
3648
|
+
const BUG_REPORT_OVERLAY_BG = chalk.bgRgb(46, 20, 20) // Dark red-ish background (RGB: 46, 20, 20)
|
|
3649
|
+
const tintedLines = tintOverlayLines(lines, BUG_REPORT_OVERLAY_BG)
|
|
3650
|
+
const cleared = tintedLines.map(l => l + EL)
|
|
3651
|
+
return cleared.join('\n')
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3494
3654
|
// π stopRecommendAnalysis: cleanup timers if user cancels during analysis
|
|
3495
3655
|
function stopRecommendAnalysis() {
|
|
3496
3656
|
if (state.recommendAnalysisTimer) { clearInterval(state.recommendAnalysisTimer); state.recommendAnalysisTimer = null }
|
|
@@ -3674,6 +3834,73 @@ async function main() {
|
|
|
3674
3834
|
return
|
|
3675
3835
|
}
|
|
3676
3836
|
|
|
3837
|
+
// π Bug Report overlay: intercept ALL keys while overlay is active.
|
|
3838
|
+
// π Enter β send to Discord, Esc β cancel, Backspace β delete char, printable β append to buffer.
|
|
3839
|
+
if (state.bugReportOpen) {
|
|
3840
|
+
if (key.ctrl && key.name === 'c') { exit(0); return }
|
|
3841
|
+
|
|
3842
|
+
if (key.name === 'escape') {
|
|
3843
|
+
// π Cancel bug report β close overlay
|
|
3844
|
+
state.bugReportOpen = false
|
|
3845
|
+
state.bugReportBuffer = ''
|
|
3846
|
+
state.bugReportStatus = 'idle'
|
|
3847
|
+
state.bugReportError = null
|
|
3848
|
+
return
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
if (key.name === 'return') {
|
|
3852
|
+
// π Send bug report to Discord webhook
|
|
3853
|
+
const message = state.bugReportBuffer.trim()
|
|
3854
|
+
if (message.length > 0 && state.bugReportStatus !== 'sending') {
|
|
3855
|
+
state.bugReportStatus = 'sending'
|
|
3856
|
+
const result = await sendBugReport(message)
|
|
3857
|
+
if (result.success) {
|
|
3858
|
+
// π Success β show confirmation briefly, then close overlay after 3 seconds
|
|
3859
|
+
state.bugReportStatus = 'success'
|
|
3860
|
+
setTimeout(() => {
|
|
3861
|
+
state.bugReportOpen = false
|
|
3862
|
+
state.bugReportBuffer = ''
|
|
3863
|
+
state.bugReportStatus = 'idle'
|
|
3864
|
+
state.bugReportError = null
|
|
3865
|
+
}, 3000)
|
|
3866
|
+
} else {
|
|
3867
|
+
// π Error β show error message, keep overlay open
|
|
3868
|
+
state.bugReportStatus = 'error'
|
|
3869
|
+
state.bugReportError = result.error || 'Unknown error'
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
return
|
|
3873
|
+
}
|
|
3874
|
+
|
|
3875
|
+
if (key.name === 'backspace') {
|
|
3876
|
+
// π Don't allow editing while sending or after success
|
|
3877
|
+
if (state.bugReportStatus === 'sending' || state.bugReportStatus === 'success') return
|
|
3878
|
+
state.bugReportBuffer = state.bugReportBuffer.slice(0, -1)
|
|
3879
|
+
// π Clear error status when user starts editing again
|
|
3880
|
+
if (state.bugReportStatus === 'error') {
|
|
3881
|
+
state.bugReportStatus = 'idle'
|
|
3882
|
+
state.bugReportError = null
|
|
3883
|
+
}
|
|
3884
|
+
return
|
|
3885
|
+
}
|
|
3886
|
+
|
|
3887
|
+
// π Append printable characters (str is the raw character typed)
|
|
3888
|
+
// π Limit to 500 characters (Discord embed description limit)
|
|
3889
|
+
if (str && str.length === 1 && !key.ctrl && !key.meta) {
|
|
3890
|
+
// π Don't allow editing while sending or after success
|
|
3891
|
+
if (state.bugReportStatus === 'sending' || state.bugReportStatus === 'success') return
|
|
3892
|
+
if (state.bugReportBuffer.length < 500) {
|
|
3893
|
+
state.bugReportBuffer += str
|
|
3894
|
+
// π Clear error status when user starts editing again
|
|
3895
|
+
if (state.bugReportStatus === 'error') {
|
|
3896
|
+
state.bugReportStatus = 'idle'
|
|
3897
|
+
state.bugReportError = null
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
return
|
|
3902
|
+
}
|
|
3903
|
+
|
|
3677
3904
|
// π Help overlay: full keyboard navigation + key swallowing while overlay is open.
|
|
3678
3905
|
if (state.helpVisible) {
|
|
3679
3906
|
const pageStep = Math.max(1, (state.terminalRows || 1) - 2)
|
|
@@ -4155,6 +4382,15 @@ async function main() {
|
|
|
4155
4382
|
return
|
|
4156
4383
|
}
|
|
4157
4384
|
|
|
4385
|
+
// π I key: open Bug Report overlay (anonymous Discord bug reports)
|
|
4386
|
+
if (key.name === 'i') {
|
|
4387
|
+
state.bugReportOpen = true
|
|
4388
|
+
state.bugReportBuffer = ''
|
|
4389
|
+
state.bugReportStatus = 'idle'
|
|
4390
|
+
state.bugReportError = null
|
|
4391
|
+
return
|
|
4392
|
+
}
|
|
4393
|
+
|
|
4158
4394
|
// π Interval adjustment keys: W=decrease (faster), X=increase (slower)
|
|
4159
4395
|
// π Minimum 1s, maximum 60s
|
|
4160
4396
|
if (key.name === 'w') {
|
|
@@ -4288,11 +4524,11 @@ async function main() {
|
|
|
4288
4524
|
|
|
4289
4525
|
process.stdin.on('keypress', onKeyPress)
|
|
4290
4526
|
|
|
4291
|
-
// π Animation loop: render settings overlay, recommend overlay, help overlay, feature request overlay, OR main table
|
|
4527
|
+
// π Animation loop: render settings overlay, recommend overlay, help overlay, feature request overlay, bug report overlay, OR main table
|
|
4292
4528
|
const ticker = setInterval(() => {
|
|
4293
4529
|
state.frame++
|
|
4294
4530
|
// π Cache visible+sorted models each frame so Enter handler always matches the display
|
|
4295
|
-
if (!state.settingsOpen && !state.recommendOpen && !state.featureRequestOpen) {
|
|
4531
|
+
if (!state.settingsOpen && !state.recommendOpen && !state.featureRequestOpen && !state.bugReportOpen) {
|
|
4296
4532
|
const visible = state.results.filter(r => !r.hidden)
|
|
4297
4533
|
state.visibleSorted = sortResultsWithPinnedFavorites(visible, state.sortColumn, state.sortDirection)
|
|
4298
4534
|
}
|
|
@@ -4302,9 +4538,11 @@ async function main() {
|
|
|
4302
4538
|
? renderRecommend()
|
|
4303
4539
|
: state.featureRequestOpen
|
|
4304
4540
|
? renderFeatureRequest()
|
|
4305
|
-
: state.
|
|
4306
|
-
?
|
|
4307
|
-
:
|
|
4541
|
+
: state.bugReportOpen
|
|
4542
|
+
? renderBugReport()
|
|
4543
|
+
: state.helpVisible
|
|
4544
|
+
? renderHelp()
|
|
4545
|
+
: renderTable(state.results, state.pendingPings, state.frame, state.cursor, state.sortColumn, state.sortDirection, state.pingInterval, state.lastPingTime, state.mode, tierFilterMode, state.scrollOffset, state.terminalRows, originFilterMode, state.activeProfile, state.profileSaveMode, state.profileSaveBuffer)
|
|
4308
4546
|
process.stdout.write(ALT_HOME + content)
|
|
4309
4547
|
}, Math.round(1000 / FPS))
|
|
4310
4548
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.77",
|
|
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",
|