MetaList 0.3.13__tar.gz → 0.3.14__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.
- {metalist-0.3.13/metalist.egg-info → metalist-0.3.14}/PKG-INFO +16 -2
- {metalist-0.3.13 → metalist-0.3.14}/README.md +15 -1
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/ontology.py +13 -4
- {metalist-0.3.13 → metalist-0.3.14}/app/services/content_formatting.py +29 -6
- {metalist-0.3.13 → metalist-0.3.14}/app/services/embedded_references.py +9 -4
- {metalist-0.3.13 → metalist-0.3.14}/app/services/ontology_rules_store.py +41 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/tag_rename.py +77 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/css/main.css +511 -56
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/help-modal.js +1 -1
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/ontology-modal.js +122 -37
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/password-modal.js +1 -3
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/random-password-modal.js +15 -27
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/reminder-modal.js +1 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/sound-manager-modal.js +1 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/events/keyboard-events.js +168 -38
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/mode-context.js +8 -16
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/collapse-affordance-service.js +24 -5
- metalist-0.3.14/app/static/js/modules/mode-manager/services/tab-drag-service.js +42 -0
- metalist-0.3.14/app/usecases/delete_tag.py +66 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/version.py +1 -1
- {metalist-0.3.13 → metalist-0.3.14/metalist.egg-info}/PKG-INFO +16 -2
- {metalist-0.3.13 → metalist-0.3.14}/metalist.egg-info/SOURCES.txt +2 -0
- {metalist-0.3.13 → metalist-0.3.14}/MANIFEST.in +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/deps.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/dev.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/middleware/auth.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/request_auth.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/auth.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/backups.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/files.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/notes.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/reminders.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/remote_images.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/sounds.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/routes/test.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/api/transactions.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/config.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/backup_settings_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/engine.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/file_schema.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/file_session.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/files_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/link_titles_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/migrations.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/notes_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/ontology_rules_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/reminders_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/schema.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/search_history_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/session.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/settings_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/sounds_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/tab_state_sql.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/db/version.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/encryption_audit.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/main.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/commands.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/database.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/entities.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/enums.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/linked_list.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/list_operations.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/list_traversal.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/note_crud.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/models/utils.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/presentation/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/presentation/render/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/presentation/render/note_renderer.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/presentation/templates.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/authenticated_logging.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/encryption.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/http_headers.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/note_html.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/request_boundary.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/sensitive_logging.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/shell_execution.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/security/validation_errors.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/server_runtime.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/auth.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/auth_cache_state.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/auth_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/backlinks.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/backup_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/backup_settings_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/base_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/client_state_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/content_cache.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/date_filtering.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/dependencies.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/diagnostics.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/encryption.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/exception_capture.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/file_registry.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/file_storage.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/html_export.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/html_unformatting.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/hydration_state.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/image_size_formatting.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/inline_image_occurrences.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/integrity.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/latex_rendering.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/link_titles.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/login_rate_limit.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/maintenance_mode.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/markdown_rendering.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/namespace_deletion_jobs.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/namespace_deletion_worker.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/namespace_rename_jobs.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/namespace_rename_worker.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/namespace_runtime_guard.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/namespace_switcher.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/note_fullscreen.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/note_image_tags.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/note_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/note_store.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/query_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/reminders.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/remote_image_proxy.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/root_sorting.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/runtime_hardening.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/runtime_lock.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/search_history.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/search_history_storage.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/search_index.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/search_query.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/search_text.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/selected_text_tag.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/self_update.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/session_timeout_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/shell_session_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/snapshot.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/sound_storage.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/store.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/sync.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/sync_state.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/tab_state.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/tag_case.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/tag_ontology.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/tag_suggestions.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/tag_term_matching.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/test_reset.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/tokens.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/transaction_manager.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/undo_service.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/undo_state.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/view_cache.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/view_diff.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/view_state.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/services/windows_process_control.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/startup_environment.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/startup_js_sanity.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/startup_sanity.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/startup_sanity_config.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/config/command_palette_tags.json +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/css/forms.css +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/img/favicon.ico +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/locked.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/main.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/activity-tracker.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/api-client.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/api-failure-classification-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/async-result.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/auth.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/client-state-api.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/client-state-migration.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/activation-auth-policy.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/backup-command-availability.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/click-activation-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/command-palette-controller.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/endpoint-registry.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/note-layout-preferences.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/preferences-store.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/tag-config-loader.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/command-palette/usage-store.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/config.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/connectivity-monitor.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/context-menu/context-menu-registry.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/context-menu/context-menu-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/context-menu/context-menu-target-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/context-menu/input-caret-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/disconnect-editing-state-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/dom-utils-fixed.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/dom-utils.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/editor-commands.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/editor-selection.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/editor-toolbar.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/elapsed-time.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/error-handler.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/error-overlay.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/location-flags.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/login-namespace-picker.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/alphabetize-root-notes-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/backup-restore-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/backup-result-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/backup-retention-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/backup-settings-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/base-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/confirmation-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/delete-namespace-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/delete-namespace-validation.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/namespace-loading-page.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/namespace-modals.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/namespace-ports-profile.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/namespace-rename-validation.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/note-layout-appearance-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/prioritize-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/reset-updated-at-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/search-suggestion-statistics-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/session-timeout-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/modals/version-info-modal.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/actions/content-actions.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/actions/history-actions.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/actions/note-actions.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/actions/search-actions.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/actions/selection-actions.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/actions/ui-actions.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/events/context-menu-events.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/events/focus-events.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/events/inactivity-events.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/events/input-events.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/events/mouse-events.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/events/search-events.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/mode-logger.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/mode-manager-controller.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/add-style-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/animated-scroll-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/backlinks-panel-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/clipboard-shortcut-policy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/collapse-editing-policy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/command-gate-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/context-menu-target-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/date-filter-indicator-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/date-filter-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/deselect-selection-state-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/differential-view-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/edit-session-collapse-policy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/edit-session-collapse-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/embedded-image-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/file-drop-policy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/file-image-preview-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/file-reference-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/filtered-refresh-selection-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/history-selection-policy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/history-shortcut-policy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/html-paste-sanitizer-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/image-context-menu-action-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/image-file-insert-choice-modal-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/infinite-scroll-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/link-context-menu-action-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/markdown-render-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/mermaid-render-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-click-target-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-clipboard-write-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-collapse-animation-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-context-menu-action-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-delete-shortcut-policy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-drag-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-fullscreen-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-reposition-animation-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-split-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/note-timestamp-hover-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/password-clipboard-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/polling-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/reference-source-navigation-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/remote-image-proxy-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/remove-formatting-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/rhs-panel-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/root-date-separator-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/root-sort-indicator-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/root-sort-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/scroll-anchor-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/scroll-restoration-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/scroll-to-top-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-contexts-overlay-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-debounce-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-input-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-interaction-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-redaction-reveal-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-suggestion-statistics-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-suggestion-window-labels-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-suggestion-windows-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-suggestions-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/search-syntax-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/selected-formatting-removal-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/selected-text-tag-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/shell-output-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/tab-dom-cache-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/tab-duplication-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/tab-state-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/tag-bar-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/tag-suggestions-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/tag-syntax-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/todo-toggle-editing-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/untagged-view-indicator-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/mode-manager/services/view-mode-search-shortcut-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/note-html-sanitizer.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/password-generator.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/password-operation-response.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/password-policy.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/password-strength.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/reminder-store.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/reminder-surface-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/selection-markers.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/session-auth.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/sound-service.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/tag-token.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/modules/uuid.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/namespace-deleted.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/namespace-renamed.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/vendor/dompurify-3.4.12.LICENSE.txt +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/vendor/dompurify-3.4.12.min.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/vendor/markdown-it.min.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/vendor/mermaid-11.9.0.LICENSE.txt +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/vendor/mermaid-11.9.0.min.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/vendor/zxcvbn-4.4.2.LICENSE.txt +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/js/vendor/zxcvbn-4.4.2.js +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/note-html-policy.json +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/static/video/login-startup.mp4 +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/templates/base.html +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/templates/index.html +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/templates/locked.html +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/templates/maintenance.html +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/templates/namespace_deleted.html +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/templates/namespace_renamed.html +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/templates/notes_list.html +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/add_selected_text_tag.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/alphabetize_root_notes.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/base.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/collapse.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/copy_note.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/create_child.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/create_note.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/create_sibling.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/delete_subtree.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/expand.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/indent.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/lock.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/move.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/move_to_top.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/outdent.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/paste_child.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/paste_sibling.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/prioritize.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/redo.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/rename_tag.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/reset_updated_at.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/resize_image.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/run_shell.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/search_comment_autofill.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/search_context_tags.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/set_collapse_bulk.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/set_collapse_in_context.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/split_note.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/toggle_reference_mode.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/toggle_todo_done.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/undo.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/unformat_content.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/update_content.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/usecases/view.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/utils/__init__.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/utils/encryption.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/app/utils/text_utils.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/convert-from-legacy.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/main.py +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/metalist.egg-info/dependency_links.txt +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/metalist.egg-info/entry_points.txt +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/metalist.egg-info/requires.txt +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/metalist.egg-info/top_level.txt +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/pyproject.toml +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/scripts/generate-lan-cert.sh +0 -0
- {metalist-0.3.13 → metalist-0.3.14}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: metalist
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.14
|
|
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
|
|
@@ -67,6 +67,20 @@ A minimalist single-user note-taking app focused on server-side rendering (SSR),
|
|
|
67
67
|
- The browser client drives interaction via `/api2` JSON endpoints.
|
|
68
68
|
- Notes are loaded/decrypted into an in-memory store at startup; a post-startup DB read guard prevents accidental runtime SELECTs.
|
|
69
69
|
|
|
70
|
+
## Security Boundary
|
|
71
|
+
|
|
72
|
+
Password protection encrypts namespace data at rest. While a namespace is
|
|
73
|
+
unlocked, the server must hold its data-encryption key and decrypted working
|
|
74
|
+
data in process memory, and the browser holds the decrypted content currently
|
|
75
|
+
rendered in the page. A sufficiently privileged local process, debugger,
|
|
76
|
+
administrator, browser extension, or process-memory dump can therefore expose
|
|
77
|
+
an unlocked namespace.
|
|
78
|
+
|
|
79
|
+
Explicit logout removes the live key and purges decrypted runtime stores, but
|
|
80
|
+
it cannot guarantee forensic overwriting of memory previously allocated by the
|
|
81
|
+
Python or browser runtimes. Protect the host account and operating system, and
|
|
82
|
+
see the detailed [security architecture and threat model](docs/security/README.md).
|
|
83
|
+
|
|
70
84
|
## Development
|
|
71
85
|
|
|
72
86
|
### Setup
|
|
@@ -85,7 +99,7 @@ After the first installation, update and restart MetaList with one cross-platfor
|
|
|
85
99
|
```bash
|
|
86
100
|
metalist update
|
|
87
101
|
```
|
|
88
|
-
The updater checks the installed version against the latest PyPI release first. If MetaList is already current, it reports the installed version and leaves all running namespaces untouched. When an update is available, it stops running namespaces, hands off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock, installs the exact version reported by PyPI with a forced cache refresh, launches MetaList again, and reports the installed version (for example, `MetaList updated to v0.3.
|
|
102
|
+
The updater checks the installed version against the latest PyPI release first. If MetaList is already current, it reports the installed version and leaves all running namespaces untouched. When an update is available, it stops running namespaces, hands off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock, installs the exact version reported by PyPI with a forced cache refresh, launches MetaList again, and reports the installed version (for example, `MetaList updated to v0.3.14.`).
|
|
89
103
|
|
|
90
104
|
For pip, users can run `pip install metalist`. For a non-editable local install from this checkout, use `uv pip install .` or `pip install .` instead of the editable command below.
|
|
91
105
|
|
|
@@ -33,6 +33,20 @@ A minimalist single-user note-taking app focused on server-side rendering (SSR),
|
|
|
33
33
|
- The browser client drives interaction via `/api2` JSON endpoints.
|
|
34
34
|
- Notes are loaded/decrypted into an in-memory store at startup; a post-startup DB read guard prevents accidental runtime SELECTs.
|
|
35
35
|
|
|
36
|
+
## Security Boundary
|
|
37
|
+
|
|
38
|
+
Password protection encrypts namespace data at rest. While a namespace is
|
|
39
|
+
unlocked, the server must hold its data-encryption key and decrypted working
|
|
40
|
+
data in process memory, and the browser holds the decrypted content currently
|
|
41
|
+
rendered in the page. A sufficiently privileged local process, debugger,
|
|
42
|
+
administrator, browser extension, or process-memory dump can therefore expose
|
|
43
|
+
an unlocked namespace.
|
|
44
|
+
|
|
45
|
+
Explicit logout removes the live key and purges decrypted runtime stores, but
|
|
46
|
+
it cannot guarantee forensic overwriting of memory previously allocated by the
|
|
47
|
+
Python or browser runtimes. Protect the host account and operating system, and
|
|
48
|
+
see the detailed [security architecture and threat model](docs/security/README.md).
|
|
49
|
+
|
|
36
50
|
## Development
|
|
37
51
|
|
|
38
52
|
### Setup
|
|
@@ -51,7 +65,7 @@ After the first installation, update and restart MetaList with one cross-platfor
|
|
|
51
65
|
```bash
|
|
52
66
|
metalist update
|
|
53
67
|
```
|
|
54
|
-
The updater checks the installed version against the latest PyPI release first. If MetaList is already current, it reports the installed version and leaves all running namespaces untouched. When an update is available, it stops running namespaces, hands off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock, installs the exact version reported by PyPI with a forced cache refresh, launches MetaList again, and reports the installed version (for example, `MetaList updated to v0.3.
|
|
68
|
+
The updater checks the installed version against the latest PyPI release first. If MetaList is already current, it reports the installed version and leaves all running namespaces untouched. When an update is available, it stops running namespaces, hands off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock, installs the exact version reported by PyPI with a forced cache refresh, launches MetaList again, and reports the installed version (for example, `MetaList updated to v0.3.14.`).
|
|
55
69
|
|
|
56
70
|
For pip, users can run `pip install metalist`. For a non-editable local install from this checkout, use `uv pip install .` or `pip install .` instead of the editable command below.
|
|
57
71
|
|
|
@@ -20,6 +20,7 @@ from app.services.ontology_rules_store import (
|
|
|
20
20
|
update_rule_line,
|
|
21
21
|
)
|
|
22
22
|
from app.usecases.rename_tag import apply_rename_tag_everywhere
|
|
23
|
+
from app.usecases.delete_tag import apply_delete_tag_everywhere
|
|
23
24
|
from app.utils.text_utils import strip_html
|
|
24
25
|
|
|
25
26
|
|
|
@@ -226,6 +227,16 @@ def rename_tag(request: Request, payload: dict) -> dict:
|
|
|
226
227
|
return apply_rename_tag_everywhere(old=old, new=new, token=token)
|
|
227
228
|
|
|
228
229
|
|
|
230
|
+
@router.post("/delete-tag")
|
|
231
|
+
@transactional_route
|
|
232
|
+
def delete_tag(request: Request, payload: dict) -> dict:
|
|
233
|
+
tag = payload["tag"]
|
|
234
|
+
if not isinstance(tag, str) or tag.strip() == "":
|
|
235
|
+
raise HTTPException(status_code=400, detail="tag must be a non-empty string")
|
|
236
|
+
token = _maybe_bearer_token(request)
|
|
237
|
+
return apply_delete_tag_everywhere(tag=tag, token=token)
|
|
238
|
+
|
|
239
|
+
|
|
229
240
|
@router.get("/focus")
|
|
230
241
|
def focus_view(tag: str) -> dict:
|
|
231
242
|
ontology = get_ontology()
|
|
@@ -422,8 +433,7 @@ def list_tags(q: str, limit: int) -> dict:
|
|
|
422
433
|
|
|
423
434
|
if needle == "":
|
|
424
435
|
ordered = sorted(tags, key=lambda tag: (-tag_counts.get(tag, 0), tag))
|
|
425
|
-
|
|
426
|
-
ordered = ordered[:limit]
|
|
436
|
+
ordered = ordered[:limit]
|
|
427
437
|
payload = [
|
|
428
438
|
{"tag": tag, "count": tag_counts.get(tag, 0)}
|
|
429
439
|
for tag in ordered
|
|
@@ -446,8 +456,7 @@ def list_tags(q: str, limit: int) -> dict:
|
|
|
446
456
|
|
|
447
457
|
matches.sort(key=lambda item: (item[0], item[1], item[2]))
|
|
448
458
|
results = [item[2] for item in matches]
|
|
449
|
-
|
|
450
|
-
results = results[:limit]
|
|
459
|
+
results = results[:limit]
|
|
451
460
|
|
|
452
461
|
payload = [
|
|
453
462
|
{"tag": tag, "count": tag_counts.get(tag, 0)}
|
|
@@ -500,9 +500,8 @@ def _render_plain_url_anchor(*, text: str, link_text: str, href_value: str) -> s
|
|
|
500
500
|
if stripped != link_text:
|
|
501
501
|
return f'<a href="{href_value}" target="_blank" rel="noopener noreferrer">{link_text}</a>'
|
|
502
502
|
|
|
503
|
-
|
|
504
|
-
if
|
|
505
|
-
link_title_store.maybe_enqueue_fetch(link_text)
|
|
503
|
+
title_html = render_standalone_link_title_html(link_text)
|
|
504
|
+
if title_html is None:
|
|
506
505
|
diagnostic = link_title_store.get_diagnostic(link_text)
|
|
507
506
|
diagnostic_title_attr = ""
|
|
508
507
|
if diagnostic is not None:
|
|
@@ -513,14 +512,38 @@ def _render_plain_url_anchor(*, text: str, link_text: str, href_value: str) -> s
|
|
|
513
512
|
f'target="_blank" rel="noopener noreferrer">{link_text}</a>'
|
|
514
513
|
)
|
|
515
514
|
|
|
516
|
-
escaped_title = html.escape(title)
|
|
517
|
-
escaped_domain = html.escape(display_domain_for_url(link_text))
|
|
518
515
|
return (
|
|
519
516
|
f'<a class="link-title" href="{href_value}" title="{href_value}" '
|
|
520
517
|
'target="_blank" rel="noopener noreferrer">'
|
|
518
|
+
f"{title_html}"
|
|
519
|
+
"</a>"
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
def render_standalone_link_title_html(text: str) -> str | None:
|
|
524
|
+
if not isinstance(text, str):
|
|
525
|
+
raise TypeError("text must be a string")
|
|
526
|
+
stripped = text.strip()
|
|
527
|
+
if stripped == "":
|
|
528
|
+
return None
|
|
529
|
+
|
|
530
|
+
match = _PLAIN_URL_RE.fullmatch(stripped)
|
|
531
|
+
if match is None:
|
|
532
|
+
return None
|
|
533
|
+
link_text, trailing_suffix = _split_trailing_url_punctuation(match.group(0))
|
|
534
|
+
if link_text != stripped or trailing_suffix != "":
|
|
535
|
+
return None
|
|
536
|
+
|
|
537
|
+
title = link_title_store.get_ok_title(link_text)
|
|
538
|
+
if title is None:
|
|
539
|
+
link_title_store.maybe_enqueue_fetch(link_text)
|
|
540
|
+
return None
|
|
541
|
+
|
|
542
|
+
escaped_title = html.escape(title)
|
|
543
|
+
escaped_domain = html.escape(display_domain_for_url(link_text))
|
|
544
|
+
return (
|
|
521
545
|
f'<span class="link-title-text">{escaped_title}</span>'
|
|
522
546
|
f'<span class="link-title-domain"> · {escaped_domain}</span>'
|
|
523
|
-
"</a>"
|
|
524
547
|
)
|
|
525
548
|
|
|
526
549
|
|
|
@@ -8,6 +8,7 @@ from typing import Callable, FrozenSet, List, Optional, Tuple
|
|
|
8
8
|
from app.services.content_formatting import find_consumed_content_wrapper_keys
|
|
9
9
|
from app.services.content_formatting import find_global_credential_tag
|
|
10
10
|
from app.services.content_formatting import format_note_content_for_view
|
|
11
|
+
from app.services.content_formatting import render_standalone_link_title_html
|
|
11
12
|
from app.services.inline_image_occurrences import annotate_inline_image_occurrences
|
|
12
13
|
from app.services.remote_image_proxy import (
|
|
13
14
|
remote_image_proxy_registry,
|
|
@@ -630,23 +631,27 @@ def _render_link_body(
|
|
|
630
631
|
)
|
|
631
632
|
if is_password_preview:
|
|
632
633
|
preview = "X" * len(preview)
|
|
633
|
-
|
|
634
|
+
preview_html = None
|
|
635
|
+
if not is_password_preview:
|
|
636
|
+
preview_html = render_standalone_link_title_html(preview)
|
|
637
|
+
if preview_html is None:
|
|
638
|
+
preview_html = html.escape(preview)
|
|
634
639
|
if static_export:
|
|
635
640
|
if is_password_preview:
|
|
636
641
|
return (
|
|
637
642
|
'<span class="note-reference-link note-reference-link-static meta-credential-password">'
|
|
638
|
-
f'<span class="meta-credential-value">{
|
|
643
|
+
f'<span class="meta-credential-value">{preview_html}</span>'
|
|
639
644
|
"</span>"
|
|
640
645
|
)
|
|
641
646
|
return (
|
|
642
647
|
f'<span class="note-reference-link note-reference-link-static">'
|
|
643
|
-
f"{
|
|
648
|
+
f"{preview_html}"
|
|
644
649
|
"</span>"
|
|
645
650
|
)
|
|
646
651
|
return (
|
|
647
652
|
f'<a href="#" class="note-reference-link" data-ref-note-id="{escaped_note_id}">'
|
|
648
653
|
'<span class="note-reference-link-icon" aria-hidden="true" title="Link to reference source">↗</span>'
|
|
649
|
-
f'<span class="note-reference-link-title">{
|
|
654
|
+
f'<span class="note-reference-link-title">{preview_html}</span>'
|
|
650
655
|
"</a>"
|
|
651
656
|
)
|
|
652
657
|
|
|
@@ -532,6 +532,47 @@ def rename_tag_everywhere(*, old: str, new: str, token: str) -> None:
|
|
|
532
532
|
_upsert_state_locked(rules=updated_rows, plaintext_by_id=updated_plaintext)
|
|
533
533
|
|
|
534
534
|
|
|
535
|
+
def delete_tag_everywhere(*, tag: str) -> int:
|
|
536
|
+
if not isinstance(tag, str) or tag.strip() == "":
|
|
537
|
+
raise TypeError("tag must be a non-empty string")
|
|
538
|
+
|
|
539
|
+
normalized = tag.strip()
|
|
540
|
+
with _LOCK:
|
|
541
|
+
state = _STATE
|
|
542
|
+
if state is None:
|
|
543
|
+
raise RuntimeError("Ontology rules store not bootstrapped")
|
|
544
|
+
if not state.is_decrypted:
|
|
545
|
+
raise RuntimeError("Ontology rules not decrypted yet")
|
|
546
|
+
|
|
547
|
+
deleted_rule_ids: list[int] = []
|
|
548
|
+
for rule_id, line in state.plaintext_by_id.items():
|
|
549
|
+
rules = parse_rules_text(text=f"{line}\n", filename=f"ontology_rules:{rule_id}")
|
|
550
|
+
references_tag = any(
|
|
551
|
+
rule.rhs == normalized
|
|
552
|
+
or any(isinstance(atom, TagAtom) and atom.tag == normalized for atom in rule.lhs)
|
|
553
|
+
for rule in rules
|
|
554
|
+
)
|
|
555
|
+
if references_tag:
|
|
556
|
+
deleted_rule_ids.append(rule_id)
|
|
557
|
+
|
|
558
|
+
if not deleted_rule_ids:
|
|
559
|
+
return 0
|
|
560
|
+
|
|
561
|
+
with begin_writer() as connection:
|
|
562
|
+
for rule_id in deleted_rule_ids:
|
|
563
|
+
db_delete_rule(connection, rule_id)
|
|
564
|
+
|
|
565
|
+
deleted_rule_id_set = set(deleted_rule_ids)
|
|
566
|
+
updated_rows = [row for row in state.rules if row.id not in deleted_rule_id_set]
|
|
567
|
+
updated_plaintext = {
|
|
568
|
+
rule_id: line
|
|
569
|
+
for rule_id, line in state.plaintext_by_id.items()
|
|
570
|
+
if rule_id not in deleted_rule_id_set
|
|
571
|
+
}
|
|
572
|
+
_upsert_state_locked(rules=updated_rows, plaintext_by_id=updated_plaintext)
|
|
573
|
+
return len(deleted_rule_ids)
|
|
574
|
+
|
|
575
|
+
|
|
535
576
|
def extract_ontology_tags(ontology: TagOntology) -> set[str]:
|
|
536
577
|
tags: set[str] = set()
|
|
537
578
|
for src, outs in ontology.implication_out_edges.items():
|
|
@@ -5,6 +5,83 @@ import re
|
|
|
5
5
|
from app.services.content_formatting import _unwrap_tag_token
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
def delete_tag_from_tag_bar(*, tags: str, tag: str) -> tuple[str, bool]:
|
|
9
|
+
if not isinstance(tags, str):
|
|
10
|
+
raise TypeError('tags must be a string')
|
|
11
|
+
if not isinstance(tag, str) or tag == '':
|
|
12
|
+
raise TypeError('tag must be a non-empty string')
|
|
13
|
+
|
|
14
|
+
out = ''
|
|
15
|
+
changed = False
|
|
16
|
+
index = 0
|
|
17
|
+
while index < len(tags):
|
|
18
|
+
if tags.startswith('/*', index):
|
|
19
|
+
end = tags.find('*/', index + 2)
|
|
20
|
+
if end == -1:
|
|
21
|
+
out += tags[index:]
|
|
22
|
+
break
|
|
23
|
+
out += tags[index : end + 2]
|
|
24
|
+
index = end + 2
|
|
25
|
+
continue
|
|
26
|
+
|
|
27
|
+
ch = tags[index]
|
|
28
|
+
if ch.isspace():
|
|
29
|
+
out += ch
|
|
30
|
+
index += 1
|
|
31
|
+
continue
|
|
32
|
+
|
|
33
|
+
start = index
|
|
34
|
+
opener = tags[index]
|
|
35
|
+
token_end = None
|
|
36
|
+
|
|
37
|
+
if opener in {'[', '{', '('}:
|
|
38
|
+
opener_run = 1
|
|
39
|
+
while index + opener_run < len(tags) and tags[index + opener_run] == opener:
|
|
40
|
+
opener_run += 1
|
|
41
|
+
if opener_run <= 3:
|
|
42
|
+
closer = {"[": "]", "{": "}", "(": ")"}[opener]
|
|
43
|
+
needle = closer * opener_run
|
|
44
|
+
close_at = tags.find(needle, index + opener_run)
|
|
45
|
+
if close_at != -1:
|
|
46
|
+
token_end = close_at + opener_run
|
|
47
|
+
|
|
48
|
+
if token_end is None:
|
|
49
|
+
token_end = start
|
|
50
|
+
while token_end < len(tags) and not tags[token_end].isspace():
|
|
51
|
+
token_end += 1
|
|
52
|
+
|
|
53
|
+
token = tags[start:token_end]
|
|
54
|
+
base, wrapper = _unwrap_tag_token(token)
|
|
55
|
+
|
|
56
|
+
if wrapper is None:
|
|
57
|
+
if base == tag:
|
|
58
|
+
changed = True
|
|
59
|
+
else:
|
|
60
|
+
out += token
|
|
61
|
+
else:
|
|
62
|
+
remaining = _delete_inner_token(inner=base, tag=tag)
|
|
63
|
+
if remaining != base:
|
|
64
|
+
changed = True
|
|
65
|
+
if remaining != '':
|
|
66
|
+
opener_char, depth = wrapper
|
|
67
|
+
closer_char = {"[": "]", "{": "}", "(": ")"}[opener_char]
|
|
68
|
+
out += (opener_char * depth) + remaining + (closer_char * depth)
|
|
69
|
+
else:
|
|
70
|
+
out += token
|
|
71
|
+
|
|
72
|
+
index = token_end
|
|
73
|
+
|
|
74
|
+
return out, changed
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _delete_inner_token(*, inner: str, tag: str) -> str:
|
|
78
|
+
parts = re.split(r'\s+', inner.strip())
|
|
79
|
+
remaining = [part for part in parts if part != tag]
|
|
80
|
+
if len(remaining) == len(parts):
|
|
81
|
+
return inner
|
|
82
|
+
return ' '.join(remaining)
|
|
83
|
+
|
|
84
|
+
|
|
8
85
|
def rename_tag_in_tag_bar(*, tags: str, old: str, new: str) -> tuple[str, bool]:
|
|
9
86
|
if not isinstance(tags, str):
|
|
10
87
|
raise TypeError('tags must be a string')
|