@gtkx/cli 0.21.0 → 1.0.0-rc.1

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 (346) hide show
  1. package/README.md +173 -0
  2. package/bin/gtkx-dev-runner.js +9 -0
  3. package/dist/builder.d.ts +2 -50
  4. package/dist/builder.d.ts.map +1 -1
  5. package/dist/builder.js +22 -56
  6. package/dist/builder.js.map +1 -1
  7. package/dist/cli.d.ts +1 -2
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +11 -124
  10. package/dist/cli.js.map +1 -1
  11. package/dist/codegen/freshness.d.ts +11 -0
  12. package/dist/codegen/freshness.d.ts.map +1 -0
  13. package/dist/codegen/freshness.js +42 -0
  14. package/dist/codegen/freshness.js.map +1 -0
  15. package/dist/codegen/report.d.ts +3 -0
  16. package/dist/codegen/report.d.ts.map +1 -0
  17. package/dist/codegen/report.js +16 -0
  18. package/dist/codegen/report.js.map +1 -0
  19. package/dist/codegen/run-codegen.d.ts +35 -0
  20. package/dist/codegen/run-codegen.d.ts.map +1 -0
  21. package/dist/codegen/run-codegen.js +133 -0
  22. package/dist/codegen/run-codegen.js.map +1 -0
  23. package/dist/codegen/store-resolver.d.ts +21 -0
  24. package/dist/codegen/store-resolver.d.ts.map +1 -0
  25. package/dist/codegen/store-resolver.js +52 -0
  26. package/dist/codegen/store-resolver.js.map +1 -0
  27. package/dist/commands/build.d.ts +9 -0
  28. package/dist/commands/build.d.ts.map +1 -0
  29. package/dist/commands/build.js +33 -0
  30. package/dist/commands/build.js.map +1 -0
  31. package/dist/commands/codegen.d.ts +9 -0
  32. package/dist/commands/codegen.d.ts.map +1 -0
  33. package/dist/commands/codegen.js +40 -0
  34. package/dist/commands/codegen.js.map +1 -0
  35. package/dist/commands/dev.d.ts +5 -0
  36. package/dist/commands/dev.d.ts.map +1 -0
  37. package/dist/commands/dev.js +21 -0
  38. package/dist/commands/dev.js.map +1 -0
  39. package/dist/commands/docs.d.ts +19 -0
  40. package/dist/commands/docs.d.ts.map +1 -0
  41. package/dist/commands/docs.js +59 -0
  42. package/dist/commands/docs.js.map +1 -0
  43. package/dist/dev/icon-dir.d.ts +2 -0
  44. package/dist/dev/icon-dir.d.ts.map +1 -0
  45. package/dist/dev/icon-dir.js +13 -0
  46. package/dist/dev/icon-dir.js.map +1 -0
  47. package/dist/dev/refresh-tracker.d.ts +6 -0
  48. package/dist/dev/refresh-tracker.d.ts.map +1 -0
  49. package/dist/dev/refresh-tracker.js +18 -0
  50. package/dist/dev/refresh-tracker.js.map +1 -0
  51. package/dist/dev/runner-deps.d.ts +3 -0
  52. package/dist/dev/runner-deps.d.ts.map +1 -0
  53. package/dist/dev/runner-deps.js +39 -0
  54. package/dist/dev/runner-deps.js.map +1 -0
  55. package/dist/dev/runner-main.d.ts +2 -0
  56. package/dist/dev/runner-main.d.ts.map +1 -0
  57. package/dist/dev/runner-main.js +28 -0
  58. package/dist/dev/runner-main.js.map +1 -0
  59. package/dist/dev/runner.d.ts +23 -0
  60. package/dist/dev/runner.d.ts.map +1 -0
  61. package/dist/dev/runner.js +88 -0
  62. package/dist/dev/runner.js.map +1 -0
  63. package/dist/dev/schema-dir.d.ts +2 -0
  64. package/dist/dev/schema-dir.d.ts.map +1 -0
  65. package/dist/dev/schema-dir.js +10 -0
  66. package/dist/dev/schema-dir.js.map +1 -0
  67. package/dist/dev/supervisor.d.ts +17 -0
  68. package/dist/dev/supervisor.d.ts.map +1 -0
  69. package/dist/dev/supervisor.js +142 -0
  70. package/dist/dev/supervisor.js.map +1 -0
  71. package/dist/dev/vite-dev-server.d.ts +21 -0
  72. package/dist/dev/vite-dev-server.d.ts.map +1 -0
  73. package/dist/dev/vite-dev-server.js +12 -0
  74. package/dist/dev/vite-dev-server.js.map +1 -0
  75. package/dist/internal/banner.d.ts +3 -0
  76. package/dist/internal/banner.d.ts.map +1 -0
  77. package/dist/internal/banner.js +8 -0
  78. package/dist/internal/banner.js.map +1 -0
  79. package/dist/internal/data-dir.d.ts +3 -0
  80. package/dist/internal/data-dir.d.ts.map +1 -0
  81. package/dist/internal/data-dir.js +37 -0
  82. package/dist/internal/data-dir.js.map +1 -0
  83. package/dist/internal/entry-arg.d.ts +19 -0
  84. package/dist/internal/entry-arg.d.ts.map +1 -0
  85. package/dist/internal/entry-arg.js +33 -0
  86. package/dist/internal/entry-arg.js.map +1 -0
  87. package/dist/internal/errors.d.ts +4 -0
  88. package/dist/internal/errors.d.ts.map +1 -0
  89. package/dist/internal/errors.js +27 -0
  90. package/dist/internal/errors.js.map +1 -0
  91. package/dist/internal/list-files.d.ts +6 -0
  92. package/dist/internal/list-files.d.ts.map +1 -0
  93. package/dist/internal/list-files.js +13 -0
  94. package/dist/internal/list-files.js.map +1 -0
  95. package/dist/internal/resolve-cli-tool.d.ts +2 -0
  96. package/dist/internal/resolve-cli-tool.d.ts.map +1 -0
  97. package/dist/internal/resolve-cli-tool.js +20 -0
  98. package/dist/internal/resolve-cli-tool.js.map +1 -0
  99. package/dist/internal/staging-dir.d.ts +3 -0
  100. package/dist/internal/staging-dir.d.ts.map +1 -0
  101. package/dist/internal/staging-dir.js +16 -0
  102. package/dist/internal/staging-dir.js.map +1 -0
  103. package/dist/internal/xdg-data-dirs.d.ts +2 -0
  104. package/dist/internal/xdg-data-dirs.d.ts.map +1 -0
  105. package/dist/internal/xdg-data-dirs.js +8 -0
  106. package/dist/internal/xdg-data-dirs.js.map +1 -0
  107. package/dist/mcp/client.d.ts +23 -0
  108. package/dist/mcp/client.d.ts.map +1 -0
  109. package/dist/mcp/client.js +157 -0
  110. package/dist/mcp/client.js.map +1 -0
  111. package/dist/mcp/handlers.d.ts +8 -0
  112. package/dist/mcp/handlers.d.ts.map +1 -0
  113. package/dist/mcp/handlers.js +119 -0
  114. package/dist/mcp/handlers.js.map +1 -0
  115. package/dist/mcp/index.d.ts +4 -0
  116. package/dist/mcp/index.d.ts.map +1 -0
  117. package/dist/mcp/index.js +17 -0
  118. package/dist/mcp/index.js.map +1 -0
  119. package/dist/mcp/serialize-widget.d.ts +10 -0
  120. package/dist/mcp/serialize-widget.d.ts.map +1 -0
  121. package/dist/mcp/serialize-widget.js +20 -0
  122. package/dist/mcp/serialize-widget.js.map +1 -0
  123. package/dist/mcp/testing-loader.d.ts +6 -0
  124. package/dist/mcp/testing-loader.d.ts.map +1 -0
  125. package/dist/mcp/testing-loader.js +25 -0
  126. package/dist/mcp/testing-loader.js.map +1 -0
  127. package/dist/mcp/widget-registry.d.ts +13 -0
  128. package/dist/mcp/widget-registry.d.ts.map +1 -0
  129. package/dist/mcp/widget-registry.js +38 -0
  130. package/dist/mcp/widget-registry.js.map +1 -0
  131. package/dist/refresh-runtime.d.ts +10 -20
  132. package/dist/refresh-runtime.d.ts.map +1 -1
  133. package/dist/refresh-runtime.js +12 -36
  134. package/dist/refresh-runtime.js.map +1 -1
  135. package/dist/settings/compile.d.ts +2 -0
  136. package/dist/settings/compile.d.ts.map +1 -0
  137. package/dist/settings/compile.js +19 -0
  138. package/dist/settings/compile.js.map +1 -0
  139. package/dist/settings/parser.d.ts +23 -0
  140. package/dist/settings/parser.d.ts.map +1 -0
  141. package/dist/settings/parser.js +117 -0
  142. package/dist/settings/parser.js.map +1 -0
  143. package/dist/settings/render.d.ts +4 -0
  144. package/dist/settings/render.d.ts.map +1 -0
  145. package/dist/settings/render.js +148 -0
  146. package/dist/settings/render.js.map +1 -0
  147. package/dist/settings/schema.d.ts +13 -0
  148. package/dist/settings/schema.d.ts.map +1 -0
  149. package/dist/settings/schema.js +103 -0
  150. package/dist/settings/schema.js.map +1 -0
  151. package/dist/vite-plugins/asset-extensions.d.ts +4 -0
  152. package/dist/vite-plugins/asset-extensions.d.ts.map +1 -0
  153. package/dist/vite-plugins/asset-extensions.js +27 -0
  154. package/dist/vite-plugins/asset-extensions.js.map +1 -0
  155. package/dist/vite-plugins/built-url.d.ts +3 -0
  156. package/dist/vite-plugins/built-url.d.ts.map +1 -0
  157. package/dist/{vite-plugin-gtkx-built-url.js → vite-plugins/built-url.js} +4 -17
  158. package/dist/vite-plugins/built-url.js.map +1 -0
  159. package/dist/vite-plugins/css.d.ts +3 -0
  160. package/dist/vite-plugins/css.d.ts.map +1 -0
  161. package/dist/vite-plugins/css.js +30 -0
  162. package/dist/vite-plugins/css.js.map +1 -0
  163. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts +7 -0
  164. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts.map +1 -0
  165. package/dist/vite-plugins/fast-refresh/refresh-filter.js +15 -0
  166. package/dist/vite-plugins/fast-refresh/refresh-filter.js.map +1 -0
  167. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts +5 -0
  168. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -0
  169. package/dist/vite-plugins/fast-refresh/swc-refresh.js +66 -0
  170. package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -0
  171. package/dist/vite-plugins/icons.d.ts +3 -0
  172. package/dist/vite-plugins/icons.d.ts.map +1 -0
  173. package/dist/vite-plugins/icons.js +47 -0
  174. package/dist/vite-plugins/icons.js.map +1 -0
  175. package/dist/vite-plugins/index.d.ts +3 -0
  176. package/dist/vite-plugins/index.d.ts.map +1 -0
  177. package/dist/vite-plugins/index.js +21 -0
  178. package/dist/vite-plugins/index.js.map +1 -0
  179. package/dist/vite-plugins/native.d.ts +3 -0
  180. package/dist/vite-plugins/native.d.ts.map +1 -0
  181. package/dist/vite-plugins/native.js +60 -0
  182. package/dist/vite-plugins/native.js.map +1 -0
  183. package/dist/vite-plugins/react-compiler.d.ts +4 -0
  184. package/dist/vite-plugins/react-compiler.d.ts.map +1 -0
  185. package/dist/vite-plugins/react-compiler.js +56 -0
  186. package/dist/vite-plugins/react-compiler.js.map +1 -0
  187. package/dist/vite-plugins/react-dom-prebundle.d.ts +3 -0
  188. package/dist/vite-plugins/react-dom-prebundle.d.ts.map +1 -0
  189. package/dist/vite-plugins/react-dom-prebundle.js +11 -0
  190. package/dist/vite-plugins/react-dom-prebundle.js.map +1 -0
  191. package/dist/vite-plugins/resource-init-module.d.ts +5 -0
  192. package/dist/vite-plugins/resource-init-module.d.ts.map +1 -0
  193. package/dist/vite-plugins/resource-init-module.js +50 -0
  194. package/dist/vite-plugins/resource-init-module.js.map +1 -0
  195. package/dist/vite-plugins/resource-shared.d.ts +6 -0
  196. package/dist/vite-plugins/resource-shared.d.ts.map +1 -0
  197. package/dist/vite-plugins/resource-shared.js +21 -0
  198. package/dist/vite-plugins/resource-shared.js.map +1 -0
  199. package/dist/vite-plugins/resources.d.ts +4 -0
  200. package/dist/vite-plugins/resources.d.ts.map +1 -0
  201. package/dist/vite-plugins/resources.js +220 -0
  202. package/dist/vite-plugins/resources.js.map +1 -0
  203. package/dist/vite-plugins/settings-worker-env.d.ts +3 -0
  204. package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -0
  205. package/dist/vite-plugins/settings-worker-env.js +21 -0
  206. package/dist/vite-plugins/settings-worker-env.js.map +1 -0
  207. package/dist/vite-plugins/settings.d.ts +3 -0
  208. package/dist/vite-plugins/settings.d.ts.map +1 -0
  209. package/dist/vite-plugins/settings.js +190 -0
  210. package/dist/vite-plugins/settings.js.map +1 -0
  211. package/dist/vite-plugins/undeclared-library.d.ts +3 -0
  212. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -0
  213. package/dist/vite-plugins/undeclared-library.js +47 -0
  214. package/dist/vite-plugins/undeclared-library.js.map +1 -0
  215. package/dist/vite-plugins/virtual-module.d.ts +22 -0
  216. package/dist/vite-plugins/virtual-module.d.ts.map +1 -0
  217. package/dist/vite-plugins/virtual-module.js +18 -0
  218. package/dist/vite-plugins/virtual-module.js.map +1 -0
  219. package/dist/vitest-plugin.d.ts +10 -0
  220. package/dist/vitest-plugin.d.ts.map +1 -0
  221. package/dist/vitest-plugin.js +12 -0
  222. package/dist/vitest-plugin.js.map +1 -0
  223. package/env.d.ts +131 -8
  224. package/package.json +32 -38
  225. package/src/babel-modules.d.ts +13 -0
  226. package/src/builder.ts +28 -84
  227. package/src/cli.ts +22 -0
  228. package/src/codegen/freshness.ts +52 -0
  229. package/src/codegen/report.ts +20 -0
  230. package/src/codegen/run-codegen.ts +185 -0
  231. package/src/codegen/store-resolver.ts +75 -0
  232. package/src/commands/build.ts +37 -0
  233. package/src/commands/codegen.ts +44 -0
  234. package/src/commands/dev.ts +25 -0
  235. package/src/commands/docs.ts +66 -0
  236. package/src/dev/icon-dir.ts +11 -0
  237. package/src/dev/refresh-tracker.ts +21 -0
  238. package/src/dev/runner-deps.ts +42 -0
  239. package/src/dev/runner-main.ts +33 -0
  240. package/src/dev/runner.ts +126 -0
  241. package/src/dev/schema-dir.ts +11 -0
  242. package/src/dev/supervisor.ts +178 -0
  243. package/src/dev/vite-dev-server.ts +34 -0
  244. package/src/internal/banner.ts +9 -0
  245. package/src/internal/data-dir.ts +39 -0
  246. package/src/internal/entry-arg.ts +38 -0
  247. package/src/internal/errors.ts +28 -0
  248. package/src/internal/list-files.ts +17 -0
  249. package/src/internal/resolve-cli-tool.ts +21 -0
  250. package/src/internal/staging-dir.ts +16 -0
  251. package/src/internal/xdg-data-dirs.ts +7 -0
  252. package/src/mcp/client.ts +177 -0
  253. package/src/mcp/handlers.ts +156 -0
  254. package/src/mcp/index.ts +22 -0
  255. package/src/mcp/serialize-widget.ts +34 -0
  256. package/src/mcp/testing-loader.ts +32 -0
  257. package/src/mcp/widget-registry.ts +43 -0
  258. package/src/refresh-runtime.ts +12 -41
  259. package/src/settings/compile.ts +19 -0
  260. package/src/settings/parser.ts +154 -0
  261. package/src/settings/render.ts +167 -0
  262. package/src/settings/schema.ts +115 -0
  263. package/src/vite-plugins/asset-extensions.ts +28 -0
  264. package/src/{vite-plugin-gtkx-built-url.ts → vite-plugins/built-url.ts} +3 -16
  265. package/src/vite-plugins/css.ts +38 -0
  266. package/src/vite-plugins/fast-refresh/refresh-filter.ts +18 -0
  267. package/src/vite-plugins/fast-refresh/swc-refresh.ts +79 -0
  268. package/src/vite-plugins/icons.ts +58 -0
  269. package/src/vite-plugins/index.ts +22 -0
  270. package/src/vite-plugins/native.ts +74 -0
  271. package/src/vite-plugins/react-compiler.ts +70 -0
  272. package/src/vite-plugins/react-dom-prebundle.ts +14 -0
  273. package/src/vite-plugins/resource-init-module.ts +54 -0
  274. package/src/vite-plugins/resource-shared.ts +27 -0
  275. package/src/vite-plugins/resources.ts +272 -0
  276. package/src/vite-plugins/settings-worker-env.ts +25 -0
  277. package/src/vite-plugins/settings.ts +221 -0
  278. package/src/vite-plugins/undeclared-library.ts +69 -0
  279. package/src/vite-plugins/virtual-module.ts +37 -0
  280. package/src/vitest-plugin.ts +14 -0
  281. package/dist/create.d.ts +0 -55
  282. package/dist/create.d.ts.map +0 -1
  283. package/dist/create.js +0 -236
  284. package/dist/create.js.map +0 -1
  285. package/dist/dev-server.d.ts +0 -37
  286. package/dist/dev-server.d.ts.map +0 -1
  287. package/dist/dev-server.js +0 -130
  288. package/dist/dev-server.js.map +0 -1
  289. package/dist/index.d.ts +0 -4
  290. package/dist/index.d.ts.map +0 -1
  291. package/dist/index.js +0 -4
  292. package/dist/index.js.map +0 -1
  293. package/dist/mcp-client.d.ts +0 -31
  294. package/dist/mcp-client.d.ts.map +0 -1
  295. package/dist/mcp-client.js +0 -430
  296. package/dist/mcp-client.js.map +0 -1
  297. package/dist/templates.d.ts +0 -9
  298. package/dist/templates.d.ts.map +0 -1
  299. package/dist/templates.js +0 -16
  300. package/dist/templates.js.map +0 -1
  301. package/dist/vite-plugin-gtkx-assets.d.ts +0 -20
  302. package/dist/vite-plugin-gtkx-assets.d.ts.map +0 -1
  303. package/dist/vite-plugin-gtkx-assets.js +0 -57
  304. package/dist/vite-plugin-gtkx-assets.js.map +0 -1
  305. package/dist/vite-plugin-gtkx-built-url.d.ts +0 -18
  306. package/dist/vite-plugin-gtkx-built-url.d.ts.map +0 -1
  307. package/dist/vite-plugin-gtkx-built-url.js.map +0 -1
  308. package/dist/vite-plugin-gtkx-gsettings.d.ts +0 -28
  309. package/dist/vite-plugin-gtkx-gsettings.d.ts.map +0 -1
  310. package/dist/vite-plugin-gtkx-gsettings.js +0 -147
  311. package/dist/vite-plugin-gtkx-gsettings.js.map +0 -1
  312. package/dist/vite-plugin-gtkx-native.d.ts +0 -14
  313. package/dist/vite-plugin-gtkx-native.d.ts.map +0 -1
  314. package/dist/vite-plugin-gtkx-native.js +0 -53
  315. package/dist/vite-plugin-gtkx-native.js.map +0 -1
  316. package/dist/vite-plugin-gtkx-refresh.d.ts +0 -8
  317. package/dist/vite-plugin-gtkx-refresh.d.ts.map +0 -1
  318. package/dist/vite-plugin-gtkx-refresh.js +0 -37
  319. package/dist/vite-plugin-gtkx-refresh.js.map +0 -1
  320. package/dist/vite-plugin-swc-ssr-refresh.d.ts +0 -8
  321. package/dist/vite-plugin-swc-ssr-refresh.d.ts.map +0 -1
  322. package/dist/vite-plugin-swc-ssr-refresh.js +0 -46
  323. package/dist/vite-plugin-swc-ssr-refresh.js.map +0 -1
  324. package/src/cli.tsx +0 -154
  325. package/src/create.ts +0 -326
  326. package/src/dev-server.tsx +0 -162
  327. package/src/index.ts +0 -3
  328. package/src/mcp-client.ts +0 -518
  329. package/src/templates.ts +0 -26
  330. package/src/vite-plugin-gtkx-assets.ts +0 -69
  331. package/src/vite-plugin-gtkx-gsettings.ts +0 -168
  332. package/src/vite-plugin-gtkx-native.ts +0 -64
  333. package/src/vite-plugin-gtkx-refresh.ts +0 -54
  334. package/src/vite-plugin-swc-ssr-refresh.ts +0 -61
  335. package/templates/claude/EXAMPLES.md.ejs +0 -744
  336. package/templates/claude/SKILL.md.ejs +0 -93
  337. package/templates/claude/WIDGETS.md.ejs +0 -820
  338. package/templates/config/vitest.config.ts.ejs +0 -11
  339. package/templates/gitignore.ejs +0 -4
  340. package/templates/package.json.ejs +0 -16
  341. package/templates/src/app.tsx.ejs +0 -32
  342. package/templates/src/dev.tsx.ejs +0 -5
  343. package/templates/src/gtkx-env.d.ts.ejs +0 -1
  344. package/templates/src/index.tsx.ejs +0 -5
  345. package/templates/tests/app.test.tsx.ejs +0 -16
  346. package/templates/tsconfig.json.ejs +0 -14
