specmem-hardwicksoftware 3.5.99

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 (1473) hide show
  1. package/CHANGELOG.md +299 -0
  2. package/LICENSE.md +6406 -0
  3. package/README.md +539 -0
  4. package/bin/AegisTheme.cjs +1022 -0
  5. package/bin/AnsiRenderer.cjs +1055 -0
  6. package/bin/BoxRenderer.cjs +605 -0
  7. package/bin/ClaudeLiveScreen.cjs +1299 -0
  8. package/bin/DashboardModules.cjs +733 -0
  9. package/bin/LiveScreenCapture.cjs +1012 -0
  10. package/bin/MemoryBrowserScreen.cjs +1595 -0
  11. package/bin/TabManager.cjs +1414 -0
  12. package/bin/checkAgentStatus-fix.patch +30 -0
  13. package/bin/mcp-socket-client.cjs +462 -0
  14. package/bin/screen-utils.cjs +106 -0
  15. package/bin/specmem-autoclaude.cjs +663 -0
  16. package/bin/specmem-cleanup.cjs +421 -0
  17. package/bin/specmem-cli.cjs +794 -0
  18. package/bin/specmem-console-teamcomms-class.cjs +428 -0
  19. package/bin/specmem-console.cjs +8104 -0
  20. package/bin/specmem-statusbar.cjs +530 -0
  21. package/bootstrap.cjs +5065 -0
  22. package/claude-hooks/agent-chooser-hook.js +179 -0
  23. package/claude-hooks/agent-chooser-inject.js +121 -0
  24. package/claude-hooks/agent-loading-hook.js +990 -0
  25. package/claude-hooks/agent-output-fader.cjs +542 -0
  26. package/claude-hooks/agent-output-interceptor.js +193 -0
  27. package/claude-hooks/agent-type-matcher.js +419 -0
  28. package/claude-hooks/auto-bypass.py +74 -0
  29. package/claude-hooks/background-completion-silencer.js +134 -0
  30. package/claude-hooks/bash-auto-background.js +182 -0
  31. package/claude-hooks/build-cedict-dictionary.mjs +167 -0
  32. package/claude-hooks/bullshit-radar.cjs +323 -0
  33. package/claude-hooks/cedict-codes.json +270 -0
  34. package/claude-hooks/cedict-extracted.json +22632 -0
  35. package/claude-hooks/claude-watchdog.sh +401 -0
  36. package/claude-hooks/context-dedup.cjs +144 -0
  37. package/claude-hooks/context-yeeter.cjs +244 -0
  38. package/claude-hooks/debug-suffix.cjs +15 -0
  39. package/claude-hooks/debug2.cjs +7 -0
  40. package/claude-hooks/drilldown-enforcer.js +242 -0
  41. package/claude-hooks/english-morphology-standalone.cjs +149 -0
  42. package/claude-hooks/english-morphology.cjs +152 -0
  43. package/claude-hooks/extract-translations.mjs +193 -0
  44. package/claude-hooks/file-claim-enforcer.cjs +293 -0
  45. package/claude-hooks/file-claim-enforcer.js +293 -0
  46. package/claude-hooks/find-collisions.cjs +39 -0
  47. package/claude-hooks/fix-abbreviations.cjs +60 -0
  48. package/claude-hooks/fix-collisions.cjs +60 -0
  49. package/claude-hooks/fix-decompressor.cjs +79 -0
  50. package/claude-hooks/fix-suffixes.cjs +66 -0
  51. package/claude-hooks/grammar-engine.cjs +159 -0
  52. package/claude-hooks/input-aware-improver.js +231 -0
  53. package/claude-hooks/is-agent.cjs +64 -0
  54. package/claude-hooks/mega-test.cjs +213 -0
  55. package/claude-hooks/merge-dictionaries.mjs +207 -0
  56. package/claude-hooks/merged-codes.cjs +22675 -0
  57. package/claude-hooks/merged-codes.json +22676 -0
  58. package/claude-hooks/output-cleaner.cjs +388 -0
  59. package/claude-hooks/post-write-memory-hook.cjs +430 -0
  60. package/claude-hooks/quick-test.cjs +24 -0
  61. package/claude-hooks/quick-test2.cjs +24 -0
  62. package/claude-hooks/remove-bad-codes.cjs +23 -0
  63. package/claude-hooks/search-reminder-hook.js +90 -0
  64. package/claude-hooks/semantic-test.cjs +93 -0
  65. package/claude-hooks/settings.json +445 -0
  66. package/claude-hooks/smart-context-hook.cjs +547 -0
  67. package/claude-hooks/smart-context-hook.js +539 -0
  68. package/claude-hooks/smart-search-interceptor.js +364 -0
  69. package/claude-hooks/socket-connect-helper.cjs +235 -0
  70. package/claude-hooks/specmem/sockets/session-start.lock +1 -0
  71. package/claude-hooks/specmem-context-hook.cjs +357 -0
  72. package/claude-hooks/specmem-context-hook.js +357 -0
  73. package/claude-hooks/specmem-drilldown-hook.cjs +480 -0
  74. package/claude-hooks/specmem-drilldown-hook.js +480 -0
  75. package/claude-hooks/specmem-drilldown-setter.js +210 -0
  76. package/claude-hooks/specmem-paths.cjs +213 -0
  77. package/claude-hooks/specmem-precompact.js +183 -0
  78. package/claude-hooks/specmem-session-init.sh +33 -0
  79. package/claude-hooks/specmem-session-start.cjs +498 -0
  80. package/claude-hooks/specmem-stop-hook.cjs +73 -0
  81. package/claude-hooks/specmem-stop-hook.js +5 -0
  82. package/claude-hooks/specmem-team-comms.cjs +434 -0
  83. package/claude-hooks/specmem-team-member-inject.js +271 -0
  84. package/claude-hooks/specmem-unified-hook.py +670 -0
  85. package/claude-hooks/subagent-loading-hook.js +194 -0
  86. package/claude-hooks/sysprompt-squisher.cjs +167 -0
  87. package/claude-hooks/task-progress-hook.js +204 -0
  88. package/claude-hooks/team-comms-enforcer.cjs +585 -0
  89. package/claude-hooks/test-accuracy.cjs +27 -0
  90. package/claude-hooks/test-big.cjs +28 -0
  91. package/claude-hooks/test-inflectors.cjs +39 -0
  92. package/claude-hooks/test-pluralize.cjs +37 -0
  93. package/claude-hooks/test-quick.cjs +8 -0
  94. package/claude-hooks/test-wink.cjs +20 -0
  95. package/claude-hooks/token-compressor.cjs +940 -0
  96. package/claude-hooks/use-code-pointers.cjs +279 -0
  97. package/commands/COMMAND_TOOL_MAP.md +299 -0
  98. package/commands/specmem-agents.md +412 -0
  99. package/commands/specmem-autoclaude.md +295 -0
  100. package/commands/specmem-changes.md +247 -0
  101. package/commands/specmem-code.md +103 -0
  102. package/commands/specmem-configteammembercomms.md +322 -0
  103. package/commands/specmem-drilldown.md +208 -0
  104. package/commands/specmem-find.md +195 -0
  105. package/commands/specmem-getdashboard.md +243 -0
  106. package/commands/specmem-hooks.md +219 -0
  107. package/commands/specmem-pointers.md +149 -0
  108. package/commands/specmem-progress.md +287 -0
  109. package/commands/specmem-remember.md +123 -0
  110. package/commands/specmem-service.md +349 -0
  111. package/commands/specmem-stats.md +189 -0
  112. package/commands/specmem-team-member.md +409 -0
  113. package/commands/specmem-webdev.md +583 -0
  114. package/commands/specmem.md +363 -0
  115. package/dist/autoStart/index.d.ts +214 -0
  116. package/dist/autoStart/index.d.ts.map +1 -0
  117. package/dist/autoStart/index.js +883 -0
  118. package/dist/autoStart/index.js.map +1 -0
  119. package/dist/claude-sessions/contextRestorationParser.d.ts +74 -0
  120. package/dist/claude-sessions/contextRestorationParser.d.ts.map +1 -0
  121. package/dist/claude-sessions/contextRestorationParser.js +570 -0
  122. package/dist/claude-sessions/contextRestorationParser.js.map +1 -0
  123. package/dist/claude-sessions/index.d.ts +13 -0
  124. package/dist/claude-sessions/index.d.ts.map +1 -0
  125. package/dist/claude-sessions/index.js +11 -0
  126. package/dist/claude-sessions/index.js.map +1 -0
  127. package/dist/claude-sessions/sessionIntegration.d.ts +48 -0
  128. package/dist/claude-sessions/sessionIntegration.d.ts.map +1 -0
  129. package/dist/claude-sessions/sessionIntegration.js +146 -0
  130. package/dist/claude-sessions/sessionIntegration.js.map +1 -0
  131. package/dist/claude-sessions/sessionParser.d.ts +293 -0
  132. package/dist/claude-sessions/sessionParser.d.ts.map +1 -0
  133. package/dist/claude-sessions/sessionParser.js +1028 -0
  134. package/dist/claude-sessions/sessionParser.js.map +1 -0
  135. package/dist/claude-sessions/sessionWatcher.d.ts +139 -0
  136. package/dist/claude-sessions/sessionWatcher.d.ts.map +1 -0
  137. package/dist/claude-sessions/sessionWatcher.js +722 -0
  138. package/dist/claude-sessions/sessionWatcher.js.map +1 -0
  139. package/dist/cli/deploy-to-claude.d.ts +56 -0
  140. package/dist/cli/deploy-to-claude.d.ts.map +1 -0
  141. package/dist/cli/deploy-to-claude.js +576 -0
  142. package/dist/cli/deploy-to-claude.js.map +1 -0
  143. package/dist/code-explanations/explainCode.d.ts +86 -0
  144. package/dist/code-explanations/explainCode.d.ts.map +1 -0
  145. package/dist/code-explanations/explainCode.js +286 -0
  146. package/dist/code-explanations/explainCode.js.map +1 -0
  147. package/dist/code-explanations/feedback.d.ts +87 -0
  148. package/dist/code-explanations/feedback.d.ts.map +1 -0
  149. package/dist/code-explanations/feedback.js +212 -0
  150. package/dist/code-explanations/feedback.js.map +1 -0
  151. package/dist/code-explanations/getRelatedCode.d.ts +80 -0
  152. package/dist/code-explanations/getRelatedCode.d.ts.map +1 -0
  153. package/dist/code-explanations/getRelatedCode.js +262 -0
  154. package/dist/code-explanations/getRelatedCode.js.map +1 -0
  155. package/dist/code-explanations/index.d.ts +284 -0
  156. package/dist/code-explanations/index.d.ts.map +1 -0
  157. package/dist/code-explanations/index.js +249 -0
  158. package/dist/code-explanations/index.js.map +1 -0
  159. package/dist/code-explanations/linkCodeToPrompt.d.ts +79 -0
  160. package/dist/code-explanations/linkCodeToPrompt.d.ts.map +1 -0
  161. package/dist/code-explanations/linkCodeToPrompt.js +213 -0
  162. package/dist/code-explanations/linkCodeToPrompt.js.map +1 -0
  163. package/dist/code-explanations/recallExplanation.d.ts +88 -0
  164. package/dist/code-explanations/recallExplanation.d.ts.map +1 -0
  165. package/dist/code-explanations/recallExplanation.js +218 -0
  166. package/dist/code-explanations/recallExplanation.js.map +1 -0
  167. package/dist/code-explanations/schema.d.ts +32 -0
  168. package/dist/code-explanations/schema.d.ts.map +1 -0
  169. package/dist/code-explanations/schema.js +221 -0
  170. package/dist/code-explanations/schema.js.map +1 -0
  171. package/dist/code-explanations/semanticSearch.d.ts +75 -0
  172. package/dist/code-explanations/semanticSearch.d.ts.map +1 -0
  173. package/dist/code-explanations/semanticSearch.js +203 -0
  174. package/dist/code-explanations/semanticSearch.js.map +1 -0
  175. package/dist/code-explanations/types.d.ts +328 -0
  176. package/dist/code-explanations/types.d.ts.map +1 -0
  177. package/dist/code-explanations/types.js +122 -0
  178. package/dist/code-explanations/types.js.map +1 -0
  179. package/dist/codebase/codeAnalyzer.d.ts +272 -0
  180. package/dist/codebase/codeAnalyzer.d.ts.map +1 -0
  181. package/dist/codebase/codeAnalyzer.js +1353 -0
  182. package/dist/codebase/codeAnalyzer.js.map +1 -0
  183. package/dist/codebase/codebaseIndexer.d.ts +360 -0
  184. package/dist/codebase/codebaseIndexer.d.ts.map +1 -0
  185. package/dist/codebase/codebaseIndexer.js +1735 -0
  186. package/dist/codebase/codebaseIndexer.js.map +1 -0
  187. package/dist/codebase/codebaseTools.d.ts +853 -0
  188. package/dist/codebase/codebaseTools.d.ts.map +1 -0
  189. package/dist/codebase/codebaseTools.js +1279 -0
  190. package/dist/codebase/codebaseTools.js.map +1 -0
  191. package/dist/codebase/exclusions.d.ts +111 -0
  192. package/dist/codebase/exclusions.d.ts.map +1 -0
  193. package/dist/codebase/exclusions.js +771 -0
  194. package/dist/codebase/exclusions.js.map +1 -0
  195. package/dist/codebase/fileWatcher.d.ts +135 -0
  196. package/dist/codebase/fileWatcher.d.ts.map +1 -0
  197. package/dist/codebase/fileWatcher.js +309 -0
  198. package/dist/codebase/fileWatcher.js.map +1 -0
  199. package/dist/codebase/index.d.ts +33 -0
  200. package/dist/codebase/index.d.ts.map +1 -0
  201. package/dist/codebase/index.js +77 -0
  202. package/dist/codebase/index.js.map +1 -0
  203. package/dist/codebase/ingestion.d.ts +177 -0
  204. package/dist/codebase/ingestion.d.ts.map +1 -0
  205. package/dist/codebase/ingestion.js +690 -0
  206. package/dist/codebase/ingestion.js.map +1 -0
  207. package/dist/codebase/languageDetection.d.ts +75 -0
  208. package/dist/codebase/languageDetection.d.ts.map +1 -0
  209. package/dist/codebase/languageDetection.js +768 -0
  210. package/dist/codebase/languageDetection.js.map +1 -0
  211. package/dist/commands/codebaseCommands.d.ts +101 -0
  212. package/dist/commands/codebaseCommands.d.ts.map +1 -0
  213. package/dist/commands/codebaseCommands.js +911 -0
  214. package/dist/commands/codebaseCommands.js.map +1 -0
  215. package/dist/commands/commandHandler.d.ts +126 -0
  216. package/dist/commands/commandHandler.d.ts.map +1 -0
  217. package/dist/commands/commandHandler.js +296 -0
  218. package/dist/commands/commandHandler.js.map +1 -0
  219. package/dist/commands/commandLoader.d.ts +103 -0
  220. package/dist/commands/commandLoader.d.ts.map +1 -0
  221. package/dist/commands/commandLoader.js +223 -0
  222. package/dist/commands/commandLoader.js.map +1 -0
  223. package/dist/commands/contextCommands.d.ts +83 -0
  224. package/dist/commands/contextCommands.d.ts.map +1 -0
  225. package/dist/commands/contextCommands.js +512 -0
  226. package/dist/commands/contextCommands.js.map +1 -0
  227. package/dist/commands/index.d.ts +24 -0
  228. package/dist/commands/index.d.ts.map +1 -0
  229. package/dist/commands/index.js +28 -0
  230. package/dist/commands/index.js.map +1 -0
  231. package/dist/commands/mcpResources.d.ts +50 -0
  232. package/dist/commands/mcpResources.d.ts.map +1 -0
  233. package/dist/commands/mcpResources.js +372 -0
  234. package/dist/commands/mcpResources.js.map +1 -0
  235. package/dist/commands/memoryCommands.d.ts +74 -0
  236. package/dist/commands/memoryCommands.d.ts.map +1 -0
  237. package/dist/commands/memoryCommands.js +609 -0
  238. package/dist/commands/memoryCommands.js.map +1 -0
  239. package/dist/commands/promptCommands.d.ts +91 -0
  240. package/dist/commands/promptCommands.d.ts.map +1 -0
  241. package/dist/commands/promptCommands.js +801 -0
  242. package/dist/commands/promptCommands.js.map +1 -0
  243. package/dist/commands/teamMemberCommands.d.ts +21 -0
  244. package/dist/commands/teamMemberCommands.d.ts.map +1 -0
  245. package/dist/commands/teamMemberCommands.js +137 -0
  246. package/dist/commands/teamMemberCommands.js.map +1 -0
  247. package/dist/comms/fileCommsTransport.d.ts +91 -0
  248. package/dist/comms/fileCommsTransport.d.ts.map +1 -0
  249. package/dist/comms/fileCommsTransport.js +244 -0
  250. package/dist/comms/fileCommsTransport.js.map +1 -0
  251. package/dist/comms/index.d.ts +7 -0
  252. package/dist/comms/index.d.ts.map +1 -0
  253. package/dist/comms/index.js +7 -0
  254. package/dist/comms/index.js.map +1 -0
  255. package/dist/config/apiKeyDetection.d.ts +41 -0
  256. package/dist/config/apiKeyDetection.d.ts.map +1 -0
  257. package/dist/config/apiKeyDetection.js +211 -0
  258. package/dist/config/apiKeyDetection.js.map +1 -0
  259. package/dist/config/autoConfig.d.ts +188 -0
  260. package/dist/config/autoConfig.d.ts.map +1 -0
  261. package/dist/config/autoConfig.js +850 -0
  262. package/dist/config/autoConfig.js.map +1 -0
  263. package/dist/config/configSync.d.ts +119 -0
  264. package/dist/config/configSync.d.ts.map +1 -0
  265. package/dist/config/configSync.js +878 -0
  266. package/dist/config/configSync.js.map +1 -0
  267. package/dist/config/embeddingTimeouts.d.ts +145 -0
  268. package/dist/config/embeddingTimeouts.d.ts.map +1 -0
  269. package/dist/config/embeddingTimeouts.js +255 -0
  270. package/dist/config/embeddingTimeouts.js.map +1 -0
  271. package/dist/config/index.d.ts +5 -0
  272. package/dist/config/index.d.ts.map +1 -0
  273. package/dist/config/index.js +7 -0
  274. package/dist/config/index.js.map +1 -0
  275. package/dist/config/languageConfig.d.ts +68 -0
  276. package/dist/config/languageConfig.d.ts.map +1 -0
  277. package/dist/config/languageConfig.js +473 -0
  278. package/dist/config/languageConfig.js.map +1 -0
  279. package/dist/config/password.d.ts +145 -0
  280. package/dist/config/password.d.ts.map +1 -0
  281. package/dist/config/password.js +428 -0
  282. package/dist/config/password.js.map +1 -0
  283. package/dist/config.d.ts +338 -0
  284. package/dist/config.d.ts.map +1 -0
  285. package/dist/config.js +1177 -0
  286. package/dist/config.js.map +1 -0
  287. package/dist/consolidation.d.ts +44 -0
  288. package/dist/consolidation.d.ts.map +1 -0
  289. package/dist/consolidation.js +447 -0
  290. package/dist/consolidation.js.map +1 -0
  291. package/dist/constants.d.ts +371 -0
  292. package/dist/constants.d.ts.map +1 -0
  293. package/dist/constants.js +552 -0
  294. package/dist/constants.js.map +1 -0
  295. package/dist/coordination/TeamMemberRegistry.d.ts +192 -0
  296. package/dist/coordination/TeamMemberRegistry.d.ts.map +1 -0
  297. package/dist/coordination/TeamMemberRegistry.js +415 -0
  298. package/dist/coordination/TeamMemberRegistry.js.map +1 -0
  299. package/dist/coordination/events.d.ts +369 -0
  300. package/dist/coordination/events.d.ts.map +1 -0
  301. package/dist/coordination/events.js +232 -0
  302. package/dist/coordination/events.js.map +1 -0
  303. package/dist/coordination/handlers.d.ts +116 -0
  304. package/dist/coordination/handlers.d.ts.map +1 -0
  305. package/dist/coordination/handlers.js +400 -0
  306. package/dist/coordination/handlers.js.map +1 -0
  307. package/dist/coordination/index.d.ts +14 -0
  308. package/dist/coordination/index.d.ts.map +1 -0
  309. package/dist/coordination/index.js +31 -0
  310. package/dist/coordination/index.js.map +1 -0
  311. package/dist/coordination/integration.d.ts +260 -0
  312. package/dist/coordination/integration.d.ts.map +1 -0
  313. package/dist/coordination/integration.js +472 -0
  314. package/dist/coordination/integration.js.map +1 -0
  315. package/dist/coordination/server.d.ts +266 -0
  316. package/dist/coordination/server.d.ts.map +1 -0
  317. package/dist/coordination/server.js +995 -0
  318. package/dist/coordination/server.js.map +1 -0
  319. package/dist/coordination/serviceProvider.d.ts +70 -0
  320. package/dist/coordination/serviceProvider.d.ts.map +1 -0
  321. package/dist/coordination/serviceProvider.js +273 -0
  322. package/dist/coordination/serviceProvider.js.map +1 -0
  323. package/dist/dashboard/api/claudeControl.d.ts +44 -0
  324. package/dist/dashboard/api/claudeControl.d.ts.map +1 -0
  325. package/dist/dashboard/api/claudeControl.js +650 -0
  326. package/dist/dashboard/api/claudeControl.js.map +1 -0
  327. package/dist/dashboard/api/claudeHistory.d.ts +4 -0
  328. package/dist/dashboard/api/claudeHistory.d.ts.map +1 -0
  329. package/dist/dashboard/api/claudeHistory.js +319 -0
  330. package/dist/dashboard/api/claudeHistory.js.map +1 -0
  331. package/dist/dashboard/api/dataExport.d.ts +23 -0
  332. package/dist/dashboard/api/dataExport.d.ts.map +1 -0
  333. package/dist/dashboard/api/dataExport.js +509 -0
  334. package/dist/dashboard/api/dataExport.js.map +1 -0
  335. package/dist/dashboard/api/fileManager.d.ts +39 -0
  336. package/dist/dashboard/api/fileManager.d.ts.map +1 -0
  337. package/dist/dashboard/api/fileManager.js +814 -0
  338. package/dist/dashboard/api/fileManager.js.map +1 -0
  339. package/dist/dashboard/api/hooks.d.ts +16 -0
  340. package/dist/dashboard/api/hooks.d.ts.map +1 -0
  341. package/dist/dashboard/api/hooks.js +342 -0
  342. package/dist/dashboard/api/hooks.js.map +1 -0
  343. package/dist/dashboard/api/hotReload.d.ts +14 -0
  344. package/dist/dashboard/api/hotReload.d.ts.map +1 -0
  345. package/dist/dashboard/api/hotReload.js +219 -0
  346. package/dist/dashboard/api/hotReload.js.map +1 -0
  347. package/dist/dashboard/api/liveSessionStream.d.ts +19 -0
  348. package/dist/dashboard/api/liveSessionStream.d.ts.map +1 -0
  349. package/dist/dashboard/api/liveSessionStream.js +430 -0
  350. package/dist/dashboard/api/liveSessionStream.js.map +1 -0
  351. package/dist/dashboard/api/memoryRecall.d.ts +20 -0
  352. package/dist/dashboard/api/memoryRecall.d.ts.map +1 -0
  353. package/dist/dashboard/api/memoryRecall.js +524 -0
  354. package/dist/dashboard/api/memoryRecall.js.map +1 -0
  355. package/dist/dashboard/api/promptSend.d.ts +33 -0
  356. package/dist/dashboard/api/promptSend.d.ts.map +1 -0
  357. package/dist/dashboard/api/promptSend.js +544 -0
  358. package/dist/dashboard/api/promptSend.js.map +1 -0
  359. package/dist/dashboard/api/settings.d.ts +10 -0
  360. package/dist/dashboard/api/settings.d.ts.map +1 -0
  361. package/dist/dashboard/api/settings.js +656 -0
  362. package/dist/dashboard/api/settings.js.map +1 -0
  363. package/dist/dashboard/api/setup.d.ts +21 -0
  364. package/dist/dashboard/api/setup.d.ts.map +1 -0
  365. package/dist/dashboard/api/setup.js +663 -0
  366. package/dist/dashboard/api/setup.js.map +1 -0
  367. package/dist/dashboard/api/specmemTools.d.ts +14 -0
  368. package/dist/dashboard/api/specmemTools.d.ts.map +1 -0
  369. package/dist/dashboard/api/specmemTools.js +1059 -0
  370. package/dist/dashboard/api/specmemTools.js.map +1 -0
  371. package/dist/dashboard/api/taskTeamMembers.d.ts +8 -0
  372. package/dist/dashboard/api/taskTeamMembers.d.ts.map +1 -0
  373. package/dist/dashboard/api/taskTeamMembers.js +136 -0
  374. package/dist/dashboard/api/taskTeamMembers.js.map +1 -0
  375. package/dist/dashboard/api/teamMemberDeploy.d.ts +15 -0
  376. package/dist/dashboard/api/teamMemberDeploy.d.ts.map +1 -0
  377. package/dist/dashboard/api/teamMemberDeploy.js +421 -0
  378. package/dist/dashboard/api/teamMemberDeploy.js.map +1 -0
  379. package/dist/dashboard/api/teamMemberHistory.d.ts +38 -0
  380. package/dist/dashboard/api/teamMemberHistory.d.ts.map +1 -0
  381. package/dist/dashboard/api/teamMemberHistory.js +583 -0
  382. package/dist/dashboard/api/teamMemberHistory.js.map +1 -0
  383. package/dist/dashboard/api/terminal.d.ts +12 -0
  384. package/dist/dashboard/api/terminal.d.ts.map +1 -0
  385. package/dist/dashboard/api/terminal.js +344 -0
  386. package/dist/dashboard/api/terminal.js.map +1 -0
  387. package/dist/dashboard/api/terminalInject.d.ts +17 -0
  388. package/dist/dashboard/api/terminalInject.d.ts.map +1 -0
  389. package/dist/dashboard/api/terminalInject.js +322 -0
  390. package/dist/dashboard/api/terminalInject.js.map +1 -0
  391. package/dist/dashboard/api/terminalStream.d.ts +12 -0
  392. package/dist/dashboard/api/terminalStream.d.ts.map +1 -0
  393. package/dist/dashboard/api/terminalStream.js +482 -0
  394. package/dist/dashboard/api/terminalStream.js.map +1 -0
  395. package/dist/dashboard/index.d.ts +7 -0
  396. package/dist/dashboard/index.d.ts.map +1 -0
  397. package/dist/dashboard/index.js +7 -0
  398. package/dist/dashboard/index.js.map +1 -0
  399. package/dist/dashboard/ptyStreamer.d.ts +173 -0
  400. package/dist/dashboard/ptyStreamer.d.ts.map +1 -0
  401. package/dist/dashboard/ptyStreamer.js +661 -0
  402. package/dist/dashboard/ptyStreamer.js.map +1 -0
  403. package/dist/dashboard/public/DASHBOARD-README.md +378 -0
  404. package/dist/dashboard/public/INTEGRATION-GUIDE.md +395 -0
  405. package/dist/dashboard/public/codebase-config.html +1247 -0
  406. package/dist/dashboard/public/dashboard-v2.html +1942 -0
  407. package/dist/dashboard/public/data-export.html +819 -0
  408. package/dist/dashboard/public/example-page.html +164 -0
  409. package/dist/dashboard/public/file-explorer.html +1023 -0
  410. package/dist/dashboard/public/hooks.html +1103 -0
  411. package/dist/dashboard/public/index-improvements.css +499 -0
  412. package/dist/dashboard/public/index.html +5534 -0
  413. package/dist/dashboard/public/memory-controls.html +1959 -0
  414. package/dist/dashboard/public/memory-recall.html +1495 -0
  415. package/dist/dashboard/public/previews/skeleton-memory-graph.html +361 -0
  416. package/dist/dashboard/public/previews/skeleton-memory-list.html +366 -0
  417. package/dist/dashboard/public/previews/skeleton-search-results.html +609 -0
  418. package/dist/dashboard/public/previews/skeleton-stats-dashboard.html +556 -0
  419. package/dist/dashboard/public/prompt-console.html +2763 -0
  420. package/dist/dashboard/public/react-dist/assets/index-CkjobT5B.js +871 -0
  421. package/dist/dashboard/public/react-dist/assets/index-iRclxMst.css +1 -0
  422. package/dist/dashboard/public/react-dist/index.html +16 -0
  423. package/dist/dashboard/public/shared-header.js +325 -0
  424. package/dist/dashboard/public/shared-language-selector.js +626 -0
  425. package/dist/dashboard/public/shared-logger.js +66 -0
  426. package/dist/dashboard/public/shared-nav.js +325 -0
  427. package/dist/dashboard/public/shared-theme-blue.css +331 -0
  428. package/dist/dashboard/public/shared-theme.css +813 -0
  429. package/dist/dashboard/public/shared-toast.js +415 -0
  430. package/dist/dashboard/public/team-member-history.html +1291 -0
  431. package/dist/dashboard/public/team-member-spy.html +1199 -0
  432. package/dist/dashboard/public/team-members.html +3756 -0
  433. package/dist/dashboard/public/terminal-output.html +1013 -0
  434. package/dist/dashboard/public/terminal.html +372 -0
  435. package/dist/dashboard/sessionStore.d.ts +86 -0
  436. package/dist/dashboard/sessionStore.d.ts.map +1 -0
  437. package/dist/dashboard/sessionStore.js +262 -0
  438. package/dist/dashboard/sessionStore.js.map +1 -0
  439. package/dist/dashboard/standalone.d.ts +27 -0
  440. package/dist/dashboard/standalone.d.ts.map +1 -0
  441. package/dist/dashboard/standalone.js +380 -0
  442. package/dist/dashboard/standalone.js.map +1 -0
  443. package/dist/dashboard/webServer.d.ts +390 -0
  444. package/dist/dashboard/webServer.d.ts.map +1 -0
  445. package/dist/dashboard/webServer.js +4297 -0
  446. package/dist/dashboard/webServer.js.map +1 -0
  447. package/dist/dashboard/websocket/teamMemberStream.d.ts +87 -0
  448. package/dist/dashboard/websocket/teamMemberStream.d.ts.map +1 -0
  449. package/dist/dashboard/websocket/teamMemberStream.js +366 -0
  450. package/dist/dashboard/websocket/teamMemberStream.js.map +1 -0
  451. package/dist/dashboard/websocket/terminalStream.d.ts +130 -0
  452. package/dist/dashboard/websocket/terminalStream.d.ts.map +1 -0
  453. package/dist/dashboard/websocket/terminalStream.js +456 -0
  454. package/dist/dashboard/websocket/terminalStream.js.map +1 -0
  455. package/dist/database/embeddedPostgres.d.ts +187 -0
  456. package/dist/database/embeddedPostgres.d.ts.map +1 -0
  457. package/dist/database/embeddedPostgres.js +763 -0
  458. package/dist/database/embeddedPostgres.js.map +1 -0
  459. package/dist/database/index.d.ts +12 -0
  460. package/dist/database/index.d.ts.map +1 -0
  461. package/dist/database/index.js +20 -0
  462. package/dist/database/index.js.map +1 -0
  463. package/dist/database/initEmbeddedPostgres.d.ts +124 -0
  464. package/dist/database/initEmbeddedPostgres.d.ts.map +1 -0
  465. package/dist/database/initEmbeddedPostgres.js +855 -0
  466. package/dist/database/initEmbeddedPostgres.js.map +1 -0
  467. package/dist/database.d.ts +256 -0
  468. package/dist/database.d.ts.map +1 -0
  469. package/dist/database.js +1209 -0
  470. package/dist/database.js.map +1 -0
  471. package/dist/db/apiDataManager.d.ts +334 -0
  472. package/dist/db/apiDataManager.d.ts.map +1 -0
  473. package/dist/db/apiDataManager.js +631 -0
  474. package/dist/db/apiDataManager.js.map +1 -0
  475. package/dist/db/batchOperations.d.ts +154 -0
  476. package/dist/db/batchOperations.d.ts.map +1 -0
  477. package/dist/db/batchOperations.js +564 -0
  478. package/dist/db/batchOperations.js.map +1 -0
  479. package/dist/db/bigBrainMigrations.d.ts +48 -0
  480. package/dist/db/bigBrainMigrations.d.ts.map +1 -0
  481. package/dist/db/bigBrainMigrations.js +4266 -0
  482. package/dist/db/bigBrainMigrations.js.map +1 -0
  483. package/dist/db/connectionPoolGoBrrr.d.ts +94 -0
  484. package/dist/db/connectionPoolGoBrrr.d.ts.map +1 -0
  485. package/dist/db/connectionPoolGoBrrr.js +548 -0
  486. package/dist/db/connectionPoolGoBrrr.js.map +1 -0
  487. package/dist/db/dashboardQueries.d.ts +182 -0
  488. package/dist/db/dashboardQueries.d.ts.map +1 -0
  489. package/dist/db/dashboardQueries.js +821 -0
  490. package/dist/db/dashboardQueries.js.map +1 -0
  491. package/dist/db/deploymentBootstrap.d.ts +43 -0
  492. package/dist/db/deploymentBootstrap.d.ts.map +1 -0
  493. package/dist/db/deploymentBootstrap.js +329 -0
  494. package/dist/db/deploymentBootstrap.js.map +1 -0
  495. package/dist/db/dimensionService.d.ts +140 -0
  496. package/dist/db/dimensionService.d.ts.map +1 -0
  497. package/dist/db/dimensionService.js +261 -0
  498. package/dist/db/dimensionService.js.map +1 -0
  499. package/dist/db/embeddingOverflow.d.ts +69 -0
  500. package/dist/db/embeddingOverflow.d.ts.map +1 -0
  501. package/dist/db/embeddingOverflow.js +332 -0
  502. package/dist/db/embeddingOverflow.js.map +1 -0
  503. package/dist/db/embeddingOverflow.sql +221 -0
  504. package/dist/db/findThatShit.d.ts +145 -0
  505. package/dist/db/findThatShit.d.ts.map +1 -0
  506. package/dist/db/findThatShit.js +782 -0
  507. package/dist/db/findThatShit.js.map +1 -0
  508. package/dist/db/hotPathManager.d.ts +187 -0
  509. package/dist/db/hotPathManager.d.ts.map +1 -0
  510. package/dist/db/hotPathManager.js +504 -0
  511. package/dist/db/hotPathManager.js.map +1 -0
  512. package/dist/db/index.d.ts +85 -0
  513. package/dist/db/index.d.ts.map +1 -0
  514. package/dist/db/index.js +219 -0
  515. package/dist/db/index.js.map +1 -0
  516. package/dist/db/memoryDrilldown.sql +99 -0
  517. package/dist/db/migrate.d.ts +3 -0
  518. package/dist/db/migrate.d.ts.map +1 -0
  519. package/dist/db/migrate.js +97 -0
  520. package/dist/db/migrate.js.map +1 -0
  521. package/dist/db/migrateJsonToPostgres.d.ts +43 -0
  522. package/dist/db/migrateJsonToPostgres.d.ts.map +1 -0
  523. package/dist/db/migrateJsonToPostgres.js +465 -0
  524. package/dist/db/migrateJsonToPostgres.js.map +1 -0
  525. package/dist/db/nukeFromOrbit.d.ts +63 -0
  526. package/dist/db/nukeFromOrbit.d.ts.map +1 -0
  527. package/dist/db/nukeFromOrbit.js +499 -0
  528. package/dist/db/nukeFromOrbit.js.map +1 -0
  529. package/dist/db/processedTraining.sql +60 -0
  530. package/dist/db/projectNamespacing.d.ts +258 -0
  531. package/dist/db/projectNamespacing.d.ts.map +1 -0
  532. package/dist/db/projectNamespacing.js +920 -0
  533. package/dist/db/projectNamespacing.js.map +1 -0
  534. package/dist/db/projectNamespacing.sql +374 -0
  535. package/dist/db/projectSchemaInit.sql +271 -0
  536. package/dist/db/spatialMemory.d.ts +296 -0
  537. package/dist/db/spatialMemory.d.ts.map +1 -0
  538. package/dist/db/spatialMemory.js +818 -0
  539. package/dist/db/spatialMemory.js.map +1 -0
  540. package/dist/db/streamingQuery.d.ts +143 -0
  541. package/dist/db/streamingQuery.d.ts.map +1 -0
  542. package/dist/db/streamingQuery.js +350 -0
  543. package/dist/db/streamingQuery.js.map +1 -0
  544. package/dist/db/teamComms.sql +224 -0
  545. package/dist/db/yeetStuffInDb.d.ts +72 -0
  546. package/dist/db/yeetStuffInDb.d.ts.map +1 -0
  547. package/dist/db/yeetStuffInDb.js +473 -0
  548. package/dist/db/yeetStuffInDb.js.map +1 -0
  549. package/dist/embedding-providers/index.d.ts +10 -0
  550. package/dist/embedding-providers/index.d.ts.map +1 -0
  551. package/dist/embedding-providers/index.js +12 -0
  552. package/dist/embedding-providers/index.js.map +1 -0
  553. package/dist/embeddings/projectionLayer.d.ts +114 -0
  554. package/dist/embeddings/projectionLayer.d.ts.map +1 -0
  555. package/dist/embeddings/projectionLayer.js +345 -0
  556. package/dist/embeddings/projectionLayer.js.map +1 -0
  557. package/dist/events/Publisher.d.ts +193 -0
  558. package/dist/events/Publisher.d.ts.map +1 -0
  559. package/dist/events/Publisher.js +439 -0
  560. package/dist/events/Publisher.js.map +1 -0
  561. package/dist/events/config.d.ts +139 -0
  562. package/dist/events/config.d.ts.map +1 -0
  563. package/dist/events/config.js +266 -0
  564. package/dist/events/config.js.map +1 -0
  565. package/dist/events/index.d.ts +19 -0
  566. package/dist/events/index.d.ts.map +1 -0
  567. package/dist/events/index.js +31 -0
  568. package/dist/events/index.js.map +1 -0
  569. package/dist/events/integration.d.ts +206 -0
  570. package/dist/events/integration.d.ts.map +1 -0
  571. package/dist/events/integration.js +348 -0
  572. package/dist/events/integration.js.map +1 -0
  573. package/dist/events/metrics.d.ts +147 -0
  574. package/dist/events/metrics.d.ts.map +1 -0
  575. package/dist/events/metrics.js +343 -0
  576. package/dist/events/metrics.js.map +1 -0
  577. package/dist/hooks/cli.d.ts +28 -0
  578. package/dist/hooks/cli.d.ts.map +1 -0
  579. package/dist/hooks/cli.js +118 -0
  580. package/dist/hooks/cli.js.map +1 -0
  581. package/dist/hooks/contextInjectionHook.d.ts +60 -0
  582. package/dist/hooks/contextInjectionHook.d.ts.map +1 -0
  583. package/dist/hooks/contextInjectionHook.js +294 -0
  584. package/dist/hooks/contextInjectionHook.js.map +1 -0
  585. package/dist/hooks/drilldownHook.d.ts +125 -0
  586. package/dist/hooks/drilldownHook.d.ts.map +1 -0
  587. package/dist/hooks/drilldownHook.js +181 -0
  588. package/dist/hooks/drilldownHook.js.map +1 -0
  589. package/dist/hooks/hookManager.d.ts +180 -0
  590. package/dist/hooks/hookManager.d.ts.map +1 -0
  591. package/dist/hooks/hookManager.js +782 -0
  592. package/dist/hooks/hookManager.js.map +1 -0
  593. package/dist/hooks/index.d.ts +62 -0
  594. package/dist/hooks/index.d.ts.map +1 -0
  595. package/dist/hooks/index.js +66 -0
  596. package/dist/hooks/index.js.map +1 -0
  597. package/dist/hooks/lowContextHook.d.ts +71 -0
  598. package/dist/hooks/lowContextHook.d.ts.map +1 -0
  599. package/dist/hooks/lowContextHook.js +258 -0
  600. package/dist/hooks/lowContextHook.js.map +1 -0
  601. package/dist/hooks/simpleContextHook.d.ts +65 -0
  602. package/dist/hooks/simpleContextHook.d.ts.map +1 -0
  603. package/dist/hooks/simpleContextHook.js +194 -0
  604. package/dist/hooks/simpleContextHook.js.map +1 -0
  605. package/dist/hooks/teamFramingCli.d.ts +56 -0
  606. package/dist/hooks/teamFramingCli.d.ts.map +1 -0
  607. package/dist/hooks/teamFramingCli.js +264 -0
  608. package/dist/hooks/teamFramingCli.js.map +1 -0
  609. package/dist/hooks/teamMemberPrepromptHook.d.ts +150 -0
  610. package/dist/hooks/teamMemberPrepromptHook.d.ts.map +1 -0
  611. package/dist/hooks/teamMemberPrepromptHook.js +308 -0
  612. package/dist/hooks/teamMemberPrepromptHook.js.map +1 -0
  613. package/dist/index.d.ts +42 -0
  614. package/dist/index.d.ts.map +1 -0
  615. package/dist/index.js +4433 -0
  616. package/dist/index.js.map +1 -0
  617. package/dist/init/claudeConfigInjector.d.ts +116 -0
  618. package/dist/init/claudeConfigInjector.d.ts.map +1 -0
  619. package/dist/init/claudeConfigInjector.js +1154 -0
  620. package/dist/init/claudeConfigInjector.js.map +1 -0
  621. package/dist/installer/autoInstall.d.ts +72 -0
  622. package/dist/installer/autoInstall.d.ts.map +1 -0
  623. package/dist/installer/autoInstall.js +617 -0
  624. package/dist/installer/autoInstall.js.map +1 -0
  625. package/dist/installer/dbSetup.d.ts +84 -0
  626. package/dist/installer/dbSetup.d.ts.map +1 -0
  627. package/dist/installer/dbSetup.js +350 -0
  628. package/dist/installer/dbSetup.js.map +1 -0
  629. package/dist/installer/firstRun.d.ts +49 -0
  630. package/dist/installer/firstRun.d.ts.map +1 -0
  631. package/dist/installer/firstRun.js +207 -0
  632. package/dist/installer/firstRun.js.map +1 -0
  633. package/dist/installer/index.d.ts +10 -0
  634. package/dist/installer/index.d.ts.map +1 -0
  635. package/dist/installer/index.js +10 -0
  636. package/dist/installer/index.js.map +1 -0
  637. package/dist/installer/silentAutoInstall.d.ts +99 -0
  638. package/dist/installer/silentAutoInstall.d.ts.map +1 -0
  639. package/dist/installer/silentAutoInstall.js +491 -0
  640. package/dist/installer/silentAutoInstall.js.map +1 -0
  641. package/dist/installer/systemDeps.d.ts +54 -0
  642. package/dist/installer/systemDeps.d.ts.map +1 -0
  643. package/dist/installer/systemDeps.js +322 -0
  644. package/dist/installer/systemDeps.js.map +1 -0
  645. package/dist/mcp/cliNotifications.d.ts +133 -0
  646. package/dist/mcp/cliNotifications.d.ts.map +1 -0
  647. package/dist/mcp/cliNotifications.js +289 -0
  648. package/dist/mcp/cliNotifications.js.map +1 -0
  649. package/dist/mcp/embeddingServerManager.d.ts +307 -0
  650. package/dist/mcp/embeddingServerManager.d.ts.map +1 -0
  651. package/dist/mcp/embeddingServerManager.js +2081 -0
  652. package/dist/mcp/embeddingServerManager.js.map +1 -0
  653. package/dist/mcp/healthMonitor.d.ts +196 -0
  654. package/dist/mcp/healthMonitor.d.ts.map +1 -0
  655. package/dist/mcp/healthMonitor.js +685 -0
  656. package/dist/mcp/healthMonitor.js.map +1 -0
  657. package/dist/mcp/hotReloadManager.d.ts +101 -0
  658. package/dist/mcp/hotReloadManager.d.ts.map +1 -0
  659. package/dist/mcp/hotReloadManager.js +251 -0
  660. package/dist/mcp/hotReloadManager.js.map +1 -0
  661. package/dist/mcp/index.d.ts +16 -0
  662. package/dist/mcp/index.d.ts.map +1 -0
  663. package/dist/mcp/index.js +22 -0
  664. package/dist/mcp/index.js.map +1 -0
  665. package/dist/mcp/mcpProtocolHandler.d.ts +64 -0
  666. package/dist/mcp/mcpProtocolHandler.d.ts.map +1 -0
  667. package/dist/mcp/mcpProtocolHandler.js +253 -0
  668. package/dist/mcp/mcpProtocolHandler.js.map +1 -0
  669. package/dist/mcp/miniCOTServerManager.d.ts +336 -0
  670. package/dist/mcp/miniCOTServerManager.d.ts.map +1 -0
  671. package/dist/mcp/miniCOTServerManager.js +1384 -0
  672. package/dist/mcp/miniCOTServerManager.js.map +1 -0
  673. package/dist/mcp/promptExecutor.d.ts +188 -0
  674. package/dist/mcp/promptExecutor.d.ts.map +1 -0
  675. package/dist/mcp/promptExecutor.js +469 -0
  676. package/dist/mcp/promptExecutor.js.map +1 -0
  677. package/dist/mcp/reloadBroadcast.d.ts +127 -0
  678. package/dist/mcp/reloadBroadcast.d.ts.map +1 -0
  679. package/dist/mcp/reloadBroadcast.js +275 -0
  680. package/dist/mcp/reloadBroadcast.js.map +1 -0
  681. package/dist/mcp/resilientTransport.d.ts +249 -0
  682. package/dist/mcp/resilientTransport.d.ts.map +1 -0
  683. package/dist/mcp/resilientTransport.js +931 -0
  684. package/dist/mcp/resilientTransport.js.map +1 -0
  685. package/dist/mcp/samplingHandler.d.ts +129 -0
  686. package/dist/mcp/samplingHandler.d.ts.map +1 -0
  687. package/dist/mcp/samplingHandler.js +276 -0
  688. package/dist/mcp/samplingHandler.js.map +1 -0
  689. package/dist/mcp/specMemServer.d.ts +305 -0
  690. package/dist/mcp/specMemServer.d.ts.map +1 -0
  691. package/dist/mcp/specMemServer.js +2048 -0
  692. package/dist/mcp/specMemServer.js.map +1 -0
  693. package/dist/mcp/toolRegistry.d.ts +122 -0
  694. package/dist/mcp/toolRegistry.d.ts.map +1 -0
  695. package/dist/mcp/toolRegistry.js +609 -0
  696. package/dist/mcp/toolRegistry.js.map +1 -0
  697. package/dist/mcp/tools/embeddingControl.d.ts +114 -0
  698. package/dist/mcp/tools/embeddingControl.d.ts.map +1 -0
  699. package/dist/mcp/tools/embeddingControl.js +222 -0
  700. package/dist/mcp/tools/embeddingControl.js.map +1 -0
  701. package/dist/mcp/tools/index.d.ts +10 -0
  702. package/dist/mcp/tools/index.d.ts.map +1 -0
  703. package/dist/mcp/tools/index.js +17 -0
  704. package/dist/mcp/tools/index.js.map +1 -0
  705. package/dist/mcp/tools/teamComms.d.ts +444 -0
  706. package/dist/mcp/tools/teamComms.d.ts.map +1 -0
  707. package/dist/mcp/tools/teamComms.js +1953 -0
  708. package/dist/mcp/tools/teamComms.js.map +1 -0
  709. package/dist/mcp/triggerSystem.d.ts +129 -0
  710. package/dist/mcp/triggerSystem.d.ts.map +1 -0
  711. package/dist/mcp/triggerSystem.js +363 -0
  712. package/dist/mcp/triggerSystem.js.map +1 -0
  713. package/dist/mcp/watcherIntegration.d.ts +77 -0
  714. package/dist/mcp/watcherIntegration.d.ts.map +1 -0
  715. package/dist/mcp/watcherIntegration.js +428 -0
  716. package/dist/mcp/watcherIntegration.js.map +1 -0
  717. package/dist/mcp/watcherToolWrappers.d.ts +89 -0
  718. package/dist/mcp/watcherToolWrappers.d.ts.map +1 -0
  719. package/dist/mcp/watcherToolWrappers.js +91 -0
  720. package/dist/mcp/watcherToolWrappers.js.map +1 -0
  721. package/dist/memorization/claudeCodeMigration.d.ts +34 -0
  722. package/dist/memorization/claudeCodeMigration.d.ts.map +1 -0
  723. package/dist/memorization/claudeCodeMigration.js +210 -0
  724. package/dist/memorization/claudeCodeMigration.js.map +1 -0
  725. package/dist/memorization/claudeCodeTracker.d.ts +147 -0
  726. package/dist/memorization/claudeCodeTracker.d.ts.map +1 -0
  727. package/dist/memorization/claudeCodeTracker.js +424 -0
  728. package/dist/memorization/claudeCodeTracker.js.map +1 -0
  729. package/dist/memorization/codeMemorizer.d.ts +158 -0
  730. package/dist/memorization/codeMemorizer.d.ts.map +1 -0
  731. package/dist/memorization/codeMemorizer.js +357 -0
  732. package/dist/memorization/codeMemorizer.js.map +1 -0
  733. package/dist/memorization/codeRecall.d.ts +156 -0
  734. package/dist/memorization/codeRecall.d.ts.map +1 -0
  735. package/dist/memorization/codeRecall.js +499 -0
  736. package/dist/memorization/codeRecall.js.map +1 -0
  737. package/dist/memorization/index.d.ts +55 -0
  738. package/dist/memorization/index.d.ts.map +1 -0
  739. package/dist/memorization/index.js +64 -0
  740. package/dist/memorization/index.js.map +1 -0
  741. package/dist/memorization/memorizationTools.d.ts +413 -0
  742. package/dist/memorization/memorizationTools.d.ts.map +1 -0
  743. package/dist/memorization/memorizationTools.js +513 -0
  744. package/dist/memorization/memorizationTools.js.map +1 -0
  745. package/dist/memorization/watcherIntegration.d.ts +100 -0
  746. package/dist/memorization/watcherIntegration.d.ts.map +1 -0
  747. package/dist/memorization/watcherIntegration.js +196 -0
  748. package/dist/memorization/watcherIntegration.js.map +1 -0
  749. package/dist/memory/humanLikeMemory.d.ts +206 -0
  750. package/dist/memory/humanLikeMemory.d.ts.map +1 -0
  751. package/dist/memory/humanLikeMemory.js +603 -0
  752. package/dist/memory/humanLikeMemory.js.map +1 -0
  753. package/dist/memory/index.d.ts +22 -0
  754. package/dist/memory/index.d.ts.map +1 -0
  755. package/dist/memory/index.js +24 -0
  756. package/dist/memory/index.js.map +1 -0
  757. package/dist/memory/memoryEvolutionMigration.d.ts +36 -0
  758. package/dist/memory/memoryEvolutionMigration.d.ts.map +1 -0
  759. package/dist/memory/memoryEvolutionMigration.js +371 -0
  760. package/dist/memory/memoryEvolutionMigration.js.map +1 -0
  761. package/dist/memory/quadrantSearch.d.ts +221 -0
  762. package/dist/memory/quadrantSearch.d.ts.map +1 -0
  763. package/dist/memory/quadrantSearch.js +897 -0
  764. package/dist/memory/quadrantSearch.js.map +1 -0
  765. package/dist/middleware/apiVersioning.d.ts +83 -0
  766. package/dist/middleware/apiVersioning.d.ts.map +1 -0
  767. package/dist/middleware/apiVersioning.js +152 -0
  768. package/dist/middleware/apiVersioning.js.map +1 -0
  769. package/dist/middleware/compression.d.ts +48 -0
  770. package/dist/middleware/compression.d.ts.map +1 -0
  771. package/dist/middleware/compression.js +240 -0
  772. package/dist/middleware/compression.js.map +1 -0
  773. package/dist/middleware/csrf.d.ts +118 -0
  774. package/dist/middleware/csrf.d.ts.map +1 -0
  775. package/dist/middleware/csrf.js +300 -0
  776. package/dist/middleware/csrf.js.map +1 -0
  777. package/dist/middleware/index.d.ts +13 -0
  778. package/dist/middleware/index.d.ts.map +1 -0
  779. package/dist/middleware/index.js +17 -0
  780. package/dist/middleware/index.js.map +1 -0
  781. package/dist/middleware/wsRateLimiter.d.ts +129 -0
  782. package/dist/middleware/wsRateLimiter.d.ts.map +1 -0
  783. package/dist/middleware/wsRateLimiter.js +279 -0
  784. package/dist/middleware/wsRateLimiter.js.map +1 -0
  785. package/dist/migrations/run.d.ts +2 -0
  786. package/dist/migrations/run.d.ts.map +1 -0
  787. package/dist/migrations/run.js +25 -0
  788. package/dist/migrations/run.js.map +1 -0
  789. package/dist/migrations/syncDimensions.d.ts +24 -0
  790. package/dist/migrations/syncDimensions.d.ts.map +1 -0
  791. package/dist/migrations/syncDimensions.js +140 -0
  792. package/dist/migrations/syncDimensions.js.map +1 -0
  793. package/dist/migrations/teamComms.d.ts +16 -0
  794. package/dist/migrations/teamComms.d.ts.map +1 -0
  795. package/dist/migrations/teamComms.js +210 -0
  796. package/dist/migrations/teamComms.js.map +1 -0
  797. package/dist/openapi/index.d.ts +10 -0
  798. package/dist/openapi/index.d.ts.map +1 -0
  799. package/dist/openapi/index.js +10 -0
  800. package/dist/openapi/index.js.map +1 -0
  801. package/dist/openapi/spec.d.ts +902 -0
  802. package/dist/openapi/spec.d.ts.map +1 -0
  803. package/dist/openapi/spec.js +733 -0
  804. package/dist/openapi/spec.js.map +1 -0
  805. package/dist/packages/dependencyHistory.d.ts +113 -0
  806. package/dist/packages/dependencyHistory.d.ts.map +1 -0
  807. package/dist/packages/dependencyHistory.js +360 -0
  808. package/dist/packages/dependencyHistory.js.map +1 -0
  809. package/dist/packages/index.d.ts +30 -0
  810. package/dist/packages/index.d.ts.map +1 -0
  811. package/dist/packages/index.js +65 -0
  812. package/dist/packages/index.js.map +1 -0
  813. package/dist/packages/packageTools.d.ts +255 -0
  814. package/dist/packages/packageTools.d.ts.map +1 -0
  815. package/dist/packages/packageTools.js +242 -0
  816. package/dist/packages/packageTools.js.map +1 -0
  817. package/dist/packages/packageTracker.d.ts +98 -0
  818. package/dist/packages/packageTracker.d.ts.map +1 -0
  819. package/dist/packages/packageTracker.js +268 -0
  820. package/dist/packages/packageTracker.js.map +1 -0
  821. package/dist/packages/packageWatcher.d.ts +62 -0
  822. package/dist/packages/packageWatcher.d.ts.map +1 -0
  823. package/dist/packages/packageWatcher.js +146 -0
  824. package/dist/packages/packageWatcher.js.map +1 -0
  825. package/dist/providers/MiniCOTProvider.d.ts +48 -0
  826. package/dist/providers/MiniCOTProvider.d.ts.map +1 -0
  827. package/dist/providers/MiniCOTProvider.js +98 -0
  828. package/dist/providers/MiniCOTProvider.js.map +1 -0
  829. package/dist/reminders/index.d.ts +5 -0
  830. package/dist/reminders/index.d.ts.map +1 -0
  831. package/dist/reminders/index.js +5 -0
  832. package/dist/reminders/index.js.map +1 -0
  833. package/dist/reminders/skillReminder.d.ts +131 -0
  834. package/dist/reminders/skillReminder.d.ts.map +1 -0
  835. package/dist/reminders/skillReminder.js +386 -0
  836. package/dist/reminders/skillReminder.js.map +1 -0
  837. package/dist/search.d.ts +35 -0
  838. package/dist/search.d.ts.map +1 -0
  839. package/dist/search.js +574 -0
  840. package/dist/search.js.map +1 -0
  841. package/dist/security/localhostOnly.d.ts +36 -0
  842. package/dist/security/localhostOnly.d.ts.map +1 -0
  843. package/dist/security/localhostOnly.js +101 -0
  844. package/dist/security/localhostOnly.js.map +1 -0
  845. package/dist/services/CameraZoomSearch.d.ts +206 -0
  846. package/dist/services/CameraZoomSearch.d.ts.map +1 -0
  847. package/dist/services/CameraZoomSearch.js +669 -0
  848. package/dist/services/CameraZoomSearch.js.map +1 -0
  849. package/dist/services/DataFlowPipeline.d.ts +111 -0
  850. package/dist/services/DataFlowPipeline.d.ts.map +1 -0
  851. package/dist/services/DataFlowPipeline.js +379 -0
  852. package/dist/services/DataFlowPipeline.js.map +1 -0
  853. package/dist/services/DimensionAdapter.d.ts +194 -0
  854. package/dist/services/DimensionAdapter.d.ts.map +1 -0
  855. package/dist/services/DimensionAdapter.js +566 -0
  856. package/dist/services/DimensionAdapter.js.map +1 -0
  857. package/dist/services/DimensionService.d.ts +252 -0
  858. package/dist/services/DimensionService.d.ts.map +1 -0
  859. package/dist/services/DimensionService.js +564 -0
  860. package/dist/services/DimensionService.js.map +1 -0
  861. package/dist/services/EmbeddingQueue.d.ts +71 -0
  862. package/dist/services/EmbeddingQueue.d.ts.map +1 -0
  863. package/dist/services/EmbeddingQueue.js +258 -0
  864. package/dist/services/EmbeddingQueue.js.map +1 -0
  865. package/dist/services/MemoryDrilldown.d.ts +226 -0
  866. package/dist/services/MemoryDrilldown.d.ts.map +1 -0
  867. package/dist/services/MemoryDrilldown.js +479 -0
  868. package/dist/services/MemoryDrilldown.js.map +1 -0
  869. package/dist/services/MiniCOTScorer.d.ts +140 -0
  870. package/dist/services/MiniCOTScorer.d.ts.map +1 -0
  871. package/dist/services/MiniCOTScorer.js +292 -0
  872. package/dist/services/MiniCOTScorer.js.map +1 -0
  873. package/dist/services/ProjectContext.d.ts +342 -0
  874. package/dist/services/ProjectContext.d.ts.map +1 -0
  875. package/dist/services/ProjectContext.js +667 -0
  876. package/dist/services/ProjectContext.js.map +1 -0
  877. package/dist/services/ResponseCompactor.d.ts +135 -0
  878. package/dist/services/ResponseCompactor.d.ts.map +1 -0
  879. package/dist/services/ResponseCompactor.js +501 -0
  880. package/dist/services/ResponseCompactor.js.map +1 -0
  881. package/dist/services/TeamCommsDbService.d.ts +202 -0
  882. package/dist/services/TeamCommsDbService.d.ts.map +1 -0
  883. package/dist/services/TeamCommsDbService.js +526 -0
  884. package/dist/services/TeamCommsDbService.js.map +1 -0
  885. package/dist/services/UnifiedPasswordService.d.ts +166 -0
  886. package/dist/services/UnifiedPasswordService.d.ts.map +1 -0
  887. package/dist/services/UnifiedPasswordService.js +587 -0
  888. package/dist/services/UnifiedPasswordService.js.map +1 -0
  889. package/dist/services/adaptiveSearchConfig.d.ts +64 -0
  890. package/dist/services/adaptiveSearchConfig.d.ts.map +1 -0
  891. package/dist/services/adaptiveSearchConfig.js +187 -0
  892. package/dist/services/adaptiveSearchConfig.js.map +1 -0
  893. package/dist/skills/index.d.ts +8 -0
  894. package/dist/skills/index.d.ts.map +1 -0
  895. package/dist/skills/index.js +8 -0
  896. package/dist/skills/index.js.map +1 -0
  897. package/dist/skills/skillScanner.d.ts +203 -0
  898. package/dist/skills/skillScanner.d.ts.map +1 -0
  899. package/dist/skills/skillScanner.js +559 -0
  900. package/dist/skills/skillScanner.js.map +1 -0
  901. package/dist/skills/skillsResource.d.ts +69 -0
  902. package/dist/skills/skillsResource.d.ts.map +1 -0
  903. package/dist/skills/skillsResource.js +257 -0
  904. package/dist/skills/skillsResource.js.map +1 -0
  905. package/dist/startup/index.d.ts +9 -0
  906. package/dist/startup/index.d.ts.map +1 -0
  907. package/dist/startup/index.js +12 -0
  908. package/dist/startup/index.js.map +1 -0
  909. package/dist/startup/startupIndexing.d.ts +80 -0
  910. package/dist/startup/startupIndexing.d.ts.map +1 -0
  911. package/dist/startup/startupIndexing.js +463 -0
  912. package/dist/startup/startupIndexing.js.map +1 -0
  913. package/dist/startup/validation.d.ts +89 -0
  914. package/dist/startup/validation.d.ts.map +1 -0
  915. package/dist/startup/validation.js +590 -0
  916. package/dist/startup/validation.js.map +1 -0
  917. package/dist/storage/index.d.ts +4 -0
  918. package/dist/storage/index.d.ts.map +1 -0
  919. package/dist/storage/index.js +4 -0
  920. package/dist/storage/index.js.map +1 -0
  921. package/dist/storage/overflowManager.d.ts +80 -0
  922. package/dist/storage/overflowManager.d.ts.map +1 -0
  923. package/dist/storage/overflowManager.js +317 -0
  924. package/dist/storage/overflowManager.js.map +1 -0
  925. package/dist/storage/overflowStorage.d.ts +69 -0
  926. package/dist/storage/overflowStorage.d.ts.map +1 -0
  927. package/dist/storage/overflowStorage.js +379 -0
  928. package/dist/storage/overflowStorage.js.map +1 -0
  929. package/dist/storage/toonFormat.d.ts +50 -0
  930. package/dist/storage/toonFormat.d.ts.map +1 -0
  931. package/dist/storage/toonFormat.js +224 -0
  932. package/dist/storage/toonFormat.js.map +1 -0
  933. package/dist/team-members/communication.d.ts +237 -0
  934. package/dist/team-members/communication.d.ts.map +1 -0
  935. package/dist/team-members/communication.js +650 -0
  936. package/dist/team-members/communication.js.map +1 -0
  937. package/dist/team-members/index.d.ts +14 -0
  938. package/dist/team-members/index.d.ts.map +1 -0
  939. package/dist/team-members/index.js +22 -0
  940. package/dist/team-members/index.js.map +1 -0
  941. package/dist/team-members/taskOrchestrator.d.ts +224 -0
  942. package/dist/team-members/taskOrchestrator.d.ts.map +1 -0
  943. package/dist/team-members/taskOrchestrator.js +574 -0
  944. package/dist/team-members/taskOrchestrator.js.map +1 -0
  945. package/dist/team-members/taskTeamMemberLogger.d.ts +157 -0
  946. package/dist/team-members/taskTeamMemberLogger.d.ts.map +1 -0
  947. package/dist/team-members/taskTeamMemberLogger.js +478 -0
  948. package/dist/team-members/taskTeamMemberLogger.js.map +1 -0
  949. package/dist/team-members/teamCommsService.d.ts +221 -0
  950. package/dist/team-members/teamCommsService.d.ts.map +1 -0
  951. package/dist/team-members/teamCommsService.js +628 -0
  952. package/dist/team-members/teamCommsService.js.map +1 -0
  953. package/dist/team-members/teamMemberChannels.d.ts +217 -0
  954. package/dist/team-members/teamMemberChannels.d.ts.map +1 -0
  955. package/dist/team-members/teamMemberChannels.js +687 -0
  956. package/dist/team-members/teamMemberChannels.js.map +1 -0
  957. package/dist/team-members/teamMemberDashboard.d.ts +222 -0
  958. package/dist/team-members/teamMemberDashboard.d.ts.map +1 -0
  959. package/dist/team-members/teamMemberDashboard.js +610 -0
  960. package/dist/team-members/teamMemberDashboard.js.map +1 -0
  961. package/dist/team-members/teamMemberDeployment.d.ts +60 -0
  962. package/dist/team-members/teamMemberDeployment.d.ts.map +1 -0
  963. package/dist/team-members/teamMemberDeployment.js +429 -0
  964. package/dist/team-members/teamMemberDeployment.js.map +1 -0
  965. package/dist/team-members/teamMemberDiscovery.d.ts +178 -0
  966. package/dist/team-members/teamMemberDiscovery.d.ts.map +1 -0
  967. package/dist/team-members/teamMemberDiscovery.js +446 -0
  968. package/dist/team-members/teamMemberDiscovery.js.map +1 -0
  969. package/dist/team-members/teamMemberHistory.d.ts +80 -0
  970. package/dist/team-members/teamMemberHistory.d.ts.map +1 -0
  971. package/dist/team-members/teamMemberHistory.js +426 -0
  972. package/dist/team-members/teamMemberHistory.js.map +1 -0
  973. package/dist/team-members/teamMemberLimits.d.ts +66 -0
  974. package/dist/team-members/teamMemberLimits.d.ts.map +1 -0
  975. package/dist/team-members/teamMemberLimits.js +259 -0
  976. package/dist/team-members/teamMemberLimits.js.map +1 -0
  977. package/dist/team-members/teamMemberRegistry.d.ts +199 -0
  978. package/dist/team-members/teamMemberRegistry.d.ts.map +1 -0
  979. package/dist/team-members/teamMemberRegistry.js +572 -0
  980. package/dist/team-members/teamMemberRegistry.js.map +1 -0
  981. package/dist/team-members/teamMemberTracker.d.ts +148 -0
  982. package/dist/team-members/teamMemberTracker.d.ts.map +1 -0
  983. package/dist/team-members/teamMemberTracker.js +828 -0
  984. package/dist/team-members/teamMemberTracker.js.map +1 -0
  985. package/dist/team-members/workers/aiWorker.d.ts +53 -0
  986. package/dist/team-members/workers/aiWorker.d.ts.map +1 -0
  987. package/dist/team-members/workers/aiWorker.js +322 -0
  988. package/dist/team-members/workers/aiWorker.js.map +1 -0
  989. package/dist/team-members/workers/baseWorker.d.ts +101 -0
  990. package/dist/team-members/workers/baseWorker.d.ts.map +1 -0
  991. package/dist/team-members/workers/baseWorker.js +179 -0
  992. package/dist/team-members/workers/baseWorker.js.map +1 -0
  993. package/dist/team-members/workers/codeReviewWorker.d.ts +3 -0
  994. package/dist/team-members/workers/codeReviewWorker.d.ts.map +1 -0
  995. package/dist/team-members/workers/codeReviewWorker.js +144 -0
  996. package/dist/team-members/workers/codeReviewWorker.js.map +1 -0
  997. package/dist/team-members/workers/index.d.ts +7 -0
  998. package/dist/team-members/workers/index.d.ts.map +1 -0
  999. package/dist/team-members/workers/index.js +7 -0
  1000. package/dist/team-members/workers/index.js.map +1 -0
  1001. package/dist/team-members/workers/repairWorker.d.ts +9 -0
  1002. package/dist/team-members/workers/repairWorker.d.ts.map +1 -0
  1003. package/dist/team-members/workers/repairWorker.js +102 -0
  1004. package/dist/team-members/workers/repairWorker.js.map +1 -0
  1005. package/dist/team-members/workers/sendToTeamMemberB.d.ts +9 -0
  1006. package/dist/team-members/workers/sendToTeamMemberB.d.ts.map +1 -0
  1007. package/dist/team-members/workers/sendToTeamMemberB.js +105 -0
  1008. package/dist/team-members/workers/sendToTeamMemberB.js.map +1 -0
  1009. package/dist/team-members/workers/specmemClient.d.ts +179 -0
  1010. package/dist/team-members/workers/specmemClient.d.ts.map +1 -0
  1011. package/dist/team-members/workers/specmemClient.js +421 -0
  1012. package/dist/team-members/workers/specmemClient.js.map +1 -0
  1013. package/dist/team-members/workers/testCommunication.d.ts +8 -0
  1014. package/dist/team-members/workers/testCommunication.d.ts.map +1 -0
  1015. package/dist/team-members/workers/testCommunication.js +136 -0
  1016. package/dist/team-members/workers/testCommunication.js.map +1 -0
  1017. package/dist/team-members/workers/testCommunicationSuite.d.ts +26 -0
  1018. package/dist/team-members/workers/testCommunicationSuite.d.ts.map +1 -0
  1019. package/dist/team-members/workers/testCommunicationSuite.js +415 -0
  1020. package/dist/team-members/workers/testCommunicationSuite.js.map +1 -0
  1021. package/dist/team-members/workers/testWorker.d.ts +9 -0
  1022. package/dist/team-members/workers/testWorker.d.ts.map +1 -0
  1023. package/dist/team-members/workers/testWorker.js +107 -0
  1024. package/dist/team-members/workers/testWorker.js.map +1 -0
  1025. package/dist/tools/agentDefinitions.d.ts +30 -0
  1026. package/dist/tools/agentDefinitions.d.ts.map +1 -0
  1027. package/dist/tools/agentDefinitions.js +166 -0
  1028. package/dist/tools/agentDefinitions.js.map +1 -0
  1029. package/dist/tools/goofy/checkSyncStatus.d.ts +68 -0
  1030. package/dist/tools/goofy/checkSyncStatus.d.ts.map +1 -0
  1031. package/dist/tools/goofy/checkSyncStatus.js +112 -0
  1032. package/dist/tools/goofy/checkSyncStatus.js.map +1 -0
  1033. package/dist/tools/goofy/codeMemoryLink.d.ts +82 -0
  1034. package/dist/tools/goofy/codeMemoryLink.d.ts.map +1 -0
  1035. package/dist/tools/goofy/codeMemoryLink.js +212 -0
  1036. package/dist/tools/goofy/codeMemoryLink.js.map +1 -0
  1037. package/dist/tools/goofy/compareInstanceMemory.d.ts +97 -0
  1038. package/dist/tools/goofy/compareInstanceMemory.d.ts.map +1 -0
  1039. package/dist/tools/goofy/compareInstanceMemory.js +218 -0
  1040. package/dist/tools/goofy/compareInstanceMemory.js.map +1 -0
  1041. package/dist/tools/goofy/createReasoningChain.d.ts +135 -0
  1042. package/dist/tools/goofy/createReasoningChain.d.ts.map +1 -0
  1043. package/dist/tools/goofy/createReasoningChain.js +257 -0
  1044. package/dist/tools/goofy/createReasoningChain.js.map +1 -0
  1045. package/dist/tools/goofy/deployTeamMember.d.ts +63 -0
  1046. package/dist/tools/goofy/deployTeamMember.d.ts.map +1 -0
  1047. package/dist/tools/goofy/deployTeamMember.js +103 -0
  1048. package/dist/tools/goofy/deployTeamMember.js.map +1 -0
  1049. package/dist/tools/goofy/drillDown.d.ts +143 -0
  1050. package/dist/tools/goofy/drillDown.d.ts.map +1 -0
  1051. package/dist/tools/goofy/drillDown.js +288 -0
  1052. package/dist/tools/goofy/drillDown.js.map +1 -0
  1053. package/dist/tools/goofy/extractClaudeSessions.d.ts +90 -0
  1054. package/dist/tools/goofy/extractClaudeSessions.d.ts.map +1 -0
  1055. package/dist/tools/goofy/extractClaudeSessions.js +277 -0
  1056. package/dist/tools/goofy/extractClaudeSessions.js.map +1 -0
  1057. package/dist/tools/goofy/extractContextRestorations.d.ts +70 -0
  1058. package/dist/tools/goofy/extractContextRestorations.d.ts.map +1 -0
  1059. package/dist/tools/goofy/extractContextRestorations.js +100 -0
  1060. package/dist/tools/goofy/extractContextRestorations.js.map +1 -0
  1061. package/dist/tools/goofy/findCodePointers.d.ts +364 -0
  1062. package/dist/tools/goofy/findCodePointers.d.ts.map +1 -0
  1063. package/dist/tools/goofy/findCodePointers.js +1764 -0
  1064. package/dist/tools/goofy/findCodePointers.js.map +1 -0
  1065. package/dist/tools/goofy/findMemoryGallery.d.ts +40 -0
  1066. package/dist/tools/goofy/findMemoryGallery.d.ts.map +1 -0
  1067. package/dist/tools/goofy/findMemoryGallery.js +66 -0
  1068. package/dist/tools/goofy/findMemoryGallery.js.map +1 -0
  1069. package/dist/tools/goofy/findWhatISaid.d.ts +300 -0
  1070. package/dist/tools/goofy/findWhatISaid.d.ts.map +1 -0
  1071. package/dist/tools/goofy/findWhatISaid.js +2547 -0
  1072. package/dist/tools/goofy/findWhatISaid.js.map +1 -0
  1073. package/dist/tools/goofy/forceResync.d.ts +57 -0
  1074. package/dist/tools/goofy/forceResync.d.ts.map +1 -0
  1075. package/dist/tools/goofy/forceResync.js +100 -0
  1076. package/dist/tools/goofy/forceResync.js.map +1 -0
  1077. package/dist/tools/goofy/getActiveTeamMembers.d.ts +48 -0
  1078. package/dist/tools/goofy/getActiveTeamMembers.d.ts.map +1 -0
  1079. package/dist/tools/goofy/getActiveTeamMembers.js +136 -0
  1080. package/dist/tools/goofy/getActiveTeamMembers.js.map +1 -0
  1081. package/dist/tools/goofy/getMemoryFull.d.ts +34 -0
  1082. package/dist/tools/goofy/getMemoryFull.d.ts.map +1 -0
  1083. package/dist/tools/goofy/getMemoryFull.js +58 -0
  1084. package/dist/tools/goofy/getMemoryFull.js.map +1 -0
  1085. package/dist/tools/goofy/getSessionWatcherStatus.d.ts +43 -0
  1086. package/dist/tools/goofy/getSessionWatcherStatus.d.ts.map +1 -0
  1087. package/dist/tools/goofy/getSessionWatcherStatus.js +92 -0
  1088. package/dist/tools/goofy/getSessionWatcherStatus.js.map +1 -0
  1089. package/dist/tools/goofy/getTeamMemberOutput.d.ts +35 -0
  1090. package/dist/tools/goofy/getTeamMemberOutput.d.ts.map +1 -0
  1091. package/dist/tools/goofy/getTeamMemberOutput.js +62 -0
  1092. package/dist/tools/goofy/getTeamMemberOutput.js.map +1 -0
  1093. package/dist/tools/goofy/getTeamMemberScreen.d.ts +28 -0
  1094. package/dist/tools/goofy/getTeamMemberScreen.d.ts.map +1 -0
  1095. package/dist/tools/goofy/getTeamMemberScreen.js +59 -0
  1096. package/dist/tools/goofy/getTeamMemberScreen.js.map +1 -0
  1097. package/dist/tools/goofy/getTeamMemberStatus.d.ts +33 -0
  1098. package/dist/tools/goofy/getTeamMemberStatus.d.ts.map +1 -0
  1099. package/dist/tools/goofy/getTeamMemberStatus.js +56 -0
  1100. package/dist/tools/goofy/getTeamMemberStatus.js.map +1 -0
  1101. package/dist/tools/goofy/index.d.ts +39 -0
  1102. package/dist/tools/goofy/index.d.ts.map +1 -0
  1103. package/dist/tools/goofy/index.js +51 -0
  1104. package/dist/tools/goofy/index.js.map +1 -0
  1105. package/dist/tools/goofy/interveneTeamMember.d.ts +33 -0
  1106. package/dist/tools/goofy/interveneTeamMember.d.ts.map +1 -0
  1107. package/dist/tools/goofy/interveneTeamMember.js +69 -0
  1108. package/dist/tools/goofy/interveneTeamMember.js.map +1 -0
  1109. package/dist/tools/goofy/killDeployedTeamMember.d.ts +29 -0
  1110. package/dist/tools/goofy/killDeployedTeamMember.d.ts.map +1 -0
  1111. package/dist/tools/goofy/killDeployedTeamMember.js +56 -0
  1112. package/dist/tools/goofy/killDeployedTeamMember.js.map +1 -0
  1113. package/dist/tools/goofy/linkTheVibes.d.ts +125 -0
  1114. package/dist/tools/goofy/linkTheVibes.d.ts.map +1 -0
  1115. package/dist/tools/goofy/linkTheVibes.js +354 -0
  1116. package/dist/tools/goofy/linkTheVibes.js.map +1 -0
  1117. package/dist/tools/goofy/listDeployedTeamMembers.d.ts +26 -0
  1118. package/dist/tools/goofy/listDeployedTeamMembers.d.ts.map +1 -0
  1119. package/dist/tools/goofy/listDeployedTeamMembers.js +52 -0
  1120. package/dist/tools/goofy/listDeployedTeamMembers.js.map +1 -0
  1121. package/dist/tools/goofy/listenForMessages.d.ts +56 -0
  1122. package/dist/tools/goofy/listenForMessages.d.ts.map +1 -0
  1123. package/dist/tools/goofy/listenForMessages.js +122 -0
  1124. package/dist/tools/goofy/listenForMessages.js.map +1 -0
  1125. package/dist/tools/goofy/memoryHealthCheck.d.ts +159 -0
  1126. package/dist/tools/goofy/memoryHealthCheck.d.ts.map +1 -0
  1127. package/dist/tools/goofy/memoryHealthCheck.js +443 -0
  1128. package/dist/tools/goofy/memoryHealthCheck.js.map +1 -0
  1129. package/dist/tools/goofy/rememberThisShit.d.ts +103 -0
  1130. package/dist/tools/goofy/rememberThisShit.d.ts.map +1 -0
  1131. package/dist/tools/goofy/rememberThisShit.js +291 -0
  1132. package/dist/tools/goofy/rememberThisShit.js.map +1 -0
  1133. package/dist/tools/goofy/sayToTeamMember.d.ts +55 -0
  1134. package/dist/tools/goofy/sayToTeamMember.d.ts.map +1 -0
  1135. package/dist/tools/goofy/sayToTeamMember.js +116 -0
  1136. package/dist/tools/goofy/sayToTeamMember.js.map +1 -0
  1137. package/dist/tools/goofy/selfMessage.d.ts +54 -0
  1138. package/dist/tools/goofy/selfMessage.d.ts.map +1 -0
  1139. package/dist/tools/goofy/selfMessage.js +111 -0
  1140. package/dist/tools/goofy/selfMessage.js.map +1 -0
  1141. package/dist/tools/goofy/sendHeartbeat.d.ts +53 -0
  1142. package/dist/tools/goofy/sendHeartbeat.d.ts.map +1 -0
  1143. package/dist/tools/goofy/sendHeartbeat.js +119 -0
  1144. package/dist/tools/goofy/sendHeartbeat.js.map +1 -0
  1145. package/dist/tools/goofy/showMeTheStats.d.ts +216 -0
  1146. package/dist/tools/goofy/showMeTheStats.d.ts.map +1 -0
  1147. package/dist/tools/goofy/showMeTheStats.js +535 -0
  1148. package/dist/tools/goofy/showMeTheStats.js.map +1 -0
  1149. package/dist/tools/goofy/smartRecall.d.ts +136 -0
  1150. package/dist/tools/goofy/smartRecall.d.ts.map +1 -0
  1151. package/dist/tools/goofy/smartRecall.js +286 -0
  1152. package/dist/tools/goofy/smartRecall.js.map +1 -0
  1153. package/dist/tools/goofy/smartSearch.d.ts +64 -0
  1154. package/dist/tools/goofy/smartSearch.d.ts.map +1 -0
  1155. package/dist/tools/goofy/smartSearch.js +89 -0
  1156. package/dist/tools/goofy/smartSearch.js.map +1 -0
  1157. package/dist/tools/goofy/smushMemoriesTogether.d.ts +128 -0
  1158. package/dist/tools/goofy/smushMemoriesTogether.d.ts.map +1 -0
  1159. package/dist/tools/goofy/smushMemoriesTogether.js +536 -0
  1160. package/dist/tools/goofy/smushMemoriesTogether.js.map +1 -0
  1161. package/dist/tools/goofy/spatialSearch.d.ts +198 -0
  1162. package/dist/tools/goofy/spatialSearch.d.ts.map +1 -0
  1163. package/dist/tools/goofy/spatialSearch.js +551 -0
  1164. package/dist/tools/goofy/spatialSearch.js.map +1 -0
  1165. package/dist/tools/goofy/spawnResearchTeamMember.d.ts +104 -0
  1166. package/dist/tools/goofy/spawnResearchTeamMember.d.ts.map +1 -0
  1167. package/dist/tools/goofy/spawnResearchTeamMember.js +290 -0
  1168. package/dist/tools/goofy/spawnResearchTeamMember.js.map +1 -0
  1169. package/dist/tools/goofy/spawnResearchTeamMemberTool.d.ts +121 -0
  1170. package/dist/tools/goofy/spawnResearchTeamMemberTool.d.ts.map +1 -0
  1171. package/dist/tools/goofy/spawnResearchTeamMemberTool.js +215 -0
  1172. package/dist/tools/goofy/spawnResearchTeamMemberTool.js.map +1 -0
  1173. package/dist/tools/goofy/startWatchingTheFiles.d.ts +81 -0
  1174. package/dist/tools/goofy/startWatchingTheFiles.d.ts.map +1 -0
  1175. package/dist/tools/goofy/startWatchingTheFiles.js +161 -0
  1176. package/dist/tools/goofy/startWatchingTheFiles.js.map +1 -0
  1177. package/dist/tools/goofy/stopWatchingTheFiles.d.ts +50 -0
  1178. package/dist/tools/goofy/stopWatchingTheFiles.d.ts.map +1 -0
  1179. package/dist/tools/goofy/stopWatchingTheFiles.js +81 -0
  1180. package/dist/tools/goofy/stopWatchingTheFiles.js.map +1 -0
  1181. package/dist/tools/goofy/whatDidIMean.d.ts +113 -0
  1182. package/dist/tools/goofy/whatDidIMean.d.ts.map +1 -0
  1183. package/dist/tools/goofy/whatDidIMean.js +401 -0
  1184. package/dist/tools/goofy/whatDidIMean.js.map +1 -0
  1185. package/dist/tools/goofy/yeahNahDeleteThat.d.ts +109 -0
  1186. package/dist/tools/goofy/yeahNahDeleteThat.d.ts.map +1 -0
  1187. package/dist/tools/goofy/yeahNahDeleteThat.js +319 -0
  1188. package/dist/tools/goofy/yeahNahDeleteThat.js.map +1 -0
  1189. package/dist/tools/index.d.ts +9 -0
  1190. package/dist/tools/index.d.ts.map +1 -0
  1191. package/dist/tools/index.js +9 -0
  1192. package/dist/tools/index.js.map +1 -0
  1193. package/dist/tools/teamMemberDeployer.d.ts +117 -0
  1194. package/dist/tools/teamMemberDeployer.d.ts.map +1 -0
  1195. package/dist/tools/teamMemberDeployer.js +613 -0
  1196. package/dist/tools/teamMemberDeployer.js.map +1 -0
  1197. package/dist/trace/index.d.ts +14 -0
  1198. package/dist/trace/index.d.ts.map +1 -0
  1199. package/dist/trace/index.js +16 -0
  1200. package/dist/trace/index.js.map +1 -0
  1201. package/dist/trace/tools/analyzeImpact.d.ts +90 -0
  1202. package/dist/trace/tools/analyzeImpact.d.ts.map +1 -0
  1203. package/dist/trace/tools/analyzeImpact.js +240 -0
  1204. package/dist/trace/tools/analyzeImpact.js.map +1 -0
  1205. package/dist/trace/tools/exploreDependencies.d.ts +81 -0
  1206. package/dist/trace/tools/exploreDependencies.d.ts.map +1 -0
  1207. package/dist/trace/tools/exploreDependencies.js +161 -0
  1208. package/dist/trace/tools/exploreDependencies.js.map +1 -0
  1209. package/dist/trace/tools/findSimilarBugs.d.ts +112 -0
  1210. package/dist/trace/tools/findSimilarBugs.d.ts.map +1 -0
  1211. package/dist/trace/tools/findSimilarBugs.js +216 -0
  1212. package/dist/trace/tools/findSimilarBugs.js.map +1 -0
  1213. package/dist/trace/tools/index.d.ts +22 -0
  1214. package/dist/trace/tools/index.d.ts.map +1 -0
  1215. package/dist/trace/tools/index.js +39 -0
  1216. package/dist/trace/tools/index.js.map +1 -0
  1217. package/dist/trace/tools/smartExplore.d.ts +126 -0
  1218. package/dist/trace/tools/smartExplore.d.ts.map +1 -0
  1219. package/dist/trace/tools/smartExplore.js +303 -0
  1220. package/dist/trace/tools/smartExplore.js.map +1 -0
  1221. package/dist/trace/tools/traceError.d.ts +101 -0
  1222. package/dist/trace/tools/traceError.d.ts.map +1 -0
  1223. package/dist/trace/tools/traceError.js +175 -0
  1224. package/dist/trace/tools/traceError.js.map +1 -0
  1225. package/dist/trace/traceExploreSystem.d.ts +271 -0
  1226. package/dist/trace/traceExploreSystem.d.ts.map +1 -0
  1227. package/dist/trace/traceExploreSystem.js +789 -0
  1228. package/dist/trace/traceExploreSystem.js.map +1 -0
  1229. package/dist/types/index.d.ts +421 -0
  1230. package/dist/types/index.d.ts.map +1 -0
  1231. package/dist/types/index.js +118 -0
  1232. package/dist/types/index.js.map +1 -0
  1233. package/dist/utils/circuitBreaker.d.ts +195 -0
  1234. package/dist/utils/circuitBreaker.d.ts.map +1 -0
  1235. package/dist/utils/circuitBreaker.js +374 -0
  1236. package/dist/utils/circuitBreaker.js.map +1 -0
  1237. package/dist/utils/cleanupHandler.d.ts +108 -0
  1238. package/dist/utils/cleanupHandler.d.ts.map +1 -0
  1239. package/dist/utils/cleanupHandler.js +203 -0
  1240. package/dist/utils/cleanupHandler.js.map +1 -0
  1241. package/dist/utils/compactXmlResponse.d.ts +60 -0
  1242. package/dist/utils/compactXmlResponse.d.ts.map +1 -0
  1243. package/dist/utils/compactXmlResponse.js +209 -0
  1244. package/dist/utils/compactXmlResponse.js.map +1 -0
  1245. package/dist/utils/cotBroadcast.d.ts +56 -0
  1246. package/dist/utils/cotBroadcast.d.ts.map +1 -0
  1247. package/dist/utils/cotBroadcast.js +157 -0
  1248. package/dist/utils/cotBroadcast.js.map +1 -0
  1249. package/dist/utils/debugLogger.d.ts +95 -0
  1250. package/dist/utils/debugLogger.d.ts.map +1 -0
  1251. package/dist/utils/debugLogger.js +610 -0
  1252. package/dist/utils/debugLogger.js.map +1 -0
  1253. package/dist/utils/fileProcessingQueue.d.ts +259 -0
  1254. package/dist/utils/fileProcessingQueue.d.ts.map +1 -0
  1255. package/dist/utils/fileProcessingQueue.js +714 -0
  1256. package/dist/utils/fileProcessingQueue.js.map +1 -0
  1257. package/dist/utils/humanReadableOutput.d.ts +124 -0
  1258. package/dist/utils/humanReadableOutput.d.ts.map +1 -0
  1259. package/dist/utils/humanReadableOutput.js +340 -0
  1260. package/dist/utils/humanReadableOutput.js.map +1 -0
  1261. package/dist/utils/index.d.ts +32 -0
  1262. package/dist/utils/index.d.ts.map +1 -0
  1263. package/dist/utils/index.js +71 -0
  1264. package/dist/utils/index.js.map +1 -0
  1265. package/dist/utils/instanceManager.d.ts +530 -0
  1266. package/dist/utils/instanceManager.d.ts.map +1 -0
  1267. package/dist/utils/instanceManager.js +1784 -0
  1268. package/dist/utils/instanceManager.js.map +1 -0
  1269. package/dist/utils/logger.d.ts +6 -0
  1270. package/dist/utils/logger.d.ts.map +1 -0
  1271. package/dist/utils/logger.js +49 -0
  1272. package/dist/utils/logger.js.map +1 -0
  1273. package/dist/utils/mapCleanup.d.ts +58 -0
  1274. package/dist/utils/mapCleanup.d.ts.map +1 -0
  1275. package/dist/utils/mapCleanup.js +150 -0
  1276. package/dist/utils/mapCleanup.js.map +1 -0
  1277. package/dist/utils/memoryManager.d.ts +349 -0
  1278. package/dist/utils/memoryManager.d.ts.map +1 -0
  1279. package/dist/utils/memoryManager.js +799 -0
  1280. package/dist/utils/memoryManager.js.map +1 -0
  1281. package/dist/utils/metrics.d.ts +160 -0
  1282. package/dist/utils/metrics.d.ts.map +1 -0
  1283. package/dist/utils/metrics.js +558 -0
  1284. package/dist/utils/metrics.js.map +1 -0
  1285. package/dist/utils/pathValidator.d.ts +96 -0
  1286. package/dist/utils/pathValidator.d.ts.map +1 -0
  1287. package/dist/utils/pathValidator.js +320 -0
  1288. package/dist/utils/pathValidator.js.map +1 -0
  1289. package/dist/utils/portAllocator.d.ts +296 -0
  1290. package/dist/utils/portAllocator.d.ts.map +1 -0
  1291. package/dist/utils/portAllocator.js +768 -0
  1292. package/dist/utils/portAllocator.js.map +1 -0
  1293. package/dist/utils/portUtils.d.ts +97 -0
  1294. package/dist/utils/portUtils.d.ts.map +1 -0
  1295. package/dist/utils/portUtils.js +285 -0
  1296. package/dist/utils/portUtils.js.map +1 -0
  1297. package/dist/utils/postgresAutoSetup.d.ts +55 -0
  1298. package/dist/utils/postgresAutoSetup.d.ts.map +1 -0
  1299. package/dist/utils/postgresAutoSetup.js +406 -0
  1300. package/dist/utils/postgresAutoSetup.js.map +1 -0
  1301. package/dist/utils/processHealthCheck.d.ts +61 -0
  1302. package/dist/utils/processHealthCheck.d.ts.map +1 -0
  1303. package/dist/utils/processHealthCheck.js +313 -0
  1304. package/dist/utils/processHealthCheck.js.map +1 -0
  1305. package/dist/utils/progressReporter.d.ts +151 -0
  1306. package/dist/utils/progressReporter.d.ts.map +1 -0
  1307. package/dist/utils/progressReporter.js +345 -0
  1308. package/dist/utils/progressReporter.js.map +1 -0
  1309. package/dist/utils/projectEnv.d.ts +73 -0
  1310. package/dist/utils/projectEnv.d.ts.map +1 -0
  1311. package/dist/utils/projectEnv.js +137 -0
  1312. package/dist/utils/projectEnv.js.map +1 -0
  1313. package/dist/utils/qoms.d.ts +122 -0
  1314. package/dist/utils/qoms.d.ts.map +1 -0
  1315. package/dist/utils/qoms.js +650 -0
  1316. package/dist/utils/qoms.js.map +1 -0
  1317. package/dist/utils/retryHelper.d.ts +122 -0
  1318. package/dist/utils/retryHelper.d.ts.map +1 -0
  1319. package/dist/utils/retryHelper.js +272 -0
  1320. package/dist/utils/retryHelper.js.map +1 -0
  1321. package/dist/utils/safeProcessTermination.d.ts +206 -0
  1322. package/dist/utils/safeProcessTermination.d.ts.map +1 -0
  1323. package/dist/utils/safeProcessTermination.js +552 -0
  1324. package/dist/utils/safeProcessTermination.js.map +1 -0
  1325. package/dist/utils/sessionInjector.d.ts +68 -0
  1326. package/dist/utils/sessionInjector.d.ts.map +1 -0
  1327. package/dist/utils/sessionInjector.js +189 -0
  1328. package/dist/utils/sessionInjector.js.map +1 -0
  1329. package/dist/utils/statsCache.d.ts +134 -0
  1330. package/dist/utils/statsCache.d.ts.map +1 -0
  1331. package/dist/utils/statsCache.js +285 -0
  1332. package/dist/utils/statsCache.js.map +1 -0
  1333. package/dist/utils/timeoutMiddleware.d.ts +81 -0
  1334. package/dist/utils/timeoutMiddleware.d.ts.map +1 -0
  1335. package/dist/utils/timeoutMiddleware.js +155 -0
  1336. package/dist/utils/timeoutMiddleware.js.map +1 -0
  1337. package/dist/utils/timerRegistry.d.ts +91 -0
  1338. package/dist/utils/timerRegistry.d.ts.map +1 -0
  1339. package/dist/utils/timerRegistry.js +187 -0
  1340. package/dist/utils/timerRegistry.js.map +1 -0
  1341. package/dist/utils/tokenCompressor.d.ts +332 -0
  1342. package/dist/utils/tokenCompressor.d.ts.map +1 -0
  1343. package/dist/utils/tokenCompressor.js +1306 -0
  1344. package/dist/utils/tokenCompressor.js.map +1 -0
  1345. package/dist/utils/tracing.d.ts +236 -0
  1346. package/dist/utils/tracing.d.ts.map +1 -0
  1347. package/dist/utils/tracing.js +378 -0
  1348. package/dist/utils/tracing.js.map +1 -0
  1349. package/dist/watcher/changeHandler.d.ts +123 -0
  1350. package/dist/watcher/changeHandler.d.ts.map +1 -0
  1351. package/dist/watcher/changeHandler.js +623 -0
  1352. package/dist/watcher/changeHandler.js.map +1 -0
  1353. package/dist/watcher/changeQueue.d.ts +133 -0
  1354. package/dist/watcher/changeQueue.d.ts.map +1 -0
  1355. package/dist/watcher/changeQueue.js +355 -0
  1356. package/dist/watcher/changeQueue.js.map +1 -0
  1357. package/dist/watcher/fileWatcher.d.ts +121 -0
  1358. package/dist/watcher/fileWatcher.d.ts.map +1 -0
  1359. package/dist/watcher/fileWatcher.js +531 -0
  1360. package/dist/watcher/fileWatcher.js.map +1 -0
  1361. package/dist/watcher/index.d.ts +94 -0
  1362. package/dist/watcher/index.d.ts.map +1 -0
  1363. package/dist/watcher/index.js +235 -0
  1364. package/dist/watcher/index.js.map +1 -0
  1365. package/dist/watcher/syncChecker.d.ts +93 -0
  1366. package/dist/watcher/syncChecker.d.ts.map +1 -0
  1367. package/dist/watcher/syncChecker.js +401 -0
  1368. package/dist/watcher/syncChecker.js.map +1 -0
  1369. package/dist/watcher/tsCompiler.d.ts +88 -0
  1370. package/dist/watcher/tsCompiler.d.ts.map +1 -0
  1371. package/dist/watcher/tsCompiler.js +212 -0
  1372. package/dist/watcher/tsCompiler.js.map +1 -0
  1373. package/embedding-sandbox/Dockerfile +77 -0
  1374. package/embedding-sandbox/Dockerfile.frankenstein +91 -0
  1375. package/embedding-sandbox/README.md +193 -0
  1376. package/embedding-sandbox/__pycache__/frankenstein-embeddings.cpython-312.pyc +0 -0
  1377. package/embedding-sandbox/__pycache__/frankenstein-embeddings.cpython-313.pyc +0 -0
  1378. package/embedding-sandbox/__pycache__/qqms_v2.cpython-312.pyc +0 -0
  1379. package/embedding-sandbox/__pycache__/qqms_v2.cpython-313.pyc +0 -0
  1380. package/embedding-sandbox/add_js_docs.py +684 -0
  1381. package/embedding-sandbox/build_docs_db.py +239 -0
  1382. package/embedding-sandbox/client.cjs +376 -0
  1383. package/embedding-sandbox/client.ts +913 -0
  1384. package/embedding-sandbox/deploy-frankenstein.sh +240 -0
  1385. package/embedding-sandbox/docker-compose.yml +60 -0
  1386. package/embedding-sandbox/docker-manager.py +325 -0
  1387. package/embedding-sandbox/docs/python_docs.db +0 -0
  1388. package/embedding-sandbox/download-model.mjs +79 -0
  1389. package/embedding-sandbox/download-model.py +28 -0
  1390. package/embedding-sandbox/embedding-supervisor.sh +164 -0
  1391. package/embedding-sandbox/frankenstein-embeddings.py +3940 -0
  1392. package/embedding-sandbox/manage-services.sh +354 -0
  1393. package/embedding-sandbox/overflow_queue.py +345 -0
  1394. package/embedding-sandbox/package.json +17 -0
  1395. package/embedding-sandbox/project_isolation.py +292 -0
  1396. package/embedding-sandbox/qqms_v2.py +967 -0
  1397. package/embedding-sandbox/ram-manager.sh +311 -0
  1398. package/embedding-sandbox/requirements-frankenstein.txt +7 -0
  1399. package/embedding-sandbox/run_js_docs.py +59 -0
  1400. package/embedding-sandbox/seed_docs.py +885 -0
  1401. package/embedding-sandbox/server-batch.mjs +228 -0
  1402. package/embedding-sandbox/server.mjs +389 -0
  1403. package/embedding-sandbox/specmem/sockets/claude-input-state.json +1 -0
  1404. package/embedding-sandbox/specmem/sockets/embedding-death-reason.txt +3 -0
  1405. package/embedding-sandbox/specmem/sockets/seen-sessions.json +1 -0
  1406. package/embedding-sandbox/specmem/sockets/session-start.lock +1 -0
  1407. package/embedding-sandbox/specmem/sockets/session-stops.log +7 -0
  1408. package/embedding-sandbox/start-frankenstein-throttled.sh +98 -0
  1409. package/embedding-sandbox/start-on-demand.sh +116 -0
  1410. package/embedding-sandbox/start-sandbox.sh +237 -0
  1411. package/embedding-sandbox/start-supervised.sh +11 -0
  1412. package/embedding-sandbox/stop-sandbox.sh +51 -0
  1413. package/embedding-sandbox/test-socket.mjs +61 -0
  1414. package/embedding-sandbox/warm-start.sh +353 -0
  1415. package/embedding-sandbox/warm_start_feeder.py +660 -0
  1416. package/legal/README.md +31 -0
  1417. package/legal/anthropic-privacy-center-screenshot-2026-01-30.png +0 -0
  1418. package/legal/anthropic-tos-screenshot-2026-01-30.png +0 -0
  1419. package/lib/codebase-bridge.cjs +308 -0
  1420. package/package.json +136 -0
  1421. package/plugins/specmem-agents/agents/bug-hunter.md +79 -0
  1422. package/plugins/specmem-agents/agents/memory-explorer.md +57 -0
  1423. package/plugins/specmem-agents/agents/team-coordinator.md +82 -0
  1424. package/scripts/auto-updater.cjs +399 -0
  1425. package/scripts/backfill-code-definition-embeddings.ts +440 -0
  1426. package/scripts/backfill-code-embeddings.ts +206 -0
  1427. package/scripts/capture-tos-screenshots.cjs +94 -0
  1428. package/scripts/check-global-install.cjs +67 -0
  1429. package/scripts/cleanup-embedding-servers.sh +25 -0
  1430. package/scripts/dashboard-standalone.sh +369 -0
  1431. package/scripts/deploy-hooks.cjs +1451 -0
  1432. package/scripts/deploy.sh +106 -0
  1433. package/scripts/docker-project-down.sh +83 -0
  1434. package/scripts/docker-project-list.sh +40 -0
  1435. package/scripts/docker-project-up.sh +79 -0
  1436. package/scripts/fast-backfill-embeddings.ts +173 -0
  1437. package/scripts/fast-batch-embedder.cjs +334 -0
  1438. package/scripts/first-run-model-setup.cjs +849 -0
  1439. package/scripts/global-postinstall.cjs +1957 -0
  1440. package/scripts/index-codebase.js +72 -0
  1441. package/scripts/migrate-fix-embeddings.py +110 -0
  1442. package/scripts/migrate-to-project-schemas.ts +525 -0
  1443. package/scripts/optimize-embedding-model.py +324 -0
  1444. package/scripts/optimize-instructions.cjs +530 -0
  1445. package/scripts/pack-docker-images.sh +68 -0
  1446. package/scripts/pack-for-testing.sh +130 -0
  1447. package/scripts/postinstall.cjs +54 -0
  1448. package/scripts/project-env.sh +51 -0
  1449. package/scripts/reset-db.sh +30 -0
  1450. package/scripts/run-indexer.ts +69 -0
  1451. package/scripts/run-migrations.js +47 -0
  1452. package/scripts/setup-db.sh +34 -0
  1453. package/scripts/setup-minimal-schema.sql +143 -0
  1454. package/scripts/skills/code-review.md +44 -0
  1455. package/scripts/skills/debugging.md +56 -0
  1456. package/scripts/skills/specmem-deployteam.md +239 -0
  1457. package/scripts/skills/teammemberskills/EFFICIENT_GREP.md +171 -0
  1458. package/scripts/skills/teammemberskills/task-planning.md +67 -0
  1459. package/scripts/specmem/sockets/session-start.lock +1 -0
  1460. package/scripts/specmem/sockets/session-stops.log +1 -0
  1461. package/scripts/specmem-health.sh +382 -0
  1462. package/scripts/specmem-init.cjs +6935 -0
  1463. package/scripts/strip-debug-logs.cjs +43 -0
  1464. package/scripts/test-mcp-standalone.sh +365 -0
  1465. package/scripts/test-optimized-models.py +166 -0
  1466. package/scripts/verify-embedding-fix.sh +148 -0
  1467. package/skills/code-review.md +44 -0
  1468. package/skills/debugging.md +56 -0
  1469. package/skills/specmem-deployteam.md +239 -0
  1470. package/skills/teammemberskills/EFFICIENT_GREP.md +171 -0
  1471. package/skills/teammemberskills/task-planning.md +67 -0
  1472. package/specmem-health.cjs +522 -0
  1473. package/specmem.env +216 -0
