OperonDBS 0.8.2__tar.gz → 0.8.3__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 (313) hide show
  1. {operondbs-0.8.2 → operondbs-0.8.3}/.github/workflows/publish.yml +3 -1
  2. {operondbs-0.8.2 → operondbs-0.8.3}/.github/workflows/test.yml +3 -1
  3. {operondbs-0.8.2 → operondbs-0.8.3}/.gitignore +1 -1
  4. {operondbs-0.8.2 → operondbs-0.8.3}/AGENTS.md +60 -14
  5. {operondbs-0.8.2 → operondbs-0.8.3}/MANIFEST.in +3 -2
  6. {operondbs-0.8.2 → operondbs-0.8.3}/OperonDBS.egg-info/PKG-INFO +5 -4
  7. {operondbs-0.8.2 → operondbs-0.8.3}/OperonDBS.egg-info/SOURCES.txt +20 -6
  8. {operondbs-0.8.2 → operondbs-0.8.3}/PKG-INFO +5 -4
  9. {operondbs-0.8.2 → operondbs-0.8.3}/README.md +4 -3
  10. {operondbs-0.8.2 → operondbs-0.8.3}/README_ZH.md +4 -3
  11. operondbs-0.8.3/docs/conf_common.py +218 -0
  12. operondbs-0.8.3/docs/en/.readthedocs.yaml +29 -0
  13. operondbs-0.8.3/docs/en/conf.py +24 -0
  14. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/contributor/development-testing.md +69 -1
  15. operondbs-0.8.3/docs/en/contributor/documentation-deployment.md +57 -0
  16. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/qc-profiles.md +2 -0
  17. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/behaviors-and-limitations.md +9 -5
  18. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-tui.md +66 -16
  19. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/resolved-issues.md +6 -0
  20. operondbs-0.8.3/docs/locales/README.md +34 -0
  21. operondbs-0.8.3/docs/zh/.readthedocs.yaml +28 -0
  22. operondbs-0.8.3/docs/zh/conf.py +23 -0
  23. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/contributor/development-testing.md +54 -1
  24. operondbs-0.8.3/docs/zh/contributor/documentation-deployment.md +57 -0
  25. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/qc-profiles.md +5 -0
  26. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/behaviors-and-limitations.md +9 -5
  27. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-tui.md +59 -15
  28. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/resolved-issues.md +6 -0
  29. {operondbs-0.8.2 → operondbs-0.8.3}/operon/adapters/ncbi_datasets.py +3 -2
  30. {operondbs-0.8.2 → operondbs-0.8.3}/operon/adapters/timetree.py +4 -3
  31. {operondbs-0.8.2 → operondbs-0.8.3}/operon/cli.py +20 -24
  32. {operondbs-0.8.2 → operondbs-0.8.3}/operon/config.py +2 -2
  33. {operondbs-0.8.2 → operondbs-0.8.3}/operon/coverage.py +3 -2
  34. {operondbs-0.8.2 → operondbs-0.8.3}/operon/database.py +2 -1
  35. {operondbs-0.8.2 → operondbs-0.8.3}/operon/demo.py +4 -7
  36. {operondbs-0.8.2 → operondbs-0.8.3}/operon/environment_capture.py +1 -3
  37. {operondbs-0.8.2 → operondbs-0.8.3}/operon/execution.py +53 -19
  38. {operondbs-0.8.2 → operondbs-0.8.3}/operon/export.py +3 -2
  39. {operondbs-0.8.2 → operondbs-0.8.3}/operon/fanout.py +1 -1
  40. {operondbs-0.8.2 → operondbs-0.8.3}/operon/files.py +50 -4
  41. {operondbs-0.8.2 → operondbs-0.8.3}/operon/import_wizard.py +9 -2
  42. {operondbs-0.8.2 → operondbs-0.8.3}/operon/lifecycle.py +2 -1
  43. {operondbs-0.8.2 → operondbs-0.8.3}/operon/lineage.py +7 -1
  44. {operondbs-0.8.2 → operondbs-0.8.3}/operon/qc/__init__.py +15 -15
  45. {operondbs-0.8.2 → operondbs-0.8.3}/operon/qc/alignment.py +3 -2
  46. {operondbs-0.8.2 → operondbs-0.8.3}/operon/qc/measure.py +7 -7
  47. {operondbs-0.8.2 → operondbs-0.8.3}/operon/qc/parsers.py +2 -1
  48. {operondbs-0.8.2 → operondbs-0.8.3}/operon/remotes.py +16 -10
  49. {operondbs-0.8.2 → operondbs-0.8.3}/operon/reports.py +47 -0
  50. {operondbs-0.8.2 → operondbs-0.8.3}/operon/schema.py +3 -2
  51. {operondbs-0.8.2 → operondbs-0.8.3}/operon/sequence_tools.py +3 -2
  52. {operondbs-0.8.2 → operondbs-0.8.3}/operon/shutdown.py +18 -2
  53. {operondbs-0.8.2 → operondbs-0.8.3}/operon/taxonomy.py +2 -1
  54. {operondbs-0.8.2 → operondbs-0.8.3}/operon/timetree.py +36 -14
  55. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tools.py +133 -30
  56. operondbs-0.8.3/operon/tui/actions.py +1225 -0
  57. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/app.py +9 -1
  58. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/app.tcss +179 -1
  59. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/data.py +298 -19
  60. operondbs-0.8.3/operon/tui/parity.py +716 -0
  61. operondbs-0.8.3/operon/tui/screens/analyze.py +435 -0
  62. operondbs-0.8.3/operon/tui/screens/classify.py +102 -0
  63. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/common.py +265 -19
  64. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/config.py +503 -49
  65. operondbs-0.8.3/operon/tui/screens/config_classification.py +666 -0
  66. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/coverage.py +3 -6
  67. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/decisions.py +2 -3
  68. operondbs-0.8.3/operon/tui/screens/derived_ops.py +593 -0
  69. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/entities.py +4 -11
  70. operondbs-0.8.3/operon/tui/screens/environments.py +117 -0
  71. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/files.py +90 -5
  72. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/files_ops.py +4 -11
  73. operondbs-0.8.3/operon/tui/screens/hits.py +180 -0
  74. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/home.py +1 -1
  75. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/import_wizard.py +9 -18
  76. operondbs-0.8.3/operon/tui/screens/labels.py +103 -0
  77. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/publish.py +4 -11
  78. operondbs-0.8.3/operon/tui/screens/run_external.py +236 -0
  79. operondbs-0.8.3/operon/tui/screens/runs.py +633 -0
  80. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/splash.py +7 -3
  81. {operondbs-0.8.2 → operondbs-0.8.3}/operon/utils.py +3 -2
  82. {operondbs-0.8.2 → operondbs-0.8.3}/operon/workflow.py +3 -2
  83. {operondbs-0.8.2 → operondbs-0.8.3}/pyproject.toml +1 -1
  84. {operondbs-0.8.2 → operondbs-0.8.3}/tests/compatibility/test_python_support.py +0 -1
  85. {operondbs-0.8.2 → operondbs-0.8.3}/tests/helpers.py +30 -3
  86. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_analysis_array.py +217 -2
  87. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_analysis_resume.py +1 -2
  88. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_analysis_shutdown.py +38 -9
  89. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_analysis_tools.py +6 -7
  90. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_classify_sequences.py +1 -2
  91. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_execution_backends.py +1 -3
  92. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_fanout_analyze.py +1 -2
  93. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_lineage_cascade.py +1 -2
  94. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_ncbi_datasets_adapter.py +30 -36
  95. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_pipeline_and_release.py +1 -3
  96. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_python_packaging.py +17 -6
  97. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_qc_remote_measure.py +1 -2
  98. {operondbs-0.8.2 → operondbs-0.8.3}/tests/regression/test_correctness.py +1 -2
  99. {operondbs-0.8.2 → operondbs-0.8.3}/tests/regression/test_cython_alignment_parity.py +1 -1
  100. {operondbs-0.8.2 → operondbs-0.8.3}/tests/regression/test_cython_parser_parity.py +1 -2
  101. {operondbs-0.8.2 → operondbs-0.8.3}/tests/regression/test_parser_semantics.py +1 -2
  102. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_alignment_qc.py +4 -5
  103. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_classify.py +1 -2
  104. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_core_coverage_more.py +3 -4
  105. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_defects_cli.py +0 -1
  106. operondbs-0.8.3/tests/unit/test_docs_projects.py +188 -0
  107. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_docs_versions.py +1 -1
  108. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_environment.py +1 -2
  109. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_environment_capture.py +10 -7
  110. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_execution.py +152 -14
  111. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_execution_edges.py +2 -2
  112. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_fanout.py +6 -1
  113. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_files_edges.py +95 -1
  114. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_import_backup_show.py +0 -1
  115. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_lifecycle.py +4 -1
  116. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_misc_coverage_more.py +19 -6
  117. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_ncbi_coverage_gaps.py +6 -5
  118. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_parser_edge_paths.py +0 -1
  119. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_qc_and_rules.py +3 -4
  120. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_qc_edges_more.py +2 -3
  121. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_qc_measure.py +1 -2
  122. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_qc_remote_only.py +1 -2
  123. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_remote_taxonomy_more.py +7 -6
  124. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_remote_transport_edges.py +1 -1
  125. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_remotes.py +4 -5
  126. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_remotes_edges.py +10 -11
  127. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_schema_2_10.py +1 -2
  128. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_schema_2_11.py +1 -2
  129. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_schema_2_9.py +1 -2
  130. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_schema_and_metadata.py +1 -2
  131. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_sequence_tools.py +1 -4
  132. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_sequences.py +1 -2
  133. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_shutdown.py +42 -7
  134. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_support_edges.py +0 -1
  135. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_timetree_snapshots.py +70 -0
  136. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tools_edges.py +28 -0
  137. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tools_execution_more.py +0 -1
  138. operondbs-0.8.3/tests/unit/test_tui.py +2250 -0
  139. operondbs-0.8.3/tests/unit/test_tui_analyze.py +952 -0
  140. operondbs-0.8.3/tests/unit/test_tui_cli_parity.py +1233 -0
  141. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tui_config.py +764 -15
  142. operondbs-0.8.3/tests/unit/test_tui_derived_ops.py +703 -0
  143. operondbs-0.8.3/tests/unit/test_tui_m3_loop.py +273 -0
  144. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tui_publish.py +10 -1
  145. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tui_screens_more.py +5 -4
  146. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tui_splash_terminal.py +8 -1
  147. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tui_writes.py +244 -0
  148. operondbs-0.8.2/.readthedocs.yaml +0 -15
  149. operondbs-0.8.2/docs/_static/language-switcher.js +0 -20
  150. operondbs-0.8.2/docs/_static/operon.css +0 -32
  151. operondbs-0.8.2/docs/_templates/layout.html +0 -10
  152. operondbs-0.8.2/docs/conf.py +0 -129
  153. operondbs-0.8.2/docs/en/contributor/documentation-deployment.md +0 -36
  154. operondbs-0.8.2/docs/index.md +0 -18
  155. operondbs-0.8.2/docs/zh/contributor/documentation-deployment.md +0 -36
  156. operondbs-0.8.2/operon/tui/actions.py +0 -642
  157. operondbs-0.8.2/operon/tui/screens/runs.py +0 -217
  158. operondbs-0.8.2/tests/unit/test_tui.py +0 -1068
  159. {operondbs-0.8.2 → operondbs-0.8.3}/LICENSE +0 -0
  160. {operondbs-0.8.2 → operondbs-0.8.3}/OperonDBS.egg-info/dependency_links.txt +0 -0
  161. {operondbs-0.8.2 → operondbs-0.8.3}/OperonDBS.egg-info/entry_points.txt +0 -0
  162. {operondbs-0.8.2 → operondbs-0.8.3}/OperonDBS.egg-info/requires.txt +0 -0
  163. {operondbs-0.8.2 → operondbs-0.8.3}/OperonDBS.egg-info/top_level.txt +0 -0
  164. {operondbs-0.8.2 → operondbs-0.8.3}/benchmarks/qc_representative_entities.tsv +0 -0
  165. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/extensibility.md +0 -0
  166. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/external-analysis.md +0 -0
  167. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/files-and-storage.md +0 -0
  168. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/index.md +0 -0
  169. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/metadata-and-data-model.md +0 -0
  170. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/overview.md +0 -0
  171. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/qc-and-rules.md +0 -0
  172. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/release-lifecycle.md +0 -0
  173. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/architecture/taxonomy-coverage.md +0 -0
  174. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/contributor/defect-tracking.md +0 -0
  175. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/contributor/index.md +0 -0
  176. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/contributor/pypi-release.md +0 -0
  177. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/contributor/repository-guide.md +0 -0
  178. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/getting-started/daily-workflow.md +0 -0
  179. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/getting-started/first-project.md +0 -0
  180. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/getting-started/index.md +0 -0
  181. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/getting-started/installation.md +0 -0
  182. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/getting-started/quickstart.md +0 -0
  183. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/backup-migration.md +0 -0
  184. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/curation-lifecycle.md +0 -0
  185. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/external-analysis.md +0 -0
  186. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/file-archiving.md +0 -0
  187. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/index.md +0 -0
  188. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/metadata-import.md +0 -0
  189. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/ncbi-datasets.md +0 -0
  190. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/phylogenetics-workflow.md +0 -0
  191. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/remote-execution.md +0 -0
  192. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/remote-first.md +0 -0
  193. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/remote-storage.md +0 -0
  194. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/taxonomy-coverage.md +0 -0
  195. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/guides/troubleshooting.md +0 -0
  196. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/index.md +0 -0
  197. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/operations/database-compatibility.md +0 -0
  198. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/operations/index.md +0 -0
  199. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/operations/ncbi-recovery-migration.md +0 -0
  200. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/operations/qc-performance.md +0 -0
  201. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/overview.md +0 -0
  202. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-analysis.md +0 -0
  203. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-decisions-reports.md +0 -0
  204. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-files-qc.md +0 -0
  205. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-project-metadata.md +0 -0
  206. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-remote.md +0 -0
  207. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-taxonomy-lifecycle-admin.md +0 -0
  208. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/cli-workflow.md +0 -0
  209. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/data-model.md +0 -0
  210. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/index.md +0 -0
  211. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/recipe-fields.md +0 -0
  212. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/recipe-overview.md +0 -0
  213. {operondbs-0.8.2 → operondbs-0.8.3}/docs/en/reference/recipe-parsers-examples.md +0 -0
  214. {operondbs-0.8.2 → operondbs-0.8.3}/docs/requirements.txt +0 -0
  215. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/extensibility.md +0 -0
  216. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/external-analysis.md +0 -0
  217. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/files-and-storage.md +0 -0
  218. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/index.md +0 -0
  219. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/metadata-and-data-model.md +0 -0
  220. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/overview.md +0 -0
  221. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/qc-and-rules.md +0 -0
  222. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/release-lifecycle.md +0 -0
  223. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/architecture/taxonomy-coverage.md +0 -0
  224. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/contributor/defect-tracking.md +0 -0
  225. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/contributor/index.md +0 -0
  226. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/contributor/pypi-release.md +0 -0
  227. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/contributor/repository-guide.md +0 -0
  228. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/getting-started/daily-workflow.md +0 -0
  229. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/getting-started/first-project.md +0 -0
  230. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/getting-started/index.md +0 -0
  231. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/getting-started/installation.md +0 -0
  232. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/getting-started/quickstart.md +0 -0
  233. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/backup-migration.md +0 -0
  234. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/curation-lifecycle.md +0 -0
  235. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/external-analysis.md +0 -0
  236. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/file-archiving.md +0 -0
  237. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/index.md +0 -0
  238. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/metadata-import.md +0 -0
  239. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/ncbi-datasets.md +0 -0
  240. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/phylogenetics-workflow.md +0 -0
  241. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/remote-execution.md +0 -0
  242. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/remote-first.md +0 -0
  243. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/remote-storage.md +0 -0
  244. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/taxonomy-coverage.md +0 -0
  245. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/guides/troubleshooting.md +0 -0
  246. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/index.md +0 -0
  247. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/operations/database-compatibility.md +0 -0
  248. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/operations/index.md +0 -0
  249. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/operations/ncbi-recovery-migration.md +0 -0
  250. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/operations/qc-performance.md +0 -0
  251. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/overview.md +0 -0
  252. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-analysis.md +0 -0
  253. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-decisions-reports.md +0 -0
  254. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-files-qc.md +0 -0
  255. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-project-metadata.md +0 -0
  256. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-remote.md +0 -0
  257. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-taxonomy-lifecycle-admin.md +0 -0
  258. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/cli-workflow.md +0 -0
  259. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/data-model.md +0 -0
  260. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/index.md +0 -0
  261. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/recipe-fields.md +0 -0
  262. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/recipe-overview.md +0 -0
  263. {operondbs-0.8.2 → operondbs-0.8.3}/docs/zh/reference/recipe-parsers-examples.md +0 -0
  264. {operondbs-0.8.2 → operondbs-0.8.3}/operon/__init__.py +0 -0
  265. {operondbs-0.8.2 → operondbs-0.8.3}/operon/__main__.py +0 -0
  266. {operondbs-0.8.2 → operondbs-0.8.3}/operon/adapters/__init__.py +0 -0
  267. {operondbs-0.8.2 → operondbs-0.8.3}/operon/backup.py +0 -0
  268. {operondbs-0.8.2 → operondbs-0.8.3}/operon/classify.py +0 -0
  269. {operondbs-0.8.2 → operondbs-0.8.3}/operon/entity_view.py +0 -0
  270. {operondbs-0.8.2 → operondbs-0.8.3}/operon/environment.py +0 -0
  271. {operondbs-0.8.2 → operondbs-0.8.3}/operon/errors.py +0 -0
  272. {operondbs-0.8.2 → operondbs-0.8.3}/operon/metadata_files.py +0 -0
  273. {operondbs-0.8.2 → operondbs-0.8.3}/operon/ncbi_reconcile.py +0 -0
  274. {operondbs-0.8.2 → operondbs-0.8.3}/operon/profiles.py +0 -0
  275. {operondbs-0.8.2 → operondbs-0.8.3}/operon/qc/_alignment.pyx +0 -0
  276. {operondbs-0.8.2 → operondbs-0.8.3}/operon/qc/_parsers.pyx +0 -0
  277. {operondbs-0.8.2 → operondbs-0.8.3}/operon/release.py +0 -0
  278. {operondbs-0.8.2 → operondbs-0.8.3}/operon/rules.py +0 -0
  279. {operondbs-0.8.2 → operondbs-0.8.3}/operon/sql.py +0 -0
  280. {operondbs-0.8.2 → operondbs-0.8.3}/operon/table_import.py +0 -0
  281. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/__init__.py +0 -0
  282. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/assets/splash.png +0 -0
  283. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/assets/splash.rgb.z +0 -0
  284. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/screens/__init__.py +0 -0
  285. {operondbs-0.8.2 → operondbs-0.8.3}/operon/tui/splash_terminal.py +0 -0
  286. {operondbs-0.8.2 → operondbs-0.8.3}/setup.cfg +0 -0
  287. {operondbs-0.8.2 → operondbs-0.8.3}/setup.py +0 -0
  288. {operondbs-0.8.2 → operondbs-0.8.3}/tests/__init__.py +0 -0
  289. {operondbs-0.8.2 → operondbs-0.8.3}/tests/compatibility/__init__.py +0 -0
  290. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/__init__.py +0 -0
  291. {operondbs-0.8.2 → operondbs-0.8.3}/tests/integration/test_taxonomy_coverage.py +1 -1
  292. {operondbs-0.8.2 → operondbs-0.8.3}/tests/regression/__init__.py +0 -0
  293. {operondbs-0.8.2 → operondbs-0.8.3}/tests/regression/test_sql_identifier_security.py +0 -0
  294. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/__init__.py +0 -0
  295. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_cli_edges.py +0 -0
  296. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_config_workflow_edges.py +0 -0
  297. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_coverage_edges.py +0 -0
  298. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_database_edges_more.py +0 -0
  299. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_defect_registry.py +0 -0
  300. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_export.py +0 -0
  301. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_follow.py +0 -0
  302. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_import_wizard_edges.py +1 -1
  303. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_lineage.py +1 -1
  304. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_ncbi_edge_cases.py +1 -1
  305. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_ncbi_reconcile_edges.py +0 -0
  306. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_recipe_history.py +0 -0
  307. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_rules_schema_edges.py +0 -0
  308. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_table_import_edges.py +0 -0
  309. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_taxonomy_edges.py +0 -0
  310. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_timetree.py +0 -0
  311. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_tui_flows_more.py +0 -0
  312. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_views_release_reports_edges.py +0 -0
  313. {operondbs-0.8.2 → operondbs-0.8.3}/tests/unit/test_workflow_cli.py +0 -0
