dankgrinder 7.68.0 → 7.71.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/lib/dashboard.js CHANGED
@@ -252,12 +252,18 @@ function renderDashboard(ctx) {
252
252
  rows.push(mkRow(`${modeTag} ${D}P=pause R=resume S=status Q=quit${_}`));
253
253
  rows.push(border('╚'));
254
254
 
255
- // ── Flush: write all rows, each clears its line first ─────────
256
- // This is how top/htop work — overwrite each row in place.
257
- // No full-screen clear, no cursor tricks. Simple and reliable.
255
+ // ── Flush: overwrite rows from line 1, then blank remaining screen ──
256
+ const rowsOnScreen = process.stdout.rows || 24;
258
257
  for (const row of rows) {
259
258
  process.stdout.write(`${_c.clearLine}\r${row}\n`);
260
259
  }
260
+ // Fill remaining screen lines with blanks so old startup logs don't bleed through
261
+ const extra = rowsOnScreen - rows.length;
262
+ for (let i = 0; i < extra; i++) {
263
+ process.stdout.write(`${_c.clearLine}\r${' '.repeat(tw)}\n`);
264
+ }
265
+ // Move cursor to end so terminal doesn't scroll on next \r write
266
+ process.stdout.write(`\x1b[${rows.length};1H`);
261
267
 
262
268
  return rows.length;
263
269
  }
package/lib/grinder.js CHANGED
@@ -133,10 +133,25 @@ const CLUSTER_PREFIX = 'dkg:cluster:';
133
133
  function initRedis() {
134
134
  if (!redis && REDIS_URL) {
135
135
  try {
136
- redis = new Redis(REDIS_URL, { maxRetriesPerRequest: null, lazyConnect: true });
137
- redis.connect().catch(() => {});
136
+ redis = new Redis(REDIS_URL, {
137
+ maxRetriesPerRequest: 3,
138
+ retryStrategy: (times) => times > 5 ? null : Math.min(times * 500, 3000),
139
+ lazyConnect: true,
140
+ });
141
+ redis.connect().catch((e) => {
142
+ // Only warn once — don't spam on persistent connection failures
143
+ if (!redis || redis.status === 'wait') {
144
+ console.warn(`[Redis] connection failed: ${e.message} — continuing without Redis`);
145
+ }
146
+ });
147
+ redis.on('error', (e) => {
148
+ // Suppress common transient errors from spamming stderr
149
+ const msg = e?.message || '';
150
+ if (msg.includes('ETIMEDOUT') || msg.includes('ECONNRESET') || msg.includes('ENOTFOUND') || msg.includes('connect')) return;
151
+ console.error(`[Redis] error: ${msg}`);
152
+ });
138
153
  } catch (e) {
139
- console.error('Redis connection failed', e);
154
+ // Redis optional continue without it
140
155
  }
141
156
  }
142
157
  }
@@ -2872,7 +2887,6 @@ async function start(apiKey, apiUrl, opts = {}) {
2872
2887
  await new Promise((r) => setTimeout(r, 10000));
2873
2888
  data = await fetchConfig(4, 2000, fetchOpts);
2874
2889
  }
2875
-
2876
2890
  if (data && data.error) {
2877
2891
  log('error', `${data.error}`);
2878
2892
  return;
@@ -3346,7 +3360,6 @@ async function start(apiKey, apiUrl, opts = {}) {
3346
3360
  console.log('');
3347
3361
 
3348
3362
  console.log(` ${rgb(139, 92, 246)}${c.bold}>>>${c.reset} ${gradientText('Starting grind loops...', [139, 92, 246], [52, 211, 153])}`);
3349
- console.log('');
3350
3363
 
3351
3364
  // Phase 3: Start all grind loops (only for valid workers)
3352
3365
  for (const w of activeWorkers) {
@@ -3356,10 +3369,12 @@ async function start(apiKey, apiUrl, opts = {}) {
3356
3369
  startTime = Date.now();
3357
3370
  dashboardStarted = true;
3358
3371
  setDashboardActive(true);
3372
+
3373
+ // Clear screen and position cursor at top-left before dashboard takes over
3374
+ process.stdout.write('\x1b[2J\x1b[H');
3375
+
3359
3376
  // Setup keyboard shortcuts
3360
3377
  setupKeyboardShortcuts();
3361
- // Cursor hide to reduce visual noise during renders
3362
- process.stdout.write(c.hide);
3363
3378
 
3364
3379
  // Re-render on terminal resize so layout adapts to window size
3365
3380
  process.stdout.on('resize', () => {
package/lib/rawLogger.js CHANGED
@@ -54,7 +54,10 @@ async function init(redisUrl) {
54
54
  redisReady = true;
55
55
  console.log('[rawLogger] Redis connected');
56
56
  redis.on('error', (e) => {
57
- console.error(`[rawLogger] Redis error: ${e.message}`);
57
+ // Suppress common transient network errors from spamming stderr
58
+ const msg = e?.message || '';
59
+ if (msg.includes('ETIMEDOUT') || msg.includes('ECONNRESET') || msg.includes('ENOTFOUND') || msg.includes('read') || msg.includes('connect')) return;
60
+ console.error(`[rawLogger] Redis error: ${msg}`);
58
61
  redisReady = false;
59
62
  });
60
63
  redis.on('close', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dankgrinder",
3
- "version": "7.68.0",
3
+ "version": "7.71.0",
4
4
  "description": "Dank Memer automation engine — grind coins while you sleep",
5
5
  "bin": {
6
6
  "dankgrinder": "bin/dankgrinder.js"