@@ -0,0 +1,2081 @@
1
+ /**
2
+ * Embedding Server Lifecycle Manager
3
+ *
4
+ * Manages the embedding server process lifecycle for the MCP server.
5
+ * Ensures embedding server is ALWAYS available when needs it.
6
+ *
7
+ * Features:
8
+ * 1. On MCP server start: Check for stale processes, kill them, start fresh
9
+ * 2. On MCP server stop: Gracefully kill embedding server using PID file
10
+ * 3. Project-specific socket path: {PROJECT}/specmem/sockets/embeddings.sock
11
+ * 4. Health check that pings embedding server periodically
12
+ * 5. Auto-restart if embedding server dies
13
+ *
14
+ * @author hardwicksoftwareservices
15
+ */
16
+ import { spawn, execSync } from 'child_process';
17
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, openSync, closeSync, constants } from 'fs';
18
+ import { join, dirname } from 'path';
19
+ import { createConnection } from 'net';
20
+ import { EventEmitter } from 'events';
21
+ import { fileURLToPath } from 'url';
22
+ import { logger } from '../utils/logger.js';
23
+ import { getProjectPath, getEmbeddingSocketPath } from '../config.js';
24
+ import { checkProcessHealth } from '../utils/processHealthCheck.js';
25
+ import { getPythonPath, mergeWithProjectEnv } from '../utils/projectEnv.js';
26
+ import { getProjectSchema } from '../db/projectNamespacing.js';
27
+ import { ensureSocketDirAtomicSync } from '../utils/fileProcessingQueue.js';
28
+ import { getEmbeddingQueue, hasEmbeddingQueue } from '../services/EmbeddingQueue.js';
29
+ import { getDatabase } from '../database.js';
30
+ // ESM __dirname equivalent - replaces hardcoded paths
31
+ const __filename = fileURLToPath(import.meta.url);
32
+ const __dirname = dirname(__filename);
33
+ const DEFAULT_CONFIG = {
34
+ healthCheckIntervalMs: parseInt(process.env['SPECMEM_EMBEDDING_HEALTH_INTERVAL'] || '30000', 10),
35
+ // MED-24 FIX: Increased from 3s to 10s to handle lazy-load scenarios
36
+ // The embedding server may need time to load the model on first request
37
+ healthCheckTimeoutMs: parseInt(process.env['SPECMEM_EMBEDDING_HEALTH_TIMEOUT'] || '10000', 10),
38
+ maxFailuresBeforeRestart: parseInt(process.env['SPECMEM_EMBEDDING_MAX_FAILURES'] || '2', 10),
39
+ restartCooldownMs: parseInt(process.env['SPECMEM_EMBEDDING_RESTART_COOLDOWN'] || '10000', 10),
40
+ // FIX: Increased from 15s to 45s - Python embedding server needs time to:
41
+ // 1. Start Python interpreter (~1-2s)
42
+ // 2. Import torch/sentence-transformers (~5-10s)
43
+ // 3. Load the ML model into memory (~10-20s)
44
+ // 4. Create the Unix socket (~100ms)
45
+ // Total: 15-30s typical, 45s gives headroom for slower machines
46
+ startupTimeoutMs: parseInt(process.env['SPECMEM_EMBEDDING_STARTUP_TIMEOUT'] || '45000', 10),
47
+ maxRestartAttempts: parseInt(process.env['SPECMEM_EMBEDDING_MAX_RESTARTS'] || '5', 10),
48
+ autoStart: process.env['SPECMEM_EMBEDDING_AUTO_START'] !== 'false',
49
+ killStaleOnStart: process.env['SPECMEM_EMBEDDING_KILL_STALE'] !== 'false',
50
+ maxProcessAgeHours: parseFloat(process.env['SPECMEM_EMBEDDING_MAX_AGE_HOURS'] || '1'),
51
+ };
52
+ // ============================================================================
53
+ // EMBEDDING SERVER MANAGER
54
+ // ============================================================================
55
+ /**
56
+ * EmbeddingServerManager - Manages embedding server process lifecycle
57
+ *
58
+ * Events emitted:
59
+ * - 'started': { pid: number } - Server started successfully
60
+ * - 'stopped': { pid: number } - Server stopped
61
+ * - 'health': HealthCheckResult - Health check result
62
+ * - 'unhealthy': { failures: number } - Server unhealthy
63
+ * - 'restarting': { attempt: number } - Restarting server
64
+ * - 'restart_failed': { attempts: number } - All restart attempts failed
65
+ */
66
+ export class EmbeddingServerManager extends EventEmitter {
67
+ config;
68
+ process = null;
69
+ healthCheckTimer = null;
70
+ isRunning = false;
71
+ consecutiveFailures = 0;
72
+ restartCount = 0;
73
+ lastRestartTime = 0;
74
+ startTime = null;
75
+ projectPath;
76
+ socketPath;
77
+ pidFilePath;
78
+ isShuttingDown = false;
79
+ // FIX: Prevent concurrent starts (race condition causing duplicate processes)
80
+ isStarting = false;
81
+ // FIX: Startup grace period - prevents health monitoring from reporting errors during initialization
82
+ startupGraceUntil = 0;
83
+ // FIX: File-based lock to prevent CROSS-PROCESS concurrent starts
84
+ // The in-memory isStarting flag only prevents within same process
85
+ // Multiple MCP servers (subagents, sessions) need file-based coordination
86
+ startLockPath;
87
+ START_LOCK_TIMEOUT_MS = 60000; // 60 second lock timeout
88
+ // Phase 4: Track if user manually stopped server (prevents auto-restart)
89
+ stoppedFlagPath;
90
+ // Phase 4: Track restart timestamps for loop detection
91
+ restartTimestamps = [];
92
+ // KYS (Keep Yourself Safe) heartbeat timer - sends heartbeat every 25s to embedding server
93
+ // If embedding server doesn't receive heartbeat within 90s, it commits suicide
94
+ // This prevents zombie embedding servers when MCP crashes (increased from 30s for startup tolerance)
95
+ kysHeartbeatTimer = null;
96
+ KYS_HEARTBEAT_INTERVAL_MS = 25000; // 25 seconds
97
+ constructor(config = {}) {
98
+ super();
99
+ this.config = { ...DEFAULT_CONFIG, ...config };
100
+ // Get project-specific paths
101
+ this.projectPath = getProjectPath();
102
+ this.socketPath = getEmbeddingSocketPath();
103
+ this.pidFilePath = join(dirname(this.socketPath), 'embedding.pid');
104
+ // Phase 4: Stopped flag file path - prevents auto-restart when user manually stops
105
+ this.stoppedFlagPath = join(dirname(this.socketPath), 'embedding.stopped');
106
+ // FIX: File-based start lock path - prevents cross-process race condition
107
+ this.startLockPath = join(dirname(this.socketPath), 'embedding.starting');
108
+ logger.info({
109
+ projectPath: this.projectPath,
110
+ socketPath: this.socketPath,
111
+ pidFilePath: this.pidFilePath,
112
+ startLockPath: this.startLockPath,
113
+ config: this.config,
114
+ }, '[EmbeddingServerManager] Initialized');
115
+ }
116
+ // ==========================================================================
117
+ // PUBLIC METHODS
118
+ // ==========================================================================
119
+ /**
120
+ * Initialize and start the embedding server
121
+ * Should be called on MCP server startup
122
+ */
123
+ async initialize() {
124
+ logger.info('[EmbeddingServerManager] Initializing...');
125
+ // Phase 4: Check if user manually stopped the server - respect their choice
126
+ if (this.isStoppedByUser()) {
127
+ logger.info('[EmbeddingServerManager] Server stopped by user, skipping auto-start. Use userStart() to restart.');
128
+ // Still start health monitoring so we can detect if Docker starts it externally
129
+ this.startHealthMonitoring();
130
+ // KYS heartbeat keeps server alive when externally started
131
+ this.startKysHeartbeat();
132
+ return;
133
+ }
134
+ // Step 1: Kill any stale processes
135
+ if (this.config.killStaleOnStart) {
136
+ await this.killStaleProcesses();
137
+ }
138
+ // Step 2: Start the embedding server if auto-start is enabled
139
+ if (this.config.autoStart) {
140
+ await this.start();
141
+ // NOTE: KYS heartbeat is started inside start() immediately after server starts
142
+ // This prevents watchdog timeout during long initialization operations
143
+ }
144
+ // Step 3: Start health monitoring
145
+ this.startHealthMonitoring();
146
+ // Step 4: Start KYS heartbeat if server wasn't auto-started (e.g., externally managed)
147
+ // Only start if not already running to avoid duplicate timers
148
+ if (!this.kysHeartbeatTimer) {
149
+ this.startKysHeartbeat();
150
+ logger.info('[EmbeddingServerManager] KYS heartbeat started (fallback path)');
151
+ }
152
+ logger.info('[EmbeddingServerManager] Initialization complete');
153
+ }
154
+ /**
155
+ * Start the embedding server
156
+ * FIX: First check if Docker container is already serving on this socket
157
+ * FIX: Uses file-based lock to prevent CROSS-PROCESS race conditions
158
+ */
159
+ async start() {
160
+ if (this.isRunning) {
161
+ logger.debug('[EmbeddingServerManager] Server already running');
162
+ return true;
163
+ }
164
+ // FIX: Prevent concurrent starts (race condition causing duplicate processes)
165
+ if (this.isStarting) {
166
+ logger.debug('[EmbeddingServerManager] Start already in progress (in-memory lock), skipping duplicate');
167
+ return false;
168
+ }
169
+ if (this.isShuttingDown) {
170
+ logger.warn('[EmbeddingServerManager] Cannot start during shutdown');
171
+ return false;
172
+ }
173
+ // FIX 1B: Process deduplication check BEFORE acquiring lock
174
+ // Find all running embedding server processes and try to reuse one
175
+ const runningServers = this.findRunningEmbeddingServers();
176
+ if (runningServers.length > 0) {
177
+ logger.info({ count: runningServers.length, pids: runningServers.map(s => s.pid) },
178
+ '[EmbeddingServerManager] FIX 1B: Found existing embedding server processes, checking health');
179
+ // Test if any existing process is healthy via socket
180
+ if (existsSync(this.socketPath)) {
181
+ const healthResult = await this.healthCheck();
182
+ if (healthResult.success) {
183
+ logger.info({
184
+ pids: runningServers.map(s => s.pid),
185
+ responseTimeMs: healthResult.responseTimeMs,
186
+ }, '[EmbeddingServerManager] FIX 1B: Existing server is healthy - reusing instead of spawning new');
187
+ this.isRunning = true;
188
+ this.startTime = Date.now();
189
+ this.consecutiveFailures = 0;
190
+ return true;
191
+ }
192
+ }
193
+ // Existing processes found but unhealthy - kill them all before starting fresh
194
+ logger.warn({ count: runningServers.length },
195
+ '[EmbeddingServerManager] FIX 1B: Existing processes are unhealthy, killing all before fresh start');
196
+ for (const server of runningServers) {
197
+ try {
198
+ process.kill(server.pid, 'SIGTERM');
199
+ logger.info({ pid: server.pid }, '[EmbeddingServerManager] FIX 1B: Sent SIGTERM to unhealthy server');
200
+ }
201
+ catch (err) {
202
+ logger.debug({ pid: server.pid, error: err.message }, '[EmbeddingServerManager] FIX 1B: Failed to SIGTERM process');
203
+ }
204
+ }
205
+ // Wait 2 seconds for processes to terminate
206
+ await this.sleep(2000);
207
+ // Force kill any survivors
208
+ for (const server of runningServers) {
209
+ try {
210
+ process.kill(server.pid, 0); // Check if alive
211
+ process.kill(server.pid, 'SIGKILL');
212
+ logger.info({ pid: server.pid }, '[EmbeddingServerManager] FIX 1B: Force killed surviving process');
213
+ }
214
+ catch {
215
+ // Already dead - good
216
+ }
217
+ }
218
+ // Clean up stale socket
219
+ if (existsSync(this.socketPath)) {
220
+ try { unlinkSync(this.socketPath); } catch { /* ignore */ }
221
+ }
222
+ }
223
+ // FIX 1C: PID file validation before acquiring lock
224
+ // Check if PID file points to a live, healthy process we can reuse
225
+ const pidData = this.readPidFileWithTimestamp();
226
+ if (pidData && pidData.pid) {
227
+ try {
228
+ process.kill(pidData.pid, 0); // Check if process is alive
229
+ // Process is alive - check if it's healthy
230
+ if (existsSync(this.socketPath)) {
231
+ const pidHealthResult = await this.healthCheck();
232
+ if (pidHealthResult.success) {
233
+ logger.info({
234
+ pid: pidData.pid,
235
+ responseTimeMs: pidHealthResult.responseTimeMs,
236
+ }, '[EmbeddingServerManager] FIX 1C: PID file process is alive and healthy - reusing');
237
+ this.isRunning = true;
238
+ this.startTime = Date.now();
239
+ this.consecutiveFailures = 0;
240
+ return true;
241
+ }
242
+ }
243
+ logger.info({ pid: pidData.pid },
244
+ '[EmbeddingServerManager] FIX 1C: PID file process alive but not healthy, continuing with start');
245
+ }
246
+ catch {
247
+ // Process is dead - clean up PID file
248
+ logger.info({ pid: pidData.pid },
249
+ '[EmbeddingServerManager] FIX 1C: PID file process is dead, cleaning up');
250
+ this.removePidFile();
251
+ }
252
+ }
253
+ // FIX: ATOMIC CROSS-PROCESS file-based lock using O_CREAT | O_EXCL
254
+ // This prevents race condition where multiple processes check then write
255
+ // O_EXCL makes openSync fail if file exists - truly atomic lock acquisition
256
+ const lockAcquired = await this.acquireStartLockAtomic();
257
+ if (!lockAcquired) {
258
+ // Another process is starting - wait for them
259
+ logger.info('[EmbeddingServerManager] Lock held by another process, waiting for server...');
260
+ const waitStart = Date.now();
261
+ while (Date.now() - waitStart < 30000) { // 30s max wait
262
+ await this.sleep(1000);
263
+ if (existsSync(this.socketPath)) {
264
+ const healthResult = await this.healthCheck();
265
+ if (healthResult.success) {
266
+ logger.info('[EmbeddingServerManager] Another process started the server successfully');
267
+ this.isRunning = true;
268
+ this.startTime = Date.now();
269
+ return true;
270
+ }
271
+ }
272
+ // Check if lock released (we can try again)
273
+ if (!existsSync(this.startLockPath)) {
274
+ const retryLock = await this.acquireStartLockAtomic();
275
+ if (retryLock)
276
+ break; // Got lock on retry
277
+ }
278
+ }
279
+ // Timed out waiting
280
+ if (!this.acquireStartLockAtomic()) {
281
+ logger.warn('[EmbeddingServerManager] Timeout waiting for lock, giving up');
282
+ return false;
283
+ }
284
+ }
285
+ // Set starting flag immediately to prevent race conditions
286
+ this.isStarting = true;
287
+ // FIX: Set dynamic startup grace period based on configured startupTimeoutMs
288
+ this.startupGraceUntil = Date.now() + this.config.startupTimeoutMs;
289
+ logger.info({ graceMs: this.config.startupTimeoutMs }, '[EmbeddingServerManager] Starting embedding server (grace period active)...');
290
+ // Ensure socket directory exists
291
+ // Task #17 FIX: Use atomic mkdir to prevent race condition when multiple
292
+ // MCP servers try to create the socket directory simultaneously
293
+ const socketDir = dirname(this.socketPath);
294
+ try {
295
+ const created = ensureSocketDirAtomicSync(socketDir);
296
+ if (created) {
297
+ logger.debug({ socketDir }, '[EmbeddingServerManager] Created socket directory atomically');
298
+ }
299
+ }
300
+ catch (err) {
301
+ logger.error({ error: err }, '[EmbeddingServerManager] Failed to create socket directory');
302
+ }
303
+ // FIX: Check if socket already exists AND is responsive (Docker may have started it)
304
+ if (existsSync(this.socketPath)) {
305
+ const healthResult = await this.healthCheck();
306
+ if (healthResult.success) {
307
+ logger.info({
308
+ socketPath: this.socketPath,
309
+ responseTimeMs: healthResult.responseTimeMs
310
+ }, '[EmbeddingServerManager] Socket already responsive (Docker/external server) - using existing');
311
+ // Mark as running but with no managed process (external server)
312
+ this.isRunning = true;
313
+ this.startTime = Date.now();
314
+ this.consecutiveFailures = 0;
315
+ this.isStarting = false; // Reset starting flag
316
+ this.releaseStartLock(); // Release file-based lock
317
+ // CRITICAL FIX: Start KYS heartbeat for external server too
318
+ this.startKysHeartbeat();
319
+ logger.info('[EmbeddingServerManager] KYS heartbeat started for external server');
320
+ this.emit('started', { pid: null, external: true });
321
+ return true;
322
+ }
323
+ // Socket exists but not responding - clean it up
324
+ try {
325
+ unlinkSync(this.socketPath);
326
+ logger.debug('[EmbeddingServerManager] Removed non-responsive socket file');
327
+ }
328
+ catch (err) {
329
+ logger.warn({ error: err }, '[EmbeddingServerManager] Failed to remove old socket');
330
+ }
331
+ }
332
+ // Find the embedding script (prefers warm-start.sh Docker mode)
333
+ const scriptInfo = this.findEmbeddingScript();
334
+ if (!scriptInfo) {
335
+ logger.error('[EmbeddingServerManager] Could not find embedding script');
336
+ this.isStarting = false;
337
+ this.releaseStartLock();
338
+ return false;
339
+ }
340
+ const { script: embeddingScript, useWarmStart } = scriptInfo;
341
+ // Spawn the embedding server process
342
+ try {
343
+ // Read config from model-config.json (heavyOps + resource limits)
344
+ let configEnv = {};
345
+ try {
346
+ const configPath = join(this.projectPath, 'specmem', 'model-config.json');
347
+ if (existsSync(configPath)) {
348
+ const modelConfig = JSON.parse(readFileSync(configPath, 'utf8'));
349
+ // Pass heavyOps settings
350
+ if (modelConfig.heavyOps?.enabled) {
351
+ configEnv.SPECMEM_HEAVY_OPS = '1';
352
+ configEnv.SPECMEM_HEAVY_OPS_BATCH_MULT = String(modelConfig.heavyOps.batchSizeMultiplier || 2);
353
+ configEnv.SPECMEM_HEAVY_OPS_THROTTLE_REDUCE = String(modelConfig.heavyOps.throttleReduction || 0.20);
354
+ logger.info({ heavyOps: modelConfig.heavyOps }, '[EmbeddingServerManager] Heavy Ops mode enabled');
355
+ }
356
+ // Pass batch size from config
357
+ if (modelConfig.embedding?.batchSize) {
358
+ configEnv.SPECMEM_EMBEDDING_BATCH_SIZE = String(modelConfig.embedding.batchSize);
359
+ }
360
+ // Pass resource limits (cpuMin, cpuMax, ramMin, ramMax)
361
+ if (modelConfig.resources) {
362
+ const r = modelConfig.resources;
363
+ if (r.cpuMin != null)
364
+ configEnv.SPECMEM_CPU_MIN = String(r.cpuMin);
365
+ if (r.cpuMax != null)
366
+ configEnv.SPECMEM_CPU_MAX = String(r.cpuMax);
367
+ if (r.ramMinMb != null)
368
+ configEnv.SPECMEM_RAM_MIN_MB = String(r.ramMinMb);
369
+ if (r.ramMaxMb != null)
370
+ configEnv.SPECMEM_RAM_MAX_MB = String(r.ramMaxMb);
371
+ logger.info({ resources: r }, '[EmbeddingServerManager] Resource limits configured');
372
+ }
373
+ }
374
+ }
375
+ catch (configErr) {
376
+ logger.warn({ error: configErr }, '[EmbeddingServerManager] Could not read model-config.json');
377
+ }
378
+ // yooo ALWAYS use mergeWithProjectEnv for project isolation - spawned processes need the full context
379
+ // CRITICAL: Pass DB schema name so embedding server queries the right schema
380
+ const projectSchema = getProjectSchema(this.projectPath);
381
+ const env = mergeWithProjectEnv({
382
+ SPECMEM_SOCKET_DIR: socketDir,
383
+ SPECMEM_EMBEDDING_SOCKET: this.socketPath,
384
+ SPECMEM_EMBEDDING_IDLE_TIMEOUT: '0',
385
+ SPECMEM_DB_SCHEMA: projectSchema,
386
+ ...configEnv,
387
+ });
388
+ if (useWarmStart) {
389
+ // Docker mode via warm-start.sh - handles container lifecycle
390
+ logger.info({ script: embeddingScript }, '[EmbeddingServerManager] Starting via warm-start.sh (Docker mode)');
391
+ this.process = spawn('bash', [embeddingScript], {
392
+ env,
393
+ cwd: dirname(embeddingScript),
394
+ detached: true,
395
+ stdio: ['ignore', 'pipe', 'pipe'],
396
+ });
397
+ }
398
+ else {
399
+ // Direct Python mode - Task #22 fix: Use getPythonPath()
400
+ const pythonPath = getPythonPath();
401
+ logger.info({ pythonPath, script: embeddingScript }, '[EmbeddingServerManager] Starting via Python (direct mode)');
402
+ this.process = spawn(pythonPath, [embeddingScript, '--service'], {
403
+ env,
404
+ cwd: this.projectPath,
405
+ detached: true,
406
+ stdio: ['ignore', 'pipe', 'pipe'],
407
+ });
408
+ }
409
+ const pid = this.process.pid;
410
+ if (!pid) {
411
+ throw new Error('Failed to get process PID');
412
+ }
413
+ // Write PID file
414
+ this.writePidFile(pid);
415
+ // Handle process events
416
+ this.process.on('error', (err) => {
417
+ logger.error({ error: err }, '[EmbeddingServerManager] Process error');
418
+ this.handleProcessExit(-1, 'error');
419
+ });
420
+ this.process.on('exit', (code, signal) => {
421
+ logger.info({ code, signal }, '[EmbeddingServerManager] Process exited');
422
+ this.handleProcessExit(code ?? -1, signal ?? 'unknown');
423
+ });
424
+ // Log stderr for debugging
425
+ this.process.stderr?.on('data', (data) => {
426
+ const msg = data.toString().trim();
427
+ if (msg && (msg.includes('Socket') || msg.includes('READY') || msg.includes('Error') || msg.includes('FRANKENSTEIN'))) {
428
+ logger.debug({ msg }, '[EmbeddingServerManager] Server stderr');
429
+ }
430
+ });
431
+ // Wait for socket to appear
432
+ const socketReady = await this.waitForSocket();
433
+ if (!socketReady) {
434
+ logger.error('[EmbeddingServerManager] Socket did not appear within timeout');
435
+ this.isStarting = false; // Reset starting flag on timeout
436
+ this.releaseStartLock(); // Release file-based lock
437
+ await this.stop();
438
+ return false;
439
+ }
440
+ this.isRunning = true;
441
+ this.startTime = Date.now();
442
+ this.consecutiveFailures = 0;
443
+ // Verify the new process with health check
444
+ const verifyHealth = await this.healthCheck();
445
+ if (verifyHealth.success) {
446
+ logger.info({
447
+ pid,
448
+ socketPath: this.socketPath,
449
+ responseTimeMs: verifyHealth.responseTimeMs,
450
+ dimensions: verifyHealth.dimensions,
451
+ }, '[EmbeddingServerManager] Server started successfully and verified healthy');
452
+ }
453
+ else {
454
+ logger.warn({
455
+ pid,
456
+ socketPath: this.socketPath,
457
+ error: verifyHealth.error,
458
+ }, '[EmbeddingServerManager] Server started but health check failed (may still be initializing)');
459
+ }
460
+ this.emit('started', { pid });
461
+ // CRITICAL FIX: Start KYS heartbeat IMMEDIATELY after server starts
462
+ // The heartbeat must begin BEFORE any long-running operations (like queue draining)
463
+ // to prevent the embedding server's watchdog from timing out
464
+ this.startKysHeartbeat();
465
+ logger.info('[EmbeddingServerManager] KYS heartbeat started immediately after server start');
466
+ // Drain any queued embedding requests now that server is up
467
+ this.drainEmbeddingQueueIfNeeded().catch(err => {
468
+ logger.warn({ error: err }, '[EmbeddingServerManager] Queue drain failed (non-fatal)');
469
+ });
470
+ this.isStarting = false; // Reset starting flag on success
471
+ // FIX: Clear grace period once server is verified running
472
+ if (verifyHealth.success) {
473
+ this.startupGraceUntil = 0;
474
+ }
475
+ this.releaseStartLock(); // Release file-based lock
476
+ return true;
477
+ }
478
+ catch (err) {
479
+ logger.error({ error: err }, '[EmbeddingServerManager] Failed to start server');
480
+ this.isStarting = false; // Reset starting flag on error
481
+ this.startupGraceUntil = 0; // Clear grace on failure too
482
+ this.releaseStartLock(); // Release file-based lock
483
+ return false;
484
+ }
485
+ }
486
+ /**
487
+ * Atomically acquire the start lock using O_CREAT | O_EXCL
488
+ * This is truly atomic - the OS ensures only one process can create the file
489
+ * @returns true if lock acquired, false if another process has it
490
+ */
491
+ async acquireStartLockAtomic() {
492
+ try {
493
+ // FIX 1A: Strengthened lock acquisition with PID validation and stale detection
494
+ // First check if lock exists and is stale
495
+ if (existsSync(this.startLockPath)) {
496
+ try {
497
+ const lockContent = readFileSync(this.startLockPath, 'utf8').trim();
498
+ const parts = lockContent.split(':');
499
+ const lockTime = parseInt(parts[0], 10);
500
+ const lockPid = parseInt(parts[1], 10);
501
+ const lockAge = Date.now() - lockTime;
502
+ // FIX 1A: Reduced stale threshold from 60s to 120s for robustness
503
+ const STALE_LOCK_THRESHOLD_MS = 120000; // 120 seconds
504
+ if (lockAge >= STALE_LOCK_THRESHOLD_MS) {
505
+ // Stale lock by time - remove it
506
+ logger.warn({ lockAge, lockPid, thresholdMs: STALE_LOCK_THRESHOLD_MS }, '[EmbeddingServerManager] Removing stale start lock (exceeded time threshold)');
507
+ unlinkSync(this.startLockPath);
508
+ }
509
+ else if (!isNaN(lockPid) && lockPid > 0) {
510
+ // FIX 1A: Lock is recent - check if the owning process is still alive
511
+ try {
512
+ process.kill(lockPid, 0); // Signal 0 = check existence
513
+ // Process is alive and lock is recent - respect it
514
+ logger.debug({ lockAge, lockPid }, '[EmbeddingServerManager] Lock held by alive process');
515
+ return false;
516
+ }
517
+ catch (killErr) {
518
+ // Process is dead - stale lock from a crashed process
519
+ logger.warn({ lockPid, lockAge }, '[EmbeddingServerManager] Lock owner process is dead, removing stale lock');
520
+ try {
521
+ unlinkSync(this.startLockPath);
522
+ }
523
+ catch { /* ignore */ }
524
+ }
525
+ }
526
+ else {
527
+ // Recent lock but no valid PID - respect it
528
+ logger.debug({ lockAge, lockPid }, '[EmbeddingServerManager] Lock held by another process (no valid PID)');
529
+ return false;
530
+ }
531
+ }
532
+ catch (readErr) {
533
+ // Lock file corrupt or unreadable - try to remove it
534
+ try {
535
+ unlinkSync(this.startLockPath);
536
+ }
537
+ catch { /* ignore */ }
538
+ }
539
+ }
540
+ // Try atomic create with O_CREAT | O_EXCL - fails if file exists
541
+ // This is the atomic part - only one process can succeed
542
+ const fd = openSync(this.startLockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);
543
+ // FIX 1A: Write PID + timestamp to lock file for stale detection
544
+ const lockContent = `${Date.now()}:${process.pid}`;
545
+ writeFileSync(fd, lockContent, 'utf8');
546
+ closeSync(fd);
547
+ logger.debug({ pid: process.pid }, '[EmbeddingServerManager] Acquired start lock atomically');
548
+ return true;
549
+ }
550
+ catch (err) {
551
+ if (err.code === 'EEXIST') {
552
+ // FIX 1A: On EEXIST, read the lock content and check if owner is alive
553
+ try {
554
+ const lockContent = readFileSync(this.startLockPath, 'utf8').trim();
555
+ const parts = lockContent.split(':');
556
+ const lockTime = parseInt(parts[0], 10);
557
+ const lockPid = parseInt(parts[1], 10);
558
+ const lockAge = Date.now() - lockTime;
559
+ // Check if lock is stale (>120s) or owner process is dead
560
+ let isStale = lockAge > 120000;
561
+ if (!isStale && !isNaN(lockPid) && lockPid > 0) {
562
+ try {
563
+ process.kill(lockPid, 0);
564
+ // Owner alive, lock valid
565
+ }
566
+ catch {
567
+ // Owner dead, lock is stale
568
+ isStale = true;
569
+ }
570
+ }
571
+ if (isStale) {
572
+ logger.warn({ lockPid, lockAge }, '[EmbeddingServerManager] EEXIST but lock is stale, removing and retrying');
573
+ try {
574
+ unlinkSync(this.startLockPath);
575
+ }
576
+ catch { /* ignore */ }
577
+ // Retry once after removing stale lock
578
+ try {
579
+ const fd = openSync(this.startLockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);
580
+ const newLockContent = `${Date.now()}:${process.pid}`;
581
+ writeFileSync(fd, newLockContent, 'utf8');
582
+ closeSync(fd);
583
+ logger.debug({ pid: process.pid }, '[EmbeddingServerManager] Acquired start lock on retry after stale removal');
584
+ return true;
585
+ }
586
+ catch (retryErr) {
587
+ logger.debug('[EmbeddingServerManager] Retry lock acquisition failed - another process won the race');
588
+ return false;
589
+ }
590
+ }
591
+ }
592
+ catch (readErr) {
593
+ // Can't read lock file - just report as held
594
+ }
595
+ logger.debug('[EmbeddingServerManager] Lock already exists (EEXIST) - another process has it');
596
+ return false;
597
+ }
598
+ // Other error - log and fail
599
+ logger.warn({ error: err }, '[EmbeddingServerManager] Lock acquisition error');
600
+ return false;
601
+ }
602
+ }
603
+ /**
604
+ * Release the file-based start lock
605
+ */
606
+ releaseStartLock() {
607
+ try {
608
+ if (existsSync(this.startLockPath)) {
609
+ unlinkSync(this.startLockPath);
610
+ logger.debug('[EmbeddingServerManager] Released start lock');
611
+ }
612
+ }
613
+ catch (err) {
614
+ logger.debug({ error: err }, '[EmbeddingServerManager] Failed to release start lock');
615
+ }
616
+ }
617
+ /**
618
+ * FIX 1B: Find all running embedding server processes using ps
619
+ * Returns array of { pid, command } objects for each running frankenstein-embeddings.py process
620
+ */
621
+ findRunningEmbeddingServers() {
622
+ try {
623
+ const result = execSync('ps aux | grep frankenstein-embeddings.py | grep -v grep', {
624
+ encoding: 'utf8',
625
+ timeout: 5000,
626
+ }).trim();
627
+ if (!result) return [];
628
+ const processes = [];
629
+ for (const line of result.split('\n')) {
630
+ if (!line.trim()) continue;
631
+ const parts = line.trim().split(/\s+/);
632
+ const pid = parseInt(parts[1], 10);
633
+ if (!isNaN(pid)) {
634
+ processes.push({ pid, command: parts.slice(10).join(' ') });
635
+ }
636
+ }
637
+ return processes;
638
+ }
639
+ catch (err) {
640
+ // ps/grep returns exit code 1 when no matches found - that's normal
641
+ return [];
642
+ }
643
+ }
644
+ /**
645
+ * Drain embedding queue after server starts
646
+ * Processes any pending embedding requests that were queued while server was down
647
+ */
648
+ async drainEmbeddingQueueIfNeeded() {
649
+ try {
650
+ const db = getDatabase();
651
+ if (!db) {
652
+ logger.debug('[EmbeddingServerManager] No database available, skipping queue drain');
653
+ return;
654
+ }
655
+ const pool = db.getPool();
656
+ if (!pool) {
657
+ logger.debug('[EmbeddingServerManager] No pool available, skipping queue drain');
658
+ return;
659
+ }
660
+ if (!hasEmbeddingQueue()) {
661
+ logger.debug('[EmbeddingServerManager] No embedding queue exists, skipping drain');
662
+ return;
663
+ }
664
+ const queue = getEmbeddingQueue(pool);
665
+ const pendingCount = await queue.getPendingCount();
666
+ if (pendingCount === 0) {
667
+ logger.debug('[EmbeddingServerManager] No pending items in queue');
668
+ return;
669
+ }
670
+ logger.info({ pendingCount }, '[EmbeddingServerManager] Draining embedding queue after server start');
671
+ const drained = await queue.drainQueue((text) => this.generateEmbeddingViaSocket(text));
672
+ logger.info({ drained }, '[EmbeddingServerManager] Queue drain complete');
673
+ }
674
+ catch (err) {
675
+ logger.warn({ error: err }, '[EmbeddingServerManager] Failed to drain embedding queue');
676
+ }
677
+ }
678
+ /**
679
+ * Generate embedding using direct socket connection
680
+ * Used by drainQueue to process pending requests after server comes online
681
+ */
682
+ async generateEmbeddingViaSocket(text) {
683
+ return new Promise((resolve, reject) => {
684
+ const socket = createConnection(this.socketPath);
685
+ let buffer = '';
686
+ let resolved = false;
687
+ const timeout = setTimeout(() => {
688
+ if (!resolved) {
689
+ resolved = true;
690
+ socket.destroy();
691
+ reject(new Error('Embedding generation timeout'));
692
+ }
693
+ }, 60000); // 60 second timeout for embedding generation
694
+ socket.on('connect', () => {
695
+ socket.write(JSON.stringify({ text }) + '\n');
696
+ });
697
+ socket.on('data', (data) => {
698
+ buffer += data.toString();
699
+ // Process all complete lines in the buffer
700
+ // The server may send multiple lines: {"status": "processing"} then {"embedding": [...]}
701
+ let newlineIndex;
702
+ while ((newlineIndex = buffer.indexOf('\n')) !== -1) {
703
+ if (resolved)
704
+ return;
705
+ const line = buffer.slice(0, newlineIndex);
706
+ buffer = buffer.slice(newlineIndex + 1);
707
+ try {
708
+ const response = JSON.parse(line);
709
+ // Handle error responses
710
+ if (response.error) {
711
+ clearTimeout(timeout);
712
+ resolved = true;
713
+ socket.end();
714
+ reject(new Error(response.error));
715
+ return;
716
+ }
717
+ // Skip "processing" status messages - wait for actual embedding
718
+ if (response.status === 'processing') {
719
+ logger.debug({ textLength: response.text_length }, '[EmbeddingServerManager] Embedding request queued, waiting for result...');
720
+ continue; // Keep reading for the actual embedding
721
+ }
722
+ // Got the embedding!
723
+ if (response.embedding && Array.isArray(response.embedding)) {
724
+ clearTimeout(timeout);
725
+ resolved = true;
726
+ socket.end();
727
+ resolve(response.embedding);
728
+ return;
729
+ }
730
+ // Unknown response format - log but keep waiting
731
+ logger.warn({ response: JSON.stringify(response).slice(0, 100) }, '[EmbeddingServerManager] Unexpected response format, continuing to wait');
732
+ }
733
+ catch (parseErr) {
734
+ logger.warn({ line: line.slice(0, 100) }, '[EmbeddingServerManager] Failed to parse line, continuing to wait');
735
+ }
736
+ }
737
+ });
738
+ socket.on('error', (err) => {
739
+ clearTimeout(timeout);
740
+ if (!resolved) {
741
+ resolved = true;
742
+ reject(err);
743
+ }
744
+ });
745
+ });
746
+ }
747
+ /**
748
+ * Stop the embedding server gracefully
749
+ */
750
+ async stop() {
751
+ this.isShuttingDown = true;
752
+ this.isStarting = false; // Reset starting flag on stop
753
+ this.startupGraceUntil = 0; // Clear any active grace period
754
+ logger.info('[EmbeddingServerManager] Stopping embedding server...');
755
+ // Stop health monitoring
756
+ this.stopHealthMonitoring();
757
+ // Stop KYS heartbeat - server will suicide after 30s without heartbeat
758
+ this.stopKysHeartbeat();
759
+ // Kill the process
760
+ if (this.process && this.process.pid) {
761
+ try {
762
+ // Try graceful SIGTERM first
763
+ process.kill(this.process.pid, 'SIGTERM');
764
+ // Wait briefly for graceful shutdown
765
+ await this.sleep(1000);
766
+ // Force kill if still running
767
+ try {
768
+ process.kill(this.process.pid, 0); // Check if still running
769
+ process.kill(this.process.pid, 'SIGKILL');
770
+ logger.debug('[EmbeddingServerManager] Force killed process');
771
+ }
772
+ catch {
773
+ // Process already dead - good
774
+ }
775
+ }
776
+ catch (err) {
777
+ logger.debug({ error: err }, '[EmbeddingServerManager] Process already dead');
778
+ }
779
+ }
780
+ // Also try killing by PID file (in case process reference was lost)
781
+ await this.killByPidFile();
782
+ // FIX: Kill ALL running embedding server processes (orphans from previous sessions/subagents)
783
+ const allServers = this.findRunningEmbeddingServers();
784
+ if (allServers.length > 0) {
785
+ logger.info({ count: allServers.length, pids: allServers.map(s => s.pid) },
786
+ '[EmbeddingServerManager] Killing all remaining embedding server processes');
787
+ for (const server of allServers) {
788
+ try {
789
+ process.kill(server.pid, 'SIGTERM');
790
+ } catch { /* already dead */ }
791
+ }
792
+ await this.sleep(2000);
793
+ for (const server of allServers) {
794
+ try {
795
+ process.kill(server.pid, 0);
796
+ process.kill(server.pid, 'SIGKILL');
797
+ logger.info({ pid: server.pid }, '[EmbeddingServerManager] Force killed orphan embedding process');
798
+ } catch { /* already dead */ }
799
+ }
800
+ }
801
+ // Clean up PID file
802
+ this.removePidFile();
803
+ // Clean up socket file
804
+ if (existsSync(this.socketPath)) {
805
+ try {
806
+ unlinkSync(this.socketPath);
807
+ }
808
+ catch (err) {
809
+ logger.debug({ error: err }, '[EmbeddingServerManager] Failed to remove socket');
810
+ }
811
+ }
812
+ this.process = null;
813
+ this.isRunning = false;
814
+ this.startTime = null;
815
+ logger.info('[EmbeddingServerManager] Server stopped');
816
+ this.emit('stopped', { pid: this.process?.pid });
817
+ }
818
+ /**
819
+ * Perform a health check on the embedding server
820
+ */
821
+ async healthCheck() {
822
+ const startTime = Date.now();
823
+ // Quick check: socket must exist
824
+ if (!existsSync(this.socketPath)) {
825
+ return {
826
+ success: false,
827
+ responseTimeMs: Date.now() - startTime,
828
+ error: 'Socket file does not exist',
829
+ };
830
+ }
831
+ // Ping the server
832
+ return new Promise((resolve) => {
833
+ const socket = createConnection(this.socketPath);
834
+ let buffer = '';
835
+ let resolved = false;
836
+ const timeout = setTimeout(() => {
837
+ if (!resolved) {
838
+ resolved = true;
839
+ socket.destroy();
840
+ resolve({
841
+ success: false,
842
+ responseTimeMs: Date.now() - startTime,
843
+ error: 'Health check timeout',
844
+ });
845
+ }
846
+ }, this.config.healthCheckTimeoutMs);
847
+ socket.on('connect', () => {
848
+ // FIX: Docker server.mjs requires type field - use {"type":"health"} for health checks
849
+ // Python server (frankenstein-embeddings.py) accepts both {"stats":true} and {"type":"health"}
850
+ // Docker server.mjs ONLY accepts {"type":"health"} - so use that for compatibility with both
851
+ socket.write(JSON.stringify({ type: 'health' }) + '\n');
852
+ });
853
+ socket.on('data', (data) => {
854
+ buffer += data.toString();
855
+ const newlineIndex = buffer.indexOf('\n');
856
+ if (newlineIndex !== -1) {
857
+ clearTimeout(timeout);
858
+ if (resolved)
859
+ return;
860
+ resolved = true;
861
+ try {
862
+ const response = JSON.parse(buffer.slice(0, newlineIndex));
863
+ socket.end();
864
+ // Check for error response first
865
+ if (response.error) {
866
+ resolve({
867
+ success: false,
868
+ responseTimeMs: Date.now() - startTime,
869
+ error: `Server error: ${response.error}`,
870
+ });
871
+ return;
872
+ }
873
+ // Handle both Python (capabilities) and Docker (native_dimensions) response formats
874
+ // Python frankenstein-embeddings.py: { capabilities: { native_dims, target_dims }, ... }
875
+ // Docker server.mjs: { status: "healthy", native_dimensions, target_dimensions, ... }
876
+ if (response.capabilities) {
877
+ // Python format
878
+ resolve({
879
+ success: true,
880
+ responseTimeMs: Date.now() - startTime,
881
+ dimensions: {
882
+ native: response.capabilities.native_dims,
883
+ target: response.capabilities.target_dims,
884
+ },
885
+ });
886
+ }
887
+ else if (response.native_dimensions !== undefined) {
888
+ // Docker format - check for healthy status
889
+ const isHealthy = response.status === 'healthy' || response.status === 'ok';
890
+ resolve({
891
+ success: isHealthy,
892
+ responseTimeMs: Date.now() - startTime,
893
+ dimensions: {
894
+ native: response.native_dimensions,
895
+ target: response.target_dimensions,
896
+ },
897
+ });
898
+ }
899
+ else {
900
+ // Fallback for other response formats - assume healthy if no error
901
+ resolve({
902
+ success: true,
903
+ responseTimeMs: Date.now() - startTime,
904
+ });
905
+ }
906
+ }
907
+ catch (parseErr) {
908
+ socket.end();
909
+ resolve({
910
+ success: false,
911
+ responseTimeMs: Date.now() - startTime,
912
+ error: 'Invalid response from server',
913
+ });
914
+ }
915
+ }
916
+ });
917
+ socket.on('error', (err) => {
918
+ clearTimeout(timeout);
919
+ if (!resolved) {
920
+ resolved = true;
921
+ resolve({
922
+ success: false,
923
+ responseTimeMs: Date.now() - startTime,
924
+ error: `Socket error: ${err.message}`,
925
+ });
926
+ }
927
+ });
928
+ });
929
+ }
930
+ /**
931
+ * Get current server status
932
+ */
933
+ getStatus() {
934
+ const pid = this.readPidFile();
935
+ const socketExists = existsSync(this.socketPath);
936
+ return {
937
+ running: this.isRunning,
938
+ pid,
939
+ socketPath: this.socketPath,
940
+ socketExists,
941
+ healthy: this.isRunning && socketExists && this.consecutiveFailures === 0,
942
+ lastHealthCheck: this.healthCheckTimer ? Date.now() : null,
943
+ consecutiveFailures: this.consecutiveFailures,
944
+ restartCount: this.restartCount,
945
+ startTime: this.startTime,
946
+ uptime: this.startTime ? Date.now() - this.startTime : null,
947
+ };
948
+ }
949
+ /**
950
+ * Shutdown - called when MCP server is shutting down
951
+ */
952
+ async shutdown() {
953
+ await this.stop();
954
+ this.removeAllListeners();
955
+ }
956
+ // ==========================================================================
957
+ // PHASE 4: USER-INITIATED START/STOP + RESTART LOOP DETECTION
958
+ // ==========================================================================
959
+ /**
960
+ * Check if user manually stopped the server
961
+ * Returns true if the stopped flag file exists
962
+ */
963
+ isStoppedByUser() {
964
+ return existsSync(this.stoppedFlagPath);
965
+ }
966
+ /**
967
+ * Check if the embedding server died due to KYS watchdog (no heartbeat from MCP)
968
+ * Returns true if death reason file exists and contains "kys"
969
+ */
970
+ wasKilledByKYS() {
971
+ const deathReasonPath = join(dirname(this.socketPath), 'embedding-death-reason.txt');
972
+ if (!existsSync(deathReasonPath)) {
973
+ return false;
974
+ }
975
+ try {
976
+ const content = readFileSync(deathReasonPath, 'utf8');
977
+ return content.startsWith('kys');
978
+ }
979
+ catch {
980
+ return false;
981
+ }
982
+ }
983
+ /**
984
+ * Clear the KYS death reason file (called after successful respawn)
985
+ */
986
+ clearKYSDeathReason() {
987
+ const deathReasonPath = join(dirname(this.socketPath), 'embedding-death-reason.txt');
988
+ if (existsSync(deathReasonPath)) {
989
+ try {
990
+ unlinkSync(deathReasonPath);
991
+ logger.info('[EmbeddingServerManager] Cleared KYS death reason file');
992
+ }
993
+ catch (err) {
994
+ logger.warn({ err }, '[EmbeddingServerManager] Failed to clear KYS death reason file');
995
+ }
996
+ }
997
+ }
998
+ /**
999
+ * Auto-respawn if server was killed by KYS watchdog
1000
+ * This is called when a socket connection fails - if KYS was the cause,
1001
+ * we respawn the server and return true so caller can retry
1002
+ */
1003
+ async autoRespawnIfKYSDeath() {
1004
+ if (!this.wasKilledByKYS()) {
1005
+ return false;
1006
+ }
1007
+ logger.info('[EmbeddingServerManager] Server was killed by KYS watchdog - auto-respawning');
1008
+ // Clear the death reason so we don't loop
1009
+ this.clearKYSDeathReason();
1010
+ // Clear stopped flag in case it was set
1011
+ this.setStoppedByUser(false);
1012
+ // Reset failure counters
1013
+ this.consecutiveFailures = 0;
1014
+ this.restartCount = 0;
1015
+ // Force a fresh start
1016
+ try {
1017
+ await this.start();
1018
+ logger.info('[EmbeddingServerManager] Auto-respawn complete after KYS death');
1019
+ return true;
1020
+ }
1021
+ catch (err) {
1022
+ logger.error({ err }, '[EmbeddingServerManager] Auto-respawn failed after KYS death');
1023
+ return false;
1024
+ }
1025
+ }
1026
+ /**
1027
+ * Set the stopped-by-user flag
1028
+ * When true, prevents auto-restart
1029
+ */
1030
+ setStoppedByUser(stopped) {
1031
+ if (stopped) {
1032
+ writeFileSync(this.stoppedFlagPath, Date.now().toString(), 'utf8');
1033
+ logger.info('[EmbeddingServerManager] Set stopped-by-user flag');
1034
+ }
1035
+ else if (existsSync(this.stoppedFlagPath)) {
1036
+ unlinkSync(this.stoppedFlagPath);
1037
+ logger.info('[EmbeddingServerManager] Cleared stopped-by-user flag');
1038
+ }
1039
+ }
1040
+ /**
1041
+ * User-initiated stop - sets flag to prevent auto-restart
1042
+ * Use this when user explicitly wants to stop the embedding server
1043
+ */
1044
+ async userStop() {
1045
+ logger.info('[EmbeddingServerManager] User-initiated stop');
1046
+ // Set flag BEFORE stopping to prevent health check restart race
1047
+ this.setStoppedByUser(true);
1048
+ await this.stop();
1049
+ return {
1050
+ success: true,
1051
+ message: 'Embedding server stopped. Auto-restart disabled. Use userStart() to restart.'
1052
+ };
1053
+ }
1054
+ /**
1055
+ * User-initiated start - clears stopped flag and does hard restart
1056
+ * Use this when user explicitly wants to (re)start the embedding server
1057
+ */
1058
+ async userStart() {
1059
+ logger.info('[EmbeddingServerManager] User-initiated start');
1060
+ // Clear the stopped flag
1061
+ this.setStoppedByUser(false);
1062
+ // Reset restart counter for fresh start
1063
+ this.restartCount = 0;
1064
+ this.restartTimestamps = [];
1065
+ this.consecutiveFailures = 0;
1066
+ this.isShuttingDown = false;
1067
+ // Kill existing and start fresh
1068
+ await this.stop();
1069
+ // Clear the shutdown flag that stop() sets
1070
+ this.isShuttingDown = false;
1071
+ const success = await this.start();
1072
+ if (success) {
1073
+ // Start health monitoring if not already running
1074
+ this.startHealthMonitoring();
1075
+ // NOTE: KYS heartbeat already started inside start() method
1076
+ // No need to start it again here
1077
+ }
1078
+ return {
1079
+ success,
1080
+ message: success
1081
+ ? 'Embedding server started successfully'
1082
+ : 'Failed to start embedding server - check logs for details'
1083
+ };
1084
+ }
1085
+ /**
1086
+ * Get restart loop detection info
1087
+ * Detects if we're in a restart loop (>3 restarts in 60 seconds)
1088
+ */
1089
+ getRestartLoopInfo() {
1090
+ const windowMs = 60000; // 60 seconds
1091
+ const loopThreshold = 3;
1092
+ const now = Date.now();
1093
+ // Count restarts in the last 60 seconds
1094
+ const recentRestarts = this.restartTimestamps.filter(ts => now - ts < windowMs).length;
1095
+ return {
1096
+ inLoop: recentRestarts >= loopThreshold,
1097
+ recentRestarts,
1098
+ maxAttempts: this.config.maxRestartAttempts,
1099
+ windowSeconds: 60,
1100
+ restartCount: this.restartCount
1101
+ };
1102
+ }
1103
+ /**
1104
+ * Get extended status including stopped-by-user flag and restart loop info
1105
+ */
1106
+ getExtendedStatus() {
1107
+ const graceActive = this.startupGraceUntil > 0 && Date.now() < this.startupGraceUntil;
1108
+ return {
1109
+ ...this.getStatus(),
1110
+ stoppedByUser: this.isStoppedByUser(),
1111
+ restartLoop: this.getRestartLoopInfo(),
1112
+ startupGrace: graceActive ? {
1113
+ active: true,
1114
+ remainingMs: this.startupGraceUntil - Date.now(),
1115
+ totalMs: this.config.startupTimeoutMs
1116
+ } : { active: false }
1117
+ };
1118
+ }
1119
+ // ==========================================================================
1120
+ // PRIVATE METHODS
1121
+ // ==========================================================================
1122
+ /**
1123
+ * Kill any stale embedding processes from previous runs
1124
+ * Uses robust process age checking to verify we're killing the right process
1125
+ */
1126
+ async killStaleProcesses() {
1127
+ logger.info('[EmbeddingServerManager] Checking for stale processes...');
1128
+ // Step 0: KILL ANY ROGUE DOCKER EMBEDDING CONTAINERS
1129
+ // Docker containers crash-loop if they can't bind to the socket because
1130
+ // the native Python server already owns it. Clean them up FIRST.
1131
+ try {
1132
+ const projectDirName = require('path').basename(this.projectPath).toLowerCase().replace(/[^a-z0-9]/g, '');
1133
+ const containerName = `specmem-embedding-${projectDirName}`;
1134
+ // Check if container exists (running or stopped)
1135
+ const checkCmd = `docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^${containerName}$"`;
1136
+ try {
1137
+ execSync(checkCmd, { stdio: 'pipe' });
1138
+ // Container exists - remove it forcefully
1139
+ logger.info({ containerName }, '[EmbeddingServerManager] Removing rogue Docker embedding container');
1140
+ execSync(`docker rm -f ${containerName} 2>/dev/null`, { stdio: 'pipe' });
1141
+ logger.info({ containerName }, '[EmbeddingServerManager] Rogue Docker container removed');
1142
+ }
1143
+ catch {
1144
+ // Container doesn't exist - good
1145
+ logger.debug({ containerName }, '[EmbeddingServerManager] No rogue Docker container found');
1146
+ }
1147
+ }
1148
+ catch (err) {
1149
+ logger.debug({ error: err?.message || err }, '[EmbeddingServerManager] Docker cleanup check failed (Docker may not be installed)');
1150
+ }
1151
+ // Step 1: Check PID file with health check
1152
+ const healthInfo = checkProcessHealth({
1153
+ pidFilePath: this.pidFilePath,
1154
+ maxAgeHours: this.config.maxProcessAgeHours,
1155
+ expectedProcessName: 'frankenstein-embeddings',
1156
+ projectPath: this.projectPath,
1157
+ });
1158
+ if (healthInfo) {
1159
+ logger.info({
1160
+ pid: healthInfo.pid,
1161
+ processExists: healthInfo.processExists,
1162
+ isEmbeddingServer: healthInfo.isEmbeddingServer,
1163
+ ageHours: healthInfo.processAgeHours?.toFixed(2) || 'unknown',
1164
+ pidFileAgeHours: healthInfo.pidFileAgeHours.toFixed(2),
1165
+ isStale: healthInfo.isStale,
1166
+ recommendedAction: healthInfo.recommendedAction,
1167
+ statusMessage: healthInfo.statusMessage,
1168
+ }, '[EmbeddingServerManager] Process health check result');
1169
+ // Take action based on health check
1170
+ // CRITICAL FIX: Only kill if process belongs to THIS project's socket path
1171
+ // Check process's SPECMEM_EMBEDDING_SOCKET env var (not cmdline - socket isn't in cmdline!)
1172
+ const processSocketPath = healthInfo.pid ? this.getProcessSocketPath(healthInfo.pid) : null;
1173
+ const belongsToThisProject = processSocketPath === this.socketPath;
1174
+ if (!belongsToThisProject && processSocketPath) {
1175
+ logger.info({
1176
+ pid: healthInfo.pid,
1177
+ thisProjectSocket: this.socketPath,
1178
+ processSocket: processSocketPath,
1179
+ }, '[EmbeddingServerManager] Process belongs to different project - skipping kill');
1180
+ // Don't kill processes from other projects - just clean up our PID file
1181
+ this.removePidFile();
1182
+ return;
1183
+ }
1184
+ if (healthInfo.recommendedAction === 'kill') {
1185
+ await this.killProcessWithHealthInfo(healthInfo);
1186
+ }
1187
+ else if (healthInfo.recommendedAction === 'investigate') {
1188
+ logger.warn({
1189
+ pid: healthInfo.pid,
1190
+ commandLine: healthInfo.commandLine,
1191
+ message: 'Process exists but may not be embedding server - killing to be safe',
1192
+ }, '[EmbeddingServerManager] Suspicious process found');
1193
+ await this.killProcessWithHealthInfo(healthInfo);
1194
+ }
1195
+ else {
1196
+ // CRITICAL FIX: Don't kill healthy servers - REUSE them!
1197
+ // This allows multiple MCP sessions to share the same embedding server
1198
+ // Killing a healthy server breaks other sessions that depend on it
1199
+ logger.info({
1200
+ pid: healthInfo.pid,
1201
+ ageHours: healthInfo.processAgeHours?.toFixed(2) || 'unknown',
1202
+ }, '[EmbeddingServerManager] Process is healthy - REUSING instead of killing (preserves other sessions)');
1203
+ // Mark as running so we don't try to start a new one
1204
+ this.isRunning = true;
1205
+ this.process = { pid: healthInfo.pid }; // Track the existing process
1206
+ return; // Don't kill, don't clean socket - just reuse
1207
+ }
1208
+ }
1209
+ else {
1210
+ logger.debug('[EmbeddingServerManager] No PID file found, checking for orphaned processes');
1211
+ }
1212
+ // Step 2: Also check for orphaned processes (no PID file but process exists)
1213
+ await this.killOrphanedProcesses();
1214
+ // Step 3: Clean up old socket if exists
1215
+ if (existsSync(this.socketPath)) {
1216
+ try {
1217
+ unlinkSync(this.socketPath);
1218
+ logger.debug('[EmbeddingServerManager] Removed stale socket');
1219
+ }
1220
+ catch (err) {
1221
+ logger.debug({ error: err }, '[EmbeddingServerManager] Failed to remove stale socket');
1222
+ }
1223
+ }
1224
+ // Step 4: Clean up PID file if exists
1225
+ this.removePidFile();
1226
+ logger.info('[EmbeddingServerManager] Stale process cleanup complete');
1227
+ }
1228
+ /**
1229
+ * Kill a process using health info metadata
1230
+ */
1231
+ async killProcessWithHealthInfo(healthInfo) {
1232
+ const { pid, processAgeHours, pidFileAgeHours } = healthInfo;
1233
+ if (!healthInfo.processExists) {
1234
+ logger.debug({ pid }, '[EmbeddingServerManager] Process does not exist, nothing to kill');
1235
+ return;
1236
+ }
1237
+ try {
1238
+ logger.info({
1239
+ pid,
1240
+ processAge: processAgeHours?.toFixed(2) || 'unknown',
1241
+ pidFileAge: pidFileAgeHours.toFixed(2),
1242
+ commandLine: healthInfo.commandLine,
1243
+ }, '[EmbeddingServerManager] Killing process');
1244
+ // Try graceful SIGTERM first
1245
+ process.kill(pid, 'SIGTERM');
1246
+ await this.sleep(500);
1247
+ // Check if still running
1248
+ try {
1249
+ process.kill(pid, 0);
1250
+ // Still running - force kill
1251
+ process.kill(pid, 'SIGKILL');
1252
+ logger.debug({ pid }, '[EmbeddingServerManager] Force killed process with SIGKILL');
1253
+ }
1254
+ catch {
1255
+ // Already dead - good
1256
+ logger.debug({ pid }, '[EmbeddingServerManager] Process terminated gracefully');
1257
+ }
1258
+ }
1259
+ catch (err) {
1260
+ logger.debug({ pid, error: err }, '[EmbeddingServerManager] Failed to kill process (may already be dead)');
1261
+ }
1262
+ }
1263
+ /**
1264
+ * Find and kill orphaned embedding processes (no PID file)
1265
+ * Kills zombie frankenstein processes NOT tracked by any project's PID file
1266
+ * Preserves processes actively used by other SpecMem instances
1267
+ *
1268
+ * CRITICAL FIX: Socket path is passed via ENVIRONMENT VARIABLES, not command line!
1269
+ * So we find ALL frankenstein processes, then filter by checking /proc/PID/environ
1270
+ */
1271
+ async killOrphanedProcesses() {
1272
+ try {
1273
+ // FIX: Find ALL frankenstein processes (socket path is in env, not cmdline)
1274
+ // Then filter by checking each process's SPECMEM_EMBEDDING_SOCKET env var
1275
+ const result = execSync(`pgrep -f "frankenstein-embeddings.py" 2>/dev/null || true`, { encoding: 'utf8' }).trim();
1276
+ // Get ALL known PID files from ALL possible locations
1277
+ // These are processes actively tracked by running instances
1278
+ const trackedPids = new Set();
1279
+ // Search common PID file locations more comprehensively
1280
+ try {
1281
+ const pidFiles = execSync(`find /tmp ~/.specmem /specmem -name "embedding.pid" 2>/dev/null | xargs cat 2>/dev/null || true`, { encoding: 'utf8' }).trim();
1282
+ // PID files format: {PID}:{TIMESTAMP}
1283
+ for (const line of pidFiles.split('\n')) {
1284
+ if (!line.trim())
1285
+ continue;
1286
+ const pid = parseInt(line.split(':')[0], 10);
1287
+ if (!isNaN(pid))
1288
+ trackedPids.add(pid);
1289
+ }
1290
+ }
1291
+ catch { /* no pid files - all are orphans */ }
1292
+ // CRITICAL FIX: Also search for PID files in ANY project path
1293
+ // This catches project-specific socket directories like /newServer/specmem/sockets/
1294
+ try {
1295
+ const allProjectPids = execSync(`find / -path "*/specmem/sockets/embedding.pid" -o -path "*/.specmem/*/sockets/embedding.pid" 2>/dev/null | xargs cat 2>/dev/null || true`, { encoding: 'utf8', timeout: 5000 }).trim();
1296
+ for (const line of allProjectPids.split('\n')) {
1297
+ if (!line.trim())
1298
+ continue;
1299
+ const pid = parseInt(line.split(':')[0], 10);
1300
+ if (!isNaN(pid))
1301
+ trackedPids.add(pid);
1302
+ }
1303
+ }
1304
+ catch { /* filesystem search may be slow or fail - that's ok */ }
1305
+ if (result) {
1306
+ const pids = result.split('\n').filter(p => p.trim());
1307
+ const orphanPids = pids.filter(p => !trackedPids.has(parseInt(p, 10)));
1308
+ if (orphanPids.length > 0) {
1309
+ logger.info({
1310
+ orphanPids,
1311
+ trackedCount: trackedPids.size,
1312
+ totalFound: pids.length,
1313
+ thisProjectSocket: this.socketPath,
1314
+ }, '[EmbeddingServerManager] Found orphaned processes for THIS project (not tracked by PID file)');
1315
+ }
1316
+ for (const pidStr of orphanPids) {
1317
+ const pid = parseInt(pidStr, 10);
1318
+ if (isNaN(pid))
1319
+ continue;
1320
+ // Skip if tracked by another project
1321
+ if (trackedPids.has(pid)) {
1322
+ logger.debug({ pid }, '[EmbeddingServerManager] Skipping - tracked by another project');
1323
+ continue;
1324
+ }
1325
+ try {
1326
+ // Get process info before killing
1327
+ const healthInfo = this.getProcessInfoForOrphan(pid);
1328
+ const ageHours = healthInfo?.ageHours ?? null;
1329
+ const commandLine = healthInfo?.commandLine || '';
1330
+ // CRITICAL FIX: Double-check that process belongs to THIS project
1331
+ // First try reading socket path from process environment (most reliable)
1332
+ const processSocketPath = this.getProcessSocketPath(pid);
1333
+ if (processSocketPath && processSocketPath !== this.socketPath) {
1334
+ logger.warn({
1335
+ pid,
1336
+ processSocketPath,
1337
+ thisProjectSocket: this.socketPath,
1338
+ }, '[EmbeddingServerManager] SAFETY CHECK: Process socket path does not match this project - skipping kill');
1339
+ continue;
1340
+ }
1341
+ // Fallback: verify socket path is in command line
1342
+ if (!processSocketPath && !commandLine.includes(this.socketPath)) {
1343
+ logger.warn({
1344
+ pid,
1345
+ commandLine,
1346
+ thisProjectSocket: this.socketPath,
1347
+ }, '[EmbeddingServerManager] SAFETY CHECK: Process command line does not match this project - skipping kill');
1348
+ continue;
1349
+ }
1350
+ // Only kill if older than max age
1351
+ if (ageHours !== null && ageHours <= this.config.maxProcessAgeHours) {
1352
+ logger.info({
1353
+ pid,
1354
+ ageHours: ageHours.toFixed(2),
1355
+ maxAgeHours: this.config.maxProcessAgeHours,
1356
+ socketPath: this.socketPath,
1357
+ }, '[EmbeddingServerManager] Orphaned process is recent and belongs to this project, keeping it');
1358
+ continue;
1359
+ }
1360
+ logger.info({
1361
+ pid,
1362
+ ageHours: ageHours?.toFixed(2) || 'unknown',
1363
+ maxAgeHours: this.config.maxProcessAgeHours,
1364
+ commandLine: healthInfo?.commandLine || 'unknown',
1365
+ socketPath: this.socketPath,
1366
+ }, '[EmbeddingServerManager] Killing stale orphaned process for THIS project (zombie)');
1367
+ process.kill(pid, 'SIGTERM');
1368
+ await this.sleep(200);
1369
+ // Force kill if still running
1370
+ try {
1371
+ process.kill(pid, 0);
1372
+ process.kill(pid, 'SIGKILL');
1373
+ }
1374
+ catch {
1375
+ // Already dead
1376
+ }
1377
+ }
1378
+ catch (err) {
1379
+ logger.debug({ pid, error: err }, '[EmbeddingServerManager] Failed to kill orphaned process');
1380
+ }
1381
+ }
1382
+ }
1383
+ }
1384
+ catch (err) {
1385
+ // pgrep may not exist or may fail - that's OK
1386
+ logger.debug({ error: err }, '[EmbeddingServerManager] pgrep failed (may not exist)');
1387
+ }
1388
+ }
1389
+ /**
1390
+ * Get the SPECMEM_EMBEDDING_SOCKET env var from a running process
1391
+ * Returns the socket path this process is bound to, or null if not found
1392
+ */
1393
+ getProcessSocketPath(pid) {
1394
+ try {
1395
+ const environPath = `/proc/${pid}/environ`;
1396
+ if (!existsSync(environPath)) {
1397
+ return null;
1398
+ }
1399
+ const environ = readFileSync(environPath, 'utf8');
1400
+ // Environment variables are null-separated
1401
+ const envVars = environ.split('\0');
1402
+ for (const envVar of envVars) {
1403
+ if (envVar.startsWith('SPECMEM_EMBEDDING_SOCKET=')) {
1404
+ return envVar.split('=')[1];
1405
+ }
1406
+ }
1407
+ return null;
1408
+ }
1409
+ catch {
1410
+ return null;
1411
+ }
1412
+ }
1413
+ /**
1414
+ * Get process info for an orphaned process (no PID file)
1415
+ */
1416
+ getProcessInfoForOrphan(pid) {
1417
+ try {
1418
+ // Try to read /proc/[pid]/stat for start time
1419
+ const statPath = `/proc/${pid}/stat`;
1420
+ if (!existsSync(statPath)) {
1421
+ return null;
1422
+ }
1423
+ const statContent = readFileSync(statPath, 'utf8');
1424
+ const match = statContent.match(/\(.*?\)\s+(.*)$/);
1425
+ if (!match) {
1426
+ return null;
1427
+ }
1428
+ const fields = match[1].split(/\s+/);
1429
+ const startTimeJiffies = parseInt(fields[19], 10);
1430
+ if (!isNaN(startTimeJiffies)) {
1431
+ // Simple age calculation (not fully accurate but good enough)
1432
+ const uptimeContent = readFileSync('/proc/uptime', 'utf8');
1433
+ const uptimeSeconds = parseFloat(uptimeContent.split(/\s+/)[0]);
1434
+ const clockTicks = 100; // Standard for most systems
1435
+ const processStartSeconds = startTimeJiffies / clockTicks;
1436
+ const processAgeSeconds = uptimeSeconds - processStartSeconds;
1437
+ const ageHours = processAgeSeconds / 3600;
1438
+ // Get command line
1439
+ const cmdlinePath = `/proc/${pid}/cmdline`;
1440
+ let commandLine = null;
1441
+ if (existsSync(cmdlinePath)) {
1442
+ commandLine = readFileSync(cmdlinePath, 'utf8').replace(/\0/g, ' ').trim();
1443
+ }
1444
+ return { ageHours, commandLine };
1445
+ }
1446
+ }
1447
+ catch (err) {
1448
+ logger.debug({ pid, error: err }, '[EmbeddingServerManager] Failed to get orphan process info');
1449
+ }
1450
+ return null;
1451
+ }
1452
+ /**
1453
+ * Kill process by PID file (using robust health check)
1454
+ */
1455
+ async killByPidFile() {
1456
+ const healthInfo = checkProcessHealth({
1457
+ pidFilePath: this.pidFilePath,
1458
+ maxAgeHours: this.config.maxProcessAgeHours,
1459
+ expectedProcessName: 'frankenstein-embeddings',
1460
+ projectPath: this.projectPath,
1461
+ });
1462
+ if (!healthInfo) {
1463
+ logger.debug('[EmbeddingServerManager] No PID file found');
1464
+ return;
1465
+ }
1466
+ logger.debug({
1467
+ pid: healthInfo.pid,
1468
+ processExists: healthInfo.processExists,
1469
+ isEmbeddingServer: healthInfo.isEmbeddingServer,
1470
+ ageHours: healthInfo.processAgeHours?.toFixed(2) || 'unknown',
1471
+ recommendedAction: healthInfo.recommendedAction,
1472
+ statusMessage: healthInfo.statusMessage,
1473
+ }, '[EmbeddingServerManager] Checked PID file process');
1474
+ if (healthInfo.processExists) {
1475
+ await this.killProcessWithHealthInfo(healthInfo);
1476
+ }
1477
+ else {
1478
+ logger.debug({ pid: healthInfo.pid }, '[EmbeddingServerManager] Process from PID file no longer exists');
1479
+ }
1480
+ this.removePidFile();
1481
+ }
1482
+ /**
1483
+ * Find the embedding script path
1484
+ *
1485
+ * PRIORITY: frankenstein-embeddings.py (has ALL 4 optimizations + ACK verification)
1486
+ * > warm-start.sh (Docker)
1487
+ *
1488
+ * We NEVER use a model that hasn't been optimized with all 4 optimizations.
1489
+ */
1490
+ findEmbeddingScript() {
1491
+ // specmem root dir is 2 levels up from src/mcp/
1492
+ const specmemRoot = dirname(dirname(__dirname));
1493
+ // PRIORITY 1: frankenstein-embeddings.py (OPTIMIZED - has all 4 optimizations + ACK verification)
1494
+ const embeddingPaths = [
1495
+ // Project-local (development)
1496
+ join(this.projectPath, 'embedding-sandbox', 'frankenstein-embeddings.py'),
1497
+ // SpecMem package root (via __dirname - works for all installs)
1498
+ join(specmemRoot, 'embedding-sandbox', 'frankenstein-embeddings.py'),
1499
+ // Local npm install
1500
+ join(this.projectPath, 'node_modules', 'specmem-hardwicksoftware', 'embedding-sandbox', 'frankenstein-embeddings.py'),
1501
+ // Global npm install fallback (platform-agnostic)
1502
+ join(dirname(dirname(process.execPath)), 'lib', 'node_modules', 'specmem-hardwicksoftware', 'embedding-sandbox', 'frankenstein-embeddings.py'),
1503
+ ];
1504
+ for (const p of embeddingPaths) {
1505
+ if (existsSync(p)) {
1506
+ logger.info({ path: p }, '[EmbeddingServerManager] Using frankenstein-embeddings.py (all 4 optimizations + ACK verification)');
1507
+ return { script: p, useWarmStart: false };
1508
+ }
1509
+ }
1510
+ // PRIORITY 2: warm-start.sh (Docker-based)
1511
+ const warmStartPaths = [
1512
+ join(this.projectPath, 'embedding-sandbox', 'warm-start.sh'),
1513
+ join(specmemRoot, 'embedding-sandbox', 'warm-start.sh'),
1514
+ join(this.projectPath, 'node_modules', 'specmem-hardwicksoftware', 'embedding-sandbox', 'warm-start.sh'),
1515
+ join(dirname(dirname(process.execPath)), 'lib', 'node_modules', 'specmem-hardwicksoftware', 'embedding-sandbox', 'warm-start.sh'),
1516
+ ];
1517
+ for (const p of warmStartPaths) {
1518
+ if (existsSync(p)) {
1519
+ logger.info({ path: p }, '[EmbeddingServerManager] Using warm-start.sh (Docker mode)');
1520
+ return { script: p, useWarmStart: true };
1521
+ }
1522
+ }
1523
+ logger.error({ searchedPaths: [...embeddingPaths, ...warmStartPaths] }, '[EmbeddingServerManager] Embedding script not found');
1524
+ return null;
1525
+ }
1526
+ /**
1527
+ * Wait for socket file to appear AND server to be ready
1528
+ * FIX: Task #12 - Race condition fix: Poll with health checks instead of just file existence
1529
+ * The 60s timeout window was creating a race where socket file exists but server not ready
1530
+ */
1531
+ async waitForSocket() {
1532
+ const startTime = Date.now();
1533
+ const fileCheckInterval = 200; // fast initial polling for file
1534
+ // FIX: Increased health check interval to account for health check timeout (10s default)
1535
+ // Previous 500ms was too aggressive - health check itself takes up to 10s
1536
+ const healthCheckInterval = 1000; // 1 second between health check attempts
1537
+ // FIX: Removed fixed maxHealthCheckAttempts - now uses time-based cutoff only
1538
+ // This ensures we use the full startupTimeoutMs window instead of arbitrary attempt limit
1539
+ logger.debug({ socketPath: this.socketPath, timeoutMs: this.config.startupTimeoutMs }, '[EmbeddingServerManager] Waiting for socket with readiness polling');
1540
+ // Phase 1: Wait for socket file to appear (use 50% of timeout for file appearance)
1541
+ const fileWaitDeadline = startTime + (this.config.startupTimeoutMs * 0.5);
1542
+ while (Date.now() < fileWaitDeadline) {
1543
+ if (existsSync(this.socketPath)) {
1544
+ logger.debug({ elapsed: Date.now() - startTime }, '[EmbeddingServerManager] Socket file appeared, starting health check polling');
1545
+ break;
1546
+ }
1547
+ await this.sleep(fileCheckInterval);
1548
+ }
1549
+ if (!existsSync(this.socketPath)) {
1550
+ logger.error({ elapsed: Date.now() - startTime, timeoutMs: this.config.startupTimeoutMs }, '[EmbeddingServerManager] Socket file never appeared within timeout');
1551
+ return false;
1552
+ }
1553
+ // Phase 2: Poll health check until server responds
1554
+ // FIX: Use remaining time from startup timeout instead of fixed attempt count
1555
+ // This prevents the case where health checks + interval exceed the startup timeout
1556
+ let healthAttempts = 0;
1557
+ const healthCheckDeadline = startTime + this.config.startupTimeoutMs;
1558
+ while (Date.now() < healthCheckDeadline) {
1559
+ healthAttempts++;
1560
+ const healthResult = await this.healthCheck();
1561
+ if (healthResult.success) {
1562
+ logger.info({
1563
+ elapsed: Date.now() - startTime,
1564
+ healthAttempts,
1565
+ responseTimeMs: healthResult.responseTimeMs,
1566
+ dimensions: healthResult.dimensions,
1567
+ }, '[EmbeddingServerManager] Server ready - health check passed');
1568
+ return true;
1569
+ }
1570
+ // FIX: Check if we have enough time for another health check before sleeping
1571
+ const remainingTime = healthCheckDeadline - Date.now();
1572
+ if (remainingTime < healthCheckInterval) {
1573
+ logger.debug({
1574
+ attempt: healthAttempts,
1575
+ remainingMs: remainingTime,
1576
+ error: healthResult.error,
1577
+ }, '[EmbeddingServerManager] Health check failed, not enough time for another attempt');
1578
+ break;
1579
+ }
1580
+ logger.debug({
1581
+ attempt: healthAttempts,
1582
+ remainingMs: remainingTime,
1583
+ error: healthResult.error,
1584
+ }, '[EmbeddingServerManager] Health check failed, retrying...');
1585
+ await this.sleep(healthCheckInterval);
1586
+ }
1587
+ logger.error({
1588
+ elapsed: Date.now() - startTime,
1589
+ healthAttempts,
1590
+ socketExists: existsSync(this.socketPath),
1591
+ }, '[EmbeddingServerManager] Server never became ready - health checks exhausted');
1592
+ return false;
1593
+ }
1594
+ /**
1595
+ * Handle process exit
1596
+ */
1597
+ handleProcessExit(code, signal) {
1598
+ const wasRunning = this.isRunning;
1599
+ this.isRunning = false;
1600
+ // Only clear process if we actually had one (not external server)
1601
+ if (this.process) {
1602
+ this.process = null;
1603
+ }
1604
+ if (this.isShuttingDown) {
1605
+ // Expected exit during shutdown
1606
+ return;
1607
+ }
1608
+ logger.warn({ code, signal, wasRunning }, '[EmbeddingServerManager] Process exited unexpectedly');
1609
+ // Attempt restart if not shutting down
1610
+ this.attemptRestart();
1611
+ }
1612
+ /**
1613
+ * Attempt to restart the server
1614
+ */
1615
+ async attemptRestart() {
1616
+ // Phase 4: Don't restart if user manually stopped
1617
+ if (this.isStoppedByUser()) {
1618
+ logger.info('[EmbeddingServerManager] Skipping restart - stopped by user');
1619
+ return;
1620
+ }
1621
+ // Phase 4: Check for restart loop (>3 restarts in 60 seconds)
1622
+ const loopInfo = this.getRestartLoopInfo();
1623
+ if (loopInfo.inLoop) {
1624
+ logger.error({
1625
+ recentRestarts: loopInfo.recentRestarts,
1626
+ windowSeconds: 60,
1627
+ }, '[EmbeddingServerManager] RESTART LOOP DETECTED - backing off');
1628
+ this.emit('restart_loop', loopInfo);
1629
+ // Exponential backoff: wait 2^restartCount seconds (max 5 minutes)
1630
+ const backoffMs = Math.min(Math.pow(2, this.restartCount) * 1000, 300000);
1631
+ logger.info({ backoffMs }, '[EmbeddingServerManager] Waiting for exponential backoff');
1632
+ await this.sleep(backoffMs);
1633
+ }
1634
+ // Check cooldown
1635
+ const timeSinceLastRestart = Date.now() - this.lastRestartTime;
1636
+ if (timeSinceLastRestart < this.config.restartCooldownMs) {
1637
+ const waitTime = this.config.restartCooldownMs - timeSinceLastRestart;
1638
+ logger.debug({ waitTime }, '[EmbeddingServerManager] Waiting for restart cooldown');
1639
+ await this.sleep(waitTime);
1640
+ }
1641
+ // Check max restarts
1642
+ if (this.restartCount >= this.config.maxRestartAttempts) {
1643
+ logger.error({
1644
+ restartCount: this.restartCount,
1645
+ maxAttempts: this.config.maxRestartAttempts,
1646
+ }, '[EmbeddingServerManager] Max restart attempts reached');
1647
+ this.emit('restart_failed', { attempts: this.restartCount });
1648
+ return;
1649
+ }
1650
+ this.restartCount++;
1651
+ this.lastRestartTime = Date.now();
1652
+ // Phase 4: Track restart timestamp for loop detection
1653
+ this.restartTimestamps.push(Date.now());
1654
+ // Keep only last 10 timestamps
1655
+ if (this.restartTimestamps.length > 10) {
1656
+ this.restartTimestamps.shift();
1657
+ }
1658
+ logger.info({ attempt: this.restartCount }, '[EmbeddingServerManager] Attempting restart');
1659
+ this.emit('restarting', { attempt: this.restartCount });
1660
+ const success = await this.start();
1661
+ if (!success) {
1662
+ // Will retry on next health check
1663
+ logger.warn('[EmbeddingServerManager] Restart attempt failed');
1664
+ }
1665
+ }
1666
+ /**
1667
+ * Start health monitoring
1668
+ */
1669
+ startHealthMonitoring() {
1670
+ if (this.healthCheckTimer) {
1671
+ return;
1672
+ }
1673
+ this.healthCheckTimer = setInterval(async () => {
1674
+ const result = await this.healthCheck();
1675
+ this.emit('health', result);
1676
+ if (result.success) {
1677
+ // Reset failure counter on success
1678
+ if (this.consecutiveFailures > 0) {
1679
+ logger.info({
1680
+ responseTimeMs: result.responseTimeMs,
1681
+ dimensions: result.dimensions,
1682
+ previousFailures: this.consecutiveFailures,
1683
+ }, '[EmbeddingServerManager] Health check recovered - server is healthy');
1684
+ }
1685
+ else {
1686
+ logger.debug({
1687
+ responseTimeMs: result.responseTimeMs,
1688
+ dimensions: result.dimensions,
1689
+ }, '[EmbeddingServerManager] Health check successful');
1690
+ }
1691
+ this.consecutiveFailures = 0;
1692
+ }
1693
+ else {
1694
+ // FIX: During startup grace period, suppress failure counting and restart attempts
1695
+ // Grace period is dynamic, derived from config.startupTimeoutMs
1696
+ if (this.startupGraceUntil > 0 && Date.now() < this.startupGraceUntil) {
1697
+ const remainingMs = this.startupGraceUntil - Date.now();
1698
+ logger.debug({ remainingMs, error: result.error },
1699
+ '[EmbeddingServerManager] Health check failed during startup grace period - suppressing');
1700
+ return; // Don't count failures or attempt restarts during grace
1701
+ }
1702
+ // Clear expired grace period
1703
+ if (this.startupGraceUntil > 0 && Date.now() >= this.startupGraceUntil) {
1704
+ this.startupGraceUntil = 0;
1705
+ }
1706
+ // Check if server was killed by KYS watchdog - if so, auto-respawn immediately
1707
+ if (this.wasKilledByKYS()) {
1708
+ logger.info('[EmbeddingServerManager] Health check failed - server was killed by KYS watchdog, auto-respawning...');
1709
+ const respawned = await this.autoRespawnIfKYSDeath();
1710
+ if (respawned) {
1711
+ logger.info('[EmbeddingServerManager] Auto-respawn after KYS death successful');
1712
+ return; // Skip failure counting, server is back
1713
+ }
1714
+ }
1715
+ this.consecutiveFailures++;
1716
+ logger.warn({
1717
+ failures: this.consecutiveFailures,
1718
+ maxFailures: this.config.maxFailuresBeforeRestart,
1719
+ error: result.error,
1720
+ responseTimeMs: result.responseTimeMs,
1721
+ socketPath: this.socketPath,
1722
+ socketExists: existsSync(this.socketPath),
1723
+ }, '[EmbeddingServerManager] Health check failed');
1724
+ this.emit('unhealthy', { failures: this.consecutiveFailures });
1725
+ // Attempt restart if too many failures
1726
+ if (this.consecutiveFailures >= this.config.maxFailuresBeforeRestart) {
1727
+ logger.warn({
1728
+ failures: this.consecutiveFailures,
1729
+ maxFailures: this.config.maxFailuresBeforeRestart,
1730
+ restartCount: this.restartCount,
1731
+ }, '[EmbeddingServerManager] Too many consecutive failures, initiating restart...');
1732
+ this.consecutiveFailures = 0;
1733
+ await this.attemptRestart();
1734
+ }
1735
+ }
1736
+ // FIX 4: Duplicate process detection during health monitoring
1737
+ // Check for multiple embedding server processes and kill extras
1738
+ try {
1739
+ const runningServers = this.findRunningEmbeddingServers();
1740
+ if (runningServers.length > 1) {
1741
+ logger.error({
1742
+ count: runningServers.length,
1743
+ pids: runningServers.map(s => s.pid),
1744
+ }, '[EmbeddingServerManager] CRITICAL: Multiple embedding server processes detected!');
1745
+ // Determine the legitimate PID from PID file
1746
+ const legitimatePid = this.readPidFile();
1747
+ if (legitimatePid) {
1748
+ // Kill all processes that are NOT the legitimate one
1749
+ for (const server of runningServers) {
1750
+ if (server.pid !== legitimatePid) {
1751
+ try {
1752
+ logger.warn({ pid: server.pid, legitimatePid },
1753
+ '[EmbeddingServerManager] FIX 4: Killing duplicate embedding server process');
1754
+ process.kill(server.pid, 'SIGTERM');
1755
+ // Give it a moment, then force kill if needed
1756
+ setTimeout(() => {
1757
+ try {
1758
+ process.kill(server.pid, 0);
1759
+ process.kill(server.pid, 'SIGKILL');
1760
+ logger.warn({ pid: server.pid },
1761
+ '[EmbeddingServerManager] FIX 4: Force killed duplicate process');
1762
+ }
1763
+ catch { /* already dead */ }
1764
+ }, 2000);
1765
+ }
1766
+ catch (killErr) {
1767
+ logger.debug({ pid: server.pid, error: killErr.message },
1768
+ '[EmbeddingServerManager] FIX 4: Failed to kill duplicate (may be dead)');
1769
+ }
1770
+ }
1771
+ }
1772
+ }
1773
+ else {
1774
+ // No PID file - keep the first one, kill the rest
1775
+ logger.warn('[EmbeddingServerManager] FIX 4: No PID file found, keeping oldest process');
1776
+ for (let i = 1; i < runningServers.length; i++) {
1777
+ try {
1778
+ process.kill(runningServers[i].pid, 'SIGTERM');
1779
+ logger.warn({ pid: runningServers[i].pid },
1780
+ '[EmbeddingServerManager] FIX 4: Killing extra duplicate process');
1781
+ }
1782
+ catch { /* ignore */ }
1783
+ }
1784
+ }
1785
+ }
1786
+ }
1787
+ catch (dupErr) {
1788
+ logger.debug({ error: dupErr.message },
1789
+ '[EmbeddingServerManager] FIX 4: Duplicate detection check failed (non-fatal)');
1790
+ }
1791
+ }, this.config.healthCheckIntervalMs);
1792
+ // Don't prevent process exit
1793
+ this.healthCheckTimer.unref();
1794
+ logger.debug('[EmbeddingServerManager] Health monitoring started');
1795
+ }
1796
+ /**
1797
+ * Stop health monitoring
1798
+ */
1799
+ stopHealthMonitoring() {
1800
+ if (this.healthCheckTimer) {
1801
+ clearInterval(this.healthCheckTimer);
1802
+ this.healthCheckTimer = null;
1803
+ logger.debug('[EmbeddingServerManager] Health monitoring stopped');
1804
+ }
1805
+ }
1806
+ /**
1807
+ * Start KYS (Keep Yourself Safe) heartbeat - two-way ack system
1808
+ *
1809
+ * Sends {"type": "kys", "text": "kurt cobain t minus 25"} every 25 seconds.
1810
+ * If the embedding server doesn't receive this heartbeat within 30 seconds,
1811
+ * it commits suicide to prevent zombie processes.
1812
+ *
1813
+ * This prevents orphan embedding servers when MCP crashes or is killed.
1814
+ */
1815
+ startKysHeartbeat() {
1816
+ // Stop existing heartbeat if any
1817
+ this.stopKysHeartbeat();
1818
+ logger.info('[EmbeddingServerManager] Starting KYS heartbeat (every 25s)');
1819
+ this.kysHeartbeatTimer = setInterval(async () => {
1820
+ // FIX: Only skip if shutting down - heartbeat should still try for externally started servers
1821
+ if (this.isShuttingDown) {
1822
+ return;
1823
+ }
1824
+ try {
1825
+ const socket = createConnection(this.socketPath);
1826
+ let responded = false;
1827
+ socket.setTimeout(5000); // 5 second timeout for kys ack
1828
+ socket.on('connect', () => {
1829
+ socket.write(JSON.stringify({
1830
+ type: 'kys',
1831
+ text: 'kurt cobain t minus 25'
1832
+ }) + '\n');
1833
+ });
1834
+ socket.on('data', (data) => {
1835
+ responded = true;
1836
+ try {
1837
+ const response = JSON.parse(data.toString().trim());
1838
+ logger.debug({
1839
+ status: response.status,
1840
+ ack: response.ack,
1841
+ }, '[EmbeddingServerManager] KYS heartbeat acknowledged');
1842
+ }
1843
+ catch (e) {
1844
+ // Parse error, but we got data so server is alive
1845
+ }
1846
+ socket.destroy();
1847
+ });
1848
+ socket.on('error', (err) => {
1849
+ if (!responded) {
1850
+ logger.warn({ error: err.message }, '[EmbeddingServerManager] KYS heartbeat failed');
1851
+ }
1852
+ socket.destroy();
1853
+ });
1854
+ socket.on('timeout', () => {
1855
+ if (!responded) {
1856
+ logger.warn('[EmbeddingServerManager] KYS heartbeat timed out');
1857
+ }
1858
+ socket.destroy();
1859
+ });
1860
+ }
1861
+ catch (err) {
1862
+ logger.warn({ error: err.message }, '[EmbeddingServerManager] Failed to send KYS heartbeat');
1863
+ }
1864
+ }, this.KYS_HEARTBEAT_INTERVAL_MS);
1865
+ // Don't prevent process exit
1866
+ this.kysHeartbeatTimer.unref();
1867
+ }
1868
+ /**
1869
+ * Stop KYS heartbeat
1870
+ */
1871
+ stopKysHeartbeat() {
1872
+ if (this.kysHeartbeatTimer) {
1873
+ clearInterval(this.kysHeartbeatTimer);
1874
+ this.kysHeartbeatTimer = null;
1875
+ logger.debug('[EmbeddingServerManager] KYS heartbeat stopped');
1876
+ }
1877
+ }
1878
+ /**
1879
+ * Write PID file with timestamp
1880
+ */
1881
+ writePidFile(pid) {
1882
+ try {
1883
+ const pidDir = dirname(this.pidFilePath);
1884
+ if (!existsSync(pidDir)) {
1885
+ mkdirSync(pidDir, { recursive: true });
1886
+ }
1887
+ // Format: PID:TIMESTAMP
1888
+ writeFileSync(this.pidFilePath, `${pid}:${Date.now()}`, 'utf8');
1889
+ logger.debug({ pid, path: this.pidFilePath }, '[EmbeddingServerManager] Wrote PID file');
1890
+ }
1891
+ catch (err) {
1892
+ logger.error({ error: err }, '[EmbeddingServerManager] Failed to write PID file');
1893
+ }
1894
+ }
1895
+ /**
1896
+ * Read PID from file
1897
+ */
1898
+ readPidFile() {
1899
+ try {
1900
+ if (!existsSync(this.pidFilePath)) {
1901
+ return null;
1902
+ }
1903
+ const content = readFileSync(this.pidFilePath, 'utf8').trim();
1904
+ const pid = parseInt(content.split(':')[0], 10);
1905
+ return isNaN(pid) ? null : pid;
1906
+ }
1907
+ catch (err) {
1908
+ return null;
1909
+ }
1910
+ }
1911
+ /**
1912
+ * Read PID file with timestamp
1913
+ */
1914
+ readPidFileWithTimestamp() {
1915
+ try {
1916
+ if (!existsSync(this.pidFilePath)) {
1917
+ return null;
1918
+ }
1919
+ const content = readFileSync(this.pidFilePath, 'utf8').trim();
1920
+ const parts = content.split(':');
1921
+ const pid = parseInt(parts[0], 10);
1922
+ const timestamp = parseInt(parts[1], 10);
1923
+ if (isNaN(pid))
1924
+ return null;
1925
+ return { pid, timestamp: isNaN(timestamp) ? Date.now() : timestamp };
1926
+ }
1927
+ catch (err) {
1928
+ return null;
1929
+ }
1930
+ }
1931
+ /**
1932
+ * Remove PID file
1933
+ */
1934
+ removePidFile() {
1935
+ try {
1936
+ if (existsSync(this.pidFilePath)) {
1937
+ unlinkSync(this.pidFilePath);
1938
+ logger.debug('[EmbeddingServerManager] Removed PID file');
1939
+ }
1940
+ }
1941
+ catch (err) {
1942
+ logger.debug({ error: err }, '[EmbeddingServerManager] Failed to remove PID file');
1943
+ }
1944
+ }
1945
+ /**
1946
+ * FIX 6: Get process resource usage (CPU, memory) for the embedding server
1947
+ * Uses `ps -p PID -o pid,pcpu,pmem,rss,vsz` to get resource metrics
1948
+ * @returns {{ pid: number, cpu: number, memPercent: number, rss: number, vsz: number } | null}
1949
+ */
1950
+ getProcessResources() {
1951
+ const pid = this.readPidFile();
1952
+ if (!pid) return null;
1953
+ try {
1954
+ // Check process is alive first
1955
+ process.kill(pid, 0);
1956
+ const result = execSync(`ps -p ${pid} -o pid,pcpu,pmem,rss,vsz --no-headers`, {
1957
+ encoding: 'utf8',
1958
+ timeout: 5000,
1959
+ }).trim();
1960
+ if (!result) return null;
1961
+ const parts = result.trim().split(/\s+/);
1962
+ if (parts.length < 5) return null;
1963
+ return {
1964
+ pid: parseInt(parts[0], 10),
1965
+ cpu: parseFloat(parts[1]), // %CPU
1966
+ memPercent: parseFloat(parts[2]), // %MEM
1967
+ rss: parseInt(parts[3], 10), // RSS in KB
1968
+ vsz: parseInt(parts[4], 10), // VSZ in KB
1969
+ };
1970
+ }
1971
+ catch (err) {
1972
+ logger.debug({ pid, error: err.message }, '[EmbeddingServerManager] FIX 6: Failed to get process resources');
1973
+ return null;
1974
+ }
1975
+ }
1976
+ /**
1977
+ * FIX 6: Check resource limits and log warnings if exceeded
1978
+ * Warns if RSS > 6000MB or CPU > 80%
1979
+ * @returns {{ withinLimits: boolean, warnings: string[] }}
1980
+ */
1981
+ checkResourceLimits() {
1982
+ const resources = this.getProcessResources();
1983
+ if (!resources) {
1984
+ return { withinLimits: true, warnings: [] };
1985
+ }
1986
+ const warnings = [];
1987
+ const RSS_LIMIT_MB = 6000; // 6GB RSS limit
1988
+ const CPU_LIMIT_PCT = 80; // 80% CPU limit
1989
+ const rssMb = resources.rss / 1024; // Convert KB to MB
1990
+ if (rssMb > RSS_LIMIT_MB) {
1991
+ const msg = `Embedding server RSS memory (${rssMb.toFixed(0)}MB) exceeds limit (${RSS_LIMIT_MB}MB)`;
1992
+ warnings.push(msg);
1993
+ logger.warn({
1994
+ pid: resources.pid,
1995
+ rssMb: rssMb.toFixed(0),
1996
+ limitMb: RSS_LIMIT_MB,
1997
+ }, `[EmbeddingServerManager] FIX 6: RESOURCE WARNING - ${msg}`);
1998
+ }
1999
+ if (resources.cpu > CPU_LIMIT_PCT) {
2000
+ const msg = `Embedding server CPU usage (${resources.cpu.toFixed(1)}%) exceeds limit (${CPU_LIMIT_PCT}%)`;
2001
+ warnings.push(msg);
2002
+ logger.warn({
2003
+ pid: resources.pid,
2004
+ cpuPercent: resources.cpu.toFixed(1),
2005
+ limitPercent: CPU_LIMIT_PCT,
2006
+ }, `[EmbeddingServerManager] FIX 6: RESOURCE WARNING - ${msg}`);
2007
+ }
2008
+ if (warnings.length === 0) {
2009
+ logger.debug({
2010
+ pid: resources.pid,
2011
+ rssMb: rssMb.toFixed(0),
2012
+ cpuPercent: resources.cpu.toFixed(1),
2013
+ }, '[EmbeddingServerManager] FIX 6: Resource usage within limits');
2014
+ }
2015
+ return {
2016
+ withinLimits: warnings.length === 0,
2017
+ warnings,
2018
+ resources: {
2019
+ pid: resources.pid,
2020
+ cpuPercent: resources.cpu,
2021
+ rssMb: Math.round(rssMb),
2022
+ vszMb: Math.round(resources.vsz / 1024),
2023
+ memPercent: resources.memPercent,
2024
+ },
2025
+ };
2026
+ }
2027
+ /**
2028
+ * Sleep helper
2029
+ */
2030
+ sleep(ms) {
2031
+ return new Promise(resolve => setTimeout(resolve, ms));
2032
+ }
2033
+ }
2034
+ // ============================================================================
2035
+ // PER-PROJECT INSTANCE MAP
2036
+ // ============================================================================
2037
+ // FIX: Use per-project Map instead of global singleton
2038
+ // This prevents cross-project socket conflicts when running multiple instances
2039
+ const embeddingManagersByProject = new Map();
2040
+ /**
2041
+ * Get or create the embedding server manager for a specific project
2042
+ * Uses per-project Map pattern to ensure proper isolation
2043
+ */
2044
+ export function getEmbeddingServerManager(config) {
2045
+ const projectPath = getProjectPath();
2046
+ // Check if we already have a manager for this project
2047
+ if (embeddingManagersByProject.has(projectPath)) {
2048
+ return embeddingManagersByProject.get(projectPath);
2049
+ }
2050
+ // Create new manager for this project
2051
+ const manager = new EmbeddingServerManager(config);
2052
+ embeddingManagersByProject.set(projectPath, manager);
2053
+ logger.info({ projectPath, totalManagers: embeddingManagersByProject.size }, '[EmbeddingServerManager] Created new per-project manager');
2054
+ return manager;
2055
+ }
2056
+ /**
2057
+ * Reset the embedding server manager for a specific project (or current project)
2058
+ */
2059
+ export async function resetEmbeddingServerManager(projectPath) {
2060
+ const targetPath = projectPath || getProjectPath();
2061
+ if (embeddingManagersByProject.has(targetPath)) {
2062
+ const manager = embeddingManagersByProject.get(targetPath);
2063
+ await manager.shutdown();
2064
+ embeddingManagersByProject.delete(targetPath);
2065
+ logger.info({ projectPath: targetPath }, '[EmbeddingServerManager] Reset project manager');
2066
+ }
2067
+ }
2068
+ /**
2069
+ * Reset ALL embedding server managers (for global cleanup)
2070
+ */
2071
+ export async function resetAllEmbeddingServerManagers() {
2072
+ const promises = [];
2073
+ for (const [projectPath, manager] of embeddingManagersByProject) {
2074
+ promises.push(manager.shutdown().then(() => {
2075
+ logger.info({ projectPath }, '[EmbeddingServerManager] Shutdown manager');
2076
+ }));
2077
+ }
2078
+ await Promise.all(promises);
2079
+ embeddingManagersByProject.clear();
2080
+ }
2081
+ //# sourceMappingURL=embeddingServerManager.js.map