pycforge-sdk 0.6.3__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.
Files changed (559) hide show
  1. pycforge_sdk/__init__.py +6 -0
  2. pycforge_sdk/__main__.py +3 -0
  3. pycforge_sdk/catalogue.py +287 -0
  4. pycforge_sdk/cli.py +114 -0
  5. pycforge_sdk/connection.py +136 -0
  6. pycforge_sdk/discovery.py +227 -0
  7. pycforge_sdk/editing.py +84 -0
  8. pycforge_sdk/engine_launch.py +45 -0
  9. pycforge_sdk/engine_worker.py +53 -0
  10. pycforge_sdk/gui/__init__.py +1 -0
  11. pycforge_sdk/gui/__main__.py +3 -0
  12. pycforge_sdk/gui/app.py +36 -0
  13. pycforge_sdk/gui/dialogs.py +310 -0
  14. pycforge_sdk/gui/editor.py +412 -0
  15. pycforge_sdk/gui/help/index.html +9 -0
  16. pycforge_sdk/gui/identity.py +139 -0
  17. pycforge_sdk/gui/jobs.py +146 -0
  18. pycforge_sdk/gui/reference.py +39 -0
  19. pycforge_sdk/gui/resources/sdk-mark.png +0 -0
  20. pycforge_sdk/gui/scanner.py +134 -0
  21. pycforge_sdk/gui/startup.py +118 -0
  22. pycforge_sdk/gui/visual/__init__.py +1 -0
  23. pycforge_sdk/gui/visual/action_contract.py +550 -0
  24. pycforge_sdk/gui/visual/icons.py +117 -0
  25. pycforge_sdk/gui/visual/qt_actions.py +501 -0
  26. pycforge_sdk/gui/visual/qt_branding.py +47 -0
  27. pycforge_sdk/gui/visual/qt_dialog_chrome.py +337 -0
  28. pycforge_sdk/gui/visual/qt_file_icons.py +130 -0
  29. pycforge_sdk/gui/visual/qt_icons.py +80 -0
  30. pycforge_sdk/gui/visual/qt_screen_geometry.py +166 -0
  31. pycforge_sdk/gui/visual/qt_title_controls.py +333 -0
  32. pycforge_sdk/gui/visual/qt_window_chrome.py +314 -0
  33. pycforge_sdk/gui/visual/qt_window_resize.py +93 -0
  34. pycforge_sdk/gui/visual/qt_workspace_widgets.py +448 -0
  35. pycforge_sdk/gui/visual/resources/icons/128/add-document.png +0 -0
  36. pycforge_sdk/gui/visual/resources/icons/128/brand-mark.png +0 -0
  37. pycforge_sdk/gui/visual/resources/icons/128/bundle-search.png +0 -0
  38. pycforge_sdk/gui/visual/resources/icons/128/cancel.png +0 -0
  39. pycforge_sdk/gui/visual/resources/icons/128/check.png +0 -0
  40. pycforge_sdk/gui/visual/resources/icons/128/chevron-right.png +0 -0
  41. pycforge_sdk/gui/visual/resources/icons/128/close.png +0 -0
  42. pycforge_sdk/gui/visual/resources/icons/128/collapse-all.png +0 -0
  43. pycforge_sdk/gui/visual/resources/icons/128/command-palette.png +0 -0
  44. pycforge_sdk/gui/visual/resources/icons/128/convert.png +0 -0
  45. pycforge_sdk/gui/visual/resources/icons/128/copy.png +0 -0
  46. pycforge_sdk/gui/visual/resources/icons/128/cut.png +0 -0
  47. pycforge_sdk/gui/visual/resources/icons/128/decision-trace.png +0 -0
  48. pycforge_sdk/gui/visual/resources/icons/128/details.png +0 -0
  49. pycforge_sdk/gui/visual/resources/icons/128/diagnostics.png +0 -0
  50. pycforge_sdk/gui/visual/resources/icons/128/duplicate-line.png +0 -0
  51. pycforge_sdk/gui/visual/resources/icons/128/exit.png +0 -0
  52. pycforge_sdk/gui/visual/resources/icons/128/expand-all.png +0 -0
  53. pycforge_sdk/gui/visual/resources/icons/128/export.png +0 -0
  54. pycforge_sdk/gui/visual/resources/icons/128/find.png +0 -0
  55. pycforge_sdk/gui/visual/resources/icons/128/go-to-line.png +0 -0
  56. pycforge_sdk/gui/visual/resources/icons/128/go-to-output.png +0 -0
  57. pycforge_sdk/gui/visual/resources/icons/128/go-to-source.png +0 -0
  58. pycforge_sdk/gui/visual/resources/icons/128/help.png +0 -0
  59. pycforge_sdk/gui/visual/resources/icons/128/history.png +0 -0
  60. pycforge_sdk/gui/visual/resources/icons/128/indent.png +0 -0
  61. pycforge_sdk/gui/visual/resources/icons/128/link-c.png +0 -0
  62. pycforge_sdk/gui/visual/resources/icons/128/mappings.png +0 -0
  63. pycforge_sdk/gui/visual/resources/icons/128/module.png +0 -0
  64. pycforge_sdk/gui/visual/resources/icons/128/move-down.png +0 -0
  65. pycforge_sdk/gui/visual/resources/icons/128/move-line-down.png +0 -0
  66. pycforge_sdk/gui/visual/resources/icons/128/move-line-up.png +0 -0
  67. pycforge_sdk/gui/visual/resources/icons/128/move-up.png +0 -0
  68. pycforge_sdk/gui/visual/resources/icons/128/next.png +0 -0
  69. pycforge_sdk/gui/visual/resources/icons/128/open.png +0 -0
  70. pycforge_sdk/gui/visual/resources/icons/128/outdent.png +0 -0
  71. pycforge_sdk/gui/visual/resources/icons/128/outline.png +0 -0
  72. pycforge_sdk/gui/visual/resources/icons/128/paste.png +0 -0
  73. pycforge_sdk/gui/visual/resources/icons/128/previous.png +0 -0
  74. pycforge_sdk/gui/visual/resources/icons/128/primary-module.png +0 -0
  75. pycforge_sdk/gui/visual/resources/icons/128/redo.png +0 -0
  76. pycforge_sdk/gui/visual/resources/icons/128/remove-document.png +0 -0
  77. pycforge_sdk/gui/visual/resources/icons/128/replace.png +0 -0
  78. pycforge_sdk/gui/visual/resources/icons/128/save-as.png +0 -0
  79. pycforge_sdk/gui/visual/resources/icons/128/save.png +0 -0
  80. pycforge_sdk/gui/visual/resources/icons/128/select-all.png +0 -0
  81. pycforge_sdk/gui/visual/resources/icons/128/settings.png +0 -0
  82. pycforge_sdk/gui/visual/resources/icons/128/show-c.png +0 -0
  83. pycforge_sdk/gui/visual/resources/icons/128/split-view.png +0 -0
  84. pycforge_sdk/gui/visual/resources/icons/128/summary.png +0 -0
  85. pycforge_sdk/gui/visual/resources/icons/128/telemetry.png +0 -0
  86. pycforge_sdk/gui/visual/resources/icons/128/toggle-comment.png +0 -0
  87. pycforge_sdk/gui/visual/resources/icons/128/toggle-fold.png +0 -0
  88. pycforge_sdk/gui/visual/resources/icons/128/tools.png +0 -0
  89. pycforge_sdk/gui/visual/resources/icons/128/undo.png +0 -0
  90. pycforge_sdk/gui/visual/resources/icons/128/whitespace.png +0 -0
  91. pycforge_sdk/gui/visual/resources/icons/16/add-document.png +0 -0
  92. pycforge_sdk/gui/visual/resources/icons/16/brand-mark.png +0 -0
  93. pycforge_sdk/gui/visual/resources/icons/16/bundle-search.png +0 -0
  94. pycforge_sdk/gui/visual/resources/icons/16/cancel.png +0 -0
  95. pycforge_sdk/gui/visual/resources/icons/16/check.png +0 -0
  96. pycforge_sdk/gui/visual/resources/icons/16/chevron-right.png +0 -0
  97. pycforge_sdk/gui/visual/resources/icons/16/close.png +0 -0
  98. pycforge_sdk/gui/visual/resources/icons/16/collapse-all.png +0 -0
  99. pycforge_sdk/gui/visual/resources/icons/16/command-palette.png +0 -0
  100. pycforge_sdk/gui/visual/resources/icons/16/convert.png +0 -0
  101. pycforge_sdk/gui/visual/resources/icons/16/copy.png +0 -0
  102. pycforge_sdk/gui/visual/resources/icons/16/cut.png +0 -0
  103. pycforge_sdk/gui/visual/resources/icons/16/decision-trace.png +0 -0
  104. pycforge_sdk/gui/visual/resources/icons/16/details.png +0 -0
  105. pycforge_sdk/gui/visual/resources/icons/16/diagnostics.png +0 -0
  106. pycforge_sdk/gui/visual/resources/icons/16/duplicate-line.png +0 -0
  107. pycforge_sdk/gui/visual/resources/icons/16/exit.png +0 -0
  108. pycforge_sdk/gui/visual/resources/icons/16/expand-all.png +0 -0
  109. pycforge_sdk/gui/visual/resources/icons/16/export.png +0 -0
  110. pycforge_sdk/gui/visual/resources/icons/16/find.png +0 -0
  111. pycforge_sdk/gui/visual/resources/icons/16/go-to-line.png +0 -0
  112. pycforge_sdk/gui/visual/resources/icons/16/go-to-output.png +0 -0
  113. pycforge_sdk/gui/visual/resources/icons/16/go-to-source.png +0 -0
  114. pycforge_sdk/gui/visual/resources/icons/16/help.png +0 -0
  115. pycforge_sdk/gui/visual/resources/icons/16/history.png +0 -0
  116. pycforge_sdk/gui/visual/resources/icons/16/indent.png +0 -0
  117. pycforge_sdk/gui/visual/resources/icons/16/link-c.png +0 -0
  118. pycforge_sdk/gui/visual/resources/icons/16/mappings.png +0 -0
  119. pycforge_sdk/gui/visual/resources/icons/16/module.png +0 -0
  120. pycforge_sdk/gui/visual/resources/icons/16/move-down.png +0 -0
  121. pycforge_sdk/gui/visual/resources/icons/16/move-line-down.png +0 -0
  122. pycforge_sdk/gui/visual/resources/icons/16/move-line-up.png +0 -0
  123. pycforge_sdk/gui/visual/resources/icons/16/move-up.png +0 -0
  124. pycforge_sdk/gui/visual/resources/icons/16/next.png +0 -0
  125. pycforge_sdk/gui/visual/resources/icons/16/open.png +0 -0
  126. pycforge_sdk/gui/visual/resources/icons/16/outdent.png +0 -0
  127. pycforge_sdk/gui/visual/resources/icons/16/outline.png +0 -0
  128. pycforge_sdk/gui/visual/resources/icons/16/paste.png +0 -0
  129. pycforge_sdk/gui/visual/resources/icons/16/previous.png +0 -0
  130. pycforge_sdk/gui/visual/resources/icons/16/primary-module.png +0 -0
  131. pycforge_sdk/gui/visual/resources/icons/16/redo.png +0 -0
  132. pycforge_sdk/gui/visual/resources/icons/16/remove-document.png +0 -0
  133. pycforge_sdk/gui/visual/resources/icons/16/replace.png +0 -0
  134. pycforge_sdk/gui/visual/resources/icons/16/save-as.png +0 -0
  135. pycforge_sdk/gui/visual/resources/icons/16/save.png +0 -0
  136. pycforge_sdk/gui/visual/resources/icons/16/select-all.png +0 -0
  137. pycforge_sdk/gui/visual/resources/icons/16/settings.png +0 -0
  138. pycforge_sdk/gui/visual/resources/icons/16/show-c.png +0 -0
  139. pycforge_sdk/gui/visual/resources/icons/16/split-view.png +0 -0
  140. pycforge_sdk/gui/visual/resources/icons/16/summary.png +0 -0
  141. pycforge_sdk/gui/visual/resources/icons/16/telemetry.png +0 -0
  142. pycforge_sdk/gui/visual/resources/icons/16/toggle-comment.png +0 -0
  143. pycforge_sdk/gui/visual/resources/icons/16/toggle-fold.png +0 -0
  144. pycforge_sdk/gui/visual/resources/icons/16/tools.png +0 -0
  145. pycforge_sdk/gui/visual/resources/icons/16/undo.png +0 -0
  146. pycforge_sdk/gui/visual/resources/icons/16/whitespace.png +0 -0
  147. pycforge_sdk/gui/visual/resources/icons/20/add-document.png +0 -0
  148. pycforge_sdk/gui/visual/resources/icons/20/brand-mark.png +0 -0
  149. pycforge_sdk/gui/visual/resources/icons/20/bundle-search.png +0 -0
  150. pycforge_sdk/gui/visual/resources/icons/20/cancel.png +0 -0
  151. pycforge_sdk/gui/visual/resources/icons/20/check.png +0 -0
  152. pycforge_sdk/gui/visual/resources/icons/20/chevron-right.png +0 -0
  153. pycforge_sdk/gui/visual/resources/icons/20/close.png +0 -0
  154. pycforge_sdk/gui/visual/resources/icons/20/collapse-all.png +0 -0
  155. pycforge_sdk/gui/visual/resources/icons/20/command-palette.png +0 -0
  156. pycforge_sdk/gui/visual/resources/icons/20/convert.png +0 -0
  157. pycforge_sdk/gui/visual/resources/icons/20/copy.png +0 -0
  158. pycforge_sdk/gui/visual/resources/icons/20/cut.png +0 -0
  159. pycforge_sdk/gui/visual/resources/icons/20/decision-trace.png +0 -0
  160. pycforge_sdk/gui/visual/resources/icons/20/details.png +0 -0
  161. pycforge_sdk/gui/visual/resources/icons/20/diagnostics.png +0 -0
  162. pycforge_sdk/gui/visual/resources/icons/20/duplicate-line.png +0 -0
  163. pycforge_sdk/gui/visual/resources/icons/20/exit.png +0 -0
  164. pycforge_sdk/gui/visual/resources/icons/20/expand-all.png +0 -0
  165. pycforge_sdk/gui/visual/resources/icons/20/export.png +0 -0
  166. pycforge_sdk/gui/visual/resources/icons/20/find.png +0 -0
  167. pycforge_sdk/gui/visual/resources/icons/20/go-to-line.png +0 -0
  168. pycforge_sdk/gui/visual/resources/icons/20/go-to-output.png +0 -0
  169. pycforge_sdk/gui/visual/resources/icons/20/go-to-source.png +0 -0
  170. pycforge_sdk/gui/visual/resources/icons/20/help.png +0 -0
  171. pycforge_sdk/gui/visual/resources/icons/20/history.png +0 -0
  172. pycforge_sdk/gui/visual/resources/icons/20/indent.png +0 -0
  173. pycforge_sdk/gui/visual/resources/icons/20/link-c.png +0 -0
  174. pycforge_sdk/gui/visual/resources/icons/20/mappings.png +0 -0
  175. pycforge_sdk/gui/visual/resources/icons/20/module.png +0 -0
  176. pycforge_sdk/gui/visual/resources/icons/20/move-down.png +0 -0
  177. pycforge_sdk/gui/visual/resources/icons/20/move-line-down.png +0 -0
  178. pycforge_sdk/gui/visual/resources/icons/20/move-line-up.png +0 -0
  179. pycforge_sdk/gui/visual/resources/icons/20/move-up.png +0 -0
  180. pycforge_sdk/gui/visual/resources/icons/20/next.png +0 -0
  181. pycforge_sdk/gui/visual/resources/icons/20/open.png +0 -0
  182. pycforge_sdk/gui/visual/resources/icons/20/outdent.png +0 -0
  183. pycforge_sdk/gui/visual/resources/icons/20/outline.png +0 -0
  184. pycforge_sdk/gui/visual/resources/icons/20/paste.png +0 -0
  185. pycforge_sdk/gui/visual/resources/icons/20/previous.png +0 -0
  186. pycforge_sdk/gui/visual/resources/icons/20/primary-module.png +0 -0
  187. pycforge_sdk/gui/visual/resources/icons/20/redo.png +0 -0
  188. pycforge_sdk/gui/visual/resources/icons/20/remove-document.png +0 -0
  189. pycforge_sdk/gui/visual/resources/icons/20/replace.png +0 -0
  190. pycforge_sdk/gui/visual/resources/icons/20/save-as.png +0 -0
  191. pycforge_sdk/gui/visual/resources/icons/20/save.png +0 -0
  192. pycforge_sdk/gui/visual/resources/icons/20/select-all.png +0 -0
  193. pycforge_sdk/gui/visual/resources/icons/20/settings.png +0 -0
  194. pycforge_sdk/gui/visual/resources/icons/20/show-c.png +0 -0
  195. pycforge_sdk/gui/visual/resources/icons/20/split-view.png +0 -0
  196. pycforge_sdk/gui/visual/resources/icons/20/summary.png +0 -0
  197. pycforge_sdk/gui/visual/resources/icons/20/telemetry.png +0 -0
  198. pycforge_sdk/gui/visual/resources/icons/20/toggle-comment.png +0 -0
  199. pycforge_sdk/gui/visual/resources/icons/20/toggle-fold.png +0 -0
  200. pycforge_sdk/gui/visual/resources/icons/20/tools.png +0 -0
  201. pycforge_sdk/gui/visual/resources/icons/20/undo.png +0 -0
  202. pycforge_sdk/gui/visual/resources/icons/20/whitespace.png +0 -0
  203. pycforge_sdk/gui/visual/resources/icons/24/add-document.png +0 -0
  204. pycforge_sdk/gui/visual/resources/icons/24/brand-mark.png +0 -0
  205. pycforge_sdk/gui/visual/resources/icons/24/bundle-search.png +0 -0
  206. pycforge_sdk/gui/visual/resources/icons/24/cancel.png +0 -0
  207. pycforge_sdk/gui/visual/resources/icons/24/check.png +0 -0
  208. pycforge_sdk/gui/visual/resources/icons/24/chevron-right.png +0 -0
  209. pycforge_sdk/gui/visual/resources/icons/24/close.png +0 -0
  210. pycforge_sdk/gui/visual/resources/icons/24/collapse-all.png +0 -0
  211. pycforge_sdk/gui/visual/resources/icons/24/command-palette.png +0 -0
  212. pycforge_sdk/gui/visual/resources/icons/24/convert.png +0 -0
  213. pycforge_sdk/gui/visual/resources/icons/24/copy.png +0 -0
  214. pycforge_sdk/gui/visual/resources/icons/24/cut.png +0 -0
  215. pycforge_sdk/gui/visual/resources/icons/24/decision-trace.png +0 -0
  216. pycforge_sdk/gui/visual/resources/icons/24/details.png +0 -0
  217. pycforge_sdk/gui/visual/resources/icons/24/diagnostics.png +0 -0
  218. pycforge_sdk/gui/visual/resources/icons/24/duplicate-line.png +0 -0
  219. pycforge_sdk/gui/visual/resources/icons/24/exit.png +0 -0
  220. pycforge_sdk/gui/visual/resources/icons/24/expand-all.png +0 -0
  221. pycforge_sdk/gui/visual/resources/icons/24/export.png +0 -0
  222. pycforge_sdk/gui/visual/resources/icons/24/find.png +0 -0
  223. pycforge_sdk/gui/visual/resources/icons/24/go-to-line.png +0 -0
  224. pycforge_sdk/gui/visual/resources/icons/24/go-to-output.png +0 -0
  225. pycforge_sdk/gui/visual/resources/icons/24/go-to-source.png +0 -0
  226. pycforge_sdk/gui/visual/resources/icons/24/help.png +0 -0
  227. pycforge_sdk/gui/visual/resources/icons/24/history.png +0 -0
  228. pycforge_sdk/gui/visual/resources/icons/24/indent.png +0 -0
  229. pycforge_sdk/gui/visual/resources/icons/24/link-c.png +0 -0
  230. pycforge_sdk/gui/visual/resources/icons/24/mappings.png +0 -0
  231. pycforge_sdk/gui/visual/resources/icons/24/module.png +0 -0
  232. pycforge_sdk/gui/visual/resources/icons/24/move-down.png +0 -0
  233. pycforge_sdk/gui/visual/resources/icons/24/move-line-down.png +0 -0
  234. pycforge_sdk/gui/visual/resources/icons/24/move-line-up.png +0 -0
  235. pycforge_sdk/gui/visual/resources/icons/24/move-up.png +0 -0
  236. pycforge_sdk/gui/visual/resources/icons/24/next.png +0 -0
  237. pycforge_sdk/gui/visual/resources/icons/24/open.png +0 -0
  238. pycforge_sdk/gui/visual/resources/icons/24/outdent.png +0 -0
  239. pycforge_sdk/gui/visual/resources/icons/24/outline.png +0 -0
  240. pycforge_sdk/gui/visual/resources/icons/24/paste.png +0 -0
  241. pycforge_sdk/gui/visual/resources/icons/24/previous.png +0 -0
  242. pycforge_sdk/gui/visual/resources/icons/24/primary-module.png +0 -0
  243. pycforge_sdk/gui/visual/resources/icons/24/redo.png +0 -0
  244. pycforge_sdk/gui/visual/resources/icons/24/remove-document.png +0 -0
  245. pycforge_sdk/gui/visual/resources/icons/24/replace.png +0 -0
  246. pycforge_sdk/gui/visual/resources/icons/24/save-as.png +0 -0
  247. pycforge_sdk/gui/visual/resources/icons/24/save.png +0 -0
  248. pycforge_sdk/gui/visual/resources/icons/24/select-all.png +0 -0
  249. pycforge_sdk/gui/visual/resources/icons/24/settings.png +0 -0
  250. pycforge_sdk/gui/visual/resources/icons/24/show-c.png +0 -0
  251. pycforge_sdk/gui/visual/resources/icons/24/split-view.png +0 -0
  252. pycforge_sdk/gui/visual/resources/icons/24/summary.png +0 -0
  253. pycforge_sdk/gui/visual/resources/icons/24/telemetry.png +0 -0
  254. pycforge_sdk/gui/visual/resources/icons/24/toggle-comment.png +0 -0
  255. pycforge_sdk/gui/visual/resources/icons/24/toggle-fold.png +0 -0
  256. pycforge_sdk/gui/visual/resources/icons/24/tools.png +0 -0
  257. pycforge_sdk/gui/visual/resources/icons/24/undo.png +0 -0
  258. pycforge_sdk/gui/visual/resources/icons/24/whitespace.png +0 -0
  259. pycforge_sdk/gui/visual/resources/icons/256/add-document.png +0 -0
  260. pycforge_sdk/gui/visual/resources/icons/256/brand-mark.png +0 -0
  261. pycforge_sdk/gui/visual/resources/icons/256/bundle-search.png +0 -0
  262. pycforge_sdk/gui/visual/resources/icons/256/cancel.png +0 -0
  263. pycforge_sdk/gui/visual/resources/icons/256/check.png +0 -0
  264. pycforge_sdk/gui/visual/resources/icons/256/chevron-right.png +0 -0
  265. pycforge_sdk/gui/visual/resources/icons/256/close.png +0 -0
  266. pycforge_sdk/gui/visual/resources/icons/256/collapse-all.png +0 -0
  267. pycforge_sdk/gui/visual/resources/icons/256/command-palette.png +0 -0
  268. pycforge_sdk/gui/visual/resources/icons/256/convert.png +0 -0
  269. pycforge_sdk/gui/visual/resources/icons/256/copy.png +0 -0
  270. pycforge_sdk/gui/visual/resources/icons/256/cut.png +0 -0
  271. pycforge_sdk/gui/visual/resources/icons/256/decision-trace.png +0 -0
  272. pycforge_sdk/gui/visual/resources/icons/256/details.png +0 -0
  273. pycforge_sdk/gui/visual/resources/icons/256/diagnostics.png +0 -0
  274. pycforge_sdk/gui/visual/resources/icons/256/duplicate-line.png +0 -0
  275. pycforge_sdk/gui/visual/resources/icons/256/exit.png +0 -0
  276. pycforge_sdk/gui/visual/resources/icons/256/expand-all.png +0 -0
  277. pycforge_sdk/gui/visual/resources/icons/256/export.png +0 -0
  278. pycforge_sdk/gui/visual/resources/icons/256/find.png +0 -0
  279. pycforge_sdk/gui/visual/resources/icons/256/go-to-line.png +0 -0
  280. pycforge_sdk/gui/visual/resources/icons/256/go-to-output.png +0 -0
  281. pycforge_sdk/gui/visual/resources/icons/256/go-to-source.png +0 -0
  282. pycforge_sdk/gui/visual/resources/icons/256/help.png +0 -0
  283. pycforge_sdk/gui/visual/resources/icons/256/history.png +0 -0
  284. pycforge_sdk/gui/visual/resources/icons/256/indent.png +0 -0
  285. pycforge_sdk/gui/visual/resources/icons/256/link-c.png +0 -0
  286. pycforge_sdk/gui/visual/resources/icons/256/mappings.png +0 -0
  287. pycforge_sdk/gui/visual/resources/icons/256/module.png +0 -0
  288. pycforge_sdk/gui/visual/resources/icons/256/move-down.png +0 -0
  289. pycforge_sdk/gui/visual/resources/icons/256/move-line-down.png +0 -0
  290. pycforge_sdk/gui/visual/resources/icons/256/move-line-up.png +0 -0
  291. pycforge_sdk/gui/visual/resources/icons/256/move-up.png +0 -0
  292. pycforge_sdk/gui/visual/resources/icons/256/next.png +0 -0
  293. pycforge_sdk/gui/visual/resources/icons/256/open.png +0 -0
  294. pycforge_sdk/gui/visual/resources/icons/256/outdent.png +0 -0
  295. pycforge_sdk/gui/visual/resources/icons/256/outline.png +0 -0
  296. pycforge_sdk/gui/visual/resources/icons/256/paste.png +0 -0
  297. pycforge_sdk/gui/visual/resources/icons/256/previous.png +0 -0
  298. pycforge_sdk/gui/visual/resources/icons/256/primary-module.png +0 -0
  299. pycforge_sdk/gui/visual/resources/icons/256/redo.png +0 -0
  300. pycforge_sdk/gui/visual/resources/icons/256/remove-document.png +0 -0
  301. pycforge_sdk/gui/visual/resources/icons/256/replace.png +0 -0
  302. pycforge_sdk/gui/visual/resources/icons/256/save-as.png +0 -0
  303. pycforge_sdk/gui/visual/resources/icons/256/save.png +0 -0
  304. pycforge_sdk/gui/visual/resources/icons/256/select-all.png +0 -0
  305. pycforge_sdk/gui/visual/resources/icons/256/settings.png +0 -0
  306. pycforge_sdk/gui/visual/resources/icons/256/show-c.png +0 -0
  307. pycforge_sdk/gui/visual/resources/icons/256/split-view.png +0 -0
  308. pycforge_sdk/gui/visual/resources/icons/256/summary.png +0 -0
  309. pycforge_sdk/gui/visual/resources/icons/256/telemetry.png +0 -0
  310. pycforge_sdk/gui/visual/resources/icons/256/toggle-comment.png +0 -0
  311. pycforge_sdk/gui/visual/resources/icons/256/toggle-fold.png +0 -0
  312. pycforge_sdk/gui/visual/resources/icons/256/tools.png +0 -0
  313. pycforge_sdk/gui/visual/resources/icons/256/undo.png +0 -0
  314. pycforge_sdk/gui/visual/resources/icons/256/whitespace.png +0 -0
  315. pycforge_sdk/gui/visual/resources/icons/32/add-document.png +0 -0
  316. pycforge_sdk/gui/visual/resources/icons/32/brand-mark.png +0 -0
  317. pycforge_sdk/gui/visual/resources/icons/32/bundle-search.png +0 -0
  318. pycforge_sdk/gui/visual/resources/icons/32/cancel.png +0 -0
  319. pycforge_sdk/gui/visual/resources/icons/32/check.png +0 -0
  320. pycforge_sdk/gui/visual/resources/icons/32/chevron-right.png +0 -0
  321. pycforge_sdk/gui/visual/resources/icons/32/close.png +0 -0
  322. pycforge_sdk/gui/visual/resources/icons/32/collapse-all.png +0 -0
  323. pycforge_sdk/gui/visual/resources/icons/32/command-palette.png +0 -0
  324. pycforge_sdk/gui/visual/resources/icons/32/convert.png +0 -0
  325. pycforge_sdk/gui/visual/resources/icons/32/copy.png +0 -0
  326. pycforge_sdk/gui/visual/resources/icons/32/cut.png +0 -0
  327. pycforge_sdk/gui/visual/resources/icons/32/decision-trace.png +0 -0
  328. pycforge_sdk/gui/visual/resources/icons/32/details.png +0 -0
  329. pycforge_sdk/gui/visual/resources/icons/32/diagnostics.png +0 -0
  330. pycforge_sdk/gui/visual/resources/icons/32/duplicate-line.png +0 -0
  331. pycforge_sdk/gui/visual/resources/icons/32/exit.png +0 -0
  332. pycforge_sdk/gui/visual/resources/icons/32/expand-all.png +0 -0
  333. pycforge_sdk/gui/visual/resources/icons/32/export.png +0 -0
  334. pycforge_sdk/gui/visual/resources/icons/32/find.png +0 -0
  335. pycforge_sdk/gui/visual/resources/icons/32/go-to-line.png +0 -0
  336. pycforge_sdk/gui/visual/resources/icons/32/go-to-output.png +0 -0
  337. pycforge_sdk/gui/visual/resources/icons/32/go-to-source.png +0 -0
  338. pycforge_sdk/gui/visual/resources/icons/32/help.png +0 -0
  339. pycforge_sdk/gui/visual/resources/icons/32/history.png +0 -0
  340. pycforge_sdk/gui/visual/resources/icons/32/indent.png +0 -0
  341. pycforge_sdk/gui/visual/resources/icons/32/link-c.png +0 -0
  342. pycforge_sdk/gui/visual/resources/icons/32/mappings.png +0 -0
  343. pycforge_sdk/gui/visual/resources/icons/32/module.png +0 -0
  344. pycforge_sdk/gui/visual/resources/icons/32/move-down.png +0 -0
  345. pycforge_sdk/gui/visual/resources/icons/32/move-line-down.png +0 -0
  346. pycforge_sdk/gui/visual/resources/icons/32/move-line-up.png +0 -0
  347. pycforge_sdk/gui/visual/resources/icons/32/move-up.png +0 -0
  348. pycforge_sdk/gui/visual/resources/icons/32/next.png +0 -0
  349. pycforge_sdk/gui/visual/resources/icons/32/open.png +0 -0
  350. pycforge_sdk/gui/visual/resources/icons/32/outdent.png +0 -0
  351. pycforge_sdk/gui/visual/resources/icons/32/outline.png +0 -0
  352. pycforge_sdk/gui/visual/resources/icons/32/paste.png +0 -0
  353. pycforge_sdk/gui/visual/resources/icons/32/previous.png +0 -0
  354. pycforge_sdk/gui/visual/resources/icons/32/primary-module.png +0 -0
  355. pycforge_sdk/gui/visual/resources/icons/32/redo.png +0 -0
  356. pycforge_sdk/gui/visual/resources/icons/32/remove-document.png +0 -0
  357. pycforge_sdk/gui/visual/resources/icons/32/replace.png +0 -0
  358. pycforge_sdk/gui/visual/resources/icons/32/save-as.png +0 -0
  359. pycforge_sdk/gui/visual/resources/icons/32/save.png +0 -0
  360. pycforge_sdk/gui/visual/resources/icons/32/select-all.png +0 -0
  361. pycforge_sdk/gui/visual/resources/icons/32/settings.png +0 -0
  362. pycforge_sdk/gui/visual/resources/icons/32/show-c.png +0 -0
  363. pycforge_sdk/gui/visual/resources/icons/32/split-view.png +0 -0
  364. pycforge_sdk/gui/visual/resources/icons/32/summary.png +0 -0
  365. pycforge_sdk/gui/visual/resources/icons/32/telemetry.png +0 -0
  366. pycforge_sdk/gui/visual/resources/icons/32/toggle-comment.png +0 -0
  367. pycforge_sdk/gui/visual/resources/icons/32/toggle-fold.png +0 -0
  368. pycforge_sdk/gui/visual/resources/icons/32/tools.png +0 -0
  369. pycforge_sdk/gui/visual/resources/icons/32/undo.png +0 -0
  370. pycforge_sdk/gui/visual/resources/icons/32/whitespace.png +0 -0
  371. pycforge_sdk/gui/visual/resources/icons/48/add-document.png +0 -0
  372. pycforge_sdk/gui/visual/resources/icons/48/brand-mark.png +0 -0
  373. pycforge_sdk/gui/visual/resources/icons/48/bundle-search.png +0 -0
  374. pycforge_sdk/gui/visual/resources/icons/48/cancel.png +0 -0
  375. pycforge_sdk/gui/visual/resources/icons/48/check.png +0 -0
  376. pycforge_sdk/gui/visual/resources/icons/48/chevron-right.png +0 -0
  377. pycforge_sdk/gui/visual/resources/icons/48/close.png +0 -0
  378. pycforge_sdk/gui/visual/resources/icons/48/collapse-all.png +0 -0
  379. pycforge_sdk/gui/visual/resources/icons/48/command-palette.png +0 -0
  380. pycforge_sdk/gui/visual/resources/icons/48/convert.png +0 -0
  381. pycforge_sdk/gui/visual/resources/icons/48/copy.png +0 -0
  382. pycforge_sdk/gui/visual/resources/icons/48/cut.png +0 -0
  383. pycforge_sdk/gui/visual/resources/icons/48/decision-trace.png +0 -0
  384. pycforge_sdk/gui/visual/resources/icons/48/details.png +0 -0
  385. pycforge_sdk/gui/visual/resources/icons/48/diagnostics.png +0 -0
  386. pycforge_sdk/gui/visual/resources/icons/48/duplicate-line.png +0 -0
  387. pycforge_sdk/gui/visual/resources/icons/48/exit.png +0 -0
  388. pycforge_sdk/gui/visual/resources/icons/48/expand-all.png +0 -0
  389. pycforge_sdk/gui/visual/resources/icons/48/export.png +0 -0
  390. pycforge_sdk/gui/visual/resources/icons/48/find.png +0 -0
  391. pycforge_sdk/gui/visual/resources/icons/48/go-to-line.png +0 -0
  392. pycforge_sdk/gui/visual/resources/icons/48/go-to-output.png +0 -0
  393. pycforge_sdk/gui/visual/resources/icons/48/go-to-source.png +0 -0
  394. pycforge_sdk/gui/visual/resources/icons/48/help.png +0 -0
  395. pycforge_sdk/gui/visual/resources/icons/48/history.png +0 -0
  396. pycforge_sdk/gui/visual/resources/icons/48/indent.png +0 -0
  397. pycforge_sdk/gui/visual/resources/icons/48/link-c.png +0 -0
  398. pycforge_sdk/gui/visual/resources/icons/48/mappings.png +0 -0
  399. pycforge_sdk/gui/visual/resources/icons/48/module.png +0 -0
  400. pycforge_sdk/gui/visual/resources/icons/48/move-down.png +0 -0
  401. pycforge_sdk/gui/visual/resources/icons/48/move-line-down.png +0 -0
  402. pycforge_sdk/gui/visual/resources/icons/48/move-line-up.png +0 -0
  403. pycforge_sdk/gui/visual/resources/icons/48/move-up.png +0 -0
  404. pycforge_sdk/gui/visual/resources/icons/48/next.png +0 -0
  405. pycforge_sdk/gui/visual/resources/icons/48/open.png +0 -0
  406. pycforge_sdk/gui/visual/resources/icons/48/outdent.png +0 -0
  407. pycforge_sdk/gui/visual/resources/icons/48/outline.png +0 -0
  408. pycforge_sdk/gui/visual/resources/icons/48/paste.png +0 -0
  409. pycforge_sdk/gui/visual/resources/icons/48/previous.png +0 -0
  410. pycforge_sdk/gui/visual/resources/icons/48/primary-module.png +0 -0
  411. pycforge_sdk/gui/visual/resources/icons/48/redo.png +0 -0
  412. pycforge_sdk/gui/visual/resources/icons/48/remove-document.png +0 -0
  413. pycforge_sdk/gui/visual/resources/icons/48/replace.png +0 -0
  414. pycforge_sdk/gui/visual/resources/icons/48/save-as.png +0 -0
  415. pycforge_sdk/gui/visual/resources/icons/48/save.png +0 -0
  416. pycforge_sdk/gui/visual/resources/icons/48/select-all.png +0 -0
  417. pycforge_sdk/gui/visual/resources/icons/48/settings.png +0 -0
  418. pycforge_sdk/gui/visual/resources/icons/48/show-c.png +0 -0
  419. pycforge_sdk/gui/visual/resources/icons/48/split-view.png +0 -0
  420. pycforge_sdk/gui/visual/resources/icons/48/summary.png +0 -0
  421. pycforge_sdk/gui/visual/resources/icons/48/telemetry.png +0 -0
  422. pycforge_sdk/gui/visual/resources/icons/48/toggle-comment.png +0 -0
  423. pycforge_sdk/gui/visual/resources/icons/48/toggle-fold.png +0 -0
  424. pycforge_sdk/gui/visual/resources/icons/48/tools.png +0 -0
  425. pycforge_sdk/gui/visual/resources/icons/48/undo.png +0 -0
  426. pycforge_sdk/gui/visual/resources/icons/48/whitespace.png +0 -0
  427. pycforge_sdk/gui/visual/resources/icons/64/add-document.png +0 -0
  428. pycforge_sdk/gui/visual/resources/icons/64/brand-mark.png +0 -0
  429. pycforge_sdk/gui/visual/resources/icons/64/bundle-search.png +0 -0
  430. pycforge_sdk/gui/visual/resources/icons/64/cancel.png +0 -0
  431. pycforge_sdk/gui/visual/resources/icons/64/check.png +0 -0
  432. pycforge_sdk/gui/visual/resources/icons/64/chevron-right.png +0 -0
  433. pycforge_sdk/gui/visual/resources/icons/64/close.png +0 -0
  434. pycforge_sdk/gui/visual/resources/icons/64/collapse-all.png +0 -0
  435. pycforge_sdk/gui/visual/resources/icons/64/command-palette.png +0 -0
  436. pycforge_sdk/gui/visual/resources/icons/64/convert.png +0 -0
  437. pycforge_sdk/gui/visual/resources/icons/64/copy.png +0 -0
  438. pycforge_sdk/gui/visual/resources/icons/64/cut.png +0 -0
  439. pycforge_sdk/gui/visual/resources/icons/64/decision-trace.png +0 -0
  440. pycforge_sdk/gui/visual/resources/icons/64/details.png +0 -0
  441. pycforge_sdk/gui/visual/resources/icons/64/diagnostics.png +0 -0
  442. pycforge_sdk/gui/visual/resources/icons/64/duplicate-line.png +0 -0
  443. pycforge_sdk/gui/visual/resources/icons/64/exit.png +0 -0
  444. pycforge_sdk/gui/visual/resources/icons/64/expand-all.png +0 -0
  445. pycforge_sdk/gui/visual/resources/icons/64/export.png +0 -0
  446. pycforge_sdk/gui/visual/resources/icons/64/find.png +0 -0
  447. pycforge_sdk/gui/visual/resources/icons/64/go-to-line.png +0 -0
  448. pycforge_sdk/gui/visual/resources/icons/64/go-to-output.png +0 -0
  449. pycforge_sdk/gui/visual/resources/icons/64/go-to-source.png +0 -0
  450. pycforge_sdk/gui/visual/resources/icons/64/help.png +0 -0
  451. pycforge_sdk/gui/visual/resources/icons/64/history.png +0 -0
  452. pycforge_sdk/gui/visual/resources/icons/64/indent.png +0 -0
  453. pycforge_sdk/gui/visual/resources/icons/64/link-c.png +0 -0
  454. pycforge_sdk/gui/visual/resources/icons/64/mappings.png +0 -0
  455. pycforge_sdk/gui/visual/resources/icons/64/module.png +0 -0
  456. pycforge_sdk/gui/visual/resources/icons/64/move-down.png +0 -0
  457. pycforge_sdk/gui/visual/resources/icons/64/move-line-down.png +0 -0
  458. pycforge_sdk/gui/visual/resources/icons/64/move-line-up.png +0 -0
  459. pycforge_sdk/gui/visual/resources/icons/64/move-up.png +0 -0
  460. pycforge_sdk/gui/visual/resources/icons/64/next.png +0 -0
  461. pycforge_sdk/gui/visual/resources/icons/64/open.png +0 -0
  462. pycforge_sdk/gui/visual/resources/icons/64/outdent.png +0 -0
  463. pycforge_sdk/gui/visual/resources/icons/64/outline.png +0 -0
  464. pycforge_sdk/gui/visual/resources/icons/64/paste.png +0 -0
  465. pycforge_sdk/gui/visual/resources/icons/64/previous.png +0 -0
  466. pycforge_sdk/gui/visual/resources/icons/64/primary-module.png +0 -0
  467. pycforge_sdk/gui/visual/resources/icons/64/redo.png +0 -0
  468. pycforge_sdk/gui/visual/resources/icons/64/remove-document.png +0 -0
  469. pycforge_sdk/gui/visual/resources/icons/64/replace.png +0 -0
  470. pycforge_sdk/gui/visual/resources/icons/64/save-as.png +0 -0
  471. pycforge_sdk/gui/visual/resources/icons/64/save.png +0 -0
  472. pycforge_sdk/gui/visual/resources/icons/64/select-all.png +0 -0
  473. pycforge_sdk/gui/visual/resources/icons/64/settings.png +0 -0
  474. pycforge_sdk/gui/visual/resources/icons/64/show-c.png +0 -0
  475. pycforge_sdk/gui/visual/resources/icons/64/split-view.png +0 -0
  476. pycforge_sdk/gui/visual/resources/icons/64/summary.png +0 -0
  477. pycforge_sdk/gui/visual/resources/icons/64/telemetry.png +0 -0
  478. pycforge_sdk/gui/visual/resources/icons/64/toggle-comment.png +0 -0
  479. pycforge_sdk/gui/visual/resources/icons/64/toggle-fold.png +0 -0
  480. pycforge_sdk/gui/visual/resources/icons/64/tools.png +0 -0
  481. pycforge_sdk/gui/visual/resources/icons/64/undo.png +0 -0
  482. pycforge_sdk/gui/visual/resources/icons/64/whitespace.png +0 -0
  483. pycforge_sdk/gui/visual/resources/icons/96/add-document.png +0 -0
  484. pycforge_sdk/gui/visual/resources/icons/96/brand-mark.png +0 -0
  485. pycforge_sdk/gui/visual/resources/icons/96/bundle-search.png +0 -0
  486. pycforge_sdk/gui/visual/resources/icons/96/cancel.png +0 -0
  487. pycforge_sdk/gui/visual/resources/icons/96/check.png +0 -0
  488. pycforge_sdk/gui/visual/resources/icons/96/chevron-right.png +0 -0
  489. pycforge_sdk/gui/visual/resources/icons/96/close.png +0 -0
  490. pycforge_sdk/gui/visual/resources/icons/96/collapse-all.png +0 -0
  491. pycforge_sdk/gui/visual/resources/icons/96/command-palette.png +0 -0
  492. pycforge_sdk/gui/visual/resources/icons/96/convert.png +0 -0
  493. pycforge_sdk/gui/visual/resources/icons/96/copy.png +0 -0
  494. pycforge_sdk/gui/visual/resources/icons/96/cut.png +0 -0
  495. pycforge_sdk/gui/visual/resources/icons/96/decision-trace.png +0 -0
  496. pycforge_sdk/gui/visual/resources/icons/96/details.png +0 -0
  497. pycforge_sdk/gui/visual/resources/icons/96/diagnostics.png +0 -0
  498. pycforge_sdk/gui/visual/resources/icons/96/duplicate-line.png +0 -0
  499. pycforge_sdk/gui/visual/resources/icons/96/exit.png +0 -0
  500. pycforge_sdk/gui/visual/resources/icons/96/expand-all.png +0 -0
  501. pycforge_sdk/gui/visual/resources/icons/96/export.png +0 -0
  502. pycforge_sdk/gui/visual/resources/icons/96/find.png +0 -0
  503. pycforge_sdk/gui/visual/resources/icons/96/go-to-line.png +0 -0
  504. pycforge_sdk/gui/visual/resources/icons/96/go-to-output.png +0 -0
  505. pycforge_sdk/gui/visual/resources/icons/96/go-to-source.png +0 -0
  506. pycforge_sdk/gui/visual/resources/icons/96/help.png +0 -0
  507. pycforge_sdk/gui/visual/resources/icons/96/history.png +0 -0
  508. pycforge_sdk/gui/visual/resources/icons/96/indent.png +0 -0
  509. pycforge_sdk/gui/visual/resources/icons/96/link-c.png +0 -0
  510. pycforge_sdk/gui/visual/resources/icons/96/mappings.png +0 -0
  511. pycforge_sdk/gui/visual/resources/icons/96/module.png +0 -0
  512. pycforge_sdk/gui/visual/resources/icons/96/move-down.png +0 -0
  513. pycforge_sdk/gui/visual/resources/icons/96/move-line-down.png +0 -0
  514. pycforge_sdk/gui/visual/resources/icons/96/move-line-up.png +0 -0
  515. pycforge_sdk/gui/visual/resources/icons/96/move-up.png +0 -0
  516. pycforge_sdk/gui/visual/resources/icons/96/next.png +0 -0
  517. pycforge_sdk/gui/visual/resources/icons/96/open.png +0 -0
  518. pycforge_sdk/gui/visual/resources/icons/96/outdent.png +0 -0
  519. pycforge_sdk/gui/visual/resources/icons/96/outline.png +0 -0
  520. pycforge_sdk/gui/visual/resources/icons/96/paste.png +0 -0
  521. pycforge_sdk/gui/visual/resources/icons/96/previous.png +0 -0
  522. pycforge_sdk/gui/visual/resources/icons/96/primary-module.png +0 -0
  523. pycforge_sdk/gui/visual/resources/icons/96/redo.png +0 -0
  524. pycforge_sdk/gui/visual/resources/icons/96/remove-document.png +0 -0
  525. pycforge_sdk/gui/visual/resources/icons/96/replace.png +0 -0
  526. pycforge_sdk/gui/visual/resources/icons/96/save-as.png +0 -0
  527. pycforge_sdk/gui/visual/resources/icons/96/save.png +0 -0
  528. pycforge_sdk/gui/visual/resources/icons/96/select-all.png +0 -0
  529. pycforge_sdk/gui/visual/resources/icons/96/settings.png +0 -0
  530. pycforge_sdk/gui/visual/resources/icons/96/show-c.png +0 -0
  531. pycforge_sdk/gui/visual/resources/icons/96/split-view.png +0 -0
  532. pycforge_sdk/gui/visual/resources/icons/96/summary.png +0 -0
  533. pycforge_sdk/gui/visual/resources/icons/96/telemetry.png +0 -0
  534. pycforge_sdk/gui/visual/resources/icons/96/toggle-comment.png +0 -0
  535. pycforge_sdk/gui/visual/resources/icons/96/toggle-fold.png +0 -0
  536. pycforge_sdk/gui/visual/resources/icons/96/tools.png +0 -0
  537. pycforge_sdk/gui/visual/resources/icons/96/undo.png +0 -0
  538. pycforge_sdk/gui/visual/resources/icons/96/whitespace.png +0 -0
  539. pycforge_sdk/gui/visual/theme.py +204 -0
  540. pycforge_sdk/gui/visual/theme_steel_stylesheet.py +901 -0
  541. pycforge_sdk/gui/visual/theme_stylesheet.py +597 -0
  542. pycforge_sdk/gui/visual/theme_workspace_stylesheet.py +169 -0
  543. pycforge_sdk/gui/visual/visual_tokens.py +146 -0
  544. pycforge_sdk/gui/widgets.py +68 -0
  545. pycforge_sdk/gui/window.py +559 -0
  546. pycforge_sdk/native.py +42 -0
  547. pycforge_sdk/package_metadata.py +21 -0
  548. pycforge_sdk/process.py +58 -0
  549. pycforge_sdk/project.py +143 -0
  550. pycforge_sdk/readiness.py +106 -0
  551. pycforge_sdk/results.py +45 -0
  552. pycforge_sdk/service.py +454 -0
  553. pycforge_sdk/workbench.py +88 -0
  554. pycforge_sdk-0.6.3.dist-info/METADATA +221 -0
  555. pycforge_sdk-0.6.3.dist-info/RECORD +559 -0
  556. pycforge_sdk-0.6.3.dist-info/WHEEL +5 -0
  557. pycforge_sdk-0.6.3.dist-info/entry_points.txt +5 -0
  558. pycforge_sdk-0.6.3.dist-info/licenses/LICENSE +674 -0
  559. pycforge_sdk-0.6.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,227 @@
