modmgr 0.0.2__tar.gz → 0.0.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 (218) hide show
  1. {modmgr-0.0.2/src/modmgr.egg-info → modmgr-0.0.3}/PKG-INFO +21 -7
  2. {modmgr-0.0.2 → modmgr-0.0.3}/README.md +20 -6
  3. {modmgr-0.0.2 → modmgr-0.0.3}/pyproject.toml +1 -1
  4. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/__init__.py +1 -1
  5. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/acf_parser.py +0 -30
  6. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/apply_ops.py +19 -1
  7. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/backup_dir_builder.py +6 -16
  8. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/backup_ops.py +157 -70
  9. modmgr-0.0.3/src/modmgr/bootstrap.py +136 -0
  10. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/cli.py +28 -24
  11. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/core/workspacemanager.py +19 -0
  12. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/database_ops.py +230 -1
  13. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/engine.py +57 -4
  14. modmgr-0.0.3/src/modmgr/orchestrator/__init__.py +136 -0
  15. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/orchestrator/_common.py +14 -17
  16. modmgr-0.0.3/src/modmgr/orchestrator/compute_pipeline.py +140 -0
  17. modmgr-0.0.3/src/modmgr/orchestrator/data_port.py +229 -0
  18. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/orchestrator/entry.py +2 -0
  19. modmgr-0.0.3/src/modmgr/orchestrator/fileops/__init__.py +292 -0
  20. modmgr-0.0.3/src/modmgr/orchestrator/fileops/_common.py +11 -0
  21. modmgr-0.0.3/src/modmgr/orchestrator/fileops/planner/__init__.py +1 -0
  22. {modmgr-0.0.2/src/modmgr/orchestrator → modmgr-0.0.3/src/modmgr/orchestrator/fileops/planner}/ignore_rules.py +10 -22
  23. modmgr-0.0.3/src/modmgr/orchestrator/fileops/planner/planner.py +263 -0
  24. {modmgr-0.0.2/src/modmgr/orchestrator → modmgr-0.0.3/src/modmgr/orchestrator/fileops/planner}/preflight.py +3 -9
  25. modmgr-0.0.3/src/modmgr/orchestrator/resolver.py +65 -0
  26. modmgr-0.0.3/src/modmgr/orchestrator/verifier.py +34 -0
  27. modmgr-0.0.3/src/modmgr/osplatform.py +83 -0
  28. modmgr-0.0.3/src/modmgr/path_normalizer.py +153 -0
  29. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/paths.py +46 -0
  30. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/prep.py +22 -6
  31. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/restore_ops.py +19 -7
  32. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/rule_aggregator.py +28 -27
  33. modmgr-0.0.3/src/modmgr/rule_validator.py +262 -0
  34. modmgr-0.0.3/src/modmgr/userconfig_ops.py +157 -0
  35. {modmgr-0.0.2 → modmgr-0.0.3/src/modmgr.egg-info}/PKG-INFO +21 -7
  36. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr.egg-info/SOURCES.txt +72 -49
  37. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/__init__.py +2 -2
  38. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/adapters.py +8 -3
  39. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/app.py +5 -4
  40. modmgr-0.0.3/src/modmgr_web/dependencies.py +23 -0
  41. modmgr-0.0.3/src/modmgr_web/routes/config.py +75 -0
  42. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/routes/database.py +11 -7
  43. modmgr-0.0.3/src/modmgr_web/routes/os_defaults.py +22 -0
  44. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/routes/rules.py +94 -65
  45. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/routes/workspace.py +104 -52
  46. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/schemas.py +14 -34
  47. modmgr-0.0.2/src/modmgr_web/static/assets/AdvancedPage-BlynjfkZ.css → modmgr-0.0.3/src/modmgr_web/static/assets/AdvancedPage-BOy2nqQ8.css +1 -1
  48. modmgr-0.0.3/src/modmgr_web/static/assets/AdvancedPage-CwT_3NzI.js +1 -0
  49. modmgr-0.0.3/src/modmgr_web/static/assets/ComputePrepPage-BxOuQEE4.js +1 -0
  50. modmgr-0.0.3/src/modmgr_web/static/assets/ConflictsPage-st8yBvaW.js +1 -0
  51. modmgr-0.0.3/src/modmgr_web/static/assets/DataSourcePage-B0Fb4feM.css +1 -0
  52. modmgr-0.0.3/src/modmgr_web/static/assets/DataSourcePage-BtCbwJ-T.js +9 -0
  53. modmgr-0.0.3/src/modmgr_web/static/assets/DatabaseSelector.vue_vue_type_script_setup_true_lang-BIJrR2HG.js +1 -0
  54. modmgr-0.0.3/src/modmgr_web/static/assets/ForestPage-6KpG9V6V.js +1 -0
  55. modmgr-0.0.2/src/modmgr_web/static/assets/ForestPage-Byt42R5I.css → modmgr-0.0.3/src/modmgr_web/static/assets/ForestPage-DGF6rvaN.css +1 -1
  56. modmgr-0.0.3/src/modmgr_web/static/assets/OperationsPage-D-Nv6brQ.js +1 -0
  57. modmgr-0.0.2/src/modmgr_web/static/assets/RuleEditorPage-BRdl1DQE.js → modmgr-0.0.3/src/modmgr_web/static/assets/RuleEditorPage-BSBCt3wv.js +1 -1
  58. modmgr-0.0.3/src/modmgr_web/static/assets/RulesOverviewPage-X6AwekNq.js +1 -0
  59. modmgr-0.0.3/src/modmgr_web/static/assets/RulesOverviewPage-n5UOmk0q.css +1 -0
  60. modmgr-0.0.3/src/modmgr_web/static/assets/SettingsPage-BqGIPRGT.css +1 -0
  61. modmgr-0.0.3/src/modmgr_web/static/assets/SettingsPage-D__Ltuai.js +3 -0
  62. modmgr-0.0.3/src/modmgr_web/static/assets/WorkspaceListPage-BhaxJXyF.js +1 -0
  63. modmgr-0.0.3/src/modmgr_web/static/assets/WorkspaceListPage-CpPPvOBL.css +1 -0
  64. modmgr-0.0.3/src/modmgr_web/static/assets/el-alert-D2Saa0Hc.js +1 -0
  65. modmgr-0.0.2/src/modmgr_web/static/assets/el-button-AT5h7hGh.js → modmgr-0.0.3/src/modmgr_web/static/assets/el-button-BYe4S2ex.js +2 -2
  66. modmgr-0.0.2/src/modmgr_web/static/assets/el-card-D-_HzL2Z.js → modmgr-0.0.3/src/modmgr_web/static/assets/el-card-s1CSqXfS.js +1 -1
  67. modmgr-0.0.3/src/modmgr_web/static/assets/el-checkbox-DeteIHNl.js +1 -0
  68. modmgr-0.0.3/src/modmgr_web/static/assets/el-descriptions-vSz7N21L.js +1 -0
  69. modmgr-0.0.2/src/modmgr_web/static/assets/el-dialog-Cza5NAqp.js → modmgr-0.0.3/src/modmgr_web/static/assets/el-dialog-DwhSavoe.js +1 -1
  70. modmgr-0.0.2/src/modmgr_web/static/assets/el-empty-CCIPJNFU.js → modmgr-0.0.3/src/modmgr_web/static/assets/el-empty-VMYF2sSP.js +1 -1
  71. modmgr-0.0.3/src/modmgr_web/static/assets/el-form-item-B4gKaEz8.js +12 -0
  72. modmgr-0.0.3/src/modmgr_web/static/assets/el-overlay-wnSnOlkc.js +1 -0
  73. modmgr-0.0.3/src/modmgr_web/static/assets/el-popconfirm-BGy5JHgt.js +1 -0
  74. modmgr-0.0.3/src/modmgr_web/static/assets/el-radio-group-DoHaUrP6.js +1 -0
  75. modmgr-0.0.3/src/modmgr_web/static/assets/el-select-OUVOOvVS.js +1 -0
  76. modmgr-0.0.2/src/modmgr_web/static/assets/el-switch-DIwbzpAs.js → modmgr-0.0.3/src/modmgr_web/static/assets/el-switch-BaqOoRAo.js +1 -1
  77. modmgr-0.0.2/src/modmgr_web/static/assets/el-table-column-CHXB8sqU.js → modmgr-0.0.3/src/modmgr_web/static/assets/el-table-column-ZcwEwZCy.js +2 -2
  78. modmgr-0.0.3/src/modmgr_web/static/assets/el-tag-BkjtId4Z.js +1 -0
  79. modmgr-0.0.3/src/modmgr_web/static/assets/el-tag-ChKtugzh.css +1 -0
  80. modmgr-0.0.2/src/modmgr_web/static/assets/errorCodes-R2Ns5uWN.js → modmgr-0.0.3/src/modmgr_web/static/assets/errorCodes-D-5ZmgKx.js +1 -1
  81. modmgr-0.0.2/src/modmgr_web/static/assets/index-CS8EMmUO.js → modmgr-0.0.3/src/modmgr_web/static/assets/index-CD5SgAY3.js +1 -1
  82. modmgr-0.0.3/src/modmgr_web/static/assets/index-D1sN9TXS.js +20 -0
  83. modmgr-0.0.3/src/modmgr_web/static/assets/index-DoSbT-ZE.js +1 -0
  84. modmgr-0.0.3/src/modmgr_web/static/assets/index-wmYzOOc3.js +1 -0
  85. modmgr-0.0.3/src/modmgr_web/static/assets/omit-0VPi5Pw4.js +1 -0
  86. modmgr-0.0.2/src/modmgr_web/static/assets/scroll-B0BQcoln.js → modmgr-0.0.3/src/modmgr_web/static/assets/scroll-bIjgS0la.js +1 -1
  87. modmgr-0.0.3/src/modmgr_web/static/assets/validator-bvQTp9xD.js +1 -0
  88. modmgr-0.0.2/src/modmgr_web/static/assets/vue-vendor-D2-6FgTr.js → modmgr-0.0.3/src/modmgr_web/static/assets/vue-vendor-BAcbAOSy.js +1 -1
  89. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/index.html +2 -2
  90. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_backup_dir_builder.py +5 -18
  91. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_backup_dir_multi_mod.py +2 -2
  92. modmgr-0.0.3/tests/test_backup_ops.py +95 -0
  93. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_backup_tree.py +129 -5
  94. modmgr-0.0.3/tests/test_bootstrap.py +187 -0
  95. modmgr-0.0.3/tests/test_case_mismatch_warning.py +121 -0
  96. modmgr-0.0.3/tests/test_database_ops_promotion.py +231 -0
  97. modmgr-0.0.3/tests/test_dataport_spec.py +724 -0
  98. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_dispatch_cross_contam.py +1 -1
  99. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_dump_backup_assignment.py +1 -1
  100. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_full_pipeline_integration.py +3 -3
  101. modmgr-0.0.3/tests/test_gate_boundary.py +177 -0
  102. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_ignore_rules.py +9 -21
  103. modmgr-0.0.3/tests/test_inherent_fixes.py +222 -0
  104. modmgr-0.0.3/tests/test_kmmignore_lifecycle.py +441 -0
  105. modmgr-0.0.3/tests/test_orchestrator.py +486 -0
  106. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_orchestrator_engine.py +93 -47
  107. modmgr-0.0.3/tests/test_osplatform.py +142 -0
  108. modmgr-0.0.3/tests/test_path_normalizer.py +350 -0
  109. modmgr-0.0.3/tests/test_paths.py +119 -0
  110. modmgr-0.0.3/tests/test_planner_fileops.py +278 -0
  111. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_preflight.py +20 -21
  112. modmgr-0.0.3/tests/test_restore_backupdir_contract.py +349 -0
  113. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_restore_ops.py +1 -1
  114. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_rule_aggregator.py +4 -33
  115. modmgr-0.0.3/tests/test_rule_validator.py +345 -0
  116. modmgr-0.0.3/tests/test_userconfig_ops.py +179 -0
  117. modmgr-0.0.3/tests/test_validator_normalizer_placement.py +423 -0
  118. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_web_api.py +219 -398
  119. modmgr-0.0.3/tests/test_web_api_rule_sources.py +356 -0
  120. modmgr-0.0.3/tests/test_web_purification.py +512 -0
  121. modmgr-0.0.2/src/modmgr/bootstrap.py +0 -284
  122. modmgr-0.0.2/src/modmgr/orchestrator/__init__.py +0 -308
  123. modmgr-0.0.2/src/modmgr/orchestrator/compute_pipeline.py +0 -232
  124. modmgr-0.0.2/src/modmgr/orchestrator/planner_fileops.py +0 -151
  125. modmgr-0.0.2/src/modmgr/orchestrator/resolver.py +0 -116
  126. modmgr-0.0.2/src/modmgr_web/routes/config.py +0 -73
  127. modmgr-0.0.2/src/modmgr_web/routes/pipeline.py +0 -158
  128. modmgr-0.0.2/src/modmgr_web/static/assets/AdvancedPage-BVtD3b30.js +0 -1
  129. modmgr-0.0.2/src/modmgr_web/static/assets/ComputePrepPage-Bbijng11.js +0 -1
  130. modmgr-0.0.2/src/modmgr_web/static/assets/ConflictsPage-CtRN5peD.js +0 -1
  131. modmgr-0.0.2/src/modmgr_web/static/assets/DataSourcePage-CYYM2t-S.css +0 -1
  132. modmgr-0.0.2/src/modmgr_web/static/assets/DataSourcePage-la0myoei.js +0 -9
  133. modmgr-0.0.2/src/modmgr_web/static/assets/DatabaseSelector.vue_vue_type_script_setup_true_lang-BOtgwjhY.js +0 -1
  134. modmgr-0.0.2/src/modmgr_web/static/assets/ForestPage-CdwZkKqj.js +0 -1
  135. modmgr-0.0.2/src/modmgr_web/static/assets/OperationsPage-Df4OFUiU.js +0 -1
  136. modmgr-0.0.2/src/modmgr_web/static/assets/RulesOverviewPage-CgxjIB-t.js +0 -1
  137. modmgr-0.0.2/src/modmgr_web/static/assets/RulesOverviewPage-u3pKIDBY.css +0 -1
  138. modmgr-0.0.2/src/modmgr_web/static/assets/SettingsPage-Bm_gPec4.js +0 -1
  139. modmgr-0.0.2/src/modmgr_web/static/assets/SettingsPage-D2YOErl8.css +0 -1
  140. modmgr-0.0.2/src/modmgr_web/static/assets/WorkspaceListPage-Bt5Ef8qB.js +0 -1
  141. modmgr-0.0.2/src/modmgr_web/static/assets/WorkspaceListPage-gpzf4m3z.css +0 -1
  142. modmgr-0.0.2/src/modmgr_web/static/assets/el-alert-IVqfzkxo.js +0 -1
  143. modmgr-0.0.2/src/modmgr_web/static/assets/el-checkbox-DamL9NFG.js +0 -1
  144. modmgr-0.0.2/src/modmgr_web/static/assets/el-descriptions-DCWEzttD.js +0 -1
  145. modmgr-0.0.2/src/modmgr_web/static/assets/el-form-item-BTg7KMpb.js +0 -12
  146. modmgr-0.0.2/src/modmgr_web/static/assets/el-overlay-BozBPV_3.js +0 -1
  147. modmgr-0.0.2/src/modmgr_web/static/assets/el-popconfirm-Dh0aYkpl.js +0 -1
  148. modmgr-0.0.2/src/modmgr_web/static/assets/el-radio-group-DS4donKo.js +0 -1
  149. modmgr-0.0.2/src/modmgr_web/static/assets/el-scrollbar-GF-yQkxY.css +0 -1
  150. modmgr-0.0.2/src/modmgr_web/static/assets/el-scrollbar-bnCh1REM.js +0 -1
  151. modmgr-0.0.2/src/modmgr_web/static/assets/el-select-CjDrv2OP.js +0 -1
  152. modmgr-0.0.2/src/modmgr_web/static/assets/el-tag-1VV9QMa7.css +0 -1
  153. modmgr-0.0.2/src/modmgr_web/static/assets/el-tag-CzJcUa9U.js +0 -1
  154. modmgr-0.0.2/src/modmgr_web/static/assets/index-BvWwu1pq.js +0 -19
  155. modmgr-0.0.2/src/modmgr_web/static/assets/index-KQG8QDNo.js +0 -1
  156. modmgr-0.0.2/src/modmgr_web/static/assets/index-xu_G5r7L.js +0 -1
  157. modmgr-0.0.2/src/modmgr_web/static/assets/omit-DgViQIMi.js +0 -1
  158. modmgr-0.0.2/src/modmgr_web/static/assets/validator-DDEwb28U.js +0 -1
  159. modmgr-0.0.2/tests/test_backup_ops.py +0 -716
  160. modmgr-0.0.2/tests/test_bootstrap.py +0 -198
  161. modmgr-0.0.2/tests/test_orchestrator.py +0 -628
  162. modmgr-0.0.2/tests/test_paths.py +0 -56
  163. {modmgr-0.0.2 → modmgr-0.0.3}/LICENSE +0 -0
  164. {modmgr-0.0.2 → modmgr-0.0.3}/MANIFEST.in +0 -0
  165. {modmgr-0.0.2 → modmgr-0.0.3}/setup.cfg +0 -0
  166. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/core/__init__.py +0 -0
  167. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/forest_visual.py +0 -0
  168. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/iojson.py +0 -0
  169. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/path_resolver.py +0 -0
  170. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/pathstyle.py +0 -0
  171. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/schema.py +0 -0
  172. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/steam_scanner.py +0 -0
  173. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/validation.py +0 -0
  174. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr/vdf_parser.py +0 -0
  175. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr.egg-info/dependency_links.txt +0 -0
  176. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr.egg-info/entry_points.txt +0 -0
  177. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr.egg-info/requires.txt +0 -0
  178. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr.egg-info/top_level.txt +0 -0
  179. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/__main__.py +0 -0
  180. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/routes/__init__.py +0 -0
  181. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/routes/backups.py +0 -0
  182. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/sse.py +0 -0
  183. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/ComputePrepPage-Cuwyx6dM.css +0 -0
  184. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/ConflictsPage-Dfe3kTdp.css +0 -0
  185. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/OperationsPage-DUJyGPlV.css +0 -0
  186. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/RuleEditorPage-BN6I5Wjs.css +0 -0
  187. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-alert-B6UgayC7.css +0 -0
  188. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-button-DITZ5HsB.css +0 -0
  189. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-card-BAyktVMS.css +0 -0
  190. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-checkbox-CzNtyWdF.css +0 -0
  191. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-descriptions-BpDzfuC8.css +0 -0
  192. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-dialog-DdHdkgt4.css +0 -0
  193. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-empty-S7fQQ3B8.css +0 -0
  194. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-form-item-BUYvSc9V.css +0 -0
  195. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-input-xaztPnzw.css +0 -0
  196. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-overlay-BKLuON5C.css +0 -0
  197. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-popconfirm-BmypG9Rq.css +0 -0
  198. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-radio-group-iy_biC8N.css +0 -0
  199. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-select-CK58rX4v.css +0 -0
  200. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-switch-DpR9-s4E.css +0 -0
  201. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/el-table-column-Dp73S2HR.css +0 -0
  202. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/assets/index-BK5KbVso.css +0 -0
  203. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/favicon.jpg +0 -0
  204. {modmgr-0.0.2 → modmgr-0.0.3}/src/modmgr_web/static/mockServiceWorker.js +0 -0
  205. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_apply_ops.py +0 -0
  206. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_cli_database_ops.py +0 -0
  207. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_contract.py +0 -0
  208. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_database_ops.py +0 -0
  209. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_engine.py +0 -0
  210. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_forest_visual.py +0 -0
  211. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_integration_fixtures.py +0 -0
  212. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_iojson.py +0 -0
  213. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_path_resolver.py +0 -0
  214. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_pathstyle.py +0 -0
  215. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_restore_per_design.py +0 -0
  216. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_steam_scanner.py +0 -0
  217. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_validation.py +0 -0
  218. {modmgr-0.0.2 → modmgr-0.0.3}/tests/test_web_entrypoint.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modmgr
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: File mapping and backup rule engine for workshop mods
5
5
  Project-URL: Homepage, https://github.com/Knighthana/modmanager
