metalist 0.2.0__tar.gz

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 (321) hide show
  1. metalist-0.2.0/MANIFEST.in +3 -0
  2. metalist-0.2.0/PKG-INFO +288 -0
  3. metalist-0.2.0/README.md +259 -0
  4. metalist-0.2.0/app/__init__.py +0 -0
  5. metalist-0.2.0/app/api/__init__.py +0 -0
  6. metalist-0.2.0/app/api/deps.py +15 -0
  7. metalist-0.2.0/app/api/dev.py +32 -0
  8. metalist-0.2.0/app/api/middleware/auth.py +137 -0
  9. metalist-0.2.0/app/api/request_auth.py +61 -0
  10. metalist-0.2.0/app/api/routes/auth.py +1183 -0
  11. metalist-0.2.0/app/api/routes/backups.py +1033 -0
  12. metalist-0.2.0/app/api/routes/files.py +97 -0
  13. metalist-0.2.0/app/api/routes/mcp.py +30 -0
  14. metalist-0.2.0/app/api/routes/memory.py +107 -0
  15. metalist-0.2.0/app/api/routes/notes.py +1229 -0
  16. metalist-0.2.0/app/api/routes/ontology.py +456 -0
  17. metalist-0.2.0/app/api/routes/reminders.py +257 -0
  18. metalist-0.2.0/app/api/routes/sounds.py +190 -0
  19. metalist-0.2.0/app/api/routes/test.py +17 -0
  20. metalist-0.2.0/app/api/transactions.py +95 -0
  21. metalist-0.2.0/app/config.py +124 -0
  22. metalist-0.2.0/app/db/__init__.py +13 -0
  23. metalist-0.2.0/app/db/backup_settings_sql.py +70 -0
  24. metalist-0.2.0/app/db/engine.py +109 -0
  25. metalist-0.2.0/app/db/file_schema.py +48 -0
  26. metalist-0.2.0/app/db/file_session.py +146 -0
  27. metalist-0.2.0/app/db/files_sql.py +178 -0
  28. metalist-0.2.0/app/db/link_titles_sql.py +225 -0
  29. metalist-0.2.0/app/db/migrations.py +166 -0
  30. metalist-0.2.0/app/db/notes_sql.py +465 -0
  31. metalist-0.2.0/app/db/ontology_rules_sql.py +153 -0
  32. metalist-0.2.0/app/db/reminders_sql.py +119 -0
  33. metalist-0.2.0/app/db/schema.py +234 -0
  34. metalist-0.2.0/app/db/search_history_sql.py +213 -0
  35. metalist-0.2.0/app/db/session.py +171 -0
  36. metalist-0.2.0/app/db/settings_sql.py +289 -0
  37. metalist-0.2.0/app/db/sounds_sql.py +162 -0
  38. metalist-0.2.0/app/db/tab_state_sql.py +97 -0
  39. metalist-0.2.0/app/encryption_audit.py +776 -0
  40. metalist-0.2.0/app/main.py +633 -0
  41. metalist-0.2.0/app/mcp/__init__.py +2 -0
  42. metalist-0.2.0/app/mcp/__main__.py +8 -0
  43. metalist-0.2.0/app/mcp/errors.py +18 -0
  44. metalist-0.2.0/app/mcp/policy.py +55 -0
  45. metalist-0.2.0/app/mcp/read_service.py +1124 -0
  46. metalist-0.2.0/app/mcp/server.py +230 -0
  47. metalist-0.2.0/app/mcp/tools.py +480 -0
  48. metalist-0.2.0/app/models/commands.py +7 -0
  49. metalist-0.2.0/app/models/database.py +253 -0
  50. metalist-0.2.0/app/models/entities.py +19 -0
  51. metalist-0.2.0/app/models/enums.py +5 -0
  52. metalist-0.2.0/app/models/linked_list.py +67 -0
  53. metalist-0.2.0/app/models/list_operations.py +263 -0
  54. metalist-0.2.0/app/models/list_traversal.py +202 -0
  55. metalist-0.2.0/app/models/note_crud.py +307 -0
  56. metalist-0.2.0/app/models/utils.py +649 -0
  57. metalist-0.2.0/app/presentation/__init__.py +0 -0
  58. metalist-0.2.0/app/presentation/render/__init__.py +0 -0
  59. metalist-0.2.0/app/presentation/render/note_renderer.py +457 -0
  60. metalist-0.2.0/app/presentation/templates.py +22 -0
  61. metalist-0.2.0/app/security/encryption.py +41 -0
  62. metalist-0.2.0/app/server_runtime.py +1089 -0
  63. metalist-0.2.0/app/services/__init__.py +1 -0
  64. metalist-0.2.0/app/services/auth.py +3 -0
  65. metalist-0.2.0/app/services/auth_cache_state.py +32 -0
  66. metalist-0.2.0/app/services/auth_service.py +729 -0
  67. metalist-0.2.0/app/services/backlinks.py +100 -0
  68. metalist-0.2.0/app/services/backup_service.py +1039 -0
  69. metalist-0.2.0/app/services/backup_settings_service.py +173 -0
  70. metalist-0.2.0/app/services/base_service.py +142 -0
  71. metalist-0.2.0/app/services/client_state_service.py +364 -0
  72. metalist-0.2.0/app/services/content_cache.py +341 -0
  73. metalist-0.2.0/app/services/content_formatting.py +1798 -0
  74. metalist-0.2.0/app/services/date_filtering.py +135 -0
  75. metalist-0.2.0/app/services/dependencies.py +72 -0
  76. metalist-0.2.0/app/services/diagnostics.py +564 -0
  77. metalist-0.2.0/app/services/embedded_references.py +989 -0
  78. metalist-0.2.0/app/services/encryption.py +331 -0
  79. metalist-0.2.0/app/services/exception_capture.py +29 -0
  80. metalist-0.2.0/app/services/file_registry.py +83 -0
  81. metalist-0.2.0/app/services/file_storage.py +641 -0
  82. metalist-0.2.0/app/services/html_export.py +311 -0
  83. metalist-0.2.0/app/services/html_unformatting.py +344 -0
  84. metalist-0.2.0/app/services/hydration_state.py +131 -0
  85. metalist-0.2.0/app/services/integrity.py +150 -0
  86. metalist-0.2.0/app/services/latex_rendering.py +278 -0
  87. metalist-0.2.0/app/services/link_titles.py +1178 -0
  88. metalist-0.2.0/app/services/login_rate_limit.py +86 -0
  89. metalist-0.2.0/app/services/maintenance_mode.py +46 -0
  90. metalist-0.2.0/app/services/markdown_rendering.py +627 -0
  91. metalist-0.2.0/app/services/memory.py +9 -0
  92. metalist-0.2.0/app/services/memory_service.py +213 -0
  93. metalist-0.2.0/app/services/namespace_deletion_jobs.py +119 -0
  94. metalist-0.2.0/app/services/namespace_deletion_worker.py +138 -0
  95. metalist-0.2.0/app/services/namespace_switcher.py +1525 -0
  96. metalist-0.2.0/app/services/note_image_tags.py +69 -0
  97. metalist-0.2.0/app/services/note_service.py +290 -0
  98. metalist-0.2.0/app/services/note_store.py +1362 -0
  99. metalist-0.2.0/app/services/ontology_rules_store.py +544 -0
  100. metalist-0.2.0/app/services/query_service.py +282 -0
  101. metalist-0.2.0/app/services/reminders.py +1415 -0
  102. metalist-0.2.0/app/services/root_sorting.py +138 -0
  103. metalist-0.2.0/app/services/runtime_hardening.py +89 -0
  104. metalist-0.2.0/app/services/search_history.py +987 -0
  105. metalist-0.2.0/app/services/search_index.py +904 -0
  106. metalist-0.2.0/app/services/search_query.py +140 -0
  107. metalist-0.2.0/app/services/search_text.py +65 -0
  108. metalist-0.2.0/app/services/session_timeout_service.py +77 -0
  109. metalist-0.2.0/app/services/shell_session_service.py +247 -0
  110. metalist-0.2.0/app/services/snapshot.py +685 -0
  111. metalist-0.2.0/app/services/sound_storage.py +754 -0
  112. metalist-0.2.0/app/services/store.py +134 -0
  113. metalist-0.2.0/app/services/sync.py +74 -0
  114. metalist-0.2.0/app/services/sync_state.py +146 -0
  115. metalist-0.2.0/app/services/tab_state.py +603 -0
  116. metalist-0.2.0/app/services/tag_case.py +58 -0
  117. metalist-0.2.0/app/services/tag_ontology.py +663 -0
  118. metalist-0.2.0/app/services/tag_rename.py +212 -0
  119. metalist-0.2.0/app/services/tag_suggestions.py +1221 -0
  120. metalist-0.2.0/app/services/tag_term_matching.py +379 -0
  121. metalist-0.2.0/app/services/test_reset.py +50 -0
  122. metalist-0.2.0/app/services/tokens.py +284 -0
  123. metalist-0.2.0/app/services/transaction_manager.py +156 -0
  124. metalist-0.2.0/app/services/undo_service.py +44 -0
  125. metalist-0.2.0/app/services/undo_state.py +1266 -0
  126. metalist-0.2.0/app/services/view_cache.py +61 -0
  127. metalist-0.2.0/app/services/view_diff.py +100 -0
  128. metalist-0.2.0/app/services/view_state.py +19 -0
  129. metalist-0.2.0/app/startup_js_sanity.py +498 -0
  130. metalist-0.2.0/app/startup_sanity.py +615 -0
  131. metalist-0.2.0/app/startup_sanity_config.py +67 -0
  132. metalist-0.2.0/app/static/config/command_palette_tags.json +164 -0
  133. metalist-0.2.0/app/static/css/forms.css +177 -0
  134. metalist-0.2.0/app/static/css/main.css +6037 -0
  135. metalist-0.2.0/app/static/img/favicon.ico +0 -0
  136. metalist-0.2.0/app/static/js/locked.js +14 -0
  137. metalist-0.2.0/app/static/js/main.js +76 -0
  138. metalist-0.2.0/app/static/js/modules/activity-tracker.js +39 -0
  139. metalist-0.2.0/app/static/js/modules/api-client.js +1154 -0
  140. metalist-0.2.0/app/static/js/modules/async-result.js +11 -0
  141. metalist-0.2.0/app/static/js/modules/auth.js +810 -0
  142. metalist-0.2.0/app/static/js/modules/client-state-api.js +69 -0
  143. metalist-0.2.0/app/static/js/modules/client-state-migration.js +277 -0
  144. metalist-0.2.0/app/static/js/modules/command-palette/click-activation-service.js +27 -0
  145. metalist-0.2.0/app/static/js/modules/command-palette/command-palette-controller.js +1974 -0
  146. metalist-0.2.0/app/static/js/modules/command-palette/endpoint-registry.js +345 -0
  147. metalist-0.2.0/app/static/js/modules/command-palette/preferences-store.js +63 -0
  148. metalist-0.2.0/app/static/js/modules/command-palette/tag-config-loader.js +54 -0
  149. metalist-0.2.0/app/static/js/modules/command-palette/usage-store.js +72 -0
  150. metalist-0.2.0/app/static/js/modules/config.js +204 -0
  151. metalist-0.2.0/app/static/js/modules/connectivity-monitor.js +91 -0
  152. metalist-0.2.0/app/static/js/modules/context-menu/context-menu-registry.js +338 -0
  153. metalist-0.2.0/app/static/js/modules/context-menu/context-menu-service.js +396 -0
  154. metalist-0.2.0/app/static/js/modules/context-menu/input-caret-service.js +127 -0
  155. metalist-0.2.0/app/static/js/modules/dom-utils-fixed.js +293 -0
  156. metalist-0.2.0/app/static/js/modules/dom-utils.js +339 -0
  157. metalist-0.2.0/app/static/js/modules/editor-commands.js +192 -0
  158. metalist-0.2.0/app/static/js/modules/editor-selection.js +110 -0
  159. metalist-0.2.0/app/static/js/modules/editor-toolbar.js +203 -0
  160. metalist-0.2.0/app/static/js/modules/error-handler.js +288 -0
  161. metalist-0.2.0/app/static/js/modules/error-overlay.js +73 -0
  162. metalist-0.2.0/app/static/js/modules/location-flags.js +22 -0
  163. metalist-0.2.0/app/static/js/modules/login-namespace-picker.js +101 -0
  164. metalist-0.2.0/app/static/js/modules/modals/alphabetize-root-notes-modal.js +175 -0
  165. metalist-0.2.0/app/static/js/modules/modals/backup-restore-modal.js +894 -0
  166. metalist-0.2.0/app/static/js/modules/modals/backup-result-modal.js +247 -0
  167. metalist-0.2.0/app/static/js/modules/modals/backup-retention-modal.js +301 -0
  168. metalist-0.2.0/app/static/js/modules/modals/backup-settings-modal.js +511 -0
  169. metalist-0.2.0/app/static/js/modules/modals/base-modal.js +324 -0
  170. metalist-0.2.0/app/static/js/modules/modals/delete-namespace-modal.js +529 -0
  171. metalist-0.2.0/app/static/js/modules/modals/delete-namespace-validation.js +35 -0
  172. metalist-0.2.0/app/static/js/modules/modals/help-modal.js +174 -0
  173. metalist-0.2.0/app/static/js/modules/modals/memory-modal.js +282 -0
  174. metalist-0.2.0/app/static/js/modules/modals/namespace-loading-page.js +124 -0
  175. metalist-0.2.0/app/static/js/modules/modals/namespace-modals.js +962 -0
  176. metalist-0.2.0/app/static/js/modules/modals/ontology-modal.js +2736 -0
  177. metalist-0.2.0/app/static/js/modules/modals/password-modal.js +554 -0
  178. metalist-0.2.0/app/static/js/modules/modals/prioritize-modal.js +527 -0
  179. metalist-0.2.0/app/static/js/modules/modals/random-password-modal.js +323 -0
  180. metalist-0.2.0/app/static/js/modules/modals/reminder-modal.js +1473 -0
  181. metalist-0.2.0/app/static/js/modules/modals/reset-updated-at-modal.js +165 -0
  182. metalist-0.2.0/app/static/js/modules/modals/session-timeout-modal.js +334 -0
  183. metalist-0.2.0/app/static/js/modules/modals/sound-manager-modal.js +273 -0
  184. metalist-0.2.0/app/static/js/modules/modals/version-info-modal.js +196 -0
  185. metalist-0.2.0/app/static/js/modules/mode-manager/actions/content-actions.js +116 -0
  186. metalist-0.2.0/app/static/js/modules/mode-manager/actions/history-actions.js +328 -0
  187. metalist-0.2.0/app/static/js/modules/mode-manager/actions/note-actions.js +1048 -0
  188. metalist-0.2.0/app/static/js/modules/mode-manager/actions/search-actions.js +29 -0
  189. metalist-0.2.0/app/static/js/modules/mode-manager/actions/selection-actions.js +273 -0
  190. metalist-0.2.0/app/static/js/modules/mode-manager/actions/ui-actions.js +405 -0
  191. metalist-0.2.0/app/static/js/modules/mode-manager/events/context-menu-events.js +822 -0
  192. metalist-0.2.0/app/static/js/modules/mode-manager/events/focus-events.js +93 -0
  193. metalist-0.2.0/app/static/js/modules/mode-manager/events/inactivity-events.js +41 -0
  194. metalist-0.2.0/app/static/js/modules/mode-manager/events/input-events.js +182 -0
  195. metalist-0.2.0/app/static/js/modules/mode-manager/events/keyboard-events.js +3547 -0
  196. metalist-0.2.0/app/static/js/modules/mode-manager/events/mouse-events.js +2154 -0
  197. metalist-0.2.0/app/static/js/modules/mode-manager/events/search-events.js +185 -0
  198. metalist-0.2.0/app/static/js/modules/mode-manager/mode-context.js +1920 -0
  199. metalist-0.2.0/app/static/js/modules/mode-manager/mode-logger.js +62 -0
  200. metalist-0.2.0/app/static/js/modules/mode-manager/mode-manager-controller.js +106 -0
  201. metalist-0.2.0/app/static/js/modules/mode-manager/services/animated-scroll-service.js +80 -0
  202. metalist-0.2.0/app/static/js/modules/mode-manager/services/backlinks-panel-service.js +216 -0
  203. metalist-0.2.0/app/static/js/modules/mode-manager/services/clipboard-shortcut-policy-service.js +81 -0
  204. metalist-0.2.0/app/static/js/modules/mode-manager/services/collapse-affordance-service.js +232 -0
  205. metalist-0.2.0/app/static/js/modules/mode-manager/services/collapse-editing-policy-service.js +26 -0
  206. metalist-0.2.0/app/static/js/modules/mode-manager/services/command-gate-service.js +119 -0
  207. metalist-0.2.0/app/static/js/modules/mode-manager/services/context-menu-target-service.js +78 -0
  208. metalist-0.2.0/app/static/js/modules/mode-manager/services/date-filter-indicator-service.js +100 -0
  209. metalist-0.2.0/app/static/js/modules/mode-manager/services/date-filter-service.js +105 -0
  210. metalist-0.2.0/app/static/js/modules/mode-manager/services/differential-view-service.js +1133 -0
  211. metalist-0.2.0/app/static/js/modules/mode-manager/services/edit-session-collapse-policy-service.js +19 -0
  212. metalist-0.2.0/app/static/js/modules/mode-manager/services/edit-session-collapse-service.js +66 -0
  213. metalist-0.2.0/app/static/js/modules/mode-manager/services/embedded-image-service.js +332 -0
  214. metalist-0.2.0/app/static/js/modules/mode-manager/services/file-image-preview-service.js +159 -0
  215. metalist-0.2.0/app/static/js/modules/mode-manager/services/file-reference-service.js +441 -0
  216. metalist-0.2.0/app/static/js/modules/mode-manager/services/filtered-refresh-selection-service.js +38 -0
  217. metalist-0.2.0/app/static/js/modules/mode-manager/services/html-paste-sanitizer-service.js +1833 -0
  218. metalist-0.2.0/app/static/js/modules/mode-manager/services/image-context-menu-action-service.js +399 -0
  219. metalist-0.2.0/app/static/js/modules/mode-manager/services/image-file-insert-choice-modal-service.js +160 -0
  220. metalist-0.2.0/app/static/js/modules/mode-manager/services/infinite-scroll-service.js +203 -0
  221. metalist-0.2.0/app/static/js/modules/mode-manager/services/link-context-menu-action-service.js +62 -0
  222. metalist-0.2.0/app/static/js/modules/mode-manager/services/markdown-render-service.js +160 -0
  223. metalist-0.2.0/app/static/js/modules/mode-manager/services/note-click-target-service.js +27 -0
  224. metalist-0.2.0/app/static/js/modules/mode-manager/services/note-clipboard-write-service.js +282 -0
  225. metalist-0.2.0/app/static/js/modules/mode-manager/services/note-collapse-animation-service.js +202 -0
  226. metalist-0.2.0/app/static/js/modules/mode-manager/services/note-context-menu-action-service.js +91 -0
  227. metalist-0.2.0/app/static/js/modules/mode-manager/services/note-drag-service.js +170 -0
  228. metalist-0.2.0/app/static/js/modules/mode-manager/services/note-reposition-animation-service.js +363 -0
  229. metalist-0.2.0/app/static/js/modules/mode-manager/services/note-split-service.js +52 -0
  230. metalist-0.2.0/app/static/js/modules/mode-manager/services/password-clipboard-service.js +97 -0
  231. metalist-0.2.0/app/static/js/modules/mode-manager/services/polling-service.js +159 -0
  232. metalist-0.2.0/app/static/js/modules/mode-manager/services/rhs-panel-service.js +1019 -0
  233. metalist-0.2.0/app/static/js/modules/mode-manager/services/root-date-separator-service.js +45 -0
  234. metalist-0.2.0/app/static/js/modules/mode-manager/services/root-sort-indicator-service.js +31 -0
  235. metalist-0.2.0/app/static/js/modules/mode-manager/services/root-sort-service.js +90 -0
  236. metalist-0.2.0/app/static/js/modules/mode-manager/services/scroll-anchor-service.js +237 -0
  237. metalist-0.2.0/app/static/js/modules/mode-manager/services/scroll-restoration-service.js +312 -0
  238. metalist-0.2.0/app/static/js/modules/mode-manager/services/scroll-to-top-service.js +129 -0
  239. metalist-0.2.0/app/static/js/modules/mode-manager/services/search-contexts-overlay-service.js +328 -0
  240. metalist-0.2.0/app/static/js/modules/mode-manager/services/search-debounce-service.js +25 -0
  241. metalist-0.2.0/app/static/js/modules/mode-manager/services/search-input-service.js +110 -0
  242. metalist-0.2.0/app/static/js/modules/mode-manager/services/search-interaction-service.js +181 -0
  243. metalist-0.2.0/app/static/js/modules/mode-manager/services/search-redaction-reveal-service.js +300 -0
  244. metalist-0.2.0/app/static/js/modules/mode-manager/services/search-suggestions-service.js +506 -0
  245. metalist-0.2.0/app/static/js/modules/mode-manager/services/search-syntax-service.js +299 -0
  246. metalist-0.2.0/app/static/js/modules/mode-manager/services/shell-output-service.js +302 -0
  247. metalist-0.2.0/app/static/js/modules/mode-manager/services/tab-dom-cache-service.js +141 -0
  248. metalist-0.2.0/app/static/js/modules/mode-manager/services/tab-duplication-service.js +122 -0
  249. metalist-0.2.0/app/static/js/modules/mode-manager/services/tab-state-service.js +281 -0
  250. metalist-0.2.0/app/static/js/modules/mode-manager/services/tag-bar-service.js +508 -0
  251. metalist-0.2.0/app/static/js/modules/mode-manager/services/tag-suggestions-service.js +379 -0
  252. metalist-0.2.0/app/static/js/modules/mode-manager/services/tag-syntax-service.js +669 -0
  253. metalist-0.2.0/app/static/js/modules/mode-manager/services/todo-toggle-editing-service.js +34 -0
  254. metalist-0.2.0/app/static/js/modules/mode-manager/services/view-mode-search-shortcut-service.js +35 -0
  255. metalist-0.2.0/app/static/js/modules/password-generator.js +75 -0
  256. metalist-0.2.0/app/static/js/modules/reminder-store.js +144 -0
  257. metalist-0.2.0/app/static/js/modules/reminder-surface-service.js +1317 -0
  258. metalist-0.2.0/app/static/js/modules/selection-markers.js +86 -0
  259. metalist-0.2.0/app/static/js/modules/session-auth.js +22 -0
  260. metalist-0.2.0/app/static/js/modules/sound-service.js +380 -0
  261. metalist-0.2.0/app/static/js/modules/tag-token.js +49 -0
  262. metalist-0.2.0/app/static/js/modules/uuid.js +19 -0
  263. metalist-0.2.0/app/static/js/namespace-deleted.js +190 -0
  264. metalist-0.2.0/app/static/js/vendor/markdown-it.min.js +1 -0
  265. metalist-0.2.0/app/static/video/login-startup.mp4 +0 -0
  266. metalist-0.2.0/app/templates/base.html +24 -0
  267. metalist-0.2.0/app/templates/index.html +183 -0
  268. metalist-0.2.0/app/templates/locked.html +85 -0
  269. metalist-0.2.0/app/templates/maintenance.html +106 -0
  270. metalist-0.2.0/app/templates/namespace_deleted.html +230 -0
  271. metalist-0.2.0/app/templates/notes_list.html +54 -0
  272. metalist-0.2.0/app/usecases/__init__.py +2 -0
  273. metalist-0.2.0/app/usecases/alphabetize_root_notes.py +201 -0
  274. metalist-0.2.0/app/usecases/base.py +14 -0
  275. metalist-0.2.0/app/usecases/collapse.py +65 -0
  276. metalist-0.2.0/app/usecases/copy_note.py +84 -0
  277. metalist-0.2.0/app/usecases/create_child.py +65 -0
  278. metalist-0.2.0/app/usecases/create_note.py +132 -0
  279. metalist-0.2.0/app/usecases/create_sibling.py +75 -0
  280. metalist-0.2.0/app/usecases/delete_subtree.py +139 -0
  281. metalist-0.2.0/app/usecases/expand.py +43 -0
  282. metalist-0.2.0/app/usecases/indent.py +86 -0
  283. metalist-0.2.0/app/usecases/lock.py +35 -0
  284. metalist-0.2.0/app/usecases/move.py +131 -0
  285. metalist-0.2.0/app/usecases/move_to_top.py +116 -0
  286. metalist-0.2.0/app/usecases/outdent.py +91 -0
  287. metalist-0.2.0/app/usecases/paste_child.py +46 -0
  288. metalist-0.2.0/app/usecases/paste_sibling.py +292 -0
  289. metalist-0.2.0/app/usecases/prioritize.py +280 -0
  290. metalist-0.2.0/app/usecases/record_edit_mode.py +45 -0
  291. metalist-0.2.0/app/usecases/redo.py +33 -0
  292. metalist-0.2.0/app/usecases/rename_tag.py +79 -0
  293. metalist-0.2.0/app/usecases/reset_updated_at.py +127 -0
  294. metalist-0.2.0/app/usecases/run_shell.py +63 -0
  295. metalist-0.2.0/app/usecases/search_comment_autofill.py +128 -0
  296. metalist-0.2.0/app/usecases/search_context_tags.py +105 -0
  297. metalist-0.2.0/app/usecases/set_collapse_bulk.py +55 -0
  298. metalist-0.2.0/app/usecases/set_collapse_in_context.py +175 -0
  299. metalist-0.2.0/app/usecases/split_note.py +96 -0
  300. metalist-0.2.0/app/usecases/toggle_reference_mode.py +65 -0
  301. metalist-0.2.0/app/usecases/toggle_todo_done.py +49 -0
  302. metalist-0.2.0/app/usecases/undo.py +33 -0
  303. metalist-0.2.0/app/usecases/unformat_content.py +50 -0
  304. metalist-0.2.0/app/usecases/update_content.py +128 -0
  305. metalist-0.2.0/app/usecases/view.py +28 -0
  306. metalist-0.2.0/app/utils/__init__.py +0 -0
  307. metalist-0.2.0/app/utils/encryption.py +205 -0
  308. metalist-0.2.0/app/utils/text_utils.py +117 -0
  309. metalist-0.2.0/app/version.py +3 -0
  310. metalist-0.2.0/convert-from-legacy.py +992 -0
  311. metalist-0.2.0/main.py +811 -0
  312. metalist-0.2.0/mcp_client.py +10083 -0
  313. metalist-0.2.0/metalist.egg-info/PKG-INFO +288 -0
  314. metalist-0.2.0/metalist.egg-info/SOURCES.txt +319 -0
  315. metalist-0.2.0/metalist.egg-info/dependency_links.txt +1 -0
  316. metalist-0.2.0/metalist.egg-info/entry_points.txt +4 -0
  317. metalist-0.2.0/metalist.egg-info/requires.txt +20 -0
  318. metalist-0.2.0/metalist.egg-info/top_level.txt +3 -0
  319. metalist-0.2.0/pyproject.toml +62 -0
  320. metalist-0.2.0/scripts/generate-lan-cert.sh +121 -0
  321. metalist-0.2.0/setup.cfg +4 -0
