deepthinking-mcp 2.5.3 → 2.5.5

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/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
5
- import { randomUUID } from 'crypto';
5
+ import { randomUUID, createHash } from 'crypto';
6
6
  import { readFileSync } from 'fs';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { dirname, join } from 'path';
@@ -991,8 +991,399 @@ var ModeRecommender = class {
991
991
  }
992
992
  };
993
993
 
994
- // src/session/manager.ts
994
+ // src/utils/errors.ts
995
+ var DeepThinkingError = class extends Error {
996
+ code;
997
+ context;
998
+ timestamp;
999
+ constructor(message, code, context) {
1000
+ super(message);
1001
+ this.name = this.constructor.name;
1002
+ this.code = code;
1003
+ this.context = context;
1004
+ this.timestamp = /* @__PURE__ */ new Date();
1005
+ if (Error.captureStackTrace) {
1006
+ Error.captureStackTrace(this, this.constructor);
1007
+ }
1008
+ }
1009
+ /**
1010
+ * Convert error to JSON for logging/serialization
1011
+ */
1012
+ toJSON() {
1013
+ return {
1014
+ name: this.name,
1015
+ message: this.message,
1016
+ code: this.code,
1017
+ context: this.context,
1018
+ timestamp: this.timestamp.toISOString(),
1019
+ stack: this.stack
1020
+ };
1021
+ }
1022
+ };
1023
+ var SessionError = class extends DeepThinkingError {
1024
+ constructor(message, context) {
1025
+ super(message, "SESSION_ERROR", context);
1026
+ }
1027
+ };
1028
+ var SessionNotFoundError = class extends SessionError {
1029
+ constructor(sessionId) {
1030
+ super(`Session not found: ${sessionId}`, { sessionId });
1031
+ this.code = "SESSION_NOT_FOUND";
1032
+ }
1033
+ };
1034
+
1035
+ // src/utils/sanitization.ts
1036
+ var MAX_LENGTHS = {
1037
+ THOUGHT_CONTENT: 1e5,
1038
+ // 100KB for thought content
1039
+ TITLE: 500,
1040
+ DOMAIN: 200,
1041
+ AUTHOR: 300,
1042
+ STRING_FIELD: 1e3
1043
+ };
1044
+ function sanitizeString(input, maxLength = MAX_LENGTHS.STRING_FIELD, fieldName = "input") {
1045
+ if (typeof input !== "string") {
1046
+ throw new Error(`${fieldName} must be a string`);
1047
+ }
1048
+ const trimmed = input.trim();
1049
+ if (trimmed.length === 0) {
1050
+ throw new Error(`${fieldName} cannot be empty`);
1051
+ }
1052
+ if (trimmed.length > maxLength) {
1053
+ throw new Error(`${fieldName} exceeds maximum length of ${maxLength} characters`);
1054
+ }
1055
+ if (trimmed.includes("\0")) {
1056
+ throw new Error(`${fieldName} contains invalid null bytes`);
1057
+ }
1058
+ return trimmed;
1059
+ }
1060
+ function validateSessionId(sessionId) {
1061
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
1062
+ if (!uuidRegex.test(sessionId)) {
1063
+ throw new Error(`Invalid session ID format: ${sessionId}`);
1064
+ }
1065
+ return sessionId;
1066
+ }
1067
+ function sanitizeThoughtContent(content) {
1068
+ return sanitizeString(content, MAX_LENGTHS.THOUGHT_CONTENT, "thought content");
1069
+ }
1070
+
1071
+ // src/utils/logger.ts
1072
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
1073
+ LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
1074
+ LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
1075
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
1076
+ LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
1077
+ LogLevel2[LogLevel2["SILENT"] = 4] = "SILENT";
1078
+ return LogLevel2;
1079
+ })(LogLevel || {});
995
1080
  var DEFAULT_CONFIG = {
1081
+ minLevel: 1 /* INFO */,
1082
+ enableConsole: true,
1083
+ enableTimestamps: true,
1084
+ prettyPrint: true
1085
+ };
1086
+ var Logger = class {
1087
+ config;
1088
+ logs = [];
1089
+ constructor(config) {
1090
+ this.config = { ...DEFAULT_CONFIG, ...config };
1091
+ }
1092
+ /**
1093
+ * Log a debug message
1094
+ */
1095
+ debug(message, context) {
1096
+ this.log(0 /* DEBUG */, message, context);
1097
+ }
1098
+ /**
1099
+ * Log an info message
1100
+ */
1101
+ info(message, context) {
1102
+ this.log(1 /* INFO */, message, context);
1103
+ }
1104
+ /**
1105
+ * Log a warning message
1106
+ */
1107
+ warn(message, context) {
1108
+ this.log(2 /* WARN */, message, context);
1109
+ }
1110
+ /**
1111
+ * Log an error message
1112
+ */
1113
+ error(message, error, context) {
1114
+ this.log(3 /* ERROR */, message, context, error);
1115
+ }
1116
+ /**
1117
+ * Internal log method
1118
+ */
1119
+ log(level, message, context, error) {
1120
+ if (level < this.config.minLevel) {
1121
+ return;
1122
+ }
1123
+ const entry = {
1124
+ level,
1125
+ message,
1126
+ timestamp: /* @__PURE__ */ new Date(),
1127
+ context,
1128
+ error
1129
+ };
1130
+ this.logs.push(entry);
1131
+ if (this.config.enableConsole) {
1132
+ this.writeToConsole(entry);
1133
+ }
1134
+ }
1135
+ /**
1136
+ * Write log entry to console
1137
+ */
1138
+ writeToConsole(entry) {
1139
+ const levelName = LogLevel[entry.level];
1140
+ const timestamp = this.config.enableTimestamps ? `[${entry.timestamp.toISOString()}] ` : "";
1141
+ let message = `${timestamp}${levelName}: ${entry.message}`;
1142
+ if (entry.context && this.config.prettyPrint) {
1143
+ message += `
1144
+ Context: ${JSON.stringify(entry.context, null, 2)}`;
1145
+ }
1146
+ if (entry.error) {
1147
+ message += `
1148
+ Error: ${entry.error.message}`;
1149
+ if (entry.error.stack && this.config.prettyPrint) {
1150
+ message += `
1151
+ Stack: ${entry.error.stack}`;
1152
+ }
1153
+ }
1154
+ switch (entry.level) {
1155
+ case 0 /* DEBUG */:
1156
+ case 1 /* INFO */:
1157
+ console.log(message);
1158
+ break;
1159
+ case 2 /* WARN */:
1160
+ console.warn(message);
1161
+ break;
1162
+ case 3 /* ERROR */:
1163
+ console.error(message);
1164
+ break;
1165
+ }
1166
+ }
1167
+ /**
1168
+ * Get all log entries
1169
+ */
1170
+ getLogs(minLevel) {
1171
+ if (minLevel !== void 0) {
1172
+ return this.logs.filter((log) => log.level >= minLevel);
1173
+ }
1174
+ return [...this.logs];
1175
+ }
1176
+ /**
1177
+ * Clear all logs
1178
+ */
1179
+ clearLogs() {
1180
+ this.logs = [];
1181
+ }
1182
+ /**
1183
+ * Set minimum log level
1184
+ */
1185
+ setLevel(level) {
1186
+ this.config.minLevel = level;
1187
+ }
1188
+ /**
1189
+ * Export logs as JSON
1190
+ */
1191
+ exportLogs() {
1192
+ return JSON.stringify(this.logs.map((log) => ({
1193
+ ...log,
1194
+ level: LogLevel[log.level],
1195
+ timestamp: log.timestamp.toISOString()
1196
+ })), null, 2);
1197
+ }
1198
+ };
1199
+ new Logger();
1200
+ function createLogger(config) {
1201
+ return new Logger(config);
1202
+ }
1203
+
1204
+ // src/config/index.ts
1205
+ var defaultConfig = {
1206
+ maxThoughtsInMemory: parseInt(process.env.MCP_MAX_THOUGHTS || "1000", 10),
1207
+ compressionThreshold: parseInt(process.env.MCP_COMPRESSION_THRESHOLD || "500", 10),
1208
+ maxContentLength: parseInt(process.env.MCP_MAX_CONTENT_LENGTH || "10000", 10),
1209
+ validationTolerance: parseFloat(process.env.MCP_VALIDATION_TOLERANCE || "0.01"),
1210
+ maxActiveSessions: parseInt(process.env.MCP_MAX_SESSIONS || "100", 10),
1211
+ sessionTimeoutMs: parseInt(process.env.MCP_SESSION_TIMEOUT_MS || "0", 10),
1212
+ enableValidationCache: process.env.MCP_ENABLE_VALIDATION_CACHE !== "false",
1213
+ validationCacheMaxSize: parseInt(process.env.MCP_VALIDATION_CACHE_SIZE || "1000", 10),
1214
+ enablePersistence: process.env.MCP_ENABLE_PERSISTENCE === "true",
1215
+ persistenceDir: process.env.MCP_PERSISTENCE_DIR || "./.deepthinking-sessions",
1216
+ logLevel: process.env.MCP_LOG_LEVEL || "info",
1217
+ enablePerformanceMetrics: process.env.MCP_ENABLE_PERF_METRICS === "true"
1218
+ };
1219
+ var activeConfig = { ...defaultConfig };
1220
+ function getConfig() {
1221
+ return Object.freeze({ ...activeConfig });
1222
+ }
1223
+ function validateConfig(config) {
1224
+ if (config.maxThoughtsInMemory < 1) {
1225
+ throw new Error("maxThoughtsInMemory must be at least 1");
1226
+ }
1227
+ if (config.compressionThreshold < 0) {
1228
+ throw new Error("compressionThreshold must be non-negative");
1229
+ }
1230
+ if (config.maxContentLength < 1) {
1231
+ throw new Error("maxContentLength must be at least 1");
1232
+ }
1233
+ if (config.validationTolerance < 0 || config.validationTolerance > 1) {
1234
+ throw new Error("validationTolerance must be between 0 and 1");
1235
+ }
1236
+ if (config.maxActiveSessions < 1) {
1237
+ throw new Error("maxActiveSessions must be at least 1");
1238
+ }
1239
+ if (config.sessionTimeoutMs < 0) {
1240
+ throw new Error("sessionTimeoutMs must be non-negative");
1241
+ }
1242
+ if (config.validationCacheMaxSize < 0) {
1243
+ throw new Error("validationCacheMaxSize must be non-negative");
1244
+ }
1245
+ if (!["debug", "info", "warn", "error"].includes(config.logLevel)) {
1246
+ throw new Error("logLevel must be one of: debug, info, warn, error");
1247
+ }
1248
+ }
1249
+ validateConfig(activeConfig);
1250
+ var ValidationCache = class {
1251
+ cache;
1252
+ maxSize;
1253
+ hits = 0;
1254
+ misses = 0;
1255
+ constructor(maxSize) {
1256
+ const config = getConfig();
1257
+ this.maxSize = maxSize || config.validationCacheMaxSize;
1258
+ this.cache = /* @__PURE__ */ new Map();
1259
+ }
1260
+ /**
1261
+ * Generate a cache key from thought content
1262
+ *
1263
+ * Uses SHA-256 hash of JSON-serialized content for reliable cache keys
1264
+ *
1265
+ * @param content - Content to hash
1266
+ * @returns Cache key
1267
+ */
1268
+ generateKey(content) {
1269
+ const json = JSON.stringify(content);
1270
+ return createHash("sha256").update(json).digest("hex");
1271
+ }
1272
+ /**
1273
+ * Get validation result from cache
1274
+ *
1275
+ * @param content - Content to look up
1276
+ * @returns Cached result or undefined if not found
1277
+ */
1278
+ get(content) {
1279
+ const key = this.generateKey(content);
1280
+ const entry = this.cache.get(key);
1281
+ if (entry) {
1282
+ this.hits++;
1283
+ entry.hitCount++;
1284
+ this.cache.delete(key);
1285
+ this.cache.set(key, entry);
1286
+ return entry;
1287
+ }
1288
+ this.misses++;
1289
+ return void 0;
1290
+ }
1291
+ /**
1292
+ * Store validation result in cache
1293
+ *
1294
+ * @param content - Content that was validated
1295
+ * @param result - Validation result to cache
1296
+ */
1297
+ set(content, result) {
1298
+ const key = this.generateKey(content);
1299
+ if (this.cache.size >= this.maxSize) {
1300
+ const firstKey = this.cache.keys().next().value;
1301
+ if (firstKey !== void 0) {
1302
+ this.cache.delete(firstKey);
1303
+ }
1304
+ }
1305
+ const entry = {
1306
+ result,
1307
+ timestamp: Date.now(),
1308
+ hitCount: 0
1309
+ };
1310
+ this.cache.set(key, entry);
1311
+ }
1312
+ /**
1313
+ * Check if content is in cache
1314
+ *
1315
+ * @param content - Content to check
1316
+ * @returns true if cached
1317
+ */
1318
+ has(content) {
1319
+ const key = this.generateKey(content);
1320
+ return this.cache.has(key);
1321
+ }
1322
+ /**
1323
+ * Clear all cached validation results
1324
+ */
1325
+ clear() {
1326
+ this.cache.clear();
1327
+ this.hits = 0;
1328
+ this.misses = 0;
1329
+ }
1330
+ /**
1331
+ * Get cache statistics
1332
+ */
1333
+ getStats() {
1334
+ const total = this.hits + this.misses;
1335
+ return {
1336
+ size: this.cache.size,
1337
+ maxSize: this.maxSize,
1338
+ hits: this.hits,
1339
+ misses: this.misses,
1340
+ hitRate: total > 0 ? this.hits / total : 0
1341
+ };
1342
+ }
1343
+ /**
1344
+ * Resize the cache
1345
+ *
1346
+ * @param newSize - New maximum cache size
1347
+ */
1348
+ resize(newSize) {
1349
+ this.maxSize = newSize;
1350
+ if (this.cache.size > newSize) {
1351
+ const keysToDelete = this.cache.size - newSize;
1352
+ const keys = Array.from(this.cache.keys());
1353
+ for (let i = 0; i < keysToDelete; i++) {
1354
+ this.cache.delete(keys[i]);
1355
+ }
1356
+ }
1357
+ }
1358
+ /**
1359
+ * Get entries sorted by hit count (most used first)
1360
+ */
1361
+ getTopEntries(limit = 10) {
1362
+ const entries = Array.from(this.cache.entries()).map(([key, entry]) => ({ key, entry })).sort((a, b) => b.entry.hitCount - a.entry.hitCount);
1363
+ return entries.slice(0, limit);
1364
+ }
1365
+ /**
1366
+ * Remove entries older than a certain age
1367
+ *
1368
+ * @param maxAgeMs - Maximum age in milliseconds
1369
+ * @returns Number of entries removed
1370
+ */
1371
+ evictOld(maxAgeMs) {
1372
+ const now = Date.now();
1373
+ let removed = 0;
1374
+ for (const [key, entry] of this.cache.entries()) {
1375
+ if (now - entry.timestamp > maxAgeMs) {
1376
+ this.cache.delete(key);
1377
+ removed++;
1378
+ }
1379
+ }
1380
+ return removed;
1381
+ }
1382
+ };
1383
+ var validationCache = new ValidationCache();
1384
+
1385
+ // src/session/manager.ts
1386
+ var DEFAULT_CONFIG2 = {
996
1387
  modeConfig: {
997
1388
  mode: "hybrid" /* HYBRID */,
998
1389
  strictValidation: false,
@@ -1010,48 +1401,139 @@ var DEFAULT_CONFIG = {
1010
1401
  var SessionManager = class {
1011
1402
  activeSessions;
1012
1403
  config;
1013
- constructor(config) {
1404
+ logger;
1405
+ /**
1406
+ * Creates a new SessionManager instance
1407
+ *
1408
+ * @param config - Optional default configuration applied to all new sessions
1409
+ * @param logLevel - Optional minimum log level (default: INFO)
1410
+ *
1411
+ * @example
1412
+ * ```typescript
1413
+ * const manager = new SessionManager({
1414
+ * enableAutoSave: true,
1415
+ * maxThoughtsInMemory: 500
1416
+ * }, LogLevel.DEBUG);
1417
+ * ```
1418
+ */
1419
+ constructor(config, logLevel) {
1014
1420
  this.activeSessions = /* @__PURE__ */ new Map();
1015
1421
  this.config = config || {};
1422
+ this.logger = createLogger({
1423
+ minLevel: logLevel || 1 /* INFO */,
1424
+ enableConsole: true
1425
+ });
1016
1426
  }
1017
1427
  /**
1018
1428
  * Create a new thinking session
1429
+ *
1430
+ * Creates and initializes a new thinking session with the specified configuration.
1431
+ * Sessions are stored in memory and tracked until explicitly deleted.
1432
+ *
1433
+ * @param options - Session creation options
1434
+ * @param options.title - Session title (default: 'Untitled Session')
1435
+ * @param options.mode - Thinking mode to use (default: HYBRID)
1436
+ * @param options.domain - Problem domain (e.g., 'mathematics', 'physics')
1437
+ * @param options.author - Session creator/author
1438
+ * @param options.config - Session-specific configuration overrides
1439
+ * @returns Promise resolving to the created session
1440
+ *
1441
+ * @example
1442
+ * ```typescript
1443
+ * const session = await manager.createSession({
1444
+ * title: 'Mathematical Proof',
1445
+ * mode: ThinkingMode.MATHEMATICS,
1446
+ * domain: 'number-theory',
1447
+ * author: 'user@example.com'
1448
+ * });
1449
+ * ```
1019
1450
  */
1020
1451
  async createSession(options = {}) {
1452
+ const title = options.title ? sanitizeString(options.title, MAX_LENGTHS.TITLE, "title") : "Untitled Session";
1453
+ const domain = options.domain ? sanitizeString(options.domain, MAX_LENGTHS.DOMAIN, "domain") : void 0;
1454
+ const author = options.author ? sanitizeString(options.author, MAX_LENGTHS.AUTHOR, "author") : void 0;
1021
1455
  const sessionId = randomUUID();
1022
1456
  const now = /* @__PURE__ */ new Date();
1023
1457
  const session = {
1024
1458
  id: sessionId,
1025
- title: options.title || "Untitled Session",
1459
+ title,
1026
1460
  mode: options.mode || "hybrid" /* HYBRID */,
1027
- domain: options.domain,
1461
+ domain,
1028
1462
  config: this.mergeConfig(options.config),
1029
1463
  thoughts: [],
1030
1464
  createdAt: now,
1031
1465
  updatedAt: now,
1032
- author: options.author,
1466
+ author,
1033
1467
  currentThoughtNumber: 0,
1034
1468
  isComplete: false,
1035
1469
  metrics: this.initializeMetrics(),
1036
1470
  tags: [],
1037
- collaborators: options.author ? [options.author] : []
1471
+ collaborators: author ? [author] : []
1038
1472
  };
1039
1473
  this.activeSessions.set(sessionId, session);
1474
+ this.logger.info("Session created", {
1475
+ sessionId,
1476
+ title,
1477
+ mode: session.mode,
1478
+ domain,
1479
+ author
1480
+ });
1040
1481
  return session;
1041
1482
  }
1042
1483
  /**
1043
1484
  * Get a session by ID
1485
+ *
1486
+ * Retrieves an active session by its unique identifier.
1487
+ *
1488
+ * @param sessionId - Unique UUID v4 identifier of the session
1489
+ * @returns Promise resolving to the session, or null if not found
1490
+ *
1491
+ * @example
1492
+ * ```typescript
1493
+ * const session = await manager.getSession('550e8400-e29b-41d4-a716-446655440000');
1494
+ * if (session) {
1495
+ * console.log(`Session: ${session.title}`);
1496
+ * console.log(`Thoughts: ${session.thoughts.length}`);
1497
+ * }
1498
+ * ```
1044
1499
  */
1045
1500
  async getSession(sessionId) {
1046
1501
  return this.activeSessions.get(sessionId) || null;
1047
1502
  }
1048
1503
  /**
1049
1504
  * Add a thought to a session
1505
+ *
1506
+ * Adds a new thought to an existing session and automatically updates:
1507
+ * - Session metrics (uses O(1) incremental calculation)
1508
+ * - Thought timestamps
1509
+ * - Session completion status
1510
+ * - Mode-specific analytics
1511
+ *
1512
+ * @param sessionId - ID of the session to add thought to
1513
+ * @param thought - The thought object to add
1514
+ * @returns Promise resolving to the updated session
1515
+ * @throws Error if session is not found
1516
+ *
1517
+ * @example
1518
+ * ```typescript
1519
+ * await manager.addThought(session.id, {
1520
+ * thought: 'Initial hypothesis: the problem can be solved using...',
1521
+ * thoughtNumber: 1,
1522
+ * totalThoughts: 5,
1523
+ * nextThoughtNeeded: true,
1524
+ * uncertainty: 0.3
1525
+ * });
1526
+ * ```
1050
1527
  */
1051
1528
  async addThought(sessionId, thought) {
1529
+ validateSessionId(sessionId);
1052
1530
  const session = this.activeSessions.get(sessionId);
1053
1531
  if (!session) {
1054
- throw new Error(`Session ${sessionId} not found`);
1532
+ this.logger.error("Session not found", void 0, { sessionId });
1533
+ throw new SessionNotFoundError(sessionId);
1534
+ }
1535
+ if (thought.content) {
1536
+ thought.content = sanitizeThoughtContent(thought.content);
1055
1537
  }
1056
1538
  thought.sessionId = sessionId;
1057
1539
  thought.timestamp = /* @__PURE__ */ new Date();
@@ -1061,25 +1543,74 @@ var SessionManager = class {
1061
1543
  this.updateMetrics(session, thought);
1062
1544
  if (!thought.nextThoughtNeeded) {
1063
1545
  session.isComplete = true;
1546
+ this.logger.info("Session completed", {
1547
+ sessionId,
1548
+ title: session.title,
1549
+ totalThoughts: session.thoughts.length
1550
+ });
1064
1551
  }
1552
+ this.logger.debug("Thought added", {
1553
+ sessionId,
1554
+ thoughtNumber: thought.thoughtNumber,
1555
+ totalThoughts: session.thoughts.length
1556
+ });
1065
1557
  return session;
1066
1558
  }
1067
1559
  /**
1068
- * Update session mode
1560
+ * Update session mode (switch reasoning approach mid-session)
1561
+ *
1562
+ * Changes the thinking mode of an active session. This is useful when
1563
+ * the problem requires a different reasoning approach.
1564
+ *
1565
+ * @param sessionId - ID of the session to update
1566
+ * @param newMode - New thinking mode to switch to
1567
+ * @param reason - Optional reason for the mode switch
1568
+ * @returns Promise resolving to the updated session
1569
+ * @throws Error if session is not found
1570
+ *
1571
+ * @example
1572
+ * ```typescript
1573
+ * await manager.switchMode(
1574
+ * session.id,
1575
+ * ThinkingMode.CAUSAL,
1576
+ * 'Need to analyze cause-effect relationships'
1577
+ * );
1578
+ * ```
1069
1579
  */
1070
1580
  async switchMode(sessionId, newMode, reason) {
1581
+ validateSessionId(sessionId);
1071
1582
  const session = this.activeSessions.get(sessionId);
1072
1583
  if (!session) {
1073
- throw new Error(`Session ${sessionId} not found`);
1584
+ this.logger.error("Session not found", void 0, { sessionId });
1585
+ throw new SessionNotFoundError(sessionId);
1074
1586
  }
1075
- session.mode;
1587
+ const oldMode = session.mode;
1076
1588
  session.mode = newMode;
1077
1589
  session.config.modeConfig.mode = newMode;
1078
1590
  session.updatedAt = /* @__PURE__ */ new Date();
1591
+ this.logger.info("Session mode switched", {
1592
+ sessionId,
1593
+ oldMode,
1594
+ newMode,
1595
+ reason
1596
+ });
1079
1597
  return session;
1080
1598
  }
1081
1599
  /**
1082
- * List all sessions
1600
+ * List all active sessions with metadata
1601
+ *
1602
+ * Returns summary information for all sessions currently managed
1603
+ * by this SessionManager instance.
1604
+ *
1605
+ * @returns Promise resolving to array of session metadata
1606
+ *
1607
+ * @example
1608
+ * ```typescript
1609
+ * const sessions = await manager.listSessions();
1610
+ * sessions.forEach(s => {
1611
+ * console.log(`${s.title}: ${s.thoughtCount} thoughts (${s.mode})`);
1612
+ * });
1613
+ * ```
1083
1614
  */
1084
1615
  async listSessions() {
1085
1616
  return Array.from(this.activeSessions.values()).map((session) => ({
@@ -1094,17 +1625,59 @@ var SessionManager = class {
1094
1625
  }
1095
1626
  /**
1096
1627
  * Delete a session
1628
+ *
1629
+ * Removes a session from memory. This operation cannot be undone.
1630
+ *
1631
+ * @param sessionId - ID of the session to delete
1632
+ * @returns Promise that resolves when deletion is complete
1633
+ *
1634
+ * @example
1635
+ * ```typescript
1636
+ * await manager.deleteSession('old-session-id');
1637
+ * ```
1097
1638
  */
1098
1639
  async deleteSession(sessionId) {
1099
- this.activeSessions.delete(sessionId);
1640
+ const session = this.activeSessions.get(sessionId);
1641
+ const deleted = this.activeSessions.delete(sessionId);
1642
+ if (deleted && session) {
1643
+ this.logger.info("Session deleted", {
1644
+ sessionId,
1645
+ title: session.title,
1646
+ thoughtCount: session.thoughts.length
1647
+ });
1648
+ } else {
1649
+ this.logger.warn("Attempted to delete non-existent session", { sessionId });
1650
+ }
1100
1651
  }
1101
1652
  /**
1102
- * Generate summary of session
1653
+ * Generate a text summary of a session
1654
+ *
1655
+ * Creates a markdown-formatted summary including:
1656
+ * - Session metadata (title, mode, status)
1657
+ * - Total thought count
1658
+ * - Key thoughts (first 100 characters of each)
1659
+ *
1660
+ * @param sessionId - ID of the session to summarize
1661
+ * @returns Promise resolving to markdown-formatted summary
1662
+ * @throws Error if session is not found
1663
+ *
1664
+ * @example
1665
+ * ```typescript
1666
+ * const summary = await manager.generateSummary(session.id);
1667
+ * console.log(summary);
1668
+ * // Output:
1669
+ * // # Mathematical Proof
1670
+ * // Mode: mathematics
1671
+ * // Total Thoughts: 15
1672
+ * // Status: Complete
1673
+ * // ...
1674
+ * ```
1103
1675
  */
1104
1676
  async generateSummary(sessionId) {
1677
+ validateSessionId(sessionId);
1105
1678
  const session = this.activeSessions.get(sessionId);
1106
1679
  if (!session) {
1107
- throw new Error(`Session ${sessionId} not found`);
1680
+ throw new SessionNotFoundError(sessionId);
1108
1681
  }
1109
1682
  let summary = `# ${session.title}
1110
1683
 
@@ -1126,17 +1699,22 @@ var SessionManager = class {
1126
1699
  return summary;
1127
1700
  }
1128
1701
  /**
1129
- * Merge configurations
1702
+ * Merge configurations (private helper)
1703
+ *
1704
+ * Combines default config, instance config, and user config
1705
+ * with proper precedence: user > instance > default
1130
1706
  */
1131
1707
  mergeConfig(userConfig) {
1132
1708
  return {
1133
- ...DEFAULT_CONFIG,
1709
+ ...DEFAULT_CONFIG2,
1134
1710
  ...this.config,
1135
1711
  ...userConfig
1136
1712
  };
1137
1713
  }
1138
1714
  /**
1139
- * Initialize metrics
1715
+ * Initialize metrics (private helper)
1716
+ *
1717
+ * Creates a fresh SessionMetrics object with zero values
1140
1718
  */
1141
1719
  initializeMetrics() {
1142
1720
  return {
@@ -1146,15 +1724,30 @@ var SessionManager = class {
1146
1724
  revisionCount: 0,
1147
1725
  timeSpent: 0,
1148
1726
  dependencyDepth: 0,
1149
- customMetrics: /* @__PURE__ */ new Map()
1727
+ customMetrics: /* @__PURE__ */ new Map(),
1728
+ cacheStats: {
1729
+ hits: 0,
1730
+ misses: 0,
1731
+ hitRate: 0,
1732
+ size: 0,
1733
+ maxSize: 0
1734
+ }
1150
1735
  };
1151
1736
  }
1152
1737
  /**
1153
- * Update session metrics
1738
+ * Update session metrics (private helper)
1739
+ *
1740
+ * Incrementally updates metrics using O(1) algorithms for performance.
1741
+ * Handles mode-specific metrics for temporal, game theory, and evidential modes.
1742
+ *
1743
+ * @param session - Session to update
1744
+ * @param thought - Newly added thought
1154
1745
  */
1155
1746
  updateMetrics(session, thought) {
1156
1747
  const metrics = session.metrics;
1157
1748
  metrics.totalThoughts = session.thoughts.length;
1749
+ const thoughtType = thought.type || "unknown";
1750
+ metrics.thoughtsByType[thoughtType] = (metrics.thoughtsByType[thoughtType] || 0) + 1;
1158
1751
  if (thought.isRevision) {
1159
1752
  metrics.revisionCount++;
1160
1753
  }
@@ -1235,6 +1828,22 @@ var SessionManager = class {
1235
1828
  metrics.customMetrics.set("decisions", thought.decisions.length);
1236
1829
  }
1237
1830
  }
1831
+ this.updateCacheStats(session);
1832
+ }
1833
+ /**
1834
+ * Update validation cache statistics in session metrics
1835
+ *
1836
+ * @param session - Session to update
1837
+ */
1838
+ updateCacheStats(session) {
1839
+ const cacheStats = validationCache.getStats();
1840
+ session.metrics.cacheStats = {
1841
+ hits: cacheStats.hits,
1842
+ misses: cacheStats.misses,
1843
+ hitRate: cacheStats.hitRate,
1844
+ size: cacheStats.size,
1845
+ maxSize: cacheStats.maxSize
1846
+ };
1238
1847
  }
1239
1848
  };
1240
1849
 
@@ -1682,6 +2291,52 @@ Bayes Factor: ${thought.bayesFactor.toFixed(2)}
1682
2291
  }
1683
2292
  };
1684
2293
 
2294
+ // src/utils/type-guards.ts
2295
+ var VALID_THOUGHT_TYPES = [
2296
+ "problem_definition",
2297
+ "constraints",
2298
+ "model",
2299
+ "proof",
2300
+ "implementation",
2301
+ "axiom_definition",
2302
+ "theorem_statement",
2303
+ "proof_construction",
2304
+ "lemma_derivation",
2305
+ "corollary",
2306
+ "counterexample",
2307
+ "algebraic_manipulation",
2308
+ "symbolic_computation",
2309
+ "numerical_analysis",
2310
+ "symmetry_analysis",
2311
+ "gauge_theory",
2312
+ "field_equations",
2313
+ "lagrangian",
2314
+ "hamiltonian",
2315
+ "conservation_law",
2316
+ "dimensional_analysis",
2317
+ "tensor_formulation",
2318
+ "differential_geometry",
2319
+ "decomposition",
2320
+ "synthesis",
2321
+ "abstraction",
2322
+ "analogy",
2323
+ "metacognition"
2324
+ ];
2325
+ function isExtendedThoughtType(value) {
2326
+ return typeof value === "string" && VALID_THOUGHT_TYPES.includes(value);
2327
+ }
2328
+ function toExtendedThoughtType(value, fallback) {
2329
+ if (isExtendedThoughtType(value)) {
2330
+ return value;
2331
+ }
2332
+ if (fallback !== void 0) {
2333
+ return fallback;
2334
+ }
2335
+ throw new Error(
2336
+ `Invalid ExtendedThoughtType: ${value}. Must be one of: ${VALID_THOUGHT_TYPES.join(", ")}`
2337
+ );
2338
+ }
2339
+
1685
2340
  // src/index.ts
1686
2341
  var __filename2 = fileURLToPath(import.meta.url);
1687
2342
  var __dirname2 = dirname(__filename2);
@@ -1948,7 +2603,7 @@ function createThought(input, sessionId) {
1948
2603
  return {
1949
2604
  ...baseThought,
1950
2605
  mode: "mathematics" /* MATHEMATICS */,
1951
- thoughtType: input.thoughtType,
2606
+ thoughtType: toExtendedThoughtType(input.thoughtType, "model"),
1952
2607
  mathematicalModel: input.mathematicalModel,
1953
2608
  proofStrategy: input.proofStrategy,
1954
2609
  dependencies: input.dependencies || [],
@@ -1959,7 +2614,7 @@ function createThought(input, sessionId) {
1959
2614
  return {
1960
2615
  ...baseThought,
1961
2616
  mode: "physics" /* PHYSICS */,
1962
- thoughtType: input.thoughtType,
2617
+ thoughtType: toExtendedThoughtType(input.thoughtType, "model"),
1963
2618
  tensorProperties: input.tensorProperties,
1964
2619
  physicalInterpretation: input.physicalInterpretation,
1965
2620
  dependencies: input.dependencies || [],
@@ -1970,7 +2625,7 @@ function createThought(input, sessionId) {
1970
2625
  return {
1971
2626
  ...baseThought,
1972
2627
  mode: "abductive" /* ABDUCTIVE */,
1973
- thoughtType: input.thoughtType,
2628
+ thoughtType: toExtendedThoughtType(input.thoughtType, "problem_definition"),
1974
2629
  observations: input.observations || [],
1975
2630
  hypotheses: input.hypotheses || [],
1976
2631
  evaluationCriteria: input.evaluationCriteria,
@@ -1981,7 +2636,7 @@ function createThought(input, sessionId) {
1981
2636
  return {
1982
2637
  ...baseThought,
1983
2638
  mode: "causal" /* CAUSAL */,
1984
- thoughtType: input.thoughtType,
2639
+ thoughtType: toExtendedThoughtType(input.thoughtType, "problem_definition"),
1985
2640
  causalGraph: input.causalGraph,
1986
2641
  interventions: input.interventions || [],
1987
2642
  mechanisms: input.mechanisms || [],
@@ -1991,7 +2646,7 @@ function createThought(input, sessionId) {
1991
2646
  return {
1992
2647
  ...baseThought,
1993
2648
  mode: "bayesian" /* BAYESIAN */,
1994
- thoughtType: input.thoughtType,
2649
+ thoughtType: toExtendedThoughtType(input.thoughtType, "problem_definition"),
1995
2650
  hypothesis: input.hypothesis,
1996
2651
  prior: input.prior,
1997
2652
  likelihood: input.likelihood,
@@ -2003,7 +2658,7 @@ function createThought(input, sessionId) {
2003
2658
  return {
2004
2659
  ...baseThought,
2005
2660
  mode: "counterfactual" /* COUNTERFACTUAL */,
2006
- thoughtType: input.thoughtType,
2661
+ thoughtType: toExtendedThoughtType(input.thoughtType, "problem_definition"),
2007
2662
  actual: input.actual,
2008
2663
  counterfactuals: input.counterfactuals || [],
2009
2664
  comparison: input.comparison,
@@ -2014,7 +2669,7 @@ function createThought(input, sessionId) {
2014
2669
  return {
2015
2670
  ...baseThought,
2016
2671
  mode: "analogical" /* ANALOGICAL */,
2017
- thoughtType: input.thoughtType,
2672
+ thoughtType: toExtendedThoughtType(input.thoughtType, "analogy"),
2018
2673
  sourceDomain: input.sourceDomain,
2019
2674
  targetDomain: input.targetDomain,
2020
2675
  mapping: input.mapping || [],
@@ -2027,7 +2682,7 @@ function createThought(input, sessionId) {
2027
2682
  return {
2028
2683
  ...baseThought,
2029
2684
  mode: "temporal" /* TEMPORAL */,
2030
- thoughtType: input.thoughtType,
2685
+ thoughtType: input.thoughtType || "event_definition",
2031
2686
  timeline: input.timeline,
2032
2687
  events: input.events || [],
2033
2688
  intervals: input.intervals || [],
@@ -2038,7 +2693,7 @@ function createThought(input, sessionId) {
2038
2693
  return {
2039
2694
  ...baseThought,
2040
2695
  mode: "gametheory" /* GAMETHEORY */,
2041
- thoughtType: input.thoughtType,
2696
+ thoughtType: input.thoughtType || "game_definition",
2042
2697
  game: input.game,
2043
2698
  players: input.players || [],
2044
2699
  strategies: input.strategies || [],
@@ -2051,7 +2706,7 @@ function createThought(input, sessionId) {
2051
2706
  return {
2052
2707
  ...baseThought,
2053
2708
  mode: "evidential" /* EVIDENTIAL */,
2054
- thoughtType: input.thoughtType,
2709
+ thoughtType: input.thoughtType || "hypothesis_definition",
2055
2710
  frameOfDiscernment: input.frameOfDiscernment,
2056
2711
  hypotheses: input.hypotheses || [],
2057
2712
  evidence: input.evidence || [],
@@ -2065,7 +2720,7 @@ function createThought(input, sessionId) {
2065
2720
  return {
2066
2721
  ...baseThought,
2067
2722
  mode: "hybrid" /* HYBRID */,
2068
- thoughtType: input.thoughtType,
2723
+ thoughtType: toExtendedThoughtType(input.thoughtType, "synthesis"),
2069
2724
  stage: input.stage,
2070
2725
  uncertainty: input.uncertainty,
2071
2726
  dependencies: input.dependencies,
@@ -2073,7 +2728,7 @@ function createThought(input, sessionId) {
2073
2728
  mathematicalModel: input.mathematicalModel,
2074
2729
  tensorProperties: input.tensorProperties,
2075
2730
  physicalInterpretation: input.physicalInterpretation,
2076
- primaryMode: input.mode,
2731
+ primaryMode: input.mode || "hybrid" /* HYBRID */,
2077
2732
  secondaryFeatures: []
2078
2733
  };
2079
2734
  }