MetaList 0.6.1__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.1/metalist.egg-info → metalist-0.6.2}/PKG-INFO +18 -7
- {metalist-0.6.1 → metalist-0.6.2}/README.md +16 -5
- {metalist-0.6.1 → metalist-0.6.2}/app/exception_boundaries.py +5 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/namespace_switcher.py +55 -2
- {metalist-0.6.1 → 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.1 → metalist-0.6.2}/app/version.py +1 -1
- {metalist-0.6.1 → metalist-0.6.2}/convert-from-legacy.py +4 -1
- {metalist-0.6.1 → metalist-0.6.2/metalist.egg-info}/PKG-INFO +18 -7
- {metalist-0.6.1 → metalist-0.6.2}/metalist.egg-info/SOURCES.txt +1 -0
- {metalist-0.6.1 → metalist-0.6.2}/pyproject.toml +1 -1
- {metalist-0.6.1 → metalist-0.6.2}/MANIFEST.in +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/deps.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/dev.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/middleware/auth.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/note_requests.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/request_auth.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/ai.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/auth.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/backups.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/files.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/notes.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/ontology.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/reminders.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/remote_images.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/routes/test.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/transactions.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/api/upload_limits.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/config.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/data_directory.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/backup_settings_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/engine.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/file_schema.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/file_session.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/files_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/link_titles_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/live_recovery.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/migrations.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/notes_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/ontology_rules_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/reminders_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/retire_sounds.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/schema.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/search_history_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/session.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/settings_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/tab_state_sql.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/db/version.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/encryption_audit.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/https_proxy.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/main.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/commands.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/database.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/entities.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/enums.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/linked_list.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/list_operations.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/list_traversal.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/note_crud.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/models/utils.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/presentation/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/presentation/render/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/presentation/render/note_renderer.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/presentation/templates.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/authenticated_logging.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/encryption.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/http_headers.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/note_html.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/request_boundary.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/sensitive_cache.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/sensitive_logging.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/shell_execution.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/security/validation_errors.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/server_runtime.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/actions.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/cloud_privacy.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/context.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/evidence_serialization.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/inference.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/investigation.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/model_policy.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/ollama_inference.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/openai_cost_tracking.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/openai_inference.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/permissions.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/prompt_settings.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/prompts/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/prompts/final-response.md +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/prompts/system.md +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/prompts/tool-result.md +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/retrieval_settings.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/runtime.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/scope.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/skill_settings.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/skills/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/skills/scoped-investigation.md +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/tagging.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/tagging_run.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/token_estimation.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/tools.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/agent/trace.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/ai_chat.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/ai_chat_rendering.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/ai_chat_stream.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/auth.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/auth_cache_state.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/auth_service.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/backlink_index.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/backlinks.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/backup_service.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/backup_settings_service.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/bulk_operation.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/client_state_service.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/content_cache.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/content_formatting.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/diagnostics.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/embedded_references.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/encryption.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/exception_capture.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/file_registry.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/file_storage.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/footnote_layout.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/footnote_rendering.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/hierarchy.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/html_export.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/html_unformatting.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/hydration_state.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/image_size_formatting.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/inline_image_occurrences.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/input_errors.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/integrity.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/latex_rendering.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/link_titles.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/login_rate_limit.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/maintenance_mode.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/managed_ollama_runtime.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/markdown_rendering.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/namespace_deletion_jobs.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/namespace_deletion_worker.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/namespace_rename_jobs.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/namespace_rename_worker.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/namespace_runtime_guard.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/note_fullscreen.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/note_image_tags.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/note_ordering.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/note_store.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/ollama_provider.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/ontology_rules_store.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/openai_credentials.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/password_note_fields.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/reference_presentation.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/reminders.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/remote_image_proxy.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/request_recovery.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/resource_limits.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/root_sorting.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/runtime_generation.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/runtime_hardening.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/runtime_lock.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/search_history.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/search_history_storage.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/search_index.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/search_query.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/search_text.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/selected_text_tag.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/session_timeout_service.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/shell_session_service.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/snapshot.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/store.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/structured_note_renderers.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/sync.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/sync_state.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/tab_state.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/tag_case.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/tag_ontology.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/tag_rename.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/tag_suggestions.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/tag_term_matching.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/test_reset.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/tokens.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/undo_state.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/update_backups.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/view_cache.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/view_diff.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/view_state.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/services/windows_process_control.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/startup_environment.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/startup_js_sanity.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/startup_sanity.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/startup_sanity_config.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/config/command_palette_tags.json +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/css/floating-notes.css +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/css/forms.css +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/css/main.css +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/img/favicon.ico +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/locked.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/main.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/activity-tracker.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/agent-prompt-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/agent-retrieval-settings.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-agent-debug-view.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-chat-api.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-chat-panel-controller.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-chat-panel-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/ai-thinking-level-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/bulk-elapsed-clock.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/bulk-proposal-ui.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/cloud-privacy-policy.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/ai-chat/proposal-menu.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/api-client.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/api-failure-classification-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/application-state.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/async-result.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/auth.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/client-state-api.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/client-state-migration.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/activation-auth-policy.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/backup-command-availability.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/click-activation-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/command-palette-controller.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/endpoint-registry.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/note-layout-preferences.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/preferences-store.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/tag-config-loader.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/command-palette/usage-store.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/config.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/connectivity-monitor.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/context-menu/context-menu-registry.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/context-menu/context-menu-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/context-menu/context-menu-target-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/context-menu/input-caret-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/disconnect-editing-state-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/dom-utils-fixed.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/dom-utils.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/editor-commands.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/editor-selection.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/editor-toolbar.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/elapsed-time.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/error-handler.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/error-overlay.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/expected-errors.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/location-flags.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/login-namespace-picker.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/maintenance.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/agent-prompt-editor-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/ai-agent-settings-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/alphabetize-root-notes-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/backup-restore-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/backup-result-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/backup-retention-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/backup-settings-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/base-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/confirmation-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/delete-namespace-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/delete-namespace-validation.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/help-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/namespace-loading-page.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/namespace-modals.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/namespace-ports-profile.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/namespace-rename-validation.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/note-layout-appearance-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/ontology-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/password-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/prioritize-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/random-password-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/reminder-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/reset-updated-at-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/search-suggestion-statistics-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/session-timeout-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/modals/version-info-modal.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/content-actions.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/history-actions.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/note-actions.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/search-actions.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/selection-actions.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/actions/ui-actions.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/context-menu-events.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/focus-events.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/inactivity-events.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/input-events.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/keyboard-events.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/mouse-events.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/events/search-events.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/mode-context.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/mode-logger.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/mode-manager-controller.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/add-style-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/animated-scroll-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/backlinks-navigation-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/backlinks-panel-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/clipboard-shortcut-policy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/collapse-affordance-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/collapse-editing-policy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/command-gate-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/context-menu-target-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/deselect-selection-state-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/differential-view-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/edit-session-collapse-policy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/edit-session-collapse-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/embedded-image-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/file-drop-policy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/file-image-preview-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/file-reference-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/filtered-refresh-selection-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/floating-note-dom.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/floating-note-layout.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/floating-note-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/footnote-navigation-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/history-selection-policy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/history-shortcut-policy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/html-paste-sanitizer-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/image-context-menu-action-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/image-file-insert-choice-modal-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/infinite-scroll-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/link-context-menu-action-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/link-title-prefetch-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/markdown-render-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/mermaid-render-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-click-target-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-clipboard-write-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-collapse-animation-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-context-menu-action-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-delete-shortcut-policy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-drag-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-fullscreen-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-reposition-animation-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-split-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/note-timestamp-hover-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/password-clipboard-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/polling-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/reference-source-navigation-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/remote-image-proxy-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/remove-formatting-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/root-date-separator-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/root-sort-indicator-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/root-sort-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/scroll-anchor-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/scroll-restoration-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/scroll-to-top-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-contexts-overlay-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-debounce-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-input-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-interaction-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-redaction-reveal-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestion-statistics-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestion-window-labels-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestion-windows-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-suggestions-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/search-syntax-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/selected-formatting-removal-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/selected-text-tag-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/shell-output-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-dom-cache-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-drag-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-duplication-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tab-state-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-bar-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-input-selection-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-proposal-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-suggestions-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/tag-syntax-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/todo-toggle-editing-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/untagged-view-indicator-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/mode-manager/services/view-mode-search-shortcut-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/note-html-sanitizer.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/password-generator.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/password-operation-response.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/password-policy.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/password-strength.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/reminder-store.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/reminder-surface-service.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/selection-markers.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/session-auth.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/tag-token.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/modules/uuid.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/namespace-deleted.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/namespace-renamed.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/dompurify-3.4.13.LICENSE.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/dompurify-3.4.13.min.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/markdown-it-14.3.2.LICENSE.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/markdown-it-14.3.2.min.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/mermaid-11.16.1.LICENSE.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/mermaid-11.16.1.min.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/zxcvbn-4.4.2.LICENSE.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/js/vendor/zxcvbn-4.4.2.js +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/note-html-policy.json +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/static/video/login-startup.mp4 +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/templates/base.html +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/templates/index.html +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/templates/locked.html +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/templates/maintenance.html +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/templates/namespace_deleted.html +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/templates/namespace_renamed.html +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/templates/notes_list.html +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/upload_limits.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/add_selected_text_tag.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/alphabetize_root_notes.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/base.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/bulk_tag_proposals.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/collapse.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/copy_note.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/create_child.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/create_note.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/create_sibling.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/delete_subtree.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/delete_tag.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/expand.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/indent.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/lock.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/move.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/move_to_top.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/outdent.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/paste_child.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/paste_sibling.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/prefetch_link_titles.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/prioritize.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/redo.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/rename_tag.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/reset_updated_at.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/resize_image.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/run_shell.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/search_comment_autofill.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/search_context_tags.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/set_collapse_bulk.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/set_collapse_in_context.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/split_note.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/tag_proposals.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/toggle_reference_mode.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/toggle_todo_done.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/undo.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/unformat_content.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/update_content.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/usecases/view.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/utils/__init__.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/utils/encryption.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/app/utils/text_utils.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/main.py +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/metalist.egg-info/dependency_links.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/metalist.egg-info/entry_points.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/metalist.egg-info/requires.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/metalist.egg-info/top_level.txt +0 -0
- {metalist-0.6.1 → metalist-0.6.2}/scripts/generate-lan-cert.sh +0 -0
- {metalist-0.6.1 → 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,13 @@ 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
|
+
|
|
51
58
|
## Changes in 0.6.1
|
|
52
59
|
|
|
53
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.
|
|
@@ -119,11 +126,11 @@ After the first installation, update and restart MetaList with one cross-platfor
|
|
|
119
126
|
```bash
|
|
120
127
|
metalist update
|
|
121
128
|
```
|
|
122
|
-
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.
|
|
123
130
|
|
|
124
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.
|
|
125
132
|
|
|
126
|
-
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.
|
|
127
134
|
|
|
128
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.
|
|
129
136
|
|
|
@@ -283,6 +290,10 @@ convert-from-legacy.py --namespace work --input /path/to/legacy-export.json
|
|
|
283
290
|
|
|
284
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`.
|
|
285
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
|
+
|
|
286
297
|
### Publishing
|
|
287
298
|
For the real user-facing install flow:
|
|
288
299
|
```bash
|
|
@@ -292,15 +303,15 @@ uv tool install metalist
|
|
|
292
303
|
metalist
|
|
293
304
|
```
|
|
294
305
|
|
|
295
|
-
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.
|
|
296
307
|
|
|
297
308
|
Recommended release path:
|
|
298
309
|
1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
|
|
299
|
-
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.
|
|
300
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.
|
|
301
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`.
|
|
302
313
|
|
|
303
|
-
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).
|
|
304
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.
|
|
305
316
|
|
|
306
317
|
### Run Tests
|
|
@@ -12,6 +12,13 @@ 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
|
+
|
|
15
22
|
## Changes in 0.6.1
|
|
16
23
|
|
|
17
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.
|
|
@@ -83,11 +90,11 @@ After the first installation, update and restart MetaList with one cross-platfor
|
|
|
83
90
|
```bash
|
|
84
91
|
metalist update
|
|
85
92
|
```
|
|
86
|
-
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.
|
|
87
94
|
|
|
88
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.
|
|
89
96
|
|
|
90
|
-
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.
|
|
91
98
|
|
|
92
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.
|
|
93
100
|
|
|
@@ -247,6 +254,10 @@ convert-from-legacy.py --namespace work --input /path/to/legacy-export.json
|
|
|
247
254
|
|
|
248
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`.
|
|
249
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
|
+
|
|
250
261
|
### Publishing
|
|
251
262
|
For the real user-facing install flow:
|
|
252
263
|
```bash
|
|
@@ -256,15 +267,15 @@ uv tool install metalist
|
|
|
256
267
|
metalist
|
|
257
268
|
```
|
|
258
269
|
|
|
259
|
-
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.
|
|
260
271
|
|
|
261
272
|
Recommended release path:
|
|
262
273
|
1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
|
|
263
|
-
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.
|
|
264
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.
|
|
265
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`.
|
|
266
277
|
|
|
267
|
-
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).
|
|
268
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.
|
|
269
280
|
|
|
270
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.
|
|
@@ -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
|
|
@@ -26,7 +26,10 @@ tk = None # type: ignore[assignment]
|
|
|
26
26
|
filedialog = None # type: ignore[assignment]
|
|
27
27
|
_TK_IMPORT_ERROR = None
|
|
28
28
|
|
|
29
|
-
if
|
|
29
|
+
if (
|
|
30
|
+
importlib.util.find_spec("tkinter") is not None
|
|
31
|
+
and importlib.util.find_spec("_tkinter") is not None
|
|
32
|
+
):
|
|
30
33
|
import tkinter as tk
|
|
31
34
|
from tkinter import filedialog
|
|
32
35
|
else:
|
|
@@ -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,13 @@ 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
|
+
|
|
51
58
|
## Changes in 0.6.1
|
|
52
59
|
|
|
53
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.
|
|
@@ -119,11 +126,11 @@ After the first installation, update and restart MetaList with one cross-platfor
|
|
|
119
126
|
```bash
|
|
120
127
|
metalist update
|
|
121
128
|
```
|
|
122
|
-
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.
|
|
123
130
|
|
|
124
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.
|
|
125
132
|
|
|
126
|
-
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.
|
|
127
134
|
|
|
128
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.
|
|
129
136
|
|
|
@@ -283,6 +290,10 @@ convert-from-legacy.py --namespace work --input /path/to/legacy-export.json
|
|
|
283
290
|
|
|
284
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`.
|
|
285
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
|
+
|
|
286
297
|
### Publishing
|
|
287
298
|
For the real user-facing install flow:
|
|
288
299
|
```bash
|
|
@@ -292,15 +303,15 @@ uv tool install metalist
|
|
|
292
303
|
metalist
|
|
293
304
|
```
|
|
294
305
|
|
|
295
|
-
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.
|
|
296
307
|
|
|
297
308
|
Recommended release path:
|
|
298
309
|
1. In the existing PyPI project `metalist`, configure GitHub Trusted Publishing for `evolvingstuff/metalist` and the workflow file `.github/workflows/publish-pypi.yml`.
|
|
299
|
-
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.
|
|
300
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.
|
|
301
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`.
|
|
302
313
|
|
|
303
|
-
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).
|
|
304
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.
|
|
305
316
|
|
|
306
317
|
### Run Tests
|
|
@@ -7,7 +7,7 @@ name = "metalist"
|
|
|
7
7
|
dynamic = ["version"]
|
|
8
8
|
description = "A minimalist single-user note-taking app with SSR, fast in-memory tree operations, and efficient sync."
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.10,<3.
|
|
10
|
+
requires-python = ">=3.10,<3.15"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"argon2-cffi==25.1.0",
|
|
13
13
|
"cryptography==50.0.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|