memorylink 1.0.0

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 (870) hide show
  1. package/.cursorrules +0 -0
  2. package/.github/workflows/buddy-check.yml +105 -0
  3. package/.github/workflows/memorylink-preflight.yml +63 -0
  4. package/.github/workflows/release-on-tag.yml +58 -0
  5. package/.github/workflows/stress-tests.yml +79 -0
  6. package/.memorylinkignore +24 -0
  7. package/5000_SCENARIOS_TEST_RESULTS.md +174 -0
  8. package/ADVANCED_SCENARIOS_TEST_RESULTS.md +377 -0
  9. package/AGGRESSIVE_RANDOM_TEST_RESULTS.md +134 -0
  10. package/AI_CONSENSUS_ANALYSIS.md +138 -0
  11. package/AI_CONSENSUS_ANALYSIS_FINAL.md +345 -0
  12. package/AI_CONSENSUS_ANALYSIS_v2.md +188 -0
  13. package/AI_CONSENSUS_ANALYSIS_v3.md +246 -0
  14. package/AI_CONSENSUS_ANALYSIS_v4.md +309 -0
  15. package/AI_CONSENSUS_ANALYSIS_v5.md +311 -0
  16. package/AI_CONSENSUS_ANALYSIS_v6.md +432 -0
  17. package/AI_PANEL_CLARIFICATION_REQUEST.md +37 -0
  18. package/AI_RESPONSES_BLACKBOX.md +338 -0
  19. package/AI_RESPONSES_CHATGPT.md +379 -0
  20. package/AI_RESPONSES_CLAUDE.md +464 -0
  21. package/AI_RESPONSES_CONSOLIDATED.md +560 -0
  22. package/AI_RESPONSES_DEEPSEEK.md +341 -0
  23. package/AI_RESPONSES_GEMINI.md +262 -0
  24. package/AI_RESPONSES_GROK.md +335 -0
  25. package/AI_RESPONSES_MANUS.md +246 -0
  26. package/AI_RESPONSES_PERPLEXITY.md +295 -0
  27. package/AI_RESPONSES_QWEN.md +335 -0
  28. package/AI_REVIEW_REQUEST.md +333 -0
  29. package/AI_STRATEGIC_CONSENSUS_COMPARISON.md +507 -0
  30. package/AI_VALIDATION_AND_GAP_ANALYSIS.md +410 -0
  31. package/ALL_10_AI_RESPONSES_FINAL.md +435 -0
  32. package/ALL_3_AI_RESPONSES_FINAL.md +305 -0
  33. package/ALL_4_AI_RESPONSES_FINAL.md +335 -0
  34. package/ALL_5_AI_RESPONSES_FINAL.md +349 -0
  35. package/ALL_6_AI_RESPONSES_FINAL.md +354 -0
  36. package/ALL_7_AI_RESPONSES_FINAL.md +369 -0
  37. package/ALL_8_AI_RESPONSES_FINAL.md +381 -0
  38. package/ALL_9_AI_RESPONSES_FINAL.md +398 -0
  39. package/ALL_AI_RESPONSES_TRACKER.md +152 -0
  40. package/ALL_AI_RESPONSES_VALIDATED.md +261 -0
  41. package/ALL_FEATURES_COMPLETE.md +198 -0
  42. package/BREAK_IT_TEST_RESULTS.md +273 -0
  43. package/BUDDY_CHECK_STRESS_TEST_PLAN.md +1089 -0
  44. package/CHANGELOG.md +135 -0
  45. package/CHATGPT_GAP_ANALYSIS.md +286 -0
  46. package/CHATGPT_V2_ANALYSIS.md +109 -0
  47. package/CHECK_MISSING_FEATURES.md +192 -0
  48. package/CI_CD_INTEGRATION.md +421 -0
  49. package/COMPETITIVE_LAUNCH_STRATEGY.md +257 -0
  50. package/COMPLETE_COMPETITIVE_ANALYSIS_ALL_AIS.md +339 -0
  51. package/COMPLETE_DEVELOPMENT_PLAN_ALL_AIS.md +622 -0
  52. package/COMPREHENSIVE_FEATURE_ANALYSIS_100_PERCENT.md +423 -0
  53. package/COMPREHENSIVE_TEST_SUMMARY.md +314 -0
  54. package/CONTINUOUS_TESTING_COMPLETE.md +268 -0
  55. package/CONTINUOUS_TESTING_GUIDE.md +328 -0
  56. package/CONTINUOUS_TEST_FINAL_RESULTS.md +148 -0
  57. package/CONTINUOUS_TEST_INSTRUCTIONS.md +173 -0
  58. package/CONTINUOUS_TEST_RESULTS.md +194 -0
  59. package/CONTINUOUS_TEST_STATUS.md +68 -0
  60. package/CURSOR_AI_BUDDY_CHECK_GUIDE.md +439 -0
  61. package/CURSOR_AI_INTEGRATION_GUIDE.md +775 -0
  62. package/CURSOR_AI_V1.4_NEXT_STEPS.md +314 -0
  63. package/CURSOR_BREAK_IT_TEST.md +389 -0
  64. package/CURSOR_DOCUMENTATION_RULES.md +259 -0
  65. package/CURSOR_HOSTILE_TEST_DOCUMENT.md +343 -0
  66. package/CURSOR_PROMPTS_FOR_TESTING.md +252 -0
  67. package/DEPLOYMENT_GUIDE.md +493 -0
  68. package/DEVELOPMENT_AND_OVERNIGHT_TESTING.md +304 -0
  69. package/DEVELOPMENT_PROGRESS.md +185 -0
  70. package/DOCS_CLEANUP_SUMMARY.md +192 -0
  71. package/DOC_CONFIDENTIALITY_RULES.md +259 -0
  72. package/E2E_TEST_REPORT_v1.3.0.md +196 -0
  73. package/E2E_TEST_RESULTS.md +250 -0
  74. package/E2E_TEST_SCENARIOS.md +357 -0
  75. package/END_TO_END_TEST_REPORT.md +217 -0
  76. package/ENHANCEMENT_RECOMMENDATIONS.md +368 -0
  77. package/EPIPE_FIX_SUMMARY.md +177 -0
  78. package/FEEDBACK_TEMPLATE.md +173 -0
  79. package/FINAL_100_PERCENT_CONFIRMATION.md +319 -0
  80. package/FINAL_8_AI_CONSENSUS_SUMMARY.md +355 -0
  81. package/FINAL_CONFIRMATION.md +143 -0
  82. package/FINAL_E2E_TEST_REPORT.md +248 -0
  83. package/FINAL_E2E_TEST_RESULTS.md +212 -0
  84. package/FINAL_LAUNCH_CLARIFICATION_SUMMARY.md +101 -0
  85. package/FINAL_LAUNCH_PLAN_BASED_ON_AI_CONSENSUS.md +410 -0
  86. package/FINAL_LAUNCH_SUMMARY.md +176 -0
  87. package/FINAL_PRODUCT_TEST.md +316 -0
  88. package/FINAL_PROJECT_STATUS.md +407 -0
  89. package/FINAL_STATUS_REPORT.md +244 -0
  90. package/FINAL_STRATEGIC_PLAN_9_AIS.md +576 -0
  91. package/FINAL_TEST_EXECUTION_REPORT.md +252 -0
  92. package/FINAL_VALIDATION_DOCUMENT.md +238 -0
  93. package/FINAL_VALIDATION_SUMMARY.md +230 -0
  94. package/FIX_SPECIAL_CHARS.sh +13 -0
  95. package/FRESH_SCENARIOS_TEST_RESULTS.md +358 -0
  96. package/GAP_EVALUATION_TEMPLATE.md +146 -0
  97. package/GITHUB_SETUP_GUIDE.md +193 -0
  98. package/HOSTILE_TEST_RESULTS.md +221 -0
  99. package/HOW_MEMORYLINK_HELPS_AI.md +401 -0
  100. package/IMPLEMENTATION_PLANS_DETAILED.md +516 -0
  101. package/LAUNCH_CHECKLIST.md +247 -0
  102. package/LAUNCH_DOCS_FRAMEWORK.md +378 -0
  103. package/LAUNCH_READINESS.md +148 -0
  104. package/LAUNCH_SEQUENCE.md +137 -0
  105. package/LICENSE +67 -0
  106. package/MARKET_ANALYSIS_AND_STRATEGY.md +280 -0
  107. package/MASTER_AI_VERIFICATION_DOCUMENT.md +1085 -0
  108. package/MASTER_VALIDATION_DOCUMENT.md +818 -0
  109. package/MINORITY_OPINION_ANALYSIS.md +464 -0
  110. package/NEW_RANDOM_TEST_RESULTS.md +127 -0
  111. package/NEW_SCENARIOS_TEST_RESULTS.md +272 -0
  112. package/NEXT_ACTIONS_COMPLETE.md +137 -0
  113. package/NEXT_PLAN_BASED_ON_AI_ANALYSES.md +413 -0
  114. package/NEXT_PLAN_BASED_ON_ALL_AI_RESPONSES.md +558 -0
  115. package/NEXT_STEPS.md +120 -0
  116. package/NEXT_STEPS_ACTION_PLAN.md +369 -0
  117. package/NPM_2FA_FIX.md +113 -0
  118. package/NPM_PUBLISH_TROUBLESHOOTING.md +230 -0
  119. package/PERPLEXITY_AI_VALIDATION_REQUEST.md +318 -0
  120. package/PERPLEXITY_AI_VALIDATION_RESPONSE.md +172 -0
  121. package/PERPLEXITY_BREAK_IT_VALIDATION.md +262 -0
  122. package/PERPLEXITY_DOCS_VALIDATION.md +237 -0
  123. package/PERPLEXITY_FEEDBACK_ACTION_PLAN.md +271 -0
  124. package/PERPLEXITY_FINAL_E2E_VALIDATION.md +210 -0
  125. package/PERPLEXITY_FINAL_SUMMARY.md +211 -0
  126. package/PERPLEXITY_PHASE2_VALIDATION.md +270 -0
  127. package/PERPLEXITY_PHASE2_VALIDATION_RESPONSE.md +136 -0
  128. package/PERPLEXITY_PRIORITY2_VALIDATION.md +321 -0
  129. package/PERPLEXITY_TELEMETRY_EXPLANATION.md +174 -0
  130. package/PERPLEXITY_TELEMETRY_VALIDATION.md +118 -0
  131. package/PERPLEXITY_TELEMETRY_VALIDATION_RESPONSE.md +154 -0
  132. package/PERPLEXITY_USER_GUIDE_VALIDATION.md +236 -0
  133. package/PERPLEXITY_VALIDATION_REQUEST.md +427 -0
  134. package/PERPLEXITY_VALIDATION_REQUEST_v1.5.1.md +190 -0
  135. package/PHASE_2_COMPLETE.md +149 -0
  136. package/PRE_LAUNCH_SECURITY_AUDIT.md +155 -0
  137. package/PRE_LAUNCH_TEST_CYCLE.md +326 -0
  138. package/PRE_LAUNCH_TEST_RESULTS.md +148 -0
  139. package/PROJECT_STRUCTURE_PLAN.md +104 -0
  140. package/PUBLIC_DOCS.md +90 -0
  141. package/PUBLISH_CHECKLIST.md +134 -0
  142. package/PUSH_INSTRUCTIONS.md +120 -0
  143. package/QUICK_START_TEST_CYCLE.md +76 -0
  144. package/README.md +557 -0
  145. package/README_TEST_INSTRUCTIONS.md +65 -0
  146. package/README_v1.5.1.md +137 -0
  147. package/REALISTIC_ASSESSMENT.md +186 -0
  148. package/REAL_WORLD_VALIDATION_COMPLETE.md +98 -0
  149. package/RED_TEAM_TESTING_GUIDE.md +302 -0
  150. package/RELEASE_NOTES_v1.0.0.md +125 -0
  151. package/RELEASE_NOTES_v1.5.1.md +105 -0
  152. package/REQUEST_COUNTERS.md +22 -0
  153. package/ROADMAP_v1.6.md +335 -0
  154. package/ROUND3_RANDOM_TEST_RESULTS.md +135 -0
  155. package/SECURITY_MODEL.md +577 -0
  156. package/SESSION_SUMMARY_CURRENT_STATE.md +206 -0
  157. package/SESSION_SUMMARY_REVIEW.md +203 -0
  158. package/SINGLE_RUN_ALL_SCENARIOS_TEST.sh +129 -0
  159. package/STRATEGIC_QUESTIONS_FOR_AI_VALIDATION.md +277 -0
  160. package/STRESS_TEST_CHECK_RESULTS.md +154 -0
  161. package/STRESS_TEST_EXECUTION_GUIDE.md +284 -0
  162. package/STRESS_TEST_IMPLEMENTATION_SUMMARY.md +221 -0
  163. package/TELEMETRY.md +370 -0
  164. package/TELEMETRY_COMPLETE_SUMMARY.md +231 -0
  165. package/TELEMETRY_CONTROL_POLICY.md +135 -0
  166. package/TELEMETRY_DESIGN_SUMMARY.md +210 -0
  167. package/TELEMETRY_FINAL_STATUS.md +178 -0
  168. package/TELEMETRY_NEXT_STEPS.md +258 -0
  169. package/TELEMETRY_TESTING_NOTES.md +217 -0
  170. package/TELEMETRY_WORK_COMPLETE.md +237 -0
  171. package/TEST_PLAN_v1.0.1.md +194 -0
  172. package/TEST_RESULTS_SUMMARY.md +128 -0
  173. package/TREE_SITTER_EXPLANATION.md +303 -0
  174. package/TROUBLESHOOTING.md +62 -0
  175. package/ULTIMATE_SCENARIOS_TEST_RESULTS.md +366 -0
  176. package/USER_FEEDBACK_TEMPLATE.md +104 -0
  177. package/USER_GUIDE.md +809 -0
  178. package/V1.1_DEVELOPMENT_COMPLETE.md +299 -0
  179. package/V1.1_SCENARIOS_ADDED.md +161 -0
  180. package/V1.2_CODE_STRUCTURE_IMPLEMENTATION.md +243 -0
  181. package/V1.3_COMPETITIVE_LAUNCH_COMPLETE.md +253 -0
  182. package/V1.3_COMPETITIVE_LAUNCH_IMPLEMENTATION_PLAN.md +385 -0
  183. package/V1.3_TEAM_PATTERNS_IMPLEMENTATION.md +183 -0
  184. package/V1.4_BUILD_PLAN_IMPLEMENTATION.md +698 -0
  185. package/V1.4_COMPLETE_SUMMARY_FOR_AI_REVIEW.md +516 -0
  186. package/V1.4_COMPLETE_VALIDATION_DOCUMENT.md +601 -0
  187. package/V1.4_DEVELOPMENT_PROGRESS.md +117 -0
  188. package/V1.4_FINAL_STATUS.md +147 -0
  189. package/V1.4_INTEGRATION_COMPLETE.md +207 -0
  190. package/V1.4_INTEGRATION_TEST_RESULTS.md +181 -0
  191. package/V1.4_OBSERVABILITY_AND_OVERRIDE_COMPLETE.md +180 -0
  192. package/V1.4_PHASE_3_COMPLETE.md +135 -0
  193. package/V1.4_RUNTIME_TESTING_GUIDE.md +364 -0
  194. package/V1.4_VERIFICATION_REPORT.md +199 -0
  195. package/V1.5.1_COMPLETE_SUMMARY.md +234 -0
  196. package/V1.5.1_RELEASE_NOTES.md +206 -0
  197. package/V1.5.1_RELEASE_READY.md +198 -0
  198. package/V1.5_COMPLETE_SUMMARY.md +264 -0
  199. package/V1.5_COMPLETE_VERIFICATION.md +183 -0
  200. package/V1.5_DESIGN_NOTES.md +272 -0
  201. package/V1.5_FINAL_STATUS.md +224 -0
  202. package/V1.5_IMPLEMENTATION_SUMMARY.md +113 -0
  203. package/V1.5_IMPROVEMENTS_COMPLETE.md +205 -0
  204. package/V1.5_PHASE1_COMPLETE.md +183 -0
  205. package/V1.5_PHASE1_PROGRESS.md +102 -0
  206. package/V1.5_PHASE2_COMPLETE.md +133 -0
  207. package/V1.5_PHASE2_PLAN.md +185 -0
  208. package/V1.5_PRIORITIZATION.md +313 -0
  209. package/V1.5_PRIORITY2_COMPLETE.md +150 -0
  210. package/V1.5_TESTING_COMPLETE.md +69 -0
  211. package/V1.5_TEST_RESULTS.md +178 -0
  212. package/V1.5_VALIDATION_RESULTS.md +209 -0
  213. package/V1.6_GAP_TRACKING.md +118 -0
  214. package/VALIDATION_SUMMARY_FOR_PERPLEXITY.md +83 -0
  215. package/VERIFICATION_REPORT.md +220 -0
  216. package/VERSION_UPDATE_VERIFICATION.md +76 -0
  217. package/config/tsconfig.json +21 -0
  218. package/dist/cli.d.ts +9 -0
  219. package/dist/cli.d.ts.map +1 -0
  220. package/dist/cli.js +1114 -0
  221. package/dist/cli.js.map +1 -0
  222. package/dist/commands/archive.d.ts +20 -0
  223. package/dist/commands/archive.d.ts.map +1 -0
  224. package/dist/commands/archive.js +231 -0
  225. package/dist/commands/archive.js.map +1 -0
  226. package/dist/commands/auto-context.d.ts +22 -0
  227. package/dist/commands/auto-context.d.ts.map +1 -0
  228. package/dist/commands/auto-context.js +172 -0
  229. package/dist/commands/auto-context.js.map +1 -0
  230. package/dist/commands/auto-log.d.ts +30 -0
  231. package/dist/commands/auto-log.d.ts.map +1 -0
  232. package/dist/commands/auto-log.js +500 -0
  233. package/dist/commands/auto-log.js.map +1 -0
  234. package/dist/commands/change.d.ts +13 -0
  235. package/dist/commands/change.d.ts.map +1 -0
  236. package/dist/commands/change.js +254 -0
  237. package/dist/commands/change.js.map +1 -0
  238. package/dist/commands/checkpoint.d.ts +26 -0
  239. package/dist/commands/checkpoint.d.ts.map +1 -0
  240. package/dist/commands/checkpoint.js +326 -0
  241. package/dist/commands/checkpoint.js.map +1 -0
  242. package/dist/commands/configure.d.ts +21 -0
  243. package/dist/commands/configure.d.ts.map +1 -0
  244. package/dist/commands/configure.js +283 -0
  245. package/dist/commands/configure.js.map +1 -0
  246. package/dist/commands/consolidate.d.ts +19 -0
  247. package/dist/commands/consolidate.d.ts.map +1 -0
  248. package/dist/commands/consolidate.js +236 -0
  249. package/dist/commands/consolidate.js.map +1 -0
  250. package/dist/commands/context.d.ts +10 -0
  251. package/dist/commands/context.d.ts.map +1 -0
  252. package/dist/commands/context.js +571 -0
  253. package/dist/commands/context.js.map +1 -0
  254. package/dist/commands/detect.d.ts +13 -0
  255. package/dist/commands/detect.d.ts.map +1 -0
  256. package/dist/commands/detect.js +187 -0
  257. package/dist/commands/detect.js.map +1 -0
  258. package/dist/commands/doctor.d.ts +19 -0
  259. package/dist/commands/doctor.d.ts.map +1 -0
  260. package/dist/commands/doctor.js +1272 -0
  261. package/dist/commands/doctor.js.map +1 -0
  262. package/dist/commands/export.d.ts +3 -0
  263. package/dist/commands/export.d.ts.map +1 -0
  264. package/dist/commands/export.js +95 -0
  265. package/dist/commands/export.js.map +1 -0
  266. package/dist/commands/graph.d.ts +25 -0
  267. package/dist/commands/graph.d.ts.map +1 -0
  268. package/dist/commands/graph.js +208 -0
  269. package/dist/commands/graph.js.map +1 -0
  270. package/dist/commands/hooks.d.ts +9 -0
  271. package/dist/commands/hooks.d.ts.map +1 -0
  272. package/dist/commands/hooks.js +240 -0
  273. package/dist/commands/hooks.js.map +1 -0
  274. package/dist/commands/impact.d.ts +18 -0
  275. package/dist/commands/impact.d.ts.map +1 -0
  276. package/dist/commands/impact.js +163 -0
  277. package/dist/commands/impact.js.map +1 -0
  278. package/dist/commands/index-vector.d.ts +13 -0
  279. package/dist/commands/index-vector.d.ts.map +1 -0
  280. package/dist/commands/index-vector.js +103 -0
  281. package/dist/commands/index-vector.js.map +1 -0
  282. package/dist/commands/index.d.ts +37 -0
  283. package/dist/commands/index.d.ts.map +1 -0
  284. package/dist/commands/index.js +105 -0
  285. package/dist/commands/index.js.map +1 -0
  286. package/dist/commands/init.d.ts +8 -0
  287. package/dist/commands/init.d.ts.map +1 -0
  288. package/dist/commands/init.js +200 -0
  289. package/dist/commands/init.js.map +1 -0
  290. package/dist/commands/inject.d.ts +22 -0
  291. package/dist/commands/inject.d.ts.map +1 -0
  292. package/dist/commands/inject.js +394 -0
  293. package/dist/commands/inject.js.map +1 -0
  294. package/dist/commands/learn.d.ts +13 -0
  295. package/dist/commands/learn.d.ts.map +1 -0
  296. package/dist/commands/learn.js +282 -0
  297. package/dist/commands/learn.js.map +1 -0
  298. package/dist/commands/lock.d.ts +35 -0
  299. package/dist/commands/lock.d.ts.map +1 -0
  300. package/dist/commands/lock.js +308 -0
  301. package/dist/commands/lock.js.map +1 -0
  302. package/dist/commands/memory.d.ts +15 -0
  303. package/dist/commands/memory.d.ts.map +1 -0
  304. package/dist/commands/memory.js +366 -0
  305. package/dist/commands/memory.js.map +1 -0
  306. package/dist/commands/migrate.d.ts +22 -0
  307. package/dist/commands/migrate.d.ts.map +1 -0
  308. package/dist/commands/migrate.js +458 -0
  309. package/dist/commands/migrate.js.map +1 -0
  310. package/dist/commands/patterns.d.ts +18 -0
  311. package/dist/commands/patterns.d.ts.map +1 -0
  312. package/dist/commands/patterns.js +120 -0
  313. package/dist/commands/patterns.js.map +1 -0
  314. package/dist/commands/protect.d.ts +12 -0
  315. package/dist/commands/protect.d.ts.map +1 -0
  316. package/dist/commands/protect.js +181 -0
  317. package/dist/commands/protect.js.map +1 -0
  318. package/dist/commands/quickstart.d.ts +11 -0
  319. package/dist/commands/quickstart.d.ts.map +1 -0
  320. package/dist/commands/quickstart.js +256 -0
  321. package/dist/commands/quickstart.js.map +1 -0
  322. package/dist/commands/repair.d.ts +13 -0
  323. package/dist/commands/repair.d.ts.map +1 -0
  324. package/dist/commands/repair.js +157 -0
  325. package/dist/commands/repair.js.map +1 -0
  326. package/dist/commands/resolve.d.ts +19 -0
  327. package/dist/commands/resolve.d.ts.map +1 -0
  328. package/dist/commands/resolve.js +355 -0
  329. package/dist/commands/resolve.js.map +1 -0
  330. package/dist/commands/roadmap.d.ts +5 -0
  331. package/dist/commands/roadmap.d.ts.map +1 -0
  332. package/dist/commands/roadmap.js +23 -0
  333. package/dist/commands/roadmap.js.map +1 -0
  334. package/dist/commands/scopes.d.ts +10 -0
  335. package/dist/commands/scopes.d.ts.map +1 -0
  336. package/dist/commands/scopes.js +80 -0
  337. package/dist/commands/scopes.js.map +1 -0
  338. package/dist/commands/search.d.ts +9 -0
  339. package/dist/commands/search.d.ts.map +1 -0
  340. package/dist/commands/search.js +313 -0
  341. package/dist/commands/search.js.map +1 -0
  342. package/dist/commands/setup.d.ts +13 -0
  343. package/dist/commands/setup.d.ts.map +1 -0
  344. package/dist/commands/setup.js +405 -0
  345. package/dist/commands/setup.js.map +1 -0
  346. package/dist/commands/snippet.d.ts +23 -0
  347. package/dist/commands/snippet.d.ts.map +1 -0
  348. package/dist/commands/snippet.js +235 -0
  349. package/dist/commands/snippet.js.map +1 -0
  350. package/dist/commands/stats.d.ts +15 -0
  351. package/dist/commands/stats.d.ts.map +1 -0
  352. package/dist/commands/stats.js +502 -0
  353. package/dist/commands/stats.js.map +1 -0
  354. package/dist/commands/status.d.ts +8 -0
  355. package/dist/commands/status.d.ts.map +1 -0
  356. package/dist/commands/status.js +134 -0
  357. package/dist/commands/status.js.map +1 -0
  358. package/dist/commands/suggest-tags.d.ts +9 -0
  359. package/dist/commands/suggest-tags.d.ts.map +1 -0
  360. package/dist/commands/suggest-tags.js +95 -0
  361. package/dist/commands/suggest-tags.js.map +1 -0
  362. package/dist/commands/sync-rules.d.ts +14 -0
  363. package/dist/commands/sync-rules.d.ts.map +1 -0
  364. package/dist/commands/sync-rules.js +211 -0
  365. package/dist/commands/sync-rules.js.map +1 -0
  366. package/dist/commands/sync.d.ts +24 -0
  367. package/dist/commands/sync.d.ts.map +1 -0
  368. package/dist/commands/sync.js +330 -0
  369. package/dist/commands/sync.js.map +1 -0
  370. package/dist/commands/telemetry-test.d.ts +24 -0
  371. package/dist/commands/telemetry-test.d.ts.map +1 -0
  372. package/dist/commands/telemetry-test.js +84 -0
  373. package/dist/commands/telemetry-test.js.map +1 -0
  374. package/dist/commands/template.d.ts +16 -0
  375. package/dist/commands/template.d.ts.map +1 -0
  376. package/dist/commands/template.js +122 -0
  377. package/dist/commands/template.js.map +1 -0
  378. package/dist/commands/validate.d.ts +11 -0
  379. package/dist/commands/validate.d.ts.map +1 -0
  380. package/dist/commands/validate.js +144 -0
  381. package/dist/commands/validate.js.map +1 -0
  382. package/dist/commands/watch-preferences.d.ts +17 -0
  383. package/dist/commands/watch-preferences.d.ts.map +1 -0
  384. package/dist/commands/watch-preferences.js +172 -0
  385. package/dist/commands/watch-preferences.js.map +1 -0
  386. package/dist/commands/watch.d.ts +11 -0
  387. package/dist/commands/watch.d.ts.map +1 -0
  388. package/dist/commands/watch.js +223 -0
  389. package/dist/commands/watch.js.map +1 -0
  390. package/dist/config/thresholds.d.ts +8 -0
  391. package/dist/config/thresholds.d.ts.map +1 -0
  392. package/dist/config/thresholds.js +10 -0
  393. package/dist/config/thresholds.js.map +1 -0
  394. package/dist/index.d.ts +9 -0
  395. package/dist/index.d.ts.map +1 -0
  396. package/dist/index.js +31 -0
  397. package/dist/index.js.map +1 -0
  398. package/dist/memorylink.d.ts +91 -0
  399. package/dist/memorylink.d.ts.map +1 -0
  400. package/dist/memorylink.js +208 -0
  401. package/dist/memorylink.js.map +1 -0
  402. package/dist/search/local-embeddings.d.ts +21 -0
  403. package/dist/search/local-embeddings.d.ts.map +1 -0
  404. package/dist/search/local-embeddings.js +87 -0
  405. package/dist/search/local-embeddings.js.map +1 -0
  406. package/dist/search/vector-search.d.ts +58 -0
  407. package/dist/search/vector-search.d.ts.map +1 -0
  408. package/dist/search/vector-search.js +535 -0
  409. package/dist/search/vector-search.js.map +1 -0
  410. package/dist/server/mcp-server.d.ts +18 -0
  411. package/dist/server/mcp-server.d.ts.map +1 -0
  412. package/dist/server/mcp-server.js +293 -0
  413. package/dist/server/mcp-server.js.map +1 -0
  414. package/dist/telemetry.d.ts +92 -0
  415. package/dist/telemetry.d.ts.map +1 -0
  416. package/dist/telemetry.js +339 -0
  417. package/dist/telemetry.js.map +1 -0
  418. package/dist/telemetry.test.d.ts +13 -0
  419. package/dist/telemetry.test.d.ts.map +1 -0
  420. package/dist/telemetry.test.js +324 -0
  421. package/dist/telemetry.test.js.map +1 -0
  422. package/dist/test-runner/TestRunner.d.ts +68 -0
  423. package/dist/test-runner/TestRunner.d.ts.map +1 -0
  424. package/dist/test-runner/TestRunner.js +384 -0
  425. package/dist/test-runner/TestRunner.js.map +1 -0
  426. package/dist/test-runner/performance-test.d.ts +36 -0
  427. package/dist/test-runner/performance-test.d.ts.map +1 -0
  428. package/dist/test-runner/performance-test.js +163 -0
  429. package/dist/test-runner/performance-test.js.map +1 -0
  430. package/dist/test-runner/run-tests.d.ts +7 -0
  431. package/dist/test-runner/run-tests.d.ts.map +1 -0
  432. package/dist/test-runner/run-tests.js +167 -0
  433. package/dist/test-runner/run-tests.js.map +1 -0
  434. package/dist/types.d.ts +400 -0
  435. package/dist/types.d.ts.map +1 -0
  436. package/dist/types.js +81 -0
  437. package/dist/types.js.map +1 -0
  438. package/dist/utils/batch-commits.d.ts +48 -0
  439. package/dist/utils/batch-commits.d.ts.map +1 -0
  440. package/dist/utils/batch-commits.js +164 -0
  441. package/dist/utils/batch-commits.js.map +1 -0
  442. package/dist/utils/code-structure.d.ts +62 -0
  443. package/dist/utils/code-structure.d.ts.map +1 -0
  444. package/dist/utils/code-structure.js +582 -0
  445. package/dist/utils/code-structure.js.map +1 -0
  446. package/dist/utils/commit-patterns.d.ts +24 -0
  447. package/dist/utils/commit-patterns.d.ts.map +1 -0
  448. package/dist/utils/commit-patterns.js +78 -0
  449. package/dist/utils/commit-patterns.js.map +1 -0
  450. package/dist/utils/observability.d.ts +47 -0
  451. package/dist/utils/observability.d.ts.map +1 -0
  452. package/dist/utils/observability.js +137 -0
  453. package/dist/utils/observability.js.map +1 -0
  454. package/dist/utils/quality.d.ts +32 -0
  455. package/dist/utils/quality.d.ts.map +1 -0
  456. package/dist/utils/quality.js +207 -0
  457. package/dist/utils/quality.js.map +1 -0
  458. package/dist/utils/semantic-search.d.ts +29 -0
  459. package/dist/utils/semantic-search.d.ts.map +1 -0
  460. package/dist/utils/semantic-search.js +167 -0
  461. package/dist/utils/semantic-search.js.map +1 -0
  462. package/dist/utils/streaming.d.ts +24 -0
  463. package/dist/utils/streaming.d.ts.map +1 -0
  464. package/dist/utils/streaming.js +121 -0
  465. package/dist/utils/streaming.js.map +1 -0
  466. package/dist/utils/tag-suggestions.d.ts +18 -0
  467. package/dist/utils/tag-suggestions.d.ts.map +1 -0
  468. package/dist/utils/tag-suggestions.js +103 -0
  469. package/dist/utils/tag-suggestions.js.map +1 -0
  470. package/dist/utils/team-patterns.d.ts +48 -0
  471. package/dist/utils/team-patterns.d.ts.map +1 -0
  472. package/dist/utils/team-patterns.js +413 -0
  473. package/dist/utils/team-patterns.js.map +1 -0
  474. package/dist/utils/templates.d.ts +36 -0
  475. package/dist/utils/templates.d.ts.map +1 -0
  476. package/dist/utils/templates.js +200 -0
  477. package/dist/utils/templates.js.map +1 -0
  478. package/dist/utils/tree-sitter-parser.d.ts +20 -0
  479. package/dist/utils/tree-sitter-parser.d.ts.map +1 -0
  480. package/dist/utils/tree-sitter-parser.js +259 -0
  481. package/dist/utils/tree-sitter-parser.js.map +1 -0
  482. package/dist/utils/v1.6-patterns.d.ts +117 -0
  483. package/dist/utils/v1.6-patterns.d.ts.map +1 -0
  484. package/dist/utils/v1.6-patterns.js +201 -0
  485. package/dist/utils/v1.6-patterns.js.map +1 -0
  486. package/dist/utils.d.ts +176 -0
  487. package/dist/utils.d.ts.map +1 -0
  488. package/dist/utils.js +822 -0
  489. package/dist/utils.js.map +1 -0
  490. package/docs/1000_SCENARIOS_TEST_RESULTS.md +138 -0
  491. package/docs/1000_UNIQUE_SCENARIOS_TEST.md +171 -0
  492. package/docs/100_PERCENT_PASS_RATE_VERIFICATION.md +111 -0
  493. package/docs/5000_SCENARIOS_ISSUE_ANALYSIS.md +96 -0
  494. package/docs/5000_SCENARIOS_TEST_PLAN.md +281 -0
  495. package/docs/AGENT_CONTRACT.md +240 -0
  496. package/docs/AI_RESPONSE_ANALYZER.md +157 -0
  497. package/docs/AI_RESPONSE_TRACKER.md +923 -0
  498. package/docs/AI_TESTING_PROMPT.md +307 -0
  499. package/docs/AI_VALIDATION_PROMPTS.md +366 -0
  500. package/docs/ALL_AI_ANALYSES_CONSOLIDATED.md +354 -0
  501. package/docs/ALL_AI_CONSOLIDATION_FINAL.md +372 -0
  502. package/docs/ALL_AI_TEST_CONSOLIDATION.md +290 -0
  503. package/docs/ALL_AI_VALIDATION_SYNTHESIS.md +241 -0
  504. package/docs/BEST_TESTING_SOLUTION.md +227 -0
  505. package/docs/BLACKBOX_AI_ANALYSIS.md +288 -0
  506. package/docs/BLACKBOX_AI_CLARIFICATION.md +55 -0
  507. package/docs/BLACKBOX_AI_STRATEGIC_VALIDATION.md +283 -0
  508. package/docs/BLACKBOX_AI_VALIDATION_RESPONSE.md +251 -0
  509. package/docs/BLACKBOX_AI_VALIDATION_RESPONSE_v2.md +402 -0
  510. package/docs/BLACKBOX_LAUNCH_VALIDATION.md +25 -0
  511. package/docs/BLACKBOX_SUPERMEMORY_VALIDATION_AND_PLAN.md +50 -0
  512. package/docs/CAPACITY_AND_ALTERNATIVES_ANALYSIS.md +289 -0
  513. package/docs/CHATGPT_AI_CLARIFICATION.md +65 -0
  514. package/docs/CHATGPT_FINAL_VALIDATION.md +348 -0
  515. package/docs/CHATGPT_IMPLEMENTATION_GUIDE.md +325 -0
  516. package/docs/CHATGPT_LAUNCH_VALIDATION.md +47 -0
  517. package/docs/CHATGPT_MEMORY_QUALITY_AND_VSCODE_CHECK.md +43 -0
  518. package/docs/CHATGPT_SCOPE_REALITY_CHECK.md +35 -0
  519. package/docs/CHATGPT_STRATEGIC_VALIDATION.md +329 -0
  520. package/docs/CHATGPT_VALIDATION_RESPONSE.md +332 -0
  521. package/docs/CHATGPT_VALIDATION_RESPONSE_v2.md +294 -0
  522. package/docs/CHATGPT_VALIDATION_RESULTS.md +143 -0
  523. package/docs/CLAUDE_AI_ANALYSIS.md +692 -0
  524. package/docs/CLAUDE_AI_CLARIFICATION.md +67 -0
  525. package/docs/CLAUDE_AI_STRATEGIC_VALIDATION.md +578 -0
  526. package/docs/CLAUDE_AI_VALIDATION_RESPONSE.md +374 -0
  527. package/docs/CLAUDE_AI_VALIDATION_RESPONSE_v2.md +463 -0
  528. package/docs/CLAUDE_FINAL_VALIDATION.md +679 -0
  529. package/docs/CLAUDE_LAUNCH_VALIDATION.md +27 -0
  530. package/docs/CLAUDE_SUPERMEMORY_LAUNCH_PRIORITIES.md +44 -0
  531. package/docs/CLAUDE_UNIVERSAL_VISION.md +18 -0
  532. package/docs/COMPLETE_AI_VALIDATION_SYNTHESIS.md +229 -0
  533. package/docs/COMPLETE_MEMORY_ANALYSIS_SUMMARY.md +323 -0
  534. package/docs/COMPLETE_STRATEGIC_LAUNCH_PLAN.md +241 -0
  535. package/docs/COPILOT_LANGCHAIN_MEMORY_COMPARISON_AND_PLAN.md +43 -0
  536. package/docs/CRITICAL_FIXES_ACTION_PLAN.md +251 -0
  537. package/docs/CRITICAL_MEMORY_USAGE_PROMPTS.md +290 -0
  538. package/docs/CURSOR_AI_MEMORY_ANALYSIS.md +479 -0
  539. package/docs/CURSOR_AI_MEMORY_WORKFLOW_ANALYSIS.md +267 -0
  540. package/docs/CURSOR_AI_TEST_RESULTS.md +298 -0
  541. package/docs/DEEPSEEK_AI_CLARIFICATION.md +52 -0
  542. package/docs/DEEPSEEK_AI_IMPLEMENTATION_GUIDE.md +398 -0
  543. package/docs/DEEPSEEK_AI_STRATEGIC_VALIDATION.md +348 -0
  544. package/docs/DEEPSEEK_AI_VALIDATION_RESPONSE.md +276 -0
  545. package/docs/DEEPSEEK_AI_VALIDATION_RESPONSE_v2.md +325 -0
  546. package/docs/DEEPSEEK_FINAL_VALIDATION.md +337 -0
  547. package/docs/DEEPSEEK_LAUNCH_VALIDATION.md +55 -0
  548. package/docs/DEEPSEEK_SCOPE_REALITY_CHECK.md +30 -0
  549. package/docs/DEEPSEEK_SUPERMEMORY_ADOPTION_AND_VSCODE_PIVOT.md +47 -0
  550. package/docs/DEEPSEEK_VALIDATION_RESULTS.md +165 -0
  551. package/docs/DEVELOPMENT_TESTING_PROTOCOL.md +378 -0
  552. package/docs/E2E_TEST_RESULTS.md +102 -0
  553. package/docs/END_TO_END_MEMORY_ISSUE_ANALYSIS.md +442 -0
  554. package/docs/FEATURE_1_GIT_SYNC_PLAN.md +228 -0
  555. package/docs/FEATURE_2_AUTO_LOGGING_PLAN.md +239 -0
  556. package/docs/FEATURE_3_CODE_SNIPPET_PLAN.md +249 -0
  557. package/docs/FEATURE_4_TAG_NORMALIZATION_PLAN.md +211 -0
  558. package/docs/FEATURE_5_WINDOWS_PATH_HANDLING_PLAN.md +199 -0
  559. package/docs/FEATURE_6_CONFLICT_DETECTION_PLAN.md +126 -0
  560. package/docs/FEATURE_IMPLEMENTATION_REPORT.md +203 -0
  561. package/docs/FINAL_COMPLETE_LAUNCH_DECISION.md +255 -0
  562. package/docs/FINAL_LAUNCH_DECISION.md +235 -0
  563. package/docs/FINAL_LAUNCH_DECISION_ALL_AIS.md +226 -0
  564. package/docs/FINAL_SCENARIO_VERIFICATION.md +363 -0
  565. package/docs/FIX_100_PERCENT_ANALYSIS.md +133 -0
  566. package/docs/FRAMEWORK_STRUCTURE.md +94 -0
  567. package/docs/GEMINI_AI_ANALYSIS.md +156 -0
  568. package/docs/GEMINI_AI_CLARIFICATION.md +47 -0
  569. package/docs/GEMINI_AI_STRATEGIC_VALIDATION.md +235 -0
  570. package/docs/GEMINI_AI_VALIDATION_RESPONSE.md +238 -0
  571. package/docs/GEMINI_AI_VALIDATION_RESPONSE_v2.md +168 -0
  572. package/docs/GEMINI_FINAL_VALIDATION.md +204 -0
  573. package/docs/GEMINI_LAUNCH_VALIDATION.md +30 -0
  574. package/docs/GEMINI_SCOPE_AND_UNIVERSALITY_DEBATE.md +25 -0
  575. package/docs/GEMINI_SUPERMEMORY_TREE_SITTER_MANDATE.md +43 -0
  576. package/docs/GEMINI_VALIDATION_RESULTS.md +183 -0
  577. package/docs/GROK_AI_ANALYSIS.md +278 -0
  578. package/docs/GROK_AI_CLARIFICATION.md +52 -0
  579. package/docs/GROK_AI_STRATEGIC_VALIDATION.md +306 -0
  580. package/docs/GROK_AI_VALIDATION_RESPONSE.md +252 -0
  581. package/docs/GROK_AI_VALIDATION_RESPONSE_v2.md +264 -0
  582. package/docs/GROK_FINAL_VALIDATION.md +251 -0
  583. package/docs/GROK_LAUNCH_VALIDATION.md +24 -0
  584. package/docs/GROK_SCOPE_REALITY_CHECK.md +28 -0
  585. package/docs/GROK_SUPERMEMORY_LAUNCH_ANALYSIS.md +44 -0
  586. package/docs/GROK_VALIDATION_RESULTS.md +180 -0
  587. package/docs/IMPLEMENTATION_PLAN_16_CRITICAL_FIXES.md +641 -0
  588. package/docs/LANGCHAIN_AND_LANGGRAPH_INTEGRATION_PLAN.md +51 -0
  589. package/docs/LAUNCH_DECISION_FINAL.md +243 -0
  590. package/docs/MANUS_AI_ANALYSIS.md +171 -0
  591. package/docs/MANUS_AI_CLARIFICATION.md +43 -0
  592. package/docs/MANUS_AI_VALIDATION_RESPONSE.md +335 -0
  593. package/docs/MANUS_AI_VALIDATION_RESPONSE_v2.md +226 -0
  594. package/docs/MANUS_FINAL_VALIDATION.md +257 -0
  595. package/docs/MANUS_VALIDATION_RESULTS.md +237 -0
  596. package/docs/MCP_SERVER_SETUP.md +167 -0
  597. package/docs/MEMORYLINK_7AI_FINAL_CONFIRMATION.md +210 -0
  598. package/docs/MEMORYLINK_CURSOR_AI_DEVELOPMENT_GUIDE.md +1092 -0
  599. package/docs/MEMORYLINK_DEVELOPMENT_PLAN_CURSOR_AI.md +629 -0
  600. package/docs/MEMORYLINK_FINAL_7AI_CLARIFICATION.md +184 -0
  601. package/docs/MEMORYLINK_MASTER_DOCUMENT_v4.md +1338 -0
  602. package/docs/MEMORYLINK_NAMING_ANALYSIS.md +427 -0
  603. package/docs/MEMORYLINK_REAL_WORLD_SCENARIOS.md +3517 -0
  604. package/docs/MEMORYLINK_STORAGE_COMPARISON.md +498 -0
  605. package/docs/MEMORYLINK_V1.0_FINAL_IMPLEMENTATION_PLAN.md +285 -0
  606. package/docs/MEMORYLINK_VALIDATION_COMPLETE_ANALYSIS.md +207 -0
  607. package/docs/MEMORYLINK_VS_MEMORY_APPS_ANALYSIS.md +667 -0
  608. package/docs/MEMORYLINK_v1.0_BUILD_DOCUMENT_FINAL.md +1928 -0
  609. package/docs/MEMORY_USAGE_FIX_IMPLEMENTATION.md +314 -0
  610. package/docs/MISTRAL_AI_ANALYSIS.md +189 -0
  611. package/docs/MISTRAL_AI_CLARIFICATION.md +57 -0
  612. package/docs/MISTRAL_AI_STRATEGIC_VALIDATION.md +334 -0
  613. package/docs/MISTRAL_AI_TESTING_REQUEST.md +261 -0
  614. package/docs/MISTRAL_AI_VALIDATION_RESPONSE.md +446 -0
  615. package/docs/MISTRAL_AI_VALIDATION_RESPONSE_v2.md +227 -0
  616. package/docs/MISTRAL_FINAL_VALIDATION.md +398 -0
  617. package/docs/MISTRAL_LAUNCH_VALIDATION.md +32 -0
  618. package/docs/MISTRAL_SCOPE_REALITY_CHECK.md +32 -0
  619. package/docs/MISTRAL_SUPERMEMORY_LAUNCH_ANALYSIS.md +43 -0
  620. package/docs/MISTRAL_VALIDATION_RESULTS.md +371 -0
  621. package/docs/NEXT_PLAN.md +300 -0
  622. package/docs/PERPLEXITY_AI_ANALYSIS.md +285 -0
  623. package/docs/PERPLEXITY_AI_CLARIFICATION.md +57 -0
  624. package/docs/PERPLEXITY_AI_STRATEGIC_VALIDATION.md +288 -0
  625. package/docs/PERPLEXITY_AI_VALIDATION_RESPONSE.md +350 -0
  626. package/docs/PERPLEXITY_AI_VALIDATION_RESPONSE_v2.md +260 -0
  627. package/docs/PERPLEXITY_FINAL_VALIDATION.md +320 -0
  628. package/docs/PERPLEXITY_LAUNCH_VALIDATION.md +42 -0
  629. package/docs/PERPLEXITY_MEMORY_QUALITY_AND_VSCODE_PLAN.md +56 -0
  630. package/docs/PERPLEXITY_SCOPE_REALITY_CHECK.md +31 -0
  631. package/docs/PERPLEXITY_VALIDATION_RESULTS.md +154 -0
  632. package/docs/PRE_LAUNCH_GAP_ANALYSIS.md +663 -0
  633. package/docs/PROJECT_STRUCTURE_PLAN.md +104 -0
  634. package/docs/QWEN_AI_ANALYSIS.md +176 -0
  635. package/docs/QWEN_AI_CLARIFICATION.md +60 -0
  636. package/docs/QWEN_AI_STRATEGIC_VALIDATION.md +241 -0
  637. package/docs/QWEN_AI_VALIDATION_RESPONSE.md +197 -0
  638. package/docs/QWEN_AI_VALIDATION_RESPONSE_v2.md +186 -0
  639. package/docs/QWEN_FINAL_VALIDATION.md +284 -0
  640. package/docs/QWEN_LAUNCH_VALIDATION.md +26 -0
  641. package/docs/QWEN_SCENARIOS_TEST_RESULTS.md +244 -0
  642. package/docs/QWEN_SCOPE_REALITY_CHECK.md +26 -0
  643. package/docs/QWEN_SUPERMEMORY_LAUNCH_AND_ENFORCEMENT_PLAN.md +56 -0
  644. package/docs/QWEN_VALIDATION_RESULTS.md +185 -0
  645. package/docs/README.md +479 -0
  646. package/docs/REAL_PRODUCT_LAUNCH_DECISION.md +185 -0
  647. package/docs/RECIPES.md +424 -0
  648. package/docs/RELEASE_NOTES_v1.0.0.md +193 -0
  649. package/docs/SCENARIO_INVENTORY_AND_VERIFICATION.md +284 -0
  650. package/docs/SINGLE_RUN_1018_SCENARIOS_RESULTS.md +142 -0
  651. package/docs/TESTING.md +256 -0
  652. package/docs/TESTING_STRATEGY.md +194 -0
  653. package/docs/TROUBLESHOOTING.md +188 -0
  654. package/docs/ULTIMATE_LAUNCH_DECISION.md +246 -0
  655. package/docs/WHAT_WE_BUILT.md +504 -0
  656. package/docs/v1.0_LAUNCH_CHECKLIST.md +104 -0
  657. package/examples/README.md +199 -0
  658. package/examples/chatgpt-context.js +161 -0
  659. package/examples/ci-integration.js +288 -0
  660. package/examples/sync-from-cursor.js +196 -0
  661. package/extensions/vscode/README.md +25 -0
  662. package/extensions/vscode/out/buddy-check.js +208 -0
  663. package/extensions/vscode/out/buddy-check.js.map +1 -0
  664. package/extensions/vscode/out/extension.js +413 -0
  665. package/extensions/vscode/out/extension.js.map +1 -0
  666. package/extensions/vscode/out/sidebar.js +409 -0
  667. package/extensions/vscode/out/sidebar.js.map +1 -0
  668. package/extensions/vscode/package.json +92 -0
  669. package/extensions/vscode/src/buddy-check.ts +220 -0
  670. package/extensions/vscode/src/extension.ts +425 -0
  671. package/extensions/vscode/src/shims-vscode.d.ts +2 -0
  672. package/extensions/vscode/src/sidebar.ts +431 -0
  673. package/extensions/vscode/tsconfig.json +14 -0
  674. package/k6-load-test.js +86 -0
  675. package/package.json +68 -0
  676. package/run-professional-tests.sh +72 -0
  677. package/scripts/monitor-continuous-test.sh +17 -0
  678. package/scripts/reorganize-project.sh +164 -0
  679. package/scripts/run-tests-parallel.sh +111 -0
  680. package/scripts/run-tests.sh +30 -0
  681. package/scripts/setup-framework.sh +139 -0
  682. package/scripts/setup-testing.sh +96 -0
  683. package/scripts/stress-test/README.md +86 -0
  684. package/scripts/stress-test/create-all-scenarios.sh +17 -0
  685. package/scripts/stress-test/create-remaining-scenarios.sh +3 -0
  686. package/scripts/stress-test/dev-test.sh +21 -0
  687. package/scripts/stress-test/monitor-continuous.sh +149 -0
  688. package/scripts/stress-test/overnight-test.sh +30 -0
  689. package/scripts/stress-test/quick-test.sh +21 -0
  690. package/scripts/stress-test/run-all-tests.sh +157 -0
  691. package/scripts/stress-test/run-continuous.sh +300 -0
  692. package/scripts/stress-test/run-stress-test.sh +153 -0
  693. package/scripts/stress-test/set1/1_1_mass_refactoring.sh +117 -0
  694. package/scripts/stress-test/set1/1_1_mass_refactoring_simple.sh +117 -0
  695. package/scripts/stress-test/set1/1_2_function_rename.sh +95 -0
  696. package/scripts/stress-test/set1/1_3_feature_flags.sh +93 -0
  697. package/scripts/stress-test/set1/1_4_feature_removal.sh +57 -0
  698. package/scripts/stress-test/set1/1_5_schema_changes.sh +42 -0
  699. package/scripts/stress-test/set1/1_6_dependency_update.sh +47 -0
  700. package/scripts/stress-test/set1/1_7_config_modification.sh +53 -0
  701. package/scripts/stress-test/set2/2_1_payment_logging.sh +49 -0
  702. package/scripts/stress-test/set2/2_2_test_data_generation.sh +43 -0
  703. package/scripts/stress-test/set2/2_3_documentation_leak.sh +45 -0
  704. package/scripts/stress-test/set2/2_4_api_key_rotation.sh +45 -0
  705. package/scripts/stress-test/set2/2_5_hardcoded_secrets.sh +45 -0
  706. package/scripts/stress-test/set2/2_6_debug_output.sh +49 -0
  707. package/scripts/stress-test/set3/3_1_billing_modification.sh +47 -0
  708. package/scripts/stress-test/set3/3_2_migration_deletion.sh +43 -0
  709. package/scripts/stress-test/set3/3_3_auth_middleware.sh +52 -0
  710. package/scripts/stress-test/set3/3_4_permission_bypass.sh +48 -0
  711. package/scripts/stress-test/set3/3_5_config_modification.sh +43 -0
  712. package/scripts/stress-test/set3/3_6_core_library.sh +51 -0
  713. package/scripts/stress-test/set3/3_7_test_infrastructure.sh +49 -0
  714. package/scripts/stress-test/set4/4_1_concurrent_features.sh +49 -0
  715. package/scripts/stress-test/set4/4_2_lock_acquisition.sh +32 -0
  716. package/scripts/stress-test/set4/4_3_migration_hotfix.sh +43 -0
  717. package/scripts/stress-test/set4/4_4_overlapping_scopes.sh +50 -0
  718. package/scripts/stress-test/set4/4_5_lock_timeout.sh +34 -0
  719. package/scripts/stress-test/set4/4_6_concurrent_stats.sh +33 -0
  720. package/scripts/stress-test/set5/5_1_wrong_decision.sh +41 -0
  721. package/scripts/stress-test/set5/5_2_outdated_docs.sh +40 -0
  722. package/scripts/stress-test/set5/5_3_conflicting_memories.sh +34 -0
  723. package/scripts/stress-test/set5/5_4_deleted_file_references.sh +38 -0
  724. package/scripts/stress-test/set5/5_5_old_pattern.sh +41 -0
  725. package/scripts/stress-test/set5/5_6_wrong_architecture.sh +42 -0
  726. package/scripts/stress-test/set5/5_7_high_trust_stale.sh +46 -0
  727. package/scripts/stress-test/set5/5_8_observability_stale.sh +36 -0
  728. package/scripts/stress-test/setup-test-repo-simple.sh +144 -0
  729. package/scripts/stress-test/setup-test-repo.sh +154 -0
  730. package/scripts/stress-test/start-continuous.sh +48 -0
  731. package/scripts/stress-test/stop-continuous.sh +42 -0
  732. package/scripts/stress-test/template-scenario.sh +115 -0
  733. package/scripts/test-advanced-scenarios.sh +411 -0
  734. package/scripts/test-continuous-30min.sh +307 -0
  735. package/scripts/test-continuous-enhanced.sh +250 -0
  736. package/scripts/test-e2e-comprehensive.sh +114 -0
  737. package/scripts/test-e2e-random.sh +359 -0
  738. package/scripts/test-fresh-scenarios.sh +412 -0
  739. package/scripts/test-new-scenarios.sh +374 -0
  740. package/scripts/test-quick-random.sh +97 -0
  741. package/scripts/test-runtime.sh +129 -0
  742. package/scripts/test-telemetry-local.sh +193 -0
  743. package/scripts/test-ultimate-scenarios.sh +428 -0
  744. package/scripts/test-v1.5-complete.sh +225 -0
  745. package/scripts/test-v1.5-phase1.sh +222 -0
  746. package/src/cli.ts +1259 -0
  747. package/src/commands/archive.ts +252 -0
  748. package/src/commands/auto-context.ts +159 -0
  749. package/src/commands/auto-log.ts +531 -0
  750. package/src/commands/change.ts +298 -0
  751. package/src/commands/checkpoint.ts +390 -0
  752. package/src/commands/configure.ts +297 -0
  753. package/src/commands/consolidate.ts +263 -0
  754. package/src/commands/context.ts +618 -0
  755. package/src/commands/detect.ts +181 -0
  756. package/src/commands/doctor.ts +1468 -0
  757. package/src/commands/export.ts +77 -0
  758. package/src/commands/graph.ts +214 -0
  759. package/src/commands/hooks.ts +245 -0
  760. package/src/commands/impact.ts +163 -0
  761. package/src/commands/index-vector.ts +126 -0
  762. package/src/commands/index.ts +57 -0
  763. package/src/commands/init.ts +194 -0
  764. package/src/commands/inject.ts +440 -0
  765. package/src/commands/learn.ts +328 -0
  766. package/src/commands/lock.ts +345 -0
  767. package/src/commands/memory.ts +415 -0
  768. package/src/commands/migrate.ts +540 -0
  769. package/src/commands/patterns.ts +158 -0
  770. package/src/commands/protect.ts +199 -0
  771. package/src/commands/quickstart.ts +259 -0
  772. package/src/commands/resolve.ts +373 -0
  773. package/src/commands/roadmap.ts +25 -0
  774. package/src/commands/scopes.ts +113 -0
  775. package/src/commands/search.ts +365 -0
  776. package/src/commands/setup.ts +430 -0
  777. package/src/commands/snippet.ts +271 -0
  778. package/src/commands/stats.ts +591 -0
  779. package/src/commands/status.ts +127 -0
  780. package/src/commands/suggest-tags.ts +122 -0
  781. package/src/commands/sync-rules.ts +218 -0
  782. package/src/commands/sync.ts +363 -0
  783. package/src/commands/telemetry-test.ts +97 -0
  784. package/src/commands/template.ts +166 -0
  785. package/src/commands/validate.ts +191 -0
  786. package/src/commands/watch-preferences.ts +162 -0
  787. package/src/commands/watch.ts +239 -0
  788. package/src/config/thresholds.ts +14 -0
  789. package/src/index.ts +12 -0
  790. package/src/memorylink.ts +308 -0
  791. package/src/search/local-embeddings.ts +94 -0
  792. package/src/search/vector-search.ts +608 -0
  793. package/src/server/mcp-server.ts +355 -0
  794. package/src/telemetry.ts +391 -0
  795. package/src/test-runner/TestRunner.ts +421 -0
  796. package/src/test-runner/performance-test.ts +161 -0
  797. package/src/test-runner/run-tests.ts +152 -0
  798. package/src/types.ts +533 -0
  799. package/src/utils/batch-commits.ts +162 -0
  800. package/src/utils/code-structure.ts +686 -0
  801. package/src/utils/commit-patterns.ts +87 -0
  802. package/src/utils/observability.ts +149 -0
  803. package/src/utils/quality.ts +230 -0
  804. package/src/utils/semantic-search.ts +222 -0
  805. package/src/utils/streaming.ts +109 -0
  806. package/src/utils/tag-suggestions.ts +117 -0
  807. package/src/utils/team-patterns.ts +499 -0
  808. package/src/utils/templates.ts +181 -0
  809. package/src/utils/tree-sitter-parser.ts +246 -0
  810. package/src/utils/v1.6-patterns.ts +227 -0
  811. package/src/utils.ts +885 -0
  812. package/test-all-features.sh +102 -0
  813. package/test-all-implemented-features.sh +209 -0
  814. package/test-all-new-features.sh +171 -0
  815. package/test-auto-log.txt +1 -0
  816. package/test-batch-commits.sh +47 -0
  817. package/test-conflict-resolution.sh +47 -0
  818. package/test-e2e.sh +22 -0
  819. package/test-end-to-end.sh +151 -0
  820. package/test-enhanced-autocapture.sh +164 -0
  821. package/test-inject.sh +44 -0
  822. package/test-mcp-server.sh +67 -0
  823. package/test-pagination.sh +37 -0
  824. package/test-python-go-structure.sh +164 -0
  825. package/test-quality-validation.sh +167 -0
  826. package/test-results-quick-smoke.json +13 -0
  827. package/test-results-targeted-perf.json +23 -0
  828. package/test-results.json +2272 -0
  829. package/test-scenarios/payment-logging.ts +17 -0
  830. package/test-scenarios/test-config.ts +13 -0
  831. package/test-semantic-search.sh +161 -0
  832. package/test-tag-intelligence.sh +49 -0
  833. package/test-vector-search.sh +64 -0
  834. package/test-vscode-extension.sh +144 -0
  835. package/test-watcher-file.txt +2 -0
  836. package/test-watcher-file2.txt +1 -0
  837. package/test-watcher.sh +103 -0
  838. package/test_qwen_scenarios.sh +285 -0
  839. package/tests/scenarios/4000_HARD_SCENARIOS.sh +4137 -0
  840. package/tests/scenarios/ADD_V1.1_SCENARIOS.sh +93 -0
  841. package/tests/scenarios/AGGRESSIVE_RANDOM_E2E_TEST.sh +474 -0
  842. package/tests/scenarios/COMPLETE_PRODUCT_VALIDATION.sh +227 -0
  843. package/tests/scenarios/COMPREHENSIVE_E2E_TEST.sh +426 -0
  844. package/tests/scenarios/CONTINUOUS_RANDOM_STRESS_TEST.sh +240 -0
  845. package/tests/scenarios/EXECUTE_10000_SCENARIOS.sh +61 -0
  846. package/tests/scenarios/EXECUTE_1000_UNIQUE_SCENARIOS.sh +190 -0
  847. package/tests/scenarios/EXECUTE_5000_SCENARIOS_SPLIT.sh +192 -0
  848. package/tests/scenarios/EXECUTE_5000_TOTAL_SCENARIOS.sh +162 -0
  849. package/tests/scenarios/EXECUTE_5040_SCENARIOS_WITH_V1.1.sh +251 -0
  850. package/tests/scenarios/EXECUTE_8_BATCHES_500.sh +51 -0
  851. package/tests/scenarios/EXECUTE_QUICK_SMOKE.sh +9 -0
  852. package/tests/scenarios/EXECUTE_SINGLE_BATCH.sh +117 -0
  853. package/tests/scenarios/EXECUTE_TARGETED_PERF.sh +19 -0
  854. package/tests/scenarios/GENERATE_1000_SCENARIOS.sh +235 -0
  855. package/tests/scenarios/GENERATE_4000_HARD_SCENARIOS.sh +266 -0
  856. package/tests/scenarios/GENERATE_4000_HARD_SCENARIOS_FIXED.sh +267 -0
  857. package/tests/scenarios/GENERATE_4000_HARD_SCENARIOS_FIXED_V2.sh +267 -0
  858. package/tests/scenarios/NEW_RANDOM_E2E_TEST.sh +422 -0
  859. package/tests/scenarios/QUICK_SMOKE_200.sh +38 -0
  860. package/tests/scenarios/QUICK_SMOKE_MINI.sh +3 -0
  861. package/tests/scenarios/RANDOM_REAL_WORLD_SCENARIOS.sh +372 -0
  862. package/tests/scenarios/ROUND3_RANDOM_E2E_TEST.sh +446 -0
  863. package/tests/scenarios/RUN_AGGRESSIVE_AND_SUMMARY.sh +51 -0
  864. package/tests/scenarios/RUN_ALL_1018_SCENARIOS.sh +161 -0
  865. package/tests/scenarios/TARGETED_PERF.sh +75 -0
  866. package/tests/scenarios/V1.1_FEATURES_SCENARIOS.sh +145 -0
  867. package/tests/unit/utils.test.ts +52 -0
  868. package/tests/v1.1-features-scenarios.sh +276 -0
  869. package/tsconfig.json +21 -0
  870. package/v1.6_FEATURE_REQUESTS.md +79 -0
@@ -0,0 +1,1468 @@
1
+ /**
2
+ * MemoryLink - Doctor Command
3
+ * System health check and troubleshooting
4
+ */
5
+
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import { execSync } from 'child_process';
9
+ import {
10
+ isInitialized,
11
+ success,
12
+ error,
13
+ warn,
14
+ info,
15
+ log,
16
+ findRoot,
17
+ readConfig,
18
+ getFilePath,
19
+ readJsonlEntries,
20
+ isJsonlFormat,
21
+ safeLog,
22
+ safeError,
23
+ isStdoutWritable,
24
+ } from '../utils.js';
25
+ import { loadGraph } from '../utils/code-structure.js';
26
+ import { MEMORYLINK_DIR, FILES } from '../types.js';
27
+ import { logBuddyCheckRun } from '../utils/observability.js';
28
+ import { checkLock } from './lock.js';
29
+ import type {
30
+ GlobalOptions,
31
+ DoctorCheck,
32
+ MemoryEntry,
33
+ LearningEntry,
34
+ BuddyStatus,
35
+ BuddyIssue,
36
+ BuddyReport,
37
+ BuddyOverride,
38
+ MemoryStatus,
39
+ Sensitivity,
40
+ TrustLevel,
41
+ SourceType,
42
+ } from '../types.js';
43
+
44
+ // Secret patterns to detect (HIGH PRIORITY - All 7 AIs require this)
45
+ const SECRET_PATTERNS = [
46
+ // API Keys
47
+ { name: 'OpenAI API Key', pattern: /sk-[a-zA-Z0-9]{20,}/g },
48
+ { name: 'Anthropic API Key', pattern: /sk-ant-[a-zA-Z0-9-]{20,}/g },
49
+ { name: 'Stripe Secret Key', pattern: /sk_live_[a-zA-Z0-9]{20,}/g },
50
+ { name: 'Stripe Test Key', pattern: /sk_test_[a-zA-Z0-9]{20,}/g },
51
+ { name: 'AWS Access Key', pattern: /AKIA[0-9A-Z]{16}/g },
52
+ { name: 'AWS Secret Key', pattern: /[a-zA-Z0-9/+=]{40}/g },
53
+ { name: 'GitHub Token', pattern: /ghp_[a-zA-Z0-9]{36}/g },
54
+ { name: 'GitHub Token (old)', pattern: /github_pat_[a-zA-Z0-9_]{22,}/g },
55
+ { name: 'Google API Key', pattern: /AIza[0-9A-Za-z-_]{35}/g },
56
+ { name: 'Slack Token', pattern: /xox[baprs]-[0-9]{10,13}-[a-zA-Z0-9-]+/g },
57
+ { name: 'Discord Token', pattern: /[MN][A-Za-z\d]{23,}\.[\w-]{6}\.[\w-]{27}/g },
58
+
59
+ // Generic patterns
60
+ { name: 'Generic API Key', pattern: /api[_-]?key["\s]*[:=]["\s]*[a-zA-Z0-9_-]{16,}/gi },
61
+ { name: 'Generic Secret', pattern: /secret["\s]*[:=]["\s]*[a-zA-Z0-9_-]{16,}/gi },
62
+ { name: 'Generic Token', pattern: /token["\s]*[:=]["\s]*[a-zA-Z0-9_-]{16,}/gi },
63
+ { name: 'Password', pattern: /password["\s]*[:=]["\s]*[^\s"]{8,}/gi },
64
+ { name: 'Private Key', pattern: /-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g },
65
+ { name: 'Bearer Token', pattern: /bearer\s+[a-zA-Z0-9_-]{20,}/gi },
66
+ ];
67
+
68
+ interface SecretMatch {
69
+ file: string;
70
+ line: number;
71
+ pattern: string;
72
+ preview: string;
73
+ }
74
+
75
+ interface Conflict {
76
+ type: 'duplicate' | 'conflict';
77
+ entries: string[];
78
+ message: string;
79
+ suggestion?: string;
80
+ }
81
+
82
+ /**
83
+ * Detect Git merge conflict markers in log files
84
+ */
85
+ function detectGitConflicts(root: string): { file: string; line: number }[] {
86
+ const conflicts: { file: string; line: number }[] = [];
87
+ const filesToScan = ['MEMORY', 'LEARNINGS', 'CHANGES'] as const;
88
+
89
+ for (const fileKey of filesToScan) {
90
+ const filePath = getFilePath(fileKey, root);
91
+ if (!fs.existsSync(filePath)) continue;
92
+
93
+ const content = fs.readFileSync(filePath, 'utf-8');
94
+ const lines = content.split('\n');
95
+
96
+ for (let i = 0; i < lines.length; i++) {
97
+ const line = lines[i];
98
+ // Check for Git merge conflict markers
99
+ if (line.trim().startsWith('<<<<<<<') ||
100
+ line.trim().startsWith('=======') ||
101
+ line.trim().startsWith('>>>>>>>')) {
102
+ conflicts.push({
103
+ file: FILES[fileKey],
104
+ line: i + 1,
105
+ });
106
+ }
107
+ }
108
+ }
109
+
110
+ return conflicts;
111
+ }
112
+
113
+ function scanForSecrets(root: string): SecretMatch[] {
114
+ const matches: SecretMatch[] = [];
115
+ const filesToScan = ['MEMORY', 'LEARNINGS', 'CHANGES'] as const;
116
+
117
+ for (const fileKey of filesToScan) {
118
+ const filePath = getFilePath(fileKey, root);
119
+ if (!fs.existsSync(filePath)) continue;
120
+
121
+ const content = fs.readFileSync(filePath, 'utf-8');
122
+ const lines = content.split('\n');
123
+
124
+ for (let i = 0; i < lines.length; i++) {
125
+ const line = lines[i];
126
+
127
+ for (const secretPattern of SECRET_PATTERNS) {
128
+ const regex = new RegExp(secretPattern.pattern);
129
+ if (regex.test(line)) {
130
+ // Create a safe preview (mask most of the secret)
131
+ const preview = line.length > 60
132
+ ? line.substring(0, 30) + '...' + line.substring(line.length - 10)
133
+ : line;
134
+
135
+ matches.push({
136
+ file: FILES[fileKey],
137
+ line: i + 1,
138
+ pattern: secretPattern.name,
139
+ preview: preview.replace(/([a-zA-Z0-9_-]{8})[a-zA-Z0-9_-]{8,}([a-zA-Z0-9_-]{4})/g, '$1****$2'),
140
+ });
141
+ break; // Only report once per line
142
+ }
143
+ }
144
+ }
145
+ }
146
+
147
+ return matches;
148
+ }
149
+
150
+ /**
151
+ * Normalize text for comparison (lowercase, trim, remove extra spaces)
152
+ */
153
+ function normalizeText(text: string): string {
154
+ return text.toLowerCase().trim().replace(/\s+/g, ' ');
155
+ }
156
+
157
+ /**
158
+ * Detect duplicate and conflicting memories
159
+ */
160
+ function detectMemoryConflicts(root: string): Conflict[] {
161
+ const conflicts: Conflict[] = [];
162
+ const memoryPath = getFilePath('MEMORY', root);
163
+
164
+ if (!fs.existsSync(memoryPath) || !isJsonlFormat(memoryPath)) {
165
+ return conflicts;
166
+ }
167
+
168
+ const memories = readJsonlEntries<MemoryEntry>(memoryPath)
169
+ .filter(e => e.status === 'ACTIVE');
170
+
171
+ // Group by normalized details (exact duplicates)
172
+ const detailsMap = new Map<string, MemoryEntry[]>();
173
+ for (const mem of memories) {
174
+ const normalized = normalizeText(mem.details);
175
+ if (!detailsMap.has(normalized)) {
176
+ detailsMap.set(normalized, []);
177
+ }
178
+ detailsMap.get(normalized)!.push(mem);
179
+ }
180
+
181
+ // Find duplicates
182
+ for (const [normalized, entries] of detailsMap) {
183
+ if (entries.length > 1) {
184
+ const preview = entries[0].details.length > 60
185
+ ? entries[0].details.substring(0, 60) + '...'
186
+ : entries[0].details;
187
+
188
+ conflicts.push({
189
+ type: 'duplicate',
190
+ entries: entries.map(e => e.id),
191
+ message: `Duplicate memory: "${preview}"`,
192
+ suggestion: `Consider deprecating older entries or merging them`,
193
+ });
194
+ }
195
+ }
196
+
197
+ // Find conflicting rules/decisions (same topic, contradictory)
198
+ const rules = memories.filter(m => m.type === 'rule' || m.type === 'decision');
199
+ const rulesByTopic = new Map<string, MemoryEntry[]>();
200
+
201
+ for (const rule of rules) {
202
+ // Extract topic from details (first few words)
203
+ const topic = normalizeText(rule.details).split(' ').slice(0, 3).join(' ');
204
+ if (!rulesByTopic.has(topic)) {
205
+ rulesByTopic.set(topic, []);
206
+ }
207
+ rulesByTopic.get(topic)!.push(rule);
208
+ }
209
+
210
+ // Check for potential conflicts (same topic, different details)
211
+ for (const [topic, entries] of rulesByTopic) {
212
+ if (entries.length > 1) {
213
+ const uniqueDetails = new Set(entries.map(e => normalizeText(e.details)));
214
+ if (uniqueDetails.size > 1) {
215
+ conflicts.push({
216
+ type: 'conflict',
217
+ entries: entries.map(e => e.id),
218
+ message: `Conflicting ${entries[0].type}s about: "${topic}..."`,
219
+ suggestion: `Review and resolve contradictions`,
220
+ });
221
+ }
222
+ }
223
+ }
224
+
225
+ return conflicts;
226
+ }
227
+
228
+ /**
229
+ * Detect duplicate learnings
230
+ */
231
+ function detectLearningConflicts(root: string): Conflict[] {
232
+ const conflicts: Conflict[] = [];
233
+ const learningsPath = getFilePath('LEARNINGS', root);
234
+
235
+ if (!fs.existsSync(learningsPath) || !isJsonlFormat(learningsPath)) {
236
+ return conflicts;
237
+ }
238
+
239
+ const learnings = readJsonlEntries<LearningEntry>(learningsPath)
240
+ .filter(e => e.status === 'ACTIVE');
241
+
242
+ // Group by normalized problem + solution (exact duplicates)
243
+ const problemSolutionMap = new Map<string, LearningEntry[]>();
244
+ for (const learning of learnings) {
245
+ const key = `${normalizeText(learning.problem)}|${normalizeText(learning.solution)}`;
246
+ if (!problemSolutionMap.has(key)) {
247
+ problemSolutionMap.set(key, []);
248
+ }
249
+ problemSolutionMap.get(key)!.push(learning);
250
+ }
251
+
252
+ // Find duplicates
253
+ for (const [key, entries] of problemSolutionMap) {
254
+ if (entries.length > 1) {
255
+ const preview = entries[0].problem.length > 50
256
+ ? entries[0].problem.substring(0, 50) + '...'
257
+ : entries[0].problem;
258
+
259
+ conflicts.push({
260
+ type: 'duplicate',
261
+ entries: entries.map(e => e.id),
262
+ message: `Duplicate learning: "${preview}"`,
263
+ suggestion: `Keep the most recent entry, deprecate others`,
264
+ });
265
+ }
266
+ }
267
+
268
+ return conflicts;
269
+ }
270
+
271
+ export interface DoctorOptions extends GlobalOptions {
272
+ scanSecrets?: boolean;
273
+ autoFix?: boolean; // Auto-fix issues where possible
274
+ preflight?: boolean; // v1.4: Run preflight check
275
+ postflight?: boolean; // v1.4: Run postflight check
276
+ changed?: boolean; // v1.4: Only check changed files (for postflight)
277
+ fix?: boolean; // v1.4: Auto-fix memory records (for postflight)
278
+ json?: boolean; // v1.4: Output as JSON
279
+ for?: string; // v1.4: Agent/user ID for preflight
280
+ pr?: string; // v1.4: PR number for preflight
281
+ branch?: string; // v1.4: Branch name for preflight
282
+ }
283
+
284
+ export async function doctorCommand(options: DoctorOptions = {}): Promise<void> {
285
+ const {
286
+ verbose,
287
+ scanSecrets,
288
+ autoFix = false,
289
+ preflight = false,
290
+ postflight = false,
291
+ changed = false,
292
+ fix = false,
293
+ json = false,
294
+ for: agentId,
295
+ pr: prNumber,
296
+ branch: branchName,
297
+ } = options;
298
+
299
+ // TODO v1.6: Record telemetry event (command start)
300
+ // await recordEvent({
301
+ // command: 'doctor',
302
+ // result: 'success', // Will be updated to 'error' if command fails
303
+ // flags: { preflight, postflight, json, scanSecrets },
304
+ // isGitRepo: checkIsGitRepo(),
305
+ // hasConfig: checkHasConfig(),
306
+ // });
307
+
308
+ // v1.4: Handle preflight/postflight
309
+ if (preflight) {
310
+ const root = findRoot();
311
+ let report = await runPreflightCheck(options);
312
+
313
+ // Handle override if RED status
314
+ if (report.status === 'RED' && !json) {
315
+ report = await handleOverride(report, root, options);
316
+ }
317
+
318
+ // Log to observability
319
+ if (root) {
320
+ logBuddyCheckRun(report, root);
321
+ }
322
+
323
+ if (json) {
324
+ // For JSON output, use safeLog to handle EPIPE
325
+ safeLog(JSON.stringify(report, null, 2));
326
+ } else {
327
+ printBuddyReport(report);
328
+ }
329
+
330
+ // Write to file
331
+ if (root) {
332
+ const reportPath = path.join(root, MEMORYLINK_DIR, 'preflight.json');
333
+ fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
334
+ if (!json) {
335
+ info(`Report saved to: ${reportPath}`);
336
+ }
337
+
338
+ // Log override to overrides.log if present
339
+ if (report.override) {
340
+ logOverride(report.override, 'preflight', root);
341
+ }
342
+ }
343
+
344
+ // Exit with error code only if RED and not overridden
345
+ if (report.status === 'RED' && !report.override) {
346
+ process.exit(1);
347
+ }
348
+ return;
349
+ }
350
+
351
+ if (postflight) {
352
+ const root = findRoot();
353
+ let report = await runPostflightCheck(options);
354
+
355
+ // Handle override if RED status
356
+ if (report.status === 'RED' && !json) {
357
+ report = await handleOverride(report, root, options);
358
+ }
359
+
360
+ // Log to observability
361
+ if (root) {
362
+ logBuddyCheckRun(report, root);
363
+ }
364
+
365
+ if (json) {
366
+ // For JSON output, use safeLog to handle EPIPE
367
+ safeLog(JSON.stringify(report, null, 2));
368
+ } else {
369
+ printBuddyReport(report);
370
+ }
371
+
372
+ // Write to file
373
+ if (root) {
374
+ const reportPath = path.join(root, MEMORYLINK_DIR, 'postflight.json');
375
+ fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
376
+ if (!json) {
377
+ info(`Report saved to: ${reportPath}`);
378
+ }
379
+
380
+ // Log override to overrides.log if present
381
+ if (report.override) {
382
+ logOverride(report.override, 'postflight', root);
383
+ }
384
+ }
385
+
386
+ // Exit with error code only if RED and not overridden
387
+ if (report.status === 'RED' && !report.override) {
388
+ process.exit(1);
389
+ }
390
+ return;
391
+ }
392
+
393
+ // Original doctor command (v1.3)
394
+ log('Running health checks', verbose);
395
+
396
+ console.log('');
397
+ console.log('\x1b[1m🩺 MemoryLink Doctor\x1b[0m');
398
+ console.log('');
399
+
400
+ const checks: DoctorCheck[] = [];
401
+
402
+ // Check 1: MemoryLink initialized
403
+ const root = findRoot();
404
+ const initialized = root && isInitialized(root);
405
+
406
+ checks.push({
407
+ name: 'MemoryLink initialized',
408
+ status: initialized ? 'pass' : 'fail',
409
+ message: initialized
410
+ ? `Found .memorylink/ in ${root}`
411
+ : 'Run: memorylink init',
412
+ suggestion: initialized ? undefined : 'Run: memorylink init',
413
+ });
414
+
415
+ if (!initialized) {
416
+ printChecks(checks);
417
+ return;
418
+ }
419
+
420
+ // Check 2: All required files exist
421
+ const requiredFiles = ['PROTECTED', 'MEMORY', 'CHANGES', 'LEARNINGS', 'CONFIG'] as const;
422
+ let allFilesExist = true;
423
+ const missingFiles: string[] = [];
424
+
425
+ for (const fileKey of requiredFiles) {
426
+ const filePath = getFilePath(fileKey, root);
427
+ if (!fs.existsSync(filePath)) {
428
+ allFilesExist = false;
429
+ missingFiles.push(FILES[fileKey]);
430
+ }
431
+ }
432
+
433
+ checks.push({
434
+ name: 'Required files exist',
435
+ status: allFilesExist ? 'pass' : 'fail',
436
+ message: allFilesExist
437
+ ? 'All 5 files present'
438
+ : `Missing: ${missingFiles.join(', ')}`,
439
+ });
440
+
441
+ // Check 3: Config file valid
442
+ const config = readConfig(root);
443
+ checks.push({
444
+ name: 'Config file valid',
445
+ status: config ? 'pass' : 'fail',
446
+ message: config
447
+ ? `Version ${config.version}, initialized ${new Date(config.initialized).toLocaleDateString()}`
448
+ : 'Config file is corrupted or invalid',
449
+ suggestion: config ? undefined : 'Run: memorylink init (will recreate config)',
450
+ });
451
+
452
+ // Check 4: Files are readable/writable
453
+ let filesWritable = true;
454
+ try {
455
+ const testFile = path.join(root!, MEMORYLINK_DIR, '.doctor-test');
456
+ fs.writeFileSync(testFile, 'test');
457
+ fs.unlinkSync(testFile);
458
+ } catch {
459
+ filesWritable = false;
460
+ }
461
+
462
+ checks.push({
463
+ name: 'Files are writable',
464
+ status: filesWritable ? 'pass' : 'fail',
465
+ message: filesWritable
466
+ ? 'Read/write access confirmed'
467
+ : 'Permission denied - check file permissions',
468
+ });
469
+
470
+ // Check 5: Git repository
471
+ let isGitRepo = false;
472
+ let gitTracked = false;
473
+
474
+ try {
475
+ execSync('git rev-parse --git-dir', { cwd: root!, stdio: 'pipe' });
476
+ isGitRepo = true;
477
+
478
+ // Check if .memorylink is tracked
479
+ try {
480
+ const gitStatus = execSync(`git ls-files ${MEMORYLINK_DIR}`, { cwd: root!, stdio: 'pipe' }).toString();
481
+ gitTracked = gitStatus.trim().length > 0;
482
+ } catch {
483
+ gitTracked = false;
484
+ }
485
+ } catch {
486
+ isGitRepo = false;
487
+ }
488
+
489
+ checks.push({
490
+ name: 'Git repository',
491
+ status: isGitRepo ? 'pass' : 'warn',
492
+ message: isGitRepo
493
+ ? gitTracked
494
+ ? '.memorylink/ is tracked in Git (team sharing enabled)'
495
+ : '.memorylink/ exists but not tracked in Git'
496
+ : 'Not a Git repository - team sharing disabled',
497
+ });
498
+
499
+ // Check 6: Git hooks
500
+ let hooksInstalled = false;
501
+ if (isGitRepo && root) {
502
+ const preCommitPath = path.join(root, '.git', 'hooks', 'pre-commit');
503
+ if (fs.existsSync(preCommitPath)) {
504
+ const hookContent = fs.readFileSync(preCommitPath, 'utf-8');
505
+ hooksInstalled = hookContent.includes('memorylink');
506
+ }
507
+ }
508
+
509
+ checks.push({
510
+ name: 'Git hooks installed',
511
+ status: hooksInstalled ? 'pass' : 'warn',
512
+ message: hooksInstalled
513
+ ? 'Pre-commit hook protects files'
514
+ : 'Run: memorylink hooks install',
515
+ });
516
+
517
+ // Check 7: Node.js version
518
+ const nodeVersion = process.version;
519
+ const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0], 10);
520
+
521
+ checks.push({
522
+ name: 'Node.js version',
523
+ status: majorVersion >= 18 ? 'pass' : 'warn',
524
+ message: `${nodeVersion} ${majorVersion >= 18 ? '(supported)' : '(recommend v18+)'}`,
525
+ });
526
+
527
+ // Check 8: Protected files exist
528
+ const protectedPath = getFilePath('PROTECTED', root);
529
+ const protectedFiles = fs.readFileSync(protectedPath, 'utf-8')
530
+ .split('\n')
531
+ .filter(l => l.trim() && !l.startsWith('#'))
532
+ .map(l => l.split('#')[0].trim());
533
+
534
+ let allProtectedExist = true;
535
+ const missingProtected: string[] = [];
536
+
537
+ for (const file of protectedFiles) {
538
+ const fullPath = path.join(root!, file);
539
+ if (!fs.existsSync(fullPath)) {
540
+ allProtectedExist = false;
541
+ missingProtected.push(file);
542
+ }
543
+ }
544
+
545
+ if (protectedFiles.length > 0) {
546
+ checks.push({
547
+ name: 'Protected files exist',
548
+ status: allProtectedExist ? 'pass' : 'warn',
549
+ message: allProtectedExist
550
+ ? `All ${protectedFiles.length} protected files found`
551
+ : `Missing: ${missingProtected.slice(0, 3).join(', ')}${missingProtected.length > 3 ? '...' : ''}`,
552
+ });
553
+ }
554
+
555
+ // Check 9: SECRET SCANNING (Critical - All 7 AIs require this)
556
+ const secretMatches = scanForSecrets(root!);
557
+
558
+ checks.push({
559
+ name: 'Secret scanning',
560
+ status: secretMatches.length === 0 ? 'pass' : 'fail',
561
+ message: secretMatches.length === 0
562
+ ? 'No potential secrets detected in logs'
563
+ : `⚠️ ${secretMatches.length} potential secret(s) detected!`,
564
+ suggestion: secretMatches.length === 0 ? undefined : 'Review detected secrets and remove them from logs',
565
+ });
566
+
567
+ // Check 10: Common sensitive files protection
568
+ const sensitiveFiles = ['.env', '.env.local', '.env.production', 'secrets.json', '*.pem', 'id_rsa'];
569
+ const unprotectedSensitive: string[] = [];
570
+
571
+ for (const sensitive of sensitiveFiles) {
572
+ // Check if file exists and is not protected
573
+ if (sensitive.includes('*')) continue; // Skip glob patterns for now
574
+ const sensitivePath = path.join(root!, sensitive);
575
+ if (fs.existsSync(sensitivePath) && !protectedFiles.includes(sensitive)) {
576
+ unprotectedSensitive.push(sensitive);
577
+ }
578
+ }
579
+
580
+ if (unprotectedSensitive.length > 0) {
581
+ checks.push({
582
+ name: 'Sensitive files protected',
583
+ status: 'warn',
584
+ message: `Unprotected: ${unprotectedSensitive.join(', ')} - Run: memorylink protect <file>`,
585
+ suggestion: `Run: memorylink protect ${unprotectedSensitive[0]}`,
586
+ });
587
+ }
588
+
589
+ // Check 11: Git merge conflict detection
590
+ const gitConflicts = detectGitConflicts(root!);
591
+ checks.push({
592
+ name: 'Git merge conflicts',
593
+ status: gitConflicts.length === 0 ? 'pass' : 'fail',
594
+ message: gitConflicts.length === 0
595
+ ? 'No Git merge conflicts found'
596
+ : `${gitConflicts.length} Git merge conflict(s) detected in log files`,
597
+ });
598
+
599
+ // Check 12: Conflict/duplicate detection
600
+ const memoryConflicts = detectMemoryConflicts(root!);
601
+ const learningConflicts = detectLearningConflicts(root!);
602
+ const allConflicts = [...memoryConflicts, ...learningConflicts];
603
+
604
+ checks.push({
605
+ name: 'Conflict/duplicate detection',
606
+ status: allConflicts.length === 0 ? 'pass' : 'warn',
607
+ message: allConflicts.length === 0
608
+ ? 'No duplicates or conflicts found'
609
+ : `${allConflicts.length} conflict(s) detected (see details below)`,
610
+ });
611
+
612
+ // Check 13: Code structure graph freshness (v1.2)
613
+ const graphFile = path.join(root!, '.memorylink', 'code-graph.json');
614
+ if (fs.existsSync(graphFile)) {
615
+ const stats = fs.statSync(graphFile);
616
+ const age = Date.now() - stats.mtimeMs;
617
+ const oneWeek = 7 * 24 * 60 * 60 * 1000;
618
+
619
+ checks.push({
620
+ name: 'Code structure graph',
621
+ status: age < oneWeek ? 'pass' : 'warn',
622
+ message: age < oneWeek
623
+ ? `Graph is ${Math.floor(age / (24 * 60 * 60 * 1000))} day(s) old`
624
+ : 'Graph is older than 7 days - Run: memorylink graph build --rebuild',
625
+ suggestion: age >= oneWeek ? 'Run: memorylink graph build --rebuild' : undefined,
626
+ });
627
+ } else {
628
+ checks.push({
629
+ name: 'Code structure graph',
630
+ status: 'warn',
631
+ message: 'No code structure graph found',
632
+ suggestion: 'Run: memorylink graph build to enable code structure memory',
633
+ });
634
+ }
635
+
636
+ printChecks(checks);
637
+
638
+ // If secrets were found, print detailed report
639
+ if (secretMatches.length > 0) {
640
+ console.log('');
641
+ console.log('\x1b[31m\x1b[1m🚨 SECURITY WARNING: Potential Secrets Detected!\x1b[0m');
642
+ console.log('');
643
+ console.log('\x1b[33mThe following entries may contain sensitive data:\x1b[0m');
644
+ console.log('');
645
+
646
+ for (const match of secretMatches) {
647
+ console.log(` \x1b[31m•\x1b[0m ${match.file}:${match.line}`);
648
+ console.log(` \x1b[90mType: ${match.pattern}\x1b[0m`);
649
+ console.log(` \x1b[90mPreview: ${match.preview}\x1b[0m`);
650
+ console.log('');
651
+ }
652
+
653
+ console.log('\x1b[33m⚠️ ACTION REQUIRED:\x1b[0m');
654
+ console.log(' 1. Remove secrets from MemoryLink logs immediately');
655
+ console.log(' 2. Rotate any exposed credentials');
656
+ console.log(' 3. Use environment variables instead of storing secrets');
657
+ console.log(' 4. Add sensitive files to protected.txt');
658
+ console.log('');
659
+ console.log('\x1b[90mTip: Never store API keys, passwords, or tokens in MemoryLink logs.\x1b[0m');
660
+ console.log('\x1b[90mUse: memorylink protect .env\x1b[0m');
661
+ console.log('');
662
+ }
663
+
664
+ // Auto-fix suggestions
665
+ const failCount = checks.filter(c => c.status === 'fail').length;
666
+ if (autoFix && failCount > 0) {
667
+ const fixableChecks = checks.filter(c => c.status === 'fail' && c.suggestion);
668
+ if (fixableChecks.length > 0) {
669
+ console.log('');
670
+ info('🔧 Auto-fix suggestions:');
671
+ console.log('');
672
+ for (const check of fixableChecks) {
673
+ if (check.suggestion) {
674
+ console.log(` ${check.name}:`);
675
+ console.log(` → ${check.suggestion}`);
676
+ console.log('');
677
+ }
678
+ }
679
+ }
680
+ }
681
+
682
+ // If conflicts were found, print detailed report
683
+ if (allConflicts.length > 0) {
684
+ console.log('');
685
+ console.log('\x1b[33m\x1b[1m⚠️ CONFLICTS & DUPLICATES DETECTED\x1b[0m');
686
+ console.log('');
687
+ console.log('\x1b[33mThe following entries may need attention:\x1b[0m');
688
+ console.log('');
689
+
690
+ for (const conflict of allConflicts) {
691
+ const icon = conflict.type === 'duplicate' ? '📋' : '⚠️';
692
+ const color = conflict.type === 'duplicate' ? '\x1b[33m' : '\x1b[31m';
693
+ console.log(` ${icon} ${color}${conflict.message}\x1b[0m`);
694
+ console.log(` \x1b[90mEntry IDs: ${conflict.entries.slice(0, 3).join(', ')}${conflict.entries.length > 3 ? ` (+${conflict.entries.length - 3} more)` : ''}\x1b[0m`);
695
+ if (conflict.suggestion) {
696
+ console.log(` \x1b[90mSuggestion: ${conflict.suggestion}\x1b[0m`);
697
+ }
698
+ console.log('');
699
+ }
700
+
701
+ console.log('\x1b[33m💡 TIPS:\x1b[0m');
702
+ console.log(' • Review duplicate entries and keep the most relevant');
703
+ console.log(' • Resolve conflicting rules/decisions');
704
+ console.log(' • Use memorylink search to find entries by ID');
705
+ console.log(' • Consider deprecating outdated entries');
706
+ console.log('');
707
+ }
708
+
709
+ // Print all checks
710
+ printChecks(checks);
711
+
712
+ // Summary
713
+ console.log('');
714
+ const passCount = checks.filter(c => c.status === 'pass').length;
715
+ const warnCount = checks.filter(c => c.status === 'warn').length;
716
+
717
+ if (failCount > 0) {
718
+ error(`${failCount} issue(s) need attention`);
719
+ if (!autoFix) {
720
+ info(' Run with --auto-fix to see fix suggestions');
721
+ }
722
+ } else if (warnCount > 0) {
723
+ warn(`${warnCount} warning(s), ${passCount} passed`);
724
+ } else {
725
+ success(`All ${passCount} checks passed! MemoryLink is healthy.`);
726
+ }
727
+ console.log('');
728
+ }
729
+
730
+ function printChecks(checks: DoctorCheck[]): void {
731
+ for (const check of checks) {
732
+ let icon: string;
733
+ let color: string;
734
+
735
+ switch (check.status) {
736
+ case 'pass':
737
+ icon = '✓';
738
+ color = '\x1b[32m';
739
+ break;
740
+ case 'warn':
741
+ icon = '⚠';
742
+ color = '\x1b[33m';
743
+ break;
744
+ case 'fail':
745
+ icon = '✗';
746
+ color = '\x1b[31m';
747
+ break;
748
+ }
749
+
750
+ console.log(` ${color}${icon}\x1b[0m ${check.name}`);
751
+ console.log(` \x1b[90m${check.message}\x1b[0m`);
752
+ }
753
+ }
754
+
755
+ // ============================================
756
+ // V1.4 BUDDY-CHECK: PREFLIGHT & POSTFLIGHT
757
+ // ============================================
758
+
759
+ /**
760
+ * Run preflight check before AI agent operations
761
+ */
762
+ async function runPreflightCheck(options: DoctorOptions): Promise<BuddyReport> {
763
+ const startTime = Date.now();
764
+ const root = findRoot();
765
+
766
+ if (!root || !isInitialized(root)) {
767
+ return {
768
+ status: 'RED',
769
+ summary: 'MemoryLink not initialized',
770
+ issues: [{
771
+ type: 'INIT',
772
+ severity: 'error',
773
+ message: 'MemoryLink is not initialized. Run: memorylink init',
774
+ }],
775
+ timestamp: new Date().toISOString(),
776
+ runType: 'preflight',
777
+ durationMs: Date.now() - startTime,
778
+ };
779
+ }
780
+
781
+ const issues: BuddyIssue[] = [];
782
+
783
+ // Check 0: Agent locking (v1.5)
784
+ const lockStatus = checkLock(root);
785
+ if (lockStatus.locked) {
786
+ issues.push({
787
+ type: 'LOCK',
788
+ severity: 'warning',
789
+ message: `Agent lock active: ${lockStatus.agentId} (expires ${lockStatus.expiresAt?.toLocaleString()})`,
790
+ projectPath: root,
791
+ suggestion: 'Wait for lock to expire or release with: memorylink lock release',
792
+ });
793
+ }
794
+
795
+ const memoryEntries = readJsonlEntries<MemoryEntry>(getFilePath('MEMORY', root));
796
+
797
+ // Check 1: Schema validation
798
+ const schemaIssues = validateSchema(memoryEntries, root);
799
+ issues.push(...schemaIssues);
800
+
801
+ // Check 2: Referential integrity
802
+ const refIssues = validateReferentialIntegrity(memoryEntries, root);
803
+ issues.push(...refIssues);
804
+
805
+ // Check 3: Security checks (secrets, PII)
806
+ const securityIssues = validateSecurity(memoryEntries, root);
807
+ issues.push(...securityIssues);
808
+
809
+ // Check 4: Staleness detection
810
+ const stalenessIssues = detectStaleness(memoryEntries, root);
811
+ issues.push(...stalenessIssues);
812
+
813
+ // Check 5: Policy validation
814
+ const policyIssues = validatePolicies(memoryEntries, root);
815
+ issues.push(...policyIssues);
816
+
817
+ // Calculate status
818
+ const status = calculateBuddyStatus(issues);
819
+
820
+ // Count trust levels
821
+ const trustCounts = countTrustLevels(memoryEntries);
822
+
823
+ const duration = Date.now() - startTime;
824
+
825
+ return {
826
+ status,
827
+ summary: generateSummary(status, issues.length, memoryEntries.length),
828
+ issues,
829
+ timestamp: new Date().toISOString(),
830
+ runType: 'preflight',
831
+ agentId: options.for,
832
+ branch: options.branch,
833
+ recordsUsed: memoryEntries.length,
834
+ highTrust: trustCounts.high,
835
+ mediumTrust: trustCounts.medium,
836
+ lowTrust: trustCounts.low,
837
+ staleCount: stalenessIssues.length,
838
+ durationMs: duration,
839
+ };
840
+ }
841
+
842
+ /**
843
+ * Run postflight check after AI agent operations
844
+ */
845
+ async function runPostflightCheck(options: DoctorOptions): Promise<BuddyReport> {
846
+ const startTime = Date.now();
847
+ const root = findRoot();
848
+
849
+ if (!root || !isInitialized(root)) {
850
+ return {
851
+ status: 'RED',
852
+ summary: 'MemoryLink not initialized',
853
+ issues: [{
854
+ type: 'INIT',
855
+ severity: 'error',
856
+ message: 'MemoryLink is not initialized. Run: memorylink init',
857
+ }],
858
+ timestamp: new Date().toISOString(),
859
+ runType: 'postflight',
860
+ durationMs: Date.now() - startTime,
861
+ };
862
+ }
863
+
864
+ const issues: BuddyIssue[] = [];
865
+
866
+ // Get changed files if --changed flag is set
867
+ // TODO v1.6: Use `git diff` to detect changed files instead of file watching
868
+ // This will enable detection of:
869
+ // - Protected file modifications (via git diff --name-only + protected.txt check)
870
+ // - File deletions (via git diff --diff-filter=D)
871
+ // - Large-scale changes (via git diff --stat line count)
872
+ const changedFiles = options.changed ? getChangedFiles(root) : [];
873
+
874
+ // Read memory entries (filter to changed if needed)
875
+ let memoryEntries = readJsonlEntries<MemoryEntry>(getFilePath('MEMORY', root));
876
+ if (options.changed && changedFiles.length > 0) {
877
+ // Filter entries related to changed files
878
+ memoryEntries = memoryEntries.filter(entry => {
879
+ if (entry.file && changedFiles.includes(entry.file)) return true;
880
+ if (entry.path && changedFiles.includes(entry.path)) return true;
881
+ // Check if entry was created/updated recently (last 5 minutes)
882
+ const entryTime = new Date(entry.ts).getTime();
883
+ const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;
884
+ return entryTime > fiveMinutesAgo;
885
+ });
886
+ }
887
+
888
+ // Run same checks as preflight
889
+ const schemaIssues = validateSchema(memoryEntries, root);
890
+ issues.push(...schemaIssues);
891
+
892
+ const refIssues = validateReferentialIntegrity(memoryEntries, root);
893
+ issues.push(...refIssues);
894
+
895
+ const securityIssues = validateSecurity(memoryEntries, root);
896
+ issues.push(...securityIssues);
897
+
898
+ const stalenessIssues = detectStaleness(memoryEntries, root);
899
+ issues.push(...stalenessIssues);
900
+
901
+ const policyIssues = validatePolicies(memoryEntries, root);
902
+ issues.push(...policyIssues);
903
+
904
+ // Additional postflight checks
905
+ const consistencyIssues = validateConsistency(memoryEntries, root, changedFiles);
906
+ issues.push(...consistencyIssues);
907
+
908
+ // Mark new agent records as DRAFT
909
+ if (options.fix) {
910
+ await markAgentRecordsAsDraft(memoryEntries, root);
911
+ }
912
+
913
+ // Calculate status
914
+ const status = calculateBuddyStatus(issues);
915
+
916
+ const trustCounts = countTrustLevels(memoryEntries);
917
+ const duration = Date.now() - startTime;
918
+
919
+ return {
920
+ status,
921
+ summary: generateSummary(status, issues.length, memoryEntries.length),
922
+ issues,
923
+ timestamp: new Date().toISOString(),
924
+ runType: 'postflight',
925
+ recordsUsed: memoryEntries.length,
926
+ highTrust: trustCounts.high,
927
+ mediumTrust: trustCounts.medium,
928
+ lowTrust: trustCounts.low,
929
+ staleCount: stalenessIssues.length,
930
+ durationMs: duration,
931
+ };
932
+ }
933
+
934
+ /**
935
+ * Validate schema and required fields
936
+ */
937
+ function validateSchema(entries: MemoryEntry[], root: string): BuddyIssue[] {
938
+ const issues: BuddyIssue[] = [];
939
+
940
+ for (const entry of entries) {
941
+ // Check required fields
942
+ if (!entry.id) {
943
+ issues.push({
944
+ id: entry.id,
945
+ type: 'SCHEMA',
946
+ severity: 'error',
947
+ message: 'Missing required field: id',
948
+ projectPath: root,
949
+ });
950
+ }
951
+
952
+ if (!entry.ts) {
953
+ issues.push({
954
+ id: entry.id,
955
+ type: 'SCHEMA',
956
+ severity: 'error',
957
+ message: 'Missing required field: ts (timestamp)',
958
+ projectPath: root,
959
+ });
960
+ }
961
+
962
+ if (!entry.type) {
963
+ issues.push({
964
+ id: entry.id,
965
+ type: 'SCHEMA',
966
+ severity: 'error',
967
+ message: 'Missing required field: type',
968
+ projectPath: root,
969
+ });
970
+ }
971
+
972
+ // v1.4: Check schema version if present
973
+ if (entry.schemaVersion && entry.schemaVersion !== '1.4.0' && entry.schemaVersion !== '1.3.0') {
974
+ issues.push({
975
+ id: entry.id,
976
+ type: 'SCHEMA',
977
+ severity: 'warning',
978
+ message: `Unknown schema version: ${entry.schemaVersion}`,
979
+ projectPath: root,
980
+ });
981
+ }
982
+ }
983
+
984
+ return issues;
985
+ }
986
+
987
+ /**
988
+ * Validate referential integrity (files exist, lines in range, commits exist)
989
+ */
990
+ function validateReferentialIntegrity(entries: MemoryEntry[], root: string): BuddyIssue[] {
991
+ const issues: BuddyIssue[] = [];
992
+
993
+ for (const entry of entries) {
994
+ // Check file references
995
+ if (entry.file) {
996
+ const filePath = path.join(root, entry.file);
997
+ if (!fs.existsSync(filePath)) {
998
+ issues.push({
999
+ id: entry.id,
1000
+ type: 'BROKEN_REF',
1001
+ severity: 'warning',
1002
+ message: `Referenced file does not exist: ${entry.file}`,
1003
+ projectPath: root,
1004
+ });
1005
+ } else if (entry.lines) {
1006
+ // Check line numbers are in range
1007
+ const lineRange = parseLineRange(entry.lines);
1008
+ if (lineRange) {
1009
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
1010
+ const totalLines = fileContent.split('\n').length;
1011
+ if (lineRange.end > totalLines) {
1012
+ issues.push({
1013
+ id: entry.id,
1014
+ type: 'BROKEN_REF',
1015
+ severity: 'warning',
1016
+ message: `Line range ${entry.lines} exceeds file length (${totalLines} lines)`,
1017
+ projectPath: root,
1018
+ });
1019
+ }
1020
+ }
1021
+ }
1022
+ }
1023
+
1024
+ // Check commit OID if location.commit is present (v1.4)
1025
+ if (entry.location?.commit) {
1026
+ try {
1027
+ execSync(`git cat-file -e ${entry.location.commit}`, {
1028
+ cwd: root,
1029
+ stdio: 'ignore'
1030
+ });
1031
+ } catch {
1032
+ issues.push({
1033
+ id: entry.id,
1034
+ type: 'BROKEN_REF',
1035
+ severity: 'warning',
1036
+ message: `Referenced commit does not exist: ${entry.location.commit}`,
1037
+ projectPath: root,
1038
+ });
1039
+ }
1040
+ }
1041
+ }
1042
+
1043
+ return issues;
1044
+ }
1045
+
1046
+ /**
1047
+ * Validate security (secrets, PII)
1048
+ *
1049
+ * TODO v1.6: Enhanced pattern matching
1050
+ * - Add credit card patterns (Luhn algorithm validation)
1051
+ * - Add CVV patterns (3-4 digits)
1052
+ * - Add SSN patterns (XXX-XX-XXXX)
1053
+ * - Add API key patterns (common formats)
1054
+ * - Add file-based logging detection (console.log with sensitive data)
1055
+ * - See: src/utils/v1.6-patterns.ts (commented out for v1.6)
1056
+ */
1057
+ function validateSecurity(entries: MemoryEntry[], root: string): BuddyIssue[] {
1058
+ const issues: BuddyIssue[] = [];
1059
+
1060
+ for (const entry of entries) {
1061
+ const content = entry.details || entry.code || '';
1062
+
1063
+ // Check for secrets
1064
+ for (const pattern of SECRET_PATTERNS) {
1065
+ const matches = content.match(pattern.pattern);
1066
+ if (matches) {
1067
+ // RED if agent-origin, YELLOW if human
1068
+ const severity = entry.sourceType === 'agent' ? 'error' : 'warning';
1069
+ issues.push({
1070
+ id: entry.id,
1071
+ type: 'SECRET',
1072
+ severity,
1073
+ message: `Potential secret detected (${pattern.name}): ${matches[0].substring(0, 20)}...`,
1074
+ projectPath: root,
1075
+ suggestion: 'Remove secret from memory entry',
1076
+ });
1077
+ }
1078
+ }
1079
+
1080
+ // Check for PII (emails, IDs)
1081
+ const emailPattern = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g;
1082
+ const emailMatches = content.match(emailPattern);
1083
+ if (emailMatches && entry.sourceType === 'agent') {
1084
+ issues.push({
1085
+ id: entry.id,
1086
+ type: 'PII',
1087
+ severity: 'error',
1088
+ message: `PII detected (email): ${emailMatches[0]}`,
1089
+ projectPath: root,
1090
+ suggestion: 'Remove PII from memory entry',
1091
+ });
1092
+ }
1093
+
1094
+ // TODO v1.6: Enhanced patterns (see src/utils/v1.6-patterns.ts)
1095
+ // - Credit card: /(?:\d{4}[-\s]?){3}\d{4}/g + Luhn validation
1096
+ // - CVV: /\b\d{3,4}\b/g (context-dependent)
1097
+ // - SSN: /\b\d{3}-\d{2}-\d{4}\b/g
1098
+ // - API keys: Common formats (AWS, Google, etc.)
1099
+ // - File logging: console.log/logger.* with sensitive patterns
1100
+ }
1101
+
1102
+ return issues;
1103
+ }
1104
+
1105
+ /**
1106
+ * Detect stale records (file changed since commit)
1107
+ */
1108
+ function detectStaleness(entries: MemoryEntry[], root: string): BuddyIssue[] {
1109
+ const issues: BuddyIssue[] = [];
1110
+
1111
+ for (const entry of entries) {
1112
+ if (entry.location?.commit && entry.file) {
1113
+ try {
1114
+ // Check if file has changed since commit
1115
+ const filePath = path.join(root, entry.file);
1116
+ if (fs.existsSync(filePath)) {
1117
+ const currentCommit = execSync('git rev-parse HEAD', {
1118
+ cwd: root,
1119
+ encoding: 'utf-8'
1120
+ }).trim();
1121
+
1122
+ if (currentCommit !== entry.location.commit) {
1123
+ // File has changed - mark as stale
1124
+ issues.push({
1125
+ id: entry.id,
1126
+ type: 'STALE',
1127
+ severity: 'warning',
1128
+ message: `File changed since commit ${entry.location.commit.substring(0, 8)}`,
1129
+ projectPath: root,
1130
+ suggestion: 'Update memory entry or rebuild graph',
1131
+ });
1132
+ }
1133
+ }
1134
+ } catch {
1135
+ // Git not available or file doesn't exist - skip
1136
+ }
1137
+ }
1138
+ }
1139
+
1140
+ return issues;
1141
+ }
1142
+
1143
+ /**
1144
+ * Validate policy rules
1145
+ *
1146
+ * TODO v1.6: Add Git-based protected file detection
1147
+ * - Use `git diff --name-only HEAD` to get changed files
1148
+ * - Cross-reference with protected.txt
1149
+ * - Detect protected file modifications (RED status)
1150
+ * - Detect file deletions (via `git diff --diff-filter=D`)
1151
+ * - Detect large-scale changes (via `git diff --stat` line count > threshold)
1152
+ */
1153
+ function validatePolicies(entries: MemoryEntry[], root: string): BuddyIssue[] {
1154
+ const issues: BuddyIssue[] = [];
1155
+
1156
+ // Policy: "Prefer fresh code over memory"
1157
+ // Policy: "No secrets in memory"
1158
+ // (Already checked in validateSecurity)
1159
+
1160
+ // TODO v1.6: Protected file detection via Git diff
1161
+ // const protectedFiles = readLines(getFilePath('PROTECTED', root));
1162
+ // const changedFiles = getChangedFiles(root);
1163
+ // for (const file of changedFiles) {
1164
+ // if (protectedFiles.includes(file)) {
1165
+ // issues.push({
1166
+ // type: 'PROTECTED_FILE',
1167
+ // severity: 'error',
1168
+ // message: `Protected file modified: ${file}`,
1169
+ // projectPath: root,
1170
+ // suggestion: 'Review changes or remove from protected.txt',
1171
+ // });
1172
+ // }
1173
+ // }
1174
+
1175
+ // Policy: "Agent records should be DRAFT until verified"
1176
+ for (const entry of entries) {
1177
+ if (entry.sourceType === 'agent' && entry.memoryStatus !== 'DRAFT') {
1178
+ issues.push({
1179
+ id: entry.id,
1180
+ type: 'POLICY',
1181
+ severity: 'info',
1182
+ message: 'Agent-origin record should be DRAFT until verified',
1183
+ projectPath: root,
1184
+ suggestion: 'Mark as DRAFT or promote to VERIFIED after review',
1185
+ });
1186
+ }
1187
+ }
1188
+
1189
+ return issues;
1190
+ }
1191
+
1192
+ /**
1193
+ * Validate consistency (code + memory changes)
1194
+ */
1195
+ function validateConsistency(entries: MemoryEntry[], root: string, changedFiles: string[]): BuddyIssue[] {
1196
+ const issues: BuddyIssue[] = [];
1197
+
1198
+ // Check if memory entries match changed files
1199
+ for (const entry of entries) {
1200
+ if (entry.file && changedFiles.length > 0 && !changedFiles.includes(entry.file)) {
1201
+ // Entry references file that wasn't changed - might be inconsistent
1202
+ issues.push({
1203
+ id: entry.id,
1204
+ type: 'CONFLICT',
1205
+ severity: 'info',
1206
+ message: `Memory entry references unchanged file: ${entry.file}`,
1207
+ projectPath: root,
1208
+ });
1209
+ }
1210
+ }
1211
+
1212
+ return issues;
1213
+ }
1214
+
1215
+ /**
1216
+ * Calculate Buddy-Check status from issues
1217
+ */
1218
+ function calculateBuddyStatus(issues: BuddyIssue[]): BuddyStatus {
1219
+ // RED: Any error-level issues
1220
+ if (issues.some(i => i.severity === 'error')) {
1221
+ return 'RED';
1222
+ }
1223
+
1224
+ // YELLOW: Any warnings
1225
+ if (issues.some(i => i.severity === 'warning')) {
1226
+ return 'YELLOW';
1227
+ }
1228
+
1229
+ // GREEN: No errors or warnings
1230
+ return 'GREEN';
1231
+ }
1232
+
1233
+ /**
1234
+ * Generate summary text
1235
+ */
1236
+ function generateSummary(status: BuddyStatus, issueCount: number, recordCount: number): string {
1237
+ if (status === 'RED') {
1238
+ return `RED: ${issueCount} critical issue(s) found in ${recordCount} records`;
1239
+ } else if (status === 'YELLOW') {
1240
+ return `YELLOW: ${issueCount} warning(s) found in ${recordCount} records`;
1241
+ } else {
1242
+ return `GREEN: All checks passed for ${recordCount} records`;
1243
+ }
1244
+ }
1245
+
1246
+ /**
1247
+ * Count trust levels in entries
1248
+ */
1249
+ function countTrustLevels(entries: MemoryEntry[]): { high: number; medium: number; low: number } {
1250
+ let high = 0;
1251
+ let medium = 0;
1252
+ let low = 0;
1253
+
1254
+ for (const entry of entries) {
1255
+ const trust = entry.trustLevel || 'medium';
1256
+ if (trust === 'high') high++;
1257
+ else if (trust === 'low') low++;
1258
+ else medium++;
1259
+ }
1260
+
1261
+ return { high, medium, low };
1262
+ }
1263
+
1264
+ /**
1265
+ * Get changed files from Git
1266
+ */
1267
+ function getChangedFiles(root: string): string[] {
1268
+ try {
1269
+ const output = execSync('git diff --name-only HEAD', {
1270
+ cwd: root,
1271
+ encoding: 'utf-8'
1272
+ });
1273
+ return output.split('\n').filter(f => f.trim()).map(f => f.trim());
1274
+ } catch {
1275
+ return [];
1276
+ }
1277
+ }
1278
+
1279
+ /**
1280
+ * Parse line range (e.g., "42-50" or "42")
1281
+ */
1282
+ function parseLineRange(lines: string): { start: number; end: number } | null {
1283
+ if (lines.includes('-')) {
1284
+ const [start, end] = lines.split('-').map(n => parseInt(n, 10));
1285
+ if (!isNaN(start) && !isNaN(end)) {
1286
+ return { start, end };
1287
+ }
1288
+ } else {
1289
+ const line = parseInt(lines, 10);
1290
+ if (!isNaN(line)) {
1291
+ return { start: line, end: line };
1292
+ }
1293
+ }
1294
+ return null;
1295
+ }
1296
+
1297
+ /**
1298
+ * Mark agent records as DRAFT (for postflight --fix)
1299
+ */
1300
+ async function markAgentRecordsAsDraft(entries: MemoryEntry[], root: string): Promise<void> {
1301
+ const memoryPath = getFilePath('MEMORY', root);
1302
+ const updatedEntries: MemoryEntry[] = [];
1303
+ let updated = false;
1304
+
1305
+ for (const entry of entries) {
1306
+ if (entry.sourceType === 'agent' && entry.memoryStatus !== 'DRAFT') {
1307
+ updatedEntries.push({
1308
+ ...entry,
1309
+ memoryStatus: 'DRAFT',
1310
+ recordVersion: (entry.recordVersion || 1) + 1,
1311
+ });
1312
+ updated = true;
1313
+ } else {
1314
+ updatedEntries.push(entry);
1315
+ }
1316
+ }
1317
+
1318
+ if (updated) {
1319
+ // Write updated entries back
1320
+ const jsonl = updatedEntries.map(e => JSON.stringify(e)).join('\n') + '\n';
1321
+ fs.writeFileSync(memoryPath, jsonl);
1322
+ info('Marked agent records as DRAFT');
1323
+ }
1324
+ }
1325
+
1326
+ /**
1327
+ * Handle human override for RED status
1328
+ */
1329
+ async function handleOverride(
1330
+ report: BuddyReport,
1331
+ root: string | null,
1332
+ options: DoctorOptions
1333
+ ): Promise<BuddyReport> {
1334
+ if (!root) {
1335
+ return report;
1336
+ }
1337
+
1338
+ // Check if in strict mode (would require override)
1339
+ const config = readConfig(root);
1340
+ const isStrict = config?.strict === true || config?.mode === 'enterprise';
1341
+
1342
+ if (!isStrict) {
1343
+ // Developer mode: allow override but don't require it
1344
+ return report;
1345
+ }
1346
+
1347
+ // In strict mode, prompt for override
1348
+ console.log('');
1349
+ warn('⚠️ RED status detected - override required in strict mode');
1350
+ console.log('');
1351
+
1352
+ // For now, we'll just return the report without override
1353
+ // In a full implementation, this would prompt for:
1354
+ // - approvedBy (user name/ID)
1355
+ // - reason (why override is needed)
1356
+
1357
+ // For CLI, we can use environment variables or flags
1358
+ const overrideBy = process.env.MEMORYLINK_OVERRIDE_BY || options.for || 'unknown';
1359
+ const overrideReason = process.env.MEMORYLINK_OVERRIDE_REASON || 'Manual override via CLI';
1360
+
1361
+ if (overrideBy !== 'unknown' || overrideReason !== 'Manual override via CLI') {
1362
+ const override: BuddyOverride = {
1363
+ approvedBy: overrideBy,
1364
+ reason: overrideReason,
1365
+ timestamp: new Date().toISOString(),
1366
+ };
1367
+
1368
+ return {
1369
+ ...report,
1370
+ override,
1371
+ };
1372
+ }
1373
+
1374
+ return report;
1375
+ }
1376
+
1377
+ /**
1378
+ * Log override to overrides.log (JSONL)
1379
+ *
1380
+ * TODO v1.6: Enhanced override logging
1381
+ * - Add report ID reference
1382
+ * - Add issue IDs that were overridden
1383
+ * - Add context (branch, PR, agent)
1384
+ * - Add audit trail fields (who, when, why, what)
1385
+ * - Format: { approvedBy, reason, timestamp, runType, reportId, issueIds[], context: { branch, pr, agent } }
1386
+ */
1387
+ function logOverride(override: BuddyOverride, runType: 'preflight' | 'postflight', root: string): void {
1388
+ try {
1389
+ const overridesPath = path.join(root, MEMORYLINK_DIR, 'overrides.log');
1390
+ const entry = {
1391
+ ...override,
1392
+ runType,
1393
+ // TODO v1.6: Add reportId, issueIds[], context
1394
+ };
1395
+ const jsonlLine = JSON.stringify(entry) + '\n';
1396
+ fs.appendFileSync(overridesPath, jsonlLine, 'utf-8');
1397
+ } catch (err) {
1398
+ // Silently fail - override logging should not break the main flow
1399
+ }
1400
+ }
1401
+
1402
+ /**
1403
+ * Print Buddy-Check report
1404
+ */
1405
+ function printBuddyReport(report: BuddyReport): void {
1406
+ // Check if stdout is writable before printing
1407
+ if (!isStdoutWritable()) {
1408
+ return; // Silently return if stdout is closed
1409
+ }
1410
+
1411
+ safeLog('');
1412
+ safeLog('\x1b[1m🔍 Buddy-Check Report\x1b[0m');
1413
+ safeLog('');
1414
+
1415
+ // Status indicator
1416
+ let statusColor = '\x1b[32m'; // GREEN
1417
+ let statusIcon = '●';
1418
+ if (report.status === 'YELLOW') {
1419
+ statusColor = '\x1b[33m'; // YELLOW
1420
+ } else if (report.status === 'RED') {
1421
+ statusColor = '\x1b[31m'; // RED
1422
+ }
1423
+
1424
+ safeLog(` Status: ${statusColor}${statusIcon} ${report.status}\x1b[0m`);
1425
+ safeLog(` ${report.summary}`);
1426
+ safeLog('');
1427
+
1428
+ if (report.issues.length > 0) {
1429
+ safeLog(` Issues (${report.issues.length}):`);
1430
+ for (const issue of report.issues.slice(0, 10)) {
1431
+ const severityColor = issue.severity === 'error' ? '\x1b[31m' :
1432
+ issue.severity === 'warning' ? '\x1b[33m' : '\x1b[36m';
1433
+ safeLog(` ${severityColor}${issue.severity.toUpperCase()}\x1b[0m [${issue.type}] ${issue.message}`);
1434
+ if (issue.suggestion) {
1435
+ safeLog(` 💡 ${issue.suggestion}`);
1436
+ }
1437
+ }
1438
+ if (report.issues.length > 10) {
1439
+ safeLog(` ... and ${report.issues.length - 10} more`);
1440
+ }
1441
+ } else {
1442
+ safeLog(' ✓ No issues found');
1443
+ }
1444
+
1445
+ if (report.recordsUsed !== undefined) {
1446
+ safeLog('');
1447
+ safeLog(` Records: ${report.recordsUsed} checked`);
1448
+ if (report.highTrust !== undefined) {
1449
+ safeLog(` Trust: ${report.highTrust} high, ${report.mediumTrust} medium, ${report.lowTrust} low`);
1450
+ }
1451
+ if (report.staleCount !== undefined && report.staleCount > 0) {
1452
+ safeLog(` Stale: ${report.staleCount}`);
1453
+ }
1454
+ }
1455
+
1456
+ if (report.durationMs !== undefined) {
1457
+ safeLog(` Duration: ${report.durationMs}ms`);
1458
+ }
1459
+
1460
+ if (report.override) {
1461
+ safeLog('');
1462
+ warn(`⚠️ Override: Approved by ${report.override.approvedBy}`);
1463
+ safeLog(` Reason: ${report.override.reason}`);
1464
+ }
1465
+
1466
+ safeLog('');
1467
+ }
1468
+