machineconfig 8.14__py3-none-any.whl → 8.50__py3-none-any.whl

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.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

Files changed (273) hide show
  1. machineconfig/cluster/remote/run_cluster.py +1 -1
  2. machineconfig/cluster/remote/run_remote.py +1 -1
  3. machineconfig/cluster/sessions_managers/utils/maker.py +10 -8
  4. machineconfig/cluster/sessions_managers/wt_local.py +1 -1
  5. machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
  6. machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
  7. machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
  8. machineconfig/jobs/installer/checks/check_installations.py +133 -0
  9. machineconfig/jobs/installer/checks/install_utils.py +132 -0
  10. machineconfig/jobs/installer/checks/report_utils.py +39 -0
  11. machineconfig/jobs/installer/checks/vt_utils.py +89 -0
  12. machineconfig/jobs/installer/installer_data.json +225 -140
  13. machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
  14. machineconfig/jobs/installer/package_groups.py +10 -9
  15. machineconfig/jobs/installer/python_scripts/boxes.py +1 -2
  16. machineconfig/jobs/installer/python_scripts/code.py +10 -8
  17. machineconfig/jobs/installer/python_scripts/hx.py +30 -13
  18. machineconfig/jobs/installer/python_scripts/nerfont_windows_helper.py +6 -5
  19. machineconfig/jobs/installer/python_scripts/sysabc.py +25 -19
  20. machineconfig/jobs/installer/python_scripts/yazi.py +33 -17
  21. machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
  22. machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +1 -1
  23. machineconfig/jobs/scripts_dynamic/a.py +413 -10
  24. machineconfig/profile/create_links.py +77 -20
  25. machineconfig/profile/create_links_export.py +63 -58
  26. machineconfig/profile/mapper_data.toml +30 -0
  27. machineconfig/profile/mapper_dotfiles.toml +253 -0
  28. machineconfig/scripts/python/agents.py +70 -172
  29. machineconfig/scripts/python/ai/initai.py +3 -1
  30. machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
  31. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
  32. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +7 -5
  33. machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
  34. machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
  35. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +1 -1
  36. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +29 -0
  37. machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
  38. machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
  39. machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
  40. machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
  41. machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
  42. machineconfig/scripts/python/ai/utils/vscode_tasks.py +6 -3
  43. machineconfig/scripts/python/cloud.py +58 -11
  44. machineconfig/scripts/python/croshell.py +4 -156
  45. machineconfig/scripts/python/devops.py +57 -40
  46. machineconfig/scripts/python/devops_navigator.py +17 -3
  47. machineconfig/scripts/python/fire_jobs.py +8 -207
  48. machineconfig/scripts/python/ftpx.py +5 -225
  49. machineconfig/scripts/python/graph/cli_graph.json +8743 -0
  50. machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
  51. machineconfig/scripts/python/{env_manager → helpers/helper_env}/env_manager_tui.py +1 -1
  52. machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
  53. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.py +1 -1
  54. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +1 -1
  55. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_gemini.py +1 -1
  56. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_qwen.py +1 -1
  57. machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
  58. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_launch.py +5 -5
  59. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +6 -6
  60. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +10 -5
  61. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +3 -3
  62. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
  63. machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
  64. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
  65. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +7 -6
  66. machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
  67. machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +267 -0
  68. machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
  69. machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
  70. machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +76 -0
  71. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_nw.py +52 -72
  72. machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
  73. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +40 -23
  74. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_file.py +44 -30
  75. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_server.py +26 -43
  76. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_terminal.py +12 -6
  77. machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
  78. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +12 -6
  79. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
  80. machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +68 -52
  81. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/run_script.py +75 -58
  82. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
  83. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
  84. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +3 -3
  85. machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
  86. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +3 -3
  87. machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
  88. machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_linux/fzfg +4 -3
  89. machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
  90. machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_windows/fzfg.ps1 +1 -1
  91. machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
  92. machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
  93. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
  94. machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
  95. machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
  96. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
  97. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
  98. machineconfig/scripts/python/helpers/helpers_network/__init__.py +0 -0
  99. machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address.py +15 -17
  100. machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address_switch.py +1 -1
  101. machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
  102. machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_ssh.py +2 -2
  103. machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
  104. machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
  105. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
  106. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
  107. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
  108. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
  109. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +117 -33
  110. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +3 -2
  111. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -13
  112. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_2.py +63 -19
  113. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
  114. machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
  115. machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
  116. machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
  117. machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +1 -1
  118. machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
  119. machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
  120. machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/download.py +1 -1
  121. machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/python.py +47 -26
  122. machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
  123. machineconfig/scripts/python/mcfg_entry.py +133 -48
  124. machineconfig/scripts/python/msearch.py +15 -61
  125. machineconfig/scripts/python/sessions.py +59 -194
  126. machineconfig/scripts/python/terminal.py +18 -96
  127. machineconfig/scripts/python/utils.py +101 -20
  128. machineconfig/settings/atuin/config.toml +294 -0
  129. machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
  130. machineconfig/settings/linters/.ruff.toml +1 -0
  131. machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
  132. machineconfig/settings/shells/bash/init.sh +6 -3
  133. machineconfig/settings/shells/pwsh/init.ps1 +69 -1
  134. machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
  135. machineconfig/settings/shells/wezterm/wezterm.lua +4 -1
  136. machineconfig/settings/shells/wt/settings.json +20 -7
  137. machineconfig/settings/shells/zsh/init.sh +25 -4
  138. machineconfig/settings/television/cable_unix/bash-history.toml +1 -1
  139. machineconfig/settings/television/cable_windows/pwsh-history.toml +1 -1
  140. machineconfig/settings/tv/config.toml +234 -0
  141. machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
  142. machineconfig/settings/wsl/.wslconfig +5 -30
  143. machineconfig/settings/yazi/yazi_linux.toml +18 -8
  144. machineconfig/settings/zellij/layouts/st.kdl +2 -2
  145. machineconfig/settings/zellij/layouts/st2.kdl +1 -1
  146. machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
  147. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +3 -0
  148. machineconfig/setup_mac/__init__.py +0 -2
  149. machineconfig/setup_windows/__init__.py +0 -1
  150. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +14 -13
  151. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +4 -3
  152. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -3
  153. machineconfig/type_hinting/sql/__init__.py +1 -0
  154. machineconfig/type_hinting/sql/base.py +216 -0
  155. machineconfig/type_hinting/sql/core_schema.py +64 -0
  156. machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
  157. machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
  158. machineconfig/type_hinting/typedict/__init__.py +1 -0
  159. machineconfig/type_hinting/typedict/ast_utils.py +130 -0
  160. machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
  161. machineconfig/type_hinting/typedict/generators.py +231 -0
  162. machineconfig/type_hinting/typedict/polars_schema.py +24 -0
  163. machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
  164. machineconfig/utils/accessories.py +24 -0
  165. machineconfig/utils/code.py +41 -13
  166. machineconfig/utils/files/ascii_art.py +10 -14
  167. machineconfig/utils/files/headers.py +3 -5
  168. machineconfig/utils/files/read.py +8 -1
  169. machineconfig/utils/installer_utils/github_release_bulk.py +11 -91
  170. machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
  171. machineconfig/utils/installer_utils/install_from_url.py +1 -1
  172. machineconfig/utils/installer_utils/installer_class.py +12 -4
  173. machineconfig/utils/installer_utils/installer_cli.py +1 -15
  174. machineconfig/utils/installer_utils/installer_helper.py +2 -2
  175. machineconfig/utils/installer_utils/installer_locator_utils.py +13 -13
  176. machineconfig/utils/installer_utils/installer_runner.py +4 -4
  177. machineconfig/utils/io.py +25 -8
  178. machineconfig/utils/meta.py +6 -4
  179. machineconfig/utils/options.py +49 -19
  180. machineconfig/utils/options_utils/__init__.py +0 -0
  181. machineconfig/utils/options_utils/options_tv_linux.py +211 -0
  182. machineconfig/utils/options_utils/options_tv_windows.py +88 -0
  183. machineconfig/utils/options_utils/tv_options.py +37 -0
  184. machineconfig/utils/path_extended.py +6 -6
  185. machineconfig/utils/scheduler.py +8 -2
  186. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  187. machineconfig/utils/source_of_truth.py +6 -1
  188. machineconfig/utils/ssh.py +69 -18
  189. machineconfig/utils/ssh_utils/abc.py +1 -1
  190. machineconfig/utils/ssh_utils/copy_from_here.py +17 -12
  191. machineconfig/utils/ssh_utils/utils.py +21 -5
  192. machineconfig/utils/ssh_utils/wsl.py +107 -170
  193. machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
  194. machineconfig/utils/upgrade_packages.py +4 -8
  195. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/METADATA +29 -22
  196. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/RECORD +251 -211
  197. machineconfig/jobs/installer/check_installations.py +0 -248
  198. machineconfig/profile/backup.toml +0 -49
  199. machineconfig/profile/mapper.toml +0 -263
  200. machineconfig/scripts/python/helpers_devops/cli_config.py +0 -105
  201. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -89
  202. machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
  203. machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -208
  204. machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
  205. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
  206. machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
  207. machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
  208. machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -620
  209. machineconfig/scripts/python/helpers_network/ssh_add_identity.py +0 -116
  210. machineconfig/scripts/python/helpers_network/ssh_add_ssh_key.py +0 -153
  211. machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +0 -391
  212. machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +0 -338
  213. machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -77
  214. machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
  215. machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
  216. machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
  217. machineconfig/utils/options_tv.py +0 -119
  218. machineconfig/utils/tst.py +0 -20
  219. /machineconfig/{scripts/python/helpers_agents → jobs/installer/checks}/__init__.py +0 -0
  220. /machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
  221. /machineconfig/scripts/python/{helpers_agents/agentic_frameworks → graph}/__init__.py +0 -0
  222. /machineconfig/scripts/python/{helpers_cloud → helpers}/__init__.py +0 -0
  223. /machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
  224. /machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
  225. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_agents}/__init__.py +0 -0
  226. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_agents/agentic_frameworks}/__init__.py +0 -0
  227. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +0 -0
  228. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
  229. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_helper_types.py +0 -0
  230. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
  231. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aichat/config.yaml +0 -0
  232. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aider/.aider.conf.yml +0 -0
  233. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/copilot/config.yml +0 -0
  234. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/crush/crush.json +0 -0
  235. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/gemini/settings.json +0 -0
  236. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/privacy.py +0 -0
  237. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/prompt.txt +0 -0
  238. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.ps1 +0 -0
  239. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.sh +0 -0
  240. /machineconfig/scripts/python/{helpers_devops/themes → helpers/helpers_cloud}/__init__.py +0 -0
  241. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +0 -0
  242. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
  243. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_croshell}/__init__.py +0 -0
  244. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +0 -0
  245. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
  246. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
  247. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
  248. /machineconfig/scripts/python/{helpers_network → helpers/helpers_devops}/__init__.py +0 -0
  249. /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_devops/themes}/__init__.py +0 -0
  250. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
  251. /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_fire_command/__init__.py} +0 -0
  252. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
  253. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/f.py +0 -0
  254. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/file_wrangler.py +0 -0
  255. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +0 -0
  256. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_streamlit_helper.py +0 -0
  257. /machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/__init__.py +0 -0
  258. /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
  259. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nfs.py +0 -0
  260. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nw_drive.py +0 -0
  261. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/onetimeshare.py +0 -0
  262. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/wifi_conn.py +0 -0
  263. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -0
  264. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_1.py +0 -0
  265. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
  266. /machineconfig/scripts/python/helpers/{ast_search.py → helpers_search/ast_search.py} +0 -0
  267. /machineconfig/scripts/python/helpers/{qr_code.py → helpers_search/qr_code.py} +0 -0
  268. /machineconfig/scripts/python/helpers/{repo_rag.py → helpers_search/repo_rag.py} +0 -0
  269. /machineconfig/scripts/python/helpers/{symantic_search.py → helpers_search/symantic_search.py} +0 -0
  270. /machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/pdf.py +0 -0
  271. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/WHEEL +0 -0
  272. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/entry_points.txt +0 -0
  273. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,216 @@