6
6
  Project-URL: Repository, https://github.com/Knighthana/modmanager
@@ -18,15 +18,20 @@ Requires-Dist: uvicorn[standard]>=0.23; extra == "web"
18
18
  Dynamic: license-file
19
19
 
20
20
  ---
21
- status: active
22
- concept: readme
23
- applicable-to: human
24
- update: 2026-05-20
21
+ Status: active
22
+ Authority: reference-only
23
+ Purpose: readme for beginner
24
+ Read-Tier: never
25
+ Applicable-to: human-only
26
+ Unapplicable-to: agents
27
+ Updated: 2026-06-01
25
28
  ---
26
29
 
27
30
  The Knighthana's Mod Manager
28
31
  ============================
29
32
 
33
+ 作为向最终用户的说明文档省略了内部细节的详细描述,故此**禁止**任何Agent以此作为实现依据;
34
+
30
35
  **项目仍然处于开发阶段,部分核心功能正在深度重构和优化,欢迎开发者加入讨论和贡献,但目前不建议一般用户直接用于生产环境**
31
36
 
32
37
  探索性开发已告一段落,因个人工作变动,项目短期内将进入低活跃维护状态,欢迎有兴趣的开发者参与。
@@ -57,7 +62,7 @@ The Knighthana's Mod Manager(简称KMM)通过对"文件迁移过程"进行脱离
57
62
  pip install modmgr
