@cloudgrid-io/mcp 0.13.0 → 0.15.0
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/package.json +1 -1
- package/src/corpus/capability-map.md +81 -7
- package/src/corpus/templates/_cloudgrid.yaml.reference +228 -0
- package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +226 -8
- package/src/corpus/templates/admin-dashboard/index.md +3 -0
- package/src/corpus/templates/ai-app/cloudgrid.yaml +225 -11
- package/src/corpus/templates/ai-app/index.md +3 -11
- package/src/corpus/templates/ai-knowledge-base/AGENTS.md +254 -0
- package/src/corpus/templates/ai-knowledge-base/README.md +28 -0
- package/src/corpus/templates/ai-knowledge-base/cloudgrid.yaml +238 -0
- package/src/corpus/templates/ai-knowledge-base/index.md +81 -0
- package/src/corpus/templates/analytics-dashboard/README.md +85 -0
- package/src/corpus/templates/analytics-dashboard/cloudgrid.yaml +232 -0
- package/src/corpus/templates/analytics-dashboard/index.md +316 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/api/events/route.js +60 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/event-form.js +100 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/layout.js +41 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/page.js +54 -0
- package/src/corpus/templates/analytics-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/analytics-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/api-dashboard/README.md +84 -0
- package/src/corpus/templates/api-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/api-dashboard/index.md +310 -0
- package/src/corpus/templates/api-dashboard/services/web/app/api/requests/route.js +62 -0
- package/src/corpus/templates/api-dashboard/services/web/app/dashboard.js +156 -0
- package/src/corpus/templates/api-dashboard/services/web/app/layout.js +42 -0
- package/src/corpus/templates/api-dashboard/services/web/app/page.js +39 -0
- package/src/corpus/templates/api-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/api-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/api-docs/cloudgrid.yaml +222 -4
- package/src/corpus/templates/api-docs/index.md +3 -5
- package/src/corpus/templates/api-service/cloudgrid.yaml +224 -9
- package/src/corpus/templates/api-service/index.md +3 -11
- package/src/corpus/templates/app-with-data/cloudgrid.yaml +226 -8
- package/src/corpus/templates/app-with-data/index.md +3 -8
- package/src/corpus/templates/appointment-booking/AGENTS.md +223 -0
- package/src/corpus/templates/appointment-booking/README.md +16 -0
- package/src/corpus/templates/appointment-booking/cloudgrid.yaml +250 -0
- package/src/corpus/templates/appointment-booking/index.md +72 -0
- package/src/corpus/templates/approval-workflow/AGENTS.md +170 -0
- package/src/corpus/templates/approval-workflow/README.md +12 -0
- package/src/corpus/templates/approval-workflow/cloudgrid.yaml +237 -0
- package/src/corpus/templates/approval-workflow/index.md +58 -0
- package/src/corpus/templates/billing-dashboard/AGENTS.md +199 -0
- package/src/corpus/templates/billing-dashboard/README.md +18 -0
- package/src/corpus/templates/billing-dashboard/cloudgrid.yaml +235 -0
- package/src/corpus/templates/billing-dashboard/index.md +87 -0
- package/src/corpus/templates/blog-cms/README.md +94 -0
- package/src/corpus/templates/blog-cms/cloudgrid.yaml +233 -0
- package/src/corpus/templates/blog-cms/index.md +358 -0
- package/src/corpus/templates/blog-cms/services/web/app/admin/admin-editor.js +133 -0
- package/src/corpus/templates/blog-cms/services/web/app/admin/page.js +33 -0
- package/src/corpus/templates/blog-cms/services/web/app/api/posts/route.js +84 -0
- package/src/corpus/templates/blog-cms/services/web/app/layout.js +47 -0
- package/src/corpus/templates/blog-cms/services/web/app/page.js +56 -0
- package/src/corpus/templates/blog-cms/services/web/app/posts/[slug]/page.js +45 -0
- package/src/corpus/templates/blog-cms/services/web/lib/db.js +32 -0
- package/src/corpus/templates/blog-cms/services/web/package.json +16 -0
- package/src/corpus/templates/booking-system/AGENTS.md +189 -0
- package/src/corpus/templates/booking-system/README.md +17 -0
- package/src/corpus/templates/booking-system/cloudgrid.yaml +248 -0
- package/src/corpus/templates/booking-system/index.md +86 -0
- package/src/corpus/templates/calendar-scheduler/AGENTS.md +226 -0
- package/src/corpus/templates/calendar-scheduler/README.md +25 -0
- package/src/corpus/templates/calendar-scheduler/cloudgrid.yaml +259 -0
- package/src/corpus/templates/calendar-scheduler/index.md +85 -0
- package/src/corpus/templates/changelog/cloudgrid.yaml +222 -4
- package/src/corpus/templates/changelog/index.md +3 -5
- package/src/corpus/templates/company-website/README.md +54 -0
- package/src/corpus/templates/company-website/cloudgrid.yaml +233 -0
- package/src/corpus/templates/company-website/index.html +309 -0
- package/src/corpus/templates/company-website/index.md +29 -0
- package/src/corpus/templates/course-platform/AGENTS.md +161 -0
- package/src/corpus/templates/course-platform/README.md +26 -0
- package/src/corpus/templates/course-platform/cloudgrid.yaml +237 -0
- package/src/corpus/templates/course-platform/index.md +70 -0
- package/src/corpus/templates/crm/cloudgrid.yaml +226 -8
- package/src/corpus/templates/crm/index.md +3 -0
- package/src/corpus/templates/dashboard/cloudgrid.yaml +228 -4
- package/src/corpus/templates/dashboard/index.md +3 -5
- package/src/corpus/templates/deck/cloudgrid.yaml +228 -4
- package/src/corpus/templates/deck/index.md +3 -5
- package/src/corpus/templates/directory/README.md +75 -0
- package/src/corpus/templates/directory/cloudgrid.yaml +233 -0
- package/src/corpus/templates/directory/index.md +334 -0
- package/src/corpus/templates/directory/services/web/app/api/entries/route.js +63 -0
- package/src/corpus/templates/directory/services/web/app/directory-list.js +146 -0
- package/src/corpus/templates/directory/services/web/app/layout.js +44 -0
- package/src/corpus/templates/directory/services/web/app/page.js +38 -0
- package/src/corpus/templates/directory/services/web/lib/db.js +32 -0
- package/src/corpus/templates/directory/services/web/package.json +16 -0
- package/src/corpus/templates/docs-site/cloudgrid.yaml +222 -4
- package/src/corpus/templates/docs-site/index.md +3 -5
- package/src/corpus/templates/erp/AGENTS.md +116 -0
- package/src/corpus/templates/erp/README.md +17 -0
- package/src/corpus/templates/erp/cloudgrid.yaml +235 -0
- package/src/corpus/templates/erp/index.md +81 -0
- package/src/corpus/templates/event-board/README.md +74 -0
- package/src/corpus/templates/event-board/cloudgrid.yaml +233 -0
- package/src/corpus/templates/event-board/index.md +299 -0
- package/src/corpus/templates/event-board/services/web/app/api/events/route.js +61 -0
- package/src/corpus/templates/event-board/services/web/app/event-form.js +118 -0
- package/src/corpus/templates/event-board/services/web/app/layout.js +39 -0
- package/src/corpus/templates/event-board/services/web/app/page.js +34 -0
- package/src/corpus/templates/event-board/services/web/lib/db.js +32 -0
- package/src/corpus/templates/event-board/services/web/package.json +16 -0
- package/src/corpus/templates/expense-tracker/README.md +76 -0
- package/src/corpus/templates/expense-tracker/cloudgrid.yaml +233 -0
- package/src/corpus/templates/expense-tracker/index.md +305 -0
- package/src/corpus/templates/expense-tracker/services/web/app/api/expenses/route.js +61 -0
- package/src/corpus/templates/expense-tracker/services/web/app/expense-form.js +145 -0
- package/src/corpus/templates/expense-tracker/services/web/app/layout.js +42 -0
- package/src/corpus/templates/expense-tracker/services/web/app/page.js +34 -0
- package/src/corpus/templates/expense-tracker/services/web/lib/db.js +32 -0
- package/src/corpus/templates/expense-tracker/services/web/package.json +16 -0
- package/src/corpus/templates/feature-request-board/README.md +87 -0
- package/src/corpus/templates/feature-request-board/cloudgrid.yaml +233 -0
- package/src/corpus/templates/feature-request-board/index.md +317 -0
- package/src/corpus/templates/feature-request-board/services/web/app/api/requests/route.js +92 -0
- package/src/corpus/templates/feature-request-board/services/web/app/board.js +91 -0
- package/src/corpus/templates/feature-request-board/services/web/app/layout.js +43 -0
- package/src/corpus/templates/feature-request-board/services/web/app/page.js +35 -0
- package/src/corpus/templates/feature-request-board/services/web/lib/db.js +32 -0
- package/src/corpus/templates/feature-request-board/services/web/package.json +16 -0
- package/src/corpus/templates/financial-dashboard/README.md +80 -0
- package/src/corpus/templates/financial-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/financial-dashboard/index.md +326 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/api/entries/route.js +63 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/entry-board.js +130 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/layout.js +46 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/page.js +31 -0
- package/src/corpus/templates/financial-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/financial-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/forum/AGENTS.md +196 -0
- package/src/corpus/templates/forum/README.md +12 -0
- package/src/corpus/templates/forum/cloudgrid.yaml +237 -0
- package/src/corpus/templates/forum/index.md +66 -0
- package/src/corpus/templates/hr-portal/AGENTS.md +174 -0
- package/src/corpus/templates/hr-portal/README.md +14 -0
- package/src/corpus/templates/hr-portal/cloudgrid.yaml +237 -0
- package/src/corpus/templates/hr-portal/index.md +56 -0
- package/src/corpus/templates/internal-tools-portal/AGENTS.md +201 -0
- package/src/corpus/templates/internal-tools-portal/README.md +17 -0
- package/src/corpus/templates/internal-tools-portal/cloudgrid.yaml +237 -0
- package/src/corpus/templates/internal-tools-portal/index.md +62 -0
- package/src/corpus/templates/inventory/README.md +71 -0
- package/src/corpus/templates/inventory/cloudgrid.yaml +233 -0
- package/src/corpus/templates/inventory/index.md +68 -0
- package/src/corpus/templates/inventory/services/web/app/api/items/route.js +88 -0
- package/src/corpus/templates/inventory/services/web/app/inventory-manager.js +101 -0
- package/src/corpus/templates/inventory/services/web/app/layout.js +36 -0
- package/src/corpus/templates/inventory/services/web/app/page.js +37 -0
- package/src/corpus/templates/inventory/services/web/lib/db.js +32 -0
- package/src/corpus/templates/inventory/services/web/package.json +16 -0
- package/src/corpus/templates/invoice/README.md +71 -0
- package/src/corpus/templates/invoice/cloudgrid.yaml +233 -0
- package/src/corpus/templates/invoice/index.md +68 -0
- package/src/corpus/templates/invoice/services/web/app/api/invoices/route.js +82 -0
- package/src/corpus/templates/invoice/services/web/app/invoice-manager.js +101 -0
- package/src/corpus/templates/invoice/services/web/app/layout.js +35 -0
- package/src/corpus/templates/invoice/services/web/app/page.js +34 -0
- package/src/corpus/templates/invoice/services/web/lib/db.js +32 -0
- package/src/corpus/templates/invoice/services/web/package.json +16 -0
- package/src/corpus/templates/job-board/README.md +71 -0
- package/src/corpus/templates/job-board/cloudgrid.yaml +233 -0
- package/src/corpus/templates/job-board/index.md +68 -0
- package/src/corpus/templates/job-board/services/web/app/api/jobs/route.js +66 -0
- package/src/corpus/templates/job-board/services/web/app/job-board.js +73 -0
- package/src/corpus/templates/job-board/services/web/app/layout.js +35 -0
- package/src/corpus/templates/job-board/services/web/app/page.js +32 -0
- package/src/corpus/templates/job-board/services/web/lib/db.js +32 -0
- package/src/corpus/templates/job-board/services/web/package.json +16 -0
- package/src/corpus/templates/kanban/cloudgrid.yaml +226 -8
- package/src/corpus/templates/kanban/index.md +3 -0
- package/src/corpus/templates/landing-page/cloudgrid.yaml +228 -4
- package/src/corpus/templates/landing-page/index.md +3 -5
- package/src/corpus/templates/lms/AGENTS.md +193 -0
- package/src/corpus/templates/lms/README.md +27 -0
- package/src/corpus/templates/lms/cloudgrid.yaml +237 -0
- package/src/corpus/templates/lms/index.md +79 -0
- package/src/corpus/templates/marketplace/AGENTS.md +208 -0
- package/src/corpus/templates/marketplace/README.md +22 -0
- package/src/corpus/templates/marketplace/cloudgrid.yaml +233 -0
- package/src/corpus/templates/marketplace/index.md +76 -0
- package/src/corpus/templates/membership-site/AGENTS.md +160 -0
- package/src/corpus/templates/membership-site/README.md +18 -0
- package/src/corpus/templates/membership-site/cloudgrid.yaml +236 -0
- package/src/corpus/templates/membership-site/index.md +66 -0
- package/src/corpus/templates/monitoring-dashboard/README.md +84 -0
- package/src/corpus/templates/monitoring-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/monitoring-dashboard/index.md +328 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/api/checks/route.js +76 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/check-form.js +124 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/layout.js +44 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/page.js +49 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/online-store/AGENTS.md +153 -0
- package/src/corpus/templates/online-store/README.md +16 -0
- package/src/corpus/templates/online-store/cloudgrid.yaml +234 -0
- package/src/corpus/templates/online-store/index.md +81 -0
- package/src/corpus/templates/portfolio/cloudgrid.yaml +222 -4
- package/src/corpus/templates/portfolio/index.md +3 -5
- package/src/corpus/templates/product-catalog/README.md +74 -0
- package/src/corpus/templates/product-catalog/cloudgrid.yaml +232 -0
- package/src/corpus/templates/product-catalog/index.md +330 -0
- package/src/corpus/templates/product-catalog/services/web/app/api/products/route.js +69 -0
- package/src/corpus/templates/product-catalog/services/web/app/catalog.js +153 -0
- package/src/corpus/templates/product-catalog/services/web/app/layout.js +49 -0
- package/src/corpus/templates/product-catalog/services/web/app/page.js +36 -0
- package/src/corpus/templates/product-catalog/services/web/lib/db.js +32 -0
- package/src/corpus/templates/product-catalog/services/web/package.json +16 -0
- package/src/corpus/templates/product-launch/README.md +46 -0
- package/src/corpus/templates/product-launch/cloudgrid.yaml +234 -0
- package/src/corpus/templates/product-launch/index.html +320 -0
- package/src/corpus/templates/product-launch/index.md +34 -0
- package/src/corpus/templates/project-management/README.md +83 -0
- package/src/corpus/templates/project-management/cloudgrid.yaml +233 -0
- package/src/corpus/templates/project-management/index.md +346 -0
- package/src/corpus/templates/project-management/services/web/app/api/projects/route.js +48 -0
- package/src/corpus/templates/project-management/services/web/app/api/tasks/route.js +85 -0
- package/src/corpus/templates/project-management/services/web/app/board.js +182 -0
- package/src/corpus/templates/project-management/services/web/app/layout.js +45 -0
- package/src/corpus/templates/project-management/services/web/app/page.js +49 -0
- package/src/corpus/templates/project-management/services/web/lib/db.js +32 -0
- package/src/corpus/templates/project-management/services/web/package.json +16 -0
- package/src/corpus/templates/property-listings/README.md +76 -0
- package/src/corpus/templates/property-listings/cloudgrid.yaml +233 -0
- package/src/corpus/templates/property-listings/index.md +335 -0
- package/src/corpus/templates/property-listings/services/web/app/api/properties/route.js +73 -0
- package/src/corpus/templates/property-listings/services/web/app/layout.js +45 -0
- package/src/corpus/templates/property-listings/services/web/app/listings.js +152 -0
- package/src/corpus/templates/property-listings/services/web/app/page.js +53 -0
- package/src/corpus/templates/property-listings/services/web/lib/db.js +32 -0
- package/src/corpus/templates/property-listings/services/web/package.json +16 -0
- package/src/corpus/templates/quiz-platform/README.md +84 -0
- package/src/corpus/templates/quiz-platform/cloudgrid.yaml +233 -0
- package/src/corpus/templates/quiz-platform/index.md +313 -0
- package/src/corpus/templates/quiz-platform/services/web/app/api/questions/route.js +69 -0
- package/src/corpus/templates/quiz-platform/services/web/app/layout.js +47 -0
- package/src/corpus/templates/quiz-platform/services/web/app/page.js +37 -0
- package/src/corpus/templates/quiz-platform/services/web/app/quiz.js +188 -0
- package/src/corpus/templates/quiz-platform/services/web/lib/db.js +32 -0
- package/src/corpus/templates/quiz-platform/services/web/package.json +16 -0
- package/src/corpus/templates/report/cloudgrid.yaml +228 -4
- package/src/corpus/templates/report/index.md +3 -5
- package/src/corpus/templates/restaurant-reservations/AGENTS.md +258 -0
- package/src/corpus/templates/restaurant-reservations/README.md +17 -0
- package/src/corpus/templates/restaurant-reservations/cloudgrid.yaml +258 -0
- package/src/corpus/templates/restaurant-reservations/index.md +62 -0
- package/src/corpus/templates/revenue-dashboard/README.md +75 -0
- package/src/corpus/templates/revenue-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/revenue-dashboard/index.md +307 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/api/sales/route.js +60 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/layout.js +40 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/page.js +87 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/sale-form.js +63 -0
- package/src/corpus/templates/revenue-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/revenue-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/saas-marketing/cloudgrid.yaml +222 -4
- package/src/corpus/templates/saas-marketing/index.md +3 -5
- package/src/corpus/templates/semantic-search/AGENTS.md +192 -0
- package/src/corpus/templates/semantic-search/README.md +74 -0
- package/src/corpus/templates/semantic-search/cloudgrid.yaml +217 -0
- package/src/corpus/templates/semantic-search/index.md +97 -0
- package/src/corpus/templates/semantic-search/services/backend/requirements.txt +7 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/__init__.py +0 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/answer.py +90 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/auth.py +65 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/config.py +110 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/db.py +89 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/embeddings.py +44 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/indexing.py +222 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/main.py +259 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/search.py +222 -0
- package/src/corpus/templates/semantic-search/services/backend/src/app/source.py +259 -0
- package/src/corpus/templates/semantic-search/services/backend/src/main.py +12 -0
- package/src/corpus/templates/semantic-search/services/web/index.html +12 -0
- package/src/corpus/templates/semantic-search/services/web/package-lock.json +1680 -0
- package/src/corpus/templates/semantic-search/services/web/package.json +19 -0
- package/src/corpus/templates/semantic-search/services/web/src/App.jsx +55 -0
- package/src/corpus/templates/semantic-search/services/web/src/api.js +125 -0
- package/src/corpus/templates/semantic-search/services/web/src/components/Dashboard.jsx +61 -0
- package/src/corpus/templates/semantic-search/services/web/src/components/ManagerLogin.jsx +39 -0
- package/src/corpus/templates/semantic-search/services/web/src/components/SearchView.jsx +166 -0
- package/src/corpus/templates/semantic-search/services/web/src/components/Settings.jsx +148 -0
- package/src/corpus/templates/semantic-search/services/web/src/main.jsx +10 -0
- package/src/corpus/templates/semantic-search/services/web/src/styles.css +78 -0
- package/src/corpus/templates/semantic-search/services/web/vite.config.js +10 -0
- package/src/corpus/templates/status-page/cloudgrid.yaml +222 -4
- package/src/corpus/templates/status-page/index.md +3 -5
- package/src/corpus/templates/subscription-management/AGENTS.md +191 -0
- package/src/corpus/templates/subscription-management/README.md +21 -0
- package/src/corpus/templates/subscription-management/cloudgrid.yaml +236 -0
- package/src/corpus/templates/subscription-management/index.md +73 -0
- package/src/corpus/templates/task-manager/cloudgrid.yaml +226 -8
- package/src/corpus/templates/task-manager/index.md +3 -0
- package/src/corpus/templates/ticket-system/README.md +71 -0
- package/src/corpus/templates/ticket-system/cloudgrid.yaml +233 -0
- package/src/corpus/templates/ticket-system/index.md +68 -0
- package/src/corpus/templates/ticket-system/services/web/app/api/tickets/route.js +81 -0
- package/src/corpus/templates/ticket-system/services/web/app/layout.js +36 -0
- package/src/corpus/templates/ticket-system/services/web/app/page.js +35 -0
- package/src/corpus/templates/ticket-system/services/web/app/ticket-queue.js +112 -0
- package/src/corpus/templates/ticket-system/services/web/lib/db.js +32 -0
- package/src/corpus/templates/ticket-system/services/web/package.json +16 -0
- package/src/corpus/templates/time-tracking/README.md +81 -0
- package/src/corpus/templates/time-tracking/cloudgrid.yaml +233 -0
- package/src/corpus/templates/time-tracking/index.md +298 -0
- package/src/corpus/templates/time-tracking/services/web/app/api/entries/route.js +66 -0
- package/src/corpus/templates/time-tracking/services/web/app/entry-form.js +106 -0
- package/src/corpus/templates/time-tracking/services/web/app/layout.js +39 -0
- package/src/corpus/templates/time-tracking/services/web/app/page.js +30 -0
- package/src/corpus/templates/time-tracking/services/web/lib/db.js +32 -0
- package/src/corpus/templates/time-tracking/services/web/package.json +16 -0
- package/src/corpus/templates/travel-booking/AGENTS.md +207 -0
- package/src/corpus/templates/travel-booking/README.md +17 -0
- package/src/corpus/templates/travel-booking/cloudgrid.yaml +249 -0
- package/src/corpus/templates/travel-booking/index.md +88 -0
- package/src/corpus/templates/waitlist/cloudgrid.yaml +222 -4
- package/src/corpus/templates/waitlist/index.md +3 -5
- package/src/corpus/templates/web-app/cloudgrid.yaml +228 -4
- package/src/corpus/templates/web-app/index.md +3 -5
- package/src/corpus/workflows/ai-knowledge-base.md +137 -0
- package/src/corpus/workflows/analytics-dashboard.md +104 -0
- package/src/corpus/workflows/api-dashboard.md +102 -0
- package/src/corpus/workflows/appointment-booking.md +143 -0
- package/src/corpus/workflows/approval-workflow.md +124 -0
- package/src/corpus/workflows/billing-dashboard.md +120 -0
- package/src/corpus/workflows/blog-cms.md +104 -0
- package/src/corpus/workflows/booking-system.md +116 -0
- package/src/corpus/workflows/calendar-scheduler.md +134 -0
- package/src/corpus/workflows/company-website.md +46 -0
- package/src/corpus/workflows/course-platform.md +126 -0
- package/src/corpus/workflows/directory.md +101 -0
- package/src/corpus/workflows/erp.md +125 -0
- package/src/corpus/workflows/event-board.md +102 -0
- package/src/corpus/workflows/expense-tracker.md +102 -0
- package/src/corpus/workflows/feature-request-board.md +105 -0
- package/src/corpus/workflows/financial-dashboard.md +103 -0
- package/src/corpus/workflows/forum.md +128 -0
- package/src/corpus/workflows/hr-portal.md +115 -0
- package/src/corpus/workflows/internal-tools-portal.md +125 -0
- package/src/corpus/workflows/inventory.md +101 -0
- package/src/corpus/workflows/invoice.md +101 -0
- package/src/corpus/workflows/job-board.md +101 -0
- package/src/corpus/workflows/lms.md +113 -0
- package/src/corpus/workflows/marketplace.md +123 -0
- package/src/corpus/workflows/membership-site.md +128 -0
- package/src/corpus/workflows/monitoring-dashboard.md +104 -0
- package/src/corpus/workflows/online-store.md +114 -0
- package/src/corpus/workflows/product-catalog.md +105 -0
- package/src/corpus/workflows/product-launch.md +43 -0
- package/src/corpus/workflows/project-management.md +106 -0
- package/src/corpus/workflows/property-listings.md +101 -0
- package/src/corpus/workflows/quiz-platform.md +105 -0
- package/src/corpus/workflows/restaurant-reservations.md +123 -0
- package/src/corpus/workflows/revenue-dashboard.md +102 -0
- package/src/corpus/workflows/semantic-search.md +133 -0
- package/src/corpus/workflows/subscription-management.md +141 -0
- package/src/corpus/workflows/ticket-system.md +101 -0
- package/src/corpus/workflows/time-tracking.md +104 -0
- package/src/corpus/workflows/travel-booking.md +115 -0
- package/src/tools.js +73 -12
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: subscription-management
|
|
3
|
+
when: "subscription management, manage subscriptions, self-serve plans/billing"
|
|
4
|
+
needs: database
|
|
5
|
+
deploy: runtime
|
|
6
|
+
editions: local
|
|
7
|
+
kind: blueprint
|
|
8
|
+
capabilities_note: "persistent — needs a database (Mongo) plus Stripe subscription secrets. Runtime app, async build, local edition only. Declare needs { database: true } (deployer injects DATABASE_MONGODB_URL / legacy MONGODB_URL) and a vault block mapping STRIPE_KEY / STRIPE_WEBHOOK_SECRET to env vars. This is a BLUEPRINT — read AGENTS.md for the structure, then build."
|
|
9
|
+
summary: "Build a self-serve subscription-management app on the grid — a Next.js app where a signed-in customer views their current plan, changes/upgrades/downgrades or cancels it, and manages billing via the Stripe Billing Portal, with a Stripe webhook syncing local state and grid-shared Mongo (customers + subscriptions collections). This is a BLUEPRINT: fetch the template, read AGENTS.md for the file tree + CloudGrid wiring (needs database true, vault for Stripe secrets), build the app under services/web/, deploy async, poll to a live URL."
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Workflow: subscription-management
|
|
13
|
+
|
|
14
|
+
The user wants self-serve subscription management: a signed-in customer sees
|
|
15
|
+
their current plan, upgrades/downgrades or cancels it, and manages billing (card,
|
|
16
|
+
invoices, receipts) — with the app's state staying in sync with Stripe. That is a
|
|
17
|
+
**persistent runtime app** — a Next.js app backed by the grid's shared Mongo,
|
|
18
|
+
with Stripe subscription updates, the Stripe Billing Portal, and a webhook that
|
|
19
|
+
keeps local subscription state authoritative.
|
|
20
|
+
|
|
21
|
+
This is the **manage-what-you-already-have** surface. If the user actually wants
|
|
22
|
+
the sign-up + paywall + gated-content acquisition flow, that is the
|
|
23
|
+
`membership-site` workflow instead — the two share the same Stripe + Mongo wiring.
|
|
24
|
+
|
|
25
|
+
This is a **blueprint**, not a fill-in template. There is no finished app to
|
|
26
|
+
copy — there is a `cloudgrid.yaml` and a structure guide (`AGENTS.md`). Read the
|
|
27
|
+
guide, then build the app following it. Be honest that a runtime deploy is async
|
|
28
|
+
(not instant like a static drop) and that it needs the local edition.
|
|
29
|
+
|
|
30
|
+
## 1. Edition check FIRST (hard gate)
|
|
31
|
+
|
|
32
|
+
A subscription-management app is a built + deployed container. It requires the
|
|
33
|
+
**local edition** (Claude Desktop / Claude Code) or the CLI.
|
|
34
|
+
|
|
35
|
+
- **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
|
|
36
|
+
hosted is inline-only and can only publish static pages. Tell the user
|
|
37
|
+
plainly, offer a **static pricing/plans page** instead, and STOP the runtime
|
|
38
|
+
path here.
|
|
39
|
+
- **Local edition:** continue.
|
|
40
|
+
|
|
41
|
+
## 2. Auth + grid
|
|
42
|
+
|
|
43
|
+
1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
|
|
44
|
+
2. A grid is required. Respect the grid picker: if the user has more than one
|
|
45
|
+
grid, ask which to use; do not assume a target.
|
|
46
|
+
|
|
47
|
+
## 3. Read the blueprint
|
|
48
|
+
|
|
49
|
+
Fetch the template and read its structure guide — this is the core of the
|
|
50
|
+
workflow:
|
|
51
|
+
|
|
52
|
+
- `gridctl_fetch("template", "subscription-management")` — the `cloudgrid.yaml` +
|
|
53
|
+
**`AGENTS.md`**. AGENTS.md has the file tree, the Mongo collections
|
|
54
|
+
(`customers`, `subscriptions`), the CloudGrid injection table, and the Stripe
|
|
55
|
+
change-plan / cancel / billing-portal / webhook wiring. **Read it fully before
|
|
56
|
+
building.**
|
|
57
|
+
- `gridctl_fetch("template", "app-with-data")` — the proven Next.js + Mongo
|
|
58
|
+
shape this blueprint extends (lazy db client in `lib/db.js`, App-Router
|
|
59
|
+
GET/POST route). Imitate its wiring.
|
|
60
|
+
|
|
61
|
+
## 4. Scaffold
|
|
62
|
+
|
|
63
|
+
`gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
|
|
64
|
+
and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a linked
|
|
65
|
+
directory, so run `init` FIRST. Then write the app under **`services/web/`** and
|
|
66
|
+
set `cloudgrid.yaml` to the active shape below.
|
|
67
|
+
|
|
68
|
+
## 5. Build the app following AGENTS.md
|
|
69
|
+
|
|
70
|
+
Build the file tree from AGENTS.md under `services/web/`: the lazy Mongo client,
|
|
71
|
+
the lazy Stripe client, the plan catalog (`lib/plans.js`), the auth middleware,
|
|
72
|
+
the subscription (change-plan) + cancel + billing-portal + webhook API routes,
|
|
73
|
+
and the `/account` dashboard. Adapt the plans and document fields to the user.
|
|
74
|
+
Key non-negotiables:
|
|
75
|
+
|
|
76
|
+
- **App code under `services/web/`** — `path:` is the URL mount, NOT the
|
|
77
|
+
filesystem path. Root files fail with `Service directory not found`.
|
|
78
|
+
- **Read the DB LAZILY** from `process.env.DATABASE_MONGODB_URL` (legacy
|
|
79
|
+
`process.env.MONGODB_URL` fallback) inside the getter — never at module top
|
|
80
|
+
level, or `next build` fails.
|
|
81
|
+
- **Read secrets LAZILY** too — `process.env.STRIPE_KEY`,
|
|
82
|
+
`STRIPE_WEBHOOK_SECRET` — inside getters, never top-level.
|
|
83
|
+
- **The webhook is the source of truth.** The change-plan and cancel APIs call
|
|
84
|
+
Stripe; do NOT write plan/status to Mongo there — let `/api/webhook` reconcile
|
|
85
|
+
the `subscriptions` collection so Stripe and Mongo never diverge. Read
|
|
86
|
+
plan/status server-side from Mongo; validate requested plans against
|
|
87
|
+
`lib/plans.js` (never accept an arbitrary price id from the client).
|
|
88
|
+
- **Tie every action to the signed-in user** — resolve `userRef` server-side and
|
|
89
|
+
only ever act on that user's `stripeCustomerId`.
|
|
90
|
+
|
|
91
|
+
`cloudgrid.yaml` active shape:
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
name: my-subscription-management
|
|
95
|
+
services:
|
|
96
|
+
web:
|
|
97
|
+
type: nextjs
|
|
98
|
+
path: /
|
|
99
|
+
needs:
|
|
100
|
+
database: true
|
|
101
|
+
vault:
|
|
102
|
+
STRIPE_KEY: stripe-live-key
|
|
103
|
+
STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Declare the datastore with `needs: { database: true }`** — the canonical
|
|
107
|
+
shape. `requires:` is the deprecated v1 alias; don't author new yaml with it, and
|
|
108
|
+
never set `needs:` and `requires:` together (the validator rejects it).
|
|
109
|
+
|
|
110
|
+
## 6. Config / secrets
|
|
111
|
+
|
|
112
|
+
- Stripe secrets → `gridctl_secrets` (set the vault items `stripe-live-key` and
|
|
113
|
+
`stripe-webhook-secret` that the `vault:` block maps from). The deployer
|
|
114
|
+
injects each as its env var at runtime and under `grid dev`. Add
|
|
115
|
+
`auth-provider-key` too if you use an auth SDK.
|
|
116
|
+
- Non-secret config (Stripe publishable key `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`,
|
|
117
|
+
price ids, auth publishable key) → `gridctl_env` / `services.web.env`.
|
|
118
|
+
- Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` / legacy
|
|
119
|
+
`MONGODB_URL`) — the grid injects them.
|
|
120
|
+
|
|
121
|
+
## 7. (Optional) Run locally
|
|
122
|
+
|
|
123
|
+
Mention that the user can `grid dev` to run locally against the injected Mongo
|
|
124
|
+
and vault secrets before deploying. Don't require it.
|
|
125
|
+
|
|
126
|
+
## 8. Deploy (async)
|
|
127
|
+
|
|
128
|
+
Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
|
|
129
|
+
response is `status: "building"`, NOT a live URL yet.
|
|
130
|
+
- Poll `gridctl_status` (or the returned poll_url) until the entity is live.
|
|
131
|
+
- Surface a liveness signal while it builds — never a bare silent wait.
|
|
132
|
+
- Once live, register the `/api/webhook` URL as the Stripe webhook endpoint,
|
|
133
|
+
copy the signing secret into the `stripe-webhook-secret` vault item, configure
|
|
134
|
+
the Billing Portal in the Stripe dashboard, and re-plug. Return the deployed
|
|
135
|
+
app URL (NOT the build/log link).
|
|
136
|
+
|
|
137
|
+
## 9. Return the live URL + iterate
|
|
138
|
+
|
|
139
|
+
Give the user the live app URL — that is the deliverable. To iterate, re-plug the
|
|
140
|
+
SAME entity so it updates the same URL. Keep it honest: async build, local-edition
|
|
141
|
+
only, DB injected by the grid, secrets injected from the vault.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ticket-system
|
|
3
|
+
when: ticket system, support tickets, helpdesk, issue tracker, support queue — a persistent app that stores tickets (subject, requester, status, priority, body) with status changes. Needs a database → runtime → local edition.
|
|
4
|
+
needs: database
|
|
5
|
+
deploy: runtime
|
|
6
|
+
editions: local
|
|
7
|
+
capabilities_note: persistent — needs a database (Mongo). Runtime app, async build, local edition only. Declare the canonical `needs: { database: true }`; the deployer injects DATABASE_MONGODB_URL (+legacy MONGODB_URL).
|
|
8
|
+
summary: Build a persistent Next.js + Mongo support ticket queue on the grid — a `tickets` collection (subject, requester, status open/pending/closed, priority, body) with add / status-change / delete. Edition-gate first, scaffold, put the app under services/web/, wire process.env.DATABASE_MONGODB_URL (legacy MONGODB_URL fallback) lazily, declare needs:{database:true} (not requires:), deploy async, poll to a live URL.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Workflow: ticket-system
|
|
12
|
+
|
|
13
|
+
The user wants a tickets app that **remembers** its
|
|
14
|
+
records — they survive refresh and are shared across sessions. That is a
|
|
15
|
+
**runtime app** backed by the grid's shared Mongo, not a static page. It is the
|
|
16
|
+
same proven shape as `app-with-data`, with a `tickets` domain
|
|
17
|
+
(subject, requester, status of open/pending/closed, priority, body) and a table view with add, per-row status changes, and delete.
|
|
18
|
+
|
|
19
|
+
Follow this recipe. Be honest that a runtime deploy is async (not instant like a
|
|
20
|
+
static drop) and that it needs the local edition.
|
|
21
|
+
|
|
22
|
+
## 1. Edition check FIRST (hard gate)
|
|
23
|
+
|
|
24
|
+
A persistent app is a built + deployed container. It requires the **local
|
|
25
|
+
edition** (Claude Desktop / Claude Code) or the CLI.
|
|
26
|
+
|
|
27
|
+
- **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
|
|
28
|
+
hosted is inline-only and can only publish static pages. Tell the user
|
|
29
|
+
plainly, offer a **static version** instead, and STOP the runtime path here.
|
|
30
|
+
- **Local edition:** continue.
|
|
31
|
+
|
|
32
|
+
## 2. Auth + grid
|
|
33
|
+
|
|
34
|
+
1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
|
|
35
|
+
2. A grid is required. Respect the grid picker: if the user has more than one
|
|
36
|
+
grid, ask which to use; do not assume a target.
|
|
37
|
+
|
|
38
|
+
## 3. Scaffold
|
|
39
|
+
|
|
40
|
+
`gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
|
|
41
|
+
and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a linked
|
|
42
|
+
directory, so run `init` FIRST. Then (a) write the app under **`services/web/`**,
|
|
43
|
+
and (b) fill `cloudgrid.yaml` to the shape below (`services.web` + `needs:
|
|
44
|
+
{ database: true }`).
|
|
45
|
+
|
|
46
|
+
## 4. Add the datastore + wire Mongo
|
|
47
|
+
|
|
48
|
+
1. Set `cloudgrid.yaml`. **App code MUST live under `services/<name>/`** —
|
|
49
|
+
`path:` is the URL mount, NOT the filesystem path.
|
|
50
|
+
```yaml
|
|
51
|
+
name: my-tickets
|
|
52
|
+
services:
|
|
53
|
+
web:
|
|
54
|
+
type: nextjs
|
|
55
|
+
path: /
|
|
56
|
+
needs:
|
|
57
|
+
database: true
|
|
58
|
+
```
|
|
59
|
+
**Declare the datastore with `needs: { database: true }`** — the canonical
|
|
60
|
+
shape. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus
|
|
61
|
+
the legacy `MONGODB_URL` alias). `requires:` is the deprecated v1 alias; don't
|
|
62
|
+
author new yaml with it, and never set `needs:` and `requires:` together (the
|
|
63
|
+
validator rejects it). The template ships this file in the **full-annotated
|
|
64
|
+
reference form** — every field present as a comment, only `name`,
|
|
65
|
+
`services.web`, and `needs.database` uncommented — so it deploys to exactly
|
|
66
|
+
those active fields.
|
|
67
|
+
2. Fetch the template for the Mongo wiring + CRUD shape:
|
|
68
|
+
`gridctl_fetch("template", "ticket-system")`. It is a minimal, real Next.js +
|
|
69
|
+
`mongodb`-driver app under `services/web/`: a lazy client in
|
|
70
|
+
`services/web/lib/db.js`, an App-Router GET/POST/PATCH (status)/DELETE route on a `tickets` collection, a
|
|
71
|
+
server-component page, and a client component.
|
|
72
|
+
3. Adapt it (rename the collection, change fields, adjust the UI). **Read the DB
|
|
73
|
+
from `process.env.DATABASE_MONGODB_URL`** (legacy `process.env.MONGODB_URL`
|
|
74
|
+
fallback) — the grid injects it at dev-time and runtime.
|
|
75
|
+
- **Put the DB connection behind a lazy getter — never read the connection
|
|
76
|
+
string at module top level, or `next build` fails.**
|
|
77
|
+
|
|
78
|
+
## 5. (Optional) Run locally
|
|
79
|
+
|
|
80
|
+
Mention that the user can `grid dev` to run locally against the injected Mongo
|
|
81
|
+
before deploying. Don't require it.
|
|
82
|
+
|
|
83
|
+
## 6. Config
|
|
84
|
+
|
|
85
|
+
- API keys / secrets → `gridctl_secrets`. Non-secret config → `gridctl_env`.
|
|
86
|
+
- Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
|
|
87
|
+
legacy `MONGODB_URL`) — the grid injects them.
|
|
88
|
+
|
|
89
|
+
## 7. Deploy (async)
|
|
90
|
+
|
|
91
|
+
Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
|
|
92
|
+
response is `status: "building"`, NOT a live URL yet.
|
|
93
|
+
- Poll `gridctl_status` (or the returned poll_url) until the entity is live.
|
|
94
|
+
- Surface a liveness signal while it builds — never a bare silent wait.
|
|
95
|
+
- Only once it is live, return the deployed app URL (NOT the build/log link).
|
|
96
|
+
|
|
97
|
+
## 8. Return the live URL + iterate
|
|
98
|
+
|
|
99
|
+
Give the user the live app URL — that is the deliverable. To iterate, re-plug the
|
|
100
|
+
SAME entity so it updates the same URL. Keep it honest: async build, local-edition
|
|
101
|
+
only, credentials injected by the grid.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: time-tracking
|
|
3
|
+
when: time tracking, timesheet, hours logger, billable hours — a persistent app that logs time entries (task, project, minutes, date) and totals hours per project. Needs a database → runtime → local edition.
|
|
4
|
+
needs: database
|
|
5
|
+
deploy: runtime
|
|
6
|
+
editions: local
|
|
7
|
+
capabilities_note: persistent — needs a database (Mongo). Runtime app, async build, local edition only. Declare the canonical `needs: { database: true }`; the deployer injects DATABASE_MONGODB_URL (+legacy MONGODB_URL).
|
|
8
|
+
summary: Build a persistent Next.js + Mongo time tracker on the grid — an `entries` collection (task, project, minutes:number, date) with add / list / delete and totals per project. Edition-gate first, scaffold, put the app under services/web/, wire process.env.DATABASE_MONGODB_URL (legacy MONGODB_URL fallback) lazily, declare needs:{database:true} (not requires:), deploy async, poll to a live URL.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Workflow: time-tracking
|
|
12
|
+
|
|
13
|
+
The user wants a time tracker / timesheet / billable-hours logger that
|
|
14
|
+
**remembers** its entries — hours that survive refresh and are shared across
|
|
15
|
+
sessions. That is a **runtime app** backed by the grid's shared Mongo, not a
|
|
16
|
+
static page. It is the same proven shape as `app-with-data`, with an `entries`
|
|
17
|
+
domain (task, project, minutes, date), an add form, a list of entries, and a
|
|
18
|
+
per-project totals table.
|
|
19
|
+
|
|
20
|
+
Follow this recipe. Be honest that a runtime deploy is async (not instant like a
|
|
21
|
+
static drop) and that it needs the local edition.
|
|
22
|
+
|
|
23
|
+
## 1. Edition check FIRST (hard gate)
|
|
24
|
+
|
|
25
|
+
A persistent app is a built + deployed container. It requires the **local
|
|
26
|
+
edition** (Claude Desktop / Claude Code) or the CLI.
|
|
27
|
+
|
|
28
|
+
- **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
|
|
29
|
+
hosted is inline-only and can only publish static pages. Tell the user
|
|
30
|
+
plainly, offer a **static version** instead, and STOP the runtime path here.
|
|
31
|
+
- **Local edition:** continue.
|
|
32
|
+
|
|
33
|
+
## 2. Auth + grid
|
|
34
|
+
|
|
35
|
+
1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
|
|
36
|
+
2. A grid is required. Respect the grid picker: if the user has more than one
|
|
37
|
+
grid, ask which to use; do not assume a target.
|
|
38
|
+
|
|
39
|
+
## 3. Scaffold
|
|
40
|
+
|
|
41
|
+
`gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
|
|
42
|
+
and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a linked
|
|
43
|
+
directory, so run `init` FIRST. Then (a) write the app under **`services/web/`**,
|
|
44
|
+
and (b) fill `cloudgrid.yaml` to the shape below (`services.web` + `needs:
|
|
45
|
+
{ database: true }`).
|
|
46
|
+
|
|
47
|
+
## 4. Add the datastore + wire Mongo
|
|
48
|
+
|
|
49
|
+
1. Set `cloudgrid.yaml`. **App code MUST live under `services/<name>/`** —
|
|
50
|
+
`path:` is the URL mount, NOT the filesystem path.
|
|
51
|
+
```yaml
|
|
52
|
+
name: my-tracker
|
|
53
|
+
services:
|
|
54
|
+
web:
|
|
55
|
+
type: nextjs
|
|
56
|
+
path: /
|
|
57
|
+
needs:
|
|
58
|
+
database: true
|
|
59
|
+
```
|
|
60
|
+
**Declare the datastore with `needs: { database: true }`** — the canonical
|
|
61
|
+
shape. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus
|
|
62
|
+
the legacy `MONGODB_URL` alias). `requires:` is the deprecated v1 alias; don't
|
|
63
|
+
author new yaml with it, and never set `needs:` and `requires:` together (the
|
|
64
|
+
validator rejects it).
|
|
65
|
+
2. Fetch the template for the Mongo wiring + CRUD shape:
|
|
66
|
+
`gridctl_fetch("template", "time-tracking")`. It is a minimal, real Next.js +
|
|
67
|
+
`mongodb`-driver time tracker under `services/web/`: a lazy client in
|
|
68
|
+
`services/web/lib/db.js`, an App-Router GET/POST/DELETE route on an `entries`
|
|
69
|
+
collection, a server-component page, and a client form that also renders
|
|
70
|
+
per-project totals.
|
|
71
|
+
3. Adapt it (rename the collection, change fields, adjust the UI). The domain is
|
|
72
|
+
`entries {task, project, minutes:number, date}`: add an entry, list entries,
|
|
73
|
+
total minutes per project. **Read the DB from
|
|
74
|
+
`process.env.DATABASE_MONGODB_URL`** (legacy `process.env.MONGODB_URL`
|
|
75
|
+
fallback) — the grid injects it at dev-time and runtime.
|
|
76
|
+
- **Put the DB connection behind a lazy getter — never read the connection
|
|
77
|
+
string at module top level, or `next build` fails.**
|
|
78
|
+
- The route handler is `export const dynamic = "force-dynamic"` so time
|
|
79
|
+
entries are always read/written live.
|
|
80
|
+
|
|
81
|
+
## 5. (Optional) Run locally
|
|
82
|
+
|
|
83
|
+
Mention that the user can `grid dev` to run locally against the injected Mongo
|
|
84
|
+
before deploying. Don't require it.
|
|
85
|
+
|
|
86
|
+
## 6. Config
|
|
87
|
+
|
|
88
|
+
- API keys / secrets → `gridctl_secrets`. Non-secret config → `gridctl_env`.
|
|
89
|
+
- Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
|
|
90
|
+
legacy `MONGODB_URL`) — the grid injects them.
|
|
91
|
+
|
|
92
|
+
## 7. Deploy (async)
|
|
93
|
+
|
|
94
|
+
Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
|
|
95
|
+
response is `status: "building"`, NOT a live URL yet.
|
|
96
|
+
- Poll `gridctl_status` (or the returned poll_url) until the entity is live.
|
|
97
|
+
- Surface a liveness signal while it builds — never a bare silent wait.
|
|
98
|
+
- Only once it is live, return the deployed app URL (NOT the build/log link).
|
|
99
|
+
|
|
100
|
+
## 8. Return the live URL + iterate
|
|
101
|
+
|
|
102
|
+
Give the user the live app URL — that is the deliverable. To iterate, re-plug the
|
|
103
|
+
SAME entity so it updates the same URL. Keep it honest: async build, local-edition
|
|
104
|
+
only, credentials injected by the grid.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: travel-booking
|
|
3
|
+
when: travel booking portal, trip booking, flights/hotels booking, book a flight, book a hotel, travel reservations — a persistent app where users search and book flights/hotels and manage trips that survive refresh and are shared across sessions. Needs a database → runtime → local edition.
|
|
4
|
+
needs: database
|
|
5
|
+
deploy: runtime
|
|
6
|
+
editions: local
|
|
7
|
+
kind: blueprint
|
|
8
|
+
capabilities_note: "persistent — needs a database (Mongo). Runtime app, async build, local edition only. BLUEPRINT — ships structure + cloudgrid.yaml, not app code; read AGENTS.md and build. Declare the canonical `needs: { database: true }`; the deployer injects DATABASE_MONGODB_URL (+legacy MONGODB_URL). Payment/auth secrets via the `vault:` block → env vars. Trip-reminder cron is NOT yet deployable (platform issue #1543)."
|
|
9
|
+
summary: "Build a persistent Next.js + Mongo travel booking portal on the grid — `flights`, `hotels`, `bookings`, `trips` collections with search + availability logic, Stripe checkout, an auth provider, and a (pending) trip-reminder cron. This is a BLUEPRINT: fetch it, read AGENTS.md for the file tree + data model + CloudGrid wiring, then build the app under services/web/. Edition-gate first, scaffold, declare needs:{database:true} (not requires:), map secrets via vault:, deploy async, poll to a live URL."
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Workflow: travel-booking
|
|
13
|
+
|
|
14
|
+
The user wants a travel booking portal — search and book flights and hotels, pay,
|
|
15
|
+
and manage trips — that **remembers** its bookings across refresh and sessions.
|
|
16
|
+
That is a **runtime app** backed by the grid's shared Mongo, not a static page.
|
|
17
|
+
The proven runtime shape is the same as `app-with-data` (Next.js + lazy Mongo
|
|
18
|
+
client under `services/web/`), with a travel domain (`flights`, `hotels`,
|
|
19
|
+
`bookings`, `trips` with overbooking protection), Stripe checkout for paid
|
|
20
|
+
bookings, an auth provider for accounts, and a scheduled trip-reminder job.
|
|
21
|
+
|
|
22
|
+
**This is a BLUEPRINT.** It does NOT ship prewritten app code — it ships the
|
|
23
|
+
annotated `cloudgrid.yaml` and an `AGENTS.md` structure guide (file tree, Mongo
|
|
24
|
+
data model, and CloudGrid wiring). Fetch it, **read `AGENTS.md`**, then build the
|
|
25
|
+
app under `services/web/` following it.
|
|
26
|
+
|
|
27
|
+
Follow this recipe. Be honest that a runtime deploy is async (not instant like a
|
|
28
|
+
static drop), that it needs the local edition, and that the trip-reminder **cron
|
|
29
|
+
service is not yet deployable** (platform issue #1543).
|
|
30
|
+
|
|
31
|
+
## 1. Edition check FIRST (hard gate)
|
|
32
|
+
|
|
33
|
+
A persistent app is a built + deployed container. It requires the **local
|
|
34
|
+
edition** (Claude Desktop / Claude Code) or the CLI.
|
|
35
|
+
|
|
36
|
+
- **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
|
|
37
|
+
hosted is inline-only and can only publish static pages. Tell the user plainly,
|
|
38
|
+
offer a **static preview** instead, and STOP the runtime path here.
|
|
39
|
+
- **Local edition:** continue.
|
|
40
|
+
|
|
41
|
+
## 2. Auth + grid
|
|
42
|
+
|
|
43
|
+
1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
|
|
44
|
+
2. A grid is required. Respect the grid picker: if the user has more than one
|
|
45
|
+
grid, ask which to use; do not assume a target.
|
|
46
|
+
|
|
47
|
+
## 3. Read the blueprint, then scaffold
|
|
48
|
+
|
|
49
|
+
1. Fetch the blueprint: `gridctl_fetch("template", "travel-booking")`. **Read its
|
|
50
|
+
`AGENTS.md`** — it is the structure guide (file tree under `services/web/`, the
|
|
51
|
+
`flights` / `hotels` / `bookings` / `trips` collections + the overbooking
|
|
52
|
+
guard, how CloudGrid injects the DB and vault secrets, how to wire Stripe +
|
|
53
|
+
auth, and the trip-reminder-cron design).
|
|
54
|
+
2. `gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
|
|
55
|
+
and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a
|
|
56
|
+
linked directory, so run `init` FIRST.
|
|
57
|
+
|
|
58
|
+
## 4. Build the app + set cloudgrid.yaml
|
|
59
|
+
|
|
60
|
+
1. Build the files under **`services/web/`** per the AGENTS.md file tree. **App
|
|
61
|
+
code MUST live under `services/<name>/`** — `path:` is the URL mount, NOT the
|
|
62
|
+
filesystem path.
|
|
63
|
+
2. Set `cloudgrid.yaml` to the blueprint shape:
|
|
64
|
+
```yaml
|
|
65
|
+
name: my-travel-booking
|
|
66
|
+
vault:
|
|
67
|
+
STRIPE_KEY: stripe-live-key
|
|
68
|
+
STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
|
|
69
|
+
AUTH_PROVIDER_KEY: auth-provider-key
|
|
70
|
+
services:
|
|
71
|
+
web:
|
|
72
|
+
type: nextjs
|
|
73
|
+
path: /
|
|
74
|
+
needs:
|
|
75
|
+
database: true
|
|
76
|
+
```
|
|
77
|
+
**Declare the datastore with `needs: { database: true }`** — the canonical
|
|
78
|
+
shape. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus
|
|
79
|
+
the legacy `MONGODB_URL` alias). `requires:` is the deprecated v1 alias; don't
|
|
80
|
+
author new yaml with it, and never set `needs:` and `requires:` together (the
|
|
81
|
+
validator rejects it).
|
|
82
|
+
3. **Read every injected var lazily** (inside a getter), never at module top level
|
|
83
|
+
— `process.env.DATABASE_MONGODB_URL || process.env.MONGODB_URL`, and the vault
|
|
84
|
+
secrets (`STRIPE_KEY`, etc.) the same way. A top-level read fails `next build`.
|
|
85
|
+
4. **Keep the trip-reminder cron COMMENTED.** cron deploy is PENDING platform
|
|
86
|
+
issue #1543 — `plug` rejects a `type: cron` service. Ship `web` alone; use the
|
|
87
|
+
stopgap in AGENTS.md §7 for reminders until #1543 lands.
|
|
88
|
+
|
|
89
|
+
## 5. Config (secrets)
|
|
90
|
+
|
|
91
|
+
- Payment/auth secrets → add the vault items with `gridctl_secrets` (e.g.
|
|
92
|
+
`stripe-live-key`, `stripe-webhook-secret`, `auth-provider-key`) BEFORE plug so
|
|
93
|
+
the `vault:` mappings resolve. Non-secret config → `gridctl_env`.
|
|
94
|
+
- Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` / legacy
|
|
95
|
+
`MONGODB_URL`) — the grid injects them.
|
|
96
|
+
|
|
97
|
+
## 6. (Optional) Run locally
|
|
98
|
+
|
|
99
|
+
Mention that the user can `grid dev` to run locally against the injected Mongo +
|
|
100
|
+
vault env vars before deploying. Good for testing search/availability logic. Don't
|
|
101
|
+
require it.
|
|
102
|
+
|
|
103
|
+
## 7. Deploy (async)
|
|
104
|
+
|
|
105
|
+
Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
|
|
106
|
+
response is `status: "building"`, NOT a live URL yet.
|
|
107
|
+
- Poll `gridctl_status` (or the returned poll_url) until the entity is live.
|
|
108
|
+
- Surface a liveness signal while it builds — never a bare silent wait.
|
|
109
|
+
- Only once it is live, return the deployed app URL (NOT the build/log link).
|
|
110
|
+
|
|
111
|
+
## 8. Return the live URL + iterate
|
|
112
|
+
|
|
113
|
+
Give the user the live app URL — that is the deliverable. To iterate, re-plug the
|
|
114
|
+
SAME entity so it updates the same URL. Keep it honest: async build, local-edition
|
|
115
|
+
only, credentials injected by the grid, and the trip-reminder cron pending #1543.
|
package/src/tools.js
CHANGED
|
@@ -867,6 +867,30 @@ function composePlugUrl(data) {
|
|
|
867
867
|
return `https://${grid}.cloudgrid.io/${slug}`;
|
|
868
868
|
}
|
|
869
869
|
|
|
870
|
+
// Parse the top-level `name:` from a cloudgrid.yaml manifest (issue #48). The
|
|
871
|
+
// manifest is the source of truth for the entity name on a create, but the
|
|
872
|
+
// inline-create wire never forwarded it, so an `artifact_files` create landed as
|
|
873
|
+
// an auto `drop-XXXX` slug. Deliberately a tiny top-level-scalar scan (no YAML
|
|
874
|
+
// dep, matching the rest of this module): the FIRST unindented `name:` key wins,
|
|
875
|
+
// nested `services:`/`needs:` `name:` keys (indented) are ignored, and quotes +
|
|
876
|
+
// inline `# comments` are stripped. Returns null when absent/unparseable.
|
|
877
|
+
export function parseManifestName(yaml) {
|
|
878
|
+
if (typeof yaml !== "string" || yaml.length === 0) return null;
|
|
879
|
+
for (const rawLine of yaml.split(/\r?\n/)) {
|
|
880
|
+
// Top-level keys only — a leading space/tab means it is nested under a map.
|
|
881
|
+
if (/^\s/.test(rawLine)) continue;
|
|
882
|
+
const m = /^name:\s*(.+?)\s*$/.exec(rawLine);
|
|
883
|
+
if (!m) continue;
|
|
884
|
+
let val = m[1];
|
|
885
|
+
// Strip an inline comment on an unquoted scalar.
|
|
886
|
+
if (!/^["']/.test(val)) val = val.replace(/\s+#.*$/, "").trim();
|
|
887
|
+
// Strip surrounding quotes.
|
|
888
|
+
val = val.replace(/^(["'])(.*)\1$/, "$2").trim();
|
|
889
|
+
return val.length > 0 ? val : null;
|
|
890
|
+
}
|
|
891
|
+
return null;
|
|
892
|
+
}
|
|
893
|
+
|
|
870
894
|
// The public URL of a `/plug` response: the server-composed `url` verbatim
|
|
871
895
|
// (canonical, flat-arch-aware — the unified plug spec), falling back to client-side composition
|
|
872
896
|
// ONLY when the server left it empty (its composition is best-effort).
|
|
@@ -1958,6 +1982,24 @@ export async function runPlug(ctx, input, deps = {}) {
|
|
|
1958
1982
|
}
|
|
1959
1983
|
if (useAnonWire && ctx.state.anonCookie) headers["Cookie"] = ctx.state.anonCookie;
|
|
1960
1984
|
|
|
1985
|
+
// ── CREATE manifest injection (issue #48) ───────────────────────────────────
|
|
1986
|
+
// On a folder-walk create, a `cloudgrid.yaml` on disk is walked into the tree
|
|
1987
|
+
// and — because directory reads surface it before the nested `services/…`
|
|
1988
|
+
// files — rides the multipart body as the FIRST `artifact` part, with the
|
|
1989
|
+
// walk's uniform `application/octet-stream` content-type. The runtime build
|
|
1990
|
+
// orchestrator relies on the manifest leading the bundle (it drives the
|
|
1991
|
+
// service graph + the entity name). The inline `artifact_files` create used to
|
|
1992
|
+
// APPEND the `cloudgrid_yaml` manifest LAST and as `text/plain`, so a
|
|
1993
|
+
// multi-service runtime rolled out with no service graph (0 replicas /
|
|
1994
|
+
// rollout_failed) and an auto `drop-XXXX` name. Fold the manifest into the
|
|
1995
|
+
// artifact list as the first entry (deduping any `cloudgrid.yaml` the caller
|
|
1996
|
+
// already inlined) so both create paths emit a byte-equivalent bundle.
|
|
1997
|
+
if (!isEdit && cloudgrid_yaml) {
|
|
1998
|
+
const manifest = { path: "cloudgrid.yaml", buffer: Buffer.from(cloudgrid_yaml, "utf8") };
|
|
1999
|
+
const rest = artifacts.filter((a) => a.path !== "cloudgrid.yaml");
|
|
2000
|
+
artifacts = [manifest, ...rest];
|
|
2001
|
+
}
|
|
2002
|
+
|
|
1961
2003
|
// ── Wire assembly ───────────────────────────────────────────────────────────
|
|
1962
2004
|
const form = new FormData();
|
|
1963
2005
|
for (const a of artifacts) {
|
|
@@ -1976,15 +2018,17 @@ export async function runPlug(ctx, input, deps = {}) {
|
|
|
1976
2018
|
"cloudgrid.yaml",
|
|
1977
2019
|
);
|
|
1978
2020
|
}
|
|
1979
|
-
}
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2021
|
+
}
|
|
2022
|
+
// Honor the manifest name (issue #48): send `name:` parsed from `cloudgrid_yaml`
|
|
2023
|
+
// as an explicit name/slug hint so the created entity uses it instead of an
|
|
2024
|
+
// auto `drop-XXXX` slug. Harmless if the server owns slug generation; on a
|
|
2025
|
+
// re-plug the entity's name is authoritative, so only send on create.
|
|
2026
|
+
if (!isEdit) {
|
|
2027
|
+
const manifestName = parseManifestName(cloudgrid_yaml);
|
|
2028
|
+
if (manifestName) {
|
|
2029
|
+
form.append("name", manifestName);
|
|
2030
|
+
form.append("slug", manifestName);
|
|
2031
|
+
}
|
|
1988
2032
|
}
|
|
1989
2033
|
if (hints?.kind) {
|
|
1990
2034
|
// `kind_hint` is what the create orchestrator reads; `hints_kind` is the
|
|
@@ -2086,10 +2130,27 @@ export async function runPlug(ctx, input, deps = {}) {
|
|
|
2086
2130
|
...(freshOwnerToken ? { owner_token: freshOwnerToken } : {}),
|
|
2087
2131
|
};
|
|
2088
2132
|
|
|
2133
|
+
// Accurate status (issue #48): a runtime create/edit is an ASYNC build — the
|
|
2134
|
+
// server replies `status: "building"` (+ a poll_url) while the rollout is still
|
|
2135
|
+
// in flight. Do NOT claim "Live"/"Updated in place" for a build that has not
|
|
2136
|
+
// finished; that reported success for apps that then rolled-out-failed. Only
|
|
2137
|
+
// the terminal states get the live wording; anything still building points at
|
|
2138
|
+
// the poll_url and gridctl_status.
|
|
2139
|
+
const isBuilding = data.status === "building" || Boolean(data.poll_url);
|
|
2089
2140
|
const lines = [];
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2141
|
+
if (isBuilding) {
|
|
2142
|
+
lines.push(
|
|
2143
|
+
isEdit
|
|
2144
|
+
? `Building (async): ${url} — the update is deploying, not live yet.`
|
|
2145
|
+
: `Building (async): ${url} — the deploy is in progress, not live yet.`,
|
|
2146
|
+
);
|
|
2147
|
+
lines.push(
|
|
2148
|
+
data.poll_url
|
|
2149
|
+
? `Poll ${data.poll_url} or run gridctl_status until it is ready (trace ${data.trace_id ?? "n/a"}). Do not report it as live until then.`
|
|
2150
|
+
: "Run gridctl_status until it is ready. Do not report it as live until then.",
|
|
2151
|
+
);
|
|
2152
|
+
} else {
|
|
2153
|
+
lines.push(isEdit ? `Updated in place: ${url}` : `Live: ${url}`);
|
|
2093
2154
|
}
|
|
2094
2155
|
if (data.entity_id) {
|
|
2095
2156
|
lines.push(
|