sqlseed-web 0.2.4__tar.gz → 0.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. sqlseed_web-0.2.5/AGENTS.md +38 -0
  2. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/PKG-INFO +43 -13
  3. sqlseed_web-0.2.5/README.md +111 -0
  4. sqlseed_web-0.2.5/README.zh-CN.md +73 -0
  5. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/pyproject.toml +1 -1
  6. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/AGENTS.md +62 -48
  7. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/__init__.py +6 -1
  8. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/_application.py +51 -20
  9. sqlseed_web-0.2.5/src/sqlseed_web/_diagnostic_text.py +36 -0
  10. sqlseed_web-0.2.5/src/sqlseed_web/_windows_process.py +342 -0
  11. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/ai_settings.py +2 -1
  12. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/api.py +97 -56
  13. sqlseed_web-0.2.5/src/sqlseed_web/diagnostics.py +37 -0
  14. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/managed_worker.py +36 -6
  15. sqlseed_web-0.2.5/src/sqlseed_web/messages.py +213 -0
  16. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/plugin_environment.py +92 -28
  17. sqlseed_web-0.2.5/src/sqlseed_web/plugin_management.py +484 -0
  18. sqlseed_web-0.2.5/src/sqlseed_web/plugin_process.py +193 -0
  19. sqlseed_web-0.2.5/src/sqlseed_web/plugin_updates.py +297 -0
  20. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/runtime_lifecycle.py +5 -3
  21. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/runtime_session.py +13 -7
  22. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/settings_environment.py +91 -32
  23. sqlseed_web-0.2.5/src/sqlseed_web/settings_updates.py +229 -0
  24. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/sqlite_target.py +42 -9
  25. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/state.py +28 -18
  26. sqlseed_web-0.2.5/src/sqlseed_web/static/AGENTS.md +222 -0
  27. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/ai.css +19 -11
  28. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/configs.css +19 -8
  29. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/date-picker.css +7 -7
  30. sqlseed_web-0.2.5/src/sqlseed_web/static/design-system.css +47 -0
  31. sqlseed_web-0.2.5/src/sqlseed_web/static/design-system.html +24 -0
  32. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/disclosure.css +9 -6
  33. sqlseed_web-0.2.5/src/sqlseed_web/static/fonts/chill-round-gothic/ChillRoundGothic-Medium.woff2 +0 -0
  34. sqlseed_web-0.2.5/src/sqlseed_web/static/fonts/chill-round-gothic/ChillRoundGothic-Regular.woff2 +0 -0
  35. sqlseed_web-0.2.5/src/sqlseed_web/static/fonts/chill-round-gothic/License.txt +93 -0
  36. sqlseed_web-0.2.5/src/sqlseed_web/static/fonts/chill-round-gothic/README.md +70 -0
  37. sqlseed_web-0.2.5/src/sqlseed_web/static/graph-clarity.css +278 -0
  38. sqlseed_web-0.2.5/src/sqlseed_web/static/i18n/backend-messages.json +1725 -0
  39. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/index.html +6 -4
  40. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/api.js +31 -18
  41. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/app.js +49 -10
  42. sqlseed_web-0.2.5/src/sqlseed_web/static/js/design-system.js +370 -0
  43. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/dropdown.js +108 -23
  44. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/filepicker.js +36 -25
  45. sqlseed_web-0.2.5/src/sqlseed_web/static/js/generation-defaults-control.js +84 -0
  46. sqlseed_web-0.2.5/src/sqlseed_web/static/js/generation-defaults.js +35 -0
  47. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/genform.js +22 -11
  48. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/assistant.js +3 -0
  49. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/assistant.json +574 -0
  50. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/components.js +3 -0
  51. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/components.json +626 -0
  52. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/configurations.js +3 -0
  53. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/configurations.json +370 -0
  54. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/datePicker.js +3 -0
  55. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/datePicker.json +144 -0
  56. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/editor.js +3 -0
  57. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/editor.json +464 -0
  58. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/flow.js +3 -0
  59. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/flow.json +448 -0
  60. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/graph.js +3 -0
  61. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/graph.json +344 -0
  62. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/labels.js +3 -0
  63. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/labels.json +548 -0
  64. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/preview.js +3 -0
  65. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/preview.json +309 -0
  66. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/providerGuide.js +3 -0
  67. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/providerGuide.json +112 -0
  68. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/runs.js +3 -0
  69. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/runs.json +262 -0
  70. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/settings.js +3 -0
  71. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/settings.json +536 -0
  72. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/shell.js +3 -0
  73. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/shell.json +96 -0
  74. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/workbench.js +3 -0
  75. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n/messages/workbench.json +1712 -0
  76. sqlseed_web-0.2.5/src/sqlseed_web/static/js/i18n.js +324 -0
  77. sqlseed_web-0.2.5/src/sqlseed_web/static/js/labels.js +197 -0
  78. sqlseed_web-0.2.5/src/sqlseed_web/static/js/pages/configs.js +580 -0
  79. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/pages/connect.js +35 -28
  80. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/pages/heal.js +11 -9
  81. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/pages/meta.js +1 -1
  82. sqlseed_web-0.2.5/src/sqlseed_web/static/js/pages/runs.js +364 -0
  83. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/pages/settings.js +252 -176
  84. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/pages/wizard.js +39 -8
  85. sqlseed_web-0.2.5/src/sqlseed_web/static/js/pages/workbench.js +3684 -0
  86. sqlseed_web-0.2.5/src/sqlseed_web/static/js/segment-motion.js +69 -0
  87. sqlseed_web-0.2.5/src/sqlseed_web/static/js/tab-motion.js +47 -0
  88. sqlseed_web-0.2.5/src/sqlseed_web/static/js/theme-control.js +42 -0
  89. sqlseed_web-0.2.5/src/sqlseed_web/static/js/theme.js +71 -0
  90. sqlseed_web-0.2.5/src/sqlseed_web/static/js/update-check-control.js +41 -0
  91. sqlseed_web-0.2.5/src/sqlseed_web/static/js/workbench/ai-adjustment.js +51 -0
  92. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/ai-eligibility.js +16 -13
  93. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/ai-stream.js +35 -16
  94. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/ai.js +228 -146
  95. sqlseed_web-0.2.5/src/sqlseed_web/static/js/workbench/clear-recovery.js +63 -0
  96. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/connection.js +140 -99
  97. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/date-picker.js +40 -37
  98. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/dependency-view.js +31 -12
  99. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/editor.js +172 -124
  100. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/focus.js +4 -1
  101. sqlseed_web-0.2.5/src/sqlseed_web/static/js/workbench/graph-layout.js +760 -0
  102. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/graph.js +505 -160
  103. sqlseed_web-0.2.5/src/sqlseed_web/static/js/workbench/guidance.js +33 -0
  104. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/model.js +61 -8
  105. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/plugin-management.js +108 -70
  106. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/preview-scroll-layout.js +6 -5
  107. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/preview.js +200 -102
  108. sqlseed_web-0.2.5/src/sqlseed_web/static/js/workbench/provider-guide.js +35 -0
  109. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/recovery.js +11 -9
  110. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/session.js +11 -9
  111. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/table-data.js +60 -34
  112. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/ui.js +38 -26
  113. sqlseed_web-0.2.5/src/sqlseed_web/static/motion.css +65 -0
  114. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/navigation.css +14 -4
  115. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/preview.css +23 -5
  116. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/runs.css +8 -17
  117. sqlseed_web-0.2.5/src/sqlseed_web/static/scrollbars.css +110 -0
  118. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/settings.css +36 -14
  119. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/style.css +1034 -324
  120. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/table-data.css +5 -2
  121. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/workbench.css +162 -46
  122. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/supervised_plugins.py +48 -22
  123. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/supervisor.py +19 -10
  124. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench.py +6 -2
  125. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_ai.py +181 -73
  126. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_ai_relations.py +37 -17
  127. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_ai_stream.py +50 -9
  128. sqlseed_web-0.2.5/src/sqlseed_web/workbench_cycles.py +222 -0
  129. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_data.py +31 -7
  130. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_execution.py +46 -13
  131. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_runtime.py +332 -162
  132. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_store.py +60 -31
  133. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/worker_control.py +45 -13
  134. sqlseed_web-0.2.5/tests/AGENTS.md +45 -0
  135. sqlseed_web-0.2.5/tests/complex_business_graph.json +1830 -0
  136. sqlseed_web-0.2.5/tests/complex_graph_fixture.py +251 -0
  137. sqlseed_web-0.2.5/tests/component_test_support.py +88 -0
  138. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/frontend_helpers.cjs +56 -2
  139. sqlseed_web-0.2.5/tests/test_ai_adjustment.cjs +78 -0
  140. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_ai_eligibility.cjs +2 -2
  141. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_api.py +2 -1
  142. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_api_regressions.py +66 -0
  143. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_app_shell.cjs +110 -14
  144. sqlseed_web-0.2.5/tests/test_backend_messages.py +294 -0
  145. sqlseed_web-0.2.5/tests/test_complex_business_graph.cjs +162 -0
  146. sqlseed_web-0.2.5/tests/test_complex_graph_fixture.py +196 -0
  147. sqlseed_web-0.2.5/tests/test_component_test_support.py +48 -0
  148. sqlseed_web-0.2.5/tests/test_configs.cjs +488 -0
  149. sqlseed_web-0.2.5/tests/test_connection.cjs +459 -0
  150. sqlseed_web-0.2.5/tests/test_connection_existing_file.py +138 -0
  151. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_date_picker.cjs +50 -2
  152. sqlseed_web-0.2.5/tests/test_dependency_groups.cjs +35 -0
  153. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_dropdown.cjs +226 -11
  154. sqlseed_web-0.2.5/tests/test_filepicker.cjs +76 -0
  155. sqlseed_web-0.2.5/tests/test_generation_defaults.cjs +50 -0
  156. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_genform.cjs +66 -3
  157. sqlseed_web-0.2.5/tests/test_graph_layout_order.cjs +120 -0
  158. sqlseed_web-0.2.5/tests/test_graph_routing.cjs +155 -0
  159. sqlseed_web-0.2.5/tests/test_hardening_boundaries.py +196 -0
  160. sqlseed_web-0.2.5/tests/test_i18n.cjs +272 -0
  161. sqlseed_web-0.2.5/tests/test_i18n_catalog.cjs +180 -0
  162. sqlseed_web-0.2.5/tests/test_i18n_component_paths.py +465 -0
  163. sqlseed_web-0.2.5/tests/test_i18n_validation_paths.py +416 -0
  164. sqlseed_web-0.2.5/tests/test_legacy_connect.cjs +92 -0
  165. sqlseed_web-0.2.5/tests/test_legacy_page_async.cjs +69 -0
  166. sqlseed_web-0.2.5/tests/test_modal_scroll.cjs +196 -0
  167. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_navigation_motion.cjs +11 -4
  168. sqlseed_web-0.2.5/tests/test_plugin_cleanup.py +123 -0
  169. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_plugin_management.cjs +110 -1
  170. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_plugin_management.py +135 -4
  171. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_plugin_process.py +54 -2
  172. sqlseed_web-0.2.5/tests/test_plugin_updates.py +492 -0
  173. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_preview_editing.cjs +7 -1
  174. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_provider_guide.cjs +18 -1
  175. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_rule_usability.cjs +1 -1
  176. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_run_recovery.cjs +13 -0
  177. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_runs.cjs +163 -2
  178. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_runtime_session.py +27 -0
  179. sqlseed_web-0.2.5/tests/test_segment_motion.cjs +122 -0
  180. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_settings.cjs +322 -6
  181. sqlseed_web-0.2.5/tests/test_settings_update_lifecycle.py +281 -0
  182. sqlseed_web-0.2.5/tests/test_settings_updates.py +124 -0
  183. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_supervised_plugins.py +83 -24
  184. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_supervisor.py +1 -2
  185. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_table_data.cjs +84 -0
  186. sqlseed_web-0.2.5/tests/test_theme.cjs +200 -0
  187. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_web_request_security.py +22 -0
  188. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_web_settings.py +86 -1
  189. sqlseed_web-0.2.5/tests/test_windows_environment.py +153 -0
  190. sqlseed_web-0.2.5/tests/test_windows_guard.py +131 -0
  191. sqlseed_web-0.2.5/tests/test_windows_plugin_lifecycle.py +259 -0
  192. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_wizard.cjs +192 -0
  193. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_ai.cjs +4 -0
  194. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_ai.py +95 -13
  195. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_ai_integration.cjs +101 -1
  196. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_ai_progress.cjs +59 -1
  197. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_ai_stream.cjs +51 -0
  198. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_async_boundaries.cjs +24 -0
  199. sqlseed_web-0.2.5/tests/test_workbench_capability_limits.cjs +243 -0
  200. sqlseed_web-0.2.5/tests/test_workbench_clear_recovery.cjs +202 -0
  201. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_concurrency.py +52 -27
  202. sqlseed_web-0.2.5/tests/test_workbench_connection_routing.cjs +120 -0
  203. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_context.cjs +4 -4
  204. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_data.cjs +1 -1
  205. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_documents.cjs +145 -1
  206. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_editor.cjs +148 -8
  207. sqlseed_web-0.2.5/tests/test_workbench_empty_schema.cjs +69 -0
  208. sqlseed_web-0.2.5/tests/test_workbench_execution.cjs +210 -0
  209. sqlseed_web-0.2.5/tests/test_workbench_existing_cycles.py +439 -0
  210. sqlseed_web-0.2.5/tests/test_workbench_graph.cjs +1359 -0
  211. sqlseed_web-0.2.5/tests/test_workbench_graph_checks.cjs +173 -0
  212. sqlseed_web-0.2.5/tests/test_workbench_guidance.cjs +262 -0
  213. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_model.cjs +63 -2
  214. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_page.cjs +61 -2
  215. sqlseed_web-0.2.5/tests/test_workbench_postgresql_cycles.py +197 -0
  216. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_preview.cjs +155 -1
  217. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_review.cjs +1 -1
  218. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_runtime.py +40 -3
  219. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_session.cjs +20 -2
  220. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_store.py +32 -1
  221. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_target_identity.py +56 -7
  222. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_usability.cjs +1 -1
  223. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_v8.cjs +2 -2
  224. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/workbench_harness.cjs +16 -9
  225. sqlseed_web-0.2.4/AGENTS.md +0 -56
  226. sqlseed_web-0.2.4/README.md +0 -81
  227. sqlseed_web-0.2.4/src/sqlseed_web/plugin_management.py +0 -322
  228. sqlseed_web-0.2.4/src/sqlseed_web/plugin_process.py +0 -131
  229. sqlseed_web-0.2.4/src/sqlseed_web/static/AGENTS.md +0 -180
  230. sqlseed_web-0.2.4/src/sqlseed_web/static/graph-clarity.css +0 -103
  231. sqlseed_web-0.2.4/src/sqlseed_web/static/js/labels.js +0 -195
  232. sqlseed_web-0.2.4/src/sqlseed_web/static/js/pages/configs.js +0 -424
  233. sqlseed_web-0.2.4/src/sqlseed_web/static/js/pages/runs.js +0 -293
  234. sqlseed_web-0.2.4/src/sqlseed_web/static/js/pages/workbench.js +0 -3123
  235. sqlseed_web-0.2.4/src/sqlseed_web/static/js/workbench/graph-layout.js +0 -332
  236. sqlseed_web-0.2.4/src/sqlseed_web/static/js/workbench/guidance.js +0 -29
  237. sqlseed_web-0.2.4/src/sqlseed_web/static/js/workbench/provider-guide.js +0 -33
  238. sqlseed_web-0.2.4/src/sqlseed_web/static/scrollbars.css +0 -42
  239. sqlseed_web-0.2.4/tests/AGENTS.md +0 -25
  240. sqlseed_web-0.2.4/tests/test_configs.cjs +0 -226
  241. sqlseed_web-0.2.4/tests/test_connection.cjs +0 -207
  242. sqlseed_web-0.2.4/tests/test_modal_scroll.cjs +0 -74
  243. sqlseed_web-0.2.4/tests/test_workbench_execution.cjs +0 -61
  244. sqlseed_web-0.2.4/tests/test_workbench_graph.cjs +0 -541
  245. sqlseed_web-0.2.4/tests/test_workbench_guidance.cjs +0 -100
  246. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/.gitignore +0 -0
  247. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/LICENSE +0 -0
  248. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/__main__.py +0 -0
  249. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/app.py +0 -0
  250. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/operation_errors.py +0 -0
  251. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/pages/browse.js +0 -0
  252. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/tree.js +0 -0
  253. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/ai-handoff.js +0 -0
  254. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/static/js/workbench/scroll-lock.js +0 -0
  255. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/src/sqlseed_web/workbench_schema.py +0 -0
  256. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/conftest.py +0 -0
  257. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_api_ai_secrets.py +0 -0
  258. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_browse.cjs +0 -0
  259. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_component_availability.py +0 -0
  260. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_disclosure_focus.cjs +0 -0
  261. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_job_completion.py +0 -0
  262. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_preview_scroll_layout.cjs +0 -0
  263. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_runtime_lifecycle.py +0 -0
  264. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_acceptance.py +0 -0
  265. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_ai_handoff.cjs +0 -0
  266. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_ai_relations.py +0 -0
  267. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_busy.cjs +0 -0
  268. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_configs.py +0 -0
  269. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_data.py +0 -0
  270. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_execution.py +0 -0
  271. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_providers.cjs +0 -0
  272. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_sample_budget.py +0 -0
  273. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_workbench_schema.py +0 -0
  274. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/test_worker_control.py +0 -0
  275. {sqlseed_web-0.2.4 → sqlseed_web-0.2.5}/tests/workbench_test_helpers.py +0 -0
