@gtkx/cli 1.0.0-rc.4 → 1.1.0

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 (520) hide show
  1. package/README.md +5 -5
  2. package/dist/builder.d.ts +2 -2
  3. package/dist/builder.d.ts.map +1 -1
  4. package/dist/builder.js +21 -3
  5. package/dist/builder.js.map +1 -1
  6. package/dist/cli.js +9 -3
  7. package/dist/cli.js.map +1 -1
  8. package/dist/codegen/freshness.d.ts.map +1 -1
  9. package/dist/codegen/freshness.js +2 -4
  10. package/dist/codegen/freshness.js.map +1 -1
  11. package/dist/codegen/run-codegen.d.ts +8 -5
  12. package/dist/codegen/run-codegen.d.ts.map +1 -1
  13. package/dist/codegen/run-codegen.js +25 -19
  14. package/dist/codegen/run-codegen.js.map +1 -1
  15. package/dist/codegen/store-resolver.d.ts +1 -1
  16. package/dist/codegen/store-resolver.d.ts.map +1 -1
  17. package/dist/codegen/store-resolver.js.map +1 -1
  18. package/dist/commands/build.d.ts.map +1 -1
  19. package/dist/commands/build.js +5 -6
  20. package/dist/commands/build.js.map +1 -1
  21. package/dist/commands/codegen.d.ts.map +1 -1
  22. package/dist/commands/codegen.js +11 -1
  23. package/dist/commands/codegen.js.map +1 -1
  24. package/dist/commands/deploy.d.ts +22 -0
  25. package/dist/commands/deploy.d.ts.map +1 -0
  26. package/dist/commands/deploy.js +44 -0
  27. package/dist/commands/deploy.js.map +1 -0
  28. package/dist/commands/dev.d.ts.map +1 -1
  29. package/dist/commands/dev.js +7 -5
  30. package/dist/commands/dev.js.map +1 -1
  31. package/dist/commands/docs.d.ts +2 -2
  32. package/dist/commands/docs.d.ts.map +1 -1
  33. package/dist/commands/docs.js +27 -4
  34. package/dist/commands/docs.js.map +1 -1
  35. package/dist/deploy/depends.d.ts +8 -0
  36. package/dist/deploy/depends.d.ts.map +1 -0
  37. package/dist/deploy/depends.js +27 -0
  38. package/dist/deploy/depends.js.map +1 -0
  39. package/dist/deploy/download.d.ts +20 -0
  40. package/dist/deploy/download.d.ts.map +1 -0
  41. package/dist/deploy/download.js +98 -0
  42. package/dist/deploy/download.js.map +1 -0
  43. package/dist/deploy/freedesktop/copyright.d.ts +4 -0
  44. package/dist/deploy/freedesktop/copyright.d.ts.map +1 -0
  45. package/dist/deploy/freedesktop/copyright.js +33 -0
  46. package/dist/deploy/freedesktop/copyright.js.map +1 -0
  47. package/dist/deploy/freedesktop/dbus-service.d.ts +4 -0
  48. package/dist/deploy/freedesktop/dbus-service.d.ts.map +1 -0
  49. package/dist/deploy/freedesktop/dbus-service.js +15 -0
  50. package/dist/deploy/freedesktop/dbus-service.js.map +1 -0
  51. package/dist/deploy/freedesktop/desktop-entry.d.ts +4 -0
  52. package/dist/deploy/freedesktop/desktop-entry.d.ts.map +1 -0
  53. package/dist/deploy/freedesktop/desktop-entry.js +73 -0
  54. package/dist/deploy/freedesktop/desktop-entry.js.map +1 -0
  55. package/dist/deploy/freedesktop/ini.d.ts +7 -0
  56. package/dist/deploy/freedesktop/ini.d.ts.map +1 -0
  57. package/dist/deploy/freedesktop/ini.js +22 -0
  58. package/dist/deploy/freedesktop/ini.js.map +1 -0
  59. package/dist/deploy/freedesktop/metainfo-sections.d.ts +13 -0
  60. package/dist/deploy/freedesktop/metainfo-sections.d.ts.map +1 -0
  61. package/dist/deploy/freedesktop/metainfo-sections.js +73 -0
  62. package/dist/deploy/freedesktop/metainfo-sections.js.map +1 -0
  63. package/dist/deploy/freedesktop/metainfo.d.ts +4 -0
  64. package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -0
  65. package/dist/deploy/freedesktop/metainfo.js +29 -0
  66. package/dist/deploy/freedesktop/metainfo.js.map +1 -0
  67. package/dist/deploy/freedesktop/mime-package.d.ts +4 -0
  68. package/dist/deploy/freedesktop/mime-package.d.ts.map +1 -0
  69. package/dist/deploy/freedesktop/mime-package.js +16 -0
  70. package/dist/deploy/freedesktop/mime-package.js.map +1 -0
  71. package/dist/deploy/freedesktop/validate.d.ts +4 -0
  72. package/dist/deploy/freedesktop/validate.d.ts.map +1 -0
  73. package/dist/deploy/freedesktop/validate.js +81 -0
  74. package/dist/deploy/freedesktop/validate.js.map +1 -0
  75. package/dist/deploy/freedesktop/xml.d.ts +11 -0
  76. package/dist/deploy/freedesktop/xml.d.ts.map +1 -0
  77. package/dist/deploy/freedesktop/xml.js +33 -0
  78. package/dist/deploy/freedesktop/xml.js.map +1 -0
  79. package/dist/deploy/git.d.ts +4 -0
  80. package/dist/deploy/git.d.ts.map +1 -0
  81. package/dist/deploy/git.js +17 -0
  82. package/dist/deploy/git.js.map +1 -0
  83. package/dist/deploy/install-hints.d.ts +5 -0
  84. package/dist/deploy/install-hints.d.ts.map +1 -0
  85. package/dist/deploy/install-hints.js +85 -0
  86. package/dist/deploy/install-hints.js.map +1 -0
  87. package/dist/deploy/nfpm/config.d.ts +8 -0
  88. package/dist/deploy/nfpm/config.d.ts.map +1 -0
  89. package/dist/deploy/nfpm/config.js +119 -0
  90. package/dist/deploy/nfpm/config.js.map +1 -0
  91. package/dist/deploy/nfpm/contents.d.ts +12 -0
  92. package/dist/deploy/nfpm/contents.d.ts.map +1 -0
  93. package/dist/deploy/nfpm/contents.js +48 -0
  94. package/dist/deploy/nfpm/contents.js.map +1 -0
  95. package/dist/deploy/nfpm/description.d.ts +5 -0
  96. package/dist/deploy/nfpm/description.d.ts.map +1 -0
  97. package/dist/deploy/nfpm/description.js +5 -0
  98. package/dist/deploy/nfpm/description.js.map +1 -0
  99. package/dist/deploy/nfpm/optional.d.ts +5 -0
  100. package/dist/deploy/nfpm/optional.d.ts.map +1 -0
  101. package/dist/deploy/nfpm/optional.js +4 -0
  102. package/dist/deploy/nfpm/optional.js.map +1 -0
  103. package/dist/deploy/nfpm/pack.d.ts +5 -0
  104. package/dist/deploy/nfpm/pack.d.ts.map +1 -0
  105. package/dist/deploy/nfpm/pack.js +32 -0
  106. package/dist/deploy/nfpm/pack.js.map +1 -0
  107. package/dist/deploy/node-runtime/download.d.ts +3 -0
  108. package/dist/deploy/node-runtime/download.d.ts.map +1 -0
  109. package/dist/deploy/node-runtime/download.js +39 -0
  110. package/dist/deploy/node-runtime/download.js.map +1 -0
  111. package/dist/deploy/node-runtime/elf.d.ts +7 -0
  112. package/dist/deploy/node-runtime/elf.d.ts.map +1 -0
  113. package/dist/deploy/node-runtime/elf.js +100 -0
  114. package/dist/deploy/node-runtime/elf.js.map +1 -0
  115. package/dist/deploy/node-runtime/guard.d.ts +4 -0
  116. package/dist/deploy/node-runtime/guard.d.ts.map +1 -0
  117. package/dist/deploy/node-runtime/guard.js +22 -0
  118. package/dist/deploy/node-runtime/guard.js.map +1 -0
  119. package/dist/deploy/node-runtime/index.d.ts +4 -0
  120. package/dist/deploy/node-runtime/index.d.ts.map +1 -0
  121. package/dist/deploy/node-runtime/index.js +61 -0
  122. package/dist/deploy/node-runtime/index.js.map +1 -0
  123. package/dist/deploy/payload/copy-tree.d.ts +7 -0
  124. package/dist/deploy/payload/copy-tree.d.ts.map +1 -0
  125. package/dist/deploy/payload/copy-tree.js +36 -0
  126. package/dist/deploy/payload/copy-tree.js.map +1 -0
  127. package/dist/deploy/payload/icons.d.ts +6 -0
  128. package/dist/deploy/payload/icons.d.ts.map +1 -0
  129. package/dist/deploy/payload/icons.js +53 -0
  130. package/dist/deploy/payload/icons.js.map +1 -0
  131. package/dist/deploy/payload/launcher.d.ts +5 -0
  132. package/dist/deploy/payload/launcher.d.ts.map +1 -0
  133. package/dist/deploy/payload/launcher.js +22 -0
  134. package/dist/deploy/payload/launcher.js.map +1 -0
  135. package/dist/deploy/payload/schemas.d.ts +4 -0
  136. package/dist/deploy/payload/schemas.d.ts.map +1 -0
  137. package/dist/deploy/payload/schemas.js +17 -0
  138. package/dist/deploy/payload/schemas.js.map +1 -0
  139. package/dist/deploy/payload/stage.d.ts +15 -0
  140. package/dist/deploy/payload/stage.d.ts.map +1 -0
  141. package/dist/deploy/payload/stage.js +100 -0
  142. package/dist/deploy/payload/stage.js.map +1 -0
  143. package/dist/deploy/registry.d.ts +7 -0
  144. package/dist/deploy/registry.d.ts.map +1 -0
  145. package/dist/deploy/registry.js +30 -0
  146. package/dist/deploy/registry.js.map +1 -0
  147. package/dist/deploy/run-deploy.d.ts +11 -0
  148. package/dist/deploy/run-deploy.d.ts.map +1 -0
  149. package/dist/deploy/run-deploy.js +153 -0
  150. package/dist/deploy/run-deploy.js.map +1 -0
  151. package/dist/deploy/settings/arch.d.ts +4 -0
  152. package/dist/deploy/settings/arch.d.ts.map +1 -0
  153. package/dist/deploy/settings/arch.js +13 -0
  154. package/dist/deploy/settings/arch.js.map +1 -0
  155. package/dist/deploy/settings/categories.d.ts +4 -0
  156. package/dist/deploy/settings/categories.d.ts.map +1 -0
  157. package/dist/deploy/settings/categories.js +29 -0
  158. package/dist/deploy/settings/categories.js.map +1 -0
  159. package/dist/deploy/settings/exec.d.ts +6 -0
  160. package/dist/deploy/settings/exec.d.ts.map +1 -0
  161. package/dist/deploy/settings/exec.js +20 -0
  162. package/dist/deploy/settings/exec.js.map +1 -0
  163. package/dist/deploy/settings/identity.d.ts +18 -0
  164. package/dist/deploy/settings/identity.d.ts.map +1 -0
  165. package/dist/deploy/settings/identity.js +73 -0
  166. package/dist/deploy/settings/identity.js.map +1 -0
  167. package/dist/deploy/settings/index.d.ts +11 -0
  168. package/dist/deploy/settings/index.d.ts.map +1 -0
  169. package/dist/deploy/settings/index.js +103 -0
  170. package/dist/deploy/settings/index.js.map +1 -0
  171. package/dist/deploy/settings/package-manifest.d.ts +15 -0
  172. package/dist/deploy/settings/package-manifest.d.ts.map +1 -0
  173. package/dist/deploy/settings/package-manifest.js +41 -0
  174. package/dist/deploy/settings/package-manifest.js.map +1 -0
  175. package/dist/deploy/settings/paths.d.ts +9 -0
  176. package/dist/deploy/settings/paths.d.ts.map +1 -0
  177. package/dist/deploy/settings/paths.js +82 -0
  178. package/dist/deploy/settings/paths.js.map +1 -0
  179. package/dist/deploy/settings/screenshots.d.ts +8 -0
  180. package/dist/deploy/settings/screenshots.d.ts.map +1 -0
  181. package/dist/deploy/settings/screenshots.js +79 -0
  182. package/dist/deploy/settings/screenshots.js.map +1 -0
  183. package/dist/deploy/settings/starter.d.ts +4 -0
  184. package/dist/deploy/settings/starter.d.ts.map +1 -0
  185. package/dist/deploy/settings/starter.js +28 -0
  186. package/dist/deploy/settings/starter.js.map +1 -0
  187. package/dist/deploy/settings/version.d.ts +9 -0
  188. package/dist/deploy/settings/version.d.ts.map +1 -0
  189. package/dist/deploy/settings/version.js +37 -0
  190. package/dist/deploy/settings/version.js.map +1 -0
  191. package/dist/deploy/targets/appimage.d.ts +4 -0
  192. package/dist/deploy/targets/appimage.d.ts.map +1 -0
  193. package/dist/deploy/targets/appimage.js +105 -0
  194. package/dist/deploy/targets/appimage.js.map +1 -0
  195. package/dist/deploy/targets/deb.d.ts +4 -0
  196. package/dist/deploy/targets/deb.d.ts.map +1 -0
  197. package/dist/deploy/targets/deb.js +4 -0
  198. package/dist/deploy/targets/deb.js.map +1 -0
  199. package/dist/deploy/targets/flatpak-manifest.d.ts +6 -0
  200. package/dist/deploy/targets/flatpak-manifest.d.ts.map +1 -0
  201. package/dist/deploy/targets/flatpak-manifest.js +48 -0
  202. package/dist/deploy/targets/flatpak-manifest.js.map +1 -0
  203. package/dist/deploy/targets/flatpak-prebuilt.d.ts +8 -0
  204. package/dist/deploy/targets/flatpak-prebuilt.d.ts.map +1 -0
  205. package/dist/deploy/targets/flatpak-prebuilt.js +43 -0
  206. package/dist/deploy/targets/flatpak-prebuilt.js.map +1 -0
  207. package/dist/deploy/targets/flatpak-source.d.ts +5 -0
  208. package/dist/deploy/targets/flatpak-source.d.ts.map +1 -0
  209. package/dist/deploy/targets/flatpak-source.js +110 -0
  210. package/dist/deploy/targets/flatpak-source.js.map +1 -0
  211. package/dist/deploy/targets/flatpak-sources.d.ts +17 -0
  212. package/dist/deploy/targets/flatpak-sources.d.ts.map +1 -0
  213. package/dist/deploy/targets/flatpak-sources.js +108 -0
  214. package/dist/deploy/targets/flatpak-sources.js.map +1 -0
  215. package/dist/deploy/targets/flatpak.d.ts +4 -0
  216. package/dist/deploy/targets/flatpak.d.ts.map +1 -0
  217. package/dist/deploy/targets/flatpak.js +112 -0
  218. package/dist/deploy/targets/flatpak.js.map +1 -0
  219. package/dist/deploy/targets/nfpm-target.d.ts +5 -0
  220. package/dist/deploy/targets/nfpm-target.d.ts.map +1 -0
  221. package/dist/deploy/targets/nfpm-target.js +26 -0
  222. package/dist/deploy/targets/nfpm-target.js.map +1 -0
  223. package/dist/deploy/targets/rpm.d.ts +4 -0
  224. package/dist/deploy/targets/rpm.d.ts.map +1 -0
  225. package/dist/deploy/targets/rpm.js +4 -0
  226. package/dist/deploy/targets/rpm.js.map +1 -0
  227. package/dist/deploy/tools.d.ts +18 -0
  228. package/dist/deploy/tools.d.ts.map +1 -0
  229. package/dist/deploy/tools.js +92 -0
  230. package/dist/deploy/tools.js.map +1 -0
  231. package/dist/deploy/types.d.ts +140 -0
  232. package/dist/deploy/types.d.ts.map +1 -0
  233. package/dist/deploy/types.js +2 -0
  234. package/dist/deploy/types.js.map +1 -0
  235. package/dist/deploy/vendored/appimagetool.d.ts +7 -0
  236. package/dist/deploy/vendored/appimagetool.d.ts.map +1 -0
  237. package/dist/deploy/vendored/appimagetool.js +42 -0
  238. package/dist/deploy/vendored/appimagetool.js.map +1 -0
  239. package/dist/deploy/vendored/nfpm.d.ts +3 -0
  240. package/dist/deploy/vendored/nfpm.d.ts.map +1 -0
  241. package/dist/deploy/vendored/nfpm.js +60 -0
  242. package/dist/deploy/vendored/nfpm.js.map +1 -0
  243. package/dist/dev/change-queue.d.ts +11 -0
  244. package/dist/dev/change-queue.d.ts.map +1 -0
  245. package/dist/dev/change-queue.js +34 -0
  246. package/dist/dev/change-queue.js.map +1 -0
  247. package/dist/dev/entry-env.d.ts +3 -0
  248. package/dist/dev/entry-env.d.ts.map +1 -0
  249. package/dist/dev/entry-env.js +3 -0
  250. package/dist/dev/entry-env.js.map +1 -0
  251. package/dist/dev/failure-tracker.d.ts +10 -0
  252. package/dist/dev/failure-tracker.d.ts.map +1 -0
  253. package/dist/dev/failure-tracker.js +61 -0
  254. package/dist/dev/failure-tracker.js.map +1 -0
  255. package/dist/dev/missing-import.d.ts +4 -0
  256. package/dist/dev/missing-import.d.ts.map +1 -0
  257. package/dist/dev/missing-import.js +23 -0
  258. package/dist/dev/missing-import.js.map +1 -0
  259. package/dist/dev/runner-deps.d.ts.map +1 -1
  260. package/dist/dev/runner-deps.js +25 -5
  261. package/dist/dev/runner-deps.js.map +1 -1
  262. package/dist/dev/runner-main.d.ts.map +1 -1
  263. package/dist/dev/runner-main.js +3 -3
  264. package/dist/dev/runner-main.js.map +1 -1
  265. package/dist/dev/runner.d.ts +8 -3
  266. package/dist/dev/runner.d.ts.map +1 -1
  267. package/dist/dev/runner.js +343 -65
  268. package/dist/dev/runner.js.map +1 -1
  269. package/dist/dev/supervisor.d.ts +10 -4
  270. package/dist/dev/supervisor.d.ts.map +1 -1
  271. package/dist/dev/supervisor.js +23 -4
  272. package/dist/dev/supervisor.js.map +1 -1
  273. package/dist/dev/vite-dev-server.d.ts +13 -2
  274. package/dist/dev/vite-dev-server.d.ts.map +1 -1
  275. package/dist/dev/vite-dev-server.js +30 -2
  276. package/dist/dev/vite-dev-server.js.map +1 -1
  277. package/dist/internal/application-args.d.ts +6 -0
  278. package/dist/internal/application-args.d.ts.map +1 -0
  279. package/dist/internal/application-args.js +10 -0
  280. package/dist/internal/application-args.js.map +1 -0
  281. package/dist/internal/entry-arg.d.ts +1 -7
  282. package/dist/internal/entry-arg.d.ts.map +1 -1
  283. package/dist/internal/entry-arg.js +18 -11
  284. package/dist/internal/entry-arg.js.map +1 -1
  285. package/dist/internal/errors.d.ts +1 -2
  286. package/dist/internal/errors.d.ts.map +1 -1
  287. package/dist/internal/errors.js +1 -1
  288. package/dist/internal/errors.js.map +1 -1
  289. package/dist/internal/module-loads.d.ts +7 -0
  290. package/dist/internal/module-loads.d.ts.map +1 -0
  291. package/dist/internal/module-loads.js +21 -0
  292. package/dist/internal/module-loads.js.map +1 -0
  293. package/dist/internal/prepare-project.d.ts +16 -0
  294. package/dist/internal/prepare-project.d.ts.map +1 -0
  295. package/dist/internal/prepare-project.js +15 -0
  296. package/dist/internal/prepare-project.js.map +1 -0
  297. package/dist/internal/run-cli-tool.d.ts +11 -0
  298. package/dist/internal/run-cli-tool.d.ts.map +1 -0
  299. package/dist/internal/run-cli-tool.js +24 -0
  300. package/dist/internal/run-cli-tool.js.map +1 -0
  301. package/dist/internal/staging-dir.d.ts +8 -1
  302. package/dist/internal/staging-dir.d.ts.map +1 -1
  303. package/dist/internal/staging-dir.js +38 -2
  304. package/dist/internal/staging-dir.js.map +1 -1
  305. package/dist/mcp/client.d.ts +1 -1
  306. package/dist/mcp/client.d.ts.map +1 -1
  307. package/dist/mcp/client.js.map +1 -1
  308. package/dist/mcp/handlers.d.ts +1 -1
  309. package/dist/mcp/handlers.d.ts.map +1 -1
  310. package/dist/mcp/handlers.js +78 -41
  311. package/dist/mcp/handlers.js.map +1 -1
  312. package/dist/mcp/index.d.ts.map +1 -1
  313. package/dist/mcp/index.js +1 -0
  314. package/dist/mcp/index.js.map +1 -1
  315. package/dist/mcp/serialize-widget.d.ts +4 -3
  316. package/dist/mcp/serialize-widget.d.ts.map +1 -1
  317. package/dist/mcp/serialize-widget.js +47 -17
  318. package/dist/mcp/serialize-widget.js.map +1 -1
  319. package/dist/mcp/testing-loader.d.ts +5 -2
  320. package/dist/mcp/testing-loader.d.ts.map +1 -1
  321. package/dist/mcp/testing-loader.js +7 -3
  322. package/dist/mcp/testing-loader.js.map +1 -1
  323. package/dist/mcp/widget-properties.d.ts +6 -0
  324. package/dist/mcp/widget-properties.d.ts.map +1 -0
  325. package/dist/mcp/widget-properties.js +102 -0
  326. package/dist/mcp/widget-properties.js.map +1 -0
  327. package/dist/refresh-runtime.d.ts +2 -1
  328. package/dist/refresh-runtime.d.ts.map +1 -1
  329. package/dist/refresh-runtime.js +32 -2
  330. package/dist/refresh-runtime.js.map +1 -1
  331. package/dist/settings/compile.d.ts.map +1 -1
  332. package/dist/settings/compile.js +8 -12
  333. package/dist/settings/compile.js.map +1 -1
  334. package/dist/settings/schema.d.ts +1 -2
  335. package/dist/settings/schema.d.ts.map +1 -1
  336. package/dist/settings/schema.js +1 -1
  337. package/dist/settings/schema.js.map +1 -1
  338. package/dist/vite-plugins/asset-emitter.d.ts +9 -0
  339. package/dist/vite-plugins/asset-emitter.d.ts.map +1 -0
  340. package/dist/vite-plugins/asset-emitter.js +2 -0
  341. package/dist/vite-plugins/asset-emitter.js.map +1 -0
  342. package/dist/vite-plugins/asset-extensions.d.ts +2 -2
  343. package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
  344. package/dist/vite-plugins/asset-extensions.js +2 -1
  345. package/dist/vite-plugins/asset-extensions.js.map +1 -1
  346. package/dist/vite-plugins/asset-imports.d.ts +4 -0
  347. package/dist/vite-plugins/asset-imports.d.ts.map +1 -0
  348. package/dist/vite-plugins/asset-imports.js +88 -0
  349. package/dist/vite-plugins/asset-imports.js.map +1 -0
  350. package/dist/vite-plugins/asset-specifier.d.ts +5 -0
  351. package/dist/vite-plugins/asset-specifier.d.ts.map +1 -0
  352. package/dist/vite-plugins/asset-specifier.js +7 -0
  353. package/dist/vite-plugins/asset-specifier.js.map +1 -0
  354. package/dist/vite-plugins/built-url.d.ts.map +1 -1
  355. package/dist/vite-plugins/built-url.js +14 -10
  356. package/dist/vite-plugins/built-url.js.map +1 -1
  357. package/dist/vite-plugins/ensure-store.d.ts +4 -0
  358. package/dist/vite-plugins/ensure-store.d.ts.map +1 -0
  359. package/dist/vite-plugins/ensure-store.js +10 -0
  360. package/dist/vite-plugins/ensure-store.js.map +1 -0
  361. package/dist/vite-plugins/esm-extension.d.ts +4 -0
  362. package/dist/vite-plugins/esm-extension.d.ts.map +1 -0
  363. package/dist/vite-plugins/esm-extension.js +4 -0
  364. package/dist/vite-plugins/esm-extension.js.map +1 -0
  365. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts +1 -3
  366. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -1
  367. package/dist/vite-plugins/fast-refresh/swc-refresh.js +1 -1
  368. package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -1
  369. package/dist/vite-plugins/icons.d.ts.map +1 -1
  370. package/dist/vite-plugins/icons.js.map +1 -1
  371. package/dist/vite-plugins/index.d.ts.map +1 -1
  372. package/dist/vite-plugins/index.js +4 -0
  373. package/dist/vite-plugins/index.js.map +1 -1
  374. package/dist/vite-plugins/react-compiler.d.ts +1 -1
  375. package/dist/vite-plugins/react-compiler.d.ts.map +1 -1
  376. package/dist/vite-plugins/react-compiler.js.map +1 -1
  377. package/dist/vite-plugins/resource-shared.d.ts +2 -1
  378. package/dist/vite-plugins/resource-shared.d.ts.map +1 -1
  379. package/dist/vite-plugins/resource-shared.js +2 -1
  380. package/dist/vite-plugins/resource-shared.js.map +1 -1
  381. package/dist/vite-plugins/resources.d.ts +1 -1
  382. package/dist/vite-plugins/resources.d.ts.map +1 -1
  383. package/dist/vite-plugins/resources.js +36 -44
  384. package/dist/vite-plugins/resources.js.map +1 -1
  385. package/dist/vite-plugins/self-contained.d.ts +4 -0
  386. package/dist/vite-plugins/self-contained.d.ts.map +1 -0
  387. package/dist/vite-plugins/self-contained.js +244 -0
  388. package/dist/vite-plugins/self-contained.js.map +1 -0
  389. package/dist/vite-plugins/settings.d.ts.map +1 -1
  390. package/dist/vite-plugins/settings.js +19 -40
  391. package/dist/vite-plugins/settings.js.map +1 -1
  392. package/dist/vite-plugins/store-links.d.ts +4 -0
  393. package/dist/vite-plugins/store-links.d.ts.map +1 -0
  394. package/dist/vite-plugins/store-links.js +19 -0
  395. package/dist/vite-plugins/store-links.js.map +1 -0
  396. package/dist/vite-plugins/undeclared-library.d.ts +1 -1
  397. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
  398. package/dist/vite-plugins/undeclared-library.js +51 -12
  399. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  400. package/dist/vite-plugins/worker.d.ts +4 -0
  401. package/dist/vite-plugins/worker.d.ts.map +1 -0
  402. package/dist/vite-plugins/worker.js +138 -0
  403. package/dist/vite-plugins/worker.js.map +1 -0
  404. package/dist/vitest-plugin.d.ts +7 -0
  405. package/dist/vitest-plugin.d.ts.map +1 -1
  406. package/dist/vitest-plugin.js +14 -1
  407. package/dist/vitest-plugin.js.map +1 -1
  408. package/env.d.ts +106 -25
  409. package/package.json +23 -12
  410. package/src/builder.ts +24 -5
  411. package/src/cli.ts +10 -3
  412. package/src/codegen/freshness.ts +2 -4
  413. package/src/codegen/run-codegen.ts +37 -23
  414. package/src/codegen/store-resolver.ts +1 -1
  415. package/src/commands/build.ts +5 -6
  416. package/src/commands/codegen.ts +14 -1
  417. package/src/commands/deploy.ts +47 -0
  418. package/src/commands/dev.ts +7 -5
  419. package/src/commands/docs.ts +39 -4
  420. package/src/deploy/depends.ts +42 -0
  421. package/src/deploy/download.ts +148 -0
  422. package/src/deploy/freedesktop/copyright.ts +41 -0
  423. package/src/deploy/freedesktop/dbus-service.ts +19 -0
  424. package/src/deploy/freedesktop/desktop-entry.ts +102 -0
  425. package/src/deploy/freedesktop/ini.ts +39 -0
  426. package/src/deploy/freedesktop/metainfo-sections.ts +116 -0
  427. package/src/deploy/freedesktop/metainfo.ts +46 -0
  428. package/src/deploy/freedesktop/mime-package.ts +28 -0
  429. package/src/deploy/freedesktop/validate.ts +124 -0
  430. package/src/deploy/freedesktop/xml.ts +53 -0
  431. package/src/deploy/git.ts +20 -0
  432. package/src/deploy/install-hints.ts +108 -0
  433. package/src/deploy/nfpm/config.ts +153 -0
  434. package/src/deploy/nfpm/contents.ts +69 -0
  435. package/src/deploy/nfpm/description.ts +11 -0
  436. package/src/deploy/nfpm/optional.ts +8 -0
  437. package/src/deploy/nfpm/pack.ts +44 -0
  438. package/src/deploy/node-runtime/download.ts +48 -0
  439. package/src/deploy/node-runtime/elf.ts +145 -0
  440. package/src/deploy/node-runtime/guard.ts +29 -0
  441. package/src/deploy/node-runtime/index.ts +80 -0
  442. package/src/deploy/payload/copy-tree.ts +51 -0
  443. package/src/deploy/payload/icons.ts +80 -0
  444. package/src/deploy/payload/launcher.ts +27 -0
  445. package/src/deploy/payload/schemas.ts +27 -0
  446. package/src/deploy/payload/stage.ts +145 -0
  447. package/src/deploy/registry.ts +40 -0
  448. package/src/deploy/run-deploy.ts +235 -0
  449. package/src/deploy/settings/arch.ts +18 -0
  450. package/src/deploy/settings/categories.ts +39 -0
  451. package/src/deploy/settings/exec.ts +29 -0
  452. package/src/deploy/settings/identity.ts +133 -0
  453. package/src/deploy/settings/index.ts +189 -0
  454. package/src/deploy/settings/package-manifest.ts +66 -0
  455. package/src/deploy/settings/paths.ts +115 -0
  456. package/src/deploy/settings/screenshots.ts +125 -0
  457. package/src/deploy/settings/starter.ts +41 -0
  458. package/src/deploy/settings/version.ts +59 -0
  459. package/src/deploy/targets/appimage.ts +140 -0
  460. package/src/deploy/targets/deb.ts +6 -0
  461. package/src/deploy/targets/flatpak-manifest.ts +61 -0
  462. package/src/deploy/targets/flatpak-prebuilt.ts +59 -0
  463. package/src/deploy/targets/flatpak-source.ts +168 -0
  464. package/src/deploy/targets/flatpak-sources.ts +171 -0
  465. package/src/deploy/targets/flatpak.ts +143 -0
  466. package/src/deploy/targets/nfpm-target.ts +33 -0
  467. package/src/deploy/targets/rpm.ts +6 -0
  468. package/src/deploy/tools.ts +135 -0
  469. package/src/deploy/types.ts +174 -0
  470. package/src/deploy/vendored/appimagetool.ts +57 -0
  471. package/src/deploy/vendored/nfpm.ts +79 -0
  472. package/src/dev/change-queue.ts +59 -0
  473. package/src/dev/entry-env.ts +3 -0
  474. package/src/dev/failure-tracker.ts +92 -0
  475. package/src/dev/missing-import.ts +32 -0
  476. package/src/dev/runner-deps.ts +34 -5
  477. package/src/dev/runner-main.ts +3 -4
  478. package/src/dev/runner.ts +524 -89
  479. package/src/dev/supervisor.ts +51 -11
  480. package/src/dev/vite-dev-server.ts +54 -3
  481. package/src/internal/application-args.ts +13 -0
  482. package/src/internal/entry-arg.ts +25 -11
  483. package/src/internal/errors.ts +1 -1
  484. package/src/internal/module-loads.ts +32 -0
  485. package/src/internal/prepare-project.ts +23 -0
  486. package/src/internal/run-cli-tool.ts +38 -0
  487. package/src/internal/staging-dir.ts +57 -2
  488. package/src/mcp/client.ts +1 -1
  489. package/src/mcp/handlers.ts +123 -56
  490. package/src/mcp/index.ts +1 -0
  491. package/src/mcp/serialize-widget.ts +73 -22
  492. package/src/mcp/testing-loader.ts +19 -4
  493. package/src/mcp/widget-properties.ts +153 -0
  494. package/src/refresh-runtime.ts +48 -2
  495. package/src/settings/compile.ts +8 -11
  496. package/src/settings/schema.ts +0 -1
  497. package/src/vite-plugins/asset-emitter.ts +5 -0
  498. package/src/vite-plugins/asset-extensions.ts +2 -1
  499. package/src/vite-plugins/asset-imports.ts +134 -0
  500. package/src/vite-plugins/asset-specifier.ts +9 -0
  501. package/src/vite-plugins/built-url.ts +19 -13
  502. package/src/vite-plugins/ensure-store.ts +14 -0
  503. package/src/vite-plugins/esm-extension.ts +4 -0
  504. package/src/vite-plugins/fast-refresh/swc-refresh.ts +1 -1
  505. package/src/vite-plugins/icons.ts +2 -5
  506. package/src/vite-plugins/index.ts +4 -0
  507. package/src/vite-plugins/react-compiler.ts +2 -1
  508. package/src/vite-plugins/resource-shared.ts +2 -0
  509. package/src/vite-plugins/resources.ts +43 -52
  510. package/src/vite-plugins/self-contained.ts +352 -0
  511. package/src/vite-plugins/settings.ts +23 -50
  512. package/src/vite-plugins/store-links.ts +25 -0
  513. package/src/vite-plugins/undeclared-library.ts +75 -13
  514. package/src/vite-plugins/worker.ts +238 -0
  515. package/src/vitest-plugin.ts +15 -1
  516. package/dist/internal/resolve-cli-tool.d.ts +0 -3
  517. package/dist/internal/resolve-cli-tool.d.ts.map +0 -1
  518. package/dist/internal/resolve-cli-tool.js +0 -27
  519. package/dist/internal/resolve-cli-tool.js.map +0 -1
  520. package/src/internal/resolve-cli-tool.ts +0 -37
