tracelattice 1.3.2 → 1.3.3

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 (148) hide show
  1. package/README.md +25 -25
  2. package/dist/ServerConfig.d.ts +2 -23
  3. package/dist/ServerConfig.d.ts.map +1 -1
  4. package/dist/ServerConfig.js.map +1 -1
  5. package/dist/__tests__/eval/fixtures/scenarios.d.ts.map +1 -1
  6. package/dist/__tests__/helpers/factories.d.ts +13 -1
  7. package/dist/__tests__/helpers/factories.d.ts.map +1 -1
  8. package/dist/cache/DiscoveryCache.d.ts +1 -1
  9. package/dist/cache/DiscoveryCache.d.ts.map +1 -1
  10. package/dist/cache/DiscoveryCache.js.map +1 -1
  11. package/dist/cli.js +3483 -8
  12. package/dist/config/ConfigLoader.d.ts +2 -2
  13. package/dist/config/ConfigLoader.d.ts.map +1 -1
  14. package/dist/config/ConfigLoader.js +6 -4
  15. package/dist/config/ConfigLoader.js.map +1 -1
  16. package/dist/contracts/PersistenceBackend.d.ts.map +1 -0
  17. package/dist/contracts/features.d.ts +39 -0
  18. package/dist/contracts/features.d.ts.map +1 -0
  19. package/dist/contracts/features.js +15 -0
  20. package/dist/contracts/features.js.map +1 -0
  21. package/dist/contracts/ids.d.ts +58 -0
  22. package/dist/contracts/ids.d.ts.map +1 -0
  23. package/dist/contracts/ids.js +31 -0
  24. package/dist/contracts/ids.js.map +1 -0
  25. package/dist/contracts/interfaces.d.ts +6 -3
  26. package/dist/contracts/interfaces.d.ts.map +1 -1
  27. package/dist/contracts/strategy.d.ts +2 -2
  28. package/dist/contracts/strategy.d.ts.map +1 -1
  29. package/dist/contracts/suspension.d.ts +3 -2
  30. package/dist/contracts/suspension.d.ts.map +1 -1
  31. package/dist/contracts/transport.d.ts +25 -0
  32. package/dist/contracts/transport.d.ts.map +1 -0
  33. package/dist/core/HistoryManager.d.ts +2 -3
  34. package/dist/core/HistoryManager.d.ts.map +1 -1
  35. package/dist/core/HistoryManager.js.map +1 -1
  36. package/dist/core/IHistoryManager.d.ts +10 -0
  37. package/dist/core/IHistoryManager.d.ts.map +1 -1
  38. package/dist/core/IThoughtFormatter.d.ts +51 -0
  39. package/dist/core/IThoughtFormatter.d.ts.map +1 -0
  40. package/dist/core/IThoughtFormatter.js +1 -0
  41. package/dist/core/InputNormalizer.d.ts.map +1 -1
  42. package/dist/core/InputNormalizer.js +4 -3
  43. package/dist/core/InputNormalizer.js.map +1 -1
  44. package/dist/core/PersistenceBuffer.d.ts +1 -1
  45. package/dist/core/PersistenceBuffer.d.ts.map +1 -1
  46. package/dist/core/PersistenceBuffer.js.map +1 -1
  47. package/dist/core/ThoughtFormatter.d.ts +2 -1
  48. package/dist/core/ThoughtFormatter.d.ts.map +1 -1
  49. package/dist/core/ThoughtFormatter.js +3 -0
  50. package/dist/core/ThoughtFormatter.js.map +1 -1
  51. package/dist/core/ThoughtProcessor.d.ts +2 -2
  52. package/dist/core/ThoughtProcessor.d.ts.map +1 -1
  53. package/dist/core/ThoughtProcessor.js +8 -3
  54. package/dist/core/ThoughtProcessor.js.map +1 -1
  55. package/dist/core/compression/CompressionService.js +3 -3
  56. package/dist/core/compression/CompressionService.js.map +1 -1
  57. package/dist/core/compression/Summary.d.ts +4 -3
  58. package/dist/core/compression/Summary.d.ts.map +1 -1
  59. package/dist/core/graph/Edge.d.ts +11 -4
  60. package/dist/core/graph/Edge.d.ts.map +1 -1
  61. package/dist/core/graph/EdgeEmitter.js +5 -5
  62. package/dist/core/graph/EdgeEmitter.js.map +1 -1
  63. package/dist/core/reasoning/strategies/StrategyFactory.d.ts +1 -1
  64. package/dist/core/reasoning/strategies/StrategyFactory.d.ts.map +1 -1
  65. package/dist/core/reasoning/strategies/StrategyFactory.js.map +1 -1
  66. package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.d.ts.map +1 -1
  67. package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js +5 -0
  68. package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js.map +1 -1
  69. package/dist/core/reasoning.d.ts +8 -1
  70. package/dist/core/reasoning.d.ts.map +1 -1
  71. package/dist/core/step.d.ts +5 -0
  72. package/dist/core/step.d.ts.map +1 -1
  73. package/dist/core/thought.d.ts +4 -3
  74. package/dist/core/thought.d.ts.map +1 -1
  75. package/dist/core/tools/InMemorySuspensionStore.d.ts +3 -1
  76. package/dist/core/tools/InMemorySuspensionStore.d.ts.map +1 -1
  77. package/dist/core/tools/InMemorySuspensionStore.js +2 -2
  78. package/dist/core/tools/InMemorySuspensionStore.js.map +1 -1
  79. package/dist/di/Container.d.ts +6 -3
  80. package/dist/di/Container.d.ts.map +1 -1
  81. package/dist/di/Container.js.map +1 -1
  82. package/dist/di/ServiceRegistry.d.ts +3 -3
  83. package/dist/di/ServiceRegistry.d.ts.map +1 -1
  84. package/dist/errors.d.ts +36 -2
  85. package/dist/errors.d.ts.map +1 -1
  86. package/dist/errors.js +49 -22
  87. package/dist/errors.js.map +1 -1
  88. package/dist/health/HealthChecker.d.ts +1 -1
  89. package/dist/health/HealthChecker.d.ts.map +1 -1
  90. package/dist/health/HealthChecker.js.map +1 -1
  91. package/dist/lib.d.ts +60 -2
  92. package/dist/lib.d.ts.map +1 -1
  93. package/dist/lib.js.map +1 -1
  94. package/dist/persistence/FilePersistence.d.ts +2 -2
  95. package/dist/persistence/FilePersistence.d.ts.map +1 -1
  96. package/dist/persistence/FilePersistence.js.map +1 -1
  97. package/dist/persistence/MemoryPersistence.d.ts +1 -1
  98. package/dist/persistence/MemoryPersistence.d.ts.map +1 -1
  99. package/dist/persistence/MemoryPersistence.js.map +1 -1
  100. package/dist/persistence/PersistenceFactory.d.ts +1 -1
  101. package/dist/persistence/PersistenceFactory.d.ts.map +1 -1
  102. package/dist/persistence/PersistenceFactory.js.map +1 -1
  103. package/dist/persistence/SqlitePersistence.d.ts +1 -1
  104. package/dist/persistence/SqlitePersistence.d.ts.map +1 -1
  105. package/dist/persistence/SqlitePersistence.js.map +1 -1
  106. package/dist/pool/ConnectionPool.d.ts +11 -13
  107. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  108. package/dist/pool/ConnectionPool.js.map +1 -1
  109. package/dist/pool/IConnectionPool.d.ts +100 -0
  110. package/dist/pool/IConnectionPool.d.ts.map +1 -0
  111. package/dist/pool/IConnectionPool.js +1 -0
  112. package/dist/registry/BaseRegistry.d.ts +1 -1
  113. package/dist/registry/BaseRegistry.d.ts.map +1 -1
  114. package/dist/registry/BaseRegistry.js.map +1 -1
  115. package/dist/schema.d.ts.map +1 -1
  116. package/dist/schema.js.map +1 -1
  117. package/dist/transport/BaseTransport.d.ts +3 -2
  118. package/dist/transport/BaseTransport.d.ts.map +1 -1
  119. package/dist/transport/BaseTransport.js +1 -1
  120. package/dist/transport/BaseTransport.js.map +1 -1
  121. package/dist/transport/HttpTransport.d.ts +4 -2
  122. package/dist/transport/HttpTransport.d.ts.map +1 -1
  123. package/dist/transport/HttpTransport.js +4 -1
  124. package/dist/transport/HttpTransport.js.map +1 -1
  125. package/dist/transport/SseTransport.d.ts +4 -2
  126. package/dist/transport/SseTransport.d.ts.map +1 -1
  127. package/dist/transport/SseTransport.js +3 -0
  128. package/dist/transport/SseTransport.js.map +1 -1
  129. package/dist/transport/StreamableHttpTransport.d.ts +4 -2
  130. package/dist/transport/StreamableHttpTransport.d.ts.map +1 -1
  131. package/dist/transport/StreamableHttpTransport.js +4 -1
  132. package/dist/transport/StreamableHttpTransport.js.map +1 -1
  133. package/dist/types/skill.d.ts +5 -0
  134. package/dist/types/skill.d.ts.map +1 -1
  135. package/dist/types/tool.d.ts +5 -0
  136. package/dist/types/tool.d.ts.map +1 -1
  137. package/package.json +11 -11
  138. package/dist/__tests__/helpers/index.d.ts +0 -3
  139. package/dist/__tests__/helpers/index.d.ts.map +0 -1
  140. package/dist/contracts/index.d.ts +0 -14
  141. package/dist/contracts/index.d.ts.map +0 -1
  142. package/dist/index.d.ts +0 -2
  143. package/dist/index.d.ts.map +0 -1
  144. package/dist/index.js +0 -1
  145. package/dist/persistence/PersistenceBackend.d.ts.map +0 -1
  146. /package/dist/{persistence → contracts}/PersistenceBackend.d.ts +0 -0
  147. /package/dist/{persistence → contracts}/PersistenceBackend.js +0 -0
  148. /package/dist/contracts/{index.js → transport.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sources":["../src/errors.ts"],"sourcesContent":["/**\n * Custom error types for the TraceLattice server.\n *\n * This module defines a hierarchy of error classes for handling various\n * error conditions that can occur in the sequential thinking server.\n * All errors extend the base `SequentialThinkingError` class with\n * specific error codes for programmatic handling.\n *\n * @example\n * ```typescript\n * import { ToolNotFoundError, SkillDiscoveryError } from './errors.js';\n *\n * // Throw a tool not found error\n * throw new ToolNotFoundError('my-tool');\n *\n * // Catch and handle specific errors\n * try {\n * await discoverSkills(dir);\n * } catch (error) {\n * if (error instanceof SkillDiscoveryError) {\n * console.error(`Failed to discover skills: ${error.message}`);\n * console.error(`Error code: ${error.code}`);\n * }\n * }\n * ```\n * @module errors\n */\n\n/**\n * Base error class for all Sequential Thinking server errors.\n *\n * This error extends the native `Error` class and adds a `code` property\n * for programmatic error identification and handling. All specific error\n * types in the system extend this base class.\n *\n * @remarks\n * **Error Codes:**\n * - `TOOL_NOT_FOUND` - A requested tool was not found\n * - `SKILL_NOT_FOUND` - A requested skill was not found\n * - `INVALID_THOUGHT` - Thought validation failed\n * - `SKILL_DISCOVERY_FAILED` - Skill discovery operation failed\n * - `HISTORY_LIMIT_EXCEEDED` - History size limit was exceeded\n * - `INVALID_EDGE` - An invalid edge operation was attempted\n *\n * @example\n * ```typescript\n * // Throw a custom sequential thinking error\n * throw new SequentialThinkingError('Custom error message', 'CUSTOM_CODE');\n *\n * // Check if an error is a SequentialThinkingError\n * if (error instanceof SequentialThinkingError) {\n * console.error(`Error [${error.code}]: ${error.message}`);\n * }\n * ```\n */\nexport class SequentialThinkingError extends Error {\n\t/** The error code for programmatic identification. */\n\tpublic readonly code: string;\n\n\t/**\n\t * Creates a new SequentialThinkingError.\n\t *\n\t * @param message - Human-readable error message\n\t * @param code - Error code for programmatic handling\n\t *\n\t * @example\n\t * ```typescript\n\t * const error = new SequentialThinkingError(\n\t * 'Something went wrong',\n\t * 'CUSTOM_ERROR'\n\t * );\n\t * console.log(error.code); // 'CUSTOM_ERROR'\n\t * ```\n\t */\n\tconstructor(message: string, code: string) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t\tthis.name = 'SequentialThinkingError';\n\t\tError.captureStackTrace(this, this.constructor);\n\t}\n}\n\nexport class ConfigurationError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, 'CONFIGURATION_ERROR');\n\t\tthis.name = 'ConfigurationError';\n\t}\n}\n\n/**\n * Error thrown when a requested tool is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a tool that doesn't exist in the tool registry.\n *\n * @example\n * ```typescript\n * const tool = registry.getTool('non-existent-tool');\n * if (!tool) {\n * throw new ToolNotFoundError('non-existent-tool');\n * }\n * ```\n */\nexport class ToolNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new ToolNotFoundError.\n\t *\n\t * @param toolName - The name of the tool that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new ToolNotFoundError('my-custom-tool');\n\t * // Error: tool 'my-custom-tool' not found\n\t *\n\t * throw new ToolNotFoundError('my-custom-tool', 'remove');\n\t * // Error: tool 'my-custom-tool' not found, cannot remove\n\t * // Code: TOOL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(toolName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Tool '${toolName}' not found, cannot ${action}`\n\t\t\t: `Tool '${toolName}' not found`;\n\t\tsuper(message, 'TOOL_NOT_FOUND');\n\t\tthis.name = 'ToolNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a requested skill is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a skill that doesn't exist in the skill registry.\n *\n * @example\n * ```typescript\n * const skill = registry.getSkill('non-existent-skill');\n * if (!skill) {\n * throw new SkillNotFoundError('non-existent-skill');\n * }\n * ```\n */\nexport class SkillNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SkillNotFoundError.\n\t *\n\t * @param skillName - The name of the skill that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SkillNotFoundError('my-custom-skill');\n\t * // Error: skill 'my-custom-skill' not found\n\t *\n\t * throw new SkillNotFoundError('my-custom-skill', 'remove');\n\t * // Error: skill 'my-custom-skill' not found, cannot remove\n\t * // Code: SKILL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(skillName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Skill '${skillName}' not found, cannot ${action}`\n\t\t\t: `Skill '${skillName}' not found`;\n\t\tsuper(message, 'SKILL_NOT_FOUND');\n\t\tthis.name = 'SkillNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when thought validation fails.\n *\n * This error is thrown when a thought fails validation, typically due to\n * invalid values, missing required fields, or constraint violations.\n *\n * @example\n * ```typescript\n * // Validate thought number\n * if (thought.thought_number < 1) {\n * throw new InvalidThoughtError(thought.thought_number, 'thought_number must be >= 1');\n * }\n * ```\n */\nexport class InvalidThoughtError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidThoughtError.\n\t *\n\t * @param thoughtNumber - The thought number that failed validation\n\t * @param reason - Human-readable explanation of why validation failed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidThoughtError(5, 'thought_number exceeds total_thoughts');\n\t * // Error: Invalid thought 5: thought_number exceeds total_thoughts\n\t * // Code: INVALID_THOUGHT\n\t * ```\n\t */\n\tconstructor(thoughtNumber: number, reason: string) {\n\t\tsuper(`Invalid thought ${thoughtNumber}: ${reason}`, 'INVALID_THOUGHT');\n\t\tthis.name = 'InvalidThoughtError';\n\t}\n}\n\n/**\n * Error thrown when skill discovery fails.\n *\n * This error is thrown when the skill discovery process encounters an issue,\n * such as filesystem errors, invalid skill files, or parsing failures.\n *\n * @remarks\n * The original error that caused the discovery failure is preserved in the\n * `cause` property for debugging purposes.\n *\n * @example\n * ```typescript\n * try {\n * await discoverSkills('./skills');\n * } catch (error) {\n * throw new SkillDiscoveryError('./skills', error as Error);\n * }\n * ```\n */\nexport class SkillDiscoveryError extends SequentialThinkingError {\n\t/** The underlying error that caused the discovery failure. */\n\tpublic override readonly cause: Error;\n\n\t/**\n\t * Creates a new SkillDiscoveryError.\n\t *\n\t * @param directory - The directory where discovery failed\n\t * @param cause - The underlying error that caused the failure\n\t *\n\t * @example\n\t * ```typescript\n\t * try {\n\t * const skills = await loadSkills('./invalid-directory');\n\t * } catch (error) {\n\t * throw new SkillDiscoveryError('./invalid-directory', error as Error);\n\t * }\n\t * ```\n\t */\n\tconstructor(directory: string, cause: Error) {\n\t\tsuper(`Failed to discover skills in ${directory}: ${cause.message}`, 'SKILL_DISCOVERY_FAILED');\n\t\tthis.name = 'SkillDiscoveryError';\n\t\tthis.cause = cause;\n\t}\n}\n\n/**\n * Error thrown when history size exceeds the configured limit.\n *\n * This error is thrown when an operation would cause the history size\n * to exceed the maximum configured size limit.\n *\n * @example\n * ```typescript\n * if (history.length >= maxSize) {\n * throw new HistoryLimitExceededError(history.length, maxSize);\n * }\n * ```\n */\nexport class HistoryLimitExceededError extends SequentialThinkingError {\n\t/**\n\t * Creates a new HistoryLimitExceededError.\n\t *\n\t * @param currentSize - The current history size\n\t * @param maxSize - The maximum allowed size\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new HistoryLimitExceededError(1500, 1000);\n\t * // Error: History size 1500 exceeds limit 1000\n\t * // Code: HISTORY_LIMIT_EXCEEDED\n\t * ```\n\t */\n\tconstructor(currentSize: number, maxSize: number) {\n\t\tsuper(`History size ${currentSize} exceeds limit ${maxSize}`, 'HISTORY_LIMIT_EXCEEDED');\n\t\tthis.name = 'HistoryLimitExceededError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a skill that already exists.\n *\n * This error is thrown when trying to register a skill with a name that\n * is already present in the skill registry.\n *\n * @example\n * ```typescript\n * if (registry.hasSkill(skill.name)) {\n * throw new DuplicateSkillError(skill.name);\n * }\n * ```\n */\nexport class DuplicateSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateSkillError.\n\t *\n\t * @param skillName - The name of the duplicate skill\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateSkillError('my-skill');\n\t * // Error: skill 'my-skill' already exists\n\t * // Code: DUPLICATE_SKILL\n\t * ```\n\t */\n\tconstructor(skillName: string) {\n\t\tsuper(`skill '${skillName}' already exists`, 'DUPLICATE_SKILL');\n\t\tthis.name = 'DuplicateSkillError';\n\t}\n}\n\n/**\n * Error thrown when a skill has invalid data.\n *\n * This error is thrown when a skill fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!skill.name) {\n * throw new InvalidSkillError('Skill must have a valid name');\n * }\n * ```\n */\nexport class InvalidSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidSkillError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidSkillError('Skill must have a valid name');\n\t * // Error: Invalid skill: Skill must have a valid name\n\t * // Code: INVALID_SKILL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid skill: ${reason}`, 'INVALID_SKILL');\n\t\tthis.name = 'InvalidSkillError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a tool that already exists.\n *\n * This error is thrown when trying to register a tool with a name that\n * is already present in the tool registry.\n *\n * @example\n * ```typescript\n * if (registry.hasTool(tool.name)) {\n * throw new DuplicateToolError(tool.name);\n * }\n * ```\n */\nexport class DuplicateToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateToolError.\n\t *\n\t * @param toolName - The name of the duplicate tool\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateToolError('my-tool');\n\t * // Error: tool 'my-tool' already exists\n\t * // Code: DUPLICATE_TOOL\n\t * ```\n\t */\n\tconstructor(toolName: string) {\n\t\tsuper(`tool '${toolName}' already exists`, 'DUPLICATE_TOOL');\n\t\tthis.name = 'DuplicateToolError';\n\t}\n}\n\n/**\n * Error thrown when a tool has invalid data.\n *\n * This error is thrown when a tool fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!tool.name) {\n * throw new InvalidToolError('Tool must have a valid name');\n * }\n * ```\n */\nexport class InvalidToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidToolError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidToolError('Tool must have a valid name');\n\t * // Error: Invalid tool: Tool must have a valid name\n\t * // Code: INVALID_TOOL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid tool: ${reason}`, 'INVALID_TOOL');\n\t\tthis.name = 'InvalidToolError';\n\t}\n}\n\n/**\n * Error thrown when attempting to process a session that is not active.\n *\n * This error is thrown when trying to use a session that has been closed\n * or deactivated.\n *\n * @example\n * ```typescript\n * if (!session.isActive) {\n * throw new SessionNotActiveError(sessionId);\n * }\n * ```\n */\nexport class SessionNotActiveError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SessionNotActiveError.\n\t *\n\t * @param sessionId - The ID of the inactive session\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SessionNotActiveError('session-123');\n\t * // Error: Session 'session-123' is not active\n\t * // Code: SESSION_NOT_ACTIVE\n\t * ```\n\t */\n\tconstructor(sessionId: string) {\n\t\tsuper(`Session '${sessionId}' is not active`, 'SESSION_NOT_ACTIVE');\n\t\tthis.name = 'SessionNotActiveError';\n\t}\n}\n\n/**\n * Error thrown when a requested session is not found in the pool.\n *\n * This error is thrown when attempting to retrieve, process, or close\n * a session that doesn't exist in the session pool.\n *\n * @example\n * ```typescript\n * const session = pool.getSession('non-existent-session');\n * if (!session) {\n * throw new SessionNotFoundError('non-existent-session');\n * }\n * ```\n */\nexport class SessionNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SessionNotFoundError.\n\t *\n\t * @param sessionId - The ID of the session that was not found\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SessionNotFoundError('session-123');\n\t * // Error: Session not found: session-123\n\t * // Code: SESSION_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(sessionId: string) {\n\t\tsuper(`Session not found: ${sessionId}`, 'SESSION_NOT_FOUND');\n\t\tthis.name = 'SessionNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when the maximum number of sessions has been reached.\n *\n * This error is thrown when trying to create a new session when the\n * pool has reached its configured maximum session limit.\n *\n * @example\n * ```typescript\n * if (pool.sessionCount >= pool.maxSessions) {\n * throw new MaxSessionsReachedError(pool.maxSessions);\n * }\n * ```\n */\nexport class MaxSessionsReachedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new MaxSessionsReachedError.\n\t *\n\t * @param maxSessions - The maximum number of sessions allowed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new MaxSessionsReachedError(100);\n\t * // Error: Max sessions (100) reached. Wait for a session to close or increase maxSessions.\n\t * // Code: MAX_SESSIONS_REACHED\n\t * ```\n\t */\n\tconstructor(maxSessions: number) {\n\t\tsuper(\n\t\t\t`Max sessions (${maxSessions}) reached. Wait for a session to close or increase maxSessions.`,\n\t\t\t'MAX_SESSIONS_REACHED'\n\t\t);\n\t\tthis.name = 'MaxSessionsReachedError';\n\t}\n}\n\n/**\n * Error thrown when attempting to use a terminated connection pool.\n *\n * This error is thrown when trying to create sessions or process requests\n * after the connection pool has been terminated.\n *\n * @example\n * ```typescript\n * if (pool.isTerminated) {\n * throw new PoolTerminatedError();\n * }\n * ```\n */\nexport class PoolTerminatedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new PoolTerminatedError.\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new PoolTerminatedError();\n\t * // Error: ConnectionPool has been terminated\n\t * // Code: POOL_TERMINATED\n\t * ```\n\t */\n\tconstructor() {\n\t\tsuper('ConnectionPool has been terminated', 'POOL_TERMINATED');\n\t\tthis.name = 'PoolTerminatedError';\n\t}\n}\n\n/**\n * Error thrown when input validation fails due to invalid or malicious data.\n *\n * This error is thrown when user input fails security or format validation,\n * such as path traversal attempts or invalid identifier formats.\n *\n * @example\n * ```typescript\n * if (!BRANCH_ID_PATTERN.test(branchId)) {\n * throw new ValidationError('branchId', 'Invalid format');\n * }\n * ```\n */\nexport class ValidationError extends SequentialThinkingError {\n\t/** The field that failed validation. */\n\tpublic readonly field: string;\n\n\tconstructor(field: string, reason: string) {\n\t\tsuper(`Validation failed for '${field}': ${reason}`, 'VALIDATION_ERROR');\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t}\n}\n\n/**\n * Error thrown when an invalid edge operation is attempted.\n *\n * This error is thrown when attempting to add an edge that violates\n * structural invariants of the thought DAG, such as a self-edge\n * (where `from` and `to` reference the same thought).\n *\n * @example\n * ```typescript\n * if (edge.from === edge.to) {\n * throw new InvalidEdgeError(\n * `Self-edge not allowed: from and to are the same (${edge.from})`\n * );\n * }\n * ```\n */\nexport class InvalidEdgeError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidEdgeError.\n\t *\n\t * @param message - Human-readable explanation of the invalid edge\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidEdgeError('Self-edge not allowed: from and to are the same (t1)');\n\t * // Code: INVALID_EDGE\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, 'INVALID_EDGE');\n\t\tthis.name = 'InvalidEdgeError';\n\t}\n}\n\n/**\n * Error thrown when a cycle is detected during graph traversal.\n *\n * This error is thrown by graph algorithms (such as topological sort)\n * when the thought DAG contains a cycle, violating the acyclic invariant.\n *\n * @example\n * ```typescript\n * try {\n * const order = graphView.topological(sessionId);\n * } catch (error) {\n * if (error instanceof CycleDetectedError) {\n * console.error('Cycle in thought graph:', error.message);\n * }\n * }\n * ```\n */\nexport class CycleDetectedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new CycleDetectedError.\n\t *\n\t * @param message - Human-readable explanation of the cycle\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new CycleDetectedError('Cycle detected in session s1');\n\t * // Code: CYCLE_DETECTED\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, 'CYCLE_DETECTED');\n\t\tthis.name = 'CycleDetectedError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record is not found.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension that does not exist in the suspension store.\n */\nexport class SuspensionNotFoundError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, 'SUSPENSION_NOT_FOUND');\n\t\tthis.name = 'SuspensionNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record has expired.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension whose TTL has elapsed.\n */\nexport class SuspensionExpiredError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, 'SUSPENSION_EXPIRED');\n\t\tthis.name = 'SuspensionExpiredError';\n\t}\n}\n\n/**\n * Error thrown when a tool call payload is invalid.\n *\n * This error is thrown when a tool interleave invocation has malformed\n * arguments, missing identifiers, or otherwise fails validation.\n */\nexport class InvalidToolCallError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, 'INVALID_TOOL_CALL');\n\t\tthis.name = 'InvalidToolCallError';\n\t}\n}\n\n/**\n * Error thrown when a backtrack operation is invalid.\n *\n * This error is thrown when an attempt to backtrack the reasoning\n * chain references an unreachable thought or violates DAG invariants.\n */\nexport class InvalidBacktrackError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, 'INVALID_BACKTRACK');\n\t\tthis.name = 'InvalidBacktrackError';\n\t}\n}\n\n/**\n * Extract a human-readable message from an unknown error value.\n *\n * Standardizes the common `error instanceof Error ? error.message : String(error)`\n * pattern used in catch blocks across the codebase.\n *\n * @param error - The unknown error value to extract a message from\n * @returns The error message string\n *\n * @example\n * ```typescript\n * try {\n * await doSomething();\n * } catch (error) {\n * logger.error('Failed', { error: getErrorMessage(error) });\n * }\n * ```\n */\nexport function getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],"names":["SequentialThinkingError","Error","message","code","ConfigurationError","ToolNotFoundError","toolName","action","SkillNotFoundError","skillName","InvalidThoughtError","thoughtNumber","reason","SkillDiscoveryError","directory","cause","HistoryLimitExceededError","currentSize","maxSize","DuplicateSkillError","InvalidSkillError","DuplicateToolError","InvalidToolError","SessionNotActiveError","sessionId","SessionNotFoundError","MaxSessionsReachedError","maxSessions","PoolTerminatedError","ValidationError","field","InvalidEdgeError","CycleDetectedError","SuspensionNotFoundError","SuspensionExpiredError","InvalidToolCallError","InvalidBacktrackError","getErrorMessage","error","String"],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sources":["../src/errors.ts"],"sourcesContent":["/**\n * Custom error types for the TraceLattice server.\n *\n * This module defines a hierarchy of error classes for handling various\n * error conditions that can occur in the sequential thinking server.\n * All errors extend the base `SequentialThinkingError` class with\n * specific error codes for programmatic handling.\n *\n * @example\n * ```typescript\n * import { ToolNotFoundError, SkillDiscoveryError } from './errors.js';\n *\n * // Throw a tool not found error\n * throw new ToolNotFoundError('my-tool');\n *\n * // Catch and handle specific errors\n * try {\n * await discoverSkills(dir);\n * } catch (error) {\n * if (error instanceof SkillDiscoveryError) {\n * console.error(`Failed to discover skills: ${error.message}`);\n * console.error(`Error code: ${error.code}`);\n * }\n * }\n * ```\n * @module errors\n */\n\n/**\n * All known error codes as a const object for exhaustive switching.\n */\nexport const ERROR_CODES = {\n\tCONFIGURATION_ERROR: 'CONFIGURATION_ERROR',\n\tTOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n\tSKILL_NOT_FOUND: 'SKILL_NOT_FOUND',\n\tINVALID_THOUGHT: 'INVALID_THOUGHT',\n\tSKILL_DISCOVERY_FAILED: 'SKILL_DISCOVERY_FAILED',\n\tHISTORY_LIMIT_EXCEEDED: 'HISTORY_LIMIT_EXCEEDED',\n\tDUPLICATE_SKILL: 'DUPLICATE_SKILL',\n\tINVALID_SKILL: 'INVALID_SKILL',\n\tDUPLICATE_TOOL: 'DUPLICATE_TOOL',\n\tINVALID_TOOL: 'INVALID_TOOL',\n\tSESSION_NOT_ACTIVE: 'SESSION_NOT_ACTIVE',\n\tSESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n\tMAX_SESSIONS_REACHED: 'MAX_SESSIONS_REACHED',\n\tPOOL_TERMINATED: 'POOL_TERMINATED',\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_EDGE: 'INVALID_EDGE',\n\tCYCLE_DETECTED: 'CYCLE_DETECTED',\n\tSUSPENSION_NOT_FOUND: 'SUSPENSION_NOT_FOUND',\n\tSUSPENSION_EXPIRED: 'SUSPENSION_EXPIRED',\n\tINVALID_TOOL_CALL: 'INVALID_TOOL_CALL',\n\tINVALID_BACKTRACK: 'INVALID_BACKTRACK',\n\tDUPLICATE_SUMMARY: 'DUPLICATE_SUMMARY',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Base error class for all Sequential Thinking server errors.\n *\n * This error extends the native `Error` class and adds a `code` property\n * for programmatic error identification and handling. All specific error\n * types in the system extend this base class.\n *\n * @remarks\n * **Error Codes:**\n * - `TOOL_NOT_FOUND` - A requested tool was not found\n * - `SKILL_NOT_FOUND` - A requested skill was not found\n * - `INVALID_THOUGHT` - Thought validation failed\n * - `SKILL_DISCOVERY_FAILED` - Skill discovery operation failed\n * - `HISTORY_LIMIT_EXCEEDED` - History size limit was exceeded\n * - `INVALID_EDGE` - An invalid edge operation was attempted\n *\n * @example\n * ```typescript\n * // Throw a custom sequential thinking error\n * throw new SequentialThinkingError('Custom error message', 'CUSTOM_CODE');\n *\n * // Check if an error is a SequentialThinkingError\n * if (error instanceof SequentialThinkingError) {\n * console.error(`Error [${error.code}]: ${error.message}`);\n * }\n * ```\n */\nexport class SequentialThinkingError extends Error {\n\t/** The error code for programmatic identification. */\n\tpublic readonly code: ErrorCode;\n\n\t/**\n\t * Creates a new SequentialThinkingError.\n\t *\n\t * @param message - Human-readable error message\n\t * @param code - Error code for programmatic handling\n\t *\n\t * @example\n\t * ```typescript\n\t * const error = new SequentialThinkingError(\n\t * 'Something went wrong',\n\t * 'CUSTOM_ERROR'\n\t * );\n\t * console.log(error.code); // 'CUSTOM_ERROR'\n\t * ```\n\t */\n\tconstructor(message: string, code: ErrorCode) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t\tthis.name = 'SequentialThinkingError';\n\t\tError.captureStackTrace(this, this.constructor);\n\t}\n}\n\nexport class ConfigurationError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.CONFIGURATION_ERROR);\n\t\tthis.name = 'ConfigurationError';\n\t}\n}\n\n/**\n * Error thrown when a requested tool is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a tool that doesn't exist in the tool registry.\n *\n * @example\n * ```typescript\n * const tool = registry.getTool('non-existent-tool');\n * if (!tool) {\n * throw new ToolNotFoundError('non-existent-tool');\n * }\n * ```\n */\nexport class ToolNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new ToolNotFoundError.\n\t *\n\t * @param toolName - The name of the tool that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new ToolNotFoundError('my-custom-tool');\n\t * // Error: tool 'my-custom-tool' not found\n\t *\n\t * throw new ToolNotFoundError('my-custom-tool', 'remove');\n\t * // Error: tool 'my-custom-tool' not found, cannot remove\n\t * // Code: TOOL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(toolName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Tool '${toolName}' not found, cannot ${action}`\n\t\t\t: `Tool '${toolName}' not found`;\n\t\tsuper(message, ERROR_CODES.TOOL_NOT_FOUND);\n\t\tthis.name = 'ToolNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a requested skill is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a skill that doesn't exist in the skill registry.\n *\n * @example\n * ```typescript\n * const skill = registry.getSkill('non-existent-skill');\n * if (!skill) {\n * throw new SkillNotFoundError('non-existent-skill');\n * }\n * ```\n */\nexport class SkillNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SkillNotFoundError.\n\t *\n\t * @param skillName - The name of the skill that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SkillNotFoundError('my-custom-skill');\n\t * // Error: skill 'my-custom-skill' not found\n\t *\n\t * throw new SkillNotFoundError('my-custom-skill', 'remove');\n\t * // Error: skill 'my-custom-skill' not found, cannot remove\n\t * // Code: SKILL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(skillName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Skill '${skillName}' not found, cannot ${action}`\n\t\t\t: `Skill '${skillName}' not found`;\n\t\tsuper(message, ERROR_CODES.SKILL_NOT_FOUND);\n\t\tthis.name = 'SkillNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when thought validation fails.\n *\n * This error is thrown when a thought fails validation, typically due to\n * invalid values, missing required fields, or constraint violations.\n *\n * @example\n * ```typescript\n * // Validate thought number\n * if (thought.thought_number < 1) {\n * throw new InvalidThoughtError(thought.thought_number, 'thought_number must be >= 1');\n * }\n * ```\n */\nexport class InvalidThoughtError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidThoughtError.\n\t *\n\t * @param thoughtNumber - The thought number that failed validation\n\t * @param reason - Human-readable explanation of why validation failed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidThoughtError(5, 'thought_number exceeds total_thoughts');\n\t * // Error: Invalid thought 5: thought_number exceeds total_thoughts\n\t * // Code: INVALID_THOUGHT\n\t * ```\n\t */\n\tconstructor(thoughtNumber: number, reason: string) {\n\t\tsuper(`Invalid thought ${thoughtNumber}: ${reason}`, ERROR_CODES.INVALID_THOUGHT);\n\t\tthis.name = 'InvalidThoughtError';\n\t}\n}\n\n/**\n * Error thrown when skill discovery fails.\n *\n * This error is thrown when the skill discovery process encounters an issue,\n * such as filesystem errors, invalid skill files, or parsing failures.\n *\n * @remarks\n * The original error that caused the discovery failure is preserved in the\n * `cause` property for debugging purposes.\n *\n * @example\n * ```typescript\n * try {\n * await discoverSkills('./skills');\n * } catch (error) {\n * throw new SkillDiscoveryError('./skills', error as Error);\n * }\n * ```\n */\nexport class SkillDiscoveryError extends SequentialThinkingError {\n\t/** The underlying error that caused the discovery failure. */\n\tpublic override readonly cause: Error;\n\n\t/**\n\t * Creates a new SkillDiscoveryError.\n\t *\n\t * @param directory - The directory where discovery failed\n\t * @param cause - The underlying error that caused the failure\n\t *\n\t * @example\n\t * ```typescript\n\t * try {\n\t * const skills = await loadSkills('./invalid-directory');\n\t * } catch (error) {\n\t * throw new SkillDiscoveryError('./invalid-directory', error as Error);\n\t * }\n\t * ```\n\t */\n\tconstructor(directory: string, cause: Error) {\n\t\tsuper(\n\t\t\t`Failed to discover skills in ${directory}: ${cause.message}`,\n\t\t\tERROR_CODES.SKILL_DISCOVERY_FAILED,\n\t\t);\n\t\tthis.name = 'SkillDiscoveryError';\n\t\tthis.cause = cause;\n\t}\n}\n\n/**\n * Error thrown when history size exceeds the configured limit.\n *\n * This error is thrown when an operation would cause the history size\n * to exceed the maximum configured size limit.\n *\n * @example\n * ```typescript\n * if (history.length >= maxSize) {\n * throw new HistoryLimitExceededError(history.length, maxSize);\n * }\n * ```\n */\nexport class HistoryLimitExceededError extends SequentialThinkingError {\n\t/**\n\t * Creates a new HistoryLimitExceededError.\n\t *\n\t * @param currentSize - The current history size\n\t * @param maxSize - The maximum allowed size\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new HistoryLimitExceededError(1500, 1000);\n\t * // Error: History size 1500 exceeds limit 1000\n\t * // Code: HISTORY_LIMIT_EXCEEDED\n\t * ```\n\t */\n\tconstructor(currentSize: number, maxSize: number) {\n\t\tsuper(`History size ${currentSize} exceeds limit ${maxSize}`, ERROR_CODES.HISTORY_LIMIT_EXCEEDED);\n\t\tthis.name = 'HistoryLimitExceededError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a skill that already exists.\n *\n * This error is thrown when trying to register a skill with a name that\n * is already present in the skill registry.\n *\n * @example\n * ```typescript\n * if (registry.hasSkill(skill.name)) {\n * throw new DuplicateSkillError(skill.name);\n * }\n * ```\n */\nexport class DuplicateSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateSkillError.\n\t *\n\t * @param skillName - The name of the duplicate skill\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateSkillError('my-skill');\n\t * // Error: skill 'my-skill' already exists\n\t * // Code: DUPLICATE_SKILL\n\t * ```\n\t */\n\tconstructor(skillName: string) {\n\t\tsuper(`skill '${skillName}' already exists`, ERROR_CODES.DUPLICATE_SKILL);\n\t\tthis.name = 'DuplicateSkillError';\n\t}\n}\n\n/**\n * Error thrown when a skill has invalid data.\n *\n * This error is thrown when a skill fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!skill.name) {\n * throw new InvalidSkillError('Skill must have a valid name');\n * }\n * ```\n */\nexport class InvalidSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidSkillError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidSkillError('Skill must have a valid name');\n\t * // Error: Invalid skill: Skill must have a valid name\n\t * // Code: INVALID_SKILL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid skill: ${reason}`, ERROR_CODES.INVALID_SKILL);\n\t\tthis.name = 'InvalidSkillError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a tool that already exists.\n *\n * This error is thrown when trying to register a tool with a name that\n * is already present in the tool registry.\n *\n * @example\n * ```typescript\n * if (registry.hasTool(tool.name)) {\n * throw new DuplicateToolError(tool.name);\n * }\n * ```\n */\nexport class DuplicateToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateToolError.\n\t *\n\t * @param toolName - The name of the duplicate tool\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateToolError('my-tool');\n\t * // Error: tool 'my-tool' already exists\n\t * // Code: DUPLICATE_TOOL\n\t * ```\n\t */\n\tconstructor(toolName: string) {\n\t\tsuper(`tool '${toolName}' already exists`, ERROR_CODES.DUPLICATE_TOOL);\n\t\tthis.name = 'DuplicateToolError';\n\t}\n}\n\n/**\n * Error thrown when a tool has invalid data.\n *\n * This error is thrown when a tool fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!tool.name) {\n * throw new InvalidToolError('Tool must have a valid name');\n * }\n * ```\n */\nexport class InvalidToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidToolError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidToolError('Tool must have a valid name');\n\t * // Error: Invalid tool: Tool must have a valid name\n\t * // Code: INVALID_TOOL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid tool: ${reason}`, ERROR_CODES.INVALID_TOOL);\n\t\tthis.name = 'InvalidToolError';\n\t}\n}\n\n/**\n * Error thrown when attempting to process a session that is not active.\n *\n * This error is thrown when trying to use a session that has been closed\n * or deactivated.\n *\n * @example\n * ```typescript\n * if (!session.isActive) {\n * throw new SessionNotActiveError(sessionId);\n * }\n * ```\n */\nexport class SessionNotActiveError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SessionNotActiveError.\n\t *\n\t * @param sessionId - The ID of the inactive session\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SessionNotActiveError('session-123');\n\t * // Error: Session 'session-123' is not active\n\t * // Code: SESSION_NOT_ACTIVE\n\t * ```\n\t */\n\tconstructor(sessionId: string) {\n\t\tsuper(`Session '${sessionId}' is not active`, ERROR_CODES.SESSION_NOT_ACTIVE);\n\t\tthis.name = 'SessionNotActiveError';\n\t}\n}\n\n/**\n * Error thrown when a requested session is not found in the pool.\n *\n * This error is thrown when attempting to retrieve, process, or close\n * a session that doesn't exist in the session pool.\n *\n * @example\n * ```typescript\n * const session = pool.getSession('non-existent-session');\n * if (!session) {\n * throw new SessionNotFoundError('non-existent-session');\n * }\n * ```\n */\nexport class SessionNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SessionNotFoundError.\n\t *\n\t * @param sessionId - The ID of the session that was not found\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SessionNotFoundError('session-123');\n\t * // Error: Session not found: session-123\n\t * // Code: SESSION_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(sessionId: string) {\n\t\tsuper(`Session not found: ${sessionId}`, ERROR_CODES.SESSION_NOT_FOUND);\n\t\tthis.name = 'SessionNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when the maximum number of sessions has been reached.\n *\n * This error is thrown when trying to create a new session when the\n * pool has reached its configured maximum session limit.\n *\n * @example\n * ```typescript\n * if (pool.sessionCount >= pool.maxSessions) {\n * throw new MaxSessionsReachedError(pool.maxSessions);\n * }\n * ```\n */\nexport class MaxSessionsReachedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new MaxSessionsReachedError.\n\t *\n\t * @param maxSessions - The maximum number of sessions allowed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new MaxSessionsReachedError(100);\n\t * // Error: Max sessions (100) reached. Wait for a session to close or increase maxSessions.\n\t * // Code: MAX_SESSIONS_REACHED\n\t * ```\n\t */\n\tconstructor(maxSessions: number) {\n\t\tsuper(\n\t\t\t`Max sessions (${maxSessions}) reached. Wait for a session to close or increase maxSessions.`,\n\t\t\tERROR_CODES.MAX_SESSIONS_REACHED,\n\t\t);\n\t\tthis.name = 'MaxSessionsReachedError';\n\t}\n}\n\n/**\n * Error thrown when attempting to use a terminated connection pool.\n *\n * This error is thrown when trying to create sessions or process requests\n * after the connection pool has been terminated.\n *\n * @example\n * ```typescript\n * if (pool.isTerminated) {\n * throw new PoolTerminatedError();\n * }\n * ```\n */\nexport class PoolTerminatedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new PoolTerminatedError.\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new PoolTerminatedError();\n\t * // Error: ConnectionPool has been terminated\n\t * // Code: POOL_TERMINATED\n\t * ```\n\t */\n\tconstructor() {\n\t\tsuper('ConnectionPool has been terminated', ERROR_CODES.POOL_TERMINATED);\n\t\tthis.name = 'PoolTerminatedError';\n\t}\n}\n\n/**\n * Error thrown when input validation fails due to invalid or malicious data.\n *\n * This error is thrown when user input fails security or format validation,\n * such as path traversal attempts or invalid identifier formats.\n *\n * @example\n * ```typescript\n * if (!BRANCH_ID_PATTERN.test(branchId)) {\n * throw new ValidationError('branchId', 'Invalid format');\n * }\n * ```\n */\nexport class ValidationError extends SequentialThinkingError {\n\t/** The field that failed validation. */\n\tpublic readonly field: string;\n\n\tconstructor(field: string, reason: string) {\n\t\tsuper(`Validation failed for '${field}': ${reason}`, ERROR_CODES.VALIDATION_ERROR);\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t}\n}\n\n/**\n * Error thrown when an invalid edge operation is attempted.\n *\n * This error is thrown when attempting to add an edge that violates\n * structural invariants of the thought DAG, such as a self-edge\n * (where `from` and `to` reference the same thought).\n *\n * @example\n * ```typescript\n * if (edge.from === edge.to) {\n * throw new InvalidEdgeError(\n * `Self-edge not allowed: from and to are the same (${edge.from})`\n * );\n * }\n * ```\n */\nexport class InvalidEdgeError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidEdgeError.\n\t *\n\t * @param message - Human-readable explanation of the invalid edge\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidEdgeError('Self-edge not allowed: from and to are the same (t1)');\n\t * // Code: INVALID_EDGE\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_EDGE);\n\t\tthis.name = 'InvalidEdgeError';\n\t}\n}\n\n/**\n * Error thrown when a cycle is detected during graph traversal.\n *\n * This error is thrown by graph algorithms (such as topological sort)\n * when the thought DAG contains a cycle, violating the acyclic invariant.\n *\n * @example\n * ```typescript\n * try {\n * const order = graphView.topological(sessionId);\n * } catch (error) {\n * if (error instanceof CycleDetectedError) {\n * console.error('Cycle in thought graph:', error.message);\n * }\n * }\n * ```\n */\nexport class CycleDetectedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new CycleDetectedError.\n\t *\n\t * @param message - Human-readable explanation of the cycle\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new CycleDetectedError('Cycle detected in session s1');\n\t * // Code: CYCLE_DETECTED\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.CYCLE_DETECTED);\n\t\tthis.name = 'CycleDetectedError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record is not found.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension that does not exist in the suspension store.\n */\nexport class SuspensionNotFoundError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.SUSPENSION_NOT_FOUND);\n\t\tthis.name = 'SuspensionNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record has expired.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension whose TTL has elapsed.\n */\nexport class SuspensionExpiredError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.SUSPENSION_EXPIRED);\n\t\tthis.name = 'SuspensionExpiredError';\n\t}\n}\n\n/**\n * Error thrown when a tool call payload is invalid.\n *\n * This error is thrown when a tool interleave invocation has malformed\n * arguments, missing identifiers, or otherwise fails validation.\n */\nexport class InvalidToolCallError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_TOOL_CALL);\n\t\tthis.name = 'InvalidToolCallError';\n\t}\n}\n\n/**\n * Error thrown when a backtrack operation is invalid.\n *\n * This error is thrown when an attempt to backtrack the reasoning\n * chain references an unreachable thought or violates DAG invariants.\n */\nexport class InvalidBacktrackError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_BACKTRACK);\n\t\tthis.name = 'InvalidBacktrackError';\n\t}\n}\n\n/**\n * Type guard to check if an error has a specific error code.\n */\nexport function isErrorCode<C extends ErrorCode>(\n\terr: unknown,\n\tcode: C,\n): err is SequentialThinkingError & { readonly code: C } {\n\treturn err instanceof SequentialThinkingError && err.code === code;\n}\n\n/**\n * Extract a human-readable message from an unknown error value.\n *\n * Standardizes the common `error instanceof Error ? error.message : String(error)`\n * pattern used in catch blocks across the codebase.\n *\n * @param error - The unknown error value to extract a message from\n * @returns The error message string\n *\n * @example\n * ```typescript\n * try {\n * await doSomething();\n * } catch (error) {\n * logger.error('Failed', { error: getErrorMessage(error) });\n * }\n * ```\n */\nexport function getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],"names":["ERROR_CODES","SequentialThinkingError","Error","message","code","ConfigurationError","ToolNotFoundError","toolName","action","SkillNotFoundError","skillName","InvalidThoughtError","thoughtNumber","reason","SkillDiscoveryError","directory","cause","HistoryLimitExceededError","currentSize","maxSize","DuplicateSkillError","InvalidSkillError","DuplicateToolError","InvalidToolError","SessionNotActiveError","sessionId","SessionNotFoundError","MaxSessionsReachedError","maxSessions","PoolTerminatedError","ValidationError","field","InvalidEdgeError","CycleDetectedError","SuspensionNotFoundError","SuspensionExpiredError","InvalidToolCallError","InvalidBacktrackError","isErrorCode","err","getErrorMessage","error","String"],"mappings":"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"}
