@stacksjs/defaults 0.70.207 → 0.70.208
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/TODO.md +21 -0
- package/ai/AGENTS.md +79 -0
- package/ai/README.md +45 -0
- package/ai/claude/launch.json +12 -0
- package/ai/skills/stacks-actions/SKILL.md +128 -0
- package/ai/skills/stacks-ai/SKILL.md +276 -0
- package/ai/skills/stacks-alias/SKILL.md +94 -0
- package/ai/skills/stacks-analytics/SKILL.md +91 -0
- package/ai/skills/stacks-api/SKILL.md +738 -0
- package/ai/skills/stacks-arrays/SKILL.md +277 -0
- package/ai/skills/stacks-auth/SKILL.md +422 -0
- package/ai/skills/stacks-auto-imports/SKILL.md +138 -0
- package/ai/skills/stacks-brandkit/SKILL.md +811 -0
- package/ai/skills/stacks-browse/SKILL.md +127 -0
- package/ai/skills/stacks-browse/scripts/browse.ts +492 -0
- package/ai/skills/stacks-browser/SKILL.md +145 -0
- package/ai/skills/stacks-buddy/SKILL.md +676 -0
- package/ai/skills/stacks-build/SKILL.md +163 -0
- package/ai/skills/stacks-cache/SKILL.md +125 -0
- package/ai/skills/stacks-calendar/SKILL.md +113 -0
- package/ai/skills/stacks-chat/SKILL.md +371 -0
- package/ai/skills/stacks-cli/SKILL.md +112 -0
- package/ai/skills/stacks-cloud/SKILL.md +192 -0
- package/ai/skills/stacks-cms/SKILL.md +217 -0
- package/ai/skills/stacks-collections/SKILL.md +82 -0
- package/ai/skills/stacks-commerce/SKILL.md +114 -0
- package/ai/skills/stacks-composables/SKILL.md +161 -0
- package/ai/skills/stacks-config/SKILL.md +144 -0
- package/ai/skills/stacks-configuration/SKILL.md +154 -0
- package/ai/skills/stacks-cron/SKILL.md +123 -0
- package/ai/skills/stacks-crosswind/SKILL.md +190 -0
- package/ai/skills/stacks-dashboard/SKILL.md +173 -0
- package/ai/skills/stacks-database/SKILL.md +286 -0
- package/ai/skills/stacks-datetime/SKILL.md +269 -0
- package/ai/skills/stacks-dependencies/SKILL.md +111 -0
- package/ai/skills/stacks-deploy/SKILL.md +102 -0
- package/ai/skills/stacks-design-brutalist/SKILL.md +110 -0
- package/ai/skills/stacks-design-minimalist/SKILL.md +115 -0
- package/ai/skills/stacks-design-output/SKILL.md +55 -0
- package/ai/skills/stacks-design-soft/SKILL.md +156 -0
- package/ai/skills/stacks-design-taste/SKILL.md +1012 -0
- package/ai/skills/stacks-design-taste-codex/SKILL.md +294 -0
- package/ai/skills/stacks-desktop/SKILL.md +78 -0
- package/ai/skills/stacks-development/SKILL.md +298 -0
- package/ai/skills/stacks-dns/SKILL.md +149 -0
- package/ai/skills/stacks-docs/SKILL.md +109 -0
- package/ai/skills/stacks-email/SKILL.md +236 -0
- package/ai/skills/stacks-enums/SKILL.md +100 -0
- package/ai/skills/stacks-env/SKILL.md +181 -0
- package/ai/skills/stacks-error-handling/SKILL.md +137 -0
- package/ai/skills/stacks-events/SKILL.md +228 -0
- package/ai/skills/stacks-faker/SKILL.md +158 -0
- package/ai/skills/stacks-git/SKILL.md +158 -0
- package/ai/skills/stacks-guard/SKILL.md +98 -0
- package/ai/skills/stacks-health/SKILL.md +75 -0
- package/ai/skills/stacks-http/SKILL.md +316 -0
- package/ai/skills/stacks-i18n/SKILL.md +198 -0
- package/ai/skills/stacks-image-to-code/SKILL.md +629 -0
- package/ai/skills/stacks-imagegen-mobile/SKILL.md +1474 -0
- package/ai/skills/stacks-imagegen-web/SKILL.md +998 -0
- package/ai/skills/stacks-investigate/SKILL.md +119 -0
- package/ai/skills/stacks-jobs/SKILL.md +136 -0
- package/ai/skills/stacks-lint/SKILL.md +184 -0
- package/ai/skills/stacks-listeners/SKILL.md +99 -0
- package/ai/skills/stacks-logging/SKILL.md +78 -0
- package/ai/skills/stacks-mail/SKILL.md +120 -0
- package/ai/skills/stacks-middleware/SKILL.md +249 -0
- package/ai/skills/stacks-migrations/SKILL.md +105 -0
- package/ai/skills/stacks-models/SKILL.md +267 -0
- package/ai/skills/stacks-new-feature/SKILL.md +206 -0
- package/ai/skills/stacks-notifications/SKILL.md +210 -0
- package/ai/skills/stacks-objects/SKILL.md +205 -0
- package/ai/skills/stacks-office-hours/SKILL.md +134 -0
- package/ai/skills/stacks-orm/SKILL.md +342 -0
- package/ai/skills/stacks-path/SKILL.md +118 -0
- package/ai/skills/stacks-payments/SKILL.md +373 -0
- package/ai/skills/stacks-plan-review/SKILL.md +152 -0
- package/ai/skills/stacks-plugins/SKILL.md +149 -0
- package/ai/skills/stacks-push/SKILL.md +376 -0
- package/ai/skills/stacks-query-builder/SKILL.md +128 -0
- package/ai/skills/stacks-queue/SKILL.md +559 -0
- package/ai/skills/stacks-realtime/SKILL.md +442 -0
- package/ai/skills/stacks-redesign/SKILL.md +182 -0
- package/ai/skills/stacks-registry/SKILL.md +58 -0
- package/ai/skills/stacks-repl/SKILL.md +80 -0
- package/ai/skills/stacks-retro/SKILL.md +122 -0
- package/ai/skills/stacks-review/SKILL.md +135 -0
- package/ai/skills/stacks-router/SKILL.md +231 -0
- package/ai/skills/stacks-routes/SKILL.md +105 -0
- package/ai/skills/stacks-scaffolding/SKILL.md +162 -0
- package/ai/skills/stacks-scheduler/SKILL.md +363 -0
- package/ai/skills/stacks-search-engine/SKILL.md +112 -0
- package/ai/skills/stacks-security/SKILL.md +129 -0
- package/ai/skills/stacks-security-audit/SKILL.md +128 -0
- package/ai/skills/stacks-server/SKILL.md +458 -0
- package/ai/skills/stacks-shell/SKILL.md +62 -0
- package/ai/skills/stacks-slug/SKILL.md +87 -0
- package/ai/skills/stacks-sms/SKILL.md +385 -0
- package/ai/skills/stacks-socials/SKILL.md +303 -0
- package/ai/skills/stacks-storage/SKILL.md +576 -0
- package/ai/skills/stacks-strings/SKILL.md +416 -0
- package/ai/skills/stacks-stx/SKILL.md +176 -0
- package/ai/skills/stacks-technical-diagrams/LICENSE +22 -0
- package/ai/skills/stacks-technical-diagrams/SKILL.md +290 -0
- package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +4 -0
- package/ai/skills/stacks-technical-diagrams/assets/template.html +1252 -0
- package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +289 -0
- package/ai/skills/stacks-technical-diagrams/bunfig.toml +1 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +64 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +88 -0
- package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +75 -0
- package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +70 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +41 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +62 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +371 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +82 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +295 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +91 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +384 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +84 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +257 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +42 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +13 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +230 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +88 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +103 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +481 -0
- package/ai/skills/stacks-technical-diagrams/schemas/README.md +68 -0
- package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +121 -0
- package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +43 -0
- package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +221 -0
- package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +241 -0
- package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +186 -0
- package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +332 -0
- package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +297 -0
- package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +28 -0
- package/ai/skills/stacks-testing/SKILL.md +129 -0
- package/ai/skills/stacks-tunnel/SKILL.md +125 -0
- package/ai/skills/stacks-types/SKILL.md +178 -0
- package/ai/skills/stacks-ui/SKILL.md +246 -0
- package/ai/skills/stacks-utils/SKILL.md +444 -0
- package/ai/skills/stacks-validation/SKILL.md +371 -0
- package/ai/skills/stacks-whois/SKILL.md +315 -0
- package/assets/world-map-data.ts +121 -0
- package/bootstrap.ts +114 -0
- package/docs/api-examples.md +46 -0
- package/docs/index.md +24 -0
- package/docs/markdown-examples.md +87 -0
- package/functions/analytics.ts +97 -0
- package/functions/api.ts +143 -0
- package/functions/auth.ts +208 -0
- package/functions/billing/payments.ts +149 -0
- package/functions/blog.ts +120 -0
- package/functions/cms/categorizables.ts +107 -0
- package/functions/cms/pages.ts +108 -0
- package/functions/cms/posts.ts +100 -0
- package/functions/cms/taggables.ts +102 -0
- package/functions/commerce/coupons.ts +128 -0
- package/functions/commerce/customers.ts +128 -0
- package/functions/commerce/gift-cards.ts +119 -0
- package/functions/commerce/orders.ts +112 -0
- package/functions/commerce/payments.ts +119 -0
- package/functions/commerce/products/categories.ts +123 -0
- package/functions/commerce/products/manufacturers.ts +123 -0
- package/functions/commerce/products/products.ts +123 -0
- package/functions/commerce/products/reviews.ts +123 -0
- package/functions/commerce/products/units.ts +123 -0
- package/functions/commerce/products/variants.ts +123 -0
- package/functions/commerce/shippings/delivery-routes.ts +123 -0
- package/functions/commerce/shippings/digital-deliveries.ts +119 -0
- package/functions/commerce/shippings/drivers.ts +123 -0
- package/functions/commerce/shippings/license-keys.ts +123 -0
- package/functions/commerce/shippings/shipping-methods.ts +123 -0
- package/functions/commerce/shippings/shipping-rates.ts +119 -0
- package/functions/commerce/shippings/shipping-zones.ts +119 -0
- package/functions/commerce/taxes.ts +119 -0
- package/functions/commerce/waitlist/products.ts +123 -0
- package/functions/commerce/waitlist/restaurants.ts +123 -0
- package/functions/craft.ts +107 -0
- package/functions/dashboard.ts +153 -0
- package/functions/inbox.ts +95 -0
- package/functions/jobs.ts +86 -0
- package/functions/monitoring/errors.ts +295 -0
- package/functions/queue.ts +111 -0
- package/functions/realtime/websockets.ts +96 -0
- package/functions/realtime.ts +52 -0
- package/functions/releases.ts +49 -0
- package/functions/search.ts +126 -0
- package/functions/toasts.ts +95 -0
- package/functions/uploads.ts +216 -0
- package/ide/.gitignore +4 -0
- package/ide/cursor/rules/auto-imports.mdc +574 -0
- package/ide/cursor/rules/code-style.mdc +12 -0
- package/ide/cursor/rules/documentation.mdc +9 -0
- package/ide/cursor/rules/error-handling-validation.mdc +11 -0
- package/ide/cursor/rules/key-conventions.mdc +11 -0
- package/ide/cursor/rules/project-structure.mdc +169 -0
- package/ide/cursor/rules/readme.mdc +318 -0
- package/ide/cursor/rules/syntax-formatting.mdc +9 -0
- package/ide/cursor/rules/testing.mdc +10 -0
- package/ide/cursor/rules/typescript.mdc +9 -0
- package/ide/cursor/rules/ui-styling.mdc +0 -0
- package/ide/dictionary.txt +397 -0
- package/ide/jetbrains/.fleet/settings.json +4 -0
- package/ide/jetbrains/.idea/.gitignore +5 -0
- package/ide/jetbrains/.idea/.name +1 -0
- package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/ide/jetbrains/.idea/jsLinters/eslint.xml +7 -0
- package/ide/jetbrains/.idea/modules.xml +8 -0
- package/ide/jetbrains/.idea/stacks.iml +22 -0
- package/ide/jetbrains/.idea/vcs.xml +6 -0
- package/ide/jetbrains/.idea/webResources.xml +14 -0
- package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
- package/ide/jetbrains/installed.txt +4 -0
- package/ide/jetbrains/options/github-copilot.xml +5 -0
- package/ide/jetbrains/options/nodejs.xml +7 -0
- package/ide/jetbrains/options/templates.xml +124 -0
- package/ide/jetbrains/templates/JavaScript.xml +6 -0
- package/ide/jetbrains/templates/Stacks.xml +8 -0
- package/ide/vscode/.vscode/README.md +23 -0
- package/ide/vscode/.vscode/extensions.json +5 -0
- package/ide/vscode/.vscode/settings.json +176 -0
- package/ide/vscode/.vscode/stacks.code-snippets +181 -0
- package/ide/vscode/LICENSE.md +21 -0
- package/ide/vscode/README.md +36 -0
- package/ide/vscode/logo.png +0 -0
- package/ide/vscode/package.json +79 -0
- package/ide/zed/.zed/settings.json +139 -0
- package/lang/README.md +28 -0
- package/lang/de.yml +14 -0
- package/lang/en.yml +15 -0
- package/package.json +19 -3
- package/project/bootstrap +161 -0
- package/project/buddy +175 -0
- package/project/storage/framework/tsconfig.app.json +50 -0
- package/project/storage/framework/tsconfig.base.json +58 -0
- package/routes/core.ts +78 -0
- package/routes/dashboard-api.ts +233 -0
- package/routes/dashboard.ts +739 -0
- package/routes/email.ts +129 -0
- package/stores/[name].stx +16 -0
- package/stores/git.ts +71 -0
- package/stores/payment.ts +474 -0
- package/stores/queue.ts +43 -0
- package/stores/user.ts +29 -0
- package/stx-components-plugin.ts +25 -0
- package/styles/design-tokens.css +597 -0
- package/types/dashboard.ts +70 -0
- package/types/defaults.ts +438 -0
- package/vcs/github/CODE_OF_CONDUCT.md +83 -0
- package/vcs/github/CONTRIBUTING.md +187 -0
- package/vcs/github/EXPLANATIONS.md +41 -0
- package/vcs/github/FUNDING.yml +1 -0
- package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +49 -0
- package/vcs/github/ISSUE_TEMPLATE/config.yml +10 -0
- package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +44 -0
- package/vcs/github/SECURITY.md +70 -0
- package/vcs/github/renovate.json +5 -0
- package/vcs/github/stale.yml +14 -0
- package/vcs/github/workflows/README.md +16 -0
- package/vcs/github/workflows/ci.yml +114 -0
- package/vcs/github/workflows/export-size.yml +25 -0
- package/vcs/github/workflows/labeler.yml +13 -0
- package/vcs/github/workflows/release.yml +219 -0
- package/views/[...all].stx +8 -0
- package/views/about.md +3 -0
- package/views/auth/login.stx +1 -0
- package/views/auth/signup.stx +85 -0
- package/views/dashboard/.discovered-models.json +542 -0
- package/views/dashboard/AUDIT.md +904 -0
- package/views/dashboard/[...all].stx +89 -0
- package/views/dashboard/access-tokens/index.stx +177 -0
- package/views/dashboard/actions/index.stx +129 -0
- package/views/dashboard/analytics/blog/index.stx +356 -0
- package/views/dashboard/analytics/browsers/index.stx +263 -0
- package/views/dashboard/analytics/commerce/sales/index.stx +329 -0
- package/views/dashboard/analytics/commerce/web/index.stx +379 -0
- package/views/dashboard/analytics/countries/index.stx +289 -0
- package/views/dashboard/analytics/devices/index.stx +305 -0
- package/views/dashboard/analytics/events/index.stx +536 -0
- package/views/dashboard/analytics/index.stx +88 -0
- package/views/dashboard/analytics/marketing/index.stx +315 -0
- package/views/dashboard/analytics/pages/index.stx +271 -0
- package/views/dashboard/analytics/referrers/index.stx +319 -0
- package/views/dashboard/analytics/web/index.stx +356 -0
- package/views/dashboard/buddy/index.stx +198 -0
- package/views/dashboard/ci/index.stx +462 -0
- package/views/dashboard/cloud/index.stx +452 -0
- package/views/dashboard/commands/index.stx +295 -0
- package/views/dashboard/commerce/categories/index.stx +406 -0
- package/views/dashboard/commerce/coupons/index.stx +485 -0
- package/views/dashboard/commerce/customers/index.stx +410 -0
- package/views/dashboard/commerce/dashboard/index.stx +287 -0
- package/views/dashboard/commerce/delivery/delivery-routes.stx +305 -0
- package/views/dashboard/commerce/delivery/digital-delivery.stx +332 -0
- package/views/dashboard/commerce/delivery/drivers.stx +397 -0
- package/views/dashboard/commerce/delivery/index.stx +18 -0
- package/views/dashboard/commerce/delivery/license-keys.stx +380 -0
- package/views/dashboard/commerce/delivery/shipping-methods.stx +346 -0
- package/views/dashboard/commerce/delivery/shipping-rates.stx +338 -0
- package/views/dashboard/commerce/delivery/shipping-zones.stx +302 -0
- package/views/dashboard/commerce/delivery/tabs.ts +25 -0
- package/views/dashboard/commerce/gift-cards/index.stx +561 -0
- package/views/dashboard/commerce/manufacturers/index.stx +308 -0
- package/views/dashboard/commerce/orders/index.stx +247 -0
- package/views/dashboard/commerce/payments/index.stx +535 -0
- package/views/dashboard/commerce/pos/index.stx +653 -0
- package/views/dashboard/commerce/printers/devices/index.stx +273 -0
- package/views/dashboard/commerce/printers/receipts/index.stx +308 -0
- package/views/dashboard/commerce/products/detail.stx +563 -0
- package/views/dashboard/commerce/products/index.stx +370 -0
- package/views/dashboard/commerce/reviews/index.stx +656 -0
- package/views/dashboard/commerce/reviews/index.ts +0 -0
- package/views/dashboard/commerce/taxes/index.stx +377 -0
- package/views/dashboard/commerce/units/index.stx +317 -0
- package/views/dashboard/commerce/variants/index.stx +319 -0
- package/views/dashboard/commerce/waitlist/products.stx +942 -0
- package/views/dashboard/commerce/waitlist/restaurant.stx +1024 -0
- package/views/dashboard/components/index.stx +330 -0
- package/views/dashboard/composables/index.ts +19 -0
- package/views/dashboard/composables/useChart.ts +77 -0
- package/views/dashboard/composables/useNavigation.ts +99 -0
- package/views/dashboard/composables/useRole.ts +58 -0
- package/views/dashboard/composables/useTheme.ts +74 -0
- package/views/dashboard/content/authors/index.stx +171 -0
- package/views/dashboard/content/blog/index.stx +493 -0
- package/views/dashboard/content/categories/index.stx +169 -0
- package/views/dashboard/content/comments/index.stx +189 -0
- package/views/dashboard/content/dashboard.stx +383 -0
- package/views/dashboard/content/files/index.stx +706 -0
- package/views/dashboard/content/pages/index.stx +174 -0
- package/views/dashboard/content/posts/index.stx +269 -0
- package/views/dashboard/content/seo/index.stx +240 -0
- package/views/dashboard/content/tags/index.stx +167 -0
- package/views/dashboard/data/activity/index.stx +261 -0
- package/views/dashboard/data/dashboard/index.stx +116 -0
- package/views/dashboard/data/subscribers.stx +270 -0
- package/views/dashboard/data/teams.stx +275 -0
- package/views/dashboard/data/users.stx +279 -0
- package/views/dashboard/dependencies/index.stx +178 -0
- package/views/dashboard/deployments/[id].stx +234 -0
- package/views/dashboard/deployments/index.stx +9 -0
- package/views/dashboard/dns/index.stx +163 -0
- package/views/dashboard/environment/index.stx +283 -0
- package/views/dashboard/errors/index.stx +274 -0
- package/views/dashboard/forgot-password.stx +57 -0
- package/views/dashboard/functions/index.stx +159 -0
- package/views/dashboard/health/index.stx +248 -0
- package/views/dashboard/inbox/activity.stx +350 -0
- package/views/dashboard/inbox/index.stx +452 -0
- package/views/dashboard/inbox/settings.stx +290 -0
- package/views/dashboard/index.stx +252 -0
- package/views/dashboard/insights/index.stx +529 -0
- package/views/dashboard/jobs/[id].stx +430 -0
- package/views/dashboard/jobs/history.stx +222 -0
- package/views/dashboard/jobs/index.stx +214 -0
- package/views/dashboard/kanban/[id].stx +899 -0
- package/views/dashboard/kanban/index.stx +260 -0
- package/views/dashboard/layouts/default.stx +565 -0
- package/views/dashboard/layouts/guest.stx +10 -0
- package/views/dashboard/login.stx +48 -0
- package/views/dashboard/logs/index.stx +540 -0
- package/views/dashboard/mailboxes/index.stx +149 -0
- package/views/dashboard/management/permissions/index.stx +490 -0
- package/views/dashboard/marketing/campaigns/index.stx +604 -0
- package/views/dashboard/marketing/lists/index.stx +514 -0
- package/views/dashboard/marketing/reviews/index.stx +475 -0
- package/views/dashboard/marketing/social-posts/index.stx +560 -0
- package/views/dashboard/models/[model].stx +195 -0
- package/views/dashboard/models/index.stx +159 -0
- package/views/dashboard/monitoring/errors/index.stx +415 -0
- package/views/dashboard/notifications/dashboard.stx +383 -0
- package/views/dashboard/notifications/email.stx +336 -0
- package/views/dashboard/notifications/history.stx +373 -0
- package/views/dashboard/notifications/sms.stx +332 -0
- package/views/dashboard/packages/index.stx +195 -0
- package/views/dashboard/queries/[id].stx +381 -0
- package/views/dashboard/queries/history.stx +227 -0
- package/views/dashboard/queries/index.stx +335 -0
- package/views/dashboard/queries/slow.stx +318 -0
- package/views/dashboard/queue/index.stx +427 -0
- package/views/dashboard/realtime/index.stx +429 -0
- package/views/dashboard/register.stx +46 -0
- package/views/dashboard/releases/index.stx +389 -0
- package/views/dashboard/requests/index.stx +462 -0
- package/views/dashboard/serverless/index.stx +475 -0
- package/views/dashboard/servers/[id].stx +299 -0
- package/views/dashboard/servers/index.stx +483 -0
- package/views/dashboard/settings/billing.stx +50 -0
- package/views/dashboard/settings/index.stx +256 -0
- package/views/dashboard/settings/mail.stx +252 -0
- package/views/dashboard/stores/auth.ts +123 -0
- package/views/dashboard/stores/ci.ts +342 -0
- package/views/dashboard/stores/index.ts +129 -0
- package/views/dashboard/stores/kanban.ts +723 -0
- package/views/dashboard/stores/rbac.ts +350 -0
- package/views/dashboard/stx.config.ts +34 -0
- package/views/dashboard/teams/[id].stx +170 -0
- package/views/forum/category.stx +92 -0
- package/views/forum/index.stx +209 -0
- package/views/forum/new-topic.stx +113 -0
- package/views/forum/profile.stx +1 -0
- package/views/forum/topic.stx +143 -0
- package/views/hello-world/[name].stx +47 -0
- package/views/index.stx +21 -0
- package/views/system-tray/index.stx +147 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-chat
|
|
3
|
+
description: Use when implementing chat messaging in Stacks — sending messages to Slack (webhooks, bot tokens, block kit), Discord (webhooks, bot tokens, embeds), Microsoft Teams (adaptive cards, webhooks), the BaseChatDriver abstraction, retry logic, or multi-channel chat routing. Covers @stacksjs/chat.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Chat
|
|
10
|
+
|
|
11
|
+
Multi-driver chat messaging with Slack, Discord, and Microsoft Teams support. Each driver supports both webhook and bot token modes, with retry logic and structured message formats.
|
|
12
|
+
|
|
13
|
+
## Key Paths
|
|
14
|
+
- Core package: `storage/framework/core/chat/src/`
|
|
15
|
+
- Types: `storage/framework/core/types/src/chat.ts`
|
|
16
|
+
|
|
17
|
+
## Source Files
|
|
18
|
+
```
|
|
19
|
+
chat/src/
|
|
20
|
+
├── index.ts # router, configure functions, type re-exports
|
|
21
|
+
└── drivers/
|
|
22
|
+
├── base.ts # BaseChatDriver abstract class
|
|
23
|
+
├── slack.ts # SlackDriver + sendWebhook()
|
|
24
|
+
├── discord.ts # DiscordDriver + sendWebhook() + sendEmbed()
|
|
25
|
+
└── teams.ts # TeamsDriver + sendWebhook() + sendCard()
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Router (index.ts)
|
|
29
|
+
|
|
30
|
+
The main `send()` function routes to the specified driver. Default driver is `'slack'`:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { send, sendToSlack, sendToDiscord, sendToTeams } from '@stacksjs/chat'
|
|
34
|
+
|
|
35
|
+
// Route to driver (default: 'slack')
|
|
36
|
+
await send(message, { driver: 'slack' })
|
|
37
|
+
await send(message, { driver: 'discord' })
|
|
38
|
+
await send(message, { driver: 'teams' })
|
|
39
|
+
|
|
40
|
+
// Direct webhook helpers
|
|
41
|
+
await sendToSlack(webhookUrl, text, options?)
|
|
42
|
+
await sendToDiscord(webhookUrl, content, options?)
|
|
43
|
+
await sendToTeams(webhookUrl, text)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Configure functions:
|
|
47
|
+
```typescript
|
|
48
|
+
import { configureSlack, configureDiscord, configureTeams } from '@stacksjs/chat'
|
|
49
|
+
configureSlack({ webhookUrl: '...', botToken: '...' })
|
|
50
|
+
configureDiscord({ webhookUrl: '...', botToken: '...' })
|
|
51
|
+
configureTeams({ webhookUrl: '...' })
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Exported types: `ChatDriver` (union), `SendOptions`, `SlackConfig`, `SlackMessage`, `SlackBlock`, `SlackAttachment`, `DiscordConfig`, `DiscordMessage`, `DiscordEmbed`, `TeamsConfig`, `TeamsMessage`, `TeamsAdaptiveCard`, `TeamsCardElement`, `TeamsCardAction`
|
|
55
|
+
|
|
56
|
+
## BaseChatDriver (base.ts)
|
|
57
|
+
|
|
58
|
+
Abstract base class all drivers extend. Implements `ChatDriver` interface from `@stacksjs/types`:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
abstract class BaseChatDriver implements ChatDriver {
|
|
62
|
+
public abstract name: string
|
|
63
|
+
protected config: Required<ChatDriverConfig>
|
|
64
|
+
|
|
65
|
+
constructor(config?: ChatDriverConfig) // defaults: maxRetries=3, retryTimeout=1000
|
|
66
|
+
|
|
67
|
+
configure(config: ChatDriverConfig): void
|
|
68
|
+
abstract send(message: ChatMessage, options?: RenderOptions): Promise<ChatResult>
|
|
69
|
+
|
|
70
|
+
// Protected helpers
|
|
71
|
+
protected validateMessage(message: ChatMessage): boolean // throws if no `to` or no `content`/`template`
|
|
72
|
+
protected async handleError(error: unknown, message: ChatMessage): Promise<ChatResult>
|
|
73
|
+
protected async handleSuccess(message: ChatMessage, messageId?: string): Promise<ChatResult>
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- `handleError()` logs the error, then calls `message.onError()` if defined, returns `ChatResult` with `success: false`
|
|
78
|
+
- `handleSuccess()` calls `message.handle()` first, then `message.onSuccess()` if defined, returns `ChatResult` with `success: true`
|
|
79
|
+
- Both handlers merge any partial result from callbacks into the final `ChatResult`
|
|
80
|
+
|
|
81
|
+
## ChatMessage Interface (from @stacksjs/types)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
interface ChatMessage {
|
|
85
|
+
to: string | string[] // recipient (channel ID, user ID, etc.)
|
|
86
|
+
from?: { id?: string, name?: string, avatar?: string }
|
|
87
|
+
subject?: string // title for rich messages
|
|
88
|
+
content?: string // plain text content
|
|
89
|
+
template?: string // template for rich message rendering
|
|
90
|
+
data?: Record<string, any> // template data
|
|
91
|
+
attachments?: ChatAttachment[]
|
|
92
|
+
onSuccess?: () => void | Promise<void> | Partial<ChatResult>
|
|
93
|
+
onError?: (error: Error) => void | Promise<void> | Partial<ChatResult>
|
|
94
|
+
handle?: () => void | Promise<void> | Partial<ChatResult>
|
|
95
|
+
[key: string]: any // custom platform-specific fields
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## ChatResult Interface (from @stacksjs/types)
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
interface ChatResult {
|
|
103
|
+
success: boolean
|
|
104
|
+
message: string
|
|
105
|
+
provider: string // 'slack' | 'discord' | 'teams'
|
|
106
|
+
messageId?: string
|
|
107
|
+
data?: Record<string, any>
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Slack Driver
|
|
112
|
+
|
|
113
|
+
### SlackConfig
|
|
114
|
+
```typescript
|
|
115
|
+
interface SlackConfig {
|
|
116
|
+
webhookUrl?: string
|
|
117
|
+
botToken?: string
|
|
118
|
+
maxRetries?: number // default: 3
|
|
119
|
+
retryTimeout?: number // default: 1000ms
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### SlackMessage (for webhook payloads)
|
|
124
|
+
```typescript
|
|
125
|
+
interface SlackMessage {
|
|
126
|
+
channel?: string
|
|
127
|
+
text?: string
|
|
128
|
+
blocks?: SlackBlock[]
|
|
129
|
+
attachments?: SlackAttachment[]
|
|
130
|
+
username?: string
|
|
131
|
+
iconEmoji?: string
|
|
132
|
+
iconUrl?: string
|
|
133
|
+
threadTs?: string
|
|
134
|
+
mrkdwn?: boolean
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### SlackBlock
|
|
139
|
+
```typescript
|
|
140
|
+
interface SlackBlock {
|
|
141
|
+
type: 'section' | 'divider' | 'header' | 'context' | 'actions' | 'image'
|
|
142
|
+
text?: { type: 'plain_text' | 'mrkdwn', text: string, emoji?: boolean }
|
|
143
|
+
accessory?: any
|
|
144
|
+
elements?: any[]
|
|
145
|
+
block_id?: string
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### SlackAttachment
|
|
150
|
+
```typescript
|
|
151
|
+
interface SlackAttachment {
|
|
152
|
+
color?: string
|
|
153
|
+
pretext?: string
|
|
154
|
+
author_name?: string
|
|
155
|
+
author_link?: string
|
|
156
|
+
author_icon?: string
|
|
157
|
+
title?: string
|
|
158
|
+
title_link?: string
|
|
159
|
+
text?: string
|
|
160
|
+
fields?: Array<{ title: string, value: string, short?: boolean }>
|
|
161
|
+
image_url?: string
|
|
162
|
+
thumb_url?: string
|
|
163
|
+
footer?: string
|
|
164
|
+
footer_icon?: string
|
|
165
|
+
ts?: number
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Slack Sending Modes
|
|
170
|
+
|
|
171
|
+
1. **Webhook mode**: If `config.webhookUrl` is set, sends via `POST` to webhook URL. Payload includes `text`, `username`, `mrkdwn: true`. If `message.template` exists, builds Block Kit blocks.
|
|
172
|
+
2. **Bot token mode**: If `config.botToken` is set, sends via Slack API `https://slack.com/api/chat.postMessage` with `Authorization: Bearer <token>`. Returns `ts` (timestamp) as message ID.
|
|
173
|
+
3. Throws `Error('Slack not configured: provide webhookUrl or botToken')` if neither is set.
|
|
174
|
+
|
|
175
|
+
### Direct Webhook Function
|
|
176
|
+
```typescript
|
|
177
|
+
async function sendWebhook(webhookUrl: string, text: string, options?: Partial<SlackMessage>): Promise<ChatResult>
|
|
178
|
+
```
|
|
179
|
+
Merges `options` into payload, sends POST to the provided webhook URL.
|
|
180
|
+
|
|
181
|
+
### Block Building
|
|
182
|
+
When `message.template` is set, `buildBlocks()` creates:
|
|
183
|
+
- A `header` block from `message.subject` (if present)
|
|
184
|
+
- A `section` block from `message.content` with `mrkdwn` type
|
|
185
|
+
|
|
186
|
+
### Exports
|
|
187
|
+
- `SlackDriver` class (also as `Driver`)
|
|
188
|
+
- `driver` -- pre-instantiated `SlackDriver` singleton
|
|
189
|
+
- `send()`, `sendWebhook()`, `configure()` functions
|
|
190
|
+
|
|
191
|
+
## Discord Driver
|
|
192
|
+
|
|
193
|
+
### DiscordConfig
|
|
194
|
+
```typescript
|
|
195
|
+
interface DiscordConfig {
|
|
196
|
+
webhookUrl?: string
|
|
197
|
+
botToken?: string
|
|
198
|
+
maxRetries?: number // default: 3
|
|
199
|
+
retryTimeout?: number // default: 1000ms
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### DiscordEmbed
|
|
204
|
+
```typescript
|
|
205
|
+
interface DiscordEmbed {
|
|
206
|
+
title?: string
|
|
207
|
+
description?: string
|
|
208
|
+
url?: string
|
|
209
|
+
color?: number // integer color value (e.g. 0x5865F2)
|
|
210
|
+
timestamp?: string // ISO 8601
|
|
211
|
+
footer?: { text: string, icon_url?: string }
|
|
212
|
+
image?: { url: string }
|
|
213
|
+
thumbnail?: { url: string }
|
|
214
|
+
author?: { name: string, url?: string, icon_url?: string }
|
|
215
|
+
fields?: Array<{ name: string, value: string, inline?: boolean }>
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### DiscordMessage
|
|
220
|
+
```typescript
|
|
221
|
+
interface DiscordMessage {
|
|
222
|
+
content?: string
|
|
223
|
+
username?: string
|
|
224
|
+
avatarUrl?: string
|
|
225
|
+
tts?: boolean
|
|
226
|
+
embeds?: DiscordEmbed[]
|
|
227
|
+
allowedMentions?: {
|
|
228
|
+
parse?: Array<'roles' | 'users' | 'everyone'>
|
|
229
|
+
roles?: string[]
|
|
230
|
+
users?: string[]
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Discord Sending Modes
|
|
236
|
+
|
|
237
|
+
1. **Webhook mode**: POST to `config.webhookUrl`. Handles `204` (empty success) responses. Returns `id` from response.
|
|
238
|
+
2. **Bot token mode**: POST to `https://discord.com/api/v10/channels/{channelId}/messages` with `Authorization: Bot <token>`. Uses `message.to` as the channel ID.
|
|
239
|
+
|
|
240
|
+
### Embed Building
|
|
241
|
+
When `message.subject` or `message.template` is set, `buildEmbed()` creates an embed with:
|
|
242
|
+
- `title` from `message.subject`
|
|
243
|
+
- `description` from `message.content`
|
|
244
|
+
- Default color: `0x5865F2` (Discord blurple)
|
|
245
|
+
- `timestamp`: current ISO date
|
|
246
|
+
|
|
247
|
+
### Extra Functions
|
|
248
|
+
```typescript
|
|
249
|
+
async function sendWebhook(webhookUrl: string, content: string, options?: Partial<DiscordMessage>): Promise<ChatResult>
|
|
250
|
+
async function sendEmbed(webhookUrl: string, embed: DiscordEmbed, options?: Partial<DiscordMessage>): Promise<ChatResult>
|
|
251
|
+
```
|
|
252
|
+
`sendEmbed()` wraps the embed inside `sendWebhook()` with empty content.
|
|
253
|
+
|
|
254
|
+
### Exports
|
|
255
|
+
- `DiscordDriver` class (also as `Driver`)
|
|
256
|
+
- `driver` -- pre-instantiated singleton
|
|
257
|
+
- `send()`, `sendWebhook()`, `sendEmbed()`, `configure()` functions
|
|
258
|
+
|
|
259
|
+
## Teams Driver
|
|
260
|
+
|
|
261
|
+
### TeamsConfig
|
|
262
|
+
```typescript
|
|
263
|
+
interface TeamsConfig {
|
|
264
|
+
webhookUrl?: string
|
|
265
|
+
maxRetries?: number // default: 3
|
|
266
|
+
retryTimeout?: number // default: 1000ms
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### TeamsAdaptiveCard
|
|
271
|
+
```typescript
|
|
272
|
+
interface TeamsAdaptiveCard {
|
|
273
|
+
type: 'AdaptiveCard'
|
|
274
|
+
version: string // '1.4'
|
|
275
|
+
body: TeamsCardElement[]
|
|
276
|
+
actions?: TeamsCardAction[]
|
|
277
|
+
$schema?: string // 'http://adaptivecards.io/schemas/adaptive-card.json'
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### TeamsCardElement
|
|
282
|
+
```typescript
|
|
283
|
+
interface TeamsCardElement {
|
|
284
|
+
type: 'TextBlock' | 'Image' | 'Container' | 'ColumnSet' | 'Column' | 'FactSet' | 'ImageSet'
|
|
285
|
+
text?: string
|
|
286
|
+
size?: 'Small' | 'Default' | 'Medium' | 'Large' | 'ExtraLarge'
|
|
287
|
+
weight?: 'Lighter' | 'Default' | 'Bolder'
|
|
288
|
+
color?: 'Default' | 'Dark' | 'Light' | 'Accent' | 'Good' | 'Warning' | 'Attention'
|
|
289
|
+
wrap?: boolean
|
|
290
|
+
url?: string
|
|
291
|
+
altText?: string
|
|
292
|
+
items?: TeamsCardElement[]
|
|
293
|
+
columns?: TeamsCardElement[]
|
|
294
|
+
width?: string
|
|
295
|
+
facts?: Array<{ title: string, value: string }>
|
|
296
|
+
images?: Array<{ type: 'Image', url: string, size?: string }>
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### TeamsCardAction
|
|
301
|
+
```typescript
|
|
302
|
+
interface TeamsCardAction {
|
|
303
|
+
type: 'Action.OpenUrl' | 'Action.Submit' | 'Action.ShowCard'
|
|
304
|
+
title: string
|
|
305
|
+
url?: string
|
|
306
|
+
data?: Record<string, any>
|
|
307
|
+
card?: TeamsAdaptiveCard
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### TeamsMessage
|
|
312
|
+
```typescript
|
|
313
|
+
interface TeamsMessage {
|
|
314
|
+
type?: 'message'
|
|
315
|
+
summary?: string
|
|
316
|
+
text?: string
|
|
317
|
+
attachments?: Array<{
|
|
318
|
+
contentType: 'application/vnd.microsoft.card.adaptive'
|
|
319
|
+
content: TeamsAdaptiveCard
|
|
320
|
+
}>
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Teams Sending
|
|
325
|
+
|
|
326
|
+
- Uses `config.webhookUrl` or falls back to `message.to` as the webhook URL
|
|
327
|
+
- Validates URL contains `webhook.office.com`
|
|
328
|
+
- Simple messages (no subject/template): sends `{ type: 'message', text: content }`
|
|
329
|
+
- Rich messages (with subject or template): builds an Adaptive Card v1.4 with:
|
|
330
|
+
- Title as `TextBlock` (size: Large, weight: Bolder)
|
|
331
|
+
- Content as `TextBlock` (wrap: true)
|
|
332
|
+
- Timestamp as `TextBlock` (size: Small, color: Dark)
|
|
333
|
+
|
|
334
|
+
### Extra Functions
|
|
335
|
+
```typescript
|
|
336
|
+
async function sendWebhook(webhookUrl: string, text: string): Promise<ChatResult>
|
|
337
|
+
async function sendCard(webhookUrl: string, card: TeamsAdaptiveCard, summary?: string): Promise<ChatResult>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Exports
|
|
341
|
+
- `TeamsDriver` class (also as `Driver`)
|
|
342
|
+
- `driver` -- pre-instantiated singleton
|
|
343
|
+
- `send()`, `sendWebhook()`, `sendCard()`, `configure()` functions
|
|
344
|
+
|
|
345
|
+
## Retry Logic
|
|
346
|
+
|
|
347
|
+
All three drivers implement `sendWithRetry()`:
|
|
348
|
+
- Retries up to `config.maxRetries` times (default 3)
|
|
349
|
+
- Waits `config.retryTimeout` ms between attempts (default 1000ms)
|
|
350
|
+
- On final failure, throws the error (caught by the outer `send()` which calls `handleError()`)
|
|
351
|
+
|
|
352
|
+
## Dependencies
|
|
353
|
+
- `@stacksjs/types` -- `ChatMessage`, `ChatResult`, `RenderOptions`, `ChatDriver`, `ChatDriverConfig`
|
|
354
|
+
- `@stacksjs/logging` -- `log` for info/warn/error logging
|
|
355
|
+
|
|
356
|
+
## Gotchas
|
|
357
|
+
- The default driver for `send()` is `'slack'`, not auto-detected
|
|
358
|
+
- Each driver has two modes: webhook (simpler) and bot token (richer, returns message IDs)
|
|
359
|
+
- Slack bot token mode uses `https://slack.com/api/chat.postMessage`, not a webhook
|
|
360
|
+
- Discord webhook returns `204` on success with no body -- this is handled as success
|
|
361
|
+
- Discord bot token mode uses `message.to` as the channel ID
|
|
362
|
+
- Teams validates that the webhook URL contains `webhook.office.com`
|
|
363
|
+
- Teams uses `message.to` as fallback webhook URL if `config.webhookUrl` is not set
|
|
364
|
+
- All drivers set `mrkdwn: true` or equivalent by default
|
|
365
|
+
- Block Kit blocks are only built when `message.template` is set (Slack) or when `message.subject`/`message.template` is set (Discord/Teams)
|
|
366
|
+
- `validateMessage()` requires both `to` and either `content` or `template`
|
|
367
|
+
- The `handle()` callback runs before `onSuccess()` -- both results are merged
|
|
368
|
+
- `ChatMessage` supports `onSuccess`, `onError`, and `handle` callbacks that can return partial `ChatResult` objects
|
|
369
|
+
- Each driver module exports a pre-instantiated `driver` singleton and both class-based and function-based APIs
|
|
370
|
+
- Discord embed default color is `0x5865F2` (Discord blurple), not customizable via the auto-build path
|
|
371
|
+
- Teams Adaptive Cards use version `1.4` with the official JSON schema URL
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-cli
|
|
3
|
+
description: Use when building CLI commands or tools with Stacks — the @stacksjs/cli package for creating commands with argument parsing, option handling, colored output, tables, progress indicators, prompts, or integrating with the buddy command system. Covers @stacksjs/cli and app/Commands/.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks CLI Framework
|
|
10
|
+
|
|
11
|
+
The `@stacksjs/cli` package provides the foundation for building CLI commands, used internally by the buddy CLI.
|
|
12
|
+
|
|
13
|
+
## Key Paths
|
|
14
|
+
- Core package: `storage/framework/core/cli/src/`
|
|
15
|
+
- CLI configuration: `config/cli.ts`
|
|
16
|
+
- Application commands: `app/Commands/`
|
|
17
|
+
- Command registry: `app/Commands.ts`
|
|
18
|
+
|
|
19
|
+
## Creating Commands
|
|
20
|
+
|
|
21
|
+
### Simple Command
|
|
22
|
+
```typescript
|
|
23
|
+
// app/Commands/Greet.ts
|
|
24
|
+
export default {
|
|
25
|
+
name: 'greet',
|
|
26
|
+
description: 'Greet a user',
|
|
27
|
+
alias: 'g',
|
|
28
|
+
options: {
|
|
29
|
+
name: { alias: 'n', description: 'Name to greet', default: 'World' },
|
|
30
|
+
loud: { alias: 'l', description: 'Shout the greeting', type: 'boolean' }
|
|
31
|
+
},
|
|
32
|
+
handle: async ({ options }) => {
|
|
33
|
+
const greeting = `Hello, ${options.name}!`
|
|
34
|
+
console.log(options.loud ? greeting.toUpperCase() : greeting)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Register in app/Commands.ts
|
|
40
|
+
```typescript
|
|
41
|
+
export default {
|
|
42
|
+
'greet': 'Greet',
|
|
43
|
+
'inspire': 'Inspire',
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Three Registration Methods
|
|
48
|
+
1. **app/Commands.ts** — name → file mapping
|
|
49
|
+
2. **Event listeners** — CLI events in `app/Listeners/Console.ts`
|
|
50
|
+
3. **Inline** — direct command definitions
|
|
51
|
+
|
|
52
|
+
## CLI Event Listeners
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// app/Listeners/Console.ts
|
|
56
|
+
export default function(cli: CLI) {
|
|
57
|
+
cli.on('custom:command', () => {
|
|
58
|
+
console.log('Custom command executed!')
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
cli.on('my:*', () => {
|
|
62
|
+
// Wildcard — matches my:anything
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
cli.on('unknown:!', () => {
|
|
66
|
+
// Default/fallback handler
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Output Formatting
|
|
72
|
+
|
|
73
|
+
Via `@stacksjs/utils` color functions (available in CLI context):
|
|
74
|
+
```typescript
|
|
75
|
+
import { bold, green, red, yellow, dim, underline } from '@stacksjs/utils'
|
|
76
|
+
|
|
77
|
+
console.log(green('✓ Success'))
|
|
78
|
+
console.log(red('✗ Error'))
|
|
79
|
+
console.log(yellow('⚠ Warning'))
|
|
80
|
+
console.log(bold('Important'))
|
|
81
|
+
console.log(dim('Subtle info'))
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## config/cli.ts (BinaryConfig)
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
{
|
|
88
|
+
name: 'My Custom CLI',
|
|
89
|
+
command: 'mycli',
|
|
90
|
+
description: 'My custom CLI tool',
|
|
91
|
+
deploy: true
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## CLI Commands
|
|
96
|
+
- `buddy make:command [name]` — scaffold a new command
|
|
97
|
+
|
|
98
|
+
## Compiled Binaries
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
buddy build:cli # build CLI binary
|
|
102
|
+
# Compiles for: linux-x64, linux-arm64, windows-x64, darwin-x64, darwin-arm64
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Gotchas
|
|
106
|
+
- Application commands go in `app/Commands/`, framework commands in `storage/framework/core/buddy/src/commands/`
|
|
107
|
+
- Commands are auto-discovered from `app/Commands.ts` registry
|
|
108
|
+
- CLI events support wildcards (`*`) and default handlers (`!`)
|
|
109
|
+
- The buddy CLI lazy-loads commands — not all load at startup
|
|
110
|
+
- Output formatting uses ANSI colors from `@stacksjs/utils`
|
|
111
|
+
- Custom CLIs can be compiled to platform-specific binaries
|
|
112
|
+
- The CLI framework is separate from buddy — buddy uses it internally
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-cloud
|
|
3
|
+
description: Use when deploying or managing cloud infrastructure for Stacks — AWS deployment via CloudFormation/CDK, server mode (EC2, ALB, VPC), serverless mode (Lambda, API Gateway, CloudFront), jump boxes, domain management (Route53), S3 storage, SES email, edge computing, security groups, IAM, or the cloud configuration. Covers @stacksjs/cloud, @stacksjs/deploy, storage/framework/cloud/, and cloud/.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript, AWS
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Cloud & Deployment
|
|
10
|
+
|
|
11
|
+
AWS-focused cloud deployment using CloudFormation via `@stacksjs/ts-cloud`.
|
|
12
|
+
|
|
13
|
+
## Key Paths
|
|
14
|
+
- Cloud package: `storage/framework/core/cloud/src/`
|
|
15
|
+
- Deploy package: `storage/framework/core/deploy/`
|
|
16
|
+
- CDK stacks: `storage/framework/cloud/` (deploy.ts, cdk.json, package.json)
|
|
17
|
+
- Cloud config: `cloud/` (serverless.ts, servers.ts, deploy-script.ts)
|
|
18
|
+
- Cloud driver state: `storage/cloud/` (ts-cloud's `stateDir`, set in `config/cloud.ts`)
|
|
19
|
+
- Configuration: `config/cloud.ts`
|
|
20
|
+
|
|
21
|
+
## Deployment Modes
|
|
22
|
+
|
|
23
|
+
### Server Mode (EC2)
|
|
24
|
+
- EC2 instances with configurable types (t3.micro, t4g.nano, etc.)
|
|
25
|
+
- Application Load Balancer (ALB)
|
|
26
|
+
- VPC with public/private subnets
|
|
27
|
+
- Security groups with firewall rules
|
|
28
|
+
- Auto-scaling capabilities
|
|
29
|
+
- SQLite database on instance
|
|
30
|
+
- Docker support via Dockerfile
|
|
31
|
+
|
|
32
|
+
### Serverless Mode (Lambda)
|
|
33
|
+
- Lambda functions for API
|
|
34
|
+
- API Gateway (REST/WebSocket)
|
|
35
|
+
- CloudFront CDN for static assets
|
|
36
|
+
- S3 buckets (frontend, docs, logs, assets)
|
|
37
|
+
- SQS queues for background jobs
|
|
38
|
+
- DynamoDB (optional)
|
|
39
|
+
|
|
40
|
+
## Deployment Flow
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
buddy deploy # deploy to cloud
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
1. Validates APP_KEY format (colon-separated)
|
|
47
|
+
2. Checks AWS region and credentials
|
|
48
|
+
3. Validates app URL, name, team configuration
|
|
49
|
+
4. Creates `InfrastructureGenerator` from cloud config
|
|
50
|
+
5. Generates CloudFormation template
|
|
51
|
+
6. Creates or updates stack with:
|
|
52
|
+
- Capabilities: `CAPABILITY_IAM`, `CAPABILITY_NAMED_IAM`
|
|
53
|
+
- Tags: Environment, Project, ManagedBy
|
|
54
|
+
- OnFailure: ROLLBACK
|
|
55
|
+
|
|
56
|
+
## Cloud Helper Functions
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { getSecurityGroupId, purchaseDomain, hasBeenDeployed, isFirstDeployment, isFailedState } from '@stacksjs/cloud'
|
|
60
|
+
|
|
61
|
+
// Domain management
|
|
62
|
+
await purchaseDomain('example.com', { years: 1, privacy: true, autoRenew: true })
|
|
63
|
+
|
|
64
|
+
// Infrastructure queries
|
|
65
|
+
const sgId = await getSecurityGroupId('my-sg')
|
|
66
|
+
const jumpBoxId = await getJumpBoxInstanceId('stack-name')
|
|
67
|
+
const deployed = await hasBeenDeployed()
|
|
68
|
+
const firstDeploy = await isFirstDeployment()
|
|
69
|
+
const failed = await isFailedState()
|
|
70
|
+
|
|
71
|
+
// Resource management
|
|
72
|
+
await addJumpBox('stack-name')
|
|
73
|
+
await deleteJumpBox('stack-name')
|
|
74
|
+
await deleteEc2Instance(instanceId, 'stack-name')
|
|
75
|
+
|
|
76
|
+
// Cleanup
|
|
77
|
+
await deleteStacksBuckets()
|
|
78
|
+
await deleteStacksFunctions()
|
|
79
|
+
await deleteLogGroups()
|
|
80
|
+
await deleteParameterStore()
|
|
81
|
+
await deleteVpcs()
|
|
82
|
+
await deleteCdkRemnants()
|
|
83
|
+
await deleteIamUsers()
|
|
84
|
+
await deleteSubnets()
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## DNS Functions (AWS Route53)
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { createHostedZone, deleteHostedZone, findHostedZone, getNameservers, updateNameservers } from '@stacksjs/cloud'
|
|
91
|
+
|
|
92
|
+
const zone = await createHostedZone('example.com')
|
|
93
|
+
const zoneId = await findHostedZone('example.com')
|
|
94
|
+
const ns = await getNameservers('example.com')
|
|
95
|
+
const hostedNs = await getHostedZoneNameservers('example.com')
|
|
96
|
+
await updateNameservers(hostedNs, 'example.com')
|
|
97
|
+
await deleteHostedZoneRecords('example.com')
|
|
98
|
+
await writeNameserversToConfig(nameservers)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Server Configuration (cloud/servers.ts)
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
export default [
|
|
105
|
+
{
|
|
106
|
+
name: 'app-server-1',
|
|
107
|
+
domain: 'stacksjs.com',
|
|
108
|
+
region: 'us-east-1',
|
|
109
|
+
type: 'app', // 'app' | 'web' | 'cache' | 'worker' | 'search'
|
|
110
|
+
instance: 't3.micro',
|
|
111
|
+
disk: 20, // GB
|
|
112
|
+
os: 'ubuntu-20-lts-x86_64',
|
|
113
|
+
bun: '1.1.26',
|
|
114
|
+
database: { type: 'sqlite', name: 'stacks' }
|
|
115
|
+
},
|
|
116
|
+
// ... more servers
|
|
117
|
+
]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Deploy Hooks (cloud/deploy-script.ts)
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
export default {
|
|
124
|
+
beforeDeploy({ environment, region }) {
|
|
125
|
+
// Pre-deployment: build assets, validate, notify
|
|
126
|
+
},
|
|
127
|
+
afterDeploy({ environment, region, outputs }) {
|
|
128
|
+
// Post-deployment: cache warming, smoke tests, database seeding
|
|
129
|
+
console.log('Public IP:', outputs.PublicIp)
|
|
130
|
+
console.log('DNS:', outputs.DNS)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## CLI Commands
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
buddy deploy # deploy application
|
|
139
|
+
buddy cloud --diff # show infrastructure changes
|
|
140
|
+
buddy cloud --ssh # SSH into cloud
|
|
141
|
+
buddy cloud --invalidate-cache # invalidate CDN
|
|
142
|
+
buddy cloud:add --jump-box # add jump box instance
|
|
143
|
+
buddy cloud:remove --force # destroy cloud resources
|
|
144
|
+
buddy cloud:cleanup # clean retained resources
|
|
145
|
+
buddy cloud:optimize-cost # remove optional resources
|
|
146
|
+
buddy domains:purchase <domain> # purchase domain via Route53
|
|
147
|
+
buddy domains:add <domain> # add existing domain
|
|
148
|
+
buddy domains:remove <domain> # remove domain
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## config/cloud.ts
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
{
|
|
155
|
+
project: { name: 'my-app', slug: 'my-app', region: 'us-east-1' },
|
|
156
|
+
mode: 'server', // 'server' | 'serverless'
|
|
157
|
+
environments: {
|
|
158
|
+
production: { domain: 'app.com', region: 'us-east-1' },
|
|
159
|
+
staging: { domain: 'staging.app.com' }
|
|
160
|
+
},
|
|
161
|
+
infrastructure: {
|
|
162
|
+
compute: { type: 't3.micro', spot: false },
|
|
163
|
+
loadBalancer: { enabled: true, type: 'application' },
|
|
164
|
+
ssl: { enabled: true },
|
|
165
|
+
dns: { provider: 'route53' },
|
|
166
|
+
storage: { buckets: [] },
|
|
167
|
+
cdn: { enabled: true },
|
|
168
|
+
cache: { enabled: false },
|
|
169
|
+
queue: { enabled: false }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Infrastructure Stack (storage/framework/cloud/)
|
|
175
|
+
|
|
176
|
+
- `deploy.ts` — Main deployment script (CDK app entry)
|
|
177
|
+
- `cdk.json` — CDK configuration with 54 AWS context settings
|
|
178
|
+
- `package.json` — Cloud package dependencies
|
|
179
|
+
|
|
180
|
+
Stack naming: `{slugified-app-name}-cloud`
|
|
181
|
+
|
|
182
|
+
## Gotchas
|
|
183
|
+
- AWS credentials MUST be configured (`buddy configure:aws` or env vars)
|
|
184
|
+
- Default region is `us-east-1` (from AWS_DEFAULT_REGION env)
|
|
185
|
+
- APP_KEY must be colon-separated format (validated during deployment)
|
|
186
|
+
- Server mode uses EC2 + ALB; serverless uses Lambda + API Gateway + CloudFront
|
|
187
|
+
- Jump boxes are optional — used for SSH access to private instances
|
|
188
|
+
- `cloud:remove` with `--force` skips confirmation — destructive operation
|
|
189
|
+
- CDK toolkit stack is named `stacks-toolkit`
|
|
190
|
+
- Environment mapping: `local` → `development`, others preserved
|
|
191
|
+
- Deploy hooks run before/after deployment for custom logic
|
|
192
|
+
- The cloud package has its own `package.json` with framework dependencies
|