@@ -43,7 +43,9 @@ jobs:
43
43
  python-version: "3.12"
44
44
  - run: python -m pip install --upgrade pip
45
45
  - run: python -m pip install -e '.[docs]'
46
- - run: sphinx-build -W --keep-going -b html docs docs/_build/html
46
+ - run: |
47
+ sphinx-build -W --keep-going -b html docs/en docs/_build/en/html
48
+ sphinx-build -W --keep-going -b html docs/zh docs/_build/zh/html
47
49
 
48
50
  wheels:
49
51
  strategy:
@@ -25,7 +25,9 @@ jobs:
25
25
  cache-dependency-path: pyproject.toml
26
26
  - run: python -m pip install --upgrade pip
27
27
  - run: python -m pip install -e '.[docs]'
28
- - run: sphinx-build -W --keep-going -b html docs docs/_build/html
28
+ - run: |
29
+ sphinx-build -W --keep-going -b html docs/en docs/_build/en/html
30
+ sphinx-build -W --keep-going -b html docs/zh docs/_build/zh/html
29
31
 
30
32
  pytest:
31
33
  strategy:
@@ -29,6 +29,6 @@ htmlcov/
29
29
  /site/
30
30
  /docs/_build/
31
31
  /workflows/
32
- /HPC/
32
+ /others/
33
33
  .matrix/
