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,550 @@
1
+ """Headless contracts for PyCForge application actions and menu surfaces.
2
+
3
+ The declarations in this module contain no Qt objects. They are the stable
4
+ source for action identity, user-facing text, shortcuts, accessibility, and
5
+ surface placement. The optional Qt adapter materializes these declarations
6
+ without becoming a second source of action metadata.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from dataclasses import dataclass
12
+ from enum import Enum
13
+ from types import MappingProxyType
14
+ from typing import Iterable, Mapping
15
+
16
+
17
+ MAX_DYNAMIC_ACTIONS = 10
18
+ MAX_DYNAMIC_LABEL_CHARS = 160
19
+ MAX_DYNAMIC_TOOLTIP_CHARS = 4096
20
+
21
+
22
+ class PlacementKind(str, Enum):
23
+ """Kinds of entries accepted by a declared action surface."""
24
+
25
+ ACTION = "action"
26
+ SEPARATOR = "separator"
27
+ SUBMENU = "submenu"
28
+ DYNAMIC = "dynamic"
29
+
30
+
31
+ class SurfaceKind(str, Enum):
32
+ """Presentation roles supported by the Phase 15 action foundation."""
33
+
34
+ MENU = "menu"
35
+ TOOLBAR = "toolbar"
36
+ CONTEXT = "context"
37
+
38
+
39
+ @dataclass(frozen=True, slots=True)
40
+ class ActionSpec:
41
+ """Complete immutable presentation contract for one application action."""
42
+
43
+ action_id: str
44
+ menu_text: str
45
+ toolbar_text: str
46
+ tooltip: str
47
+ accessible_name: str
48
+ icon_name: str | None = None
49
+ standard_shortcut: str | None = None
50
+ shortcut: str | None = None
51
+ shortcut_context: str = "window"
52
+ checkable: bool = False
53
+ tone: str = "normal"
54
+ dynamic: bool = False
55
+
56
+
57
+ @dataclass(frozen=True, slots=True)
58
+ class ActionState:
59
+ """One bounded enabled/checked projection supplied by the application."""
60
+
61
+ enabled: bool = True
62
+ checked: bool | None = None
63
+ visible: bool = True
64
+
65
+
66
+ @dataclass(frozen=True, slots=True)
67
+ class ActionPlacement:
68
+ """An action, separator, submenu, or dynamic group in a surface."""
69
+
70
+ kind: PlacementKind
71
+ target: str = ""
72
+
73
+ @classmethod
74
+ def action(cls, action_id: str) -> "ActionPlacement":
75
+ return cls(PlacementKind.ACTION, action_id)
76
+
77
+ @classmethod
78
+ def separator(cls) -> "ActionPlacement":
79
+ return cls(PlacementKind.SEPARATOR)
80
+
81
+ @classmethod
82
+ def submenu(cls, surface_id: str) -> "ActionPlacement":
83
+ return cls(PlacementKind.SUBMENU, surface_id)
84
+
85
+ @classmethod
86
+ def dynamic(cls, group_id: str) -> "ActionPlacement":
87
+ return cls(PlacementKind.DYNAMIC, group_id)
88
+
89
+
90
+ @dataclass(frozen=True, slots=True)
91
+ class SurfaceSpec:
92
+ """Declarative composition of one main, toolbar, or context surface."""
93
+
94
+ surface_id: str
95
+ kind: SurfaceKind
96
+ title: str
97
+ accessible_name: str
98
+ placements: tuple[ActionPlacement, ...]
99
+
100
+
101
+ @dataclass(frozen=True, slots=True)
102
+ class DynamicActionEntry:
103
+ """Validated data for one bounded parameterized action instance."""
104
+
105
+ key: str
106
+ label: str
107
+ tooltip: str
108
+ accessible_name: str
109
+ payload: str
110
+ enabled: bool = True
111
+
112
+
113
+ def _action(
114
+ action_id: str,
115
+ menu_text: str,
116
+ tooltip: str,
117
+ accessible_name: str,
118
+ *,
119
+ toolbar_text: str | None = None,
120
+ icon_name: str | None = None,
121
+ standard_shortcut: str | None = None,
122
+ shortcut: str | None = None,
123
+ shortcut_context: str = "window",
124
+ checkable: bool = False,
125
+ tone: str = "normal",
126
+ dynamic: bool = False,
127
+ ) -> ActionSpec:
128
+ return ActionSpec(
129
+ action_id=action_id,
130
+ menu_text=menu_text,
131
+ toolbar_text=toolbar_text or menu_text.replace("&", ""),
132
+ tooltip=tooltip,
133
+ accessible_name=accessible_name,
134
+ icon_name=icon_name,
135
+ standard_shortcut=standard_shortcut,
136
+ shortcut=shortcut,
137
+ shortcut_context=shortcut_context,
138
+ checkable=checkable,
139
+ tone=tone,
140
+ dynamic=dynamic,
141
+ )
142
+
143
+
144
+ # Row fields after the four required strings are:
145
+ # toolbar, icon, standard key, literal key, context, checkable, tone, dynamic.
146
+ _ACTION_ROWS = (
147
+ ("project.open", "&Open Project…", "Open a portable project in a new working folder", "Open project", None, "open", None, None, "window", False, "normal", False),
148
+ ("project.save", "&Save Project", "Save all open Python modules and their project history to one bundle", "Save project", None, "save-python", None, None, "window", False, "normal", False),
149
+ ("project.save_as", "Save Project &As…", "Save a project bundle with optional checkpoint history", "Save project as", None, "save-as", None, None, "window", False, "normal", False),
150
+ ("project.checkpoint", "Create &Checkpoint…", "Name and save a checkpoint of the current open Python modules", "Create project checkpoint", None, None, None, None, "window", False, "normal", False),
151
+ ("project.history", "Project &History…", "Compare checkpoints and restore a module or the whole project", "Project history", None, "history", None, None, "window", False, "normal", False),
152
+ ("file.open_python", "&Open Python…", "Open Python documents into the source bundle", "Open Python documents", "Open", "open", "Open", None, "window", False, "normal", False),
153
+ ("file.open_recent", "Open Recent Python", "Open this recent Python document", "Open recent Python document", None, "open", None, None, "window", False, "normal", True),
154
+ ("file.clear_recent", "&Clear Recent Files", "Clear recent Python file history without closing tabs or deleting files", "Clear recent Python file history", None, "close", None, None, "window", False, "normal", False),
155
+ ("bundle.new_module", "&New Module", "Add a blank logical module to the source bundle", "Add source bundle module", "New Module", "add-document", "New", None, "window", False, "normal", False),
156
+ ("bundle.remove_module", "&Remove Module", "Remove the selected module from the source bundle", "Remove selected source bundle module", None, "remove-document", None, "Ctrl+Shift+W", "window", False, "danger", False),
157
+ ("bundle.move_up", "Move Module &Up", "Move the selected module one position earlier", "Move selected module up", None, "move-up", None, "Alt+Up", "widget", False, "normal", False),
158
+ ("bundle.move_down", "Move Module &Down", "Move the selected module one position later", "Move selected module down", None, "move-down", None, "Alt+Down", "widget", False, "normal", False),
159
+ ("bundle.make_primary", "Make &Primary", "Make the selected module the primary source document", "Make selected module primary", None, "primary-module", None, None, "window", False, "normal", False),
160
+ ("file.save_python", "&Save Python", "Atomically save the active Python document", "Save active Python document", "Save Python", "save-python", "Save", None, "window", False, "normal", False),
161
+ ("file.save_python_as", "Save Python &As…", "Atomically save the active document to a new Python path", "Save active Python document as", None, "save-as", "SaveAs", None, "window", False, "normal", False),
162
+ ("file.save_all_python", "Save A&ll Python", "Save every new or modified Python document", "Save all Python documents", None, "save-python", None, None, "window", False, "normal", False),
163
+ ("output.set_destination", "Set C &Destination…", "Choose the explicit destination for generated C", "Set generated C destination", "C Destination", "link-c", None, "Ctrl+Shift+L", "window", False, "normal", False),
164
+ ("output.save_c", "Save Generated &C", "Atomically save fresh generated C to its destination", "Save current generated C", "Save C", "save-c", None, "Ctrl+Alt+S", "window", False, "normal", False),
165
+ ("output.export_modules", "Export C &Modules…", "Save separate Typed C sources, headers and an interface manifest in a ZIP archive", "Export Typed C modules", None, "save-c", None, None, "window", False, "normal", False),
166
+ ("conversion.convert", "&Transpile", "Transpile Python to C using the checked mode in the Transpile menu", "Transpile using the selected conversion mode", "Transpile", "convert", None, "Ctrl+Return", "window", False, "primary", False),
167
+ ("conversion.mode_typed", "&Typed", "Select typed conversion for the source bundle; click Transpile to convert", "Select typed conversion", None, None, None, None, "window", True, "normal", False),
168
+ ("conversion.mode_runtime", "&Runtime", "Select runtime value conversion for the source bundle; click Transpile to convert", "Select runtime value conversion preview", None, None, None, None, "window", True, "normal", False),
169
+ ("build.compile", "Com&pile C…", "Build the current generated C with the selected compiler", "Compile generated C", "Compile", "settings", None, "Ctrl+Shift+Return", "window", False, "normal", False),
170
+ ("tools.check_python", "&Check Python Code…", "Check the selected tab with Python analysis and Ting rules", "Check Python code", "check", None, None, None, "window", False, "normal", False),
171
+ ("tools.register_imports", "Register Conversion &Imports…", "Manage registered conversion import files and availability", "Register conversion imports", None, "module", None, None, "window", False, "normal", False),
172
+ ("tools.run_python", "&Run Python…", "Open the saved active Python module in an editable terminal command dialog", "Run saved Python module", None, None, None, "F5", "window", False, "normal", False),
173
+ ("conversion.cancel", "&Cancel Transpilation", "Cancel the current isolated transpilation", "Cancel current transpilation", "Cancel", "cancel", None, None, "window", False, "danger", False),
174
+ ("edit.undo", "&Undo", "Undo the most recent source edit", "Undo source edit", None, "undo", "Undo", None, "window", False, "normal", False),
175
+ ("edit.redo", "&Redo", "Redo the most recently undone source edit", "Redo source edit", None, "redo", "Redo", None, "window", False, "normal", False),
176
+ ("edit.cut", "Cu&t", "Cut the selected writable text", "Cut selected text", None, "cut", "Cut", None, "window", False, "normal", False),
177
+ ("edit.copy", "&Copy", "Copy the current selection", "Copy current selection", None, "copy", "Copy", None, "window", False, "normal", False),
178
+ ("edit.paste", "&Paste", "Paste text into the writable source surface", "Paste text into source", None, "paste", "Paste", None, "window", False, "normal", False),
179
+ ("edit.clipboard", "PyCForge Clip&board…", "Browse code clips and paired Python/C captures", "Open PyCForge Clipboard", "Clipboard", "copy", None, None, "window", False, "normal", False),
180
+ ("edit.character_map", "C&haracter Map…", "Choose characters and copy them to the clipboard", "Open PyCForge Character Map", "Character Map", "whitespace", None, None, "window", False, "normal", False),
181
+ ("edit.select_all", "Select &All", "Select all text or visible records in the focused surface", "Select all content", None, "select-all", "SelectAll", None, "window", False, "normal", False),
182
+ ("edit.duplicate_line", "&Duplicate Line or Selection", "Duplicate the selected Python source lines", "Duplicate selected Python source lines", None, "duplicate-line", None, "Ctrl+Shift+D", "widget", False, "normal", False),
183
+ ("edit.move_line_up", "Move &Line Up", "Move the selected Python source lines one line earlier", "Move selected Python source lines up", None, "move-line-up", None, "Alt+Shift+Up", "widget", False, "normal", False),
184
+ ("edit.move_line_down", "Move Line Do&wn", "Move the selected Python source lines one line later", "Move selected Python source lines down", None, "move-line-down", None, "Alt+Shift+Down", "widget", False, "normal", False),
185
+ ("edit.indent", "&Indent Lines", "Indent the selected Python source lines by four spaces", "Indent selected Python source lines", None, "indent", None, "Ctrl+]", "widget", False, "normal", False),
186
+ ("edit.outdent", "&Outdent Lines", "Outdent the selected Python source lines by up to four spaces", "Outdent selected Python source lines", None, "outdent", None, "Ctrl+[", "widget", False, "normal", False),
187
+ ("edit.toggle_comment", "Toggle Co&mment", "Toggle Python line comments for the selected source lines", "Toggle comments on selected Python source lines", None, "toggle-comment", None, "Ctrl+/", "widget", False, "normal", False),
188
+ ("edit.select_next_occurrence", "Select &Next Occurrence", "Add the next exact occurrence as an editing selection", "Select next occurrence", None, "next-match", None, "Ctrl+D", "widget", False, "normal", False),
189
+ ("edit.select_all_occurrences", "Select All &Occurrences", "Select up to 256 exact occurrences for simultaneous editing", "Select all occurrences", None, "select-all", None, "Ctrl+Alt+L", "widget", False, "normal", False),
190
+ ("edit.clear_carets", "Clear &Extra Cursors", "Return to one editing cursor; Escape also clears extra cursors", "Clear extra cursors", None, None, None, None, "widget", False, "normal", False),
191
+ ("editor.smart_pairs", "&Smart Brackets and Quotes", "Pair brackets and quotes, wrap selections, and skip existing closers", "Smart brackets and quotes", None, None, None, None, "window", True, "normal", False),
192
+ ("editor.auto_complete", "&Automatic Completion", "Show offline completions and parameter hints while typing", "Automatic offline completion", None, None, None, None, "window", True, "normal", False),
193
+ ("editor.complete", "&Complete Name", "Show offline Python names and members at the cursor", "Complete Python name", None, None, None, "Ctrl+Space", "widget", False, "normal", False),
194
+ ("editor.parameter_hints", "Parameter &Hints", "Show the parameters of the current Python call", "Show Python parameter hints", None, None, None, "Ctrl+Shift+Space", "widget", False, "normal", False),
195
+ ("navigation.definition", "Go to &Definition", "Jump to a statically resolved definition in this document", "Go to Python definition", None, "go-to-source", None, "F12", "widget", False, "normal", False),
196
+ ("navigation.return_location", "Return to Previous &Location", "Return to the editing position before Go to Definition", "Return to previous editing location", None, "previous-match", None, "Alt+Left", "window", False, "normal", False),
197
+ ("edit.rename", "&Rename Name…", "Preview a scope-aware rename in the current Python document", "Rename Python name with preview", None, None, None, "F2", "widget", False, "normal", False),
198
+ ("edit.format_document", "Format &Document", "Format the current Python document as one undoable edit", "Format Python document", None, None, None, "Alt+Shift+F", "widget", False, "normal", False),
199
+ ("edit.format_selection", "Format &Selection", "Format the selected Python lines as one undoable edit", "Format selected Python lines", None, None, None, "Ctrl+K, Ctrl+F", "widget", False, "normal", False),
200
+ ("search.replace_bundle", "Replace in Open &Documents…", "Preview replacement across the open source bundle before applying", "Replace across open Python documents", None, "replace", None, "Ctrl+Shift+H", "window", False, "normal", False),
201
+ ("search.find", "&Find…", "Find text in the focused editor", "Find text", "Find", "find", "Find", None, "window", False, "normal", False),
202
+ ("search.replace", "R&eplace…", "Find and replace text in Python source", "Find and replace Python source text", None, "replace", "Replace", None, "window", False, "normal", False),
203
+ ("search.bundle", "Find in Source &Bundle…", "Search exact text across the already-open source bundle", "Find text in the open source bundle", "Bundle Search", "bundle-search", None, "Ctrl+Shift+F", "window", False, "normal", False),
204
+ ("search.next_match", "Find &Next", "Move to the next literal search match", "Find next match", None, "next-match", "FindNext", None, "widget", False, "normal", False),
205
+ ("search.previous_match", "Find Pre&vious", "Move to the previous literal search match", "Find previous match", None, "previous-match", None, "Shift+F3", "widget", False, "normal", False),
206
+ ("search.replace_current", "Replace &Current", "Replace the active Python source match", "Replace current source match", None, "replace", None, None, "widget", False, "normal", False),
207
+ ("search.replace_all", "Replace &All", "Replace every exact match in the active Python source document", "Replace all source matches", None, "replace", None, None, "widget", False, "normal", False),
208
+ ("search.close", "&Close Find", "Close the find and replace controls", "Close find and replace", None, "close", None, "Escape", "widget", False, "normal", False),
209
+ ("view.source_bundle", "Source &Bundle", "Show or hide the source bundle navigator", "Show or hide source bundle", None, "settings", None, "Ctrl+Alt+B", "window", True, "normal", False),
210
+ ("view.generated_c", "Generated &C", "Show or hide the read-only generated C viewer", "Show or hide generated C", None, "view-c", None, "Ctrl+Shift+C", "window", True, "normal", False),
211
+ ("view.conversion_details", "Transpilation &Details", "Show or hide structured transpilation details", "Show or hide transpilation details", None, "details", None, "Ctrl+Alt+D", "window", True, "normal", False),
212
+ ("view.outline", "&Outline", "Show the bounded outline for already-open Python source", "Show Python source outline", None, "outline", None, "Ctrl+Shift+O", "window", False, "normal", False),
213
+ ("view.conversion_history", "Transpilation &History", "Show bounded transpilation history for this application session", "Show current session transpilation history", None, "history", None, "Ctrl+Alt+H", "window", False, "normal", False),
214
+ ("view.whitespace", "Show &Whitespace", "Show or hide whitespace marks in Python source views", "Show or hide Python source whitespace", None, "whitespace", None, "Ctrl+Alt+W", "window", True, "normal", False),
215
+ ("view.increase_text_size", "&Increase Python Text Size", "Increase text in both Python source editor panes", "Increase Python source text size", None, None, None, "Ctrl+=", "window", False, "normal", False),
216
+ ("view.decrease_text_size", "Decrease Python Text Si&ze", "Decrease text in both Python source editor panes", "Decrease Python source text size", None, None, None, "Ctrl+-", "window", False, "normal", False),
217
+ ("view.reset_text_size", "&Reset Python Text Size", "Restore the 14 point default in both Python source editor panes", "Reset Python source text size", None, None, None, "Ctrl+0", "window", False, "normal", False),
218
+ ("workspace.editor_settings", "Code && &Editor Settings…", "Choose code text size and Python-to-C highlighting settings", "Open code and editor settings", None, "settings", None, "Ctrl+Alt+T", "window", False, "normal", False),
219
+ ("view.split_source", "Split Python &View", "Show or hide a second synchronized Python source view", "Split the Python source editor", None, "split-view", None, "Ctrl+\\", "window", True, "normal", False),
220
+ ("editor.toggle_fold", "To&ggle Code Fold State", "Fold or unfold the Python source region at the cursor", "Toggle Python source code fold", None, "toggle-fold", None, "Ctrl+Shift+[", "widget", False, "normal", False),
221
+ ("editor.fold_all", "Fold All Fu&nctions", "Fold every discovered function in the active Python source", "Fold all Python source functions", None, "collapse-all", None, None, "window", False, "normal", False),
222
+ ("editor.unfold_all", "Unfold All Function&s", "Unfold every function in the active Python source", "Unfold all Python source functions", None, "expand-all", None, None, "window", False, "normal", False),
223
+ ("navigation.go_to_line", "&Go to Line…", "Move to a line in the active Python source document", "Go to a Python source line", None, "go-to-line", None, "Ctrl+G", "window", False, "normal", False),
224
+ ("navigation.classes_functions", "&Classes && Functions…", "View classes and functions in the selected Python module", "View classes and functions", None, None, None, None, "window", False, "normal", False),
225
+ ("workspace.command_palette", "&Command Palette…", "Search and invoke enabled declared PyCForge actions", "Open the PyCForge command palette", "Commands", "command-palette", None, "Ctrl+Shift+P", "window", False, "normal", False),
226
+ ("tree.expand_all", "E&xpand All", "Expand every currently projected inspector branch", "Expand all inspector branches", None, "expand-all", None, None, "window", False, "normal", False),
227
+ ("tree.collapse_all", "C&ollapse All", "Collapse every currently projected inspector branch", "Collapse all inspector branches", None, "collapse-all", None, None, "window", False, "normal", False),
228
+ ("diagnostics.reveal_source", "&Reveal in Python Source", "Reveal the selected diagnostic in its Python source document", "Reveal selected diagnostic in Python source", None, "go-to-source", None, None, "window", False, "normal", False),
229
+ ("mappings.reveal_output", "&Reveal in Generated C", "Reveal the selected mapping in read-only generated C", "Reveal selected mapping in generated C", None, "go-to-output", None, None, "window", False, "normal", False),
230
+ ("mappings.reveal_source", "Reveal Source &Module", "Reveal the source module owned by the selected mapping", "Reveal selected mapping source module", None, "go-to-source", None, None, "window", False, "normal", False),
231
+ ("help.open", "PyCForge &Help…", "Open the complete searchable offline PyCForge help", "Open searchable PyCForge help", "Help", "help", None, "F1", "window", False, "normal", False),
232
+ ("help.about", "&About PyCForge…", "Show PyCForge version and product information", "Open About PyCForge", None, "brand-mark", None, None, "window", False, "normal", False),
233
+ )
234
+
235
+
236
+ def _catalog_action(row: tuple[object, ...]) -> ActionSpec:
237
+ (
238
+ action_id, menu_text, tooltip, accessible_name, toolbar_text,
239
+ icon_name, standard_shortcut, shortcut, shortcut_context,
240
+ checkable, tone, dynamic,
241
+ ) = row
242
+ return _action(
243
+ str(action_id), str(menu_text), str(tooltip), str(accessible_name),
244
+ toolbar_text=None if toolbar_text is None else str(toolbar_text),
245
+ icon_name=None if icon_name is None else str(icon_name),
246
+ standard_shortcut=(
247
+ None if standard_shortcut is None else str(standard_shortcut)
248
+ ),
249
+ shortcut=None if shortcut is None else str(shortcut),
250
+ shortcut_context=str(shortcut_context),
251
+ checkable=bool(checkable), tone=str(tone), dynamic=bool(dynamic),
252
+ )
253
+
254
+
255
+ _ACTION_SPECS = tuple(_catalog_action(row) for row in _ACTION_ROWS)
256
+
257
+ ACTION_SPECS: Mapping[str, ActionSpec] = MappingProxyType(
258
+ {spec.action_id: spec for spec in _ACTION_SPECS}
259
+ )
260
+
261
+ DYNAMIC_ACTION_GROUPS: Mapping[str, str] = MappingProxyType(
262
+ {"recent_python": "file.open_recent"}
263
+ )
264
+
265
+
266
+ def _surface(
267
+ surface_id: str,
268
+ kind: SurfaceKind,
269
+ title: str,
270
+ accessible_name: str,
271
+ *placements: ActionPlacement,
272
+ ) -> SurfaceSpec:
273
+ return SurfaceSpec(
274
+ surface_id,
275
+ kind,
276
+ title,
277
+ accessible_name,
278
+ tuple(placements),
279
+ )
280
+
281
+
282
+ def _layout(*tokens: str | None) -> tuple[ActionPlacement, ...]:
283
+ placements: list[ActionPlacement] = []
284
+ for token in tokens:
285
+ if token is None:
286
+ placements.append(ActionPlacement.separator())
287
+ elif token.startswith(">"):
288
+ placements.append(ActionPlacement.submenu(token[1:]))
289
+ elif token.startswith("$"):
290
+ placements.append(ActionPlacement.dynamic(token[1:]))
291
+ else:
292
+ placements.append(ActionPlacement.action(token))
293
+ return tuple(placements)
294
+
295
+
296
+ _SURFACE_SPECS = (
297
+ _surface(
298
+ "menu.file", SurfaceKind.MENU, "&File", "File menu",
299
+ *_layout(
300
+ "file.open_python", ">menu.open_recent", None,
301
+ "bundle.new_module", "bundle.remove_module", None,
302
+ "file.save_python", "file.save_python_as", "file.save_all_python", None,
303
+ ">menu.project", None,
304
+ "output.set_destination", "output.save_c", "output.export_modules",
305
+ ),
306
+ ),
307
+ _surface(
308
+ "menu.project", SurfaceKind.MENU, "&Project", "Project menu",
309
+ *_layout("project.open", "project.save", "project.save_as", None,
310
+ "project.checkpoint", "project.history"),
311
+ ),
312
+ _surface(
313
+ "menu.open_recent", SurfaceKind.MENU, "Open Recen&t",
314
+ "Open recent Python documents menu",
315
+ *_layout("$recent_python", None, "file.clear_recent"),
316
+ ),
317
+ _surface(
318
+ "menu.code_folding", SurfaceKind.MENU, "Folding Functio&ns",
319
+ "Python function folding menu",
320
+ *_layout(
321
+ "editor.toggle_fold", "editor.fold_all", "editor.unfold_all"
322
+ ),
323
+ ),
324
+ _surface(
325
+ "menu.edit", SurfaceKind.MENU, "&Edit", "Edit menu",
326
+ *_layout(
327
+ "edit.undo", "edit.redo", None, "edit.cut", "edit.copy",
328
+ "edit.paste", "edit.clipboard", "edit.character_map", None, ">menu.edit_selection", ">menu.edit_lines",
329
+ ">menu.edit_search", ">menu.edit_code", ">menu.code_folding",
330
+ ),
331
+ ),
332
+ _surface(
333
+ "menu.edit_selection", SurfaceKind.MENU, "&Selection", "Selection menu",
334
+ *_layout("edit.select_all", "edit.select_next_occurrence", "edit.select_all_occurrences", "edit.clear_carets"),
335
+ ),
336
+ _surface(
337
+ "menu.edit_lines", SurfaceKind.MENU, "&Lines", "Line editing menu",
338
+ *_layout("edit.duplicate_line", "edit.move_line_up", "edit.move_line_down", "edit.indent", "edit.outdent", "edit.toggle_comment"),
339
+ ),
340
+ _surface(
341
+ "menu.edit_search", SurfaceKind.MENU, "&Find and Replace", "Find and replace menu",
342
+ *_layout("search.find", "search.replace", "search.next_match", "search.previous_match", "search.bundle", "search.replace_bundle"),
343
+ ),
344
+ _surface(
345
+ "menu.edit_code", SurfaceKind.MENU, "C&ode", "Python code editing menu",
346
+ *_layout("editor.complete", "editor.parameter_hints", "navigation.definition", "navigation.return_location", "edit.rename", ">menu.edit_format", None, "editor.smart_pairs", "editor.auto_complete"),
347
+ ),
348
+ _surface(
349
+ "menu.edit_format", SurfaceKind.MENU, "&Format", "Python formatting menu",
350
+ *_layout("edit.format_document", "edit.format_selection"),
351
+ ),
352
+ _surface(
353
+ "menu.view", SurfaceKind.MENU, "&View", "View menu",
354
+ *_layout(
355
+ "view.source_bundle", "view.generated_c",
356
+ "view.conversion_details", None, "view.split_source",
357
+ "view.whitespace", None,
358
+ "view.increase_text_size", "view.decrease_text_size",
359
+ "view.reset_text_size", "workspace.editor_settings",
360
+ ),
361
+ ),
362
+ _surface(
363
+ "menu.navigate", SurfaceKind.MENU, "&Navigate", "Navigate menu",
364
+ *_layout(
365
+ "navigation.go_to_line", "search.bundle", "view.outline",
366
+ "navigation.definition", "navigation.return_location",
367
+ "view.conversion_history", None,
368
+ "workspace.command_palette",
369
+ ),
370
+ ),
371
+ _surface(
372
+ "menu.conversion", SurfaceKind.MENU, "&Transpile",
373
+ "Transpile menu",
374
+ *_layout("conversion.mode_typed", "conversion.mode_runtime", None, "build.compile"),
375
+ ),
376
+ _surface(
377
+ "menu.tools", SurfaceKind.MENU, "T&ools", "Tools menu",
378
+ *_layout("tools.check_python", "tools.run_python", "tools.register_imports"),
379
+ ),
380
+ _surface(
381
+ "menu.help", SurfaceKind.MENU, "&Help", "Help menu",
382
+ *_layout("help.open", None, "help.about"),
383
+ ),
384
+ _surface(
385
+ "toolbar.workspace", SurfaceKind.TOOLBAR, "PyCForge Workspace",
386
+ "PyCForge workspace actions",
387
+ *_layout(
388
+ "file.open_python", "file.save_python", None,
389
+ "edit.undo", "edit.redo", None,
390
+ "edit.cut", "edit.copy", "edit.paste", "edit.clipboard", "edit.character_map", None,
391
+ "conversion.convert", "conversion.cancel", "build.compile", None,
392
+ "view.generated_c", "view.conversion_details", "search.find",
393
+ None, "output.set_destination", "output.save_c",
394
+ ),
395
+ ),
396
+ _surface(
397
+ "context.python_source", SurfaceKind.CONTEXT, "Python Source",
398
+ "Python source editor menu",
399
+ *_layout(
400
+ "edit.undo", "edit.redo", None, "edit.cut", "edit.copy",
401
+ "edit.paste", "edit.clipboard", "edit.character_map", None, ">menu.edit_selection", ">menu.edit_lines",
402
+ ">menu.edit_search", ">menu.edit_code", ">menu.code_folding",
403
+ ),
404
+ ),
405
+ _surface(
406
+ "context.generated_c", SurfaceKind.CONTEXT, "Generated C",
407
+ "Generated C viewer menu",
408
+ *_layout("edit.copy", "edit.select_all", None, "search.find"),
409
+ ),
410
+ _surface(
411
+ "context.source_bundle", SurfaceKind.CONTEXT, "Source Bundle",
412
+ "Source bundle menu",
413
+ *_layout(
414
+ "bundle.new_module", "bundle.remove_module", None,
415
+ "bundle.move_up", "bundle.move_down", "bundle.make_primary",
416
+ ),
417
+ ),
418
+ _surface(
419
+ "context.document_tabs", SurfaceKind.CONTEXT, "Document Tabs",
420
+ "Python document tabs menu",
421
+ *_layout(
422
+ "file.save_python", "file.save_python_as", None,
423
+ "bundle.remove_module", "bundle.make_primary", None,
424
+ "navigation.classes_functions", "view.split_source",
425
+ ),
426
+ ),
427
+ _surface(
428
+ "context.diagnostics", SurfaceKind.CONTEXT, "Diagnostics",
429
+ "Diagnostics menu",
430
+ *_layout("edit.copy", None, "diagnostics.reveal_source"),
431
+ ),
432
+ _surface(
433
+ "context.mappings", SurfaceKind.CONTEXT, "Mappings",
434
+ "Source mappings menu",
435
+ *_layout(
436
+ "edit.copy", None, "mappings.reveal_output",
437
+ "mappings.reveal_source",
438
+ ),
439
+ ),
440
+ _surface(
441
+ "context.bundle_search", SurfaceKind.CONTEXT, "Bundle Search",
442
+ "Source bundle search results menu",
443
+ *_layout("edit.copy"),
444
+ ),
445
+ _surface(
446
+ "context.conversion_history", SurfaceKind.CONTEXT,
447
+ "Transpilation History", "Transpilation history menu",
448
+ *_layout("edit.copy"),
449
+ ),
450
+ _surface(
451
+ "context.inspector", SurfaceKind.CONTEXT, "Inspector",
452
+ "Inspector tree menu",
453
+ *_layout(
454
+ "edit.copy", None, "tree.expand_all", "tree.collapse_all",
455
+ ),
456
+ ),
457
+ _surface(
458
+ "context.text_input", SurfaceKind.CONTEXT, "Text Input",
459
+ "Text editing menu",
460
+ *_layout(
461
+ "edit.undo", "edit.redo", None, "edit.cut", "edit.copy",
462
+ "edit.paste", None, "edit.select_all",
463
+ ),
464
+ ),
465
+ _surface(
466
+ "context.read_only_text", SurfaceKind.CONTEXT, "Read-only Text",
467
+ "Read-only text menu",
468
+ *_layout("edit.copy", "edit.select_all"),
469
+ ),
470
+ )
471
+
472
+ SURFACE_SPECS: Mapping[str, SurfaceSpec] = MappingProxyType(
473
+ {spec.surface_id: spec for spec in _SURFACE_SPECS}
474
+ )
475
+
476
+ MAIN_MENU_SURFACES = (
477
+ "menu.file",
478
+ "menu.edit",
479
+ "menu.view",
480
+ "menu.navigate",
481
+ "menu.conversion",
482
+ "menu.help",
483
+ "menu.tools",
484
+ )
485
+
486
+
487
+ def validated_dynamic_entries(
488
+ entries: Iterable[DynamicActionEntry],
489
+ ) -> tuple[DynamicActionEntry, ...]:
490
+ """Return bounded entries after rejecting ambiguous or oversized data."""
491
+
492
+ records = tuple(entries)
493
+ if len(records) > MAX_DYNAMIC_ACTIONS:
494
+ raise ValueError(
495
+ f"dynamic actions exceed the limit of {MAX_DYNAMIC_ACTIONS}"
496
+ )
497
+ seen: set[str] = set()
498
+ for entry in records:
499
+ if not isinstance(entry, DynamicActionEntry):
500
+ raise TypeError("dynamic entries must be DynamicActionEntry values")
501
+ if not entry.key or entry.key in seen:
502
+ raise ValueError("dynamic action keys must be non-empty and unique")
503
+ seen.add(entry.key)
504
+ if not entry.label or len(entry.label) > MAX_DYNAMIC_LABEL_CHARS:
505
+ raise ValueError("dynamic action label is empty or oversized")
506
+ if (
507
+ not entry.tooltip
508
+ or len(entry.tooltip) > MAX_DYNAMIC_TOOLTIP_CHARS
509
+ ):
510
+ raise ValueError("dynamic action tooltip is empty or oversized")
511
+ if not entry.accessible_name:
512
+ raise ValueError("dynamic action accessible name is required")
513
+ if not isinstance(entry.payload, str):
514
+ raise TypeError("dynamic action payload must be text")
515
+ return records
516
+
517
+
518
+ def validate_action_contract(
519
+ *,
520
+ action_specs: Mapping[str, ActionSpec] = ACTION_SPECS,
521
+ surface_specs: Mapping[str, SurfaceSpec] = SURFACE_SPECS,
522
+ dynamic_groups: Mapping[str, str] = DYNAMIC_ACTION_GROUPS,
523
+ ) -> tuple[str, ...]:
524
+ """Return deterministic contract errors without importing optional Qt."""
525
+
526
+ from .action_validation import validate_action_contract as validate
527
+
528
+ return validate(
529
+ action_specs=action_specs,
530
+ surface_specs=surface_specs,
531
+ dynamic_groups=dynamic_groups,
532
+ )
533
+
534
+
535
+ __all__ = [
536
+ "ACTION_SPECS",
537
+ "DYNAMIC_ACTION_GROUPS",
538
+ "MAIN_MENU_SURFACES",
539
+ "MAX_DYNAMIC_ACTIONS",
540
+ "ActionPlacement",
541
+ "ActionSpec",
542
+ "ActionState",
543
+ "DynamicActionEntry",
544
+ "PlacementKind",
545
+ "SURFACE_SPECS",
546
+ "SurfaceKind",
547
+ "SurfaceSpec",
548
+ "validate_action_contract",
549
+ "validated_dynamic_entries",
550
+ ]