@littlebearapps/create-platform 1.0.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.
Files changed (31) hide show
  1. package/dist/index.d.ts +11 -0
  2. package/dist/index.js +59 -0
  3. package/dist/prompts.d.ts +15 -0
  4. package/dist/prompts.js +58 -0
  5. package/dist/scaffold.d.ts +5 -0
  6. package/dist/scaffold.js +65 -0
  7. package/dist/templates.d.ts +16 -0
  8. package/dist/templates.js +53 -0
  9. package/package.json +46 -0
  10. package/templates/full/migrations/006_pattern_discovery.sql +199 -0
  11. package/templates/full/migrations/007_notifications_search.sql +127 -0
  12. package/templates/full/wrangler.alert-router.jsonc.hbs +34 -0
  13. package/templates/full/wrangler.notifications.jsonc.hbs +23 -0
  14. package/templates/full/wrangler.pattern-discovery.jsonc.hbs +33 -0
  15. package/templates/full/wrangler.search.jsonc.hbs +16 -0
  16. package/templates/full/wrangler.settings.jsonc.hbs +23 -0
  17. package/templates/shared/README.md.hbs +69 -0
  18. package/templates/shared/config/budgets.yaml.hbs +72 -0
  19. package/templates/shared/config/services.yaml.hbs +45 -0
  20. package/templates/shared/migrations/001_core_tables.sql +117 -0
  21. package/templates/shared/migrations/002_usage_warehouse.sql +830 -0
  22. package/templates/shared/migrations/003_feature_tracking.sql +250 -0
  23. package/templates/shared/migrations/004_settings_alerts.sql +452 -0
  24. package/templates/shared/migrations/seed.sql.hbs +4 -0
  25. package/templates/shared/package.json.hbs +21 -0
  26. package/templates/shared/scripts/sync-config.ts +242 -0
  27. package/templates/shared/tsconfig.json +12 -0
  28. package/templates/shared/wrangler.usage.jsonc.hbs +58 -0
  29. package/templates/standard/migrations/005_error_collection.sql +162 -0
  30. package/templates/standard/wrangler.error-collector.jsonc.hbs +44 -0
  31. package/templates/standard/wrangler.sentinel.jsonc.hbs +45 -0
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "./node_modules/wrangler/config-schema.json",
3
+ "name": "{{projectSlug}}-alert-router",
4
+ "main": "workers/platform-alert-router.ts",
5
+ "compatibility_date": "2026-01-01",
6
+ "compatibility_flags": ["nodejs_compat_v2"],
7
+ "observability": { "enabled": true },
8
+
9
+ "d1_databases": [
10
+ {
11
+ "binding": "PLATFORM_DB",
12
+ "database_name": "{{projectSlug}}-metrics",
13
+ "database_id": "YOUR_D1_DATABASE_ID"
14
+ }
15
+ ],
16
+
17
+ "kv_namespaces": [
18
+ {
19
+ "binding": "PLATFORM_CACHE",
20
+ "id": "YOUR_KV_NAMESPACE_ID"
21
+ },
22
+ {
23
+ "binding": "PLATFORM_ALERTS",
24
+ "id": "YOUR_KV_ALERTS_NAMESPACE_ID"
25
+ }
26
+ ],
27
+
28
+ "vars": {
29
+ "CLOUDFLARE_ACCOUNT_ID": "YOUR_CLOUDFLARE_ACCOUNT_ID"
30
+ }
31
+
32
+ // Secrets needed:
33
+ // SLACK_WEBHOOK_URL
34
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "./node_modules/wrangler/config-schema.json",
3
+ "name": "{{projectSlug}}-notifications",
4
+ "main": "workers/platform-notifications.ts",
5
+ "compatibility_date": "2026-01-01",
6
+ "compatibility_flags": ["nodejs_compat_v2"],
7
+ "observability": { "enabled": true },
8
+
9
+ "d1_databases": [
10
+ {
11
+ "binding": "PLATFORM_DB",
12
+ "database_name": "{{projectSlug}}-metrics",
13
+ "database_id": "YOUR_D1_DATABASE_ID"
14
+ }
15
+ ],
16
+
17
+ "kv_namespaces": [
18
+ {
19
+ "binding": "PLATFORM_CACHE",
20
+ "id": "YOUR_KV_NAMESPACE_ID"
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "./node_modules/wrangler/config-schema.json",
3
+ "name": "{{projectSlug}}-pattern-discovery",
4
+ "main": "workers/pattern-discovery.ts",
5
+ "compatibility_date": "2026-01-01",
6
+ "compatibility_flags": ["nodejs_compat_v2"],
7
+ "observability": { "enabled": true },
8
+
9
+ "triggers": {
10
+ "crons": ["0 2 * * *", "0 3 * * *"]
11
+ },
12
+
13
+ "d1_databases": [
14
+ {
15
+ "binding": "PLATFORM_DB",
16
+ "database_name": "{{projectSlug}}-metrics",
17
+ "database_id": "YOUR_D1_DATABASE_ID"
18
+ }
19
+ ],
20
+
21
+ "kv_namespaces": [
22
+ {
23
+ "binding": "PLATFORM_CACHE",
24
+ "id": "YOUR_KV_NAMESPACE_ID"
25
+ }
26
+ ],
27
+
28
+ "ai": { "binding": "AI" },
29
+
30
+ "vars": {
31
+ "GATUS_HEARTBEAT_URL": "{{gatusUrl}}"
32
+ }
33
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "./node_modules/wrangler/config-schema.json",
3
+ "name": "{{projectSlug}}-search",
4
+ "main": "workers/platform-search.ts",
5
+ "compatibility_date": "2026-01-01",
6
+ "compatibility_flags": ["nodejs_compat_v2"],
7
+ "observability": { "enabled": true },
8
+
9
+ "d1_databases": [
10
+ {
11
+ "binding": "PLATFORM_DB",
12
+ "database_name": "{{projectSlug}}-metrics",
13
+ "database_id": "YOUR_D1_DATABASE_ID"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "./node_modules/wrangler/config-schema.json",
3
+ "name": "{{projectSlug}}-settings",
4
+ "main": "workers/platform-settings.ts",
5
+ "compatibility_date": "2026-01-01",
6
+ "compatibility_flags": ["nodejs_compat_v2"],
7
+ "observability": { "enabled": true },
8
+
9
+ "d1_databases": [
10
+ {
11
+ "binding": "PLATFORM_DB",
12
+ "database_name": "{{projectSlug}}-metrics",
13
+ "database_id": "YOUR_D1_DATABASE_ID"
14
+ }
15
+ ],
16
+
17
+ "kv_namespaces": [
18
+ {
19
+ "binding": "PLATFORM_CACHE",
20
+ "id": "YOUR_KV_NAMESPACE_ID"
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,69 @@
1
+ # {{projectName}} Platform
2
+
3
+ Cost protection and monitoring infrastructure powered by [Platform SDK](https://github.com/littlebearapps/platform-sdk).
4
+
5
+ ## Setup
6
+
7
+ **Tier**: {{tier}}
8
+
9
+ ### 1. Create Cloudflare Resources
10
+
11
+ ```bash
12
+ npx wrangler d1 create {{projectSlug}}-metrics
13
+ npx wrangler kv namespace create PLATFORM_CACHE
14
+ npx wrangler queues create {{projectSlug}}-telemetry
15
+ npx wrangler queues create {{projectSlug}}-telemetry-dlq
16
+ ```
17
+
18
+ ### 2. Update Wrangler Configs
19
+
20
+ Replace `YOUR_*_ID` placeholders in `wrangler.*.jsonc` with the IDs from step 1.
21
+
22
+ ### 3. Run Migrations
23
+
24
+ ```bash
25
+ npx wrangler d1 migrations apply {{projectSlug}}-metrics --remote
26
+ ```
27
+
28
+ ### 4. Sync Config
29
+
30
+ ```bash
31
+ npm run sync:config
32
+ ```
33
+
34
+ ### 5. Deploy
35
+
36
+ ```bash
37
+ npx wrangler deploy -c wrangler.{{projectSlug}}-usage.jsonc
38
+ ```
39
+
40
+ ### 6. Install SDK in Consumer Projects
41
+
42
+ ```bash
43
+ npm install @littlebearapps/platform-sdk
44
+ ```
45
+
46
+ ## Architecture
47
+
48
+ ```
49
+ Consumer Projects
50
+ |
51
+ | SDK telemetry (via queue)
52
+ v
53
+ {{projectSlug}}-usage (cron + queue consumer)
54
+ |
55
+ v
56
+ D1 Warehouse + KV Cache + Analytics Engine
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ - `platform/config/services.yaml` — Project and feature registry
62
+ - `platform/config/budgets.yaml` — Limits, thresholds, circuit breakers
63
+
64
+ After editing config, run `npm run sync:config` to sync to D1/KV.
65
+
66
+ ## Resources
67
+
68
+ - [Platform SDK Documentation](https://github.com/littlebearapps/platform-sdk)
69
+ - [Cloudflare Workers Pricing](https://developers.cloudflare.com/workers/platform/pricing/)
@@ -0,0 +1,72 @@
1
+ # Budget Configuration — Limits, Thresholds, Circuit Breakers
2
+ # Sync to D1/KV: npm run sync:config
3
+
4
+ # Cloudflare Workers Paid Plan limits (as of Jan 2026)
5
+ account_limits:
6
+ workers:
7
+ requests: 10_000_000 # 10M requests/month included
8
+ cpu_ms: 30_000 # 30s CPU time per invocation
9
+ d1:
10
+ reads: 25_000_000_000 # 25B reads/month
11
+ writes: 50_000_000 # 50M writes/month
12
+ storage_gb: 5 # 5GB included
13
+ kv:
14
+ reads: 10_000_000 # 10M reads/month
15
+ writes: 1_000_000 # 1M writes/month
16
+ storage_gb: 1 # 1GB included
17
+ queues:
18
+ messages: 1_000_000 # 1M messages/month
19
+ r2:
20
+ class_a: 1_000_000 # 1M Class A ops/month
21
+ class_b: 10_000_000 # 10M Class B ops/month
22
+ storage_gb: 10 # 10GB included
23
+
24
+ # Default limits (applied when no feature-specific override exists)
25
+ defaults:
26
+ global_limits:
27
+ d1_write_limit: 100_000 # Daily D1 write limit per feature
28
+ daily:
29
+ d1_reads: 1_000_000
30
+ d1_writes: 100_000
31
+ kv_reads: 100_000
32
+ kv_writes: 10_000
33
+ worker_requests: 500_000
34
+ queue_messages: 50_000
35
+ circuit_breaker:
36
+ auto_reset_seconds: 3600 # 1 hour
37
+ cooldown_seconds: 300 # 5 minutes
38
+ error_budget:
39
+ error_rate_threshold: 5 # 5% error rate triggers warning
40
+ window_minutes: 60
41
+ thresholds:
42
+ warning: 70 # 70% of budget
43
+ critical: 90 # 90% of budget
44
+
45
+ # Cost tiers for feature categorisation
46
+ cost_tiers:
47
+ low:
48
+ d1_writes: 10_000
49
+ kv_writes: 1_000
50
+ medium:
51
+ d1_writes: 50_000
52
+ kv_writes: 5_000
53
+ high:
54
+ d1_writes: 200_000
55
+ kv_writes: 20_000
56
+ critical:
57
+ d1_writes: 500_000
58
+ kv_writes: 50_000
59
+
60
+ # Per-project budgets
61
+ project_budgets:
62
+ {{projectSlug}}:
63
+ daily:
64
+ d1_writes: 500_000
65
+ kv_writes: 50_000
66
+ worker_requests: 1_000_000
67
+
68
+ # Feature-specific overrides (feature_id: limits)
69
+ feature_overrides:
70
+ "{{projectSlug}}:cron:hourly":
71
+ d1_writes: 200_000
72
+ d1_reads: 500_000
@@ -0,0 +1,45 @@
1
+ # Service Registry — Source of Truth
2
+ # Sync to D1/KV: npm run sync:config
3
+
4
+ metadata:
5
+ version: "1.0.0"
6
+ autoDiscovery: true
7
+ kvNamespace: PLATFORM_CACHE
8
+ d1Database: {{projectSlug}}-metrics
9
+
10
+ projects:
11
+ {{projectSlug}}:
12
+ display_name: "{{projectName}}"
13
+ status: active
14
+ tier: paid
15
+ repository: "{{githubOrg}}/{{projectSlug}}"
16
+ infrastructure:
17
+ workers:
18
+ - id: {{projectSlug}}-usage
19
+ name: "Usage Collector"
20
+ script_name: {{projectSlug}}-usage
21
+ status: active
22
+ schedule: "0 * * * *"
23
+ storage:
24
+ d1:
25
+ - database_name: {{projectSlug}}-metrics
26
+ binding: PLATFORM_DB
27
+ features:
28
+ api:
29
+ main-api:
30
+ display_name: "Main API"
31
+ feature_id: "{{projectSlug}}:api:main"
32
+ circuit_breaker: true
33
+ cost_tier: medium
34
+ cron:
35
+ hourly-collection:
36
+ display_name: "Hourly Collection"
37
+ feature_id: "{{projectSlug}}:cron:hourly"
38
+ circuit_breaker: true
39
+ cost_tier: low
40
+ queue:
41
+ telemetry-processing:
42
+ display_name: "Telemetry Processing"
43
+ feature_id: "{{projectSlug}}:queue:telemetry"
44
+ circuit_breaker: true
45
+ cost_tier: low
@@ -0,0 +1,117 @@
1
+ -- =============================================================================
2
+ -- 001_core_tables.sql — Core platform tables
3
+ -- =============================================================================
4
+ -- Consolidated from original migrations: 001, 002, 007, 009, 016
5
+ --
6
+ -- Tables:
7
+ -- alerts — Platform alerts with severity and resolution tracking
8
+ -- project_registry — Logical project definitions for resource grouping
9
+ -- resource_project_mapping — Maps CF resources to owning projects
10
+ -- resource_types — Valid resource types and their CF API endpoints
11
+ -- =============================================================================
12
+
13
+
14
+ -- =============================================================================
15
+ -- ALERTS
16
+ -- =============================================================================
17
+ -- Platform-wide alert tracking with severity tiers and resolution status.
18
+
19
+ CREATE TABLE IF NOT EXISTS alerts (
20
+ id TEXT PRIMARY KEY,
21
+ category TEXT NOT NULL,
22
+ severity TEXT NOT NULL,
23
+ title TEXT NOT NULL,
24
+ description TEXT NOT NULL,
25
+ source TEXT NOT NULL,
26
+ timestamp INTEGER NOT NULL,
27
+ resolved INTEGER DEFAULT 0,
28
+ resolved_at INTEGER,
29
+ created_at INTEGER DEFAULT (unixepoch())
30
+ );
31
+
32
+ CREATE INDEX IF NOT EXISTS idx_alerts_category ON alerts(category, severity, timestamp);
33
+ CREATE INDEX IF NOT EXISTS idx_alerts_resolved ON alerts(resolved, timestamp);
34
+
35
+
36
+ -- =============================================================================
37
+ -- PROJECT REGISTRY
38
+ -- =============================================================================
39
+ -- Defines logical projects within a Cloudflare account.
40
+ -- Cloudflare has no native resource grouping — this table provides it.
41
+ -- Columns from migrations 007, 009, 016 merged into one CREATE TABLE.
42
+
43
+ CREATE TABLE IF NOT EXISTS project_registry (
44
+ project_id TEXT PRIMARY KEY, -- 'my-project', 'my-other-project'
45
+ display_name TEXT NOT NULL, -- Human-readable name
46
+ description TEXT, -- Brief description
47
+ color TEXT, -- Hex colour for dashboard (#FF5733)
48
+ icon TEXT, -- Icon identifier for UI
49
+ owner TEXT, -- Team or person responsible
50
+ repo_path TEXT, -- Git repo path (e.g., 'org/repo')
51
+ repo_url TEXT, -- Full GitHub URL
52
+ github_repo_id TEXT, -- For GitHub API integration
53
+ status TEXT DEFAULT 'active', -- 'active', 'archived', 'development'
54
+ primary_resource TEXT, -- Main CF resource type for utilisation tracking
55
+ custom_limit INTEGER, -- Optional custom limit override
56
+ created_at INTEGER DEFAULT (unixepoch()),
57
+ updated_at INTEGER DEFAULT (unixepoch())
58
+ );
59
+
60
+ CREATE INDEX IF NOT EXISTS idx_project_status ON project_registry(status);
61
+ CREATE INDEX IF NOT EXISTS idx_project_github_repo ON project_registry(github_repo_id);
62
+
63
+
64
+ -- =============================================================================
65
+ -- RESOURCE PROJECT MAPPING
66
+ -- =============================================================================
67
+ -- Maps individual Cloudflare resources to their owning project.
68
+ -- Used by the usage worker to aggregate metrics by project.
69
+
70
+ CREATE TABLE IF NOT EXISTS resource_project_mapping (
71
+ resource_type TEXT NOT NULL, -- 'worker', 'd1', 'kv', 'r2', etc.
72
+ resource_id TEXT NOT NULL, -- CF resource ID (UUID or name)
73
+ resource_name TEXT NOT NULL, -- Human-readable name
74
+ project_id TEXT NOT NULL, -- FK to project_registry
75
+ environment TEXT DEFAULT 'production', -- 'production', 'staging', 'preview', 'development'
76
+ notes TEXT,
77
+ created_at INTEGER DEFAULT (unixepoch()),
78
+ updated_at INTEGER DEFAULT (unixepoch()),
79
+
80
+ PRIMARY KEY (resource_type, resource_id),
81
+ FOREIGN KEY (project_id) REFERENCES project_registry(project_id)
82
+ );
83
+
84
+ CREATE INDEX IF NOT EXISTS idx_resource_project ON resource_project_mapping(project_id);
85
+ CREATE INDEX IF NOT EXISTS idx_resource_type ON resource_project_mapping(resource_type);
86
+ CREATE INDEX IF NOT EXISTS idx_resource_name ON resource_project_mapping(resource_name);
87
+ CREATE INDEX IF NOT EXISTS idx_resource_env ON resource_project_mapping(environment);
88
+
89
+
90
+ -- =============================================================================
91
+ -- RESOURCE TYPES (reference table)
92
+ -- =============================================================================
93
+ -- Defines valid resource types and their Cloudflare API endpoints.
94
+
95
+ CREATE TABLE IF NOT EXISTS resource_types (
96
+ type_id TEXT PRIMARY KEY, -- 'worker', 'd1', 'kv', etc.
97
+ display_name TEXT NOT NULL, -- 'Workers', 'D1 Database', etc.
98
+ api_endpoint TEXT, -- GraphQL node or REST endpoint
99
+ billing_dimension TEXT, -- Primary billing metric
100
+ icon TEXT, -- Icon for UI
101
+ sort_order INTEGER DEFAULT 0 -- Display order in UI
102
+ );
103
+
104
+ -- Seed resource types
105
+ INSERT OR IGNORE INTO resource_types (type_id, display_name, api_endpoint, billing_dimension, icon, sort_order) VALUES
106
+ ('worker', 'Workers', 'workersInvocationsAdaptive', 'requests + CPU ms', 'zap', 1),
107
+ ('d1', 'D1 Database', 'd1AnalyticsAdaptiveGroups', 'rows read/written', 'database', 2),
108
+ ('kv', 'KV Namespace', 'kvStorageAdaptiveGroups', 'reads/writes/storage', 'key', 3),
109
+ ('r2', 'R2 Bucket', 'r2StorageAdaptiveGroups', 'Class A/B ops + storage', 'hard-drive', 4),
110
+ ('vectorize', 'Vectorize Index', 'REST /vectorize', 'dimensions stored/queried', 'search', 5),
111
+ ('queue', 'Queue', 'REST /queues', 'messages produced/consumed', 'list', 6),
112
+ ('workflow', 'Workflow', 'workersWorkflowsAdaptiveGroups', 'executions', 'git-branch', 7),
113
+ ('ai_gateway', 'AI Gateway', 'REST /ai-gateway', 'requests + tokens', 'cpu', 8),
114
+ ('workers_ai', 'Workers AI', 'workersAiAdaptiveGroups', 'neurons', 'brain', 9),
115
+ ('durable_object', 'Durable Object', 'durableObjectsPeriodicGroups', 'requests + GB-seconds', 'box', 10),
116
+ ('pages', 'Pages', 'pagesProjectsAdaptiveGroups', 'requests + bandwidth', 'globe', 11),
117
+ ('analytics_engine', 'Analytics Engine', 'aeDatasets', 'data points', 'bar-chart', 12);