@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 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","names":[],"sources":["../src/bin/create.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { spawnSync } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport readline from \"node:readline\";\nimport { fileURLToPath } from \"node:url\";\nimport { isDirectExecution } from \"./is-direct-execution\";\nimport { installBundledSkills } from \"./skills\";\n\ntype CliIo = Pick<Console, \"error\" | \"log\">;\ntype PackageManager = \"npm\" | \"yarn\";\n\nconst TEMPLATE_LABELS = {\n \"full-stack\": \"Full-stack\",\n spa: \"SPA\",\n ssr: \"SSR\",\n ssg: \"SSG\",\n startkit: \"StartKit\",\n} as const;\n\ntype TemplateType = keyof typeof TEMPLATE_LABELS;\n\ntype Capability =\n | \"agent-workflows\"\n | \"api-integration\"\n | \"auth-access\"\n | \"dashboard-charts\"\n | \"design-system\"\n | \"file-upload-artifacts\"\n | \"forms-tables-crud\"\n | \"query-mutation\"\n | \"realtime-streaming\"\n | \"routing-layouts\"\n | \"ssr-ssg\";\n\ntype TemplateSelectionMode = \"default\" | \"explicit\" | \"interactive\" | \"prompt\";\n\ninterface ParsedArgs {\n positional: string[];\n install: boolean;\n help: boolean;\n promptText: string;\n skills: boolean;\n errors: string[];\n}\n\ninterface TemplateSelection {\n mode: TemplateSelectionMode;\n reason: string;\n matchedTerms?: string[];\n}\n\ninterface Blueprint {\n schemaVersion: number;\n appName: string;\n template: TemplateType;\n sourcePrompt: string | null;\n templateSelection: TemplateSelection;\n capabilities: Capability[];\n recommendedSkills: string[];\n guardrails: string[];\n}\n\nconst TEMPLATE_TYPES = new Set<TemplateType>([\"startkit\", \"spa\", \"ssr\", \"ssg\", \"full-stack\"]);\nconst TEMPLATE_ORDER: TemplateType[] = [\"startkit\", \"spa\", \"ssr\", \"ssg\", \"full-stack\"];\nconst PROMPT_STOP_WORDS = new Set([\n \"a\",\n \"an\",\n \"and\",\n \"app\",\n \"application\",\n \"build\",\n \"create\",\n \"for\",\n \"from\",\n \"in\",\n \"into\",\n \"me\",\n \"of\",\n \"or\",\n \"platform\",\n \"product\",\n \"that\",\n \"the\",\n \"to\",\n \"with\",\n]);\nconst TEMPLATE_DEFAULT_CAPABILITIES: Record<TemplateType, Capability[]> = {\n \"full-stack\": [\n \"routing-layouts\",\n \"ssr-ssg\",\n \"api-integration\",\n \"auth-access\",\n \"forms-tables-crud\",\n \"query-mutation\",\n \"design-system\",\n ],\n spa: [\"routing-layouts\", \"dashboard-charts\", \"agent-workflows\", \"design-system\"],\n ssr: [\"routing-layouts\", \"ssr-ssg\", \"query-mutation\", \"design-system\"],\n ssg: [\"routing-layouts\", \"ssr-ssg\", \"design-system\"],\n startkit: [\"routing-layouts\", \"auth-access\", \"forms-tables-crud\", \"design-system\"],\n};\nconst TEMPLATE_PROMPT_RULES: Array<{\n template: TemplateType;\n reason: string;\n terms: string[];\n weight: number;\n}> = [\n {\n template: \"full-stack\",\n reason: \"Prompt requires server APIs, authenticated actions, and request-time rendering.\",\n terms: [\n \"api and ssr\",\n \"authenticated api\",\n \"backend and frontend\",\n \"full stack\",\n \"full-stack\",\n \"server action\",\n ],\n weight: 6,\n },\n {\n template: \"ssg\",\n reason: \"Prompt emphasizes static content or documentation publishing.\",\n terms: [\n \"blog\",\n \"content\",\n \"docs\",\n \"documentation\",\n \"knowledge base\",\n \"landing page\",\n \"marketing\",\n \"static\",\n ],\n weight: 4,\n },\n {\n template: \"ssr\",\n reason: \"Prompt emphasizes server rendering or request-time HTML.\",\n terms: [\n \"edge render\",\n \"personalized seo\",\n \"request-time\",\n \"server render\",\n \"server rendered\",\n \"server-rendered\",\n \"ssr\",\n ],\n weight: 4,\n },\n {\n template: \"spa\",\n reason: \"Prompt emphasizes interactive workflows, control planes, or agent operations.\",\n terms: [\n \"agent\",\n \"approval\",\n \"assistant\",\n \"console\",\n \"control plane\",\n \"dashboard\",\n \"operations\",\n \"realtime\",\n \"stream\",\n \"workflow\",\n ],\n weight: 3,\n },\n {\n template: \"startkit\",\n reason: \"Prompt emphasizes auth, workspace, or back-office product surfaces.\",\n terms: [\n \"account\",\n \"admin\",\n \"auth\",\n \"billing\",\n \"login\",\n \"portal\",\n \"settings\",\n \"tenant\",\n \"workspace\",\n ],\n weight: 3,\n },\n];\nconst CAPABILITY_RULES: Array<{ capability: Capability; terms: string[] }> = [\n {\n capability: \"agent-workflows\",\n terms: [\"agent\", \"approval\", \"artifact\", \"assistant\", \"prompt\", \"run\", \"tool\", \"workflow\"],\n },\n { capability: \"api-integration\", terms: [\"api\", \"backend\", \"graphql\", \"rest\", \"sdk\", \"webhook\"] },\n {\n capability: \"auth-access\",\n terms: [\"access\", \"auth\", \"login\", \"permission\", \"role\", \"session\", \"tenant\", \"workspace\"],\n },\n {\n capability: \"dashboard-charts\",\n terms: [\"analytics\", \"chart\", \"dashboard\", \"kpi\", \"metric\", \"report\"],\n },\n {\n capability: \"file-upload-artifacts\",\n terms: [\"artifact\", \"attachment\", \"document\", \"file\", \"upload\"],\n },\n { capability: \"forms-tables-crud\", terms: [\"crud\", \"edit\", \"form\", \"record\", \"table\"] },\n {\n capability: \"query-mutation\",\n terms: [\"cache\", \"data\", \"mutation\", \"query\", \"resource\", \"sync\"],\n },\n {\n capability: \"realtime-streaming\",\n terms: [\"event\", \"live\", \"realtime\", \"stream\", \"subscription\", \"websocket\"],\n },\n {\n capability: \"ssr-ssg\",\n terms: [\"content\", \"docs\", \"seo\", \"server render\", \"ssg\", \"ssr\", \"static\"],\n },\n];\nconst CAPABILITY_LABELS: Record<Capability, string> = {\n \"agent-workflows\": \"Agent workflows\",\n \"api-integration\": \"API integration\",\n \"auth-access\": \"Authentication and access\",\n \"dashboard-charts\": \"Dashboards and charts\",\n \"design-system\": \"Design system and theming\",\n \"file-upload-artifacts\": \"Files and artifacts\",\n \"forms-tables-crud\": \"Forms, tables, and CRUD\",\n \"query-mutation\": \"Queries and mutations\",\n \"realtime-streaming\": \"Realtime and streaming\",\n \"routing-layouts\": \"Routing and layouts\",\n \"ssr-ssg\": \"SSR or SSG\",\n};\nconst CORE_RECOMMENDED_SKILLS = [\n \"askr-agent-execution\",\n \"askr-mental-model\",\n \"askr-project-structure\",\n \"askr-routing-layouts\",\n \"askr-runtime-reactivity\",\n \"askr-testing-determinism\",\n];\nconst CAPABILITY_SKILL_MAP: Record<Capability, string[]> = {\n \"agent-workflows\": [\"askr-agent-workflows\", \"askr-error-loading-empty\"],\n \"api-integration\": [\"askr-api-integration\", \"askr-env-config\"],\n \"auth-access\": [\"askr-auth-access\"],\n \"dashboard-charts\": [\"askr-dashboard-charts\"],\n \"design-system\": [\"askr-theming\"],\n \"file-upload-artifacts\": [\"askr-file-upload-artifacts\"],\n \"forms-tables-crud\": [\"askr-forms-tables-crud\", \"askr-error-loading-empty\"],\n \"query-mutation\": [\"askr-resources-data\", \"askr-query-mutation\", \"askr-error-loading-empty\"],\n \"realtime-streaming\": [\"askr-realtime-streaming\"],\n \"routing-layouts\": [\"askr-routing-layouts\"],\n \"ssr-ssg\": [\"askr-ssr-ssg\"],\n};\nconst FOUNDATION_SKILL_SEQUENCE = [\n \"askr-agent-execution\",\n \"askr-mental-model\",\n \"askr-project-structure\",\n \"askr-routing-layouts\",\n \"askr-runtime-reactivity\",\n];\nconst VALIDATION_SKILLS = [\"askr-testing-determinism\"];\nconst BROAD_PLANNING_SKILLS = [\"askr-app-builder\"];\nconst SKILL_SEQUENCE = [\n ...FOUNDATION_SKILL_SEQUENCE,\n \"askr-resources-data\",\n \"askr-query-mutation\",\n \"askr-error-loading-empty\",\n \"askr-forms-tables-crud\",\n \"askr-auth-access\",\n \"askr-agent-workflows\",\n \"askr-dashboard-charts\",\n \"askr-api-integration\",\n \"askr-env-config\",\n \"askr-file-upload-artifacts\",\n \"askr-realtime-streaming\",\n \"askr-ssr-ssg\",\n \"askr-theming\",\n \"askr-ui-composition\",\n \"askr-design-system\",\n \"askr-accessibility\",\n \"askr-observability-debugging\",\n ...VALIDATION_SKILLS,\n ...BROAD_PLANNING_SKILLS,\n];\nconst SKILL_SUMMARIES: Record<string, string> = {\n \"askr-accessibility\": \"Review keyboard, focus, announcements, and semantic coverage.\",\n \"askr-agent-execution\": \"Read the repo in the right order and validate narrowly.\",\n \"askr-agent-workflows\": \"Model runs, approvals, timelines, and audit-friendly states.\",\n \"askr-api-integration\": \"Keep DTO mapping, retries, and transport boundaries out of pages.\",\n \"askr-app-builder\": \"Use only when a task spans multiple app surfaces and needs a broad plan.\",\n \"askr-auth-access\": \"Keep access rules in route metadata and auth workflows, not pages.\",\n \"askr-dashboard-charts\": \"Add charts without bypassing route, state, or theming conventions.\",\n \"askr-design-system\": \"Use only when shaping reusable product patterns beyond one screen.\",\n \"askr-env-config\": \"Keep environment-specific configuration and secrets handling outside UI.\",\n \"askr-error-loading-empty\":\n \"Represent loading, empty, stale, retry, and pending-write truthfully.\",\n \"askr-file-upload-artifacts\":\n \"Add uploads and artifact flows without breaking ownership boundaries.\",\n \"askr-forms-tables-crud\":\n \"Build forms, tables, filters, and destructive actions with stable ownership.\",\n \"askr-mental-model\": \"Choose native Askr primitives and reject React-shaped defaults.\",\n \"askr-observability-debugging\": \"Preserve correlation IDs and diagnosable failure context.\",\n \"askr-project-structure\": \"Place routes, features, shared helpers, and adapters predictably.\",\n \"askr-query-mutation\": \"Use shared keyed reads and mutations with explicit invalidation.\",\n \"askr-realtime-streaming\": \"Handle reconnects, cursors, and bounded live lists.\",\n \"askr-resources-data\": \"Own route-scoped async reads with resource() and cancellation.\",\n \"askr-routing-layouts\": \"Keep one obvious route tree, shell boundary, and navigation path.\",\n \"askr-runtime-reactivity\": \"Apply state(), derive(), selector(), and For with stable call order.\",\n \"askr-ssr-ssg\": \"Keep routes deterministic and render paths hydration-safe.\",\n \"askr-testing-determinism\":\n \"Finish with the narrowest executable check for the changed contract.\",\n \"askr-theming\": \"Apply the theme layer, tokens, and shell primitives before custom styling.\",\n \"askr-ui-composition\": \"Use askr-ui behavior primitives before inventing local components.\",\n};\nconst TEMPLATE_INSPECT_PATHS: Record<TemplateType, string[]> = {\n \"full-stack\": [\n \"AGENTS.md\",\n \"src/routes.tsx\",\n \"src/actions/create-message.ts\",\n \"src/schemas.ts\",\n \"src/server/app.ts\",\n \"src/server/action-registry.ts\",\n \"src/server/dependencies.ts\",\n \"src/server/entry-server.ts\",\n \"server.ts\",\n ],\n spa: [\n \"AGENTS.md\",\n \"src/main.tsx\",\n \"src/pages/_layout.tsx\",\n \"src/pages/_routes.tsx\",\n \"src/pages/public/_layout.tsx\",\n \"src/pages/public/_routes.tsx\",\n \"src/pages/public/home.tsx\",\n \"src/pages/auth/_layout.tsx\",\n \"src/pages/auth/_routes.tsx\",\n \"src/pages/auth/login.tsx\",\n \"src/pages/app/_layout.tsx\",\n \"src/pages/app/_routes.tsx\",\n \"src/pages/app/admin-home.tsx\",\n \"src/styles.css\",\n \"src/styles/reset.css\",\n \"src/styles/tokens.css\",\n \"src/styles/theme.css\",\n \"src/styles/layout.css\",\n \"src/styles/components.css\",\n ],\n ssr: [\"AGENTS.md\", \"src/main.tsx\", \"src/server-entry.tsx\", \"src/pages/_routes.tsx\", \"server.ts\"],\n ssg: [\n \"AGENTS.md\",\n \"src/main.tsx\",\n \"src/routes.tsx\",\n \"src/components/site-shell.tsx\",\n \"src/pages/home.tsx\",\n \"ssg.config.ts\",\n ],\n startkit: [\n \"AGENTS.md\",\n \"src/main.tsx\",\n \"src/router.tsx\",\n \"src/routes/index.ts\",\n \"src/pages/workspace/_layout.tsx\",\n ],\n};\nconst TEMPLATE_GOLDEN_EXAMPLES: Record<TemplateType, string[]> = {\n \"full-stack\": [\n \"src/routes.tsx\",\n \"src/pages/home.tsx\",\n \"src/actions/create-message.ts\",\n \"src/server/action-registry.ts\",\n \"src/server/app.ts\",\n ],\n spa: [\n \"src/pages/public/home.tsx\",\n \"src/pages/auth/login.tsx\",\n \"src/pages/app/admin-home.tsx\",\n \"src/features/operations/operations.query.ts\",\n ],\n ssr: [\"src/main.tsx\", \"src/pages/_routes.tsx\", \"server.ts\"],\n ssg: [\"src/main.tsx\", \"src/routes.tsx\", \"src/components/site-shell.tsx\", \"ssg.config.ts\"],\n startkit: [\n \"src/routes/index.ts\",\n \"src/pages/workspace/accounts/index.tsx\",\n \"src/features/accounts/account-table.tsx\",\n ],\n};\nconst BLUEPRINT_GUARDRAILS = [\n \"Keep the route-first file structure so new features land where builders expect them.\",\n \"Use state(), derive(), resource(), and selector() for reactive state and derived views.\",\n \"Use For for keyed or dynamic list rendering instead of ad hoc array mapping.\",\n \"Keep adapters, queries, and mutations outside page files so data boundaries stay deterministic.\",\n \"Model loading, empty, error, and success states explicitly and keep them testable.\",\n];\n\nfunction isTemplateType(value: string): value is TemplateType {\n return TEMPLATE_TYPES.has(value as TemplateType);\n}\n\nfunction helpText(): string {\n return [\n \"askr create - Project scaffolding for Askr\",\n \"\",\n \"Usage:\",\n \" askr create [template] <name> [--prompt <text>] [--no-install] [--no-skills]\",\n \" askr create --prompt <text> [name] [--no-install] [--no-skills]\",\n \"\",\n \"Templates:\",\n \" startkit, spa, ssr, ssg, full-stack\",\n \"\",\n \"Options:\",\n \" --prompt <text> Infer the best template from a product prompt and emit a builder blueprint\",\n \" --no-install Skip dependency installation\",\n \" --no-skills Skip bundled Askr skill installation into skills/\",\n \" --help, -h Show help\",\n \"\",\n \"Examples:\",\n \" askr create startkit my-app\",\n \" askr create full-stack my-app\",\n \" askr create startkit acme-dashboard\",\n ' askr create --prompt \"Agent workflow console with approvals and analytics\"',\n ].join(\"\\n\");\n}\n\nasync function prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolveAnswer) => {\n rl.question(question, (answer) => {\n rl.close();\n resolveAnswer(answer);\n });\n });\n}\n\nfunction detectPm(): PackageManager {\n const ua = process.env.npm_config_user_agent || \"\";\n if (ua.startsWith(\"yarn\")) return \"yarn\";\n if (ua.startsWith(\"npm\")) return \"npm\";\n\n return \"npm\";\n}\n\nconst TEMPLATE_COPY_EXCLUDES = new Set([\n \"node_modules\",\n \"dist\",\n \".vite\",\n \"coverage\",\n \"package-lock.json\",\n \"pnpm-lock.yaml\",\n \"yarn.lock\",\n \"bun.lock\",\n \"bun.lockb\",\n]);\n\nasync function copyDir(\n src: string,\n dest: string,\n replacements: { appName: string },\n): Promise<void> {\n const entries = await fs.readdir(src, { withFileTypes: true });\n await fs.mkdir(dest, { recursive: true });\n\n for (const entry of entries) {\n if (TEMPLATE_COPY_EXCLUDES.has(entry.name)) {\n continue;\n }\n\n const srcPath = path.join(src, entry.name);\n const sourceName = entry.name === \"gitignore.template\" ? \".gitignore\" : entry.name;\n const outputName = sourceName.replace(/\\{\\{\\s*appName\\s*\\}\\}/g, replacements.appName);\n const destPath = path.join(dest, outputName);\n\n if (entry.isDirectory()) {\n await copyDir(srcPath, destPath, replacements);\n continue;\n }\n\n const buffer = await fs.readFile(srcPath);\n const content = buffer.toString(\"utf8\");\n const replaced = content\n .replace(/\\{\\{\\s*appName\\s*\\}\\}/g, replacements.appName)\n .replace(/\\{\\{appName\\}\\}/g, replacements.appName);\n\n await fs.writeFile(destPath, replaced, \"utf8\");\n }\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n return Boolean(await fs.stat(filePath).catch(() => null));\n}\n\nfunction cliDir(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\nasync function findTemplateDir(templateType: TemplateType): Promise<string> {\n const base = cliDir();\n const candidates = [\n path.resolve(base, \"..\", \"..\", \"templates\", templateType),\n path.resolve(base, \"..\", \"templates\", templateType),\n path.resolve(base, \"templates\", templateType),\n ];\n\n for (const candidate of candidates) {\n if (await pathExists(candidate)) {\n return candidate;\n }\n }\n\n return candidates[0];\n}\n\nfunction parseArgs(args: string[]): ParsedArgs {\n const positional: string[] = [];\n let install = true;\n let help = false;\n let promptText = \"\";\n let skills = true;\n const errors: string[] = [];\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === \"--no-install\") {\n install = false;\n } else if (arg === \"--no-skills\") {\n skills = false;\n } else if (arg === \"--prompt\") {\n if (i + 1 >= args.length) {\n errors.push(\"Missing value for --prompt\");\n } else {\n promptText = normalizePromptText(args[i + 1]);\n i += 1;\n }\n } else if (arg === \"--help\" || arg === \"-h\") {\n help = true;\n } else {\n positional.push(arg);\n }\n }\n\n return { positional, install, help, promptText, skills, errors };\n}\n\nfunction normalizePromptText(promptText: string): string {\n return promptText.trim().replace(/\\s+/g, \" \");\n}\n\nfunction normalizeSearchText(value: string): string {\n return ` ${value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \" \")\n .trim()} `;\n}\n\nfunction scoreTerms(text: string, terms: string[]): string[] {\n const normalizedText = normalizeSearchText(text);\n\n return terms.filter((term) => {\n const normalizedTerm = normalizeSearchText(term).trim();\n if (!normalizedTerm) {\n return false;\n }\n\n return (\n normalizedText.includes(` ${normalizedTerm} `) ||\n normalizedText.includes(` ${normalizedTerm}s `) ||\n normalizedText.includes(` ${normalizedTerm}es `)\n );\n });\n}\n\nfunction inferTemplateFromPrompt(promptText: string): {\n matchedTerms: string[];\n reason: string;\n templateType: TemplateType;\n} {\n const normalizedPrompt = promptText.toLowerCase();\n const templateScores: Record<TemplateType, number> = {\n \"full-stack\": 0,\n startkit: 1,\n spa: 0,\n ssr: 0,\n ssg: 0,\n };\n const templateMatches: Record<TemplateType, string[]> = {\n \"full-stack\": [],\n startkit: [],\n spa: [],\n ssr: [],\n ssg: [],\n };\n const templateReasons: Record<TemplateType, string> = {\n \"full-stack\": \"Prompt requires server APIs, authenticated actions, and request-time rendering.\",\n startkit:\n \"No stronger prompt signal was detected, so the CLI defaulted to the full app startkit.\",\n spa: \"Prompt emphasizes interactive workflows, control planes, or agent operations.\",\n ssr: \"Prompt emphasizes server rendering or request-time HTML.\",\n ssg: \"Prompt emphasizes static content or documentation publishing.\",\n };\n\n for (const rule of TEMPLATE_PROMPT_RULES) {\n const matches = scoreTerms(normalizedPrompt, rule.terms);\n if (matches.length === 0) {\n continue;\n }\n\n templateScores[rule.template] += matches.length * rule.weight;\n templateMatches[rule.template].push(...matches);\n templateReasons[rule.template] = rule.reason;\n }\n\n let selectedTemplate = TEMPLATE_ORDER[0];\n for (const templateType of TEMPLATE_ORDER.slice(1)) {\n if (templateScores[templateType] > templateScores[selectedTemplate]) {\n selectedTemplate = templateType;\n }\n }\n\n return {\n matchedTerms: [...new Set(templateMatches[selectedTemplate])],\n reason: templateReasons[selectedTemplate],\n templateType: selectedTemplate,\n };\n}\n\nfunction deriveAppNameFromPrompt(promptText: string): string {\n const tokens = promptText\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \" \")\n .split(/\\s+/)\n .map((token) => token.trim())\n .filter(Boolean)\n .filter((token) => !PROMPT_STOP_WORDS.has(token))\n .filter((token) => token.length > 2);\n\n const nameParts: string[] = [];\n for (const token of tokens) {\n if (!nameParts.includes(token)) {\n nameParts.push(token);\n }\n\n if (nameParts.length === 3) {\n break;\n }\n }\n\n return nameParts.join(\"-\") || \"askr-app\";\n}\n\nfunction buildCapabilities(templateType: TemplateType, promptText: string): Capability[] {\n const capabilities = new Set<Capability>(TEMPLATE_DEFAULT_CAPABILITIES[templateType] || []);\n\n if (promptText) {\n const normalizedPrompt = promptText.toLowerCase();\n for (const rule of CAPABILITY_RULES) {\n if (scoreTerms(normalizedPrompt, rule.terms).length > 0) {\n capabilities.add(rule.capability);\n }\n }\n }\n\n return (Object.keys(CAPABILITY_LABELS) as Capability[]).filter((capability) =>\n capabilities.has(capability),\n );\n}\n\nfunction buildRecommendedSkills(options: {\n capabilities: Capability[];\n promptText: string;\n}): string[] {\n const { capabilities, promptText } = options;\n const recommendedSkills = new Set<string>(CORE_RECOMMENDED_SKILLS);\n\n for (const capability of capabilities) {\n for (const skill of CAPABILITY_SKILL_MAP[capability] || []) {\n recommendedSkills.add(skill);\n }\n }\n\n if (promptText.trim().length > 0) {\n recommendedSkills.add(\"askr-app-builder\");\n }\n\n const orderedSkills = SKILL_SEQUENCE.filter((skill) => recommendedSkills.has(skill));\n const remainingSkills = [...recommendedSkills]\n .filter((skill) => !SKILL_SEQUENCE.includes(skill))\n .sort();\n\n return [...orderedSkills, ...remainingSkills];\n}\n\nfunction renderSkillBullets(skills: string[]): string[] {\n return skills.map((skill) => {\n const summary = SKILL_SUMMARIES[skill];\n return summary ? `- ${skill} - ${summary}` : `- ${skill}`;\n });\n}\n\nfunction pickSkills(source: string[], allowed: string[]): string[] {\n const allowedSet = new Set(allowed);\n return source.filter((skill) => allowedSet.has(skill));\n}\n\nfunction pickWorkflowSkills(skills: string[]): string[] {\n const excluded = new Set([\n ...FOUNDATION_SKILL_SEQUENCE,\n ...VALIDATION_SKILLS,\n ...BROAD_PLANNING_SKILLS,\n ]);\n return skills.filter((skill) => !excluded.has(skill));\n}\n\nfunction renderListSection(title: string, items: string[]): string[] {\n if (items.length === 0) {\n return [];\n }\n\n return [title, ...items, \"\"];\n}\n\nfunction buildFollowUpPrompts(capabilities: Capability[]): string[] {\n const suggestions: string[] = [];\n\n if (capabilities.includes(\"agent-workflows\")) {\n suggestions.push(\n \"Add an agent run detail screen with prompt, timeline, approvals, and artifact history.\",\n );\n }\n\n if (capabilities.includes(\"dashboard-charts\")) {\n suggestions.push(\n \"Connect dashboard metrics through adapters and queries while preserving loading, empty, and error states.\",\n );\n }\n\n if (capabilities.includes(\"auth-access\")) {\n suggestions.push(\n \"Wire route access and session state without moving auth logic into page components.\",\n );\n }\n\n if (capabilities.includes(\"forms-tables-crud\")) {\n suggestions.push(\n \"Add a CRUD feature using feature-scoped forms, tables, and deterministic tests.\",\n );\n }\n\n if (capabilities.includes(\"ssr-ssg\")) {\n suggestions.push(\n \"Extend SSR or SSG routes while keeping route registration deterministic and environment-safe.\",\n );\n }\n\n suggestions.push(\n \"Use the bundled Askr skills before adding new features so generated code stays idiomatic.\",\n );\n return suggestions.slice(0, 4);\n}\n\nfunction buildBlueprint(options: {\n appName: string;\n promptText: string;\n templateSelection: TemplateSelection;\n templateType: TemplateType;\n}): Blueprint {\n const capabilities = buildCapabilities(options.templateType, options.promptText);\n return {\n schemaVersion: 1,\n appName: options.appName,\n template: options.templateType,\n sourcePrompt: options.promptText || null,\n templateSelection: options.templateSelection,\n capabilities,\n recommendedSkills: buildRecommendedSkills({ capabilities, promptText: options.promptText }),\n guardrails: BLUEPRINT_GUARDRAILS,\n };\n}\n\nfunction renderPromptBlock(promptText: string | null): string {\n if (!promptText) {\n return \"No app prompt was provided. This project was scaffolded from explicit CLI arguments.\";\n }\n\n return promptText\n .split(/\\r?\\n/)\n .filter(Boolean)\n .map((line) => `> ${line}`)\n .join(\"\\n\");\n}\n\nfunction renderBuilderBrief(blueprint: Blueprint): string {\n const foundationSkills = pickSkills(blueprint.recommendedSkills, FOUNDATION_SKILL_SEQUENCE);\n const workflowSkills = pickWorkflowSkills(blueprint.recommendedSkills);\n const validationSkills = pickSkills(blueprint.recommendedSkills, VALIDATION_SKILLS);\n const planningSkills = pickSkills(blueprint.recommendedSkills, BROAD_PLANNING_SKILLS);\n\n return [\n \"# Askr Builder Brief\",\n \"\",\n `- App name: ${blueprint.appName}`,\n `- Template: ${blueprint.template}`,\n `- Selection mode: ${blueprint.templateSelection.mode}`,\n `- Selection reason: ${blueprint.templateSelection.reason}`,\n \"\",\n \"## Prompt\",\n renderPromptBlock(blueprint.sourcePrompt),\n \"\",\n \"## Capabilities\",\n ...blueprint.capabilities.map((capability) => `- ${CAPABILITY_LABELS[capability]}`),\n \"\",\n \"## Inspect First In This Scaffold\",\n ...TEMPLATE_INSPECT_PATHS[blueprint.template].map((item) => `- ${item}`),\n \"\",\n \"## Skill Execution Order\",\n ...renderListSection(\"### Start here\", renderSkillBullets(foundationSkills)),\n ...renderListSection(\n \"### Pull in next when the task needs it\",\n renderSkillBullets(workflowSkills),\n ),\n ...renderListSection(\"### Finish with validation\", renderSkillBullets(validationSkills)),\n ...renderListSection(\n \"### Use only for broad multi-surface planning\",\n renderSkillBullets(planningSkills),\n ),\n \"## All Recommended Skills\",\n ...blueprint.recommendedSkills.map((skill) => `- ${skill}`),\n \"\",\n \"## Golden Examples In This Scaffold\",\n ...TEMPLATE_GOLDEN_EXAMPLES[blueprint.template].map((item) => `- ${item}`),\n \"\",\n \"## Guardrails\",\n ...blueprint.guardrails.map((guardrail) => `- ${guardrail}`),\n \"\",\n \"## Suggested builder prompts\",\n ...buildFollowUpPrompts(blueprint.capabilities).map((item) => `- ${item}`),\n \"\",\n ].join(\"\\n\");\n}\n\nasync function writeBlueprintFiles(target: string, blueprint: Blueprint): Promise<void> {\n const blueprintRoot = path.join(target, \".askr\");\n await fs.mkdir(blueprintRoot, { recursive: true });\n await fs.writeFile(\n path.join(blueprintRoot, \"blueprint.json\"),\n `${JSON.stringify(blueprint, null, 2)}\\n`,\n \"utf8\",\n );\n await fs.writeFile(\n path.join(blueprintRoot, \"builder-brief.md\"),\n renderBuilderBrief(blueprint),\n \"utf8\",\n );\n}\n\nexport async function runCreateCli(\n args: string[] = process.argv.slice(2),\n io: CliIo = console,\n): Promise<number> {\n const parsed = parseArgs(args);\n\n if (parsed.errors.length > 0) {\n for (const message of parsed.errors) {\n io.error(message);\n }\n return 1;\n }\n\n if (parsed.help) {\n io.log(helpText());\n return 0;\n }\n\n let templateType: TemplateType = \"startkit\";\n let name = \"\";\n let templateSelection: TemplateSelection = {\n mode: \"default\",\n reason:\n \"No stronger prompt signal was detected, so the CLI defaulted to the full app startkit.\",\n };\n const explicitTemplate = parsed.positional.length > 0 && isTemplateType(parsed.positional[0]);\n\n if (parsed.positional.length > 0) {\n const first = parsed.positional[0];\n if (isTemplateType(first)) {\n templateType = first;\n name = parsed.positional[1] || \"\";\n templateSelection = {\n mode: \"explicit\",\n reason: `Template '${first}' was provided explicitly on the command line.`,\n };\n } else {\n name = first;\n }\n }\n\n if (!explicitTemplate && parsed.promptText) {\n const inferredTemplate = inferTemplateFromPrompt(parsed.promptText);\n templateType = inferredTemplate.templateType;\n templateSelection = {\n mode: \"prompt\",\n reason: inferredTemplate.reason,\n matchedTerms: inferredTemplate.matchedTerms,\n };\n }\n\n if (!name && parsed.promptText) {\n name = deriveAppNameFromPrompt(parsed.promptText);\n }\n\n if (!name) {\n if (!explicitTemplate) {\n io.log(\"Available templates: startkit, spa, ssr, ssg, full-stack\");\n io.log(\"\");\n\n const selectedTemplate =\n (await prompt(\"Template type (startkit/spa/ssr/ssg/full-stack) [startkit]: \")).trim() ||\n \"startkit\";\n if (!isTemplateType(selectedTemplate)) {\n io.error(\"Invalid template type\");\n return 1;\n }\n\n templateType = selectedTemplate;\n templateSelection = {\n mode: \"interactive\",\n reason: `Template '${selectedTemplate}' was chosen interactively.`,\n };\n }\n\n name = (await prompt(\"App name: \")).trim();\n }\n\n if (!name) {\n io.error(\"App name is required\");\n return 1;\n }\n\n const target = path.resolve(process.cwd(), name);\n const templateDir = await findTemplateDir(templateType);\n\n try {\n await fs.access(templateDir);\n } catch {\n io.error(`Template '${templateType}' not found at ${templateDir}`);\n return 1;\n }\n\n try {\n const stat = await fs.stat(target).catch(() => null);\n if (stat) {\n const files = await fs.readdir(target).catch(() => [] as string[]);\n if (files.length > 0) {\n io.error(`Directory ${target} already exists and is not empty.`);\n return 1;\n }\n }\n } catch (error) {\n io.error(\"Failed to access target directory\");\n io.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n\n const blueprint = buildBlueprint({\n appName: name,\n promptText: parsed.promptText,\n templateSelection,\n templateType,\n });\n\n if (parsed.promptText) {\n io.log(`Prompt profile selected ${TEMPLATE_LABELS[templateType]} for ${name}.`);\n io.log(`Reason: ${templateSelection.reason}`);\n if (\n Array.isArray(templateSelection.matchedTerms) &&\n templateSelection.matchedTerms.length > 0\n ) {\n io.log(`Matched prompt terms: ${templateSelection.matchedTerms.join(\", \")}`);\n }\n io.log(\"\");\n }\n\n io.log(`Creating ${TEMPLATE_LABELS[templateType]} project: ${name}...`);\n io.log(\"\");\n\n try {\n await copyDir(templateDir, target, { appName: name });\n } catch (error) {\n io.error(\"Failed to copy template\");\n io.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n\n try {\n await writeBlueprintFiles(target, blueprint);\n } catch (error) {\n io.error(\"Failed to write project blueprint\");\n io.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n\n if (parsed.skills) {\n try {\n const { bundledNames, targetSkillsDir } = await installBundledSkills({\n cwd: target,\n force: true,\n });\n io.log(\n `Installed ${bundledNames.length} bundled Askr skills into ${path.basename(targetSkillsDir)}/`,\n );\n io.log(\"\");\n } catch (error) {\n io.error(\"Failed to install bundled Askr skills\");\n io.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n } else {\n io.log(\"Skipping bundled Askr skill installation (--no-skills)\");\n io.log(\"\");\n }\n\n if (!parsed.install) {\n io.log(\"Skipping dependency installation (--no-install)\");\n io.log(\"\");\n io.log(\"Next steps:\");\n io.log(` cd ${name}`);\n io.log(\" review .askr/builder-brief.md\");\n if (!parsed.skills) {\n io.log(\" askr skills install\");\n }\n io.log(\" npm install\");\n io.log(\" npm run dev\");\n return 0;\n }\n\n const pm = detectPm();\n io.log(`Installing dependencies with ${pm}...`);\n io.log(\"\");\n\n const result = spawnSync(pm, [\"install\"], {\n cwd: target,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n\n io.log(\"\");\n io.log(`Success! Created ${name}`);\n io.log(\"\");\n\n if (result.status !== 0) {\n io.log(\"Dependency installation failed. Please run manually:\");\n io.log(` cd ${name}`);\n io.log(\" review .askr/builder-brief.md\");\n if (!parsed.skills) {\n io.log(\" askr skills install\");\n }\n io.log(` ${pm} install`);\n io.log(` ${pm} run dev`);\n return 1;\n }\n\n io.log(\"Next steps:\");\n io.log(` cd ${name}`);\n io.log(\" review .askr/builder-brief.md\");\n if (!parsed.skills) {\n io.log(\" askr skills install\");\n }\n io.log(` ${pm} run dev`);\n return 0;\n}\n\nasync function main(): Promise<void> {\n const code = await runCreateCli(process.argv.slice(2));\n process.exit(code);\n}\n\nif (isDirectExecution(import.meta.url)) {\n void main();\n}\n"],"mappings":"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;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,GAAG;CACH,GAAG;AACL;AACA,MAAM,kBAA0C;CAC9C,sBAAsB;CACtB,wBAAwB;CACxB,wBAAwB;CACxB,wBAAwB;CACxB,oBAAoB;CACpB,oBAAoB;CACpB,yBAAyB;CACzB,sBAAsB;CACtB,mBAAmB;CACnB,4BACE;CACF,8BACE;CACF,0BACE;CACF,qBAAqB;CACrB,gCAAgC;CAChC,0BAA0B;CAC1B,uBAAuB;CACvB,2BAA2B;CAC3B,uBAAuB;CACvB,wBAAwB;CACxB,2BAA2B;CAC3B,gBAAgB;CAChB,4BACE;CACF,gBAAgB;CAChB,uBAAuB;AACzB;AACA,MAAM,yBAAyD;CAC7D,cAAc;EACZ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,KAAK;EAAC;EAAa;EAAgB;EAAwB;EAAyB;CAAW;CAC/F,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;EACR;EACA;EACA;EACA;EACA;CACF;AACF;AACA,MAAM,2BAA2D;CAC/D,cAAc;EACZ;EACA;EACA;EACA;EACA;CACF;CACA,KAAK;EACH;EACA;EACA;EACA;CACF;CACA,KAAK;EAAC;EAAgB;EAAyB;CAAW;CAC1D,KAAK;EAAC;EAAgB;EAAkB;EAAiC;CAAe;CACxF,UAAU;EACR;EACA;EACA;CACF;AACF;AACA,MAAM,uBAAuB;CAC3B;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,eAAe,OAAsC;CAC5D,OAAO,eAAe,IAAI,KAAqB;AACjD;AAEA,SAAS,WAAmB;CAC1B,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,eAAe,OAAO,UAAmC;CACvD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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
//#region src/bin/is-direct-execution.ts
|
|
5
|
+
function normalizePath(filePath) {
|
|
6
|
+
const resolvedPath = resolve(filePath);
|
|
7
|
+
try {
|
|
8
|
+
return typeof realpathSync.native === "function" ? realpathSync.native(resolvedPath) : realpathSync(resolvedPath);
|
|
9
|
+
} catch {
|
|
10
|
+
return resolvedPath;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function isDirectExecution(moduleUrl, argvPath = process.argv[1]) {
|
|
14
|
+
if (!argvPath) return false;
|
|
15
|
+
return normalizePath(argvPath) === normalizePath(fileURLToPath(moduleUrl));
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { isDirectExecution as t };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=is-direct-execution-Cdlr-ZUl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-direct-execution-Cdlr-ZUl.js","names":[],"sources":["../src/bin/is-direct-execution.ts"],"sourcesContent":["import { realpathSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction normalizePath(filePath: string): string {\n const resolvedPath = resolve(filePath);\n\n try {\n return typeof realpathSync.native === \"function\"\n ? realpathSync.native(resolvedPath)\n : realpathSync(resolvedPath);\n } catch {\n return resolvedPath;\n }\n}\n\nexport function isDirectExecution(\n moduleUrl: string,\n argvPath: string | undefined = process.argv[1],\n): boolean {\n if (!argvPath) {\n return false;\n }\n\n return normalizePath(argvPath) === normalizePath(fileURLToPath(moduleUrl));\n}\n"],"mappings":";;;;AAIA,SAAS,cAAc,UAA0B;CAC/C,MAAM,eAAe,QAAQ,QAAQ;CAErC,IAAI;EACF,OAAO,OAAO,aAAa,WAAW,aAClC,aAAa,OAAO,YAAY,IAChC,aAAa,YAAY;CAC/B,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,kBACd,WACA,WAA+B,QAAQ,KAAK,IACnC;CACT,IAAI,CAAC,UACH,OAAO;CAGT,OAAO,cAAc,QAAQ,MAAM,cAAc,cAAc,SAAS,CAAC;AAC3E"}
|
package/dist/openapi.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { t as isDirectExecution } from "./is-direct-execution-Cdlr-ZUl.js";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { tsImport } from "tsx/esm/api";
|
|
7
|
+
import { stringify } from "yaml";
|
|
8
|
+
//#region src/bin/openapi.ts
|
|
9
|
+
const helpText = `askr openapi - Generate an OpenAPI YAML artifact
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
askr openapi [--entry <path>] [--output <path>] [--check]
|
|
13
|
+
|
|
14
|
+
Options:
|
|
15
|
+
--entry <path> TypeScript API module (default: ./src/api.ts)
|
|
16
|
+
--output <path> YAML artifact (default: ./openapi.yml)
|
|
17
|
+
--check Fail when the artifact is missing or byte-stale; never write
|
|
18
|
+
--help, -h Show help
|
|
19
|
+
`;
|
|
20
|
+
const defaultDeps = {
|
|
21
|
+
cwd: () => process.cwd(),
|
|
22
|
+
importModule: (filePath) => tsImport(pathToFileURL(filePath).href, import.meta.url),
|
|
23
|
+
readFile: (filePath) => fs.readFile(filePath, "utf8"),
|
|
24
|
+
mkdir: (directory) => fs.mkdir(directory, { recursive: true }).then(() => void 0),
|
|
25
|
+
writeFile: (filePath, contents) => fs.writeFile(filePath, contents, "utf8"),
|
|
26
|
+
rename: (from, to) => fs.rename(from, to),
|
|
27
|
+
rm: (filePath) => fs.rm(filePath, { force: true }),
|
|
28
|
+
temporarySuffix: () => `${process.pid}.${Date.now()}`
|
|
29
|
+
};
|
|
30
|
+
function parseOpenApiArgs(args) {
|
|
31
|
+
const parsed = {
|
|
32
|
+
entry: "./src/api.ts",
|
|
33
|
+
output: "./openapi.yml",
|
|
34
|
+
check: false,
|
|
35
|
+
help: false
|
|
36
|
+
};
|
|
37
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
38
|
+
const value = args[index];
|
|
39
|
+
if (value === "--entry" || value === "--output") {
|
|
40
|
+
const next = args[index + 1];
|
|
41
|
+
if (!next) throw new Error(`${value} requires a path`);
|
|
42
|
+
if (value === "--entry") parsed.entry = next;
|
|
43
|
+
else parsed.output = next;
|
|
44
|
+
index += 1;
|
|
45
|
+
} else if (value === "--check") parsed.check = true;
|
|
46
|
+
else if (value === "--help" || value === "-h") parsed.help = true;
|
|
47
|
+
else throw new Error(`Unknown option: ${value}`);
|
|
48
|
+
}
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
function exporterFrom(moduleValue) {
|
|
52
|
+
if (!moduleValue || typeof moduleValue !== "object") throw new Error("API module must have a default export with toOpenApiDocument()");
|
|
53
|
+
let exported = moduleValue.default;
|
|
54
|
+
for (let depth = 0; depth < 3 && exported && typeof exported === "object" && typeof exported.toOpenApiDocument !== "function" && "default" in exported; depth += 1) exported = exported.default;
|
|
55
|
+
if (!exported || typeof exported !== "object" || typeof exported.toOpenApiDocument !== "function") throw new Error("API module must have a default export with toOpenApiDocument()");
|
|
56
|
+
return exported;
|
|
57
|
+
}
|
|
58
|
+
function serializeOpenApi(document) {
|
|
59
|
+
return `${stringify(document, {
|
|
60
|
+
aliasDuplicateObjects: false,
|
|
61
|
+
lineWidth: 0
|
|
62
|
+
}).replace(/\n+$/, "")}\n`;
|
|
63
|
+
}
|
|
64
|
+
async function generate(entry, deps) {
|
|
65
|
+
const document = exporterFrom(await deps.importModule(entry)).toOpenApiDocument();
|
|
66
|
+
if (!document || typeof document !== "object" || Array.isArray(document)) throw new Error("toOpenApiDocument() must return an OpenAPI document object");
|
|
67
|
+
return serializeOpenApi(document);
|
|
68
|
+
}
|
|
69
|
+
async function atomicWrite(output, contents, deps) {
|
|
70
|
+
await deps.mkdir(path.dirname(output));
|
|
71
|
+
const temporary = `${output}.${deps.temporarySuffix()}.tmp`;
|
|
72
|
+
try {
|
|
73
|
+
await deps.writeFile(temporary, contents);
|
|
74
|
+
await deps.rename(temporary, output);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
await deps.rm(temporary);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function runOpenApiCli(args = process.argv.slice(2), io = console, overrides = {}) {
|
|
81
|
+
const deps = {
|
|
82
|
+
...defaultDeps,
|
|
83
|
+
...overrides
|
|
84
|
+
};
|
|
85
|
+
try {
|
|
86
|
+
const parsed = parseOpenApiArgs(args);
|
|
87
|
+
if (parsed.help) {
|
|
88
|
+
io.log(helpText.trimEnd());
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
const entry = path.resolve(deps.cwd(), parsed.entry);
|
|
92
|
+
const output = path.resolve(deps.cwd(), parsed.output);
|
|
93
|
+
const expected = await generate(entry, deps);
|
|
94
|
+
if (parsed.check) {
|
|
95
|
+
let actual;
|
|
96
|
+
try {
|
|
97
|
+
actual = await deps.readFile(output);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (error.code === "ENOENT") {
|
|
100
|
+
io.error(`OpenAPI artifact is missing: ${output}`);
|
|
101
|
+
return 1;
|
|
102
|
+
}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
if (actual !== expected) {
|
|
106
|
+
io.error(`OpenAPI artifact is stale: ${output}`);
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
io.log(`OpenAPI artifact is current: ${output}`);
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
await atomicWrite(output, expected, deps);
|
|
113
|
+
io.log(`Generated OpenAPI artifact: ${output}`);
|
|
114
|
+
return 0;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
io.error(error instanceof Error ? error.message : String(error));
|
|
117
|
+
return 1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function main() {
|
|
121
|
+
process.exit(await runOpenApiCli(process.argv.slice(2)));
|
|
122
|
+
}
|
|
123
|
+
if (isDirectExecution(import.meta.url)) main();
|
|
124
|
+
//#endregion
|
|
125
|
+
export { parseOpenApiArgs, runOpenApiCli, serializeOpenApi };
|
|
126
|
+
|
|
127
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","names":[],"sources":["../src/bin/openapi.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { tsImport } from \"tsx/esm/api\";\nimport { stringify } from \"yaml\";\nimport { isDirectExecution } from \"./is-direct-execution\";\n\ntype CliIo = Pick<Console, \"error\" | \"log\">;\n\ninterface ParsedArgs {\n entry: string;\n output: string;\n check: boolean;\n help: boolean;\n}\n\ninterface DocumentExporter {\n toOpenApiDocument(): unknown;\n}\n\ninterface OpenApiDeps {\n cwd(): string;\n importModule(filePath: string): Promise<unknown>;\n readFile(filePath: string): Promise<string>;\n mkdir(directory: string): Promise<void>;\n writeFile(filePath: string, contents: string): Promise<void>;\n rename(from: string, to: string): Promise<void>;\n rm(filePath: string): Promise<void>;\n temporarySuffix(): string;\n}\n\nconst helpText = `askr openapi - Generate an OpenAPI YAML artifact\n\nUsage:\n askr openapi [--entry <path>] [--output <path>] [--check]\n\nOptions:\n --entry <path> TypeScript API module (default: ./src/api.ts)\n --output <path> YAML artifact (default: ./openapi.yml)\n --check Fail when the artifact is missing or byte-stale; never write\n --help, -h Show help\n`;\n\nconst defaultDeps: OpenApiDeps = {\n cwd: () => process.cwd(),\n importModule: (filePath) => tsImport(pathToFileURL(filePath).href, import.meta.url),\n readFile: (filePath) => fs.readFile(filePath, \"utf8\"),\n mkdir: (directory) => fs.mkdir(directory, { recursive: true }).then(() => undefined),\n writeFile: (filePath, contents) => fs.writeFile(filePath, contents, \"utf8\"),\n rename: (from, to) => fs.rename(from, to),\n rm: (filePath) => fs.rm(filePath, { force: true }),\n temporarySuffix: () => `${process.pid}.${Date.now()}`,\n};\n\nexport function parseOpenApiArgs(args: readonly string[]): ParsedArgs {\n const parsed: ParsedArgs = {\n entry: \"./src/api.ts\",\n output: \"./openapi.yml\",\n check: false,\n help: false,\n };\n for (let index = 0; index < args.length; index += 1) {\n const value = args[index];\n if (value === \"--entry\" || value === \"--output\") {\n const next = args[index + 1];\n if (!next) throw new Error(`${value} requires a path`);\n if (value === \"--entry\") parsed.entry = next;\n else parsed.output = next;\n index += 1;\n } else if (value === \"--check\") parsed.check = true;\n else if (value === \"--help\" || value === \"-h\") parsed.help = true;\n else throw new Error(`Unknown option: ${value}`);\n }\n return parsed;\n}\n\nfunction exporterFrom(moduleValue: unknown): DocumentExporter {\n if (!moduleValue || typeof moduleValue !== \"object\") {\n throw new Error(\"API module must have a default export with toOpenApiDocument()\");\n }\n let exported = (moduleValue as { default?: unknown }).default;\n for (\n let depth = 0;\n depth < 3 &&\n exported &&\n typeof exported === \"object\" &&\n typeof (exported as Partial<DocumentExporter>).toOpenApiDocument !== \"function\" &&\n \"default\" in exported;\n depth += 1\n ) {\n exported = (exported as { default?: unknown }).default;\n }\n if (\n !exported ||\n typeof exported !== \"object\" ||\n typeof (exported as Partial<DocumentExporter>).toOpenApiDocument !== \"function\"\n ) {\n throw new Error(\"API module must have a default export with toOpenApiDocument()\");\n }\n return exported as DocumentExporter;\n}\n\nexport function serializeOpenApi(document: unknown): string {\n const yaml = stringify(document, { aliasDuplicateObjects: false, lineWidth: 0 });\n return `${yaml.replace(/\\n+$/, \"\")}\\n`;\n}\n\nasync function generate(entry: string, deps: OpenApiDeps): Promise<string> {\n const moduleValue = await deps.importModule(entry);\n const document = exporterFrom(moduleValue).toOpenApiDocument();\n if (!document || typeof document !== \"object\" || Array.isArray(document)) {\n throw new Error(\"toOpenApiDocument() must return an OpenAPI document object\");\n }\n return serializeOpenApi(document);\n}\n\nasync function atomicWrite(output: string, contents: string, deps: OpenApiDeps): Promise<void> {\n await deps.mkdir(path.dirname(output));\n const temporary = `${output}.${deps.temporarySuffix()}.tmp`;\n try {\n await deps.writeFile(temporary, contents);\n await deps.rename(temporary, output);\n } catch (error) {\n await deps.rm(temporary);\n throw error;\n }\n}\n\nexport async function runOpenApiCli(\n args: string[] = process.argv.slice(2),\n io: CliIo = console,\n overrides: Partial<OpenApiDeps> = {},\n): Promise<number> {\n const deps = { ...defaultDeps, ...overrides };\n try {\n const parsed = parseOpenApiArgs(args);\n if (parsed.help) {\n io.log(helpText.trimEnd());\n return 0;\n }\n const entry = path.resolve(deps.cwd(), parsed.entry);\n const output = path.resolve(deps.cwd(), parsed.output);\n const expected = await generate(entry, deps);\n if (parsed.check) {\n let actual: string;\n try {\n actual = await deps.readFile(output);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n io.error(`OpenAPI artifact is missing: ${output}`);\n return 1;\n }\n throw error;\n }\n if (actual !== expected) {\n io.error(`OpenAPI artifact is stale: ${output}`);\n return 1;\n }\n io.log(`OpenAPI artifact is current: ${output}`);\n return 0;\n }\n await atomicWrite(output, expected, deps);\n io.log(`Generated OpenAPI artifact: ${output}`);\n return 0;\n } catch (error) {\n io.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n\nasync function main(): Promise<void> {\n process.exit(await runOpenApiCli(process.argv.slice(2)));\n}\n\nif (isDirectExecution(import.meta.url)) void main();\n"],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: askr-accessibility
|
|
3
|
+
description: Use when making Askr UI accessible, including keyboard flows, focus management, ARIA names, dialogs, menus, forms, tables, live regions, screen-reader behavior, and @askrjs/ui primitive selection.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Askr Accessibility
|
|
7
|
+
|
|
8
|
+
Use this for accessibility-sensitive UI or when composing interactive primitives. The goal is predictable keyboard flow, visible and announced state changes, and reuse of primitives that already own behavior.
|
|
9
|
+
|
|
10
|
+
## Use This When
|
|
11
|
+
|
|
12
|
+
- The surface includes dialogs, menus, forms, tables, or other interactive controls.
|
|
13
|
+
- Focus management, keyboard flow, or screen-reader behavior matters to the task.
|
|
14
|
+
- Async status, stale state, or destructive confirmation must be announced clearly.
|
|
15
|
+
- You need to review whether a UI change stayed accessible after composition or theming work.
|
|
16
|
+
|
|
17
|
+
## Inspect First
|
|
18
|
+
|
|
19
|
+
- Existing `@askrjs/ui` primitive usage
|
|
20
|
+
- Labels, accessible names, focus order, and keyboard behavior
|
|
21
|
+
- Form errors, async status messages, and destructive confirmations
|
|
22
|
+
- Browser tests for overlays, menus, forms, and tables
|
|
23
|
+
|
|
24
|
+
## Do This In Order
|
|
25
|
+
|
|
26
|
+
1. Prefer `@askrjs/ui` for behavior-heavy controls before raw HTML.
|
|
27
|
+
2. Make sure every interactive control has an accessible name.
|
|
28
|
+
3. Keep dialog, menu, and overlay focus behavior predictable.
|
|
29
|
+
4. Make form errors, async failures, and important status changes visible and announceable.
|
|
30
|
+
5. Check that stale, selected, pending, and error states are not color-only.
|
|
31
|
+
|
|
32
|
+
## Copy This Shape
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<Show when={mutation.error}>
|
|
36
|
+
<p role="alert">Unable to save changes.</p>
|
|
37
|
+
</Show>
|
|
38
|
+
|
|
39
|
+
<button aria-label="Archive account">Archive</button>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Never Do These
|
|
43
|
+
|
|
44
|
+
- Reimplementing primitive keyboard behavior.
|
|
45
|
+
- Icon-only buttons without labels.
|
|
46
|
+
- Focus loss after route changes, dialogs, or list updates.
|
|
47
|
+
- Color-only error, stale, selected, or pending states.
|
|
48
|
+
- Toast-only critical errors.
|
|
49
|
+
|
|
50
|
+
## Validate
|
|
51
|
+
|
|
52
|
+
- Keyboard-only users can complete the workflow.
|
|
53
|
+
- Focus lands in the expected place after navigation, dialog open or close, and submit.
|
|
54
|
+
- Axe or equivalent accessibility checks pass for changed surfaces when available.
|
|
55
|
+
- Browser tests cover complex focus and keyboard behavior.
|
|
56
|
+
|
|
57
|
+
## Done When
|
|
58
|
+
|
|
59
|
+
- Keyboard, focus, and naming behavior are predictable.
|
|
60
|
+
- Important async and failure states are announced or visible semantically.
|
|
61
|
+
- The surface does not depend on color alone to communicate state.
|
|
62
|
+
- Accessibility behavior is verified at the right test level.
|
|
63
|
+
|
|
64
|
+
## Handoff
|
|
65
|
+
|
|
66
|
+
- Use `askr-ui-composition` when the hard part is primitive behavior composition.
|
|
67
|
+
- Use `askr-error-loading-empty` when async state truth is the blocker.
|
|
68
|
+
- Use `askr-testing-determinism` before closing browser-level accessibility changes.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: askr-agent-execution
|
|
3
|
+
description: Use when an AI coding agent needs the canonical execution playbook for reading an Askr repo, choosing the right skill, validating work, and avoiding invented primitives or foreign framework defaults.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Askr Agent Execution
|
|
7
|
+
|
|
8
|
+
Use this before any edit in an Askr repo. This is the execution loop that every other Askr skill assumes.
|
|
9
|
+
|
|
10
|
+
## Use This When
|
|
11
|
+
|
|
12
|
+
- Starting a new task.
|
|
13
|
+
- The right Askr skill is not obvious yet.
|
|
14
|
+
- You need a fixed read order before editing.
|
|
15
|
+
- You need objective done criteria.
|
|
16
|
+
|
|
17
|
+
## Read In This Order
|
|
18
|
+
|
|
19
|
+
1. `package.json`
|
|
20
|
+
2. `AGENTS.md` when it exists
|
|
21
|
+
3. `src/main.tsx`
|
|
22
|
+
4. `src/router.tsx` or `src/pages/_routes.tsx`
|
|
23
|
+
5. The nearest branch `_routes.tsx` and `_layout.tsx`
|
|
24
|
+
6. The nearest `src/features/<feature>/` or `src/components/<feature>/` owner
|
|
25
|
+
7. Existing tests for the touched surface
|
|
26
|
+
8. `src/styles.css` and `src/styles/*` only when visual behavior changes
|
|
27
|
+
|
|
28
|
+
## Choose The Next Skill
|
|
29
|
+
|
|
30
|
+
- File ownership unclear: use `askr-project-structure`.
|
|
31
|
+
- Route tree, shell, metadata, or navigation change: use `askr-routing-layouts`.
|
|
32
|
+
- Local state, derived values, keyed rendering, or call-order safety: use `askr-runtime-reactivity`.
|
|
33
|
+
- One route or container owns an async read: use `askr-resources-data`.
|
|
34
|
+
- Shared keyed reads or writes must coordinate across screens: use `askr-query-mutation`.
|
|
35
|
+
- Loading, empty, stale, retry, or pending-write truth is the hard part: use `askr-error-loading-empty`.
|
|
36
|
+
- You are closing the task and need the right checks: use `askr-testing-determinism`.
|
|
37
|
+
- The task spans many app surfaces and no narrower owner is enough: use `askr-app-builder` last, not first.
|
|
38
|
+
|
|
39
|
+
## Execution Loop
|
|
40
|
+
|
|
41
|
+
1. Inspect the existing owner files before proposing a new abstraction.
|
|
42
|
+
2. Pick one owning skill for the current slice.
|
|
43
|
+
3. Make the smallest edit that matches the repo's current structure.
|
|
44
|
+
4. Run the narrowest executable validation for that slice.
|
|
45
|
+
5. Only widen scope after that validation passes or clearly changes your understanding.
|
|
46
|
+
6. Stop when the change is structurally correct, validated, and easy for the next agent to follow.
|
|
47
|
+
|
|
48
|
+
## Non-Negotiables
|
|
49
|
+
|
|
50
|
+
- Keep pages route-focused, features workflow-focused, and adapters transport-focused.
|
|
51
|
+
- Add files only where another agent could predict they belong.
|
|
52
|
+
- Reuse existing layouts, route groups, features, and shared helpers before creating new ones.
|
|
53
|
+
- Use `@askrjs/ui` and `@askrjs/themes` before inventing app-local primitives.
|
|
54
|
+
|
|
55
|
+
## Never Do These By Default
|
|
56
|
+
|
|
57
|
+
- React hooks or React Router patterns.
|
|
58
|
+
- TanStack Query or a generic query-client abstraction.
|
|
59
|
+
- Custom routing systems or page-local route state copies.
|
|
60
|
+
- App-local `Button`, `Card`, `Panel`, `Sidebar`, `Navbar`, `EmptyState`, `Page`, `Toolbar`, `HStack`, or `VStack` clones.
|
|
61
|
+
- Generic store or service-locator layers when `state()`, `resource()`, `createQuery()`, or `createMutation()` already fit.
|
|
62
|
+
- Diff-only validation when a narrower executable check exists.
|
|
63
|
+
|
|
64
|
+
## Validate In This Order
|
|
65
|
+
|
|
66
|
+
1. Run the narrowest relevant test for the touched behavior.
|
|
67
|
+
2. Run the nearest type check or project check.
|
|
68
|
+
3. Run build or template-specific checks if the change affects app boot, routing, SSR/SSG, or packaging.
|
|
69
|
+
4. Confirm loading, error, empty, stale, pending, focus, and overflow states when user-visible.
|
|
70
|
+
|
|
71
|
+
Use existing scripts such as `npm test`, `npm run type-check`, `npm run build`, `npm run lint`, or `npm run check` when they exist. Do not invent new validation commands when the repo already defines the contract.
|
|
72
|
+
|
|
73
|
+
## Done When
|
|
74
|
+
|
|
75
|
+
- You can name the owner file for every new change.
|
|
76
|
+
- The chosen skill matches the slice you edited.
|
|
77
|
+
- No foreign framework defaults or parallel architecture were introduced.
|
|
78
|
+
- At least one executable validation ran, or the blocker is explicit.
|
|
79
|
+
- The next likely skill for follow-up work is obvious.
|
|
80
|
+
|
|
81
|
+
## Handoff
|
|
82
|
+
|
|
83
|
+
- Use `askr-project-structure` when the next step is mostly about file placement.
|
|
84
|
+
- Use `askr-routing-layouts` when the next step is mostly about URL ownership or shell boundaries.
|
|
85
|
+
- Use `askr-testing-determinism` before closing any user-visible or stateful change.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: askr-agent-workflows
|
|
3
|
+
description: Use when building Askr UI for AI or agent workflows, including prompts, runs, streaming output, tool timelines, approvals, cancellation, retries, audit logs, persistence, and event-sourced run state.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Askr Agent Workflows
|
|
7
|
+
|
|
8
|
+
Use this for user-facing agentic product flows.
|
|
9
|
+
|
|
10
|
+
## Inspect First
|
|
11
|
+
|
|
12
|
+
- Existing agent API adapters and run/event schemas.
|
|
13
|
+
- Feature folders for prompts, runs, tools, approvals, or artifacts.
|
|
14
|
+
- Realtime/event-streaming utilities.
|
|
15
|
+
- Product requirements for human approval, audit, and cancellation.
|
|
16
|
+
|
|
17
|
+
## Run State Model
|
|
18
|
+
|
|
19
|
+
Model agent work as a run, not a one-off response:
|
|
20
|
+
|
|
21
|
+
- `draft`: user is composing input.
|
|
22
|
+
- `queued`: backend accepted the run but no work is visible.
|
|
23
|
+
- `running`: events or tokens are arriving.
|
|
24
|
+
- `requires-action`: user approval, credential, or clarification is needed.
|
|
25
|
+
- `cancelling`: cancel requested, waiting for acknowledgement.
|
|
26
|
+
- `succeeded`, `failed`, `cancelled`: terminal states.
|
|
27
|
+
|
|
28
|
+
## Event-Sourced UX
|
|
29
|
+
|
|
30
|
+
- Treat the server event log as the source of truth.
|
|
31
|
+
- Apply events idempotently by event ID or sequence.
|
|
32
|
+
- Show optimistic local intent separately from confirmed server state.
|
|
33
|
+
- Preserve `lastEventId` or cursor for resume/reconnect.
|
|
34
|
+
- On reconnect, request events after the last seen cursor and refetch the affected projection if a gap is detected.
|
|
35
|
+
- When projections lag, display "saving", "syncing", or "finalizing" rather than pretending completion.
|
|
36
|
+
|
|
37
|
+
## UI Composition
|
|
38
|
+
|
|
39
|
+
- Prompt composer owns draft state and submit intent.
|
|
40
|
+
- Run timeline renders messages, tool calls, approvals, errors, and artifacts.
|
|
41
|
+
- Approval cards make the requested action, risk, and resulting command explicit.
|
|
42
|
+
- Cancel and retry controls reflect backend acknowledgement, not just button clicks.
|
|
43
|
+
|
|
44
|
+
## Avoid
|
|
45
|
+
|
|
46
|
+
- A single `loading` boolean for the whole run.
|
|
47
|
+
- Replacing the timeline wholesale when streaming events arrive.
|
|
48
|
+
- Hiding tool calls or approvals in unstructured text.
|
|
49
|
+
- Retrying runs without idempotency or parent-run linkage.
|
|
50
|
+
- Losing partial output on refresh or reconnect.
|
|
51
|
+
|
|
52
|
+
## Checks
|
|
53
|
+
|
|
54
|
+
- Run states map to visible UI.
|
|
55
|
+
- Event application is idempotent and ordered.
|
|
56
|
+
- Cancellation, retry, approval, and failure paths are covered.
|
|
57
|
+
- The user can understand what the agent did and what still needs attention.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: askr-api-integration
|
|
3
|
+
description: Use when integrating Askr apps with generated API clients, transport adapters, auth headers, cancellation, DTO mapping, error normalization, retries, and event-sourced consistency metadata.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Askr API Integration
|
|
7
|
+
|
|
8
|
+
Use this for the boundary between Askr feature code and backend APIs. The goal is one adapter boundary, deterministic DTO mapping, and preserved cancellation and consistency metadata.
|
|
9
|
+
|
|
10
|
+
## Use This When
|
|
11
|
+
|
|
12
|
+
- Frontend code crosses an HTTP, SSE, WebSocket, or generated-client boundary.
|
|
13
|
+
- DTOs need mapping before they enter features or UI.
|
|
14
|
+
- Auth headers, retries, request IDs, or error normalization belong in one place.
|
|
15
|
+
- Event-sourced writes need version, cursor, or event metadata for reconciliation.
|
|
16
|
+
|
|
17
|
+
## Inspect First
|
|
18
|
+
|
|
19
|
+
- Existing `src/adapters` generated clients and transport wrappers
|
|
20
|
+
- Existing `src/features` query or mutation workflows
|
|
21
|
+
- Existing `src/shared` config, error formatting, and auth helpers
|
|
22
|
+
- API DTO naming, version fields, event IDs, cursor fields, and request IDs
|
|
23
|
+
|
|
24
|
+
## Choose The Boundary
|
|
25
|
+
|
|
26
|
+
- `src/adapters`: generated clients, raw transport, auth header injection, and low-level retry behavior.
|
|
27
|
+
- `src/features/<feature>`: app-level queries, mutations, DTO-to-model mapping, and workflow state.
|
|
28
|
+
- `src/shared`: cross-cutting config, error normalization, formatters, and request tracing.
|
|
29
|
+
- Components should consume app models and feature state, never raw transport DTOs.
|
|
30
|
+
|
|
31
|
+
## Do This In Order
|
|
32
|
+
|
|
33
|
+
1. Keep raw client calls in the adapter boundary.
|
|
34
|
+
2. Forward `AbortSignal` through every cancellable layer.
|
|
35
|
+
3. Map DTOs into app models before they leave the feature or adapter boundary.
|
|
36
|
+
4. Normalize errors into user-safe messages plus machine-readable diagnostics.
|
|
37
|
+
5. Preserve request IDs, versions, cursors, or event IDs when the UI needs freshness or reconciliation truth.
|
|
38
|
+
6. Retry only idempotent reads or commands with explicit idempotency keys.
|
|
39
|
+
|
|
40
|
+
## Copy This Shape
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
export async function listAccounts({ signal }: { signal: AbortSignal }) {
|
|
44
|
+
const response = await accountsClient.list({ signal });
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
items: response.items.map(toAccount),
|
|
48
|
+
version: response.version,
|
|
49
|
+
lastEventId: response.last_event_id,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Never Do These
|
|
55
|
+
|
|
56
|
+
- Returning raw API DTOs directly to page props.
|
|
57
|
+
- Hiding `signal`, request IDs, or version metadata because the first screen does not need them yet.
|
|
58
|
+
- Retrying a non-idempotent command from the UI without a server-recognized idempotency key.
|
|
59
|
+
- Putting raw clients in `src/pages` or generic UI components.
|
|
60
|
+
|
|
61
|
+
## Validate
|
|
62
|
+
|
|
63
|
+
- Every async adapter accepts and forwards `signal`.
|
|
64
|
+
- Errors normalize into user-safe messages and machine-readable codes.
|
|
65
|
+
- DTO mapping is deterministic and tested where the boundary matters.
|
|
66
|
+
- Event or version metadata reaches query or mutation state when consistency matters.
|
|
67
|
+
|
|
68
|
+
## Done When
|
|
69
|
+
|
|
70
|
+
- Components no longer see raw transport DTOs.
|
|
71
|
+
- `signal`, request IDs, and consistency metadata survive the adapter boundary.
|
|
72
|
+
- Retry behavior is explicit and safe.
|
|
73
|
+
- Error normalization is ready for both user copy and machine-readable handling.
|
|
74
|
+
|
|
75
|
+
## Handoff
|
|
76
|
+
|
|
77
|
+
- Use `askr-query-mutation` when feature state must invalidate or reconcile shared reads.
|
|
78
|
+
- Use `askr-auth-access` when auth headers or session policy shape the adapter behavior.
|
|
79
|
+
- Use `askr-observability-debugging` when request IDs, traces, and safe diagnostics must survive end to end.
|