vibehacker 4.1.0 → 4.2.0

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 CHANGED
@@ -1,77 +1,415 @@
1
- # Vibe Hacker
1
+ <p align="center">
2
+ <img src="https://vibsecurity.com/logo.png" alt="Vibe Hacker" width="80" />
3
+ </p>
2
4
 
3
- > Terminal AI assistant for cybersecurity professionals. Free models, autonomous agent, multi-provider rotation. No credit card required.
5
+ <h1 align="center">Vibe Hacker</h1>
4
6
 
5
- [![npm version](https://img.shields.io/npm/v/vibehacker.svg)](https://www.npmjs.com/package/vibehacker)
6
- [![license](https://img.shields.io/npm/l/vibehacker.svg)](https://github.com/agentichacker/vibehacker/blob/main/LICENSE)
7
- [![node](https://img.shields.io/node/v/vibehacker.svg)](https://nodejs.org)
7
+ <p align="center">
8
+ <strong>Terminal AI Cybersecurity Assistant</strong><br/>
9
+ Autonomous agent with 10 tools, 13 providers, multi-model rotation — 100% free to start.
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/vibehacker"><img src="https://img.shields.io/npm/v/vibehacker?color=00ff88&label=npm" alt="npm version" /></a>
14
+ <a href="https://www.npmjs.com/package/vibehacker"><img src="https://img.shields.io/npm/dm/vibehacker?color=00ff88" alt="npm downloads" /></a>
15
+ <a href="https://github.com/agentichacker/vibehacker/blob/main/LICENSE"><img src="https://img.shields.io/github/license/agentichacker/vibehacker?color=00ff88" alt="license" /></a>
16
+ <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D16-00ff88" alt="node version" /></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://vibsecurity.com">Website</a> &middot;
21
+ <a href="#install">Install</a> &middot;
22
+ <a href="#providers">Providers</a> &middot;
23
+ <a href="https://github.com/agentichacker/vibehacker/issues">Issues</a> &middot;
24
+ <a href="CONTRIBUTING.md">Contributing</a>
25
+ </p>
26
+
27
+ ---
28
+
29
+ ## What is Vibe Hacker?
30
+
31
+ Vibe Hacker is an AI-powered cybersecurity assistant that runs entirely in your terminal. It can read, write, and edit files, run shell commands, search codebases, and reason about security — all autonomously.
32
+
33
+ Think of it as **Claude Code for cybersecurity** — but free, open-source, and works with 13 AI providers out of the box.
34
+
35
+ ```
36
+ +-----------------------------------------------------------------+
37
+ | Vibe Hacker v4.1.0 Hunt Mode Vibe Model |
38
+ +-----------------------------------------------------------------+
39
+ | |
40
+ | You: Find all SQL injection vulnerabilities in this project |
41
+ | |
42
+ | > Searching for SQL patterns... |
43
+ | | grep: "query|execute|raw.*sql" in **/*.js |
44
+ | | read_file: src/db/users.js (lines 45-80) |
45
+ | | edit_file: src/db/users.js (parameterized query) |
46
+ | | Done - fixed 3 SQL injection vulnerabilities |
47
+ | |
48
+ | Found 3 SQL injection vulnerabilities in src/db/: |
49
+ | - users.js:52 string concatenation in WHERE clause |
50
+ | - users.js:67 unsanitized ORDER BY |
51
+ | - posts.js:23 raw query with user input |
52
+ | All 3 have been patched with parameterized queries. |
53
+ | |
54
+ +-----------------------------------------------------------------+
55
+ | > |
56
+ +-----------------------------------------------------------------+
57
+ ```
58
+
59
+ ### Key Features
60
+
61
+ - **Autonomous Agent** — Reads, writes, edits files and runs commands to complete tasks end-to-end
62
+ - **10 Built-in Tools** — read, edit, write, execute, grep, glob, list, search, mkdir, delete
63
+ - **13 AI Providers** — Groq, Gemini, Cerebras, Mistral, OpenRouter, xAI, Anthropic, OpenAI, and more
64
+ - **Smart Rotation** — Auto-switches providers on rate limits with circuit breaker protection
65
+ - **Surgical Edit** — Exact string replacement with mtime conflict detection and undo support
66
+ - **Parallel Grep** — 8-concurrent file reads with binary extension filtering
67
+ - **Context Management** — 3-phase trimming keeps conversations within token limits
68
+ - **Project Memory** — Reads `VIBEHACKER.md` for project-specific instructions
69
+ - **100% Free** — Works with free-tier API keys, no credit card needed
70
+
71
+ ---
8
72
 
9
73
  ## Install
10
74
 
75
+ ### One-liner (Linux / macOS / WSL)
76
+
77
+ ```bash
78
+ curl -fsSL https://vibsecurity.com/install.sh | bash
79
+ ```
80
+
81
+ ### npm
82
+
11
83
  ```bash
12
84
  npm install -g vibehacker
85
+ ```
86
+
87
+ ### Run
88
+
89
+ ```bash
13
90
  vibehacker
14
91
  ```
15
92
 
16
- Or zero-install:
93
+ ### Uninstall
94
+
17
95
  ```bash
18
- npx vibehacker
96
+ npm uninstall -g vibehacker
97
+ # or
98
+ curl -fsSL https://vibsecurity.com/install.sh | bash -s -- --uninstall
19
99
  ```
20
100
 
21
- ## Get Started
101
+ ### Requirements
22
102
 
23
- 1. Get a free API key at [vibsecurity.com](https://vibsecurity.com)
24
- 2. Paste your key when prompted
25
- 3. Start hacking
103
+ - Node.js 16+ (recommend 22 LTS)
104
+ - A terminal with ANSI color support
26
105
 
27
- ## Features
106
+ ---
28
107
 
29
- - **Chat Mode** — Security Q&A, threat intel, vulnerability research
30
- - **Hunt Mode** — Autonomous agent with file system + shell access for pentesting, code review, exploit development
31
- - **Multi-Provider** — Add keys for Groq, Gemini, Cerebras, Mistral, OpenAI, Anthropic, DeepSeek, xAI
32
- - **Silent Auto-Rotation** — Rate limit on one model? Automatically switches to another. Zero downtime
33
- - **Cross-Platform** — Windows, macOS, Linux, WSL
108
+ ## Quick Start
34
109
 
35
- ## Commands
110
+ ```bash
111
+ # 1. Install
112
+ npm install -g vibehacker
36
113
 
37
- | Command | Description |
38
- |---------|-------------|
39
- | `/mode` | Switch between Chat and Hunt |
40
- | `/addkey` | Add a provider API key |
41
- | `/providers` | List configured providers |
42
- | `/clear` | Clear chat and context |
43
- | `/update` | Self-update to latest version |
44
- | `/pro` | Upgrade to Pro (unlimited requests) |
45
- | `/account` | View usage and tier info |
114
+ # 2. Launch
115
+ vibehacker
116
+
117
+ # 3. (Optional) Add a free API key for more requests
118
+ # Inside the app, type:
119
+ /addkey gsk_your_groq_key_here
120
+ ```
121
+
122
+ On first launch you get **50 free requests/day** with zero setup. Add your own free API keys for unlimited usage.
123
+
124
+ ---
125
+
126
+ ## Modes
127
+
128
+ | Mode | Description | Tools |
129
+ |------|-------------|-------|
130
+ | **Chat** | Expert Q&A — security, engineering, threat intel | None (conversation only) |
131
+ | **Hunt** | Autonomous agent — reads, writes, edits files, runs commands | All 10 tools |
132
+
133
+ Switch modes with **Tab** or `/mode`.
134
+
135
+ ---
136
+
137
+ ## Tools
138
+
139
+ Hunt mode gives the AI access to 10 tools for autonomous task completion:
140
+
141
+ | Tool | Description | Needs Approval |
142
+ |------|-------------|:--------------:|
143
+ | `read_file` | Read file contents with line numbers, offset/limit | No |
144
+ | `edit_file` | Surgical string replacement with diff output and undo | Yes |
145
+ | `write_file` | Create or overwrite files | Yes |
146
+ | `execute_command` | Run shell commands (2 min timeout) | Yes |
147
+ | `grep` | Regex search across files (parallel, 8 concurrent) | No |
148
+ | `glob` | Find files by glob pattern | No |
149
+ | `list_files` | List directory contents | No |
150
+ | `search_files` | Regex search with context lines | No |
151
+ | `create_directory` | Create directories recursively | No |
152
+ | `delete_file` | Delete a file | Yes |
153
+
154
+ ### Tool Approval
155
+
156
+ Tools that modify your system ask for confirmation before running:
157
+
158
+ | Option | Key | What it does |
159
+ |--------|-----|-------------|
160
+ | Yes | `1` or `y` | Execute this one time |
161
+ | Always allow | `2` | Auto-approve similar operations going forward |
162
+ | No | `3` or `n` | Reject |
163
+
164
+ ---
46
165
 
47
166
  ## Keyboard Shortcuts
48
167
 
49
168
  | Key | Action |
50
169
  |-----|--------|
51
- | `Tab` | Cycle mode |
170
+ | `Tab` | Cycle mode (Chat / Hunt) |
171
+ | `Ctrl+P` | Command palette |
172
+ | `Ctrl+L` | Clear output |
173
+ | `Ctrl+X` | Cancel running request |
52
174
  | `Ctrl+R` | Retry last message |
53
- | `Ctrl+C` | Cancel / exit |
54
- | `/` | Open command menu |
175
+ | `Up / Down` | Input history |
176
+ | `PageUp / PageDown` | Scroll output |
177
+ | `Escape` | Clear input |
178
+ | `Ctrl+C` | Exit |
179
+
180
+ ---
55
181
 
56
- ## Pricing
182
+ ## Slash Commands
57
183
 
58
- | | Free | Pro |
59
- |---|---|---|
60
- | Requests/day | 50 | Unlimited |
61
- | Models | Free tier | All + frontier |
62
- | Support | Community | Email |
63
- | Price | $0 | $19/mo |
184
+ | Command | Description |
185
+ |---------|-------------|
186
+ | `/clear` | Clear chat history and context |
187
+ | `/undo` | Undo the last file edit |
188
+ | `/modified` | List all files changed this session |
189
+ | `/mode` | Switch mode (Chat / Hunt) |
190
+ | `/retry` | Retry the last message |
191
+ | `/cd <path>` | Change working directory |
192
+ | `/cwd` | Show current directory |
193
+ | `/addkey <key>` | Add an AI provider key |
194
+ | `/providers` | List configured providers |
195
+ | `/model` | Switch model |
196
+ | `/tokens <n>` | Set max output tokens |
197
+ | `/approve` | Manage auto-approved tools |
198
+ | `/refresh` | Refresh model list |
199
+ | `/update` | Check for updates |
200
+ | `/pro` | Upgrade to Pro |
201
+ | `/help` | Show help |
202
+ | `/exit` | Exit |
203
+
204
+ ---
205
+
206
+ ## Providers
207
+
208
+ Vibe Hacker supports **13 AI providers**. Free-tier providers require no credit card.
209
+
210
+ ### Free Providers
211
+
212
+ | Provider | Free Limit | Top Models | Get a Key |
213
+ |----------|-----------|------------|-----------|
214
+ | **Built-in** | 50 req/day | Llama 3.3 70B, Qwen3 235B, DeepSeek R1 | No key needed |
215
+ | **Groq** | 14,400 req/day | Llama 3.3 70B, Llama 4 Scout, Kimi K2 | [console.groq.com](https://console.groq.com) |
216
+ | **Cerebras** | 1M tokens/day | Qwen3 235B, Llama 3.1 8B | [inference.cerebras.ai](https://inference.cerebras.ai) |
217
+ | **Gemini** | 1,000 req/day | Gemini 2.5 Flash, 2.5 Pro (1M context!) | [aistudio.google.com](https://aistudio.google.com) |
218
+ | **Mistral** | ~1B tok/month | Codestral, Mistral Large | [console.mistral.ai](https://console.mistral.ai) |
219
+ | **xAI** | $25/mo credits | Grok 3, Grok 3 Mini | [console.x.ai](https://console.x.ai) |
220
+ | **Together** | $1 free credit | Llama 3.3 70B, DeepSeek R1 | [api.together.xyz](https://api.together.xyz) |
221
+ | **OpenRouter** | 50 req/day | 7 free models | [openrouter.ai](https://openrouter.ai) |
222
+
223
+ ### Paid Providers
224
+
225
+ | Provider | Models | Get a Key |
226
+ |----------|--------|-----------|
227
+ | **Anthropic** | Claude Opus 4.5, Sonnet 4.5, Haiku 3.5 | [console.anthropic.com](https://console.anthropic.com) |
228
+ | **OpenAI** | GPT-4.1, GPT-4o, o4-mini | [platform.openai.com](https://platform.openai.com) |
229
+ | **DeepSeek** | DeepSeek V3, DeepSeek R1 | [platform.deepseek.com](https://platform.deepseek.com) |
230
+
231
+ ### Adding a Provider
232
+
233
+ Inside Vibe Hacker, type:
234
+
235
+ ```
236
+ /addkey gsk_xxxxxxxxxxxx # Groq
237
+ /addkey csk-xxxxxxxxxxxx # Cerebras
238
+ /addkey AIzaxxxxxxxxxxxx # Gemini
239
+ /addkey mistral:xxxxxxxxxxxx # Mistral
240
+ /addkey xai-xxxxxxxxxxxx # xAI
241
+ /addkey sk-ant-xxxxxxxxxxxx # Anthropic
242
+ /addkey sk-xxxxxxxxxxxx # OpenAI
243
+ ```
244
+
245
+ Keys are auto-detected by their prefix and stored locally in `~/.vibehacker/config.json`.
246
+
247
+ ### Smart Rotation
248
+
249
+ When a provider hits a rate limit:
250
+
251
+ 1. Tries another model on the same provider
252
+ 2. Switches to the next healthy provider if all models fail
253
+ 3. Circuit breaker opens after 3 consecutive failures (30s cooldown)
254
+ 4. Providers with open circuit breakers are skipped automatically
255
+
256
+ This happens silently — you never see rate limit errors.
257
+
258
+ ---
259
+
260
+ ## Project Memory
261
+
262
+ Create a `VIBEHACKER.md` file in your project root to give the agent project-specific context:
263
+
264
+ ```markdown
265
+ # Project Context
266
+
267
+ This is a Node.js REST API using Express and PostgreSQL.
268
+
269
+ ## Conventions
270
+ - Use TypeScript strict mode
271
+ - All SQL queries must use parameterized statements
272
+ - Error responses follow RFC 7807
64
273
 
65
274
  ## Security
275
+ - All endpoints require JWT auth
276
+ - Rate limit: 100 req/min per IP
277
+ - Input validation with Joi on all POST/PUT
278
+ ```
279
+
280
+ Also supports `.vibehacker/context.md` and `.vibehacker/instructions.md`.
281
+
282
+ ---
283
+
284
+ ## Use Cases
285
+
286
+ ### Security Auditing
287
+ ```
288
+ Find all OWASP Top 10 vulnerabilities in this project
289
+ Check dependencies for known CVEs
290
+ Find hardcoded secrets in this repo
291
+ ```
292
+
293
+ ### Penetration Testing
294
+ ```
295
+ Generate a recon checklist for example.com
296
+ Review this firewall config for misconfigurations
297
+ Analyze this pcap for suspicious traffic
298
+ ```
299
+
300
+ ### Code Security
301
+ ```
302
+ Fix all SQL injection vulnerabilities in src/
303
+ Add input validation to every API endpoint
304
+ Review the auth flow for security issues
305
+ ```
306
+
307
+ ### DevSecOps
308
+ ```
309
+ Write a GitHub Actions workflow for SAST scanning
310
+ Create a secure Dockerfile for this app
311
+ Set up CSP headers for this Express server
312
+ ```
313
+
314
+ ### Learning
315
+ ```
316
+ Explain how buffer overflow attacks work
317
+ What is the difference between symmetric and asymmetric encryption?
318
+ Walk me through the TLS 1.3 handshake
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Architecture
324
+
325
+ ```
326
+ vibehacker/
327
+ ├── index.js Entry point
328
+ ├── install.sh One-line installer
329
+ └── src/
330
+ ├── app.js TUI (blessed), streaming, XML filter, render loop
331
+ ├── agent.js Agent loop, system prompt, context management
332
+ ├── api.js HTTP streaming, provider health, circuit breaker
333
+ ├── tools.js 10 tools, file state tracking, parallel grep
334
+ ├── providers.js 13 provider definitions, rotation logic
335
+ ├── approve.js Tool approval dialog
336
+ └── config.js Configuration loading and migration
337
+ ```
338
+
339
+ ### Technical Highlights
340
+
341
+ | Feature | Detail |
342
+ |---------|--------|
343
+ | Streaming | Real-time SSE with unified parser (OpenAI + Anthropic formats) |
344
+ | Tool Calling | XML tags in model output — works with any model, no function-calling API needed |
345
+ | Circuit Breaker | Provider health tracking, auto-failover after 3 failures, 30s cooldown |
346
+ | Context Trimming | 3-phase: strip thinking blocks, compress old tool results, drop middle messages |
347
+ | Parallel I/O | Grep runs 8 concurrent file reads with binary extension pre-filtering |
348
+ | Streaming Filter | Array-based XmlStreamFilter with 8KB buffer compaction |
349
+ | Rendering | Adaptive — 30fps during streaming, 60fps idle |
350
+ | Edit Journal | Last 50 edits tracked for `/undo` support |
351
+ | Prompt Cache | System prompt and project memory rebuilt only when cwd/mode changes |
352
+
353
+ ---
354
+
355
+ ## Configuration
356
+
357
+ Stored in `~/.vibehacker/config.json`:
358
+
359
+ | Option | Default | Description |
360
+ |--------|---------|-------------|
361
+ | `apiKey` | — | Primary API key |
362
+ | `baseURL` | OpenRouter | Primary API endpoint |
363
+ | `maxTokens` | 8192 | Max output tokens per response |
364
+ | `temperature` | 0.6 | Generation temperature (0-1) |
365
+ | `maxToolIterations` | 30 | Max tool calls per task |
366
+
367
+ ---
368
+
369
+ ## FAQ
370
+
371
+ **Is it really free?**
372
+ Yes. You get 50 requests/day with no setup. Add free keys from Groq, Cerebras, or Gemini for thousands more daily requests.
66
373
 
67
- This is a dual-use security tool. Only use on systems you own or have written authorization to test. By using this tool you acknowledge that you are solely responsible for your actions.
374
+ **Does it send my code to the cloud?**
375
+ Code is sent to your chosen AI provider for processing. Nothing is stored on Vibe Hacker servers. For full privacy, use a self-hosted model.
68
376
 
69
- ## Links
377
+ **Which models work best for Hunt mode?**
378
+ Llama 3.3 70B (Groq) and Qwen3 235B (Cerebras) handle tool calling best. Gemini 2.5 Flash offers 1M context for large codebases.
70
379
 
71
- - Website: [vibsecurity.com](https://vibsecurity.com)
72
- - Issues: [github.com/agentichacker/vibehacker/issues](https://github.com/agentichacker/vibehacker/issues)
73
- - Pricing: [vibsecurity.com/pricing](https://vibsecurity.com/pricing)
380
+ **Can I use OpenAI or Anthropic?**
381
+ Yes. `/addkey sk-your-key` for OpenAI, `/addkey sk-ant-your-key` for Anthropic.
382
+
383
+ **Windows support?**
384
+ Works via WSL or Git Bash. Native Windows terminal is experimental.
385
+
386
+ **Node.js version?**
387
+ 16 or higher. Recommend 22 LTS.
388
+
389
+ ---
390
+
391
+ ## Pro
392
+
393
+ **Vibe Hacker Pro** includes unlimited requests, priority model access, faster responses, and priority support.
394
+
395
+ Visit [vibsecurity.com](https://vibsecurity.com) or type `/pro` in the app.
396
+
397
+ ---
398
+
399
+ ## Contributing
400
+
401
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
402
+
403
+ ## Security
404
+
405
+ Report vulnerabilities per [SECURITY.md](SECURITY.md).
74
406
 
75
407
  ## License
76
408
 
77
- MIT — see [LICENSE](LICENSE)
409
+ [MIT](LICENSE)
410
+
411
+ ---
412
+
413
+ <p align="center">
414
+ Built by <a href="https://vibsecurity.com">Vibe Security</a>
415
+ </p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibehacker",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "Vibe Hacker — Terminal AI cybersecurity assistant. Free models, autonomous agent, multi-provider rotation.",
5
5
  "main": "index.js",
6
6
  "bin": {
package/src/app.js CHANGED
@@ -303,7 +303,6 @@ class HackerCLIApp {
303
303
  this.providers.add(key);
304
304
  this.providers.clearLimits();
305
305
  this._updateModeBar();
306
- this._pendingModelPick = true; // show model picker after welcome
307
306
  this._freshSetup = true; // skip silent key check — model fetch validates key
308
307
  }
309
308
  }
@@ -336,17 +335,11 @@ class HackerCLIApp {
336
335
  this._log('');
337
336
  this.screen.render();
338
337
 
339
- // After first-run setup, refresh models and show picker
340
- if (this._pendingModelPick) {
341
- this._pendingModelPick = false;
342
- this._refreshModelsAndPick();
343
- } else {
344
- // Always refresh models on startup so stale models don't cause 404s
345
- const cfg2 = require('./config');
346
- if (cfg2.hasKey()) {
347
- this._silentModelRefresh();
348
- this._checkTier();
349
- }
338
+ // Always silently refresh models on startup — no picker, no prompts
339
+ const cfg2 = require('./config');
340
+ if (cfg2.hasKey()) {
341
+ this._silentModelRefresh();
342
+ this._checkTier();
350
343
  }
351
344
 
352
345
  // Background update check — delayed 3s so it doesn't slow the first render
@@ -394,8 +387,15 @@ class HackerCLIApp {
394
387
  this._updateModeBar();
395
388
  });
396
389
 
397
- sc.key(['pageup'], () => { this.chat.scroll(-Math.floor(this.chat.height / 2)); sc.render(); });
398
- sc.key(['pagedown'], () => { this.chat.scroll( Math.floor(this.chat.height / 2)); sc.render(); });
390
+ // Smooth scrolling scroll by a few lines, not half-page jumps
391
+ const SCROLL_LINES = 3;
392
+ const PAGE_LINES = () => Math.max(3, Math.floor(this.chat.height / 2));
393
+ sc.key(['pageup'], () => { this.chat.scroll(-PAGE_LINES()); sc.render(); });
394
+ sc.key(['pagedown'], () => { this.chat.scroll( PAGE_LINES()); sc.render(); });
395
+
396
+ // Mouse wheel scrolling — smooth 3-line increments
397
+ this.chat.on('wheelup', () => { this.chat.scroll(-SCROLL_LINES); this.screen.render(); });
398
+ this.chat.on('wheeldown', () => { this.chat.scroll( SCROLL_LINES); this.screen.render(); });
399
399
 
400
400
  // ── Manual keyboard input (bypasses inputOnFocus raw capture) ──
401
401
  sc.on('keypress', (ch, key) => {
@@ -603,14 +603,15 @@ class HackerCLIApp {
603
603
  const modelName = model ? 'Vibe Model' : '—';
604
604
  const mode = MODES[this.modeIndex];
605
605
 
606
- // Tier badge with remaining
606
+ // Tier badge with remaining requests
607
607
  let tierBadge = '';
608
608
  if (this._tier === 'pro') {
609
609
  tierBadge = '{#ffaa00-fg}{bold}PRO{/bold}{/#ffaa00-fg}';
610
- } else if (this._tier === 'free' && this._remaining !== null) {
611
- const r = this._remaining;
612
- const color = r > 50 ? '#00cc44' : r > 15 ? '#ffaa00' : '#ff4444';
613
- tierBadge = `{#00aa44-fg}FREE{/#00aa44-fg} {${color}-fg}${r}{/${color}-fg}`;
610
+ } else {
611
+ const limit = this._dailyLimit || 50;
612
+ const r = this._remaining !== null && this._remaining !== undefined ? this._remaining : limit;
613
+ const color = r > 25 ? '#00cc44' : r > 10 ? '#ffaa00' : r > 0 ? '#ff6600' : '#ff4444';
614
+ tierBadge = `{${color}-fg}${r}/${limit}{/${color}-fg}`;
614
615
  }
615
616
 
616
617
  return (
@@ -1189,38 +1190,12 @@ class HackerCLIApp {
1189
1190
  }
1190
1191
 
1191
1192
  case 'login': case 'auth': {
1192
- // Open vibsecurity.com/login in browser, prompt user to paste their API key
1193
- const { openLoginPage, LOGIN_URL } = require('./auth');
1193
+ // Redirect to /addkey no separate login flow
1194
1194
  this._log('');
1195
- this._log('{#00aa44-fg} Opening browser…{/#00aa44-fg}');
1196
- this._log(` {#444444-fg}If it doesn't open: ${esc(LOGIN_URL)}{/#444444-fg}`);
1195
+ this._log('{#444444-fg} Use {#00ff88-fg}/addkey <paste-key>{/#00ff88-fg} to add a provider key.{/#444444-fg}');
1196
+ this._log('{#444444-fg} Get a free key: {cyan-fg}vibsecurity.com{/cyan-fg}{/#444444-fg}');
1197
1197
  this._log('');
1198
1198
  this.screen.render();
1199
- openLoginPage().catch(() => {});
1200
- this._promptInput('Paste your API key (vh_… / sk-or-v1-… / gsk_…):', (k) => {
1201
- k = (k || '').trim();
1202
- if (!k) {
1203
- this._log('{red-fg} ✗ No key entered.{/red-fg}');
1204
- this.screen.render();
1205
- return;
1206
- }
1207
- try {
1208
- const type = this.providers.add(k);
1209
- this.providers.clearLimits();
1210
- this._dailyLimitHit = false;
1211
- this._updateModeBar();
1212
- const pname = (PROVIDERS[type] || {}).name || type;
1213
- this._log('');
1214
- this._log(`{green-fg}{bold} ✓ ${esc(pname)} key saved.{/bold}{/green-fg}`);
1215
- this._log('');
1216
- this.screen.render();
1217
- this._checkTier();
1218
- this._refreshModelsAndPick();
1219
- } catch (err) {
1220
- this._log(`{red-fg} ✗ ${esc(err.message || 'Invalid key')}{/red-fg}`);
1221
- this.screen.render();
1222
- }
1223
- });
1224
1199
  break;
1225
1200
  }
1226
1201
 
@@ -1322,8 +1297,8 @@ class HackerCLIApp {
1322
1297
  return;
1323
1298
  }
1324
1299
  doAdd(newKey);
1325
- // After adding key, refresh models from API then let user pick
1326
- this._refreshModelsAndPick();
1300
+ // Silently refresh models auto-rotation handles the rest
1301
+ this._silentModelRefresh();
1327
1302
  return;
1328
1303
  }
1329
1304
 
@@ -1476,7 +1451,7 @@ class HackerCLIApp {
1476
1451
 
1477
1452
  // Usage
1478
1453
  if (this._remaining !== null && this._remaining !== undefined) {
1479
- const limit = this._dailyLimit || 100;
1454
+ const limit = this._dailyLimit || 50;
1480
1455
  const used = limit - this._remaining;
1481
1456
  const pct = Math.round((used / limit) * 100);
1482
1457
  const barW = 20;
@@ -1893,7 +1868,7 @@ class HackerCLIApp {
1893
1868
  this._log('{#005500-fg} ┌──────────────────────────────────────────────────────┐{/#005500-fg}');
1894
1869
  this._log(`{#005500-fg} │{/#005500-fg} {yellow-fg}{bold}⚠ Daily limit reached{/bold}{/yellow-fg} {#005500-fg}│{/#005500-fg}`);
1895
1870
  this._log('{#005500-fg} │{/#005500-fg} {#005500-fg}│{/#005500-fg}');
1896
- this._log("{#005500-fg} │{/#005500-fg} {#888888-fg}You've used all 100 free requests for today.{/#888888-fg} {#005500-fg}│{/#005500-fg}");
1871
+ this._log("{#005500-fg} │{/#005500-fg} {#888888-fg}You've used all 50 free requests for today.{/#888888-fg} {#005500-fg}│{/#005500-fg}");
1897
1872
  this._log('{#005500-fg} │{/#005500-fg} {#888888-fg}Resets in 24 hours or upgrade for unlimited.{/#888888-fg} {#005500-fg}│{/#005500-fg}');
1898
1873
  this._log('{#005500-fg} │{/#005500-fg} {#005500-fg}│{/#005500-fg}');
1899
1874
  this._log('{#005500-fg} │{/#005500-fg} {#00ff88-fg}{bold}Go Pro → vibsecurity.com{/bold}{/#00ff88-fg} {#005500-fg}│{/#005500-fg}');
@@ -2014,7 +1989,7 @@ class HackerCLIApp {
2014
1989
  this._refreshHeader();
2015
1990
  this._log('');
2016
1991
  this._log('{red-fg}{bold} ⚠ Daily request limit reached{/bold}{/red-fg}');
2017
- this._log(`{#888888-fg} Free tier: ${this._dailyLimit || 100} requests/day{/#888888-fg}`);
1992
+ this._log(`{#888888-fg} Free tier: ${this._dailyLimit || 50} requests/day{/#888888-fg}`);
2018
1993
  this._log('');
2019
1994
  this._log('{#00ff88-fg} Go Pro for unlimited requests:{/#00ff88-fg}');
2020
1995
  this._log(' {cyan-fg}{bold}https://vibsecurity.com{/bold}{/cyan-fg}');
@@ -2154,29 +2129,7 @@ class HackerCLIApp {
2154
2129
  });
2155
2130
  }
2156
2131
 
2157
- // ── Refresh models then show picker ────────────────────────────────────────
2158
-
2159
- async _refreshModelsAndPick() {
2160
- this._log('{#444444-fg}[fetching available free models…]{/#444444-fg}');
2161
- this.screen.render();
2162
- try {
2163
- const cfg = require('./config');
2164
- const count = await this.models.refresh(cfg.apiKey, cfg.baseURL);
2165
- if (count > 0) {
2166
- this._log(`{green-fg}[found ${count} free models — choose your default:]{/green-fg}`);
2167
- this._updateModeBar();
2168
- } else {
2169
- this._log('{#444444-fg}[using built-in model list]{/#444444-fg}');
2170
- }
2171
- } catch (err) {
2172
- this._log(`{yellow-fg}[could not fetch models: ${esc(err.message)} — using defaults]{/yellow-fg}`);
2173
- }
2174
- this.screen.render();
2175
-
2176
- // Small delay so user sees the log, then open picker
2177
- await new Promise(r => setTimeout(r, 300));
2178
- await this._showModelPicker();
2179
- }
2132
+ // (_refreshModelsAndPick removed models refresh silently, auto-rotation handles switching)
2180
2133
 
2181
2134
  // ── Exit ──────────────────────────────────────────────────────────────────
2182
2135