58
63
 
59
64
  # 安装 Web 界面(可选)
60
- pip install modmgr[web]
65
+ pip install "modmgr[web]"
61
66
 
62
67
  # 启动 Web 服务(需先安装 web 依赖)
63
68
  modmgr-web # → http://127.0.0.1:8000
@@ -73,16 +78,23 @@ modmgr-cli --help
73
78
  待程序运行之后,请打开浏览器在[KMM面板](127.0.0.1:8000)进行操作:
74
79
 
75
80
  1. 在“数据来源”点击“扫描Steam库”等待其完成,这一步是为了创建游戏-MOD数据库;
81
+ ![scan_steam_lib](description/ref/webuse03.png)
76
82
  2. 在“设置面板”的“规则来源”下方,点击“➕ 添加来源”创建一个新的空行,将Modder交给你的kmmrule文件的路径填写在空行中,点击“保存”;
83
+ ![rule_sources](description/ref/webuse04.png)
77
84
  3. **务必**点击下方的“保存设置”按钮,对设定进行保存;
78
85
  4. 进入“工作区”页面,点击右上方的“新建工作区”,输入必要的信息来创建一个工作区,每个工作区各自保存了一种替换模式,尽可能为每类不同的任务创建不同的工作区;
86
+ ![work_save_space1](description/ref/webuse01.png) ![work_save_space2](description/ref/webuse02.png)
79
87
  5. 在面板中点击工作区条目的“进入”来进入一个工作区;
