sqlseed-web 0.2.5__tar.gz → 0.2.6__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.
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/.gitignore +10 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/PKG-INFO +29 -8
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/README.md +28 -7
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/README.zh-CN.md +28 -9
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/AGENTS.md +2 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/managed_worker.py +70 -17
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/sqlite_target.py +36 -1
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/i18n/backend-messages.json +28 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/design-system.js +10 -6
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/dropdown.js +1 -1
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/generation-defaults-control.js +2 -2
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/shell.json +1 -1
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/workbench.json +14 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/workbench.js +144 -30
- sqlseed_web-0.2.6/src/sqlseed_web/static/js/tab-motion.js +79 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/motion.css +8 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/navigation.css +3 -2
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/runs.css +5 -1
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/style.css +67 -39
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/workbench.css +48 -9
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/supervised_plugins.py +38 -2
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/supervisor.py +108 -23
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/AGENTS.md +1 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_dropdown.cjs +48 -1
- sqlseed_web-0.2.6/tests/test_managed_worker.py +255 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_settings.cjs +46 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_supervised_plugins.py +39 -0
- sqlseed_web-0.2.6/tests/test_supervisor.py +428 -0
- sqlseed_web-0.2.6/tests/test_tab_motion.cjs +277 -0
- sqlseed_web-0.2.6/tests/test_workbench_compact.cjs +146 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_execution.cjs +195 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_guidance.cjs +5 -4
- sqlseed_web-0.2.6/tests/test_workbench_run_plan.py +191 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_runtime.py +130 -34
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_target_identity.py +164 -0
- sqlseed_web-0.2.5/src/sqlseed_web/static/js/tab-motion.js +0 -47
- sqlseed_web-0.2.5/tests/test_supervisor.py +0 -125
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/AGENTS.md +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/LICENSE +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/pyproject.toml +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/__init__.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/__main__.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/_application.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/_diagnostic_text.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/_windows_process.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/ai_settings.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/api.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/app.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/diagnostics.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/messages.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/operation_errors.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/plugin_environment.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/plugin_management.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/plugin_process.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/plugin_updates.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/runtime_lifecycle.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/runtime_session.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/settings_environment.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/settings_updates.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/state.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/AGENTS.md +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/ai.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/configs.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/date-picker.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/design-system.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/design-system.html +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/disclosure.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/fonts/chill-round-gothic/ChillRoundGothic-Medium.woff2 +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/fonts/chill-round-gothic/ChillRoundGothic-Regular.woff2 +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/fonts/chill-round-gothic/License.txt +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/fonts/chill-round-gothic/README.md +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/graph-clarity.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/index.html +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/api.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/app.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/filepicker.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/generation-defaults.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/genform.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/assistant.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/assistant.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/components.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/components.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/configurations.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/configurations.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/datePicker.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/datePicker.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/editor.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/editor.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/flow.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/flow.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/graph.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/graph.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/labels.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/labels.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/preview.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/preview.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/providerGuide.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/providerGuide.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/runs.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/runs.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/settings.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/settings.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/shell.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/workbench.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/labels.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/browse.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/configs.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/connect.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/heal.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/meta.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/runs.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/settings.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/pages/wizard.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/segment-motion.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/theme-control.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/theme.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/tree.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/update-check-control.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/ai-adjustment.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/ai-eligibility.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/ai-handoff.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/ai-stream.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/ai.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/clear-recovery.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/connection.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/date-picker.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/dependency-view.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/editor.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/focus.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/graph-layout.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/graph.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/guidance.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/model.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/plugin-management.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/preview-scroll-layout.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/preview.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/provider-guide.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/recovery.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/scroll-lock.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/session.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/table-data.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/workbench/ui.js +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/preview.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/scrollbars.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/settings.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/table-data.css +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_ai.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_ai_relations.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_ai_stream.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_cycles.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_data.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_execution.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_runtime.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_schema.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/workbench_store.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/worker_control.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/complex_business_graph.json +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/complex_graph_fixture.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/component_test_support.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/conftest.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/frontend_helpers.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_ai_adjustment.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_ai_eligibility.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_api.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_api_ai_secrets.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_api_regressions.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_app_shell.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_backend_messages.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_browse.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_complex_business_graph.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_complex_graph_fixture.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_component_availability.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_component_test_support.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_configs.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_connection.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_connection_existing_file.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_date_picker.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_dependency_groups.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_disclosure_focus.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_filepicker.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_generation_defaults.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_genform.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_graph_layout_order.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_graph_routing.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_hardening_boundaries.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_i18n.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_i18n_catalog.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_i18n_component_paths.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_i18n_validation_paths.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_job_completion.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_legacy_connect.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_legacy_page_async.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_modal_scroll.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_navigation_motion.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_plugin_cleanup.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_plugin_management.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_plugin_management.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_plugin_process.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_plugin_updates.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_preview_editing.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_preview_scroll_layout.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_provider_guide.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_rule_usability.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_run_recovery.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_runs.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_runtime_lifecycle.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_runtime_session.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_segment_motion.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_settings_update_lifecycle.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_settings_updates.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_table_data.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_theme.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_web_request_security.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_web_settings.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_windows_environment.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_windows_guard.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_windows_plugin_lifecycle.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_wizard.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_acceptance.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_ai.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_ai.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_ai_handoff.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_ai_integration.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_ai_progress.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_ai_relations.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_ai_stream.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_async_boundaries.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_busy.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_capability_limits.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_clear_recovery.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_concurrency.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_configs.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_connection_routing.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_context.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_data.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_data.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_documents.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_editor.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_empty_schema.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_execution.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_existing_cycles.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_graph.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_graph_checks.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_model.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_page.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_postgresql_cycles.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_preview.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_providers.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_review.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_sample_budget.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_schema.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_session.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_store.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_usability.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_workbench_v8.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/test_worker_control.py +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/workbench_harness.cjs +0 -0
- {sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/tests/workbench_test_helpers.py +0 -0
|
@@ -59,6 +59,16 @@ dmypy.json
|
|
|
59
59
|
*.db
|
|
60
60
|
*.sqlite
|
|
61
61
|
*.sqlite3
|
|
62
|
+
# SQLite runtime sidecars
|
|
63
|
+
*.db-wal
|
|
64
|
+
*.db-shm
|
|
65
|
+
*.db-journal
|
|
66
|
+
*.sqlite-wal
|
|
67
|
+
*.sqlite-shm
|
|
68
|
+
*.sqlite-journal
|
|
69
|
+
*.sqlite3-wal
|
|
70
|
+
*.sqlite3-shm
|
|
71
|
+
*.sqlite3-journal
|
|
62
72
|
.sqlseed_cache/
|
|
63
73
|
snapshots/
|
|
64
74
|
.env
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sqlseed-web
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: Local sqlseed workbench for SQLite and PostgreSQL rules, previews, generation and optional AI suggestions
|
|
5
5
|
Project-URL: Homepage, https://github.com/sunbos/sqlseed
|
|
6
6
|
Project-URL: Repository, https://github.com/sunbos/sqlseed/tree/main/plugins/sqlseed-web
|
|
@@ -30,19 +30,40 @@ A local browser workbench for declarative SQLite and PostgreSQL test data genera
|
|
|
30
30
|
Connect a database, edit field rules, preview samples, inspect dependencies and review
|
|
31
31
|
generation results. The Python core runs offline; AI suggestions are optional.
|
|
32
32
|
|
|
33
|
+
## A look at the workbench
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
The actual 0.2.5 interface with the repository's fictional SQLite order example.
|
|
38
|
+
[Open the full-size PNG](https://raw.githubusercontent.com/sunbos/sqlseed/992ba0e733d5b41f73e37b0a9d02d573d6e2bb23/docs/assets/screenshots/web-workbench-en-light.png)
|
|
39
|
+
or [see the read-only sample preview in the dark theme](https://raw.githubusercontent.com/sunbos/sqlseed/992ba0e733d5b41f73e37b0a9d02d573d6e2bb23/docs/assets/screenshots/web-workbench-en-dark.png).
|
|
40
|
+
|
|
41
|
+
Connect an existing database, select tables and row counts, review field rules and
|
|
42
|
+
dependencies, preview samples, then confirm the generation plan.
|
|
43
|
+
|
|
44
|
+
| Page | What you can do |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| Workbench | Edit rules, inspect the relationship graph, preview samples without writing, and confirm generation. |
|
|
47
|
+
| Configs | Save reusable rules, import or export YAML, and reopen configurations for the matching database. |
|
|
48
|
+
| Runs | Review per-table outcomes, committed row counts, and the configuration snapshot used for a run. |
|
|
49
|
+
| Settings | Choose generation defaults, light/dark appearance, optional AI settings, and available components. |
|
|
50
|
+
|
|
51
|
+
The [order workflow example](https://github.com/sunbos/sqlseed/tree/main/examples/order_workflow)
|
|
52
|
+
includes the schema, rules, and instructions for creating your own disposable demo.
|
|
53
|
+
|
|
33
54
|
## Installation
|
|
34
55
|
|
|
35
|
-
These instructions target version 0.2.
|
|
56
|
+
These instructions target version 0.2.6. Check [Releases](https://github.com/sunbos/sqlseed/releases)
|
|
36
57
|
for publication status; use the source installation below to test an unpublished candidate.
|
|
37
58
|
Use a Python 3.10+ virtual environment:
|
|
38
59
|
|
|
39
60
|
```bash
|
|
40
|
-
python -m pip install "sqlseed==0.2.
|
|
61
|
+
python -m pip install "sqlseed==0.2.6" "sqlseed-web==0.2.6"
|
|
41
62
|
sqlseed-web
|
|
42
63
|
```
|
|
43
64
|
|
|
44
65
|
Open `http://127.0.0.1:8630`. The wheel includes the frontend; no Node or npm build
|
|
45
|
-
is needed to use the app. For PostgreSQL, also install `"sqlseed[postgres]==0.2.
|
|
66
|
+
is needed to use the app. For PostgreSQL, also install `"sqlseed[postgres]==0.2.6"`.
|
|
46
67
|
Core 0.2.4 and older lack the shared connection and diagnostic interfaces required by this version.
|
|
47
68
|
|
|
48
69
|
For development, install local Core and Web together from the repository root:
|
|
@@ -51,13 +72,13 @@ For development, install local Core and Web together from the repository root:
|
|
|
51
72
|
python -m pip install -e . -e ./plugins/sqlseed-web
|
|
52
73
|
```
|
|
53
74
|
|
|
54
|
-
Version 0.2.
|
|
75
|
+
Version 0.2.6 and its source candidates require Core `>=0.2.5.dev0,<0.3` for
|
|
55
76
|
connection-target parsing and diagnostic redaction. Install matching Core and Web
|
|
56
77
|
versions; do not disable dependency checks to keep an older Core.
|
|
57
78
|
|
|
58
79
|
## Interface language
|
|
59
80
|
|
|
60
|
-
Version 0.2.
|
|
81
|
+
Version 0.2.6 offers **简体中文 / English** in the top bar.
|
|
61
82
|
The browser remembers your choice and synchronizes it with other tabs on the same
|
|
62
83
|
origin. Without a saved choice, the first supported browser language is used,
|
|
63
84
|
falling back to English. If storage is unavailable, switching still works for the
|
|
@@ -89,10 +110,10 @@ install local Core, CLI, AI, and Web together in the same resolution:
|
|
|
89
110
|
python -m pip install -e . -e ./plugins/sqlseed-cli -e ./plugins/sqlseed-ai -e ./plugins/sqlseed-web
|
|
90
111
|
```
|
|
91
112
|
|
|
92
|
-
For version 0.2.
|
|
113
|
+
For version 0.2.6, `python -m pip install "sqlseed-web[ai]==0.2.6"` installs
|
|
93
114
|
the optional AI component. The page does not fall back to an incompatible older release.
|
|
94
115
|
|
|
95
|
-
The version 0.2.
|
|
116
|
+
The version 0.2.6 default launcher manages optional packages
|
|
96
117
|
in supported writable Windows, macOS and Linux virtual environments and restores
|
|
97
118
|
the service automatically. Externally hosted apps and read-only/system environments
|
|
98
119
|
can use the workbench but do not offer in-page package changes. Missing components
|
|
@@ -6,19 +6,40 @@ A local browser workbench for declarative SQLite and PostgreSQL test data genera
|
|
|
6
6
|
Connect a database, edit field rules, preview samples, inspect dependencies and review
|
|
7
7
|
generation results. The Python core runs offline; AI suggestions are optional.
|
|
8
8
|
|
|
9
|
+
## A look at the workbench
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
The actual 0.2.5 interface with the repository's fictional SQLite order example.
|
|
14
|
+
[Open the full-size PNG](https://raw.githubusercontent.com/sunbos/sqlseed/992ba0e733d5b41f73e37b0a9d02d573d6e2bb23/docs/assets/screenshots/web-workbench-en-light.png)
|
|
15
|
+
or [see the read-only sample preview in the dark theme](https://raw.githubusercontent.com/sunbos/sqlseed/992ba0e733d5b41f73e37b0a9d02d573d6e2bb23/docs/assets/screenshots/web-workbench-en-dark.png).
|
|
16
|
+
|
|
17
|
+
Connect an existing database, select tables and row counts, review field rules and
|
|
18
|
+
dependencies, preview samples, then confirm the generation plan.
|
|
19
|
+
|
|
20
|
+
| Page | What you can do |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| Workbench | Edit rules, inspect the relationship graph, preview samples without writing, and confirm generation. |
|
|
23
|
+
| Configs | Save reusable rules, import or export YAML, and reopen configurations for the matching database. |
|
|
24
|
+
| Runs | Review per-table outcomes, committed row counts, and the configuration snapshot used for a run. |
|
|
25
|
+
| Settings | Choose generation defaults, light/dark appearance, optional AI settings, and available components. |
|
|
26
|
+
|
|
27
|
+
The [order workflow example](https://github.com/sunbos/sqlseed/tree/main/examples/order_workflow)
|
|
28
|
+
includes the schema, rules, and instructions for creating your own disposable demo.
|
|
29
|
+
|
|
9
30
|
## Installation
|
|
10
31
|
|
|
11
|
-
These instructions target version 0.2.
|
|
32
|
+
These instructions target version 0.2.6. Check [Releases](https://github.com/sunbos/sqlseed/releases)
|
|
12
33
|
for publication status; use the source installation below to test an unpublished candidate.
|
|
13
34
|
Use a Python 3.10+ virtual environment:
|
|
14
35
|
|
|
15
36
|
```bash
|
|
16
|
-
python -m pip install "sqlseed==0.2.
|
|
37
|
+
python -m pip install "sqlseed==0.2.6" "sqlseed-web==0.2.6"
|
|
17
38
|
sqlseed-web
|
|
18
39
|
```
|
|
19
40
|
|
|
20
41
|
Open `http://127.0.0.1:8630`. The wheel includes the frontend; no Node or npm build
|
|
21
|
-
is needed to use the app. For PostgreSQL, also install `"sqlseed[postgres]==0.2.
|
|
42
|
+
is needed to use the app. For PostgreSQL, also install `"sqlseed[postgres]==0.2.6"`.
|
|
22
43
|
Core 0.2.4 and older lack the shared connection and diagnostic interfaces required by this version.
|
|
23
44
|
|
|
24
45
|
For development, install local Core and Web together from the repository root:
|
|
@@ -27,13 +48,13 @@ For development, install local Core and Web together from the repository root:
|
|
|
27
48
|
python -m pip install -e . -e ./plugins/sqlseed-web
|
|
28
49
|
```
|
|
29
50
|
|
|
30
|
-
Version 0.2.
|
|
51
|
+
Version 0.2.6 and its source candidates require Core `>=0.2.5.dev0,<0.3` for
|
|
31
52
|
connection-target parsing and diagnostic redaction. Install matching Core and Web
|
|
32
53
|
versions; do not disable dependency checks to keep an older Core.
|
|
33
54
|
|
|
34
55
|
## Interface language
|
|
35
56
|
|
|
36
|
-
Version 0.2.
|
|
57
|
+
Version 0.2.6 offers **简体中文 / English** in the top bar.
|
|
37
58
|
The browser remembers your choice and synchronizes it with other tabs on the same
|
|
38
59
|
origin. Without a saved choice, the first supported browser language is used,
|
|
39
60
|
falling back to English. If storage is unavailable, switching still works for the
|
|
@@ -65,10 +86,10 @@ install local Core, CLI, AI, and Web together in the same resolution:
|
|
|
65
86
|
python -m pip install -e . -e ./plugins/sqlseed-cli -e ./plugins/sqlseed-ai -e ./plugins/sqlseed-web
|
|
66
87
|
```
|
|
67
88
|
|
|
68
|
-
For version 0.2.
|
|
89
|
+
For version 0.2.6, `python -m pip install "sqlseed-web[ai]==0.2.6"` installs
|
|
69
90
|
the optional AI component. The page does not fall back to an incompatible older release.
|
|
70
91
|
|
|
71
|
-
The version 0.2.
|
|
92
|
+
The version 0.2.6 default launcher manages optional packages
|
|
72
93
|
in supported writable Windows, macOS and Linux virtual environments and restores
|
|
73
94
|
the service automatically. Externally hosted apps and read-only/system environments
|
|
74
95
|
can use the workbench but do not offer in-page package changes. Missing components
|
|
@@ -4,16 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
面向 SQLite 与 PostgreSQL 声明式测试数据生成的本机浏览器工作台。连接数据库、编辑字段规则、预览样例、检查依赖并查看生成结果。Python core 离线运行;AI 建议是可选功能。
|
|
6
6
|
|
|
7
|
+
## 工作台概览
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
0.2.5 正式界面的实际截图,使用仓库中的虚构 SQLite 订单示例。
|
|
12
|
+
[查看原尺寸高清 PNG](https://raw.githubusercontent.com/sunbos/sqlseed/992ba0e733d5b41f73e37b0a9d02d573d6e2bb23/docs/assets/screenshots/web-workbench-zh-CN-light.png),
|
|
13
|
+
或[查看深色主题下的只读样例预览](https://raw.githubusercontent.com/sunbos/sqlseed/992ba0e733d5b41f73e37b0a9d02d573d6e2bb23/docs/assets/screenshots/web-workbench-zh-CN-dark.png)。
|
|
14
|
+
|
|
15
|
+
连接已有数据库 → 选择表和生成数量 → 核对字段规则与依赖 → 预览样例 → 确认生成计划。
|
|
16
|
+
|
|
17
|
+
| 页面 | 可以做什么 |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| 工作台 | 编辑规则、浏览关系图、只读预览样例,并确认生成。 |
|
|
20
|
+
| 配置管理 | 保存可复用规则、导入导出 YAML、重新打开对应数据库的配置。 |
|
|
21
|
+
| 运行记录 | 查看逐表结果、实际已提交行数和本次使用的配置快照。 |
|
|
22
|
+
| 设置 | 调整生成默认值、浅色/深色外观、可选 AI 设置与组件。 |
|
|
23
|
+
|
|
24
|
+
[订单工作流示例](https://github.com/sunbos/sqlseed/tree/main/examples/order_workflow)提供建表结构、生成规则和操作说明,可用于创建自己的独立演示库。
|
|
25
|
+
|
|
7
26
|
## 安装
|
|
8
27
|
|
|
9
|
-
本文安装说明对应 0.2.
|
|
28
|
+
本文安装说明对应 0.2.6 版本;发布状态以 [Releases](https://github.com/sunbos/sqlseed/releases) 为准。测试尚未发布的候选版本时,使用下方的源码安装方式。请先创建并激活 Python 3.10+ 虚拟环境:
|
|
10
29
|
|
|
11
30
|
```bash
|
|
12
|
-
python -m pip install "sqlseed==0.2.
|
|
31
|
+
python -m pip install "sqlseed==0.2.6" "sqlseed-web==0.2.6"
|
|
13
32
|
sqlseed-web
|
|
14
33
|
```
|
|
15
34
|
|
|
16
|
-
打开 `http://127.0.0.1:8630`。wheel 包含前端,使用时无需 Node 或 npm 构建。PostgreSQL 还需安装 `"sqlseed[postgres]==0.2.
|
|
35
|
+
打开 `http://127.0.0.1:8630`。wheel 包含前端,使用时无需 Node 或 npm 构建。PostgreSQL 还需安装 `"sqlseed[postgres]==0.2.6"`。Core 0.2.4 及更早版本缺少本版本所需的共享连接和诊断接口。
|
|
17
36
|
|
|
18
37
|
开发源码从仓库根同时安装 Core 与 Web:
|
|
19
38
|
|
|
@@ -21,15 +40,15 @@ sqlseed-web
|
|
|
21
40
|
python -m pip install -e . -e ./plugins/sqlseed-web
|
|
22
41
|
```
|
|
23
42
|
|
|
24
|
-
0.2.
|
|
43
|
+
0.2.6 版本及其源码候选要求 Core `>=0.2.5.dev0,<0.3`,用于连接目标解析与诊断脱敏。请使用匹配的 Core 与 Web 版本,不要关闭依赖检查来保留旧 Core。
|
|
25
44
|
|
|
26
45
|
## 界面语言
|
|
27
46
|
|
|
28
|
-
0.2.
|
|
47
|
+
0.2.6 版本在顶栏提供 **简体中文 / English**。浏览器记住选择,并与同源标签页同步。没有已存偏好时,采用浏览器偏好中第一个支持的语言,无匹配则使用 English;存储不可用时仍能在当前页切换。
|
|
29
48
|
|
|
30
49
|
切换就地更新标签、帮助和受支持的诊断,不刷新页面、不提交表单,也不发数据库或 AI 请求;未保存的修改、焦点和选择保持不变。**数据语言与地区**是独立的生成配置:切换界面语言不改变生成内容、配置名称、表列标识、YAML 或数据库原值。旧记录或第三方诊断可能保留原文,并附当前语言说明。
|
|
31
50
|
|
|
32
|
-
语言资源随 wheel 分发,不需要翻译服务。覆盖与新增文案所需验证见 [Web 双语维护](https://sunbos.github.io/sqlseed/development/web-i18n/)。
|
|
51
|
+
语言资源随 wheel 分发,不需要翻译服务。覆盖与新增文案所需验证见 [Web 双语维护](https://sunbos.github.io/sqlseed/zh-CN/development/web-i18n/)。
|
|
33
52
|
|
|
34
53
|
## 可选组件
|
|
35
54
|
|
|
@@ -41,9 +60,9 @@ python -m pip install -e . -e ./plugins/sqlseed-web
|
|
|
41
60
|
python -m pip install -e . -e ./plugins/sqlseed-cli -e ./plugins/sqlseed-ai -e ./plugins/sqlseed-web
|
|
42
61
|
```
|
|
43
62
|
|
|
44
|
-
0.2.
|
|
63
|
+
0.2.6 使用 `python -m pip install "sqlseed-web[ai]==0.2.6"` 安装可选 AI 组件。页面不会回退到不兼容的旧版本。
|
|
45
64
|
|
|
46
|
-
0.2.
|
|
65
|
+
0.2.6 的默认启动器可在受支持、可写的 Windows、macOS 与 Linux 虚拟环境中管理可选包,并自动恢复服务。外部托管、只读或系统环境仍可使用工作台,但不开放网页包变更。组件缺失会显示原因和恢复入口,不会静默替换配置中的引擎。更新必须审阅兼容 wheel,保持其他已安装组件的版本;Core 与 Web 由环境的包管理工具更新。
|
|
47
66
|
|
|
48
67
|
## 数据与部署边界
|
|
49
68
|
|
|
@@ -51,7 +70,7 @@ python -m pip install -e . -e ./plugins/sqlseed-cli -e ./plugins/sqlseed-ai -e .
|
|
|
51
70
|
|
|
52
71
|
服务面向一个可信的本机用户,没有多用户认证,默认只监听 loopback。不要直接暴露到不可信网络;同源请求检查不能替代认证或数据库权限。
|
|
53
72
|
|
|
54
|
-
详见[工作台指南](https://sunbos.github.io/sqlseed/web-workbench/)与[支持边界](https://sunbos.github.io/sqlseed/maintainable-release/)。
|
|
73
|
+
详见[工作台指南](https://sunbos.github.io/sqlseed/zh-CN/web-workbench/)与[支持边界](https://sunbos.github.io/sqlseed/zh-CN/maintainable-release/)。
|
|
55
74
|
|
|
56
75
|
## 依赖
|
|
57
76
|
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
- SQLite URI 中解码后的 NUL、原始 TAB/CR/LF、无效 UTF-8 百分号编码也在注册前拒绝:SQLite 字符串截断与 Python URL 清理/替代解码不同,不能把异常编码折叠成另一目标。合法 UTF-8 与经过百分号编码的 TAB/CR/LF 文件名仍按真实路径识别。
|
|
31
31
|
- URI 文件路径须经平台路径转换;Windows 的 `/C:/...` 与普通 `C:\...` 指向同一文件。百分号只解码一次,文件名中的字面 `%41` 不能被误识别为 `A`;真实文件别名回归覆盖空格、百分号及编码盘符。
|
|
32
32
|
- 列表、打开和运行只接受当前 canonical `target_key`,不提供或接受旧身份 aliases。旧 URI hash 可能恰好属于另一个真实的 `file:` 前缀文件,不能仅凭当前连接写法推导旧 hash 并自动授权;没有可信身份版本的记录不得通过同 schema 或解析 target_label 猜库迁移。普通路径的旧 key 不变;身份发生变化的旧 URI 配置与运行仍保留可导出,由用户明确导入当前目标创建新配置,历史运行快照不改。历史记录未存原始连接或身份算法版本,旧错 hash 与真实字面 `file:` 路径 hash 的反向碰撞无法可靠区分,这是既有数据的限制,不自动推断或重绑。
|
|
33
|
+
- macOS 的 SQLite 文件身份通过 Darwin libc `realpath(3)` 获取实际拼写,兼容文件系统认可的大小写和 Unicode 别名;不能直接 lower 路径或只凭文字归一化合并不同文件。身份查询不得打开再关闭数据库文件,否则可能释放同进程 SQLite 的 POSIX 锁;原生调用固定 ctypes 签名并使用 Python 持有的 PATH_MAX buffer,失败不采用部分输出。缺失路径不创建文件,其他查验失败不猜测身份;已保存的非规范别名历史不自动重绑,沿用明确导入策略。
|
|
33
34
|
- Web locale 使用 Faker 风格(`zh_CN`/`en_US`);`SUPPORTED_LOCALES` 与 `MimesisProvider.set_locale` 的映射保持一致。
|
|
34
35
|
|
|
35
36
|
## 后台任务与终态
|
|
@@ -103,6 +104,7 @@
|
|
|
103
104
|
## 可选组件自动管理
|
|
104
105
|
|
|
105
106
|
- `supervisor.py` 在默认启动时持有监听 socket 与管理状态,`managed_worker.py` 分别启动业务/维护 worker,`worker_control.py` 以有界匿名 IPC 传递控制与临时会话。保留原 NDJSON,不代理 HTTP。旧 `--manage-plugins` 仅兼容入口;普通网页无需命令切换或手动重启。
|
|
107
|
+
- Worker 就绪与恢复准入确认是两个步骤。`resume` 确认丢失时可能已有业务请求,必须保留该进程与控制通道,确认自然排空退出后才启动维护 worker;不得覆盖引用或强杀可能已恢复准入的进程。启动失败保留固定阶段、错误码、耗时与退出码,任务输出和 `recovery_error` 不带原始异常/凭据;`/recover` 仅恢复服务和原会话,不重复安装器。启动期限仍为有界的 20 秒,不用扩大期限代替退出/超时诊断。
|
|
106
108
|
- 维护 worker 业务 `/api/` 一律拒绝,仅保留 health、environment 与 `/api/settings/plugins/*`;HTML 固定标识用于首次导航,API 门禁不能依赖前端,受管维护标识不得永久锁定恢复后的导航。
|
|
107
109
|
- `plugin_environment.py` 只接受当前解释器与可写独立 virtualenv,解析真实 distribution metadata/Requires-Dist;不使用 import 缓存判断新安装状态。系统/只读/共享系统包/环境外 metadata 不可管理,但保留普通 Web。
|
|
108
110
|
- `plugin_management.py` 白名单仅 ai/cli/mcp/mimesis。管理请求检查 loopback client/Host;POST 必须同 Origin 及 token。计划绑定五分钟内 metadata 快照,一次领取。新计划可在同一受锁解释器且权限仍满足时重新绑定合法安装器;计划到执行及更新下载后的环境变化仍须拒绝,不能将短时安装器探测结果固定为进程生命周期身份。Core/Web/Faker/Base 不接受操作,不自动卸载依赖。`supervised_plugins.py` 仅在新业务就绪后发布任务终态,恢复失败保留页面与只恢复服务的重试入口。
|
|
@@ -28,6 +28,33 @@ if TYPE_CHECKING:
|
|
|
28
28
|
|
|
29
29
|
from sqlseed_web.runtime_lifecycle import RuntimeGate
|
|
30
30
|
|
|
31
|
+
_WORKER_STARTUP_FAILED = "backend.supervisor.worker_startup_failed"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class WorkerLifecycleError(RuntimeError):
|
|
35
|
+
"""Only fixed lifecycle facts may cross the public recovery boundary."""
|
|
36
|
+
|
|
37
|
+
def __init__(self, code: str, *, mode: str, phase: str, elapsed_ms: int, exit_code: int | None) -> None:
|
|
38
|
+
"""Build a localized error from fixed lifecycle facts without private exception text."""
|
|
39
|
+
messages = {
|
|
40
|
+
"worker_startup_timeout": tr("backend.supervisor.worker_startup_timeout"),
|
|
41
|
+
"worker_exited_before_ready": tr("backend.supervisor.worker_exited_before_ready"),
|
|
42
|
+
"worker_startup_failed": tr(_WORKER_STARTUP_FAILED),
|
|
43
|
+
"worker_resume_failed": tr("backend.supervisor.worker_resume_failed"),
|
|
44
|
+
"worker_shutdown_timeout": tr("backend.supervisor.worker_shutdown_timeout"),
|
|
45
|
+
"worker_stop_pending": tr("backend.supervisor.worker_stop_pending"),
|
|
46
|
+
}
|
|
47
|
+
message = messages[code]
|
|
48
|
+
super().__init__(message)
|
|
49
|
+
self.detail: dict[str, Any] = {
|
|
50
|
+
"code": code,
|
|
51
|
+
"message": message,
|
|
52
|
+
"worker_mode": mode,
|
|
53
|
+
"phase": phase,
|
|
54
|
+
"elapsed_ms": elapsed_ms,
|
|
55
|
+
"exit_code": exit_code,
|
|
56
|
+
}
|
|
57
|
+
|
|
31
58
|
|
|
32
59
|
class RemotePluginManager:
|
|
33
60
|
"""The HTTP worker cannot execute package operations itself."""
|
|
@@ -145,6 +172,33 @@ def _serve_worker(server: uvicorn.Server, listener: socket.socket) -> None:
|
|
|
145
172
|
asyncio.set_event_loop(None)
|
|
146
173
|
|
|
147
174
|
|
|
175
|
+
def _restore_worker_session(mode: str, session: dict[str, Any]) -> dict[str, Any]:
|
|
176
|
+
"""Restore business connections only; maintenance workers must not open databases."""
|
|
177
|
+
if mode != "business":
|
|
178
|
+
return {}
|
|
179
|
+
from sqlseed_web.runtime_session import restore_session
|
|
180
|
+
|
|
181
|
+
if session:
|
|
182
|
+
return restore_session(session)
|
|
183
|
+
return {"restored_connections": 0, "failed_connections": [], "ai_session_restored": True}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _wait_for_http_start(server: uvicorn.Server, thread: threading.Thread) -> None:
|
|
187
|
+
"""Wait for HTTP readiness or report a safe error if its serving thread exits first."""
|
|
188
|
+
while thread.is_alive() and not server.started:
|
|
189
|
+
time.sleep(0.01)
|
|
190
|
+
if not server.started:
|
|
191
|
+
raise RuntimeError(tr(_WORKER_STARTUP_FAILED))
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _report_startup_failure(channel: ControlChannel, mode: str, stage: str) -> None:
|
|
195
|
+
"""Send only the failed stage, tolerating a parent control channel that has already closed."""
|
|
196
|
+
try:
|
|
197
|
+
channel.call("worker_failed", {"mode": mode, "phase": stage})
|
|
198
|
+
except (OSError, RuntimeError):
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
|
|
148
202
|
def run_worker(
|
|
149
203
|
listener: socket.socket,
|
|
150
204
|
connection: ControlTransport,
|
|
@@ -163,7 +217,6 @@ def run_worker(
|
|
|
163
217
|
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
|
164
218
|
channel = ControlChannel(connection)
|
|
165
219
|
manager = RemotePluginManager(channel, token)
|
|
166
|
-
result: dict[str, Any] = {}
|
|
167
220
|
server: uvicorn.Server | None = None
|
|
168
221
|
thread: threading.Thread | None = None
|
|
169
222
|
lock_fd = lock_descriptor.detach() if lock_descriptor is not None else None
|
|
@@ -172,20 +225,14 @@ def run_worker(
|
|
|
172
225
|
return _worker_control(method, mode, server, runtime_gate)
|
|
173
226
|
|
|
174
227
|
channel.start(control)
|
|
228
|
+
stage = "session"
|
|
229
|
+
announced_ready = False
|
|
175
230
|
try:
|
|
231
|
+
channel.call("worker_starting", {"mode": mode, "phase": stage})
|
|
176
232
|
runtime_gate.pause_if_idle()
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
result = (
|
|
181
|
-
restore_session(session)
|
|
182
|
-
if session
|
|
183
|
-
else {
|
|
184
|
-
"restored_connections": 0,
|
|
185
|
-
"failed_connections": [],
|
|
186
|
-
"ai_session_restored": True,
|
|
187
|
-
}
|
|
188
|
-
)
|
|
233
|
+
result = _restore_worker_session(mode, session)
|
|
234
|
+
stage = "application"
|
|
235
|
+
channel.call("worker_starting", {"mode": mode, "phase": stage})
|
|
189
236
|
app = create_app(manage_plugins=mode == "maintenance", management_service=manager, supervised_worker=True)
|
|
190
237
|
config = uvicorn.Config(
|
|
191
238
|
app, log_level="warning", access_log=False, lifespan="on", timeout_graceful_shutdown=None
|
|
@@ -194,14 +241,20 @@ def run_worker(
|
|
|
194
241
|
thread = threading.Thread(
|
|
195
242
|
target=_serve_worker, args=(server, listener), daemon=False, name="sqlseed-http-worker"
|
|
196
243
|
)
|
|
244
|
+
stage = "http"
|
|
245
|
+
channel.call("worker_starting", {"mode": mode, "phase": stage})
|
|
197
246
|
thread.start()
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
channel.call("worker_ready", {"mode": mode, "restoration": result})
|
|
247
|
+
_wait_for_http_start(server, thread)
|
|
248
|
+
channel.call("worker_ready", {"mode": mode, "restoration": result})
|
|
249
|
+
announced_ready = True
|
|
202
250
|
while thread.is_alive():
|
|
203
251
|
if channel.wait_closed(0.1):
|
|
204
252
|
break
|
|
253
|
+
except (HTTPException, ImportError, OSError, RuntimeError, TypeError, ValueError):
|
|
254
|
+
if not announced_ready:
|
|
255
|
+
_report_startup_failure(channel, mode, stage)
|
|
256
|
+
# Import/ASGI failures may contain credentials or driver parameters.
|
|
257
|
+
raise RuntimeError(tr(_WORKER_STARTUP_FAILED)) from None
|
|
205
258
|
finally:
|
|
206
259
|
_drain_worker_runtime(mode, runtime_gate)
|
|
207
260
|
if server is not None:
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import ctypes
|
|
6
|
+
import errno
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
5
9
|
from dataclasses import dataclass
|
|
10
|
+
from functools import cache
|
|
6
11
|
from pathlib import Path
|
|
7
12
|
from typing import Literal
|
|
8
13
|
from urllib.parse import parse_qs, quote, unquote, urlencode, urlsplit
|
|
@@ -15,6 +20,36 @@ from sqlseed.database._connection_url import connection_url
|
|
|
15
20
|
from sqlseed_web.messages import message as tr
|
|
16
21
|
|
|
17
22
|
|
|
23
|
+
@cache
|
|
24
|
+
def _macos_libc() -> ctypes.CDLL:
|
|
25
|
+
"""Bind Darwin realpath once with its native pointer signature."""
|
|
26
|
+
library = ctypes.CDLL(None, use_errno=True)
|
|
27
|
+
library.realpath.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_char)]
|
|
28
|
+
library.realpath.restype = ctypes.c_void_p
|
|
29
|
+
return library
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _canonical_file_path(filename: str) -> str:
|
|
33
|
+
"""Resolve macOS filesystem spellings without folding distinct filenames."""
|
|
34
|
+
path = Path(filename).resolve()
|
|
35
|
+
if sys.platform != "darwin":
|
|
36
|
+
return str(path)
|
|
37
|
+
# Unlike Python's realpath, Darwin libc reads each component's actual
|
|
38
|
+
# filesystem name. It neither scans directories nor opens the database;
|
|
39
|
+
# closing an extra database descriptor would release active POSIX locks.
|
|
40
|
+
# Darwin sys/syslimits.h defines PATH_MAX=1024. Passing our own buffer
|
|
41
|
+
# avoids libc-allocated memory and retains ownership on every error path.
|
|
42
|
+
buffer = ctypes.create_string_buffer(1024)
|
|
43
|
+
if _macos_libc().realpath(os.fsencode(path), buffer):
|
|
44
|
+
return os.fsdecode(buffer.value)
|
|
45
|
+
if (error := ctypes.get_errno()) in {errno.ENOENT, errno.ENOTDIR}:
|
|
46
|
+
# Identity lookup must not create a missing database; existing callers
|
|
47
|
+
# retain their own create/no-create policy when opening it later.
|
|
48
|
+
return str(path)
|
|
49
|
+
# realpath's partial output on failure is not a valid target identity.
|
|
50
|
+
raise OSError(error, os.strerror(error), str(path))
|
|
51
|
+
|
|
52
|
+
|
|
18
53
|
@dataclass(frozen=True)
|
|
19
54
|
class SQLiteTarget:
|
|
20
55
|
"""A file, a named shared memory database, or one private connection."""
|
|
@@ -86,7 +121,7 @@ def sqlite_target(target: str, conn_id: str) -> SQLiteTarget | None:
|
|
|
86
121
|
# Re-encode the validated text so literal percent sequences are not
|
|
87
122
|
# decoded twice by url2pathname; keep drive colons visible to it.
|
|
88
123
|
filename = url2pathname(quote(filename, safe="/:"))
|
|
89
|
-
return SQLiteTarget("sqlite",
|
|
124
|
+
return SQLiteTarget("sqlite", _canonical_file_path(filename))
|
|
90
125
|
|
|
91
126
|
|
|
92
127
|
def existing_sqlite_connection_target(target: str, conn_id: str) -> str:
|
|
@@ -731,6 +731,34 @@
|
|
|
731
731
|
"业务进程意外退出,原有连接与会话密钥需要重新配置。",
|
|
732
732
|
"The application process stopped unexpectedly. Reconfigure connections and session keys."
|
|
733
733
|
],
|
|
734
|
+
"backend.supervisor.worker_startup_timeout": [
|
|
735
|
+
"应用进程未在启动期限内就绪,请重试恢复;不会重复安装组件。",
|
|
736
|
+
"The application process did not become ready before its startup deadline. Retry recovery; the component will not be installed again."
|
|
737
|
+
],
|
|
738
|
+
"backend.supervisor.worker_exited_before_ready": [
|
|
739
|
+
"应用进程在就绪前退出,请检查组件环境后重试恢复。",
|
|
740
|
+
"The application process exited before becoming ready. Check the component environment and retry recovery."
|
|
741
|
+
],
|
|
742
|
+
"backend.supervisor.worker_startup_failed": [
|
|
743
|
+
"应用进程初始化失败,请检查组件环境后重试恢复。",
|
|
744
|
+
"Application process initialization failed. Check the component environment and retry recovery."
|
|
745
|
+
],
|
|
746
|
+
"backend.supervisor.worker_resume_failed": [
|
|
747
|
+
"未能确认应用进程已恢复服务,将先等待该进程安全退出,再恢复工作台。",
|
|
748
|
+
"The application process did not acknowledge service resumption. Wait for that process to exit safely before restoring the workbench."
|
|
749
|
+
],
|
|
750
|
+
"backend.supervisor.worker_shutdown_timeout": [
|
|
751
|
+
"原应用进程尚未安全退出,已保留进程与环境锁;请稍后重试恢复。",
|
|
752
|
+
"The previous application process has not exited safely. Its ownership and environment lock are retained; retry recovery shortly."
|
|
753
|
+
],
|
|
754
|
+
"backend.supervisor.worker_stop_pending": [
|
|
755
|
+
"原应用进程尚未完成清理,不能启动替代进程;请稍后重试恢复。",
|
|
756
|
+
"The previous application process has not finished cleanup. A replacement cannot start yet; retry recovery shortly."
|
|
757
|
+
],
|
|
758
|
+
"backend.supervised_plugins.service_restore_failed": [
|
|
759
|
+
"服务恢复未完成,请重试恢复;组件操作不会重复执行。",
|
|
760
|
+
"Service recovery did not complete. Retry recovery; the component operation will not run again."
|
|
761
|
+
],
|
|
734
762
|
"backend.supervisor.another_web_service_is_using_this_python": [
|
|
735
763
|
"此 Python 环境正被另一个 Web 服务使用,无法启动受管服务。",
|
|
736
764
|
"Another Web service is using this Python environment. Cannot start the managed service."
|
|
@@ -67,9 +67,9 @@ const readingTable = table(['#', '字段', '规则', '示例'], [
|
|
|
67
67
|
readingTable.classList.add('wb-preview-data');
|
|
68
68
|
root.append(section('foundation', '材质与文字', '透明度服从信息层级。功能层轻盈,数据与代码保持稳定阅读。', 'fields',
|
|
69
69
|
h('div', { class: 'ds-grid ds-grid-three' },
|
|
70
|
-
surface('wb-config-context', '控制层', '
|
|
71
|
-
surface('wb-content', '阅读层', '
|
|
72
|
-
surface('drawer-help', '内嵌说明', '
|
|
70
|
+
surface('wb-config-context', '控制层', '导航与临时操作使用轻透表面,通过边缘区分层级。', '--surface-control'),
|
|
71
|
+
surface('wb-content', '阅读层', '字段、记录和配置正文使用稳定底色,不模糊其后的内容。', '--surface-data'),
|
|
72
|
+
surface('drawer-help', '内嵌说明', '规则说明与写入事实使用安静的底板,不在浮层中叠加玻璃。', '--wash')),
|
|
73
73
|
h('div', { class: 'ds-fonts' }, h('div', { class: 'table-title' }, h('h2', {}, 'users · 用户基础信息')),
|
|
74
74
|
h('span', {}, 'orders · 每一行,都有依据。'), h('code', { class: 'mono' }, 'user_id INTEGER'),
|
|
75
75
|
h('span', {}, '1,024 行 · 2026-09-26')),
|
|
@@ -125,6 +125,11 @@ const countInput = h('input', { type: 'text', inputmode: 'numeric', value: '0',
|
|
|
125
125
|
const countField = field('生成数量 · 错误恢复示例', countInput);
|
|
126
126
|
countField.append(countError);
|
|
127
127
|
const stageSample = h('ol', {class:'wb-guide-stages', 'aria-label':'生成流程样式示例'});
|
|
128
|
+
const pathShortcutSample = button('', () => {
|
|
129
|
+
const selected = pathShortcutSample.getAttribute('aria-pressed') !== 'true';
|
|
130
|
+
pathShortcutSample.setAttribute('aria-pressed', String(selected));
|
|
131
|
+
actionStatus.textContent = selected ? '依赖路径入口已选中;此样例未修改配置。' : '依赖路径入口恢复普通状态;此样例未修改配置。';
|
|
132
|
+
}, {glyph:'relations', plain:true, class:'table-graph-shortcut', 'aria-label':'查看依赖路径样例', title:'查看依赖路径样例', 'aria-pressed':'false'});
|
|
128
133
|
let stageIndicator;
|
|
129
134
|
for (const [index, [label, hint]] of [['设定规则','选择表与字段'],['预览样例','只读查看结果'],['确认写入','核对生成计划']].entries()) {
|
|
130
135
|
const stage = button('', () => {
|
|
@@ -143,8 +148,7 @@ root.append(section('controls', '基础控件', '悬停、键盘焦点与选中
|
|
|
143
148
|
actionStatus,
|
|
144
149
|
h('h3',{},'关系图入口 · 节点与分支'),
|
|
145
150
|
h('div', {class:'ds-row'},
|
|
146
|
-
|
|
147
|
-
{glyph:'relations', plain:true, class:'table-graph-shortcut', 'aria-label':'查看依赖路径样例', title:'查看依赖路径样例'}),
|
|
151
|
+
pathShortcutSample,
|
|
148
152
|
button('查看关系图', () => { actionStatus.textContent = '带文字的关系图入口样例,没有修改配置。'; }, {glyph:'relations',small:true})),
|
|
149
153
|
h('h3',{},'生成流程 · 分段导航'), stageSample,
|
|
150
154
|
h('h3',{},'连接恢复 · 主次操作'),
|
|
@@ -164,7 +168,7 @@ root.append(section('controls', '基础控件', '悬停、键盘焦点与选中
|
|
|
164
168
|
notes('Tab 逐项移动焦点,Space 切换复选框;焦点环不等同于已选状态。',
|
|
165
169
|
'鼠标悬停呈现柔和阴影,按钮不移动;已选底色仍然保留,键盘焦点继续有清晰外圈。',
|
|
166
170
|
'绿色主按钮使用同色相渐变、低反光内缘与柔和外阴影表达厚度;按下时回落,不出现白色亮顶线。',
|
|
167
|
-
'
|
|
171
|
+
'关系入口使用居中的三个圆角节点和正交分支;点击样例切换选中状态。桌面触发区为 32×32px,窄屏及触控为 44×44px;检查明暗、悬停和键盘焦点,图标与触发区保持同心。',
|
|
168
172
|
'生成流程共用底槽,选中底板短暂滑动,编号和文字保持原位;窄屏换行、初载和尺寸变化直接定位。',
|
|
169
173
|
'快速来回切换时底板从当前位置转向;系统选择减少动态效果时立即切换。复选框和单选框只让标记短暂浮现,输入框不会位移。',
|
|
170
174
|
'连接恢复按钮居中并保持间距,窄屏自然换行;主操作和次操作使用正式按钮样式。',
|
|
@@ -372,7 +372,7 @@ export function createDropdown({
|
|
|
372
372
|
}
|
|
373
373
|
function reposition(event) {
|
|
374
374
|
// 列表内部滚动只更新方向提示,不重新测量定位或改动其滚动位置。
|
|
375
|
-
if (event?.target && popup.contains(event.target)) {
|
|
375
|
+
if (event?.type === 'scroll' && event.target && popup.contains(event.target)) {
|
|
376
376
|
return;
|
|
377
377
|
}
|
|
378
378
|
// 属性面板被 render() 整体重绘时(切列 / 切生成器 / AI 回填),旧的 dropdown
|
{sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/generation-defaults-control.js
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {tr, formatNumber, setText, setAttr, UserFacingError, errorText
|
|
1
|
+
import {tr, formatNumber, setText, setAttr, UserFacingError, errorText} from './i18n.js';
|
|
2
2
|
import './i18n/messages/components.js';
|
|
3
3
|
import {h, api} from './api.js';
|
|
4
4
|
import {button} from './workbench/ui.js';
|
|
@@ -70,7 +70,7 @@ export function createGenerationDefaultsControl() {
|
|
|
70
70
|
try {
|
|
71
71
|
const [languages, providers] = await Promise.all([api('/api/meta/locales', {signal: controller.signal}), api('/api/meta/providers', {signal: controller.signal})]);
|
|
72
72
|
if (destroyed) return;
|
|
73
|
-
localeOptions = languages.locales.map(item => ({value: item.code, label:
|
|
73
|
+
localeOptions = languages.locales.map(item => ({value: item.code, label: item.label}));
|
|
74
74
|
providerFacts = providers.statuses || {};
|
|
75
75
|
// Keep unavailable stored choices visible; never silently switch their meaning.
|
|
76
76
|
const value = locale.get();
|
{sqlseed_web-0.2.5 → sqlseed_web-0.2.6}/src/sqlseed_web/static/js/i18n/messages/workbench.json
RENAMED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"workbench": {
|
|
3
|
+
"scope.viewing": ["当前查看:{table}", "Viewing: {table}"],
|
|
4
|
+
"scope.noTable": ["暂无表", "No table"],
|
|
5
|
+
"scope.selectedCount": ["已选 {count} 张表用于生成", {"one":"{count} table selected for generation", "other":"{count} tables selected for generation"}],
|
|
6
|
+
"guide.currentStage": ["{stage}/3 · {title}", "{stage}/3 · {title}"],
|
|
7
|
+
"guide.rulesShort": ["规则", "Rules"],
|
|
8
|
+
"guide.previewShort": ["样例", "Preview"],
|
|
9
|
+
"guide.confirmShort": ["确认", "Confirm"],
|
|
10
|
+
"execution.status.ready": ["已核对,确认后将写入数据库。", "Reviewed. Confirm to write to the database."],
|
|
11
|
+
"execution.status.checking": ["正在核对写入方案,请稍候。", "Checking the write plan. Please wait."],
|
|
12
|
+
"execution.status.busy": ["正在提交写入,请勿重复操作。", "Submitting the write. Please wait."],
|
|
13
|
+
"execution.status.blocked": ["暂不能写入,请查看原因并调整。", "Writing is blocked. Review the reasons and adjust."],
|
|
14
|
+
"execution.status.failure": ["未能完成,请查看原因后重试。", "The request failed. Review the reasons before retrying."],
|
|
15
|
+
"execution.viewReasons": ["查看原因", "View reasons"],
|
|
16
|
+
"execution.diagnostics": ["详细诊断", "Detailed diagnostics"],
|
|
3
17
|
"unsupported.title": ["当前工作台不支持此生成范围", "This generation scope is not supported"],
|
|
4
18
|
"unsupported.body": [
|
|
5
19
|
"所选范围包含当前不支持的跨表循环:{tables}。这不是行数或生成器参数错误。具体原因见下方;SQLite 追加仅在循环内每条单列外键已有可用父键时受支持,缺少来源时全选或原样重试无法解除限制。",
|