@askrjs/cli 0.0.2

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 (460) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +140 -0
  3. package/dist/add-DqhqRzBQ.js +555 -0
  4. package/dist/add-DqhqRzBQ.js.map +1 -0
  5. package/dist/add.js +3 -0
  6. package/dist/cli.js +91 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/create.js +923 -0
  9. package/dist/create.js.map +1 -0
  10. package/dist/is-direct-execution-Cdlr-ZUl.js +20 -0
  11. package/dist/is-direct-execution-Cdlr-ZUl.js.map +1 -0
  12. package/dist/openapi.js +127 -0
  13. package/dist/openapi.js.map +1 -0
  14. package/dist/skills/askr-accessibility/SKILL.md +68 -0
  15. package/dist/skills/askr-accessibility/agents/openai.yaml +4 -0
  16. package/dist/skills/askr-agent-execution/SKILL.md +85 -0
  17. package/dist/skills/askr-agent-execution/agents/openai.yaml +4 -0
  18. package/dist/skills/askr-agent-workflows/SKILL.md +57 -0
  19. package/dist/skills/askr-agent-workflows/agents/openai.yaml +4 -0
  20. package/dist/skills/askr-api-integration/SKILL.md +79 -0
  21. package/dist/skills/askr-api-integration/agents/openai.yaml +4 -0
  22. package/dist/skills/askr-app-builder/SKILL.md +99 -0
  23. package/dist/skills/askr-app-builder/agents/openai.yaml +4 -0
  24. package/dist/skills/askr-auth-access/SKILL.md +74 -0
  25. package/dist/skills/askr-auth-access/agents/openai.yaml +4 -0
  26. package/dist/skills/askr-cli-vite/SKILL.md +76 -0
  27. package/dist/skills/askr-cli-vite/agents/openai.yaml +4 -0
  28. package/dist/skills/askr-dashboard-charts/SKILL.md +82 -0
  29. package/dist/skills/askr-dashboard-charts/agents/openai.yaml +4 -0
  30. package/dist/skills/askr-design-system/SKILL.md +86 -0
  31. package/dist/skills/askr-design-system/agents/openai.yaml +4 -0
  32. package/dist/skills/askr-env-config/SKILL.md +74 -0
  33. package/dist/skills/askr-env-config/agents/openai.yaml +4 -0
  34. package/dist/skills/askr-error-loading-empty/SKILL.md +89 -0
  35. package/dist/skills/askr-error-loading-empty/agents/openai.yaml +4 -0
  36. package/dist/skills/askr-file-upload-artifacts/SKILL.md +77 -0
  37. package/dist/skills/askr-file-upload-artifacts/agents/openai.yaml +4 -0
  38. package/dist/skills/askr-forms-tables-crud/SKILL.md +98 -0
  39. package/dist/skills/askr-forms-tables-crud/agents/openai.yaml +4 -0
  40. package/dist/skills/askr-mental-model/SKILL.md +109 -0
  41. package/dist/skills/askr-mental-model/agents/openai.yaml +4 -0
  42. package/dist/skills/askr-migration-react/SKILL.md +81 -0
  43. package/dist/skills/askr-migration-react/agents/openai.yaml +4 -0
  44. package/dist/skills/askr-observability-debugging/SKILL.md +83 -0
  45. package/dist/skills/askr-observability-debugging/agents/openai.yaml +4 -0
  46. package/dist/skills/askr-project-structure/SKILL.md +79 -0
  47. package/dist/skills/askr-project-structure/agents/openai.yaml +4 -0
  48. package/dist/skills/askr-query-mutation/SKILL.md +115 -0
  49. package/dist/skills/askr-query-mutation/agents/openai.yaml +4 -0
  50. package/dist/skills/askr-realtime-streaming/SKILL.md +76 -0
  51. package/dist/skills/askr-realtime-streaming/agents/openai.yaml +4 -0
  52. package/dist/skills/askr-resources-data/SKILL.md +100 -0
  53. package/dist/skills/askr-resources-data/agents/openai.yaml +4 -0
  54. package/dist/skills/askr-routing-layouts/SKILL.md +107 -0
  55. package/dist/skills/askr-routing-layouts/agents/openai.yaml +4 -0
  56. package/dist/skills/askr-runtime-reactivity/SKILL.md +92 -0
  57. package/dist/skills/askr-runtime-reactivity/agents/openai.yaml +4 -0
  58. package/dist/skills/askr-ssr-ssg/SKILL.md +76 -0
  59. package/dist/skills/askr-ssr-ssg/agents/openai.yaml +4 -0
  60. package/dist/skills/askr-testing-determinism/SKILL.md +75 -0
  61. package/dist/skills/askr-testing-determinism/agents/openai.yaml +4 -0
  62. package/dist/skills/askr-theming/SKILL.md +86 -0
  63. package/dist/skills/askr-theming/agents/openai.yaml +4 -0
  64. package/dist/skills/askr-ui-composition/SKILL.md +92 -0
  65. package/dist/skills/askr-ui-composition/agents/openai.yaml +4 -0
  66. package/dist/skills-Bh0mEhIx.js +682 -0
  67. package/dist/skills-Bh0mEhIx.js.map +1 -0
  68. package/dist/skills.js +3 -0
  69. package/dist/ssg.js +188 -0
  70. package/dist/ssg.js.map +1 -0
  71. package/dist/templates/full-stack/AGENTS.md +12 -0
  72. package/dist/templates/full-stack/README.md +18 -0
  73. package/dist/templates/full-stack/gitignore.template +4 -0
  74. package/dist/templates/full-stack/index.html +14 -0
  75. package/dist/templates/full-stack/package.json +37 -0
  76. package/dist/templates/full-stack/server.ts +13 -0
  77. package/dist/templates/full-stack/src/action-authorizations.ts +10 -0
  78. package/dist/templates/full-stack/src/actions/create-message.ts +10 -0
  79. package/dist/templates/full-stack/src/i18n.ts +8 -0
  80. package/dist/templates/full-stack/src/main.tsx +12 -0
  81. package/dist/templates/full-stack/src/pages/home.tsx +25 -0
  82. package/dist/templates/full-stack/src/pages/layout.tsx +33 -0
  83. package/dist/templates/full-stack/src/pages/not-found.tsx +4 -0
  84. package/dist/templates/full-stack/src/routes.tsx +20 -0
  85. package/dist/templates/full-stack/src/schemas.ts +11 -0
  86. package/dist/templates/full-stack/src/server/action-registry.ts +12 -0
  87. package/dist/templates/full-stack/src/server/actions/create-message.ts +14 -0
  88. package/dist/templates/full-stack/src/server/app.ts +66 -0
  89. package/dist/templates/full-stack/src/server/dependencies.ts +55 -0
  90. package/dist/templates/full-stack/src/server/entry-server.ts +8 -0
  91. package/dist/templates/full-stack/src/telemetry.ts +4 -0
  92. package/dist/templates/full-stack/src/vite-server.d.ts +6 -0
  93. package/dist/templates/full-stack/tests/actions/create-message.test.ts +13 -0
  94. package/dist/templates/full-stack/tsconfig.json +16 -0
  95. package/dist/templates/full-stack/vite.config.ts +11 -0
  96. package/dist/templates/spa/AGENTS.md +60 -0
  97. package/dist/templates/spa/README.md +96 -0
  98. package/dist/templates/spa/gitignore.template +16 -0
  99. package/dist/templates/spa/index.html +13 -0
  100. package/dist/templates/spa/package.json +35 -0
  101. package/dist/templates/spa/src/adapters/operations-client.ts +90 -0
  102. package/dist/templates/spa/src/components/shared/metric-card.tsx +27 -0
  103. package/dist/templates/spa/src/components/shared/status-badge.tsx +24 -0
  104. package/dist/templates/spa/src/features/operations/operations.query.ts +9 -0
  105. package/dist/templates/spa/src/main.tsx +10 -0
  106. package/dist/templates/spa/src/pages/_layout.tsx +9 -0
  107. package/dist/templates/spa/src/pages/_routes.tsx +27 -0
  108. package/dist/templates/spa/src/pages/app/_layout.tsx +94 -0
  109. package/dist/templates/spa/src/pages/app/_routes.tsx +10 -0
  110. package/dist/templates/spa/src/pages/app/admin-home.tsx +152 -0
  111. package/dist/templates/spa/src/pages/app/agent-runs.tsx +93 -0
  112. package/dist/templates/spa/src/pages/app/settings.tsx +91 -0
  113. package/dist/templates/spa/src/pages/auth/_layout.tsx +38 -0
  114. package/dist/templates/spa/src/pages/auth/_routes.tsx +6 -0
  115. package/dist/templates/spa/src/pages/auth/login.tsx +63 -0
  116. package/dist/templates/spa/src/pages/not-found.tsx +22 -0
  117. package/dist/templates/spa/src/pages/public/_layout.tsx +47 -0
  118. package/dist/templates/spa/src/pages/public/_routes.tsx +6 -0
  119. package/dist/templates/spa/src/pages/public/home.tsx +143 -0
  120. package/dist/templates/spa/src/shared/format.ts +12 -0
  121. package/dist/templates/spa/src/shared/navigation.ts +15 -0
  122. package/dist/templates/spa/src/styles/components.css +49 -0
  123. package/dist/templates/spa/src/styles/layout.css +192 -0
  124. package/dist/templates/spa/src/styles/reset.css +44 -0
  125. package/dist/templates/spa/src/styles/theme.css +57 -0
  126. package/dist/templates/spa/src/styles/tokens.css +20 -0
  127. package/dist/templates/spa/src/styles.css +7 -0
  128. package/dist/templates/spa/src/styles.d.ts +1 -0
  129. package/dist/templates/spa/tests/app.test.tsx +37 -0
  130. package/dist/templates/spa/tests/components/shared.test.tsx +12 -0
  131. package/dist/templates/spa/tests/resources.test.ts +22 -0
  132. package/dist/templates/spa/tsconfig.json +20 -0
  133. package/dist/templates/spa/tsconfig.node.json +10 -0
  134. package/dist/templates/spa/vite.config.ts +24 -0
  135. package/dist/templates/spa/vitest.config.ts +17 -0
  136. package/dist/templates/ssg/AGENTS.md +55 -0
  137. package/dist/templates/ssg/README.md +39 -0
  138. package/dist/templates/ssg/gitignore.template +17 -0
  139. package/dist/templates/ssg/index.html +13 -0
  140. package/dist/templates/ssg/package.json +35 -0
  141. package/dist/templates/ssg/src/app.tsx +14 -0
  142. package/dist/templates/ssg/src/components/badge.tsx +3 -0
  143. package/dist/templates/ssg/src/components/counter.tsx +30 -0
  144. package/dist/templates/ssg/src/components/site-shell.tsx +111 -0
  145. package/dist/templates/ssg/src/jsx.d.ts +23 -0
  146. package/dist/templates/ssg/src/main.tsx +8 -0
  147. package/dist/templates/ssg/src/pages/about.tsx +82 -0
  148. package/dist/templates/ssg/src/pages/content.tsx +63 -0
  149. package/dist/templates/ssg/src/pages/example.tsx +97 -0
  150. package/dist/templates/ssg/src/pages/home.tsx +51 -0
  151. package/dist/templates/ssg/src/resources/user.ts +15 -0
  152. package/dist/templates/ssg/src/routes.tsx +15 -0
  153. package/dist/templates/ssg/src/styles.css +89 -0
  154. package/dist/templates/ssg/src/vite-env.d.ts +5 -0
  155. package/dist/templates/ssg/ssg.config.ts +34 -0
  156. package/dist/templates/ssg/tests/app.test.tsx +19 -0
  157. package/dist/templates/ssg/tests/components/counter.test.tsx +18 -0
  158. package/dist/templates/ssg/tests/resources.test.ts +11 -0
  159. package/dist/templates/ssg/tests/ssg-config.test.ts +11 -0
  160. package/dist/templates/ssg/tsconfig.json +20 -0
  161. package/dist/templates/ssg/tsconfig.node.json +10 -0
  162. package/dist/templates/ssg/vite.config.ts +24 -0
  163. package/dist/templates/ssg/vitest.config.ts +17 -0
  164. package/dist/templates/ssr/AGENTS.md +28 -0
  165. package/dist/templates/ssr/README.md +38 -0
  166. package/dist/templates/ssr/gitignore.template +16 -0
  167. package/dist/templates/ssr/index.html +13 -0
  168. package/dist/templates/ssr/package.json +34 -0
  169. package/dist/templates/ssr/server.ts +16 -0
  170. package/dist/templates/ssr/src/app.tsx +21 -0
  171. package/dist/templates/ssr/src/components/counter.tsx +26 -0
  172. package/dist/templates/ssr/src/entry-server.tsx +10 -0
  173. package/dist/templates/ssr/src/main.tsx +11 -0
  174. package/dist/templates/ssr/src/pages/about.tsx +75 -0
  175. package/dist/templates/ssr/src/pages/example.tsx +113 -0
  176. package/dist/templates/ssr/src/pages/home.tsx +56 -0
  177. package/dist/templates/ssr/src/resources/user.ts +15 -0
  178. package/dist/templates/ssr/src/routes.tsx +13 -0
  179. package/dist/templates/ssr/src/styles.css +148 -0
  180. package/dist/templates/ssr/src/vite-server.d.ts +7 -0
  181. package/dist/templates/ssr/tests/app.test.tsx +24 -0
  182. package/dist/templates/ssr/tests/components/counter.test.tsx +13 -0
  183. package/dist/templates/ssr/tests/resources.test.ts +11 -0
  184. package/dist/templates/ssr/tsconfig.json +22 -0
  185. package/dist/templates/ssr/tsconfig.node.json +10 -0
  186. package/dist/templates/ssr/tsconfig.server.json +15 -0
  187. package/dist/templates/ssr/vite.config.ts +25 -0
  188. package/dist/templates/ssr/vitest.config.ts +13 -0
  189. package/dist/templates/startkit/AGENTS.md +77 -0
  190. package/dist/templates/startkit/README.md +192 -0
  191. package/dist/templates/startkit/gitignore.template +16 -0
  192. package/dist/templates/startkit/index.html +13 -0
  193. package/dist/templates/startkit/package.json +35 -0
  194. package/dist/templates/startkit/src/components/app-header.tsx +93 -0
  195. package/dist/templates/startkit/src/components/app-sidebar.tsx +95 -0
  196. package/dist/templates/startkit/src/components/data-table.tsx +80 -0
  197. package/dist/templates/startkit/src/components/empty-state.tsx +13 -0
  198. package/dist/templates/startkit/src/components/page-header.tsx +23 -0
  199. package/dist/templates/startkit/src/components/stat-card.tsx +24 -0
  200. package/dist/templates/startkit/src/features/accounts/account-filters.tsx +61 -0
  201. package/dist/templates/startkit/src/features/accounts/account-table.tsx +79 -0
  202. package/dist/templates/startkit/src/lib/format.ts +31 -0
  203. package/dist/templates/startkit/src/lib/mock-data.ts +441 -0
  204. package/dist/templates/startkit/src/lib/routes.ts +116 -0
  205. package/dist/templates/startkit/src/main.tsx +12 -0
  206. package/dist/templates/startkit/src/pages/_layout.tsx +56 -0
  207. package/dist/templates/startkit/src/pages/auth/_layout.tsx +7 -0
  208. package/dist/templates/startkit/src/pages/auth/login.tsx +129 -0
  209. package/dist/templates/startkit/src/pages/home.tsx +83 -0
  210. package/dist/templates/startkit/src/pages/not-found.tsx +24 -0
  211. package/dist/templates/startkit/src/pages/workspace/_layout.tsx +17 -0
  212. package/dist/templates/startkit/src/pages/workspace/accounts/index.tsx +217 -0
  213. package/dist/templates/startkit/src/pages/workspace/dashboard.tsx +118 -0
  214. package/dist/templates/startkit/src/pages/workspace/settings.tsx +218 -0
  215. package/dist/templates/startkit/src/router.tsx +7 -0
  216. package/dist/templates/startkit/src/routes/auth-config.ts +38 -0
  217. package/dist/templates/startkit/src/routes/auth.ts +8 -0
  218. package/dist/templates/startkit/src/routes/index.ts +28 -0
  219. package/dist/templates/startkit/src/routes/public.ts +8 -0
  220. package/dist/templates/startkit/src/routes/workspace/accounts.ts +8 -0
  221. package/dist/templates/startkit/src/routes/workspace/index.ts +14 -0
  222. package/dist/templates/startkit/src/styles/components.css +396 -0
  223. package/dist/templates/startkit/src/styles/layout.css +192 -0
  224. package/dist/templates/startkit/src/styles/reset.css +38 -0
  225. package/dist/templates/startkit/src/styles/theme.css +76 -0
  226. package/dist/templates/startkit/src/styles/tokens.css +67 -0
  227. package/dist/templates/startkit/src/styles.css +7 -0
  228. package/dist/templates/startkit/src/toast.ts +55 -0
  229. package/dist/templates/startkit/src/utils/join-classes.ts +4 -0
  230. package/dist/templates/startkit/src/vite-env.d.ts +5 -0
  231. package/dist/templates/startkit/tests/app.test.tsx +32 -0
  232. package/dist/templates/startkit/tests/preferences.test.ts +43 -0
  233. package/dist/templates/startkit/tests/resources.test.ts +82 -0
  234. package/dist/templates/startkit/tsconfig.json +20 -0
  235. package/dist/templates/startkit/tsconfig.node.json +10 -0
  236. package/dist/templates/startkit/vite.config.ts +32 -0
  237. package/dist/templates/startkit/vitest.config.ts +13 -0
  238. package/dist/update-DyW1na5V.js +1140 -0
  239. package/dist/update-DyW1na5V.js.map +1 -0
  240. package/dist/update.js +3 -0
  241. package/package.json +84 -0
  242. package/skills/askr-accessibility/SKILL.md +68 -0
  243. package/skills/askr-accessibility/agents/openai.yaml +4 -0
  244. package/skills/askr-agent-execution/SKILL.md +85 -0
  245. package/skills/askr-agent-execution/agents/openai.yaml +4 -0
  246. package/skills/askr-agent-workflows/SKILL.md +57 -0
  247. package/skills/askr-agent-workflows/agents/openai.yaml +4 -0
  248. package/skills/askr-api-integration/SKILL.md +79 -0
  249. package/skills/askr-api-integration/agents/openai.yaml +4 -0
  250. package/skills/askr-app-builder/SKILL.md +99 -0
  251. package/skills/askr-app-builder/agents/openai.yaml +4 -0
  252. package/skills/askr-auth-access/SKILL.md +74 -0
  253. package/skills/askr-auth-access/agents/openai.yaml +4 -0
  254. package/skills/askr-cli-vite/SKILL.md +76 -0
  255. package/skills/askr-cli-vite/agents/openai.yaml +4 -0
  256. package/skills/askr-dashboard-charts/SKILL.md +82 -0
  257. package/skills/askr-dashboard-charts/agents/openai.yaml +4 -0
  258. package/skills/askr-design-system/SKILL.md +86 -0
  259. package/skills/askr-design-system/agents/openai.yaml +4 -0
  260. package/skills/askr-env-config/SKILL.md +74 -0
  261. package/skills/askr-env-config/agents/openai.yaml +4 -0
  262. package/skills/askr-error-loading-empty/SKILL.md +89 -0
  263. package/skills/askr-error-loading-empty/agents/openai.yaml +4 -0
  264. package/skills/askr-file-upload-artifacts/SKILL.md +77 -0
  265. package/skills/askr-file-upload-artifacts/agents/openai.yaml +4 -0
  266. package/skills/askr-forms-tables-crud/SKILL.md +98 -0
  267. package/skills/askr-forms-tables-crud/agents/openai.yaml +4 -0
  268. package/skills/askr-mental-model/SKILL.md +109 -0
  269. package/skills/askr-mental-model/agents/openai.yaml +4 -0
  270. package/skills/askr-migration-react/SKILL.md +81 -0
  271. package/skills/askr-migration-react/agents/openai.yaml +4 -0
  272. package/skills/askr-observability-debugging/SKILL.md +83 -0
  273. package/skills/askr-observability-debugging/agents/openai.yaml +4 -0
  274. package/skills/askr-project-structure/SKILL.md +79 -0
  275. package/skills/askr-project-structure/agents/openai.yaml +4 -0
  276. package/skills/askr-query-mutation/SKILL.md +115 -0
  277. package/skills/askr-query-mutation/agents/openai.yaml +4 -0
  278. package/skills/askr-realtime-streaming/SKILL.md +76 -0
  279. package/skills/askr-realtime-streaming/agents/openai.yaml +4 -0
  280. package/skills/askr-resources-data/SKILL.md +100 -0
  281. package/skills/askr-resources-data/agents/openai.yaml +4 -0
  282. package/skills/askr-routing-layouts/SKILL.md +107 -0
  283. package/skills/askr-routing-layouts/agents/openai.yaml +4 -0
  284. package/skills/askr-runtime-reactivity/SKILL.md +92 -0
  285. package/skills/askr-runtime-reactivity/agents/openai.yaml +4 -0
  286. package/skills/askr-ssr-ssg/SKILL.md +76 -0
  287. package/skills/askr-ssr-ssg/agents/openai.yaml +4 -0
  288. package/skills/askr-testing-determinism/SKILL.md +75 -0
  289. package/skills/askr-testing-determinism/agents/openai.yaml +4 -0
  290. package/skills/askr-theming/SKILL.md +86 -0
  291. package/skills/askr-theming/agents/openai.yaml +4 -0
  292. package/skills/askr-ui-composition/SKILL.md +92 -0
  293. package/skills/askr-ui-composition/agents/openai.yaml +4 -0
  294. package/templates/full-stack/AGENTS.md +12 -0
  295. package/templates/full-stack/README.md +18 -0
  296. package/templates/full-stack/gitignore.template +4 -0
  297. package/templates/full-stack/index.html +14 -0
  298. package/templates/full-stack/package.json +37 -0
  299. package/templates/full-stack/server.ts +13 -0
  300. package/templates/full-stack/src/action-authorizations.ts +10 -0
  301. package/templates/full-stack/src/actions/create-message.ts +10 -0
  302. package/templates/full-stack/src/i18n.ts +8 -0
  303. package/templates/full-stack/src/main.tsx +12 -0
  304. package/templates/full-stack/src/pages/home.tsx +25 -0
  305. package/templates/full-stack/src/pages/layout.tsx +33 -0
  306. package/templates/full-stack/src/pages/not-found.tsx +4 -0
  307. package/templates/full-stack/src/routes.tsx +20 -0
  308. package/templates/full-stack/src/schemas.ts +11 -0
  309. package/templates/full-stack/src/server/action-registry.ts +12 -0
  310. package/templates/full-stack/src/server/actions/create-message.ts +14 -0
  311. package/templates/full-stack/src/server/app.ts +66 -0
  312. package/templates/full-stack/src/server/dependencies.ts +55 -0
  313. package/templates/full-stack/src/server/entry-server.ts +8 -0
  314. package/templates/full-stack/src/telemetry.ts +4 -0
  315. package/templates/full-stack/src/vite-server.d.ts +6 -0
  316. package/templates/full-stack/tests/actions/create-message.test.ts +13 -0
  317. package/templates/full-stack/tsconfig.json +16 -0
  318. package/templates/full-stack/vite.config.ts +11 -0
  319. package/templates/spa/AGENTS.md +60 -0
  320. package/templates/spa/README.md +96 -0
  321. package/templates/spa/gitignore.template +16 -0
  322. package/templates/spa/index.html +13 -0
  323. package/templates/spa/package.json +35 -0
  324. package/templates/spa/src/adapters/operations-client.ts +90 -0
  325. package/templates/spa/src/components/shared/metric-card.tsx +27 -0
  326. package/templates/spa/src/components/shared/status-badge.tsx +24 -0
  327. package/templates/spa/src/features/operations/operations.query.ts +9 -0
  328. package/templates/spa/src/main.tsx +10 -0
  329. package/templates/spa/src/pages/_layout.tsx +9 -0
  330. package/templates/spa/src/pages/_routes.tsx +27 -0
  331. package/templates/spa/src/pages/app/_layout.tsx +94 -0
  332. package/templates/spa/src/pages/app/_routes.tsx +10 -0
  333. package/templates/spa/src/pages/app/admin-home.tsx +152 -0
  334. package/templates/spa/src/pages/app/agent-runs.tsx +93 -0
  335. package/templates/spa/src/pages/app/settings.tsx +91 -0
  336. package/templates/spa/src/pages/auth/_layout.tsx +38 -0
  337. package/templates/spa/src/pages/auth/_routes.tsx +6 -0
  338. package/templates/spa/src/pages/auth/login.tsx +63 -0
  339. package/templates/spa/src/pages/not-found.tsx +22 -0
  340. package/templates/spa/src/pages/public/_layout.tsx +47 -0
  341. package/templates/spa/src/pages/public/_routes.tsx +6 -0
  342. package/templates/spa/src/pages/public/home.tsx +143 -0
  343. package/templates/spa/src/shared/format.ts +12 -0
  344. package/templates/spa/src/shared/navigation.ts +15 -0
  345. package/templates/spa/src/styles/components.css +49 -0
  346. package/templates/spa/src/styles/layout.css +192 -0
  347. package/templates/spa/src/styles/reset.css +44 -0
  348. package/templates/spa/src/styles/theme.css +57 -0
  349. package/templates/spa/src/styles/tokens.css +20 -0
  350. package/templates/spa/src/styles.css +7 -0
  351. package/templates/spa/src/styles.d.ts +1 -0
  352. package/templates/spa/tests/app.test.tsx +37 -0
  353. package/templates/spa/tests/components/shared.test.tsx +12 -0
  354. package/templates/spa/tests/resources.test.ts +22 -0
  355. package/templates/spa/tsconfig.json +20 -0
  356. package/templates/spa/tsconfig.node.json +10 -0
  357. package/templates/spa/vite.config.ts +24 -0
  358. package/templates/spa/vitest.config.ts +17 -0
  359. package/templates/ssg/AGENTS.md +55 -0
  360. package/templates/ssg/README.md +39 -0
  361. package/templates/ssg/gitignore.template +17 -0
  362. package/templates/ssg/index.html +13 -0
  363. package/templates/ssg/package.json +35 -0
  364. package/templates/ssg/src/app.tsx +14 -0
  365. package/templates/ssg/src/components/badge.tsx +3 -0
  366. package/templates/ssg/src/components/counter.tsx +30 -0
  367. package/templates/ssg/src/components/site-shell.tsx +111 -0
  368. package/templates/ssg/src/jsx.d.ts +23 -0
  369. package/templates/ssg/src/main.tsx +8 -0
  370. package/templates/ssg/src/pages/about.tsx +82 -0
  371. package/templates/ssg/src/pages/content.tsx +63 -0
  372. package/templates/ssg/src/pages/example.tsx +97 -0
  373. package/templates/ssg/src/pages/home.tsx +51 -0
  374. package/templates/ssg/src/resources/user.ts +15 -0
  375. package/templates/ssg/src/routes.tsx +15 -0
  376. package/templates/ssg/src/styles.css +89 -0
  377. package/templates/ssg/src/vite-env.d.ts +5 -0
  378. package/templates/ssg/ssg.config.ts +34 -0
  379. package/templates/ssg/tests/app.test.tsx +19 -0
  380. package/templates/ssg/tests/components/counter.test.tsx +18 -0
  381. package/templates/ssg/tests/resources.test.ts +11 -0
  382. package/templates/ssg/tests/ssg-config.test.ts +11 -0
  383. package/templates/ssg/tsconfig.json +20 -0
  384. package/templates/ssg/tsconfig.node.json +10 -0
  385. package/templates/ssg/vite.config.ts +24 -0
  386. package/templates/ssg/vitest.config.ts +17 -0
  387. package/templates/ssr/AGENTS.md +28 -0
  388. package/templates/ssr/README.md +38 -0
  389. package/templates/ssr/gitignore.template +16 -0
  390. package/templates/ssr/index.html +13 -0
  391. package/templates/ssr/package.json +34 -0
  392. package/templates/ssr/server.ts +16 -0
  393. package/templates/ssr/src/app.tsx +21 -0
  394. package/templates/ssr/src/components/counter.tsx +26 -0
  395. package/templates/ssr/src/entry-server.tsx +10 -0
  396. package/templates/ssr/src/main.tsx +11 -0
  397. package/templates/ssr/src/pages/about.tsx +75 -0
  398. package/templates/ssr/src/pages/example.tsx +113 -0
  399. package/templates/ssr/src/pages/home.tsx +56 -0
  400. package/templates/ssr/src/resources/user.ts +15 -0
  401. package/templates/ssr/src/routes.tsx +13 -0
  402. package/templates/ssr/src/styles.css +148 -0
  403. package/templates/ssr/src/vite-server.d.ts +7 -0
  404. package/templates/ssr/tests/app.test.tsx +24 -0
  405. package/templates/ssr/tests/components/counter.test.tsx +13 -0
  406. package/templates/ssr/tests/resources.test.ts +11 -0
  407. package/templates/ssr/tsconfig.json +22 -0
  408. package/templates/ssr/tsconfig.node.json +10 -0
  409. package/templates/ssr/tsconfig.server.json +15 -0
  410. package/templates/ssr/vite.config.ts +25 -0
  411. package/templates/ssr/vitest.config.ts +13 -0
  412. package/templates/startkit/AGENTS.md +77 -0
  413. package/templates/startkit/README.md +192 -0
  414. package/templates/startkit/gitignore.template +16 -0
  415. package/templates/startkit/index.html +13 -0
  416. package/templates/startkit/package.json +35 -0
  417. package/templates/startkit/src/components/app-header.tsx +93 -0
  418. package/templates/startkit/src/components/app-sidebar.tsx +95 -0
  419. package/templates/startkit/src/components/data-table.tsx +80 -0
  420. package/templates/startkit/src/components/empty-state.tsx +13 -0
  421. package/templates/startkit/src/components/page-header.tsx +23 -0
  422. package/templates/startkit/src/components/stat-card.tsx +24 -0
  423. package/templates/startkit/src/features/accounts/account-filters.tsx +61 -0
  424. package/templates/startkit/src/features/accounts/account-table.tsx +79 -0
  425. package/templates/startkit/src/lib/format.ts +31 -0
  426. package/templates/startkit/src/lib/mock-data.ts +441 -0
  427. package/templates/startkit/src/lib/routes.ts +116 -0
  428. package/templates/startkit/src/main.tsx +12 -0
  429. package/templates/startkit/src/pages/_layout.tsx +56 -0
  430. package/templates/startkit/src/pages/auth/_layout.tsx +7 -0
  431. package/templates/startkit/src/pages/auth/login.tsx +129 -0
  432. package/templates/startkit/src/pages/home.tsx +83 -0
  433. package/templates/startkit/src/pages/not-found.tsx +24 -0
  434. package/templates/startkit/src/pages/workspace/_layout.tsx +17 -0
  435. package/templates/startkit/src/pages/workspace/accounts/index.tsx +217 -0
  436. package/templates/startkit/src/pages/workspace/dashboard.tsx +118 -0
  437. package/templates/startkit/src/pages/workspace/settings.tsx +218 -0
  438. package/templates/startkit/src/router.tsx +7 -0
  439. package/templates/startkit/src/routes/auth-config.ts +38 -0
  440. package/templates/startkit/src/routes/auth.ts +8 -0
  441. package/templates/startkit/src/routes/index.ts +28 -0
  442. package/templates/startkit/src/routes/public.ts +8 -0
  443. package/templates/startkit/src/routes/workspace/accounts.ts +8 -0
  444. package/templates/startkit/src/routes/workspace/index.ts +14 -0
  445. package/templates/startkit/src/styles/components.css +396 -0
  446. package/templates/startkit/src/styles/layout.css +192 -0
  447. package/templates/startkit/src/styles/reset.css +38 -0
  448. package/templates/startkit/src/styles/theme.css +76 -0
  449. package/templates/startkit/src/styles/tokens.css +67 -0
  450. package/templates/startkit/src/styles.css +7 -0
  451. package/templates/startkit/src/toast.ts +55 -0
  452. package/templates/startkit/src/utils/join-classes.ts +4 -0
  453. package/templates/startkit/src/vite-env.d.ts +5 -0
  454. package/templates/startkit/tests/app.test.tsx +32 -0
  455. package/templates/startkit/tests/preferences.test.ts +43 -0
  456. package/templates/startkit/tests/resources.test.ts +82 -0
  457. package/templates/startkit/tsconfig.json +20 -0
  458. package/templates/startkit/tsconfig.node.json +10 -0
  459. package/templates/startkit/vite.config.ts +32 -0
  460. package/templates/startkit/vitest.config.ts +13 -0
