@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,66 @@
1
+ import { createAuth } from '@askrjs/auth';
2
+ import { createServerApp } from '@askrjs/server';
3
+ import { createAskrPageHandler } from '@askrjs/server/askr';
4
+ import { csrf, rateLimit, requestId, securityHeaders } from '@askrjs/server/middleware';
5
+ import { createApi } from '@askrjs/server/openapi';
6
+ import { pageRegistry } from '../routes';
7
+ import { Message, MessageInput } from '../schemas';
8
+ import { telemetry } from '../telemetry';
9
+ import { createActions } from './action-registry';
10
+ import type { AppDependencies } from './dependencies';
11
+
12
+ export function createApp(deps: AppDependencies) {
13
+ const api = createApi<AppDependencies>({
14
+ info: { title: '{{appName}} API', version: '1.0.0' },
15
+ });
16
+ api.post('/api/messages', {
17
+ input: {
18
+ body: {
19
+ schema: MessageInput,
20
+ mediaTypes: ['application/json'],
21
+ },
22
+ },
23
+ documentation: { body: { required: true } },
24
+ async handler(ctx, input, dependencies) {
25
+ const message = { id: crypto.randomUUID(), value: input.body.value };
26
+ await dependencies.actions.record({ action: 'api.create-message', value: message.value });
27
+ return ctx.created(message);
28
+ },
29
+ })
30
+ .operationId('createMessage')
31
+ .summary('Create a message')
32
+ .tags('Messages')
33
+ .use(
34
+ csrf({ secret: process.env.CSRF_SECRET ?? 'development-only-secret' }),
35
+ rateLimit({ store: deps.rateLimits, limit: 30, windowMs: 60_000 }),
36
+ )
37
+ .created(Message)
38
+ .badRequest()
39
+ .unprocessableEntity()
40
+ .tooManyRequests();
41
+
42
+ const router = api.createRouter(deps);
43
+ router.post('/api/session', (ctx) => {
44
+ const response = ctx.redirect('/', 303);
45
+ return ctx.setCookie(response, 'askr-session', 'demo-session', {
46
+ httpOnly: true,
47
+ sameSite: 'lax',
48
+ secure: ctx.url.protocol === 'https:',
49
+ path: '/',
50
+ });
51
+ });
52
+ return createServerApp({
53
+ router,
54
+ auth: createAuth({
55
+ sessions: deps.sessions,
56
+ principals: deps.principals,
57
+ sessionCookie: 'askr-session',
58
+ }),
59
+ middleware: [requestId(), securityHeaders()],
60
+ telemetry,
61
+ fallback: createAskrPageHandler({
62
+ registry: pageRegistry,
63
+ actions: createActions(deps),
64
+ }),
65
+ });
66
+ }
@@ -0,0 +1,55 @@
1
+ export interface AppDependencies {
2
+ readonly sessions: {
3
+ get(id: string): Promise<{ id: string; subject: string } | null>;
4
+ };
5
+ readonly principals: {
6
+ get(subject: string): Promise<{
7
+ id: string;
8
+ subject: string;
9
+ permissions: readonly string[];
10
+ } | null>;
11
+ };
12
+ readonly actions: {
13
+ record(entry: { action: string; value: string }): Promise<void>;
14
+ };
15
+ readonly rateLimits: {
16
+ consume(key: string, limit: number, windowMs: number): Promise<{
17
+ allowed: boolean;
18
+ remaining: number;
19
+ reset: number;
20
+ }>;
21
+ };
22
+ }
23
+
24
+ export function createDependencies(): AppDependencies {
25
+ const counters = new Map<string, { count: number; reset: number }>();
26
+ return {
27
+ sessions: {
28
+ get: async (id) => id === 'demo-session'
29
+ ? { id, subject: 'demo-user' }
30
+ : null,
31
+ },
32
+ principals: {
33
+ get: async (subject) => subject === 'demo-user'
34
+ ? { id: subject, subject, permissions: ['messages:create'] }
35
+ : null,
36
+ },
37
+ actions: { record: async () => undefined },
38
+ rateLimits: {
39
+ async consume(key, limit, windowMs) {
40
+ const now = Date.now();
41
+ const current = counters.get(key);
42
+ const window = !current || current.reset <= now
43
+ ? { count: 0, reset: now + windowMs }
44
+ : current;
45
+ window.count += 1;
46
+ counters.set(key, window);
47
+ return {
48
+ allowed: window.count <= limit,
49
+ remaining: Math.max(0, limit - window.count),
50
+ reset: window.reset,
51
+ };
52
+ },
53
+ },
54
+ };
55
+ }
@@ -0,0 +1,8 @@
1
+ import { createApp } from './app';
2
+ import { createDependencies } from './dependencies';
3
+
4
+ const app = createApp(createDependencies());
5
+
6
+ export { app };
7
+ export { telemetry } from '../telemetry';
8
+ export default app;
@@ -0,0 +1,4 @@
1
+ import { createTelemetry } from '@askrjs/otel';
2
+
3
+ export const telemetry = createTelemetry();
4
+
@@ -0,0 +1,6 @@
1
+ declare module 'virtual:askr-server' {
2
+ import type { ServerApp } from '@askrjs/server';
3
+ const app: ServerApp;
4
+ export default app;
5
+ }
6
+
@@ -0,0 +1,13 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { createMessageAction } from '../../src/actions/create-message';
3
+
4
+ describe('create message action', () => {
5
+ it('should reject an empty message given declared input validation', () => {
6
+ expect(createMessageAction.input.safeParse({ value: '' }).success).toBe(false);
7
+ });
8
+
9
+ it('should accept a message given valid input', () => {
10
+ expect(createMessageAction.input.safeParse({ value: 'hello' }).success).toBe(true);
11
+ });
12
+ });
13
+
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+ "noEmit": true,
10
+ "jsx": "preserve",
11
+ "jsxImportSource": "@askrjs/askr",
12
+ "types": ["vite/client", "node"]
13
+ },
14
+ "include": ["src", "tests", "server.ts", "vite.config.ts"]
15
+ }
16
+
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'vite-plus';
2
+ import { askr } from '@askrjs/vite';
3
+ import { askrServer } from '@askrjs/vite/server';
4
+
5
+ export default defineConfig({
6
+ plugins: [askr(), askrServer({ entry: './src/server/entry-server.ts' })],
7
+ lint: { ignorePatterns: ['dist/**', 'node_modules/**', 'coverage/**'] },
8
+ server: { port: 5173, open: true },
9
+ build: { manifest: true, sourcemap: true },
10
+ });
11
+
@@ -0,0 +1,60 @@
1
+ # {{appName}}
2
+
3
+ Client-side SPA built with Askr, askr-ui, askr-themes, and askr-charts.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ npm run dev # Vite dev server with HMR (port 5173)
9
+ npm run build # Production build to dist/
10
+ npm run preview # Serve production build locally
11
+ npm test # Vitest (jsdom)
12
+ npm run typecheck # tsc --noEmit
13
+ npm run lint # ESLint
14
+ npm run fmt # Prettier
15
+ ```
16
+
17
+ ## Architecture
18
+
19
+ - **Routing:** `src/main.tsx` imports `src/pages/_routes.tsx`, then boots `createSPA()` with the route manifest. Route branches live under `src/pages/public`, `src/pages/auth`, and `src/pages/app`.
20
+ - **Layouts:** `_layout.tsx` files own shells. The root layout owns `ThemeScope`; public layouts own landing chrome, auth layouts own sign-in chrome, and app layouts own authenticated sidebar chrome.
21
+ - **UI:** Prefer the `@askrjs/themes/components` catalog before writing local components. Use app-local components only for product concepts such as `MetricCard` and `StatusBadge`; keep charts in `@askrjs/charts`.
22
+ - **State:** `const [value, setValue] = state(initial)`. Read with `value()`, update with `setValue(...)`. Use `derive()` for computed values and `resource()` for async data.
23
+ - **Data:** Route/container components own resources; `src/features` owns product workflows; `src/adapters` owns API clients, transports, abort handling, and generated clients.
24
+ - **Consistency:** Event-sourced screens should expose pending writes, projection lag, stale data, retries, and manual refresh instead of hiding everything behind one loading state.
25
+ - **Styling:** Keep `src/styles.css` thin. Customize theme values in `src/styles/tokens.css`, global defaults in `src/styles/theme.css`, shell structure in `src/styles/layout.css`, and component classes in `src/styles/components.css`.
26
+ - **Charts:** Import chart components from `@askrjs/charts/components`; chart CSS is loaded from `@askrjs/charts/default`.
27
+ - **Vite plugin:** `askr()` from `@askrjs/vite` handles JSX transform. Do not add manual esbuild JSX config.
28
+
29
+ ## File Structure
30
+
31
+ ```
32
+ src/
33
+ main.tsx
34
+ pages/
35
+ _routes.tsx
36
+ _layout.tsx
37
+ public/
38
+ auth/
39
+ app/
40
+ components/shared/
41
+ features/
42
+ adapters/
43
+ shared/
44
+ styles/
45
+ reset.css
46
+ tokens.css
47
+ theme.css
48
+ layout.css
49
+ components.css
50
+ tests/
51
+ ```
52
+
53
+ ## Conventions
54
+
55
+ - Keep routes thin and route-first.
56
+ - Keep shell chrome in layouts, not leaf pages.
57
+ - Keep business logic out of `src/pages`.
58
+ - Use `Link` and `navigate` from `@askrjs/askr/router`.
59
+ - Use headless `@askrjs/ui/*` for behavior primitives and `@askrjs/themes/*` for composed visual surfaces.
60
+ - Avoid hardcoded color systems, custom component catalogs, and React habits like effect-driven data loading.
@@ -0,0 +1,96 @@
1
+ # {{appName}} - SPA Template
2
+
3
+ A route-first Askr SPA built with `@askrjs/askr`, `@askrjs/ui`, `@askrjs/themes`, and `@askrjs/charts`.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npm install
9
+ npm run dev # Start dev server at http://localhost:5173
10
+ npm run build # Build for production
11
+ npm run preview # Preview production build
12
+ npm test # Run tests with Vitest
13
+ ```
14
+
15
+ ## Project Structure
16
+
17
+ ```
18
+ src/
19
+ |-- main.tsx # SPA boot and route manifest
20
+ |-- pages/
21
+ | |-- _routes.tsx # Top-level route branches
22
+ | |-- _layout.tsx # Theme provider and app root
23
+ | |-- public/ # Guest-facing landing pages and shell
24
+ | |-- auth/ # Sign-in routes and shell
25
+ | `-- app/ # Authenticated branch routes and shell
26
+ |-- components/shared/ # App-local wrappers around theme primitives
27
+ |-- features/operations/ # Product workflow queries and mutations
28
+ |-- adapters/ # API clients and transport adapters
29
+ |-- shared/ # Cross-cutting helpers and navigation data
30
+ `-- styles/ # reset.css, tokens.css, theme.css, layout.css, components.css
31
+ ```
32
+
33
+ ## Core Patterns
34
+
35
+ Routes live in `src/pages`, shells live in `_layout.tsx`, reusable UI lives in
36
+ `src/components/shared`, business workflows live in `src/features`, and adapter
37
+ code lives in `src/adapters`.
38
+
39
+ ```tsx
40
+ // src/pages/_routes.tsx
41
+ import { fallback, group, registerRoutes } from '@askrjs/askr/router';
42
+ import RootLayout from './_layout';
43
+ import NotFoundPage from './not-found';
44
+ import AuthLayout from './auth/_layout';
45
+ import { registerAuthRoutes } from './auth/_routes';
46
+ import AppLayout from './app/_layout';
47
+ import { registerAppRoutes } from './app/_routes';
48
+ import PublicLayout from './public/_layout';
49
+ import { registerPublicRoutes } from './public/_routes';
50
+
51
+ registerRoutes(() => {
52
+ group({ layout: RootLayout }, () => {
53
+ group({ layout: PublicLayout }, () => {
54
+ registerPublicRoutes();
55
+ });
56
+ group({ layout: AuthLayout }, () => {
57
+ registerAuthRoutes();
58
+ });
59
+ group({ layout: AppLayout }, () => {
60
+ registerAppRoutes();
61
+ });
62
+ fallback(NotFoundPage);
63
+ });
64
+ });
65
+ ```
66
+
67
+ The template uses the `@askrjs/themes/components` catalog for styled UI
68
+ composition and keeps charts in `@askrjs/charts`. Add app-local components only
69
+ when they compose those primitives into a product concept. Start with
70
+ `src/styles/tokens.css` for theme knobs, then tune `theme.css`, `layout.css`,
71
+ and `components.css`.
72
+
73
+ Async reads are owned by route or container components with `resource()` and
74
+ delegated through feature/adapters:
75
+
76
+ ```tsx
77
+ const operations = resource(({ signal }) => loadOperations({ signal }), []);
78
+ ```
79
+
80
+ Cancellation belongs in adapters, loading/error/value states stay visible in the
81
+ route, and event-sourced consistency states should be modeled explicitly.
82
+
83
+ ## What This Template Includes
84
+
85
+ - Public, auth, and authenticated app branches with separate layout shells
86
+ - Theme provider, header/nav/sidebar, cards, badges, buttons, empty states, and layout primitives
87
+ - A dashboard with async loading, charts, projection lag, and explicit refresh
88
+ - Feature and adapter boundaries for data ownership
89
+ - Tests that protect the route-first structure and cancellation behavior
90
+
91
+ ## Next Steps
92
+
93
+ 1. Replace the mock operations adapter with your generated API client.
94
+ 2. Tune `src/styles/tokens.css` and `src/styles/theme.css` to match your brand.
95
+ 3. Add route metadata for real auth and loader policies.
96
+ 4. Keep new screens route-first and compose solved UI through `@askrjs/themes`.
@@ -0,0 +1,16 @@
1
+ node_modules/
2
+ dist/
3
+ build/
4
+ .env.local
5
+ .env.*.local
6
+ npm-debug.log*
7
+ yarn-debug.log*
8
+ yarn-error.log*
9
+ pnpm-debug.log*
10
+ .DS_Store
11
+ Thumbs.db
12
+ .vscode/
13
+ .idea/
14
+ *.swp
15
+ *.swo
16
+ *~
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>{{appName}}</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "{{appName}}",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "clean": "npx rimraf node_modules dist",
7
+ "dev": "vp dev",
8
+ "build": "vp build",
9
+ "preview": "vp preview",
10
+ "test": "vp test run",
11
+ "typecheck": "tsc --noEmit",
12
+ "lint": "vp lint .",
13
+ "lint:fix": "npm run lint -- --fix",
14
+ "fmt": "vp fmt .",
15
+ "check": "npm run lint && npm run typecheck && npm test && npm run build"
16
+ },
17
+ "dependencies": {
18
+ "@askrjs/askr": ">=0.0.53 <0.1.0",
19
+ "@askrjs/charts": ">=0.0.3 <0.1.0",
20
+ "@askrjs/logos": ">=0.0.3 <0.1.0",
21
+ "@askrjs/lucide": ">=0.0.3 <0.1.0",
22
+ "@askrjs/themes": ">=0.0.12 <0.1.0",
23
+ "@askrjs/ui": ">=0.0.13 <0.1.0"
24
+ },
25
+ "devDependencies": {
26
+ "@askrjs/vite": ">=0.0.6 <0.1.0",
27
+ "@types/node": "^26.0.0",
28
+ "jsdom": "^29.1.1",
29
+ "typescript": "^6.0.3",
30
+ "vite-plus": "^0.2.4"
31
+ },
32
+ "engines": {
33
+ "node": "^20.19.0 || >=22.12.0"
34
+ }
35
+ }
@@ -0,0 +1,90 @@
1
+ import type { RunStatus } from '../components/shared/status-badge';
2
+
3
+ export type OperationRun = {
4
+ id: string;
5
+ title: string;
6
+ status: RunStatus;
7
+ owner: string;
8
+ updatedAt: string;
9
+ };
10
+
11
+ export type OperationsSnapshot = {
12
+ version: number;
13
+ consistency: 'fresh' | 'pending-write' | 'stale';
14
+ lastEventId: string;
15
+ metrics: Array<{ label: string; value: string; trend: string }>;
16
+ throughput: Array<{ label: string; value: number }>;
17
+ lag: Array<{ label: string; value: number }>;
18
+ runs: OperationRun[];
19
+ };
20
+
21
+ export async function getOperationsSnapshot({
22
+ signal,
23
+ }: {
24
+ signal: AbortSignal;
25
+ }): Promise<OperationsSnapshot> {
26
+ await delay(220, signal);
27
+
28
+ return {
29
+ version: 42,
30
+ consistency: 'fresh',
31
+ lastEventId: 'evt_18442',
32
+ metrics: [
33
+ { label: 'Active runs', value: '12', trend: '+3 today' },
34
+ { label: 'Pending approvals', value: '3', trend: '2 urgent' },
35
+ { label: 'Projection lag', value: '1.2s', trend: 'healthy' },
36
+ ],
37
+ throughput: [
38
+ { label: 'Research', value: 18 },
39
+ { label: 'Review', value: 11 },
40
+ { label: 'Deploy', value: 7 },
41
+ { label: 'Audit', value: 9 },
42
+ ],
43
+ lag: [
44
+ { label: '10:00', value: 4 },
45
+ { label: '10:10', value: 3 },
46
+ { label: '10:20', value: 2 },
47
+ { label: '10:30', value: 1 },
48
+ { label: '10:40', value: 2 },
49
+ { label: '10:50', value: 1 },
50
+ ],
51
+ runs: [
52
+ {
53
+ id: 'run_4812',
54
+ title: 'Summarize renewal risk',
55
+ status: 'running',
56
+ owner: 'Revenue ops',
57
+ updatedAt: '2026-05-22T09:52:00.000Z',
58
+ },
59
+ {
60
+ id: 'run_4811',
61
+ title: 'Approve workspace migration',
62
+ status: 'requires-action',
63
+ owner: 'Platform',
64
+ updatedAt: '2026-05-22T09:40:00.000Z',
65
+ },
66
+ {
67
+ id: 'run_4810',
68
+ title: 'Reconcile audit events',
69
+ status: 'succeeded',
70
+ owner: 'Security',
71
+ updatedAt: '2026-05-22T09:25:00.000Z',
72
+ },
73
+ ],
74
+ };
75
+ }
76
+
77
+ function delay(ms: number, signal: AbortSignal): Promise<void> {
78
+ return new Promise((resolve, reject) => {
79
+ const timeout = globalThis.setTimeout(resolve, ms);
80
+
81
+ signal.addEventListener(
82
+ 'abort',
83
+ () => {
84
+ globalThis.clearTimeout(timeout);
85
+ reject(new DOMException('Operation aborted', 'AbortError'));
86
+ },
87
+ { once: true }
88
+ );
89
+ });
90
+ }
@@ -0,0 +1,27 @@
1
+ import {
2
+ Card,
3
+ CardDescription,
4
+ CardHeader,
5
+ CardTitle,
6
+ } from '@askrjs/themes/components';
7
+ import { Inline } from '@askrjs/themes/components';
8
+
9
+ export type MetricCardProps = {
10
+ label: string;
11
+ value: string;
12
+ trend: string;
13
+ };
14
+
15
+ export default function MetricCard({ label, value, trend }: MetricCardProps) {
16
+ return (
17
+ <Card class="metric-card">
18
+ <CardHeader>
19
+ <Inline justify="between" align="center" gap="3">
20
+ <CardDescription>{label}</CardDescription>
21
+ <span class="metric-trend">{trend}</span>
22
+ </Inline>
23
+ <CardTitle>{value}</CardTitle>
24
+ </CardHeader>
25
+ </Card>
26
+ );
27
+ }
@@ -0,0 +1,24 @@
1
+ import { Badge } from '@askrjs/themes/components';
2
+
3
+ export type RunStatus =
4
+ | 'queued'
5
+ | 'running'
6
+ | 'requires-action'
7
+ | 'succeeded'
8
+ | 'failed';
9
+
10
+ export type StatusBadgeProps = {
11
+ status: RunStatus;
12
+ };
13
+
14
+ const labels: Record<RunStatus, string> = {
15
+ queued: 'queued',
16
+ running: 'running',
17
+ 'requires-action': 'needs review',
18
+ succeeded: 'succeeded',
19
+ failed: 'failed',
20
+ };
21
+
22
+ export default function StatusBadge({ status }: StatusBadgeProps) {
23
+ return <Badge data-status={status}>{labels[status]}</Badge>;
24
+ }
@@ -0,0 +1,9 @@
1
+ import { getOperationsSnapshot } from '../../adapters/operations-client';
2
+
3
+ export function loadOperations({
4
+ signal = new AbortController().signal,
5
+ }: {
6
+ signal?: AbortSignal;
7
+ }) {
8
+ return getOperationsSnapshot({ signal });
9
+ }
@@ -0,0 +1,10 @@
1
+ import { createSPA } from '@askrjs/askr/boot';
2
+ import { getManifest } from '@askrjs/askr/router';
3
+
4
+ import './styles.css';
5
+ import './pages/_routes';
6
+
7
+ await createSPA({
8
+ root: document.getElementById('app')!,
9
+ manifest: getManifest(),
10
+ });
@@ -0,0 +1,9 @@
1
+ import { ThemeScope } from '@askrjs/themes/theme';
2
+
3
+ export default function RootLayout({ children }: { children?: unknown }) {
4
+ return (
5
+ <ThemeScope defaultTheme="tabby">
6
+ <div class="app-root">{children}</div>
7
+ </ThemeScope>
8
+ );
9
+ }
@@ -0,0 +1,27 @@
1
+ import { fallback, group, registerRoutes } from '@askrjs/askr/router';
2
+ import RootLayout from './_layout';
3
+ import AuthLayout from './auth/_layout';
4
+ import { registerAuthRoutes } from './auth/_routes';
5
+ import { registerAppRoutes } from './app/_routes';
6
+ import AppLayout from './app/_layout';
7
+ import NotFoundPage from './not-found';
8
+ import { registerPublicRoutes } from './public/_routes';
9
+ import PublicLayout from './public/_layout';
10
+
11
+ registerRoutes(() => {
12
+ group({ layout: RootLayout }, () => {
13
+ group({ layout: PublicLayout }, () => {
14
+ registerPublicRoutes();
15
+ });
16
+
17
+ group({ layout: AuthLayout }, () => {
18
+ registerAuthRoutes();
19
+ });
20
+
21
+ group({ layout: AppLayout }, () => {
22
+ registerAppRoutes();
23
+ });
24
+
25
+ fallback(NotFoundPage);
26
+ });
27
+ });