dankgrinder 8.87.0 → 8.89.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.
Files changed (2) hide show
  1. package/lib/ui.js +50 -83
  2. package/package.json +1 -1
package/lib/ui.js CHANGED
@@ -134,16 +134,6 @@ function render() {
134
134
 
135
135
  let out = '';
136
136
 
137
- // Banner
138
- const titleStr = figlet.textSync('DANK GRINDER', { font: 'ANSI Shadow' });
139
- out += chalk.bold(applyGradient(titleStr));
140
- out += chalk.bold.magenta(` v${_version} — ${getLoader()} Running... \n\n`);
141
-
142
- const wCols = { num: 4, name: 18, bal: 14, ls: 6, lv: 5 };
143
- const overhead = 19 + wCols.num + wCols.name + wCols.bal + wCols.ls + wCols.lv;
144
- const logW = Math.max(10, C - overhead);
145
- const actualC = logW + overhead;
146
-
147
137
  const sorted = [..._workers].sort((a, b) => {
148
138
  if (!a.channel !== !b.channel) return a.channel ? -1 : 1;
149
139
  return (b.stats.commands || 0) - (a.stats.commands || 0);
@@ -157,44 +147,30 @@ function render() {
157
147
  if (w.channel && !w.paused && !w.dashboardPaused) onlineCount++;
158
148
  }
159
149
 
160
- // BIG STATS DASHBOARD
161
- const totC = totalCoins > 0 ? '+' + formatBal(totalCoins) : '+0';
162
-
163
- out += chalk.cyan('' + '─'.repeat(actualC - 2) + '╮\n');
164
- out += chalk.cyan('│') + ' ' + chalk.bold('ACCOUNTS: ') + String(_workers.length).padEnd(5) +
165
- chalk.bold('ONLINE: ') + String(onlineCount).padEnd(5) +
166
- chalk.bold('UPTIME: ') + fmtUptime().padEnd(10) + ' '.repeat(Math.max(0, actualC - 48)) + chalk.cyan('│\n');
150
+ // 1. MODERN BRANDING (Vercel / Claude CLI Style)
151
+ // No big flashy ASCII, just a clean sleek badge
152
+ out += '\n ' + chalk.bgBlack.white.bold(' DANK GRINDER ') + chalk.gray(' v' + _version) +
153
+ chalk.dim(' ') + chalk.cyan('' + getLoader() + ' Running') + '\n\n';
154
+
155
+ // 2. MINIMALIST STATS
156
+ const profStr = totalCoins > 0 ? '+' + formatBal(totalCoins) : '0';
167
157
 
168
- const balStr = ' ' + formatBal(totalBal);
169
- const balPadding = Math.max(0, 16 - balStr.length);
170
- const profStr = totC;
171
- const graph = getSparkline();
158
+ out += ' ' + chalk.cyan('◆') + chalk.bold(' ONLINE ') + chalk.white(onlineCount + ' / ' + _workers.length) + '\n';
159
+ out += ' ' + chalk.blue('◆') + chalk.bold(' UPTIME ') + chalk.white(fmtUptime()) + '\n';
160
+ out += ' ' + chalk.green('◆') + chalk.bold(' BALANCE ') + chalk.white('⏣ ' + formatBal(totalBal)) + chalk.gray(' (profit: ' + profStr + ')') + '\n';
172
161
 
173
- out += chalk.cyan('│') + ' ' + chalk.bold.green('BALANCE: ') + chalk.bold.greenBright(balStr) + ' '.repeat(balPadding) +
174
- chalk.bold.yellow('PROFIT: ') + chalk.bold.yellowBright(profStr).padEnd(12) +
175
- chalk.dim('TREND: [') + graph + chalk.dim(']') + ' '.repeat(Math.max(0, actualC - 70)) + chalk.cyan('│\n');
176
- out += chalk.cyan('╰' + '─'.repeat(actualC - 2) + '╯\n');
162
+ // Divider
163
+ const divWidth = Math.min(C - 4, 100);
164
+ out += '\n ' + chalk.dim(''.repeat(divWidth)) + '\n\n';
165
+
166
+ // 3. TABLE DATA (Clean spacing, dimmed headers)
167
+ const wCols = { num: 4, name: 20, bal: 12, ls: 6, lv: 5 };
168
+ const overhead = 2 + wCols.num + 1 + wCols.name + 1 + wCols.bal + 1 + wCols.ls + 1 + wCols.lv + 1;
169
+ const logW = Math.max(15, C - overhead - 4);
177
170
 
178
- // Accounts Table
179
- out += '╭' + '─'.repeat(wCols.num + 2) + '┬'
180
- + '─'.repeat(wCols.name + 2) + '┬'
181
- + '─'.repeat(wCols.bal + 2) + '┬'
182
- + '─'.repeat(wCols.ls + 2) + '┬'
183
- + '─'.repeat(wCols.lv + 2) + '┬'
184
- + '─'.repeat(logW + 2) + '╮\n';
185
-
186
- out += makeRow(
187
- chalk.bold('#'), chalk.bold('ACCOUNT'), chalk.bold('BAL'),
188
- chalk.bold('LS'), chalk.bold('LV'), chalk.bold('LOGS'),
189
- wCols, logW
190
- ) + '\n';
171
+ const headRow = ` ${chalk.dim(pad('ID', wCols.num))} ${chalk.dim(pad('ACCOUNT', wCols.name))} ${chalk.dim(pad('BAL', wCols.bal))} ${chalk.dim(pad('LIFE', wCols.ls))} ${chalk.dim(pad('LVL', wCols.lv))} ${chalk.dim('PROCESS')}`;
191
172
 
192
- out += '├' + ''.repeat(wCols.num + 2) + '┼'
193
- + '─'.repeat(wCols.name + 2) + '┼'
194
- + '─'.repeat(wCols.bal + 2) + '┼'
195
- + '─'.repeat(wCols.ls + 2) + '┼'
196
- + '─'.repeat(wCols.lv + 2) + '┼'
197
- + '─'.repeat(logW + 2) + '┤\n';
173
+ out += headRow + '\n\n';
198
174
 
199
175
  for (let i = 0; i < sorted.length; i++) {
200
176
  const w = sorted[i];
@@ -204,71 +180,62 @@ function render() {
204
180
  if (w.globalCooldownUntil && Date.now() < w.globalCooldownUntil) {
205
181
  const s = Math.ceil((w.globalCooldownUntil - Date.now()) / 1000);
206
182
  logText = s > 60 ? `cd ${Math.ceil(s/60)}m` : `cd ${s}s`;
207
- activity = chalk.yellow(getSpinner());
183
+ activity = chalk.yellow('⏸');
208
184
  } else if (w.paused || w.dashboardPaused) {
209
185
  logText = 'paused';
186
+ activity = chalk.dim('⏸');
210
187
  } else if (w.channel) {
211
- activity = chalk.cyan(getSpinner());
188
+ activity = chalk.cyan('▶');
212
189
  } else {
213
- activity = chalk.gray(getLoader());
190
+ activity = chalk.gray('◎');
214
191
  }
215
192
 
216
- const numStr = trunc(String(i + 1), wCols.num);
193
+ const numStr = chalk.dim(String(i + 1).padStart(2, '0'));
217
194
  const dot = getDot(w);
218
195
 
219
- const nameRaw = trunc(w.username || 'Worker ' + (i+1), wCols.name - 2);
220
- const nameStr = dot.color(dot.dot) + ' ' + getAccountColor(nameRaw)(chalk.bold(nameRaw));
196
+ const nameRaw = trunc(w.username || 'Worker ' + (i+1), wCols.name - 3);
197
+ const nameStr = dot.color(dot.dot) + ' ' + chalk.whiteBright(nameRaw);
221
198
 
222
199
  const bVal = w.stats.balance !== undefined ? formatBal(w.stats.balance) : '—';
223
- const balRaw = trunc(bVal === '—' ? '—' : '⏣' + bVal, wCols.bal);
224
- const balStr = balRaw === '—' ? chalk.dim('—') : chalk.bold.green(balRaw);
200
+ const balRaw = trunc(bVal === '—' ? '—' : bVal, wCols.bal - 1);
201
+ const balStr = balRaw === '—' ? chalk.dim('—') : chalk.greenBright(balRaw);
225
202
 
226
- // Exact unicode block character, NOT an emoji
227
- let lsRaw = '—';
228
- let lsStr = chalk.dim('—');
203
+ let lsStr = chalk.dim('-');
229
204
  if (w._lifesavers !== undefined) {
230
205
  let lsCount = w._lifesavers;
231
- let lsEmoji = '█'; // Solid code block character!
232
- let lsColor = chalk.bold.red;
233
-
234
- if (lsCount >= 5) { lsColor = chalk.bold.green; }
235
- else if (lsCount >= 3) { lsColor = chalk.bold.yellow; }
236
-
237
- lsRaw = trunc(`${lsEmoji} ${lsCount}`, wCols.ls);
238
- lsStr = lsColor(lsRaw);
206
+ let lsColor = chalk.red;
207
+ if (lsCount >= 5) lsColor = chalk.green;
208
+ else if (lsCount >= 3) lsColor = chalk.yellow;
209
+ lsStr = lsColor(lsCount);
239
210
  }
240
211
 
241
- const lvRaw = trunc(w._level !== undefined ? String(w._level) : '', wCols.lv);
242
- const lvStr = chalk.bold.magenta(lvRaw);
212
+ const lvStr = w._level !== undefined ? chalk.magenta(w._level) : chalk.dim('-');
213
+ const logStr = activity + ' ' + chalk.dim(trunc(logText, logW - 2));
243
214
 
244
- const logRaw = trunc(logText, logW - 2);
245
- const logStr = activity + ' ' + chalk.dim.bold(logRaw);
246
-
247
- out += makeRow(numStr, nameStr, balStr, lsStr, lvStr, logStr, wCols, logW) + '\n';
215
+ out += ` ${pad(numStr, wCols.num)} ${pad(nameStr, wCols.name)} ${pad(balStr, wCols.bal)} ${pad(lsStr, wCols.ls)} ${pad(lvStr, wCols.lv)} ${logStr}\n`;
248
216
  }
249
217
 
250
218
  if (sorted.length === 0) {
251
- out += makeRow('—', 'No Accounts', '—', '—', '—', 'Waiting...', wCols, logW) + '\n';
219
+ out += ` ${chalk.dim('No accounts configured...')}\n`;
252
220
  }
253
-
254
- out += '╰' + '─'.repeat(wCols.num + 2) + '┴'
255
- + '─'.repeat(wCols.name + 2) + '┴'
256
- + '─'.repeat(wCols.bal + 2) + '┴'
257
- + '─'.repeat(wCols.ls + 2) + '┴'
258
- + '─'.repeat(wCols.lv + 2) + '┴'
259
- + '─'.repeat(logW + 2) + '╯\n\n';
260
221
 
261
- out += chalk.bold.cyan(' 📻 LATEST EVENTS') + '\n';
262
- if (_events.length === 0) out += chalk.dim(' Quiet here...\n');
263
- _events.forEach(ev => { out += ` ${chalk.dim(`[${ev.ts}]`)} ${ev.icon} ${ev.msg}\n`; });
222
+ out += '\n ' + chalk.dim('─'.repeat(divWidth)) + '\n\n';
223
+
224
+ // 4. ACTIVITY STREAM
225
+ out += chalk.gray(' ACTIVITY') + '\n';
226
+ if (_events.length === 0) {
227
+ out += chalk.dim(' No recent events.\n');
228
+ } else {
229
+ _events.forEach(ev => {
230
+ out += ` ${chalk.dim(ev.ts)} ${ev.icon} ${chalk.white(ev.msg)}\n`;
231
+ });
232
+ }
264
233
 
265
- // Fixing the blank space spam by ensuring exactly no trailing newlines and NO raw buffer resets
266
234
  logUpdate(out.trimEnd());
267
235
  }
268
-
269
236
  function start() {}
270
237
  function draw() { render(); }
271
- function setLive(val) { _live = val; if (val) render(); }
238
+ function setLive(val) { _live = val; if (val) { process.stdout.write('\x1b[2J\x1b[3J\x1b[H'); render(); } }
272
239
  function setPhase(phase) {}
273
240
  function startRefresh() { setInterval(() => { if(_live){ const tot = _workers.reduce((a,w)=>a+(w.stats.coins||0),0); _coinHistory.shift(); _coinHistory.push(tot); } }, 5000);
274
241
  if (!_refreshTimer) _refreshTimer = setInterval(() => { if (_live) render(); }, 80); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dankgrinder",
3
- "version": "8.87.0",
3
+ "version": "8.89.0",
4
4
  "description": "Dank Memer automation engine — grind coins while you sleep",
5
5
  "bin": {
6
6
  "dankgrinder": "bin/dankgrinder.js"