claude-flow-novice 1.6.3 → 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/.claude/commands/parse-epic.js +180 -0
  2. package/.claude/settings.json +12 -2
  3. package/.claude/settings.local.json +4 -2
  4. package/.claude-flow-novice/dist/mcp/mcp-server-novice.js +37 -2
  5. package/.claude-flow-novice/dist/mcp/transports/base.js +5 -0
  6. package/.claude-flow-novice/dist/mcp/transports/base.js.map +1 -0
  7. package/.claude-flow-novice/dist/mcp/transports/http.js +414 -0
  8. package/.claude-flow-novice/dist/mcp/transports/http.js.map +1 -0
  9. package/.claude-flow-novice/dist/mcp/transports/stdio.js +217 -0
  10. package/.claude-flow-novice/dist/mcp/transports/stdio.js.map +1 -0
  11. package/.claude-flow-novice/dist/src/cli/commands/parse-epic.js +129 -0
  12. package/.claude-flow-novice/dist/src/cli/commands/parse-epic.js.map +1 -0
  13. package/.claude-flow-novice/dist/src/cli/index.js +3 -0
  14. package/.claude-flow-novice/dist/src/cli/index.js.map +1 -1
  15. package/.claude-flow-novice/dist/src/cli/utils/epic-parser.js +266 -0
  16. package/.claude-flow-novice/dist/src/cli/utils/epic-parser.js.map +1 -0
  17. package/.claude-flow-novice/dist/src/communication/message-bus.js +105 -2
  18. package/.claude-flow-novice/dist/src/communication/message-bus.js.map +1 -1
  19. package/.claude-flow-novice/dist/src/coordination/adapters/v1-coordinator-adapter.js +1 -1
  20. package/.claude-flow-novice/dist/src/coordination/adapters/v1-coordinator-adapter.js.map +1 -1
  21. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/cache/artifact-cache-optimizer.js +632 -0
  22. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/cache/artifact-cache-optimizer.js.map +1 -0
  23. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/cache/index.js +11 -0
  24. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/cache/index.js.map +1 -0
  25. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/checkpoints/checkpoint-compressor.js +318 -0
  26. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/checkpoints/checkpoint-compressor.js.map +1 -0
  27. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/completion-detector.js +234 -0
  28. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/completion-detector.js.map +1 -0
  29. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/hierarchical-detector.js +347 -0
  30. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/hierarchical-detector.js.map +1 -0
  31. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/index.js +13 -0
  32. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/index.js.map +1 -0
  33. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/lamport-clock.js +173 -0
  34. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/lamport-clock.js.map +1 -0
  35. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/mesh-detector.js +526 -0
  36. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/mesh-detector.js.map +1 -0
  37. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/sdk-completion-detector.js +443 -0
  38. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/sdk-completion-detector.js.map +1 -0
  39. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/swarm-shutdown.js +366 -0
  40. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/completion/swarm-shutdown.js.map +1 -0
  41. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinator-factory.js +287 -0
  42. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinator-factory.js.map +1 -0
  43. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/cascading-shutdown.example.js +364 -0
  44. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/cascading-shutdown.example.js.map +1 -0
  45. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/cascading-shutdown.js +492 -0
  46. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/cascading-shutdown.js.map +1 -0
  47. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/hierarchical-coordinator.js +786 -0
  48. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/hierarchical-coordinator.js.map +1 -0
  49. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/index.js +16 -0
  50. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/index.js.map +1 -0
  51. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/parent-child-manager.js +342 -0
  52. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/parent-child-manager.js.map +1 -0
  53. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/swarm-coordinator-v2.js +601 -0
  54. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/coordinators/swarm-coordinator-v2.js.map +1 -0
  55. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/agent-state.js +9 -0
  56. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/agent-state.js.map +1 -0
  57. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dead-letter-queue.js +413 -0
  58. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dead-letter-queue.js.map +1 -0
  59. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dependency-graph.js +471 -0
  60. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dependency-graph.js.map +1 -0
  61. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dependency-node.js +379 -0
  62. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dependency-node.js.map +1 -0
  63. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dependency-resolver.js +335 -0
  64. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/dependency-resolver.js.map +1 -0
  65. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/help-request-metrics.js +211 -0
  66. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/help-request-metrics.js.map +1 -0
  67. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/index.js +33 -0
  68. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/index.js.map +1 -0
  69. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/message-broker.js +920 -0
  70. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/message-broker.js.map +1 -0
  71. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/message-router.js +385 -0
  72. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/message-router.js.map +1 -0
  73. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/message.js +138 -0
  74. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/message.js.map +1 -0
  75. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/resource-manager-safe.js +478 -0
  76. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/resource-manager-safe.js.map +1 -0
  77. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/state-machine-config.js +358 -0
  78. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/state-machine-config.js.map +1 -0
  79. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/state-machine.js +588 -0
  80. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/state-machine.js.map +1 -0
  81. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/state-transition.js +153 -0
  82. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/state-transition.js.map +1 -0
  83. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/task-scheduler.js +360 -0
  84. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/task-scheduler.js.map +1 -0
  85. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/topic-manager.js +337 -0
  86. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/core/topic-manager.js.map +1 -0
  87. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/deadlock/deadlock-detector.js +424 -0
  88. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/deadlock/deadlock-detector.js.map +1 -0
  89. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/deadlock/index.js +9 -0
  90. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/deadlock/index.js.map +1 -0
  91. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/deadlock/resource-manager.js +669 -0
  92. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/deadlock/resource-manager.js.map +1 -0
  93. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/artifact-storage.js +451 -0
  94. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/artifact-storage.js.map +1 -0
  95. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/cycle-detector.js +271 -0
  96. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/cycle-detector.js.map +1 -0
  97. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/dependency-graph.js +335 -0
  98. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/dependency-graph.js.map +1 -0
  99. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/dependency-manager.js +439 -0
  100. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/dependency-manager.js.map +1 -0
  101. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/dependency-request.js +92 -0
  102. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/dependency-request.js.map +1 -0
  103. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/index.js +21 -0
  104. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/index.js.map +1 -0
  105. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/topological-sort.js +223 -0
  106. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/dependency/topological-sort.js.map +1 -0
  107. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-coordinator.js +436 -0
  108. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-coordinator.js.map +1 -0
  109. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-matcher.js +278 -0
  110. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-matcher.js.map +1 -0
  111. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-request-handler.js +317 -0
  112. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-request-handler.js.map +1 -0
  113. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-request.js +273 -0
  114. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/help-request.js.map +1 -0
  115. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/index.js +15 -0
  116. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/index.js.map +1 -0
  117. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/waiting-agent-pool.js +512 -0
  118. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/help-system/waiting-agent-pool.js.map +1 -0
  119. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/index.js +67 -0
  120. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/index.js.map +1 -0
  121. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/help-deadlock-integration.js +557 -0
  122. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/help-deadlock-integration.js.map +1 -0
  123. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/index.js +14 -0
  124. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/index.js.map +1 -0
  125. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/message-bus-completion-integration.example.js +212 -0
  126. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/message-bus-completion-integration.example.js.map +1 -0
  127. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/message-bus-completion-integration.js +552 -0
  128. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/message-bus-completion-integration.js.map +1 -0
  129. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/state-machine-integration.js +635 -0
  130. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/integration/state-machine-integration.js.map +1 -0
  131. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/IArtifactStorage.js +28 -0
  132. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/IArtifactStorage.js.map +1 -0
  133. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/ICoordinator.js +9 -0
  134. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/ICoordinator.js.map +1 -0
  135. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/ISessionStore.js +25 -0
  136. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/ISessionStore.js.map +1 -0
  137. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/index.js +14 -0
  138. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/interfaces/index.js.map +1 -0
  139. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/artifact-adapter.js +308 -0
  140. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/artifact-adapter.js.map +1 -0
  141. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/completion-storage.js +439 -0
  142. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/completion-storage.js.map +1 -0
  143. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/dependency-graph-storage.js +540 -0
  144. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/dependency-graph-storage.js.map +1 -0
  145. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/dependency-storage.js +367 -0
  146. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/dependency-storage.js.map +1 -0
  147. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/index.js +14 -0
  148. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/index.js.map +1 -0
  149. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/message-storage.js +518 -0
  150. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/message-storage.js.map +1 -0
  151. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/state-storage.js +377 -0
  152. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/memory/state-storage.js.map +1 -0
  153. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channel.js +371 -0
  154. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channel.js.map +1 -0
  155. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/dependency-channel.js +355 -0
  156. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/dependency-channel.js.map +1 -0
  157. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/help-channel.js +424 -0
  158. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/help-channel.js.map +1 -0
  159. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/index.js +16 -0
  160. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/index.js.map +1 -0
  161. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/state-channel.js +295 -0
  162. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/state-channel.js.map +1 -0
  163. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/task-channel.js +411 -0
  164. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/channels/task-channel.js.map +1 -0
  165. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/index.js +14 -0
  166. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/index.js.map +1 -0
  167. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/message-bus.js +387 -0
  168. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/message-bus.js.map +1 -0
  169. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/message-persistence.js +589 -0
  170. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/message-persistence.js.map +1 -0
  171. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/message-router.js +444 -0
  172. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/messaging/message-router.js.map +1 -0
  173. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/artifact-storage.js +560 -0
  174. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/artifact-storage.js.map +1 -0
  175. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/background-orchestrator.js +335 -0
  176. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/background-orchestrator.js.map +1 -0
  177. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/bash-output-monitor.js +104 -0
  178. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/bash-output-monitor.js.map +1 -0
  179. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/checkpoint-manager.js +847 -0
  180. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/checkpoint-manager.js.map +1 -0
  181. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/help-coordinator.js +470 -0
  182. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/help-coordinator.js.map +1 -0
  183. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/hierarchical-background-integration.js +450 -0
  184. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/hierarchical-background-integration.js.map +1 -0
  185. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/index.js +13 -0
  186. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/index.js.map +1 -0
  187. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/message-bus-integration.js +625 -0
  188. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/message-bus-integration.js.map +1 -0
  189. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/multi-level-control.js +545 -0
  190. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/multi-level-control.js.map +1 -0
  191. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/query-controller.js +740 -0
  192. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/query-controller.js.map +1 -0
  193. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/query-message-integration.js +415 -0
  194. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/query-message-integration.js.map +1 -0
  195. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/session-pool-optimizer.js +615 -0
  196. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/session-pool-optimizer.js.map +1 -0
  197. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/state-machine-integration.js +547 -0
  198. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/state-machine-integration.js.map +1 -0
  199. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/state-sdk-integration.js +342 -0
  200. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/sdk/state-sdk-integration.js.map +1 -0
  201. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/security/payload-validator.js +259 -0
  202. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/security/payload-validator.js.map +1 -0
  203. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/framework-registry.js +273 -0
  204. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/framework-registry.js.map +1 -0
  205. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/index.js +8 -0
  206. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/index.js.map +1 -0
  207. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/truth-config-manager.js +310 -0
  208. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/truth-config-manager.js.map +1 -0
  209. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/truth-validator.js +218 -0
  210. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/truth/truth-validator.js.map +1 -0
  211. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/types/sdk.js +9 -0
  212. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/types/sdk.js.map +1 -0
  213. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/utils/index.js +6 -0
  214. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/utils/index.js.map +1 -0
  215. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/utils/priority-queue.js +145 -0
  216. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/utils/priority-queue.js.map +1 -0
  217. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/utils/sdk-helpers.js +122 -0
  218. package/.claude-flow-novice/dist/src/coordination/archives/v2-sdk-typescript/v2/utils/sdk-helpers.js.map +1 -0
  219. package/.claude-flow-novice/dist/src/coordination/config-translator.js +17 -43
  220. package/.claude-flow-novice/dist/src/coordination/config-translator.js.map +1 -1
  221. package/.claude-flow-novice/dist/src/coordination/coordination-toggle.js +34 -76
  222. package/.claude-flow-novice/dist/src/coordination/coordination-toggle.js.map +1 -1
  223. package/.claude-flow-novice/dist/src/coordination/index.js +3 -0
  224. package/.claude-flow-novice/dist/src/coordination/index.js.map +1 -1
  225. package/.claude-flow-novice/dist/src/coordination/shared/core/agent-state.js +172 -0
  226. package/.claude-flow-novice/dist/src/coordination/shared/core/agent-state.js.map +1 -0
  227. package/.claude-flow-novice/dist/src/coordination/shared/core/index.js +7 -0
  228. package/.claude-flow-novice/dist/src/coordination/shared/core/index.js.map +1 -0
  229. package/.claude-flow-novice/dist/src/coordination/shared/index.js +19 -0
  230. package/.claude-flow-novice/dist/src/coordination/shared/index.js.map +1 -0
  231. package/.claude-flow-novice/dist/src/coordination/shared/interfaces/ICoordinator.js +24 -0
  232. package/.claude-flow-novice/dist/src/coordination/shared/interfaces/ICoordinator.js.map +1 -0
  233. package/.claude-flow-novice/dist/src/coordination/shared/interfaces/index.js +7 -0
  234. package/.claude-flow-novice/dist/src/coordination/shared/interfaces/index.js.map +1 -0
  235. package/.claude-flow-novice/dist/src/coordination/shared/message-broker.js +920 -0
  236. package/.claude-flow-novice/dist/src/coordination/shared/message-broker.js.map +1 -0
  237. package/.claude-flow-novice/dist/src/coordination/shared/message.js +138 -0
  238. package/.claude-flow-novice/dist/src/coordination/shared/message.js.map +1 -0
  239. package/.claude-flow-novice/dist/src/coordination/shared/security/payload-validator.js +259 -0
  240. package/.claude-flow-novice/dist/src/coordination/shared/security/payload-validator.js.map +1 -0
  241. package/.claude-flow-novice/dist/src/coordination/shared/transparency/index.js +17 -0
  242. package/.claude-flow-novice/dist/src/coordination/shared/transparency/index.js.map +1 -0
  243. package/.claude-flow-novice/dist/src/coordination/shared/transparency/interfaces/transparency-system.js +19 -0
  244. package/.claude-flow-novice/dist/src/coordination/shared/transparency/interfaces/transparency-system.js.map +1 -0
  245. package/.claude-flow-novice/dist/src/coordination/shared/transparency/transparency-integration.js +357 -0
  246. package/.claude-flow-novice/dist/src/coordination/shared/transparency/transparency-integration.js.map +1 -0
  247. package/.claude-flow-novice/dist/src/coordination/shared/transparency/transparency-system.js +679 -0
  248. package/.claude-flow-novice/dist/src/coordination/shared/transparency/transparency-system.js.map +1 -0
  249. package/.claude-flow-novice/dist/src/coordination/shared/types/index.js +7 -0
  250. package/.claude-flow-novice/dist/src/coordination/shared/types/index.js.map +1 -0
  251. package/.claude-flow-novice/dist/src/coordination/shared/types/sdk.js +10 -0
  252. package/.claude-flow-novice/dist/src/coordination/shared/types/sdk.js.map +1 -0
  253. package/.claude-flow-novice/dist/src/coordination/v1-transparency/interfaces/v1-transparency-system.js +12 -0
  254. package/.claude-flow-novice/dist/src/coordination/v1-transparency/interfaces/v1-transparency-system.js.map +1 -0
  255. package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-to-v2-bridge.js +433 -0
  256. package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-to-v2-bridge.js.map +1 -0
  257. package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-transparency-adapter.js +1468 -0
  258. package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-transparency-adapter.js.map +1 -0
  259. package/.claude-flow-novice/dist/src/feature-flags/core/FeatureFlagManager.js +52 -2
  260. package/.claude-flow-novice/dist/src/feature-flags/core/FeatureFlagManager.js.map +1 -1
  261. package/.claude-flow-novice/dist/src/mcp/mcp-server-novice.js +37 -2
  262. package/.claude-flow-novice/dist/src/mcp/session-manager.js +3 -1
  263. package/.claude-flow-novice/dist/src/mcp/session-manager.js.map +1 -1
  264. package/.claude-flow-novice/dist/src/monitoring/apm/apm-integration.js +5 -0
  265. package/.claude-flow-novice/dist/src/monitoring/apm/apm-integration.js.map +1 -1
  266. package/.claude-flow-novice/dist/src/providers/provider-manager.js +41 -6
  267. package/.claude-flow-novice/dist/src/providers/provider-manager.js.map +1 -1
  268. package/.claude-flow-novice/dist/src/providers/tiered-router.js +9 -17
  269. package/.claude-flow-novice/dist/src/providers/tiered-router.js.map +1 -1
  270. package/.claude-flow-novice/dist/src/utils/markdown-sanitizer.js +65 -41
  271. package/.claude-flow-novice/dist/src/utils/markdown-sanitizer.js.map +1 -1
  272. package/.claude-flow-novice/dist/src/web/api/server.js +1 -1
  273. package/.claude-flow-novice/dist/src/web/api/server.js.map +1 -1
  274. package/.claude-flow-novice/dist/src/workflows/progressive-rollout-manager.js +30 -0
  275. package/.claude-flow-novice/dist/src/workflows/progressive-rollout-manager.js.map +1 -1
  276. package/.claude-flow-novice/metrics.db +0 -0
  277. package/.claude-flow-novice/metrics.db-shm +0 -0
  278. package/.claude-flow-novice/metrics.db-wal +0 -0
  279. package/CLAUDE.md +72 -0
  280. package/config/hooks/post-edit-pipeline.js +68 -118
  281. package/config/hooks/pre-tool-memory-safety.js +209 -0
  282. package/package.json +7 -4
  283. package/scripts/cleanup-idle-sessions.sh +59 -0
  284. package/scripts/monitoring/alert-monitor.sh +220 -0
  285. package/scripts/monitoring/view-alerts.sh +307 -0
  286. package/scripts/test-provider-routing.cjs +7 -9
  287. package/scripts/test-zai-api.cjs +2 -2
  288. package/src/slash-commands/parse-epic.js +1 -1
  289. package/wiki/Provider-Routing.md +57 -69
  290. package/MEMORY_LEAK_ROOT_CAUSE.md +0 -149