@@ -1,37 +0,0 @@
1
- import { type InlineConfig, type ViteDevServer } from "vite";
2
- /**
3
- * Options for the GTKX development server.
4
- */
5
- export type DevServerOptions = {
6
- /** Path to the entry file (e.g., "src/dev.tsx") */
7
- entry: string;
8
- /** Additional Vite configuration */
9
- vite?: InlineConfig;
10
- };
11
- /**
12
- * Creates a Vite-based development server with hot module replacement.
13
- *
14
- * Provides fast refresh for React components and full reload for other changes.
15
- * The server watches for file changes and automatically updates the running
16
- * GTK application.
17
- *
18
- * @param options - Server configuration including entry point and Vite options
19
- * @returns A Vite development server instance
20
- *
21
- * @example
22
- * ```tsx
23
- * import { createDevServer } from "@gtkx/cli";
24
- * import { render } from "@gtkx/react";
25
- *
26
- * const server = await createDevServer({
27
- * entry: "./src/dev.tsx",
28
- * });
29
- *
30
- * const mod = await server.ssrLoadModule("./src/dev.tsx");
31
- * render(<mod.default />, mod.appId);
32
- * ```
33
- *
34
- * @see {@link DevServerOptions} for configuration options
35
- */
36
- export declare const createDevServer: (options: DevServerOptions) => Promise<ViteDevServer>;
37
- //# sourceMappingURL=dev-server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../src/dev-server.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAO3E;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,IAAI,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,eAAe,GAAU,SAAS,gBAAgB,KAAG,OAAO,CAAC,aAAa,CAiHtF,CAAC"}
@@ -1,130 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { events } from "@gtkx/ffi";
3
- import { setHotReloading, update } from "@gtkx/react";
4
- import { createServer } from "vite";
5
- import { isReactRefreshBoundary, performRefresh } from "./refresh-runtime.js";
6
- import { gtkxAssets } from "./vite-plugin-gtkx-assets.js";
7
- import { gtkxGSettings } from "./vite-plugin-gtkx-gsettings.js";
8
- import { gtkxRefresh } from "./vite-plugin-gtkx-refresh.js";
9
- import { swcSsrRefresh } from "./vite-plugin-swc-ssr-refresh.js";
10
- /**
11
- * Creates a Vite-based development server with hot module replacement.
12
- *
13
- * Provides fast refresh for React components and full reload for other changes.
14
- * The server watches for file changes and automatically updates the running
15
- * GTK application.
16
- *
17
- * @param options - Server configuration including entry point and Vite options
18
- * @returns A Vite development server instance
19
- *
20
- * @example
21
- * ```tsx
22
- * import { createDevServer } from "@gtkx/cli";
23
- * import { render } from "@gtkx/react";
24
- *
25
- * const server = await createDevServer({
26
- * entry: "./src/dev.tsx",
27
- * });
28
- *
29
- * const mod = await server.ssrLoadModule("./src/dev.tsx");
30
- * render(<mod.default />, mod.appId);
31
- * ```
32
- *
33
- * @see {@link DevServerOptions} for configuration options
34
- */
35
- export const createDevServer = async (options) => {
36
- const { entry, vite: viteConfig } = options;
37
- const moduleExports = new Map();
38
- const server = await createServer({
39
- ...viteConfig,
40
- appType: "custom",
41
- plugins: [
42
- gtkxGSettings(),
43
- gtkxAssets(),
44
- swcSsrRefresh(),
45
- gtkxRefresh(),
46
- {
47
- name: "gtkx:remove-react-dom-optimized",
48
- enforce: "post",
49
- config(config) {
50
- config.optimizeDeps ??= {};
51
- config.optimizeDeps.include = config.optimizeDeps.include?.filter((dep) => dep !== "react-dom" && !dep.startsWith("react-dom/"));
52
- },
53
- },
54
- ],
55
- server: {
56
- ...viteConfig?.server,
57
- middlewareMode: true,
58
- },
59
- optimizeDeps: {
60
- ...viteConfig?.optimizeDeps,
61
- noDiscovery: true,
62
- include: [],
63
- },
64
- ssr: {
65
- ...viteConfig?.ssr,
66
- external: true,
67
- },
68
- });
69
- const loadModule = async () => {
70
- const mod = (await server.ssrLoadModule(entry));
71
- moduleExports.set(entry, { ...mod });
72
- return mod;
73
- };
74
- const invalidateAllModules = () => {
75
- for (const module of server.moduleGraph.idToModuleMap.values()) {
76
- server.moduleGraph.invalidateModule(module);
77
- }
78
- };
79
- const invalidateModuleAndImporters = (filePath) => {
80
- const module = server.moduleGraph.getModuleById(filePath);
81
- if (module) {
82
- server.moduleGraph.invalidateModule(module);
83
- for (const importer of module.importers) {
84
- server.moduleGraph.invalidateModule(importer);
85
- }
86
- }
87
- };
88
- events.on("stop", () => {
89
- server.close();
90
- });
91
- server.watcher.on("change", async (changedPath) => {
92
- try {
93
- const module = server.moduleGraph.getModuleById(changedPath);
94
- if (!module) {
95
- return;
96
- }
97
- console.log(`[gtkx] File changed: ${changedPath}`);
98
- invalidateModuleAndImporters(changedPath);
99
- const newMod = (await server.ssrLoadModule(changedPath));
100
- moduleExports.set(changedPath, { ...newMod });
101
- if (isReactRefreshBoundary(newMod)) {
102
- console.log("[gtkx] Fast refreshing...");
103
- performRefresh();
104
- console.log("[gtkx] Fast refresh complete");
105
- return;
106
- }
107
- console.log("[gtkx] Full reload...");
108
- invalidateAllModules();
109
- const mod = await loadModule();
110
- const App = mod.default;
111
- if (typeof App !== "function") {
112
- console.error("[gtkx] Entry file must export a default function component");
113
- return;
114
- }
115
- setHotReloading(true);
116
- try {
117
- await update(_jsx(App, {}));
118
- }
119
- finally {
120
- setHotReloading(false);
121
- }
122
- console.log("[gtkx] Full reload complete");
123
- }
124
- catch (error) {
125
- console.error("[gtkx] Hot reload failed:", error);
126
- }
127
- });
128
- return server;
129
- };
130
- //# sourceMappingURL=dev-server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../src/dev-server.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export { type BuildOptions, build } from "./builder.js";
2
- export { createApp } from "./create.js";
3
- export { createDevServer, type DevServerOptions } from "./dev-server.js";
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js DELETED
@@ -1,4 +0,0 @@
1
- export { build } from "./builder.js";
2
- export { createApp } from "./create.js";
3
- export { createDevServer } from "./dev-server.js";
4
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAyB,MAAM,iBAAiB,CAAC"}
@@ -1,31 +0,0 @@
1
- type McpClientOptions = {
2
- socketPath?: string;
3
- appId: string;
4
- };
5
- declare class McpClient {
6
- private socket;
7
- private buffer;
8
- private socketPath;
9
- private appId;
10
- private reconnectTimer;
11
- private hasConnected;
12
- private isStopping;
13
- private pendingRequests;
14
- constructor(options: McpClientOptions);
15
- connect(): Promise<void>;
16
- private attemptConnect;
17
- private scheduleReconnect;
18
- disconnect(): void;
19
- private rejectPendingRequests;
20
- private register;
21
- private send;
22
- private sendRequest;
23
- private handleData;
24
- private processMessage;
25
- private handleRequest;
26
- private executeMethod;
27
- }
28
- export declare const startMcpClient: (appId: string) => Promise<McpClient>;
29
- export declare const stopMcpClient: () => void;
30
- export {};
31
- //# sourceMappingURL=mcp-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAoDA,KAAK,gBAAgB,GAAG;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAgFF,cAAM,SAAS;IACX,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAqC;gBAEhD,OAAO,EAAE,gBAAgB;IAK/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B,OAAO,CAAC,cAAc;IAgDtB,OAAO,CAAC,iBAAiB;IAQzB,UAAU,IAAI,IAAI;IAelB,OAAO,CAAC,qBAAqB;YAQf,QAAQ;IAOtB,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,cAAc;YAmCR,aAAa;YAsBb,aAAa;CA+J9B;AAID,eAAO,MAAM,cAAc,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,SAAS,CAUrE,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,IAKhC,CAAC"}
@@ -1,430 +0,0 @@
1
- import * as net from "node:net";
2
- import { getNativeInterface } from "@gtkx/ffi";
3
- import * as Gio from "@gtkx/ffi/gio";
4
- import { Value } from "@gtkx/ffi/gobject";
5
- import * as Gtk from "@gtkx/ffi/gtk";
6
- import { DEFAULT_SOCKET_PATH, IpcRequestSchema, IpcResponseSchema, McpError, McpErrorCode, methodNotFoundError, widgetNotFoundError, } from "@gtkx/mcp";
7
- const widgetIdMap = new WeakMap();
8
- let nextWidgetId = 0;
9
- const getWidgetId = (widget) => {
10
- let id = widgetIdMap.get(widget);
11
- if (!id) {
12
- id = String(nextWidgetId++);
13
- widgetIdMap.set(widget, id);
14
- }
15
- return id;
16
- };
17
- let testingModule = null;
18
- let testingLoadError = null;
19
- const loadTestingModule = async () => {
20
- if (testingModule)
21
- return testingModule;
22
- if (testingLoadError)
23
- throw testingLoadError;
24
- try {
25
- testingModule = await import("@gtkx/testing");
26
- return testingModule;
27
- }
28
- catch (cause) {
29
- testingLoadError = new Error("@gtkx/testing is not installed, install it to enable MCP widget interactions: pnpm add -D @gtkx/testing", { cause });
30
- throw testingLoadError;
31
- }
32
- };
33
- const RECONNECT_DELAY_MS = 2000;
34
- const REQUEST_TIMEOUT_MS = 30000;
35
- const formatRole = (role) => {
36
- if (role === undefined)
37
- return "UNKNOWN";
38
- return Gtk.AccessibleRole[role] ?? String(role);
39
- };
40
- const getWidgetText = (widget) => {
41
- if ("getLabel" in widget && typeof widget.getLabel === "function") {
42
- return widget.getLabel() ?? null;
43
- }
44
- if ("getText" in widget && typeof widget.getText === "function") {
45
- return widget.getText() ?? null;
46
- }
47
- if ("getTitle" in widget && typeof widget.getTitle === "function") {
48
- return widget.getTitle() ?? null;
49
- }
50
- return getNativeInterface(widget, Gtk.Editable)?.getText() ?? null;
51
- };
52
- const serializeWidget = (widget) => {
53
- const children = [];
54
- let child = widget.getFirstChild();
55
- while (child) {
56
- children.push(serializeWidget(child));
57
- child = child.getNextSibling();
58
- }
59
- const text = getWidgetText(widget);
60
- return {
61
- id: getWidgetId(widget),
62
- type: widget.constructor.name,
63
- role: formatRole(widget.getAccessibleRole()),
64
- name: widget.getName() || null,
65
- label: text,
66
- text,
67
- sensitive: widget.getSensitive(),
68
- visible: widget.getVisible(),
69
- cssClasses: widget.getCssClasses() ?? [],
70
- children,
71
- };
72
- };
73
- const widgetRegistry = new Map();
74
- const registerWidgets = (widget) => {
75
- const idStr = getWidgetId(widget);
76
- widgetRegistry.set(idStr, widget);
77
- let child = widget.getFirstChild();
78
- while (child) {
79
- registerWidgets(child);
80
- child = child.getNextSibling();
81
- }
82
- };
83
- const getWidgetById = (id) => {
84
- return widgetRegistry.get(id);
85
- };
86
- const refreshWidgetRegistry = () => {
87
- widgetRegistry.clear();
88
- const windows = Gtk.Window.listToplevels();
89
- for (const window of windows) {
90
- registerWidgets(window);
91
- }
92
- };
93
- class McpClient {
94
- socket = null;
95
- buffer = "";
96
- socketPath;
97
- appId;
98
- reconnectTimer = null;
99
- hasConnected = false;
100
- isStopping = false;
101
- pendingRequests = new Map();
102
- constructor(options) {
103
- this.socketPath = options.socketPath ?? DEFAULT_SOCKET_PATH;
104
- this.appId = options.appId;
105
- }
106
- async connect() {
107
- return new Promise((resolve, reject) => {
108
- this.attemptConnect(resolve, reject);
109
- });
110
- }
111
- attemptConnect(onSuccess, onError) {
112
- let settled = false;
113
- const settle = (callback, ...args) => {
114
- if (settled)
115
- return;
116
- settled = true;
117
- callback?.(...args);
118
- };
119
- this.socket = net.createConnection(this.socketPath, () => {
120
- console.log(`[gtkx] Connected to MCP server at ${this.socketPath}`);
121
- this.hasConnected = true;
122
- this.register()
123
- .then(() => {
124
- console.log("[gtkx] Registered with MCP server");
125
- settle(onSuccess);
126
- })
127
- .catch((error) => {
128
- console.error("[gtkx] Failed to register with MCP server:", error.message);
129
- settle(onError, error instanceof Error ? error : new Error(String(error)));
130
- });
131
- });
132
- this.socket.on("data", (data) => this.handleData(data));
133
- this.socket.on("close", () => {
134
- if (this.hasConnected) {
135
- console.log("[gtkx] Disconnected from MCP server");
136
- this.hasConnected = false;
137
- }
138
- this.socket = null;
139
- this.rejectPendingRequests(new Error("Connection closed"));
140
- this.scheduleReconnect();
141
- });
142
- this.socket.on("error", (error) => {
143
- const code = error.code;
144
- const isDisconnectError = code === "ENOENT" || code === "ECONNREFUSED" || code === "EPIPE" || code === "ECONNRESET";
145
- if (isDisconnectError) {
146
- this.scheduleReconnect();
147
- }
148
- else {
149
- console.error("[gtkx] Socket error:", error.message);
150
- }
151
- settle(onError, error);
152
- });
153
- }
154
- scheduleReconnect() {
155
- if (this.reconnectTimer || this.isStopping)
156
- return;
157
- this.reconnectTimer = setTimeout(() => {
158
- this.reconnectTimer = null;
159
- this.attemptConnect();
160
- }, RECONNECT_DELAY_MS);
161
- }
162
- disconnect() {
163
- this.isStopping = true;
164
- if (this.reconnectTimer) {
165
- clearTimeout(this.reconnectTimer);
166
- this.reconnectTimer = null;
167
- }
168
- this.rejectPendingRequests(new Error("Client disconnected"));
169
- if (this.socket) {
170
- this.send({ id: crypto.randomUUID(), method: "app.unregister" });
171
- this.socket.destroy();
172
- this.socket = null;
173
- }
174
- this.hasConnected = false;
175
- }
176
- rejectPendingRequests(error) {
177
- for (const pending of this.pendingRequests.values()) {
178
- clearTimeout(pending.timeout);
179
- pending.reject(error);
180
- }
181
- this.pendingRequests.clear();
182
- }
183
- async register() {
184
- await this.sendRequest("app.register", {
185
- appId: this.appId,
186
- pid: process.pid,
187
- });
188
- }
189
- send(message) {
190
- if (!this.socket?.writable)
191
- return;
192
- this.socket.write(`${JSON.stringify(message)}\n`);
193
- }
194
- sendRequest(method, params) {
195
- return new Promise((resolve, reject) => {
196
- if (!this.socket?.writable) {
197
- reject(new Error("Socket not connected"));
198
- return;
199
- }
200
- const id = crypto.randomUUID();
201
- const timeout = setTimeout(() => {
202
- this.pendingRequests.delete(id);
203
- reject(new Error(`Request timed out: ${method}`));
204
- }, REQUEST_TIMEOUT_MS);
205
- this.pendingRequests.set(id, { resolve, reject, timeout });
206
- this.send({ id, method, params });
207
- });
208
- }
209
- handleData(data) {
210
- this.buffer += data.toString();
211
- let newlineIndex = this.buffer.indexOf("\n");
212
- while (newlineIndex !== -1) {
213
- const line = this.buffer.slice(0, newlineIndex);
214
- this.buffer = this.buffer.slice(newlineIndex + 1);
215
- if (line.trim()) {
216
- this.processMessage(line);
217
- }
218
- newlineIndex = this.buffer.indexOf("\n");
219
- }
220
- }
221
- processMessage(line) {
222
- let parsed;
223
- try {
224
- parsed = JSON.parse(line);
225
- }
226
- catch {
227
- console.warn("[gtkx] Received invalid JSON from MCP server");
228
- return;
229
- }
230
- const responseResult = IpcResponseSchema.safeParse(parsed);
231
- if (responseResult.success) {
232
- const response = responseResult.data;
233
- const pending = this.pendingRequests.get(response.id);
234
- if (pending) {
235
- clearTimeout(pending.timeout);
236
- this.pendingRequests.delete(response.id);
237
- if (response.error) {
238
- pending.reject(new Error(response.error.message));
239
- }
240
- else {
241
- pending.resolve(response.result);
242
- }
243
- return;
244
- }
245
- }
246
- const requestResult = IpcRequestSchema.safeParse(parsed);
247
- if (!requestResult.success) {
248
- return;
249
- }
250
- this.handleRequest(requestResult.data).catch((error) => {
251
- console.error("[gtkx] Error handling request:", error);
252
- });
253
- }
254
- async handleRequest(request) {
255
- const { id, method, params } = request;
256
- try {
257
- const result = await this.executeMethod(method, params);
258
- this.send({ id, result });
259
- }
260
- catch (error) {
261
- if (error instanceof McpError) {
262
- this.send({ id, error: error.toIpcError() });
263
- }
264
- else {
265
- const message = error instanceof Error ? error.message : String(error);
266
- this.send({
267
- id,
268
- error: {
269
- code: McpErrorCode.INTERNAL_ERROR,
270
- message,
271
- },
272
- });
273
- }
274
- }
275
- }
276
- async executeMethod(method, params) {
277
- const app = Gio.Application.getDefault();
278
- if (!app) {
279
- throw new Error("Application not initialized");
280
- }
281
- refreshWidgetRegistry();
282
- switch (method) {
283
- case "app.getWindows": {
284
- const windows = Gtk.Window.listToplevels();
285
- return {
286
- windows: windows.map((w) => ({
287
- id: getWidgetId(w),
288
- title: w.getTitle?.() ?? null,
289
- })),
290
- };
291
- }
292
- case "widget.getTree": {
293
- const testing = await loadTestingModule();
294
- return { tree: testing.prettyWidget(app, { includeIds: true, highlight: false }) };
295
- }
296
- case "widget.query": {
297
- const testing = await loadTestingModule();
298
- const p = params;
299
- let widgets = [];
300
- switch (p.queryType) {
301
- case "role": {
302
- const roleValue = typeof p.value === "string"
303
- ? Gtk.AccessibleRole[p.value]
304
- : p.value;
305
- widgets = await testing.findAllByRole(app, roleValue, p.options);
306
- break;
307
- }
308
- case "text":
309
- widgets = await testing.findAllByText(app, String(p.value), p.options);
310
- break;
311
- case "name":
312
- widgets = await testing.findAllByName(app, String(p.value), p.options);
313
- break;
314
- case "labelText":
315
- widgets = await testing.findAllByLabelText(app, String(p.value), p.options);
316
- break;
317
- default:
318
- throw new Error(`Unknown query type: ${p.queryType}`);
319
- }
320
- return { widgets: widgets.map((w) => serializeWidget(w)) };
321
- }
322
- case "widget.getProps": {
323
- const p = params;
324
- const widget = getWidgetById(p.widgetId);
325
- if (!widget) {
326
- throw widgetNotFoundError(p.widgetId);
327
- }
328
- return serializeWidget(widget);
329
- }
330
- case "widget.click": {
331
- const testing = await loadTestingModule();
332
- const p = params;
333
- const widget = getWidgetById(p.widgetId);
334
- if (!widget) {
335
- throw widgetNotFoundError(p.widgetId);
336
- }
337
- await testing.userEvent.click(widget);
338
- return { success: true };
339
- }
340
- case "widget.type": {
341
- const testing = await loadTestingModule();
342
- const p = params;
343
- const widget = getWidgetById(p.widgetId);
344
- if (!widget) {
345
- throw widgetNotFoundError(p.widgetId);
346
- }
347
- if (p.clear) {
348
- await testing.userEvent.clear(widget);
349
- }
350
- await testing.userEvent.type(widget, p.text);
351
- return { success: true };
352
- }
353
- case "widget.fireEvent": {
354
- const testing = await loadTestingModule();
355
- const p = params;
356
- const widget = getWidgetById(p.widgetId);
357
- if (!widget) {
358
- throw widgetNotFoundError(p.widgetId);
359
- }
360
- const signalArgs = (p.args ?? []).map((arg) => {
361
- const isTypedArg = typeof arg === "object" && arg !== null && "type" in arg && "value" in arg;
362
- const argType = isTypedArg ? arg.type : typeof arg;
363
- const argValue = isTypedArg ? arg.value : arg;
364
- switch (argType) {
365
- case "boolean":
366
- return Value.newFromBoolean(argValue);
367
- case "int":
368
- return Value.newFromInt(argValue);
369
- case "uint":
370
- return Value.newFromUint(argValue);
371
- case "int64":
372
- return Value.newFromInt64(argValue);
373
- case "uint64":
374
- return Value.newFromUint64(argValue);
375
- case "float":
376
- return Value.newFromFloat(argValue);
377
- case "double":
378
- case "number":
379
- return Value.newFromDouble(argValue);
380
- case "string":
381
- return Value.newFromString(argValue);
382
- default:
383
- throw new McpError(McpErrorCode.INVALID_REQUEST, `Unknown argument type: ${argType}`);
384
- }
385
- });
386
- await testing.fireEvent(widget, p.signal, ...signalArgs);
387
- return { success: true };
388
- }
389
- case "widget.screenshot": {
390
- const testing = await loadTestingModule();
391
- const p = params;
392
- let targetWindow;
393
- if (p.windowId) {
394
- const widget = getWidgetById(p.windowId);
395
- if (!widget) {
396
- throw widgetNotFoundError(p.windowId);
397
- }
398
- targetWindow = widget;
399
- }
400
- else {
401
- const windows = app.getWindows();
402
- if (windows.length === 0) {
403
- throw new Error("No windows available for screenshot");
404
- }
405
- targetWindow = windows[0];
406
- }
407
- const result = await testing.screenshot(targetWindow);
408
- return { data: result.data, mimeType: result.mimeType };
409
- }
410
- default:
411
- throw methodNotFoundError(method);
412
- }
413
- }
414
- }
415
- let globalClient = null;
416
- export const startMcpClient = async (appId) => {
417
- if (globalClient) {
418
- return globalClient;
419
- }
420
- globalClient = new McpClient({ appId });
421
- await globalClient.connect().catch(() => { });
422
- return globalClient;
423
- };
424
- export const stopMcpClient = () => {
425
- if (globalClient) {
426
- globalClient.disconnect();
427
- globalClient = null;
428
- }
429
- };
430
- //# sourceMappingURL=mcp-client.js.map