1
+ """Bounded installation discovery, shared by human and automated SDK clients.
2
+
3
+ Searching enumerates known environment roots, never an entire drive. Candidates
4
+ are validated through PyCForge's public discovery protocol in separate processes.
5
+ Discovery neither changes the reference cache nor installs or registers anything.
6
+ """
7
+ from __future__ import annotations
8
+ from itertools import islice
9
+ import os
10
+ from pathlib import Path
11
+ import re
12
+ import sys
13
+ import time
14
+ from . import catalogue
15
+ from .connection import Connection
16
+ from .results import Outcome, SDKError, operation
17
+
18
+ DISCOVERY_SCHEMA = "pycforge-sdk.discovery/0.1"
19
+ _PYTHON = re.compile(r"python(?:3(?:\.\d+)*)?(?:\.exe)?$", re.IGNORECASE)
20
+
21
+
22
+ def _key(path):
23
+ # Resolving a venv's python symlink would lose the environment identity.
24
+ return os.path.normcase(os.path.abspath(os.path.expanduser(str(path))))
25
+
26
+
27
+ def _children(path):
28
+ try:
29
+ return sorted(islice(Path(path).iterdir(), 256), key=lambda p: p.name.lower())
30
+ except OSError:
31
+ return []
32
+
33
+
34
+ def support_folder(location):
35
+ """Recognize the engine-owned support folder without importing engine code."""
36
+ path = Path(location).expanduser().absolute()
37
+ for item in (path, path / "crucible/landscape", path / "pycforge/crucible/landscape"):
38
+ if item.is_dir() and (item / "index.json").is_file() and (item / "api.xml").is_file():
39
+ return item
40
+ return None
41
+
42
+
43
+ def interpreters_at(location):
44
+ """Resolve a Python, environment, or installed support folder without execution."""
45
+ path = Path(location).expanduser().absolute()
46
+ if path.is_file():
47
+ if path.name.lower() == "pythonw.exe":
48
+ path = path.with_name("python.exe")
49
+ return [path] if path.is_file() and _PYTHON.fullmatch(path.name) else []
50
+ if not path.is_dir():
51
+ return []
52
+ roots = [path]
53
+ support = support_folder(path)
54
+ if support:
55
+ roots.extend(list(support.parents)[:8])
56
+ found = []
57
+ for root in roots:
58
+ for relative in ("Scripts/python.exe", "bin/python", "bin/python3", "python.exe", "python", "python3"):
59
+ item = root / relative
60
+ if item.is_file() and _key(item) not in {_key(p) for p in found}:
61
+ found.append(item)
62
+ return found
63
+
64
+
65
+ def _windows_registry_locations():
66
+ """PEP 514 Python registrations, including both registry views."""
67
+ if sys.platform != "win32":
68
+ return []
69
+ import winreg
70
+ values = []
71
+ for hive in (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE):
72
+ for view in (winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_32KEY):
73
+ try:
74
+ with winreg.OpenKey(hive, r"Software\Python", 0, winreg.KEY_READ | view) as root:
75
+ for ci in range(min(winreg.QueryInfoKey(root)[0], 64)):
76
+ company = winreg.EnumKey(root, ci)
77
+ with winreg.OpenKey(root, company) as vendor:
78
+ for ti in range(min(winreg.QueryInfoKey(vendor)[0], 64)):
79
+ tag = winreg.EnumKey(vendor, ti)
80
+ try:
81
+ with winreg.OpenKey(vendor, tag + r"\InstallPath") as install:
82
+ for field in ("ExecutablePath", ""):
83
+ try:
84
+ value, kind = winreg.QueryValueEx(install, field)
85
+ if kind in (winreg.REG_SZ, winreg.REG_EXPAND_SZ):
86
+ values.append(os.path.expandvars(value))
87
+ except OSError:
88
+ pass
89
+ except OSError:
90
+ pass
91
+ except OSError:
92
+ pass
93
+ return values
94
+
95
+
96
+ def common_locations():
97
+ """Known Python/environment locations; no shell, registry writes or recursion."""
98
+ home = Path.home()
99
+ locations = [sys.executable]
100
+ for name in ("VIRTUAL_ENV", "CONDA_PREFIX"):
101
+ if os.environ.get(name):
102
+ locations.append(os.environ[name])
103
+ locations.extend(_windows_registry_locations())
104
+ # Ignore empty/relative PATH entries and Windows Store execution aliases.
105
+ for value in os.environ.get("PATH", "").split(os.pathsep)[:64]:
106
+ if value and Path(value).is_absolute() and "windowsapps" not in value.lower():
107
+ locations.append(value)
108
+ locations.append(getattr(sys, "_base_executable", sys.executable))
109
+ bases = [home / ".virtualenvs", home / ".venvs", home / "venvs",
110
+ home / ".pyenv/versions", home / ".local/share/pipx/venvs", home / ".local/pipx/venvs",
111
+ home / "miniconda3/envs", home / "anaconda3/envs", home / ".conda/envs"]
112
+ locations.extend([home / "miniconda3", home / "anaconda3"])
113
+ if sys.platform == "win32":
114
+ local = os.environ.get("LOCALAPPDATA")
115
+ if local:
116
+ bases.append(Path(local) / "Programs/Python")
117
+ for name in ("ProgramFiles", "ProgramFiles(x86)"):
118
+ if os.environ.get(name):
119
+ locations.extend(p for p in _children(os.environ[name]) if p.name.lower().startswith("python"))
120
+ elif sys.platform == "darwin":
121
+ bases.extend([Path("/Library/Frameworks/Python.framework/Versions"),
122
+ home / "Library/Python", Path("/opt/homebrew/opt")])
123
+ for base in bases:
124
+ locations.extend(_children(base))
125
+ # Conda records environments outside its default envs directory here.
126
+ try:
127
+ with (home / ".conda/environments.txt").open(encoding="utf-8") as file:
128
+ text = file.read(65537)
129
+ if len(text) <= 65536:
130
+ locations.extend(line.strip() for line in text.splitlines()[:128]
131
+ if line.strip() and Path(line.strip()).is_absolute())
132
+ except (OSError, UnicodeError):
133
+ pass
134
+ return locations
135
+
136
+
137
+ def _probe(python, timeout, cancel):
138
+ connection = Connection(python, ".", timeout=timeout, cancel=cancel)
139
+ discovery = connection.discover()
140
+ connection.snapshot = catalogue.read_snapshot(discovery)
141
+ if "authoring.json" in connection.snapshot.files:
142
+ connection.reference()
143
+ connection.workbench()
144
+ return {"engine_python": str(python), "engine": dict(connection.snapshot.identity),
145
+ "folder": str(discovery["folder"]), "execution_available": connection._authoring_ready}
146
+
147
+
148
+ @operation
149
+ def discover_engines(*, preferred=None, locations=None, timeout=3.0, search_timeout=20.0,
150
+ max_candidates=48, cancel=None, progress=None):
151
+ """Find validated installations without changing a cache or authoring state.
152
+
153
+ A valid preferred installation wins immediately. Explicit locations restrict
154
+ the search; otherwise known installations and environment roots are checked.
155
+ Results identify partial searches and failures. Cancellation returns no choice.
156
+ Time/output budgets supervise child processes, not filesystem/network mounts.
157
+ """
158
+ if (not 0 < timeout <= 300 or not 0 < search_timeout <= 300
159
+ or type(max_candidates) is not int or not 1 <= max_candidates <= 128):
160
+ raise SDKError("SDK_ARGUMENT", "Use positive timeouts up to 300 seconds and 1–128 candidates.")
161
+ if locations is not None and (not isinstance(locations, (list, tuple)) or len(locations) > 128):
162
+ raise SDKError("SDK_ARGUMENT", "Locations must be a list of at most 128 paths.")
163
+ started = time.monotonic()
164
+ def notify(**data):
165
+ if cancel is not None and cancel.is_set():
166
+ raise SDKError("SDK_CANCELED", "Installation search canceled.", status="canceled")
167
+ if progress:
168
+ progress({"schema": "pycforge-sdk.progress/0.1", "phase": "discovery", **data})
169
+ notify(name="Looking for installed PyCForge support files…", current=0, total=1)
170
+ sources = ([preferred] if preferred else []) + (list(locations) if locations is not None else common_locations())
171
+ candidates, seen = [], set()
172
+ support_requested = [support_folder(item) for item in (locations or [])]
173
+ support_requested = [item for item in support_requested if item is not None]
174
+ # An installed user-site catalogue may have its interpreter outside its parents.
175
+ if support_requested:
176
+ sources.extend(common_locations())
177
+ limited = False
178
+ for location in sources:
179
+ notify(name="Checking known installation locations…", current=0, total=1)
180
+ for python in interpreters_at(location):
181
+ key = _key(python)
182
+ if key in seen:
183
+ continue
184
+ seen.add(key)
185
+ if len(candidates) >= max_candidates:
186
+ limited = True
187
+ break
188
+ candidates.append(python)
189
+ if limited:
190
+ break
191
+ engines, attempts, identities = [], [], set()
192
+ preferred_keys = {_key(p) for p in interpreters_at(preferred)} if preferred else set()
193
+ reason = "searched"
194
+ for index, python in enumerate(candidates):
195
+ notify(name="Checking PyCForge installation…", path=str(python), current=index, total=len(candidates))
196
+ remaining = search_timeout - (time.monotonic() - started)
197
+ if remaining <= 0:
198
+ limited = True
199
+ break
200
+ try:
201
+ item = _probe(python, min(timeout, remaining), cancel)
202
+ if support_requested and not any(_key(item["folder"]) == _key(p) for p in support_requested):
203
+ attempts.append({"engine_python": str(python), "code": "SDK_LOCATION_MISMATCH",
204
+ "message": "This interpreter uses a different PyCForge support folder."})
205
+ continue
206
+ identity = (_key(item["folder"]), item["engine"]["manifest_sha256"])
207
+ if identity not in identities:
208
+ engines.append(item)
209
+ identities.add(identity)
210
+ if _key(python) in preferred_keys:
211
+ reason = "preferred"
212
+ limited = False
213
+ break
214
+ except (SDKError, catalogue.CatalogueError, OSError, ValueError, TypeError, KeyError) as exc:
215
+ if isinstance(exc, SDKError) and exc.status == "canceled":
216
+ raise
217
+ attempts.append({"engine_python": str(python), "code": getattr(exc, "code", "SDK_DISCOVERY"),
218
+ "message": str(exc)[:500]})
219
+ notify(name="Installation search finished", current=1, total=1)
220
+ data = {"schema": DISCOVERY_SCHEMA, "engines": engines, "attempts": attempts,
221
+ "limited": limited, "reason": reason, "candidate_count": len(candidates)}
222
+ if not engines:
223
+ message = ("The selected support folder needs its matching installed PyCForge environment. "
224
+ "A source folder alone does not provide a working engine." if support_requested else
225
+ "No compatible PyCForge installation was found in the checked locations.")
226
+ return Outcome("incomplete", data, ({"code": "SDK_ENGINE_NOT_FOUND", "message": message},))
227
+ return Outcome("succeeded", data)
@@ -0,0 +1,84 @@
1
+ """Bounded editor snapshots and optimistic, one-file atomic saves; no Qt."""
2
+ from pathlib import Path
3
+ import tempfile
4
+ from .project import Project, MAX_PROJECT, MAX_SOURCE, atomic_write, canonical
5
+ from .results import SDKError
6
+
7
+
8
+ def snapshot(project):
9
+ document = project.document
10
+ declaration = document.get("declaration")
11
+ if (type(declaration) is not dict or type(declaration.get("functions")) is not list
12
+ or any(type(f) is not dict or type(f.get("export")) is not str for f in declaration["functions"])
13
+ or any(key in declaration and type(declaration[key]) is not str for key in ("namespace", "package_id", "version", "schema"))):
14
+ raise SDKError("SDK_EDITOR_DATA", "The declaration needs an object with a list of named functions. Correct project.json and reopen it.")
15
+ documentation = document.get("documentation")
16
+ if isinstance(documentation, dict) and (type(documentation.get("functions", {})) is not dict or type(documentation.get("constants", {})) is not dict):
17
+ raise SDKError("SDK_EDITOR_DATA", "Help functions and constants must be objects. Correct project.json and reopen it.")
18
+ if isinstance(documentation, dict):
19
+ for function in documentation.get("functions", {}).values():
20
+ if (type(function) is not dict or type(function.get("parameters", [])) is not list
21
+ or any(type(p) is not str for p in function.get("parameters", []))):
22
+ raise SDKError("SDK_EDITOR_DATA", "Function Help needs an object with a list of parameter explanations. Correct project.json and reopen it.")
23
+ return {"directory": str(project.root), "project_sha256": project.sha256,
24
+ "document": document,
25
+ "sources": {name: value.decode("utf-8") for name, value in project.sources}}
26
+
27
+
28
+ def open_project(directory):
29
+ project = Project.load(directory)
30
+ project.ensure_current()
31
+ return snapshot(project)
32
+
33
+
34
+ def current(directory, expected_sha256):
35
+ project = Project.load(directory)
36
+ if project.sha256 != expected_sha256:
37
+ raise SDKError("SDK_EDIT_CONFLICT", "Project changed on disk. Reload it before saving; your saved files were preserved.")
38
+ return project
39
+
40
+
41
+ def validate_draft(project, document, sources):
42
+ # Project.load owns data/path/budget validation for every client. A private
43
+ # staged snapshot never imports source and never creates verification.
44
+ data = canonical(document)
45
+ if len(data) + sum(len(v) for v in sources.values()) > MAX_PROJECT:
46
+ raise SDKError("SDK_PROJECT", "Project exceeds the 4 MiB budget; no files were changed.")
47
+ # Newly referenced existing files go through the same path/symlink/budget
48
+ # checks before any path is copied into the private validation directory.
49
+ candidate = Project.load(project.root, document_bytes=data)
50
+ snapshot(candidate)
51
+ sources = {**dict(candidate.sources), **sources}
52
+ with tempfile.TemporaryDirectory(prefix="sdk-edit-") as folder:
53
+ root = Path(folder)
54
+ (root / "project.json").write_bytes(data)
55
+ # Keys originate in an already validated Project, never draft paths.
56
+ for name, value in sources.items():
57
+ target = root / name
58
+ target.parent.mkdir(parents=True, exist_ok=True)
59
+ target.write_bytes(value)
60
+ snapshot(Project.load(root))
61
+ return data
62
+
63
+
64
+ def save_project(directory, document, *, expected_sha256):
65
+ project = current(directory, expected_sha256)
66
+ data = validate_draft(project, document, dict(project.sources))
67
+ project.ensure_current()
68
+ atomic_write(project.root / "project.json", data)
69
+ return open_project(directory)
70
+
71
+
72
+ def save_source(directory, filename, source, *, expected_sha256):
73
+ project = current(directory, expected_sha256)
74
+ sources = dict(project.sources)
75
+ if filename not in sources or type(source) is not str:
76
+ raise SDKError("SDK_ARGUMENT", "Choose an existing UTF-8 project fixture.")
77
+ data = source.encode("utf-8")
78
+ if len(data) > MAX_SOURCE:
79
+ raise SDKError("SDK_PROJECT", "Fixture exceeds the 256 KiB budget; no files were changed.")
80
+ sources[filename] = data
81
+ validate_draft(project, project.document, sources)
82
+ project.ensure_current()
83
+ atomic_write(project.root / filename, data)
84
+ return open_project(directory)
@@ -0,0 +1,45 @@
1
+ """Isolated engine entry point, including standard per-user installations.
2
+
3
+ Executed by the selected Python, not imported into the SDK process. Preserve
4
+ -I's exclusion of the working directory and PYTHONPATH. Add that interpreter's
5
+ standard user-site folder when its environment permits it; never process its
6
+ .pth files or accept an arbitrary source folder as an import path.
7
+ """
8
+ from pathlib import Path
9
+ import runpy
10
+ import site
11
+ import sys
12
+
13
+
14
+ def user_site_allowed():
15
+ if sys.prefix == sys.base_prefix:
16
+ return True
17
+ try:
18
+ lines = (Path(sys.prefix) / "pyvenv.cfg").read_text(encoding="utf-8").splitlines()
19
+ except (OSError, UnicodeError):
20
+ return False
21
+ return any(line.partition("=")[0].strip().lower() == "include-system-site-packages"
22
+ and line.partition("=")[2].strip().lower() == "true" for line in lines)
23
+
24
+
25
+ def main():
26
+ if user_site_allowed():
27
+ folder = site.getusersitepackages()
28
+ if isinstance(folder, str) and Path(folder).is_dir() and folder not in sys.path:
29
+ # Match normal user-site precedence ahead of global site-packages,
30
+ # retaining the standard library first.
31
+ globals_ = site.getsitepackages()
32
+ position = next((i for i, p in enumerate(sys.path) if p in globals_), len(sys.path))
33
+ sys.path.insert(position, folder)
34
+ mode = sys.argv[1]
35
+ if mode == "discover":
36
+ sys.argv = ["pycforge", "--format", "json", "sdk-api"]
37
+ runpy.run_module("pycforge", run_name="__main__", alter_sys=True)
38
+ elif mode == "call":
39
+ runpy.run_path(str(Path(__file__).with_name("engine_worker.py")), run_name="__main__")
40
+ else:
41
+ raise ValueError("Unknown engine launch mode")
42
+
43
+
44
+ if __name__ == "__main__":
45
+ main()
@@ -0,0 +1,53 @@
1
+ """SDK bridge executed by the selected engine interpreter using -I.
2
+
3
+ Only public PyCForge services are imported. The SDK need not be installed in
4
+ that interpreter. Incoming authoring data is JSON, never executable Python.
5
+ """
6
+ import base64
7
+ import json
8
+ from pathlib import Path
9
+ import sys
10
+
11
+
12
+ def main():
13
+ request = json.loads(sys.stdin.buffer.read(8*1024*1024 + 1))
14
+ from pycforge.crucible.sdk_api import discover
15
+ identity = discover()
16
+ if request["identity"] != identity:
17
+ raise ValueError("Engine identity changed; reconnect and reverify.")
18
+ action, payload = request["action"], request["payload"]
19
+ from pycforge.crucible import ScalarAuthoring, ImportRegistrationStore
20
+ import pycforge.crucible as api
21
+ Authoring = getattr(api, "ExtensionAuthoring", ScalarAuthoring)
22
+ if action == "register":
23
+ store = ImportRegistrationStore(Path(payload["store"]) if payload.get("store") else None)
24
+ row = store.register_file(Path(payload["file"]))
25
+ from dataclasses import fields
26
+ result = {field.name: getattr(row, field.name) for field in fields(row) if field.name != "package"}
27
+ result["package_sha256"] = row.package.package_sha256 if row.package is not None else None
28
+ else:
29
+ candidate = Authoring(payload["declaration"])
30
+ if action == "inspect":
31
+ result = candidate.inspect()
32
+ elif action == "scan":
33
+ result = candidate.scan(payload.get("documentation"), examples=payload.get("examples"))
34
+ elif action == "convert":
35
+ result = candidate.convert(payload["source"], logical_name=payload["logical_name"]).semantic_dict()
36
+ elif action == "package":
37
+ result = {"package_base64": base64.b64encode(candidate.package(
38
+ **payload["metadata"], verification_producer=payload["verification_producer"],
39
+ documentation=payload["documentation"], examples=payload["examples"])).decode("ascii")}
40
+ else:
41
+ raise ValueError("Unknown bridge action")
42
+ if discover() != identity:
43
+ raise ValueError("Engine identity changed during the operation.")
44
+ return {"schema": "pycforge-sdk.bridge/0.1", "identity": identity, "ok": True, "result": result}
45
+
46
+
47
+ if __name__ == "__main__":
48
+ try:
49
+ answer = main()
50
+ except Exception as exc:
51
+ answer = {"schema": "pycforge-sdk.bridge/0.1", "ok": False,
52
+ "diagnostic": {"code": getattr(exc, "code", "SDK_ENGINE_ERROR"), "message": str(exc)}}
53
+ print(json.dumps(answer, sort_keys=True, allow_nan=False))
@@ -0,0 +1 @@
1
+ """Optional desktop client. Importing the SDK never imports this application."""
@@ -0,0 +1,3 @@
1
+ from .app import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,36 @@
1
+ """Optional PySide6 entry point; dependency errors stay separate from the SDK."""
2
+ import argparse
3
+ from pathlib import Path
4
+ import sys
5
+ from .. import __version__
6
+
7
+
8
+ def main(argv=None):
9
+ parser = argparse.ArgumentParser(prog="pycforge-sdk-ui", description="PyCForge conversion extension workshop")
10
+ parser.add_argument("--version", action="version", version=__version__)
11
+ parser.add_argument("--engine-python")
12
+ parser.add_argument("--compiler")
13
+ parser.add_argument("--cache", type=Path)
14
+ parser.add_argument("--project", type=Path)
15
+ parser.add_argument("--timeout", type=float, default=30)
16
+ args = parser.parse_args(argv)
17
+ if not 0 < args.timeout <= 300: parser.error("timeout must be greater than zero and at most 300 seconds")
18
+ try:
19
+ from PySide6.QtCore import QTimer
20
+ from PySide6.QtWidgets import QApplication
21
+ except ImportError:
22
+ print("The desktop needs the optional GUI dependency. Install pycforge-sdk[gui] in this environment; the headless SDK remains usable.", file=sys.stderr)
23
+ return 3
24
+ from .visual.theme import apply_pycforge_theme
25
+ from .identity import sdk_icon
26
+ from .window import MainWindow
27
+ from .visual.qt_screen_geometry import fit_window_to_available_screen
28
+ app = QApplication.instance() or QApplication([sys.argv[0]])
29
+ app.setApplicationName("PyCForge SDK"); app.setApplicationVersion(__version__)
30
+ app.setWindowIcon(sdk_icon())
31
+ apply_pycforge_theme(app)
32
+ window = MainWindow(engine_python=args.engine_python, compiler=args.compiler, cache=args.cache, timeout=args.timeout)
33
+ fit_window_to_available_screen(window, preferred=(1320, 860), minimum=(920, 640))
34
+ if args.project: window.after_connect = str(args.project.absolute())
35
+ QTimer.singleShot(0, window.begin_startup)
36
+ return app.exec()