MetaList 0.12.0__tar.gz → 0.14.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 (551) hide show
  1. {metalist-0.12.0/metalist.egg-info → metalist-0.14.0}/PKG-INFO +19 -1
  2. {metalist-0.12.0 → metalist-0.14.0}/README.md +17 -0
  3. {metalist-0.12.0 → metalist-0.14.0}/app/api/middleware/auth.py +1 -0
  4. {metalist-0.12.0 → metalist-0.14.0}/app/api/note_requests.py +20 -0
  5. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/ai.py +4 -2
  6. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/auth.py +6 -0
  7. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/notes.py +67 -0
  8. {metalist-0.12.0 → metalist-0.14.0}/app/config.py +0 -1
  9. {metalist-0.12.0 → metalist-0.14.0}/app/encryption_audit.py +16 -9
  10. {metalist-0.12.0 → metalist-0.14.0}/app/exception_boundaries.py +8 -0
  11. {metalist-0.12.0 → metalist-0.14.0}/app/main.py +5 -3
  12. metalist-0.14.0/app/presentation/login_page.py +18 -0
  13. metalist-0.14.0/app/services/agent/action_log.py +59 -0
  14. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/agent_loop.py +16 -1
  15. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/context.py +18 -2
  16. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/help_catalog.py +1 -0
  17. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/prompts/agent.md +7 -0
  18. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/runtime.py +6 -2
  19. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-ai.md +1 -1
  20. metalist-0.14.0/app/services/agent/skills/help-dictation.md +94 -0
  21. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-formatting.md +6 -3
  22. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-menus.md +2 -0
  23. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-notes.md +1 -0
  24. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-privacy.md +8 -0
  25. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-references.md +4 -3
  26. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-releases.md +17 -0
  27. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-search.md +18 -0
  28. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-tags.md +3 -2
  29. {metalist-0.12.0 → metalist-0.14.0}/app/services/ai_chat.py +37 -0
  30. {metalist-0.12.0 → metalist-0.14.0}/app/services/ai_chat_stream.py +8 -1
  31. {metalist-0.12.0 → metalist-0.14.0}/app/services/backlink_index.py +1 -1
  32. {metalist-0.12.0 → metalist-0.14.0}/app/services/client_state_service.py +10 -0
  33. {metalist-0.12.0 → metalist-0.14.0}/app/services/content_formatting.py +11 -5
  34. metalist-0.14.0/app/services/dictation_cleanup.py +469 -0
  35. {metalist-0.12.0 → metalist-0.14.0}/app/services/embedded_references.py +28 -61
  36. metalist-0.14.0/app/services/file_text_preview.py +83 -0
  37. metalist-0.14.0/app/services/link_title_retry.py +169 -0
  38. {metalist-0.12.0 → metalist-0.14.0}/app/services/link_titles.py +389 -5
  39. {metalist-0.12.0 → metalist-0.14.0}/app/services/note_store.py +15 -6
  40. {metalist-0.12.0 → metalist-0.14.0}/app/services/reference_presentation.py +1 -1
  41. {metalist-0.12.0 → metalist-0.14.0}/app/services/search_index.py +69 -14
  42. {metalist-0.12.0 → metalist-0.14.0}/app/services/search_query.py +5 -1
  43. metalist-0.14.0/app/services/search_text.py +141 -0
  44. {metalist-0.12.0 → metalist-0.14.0}/app/services/tab_state.py +20 -6
  45. {metalist-0.12.0 → metalist-0.14.0}/app/services/tag_suggestions.py +104 -23
  46. metalist-0.14.0/app/startup_console.py +100 -0
  47. {metalist-0.12.0 → metalist-0.14.0}/app/static/config/agent-menu-actions.json +12 -0
  48. {metalist-0.12.0 → metalist-0.14.0}/app/static/config/command_palette_tags.json +8 -0
  49. {metalist-0.12.0 → metalist-0.14.0}/app/static/css/main.css +247 -183
  50. metalist-0.14.0/app/static/js/locked.js +36 -0
  51. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/main.js +0 -1
  52. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/ai-chat-panel-controller.js +4 -2
  53. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/proposal-menu.js +5 -0
  54. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/api-client.js +21 -0
  55. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/auth.js +162 -284
  56. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/command-palette-controller.js +78 -1
  57. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/endpoint-registry.js +15 -0
  58. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/preferences-store.js +38 -23
  59. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/config.js +4 -10
  60. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/ai-agent-settings-modal.js +4 -0
  61. metalist-0.14.0/app/static/js/modules/modals/dictation-settings-modal.js +130 -0
  62. metalist-0.14.0/app/static/js/modules/modals/link-title-retry-modal.js +308 -0
  63. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/ontology-modal.js +20 -0
  64. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/prioritize-modal.js +3 -0
  65. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/visual-cues-modal.js +1 -1
  66. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/events/input-events.js +14 -1
  67. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/events/keyboard-events.js +23 -1
  68. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/events/search-events.js +7 -0
  69. metalist-0.14.0/app/static/js/modules/mode-manager/services/dictation-note-paste.js +48 -0
  70. metalist-0.14.0/app/static/js/modules/mode-manager/services/dictation-paste-padding.js +21 -0
  71. metalist-0.14.0/app/static/js/modules/mode-manager/services/dictation-paste-service.js +245 -0
  72. metalist-0.14.0/app/static/js/modules/mode-manager/services/dropped-file-preview-service.js +47 -0
  73. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/reference-source-navigation-service.js +9 -1
  74. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-syntax-service.js +52 -0
  75. metalist-0.14.0/app/templates/_logo_mark.html +6 -0
  76. {metalist-0.12.0 → metalist-0.14.0}/app/templates/base.html +0 -5
  77. {metalist-0.12.0 → metalist-0.14.0}/app/templates/index.html +37 -51
  78. metalist-0.14.0/app/templates/locked.html +37 -0
  79. metalist-0.14.0/app/usecases/create_file_preview_child.py +68 -0
  80. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/search_comment_autofill.py +4 -3
  81. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/search_context_tags.py +4 -3
  82. {metalist-0.12.0 → metalist-0.14.0}/app/utils/text_utils.py +42 -0
  83. {metalist-0.12.0 → metalist-0.14.0}/app/version.py +1 -1
  84. {metalist-0.12.0 → metalist-0.14.0}/main.py +57 -25
  85. {metalist-0.12.0 → metalist-0.14.0/metalist.egg-info}/PKG-INFO +19 -1
  86. {metalist-0.12.0 → metalist-0.14.0}/metalist.egg-info/SOURCES.txt +15 -1
  87. {metalist-0.12.0 → metalist-0.14.0}/metalist.egg-info/requires.txt +1 -0
  88. {metalist-0.12.0 → metalist-0.14.0}/pyproject.toml +1 -0
  89. metalist-0.12.0/app/services/search_text.py +0 -65
  90. metalist-0.12.0/app/static/js/locked.js +0 -14
  91. metalist-0.12.0/app/static/video/login-startup.mp4 +0 -0
  92. metalist-0.12.0/app/templates/locked.html +0 -85
  93. {metalist-0.12.0 → metalist-0.14.0}/MANIFEST.in +0 -0
  94. {metalist-0.12.0 → metalist-0.14.0}/app/__init__.py +0 -0
  95. {metalist-0.12.0 → metalist-0.14.0}/app/api/__init__.py +0 -0
  96. {metalist-0.12.0 → metalist-0.14.0}/app/api/deps.py +0 -0
  97. {metalist-0.12.0 → metalist-0.14.0}/app/api/dev.py +0 -0
  98. {metalist-0.12.0 → metalist-0.14.0}/app/api/request_auth.py +0 -0
  99. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/app_updates.py +0 -0
  100. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/backups.py +0 -0
  101. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/files.py +0 -0
  102. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/ontology.py +0 -0
  103. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/reminders.py +0 -0
  104. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/remote_images.py +0 -0
  105. {metalist-0.12.0 → metalist-0.14.0}/app/api/routes/test.py +0 -0
  106. {metalist-0.12.0 → metalist-0.14.0}/app/api/transactions.py +0 -0
  107. {metalist-0.12.0 → metalist-0.14.0}/app/api/upload_limits.py +0 -0
  108. {metalist-0.12.0 → metalist-0.14.0}/app/data_directory.py +0 -0
  109. {metalist-0.12.0 → metalist-0.14.0}/app/db/__init__.py +0 -0
  110. {metalist-0.12.0 → metalist-0.14.0}/app/db/backup_settings_sql.py +0 -0
  111. {metalist-0.12.0 → metalist-0.14.0}/app/db/editable_files_migration.py +0 -0
  112. {metalist-0.12.0 → metalist-0.14.0}/app/db/engine.py +0 -0
  113. {metalist-0.12.0 → metalist-0.14.0}/app/db/file_schema.py +0 -0
  114. {metalist-0.12.0 → metalist-0.14.0}/app/db/file_session.py +0 -0
  115. {metalist-0.12.0 → metalist-0.14.0}/app/db/files_sql.py +0 -0
  116. {metalist-0.12.0 → metalist-0.14.0}/app/db/link_titles_sql.py +0 -0
  117. {metalist-0.12.0 → metalist-0.14.0}/app/db/live_recovery.py +0 -0
  118. {metalist-0.12.0 → metalist-0.14.0}/app/db/migrations.py +0 -0
  119. {metalist-0.12.0 → metalist-0.14.0}/app/db/notes_sql.py +0 -0
  120. {metalist-0.12.0 → metalist-0.14.0}/app/db/ontology_rules_sql.py +0 -0
  121. {metalist-0.12.0 → metalist-0.14.0}/app/db/reminders_sql.py +0 -0
  122. {metalist-0.12.0 → metalist-0.14.0}/app/db/retire_sounds.py +0 -0
  123. {metalist-0.12.0 → metalist-0.14.0}/app/db/schema.py +0 -0
  124. {metalist-0.12.0 → metalist-0.14.0}/app/db/search_history_sql.py +0 -0
  125. {metalist-0.12.0 → metalist-0.14.0}/app/db/session.py +0 -0
  126. {metalist-0.12.0 → metalist-0.14.0}/app/db/settings_sql.py +0 -0
  127. {metalist-0.12.0 → metalist-0.14.0}/app/db/tab_state_sql.py +0 -0
  128. {metalist-0.12.0 → metalist-0.14.0}/app/db/version.py +0 -0
  129. {metalist-0.12.0 → metalist-0.14.0}/app/https_proxy.py +0 -0
  130. {metalist-0.12.0 → metalist-0.14.0}/app/models/commands.py +0 -0
  131. {metalist-0.12.0 → metalist-0.14.0}/app/models/database.py +0 -0
  132. {metalist-0.12.0 → metalist-0.14.0}/app/models/entities.py +0 -0
  133. {metalist-0.12.0 → metalist-0.14.0}/app/models/enums.py +0 -0
  134. {metalist-0.12.0 → metalist-0.14.0}/app/models/linked_list.py +0 -0
  135. {metalist-0.12.0 → metalist-0.14.0}/app/models/list_operations.py +0 -0
  136. {metalist-0.12.0 → metalist-0.14.0}/app/models/list_traversal.py +0 -0
  137. {metalist-0.12.0 → metalist-0.14.0}/app/models/note_crud.py +0 -0
  138. {metalist-0.12.0 → metalist-0.14.0}/app/models/utils.py +0 -0
  139. {metalist-0.12.0 → metalist-0.14.0}/app/network_settings.py +0 -0
  140. {metalist-0.12.0 → metalist-0.14.0}/app/presentation/__init__.py +0 -0
  141. {metalist-0.12.0 → metalist-0.14.0}/app/presentation/render/__init__.py +0 -0
  142. {metalist-0.12.0 → metalist-0.14.0}/app/presentation/render/note_renderer.py +0 -0
  143. {metalist-0.12.0 → metalist-0.14.0}/app/presentation/templates.py +0 -0
  144. {metalist-0.12.0 → metalist-0.14.0}/app/security/authenticated_logging.py +0 -0
  145. {metalist-0.12.0 → metalist-0.14.0}/app/security/encryption.py +0 -0
  146. {metalist-0.12.0 → metalist-0.14.0}/app/security/http_error_diagnostics.py +0 -0
  147. {metalist-0.12.0 → metalist-0.14.0}/app/security/http_headers.py +0 -0
  148. {metalist-0.12.0 → metalist-0.14.0}/app/security/note_html.py +0 -0
  149. {metalist-0.12.0 → metalist-0.14.0}/app/security/request_boundary.py +0 -0
  150. {metalist-0.12.0 → metalist-0.14.0}/app/security/request_hosts.py +0 -0
  151. {metalist-0.12.0 → metalist-0.14.0}/app/security/sensitive_cache.py +0 -0
  152. {metalist-0.12.0 → metalist-0.14.0}/app/security/sensitive_logging.py +0 -0
  153. {metalist-0.12.0 → metalist-0.14.0}/app/security/shell_execution.py +0 -0
  154. {metalist-0.12.0 → metalist-0.14.0}/app/security/validation_errors.py +0 -0
  155. {metalist-0.12.0 → metalist-0.14.0}/app/server_runtime.py +0 -0
  156. {metalist-0.12.0 → metalist-0.14.0}/app/services/__init__.py +0 -0
  157. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/__init__.py +0 -0
  158. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/agent_tools.py +0 -0
  159. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/citation_tokens.py +0 -0
  160. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/cloud_privacy.py +0 -0
  161. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/evidence_serialization.py +0 -0
  162. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/execution_errors.py +0 -0
  163. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/failure_explanations.py +0 -0
  164. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/history.py +0 -0
  165. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/inference.py +0 -0
  166. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/investigation.py +0 -0
  167. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/judging.py +0 -0
  168. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/menu_actions.py +0 -0
  169. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/model_policy.py +0 -0
  170. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/note_aliases.py +0 -0
  171. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/openai_cost_tracking.py +0 -0
  172. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/openai_inference.py +0 -0
  173. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/prompt_settings.py +0 -0
  174. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/prompts/__init__.py +0 -0
  175. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/prompts/final-response.md +0 -0
  176. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/prompts/system.md +0 -0
  177. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/release_notes.py +0 -0
  178. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/retrieval_settings.py +0 -0
  179. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/scope.py +0 -0
  180. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skill_settings.py +0 -0
  181. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/__init__.py +0 -0
  182. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-data.md +0 -0
  183. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/help-reminders.md +0 -0
  184. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/staged-summary.md +0 -0
  185. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/tag-proposals.md +0 -0
  186. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/skills/web-browsing.md +0 -0
  187. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/staged_summary.py +0 -0
  188. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/structured_inference.py +0 -0
  189. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/tagging.py +0 -0
  190. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/tagging_run.py +0 -0
  191. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/token_estimation.py +0 -0
  192. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/tool_calling.py +0 -0
  193. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/trace.py +0 -0
  194. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/web_actions.py +0 -0
  195. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/web_capabilities.py +0 -0
  196. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/web_evidence.py +0 -0
  197. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/web_fetch.py +0 -0
  198. {metalist-0.12.0 → metalist-0.14.0}/app/services/agent/web_settings.py +0 -0
  199. {metalist-0.12.0 → metalist-0.14.0}/app/services/ai_chat_rendering.py +0 -0
  200. {metalist-0.12.0 → metalist-0.14.0}/app/services/app_update_worker.py +0 -0
  201. {metalist-0.12.0 → metalist-0.14.0}/app/services/app_updates.py +0 -0
  202. {metalist-0.12.0 → metalist-0.14.0}/app/services/auth.py +0 -0
  203. {metalist-0.12.0 → metalist-0.14.0}/app/services/auth_cache_state.py +0 -0
  204. {metalist-0.12.0 → metalist-0.14.0}/app/services/auth_service.py +0 -0
  205. {metalist-0.12.0 → metalist-0.14.0}/app/services/backlinks.py +0 -0
  206. {metalist-0.12.0 → metalist-0.14.0}/app/services/backup_service.py +0 -0
  207. {metalist-0.12.0 → metalist-0.14.0}/app/services/backup_settings_service.py +0 -0
  208. {metalist-0.12.0 → metalist-0.14.0}/app/services/bulk_operation.py +0 -0
  209. {metalist-0.12.0 → metalist-0.14.0}/app/services/content_cache.py +0 -0
  210. {metalist-0.12.0 → metalist-0.14.0}/app/services/diagnostics.py +0 -0
  211. {metalist-0.12.0 → metalist-0.14.0}/app/services/encryption.py +0 -0
  212. {metalist-0.12.0 → metalist-0.14.0}/app/services/exception_capture.py +0 -0
  213. {metalist-0.12.0 → metalist-0.14.0}/app/services/file_edit_sessions.py +0 -0
  214. {metalist-0.12.0 → metalist-0.14.0}/app/services/file_registry.py +0 -0
  215. {metalist-0.12.0 → metalist-0.14.0}/app/services/file_storage.py +0 -0
  216. {metalist-0.12.0 → metalist-0.14.0}/app/services/footnote_layout.py +0 -0
  217. {metalist-0.12.0 → metalist-0.14.0}/app/services/footnote_rendering.py +0 -0
  218. {metalist-0.12.0 → metalist-0.14.0}/app/services/hierarchy.py +0 -0
  219. {metalist-0.12.0 → metalist-0.14.0}/app/services/html_export.py +0 -0
  220. {metalist-0.12.0 → metalist-0.14.0}/app/services/html_unformatting.py +0 -0
  221. {metalist-0.12.0 → metalist-0.14.0}/app/services/hydration_state.py +0 -0
  222. {metalist-0.12.0 → metalist-0.14.0}/app/services/image_size_formatting.py +0 -0
  223. {metalist-0.12.0 → metalist-0.14.0}/app/services/inline_image_dimensions.py +0 -0
  224. {metalist-0.12.0 → metalist-0.14.0}/app/services/inline_image_occurrences.py +0 -0
  225. {metalist-0.12.0 → metalist-0.14.0}/app/services/input_errors.py +0 -0
  226. {metalist-0.12.0 → metalist-0.14.0}/app/services/integrity.py +0 -0
  227. {metalist-0.12.0 → metalist-0.14.0}/app/services/latex_rendering.py +0 -0
  228. {metalist-0.12.0 → metalist-0.14.0}/app/services/login_rate_limit.py +0 -0
  229. {metalist-0.12.0 → metalist-0.14.0}/app/services/maintenance_mode.py +0 -0
  230. {metalist-0.12.0 → metalist-0.14.0}/app/services/markdown_rendering.py +0 -0
  231. {metalist-0.12.0 → metalist-0.14.0}/app/services/namespace_deletion_jobs.py +0 -0
  232. {metalist-0.12.0 → metalist-0.14.0}/app/services/namespace_deletion_worker.py +0 -0
  233. {metalist-0.12.0 → metalist-0.14.0}/app/services/namespace_rename_jobs.py +0 -0
  234. {metalist-0.12.0 → metalist-0.14.0}/app/services/namespace_rename_worker.py +0 -0
  235. {metalist-0.12.0 → metalist-0.14.0}/app/services/namespace_runtime_guard.py +0 -0
  236. {metalist-0.12.0 → metalist-0.14.0}/app/services/namespace_switcher.py +0 -0
  237. {metalist-0.12.0 → metalist-0.14.0}/app/services/note_fullscreen.py +0 -0
  238. {metalist-0.12.0 → metalist-0.14.0}/app/services/note_image_tags.py +0 -0
  239. {metalist-0.12.0 → metalist-0.14.0}/app/services/note_ordering.py +0 -0
  240. {metalist-0.12.0 → metalist-0.14.0}/app/services/ontology_rules_store.py +0 -0
  241. {metalist-0.12.0 → metalist-0.14.0}/app/services/openai_credentials.py +0 -0
  242. {metalist-0.12.0 → metalist-0.14.0}/app/services/password_note_fields.py +0 -0
  243. {metalist-0.12.0 → metalist-0.14.0}/app/services/public_http.py +0 -0
  244. {metalist-0.12.0 → metalist-0.14.0}/app/services/reminders.py +0 -0
  245. {metalist-0.12.0 → metalist-0.14.0}/app/services/remote_image_proxy.py +0 -0
  246. {metalist-0.12.0 → metalist-0.14.0}/app/services/request_recovery.py +0 -0
  247. {metalist-0.12.0 → metalist-0.14.0}/app/services/resource_limits.py +0 -0
  248. {metalist-0.12.0 → metalist-0.14.0}/app/services/root_sorting.py +0 -0
  249. {metalist-0.12.0 → metalist-0.14.0}/app/services/runtime_generation.py +0 -0
  250. {metalist-0.12.0 → metalist-0.14.0}/app/services/runtime_hardening.py +0 -0
  251. {metalist-0.12.0 → metalist-0.14.0}/app/services/runtime_lock.py +0 -0
  252. {metalist-0.12.0 → metalist-0.14.0}/app/services/search_history.py +0 -0
  253. {metalist-0.12.0 → metalist-0.14.0}/app/services/search_history_storage.py +0 -0
  254. {metalist-0.12.0 → metalist-0.14.0}/app/services/selected_text_tag.py +0 -0
  255. {metalist-0.12.0 → metalist-0.14.0}/app/services/self_update.py +0 -0
  256. {metalist-0.12.0 → metalist-0.14.0}/app/services/session_timeout_service.py +0 -0
  257. {metalist-0.12.0 → metalist-0.14.0}/app/services/shell_session_service.py +0 -0
  258. {metalist-0.12.0 → metalist-0.14.0}/app/services/snapshot.py +0 -0
  259. {metalist-0.12.0 → metalist-0.14.0}/app/services/store.py +0 -0
  260. {metalist-0.12.0 → metalist-0.14.0}/app/services/structured_note_renderers.py +0 -0
  261. {metalist-0.12.0 → metalist-0.14.0}/app/services/sync.py +0 -0
  262. {metalist-0.12.0 → metalist-0.14.0}/app/services/sync_state.py +0 -0
  263. {metalist-0.12.0 → metalist-0.14.0}/app/services/tag_case.py +0 -0
  264. {metalist-0.12.0 → metalist-0.14.0}/app/services/tag_ontology.py +0 -0
  265. {metalist-0.12.0 → metalist-0.14.0}/app/services/tag_rename.py +0 -0
  266. {metalist-0.12.0 → metalist-0.14.0}/app/services/tag_term_matching.py +0 -0
  267. {metalist-0.12.0 → metalist-0.14.0}/app/services/test_reset.py +0 -0
  268. {metalist-0.12.0 → metalist-0.14.0}/app/services/tokens.py +0 -0
  269. {metalist-0.12.0 → metalist-0.14.0}/app/services/undo_state.py +0 -0
  270. {metalist-0.12.0 → metalist-0.14.0}/app/services/update_backups.py +0 -0
  271. {metalist-0.12.0 → metalist-0.14.0}/app/services/update_installer.py +0 -0
  272. {metalist-0.12.0 → metalist-0.14.0}/app/services/update_preflight.py +0 -0
  273. {metalist-0.12.0 → metalist-0.14.0}/app/services/view_cache.py +0 -0
  274. {metalist-0.12.0 → metalist-0.14.0}/app/services/view_diff.py +0 -0
  275. {metalist-0.12.0 → metalist-0.14.0}/app/services/view_state.py +0 -0
  276. {metalist-0.12.0 → metalist-0.14.0}/app/services/windows_process_control.py +0 -0
  277. {metalist-0.12.0 → metalist-0.14.0}/app/startup_environment.py +0 -0
  278. {metalist-0.12.0 → metalist-0.14.0}/app/startup_js_sanity.py +0 -0
  279. {metalist-0.12.0 → metalist-0.14.0}/app/startup_sanity.py +0 -0
  280. {metalist-0.12.0 → metalist-0.14.0}/app/startup_sanity_config.py +0 -0
  281. {metalist-0.12.0 → metalist-0.14.0}/app/static/css/floating-notes.css +0 -0
  282. {metalist-0.12.0 → metalist-0.14.0}/app/static/css/forms.css +0 -0
  283. {metalist-0.12.0 → metalist-0.14.0}/app/static/img/favicon.ico +0 -0
  284. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/activity-tracker.js +0 -0
  285. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/agent-menu-actions.js +0 -0
  286. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/agent-retrieval-settings.js +0 -0
  287. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/agent-web-settings.js +0 -0
  288. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/ai-agent-debug-view.js +0 -0
  289. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/ai-chat-api.js +0 -0
  290. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/ai-chat-message-placement.js +0 -0
  291. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/ai-chat-panel-service.js +0 -0
  292. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/ai-thinking-level-service.js +0 -0
  293. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/bulk-elapsed-clock.js +0 -0
  294. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/bulk-proposal-ui.js +0 -0
  295. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/bulk-scope-question.js +0 -0
  296. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/cloud-privacy-policy.js +0 -0
  297. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/confirmation-card.js +0 -0
  298. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/confirmation-question.js +0 -0
  299. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/ai-chat/summary-batch-preview.js +0 -0
  300. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/api-error-diagnostics.js +0 -0
  301. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/api-failure-classification-service.js +0 -0
  302. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/app-update-service.js +0 -0
  303. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/application-state.js +0 -0
  304. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/async-result.js +0 -0
  305. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/client-state-api.js +0 -0
  306. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/client-state-migration.js +0 -0
  307. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/activation-auth-policy.js +0 -0
  308. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/backup-command-availability.js +0 -0
  309. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/click-activation-service.js +0 -0
  310. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/note-layout-preferences.js +0 -0
  311. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/tag-config-loader.js +0 -0
  312. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/command-palette/usage-store.js +0 -0
  313. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/connectivity-monitor.js +0 -0
  314. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/context-menu/context-menu-registry.js +0 -0
  315. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/context-menu/context-menu-service.js +0 -0
  316. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/context-menu/context-menu-target-service.js +0 -0
  317. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/context-menu/input-caret-service.js +0 -0
  318. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/disconnect-editing-state-service.js +0 -0
  319. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/dom-utils-fixed.js +0 -0
  320. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/dom-utils.js +0 -0
  321. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/editor-commands.js +0 -0
  322. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/editor-selection.js +0 -0
  323. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/editor-toolbar.js +0 -0
  324. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/elapsed-time.js +0 -0
  325. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/error-handler.js +0 -0
  326. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/error-overlay.js +0 -0
  327. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/excalidraw/excalidraw-actions.js +0 -0
  328. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/excalidraw/excalidraw-autosave.js +0 -0
  329. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/excalidraw/excalidraw-editor-service.js +0 -0
  330. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/excalidraw/excalidraw-editor-state.js +0 -0
  331. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/excalidraw/excalidraw-loader.js +0 -0
  332. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/excalidraw/excalidraw-preview-service.js +0 -0
  333. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/excalidraw/excalidraw-scene.js +0 -0
  334. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/expected-errors.js +0 -0
  335. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/location-flags.js +0 -0
  336. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/login-namespace-picker.js +0 -0
  337. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/maintenance.js +0 -0
  338. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/alphabetize-root-notes-modal.js +0 -0
  339. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/backup-restore-modal.js +0 -0
  340. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/backup-result-modal.js +0 -0
  341. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/backup-retention-modal.js +0 -0
  342. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/backup-settings-modal.js +0 -0
  343. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/base-modal.js +0 -0
  344. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/confirmation-modal.js +0 -0
  345. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/delete-namespace-modal.js +0 -0
  346. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/delete-namespace-validation.js +0 -0
  347. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/help-modal.js +0 -0
  348. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/namespace-loading-page.js +0 -0
  349. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/namespace-modals.js +0 -0
  350. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/namespace-ports-profile.js +0 -0
  351. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/namespace-rename-validation.js +0 -0
  352. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/note-layout-appearance-modal.js +0 -0
  353. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/password-modal.js +0 -0
  354. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/random-password-modal.js +0 -0
  355. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/reminder-modal.js +0 -0
  356. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/reset-updated-at-modal.js +0 -0
  357. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/search-suggestion-statistics-modal.js +0 -0
  358. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/session-timeout-modal.js +0 -0
  359. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/modals/version-info-modal.js +0 -0
  360. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/actions/content-actions.js +0 -0
  361. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/actions/history-actions.js +0 -0
  362. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/actions/note-actions.js +0 -0
  363. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/actions/search-actions.js +0 -0
  364. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/actions/selection-actions.js +0 -0
  365. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/actions/ui-actions.js +0 -0
  366. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/events/context-menu-events.js +0 -0
  367. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/events/focus-events.js +0 -0
  368. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/events/inactivity-events.js +0 -0
  369. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/events/mouse-events.js +0 -0
  370. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/mode-context.js +0 -0
  371. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/mode-logger.js +0 -0
  372. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/mode-manager-controller.js +0 -0
  373. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/add-style-service.js +0 -0
  374. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/animated-scroll-service.js +0 -0
  375. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/backlinks-navigation-service.js +0 -0
  376. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/backlinks-panel-service.js +0 -0
  377. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/clipboard-shortcut-policy-service.js +0 -0
  378. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/collapse-affordance-service.js +0 -0
  379. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/collapse-editing-policy-service.js +0 -0
  380. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/command-gate-service.js +0 -0
  381. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/context-menu-target-service.js +0 -0
  382. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/deselect-selection-state-service.js +0 -0
  383. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/differential-view-service.js +0 -0
  384. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/edit-session-collapse-policy-service.js +0 -0
  385. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/edit-session-collapse-service.js +0 -0
  386. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/embedded-image-service.js +0 -0
  387. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/file-drop-policy-service.js +0 -0
  388. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/file-image-preview-service.js +0 -0
  389. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/file-reference-service.js +0 -0
  390. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/filtered-refresh-selection-service.js +0 -0
  391. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/floating-note-dom.js +0 -0
  392. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/floating-note-layout.js +0 -0
  393. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/floating-note-service.js +0 -0
  394. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/footnote-navigation-service.js +0 -0
  395. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/history-selection-policy-service.js +0 -0
  396. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/history-shortcut-policy-service.js +0 -0
  397. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/html-paste-sanitizer-service.js +0 -0
  398. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/image-context-menu-action-service.js +0 -0
  399. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/image-file-insert-choice-modal-service.js +0 -0
  400. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/infinite-scroll-service.js +0 -0
  401. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/link-context-menu-action-service.js +0 -0
  402. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/link-title-prefetch-service.js +0 -0
  403. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/markdown-render-service.js +0 -0
  404. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/mermaid-render-service.js +0 -0
  405. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-click-target-service.js +0 -0
  406. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-clipboard-write-service.js +0 -0
  407. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-collapse-animation-service.js +0 -0
  408. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-context-menu-action-service.js +0 -0
  409. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-delete-shortcut-policy-service.js +0 -0
  410. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-drag-indicator-service.js +0 -0
  411. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-drag-service.js +0 -0
  412. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-fullscreen-service.js +0 -0
  413. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-reposition-animation-service.js +0 -0
  414. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-split-service.js +0 -0
  415. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/note-timestamp-hover-service.js +0 -0
  416. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/password-clipboard-service.js +0 -0
  417. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/polling-service.js +0 -0
  418. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/remote-image-proxy-service.js +0 -0
  419. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/remove-formatting-service.js +0 -0
  420. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/root-date-separator-service.js +0 -0
  421. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/root-note-creation-service.js +0 -0
  422. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/root-sort-indicator-service.js +0 -0
  423. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/root-sort-service.js +0 -0
  424. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/scroll-anchor-service.js +0 -0
  425. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/scroll-restoration-service.js +0 -0
  426. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/scroll-to-top-service.js +0 -0
  427. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-contexts-overlay-service.js +0 -0
  428. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-debounce-service.js +0 -0
  429. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-input-service.js +0 -0
  430. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-interaction-service.js +0 -0
  431. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-redaction-reveal-service.js +0 -0
  432. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-suggestion-statistics-service.js +0 -0
  433. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-suggestion-window-labels-service.js +0 -0
  434. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-suggestion-windows-service.js +0 -0
  435. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/search-suggestions-service.js +0 -0
  436. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/selected-formatting-removal-service.js +0 -0
  437. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/selected-text-tag-service.js +0 -0
  438. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/shell-output-service.js +0 -0
  439. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tab-dom-cache-service.js +0 -0
  440. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tab-drag-service.js +0 -0
  441. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tab-duplication-service.js +0 -0
  442. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tab-state-service.js +0 -0
  443. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tag-bar-service.js +0 -0
  444. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tag-input-selection-service.js +0 -0
  445. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tag-proposal-service.js +0 -0
  446. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tag-suggestions-service.js +0 -0
  447. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/tag-syntax-service.js +0 -0
  448. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/todo-toggle-editing-service.js +0 -0
  449. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/untagged-view-indicator-service.js +0 -0
  450. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/view-mode-search-shortcut-service.js +0 -0
  451. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/mode-manager/services/viewport-hold-service.js +0 -0
  452. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/note-html-sanitizer.js +0 -0
  453. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/password-generator.js +0 -0
  454. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/password-operation-response.js +0 -0
  455. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/password-policy.js +0 -0
  456. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/password-strength.js +0 -0
  457. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/reminder-store.js +0 -0
  458. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/reminder-surface-service.js +0 -0
  459. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/selection-markers.js +0 -0
  460. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/session-auth.js +0 -0
  461. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/tag-token.js +0 -0
  462. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/modules/uuid.js +0 -0
  463. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/namespace-deleted.js +0 -0
  464. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/namespace-renamed.js +0 -0
  465. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/dompurify-3.4.16.LICENSE.txt +0 -0
  466. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/dompurify-3.4.16.min.js +0 -0
  467. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/excalidraw.css +0 -0
  468. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Assistant/Assistant-Bold.woff2 +0 -0
  469. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Assistant/Assistant-Medium.woff2 +0 -0
  470. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Assistant/Assistant-Regular.woff2 +0 -0
  471. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Assistant/Assistant-SemiBold.woff2 +0 -0
  472. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Cascadia/CascadiaCode-Regular.woff2 +0 -0
  473. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2 +0 -0
  474. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2 +0 -0
  475. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2 +0 -0
  476. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2 +0 -0
  477. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2 +0 -0
  478. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2 +0 -0
  479. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2 +0 -0
  480. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2 +0 -0
  481. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2 +0 -0
  482. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2 +0 -0
  483. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2 +0 -0
  484. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2 +0 -0
  485. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2 +0 -0
  486. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2 +0 -0
  487. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2 +0 -0
  488. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2 +0 -0
  489. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2 +0 -0
  490. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2 +0 -0
  491. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1-assets/fonts/Virgil/Virgil-Regular.woff2 +0 -0
  492. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1.LICENSE.txt +0 -0
  493. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/excalidraw-0.18.1.min.js +0 -0
  494. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/markdown-it-14.3.2.LICENSE.txt +0 -0
  495. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/markdown-it-14.3.2.min.js +0 -0
  496. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/mermaid-11.16.1.LICENSE.txt +0 -0
  497. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/mermaid-11.16.1.min.js +0 -0
  498. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/zxcvbn-4.4.2.LICENSE.txt +0 -0
  499. {metalist-0.12.0 → metalist-0.14.0}/app/static/js/vendor/zxcvbn-4.4.2.js +0 -0
  500. {metalist-0.12.0 → metalist-0.14.0}/app/static/note-html-policy.json +0 -0
  501. {metalist-0.12.0 → metalist-0.14.0}/app/templates/maintenance.html +0 -0
  502. {metalist-0.12.0 → metalist-0.14.0}/app/templates/namespace_deleted.html +0 -0
  503. {metalist-0.12.0 → metalist-0.14.0}/app/templates/namespace_renamed.html +0 -0
  504. {metalist-0.12.0 → metalist-0.14.0}/app/templates/notes_list.html +0 -0
  505. {metalist-0.12.0 → metalist-0.14.0}/app/upload_limits.py +0 -0
  506. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/__init__.py +0 -0
  507. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/add_selected_text_tag.py +0 -0
  508. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/alphabetize_root_notes.py +0 -0
  509. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/base.py +0 -0
  510. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/bulk_tag_proposals.py +0 -0
  511. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/collapse.py +0 -0
  512. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/copy_note.py +0 -0
  513. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/create_child.py +0 -0
  514. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/create_note.py +0 -0
  515. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/create_sibling.py +0 -0
  516. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/delete_subtree.py +0 -0
  517. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/delete_tag.py +0 -0
  518. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/expand.py +0 -0
  519. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/file_edit_session.py +0 -0
  520. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/indent.py +0 -0
  521. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/lock.py +0 -0
  522. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/move.py +0 -0
  523. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/move_to_top.py +0 -0
  524. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/outdent.py +0 -0
  525. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/paste_child.py +0 -0
  526. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/paste_sibling.py +0 -0
  527. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/prefetch_link_titles.py +0 -0
  528. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/prioritize.py +0 -0
  529. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/redo.py +0 -0
  530. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/rename_tag.py +0 -0
  531. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/reset_updated_at.py +0 -0
  532. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/resize_image.py +0 -0
  533. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/run_shell.py +0 -0
  534. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/set_collapse_bulk.py +0 -0
  535. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/set_collapse_in_context.py +0 -0
  536. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/split_note.py +0 -0
  537. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/tag_proposals.py +0 -0
  538. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/toggle_reference_mode.py +0 -0
  539. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/toggle_todo_done.py +0 -0
  540. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/undo.py +0 -0
  541. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/unformat_content.py +0 -0
  542. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/update_content.py +0 -0
  543. {metalist-0.12.0 → metalist-0.14.0}/app/usecases/view.py +0 -0
  544. {metalist-0.12.0 → metalist-0.14.0}/app/utils/__init__.py +0 -0
  545. {metalist-0.12.0 → metalist-0.14.0}/app/utils/encryption.py +0 -0
  546. {metalist-0.12.0 → metalist-0.14.0}/convert-from-legacy.py +0 -0
  547. {metalist-0.12.0 → metalist-0.14.0}/metalist.egg-info/dependency_links.txt +0 -0
  548. {metalist-0.12.0 → metalist-0.14.0}/metalist.egg-info/entry_points.txt +0 -0
  549. {metalist-0.12.0 → metalist-0.14.0}/metalist.egg-info/top_level.txt +0 -0
  550. {metalist-0.12.0 → metalist-0.14.0}/scripts/generate-lan-cert.sh +0 -0
  551. {metalist-0.12.0 → metalist-0.14.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metalist
3
- Version: 0.12.0
3
+ Version: 0.14.0
4
4
  Summary: A minimalist single-user note-taking app with SSR, fast in-memory tree operations, and efficient sync.
5
5
  Project-URL: Homepage, https://github.com/evolvingstuff/metalist
6
6
  Project-URL: Repository, https://github.com/evolvingstuff/metalist
@@ -23,6 +23,7 @@ Requires-Dist: pydantic==2.13.4
23
23
  Requires-Dist: pypdf==6.19.0
24
24
  Requires-Dist: python-dotenv==1.2.2
25
25
  Requires-Dist: python-multipart==0.0.32
26
+ Requires-Dist: rich==14.3.4
26
27
  Requires-Dist: starlette==1.3.1
27
28
  Requires-Dist: tqdm==4.70.0
28
29
  Requires-Dist: tree-sitter==0.25.2
@@ -49,6 +50,23 @@ A minimalist single-user note-taking app focused on server-side rendering (SSR),
49
50
  - Multi-tab search contexts with server-persisted scroll/search state (survives browser restarts)
50
51
  - Manual namespace backups/restores to a user-selected backup folder with retention controls
51
52
 
53
+ ## Changes in 0.14.0
54
+
55
+ - A new login screen: one dark screen with the MetaList logo. The namespace, password and OK fade in together; once the password is accepted, the loading progress slides in with the current step and the seconds elapsed. When the first login after an update backs up and upgrades the namespace, a note under OK says so. The Session locked page has the same look, and there is no white flash between them.
56
+ - Web link titles: links to Reddit (including share links), YouTube, Vimeo, TikTok, Spotify and SoundCloud get their real titles. Lookups are paced per site, so a note full of links no longer trips a site's rate limit. Login, consent and site-name-only titles ("Sign in", "Reddit") show the link instead. The new command palette action Retry failed link titles asks every failed link again, with a progress dialog.
57
+ - Quoted search also matches link titles and the URLs hidden behind link labels, and the AI sees those URLs too. Pasting into a quoted search inserts the text as copied.
58
+ - `[[note id]]` is always a link, even in a note with a `[[ ]]` formatting tag.
59
+ - The startup output in the terminal is easier to read: the version, a check mark per check, and each namespace's URLs lined up.
60
+ - Fixed: clicking the AI chat's $ or eye button twice quickly crashed with "Redundant state change".
61
+
62
+ ## Changes in 0.13.0
63
+
64
+ - Dictation: text from speech-to-text tools such as Superwhisper, pasted into the search bar or any tag field, becomes your existing tags ("neural network" gives `neural-network`). Say "quote … end quote" for text, "minus" to exclude, "at" before meta tags such as `@todo`. In a note, the words after "start tags" go to its tag bar. The phrases are set in Dictation Settings, and one undo restores what was pasted.
65
+ - A quoted search with a space at its edge matches whole words: `" fat"` no longer finds "father".
66
+ - The AI keeps a record of what it did for each answer (notes read, searches, web pages opened), so questions like "did you search the web for that?" are answered from what actually happened.
67
+ - Dropping a `.txt`, `.md`, `.csv` or `.json` file stores it as before and adds its text as a child note, shown as Markdown, a table or formatted JSON. File pills show the extension (`.MD`, `.CSV`, …), and hovering a pill says that clicking downloads the file.
68
+ - Typing one letter in the tag bar now narrows the suggestions you were already shown instead of reordering them, so the tag you want is in the top five far more often.
69
+
52
70
  ## Changes in 0.12.0
53
71
 
54
72
  - AI chat is now a tool-using agent: in one answer it can look up MetaList help, read and search the notes in your view, open web pages, and open menus, instead of picking a single route up front. Answers cite notes and web pages with clickable references, including each item listed from a web page.
@@ -12,6 +12,23 @@ A minimalist single-user note-taking app focused on server-side rendering (SSR),
12
12
  - Multi-tab search contexts with server-persisted scroll/search state (survives browser restarts)
13
13
  - Manual namespace backups/restores to a user-selected backup folder with retention controls
14
14
 
15
+ ## Changes in 0.14.0
16
+
17
+ - A new login screen: one dark screen with the MetaList logo. The namespace, password and OK fade in together; once the password is accepted, the loading progress slides in with the current step and the seconds elapsed. When the first login after an update backs up and upgrades the namespace, a note under OK says so. The Session locked page has the same look, and there is no white flash between them.
18
+ - Web link titles: links to Reddit (including share links), YouTube, Vimeo, TikTok, Spotify and SoundCloud get their real titles. Lookups are paced per site, so a note full of links no longer trips a site's rate limit. Login, consent and site-name-only titles ("Sign in", "Reddit") show the link instead. The new command palette action Retry failed link titles asks every failed link again, with a progress dialog.
19
+ - Quoted search also matches link titles and the URLs hidden behind link labels, and the AI sees those URLs too. Pasting into a quoted search inserts the text as copied.
20
+ - `[[note id]]` is always a link, even in a note with a `[[ ]]` formatting tag.
21
+ - The startup output in the terminal is easier to read: the version, a check mark per check, and each namespace's URLs lined up.
22
+ - Fixed: clicking the AI chat's $ or eye button twice quickly crashed with "Redundant state change".
23
+
24
+ ## Changes in 0.13.0
25
+
26
+ - Dictation: text from speech-to-text tools such as Superwhisper, pasted into the search bar or any tag field, becomes your existing tags ("neural network" gives `neural-network`). Say "quote … end quote" for text, "minus" to exclude, "at" before meta tags such as `@todo`. In a note, the words after "start tags" go to its tag bar. The phrases are set in Dictation Settings, and one undo restores what was pasted.
27
+ - A quoted search with a space at its edge matches whole words: `" fat"` no longer finds "father".
28
+ - The AI keeps a record of what it did for each answer (notes read, searches, web pages opened), so questions like "did you search the web for that?" are answered from what actually happened.
29
+ - Dropping a `.txt`, `.md`, `.csv` or `.json` file stores it as before and adds its text as a child note, shown as Markdown, a table or formatted JSON. File pills show the extension (`.MD`, `.CSV`, …), and hovering a pill says that clicking downloads the file.
30
+ - Typing one letter in the tag bar now narrows the suggestions you were already shown instead of reordering them, so the tag you want is in the top five far more often.
31
+
15
32
  ## Changes in 0.12.0
16
33
 
17
34
  - AI chat is now a tool-using agent: in one answer it can look up MetaList help, read and search the notes in your view, open web pages, and open menus, instead of picking a single route up front. Answers cite notes and web pages with clickable references, including each item listed from a web page.
@@ -41,6 +41,7 @@ class AuthMiddleware(BaseHTTPMiddleware):
41
41
  NO_TOKEN_REFRESH_PATHS = [
42
42
  f"{API_PREFIX}/auth/status", # Polling service pings this for connectivity
43
43
  f"{API_PREFIX}/reminders/evaluate", # Reminder polling is not user-initiated activity
44
+ f"{API_PREFIX}/notes/link-titles/retry", # The retry dialog polls its progress
44
45
  ]
45
46
 
46
47
  # Note: /api/notes/* paths are NOT in this list - they require auth when password is set
@@ -106,6 +106,18 @@ class SearchSuggestionInteractionRequest(TypedDict):
106
106
  class TabSearchInteractionRequest(TypedDict):
107
107
  searchQuery: Text
108
108
 
109
+ @with_config(ConfigDict(strict=True))
110
+ class DictationPasteRequest(TypedDict):
111
+ """Text pasted into the search bar or the tag bar, and the field's current value."""
112
+ text: Text
113
+ target: Literal["search", "tags", "tag", "condition"]
114
+ current_value: Text
115
+ # The spoken phrases around a quoted phrase (Dictation Settings).
116
+ quote_open: Identifier
117
+ quote_close: Identifier
118
+ # Spoken before a search term to exclude it (Dictation Settings).
119
+ negate_phrase: Identifier
120
+
109
121
  @with_config(ConfigDict(strict=True))
110
122
  class TagSuggestionsRequest(TypedDict):
111
123
  note_id: Identifier
@@ -136,6 +148,14 @@ class CreateChildRequest(TypedDict):
136
148
  undoContext: UndoContext
137
149
  viewport: Viewport
138
150
 
151
+ @with_config(ConfigDict(strict=True))
152
+ class CreateFilePreviewChildRequest(TypedDict):
153
+ fileId: Identifier
154
+ search_query: Text | None
155
+ clientId: Identifier
156
+ undoContext: UndoContext
157
+ viewport: Viewport
158
+
139
159
  @with_config(ConfigDict(strict=True))
140
160
  class UpdateNoteRequest(TypedDict):
141
161
  clientId: Identifier
@@ -642,6 +642,7 @@ def stream_ai_chat(
642
642
  model=payload.model,
643
643
  )
644
644
  provider_messages = ai_chat_store.provider_messages(session_key=session_key)
645
+ earlier_actions = ai_chat_store.earlier_actions(session_key=session_key)
645
646
  initial_messages = agent_context_builder.build_initial_messages(
646
647
  canonical_messages=provider_messages,
647
648
  prompts=prompts,
@@ -654,7 +655,7 @@ def stream_ai_chat(
654
655
  events = _stream_runtime_events(payload=payload, openai_api_key=openai_api_key,
655
656
  session_key=session_key, provider_messages=provider_messages, prompts=prompts, skills=skills,
656
657
  retrieval_settings=retrieval_settings, frozen_scope=frozen_scope, tagging_run=tagging_run,
657
- web_settings=web_settings,
658
+ web_settings=web_settings, earlier_actions=earlier_actions,
658
659
  initial_input_tokens=initial_approx_input_tokens)
659
660
 
660
661
  return StreamingResponse(
@@ -673,6 +674,7 @@ async def _stream_runtime_events(
673
674
  provider_messages: list[dict[str, str]], prompts: AgentPromptSet, skills: AgentSkillSet,
674
675
  retrieval_settings: AgentRetrievalSettings, frozen_scope: ScopedSearchSnapshot,
675
676
  tagging_run: TaggingRun, initial_input_tokens: int, web_settings: AgentWebSettings,
677
+ earlier_actions: list[dict[str, object]],
676
678
  ) -> AsyncIterator[dict[str, object]]:
677
679
  action, start_label = 'provider_runtime', 'Connecting to OpenAI API'
678
680
  ready_label = 'OpenAI API ready · 1,050,000-token context'
@@ -686,7 +688,7 @@ async def _stream_runtime_events(
686
688
  selected_model=payload.model, thinking_level=payload.thinking_level,
687
689
  canonical_messages=provider_messages, prompts=prompts, skills=skills,
688
690
  retrieval_settings=retrieval_settings, web_settings=web_settings,
689
- frozen_scope=frozen_scope, tagging_run=tagging_run)
691
+ frozen_scope=frozen_scope, tagging_run=tagging_run, earlier_actions=earlier_actions)
690
692
  try:
691
693
  async for event in events:
692
694
  yield event
@@ -97,6 +97,7 @@ from app.services.client_state_service import save_client_preferences
97
97
  from app.services.client_state_service import save_command_palette_usage
98
98
  from app.services.openai_credentials import openai_credential_store
99
99
  from app.services.input_errors import NamespaceInputRejected
100
+ from app.services.link_title_retry import stop_link_title_retry
100
101
 
101
102
 
102
103
  router = APIRouter(prefix="/auth", tags=["auth2"])
@@ -595,6 +596,9 @@ def logout(
595
596
  openai_credential_store.clear_session(session_key=session_key)
596
597
  token_service.revoke_token(token)
597
598
  shell_session_service.reset()
599
+ # Lock and login end a retry through the runtime generation; a passwordless
600
+ # logout does not change it, so stop the retry here.
601
+ stop_link_title_retry()
598
602
  view_cache.clear()
599
603
  reset_all_undo_state()
600
604
  reset_sync_state()
@@ -712,6 +716,8 @@ def auth_status(
712
716
  return {
713
717
  "version": VERSION,
714
718
  "database_user_version": database_user_version,
719
+ # The next login backs up and upgrades this database (the login screen says so).
720
+ "database_upgrade_pending": database_user_version < CURRENT_DATABASE_VERSION,
715
721
  "authenticated": token is not None,
716
722
  # Same answer as AuthService.has_password(), from the row already read.
717
723
  "has_password": settings is not None and bool(settings.encryption_enabled),
@@ -20,9 +20,11 @@ from app.api.note_requests import (
20
20
  SearchSuggestionInteractionRequest,
21
21
  TabSearchInteractionRequest,
22
22
  TagSuggestionsRequest,
23
+ DictationPasteRequest,
23
24
  CreateNoteTopRequest,
24
25
  CreateSiblingRequest,
25
26
  CreateChildRequest,
27
+ CreateFilePreviewChildRequest,
26
28
  UpdateNoteRequest,
27
29
  SaveNoteRequest,
28
30
  AddSelectedTextTagRequest,
@@ -61,9 +63,16 @@ from app.services.exception_capture import CapturedExceptionContext
61
63
  from app.usecases.create_note import CmdCreateNote
62
64
  from app.usecases.base import QueryCommand
63
65
  from app.usecases.create_sibling import CmdCreateSibling
66
+ from app.services.file_registry import file_registry
64
67
  from app.usecases.create_child import CmdCreateChild
68
+ from app.usecases.create_file_preview_child import CmdCreateFilePreviewChild
65
69
  from app.usecases.update_content import CmdUpdateContent
66
70
  from app.usecases.prefetch_link_titles import CmdPrefetchLinkTitles
71
+ from app.services.link_title_retry import (
72
+ link_title_retry_snapshot,
73
+ start_link_title_retry,
74
+ stop_link_title_retry,
75
+ )
67
76
  from app.usecases.add_selected_text_tag import CmdAddSelectedTextTag
68
77
  from app.usecases.tag_proposals import (
69
78
  CmdAcceptTagProposal,
@@ -127,6 +136,7 @@ from app.services.html_export import build_notes_export_filename
127
136
  from app.services.note_fullscreen import build_note_fullscreen_markup
128
137
  from app.services.link_titles import link_title_store
129
138
  from app.services.search_index import search_index
139
+ from app.services.dictation_cleanup import clean_dictated_paste
130
140
  from app.services.tag_suggestions import suggest_tags_for_note
131
141
  from app.services.undo_state import reset_undo_stack
132
142
  from app.usecases.prioritize import list_prioritize_tag_suggestions
@@ -154,6 +164,26 @@ def prefetch_link_titles(request: Request, draft: LinkTitlePrefetchRequest) -> d
154
164
  return CmdPrefetchLinkTitles(content=draft.content, tags=draft.tags).execute()
155
165
 
156
166
 
167
+ @router.get("/notes/link-titles/retry")
168
+ def link_title_retry_progress(request: Request) -> dict[str, object]:
169
+ require_request_auth_token(request)
170
+ return link_title_retry_snapshot()
171
+
172
+
173
+ @router.post("/notes/link-titles/retry")
174
+ @transactional_route
175
+ def start_link_title_retry_route(request: Request) -> dict[str, object]:
176
+ require_request_auth_token(request)
177
+ return start_link_title_retry()
178
+
179
+
180
+ @router.post("/notes/link-titles/retry/stop")
181
+ @transactional_route
182
+ def stop_link_title_retry_route(request: Request) -> dict[str, object]:
183
+ require_request_auth_token(request)
184
+ return stop_link_title_retry()
185
+
186
+
157
187
  def _require_note_present(note_id: str, *, context: str) -> None:
158
188
  if not isinstance(context, str) or not context:
159
189
  raise ValueError("context must be a non-empty string")
@@ -551,6 +581,22 @@ def delete_tag_interactions(request: Request) -> Dict[str, object]:
551
581
  return {"deletedCount": deleted_count}
552
582
 
553
583
 
584
+ @router.post("/notes/dictation-paste")
585
+ @transactional_route
586
+ def dictation_paste(payload: DictationPasteRequest) -> Dict[str, object]:
587
+ """Read-only: the cleaned-up text to insert for a paste (docs/ui/dictation-paste.md)."""
588
+ text = clean_dictated_paste(
589
+ text=payload["text"],
590
+ target=payload["target"],
591
+ existing_tag_frequencies=search_index.list_explicit_tag_frequencies(),
592
+ current_value=payload["current_value"],
593
+ quote_open=payload["quote_open"],
594
+ quote_close=payload["quote_close"],
595
+ negate_phrase=payload["negate_phrase"],
596
+ )
597
+ return {"text": text}
598
+
599
+
554
600
  @router.post("/notes/tag-suggestions")
555
601
  @transactional_route
556
602
  def tag_suggestions(payload: TagSuggestionsRequest) -> Dict[str, object]:
@@ -750,6 +796,27 @@ def create_child(request: Request, note_id: str, body: CreateChildRequest):
750
796
  return cmd.execute()
751
797
 
752
798
 
799
+ @router.post("/notes/file-preview-child/{note_id}")
800
+ @transactional_route
801
+ def create_file_preview_child(request: Request, note_id: str, body: CreateFilePreviewChildRequest):
802
+ token = _require_bearer_token(request)
803
+ viewport = _require_viewport(body)
804
+ _require_note_present(note_id, context="notes.file-preview-child")
805
+ file_id = body["fileId"]
806
+ if not file_registry.has_file(file_id):
807
+ raise HTTPException(status_code=404, detail=f"File not found: {file_id}")
808
+ cmd = CmdCreateFilePreviewChild(
809
+ parent_note_id=note_id,
810
+ file_id=file_id,
811
+ search_query=body["search_query"],
812
+ token=token,
813
+ client_id=body["clientId"],
814
+ undo_context=body["undoContext"],
815
+ viewport=viewport,
816
+ )
817
+ return cmd.execute()
818
+
819
+
753
820
  @router.put("/notes/{note_id}")
754
821
  @transactional_route
755
822
  def update_note(request: Request, note_id: str, body: UpdateNoteRequest):
@@ -45,7 +45,6 @@ def _env_int(name: str, default: int) -> int:
45
45
  CRASH_SERVER_ON_FAIL = _env_flag("CRASH_SERVER_ON_FAIL", True)
46
46
  DEV_ENFORCE_INTEGRITY_CHECKS = _env_flag("DEV_ENFORCE_INTEGRITY_CHECKS", False)
47
47
  DISABLE_UNDO_SNAPSHOT = _env_flag("DISABLE_UNDO_SNAPSHOT", True)
48
- STARTUP_ANIMATION_ENABLED = _env_flag("STARTUP_ANIMATION_ENABLED", False)
49
48
 
50
49
  # Tag suggestions
51
50
  TAG_SUGGESTION_CONNECTORS = "-_/."
@@ -94,6 +94,20 @@ class EncryptionAuditReport:
94
94
  def startup_allowed(self) -> bool:
95
95
  return self.namespace_count > 0 and len(self.fatal_findings) == 0
96
96
 
97
+ def namespace_statuses(self) -> list[tuple[str, str]]:
98
+ """(namespace, PASS | MIGRATION REQUIRED | FAIL | SKIPPED (not encrypted)) per namespace."""
99
+ statuses: list[tuple[str, str]] = []
100
+ for result in self.results:
101
+ result_status = "SKIPPED (not encrypted)"
102
+ if result.is_encrypted:
103
+ result_status = "PASS"
104
+ if result.findings:
105
+ result_status = "MIGRATION REQUIRED"
106
+ if any(not finding.is_migration_deferred for finding in result.findings):
107
+ result_status = "FAIL"
108
+ statuses.append((result.namespace, result_status))
109
+ return statuses
110
+
97
111
  def render_text(self) -> str:
98
112
  status = "FAIL"
99
113
  if self.passed:
@@ -110,15 +124,8 @@ class EncryptionAuditReport:
110
124
  ),
111
125
  f"Sensitive payloads checked: {self.checked_payload_count}",
112
126
  ]
113
- for result in self.results:
114
- result_status = "SKIPPED (not encrypted)"
115
- if result.is_encrypted:
116
- result_status = "PASS"
117
- if result.findings:
118
- result_status = "MIGRATION REQUIRED"
119
- if any(not finding.is_migration_deferred for finding in result.findings):
120
- result_status = "FAIL"
121
- lines.append(f"- {result.namespace}: {result_status}")
127
+ for namespace, result_status in self.namespace_statuses():
128
+ lines.append(f"- {namespace}: {result_status}")
122
129
  if self.findings:
123
130
  lines.append("Findings:")
124
131
  for finding in self.findings:
@@ -26,6 +26,8 @@ CAPTURE_BOUNDARIES = {
26
26
  'app/api/routes/app_updates.py:update_status:lookup': ('AppUpdateRejected', 'FileNotFoundError'),
27
27
  # Release smoke polls only its own disposable HTTP listeners during an actual update.
28
28
  'scripts/smoke_self_update.py:_has_updated_namespace:probe_capture': ('HTTPError',),
29
+ # Release smoke cleanup: on Windows an exiting process refuses termination; the wait then checks it stopped.
30
+ 'scripts/smoke_installed_package.py:_terminate_on_windows:exit_capture': ('ProcessLookupError', 'PermissionError'),
29
31
  # A child can exit between poll and terminate; hung children must be killed and reaped.
30
32
  'app/services/namespace_switcher.py:_stop_failed_namespace_launch:terminate_capture': ('ProcessLookupError',),
31
33
  'app/services/namespace_switcher.py:_stop_failed_namespace_launch:wait_capture': ('TimeoutExpired',),
@@ -125,6 +127,12 @@ CAPTURE_BOUNDARIES = {
125
127
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
126
128
  'app/services/link_titles.py:fetch_link_title:target_capture': ('PublicHttpTargetRejected',),
127
129
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
130
+ 'app/services/link_titles.py:_fetch_oembed_title:target_capture': ('PublicHttpTargetRejected',),
131
+ # Handle expected external I/O, provider, image or LaTeX parsing failure.
132
+ 'app/services/link_titles.py:_fetch_oembed_title:json_capture': ('JSONDecodeError', 'UnicodeDecodeError'),
133
+ # Handle expected external I/O, provider, image or LaTeX parsing failure.
134
+ 'app/services/link_titles.py:_download_oembed:capture': ('TimeoutException', 'NetworkError', 'HTTPError', 'TimeoutException', 'NetworkError', 'ProtocolError'),
135
+ # Handle expected external I/O, provider, image or LaTeX parsing failure.
128
136
  'app/services/namespace_deletion_worker.py:_is_process_running:kill_capture': ('ProcessLookupError', 'PermissionError'),
129
137
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
130
138
  'app/services/namespace_deletion_worker.py:_send_signal_if_running:signal_capture': ('ProcessLookupError',),
@@ -16,7 +16,7 @@ from app.api.upload_limits import UploadLimitMiddleware
16
16
  from app.presentation.templates import get_templates
17
17
  from .api import dev
18
18
  from .api.middleware.auth import AuthMiddleware
19
- from app.config import ACTIVE_NAMESPACE, STARTUP_ANIMATION_ENABLED, VERSION
19
+ from app.config import ACTIVE_NAMESPACE, VERSION
20
20
  from .db.session import begin_writer, enable_read_guard
21
21
  from .db.schema import initialize_schema
22
22
  from .db.migrations import CURRENT_DATABASE_VERSION
@@ -61,6 +61,7 @@ from app.services.diagnostics import track_request
61
61
  from app.services.diagnostics import write_encrypted_exception_trace
62
62
  from app.security.sensitive_logging import traceback_frame_summary
63
63
  from app.api.request_auth import clear_auth_cookie
64
+ from app.presentation.login_page import login_is_certainly_needed
64
65
  from app.api.routes.notes import router as api2_router
65
66
  from app.api.routes.auth import router as api2_auth_router
66
67
  from app.api.routes.app_updates import router as api2_app_updates_router
@@ -463,7 +464,7 @@ async def home(request: Request, db: Annotated[SafeSession, Depends(get_db)]):
463
464
  asset_version=ASSET_VERSION,
464
465
  page_title=_resolve_page_title(base_title="MetaList"),
465
466
  needs_auth=True,
466
- startup_animation_enabled=STARTUP_ANIMATION_ENABLED,
467
+ shows_login_at_once=login_is_certainly_needed(request),
467
468
  )
468
469
  return template.render(
469
470
  request=request,
@@ -472,10 +473,11 @@ async def home(request: Request, db: Annotated[SafeSession, Depends(get_db)]):
472
473
  asset_version=ASSET_VERSION,
473
474
  page_title=_resolve_page_title(base_title="MetaList"),
474
475
  needs_auth=False,
475
- startup_animation_enabled=STARTUP_ANIMATION_ENABLED,
476
+ shows_login_at_once=False,
476
477
  )
477
478
 
478
479
 
480
+
479
481
  @app.get("/maintenance", response_class=HTMLResponse)
480
482
  async def maintenance_page(request: Request):
481
483
  """Maintenance mode page shown during bulk operations."""
@@ -0,0 +1,18 @@
1
+ """Whether the page opens straight on the login screen (docs/AI-SUMMARY.md, Login screen)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from starlette.requests import Request
6
+
7
+ from app.api.request_auth import AUTH_COOKIE_NAME
8
+
9
+
10
+ def login_is_certainly_needed(request: Request) -> bool:
11
+ """Whether a password namespace's page can open on the login screen at once,
12
+ with no white page before the browser checks its session: a re-login was asked
13
+ for (the Session locked page's Go to Login), or the browser has no session."""
14
+ if not isinstance(request, Request):
15
+ raise TypeError("request must be a Request")
16
+ if request.query_params.get("force_reauth") == "1":
17
+ return True
18
+ return request.cookies.get(AUTH_COOKIE_NAME) is None
@@ -0,0 +1,59 @@
1
+ """The agent's own record of what it did for an answer.
2
+
3
+ Each tool call becomes one short entry: what was asked and what came of it,
4
+ never the content a tool returned (page text and notes can be huge, and the
5
+ model can read them again). The entries are kept with the answer for the rest of
6
+ the chat and given to the model on later turns, so a question such as "did you
7
+ search the web for that?" is answered from what actually happened. Only the
8
+ model sees them.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+
15
+
16
+ _NOTE_READ_TOOLS = frozenset({"read_view_notes", "search_view_notes"})
17
+ _OPERATION_TOOLS = frozenset({"summarize_view", "propose_tag_generation", "propose_tag_review"})
18
+ _KNOWN_TOOLS = _NOTE_READ_TOOLS | _OPERATION_TOOLS | {
19
+ "lookup_metalist_help", "view_overview", "open_web_pages", "open_menu",
20
+ }
21
+
22
+
23
+ def describe_action(*, name: str, arguments: str, result_content: str, is_error: bool) -> dict[str, object]:
24
+ """One log entry for a tool call, from its JSON arguments and JSON result."""
25
+ # A rejected call may name a tool that does not exist: it is still recorded.
26
+ if is_error:
27
+ return {"tool": name, "rejected": True}
28
+ if name not in _KNOWN_TOOLS:
29
+ raise ValueError(f"No action log entry for unknown tool: {name!r}")
30
+ parsed_arguments = json.loads(arguments)
31
+ assert isinstance(parsed_arguments, dict), "Tool arguments are a JSON object"
32
+ if name in _OPERATION_TOOLS:
33
+ return {"tool": name, "arguments": parsed_arguments}
34
+ result = json.loads(result_content)
35
+ assert isinstance(result, dict), "Tool results are a JSON object"
36
+ if name == "lookup_metalist_help":
37
+ return {"tool": name, "topics": list(parsed_arguments["topics"])}
38
+ if name == "view_overview":
39
+ return {"tool": name, "notes_in_view": result["note_count"], "trees_in_view": result["tree_count"]}
40
+ if name == "open_menu":
41
+ return {"tool": name, "menu": result["label"], "status": result["status"]}
42
+ if name == "open_web_pages":
43
+ return {"tool": name, "pages": [_page_entry(page) for page in result["pages"]]}
44
+ entry: dict[str, object] = {"tool": name}
45
+ if name == "search_view_notes":
46
+ entry["query"] = parsed_arguments["query"]
47
+ entry["matching_notes"] = result["matching_note_count"]
48
+ entry["trees_read"] = len(result["trees"])
49
+ entry["trees_left_unread"] = len(result["unread_root_ids"])
50
+ entry["trees_too_large"] = len(result["too_large_root_ids"])
51
+ return entry
52
+
53
+
54
+ def _page_entry(page: dict[str, object]) -> dict[str, object]:
55
+ """The address as asked, whether it opened, and its title when it did."""
56
+ title = ""
57
+ if page["status"] == "ok":
58
+ title = page["title"]
59
+ return {"url": page["requested_url"], "status": page["status"], "title": title}
@@ -52,6 +52,7 @@ from app.services.bulk_operation import bulk_operation_guard
52
52
  from app.services.agent.citation_tokens import ShortCitationTranslator
53
53
  from app.services.agent.note_aliases import NoteAliases
54
54
  from app.services.agent.execution_errors import AgentExecutionError
55
+ from app.services.agent.action_log import describe_action
55
56
 
56
57
 
57
58
  MAX_AGENT_TURNS = 8
@@ -82,6 +83,8 @@ class AgentLoopState:
82
83
  self.web_evidence: list[WebPageEvidence] = []
83
84
  self.capabilities = capabilities
84
85
  self.content = ""
86
+ # What this answer did, for later turns (action_log.py).
87
+ self.actions: list[dict[str, object]] = []
85
88
  # Note text shown to the model, and full-mode addresses the user approved.
86
89
  self.note_text_parts: list[str] = [selected_note_text]
87
90
  self.approved_urls: set[str] = set()
@@ -129,14 +132,19 @@ class AgentLoopState:
129
132
  "reference_note_ids": list(self.reference_note_ids),
130
133
  "reference_web_ids": self.reference_web_ids()}
131
134
 
135
+ def record_action(self, *, call: dict[str, str], result_content: str, is_error: bool) -> None:
136
+ self.actions.append(describe_action(name=call["name"], arguments=call["arguments"],
137
+ result_content=result_content, is_error=is_error))
138
+
132
139
  def done_event(self) -> dict[str, object]:
133
140
  return {"type": "done", "reference_note_ids": list(self.reference_note_ids),
134
- "reference_web_ids": self.reference_web_ids()}
141
+ "reference_web_ids": self.reference_web_ids(), "actions": list(self.actions)}
135
142
 
136
143
 
137
144
  class AgentLoopMixin:
138
145
  async def _run_agent_loop(
139
146
  self, *, run, canonical_messages: list[dict[str, str]], frozen_scope: ScopedSearchSnapshot, tagging_run,
147
+ earlier_actions: list[dict[str, object]],
140
148
  ) -> AsyncIterator[dict[str, object]]:
141
149
  if not isinstance(frozen_scope, ScopedSearchSnapshot):
142
150
  raise TypeError("frozen_scope must be ScopedSearchSnapshot")
@@ -167,6 +175,7 @@ class AgentLoopMixin:
167
175
  messages = self._context_builder.build_agent_messages(
168
176
  canonical_messages=canonical_messages, skills=run.skills, web_settings=run.web_settings,
169
177
  snapshot=snapshot, available_urls=capabilities.normalized_urls, note_aliases=note_aliases,
178
+ earlier_actions=earlier_actions,
170
179
  )
171
180
  self._trace_store.append_event(
172
181
  session_key=run.session_key, run_id=run.run_id, event_type="FROZEN_SCOPE",
@@ -238,16 +247,21 @@ class AgentLoopMixin:
238
247
  result = tool_message_result({"summary": "not started",
239
248
  "reason": "The current view has no notes to summarize."})
240
249
  self._record_tool_call(run=run, call=operation, result_text=result.content)
250
+ state.record_action(call=operation, result_content=result.content, is_error=False)
241
251
  messages.append({"role": "tool", "tool_call_id": operation["id"], "name": operation["name"],
242
252
  "content": result.content})
243
253
  answered_without_operation = True
244
254
  elif not isinstance(parsed, ToolResult):
245
255
  self._record_tool_call(run=run, call=operation, result_text="(operation started)")
256
+ state.record_action(call=operation, result_content="{}", is_error=False)
246
257
  async with aclosing(self._stream_agent_operation(
247
258
  run=run, canonical_messages=canonical_messages, snapshot=snapshot,
248
259
  tagging_run=tagging_run, arguments=parsed, state=state,
249
260
  )) as operation_events:
250
261
  async for event in operation_events:
262
+ # The operation ends the answer: its completion carries the log.
263
+ if event["type"] == "done":
264
+ event = {**event, "actions": list(state.actions)}
251
265
  yield event
252
266
  return
253
267
  if answered_without_operation:
@@ -266,6 +280,7 @@ class AgentLoopMixin:
266
280
  result = result_holder[0]
267
281
  results.append(result)
268
282
  state.add_tool_result(result)
283
+ state.record_action(call=call, result_content=result.content, is_error=result.is_error)
269
284
  self._record_tool_call(run=run, call=call, result_text=result.content)
270
285
  messages.append({"role": "tool", "tool_call_id": call["id"], "name": call["name"],
271
286
  "content": result.content})
@@ -78,7 +78,8 @@ class AgentContextBuilder:
78
78
  "none": (
79
79
  "Web access is disabled. You cannot search or open pages. If the "
80
80
  "request requires the web, state that limitation and tell the user "
81
- "they can enable contextual or full web access in AI Agent Settings."
81
+ "they can enable contextual or full web access in AI Agent Settings. Label "
82
+ "anything you suggest from your own knowledge as not looked up."
82
83
  ),
83
84
  "contextual": (
84
85
  "You may open only exact URLs in available_urls, plus addresses written in "
@@ -86,7 +87,11 @@ class AgentContextBuilder:
86
87
  "A #fragment is ignored "
87
88
  "when comparing, so https://a.example/page#part is the same address as "
88
89
  "https://a.example/page. You cannot search, and links discovered inside "
89
- "opened pages do not become available."
90
+ "opened pages do not become available. When a request needs a search (for "
91
+ "example newer or recent papers, releases or news), say plainly that this mode "
92
+ "only opens links already in the notes or chat, that 'Open any public web page' "
93
+ "in AI Agent Settings allows searching, and label anything you suggest from your "
94
+ "own knowledge as not looked up."
90
95
  ),
91
96
  "full": (
92
97
  "You may open any direct public HTTP(S) page, including Google "
@@ -158,6 +163,7 @@ class AgentContextBuilder:
158
163
  snapshot: ScopedSearchSnapshot,
159
164
  available_urls: tuple[str, ...],
160
165
  note_aliases: NoteAliases,
166
+ earlier_actions: list[dict[str, object]],
161
167
  ) -> list[dict[str, object]]:
162
168
  """The tool-using agent's opening conversation.
163
169
 
@@ -189,6 +195,16 @@ class AgentContextBuilder:
189
195
  {"role": "user", "content": "SELECTED_NOTE_CONTEXT\n" + json.dumps(view_context, sort_keys=True, separators=(",", ":"))},
190
196
  *self.append_web_access_context(messages=[], settings=web_settings, available_urls=available_urls),
191
197
  ]
198
+ if earlier_actions:
199
+ context_messages.append({"role": "user", "content": "EARLIER_ACTIONS\n" + json.dumps({
200
+ "instruction": (
201
+ "Your own record of what you did for each earlier answer in this chat, oldest first: "
202
+ "the tools you called, what you asked for, and what came of them (page text and note "
203
+ "content are not repeated here). Answer questions about how an earlier answer was made "
204
+ "only from this record. If it does not show something, say you cannot tell."
205
+ ),
206
+ "answers": earlier_actions,
207
+ }, sort_keys=True, separators=(",", ":"))})
192
208
  return [
193
209
  *system_messages,
194
210
  *[dict(message) for message in canonical_messages[:-1]],
@@ -16,6 +16,7 @@ HELP_TOPICS = {
16
16
  'ai': ('AI and tag proposals', 'OpenAI settings, context limits, prompts/skills, history export, and AI tag proposals: generation, acceptance, rejection/removal and bulk undo limits. This topic alone covers proposal workflow explanations.'),
17
17
  'privacy': ('Privacy and security', 'Cloud disclosure, gray notes when hovering chat, password exclusion, encryption and credentials.'),
18
18
  'data': ('Namespaces and backups', 'Namespaces, backup/restore, HTML export, ports and updates.'),
19
+ 'dictation': ('Dictation (speech to text)', 'Pasting dictated text from speech-to-text tools such as Superwhisper into the search bar, tag bar or a note: how words become tags, spoken dash/quote/or/not, "at to do" meta tags, the "start tags" phrase in notes, undo, and Dictation Settings.'),
19
20
  'releases': ('Release notes', 'What changed in each MetaList version (what is new, when a feature or fix arrived).'),
20
21
  }
21
22
  HelpTopic = Literal[tuple(HELP_TOPICS)]
@@ -103,6 +103,13 @@ last tool call. Answer the user's exact current question. Use the conversation t
103
103
  resolve follow-ups such as "try again"; earlier answers are not evidence about the
104
104
  current view, and earlier citations must not be reused.
105
105
 
106
+ `EARLIER_ACTIONS` is your own record of what you did for each earlier answer in
107
+ this chat: the tools you called and what came of them. When asked how an earlier
108
+ answer was made (did you search the web, which pages, did you read the notes),
109
+ answer from that record, including the searches and pages it lists. If the record
110
+ does not show something, say you cannot tell; never deny or claim an action
111
+ otherwise.
112
+
106
113
  Notes are identified by short ids such as `n12`. Cite every claim drawn from a note
107
114
  with its id in double brackets, copying the `note_id` of the note whose
108
115
  `content_text` supports it (a child, not merely its root), directly after the