80
88
  6. 在“发现的规则文件”勾选Modder提供给你的kmmrule文件前方的复选框,如果感兴趣可以点击右侧的“展开”以查看这个规则的详细信息;
89
+ ![select_rules](description/ref/webuse05.png)
81
90
  7. 点击“进入计算准备”,系统会自动将你导航到“计算准备”页面;
82
91
  8. 仅保留想要替换的库/游戏/MOD前方的复选框,之后点击“开始计算”或者“计算查看”;复选框用于确定实际影响的游戏/MOD,可见按钮仅仅用于调整视觉效果,不影响最终结果;
92
+ ![prepare_for_compute](description/ref/webuse06.png)
83
93
  9. 自行点击或等待系统导航进入“森林可视”界面,可以放大映射图,检查这些映射是不是你所想要的;
94
+ ![forest_view](description/ref/webuse07.png)
84
95
  10. 如果有必要,在“冲突裁决”页面进行手动裁决;
85
96
  11. 进入“文件操作”页面,如果这是首次操作,必须先点击“备份”,如果心存疑虑,务必打开"dry run"开关进行模拟;"dry run"不会进行任何实际的文件操作;
97
+ ![file_operation](description/ref/webuse08.png)
86
98
  12. “备份”完成后,可以点击“应用”进行文件替换,等待操作完成;