@@ -0,0 +1,847 @@
1
+ /**
2
+ * Agent Coordination V2 - SDK Checkpoint Manager
3
+ * Git-like state snapshots with message UUID tracking for instant recovery
4
+ *
5
+ * Features:
6
+ * - <500ms checkpoint recovery (p99)
7
+ * - Auto-checkpoint on state transitions
8
+ * - 60% compression via MessagePack
9
+ * - Message UUID tracking for instant rollback
10
+ * - Zero data loss during recovery
11
+ */ import { createHash, timingSafeEqual } from 'crypto';
12
+ import { promises as fs } from 'fs';
13
+ import * as path from 'path';
14
+ import * as msgpack from 'msgpack-lite';
15
+ import { AgentState } from '../../shared/types/sdk.js';
16
+ import { CheckpointCompressor } from '../checkpoints/checkpoint-compressor.js';
17
+ export class CheckpointManager {
18
+ MAX_IN_MEMORY_CHECKPOINTS = 100;
19
+ checkpoints = new Map();
20
+ sessions = new Map();
21
+ agentSessions = new Map();
22
+ sessionCheckpoints = new Map();
23
+ messageUUIDIndex = new Map();
24
+ storagePath;
25
+ metrics;
26
+ restoreLatencies = [];
27
+ autoCheckpointEnabled = true;
28
+ initialized = false;
29
+ storeMetrics;
30
+ initTime = Date.now();
31
+ cleanupInterval;
32
+ retentionHours = 24;
33
+ restoredCheckpoints = new Set();
34
+ maxCheckpointAge = 3600000;
35
+ compressor;
36
+ constructor(storagePath = '.claude-flow/checkpoints/v2', retentionHours = 24){
37
+ this.storagePath = storagePath;
38
+ this.retentionHours = retentionHours;
39
+ this.compressor = new CheckpointCompressor();
40
+ this.metrics = {
41
+ totalCheckpoints: 0,
42
+ totalRestores: 0,
43
+ averageCreateTimeMs: 0,
44
+ averageRestoreTimeMs: 0,
45
+ p95RestoreTimeMs: 0,
46
+ p99RestoreTimeMs: 0,
47
+ compressionRatio: 0,
48
+ totalStorageMb: 0
49
+ };
50
+ this.storeMetrics = {
51
+ totalSessions: 0,
52
+ totalCheckpoints: 0,
53
+ totalStorageMb: 0,
54
+ averageCompressionRatio: 0,
55
+ averageReadLatencyMs: 0,
56
+ averageWriteLatencyMs: 0,
57
+ totalReads: 0,
58
+ totalWrites: 0,
59
+ totalDeletions: 0,
60
+ uptimeMs: 0,
61
+ totalRestores: 0,
62
+ averageCreateTimeMs: 0,
63
+ averageRestoreTimeMs: 0,
64
+ compressionRatio: 0,
65
+ p95RestoreTimeMs: 0,
66
+ p99RestoreTimeMs: 0
67
+ };
68
+ this.ensureStorageDirectory();
69
+ // Start automatic cleanup (every 1 hour)
70
+ this.cleanupInterval = setInterval(()=>{
71
+ this.cleanExpiredCheckpoints().catch((error)=>{
72
+ console.error('Automatic checkpoint cleanup failed:', error);
73
+ });
74
+ }, 60 * 60 * 1000); // 1 hour
75
+ }
76
+ /**
77
+ * Create a checkpoint snapshot with Git-like message UUID tracking
78
+ */ async createCheckpoint(sessionId, agentId, messageUUID, state, stateSnapshot, metadata) {
79
+ const startTime = performance.now();
80
+ const checkpointId = this.generateCheckpointId(sessionId, messageUUID);
81
+ const timestamp = Date.now();
82
+ // Get previous checkpoint for delta compression
83
+ const previousCheckpointData = this.getLatestCheckpointData(sessionId);
84
+ const previousCheckpointId = previousCheckpointData?.id;
85
+ // Use multi-layer compression: MessagePack + Delta + Gzip
86
+ const compressionResult = await this.compressor.compress(stateSnapshot, sessionId, previousCheckpointId);
87
+ const compressedBuffer = compressionResult.compressedBuffer;
88
+ const compressedSize = compressionResult.compressedSize;
89
+ const uncompressedSize = compressionResult.uncompressedSize;
90
+ const compressionRatio = compressionResult.compressionRatio;
91
+ // Calculate checksum for integrity verification
92
+ const checksum = this.calculateChecksum(stateSnapshot);
93
+ const checkpoint = {
94
+ id: checkpointId,
95
+ sessionId,
96
+ agentId,
97
+ messageUUID,
98
+ state,
99
+ timestamp,
100
+ stateSnapshot,
101
+ metadata: {
102
+ reason: metadata?.reason || 'manual',
103
+ autoCheckpoint: metadata?.autoCheckpoint || false,
104
+ pendingDependencies: metadata?.pendingDependencies,
105
+ context: metadata?.context
106
+ },
107
+ checksum,
108
+ compressedSize,
109
+ uncompressedSize
110
+ };
111
+ // SEC-025 FIX: Enforce hard LRU limit BEFORE insertion to prevent memory exhaustion
112
+ // Synchronous eviction check happens BEFORE adding new checkpoint to prevent bypass
113
+ if (this.checkpoints.size >= this.MAX_IN_MEMORY_CHECKPOINTS) {
114
+ const oldest = Array.from(this.checkpoints.entries()).sort(([, a], [, b])=>a.timestamp - b.timestamp)[0];
115
+ if (oldest) {
116
+ const [oldestId, evictedCheckpoint] = oldest;
117
+ // Remove from memory IMMEDIATELY (synchronous enforcement)
118
+ this.checkpoints.delete(oldestId);
119
+ this.messageUUIDIndex.delete(evictedCheckpoint.messageUUID);
120
+ // Remove from session index
121
+ const sessionCheckpoints = this.sessionCheckpoints.get(evictedCheckpoint.sessionId);
122
+ if (sessionCheckpoints) {
123
+ const index = sessionCheckpoints.indexOf(oldestId);
124
+ if (index > -1) {
125
+ sessionCheckpoints.splice(index, 1);
126
+ }
127
+ }
128
+ // Emit eviction event for monitoring
129
+ console.log(`🔄 LRU eviction: ${oldestId} (age: ${Date.now() - evictedCheckpoint.timestamp}ms, reason: MEMORY_LIMIT_ENFORCEMENT)`);
130
+ // Async disk cleanup (non-blocking, best-effort)
131
+ this.deleteCheckpointFile(oldestId).catch((error)=>{
132
+ console.warn(`Warning: Failed to delete evicted checkpoint file ${oldestId}: ${error}`);
133
+ });
134
+ }
135
+ }
136
+ // NOW safe to add new checkpoint (hard limit enforced above)
137
+ this.checkpoints.set(checkpointId, checkpoint);
138
+ // Update session index
139
+ if (!this.sessionCheckpoints.has(sessionId)) {
140
+ this.sessionCheckpoints.set(sessionId, []);
141
+ }
142
+ this.sessionCheckpoints.get(sessionId).push(checkpointId);
143
+ // Update message UUID index for instant lookup
144
+ this.messageUUIDIndex.set(messageUUID, checkpointId);
145
+ // Persist to disk with compression
146
+ await this.persistCheckpoint(checkpoint, compressedBuffer);
147
+ // Update metrics
148
+ const createTime = performance.now() - startTime;
149
+ this.metrics.totalCheckpoints++;
150
+ this.metrics.averageCreateTimeMs = (this.metrics.averageCreateTimeMs * (this.metrics.totalCheckpoints - 1) + createTime) / this.metrics.totalCheckpoints;
151
+ this.metrics.compressionRatio = (this.metrics.compressionRatio * (this.metrics.totalCheckpoints - 1) + compressionRatio) / this.metrics.totalCheckpoints;
152
+ console.log(`✅ Checkpoint created: ${checkpointId} (${createTime.toFixed(2)}ms, ${compressionRatio.toFixed(2)}x compression)`);
153
+ return checkpointId;
154
+ }
155
+ /**
156
+ * Restore from checkpoint with <500ms guarantee (p99)
157
+ * SEC-020: Now includes anti-replay protection
158
+ */ async restoreCheckpoint(checkpointId) {
159
+ const startTime = performance.now();
160
+ // SEC-020: Anti-replay check #1 - Prevent duplicate restoration
161
+ if (this.restoredCheckpoints.has(checkpointId)) {
162
+ throw new Error(`Checkpoint ${checkpointId} already restored (replay attack detected)`);
163
+ }
164
+ const checkpoint = this.checkpoints.get(checkpointId);
165
+ if (!checkpoint) {
166
+ throw new Error(`Checkpoint ${checkpointId} not found`);
167
+ }
168
+ // SEC-020: Anti-replay check #2 - Reject stale checkpoints
169
+ const age = Date.now() - checkpoint.timestamp;
170
+ if (age > this.maxCheckpointAge) {
171
+ throw new Error(`Checkpoint ${checkpointId} expired (age: ${age}ms, max: ${this.maxCheckpointAge}ms)`);
172
+ }
173
+ // Verify checksum integrity
174
+ const currentChecksum = this.calculateChecksum(checkpoint.stateSnapshot);
175
+ if (currentChecksum !== checkpoint.checksum) {
176
+ throw new Error(`Checkpoint ${checkpointId} integrity check failed (checksum mismatch)`);
177
+ }
178
+ // SEC-020: Track restoration BEFORE applying state
179
+ this.restoredCheckpoints.add(checkpointId);
180
+ // SEC-020: Emit audit event for monitoring
181
+ console.log(`🔐 SEC-020: Checkpoint restoration audit - ID: ${checkpointId}, Age: ${age}ms, Timestamp: ${Date.now()}`);
182
+ // Restore state (already decompressed in memory)
183
+ const restoredState = checkpoint.stateSnapshot;
184
+ const latencyMs = performance.now() - startTime;
185
+ // Update metrics
186
+ this.restoreLatencies.push(latencyMs);
187
+ this.metrics.totalRestores++;
188
+ this.metrics.averageRestoreTimeMs = (this.metrics.averageRestoreTimeMs * (this.metrics.totalRestores - 1) + latencyMs) / this.metrics.totalRestores;
189
+ this.updatePercentileMetrics();
190
+ // Verify p99 latency requirement
191
+ if (latencyMs > 500 && this.metrics.totalRestores >= 100) {
192
+ console.warn(`⚠️ Checkpoint restore exceeded 500ms: ${latencyMs.toFixed(2)}ms (p99: ${this.metrics.p99RestoreTimeMs.toFixed(2)}ms)`);
193
+ }
194
+ console.log(`✅ Checkpoint restored: ${checkpointId} (${latencyMs.toFixed(2)}ms)`);
195
+ return {
196
+ success: true,
197
+ checkpointId,
198
+ restoredState,
199
+ latencyMs,
200
+ messageUUID: checkpoint.messageUUID
201
+ };
202
+ }
203
+ /**
204
+ * Restore from message UUID (instant lookup)
205
+ */ async restoreFromMessageUUID(messageUUID) {
206
+ const checkpointId = this.messageUUIDIndex.get(messageUUID);
207
+ if (!checkpointId) {
208
+ throw new Error(`No checkpoint found for message UUID: ${messageUUID}`);
209
+ }
210
+ return this.restoreCheckpoint(checkpointId);
211
+ }
212
+ /**
213
+ * Auto-checkpoint on state transition
214
+ */ async autoCheckpointOnTransition(sessionId, agentId, messageUUID, fromState, toState, stateSnapshot) {
215
+ if (!this.autoCheckpointEnabled) {
216
+ return null;
217
+ }
218
+ // Auto-checkpoint on critical state transitions
219
+ const criticalTransitions = [
220
+ `${AgentState.WORKING}->${AgentState.WAITING}`,
221
+ `${AgentState.WORKING}->${AgentState.BLOCKED}`,
222
+ `${AgentState.WORKING}->${AgentState.COMPLETED}`,
223
+ `${AgentState.WAITING}->${AgentState.WORKING}`,
224
+ `${AgentState.BLOCKED}->${AgentState.WORKING}`
225
+ ];
226
+ const transition = `${fromState}->${toState}`;
227
+ if (!criticalTransitions.includes(transition)) {
228
+ return null;
229
+ }
230
+ const checkpointId = await this.createCheckpoint(sessionId, agentId, messageUUID, toState, stateSnapshot, {
231
+ reason: `State transition: ${transition}`,
232
+ autoCheckpoint: true
233
+ });
234
+ console.log(`🔄 Auto-checkpoint on transition: ${transition} -> ${checkpointId}`);
235
+ return checkpointId;
236
+ }
237
+ /**
238
+ * Get latest checkpoint for a session (internal use - returns CheckpointData)
239
+ */ getLatestCheckpointData(sessionId) {
240
+ const checkpointIds = this.sessionCheckpoints.get(sessionId) || [];
241
+ const checkpoints = checkpointIds.map((id)=>this.checkpoints.get(id)).filter(Boolean).sort((a, b)=>b.timestamp - a.timestamp);
242
+ return checkpoints.length > 0 ? checkpoints[0] : null;
243
+ }
244
+ /**
245
+ * Delete checkpoint
246
+ */ async deleteCheckpoint(checkpointId) {
247
+ const checkpoint = this.checkpoints.get(checkpointId);
248
+ if (!checkpoint) {
249
+ throw new Error(`Checkpoint ${checkpointId} not found`);
250
+ }
251
+ // Remove from memory
252
+ this.checkpoints.delete(checkpointId);
253
+ this.messageUUIDIndex.delete(checkpoint.messageUUID);
254
+ // Remove from session index
255
+ const sessionCheckpoints = this.sessionCheckpoints.get(checkpoint.sessionId);
256
+ if (sessionCheckpoints) {
257
+ const index = sessionCheckpoints.indexOf(checkpointId);
258
+ if (index > -1) {
259
+ sessionCheckpoints.splice(index, 1);
260
+ }
261
+ }
262
+ // Remove from disk
263
+ await this.deleteCheckpointFile(checkpointId);
264
+ console.log(`🗑️ Checkpoint deleted: ${checkpointId}`);
265
+ }
266
+ /**
267
+ * Delete checkpoint file from disk (helper for async cleanup)
268
+ */ async deleteCheckpointFile(checkpointId) {
269
+ const filePath = this.getCheckpointFilePath(checkpointId);
270
+ try {
271
+ await fs.unlink(filePath);
272
+ } catch (error) {
273
+ console.warn(`Warning: Failed to delete checkpoint file: ${error}`);
274
+ }
275
+ }
276
+ /**
277
+ * Cleanup old checkpoints (ISessionStore interface)
278
+ */ async cleanup(retentionHours = 24, maxCheckpointsPerSession = 10) {
279
+ const cutoffTime = Date.now() - retentionHours * 60 * 60 * 1000;
280
+ let deletedCount = 0;
281
+ for (const [sessionId, checkpointIds] of Array.from(this.sessionCheckpoints.entries())){
282
+ const checkpoints = checkpointIds.map((id)=>this.checkpoints.get(id)).filter(Boolean).sort((a, b)=>b.timestamp - a.timestamp);
283
+ // Delete checkpoints older than retention period
284
+ for (const checkpoint of checkpoints){
285
+ if (checkpoint.timestamp < cutoffTime) {
286
+ await this.deleteCheckpoint(checkpoint.id);
287
+ deletedCount++;
288
+ }
289
+ }
290
+ // Keep only max checkpoints per session
291
+ if (checkpoints.length > maxCheckpointsPerSession) {
292
+ const toDelete = checkpoints.slice(maxCheckpointsPerSession);
293
+ for (const checkpoint of toDelete){
294
+ await this.deleteCheckpoint(checkpoint.id);
295
+ deletedCount++;
296
+ }
297
+ }
298
+ }
299
+ console.log(`🧹 Cleaned up ${deletedCount} old checkpoints (retention: ${retentionHours}h, max/session: ${maxCheckpointsPerSession})`);
300
+ return deletedCount;
301
+ }
302
+ /**
303
+ * Automatic cleanup of expired checkpoints (internal)
304
+ */ async cleanExpiredCheckpoints() {
305
+ const now = Date.now();
306
+ const retentionMs = this.retentionHours * 60 * 60 * 1000;
307
+ let deletedCount = 0;
308
+ const entries = Array.from(this.checkpoints.entries());
309
+ for (const [checkpointId, checkpoint] of entries){
310
+ const age = now - checkpoint.timestamp;
311
+ if (age > retentionMs) {
312
+ await this.deleteCheckpoint(checkpointId);
313
+ deletedCount++;
314
+ }
315
+ }
316
+ if (deletedCount > 0) {
317
+ console.log(`🔄 Periodic cleanup: removed ${deletedCount} expired checkpoints (retention: ${this.retentionHours}h)`);
318
+ }
319
+ }
320
+ /**
321
+ * Get checkpoint metrics (internal - CheckpointMetrics format)
322
+ */ getCheckpointMetrics() {
323
+ return {
324
+ ...this.metrics
325
+ };
326
+ }
327
+ /**
328
+ * Get compression details for a specific checkpoint (for testing)
329
+ */ getCheckpointCompressionDetails(checkpointId) {
330
+ const checkpoint = this.checkpoints.get(checkpointId);
331
+ if (!checkpoint) {
332
+ return null;
333
+ }
334
+ return {
335
+ compressedSize: checkpoint.compressedSize,
336
+ uncompressedSize: checkpoint.uncompressedSize,
337
+ compressionRatio: 1 - checkpoint.compressedSize / checkpoint.uncompressedSize
338
+ };
339
+ }
340
+ /**
341
+ * Enable/disable auto-checkpointing
342
+ */ setAutoCheckpointEnabled(enabled) {
343
+ this.autoCheckpointEnabled = enabled;
344
+ console.log(`Auto-checkpointing ${enabled ? 'enabled' : 'disabled'}`);
345
+ }
346
+ /**
347
+ * Load checkpoints from disk on initialization
348
+ */ async loadFromDisk() {
349
+ try {
350
+ const files = await fs.readdir(this.storagePath);
351
+ const checkpointFiles = files.filter((f)=>f.endsWith('.msgpack'));
352
+ let loadedCount = 0;
353
+ for (const file of checkpointFiles){
354
+ try {
355
+ const filePath = path.join(this.storagePath, file);
356
+ const buffer = await fs.readFile(filePath);
357
+ const checkpoint = msgpack.decode(buffer);
358
+ // Restore indexes
359
+ this.checkpoints.set(checkpoint.id, checkpoint);
360
+ this.messageUUIDIndex.set(checkpoint.messageUUID, checkpoint.id);
361
+ if (!this.sessionCheckpoints.has(checkpoint.sessionId)) {
362
+ this.sessionCheckpoints.set(checkpoint.sessionId, []);
363
+ }
364
+ this.sessionCheckpoints.get(checkpoint.sessionId).push(checkpoint.id);
365
+ loadedCount++;
366
+ } catch (error) {
367
+ console.warn(`Warning: Failed to load checkpoint from ${file}: ${error}`);
368
+ }
369
+ }
370
+ console.log(`📁 Loaded ${loadedCount} checkpoints from disk`);
371
+ } catch (error) {
372
+ console.warn('Warning: Failed to load checkpoints from disk:', error);
373
+ }
374
+ }
375
+ /**
376
+ * Private: Persist checkpoint to disk with compression
377
+ */ async persistCheckpoint(checkpoint, compressedBuffer) {
378
+ const filePath = this.getCheckpointFilePath(checkpoint.id);
379
+ // Encode entire checkpoint with MessagePack
380
+ const checkpointBuffer = msgpack.encode(checkpoint);
381
+ await fs.writeFile(filePath, checkpointBuffer);
382
+ // Update storage metrics
383
+ const stats = await fs.stat(filePath);
384
+ this.metrics.totalStorageMb += stats.size / (1024 * 1024);
385
+ }
386
+ /**
387
+ * Private: Generate checkpoint ID
388
+ */ generateCheckpointId(sessionId, messageUUID) {
389
+ const hash = createHash('sha256').update(`${sessionId}:${messageUUID}:${Date.now()}`).digest('hex').substring(0, 12);
390
+ return `cp_${hash}`;
391
+ }
392
+ /**
393
+ * Private: Calculate checksum for integrity verification
394
+ */ calculateChecksum(data) {
395
+ const dataString = JSON.stringify(data, Object.keys(data).sort());
396
+ return createHash('sha256').update(dataString).digest('hex');
397
+ }
398
+ /**
399
+ * Private: Get checkpoint file path
400
+ */ getCheckpointFilePath(checkpointId) {
401
+ return path.join(this.storagePath, `${checkpointId}.msgpack`);
402
+ }
403
+ /**
404
+ * Private: Update percentile metrics
405
+ */ updatePercentileMetrics() {
406
+ if (this.restoreLatencies.length === 0) return;
407
+ const sorted = [
408
+ ...this.restoreLatencies
409
+ ].sort((a, b)=>a - b);
410
+ const p95Index = Math.floor(sorted.length * 0.95);
411
+ const p99Index = Math.floor(sorted.length * 0.99);
412
+ this.metrics.p95RestoreTimeMs = sorted[p95Index] || 0;
413
+ this.metrics.p99RestoreTimeMs = sorted[p99Index] || 0;
414
+ // Keep only last 1000 samples for percentile calculation
415
+ if (this.restoreLatencies.length > 1000) {
416
+ this.restoreLatencies = this.restoreLatencies.slice(-1000);
417
+ }
418
+ }
419
+ /**
420
+ * Private: Ensure storage directory exists
421
+ */ async ensureStorageDirectory() {
422
+ try {
423
+ await fs.access(this.storagePath);
424
+ } catch {
425
+ await fs.mkdir(this.storagePath, {
426
+ recursive: true
427
+ });
428
+ }
429
+ }
430
+ // ===========================
431
+ // ISessionStore Implementation
432
+ // ===========================
433
+ /**
434
+ * Store agent session
435
+ */ async storeSession(session) {
436
+ const startTime = performance.now();
437
+ this.sessions.set(session.sessionId, session);
438
+ this.agentSessions.set(session.agentId, session.sessionId);
439
+ // Persist to disk
440
+ const sessionPath = path.join(this.storagePath, 'sessions', `${session.sessionId}.msgpack`);
441
+ await fs.mkdir(path.dirname(sessionPath), {
442
+ recursive: true
443
+ });
444
+ const buffer = msgpack.encode(session);
445
+ await fs.writeFile(sessionPath, buffer);
446
+ // Update metrics
447
+ const writeTime = performance.now() - startTime;
448
+ this.storeMetrics.totalSessions = this.sessions.size;
449
+ this.storeMetrics.totalWrites++;
450
+ this.storeMetrics.averageWriteLatencyMs = (this.storeMetrics.averageWriteLatencyMs * (this.storeMetrics.totalWrites - 1) + writeTime) / this.storeMetrics.totalWrites;
451
+ }
452
+ /**
453
+ * Retrieve agent session
454
+ */ async getSession(sessionId) {
455
+ const startTime = performance.now();
456
+ let session = this.sessions.get(sessionId);
457
+ if (!session) {
458
+ // Try loading from disk
459
+ try {
460
+ const sessionPath = path.join(this.storagePath, 'sessions', `${sessionId}.msgpack`);
461
+ const buffer = await fs.readFile(sessionPath);
462
+ session = msgpack.decode(buffer);
463
+ if (session) {
464
+ this.sessions.set(sessionId, session);
465
+ this.agentSessions.set(session.agentId, sessionId);
466
+ }
467
+ } catch {
468
+ // Session not found
469
+ }
470
+ }
471
+ // Update metrics
472
+ const readTime = performance.now() - startTime;
473
+ this.storeMetrics.totalReads++;
474
+ this.storeMetrics.averageReadLatencyMs = (this.storeMetrics.averageReadLatencyMs * (this.storeMetrics.totalReads - 1) + readTime) / this.storeMetrics.totalReads;
475
+ return session || null;
476
+ }
477
+ /**
478
+ * Retrieve session by agent ID
479
+ */ async getSessionByAgentId(agentId) {
480
+ const sessionId = this.agentSessions.get(agentId);
481
+ if (!sessionId) {
482
+ return null;
483
+ }
484
+ return this.getSession(sessionId);
485
+ }
486
+ /**
487
+ * Update existing session
488
+ */ async updateSession(sessionId, updates) {
489
+ const session = await this.getSession(sessionId);
490
+ if (!session) {
491
+ throw new Error(`Session ${sessionId} not found`);
492
+ }
493
+ const updatedSession = {
494
+ ...session,
495
+ ...updates
496
+ };
497
+ await this.storeSession(updatedSession);
498
+ }
499
+ /**
500
+ * Delete session and associated checkpoints
501
+ */ async deleteSession(sessionId) {
502
+ const session = await this.getSession(sessionId);
503
+ if (session) {
504
+ this.agentSessions.delete(session.agentId);
505
+ }
506
+ this.sessions.delete(sessionId);
507
+ // Delete all associated checkpoints
508
+ const checkpointIds = this.sessionCheckpoints.get(sessionId) || [];
509
+ for (const checkpointId of checkpointIds){
510
+ await this.deleteCheckpoint(checkpointId);
511
+ }
512
+ this.sessionCheckpoints.delete(sessionId);
513
+ // Delete session file
514
+ try {
515
+ const sessionPath = path.join(this.storagePath, 'sessions', `${sessionId}.msgpack`);
516
+ await fs.unlink(sessionPath);
517
+ this.storeMetrics.totalDeletions++;
518
+ } catch {
519
+ // File may not exist
520
+ }
521
+ }
522
+ /**
523
+ * Query sessions with filtering
524
+ */ async querySessions(filter) {
525
+ let sessions = Array.from(this.sessions.values());
526
+ if (filter.agentId) {
527
+ sessions = sessions.filter((s)=>s.agentId === filter.agentId);
528
+ }
529
+ if (filter.sessionId) {
530
+ sessions = sessions.filter((s)=>s.sessionId === filter.sessionId);
531
+ }
532
+ if (filter.state && filter.state.length > 0) {
533
+ sessions = sessions.filter((s)=>filter.state.includes(s.state));
534
+ }
535
+ if (filter.isPaused !== undefined) {
536
+ sessions = sessions.filter((s)=>s.isPaused === filter.isPaused);
537
+ }
538
+ if (filter.priorityMin !== undefined) {
539
+ sessions = sessions.filter((s)=>s.priority >= filter.priorityMin);
540
+ }
541
+ if (filter.priorityMax !== undefined) {
542
+ sessions = sessions.filter((s)=>s.priority <= filter.priorityMax);
543
+ }
544
+ // Apply pagination
545
+ const offset = filter.offset || 0;
546
+ const limit = filter.limit || sessions.length;
547
+ return sessions.slice(offset, offset + limit);
548
+ }
549
+ /**
550
+ * List all sessions
551
+ */ async listSessions(limit, offset) {
552
+ return this.querySessions({
553
+ limit,
554
+ offset
555
+ });
556
+ }
557
+ /**
558
+ * Store checkpoint (ISessionStore interface)
559
+ */ async storeCheckpoint(checkpoint) {
560
+ const startTime = performance.now();
561
+ // Convert Checkpoint to CheckpointData
562
+ const checkpointData = {
563
+ id: checkpoint.id,
564
+ sessionId: checkpoint.sessionId,
565
+ agentId: checkpoint.agentId,
566
+ messageUUID: checkpoint.messageUUID,
567
+ state: checkpoint.state,
568
+ timestamp: checkpoint.timestamp instanceof Date ? checkpoint.timestamp.getTime() : checkpoint.timestamp,
569
+ stateSnapshot: checkpoint.metadata?.context || {},
570
+ metadata: {
571
+ reason: checkpoint.metadata.reason,
572
+ autoCheckpoint: checkpoint.metadata.autoCheckpoint,
573
+ pendingDependencies: checkpoint.metadata.pendingDependencies,
574
+ context: checkpoint.metadata.context
575
+ },
576
+ checksum: this.calculateChecksum(checkpoint.metadata?.context || {}),
577
+ compressedSize: 0,
578
+ uncompressedSize: 0
579
+ };
580
+ // Calculate compression sizes
581
+ const uncompressedData = JSON.stringify(checkpointData.stateSnapshot);
582
+ checkpointData.uncompressedSize = Buffer.byteLength(uncompressedData, 'utf8');
583
+ const compressedBuffer = msgpack.encode(checkpointData.stateSnapshot);
584
+ checkpointData.compressedSize = compressedBuffer.length;
585
+ // Store in memory
586
+ this.checkpoints.set(checkpoint.id, checkpointData);
587
+ this.messageUUIDIndex.set(checkpoint.messageUUID, checkpoint.id);
588
+ if (!this.sessionCheckpoints.has(checkpoint.sessionId)) {
589
+ this.sessionCheckpoints.set(checkpoint.sessionId, []);
590
+ }
591
+ this.sessionCheckpoints.get(checkpoint.sessionId).push(checkpoint.id);
592
+ // Persist to disk
593
+ await this.persistCheckpoint(checkpointData, compressedBuffer);
594
+ // Update metrics
595
+ const writeTime = performance.now() - startTime;
596
+ this.storeMetrics.totalCheckpoints = this.checkpoints.size;
597
+ this.storeMetrics.totalWrites++;
598
+ this.storeMetrics.averageWriteLatencyMs = (this.storeMetrics.averageWriteLatencyMs * (this.storeMetrics.totalWrites - 1) + writeTime) / this.storeMetrics.totalWrites;
599
+ }
600
+ /**
601
+ * Get checkpoint (ISessionStore interface)
602
+ */ async getCheckpoint(checkpointId) {
603
+ const startTime = performance.now();
604
+ const checkpointData = this.checkpoints.get(checkpointId);
605
+ if (!checkpointData) {
606
+ return null;
607
+ }
608
+ // Convert CheckpointData to Checkpoint
609
+ const checkpoint = {
610
+ id: checkpointData.id,
611
+ sessionId: checkpointData.sessionId,
612
+ agentId: checkpointData.agentId,
613
+ messageUUID: checkpointData.messageUUID,
614
+ state: checkpointData.state,
615
+ timestamp: new Date(checkpointData.timestamp),
616
+ metadata: {
617
+ reason: checkpointData.metadata.reason,
618
+ autoCheckpoint: checkpointData.metadata.autoCheckpoint,
619
+ pendingDependencies: checkpointData.metadata.pendingDependencies,
620
+ context: checkpointData.metadata.context
621
+ }
622
+ };
623
+ // Update metrics
624
+ const readTime = performance.now() - startTime;
625
+ this.storeMetrics.totalReads++;
626
+ this.storeMetrics.averageReadLatencyMs = (this.storeMetrics.averageReadLatencyMs * (this.storeMetrics.totalReads - 1) + readTime) / this.storeMetrics.totalReads;
627
+ return checkpoint;
628
+ }
629
+ /**
630
+ * Get checkpoint by message UUID
631
+ */ async getCheckpointByMessageUUID(messageUUID) {
632
+ const checkpointId = this.messageUUIDIndex.get(messageUUID);
633
+ if (!checkpointId) {
634
+ return null;
635
+ }
636
+ return this.getCheckpoint(checkpointId);
637
+ }
638
+ /**
639
+ * Get latest checkpoint for session (ISessionStore interface)
640
+ */ async getLatestCheckpoint(sessionId) {
641
+ const checkpointData = this.getLatestCheckpointData(sessionId);
642
+ if (!checkpointData) {
643
+ return null;
644
+ }
645
+ return this.getCheckpoint(checkpointData.id);
646
+ }
647
+ /**
648
+ * List checkpoints (ISessionStore interface)
649
+ */ async listCheckpoints(sessionId, limit) {
650
+ const checkpointIds = this.sessionCheckpoints.get(sessionId) || [];
651
+ const checkpoints = [];
652
+ for (const id of checkpointIds){
653
+ const checkpoint = await this.getCheckpoint(id);
654
+ if (checkpoint) {
655
+ checkpoints.push(checkpoint);
656
+ }
657
+ }
658
+ // Sort by timestamp (newest first)
659
+ checkpoints.sort((a, b)=>b.timestamp.getTime() - a.timestamp.getTime());
660
+ if (limit) {
661
+ return checkpoints.slice(0, limit);
662
+ }
663
+ return checkpoints;
664
+ }
665
+ /**
666
+ * Query checkpoints with filtering
667
+ */ async queryCheckpoints(filter) {
668
+ let checkpoints = [];
669
+ // Collect all checkpoints
670
+ for (const checkpointId of Array.from(this.checkpoints.keys())){
671
+ const checkpoint = await this.getCheckpoint(checkpointId);
672
+ if (checkpoint) {
673
+ checkpoints.push(checkpoint);
674
+ }
675
+ }
676
+ // Apply filters
677
+ if (filter.checkpointId) {
678
+ checkpoints = checkpoints.filter((c)=>c.id === filter.checkpointId);
679
+ }
680
+ if (filter.sessionId) {
681
+ checkpoints = checkpoints.filter((c)=>c.sessionId === filter.sessionId);
682
+ }
683
+ if (filter.agentId) {
684
+ checkpoints = checkpoints.filter((c)=>c.agentId === filter.agentId);
685
+ }
686
+ if (filter.messageUUID) {
687
+ checkpoints = checkpoints.filter((c)=>c.messageUUID === filter.messageUUID);
688
+ }
689
+ if (filter.state && filter.state.length > 0) {
690
+ checkpoints = checkpoints.filter((c)=>filter.state.includes(c.state));
691
+ }
692
+ if (filter.autoCheckpoint !== undefined) {
693
+ checkpoints = checkpoints.filter((c)=>c.metadata.autoCheckpoint === filter.autoCheckpoint);
694
+ }
695
+ if (filter.createdAfter) {
696
+ checkpoints = checkpoints.filter((c)=>c.timestamp >= filter.createdAfter);
697
+ }
698
+ if (filter.createdBefore) {
699
+ checkpoints = checkpoints.filter((c)=>c.timestamp <= filter.createdBefore);
700
+ }
701
+ // Apply pagination
702
+ const offset = filter.offset || 0;
703
+ const limit = filter.limit || checkpoints.length;
704
+ return checkpoints.slice(offset, offset + limit);
705
+ }
706
+ /**
707
+ * Verify checkpoint integrity (timing-safe comparison)
708
+ */ async verifyCheckpointIntegrity(checkpointId) {
709
+ const checkpointData = this.checkpoints.get(checkpointId);
710
+ if (!checkpointData) {
711
+ return false;
712
+ }
713
+ const currentChecksum = this.calculateChecksum(checkpointData.stateSnapshot);
714
+ // Use timing-safe comparison to prevent timing attacks
715
+ const currentBuf = Buffer.from(currentChecksum, 'hex');
716
+ const storedBuf = Buffer.from(checkpointData.checksum, 'hex');
717
+ if (currentBuf.length !== storedBuf.length) {
718
+ return false;
719
+ }
720
+ return timingSafeEqual(currentBuf, storedBuf);
721
+ }
722
+ /**
723
+ * Compact storage (ISessionStore interface)
724
+ */ async compact() {
725
+ // Remove duplicate checkpoints and optimize storage
726
+ const sessionsToCompact = Array.from(this.sessionCheckpoints.keys());
727
+ let deletedCount = 0;
728
+ for (const sessionId of sessionsToCompact){
729
+ const checkpointIds = this.sessionCheckpoints.get(sessionId) || [];
730
+ const checkpoints = checkpointIds.map((id)=>this.checkpoints.get(id)).filter(Boolean).sort((a, b)=>b.timestamp - a.timestamp);
731
+ // Keep only the last 10 checkpoints per session
732
+ if (checkpoints.length > 10) {
733
+ const toDelete = checkpoints.slice(10);
734
+ for (const checkpoint of toDelete){
735
+ await this.deleteCheckpoint(checkpoint.id);
736
+ deletedCount++;
737
+ }
738
+ }
739
+ }
740
+ console.log(`✅ Storage compaction complete (deleted ${deletedCount} checkpoints)`);
741
+ }
742
+ /**
743
+ * Get storage metrics (ISessionStore interface)
744
+ */ getMetrics() {
745
+ this.storeMetrics.uptimeMs = Date.now() - this.initTime;
746
+ this.storeMetrics.totalSessions = this.sessions.size;
747
+ this.storeMetrics.totalCheckpoints = this.checkpoints.size;
748
+ this.storeMetrics.totalStorageMb = this.metrics.totalStorageMb;
749
+ this.storeMetrics.averageCompressionRatio = this.metrics.compressionRatio;
750
+ return {
751
+ ...this.storeMetrics,
752
+ totalRestores: this.metrics.totalRestores,
753
+ averageCreateTimeMs: this.metrics.averageCreateTimeMs,
754
+ averageRestoreTimeMs: this.metrics.averageRestoreTimeMs,
755
+ compressionRatio: this.metrics.compressionRatio,
756
+ p95RestoreTimeMs: this.metrics.p95RestoreTimeMs,
757
+ p99RestoreTimeMs: this.metrics.p99RestoreTimeMs
758
+ };
759
+ }
760
+ /**
761
+ * Health check
762
+ */ async healthCheck() {
763
+ const startTime = performance.now();
764
+ const errors = [];
765
+ try {
766
+ // Check storage directory accessibility
767
+ await fs.access(this.storagePath);
768
+ // Check if we can write to storage
769
+ const testPath = path.join(this.storagePath, '.health-check');
770
+ await fs.writeFile(testPath, 'test');
771
+ await fs.unlink(testPath);
772
+ const latencyMs = performance.now() - startTime;
773
+ return {
774
+ healthy: true,
775
+ latencyMs
776
+ };
777
+ } catch (error) {
778
+ errors.push(`Storage health check failed: ${error}`);
779
+ return {
780
+ healthy: false,
781
+ latencyMs: performance.now() - startTime,
782
+ errors
783
+ };
784
+ }
785
+ }
786
+ /**
787
+ * Initialize storage backend
788
+ */ async initialize() {
789
+ if (this.initialized) {
790
+ return;
791
+ }
792
+ await this.ensureStorageDirectory();
793
+ await fs.mkdir(path.join(this.storagePath, 'sessions'), {
794
+ recursive: true
795
+ });
796
+ await this.loadFromDisk();
797
+ this.initialized = true;
798
+ console.log('✅ CheckpointManager initialized');
799
+ }
800
+ /**
801
+ * Close storage connections
802
+ */ async close() {
803
+ // Stop automatic cleanup
804
+ if (this.cleanupInterval) {
805
+ clearInterval(this.cleanupInterval);
806
+ this.cleanupInterval = undefined;
807
+ }
808
+ // Persist any pending data
809
+ this.initialized = false;
810
+ console.log('✅ CheckpointManager closed');
811
+ }
812
+ /**
813
+ * Shutdown with cleanup
814
+ */ async shutdown() {
815
+ if (this.cleanupInterval) {
816
+ clearInterval(this.cleanupInterval);
817
+ this.cleanupInterval = undefined;
818
+ }
819
+ // Final cleanup before shutdown
820
+ await this.cleanExpiredCheckpoints();
821
+ this.initialized = false;
822
+ console.log('✅ CheckpointManager shutdown complete');
823
+ }
824
+ /**
825
+ * Get memory usage statistics
826
+ */ getMemoryStats() {
827
+ const now = Date.now();
828
+ let oldestAge = 0;
829
+ const values = Array.from(this.checkpoints.values());
830
+ for (const checkpoint of values){
831
+ const age = now - checkpoint.timestamp;
832
+ oldestAge = Math.max(oldestAge, age);
833
+ }
834
+ return {
835
+ checkpointCount: this.checkpoints.size,
836
+ memoryUsageMB: process.memoryUsage().heapUsed / 1024 / 1024,
837
+ oldestCheckpointAge: oldestAge
838
+ };
839
+ }
840
+ /**
841
+ * Check if storage is ready
842
+ */ isReady() {
843
+ return this.initialized;
844
+ }
845
+ }
846
+
847
+ //# sourceMappingURL=checkpoint-manager.js.map