MetaList 0.8.0__tar.gz → 0.9.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 (487) hide show
  1. {metalist-0.8.0/metalist.egg-info → metalist-0.9.0}/PKG-INFO +9 -2
  2. {metalist-0.8.0 → metalist-0.9.0}/README.md +7 -1
  3. {metalist-0.8.0 → metalist-0.9.0}/app/api/note_requests.py +35 -31
  4. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/ai.py +43 -7
  5. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/auth.py +8 -0
  6. {metalist-0.8.0 → metalist-0.9.0}/app/exception_boundaries.py +15 -4
  7. {metalist-0.8.0 → metalist-0.9.0}/app/presentation/render/note_renderer.py +1 -0
  8. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/actions.py +59 -2
  9. metalist-0.9.0/app/services/agent/context.py +724 -0
  10. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/inference.py +4 -0
  11. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/investigation.py +106 -2
  12. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/model_policy.py +1 -0
  13. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/prompts/final-response.md +24 -0
  14. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/prompts/system.md +14 -2
  15. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/runtime.py +1061 -6
  16. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skill_settings.py +45 -0
  17. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-ai.md +16 -2
  18. metalist-0.9.0/app/services/agent/skills/staged-summary.md +27 -0
  19. metalist-0.9.0/app/services/agent/skills/tag-proposals.md +27 -0
  20. metalist-0.9.0/app/services/agent/skills/web-browsing.md +88 -0
  21. metalist-0.9.0/app/services/agent/staged_summary.py +223 -0
  22. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/structured_inference.py +20 -0
  23. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/tagging.py +17 -28
  24. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/tagging_run.py +143 -45
  25. metalist-0.9.0/app/services/agent/web_capabilities.py +151 -0
  26. metalist-0.9.0/app/services/agent/web_evidence.py +367 -0
  27. metalist-0.9.0/app/services/agent/web_fetch.py +600 -0
  28. metalist-0.9.0/app/services/agent/web_settings.py +40 -0
  29. {metalist-0.8.0 → metalist-0.9.0}/app/services/ai_chat.py +3 -1
  30. {metalist-0.8.0 → metalist-0.9.0}/app/services/ai_chat_rendering.py +172 -12
  31. {metalist-0.8.0 → metalist-0.9.0}/app/services/ai_chat_stream.py +62 -9
  32. {metalist-0.8.0 → metalist-0.9.0}/app/services/client_state_service.py +3 -1
  33. {metalist-0.8.0 → metalist-0.9.0}/app/services/link_titles.py +15 -216
  34. {metalist-0.8.0 → metalist-0.9.0}/app/services/markdown_rendering.py +46 -0
  35. metalist-0.9.0/app/services/public_http.py +201 -0
  36. {metalist-0.8.0 → metalist-0.9.0}/app/services/remote_image_proxy.py +8 -10
  37. {metalist-0.8.0 → metalist-0.9.0}/app/services/runtime_lock.py +2 -0
  38. {metalist-0.8.0 → metalist-0.9.0}/app/static/css/main.css +112 -2
  39. metalist-0.9.0/app/static/js/modules/ai-chat/agent-web-settings.js +21 -0
  40. metalist-0.9.0/app/static/js/modules/ai-chat/ai-chat-message-placement.js +66 -0
  41. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/ai-chat-panel-controller.js +48 -16
  42. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/ai-chat-panel-service.js +39 -0
  43. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/bulk-proposal-ui.js +129 -51
  44. metalist-0.9.0/app/static/js/modules/ai-chat/bulk-scope-question.js +84 -0
  45. metalist-0.9.0/app/static/js/modules/ai-chat/summary-batch-preview.js +133 -0
  46. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/command-palette-controller.js +10 -0
  47. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/ai-agent-settings-modal.js +28 -0
  48. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/actions/note-actions.js +7 -1
  49. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/events/keyboard-events.js +29 -20
  50. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/events/mouse-events.js +16 -1
  51. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/edit-session-collapse-policy-service.js +24 -0
  52. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-click-target-service.js +16 -0
  53. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/reference-source-navigation-service.js +112 -6
  54. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tab-state-service.js +2 -0
  55. {metalist-0.8.0 → metalist-0.9.0}/app/templates/index.html +1 -1
  56. {metalist-0.8.0 → metalist-0.9.0}/app/version.py +1 -1
  57. {metalist-0.8.0 → metalist-0.9.0/metalist.egg-info}/PKG-INFO +9 -2
  58. {metalist-0.8.0 → metalist-0.9.0}/metalist.egg-info/SOURCES.txt +13 -0
  59. {metalist-0.8.0 → metalist-0.9.0}/metalist.egg-info/requires.txt +1 -0
  60. {metalist-0.8.0 → metalist-0.9.0}/pyproject.toml +1 -0
  61. metalist-0.8.0/app/services/agent/context.py +0 -330
  62. {metalist-0.8.0 → metalist-0.9.0}/MANIFEST.in +0 -0
  63. {metalist-0.8.0 → metalist-0.9.0}/app/__init__.py +0 -0
  64. {metalist-0.8.0 → metalist-0.9.0}/app/api/__init__.py +0 -0
  65. {metalist-0.8.0 → metalist-0.9.0}/app/api/deps.py +0 -0
  66. {metalist-0.8.0 → metalist-0.9.0}/app/api/dev.py +0 -0
  67. {metalist-0.8.0 → metalist-0.9.0}/app/api/middleware/auth.py +0 -0
  68. {metalist-0.8.0 → metalist-0.9.0}/app/api/request_auth.py +0 -0
  69. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/app_updates.py +0 -0
  70. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/backups.py +0 -0
  71. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/files.py +0 -0
  72. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/notes.py +0 -0
  73. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/ontology.py +0 -0
  74. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/reminders.py +0 -0
  75. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/remote_images.py +0 -0
  76. {metalist-0.8.0 → metalist-0.9.0}/app/api/routes/test.py +0 -0
  77. {metalist-0.8.0 → metalist-0.9.0}/app/api/transactions.py +0 -0
  78. {metalist-0.8.0 → metalist-0.9.0}/app/api/upload_limits.py +0 -0
  79. {metalist-0.8.0 → metalist-0.9.0}/app/config.py +0 -0
  80. {metalist-0.8.0 → metalist-0.9.0}/app/data_directory.py +0 -0
  81. {metalist-0.8.0 → metalist-0.9.0}/app/db/__init__.py +0 -0
  82. {metalist-0.8.0 → metalist-0.9.0}/app/db/backup_settings_sql.py +0 -0
  83. {metalist-0.8.0 → metalist-0.9.0}/app/db/engine.py +0 -0
  84. {metalist-0.8.0 → metalist-0.9.0}/app/db/file_schema.py +0 -0
  85. {metalist-0.8.0 → metalist-0.9.0}/app/db/file_session.py +0 -0
  86. {metalist-0.8.0 → metalist-0.9.0}/app/db/files_sql.py +0 -0
  87. {metalist-0.8.0 → metalist-0.9.0}/app/db/link_titles_sql.py +0 -0
  88. {metalist-0.8.0 → metalist-0.9.0}/app/db/live_recovery.py +0 -0
  89. {metalist-0.8.0 → metalist-0.9.0}/app/db/migrations.py +0 -0
  90. {metalist-0.8.0 → metalist-0.9.0}/app/db/notes_sql.py +0 -0
  91. {metalist-0.8.0 → metalist-0.9.0}/app/db/ontology_rules_sql.py +0 -0
  92. {metalist-0.8.0 → metalist-0.9.0}/app/db/reminders_sql.py +0 -0
  93. {metalist-0.8.0 → metalist-0.9.0}/app/db/retire_sounds.py +0 -0
  94. {metalist-0.8.0 → metalist-0.9.0}/app/db/schema.py +0 -0
  95. {metalist-0.8.0 → metalist-0.9.0}/app/db/search_history_sql.py +0 -0
  96. {metalist-0.8.0 → metalist-0.9.0}/app/db/session.py +0 -0
  97. {metalist-0.8.0 → metalist-0.9.0}/app/db/settings_sql.py +0 -0
  98. {metalist-0.8.0 → metalist-0.9.0}/app/db/tab_state_sql.py +0 -0
  99. {metalist-0.8.0 → metalist-0.9.0}/app/db/version.py +0 -0
  100. {metalist-0.8.0 → metalist-0.9.0}/app/encryption_audit.py +0 -0
  101. {metalist-0.8.0 → metalist-0.9.0}/app/https_proxy.py +0 -0
  102. {metalist-0.8.0 → metalist-0.9.0}/app/main.py +0 -0
  103. {metalist-0.8.0 → metalist-0.9.0}/app/models/commands.py +0 -0
  104. {metalist-0.8.0 → metalist-0.9.0}/app/models/database.py +0 -0
  105. {metalist-0.8.0 → metalist-0.9.0}/app/models/entities.py +0 -0
  106. {metalist-0.8.0 → metalist-0.9.0}/app/models/enums.py +0 -0
  107. {metalist-0.8.0 → metalist-0.9.0}/app/models/linked_list.py +0 -0
  108. {metalist-0.8.0 → metalist-0.9.0}/app/models/list_operations.py +0 -0
  109. {metalist-0.8.0 → metalist-0.9.0}/app/models/list_traversal.py +0 -0
  110. {metalist-0.8.0 → metalist-0.9.0}/app/models/note_crud.py +0 -0
  111. {metalist-0.8.0 → metalist-0.9.0}/app/models/utils.py +0 -0
  112. {metalist-0.8.0 → metalist-0.9.0}/app/network_settings.py +0 -0
  113. {metalist-0.8.0 → metalist-0.9.0}/app/presentation/__init__.py +0 -0
  114. {metalist-0.8.0 → metalist-0.9.0}/app/presentation/render/__init__.py +0 -0
  115. {metalist-0.8.0 → metalist-0.9.0}/app/presentation/templates.py +0 -0
  116. {metalist-0.8.0 → metalist-0.9.0}/app/security/authenticated_logging.py +0 -0
  117. {metalist-0.8.0 → metalist-0.9.0}/app/security/encryption.py +0 -0
  118. {metalist-0.8.0 → metalist-0.9.0}/app/security/http_error_diagnostics.py +0 -0
  119. {metalist-0.8.0 → metalist-0.9.0}/app/security/http_headers.py +0 -0
  120. {metalist-0.8.0 → metalist-0.9.0}/app/security/note_html.py +0 -0
  121. {metalist-0.8.0 → metalist-0.9.0}/app/security/request_boundary.py +0 -0
  122. {metalist-0.8.0 → metalist-0.9.0}/app/security/request_hosts.py +0 -0
  123. {metalist-0.8.0 → metalist-0.9.0}/app/security/sensitive_cache.py +0 -0
  124. {metalist-0.8.0 → metalist-0.9.0}/app/security/sensitive_logging.py +0 -0
  125. {metalist-0.8.0 → metalist-0.9.0}/app/security/shell_execution.py +0 -0
  126. {metalist-0.8.0 → metalist-0.9.0}/app/security/validation_errors.py +0 -0
  127. {metalist-0.8.0 → metalist-0.9.0}/app/server_runtime.py +0 -0
  128. {metalist-0.8.0 → metalist-0.9.0}/app/services/__init__.py +0 -0
  129. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/__init__.py +0 -0
  130. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/cloud_privacy.py +0 -0
  131. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/evidence_serialization.py +0 -0
  132. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/help_catalog.py +0 -0
  133. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/history.py +0 -0
  134. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/judging.py +0 -0
  135. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/menu_actions.py +0 -0
  136. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/openai_cost_tracking.py +0 -0
  137. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/openai_inference.py +0 -0
  138. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/permissions.py +0 -0
  139. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/prompt_settings.py +0 -0
  140. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/prompts/__init__.py +0 -0
  141. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/prompts/help-response.md +0 -0
  142. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/prompts/tool-result.md +0 -0
  143. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/retrieval_settings.py +0 -0
  144. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/scope.py +0 -0
  145. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/__init__.py +0 -0
  146. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-data.md +0 -0
  147. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-formatting.md +0 -0
  148. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-menus.md +0 -0
  149. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-notes.md +0 -0
  150. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-privacy.md +0 -0
  151. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-references.md +0 -0
  152. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-reminders.md +0 -0
  153. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-search.md +0 -0
  154. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/help-tags.md +0 -0
  155. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/skills/scoped-investigation.md +0 -0
  156. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/token_estimation.py +0 -0
  157. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/tools.py +0 -0
  158. {metalist-0.8.0 → metalist-0.9.0}/app/services/agent/trace.py +0 -0
  159. {metalist-0.8.0 → metalist-0.9.0}/app/services/app_update_worker.py +0 -0
  160. {metalist-0.8.0 → metalist-0.9.0}/app/services/app_updates.py +0 -0
  161. {metalist-0.8.0 → metalist-0.9.0}/app/services/auth.py +0 -0
  162. {metalist-0.8.0 → metalist-0.9.0}/app/services/auth_cache_state.py +0 -0
  163. {metalist-0.8.0 → metalist-0.9.0}/app/services/auth_service.py +0 -0
  164. {metalist-0.8.0 → metalist-0.9.0}/app/services/backlink_index.py +0 -0
  165. {metalist-0.8.0 → metalist-0.9.0}/app/services/backlinks.py +0 -0
  166. {metalist-0.8.0 → metalist-0.9.0}/app/services/backup_service.py +0 -0
  167. {metalist-0.8.0 → metalist-0.9.0}/app/services/backup_settings_service.py +0 -0
  168. {metalist-0.8.0 → metalist-0.9.0}/app/services/bulk_operation.py +0 -0
  169. {metalist-0.8.0 → metalist-0.9.0}/app/services/content_cache.py +0 -0
  170. {metalist-0.8.0 → metalist-0.9.0}/app/services/content_formatting.py +0 -0
  171. {metalist-0.8.0 → metalist-0.9.0}/app/services/diagnostics.py +0 -0
  172. {metalist-0.8.0 → metalist-0.9.0}/app/services/embedded_references.py +0 -0
  173. {metalist-0.8.0 → metalist-0.9.0}/app/services/encryption.py +0 -0
  174. {metalist-0.8.0 → metalist-0.9.0}/app/services/exception_capture.py +0 -0
  175. {metalist-0.8.0 → metalist-0.9.0}/app/services/file_registry.py +0 -0
  176. {metalist-0.8.0 → metalist-0.9.0}/app/services/file_storage.py +0 -0
  177. {metalist-0.8.0 → metalist-0.9.0}/app/services/footnote_layout.py +0 -0
  178. {metalist-0.8.0 → metalist-0.9.0}/app/services/footnote_rendering.py +0 -0
  179. {metalist-0.8.0 → metalist-0.9.0}/app/services/hierarchy.py +0 -0
  180. {metalist-0.8.0 → metalist-0.9.0}/app/services/html_export.py +0 -0
  181. {metalist-0.8.0 → metalist-0.9.0}/app/services/html_unformatting.py +0 -0
  182. {metalist-0.8.0 → metalist-0.9.0}/app/services/hydration_state.py +0 -0
  183. {metalist-0.8.0 → metalist-0.9.0}/app/services/image_size_formatting.py +0 -0
  184. {metalist-0.8.0 → metalist-0.9.0}/app/services/inline_image_occurrences.py +0 -0
  185. {metalist-0.8.0 → metalist-0.9.0}/app/services/input_errors.py +0 -0
  186. {metalist-0.8.0 → metalist-0.9.0}/app/services/integrity.py +0 -0
  187. {metalist-0.8.0 → metalist-0.9.0}/app/services/latex_rendering.py +0 -0
  188. {metalist-0.8.0 → metalist-0.9.0}/app/services/login_rate_limit.py +0 -0
  189. {metalist-0.8.0 → metalist-0.9.0}/app/services/maintenance_mode.py +0 -0
  190. {metalist-0.8.0 → metalist-0.9.0}/app/services/namespace_deletion_jobs.py +0 -0
  191. {metalist-0.8.0 → metalist-0.9.0}/app/services/namespace_deletion_worker.py +0 -0
  192. {metalist-0.8.0 → metalist-0.9.0}/app/services/namespace_rename_jobs.py +0 -0
  193. {metalist-0.8.0 → metalist-0.9.0}/app/services/namespace_rename_worker.py +0 -0
  194. {metalist-0.8.0 → metalist-0.9.0}/app/services/namespace_runtime_guard.py +0 -0
  195. {metalist-0.8.0 → metalist-0.9.0}/app/services/namespace_switcher.py +0 -0
  196. {metalist-0.8.0 → metalist-0.9.0}/app/services/note_fullscreen.py +0 -0
  197. {metalist-0.8.0 → metalist-0.9.0}/app/services/note_image_tags.py +0 -0
  198. {metalist-0.8.0 → metalist-0.9.0}/app/services/note_ordering.py +0 -0
  199. {metalist-0.8.0 → metalist-0.9.0}/app/services/note_store.py +0 -0
  200. {metalist-0.8.0 → metalist-0.9.0}/app/services/ontology_rules_store.py +0 -0
  201. {metalist-0.8.0 → metalist-0.9.0}/app/services/openai_credentials.py +0 -0
  202. {metalist-0.8.0 → metalist-0.9.0}/app/services/password_note_fields.py +0 -0
  203. {metalist-0.8.0 → metalist-0.9.0}/app/services/reference_presentation.py +0 -0
  204. {metalist-0.8.0 → metalist-0.9.0}/app/services/reminders.py +0 -0
  205. {metalist-0.8.0 → metalist-0.9.0}/app/services/request_recovery.py +0 -0
  206. {metalist-0.8.0 → metalist-0.9.0}/app/services/resource_limits.py +0 -0
  207. {metalist-0.8.0 → metalist-0.9.0}/app/services/root_sorting.py +0 -0
  208. {metalist-0.8.0 → metalist-0.9.0}/app/services/runtime_generation.py +0 -0
  209. {metalist-0.8.0 → metalist-0.9.0}/app/services/runtime_hardening.py +0 -0
  210. {metalist-0.8.0 → metalist-0.9.0}/app/services/search_history.py +0 -0
  211. {metalist-0.8.0 → metalist-0.9.0}/app/services/search_history_storage.py +0 -0
  212. {metalist-0.8.0 → metalist-0.9.0}/app/services/search_index.py +0 -0
  213. {metalist-0.8.0 → metalist-0.9.0}/app/services/search_query.py +0 -0
  214. {metalist-0.8.0 → metalist-0.9.0}/app/services/search_text.py +0 -0
  215. {metalist-0.8.0 → metalist-0.9.0}/app/services/selected_text_tag.py +0 -0
  216. {metalist-0.8.0 → metalist-0.9.0}/app/services/self_update.py +0 -0
  217. {metalist-0.8.0 → metalist-0.9.0}/app/services/session_timeout_service.py +0 -0
  218. {metalist-0.8.0 → metalist-0.9.0}/app/services/shell_session_service.py +0 -0
  219. {metalist-0.8.0 → metalist-0.9.0}/app/services/snapshot.py +0 -0
  220. {metalist-0.8.0 → metalist-0.9.0}/app/services/store.py +0 -0
  221. {metalist-0.8.0 → metalist-0.9.0}/app/services/structured_note_renderers.py +0 -0
  222. {metalist-0.8.0 → metalist-0.9.0}/app/services/sync.py +0 -0
  223. {metalist-0.8.0 → metalist-0.9.0}/app/services/sync_state.py +0 -0
  224. {metalist-0.8.0 → metalist-0.9.0}/app/services/tab_state.py +0 -0
  225. {metalist-0.8.0 → metalist-0.9.0}/app/services/tag_case.py +0 -0
  226. {metalist-0.8.0 → metalist-0.9.0}/app/services/tag_ontology.py +0 -0
  227. {metalist-0.8.0 → metalist-0.9.0}/app/services/tag_rename.py +0 -0
  228. {metalist-0.8.0 → metalist-0.9.0}/app/services/tag_suggestions.py +0 -0
  229. {metalist-0.8.0 → metalist-0.9.0}/app/services/tag_term_matching.py +0 -0
  230. {metalist-0.8.0 → metalist-0.9.0}/app/services/test_reset.py +0 -0
  231. {metalist-0.8.0 → metalist-0.9.0}/app/services/tokens.py +0 -0
  232. {metalist-0.8.0 → metalist-0.9.0}/app/services/undo_state.py +0 -0
  233. {metalist-0.8.0 → metalist-0.9.0}/app/services/update_backups.py +0 -0
  234. {metalist-0.8.0 → metalist-0.9.0}/app/services/update_installer.py +0 -0
  235. {metalist-0.8.0 → metalist-0.9.0}/app/services/update_preflight.py +0 -0
  236. {metalist-0.8.0 → metalist-0.9.0}/app/services/view_cache.py +0 -0
  237. {metalist-0.8.0 → metalist-0.9.0}/app/services/view_diff.py +0 -0
  238. {metalist-0.8.0 → metalist-0.9.0}/app/services/view_state.py +0 -0
  239. {metalist-0.8.0 → metalist-0.9.0}/app/services/windows_process_control.py +0 -0
  240. {metalist-0.8.0 → metalist-0.9.0}/app/startup_environment.py +0 -0
  241. {metalist-0.8.0 → metalist-0.9.0}/app/startup_js_sanity.py +0 -0
  242. {metalist-0.8.0 → metalist-0.9.0}/app/startup_sanity.py +0 -0
  243. {metalist-0.8.0 → metalist-0.9.0}/app/startup_sanity_config.py +0 -0
  244. {metalist-0.8.0 → metalist-0.9.0}/app/static/config/agent-menu-actions.json +0 -0
  245. {metalist-0.8.0 → metalist-0.9.0}/app/static/config/command_palette_tags.json +0 -0
  246. {metalist-0.8.0 → metalist-0.9.0}/app/static/css/floating-notes.css +0 -0
  247. {metalist-0.8.0 → metalist-0.9.0}/app/static/css/forms.css +0 -0
  248. {metalist-0.8.0 → metalist-0.9.0}/app/static/img/favicon.ico +0 -0
  249. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/locked.js +0 -0
  250. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/main.js +0 -0
  251. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/activity-tracker.js +0 -0
  252. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/agent-menu-actions.js +0 -0
  253. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/agent-prompt-service.js +0 -0
  254. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/agent-retrieval-settings.js +0 -0
  255. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/ai-agent-debug-view.js +0 -0
  256. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/ai-chat-api.js +0 -0
  257. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/ai-thinking-level-service.js +0 -0
  258. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/bulk-elapsed-clock.js +0 -0
  259. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/cloud-privacy-policy.js +0 -0
  260. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/ai-chat/proposal-menu.js +0 -0
  261. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/api-client.js +0 -0
  262. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/api-error-diagnostics.js +0 -0
  263. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/api-failure-classification-service.js +0 -0
  264. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/app-update-service.js +0 -0
  265. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/application-state.js +0 -0
  266. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/async-result.js +0 -0
  267. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/auth.js +0 -0
  268. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/client-state-api.js +0 -0
  269. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/client-state-migration.js +0 -0
  270. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/activation-auth-policy.js +0 -0
  271. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/backup-command-availability.js +0 -0
  272. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/click-activation-service.js +0 -0
  273. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/endpoint-registry.js +0 -0
  274. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/note-layout-preferences.js +0 -0
  275. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/preferences-store.js +0 -0
  276. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/tag-config-loader.js +0 -0
  277. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/command-palette/usage-store.js +0 -0
  278. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/config.js +0 -0
  279. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/connectivity-monitor.js +0 -0
  280. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/context-menu/context-menu-registry.js +0 -0
  281. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/context-menu/context-menu-service.js +0 -0
  282. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/context-menu/context-menu-target-service.js +0 -0
  283. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/context-menu/input-caret-service.js +0 -0
  284. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/disconnect-editing-state-service.js +0 -0
  285. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/dom-utils-fixed.js +0 -0
  286. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/dom-utils.js +0 -0
  287. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/editor-commands.js +0 -0
  288. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/editor-selection.js +0 -0
  289. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/editor-toolbar.js +0 -0
  290. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/elapsed-time.js +0 -0
  291. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/error-handler.js +0 -0
  292. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/error-overlay.js +0 -0
  293. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/expected-errors.js +0 -0
  294. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/location-flags.js +0 -0
  295. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/login-namespace-picker.js +0 -0
  296. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/maintenance.js +0 -0
  297. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/agent-prompt-editor-modal.js +0 -0
  298. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/alphabetize-root-notes-modal.js +0 -0
  299. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/backup-restore-modal.js +0 -0
  300. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/backup-result-modal.js +0 -0
  301. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/backup-retention-modal.js +0 -0
  302. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/backup-settings-modal.js +0 -0
  303. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/base-modal.js +0 -0
  304. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/confirmation-modal.js +0 -0
  305. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/delete-namespace-modal.js +0 -0
  306. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/delete-namespace-validation.js +0 -0
  307. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/help-modal.js +0 -0
  308. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/namespace-loading-page.js +0 -0
  309. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/namespace-modals.js +0 -0
  310. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/namespace-ports-profile.js +0 -0
  311. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/namespace-rename-validation.js +0 -0
  312. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/note-layout-appearance-modal.js +0 -0
  313. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/ontology-modal.js +0 -0
  314. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/password-modal.js +0 -0
  315. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/prioritize-modal.js +0 -0
  316. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/random-password-modal.js +0 -0
  317. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/reminder-modal.js +0 -0
  318. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/reset-updated-at-modal.js +0 -0
  319. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/search-suggestion-statistics-modal.js +0 -0
  320. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/session-timeout-modal.js +0 -0
  321. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/modals/version-info-modal.js +0 -0
  322. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/actions/content-actions.js +0 -0
  323. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/actions/history-actions.js +0 -0
  324. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/actions/search-actions.js +0 -0
  325. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/actions/selection-actions.js +0 -0
  326. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/actions/ui-actions.js +0 -0
  327. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/events/context-menu-events.js +0 -0
  328. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/events/focus-events.js +0 -0
  329. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/events/inactivity-events.js +0 -0
  330. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/events/input-events.js +0 -0
  331. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/events/search-events.js +0 -0
  332. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/mode-context.js +0 -0
  333. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/mode-logger.js +0 -0
  334. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/mode-manager-controller.js +0 -0
  335. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/add-style-service.js +0 -0
  336. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/animated-scroll-service.js +0 -0
  337. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/backlinks-navigation-service.js +0 -0
  338. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/backlinks-panel-service.js +0 -0
  339. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/clipboard-shortcut-policy-service.js +0 -0
  340. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/collapse-affordance-service.js +0 -0
  341. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/collapse-editing-policy-service.js +0 -0
  342. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/command-gate-service.js +0 -0
  343. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/context-menu-target-service.js +0 -0
  344. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/deselect-selection-state-service.js +0 -0
  345. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/differential-view-service.js +0 -0
  346. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/edit-session-collapse-service.js +0 -0
  347. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/embedded-image-service.js +0 -0
  348. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/file-drop-policy-service.js +0 -0
  349. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/file-image-preview-service.js +0 -0
  350. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/file-reference-service.js +0 -0
  351. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/filtered-refresh-selection-service.js +0 -0
  352. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/floating-note-dom.js +0 -0
  353. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/floating-note-layout.js +0 -0
  354. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/floating-note-service.js +0 -0
  355. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/footnote-navigation-service.js +0 -0
  356. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/history-selection-policy-service.js +0 -0
  357. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/history-shortcut-policy-service.js +0 -0
  358. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/html-paste-sanitizer-service.js +0 -0
  359. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/image-context-menu-action-service.js +0 -0
  360. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/image-file-insert-choice-modal-service.js +0 -0
  361. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/infinite-scroll-service.js +0 -0
  362. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/link-context-menu-action-service.js +0 -0
  363. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/link-title-prefetch-service.js +0 -0
  364. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/markdown-render-service.js +0 -0
  365. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/mermaid-render-service.js +0 -0
  366. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-clipboard-write-service.js +0 -0
  367. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-collapse-animation-service.js +0 -0
  368. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-context-menu-action-service.js +0 -0
  369. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-delete-shortcut-policy-service.js +0 -0
  370. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-drag-service.js +0 -0
  371. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-fullscreen-service.js +0 -0
  372. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-reposition-animation-service.js +0 -0
  373. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-split-service.js +0 -0
  374. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/note-timestamp-hover-service.js +0 -0
  375. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/password-clipboard-service.js +0 -0
  376. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/polling-service.js +0 -0
  377. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/remote-image-proxy-service.js +0 -0
  378. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/remove-formatting-service.js +0 -0
  379. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/root-date-separator-service.js +0 -0
  380. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/root-sort-indicator-service.js +0 -0
  381. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/root-sort-service.js +0 -0
  382. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/scroll-anchor-service.js +0 -0
  383. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/scroll-restoration-service.js +0 -0
  384. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/scroll-to-top-service.js +0 -0
  385. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-contexts-overlay-service.js +0 -0
  386. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-debounce-service.js +0 -0
  387. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-input-service.js +0 -0
  388. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-interaction-service.js +0 -0
  389. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-redaction-reveal-service.js +0 -0
  390. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-suggestion-statistics-service.js +0 -0
  391. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-suggestion-window-labels-service.js +0 -0
  392. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-suggestion-windows-service.js +0 -0
  393. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-suggestions-service.js +0 -0
  394. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/search-syntax-service.js +0 -0
  395. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/selected-formatting-removal-service.js +0 -0
  396. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/selected-text-tag-service.js +0 -0
  397. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/shell-output-service.js +0 -0
  398. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tab-dom-cache-service.js +0 -0
  399. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tab-drag-service.js +0 -0
  400. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tab-duplication-service.js +0 -0
  401. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tag-bar-service.js +0 -0
  402. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tag-input-selection-service.js +0 -0
  403. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tag-proposal-service.js +0 -0
  404. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tag-suggestions-service.js +0 -0
  405. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/tag-syntax-service.js +0 -0
  406. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/todo-toggle-editing-service.js +0 -0
  407. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/untagged-view-indicator-service.js +0 -0
  408. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/mode-manager/services/view-mode-search-shortcut-service.js +0 -0
  409. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/note-html-sanitizer.js +0 -0
  410. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/password-generator.js +0 -0
  411. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/password-operation-response.js +0 -0
  412. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/password-policy.js +0 -0
  413. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/password-strength.js +0 -0
  414. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/reminder-store.js +0 -0
  415. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/reminder-surface-service.js +0 -0
  416. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/selection-markers.js +0 -0
  417. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/session-auth.js +0 -0
  418. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/tag-token.js +0 -0
  419. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/modules/uuid.js +0 -0
  420. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/namespace-deleted.js +0 -0
  421. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/namespace-renamed.js +0 -0
  422. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/dompurify-3.4.13.LICENSE.txt +0 -0
  423. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/dompurify-3.4.13.min.js +0 -0
  424. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/markdown-it-14.3.2.LICENSE.txt +0 -0
  425. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/markdown-it-14.3.2.min.js +0 -0
  426. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/mermaid-11.16.1.LICENSE.txt +0 -0
  427. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/mermaid-11.16.1.min.js +0 -0
  428. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/zxcvbn-4.4.2.LICENSE.txt +0 -0
  429. {metalist-0.8.0 → metalist-0.9.0}/app/static/js/vendor/zxcvbn-4.4.2.js +0 -0
  430. {metalist-0.8.0 → metalist-0.9.0}/app/static/note-html-policy.json +0 -0
  431. {metalist-0.8.0 → metalist-0.9.0}/app/static/video/login-startup.mp4 +0 -0
  432. {metalist-0.8.0 → metalist-0.9.0}/app/templates/base.html +0 -0
  433. {metalist-0.8.0 → metalist-0.9.0}/app/templates/locked.html +0 -0
  434. {metalist-0.8.0 → metalist-0.9.0}/app/templates/maintenance.html +0 -0
  435. {metalist-0.8.0 → metalist-0.9.0}/app/templates/namespace_deleted.html +0 -0
  436. {metalist-0.8.0 → metalist-0.9.0}/app/templates/namespace_renamed.html +0 -0
  437. {metalist-0.8.0 → metalist-0.9.0}/app/templates/notes_list.html +0 -0
  438. {metalist-0.8.0 → metalist-0.9.0}/app/upload_limits.py +0 -0
  439. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/__init__.py +0 -0
  440. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/add_selected_text_tag.py +0 -0
  441. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/alphabetize_root_notes.py +0 -0
  442. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/base.py +0 -0
  443. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/bulk_tag_proposals.py +0 -0
  444. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/collapse.py +0 -0
  445. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/copy_note.py +0 -0
  446. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/create_child.py +0 -0
  447. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/create_note.py +0 -0
  448. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/create_sibling.py +0 -0
  449. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/delete_subtree.py +0 -0
  450. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/delete_tag.py +0 -0
  451. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/expand.py +0 -0
  452. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/indent.py +0 -0
  453. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/lock.py +0 -0
  454. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/move.py +0 -0
  455. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/move_to_top.py +0 -0
  456. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/outdent.py +0 -0
  457. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/paste_child.py +0 -0
  458. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/paste_sibling.py +0 -0
  459. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/prefetch_link_titles.py +0 -0
  460. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/prioritize.py +0 -0
  461. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/redo.py +0 -0
  462. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/rename_tag.py +0 -0
  463. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/reset_updated_at.py +0 -0
  464. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/resize_image.py +0 -0
  465. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/run_shell.py +0 -0
  466. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/search_comment_autofill.py +0 -0
  467. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/search_context_tags.py +0 -0
  468. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/set_collapse_bulk.py +0 -0
  469. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/set_collapse_in_context.py +0 -0
  470. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/split_note.py +0 -0
  471. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/tag_proposals.py +0 -0
  472. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/toggle_reference_mode.py +0 -0
  473. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/toggle_todo_done.py +0 -0
  474. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/undo.py +0 -0
  475. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/unformat_content.py +0 -0
  476. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/update_content.py +0 -0
  477. {metalist-0.8.0 → metalist-0.9.0}/app/usecases/view.py +0 -0
  478. {metalist-0.8.0 → metalist-0.9.0}/app/utils/__init__.py +0 -0
  479. {metalist-0.8.0 → metalist-0.9.0}/app/utils/encryption.py +0 -0
  480. {metalist-0.8.0 → metalist-0.9.0}/app/utils/text_utils.py +0 -0
  481. {metalist-0.8.0 → metalist-0.9.0}/convert-from-legacy.py +0 -0
  482. {metalist-0.8.0 → metalist-0.9.0}/main.py +0 -0
  483. {metalist-0.8.0 → metalist-0.9.0}/metalist.egg-info/dependency_links.txt +0 -0
  484. {metalist-0.8.0 → metalist-0.9.0}/metalist.egg-info/entry_points.txt +0 -0
  485. {metalist-0.8.0 → metalist-0.9.0}/metalist.egg-info/top_level.txt +0 -0
  486. {metalist-0.8.0 → metalist-0.9.0}/scripts/generate-lan-cert.sh +0 -0
  487. {metalist-0.8.0 → metalist-0.9.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metalist
3
- Version: 0.8.0
3
+ Version: 0.9.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
@@ -20,6 +20,7 @@ Requires-Dist: nh3==0.3.6
20
20
  Requires-Dist: openai==2.54.0
21
21
  Requires-Dist: pillow==12.3.0
22
22
  Requires-Dist: pydantic==2.13.4
23
+ Requires-Dist: pypdf==6.19.0
23
24
  Requires-Dist: python-dotenv==1.2.2
24
25
  Requires-Dist: python-multipart==0.0.32
25
26
  Requires-Dist: starlette==1.3.1
@@ -48,6 +49,12 @@ A minimalist single-user note-taking app focused on server-side rendering (SSR),
48
49
  - Multi-tab search contexts with server-persisted scroll/search state (survives browser restarts)
49
50
  - Manual namespace backups/restores to a user-selected backup folder with retention controls
50
51
 
52
+ ## Changes in 0.9.0
53
+
54
+ - AI chat can browse the web in disabled, contextual, or unrestricted mode, fetch multiple pages concurrently, and cite the specific pages used as evidence.
55
+ - Complete-scope summaries and tag suggestions can process every permitted note in bounded parallel batches after user approval, with visible per-batch progress and final synthesis.
56
+ - AI chat retains selected-note and tree context while enforcing redaction boundaries, and reference navigation uses temporary result collections without polluting search history.
57
+
51
58
  ## Changes in 0.8.0
52
59
 
53
60
  - Error diagnostics now record safe request IDs, exception types, and source locations through Loguru; full tracebacks are available only in authenticated encrypted logs.
@@ -361,7 +368,7 @@ This repo now packages itself under the PyPI distribution name `metalist`. Curre
361
368
 
362
369
  Recommended release path:
363
370
  1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
364
- 2. Develop and review the candidate on a feature branch with focused checks. Merge it into `main` and push `main` once. This runs the full `Publish to PyPI` validation matrix for that exact commit. GitHub-hosted Windows, macOS, and Linux runners install the built wheel and test application startup outside the source checkout on Python 3.10 through 3.14. Every installed-package matrix job also exercises the real `metalist update` path with uv, backups, interpreter preservation, and two-namespace restart against a local release index. The old-version fixture carries the candidate updater so this validates the mechanism being shipped; it does not retroactively fix older installed updaters. You do not need those operating systems locally. Archive verification checks runtime files, including agent Markdown resources, against both the wheel and source distribution.
371
+ 2. Develop and review the candidate on a feature branch with focused checks. Merge it into `main` and push `main` once. This runs the full `Publish to PyPI` validation matrix for that exact commit. GitHub-hosted Windows, macOS, and Linux runners install the built wheel and test application startup outside the source checkout on the supported Python endpoints, 3.10 and 3.14. Every installed-package matrix job also exercises the real `metalist update` path with uv, backups, interpreter preservation, and two-namespace restart against a local release index. The old-version fixture carries the candidate updater so this validates the mechanism being shipped; it does not retroactively fix older installed updaters. You do not need those operating systems locally. Archive verification checks runtime files, including agent Markdown resources, against both the wheel and source distribution.
365
372
  3. Wait for the exact-commit main release matrix to pass, then run `.venv/bin/python scripts/release.py X.Y.Z` to create and push the tag. Any intervening change requires a new main validation run before tagging.
366
373
  4. The tag job independently verifies every main-job conclusion and reuses the wheel and source distribution from that run for GitHub Trusted Publishing; it does not repeat the matrix. Manual dispatch cannot publish. The release driver compares PyPI hashes with the tested artifact and checks a clean public install. Users can then run it with `uvx metalist`, install it persistently with `uv tool install metalist`, or install it with `pip install metalist`.
367
374
 
@@ -12,6 +12,12 @@ 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.9.0
16
+
17
+ - AI chat can browse the web in disabled, contextual, or unrestricted mode, fetch multiple pages concurrently, and cite the specific pages used as evidence.
18
+ - Complete-scope summaries and tag suggestions can process every permitted note in bounded parallel batches after user approval, with visible per-batch progress and final synthesis.
19
+ - AI chat retains selected-note and tree context while enforcing redaction boundaries, and reference navigation uses temporary result collections without polluting search history.
20
+
15
21
  ## Changes in 0.8.0
16
22
 
17
23
  - Error diagnostics now record safe request IDs, exception types, and source locations through Loguru; full tracebacks are available only in authenticated encrypted logs.
@@ -325,7 +331,7 @@ This repo now packages itself under the PyPI distribution name `metalist`. Curre
325
331
 
326
332
  Recommended release path:
327
333
  1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
328
- 2. Develop and review the candidate on a feature branch with focused checks. Merge it into `main` and push `main` once. This runs the full `Publish to PyPI` validation matrix for that exact commit. GitHub-hosted Windows, macOS, and Linux runners install the built wheel and test application startup outside the source checkout on Python 3.10 through 3.14. Every installed-package matrix job also exercises the real `metalist update` path with uv, backups, interpreter preservation, and two-namespace restart against a local release index. The old-version fixture carries the candidate updater so this validates the mechanism being shipped; it does not retroactively fix older installed updaters. You do not need those operating systems locally. Archive verification checks runtime files, including agent Markdown resources, against both the wheel and source distribution.
334
+ 2. Develop and review the candidate on a feature branch with focused checks. Merge it into `main` and push `main` once. This runs the full `Publish to PyPI` validation matrix for that exact commit. GitHub-hosted Windows, macOS, and Linux runners install the built wheel and test application startup outside the source checkout on the supported Python endpoints, 3.10 and 3.14. Every installed-package matrix job also exercises the real `metalist update` path with uv, backups, interpreter preservation, and two-namespace restart against a local release index. The old-version fixture carries the candidate updater so this validates the mechanism being shipped; it does not retroactively fix older installed updaters. You do not need those operating systems locally. Archive verification checks runtime files, including agent Markdown resources, against both the wheel and source distribution.
329
335
  3. Wait for the exact-commit main release matrix to pass, then run `.venv/bin/python scripts/release.py X.Y.Z` to create and push the tag. Any intervening change requires a new main validation run before tagging.
330
336
  4. The tag job independently verifies every main-job conclusion and reuses the wheel and source distribution from that run for GitHub Trusted Publishing; it does not repeat the matrix. Manual dispatch cannot publish. The release driver compares PyPI hashes with the tested artifact and checks a clean public install. Users can then run it with `uvx metalist`, install it persistently with `uv tool install metalist`, or install it with `pip install metalist`.
331
337
 
@@ -8,6 +8,10 @@ from pydantic import AfterValidator, ConfigDict, Field, with_config
8
8
  Identifier = Annotated[str, Field(min_length=1, max_length=256)]
9
9
  Text = Annotated[str, Field(max_length=1024 * 1024)]
10
10
  Content = Annotated[str, Field(max_length=16 * 1024 * 1024)]
11
+ # Clients build undo contexts as "tab:<id>|search:<executed query>|epoch:<n>", so the
12
+ # limit must admit any Text-sized search query (for example an "Open all references"
13
+ # query ORing every cited note ID) plus that small fixed envelope.
14
+ UndoContext = Annotated[str, Field(min_length=1, max_length=1024 * 1024 + 1024)]
11
15
  Nonnegative = Annotated[int, Field(ge=0)]
12
16
 
13
17
 
@@ -51,7 +55,7 @@ class ViewDiffRequest(TypedDict):
51
55
  editingNoteId: Text | None
52
56
  search: Text | None
53
57
  tabId: Identifier
54
- undoContext: Identifier
58
+ undoContext: UndoContext
55
59
  clientNoteUuidHashes: dict[Identifier, Text]
56
60
  visibleRootAnchorId: Text | None
57
61
  isUntaggedView: bool
@@ -67,7 +71,7 @@ class UpdateTabSortModeRequest(TypedDict):
67
71
  tabId: Identifier
68
72
  sortMode: Literal['normal', 'created', 'updated', 'alphabetical', 'content-volume']
69
73
  clientId: Identifier
70
- undoContext: Identifier
74
+ undoContext: UndoContext
71
75
 
72
76
  @with_config(ConfigDict(strict=True))
73
77
  class CreateNewTabRequest(TypedDict):
@@ -113,21 +117,21 @@ class CreateNoteTopRequest(TypedDict):
113
117
  first_visible_note_id: Text | None
114
118
  search_query: Text | None
115
119
  clientId: Identifier
116
- undoContext: Identifier
120
+ undoContext: UndoContext
117
121
  viewport: Viewport
118
122
 
119
123
  @with_config(ConfigDict(strict=True))
120
124
  class CreateSiblingRequest(TypedDict):
121
125
  search_query: Text | None
122
126
  clientId: Identifier
123
- undoContext: Identifier
127
+ undoContext: UndoContext
124
128
  viewport: Viewport
125
129
 
126
130
  @with_config(ConfigDict(strict=True))
127
131
  class CreateChildRequest(TypedDict):
128
132
  search_query: Text | None
129
133
  clientId: Identifier
130
- undoContext: Identifier
134
+ undoContext: UndoContext
131
135
  viewport: Viewport
132
136
 
133
137
  @with_config(ConfigDict(strict=True))
@@ -135,7 +139,7 @@ class UpdateNoteRequest(TypedDict):
135
139
  clientId: Identifier
136
140
  content: Content
137
141
  tags: Text
138
- undoContext: Identifier
142
+ undoContext: UndoContext
139
143
  viewport: Viewport
140
144
 
141
145
  @with_config(ConfigDict(strict=True))
@@ -143,34 +147,34 @@ class SaveNoteRequest(TypedDict):
143
147
  clientId: Identifier
144
148
  content: Content
145
149
  tags: Text
146
- undoContext: Identifier
150
+ undoContext: UndoContext
147
151
  viewport: Viewport
148
152
 
149
153
  @with_config(ConfigDict(strict=True))
150
154
  class AddSelectedTextTagRequest(TypedDict):
151
155
  selectedText: Identifier
152
156
  clientId: Identifier
153
- undoContext: Identifier
157
+ undoContext: UndoContext
154
158
  viewport: Viewport
155
159
 
156
160
  @with_config(ConfigDict(strict=True))
157
161
  class MakePseudoTagProposalsRequest(TypedDict):
158
162
  clientId: Identifier
159
- undoContext: Identifier
163
+ undoContext: UndoContext
160
164
  viewport: Viewport
161
165
 
162
166
  @with_config(ConfigDict(strict=True))
163
167
  class AcceptTagProposalRequest(TypedDict):
164
168
  proposal: Identifier
165
169
  clientId: Identifier
166
- undoContext: Identifier
170
+ undoContext: UndoContext
167
171
  viewport: Viewport
168
172
 
169
173
  @with_config(ConfigDict(strict=True))
170
174
  class RejectTagProposalRequest(TypedDict):
171
175
  proposal: Identifier
172
176
  clientId: Identifier
173
- undoContext: Identifier
177
+ undoContext: UndoContext
174
178
  viewport: Viewport
175
179
 
176
180
  @with_config(ConfigDict(strict=True))
@@ -178,19 +182,19 @@ class SplitNoteRequest(TypedDict):
178
182
  clientId: Identifier
179
183
  segments: Annotated[list[Content], Field(min_length=1)]
180
184
  tags: Text
181
- undoContext: Identifier
185
+ undoContext: UndoContext
182
186
  viewport: Viewport
183
187
 
184
188
  @with_config(ConfigDict(strict=True))
185
189
  class ToggleTodoDoneRequest(TypedDict):
186
190
  clientId: Identifier
187
- undoContext: Identifier
191
+ undoContext: UndoContext
188
192
  viewport: Viewport
189
193
 
190
194
  @with_config(ConfigDict(strict=True))
191
195
  class UnformatNoteContentRequest(TypedDict):
192
196
  clientId: Identifier
193
- undoContext: Identifier
197
+ undoContext: UndoContext
194
198
  viewport: Viewport
195
199
 
196
200
  @with_config(ConfigDict(strict=True))
@@ -199,7 +203,7 @@ class ResizeNoteImageRequest(TypedDict):
199
203
  sourceKind: Literal['inline', 'file']
200
204
  occurrenceIndex: Nonnegative
201
205
  action: Literal['bigger', 'smaller', 'reset']
202
- undoContext: Identifier
206
+ undoContext: UndoContext
203
207
  viewport: Viewport
204
208
 
205
209
  @with_config(ConfigDict(strict=True))
@@ -212,7 +216,7 @@ class ToggleReferenceModeEndpointRequest(TypedDict):
212
216
  occurrence_index: Nonnegative
213
217
  mode: Literal['embed', 'link']
214
218
  clientId: Identifier
215
- undoContext: Identifier
219
+ undoContext: UndoContext
216
220
  viewport: Viewport
217
221
 
218
222
  @with_config(ConfigDict(strict=True))
@@ -222,7 +226,7 @@ class MoveNoteEndpointRequest(TypedDict):
222
226
  sibling_id: Identifier
223
227
  position: Literal['BEFORE', 'AFTER']
224
228
  clientId: Identifier
225
- undoContext: Identifier
229
+ undoContext: UndoContext
226
230
  viewport: Viewport
227
231
 
228
232
  @with_config(ConfigDict(strict=True))
@@ -230,33 +234,33 @@ class MoveNoteToTopEndpointRequest(TypedDict):
230
234
  search_query: Text | None
231
235
  tab_id: Identifier
232
236
  clientId: Identifier
233
- undoContext: Identifier
237
+ undoContext: UndoContext
234
238
  viewport: Viewport
235
239
 
236
240
  @with_config(ConfigDict(strict=True))
237
241
  class IndentNoteEndpointRequest(TypedDict):
238
242
  visible_prev_id: Text | None
239
243
  clientId: Identifier
240
- undoContext: Identifier
244
+ undoContext: UndoContext
241
245
  viewport: Viewport
242
246
 
243
247
  @with_config(ConfigDict(strict=True))
244
248
  class OutdentNoteEndpointRequest(TypedDict):
245
249
  search_query: Text | None
246
250
  clientId: Identifier
247
- undoContext: Identifier
251
+ undoContext: UndoContext
248
252
  viewport: Viewport
249
253
 
250
254
  @with_config(ConfigDict(strict=True))
251
255
  class CollapseEndpointRequest(TypedDict):
252
256
  clientId: Identifier
253
- undoContext: Identifier
257
+ undoContext: UndoContext
254
258
  viewport: Viewport
255
259
 
256
260
  @with_config(ConfigDict(strict=True))
257
261
  class ExpandEndpointRequest(TypedDict):
258
262
  clientId: Identifier
259
- undoContext: Identifier
263
+ undoContext: UndoContext
260
264
  viewport: Viewport
261
265
 
262
266
  @with_config(ConfigDict(strict=True))
@@ -264,7 +268,7 @@ class SetCollapsedBulkEndpointRequest(TypedDict):
264
268
  note_ids: Annotated[list[Identifier], Field(min_length=1)]
265
269
  collapsed: bool
266
270
  clientId: Identifier
267
- undoContext: Identifier
271
+ undoContext: UndoContext
268
272
  viewport: Viewport
269
273
 
270
274
  @with_config(ConfigDict(strict=True))
@@ -273,14 +277,14 @@ class SetCollapsedInContextEndpointRequest(TypedDict):
273
277
  collapsed: bool
274
278
  recursive: bool
275
279
  clientId: Identifier
276
- undoContext: Identifier
280
+ undoContext: UndoContext
277
281
  viewport: Viewport
278
282
 
279
283
  @with_config(ConfigDict(strict=True))
280
284
  class SetCollapsedSubtreeEndpointRequest(TypedDict):
281
285
  collapsed: bool
282
286
  clientId: Identifier
283
- undoContext: Identifier
287
+ undoContext: UndoContext
284
288
  viewport: Viewport
285
289
 
286
290
  @with_config(ConfigDict(strict=True))
@@ -290,7 +294,7 @@ class PrioritizeInViewEndpointRequest(TypedDict):
290
294
  search_query: Text | None
291
295
  tab_id: Identifier
292
296
  clientId: Identifier
293
- undoContext: Identifier
297
+ undoContext: UndoContext
294
298
  viewport: Viewport
295
299
 
296
300
  @with_config(ConfigDict(strict=True))
@@ -299,20 +303,20 @@ class AlphabetizeRootNotesEndpointRequest(TypedDict):
299
303
  search_query: Text | None
300
304
  tab_id: Identifier
301
305
  clientId: Identifier
302
- undoContext: Identifier
306
+ undoContext: UndoContext
303
307
  viewport: Viewport
304
308
 
305
309
  @with_config(ConfigDict(strict=True))
306
310
  class ResetUpdatedAtToCreatedAtEndpointRequest(TypedDict):
307
311
  search_query: Text | None
308
312
  clientId: Identifier
309
- undoContext: Identifier
313
+ undoContext: UndoContext
310
314
  viewport: Viewport
311
315
 
312
316
  @with_config(ConfigDict(strict=True))
313
317
  class DeleteNoteRequest(TypedDict):
314
318
  clientId: Identifier
315
- undoContext: Identifier
319
+ undoContext: UndoContext
316
320
  viewport: Viewport
317
321
 
318
322
  @with_config(ConfigDict(strict=True))
@@ -323,13 +327,13 @@ class CopyNoteEndpointRequest(TypedDict):
323
327
  class PasteSiblingEndpointRequest(TypedDict):
324
328
  search_query: Text | None
325
329
  clientId: Identifier
326
- undoContext: Identifier
330
+ undoContext: UndoContext
327
331
  viewport: Viewport
328
332
 
329
333
  @with_config(ConfigDict(strict=True))
330
334
  class PasteChildEndpointRequest(TypedDict):
331
335
  search_query: Text | None
332
336
  clientId: Identifier
333
- undoContext: Identifier
337
+ undoContext: UndoContext
334
338
  viewport: Viewport
335
339
 
@@ -20,6 +20,7 @@ from app.models.utils import render_note_data_read_only
20
20
  from app.services.ai_chat_stream import ChatTurnStream
21
21
  from app.services.ai_chat import ai_chat_store
22
22
  from app.services.ai_chat_rendering import find_note_citation_ids
23
+ from app.services.ai_chat_rendering import find_web_citation_ids
23
24
  from app.services.ai_chat_rendering import render_ai_chat_markdown_to_html
24
25
  from app.services.agent.context import AgentContextBuilder
25
26
  from app.services.agent.cloud_privacy import cloud_privacy_evaluator
@@ -58,6 +59,9 @@ from app.services.openai_credentials import validate_openai_api_key
58
59
  from app.services.sync import set_clipboard, get_current_sync_uuid
59
60
  from app.services.agent.tagging_run import TaggingRun, proposal_scope_ids
60
61
  from app.services.agent.retrieval_settings import resolve_tagging_batch_tokens
62
+ from app.services.agent.web_settings import AgentWebSettings
63
+ from app.services.agent.web_settings import resolve_agent_web_settings
64
+ from app.services.agent.web_evidence import web_evidence_store
61
65
  from app.services.agent.tagging import TAGGING_PROMPT_KEY, TAGGING_POLICY_KEY, DEFAULT_TAGGING_PROMPT
62
66
  from app.usecases.bulk_tag_proposals import apply_bulk_proposals, prepare_proposal_changes
63
67
  from app.services.bulk_operation import bulk_operation_guard
@@ -249,7 +253,7 @@ class AiCopyMessageResponse(BaseModel):
249
253
  tags: str
250
254
 
251
255
 
252
- def _render_ai_response_note_content(markdown_text: str) -> str:
256
+ def _render_ai_response_note_content(*, markdown_text: str, session_key: str) -> str:
253
257
  if not isinstance(markdown_text, str) or markdown_text == "":
254
258
  raise ValueError("AI response Markdown must be a non-empty string")
255
259
  allowed_note_ids = find_note_citation_ids(
@@ -260,6 +264,10 @@ def _render_ai_response_note_content(markdown_text: str) -> str:
260
264
  markdown_text,
261
265
  notes=note_store,
262
266
  allowed_note_ids=allowed_note_ids,
267
+ allowed_web_evidence=web_evidence_store.available_references_for_ids(
268
+ session_key=session_key,
269
+ evidence_ids=find_web_citation_ids(markdown_text),
270
+ ),
263
271
  )
264
272
  if rendered_content == "":
265
273
  raise RuntimeError("Completed AI response rendered to empty HTML")
@@ -461,6 +469,10 @@ def get_ai_session(
461
469
  message["content"],
462
470
  notes=note_store,
463
471
  allowed_note_ids=allowed_note_ids,
472
+ allowed_web_evidence=web_evidence_store.available_references_for_ids(
473
+ session_key=session_key,
474
+ evidence_ids=find_web_citation_ids(message["content"]),
475
+ ),
464
476
  )
465
477
  if message["role"] == "assistant" and message["thinking"] != "":
466
478
  rendered_thinking = render_markdown_to_html(message["thinking"])
@@ -502,6 +514,7 @@ def clear_ai_session(
502
514
  response.headers["Cache-Control"] = "no-store"
503
515
  session_key = token_service.get_session_key(token)
504
516
  ai_chat_store.clear_session(session_key=session_key)
517
+ web_evidence_store.clear_session(session_key=session_key)
505
518
  agent_trace_store.clear_trace(session_key=session_key)
506
519
  return AiClearResponse(message="Chat cleared")
507
520
 
@@ -576,7 +589,10 @@ def copy_ai_message(
576
589
  raise HTTPException(status_code=409, detail="AI response is empty")
577
590
 
578
591
  tags = "@llm"
579
- note_content = _render_ai_response_note_content(content)
592
+ note_content = _render_ai_response_note_content(
593
+ markdown_text=content,
594
+ session_key=session_key,
595
+ )
580
596
  clipboard_record = {
581
597
  "id": f"ai-chat:{message_id}",
582
598
  "parent_id": None,
@@ -585,6 +601,7 @@ def copy_ai_message(
585
601
  "is_collapsed": False,
586
602
  "content": note_content,
587
603
  "tags": tags,
604
+ "proposed_tags": "",
588
605
  }
589
606
  set_clipboard(payload.client_id, [clipboard_record])
590
607
 
@@ -626,6 +643,7 @@ def stream_ai_chat(
626
643
  preferences=preferences,
627
644
  provider=payload.provider,
628
645
  )
646
+ web_settings = resolve_agent_web_settings(preferences=preferences)
629
647
  privacy_boundary = resolve_cloud_privacy_boundary(
630
648
  preferences=preferences,
631
649
  provider=payload.provider,
@@ -660,10 +678,12 @@ def stream_ai_chat(
660
678
  )
661
679
  tagging_run = TaggingRun(token=token, snapshot=frozen_scope, preferences=preferences, sync_uuid=get_current_sync_uuid(),
662
680
  batch_tokens=resolve_tagging_batch_tokens(preferences, payload.provider))
663
- ai_chat_store.synchronize_disclosure_boundary(
681
+ disclosure_changed = ai_chat_store.synchronize_disclosure_boundary(
664
682
  session_key=session_key,
665
683
  disclosure_key=cloud_privacy_evaluator.history_disclosure_key(boundary=privacy_boundary),
666
684
  )
685
+ if disclosure_changed:
686
+ web_evidence_store.clear_session(session_key=session_key)
667
687
  turn_id = ai_chat_store.start_turn(
668
688
  session_key=session_key,
669
689
  user_content=payload.message,
@@ -677,11 +697,13 @@ def stream_ai_chat(
677
697
  )
678
698
  initial_approx_input_tokens = estimate_input_tokens(initial_messages)
679
699
 
680
- turn_stream = ChatTurnStream(store=ai_chat_store, notes=note_store, session_key=session_key,
700
+ turn_stream = ChatTurnStream(store=ai_chat_store, notes=note_store,
701
+ web_evidence_store=web_evidence_store, session_key=session_key,
681
702
  turn_id=turn_id, initial_input_tokens=initial_approx_input_tokens)
682
703
  events = _stream_runtime_events(payload=payload, openai_api_key=openai_api_key,
683
704
  session_key=session_key, provider_messages=provider_messages, prompts=prompts, skills=skills,
684
705
  retrieval_settings=retrieval_settings, frozen_scope=frozen_scope, tagging_run=tagging_run,
706
+ web_settings=web_settings,
685
707
  initial_input_tokens=initial_approx_input_tokens)
686
708
 
687
709
  return StreamingResponse(
@@ -699,7 +721,7 @@ async def _stream_runtime_events(
699
721
  *, payload: AiChatRequest, openai_api_key: str, session_key: str,
700
722
  provider_messages: list[dict[str, str]], prompts: AgentPromptSet, skills: AgentSkillSet,
701
723
  retrieval_settings: AgentRetrievalSettings, frozen_scope: ScopedSearchSnapshot,
702
- tagging_run: TaggingRun, initial_input_tokens: int,
724
+ tagging_run: TaggingRun, initial_input_tokens: int, web_settings: AgentWebSettings,
703
725
  ) -> AsyncIterator[dict[str, object]]:
704
726
  action, start_label = 'provider_runtime', 'Connecting to OpenAI API'
705
727
  ready_label = 'OpenAI API ready · 1,050,000-token context'
@@ -712,7 +734,8 @@ async def _stream_runtime_events(
712
734
  events = runtime.stream_scoped(session_key=session_key, base_url=base_url,
713
735
  selected_model=payload.model, thinking_level=payload.thinking_level,
714
736
  canonical_messages=provider_messages, prompts=prompts, skills=skills,
715
- retrieval_settings=retrieval_settings, frozen_scope=frozen_scope, tag_handler=tagging_run.stream)
737
+ retrieval_settings=retrieval_settings, web_settings=web_settings,
738
+ frozen_scope=frozen_scope, tag_handler=tagging_run.stream)
716
739
  try:
717
740
  async for event in events:
718
741
  yield event
@@ -735,7 +758,20 @@ async def acknowledge_menu_result(payload: MenuResult, token: Annotated[str, Dep
735
758
  class BulkAnswerRequest(BaseModel):
736
759
  model_config = ConfigDict(extra="forbid")
737
760
  question_id: str = Field(..., min_length=1)
738
- value: Literal["existing", "new", "proceed", "cancel", "focus_existing", "focus_new", "focus_both"]
761
+ value: Literal[
762
+ "existing",
763
+ "new",
764
+ "proceed",
765
+ "cancel",
766
+ "focus_existing",
767
+ "focus_new",
768
+ "focus_both",
769
+ "prefix_focus_existing",
770
+ "prefix_focus_new",
771
+ "prefix_focus_both",
772
+ "summarize_all",
773
+ "use_prefix",
774
+ ]
739
775
 
740
776
 
741
777
  @router.post("/proposals/answer")
@@ -52,6 +52,7 @@ from app.security.sensitive_logging import traceback_frame_summary
52
52
  from app.services.encryption import EncryptionService
53
53
  from app.services.tokens import token_service
54
54
  from app.services.ai_chat import ai_chat_store
55
+ from app.services.agent.web_evidence import web_evidence_store
55
56
  from app.services.agent.trace import agent_trace_store
56
57
  from app.services.note_store import store as note_store
57
58
  from app.services.sync import clear_all_locks
@@ -383,6 +384,7 @@ def _reset_runtime_state_after_restore() -> bool:
383
384
  invalidate_runtime_work()
384
385
  clear_sensitive_caches()
385
386
  ai_chat_store.reset()
387
+ web_evidence_store.reset()
386
388
  agent_trace_store.reset()
387
389
  openai_credential_store.reset()
388
390
  view_cache.clear()
@@ -563,6 +565,7 @@ def login(
563
565
  invalidate_runtime_work()
564
566
  clear_sensitive_caches()
565
567
  ai_chat_store.reset()
568
+ web_evidence_store.reset()
566
569
  agent_trace_store.reset()
567
570
  openai_credential_store.reset()
568
571
  view_cache.clear()
@@ -587,6 +590,7 @@ def logout(
587
590
  ):
588
591
  session_key = token_service.get_session_key(token)
589
592
  ai_chat_store.clear_session(session_key=session_key)
593
+ web_evidence_store.clear_session(session_key=session_key)
590
594
  agent_trace_store.clear_session(session_key=session_key)
591
595
  openai_credential_store.clear_session(session_key=session_key)
592
596
  token_service.revoke_token(token)
@@ -674,6 +678,7 @@ def create_passwordless_session(
674
678
  invalidate_runtime_work()
675
679
  clear_sensitive_caches()
676
680
  ai_chat_store.reset()
681
+ web_evidence_store.reset()
677
682
  agent_trace_store.reset()
678
683
  openai_credential_store.reset()
679
684
  view_cache.clear()
@@ -1089,6 +1094,7 @@ def create_password(
1089
1094
  invalidate_runtime_work()
1090
1095
  clear_sensitive_caches()
1091
1096
  ai_chat_store.reset()
1097
+ web_evidence_store.reset()
1092
1098
  agent_trace_store.reset()
1093
1099
  openai_credential_store.reset()
1094
1100
  clear_all_locks()
@@ -1118,6 +1124,7 @@ def change_password(
1118
1124
  invalidate_runtime_work()
1119
1125
  clear_sensitive_caches()
1120
1126
  ai_chat_store.reset()
1127
+ web_evidence_store.reset()
1121
1128
  agent_trace_store.reset()
1122
1129
  openai_credential_store.reset()
1123
1130
  clear_all_locks()
@@ -1139,6 +1146,7 @@ def remove_password(
1139
1146
  invalidate_runtime_work()
1140
1147
  clear_sensitive_caches()
1141
1148
  ai_chat_store.reset()
1149
+ web_evidence_store.reset()
1142
1150
  agent_trace_store.reset()
1143
1151
  openai_credential_store.reset()
1144
1152
  clear_all_locks()
@@ -5,6 +5,16 @@ syntax suppressions and is consumed by runtime capture and the startup gate.
5
5
  """
6
6
 
7
7
  CAPTURE_BOUNDARIES = {
8
+ # Web retrieval translates only expected failures from untrusted remote targets.
9
+ 'app/services/agent/web_fetch.py:fetch_web_page:target_capture': ('PublicHttpTargetRejected',),
10
+ 'app/services/agent/web_fetch.py:_download_one_url:transport_capture': (
11
+ 'TimeoutException', 'NetworkError', 'HTTPError',
12
+ 'TimeoutException', 'NetworkError', 'ProtocolError',
13
+ ),
14
+ 'app/services/agent/web_fetch.py:_extract_pdf_content:pdf_capture': ('PyPdfError',),
15
+ 'app/services/agent/web_fetch.py:_decode_web_text:encoding_capture': ('LookupError',),
16
+ 'app/services/agent/web_fetch.py:handle_starttag:join_capture': ('ValueError',),
17
+ 'app/services/agent/runtime.py:_open_web_action:evidence_capacity_capture': ('WebEvidenceCapacityError',),
8
18
  # In-app updates translate only external transport, installation eligibility and job lookup errors.
9
19
  'app/services/app_updates.py:check_for_update:eligibility': ('AppUpdateRejected',),
10
20
  'app/services/app_updates.py:job_path:validation': ('ValueError',),
@@ -106,11 +116,12 @@ CAPTURE_BOUNDARIES = {
106
116
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
107
117
  'app/services/link_titles.py:_fetch_one_url:capture': ('TimeoutException', 'NetworkError', 'HTTPError', 'TimeoutException', 'NetworkError', 'ProtocolError'),
108
118
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
109
- 'app/services/link_titles.py:_resolve_public_http_target:capture': ('gaierror',),
119
+ 'app/services/public_http.py:resolve_public_http_target:resolve_capture': ('gaierror',),
120
+ 'app/services/public_http.py:normalize_public_http_url:parse_capture': ('ValueError',),
110
121
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
111
- 'app/services/link_titles.py:connect_tcp:connect_capture': ('ConnectError', 'ConnectTimeout'),
122
+ 'app/services/public_http.py:connect_tcp:connect_capture': ('ConnectError', 'ConnectTimeout'),
112
123
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
113
- 'app/services/link_titles.py:fetch_link_title:target_capture': ('_LinkTitleTargetRejected',),
124
+ 'app/services/link_titles.py:fetch_link_title:target_capture': ('PublicHttpTargetRejected',),
114
125
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
115
126
  'app/services/namespace_deletion_worker.py:_is_process_running:kill_capture': ('ProcessLookupError', 'PermissionError'),
116
127
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
@@ -138,7 +149,7 @@ CAPTURE_BOUNDARIES = {
138
149
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
139
150
  'app/services/remote_image_proxy.py:_download_one_url:request_capture': ('TimeoutException', 'NetworkError', 'HTTPError', 'TimeoutException', 'NetworkError', 'ProtocolError'),
140
151
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
141
- 'app/services/remote_image_proxy.py:_download_one_url:target_rejection_capture': ('_LinkTitleTargetRejected',),
152
+ 'app/services/remote_image_proxy.py:_download_one_url:target_rejection_capture': ('PublicHttpTargetRejected',),
142
153
  # Handle expected external I/O, provider, image or LaTeX parsing failure.
143
154
  'app/services/remote_image_proxy.py:_validated_image_mime_type:validation_capture': ('DecompressionBombError', 'OSError', 'SyntaxError', 'UnidentifiedImageError', 'ValueError'),
144
155
  # Record operation failure and re-raise; never resume the failed operation.
@@ -37,6 +37,7 @@ def _format_note_content_standard(*, content_html: str, tags: str) -> str:
37
37
  markdown_text,
38
38
  notes=note_store,
39
39
  allowed_note_ids=allowed_note_ids,
40
+ allowed_web_evidence=(),
40
41
  )
41
42
  return (
42
43
  '<div class="ai-chat-message-content meta-markdown" '