MetaList 0.6.0__tar.gz → 0.6.2__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.6.0/metalist.egg-info → metalist-0.6.2}/PKG-INFO +22 -7
- {metalist-0.6.0 → metalist-0.6.2}/README.md +20 -5
- {metalist-0.6.0 → metalist-0.6.2}/app/exception_boundaries.py +5 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/client_state_service.py +3 -1
- {metalist-0.6.0 → metalist-0.6.2}/app/services/namespace_switcher.py +55 -2
- {metalist-0.6.0 → metalist-0.6.2}/app/services/self_update.py +15 -18
- metalist-0.6.2/app/services/update_preflight.py +126 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/config/command_palette_tags.json +0 -4
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/client-state-migration.js +4 -2
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/command-palette-controller.js +1 -19
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/endpoint-registry.js +0 -11
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/ui-actions.js +0 -124
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/mode-context.js +0 -8
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/infinite-scroll-service.js +1 -26
- {metalist-0.6.0 → metalist-0.6.2}/app/version.py +1 -1
- {metalist-0.6.0 → metalist-0.6.2}/convert-from-legacy.py +4 -1
- {metalist-0.6.0 → metalist-0.6.2/metalist.egg-info}/PKG-INFO +22 -7
- {metalist-0.6.0 → metalist-0.6.2}/metalist.egg-info/SOURCES.txt +1 -0
- {metalist-0.6.0 → metalist-0.6.2}/pyproject.toml +1 -1
- {metalist-0.6.0 → metalist-0.6.2}/MANIFEST.in +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/deps.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/dev.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/middleware/auth.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/note_requests.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/request_auth.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/ai.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/auth.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/backups.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/files.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/notes.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/ontology.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/reminders.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/remote_images.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/routes/test.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/transactions.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/api/upload_limits.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/config.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/data_directory.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/backup_settings_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/engine.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/file_schema.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/file_session.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/files_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/link_titles_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/live_recovery.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/migrations.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/notes_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/ontology_rules_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/reminders_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/retire_sounds.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/schema.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/search_history_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/session.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/settings_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/tab_state_sql.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/db/version.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/encryption_audit.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/https_proxy.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/main.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/commands.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/database.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/entities.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/enums.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/linked_list.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/list_operations.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/list_traversal.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/note_crud.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/models/utils.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/presentation/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/presentation/render/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/presentation/render/note_renderer.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/presentation/templates.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/authenticated_logging.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/encryption.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/http_headers.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/note_html.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/request_boundary.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/sensitive_cache.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/sensitive_logging.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/shell_execution.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/security/validation_errors.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/server_runtime.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/actions.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/cloud_privacy.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/context.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/evidence_serialization.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/inference.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/investigation.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/model_policy.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/ollama_inference.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/openai_cost_tracking.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/openai_inference.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/permissions.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/prompt_settings.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/prompts/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/prompts/final-response.md +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/prompts/system.md +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/prompts/tool-result.md +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/retrieval_settings.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/runtime.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/scope.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/skill_settings.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/skills/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/skills/scoped-investigation.md +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/tagging.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/tagging_run.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/token_estimation.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/tools.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/agent/trace.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/ai_chat.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/ai_chat_rendering.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/ai_chat_stream.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/auth.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/auth_cache_state.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/auth_service.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/backlink_index.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/backlinks.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/backup_service.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/backup_settings_service.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/bulk_operation.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/content_cache.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/content_formatting.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/diagnostics.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/embedded_references.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/encryption.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/exception_capture.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/file_registry.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/file_storage.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/footnote_layout.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/footnote_rendering.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/hierarchy.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/html_export.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/html_unformatting.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/hydration_state.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/image_size_formatting.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/inline_image_occurrences.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/input_errors.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/integrity.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/latex_rendering.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/link_titles.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/login_rate_limit.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/maintenance_mode.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/managed_ollama_runtime.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/markdown_rendering.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/namespace_deletion_jobs.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/namespace_deletion_worker.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/namespace_rename_jobs.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/namespace_rename_worker.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/namespace_runtime_guard.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/note_fullscreen.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/note_image_tags.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/note_ordering.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/note_store.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/ollama_provider.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/ontology_rules_store.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/openai_credentials.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/password_note_fields.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/reference_presentation.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/reminders.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/remote_image_proxy.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/request_recovery.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/resource_limits.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/root_sorting.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/runtime_generation.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/runtime_hardening.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/runtime_lock.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/search_history.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/search_history_storage.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/search_index.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/search_query.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/search_text.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/selected_text_tag.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/session_timeout_service.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/shell_session_service.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/snapshot.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/store.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/structured_note_renderers.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/sync.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/sync_state.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/tab_state.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/tag_case.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/tag_ontology.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/tag_rename.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/tag_suggestions.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/tag_term_matching.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/test_reset.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/tokens.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/undo_state.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/update_backups.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/view_cache.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/view_diff.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/view_state.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/services/windows_process_control.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/startup_environment.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/startup_js_sanity.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/startup_sanity.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/startup_sanity_config.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/css/floating-notes.css +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/css/forms.css +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/css/main.css +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/img/favicon.ico +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/locked.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/main.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/activity-tracker.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/agent-prompt-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/agent-retrieval-settings.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-agent-debug-view.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-chat-api.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-chat-panel-controller.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-chat-panel-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-thinking-level-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/bulk-elapsed-clock.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/bulk-proposal-ui.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/cloud-privacy-policy.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/ai-chat/proposal-menu.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/api-client.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/api-failure-classification-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/application-state.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/async-result.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/auth.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/client-state-api.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/activation-auth-policy.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/backup-command-availability.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/click-activation-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/note-layout-preferences.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/preferences-store.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/tag-config-loader.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/usage-store.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/config.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/connectivity-monitor.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/context-menu/context-menu-registry.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/context-menu/context-menu-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/context-menu/context-menu-target-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/context-menu/input-caret-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/disconnect-editing-state-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/dom-utils-fixed.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/dom-utils.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/editor-commands.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/editor-selection.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/editor-toolbar.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/elapsed-time.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/error-handler.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/error-overlay.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/expected-errors.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/location-flags.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/login-namespace-picker.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/maintenance.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/agent-prompt-editor-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/ai-agent-settings-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/alphabetize-root-notes-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/backup-restore-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/backup-result-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/backup-retention-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/backup-settings-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/base-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/confirmation-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/delete-namespace-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/delete-namespace-validation.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/help-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/namespace-loading-page.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/namespace-modals.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/namespace-ports-profile.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/namespace-rename-validation.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/note-layout-appearance-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/ontology-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/password-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/prioritize-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/random-password-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/reminder-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/reset-updated-at-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/search-suggestion-statistics-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/session-timeout-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/modals/version-info-modal.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/content-actions.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/history-actions.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/note-actions.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/search-actions.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/selection-actions.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/context-menu-events.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/focus-events.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/inactivity-events.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/input-events.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/keyboard-events.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/mouse-events.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/search-events.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/mode-logger.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/mode-manager-controller.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/add-style-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/animated-scroll-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/backlinks-navigation-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/backlinks-panel-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/clipboard-shortcut-policy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/collapse-affordance-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/collapse-editing-policy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/command-gate-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/context-menu-target-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/deselect-selection-state-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/differential-view-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/edit-session-collapse-policy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/edit-session-collapse-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/embedded-image-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/file-drop-policy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/file-image-preview-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/file-reference-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/filtered-refresh-selection-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/floating-note-dom.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/floating-note-layout.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/floating-note-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/footnote-navigation-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/history-selection-policy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/history-shortcut-policy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/html-paste-sanitizer-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/image-context-menu-action-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/image-file-insert-choice-modal-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/link-context-menu-action-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/link-title-prefetch-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/markdown-render-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/mermaid-render-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-click-target-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-clipboard-write-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-collapse-animation-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-context-menu-action-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-delete-shortcut-policy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-drag-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-fullscreen-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-reposition-animation-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-split-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-timestamp-hover-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/password-clipboard-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/polling-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/reference-source-navigation-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/remote-image-proxy-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/remove-formatting-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/root-date-separator-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/root-sort-indicator-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/root-sort-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/scroll-anchor-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/scroll-restoration-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/scroll-to-top-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-contexts-overlay-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-debounce-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-input-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-interaction-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-redaction-reveal-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestion-statistics-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestion-window-labels-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestion-windows-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestions-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-syntax-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/selected-formatting-removal-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/selected-text-tag-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/shell-output-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-dom-cache-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-drag-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-duplication-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-state-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-bar-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-input-selection-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-proposal-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-suggestions-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-syntax-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/todo-toggle-editing-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/untagged-view-indicator-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/view-mode-search-shortcut-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/note-html-sanitizer.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/password-generator.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/password-operation-response.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/password-policy.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/password-strength.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/reminder-store.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/reminder-surface-service.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/selection-markers.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/session-auth.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/tag-token.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/uuid.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/namespace-deleted.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/namespace-renamed.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/dompurify-3.4.13.LICENSE.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/dompurify-3.4.13.min.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/markdown-it-14.3.2.LICENSE.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/markdown-it-14.3.2.min.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/mermaid-11.16.1.LICENSE.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/mermaid-11.16.1.min.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/zxcvbn-4.4.2.LICENSE.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/js/vendor/zxcvbn-4.4.2.js +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/note-html-policy.json +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/static/video/login-startup.mp4 +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/templates/base.html +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/templates/index.html +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/templates/locked.html +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/templates/maintenance.html +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/templates/namespace_deleted.html +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/templates/namespace_renamed.html +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/templates/notes_list.html +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/upload_limits.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/add_selected_text_tag.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/alphabetize_root_notes.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/base.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/bulk_tag_proposals.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/collapse.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/copy_note.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/create_child.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/create_note.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/create_sibling.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/delete_subtree.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/delete_tag.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/expand.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/indent.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/lock.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/move.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/move_to_top.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/outdent.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/paste_child.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/paste_sibling.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/prefetch_link_titles.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/prioritize.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/redo.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/rename_tag.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/reset_updated_at.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/resize_image.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/run_shell.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/search_comment_autofill.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/search_context_tags.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/set_collapse_bulk.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/set_collapse_in_context.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/split_note.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/tag_proposals.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/toggle_reference_mode.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/toggle_todo_done.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/undo.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/unformat_content.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/update_content.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/usecases/view.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/utils/__init__.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/utils/encryption.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/app/utils/text_utils.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/main.py +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/metalist.egg-info/dependency_links.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/metalist.egg-info/entry_points.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/metalist.egg-info/requires.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/metalist.egg-info/top_level.txt +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/scripts/generate-lan-cert.sh +0 -0
- {metalist-0.6.0 → metalist-0.6.2}/setup.cfg +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: metalist
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
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
|
|
7
7
|
Project-URL: Issues, https://github.com/evolvingstuff/metalist/issues
|
|
8
|
-
Requires-Python: <3.
|
|
8
|
+
Requires-Python: <3.15,>=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
Requires-Dist: argon2-cffi==25.1.0
|
|
11
11
|
Requires-Dist: cryptography==50.0.0
|
|
@@ -48,6 +48,17 @@ A minimalist single-user note-taking app focused on server-side rendering (SSR),
|
|
|
48
48
|
- Multi-tab search contexts with server-persisted scroll/search state (survives browser restarts)
|
|
49
49
|
- Manual namespace backups/restores to a user-selected backup folder with retention controls
|
|
50
50
|
|
|
51
|
+
## Changes in 0.6.2
|
|
52
|
+
|
|
53
|
+
- Namespace startup allows two minutes, with progress every five seconds, instead of failing after 12 seconds on a busy machine. `METALIST_STARTUP_TIMEOUT_SECONDS` can increase the allowance. Failed children are stopped and reaped.
|
|
54
|
+
- Updates preserve the running Python interpreter and validate a disposable installation and namespace startup before stopping live servers. uv then installs the tested package/dependency versions from its cache without network access.
|
|
55
|
+
- Python 3.14 is supported. Command-line legacy imports also work when Python lacks Tk's native GUI component.
|
|
56
|
+
- Release validation now includes the real uv update, backups, and multi-namespace restart on Windows, macOS, and Linux across Python 3.10–3.14.
|
|
57
|
+
|
|
58
|
+
## Changes in 0.6.1
|
|
59
|
+
|
|
60
|
+
- Removed the unused performance overlay, including its menu option and background state updates, fixing a fatal redundant-state error during note rearranging. Obsolete overlay preferences and command usage are discarded automatically.
|
|
61
|
+
|
|
51
62
|
## Changes in 0.6.0
|
|
52
63
|
|
|
53
64
|
- Open notes and their children in multiple live, read-only floating windows. Drag and resize them, keep them visible across searches and tabs, and follow links or copy passwords. Saved changes refresh every half second.
|
|
@@ -115,11 +126,11 @@ After the first installation, update and restart MetaList with one cross-platfor
|
|
|
115
126
|
```bash
|
|
116
127
|
metalist update
|
|
117
128
|
```
|
|
118
|
-
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 checks the
|
|
129
|
+
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 checks installer prerequisites and uses uv to install the candidate into a disposable tool environment with the current base Python interpreter. It checks dependencies and starts a temporary namespace to verify HTTP readiness, version, and runtime assets. A failed preflight leaves the current installation and running namespaces unchanged. After preflight succeeds, it stops running namespaces, and creates and verifies a new backup of every namespace before installation can begin. Each archive includes the complete notes/settings database, the attachments database when present, and any legacy search-history database. Locked namespaces are backed up with their encrypted data and key metadata intact, without requiring a password.
|
|
119
130
|
|
|
120
131
|
Backups are saved to `~/MetaList/namespaces/<namespace>/backups/<namespace>-<timestamp>.metalist-backup.tar.gz`; the updater prints each verified path. Existing backups remain unchanged and are not pruned. If any backup fails, the update aborts with the current installation intact; run `metalist` to restart the stopped servers after resolving the failure.
|
|
121
132
|
|
|
122
|
-
Only after all backups pass does the updater hand off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock. It
|
|
133
|
+
Only after all backups pass does the updater hand off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock. It delegates installation to uv, pinning the current base interpreter and the exact tested package/dependency versions, using the cache populated during preflight with network access disabled. It then launches MetaList again, and reports the installed version (for example, `MetaList updated to v0.5.0.`). This protection requires an installed version containing the backup safeguard and applies to `metalist update`; direct pip/uv install commands do not run it.
|
|
123
134
|
|
|
124
135
|
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.
|
|
125
136
|
|
|
@@ -279,6 +290,10 @@ convert-from-legacy.py --namespace work --input /path/to/legacy-export.json
|
|
|
279
290
|
|
|
280
291
|
If `--namespace`, `--port`, or `--https-port` are omitted, the import script prompts for them and saves the resulting launch profile inside the target namespace DB. That means a one-time import into `work` can immediately seed later shorthand launches like `metalist work`.
|
|
281
292
|
|
|
293
|
+
Namespace startup allows 120 seconds per child, reports progress every five seconds, and stops/reaps a failed child instead of leaving it running after reporting failure. Set `METALIST_STARTUP_TIMEOUT_SECONDS` to a positive number of seconds to allow more time on a heavily loaded machine. A crashed child still fails immediately. This is a startup allowance, not a guarantee that any machine will finish within two minutes.
|
|
294
|
+
|
|
295
|
+
The preflight is a disposable empty namespace; it cannot guarantee startup against every real database or prevent a later disk/process failure. If installation succeeds but real namespace startup fails, the new package remains installed: resolve the reported startup issue and run `metalist` again. No automatic code/database rollback is attempted, and backups remain unchanged.
|
|
296
|
+
|
|
282
297
|
### Publishing
|
|
283
298
|
For the real user-facing install flow:
|
|
284
299
|
```bash
|
|
@@ -288,15 +303,15 @@ uv tool install metalist
|
|
|
288
303
|
metalist
|
|
289
304
|
```
|
|
290
305
|
|
|
291
|
-
This repo now packages itself under the PyPI distribution name `metalist`. Current releases support Python 3.10 through 3.
|
|
306
|
+
This repo now packages itself under the PyPI distribution name `metalist`. Current releases support Python 3.10 through 3.14.
|
|
292
307
|
|
|
293
308
|
Recommended release path:
|
|
294
309
|
1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
|
|
295
|
-
2. Push the candidate commit to a branch and wait for the `Publish to PyPI` validation workflow to pass 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.
|
|
310
|
+
2. Push the candidate commit to a branch and wait for the `Publish to PyPI` validation workflow to pass 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 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 also checks runtime files, including agent Markdown resources, against both the wheel and source distribution.
|
|
296
311
|
3. Only after every required check passes, create and push the release tag for that same commit. Any intervening change requires a new validation run before tagging. Branch and pull-request runs validate without publishing.
|
|
297
312
|
4. The tag workflow repeats validation and publishes the same artifacts tested by its full matrix. Manual publication also requires all checks to pass. Users can then run it with `uvx metalist`, install it persistently with `uv tool install metalist`, or install it with `pip install metalist`.
|
|
298
313
|
|
|
299
|
-
If `--input` is omitted, a file picker opens (when `tkinter`
|
|
314
|
+
If `--input` is omitted, a file picker opens (when `tkinter` and its native `_tkinter` component are available).
|
|
300
315
|
Notes tagged with `@implies` are converted into ontology rules and are not imported as notes. Legacy rules that are invalid under the current ontology grammar are reported and skipped while valid rules continue importing.
|
|
301
316
|
|
|
302
317
|
### Run Tests
|
|
@@ -12,6 +12,17 @@ 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.6.2
|
|
16
|
+
|
|
17
|
+
- Namespace startup allows two minutes, with progress every five seconds, instead of failing after 12 seconds on a busy machine. `METALIST_STARTUP_TIMEOUT_SECONDS` can increase the allowance. Failed children are stopped and reaped.
|
|
18
|
+
- Updates preserve the running Python interpreter and validate a disposable installation and namespace startup before stopping live servers. uv then installs the tested package/dependency versions from its cache without network access.
|
|
19
|
+
- Python 3.14 is supported. Command-line legacy imports also work when Python lacks Tk's native GUI component.
|
|
20
|
+
- Release validation now includes the real uv update, backups, and multi-namespace restart on Windows, macOS, and Linux across Python 3.10–3.14.
|
|
21
|
+
|
|
22
|
+
## Changes in 0.6.1
|
|
23
|
+
|
|
24
|
+
- Removed the unused performance overlay, including its menu option and background state updates, fixing a fatal redundant-state error during note rearranging. Obsolete overlay preferences and command usage are discarded automatically.
|
|
25
|
+
|
|
15
26
|
## Changes in 0.6.0
|
|
16
27
|
|
|
17
28
|
- Open notes and their children in multiple live, read-only floating windows. Drag and resize them, keep them visible across searches and tabs, and follow links or copy passwords. Saved changes refresh every half second.
|
|
@@ -79,11 +90,11 @@ After the first installation, update and restart MetaList with one cross-platfor
|
|
|
79
90
|
```bash
|
|
80
91
|
metalist update
|
|
81
92
|
```
|
|
82
|
-
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 checks the
|
|
93
|
+
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 checks installer prerequisites and uses uv to install the candidate into a disposable tool environment with the current base Python interpreter. It checks dependencies and starts a temporary namespace to verify HTTP readiness, version, and runtime assets. A failed preflight leaves the current installation and running namespaces unchanged. After preflight succeeds, it stops running namespaces, and creates and verifies a new backup of every namespace before installation can begin. Each archive includes the complete notes/settings database, the attachments database when present, and any legacy search-history database. Locked namespaces are backed up with their encrypted data and key metadata intact, without requiring a password.
|
|
83
94
|
|
|
84
95
|
Backups are saved to `~/MetaList/namespaces/<namespace>/backups/<namespace>-<timestamp>.metalist-backup.tar.gz`; the updater prints each verified path. Existing backups remain unchanged and are not pruned. If any backup fails, the update aborts with the current installation intact; run `metalist` to restart the stopped servers after resolving the failure.
|
|
85
96
|
|
|
86
|
-
Only after all backups pass does the updater hand off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock. It
|
|
97
|
+
Only after all backups pass does the updater hand off to an external PowerShell process on Windows or `/bin/sh` on macOS/Linux so the installed environment can unlock. It delegates installation to uv, pinning the current base interpreter and the exact tested package/dependency versions, using the cache populated during preflight with network access disabled. It then launches MetaList again, and reports the installed version (for example, `MetaList updated to v0.5.0.`). This protection requires an installed version containing the backup safeguard and applies to `metalist update`; direct pip/uv install commands do not run it.
|
|
87
98
|
|
|
88
99
|
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.
|
|
89
100
|
|
|
@@ -243,6 +254,10 @@ convert-from-legacy.py --namespace work --input /path/to/legacy-export.json
|
|
|
243
254
|
|
|
244
255
|
If `--namespace`, `--port`, or `--https-port` are omitted, the import script prompts for them and saves the resulting launch profile inside the target namespace DB. That means a one-time import into `work` can immediately seed later shorthand launches like `metalist work`.
|
|
245
256
|
|
|
257
|
+
Namespace startup allows 120 seconds per child, reports progress every five seconds, and stops/reaps a failed child instead of leaving it running after reporting failure. Set `METALIST_STARTUP_TIMEOUT_SECONDS` to a positive number of seconds to allow more time on a heavily loaded machine. A crashed child still fails immediately. This is a startup allowance, not a guarantee that any machine will finish within two minutes.
|
|
258
|
+
|
|
259
|
+
The preflight is a disposable empty namespace; it cannot guarantee startup against every real database or prevent a later disk/process failure. If installation succeeds but real namespace startup fails, the new package remains installed: resolve the reported startup issue and run `metalist` again. No automatic code/database rollback is attempted, and backups remain unchanged.
|
|
260
|
+
|
|
246
261
|
### Publishing
|
|
247
262
|
For the real user-facing install flow:
|
|
248
263
|
```bash
|
|
@@ -252,15 +267,15 @@ uv tool install metalist
|
|
|
252
267
|
metalist
|
|
253
268
|
```
|
|
254
269
|
|
|
255
|
-
This repo now packages itself under the PyPI distribution name `metalist`. Current releases support Python 3.10 through 3.
|
|
270
|
+
This repo now packages itself under the PyPI distribution name `metalist`. Current releases support Python 3.10 through 3.14.
|
|
256
271
|
|
|
257
272
|
Recommended release path:
|
|
258
273
|
1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
|
|
259
|
-
2. Push the candidate commit to a branch and wait for the `Publish to PyPI` validation workflow to pass 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.
|
|
274
|
+
2. Push the candidate commit to a branch and wait for the `Publish to PyPI` validation workflow to pass 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 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 also checks runtime files, including agent Markdown resources, against both the wheel and source distribution.
|
|
260
275
|
3. Only after every required check passes, create and push the release tag for that same commit. Any intervening change requires a new validation run before tagging. Branch and pull-request runs validate without publishing.
|
|
261
276
|
4. The tag workflow repeats validation and publishes the same artifacts tested by its full matrix. Manual publication also requires all checks to pass. Users can then run it with `uvx metalist`, install it persistently with `uv tool install metalist`, or install it with `pip install metalist`.
|
|
262
277
|
|
|
263
|
-
If `--input` is omitted, a file picker opens (when `tkinter`
|
|
278
|
+
If `--input` is omitted, a file picker opens (when `tkinter` and its native `_tkinter` component are available).
|
|
264
279
|
Notes tagged with `@implies` are converted into ontology rules and are not imported as notes. Legacy rules that are invalid under the current ontology grammar are reported and skipped while valid rules continue importing.
|
|
265
280
|
|
|
266
281
|
### Run Tests
|
|
@@ -5,6 +5,11 @@ syntax suppressions and is consumed by runtime capture and the startup gate.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
CAPTURE_BOUNDARIES = {
|
|
8
|
+
# Release smoke polls only its own disposable HTTP listeners during an actual update.
|
|
9
|
+
'scripts/smoke_self_update.py:_has_updated_namespace:probe_capture': ('HTTPError',),
|
|
10
|
+
# A child can exit between poll and terminate; hung children must be killed and reaped.
|
|
11
|
+
'app/services/namespace_switcher.py:_stop_failed_namespace_launch:terminate_capture': ('ProcessLookupError',),
|
|
12
|
+
'app/services/namespace_switcher.py:_stop_failed_namespace_launch:wait_capture': ('TimeoutExpired',),
|
|
8
13
|
# Translate explicitly validated domain input/resource rejection.
|
|
9
14
|
'app/api/routes/auth.py:_delete_namespace_from_body:delete_capture': ('NamespaceInputRejected', 'FileNotFoundError'),
|
|
10
15
|
# Translate explicitly validated domain input/resource rejection.
|
|
@@ -44,7 +44,6 @@ _ALLOWED_CLIENT_PREFERENCES = {
|
|
|
44
44
|
"pref.show_tab_ui": {"true", "false"},
|
|
45
45
|
"pref.show_search_results_count": {"true", "false"},
|
|
46
46
|
"pref.show_ai_chat": {"true", "false"},
|
|
47
|
-
"pref.show_perf_overlay": {"true", "false"},
|
|
48
47
|
"pref.animated_transitions": {"true", "false"},
|
|
49
48
|
"pref.reminder_surface_expanded": {"true", "false"},
|
|
50
49
|
"pref.note_layout.top_level_note_size": {"same", "larger", "largest"},
|
|
@@ -80,6 +79,7 @@ _ALLOWED_CLIENT_PREFERENCES = {
|
|
|
80
79
|
|
|
81
80
|
_OBSOLETE_CLIENT_PREFERENCES = frozenset(
|
|
82
81
|
{
|
|
82
|
+
"pref.show_perf_overlay",
|
|
83
83
|
"pref.reminder_default_popup_sound_enabled",
|
|
84
84
|
"pref.reminder_default_popup_sound_id",
|
|
85
85
|
"pref.reminder_default_ack_sound_enabled",
|
|
@@ -281,6 +281,8 @@ def _validate_usage_state(usage_state: dict[str, object]) -> dict[str, dict[str,
|
|
|
281
281
|
for endpoint_id, raw_record in usage_state.items():
|
|
282
282
|
if not isinstance(endpoint_id, str) or endpoint_id == "":
|
|
283
283
|
raise ClientStateValidationError("usage endpoint ids must be non-empty strings")
|
|
284
|
+
if endpoint_id in _OBSOLETE_CLIENT_PREFERENCES:
|
|
285
|
+
continue
|
|
284
286
|
if not isinstance(raw_record, dict):
|
|
285
287
|
raise ClientStateValidationError(f"Usage record for {endpoint_id} must be an object")
|
|
286
288
|
if "count" not in raw_record:
|
|
@@ -41,7 +41,8 @@ from app.services.input_errors import NamespaceInputRejected
|
|
|
41
41
|
|
|
42
42
|
_PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
43
43
|
_PLACEHOLDER_NEW_NAMESPACE = "new-namespace"
|
|
44
|
-
_LAUNCH_READY_TIMEOUT_SECONDS =
|
|
44
|
+
_LAUNCH_READY_TIMEOUT_SECONDS = 120.0
|
|
45
|
+
_LAUNCH_PROGRESS_INTERVAL_SECONDS = 5.0
|
|
45
46
|
_PORT_PROBE_TIMEOUT_SECONDS = 0.75
|
|
46
47
|
_READY_POLL_INTERVAL_SECONDS = 0.25
|
|
47
48
|
_PROCESS_WAIT_POLL_INTERVAL_SECONDS = 0.25
|
|
@@ -1568,6 +1569,7 @@ def _launch_namespace_process(
|
|
|
1568
1569
|
if name in child_environ:
|
|
1569
1570
|
del child_environ[name]
|
|
1570
1571
|
child_environ[ORCHESTRATED_CHILD_ENV_NAME] = "1"
|
|
1572
|
+
child_environ["PYTHONUNBUFFERED"] = "1"
|
|
1571
1573
|
command = _resolve_main_launch_command(environ=child_environ)
|
|
1572
1574
|
command.extend(
|
|
1573
1575
|
[
|
|
@@ -1664,18 +1666,69 @@ def _read_namespace_launch_log_tail(*, log_path: Path, log_start_offset: int) ->
|
|
|
1664
1666
|
return tail
|
|
1665
1667
|
|
|
1666
1668
|
|
|
1669
|
+
def _stop_failed_namespace_launch(*, process: subprocess.Popen[bytes]) -> None:
|
|
1670
|
+
if process.poll() is not None:
|
|
1671
|
+
return
|
|
1672
|
+
terminate_capture = CapturedExceptionContext(
|
|
1673
|
+
ProcessLookupError,
|
|
1674
|
+
boundary='app/services/namespace_switcher.py:_stop_failed_namespace_launch:terminate_capture',
|
|
1675
|
+
)
|
|
1676
|
+
with terminate_capture:
|
|
1677
|
+
process.terminate()
|
|
1678
|
+
wait_capture = CapturedExceptionContext(
|
|
1679
|
+
subprocess.TimeoutExpired,
|
|
1680
|
+
boundary='app/services/namespace_switcher.py:_stop_failed_namespace_launch:wait_capture',
|
|
1681
|
+
)
|
|
1682
|
+
with wait_capture:
|
|
1683
|
+
process.wait(timeout=_TERMINATE_GRACE_SECONDS)
|
|
1684
|
+
if wait_capture.captured_exception is not None:
|
|
1685
|
+
process.kill()
|
|
1686
|
+
process.wait(timeout=_KILL_GRACE_SECONDS)
|
|
1687
|
+
|
|
1688
|
+
|
|
1667
1689
|
def _wait_for_namespace_ready(
|
|
1668
1690
|
*,
|
|
1669
1691
|
environ: Mapping[str, str],
|
|
1670
1692
|
namespace: str,
|
|
1671
1693
|
port: int,
|
|
1672
1694
|
launched_process: NamespaceLaunchProcess,
|
|
1695
|
+
) -> None:
|
|
1696
|
+
is_ready = False
|
|
1697
|
+
try:
|
|
1698
|
+
_poll_namespace_readiness(
|
|
1699
|
+
environ=environ, namespace=namespace, port=port,
|
|
1700
|
+
launched_process=launched_process,
|
|
1701
|
+
)
|
|
1702
|
+
is_ready = True
|
|
1703
|
+
finally:
|
|
1704
|
+
if not is_ready:
|
|
1705
|
+
_stop_failed_namespace_launch(process=launched_process.process)
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
def _poll_namespace_readiness(
|
|
1709
|
+
*,
|
|
1710
|
+
environ: Mapping[str, str],
|
|
1711
|
+
namespace: str,
|
|
1712
|
+
port: int,
|
|
1713
|
+
launched_process: NamespaceLaunchProcess,
|
|
1673
1714
|
) -> None:
|
|
1674
1715
|
main_server_config = resolve_main_server_config(environ=environ)
|
|
1675
1716
|
connect_host = resolve_backend_connect_host(host=main_server_config.host)
|
|
1676
1717
|
api_prefix = resolve_api_prefix(environ=environ)
|
|
1677
|
-
|
|
1718
|
+
started_at = time.monotonic()
|
|
1719
|
+
timeout_text = environ.get("METALIST_STARTUP_TIMEOUT_SECONDS")
|
|
1720
|
+
timeout = _LAUNCH_READY_TIMEOUT_SECONDS
|
|
1721
|
+
if timeout_text is not None:
|
|
1722
|
+
if not timeout_text.isascii() or not timeout_text.isdigit() or int(timeout_text) <= 0:
|
|
1723
|
+
raise ValueError("METALIST_STARTUP_TIMEOUT_SECONDS must be a positive integer")
|
|
1724
|
+
timeout = float(timeout_text)
|
|
1725
|
+
deadline = started_at + timeout
|
|
1726
|
+
next_progress = started_at + _LAUNCH_PROGRESS_INTERVAL_SECONDS
|
|
1678
1727
|
while time.monotonic() < deadline:
|
|
1728
|
+
now = time.monotonic()
|
|
1729
|
+
if now >= next_progress:
|
|
1730
|
+
print(f"Still starting namespace {namespace} ({now - started_at:.0f}s elapsed)...", flush=True)
|
|
1731
|
+
next_progress = now + _LAUNCH_PROGRESS_INTERVAL_SECONDS
|
|
1679
1732
|
exit_code = launched_process.process.poll()
|
|
1680
1733
|
if exit_code is not None:
|
|
1681
1734
|
log_tail = _read_namespace_launch_log_tail(
|
|
@@ -17,6 +17,7 @@ from app.server_runtime import resolve_namespaces_directory
|
|
|
17
17
|
from app.services.exception_capture import CapturedExceptionContext
|
|
18
18
|
from app.services.namespace_switcher import stop_all_namespace_processes_for_update
|
|
19
19
|
from app.services.update_backups import backup_all_namespaces_for_update
|
|
20
|
+
from app.services.update_preflight import prepare_update as _prepare_update
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
_WINDOWS_CREATE_NEW_CONSOLE = 0x00000010
|
|
@@ -73,13 +74,20 @@ def schedule_self_update(
|
|
|
73
74
|
if uv_executable is None:
|
|
74
75
|
raise RuntimeError("uv executable was not found on PATH; MetaList was not stopped")
|
|
75
76
|
|
|
77
|
+
if platform_name == "win32":
|
|
78
|
+
_resolve_windows_powershell()
|
|
79
|
+
elif not Path("/bin/sh").is_file():
|
|
80
|
+
raise RuntimeError("/bin/sh is required for MetaList self-update; MetaList was not stopped")
|
|
81
|
+
install_command = _prepare_update(
|
|
82
|
+
uv_executable=uv_executable, target_version=target_version, environ=environ,
|
|
83
|
+
)
|
|
76
84
|
updater_command: list[str]
|
|
77
85
|
updater_options: dict[str, object]
|
|
78
86
|
if platform_name == "win32":
|
|
79
87
|
powershell_executable = _resolve_windows_powershell()
|
|
80
88
|
updater_command = _build_windows_updater_command(
|
|
81
89
|
powershell_executable=powershell_executable,
|
|
82
|
-
|
|
90
|
+
install_command=install_command,
|
|
83
91
|
metalist_executable=metalist_executable,
|
|
84
92
|
current_pid=current_pid,
|
|
85
93
|
target_version=target_version,
|
|
@@ -95,7 +103,7 @@ def schedule_self_update(
|
|
|
95
103
|
raise RuntimeError("/bin/sh is required for MetaList self-update; MetaList was not stopped")
|
|
96
104
|
updater_command = _build_posix_updater_command(
|
|
97
105
|
shell_executable=str(shell_path),
|
|
98
|
-
|
|
106
|
+
install_command=install_command,
|
|
99
107
|
metalist_executable=metalist_executable,
|
|
100
108
|
current_pid=current_pid,
|
|
101
109
|
target_version=target_version,
|
|
@@ -207,18 +215,17 @@ def _quote_powershell_literal(value: str) -> str:
|
|
|
207
215
|
def _build_windows_updater_command(
|
|
208
216
|
*,
|
|
209
217
|
powershell_executable: str,
|
|
210
|
-
|
|
218
|
+
install_command: list[str],
|
|
211
219
|
metalist_executable: str,
|
|
212
220
|
current_pid: int,
|
|
213
221
|
target_version: str,
|
|
214
222
|
) -> list[str]:
|
|
215
|
-
|
|
223
|
+
quoted_install = " ".join(_quote_powershell_literal(part) for part in install_command)
|
|
216
224
|
quoted_metalist = _quote_powershell_literal(metalist_executable)
|
|
217
|
-
quoted_package = _quote_powershell_literal(f"metalist=={target_version}")
|
|
218
225
|
script = (
|
|
219
226
|
f"while (Get-Process -Id {current_pid} -ErrorAction SilentlyContinue) "
|
|
220
227
|
"{ Start-Sleep -Milliseconds 100 }; "
|
|
221
|
-
f"& {
|
|
228
|
+
f"& {quoted_install}; "
|
|
222
229
|
"if ($LASTEXITCODE -ne 0) { "
|
|
223
230
|
"Write-Host 'MetaList update failed. Review the uv output above.' -ForegroundColor Red; "
|
|
224
231
|
"Start-Sleep -Seconds 10; exit $LASTEXITCODE }; "
|
|
@@ -243,22 +250,12 @@ def _build_windows_updater_command(
|
|
|
243
250
|
def _build_posix_updater_command(
|
|
244
251
|
*,
|
|
245
252
|
shell_executable: str,
|
|
246
|
-
|
|
253
|
+
install_command: list[str],
|
|
247
254
|
metalist_executable: str,
|
|
248
255
|
current_pid: int,
|
|
249
256
|
target_version: str,
|
|
250
257
|
) -> list[str]:
|
|
251
|
-
uv_command = shlex.join(
|
|
252
|
-
[
|
|
253
|
-
uv_executable,
|
|
254
|
-
"tool",
|
|
255
|
-
"install",
|
|
256
|
-
"--force",
|
|
257
|
-
"--reinstall",
|
|
258
|
-
"--refresh",
|
|
259
|
-
f"metalist=={target_version}",
|
|
260
|
-
]
|
|
261
|
-
)
|
|
258
|
+
uv_command = shlex.join(install_command)
|
|
262
259
|
metalist_command = shlex.join([metalist_executable])
|
|
263
260
|
script = (
|
|
264
261
|
f"while kill -0 {current_pid} 2>/dev/null; do sleep 0.1; done\n"
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Validate an update in a disposable installation before stopping live namespaces."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from collections.abc import Mapping
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import socket
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
from tempfile import TemporaryDirectory
|
|
12
|
+
|
|
13
|
+
import httpx
|
|
14
|
+
|
|
15
|
+
from app.services.namespace_switcher import NamespaceLaunchProcess
|
|
16
|
+
from app.services.namespace_switcher import _stop_failed_namespace_launch
|
|
17
|
+
from app.services.namespace_switcher import _wait_for_namespace_ready
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _run_checked(command: list[str], *, environ: Mapping[str, str], directory: Path) -> str:
|
|
21
|
+
completed = subprocess.run(
|
|
22
|
+
command, env=dict(environ), cwd=directory, capture_output=True,
|
|
23
|
+
text=True, encoding="utf-8", check=False, timeout=600,
|
|
24
|
+
)
|
|
25
|
+
if completed.returncode != 0:
|
|
26
|
+
raise RuntimeError(
|
|
27
|
+
"Update preflight failed; the current installation and running namespaces "
|
|
28
|
+
f"were not changed.\n{completed.stdout}\n{completed.stderr}"
|
|
29
|
+
)
|
|
30
|
+
return completed.stdout
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _probe_candidate(*, python: str, executable: str, directory: Path,
|
|
34
|
+
environ: Mapping[str, str], target_version: str) -> None:
|
|
35
|
+
probe_environ = {
|
|
36
|
+
key: value for key, value in environ.items()
|
|
37
|
+
if not key.startswith(("METALIST_", "UVICORN_", "SECURITY_", "PYTHON"))
|
|
38
|
+
and key not in {"TEST_MODE", "API_PREFIX", "V1_API_PREFIX", "SQL_TRACE"}
|
|
39
|
+
}
|
|
40
|
+
probe_environ.update(
|
|
41
|
+
METALIST_DATA_DIRECTORY=str(directory / "probe-data"),
|
|
42
|
+
METALIST_ENVIRONMENT="production", METALIST_AUTO_GENERATE_TLS="0",
|
|
43
|
+
PYTHONUNBUFFERED="1", PYTHONUTF8="1", TEST_MODE="0",
|
|
44
|
+
)
|
|
45
|
+
if "METALIST_STARTUP_TIMEOUT_SECONDS" in environ:
|
|
46
|
+
probe_environ["METALIST_STARTUP_TIMEOUT_SECONDS"] = environ["METALIST_STARTUP_TIMEOUT_SECONDS"]
|
|
47
|
+
with socket.socket() as reservation:
|
|
48
|
+
reservation.bind(("127.0.0.1", 0))
|
|
49
|
+
port = reservation.getsockname()[1]
|
|
50
|
+
_run_checked([
|
|
51
|
+
python, "-I", "-c",
|
|
52
|
+
"import sys; from app.server_runtime import save_namespace_launch_profile; "
|
|
53
|
+
"save_namespace_launch_profile(namespace='update-probe', port=int(sys.argv[1]), https_port=None, mcp_port=None)",
|
|
54
|
+
str(port),
|
|
55
|
+
], environ=probe_environ, directory=directory)
|
|
56
|
+
log_path = directory / "startup.log"
|
|
57
|
+
with log_path.open("wb") as log:
|
|
58
|
+
process = subprocess.Popen(
|
|
59
|
+
[executable, "--namespace", "update-probe", "--port", str(port)],
|
|
60
|
+
cwd=directory, env=probe_environ, stdout=log, stderr=subprocess.STDOUT,
|
|
61
|
+
)
|
|
62
|
+
try:
|
|
63
|
+
_wait_for_namespace_ready(
|
|
64
|
+
environ=probe_environ, namespace="update-probe", port=port,
|
|
65
|
+
launched_process=NamespaceLaunchProcess(process, log_path, 0),
|
|
66
|
+
)
|
|
67
|
+
with httpx.Client(
|
|
68
|
+
base_url=f"http://127.0.0.1:{port}", timeout=15, trust_env=False,
|
|
69
|
+
headers={"X-Metalist-Tab-Id": "00000000-0000-4000-8000-000000000001"},
|
|
70
|
+
) as client:
|
|
71
|
+
status = client.get("/api2/auth/status")
|
|
72
|
+
status.raise_for_status()
|
|
73
|
+
if status.json()["version"] != target_version:
|
|
74
|
+
raise RuntimeError("Update candidate started with the wrong version")
|
|
75
|
+
for path in ("/", "/static/js/main.js", "/static/css/main.css", "/static/note-html-policy.json"):
|
|
76
|
+
response = client.get(path)
|
|
77
|
+
response.raise_for_status()
|
|
78
|
+
if len(response.content) == 0:
|
|
79
|
+
raise RuntimeError(f"Update candidate has an empty runtime resource: {path}")
|
|
80
|
+
finally:
|
|
81
|
+
_stop_failed_namespace_launch(process=process)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def prepare_update(*, uv_executable: str, target_version: str,
|
|
85
|
+
environ: Mapping[str, str]) -> list[str]:
|
|
86
|
+
# A tool environment is replaced during install: pin its external base interpreter.
|
|
87
|
+
python = str(Path(sys._base_executable).resolve())
|
|
88
|
+
if not Path(python).is_file():
|
|
89
|
+
raise RuntimeError("The current base Python interpreter is missing; MetaList was not stopped")
|
|
90
|
+
print(f"Checking MetaList v{target_version} installation and startup with Python {sys.version.split()[0]}...", flush=True)
|
|
91
|
+
with TemporaryDirectory(prefix="metalist-update-check-") as temporary:
|
|
92
|
+
directory = Path(temporary)
|
|
93
|
+
stage_environ = dict(environ)
|
|
94
|
+
stage_environ.update(UV_TOOL_DIR=str(directory / "tools"), UV_TOOL_BIN_DIR=str(directory / "bin"))
|
|
95
|
+
_run_checked([
|
|
96
|
+
uv_executable, "tool", "install", "--python", python,
|
|
97
|
+
"--refresh", "--compile-bytecode", f"metalist=={target_version}",
|
|
98
|
+
], environ=stage_environ, directory=directory)
|
|
99
|
+
if sys.platform == "win32":
|
|
100
|
+
scripts = directory / "tools" / "metalist" / "Scripts"
|
|
101
|
+
candidate_python = str(scripts / "python.exe")
|
|
102
|
+
candidate_cli = str(scripts / "metalist.exe")
|
|
103
|
+
else:
|
|
104
|
+
scripts = directory / "tools" / "metalist" / "bin"
|
|
105
|
+
candidate_python = str(scripts / "python")
|
|
106
|
+
candidate_cli = str(scripts / "metalist")
|
|
107
|
+
identity = json.loads(_run_checked([
|
|
108
|
+
candidate_python, "-I", "-c",
|
|
109
|
+
"import sys,json,importlib.metadata; print(json.dumps([list(sys.version_info[:2]),importlib.metadata.version('metalist')]))",
|
|
110
|
+
], environ=stage_environ, directory=directory))
|
|
111
|
+
if identity != [list(sys.version_info[:2]), target_version]:
|
|
112
|
+
raise RuntimeError("Update preflight changed Python or installed the wrong MetaList version")
|
|
113
|
+
_run_checked([uv_executable, "pip", "check", "--python", candidate_python], environ=stage_environ, directory=directory)
|
|
114
|
+
frozen = _run_checked([uv_executable, "pip", "freeze", "--python", candidate_python], environ=stage_environ, directory=directory)
|
|
115
|
+
_probe_candidate(python=candidate_python, executable=candidate_cli, directory=directory,
|
|
116
|
+
environ=environ, target_version=target_version)
|
|
117
|
+
# Keep the exact tested dependency set. Offline installation reuses the warmed uv cache.
|
|
118
|
+
command = [uv_executable, "tool", "install", "--force", "--offline", "--python", python,
|
|
119
|
+
"--compile-bytecode", f"metalist=={target_version}"]
|
|
120
|
+
for requirement in frozen.splitlines():
|
|
121
|
+
if "==" not in requirement or requirement.startswith("-"):
|
|
122
|
+
raise RuntimeError(f"Update preflight produced an unpinned requirement: {requirement}")
|
|
123
|
+
if requirement.split("==")[0].casefold() != "metalist":
|
|
124
|
+
command.extend(["--with", requirement])
|
|
125
|
+
print("Update installation and startup check passed; packages are cached for offline installation.", flush=True)
|
|
126
|
+
return command
|
|
@@ -20,10 +20,6 @@
|
|
|
20
20
|
"id": "pref.show_ai_chat",
|
|
21
21
|
"tags": ["ai", "chat", "assistant", "ollama", "agent", "right", "panel", "view", "show", "hide", "toggle"]
|
|
22
22
|
},
|
|
23
|
-
{
|
|
24
|
-
"id": "pref.show_perf_overlay",
|
|
25
|
-
"tags": ["perf", "performance", "overlay", "debug", "metrics", "dev", "ui", "show", "hide", "toggle"]
|
|
26
|
-
},
|
|
27
23
|
{
|
|
28
24
|
"id": "pref.animated_transitions",
|
|
29
25
|
"tags": ["animated", "animations", "animation", "transitions", "motion", "movement", "ui", "show", "hide", "toggle", "enable", "disable"]
|
|
@@ -6,11 +6,11 @@ const LEGACY_CLIENT_PREFERENCE_KEYS = [
|
|
|
6
6
|
'pref.show_backlinks',
|
|
7
7
|
'pref.show_note_tags',
|
|
8
8
|
'pref.show_tab_ui',
|
|
9
|
-
'pref.show_perf_overlay',
|
|
10
9
|
'pref.theme',
|
|
11
10
|
];
|
|
12
11
|
const LEGACY_OBSOLETE_CLIENT_PREFERENCE_KEYS = [
|
|
13
12
|
'pref.show_rhs_panel',
|
|
13
|
+
'pref.show_perf_overlay',
|
|
14
14
|
];
|
|
15
15
|
|
|
16
16
|
|
|
@@ -37,6 +37,7 @@ function normalizePreferences(rawPreferences) {
|
|
|
37
37
|
if (typeof key !== 'string' || key.length === 0) {
|
|
38
38
|
throw new Error('Preference keys must be non-empty strings');
|
|
39
39
|
}
|
|
40
|
+
if (LEGACY_OBSOLETE_CLIENT_PREFERENCE_KEYS.includes(key)) continue;
|
|
40
41
|
if (typeof value !== 'string') {
|
|
41
42
|
throw new Error(`Preference ${key} must be a string`);
|
|
42
43
|
}
|
|
@@ -86,6 +87,7 @@ function normalizeUsageState(rawUsageState) {
|
|
|
86
87
|
if (typeof endpointId !== 'string' || endpointId.length === 0) {
|
|
87
88
|
throw new Error('Usage endpoint ids must be non-empty strings');
|
|
88
89
|
}
|
|
90
|
+
if (LEGACY_OBSOLETE_CLIENT_PREFERENCE_KEYS.includes(endpointId)) continue;
|
|
89
91
|
normalized[endpointId] = normalizeUsageRecord(endpointId, rawRecord);
|
|
90
92
|
}
|
|
91
93
|
return normalized;
|
|
@@ -245,8 +247,8 @@ export async function migrateLegacyClientState({
|
|
|
245
247
|
|
|
246
248
|
if (Object.keys(legacyUsageState).length > 0) {
|
|
247
249
|
await persistCommandPaletteUsageFn(mergedUsageState);
|
|
248
|
-
clearLegacyCommandPaletteUsage();
|
|
249
250
|
}
|
|
251
|
+
clearLegacyCommandPaletteUsage();
|
|
250
252
|
|
|
251
253
|
return {
|
|
252
254
|
preferences: mergedPreferences,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
removeAllTagSuggestionsFromCurrentContext,
|
|
7
7
|
} from '../ai-chat/proposal-menu.js';
|
|
8
8
|
import { ModeContextInstance as ModeContext } from '../mode-manager/mode-context.js';
|
|
9
|
-
import { actionRefreshAndMaybeSelect
|
|
9
|
+
import { actionRefreshAndMaybeSelect } from '../mode-manager/actions/ui-actions.js';
|
|
10
10
|
import {
|
|
11
11
|
actionDeselectNote,
|
|
12
12
|
actionSaveAndExitEditingWithoutRefreshing,
|
|
@@ -541,15 +541,6 @@ class CommandPaletteController {
|
|
|
541
541
|
}));
|
|
542
542
|
}
|
|
543
543
|
|
|
544
|
-
const showPerfOverlay = this._getBoolean('pref.show_perf_overlay', false);
|
|
545
|
-
document.body.classList.toggle('pref-show-perf-overlay', showPerfOverlay);
|
|
546
|
-
if (!showPerfOverlay) {
|
|
547
|
-
const perfOverlay = document.getElementById('perf-overlay');
|
|
548
|
-
if (perfOverlay) {
|
|
549
|
-
perfOverlay.remove();
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
544
|
const animatedTransitions = this._getBoolean('pref.animated_transitions', true);
|
|
554
545
|
document.body.classList.toggle('pref-animated-transitions', animatedTransitions);
|
|
555
546
|
|
|
@@ -1355,15 +1346,6 @@ class CommandPaletteController {
|
|
|
1355
1346
|
if (typeof value === 'boolean') {
|
|
1356
1347
|
await this._preferences.setRaw(prefKey, value ? 'true' : 'false');
|
|
1357
1348
|
this._applyPreferenceEffectsFromStorage();
|
|
1358
|
-
if (prefKey === 'pref.show_perf_overlay' && value) {
|
|
1359
|
-
const hadCache = showPerfOverlayFromCache();
|
|
1360
|
-
if (!hadCache) {
|
|
1361
|
-
await actionRefreshAndMaybeSelect({
|
|
1362
|
-
startedAt: performance.now(),
|
|
1363
|
-
context: 'pref.show_perf_overlay',
|
|
1364
|
-
});
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
1349
|
return;
|
|
1368
1350
|
}
|
|
1369
1351
|
if (typeof value === 'string') {
|
{metalist-0.6.0 → metalist-0.6.2}/app/static/js/modules/command-palette/endpoint-registry.js
RENAMED
|
@@ -103,7 +103,6 @@ export function buildCommandPaletteEndpoints(deps) {
|
|
|
103
103
|
showTabUi: false,
|
|
104
104
|
showSearchResultsCount: true,
|
|
105
105
|
showAiChat: false,
|
|
106
|
-
showPerfOverlay: false,
|
|
107
106
|
animatedTransitions: true,
|
|
108
107
|
theme: 'system',
|
|
109
108
|
};
|
|
@@ -165,16 +164,6 @@ export function buildCommandPaletteEndpoints(deps) {
|
|
|
165
164
|
defaultValue: defaults.showAiChat,
|
|
166
165
|
apply: (next) => applyPreference('pref.show_ai_chat', next),
|
|
167
166
|
},
|
|
168
|
-
{
|
|
169
|
-
id: 'pref.show_perf_overlay',
|
|
170
|
-
kind: 'boolean',
|
|
171
|
-
get label() {
|
|
172
|
-
return visibilityLabel(preferencesStore, 'pref.show_perf_overlay', defaults.showPerfOverlay, 'performance overlay');
|
|
173
|
-
},
|
|
174
|
-
persistenceKey: 'pref.show_perf_overlay',
|
|
175
|
-
defaultValue: defaults.showPerfOverlay,
|
|
176
|
-
apply: (next) => applyPreference('pref.show_perf_overlay', next),
|
|
177
|
-
},
|
|
178
167
|
{
|
|
179
168
|
id: 'pref.animated_transitions',
|
|
180
169
|
kind: 'boolean',
|