@@ -0,0 +1,38 @@
1
+ # sqlseed-web 包边界
2
+
3
+ 本包是本机 Web 工作台:FastAPI 包装离线 core 与可选 AI 能力,直接提供静态 ES modules。正式导航为工作台、配置管理、运行记录、设置;连接使用同主题弹窗。当前产品能力见 [Web 工作台指南](../../docs/web-workbench.md)。
4
+
5
+ ## 入口与局部指南
6
+
7
+ | 范围 | 入口与规则 |
8
+ |---|---|
9
+ | HTTP API、连接、持久化与后台任务 | [后端指南](src/sqlseed_web/AGENTS.md) |
10
+ | 页面、规则面板、状态与样式 | [前端指南](src/sqlseed_web/static/AGENTS.md) |
11
+ | 包依赖、extra 与 console script | [pyproject.toml](pyproject.toml) |
12
+ | API、Node 与安装验收 | [测试指南](tests/AGENTS.md) |
13
+
14
+ ## 包与产品约定
15
+
16
+ - 本包是 standalone app,不注册到 `project.entry-points."sqlseed"`。必需依赖为 Core、FastAPI、Uvicorn、PyYAML、packaging;准确版本范围以 manifest 为准。
17
+ - 当前源码要求 Core `>=0.2.5.dev0,<0.3`,共享连接解析和诊断脱敏不能与旧 Core 混装;AI extra 仍为 `>=0.2.4.dev0,<0.3`。不能为安装方便放宽已使用接口的版本下界。`[ai]` 安装可选 AI,`[dev]` 提供 pytest/httpx。
18
+ - 没有 npm/Vite/bundler 或前端构建步骤,静态资源随 Python wheel 分发。保持一套清透玻璃设计及其浅色/深色模式与现有工作台交互;历史 connect/wizard/browse/heal/meta 页面不在正式 router 中加载,兼容旧 API 不要求恢复旧导航。
19
+ - 正式界面提供简体中文与 English,UI 偏好独立于生成配置的 locale。切语言只更新显式绑定的展示内容,不重挂页面、不发业务请求、不改用户数据;前后端 JSON 字典及 JS 注册入口同随 wheel 分发。维护入口见 [Web 双语维护](../../docs/development/web-i18n.md),不得把开发实现说明写成已完成发行/浏览器验收。
20
+ - 外观入口位于正式设置及组件样板页头;支持浅色、深色、跟随系统,默认浅色。偏好仅存当前浏览器并同步同源标签页,跟随系统自动响应明暗变化;不修改 AI 设置或生成配置,不发起 AI 或业务请求。主题及字体约束见前端指南。
21
+ - 未安装 AI 时基础连接、schema、配置、预览和填充仍可用。AI 仅按用户请求提供待审阅建议,应用后进入同一配置,不在写入时隐式调用 AI。provider/locale 属于生成配置,不属于连接表单。
22
+ - `sqlseed-web` 与 `python -m sqlseed_web` 默认启动 supervisor 和可替换 worker,监听 `127.0.0.1:8630`;安装发行包后即可启动,不需要仓库脚本。直接托管 `app:create_app` 可使用业务,但不具备自动组件管理。
23
+ - 草稿和运行保存在用户应用数据目录的 `sqlseed/workspace.sqlite3`,可用 `SQLSEED_WEB_WORKSPACE_PATH` 覆盖。连接凭据不随配置持久化;AI 普通设置、进程内密钥及 endpoint 隔离规则见后端指南。
24
+ - 默认受管模式在支持的独立环境中提供网页内组件管理;部署能力由后端返回,不能因为环境不可管理而阻止普通 Web。旧 `--manage-plugins` 只作兼容入口,不是普通启动步骤。
25
+ - 历史设计计划与原型用于解释已有决策;修改时以当前实现、正式指南和局部回归约束核验,不将旧导航、历史测试数量或阶段性验收状态当作新增需求。
26
+
27
+ ## 验证
28
+
29
+ 完整开发依赖使用 [根指南](../../AGENTS.md) 的五包安装命令。从仓库根运行:
30
+
31
+ ```bash
32
+ pytest plugins/sqlseed-web/tests/ -q
33
+ node --test plugins/sqlseed-web/tests/test_*.cjs
34
+ ruff check plugins/sqlseed-web/
35
+ mypy plugins/sqlseed-web/src/
36
+ ```
37
+
38
+ 根 pytest 包含 Web,CI 单独运行 Node 内置测试,无 npm 依赖。页面行为修改需补实际浏览器验证;真实 LLM、PostgreSQL、安装后入口验收分别记录,不能互相替代。generator/hook 元数据从 core 动态读取,不将历史数量硬编码为新事实。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sqlseed-web
3
- Version: 0.2.4
3
+ Version: 0.2.5
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
@@ -13,7 +13,7 @@ Requires-Python: >=3.10
13
13
  Requires-Dist: fastapi>=0.110