87
99
  13. 如果您的游戏/MOD需要分时间使用多个不同的规则,那么下次请在“备份”前先点击“恢复”,然后再“备份”和“应用”;
88
100
 
@@ -101,7 +113,7 @@ modmgr-cli --help
101
113
  |---|------|-------|-----|
102
114
  |用户配置|`~/.config/kmm/`|`%APPDATA%/kmm/`|`~/Library/Preferences/kmm/`|
103
115
  |默认数据库|`~/.local/share/kmm/`|`%LOCALAPPDATA%/kmm/database/`|`~/Library/Application Support/kmm/`|
104
- |默认工作区|`~/.cache/kmm/workspace/`|`%LOCALAPPDATA%/kmm/workspace/`|`%LOCALAPPDATA%/kmm/workspace/`|
116
+ |默认工作区|`~/.cache/kmm/workspace/`|`%LOCALAPPDATA%/kmm/workspace/`|`~/Library/Caches/`|
105
117
 
106
118
  这些值是硬编码的“默认值”,但目前也支持通过“设置面板”进行自定义;
107
119
 
@@ -130,6 +142,8 @@ modmgr-cli --help
130
142
 
131
143
  项目还在成长,接受各种想法;
132
144
 
145
+ ---------------------------
146
+
133
147
  Knighthana