@@ -7,7 +7,7 @@
7
7
  * @module health
8
8
  */
9
9
  import type { Logger } from '../logger/StructuredLogger.js';
10
- import type { PersistenceBackend } from '../persistence/PersistenceBackend.js';
10
+ import type { PersistenceBackend } from '../contracts/PersistenceBackend.js';
11
11
  /**
12
12
  * Health status of an individual component.
13
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"HealthChecker.d.ts","sourceRoot":"","sources":["../../src/health/HealthChecker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAG/E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,WAAW,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,WAAW,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,OAAO,CAAoD;gBAEvD,OAAO,GAAE,oBAAyB;IAK9C;;;;;OAKG;IACH,aAAa,IAAI,iBAAiB;IAQlC;;;;;;;OAOG;IACG,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAyClD;;OAEG;YACW,iBAAiB;CAsB/B"}
1
+ {"version":3,"file":"HealthChecker.d.ts","sourceRoot":"","sources":["../../src/health/HealthChecker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAG7E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,WAAW,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,WAAW,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,OAAO,CAAoD;gBAEvD,OAAO,GAAE,oBAAyB;IAK9C;;;;;OAKG;IACH,aAAa,IAAI,iBAAiB;IAQlC;;;;;;;OAOG;IACG,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAyClD;;OAEG;YACW,iBAAiB;CAsB/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"health/HealthChecker.js","sources":["../../src/health/HealthChecker.ts"],"sourcesContent":["/**\n * Aggregate health checking system.\n *\n * Provides liveness and readiness checks by aggregating the health\n * status of registered backend components (persistence, pool, etc.).\n *\n * @module health\n */\n\nimport type { Logger } from '../logger/StructuredLogger.js';\nimport type { PersistenceBackend } from '../persistence/PersistenceBackend.js';\nimport { getErrorMessage } from '../errors.js';\n\n/**\n * Health status of an individual component.\n */\nexport interface HealthComponent {\n\tname: string;\n\thealthy: boolean;\n\tdetails?: string;\n\tlatencyMs?: number;\n}\n\n/**\n * Aggregate health check result.\n */\nexport interface HealthCheckResult {\n\tstatus: 'ok' | 'degraded' | 'unhealthy';\n\ttimestamp: string;\n\tcomponents: Record<string, HealthComponent>;\n}\n\n/**\n * Options for constructing a HealthChecker.\n */\nexport interface HealthCheckerOptions {\n\tpersistence?: PersistenceBackend | null;\n\tlogger?: Logger;\n}\n\n/**\n * No-op logger used when none is provided.\n */\nclass NoopLogger implements Pick<Logger, 'info' | 'warn' | 'error' | 'debug'> {\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n\tdebug(): void {}\n}\n\n/**\n * Aggregates component health into liveness and readiness checks.\n *\n * - `checkLiveness()` always returns 'ok' if the process is running.\n * - `checkReadiness()` checks all registered backends and returns an aggregate status.\n *\n * @example\n * ```typescript\n * const checker = new HealthChecker({ persistence: myBackend });\n * const readiness = await checker.checkReadiness();\n * // { status: 'ok', timestamp: '...', components: { persistence: { ... } } }\n * ```\n */\nexport class HealthChecker {\n\tprivate _persistence: PersistenceBackend | null;\n\tprivate _logger: Pick<Logger, 'info' | 'warn' | 'error' | 'debug'>;\n\n\tconstructor(options: HealthCheckerOptions = {}) {\n\t\tthis._persistence = options.persistence ?? null;\n\t\tthis._logger = options.logger ?? new NoopLogger();\n\t}\n\n\t/**\n\t * Liveness check — returns 'ok' if the process is alive.\n\t *\n\t * This is a synchronous check that always succeeds; if this code\n\t * can execute, the process is alive.\n\t */\n\tcheckLiveness(): HealthCheckResult {\n\t\treturn {\n\t\t\tstatus: 'ok',\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcomponents: {},\n\t\t};\n\t}\n\n\t/**\n\t * Readiness check — aggregates health of all registered backends.\n\t *\n\t * Checks each component and returns:\n\t * - 'ok' if all components are healthy (or no components registered)\n\t * - 'degraded' if some components are unhealthy\n\t * - 'unhealthy' if all components are unhealthy\n\t */\n\tasync checkReadiness(): Promise<HealthCheckResult> {\n\t\tconst components: Record<string, HealthComponent> = {};\n\t\tlet healthyCount = 0;\n\t\tlet totalCount = 0;\n\n\t\t// Check persistence backend\n\t\tif (this._persistence) {\n\t\t\ttotalCount++;\n\t\t\tconst component = await this._checkPersistence();\n\t\t\tcomponents['persistence'] = component;\n\t\t\tif (component.healthy) {\n\t\t\t\thealthyCount++;\n\t\t\t}\n\t\t}\n\n\t\t// Determine aggregate status\n\t\tlet status: 'ok' | 'degraded' | 'unhealthy';\n\t\tif (totalCount === 0 || healthyCount === totalCount) {\n\t\t\tstatus = 'ok';\n\t\t} else if (healthyCount === 0) {\n\t\t\tstatus = 'unhealthy';\n\t\t} else {\n\t\t\tstatus = 'degraded';\n\t\t}\n\n\t\tconst result: HealthCheckResult = {\n\t\t\tstatus,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcomponents,\n\t\t};\n\n\t\tif (status !== 'ok') {\n\t\t\tthis._logger.warn('Readiness check returned non-ok status', {\n\t\t\t\tstatus,\n\t\t\t\tcomponents,\n\t\t\t});\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Check persistence backend health with latency measurement.\n\t */\n\tprivate async _checkPersistence(): Promise<HealthComponent> {\n\t\tconst start = Date.now();\n\t\ttry {\n\t\t\tconst healthy = await this._persistence!.healthy();\n\t\t\treturn {\n\t\t\t\tname: 'persistence',\n\t\t\t\thealthy,\n\t\t\t\tlatencyMs: Date.now() - start,\n\t\t\t\tdetails: healthy ? 'Backend is responsive' : 'Backend reported unhealthy',\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis._logger.error('Persistence health check failed', {\n\t\t\t\terror: getErrorMessage(error),\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tname: 'persistence',\n\t\t\t\thealthy: false,\n\t\t\t\tlatencyMs: Date.now() - start,\n\t\t\t\tdetails: `Health check error: ${getErrorMessage(error)}`,\n\t\t\t};\n\t\t}\n\t}\n}\n"],"names":["NoopLogger","HealthChecker","options","Date","components","healthyCount","totalCount","component","status","result","start","healthy","error","getErrorMessage"],"mappings":";AA2CA,MAAMA;IACL,OAAa,CAAC;IACd,OAAa,CAAC;IACd,QAAc,CAAC;IACf,QAAc,CAAC;AAChB;AAeO,MAAMC;IACJ,aAAwC;IACxC,QAA2D;IAEnE,YAAYC,UAAgC,CAAC,CAAC,CAAE;QAC/C,IAAI,CAAC,YAAY,GAAGA,QAAQ,WAAW,IAAI;QAC3C,IAAI,CAAC,OAAO,GAAGA,QAAQ,MAAM,IAAI,IAAIF;IACtC;IAQA,gBAAmC;QAClC,OAAO;YACN,QAAQ;YACR,WAAW,IAAIG,OAAO,WAAW;YACjC,YAAY,CAAC;QACd;IACD;IAUA,MAAM,iBAA6C;QAClD,MAAMC,aAA8C,CAAC;QACrD,IAAIC,eAAe;QACnB,IAAIC,aAAa;QAGjB,IAAI,IAAI,CAAC,YAAY,EAAE;YACtBA;YACA,MAAMC,YAAY,MAAM,IAAI,CAAC,iBAAiB;YAC9CH,UAAU,CAAC,cAAc,GAAGG;YAC5B,IAAIA,UAAU,OAAO,EACpBF;QAEF;QAGA,IAAIG;QAEHA,SADGF,AAAe,MAAfA,cAAoBD,iBAAiBC,aAC/B,OACCD,AAAiB,MAAjBA,eACD,cAEA;QAGV,MAAMI,SAA4B;YACjCD;YACA,WAAW,IAAIL,OAAO,WAAW;YACjCC;QACD;QAEA,IAAII,AAAW,SAAXA,QACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0CAA0C;YAC3DA;YACAJ;QACD;QAGD,OAAOK;IACR;IAKA,MAAc,oBAA8C;QAC3D,MAAMC,QAAQP,KAAK,GAAG;QACtB,IAAI;YACH,MAAMQ,UAAU,MAAM,IAAI,CAAC,YAAY,CAAE,OAAO;YAChD,OAAO;gBACN,MAAM;gBACNA;gBACA,WAAWR,KAAK,GAAG,KAAKO;gBACxB,SAASC,UAAU,0BAA0B;YAC9C;QACD,EAAE,OAAOC,OAAO;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,mCAAmC;gBACrD,OAAOC,gBAAgBD;YACxB;YACA,OAAO;gBACN,MAAM;gBACN,SAAS;gBACT,WAAWT,KAAK,GAAG,KAAKO;gBACxB,SAAS,CAAC,oBAAoB,EAAEG,gBAAgBD,QAAQ;YACzD;QACD;IACD;AACD"}
1
+ {"version":3,"file":"health/HealthChecker.js","sources":["../../src/health/HealthChecker.ts"],"sourcesContent":["/**\n * Aggregate health checking system.\n *\n * Provides liveness and readiness checks by aggregating the health\n * status of registered backend components (persistence, pool, etc.).\n *\n * @module health\n */\n\nimport type { Logger } from '../logger/StructuredLogger.js';\nimport type { PersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport { getErrorMessage } from '../errors.js';\n\n/**\n * Health status of an individual component.\n */\nexport interface HealthComponent {\n\tname: string;\n\thealthy: boolean;\n\tdetails?: string;\n\tlatencyMs?: number;\n}\n\n/**\n * Aggregate health check result.\n */\nexport interface HealthCheckResult {\n\tstatus: 'ok' | 'degraded' | 'unhealthy';\n\ttimestamp: string;\n\tcomponents: Record<string, HealthComponent>;\n}\n\n/**\n * Options for constructing a HealthChecker.\n */\nexport interface HealthCheckerOptions {\n\tpersistence?: PersistenceBackend | null;\n\tlogger?: Logger;\n}\n\n/**\n * No-op logger used when none is provided.\n */\nclass NoopLogger implements Pick<Logger, 'info' | 'warn' | 'error' | 'debug'> {\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n\tdebug(): void {}\n}\n\n/**\n * Aggregates component health into liveness and readiness checks.\n *\n * - `checkLiveness()` always returns 'ok' if the process is running.\n * - `checkReadiness()` checks all registered backends and returns an aggregate status.\n *\n * @example\n * ```typescript\n * const checker = new HealthChecker({ persistence: myBackend });\n * const readiness = await checker.checkReadiness();\n * // { status: 'ok', timestamp: '...', components: { persistence: { ... } } }\n * ```\n */\nexport class HealthChecker {\n\tprivate _persistence: PersistenceBackend | null;\n\tprivate _logger: Pick<Logger, 'info' | 'warn' | 'error' | 'debug'>;\n\n\tconstructor(options: HealthCheckerOptions = {}) {\n\t\tthis._persistence = options.persistence ?? null;\n\t\tthis._logger = options.logger ?? new NoopLogger();\n\t}\n\n\t/**\n\t * Liveness check — returns 'ok' if the process is alive.\n\t *\n\t * This is a synchronous check that always succeeds; if this code\n\t * can execute, the process is alive.\n\t */\n\tcheckLiveness(): HealthCheckResult {\n\t\treturn {\n\t\t\tstatus: 'ok',\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcomponents: {},\n\t\t};\n\t}\n\n\t/**\n\t * Readiness check — aggregates health of all registered backends.\n\t *\n\t * Checks each component and returns:\n\t * - 'ok' if all components are healthy (or no components registered)\n\t * - 'degraded' if some components are unhealthy\n\t * - 'unhealthy' if all components are unhealthy\n\t */\n\tasync checkReadiness(): Promise<HealthCheckResult> {\n\t\tconst components: Record<string, HealthComponent> = {};\n\t\tlet healthyCount = 0;\n\t\tlet totalCount = 0;\n\n\t\t// Check persistence backend\n\t\tif (this._persistence) {\n\t\t\ttotalCount++;\n\t\t\tconst component = await this._checkPersistence();\n\t\t\tcomponents['persistence'] = component;\n\t\t\tif (component.healthy) {\n\t\t\t\thealthyCount++;\n\t\t\t}\n\t\t}\n\n\t\t// Determine aggregate status\n\t\tlet status: 'ok' | 'degraded' | 'unhealthy';\n\t\tif (totalCount === 0 || healthyCount === totalCount) {\n\t\t\tstatus = 'ok';\n\t\t} else if (healthyCount === 0) {\n\t\t\tstatus = 'unhealthy';\n\t\t} else {\n\t\t\tstatus = 'degraded';\n\t\t}\n\n\t\tconst result: HealthCheckResult = {\n\t\t\tstatus,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcomponents,\n\t\t};\n\n\t\tif (status !== 'ok') {\n\t\t\tthis._logger.warn('Readiness check returned non-ok status', {\n\t\t\t\tstatus,\n\t\t\t\tcomponents,\n\t\t\t});\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Check persistence backend health with latency measurement.\n\t */\n\tprivate async _checkPersistence(): Promise<HealthComponent> {\n\t\tconst start = Date.now();\n\t\ttry {\n\t\t\tconst healthy = await this._persistence!.healthy();\n\t\t\treturn {\n\t\t\t\tname: 'persistence',\n\t\t\t\thealthy,\n\t\t\t\tlatencyMs: Date.now() - start,\n\t\t\t\tdetails: healthy ? 'Backend is responsive' : 'Backend reported unhealthy',\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis._logger.error('Persistence health check failed', {\n\t\t\t\terror: getErrorMessage(error),\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tname: 'persistence',\n\t\t\t\thealthy: false,\n\t\t\t\tlatencyMs: Date.now() - start,\n\t\t\t\tdetails: `Health check error: ${getErrorMessage(error)}`,\n\t\t\t};\n\t\t}\n\t}\n}\n"],"names":["NoopLogger","HealthChecker","options","Date","components","healthyCount","totalCount","component","status","result","start","healthy","error","getErrorMessage"],"mappings":";AA2CA,MAAMA;IACL,OAAa,CAAC;IACd,OAAa,CAAC;IACd,QAAc,CAAC;IACf,QAAc,CAAC;AAChB;AAeO,MAAMC;IACJ,aAAwC;IACxC,QAA2D;IAEnE,YAAYC,UAAgC,CAAC,CAAC,CAAE;QAC/C,IAAI,CAAC,YAAY,GAAGA,QAAQ,WAAW,IAAI;QAC3C,IAAI,CAAC,OAAO,GAAGA,QAAQ,MAAM,IAAI,IAAIF;IACtC;IAQA,gBAAmC;QAClC,OAAO;YACN,QAAQ;YACR,WAAW,IAAIG,OAAO,WAAW;YACjC,YAAY,CAAC;QACd;IACD;IAUA,MAAM,iBAA6C;QAClD,MAAMC,aAA8C,CAAC;QACrD,IAAIC,eAAe;QACnB,IAAIC,aAAa;QAGjB,IAAI,IAAI,CAAC,YAAY,EAAE;YACtBA;YACA,MAAMC,YAAY,MAAM,IAAI,CAAC,iBAAiB;YAC9CH,UAAU,CAAC,cAAc,GAAGG;YAC5B,IAAIA,UAAU,OAAO,EACpBF;QAEF;QAGA,IAAIG;QAEHA,SADGF,AAAe,MAAfA,cAAoBD,iBAAiBC,aAC/B,OACCD,AAAiB,MAAjBA,eACD,cAEA;QAGV,MAAMI,SAA4B;YACjCD;YACA,WAAW,IAAIL,OAAO,WAAW;YACjCC;QACD;QAEA,IAAII,AAAW,SAAXA,QACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0CAA0C;YAC3DA;YACAJ;QACD;QAGD,OAAOK;IACR;IAKA,MAAc,oBAA8C;QAC3D,MAAMC,QAAQP,KAAK,GAAG;QACtB,IAAI;YACH,MAAMQ,UAAU,MAAM,IAAI,CAAC,YAAY,CAAE,OAAO;YAChD,OAAO;gBACN,MAAM;gBACNA;gBACA,WAAWR,KAAK,GAAG,KAAKO;gBACxB,SAASC,UAAU,0BAA0B;YAC9C;QACD,EAAE,OAAOC,OAAO;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,mCAAmC;gBACrD,OAAOC,gBAAgBD;YACxB;YACA,OAAO;gBACN,MAAM;gBACN,SAAS;gBACT,WAAWT,KAAK,GAAG,KAAKO;gBACxB,SAAS,CAAC,oBAAoB,EAAEG,gBAAgBD,QAAQ;YACzD;QACD;IACD;AACD"}
package/dist/lib.d.ts CHANGED
@@ -5,6 +5,7 @@ import { SequentialThinkingSchema } from './schema.js';
5
5
  import { IDisposable } from './types/disposable.js';
6
6
  import type { ConfigFileOptions } from './config/ConfigLoader.js';
7
7
  import { HistoryManager } from './core/HistoryManager.js';
8
+ import { type CallToolResult } from './core/ThoughtProcessor.js';
8
9
  import { Container } from './di/Container.js';
9
10
  import { StructuredLogger } from './logger/StructuredLogger.js';
10
11
  import { SkillRegistry } from './registry/SkillRegistry.js';
@@ -66,7 +67,64 @@ interface ServerEvents {
66
67
  duration: number;
67
68
  };
68
69
  }
69
- export declare class ToolAwareSequentialThinkingServer extends EventEmitter implements IDisposable {
70
+ /**
71
+ * Public API contract for the tool-aware sequential thinking server.
72
+ *
73
+ * Extends {@link IDisposable} for resource cleanup. Concrete implementations
74
+ * are expected to also extend Node's `EventEmitter` to support the typed
75
+ * `emit`/`on` overloads.
76
+ */
77
+ export interface IToolAwareSequentialThinkingServer extends IDisposable {
78
+ /** Direct access to the history manager. */
79
+ readonly history: HistoryManager;
80
+ /** Direct access to the tool registry. */
81
+ readonly tools: ToolRegistry;
82
+ /** Direct access to the skill registry. */
83
+ readonly skills: SkillRegistry;
84
+ /** Server configuration. */
85
+ readonly config: ServerConfig;
86
+ /**
87
+ * Discover skills asynchronously without blocking server startup.
88
+ *
89
+ * @returns The number of skills discovered
90
+ */
91
+ discoverSkillsAsync(): Promise<number>;
92
+ /**
93
+ * Get all branches from the history manager.
94
+ *
95
+ * @returns Map of branch IDs to thought arrays
96
+ */
97
+ getBranches(): Record<string, ThoughtData[]>;
98
+ /**
99
+ * Process a thought through the configured pipeline.
100
+ *
101
+ * @param input - Validated thought input matching the schema
102
+ * @returns The processing result
103
+ */
104
+ processThought(input: v.InferInput<typeof SequentialThinkingSchema>): Promise<CallToolResult>;
105
+ /**
106
+ * Export the current Prometheus metrics snapshot.
107
+ */
108
+ getMetricsSnapshot(): string;
109
+ /**
110
+ * Get the DI container used by this server.
111
+ * Useful for testing and advanced customizations.
112
+ */
113
+ getContainer(): Container;
114
+ /**
115
+ * Stop the server and clean up watchers, suspension stores, and persistence.
116
+ */
117
+ stop(): Promise<void>;
118
+ /**
119
+ * Clear all server state (history, tools, skills).
120
+ */
121
+ clear(): void;
122
+ /**
123
+ * Dispose of the server and all container services.
124
+ */
125
+ dispose(): Promise<void>;
126
+ }
127
+ export declare class ToolAwareSequentialThinkingServer extends EventEmitter implements IToolAwareSequentialThinkingServer {
70
128
  /**
71
129
  * Factory method to create a new server instance with async initialization.
72
130
  * This is the recommended way to create server instances.
@@ -147,7 +205,7 @@ export declare class ToolAwareSequentialThinkingServer extends EventEmitter impl
147
205
  * @returns Record<string, ThoughtData[]> - Map of branch IDs to thought arrays
148
206
  */
149
207
  getBranches(): Record<string, ThoughtData[]>;
150
- processThought(input: v.InferInput<typeof SequentialThinkingSchema>): Promise<import("./core/ThoughtProcessor.js").CallToolResult>;
208
+ processThought(input: v.InferInput<typeof SequentialThinkingSchema>): Promise<CallToolResult>;
151
209
  getMetricsSnapshot(): string;
152
210
  /**
153
211
  * Stop the server and clean up watchers.
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sources":["../src/lib.ts"],"sourcesContent":["// Library exports for tracelattice\n// This module contains all public API exports with NO CLI side effects.\n// For the CLI entry point, see cli.ts.\n\nimport { EventEmitter } from 'node:events';\nimport * as v from 'valibot';\nimport { ThoughtData } from './core/thought.js';\nimport { SEQUENTIAL_THINKING_TOOL, SequentialThinkingSchema } from './schema.js';\nimport { IDisposable } from './types/disposable.js';\nimport { getErrorMessage } from './errors.js';\n\n// New component imports\nimport { DiscoveryCache } from './cache/DiscoveryCache.js';\nimport type { ConfigFileOptions } from './config/ConfigLoader.js';\nimport { ConfigLoader } from './config/ConfigLoader.js';\nimport { HistoryManager } from './core/HistoryManager.js';\nimport { EdgeStore } from './core/graph/EdgeStore.js';\nimport { InMemorySummaryStore } from './core/compression/InMemorySummaryStore.js';\nimport { CompressionService } from './core/compression/CompressionService.js';\nimport type { ISummaryStore } from './contracts/summary.js';\nimport { InMemorySuspensionStore } from './core/tools/InMemorySuspensionStore.js';\nimport type { ISuspensionStore } from './contracts/suspension.js';\nimport { ThoughtEvaluator } from './core/ThoughtEvaluator.js';\nimport { Calibrator } from './core/evaluator/Calibrator.js';\nimport { OutcomeRecorder } from './core/reasoning/OutcomeRecorder.js';\nimport { createReasoningStrategy } from './core/reasoning/strategies/StrategyFactory.js';\nimport { ThoughtFormatter } from './core/ThoughtFormatter.js';\nimport { ThoughtProcessor } from './core/ThoughtProcessor.js';\nimport { Container } from './di/Container.js';\nimport { StructuredLogger } from './logger/StructuredLogger.js';\nimport { Metrics } from './metrics/metrics.impl.js';\nimport type { PersistenceBackend } from './persistence/PersistenceBackend.js';\nimport { createPersistenceBackend } from './persistence/PersistenceFactory.js';\nimport { SkillRegistry } from './registry/SkillRegistry.js';\nimport { ToolRegistry } from './registry/ToolRegistry.js';\nimport { ServerConfig } from './ServerConfig.js';\nimport type { SseTransportOptions } from './transport/SseTransport.js';\nimport { SkillWatcher } from './watchers/SkillWatcher.js';\nimport { ToolWatcher } from './watchers/ToolWatcher.js';\nimport type { IReasoningStrategy } from './contracts/strategy.js';\n\nexport interface ServerOptions {\n\tmaxHistorySize?: number;\n\tmaxBranches?: number;\n\tmaxBranchSize?: number;\n\tlogger?: StructuredLogger;\n\tenableWatcher?: boolean;\n\tconfig?: ServerConfig;\n\tfileConfig?: ConfigFileOptions;\n\tcontainer?: Container;\n\t/**\n\t * Enable automatic skill discovery on server startup\n\t * @default true\n\t */\n\tautoDiscover?: boolean;\n\t/**\n\t * Enable lazy discovery (discover on first access instead of startup)\n\t * @default false\n\t */\n\tlazyDiscovery?: boolean;\n\t/**\n\t * Load history from persistence on initialization\n\t * @default true\n\t */\n\tloadFromPersistence?: boolean;\n\t/**\n\t * Transport type to use\n\t * @default 'stdio'\n\t */\n\ttransport?: 'stdio' | 'sse';\n\t/**\n\t * SSE transport options (used when transport: 'sse')\n\t */\n\tsseTransportOptions?: SseTransportOptions;\n}\n\n/**\n * Server error events for event-driven error handling\n */\ninterface ServerEvents {\n\tpersistenceError: { operation: string; error: Error };\n\tdiscoveryError: { directory: string; error: Error };\n\ttransportError: { transport: string; error: Error };\n\tthoughtProcessed: { thoughtNumber: number; duration: number };\n}\n\nexport class ToolAwareSequentialThinkingServer extends EventEmitter implements IDisposable {\n\t/**\n\t * Factory method to create a new server instance with async initialization.\n\t * This is the recommended way to create server instances.\n\t *\n\t * @param options - Server configuration options\n\t * @returns A Promise that resolves to a configured server instance\n\t */\n\tstatic async create(options: ServerOptions = {}): Promise<ToolAwareSequentialThinkingServer> {\n\t\t// Create the async container first\n\t\tconst container = await ToolAwareSequentialThinkingServer._createContainerAsyncStatic(options);\n\n\t\t// Create a minimal server with the container\n\t\tconst server = new ToolAwareSequentialThinkingServer({\n\t\t\t...options,\n\t\t\tcontainer,\n\t\t});\n\n\t\t// Load from persistence if enabled (default: true)\n\t\tif (options.loadFromPersistence !== false) {\n\t\t\tawait server.history.loadFromPersistence();\n\t\t}\n\n\t\t// Perform async discovery if enabled (default: true)\n\t\tif (options.autoDiscover !== false) {\n\t\t\tawait server.discoverSkillsAsync();\n\t\t}\n\n\t\treturn server;\n\t}\n\n\t// Type-safe event emission\n\toverride emit<K extends keyof ServerEvents>(event: K, payload: ServerEvents[K]): boolean {\n\t\treturn super.emit(event, payload);\n\t}\n\n\toverride on<K extends keyof ServerEvents>(\n\t\tevent: K,\n\t\tlistener: (payload: ServerEvents[K]) => void\n\t): this {\n\t\treturn super.on(event, listener);\n\t}\n\n\t// DI Container for managing dependencies\n\tprivate _container: Container;\n\n\t// Component instances (private)\n\tprivate _logger: StructuredLogger;\n\tprivate _historyManager: HistoryManager;\n\tprivate _thoughtProcessor: ThoughtProcessor;\n\tprivate _metrics: Metrics;\n\tprivate _skillWatcher: SkillWatcher | null = null;\n\tprivate _toolWatcher: ToolWatcher | null = null;\n\tprivate _config: ServerConfig;\n\n\t// Public manager properties (recommended API)\n\t/**\n\t * Direct access to the history manager\n\t * @example\n\t * ```typescript\n\t * server.history.getHistory();\n\t * server.history.clear();\n\t * ```\n\t */\n\tpublic readonly history: HistoryManager;\n\n\t/**\n\t * Direct access to the tool registry\n\t * @example\n\t * ```typescript\n\t * server.tools.addTool(tool);\n\t * server.tools.getTool('my-tool');\n\t * ```\n\t */\n\tpublic readonly tools: ToolRegistry;\n\n\t/**\n\t * Direct access to the skill registry\n\t * @example\n\t * ```typescript\n\t * server.skills.addSkill(skill);\n\t * server.skills.getSkill('my-skill');\n\t * ```\n\t */\n\tpublic readonly skills: SkillRegistry;\n\n\t/**\n\t * Server configuration\n\t * @example\n\t * ```typescript\n\t * console.log(server.config.maxHistorySize);\n\t * ```\n\t */\n\tpublic readonly config: ServerConfig;\n\n\tconstructor(options: ServerOptions = {}) {\n\t\t// Use provided container or create a new one\n\t\tsuper();\n\t\tif (!options.container) {\n\t\t\tthrow new Error('Container is required. Use createServer() or provide a container.');\n\t\t}\n\t\tthis._container = options.container;\n\n\t\t// Resolve dependencies from container\n\t\tthis._logger = this._container.resolve<StructuredLogger>('Logger');\n\t\tthis._historyManager = this._container.resolve<HistoryManager>('HistoryManager');\n\t\tthis._thoughtProcessor = this._container.resolve<ThoughtProcessor>('ThoughtProcessor');\n\t\tthis._metrics = this._container.resolve<Metrics>('Metrics');\n\t\tthis._config = this._container.resolve<ServerConfig>('Config');\n\n\t\t// Expose managers as public properties (recommended API)\n\t\tthis.history = this._historyManager;\n\n\t\t// Wire up persistence error event emitter\n\t\tthis._historyManager.setEventEmitter(this);\n\t\tthis.tools = this._container.resolve<ToolRegistry>('ToolRegistry');\n\t\tthis.skills = this._container.resolve<SkillRegistry>('SkillRegistry');\n\t\tthis.config = this._config;\n\n\t\t// Always include the sequential thinking tool\n\t\tthis.tools.addTool(SEQUENTIAL_THINKING_TOOL);\n\n\n\t\t// Initialize watchers if enabled\n\t\tif (options.enableWatcher) {\n\t\t\tthis._skillWatcher = new SkillWatcher(this.skills);\n\t\t\tthis._toolWatcher = new ToolWatcher(this.tools);\n\t\t}\n\t}\n\n\t/**\n\t * Shared core logic for container creation.\n\t * This method contains all common initialization logic between sync and async paths.\n\t */\n\tprivate static _createContainerCore(\n\t\toptions: ServerOptions,\n\t\tfileConfig: ConfigFileOptions | null,\n\t\tpersistence: PersistenceBackend | null\n\t): Container {\n\t\tconst container = new Container();\n\t\tconst metrics = new Metrics({\n\t\t\tprefix: 'sequentialthinking',\n\t\t});\n\n\t\t// Initialize config with file defaults overridden by constructor options\n\t\tconst config = new ServerConfig({\n\t\t\tmaxHistorySize: options.maxHistorySize ?? fileConfig?.maxHistorySize,\n\t\t\tmaxBranches: options.maxBranches ?? fileConfig?.maxBranches,\n\t\t\tmaxBranchSize: options.maxBranchSize ?? fileConfig?.maxBranchSize,\n\t\t\tskillDirs: fileConfig?.skillDirs,\n\t\t\tdiscoveryCache: fileConfig?.discoveryCache,\n\t\t\tpersistence: fileConfig?.persistence,\n\t\t});\n\n\t\t// Initialize logger\n\t\tconst logger =\n\t\t\toptions.logger ??\n\t\t\tnew StructuredLogger({\n\t\t\t\tlevel: fileConfig?.logLevel ?? 'info',\n\t\t\t\tcontext: 'SequentialThinking',\n\t\t\t\tpretty: fileConfig?.prettyLog ?? true,\n\t\t\t});\n\n\t\t// Register all services in the container\n\t\tcontainer.registerInstance('Logger', logger);\n\t\tcontainer.registerInstance('Config', config);\n\t\tcontainer.registerInstance('FileConfig', fileConfig || {});\n\t\tcontainer.registerInstance('Persistence', persistence);\n\t\tcontainer.registerInstance('Metrics', metrics);\n\t\tcontainer.register(\n\t\t\t'ToolRegistry',\n\t\t\t() =>\n\t\t\t\tnew ToolRegistry({\n\t\t\t\t\tlogger,\n\t\t\t\t\tcache: config.discoveryCache\n\t\t\t\t\t\t? new DiscoveryCache({ ...config.discoveryCache, metrics })\n\t\t\t\t\t\t: undefined,\n\t\t\t\t})\n\t\t);\n\t\tcontainer.register(\n\t\t\t'SkillRegistry',\n\t\t\t() =>\n\t\t\t\tnew SkillRegistry({\n\t\t\t\t\tlogger,\n\t\t\t\t\tcache: config.discoveryCache\n\t\t\t\t\t\t? new DiscoveryCache({ ...config.discoveryCache, metrics })\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tskillDirs: config.skillDirs,\n\t\t\t\t\tlazyDiscovery: options.lazyDiscovery,\n\t\t\t\t})\n\t\t);\n\n\t\t// Register EdgeStore as a lazy singleton (always registered; flag gates writes)\n\t\tcontainer.register('EdgeStore', () => new EdgeStore());\n\n\t\t// Register SummaryStore as a lazy singleton (always registered; flag gates writes)\n\t\tcontainer.register('summaryStore', () => new InMemorySummaryStore());\n\n\t\t// Register SuspensionStore as a lazy singleton (only when toolInterleave flag is on)\n\t\tif (config.features.toolInterleave) {\n\t\t\tcontainer.register('suspensionStore', () => {\n\t\t\t\tconst store = new InMemorySuspensionStore({\n\t\t\t\t\tttlMs: config.toolInterleaveTtlMs,\n\t\t\t\t\tsweepIntervalMs: config.toolInterleaveSweepMs,\n\t\t\t\t\tlogger,\n\t\t\t\t});\n\t\t\t\tstore.start();\n\t\t\t\treturn store;\n\t\t\t});\n\t\t}\n\n\t\t// Register CompressionService as a lazy singleton (always registered; flag gates invocation)\n\t\tcontainer.register('compressionService', () => {\n\t\t\tconst historyManager = container.resolve<HistoryManager>('HistoryManager');\n\t\t\tconst edgeStore = container.resolve<EdgeStore>('EdgeStore');\n\t\t\tconst summaryStore = container.resolve<ISummaryStore>('summaryStore');\n\t\t\tconst log = container.resolve<StructuredLogger>('Logger');\n\t\t\treturn new CompressionService({ historyManager, edgeStore, summaryStore, logger: log });\n\t\t});\n\n\t\t// Register ReasoningStrategy as a lazy singleton (selected via feature flag)\n\t\tcontainer.register('reasoningStrategy', () =>\n\t\t\tcreateReasoningStrategy(config.features.reasoningStrategy),\n\t\t);\n\n\t\t// Register HistoryManager with lazy initialization\n\t\tcontainer.register('HistoryManager', () => {\n\t\t\tconst cfg = container.resolve<ServerConfig>('Config');\n\t\t\tconst log = container.resolve<StructuredLogger>('Logger');\n\t\t\tconst pers = container.resolve('Persistence') as PersistenceBackend | null;\n\t\t\tconst componentMetrics = container.resolve<Metrics>('Metrics');\n\t\t\tconst edgeStore = container.resolve<EdgeStore>('EdgeStore');\n\t\t\treturn new HistoryManager({\n\t\t\t\tmaxHistorySize: cfg.maxHistorySize,\n\t\t\t\tmaxBranches: cfg.maxBranches,\n\t\t\t\tmaxBranchSize: cfg.maxBranchSize,\n\t\t\t\tlogger: log,\n\t\t\t\tpersistence: pers,\n\t\t\t\tmetrics: componentMetrics,\n\t\t\t\tpersistenceBufferSize: cfg.persistenceBufferSize,\n\t\t\t\tpersistenceFlushInterval: cfg.persistenceFlushInterval,\n\t\t\t\tpersistenceMaxRetries: cfg.persistenceMaxRetries,\n\t\t\t\tedgeStore,\n\t\t\t});\n\t\t});\n\n\t\t// Register ThoughtFormatter (can be transient)\n\t\tcontainer.registerFactory('ThoughtFormatter', () => new ThoughtFormatter());\n\n\t\t// Register OutcomeRecorder as a lazy singleton (gated by feature flag)\n\t\tcontainer.register(\n\t\t\t'outcomeRecorder',\n\t\t\t() => new OutcomeRecorder({ enabled: config.features.outcomeRecording ?? false }),\n\t\t);\n\n\t\t// Register Calibrator as a lazy singleton (gated by feature flag)\n\t\tcontainer.register(\n\t\t\t'calibrator',\n\t\t\t() =>\n\t\t\t\tnew Calibrator(\n\t\t\t\t\tcontainer.resolve('outcomeRecorder'),\n\t\t\t\t\tconfig.features.calibration ?? false,\n\t\t\t\t),\n\t\t);\n\n\t\t// Register ThoughtEvaluator (stateless, transient) with injected calibrator\n\t\tcontainer.registerFactory(\n\t\t\t'ThoughtEvaluator',\n\t\t\t() => new ThoughtEvaluator(container.resolve('calibrator')),\n\t\t);\n\n\t\t// Register ThoughtProcessor\n\t\tcontainer.register('ThoughtProcessor', () => {\n\t\t\tconst history = container.resolve<HistoryManager>('HistoryManager');\n\t\t\tconst formatter = container.resolve<ThoughtFormatter>('ThoughtFormatter');\n\t\t\tconst evaluator = container.resolve<ThoughtEvaluator>('ThoughtEvaluator');\n\t\t\tconst log = container.resolve<StructuredLogger>('Logger');\n\t\t\tconst strategy = container.resolve<IReasoningStrategy>('reasoningStrategy');\n\t\t\tconst compressionService = config.features.compression\n\t\t\t\t? container.resolve<CompressionService>('compressionService')\n\t\t\t\t: undefined;\n\t\t\tconst suspensionStore = config.features.toolInterleave\n\t\t\t\t? container.resolve<ISuspensionStore>('suspensionStore')\n\t\t\t\t: undefined;\n\t\t\treturn new ThoughtProcessor(\n\t\t\t\thistory,\n\t\t\t\tformatter,\n\t\t\t\tevaluator,\n\t\t\t\tlog,\n\t\t\t\tstrategy,\n\t\t\t\tcompressionService,\n\t\t\t\tsuspensionStore,\n\t\t\t\tconfig.features,\n\t\t\t);\n\t\t});\n\n\t\treturn container;\n\t}\n\n\n\t/**\n\t * Create and configure the DI container with async persistence initialization.\n\t * This is used internally by the static create() factory.\n\t */\n\tprivate static async _createContainerAsyncStatic(options: ServerOptions): Promise<Container> {\n\t\tconst configLoader = new ConfigLoader();\n\t\tconst fileConfig = configLoader.load();\n\n\t\t// Initialize persistence backend (async)\n\t\tconst persistence = await createPersistenceBackend(\n\t\t\tfileConfig?.persistence ?? { enabled: false }\n\t\t);\n\n\t\treturn ToolAwareSequentialThinkingServer._createContainerCore(options, fileConfig, persistence);\n\t}\n\n\t/**\n\t * Get the DI container used by this server\n\t * Useful for testing and advanced customizations\n\t */\n\tpublic getContainer(): Container {\n\t\treturn this._container;\n\t}\n\n\t/**\n\t * Discover skills asynchronously without blocking server startup.\n\t * This is the recommended method for skill discovery.\n\t * @returns Promise<number> - The number of skills discovered\n\t */\n\tpublic async discoverSkillsAsync(): Promise<number> {\n\t\tconst discovered = await this.skills.discoverAsync();\n\t\treturn discovered;\n\t}\n\n\t/**\n\t * Get all branches from the history manager\n\t * @returns Record<string, ThoughtData[]> - Map of branch IDs to thought arrays\n\t */\n\tpublic getBranches(): Record<string, ThoughtData[]> {\n\t\treturn this._historyManager.getBranches();\n\t}\n\n\t// Main processing method - delegate to ThoughtProcessor\n\tpublic async processThought(input: v.InferInput<typeof SequentialThinkingSchema>) {\n\t\tconst startTime = Date.now();\n\t\tconst thoughtInput = input as ThoughtData & { register_branch_id?: string };\n\t\tif (typeof thoughtInput.register_branch_id === 'string' && thoughtInput.register_branch_id.length > 0) {\n\t\t\ttry {\n\t\t\t\tthis._historyManager.registerBranch(\n\t\t\t\t\tthoughtInput.session_id,\n\t\t\t\t\tthoughtInput.register_branch_id\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthis._logger.warn('registerBranch skipped', {\n\t\t\t\t\tbranch_id: thoughtInput.register_branch_id,\n\t\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t\t});\n\t\t\t}\n\t\t\tdelete thoughtInput.register_branch_id;\n\t\t}\n\t\tconst result = await this._thoughtProcessor.process(thoughtInput);\n\t\tconst durationSeconds = (Date.now() - startTime) / 1000;\n\t\tthis._metrics.histogram('thought_processing_duration_seconds', durationSeconds, {});\n\t\treturn result;\n\t}\n\n\tpublic getMetricsSnapshot(): string {\n\t\treturn this._metrics.export();\n\t}\n\n\t/**\n\t * Stop the server and clean up watchers.\n\t * Closes persistence backend gracefully to ensure data is flushed.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tthis._skillWatcher?.stop();\n\t\tthis._toolWatcher?.stop();\n\n\t\t// Stop suspension store sweeper if registered\n\t\tif (this._config.features.toolInterleave && this._container.has('suspensionStore')) {\n\t\t\ttry {\n\t\t\t\tconst suspensionStore = this._container.resolve<ISuspensionStore>('suspensionStore');\n\t\t\t\tsuspensionStore.stop();\n\t\t\t} catch (error) {\n\t\t\t\tthis._logger.error('Error stopping suspension store', {\n\t\t\t\t\terror: getErrorMessage(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Flush any buffered writes before closing persistence\n\t\ttry {\n\t\t\tawait this._historyManager.shutdown();\n\t\t} catch (error) {\n\t\t\tthis._logger.error('Error flushing write buffer during shutdown', {\n\t\t\t\terror: getErrorMessage(error),\n\t\t\t});\n\t\t}\n\n\t\t// Close persistence backend if available\n\t\tconst persistence = this._container.resolve<PersistenceBackend | null>('Persistence');\n\t\tif (persistence) {\n\t\t\ttry {\n\t\t\t\tawait persistence.close();\n\t\t\t\tthis._logger.info('Persistence backend closed');\n\t\t\t} catch (error) {\n\t\t\t\tthis._logger.error('Error closing persistence backend', {\n\t\t\t\t\terror: getErrorMessage(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis._logger.info('Server stopped, watchers cleaned up');\n\t}\n\n\t/**\n\t * Clear all server state (history, tools, skills)\n\t * Useful for testing to reset state between tests\n\t */\n\tpublic clear(): void {\n\t\tthis._historyManager.clear();\n\t\tthis._logger.info('Server state cleared');\n\t}\n\n\t/**\n\t * Dispose of the server and all container services.\n\t * Implements the IDisposable interface.\n\t * Calls stop() for existing cleanup, then disposes the DI container.\n\t */\n\tpublic async dispose(): Promise<void> {\n\t\tawait this.stop();\n\t\tawait this._container.dispose();\n\t\tthis._logger.info('Server disposed, all resources released');\n\t}\n}\n\n/**\n * Factory function to create a new server instance with async initialization.\n *\n * This is the recommended way to create server instances, especially for testing,\n * as it allows for proper async initialization, dependency injection, and persistence.\n *\n * @param options - Server configuration options\n * @returns A Promise that resolves to a configured server instance\n *\n * @example\n * ```typescript\n * // Basic usage (with async discovery and persistence)\n * const server = await createServer();\n *\n * // With custom options\n * const server = await createServer({\n * autoDiscover: false,\n * lazyDiscovery: true,\n * maxHistorySize: 500,\n * loadFromPersistence: true\n * });\n *\n * // With custom container for testing\n * const mockContainer = new Container();\n * mockContainer.registerInstance('Logger', mockLogger);\n * const server = await createServer({ container: mockContainer });\n * ```\n */\nexport async function createServer(\n\toptions: ServerOptions = {}\n): Promise<ToolAwareSequentialThinkingServer> {\n\treturn ToolAwareSequentialThinkingServer.create(options);\n}\n\n// Initialize server\nexport async function initializeServer(): Promise<ToolAwareSequentialThinkingServer> {\n\t// Create logger for initialization\n\tconst configLoader = new ConfigLoader();\n\tconst fileConfig = configLoader.load();\n\n\tconst logger = new StructuredLogger({\n\t\tlevel: fileConfig?.logLevel ?? 'info',\n\t\tcontext: 'SequentialThinking',\n\t\tpretty: fileConfig?.prettyLog ?? true,\n\t});\n\n\t// Create server instance\n\tconst thinkingServer = await createServer({\n\t\tlogger,\n\t\tenableWatcher: true,\n\t});\n\n\tlogger.info('Server initialized successfully');\n\treturn thinkingServer;\n}\n"],"names":["ToolAwareSequentialThinkingServer","EventEmitter","options","container","server","event","payload","listener","Error","SEQUENTIAL_THINKING_TOOL","SkillWatcher","ToolWatcher","fileConfig","persistence","Container","metrics","Metrics","config","ServerConfig","logger","StructuredLogger","ToolRegistry","DiscoveryCache","undefined","SkillRegistry","EdgeStore","InMemorySummaryStore","store","InMemorySuspensionStore","historyManager","edgeStore","summaryStore","log","CompressionService","createReasoningStrategy","cfg","pers","componentMetrics","HistoryManager","ThoughtFormatter","OutcomeRecorder","Calibrator","ThoughtEvaluator","history","formatter","evaluator","strategy","compressionService","suspensionStore","ThoughtProcessor","configLoader","ConfigLoader","createPersistenceBackend","discovered","input","startTime","Date","thoughtInput","err","String","result","durationSeconds","error","getErrorMessage","createServer","initializeServer","thinkingServer"],"mappings":"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"}
1
+ {"version":3,"file":"lib.js","sources":["../src/lib.ts"],"sourcesContent":["// Library exports for tracelattice\n// This module contains all public API exports with NO CLI side effects.\n// For the CLI entry point, see cli.ts.\n\nimport { EventEmitter } from 'node:events';\nimport * as v from 'valibot';\nimport { ThoughtData } from './core/thought.js';\nimport { SEQUENTIAL_THINKING_TOOL, SequentialThinkingSchema } from './schema.js';\nimport { IDisposable } from './types/disposable.js';\nimport { getErrorMessage } from './errors.js';\n\n// New component imports\nimport { DiscoveryCache } from './cache/DiscoveryCache.js';\nimport type { ConfigFileOptions } from './config/ConfigLoader.js';\nimport { ConfigLoader } from './config/ConfigLoader.js';\nimport { HistoryManager } from './core/HistoryManager.js';\nimport { EdgeStore } from './core/graph/EdgeStore.js';\nimport { InMemorySummaryStore } from './core/compression/InMemorySummaryStore.js';\nimport { CompressionService } from './core/compression/CompressionService.js';\nimport type { ISummaryStore } from './contracts/summary.js';\nimport { InMemorySuspensionStore } from './core/tools/InMemorySuspensionStore.js';\nimport type { ISuspensionStore } from './contracts/suspension.js';\nimport { ThoughtEvaluator } from './core/ThoughtEvaluator.js';\nimport { Calibrator } from './core/evaluator/Calibrator.js';\nimport { OutcomeRecorder } from './core/reasoning/OutcomeRecorder.js';\nimport { createReasoningStrategy } from './core/reasoning/strategies/StrategyFactory.js';\nimport { ThoughtFormatter } from './core/ThoughtFormatter.js';\nimport { ThoughtProcessor, type CallToolResult } from './core/ThoughtProcessor.js';\nimport { Container } from './di/Container.js';\nimport { StructuredLogger } from './logger/StructuredLogger.js';\nimport { Metrics } from './metrics/metrics.impl.js';\nimport type { PersistenceBackend } from './contracts/PersistenceBackend.js';\nimport { createPersistenceBackend } from './persistence/PersistenceFactory.js';\nimport { SkillRegistry } from './registry/SkillRegistry.js';\nimport { ToolRegistry } from './registry/ToolRegistry.js';\nimport { ServerConfig } from './ServerConfig.js';\nimport type { SseTransportOptions } from './transport/SseTransport.js';\nimport { SkillWatcher } from './watchers/SkillWatcher.js';\nimport { ToolWatcher } from './watchers/ToolWatcher.js';\nimport type { IReasoningStrategy } from './contracts/strategy.js';\n\nexport interface ServerOptions {\n\tmaxHistorySize?: number;\n\tmaxBranches?: number;\n\tmaxBranchSize?: number;\n\tlogger?: StructuredLogger;\n\tenableWatcher?: boolean;\n\tconfig?: ServerConfig;\n\tfileConfig?: ConfigFileOptions;\n\tcontainer?: Container;\n\t/**\n\t * Enable automatic skill discovery on server startup\n\t * @default true\n\t */\n\tautoDiscover?: boolean;\n\t/**\n\t * Enable lazy discovery (discover on first access instead of startup)\n\t * @default false\n\t */\n\tlazyDiscovery?: boolean;\n\t/**\n\t * Load history from persistence on initialization\n\t * @default true\n\t */\n\tloadFromPersistence?: boolean;\n\t/**\n\t * Transport type to use\n\t * @default 'stdio'\n\t */\n\ttransport?: 'stdio' | 'sse';\n\t/**\n\t * SSE transport options (used when transport: 'sse')\n\t */\n\tsseTransportOptions?: SseTransportOptions;\n}\n\n/**\n * Server error events for event-driven error handling\n */\ninterface ServerEvents {\n\tpersistenceError: { operation: string; error: Error };\n\tdiscoveryError: { directory: string; error: Error };\n\ttransportError: { transport: string; error: Error };\n\tthoughtProcessed: { thoughtNumber: number; duration: number };\n}\n\n/**\n * Public API contract for the tool-aware sequential thinking server.\n *\n * Extends {@link IDisposable} for resource cleanup. Concrete implementations\n * are expected to also extend Node's `EventEmitter` to support the typed\n * `emit`/`on` overloads.\n */\nexport interface IToolAwareSequentialThinkingServer extends IDisposable {\n\t/** Direct access to the history manager. */\n\treadonly history: HistoryManager;\n\n\t/** Direct access to the tool registry. */\n\treadonly tools: ToolRegistry;\n\n\t/** Direct access to the skill registry. */\n\treadonly skills: SkillRegistry;\n\n\t/** Server configuration. */\n\treadonly config: ServerConfig;\n\n\t/**\n\t * Discover skills asynchronously without blocking server startup.\n\t *\n\t * @returns The number of skills discovered\n\t */\n\tdiscoverSkillsAsync(): Promise<number>;\n\n\t/**\n\t * Get all branches from the history manager.\n\t *\n\t * @returns Map of branch IDs to thought arrays\n\t */\n\tgetBranches(): Record<string, ThoughtData[]>;\n\n\t/**\n\t * Process a thought through the configured pipeline.\n\t *\n\t * @param input - Validated thought input matching the schema\n\t * @returns The processing result\n\t */\n\tprocessThought(input: v.InferInput<typeof SequentialThinkingSchema>): Promise<CallToolResult>;\n\n\t/**\n\t * Export the current Prometheus metrics snapshot.\n\t */\n\tgetMetricsSnapshot(): string;\n\n\t/**\n\t * Get the DI container used by this server.\n\t * Useful for testing and advanced customizations.\n\t */\n\tgetContainer(): Container;\n\n\t/**\n\t * Stop the server and clean up watchers, suspension stores, and persistence.\n\t */\n\tstop(): Promise<void>;\n\n\t/**\n\t * Clear all server state (history, tools, skills).\n\t */\n\tclear(): void;\n\n\t/**\n\t * Dispose of the server and all container services.\n\t */\n\tdispose(): Promise<void>;\n}\n\nexport class ToolAwareSequentialThinkingServer extends EventEmitter implements IToolAwareSequentialThinkingServer {\n\t/**\n\t * Factory method to create a new server instance with async initialization.\n\t * This is the recommended way to create server instances.\n\t *\n\t * @param options - Server configuration options\n\t * @returns A Promise that resolves to a configured server instance\n\t */\n\tstatic async create(options: ServerOptions = {}): Promise<ToolAwareSequentialThinkingServer> {\n\t\t// Create the async container first\n\t\tconst container = await ToolAwareSequentialThinkingServer._createContainerAsyncStatic(options);\n\n\t\t// Create a minimal server with the container\n\t\tconst server = new ToolAwareSequentialThinkingServer({\n\t\t\t...options,\n\t\t\tcontainer,\n\t\t});\n\n\t\t// Load from persistence if enabled (default: true)\n\t\tif (options.loadFromPersistence !== false) {\n\t\t\tawait server.history.loadFromPersistence();\n\t\t}\n\n\t\t// Perform async discovery if enabled (default: true)\n\t\tif (options.autoDiscover !== false) {\n\t\t\tawait server.discoverSkillsAsync();\n\t\t}\n\n\t\treturn server;\n\t}\n\n\t// Type-safe event emission\n\toverride emit<K extends keyof ServerEvents>(event: K, payload: ServerEvents[K]): boolean {\n\t\treturn super.emit(event, payload);\n\t}\n\n\toverride on<K extends keyof ServerEvents>(\n\t\tevent: K,\n\t\tlistener: (payload: ServerEvents[K]) => void\n\t): this {\n\t\treturn super.on(event, listener);\n\t}\n\n\t// DI Container for managing dependencies\n\tprivate _container: Container;\n\n\t// Component instances (private)\n\tprivate _logger: StructuredLogger;\n\tprivate _historyManager: HistoryManager;\n\tprivate _thoughtProcessor: ThoughtProcessor;\n\tprivate _metrics: Metrics;\n\tprivate _skillWatcher: SkillWatcher | null = null;\n\tprivate _toolWatcher: ToolWatcher | null = null;\n\tprivate _config: ServerConfig;\n\n\t// Public manager properties (recommended API)\n\t/**\n\t * Direct access to the history manager\n\t * @example\n\t * ```typescript\n\t * server.history.getHistory();\n\t * server.history.clear();\n\t * ```\n\t */\n\tpublic readonly history: HistoryManager;\n\n\t/**\n\t * Direct access to the tool registry\n\t * @example\n\t * ```typescript\n\t * server.tools.addTool(tool);\n\t * server.tools.getTool('my-tool');\n\t * ```\n\t */\n\tpublic readonly tools: ToolRegistry;\n\n\t/**\n\t * Direct access to the skill registry\n\t * @example\n\t * ```typescript\n\t * server.skills.addSkill(skill);\n\t * server.skills.getSkill('my-skill');\n\t * ```\n\t */\n\tpublic readonly skills: SkillRegistry;\n\n\t/**\n\t * Server configuration\n\t * @example\n\t * ```typescript\n\t * console.log(server.config.maxHistorySize);\n\t * ```\n\t */\n\tpublic readonly config: ServerConfig;\n\n\tconstructor(options: ServerOptions = {}) {\n\t\t// Use provided container or create a new one\n\t\tsuper();\n\t\tif (!options.container) {\n\t\t\tthrow new Error('Container is required. Use createServer() or provide a container.');\n\t\t}\n\t\tthis._container = options.container;\n\n\t\t// Resolve dependencies from container\n\t\tthis._logger = this._container.resolve<StructuredLogger>('Logger');\n\t\tthis._historyManager = this._container.resolve<HistoryManager>('HistoryManager');\n\t\tthis._thoughtProcessor = this._container.resolve<ThoughtProcessor>('ThoughtProcessor');\n\t\tthis._metrics = this._container.resolve<Metrics>('Metrics');\n\t\tthis._config = this._container.resolve<ServerConfig>('Config');\n\n\t\t// Expose managers as public properties (recommended API)\n\t\tthis.history = this._historyManager;\n\n\t\t// Wire up persistence error event emitter\n\t\tthis._historyManager.setEventEmitter(this);\n\t\tthis.tools = this._container.resolve<ToolRegistry>('ToolRegistry');\n\t\tthis.skills = this._container.resolve<SkillRegistry>('SkillRegistry');\n\t\tthis.config = this._config;\n\n\t\t// Always include the sequential thinking tool\n\t\tthis.tools.addTool(SEQUENTIAL_THINKING_TOOL);\n\n\n\t\t// Initialize watchers if enabled\n\t\tif (options.enableWatcher) {\n\t\t\tthis._skillWatcher = new SkillWatcher(this.skills);\n\t\t\tthis._toolWatcher = new ToolWatcher(this.tools);\n\t\t}\n\t}\n\n\t/**\n\t * Shared core logic for container creation.\n\t * This method contains all common initialization logic between sync and async paths.\n\t */\n\tprivate static _createContainerCore(\n\t\toptions: ServerOptions,\n\t\tfileConfig: ConfigFileOptions | null,\n\t\tpersistence: PersistenceBackend | null\n\t): Container {\n\t\tconst container = new Container();\n\t\tconst metrics = new Metrics({\n\t\t\tprefix: 'sequentialthinking',\n\t\t});\n\n\t\t// Initialize config with file defaults overridden by constructor options\n\t\tconst config = new ServerConfig({\n\t\t\tmaxHistorySize: options.maxHistorySize ?? fileConfig?.maxHistorySize,\n\t\t\tmaxBranches: options.maxBranches ?? fileConfig?.maxBranches,\n\t\t\tmaxBranchSize: options.maxBranchSize ?? fileConfig?.maxBranchSize,\n\t\t\tskillDirs: fileConfig?.skillDirs,\n\t\t\tdiscoveryCache: fileConfig?.discoveryCache,\n\t\t\tpersistence: fileConfig?.persistence,\n\t\t});\n\n\t\t// Initialize logger\n\t\tconst logger =\n\t\t\toptions.logger ??\n\t\t\tnew StructuredLogger({\n\t\t\t\tlevel: fileConfig?.logLevel ?? 'info',\n\t\t\t\tcontext: 'SequentialThinking',\n\t\t\t\tpretty: fileConfig?.prettyLog ?? true,\n\t\t\t});\n\n\t\t// Register all services in the container\n\t\tcontainer.registerInstance('Logger', logger);\n\t\tcontainer.registerInstance('Config', config);\n\t\tcontainer.registerInstance('FileConfig', fileConfig || {});\n\t\tcontainer.registerInstance('Persistence', persistence);\n\t\tcontainer.registerInstance('Metrics', metrics);\n\t\tcontainer.register(\n\t\t\t'ToolRegistry',\n\t\t\t() =>\n\t\t\t\tnew ToolRegistry({\n\t\t\t\t\tlogger,\n\t\t\t\t\tcache: config.discoveryCache\n\t\t\t\t\t\t? new DiscoveryCache({ ...config.discoveryCache, metrics })\n\t\t\t\t\t\t: undefined,\n\t\t\t\t})\n\t\t);\n\t\tcontainer.register(\n\t\t\t'SkillRegistry',\n\t\t\t() =>\n\t\t\t\tnew SkillRegistry({\n\t\t\t\t\tlogger,\n\t\t\t\t\tcache: config.discoveryCache\n\t\t\t\t\t\t? new DiscoveryCache({ ...config.discoveryCache, metrics })\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tskillDirs: config.skillDirs,\n\t\t\t\t\tlazyDiscovery: options.lazyDiscovery,\n\t\t\t\t})\n\t\t);\n\n\t\t// Register EdgeStore as a lazy singleton (always registered; flag gates writes)\n\t\tcontainer.register('EdgeStore', () => new EdgeStore());\n\n\t\t// Register SummaryStore as a lazy singleton (always registered; flag gates writes)\n\t\tcontainer.register('summaryStore', () => new InMemorySummaryStore());\n\n\t\t// Register SuspensionStore as a lazy singleton (only when toolInterleave flag is on)\n\t\tif (config.features.toolInterleave) {\n\t\t\tcontainer.register('suspensionStore', () => {\n\t\t\t\tconst store = new InMemorySuspensionStore({\n\t\t\t\t\tttlMs: config.toolInterleaveTtlMs,\n\t\t\t\t\tsweepIntervalMs: config.toolInterleaveSweepMs,\n\t\t\t\t\tlogger,\n\t\t\t\t});\n\t\t\t\tstore.start();\n\t\t\t\treturn store;\n\t\t\t});\n\t\t}\n\n\t\t// Register CompressionService as a lazy singleton (always registered; flag gates invocation)\n\t\tcontainer.register('compressionService', () => {\n\t\t\tconst historyManager = container.resolve<HistoryManager>('HistoryManager');\n\t\t\tconst edgeStore = container.resolve<EdgeStore>('EdgeStore');\n\t\t\tconst summaryStore = container.resolve<ISummaryStore>('summaryStore');\n\t\t\tconst log = container.resolve<StructuredLogger>('Logger');\n\t\t\treturn new CompressionService({ historyManager, edgeStore, summaryStore, logger: log });\n\t\t});\n\n\t\t// Register ReasoningStrategy as a lazy singleton (selected via feature flag)\n\t\tcontainer.register('reasoningStrategy', () =>\n\t\t\tcreateReasoningStrategy(config.features.reasoningStrategy),\n\t\t);\n\n\t\t// Register HistoryManager with lazy initialization\n\t\tcontainer.register('HistoryManager', () => {\n\t\t\tconst cfg = container.resolve<ServerConfig>('Config');\n\t\t\tconst log = container.resolve<StructuredLogger>('Logger');\n\t\t\tconst pers = container.resolve('Persistence') as PersistenceBackend | null;\n\t\t\tconst componentMetrics = container.resolve<Metrics>('Metrics');\n\t\t\tconst edgeStore = container.resolve<EdgeStore>('EdgeStore');\n\t\t\treturn new HistoryManager({\n\t\t\t\tmaxHistorySize: cfg.maxHistorySize,\n\t\t\t\tmaxBranches: cfg.maxBranches,\n\t\t\t\tmaxBranchSize: cfg.maxBranchSize,\n\t\t\t\tlogger: log,\n\t\t\t\tpersistence: pers,\n\t\t\t\tmetrics: componentMetrics,\n\t\t\t\tpersistenceBufferSize: cfg.persistenceBufferSize,\n\t\t\t\tpersistenceFlushInterval: cfg.persistenceFlushInterval,\n\t\t\t\tpersistenceMaxRetries: cfg.persistenceMaxRetries,\n\t\t\t\tedgeStore,\n\t\t\t});\n\t\t});\n\n\t\t// Register ThoughtFormatter (can be transient)\n\t\tcontainer.registerFactory('ThoughtFormatter', () => new ThoughtFormatter());\n\n\t\t// Register OutcomeRecorder as a lazy singleton (gated by feature flag)\n\t\tcontainer.register(\n\t\t\t'outcomeRecorder',\n\t\t\t() => new OutcomeRecorder({ enabled: config.features.outcomeRecording ?? false }),\n\t\t);\n\n\t\t// Register Calibrator as a lazy singleton (gated by feature flag)\n\t\tcontainer.register(\n\t\t\t'calibrator',\n\t\t\t() =>\n\t\t\t\tnew Calibrator(\n\t\t\t\t\tcontainer.resolve('outcomeRecorder'),\n\t\t\t\t\tconfig.features.calibration ?? false,\n\t\t\t\t),\n\t\t);\n\n\t\t// Register ThoughtEvaluator (stateless, transient) with injected calibrator\n\t\tcontainer.registerFactory(\n\t\t\t'ThoughtEvaluator',\n\t\t\t() => new ThoughtEvaluator(container.resolve('calibrator')),\n\t\t);\n\n\t\t// Register ThoughtProcessor\n\t\tcontainer.register('ThoughtProcessor', () => {\n\t\t\tconst history = container.resolve<HistoryManager>('HistoryManager');\n\t\t\tconst formatter = container.resolve<ThoughtFormatter>('ThoughtFormatter');\n\t\t\tconst evaluator = container.resolve<ThoughtEvaluator>('ThoughtEvaluator');\n\t\t\tconst log = container.resolve<StructuredLogger>('Logger');\n\t\t\tconst strategy = container.resolve<IReasoningStrategy>('reasoningStrategy');\n\t\t\tconst compressionService = config.features.compression\n\t\t\t\t? container.resolve<CompressionService>('compressionService')\n\t\t\t\t: undefined;\n\t\t\tconst suspensionStore = config.features.toolInterleave\n\t\t\t\t? container.resolve<ISuspensionStore>('suspensionStore')\n\t\t\t\t: undefined;\n\t\t\treturn new ThoughtProcessor(\n\t\t\t\thistory,\n\t\t\t\tformatter,\n\t\t\t\tevaluator,\n\t\t\t\tlog,\n\t\t\t\tstrategy,\n\t\t\t\tcompressionService,\n\t\t\t\tsuspensionStore,\n\t\t\t\tconfig.features,\n\t\t\t);\n\t\t});\n\n\t\treturn container;\n\t}\n\n\n\t/**\n\t * Create and configure the DI container with async persistence initialization.\n\t * This is used internally by the static create() factory.\n\t */\n\tprivate static async _createContainerAsyncStatic(options: ServerOptions): Promise<Container> {\n\t\tconst configLoader = new ConfigLoader();\n\t\tconst fileConfig = configLoader.load();\n\n\t\t// Initialize persistence backend (async)\n\t\tconst persistence = await createPersistenceBackend(\n\t\t\tfileConfig?.persistence ?? { enabled: false }\n\t\t);\n\n\t\treturn ToolAwareSequentialThinkingServer._createContainerCore(options, fileConfig, persistence);\n\t}\n\n\t/**\n\t * Get the DI container used by this server\n\t * Useful for testing and advanced customizations\n\t */\n\tpublic getContainer(): Container {\n\t\treturn this._container;\n\t}\n\n\t/**\n\t * Discover skills asynchronously without blocking server startup.\n\t * This is the recommended method for skill discovery.\n\t * @returns Promise<number> - The number of skills discovered\n\t */\n\tpublic async discoverSkillsAsync(): Promise<number> {\n\t\tconst discovered = await this.skills.discoverAsync();\n\t\treturn discovered;\n\t}\n\n\t/**\n\t * Get all branches from the history manager\n\t * @returns Record<string, ThoughtData[]> - Map of branch IDs to thought arrays\n\t */\n\tpublic getBranches(): Record<string, ThoughtData[]> {\n\t\treturn this._historyManager.getBranches();\n\t}\n\n\t// Main processing method - delegate to ThoughtProcessor\n\tpublic async processThought(input: v.InferInput<typeof SequentialThinkingSchema>) {\n\t\tconst startTime = Date.now();\n\t\tconst thoughtInput = input as ThoughtData & { register_branch_id?: string };\n\t\tif (typeof thoughtInput.register_branch_id === 'string' && thoughtInput.register_branch_id.length > 0) {\n\t\t\ttry {\n\t\t\t\tthis._historyManager.registerBranch(\n\t\t\t\t\tthoughtInput.session_id,\n\t\t\t\t\tthoughtInput.register_branch_id\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthis._logger.warn('registerBranch skipped', {\n\t\t\t\t\tbranch_id: thoughtInput.register_branch_id,\n\t\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t\t});\n\t\t\t}\n\t\t\tdelete thoughtInput.register_branch_id;\n\t\t}\n\t\tconst result = await this._thoughtProcessor.process(thoughtInput);\n\t\tconst durationSeconds = (Date.now() - startTime) / 1000;\n\t\tthis._metrics.histogram('thought_processing_duration_seconds', durationSeconds, {});\n\t\treturn result;\n\t}\n\n\tpublic getMetricsSnapshot(): string {\n\t\treturn this._metrics.export();\n\t}\n\n\t/**\n\t * Stop the server and clean up watchers.\n\t * Closes persistence backend gracefully to ensure data is flushed.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tthis._skillWatcher?.stop();\n\t\tthis._toolWatcher?.stop();\n\n\t\t// Stop suspension store sweeper if registered\n\t\tif (this._config.features.toolInterleave && this._container.has('suspensionStore')) {\n\t\t\ttry {\n\t\t\t\tconst suspensionStore = this._container.resolve<ISuspensionStore>('suspensionStore');\n\t\t\t\tsuspensionStore.stop();\n\t\t\t} catch (error) {\n\t\t\t\tthis._logger.error('Error stopping suspension store', {\n\t\t\t\t\terror: getErrorMessage(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Flush any buffered writes before closing persistence\n\t\ttry {\n\t\t\tawait this._historyManager.shutdown();\n\t\t} catch (error) {\n\t\t\tthis._logger.error('Error flushing write buffer during shutdown', {\n\t\t\t\terror: getErrorMessage(error),\n\t\t\t});\n\t\t}\n\n\t\t// Close persistence backend if available\n\t\tconst persistence = this._container.resolve<PersistenceBackend | null>('Persistence');\n\t\tif (persistence) {\n\t\t\ttry {\n\t\t\t\tawait persistence.close();\n\t\t\t\tthis._logger.info('Persistence backend closed');\n\t\t\t} catch (error) {\n\t\t\t\tthis._logger.error('Error closing persistence backend', {\n\t\t\t\t\terror: getErrorMessage(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis._logger.info('Server stopped, watchers cleaned up');\n\t}\n\n\t/**\n\t * Clear all server state (history, tools, skills)\n\t * Useful for testing to reset state between tests\n\t */\n\tpublic clear(): void {\n\t\tthis._historyManager.clear();\n\t\tthis._logger.info('Server state cleared');\n\t}\n\n\t/**\n\t * Dispose of the server and all container services.\n\t * Implements the IDisposable interface.\n\t * Calls stop() for existing cleanup, then disposes the DI container.\n\t */\n\tpublic async dispose(): Promise<void> {\n\t\tawait this.stop();\n\t\tawait this._container.dispose();\n\t\tthis._logger.info('Server disposed, all resources released');\n\t}\n}\n\n/**\n * Factory function to create a new server instance with async initialization.\n *\n * This is the recommended way to create server instances, especially for testing,\n * as it allows for proper async initialization, dependency injection, and persistence.\n *\n * @param options - Server configuration options\n * @returns A Promise that resolves to a configured server instance\n *\n * @example\n * ```typescript\n * // Basic usage (with async discovery and persistence)\n * const server = await createServer();\n *\n * // With custom options\n * const server = await createServer({\n * autoDiscover: false,\n * lazyDiscovery: true,\n * maxHistorySize: 500,\n * loadFromPersistence: true\n * });\n *\n * // With custom container for testing\n * const mockContainer = new Container();\n * mockContainer.registerInstance('Logger', mockLogger);\n * const server = await createServer({ container: mockContainer });\n * ```\n */\nexport async function createServer(\n\toptions: ServerOptions = {}\n): Promise<ToolAwareSequentialThinkingServer> {\n\treturn ToolAwareSequentialThinkingServer.create(options);\n}\n\n// Initialize server\nexport async function initializeServer(): Promise<ToolAwareSequentialThinkingServer> {\n\t// Create logger for initialization\n\tconst configLoader = new ConfigLoader();\n\tconst fileConfig = configLoader.load();\n\n\tconst logger = new StructuredLogger({\n\t\tlevel: fileConfig?.logLevel ?? 'info',\n\t\tcontext: 'SequentialThinking',\n\t\tpretty: fileConfig?.prettyLog ?? true,\n\t});\n\n\t// Create server instance\n\tconst thinkingServer = await createServer({\n\t\tlogger,\n\t\tenableWatcher: true,\n\t});\n\n\tlogger.info('Server initialized successfully');\n\treturn thinkingServer;\n}\n"],"names":["ToolAwareSequentialThinkingServer","EventEmitter","options","container","server","event","payload","listener","Error","SEQUENTIAL_THINKING_TOOL","SkillWatcher","ToolWatcher","fileConfig","persistence","Container","metrics","Metrics","config","ServerConfig","logger","StructuredLogger","ToolRegistry","DiscoveryCache","undefined","SkillRegistry","EdgeStore","InMemorySummaryStore","store","InMemorySuspensionStore","historyManager","edgeStore","summaryStore","log","CompressionService","createReasoningStrategy","cfg","pers","componentMetrics","HistoryManager","ThoughtFormatter","OutcomeRecorder","Calibrator","ThoughtEvaluator","history","formatter","evaluator","strategy","compressionService","suspensionStore","ThoughtProcessor","configLoader","ConfigLoader","createPersistenceBackend","discovered","input","startTime","Date","thoughtInput","err","String","result","durationSeconds","error","getErrorMessage","createServer","initializeServer","thinkingServer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA2JO,MAAMA,0CAA0CC;IAQtD,aAAa,OAAOC,UAAyB,CAAC,CAAC,EAA8C;QAE5F,MAAMC,YAAY,MAAMH,kCAAkC,2BAA2B,CAACE;QAGtF,MAAME,SAAS,IAAIJ,kCAAkC;YACpD,GAAGE,OAAO;YACVC;QACD;QAGA,IAAID,AAAgC,UAAhCA,QAAQ,mBAAmB,EAC9B,MAAME,OAAO,OAAO,CAAC,mBAAmB;QAIzC,IAAIF,AAAyB,UAAzBA,QAAQ,YAAY,EACvB,MAAME,OAAO,mBAAmB;QAGjC,OAAOA;IACR;IAGS,KAAmCC,KAAQ,EAAEC,OAAwB,EAAW;QACxF,OAAO,KAAK,CAAC,KAAKD,OAAOC;IAC1B;IAES,GACRD,KAAQ,EACRE,QAA4C,EACrC;QACP,OAAO,KAAK,CAAC,GAAGF,OAAOE;IACxB;IAGQ,WAAsB;IAGtB,QAA0B;IAC1B,gBAAgC;IAChC,kBAAoC;IACpC,SAAkB;IAClB,gBAAqC,KAAK;IAC1C,eAAmC,KAAK;IACxC,QAAsB;IAWd,QAAwB;IAUxB,MAAoB;IAUpB,OAAsB;IAStB,OAAqB;IAErC,YAAYL,UAAyB,CAAC,CAAC,CAAE;QAExC,KAAK;QACL,IAAI,CAACA,QAAQ,SAAS,EACrB,MAAM,IAAIM,MAAM;QAEjB,IAAI,CAAC,UAAU,GAAGN,QAAQ,SAAS;QAGnC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAmB;QACzD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAiB;QAC/D,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAmB;QACnE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAU;QACjD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAe;QAGrD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,eAAe;QAGnC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,IAAI;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAe;QACnD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAgB;QACrD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO;QAG1B,IAAI,CAAC,KAAK,CAAC,OAAO,CAACO;QAInB,IAAIP,QAAQ,aAAa,EAAE;YAC1B,IAAI,CAAC,aAAa,GAAG,IAAIQ,aAAa,IAAI,CAAC,MAAM;YACjD,IAAI,CAAC,YAAY,GAAG,IAAIC,YAAY,IAAI,CAAC,KAAK;QAC/C;IACD;IAMA,OAAe,qBACdT,OAAsB,EACtBU,UAAoC,EACpCC,WAAsC,EAC1B;QACZ,MAAMV,YAAY,IAAIW;QACtB,MAAMC,UAAU,IAAIC,QAAQ;YAC3B,QAAQ;QACT;QAGA,MAAMC,SAAS,IAAIC,aAAa;YAC/B,gBAAgBhB,QAAQ,cAAc,IAAIU,YAAY;YACtD,aAAaV,QAAQ,WAAW,IAAIU,YAAY;YAChD,eAAeV,QAAQ,aAAa,IAAIU,YAAY;YACpD,WAAWA,YAAY;YACvB,gBAAgBA,YAAY;YAC5B,aAAaA,YAAY;QAC1B;QAGA,MAAMO,SACLjB,QAAQ,MAAM,IACd,IAAIkB,iBAAiB;YACpB,OAAOR,YAAY,YAAY;YAC/B,SAAS;YACT,QAAQA,YAAY,aAAa;QAClC;QAGDT,UAAU,gBAAgB,CAAC,UAAUgB;QACrChB,UAAU,gBAAgB,CAAC,UAAUc;QACrCd,UAAU,gBAAgB,CAAC,cAAcS,cAAc,CAAC;QACxDT,UAAU,gBAAgB,CAAC,eAAeU;QAC1CV,UAAU,gBAAgB,CAAC,WAAWY;QACtCZ,UAAU,QAAQ,CACjB,gBACA,IACC,IAAIkB,aAAa;gBAChBF;gBACA,OAAOF,OAAO,cAAc,GACzB,IAAIK,eAAe;oBAAE,GAAGL,OAAO,cAAc;oBAAEF;gBAAQ,KACvDQ;YACJ;QAEFpB,UAAU,QAAQ,CACjB,iBACA,IACC,IAAIqB,cAAc;gBACjBL;gBACA,OAAOF,OAAO,cAAc,GACzB,IAAIK,eAAe;oBAAE,GAAGL,OAAO,cAAc;oBAAEF;gBAAQ,KACvDQ;gBACH,WAAWN,OAAO,SAAS;gBAC3B,eAAef,QAAQ,aAAa;YACrC;QAIFC,UAAU,QAAQ,CAAC,aAAa,IAAM,IAAIsB;QAG1CtB,UAAU,QAAQ,CAAC,gBAAgB,IAAM,IAAIuB;QAG7C,IAAIT,OAAO,QAAQ,CAAC,cAAc,EACjCd,UAAU,QAAQ,CAAC,mBAAmB;YACrC,MAAMwB,QAAQ,IAAIC,wBAAwB;gBACzC,OAAOX,OAAO,mBAAmB;gBACjC,iBAAiBA,OAAO,qBAAqB;gBAC7CE;YACD;YACAQ,MAAM,KAAK;YACX,OAAOA;QACR;QAIDxB,UAAU,QAAQ,CAAC,sBAAsB;YACxC,MAAM0B,iBAAiB1B,UAAU,OAAO,CAAiB;YACzD,MAAM2B,YAAY3B,UAAU,OAAO,CAAY;YAC/C,MAAM4B,eAAe5B,UAAU,OAAO,CAAgB;YACtD,MAAM6B,MAAM7B,UAAU,OAAO,CAAmB;YAChD,OAAO,IAAI8B,mBAAmB;gBAAEJ;gBAAgBC;gBAAWC;gBAAc,QAAQC;YAAI;QACtF;QAGA7B,UAAU,QAAQ,CAAC,qBAAqB,IACvC+B,wBAAwBjB,OAAO,QAAQ,CAAC,iBAAiB;QAI1Dd,UAAU,QAAQ,CAAC,kBAAkB;YACpC,MAAMgC,MAAMhC,UAAU,OAAO,CAAe;YAC5C,MAAM6B,MAAM7B,UAAU,OAAO,CAAmB;YAChD,MAAMiC,OAAOjC,UAAU,OAAO,CAAC;YAC/B,MAAMkC,mBAAmBlC,UAAU,OAAO,CAAU;YACpD,MAAM2B,YAAY3B,UAAU,OAAO,CAAY;YAC/C,OAAO,IAAImC,eAAe;gBACzB,gBAAgBH,IAAI,cAAc;gBAClC,aAAaA,IAAI,WAAW;gBAC5B,eAAeA,IAAI,aAAa;gBAChC,QAAQH;gBACR,aAAaI;gBACb,SAASC;gBACT,uBAAuBF,IAAI,qBAAqB;gBAChD,0BAA0BA,IAAI,wBAAwB;gBACtD,uBAAuBA,IAAI,qBAAqB;gBAChDL;YACD;QACD;QAGA3B,UAAU,eAAe,CAAC,oBAAoB,IAAM,IAAIoC;QAGxDpC,UAAU,QAAQ,CACjB,mBACA,IAAM,IAAIqC,gBAAgB;gBAAE,SAASvB,OAAO,QAAQ,CAAC,gBAAgB,IAAI;YAAM;QAIhFd,UAAU,QAAQ,CACjB,cACA,IACC,IAAIsC,WACHtC,UAAU,OAAO,CAAC,oBAClBc,OAAO,QAAQ,CAAC,WAAW,IAAI;QAKlCd,UAAU,eAAe,CACxB,oBACA,IAAM,IAAIuC,iBAAiBvC,UAAU,OAAO,CAAC;QAI9CA,UAAU,QAAQ,CAAC,oBAAoB;YACtC,MAAMwC,UAAUxC,UAAU,OAAO,CAAiB;YAClD,MAAMyC,YAAYzC,UAAU,OAAO,CAAmB;YACtD,MAAM0C,YAAY1C,UAAU,OAAO,CAAmB;YACtD,MAAM6B,MAAM7B,UAAU,OAAO,CAAmB;YAChD,MAAM2C,WAAW3C,UAAU,OAAO,CAAqB;YACvD,MAAM4C,qBAAqB9B,OAAO,QAAQ,CAAC,WAAW,GACnDd,UAAU,OAAO,CAAqB,wBACtCoB;YACH,MAAMyB,kBAAkB/B,OAAO,QAAQ,CAAC,cAAc,GACnDd,UAAU,OAAO,CAAmB,qBACpCoB;YACH,OAAO,IAAI0B,iBACVN,SACAC,WACAC,WACAb,KACAc,UACAC,oBACAC,iBACA/B,OAAO,QAAQ;QAEjB;QAEA,OAAOd;IACR;IAOA,aAAqB,4BAA4BD,OAAsB,EAAsB;QAC5F,MAAMgD,eAAe,IAAIC;QACzB,MAAMvC,aAAasC,aAAa,IAAI;QAGpC,MAAMrC,cAAc,MAAMuC,yBACzBxC,YAAY,eAAe;YAAE,SAAS;QAAM;QAG7C,OAAOZ,kCAAkC,oBAAoB,CAACE,SAASU,YAAYC;IACpF;IAMO,eAA0B;QAChC,OAAO,IAAI,CAAC,UAAU;IACvB;IAOA,MAAa,sBAAuC;QACnD,MAAMwC,aAAa,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa;QAClD,OAAOA;IACR;IAMO,cAA6C;QACnD,OAAO,IAAI,CAAC,eAAe,CAAC,WAAW;IACxC;IAGA,MAAa,eAAeC,KAAoD,EAAE;QACjF,MAAMC,YAAYC,KAAK,GAAG;QAC1B,MAAMC,eAAeH;QACrB,IAAI,AAA2C,YAA3C,OAAOG,aAAa,kBAAkB,IAAiBA,aAAa,kBAAkB,CAAC,MAAM,GAAG,GAAG;YACtG,IAAI;gBACH,IAAI,CAAC,eAAe,CAAC,cAAc,CAClCA,aAAa,UAAU,EACvBA,aAAa,kBAAkB;YAEjC,EAAE,OAAOC,KAAK;gBACb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0BAA0B;oBAC3C,WAAWD,aAAa,kBAAkB;oBAC1C,OAAOC,eAAelD,QAAQkD,IAAI,OAAO,GAAGC,OAAOD;gBACpD;YACD;YACA,OAAOD,aAAa,kBAAkB;QACvC;QACA,MAAMG,SAAS,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAACH;QACpD,MAAMI,kBAAmBL,AAAAA,CAAAA,KAAK,GAAG,KAAKD,SAAQ,IAAK;QACnD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,uCAAuCM,iBAAiB,CAAC;QACjF,OAAOD;IACR;IAEO,qBAA6B;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM;IAC5B;IAMA,MAAa,OAAsB;QAClC,IAAI,CAAC,aAAa,EAAE;QACpB,IAAI,CAAC,YAAY,EAAE;QAGnB,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,oBAC/D,IAAI;YACH,MAAMZ,kBAAkB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAmB;YAClEA,gBAAgB,IAAI;QACrB,EAAE,OAAOc,OAAO;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,mCAAmC;gBACrD,OAAOC,gBAAgBD;YACxB;QACD;QAID,IAAI;YACH,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ;QACpC,EAAE,OAAOA,OAAO;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,+CAA+C;gBACjE,OAAOC,gBAAgBD;YACxB;QACD;QAGA,MAAMjD,cAAc,IAAI,CAAC,UAAU,CAAC,OAAO,CAA4B;QACvE,IAAIA,aACH,IAAI;YACH,MAAMA,YAAY,KAAK;YACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QACnB,EAAE,OAAOiD,OAAO;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,qCAAqC;gBACvD,OAAOC,gBAAgBD;YACxB;QACD;QAGD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IACnB;IAMO,QAAc;QACpB,IAAI,CAAC,eAAe,CAAC,KAAK;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IACnB;IAOA,MAAa,UAAyB;QACrC,MAAM,IAAI,CAAC,IAAI;QACf,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IACnB;AACD;AA8BO,eAAeE,aACrB9D,UAAyB,CAAC,CAAC;IAE3B,OAAOF,kCAAkC,MAAM,CAACE;AACjD;AAGO,eAAe+D;IAErB,MAAMf,eAAe,IAAIC;IACzB,MAAMvC,aAAasC,aAAa,IAAI;IAEpC,MAAM/B,SAAS,IAAIC,iBAAiB;QACnC,OAAOR,YAAY,YAAY;QAC/B,SAAS;QACT,QAAQA,YAAY,aAAa;IAClC;IAGA,MAAMsD,iBAAiB,MAAMF,aAAa;QACzC7C;QACA,eAAe;IAChB;IAEAA,OAAO,IAAI,CAAC;IACZ,OAAO+C;AACR"}
@@ -1,8 +1,8 @@
1
- import type { IMetrics } from '../contracts/index.js';
1
+ import type { IMetrics } from '../contracts/interfaces.js';
2
2
  import type { ThoughtData } from '../core/thought.js';
3
3
  import type { Edge } from '../core/graph/Edge.js';
4
4
  import type { Summary } from '../core/compression/Summary.js';
5
- import type { PersistenceBackend, PersistenceConfig } from './PersistenceBackend.js';
5
+ import type { PersistenceBackend, PersistenceConfig } from '../contracts/PersistenceBackend.js';
6
6
  /**
7
7
  * File-based persistence backend using JSON files.
8
8
  *
@@ -1 +1 @@
1
- {"version":3,"file":"FilePersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/FilePersistence.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAErF;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IACzD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,CAAW;gBAEhB,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAA;KAAE;IAe3E,OAAO,CAAC,wBAAwB;IAKhC;;OAEG;YACW,kBAAkB;IAehC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IAoBV,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhD,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAoBrC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBpE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IA0BhE,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyCtB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IASxC;;OAEG;IACI,UAAU,IAAI,MAAM;IAI3B;;OAEG;IACU,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAa9C;;;OAGG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAkBrB;;;;;OAKG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBhF;;;;;OAKG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAqB1D;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IASlD;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;;;;OAMG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B3F;;;;;OAKG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAqBjE"}
1
+ {"version":3,"file":"FilePersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/FilePersistence.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEhG;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IACzD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,CAAW;gBAEhB,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAA;KAAE;IAe3E,OAAO,CAAC,wBAAwB;IAKhC;;OAEG;YACW,kBAAkB;IAehC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IAoBV,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhD,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAoBrC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBpE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IA0BhE,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyCtB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IASxC;;OAEG;IACI,UAAU,IAAI,MAAM;IAI3B;;OAEG;IACU,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAa9C;;;OAGG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAkBrB;;;;;OAKG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBhF;;;;;OAKG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAqB1D;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IASlD;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;;;;OAMG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B3F;;;;;OAKG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAqBjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/FilePersistence.js","sources":["../../src/persistence/FilePersistence.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, readFile, readdir, rename, unlink, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join, resolve, sep } from 'node:path';\nimport type { IMetrics } from '../contracts/index.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { PersistenceBackend, PersistenceConfig } from './PersistenceBackend.js';\n\n/**\n * File-based persistence backend using JSON files.\n *\n * Stores thoughts and branches as JSON files in a configured directory.\n * Simple and reliable, with no external dependencies.\n *\n * File structure:\n * ```\n * dataDir/\n * history.json # Main thought history\n * branches/\n * <branch-id>.json # Individual branch files\n * ```\n */\nexport class FilePersistence implements PersistenceBackend {\n\tprivate _dataDir: string;\n\tprivate _historyPath: string;\n\tprivate _branchesDir: string;\n\tprivate _edgesDir: string;\n\tprivate _summariesDir: string;\n\tprivate _maxHistorySize: number;\n\tprivate _persistBranches: boolean;\n\tprivate _metrics?: IMetrics;\n\n\tconstructor(options?: PersistenceConfig['options'] & { metrics?: IMetrics }) {\n\t\t// Default to .claude/data in current directory or home directory\n\t\tconst defaultDataDir = existsSync('.claude/data')\n\t\t\t? '.claude/data'\n\t\t\t: join(homedir(), '.claude/data');\n\t\tthis._dataDir = options?.dataDir ?? defaultDataDir;\n\t\tthis._historyPath = join(this._dataDir, 'history.json');\n\t\tthis._branchesDir = join(this._dataDir, 'branches');\n\t\tthis._edgesDir = join(this._dataDir, 'edges');\n\t\tthis._summariesDir = join(this._dataDir, 'summaries');\n\t\tthis._maxHistorySize = options?.maxHistorySize ?? 10000;\n\t\tthis._persistBranches = options?.persistBranches ?? true;\n\t\tthis._metrics = options?.metrics;\n\t}\n\n\tprivate _recordOperationDuration(operation: string, startTime: number): void {\n\t\tconst durationSeconds = (Date.now() - startTime) / 1000;\n\t\tthis._metrics?.histogram('persistence_op_duration_seconds', durationSeconds, { operation });\n\t}\n\n\t/**\n\t * Initialize the persistence directory structure.\n\t */\n\tprivate async _ensureDirectories(): Promise<void> {\n\t\tif (!existsSync(this._dataDir)) {\n\t\t\tawait mkdir(this._dataDir, { recursive: true });\n\t\t}\n\t\tif (this._persistBranches && !existsSync(this._branchesDir)) {\n\t\t\tawait mkdir(this._branchesDir, { recursive: true });\n\t\t}\n\t\tif (!existsSync(this._edgesDir)) {\n\t\t\tawait mkdir(this._edgesDir, { recursive: true });\n\t\t}\n\t\tif (!existsSync(this._summariesDir)) {\n\t\t\tawait mkdir(this._summariesDir, { recursive: true });\n\t\t}\n\t}\n\n\t/**\n\t * Validates branch ID format and resolves the path safely.\n\t *\n\t * This method provides defense-in-depth security by:\n\t * 1. Validating the branch ID format (alphanumeric, hyphens, underscores only)\n\t * 2. Preventing path traversal attacks\n\t *\n\t * @param branchId - The branch ID to validate and resolve\n\t * @returns The safe, resolved branch file path\n\t * @throws Error if branch ID is invalid or path traversal is detected\n\t */\n\tprivate _safeBranchPath(branchId: string): string {\n\t\t// Validate format first (must be alphanumeric with hyphens/underscores, 1-64 chars)\n\t\tconst validBranchIdPattern = /^[a-zA-Z0-9_-]{1,64}$/;\n\t\tif (!validBranchIdPattern.test(branchId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid branch ID: must be 1-64 alphanumeric characters, hyphens, or underscores only`\n\t\t\t);\n\t\t}\n\n\t\tconst resolved = resolve(this._branchesDir, `${branchId}.json`);\n\t\tconst normalizedBranchesDir = resolve(this._branchesDir);\n\n\t\t// Ensure the resolved path is still within branches directory\n\t\tif (!resolved.startsWith(normalizedBranchesDir + sep)) {\n\t\t\tthrow new Error(`Invalid branch ID: path traversal detected`);\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\tpublic async saveThought(thought: ThoughtData): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tconst history = await this.loadHistory();\n\t\t\thistory.push(thought);\n\n\t\t\tif (history.length > this._maxHistorySize) {\n\t\t\t\thistory.splice(0, history.length - this._maxHistorySize);\n\t\t\t}\n\n\t\t\tawait writeFile(this._historyPath, JSON.stringify(history, null, 2), 'utf-8');\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_thought', startTime);\n\t\t}\n\t}\n\n\tpublic async loadHistory(): Promise<ThoughtData[]> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tif (!existsSync(this._historyPath)) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\tconst content = await readFile(this._historyPath, 'utf-8');\n\t\t\tconst data = JSON.parse(content) as ThoughtData[];\n\n\t\t\t// Validate and filter\n\t\t\treturn Array.isArray(data) ? data : [];\n\t\t} catch {\n\t\t\t// If file is corrupted, start fresh\n\t\t\treturn [];\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_history', startTime);\n\t\t}\n\t}\n\n\tpublic async saveBranch(branchId: string, thoughts: ThoughtData[]): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tif (!this._persistBranches) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tconst branchPath = this._safeBranchPath(branchId);\n\t\t\tawait writeFile(branchPath, JSON.stringify(thoughts, null, 2), 'utf-8');\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_branch', startTime);\n\t\t}\n\t}\n\n\tpublic async loadBranch(branchId: string): Promise<ThoughtData[] | undefined> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tif (!this._persistBranches) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst branchPath = this._safeBranchPath(branchId);\n\n\t\t\ttry {\n\t\t\t\tif (!existsSync(branchPath)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tconst content = await readFile(branchPath, 'utf-8');\n\t\t\t\tconst data = JSON.parse(content) as ThoughtData[];\n\n\t\t\t\treturn Array.isArray(data) ? data : undefined;\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_branch', startTime);\n\t\t}\n\t}\n\n\tpublic async listBranches(): Promise<string[]> {\n\t\treturn this.getBranchIds();\n\t}\n\n\tpublic async clear(): Promise<void> {\n\t\ttry {\n\t\t\t// Clear history\n\t\t\tif (existsSync(this._historyPath)) {\n\t\t\t\tawait unlink(this._historyPath);\n\t\t\t}\n\n\t\t\t// Clear all branches\n\t\t\tif (this._persistBranches && existsSync(this._branchesDir)) {\n\t\t\t\tconst files = await readdir(this._branchesDir);\n\t\t\t\tfor (const file of files) {\n\t\t\t\t\tif (file.endsWith('.json')) {\n\t\t\t\t\t\tawait unlink(join(this._branchesDir, file));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Clear all edges\n\t\t\tif (existsSync(this._edgesDir)) {\n\t\t\t\tconst edgeFiles = await readdir(this._edgesDir);\n\t\t\t\tfor (const file of edgeFiles) {\n\t\t\t\t\tif (file.endsWith('.json')) {\n\t\t\t\t\t\tawait unlink(join(this._edgesDir, file));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Clear all summaries\n\t\t\tif (existsSync(this._summariesDir)) {\n\t\t\t\tconst summaryFiles = await readdir(this._summariesDir);\n\t\t\t\tfor (const file of summaryFiles) {\n\t\t\t\t\tif (file.endsWith('.json')) {\n\t\t\t\t\t\tawait unlink(join(this._summariesDir, file));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors during clear\n\t\t}\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Get the data directory path.\n\t */\n\tpublic getDataDir(): string {\n\t\treturn this._dataDir;\n\t}\n\n\t/**\n\t * Get all branch IDs that are persisted.\n\t */\n\tpublic async getBranchIds(): Promise<string[]> {\n\t\tif (!this._persistBranches || !existsSync(this._branchesDir)) {\n\t\t\treturn [];\n\t\t}\n\n\t\ttry {\n\t\t\tconst files = await readdir(this._branchesDir);\n\t\t\treturn files.filter((f) => f.endsWith('.json')).map((f) => f.replace('.json', ''));\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Close the backend and release resources.\n\t * No resources to release for file backend.\n\t */\n\tpublic async close(): Promise<void> {\n\t\t// No-op for file backend (files are already flushed on write)\n\t}\n\n\t/**\n\t * Validates session ID format and resolves the edge file path safely.\n\t *\n\t * @param sessionId - The session ID to validate and resolve\n\t * @returns The safe, resolved edge file path\n\t * @throws Error if session ID is invalid or path traversal is detected\n\t */\n\tprivate _safeEdgePath(sessionId: string): string {\n\t\tconst validSessionIdPattern = /^[a-zA-Z0-9_-]{1,100}$/;\n\t\tif (!validSessionIdPattern.test(sessionId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid session ID for edges: must be 1-100 alphanumeric characters, hyphens, or underscores only`\n\t\t\t);\n\t\t}\n\n\t\tconst resolved = resolve(this._edgesDir, `${sessionId}.json`);\n\t\tconst normalizedEdgesDir = resolve(this._edgesDir);\n\n\t\tif (!resolved.startsWith(normalizedEdgesDir + sep)) {\n\t\t\tthrow new Error(`Invalid session ID: path traversal detected`);\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Save edges for a session to a JSON file.\n\t *\n\t * @param sessionId - The session ID\n\t * @param edges - Edges to persist (sorted by createdAt before write)\n\t */\n\tpublic async saveEdges(sessionId: string, edges: readonly Edge[]): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tif (!existsSync(this._edgesDir)) {\n\t\t\t\tawait mkdir(this._edgesDir, { recursive: true });\n\t\t\t}\n\n\t\t\tconst edgePath = this._safeEdgePath(sessionId);\n\n\t\t\tif (edges.length === 0) {\n\t\t\t\tif (existsSync(edgePath)) {\n\t\t\t\t\tawait unlink(edgePath);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sorted = [...edges].sort((a, b) => a.createdAt - b.createdAt);\n\t\t\tawait writeFile(edgePath, JSON.stringify(sorted, null, 2), 'utf-8');\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_edges', startTime);\n\t\t}\n\t}\n\n\t/**\n\t * Load edges for a session from a JSON file.\n\t *\n\t * @param sessionId - The session ID\n\t * @returns Edges array (empty if file is missing or corrupted)\n\t */\n\tpublic async loadEdges(sessionId: string): Promise<Edge[]> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tconst edgePath = this._safeEdgePath(sessionId);\n\n\t\t\tif (!existsSync(edgePath)) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(edgePath, 'utf-8');\n\t\t\t\tconst data = JSON.parse(content) as Edge[];\n\t\t\t\treturn Array.isArray(data) ? data : [];\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_edges', startTime);\n\t\t}\n\t}\n\n\t/**\n\t * List all session IDs that have persisted edge files.\n\t *\n\t * @returns Array of session identifiers (filenames without .json extension)\n\t */\n\tpublic async listEdgeSessions(): Promise<string[]> {\n\t\ttry {\n\t\t\tconst files = await readdir(this._edgesDir);\n\t\t\treturn files.filter((f) => f.endsWith('.json')).map((f) => f.slice(0, -5));\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Validates session ID format and resolves the summary file path safely.\n\t *\n\t * @param sessionId - The session ID to validate and resolve\n\t * @returns The safe, resolved summary file path\n\t * @throws Error if session ID is invalid or path traversal is detected\n\t */\n\tprivate _safeSummaryPath(sessionId: string): string {\n\t\tconst validSessionIdPattern = /^[a-zA-Z0-9_-]{1,100}$/;\n\t\tif (!validSessionIdPattern.test(sessionId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid session ID for summaries: must be 1-100 alphanumeric characters, hyphens, or underscores only`\n\t\t\t);\n\t\t}\n\n\t\tconst resolved = resolve(this._summariesDir, `${sessionId}.json`);\n\t\tconst normalizedSummariesDir = resolve(this._summariesDir);\n\n\t\tif (!resolved.startsWith(normalizedSummariesDir + sep)) {\n\t\t\tthrow new Error(`Invalid session ID: path traversal detected`);\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Save summaries for a session to a JSON file using an atomic\n\t * write (tmp file + rename) to prevent partial-write corruption.\n\t *\n\t * @param sessionId - The session ID\n\t * @param summaries - Summaries to persist (sorted by createdAt before write)\n\t */\n\tpublic async saveSummaries(sessionId: string, summaries: readonly Summary[]): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tif (!existsSync(this._summariesDir)) {\n\t\t\t\tawait mkdir(this._summariesDir, { recursive: true });\n\t\t\t}\n\n\t\t\tconst summaryPath = this._safeSummaryPath(sessionId);\n\n\t\t\tif (summaries.length === 0) {\n\t\t\t\tif (existsSync(summaryPath)) {\n\t\t\t\t\tawait unlink(summaryPath);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sorted = [...summaries].sort((a, b) => a.createdAt - b.createdAt);\n\t\t\tconst tmpPath = `${summaryPath}.tmp`;\n\t\t\tawait writeFile(tmpPath, JSON.stringify(sorted, null, 2), 'utf-8');\n\t\t\tawait rename(tmpPath, summaryPath);\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_summaries', startTime);\n\t\t}\n\t}\n\n\t/**\n\t * Load summaries for a session from a JSON file.\n\t *\n\t * @param sessionId - The session ID\n\t * @returns Summaries array (empty if file is missing or corrupted)\n\t */\n\tpublic async loadSummaries(sessionId: string): Promise<Summary[]> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tconst summaryPath = this._safeSummaryPath(sessionId);\n\n\t\t\tif (!existsSync(summaryPath)) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(summaryPath, 'utf-8');\n\t\t\t\tconst data = JSON.parse(content) as Summary[];\n\t\t\t\tif (!Array.isArray(data)) return [];\n\t\t\t\treturn [...data].sort((a, b) => a.createdAt - b.createdAt);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_summaries', startTime);\n\t\t}\n\t}\n}\n"],"names":["FilePersistence","options","defaultDataDir","existsSync","join","homedir","operation","startTime","durationSeconds","Date","mkdir","branchId","validBranchIdPattern","Error","resolved","resolve","normalizedBranchesDir","sep","thought","history","writeFile","JSON","content","readFile","data","Array","thoughts","branchPath","undefined","unlink","files","readdir","file","edgeFiles","summaryFiles","f","sessionId","validSessionIdPattern","normalizedEdgesDir","edges","edgePath","sorted","a","b","normalizedSummariesDir","summaries","summaryPath","tmpPath","rename"],"mappings":"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"}
1
+ {"version":3,"file":"persistence/FilePersistence.js","sources":["../../src/persistence/FilePersistence.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, readFile, readdir, rename, unlink, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join, resolve, sep } from 'node:path';\nimport type { IMetrics } from '../contracts/interfaces.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { PersistenceBackend, PersistenceConfig } from '../contracts/PersistenceBackend.js';\n\n/**\n * File-based persistence backend using JSON files.\n *\n * Stores thoughts and branches as JSON files in a configured directory.\n * Simple and reliable, with no external dependencies.\n *\n * File structure:\n * ```\n * dataDir/\n * history.json # Main thought history\n * branches/\n * <branch-id>.json # Individual branch files\n * ```\n */\nexport class FilePersistence implements PersistenceBackend {\n\tprivate _dataDir: string;\n\tprivate _historyPath: string;\n\tprivate _branchesDir: string;\n\tprivate _edgesDir: string;\n\tprivate _summariesDir: string;\n\tprivate _maxHistorySize: number;\n\tprivate _persistBranches: boolean;\n\tprivate _metrics?: IMetrics;\n\n\tconstructor(options?: PersistenceConfig['options'] & { metrics?: IMetrics }) {\n\t\t// Default to .claude/data in current directory or home directory\n\t\tconst defaultDataDir = existsSync('.claude/data')\n\t\t\t? '.claude/data'\n\t\t\t: join(homedir(), '.claude/data');\n\t\tthis._dataDir = options?.dataDir ?? defaultDataDir;\n\t\tthis._historyPath = join(this._dataDir, 'history.json');\n\t\tthis._branchesDir = join(this._dataDir, 'branches');\n\t\tthis._edgesDir = join(this._dataDir, 'edges');\n\t\tthis._summariesDir = join(this._dataDir, 'summaries');\n\t\tthis._maxHistorySize = options?.maxHistorySize ?? 10000;\n\t\tthis._persistBranches = options?.persistBranches ?? true;\n\t\tthis._metrics = options?.metrics;\n\t}\n\n\tprivate _recordOperationDuration(operation: string, startTime: number): void {\n\t\tconst durationSeconds = (Date.now() - startTime) / 1000;\n\t\tthis._metrics?.histogram('persistence_op_duration_seconds', durationSeconds, { operation });\n\t}\n\n\t/**\n\t * Initialize the persistence directory structure.\n\t */\n\tprivate async _ensureDirectories(): Promise<void> {\n\t\tif (!existsSync(this._dataDir)) {\n\t\t\tawait mkdir(this._dataDir, { recursive: true });\n\t\t}\n\t\tif (this._persistBranches && !existsSync(this._branchesDir)) {\n\t\t\tawait mkdir(this._branchesDir, { recursive: true });\n\t\t}\n\t\tif (!existsSync(this._edgesDir)) {\n\t\t\tawait mkdir(this._edgesDir, { recursive: true });\n\t\t}\n\t\tif (!existsSync(this._summariesDir)) {\n\t\t\tawait mkdir(this._summariesDir, { recursive: true });\n\t\t}\n\t}\n\n\t/**\n\t * Validates branch ID format and resolves the path safely.\n\t *\n\t * This method provides defense-in-depth security by:\n\t * 1. Validating the branch ID format (alphanumeric, hyphens, underscores only)\n\t * 2. Preventing path traversal attacks\n\t *\n\t * @param branchId - The branch ID to validate and resolve\n\t * @returns The safe, resolved branch file path\n\t * @throws Error if branch ID is invalid or path traversal is detected\n\t */\n\tprivate _safeBranchPath(branchId: string): string {\n\t\t// Validate format first (must be alphanumeric with hyphens/underscores, 1-64 chars)\n\t\tconst validBranchIdPattern = /^[a-zA-Z0-9_-]{1,64}$/;\n\t\tif (!validBranchIdPattern.test(branchId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid branch ID: must be 1-64 alphanumeric characters, hyphens, or underscores only`\n\t\t\t);\n\t\t}\n\n\t\tconst resolved = resolve(this._branchesDir, `${branchId}.json`);\n\t\tconst normalizedBranchesDir = resolve(this._branchesDir);\n\n\t\t// Ensure the resolved path is still within branches directory\n\t\tif (!resolved.startsWith(normalizedBranchesDir + sep)) {\n\t\t\tthrow new Error(`Invalid branch ID: path traversal detected`);\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\tpublic async saveThought(thought: ThoughtData): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tconst history = await this.loadHistory();\n\t\t\thistory.push(thought);\n\n\t\t\tif (history.length > this._maxHistorySize) {\n\t\t\t\thistory.splice(0, history.length - this._maxHistorySize);\n\t\t\t}\n\n\t\t\tawait writeFile(this._historyPath, JSON.stringify(history, null, 2), 'utf-8');\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_thought', startTime);\n\t\t}\n\t}\n\n\tpublic async loadHistory(): Promise<ThoughtData[]> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tif (!existsSync(this._historyPath)) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\tconst content = await readFile(this._historyPath, 'utf-8');\n\t\t\tconst data = JSON.parse(content) as ThoughtData[];\n\n\t\t\t// Validate and filter\n\t\t\treturn Array.isArray(data) ? data : [];\n\t\t} catch {\n\t\t\t// If file is corrupted, start fresh\n\t\t\treturn [];\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_history', startTime);\n\t\t}\n\t}\n\n\tpublic async saveBranch(branchId: string, thoughts: ThoughtData[]): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tif (!this._persistBranches) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tconst branchPath = this._safeBranchPath(branchId);\n\t\t\tawait writeFile(branchPath, JSON.stringify(thoughts, null, 2), 'utf-8');\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_branch', startTime);\n\t\t}\n\t}\n\n\tpublic async loadBranch(branchId: string): Promise<ThoughtData[] | undefined> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tif (!this._persistBranches) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst branchPath = this._safeBranchPath(branchId);\n\n\t\t\ttry {\n\t\t\t\tif (!existsSync(branchPath)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tconst content = await readFile(branchPath, 'utf-8');\n\t\t\t\tconst data = JSON.parse(content) as ThoughtData[];\n\n\t\t\t\treturn Array.isArray(data) ? data : undefined;\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_branch', startTime);\n\t\t}\n\t}\n\n\tpublic async listBranches(): Promise<string[]> {\n\t\treturn this.getBranchIds();\n\t}\n\n\tpublic async clear(): Promise<void> {\n\t\ttry {\n\t\t\t// Clear history\n\t\t\tif (existsSync(this._historyPath)) {\n\t\t\t\tawait unlink(this._historyPath);\n\t\t\t}\n\n\t\t\t// Clear all branches\n\t\t\tif (this._persistBranches && existsSync(this._branchesDir)) {\n\t\t\t\tconst files = await readdir(this._branchesDir);\n\t\t\t\tfor (const file of files) {\n\t\t\t\t\tif (file.endsWith('.json')) {\n\t\t\t\t\t\tawait unlink(join(this._branchesDir, file));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Clear all edges\n\t\t\tif (existsSync(this._edgesDir)) {\n\t\t\t\tconst edgeFiles = await readdir(this._edgesDir);\n\t\t\t\tfor (const file of edgeFiles) {\n\t\t\t\t\tif (file.endsWith('.json')) {\n\t\t\t\t\t\tawait unlink(join(this._edgesDir, file));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Clear all summaries\n\t\t\tif (existsSync(this._summariesDir)) {\n\t\t\t\tconst summaryFiles = await readdir(this._summariesDir);\n\t\t\t\tfor (const file of summaryFiles) {\n\t\t\t\t\tif (file.endsWith('.json')) {\n\t\t\t\t\t\tawait unlink(join(this._summariesDir, file));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors during clear\n\t\t}\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Get the data directory path.\n\t */\n\tpublic getDataDir(): string {\n\t\treturn this._dataDir;\n\t}\n\n\t/**\n\t * Get all branch IDs that are persisted.\n\t */\n\tpublic async getBranchIds(): Promise<string[]> {\n\t\tif (!this._persistBranches || !existsSync(this._branchesDir)) {\n\t\t\treturn [];\n\t\t}\n\n\t\ttry {\n\t\t\tconst files = await readdir(this._branchesDir);\n\t\t\treturn files.filter((f) => f.endsWith('.json')).map((f) => f.replace('.json', ''));\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Close the backend and release resources.\n\t * No resources to release for file backend.\n\t */\n\tpublic async close(): Promise<void> {\n\t\t// No-op for file backend (files are already flushed on write)\n\t}\n\n\t/**\n\t * Validates session ID format and resolves the edge file path safely.\n\t *\n\t * @param sessionId - The session ID to validate and resolve\n\t * @returns The safe, resolved edge file path\n\t * @throws Error if session ID is invalid or path traversal is detected\n\t */\n\tprivate _safeEdgePath(sessionId: string): string {\n\t\tconst validSessionIdPattern = /^[a-zA-Z0-9_-]{1,100}$/;\n\t\tif (!validSessionIdPattern.test(sessionId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid session ID for edges: must be 1-100 alphanumeric characters, hyphens, or underscores only`\n\t\t\t);\n\t\t}\n\n\t\tconst resolved = resolve(this._edgesDir, `${sessionId}.json`);\n\t\tconst normalizedEdgesDir = resolve(this._edgesDir);\n\n\t\tif (!resolved.startsWith(normalizedEdgesDir + sep)) {\n\t\t\tthrow new Error(`Invalid session ID: path traversal detected`);\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Save edges for a session to a JSON file.\n\t *\n\t * @param sessionId - The session ID\n\t * @param edges - Edges to persist (sorted by createdAt before write)\n\t */\n\tpublic async saveEdges(sessionId: string, edges: readonly Edge[]): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tif (!existsSync(this._edgesDir)) {\n\t\t\t\tawait mkdir(this._edgesDir, { recursive: true });\n\t\t\t}\n\n\t\t\tconst edgePath = this._safeEdgePath(sessionId);\n\n\t\t\tif (edges.length === 0) {\n\t\t\t\tif (existsSync(edgePath)) {\n\t\t\t\t\tawait unlink(edgePath);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sorted = [...edges].sort((a, b) => a.createdAt - b.createdAt);\n\t\t\tawait writeFile(edgePath, JSON.stringify(sorted, null, 2), 'utf-8');\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_edges', startTime);\n\t\t}\n\t}\n\n\t/**\n\t * Load edges for a session from a JSON file.\n\t *\n\t * @param sessionId - The session ID\n\t * @returns Edges array (empty if file is missing or corrupted)\n\t */\n\tpublic async loadEdges(sessionId: string): Promise<Edge[]> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tconst edgePath = this._safeEdgePath(sessionId);\n\n\t\t\tif (!existsSync(edgePath)) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(edgePath, 'utf-8');\n\t\t\t\tconst data = JSON.parse(content) as Edge[];\n\t\t\t\treturn Array.isArray(data) ? data : [];\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_edges', startTime);\n\t\t}\n\t}\n\n\t/**\n\t * List all session IDs that have persisted edge files.\n\t *\n\t * @returns Array of session identifiers (filenames without .json extension)\n\t */\n\tpublic async listEdgeSessions(): Promise<string[]> {\n\t\ttry {\n\t\t\tconst files = await readdir(this._edgesDir);\n\t\t\treturn files.filter((f) => f.endsWith('.json')).map((f) => f.slice(0, -5));\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Validates session ID format and resolves the summary file path safely.\n\t *\n\t * @param sessionId - The session ID to validate and resolve\n\t * @returns The safe, resolved summary file path\n\t * @throws Error if session ID is invalid or path traversal is detected\n\t */\n\tprivate _safeSummaryPath(sessionId: string): string {\n\t\tconst validSessionIdPattern = /^[a-zA-Z0-9_-]{1,100}$/;\n\t\tif (!validSessionIdPattern.test(sessionId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid session ID for summaries: must be 1-100 alphanumeric characters, hyphens, or underscores only`\n\t\t\t);\n\t\t}\n\n\t\tconst resolved = resolve(this._summariesDir, `${sessionId}.json`);\n\t\tconst normalizedSummariesDir = resolve(this._summariesDir);\n\n\t\tif (!resolved.startsWith(normalizedSummariesDir + sep)) {\n\t\t\tthrow new Error(`Invalid session ID: path traversal detected`);\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Save summaries for a session to a JSON file using an atomic\n\t * write (tmp file + rename) to prevent partial-write corruption.\n\t *\n\t * @param sessionId - The session ID\n\t * @param summaries - Summaries to persist (sorted by createdAt before write)\n\t */\n\tpublic async saveSummaries(sessionId: string, summaries: readonly Summary[]): Promise<void> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tawait this._ensureDirectories();\n\n\t\t\tif (!existsSync(this._summariesDir)) {\n\t\t\t\tawait mkdir(this._summariesDir, { recursive: true });\n\t\t\t}\n\n\t\t\tconst summaryPath = this._safeSummaryPath(sessionId);\n\n\t\t\tif (summaries.length === 0) {\n\t\t\t\tif (existsSync(summaryPath)) {\n\t\t\t\t\tawait unlink(summaryPath);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sorted = [...summaries].sort((a, b) => a.createdAt - b.createdAt);\n\t\t\tconst tmpPath = `${summaryPath}.tmp`;\n\t\t\tawait writeFile(tmpPath, JSON.stringify(sorted, null, 2), 'utf-8');\n\t\t\tawait rename(tmpPath, summaryPath);\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('save_summaries', startTime);\n\t\t}\n\t}\n\n\t/**\n\t * Load summaries for a session from a JSON file.\n\t *\n\t * @param sessionId - The session ID\n\t * @returns Summaries array (empty if file is missing or corrupted)\n\t */\n\tpublic async loadSummaries(sessionId: string): Promise<Summary[]> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\tconst summaryPath = this._safeSummaryPath(sessionId);\n\n\t\t\tif (!existsSync(summaryPath)) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(summaryPath, 'utf-8');\n\t\t\t\tconst data = JSON.parse(content) as Summary[];\n\t\t\t\tif (!Array.isArray(data)) return [];\n\t\t\t\treturn [...data].sort((a, b) => a.createdAt - b.createdAt);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._recordOperationDuration('load_summaries', startTime);\n\t\t}\n\t}\n}\n"],"names":["FilePersistence","options","defaultDataDir","existsSync","join","homedir","operation","startTime","durationSeconds","Date","mkdir","branchId","validBranchIdPattern","Error","resolved","resolve","normalizedBranchesDir","sep","thought","history","writeFile","JSON","content","readFile","data","Array","thoughts","branchPath","undefined","unlink","files","readdir","file","edgeFiles","summaryFiles","f","sessionId","validSessionIdPattern","normalizedEdgesDir","edges","edgePath","sorted","a","b","normalizedSummariesDir","summaries","summaryPath","tmpPath","rename"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { ThoughtData } from '../core/thought.js';
2
2
  import type { Edge } from '../core/graph/Edge.js';
3
3
  import type { Summary } from '../core/compression/Summary.js';
4
- import type { PersistenceBackend } from './PersistenceBackend.js';
4
+ import type { PersistenceBackend } from '../contracts/PersistenceBackend.js';
5
5
  /**
6
6
  * Configuration options for MemoryPersistence.
7
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/MemoryPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC3D,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,UAAU,CAAqC;gBAE3C,OAAO,GAAE,wBAA6B;IAIrC,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAIrC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IAKhE,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI9C;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAIxC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC;;;;;OAKG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhF;;;;;;OAMG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAM1D;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIlD;;;;;OAKG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3F;;;;;;OAMG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAMjE;;OAEG;IACI,cAAc,IAAI,MAAM;IAI/B;;OAEG;IACI,cAAc,IAAI,MAAM;IAI/B;;OAEG;IACI,YAAY,IAAI,MAAM,EAAE;CAG/B"}
1
+ {"version":3,"file":"MemoryPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/MemoryPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC3D,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,UAAU,CAAqC;gBAE3C,OAAO,GAAE,wBAA6B;IAIrC,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAIrC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IAKhE,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI9C;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAIxC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC;;;;;OAKG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhF;;;;;;OAMG;IACU,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAM1D;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIlD;;;;;OAKG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3F;;;;;;OAMG;IACU,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAMjE;;OAEG;IACI,cAAc,IAAI,MAAM;IAI/B;;OAEG;IACI,cAAc,IAAI,MAAM;IAI/B;;OAEG;IACI,YAAY,IAAI,MAAM,EAAE;CAG/B"}