34
34
  cobertura.xml
@@ -26,7 +26,7 @@ principle-to-implementation mapping.
26
26
 
27
27
  Current version markers (must stay consistent across code and docs):
28
28
 
29
- - `operon` 0.8.2 (`pyproject.toml`)
29
+ - `operon` 0.8.3 (`pyproject.toml`)
30
30
  - database schema 2.11 (`operon/database.py`, `SCHEMA_VERSION`)
31
31
  - metadata schema 1.4 (`operon/schema.py`, `METADATA_SCHEMA_VERSION`)
32
32
 
@@ -83,17 +83,48 @@ The project is licensed AGPL-3.0-or-later (`LICENSE` at the repo root).
83
83
  Confirm → background worker → notify + reload or inline error. Phase 3
84
84
  actions in the same module: `import_dataset` (commits wizard drafts
85
85
  through the shared single-transaction `import_wizard._commit`),
86
- `reserve_entity_ids`, `create_release`, `export`, and `run_coverage`
86
+ `reserve_entity_ids`, `create_release`, `export`, `run_coverage`
87
87
  (a below-threshold coverage report returns `exit_code=1` in the result
88
- dict — a warning, not an exception). The
88
+ dict — a warning, not an exception), `preflight_backend`, `run_analysis`
89
+ (backing the AnalyzeModal launched from the Config screen's Run analysis
90
+ button or the Tasks screen's New analysis button; the modal mirrors
91
+ `--backend` — project default / local / slurm / ssh — and preflights the
92
+ selection inline, and cancellation sets the core's cooperative
93
+ `cancel_event`, so a queued Slurm job or array is cancelled with one
94
+ `scancel`), `run_external` (backing the Tasks screen's Run external
95
+ dialog, which mirrors `run-external` field by field and opens the run
96
+ record when it finishes) and `write_analysis_report` (backing the
97
+ Analysis hits browser's Export button: it runs the same read-only query
98
+ and the same renderer as `report analysis --hits --format … --out …`, so
99
+ the file is byte-identical and, like that command, writes no provenance
100
+ rows). Phase 3 also covers the
101
+ derived-artifact loop: `run_classify` (the Config screen's Run classify
102
+ dialog, mirroring `classify-sequences` with the CLI's summary and a re-run
103
+ button), and — on the Files screen — `extract_domains`, `select_sequences`,
104
+ `adopt` and `fanout` (modals in `operon/tui/screens/derived_ops.py`:
105
+ extract/select chain into the adopt dialog with `derived_from` prefilled and
106
+ leave their output unregistered, adopt's manifest mode previews before
107
+ Confirm, and fanout's dry run is a mandatory preflight). Read-only TUI views added for `report analysis --hits` (alignment
108
+ hits with the CLI's filters and columns) and for `sequence_labels` (the
109
+ classify-sequences output: a per-file section in the Files detail plus
110
+ the project-wide label summary behind the Files screen's `l` binding), which
111
+ has no CLI reader at all. The
89
112
  Config screen (`operon/tui/screens/config.py`, nav key `6`) edits
90
- `config/profiles/*.yaml` (kind `qc`) and single recipes inside
113
+ `config/profiles/*.yaml` (kind `qc` and kind `sequence_classification` —
114
+ each kind has its own form, dispatched by the document's own kind, with the
115
+ classification widgets in `operon/tui/screens/config_classification.py`
116
+ and `actions.save_classification_profile` sharing `save_profile`'s version,
117
+ snapshot and rollback machinery; a profile whose conditions nest deeper
118
+ than one `any:`/`not:` level opens read-only) and single recipes inside
91
119
  `config/tools.yaml` through structured control-based forms (no free-text
92
120
  YAML): every save bumps the `version`, records the same content-addressed
93
121
  snapshot the CLI records (`qc_profiles` / `recipe_snapshots`), and
94
122
  restores the previous file bytes on failure; keys the forms do not model
95
123
  are preserved verbatim; history modals restore snapshots into the editor
96
124
  as the next version; tools-check runs in a worker with per-row updates.
125
+ `operon/tui/parity.py` is the CLI/TUI parity registry: every CLI leaf
126
+ command is registered `implemented`/`cli-only`/`planned`, enforced by
127
+ `tests/unit/test_tui_cli_parity.py` (see Conventions).
97
128
  Textual is imported only inside this package, which the `tui` command
98
129
  handler imports lazily.
99
130
  - Other top-level modules by responsibility: `database.py` (SQLite schema
@@ -127,8 +158,16 @@ The project is licensed AGPL-3.0-or-later (`LICENSE` at the repo root).
127
158
  - `docs/` — Sphinx documentation in two mirrored language trees, `docs/en/`
128
159
  and `docs/zh/`, each split into `overview.md`, `getting-started/`,
129
160
  `guides/`, `architecture/`, `reference/`, `operations/`, and
130
- `contributor/`. Built with `docs/conf.py`; published via Read the Docs
131
- (`.readthedocs.yaml`).
161
+ `contributor/`. Each tree is a Sphinx project of its own
162
+ (`docs/<language>/conf.py`, sharing settings from `docs/conf_common.py`) and
163
+ a Read the Docs project of its own, linked there as parent and translation:
164
+ `operonproject` (English) and `operonproject-zh` (Chinese). Read the Docs
165
+ accepts no build-configuration file name other than `.readthedocs.yaml`, so
166
+ each tree carries one next to its `conf.py`
167
+ (`docs/<language>/.readthedocs.yaml`) and the dashboard points the project at
168
+ that path. `docs/locales/` is the catalog directory
169
+ for a future gettext-maintained language; `tests/unit/test_docs_projects.py`
170
+ guards the layout.
132
171
  - `benchmarks/` — representative entity sets for QC performance diagnostics
133
172
  (see `docs/*/operations/qc-performance.md`).
134
173
  - `scripts/` — local developer tooling; `setup-test-matrix.sh` and
@@ -158,7 +197,8 @@ scripts/run-test-matrix.sh # whole suite on 3.10-3.15 concurrently
158
197
 
159
198
  python setup.py build_ext --inplace # rebuild only the Cython extension
160
199
 
161
- sphinx-build -W --keep-going -b html docs docs/_build/html # strict docs build
200
+ sphinx-build -W --keep-going -b html docs/en docs/_build/en/html # strict build,
201
+ sphinx-build -W --keep-going -b html docs/zh docs/_build/zh/html # one per language
162
202
  ```
163
203
 
164
204
  Run the relevant test category after any change; run the full suite before
@@ -216,15 +256,18 @@ proceed with caution).
216
256
  bytes must raise `ConflictError`; identical bytes must be idempotent.
217
257
  - Manual overrides (e.g. `curate`, forced `set-state`) must always be
218
258
  recorded in the `changes` audit table.
259
+ - CLI-first: new capabilities land in the CLI/core first, and the TUI never
260
+ runs ahead of the CLI. Any change to CLI commands, flags, or the TUI
261
+ surface must update the parity registry `operon/tui/parity.py` in the same
262
+ commit — the parity tests in `tests/unit/test_tui_cli_parity.py` fail
263
+ otherwise. Commands intentionally not offered in the TUI are registered
264
+ `cli-only` with a reason; known gaps are registered `planned` with a
265
+ milestone.
219
266
  - `docs/*/operations/database-compatibility.md` lists migration code that
220
267
  exists only for pre-1.0 databases and is scheduled for removal at the 1.0
221
268
  release; check it before touching `operon/database.py` migrations or the
222
269
  NCBI adapter's schema-upgrade path.
223
- - The `operon.qc` module uses CFFI (specifically, Cython), so static analysis
224
- tools, such as `flake8`, will report "undefined reference" errors (F821).
225
- Using `# noqa: F821` behind the line **ONLY** when importing `operon.qc`
226
- and an F821 error is likely to occur. Globally ignoring F821 is **STRICKLY
227
- PROHIBITED**.
270
+ - Using `ruff` to re-format the code.
228
271
 
229
272
  ## Defect reports
230
273
 
@@ -256,12 +299,15 @@ change:
256
299
  `docs/*/operations/`
257
300
  - Contributor-facing processes → `docs/*/contributor/`; navigation →
258
301
  `docs/*/index.md`
302
+ - The set of language projects → `docs/<language>/conf.py`, its
303
+ `docs/<language>/.readthedocs.yaml`, and the registry in
304
+ `tests/unit/test_docs_projects.py`
259
305
 
260
- Version markers in docs (`operon` 0.8.2, database schema 2.11, metadata
306
+ Version markers in docs (`operon` 0.8.3, database schema 2.11, metadata
261
307
  schema 1.4) must match `pyproject.toml` and the code. Do not write the
262
308
  current values literally in Markdown sources: use the `myst_substitutions`
263
309
  references `{{ operon_version }}`, `{{ db_schema }}`, and
264
- `{{ metadata_schema }}`, which `docs/conf.py` resolves from the single
310
+ `{{ metadata_schema }}`, which `docs/conf_common.py` resolves from the single
265
311
  sources above at build time. Substitutions expand in paragraph text only,
266
312
  never inside code spans or fenced code blocks — examples there use
267
313
  `<version>` placeholders instead. Intentional historical pins stay literal — either on the
@@ -4,12 +4,13 @@ include LICENSE
4
4
  include MANIFEST.in
5
5
  include README.md
6
6
  include README_ZH.md
7
- include .readthedocs.yaml
7
+ include docs/en/.readthedocs.yaml
8
+ include docs/zh/.readthedocs.yaml
8
9
  include pyproject.toml
9
10
  include setup.py
10
11
  recursive-include .github *.yml
11
12
  recursive-include benchmarks *.tsv
12
- recursive-include docs *.css *.html *.js *.md *.py *.txt
13
+ recursive-include docs *.css *.html *.js *.md *.po *.py *.txt
13
14
  prune docs/_build
14
15
  recursive-include operon *.py *.pyx *.tcss
15
16
  recursive-include operon/tui/assets *.png *.z *.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OperonDBS
3
- Version: 0.8.2
3
+ Version: 0.8.3
4
4
  Summary: Operon the Database System: Archive, Quality-Control, Organize, Analyze and Release Your Bio-Data
5
5
  Author-email: hyli360 <lihuanyu2003@gmail.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -93,11 +93,12 @@ python -m pip install -e '.[dev]'
93
93
 
94
94
  ## Documentation
95
95
 
96
- The complete documentation is maintained in [English](docs/en/index.md) and [Chinese](docs/zh/index.md). To build the Sphinx site locally:
96
+ The complete documentation is maintained in [English](docs/en/index.md) and [Chinese](docs/zh/index.md). Each language is its own Sphinx project; build both without warnings:
97
97
 
98
98
  ```bash
99
99
  python -m pip install -e '.[docs]'
100
- sphinx-build -W --keep-going -b html docs docs/_build/html
100
+ sphinx-build -W --keep-going -b html docs/en docs/_build/en/html
101
+ sphinx-build -W --keep-going -b html docs/zh docs/_build/zh/html
101
102
  ```
102
103
 
103
- Read the Docs uses the repository's `.readthedocs.yaml` configuration and publishes a language-selection page with mirrored `/en/` and `/zh/` documentation trees.
104
+ Read the Docs publishes two projects linked as parent and translation: `operonproject` (English, `https://operonproject.readthedocs.io/en/latest/`) and `operonproject-zh` (Chinese, `https://operonproject.readthedocs.io/zh-cn/latest/`), each built from its own `docs/<language>/.readthedocs.yaml`.
@@ -1,5 +1,4 @@
1
1
  .gitignore
2
- .readthedocs.yaml
3
2
  AGENTS.md
4
3
  LICENSE
5
4
  MANIFEST.in
@@ -16,12 +15,10 @@ OperonDBS.egg-info/entry_points.txt
16
15
  OperonDBS.egg-info/requires.txt
17
16
  OperonDBS.egg-info/top_level.txt
18
17
  benchmarks/qc_representative_entities.tsv
19
- docs/conf.py
20
- docs/index.md
18
+ docs/conf_common.py
21
19
  docs/requirements.txt
22
- docs/_static/language-switcher.js
23
- docs/_static/operon.css
24
- docs/_templates/layout.html
20
+ docs/en/.readthedocs.yaml
21
+ docs/en/conf.py
25
22
  docs/en/index.md
26
23
  docs/en/overview.md
27
24
  docs/en/architecture/extensibility.md
@@ -77,6 +74,9 @@ docs/en/reference/recipe-fields.md
77
74
  docs/en/reference/recipe-overview.md
78
75
  docs/en/reference/recipe-parsers-examples.md
79
76
  docs/en/reference/resolved-issues.md
77
+ docs/locales/README.md
78
+ docs/zh/.readthedocs.yaml
79
+ docs/zh/conf.py
80
80
  docs/zh/index.md
81
81
  docs/zh/overview.md
82
82
  docs/zh/architecture/extensibility.md
@@ -183,21 +183,30 @@ operon/tui/actions.py
183
183
  operon/tui/app.py
184
184
  operon/tui/app.tcss
185
185
  operon/tui/data.py
186
+ operon/tui/parity.py
186
187
  operon/tui/splash.py
187
188
  operon/tui/splash_terminal.py
188
189
  operon/tui/assets/splash.png
189
190
  operon/tui/assets/splash.rgb.z
190
191
  operon/tui/screens/__init__.py
192
+ operon/tui/screens/analyze.py
193
+ operon/tui/screens/classify.py
191
194
  operon/tui/screens/common.py
192
195
  operon/tui/screens/config.py
196
+ operon/tui/screens/config_classification.py
193
197
  operon/tui/screens/coverage.py
194
198
  operon/tui/screens/decisions.py
199
+ operon/tui/screens/derived_ops.py
195
200
  operon/tui/screens/entities.py
201
+ operon/tui/screens/environments.py
196
202
  operon/tui/screens/files.py
197
203
  operon/tui/screens/files_ops.py
204
+ operon/tui/screens/hits.py
198
205
  operon/tui/screens/home.py
199
206
  operon/tui/screens/import_wizard.py
207
+ operon/tui/screens/labels.py
200
208
  operon/tui/screens/publish.py
209
+ operon/tui/screens/run_external.py
201
210
  operon/tui/screens/runs.py
202
211
  tests/__init__.py
203
212
  tests/helpers.py
@@ -233,6 +242,7 @@ tests/unit/test_coverage_edges.py
233
242
  tests/unit/test_database_edges_more.py
234
243
  tests/unit/test_defect_registry.py
235
244
  tests/unit/test_defects_cli.py
245
+ tests/unit/test_docs_projects.py
236
246
  tests/unit/test_docs_versions.py
237
247
  tests/unit/test_environment.py
238
248
  tests/unit/test_environment_capture.py
@@ -276,8 +286,12 @@ tests/unit/test_timetree_snapshots.py
276
286
  tests/unit/test_tools_edges.py
277
287
  tests/unit/test_tools_execution_more.py
278
288
  tests/unit/test_tui.py
289
+ tests/unit/test_tui_analyze.py
290
+ tests/unit/test_tui_cli_parity.py
279
291
  tests/unit/test_tui_config.py
292
+ tests/unit/test_tui_derived_ops.py
280
293
  tests/unit/test_tui_flows_more.py
294
+ tests/unit/test_tui_m3_loop.py
281
295
  tests/unit/test_tui_publish.py
282
296
  tests/unit/test_tui_screens_more.py
283
297
  tests/unit/test_tui_splash_terminal.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OperonDBS
3
- Version: 0.8.2
3
+ Version: 0.8.3
4
4
  Summary: Operon the Database System: Archive, Quality-Control, Organize, Analyze and Release Your Bio-Data
5
5
  Author-email: hyli360 <lihuanyu2003@gmail.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -93,11 +93,12 @@ python -m pip install -e '.[dev]'
93
93
 
94
94
  ## Documentation
95
95
 
96
- The complete documentation is maintained in [English](docs/en/index.md) and [Chinese](docs/zh/index.md). To build the Sphinx site locally:
96
+ The complete documentation is maintained in [English](docs/en/index.md) and [Chinese](docs/zh/index.md). Each language is its own Sphinx project; build both without warnings:
97
97
 
98
98
  ```bash
99
99
  python -m pip install -e '.[docs]'
100
- sphinx-build -W --keep-going -b html docs docs/_build/html
100
+ sphinx-build -W --keep-going -b html docs/en docs/_build/en/html
101
+ sphinx-build -W --keep-going -b html docs/zh docs/_build/zh/html
101
102
  ```
102
103
 
103
- Read the Docs uses the repository's `.readthedocs.yaml` configuration and publishes a language-selection page with mirrored `/en/` and `/zh/` documentation trees.
104
+ Read the Docs publishes two projects linked as parent and translation: `operonproject` (English, `https://operonproject.readthedocs.io/en/latest/`) and `operonproject-zh` (Chinese, `https://operonproject.readthedocs.io/zh-cn/latest/`), each built from its own `docs/<language>/.readthedocs.yaml`.
@@ -45,11 +45,12 @@ python -m pip install -e '.[dev]'
45
45
 
46
46
  ## Documentation
47
47
 
48
- The complete documentation is maintained in [English](docs/en/index.md) and [Chinese](docs/zh/index.md). To build the Sphinx site locally:
48
+ The complete documentation is maintained in [English](docs/en/index.md) and [Chinese](docs/zh/index.md). Each language is its own Sphinx project; build both without warnings:
49
49
 
50
50
  ```bash
51
51
  python -m pip install -e '.[docs]'
52
- sphinx-build -W --keep-going -b html docs docs/_build/html
52
+ sphinx-build -W --keep-going -b html docs/en docs/_build/en/html
53
+ sphinx-build -W --keep-going -b html docs/zh docs/_build/zh/html
53
54
  ```
54
55
 
55
- Read the Docs uses the repository's `.readthedocs.yaml` configuration and publishes a language-selection page with mirrored `/en/` and `/zh/` documentation trees.
56
+ Read the Docs publishes two projects linked as parent and translation: `operonproject` (English, `https://operonproject.readthedocs.io/en/latest/`) and `operonproject-zh` (Chinese, `https://operonproject.readthedocs.io/zh-cn/latest/`), each built from its own `docs/<language>/.readthedocs.yaml`.
@@ -43,11 +43,12 @@ python -m pip install -e '.[dev]'
43
43
 
44
44
  ## 文档
45
45
 
46
- 完整文档同时维护[中文](docs/zh/index.md)和[英文](docs/en/index.md)版本。本地构建 Sphinx 站点:
46
+ 完整文档同时维护[中文](docs/zh/index.md)和[英文](docs/en/index.md)版本。每种语言是独立的 Sphinx 工程,两条构建都必须无警告通过:
47
47
 
48
48
  ```bash
49
49
  python -m pip install -e '.[docs]'
50
- sphinx-build -W --keep-going -b html docs docs/_build/html
50
+ sphinx-build -W --keep-going -b html docs/en docs/_build/en/html
51
+ sphinx-build -W --keep-going -b html docs/zh docs/_build/zh/html
51
52
  ```
52
53
 
53
- Read the Docs 使用仓库根目录的 `.readthedocs.yaml`,发布带语言选择入口及 `/zh/`、`/en/` 镜像目录的文档站点。
54
+ Read the Docs 发布两个互为父项目与翻译的项目:`operonproject`(英文,`https://operonproject.readthedocs.io/en/latest/`)与 `operonproject-zh`(中文,`https://operonproject.readthedocs.io/zh-cn/latest/`),各自从 `docs/<语言>/.readthedocs.yaml` 构建。
@@ -0,0 +1,218 @@
1
+ """Shared Sphinx configuration for the per-language Operon documentation.
2
+
3
+ The documentation is one Sphinx project per language and one Read the Docs
4
+ project per language:
5
+
6
+ =============== ==================== ===============================
7
+ Source tree Sphinx configuration Read the Docs project
8
+ =============== ==================== ===============================
9
+ ``docs/en/`` ``docs/en/conf.py`` ``docs/en/operonproject`` (parent)
10
+ ``docs/zh/`` ``docs/zh/conf.py`` ``docs/zh/operonproject-zh``
11
+ =============== ==================== ===============================
12
+
13
+ Read the Docs links the two projects as parent and translation; that link is
14
+ dashboard state (Admin -> Settings -> Translations), not repository state.
15
+ Each project also names the build configuration file it uses in its
16
+ ``Build configuration file`` setting, and Read the Docs accepts no file name
17
+ there other than ``.readthedocs.yaml``: the language is identified by the
18
+ directory holding it, so the repository ships ``docs/en/.readthedocs.yaml`` and
19
+ ``docs/zh/.readthedocs.yaml``.
20
+
21
+ Read the Docs runs Sphinx from the directory that holds the configuration
22
+ file. That directory is the source directory — every page of a language lives
23
+ next to its own ``conf.py`` — and Read the Docs always passes
24
+ ``-D language=<dashboard language>``, which overrides ``language`` here. The
25
+ dashboard is therefore authoritative for the published site, and a project
26
+ whose dashboard language contradicts its configuration fails the build (see
27
+ ``_check_declared_language``) instead of silently publishing the wrong
28
+ language.
29
+
30
+ Everything the language projects share — version markers, MyST settings,
31
+ theme options, the gettext entry points — lives in this module; each
32
+ ``conf.py`` only declares its own language and title.
33
+ """
34
+
35
+ from __future__ import annotations
36
+
37
+ import re
38
+ from importlib.metadata import PackageNotFoundError
39
+ from importlib.metadata import version as _distribution_version
40
+ from pathlib import Path
41
+
42
+ from sphinx.errors import ConfigError
43
+
44
+ try:
45
+ import tomllib
46
+ except ModuleNotFoundError: # Python 3.10
47
+ import tomli as tomllib
48
+
49
+
50
+ DOCS_DIR = Path(__file__).resolve().parent
51
+ REPO_ROOT = DOCS_DIR.parent
52
+
53
+ #: gettext catalogs, one ``.po`` per document, under
54
+ #: ``docs/locales/<language>/LC_MESSAGES/<docname>.po``. The directory is
55
+ #: optional: only a project that localizes through gettext registers it, so a
56
+ #: Markdown-only checkout never gets a missing-locale warning. See
57
+ #: ``docs/locales/README.md``.
58
+ LOCALES_DIR = DOCS_DIR / "locales"
59
+
60
+ #: Declare this as a project's ``language`` when the build decides instead of
61
+ #: the configuration — the case for a project that reuses another tree's
62
+ #: sources with gettext catalogs and takes its language from Read the Docs'
63
+ #: ``-D language=``.
64
+ LANGUAGE_FROM_BUILD = "auto"
65
+
66
+ #: ``(language, Read the Docs project)`` pairs declared by the ``conf.py``
67
+ #: files loaded in this Sphinx process.
68
+ _DECLARED_PROJECTS: list[tuple[str, str]] = []
69
+
70
+
71
+ def normalize_language(code: str) -> str:
72
+ """Return *code* in Sphinx's spelling, from any usual spelling.
73
+
74
+ Read the Docs stores and publishes lowercase-dashed codes (``zh-cn``),
75
+ while Sphinx wants ``ll_CC`` (``zh_CN``); ``en`` is the same in both.
76
+ """
77
+
78
+ primary, _, region = code.strip().lower().replace("-", "_").partition("_")
79
+ return f"{primary}_{region.upper()}" if region else primary
80
+
81
+
82
+ def package_version() -> str:
83
+ """Return the released ``operon`` version."""
84
+
85
+ try:
86
+ return _distribution_version("OperonDBS")
87
+ except PackageNotFoundError:
88
+ with (REPO_ROOT / "pyproject.toml").open("rb") as handle:
89
+ return tomllib.load(handle)["project"]["version"]
90
+
91
+
92
+ def source_constant(module: str, name: str) -> str:
93
+ """Read a module-level string constant, falling back to the source file."""
94
+
95
+ try:
96
+ imported = __import__(f"operon.{module}", fromlist=[name])
97
+ return str(getattr(imported, name))
98
+ except Exception:
99
+ source = (REPO_ROOT / "operon" / f"{module}.py").read_text(encoding="utf-8")
100
+ match = re.search(rf'^{name} = "([^"]+)"', source, re.MULTILINE)
101
+ if match is None:
102
+ raise RuntimeError(f"cannot resolve {name} from operon/{module}.py")
103
+ return match.group(1)
104
+
105
+
106
+ def apply_shared_settings(
107
+ namespace: dict,
108
+ *,
109
+ language: str,
110
+ title_suffix: str,
111
+ rtd_project: str,
112
+ ) -> None:
113
+ """Fill *namespace* (a ``conf.py``'s globals) with the shared settings.
114
+
115
+ ``language`` is the language this tree is written in, ``title_suffix``
116
+ completes the HTML title (``documentation`` / ``文档``), and
117
+ ``rtd_project`` names the Read the Docs project so that the language guard
118
+ can point at the right dashboard page.
119
+ """
120
+
121
+ release = package_version()
122
+ author = "Project Operon Development Group"
123
+
124
+ namespace.update(
125
+ # `conf.py` is an extension: Sphinx picks `setup` out of its namespace
126
+ # and runs it before `config-inited`, which is where the language guard
127
+ # hangs off. Registering it here keeps the language `conf.py` files
128
+ # free of boilerplate.
129
+ setup=setup,
130
+ release=release,
131
+ version=release,
132
+ project="Operon",
133
+ author=author,
134
+ copyright=f"2026, {author}. All Rights Reserved",
135
+ language=language,
136
+ # Markdown sources reference these as {{ operon_version }} /
137
+ # {{ db_schema }} / {{ metadata_schema }} in paragraph text.
138
+ # Substitutions do not expand inside code spans or fenced code blocks,
139
+ # so examples there use `<version>` placeholders instead. Historical
140
+ # version mentions stay literal and are guarded by
141
+ # tests/unit/test_docs_versions.py.
142
+ myst_substitutions={
143
+ "operon_version": release,
144
+ "db_schema": source_constant("database", "SCHEMA_VERSION"),
145
+ "metadata_schema": source_constant("schema", "METADATA_SCHEMA_VERSION"),
146
+ },
147
+ extensions=["myst_parser"],
148
+ source_suffix={".md": "markdown"},
149
+ root_doc="index",
150
+ exclude_patterns=["_build", "Thumbs.db", ".DS_Store"],
151
+ nitpicky=True,
152
+ suppress_warnings=["myst.header"],
153
+ myst_heading_anchors=4,
154
+ myst_enable_extensions=[
155
+ "colon_fence",
156
+ "deflist",
157
+ "fieldlist",
158
+ "substitution",
159
+ ],
160
+ # One catalog per document, so that the catalogs of a future gettext
161
+ # project mirror the page names of this tree.
162
+ gettext_compact=False,
163
+ html_theme="sphinx_rtd_theme",
164
+ html_title=f"Operon {release} {title_suffix}",
165
+ # The version and language selectors are rendered by the theme on Read
166
+ # the Docs and filled in by the Read the Docs Addons flyout: the
167
+ # language selector appears once the translation project is linked to
168
+ # this one in the dashboard.
169
+ html_theme_options={
170
+ "collapse_navigation": False,
171
+ "navigation_depth": 4,
172
+ "sticky_navigation": True,
173
+ "titles_only": True,
174
+ "version_selector": True,
175
+ "language_selector": True,
176
+ },
177
+ )
178
+
179
+ if LOCALES_DIR.is_dir():
180
+ namespace["locale_dirs"] = [str(LOCALES_DIR)]
181
+
182
+ _DECLARED_PROJECTS.append((language, rtd_project))
183
+
184
+
185
+ def _check_declared_language(app, config) -> None:
186
+ """Refuse to build a language the configuration does not declare.
187
+
188
+ Read the Docs overrides ``language`` with the language of the project, so a
189
+ mismatch means the two settings disagree about what is being published.
190
+ Failing here — with the dashboard page named — is the difference between a
191
+ loud build error and a Chinese project that quietly serves English pages.
192
+ """
193
+
194
+ built = normalize_language(config.language)
195
+ mismatched = [
196
+ (declared, project)
197
+ for declared, project in _DECLARED_PROJECTS
198
+ if declared != LANGUAGE_FROM_BUILD and normalize_language(declared) != built
199
+ ]
200
+ if not mismatched:
201
+ return
202
+
203
+ declared, project = mismatched[0]
204
+ raise ConfigError(
205
+ f"the {project!r} project is configured to build language {built!r} "
206
+ "(Read the Docs passes the language of a project as `-D language=...`, "
207
+ "which wins over everything set here) while this configuration declares "
208
+ f"{declared!r}. Set the language of {project!r} in Admin -> Settings to "
209
+ "the language of this tree, or point the project at the configuration "
210
+ "file of the tree it should build. A project that is meant to build a "
211
+ "language it does not declare (for example one driven by gettext "
212
+ f"catalogs) declares language = {LANGUAGE_FROM_BUILD!r} instead."
213
+ )
214
+
215
+
216
+ def setup(app):
217
+ app.connect("config-inited", _check_declared_language)
218
+ return {"parallel_read_safe": True, "parallel_write_safe": True}
@@ -0,0 +1,29 @@
1
+ # Read the Docs build configuration for the parent documentation project
2
+ # (`operonproject`), which publishes the English tree at
3
+ # https://operonproject.readthedocs.io/en/latest/ .
4
+ #
5
+ # Read the Docs accepts no build-configuration file name other than
6
+ # `.readthedocs.yaml`, so each language keeps one next to its `conf.py` and its
7
+ # project names that path in Admin -> Settings -> `Build configuration file`:
8
+ # `docs/en/.readthedocs.yaml` for this project, `docs/zh/.readthedocs.yaml` for
9
+ # the Chinese translation project (`operonproject-zh`), which is linked to this
10
+ # project on its Translations page and then served under this project's domain
11
+ # with the language prefix. See docs/en/contributor/documentation-deployment.md.
12
+ version: 2
13
+
14
+ build:
15
+ os: ubuntu-24.04
16
+ tools:
17
+ python: "3.12"
18
+
19
+ sphinx:
20
+ # Read the Docs runs Sphinx from the directory holding this file, so
21
+ # `docs/en/` is both the configuration directory and the source directory.
22
+ # Paths elsewhere in this file stay relative to the repository root.
23
+ configuration: docs/en/conf.py
24
+ builder: html
25
+ fail_on_warning: true
26
+
27
+ python:
28
+ install:
29
+ - requirements: docs/requirements.txt
@@ -0,0 +1,24 @@
1
+ """Sphinx configuration for the English Operon documentation.
2
+
3
+ This tree is the parent Read the Docs project ``operonproject``, published at
4
+ ``https://operonproject.readthedocs.io/en/latest/``; the Chinese translation
5
+ project builds ``docs/zh/`` from ``docs/zh/.readthedocs.yaml``. Shared settings
6
+ live in ``docs/conf_common.py``; see
7
+ ``contributor/documentation-deployment.md``.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
16
+
17
+ from conf_common import apply_shared_settings # noqa: E402
18
+
19
+ apply_shared_settings(
20
+ globals(),
21
+ language="en",
22
+ title_suffix="documentation",
23
+ rtd_project="operonproject",
24
+ )