@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.
- package/LICENSE +201 -0
- package/README.md +140 -0
- package/dist/add-DqhqRzBQ.js +555 -0
- package/dist/add-DqhqRzBQ.js.map +1 -0
- package/dist/add.js +3 -0
- package/dist/cli.js +91 -0
- package/dist/cli.js.map +1 -0
- package/dist/create.js +923 -0
- package/dist/create.js.map +1 -0
- package/dist/is-direct-execution-Cdlr-ZUl.js +20 -0
- package/dist/is-direct-execution-Cdlr-ZUl.js.map +1 -0
- package/dist/openapi.js +127 -0
- package/dist/openapi.js.map +1 -0
- package/dist/skills/askr-accessibility/SKILL.md +68 -0
- package/dist/skills/askr-accessibility/agents/openai.yaml +4 -0
- package/dist/skills/askr-agent-execution/SKILL.md +85 -0
- package/dist/skills/askr-agent-execution/agents/openai.yaml +4 -0
- package/dist/skills/askr-agent-workflows/SKILL.md +57 -0
- package/dist/skills/askr-agent-workflows/agents/openai.yaml +4 -0
- package/dist/skills/askr-api-integration/SKILL.md +79 -0
- package/dist/skills/askr-api-integration/agents/openai.yaml +4 -0
- package/dist/skills/askr-app-builder/SKILL.md +99 -0
- package/dist/skills/askr-app-builder/agents/openai.yaml +4 -0
- package/dist/skills/askr-auth-access/SKILL.md +74 -0
- package/dist/skills/askr-auth-access/agents/openai.yaml +4 -0
- package/dist/skills/askr-cli-vite/SKILL.md +76 -0
- package/dist/skills/askr-cli-vite/agents/openai.yaml +4 -0
- package/dist/skills/askr-dashboard-charts/SKILL.md +82 -0
- package/dist/skills/askr-dashboard-charts/agents/openai.yaml +4 -0
- package/dist/skills/askr-design-system/SKILL.md +86 -0
- package/dist/skills/askr-design-system/agents/openai.yaml +4 -0
- package/dist/skills/askr-env-config/SKILL.md +74 -0
- package/dist/skills/askr-env-config/agents/openai.yaml +4 -0
- package/dist/skills/askr-error-loading-empty/SKILL.md +89 -0
- package/dist/skills/askr-error-loading-empty/agents/openai.yaml +4 -0
- package/dist/skills/askr-file-upload-artifacts/SKILL.md +77 -0
- package/dist/skills/askr-file-upload-artifacts/agents/openai.yaml +4 -0
- package/dist/skills/askr-forms-tables-crud/SKILL.md +98 -0
- package/dist/skills/askr-forms-tables-crud/agents/openai.yaml +4 -0
- package/dist/skills/askr-mental-model/SKILL.md +109 -0
- package/dist/skills/askr-mental-model/agents/openai.yaml +4 -0
- package/dist/skills/askr-migration-react/SKILL.md +81 -0
- package/dist/skills/askr-migration-react/agents/openai.yaml +4 -0
- package/dist/skills/askr-observability-debugging/SKILL.md +83 -0
- package/dist/skills/askr-observability-debugging/agents/openai.yaml +4 -0
- package/dist/skills/askr-project-structure/SKILL.md +79 -0
- package/dist/skills/askr-project-structure/agents/openai.yaml +4 -0
- package/dist/skills/askr-query-mutation/SKILL.md +115 -0
- package/dist/skills/askr-query-mutation/agents/openai.yaml +4 -0
- package/dist/skills/askr-realtime-streaming/SKILL.md +76 -0
- package/dist/skills/askr-realtime-streaming/agents/openai.yaml +4 -0
- package/dist/skills/askr-resources-data/SKILL.md +100 -0
- package/dist/skills/askr-resources-data/agents/openai.yaml +4 -0
- package/dist/skills/askr-routing-layouts/SKILL.md +107 -0
- package/dist/skills/askr-routing-layouts/agents/openai.yaml +4 -0
- package/dist/skills/askr-runtime-reactivity/SKILL.md +92 -0
- package/dist/skills/askr-runtime-reactivity/agents/openai.yaml +4 -0
- package/dist/skills/askr-ssr-ssg/SKILL.md +76 -0
- package/dist/skills/askr-ssr-ssg/agents/openai.yaml +4 -0
- package/dist/skills/askr-testing-determinism/SKILL.md +75 -0
- package/dist/skills/askr-testing-determinism/agents/openai.yaml +4 -0
- package/dist/skills/askr-theming/SKILL.md +86 -0
- package/dist/skills/askr-theming/agents/openai.yaml +4 -0
- package/dist/skills/askr-ui-composition/SKILL.md +92 -0
- package/dist/skills/askr-ui-composition/agents/openai.yaml +4 -0
- package/dist/skills-Bh0mEhIx.js +682 -0
- package/dist/skills-Bh0mEhIx.js.map +1 -0
- package/dist/skills.js +3 -0
- package/dist/ssg.js +188 -0
- package/dist/ssg.js.map +1 -0
- package/dist/templates/full-stack/AGENTS.md +12 -0
- package/dist/templates/full-stack/README.md +18 -0
- package/dist/templates/full-stack/gitignore.template +4 -0
- package/dist/templates/full-stack/index.html +14 -0
- package/dist/templates/full-stack/package.json +37 -0
- package/dist/templates/full-stack/server.ts +13 -0
- package/dist/templates/full-stack/src/action-authorizations.ts +10 -0
- package/dist/templates/full-stack/src/actions/create-message.ts +10 -0
- package/dist/templates/full-stack/src/i18n.ts +8 -0
- package/dist/templates/full-stack/src/main.tsx +12 -0
- package/dist/templates/full-stack/src/pages/home.tsx +25 -0
- package/dist/templates/full-stack/src/pages/layout.tsx +33 -0
- package/dist/templates/full-stack/src/pages/not-found.tsx +4 -0
- package/dist/templates/full-stack/src/routes.tsx +20 -0
- package/dist/templates/full-stack/src/schemas.ts +11 -0
- package/dist/templates/full-stack/src/server/action-registry.ts +12 -0
- package/dist/templates/full-stack/src/server/actions/create-message.ts +14 -0
- package/dist/templates/full-stack/src/server/app.ts +66 -0
- package/dist/templates/full-stack/src/server/dependencies.ts +55 -0
- package/dist/templates/full-stack/src/server/entry-server.ts +8 -0
- package/dist/templates/full-stack/src/telemetry.ts +4 -0
- package/dist/templates/full-stack/src/vite-server.d.ts +6 -0
- package/dist/templates/full-stack/tests/actions/create-message.test.ts +13 -0
- package/dist/templates/full-stack/tsconfig.json +16 -0
- package/dist/templates/full-stack/vite.config.ts +11 -0
- package/dist/templates/spa/AGENTS.md +60 -0
- package/dist/templates/spa/README.md +96 -0
- package/dist/templates/spa/gitignore.template +16 -0
- package/dist/templates/spa/index.html +13 -0
- package/dist/templates/spa/package.json +35 -0
- package/dist/templates/spa/src/adapters/operations-client.ts +90 -0
- package/dist/templates/spa/src/components/shared/metric-card.tsx +27 -0
- package/dist/templates/spa/src/components/shared/status-badge.tsx +24 -0
- package/dist/templates/spa/src/features/operations/operations.query.ts +9 -0
- package/dist/templates/spa/src/main.tsx +10 -0
- package/dist/templates/spa/src/pages/_layout.tsx +9 -0
- package/dist/templates/spa/src/pages/_routes.tsx +27 -0
- package/dist/templates/spa/src/pages/app/_layout.tsx +94 -0
- package/dist/templates/spa/src/pages/app/_routes.tsx +10 -0
- package/dist/templates/spa/src/pages/app/admin-home.tsx +152 -0
- package/dist/templates/spa/src/pages/app/agent-runs.tsx +93 -0
- package/dist/templates/spa/src/pages/app/settings.tsx +91 -0
- package/dist/templates/spa/src/pages/auth/_layout.tsx +38 -0
- package/dist/templates/spa/src/pages/auth/_routes.tsx +6 -0
- package/dist/templates/spa/src/pages/auth/login.tsx +63 -0
- package/dist/templates/spa/src/pages/not-found.tsx +22 -0
- package/dist/templates/spa/src/pages/public/_layout.tsx +47 -0
- package/dist/templates/spa/src/pages/public/_routes.tsx +6 -0
- package/dist/templates/spa/src/pages/public/home.tsx +143 -0
- package/dist/templates/spa/src/shared/format.ts +12 -0
- package/dist/templates/spa/src/shared/navigation.ts +15 -0
- package/dist/templates/spa/src/styles/components.css +49 -0
- package/dist/templates/spa/src/styles/layout.css +192 -0
- package/dist/templates/spa/src/styles/reset.css +44 -0
- package/dist/templates/spa/src/styles/theme.css +57 -0
- package/dist/templates/spa/src/styles/tokens.css +20 -0
- package/dist/templates/spa/src/styles.css +7 -0
- package/dist/templates/spa/src/styles.d.ts +1 -0
- package/dist/templates/spa/tests/app.test.tsx +37 -0
- package/dist/templates/spa/tests/components/shared.test.tsx +12 -0
- package/dist/templates/spa/tests/resources.test.ts +22 -0
- package/dist/templates/spa/tsconfig.json +20 -0
- package/dist/templates/spa/tsconfig.node.json +10 -0
- package/dist/templates/spa/vite.config.ts +24 -0
- package/dist/templates/spa/vitest.config.ts +17 -0
- package/dist/templates/ssg/AGENTS.md +55 -0
- package/dist/templates/ssg/README.md +39 -0
- package/dist/templates/ssg/gitignore.template +17 -0
- package/dist/templates/ssg/index.html +13 -0
- package/dist/templates/ssg/package.json +35 -0
- package/dist/templates/ssg/src/app.tsx +14 -0
- package/dist/templates/ssg/src/components/badge.tsx +3 -0
- package/dist/templates/ssg/src/components/counter.tsx +30 -0
- package/dist/templates/ssg/src/components/site-shell.tsx +111 -0
- package/dist/templates/ssg/src/jsx.d.ts +23 -0
- package/dist/templates/ssg/src/main.tsx +8 -0
- package/dist/templates/ssg/src/pages/about.tsx +82 -0
- package/dist/templates/ssg/src/pages/content.tsx +63 -0
- package/dist/templates/ssg/src/pages/example.tsx +97 -0
- package/dist/templates/ssg/src/pages/home.tsx +51 -0
- package/dist/templates/ssg/src/resources/user.ts +15 -0
- package/dist/templates/ssg/src/routes.tsx +15 -0
- package/dist/templates/ssg/src/styles.css +89 -0
- package/dist/templates/ssg/src/vite-env.d.ts +5 -0
- package/dist/templates/ssg/ssg.config.ts +34 -0
- package/dist/templates/ssg/tests/app.test.tsx +19 -0
- package/dist/templates/ssg/tests/components/counter.test.tsx +18 -0
- package/dist/templates/ssg/tests/resources.test.ts +11 -0
- package/dist/templates/ssg/tests/ssg-config.test.ts +11 -0
- package/dist/templates/ssg/tsconfig.json +20 -0
- package/dist/templates/ssg/tsconfig.node.json +10 -0
- package/dist/templates/ssg/vite.config.ts +24 -0
- package/dist/templates/ssg/vitest.config.ts +17 -0
- package/dist/templates/ssr/AGENTS.md +28 -0
- package/dist/templates/ssr/README.md +38 -0
- package/dist/templates/ssr/gitignore.template +16 -0
- package/dist/templates/ssr/index.html +13 -0
- package/dist/templates/ssr/package.json +34 -0
- package/dist/templates/ssr/server.ts +16 -0
- package/dist/templates/ssr/src/app.tsx +21 -0
- package/dist/templates/ssr/src/components/counter.tsx +26 -0
- package/dist/templates/ssr/src/entry-server.tsx +10 -0
- package/dist/templates/ssr/src/main.tsx +11 -0
- package/dist/templates/ssr/src/pages/about.tsx +75 -0
- package/dist/templates/ssr/src/pages/example.tsx +113 -0
- package/dist/templates/ssr/src/pages/home.tsx +56 -0
- package/dist/templates/ssr/src/resources/user.ts +15 -0
- package/dist/templates/ssr/src/routes.tsx +13 -0
- package/dist/templates/ssr/src/styles.css +148 -0
- package/dist/templates/ssr/src/vite-server.d.ts +7 -0
- package/dist/templates/ssr/tests/app.test.tsx +24 -0
- package/dist/templates/ssr/tests/components/counter.test.tsx +13 -0
- package/dist/templates/ssr/tests/resources.test.ts +11 -0
- package/dist/templates/ssr/tsconfig.json +22 -0
- package/dist/templates/ssr/tsconfig.node.json +10 -0
- package/dist/templates/ssr/tsconfig.server.json +15 -0
- package/dist/templates/ssr/vite.config.ts +25 -0
- package/dist/templates/ssr/vitest.config.ts +13 -0
- package/dist/templates/startkit/AGENTS.md +77 -0
- package/dist/templates/startkit/README.md +192 -0
- package/dist/templates/startkit/gitignore.template +16 -0
- package/dist/templates/startkit/index.html +13 -0
- package/dist/templates/startkit/package.json +35 -0
- package/dist/templates/startkit/src/components/app-header.tsx +93 -0
- package/dist/templates/startkit/src/components/app-sidebar.tsx +95 -0
- package/dist/templates/startkit/src/components/data-table.tsx +80 -0
- package/dist/templates/startkit/src/components/empty-state.tsx +13 -0
- package/dist/templates/startkit/src/components/page-header.tsx +23 -0
- package/dist/templates/startkit/src/components/stat-card.tsx +24 -0
- package/dist/templates/startkit/src/features/accounts/account-filters.tsx +61 -0
- package/dist/templates/startkit/src/features/accounts/account-table.tsx +79 -0
- package/dist/templates/startkit/src/lib/format.ts +31 -0
- package/dist/templates/startkit/src/lib/mock-data.ts +441 -0
- package/dist/templates/startkit/src/lib/routes.ts +116 -0
- package/dist/templates/startkit/src/main.tsx +12 -0
- package/dist/templates/startkit/src/pages/_layout.tsx +56 -0
- package/dist/templates/startkit/src/pages/auth/_layout.tsx +7 -0
- package/dist/templates/startkit/src/pages/auth/login.tsx +129 -0
- package/dist/templates/startkit/src/pages/home.tsx +83 -0
- package/dist/templates/startkit/src/pages/not-found.tsx +24 -0
- package/dist/templates/startkit/src/pages/workspace/_layout.tsx +17 -0
- package/dist/templates/startkit/src/pages/workspace/accounts/index.tsx +217 -0
- package/dist/templates/startkit/src/pages/workspace/dashboard.tsx +118 -0
- package/dist/templates/startkit/src/pages/workspace/settings.tsx +218 -0
- package/dist/templates/startkit/src/router.tsx +7 -0
- package/dist/templates/startkit/src/routes/auth-config.ts +38 -0
- package/dist/templates/startkit/src/routes/auth.ts +8 -0
- package/dist/templates/startkit/src/routes/index.ts +28 -0
- package/dist/templates/startkit/src/routes/public.ts +8 -0
- package/dist/templates/startkit/src/routes/workspace/accounts.ts +8 -0
- package/dist/templates/startkit/src/routes/workspace/index.ts +14 -0
- package/dist/templates/startkit/src/styles/components.css +396 -0
- package/dist/templates/startkit/src/styles/layout.css +192 -0
- package/dist/templates/startkit/src/styles/reset.css +38 -0
- package/dist/templates/startkit/src/styles/theme.css +76 -0
- package/dist/templates/startkit/src/styles/tokens.css +67 -0
- package/dist/templates/startkit/src/styles.css +7 -0
- package/dist/templates/startkit/src/toast.ts +55 -0
- package/dist/templates/startkit/src/utils/join-classes.ts +4 -0
- package/dist/templates/startkit/src/vite-env.d.ts +5 -0
- package/dist/templates/startkit/tests/app.test.tsx +32 -0
- package/dist/templates/startkit/tests/preferences.test.ts +43 -0
- package/dist/templates/startkit/tests/resources.test.ts +82 -0
- package/dist/templates/startkit/tsconfig.json +20 -0
- package/dist/templates/startkit/tsconfig.node.json +10 -0
- package/dist/templates/startkit/vite.config.ts +32 -0
- package/dist/templates/startkit/vitest.config.ts +13 -0
- package/dist/update-DyW1na5V.js +1140 -0
- package/dist/update-DyW1na5V.js.map +1 -0
- package/dist/update.js +3 -0
- package/package.json +84 -0
- package/skills/askr-accessibility/SKILL.md +68 -0
- package/skills/askr-accessibility/agents/openai.yaml +4 -0
- package/skills/askr-agent-execution/SKILL.md +85 -0
- package/skills/askr-agent-execution/agents/openai.yaml +4 -0
- package/skills/askr-agent-workflows/SKILL.md +57 -0
- package/skills/askr-agent-workflows/agents/openai.yaml +4 -0
- package/skills/askr-api-integration/SKILL.md +79 -0
- package/skills/askr-api-integration/agents/openai.yaml +4 -0
- package/skills/askr-app-builder/SKILL.md +99 -0
- package/skills/askr-app-builder/agents/openai.yaml +4 -0
- package/skills/askr-auth-access/SKILL.md +74 -0
- package/skills/askr-auth-access/agents/openai.yaml +4 -0
- package/skills/askr-cli-vite/SKILL.md +76 -0
- package/skills/askr-cli-vite/agents/openai.yaml +4 -0
- package/skills/askr-dashboard-charts/SKILL.md +82 -0
- package/skills/askr-dashboard-charts/agents/openai.yaml +4 -0
- package/skills/askr-design-system/SKILL.md +86 -0
- package/skills/askr-design-system/agents/openai.yaml +4 -0
- package/skills/askr-env-config/SKILL.md +74 -0
- package/skills/askr-env-config/agents/openai.yaml +4 -0
- package/skills/askr-error-loading-empty/SKILL.md +89 -0
- package/skills/askr-error-loading-empty/agents/openai.yaml +4 -0
- package/skills/askr-file-upload-artifacts/SKILL.md +77 -0
- package/skills/askr-file-upload-artifacts/agents/openai.yaml +4 -0
- package/skills/askr-forms-tables-crud/SKILL.md +98 -0
- package/skills/askr-forms-tables-crud/agents/openai.yaml +4 -0
- package/skills/askr-mental-model/SKILL.md +109 -0
- package/skills/askr-mental-model/agents/openai.yaml +4 -0
- package/skills/askr-migration-react/SKILL.md +81 -0
- package/skills/askr-migration-react/agents/openai.yaml +4 -0
- package/skills/askr-observability-debugging/SKILL.md +83 -0
- package/skills/askr-observability-debugging/agents/openai.yaml +4 -0
- package/skills/askr-project-structure/SKILL.md +79 -0
- package/skills/askr-project-structure/agents/openai.yaml +4 -0
- package/skills/askr-query-mutation/SKILL.md +115 -0
- package/skills/askr-query-mutation/agents/openai.yaml +4 -0
- package/skills/askr-realtime-streaming/SKILL.md +76 -0
- package/skills/askr-realtime-streaming/agents/openai.yaml +4 -0
- package/skills/askr-resources-data/SKILL.md +100 -0
- package/skills/askr-resources-data/agents/openai.yaml +4 -0
- package/skills/askr-routing-layouts/SKILL.md +107 -0
- package/skills/askr-routing-layouts/agents/openai.yaml +4 -0
- package/skills/askr-runtime-reactivity/SKILL.md +92 -0
- package/skills/askr-runtime-reactivity/agents/openai.yaml +4 -0
- package/skills/askr-ssr-ssg/SKILL.md +76 -0
- package/skills/askr-ssr-ssg/agents/openai.yaml +4 -0
- package/skills/askr-testing-determinism/SKILL.md +75 -0
- package/skills/askr-testing-determinism/agents/openai.yaml +4 -0
- package/skills/askr-theming/SKILL.md +86 -0
- package/skills/askr-theming/agents/openai.yaml +4 -0
- package/skills/askr-ui-composition/SKILL.md +92 -0
- package/skills/askr-ui-composition/agents/openai.yaml +4 -0
- package/templates/full-stack/AGENTS.md +12 -0
- package/templates/full-stack/README.md +18 -0
- package/templates/full-stack/gitignore.template +4 -0
- package/templates/full-stack/index.html +14 -0
- package/templates/full-stack/package.json +37 -0
- package/templates/full-stack/server.ts +13 -0
- package/templates/full-stack/src/action-authorizations.ts +10 -0
- package/templates/full-stack/src/actions/create-message.ts +10 -0
- package/templates/full-stack/src/i18n.ts +8 -0
- package/templates/full-stack/src/main.tsx +12 -0
- package/templates/full-stack/src/pages/home.tsx +25 -0
- package/templates/full-stack/src/pages/layout.tsx +33 -0
- package/templates/full-stack/src/pages/not-found.tsx +4 -0
- package/templates/full-stack/src/routes.tsx +20 -0
- package/templates/full-stack/src/schemas.ts +11 -0
- package/templates/full-stack/src/server/action-registry.ts +12 -0
- package/templates/full-stack/src/server/actions/create-message.ts +14 -0
- package/templates/full-stack/src/server/app.ts +66 -0
- package/templates/full-stack/src/server/dependencies.ts +55 -0
- package/templates/full-stack/src/server/entry-server.ts +8 -0
- package/templates/full-stack/src/telemetry.ts +4 -0
- package/templates/full-stack/src/vite-server.d.ts +6 -0
- package/templates/full-stack/tests/actions/create-message.test.ts +13 -0
- package/templates/full-stack/tsconfig.json +16 -0
- package/templates/full-stack/vite.config.ts +11 -0
- package/templates/spa/AGENTS.md +60 -0
- package/templates/spa/README.md +96 -0
- package/templates/spa/gitignore.template +16 -0
- package/templates/spa/index.html +13 -0
- package/templates/spa/package.json +35 -0
- package/templates/spa/src/adapters/operations-client.ts +90 -0
- package/templates/spa/src/components/shared/metric-card.tsx +27 -0
- package/templates/spa/src/components/shared/status-badge.tsx +24 -0
- package/templates/spa/src/features/operations/operations.query.ts +9 -0
- package/templates/spa/src/main.tsx +10 -0
- package/templates/spa/src/pages/_layout.tsx +9 -0
- package/templates/spa/src/pages/_routes.tsx +27 -0
- package/templates/spa/src/pages/app/_layout.tsx +94 -0
- package/templates/spa/src/pages/app/_routes.tsx +10 -0
- package/templates/spa/src/pages/app/admin-home.tsx +152 -0
- package/templates/spa/src/pages/app/agent-runs.tsx +93 -0
- package/templates/spa/src/pages/app/settings.tsx +91 -0
- package/templates/spa/src/pages/auth/_layout.tsx +38 -0
- package/templates/spa/src/pages/auth/_routes.tsx +6 -0
- package/templates/spa/src/pages/auth/login.tsx +63 -0
- package/templates/spa/src/pages/not-found.tsx +22 -0
- package/templates/spa/src/pages/public/_layout.tsx +47 -0
- package/templates/spa/src/pages/public/_routes.tsx +6 -0
- package/templates/spa/src/pages/public/home.tsx +143 -0
- package/templates/spa/src/shared/format.ts +12 -0
- package/templates/spa/src/shared/navigation.ts +15 -0
- package/templates/spa/src/styles/components.css +49 -0
- package/templates/spa/src/styles/layout.css +192 -0
- package/templates/spa/src/styles/reset.css +44 -0
- package/templates/spa/src/styles/theme.css +57 -0
- package/templates/spa/src/styles/tokens.css +20 -0
- package/templates/spa/src/styles.css +7 -0
- package/templates/spa/src/styles.d.ts +1 -0
- package/templates/spa/tests/app.test.tsx +37 -0
- package/templates/spa/tests/components/shared.test.tsx +12 -0
- package/templates/spa/tests/resources.test.ts +22 -0
- package/templates/spa/tsconfig.json +20 -0
- package/templates/spa/tsconfig.node.json +10 -0
- package/templates/spa/vite.config.ts +24 -0
- package/templates/spa/vitest.config.ts +17 -0
- package/templates/ssg/AGENTS.md +55 -0
- package/templates/ssg/README.md +39 -0
- package/templates/ssg/gitignore.template +17 -0
- package/templates/ssg/index.html +13 -0
- package/templates/ssg/package.json +35 -0
- package/templates/ssg/src/app.tsx +14 -0
- package/templates/ssg/src/components/badge.tsx +3 -0
- package/templates/ssg/src/components/counter.tsx +30 -0
- package/templates/ssg/src/components/site-shell.tsx +111 -0
- package/templates/ssg/src/jsx.d.ts +23 -0
- package/templates/ssg/src/main.tsx +8 -0
- package/templates/ssg/src/pages/about.tsx +82 -0
- package/templates/ssg/src/pages/content.tsx +63 -0
- package/templates/ssg/src/pages/example.tsx +97 -0
- package/templates/ssg/src/pages/home.tsx +51 -0
- package/templates/ssg/src/resources/user.ts +15 -0
- package/templates/ssg/src/routes.tsx +15 -0
- package/templates/ssg/src/styles.css +89 -0
- package/templates/ssg/src/vite-env.d.ts +5 -0
- package/templates/ssg/ssg.config.ts +34 -0
- package/templates/ssg/tests/app.test.tsx +19 -0
- package/templates/ssg/tests/components/counter.test.tsx +18 -0
- package/templates/ssg/tests/resources.test.ts +11 -0
- package/templates/ssg/tests/ssg-config.test.ts +11 -0
- package/templates/ssg/tsconfig.json +20 -0
- package/templates/ssg/tsconfig.node.json +10 -0
- package/templates/ssg/vite.config.ts +24 -0
- package/templates/ssg/vitest.config.ts +17 -0
- package/templates/ssr/AGENTS.md +28 -0
- package/templates/ssr/README.md +38 -0
- package/templates/ssr/gitignore.template +16 -0
- package/templates/ssr/index.html +13 -0
- package/templates/ssr/package.json +34 -0
- package/templates/ssr/server.ts +16 -0
- package/templates/ssr/src/app.tsx +21 -0
- package/templates/ssr/src/components/counter.tsx +26 -0
- package/templates/ssr/src/entry-server.tsx +10 -0
- package/templates/ssr/src/main.tsx +11 -0
- package/templates/ssr/src/pages/about.tsx +75 -0
- package/templates/ssr/src/pages/example.tsx +113 -0
- package/templates/ssr/src/pages/home.tsx +56 -0
- package/templates/ssr/src/resources/user.ts +15 -0
- package/templates/ssr/src/routes.tsx +13 -0
- package/templates/ssr/src/styles.css +148 -0
- package/templates/ssr/src/vite-server.d.ts +7 -0
- package/templates/ssr/tests/app.test.tsx +24 -0
- package/templates/ssr/tests/components/counter.test.tsx +13 -0
- package/templates/ssr/tests/resources.test.ts +11 -0
- package/templates/ssr/tsconfig.json +22 -0
- package/templates/ssr/tsconfig.node.json +10 -0
- package/templates/ssr/tsconfig.server.json +15 -0
- package/templates/ssr/vite.config.ts +25 -0
- package/templates/ssr/vitest.config.ts +13 -0
- package/templates/startkit/AGENTS.md +77 -0
- package/templates/startkit/README.md +192 -0
- package/templates/startkit/gitignore.template +16 -0
- package/templates/startkit/index.html +13 -0
- package/templates/startkit/package.json +35 -0
- package/templates/startkit/src/components/app-header.tsx +93 -0
- package/templates/startkit/src/components/app-sidebar.tsx +95 -0
- package/templates/startkit/src/components/data-table.tsx +80 -0
- package/templates/startkit/src/components/empty-state.tsx +13 -0
- package/templates/startkit/src/components/page-header.tsx +23 -0
- package/templates/startkit/src/components/stat-card.tsx +24 -0
- package/templates/startkit/src/features/accounts/account-filters.tsx +61 -0
- package/templates/startkit/src/features/accounts/account-table.tsx +79 -0
- package/templates/startkit/src/lib/format.ts +31 -0
- package/templates/startkit/src/lib/mock-data.ts +441 -0
- package/templates/startkit/src/lib/routes.ts +116 -0
- package/templates/startkit/src/main.tsx +12 -0
- package/templates/startkit/src/pages/_layout.tsx +56 -0
- package/templates/startkit/src/pages/auth/_layout.tsx +7 -0
- package/templates/startkit/src/pages/auth/login.tsx +129 -0
- package/templates/startkit/src/pages/home.tsx +83 -0
- package/templates/startkit/src/pages/not-found.tsx +24 -0
- package/templates/startkit/src/pages/workspace/_layout.tsx +17 -0
- package/templates/startkit/src/pages/workspace/accounts/index.tsx +217 -0
- package/templates/startkit/src/pages/workspace/dashboard.tsx +118 -0
- package/templates/startkit/src/pages/workspace/settings.tsx +218 -0
- package/templates/startkit/src/router.tsx +7 -0
- package/templates/startkit/src/routes/auth-config.ts +38 -0
- package/templates/startkit/src/routes/auth.ts +8 -0
- package/templates/startkit/src/routes/index.ts +28 -0
- package/templates/startkit/src/routes/public.ts +8 -0
- package/templates/startkit/src/routes/workspace/accounts.ts +8 -0
- package/templates/startkit/src/routes/workspace/index.ts +14 -0
- package/templates/startkit/src/styles/components.css +396 -0
- package/templates/startkit/src/styles/layout.css +192 -0
- package/templates/startkit/src/styles/reset.css +38 -0
- package/templates/startkit/src/styles/theme.css +76 -0
- package/templates/startkit/src/styles/tokens.css +67 -0
- package/templates/startkit/src/styles.css +7 -0
- package/templates/startkit/src/toast.ts +55 -0
- package/templates/startkit/src/utils/join-classes.ts +4 -0
- package/templates/startkit/src/vite-env.d.ts +5 -0
- package/templates/startkit/tests/app.test.tsx +32 -0
- package/templates/startkit/tests/preferences.test.ts +43 -0
- package/templates/startkit/tests/resources.test.ts +82 -0
- package/templates/startkit/tsconfig.json +20 -0
- package/templates/startkit/tsconfig.node.json +10 -0
- package/templates/startkit/vite.config.ts +32 -0
- package/templates/startkit/vitest.config.ts +13 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: askr-realtime-streaming
|
|
3
|
+
description: Use when building Askr realtime UX with SSE, WebSocket, event streams, reconnects, cursors, cancellation, backpressure-aware UI, optimistic updates, projection lag, and event-sourced state.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Askr Realtime Streaming
|
|
7
|
+
|
|
8
|
+
Use this for live data, event streams, and projection-driven UI. The goal is one clear stream owner, safe reconnect behavior, and bounded DOM and memory cost.
|
|
9
|
+
|
|
10
|
+
## Use This When
|
|
11
|
+
|
|
12
|
+
- You need SSE, WebSocket, or long-lived event streaming.
|
|
13
|
+
- The UI depends on reconnect, cursor, or projection-lag behavior.
|
|
14
|
+
- A timeline, operator log, or live table needs bounded updates.
|
|
15
|
+
- You need to reconcile stream events with queries or feature-owned state.
|
|
16
|
+
|
|
17
|
+
## Inspect First
|
|
18
|
+
|
|
19
|
+
- Adapter support for SSE, WebSocket, polling, or long-running requests
|
|
20
|
+
- Event schema: event ID, sequence, aggregate ID, type, timestamp, and payload
|
|
21
|
+
- Query keys and mutation invalidation affected by streamed events
|
|
22
|
+
- Reconnect and resume requirements
|
|
23
|
+
|
|
24
|
+
## Do This In Order
|
|
25
|
+
|
|
26
|
+
1. Own the stream lifecycle in a route or feature container, not a leaf row or list item.
|
|
27
|
+
2. Preserve `lastEventId` or cursor for reconnect.
|
|
28
|
+
3. Apply events idempotently by event ID or sequence.
|
|
29
|
+
4. Detect gaps and refetch or invalidate the affected read model instead of guessing.
|
|
30
|
+
5. Bound long-running buffers so memory and DOM cost stay predictable.
|
|
31
|
+
6. Show `connected`, `reconnecting`, `stale`, or `failed` state when freshness matters.
|
|
32
|
+
|
|
33
|
+
## Copy This Shape
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const MAX_EVENTS = 200;
|
|
37
|
+
|
|
38
|
+
function applyEvent(nextEvent: StreamEvent) {
|
|
39
|
+
setEvents((current) => {
|
|
40
|
+
if (current.some((event) => event.id === nextEvent.id)) {
|
|
41
|
+
return current;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return [...current, nextEvent].slice(-MAX_EVENTS);
|
|
45
|
+
});
|
|
46
|
+
setLastEventId(nextEvent.id);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Never Do These
|
|
51
|
+
|
|
52
|
+
- Assuming streamed events arrive exactly once or in order.
|
|
53
|
+
- Clearing the screen during reconnect.
|
|
54
|
+
- Unbounded in-memory event lists.
|
|
55
|
+
- Mixing transport code into pages or components.
|
|
56
|
+
- Treating command success as projection success.
|
|
57
|
+
|
|
58
|
+
## Validate
|
|
59
|
+
|
|
60
|
+
- Reconnect resumes from a cursor or falls back to refetch.
|
|
61
|
+
- Duplicate and out-of-order events are safe.
|
|
62
|
+
- Projection lag has visible UI.
|
|
63
|
+
- Stream teardown happens on navigation or unmount.
|
|
64
|
+
|
|
65
|
+
## Done When
|
|
66
|
+
|
|
67
|
+
- Stream ownership is clear and not buried in leaf components.
|
|
68
|
+
- Reconnect, duplicate, gap, and teardown paths are handled.
|
|
69
|
+
- Memory and DOM cost stay bounded for long-running screens.
|
|
70
|
+
- Projection success is never inferred from command success alone.
|
|
71
|
+
|
|
72
|
+
## Handoff
|
|
73
|
+
|
|
74
|
+
- Use `askr-query-mutation` when stream events reconcile shared queries.
|
|
75
|
+
- Use `askr-api-integration` when cursor, event ID, or transport shape is unclear.
|
|
76
|
+
- Use `askr-observability-debugging` when reconnect failures or duplicate events need operator diagnostics.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: askr-resources-data
|
|
3
|
+
description: Use when loading lifecycle-aware async data in Askr with resource, cancellation signals, pending/error/value states, refresh behavior, route/container ownership, consistency-aware refreshes, and async anti-pattern cleanup.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Askr Resources Data
|
|
7
|
+
|
|
8
|
+
Use this when one route or feature container owns an async read lifecycle. The goal is one clear async owner, explicit cancellation, and truthful refresh behavior.
|
|
9
|
+
|
|
10
|
+
## Use This When
|
|
11
|
+
|
|
12
|
+
- One route or feature container owns the read.
|
|
13
|
+
- The read should cancel on unmount, navigation, or dependency change.
|
|
14
|
+
- Children need plain data props instead of owning their own fetches.
|
|
15
|
+
- The data does not need to live as shared keyed state across screens.
|
|
16
|
+
|
|
17
|
+
## Inspect First
|
|
18
|
+
|
|
19
|
+
- The nearest route or feature container that already owns async work.
|
|
20
|
+
- The adapter or service that should receive `signal`.
|
|
21
|
+
- Existing refresh or retry controls for the same surface.
|
|
22
|
+
- Existing tests that cover load, retry, or cancellation behavior.
|
|
23
|
+
|
|
24
|
+
## Use `resource()` Only When
|
|
25
|
+
|
|
26
|
+
- The read belongs to one owner in one route or feature container.
|
|
27
|
+
- The owner should cancel stale requests automatically.
|
|
28
|
+
- The screen can keep old data during refresh when safe.
|
|
29
|
+
|
|
30
|
+
If the same keyed server state must coordinate across screens, stop and use `askr-query-mutation` instead.
|
|
31
|
+
|
|
32
|
+
## Do This In Order
|
|
33
|
+
|
|
34
|
+
1. Put the `resource()` call in the smallest route or feature container that owns the data.
|
|
35
|
+
2. Pass `signal` into the adapter or fetch layer.
|
|
36
|
+
3. Keep route handlers synchronous.
|
|
37
|
+
4. Pass `value`, `pending`, `error`, and `refresh()` downward as plain props.
|
|
38
|
+
5. Keep stale data visible during refresh unless that would be unsafe.
|
|
39
|
+
|
|
40
|
+
## Copy This Shape
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { resource } from "@askrjs/askr/resources";
|
|
44
|
+
|
|
45
|
+
function UserCard({ id }: { id: string }) {
|
|
46
|
+
const user = resource(
|
|
47
|
+
async ({ signal }) => {
|
|
48
|
+
const response = await fetch(`/api/users/${id}`, { signal });
|
|
49
|
+
return response.json();
|
|
50
|
+
},
|
|
51
|
+
[id],
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (user.pending || !user.value) return <p>Loading...</p>;
|
|
55
|
+
if (user.error) return <p role="alert">Unable to load user.</p>;
|
|
56
|
+
return <p>{user.value.name}</p>;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Owner Pattern
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
function AccountsPage() {
|
|
64
|
+
const accounts = resource(({ signal }) => loadAccounts({ signal }), []);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<AccountsScreen
|
|
68
|
+
accounts={accounts.value}
|
|
69
|
+
pending={accounts.pending}
|
|
70
|
+
error={accounts.error}
|
|
71
|
+
onRefresh={() => accounts.refresh()}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- Async route components.
|
|
78
|
+
- `useEffect`-style data loading.
|
|
79
|
+
- Custom cancellation tokens when `signal` exists.
|
|
80
|
+
- Hidden loading or error paths.
|
|
81
|
+
- Fetching in generic UI primitives.
|
|
82
|
+
- Route-local async ownership that should actually be shared keyed state.
|
|
83
|
+
|
|
84
|
+
## Validate
|
|
85
|
+
|
|
86
|
+
- The async owner is the smallest container that needs the data.
|
|
87
|
+
- `signal` reaches the cancellable work.
|
|
88
|
+
- Loading, empty, error, and retry paths are explicit.
|
|
89
|
+
- Route handlers stay synchronous.
|
|
90
|
+
- Refresh behavior is honest about stale data and projection lag.
|
|
91
|
+
|
|
92
|
+
## Done When
|
|
93
|
+
|
|
94
|
+
- The screen did not grow a parallel shared-state layer.
|
|
95
|
+
|
|
96
|
+
## Handoff
|
|
97
|
+
|
|
98
|
+
- Use `askr-query-mutation` when this data must become shared keyed state.
|
|
99
|
+
- Use `askr-error-loading-empty` when the hard part is truthful state representation.
|
|
100
|
+
- Use `askr-testing-determinism` to validate cancellation, retry, and refresh behavior.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: askr-routing-layouts
|
|
3
|
+
description: Use when defining Askr routes, route groups, page shells, index routes, fallback routes, navigation, auth requirements, route loaders, layout boundaries, or SPA/SSR/SSG shared route trees.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Askr Routing Layouts
|
|
7
|
+
|
|
8
|
+
Use this for route registration, shell ownership, route metadata, and navigation. The goal is one obvious route tree that is registered before boot.
|
|
9
|
+
|
|
10
|
+
## Use This When
|
|
11
|
+
|
|
12
|
+
- You are adding, moving, or protecting a route.
|
|
13
|
+
- You are changing a shell or layout boundary.
|
|
14
|
+
- You need to attach an auth requirement or route policy.
|
|
15
|
+
- You need to add route-aware navigation.
|
|
16
|
+
|
|
17
|
+
## Inspect First
|
|
18
|
+
|
|
19
|
+
- `src/main.tsx`
|
|
20
|
+
- The app's route registry file
|
|
21
|
+
- The nearest branch route file and `_layout.tsx`
|
|
22
|
+
- Existing navigation components for the same branch
|
|
23
|
+
- Tests that already cover routing or layout retention
|
|
24
|
+
|
|
25
|
+
## Choose The Owner
|
|
26
|
+
|
|
27
|
+
- `group()` for inherited layout, auth requirements, or policies without a path segment.
|
|
28
|
+
- `page()` for a pathful shell that renders child route content.
|
|
29
|
+
- `route()` for a leaf route.
|
|
30
|
+
- `index()` only inside a `page()` scope.
|
|
31
|
+
- `fallback()` at the root or inside a `page()` scope that owns the fallback.
|
|
32
|
+
|
|
33
|
+
## Do This In Order
|
|
34
|
+
|
|
35
|
+
1. Register the route in the existing route tree before app boot.
|
|
36
|
+
2. Put auth requirements and policies on the narrowest route or group that owns them.
|
|
37
|
+
3. Keep route components synchronous and put async work inside route-owned components or features.
|
|
38
|
+
4. Keep navigation in `Link`, `navigate()`, and `currentRoute()` instead of local copies of route state.
|
|
39
|
+
|
|
40
|
+
## Copy This Shape
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { requireUser } from "@askrjs/auth";
|
|
44
|
+
import { createRouteRegistry, fallback, group } from "@askrjs/askr/router";
|
|
45
|
+
|
|
46
|
+
export const pageRegistry = createRouteRegistry(() => {
|
|
47
|
+
group({ layout: RootLayout }, () => {
|
|
48
|
+
group({ layout: PublicLayout }, () => {
|
|
49
|
+
registerPublicRoutes();
|
|
50
|
+
});
|
|
51
|
+
group({ layout: AppLayout, auth: requireUser() }, () => {
|
|
52
|
+
registerAppRoutes();
|
|
53
|
+
});
|
|
54
|
+
fallback(NotFoundPage);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Nested Example
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { requirePermission } from "@askrjs/auth";
|
|
63
|
+
import { fallback, index, page, route } from "@askrjs/askr/router";
|
|
64
|
+
|
|
65
|
+
export function registerWorkspaceRoutes(): void {
|
|
66
|
+
page("/workspaces/{workspaceId}", WorkspaceLayout, () => {
|
|
67
|
+
index(WorkspaceOverviewPage);
|
|
68
|
+
route("settings", WorkspaceSettingsPage, {
|
|
69
|
+
auth: requirePermission("workspace.manage"),
|
|
70
|
+
});
|
|
71
|
+
route("members", WorkspaceMembersPage, {
|
|
72
|
+
auth: requirePermission("workspace.read"),
|
|
73
|
+
});
|
|
74
|
+
fallback(WorkspaceNotFoundPage);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use relative child paths inside `page()`. Put requirements and policies on the narrowest route or group that owns them.
|
|
80
|
+
|
|
81
|
+
## Never Do These
|
|
82
|
+
|
|
83
|
+
- Registering routes during render.
|
|
84
|
+
- Calling `route()` inside components; use `currentRoute()` there.
|
|
85
|
+
- Nesting `page()` inside `page()`.
|
|
86
|
+
- Absolute child route paths inside `page()`.
|
|
87
|
+
- Treating `group()` as a fallback scope.
|
|
88
|
+
- Putting theme styling decisions in route registration.
|
|
89
|
+
- Building a second router or page-local auth gate when route metadata already owns it.
|
|
90
|
+
|
|
91
|
+
## Validate
|
|
92
|
+
|
|
93
|
+
- The route tree is registered before boot.
|
|
94
|
+
- Shared route behavior lives in `group()` instead of repeated route-local checks.
|
|
95
|
+
- Child routes under `page()` use relative paths.
|
|
96
|
+
- Fallback scope is explicit.
|
|
97
|
+
- Navigation uses router primitives instead of local state copies.
|
|
98
|
+
|
|
99
|
+
## Done When
|
|
100
|
+
|
|
101
|
+
- The route tree is still the only route tree in the app.
|
|
102
|
+
|
|
103
|
+
## Handoff
|
|
104
|
+
|
|
105
|
+
- Use `askr-auth-access` when the next step is session or permission behavior.
|
|
106
|
+
- Use `askr-project-structure` when routing work also adds new files.
|
|
107
|
+
- Use `askr-testing-determinism` to validate route identity, fallback behavior, and layout retention.
|
|
@@ -0,0 +1,92 @@
|
|
|
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.
|
|
@@ -0,0 +1,76 @@
|
|
|
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.
|
|
@@ -0,0 +1,75 @@
|
|
|
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.
|
|
@@ -0,0 +1,86 @@
|
|
|
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.
|