1
+ # from uuid import uuid4
2
+ # import enum
3
+ # from datetime import date, datetime, time, timedelta
4
+
5
+ # import sqlalchemy as sa
6
+ # from sqlalchemy import (
7
+ # BigInteger,
8
+ # Boolean,
9
+ # CHAR,
10
+ # Date,
11
+ # DateTime,
12
+ # Float,
13
+ # Integer,
14
+ # Interval,
15
+ # LargeBinary,
16
+ # Numeric,
17
+ # SmallInteger,
18
+ # String,
19
+ # Text,
20
+ # Time,
21
+ # JSON,
22
+ # Enum,
23
+ # )
24
+ # from sqlalchemy.dialects.postgresql import (
25
+ # ARRAY,
26
+ # JSONB,
27
+ # UUID,
28
+ # )
29
+ # from sqlalchemy.orm import (
30
+ # DeclarativeBase,
31
+ # Mapped,
32
+ # mapped_column,
33
+ # )
34
+
35
+ # # Python enum type — stored generally as a VARCHAR or ENUM in the DB
36
+ # class ColorEnum(enum.Enum):
37
+ # RED = "red"
38
+ # GREEN = "green"
39
+ # BLUE = "blue"
40
+
41
+ # class Base(DeclarativeBase):
42
+ # pass
43
+
44
+ # class AllTypesExample(Base):
45
+ # __tablename__ = "all_types_example"
46
+
47
+ # # ----------------------------------
48
+ # # Integer types
49
+ # # ----------------------------------
50
+
51
+ # id: Mapped[int] = mapped_column(
52
+ # Integer,
53
+ # primary_key=True,
54
+ # comment="Typical SQL INTEGER (~int32 on many databases)"
55
+ # )
56
+
57
+ # small_num: Mapped[int] = mapped_column(
58
+ # SmallInteger,
59
+ # comment="SMALLINT (~int16)"
60
+ # )
61
+
62
+ # big_num: Mapped[int] = mapped_column(
63
+ # BigInteger,
64
+ # comment="BIGINT (~int64)"
65
+ # )
66
+
67
+ # # ----------------------------------
68
+ # # Floating-point & precision numbers
69
+ # # ----------------------------------
70
+
71
+ # float_num: Mapped[float] = mapped_column(
72
+ # Float,
73
+ # comment="FLOAT → typically float32/float64 depending on precision [Float maps to SQL FLOAT/REAL] (SQLAlchemy docs) :contentReference[oaicite:0]{index=0}"
74
+ # )
75
+
76
+ # decimal_value: Mapped[float] = mapped_column(
77
+ # Numeric(12, 4),
78
+ # comment="NUMERIC/DECIMAL fixed precision; client uses python Decimal by default (~exact decimal, not float)"
79
+ # )
80
+
81
+ # # ----------------------------------
82
+ # # Strings, text, character
83
+ # # ----------------------------------
84
+
85
+ # short_str: Mapped[str] = mapped_column(
86
+ # String(50),
87
+ # comment="VARCHAR(n) fixed limit"
88
+ # )
89
+
90
+ # long_text: Mapped[str] = mapped_column(
91
+ # Text,
92
+ # comment="TEXT (unbounded string)"
93
+ # )
94
+
95
+ # # ----------------------------------
96
+ # # Boolean
97
+ # # ----------------------------------
98
+
99
+ # is_active: Mapped[bool] = mapped_column(
100
+ # Boolean,
101
+ # comment="BOOLEAN (True/False)"
102
+ # )
103
+
104
+ # # ----------------------------------
105
+ # # Dates and times
106
+ # # ----------------------------------
107
+
108
+ # date_field: Mapped[date] = mapped_column(
109
+ # Date,
110
+ # comment="DATE only (year/month/day)"
111
+ # )
112
+
113
+ # time_field: Mapped[time] = mapped_column(
114
+ # Time,
115
+ # comment="TIME only (hh:mm:ss)"
116
+ # )
117
+
118
+ # datetime_field: Mapped[datetime] = mapped_column(
119
+ # DateTime,
120
+ # comment="TIMESTAMP without timezone"
121
+ # )
122
+
123
+ # interval_field: Mapped[timedelta] = mapped_column(
124
+ # Interval,
125
+ # comment="INTERVAL type (duration)"
126
+ # )
127
+
128
+ # # ----------------------------------
129
+ # # Binary / blobs
130
+ # # ----------------------------------
131
+
132
+ # binary_data: Mapped[bytes] = mapped_column(
133
+ # LargeBinary,
134
+ # comment="Large binary / BLOB"
135
+ # )
136
+
137
+ # # ----------------------------------
138
+ # # JSON
139
+ # # ----------------------------------
140
+
141
+ # json_data: Mapped[dict] = mapped_column(
142
+ # JSON,
143
+ # comment="Generic JSON type (engine specific)"
144
+ # )
145
+
146
+ # jsonb_data: Mapped[dict] = mapped_column(
147
+ # JSONB,
148
+ # comment="PostgreSQL JSONB (binary JSON)"
149
+ # )
150
+
151
+ # # ----------------------------------
152
+ # # Enum
153
+ # # ----------------------------------
154
+
155
+ # color: Mapped[ColorEnum] = mapped_column(
156
+ # Enum(ColorEnum),
157
+ # nullable=False,
158
+ # comment="ENUM type"
159
+ # )
160
+
161
+ # # ----------------------------------
162
+ # # UUID
163
+ # # ----------------------------------
164
+
165
+ # uuid_field: Mapped[str] = mapped_column(
166
+ # UUID(as_uuid=True),
167
+ # default=uuid4,
168
+ # comment="GUID/UUID (128-bit unique identifier)"
169
+ # )
170
+
171
+ # # ----------------------------------
172
+ # # Array — PostgreSQL only
173
+ # # ----------------------------------
174
+
175
+ # int_array: Mapped[list[int]] = mapped_column(
176
+ # ARRAY(Integer),
177
+ # comment="ARRAY of INTEGER (~list[int32])"
178
+ # )
179
+
180
+ # str_array: Mapped[list[str]] = mapped_column(
181
+ # ARRAY(String),
182
+ # comment="ARRAY of VARCHAR strings"
183
+ # )
184
+
185
+ # # ----------------------------------
186
+ # # Constraints & defaults
187
+ # # ----------------------------------
188
+
189
+ # unique_code: Mapped[str] = mapped_column(
190
+ # String(20),
191
+ # unique=True,
192
+ # nullable=False,
193
+ # comment="Unique code"
194
+ # )
195
+
196
+ # created_at: Mapped[datetime] = mapped_column(
197
+ # DateTime,
198
+ # server_default=sa.func.now(),
199
+ # comment="timestamp default now"
200
+ # )
201
+
202
+ # # ----------------------------------
203
+ # # Foreign key
204
+ # # ----------------------------------
205
+
206
+ # related_id: Mapped[int] = mapped_column(
207
+ # Integer,
208
+ # sa.ForeignKey("other_table.id"),
209
+ # comment="Foreign key reference"
210
+ # )
211
+
212
+
213
+ # if __name__ == "__main__":
214
+ # # Example usage: create the tables in an in-memory SQLite database
215
+ # q = AllTypesExample()
216
+ # q.created_at.__qualname__
@@ -0,0 +1,64 @@
1
+ import enum
2
+ from uuid import uuid4
3
+
4
+ import sqlalchemy as sa
5
+ from sqlalchemy import BigInteger, Boolean, Column, Date, DateTime, Float, ForeignKey, Integer, Interval, JSON, LargeBinary, MetaData, Numeric, SmallInteger, String, Table, Text, Time
6
+ from sqlalchemy.dialects.postgresql import ARRAY, JSONB, UUID
7
+
8
+
9
+ class ColorEnum(enum.Enum):
10
+ RED = "red"
11
+ GREEN = "green"
12
+ BLUE = "blue"
13
+
14
+
15
+ metadata: MetaData = MetaData()
16
+
17
+ other_table: Table = Table(
18
+ "other_table",
19
+ metadata,
20
+ Column("id", Integer, primary_key=True, comment="Referenced by all_types_example.related_id"),
21
+ )
22
+
23
+ all_types_example: Table = Table(
24
+ "all_types_example",
25
+ metadata,
26
+ Column("id", Integer, primary_key=True, comment="Typical SQL INTEGER (~int32 on many databases)"),
27
+ Column("small_num", SmallInteger, comment="SMALLINT (~int16)"),
28
+ Column("big_num", BigInteger, comment="BIGINT (~int64)"),
29
+ Column("float_num", Float, comment="FLOAT → typically float32/float64 depending on precision"),
30
+ Column(
31
+ "decimal_value",
32
+ Numeric(12, 4),
33
+ comment="NUMERIC/DECIMAL fixed precision; client uses python Decimal by default (~exact decimal, not float)",
34
+ ),
35
+ Column("short_str", String(50), comment="VARCHAR(n) fixed limit"),
36
+ Column("long_text", Text, comment="TEXT (unbounded string)"),
37
+ Column("is_active", Boolean, comment="BOOLEAN (True/False)"),
38
+ Column("date_field", Date, comment="DATE only (year/month/day)"),
39
+ Column("time_field", Time, comment="TIME only (hh:mm:ss)"),
40
+ Column("datetime_field", DateTime, comment="TIMESTAMP without timezone"),
41
+ Column("interval_field", Interval, comment="INTERVAL type (duration)"),
42
+ Column("binary_data", LargeBinary, comment="Large binary / BLOB"),
43
+ Column("json_data", JSON, comment="Generic JSON type (engine specific)"),
44
+ Column("jsonb_data", JSONB, comment="PostgreSQL JSONB (binary JSON)"),
45
+ Column("color", sa.Enum(ColorEnum), nullable=False, comment="ENUM type"),
46
+ Column("uuid_field", UUID(as_uuid=True), default=uuid4, comment="GUID/UUID (128-bit unique identifier)"),
47
+ Column("int_array", ARRAY(Integer), comment="ARRAY of INTEGER (~list[int32])"),
48
+ Column("str_array", ARRAY(String), comment="ARRAY of VARCHAR strings"),
49
+ Column("unique_code", String(20), unique=True, nullable=False, comment="Unique code"),
50
+ Column("created_at", DateTime, server_default=sa.func.now(), comment="timestamp default now"),
51
+ Column("related_id", Integer, ForeignKey("other_table.id"), comment="Foreign key reference"),
52
+ )
53
+
54
+
55
+ __all__: tuple[str, ...] = (
56
+ "ColorEnum",
57
+ "all_types_example",
58
+ "metadata",
59
+ "other_table",
60
+ )
61
+
62
+ if __name__ == "__main__":
63
+ q = all_types_example
64
+ # q.colo
@@ -0,0 +1,41 @@
1
+
2
+ from typing import Any, Literal, TypedDict, TypeAlias
3
+
4
+ import datetime
5
+ import decimal
6
+ import uuid
7
+
8
+ AllTypesExampleColor: TypeAlias = Literal["red", "green", "blue"]
9
+
10
+ class OtherTableRow(TypedDict):
11
+ id: int
12
+
13
+ class AllTypesExampleRow(TypedDict):
14
+ id: int
15
+ small_num: int | None
16
+ big_num: int | None
17
+ float_num: float | None
18
+ decimal_value: decimal.Decimal | None
19
+ short_str: str | None
20
+ long_text: str | None
21
+ is_active: bool | None
22
+ date_field: datetime.date | None
23
+ time_field: datetime.time | None
24
+ datetime_field: datetime.datetime | None
25
+ interval_field: datetime.timedelta | None
26
+ binary_data: bytes | None
27
+ json_data: Any | None
28
+ jsonb_data: Any | None
29
+ color: AllTypesExampleColor
30
+ uuid_field: uuid.UUID | None
31
+ int_array: list[int] | None
32
+ str_array: list[str] | None
33
+ unique_code: str
34
+ created_at: datetime.datetime | None
35
+ related_id: int | None
36
+
37
+ __all__: tuple[str, ...] = (
38
+ "OtherTableRow",
39
+ "AllTypesExampleRow",
40
+ "AllTypesExampleColor",
41
+ )
@@ -0,0 +1,222 @@
1
+
2
+ import enum
3
+ import re
4
+ from collections.abc import Sequence
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ import sqlalchemy as sa
10
+ from sqlalchemy.dialects.postgresql import ARRAY as PG_ARRAY
11
+ from sqlalchemy.dialects.postgresql import JSONB, UUID as PG_UUID
12
+ from sqlalchemy.sql.type_api import TypeEngine
13
+ from sqlalchemy.sql.sqltypes import (
14
+ BigInteger,
15
+ Boolean,
16
+ Date,
17
+ DateTime,
18
+ Float,
19
+ Integer,
20
+ Interval,
21
+ JSON,
22
+ LargeBinary,
23
+ Numeric,
24
+ SmallInteger,
25
+ String,
26
+ Text,
27
+ Time,
28
+ )
29
+
30
+
31
+ @dataclass(frozen=True, slots=True)
32
+ class GeneratedModule:
33
+ code: str
34
+ exports: tuple[str, ...]
35
+
36
+
37
+ def _pascal_case(value: str) -> str:
38
+ parts = [p for p in re.split(r"[^0-9A-Za-z]+", value) if p]
39
+ if not parts:
40
+ return "X"
41
+ return "".join(p[:1].upper() + p[1:] for p in parts)
42
+
43
+
44
+ def _identifier(value: str) -> str:
45
+ candidate = re.sub(r"[^0-9A-Za-z_]", "_", value)
46
+ if not candidate:
47
+ return "x"
48
+ if candidate[0].isdigit():
49
+ return f"x_{candidate}"
50
+ return candidate
51
+
52
+
53
+ def _enum_literal_alias_name(table_name: str, column_name: str) -> str:
54
+ return f"{_pascal_case(table_name)}{_pascal_case(column_name)}"
55
+
56
+
57
+ def _literal_union(values: Sequence[str]) -> str:
58
+ escaped = [v.replace("\\", "\\\\").replace('"', '\\"') for v in values]
59
+ return "Literal[" + ", ".join(f'"{v}"' for v in escaped) + "]"
60
+
61
+
62
+ @dataclass(frozen=True, slots=True)
63
+ class _TypeExpr:
64
+ expr: str
65
+ needs_datetime: bool
66
+ needs_decimal: bool
67
+ needs_uuid: bool
68
+ needs_any: bool
69
+ needs_literal: bool
70
+
71
+
72
+ def _union_with_none(type_expr: str, is_nullable: bool) -> str:
73
+ return f"{type_expr} | None" if is_nullable else type_expr
74
+
75
+
76
+ def _type_expr_for_sqla_type(*, column_type: TypeEngine[Any], table_name: str, column_name: str) -> tuple[_TypeExpr, dict[str, str]]:
77
+ enum_aliases: dict[str, str] = {}
78
+
79
+ if isinstance(column_type, (Integer, SmallInteger, BigInteger)):
80
+ return _TypeExpr("int", False, False, False, False, False), enum_aliases
81
+ if isinstance(column_type, Float):
82
+ return _TypeExpr("float", False, False, False, False, False), enum_aliases
83
+ if isinstance(column_type, Numeric):
84
+ return _TypeExpr("decimal.Decimal", False, True, False, False, False), enum_aliases
85
+
86
+ if hasattr(column_type, "enum_class"):
87
+ enum_class = getattr(column_type, "enum_class")
88
+ if isinstance(enum_class, type) and issubclass(enum_class, enum.Enum):
89
+ values = [str(member.value) for member in enum_class]
90
+ alias_name = _enum_literal_alias_name(table_name=table_name, column_name=column_name)
91
+ enum_aliases[alias_name] = _literal_union(values)
92
+ return _TypeExpr(alias_name, False, False, False, False, True), enum_aliases
93
+
94
+ if isinstance(column_type, (String, Text)):
95
+ return _TypeExpr("str", False, False, False, False, False), enum_aliases
96
+ if isinstance(column_type, Boolean):
97
+ return _TypeExpr("bool", False, False, False, False, False), enum_aliases
98
+ if isinstance(column_type, Date):
99
+ return _TypeExpr("datetime.date", True, False, False, False, False), enum_aliases
100
+ if isinstance(column_type, Time):
101
+ return _TypeExpr("datetime.time", True, False, False, False, False), enum_aliases
102
+ if isinstance(column_type, DateTime):
103
+ return _TypeExpr("datetime.datetime", True, False, False, False, False), enum_aliases
104
+ if isinstance(column_type, Interval):
105
+ return _TypeExpr("datetime.timedelta", True, False, False, False, False), enum_aliases
106
+ if isinstance(column_type, LargeBinary):
107
+ return _TypeExpr("bytes", False, False, False, False, False), enum_aliases
108
+
109
+ if isinstance(column_type, (JSON, JSONB)):
110
+ return _TypeExpr("Any", False, False, False, True, False), enum_aliases
111
+
112
+ if isinstance(column_type, PG_UUID):
113
+ return _TypeExpr("uuid.UUID", False, False, True, False, False), enum_aliases
114
+
115
+ if isinstance(column_type, PG_ARRAY):
116
+ item_type = column_type.item_type
117
+ item_expr, item_aliases = _type_expr_for_sqla_type(column_type=item_type, table_name=table_name, column_name=column_name)
118
+ enum_aliases |= item_aliases
119
+ return (
120
+ _TypeExpr(f"list[{item_expr.expr}]", item_expr.needs_datetime, item_expr.needs_decimal, item_expr.needs_uuid, item_expr.needs_any, item_expr.needs_literal),
121
+ enum_aliases,
122
+ )
123
+
124
+ return _TypeExpr("Any", False, False, False, True, False), enum_aliases
125
+
126
+
127
+ def generate_typeddict_module_code_for_tables(*, tables: Sequence[sa.Table], module_name: str) -> GeneratedModule:
128
+ alias_defs: dict[str, str] = {}
129
+ typed_dict_defs: list[str] = []
130
+
131
+ needs_datetime = False
132
+ needs_decimal = False
133
+ needs_uuid = False
134
+ needs_any = False
135
+ needs_literal = False
136
+
137
+ exports: list[str] = []
138
+
139
+ for table in tables:
140
+ table_name = table.name
141
+ td_name = f"{_pascal_case(table_name)}Row"
142
+ exports.append(td_name)
143
+
144
+ lines: list[str] = [f"class {td_name}(TypedDict):"]
145
+ for column in table.columns:
146
+ col_name = column.name
147
+ type_expr, new_aliases = _type_expr_for_sqla_type(column_type=column.type, table_name=table_name, column_name=col_name)
148
+ alias_defs |= new_aliases
149
+
150
+ needs_datetime = needs_datetime or type_expr.needs_datetime
151
+ needs_decimal = needs_decimal or type_expr.needs_decimal
152
+ needs_uuid = needs_uuid or type_expr.needs_uuid
153
+ needs_any = needs_any or type_expr.needs_any
154
+ needs_literal = needs_literal or type_expr.needs_literal
155
+
156
+ field_name = _identifier(col_name)
157
+ field_type = _union_with_none(type_expr.expr, column.nullable)
158
+ lines.append(f" {field_name}: {field_type}")
159
+
160
+ typed_dict_defs.append("\n".join(lines))
161
+
162
+ for alias_name in sorted(alias_defs.keys()):
163
+ exports.append(alias_name)
164
+
165
+ _ = module_name
166
+
167
+ typing_import_names: list[str] = ["TypedDict"]
168
+ if alias_defs:
169
+ typing_import_names.append("TypeAlias")
170
+ if needs_any:
171
+ typing_import_names.insert(0, "Any")
172
+ if needs_literal:
173
+ typing_import_names.insert(0 if not needs_any else 1, "Literal")
174
+
175
+ import_lines: list[str] = [
176
+ "",
177
+ f"from typing import {', '.join(typing_import_names)}",
178
+ ]
179
+
180
+ stdlib_imports: list[str] = []
181
+ if needs_datetime:
182
+ stdlib_imports.append("import datetime")
183
+ if needs_decimal:
184
+ stdlib_imports.append("import decimal")
185
+ if needs_uuid:
186
+ stdlib_imports.append("import uuid")
187
+ if stdlib_imports:
188
+ import_lines.extend(["", *stdlib_imports])
189
+
190
+ code_parts: list[str] = []
191
+ code_parts.extend(import_lines)
192
+
193
+ if alias_defs:
194
+ code_parts.append("")
195
+ for alias_name in sorted(alias_defs.keys()):
196
+ literal_expr = alias_defs[alias_name]
197
+ code_parts.append(f"{alias_name}: TypeAlias = {literal_expr}")
198
+
199
+ code_parts.append("")
200
+ code_parts.append("\n\n".join(typed_dict_defs))
201
+
202
+ exports_tuple = tuple(exports)
203
+ exports_rendered = ",\n ".join(f"\"{name}\"" for name in exports_tuple)
204
+ code_parts.append("")
205
+ code_parts.append("__all__: tuple[str, ...] = (\n " + exports_rendered + ",\n)\n")
206
+
207
+ return GeneratedModule(code="\n".join(code_parts), exports=exports_tuple)
208
+
209
+
210
+ def generate_typeddict_module_code_for_table(*, table: sa.Table, module_name: str) -> GeneratedModule:
211
+ return generate_typeddict_module_code_for_tables(tables=(table,), module_name=module_name)
212
+
213
+
214
+ def write_generated_module(*, generated: GeneratedModule, output_path: Path) -> None:
215
+ output_path.parent.mkdir(parents=True, exist_ok=True)
216
+ output_path.write_text(generated.code, encoding="utf-8")
217
+
218
+
219
+ def write_typeddict_module_next_to_source(*, generated: GeneratedModule, source_file_path: Path) -> Path:
220
+ output_path = source_file_path.with_name(f"{source_file_path.stem}_typeddict.py")
221
+ write_generated_module(generated=generated, output_path=output_path)
222
+ return output_path
@@ -0,0 +1,130 @@
1
+ import ast
2
+ from pathlib import Path
3
+ from dataclasses import dataclass, field
4
+
5
+
6
+ type FieldInfo = tuple[str, ast.expr | None, dict[str, tuple[str, str]]]
7
+ type ClassFields = tuple[str, list[FieldInfo]]
8
+
9
+ _file_cache: dict[Path, ast.Module] = {}
10
+
11
+
12
+ def _get_ast(path: Path) -> ast.Module:
13
+ if path not in _file_cache:
14
+ _file_cache[path] = ast.parse(path.read_text(encoding="utf-8"))
15
+ return _file_cache[path]
16
+
17
+
18
+ @dataclass
19
+ class FileContext:
20
+ path: Path
21
+ tree: ast.Module
22
+ classes: dict[str, ast.ClassDef] = field(default_factory=dict)
23
+ imports: dict[str, tuple[str, str]] = field(default_factory=dict)
24
+
25
+ def __post_init__(self):
26
+ self.classes = {node.name: node for node in ast.walk(self.tree) if isinstance(node, ast.ClassDef)}
27
+ for node in ast.walk(self.tree):
28
+ if isinstance(node, ast.ImportFrom) and node.module:
29
+ for alias in node.names:
30
+ self.imports[alias.asname or alias.name] = (node.module, alias.name)
31
+
32
+
33
+ def _get_context(path: Path) -> FileContext:
34
+ tree = _get_ast(path)
35
+ return FileContext(path, tree)
36
+
37
+
38
+ def _resolve_imported_class(module_name: str, class_name: str, search_paths: list[Path]) -> tuple[ast.ClassDef, FileContext] | None:
39
+ parts = module_name.split(".")
40
+ for root in search_paths:
41
+ file_path = root.joinpath(*parts).with_suffix(".py")
42
+ if file_path.exists():
43
+ try:
44
+ context = _get_context(file_path)
45
+ if class_name in context.classes:
46
+ return context.classes[class_name], context
47
+ except Exception:
48
+ pass
49
+ init_path = root.joinpath(*parts, "__init__.py")
50
+ if init_path.exists():
51
+ try:
52
+ context = _get_context(init_path)
53
+ if class_name in context.classes:
54
+ return context.classes[class_name], context
55
+ except Exception:
56
+ pass
57
+ return None
58
+
59
+
60
+ def load_target_class_fields(source_file_path: Path, search_paths: list[Path] | None = None) -> list[ClassFields]:
61
+ source_path = Path(source_file_path).resolve()
62
+ if search_paths is None:
63
+ search_paths = []
64
+
65
+ if not source_path.exists():
66
+ raise FileNotFoundError(f"Source file not found: {source_path}")
67
+
68
+ initial_context = _get_context(source_path)
69
+
70
+ def get_parent_node(base: ast.expr, context: FileContext) -> tuple[ast.ClassDef, FileContext] | None:
71
+ if isinstance(base, ast.Name):
72
+ if base.id in context.classes:
73
+ return context.classes[base.id], context
74
+ if base.id in context.imports:
75
+ module_name, original_name = context.imports[base.id]
76
+ return _resolve_imported_class(module_name, original_name, search_paths) # type: ignore
77
+ return None
78
+
79
+ def collect_fields(class_node: ast.ClassDef, context: FileContext, visited: set[str]) -> list[FieldInfo]:
80
+ key = f"{context.path}:{class_node.name}"
81
+ if key in visited:
82
+ return []
83
+ visited.add(key)
84
+ field_info: list[FieldInfo] = []
85
+ for base in class_node.bases:
86
+ parent_info = get_parent_node(base, context)
87
+ if parent_info:
88
+ parent_node, parent_context = parent_info
89
+ field_info.extend(collect_fields(parent_node, parent_context, visited))
90
+ for statement in class_node.body:
91
+ if isinstance(statement, ast.AnnAssign) and isinstance(statement.target, ast.Name):
92
+ field_info.append((statement.target.id, statement.annotation, context.imports))
93
+ return field_info
94
+
95
+ def deduplicate_fields(fields: list[FieldInfo]) -> list[FieldInfo]:
96
+ deduped: dict[str, FieldInfo] = {}
97
+ for item in fields:
98
+ field_name = item[0]
99
+ deduped[field_name] = item
100
+ return list(deduped.values())
101
+
102
+ def is_typeddict(node: ast.ClassDef, context: FileContext, visited: set[str]) -> bool:
103
+ key = f"{context.path}:{node.name}"
104
+ if key in visited:
105
+ return False
106
+ visited.add(key)
107
+ for base in node.bases:
108
+ if (isinstance(base, ast.Name) and base.id == "TypedDict") or (isinstance(base, ast.Attribute) and base.attr == "TypedDict"):
109
+ return True
110
+ parent_info = get_parent_node(base, context)
111
+ if parent_info:
112
+ parent_node, parent_context = parent_info
113
+ if is_typeddict(parent_node, parent_context, visited):
114
+ return True
115
+ return False
116
+
117
+ target_classes: list[ClassFields] = []
118
+ for node in ast.walk(initial_context.tree):
119
+ if not isinstance(node, ast.ClassDef):
120
+ continue
121
+ is_dataclass = any(
122
+ (isinstance(decorator, ast.Name) and decorator.id == "dataclass")
123
+ or (isinstance(decorator, ast.Attribute) and decorator.attr == "dataclass")
124
+ or (isinstance(decorator, ast.Call) and ((isinstance(decorator.func, ast.Name) and decorator.func.id == "dataclass") or (isinstance(decorator.func, ast.Attribute) and decorator.func.attr == "dataclass")))
125
+ for decorator in node.decorator_list
126
+ )
127
+ if is_dataclass or is_typeddict(node, initial_context, set()):
128
+ fields = collect_fields(node, initial_context, set())
129
+ target_classes.append((node.name, deduplicate_fields(fields)))
130
+ return target_classes