134
148
 
135
149
  2026/05/22
@@ -1,13 +1,18 @@
1
1
  ---
2
- status: active
3
- concept: readme
4
- applicable-to: human
5
- update: 2026-05-20
2
+ Status: active
3
+ Authority: reference-only
4
+ Purpose: readme for beginner
5
+ Read-Tier: never
6
+ Applicable-to: human-only
7
+ Unapplicable-to: agents
8
+ Updated: 2026-06-01
6
9
  ---
7
10
 
8
11
  The Knighthana's Mod Manager
9
12
  ============================
10
13
 
14
+ 作为向最终用户的说明文档省略了内部细节的详细描述,故此**禁止**任何Agent以此作为实现依据;
15
+
11
16
  **项目仍然处于开发阶段,部分核心功能正在深度重构和优化,欢迎开发者加入讨论和贡献,但目前不建议一般用户直接用于生产环境**
12
17
 
13
18
  探索性开发已告一段落,因个人工作变动,项目短期内将进入低活跃维护状态,欢迎有兴趣的开发者参与。
@@ -38,7 +43,7 @@ The Knighthana's Mod Manager(简称KMM)通过对"文件迁移过程"进行脱离
38
43
  pip install modmgr
39
44
 
40
45
  # 安装 Web 界面(可选)
41
- pip install modmgr[web]
46
+ pip install "modmgr[web]"
42
47
 
43
48
  # 启动 Web 服务(需先安装 web 依赖)
44
49
  modmgr-web # → http://127.0.0.1:8000
@@ -54,16 +59,23 @@ modmgr-cli --help
54
59
  待程序运行之后,请打开浏览器在[KMM面板](127.0.0.1:8000)进行操作:
55
60
 
56
61
  1. 在“数据来源”点击“扫描Steam库”等待其完成,这一步是为了创建游戏-MOD数据库;