@@ -0,0 +1,30 @@
1
+ import { state, derive } from '@askrjs/askr';
2
+ import { Button } from '@askrjs/ui';
3
+ import { Box, Stack } from '@askrjs/themes/components';
4
+ import Badge from './badge';
5
+
6
+ export default function Counter() {
7
+ const [count, setCount] = state(0);
8
+ const parity = derive(() => (count() % 2 === 0 ? 'even' : 'odd'));
9
+
10
+ return (
11
+ <Box class="card counter">
12
+ <Stack gap="3">
13
+ <h2>Hydration check</h2>
14
+ <p class="text-muted">
15
+ This counter should still feel live after static generation.
16
+ </p>
17
+ <div class="counter-value">{count()}</div>
18
+ <div>
19
+ <Badge>{parity()}</Badge>
20
+ </div>
21
+ <div class="counter-controls">
22
+ <Button onPress={() => setCount((c) => Math.max(0, c - 1))}>
23
+ - Decrement
24
+ </Button>
25
+ <Button onPress={() => setCount((c) => c + 1)}>+ Increment</Button>
26
+ </div>
27
+ </Stack>
28
+ </Box>
29
+ );
30
+ }
@@ -0,0 +1,111 @@
1
+ import { Link } from '@askrjs/askr/router';
2
+ import { Header } from '@askrjs/themes/components';
3
+ import {
4
+ Block,
5
+ Box,
6
+ Container,
7
+ Section,
8
+ Stack,
9
+ } from '@askrjs/themes/components';
10
+ import { Nav, NavLink } from '@askrjs/themes/components';
11
+ import Badge from './badge';
12
+
13
+ export const navItems = [
14
+ { href: '/', label: 'Home' },
15
+ { href: '/workflow', label: 'Workflow' },
16
+ { href: '/content', label: 'Content' },
17
+ { href: '/preview', label: 'Preview' },
18
+ ] as const;
19
+
20
+ export function SiteHeader() {
21
+ return (
22
+ <Header position="sticky">
23
+ <Container size="xl" paddingY="md">
24
+ <Box class="navbar-shell">
25
+ <Box class="navbar-brand">
26
+ <Link class="brand" href="/">
27
+ <strong>{'{{appName}}'}</strong>
28
+ <span>Static site generation sample</span>
29
+ </Link>
30
+ </Box>
31
+
32
+ <Nav
33
+ as="div"
34
+ aria-label="Primary navigation"
35
+ class="navbar-group"
36
+ data-align="end"
37
+ >
38
+ {navItems.map((item) => (
39
+ <NavLink href={item.href}>{item.label}</NavLink>
40
+ ))}
41
+ </Nav>
42
+ </Box>
43
+ </Container>
44
+ </Header>
45
+ );
46
+ }
47
+
48
+ export function PageFrame({ children }: { children?: unknown }) {
49
+ return (
50
+ <Container size="xl" paddingY="2xl">
51
+ <Stack gap="8">{children}</Stack>
52
+ </Container>
53
+ );
54
+ }
55
+
56
+ export function SectionHeader({
57
+ eyebrow,
58
+ title,
59
+ description,
60
+ actions,
61
+ }: {
62
+ eyebrow: string;
63
+ title: string;
64
+ description: string;
65
+ actions?: unknown;
66
+ }) {
67
+ return (
68
+ <Section class="section-header" paddingY="xl">
69
+ <Block gap="md">
70
+ <Stack gap="3" class="section-header-copy">
71
+ <Badge>{eyebrow}</Badge>
72
+ <h1>{title}</h1>
73
+ <p class="section-header-description">{description}</p>
74
+ </Stack>
75
+
76
+ {actions ?? null}
77
+ </Block>
78
+ </Section>
79
+ );
80
+ }
81
+
82
+ export function CardGrid({ children }: { children?: unknown }) {
83
+ return <Box class="card-grid">{children}</Box>;
84
+ }
85
+
86
+ export function Card({
87
+ eyebrow,
88
+ title,
89
+ description,
90
+ children,
91
+ }: {
92
+ eyebrow?: string;
93
+ title: string;
94
+ description?: string;
95
+ children?: unknown;
96
+ }) {
97
+ return (
98
+ <Box class="card">
99
+ <Stack gap="3">
100
+ {eyebrow ? <Badge>{eyebrow}</Badge> : null}
101
+ <h2>{title}</h2>
102
+ {description ? <p>{description}</p> : null}
103
+ {children}
104
+ </Stack>
105
+ </Box>
106
+ );
107
+ }
108
+
109
+ export function ActionRow({ children }: { children?: unknown }) {
110
+ return <Box class="action-row">{children}</Box>;
111
+ }
@@ -0,0 +1,23 @@
1
+ import type { JSXElement } from '@askrjs/askr/foundations';
2
+
3
+ declare global {
4
+ namespace JSX {
5
+ interface Element extends JSXElement {
6
+ readonly __askrSsgJsxElementBrand?: never;
7
+ }
8
+
9
+ interface IntrinsicElements {
10
+ [elem: string]: Record<string, unknown>;
11
+ }
12
+
13
+ interface ElementAttributesProperty {
14
+ props: Record<string, unknown>;
15
+ }
16
+
17
+ interface ElementChildrenAttribute {
18
+ children: unknown;
19
+ }
20
+ }
21
+ }
22
+
23
+ export {};
@@ -0,0 +1,8 @@
1
+ import './styles.css';
2
+ import { createSPA } from '@askrjs/askr/boot';
3
+ import { pageRegistry } from './routes';
4
+
5
+ await createSPA({
6
+ root: document.getElementById('app')!,
7
+ registry: pageRegistry,
8
+ });
@@ -0,0 +1,82 @@
1
+ import { Link } from '@askrjs/askr/router';
2
+ import { Button } from '@askrjs/ui';
3
+ import {
4
+ ActionRow,
5
+ Card,
6
+ CardGrid,
7
+ SectionHeader,
8
+ } from '../components/site-shell';
9
+
10
+ const steps = [
11
+ {
12
+ number: '01',
13
+ title: 'Start the dev server',
14
+ command: 'npm run dev',
15
+ body: 'Vite runs the sample as a SPA while you edit, so page changes feel immediate.',
16
+ },
17
+ {
18
+ number: '02',
19
+ title: 'Edit a page',
20
+ command: 'src/pages/*.tsx',
21
+ body: 'Each page is a plain component. Keep view code, layout, and copy close together.',
22
+ },
23
+ {
24
+ number: '03',
25
+ title: 'Keep the route map explicit',
26
+ command: 'ssg.config.ts',
27
+ body: 'The static route list mirrors the pages the sample site actually ships.',
28
+ },
29
+ {
30
+ number: '04',
31
+ title: 'Generate and preview',
32
+ command: 'npm run generate && npm run preview',
33
+ body: 'Render the site to dist/static and verify the production output before you ship it.',
34
+ },
35
+ ];
36
+
37
+ export default function Workflow() {
38
+ return (
39
+ <>
40
+ <SectionHeader
41
+ eyebrow="Workflow"
42
+ title="The authoring loop stays short."
43
+ description="This sample keeps the daily work obvious: edit a page, update the route map, generate static HTML, and preview the result."
44
+ actions={
45
+ <ActionRow>
46
+ <Button asChild>
47
+ <Link href="/content">See the route map</Link>
48
+ </Button>
49
+ <Button asChild>
50
+ <Link href="/preview">Open the preview</Link>
51
+ </Button>
52
+ </ActionRow>
53
+ }
54
+ />
55
+
56
+ <CardGrid>
57
+ {steps.map((step) => (
58
+ <Card
59
+ eyebrow={step.number}
60
+ title={step.title}
61
+ description={step.body}
62
+ >
63
+ <p>
64
+ <code>{step.command}</code>
65
+ </p>
66
+ </Card>
67
+ ))}
68
+ </CardGrid>
69
+
70
+ <Card
71
+ title="Why this feels good"
72
+ description="There is no hidden router magic. The generated site and the dev server read the same route definitions, so the UI you edit is the UI you ship."
73
+ >
74
+ <p>
75
+ <code>npm run dev</code>, <code>npm run generate</code>, and{' '}
76
+ <code>npm run preview</code> are the only commands you need to
77
+ remember.
78
+ </p>
79
+ </Card>
80
+ </>
81
+ );
82
+ }
@@ -0,0 +1,63 @@
1
+ import { Link } from '@askrjs/askr/router';
2
+ import { Button } from '@askrjs/ui';
3
+ import {
4
+ ActionRow,
5
+ Card,
6
+ CardGrid,
7
+ SectionHeader,
8
+ } from '../components/site-shell';
9
+
10
+ const routeMap = [
11
+ {
12
+ path: '/',
13
+ title: 'Home',
14
+ note: 'Start here and link out to the rest of the sample.',
15
+ },
16
+ {
17
+ path: '/workflow',
18
+ title: 'Workflow',
19
+ note: 'Show the edit, generate, and preview loop.',
20
+ },
21
+ {
22
+ path: '/content',
23
+ title: 'Content',
24
+ note: 'Keep the route list visible and easy to extend.',
25
+ },
26
+ {
27
+ path: '/preview',
28
+ title: 'Preview',
29
+ note: 'Keep one interactive page to confirm hydration.',
30
+ },
31
+ ] as const;
32
+
33
+ export default function Content() {
34
+ return (
35
+ <>
36
+ <SectionHeader
37
+ eyebrow="Content"
38
+ title="Four routes, one clear source of truth."
39
+ description="Keep the starter small and predictable. Add more routes when the app actually needs them."
40
+ actions={
41
+ <ActionRow>
42
+ <Button asChild>
43
+ <Link href="/workflow">Read the workflow</Link>
44
+ </Button>
45
+ <Button asChild>
46
+ <Link href="/preview">Open the preview</Link>
47
+ </Button>
48
+ </ActionRow>
49
+ }
50
+ />
51
+
52
+ <CardGrid>
53
+ {routeMap.map((route) => (
54
+ <Card
55
+ eyebrow={route.path}
56
+ title={route.title}
57
+ description={route.note}
58
+ />
59
+ ))}
60
+ </CardGrid>
61
+ </>
62
+ );
63
+ }
@@ -0,0 +1,97 @@
1
+ import { state } from '@askrjs/askr';
2
+ import { Link } from '@askrjs/askr/router';
3
+ import { Button, Input } from '@askrjs/ui';
4
+ import Counter from '../components/counter';
5
+ import {
6
+ ActionRow,
7
+ Card,
8
+ CardGrid,
9
+ SectionHeader,
10
+ } from '../components/site-shell';
11
+
12
+ const sampleUsers: Record<
13
+ number,
14
+ { name: string; email: string; note: string }
15
+ > = {
16
+ 1: {
17
+ name: 'User 1',
18
+ email: 'user1@example.com',
19
+ note: 'Replace this with your own content or connect it to real data later.',
20
+ },
21
+ 2: {
22
+ name: 'User 2',
23
+ email: 'user2@example.com',
24
+ note: 'This stays simple on purpose so the starter remains easy to delete or extend.',
25
+ },
26
+ 3: {
27
+ name: 'User 3',
28
+ email: 'user3@example.com',
29
+ note: 'Interactive state still hydrates after static generation without adding async complexity.',
30
+ },
31
+ };
32
+
33
+ export default function Preview() {
34
+ const [userId, setUserId] = state(1);
35
+ const user = sampleUsers[userId()] ?? {
36
+ name: `User ${userId()}`,
37
+ email: `user${userId()}@example.com`,
38
+ note: 'Use this route as a safe place to try small interactive changes.',
39
+ };
40
+
41
+ return (
42
+ <>
43
+ <SectionHeader
44
+ eyebrow="Preview"
45
+ title="Interactive parts still work after static generation."
46
+ description="Keep one page interactive so you can verify hydration, state, and resource loading without turning the template into an app."
47
+ actions={
48
+ <ActionRow>
49
+ <Button asChild>
50
+ <Link href="/workflow">Read the workflow</Link>
51
+ </Button>
52
+ <Button asChild>
53
+ <Link href="/content">Review the routes</Link>
54
+ </Button>
55
+ </ActionRow>
56
+ }
57
+ />
58
+
59
+ <CardGrid>
60
+ <Counter />
61
+
62
+ <Card
63
+ eyebrow="Interactive state"
64
+ title="State still hydrates after generation"
65
+ description="Change the user id to prove the generated page still responds in the browser."
66
+ >
67
+ <div class="preview-controls">
68
+ <Input
69
+ type="number"
70
+ min="1"
71
+ step="1"
72
+ value={String(userId())}
73
+ onInput={(event: Event) => {
74
+ const nextValue = Number.parseInt(
75
+ (event.target as HTMLInputElement).value,
76
+ 10
77
+ );
78
+
79
+ setUserId(Number.isNaN(nextValue) ? 1 : Math.max(1, nextValue));
80
+ }}
81
+ />
82
+ </div>
83
+
84
+ <div class="resource-panel">
85
+ <div class="resource-status">
86
+ <span class="badge">Ready</span>
87
+ <span>Hydrated preview</span>
88
+ </div>
89
+ <h3>{user.name}</h3>
90
+ <p>{user.email}</p>
91
+ <p class="text-muted">{user.note}</p>
92
+ </div>
93
+ </Card>
94
+ </CardGrid>
95
+ </>
96
+ );
97
+ }
@@ -0,0 +1,51 @@
1
+ import { Link } from '@askrjs/askr/router';
2
+ import { Button } from '@askrjs/ui';
3
+ import {
4
+ ActionRow,
5
+ Card,
6
+ CardGrid,
7
+ SectionHeader,
8
+ } from '../components/site-shell';
9
+
10
+ const highlights = [
11
+ {
12
+ title: 'Fast feedback',
13
+ body: 'Run npm run dev and edit a page to stay in a SPA-style authoring loop.',
14
+ },
15
+ {
16
+ title: 'Deterministic output',
17
+ body: 'Keep one explicit route registry in src/routes.tsx so dev and generated output cannot drift.',
18
+ },
19
+ {
20
+ title: 'Hydrated preview',
21
+ body: 'Keep one interactive route so you can verify static output and browser behavior together.',
22
+ },
23
+ ];
24
+
25
+ export default function Home() {
26
+ return (
27
+ <>
28
+ <SectionHeader
29
+ eyebrow="Static site generation"
30
+ title="Build a multi-page site, then ship it as plain HTML."
31
+ description="This sample keeps the loop small: author routes, preview in the SPA dev server, generate static files, and inspect the output."
32
+ actions={
33
+ <ActionRow>
34
+ <Button asChild>
35
+ <Link href="/workflow">See the workflow</Link>
36
+ </Button>
37
+ <Button asChild>
38
+ <Link href="/preview">Open the preview</Link>
39
+ </Button>
40
+ </ActionRow>
41
+ }
42
+ />
43
+
44
+ <CardGrid>
45
+ {highlights.map((highlight) => (
46
+ <Card title={highlight.title} description={highlight.body} />
47
+ ))}
48
+ </CardGrid>
49
+ </>
50
+ );
51
+ }
@@ -0,0 +1,15 @@
1
+ import { resource } from '@askrjs/askr/resources';
2
+
3
+ export function fetchUser(id: number) {
4
+ return resource(
5
+ async ({ signal }: { signal: AbortSignal }) => {
6
+ // Simulate API call
7
+ await new Promise((resolve) => setTimeout(resolve, 100));
8
+ if (signal.aborted) {
9
+ throw new DOMException('Request aborted', 'AbortError');
10
+ }
11
+ return { id, name: `User ${id}`, email: `user${id}@example.com` };
12
+ },
13
+ [id]
14
+ );
15
+ }
@@ -0,0 +1,15 @@
1
+ import { createRouteRegistry, group, route } from '@askrjs/askr/router';
2
+ import AppLayout from './app';
3
+ import Home from './pages/home';
4
+ import Workflow from './pages/about';
5
+ import Content from './pages/content';
6
+ import Preview from './pages/example';
7
+
8
+ export const pageRegistry = createRouteRegistry(() => {
9
+ group({ layout: AppLayout }, () => {
10
+ route('/', Home);
11
+ route('/workflow', Workflow);
12
+ route('/content', Content);
13
+ route('/preview', Preview);
14
+ });
15
+ });
@@ -0,0 +1,89 @@
1
+ @import '@askrjs/themes/default';
2
+
3
+ * {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ :root {
8
+ color-scheme: light;
9
+ }
10
+
11
+ body {
12
+ margin: 0;
13
+ min-height: 100vh;
14
+ color: var(--ak-color-fg);
15
+ font-family: var(--ak-font-family);
16
+ line-height: 1.5;
17
+ background: var(--ak-color-bg);
18
+ }
19
+
20
+ a {
21
+ color: inherit;
22
+ text-decoration: none;
23
+ }
24
+
25
+ .site-shell {
26
+ min-height: 100vh;
27
+ }
28
+
29
+ .site-main {
30
+ padding-block: clamp(2rem, 4vw, 4rem);
31
+ }
32
+
33
+ .brand {
34
+ display: grid;
35
+ gap: 0.15rem;
36
+ }
37
+
38
+ .brand strong {
39
+ font-size: 1.05rem;
40
+ letter-spacing: 0.02em;
41
+ }
42
+
43
+ .brand span {
44
+ color: var(--ak-color-text-muted);
45
+ font-size: var(--ak-font-size-sm);
46
+ }
47
+
48
+ .action-row {
49
+ display: flex;
50
+ flex-wrap: wrap;
51
+ gap: var(--ak-space-sm);
52
+ }
53
+
54
+ .card-grid {
55
+ display: grid;
56
+ gap: var(--ak-space-lg);
57
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
58
+ }
59
+
60
+ .text-muted {
61
+ color: var(--ak-color-text-muted);
62
+ }
63
+
64
+ code {
65
+ padding: 0.15em 0.4em;
66
+ border-radius: 0.4rem;
67
+ background: var(--ak-color-surface-muted);
68
+ font-size: 0.9em;
69
+ }
70
+
71
+ .counter-value {
72
+ font-size: clamp(2rem, 4vw, 3.25rem);
73
+ font-weight: var(--ak-font-weight-bold);
74
+ letter-spacing: -0.05em;
75
+ }
76
+
77
+ .counter-controls,
78
+ .preview-controls,
79
+ .resource-status {
80
+ display: flex;
81
+ flex-wrap: wrap;
82
+ gap: var(--ak-space-sm);
83
+ align-items: center;
84
+ }
85
+
86
+ .resource-panel {
87
+ display: grid;
88
+ gap: var(--ak-space-sm);
89
+ }
@@ -0,0 +1,5 @@
1
+ declare module '*.css' {
2
+ const css: string;
3
+
4
+ export default css;
5
+ }
@@ -0,0 +1,34 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import type { DocumentRenderArgs } from '@askrjs/askr/ssg';
4
+ import { pageRegistry } from './src/routes';
5
+
6
+ export const outputDir = './dist';
7
+
8
+ let clientTemplate: string | undefined;
9
+
10
+ function renderDocument({ appHtml }: DocumentRenderArgs) {
11
+ clientTemplate ??= readFileSync(
12
+ resolve(process.cwd(), '.askr/client/index.html'),
13
+ 'utf8'
14
+ );
15
+
16
+ const appRoot = /<div([^>]*\bid=["']app["'][^>]*)>\s*<\/div>/i;
17
+ if (!appRoot.test(clientTemplate)) {
18
+ throw new Error('Built client template must contain an empty #app root.');
19
+ }
20
+
21
+ return clientTemplate.replace(appRoot, `<div$1>${appHtml}</div>`);
22
+ }
23
+
24
+ export const staticConfig = {
25
+ registry: pageRegistry,
26
+ outputDir,
27
+ document: renderDocument,
28
+ assets: [
29
+ {
30
+ from: resolve(process.cwd(), '.askr/client/assets'),
31
+ to: 'assets',
32
+ },
33
+ ],
34
+ };
@@ -0,0 +1,19 @@
1
+ import { describe, expect, it } from 'vite-plus/test';
2
+ import { navItems } from '../src/app';
3
+
4
+ describe('App shell', () => {
5
+ it('exposes the workflow-focused navigation order', () => {
6
+ expect(navItems.map((item) => item.label)).toEqual([
7
+ 'Home',
8
+ 'Workflow',
9
+ 'Content',
10
+ 'Preview',
11
+ ]);
12
+ expect(navItems.map((item) => item.href)).toEqual([
13
+ '/',
14
+ '/workflow',
15
+ '/content',
16
+ '/preview',
17
+ ]);
18
+ });
19
+ });
@@ -0,0 +1,18 @@
1
+ import { describe, it, expect } from 'vite-plus/test';
2
+ import { renderToString } from '@askrjs/askr/ssr';
3
+ import Counter from '../../src/components/counter';
4
+
5
+ describe('Counter', () => {
6
+ it('renders the initial hydration check view', () => {
7
+ const html = renderToString(() => <Counter />);
8
+
9
+ expect(html).toContain('Hydration check');
10
+ expect(html).toContain(
11
+ 'This counter should still feel live after static generation.'
12
+ );
13
+ expect(html).toContain('0');
14
+ expect(html).toContain('even');
15
+ expect(html).toContain('- Decrement');
16
+ expect(html).toContain('+ Increment');
17
+ });
18
+ });
@@ -0,0 +1,11 @@
1
+ import { describe, it, expect } from 'vite-plus/test';
2
+ import { fetchUser } from '../src/resources/user';
3
+
4
+ describe('Resources', () => {
5
+ it('creates a resource for fetching user data', () => {
6
+ // Resources are called during component render
7
+ // Here we just verify the function is defined
8
+ expect(fetchUser).toBeDefined();
9
+ expect(typeof fetchUser).toBe('function');
10
+ });
11
+ });