@juspay/neurolink 6.2.0 → 6.2.1

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/CHANGELOG.md CHANGED
@@ -1,9 +1,15 @@
1
- # [6.2.0](https://github.com/juspay/neurolink/compare/v6.1.0...v6.2.0) (2025-07-30)
1
+ ## [6.2.1](https://github.com/juspay/neurolink/compare/v6.2.0...v6.2.1) (2025-07-31)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **logging:** consolidate MCP logging and add debug flag control ([ea0132d](https://github.com/juspay/neurolink/commit/ea0132dd954966cb42238dc3736f6cee9cc7b18d))
2
7
 
8
+ # [6.2.0](https://github.com/juspay/neurolink/compare/v6.1.0...v6.2.0) (2025-07-30)
3
9
 
4
10
  ### Features
5
11
 
6
- * systematic dead code elimination across entire codebase ([571060a](https://github.com/juspay/neurolink/commit/571060a6146dc13e486da22610122d599420fcb2))
12
+ - systematic dead code elimination across entire codebase ([571060a](https://github.com/juspay/neurolink/commit/571060a6146dc13e486da22610122d599420fcb2))
7
13
 
8
14
  # [6.1.0](https://github.com/juspay/neurolink/compare/v6.0.0...v6.1.0) (2025-07-24)
9
15
 
@@ -6,6 +6,7 @@ import { tool } from "ai";
6
6
  import { z } from "zod";
7
7
  import * as fs from "fs";
8
8
  import * as path from "path";
9
+ import { logger } from "../utils/logger.js";
9
10
  /**
10
11
  * Direct tool definitions that work immediately with Gemini/AI SDK
11
12
  * These bypass MCP complexity and provide reliable agent functionality
@@ -365,23 +366,23 @@ export function validateToolStructure() {
365
366
  try {
366
367
  for (const [name, tool] of Object.entries(directAgentTools)) {
367
368
  if (!tool.description || typeof tool.description !== "string") {
368
- console.error(`❌ Tool ${name} missing description`);
369
+ logger.error(`❌ Tool ${name} missing description`);
369
370
  return false;
370
371
  }
371
372
  if (!tool.parameters) {
372
- console.error(`❌ Tool ${name} missing parameters`);
373
+ logger.error(`❌ Tool ${name} missing parameters`);
373
374
  return false;
374
375
  }
375
376
  if (!tool.execute || typeof tool.execute !== "function") {
376
- console.error(`❌ Tool ${name} missing execute function`);
377
+ logger.error(`❌ Tool ${name} missing execute function`);
377
378
  return false;
378
379
  }
379
380
  }
380
- console.log("✅ All tools have valid structure");
381
+ logger.info("✅ All tools have valid structure");
381
382
  return true;
382
383
  }
383
384
  catch (error) {
384
- console.error("❌ Tool validation failed:", error);
385
+ logger.error("❌ Tool validation failed:", error);
385
386
  return false;
386
387
  }
387
388
  }
@@ -5,6 +5,7 @@
5
5
  import { promises as fs } from "fs";
6
6
  import path from "path";
7
7
  import crypto from "crypto";
8
+ import { logger } from "../utils/logger.js";
8
9
  const { readFile, writeFile, readdir, mkdir, unlink, access } = fs;
9
10
  /**
10
11
  * Enhanced Config Manager with automatic backup/restore capabilities
@@ -32,7 +33,7 @@ export class NeuroLinkConfigManager {
32
33
  if (createBackup) {
33
34
  await this.createBackup(reason);
34
35
  if (!silent) {
35
- console.log("💾 Backup created before config update");
36
+ logger.info("💾 Backup created before config update");
36
37
  }
37
38
  }
38
39
  const existing = await this.loadConfig();
@@ -50,7 +51,7 @@ export class NeuroLinkConfigManager {
50
51
  try {
51
52
  await this.persistConfig(this.config);
52
53
  if (!silent) {
53
- console.log("✅ Configuration updated successfully");
54
+ logger.info("✅ Configuration updated successfully");
54
55
  }
55
56
  }
56
57
  catch (error) {
@@ -58,7 +59,7 @@ export class NeuroLinkConfigManager {
58
59
  if (createBackup) {
59
60
  await this.restoreLatestBackup();
60
61
  if (!silent) {
61
- console.log("🔄 Auto-restored from backup due to error");
62
+ logger.info("🔄 Auto-restored from backup due to error");
62
63
  }
63
64
  }
64
65
  throw new Error(`Config update failed, restored from backup: ${error.message}`);
@@ -115,13 +116,13 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
115
116
  });
116
117
  }
117
118
  catch (error) {
118
- console.warn(`Failed to read backup ${file}:`, error.message);
119
+ logger.warn(`Failed to read backup ${file}:`, error.message);
119
120
  }
120
121
  }
121
122
  return backups.sort((a, b) => b.metadata.timestamp - a.metadata.timestamp);
122
123
  }
123
124
  catch (error) {
124
- console.warn("Failed to list backups:", error.message);
125
+ logger.warn("Failed to list backups:", error.message);
125
126
  return [];
126
127
  }
127
128
  }
@@ -142,7 +143,7 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
142
143
  }
143
144
  this.config = restoredConfig;
144
145
  await this.persistConfig(this.config);
145
- console.log(`✅ Config restored from backup: ${backupFilename}`);
146
+ logger.info(`✅ Config restored from backup: ${backupFilename}`);
146
147
  }
147
148
  catch (error) {
148
149
  throw new Error(`Failed to restore from backup ${backupFilename}: ${error.message}`);
@@ -167,10 +168,10 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
167
168
  for (const backup of toDelete) {
168
169
  try {
169
170
  await unlink(backup.path);
170
- console.log(`🗑️ Deleted old backup: ${backup.filename}`);
171
+ logger.info(`🗑️ Deleted old backup: ${backup.filename}`);
171
172
  }
172
173
  catch (error) {
173
- console.warn(`Failed to delete backup ${backup.filename}:`, error.message);
174
+ logger.warn(`Failed to delete backup ${backup.filename}:`, error.message);
174
175
  }
175
176
  }
176
177
  }
@@ -248,7 +249,7 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
248
249
  await mkdir(this.backupDir, { recursive: true });
249
250
  }
250
251
  catch (error) {
251
- console.warn("Failed to create backup directory:", error.message);
252
+ logger.warn("Failed to create backup directory:", error.message);
252
253
  }
253
254
  }
254
255
  async readConfigFile() {
@@ -265,7 +266,7 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
265
266
  throw new Error("Invalid config file format");
266
267
  }
267
268
  catch (error) {
268
- console.log("Config file not found, generating default...");
269
+ logger.info("Config file not found, generating default...");
269
270
  return await this.generateDefaultConfig();
270
271
  }
271
272
  }
@@ -6,6 +6,7 @@ import { tool } from "ai";
6
6
  import { z } from "zod";
7
7
  import * as fs from "fs";
8
8
  import * as path from "path";
9
+ import { logger } from "../utils/logger.js";
9
10
  /**
10
11
  * Direct tool definitions that work immediately with Gemini/AI SDK
11
12
  * These bypass MCP complexity and provide reliable agent functionality
@@ -365,23 +366,23 @@ export function validateToolStructure() {
365
366
  try {
366
367
  for (const [name, tool] of Object.entries(directAgentTools)) {
367
368
  if (!tool.description || typeof tool.description !== "string") {
368
- console.error(`❌ Tool ${name} missing description`);
369
+ logger.error(`❌ Tool ${name} missing description`);
369
370
  return false;
370
371
  }
371
372
  if (!tool.parameters) {
372
- console.error(`❌ Tool ${name} missing parameters`);
373
+ logger.error(`❌ Tool ${name} missing parameters`);
373
374
  return false;
374
375
  }
375
376
  if (!tool.execute || typeof tool.execute !== "function") {
376
- console.error(`❌ Tool ${name} missing execute function`);
377
+ logger.error(`❌ Tool ${name} missing execute function`);
377
378
  return false;
378
379
  }
379
380
  }
380
- console.log("✅ All tools have valid structure");
381
+ logger.info("✅ All tools have valid structure");
381
382
  return true;
382
383
  }
383
384
  catch (error) {
384
- console.error("❌ Tool validation failed:", error);
385
+ logger.error("❌ Tool validation failed:", error);
385
386
  return false;
386
387
  }
387
388
  }
@@ -5,6 +5,7 @@
5
5
  import { promises as fs } from "fs";
6
6
  import path from "path";
7
7
  import crypto from "crypto";
8
+ import { logger } from "../utils/logger.js";
8
9
  const { readFile, writeFile, readdir, mkdir, unlink, access } = fs;
9
10
  /**
10
11
  * Enhanced Config Manager with automatic backup/restore capabilities
@@ -32,7 +33,7 @@ export class NeuroLinkConfigManager {
32
33
  if (createBackup) {
33
34
  await this.createBackup(reason);
34
35
  if (!silent) {
35
- console.log("💾 Backup created before config update");
36
+ logger.info("💾 Backup created before config update");
36
37
  }
37
38
  }
38
39
  const existing = await this.loadConfig();
@@ -50,7 +51,7 @@ export class NeuroLinkConfigManager {
50
51
  try {
51
52
  await this.persistConfig(this.config);
52
53
  if (!silent) {
53
- console.log("✅ Configuration updated successfully");
54
+ logger.info("✅ Configuration updated successfully");
54
55
  }
55
56
  }
56
57
  catch (error) {
@@ -58,7 +59,7 @@ export class NeuroLinkConfigManager {
58
59
  if (createBackup) {
59
60
  await this.restoreLatestBackup();
60
61
  if (!silent) {
61
- console.log("🔄 Auto-restored from backup due to error");
62
+ logger.info("🔄 Auto-restored from backup due to error");
62
63
  }
63
64
  }
64
65
  throw new Error(`Config update failed, restored from backup: ${error.message}`);
@@ -115,13 +116,13 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
115
116
  });
116
117
  }
117
118
  catch (error) {
118
- console.warn(`Failed to read backup ${file}:`, error.message);
119
+ logger.warn(`Failed to read backup ${file}:`, error.message);
119
120
  }
120
121
  }
121
122
  return backups.sort((a, b) => b.metadata.timestamp - a.metadata.timestamp);
122
123
  }
123
124
  catch (error) {
124
- console.warn("Failed to list backups:", error.message);
125
+ logger.warn("Failed to list backups:", error.message);
125
126
  return [];
126
127
  }
127
128
  }
@@ -142,7 +143,7 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
142
143
  }
143
144
  this.config = restoredConfig;
144
145
  await this.persistConfig(this.config);
145
- console.log(`✅ Config restored from backup: ${backupFilename}`);
146
+ logger.info(`✅ Config restored from backup: ${backupFilename}`);
146
147
  }
147
148
  catch (error) {
148
149
  throw new Error(`Failed to restore from backup ${backupFilename}: ${error.message}`);
@@ -167,10 +168,10 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
167
168
  for (const backup of toDelete) {
168
169
  try {
169
170
  await unlink(backup.path);
170
- console.log(`🗑️ Deleted old backup: ${backup.filename}`);
171
+ logger.info(`🗑️ Deleted old backup: ${backup.filename}`);
171
172
  }
172
173
  catch (error) {
173
- console.warn(`Failed to delete backup ${backup.filename}:`, error.message);
174
+ logger.warn(`Failed to delete backup ${backup.filename}:`, error.message);
174
175
  }
175
176
  }
176
177
  }
@@ -248,7 +249,7 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
248
249
  await mkdir(this.backupDir, { recursive: true });
249
250
  }
250
251
  catch (error) {
251
- console.warn("Failed to create backup directory:", error.message);
252
+ logger.warn("Failed to create backup directory:", error.message);
252
253
  }
253
254
  }
254
255
  async readConfigFile() {
@@ -265,7 +266,7 @@ export default ${JSON.stringify(currentConfig, null, 2)};`;
265
266
  throw new Error("Invalid config file format");
266
267
  }
267
268
  catch (error) {
268
- console.log("Config file not found, generating default...");
269
+ logger.info("Config file not found, generating default...");
269
270
  return await this.generateDefaultConfig();
270
271
  }
271
272
  }
@@ -4,8 +4,8 @@
4
4
  * Implementation based on research blueprint
5
5
  */
6
6
  export type { McpMetadata, ExecutionContext, DiscoveredMcp, ToolInfo, ToolExecutionResult, } from "./contracts/mcpContract.js";
7
- export { mcpLogger } from "./logging.js";
8
- export type { LogLevel } from "./logging.js";
7
+ export { mcpLogger } from "../utils/logger.js";
8
+ export type { LogLevel } from "../utils/logger.js";
9
9
  import type { McpMetadata } from "./contracts/mcpContract.js";
10
10
  /**
11
11
  * Initialize the MCP ecosystem - simplified
@@ -4,7 +4,7 @@
4
4
  * Implementation based on research blueprint
5
5
  */
6
6
  // Core functionality exports
7
- export { mcpLogger } from "./logging.js";
7
+ export { mcpLogger } from "../utils/logger.js";
8
8
  /**
9
9
  * Initialize the MCP ecosystem - simplified
10
10
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * MCP Registry - Industry Standard Interface with camelCase
3
3
  */
4
- import { registryLogger } from "./logging.js";
4
+ import { registryLogger } from "../utils/logger.js";
5
5
  /**
6
6
  * Simple MCP registry for plugin management
7
7
  * Maintains backward compatibility with existing code
@@ -6,6 +6,7 @@
6
6
  import { z } from "zod";
7
7
  import { AIProviderFactory } from "../../../core/factory.js";
8
8
  import { getBestProvider, getAvailableProviders, } from "../../../utils/providerUtils.js";
9
+ import { logger } from "../../../utils/logger.js";
9
10
  /**
10
11
  * Input Schemas for AI Analysis Tools
11
12
  */
@@ -89,7 +90,7 @@ const analyzeAIUsageTool = {
89
90
  const typedParams = params;
90
91
  const startTime = Date.now();
91
92
  try {
92
- console.log(`[AI-Analysis] Starting real AI-powered usage analysis for timeRange: ${typedParams.timeRange}`);
93
+ logger.debug(`[AI-Analysis] Starting real AI-powered usage analysis for timeRange: ${typedParams.timeRange}`);
93
94
  const providerName = await getBestProvider();
94
95
  const provider = await AIProviderFactory.createProvider(providerName);
95
96
  if (!provider) {
@@ -3,7 +3,7 @@
3
3
  * Updated to match industry standard camelCase interfaces
4
4
  */
5
5
  import { MCPRegistry } from "./registry.js";
6
- import { registryLogger } from "./logging.js";
6
+ import { registryLogger } from "../utils/logger.js";
7
7
  import { randomUUID } from "crypto";
8
8
  export class MCPToolRegistry extends MCPRegistry {
9
9
  tools = new Map();
@@ -14,7 +14,7 @@ catch (error) {
14
14
  // Environment variables should be set externally in production
15
15
  }
16
16
  import { AIProviderFactory } from "./core/factory.js";
17
- import { mcpLogger } from "./mcp/logging.js";
17
+ import { mcpLogger } from "./utils/logger.js";
18
18
  import { toolRegistry } from "./mcp/tool-registry.js";
19
19
  import { logger } from "./utils/logger.js";
20
20
  import { getBestProvider } from "./utils/providerUtils.js";
@@ -2,6 +2,7 @@ import { createAzure } from "@ai-sdk/azure";
2
2
  import { streamText } from "ai";
3
3
  import { BaseProvider } from "../core/base-provider.js";
4
4
  import { validateApiKey, createAzureAPIKeyConfig, createAzureEndpointConfig, } from "../utils/providerConfig.js";
5
+ import { logger } from "../utils/logger.js";
5
6
  export class AzureOpenAIProvider extends BaseProvider {
6
7
  apiKey;
7
8
  resourceName;
@@ -35,7 +36,7 @@ export class AzureOpenAIProvider extends BaseProvider {
35
36
  apiKey: this.apiKey,
36
37
  apiVersion: this.apiVersion,
37
38
  });
38
- console.log("Azure Vercel Provider initialized", {
39
+ logger.debug("Azure Vercel Provider initialized", {
39
40
  deployment: this.deployment,
40
41
  resourceName: this.resourceName,
41
42
  provider: "azure-vercel",
@@ -1,5 +1,6 @@
1
1
  // Optional Telemetry Infrastructure (Phase 2)
2
2
  export { TelemetryService } from "./telemetry-service.js";
3
+ import { logger } from "../utils/logger.js";
3
4
  /**
4
5
  * Initialize telemetry for NeuroLink
5
6
  * OPTIONAL - Only works when NEUROLINK_TELEMETRY_ENABLED=true
@@ -9,7 +10,7 @@ export async function initializeTelemetry() {
9
10
  const telemetry = TelemetryService.getInstance();
10
11
  if (telemetry.isEnabled()) {
11
12
  await telemetry.initialize();
12
- console.log("[NeuroLink] Telemetry initialized");
13
+ logger.info("[NeuroLink] Telemetry initialized");
13
14
  }
14
15
  return telemetry;
15
16
  }
@@ -1,12 +1,72 @@
1
1
  /**
2
- * NeuroLink Logger Utility
2
+ * NeuroLink Unified Logger Utility
3
3
  *
4
- * Provides conditional logging based on NEUROLINK_DEBUG environment variable
4
+ * Centralized logging for the entire NeuroLink ecosystem
5
+ * Supports both CLI --debug flag and NEUROLINK_DEBUG environment variable
6
+ * Migrated from MCP logging with enhanced features
5
7
  */
8
+ export type LogLevel = "debug" | "info" | "warn" | "error";
9
+ interface LogEntry {
10
+ level: LogLevel;
11
+ message: string;
12
+ timestamp: Date;
13
+ data?: unknown;
14
+ }
15
+ declare class NeuroLinkLogger {
16
+ private logLevel;
17
+ private logs;
18
+ private maxLogs;
19
+ private isDebugMode;
20
+ constructor();
21
+ setLogLevel(level: LogLevel): void;
22
+ shouldLog(level: LogLevel): boolean;
23
+ private getLogPrefix;
24
+ /**
25
+ * Outputs a log entry to the console based on the log level.
26
+ *
27
+ * @param level - The log level (debug, info, warn, error).
28
+ * @param prefix - The formatted log prefix.
29
+ * @param message - The log message.
30
+ * @param data - Optional additional data to log.
31
+ */
32
+ private outputToConsole;
33
+ private log;
34
+ debug(message: string, data?: unknown): void;
35
+ info(message: string, data?: unknown): void;
36
+ warn(message: string, data?: unknown): void;
37
+ error(message: string, data?: unknown): void;
38
+ getLogs(level?: LogLevel): LogEntry[];
39
+ clearLogs(): void;
40
+ /**
41
+ * Logs messages unconditionally using `console.log`.
42
+ *
43
+ * This method is part of a legacy simple logger interface for backward compatibility.
44
+ * It bypasses the structured logging mechanism and should only be used when
45
+ * unstructured, unconditional logging is required.
46
+ *
47
+ * @param args - The arguments to log. These are passed directly to `console.log`.
48
+ */
49
+ always(...args: unknown[]): void;
50
+ }
6
51
  export declare const logger: {
7
52
  debug: (...args: unknown[]) => void;
8
53
  info: (...args: unknown[]) => void;
9
54
  warn: (...args: unknown[]) => void;
10
55
  error: (...args: unknown[]) => void;
11
56
  always: (...args: unknown[]) => void;
57
+ setLogLevel: (level: LogLevel) => void;
58
+ getLogs: (level?: LogLevel) => LogEntry[];
59
+ clearLogs: () => void;
12
60
  };
61
+ export declare const mcpLogger: NeuroLinkLogger;
62
+ export declare const autoDiscoveryLogger: NeuroLinkLogger;
63
+ export declare const registryLogger: NeuroLinkLogger;
64
+ export declare const unifiedRegistryLogger: NeuroLinkLogger;
65
+ export declare function setGlobalMCPLogLevel(level: LogLevel): void;
66
+ export declare const LogLevels: {
67
+ readonly debug: "debug";
68
+ readonly info: "info";
69
+ readonly warn: "warn";
70
+ readonly error: "error";
71
+ };
72
+ export type { LogEntry };
@@ -1,25 +1,190 @@
1
1
  /**
2
- * NeuroLink Logger Utility
2
+ * NeuroLink Unified Logger Utility
3
3
  *
4
- * Provides conditional logging based on NEUROLINK_DEBUG environment variable
4
+ * Centralized logging for the entire NeuroLink ecosystem
5
+ * Supports both CLI --debug flag and NEUROLINK_DEBUG environment variable
6
+ * Migrated from MCP logging with enhanced features
5
7
  */
8
+ // Pre-computed uppercase log levels for performance optimization
9
+ const UPPERCASE_LOG_LEVELS = {
10
+ debug: "DEBUG",
11
+ info: "INFO",
12
+ warn: "WARN",
13
+ error: "ERROR",
14
+ };
15
+ class NeuroLinkLogger {
16
+ logLevel = "info";
17
+ logs = [];
18
+ maxLogs = 1000;
19
+ isDebugMode;
20
+ constructor() {
21
+ // Cache debug mode check to avoid repeated array searches
22
+ this.isDebugMode =
23
+ process.argv.includes("--debug") ||
24
+ process.env.NEUROLINK_DEBUG === "true";
25
+ // Check NEUROLINK_LOG_LEVEL for consistency with the unified NeuroLink logger
26
+ let envLevel = process.env.NEUROLINK_LOG_LEVEL?.toLowerCase();
27
+ // Fallback to MCP_LOG_LEVEL for backward compatibility (if needed)
28
+ if (!envLevel) {
29
+ envLevel = process.env.MCP_LOG_LEVEL?.toLowerCase();
30
+ }
31
+ if (envLevel && ["debug", "info", "warn", "error"].includes(envLevel)) {
32
+ this.logLevel = envLevel;
33
+ }
34
+ }
35
+ setLogLevel(level) {
36
+ this.logLevel = level;
37
+ }
38
+ shouldLog(level) {
39
+ // Hide all logs except errors unless debugging
40
+ if (!this.isDebugMode && level !== "error") {
41
+ return false;
42
+ }
43
+ const levels = ["debug", "info", "warn", "error"];
44
+ return levels.indexOf(level) >= levels.indexOf(this.logLevel);
45
+ }
46
+ getLogPrefix(timestamp, level) {
47
+ return `[${timestamp}] [NEUROLINK:${UPPERCASE_LOG_LEVELS[level]}]`;
48
+ }
49
+ /**
50
+ * Outputs a log entry to the console based on the log level.
51
+ *
52
+ * @param level - The log level (debug, info, warn, error).
53
+ * @param prefix - The formatted log prefix.
54
+ * @param message - The log message.
55
+ * @param data - Optional additional data to log.
56
+ */
57
+ outputToConsole(level, prefix, message, data) {
58
+ const logMethod = {
59
+ debug: console.debug,
60
+ info: console.info,
61
+ warn: console.warn,
62
+ error: console.error,
63
+ }[level];
64
+ if (data !== undefined && data !== null) {
65
+ logMethod(prefix, message, data);
66
+ }
67
+ else {
68
+ logMethod(prefix, message);
69
+ }
70
+ }
71
+ log(level, message, data) {
72
+ if (!this.shouldLog(level)) {
73
+ return;
74
+ }
75
+ const entry = {
76
+ level,
77
+ message,
78
+ timestamp: new Date(),
79
+ data,
80
+ };
81
+ // Store log entry
82
+ this.logs.push(entry);
83
+ // Trim old logs
84
+ if (this.logs.length > this.maxLogs) {
85
+ this.logs = this.logs.slice(-this.maxLogs);
86
+ }
87
+ // Console output
88
+ const timestamp = entry.timestamp.toISOString();
89
+ const prefix = this.getLogPrefix(timestamp, level);
90
+ this.outputToConsole(level, prefix, message, data);
91
+ }
92
+ debug(message, data) {
93
+ this.log("debug", message, data);
94
+ }
95
+ info(message, data) {
96
+ this.log("info", message, data);
97
+ }
98
+ warn(message, data) {
99
+ this.log("warn", message, data);
100
+ }
101
+ error(message, data) {
102
+ this.log("error", message, data);
103
+ }
104
+ getLogs(level) {
105
+ if (level) {
106
+ return this.logs.filter((log) => log.level === level);
107
+ }
108
+ return [...this.logs];
109
+ }
110
+ clearLogs() {
111
+ this.logs = [];
112
+ }
113
+ /**
114
+ * Logs messages unconditionally using `console.log`.
115
+ *
116
+ * This method is part of a legacy simple logger interface for backward compatibility.
117
+ * It bypasses the structured logging mechanism and should only be used when
118
+ * unstructured, unconditional logging is required.
119
+ *
120
+ * @param args - The arguments to log. These are passed directly to `console.log`.
121
+ */
122
+ always(...args) {
123
+ console.log(...args);
124
+ }
125
+ }
126
+ // Export singleton instance
127
+ const neuroLinkLogger = new NeuroLinkLogger();
128
+ // Helper function to process arguments with minimal overhead
129
+ function processLoggerArgs(args, logMethod) {
130
+ if (args.length === 0) {
131
+ return;
132
+ }
133
+ // Serialize the first argument robustly to handle complex objects
134
+ const message = (() => {
135
+ try {
136
+ return typeof args[0] === "string" ? args[0] : JSON.stringify(args[0]);
137
+ }
138
+ catch {
139
+ return "[Unserializable Object]";
140
+ }
141
+ })();
142
+ const data = args.length === 2 ? args[1] : args.length > 2 ? args.slice(1) : undefined;
143
+ logMethod(message, data);
144
+ }
145
+ // Main unified logger export
6
146
  export const logger = {
7
147
  debug: (...args) => {
8
- if (process.env.NEUROLINK_DEBUG === "true") {
9
- console.log(...args);
148
+ if (neuroLinkLogger.shouldLog("debug")) {
149
+ processLoggerArgs(args, (message, data) => neuroLinkLogger.debug(message, data));
10
150
  }
11
151
  },
12
152
  info: (...args) => {
13
- // Completely disabled for clean CLI demo output
153
+ if (neuroLinkLogger.shouldLog("info")) {
154
+ processLoggerArgs(args, (message, data) => neuroLinkLogger.info(message, data));
155
+ }
14
156
  },
15
157
  warn: (...args) => {
16
- // Completely disabled for clean CLI demo output
158
+ if (neuroLinkLogger.shouldLog("warn")) {
159
+ processLoggerArgs(args, (message, data) => neuroLinkLogger.warn(message, data));
160
+ }
17
161
  },
18
162
  error: (...args) => {
19
- // Always show errors regardless of debug mode
20
- console.error(...args);
163
+ if (neuroLinkLogger.shouldLog("error")) {
164
+ processLoggerArgs(args, (message, data) => neuroLinkLogger.error(message, data));
165
+ }
21
166
  },
22
167
  always: (...args) => {
23
- console.log(...args);
168
+ neuroLinkLogger.always(...args);
24
169
  },
170
+ // Expose structured logging methods
171
+ setLogLevel: (level) => neuroLinkLogger.setLogLevel(level),
172
+ getLogs: (level) => neuroLinkLogger.getLogs(level),
173
+ clearLogs: () => neuroLinkLogger.clearLogs(),
174
+ };
175
+ // MCP compatibility exports - all use the same unified logger
176
+ export const mcpLogger = neuroLinkLogger;
177
+ export const autoDiscoveryLogger = neuroLinkLogger;
178
+ export const registryLogger = neuroLinkLogger;
179
+ export const unifiedRegistryLogger = neuroLinkLogger;
180
+ // Global log level setter
181
+ export function setGlobalMCPLogLevel(level) {
182
+ neuroLinkLogger.setLogLevel(level);
183
+ }
184
+ // Export LogLevel enum for runtime use
185
+ export const LogLevels = {
186
+ debug: "debug",
187
+ info: "info",
188
+ warn: "warn",
189
+ error: "error",
25
190
  };
@@ -4,8 +4,8 @@
4
4
  * Implementation based on research blueprint
5
5
  */
6
6
  export type { McpMetadata, ExecutionContext, DiscoveredMcp, ToolInfo, ToolExecutionResult, } from "./contracts/mcpContract.js";
7
- export { mcpLogger } from "./logging.js";
8
- export type { LogLevel } from "./logging.js";
7
+ export { mcpLogger } from "../utils/logger.js";
8
+ export type { LogLevel } from "../utils/logger.js";
9
9
  import type { McpMetadata } from "./contracts/mcpContract.js";
10
10
  /**
11
11
  * Initialize the MCP ecosystem - simplified