@askrjs/cli 0.0.3 → 0.0.4

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 (287) hide show
  1. package/README.md +37 -0
  2. package/dist/add.d.ts +16 -0
  3. package/dist/add.js +33 -29
  4. package/dist/cli.d.ts +5 -0
  5. package/dist/cli.js +0 -2
  6. package/dist/create.d.ts +5 -0
  7. package/dist/create.js +104 -26
  8. package/dist/directory-swap-DWoHtx7C.js +35 -0
  9. package/dist/discovery-Difb7Y4G.js +0 -2
  10. package/dist/generate.d.ts +5 -0
  11. package/dist/generate.js +77 -12
  12. package/dist/is-direct-execution-Cdlr-ZUl.js +0 -2
  13. package/dist/openapi.d.ts +25 -0
  14. package/dist/openapi.js +44 -12
  15. package/dist/planner-VAj7qlxr.js +0 -2
  16. package/dist/range-YUs9eimn.js +0 -2
  17. package/dist/registry-CyrRHRG5.js +0 -2
  18. package/dist/skills/askr-ssr-ssg/SKILL.md +3 -1
  19. package/dist/{skills-Bh0mEhIx.js → skills-B7CbWur9.js} +89 -26
  20. package/dist/skills.d.ts +18 -0
  21. package/dist/skills.js +1 -1
  22. package/dist/specification-DXnDOC-0.js +0 -2
  23. package/dist/ssg-config.d.ts +41 -0
  24. package/dist/ssg-config.js +1 -0
  25. package/dist/ssg.d.ts +61 -0
  26. package/dist/ssg.js +360 -24
  27. package/dist/templates/full-stack/package.json +1 -1
  28. package/dist/templates/full-stack/src/server/action-registry.ts +0 -1
  29. package/dist/templates/full-stack/tsconfig.json +1 -1
  30. package/dist/templates/spa/package.json +2 -3
  31. package/dist/templates/spa/src/pages/app/_routes.tsx +2 -0
  32. package/dist/templates/spa/src/pages/public/_routes.tsx +2 -0
  33. package/dist/templates/spa/tsconfig.json +2 -1
  34. package/dist/templates/spa/vitest.config.ts +0 -4
  35. package/dist/templates/ssg/README.md +1 -1
  36. package/dist/templates/ssg/package.json +1 -1
  37. package/dist/templates/ssg/ssg.config.ts +7 -0
  38. package/dist/templates/ssg/tests/ssg-config.test.ts +2 -0
  39. package/dist/templates/ssg/tsconfig.json +2 -1
  40. package/dist/templates/ssg/vitest.config.ts +0 -4
  41. package/dist/templates/ssr/package.json +2 -2
  42. package/dist/templates/startkit/package.json +2 -2
  43. package/dist/templates/startkit/src/lib/mock-data.ts +17 -39
  44. package/dist/templates/startkit/tsconfig.json +2 -1
  45. package/dist/update.d.ts +41 -0
  46. package/dist/update.js +0 -2
  47. package/dist/writer-D8qe_7ud.js +0 -2
  48. package/package.json +13 -8
  49. package/dist/add.js.map +0 -1
  50. package/dist/cli.js.map +0 -1
  51. package/dist/create.js.map +0 -1
  52. package/dist/discovery-Difb7Y4G.js.map +0 -1
  53. package/dist/generate.js.map +0 -1
  54. package/dist/is-direct-execution-Cdlr-ZUl.js.map +0 -1
  55. package/dist/openapi.js.map +0 -1
  56. package/dist/planner-VAj7qlxr.js.map +0 -1
  57. package/dist/range-YUs9eimn.js.map +0 -1
  58. package/dist/registry-CyrRHRG5.js.map +0 -1
  59. package/dist/skills-Bh0mEhIx.js.map +0 -1
  60. package/dist/specification-DXnDOC-0.js.map +0 -1
  61. package/dist/ssg.js.map +0 -1
  62. package/dist/templates/full-stack/src/vite-server.d.ts +0 -5
  63. package/dist/templates/spa/src/styles.d.ts +0 -1
  64. package/dist/templates/ssg/src/vite-env.d.ts +0 -5
  65. package/dist/templates/ssr/src/vite-server.d.ts +0 -7
  66. package/dist/templates/startkit/src/vite-env.d.ts +0 -5
  67. package/dist/update.js.map +0 -1
  68. package/dist/writer-D8qe_7ud.js.map +0 -1
  69. package/skills/askr-accessibility/SKILL.md +0 -68
  70. package/skills/askr-accessibility/agents/openai.yaml +0 -4
  71. package/skills/askr-agent-execution/SKILL.md +0 -85
  72. package/skills/askr-agent-execution/agents/openai.yaml +0 -4
  73. package/skills/askr-agent-workflows/SKILL.md +0 -57
  74. package/skills/askr-agent-workflows/agents/openai.yaml +0 -4
  75. package/skills/askr-api-integration/SKILL.md +0 -79
  76. package/skills/askr-api-integration/agents/openai.yaml +0 -4
  77. package/skills/askr-app-builder/SKILL.md +0 -99
  78. package/skills/askr-app-builder/agents/openai.yaml +0 -4
  79. package/skills/askr-auth-access/SKILL.md +0 -74
  80. package/skills/askr-auth-access/agents/openai.yaml +0 -4
  81. package/skills/askr-cli-vite/SKILL.md +0 -76
  82. package/skills/askr-cli-vite/agents/openai.yaml +0 -4
  83. package/skills/askr-dashboard-charts/SKILL.md +0 -99
  84. package/skills/askr-dashboard-charts/agents/openai.yaml +0 -4
  85. package/skills/askr-design-system/SKILL.md +0 -86
  86. package/skills/askr-design-system/agents/openai.yaml +0 -4
  87. package/skills/askr-env-config/SKILL.md +0 -74
  88. package/skills/askr-env-config/agents/openai.yaml +0 -4
  89. package/skills/askr-error-loading-empty/SKILL.md +0 -89
  90. package/skills/askr-error-loading-empty/agents/openai.yaml +0 -4
  91. package/skills/askr-file-upload-artifacts/SKILL.md +0 -77
  92. package/skills/askr-file-upload-artifacts/agents/openai.yaml +0 -4
  93. package/skills/askr-forms-tables-crud/SKILL.md +0 -98
  94. package/skills/askr-forms-tables-crud/agents/openai.yaml +0 -4
  95. package/skills/askr-mental-model/SKILL.md +0 -109
  96. package/skills/askr-mental-model/agents/openai.yaml +0 -4
  97. package/skills/askr-migration-react/SKILL.md +0 -81
  98. package/skills/askr-migration-react/agents/openai.yaml +0 -4
  99. package/skills/askr-observability-debugging/SKILL.md +0 -83
  100. package/skills/askr-observability-debugging/agents/openai.yaml +0 -4
  101. package/skills/askr-project-structure/SKILL.md +0 -79
  102. package/skills/askr-project-structure/agents/openai.yaml +0 -4
  103. package/skills/askr-query-mutation/SKILL.md +0 -115
  104. package/skills/askr-query-mutation/agents/openai.yaml +0 -4
  105. package/skills/askr-realtime-streaming/SKILL.md +0 -76
  106. package/skills/askr-realtime-streaming/agents/openai.yaml +0 -4
  107. package/skills/askr-resources-data/SKILL.md +0 -100
  108. package/skills/askr-resources-data/agents/openai.yaml +0 -4
  109. package/skills/askr-routing-layouts/SKILL.md +0 -107
  110. package/skills/askr-routing-layouts/agents/openai.yaml +0 -4
  111. package/skills/askr-runtime-reactivity/SKILL.md +0 -92
  112. package/skills/askr-runtime-reactivity/agents/openai.yaml +0 -4
  113. package/skills/askr-ssr-ssg/SKILL.md +0 -76
  114. package/skills/askr-ssr-ssg/agents/openai.yaml +0 -4
  115. package/skills/askr-testing-determinism/SKILL.md +0 -75
  116. package/skills/askr-testing-determinism/agents/openai.yaml +0 -4
  117. package/skills/askr-theming/SKILL.md +0 -86
  118. package/skills/askr-theming/agents/openai.yaml +0 -4
  119. package/skills/askr-ui-composition/SKILL.md +0 -92
  120. package/skills/askr-ui-composition/agents/openai.yaml +0 -4
  121. package/templates/full-stack/AGENTS.md +0 -11
  122. package/templates/full-stack/README.md +0 -17
  123. package/templates/full-stack/gitignore.template +0 -4
  124. package/templates/full-stack/index.html +0 -13
  125. package/templates/full-stack/package.json +0 -39
  126. package/templates/full-stack/server.ts +0 -9
  127. package/templates/full-stack/src/action-authorizations.ts +0 -10
  128. package/templates/full-stack/src/actions/create-message.ts +0 -10
  129. package/templates/full-stack/src/i18n.ts +0 -8
  130. package/templates/full-stack/src/main.tsx +0 -11
  131. package/templates/full-stack/src/pages/home.tsx +0 -25
  132. package/templates/full-stack/src/pages/layout.tsx +0 -43
  133. package/templates/full-stack/src/pages/not-found.tsx +0 -7
  134. package/templates/full-stack/src/routes.tsx +0 -19
  135. package/templates/full-stack/src/schemas.ts +0 -10
  136. package/templates/full-stack/src/server/action-registry.ts +0 -8
  137. package/templates/full-stack/src/server/actions/create-message.ts +0 -14
  138. package/templates/full-stack/src/server/app.ts +0 -76
  139. package/templates/full-stack/src/server/dependencies.ts +0 -55
  140. package/templates/full-stack/src/server/entry-server.ts +0 -8
  141. package/templates/full-stack/src/telemetry.ts +0 -3
  142. package/templates/full-stack/src/vite-server.d.ts +0 -5
  143. package/templates/full-stack/tests/actions/create-message.test.ts +0 -12
  144. package/templates/full-stack/tsconfig.json +0 -15
  145. package/templates/full-stack/vite.config.ts +0 -10
  146. package/templates/spa/AGENTS.md +0 -60
  147. package/templates/spa/README.md +0 -96
  148. package/templates/spa/gitignore.template +0 -16
  149. package/templates/spa/index.html +0 -13
  150. package/templates/spa/package.json +0 -35
  151. package/templates/spa/src/adapters/operations-client.ts +0 -95
  152. package/templates/spa/src/components/shared/metric-card.tsx +0 -27
  153. package/templates/spa/src/components/shared/status-badge.tsx +0 -24
  154. package/templates/spa/src/features/operations/operations.query.ts +0 -9
  155. package/templates/spa/src/main.tsx +0 -10
  156. package/templates/spa/src/pages/_layout.tsx +0 -9
  157. package/templates/spa/src/pages/_routes.tsx +0 -27
  158. package/templates/spa/src/pages/app/_layout.tsx +0 -94
  159. package/templates/spa/src/pages/app/_routes.tsx +0 -10
  160. package/templates/spa/src/pages/app/admin-home.tsx +0 -170
  161. package/templates/spa/src/pages/app/agent-runs.tsx +0 -93
  162. package/templates/spa/src/pages/app/settings.tsx +0 -91
  163. package/templates/spa/src/pages/auth/_layout.tsx +0 -38
  164. package/templates/spa/src/pages/auth/_routes.tsx +0 -6
  165. package/templates/spa/src/pages/auth/login.tsx +0 -63
  166. package/templates/spa/src/pages/not-found.tsx +0 -22
  167. package/templates/spa/src/pages/public/_layout.tsx +0 -47
  168. package/templates/spa/src/pages/public/_routes.tsx +0 -6
  169. package/templates/spa/src/pages/public/home.tsx +0 -143
  170. package/templates/spa/src/shared/format.ts +0 -12
  171. package/templates/spa/src/shared/navigation.ts +0 -15
  172. package/templates/spa/src/styles/components.css +0 -49
  173. package/templates/spa/src/styles/layout.css +0 -192
  174. package/templates/spa/src/styles/reset.css +0 -44
  175. package/templates/spa/src/styles/theme.css +0 -57
  176. package/templates/spa/src/styles/tokens.css +0 -20
  177. package/templates/spa/src/styles.css +0 -7
  178. package/templates/spa/src/styles.d.ts +0 -1
  179. package/templates/spa/tests/app.test.tsx +0 -37
  180. package/templates/spa/tests/components/shared.test.tsx +0 -12
  181. package/templates/spa/tests/resources.test.ts +0 -22
  182. package/templates/spa/tsconfig.json +0 -20
  183. package/templates/spa/tsconfig.node.json +0 -10
  184. package/templates/spa/vite.config.ts +0 -24
  185. package/templates/spa/vitest.config.ts +0 -17
  186. package/templates/ssg/AGENTS.md +0 -55
  187. package/templates/ssg/README.md +0 -39
  188. package/templates/ssg/gitignore.template +0 -17
  189. package/templates/ssg/index.html +0 -13
  190. package/templates/ssg/package.json +0 -35
  191. package/templates/ssg/src/app.tsx +0 -14
  192. package/templates/ssg/src/components/badge.tsx +0 -3
  193. package/templates/ssg/src/components/counter.tsx +0 -30
  194. package/templates/ssg/src/components/site-shell.tsx +0 -111
  195. package/templates/ssg/src/jsx.d.ts +0 -23
  196. package/templates/ssg/src/main.tsx +0 -8
  197. package/templates/ssg/src/pages/about.tsx +0 -82
  198. package/templates/ssg/src/pages/content.tsx +0 -63
  199. package/templates/ssg/src/pages/example.tsx +0 -97
  200. package/templates/ssg/src/pages/home.tsx +0 -51
  201. package/templates/ssg/src/resources/user.ts +0 -15
  202. package/templates/ssg/src/routes.tsx +0 -15
  203. package/templates/ssg/src/styles.css +0 -89
  204. package/templates/ssg/src/vite-env.d.ts +0 -5
  205. package/templates/ssg/ssg.config.ts +0 -34
  206. package/templates/ssg/tests/app.test.tsx +0 -19
  207. package/templates/ssg/tests/components/counter.test.tsx +0 -18
  208. package/templates/ssg/tests/resources.test.ts +0 -11
  209. package/templates/ssg/tests/ssg-config.test.ts +0 -11
  210. package/templates/ssg/tsconfig.json +0 -20
  211. package/templates/ssg/tsconfig.node.json +0 -10
  212. package/templates/ssg/vite.config.ts +0 -24
  213. package/templates/ssg/vitest.config.ts +0 -17
  214. package/templates/ssr/AGENTS.md +0 -28
  215. package/templates/ssr/README.md +0 -38
  216. package/templates/ssr/gitignore.template +0 -16
  217. package/templates/ssr/index.html +0 -13
  218. package/templates/ssr/package.json +0 -34
  219. package/templates/ssr/server.ts +0 -10
  220. package/templates/ssr/src/app.tsx +0 -21
  221. package/templates/ssr/src/components/counter.tsx +0 -26
  222. package/templates/ssr/src/entry-server.tsx +0 -12
  223. package/templates/ssr/src/main.tsx +0 -11
  224. package/templates/ssr/src/pages/about.tsx +0 -75
  225. package/templates/ssr/src/pages/example.tsx +0 -113
  226. package/templates/ssr/src/pages/home.tsx +0 -56
  227. package/templates/ssr/src/resources/user.ts +0 -15
  228. package/templates/ssr/src/routes.tsx +0 -13
  229. package/templates/ssr/src/styles.css +0 -148
  230. package/templates/ssr/src/vite-server.d.ts +0 -7
  231. package/templates/ssr/tests/app.test.tsx +0 -24
  232. package/templates/ssr/tests/components/counter.test.tsx +0 -13
  233. package/templates/ssr/tests/resources.test.ts +0 -11
  234. package/templates/ssr/tsconfig.json +0 -22
  235. package/templates/ssr/tsconfig.node.json +0 -10
  236. package/templates/ssr/tsconfig.server.json +0 -15
  237. package/templates/ssr/vite.config.ts +0 -25
  238. package/templates/ssr/vitest.config.ts +0 -13
  239. package/templates/startkit/AGENTS.md +0 -77
  240. package/templates/startkit/README.md +0 -192
  241. package/templates/startkit/gitignore.template +0 -16
  242. package/templates/startkit/index.html +0 -13
  243. package/templates/startkit/package.json +0 -35
  244. package/templates/startkit/src/components/app-header.tsx +0 -93
  245. package/templates/startkit/src/components/app-sidebar.tsx +0 -95
  246. package/templates/startkit/src/components/data-table.tsx +0 -80
  247. package/templates/startkit/src/components/empty-state.tsx +0 -13
  248. package/templates/startkit/src/components/page-header.tsx +0 -23
  249. package/templates/startkit/src/components/stat-card.tsx +0 -24
  250. package/templates/startkit/src/features/accounts/account-filters.tsx +0 -61
  251. package/templates/startkit/src/features/accounts/account-table.tsx +0 -79
  252. package/templates/startkit/src/lib/format.ts +0 -31
  253. package/templates/startkit/src/lib/mock-data.ts +0 -441
  254. package/templates/startkit/src/lib/routes.ts +0 -116
  255. package/templates/startkit/src/main.tsx +0 -12
  256. package/templates/startkit/src/pages/_layout.tsx +0 -56
  257. package/templates/startkit/src/pages/auth/_layout.tsx +0 -7
  258. package/templates/startkit/src/pages/auth/login.tsx +0 -129
  259. package/templates/startkit/src/pages/home.tsx +0 -83
  260. package/templates/startkit/src/pages/not-found.tsx +0 -24
  261. package/templates/startkit/src/pages/workspace/_layout.tsx +0 -17
  262. package/templates/startkit/src/pages/workspace/accounts/index.tsx +0 -217
  263. package/templates/startkit/src/pages/workspace/dashboard.tsx +0 -118
  264. package/templates/startkit/src/pages/workspace/settings.tsx +0 -218
  265. package/templates/startkit/src/router.tsx +0 -7
  266. package/templates/startkit/src/routes/auth-config.ts +0 -38
  267. package/templates/startkit/src/routes/auth.ts +0 -8
  268. package/templates/startkit/src/routes/index.ts +0 -28
  269. package/templates/startkit/src/routes/public.ts +0 -8
  270. package/templates/startkit/src/routes/workspace/accounts.ts +0 -8
  271. package/templates/startkit/src/routes/workspace/index.ts +0 -14
  272. package/templates/startkit/src/styles/components.css +0 -396
  273. package/templates/startkit/src/styles/layout.css +0 -192
  274. package/templates/startkit/src/styles/reset.css +0 -38
  275. package/templates/startkit/src/styles/theme.css +0 -76
  276. package/templates/startkit/src/styles/tokens.css +0 -67
  277. package/templates/startkit/src/styles.css +0 -7
  278. package/templates/startkit/src/toast.ts +0 -55
  279. package/templates/startkit/src/utils/join-classes.ts +0 -4
  280. package/templates/startkit/src/vite-env.d.ts +0 -5
  281. package/templates/startkit/tests/app.test.tsx +0 -32
  282. package/templates/startkit/tests/preferences.test.ts +0 -43
  283. package/templates/startkit/tests/resources.test.ts +0 -82
  284. package/templates/startkit/tsconfig.json +0 -20
  285. package/templates/startkit/tsconfig.node.json +0 -10
  286. package/templates/startkit/vite.config.ts +0 -32
  287. package/templates/startkit/vitest.config.ts +0 -13