14
14
  Requires-Dist: packaging>=23.2
15
15
  Requires-Dist: pyyaml>=6.0
16
- Requires-Dist: sqlseed<0.3,>=0.2.4.dev0
16
+ Requires-Dist: sqlseed<0.3,>=0.2.5.dev0
17
17
  Requires-Dist: uvicorn>=0.29
18
18
  Provides-Extra: ai
19
19
  Requires-Dist: sqlseed-ai<0.3,>=0.2.4.dev0; extra == 'ai'
@@ -24,22 +24,26 @@ Description-Content-Type: text/markdown
24
24
 
25
25
  # sqlseed Web
26
26
 
27
+ [简体中文](https://github.com/sunbos/sqlseed/blob/main/plugins/sqlseed-web/README.zh-CN.md)
28
+
27
29
  A local browser workbench for declarative SQLite and PostgreSQL test data generation.
28
30
  Connect a database, edit field rules, preview samples, inspect dependencies and review
29
31
  generation results. The Python core runs offline; AI suggestions are optional.
30
32
 
31
33
  ## Installation
32
34
 
33
- For the 0.2.4 release, create and activate a Python 3.10+ virtual environment:
35
+ These instructions target version 0.2.5. Check [Releases](https://github.com/sunbos/sqlseed/releases)
36
+ for publication status; use the source installation below to test an unpublished candidate.
37
+ Use a Python 3.10+ virtual environment:
34
38
 
35
39
  ```bash
36
- python -m pip install "sqlseed==0.2.4" "sqlseed-web==0.2.4"
40
+ python -m pip install "sqlseed==0.2.5" "sqlseed-web==0.2.5"
37
41
  sqlseed-web
38
42
  ```
39
43
 
40
44
  Open `http://127.0.0.1:8630`. The wheel includes the frontend; no Node or npm build
41
- is needed to use the app. For PostgreSQL, also install `"sqlseed[postgres]==0.2.4"`.
42
- Core 0.2.3 does not provide the required workbench runtime interfaces.
45
+ is needed to use the app. For PostgreSQL, also install `"sqlseed[postgres]==0.2.5"`.
46
+ Core 0.2.4 and older lack the shared connection and diagnostic interfaces required by this version.
43
47
 
44
48
  For development, install local Core and Web together from the repository root:
45
49
 
@@ -47,6 +51,29 @@ For development, install local Core and Web together from the repository root:
47
51
  python -m pip install -e . -e ./plugins/sqlseed-web
48
52
  ```
49
53
 
54
+ Version 0.2.5 and its source candidates require Core `>=0.2.5.dev0,<0.3` for
55
+ connection-target parsing and diagnostic redaction. Install matching Core and Web
56
+ versions; do not disable dependency checks to keep an older Core.
57
+
58
+ ## Interface language
59
+
60
+ Version 0.2.5 offers **简体中文 / English** in the top bar.
61
+ The browser remembers your choice and synchronizes it with other tabs on the same
62
+ origin. Without a saved choice, the first supported browser language is used,
63
+ falling back to English. If storage is unavailable, switching still works for the
64
+ current page.
65
+
66
+ Switching updates labels, help and supported diagnostics in place. It does not
67
+ reload the page, submit a form or make a database/AI request. Unsaved edits, focus
68
+ and selections are retained. **Data language and region** is a separate generation
69
+ setting: changing the interface language does not change generated data,
70
+ configuration names, schema identifiers, YAML or database values. Older or
71
+ third-party diagnostics may retain their original text with a translated explanation.
72
+
73
+ Message resources ship with the wheel and require no translation service. See the
74
+ [maintenance guide](https://sunbos.github.io/sqlseed/development/web-i18n/) for
75
+ coverage and the checks required for new UI messages.
76
+
50
77
  ## Optional components
51
78
 
52
79
  Open **Settings → Plugins and versions** to see which components are available and which
@@ -62,14 +89,17 @@ install local Core, CLI, AI, and Web together in the same resolution:
62
89
  python -m pip install -e . -e ./plugins/sqlseed-cli -e ./plugins/sqlseed-ai -e ./plugins/sqlseed-web
63
90
  ```
64
91
 
65
- For the 0.2.4 release, `python -m pip install "sqlseed-web[ai]==0.2.4"` installs
92
+ For version 0.2.5, `python -m pip install "sqlseed-web[ai]==0.2.5"` installs
66
93
  the optional AI component. The page does not fall back to an incompatible older release.
67
94
 
68
- On supported writable macOS/Linux virtual environments, the default launcher manages
69
- optional packages through the page and restores the service automatically. Windows,
70
- externally hosted apps and read-only/system environments can use the workbench but do not
71
- offer in-page package changes. Missing components produce an explanation and recovery
72
- entry point; the app preserves the configuration instead of silently changing its engine.
95
+ The version 0.2.5 default launcher manages optional packages
96
+ in supported writable Windows, macOS and Linux virtual environments and restores
97
+ the service automatically. Externally hosted apps and read-only/system environments
98
+ can use the workbench but do not offer in-page package changes. Missing components
99
+ produce an explanation and recovery entry point; the app preserves the configuration
100
+ instead of silently changing its engine. Updates require a reviewed compatible wheel
101
+ and keep other installed components fixed; Core and Web are updated through the
102
+ environment's package manager.
73
103
 
74
104
  ## Data and deployment boundaries
75
105
 
@@ -87,7 +117,7 @@ and [support boundaries](https://sunbos.github.io/sqlseed/maintainable-release/)
87
117
  ## Requirements
88
118
 
89
119
  - Python `>=3.10`
90
- - `sqlseed>=0.2.4.dev0,<0.3`
120
+ - `sqlseed>=0.2.5.dev0,<0.3`
91
121
  - `fastapi>=0.110`
92
122
  - `uvicorn>=0.29`
93
123
  - `pyyaml>=6.0`
@@ -0,0 +1,111 @@
1
+ # sqlseed Web
2
+
3
+ [简体中文](https://github.com/sunbos/sqlseed/blob/main/plugins/sqlseed-web/README.zh-CN.md)
4
+
5
+ A local browser workbench for declarative SQLite and PostgreSQL test data generation.
6
+ Connect a database, edit field rules, preview samples, inspect dependencies and review
7
+ generation results. The Python core runs offline; AI suggestions are optional.
8
+
9
+ ## Installation
10
+
11
+ These instructions target version 0.2.5. Check [Releases](https://github.com/sunbos/sqlseed/releases)
12
+ for publication status; use the source installation below to test an unpublished candidate.
13
+ Use a Python 3.10+ virtual environment:
14
+
15
+ ```bash
16
+ python -m pip install "sqlseed==0.2.5" "sqlseed-web==0.2.5"
17
+ sqlseed-web
18
+ ```
19
+
20
+ 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.5"`.
22
+ Core 0.2.4 and older lack the shared connection and diagnostic interfaces required by this version.
23
+
24
+ For development, install local Core and Web together from the repository root:
25
+
26
+ ```bash
27
+ python -m pip install -e . -e ./plugins/sqlseed-web
28
+ ```
29
+
30
+ Version 0.2.5 and its source candidates require Core `>=0.2.5.dev0,<0.3` for
31
+ connection-target parsing and diagnostic redaction. Install matching Core and Web
32
+ versions; do not disable dependency checks to keep an older Core.
33
+
34
+ ## Interface language
35
+
36
+ Version 0.2.5 offers **简体中文 / English** in the top bar.
37
+ The browser remembers your choice and synchronizes it with other tabs on the same
38
+ origin. Without a saved choice, the first supported browser language is used,
39
+ falling back to English. If storage is unavailable, switching still works for the
40
+ current page.
41
+
42
+ Switching updates labels, help and supported diagnostics in place. It does not
43
+ reload the page, submit a form or make a database/AI request. Unsaved edits, focus
44
+ and selections are retained. **Data language and region** is a separate generation
45
+ setting: changing the interface language does not change generated data,
46
+ configuration names, schema identifiers, YAML or database values. Older or
47
+ third-party diagnostics may retain their original text with a translated explanation.
48
+
49
+ Message resources ship with the wheel and require no translation service. See the
50
+ [maintenance guide](https://sunbos.github.io/sqlseed/development/web-i18n/) for
51
+ coverage and the checks required for new UI messages.
52
+
53
+ ## Optional components
54
+
55
+ Open **Settings → Plugins and versions** to see which components are available and which
56
+ features depend on them. Base is built in, Faker is installed with core, and Mimesis is
57
+ optional. AI is needed only for model-assisted rule suggestions; accepted rules can be
58
+ executed offline.
59
+
60
+ This workbench requires the AI interfaces from the 0.2.4 release line. It rejects
61
+ older importable AI packages instead of reporting them as ready. For a source checkout,
62
+ install local Core, CLI, AI, and Web together in the same resolution:
63
+
64
+ ```bash
65
+ python -m pip install -e . -e ./plugins/sqlseed-cli -e ./plugins/sqlseed-ai -e ./plugins/sqlseed-web
66
+ ```
67
+
68
+ For version 0.2.5, `python -m pip install "sqlseed-web[ai]==0.2.5"` installs
69
+ the optional AI component. The page does not fall back to an incompatible older release.
70
+
71
+ The version 0.2.5 default launcher manages optional packages
72
+ in supported writable Windows, macOS and Linux virtual environments and restores
73
+ the service automatically. Externally hosted apps and read-only/system environments
74
+ can use the workbench but do not offer in-page package changes. Missing components
75
+ produce an explanation and recovery entry point; the app preserves the configuration
76
+ instead of silently changing its engine. Updates require a reviewed compatible wheel
77
+ and keep other installed components fixed; Core and Web are updated through the
78
+ environment's package manager.
79
+
80
+ ## Data and deployment boundaries
81
+
82
+ Preview does not write generated rows. Generation requires an explicit confirmation;
83
+ batch failures can leave earlier committed data, so read the run result before retrying.
84
+ Use a test database or a disposable copy for demonstrations.
85
+
86
+ The service is designed for one trusted local user and has no multi-user authentication.
87
+ It binds to loopback by default. Do not expose it directly to an untrusted network.
88
+ Same-origin request checks do not replace authentication or database permissions.
89
+
90
+ See the [workbench guide](https://sunbos.github.io/sqlseed/web-workbench/)
91
+ and [support boundaries](https://sunbos.github.io/sqlseed/maintainable-release/).
92
+
93
+ ## Requirements
94
+
95
+ - Python `>=3.10`
96
+ - `sqlseed>=0.2.5.dev0,<0.3`
97
+ - `fastapi>=0.110`
98
+ - `uvicorn>=0.29`
99
+ - `pyyaml>=6.0`
100
+ - `packaging>=23.2`
101
+ - Optional `ai` extra: `sqlseed-ai>=0.2.4.dev0,<0.3`
102
+
103
+ ## Development checks
104
+
105
+ ```bash
106
+ pytest plugins/sqlseed-web/tests/
107
+ node --test plugins/sqlseed-web/tests/test_*.cjs
108
+ ```
109
+
110
+ License: [AGPL-3.0-or-later](https://github.com/sunbos/sqlseed/blob/main/LICENSE).
111
+ The distribution includes the full LICENSE text.
@@ -0,0 +1,73 @@
1
+ # sqlseed Web
2
+
3
+ [English](https://github.com/sunbos/sqlseed/blob/main/plugins/sqlseed-web/README.md)
4
+
5
+ 面向 SQLite 与 PostgreSQL 声明式测试数据生成的本机浏览器工作台。连接数据库、编辑字段规则、预览样例、检查依赖并查看生成结果。Python core 离线运行;AI 建议是可选功能。
6
+
7
+ ## 安装
8
+
9
+ 本文安装说明对应 0.2.5 版本;发布状态以 [Releases](https://github.com/sunbos/sqlseed/releases) 为准。测试尚未发布的候选版本时,使用下方的源码安装方式。请先创建并激活 Python 3.10+ 虚拟环境:
10
+
11
+ ```bash
12
+ python -m pip install "sqlseed==0.2.5" "sqlseed-web==0.2.5"
13
+ sqlseed-web
14
+ ```
15
+
16
+ 打开 `http://127.0.0.1:8630`。wheel 包含前端,使用时无需 Node 或 npm 构建。PostgreSQL 还需安装 `"sqlseed[postgres]==0.2.5"`。Core 0.2.4 及更早版本缺少本版本所需的共享连接和诊断接口。
17
+
18
+ 开发源码从仓库根同时安装 Core 与 Web:
19
+
20
+ ```bash
21
+ python -m pip install -e . -e ./plugins/sqlseed-web
22
+ ```
23
+
24
+ 0.2.5 版本及其源码候选要求 Core `>=0.2.5.dev0,<0.3`,用于连接目标解析与诊断脱敏。请使用匹配的 Core 与 Web 版本,不要关闭依赖检查来保留旧 Core。
25
+
26
+ ## 界面语言
27
+
28
+ 0.2.5 版本在顶栏提供 **简体中文 / English**。浏览器记住选择,并与同源标签页同步。没有已存偏好时,采用浏览器偏好中第一个支持的语言,无匹配则使用 English;存储不可用时仍能在当前页切换。
29
+
30
+ 切换就地更新标签、帮助和受支持的诊断,不刷新页面、不提交表单,也不发数据库或 AI 请求;未保存的修改、焦点和选择保持不变。**数据语言与地区**是独立的生成配置:切换界面语言不改变生成内容、配置名称、表列标识、YAML 或数据库原值。旧记录或第三方诊断可能保留原文,并附当前语言说明。
31
+
32
+ 语言资源随 wheel 分发,不需要翻译服务。覆盖与新增文案所需验证见 [Web 双语维护](https://sunbos.github.io/sqlseed/development/web-i18n/)。
33
+
34
+ ## 可选组件
35
+
36
+ 在“设置 → 插件与版本”查看组件可用性及受影响功能。Base 内置,Faker 随 Core 安装,Mimesis 可选。只有模型辅助规则建议需要 AI;接受后的规则可以离线执行。
37
+
38
+ 工作台要求 0.2.4 发布线的 AI 接口;旧包即使可导入,也不会被报告为可用。源码开发时在同一次解析中安装本地 Core、CLI、AI 与 Web:
39
+
40
+ ```bash
41
+ python -m pip install -e . -e ./plugins/sqlseed-cli -e ./plugins/sqlseed-ai -e ./plugins/sqlseed-web
42
+ ```
43
+
44
+ 0.2.5 使用 `python -m pip install "sqlseed-web[ai]==0.2.5"` 安装可选 AI 组件。页面不会回退到不兼容的旧版本。
45
+
46
+ 0.2.5 的默认启动器可在受支持、可写的 Windows、macOS 与 Linux 虚拟环境中管理可选包,并自动恢复服务。外部托管、只读或系统环境仍可使用工作台,但不开放网页包变更。组件缺失会显示原因和恢复入口,不会静默替换配置中的引擎。更新必须审阅兼容 wheel,保持其他已安装组件的版本;Core 与 Web 由环境的包管理工具更新。
47
+
48
+ ## 数据与部署边界
49
+
50
+ 预览不写入生成记录。正式生成必须明确确认;分批失败可能保留此前已提交的数据,重试前应核对运行结果。演示使用测试数据库或可丢弃副本。
51
+
52
+ 服务面向一个可信的本机用户,没有多用户认证,默认只监听 loopback。不要直接暴露到不可信网络;同源请求检查不能替代认证或数据库权限。
53
+
54
+ 详见[工作台指南](https://sunbos.github.io/sqlseed/web-workbench/)与[支持边界](https://sunbos.github.io/sqlseed/maintainable-release/)。
55
+
56
+ ## 依赖
57
+
58
+ - Python `>=3.10`
59
+ - `sqlseed>=0.2.5.dev0,<0.3`
60
+ - `fastapi>=0.110`
61
+ - `uvicorn>=0.29`
62
+ - `pyyaml>=6.0`
63
+ - `packaging>=23.2`
64
+ - 可选 `ai` extra:`sqlseed-ai>=0.2.4.dev0,<0.3`
65
+
66
+ ## 开发验证
67
+
68
+ ```bash
69
+ pytest plugins/sqlseed-web/tests/
70
+ node --test plugins/sqlseed-web/tests/test_*.cjs
71
+ ```
72
+
73
+ 许可证:[AGPL-3.0-or-later](https://github.com/sunbos/sqlseed/blob/main/LICENSE)。发行包包含完整 LICENSE 文本。
@@ -13,7 +13,7 @@ license-files = ["LICENSE"]
13
13
  authors = [{ name = "sqlseed contributors" }]
14
14
  keywords = ["sqlseed", "test-data", "web-ui", "fastapi"]
15
15
  dependencies = [
16
- "sqlseed>=0.2.4.dev0,<0.3",
16
+ "sqlseed>=0.2.5.dev0,<0.3",
17
17
  "fastapi>=0.110",
18
18
  "uvicorn>=0.29",
19
19
  "pyyaml>=6.0",
@@ -1,8 +1,6 @@
1
1
  # sqlseed_web 后端
2
2
 
3
- 上层见 [包指南](../../AGENTS.md);前端另见 [static/AGENTS.md](static/AGENTS.md)。
4
-
5
- v8 整体重建已完成;当前细化以 [可用性与 AI 辅助计划](../../../../docs/superpowers/plans/2026-09-07-workbench-usability-ai.md) 为准,保留 [v8 重建契约](../../../../docs/superpowers/plans/2026-09-07-web-v8-rebuild.md) 的样式基线;导航按后续设置评审扩展为四项。以下原有 `/api` 行为是后端兼容边界,不要求保留旧页面或导航;正式 `/api/workbench` 及可选 AI 的规则见后文。
3
+ 继承 [包指南](../../AGENTS.md);页面与交互见 [static/AGENTS.md](static/AGENTS.md),测试入口见 [测试指南](../../tests/AGENTS.md)。正式工作台使用 `/api/workbench`;旧 `/api` 的兼容约束不要求保留历史页面导航。
6
4
 
7
5
  ## 模块与 API 边界
8
6
 
@@ -13,94 +11,110 @@ v8 整体重建已完成;当前细化以 [可用性与 AI 辅助计划](../../
13
11
  - `/api/connections` 管理连接,新连接弹窗复用该接口;连接下的 tables/schema/mapping/yaml-template、topo-order、preview/fill/rows/query 保留旧 API 兼容。正式工作台通过 `/api/workbench` 检查、预览和运行。
14
12
  - `/api/config/parse` 通过临时文件调用 core `load_config()`,`finally` 删除文件;`serialize` 使用 safe YAML。解析成功不表示 generator 名称有效,未知名称仍可在生成/验证时失败。
15
13
  - `config_to_dict()` 使用完整 Pydantic `model_dump`;新增配置字段时仍需核对前端往返,避免手工白名单漏字段。
14
+ - [messages.py](messages.py) 仅为显式构造的 `Message` 添加翻译描述:保留原字符串,增加 `<field>_key/<field>_params`;数组保留原值并添加对齐的 `<field>_i18n`。HTTP、流、受管 IPC 和持久化边界保持元数据,不扫描普通字符串猜译文,不把用户对象当翻译模板。原始诊断仍先脱敏;消息参数不得带密钥。共享字典位于 `static/i18n/backend-messages.json`,与前端 JSON 字典及 JS 注册入口一起随 wheel 分发。
15
+ - `_diagnostic_text.py` 是不依赖消息层的纯文本脱敏模块,供 messages 和 diagnostics 共用;`diagnostics.public_error()` 另保留 `Message` 与 `KeyError` 的结构化翻译元数据。不要重新引入两者的循环导入或先把结构化异常转成普通字符串。
16
16
  - `/api/fs/browse` 列出服务器目录,默认隐藏非 DB 文件,始终跳过 dotfiles;浏览器 file input 不能提供服务器绝对路径。
17
17
 
18
- ## 连接与后台任务
18
+ ## HTTP 准入与数据保护
19
+
20
+ - `_application.py` 的业务 API 拒绝跨 Origin、重复 Origin/Host 与 cross-site 请求;默认 loopback supervised worker 还验证 loopback Host,避免 DNS rebinding。外部 ASGI 部署的 Host/proxy 策略由其宿主负责,不能误称所有部署都自动只允许 loopback。
21
+ - 保留页面/静态资源的 `no-cache`、防嵌入响应头,以及管理接口的独立 Origin/token/loopback 检查;业务同源检查不能替代组件管理授权。请求校验和异常响应不得回显密钥或含凭据的连接地址。
22
+ - SQL 标识符用 `validate_table_name()` + `quote_identifier()`;`run_query()` 当前只接受单条 SELECT,修改查询接口时保留该边界。
23
+
24
+ ## 连接身份与隔离
19
25
 
20
26
  - 连接请求恰好提供 `db_path`/`url` 之一。每个连接持有长生命周期 `DataOrchestrator`;连接失败时清理已注册对象。
21
27
  - 同目标多连接是有效用法。旧 API 的长生命周期 orchestrator 保留独立 provider/locale;正式工作台的 provider/locale 属于配置,并按完整配置构建执行实例,不能用旧连接默认值覆盖文档。`group_key`、`group_index`、`group_size` 仅做显示分组,不是跨连接锁。
22
28
  - [sqlite_target.py](sqlite_target.py) 统一 SQLite 的分组、写入准入与配置身份,按 SQLAlchemy 传给 sqlite3 的实际 URI 参数识别文件、具名共享内存和私有内存。普通文件路径的既有配置 hash 保持不变;共享内存按名称、私有内存按 conn_id 隔离,不能把未启用 `uri` 的 `mode=memory` 当作内存库。Web 不支持自定义 SQLite VFS;实际 URI 带 `vfs` 时在连接注册、数据库打开前拒绝,不能忽略 `memdb` 等 VFS 导致同名不同库被合并。
29
+ - 实际连接与 Web 身份共用 core 的 `database._connection_url.connection_url()`;不要在 Web 单独通过 `make_url()` 解析 SQLite 路径。SQLAlchemy 2.0/2.1 的 database 解码行为不同:普通路径保留字面百分号和问号,显式 SQLite URI 的文件部分仅由 SQLite 解码一次;query 中的 `uri`、`mode`、`timeout` 等参数继续交给 dialect。身份回归必须同时核对实际打开的文件,不能只比较两个规范化字符串。
23
30
  - SQLite URI 中解码后的 NUL、原始 TAB/CR/LF、无效 UTF-8 百分号编码也在注册前拒绝:SQLite 字符串截断与 Python URL 清理/替代解码不同,不能把异常编码折叠成另一目标。合法 UTF-8 与经过百分号编码的 TAB/CR/LF 文件名仍按真实路径识别。
24
31
  - URI 文件路径须经平台路径转换;Windows 的 `/C:/...` 与普通 `C:\...` 指向同一文件。百分号只解码一次,文件名中的字面 `%41` 不能被误识别为 `A`;真实文件别名回归覆盖空格、百分号及编码盘符。
32
+ - 列表、打开和运行只接受当前 canonical `target_key`,不提供或接受旧身份 aliases。旧 URI hash 可能恰好属于另一个真实的 `file:` 前缀文件,不能仅凭当前连接写法推导旧 hash 并自动授权;没有可信身份版本的记录不得通过同 schema 或解析 target_label 猜库迁移。普通路径的旧 key 不变;身份发生变化的旧 URI 配置与运行仍保留可导出,由用户明确导入当前目标创建新配置,历史运行快照不改。历史记录未存原始连接或身份算法版本,旧错 hash 与真实字面 `file:` 路径 hash 的反向碰撞无法可靠区分,这是既有数据的限制,不自动推断或重绑。
33
+ - Web locale 使用 Faker 风格(`zh_CN`/`en_US`);`SUPPORTED_LOCALES` 与 `MimesisProvider.set_locale` 的映射保持一致。
34
+
35
+ ## 后台任务与终态
36
+
25
37
  - fills 在后台线程运行,通过 `state.connection_operation(conn_id, job_id=...)` 领取已预留的任务;交互请求不排队等待连接锁,忙碌立即返回 HTTP 409。不得让同一 orchestrator 并发 `fill_table()`。
26
38
  - `create_job()` 原子预留连接;同一数据库目标只能有一个填充任务,其他数据库可并行。SQLite 规范路径、file URI 和共享内存身份;PostgreSQL 只规范 URL 中已知端点及有效参数,不宣称识别 DNS 别名、service 或代理后的物理身份。worker 初始化、启动或终态持久化失败也必须释放任务占用。
27
39
  - job 终态通过 `complete_job()` 原子发布 result、错误、行数和完成时间;非空 `GenerationResult.errors` 必须发布 error,不能报告成功。后台入口持有 `UIState.job_completion()`,未知程序错误继续传播,但必须在 finally 发布失败并释放占用;工作台的快照读取、执行和终态保存中断也不能留下 running 或误报 done。
28
40
  - 创建任务与关闭连接受同一状态锁协调;排队/执行中的任务阻止关闭(HTTP 409),已失效连接的 worker 必须进入 error 终态。HTTP polling 使用任务快照。
29
41
  - `GenerationResult.count` 是写入行数;`Job.rows_inserted` 是 Web 层字段。旧 `/api` fill 进度来自行数差值轮询,是近似值,不是核心进度 callback;不能把这种进度方案用于正式工作台的精确提交结果。
30
- - SQL 标识符用 `validate_table_name()` + `quote_identifier()`;`run_query()` 当前只接受单条 SELECT,修改查询接口时保留该边界。
31
- - 旧 `/api/connections/{id}/tables/{table}/schema` 的 `unique_columns`、`skippable` 和 `ColumnInfo` 驱动历史面板;FK 字段为 `column`/`ref_table`/`ref_column`,均是单数。新工作台必须使用独立完整 schema 契约,保留成组列映射和 namespace,不能沿用此简化形状。
32
- - Web locale 使用 Faker 风格(`zh_CN`/`en_US`);`SUPPORTED_LOCALES` 与 `MimesisProvider.set_locale` 的映射保持一致。
33
-
34
- ## 可选 AI 边界
35
-
36
- - `sqlseed_ai` 必须在函数内 lazy import;metadata/config 缺失 AI 时返回 `available: false`,heal endpoints 用 HTTP 503。
37
- - [workbench_ai.py](workbench_ai.py) 是正式工作台可选 AI 接口:配置与检测复用 env + 会话设置,分析复用 `AIConfig` / `SchemaAnalyzer`,返回待审阅补丁,不运行自动修复或填充。
38
- - `/ai/suggest` 保留 JSON 响应兼容,`Accept: application/x-ndjson` 使用 [workbench_ai_stream.py](workbench_ai_stream.py) 发布实际 context/model/validation/preview 阶段与唯一终态。单次请求固定 AIConfig 快照;同连接 AI 门禁直到 worker 真正退出才释放,取消或 180 秒等待预算不等于硬中断 SDK 网络调用。ASGI 2.3 与 2.4 的断开监听不得竞争同一个 receive。
39
- - AI 候选样例经实例级 DataStream 尝试预算和合作式取消检查,不全局修改重试常量。保留结构化 validation issues(表、列、生成器、约束),禁止暴露已有记录、密钥或原始 SDK 错误;catalog 必须解释 pattern 的正则语义及当前 provider 的 phone/template 差异。
40
- - AI 范围支持整库、指定表多选、指定列多选及当前/勾选表快捷项,独立于生成范围。`allowed_targets` 限定修改列;上下文保留所在整表及必要上游结构、约束、生成器目录、全局引擎/语言和用户业务说明,不包含连接地址、凭据、row_count、运行时父键或已有记录。全部 `table_drafts` 参与保护和候选校验,不能因表未勾选丢失高级规则。schema/业务说明始终视作数据。
41
- - 建议经过范围、表列、generator 目录、参数及 `ColumnConfig` 校验。新关系仅由 [workbench_ai_relations.py](workbench_ai_relations.py) 编译 copy/concat/product/date_offset 模板,验证类型、NULL、来源可用性及新旧 core DAG;保留 PK/FK/实际使用数据库默认值的列/计算列和已有 derived/native 规则,拒绝模型原始表达式、原生方法或文件路径。整份候选配置只读校验,相关补丁带 group_id 并原子审阅/应用;样例检查不宣称证明任意 SQL CHECK。分析前后复核 schema hash,网络期间释放连接操作锁。
42
- - 新旧 AI 配置响应均不能回传 API key,只给是否配置的标记;修改设置时空密钥保留已有会话密钥,旧接口显式空请求仍重置会话覆盖。密钥不得保存进工作台文档或运行记录。
43
- - `/heal/validate`、`/heal/repair`、`/heal/auto` 分别委托 Layer 2、3、5;保持修复算法在 AI 包,不搬入 Web。
44
- - auto-heal 复用 `sqlseed_ai.runtime` 的 `build_ai_config()`、`build_llm_client()`、`build_heal_orchestrator()`;不导入 CLI 私有工厂。共享服务使用普通 Python 异常,CLI/Web 入口各自转换错误,修改签名时一并检查调用者与资源释放。
45
- - 有效 AI 配置从 env 合并会话 override,再由单次 auto-heal 请求覆盖;空 override 值回退到 env。metadata 与 `/api/ai/config` 的状态应一致。
46
- - `/api/ai/test-connection` 探测 `resolve_base_url().rstrip('/') + '/models'`;本地 Ollama/LM Studio 只要求服务可达,不要求用户填写 API key。
47
- - `AI_BACKENDS` 给出基础展示顺序,heal 页面会把有效 backend 提到首位;两个地方共同决定用户看到的顺序。
48
- - auto-heal 产出 YAML,不执行数据填充;`_CountingLLMClient` 记录真实 LLM 调用次数,确定性流程可能为 0,不能把“完成”描述成必然调用过 LLM。
49
- - AI 连接目标保持与 core 一致:含 `://` 的目标按 URL 传递,包括 `sqlite+pysqlite://`;不能用固定 dialect 前缀当文件路径判据。
50
42
 
51
- ## 正式工作台不变量
43
+ ## 工作台文档、schema 与持久化
52
44
 
53
45
  - 文档经完整 `GeneratorConfig` 校验,未知 root/table 字段必须报错;目标仅由明确的连接注入,保存内容不带 `db_path`/`url` 或凭据。不能因为面板没有编辑器就丢弃高级配置。
54
46
  - 保存校验 schema hash 和乐观 revision;开始运行时在 store 同一事务校验当前 revision 与快照,再保留不可变文档。检查和运行都重新读取真实结构及来源,不能相信前端的成功标记。
55
- - 列表、打开和运行只接受当前 canonical `target_key`,不提供或接受旧身份 aliases。旧 URI hash 可能恰好属于另一个真实的 `file:` 前缀文件,不能仅凭当前连接写法推导旧 hash 并自动授权;没有可信身份版本的记录不得通过同 schema 或解析 target_label 猜库迁移。普通路径的旧 key 不变;身份发生变化的旧 URI 配置与运行仍保留可导出,由用户明确导入当前目标创建新配置,历史运行快照不改。历史记录未存原始连接或身份算法版本,旧错 hash 与真实字面 `file:` 路径 hash 的反向碰撞无法可靠区分,这是既有数据的限制,不自动推断或重绑。
47
+ - 旧 `/api/connections/{id}/tables/{table}/schema` 的 `unique_columns`、`skippable` 和 `ColumnInfo` 驱动历史面板;FK 字段为 `column`/`ref_table`/`ref_column`,均是单数。新工作台必须使用独立完整 schema 契约,保留成组列映射和 namespace,不能沿用此简化形状。
56
48
  - 结构图方向父→子;复合 FK 是同一条边的成组列映射。跨 namespace 或不存在的来源保留只读节点,不能把它们映射到同名默认 schema 表。
49
+ - 跨表循环问题由 `workbench_runtime.py` 的迭代强连通分量计算给出精确 `tables` 和 `edge_ids`:只包含真正成环的成员及同一环内边,不把被阻塞的下游或不同环之间的桥标为循环。SQLite 环内全部单列 FK 已有可用父键时可原子追加,预览/写入通过 workbench_cycles.py 冻结既有父键,环内新增记录不得互相引用;空来源、组合或重叠 FK、配置关联及 PostgreSQL 循环仍阻止。来源问题增加结构化 `columns` 时保留既有 `column` 与 sources evidence 契约;组合键必须按完整列组匹配,不能拆成单列或误拆含逗号的列名。
57
50
  - SQLite rowid 分配优先使用 core 的 `ColumnInfo.is_rowid_alias` 事实,仅旧 metadata 缺失时使用兼容查询。部分索引不得进入无条件 `unique_constraints`;其条件保留在 `conditional_indexes` 并参与 schema hash,谓词变化会使旧检查失效。
58
51
  - 空父表在所选生成计划内是合法依赖。预览不能虚构尚未生成的父键,但仍须验证独立字段的生成器参数和表达式。
59
52
  - 未选父表存在有效引用键时可以只读引用;未选且缺少必需来源时才阻止对应生成。依赖检查返回来源是否可用、数量与范围事实,不向浏览器暴露实际父键列表。追加写入的自增 ID 由数据库分配,不能为改善预览展示而重置序列。
60
- - 工作台的保存、检查和执行不依赖 AI;AI 仅在用户请求时分析并产出待审阅建议,用户选中应用后进入同一份配置,仍由确定性检查验证。执行保持 `fill_table(skip_ai=True)`,不能在写入过程中隐式更改已经确认的规则。SQLite 清空使用明确执行策略和单事务,不能通过 core 配置 clear_before 隐式开启;PostgreSQL 清空、任意服务器 Python transform、跨表通用循环等未接入能力必须明确阻止,不可忽略。
61
- - Worker 持有连接操作锁并逐表执行,失败后其余表 `not_run`。已提交数量来自 `GenerationResult.count`,不能用总行数差冒充精确值。记录异常文本先脱敏,避免 SQLAlchemy 参数和连接密码落盘。
62
53
  - Store 使用 WAL、短事务、独立连接;`get_store()` 按路径缓存,只有首次初始化恢复遗留任务为 `interrupted`,不得在每次轮询时打断活跃任务。中断记录 `row_counts_exact=False`。
54
+ - 配置删除只删除可变草稿,不删除已提交运行快照、任务和业务记录;重命名/复制/删除均按 revision 检查。
63
55
 
64
- ## 验证
56
+ ## 执行与事务边界
65
57
 
66
- 从仓库根显式运行 `pytest plugins/sqlseed-web/tests/ -q`。并发、schema 约束和配置往返应使用真实 SQLite;AI 可达性测试可替换 HTTP 请求。
58
+ - 工作台的保存、检查和执行不依赖 AI;AI 仅在用户请求时分析并产出待审阅建议,用户选中应用后进入同一份配置,仍由确定性检查验证。执行保持 `fill_table(skip_ai=True)`,不能在写入过程中隐式更改已经确认的规则。SQLite 清空使用明确执行策略和单事务,不能通过 core 配置 clear_before 隐式开启;PostgreSQL 清空、任意服务器 Python transform、跨表通用循环等未接入能力必须明确阻止,不可忽略。
59
+ - Worker 持有连接操作锁并逐表执行,失败后其余表 `not_run`。已提交数量来自 `GenerationResult.count`,不能用总行数差冒充精确值。记录异常文本先脱敏,避免 SQLAlchemy 参数和连接密码落盘。
60
+ - `workbench_execution.py` 负责只读清空规划。POST execution-plan 使用保存的 draft/revision/schema/config 绑定,返回实际表/行数、删除顺序、能力和 plan_hash。POST runs 固定 execution/plan_hash;append 为兼容默认,replace_selected 必须重新验证确认计划。
61
+ - SQLite replace 与已验证的已有来源循环追加使用 SQLAlchemyAdapter.transaction(),父键读取、清空、自引用更新和批次写入共用连接;不关闭 FK、不自动 CASCADE、不在事务提交前报告已提交。失败回滚原行与序列,运行结果明确 rolled_back。PostgreSQL replace、清空跨表循环、范围外引用、清空触发器和未覆盖自引用等通过服务端能力检查阻止。已有来源循环的 atomic_append 为不可变运行快照事实,与执行计划的 atomic 保持一致;普通无环追加仍保留原来的逐批提交语义。
62
+ - `ExistingSourceOrchestrator` 是内部 Web 会话,预览与执行统一通过 `for_config()` 构造;工厂在连接与 metadata 缓存初始化前组合专用 `RelationResolver`,保留同一 adapter、shared pool 与配置关联。冻结池仍在原有检查/写入事务内读取,只替换已接受的单列循环 FK 来源;普通 FK 与关联继续由 Core 解析。不得通过重写整段 `_resolve_specs` 改动规则解析顺序或关键字契约;直接构造后调用 `pin_cycle_sources()` 必须明确报错,不得静默失去冻结策略。
63
+ - AI DEFAULT 保护按当前实际生成模式判断;生成器主动提供值时可优化,真正省略使用 DEFAULT 时保持保护。PK/FK、计算列及已有派生/原生规则继续保护。追加失败只有完整精确计数才能创建剩余配置,扣除已提交行数,保留原快照与已完成表草稿,不自动提交;中断/未知计数/清空模式不能直接推导剩余量。
67
64
 
68
- ## 显式执行策略
65
+ ## 只读当前数据
69
66
 
70
- - `workbench_execution.py` 负责只读清空规划。POST execution-plan 使用保存的 draft/revision/schema/config 绑定,返回实际表/行数、删除顺序、能力和 plan_hash。POST runs 固定 execution/plan_hash;append 为兼容默认,replace_selected 必须重新验证确认计划。
71
- - SQLite replace 使用 SQLAlchemyAdapter.transaction(),父键读取、清空、自引用更新和批次写入共用连接;不关闭 FK、不自动 CASCADE、不在事务提交前报告已提交。失败回滚原行与序列,运行结果明确 rolled_back。PostgreSQL replace、范围外引用、触发器和未覆盖自引用等通过服务端能力检查阻止。
72
- - 配置删除只删除可变草稿,不删除已提交运行快照、任务和业务记录;重命名/复制/删除均按 revision 检查。
67
+ - `workbench_data.py` 提供有界 GET 分页(limit 1–100、offset 非负)和运行目标的已注册连接匹配。读取先领取 connection_operation;run_id 存在时检查 target_key 与运行表范围,不能借活动连接读取另一目标。匹配连接列表不连接或反射数据库。
68
+ - 当前数据使用实际目录白名单、标识符引用、参数化分页和完整主键排序;空表保留列信息。BLOB、Decimal、超出 JavaScript 安全范围的整数及非有限浮点数保留可读值,driver 异常脱敏。接口不记录本次新增主键,也不提供写操作。
73
69
 
74
- - 2026-09-09 实测修正:AI DEFAULT 保护按当前实际生成模式判断;生成器主动提供值时可优化,真正省略使用 DEFAULT 时保持保护。PK/FK、计算列及已有派生/原生规则继续保护。追加失败只有完整精确计数才能创建剩余配置,扣除已提交行数,保留原快照与已完成表草稿,不自动提交;中断/未知计数/清空模式不能直接推导剩余量。
70
+ ## 可选 AI 与候选审阅
75
71
 
72
+ - `sqlseed_ai` 必须在函数内 lazy import;metadata/config 缺失 AI 时返回 `available: false`,heal endpoints 用 HTTP 503。
73
+ - [workbench_ai.py](workbench_ai.py) 是正式工作台可选 AI 接口:配置与检测复用 env + 会话设置,分析复用 `AIConfig` / `SchemaAnalyzer`,返回待审阅补丁,不运行自动修复或填充。
74
+ - `/ai/suggest` 保留 JSON 响应兼容,`Accept: application/x-ndjson` 使用 [workbench_ai_stream.py](workbench_ai_stream.py) 发布实际 context/model/validation/preview 阶段与唯一终态。单次请求固定 AIConfig 快照;同连接 AI 门禁直到 worker 真正退出才释放,取消或 180 秒等待预算不等于硬中断 SDK 网络调用。ASGI 2.3 与 2.4 的断开监听不得竞争同一个 receive。
75
+ - AI 候选样例经实例级 DataStream 尝试预算和合作式取消检查,不全局修改重试常量。保留结构化 validation issues(表、列、生成器、约束),禁止暴露已有记录、密钥或原始 SDK 错误;catalog 必须解释 pattern 的正则语义及当前 provider 的 phone/template 差异。
76
+ - AI 范围支持整库、指定表多选、指定列多选及当前/勾选表快捷项,独立于生成范围。`allowed_targets` 限定修改列;上下文保留所在整表及必要上游结构、约束、生成器目录、全局引擎/语言和用户业务说明,不包含连接地址、凭据、row_count、运行时父键或已有记录。全部 `table_drafts` 参与保护和候选校验,不能因表未勾选丢失高级规则。schema/业务说明始终视作数据。
77
+ - 建议经过范围、表列、generator 目录、参数及 `ColumnConfig` 校验。新关系仅由 [workbench_ai_relations.py](workbench_ai_relations.py) 编译 copy/concat/product/date_offset 模板,验证类型、NULL、来源可用性及新旧 core DAG;保留 PK/FK/实际使用数据库默认值的列/计算列和已有 derived/native 规则,拒绝模型原始表达式、原生方法或文件路径。整份候选配置只读校验,相关补丁带 group_id 并原子审阅/应用;样例检查不宣称证明任意 SQL CHECK。分析前后复核 schema hash,网络期间释放连接操作锁。
78
+ - 前端手动微调建议仍走确定性 `/api/workbench/check`:校验合并后的完整候选文档,不新增模型调用,也不绕过 schema、字段保护或执行检查。为校验未勾选表而加入的候选副本不能改变真实生成范围;检查通过后仍需由用户选中的补丁原子应用,失败不得写入当前配置或数据库。
79
+ - 新旧 AI 配置响应均不能回传 API key,只给是否配置的标记;修改设置时空密钥保留已有会话密钥,旧接口显式空请求仍重置会话覆盖。密钥不得保存进工作台文档或运行记录。
76
80
  - 自定义映射/enrichment 涉及 DEFAULT 时,AI 助手先调用只读 eligibility 预检,并与 suggest 共用实际规则解析;响应只含生成模式,不含样例或父键。普通配置不增加请求;编辑、关闭或离页后的旧结果不得打开可分析界面。
81
+ - AI 连接目标保持与 core 一致:含 `://` 的目标按 URL 传递,包括 `sqlite+pysqlite://`;不能用固定 dialect 前缀当文件路径判据。
77
82
 
78
- ## 2026-09-09 应用设置评审
83
+ ## AI 设置与环境状态
79
84
 
80
- - 用户已批准第四项主导航“设置”,由新 `pages/settings.js` 提供 AI 服务、插件与版本;不恢复旧 meta/heal 页面。普通设置由 Web 的 `ai_settings.py` 持久化,密钥保持环境变量或进程内存且按服务绑定。新环境接口由 `settings_environment.py` 只读汇总当前 Python 环境。
81
- - 工作台 AI 助手仅展示服务/模型摘要与设置入口;范围、业务说明、分析和审阅继续留在助手。`ai-handoff.js` 只在内存保存明确往返的上下文,身份/epoch/schema/生命周期失效时拒绝恢复。设置检测草稿不保存,不以模型列表成功声称推理成功;保存/检测防重复,迟到响应不覆盖新页面。
85
+ - `ai_settings.py` 持久化普通 AI 设置;`settings_environment.py` 只读汇总当前解释器的环境。页面 handoff、检测草稿与迟到响应规则见前端指南。
82
86
  - AI 普通设置字段为 backend/model/base_url;`SQLSEED_WEB_SETTINGS_PATH` 可覆盖。UI key 不入磁盘,不随跨 endpoint 切换继承,清除只在当前进程有效。配置表单不把同一进程中的设置称为浏览器私有。
83
- - `preview.js` 重新预览保留上次 DOM、选中表和滚动;状态标明旧结果,失败保留旧结果。`preview.css` 只提供首载占位和状态高度。使用当前行为回归与实际浏览器尺寸核验,不能把历史测试数当成本轮验收。
84
-
85
- ## 2026-09-10 环境状态契约
86
-
87
87
  - 环境条目保留 `packages`/`providers`,补充 `category`、`requirement`、`dependency_ids`、`description`、`install_command` 和 `guidance`。这些是当前产品展示范围内的关系,不是全量 Python 依赖图;版本与 Python 信息继续动态读取。Base 属于内置,Faker 是 Core 必需依赖,Mimesis 可选。
88
88
  - AI 配置读取、保存和检测返回 `availability_status`(`available`/`not_installed`/`import_error`),保留原 `available`。Web 可选能力要求发行包存在且模块可导入;卸载后缓存模块或 spawn 继承的 editable 源码路径不能让缺包显示可用。已安装加载失败引导修复,不误报未安装,异常文本不回显。
89
89
  - AI 可用性还需无调用检查当前 Web 所需的 AIConfig 字段、call_llm(stage=...) 与共享 runtime 工厂;旧包可导入不等于接口兼容。Web ai extra 和受管安装目标要求 `sqlseed-ai>=0.2.4.dev0`,不可回退安装缺少工作台接口的 0.2.3。维护进程只读取 metadata,不导入正在变更的包。
90
90
  - 缺失/异常 AI 仍返回脱敏 `effective` 普通设置,但禁止检测、保存、eligibility 和 suggest;错误带 `component_id=ai`、`recovery_action=install/repair`。`/api/meta/providers` 保留 available 数组并增加 statuses 事实对象。选中缺失 Mimesis 的配置允许保存,check/preview/执行复核返回 `provider_not_installed` 或 `provider_import_error`,不能静默换引擎。
91
+ - `settings_updates.py` 只在显式请求时查询固定组件的 PyPI Simple JSON API,稳定版本用 packaging.version 比较;版本查询自身不升级,不接收任意包或源,不把环境路径/AI 信息发往 PyPI。实际更新须另走组件计划与确认。失败有界、脱敏且可重试;更新提示不能当作兼容性承诺。
92
+ - 只读版本查询包含 DNS 与响应头的总等待预算;每个固定组件最多一个实际网络任务。观察者较短的等待预算不能废弃仍在自身预算内的共享任务;超时任务实际退出前继续占槽,迟到结果不得写缓存,完成异常必须释放其自身槽位而不能删除后来的任务。
91
93
 
92
- ## 只读当前数据
94
+ ## 历史 AI API 兼容
93
95
 
94
- - `workbench_data.py` 提供有界 GET 分页(limit 1–100、offset 非负)和运行目标的已注册连接匹配。读取先领取 connection_operation;run_id 存在时检查 target_key 与运行表范围,不能借活动连接读取另一目标。匹配连接列表不连接或反射数据库。
95
- - 当前数据使用实际目录白名单、标识符引用、参数化分页和完整主键排序;空表保留列信息。BLOB、Decimal、超出 JavaScript 安全范围的整数及非有限浮点数保留可读值,driver 异常脱敏。接口不记录本次新增主键,也不提供写操作。
96
+ - `/heal/validate`、`/heal/repair`、`/heal/auto` 分别委托 Layer 2、3、5;保持修复算法在 AI 包,不搬入 Web。
97
+ - auto-heal 复用 `sqlseed_ai.runtime` 的 `build_ai_config()`、`build_llm_client()`、`build_heal_orchestrator()`;不导入 CLI 私有工厂。共享服务使用普通 Python 异常,CLI/Web 入口各自转换错误,修改签名时一并检查调用者与资源释放。
98
+ - 有效 AI 配置从 env 合并会话 override,再由单次 auto-heal 请求覆盖;空 override 值回退到 env。metadata 与 `/api/ai/config` 的状态应一致。
99
+ - `/api/ai/test-connection` 探测 `resolve_base_url().rstrip('/') + '/models'`;本地 Ollama/LM Studio 只要求服务可达,不要求用户填写 API key。
100
+ - `AI_BACKENDS` 给出基础展示顺序,heal 页面会把有效 backend 提到首位;两个地方共同决定用户看到的顺序。
101
+ - auto-heal 产出 YAML,不执行数据填充;`_CountingLLMClient` 记录真实 LLM 调用次数,确定性流程可能为 0,不能把“完成”描述成必然调用过 LLM。
96
102
 
97
103
  ## 可选组件自动管理
98
104
 
99
105
  - `supervisor.py` 在默认启动时持有监听 socket 与管理状态,`managed_worker.py` 分别启动业务/维护 worker,`worker_control.py` 以有界匿名 IPC 传递控制与临时会话。保留原 NDJSON,不代理 HTTP。旧 `--manage-plugins` 仅兼容入口;普通网页无需命令切换或手动重启。
100
106
  - 维护 worker 业务 `/api/` 一律拒绝,仅保留 health、environment 与 `/api/settings/plugins/*`;HTML 固定标识用于首次导航,API 门禁不能依赖前端,受管维护标识不得永久锁定恢复后的导航。
101
107
  - `plugin_environment.py` 只接受当前解释器与可写独立 virtualenv,解析真实 distribution metadata/Requires-Dist;不使用 import 缓存判断新安装状态。系统/只读/共享系统包/环境外 metadata 不可管理,但保留普通 Web。
102
- - `plugin_management.py` 白名单仅 ai/cli/mcp/mimesis。管理请求检查 loopback client/Host;POST 必须同 Origin 及 token。计划绑定五分钟内 metadata 快照,一次领取。Core/Web/Faker/Base 不接受操作,不自动卸载依赖。`supervised_plugins.py` 仅在新业务就绪后发布任务终态,恢复失败保留页面与只恢复服务的重试入口。
103
- - 默认 supervisor 持有独占环境锁;子进程保留同一 flock 描述符,父 IPC 断开后关闭准入、自然排空工作再退出。外部正常 app 持共享锁,旧维护 app 持独占锁。锁不是外部 pip/Python 进程的强制协调器,不能声称阻止旧版本或任意外部进程。
108
+ - `plugin_management.py` 白名单仅 ai/cli/mcp/mimesis。管理请求检查 loopback client/Host;POST 必须同 Origin 及 token。计划绑定五分钟内 metadata 快照,一次领取。新计划可在同一受锁解释器且权限仍满足时重新绑定合法安装器;计划到执行及更新下载后的环境变化仍须拒绝,不能将短时安装器探测结果固定为进程生命周期身份。Core/Web/Faker/Base 不接受操作,不自动卸载依赖。`supervised_plugins.py` 仅在新业务就绪后发布任务终态,恢复失败保留页面与只恢复服务的重试入口。
109
+ - `plugin_updates.py` 仅对已安装的白名单可选组件准备定向更新,拒绝降级和联动变更其他包。候选 wheel 须匹配解释器 tags、Requires-Python 与 AI 最低兼容版本;固定 PyPI 索引和 `files.pythonhosted.org/packages/` 下载地址,不接受重定向、任意源或本地文件输入。校验 wheel SHA-256 及索引声明的 sidecar metadata 哈希,再将包内 metadata 与计划保存的哈希比较;下载内容和元数据均有大小上限。
110
+ - 更新前按完整环境检查正向、反向及显式 extras 依赖;缺失、不满足或不可验证的直接 URL 依赖阻止更新,提示使用原环境工具协调处理,不能自动补装依赖。执行前、下载后复核 metadata 快照;安装使用当前解释器、已校验本地 wheel、`--no-deps --no-index` 与冻结其他包的约束。完成后核对目标版本、包集合及其他包 metadata 不变;失败不宣称自动回滚已安装包。
111
+ - 索引/metadata 计划和 wheel 下载使用有界等待及单槽网络任务。等待超时不代表底层读线程已经结束;该线程退出前不能释放槽位,迟到结果不得创建计划、写临时文件或启动安装。网络失败统一脱敏为可恢复错误,不能扩大 supervisor IPC 等待掩盖无界网络工作。
112
+ - 默认 supervisor 持有独占环境锁;POSIX 子进程保留同一 flock 描述符,Windows 复制同一内核文件对象,父 IPC 断开后关闭准入、自然排空工作再退出。外部正常 app 持共享锁,旧维护 app 持独占锁。锁不是外部 pip/Python 进程的强制协调器,不能声称阻止旧版本或任意外部进程。
104
113
  - `runtime_lifecycle.py` 对所有非管理 HTTP 和真实后台线程计数;原子空闲检查失败返回 409,不强杀生成/AI 线程。`runtime_session.py` 只经内存和 IPC 保存原连接身份、凭据、provider/locale 与完整 AI 覆盖;成功后清除原始快照。内存 SQLite 阻止操作,部分恢复失败单独报告且不创建缺失数据库。
105
114
  - `plugin_process.py` 使用受控 argv、固定环境、冻结版本 constraints、wheel-only、超时与有界脱敏输出;不得引入任意命令、路径、package spec 或 pip 私有 API。测试真实 pip/uv 只能操作临时 virtualenv 与离线测试 wheel,不得修改当前用户环境。
106
- - 首版维护包变更仅支持 macOS/Linux;Windows 保留普通 Web 与 PowerShell 手动命令,不能在未实现子进程树超时回收前开放界面操作。
115
+ - 安装器已确认退出后,临时文件清理失败也必须发布明确失败终态,保留安装返回码和实际环境变化;不得自动重装。此类文件清理失败与 `InstallerCleanupPending` 不同:后者仍持有进程资源及环境锁,不能提前恢复业务或允许第二次安装。
116
+ - Windows、macOS/Linux 的受管独立环境支持组件包变更。Windows 环境锁使用不共享删除的文件句柄,经 spawn 复制同一文件对象;安装器先加入禁止脱离的 Job Object,确认所有后代退出后才释放锁并恢复业务。不确定的清理失败必须保留维护状态及锁;重试恢复不重复安装。Windows 业务 worker 使用 SelectorEventLoop 接管继承监听 socket。手动命令仍提示激活并核对 Web 的 Python 环境;CMD 不显示含 `%`/`!` 的路径。
117
+
118
+ ## 验证
119
+
120
+ 从仓库根运行 `pytest plugins/sqlseed-web/tests/ -q`;模块导航与隔离规则见 [测试指南](../../tests/AGENTS.md)。并发、schema 约束和配置往返使用真实 SQLite;外部 HTTP/模型边界可替换。修改身份与管理生命周期时保留失败释放、错误脱敏和重启恢复回归。
@@ -14,7 +14,12 @@ static frontend. It serves two purposes:
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- __version__ = "0.1.0"
17
+ from importlib.metadata import PackageNotFoundError, version
18
+
19
+ try:
20
+ __version__ = version("sqlseed-web")
21
+ except PackageNotFoundError:
22
+ __version__ = "0+unknown"
18
23
 
19
24
 
20
25
  def main() -> None: