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.
- package/.cursorrules +0 -0
- package/.github/workflows/buddy-check.yml +105 -0
- package/.github/workflows/memorylink-preflight.yml +63 -0
- package/.github/workflows/release-on-tag.yml +58 -0
- package/.github/workflows/stress-tests.yml +79 -0
- package/.memorylinkignore +24 -0
- package/5000_SCENARIOS_TEST_RESULTS.md +174 -0
- package/ADVANCED_SCENARIOS_TEST_RESULTS.md +377 -0
- package/AGGRESSIVE_RANDOM_TEST_RESULTS.md +134 -0
- package/AI_CONSENSUS_ANALYSIS.md +138 -0
- package/AI_CONSENSUS_ANALYSIS_FINAL.md +345 -0
- package/AI_CONSENSUS_ANALYSIS_v2.md +188 -0
- package/AI_CONSENSUS_ANALYSIS_v3.md +246 -0
- package/AI_CONSENSUS_ANALYSIS_v4.md +309 -0
- package/AI_CONSENSUS_ANALYSIS_v5.md +311 -0
- package/AI_CONSENSUS_ANALYSIS_v6.md +432 -0
- package/AI_PANEL_CLARIFICATION_REQUEST.md +37 -0
- package/AI_RESPONSES_BLACKBOX.md +338 -0
- package/AI_RESPONSES_CHATGPT.md +379 -0
- package/AI_RESPONSES_CLAUDE.md +464 -0
- package/AI_RESPONSES_CONSOLIDATED.md +560 -0
- package/AI_RESPONSES_DEEPSEEK.md +341 -0
- package/AI_RESPONSES_GEMINI.md +262 -0
- package/AI_RESPONSES_GROK.md +335 -0
- package/AI_RESPONSES_MANUS.md +246 -0
- package/AI_RESPONSES_PERPLEXITY.md +295 -0
- package/AI_RESPONSES_QWEN.md +335 -0
- package/AI_REVIEW_REQUEST.md +333 -0
- package/AI_STRATEGIC_CONSENSUS_COMPARISON.md +507 -0
- package/AI_VALIDATION_AND_GAP_ANALYSIS.md +410 -0
- package/ALL_10_AI_RESPONSES_FINAL.md +435 -0
- package/ALL_3_AI_RESPONSES_FINAL.md +305 -0
- package/ALL_4_AI_RESPONSES_FINAL.md +335 -0
- package/ALL_5_AI_RESPONSES_FINAL.md +349 -0
- package/ALL_6_AI_RESPONSES_FINAL.md +354 -0
- package/ALL_7_AI_RESPONSES_FINAL.md +369 -0
- package/ALL_8_AI_RESPONSES_FINAL.md +381 -0
- package/ALL_9_AI_RESPONSES_FINAL.md +398 -0
- package/ALL_AI_RESPONSES_TRACKER.md +152 -0
- package/ALL_AI_RESPONSES_VALIDATED.md +261 -0
- package/ALL_FEATURES_COMPLETE.md +198 -0
- package/BREAK_IT_TEST_RESULTS.md +273 -0
- package/BUDDY_CHECK_STRESS_TEST_PLAN.md +1089 -0
- package/CHANGELOG.md +135 -0
- package/CHATGPT_GAP_ANALYSIS.md +286 -0
- package/CHATGPT_V2_ANALYSIS.md +109 -0
- package/CHECK_MISSING_FEATURES.md +192 -0
- package/CI_CD_INTEGRATION.md +421 -0
- package/COMPETITIVE_LAUNCH_STRATEGY.md +257 -0
- package/COMPLETE_COMPETITIVE_ANALYSIS_ALL_AIS.md +339 -0
- package/COMPLETE_DEVELOPMENT_PLAN_ALL_AIS.md +622 -0
- package/COMPREHENSIVE_FEATURE_ANALYSIS_100_PERCENT.md +423 -0
- package/COMPREHENSIVE_TEST_SUMMARY.md +314 -0
- package/CONTINUOUS_TESTING_COMPLETE.md +268 -0
- package/CONTINUOUS_TESTING_GUIDE.md +328 -0
- package/CONTINUOUS_TEST_FINAL_RESULTS.md +148 -0
- package/CONTINUOUS_TEST_INSTRUCTIONS.md +173 -0
- package/CONTINUOUS_TEST_RESULTS.md +194 -0
- package/CONTINUOUS_TEST_STATUS.md +68 -0
- package/CURSOR_AI_BUDDY_CHECK_GUIDE.md +439 -0
- package/CURSOR_AI_INTEGRATION_GUIDE.md +775 -0
- package/CURSOR_AI_V1.4_NEXT_STEPS.md +314 -0
- package/CURSOR_BREAK_IT_TEST.md +389 -0
- package/CURSOR_DOCUMENTATION_RULES.md +259 -0
- package/CURSOR_HOSTILE_TEST_DOCUMENT.md +343 -0
- package/CURSOR_PROMPTS_FOR_TESTING.md +252 -0
- package/DEPLOYMENT_GUIDE.md +493 -0
- package/DEVELOPMENT_AND_OVERNIGHT_TESTING.md +304 -0
- package/DEVELOPMENT_PROGRESS.md +185 -0
- package/DOCS_CLEANUP_SUMMARY.md +192 -0
- package/DOC_CONFIDENTIALITY_RULES.md +259 -0
- package/E2E_TEST_REPORT_v1.3.0.md +196 -0
- package/E2E_TEST_RESULTS.md +250 -0
- package/E2E_TEST_SCENARIOS.md +357 -0
- package/END_TO_END_TEST_REPORT.md +217 -0
- package/ENHANCEMENT_RECOMMENDATIONS.md +368 -0
- package/EPIPE_FIX_SUMMARY.md +177 -0
- package/FEEDBACK_TEMPLATE.md +173 -0
- package/FINAL_100_PERCENT_CONFIRMATION.md +319 -0
- package/FINAL_8_AI_CONSENSUS_SUMMARY.md +355 -0
- package/FINAL_CONFIRMATION.md +143 -0
- package/FINAL_E2E_TEST_REPORT.md +248 -0
- package/FINAL_E2E_TEST_RESULTS.md +212 -0
- package/FINAL_LAUNCH_CLARIFICATION_SUMMARY.md +101 -0
- package/FINAL_LAUNCH_PLAN_BASED_ON_AI_CONSENSUS.md +410 -0
- package/FINAL_LAUNCH_SUMMARY.md +176 -0
- package/FINAL_PRODUCT_TEST.md +316 -0
- package/FINAL_PROJECT_STATUS.md +407 -0
- package/FINAL_STATUS_REPORT.md +244 -0
- package/FINAL_STRATEGIC_PLAN_9_AIS.md +576 -0
- package/FINAL_TEST_EXECUTION_REPORT.md +252 -0
- package/FINAL_VALIDATION_DOCUMENT.md +238 -0
- package/FINAL_VALIDATION_SUMMARY.md +230 -0
- package/FIX_SPECIAL_CHARS.sh +13 -0
- package/FRESH_SCENARIOS_TEST_RESULTS.md +358 -0
- package/GAP_EVALUATION_TEMPLATE.md +146 -0
- package/GITHUB_SETUP_GUIDE.md +193 -0
- package/HOSTILE_TEST_RESULTS.md +221 -0
- package/HOW_MEMORYLINK_HELPS_AI.md +401 -0
- package/IMPLEMENTATION_PLANS_DETAILED.md +516 -0
- package/LAUNCH_CHECKLIST.md +247 -0
- package/LAUNCH_DOCS_FRAMEWORK.md +378 -0
- package/LAUNCH_READINESS.md +148 -0
- package/LAUNCH_SEQUENCE.md +137 -0
- package/LICENSE +67 -0
- package/MARKET_ANALYSIS_AND_STRATEGY.md +280 -0
- package/MASTER_AI_VERIFICATION_DOCUMENT.md +1085 -0
- package/MASTER_VALIDATION_DOCUMENT.md +818 -0
- package/MINORITY_OPINION_ANALYSIS.md +464 -0
- package/NEW_RANDOM_TEST_RESULTS.md +127 -0
- package/NEW_SCENARIOS_TEST_RESULTS.md +272 -0
- package/NEXT_ACTIONS_COMPLETE.md +137 -0
- package/NEXT_PLAN_BASED_ON_AI_ANALYSES.md +413 -0
- package/NEXT_PLAN_BASED_ON_ALL_AI_RESPONSES.md +558 -0
- package/NEXT_STEPS.md +120 -0
- package/NEXT_STEPS_ACTION_PLAN.md +369 -0
- package/NPM_2FA_FIX.md +113 -0
- package/NPM_PUBLISH_TROUBLESHOOTING.md +230 -0
- package/PERPLEXITY_AI_VALIDATION_REQUEST.md +318 -0
- package/PERPLEXITY_AI_VALIDATION_RESPONSE.md +172 -0
- package/PERPLEXITY_BREAK_IT_VALIDATION.md +262 -0
- package/PERPLEXITY_DOCS_VALIDATION.md +237 -0
- package/PERPLEXITY_FEEDBACK_ACTION_PLAN.md +271 -0
- package/PERPLEXITY_FINAL_E2E_VALIDATION.md +210 -0
- package/PERPLEXITY_FINAL_SUMMARY.md +211 -0
- package/PERPLEXITY_PHASE2_VALIDATION.md +270 -0
- package/PERPLEXITY_PHASE2_VALIDATION_RESPONSE.md +136 -0
- package/PERPLEXITY_PRIORITY2_VALIDATION.md +321 -0
- package/PERPLEXITY_TELEMETRY_EXPLANATION.md +174 -0
- package/PERPLEXITY_TELEMETRY_VALIDATION.md +118 -0
- package/PERPLEXITY_TELEMETRY_VALIDATION_RESPONSE.md +154 -0
- package/PERPLEXITY_USER_GUIDE_VALIDATION.md +236 -0
- package/PERPLEXITY_VALIDATION_REQUEST.md +427 -0
- package/PERPLEXITY_VALIDATION_REQUEST_v1.5.1.md +190 -0
- package/PHASE_2_COMPLETE.md +149 -0
- package/PRE_LAUNCH_SECURITY_AUDIT.md +155 -0
- package/PRE_LAUNCH_TEST_CYCLE.md +326 -0
- package/PRE_LAUNCH_TEST_RESULTS.md +148 -0
- package/PROJECT_STRUCTURE_PLAN.md +104 -0
- package/PUBLIC_DOCS.md +90 -0
- package/PUBLISH_CHECKLIST.md +134 -0
- package/PUSH_INSTRUCTIONS.md +120 -0
- package/QUICK_START_TEST_CYCLE.md +76 -0
- package/README.md +557 -0
- package/README_TEST_INSTRUCTIONS.md +65 -0
- package/README_v1.5.1.md +137 -0
- package/REALISTIC_ASSESSMENT.md +186 -0
- package/REAL_WORLD_VALIDATION_COMPLETE.md +98 -0
- package/RED_TEAM_TESTING_GUIDE.md +302 -0
- package/RELEASE_NOTES_v1.0.0.md +125 -0
- package/RELEASE_NOTES_v1.5.1.md +105 -0
- package/REQUEST_COUNTERS.md +22 -0
- package/ROADMAP_v1.6.md +335 -0
- package/ROUND3_RANDOM_TEST_RESULTS.md +135 -0
- package/SECURITY_MODEL.md +577 -0
- package/SESSION_SUMMARY_CURRENT_STATE.md +206 -0
- package/SESSION_SUMMARY_REVIEW.md +203 -0
- package/SINGLE_RUN_ALL_SCENARIOS_TEST.sh +129 -0
- package/STRATEGIC_QUESTIONS_FOR_AI_VALIDATION.md +277 -0
- package/STRESS_TEST_CHECK_RESULTS.md +154 -0
- package/STRESS_TEST_EXECUTION_GUIDE.md +284 -0
- package/STRESS_TEST_IMPLEMENTATION_SUMMARY.md +221 -0
- package/TELEMETRY.md +370 -0
- package/TELEMETRY_COMPLETE_SUMMARY.md +231 -0
- package/TELEMETRY_CONTROL_POLICY.md +135 -0
- package/TELEMETRY_DESIGN_SUMMARY.md +210 -0
- package/TELEMETRY_FINAL_STATUS.md +178 -0
- package/TELEMETRY_NEXT_STEPS.md +258 -0
- package/TELEMETRY_TESTING_NOTES.md +217 -0
- package/TELEMETRY_WORK_COMPLETE.md +237 -0
- package/TEST_PLAN_v1.0.1.md +194 -0
- package/TEST_RESULTS_SUMMARY.md +128 -0
- package/TREE_SITTER_EXPLANATION.md +303 -0
- package/TROUBLESHOOTING.md +62 -0
- package/ULTIMATE_SCENARIOS_TEST_RESULTS.md +366 -0
- package/USER_FEEDBACK_TEMPLATE.md +104 -0
- package/USER_GUIDE.md +809 -0
- package/V1.1_DEVELOPMENT_COMPLETE.md +299 -0
- package/V1.1_SCENARIOS_ADDED.md +161 -0
- package/V1.2_CODE_STRUCTURE_IMPLEMENTATION.md +243 -0
- package/V1.3_COMPETITIVE_LAUNCH_COMPLETE.md +253 -0
- package/V1.3_COMPETITIVE_LAUNCH_IMPLEMENTATION_PLAN.md +385 -0
- package/V1.3_TEAM_PATTERNS_IMPLEMENTATION.md +183 -0
- package/V1.4_BUILD_PLAN_IMPLEMENTATION.md +698 -0
- package/V1.4_COMPLETE_SUMMARY_FOR_AI_REVIEW.md +516 -0
- package/V1.4_COMPLETE_VALIDATION_DOCUMENT.md +601 -0
- package/V1.4_DEVELOPMENT_PROGRESS.md +117 -0
- package/V1.4_FINAL_STATUS.md +147 -0
- package/V1.4_INTEGRATION_COMPLETE.md +207 -0
- package/V1.4_INTEGRATION_TEST_RESULTS.md +181 -0
- package/V1.4_OBSERVABILITY_AND_OVERRIDE_COMPLETE.md +180 -0
- package/V1.4_PHASE_3_COMPLETE.md +135 -0
- package/V1.4_RUNTIME_TESTING_GUIDE.md +364 -0
- package/V1.4_VERIFICATION_REPORT.md +199 -0
- package/V1.5.1_COMPLETE_SUMMARY.md +234 -0
- package/V1.5.1_RELEASE_NOTES.md +206 -0
- package/V1.5.1_RELEASE_READY.md +198 -0
- package/V1.5_COMPLETE_SUMMARY.md +264 -0
- package/V1.5_COMPLETE_VERIFICATION.md +183 -0
- package/V1.5_DESIGN_NOTES.md +272 -0
- package/V1.5_FINAL_STATUS.md +224 -0
- package/V1.5_IMPLEMENTATION_SUMMARY.md +113 -0
- package/V1.5_IMPROVEMENTS_COMPLETE.md +205 -0
- package/V1.5_PHASE1_COMPLETE.md +183 -0
- package/V1.5_PHASE1_PROGRESS.md +102 -0
- package/V1.5_PHASE2_COMPLETE.md +133 -0
- package/V1.5_PHASE2_PLAN.md +185 -0
- package/V1.5_PRIORITIZATION.md +313 -0
- package/V1.5_PRIORITY2_COMPLETE.md +150 -0
- package/V1.5_TESTING_COMPLETE.md +69 -0
- package/V1.5_TEST_RESULTS.md +178 -0
- package/V1.5_VALIDATION_RESULTS.md +209 -0
- package/V1.6_GAP_TRACKING.md +118 -0
- package/VALIDATION_SUMMARY_FOR_PERPLEXITY.md +83 -0
- package/VERIFICATION_REPORT.md +220 -0
- package/VERSION_UPDATE_VERIFICATION.md +76 -0
- package/config/tsconfig.json +21 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1114 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/archive.d.ts +20 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +231 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/auto-context.d.ts +22 -0
- package/dist/commands/auto-context.d.ts.map +1 -0
- package/dist/commands/auto-context.js +172 -0
- package/dist/commands/auto-context.js.map +1 -0
- package/dist/commands/auto-log.d.ts +30 -0
- package/dist/commands/auto-log.d.ts.map +1 -0
- package/dist/commands/auto-log.js +500 -0
- package/dist/commands/auto-log.js.map +1 -0
- package/dist/commands/change.d.ts +13 -0
- package/dist/commands/change.d.ts.map +1 -0
- package/dist/commands/change.js +254 -0
- package/dist/commands/change.js.map +1 -0
- package/dist/commands/checkpoint.d.ts +26 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +326 -0
- package/dist/commands/checkpoint.js.map +1 -0
- package/dist/commands/configure.d.ts +21 -0
- package/dist/commands/configure.d.ts.map +1 -0
- package/dist/commands/configure.js +283 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/commands/consolidate.d.ts +19 -0
- package/dist/commands/consolidate.d.ts.map +1 -0
- package/dist/commands/consolidate.js +236 -0
- package/dist/commands/consolidate.js.map +1 -0
- package/dist/commands/context.d.ts +10 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +571 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/detect.d.ts +13 -0
- package/dist/commands/detect.d.ts.map +1 -0
- package/dist/commands/detect.js +187 -0
- package/dist/commands/detect.js.map +1 -0
- package/dist/commands/doctor.d.ts +19 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +1272 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +95 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/graph.d.ts +25 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +208 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/hooks.d.ts +9 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +240 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/impact.d.ts +18 -0
- package/dist/commands/impact.d.ts.map +1 -0
- package/dist/commands/impact.js +163 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/index-vector.d.ts +13 -0
- package/dist/commands/index-vector.d.ts.map +1 -0
- package/dist/commands/index-vector.js +103 -0
- package/dist/commands/index-vector.js.map +1 -0
- package/dist/commands/index.d.ts +37 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +105 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +200 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inject.d.ts +22 -0
- package/dist/commands/inject.d.ts.map +1 -0
- package/dist/commands/inject.js +394 -0
- package/dist/commands/inject.js.map +1 -0
- package/dist/commands/learn.d.ts +13 -0
- package/dist/commands/learn.d.ts.map +1 -0
- package/dist/commands/learn.js +282 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/lock.d.ts +35 -0
- package/dist/commands/lock.d.ts.map +1 -0
- package/dist/commands/lock.js +308 -0
- package/dist/commands/lock.js.map +1 -0
- package/dist/commands/memory.d.ts +15 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +366 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/migrate.d.ts +22 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +458 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/patterns.d.ts +18 -0
- package/dist/commands/patterns.d.ts.map +1 -0
- package/dist/commands/patterns.js +120 -0
- package/dist/commands/patterns.js.map +1 -0
- package/dist/commands/protect.d.ts +12 -0
- package/dist/commands/protect.d.ts.map +1 -0
- package/dist/commands/protect.js +181 -0
- package/dist/commands/protect.js.map +1 -0
- package/dist/commands/quickstart.d.ts +11 -0
- package/dist/commands/quickstart.d.ts.map +1 -0
- package/dist/commands/quickstart.js +256 -0
- package/dist/commands/quickstart.js.map +1 -0
- package/dist/commands/repair.d.ts +13 -0
- package/dist/commands/repair.d.ts.map +1 -0
- package/dist/commands/repair.js +157 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/resolve.d.ts +19 -0
- package/dist/commands/resolve.d.ts.map +1 -0
- package/dist/commands/resolve.js +355 -0
- package/dist/commands/resolve.js.map +1 -0
- package/dist/commands/roadmap.d.ts +5 -0
- package/dist/commands/roadmap.d.ts.map +1 -0
- package/dist/commands/roadmap.js +23 -0
- package/dist/commands/roadmap.js.map +1 -0
- package/dist/commands/scopes.d.ts +10 -0
- package/dist/commands/scopes.d.ts.map +1 -0
- package/dist/commands/scopes.js +80 -0
- package/dist/commands/scopes.js.map +1 -0
- package/dist/commands/search.d.ts +9 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +313 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/setup.d.ts +13 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +405 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/snippet.d.ts +23 -0
- package/dist/commands/snippet.d.ts.map +1 -0
- package/dist/commands/snippet.js +235 -0
- package/dist/commands/snippet.js.map +1 -0
- package/dist/commands/stats.d.ts +15 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +502 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +134 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/suggest-tags.d.ts +9 -0
- package/dist/commands/suggest-tags.d.ts.map +1 -0
- package/dist/commands/suggest-tags.js +95 -0
- package/dist/commands/suggest-tags.js.map +1 -0
- package/dist/commands/sync-rules.d.ts +14 -0
- package/dist/commands/sync-rules.d.ts.map +1 -0
- package/dist/commands/sync-rules.js +211 -0
- package/dist/commands/sync-rules.js.map +1 -0
- package/dist/commands/sync.d.ts +24 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +330 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/telemetry-test.d.ts +24 -0
- package/dist/commands/telemetry-test.d.ts.map +1 -0
- package/dist/commands/telemetry-test.js +84 -0
- package/dist/commands/telemetry-test.js.map +1 -0
- package/dist/commands/template.d.ts +16 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +122 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/validate.d.ts +11 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +144 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/watch-preferences.d.ts +17 -0
- package/dist/commands/watch-preferences.d.ts.map +1 -0
- package/dist/commands/watch-preferences.js +172 -0
- package/dist/commands/watch-preferences.js.map +1 -0
- package/dist/commands/watch.d.ts +11 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +223 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config/thresholds.d.ts +8 -0
- package/dist/config/thresholds.d.ts.map +1 -0
- package/dist/config/thresholds.js +10 -0
- package/dist/config/thresholds.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/memorylink.d.ts +91 -0
- package/dist/memorylink.d.ts.map +1 -0
- package/dist/memorylink.js +208 -0
- package/dist/memorylink.js.map +1 -0
- package/dist/search/local-embeddings.d.ts +21 -0
- package/dist/search/local-embeddings.d.ts.map +1 -0
- package/dist/search/local-embeddings.js +87 -0
- package/dist/search/local-embeddings.js.map +1 -0
- package/dist/search/vector-search.d.ts +58 -0
- package/dist/search/vector-search.d.ts.map +1 -0
- package/dist/search/vector-search.js +535 -0
- package/dist/search/vector-search.js.map +1 -0
- package/dist/server/mcp-server.d.ts +18 -0
- package/dist/server/mcp-server.d.ts.map +1 -0
- package/dist/server/mcp-server.js +293 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/telemetry.d.ts +92 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +339 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/telemetry.test.d.ts +13 -0
- package/dist/telemetry.test.d.ts.map +1 -0
- package/dist/telemetry.test.js +324 -0
- package/dist/telemetry.test.js.map +1 -0
- package/dist/test-runner/TestRunner.d.ts +68 -0
- package/dist/test-runner/TestRunner.d.ts.map +1 -0
- package/dist/test-runner/TestRunner.js +384 -0
- package/dist/test-runner/TestRunner.js.map +1 -0
- package/dist/test-runner/performance-test.d.ts +36 -0
- package/dist/test-runner/performance-test.d.ts.map +1 -0
- package/dist/test-runner/performance-test.js +163 -0
- package/dist/test-runner/performance-test.js.map +1 -0
- package/dist/test-runner/run-tests.d.ts +7 -0
- package/dist/test-runner/run-tests.d.ts.map +1 -0
- package/dist/test-runner/run-tests.js +167 -0
- package/dist/test-runner/run-tests.js.map +1 -0
- package/dist/types.d.ts +400 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +81 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/batch-commits.d.ts +48 -0
- package/dist/utils/batch-commits.d.ts.map +1 -0
- package/dist/utils/batch-commits.js +164 -0
- package/dist/utils/batch-commits.js.map +1 -0
- package/dist/utils/code-structure.d.ts +62 -0
- package/dist/utils/code-structure.d.ts.map +1 -0
- package/dist/utils/code-structure.js +582 -0
- package/dist/utils/code-structure.js.map +1 -0
- package/dist/utils/commit-patterns.d.ts +24 -0
- package/dist/utils/commit-patterns.d.ts.map +1 -0
- package/dist/utils/commit-patterns.js +78 -0
- package/dist/utils/commit-patterns.js.map +1 -0
- package/dist/utils/observability.d.ts +47 -0
- package/dist/utils/observability.d.ts.map +1 -0
- package/dist/utils/observability.js +137 -0
- package/dist/utils/observability.js.map +1 -0
- package/dist/utils/quality.d.ts +32 -0
- package/dist/utils/quality.d.ts.map +1 -0
- package/dist/utils/quality.js +207 -0
- package/dist/utils/quality.js.map +1 -0
- package/dist/utils/semantic-search.d.ts +29 -0
- package/dist/utils/semantic-search.d.ts.map +1 -0
- package/dist/utils/semantic-search.js +167 -0
- package/dist/utils/semantic-search.js.map +1 -0
- package/dist/utils/streaming.d.ts +24 -0
- package/dist/utils/streaming.d.ts.map +1 -0
- package/dist/utils/streaming.js +121 -0
- package/dist/utils/streaming.js.map +1 -0
- package/dist/utils/tag-suggestions.d.ts +18 -0
- package/dist/utils/tag-suggestions.d.ts.map +1 -0
- package/dist/utils/tag-suggestions.js +103 -0
- package/dist/utils/tag-suggestions.js.map +1 -0
- package/dist/utils/team-patterns.d.ts +48 -0
- package/dist/utils/team-patterns.d.ts.map +1 -0
- package/dist/utils/team-patterns.js +413 -0
- package/dist/utils/team-patterns.js.map +1 -0
- package/dist/utils/templates.d.ts +36 -0
- package/dist/utils/templates.d.ts.map +1 -0
- package/dist/utils/templates.js +200 -0
- package/dist/utils/templates.js.map +1 -0
- package/dist/utils/tree-sitter-parser.d.ts +20 -0
- package/dist/utils/tree-sitter-parser.d.ts.map +1 -0
- package/dist/utils/tree-sitter-parser.js +259 -0
- package/dist/utils/tree-sitter-parser.js.map +1 -0
- package/dist/utils/v1.6-patterns.d.ts +117 -0
- package/dist/utils/v1.6-patterns.d.ts.map +1 -0
- package/dist/utils/v1.6-patterns.js +201 -0
- package/dist/utils/v1.6-patterns.js.map +1 -0
- package/dist/utils.d.ts +176 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +822 -0
- package/dist/utils.js.map +1 -0
- package/docs/1000_SCENARIOS_TEST_RESULTS.md +138 -0
- package/docs/1000_UNIQUE_SCENARIOS_TEST.md +171 -0
- package/docs/100_PERCENT_PASS_RATE_VERIFICATION.md +111 -0
- package/docs/5000_SCENARIOS_ISSUE_ANALYSIS.md +96 -0
- package/docs/5000_SCENARIOS_TEST_PLAN.md +281 -0
- package/docs/AGENT_CONTRACT.md +240 -0
- package/docs/AI_RESPONSE_ANALYZER.md +157 -0
- package/docs/AI_RESPONSE_TRACKER.md +923 -0
- package/docs/AI_TESTING_PROMPT.md +307 -0
- package/docs/AI_VALIDATION_PROMPTS.md +366 -0
- package/docs/ALL_AI_ANALYSES_CONSOLIDATED.md +354 -0
- package/docs/ALL_AI_CONSOLIDATION_FINAL.md +372 -0
- package/docs/ALL_AI_TEST_CONSOLIDATION.md +290 -0
- package/docs/ALL_AI_VALIDATION_SYNTHESIS.md +241 -0
- package/docs/BEST_TESTING_SOLUTION.md +227 -0
- package/docs/BLACKBOX_AI_ANALYSIS.md +288 -0
- package/docs/BLACKBOX_AI_CLARIFICATION.md +55 -0
- package/docs/BLACKBOX_AI_STRATEGIC_VALIDATION.md +283 -0
- package/docs/BLACKBOX_AI_VALIDATION_RESPONSE.md +251 -0
- package/docs/BLACKBOX_AI_VALIDATION_RESPONSE_v2.md +402 -0
- package/docs/BLACKBOX_LAUNCH_VALIDATION.md +25 -0
- package/docs/BLACKBOX_SUPERMEMORY_VALIDATION_AND_PLAN.md +50 -0
- package/docs/CAPACITY_AND_ALTERNATIVES_ANALYSIS.md +289 -0
- package/docs/CHATGPT_AI_CLARIFICATION.md +65 -0
- package/docs/CHATGPT_FINAL_VALIDATION.md +348 -0
- package/docs/CHATGPT_IMPLEMENTATION_GUIDE.md +325 -0
- package/docs/CHATGPT_LAUNCH_VALIDATION.md +47 -0
- package/docs/CHATGPT_MEMORY_QUALITY_AND_VSCODE_CHECK.md +43 -0
- package/docs/CHATGPT_SCOPE_REALITY_CHECK.md +35 -0
- package/docs/CHATGPT_STRATEGIC_VALIDATION.md +329 -0
- package/docs/CHATGPT_VALIDATION_RESPONSE.md +332 -0
- package/docs/CHATGPT_VALIDATION_RESPONSE_v2.md +294 -0
- package/docs/CHATGPT_VALIDATION_RESULTS.md +143 -0
- package/docs/CLAUDE_AI_ANALYSIS.md +692 -0
- package/docs/CLAUDE_AI_CLARIFICATION.md +67 -0
- package/docs/CLAUDE_AI_STRATEGIC_VALIDATION.md +578 -0
- package/docs/CLAUDE_AI_VALIDATION_RESPONSE.md +374 -0
- package/docs/CLAUDE_AI_VALIDATION_RESPONSE_v2.md +463 -0
- package/docs/CLAUDE_FINAL_VALIDATION.md +679 -0
- package/docs/CLAUDE_LAUNCH_VALIDATION.md +27 -0
- package/docs/CLAUDE_SUPERMEMORY_LAUNCH_PRIORITIES.md +44 -0
- package/docs/CLAUDE_UNIVERSAL_VISION.md +18 -0
- package/docs/COMPLETE_AI_VALIDATION_SYNTHESIS.md +229 -0
- package/docs/COMPLETE_MEMORY_ANALYSIS_SUMMARY.md +323 -0
- package/docs/COMPLETE_STRATEGIC_LAUNCH_PLAN.md +241 -0
- package/docs/COPILOT_LANGCHAIN_MEMORY_COMPARISON_AND_PLAN.md +43 -0
- package/docs/CRITICAL_FIXES_ACTION_PLAN.md +251 -0
- package/docs/CRITICAL_MEMORY_USAGE_PROMPTS.md +290 -0
- package/docs/CURSOR_AI_MEMORY_ANALYSIS.md +479 -0
- package/docs/CURSOR_AI_MEMORY_WORKFLOW_ANALYSIS.md +267 -0
- package/docs/CURSOR_AI_TEST_RESULTS.md +298 -0
- package/docs/DEEPSEEK_AI_CLARIFICATION.md +52 -0
- package/docs/DEEPSEEK_AI_IMPLEMENTATION_GUIDE.md +398 -0
- package/docs/DEEPSEEK_AI_STRATEGIC_VALIDATION.md +348 -0
- package/docs/DEEPSEEK_AI_VALIDATION_RESPONSE.md +276 -0
- package/docs/DEEPSEEK_AI_VALIDATION_RESPONSE_v2.md +325 -0
- package/docs/DEEPSEEK_FINAL_VALIDATION.md +337 -0
- package/docs/DEEPSEEK_LAUNCH_VALIDATION.md +55 -0
- package/docs/DEEPSEEK_SCOPE_REALITY_CHECK.md +30 -0
- package/docs/DEEPSEEK_SUPERMEMORY_ADOPTION_AND_VSCODE_PIVOT.md +47 -0
- package/docs/DEEPSEEK_VALIDATION_RESULTS.md +165 -0
- package/docs/DEVELOPMENT_TESTING_PROTOCOL.md +378 -0
- package/docs/E2E_TEST_RESULTS.md +102 -0
- package/docs/END_TO_END_MEMORY_ISSUE_ANALYSIS.md +442 -0
- package/docs/FEATURE_1_GIT_SYNC_PLAN.md +228 -0
- package/docs/FEATURE_2_AUTO_LOGGING_PLAN.md +239 -0
- package/docs/FEATURE_3_CODE_SNIPPET_PLAN.md +249 -0
- package/docs/FEATURE_4_TAG_NORMALIZATION_PLAN.md +211 -0
- package/docs/FEATURE_5_WINDOWS_PATH_HANDLING_PLAN.md +199 -0
- package/docs/FEATURE_6_CONFLICT_DETECTION_PLAN.md +126 -0
- package/docs/FEATURE_IMPLEMENTATION_REPORT.md +203 -0
- package/docs/FINAL_COMPLETE_LAUNCH_DECISION.md +255 -0
- package/docs/FINAL_LAUNCH_DECISION.md +235 -0
- package/docs/FINAL_LAUNCH_DECISION_ALL_AIS.md +226 -0
- package/docs/FINAL_SCENARIO_VERIFICATION.md +363 -0
- package/docs/FIX_100_PERCENT_ANALYSIS.md +133 -0
- package/docs/FRAMEWORK_STRUCTURE.md +94 -0
- package/docs/GEMINI_AI_ANALYSIS.md +156 -0
- package/docs/GEMINI_AI_CLARIFICATION.md +47 -0
- package/docs/GEMINI_AI_STRATEGIC_VALIDATION.md +235 -0
- package/docs/GEMINI_AI_VALIDATION_RESPONSE.md +238 -0
- package/docs/GEMINI_AI_VALIDATION_RESPONSE_v2.md +168 -0
- package/docs/GEMINI_FINAL_VALIDATION.md +204 -0
- package/docs/GEMINI_LAUNCH_VALIDATION.md +30 -0
- package/docs/GEMINI_SCOPE_AND_UNIVERSALITY_DEBATE.md +25 -0
- package/docs/GEMINI_SUPERMEMORY_TREE_SITTER_MANDATE.md +43 -0
- package/docs/GEMINI_VALIDATION_RESULTS.md +183 -0
- package/docs/GROK_AI_ANALYSIS.md +278 -0
- package/docs/GROK_AI_CLARIFICATION.md +52 -0
- package/docs/GROK_AI_STRATEGIC_VALIDATION.md +306 -0
- package/docs/GROK_AI_VALIDATION_RESPONSE.md +252 -0
- package/docs/GROK_AI_VALIDATION_RESPONSE_v2.md +264 -0
- package/docs/GROK_FINAL_VALIDATION.md +251 -0
- package/docs/GROK_LAUNCH_VALIDATION.md +24 -0
- package/docs/GROK_SCOPE_REALITY_CHECK.md +28 -0
- package/docs/GROK_SUPERMEMORY_LAUNCH_ANALYSIS.md +44 -0
- package/docs/GROK_VALIDATION_RESULTS.md +180 -0
- package/docs/IMPLEMENTATION_PLAN_16_CRITICAL_FIXES.md +641 -0
- package/docs/LANGCHAIN_AND_LANGGRAPH_INTEGRATION_PLAN.md +51 -0
- package/docs/LAUNCH_DECISION_FINAL.md +243 -0
- package/docs/MANUS_AI_ANALYSIS.md +171 -0
- package/docs/MANUS_AI_CLARIFICATION.md +43 -0
- package/docs/MANUS_AI_VALIDATION_RESPONSE.md +335 -0
- package/docs/MANUS_AI_VALIDATION_RESPONSE_v2.md +226 -0
- package/docs/MANUS_FINAL_VALIDATION.md +257 -0
- package/docs/MANUS_VALIDATION_RESULTS.md +237 -0
- package/docs/MCP_SERVER_SETUP.md +167 -0
- package/docs/MEMORYLINK_7AI_FINAL_CONFIRMATION.md +210 -0
- package/docs/MEMORYLINK_CURSOR_AI_DEVELOPMENT_GUIDE.md +1092 -0
- package/docs/MEMORYLINK_DEVELOPMENT_PLAN_CURSOR_AI.md +629 -0
- package/docs/MEMORYLINK_FINAL_7AI_CLARIFICATION.md +184 -0
- package/docs/MEMORYLINK_MASTER_DOCUMENT_v4.md +1338 -0
- package/docs/MEMORYLINK_NAMING_ANALYSIS.md +427 -0
- package/docs/MEMORYLINK_REAL_WORLD_SCENARIOS.md +3517 -0
- package/docs/MEMORYLINK_STORAGE_COMPARISON.md +498 -0
- package/docs/MEMORYLINK_V1.0_FINAL_IMPLEMENTATION_PLAN.md +285 -0
- package/docs/MEMORYLINK_VALIDATION_COMPLETE_ANALYSIS.md +207 -0
- package/docs/MEMORYLINK_VS_MEMORY_APPS_ANALYSIS.md +667 -0
- package/docs/MEMORYLINK_v1.0_BUILD_DOCUMENT_FINAL.md +1928 -0
- package/docs/MEMORY_USAGE_FIX_IMPLEMENTATION.md +314 -0
- package/docs/MISTRAL_AI_ANALYSIS.md +189 -0
- package/docs/MISTRAL_AI_CLARIFICATION.md +57 -0
- package/docs/MISTRAL_AI_STRATEGIC_VALIDATION.md +334 -0
- package/docs/MISTRAL_AI_TESTING_REQUEST.md +261 -0
- package/docs/MISTRAL_AI_VALIDATION_RESPONSE.md +446 -0
- package/docs/MISTRAL_AI_VALIDATION_RESPONSE_v2.md +227 -0
- package/docs/MISTRAL_FINAL_VALIDATION.md +398 -0
- package/docs/MISTRAL_LAUNCH_VALIDATION.md +32 -0
- package/docs/MISTRAL_SCOPE_REALITY_CHECK.md +32 -0
- package/docs/MISTRAL_SUPERMEMORY_LAUNCH_ANALYSIS.md +43 -0
- package/docs/MISTRAL_VALIDATION_RESULTS.md +371 -0
- package/docs/NEXT_PLAN.md +300 -0
- package/docs/PERPLEXITY_AI_ANALYSIS.md +285 -0
- package/docs/PERPLEXITY_AI_CLARIFICATION.md +57 -0
- package/docs/PERPLEXITY_AI_STRATEGIC_VALIDATION.md +288 -0
- package/docs/PERPLEXITY_AI_VALIDATION_RESPONSE.md +350 -0
- package/docs/PERPLEXITY_AI_VALIDATION_RESPONSE_v2.md +260 -0
- package/docs/PERPLEXITY_FINAL_VALIDATION.md +320 -0
- package/docs/PERPLEXITY_LAUNCH_VALIDATION.md +42 -0
- package/docs/PERPLEXITY_MEMORY_QUALITY_AND_VSCODE_PLAN.md +56 -0
- package/docs/PERPLEXITY_SCOPE_REALITY_CHECK.md +31 -0
- package/docs/PERPLEXITY_VALIDATION_RESULTS.md +154 -0
- package/docs/PRE_LAUNCH_GAP_ANALYSIS.md +663 -0
- package/docs/PROJECT_STRUCTURE_PLAN.md +104 -0
- package/docs/QWEN_AI_ANALYSIS.md +176 -0
- package/docs/QWEN_AI_CLARIFICATION.md +60 -0
- package/docs/QWEN_AI_STRATEGIC_VALIDATION.md +241 -0
- package/docs/QWEN_AI_VALIDATION_RESPONSE.md +197 -0
- package/docs/QWEN_AI_VALIDATION_RESPONSE_v2.md +186 -0
- package/docs/QWEN_FINAL_VALIDATION.md +284 -0
- package/docs/QWEN_LAUNCH_VALIDATION.md +26 -0
- package/docs/QWEN_SCENARIOS_TEST_RESULTS.md +244 -0
- package/docs/QWEN_SCOPE_REALITY_CHECK.md +26 -0
- package/docs/QWEN_SUPERMEMORY_LAUNCH_AND_ENFORCEMENT_PLAN.md +56 -0
- package/docs/QWEN_VALIDATION_RESULTS.md +185 -0
- package/docs/README.md +479 -0
- package/docs/REAL_PRODUCT_LAUNCH_DECISION.md +185 -0
- package/docs/RECIPES.md +424 -0
- package/docs/RELEASE_NOTES_v1.0.0.md +193 -0
- package/docs/SCENARIO_INVENTORY_AND_VERIFICATION.md +284 -0
- package/docs/SINGLE_RUN_1018_SCENARIOS_RESULTS.md +142 -0
- package/docs/TESTING.md +256 -0
- package/docs/TESTING_STRATEGY.md +194 -0
- package/docs/TROUBLESHOOTING.md +188 -0
- package/docs/ULTIMATE_LAUNCH_DECISION.md +246 -0
- package/docs/WHAT_WE_BUILT.md +504 -0
- package/docs/v1.0_LAUNCH_CHECKLIST.md +104 -0
- package/examples/README.md +199 -0
- package/examples/chatgpt-context.js +161 -0
- package/examples/ci-integration.js +288 -0
- package/examples/sync-from-cursor.js +196 -0
- package/extensions/vscode/README.md +25 -0
- package/extensions/vscode/out/buddy-check.js +208 -0
- package/extensions/vscode/out/buddy-check.js.map +1 -0
- package/extensions/vscode/out/extension.js +413 -0
- package/extensions/vscode/out/extension.js.map +1 -0
- package/extensions/vscode/out/sidebar.js +409 -0
- package/extensions/vscode/out/sidebar.js.map +1 -0
- package/extensions/vscode/package.json +92 -0
- package/extensions/vscode/src/buddy-check.ts +220 -0
- package/extensions/vscode/src/extension.ts +425 -0
- package/extensions/vscode/src/shims-vscode.d.ts +2 -0
- package/extensions/vscode/src/sidebar.ts +431 -0
- package/extensions/vscode/tsconfig.json +14 -0
- package/k6-load-test.js +86 -0
- package/package.json +68 -0
- package/run-professional-tests.sh +72 -0
- package/scripts/monitor-continuous-test.sh +17 -0
- package/scripts/reorganize-project.sh +164 -0
- package/scripts/run-tests-parallel.sh +111 -0
- package/scripts/run-tests.sh +30 -0
- package/scripts/setup-framework.sh +139 -0
- package/scripts/setup-testing.sh +96 -0
- package/scripts/stress-test/README.md +86 -0
- package/scripts/stress-test/create-all-scenarios.sh +17 -0
- package/scripts/stress-test/create-remaining-scenarios.sh +3 -0
- package/scripts/stress-test/dev-test.sh +21 -0
- package/scripts/stress-test/monitor-continuous.sh +149 -0
- package/scripts/stress-test/overnight-test.sh +30 -0
- package/scripts/stress-test/quick-test.sh +21 -0
- package/scripts/stress-test/run-all-tests.sh +157 -0
- package/scripts/stress-test/run-continuous.sh +300 -0
- package/scripts/stress-test/run-stress-test.sh +153 -0
- package/scripts/stress-test/set1/1_1_mass_refactoring.sh +117 -0
- package/scripts/stress-test/set1/1_1_mass_refactoring_simple.sh +117 -0
- package/scripts/stress-test/set1/1_2_function_rename.sh +95 -0
- package/scripts/stress-test/set1/1_3_feature_flags.sh +93 -0
- package/scripts/stress-test/set1/1_4_feature_removal.sh +57 -0
- package/scripts/stress-test/set1/1_5_schema_changes.sh +42 -0
- package/scripts/stress-test/set1/1_6_dependency_update.sh +47 -0
- package/scripts/stress-test/set1/1_7_config_modification.sh +53 -0
- package/scripts/stress-test/set2/2_1_payment_logging.sh +49 -0
- package/scripts/stress-test/set2/2_2_test_data_generation.sh +43 -0
- package/scripts/stress-test/set2/2_3_documentation_leak.sh +45 -0
- package/scripts/stress-test/set2/2_4_api_key_rotation.sh +45 -0
- package/scripts/stress-test/set2/2_5_hardcoded_secrets.sh +45 -0
- package/scripts/stress-test/set2/2_6_debug_output.sh +49 -0
- package/scripts/stress-test/set3/3_1_billing_modification.sh +47 -0
- package/scripts/stress-test/set3/3_2_migration_deletion.sh +43 -0
- package/scripts/stress-test/set3/3_3_auth_middleware.sh +52 -0
- package/scripts/stress-test/set3/3_4_permission_bypass.sh +48 -0
- package/scripts/stress-test/set3/3_5_config_modification.sh +43 -0
- package/scripts/stress-test/set3/3_6_core_library.sh +51 -0
- package/scripts/stress-test/set3/3_7_test_infrastructure.sh +49 -0
- package/scripts/stress-test/set4/4_1_concurrent_features.sh +49 -0
- package/scripts/stress-test/set4/4_2_lock_acquisition.sh +32 -0
- package/scripts/stress-test/set4/4_3_migration_hotfix.sh +43 -0
- package/scripts/stress-test/set4/4_4_overlapping_scopes.sh +50 -0
- package/scripts/stress-test/set4/4_5_lock_timeout.sh +34 -0
- package/scripts/stress-test/set4/4_6_concurrent_stats.sh +33 -0
- package/scripts/stress-test/set5/5_1_wrong_decision.sh +41 -0
- package/scripts/stress-test/set5/5_2_outdated_docs.sh +40 -0
- package/scripts/stress-test/set5/5_3_conflicting_memories.sh +34 -0
- package/scripts/stress-test/set5/5_4_deleted_file_references.sh +38 -0
- package/scripts/stress-test/set5/5_5_old_pattern.sh +41 -0
- package/scripts/stress-test/set5/5_6_wrong_architecture.sh +42 -0
- package/scripts/stress-test/set5/5_7_high_trust_stale.sh +46 -0
- package/scripts/stress-test/set5/5_8_observability_stale.sh +36 -0
- package/scripts/stress-test/setup-test-repo-simple.sh +144 -0
- package/scripts/stress-test/setup-test-repo.sh +154 -0
- package/scripts/stress-test/start-continuous.sh +48 -0
- package/scripts/stress-test/stop-continuous.sh +42 -0
- package/scripts/stress-test/template-scenario.sh +115 -0
- package/scripts/test-advanced-scenarios.sh +411 -0
- package/scripts/test-continuous-30min.sh +307 -0
- package/scripts/test-continuous-enhanced.sh +250 -0
- package/scripts/test-e2e-comprehensive.sh +114 -0
- package/scripts/test-e2e-random.sh +359 -0
- package/scripts/test-fresh-scenarios.sh +412 -0
- package/scripts/test-new-scenarios.sh +374 -0
- package/scripts/test-quick-random.sh +97 -0
- package/scripts/test-runtime.sh +129 -0
- package/scripts/test-telemetry-local.sh +193 -0
- package/scripts/test-ultimate-scenarios.sh +428 -0
- package/scripts/test-v1.5-complete.sh +225 -0
- package/scripts/test-v1.5-phase1.sh +222 -0
- package/src/cli.ts +1259 -0
- package/src/commands/archive.ts +252 -0
- package/src/commands/auto-context.ts +159 -0
- package/src/commands/auto-log.ts +531 -0
- package/src/commands/change.ts +298 -0
- package/src/commands/checkpoint.ts +390 -0
- package/src/commands/configure.ts +297 -0
- package/src/commands/consolidate.ts +263 -0
- package/src/commands/context.ts +618 -0
- package/src/commands/detect.ts +181 -0
- package/src/commands/doctor.ts +1468 -0
- package/src/commands/export.ts +77 -0
- package/src/commands/graph.ts +214 -0
- package/src/commands/hooks.ts +245 -0
- package/src/commands/impact.ts +163 -0
- package/src/commands/index-vector.ts +126 -0
- package/src/commands/index.ts +57 -0
- package/src/commands/init.ts +194 -0
- package/src/commands/inject.ts +440 -0
- package/src/commands/learn.ts +328 -0
- package/src/commands/lock.ts +345 -0
- package/src/commands/memory.ts +415 -0
- package/src/commands/migrate.ts +540 -0
- package/src/commands/patterns.ts +158 -0
- package/src/commands/protect.ts +199 -0
- package/src/commands/quickstart.ts +259 -0
- package/src/commands/resolve.ts +373 -0
- package/src/commands/roadmap.ts +25 -0
- package/src/commands/scopes.ts +113 -0
- package/src/commands/search.ts +365 -0
- package/src/commands/setup.ts +430 -0
- package/src/commands/snippet.ts +271 -0
- package/src/commands/stats.ts +591 -0
- package/src/commands/status.ts +127 -0
- package/src/commands/suggest-tags.ts +122 -0
- package/src/commands/sync-rules.ts +218 -0
- package/src/commands/sync.ts +363 -0
- package/src/commands/telemetry-test.ts +97 -0
- package/src/commands/template.ts +166 -0
- package/src/commands/validate.ts +191 -0
- package/src/commands/watch-preferences.ts +162 -0
- package/src/commands/watch.ts +239 -0
- package/src/config/thresholds.ts +14 -0
- package/src/index.ts +12 -0
- package/src/memorylink.ts +308 -0
- package/src/search/local-embeddings.ts +94 -0
- package/src/search/vector-search.ts +608 -0
- package/src/server/mcp-server.ts +355 -0
- package/src/telemetry.ts +391 -0
- package/src/test-runner/TestRunner.ts +421 -0
- package/src/test-runner/performance-test.ts +161 -0
- package/src/test-runner/run-tests.ts +152 -0
- package/src/types.ts +533 -0
- package/src/utils/batch-commits.ts +162 -0
- package/src/utils/code-structure.ts +686 -0
- package/src/utils/commit-patterns.ts +87 -0
- package/src/utils/observability.ts +149 -0
- package/src/utils/quality.ts +230 -0
- package/src/utils/semantic-search.ts +222 -0
- package/src/utils/streaming.ts +109 -0
- package/src/utils/tag-suggestions.ts +117 -0
- package/src/utils/team-patterns.ts +499 -0
- package/src/utils/templates.ts +181 -0
- package/src/utils/tree-sitter-parser.ts +246 -0
- package/src/utils/v1.6-patterns.ts +227 -0
- package/src/utils.ts +885 -0
- package/test-all-features.sh +102 -0
- package/test-all-implemented-features.sh +209 -0
- package/test-all-new-features.sh +171 -0
- package/test-auto-log.txt +1 -0
- package/test-batch-commits.sh +47 -0
- package/test-conflict-resolution.sh +47 -0
- package/test-e2e.sh +22 -0
- package/test-end-to-end.sh +151 -0
- package/test-enhanced-autocapture.sh +164 -0
- package/test-inject.sh +44 -0
- package/test-mcp-server.sh +67 -0
- package/test-pagination.sh +37 -0
- package/test-python-go-structure.sh +164 -0
- package/test-quality-validation.sh +167 -0
- package/test-results-quick-smoke.json +13 -0
- package/test-results-targeted-perf.json +23 -0
- package/test-results.json +2272 -0
- package/test-scenarios/payment-logging.ts +17 -0
- package/test-scenarios/test-config.ts +13 -0
- package/test-semantic-search.sh +161 -0
- package/test-tag-intelligence.sh +49 -0
- package/test-vector-search.sh +64 -0
- package/test-vscode-extension.sh +144 -0
- package/test-watcher-file.txt +2 -0
- package/test-watcher-file2.txt +1 -0
- package/test-watcher.sh +103 -0
- package/test_qwen_scenarios.sh +285 -0
- package/tests/scenarios/4000_HARD_SCENARIOS.sh +4137 -0
- package/tests/scenarios/ADD_V1.1_SCENARIOS.sh +93 -0
- package/tests/scenarios/AGGRESSIVE_RANDOM_E2E_TEST.sh +474 -0
- package/tests/scenarios/COMPLETE_PRODUCT_VALIDATION.sh +227 -0
- package/tests/scenarios/COMPREHENSIVE_E2E_TEST.sh +426 -0
- package/tests/scenarios/CONTINUOUS_RANDOM_STRESS_TEST.sh +240 -0
- package/tests/scenarios/EXECUTE_10000_SCENARIOS.sh +61 -0
- package/tests/scenarios/EXECUTE_1000_UNIQUE_SCENARIOS.sh +190 -0
- package/tests/scenarios/EXECUTE_5000_SCENARIOS_SPLIT.sh +192 -0
- package/tests/scenarios/EXECUTE_5000_TOTAL_SCENARIOS.sh +162 -0
- package/tests/scenarios/EXECUTE_5040_SCENARIOS_WITH_V1.1.sh +251 -0
- package/tests/scenarios/EXECUTE_8_BATCHES_500.sh +51 -0
- package/tests/scenarios/EXECUTE_QUICK_SMOKE.sh +9 -0
- package/tests/scenarios/EXECUTE_SINGLE_BATCH.sh +117 -0
- package/tests/scenarios/EXECUTE_TARGETED_PERF.sh +19 -0
- package/tests/scenarios/GENERATE_1000_SCENARIOS.sh +235 -0
- package/tests/scenarios/GENERATE_4000_HARD_SCENARIOS.sh +266 -0
- package/tests/scenarios/GENERATE_4000_HARD_SCENARIOS_FIXED.sh +267 -0
- package/tests/scenarios/GENERATE_4000_HARD_SCENARIOS_FIXED_V2.sh +267 -0
- package/tests/scenarios/NEW_RANDOM_E2E_TEST.sh +422 -0
- package/tests/scenarios/QUICK_SMOKE_200.sh +38 -0
- package/tests/scenarios/QUICK_SMOKE_MINI.sh +3 -0
- package/tests/scenarios/RANDOM_REAL_WORLD_SCENARIOS.sh +372 -0
- package/tests/scenarios/ROUND3_RANDOM_E2E_TEST.sh +446 -0
- package/tests/scenarios/RUN_AGGRESSIVE_AND_SUMMARY.sh +51 -0
- package/tests/scenarios/RUN_ALL_1018_SCENARIOS.sh +161 -0
- package/tests/scenarios/TARGETED_PERF.sh +75 -0
- package/tests/scenarios/V1.1_FEATURES_SCENARIOS.sh +145 -0
- package/tests/unit/utils.test.ts +52 -0
- package/tests/v1.1-features-scenarios.sh +276 -0
- package/tsconfig.json +21 -0
- package/v1.6_FEATURE_REQUESTS.md +79 -0
package/src/utils.ts
ADDED
|
@@ -0,0 +1,885 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MemoryLink - Utility Functions
|
|
3
|
+
*
|
|
4
|
+
* v1.0 UPDATE: Added JSONL utilities, file locking, secret detection,
|
|
5
|
+
* and duration parsing for robust, concurrent-safe operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
11
|
+
import lockfile from 'proper-lockfile';
|
|
12
|
+
import {
|
|
13
|
+
MEMORYLINK_DIR,
|
|
14
|
+
FILES,
|
|
15
|
+
DEFAULT_IGNORE_PATTERNS,
|
|
16
|
+
SECRET_PATTERNS,
|
|
17
|
+
DURATION_MS,
|
|
18
|
+
type DurationUnit,
|
|
19
|
+
type BaseEntry,
|
|
20
|
+
type MemoryEntry,
|
|
21
|
+
type LearningEntry,
|
|
22
|
+
type ChangeEntry,
|
|
23
|
+
type MemoryStatus,
|
|
24
|
+
type Sensitivity,
|
|
25
|
+
type TrustLevel,
|
|
26
|
+
type SourceType,
|
|
27
|
+
type Provenance,
|
|
28
|
+
JSONL_SCHEMA_VERSION,
|
|
29
|
+
} from './types.js';
|
|
30
|
+
import type { MemoryLinkConfig } from './types.js';
|
|
31
|
+
|
|
32
|
+
// ANSI color codes (for environments where chalk might not work)
|
|
33
|
+
export const colors = {
|
|
34
|
+
reset: '\x1b[0m',
|
|
35
|
+
bold: '\x1b[1m',
|
|
36
|
+
red: '\x1b[31m',
|
|
37
|
+
green: '\x1b[32m',
|
|
38
|
+
yellow: '\x1b[33m',
|
|
39
|
+
blue: '\x1b[34m',
|
|
40
|
+
magenta: '\x1b[35m',
|
|
41
|
+
cyan: '\x1b[36m',
|
|
42
|
+
gray: '\x1b[90m',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export function colorize(text: string, color: keyof typeof colors): string {
|
|
46
|
+
return `${colors[color]}${text}${colors.reset}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Find the root directory containing .memorylink
|
|
50
|
+
export function findRoot(startDir: string = process.cwd()): string | null {
|
|
51
|
+
let currentDir = startDir;
|
|
52
|
+
|
|
53
|
+
while (currentDir !== path.parse(currentDir).root) {
|
|
54
|
+
if (fs.existsSync(path.join(currentDir, MEMORYLINK_DIR))) {
|
|
55
|
+
return currentDir;
|
|
56
|
+
}
|
|
57
|
+
currentDir = path.dirname(currentDir);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Get the .memorylink directory path
|
|
64
|
+
export function getMemoryLinkDir(root?: string): string {
|
|
65
|
+
const rootDir = root || findRoot() || process.cwd();
|
|
66
|
+
return path.join(rootDir, MEMORYLINK_DIR);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Get a specific file path
|
|
70
|
+
export function getFilePath(file: keyof typeof FILES, root?: string): string {
|
|
71
|
+
return path.join(getMemoryLinkDir(root), FILES[file]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Normalize path to use forward slashes (Git-compatible)
|
|
76
|
+
* Windows backslashes are converted to forward slashes
|
|
77
|
+
* This ensures paths are consistent across platforms for storage
|
|
78
|
+
*/
|
|
79
|
+
export function normalizePath(filePath: string): string {
|
|
80
|
+
return filePath.replace(/\\/g, '/');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Normalize path for storage (always forward slashes, relative to root)
|
|
85
|
+
* For file operations, use platform-specific paths
|
|
86
|
+
* For storage in JSONL, use normalized forward-slash paths
|
|
87
|
+
*/
|
|
88
|
+
export function normalizePathForStorage(filePath: string, root: string): string {
|
|
89
|
+
// Normalize to forward slashes
|
|
90
|
+
let normalized = normalizePath(filePath);
|
|
91
|
+
|
|
92
|
+
// If absolute path, make relative to root
|
|
93
|
+
if (path.isAbsolute(normalized)) {
|
|
94
|
+
normalized = path.relative(root, normalized);
|
|
95
|
+
// Normalize again after making relative
|
|
96
|
+
normalized = normalizePath(normalized);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Remove leading ./ if present
|
|
100
|
+
normalized = normalized.replace(/^\.\//, '');
|
|
101
|
+
|
|
102
|
+
return normalized;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Convert normalized path to platform-specific path for file operations
|
|
107
|
+
*/
|
|
108
|
+
export function denormalizePath(normalizedPath: string, root: string): string {
|
|
109
|
+
const fullPath = path.isAbsolute(normalizedPath)
|
|
110
|
+
? normalizedPath
|
|
111
|
+
: path.join(root, normalizedPath);
|
|
112
|
+
return path.normalize(fullPath);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Check if MemoryLink is initialized
|
|
116
|
+
export function isInitialized(root?: string): boolean {
|
|
117
|
+
const dir = getMemoryLinkDir(root);
|
|
118
|
+
return fs.existsSync(dir) && fs.existsSync(path.join(dir, FILES.CONFIG));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Get current timestamp in ISO format
|
|
122
|
+
export function getTimestamp(): string {
|
|
123
|
+
return new Date().toISOString();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Validate project scope name (v1.5 Phase 2)
|
|
128
|
+
* Rules: max 50 chars, alphanumeric, dash, underscore
|
|
129
|
+
*/
|
|
130
|
+
export function validateScope(scope: string): { valid: boolean; error?: string } {
|
|
131
|
+
if (!scope || scope.trim().length === 0) {
|
|
132
|
+
return { valid: false, error: 'Scope cannot be empty' };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (scope.length > 50) {
|
|
136
|
+
return { valid: false, error: 'Scope must be 50 characters or less' };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Allow: alphanumeric, dash, underscore, forward slash (for hierarchical)
|
|
140
|
+
const validPattern = /^[a-zA-Z0-9_/-]+$/;
|
|
141
|
+
if (!validPattern.test(scope)) {
|
|
142
|
+
return { valid: false, error: 'Scope can only contain letters, numbers, dashes, underscores, and slashes' };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { valid: true };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Format timestamp for display
|
|
149
|
+
export function formatTimestamp(iso: string): string {
|
|
150
|
+
const date = new Date(iso);
|
|
151
|
+
return date.toLocaleString();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Read a file safely
|
|
155
|
+
export function readFileSafe(filePath: string): string {
|
|
156
|
+
try {
|
|
157
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
158
|
+
} catch {
|
|
159
|
+
return '';
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Append to a file
|
|
164
|
+
export function appendToFile(filePath: string, content: string): void {
|
|
165
|
+
fs.appendFileSync(filePath, content + '\n');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Read lines from a file (non-empty)
|
|
169
|
+
export function readLines(filePath: string): string[] {
|
|
170
|
+
const content = readFileSafe(filePath);
|
|
171
|
+
return content.split('\n').filter(line => line.trim() !== '');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Count lines in a file
|
|
175
|
+
export function countLines(filePath: string): number {
|
|
176
|
+
return readLines(filePath).length;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Read the config file
|
|
180
|
+
export function readConfig(root?: string): MemoryLinkConfig | null {
|
|
181
|
+
const configPath = getFilePath('CONFIG', root);
|
|
182
|
+
try {
|
|
183
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
184
|
+
return JSON.parse(content);
|
|
185
|
+
} catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Write the config file
|
|
191
|
+
export function writeConfig(config: MemoryLinkConfig, root?: string): void {
|
|
192
|
+
const configPath = getFilePath('CONFIG', root);
|
|
193
|
+
writeFileAtomic(configPath, JSON.stringify(config, null, 2));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Read ignore patterns
|
|
197
|
+
export function readIgnorePatterns(root?: string): string[] {
|
|
198
|
+
const ignorePath = path.join(root || findRoot() || process.cwd(), FILES.IGNORE);
|
|
199
|
+
if (fs.existsSync(ignorePath)) {
|
|
200
|
+
const content = fs.readFileSync(ignorePath, 'utf-8');
|
|
201
|
+
const patterns = content.split('\n')
|
|
202
|
+
.map(line => line.trim())
|
|
203
|
+
.filter(line => line && !line.startsWith('#'));
|
|
204
|
+
return [...DEFAULT_IGNORE_PATTERNS, ...patterns];
|
|
205
|
+
}
|
|
206
|
+
return DEFAULT_IGNORE_PATTERNS;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Log with optional verbose mode
|
|
210
|
+
export function log(message: string, verbose: boolean = false): void {
|
|
211
|
+
if (verbose) {
|
|
212
|
+
console.log(colorize(`[DEBUG] ${getTimestamp()}`, 'gray'), message);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Print success message
|
|
217
|
+
export function success(message: string): void {
|
|
218
|
+
console.log(colorize('✓', 'green'), message);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Print error message
|
|
222
|
+
export function error(message: string): void {
|
|
223
|
+
console.error(colorize('✗', 'red'), message);
|
|
224
|
+
// Reference troubleshooting guide for common errors
|
|
225
|
+
if (message.includes('not initialized') ||
|
|
226
|
+
message.includes('Failed to read') ||
|
|
227
|
+
message.includes('locked') ||
|
|
228
|
+
message.includes('parse error')) {
|
|
229
|
+
console.error(colorize('💡', 'cyan'), 'Run `memorylink doctor` for diagnosis, or see TROUBLESHOOTING.md');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Print warning message
|
|
234
|
+
export function warn(message: string): void {
|
|
235
|
+
console.log(colorize('⚠', 'yellow'), message);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Safe console.log that handles EPIPE errors gracefully
|
|
240
|
+
* Used when output might be piped to /dev/null or closed streams
|
|
241
|
+
*/
|
|
242
|
+
export function safeLog(...args: any[]): void {
|
|
243
|
+
try {
|
|
244
|
+
console.log(...args);
|
|
245
|
+
} catch (err: any) {
|
|
246
|
+
// Ignore EPIPE errors (broken pipe) - happens when stdout is closed
|
|
247
|
+
if (err.code !== 'EPIPE' && err.errno !== -32) {
|
|
248
|
+
// Re-throw if it's not an EPIPE error
|
|
249
|
+
throw err;
|
|
250
|
+
}
|
|
251
|
+
// Silently ignore EPIPE - this is expected when output is suppressed
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Safe console.error that handles EPIPE errors gracefully
|
|
257
|
+
*/
|
|
258
|
+
export function safeError(...args: any[]): void {
|
|
259
|
+
try {
|
|
260
|
+
console.error(...args);
|
|
261
|
+
} catch (err: any) {
|
|
262
|
+
// Ignore EPIPE errors (broken pipe)
|
|
263
|
+
if (err.code !== 'EPIPE' && err.errno !== -32) {
|
|
264
|
+
throw err;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Check if stdout is writable before writing
|
|
271
|
+
* Returns true if safe to write, false otherwise
|
|
272
|
+
*/
|
|
273
|
+
export function isStdoutWritable(): boolean {
|
|
274
|
+
try {
|
|
275
|
+
return process.stdout.writable && !process.stdout.destroyed;
|
|
276
|
+
} catch {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Print info message
|
|
282
|
+
export function info(message: string): void {
|
|
283
|
+
console.log(colorize('ℹ', 'blue'), message);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Normalize a single tag (lowercase, hyphenate spaces)
|
|
288
|
+
* Examples: "TypeScript" → "typescript", "Type Script" → "type-script"
|
|
289
|
+
*/
|
|
290
|
+
export function normalizeTag(tag: string): string {
|
|
291
|
+
return tag
|
|
292
|
+
.toLowerCase() // "TypeScript" → "typescript"
|
|
293
|
+
.trim() // Remove whitespace
|
|
294
|
+
.replace(/\s+/g, '-') // "Type Script" → "type-script"
|
|
295
|
+
.replace(/[^a-z0-9-]/g, '') // Remove special chars (keep alphanumeric and hyphens)
|
|
296
|
+
.replace(/-+/g, '-') // Multiple hyphens → single hyphen
|
|
297
|
+
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Parse and normalize tags from comma-separated string
|
|
302
|
+
* Tags are automatically normalized (lowercase, hyphenated)
|
|
303
|
+
*/
|
|
304
|
+
export function parseTags(tagString?: string): string[] {
|
|
305
|
+
if (!tagString) return [];
|
|
306
|
+
return tagString
|
|
307
|
+
.split(',')
|
|
308
|
+
.map(t => normalizeTag(t))
|
|
309
|
+
.filter(t => t.length > 0); // Filter out empty tags after normalization
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Format tags for storage
|
|
313
|
+
export function formatTags(tags: string[]): string {
|
|
314
|
+
return tags.length > 0 ? ` [${tags.join(', ')}]` : '';
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Ensure directory exists
|
|
318
|
+
export function ensureDir(dirPath: string): void {
|
|
319
|
+
if (!fs.existsSync(dirPath)) {
|
|
320
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Atomic write helper (write temp then rename)
|
|
325
|
+
export function writeFileAtomic(filePath: string, content: string): void {
|
|
326
|
+
const dir = path.dirname(filePath);
|
|
327
|
+
ensureDir(dir);
|
|
328
|
+
const tempPath = path.join(dir, `.tmp-${path.basename(filePath)}-${Date.now()}`);
|
|
329
|
+
fs.writeFileSync(tempPath, content);
|
|
330
|
+
fs.renameSync(tempPath, filePath);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Relative path from root
|
|
334
|
+
export function relativePath(fullPath: string, root?: string): string {
|
|
335
|
+
const rootDir = root || findRoot() || process.cwd();
|
|
336
|
+
return path.relative(rootDir, fullPath);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// ============================================
|
|
340
|
+
// UUID GENERATION
|
|
341
|
+
// ============================================
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Generate a unique ID for log entries
|
|
345
|
+
*/
|
|
346
|
+
export function generateId(): string {
|
|
347
|
+
return uuidv4();
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Generate a short ID prefix for display (first 8 chars)
|
|
352
|
+
*/
|
|
353
|
+
export function shortId(id: string): string {
|
|
354
|
+
return id.substring(0, 8);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// ============================================
|
|
358
|
+
// FILE LOCKING (Concurrent Write Protection)
|
|
359
|
+
// ============================================
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Append a JSONL entry to a log file with file locking
|
|
363
|
+
* Prevents concurrent write corruption
|
|
364
|
+
*/
|
|
365
|
+
export async function appendJsonlEntry<T extends BaseEntry>(
|
|
366
|
+
filePath: string,
|
|
367
|
+
entry: T
|
|
368
|
+
): Promise<void> {
|
|
369
|
+
// Ensure file exists
|
|
370
|
+
if (!fs.existsSync(filePath)) {
|
|
371
|
+
fs.writeFileSync(filePath, '');
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Acquire lock with retries
|
|
375
|
+
let release: (() => Promise<void>) | null = null;
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
release = await lockfile.lock(filePath, {
|
|
379
|
+
retries: {
|
|
380
|
+
retries: 5,
|
|
381
|
+
minTimeout: 100,
|
|
382
|
+
maxTimeout: 1000,
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Append JSONL entry
|
|
387
|
+
const line = JSON.stringify(entry) + '\n';
|
|
388
|
+
// Guard against oversized entries
|
|
389
|
+
if (line.length > 10000) {
|
|
390
|
+
throw new Error('Entry too large to store. Please shorten the message.');
|
|
391
|
+
}
|
|
392
|
+
fs.appendFileSync(filePath, line);
|
|
393
|
+
} finally {
|
|
394
|
+
// Release lock
|
|
395
|
+
if (release) {
|
|
396
|
+
await release();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Normalize v1.3 MemoryEntry to v1.4 format with defaults
|
|
403
|
+
* Maintains backward compatibility while adding v1.4 fields
|
|
404
|
+
*/
|
|
405
|
+
function normalizeMemoryEntryToV14(entry: MemoryEntry, root: string): MemoryEntry {
|
|
406
|
+
// If already v1.4, return as-is
|
|
407
|
+
if (entry.schemaVersion === '1.4.0') {
|
|
408
|
+
return entry;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Determine source type from agent field
|
|
412
|
+
const sourceType: SourceType =
|
|
413
|
+
entry.agent === 'user' || !entry.agent || entry.agent === 'migrated'
|
|
414
|
+
? 'human'
|
|
415
|
+
: ['cursor', 'claude', 'chatgpt', 'copilot', 'windsurf'].includes(entry.agent.toLowerCase())
|
|
416
|
+
? 'agent'
|
|
417
|
+
: 'code';
|
|
418
|
+
|
|
419
|
+
// Determine memory status: VERIFIED for human, DRAFT for agent
|
|
420
|
+
const memoryStatus: MemoryStatus = sourceType === 'human' ? 'VERIFIED' : 'DRAFT';
|
|
421
|
+
|
|
422
|
+
// Build provenance from existing fields
|
|
423
|
+
const provenance: Provenance = {
|
|
424
|
+
createdAt: entry.ts,
|
|
425
|
+
createdBy: entry.agent || 'unknown',
|
|
426
|
+
tool: entry.agent || undefined,
|
|
427
|
+
kind: sourceType === 'human' ? 'user' : 'app',
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
// Get project path (relative to root)
|
|
431
|
+
const projectPath = root || process.cwd();
|
|
432
|
+
|
|
433
|
+
// Add v1.4 fields with defaults
|
|
434
|
+
return {
|
|
435
|
+
...entry,
|
|
436
|
+
schemaVersion: '1.4.0',
|
|
437
|
+
recordVersion: 1,
|
|
438
|
+
projectPath,
|
|
439
|
+
sensitivity: 'internal' as Sensitivity,
|
|
440
|
+
trustLevel: 'medium' as TrustLevel,
|
|
441
|
+
memoryStatus,
|
|
442
|
+
sourceType,
|
|
443
|
+
provenance,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Detect schema version from an entry
|
|
449
|
+
*/
|
|
450
|
+
function detectSchemaVersion(entry: any): string {
|
|
451
|
+
if (entry.schemaVersion) {
|
|
452
|
+
return entry.schemaVersion;
|
|
453
|
+
}
|
|
454
|
+
// v1.3 and earlier don't have schemaVersion
|
|
455
|
+
return '1.3.0';
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Read all JSONL entries from a log file
|
|
460
|
+
* v1.4: Automatically normalizes v1.3 entries to v1.4 format
|
|
461
|
+
*/
|
|
462
|
+
export function readJsonlEntries<T>(filePath: string): T[] {
|
|
463
|
+
if (!fs.existsSync(filePath)) {
|
|
464
|
+
return [];
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
468
|
+
const lines = content.split('\n').filter(line => line.trim() !== '');
|
|
469
|
+
const entries: T[] = [];
|
|
470
|
+
const root = findRoot() || process.cwd();
|
|
471
|
+
|
|
472
|
+
for (let i = 0; i < lines.length; i++) {
|
|
473
|
+
const line = lines[i].trim();
|
|
474
|
+
|
|
475
|
+
// Skip comments (legacy format)
|
|
476
|
+
if (line.startsWith('#')) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
try {
|
|
481
|
+
const entry = JSON.parse(line) as T;
|
|
482
|
+
|
|
483
|
+
// Normalize MemoryEntry from v1.3 to v1.4 if needed
|
|
484
|
+
if (filePath.includes('memory.log') && typeof entry === 'object' && entry !== null && 'type' in entry && 'details' in entry) {
|
|
485
|
+
const memEntry = entry as unknown as MemoryEntry;
|
|
486
|
+
const schemaVersion = detectSchemaVersion(memEntry);
|
|
487
|
+
|
|
488
|
+
if (schemaVersion < '1.4.0') {
|
|
489
|
+
const normalized = normalizeMemoryEntryToV14(memEntry, root);
|
|
490
|
+
entries.push(normalized as T);
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
entries.push(entry);
|
|
496
|
+
} catch (err) {
|
|
497
|
+
// Skip invalid JSON lines (might be legacy format)
|
|
498
|
+
warn(`Line ${i + 1}: Invalid JSON, skipping`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return entries;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Read JSONL entries with streaming (memory-efficient for large files)
|
|
507
|
+
* Use this for files with 10K+ entries
|
|
508
|
+
*/
|
|
509
|
+
export async function readJsonlEntriesStreaming<T>(
|
|
510
|
+
filePath: string,
|
|
511
|
+
options: {
|
|
512
|
+
page?: number;
|
|
513
|
+
perPage?: number;
|
|
514
|
+
filter?: (entry: T) => boolean;
|
|
515
|
+
} = {}
|
|
516
|
+
): Promise<T[]> {
|
|
517
|
+
const { streamJsonlEntries } = await import('./utils/streaming.js');
|
|
518
|
+
const entries: T[] = [];
|
|
519
|
+
|
|
520
|
+
for await (const entry of streamJsonlEntries<T>(filePath, options)) {
|
|
521
|
+
entries.push(entry);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return entries;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Check if a log file is in JSONL format
|
|
529
|
+
*/
|
|
530
|
+
export function isJsonlFormat(filePath: string): boolean {
|
|
531
|
+
if (!fs.existsSync(filePath)) {
|
|
532
|
+
return true; // New files will be JSONL
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
536
|
+
const lines = content.split('\n').filter(line => line.trim() !== '' && !line.startsWith('#'));
|
|
537
|
+
|
|
538
|
+
if (lines.length === 0) {
|
|
539
|
+
return true; // Empty file
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Check first non-comment line
|
|
543
|
+
const firstLine = lines[0].trim();
|
|
544
|
+
return firstLine.startsWith('{');
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// ============================================
|
|
548
|
+
// SECRET DETECTION
|
|
549
|
+
// ============================================
|
|
550
|
+
|
|
551
|
+
export interface SecretDetectionResult {
|
|
552
|
+
detected: boolean;
|
|
553
|
+
patterns: string[];
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Check content for potential secrets
|
|
558
|
+
*/
|
|
559
|
+
export function detectSecrets(content: string): SecretDetectionResult {
|
|
560
|
+
const detectedPatterns: string[] = [];
|
|
561
|
+
|
|
562
|
+
for (const secretPattern of SECRET_PATTERNS) {
|
|
563
|
+
if (secretPattern.pattern.test(content)) {
|
|
564
|
+
detectedPatterns.push(secretPattern.name);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return {
|
|
569
|
+
detected: detectedPatterns.length > 0,
|
|
570
|
+
patterns: detectedPatterns,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Check for prompt injection patterns (system prompts, instruction overrides)
|
|
576
|
+
*/
|
|
577
|
+
function detectPromptInjection(content: string): boolean {
|
|
578
|
+
const promptInjectionPatterns = [
|
|
579
|
+
/ignore\s+(previous|all|above)\s+(instructions|rules|context)/i,
|
|
580
|
+
/forget\s+(everything|all|previous)/i,
|
|
581
|
+
/you\s+are\s+now\s+(a|an)\s+/i,
|
|
582
|
+
/system\s*:\s*(you|ignore|forget)/i,
|
|
583
|
+
/\[SYSTEM\]|\[INST\]|\[PROMPT\]/i,
|
|
584
|
+
/override\s+(previous|all|system)\s+(instructions|rules)/i,
|
|
585
|
+
/new\s+(instructions|rules|system)\s*:/i,
|
|
586
|
+
/disregard\s+(previous|all|above)/i,
|
|
587
|
+
];
|
|
588
|
+
|
|
589
|
+
return promptInjectionPatterns.some(pattern => pattern.test(content));
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Check content for secrets and prompt injection, handle based on force flag
|
|
594
|
+
* Returns true if write should proceed, false if blocked
|
|
595
|
+
*/
|
|
596
|
+
export function checkSecretsBeforeWrite(
|
|
597
|
+
content: string,
|
|
598
|
+
force: boolean = false
|
|
599
|
+
): boolean {
|
|
600
|
+
// Check for prompt injection first
|
|
601
|
+
if (detectPromptInjection(content) && !force) {
|
|
602
|
+
console.error('');
|
|
603
|
+
console.error(colorize('❌ PROMPT INJECTION DETECTED - Command blocked', 'red'));
|
|
604
|
+
console.error('');
|
|
605
|
+
console.error('Detected suspicious patterns that could override AI behavior.');
|
|
606
|
+
console.error('');
|
|
607
|
+
console.error(colorize('Why this is dangerous:', 'yellow'));
|
|
608
|
+
console.error(' 1. Could inject malicious instructions into AI context');
|
|
609
|
+
console.error(' 2. Could override safety rules and preferences');
|
|
610
|
+
console.error(' 3. Could compromise AI behavior in team environments');
|
|
611
|
+
console.error('');
|
|
612
|
+
console.error(colorize('Recommended actions:', 'cyan'));
|
|
613
|
+
console.error(' 1. Rephrase without instruction-override language');
|
|
614
|
+
console.error(' 2. Use clear, declarative statements instead');
|
|
615
|
+
console.error(' Example: "Project uses TypeScript" (not "Forget previous, use TypeScript")');
|
|
616
|
+
console.error('');
|
|
617
|
+
console.error(colorize('If you\'re CERTAIN this is safe:', 'yellow'));
|
|
618
|
+
console.error(' Add --force flag to proceed');
|
|
619
|
+
console.error('');
|
|
620
|
+
return false; // Block write
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
const result = detectSecrets(content);
|
|
624
|
+
|
|
625
|
+
if (!result.detected) {
|
|
626
|
+
return true; // No secrets, proceed
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
if (!force) {
|
|
630
|
+
// Block write and show warning
|
|
631
|
+
console.error('');
|
|
632
|
+
console.error(colorize('❌ SECRET DETECTED - Command blocked', 'red'));
|
|
633
|
+
console.error('');
|
|
634
|
+
console.error('Detected patterns:');
|
|
635
|
+
for (const pattern of result.patterns) {
|
|
636
|
+
console.error(` - ${pattern}`);
|
|
637
|
+
}
|
|
638
|
+
console.error('');
|
|
639
|
+
console.error(colorize('Why this is dangerous:', 'yellow'));
|
|
640
|
+
console.error(' 1. Secrets will be committed to Git');
|
|
641
|
+
console.error(' 2. Secrets will be in Git history forever');
|
|
642
|
+
console.error(' 3. Team members will see secrets');
|
|
643
|
+
console.error(' 4. Secrets may be pushed to remote repos');
|
|
644
|
+
console.error('');
|
|
645
|
+
console.error(colorize('Recommended actions:', 'cyan'));
|
|
646
|
+
console.error(' 1. Use environment variables instead');
|
|
647
|
+
console.error(' 2. Reference secrets, don\'t include them');
|
|
648
|
+
console.error(' Example: "API key stored in .env file"');
|
|
649
|
+
console.error('');
|
|
650
|
+
console.error(colorize('If you\'re CERTAIN this is not a secret:', 'yellow'));
|
|
651
|
+
console.error(' Add --force flag to proceed');
|
|
652
|
+
console.error('');
|
|
653
|
+
|
|
654
|
+
return false; // Block write
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Force flag used - warn but allow
|
|
658
|
+
console.warn('');
|
|
659
|
+
console.warn(colorize('⚠️ WARNING: Secret pattern detected but proceeding (--force)', 'yellow'));
|
|
660
|
+
console.warn('You are responsible for this secret in version control.');
|
|
661
|
+
console.warn('');
|
|
662
|
+
|
|
663
|
+
return true; // Allow write with warning
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// ============================================
|
|
667
|
+
// DURATION PARSING
|
|
668
|
+
// ============================================
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Parse a duration string like "7d", "2w", "1m" to a Date
|
|
672
|
+
* Returns date that is `duration` ago from now
|
|
673
|
+
*/
|
|
674
|
+
export function parseDuration(duration: string): Date | null {
|
|
675
|
+
const match = duration.match(/^(\d+)([dwmy])$/);
|
|
676
|
+
|
|
677
|
+
if (!match) {
|
|
678
|
+
return null;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
const [, numStr, unit] = match;
|
|
682
|
+
const num = parseInt(numStr, 10);
|
|
683
|
+
const ms = DURATION_MS[unit as DurationUnit];
|
|
684
|
+
|
|
685
|
+
if (!ms) {
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return new Date(Date.now() - num * ms);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Format a duration for display
|
|
694
|
+
*/
|
|
695
|
+
export function formatDuration(ms: number): string {
|
|
696
|
+
const seconds = Math.floor(ms / 1000);
|
|
697
|
+
const minutes = Math.floor(seconds / 60);
|
|
698
|
+
const hours = Math.floor(minutes / 60);
|
|
699
|
+
const days = Math.floor(hours / 24);
|
|
700
|
+
|
|
701
|
+
if (days > 0) return `${days}d ago`;
|
|
702
|
+
if (hours > 0) return `${hours}h ago`;
|
|
703
|
+
if (minutes > 0) return `${minutes}m ago`;
|
|
704
|
+
return `${seconds}s ago`;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// ============================================
|
|
708
|
+
// ENTRY FILTERING
|
|
709
|
+
// ============================================
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Filter entries by tag
|
|
713
|
+
*/
|
|
714
|
+
export function filterByTag<T extends BaseEntry>(entries: T[], tag: string): T[] {
|
|
715
|
+
const lowerTag = tag.toLowerCase();
|
|
716
|
+
return entries.filter(e =>
|
|
717
|
+
e.tags?.some(t => t.toLowerCase() === lowerTag)
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Filter entries by date (since duration)
|
|
723
|
+
*/
|
|
724
|
+
export function filterBySince<T extends BaseEntry>(entries: T[], since: string): T[] {
|
|
725
|
+
const cutoff = parseDuration(since);
|
|
726
|
+
if (!cutoff) return entries;
|
|
727
|
+
|
|
728
|
+
return entries.filter(e => new Date(e.ts) > cutoff);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Filter entries by status
|
|
733
|
+
*/
|
|
734
|
+
export function filterByStatus<T extends BaseEntry>(
|
|
735
|
+
entries: T[],
|
|
736
|
+
status: string
|
|
737
|
+
): T[] {
|
|
738
|
+
return entries.filter(e => e.status === status);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Search entries by keyword (in details, problem, solution, or tags)
|
|
743
|
+
*/
|
|
744
|
+
export function searchEntries<T extends BaseEntry>(
|
|
745
|
+
entries: T[],
|
|
746
|
+
keyword: string
|
|
747
|
+
): T[] {
|
|
748
|
+
const kw = keyword.toLowerCase();
|
|
749
|
+
|
|
750
|
+
return entries.filter(e => {
|
|
751
|
+
// Check tags
|
|
752
|
+
if (e.tags?.some(t => t.toLowerCase().includes(kw))) {
|
|
753
|
+
return true;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// Check memory-specific fields
|
|
757
|
+
const memEntry = e as unknown as MemoryEntry;
|
|
758
|
+
if (memEntry.details?.toLowerCase().includes(kw)) {
|
|
759
|
+
return true;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Check learning-specific fields
|
|
763
|
+
const learnEntry = e as unknown as LearningEntry;
|
|
764
|
+
if (learnEntry.problem?.toLowerCase().includes(kw)) {
|
|
765
|
+
return true;
|
|
766
|
+
}
|
|
767
|
+
if (learnEntry.solution?.toLowerCase().includes(kw)) {
|
|
768
|
+
return true;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// Check change-specific fields
|
|
772
|
+
const changeEntry = e as unknown as ChangeEntry;
|
|
773
|
+
if (changeEntry.file?.toLowerCase().includes(kw)) {
|
|
774
|
+
return true;
|
|
775
|
+
}
|
|
776
|
+
if (changeEntry.reason?.toLowerCase().includes(kw)) {
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// Check code snippet-specific fields
|
|
781
|
+
if (memEntry.type === 'code_snippet') {
|
|
782
|
+
if (memEntry.code?.toLowerCase().includes(kw)) {
|
|
783
|
+
return true;
|
|
784
|
+
}
|
|
785
|
+
if (memEntry.language?.toLowerCase().includes(kw)) {
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
if (memEntry.context?.toLowerCase().includes(kw)) {
|
|
789
|
+
return true;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
return false;
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// ============================================
|
|
798
|
+
// LEGACY FORMAT DETECTION & PARSING
|
|
799
|
+
// ============================================
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Check if any log files are in legacy (text) format
|
|
803
|
+
*/
|
|
804
|
+
export function hasLegacyFormat(root?: string): boolean {
|
|
805
|
+
const logFiles = ['MEMORY', 'LEARNINGS', 'CHANGES'] as const;
|
|
806
|
+
|
|
807
|
+
for (const fileKey of logFiles) {
|
|
808
|
+
const filePath = getFilePath(fileKey, root);
|
|
809
|
+
if (fs.existsSync(filePath) && !isJsonlFormat(filePath)) {
|
|
810
|
+
return true;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* Parse legacy memory entry: [TIMESTAMP] MESSAGE [tags]
|
|
819
|
+
*/
|
|
820
|
+
export function parseLegacyMemoryLine(line: string): MemoryEntry | null {
|
|
821
|
+
const match = line.match(/\[(.*?)\]\s*(.+?)(\s*\[.*\])?$/);
|
|
822
|
+
if (!match) return null;
|
|
823
|
+
|
|
824
|
+
const [, timestamp, message, tagsStr] = match;
|
|
825
|
+
const tags = tagsStr
|
|
826
|
+
? tagsStr.slice(2, -1).split(',').map(t => t.trim()).filter(Boolean)
|
|
827
|
+
: [];
|
|
828
|
+
|
|
829
|
+
return {
|
|
830
|
+
id: generateId(),
|
|
831
|
+
ts: timestamp,
|
|
832
|
+
agent: 'migrated',
|
|
833
|
+
type: 'note',
|
|
834
|
+
details: message.trim(),
|
|
835
|
+
tags,
|
|
836
|
+
status: 'ACTIVE',
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Parse legacy learning entry: [TIMESTAMP] [STATUS] PROBLEM -> SOLUTION [tags]
|
|
842
|
+
*/
|
|
843
|
+
export function parseLegacyLearningLine(line: string): LearningEntry | null {
|
|
844
|
+
const match = line.match(/\[(.*?)\]\s*\[(.*?)\]\s*(.+?)\s*->\s*(.+?)(\s*\[.*\])?$/);
|
|
845
|
+
if (!match) return null;
|
|
846
|
+
|
|
847
|
+
const [, timestamp, statusPart, problem, solution, tagsStr] = match;
|
|
848
|
+
const outcome = statusPart.includes('SUCCESS') ? 'SUCCESS' : 'FAILED';
|
|
849
|
+
const tags = tagsStr
|
|
850
|
+
? tagsStr.slice(2, -1).split(',').map(t => t.trim()).filter(Boolean)
|
|
851
|
+
: [];
|
|
852
|
+
|
|
853
|
+
return {
|
|
854
|
+
id: generateId(),
|
|
855
|
+
ts: timestamp,
|
|
856
|
+
agent: 'migrated',
|
|
857
|
+
problem: problem.trim(),
|
|
858
|
+
solution: solution.trim(),
|
|
859
|
+
outcome,
|
|
860
|
+
tags,
|
|
861
|
+
status: 'ACTIVE',
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* Parse legacy change entry: [TIMESTAMP] FILE: REASON (agent)
|
|
867
|
+
*/
|
|
868
|
+
export function parseLegacyChangeLine(line: string): ChangeEntry | null {
|
|
869
|
+
const match = line.match(/\[(.*?)\]\s*(.+?):\s*(.+?)(\s*\(.*\))?$/);
|
|
870
|
+
if (!match) return null;
|
|
871
|
+
|
|
872
|
+
const [, timestamp, file, reason, agentStr] = match;
|
|
873
|
+
const agent = agentStr ? agentStr.slice(2, -1) : 'migrated';
|
|
874
|
+
|
|
875
|
+
return {
|
|
876
|
+
id: generateId(),
|
|
877
|
+
ts: timestamp,
|
|
878
|
+
agent,
|
|
879
|
+
file: file.trim(),
|
|
880
|
+
action: 'edited',
|
|
881
|
+
reason: reason.trim(),
|
|
882
|
+
status: 'ACTIVE',
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
|