@@ -8,11 +8,10 @@ import {
8
8
  ServerRequestParamsSchemas,
9
9
  widgetNotFoundError,
10
10
  } from "@gtkx/mcp/internal";
11
- import { mkdirSync, writeFileSync } from "node:fs";
12
- import { dirname } from "node:path";
13
11
  import type { WidgetRegistry } from "./widget-registry.js";
14
12
  import { serializeWidget } from "./serialize-widget.js";
15
13
  import { loadTestingModule, type TestingModule } from "./testing-loader.js";
14
+ import { readWidgetProperties } from "./widget-properties.js";
16
15
 
17
16
  type HandlerContext = {
18
17
  app: Gtk.Application;
@@ -21,6 +20,11 @@ type HandlerContext = {
21
20
 
22
21
  type ValidatedHandler = (ctx: HandlerContext, params: unknown) => Promise<unknown>;
23
22
  type WidgetTarget = { testing: TestingModule; widget: Gtk.Widget };
23
+ type WidgetParams = { widgetId?: string | undefined };
24
+ type TargetedHandler<Params> = (ctx: HandlerContext, target: WidgetTarget, params: Params) => Promise<unknown>;
25
+ type QueryParams = ServerRequestParams<"widget.query">;
26
+ type QueryBy = QueryParams["by"];
27
+ type QueryRunner = (testing: TestingModule, app: Gtk.Application, params: QueryParams) => Promise<Gtk.Widget[]>;
24
28
 
25
29
  const HANDLERS: Record<ServerInitiatedMethod, ValidatedHandler> = {
26
30
  "app.getWindows": validated(ServerRequestParamsSchemas["app.getWindows"], ({ registry }) =>
@@ -43,20 +47,22 @@ const HANDLERS: Record<ServerInitiatedMethod, ValidatedHandler> = {
43
47
  };
44
48
  }),
45
49
  "widget.query": validated(ServerRequestParamsSchemas["widget.query"], handleQuery),
46
- "widget.getProps": validated(ServerRequestParamsSchemas["widget.getProps"], async ({ registry }, params) => {
47
- const { testing, widget } = await widgetTarget(registry, params.widgetId);
48
-
49
- return serializeWidget(widget, (target) => registry.getOrCreateId(target), testing);
50
- }),
51
- "widget.click": validated(ServerRequestParamsSchemas["widget.click"], async ({ registry }, params) => {
52
- const { testing, widget } = await widgetTarget(registry, params.widgetId);
50
+ "widget.getProps": targeted(
51
+ ServerRequestParamsSchemas["widget.getProps"],
52
+ ({ registry }, { testing, widget }, params) =>
53
+ Promise.resolve({
54
+ ...(params.properties !== undefined && {
55
+ properties: readWidgetProperties(widget, params.properties, registry),
56
+ }),
57
+ ...serializeWidget(widget, (target) => registry.getOrCreateId(target), testing, params.maxDepth),
58
+ }),
59
+ ),
60
+ "widget.click": targeted(ServerRequestParamsSchemas["widget.click"], async (_ctx, { testing, widget }) => {
53
61
  await testing.userEvent.click(widget);
54
62
 
55
63
  return { success: true };
56
64
  }),
57
- "widget.type": validated(ServerRequestParamsSchemas["widget.type"], async ({ registry }, params) => {
58
- const { testing, widget } = await widgetTarget(registry, params.widgetId);
59
-
65
+ "widget.type": targeted(ServerRequestParamsSchemas["widget.type"], async (_ctx, { testing, widget }, params) => {
60
66
  if (params.clear) {
61
67
  await testing.userEvent.clear(widget);
62
68
  }
@@ -65,16 +71,43 @@ const HANDLERS: Record<ServerInitiatedMethod, ValidatedHandler> = {
65
71
 
66
72
  return { success: true };
67
73
  }),
68
- "widget.fireEvent": validated(ServerRequestParamsSchemas["widget.fireEvent"], async ({ registry }, params) => {
69
- const { testing, widget } = await widgetTarget(registry, params.widgetId);
70
- const signalArgs = (params.args ?? []).map((arg) => extractSignalArg(arg));
71
- await testing.fireEvent(widget, params.signal, ...signalArgs);
72
-
73
- return { success: true };
74
- }),
74
+ "widget.fireEvent": targeted(
75
+ ServerRequestParamsSchemas["widget.fireEvent"],
76
+ async (_ctx, { testing, widget }, params) => {
77
+ const signalArgs = (params.args ?? []).map((arg) => extractSignalArg(arg));
78
+ const isRealized = widget.getRealized();
79
+ const isMapped = widget.getMapped();
80
+ const isSensitive = widget.getSensitive();
81
+ await testing.fireEvent(widget, params.signal, ...signalArgs);
82
+
83
+ return {
84
+ signal: params.signal,
85
+ isRealized,
86
+ isMapped,
87
+ isSensitive,
88
+ note: emissionNote(isRealized, isMapped),
89
+ };
90
+ },
91
+ ),
75
92
  "widget.screenshot": validated(ServerRequestParamsSchemas["widget.screenshot"], handleScreenshot),
76
93
  };
77
94
 
95
+ const QUERY_RUNNERS: Record<QueryBy, QueryRunner> = {
96
+ role: runRoleQuery,
97
+ text: runTextQuery,
98
+ name: runNameQuery,
99
+ labelText: runLabelTextQuery,
100
+ };
101
+
102
+ const SEARCHED_BY: Record<QueryBy, string> = {
103
+ role: "the accessible role, narrowed by any options given",
104
+ text: "the text the widget renders",
105
+ name:
106
+ "the widget name (gtk_widget_get_name, which reports the GType name such as \"GtkButton\" when no name " +
107
+ "was set), the accessible label, and the text the widget renders",
108
+ labelText: "the accessible label, the labelled-by relation, and the label whose mnemonic targets the widget",
109
+ };
110
+
78
111
  function validated<Params>(
79
112
  schema: ParamsSchema<Params>,
80
113
  handler: (ctx: HandlerContext, params: Params) => Promise<unknown>,
@@ -90,6 +123,14 @@ function validated<Params>(
90
123
  };
91
124
  }
92
125
 
126
+ function targeted<Params extends WidgetParams>(
127
+ schema: ParamsSchema<Params>,
128
+ handler: TargetedHandler<Params>,
129
+ ): ValidatedHandler {
130
+ return validated(schema, async (ctx, params) =>
131
+ handler(ctx, await widgetTarget(ctx.registry, params.widgetId), params));
132
+ }
133
+
93
134
  const widgetTarget = async (registry: WidgetRegistry, widgetId: string | undefined): Promise<WidgetTarget> => ({
94
135
  testing: await loadTestingModule(),
95
136
  widget: requireWidget(registry, widgetId),
@@ -115,6 +156,21 @@ const extractSignalArg = (arg: unknown): unknown => {
115
156
  return isTypedArg ? (arg as { value: unknown }).value : arg;
116
157
  };
117
158
 
159
+ const emissionNote = (isRealized: boolean, isMapped: boolean): string => {
160
+ if (isRealized && isMapped) {
161
+ return (
162
+ "The signal was emitted. Default handlers that animate, such as a button activate, settle " +
163
+ "asynchronously, so read the widget again rather than assuming the effect has landed."
164
+ );
165
+ }
166
+
167
+ return (
168
+ "The signal was emitted on a widget that is not realized and mapped, so a default handler that " +
169
+ "requires a drawn widget does nothing. Present the containing window or open the containing " +
170
+ "popover first, then fire the signal again."
171
+ );
172
+ };
173
+
118
174
  const resolveRole = (value: string | number): Gtk.AccessibleRole | undefined => {
119
175
  if (typeof value === "number") {
120
176
  return value;
@@ -133,42 +189,56 @@ const matchesOrEmpty = async (find: () => Promise<Gtk.Widget[]>): Promise<Gtk.Wi
133
189
  }
134
190
  };
135
191
 
136
- async function handleQuery(
137
- { app, registry }: HandlerContext,
138
- params: ServerRequestParams<"widget.query">,
139
- ): Promise<unknown> {
140
- const testing = await loadTestingModule();
141
- let widgets: Gtk.Widget[] = [];
192
+ function runRoleQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {
193
+ const roleValue = resolveRole(params.value);
142
194
 
143
- switch (params.by) {
144
- case "role": {
145
- const roleValue = resolveRole(params.value);
195
+ if (roleValue === undefined) {
196
+ throw invalidRequestError(
197
+ `Unknown accessible role "${String(params.value)}"; use the lowercase role shown in the ` +
198
+ "widget tree, e.g. \"button\", \"list\", \"list_item\", or \"checkbox\".",
199
+ );
200
+ }
146
201
 
147
- if (roleValue === undefined) {
148
- throw invalidRequestError(
149
- `Unknown accessible role "${String(params.value)}"; use the lowercase role shown in the ` +
150
- "widget tree, e.g. \"button\", \"list\", \"list_item\", or \"checkbox\".",
151
- );
152
- }
202
+ return matchesOrEmpty(() => testing.findAllByRole(app, roleValue, params.options));
203
+ }
153
204
 
154
- widgets = await matchesOrEmpty(() => testing.findAllByRole(app, roleValue, params.options));
155
- break;
156
- }
157
- case "text": {
158
- widgets = await matchesOrEmpty(() => testing.findAllByText(app, String(params.value), params.options));
159
- break;
160
- }
161
- case "name": {
162
- widgets = await matchesOrEmpty(() => testing.findAllByName(app, String(params.value), params.options));
163
- break;
164
- }
165
- case "labelText": {
166
- widgets = await matchesOrEmpty(() => testing.findAllByLabelText(app, String(params.value), params.options));
167
- break;
168
- }
169
- }
205
+ function runTextQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {
206
+ return matchesOrEmpty(() => testing.findAllByText(app, String(params.value), params.options));
207
+ }
170
208
 
171
- return { widgets: widgets.map((w) => serializeWidget(w, (widget) => registry.getOrCreateId(widget), testing, 0)) };
209
+ function runLabelTextQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {
210
+ return matchesOrEmpty(() => testing.findAllByLabelText(app, String(params.value), params.options));
211
+ }
212
+
213
+ async function runNameQuery(
214
+ testing: TestingModule,
215
+ app: Gtk.Application,
216
+ params: QueryParams,
217
+ ): Promise<Gtk.Widget[]> {
218
+ const matches = await Promise.all([
219
+ matchesOrEmpty(() => testing.findAllByName(app, String(params.value), params.options)),
220
+ runLabelTextQuery(testing, app, params),
221
+ runTextQuery(testing, app, params),
222
+ ]);
223
+
224
+ return [...new Set(matches.flat())];
225
+ }
226
+
227
+ const emptyQueryHint = (params: QueryParams): string =>
228
+ `Nothing matched by:"${params.by}" value:"${String(params.value)}", which compared ${SEARCHED_BY[params.by]}. ` +
229
+ "Call gtkx_get_widget_tree to see what is mounted; by:\"name\" is the widest match, and by:\"role\" accepts " +
230
+ "options.name to match the accessible name of a known role.";
231
+
232
+ async function handleQuery({ app, registry }: HandlerContext, params: QueryParams): Promise<unknown> {
233
+ const testing = await loadTestingModule();
234
+ const widgets = await QUERY_RUNNERS[params.by](testing, app, params);
235
+ const resolveId = (widget: Gtk.Widget): string => registry.getOrCreateId(widget);
236
+
237
+ return {
238
+ widgets: widgets.map((widget) => serializeWidget(widget, resolveId, testing, 0)),
239
+ searched: SEARCHED_BY[params.by],
240
+ ...(widgets.length === 0 && { hint: emptyQueryHint(params) }),
241
+ };
172
242
  }
173
243
 
174
244
  const defaultScreenshotTarget = (registry: WidgetRegistry): Gtk.Widget => {
@@ -187,12 +257,9 @@ async function handleScreenshot(
187
257
  ): Promise<unknown> {
188
258
  const testing = await loadTestingModule();
189
259
  const target = params.windowId ? requireWidget(registry, params.windowId) : defaultScreenshotTarget(registry);
190
- const result = await testing.screenshot(target);
260
+ const result = await testing.screenshot(target, { path: params.path });
191
261
 
192
262
  if (params.path) {
193
- mkdirSync(dirname(params.path), { recursive: true });
194
- writeFileSync(params.path, Buffer.from(result.data, "base64"));
195
-
196
263
  return { data: result.data, mimeType: result.mimeType, savedPath: params.path };
197
264
  }
198
265
 
@@ -210,4 +277,4 @@ const dispatch = async (method: string, params: unknown, ctx: HandlerContext): P
210
277
  return HANDLERS[method](ctx, params);
211
278
  };
212
279
 
213
- export { dispatch, type HandlerContext };
280
+ export { dispatch };
package/src/mcp/index.ts CHANGED
@@ -7,6 +7,7 @@ type McpClientController = {
7
7
 
8
8
  const { start: startMcpClient, stop: stopMcpClient } = createMcpClientController();
9
9
 
10
+ /* eslint-disable-next-line unicorn/consistent-boolean-name -- the boolean reports whether connecting succeeded */
10
11
  async function connectQuietly(client: McpClient): Promise<boolean> {
11
12
  try {
12
13
  await client.connect();
@@ -1,41 +1,92 @@
1
1
  import type * as Gtk from "@gtkx/gi/gtk";
2
- import type { SerializedWidget } from "@gtkx/mcp/internal";
2
+ import { DEFAULT_SUBTREE_DEPTH, MAX_SUBTREE_WIDGETS, type SerializedWidget } from "@gtkx/mcp/internal";
3
3
 
4
4
  type WidgetIdResolver = (widget: Gtk.Widget) => string;
5
5
 
6
6
  type WidgetFormatting = {
7
7
  formatRole(role: Gtk.AccessibleRole): string;
8
- getWidgetNodeText(widget: Gtk.Widget): string | null;
8
+ getTypeTag(widget: Gtk.Widget): string;
9
+ getWidgetText(widget: Gtk.Widget): string | null;
10
+ };
11
+
12
+ type PendingWidget = {
13
+ depth: number;
14
+ node: SerializedWidget;
15
+ widget: Gtk.Widget;
16
+ };
17
+
18
+ type Expansion = {
19
+ budget: number;
20
+ maxDepth: number;
21
+ pending: PendingWidget[];
22
+ resolveId: WidgetIdResolver;
23
+ testing: WidgetFormatting;
24
+ };
25
+
26
+ const getChildren = (widget: Gtk.Widget): Gtk.Widget[] => {
27
+ const children: Gtk.Widget[] = [];
28
+ let child = widget.getFirstChild();
29
+
30
+ while (child) {
31
+ children.push(child);
32
+ child = child.getNextSibling();
33
+ }
34
+
35
+ return children;
36
+ };
37
+
38
+ const createNode = (widget: Gtk.Widget, expansion: Expansion): SerializedWidget => ({
39
+ id: expansion.resolveId(widget),
40
+ type: expansion.testing.getTypeTag(widget),
41
+ role: expansion.testing.formatRole(widget.getAccessibleRole()),
42
+ name: widget.getName() || null,
43
+ text: expansion.testing.getWidgetText(widget),
44
+ isSensitive: widget.getSensitive(),
45
+ isVisible: widget.getVisible(),
46
+ cssClasses: widget.getCssClasses(),
47
+ children: [],
48
+ });
49
+
50
+ const expandNode = (expansion: Expansion, parent: PendingWidget): void => {
51
+ const children = getChildren(parent.widget);
52
+ const canDescend = parent.depth < expansion.maxDepth;
53
+ const shownCount = canDescend ? Math.min(children.length, expansion.budget) : 0;
54
+ expansion.budget -= shownCount;
55
+
56
+ for (const child of children.slice(0, shownCount)) {
57
+ const node = createNode(child, expansion);
58
+ parent.node.children.push(node);
59
+ expansion.pending.push({ depth: parent.depth + 1, node, widget: child });
60
+ }
61
+
62
+ if (shownCount < children.length) {
63
+ parent.node.hiddenChildren = children.length - shownCount;
64
+ }
9
65
  };
10
66
 
11
67
  const serializeWidget = (
12
68
  widget: Gtk.Widget,
13
69
  resolveId: WidgetIdResolver,
14
70
  testing: WidgetFormatting,
15
- maxDepth = Infinity,
71
+ maxDepth = DEFAULT_SUBTREE_DEPTH,
16
72
  ): SerializedWidget => {
17
- const children: SerializedWidget[] = [];
73
+ const expansion: Expansion = {
74
+ budget: MAX_SUBTREE_WIDGETS - 1,
75
+ maxDepth,
76
+ pending: [],
77
+ resolveId,
78
+ testing,
79
+ };
18
80
 
19
- if (maxDepth > 0) {
20
- let child = widget.getFirstChild();
81
+ const root = createNode(widget, expansion);
82
+ let parent: PendingWidget | undefined = { depth: 0, node: root, widget };
21
83
 
22
- while (child) {
23
- children.push(serializeWidget(child, resolveId, testing, maxDepth - 1));
24
- child = child.getNextSibling();
25
- }
84
+ while (parent !== undefined) {
85
+ expandNode(expansion, parent);
86
+ parent = expansion.pending.shift();
26
87
  }
27
88
 
28
- return {
29
- id: resolveId(widget),
30
- type: widget.constructor.name,
31
- role: testing.formatRole(widget.getAccessibleRole()),
32
- name: widget.getName() || null,
33
- text: testing.getWidgetNodeText(widget),
34
- isSensitive: widget.getSensitive(),
35
- isVisible: widget.getVisible(),
36
- cssClasses: widget.getCssClasses(),
37
- children,
38
- };
89
+ return root;
39
90
  };
40
91
 
41
- export { serializeWidget, type WidgetFormatting };
92
+ export { serializeWidget };
@@ -1,4 +1,6 @@
1
- type TestingModule = typeof import("@gtkx/testing");
1
+ type TestingPublicModule = typeof import("@gtkx/testing");
2
+ type TestingInternalModule = typeof import("@gtkx/testing/internal");
3
+ type TestingModule = TestingPublicModule & Pick<TestingInternalModule, "getTypeTag">;
2
4
  type TestingModuleLoader = () => Promise<TestingModule>;
3
5
 
4
6
  type TestingModuleCache = {
@@ -14,8 +16,14 @@ type TestingModuleState = {
14
16
 
15
17
  const { setLoader: setTestingModuleLoader, load: loadTestingModule } = createTestingModuleCache();
16
18
 
17
- function defaultLoader(): Promise<TestingModule> {
18
- return import("@gtkx/testing");
19
+ function mergeTestingModule(publicApi: TestingPublicModule, internals: TestingInternalModule): TestingModule {
20
+ return { ...publicApi, getTypeTag: internals.getTypeTag };
21
+ }
22
+
23
+ async function defaultLoader(): Promise<TestingModule> {
24
+ const [publicApi, internals] = await Promise.all([import("@gtkx/testing"), import("@gtkx/testing/internal")]);
25
+
26
+ return mergeTestingModule(publicApi, internals);
19
27
  }
20
28
 
21
29
  function missingTestingPackageError(cause: unknown): Error {
@@ -70,4 +78,11 @@ function createTestingModuleCache(): TestingModuleCache {
70
78
  };
71
79
  }
72
80
 
73
- export { setTestingModuleLoader, loadTestingModule, type TestingModule, type TestingModuleLoader };
81
+ export {
82
+ setTestingModuleLoader,
83
+ loadTestingModule,
84
+ mergeTestingModule,
85
+ type TestingInternalModule,
86
+ type TestingModule,
87
+ type TestingPublicModule,
88
+ };
@@ -0,0 +1,153 @@
1
+ import * as GObject from "@gtkx/gi/gobject";
2
+ import * as Gtk from "@gtkx/gi/gtk";
3
+ import { propertyNotFoundError, type SerializedProperty } from "@gtkx/mcp/internal";
4
+ import {
5
+ type ExternalObject,
6
+ getHandle,
7
+ getInstanceType,
8
+ type Handle,
9
+ TYPE_ENUM,
10
+ TYPE_FLAGS,
11
+ typeIsA,
12
+ typeName,
13
+ } from "@gtkx/runtime";
14
+ import { fromValue, getValueType } from "@gtkx/runtime/internal";
15
+ import { camelCase, errorMessage, kebabCase } from "@gtkx/utils";
16
+ import type { WidgetRegistry } from "./widget-registry.js";
17
+
18
+ type PropertyRepresentation = Omit<SerializedProperty, "type">;
19
+ type NativeProperty = { type: bigint; handle: ExternalObject<Handle> };
20
+
21
+ const SCALAR_TYPES: Set<string> = new Set(["string", "number", "boolean"]);
22
+
23
+ const canonicalName = (name: string): string => kebabCase(name).replaceAll("_", "-");
24
+ const widgetTypeName = (widget: Gtk.Widget): string => typeName(getInstanceType(widget)) ?? widget.constructor.name;
25
+ const byName = (left: string, right: string): number => left.localeCompare(right);
26
+
27
+ const isScalar = (value: unknown): value is string | number | boolean | null =>
28
+ value === null || SCALAR_TYPES.has(typeof value);
29
+
30
+ function prototypesFor(widget: Gtk.Widget): object[] {
31
+ const prototypes: object[] = [];
32
+ let prototype = Object.getPrototypeOf(widget) as object | null;
33
+
34
+ while (prototype !== null && prototype !== Object.prototype) {
35
+ prototypes.push(prototype);
36
+ prototype = Object.getPrototypeOf(prototype) as object | null;
37
+ }
38
+
39
+ return prototypes;
40
+ }
41
+
42
+ function getAccessor(widget: Gtk.Widget, member: string): PropertyDescriptor | undefined {
43
+ for (const prototype of prototypesFor(widget)) {
44
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, member);
45
+
46
+ if (descriptor !== undefined) {
47
+ return descriptor;
48
+ }
49
+ }
50
+
51
+ return undefined;
52
+ }
53
+
54
+ function getReadableNames(prototype: object): string[] {
55
+ const descriptors = Object.entries(Object.getOwnPropertyDescriptors(prototype));
56
+
57
+ return descriptors.filter(([, descriptor]) => descriptor.get !== undefined).map(([member]) => kebabCase(member));
58
+ }
59
+
60
+ function readablePropertyNames(widget: Gtk.Widget): string[] {
61
+ const names = prototypesFor(widget).flatMap((prototype) => getReadableNames(prototype));
62
+
63
+ return [...new Set(names)].toSorted(byName);
64
+ }
65
+
66
+ const requireReadableProperty = (widget: Gtk.Widget, property: string): void => {
67
+ if (getAccessor(widget, camelCase(property))?.get !== undefined) {
68
+ return;
69
+ }
70
+
71
+ throw propertyNotFoundError(widgetTypeName(widget), property, readablePropertyNames(widget));
72
+ };
73
+
74
+ function readNativeProperty(widget: Gtk.Widget, property: string): NativeProperty {
75
+ const value = new GObject.Value();
76
+ widget.getProperty(property, value);
77
+ const handle = getHandle(value);
78
+
79
+ return { type: getValueType(handle), handle };
80
+ }
81
+
82
+ function describeObjectValue(value: unknown, registry: WidgetRegistry): PropertyRepresentation {
83
+ if (typeof value !== "object" || value === null) {
84
+ return { value: String(value) };
85
+ }
86
+
87
+ const name = typeName(getInstanceType(value)) ?? value.constructor.name;
88
+
89
+ if (!(value instanceof Gtk.Widget)) {
90
+ return { value: name };
91
+ }
92
+
93
+ registry.register(value);
94
+
95
+ return { value: name, widgetId: registry.getOrCreateId(value) };
96
+ }
97
+
98
+ function representValue(value: unknown, registry: WidgetRegistry): PropertyRepresentation {
99
+ if (isScalar(value)) {
100
+ return { value };
101
+ }
102
+
103
+ if (typeof value === "bigint") {
104
+ return { value: value.toString() };
105
+ }
106
+
107
+ if (Array.isArray(value)) {
108
+ return { value: value.map(String) };
109
+ }
110
+
111
+ return describeObjectValue(value, registry);
112
+ }
113
+
114
+ function representNativeProperty(native: NativeProperty, registry: WidgetRegistry): PropertyRepresentation {
115
+ if (typeIsA(native.type, TYPE_ENUM)) {
116
+ return { value: GObject.enumToString(native.type, Number(fromValue(native.handle))) };
117
+ }
118
+
119
+ if (typeIsA(native.type, TYPE_FLAGS)) {
120
+ return { value: GObject.flagsToString(native.type, Number(fromValue(native.handle))) };
121
+ }
122
+
123
+ return representValue(fromValue(native.handle), registry);
124
+ }
125
+
126
+ function serializeProperty(widget: Gtk.Widget, property: string, registry: WidgetRegistry): SerializedProperty {
127
+ const native = readNativeProperty(widget, property);
128
+ const type = typeName(native.type) ?? String(native.type);
129
+
130
+ try {
131
+ return { type, ...representNativeProperty(native, registry) };
132
+ } catch (error) {
133
+ return { type, value: null, note: `cannot be represented over MCP: ${errorMessage(error)}` };
134
+ }
135
+ }
136
+
137
+ function readWidgetProperties(
138
+ widget: Gtk.Widget,
139
+ properties: string[],
140
+ registry: WidgetRegistry,
141
+ ): Record<string, SerializedProperty> {
142
+ const values: Record<string, SerializedProperty> = {};
143
+
144
+ for (const name of properties) {
145
+ const property = canonicalName(name);
146
+ requireReadableProperty(widget, property);
147
+ values[property] = serializeProperty(widget, property, registry);
148
+ }
149
+
150
+ return values;
151
+ }
152
+
153
+ export { readWidgetProperties };
@@ -1,8 +1,13 @@
1
- import RefreshRuntime from "react-refresh/runtime";
1
+ import RefreshRuntime, { type Family } from "react-refresh/runtime";
2
2
  import "./refresh-globals.js";
3
3
 
4
4
  type ComponentType = (...args: unknown[]) => unknown;
5
5
 
6
+ type PatchedExports = {
7
+ values: Set<unknown>;
8
+ families: Set<Family>;
9
+ };
10
+
6
11
  function createModuleRegistration(moduleId: string): {
7
12
  $RefreshReg$: (type: ComponentType, id: string) => void;
8
13
  $RefreshSig$: typeof RefreshRuntime.createSignatureFunctionForTransform;
@@ -40,8 +45,49 @@ function isRefreshBoundary(moduleExports: Record<string, unknown>): boolean {
40
45
  return Object.keys(moduleExports).some((k) => k !== "__esModule");
41
46
  }
42
47
 
48
+ const exportedFamilies = (moduleExports: Record<string, unknown>): Set<Family> => {
49
+ const families: Set<Family> = new Set();
50
+
51
+ for (const key in moduleExports) {
52
+ const family = RefreshRuntime.getFamilyByType(moduleExports[key]);
53
+
54
+ if (family) {
55
+ families.add(family);
56
+ }
57
+ }
58
+
59
+ return families;
60
+ };
61
+
62
+ const patchedExports = (moduleExports: Record<string, unknown>): PatchedExports => ({
63
+ values: new Set(Object.values(moduleExports)),
64
+ families: exportedFamilies(moduleExports),
65
+ });
66
+
67
+ const isPatchedExport = (patched: PatchedExports, value: unknown): boolean => {
68
+ if (patched.values.has(value)) {
69
+ return true;
70
+ }
71
+
72
+ const family = RefreshRuntime.getFamilyByType(value);
73
+
74
+ return family !== undefined && patched.families.has(family);
75
+ };
76
+
77
+ const staleExportName = (previous: Record<string, unknown>, current: Record<string, unknown>): string | null => {
78
+ const patched = patchedExports(current);
79
+
80
+ for (const key in previous) {
81
+ if (!isPatchedExport(patched, previous[key])) {
82
+ return key;
83
+ }
84
+ }
85
+
86
+ return null;
87
+ };
88
+
43
89
  function performRefresh(): void {
44
90
  RefreshRuntime.performReactRefresh();
45
91
  }
46
92
 
47
- export { createModuleRegistration, isRefreshBoundary, performRefresh };
93
+ export { createModuleRegistration, isRefreshBoundary, performRefresh, staleExportName };
@@ -1,22 +1,19 @@
1
- import { formatChildProcessError } from "@gtkx/utils";
2
- import { execFileSync } from "node:child_process";
3
- import { resolveCliTool } from "../internal/resolve-cli-tool.js";
1
+ import { runCliTool } from "../internal/run-cli-tool.js";
4
2
 
5
3
  const SCHEMA_COMPILER = "glib-compile-schemas";
6
4
  const SCHEMA_COMPILE_TIMEOUT_MS = 30_000;
7
5
 
8
6
  const compileSchemas = (dir: string): void => {
9
- try {
10
- execFileSync(resolveCliTool(SCHEMA_COMPILER), ["--strict", dir], {
7
+ runCliTool({
8
+ tool: SCHEMA_COMPILER,
9
+ args: ["--strict", dir],
10
+ target: dir,
11
+ options: {
11
12
  stdio: ["ignore", "pipe", "pipe"],
12
13
  timeout: SCHEMA_COMPILE_TIMEOUT_MS,
13
14
  encoding: "utf8",
14
- });
15
- } catch (error) {
16
- const details = formatChildProcessError(error);
17
- const suffix = details ? `:\n${details}` : "";
18
- throw new Error(`glib-compile-schemas failed for ${dir}${suffix}`, { cause: error });
19
- }
15
+ },
16
+ });
20
17
  };
21
18
 
22
19
  export { compileSchemas };
@@ -164,6 +164,5 @@ export {
164
164
  stageSchema,
165
165
  findSchemaFiles,
166
166
  stageAndCompileProjectSchemas,
167
- schemaEnvPath,
168
167
  emitSchemaEnv,
169
168
  };
@@ -0,0 +1,5 @@
1
+ type AssetEmitter = {
2
+ emitFile: (file: { type: "asset"; fileName: string; source: Buffer }) => void;
3
+ };
4
+
5
+ export { type AssetEmitter };