62
+ ![scan_steam_lib](description/ref/webuse03.png)
57
63
  2. 在“设置面板”的“规则来源”下方,点击“➕ 添加来源”创建一个新的空行,将Modder交给你的kmmrule文件的路径填写在空行中,点击“保存”;
64
+ ![rule_sources](description/ref/webuse04.png)
58
65
  3. **务必**点击下方的“保存设置”按钮,对设定进行保存;
59
66
  4. 进入“工作区”页面,点击右上方的“新建工作区”,输入必要的信息来创建一个工作区,每个工作区各自保存了一种替换模式,尽可能为每类不同的任务创建不同的工作区;
67
+ ![work_save_space1](description/ref/webuse01.png) ![work_save_space2](description/ref/webuse02.png)
60
68
  5. 在面板中点击工作区条目的“进入”来进入一个工作区;
61
69
  6. 在“发现的规则文件”勾选Modder提供给你的kmmrule文件前方的复选框,如果感兴趣可以点击右侧的“展开”以查看这个规则的详细信息;
70
+ ![select_rules](description/ref/webuse05.png)
62
71
  7. 点击“进入计算准备”,系统会自动将你导航到“计算准备”页面;
63
72
  8. 仅保留想要替换的库/游戏/MOD前方的复选框,之后点击“开始计算”或者“计算查看”;复选框用于确定实际影响的游戏/MOD,可见按钮仅仅用于调整视觉效果,不影响最终结果;
73
+ ![prepare_for_compute](description/ref/webuse06.png)
64
74
  9. 自行点击或等待系统导航进入“森林可视”界面,可以放大映射图,检查这些映射是不是你所想要的;
75
+ ![forest_view](description/ref/webuse07.png)
65
76
  10. 如果有必要,在“冲突裁决”页面进行手动裁决;
66
77
  11. 进入“文件操作”页面,如果这是首次操作,必须先点击“备份”,如果心存疑虑,务必打开"dry run"开关进行模拟;"dry run"不会进行任何实际的文件操作;
78
+ ![file_operation](description/ref/webuse08.png)
67
79
  12. “备份”完成后,可以点击“应用”进行文件替换,等待操作完成;
68
80
  13. 如果您的游戏/MOD需要分时间使用多个不同的规则,那么下次请在“备份”前先点击“恢复”,然后再“备份”和“应用”;
69
81
 
@@ -82,7 +94,7 @@ modmgr-cli --help
82
94
  |---|------|-------|-----|
83
95
  |用户配置|`~/.config/kmm/`|`%APPDATA%/kmm/`|`~/Library/Preferences/kmm/`|
84
96
  |默认数据库|`~/.local/share/kmm/`|`%LOCALAPPDATA%/kmm/database/`|`~/Library/Application Support/kmm/`|
85
- |默认工作区|`~/.cache/kmm/workspace/`|`%LOCALAPPDATA%/kmm/workspace/`|`%LOCALAPPDATA%/kmm/workspace/`|
97
+ |默认工作区|`~/.cache/kmm/workspace/`|`%LOCALAPPDATA%/kmm/workspace/`|`~/Library/Caches/`|
86
98
 
87
99
  这些值是硬编码的“默认值”,但目前也支持通过“设置面板”进行自定义;
88
100
 
@@ -111,6 +123,8 @@ modmgr-cli --help
111
123
 
112
124
  项目还在成长,接受各种想法;
113
125
 
126
+ ---------------------------
127
+
114
128
  Knighthana
115
129
 
116
130
  2026/05/22
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "modmgr"
7
- version = "0.0.2"
7
+ version = "0.0.3"
8
8
  description = "File mapping and backup rule engine for workshop mods"
9
9
  requires-python = ">=3.10"
10
10
  keywords = ["mod", "manager", "game", "backup"]
@@ -1,4 +1,4 @@
1
- """modmanager package."""
1
+ """modmgr package."""
2
2
 
