edsger 0.27.5 → 0.27.6

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.
@@ -9,7 +9,7 @@
9
9
  import { hostname } from 'os';
10
10
  import { callMcpEndpoint } from '../api/mcp-client.js';
11
11
  import { getVersion } from '../constants.js';
12
- import { logInfo, logWarning } from '../utils/logger.js';
12
+ import { logInfo, logWarning, initLogSync, stopLogSync } from '../utils/logger.js';
13
13
  let currentSessionId = null;
14
14
  let heartbeatTimer;
15
15
  let _sessionStatus = 'running';
@@ -42,6 +42,8 @@ export async function registerSession() {
42
42
  // Session registration is best-effort, don't fail
43
43
  logWarning('Could not register CLI session with server');
44
44
  }
45
+ // Start log sync after session registration
46
+ initLogSync(sessionId);
45
47
  return sessionId;
46
48
  }
47
49
  /**
@@ -94,6 +96,8 @@ export async function deregisterSession() {
94
96
  if (!currentSessionId)
95
97
  return;
96
98
  stopHeartbeat();
99
+ // Flush remaining logs before deregistering
100
+ await stopLogSync();
97
101
  try {
98
102
  await callMcpEndpoint('cli_sessions/deregister', {
99
103
  session_id: currentSessionId,
@@ -11,6 +11,18 @@ export declare const colors: {
11
11
  gray: string;
12
12
  };
13
13
  export declare const colorize: (text: string, color: keyof typeof colors) => string;
14
+ /**
15
+ * Flush buffered logs to the server. Best-effort, failures are silent.
16
+ */
17
+ export declare function flushLogs(): Promise<void>;
18
+ /**
19
+ * Start log sync for a CLI session. Call after session registration.
20
+ */
21
+ export declare function initLogSync(sessionId: string): void;
22
+ /**
23
+ * Stop log sync and flush remaining logs. Call before session deregistration.
24
+ */
25
+ export declare function stopLogSync(): Promise<void>;
14
26
  export declare const logInfo: (message: string) => void;
15
27
  export declare const logSuccess: (message: string) => void;
16
28
  export declare const logWarning: (message: string) => void;
@@ -1,4 +1,5 @@
1
1
  import { getVersion } from '../constants.js';
2
+ import { callMcpEndpoint } from '../api/mcp-client.js';
2
3
  export const colors = {
3
4
  reset: '\x1b[0m',
4
5
  bright: '\x1b[1m',
@@ -20,22 +21,84 @@ const versionPrefix = () => {
20
21
  const v = getVersion();
21
22
  return `[v${v}]`;
22
23
  };
24
+ let _logBuffer = [];
25
+ let _logSyncSessionId = null;
26
+ let _logFlushTimer;
27
+ /** How often to flush logs to server (5 seconds) */
28
+ const LOG_FLUSH_INTERVAL = 5_000;
29
+ /** Max buffer size before forcing a flush */
30
+ const LOG_BUFFER_MAX = 50;
31
+ function bufferLog(level, message) {
32
+ if (!_logSyncSessionId)
33
+ return;
34
+ _logBuffer.push({ level, message, created_at: new Date().toISOString() });
35
+ if (_logBuffer.length >= LOG_BUFFER_MAX) {
36
+ flushLogs().catch(() => { });
37
+ }
38
+ }
39
+ /**
40
+ * Flush buffered logs to the server. Best-effort, failures are silent.
41
+ */
42
+ export async function flushLogs() {
43
+ if (!_logSyncSessionId || _logBuffer.length === 0)
44
+ return;
45
+ const batch = _logBuffer.splice(0);
46
+ try {
47
+ await callMcpEndpoint('cli_logs/batch', {
48
+ session_id: _logSyncSessionId,
49
+ logs: batch,
50
+ });
51
+ }
52
+ catch {
53
+ // Best-effort: put logs back if send fails (drop if buffer is huge)
54
+ if (_logBuffer.length < 500) {
55
+ _logBuffer.unshift(...batch);
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Start log sync for a CLI session. Call after session registration.
61
+ */
62
+ export function initLogSync(sessionId) {
63
+ _logSyncSessionId = sessionId;
64
+ _logBuffer = [];
65
+ _logFlushTimer = setInterval(() => {
66
+ flushLogs().catch(() => { });
67
+ }, LOG_FLUSH_INTERVAL);
68
+ }
69
+ /**
70
+ * Stop log sync and flush remaining logs. Call before session deregistration.
71
+ */
72
+ export async function stopLogSync() {
73
+ if (_logFlushTimer) {
74
+ clearInterval(_logFlushTimer);
75
+ _logFlushTimer = undefined;
76
+ }
77
+ await flushLogs();
78
+ _logSyncSessionId = null;
79
+ }
80
+ // ---- Logger Functions ----
23
81
  export const logInfo = (message) => {
24
82
  console.log(colorize(`${versionPrefix()} ℹ ${message}`, 'blue'));
83
+ bufferLog('info', message);
25
84
  };
26
85
  export const logSuccess = (message) => {
27
86
  console.log(colorize(`${versionPrefix()} ✓ ${message}`, 'green'));
87
+ bufferLog('success', message);
28
88
  };
29
89
  export const logWarning = (message) => {
30
90
  console.log(colorize(`${versionPrefix()} ⚠ ${message}`, 'yellow'));
91
+ bufferLog('warning', message);
31
92
  };
32
93
  export const logError = (message) => {
33
94
  console.error(colorize(`${versionPrefix()} ✗ ${message}`, 'red'));
95
+ bufferLog('error', message);
34
96
  };
35
97
  export const logProgress = (current, total, file) => {
36
98
  const percentage = Math.round((current / total) * 100);
37
99
  const progress = `[${current}/${total}] ${percentage}%`;
38
100
  console.log(colorize(`${progress} Reviewing ${file}`, 'gray'));
101
+ bufferLog('info', `${progress} Reviewing ${file}`);
39
102
  };
40
103
  export const logResults = (results, verbose = false) => {
41
104
  const okCount = results.filter(r => r.status === 'OK').length;
@@ -57,4 +120,5 @@ export const logResults = (results, verbose = false) => {
57
120
  console.log(colorize(` ⚠ Warnings: ${warnCount}`, 'yellow'));
58
121
  console.log(colorize(` ✗ Blocked: ${blockCount}`, 'red'));
59
122
  console.log(colorize(` Total: ${results.length} files reviewed`, 'gray'));
123
+ bufferLog('info', `Review complete: ${okCount} passed, ${warnCount} warnings, ${blockCount} blocked (${results.length} files)`);
60
124
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edsger",
3
- "version": "0.27.5",
3
+ "version": "0.27.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "edsger": "dist/index.js"