@@ -1,4 +0,0 @@
1
- interface:
2
- display_name: "Askr Routing Layouts"
3
- short_description: "Define Askr routes and shells"
4
- default_prompt: "Use $askr-routing-layouts to add routes, layouts, and navigation."
@@ -1,92 +0,0 @@
1
- ---
2
- name: askr-runtime-reactivity
3
- description: Use when writing askr reactive runtime code with state, derive, selector, context, JSX control flow, stable call order, deterministic event handling, or render lifecycle rules.
4
- ---
5
-
6
- # Askr Runtime Reactivity
7
-
8
- Use this when local state, derived values, keyed identity, or runtime determinism matters. The goal is stable helper call order and correct primitive use.
9
-
10
- ## Use This When
11
-
12
- - You are adding local UI state.
13
- - You need a computed value from reactive reads.
14
- - You are rendering keyed lists, selections, or filters.
15
- - You need to keep call order stable across renders.
16
-
17
- ## Inspect First
18
-
19
- - The nearest existing component with similar state or list behavior.
20
- - Existing tests that already cover toggles, selection, or filtering.
21
- - The nearest feature owner if local state may need to become shared later.
22
-
23
- ## Pick The Primitive
24
-
25
- - Local mutable value: `state()` returns a `[getter, setter]` pair.
26
- - Computed value from reactive reads: `derive()`.
27
- - One reactive source fans out to many keyed readers: `selector()`.
28
- - Cross-tree shared value: `defineScope()` and `readScope()`.
29
- - Keyed or identity-sensitive list: `For`.
30
-
31
- ## Copy This Shape
32
-
33
- ```tsx
34
- import { derive, selector, state } from "@askrjs/askr";
35
- import { For, Show } from "@askrjs/askr/control";
36
-
37
- const [count, setCount] = state(0);
38
- const [selectedId, setSelectedId] = state<number | null>(null);
39
- const doubled = derive(() => count() * 2);
40
- const isSelected = selector(selectedId);
41
- ```
42
-
43
- `state()` returns a `[getter, setter]` pair. Read with `getter()` and update with `setter(...)`.
44
-
45
- ## Determinism Rules
46
-
47
- - Do not call `state`, `derive`, `selector`, `resource`, query, or mutation helpers conditionally.
48
- - Do not mutate state during render.
49
- - Batch related updates in the event handler that owns the user action.
50
- - Preserve stable keys in `For` for rows and reorderable lists.
51
-
52
- ## Reject This Shape
53
-
54
- ```tsx
55
- function BadList({ rows }) {
56
- if (rows.length > 0) {
57
- const [selected, setSelected] = state(rows[0].id);
58
- return rows.map((row, index) => (
59
- <button key={index} onClick={() => setSelected(row.id)}>
60
- {selected === row.id ? "Selected" : row.label}
61
- </button>
62
- ));
63
- }
64
-
65
- return null;
66
- }
67
- ```
68
-
69
- Reject this shape. It creates state conditionally, treats getter/setter values like plain variables, and uses index keys where stable identity matters.
70
-
71
- - Reading a getter without calling it.
72
- - React hooks or `useState` in Askr app code.
73
- - Recreating selectors in row components.
74
- - Index keys for data with stable IDs.
75
- - Derived state that performs side effects.
76
-
77
- ## Validate
78
-
79
- - Runtime helpers are top-level and unconditional.
80
- - Getter calls are explicit.
81
- - Lists have stable identity.
82
- - Existing or new tests cover the state change that matters.
83
-
84
- ## Done When
85
-
86
- - No React-style state shape or conditional helper creation slipped in.
87
-
88
- ## Handoff
89
-
90
- - Use `askr-query-mutation` when the next step is shared keyed state.
91
- - Use `askr-resources-data` when the next step is async lifecycle ownership.
92
- - Use `askr-testing-determinism` before closing runtime-sensitive changes.
@@ -1,4 +0,0 @@
1
- interface:
2
- display_name: "Askr Runtime Reactivity"
3
- short_description: "Write deterministic Askr state code"
4
- default_prompt: "Use $askr-runtime-reactivity to write deterministic Askr state and control flow."
@@ -1,76 +0,0 @@
1
- ---
2
- name: askr-ssr-ssg
3
- description: Use when building askr server-rendered or static-generated apps, working with SSR/SSG entrypoints, route manifests, static generation configs, hydration-safe rendering, resource constraints, and render output verification.
4
- ---
5
-
6
- # Askr SSR SSG
7
-
8
- Use this when the app renders outside the browser or produces static output. The goal is one shared route tree, environment-safe render paths, and hydration-safe output.
9
-
10
- ## Inspect First
11
-
12
- - `src/main.tsx`
13
- - The shared route registry
14
- - SSR entry files such as `server.ts` or `entry-server.tsx`
15
- - SSG files such as `ssg.config.ts` or `ssg-build.ts`
16
- - Existing build and preview scripts in `package.json`
17
-
18
- ## Use This When
19
-
20
- - You are adding SSR or SSG routes.
21
- - You need parameterized static entries.
22
- - You need to keep browser-only code out of server render paths.
23
- - You need to verify hydration safety after changing render behavior.
24
-
25
- ## Do This In Order
26
-
27
- 1. Keep the route tree shared across browser, server, and static output where possible.
28
- 2. Register routes at module load before boot or render.
29
- 3. Keep render paths deterministic and environment-safe.
30
- 4. Use route `entries` or the template's static config for parameterized SSG paths.
31
- 5. Build and preview after changes that cross the render boundary.
32
-
33
- ## Copy This Shape
34
-
35
- ```ts
36
- registerRoutes(() => {
37
- page("/docs/{slug}", DocsPage, {
38
- entries: async () => [{ slug: "getting-started" }, { slug: "routing" }],
39
- });
40
- });
41
- ```
42
-
43
- ## Never Do These
44
-
45
- - Async components in render paths.
46
- - Route registration that depends on request-time mutation.
47
- - Browser-only globals in server or static render paths without guards.
48
- - Divergent route trees for client, server, and static output.
49
- - Random values or time reads that change initial markup across server and client.
50
-
51
- ## Static Generation Pattern
52
-
53
- ```bash
54
- npx @askrjs/cli create ssg my-site
55
- npm run build
56
- npx @askrjs/cli ssg --config ./ssg.config.ts --output ./dist/static
57
- ```
58
-
59
- ## Validate
60
-
61
- - SSR or SSG build output is deterministic for the same inputs.
62
- - Hydration has no structural mismatch warnings.
63
- - Generated static routes cover expected params.
64
- - Browser preview still navigates correctly after hydration.
65
-
66
- ## Done When
67
-
68
- - The same route tree still owns navigation across environments.
69
- - Server and static render paths are environment-safe.
70
- - Parameterized routes have explicit static coverage where needed.
71
- - Build and preview prove the render boundary still works.
72
-
73
- ## Handoff
74
-
75
- - Use `askr-routing-layouts` when the hard part is route ownership.
76
- - Use `askr-testing-determinism` when hydration, preview, or build verification is the real blocker.
@@ -1,4 +0,0 @@
1
- interface:
2
- display_name: "Askr SSR SSG"
3
- short_description: "Render askr on server or static"
4
- default_prompt: "Use $askr-ssr-ssg to build SSR or static Askr output."
@@ -1,75 +0,0 @@
1
- ---
2
- name: askr-testing-determinism
3
- description: Use when testing Askr apps, validating deterministic runtime behavior, writing jsdom or browser tests, checking accessibility, cleanup, route behavior, resources, queries, mutations, keyed lists, and performance-sensitive UI.
4
- ---
5
-
6
- # Askr Testing Determinism
7
-
8
- Use this when choosing or running validation for Askr work. The goal is the narrowest executable check that proves the changed contract.
9
-
10
- ## Use This When
11
-
12
- - You changed route behavior, state behavior, async ownership, or user-visible UI.
13
- - You need to decide which test level is correct.
14
- - You need objective done criteria before closing a task.
15
- - You need to avoid ending on diff review alone.
16
-
17
- ## Inspect First
18
-
19
- - Existing tests nearest to the changed files.
20
- - The repo's test scripts in `package.json`.
21
- - Existing browser or jsdom coverage for similar behavior.
22
- - Any known failing test that already describes the bug.
23
-
24
- ## Pick The Smallest Useful Check
25
-
26
- - Unit tests: pure helpers, formatters, validators, route metadata, data transforms.
27
- - jsdom tests: runtime state, resource behavior, route rendering, component logic.
28
- - Browser tests: focus, keyboard behavior, overlays, layout, hydration, visual regressions, performance-sensitive flows.
29
- - Type tests: public API and component prop contracts.
30
- - Benchmarks: hot paths, keyed lists, large tables, router matching, hydration.
31
-
32
- ## Validate In This Order
33
-
34
- 1. The narrowest failing or behavior-scoped test for the slice you changed.
35
- 2. The nearest type check or package check.
36
- 3. Build or template-specific checks when boot, routing, SSR, SSG, or packaging changed.
37
- 4. Manual runtime verification for user-visible async, focus, overflow, or stale-state behavior when tests do not already cover it.
38
-
39
- ## Determinism Targets
40
-
41
- - Event ordering and batched updates.
42
- - Stable call order for runtime helpers.
43
- - Keyed DOM identity during list updates.
44
- - No partial DOM commit after render failure.
45
- - Async cancellation on navigation or unmount.
46
- - Route identity and layout retention across navigation.
47
-
48
- ## Patterns
49
-
50
- - Clean up mounted apps with `cleanupApp(root)` when tests mount an app.
51
- - Prefer user-visible assertions over implementation detail checks.
52
- - For `resource()`, cover pending, success, error, refresh, and cancellation when relevant.
53
- - For `@askrjs/ui`, cover keyboard and ARIA behavior.
54
- - For themes, include computed style and overflow checks where visual contracts matter.
55
-
56
- - Tests that depend on uncontrolled timers or random data.
57
- - Snapshot-only coverage for interactive behavior.
58
- - Browser behavior tested only in jsdom.
59
- - Performance changes without a focused benchmark or regression test.
60
-
61
- ## Validate The Test Itself
62
-
63
- - The smallest meaningful test covers the changed contract.
64
- - The chosen test level matches the behavior under change.
65
- - Async checks wait for visible state instead of sleeping blindly.
66
- - The repo's existing scripts are used before inventing new ones.
67
-
68
- ## Done When
69
-
70
- - Diff review was not used as the only proof when an executable check existed.
71
-
72
- ## Handoff
73
-
74
- - Use `askr-accessibility` when browser coverage reveals focus or announcement issues.
75
- - Use `askr-observability-debugging` when tests expose stale-state or correlation failures.
@@ -1,4 +0,0 @@
1
- interface:
2
- display_name: "Askr Testing Determinism"
3
- short_description: "Test deterministic Askr behavior"
4
- default_prompt: "Use $askr-testing-determinism to test Askr runtime and UI behavior."
@@ -1,86 +0,0 @@
1
- ---
2
- name: askr-theming
3
- description: Use when styling Askr apps with @askrjs/themes, tokens, data-theme, ThemeScope, shell/nav/layout primitives, data-slot selectors, visual quality audits, dark mode, and theme/app boundary decisions.
4
- ---
5
-
6
- # Askr Theming
7
-
8
- Use this when styling an Askr app with the theme layer. The goal is one obvious shell, one obvious token strategy, and no app-local clones of solved surfaces.
9
-
10
- ## Inspect First
11
-
12
- - `src/styles.css` and `src/styles/*`
13
- - The root layout or app shell that imports the theme
14
- - Existing shared components and `@askrjs/themes` imports
15
- - The nearest screen with the same layout or surface pattern
16
-
17
- ## Use This When
18
-
19
- - You are styling a new product surface.
20
- - You need dark mode, shell chrome, or token overrides.
21
- - You want the default Askr admin or SaaS visual language.
22
- - You are tempted to create local `Card`, `Panel`, `Sidebar`, `Toolbar`, or `EmptyState` components.
23
-
24
- ## Choose The Layer
25
-
26
- - Use `@askrjs/themes` when the existing app already uses the default visual layer.
27
- - Use `@askrjs/ui` directly only when the app already owns its own visual system and just needs headless behavior.
28
- - Create an app-local wrapper only when it adds clear product semantics beyond one screen.
29
-
30
- ## Do This In Order
31
-
32
- 1. Import the theme once at the app boundary or stylesheet entry.
33
- 2. Reuse existing theme primitives for shells, navigation, layout, surfaces, feedback, and forms.
34
- 3. Override semantic `--ak-*` tokens in CSS, not runtime TypeScript.
35
- 4. Use `data-slot` or documented selectors for local CSS hooks.
36
- 5. Check the result in mobile, desktop, light, dark, empty, error, and disabled states.
37
-
38
- ## Copy This Shape
39
-
40
- ```ts
41
- import "@askrjs/themes/default";
42
- import {
43
- Button,
44
- Card,
45
- CardContent,
46
- CardHeader,
47
- CardTitle,
48
- Container,
49
- EmptyState,
50
- Section,
51
- Shell,
52
- ShellMain,
53
- ShellNav,
54
- Stack,
55
- ThemeScope,
56
- } from "@askrjs/themes/components";
57
- ```
58
-
59
- ## Never Do These
60
-
61
- - Moving runtime behavior into theme files.
62
- - Treating theme components as app state containers.
63
- - Hardcoded non-token colors when tokens exist.
64
- - Deep internal selectors or `!important`.
65
- - Marketing-page assumptions in operational SaaS surfaces.
66
- - Inventing app-local `Panel`, `HStack`, `VStack`, `Page`, `Toolbar`, `Badge`, `Card`, or `EmptyState` components before checking the theme surface.
67
- - Recreating shell, nav, feedback, form field, or responsive layout primitives already exported by `@askrjs/themes`.
68
-
69
- ## Validate
70
-
71
- - No clipped text, horizontal overflow, or broken shell composition.
72
- - Focus, hover, disabled, empty, and error states are styled deliberately.
73
- - Dark mode is intentional, not inverted by accident.
74
- - App CSS remains override-friendly and token-based.
75
-
76
- ## Done When
77
-
78
- - The surface reuses the existing theme layer instead of inventing a second one.
79
- - Tokens live in CSS and behavior stays in components.
80
- - The interface remains coherent across responsive and state changes.
81
-
82
- ## Handoff
83
-
84
- - Use `askr-ui-composition` when the hard part is behavior and composition, not visual styling.
85
- - Use `askr-accessibility` when announcements, focus, or semantic behavior need review.
86
- - Use `askr-testing-determinism` before closing visible UI changes.
@@ -1,4 +0,0 @@
1
- interface:
2
- display_name: "Askr Theming"
3
- short_description: "Style apps with Askr themes"
4
- default_prompt: "Use $askr-theming to apply tokens, shells, navs, and theme rules."
@@ -1,92 +0,0 @@
1
- ---
2
- name: askr-ui-composition
3
- description: Use when composing Askr UI with @askrjs/ui headless primitives, accessibility behavior, asChild polymorphism, root-owned state, private component context, slots, keyboard behavior, overlays, and app-local components.
4
- ---
5
-
6
- # Askr UI Composition
7
-
8
- Use this when the hard part is behavior and composition rather than theming. The goal is to reuse `@askrjs/ui` for focus, keyboard, dismissal, and ARIA behavior instead of rebuilding it locally.
9
-
10
- ## Inspect First
11
-
12
- - Existing component imports and slot naming
13
- - The nearest shared component with similar behavior
14
- - Existing theme usage to decide whether headless or themed primitives fit better
15
- - Existing tests for keyboard or focus behavior
16
-
17
- ## Use This When
18
-
19
- - You need dialog, popover, menu, select, toggle, checkbox, or other interactive behavior.
20
- - The app needs headless primitives or already owns its own CSS.
21
- - You are tempted to rebuild keyboard, focus, or dismissal logic locally.
22
- - Themed primitives are not enough because behavior composition is the real problem.
23
-
24
- ## Choose UI Or Theme
25
-
26
- - Use `@askrjs/ui` directly when the app has its own CSS or needs a headless behavior primitive.
27
- - Use `@askrjs/themes` when the existing visual system should also style the primitive.
28
- - Do not create app-local wrappers for solved theme surfaces unless the wrapper adds product semantics.
29
-
30
- ## Do This In Order
31
-
32
- 1. Pick the primitive family that already owns the behavior.
33
- 2. Keep coordination state in the root component that owns the interaction.
34
- 3. Use `asChild` only when caller markup must be preserved.
35
- 4. Use `data-slot` on app structure that needs stable styling hooks.
36
- 5. Validate keyboard, pointer, and ARIA behavior.
37
-
38
- ## Copy This Shape
39
-
40
- ```tsx
41
- import {
42
- AlertDialog,
43
- AlertDialogAction,
44
- AlertDialogCancel,
45
- AlertDialogContent,
46
- AlertDialogOverlay,
47
- AlertDialogPortal,
48
- AlertDialogTitle,
49
- AlertDialogTrigger,
50
- } from "@askrjs/ui/alert-dialog";
51
-
52
- <AlertDialog>
53
- <AlertDialogTrigger asChild>
54
- <button>Archive</button>
55
- </AlertDialogTrigger>
56
- <AlertDialogPortal>
57
- <AlertDialogOverlay />
58
- <AlertDialogContent>
59
- <AlertDialogTitle>Archive account?</AlertDialogTitle>
60
- <AlertDialogCancel>Cancel</AlertDialogCancel>
61
- <AlertDialogAction>Archive</AlertDialogAction>
62
- </AlertDialogContent>
63
- </AlertDialogPortal>
64
- </AlertDialog>;
65
- ```
66
-
67
- ## Never Do These
68
-
69
- - Reimplementing keyboard, focus, or dismissal behavior already owned by a primitive.
70
- - Styling or business logic inside behavior primitives.
71
- - Leaf components that fetch data or own routing.
72
- - Silent invalid composition when a part requires a root scope.
73
- - Prop bloat where composition would be clearer.
74
-
75
- ## Validate
76
-
77
- - Keyboard and pointer behavior match the primitive contract.
78
- - ARIA labels, names, and roles are present where required.
79
- - `asChild` preserves expected markup and events.
80
- - User-facing interaction has jsdom or browser coverage.
81
-
82
- ## Done When
83
-
84
- - The app reused the primitive that already owns the behavior.
85
- - Product composition stayed in the app, while behavior stayed in the primitive.
86
- - No local behavior clone was introduced.
87
-
88
- ## Handoff
89
-
90
- - Use `askr-theming` when the next step is visual styling and shell coherence.
91
- - Use `askr-accessibility` when the next step is announcement, focus, or semantic review.
92
- - Use `askr-testing-determinism` before closing user-facing interaction changes.
@@ -1,4 +0,0 @@
1
- interface:
2
- display_name: "Askr UI Composition"
3
- short_description: "Compose accessible headless UI"
4
- default_prompt: "Use $askr-ui-composition to compose Askr UI primitives correctly."
@@ -1,11 +0,0 @@
1
- # {{appName}}
2
-
3
- This project is the progressive full-stack stage of an Askr application.
4
-
5
- - Prefer functions, closures, and structural interfaces over classes.
6
- - Keep action descriptors and schemas browser-safe under `src/actions` and `src/schemas.ts`.
7
- - Keep handlers, repositories, secrets, and composition dependencies under `src/server`.
8
- - Authorize every page action through the matched `route(..., { actions })` declaration.
9
- - Keep `index.html` as the only document source. Preserve exactly one `<!--askr-head-->` and one `<!--askr-app-->` marker.
10
- - Use native forms first; enhanced submission must preserve the same validation and authorization behavior.
11
- - Never log cookies, authorization values, tokens, form fields, request bodies, or personal data.
@@ -1,17 +0,0 @@
1
- # {{appName}}
2
-
3
- An Askr full-stack application with shared routes, executable schemas, declared actions, API routes, SSR hydration, i18n, telemetry seams, and Node/Vite production entrypoints.
4
-
5
- ## Commands
6
-
7
- ```bash
8
- npm install
9
- npm run dev
10
- npm run check
11
- npm run build
12
- npm run preview
13
- ```
14
-
15
- Use `askr add action <name> --route <path>` to generate a browser-safe descriptor, server handler, composition-root registration, route authorization, and focused test.
16
-
17
- `index.html` owns the static document. `@askrjs/vite/server` injects only Askr-owned head nodes and composes the streamed app response at `<!--askr-app-->`.
@@ -1,4 +0,0 @@
1
- node_modules
2
- dist
3
- coverage
4
- .env
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en" dir="ltr">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <meta name="theme-color" content="#111827" />
7
- <!--askr-head-->
8
- </head>
9
- <body>
10
- <div id="app"><!--askr-app--></div>
11
- <script type="module" src="/src/main.tsx"></script>
12
- </body>
13
- </html>
@@ -1,39 +0,0 @@
1
- {
2
- "name": "{{appName}}",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "vp dev",
8
- "build": "vp build && vp build --ssr server.ts --outDir dist/server",
9
- "preview": "node dist/server/server.js",
10
- "test": "vp test run",
11
- "typecheck": "tsc --noEmit",
12
- "lint": "vp lint src server.ts tests vite.config.ts",
13
- "fmt": "vp fmt .",
14
- "check": "npm run lint && npm run typecheck && npm test && npm run build"
15
- },
16
- "dependencies": {
17
- "@askrjs/askr": ">=0.0.53 <0.1.0",
18
- "@askrjs/auth": ">=0.0.1 <0.1.0",
19
- "@askrjs/i18n": ">=0.0.1 <0.1.0",
20
- "@askrjs/node": ">=0.0.1 <0.1.0",
21
- "@askrjs/otel": ">=0.0.1 <0.1.0",
22
- "@askrjs/schema": ">=0.0.1 <0.1.0",
23
- "@askrjs/server": ">=0.0.1 <0.1.0",
24
- "@askrjs/themes": ">=0.0.12 <0.1.0",
25
- "@askrjs/ui": ">=0.0.13 <0.1.0",
26
- "@opentelemetry/api": "^1.9.0"
27
- },
28
- "devDependencies": {
29
- "@askrjs/vite": ">=0.0.6 <0.1.0",
30
- "@types/node": "^26.0.0",
31
- "jsdom": "^29.1.1",
32
- "typescript": "^6.0.3",
33
- "vite-plus": "^0.2.4",
34
- "vitest": "^4.1.10"
35
- },
36
- "engines": {
37
- "node": "^20.19.0 || >=22.12.0"
38
- }
39
- }
@@ -1,9 +0,0 @@
1
- import { serve } from "@askrjs/node";
2
- import app from "virtual:askr-server";
3
-
4
- const port = Number(process.env.PORT ?? 3000);
5
- await serve(app, {
6
- host: process.env.HOST ?? "127.0.0.1",
7
- port,
8
- assets: { root: new URL("./dist", import.meta.url).pathname },
9
- });
@@ -1,10 +0,0 @@
1
- import type { ActionDescriptor } from "@askrjs/askr/actions";
2
- import { createMessageAction } from "./actions/create-message";
3
-
4
- const actionsByRoute: Readonly<Record<string, readonly ActionDescriptor[]>> = Object.freeze({
5
- "/": [createMessageAction],
6
- });
7
-
8
- export function actionsFor(path: string): readonly ActionDescriptor[] {
9
- return actionsByRoute[path] ?? [];
10
- }
@@ -1,10 +0,0 @@
1
- import { defineAction } from "@askrjs/askr/actions";
2
- import { MessageInput } from "../schemas";
3
-
4
- export const createMessageActionRoute = "/";
5
-
6
- export const createMessageAction = defineAction({
7
- id: "create-message",
8
- input: MessageInput,
9
- invalidates: ["messages"],
10
- });
@@ -1,8 +0,0 @@
1
- import { createI18n } from "@askrjs/i18n";
2
-
3
- export const messages = createI18n("en", {
4
- en: {
5
- title: () => "{{appName}}",
6
- intro: () => "A progressive full-stack Askr application.",
7
- },
8
- });
@@ -1,11 +0,0 @@
1
- import { createSPA, hydrateSPA } from "@askrjs/askr/boot";
2
- import { pageRegistry } from "./routes";
3
-
4
- const root = document.getElementById("app");
5
- if (!root) throw new Error("Missing #app root element.");
6
-
7
- if (root.hasChildNodes()) {
8
- await hydrateSPA({ root, registry: pageRegistry });
9
- } else {
10
- await createSPA({ root, registry: pageRegistry });
11
- }
@@ -1,25 +0,0 @@
1
- import { ActionForm } from "@askrjs/askr/actions";
2
- import { createMessageAction } from "../actions/create-message";
3
- import { messages } from "../i18n";
4
-
5
- export function HomePage() {
6
- return (
7
- <main>
8
- <h1>{messages.text("title")}</h1>
9
- <p>{messages.text("intro")}</p>
10
- <form method="post" action="/api/session">
11
- <button type="submit">Start demo session</button>
12
- </form>
13
- {ActionForm({
14
- action: createMessageAction,
15
- children: (
16
- <>
17
- <label htmlFor="message">Message</label>
18
- <input id="message" name="value" required />
19
- <button type="submit">Create message</button>
20
- </>
21
- ),
22
- })}
23
- </main>
24
- );
25
- }