@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
package/dist/create.js
ADDED
|
@@ -0,0 +1,923 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { t as isDirectExecution } from "./is-direct-execution-Cdlr-ZUl.js";
|
|
3
|
+
import { t as installBundledSkills } from "./skills-Bh0mEhIx.js";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
import readline from "node:readline";
|
|
9
|
+
//#region src/bin/create.ts
|
|
10
|
+
const TEMPLATE_LABELS = {
|
|
11
|
+
"full-stack": "Full-stack",
|
|
12
|
+
spa: "SPA",
|
|
13
|
+
ssr: "SSR",
|
|
14
|
+
ssg: "SSG",
|
|
15
|
+
startkit: "StartKit"
|
|
16
|
+
};
|
|
17
|
+
const TEMPLATE_TYPES = /* @__PURE__ */ new Set([
|
|
18
|
+
"startkit",
|
|
19
|
+
"spa",
|
|
20
|
+
"ssr",
|
|
21
|
+
"ssg",
|
|
22
|
+
"full-stack"
|
|
23
|
+
]);
|
|
24
|
+
const TEMPLATE_ORDER = [
|
|
25
|
+
"startkit",
|
|
26
|
+
"spa",
|
|
27
|
+
"ssr",
|
|
28
|
+
"ssg",
|
|
29
|
+
"full-stack"
|
|
30
|
+
];
|
|
31
|
+
const PROMPT_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
32
|
+
"a",
|
|
33
|
+
"an",
|
|
34
|
+
"and",
|
|
35
|
+
"app",
|
|
36
|
+
"application",
|
|
37
|
+
"build",
|
|
38
|
+
"create",
|
|
39
|
+
"for",
|
|
40
|
+
"from",
|
|
41
|
+
"in",
|
|
42
|
+
"into",
|
|
43
|
+
"me",
|
|
44
|
+
"of",
|
|
45
|
+
"or",
|
|
46
|
+
"platform",
|
|
47
|
+
"product",
|
|
48
|
+
"that",
|
|
49
|
+
"the",
|
|
50
|
+
"to",
|
|
51
|
+
"with"
|
|
52
|
+
]);
|
|
53
|
+
const TEMPLATE_DEFAULT_CAPABILITIES = {
|
|
54
|
+
"full-stack": [
|
|
55
|
+
"routing-layouts",
|
|
56
|
+
"ssr-ssg",
|
|
57
|
+
"api-integration",
|
|
58
|
+
"auth-access",
|
|
59
|
+
"forms-tables-crud",
|
|
60
|
+
"query-mutation",
|
|
61
|
+
"design-system"
|
|
62
|
+
],
|
|
63
|
+
spa: [
|
|
64
|
+
"routing-layouts",
|
|
65
|
+
"dashboard-charts",
|
|
66
|
+
"agent-workflows",
|
|
67
|
+
"design-system"
|
|
68
|
+
],
|
|
69
|
+
ssr: [
|
|
70
|
+
"routing-layouts",
|
|
71
|
+
"ssr-ssg",
|
|
72
|
+
"query-mutation",
|
|
73
|
+
"design-system"
|
|
74
|
+
],
|
|
75
|
+
ssg: [
|
|
76
|
+
"routing-layouts",
|
|
77
|
+
"ssr-ssg",
|
|
78
|
+
"design-system"
|
|
79
|
+
],
|
|
80
|
+
startkit: [
|
|
81
|
+
"routing-layouts",
|
|
82
|
+
"auth-access",
|
|
83
|
+
"forms-tables-crud",
|
|
84
|
+
"design-system"
|
|
85
|
+
]
|
|
86
|
+
};
|
|
87
|
+
const TEMPLATE_PROMPT_RULES = [
|
|
88
|
+
{
|
|
89
|
+
template: "full-stack",
|
|
90
|
+
reason: "Prompt requires server APIs, authenticated actions, and request-time rendering.",
|
|
91
|
+
terms: [
|
|
92
|
+
"api and ssr",
|
|
93
|
+
"authenticated api",
|
|
94
|
+
"backend and frontend",
|
|
95
|
+
"full stack",
|
|
96
|
+
"full-stack",
|
|
97
|
+
"server action"
|
|
98
|
+
],
|
|
99
|
+
weight: 6
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
template: "ssg",
|
|
103
|
+
reason: "Prompt emphasizes static content or documentation publishing.",
|
|
104
|
+
terms: [
|
|
105
|
+
"blog",
|
|
106
|
+
"content",
|
|
107
|
+
"docs",
|
|
108
|
+
"documentation",
|
|
109
|
+
"knowledge base",
|
|
110
|
+
"landing page",
|
|
111
|
+
"marketing",
|
|
112
|
+
"static"
|
|
113
|
+
],
|
|
114
|
+
weight: 4
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
template: "ssr",
|
|
118
|
+
reason: "Prompt emphasizes server rendering or request-time HTML.",
|
|
119
|
+
terms: [
|
|
120
|
+
"edge render",
|
|
121
|
+
"personalized seo",
|
|
122
|
+
"request-time",
|
|
123
|
+
"server render",
|
|
124
|
+
"server rendered",
|
|
125
|
+
"server-rendered",
|
|
126
|
+
"ssr"
|
|
127
|
+
],
|
|
128
|
+
weight: 4
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
template: "spa",
|
|
132
|
+
reason: "Prompt emphasizes interactive workflows, control planes, or agent operations.",
|
|
133
|
+
terms: [
|
|
134
|
+
"agent",
|
|
135
|
+
"approval",
|
|
136
|
+
"assistant",
|
|
137
|
+
"console",
|
|
138
|
+
"control plane",
|
|
139
|
+
"dashboard",
|
|
140
|
+
"operations",
|
|
141
|
+
"realtime",
|
|
142
|
+
"stream",
|
|
143
|
+
"workflow"
|
|
144
|
+
],
|
|
145
|
+
weight: 3
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
template: "startkit",
|
|
149
|
+
reason: "Prompt emphasizes auth, workspace, or back-office product surfaces.",
|
|
150
|
+
terms: [
|
|
151
|
+
"account",
|
|
152
|
+
"admin",
|
|
153
|
+
"auth",
|
|
154
|
+
"billing",
|
|
155
|
+
"login",
|
|
156
|
+
"portal",
|
|
157
|
+
"settings",
|
|
158
|
+
"tenant",
|
|
159
|
+
"workspace"
|
|
160
|
+
],
|
|
161
|
+
weight: 3
|
|
162
|
+
}
|
|
163
|
+
];
|
|
164
|
+
const CAPABILITY_RULES = [
|
|
165
|
+
{
|
|
166
|
+
capability: "agent-workflows",
|
|
167
|
+
terms: [
|
|
168
|
+
"agent",
|
|
169
|
+
"approval",
|
|
170
|
+
"artifact",
|
|
171
|
+
"assistant",
|
|
172
|
+
"prompt",
|
|
173
|
+
"run",
|
|
174
|
+
"tool",
|
|
175
|
+
"workflow"
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
capability: "api-integration",
|
|
180
|
+
terms: [
|
|
181
|
+
"api",
|
|
182
|
+
"backend",
|
|
183
|
+
"graphql",
|
|
184
|
+
"rest",
|
|
185
|
+
"sdk",
|
|
186
|
+
"webhook"
|
|
187
|
+
]
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
capability: "auth-access",
|
|
191
|
+
terms: [
|
|
192
|
+
"access",
|
|
193
|
+
"auth",
|
|
194
|
+
"login",
|
|
195
|
+
"permission",
|
|
196
|
+
"role",
|
|
197
|
+
"session",
|
|
198
|
+
"tenant",
|
|
199
|
+
"workspace"
|
|
200
|
+
]
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
capability: "dashboard-charts",
|
|
204
|
+
terms: [
|
|
205
|
+
"analytics",
|
|
206
|
+
"chart",
|
|
207
|
+
"dashboard",
|
|
208
|
+
"kpi",
|
|
209
|
+
"metric",
|
|
210
|
+
"report"
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
capability: "file-upload-artifacts",
|
|
215
|
+
terms: [
|
|
216
|
+
"artifact",
|
|
217
|
+
"attachment",
|
|
218
|
+
"document",
|
|
219
|
+
"file",
|
|
220
|
+
"upload"
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
capability: "forms-tables-crud",
|
|
225
|
+
terms: [
|
|
226
|
+
"crud",
|
|
227
|
+
"edit",
|
|
228
|
+
"form",
|
|
229
|
+
"record",
|
|
230
|
+
"table"
|
|
231
|
+
]
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
capability: "query-mutation",
|
|
235
|
+
terms: [
|
|
236
|
+
"cache",
|
|
237
|
+
"data",
|
|
238
|
+
"mutation",
|
|
239
|
+
"query",
|
|
240
|
+
"resource",
|
|
241
|
+
"sync"
|
|
242
|
+
]
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
capability: "realtime-streaming",
|
|
246
|
+
terms: [
|
|
247
|
+
"event",
|
|
248
|
+
"live",
|
|
249
|
+
"realtime",
|
|
250
|
+
"stream",
|
|
251
|
+
"subscription",
|
|
252
|
+
"websocket"
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
capability: "ssr-ssg",
|
|
257
|
+
terms: [
|
|
258
|
+
"content",
|
|
259
|
+
"docs",
|
|
260
|
+
"seo",
|
|
261
|
+
"server render",
|
|
262
|
+
"ssg",
|
|
263
|
+
"ssr",
|
|
264
|
+
"static"
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
];
|
|
268
|
+
const CAPABILITY_LABELS = {
|
|
269
|
+
"agent-workflows": "Agent workflows",
|
|
270
|
+
"api-integration": "API integration",
|
|
271
|
+
"auth-access": "Authentication and access",
|
|
272
|
+
"dashboard-charts": "Dashboards and charts",
|
|
273
|
+
"design-system": "Design system and theming",
|
|
274
|
+
"file-upload-artifacts": "Files and artifacts",
|
|
275
|
+
"forms-tables-crud": "Forms, tables, and CRUD",
|
|
276
|
+
"query-mutation": "Queries and mutations",
|
|
277
|
+
"realtime-streaming": "Realtime and streaming",
|
|
278
|
+
"routing-layouts": "Routing and layouts",
|
|
279
|
+
"ssr-ssg": "SSR or SSG"
|
|
280
|
+
};
|
|
281
|
+
const CORE_RECOMMENDED_SKILLS = [
|
|
282
|
+
"askr-agent-execution",
|
|
283
|
+
"askr-mental-model",
|
|
284
|
+
"askr-project-structure",
|
|
285
|
+
"askr-routing-layouts",
|
|
286
|
+
"askr-runtime-reactivity",
|
|
287
|
+
"askr-testing-determinism"
|
|
288
|
+
];
|
|
289
|
+
const CAPABILITY_SKILL_MAP = {
|
|
290
|
+
"agent-workflows": ["askr-agent-workflows", "askr-error-loading-empty"],
|
|
291
|
+
"api-integration": ["askr-api-integration", "askr-env-config"],
|
|
292
|
+
"auth-access": ["askr-auth-access"],
|
|
293
|
+
"dashboard-charts": ["askr-dashboard-charts"],
|
|
294
|
+
"design-system": ["askr-theming"],
|
|
295
|
+
"file-upload-artifacts": ["askr-file-upload-artifacts"],
|
|
296
|
+
"forms-tables-crud": ["askr-forms-tables-crud", "askr-error-loading-empty"],
|
|
297
|
+
"query-mutation": [
|
|
298
|
+
"askr-resources-data",
|
|
299
|
+
"askr-query-mutation",
|
|
300
|
+
"askr-error-loading-empty"
|
|
301
|
+
],
|
|
302
|
+
"realtime-streaming": ["askr-realtime-streaming"],
|
|
303
|
+
"routing-layouts": ["askr-routing-layouts"],
|
|
304
|
+
"ssr-ssg": ["askr-ssr-ssg"]
|
|
305
|
+
};
|
|
306
|
+
const FOUNDATION_SKILL_SEQUENCE = [
|
|
307
|
+
"askr-agent-execution",
|
|
308
|
+
"askr-mental-model",
|
|
309
|
+
"askr-project-structure",
|
|
310
|
+
"askr-routing-layouts",
|
|
311
|
+
"askr-runtime-reactivity"
|
|
312
|
+
];
|
|
313
|
+
const VALIDATION_SKILLS = ["askr-testing-determinism"];
|
|
314
|
+
const BROAD_PLANNING_SKILLS = ["askr-app-builder"];
|
|
315
|
+
const SKILL_SEQUENCE = [
|
|
316
|
+
...FOUNDATION_SKILL_SEQUENCE,
|
|
317
|
+
"askr-resources-data",
|
|
318
|
+
"askr-query-mutation",
|
|
319
|
+
"askr-error-loading-empty",
|
|
320
|
+
"askr-forms-tables-crud",
|
|
321
|
+
"askr-auth-access",
|
|
322
|
+
"askr-agent-workflows",
|
|
323
|
+
"askr-dashboard-charts",
|
|
324
|
+
"askr-api-integration",
|
|
325
|
+
"askr-env-config",
|
|
326
|
+
"askr-file-upload-artifacts",
|
|
327
|
+
"askr-realtime-streaming",
|
|
328
|
+
"askr-ssr-ssg",
|
|
329
|
+
"askr-theming",
|
|
330
|
+
"askr-ui-composition",
|
|
331
|
+
"askr-design-system",
|
|
332
|
+
"askr-accessibility",
|
|
333
|
+
"askr-observability-debugging",
|
|
334
|
+
...VALIDATION_SKILLS,
|
|
335
|
+
...BROAD_PLANNING_SKILLS
|
|
336
|
+
];
|
|
337
|
+
const SKILL_SUMMARIES = {
|
|
338
|
+
"askr-accessibility": "Review keyboard, focus, announcements, and semantic coverage.",
|
|
339
|
+
"askr-agent-execution": "Read the repo in the right order and validate narrowly.",
|
|
340
|
+
"askr-agent-workflows": "Model runs, approvals, timelines, and audit-friendly states.",
|
|
341
|
+
"askr-api-integration": "Keep DTO mapping, retries, and transport boundaries out of pages.",
|
|
342
|
+
"askr-app-builder": "Use only when a task spans multiple app surfaces and needs a broad plan.",
|
|
343
|
+
"askr-auth-access": "Keep access rules in route metadata and auth workflows, not pages.",
|
|
344
|
+
"askr-dashboard-charts": "Add charts without bypassing route, state, or theming conventions.",
|
|
345
|
+
"askr-design-system": "Use only when shaping reusable product patterns beyond one screen.",
|
|
346
|
+
"askr-env-config": "Keep environment-specific configuration and secrets handling outside UI.",
|
|
347
|
+
"askr-error-loading-empty": "Represent loading, empty, stale, retry, and pending-write truthfully.",
|
|
348
|
+
"askr-file-upload-artifacts": "Add uploads and artifact flows without breaking ownership boundaries.",
|
|
349
|
+
"askr-forms-tables-crud": "Build forms, tables, filters, and destructive actions with stable ownership.",
|
|
350
|
+
"askr-mental-model": "Choose native Askr primitives and reject React-shaped defaults.",
|
|
351
|
+
"askr-observability-debugging": "Preserve correlation IDs and diagnosable failure context.",
|
|
352
|
+
"askr-project-structure": "Place routes, features, shared helpers, and adapters predictably.",
|
|
353
|
+
"askr-query-mutation": "Use shared keyed reads and mutations with explicit invalidation.",
|
|
354
|
+
"askr-realtime-streaming": "Handle reconnects, cursors, and bounded live lists.",
|
|
355
|
+
"askr-resources-data": "Own route-scoped async reads with resource() and cancellation.",
|
|
356
|
+
"askr-routing-layouts": "Keep one obvious route tree, shell boundary, and navigation path.",
|
|
357
|
+
"askr-runtime-reactivity": "Apply state(), derive(), selector(), and For with stable call order.",
|
|
358
|
+
"askr-ssr-ssg": "Keep routes deterministic and render paths hydration-safe.",
|
|
359
|
+
"askr-testing-determinism": "Finish with the narrowest executable check for the changed contract.",
|
|
360
|
+
"askr-theming": "Apply the theme layer, tokens, and shell primitives before custom styling.",
|
|
361
|
+
"askr-ui-composition": "Use askr-ui behavior primitives before inventing local components."
|
|
362
|
+
};
|
|
363
|
+
const TEMPLATE_INSPECT_PATHS = {
|
|
364
|
+
"full-stack": [
|
|
365
|
+
"AGENTS.md",
|
|
366
|
+
"src/routes.tsx",
|
|
367
|
+
"src/actions/create-message.ts",
|
|
368
|
+
"src/schemas.ts",
|
|
369
|
+
"src/server/app.ts",
|
|
370
|
+
"src/server/action-registry.ts",
|
|
371
|
+
"src/server/dependencies.ts",
|
|
372
|
+
"src/server/entry-server.ts",
|
|
373
|
+
"server.ts"
|
|
374
|
+
],
|
|
375
|
+
spa: [
|
|
376
|
+
"AGENTS.md",
|
|
377
|
+
"src/main.tsx",
|
|
378
|
+
"src/pages/_layout.tsx",
|
|
379
|
+
"src/pages/_routes.tsx",
|
|
380
|
+
"src/pages/public/_layout.tsx",
|
|
381
|
+
"src/pages/public/_routes.tsx",
|
|
382
|
+
"src/pages/public/home.tsx",
|
|
383
|
+
"src/pages/auth/_layout.tsx",
|
|
384
|
+
"src/pages/auth/_routes.tsx",
|
|
385
|
+
"src/pages/auth/login.tsx",
|
|
386
|
+
"src/pages/app/_layout.tsx",
|
|
387
|
+
"src/pages/app/_routes.tsx",
|
|
388
|
+
"src/pages/app/admin-home.tsx",
|
|
389
|
+
"src/styles.css",
|
|
390
|
+
"src/styles/reset.css",
|
|
391
|
+
"src/styles/tokens.css",
|
|
392
|
+
"src/styles/theme.css",
|
|
393
|
+
"src/styles/layout.css",
|
|
394
|
+
"src/styles/components.css"
|
|
395
|
+
],
|
|
396
|
+
ssr: [
|
|
397
|
+
"AGENTS.md",
|
|
398
|
+
"src/main.tsx",
|
|
399
|
+
"src/server-entry.tsx",
|
|
400
|
+
"src/pages/_routes.tsx",
|
|
401
|
+
"server.ts"
|
|
402
|
+
],
|
|
403
|
+
ssg: [
|
|
404
|
+
"AGENTS.md",
|
|
405
|
+
"src/main.tsx",
|
|
406
|
+
"src/routes.tsx",
|
|
407
|
+
"src/components/site-shell.tsx",
|
|
408
|
+
"src/pages/home.tsx",
|
|
409
|
+
"ssg.config.ts"
|
|
410
|
+
],
|
|
411
|
+
startkit: [
|
|
412
|
+
"AGENTS.md",
|
|
413
|
+
"src/main.tsx",
|
|
414
|
+
"src/router.tsx",
|
|
415
|
+
"src/routes/index.ts",
|
|
416
|
+
"src/pages/workspace/_layout.tsx"
|
|
417
|
+
]
|
|
418
|
+
};
|
|
419
|
+
const TEMPLATE_GOLDEN_EXAMPLES = {
|
|
420
|
+
"full-stack": [
|
|
421
|
+
"src/routes.tsx",
|
|
422
|
+
"src/pages/home.tsx",
|
|
423
|
+
"src/actions/create-message.ts",
|
|
424
|
+
"src/server/action-registry.ts",
|
|
425
|
+
"src/server/app.ts"
|
|
426
|
+
],
|
|
427
|
+
spa: [
|
|
428
|
+
"src/pages/public/home.tsx",
|
|
429
|
+
"src/pages/auth/login.tsx",
|
|
430
|
+
"src/pages/app/admin-home.tsx",
|
|
431
|
+
"src/features/operations/operations.query.ts"
|
|
432
|
+
],
|
|
433
|
+
ssr: [
|
|
434
|
+
"src/main.tsx",
|
|
435
|
+
"src/pages/_routes.tsx",
|
|
436
|
+
"server.ts"
|
|
437
|
+
],
|
|
438
|
+
ssg: [
|
|
439
|
+
"src/main.tsx",
|
|
440
|
+
"src/routes.tsx",
|
|
441
|
+
"src/components/site-shell.tsx",
|
|
442
|
+
"ssg.config.ts"
|
|
443
|
+
],
|
|
444
|
+
startkit: [
|
|
445
|
+
"src/routes/index.ts",
|
|
446
|
+
"src/pages/workspace/accounts/index.tsx",
|
|
447
|
+
"src/features/accounts/account-table.tsx"
|
|
448
|
+
]
|
|
449
|
+
};
|
|
450
|
+
const BLUEPRINT_GUARDRAILS = [
|
|
451
|
+
"Keep the route-first file structure so new features land where builders expect them.",
|
|
452
|
+
"Use state(), derive(), resource(), and selector() for reactive state and derived views.",
|
|
453
|
+
"Use For for keyed or dynamic list rendering instead of ad hoc array mapping.",
|
|
454
|
+
"Keep adapters, queries, and mutations outside page files so data boundaries stay deterministic.",
|
|
455
|
+
"Model loading, empty, error, and success states explicitly and keep them testable."
|
|
456
|
+
];
|
|
457
|
+
function isTemplateType(value) {
|
|
458
|
+
return TEMPLATE_TYPES.has(value);
|
|
459
|
+
}
|
|
460
|
+
function helpText() {
|
|
461
|
+
return [
|
|
462
|
+
"askr create - Project scaffolding for Askr",
|
|
463
|
+
"",
|
|
464
|
+
"Usage:",
|
|
465
|
+
" askr create [template] <name> [--prompt <text>] [--no-install] [--no-skills]",
|
|
466
|
+
" askr create --prompt <text> [name] [--no-install] [--no-skills]",
|
|
467
|
+
"",
|
|
468
|
+
"Templates:",
|
|
469
|
+
" startkit, spa, ssr, ssg, full-stack",
|
|
470
|
+
"",
|
|
471
|
+
"Options:",
|
|
472
|
+
" --prompt <text> Infer the best template from a product prompt and emit a builder blueprint",
|
|
473
|
+
" --no-install Skip dependency installation",
|
|
474
|
+
" --no-skills Skip bundled Askr skill installation into skills/",
|
|
475
|
+
" --help, -h Show help",
|
|
476
|
+
"",
|
|
477
|
+
"Examples:",
|
|
478
|
+
" askr create startkit my-app",
|
|
479
|
+
" askr create full-stack my-app",
|
|
480
|
+
" askr create startkit acme-dashboard",
|
|
481
|
+
" askr create --prompt \"Agent workflow console with approvals and analytics\""
|
|
482
|
+
].join("\n");
|
|
483
|
+
}
|
|
484
|
+
async function prompt(question) {
|
|
485
|
+
const rl = readline.createInterface({
|
|
486
|
+
input: process.stdin,
|
|
487
|
+
output: process.stdout
|
|
488
|
+
});
|
|
489
|
+
return new Promise((resolveAnswer) => {
|
|
490
|
+
rl.question(question, (answer) => {
|
|
491
|
+
rl.close();
|
|
492
|
+
resolveAnswer(answer);
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
function detectPm() {
|
|
497
|
+
const ua = process.env.npm_config_user_agent || "";
|
|
498
|
+
if (ua.startsWith("yarn")) return "yarn";
|
|
499
|
+
if (ua.startsWith("npm")) return "npm";
|
|
500
|
+
return "npm";
|
|
501
|
+
}
|
|
502
|
+
const TEMPLATE_COPY_EXCLUDES = /* @__PURE__ */ new Set([
|
|
503
|
+
"node_modules",
|
|
504
|
+
"dist",
|
|
505
|
+
".vite",
|
|
506
|
+
"coverage",
|
|
507
|
+
"package-lock.json",
|
|
508
|
+
"pnpm-lock.yaml",
|
|
509
|
+
"yarn.lock",
|
|
510
|
+
"bun.lock",
|
|
511
|
+
"bun.lockb"
|
|
512
|
+
]);
|
|
513
|
+
async function copyDir(src, dest, replacements) {
|
|
514
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
515
|
+
await fs.mkdir(dest, { recursive: true });
|
|
516
|
+
for (const entry of entries) {
|
|
517
|
+
if (TEMPLATE_COPY_EXCLUDES.has(entry.name)) continue;
|
|
518
|
+
const srcPath = path.join(src, entry.name);
|
|
519
|
+
const outputName = (entry.name === "gitignore.template" ? ".gitignore" : entry.name).replace(/\{\{\s*appName\s*\}\}/g, replacements.appName);
|
|
520
|
+
const destPath = path.join(dest, outputName);
|
|
521
|
+
if (entry.isDirectory()) {
|
|
522
|
+
await copyDir(srcPath, destPath, replacements);
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
const replaced = (await fs.readFile(srcPath)).toString("utf8").replace(/\{\{\s*appName\s*\}\}/g, replacements.appName).replace(/\{\{appName\}\}/g, replacements.appName);
|
|
526
|
+
await fs.writeFile(destPath, replaced, "utf8");
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
async function pathExists(filePath) {
|
|
530
|
+
return Boolean(await fs.stat(filePath).catch(() => null));
|
|
531
|
+
}
|
|
532
|
+
function cliDir() {
|
|
533
|
+
return path.dirname(fileURLToPath(import.meta.url));
|
|
534
|
+
}
|
|
535
|
+
async function findTemplateDir(templateType) {
|
|
536
|
+
const base = cliDir();
|
|
537
|
+
const candidates = [
|
|
538
|
+
path.resolve(base, "..", "..", "templates", templateType),
|
|
539
|
+
path.resolve(base, "..", "templates", templateType),
|
|
540
|
+
path.resolve(base, "templates", templateType)
|
|
541
|
+
];
|
|
542
|
+
for (const candidate of candidates) if (await pathExists(candidate)) return candidate;
|
|
543
|
+
return candidates[0];
|
|
544
|
+
}
|
|
545
|
+
function parseArgs(args) {
|
|
546
|
+
const positional = [];
|
|
547
|
+
let install = true;
|
|
548
|
+
let help = false;
|
|
549
|
+
let promptText = "";
|
|
550
|
+
let skills = true;
|
|
551
|
+
const errors = [];
|
|
552
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
553
|
+
const arg = args[i];
|
|
554
|
+
if (arg === "--no-install") install = false;
|
|
555
|
+
else if (arg === "--no-skills") skills = false;
|
|
556
|
+
else if (arg === "--prompt") if (i + 1 >= args.length) errors.push("Missing value for --prompt");
|
|
557
|
+
else {
|
|
558
|
+
promptText = normalizePromptText(args[i + 1]);
|
|
559
|
+
i += 1;
|
|
560
|
+
}
|
|
561
|
+
else if (arg === "--help" || arg === "-h") help = true;
|
|
562
|
+
else positional.push(arg);
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
positional,
|
|
566
|
+
install,
|
|
567
|
+
help,
|
|
568
|
+
promptText,
|
|
569
|
+
skills,
|
|
570
|
+
errors
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
function normalizePromptText(promptText) {
|
|
574
|
+
return promptText.trim().replace(/\s+/g, " ");
|
|
575
|
+
}
|
|
576
|
+
function normalizeSearchText(value) {
|
|
577
|
+
return ` ${value.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim()} `;
|
|
578
|
+
}
|
|
579
|
+
function scoreTerms(text, terms) {
|
|
580
|
+
const normalizedText = normalizeSearchText(text);
|
|
581
|
+
return terms.filter((term) => {
|
|
582
|
+
const normalizedTerm = normalizeSearchText(term).trim();
|
|
583
|
+
if (!normalizedTerm) return false;
|
|
584
|
+
return normalizedText.includes(` ${normalizedTerm} `) || normalizedText.includes(` ${normalizedTerm}s `) || normalizedText.includes(` ${normalizedTerm}es `);
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
function inferTemplateFromPrompt(promptText) {
|
|
588
|
+
const normalizedPrompt = promptText.toLowerCase();
|
|
589
|
+
const templateScores = {
|
|
590
|
+
"full-stack": 0,
|
|
591
|
+
startkit: 1,
|
|
592
|
+
spa: 0,
|
|
593
|
+
ssr: 0,
|
|
594
|
+
ssg: 0
|
|
595
|
+
};
|
|
596
|
+
const templateMatches = {
|
|
597
|
+
"full-stack": [],
|
|
598
|
+
startkit: [],
|
|
599
|
+
spa: [],
|
|
600
|
+
ssr: [],
|
|
601
|
+
ssg: []
|
|
602
|
+
};
|
|
603
|
+
const templateReasons = {
|
|
604
|
+
"full-stack": "Prompt requires server APIs, authenticated actions, and request-time rendering.",
|
|
605
|
+
startkit: "No stronger prompt signal was detected, so the CLI defaulted to the full app startkit.",
|
|
606
|
+
spa: "Prompt emphasizes interactive workflows, control planes, or agent operations.",
|
|
607
|
+
ssr: "Prompt emphasizes server rendering or request-time HTML.",
|
|
608
|
+
ssg: "Prompt emphasizes static content or documentation publishing."
|
|
609
|
+
};
|
|
610
|
+
for (const rule of TEMPLATE_PROMPT_RULES) {
|
|
611
|
+
const matches = scoreTerms(normalizedPrompt, rule.terms);
|
|
612
|
+
if (matches.length === 0) continue;
|
|
613
|
+
templateScores[rule.template] += matches.length * rule.weight;
|
|
614
|
+
templateMatches[rule.template].push(...matches);
|
|
615
|
+
templateReasons[rule.template] = rule.reason;
|
|
616
|
+
}
|
|
617
|
+
let selectedTemplate = TEMPLATE_ORDER[0];
|
|
618
|
+
for (const templateType of TEMPLATE_ORDER.slice(1)) if (templateScores[templateType] > templateScores[selectedTemplate]) selectedTemplate = templateType;
|
|
619
|
+
return {
|
|
620
|
+
matchedTerms: [...new Set(templateMatches[selectedTemplate])],
|
|
621
|
+
reason: templateReasons[selectedTemplate],
|
|
622
|
+
templateType: selectedTemplate
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
function deriveAppNameFromPrompt(promptText) {
|
|
626
|
+
const tokens = promptText.toLowerCase().replace(/[^a-z0-9]+/g, " ").split(/\s+/).map((token) => token.trim()).filter(Boolean).filter((token) => !PROMPT_STOP_WORDS.has(token)).filter((token) => token.length > 2);
|
|
627
|
+
const nameParts = [];
|
|
628
|
+
for (const token of tokens) {
|
|
629
|
+
if (!nameParts.includes(token)) nameParts.push(token);
|
|
630
|
+
if (nameParts.length === 3) break;
|
|
631
|
+
}
|
|
632
|
+
return nameParts.join("-") || "askr-app";
|
|
633
|
+
}
|
|
634
|
+
function buildCapabilities(templateType, promptText) {
|
|
635
|
+
const capabilities = new Set(TEMPLATE_DEFAULT_CAPABILITIES[templateType] || []);
|
|
636
|
+
if (promptText) {
|
|
637
|
+
const normalizedPrompt = promptText.toLowerCase();
|
|
638
|
+
for (const rule of CAPABILITY_RULES) if (scoreTerms(normalizedPrompt, rule.terms).length > 0) capabilities.add(rule.capability);
|
|
639
|
+
}
|
|
640
|
+
return Object.keys(CAPABILITY_LABELS).filter((capability) => capabilities.has(capability));
|
|
641
|
+
}
|
|
642
|
+
function buildRecommendedSkills(options) {
|
|
643
|
+
const { capabilities, promptText } = options;
|
|
644
|
+
const recommendedSkills = new Set(CORE_RECOMMENDED_SKILLS);
|
|
645
|
+
for (const capability of capabilities) for (const skill of CAPABILITY_SKILL_MAP[capability] || []) recommendedSkills.add(skill);
|
|
646
|
+
if (promptText.trim().length > 0) recommendedSkills.add("askr-app-builder");
|
|
647
|
+
const orderedSkills = SKILL_SEQUENCE.filter((skill) => recommendedSkills.has(skill));
|
|
648
|
+
const remainingSkills = [...recommendedSkills].filter((skill) => !SKILL_SEQUENCE.includes(skill)).sort();
|
|
649
|
+
return [...orderedSkills, ...remainingSkills];
|
|
650
|
+
}
|
|
651
|
+
function renderSkillBullets(skills) {
|
|
652
|
+
return skills.map((skill) => {
|
|
653
|
+
const summary = SKILL_SUMMARIES[skill];
|
|
654
|
+
return summary ? `- ${skill} - ${summary}` : `- ${skill}`;
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
function pickSkills(source, allowed) {
|
|
658
|
+
const allowedSet = new Set(allowed);
|
|
659
|
+
return source.filter((skill) => allowedSet.has(skill));
|
|
660
|
+
}
|
|
661
|
+
function pickWorkflowSkills(skills) {
|
|
662
|
+
const excluded = /* @__PURE__ */ new Set([
|
|
663
|
+
...FOUNDATION_SKILL_SEQUENCE,
|
|
664
|
+
...VALIDATION_SKILLS,
|
|
665
|
+
...BROAD_PLANNING_SKILLS
|
|
666
|
+
]);
|
|
667
|
+
return skills.filter((skill) => !excluded.has(skill));
|
|
668
|
+
}
|
|
669
|
+
function renderListSection(title, items) {
|
|
670
|
+
if (items.length === 0) return [];
|
|
671
|
+
return [
|
|
672
|
+
title,
|
|
673
|
+
...items,
|
|
674
|
+
""
|
|
675
|
+
];
|
|
676
|
+
}
|
|
677
|
+
function buildFollowUpPrompts(capabilities) {
|
|
678
|
+
const suggestions = [];
|
|
679
|
+
if (capabilities.includes("agent-workflows")) suggestions.push("Add an agent run detail screen with prompt, timeline, approvals, and artifact history.");
|
|
680
|
+
if (capabilities.includes("dashboard-charts")) suggestions.push("Connect dashboard metrics through adapters and queries while preserving loading, empty, and error states.");
|
|
681
|
+
if (capabilities.includes("auth-access")) suggestions.push("Wire route access and session state without moving auth logic into page components.");
|
|
682
|
+
if (capabilities.includes("forms-tables-crud")) suggestions.push("Add a CRUD feature using feature-scoped forms, tables, and deterministic tests.");
|
|
683
|
+
if (capabilities.includes("ssr-ssg")) suggestions.push("Extend SSR or SSG routes while keeping route registration deterministic and environment-safe.");
|
|
684
|
+
suggestions.push("Use the bundled Askr skills before adding new features so generated code stays idiomatic.");
|
|
685
|
+
return suggestions.slice(0, 4);
|
|
686
|
+
}
|
|
687
|
+
function buildBlueprint(options) {
|
|
688
|
+
const capabilities = buildCapabilities(options.templateType, options.promptText);
|
|
689
|
+
return {
|
|
690
|
+
schemaVersion: 1,
|
|
691
|
+
appName: options.appName,
|
|
692
|
+
template: options.templateType,
|
|
693
|
+
sourcePrompt: options.promptText || null,
|
|
694
|
+
templateSelection: options.templateSelection,
|
|
695
|
+
capabilities,
|
|
696
|
+
recommendedSkills: buildRecommendedSkills({
|
|
697
|
+
capabilities,
|
|
698
|
+
promptText: options.promptText
|
|
699
|
+
}),
|
|
700
|
+
guardrails: BLUEPRINT_GUARDRAILS
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
function renderPromptBlock(promptText) {
|
|
704
|
+
if (!promptText) return "No app prompt was provided. This project was scaffolded from explicit CLI arguments.";
|
|
705
|
+
return promptText.split(/\r?\n/).filter(Boolean).map((line) => `> ${line}`).join("\n");
|
|
706
|
+
}
|
|
707
|
+
function renderBuilderBrief(blueprint) {
|
|
708
|
+
const foundationSkills = pickSkills(blueprint.recommendedSkills, FOUNDATION_SKILL_SEQUENCE);
|
|
709
|
+
const workflowSkills = pickWorkflowSkills(blueprint.recommendedSkills);
|
|
710
|
+
const validationSkills = pickSkills(blueprint.recommendedSkills, VALIDATION_SKILLS);
|
|
711
|
+
const planningSkills = pickSkills(blueprint.recommendedSkills, BROAD_PLANNING_SKILLS);
|
|
712
|
+
return [
|
|
713
|
+
"# Askr Builder Brief",
|
|
714
|
+
"",
|
|
715
|
+
`- App name: ${blueprint.appName}`,
|
|
716
|
+
`- Template: ${blueprint.template}`,
|
|
717
|
+
`- Selection mode: ${blueprint.templateSelection.mode}`,
|
|
718
|
+
`- Selection reason: ${blueprint.templateSelection.reason}`,
|
|
719
|
+
"",
|
|
720
|
+
"## Prompt",
|
|
721
|
+
renderPromptBlock(blueprint.sourcePrompt),
|
|
722
|
+
"",
|
|
723
|
+
"## Capabilities",
|
|
724
|
+
...blueprint.capabilities.map((capability) => `- ${CAPABILITY_LABELS[capability]}`),
|
|
725
|
+
"",
|
|
726
|
+
"## Inspect First In This Scaffold",
|
|
727
|
+
...TEMPLATE_INSPECT_PATHS[blueprint.template].map((item) => `- ${item}`),
|
|
728
|
+
"",
|
|
729
|
+
"## Skill Execution Order",
|
|
730
|
+
...renderListSection("### Start here", renderSkillBullets(foundationSkills)),
|
|
731
|
+
...renderListSection("### Pull in next when the task needs it", renderSkillBullets(workflowSkills)),
|
|
732
|
+
...renderListSection("### Finish with validation", renderSkillBullets(validationSkills)),
|
|
733
|
+
...renderListSection("### Use only for broad multi-surface planning", renderSkillBullets(planningSkills)),
|
|
734
|
+
"## All Recommended Skills",
|
|
735
|
+
...blueprint.recommendedSkills.map((skill) => `- ${skill}`),
|
|
736
|
+
"",
|
|
737
|
+
"## Golden Examples In This Scaffold",
|
|
738
|
+
...TEMPLATE_GOLDEN_EXAMPLES[blueprint.template].map((item) => `- ${item}`),
|
|
739
|
+
"",
|
|
740
|
+
"## Guardrails",
|
|
741
|
+
...blueprint.guardrails.map((guardrail) => `- ${guardrail}`),
|
|
742
|
+
"",
|
|
743
|
+
"## Suggested builder prompts",
|
|
744
|
+
...buildFollowUpPrompts(blueprint.capabilities).map((item) => `- ${item}`),
|
|
745
|
+
""
|
|
746
|
+
].join("\n");
|
|
747
|
+
}
|
|
748
|
+
async function writeBlueprintFiles(target, blueprint) {
|
|
749
|
+
const blueprintRoot = path.join(target, ".askr");
|
|
750
|
+
await fs.mkdir(blueprintRoot, { recursive: true });
|
|
751
|
+
await fs.writeFile(path.join(blueprintRoot, "blueprint.json"), `${JSON.stringify(blueprint, null, 2)}\n`, "utf8");
|
|
752
|
+
await fs.writeFile(path.join(blueprintRoot, "builder-brief.md"), renderBuilderBrief(blueprint), "utf8");
|
|
753
|
+
}
|
|
754
|
+
async function runCreateCli(args = process.argv.slice(2), io = console) {
|
|
755
|
+
const parsed = parseArgs(args);
|
|
756
|
+
if (parsed.errors.length > 0) {
|
|
757
|
+
for (const message of parsed.errors) io.error(message);
|
|
758
|
+
return 1;
|
|
759
|
+
}
|
|
760
|
+
if (parsed.help) {
|
|
761
|
+
io.log(helpText());
|
|
762
|
+
return 0;
|
|
763
|
+
}
|
|
764
|
+
let templateType = "startkit";
|
|
765
|
+
let name = "";
|
|
766
|
+
let templateSelection = {
|
|
767
|
+
mode: "default",
|
|
768
|
+
reason: "No stronger prompt signal was detected, so the CLI defaulted to the full app startkit."
|
|
769
|
+
};
|
|
770
|
+
const explicitTemplate = parsed.positional.length > 0 && isTemplateType(parsed.positional[0]);
|
|
771
|
+
if (parsed.positional.length > 0) {
|
|
772
|
+
const first = parsed.positional[0];
|
|
773
|
+
if (isTemplateType(first)) {
|
|
774
|
+
templateType = first;
|
|
775
|
+
name = parsed.positional[1] || "";
|
|
776
|
+
templateSelection = {
|
|
777
|
+
mode: "explicit",
|
|
778
|
+
reason: `Template '${first}' was provided explicitly on the command line.`
|
|
779
|
+
};
|
|
780
|
+
} else name = first;
|
|
781
|
+
}
|
|
782
|
+
if (!explicitTemplate && parsed.promptText) {
|
|
783
|
+
const inferredTemplate = inferTemplateFromPrompt(parsed.promptText);
|
|
784
|
+
templateType = inferredTemplate.templateType;
|
|
785
|
+
templateSelection = {
|
|
786
|
+
mode: "prompt",
|
|
787
|
+
reason: inferredTemplate.reason,
|
|
788
|
+
matchedTerms: inferredTemplate.matchedTerms
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
if (!name && parsed.promptText) name = deriveAppNameFromPrompt(parsed.promptText);
|
|
792
|
+
if (!name) {
|
|
793
|
+
if (!explicitTemplate) {
|
|
794
|
+
io.log("Available templates: startkit, spa, ssr, ssg, full-stack");
|
|
795
|
+
io.log("");
|
|
796
|
+
const selectedTemplate = (await prompt("Template type (startkit/spa/ssr/ssg/full-stack) [startkit]: ")).trim() || "startkit";
|
|
797
|
+
if (!isTemplateType(selectedTemplate)) {
|
|
798
|
+
io.error("Invalid template type");
|
|
799
|
+
return 1;
|
|
800
|
+
}
|
|
801
|
+
templateType = selectedTemplate;
|
|
802
|
+
templateSelection = {
|
|
803
|
+
mode: "interactive",
|
|
804
|
+
reason: `Template '${selectedTemplate}' was chosen interactively.`
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
name = (await prompt("App name: ")).trim();
|
|
808
|
+
}
|
|
809
|
+
if (!name) {
|
|
810
|
+
io.error("App name is required");
|
|
811
|
+
return 1;
|
|
812
|
+
}
|
|
813
|
+
const target = path.resolve(process.cwd(), name);
|
|
814
|
+
const templateDir = await findTemplateDir(templateType);
|
|
815
|
+
try {
|
|
816
|
+
await fs.access(templateDir);
|
|
817
|
+
} catch {
|
|
818
|
+
io.error(`Template '${templateType}' not found at ${templateDir}`);
|
|
819
|
+
return 1;
|
|
820
|
+
}
|
|
821
|
+
try {
|
|
822
|
+
if (await fs.stat(target).catch(() => null)) {
|
|
823
|
+
if ((await fs.readdir(target).catch(() => [])).length > 0) {
|
|
824
|
+
io.error(`Directory ${target} already exists and is not empty.`);
|
|
825
|
+
return 1;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
} catch (error) {
|
|
829
|
+
io.error("Failed to access target directory");
|
|
830
|
+
io.error(error instanceof Error ? error.message : String(error));
|
|
831
|
+
return 1;
|
|
832
|
+
}
|
|
833
|
+
const blueprint = buildBlueprint({
|
|
834
|
+
appName: name,
|
|
835
|
+
promptText: parsed.promptText,
|
|
836
|
+
templateSelection,
|
|
837
|
+
templateType
|
|
838
|
+
});
|
|
839
|
+
if (parsed.promptText) {
|
|
840
|
+
io.log(`Prompt profile selected ${TEMPLATE_LABELS[templateType]} for ${name}.`);
|
|
841
|
+
io.log(`Reason: ${templateSelection.reason}`);
|
|
842
|
+
if (Array.isArray(templateSelection.matchedTerms) && templateSelection.matchedTerms.length > 0) io.log(`Matched prompt terms: ${templateSelection.matchedTerms.join(", ")}`);
|
|
843
|
+
io.log("");
|
|
844
|
+
}
|
|
845
|
+
io.log(`Creating ${TEMPLATE_LABELS[templateType]} project: ${name}...`);
|
|
846
|
+
io.log("");
|
|
847
|
+
try {
|
|
848
|
+
await copyDir(templateDir, target, { appName: name });
|
|
849
|
+
} catch (error) {
|
|
850
|
+
io.error("Failed to copy template");
|
|
851
|
+
io.error(error instanceof Error ? error.message : String(error));
|
|
852
|
+
return 1;
|
|
853
|
+
}
|
|
854
|
+
try {
|
|
855
|
+
await writeBlueprintFiles(target, blueprint);
|
|
856
|
+
} catch (error) {
|
|
857
|
+
io.error("Failed to write project blueprint");
|
|
858
|
+
io.error(error instanceof Error ? error.message : String(error));
|
|
859
|
+
return 1;
|
|
860
|
+
}
|
|
861
|
+
if (parsed.skills) try {
|
|
862
|
+
const { bundledNames, targetSkillsDir } = await installBundledSkills({
|
|
863
|
+
cwd: target,
|
|
864
|
+
force: true
|
|
865
|
+
});
|
|
866
|
+
io.log(`Installed ${bundledNames.length} bundled Askr skills into ${path.basename(targetSkillsDir)}/`);
|
|
867
|
+
io.log("");
|
|
868
|
+
} catch (error) {
|
|
869
|
+
io.error("Failed to install bundled Askr skills");
|
|
870
|
+
io.error(error instanceof Error ? error.message : String(error));
|
|
871
|
+
return 1;
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
io.log("Skipping bundled Askr skill installation (--no-skills)");
|
|
875
|
+
io.log("");
|
|
876
|
+
}
|
|
877
|
+
if (!parsed.install) {
|
|
878
|
+
io.log("Skipping dependency installation (--no-install)");
|
|
879
|
+
io.log("");
|
|
880
|
+
io.log("Next steps:");
|
|
881
|
+
io.log(` cd ${name}`);
|
|
882
|
+
io.log(" review .askr/builder-brief.md");
|
|
883
|
+
if (!parsed.skills) io.log(" askr skills install");
|
|
884
|
+
io.log(" npm install");
|
|
885
|
+
io.log(" npm run dev");
|
|
886
|
+
return 0;
|
|
887
|
+
}
|
|
888
|
+
const pm = detectPm();
|
|
889
|
+
io.log(`Installing dependencies with ${pm}...`);
|
|
890
|
+
io.log("");
|
|
891
|
+
const result = spawnSync(pm, ["install"], {
|
|
892
|
+
cwd: target,
|
|
893
|
+
stdio: "inherit",
|
|
894
|
+
shell: process.platform === "win32"
|
|
895
|
+
});
|
|
896
|
+
io.log("");
|
|
897
|
+
io.log(`Success! Created ${name}`);
|
|
898
|
+
io.log("");
|
|
899
|
+
if (result.status !== 0) {
|
|
900
|
+
io.log("Dependency installation failed. Please run manually:");
|
|
901
|
+
io.log(` cd ${name}`);
|
|
902
|
+
io.log(" review .askr/builder-brief.md");
|
|
903
|
+
if (!parsed.skills) io.log(" askr skills install");
|
|
904
|
+
io.log(` ${pm} install`);
|
|
905
|
+
io.log(` ${pm} run dev`);
|
|
906
|
+
return 1;
|
|
907
|
+
}
|
|
908
|
+
io.log("Next steps:");
|
|
909
|
+
io.log(` cd ${name}`);
|
|
910
|
+
io.log(" review .askr/builder-brief.md");
|
|
911
|
+
if (!parsed.skills) io.log(" askr skills install");
|
|
912
|
+
io.log(` ${pm} run dev`);
|
|
913
|
+
return 0;
|
|
914
|
+
}
|
|
915
|
+
async function main() {
|
|
916
|
+
const code = await runCreateCli(process.argv.slice(2));
|
|
917
|
+
process.exit(code);
|
|
918
|
+
}
|
|
919
|
+
if (isDirectExecution(import.meta.url)) main();
|
|
920
|
+
//#endregion
|
|
921
|
+
export { runCreateCli };
|
|
922
|
+
|
|
923
|
+
//# sourceMappingURL=create.js.map
|