3
3
  __all__ = [
4
4
  "engine",
@@ -116,34 +116,6 @@ def parse_appworkshop_acf(acf_path: str) -> list[dict[str, Any]]:
116
116
  return items
117
117
 
118
118
 
119
- def find_appmanifest_acf_files(steamapps_path: str) -> dict[str, str]:
120
- """
121
- Find all appmanifest_*.acf files in steamapps directory.
122
-
123
- Args:
124
- steamapps_path: Path to steamapps/ directory
125
-
126
- Returns:
127
- Dict: {appid: path_to_appmanifest_acf}
128
- Example: {"270150": "/path/to/appmanifest_270150.acf", ...}
129
- """
130
- raise NotImplementedError("To be implemented in M1.1")
131
-
132
-
133
- def find_appworkshop_acf_files(steamapps_path: str) -> dict[str, str]:
134
- """
135
- Find all appworkshop_*.acf files in steamapps directory.
136
-
137
- Args:
138
- steamapps_path: Path to steamapps/ directory
139
-
140
- Returns:
141
- Dict: {appid: path_to_appworkshop_acf}
142
- Example: {"270150": "/path/to/appworkshop_270150.acf", ...}
143
- """
144
- raise NotImplementedError("To be implemented in M1.1")
145
-
146
-
147
119
  def get_workshop_timeupdated(steamapps_path: str, appid: str, contentid: str | None = None) -> str:
148
120
  """从 appworkshop_{appid}.acf 读取 timeupdated 字段并返回字符串。
149
121
 
@@ -295,8 +267,6 @@ def get_workshop_latest_timeupdated(steamapps_path: str, appid: str, contentid:
295
267
  __all__ = [
296
268
  "parse_appmanifest_acf",
297
269
  "parse_appworkshop_acf",
298
- "find_appmanifest_acf_files",
299
- "find_appworkshop_acf_files",
300
270
  "get_workshop_timeupdated",
301
271
  "get_workshop_latest_timeupdated",
302
272
  ]
@@ -45,6 +45,11 @@ def apply_entries(
45
45
  target_path = entry["path"]
46
46
  request = entry.get("request")
47
47
 
48
+ if not target_path:
49
+ errors.append(f"E_APPLY_MISSING_TARGET: apply entry has empty target path")
50
+ finished += 1
51
+ continue
52
+
48
53
  if request is None:
49
54
  skipped.append({"path": target_path, "reason": "no source (vacuous node)"})
50
55
  finished += 1
@@ -61,8 +66,10 @@ def apply_entries(
61
66
 
62
67
  try:
63
68
  if action == "delete":
69
+ # File-to-file guard in BOTH modes so dry_run reports
70
+ # the same errors the real run would
71
+ _assert_is_file(target_path, action)
64
72
  if not dry_run:
65
- _assert_is_file(target_path, action)
66
73
  os.remove(target_path)
67
74
  applied.append({
68
75
  "action": "delete",
@@ -78,6 +85,17 @@ def apply_entries(
78
85
  finished += 1
79
86
  continue
80
87
 
88
+ # Existence + file-type checks in BOTH modes so dry_run
89
+ # reports the same errors the real run would (§6.2)
90
+ if os.path.isdir(source_path):
91
+ errors.append(f"E_APPLY_DIRECTORY_NOT_ALLOWED: {action} source is a directory: {source_path}")
92
+ finished += 1
93
+ continue
94
+ if not os.path.isfile(source_path):
95
+ errors.append(f"E_APPLY_MISSING_SOURCE: {source_path}")
96
+ finished += 1
97
+ continue
98
+
81
99
  if not dry_run:
82
100
  _assert_is_file(source_path, action)
83
101
  os.makedirs(os.path.dirname(target_path), exist_ok=True)
@@ -63,7 +63,7 @@ def build_backup_dirs(
63
63
  - backup_dir → 属于该目录的文件绝对路径列表
64
64
  - warnings: 稳定性检查中被跳过的 contentid 警告信息
65
65
  """
66
- baksuffix = str(user_config.get("baksuffix", "kmmbackup"))
66
+ baksuffix = str(user_config.get("baksuffix"))
67
67
 
68
68
  # ── 1. 收集所有目标路径 ──────────────────────────────────────────
69
69
  targets: list[str] = []
@@ -190,23 +190,13 @@ def build_backup_dir(
190
190
  return next(iter(dirs.keys()))
191
191
 
192
192
 
193
- def load_dir_suffixes(user_config: dict[str, Any]) -> list[str]:
194
- """合并硬编码底线 + user_config.ignore,去重返回目录名后缀列表。
193
+ def load_dir_suffixes() -> list[str]:
194
+ """返回硬编码的目录名后缀列表。
195
195
 
196
- 硬编码底线 ``".kmmbackup"`` 始终在列表中。
197
- user_config.ignore 中的条目自动补前导 ``.``(若缺失)。
196
+ 始终包含 ``".kmmbackup"``。
197
+ kmmignore 规则仅来自 ``.kmmignore`` 文件,不再通过此函数读取。
198
198
  """
199
- suffixes = [".kmmbackup"]
200
- config_ignore = user_config.get("ignore")
201
- if isinstance(config_ignore, list):
202
- for item in config_ignore:
203
- if isinstance(item, str) and item.strip():
204
- s = item.strip()
205
- if not s.startswith("."):
206
- s = "." + s
207
- if s not in suffixes:
208
- suffixes.append(s)
209
- return suffixes
199
+ return [".kmmbackup"]
210
200
 
211
201
 
212
202
  __all__ = [