@@ -0,0 +1,3 @@
1
+ recursive-include app/static *
2
+ recursive-include app/templates *.html
3
+ global-exclude .DS_Store
@@ -0,0 +1,288 @@
1
+ Metadata-Version: 2.4
2
+ Name: metalist
3
+ Version: 0.2.0
4
+ Summary: A minimalist single-user note-taking app with SSR, fast in-memory tree operations, and efficient sync.
5
+ Project-URL: Homepage, https://github.com/evolvingstuff/metalist
6
+ Project-URL: Repository, https://github.com/evolvingstuff/metalist
7
+ Project-URL: Issues, https://github.com/evolvingstuff/metalist/issues
8
+ Requires-Python: <3.14,>=3.10
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: argon2-cffi==25.1.0
11
+ Requires-Dist: cryptography==50.0.0
12
+ Requires-Dist: fastapi==0.141.1
13
+ Requires-Dist: httpx==0.28.1
14
+ Requires-Dist: latex2mathml==3.81.0
15
+ Requires-Dist: loguru==0.7.3
16
+ Requires-Dist: Mako==1.3.12
17
+ Requires-Dist: mutagen==1.48.1
18
+ Requires-Dist: pydantic==2.13.4
19
+ Requires-Dist: python-multipart==0.0.32
20
+ Requires-Dist: starlette==1.3.1
21
+ Requires-Dist: tqdm==4.70.0
22
+ Requires-Dist: tree-sitter==0.25.2
23
+ Requires-Dist: tree-sitter-javascript==0.25.0
24
+ Requires-Dist: uvicorn==0.52.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: hypothesis==6.164.0; extra == "dev"
27
+ Requires-Dist: pytest==9.1.1; extra == "dev"
28
+ Requires-Dist: pytest-cov==7.1.0; extra == "dev"
29
+
30
+ # MetaList
31
+
32
+ A minimalist single-user note-taking app focused on server-side rendering (SSR), fast in-memory tree operations, and efficient sync/diff updates.
33
+
34
+ ## Features
35
+ - Rich text editing (ContentEditable) with image support
36
+ - Drag-and-drop note reordering
37
+ - Real-time content saving
38
+ - Keyboard shortcuts (press `?` in the app)
39
+ - Linked-list ordering model for efficient reorders
40
+ - Optional password protection + encryption at rest (AES-GCM)
41
+ - Multi-tab search contexts with server-persisted scroll/search state (survives browser restarts)
42
+ - Manual namespace backups/restores to a user-selected backup folder with retention controls
43
+
44
+ ## Technology Stack
45
+
46
+ ### Backend
47
+ - FastAPI
48
+ - SQLite (via stdlib `sqlite3`) with a guard-aware wrapper (`SafeSession`)
49
+ - Mako templates for SSR
50
+
51
+ ### Frontend
52
+ - Vanilla JavaScript (no framework)
53
+ - HTML5 Drag and Drop API
54
+ - ContentEditable for rich text editing
55
+ - CSS custom properties for theming
56
+
57
+ ### Testing
58
+ - Python/unit tests plus manual regression passes
59
+
60
+ ## Architecture (High Level)
61
+ - Server renders the base page via Mako templates.
62
+ - The browser client drives interaction via `/api2` JSON endpoints.
63
+ - Notes are loaded/decrypted into an in-memory store at startup; a post-startup DB read guard prevents accidental runtime SELECTs.
64
+
65
+ ## Development
66
+
67
+ ### Setup
68
+ For a published one-off run with uv:
69
+ ```bash
70
+ uvx metalist
71
+ ```
72
+
73
+ For a persistent uv tool install:
74
+ ```bash
75
+ uv tool install metalist
76
+ metalist
77
+ ```
78
+
79
+ For pip, users can run `pip install metalist`. For a non-editable local install from this checkout, use `uv pip install .` or `pip install .` instead of the editable command below.
80
+
81
+ ```bash
82
+ python3 -m venv .venv
83
+ source .venv/bin/activate
84
+ uv pip install -e .[dev]
85
+
86
+ npm install
87
+ ```
88
+
89
+ ### Run
90
+ The installed entrypoint starts Uvicorn with the FastAPI app:
91
+ ```bash
92
+ metalist
93
+ ```
94
+ For source-checkout compatibility, `python main.py` still works. Plain `python main.py` is now an orchestration command: it restarts already-running namespaces from the current checkout, launches stopped namespaces, prints their URLs, and exits. Use `python main.py --namespace work` or `python main.py work` when you want one foreground namespace process.
95
+
96
+ `metalist` and explicit single-namespace source runs bind HTTP on `0.0.0.0:8000` by default, matching the old MetaList LAN-friendly behavior.
97
+ On first startup, MetaList also auto-generates a self-signed TLS pair at `~/MetaList/certs/metalist-cert.pem` and `~/MetaList/certs/metalist-key.pem`, then enables HTTPS on `0.0.0.0:8443`. If you already have real PEM files, point `METALIST_TLS_CERT` and `METALIST_TLS_KEY` at them instead. Set `METALIST_AUTO_GENERATE_TLS=0` only if you explicitly want HTTP-only startup.
98
+
99
+ Database selection:
100
+ - No explicit namespace on a single-namespace launch: `~/MetaList/namespaces/default/default.metalist.db`
101
+ - `--namespace work` or `METALIST_NAMESPACE=work`: `~/MetaList/namespaces/work/work.metalist.db`
102
+ - The related files DB is derived automatically, so `namespaces/work/work.metalist.db` uses `namespaces/work/work.metalist.files.db`
103
+ - Remembered launch ports are stored as plaintext metadata inside each namespace's main `*.metalist.db`
104
+ - Launch precedence is: explicit CLI flags > env vars > saved namespace profile; if a namespace has no saved profile, launch it once with explicit ports or configure ports from the UI
105
+ - Backups stay beside the namespace data under `~/MetaList/namespaces/work/backups/` and use one archive per snapshot with filenames like `work-<timestamp>.metalist-backup.tar.gz`
106
+ - The Backup Settings modal targets one user-selected backup folder and can include multiple namespaces in a single run
107
+ - Restoring `work` into `work` is the normal overwrite path; importing a backup under a different namespace name requires a new target namespace and rejects saved launch-port conflicts.
108
+
109
+ Useful env flags:
110
+ - `CRASH_SERVER_ON_FAIL=1` (default): fail-fast on validation errors
111
+ - `API_PREFIX=/api2`: override API prefix (client assumes `/api2` by default)
112
+ - `METALIST_NAMESPACE=work`: select `~/MetaList/namespaces/work/work.metalist.db`
113
+ - `METALIST_HOST=0.0.0.0` (default): bind the main app to a different interface such as `127.0.0.1`
114
+ - `METALIST_PORT=8000` (default): bind the main app to a different port
115
+ - `METALIST_HTTPS_PORT=8443`: override the HTTPS port when TLS is enabled
116
+ - `MCP_AGENT_WEB_PORT=8765` (default): bind the MCP sidecar web UI to a different port
117
+ - `METALIST_TLS_CERT=/path/to/fullchain.pem` + `METALIST_TLS_KEY=/path/to/privkey.pem`: override TLS paths
118
+ - `METALIST_AUTO_GENERATE_TLS=0`: disable automatic creation of the default self-signed TLS pair
119
+ - default TLS paths: `~/MetaList/certs/metalist-cert.pem` and `~/MetaList/certs/metalist-key.pem`
120
+ - `METALIST_FORWARDED_ALLOW_IPS=127.0.0.1,::1` (default): trust proxy headers only from those reverse-proxy IPs
121
+ - `MCP_AGENT_PUBLIC_ORIGIN=https://notes.example.com:8765`: public origin for the MCP sidecar redirect when it is exposed behind HTTPS or a separate hostname/port
122
+
123
+ ### Remote Access / HTTPS
124
+ Plain LAN or VPN HTTP works with a normal PyCharm run:
125
+ ```bash
126
+ metalist
127
+ ```
128
+ On a fresh machine, that first launch also creates the default TLS cert pair automatically. Then open either `http://<laptop-ip>:8000` or `https://<laptop-ip>:8443` from the other machine.
129
+
130
+ Namespaced launch example:
131
+ ```bash
132
+ metalist --namespace work --port 8001 --mcp-port 8766
133
+ ```
134
+ This starts a separate process backed by `~/MetaList/namespaces/work/work.metalist.db` on `http://127.0.0.1:8001`.
135
+ Its backup snapshots live under `~/MetaList/namespaces/work/backups/` with filenames like `work-<timestamp>.metalist-backup.tar.gz`. New backups are versioned `.tar.gz` workspace archives; legacy `.bak` backups remain restorable.
136
+
137
+ After you launch a namespace once with explicit ports, MetaList remembers them in that namespace's main DB, so later you can use the shorthand:
138
+ ```bash
139
+ metalist work
140
+ ```
141
+ and MetaList will reuse the saved HTTP / HTTPS / MCP sidecar ports for `work`. The same applies to the default namespace: `metalist` will reuse the saved default-namespace profile.
142
+
143
+ Equivalent explicit launch, if you want it:
144
+ ```bash
145
+ METALIST_HOST=0.0.0.0 \
146
+ METALIST_PORT=8000 \
147
+ METALIST_HTTPS_PORT=8443 \
148
+ metalist
149
+ ```
150
+ From the other machine, open `https://<laptop-ip>:8443`.
151
+
152
+ If you already have a real certificate and key, use the same dual-listener flow:
153
+ ```bash
154
+ METALIST_HOST=0.0.0.0 \
155
+ METALIST_PORT=8000 \
156
+ METALIST_HTTPS_PORT=8443 \
157
+ METALIST_TLS_CERT=/path/to/fullchain.pem \
158
+ METALIST_TLS_KEY=/path/to/privkey.pem \
159
+ metalist
160
+ ```
161
+
162
+ If you want to rotate or regenerate the default self-signed pair manually, the helper script is still available:
163
+ ```bash
164
+ generate-lan-cert.sh
165
+ ```
166
+
167
+ When HTTPS is enabled:
168
+ - remote HTTP requests to `http://<laptop-ip>:8000` are redirected to HTTPS
169
+ - localhost HTTP requests still stay on plain `http://127.0.0.1:8000` so the laptop can keep using the non-TLS port
170
+
171
+ If TLS is terminated by a reverse proxy on the same machine instead, keep MetaList on loopback and let the proxy forward to it:
172
+ ```bash
173
+ METALIST_HOST=127.0.0.1 \
174
+ METALIST_PORT=8000 \
175
+ METALIST_FORWARDED_ALLOW_IPS=127.0.0.1,::1 \
176
+ metalist
177
+ ```
178
+
179
+ If you do not need the MCP sidecar remotely, disable it:
180
+ ```bash
181
+ MCP_AGENT_WEB_ENABLED=0 metalist
182
+ ```
183
+
184
+ ### MCP (Phase 1 Read-Only)
185
+ MCP is available automatically when you run:
186
+ ```bash
187
+ metalist
188
+ ```
189
+
190
+ `metalist` also auto-starts the agent web app sidecar and prints:
191
+ - `Agent web app: http://127.0.0.1:8765`
192
+ - The sidecar default MCP URL follows the resolved MetaList HTTP port for the current process.
193
+ - Use `--mcp-port` when you want multiple MetaList instances to auto-start sidecars without colliding on `8765`.
194
+ - On startup, local Ollama (`127.0.0.1`) is reset by default so a fresh runner is used.
195
+ - Sidecar Ollama auto-start uses `OLLAMA_CONTEXT_LENGTH=16384` by default.
196
+
197
+ Manual web mode (optional):
198
+ ```bash
199
+ metalist-mcp web --port 8765
200
+ ```
201
+ Then open `http://127.0.0.1:8765`.
202
+
203
+ Run direct MCP CLI calls:
204
+ ```bash
205
+ metalist-mcp cli tools/list
206
+ metalist-mcp cli tools/call health_check '{}'
207
+ ```
208
+
209
+ Compatibility shortcut (still works):
210
+ ```bash
211
+ python mcp_client.py tools/list
212
+ ```
213
+
214
+ Disable auto sidecar if needed:
215
+ ```bash
216
+ MCP_AGENT_WEB_ENABLED=0 metalist
217
+ ```
218
+
219
+ Control Ollama startup behavior:
220
+ ```bash
221
+ # disable Ollama reset-on-start (default is enabled)
222
+ MCP_AGENT_RESET_OLLAMA_ON_START=0 metalist
223
+
224
+ # override auto-start context length (default 16384)
225
+ MCP_AGENT_OLLAMA_CONTEXT_LENGTH=32768 metalist
226
+ ```
227
+
228
+ Optional: direct stdio transport (advanced/manual):
229
+ ```bash
230
+ python -m app.mcp
231
+ ```
232
+
233
+ Tool catalog and schemas:
234
+ - `docs/mcp_tools.md`
235
+
236
+ ### Legacy Import
237
+ `convert-from-legacy.py` replaces the SQLite database referenced by `app.config.DATABASE_URL` and imports notes from a legacy JSON export.
238
+
239
+ This is destructive. It deletes the existing DB file before rebuilding it.
240
+
241
+ Example usage:
242
+ ```bash
243
+ convert-from-legacy.py --input /path/to/legacy-export.json
244
+ ```
245
+
246
+ Target a namespaced database during import:
247
+ ```bash
248
+ convert-from-legacy.py --namespace work --input /path/to/legacy-export.json
249
+ ```
250
+
251
+ If `--namespace`, `--port`, `--https-port`, or `--mcp-port` are omitted, the import script prompts for them and saves the resulting launch profile inside the target namespace DB. That means a one-time import into `work` can immediately seed later shorthand launches like `metalist work`.
252
+
253
+ ### Publishing
254
+ For the real user-facing install flow:
255
+ ```bash
256
+ uvx metalist
257
+ # or:
258
+ uv tool install metalist
259
+ metalist
260
+ ```
261
+
262
+ This repo now packages itself under the PyPI distribution name `metalist`. Current releases support Python 3.10 through 3.13.
263
+
264
+ Recommended release path:
265
+ 1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
266
+ 2. Push a tag such as `v0.2.0`.
267
+ 3. After the GitHub Actions workflow completes, users can run it with `uvx metalist`, install it persistently with `uv tool install metalist`, or install it with `pip install metalist`.
268
+
269
+ If `--input` is omitted, a file picker opens (when `tkinter` is available).
270
+ Notes tagged with `@implies` are converted into ontology rules and are not imported as notes.
271
+
272
+ ### Run Tests
273
+
274
+ Python/unit test examples:
275
+ ```bash
276
+ source .venv/bin/activate
277
+ .venv/bin/pytest
278
+ node --test tests/unit/*.mjs
279
+ .venv/bin/python -c "from pathlib import Path; import main; main._run_startup_sanity_gates(repo_root=Path.cwd())"
280
+ ```
281
+
282
+ `TEST_MODE=1` and `POST /api2/test/reset` still exist for deterministic browser automation if we decide to add a new harness later, but Cypress is not part of the current workflow.
283
+
284
+ ### Diagrams
285
+ Render Mermaid diagrams to PNGs:
286
+ ```bash
287
+ npm run render-diagrams
288
+ ```
@@ -0,0 +1,259 @@
1
+ # MetaList
2
+
3
+ A minimalist single-user note-taking app focused on server-side rendering (SSR), fast in-memory tree operations, and efficient sync/diff updates.
4
+
5
+ ## Features
6
+ - Rich text editing (ContentEditable) with image support
7
+ - Drag-and-drop note reordering
8
+ - Real-time content saving
9
+ - Keyboard shortcuts (press `?` in the app)
10
+ - Linked-list ordering model for efficient reorders
11
+ - Optional password protection + encryption at rest (AES-GCM)
12
+ - Multi-tab search contexts with server-persisted scroll/search state (survives browser restarts)
13
+ - Manual namespace backups/restores to a user-selected backup folder with retention controls
14
+
15
+ ## Technology Stack
16
+
17
+ ### Backend
18
+ - FastAPI
19
+ - SQLite (via stdlib `sqlite3`) with a guard-aware wrapper (`SafeSession`)
20
+ - Mako templates for SSR
21
+
22
+ ### Frontend
23
+ - Vanilla JavaScript (no framework)
24
+ - HTML5 Drag and Drop API
25
+ - ContentEditable for rich text editing
26
+ - CSS custom properties for theming
27
+
28
+ ### Testing
29
+ - Python/unit tests plus manual regression passes
30
+
31
+ ## Architecture (High Level)
32
+ - Server renders the base page via Mako templates.
33
+ - The browser client drives interaction via `/api2` JSON endpoints.
34
+ - Notes are loaded/decrypted into an in-memory store at startup; a post-startup DB read guard prevents accidental runtime SELECTs.
35
+
36
+ ## Development
37
+
38
+ ### Setup
39
+ For a published one-off run with uv:
40
+ ```bash
41
+ uvx metalist
42
+ ```
43
+
44
+ For a persistent uv tool install:
45
+ ```bash
46
+ uv tool install metalist
47
+ metalist
48
+ ```
49
+
50
+ For pip, users can run `pip install metalist`. For a non-editable local install from this checkout, use `uv pip install .` or `pip install .` instead of the editable command below.
51
+
52
+ ```bash
53
+ python3 -m venv .venv
54
+ source .venv/bin/activate
55
+ uv pip install -e .[dev]
56
+
57
+ npm install
58
+ ```
59
+
60
+ ### Run
61
+ The installed entrypoint starts Uvicorn with the FastAPI app:
62
+ ```bash
63
+ metalist
64
+ ```
65
+ For source-checkout compatibility, `python main.py` still works. Plain `python main.py` is now an orchestration command: it restarts already-running namespaces from the current checkout, launches stopped namespaces, prints their URLs, and exits. Use `python main.py --namespace work` or `python main.py work` when you want one foreground namespace process.
66
+
67
+ `metalist` and explicit single-namespace source runs bind HTTP on `0.0.0.0:8000` by default, matching the old MetaList LAN-friendly behavior.
68
+ On first startup, MetaList also auto-generates a self-signed TLS pair at `~/MetaList/certs/metalist-cert.pem` and `~/MetaList/certs/metalist-key.pem`, then enables HTTPS on `0.0.0.0:8443`. If you already have real PEM files, point `METALIST_TLS_CERT` and `METALIST_TLS_KEY` at them instead. Set `METALIST_AUTO_GENERATE_TLS=0` only if you explicitly want HTTP-only startup.
69
+
70
+ Database selection:
71
+ - No explicit namespace on a single-namespace launch: `~/MetaList/namespaces/default/default.metalist.db`
72
+ - `--namespace work` or `METALIST_NAMESPACE=work`: `~/MetaList/namespaces/work/work.metalist.db`
73
+ - The related files DB is derived automatically, so `namespaces/work/work.metalist.db` uses `namespaces/work/work.metalist.files.db`
74
+ - Remembered launch ports are stored as plaintext metadata inside each namespace's main `*.metalist.db`
75
+ - Launch precedence is: explicit CLI flags > env vars > saved namespace profile; if a namespace has no saved profile, launch it once with explicit ports or configure ports from the UI
76
+ - Backups stay beside the namespace data under `~/MetaList/namespaces/work/backups/` and use one archive per snapshot with filenames like `work-<timestamp>.metalist-backup.tar.gz`
77
+ - The Backup Settings modal targets one user-selected backup folder and can include multiple namespaces in a single run
78
+ - Restoring `work` into `work` is the normal overwrite path; importing a backup under a different namespace name requires a new target namespace and rejects saved launch-port conflicts.
79
+
80
+ Useful env flags:
81
+ - `CRASH_SERVER_ON_FAIL=1` (default): fail-fast on validation errors
82
+ - `API_PREFIX=/api2`: override API prefix (client assumes `/api2` by default)
83
+ - `METALIST_NAMESPACE=work`: select `~/MetaList/namespaces/work/work.metalist.db`
84
+ - `METALIST_HOST=0.0.0.0` (default): bind the main app to a different interface such as `127.0.0.1`
85
+ - `METALIST_PORT=8000` (default): bind the main app to a different port
86
+ - `METALIST_HTTPS_PORT=8443`: override the HTTPS port when TLS is enabled
87
+ - `MCP_AGENT_WEB_PORT=8765` (default): bind the MCP sidecar web UI to a different port
88
+ - `METALIST_TLS_CERT=/path/to/fullchain.pem` + `METALIST_TLS_KEY=/path/to/privkey.pem`: override TLS paths
89
+ - `METALIST_AUTO_GENERATE_TLS=0`: disable automatic creation of the default self-signed TLS pair
90
+ - default TLS paths: `~/MetaList/certs/metalist-cert.pem` and `~/MetaList/certs/metalist-key.pem`
91
+ - `METALIST_FORWARDED_ALLOW_IPS=127.0.0.1,::1` (default): trust proxy headers only from those reverse-proxy IPs
92
+ - `MCP_AGENT_PUBLIC_ORIGIN=https://notes.example.com:8765`: public origin for the MCP sidecar redirect when it is exposed behind HTTPS or a separate hostname/port
93
+
94
+ ### Remote Access / HTTPS
95
+ Plain LAN or VPN HTTP works with a normal PyCharm run:
96
+ ```bash
97
+ metalist
98
+ ```
99
+ On a fresh machine, that first launch also creates the default TLS cert pair automatically. Then open either `http://<laptop-ip>:8000` or `https://<laptop-ip>:8443` from the other machine.
100
+
101
+ Namespaced launch example:
102
+ ```bash
103
+ metalist --namespace work --port 8001 --mcp-port 8766
104
+ ```
105
+ This starts a separate process backed by `~/MetaList/namespaces/work/work.metalist.db` on `http://127.0.0.1:8001`.
106
+ Its backup snapshots live under `~/MetaList/namespaces/work/backups/` with filenames like `work-<timestamp>.metalist-backup.tar.gz`. New backups are versioned `.tar.gz` workspace archives; legacy `.bak` backups remain restorable.
107
+
108
+ After you launch a namespace once with explicit ports, MetaList remembers them in that namespace's main DB, so later you can use the shorthand:
109
+ ```bash
110
+ metalist work
111
+ ```
112
+ and MetaList will reuse the saved HTTP / HTTPS / MCP sidecar ports for `work`. The same applies to the default namespace: `metalist` will reuse the saved default-namespace profile.
113
+
114
+ Equivalent explicit launch, if you want it:
115
+ ```bash
116
+ METALIST_HOST=0.0.0.0 \
117
+ METALIST_PORT=8000 \
118
+ METALIST_HTTPS_PORT=8443 \
119
+ metalist
120
+ ```
121
+ From the other machine, open `https://<laptop-ip>:8443`.
122
+
123
+ If you already have a real certificate and key, use the same dual-listener flow:
124
+ ```bash
125
+ METALIST_HOST=0.0.0.0 \
126
+ METALIST_PORT=8000 \
127
+ METALIST_HTTPS_PORT=8443 \
128
+ METALIST_TLS_CERT=/path/to/fullchain.pem \
129
+ METALIST_TLS_KEY=/path/to/privkey.pem \
130
+ metalist
131
+ ```
132
+
133
+ If you want to rotate or regenerate the default self-signed pair manually, the helper script is still available:
134
+ ```bash
135
+ generate-lan-cert.sh
136
+ ```
137
+
138
+ When HTTPS is enabled:
139
+ - remote HTTP requests to `http://<laptop-ip>:8000` are redirected to HTTPS
140
+ - localhost HTTP requests still stay on plain `http://127.0.0.1:8000` so the laptop can keep using the non-TLS port
141
+
142
+ If TLS is terminated by a reverse proxy on the same machine instead, keep MetaList on loopback and let the proxy forward to it:
143
+ ```bash
144
+ METALIST_HOST=127.0.0.1 \
145
+ METALIST_PORT=8000 \
146
+ METALIST_FORWARDED_ALLOW_IPS=127.0.0.1,::1 \
147
+ metalist
148
+ ```
149
+
150
+ If you do not need the MCP sidecar remotely, disable it:
151
+ ```bash
152
+ MCP_AGENT_WEB_ENABLED=0 metalist
153
+ ```
154
+
155
+ ### MCP (Phase 1 Read-Only)
156
+ MCP is available automatically when you run:
157
+ ```bash
158
+ metalist
159
+ ```
160
+
161
+ `metalist` also auto-starts the agent web app sidecar and prints:
162
+ - `Agent web app: http://127.0.0.1:8765`
163
+ - The sidecar default MCP URL follows the resolved MetaList HTTP port for the current process.
164
+ - Use `--mcp-port` when you want multiple MetaList instances to auto-start sidecars without colliding on `8765`.
165
+ - On startup, local Ollama (`127.0.0.1`) is reset by default so a fresh runner is used.
166
+ - Sidecar Ollama auto-start uses `OLLAMA_CONTEXT_LENGTH=16384` by default.
167
+
168
+ Manual web mode (optional):
169
+ ```bash
170
+ metalist-mcp web --port 8765
171
+ ```
172
+ Then open `http://127.0.0.1:8765`.
173
+
174
+ Run direct MCP CLI calls:
175
+ ```bash
176
+ metalist-mcp cli tools/list
177
+ metalist-mcp cli tools/call health_check '{}'
178
+ ```
179
+
180
+ Compatibility shortcut (still works):
181
+ ```bash
182
+ python mcp_client.py tools/list
183
+ ```
184
+
185
+ Disable auto sidecar if needed:
186
+ ```bash
187
+ MCP_AGENT_WEB_ENABLED=0 metalist
188
+ ```
189
+
190
+ Control Ollama startup behavior:
191
+ ```bash
192
+ # disable Ollama reset-on-start (default is enabled)
193
+ MCP_AGENT_RESET_OLLAMA_ON_START=0 metalist
194
+
195
+ # override auto-start context length (default 16384)
196
+ MCP_AGENT_OLLAMA_CONTEXT_LENGTH=32768 metalist
197
+ ```
198
+
199
+ Optional: direct stdio transport (advanced/manual):
200
+ ```bash
201
+ python -m app.mcp
202
+ ```
203
+
204
+ Tool catalog and schemas:
205
+ - `docs/mcp_tools.md`
206
+
207
+ ### Legacy Import
208
+ `convert-from-legacy.py` replaces the SQLite database referenced by `app.config.DATABASE_URL` and imports notes from a legacy JSON export.
209
+
210
+ This is destructive. It deletes the existing DB file before rebuilding it.
211
+
212
+ Example usage:
213
+ ```bash
214
+ convert-from-legacy.py --input /path/to/legacy-export.json
215
+ ```
216
+
217
+ Target a namespaced database during import:
218
+ ```bash
219
+ convert-from-legacy.py --namespace work --input /path/to/legacy-export.json
220
+ ```
221
+
222
+ If `--namespace`, `--port`, `--https-port`, or `--mcp-port` are omitted, the import script prompts for them and saves the resulting launch profile inside the target namespace DB. That means a one-time import into `work` can immediately seed later shorthand launches like `metalist work`.
223
+
224
+ ### Publishing
225
+ For the real user-facing install flow:
226
+ ```bash
227
+ uvx metalist
228
+ # or:
229
+ uv tool install metalist
230
+ metalist
231
+ ```
232
+
233
+ This repo now packages itself under the PyPI distribution name `metalist`. Current releases support Python 3.10 through 3.13.
234
+
235
+ Recommended release path:
236
+ 1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
237
+ 2. Push a tag such as `v0.2.0`.
238
+ 3. After the GitHub Actions workflow completes, users can run it with `uvx metalist`, install it persistently with `uv tool install metalist`, or install it with `pip install metalist`.
239
+
240
+ If `--input` is omitted, a file picker opens (when `tkinter` is available).
241
+ Notes tagged with `@implies` are converted into ontology rules and are not imported as notes.
242
+
243
+ ### Run Tests
244
+
245
+ Python/unit test examples:
246
+ ```bash
247
+ source .venv/bin/activate
248
+ .venv/bin/pytest
249
+ node --test tests/unit/*.mjs
250
+ .venv/bin/python -c "from pathlib import Path; import main; main._run_startup_sanity_gates(repo_root=Path.cwd())"
251
+ ```
252
+
253
+ `TEST_MODE=1` and `POST /api2/test/reset` still exist for deterministic browser automation if we decide to add a new harness later, but Cypress is not part of the current workflow.
254
+
255
+ ### Diagrams
256
+ Render Mermaid diagrams to PNGs:
257
+ ```bash
258
+ npm run render-diagrams
259
+ ```
File without changes
File without changes
@@ -0,0 +1,15 @@
1
+ from app.models.database import SafeSession
2
+ from app.db.session import get_request_session
3
+
4
+
5
+ def get_db():
6
+ request_session = get_request_session()
7
+ if request_session is not None:
8
+ yield request_session
9
+ return
10
+
11
+ db = SafeSession()
12
+ try:
13
+ yield db
14
+ finally:
15
+ db.close()
@@ -0,0 +1,32 @@
1
+ from fastapi import APIRouter
2
+ import logging
3
+
4
+ from app.api.transactions import transactional_route
5
+ from ..models.database import SafeSession
6
+ from app.db.session import begin_writer
7
+ from app.db.schema import initialize_schema, NOTES_TABLE
8
+
9
+ logger = logging.getLogger(__name__)
10
+ router = APIRouter()
11
+
12
+
13
+ @router.post("/use-dev-db")
14
+ @transactional_route
15
+ async def use_dev_db():
16
+ logger.info("Switching to dev DB")
17
+ SafeSession.use_memory_db()
18
+
19
+ with begin_writer() as connection:
20
+ initialize_schema(connection.raw_connection)
21
+ connection.execute(f"DELETE FROM {NOTES_TABLE}", ())
22
+ logger.info("Cleared all notes from test DB")
23
+
24
+ return {"status": "ok"}
25
+
26
+
27
+ @router.post("/use-file-db")
28
+ @transactional_route
29
+ async def use_file_db():
30
+ logger.info("Switching to file DB")
31
+ SafeSession.use_file_db()
32
+ return {"status": "ok"}