@cervellaswarm/mcp-server 0.1.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/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # CervellaSwarm MCP Server
2
+
3
+ > 16 AI agents as MCP tools for Claude Code integration.
4
+
5
+ ## Quick Start
6
+
7
+ ### 1. Install
8
+
9
+ ```bash
10
+ cd packages/mcp-server
11
+ npm install
12
+ npm run build
13
+ ```
14
+
15
+ ### 2. Configure Claude Code
16
+
17
+ Add to your `~/.claude/settings.json`:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "cervellaswarm": {
23
+ "command": "node",
24
+ "args": ["/path/to/CervellaSwarm/packages/mcp-server/dist/index.js"]
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ Or add to your project's `.mcp.json`:
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "cervellaswarm": {
36
+ "command": "node",
37
+ "args": ["./packages/mcp-server/dist/index.js"]
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### 3. Set API Key
44
+
45
+ Either run `cervellaswarm init` or set environment variable:
46
+
47
+ ```bash
48
+ export ANTHROPIC_API_KEY=sk-ant-...
49
+ ```
50
+
51
+ ### 4. Use in Claude Code
52
+
53
+ Once configured, you'll have access to these tools in Claude Code:
54
+
55
+ - **spawn_worker**: Execute tasks with specialized AI workers
56
+ - **list_workers**: See available workers
57
+ - **check_status**: Verify configuration
58
+
59
+ ## Available Workers
60
+
61
+ | Worker | Specialty |
62
+ |--------|-----------|
63
+ | backend | Python, FastAPI, API, Database |
64
+ | frontend | React, CSS, Tailwind, UI/UX |
65
+ | tester | Testing, Debug, QA |
66
+ | docs | Documentation, README, Guides |
67
+ | devops | Deploy, CI/CD, Docker |
68
+ | data | SQL, Analytics, Database Design |
69
+ | security | Security Audit, Vulnerabilities |
70
+ | researcher | Research, Analysis, Best Practices |
71
+
72
+ ## Example Usage in Claude Code
73
+
74
+ ```
75
+ Use spawn_worker to create a REST API endpoint for user authentication
76
+ ```
77
+
78
+ Claude Code will call the `spawn_worker` tool with `worker: "backend"` automatically.
79
+
80
+ ## Development
81
+
82
+ ```bash
83
+ # Watch mode
84
+ npm run dev
85
+
86
+ # Test with MCP Inspector
87
+ npm run inspect
88
+
89
+ # Build
90
+ npm run build
91
+ ```
92
+
93
+ ## Architecture
94
+
95
+ ```
96
+ MCP Server (this package)
97
+
98
+ ├── Tools
99
+ │ ├── spawn_worker → Anthropic API
100
+ │ ├── list_workers → Static list
101
+ │ └── check_status → Config check
102
+
103
+ └── Shares config with CLI
104
+ └── ~/.config/cervellaswarm/config.json
105
+ ```
106
+
107
+ ---
108
+
109
+ *"16 agents. MCP integration. Your AI team in Claude Code."*
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Agent Spawner for MCP Server
3
+ *
4
+ * Launches specialized agents via Anthropic API.
5
+ * Port from CLI spawner.js to TypeScript.
6
+ *
7
+ * Copyright 2026 Rafa & Cervella
8
+ * Licensed under the Apache License, Version 2.0
9
+ */
10
+ type WorkerType = "backend" | "frontend" | "tester" | "docs" | "devops" | "data" | "security" | "researcher";
11
+ interface WorkerInfo {
12
+ name: string;
13
+ description: string;
14
+ }
15
+ interface SpawnResult {
16
+ success: boolean;
17
+ output?: string;
18
+ error?: string;
19
+ duration?: string;
20
+ nextStep?: string;
21
+ usage?: {
22
+ inputTokens: number;
23
+ outputTokens: number;
24
+ };
25
+ attempts?: number;
26
+ }
27
+ /**
28
+ * Get all available workers
29
+ */
30
+ export declare function getAvailableWorkers(): WorkerInfo[];
31
+ /**
32
+ * Spawn a worker to execute a task
33
+ */
34
+ export declare function spawnWorker(worker: WorkerType, task: string, context?: string): Promise<SpawnResult>;
35
+ export {};
36
+ //# sourceMappingURL=spawner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawner.d.ts","sourceRoot":"","sources":["../../src/agents/spawner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,KAAK,UAAU,GACX,SAAS,GACT,UAAU,GACV,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,UAAU,GACV,YAAY,CAAC;AAEjB,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAyDD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,UAAU,EAAE,CAiBlD;AA4BD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CA8HtB"}
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Agent Spawner for MCP Server
3
+ *
4
+ * Launches specialized agents via Anthropic API.
5
+ * Port from CLI spawner.js to TypeScript.
6
+ *
7
+ * Copyright 2026 Rafa & Cervella
8
+ * Licensed under the Apache License, Version 2.0
9
+ */
10
+ import Anthropic from "@anthropic-ai/sdk";
11
+ import { getApiKey, getDefaultModel, getTimeout, getMaxRetries, } from "../config/manager.js";
12
+ // Retry delays (ms)
13
+ const RETRY_DELAYS = [1000, 3000, 5000];
14
+ // Worker system prompts
15
+ const WORKER_PROMPTS = {
16
+ backend: `Sei CERVELLA-BACKEND, specialista Python, FastAPI, Database, API REST, logica business.
17
+ Focus: Backend, API, database, server-side logic.
18
+ Stile: Codice pulito, ben documentato, testabile.
19
+ Output: Mostra il codice completo da creare/modificare.`,
20
+ frontend: `Sei CERVELLA-FRONTEND, specialista React, CSS, Tailwind, UI/UX, componenti.
21
+ Focus: UI, componenti, styling, user experience.
22
+ Stile: Componenti riutilizzabili, accessibili, responsive.
23
+ Output: Mostra il codice JSX/CSS completo.`,
24
+ tester: `Sei CERVELLA-TESTER, specialista Testing, Debug, QA, validazione.
25
+ Focus: Test unitari, integration test, bug hunting.
26
+ Stile: Test completi, edge cases, coverage alta.
27
+ Output: Mostra i test completi pronti per essere eseguiti.`,
28
+ docs: `Sei CERVELLA-DOCS, specialista Documentazione, README, guide, tutorial.
29
+ Focus: Documentazione chiara, esempi pratici, getting started.
30
+ Stile: Conciso ma completo, utente-first.
31
+ Output: Mostra la documentazione markdown completa.`,
32
+ devops: `Sei CERVELLA-DEVOPS, specialista Deploy, CI/CD, Docker, infrastruttura.
33
+ Focus: Deployment, automation, monitoring, infrastructure.
34
+ Stile: Sicuro, scalabile, automatizzato.
35
+ Output: Mostra configurazioni complete (Dockerfile, CI config, etc).`,
36
+ data: `Sei CERVELLA-DATA, specialista SQL, analytics, query, database design.
37
+ Focus: Query ottimizzate, schema design, data integrity.
38
+ Stile: Performance-first, normalization quando serve.
39
+ Output: Mostra query SQL e schema completi.`,
40
+ security: `Sei CERVELLA-SECURITY, specialista sicurezza, audit, vulnerabilita.
41
+ Focus: Security audit, vulnerabilities, best practices.
42
+ Stile: Defense in depth, zero trust, secure by default.
43
+ Output: Lista vulnerabilita trovate e fix raccomandati.`,
44
+ researcher: `Sei CERVELLA-RESEARCHER, specialista ricerca tecnica, studi, analisi.
45
+ Focus: Ricerca approfondita, comparazioni, best practices.
46
+ Stile: Fonti affidabili, analisi critica, raccomandazioni chiare.
47
+ Output: Report strutturato con findings e raccomandazioni.`,
48
+ };
49
+ // Next step suggestions per worker type
50
+ const NEXT_STEPS = {
51
+ backend: "Review the code and run: npm test",
52
+ frontend: "Preview in browser: npm run dev",
53
+ tester: "Run the test suite: npm test",
54
+ docs: "Review documentation for clarity",
55
+ devops: "Test deployment in staging first",
56
+ data: "Verify query performance with EXPLAIN",
57
+ security: "Apply the security fixes",
58
+ researcher: "Apply findings to your project",
59
+ };
60
+ /**
61
+ * Get all available workers
62
+ */
63
+ export function getAvailableWorkers() {
64
+ return [
65
+ { name: "cervella-backend", description: "Python, FastAPI, API, Database" },
66
+ { name: "cervella-frontend", description: "React, CSS, Tailwind, UI/UX" },
67
+ { name: "cervella-tester", description: "Testing, Debug, QA" },
68
+ { name: "cervella-docs", description: "Documentation, README, Guides" },
69
+ { name: "cervella-devops", description: "Deploy, CI/CD, Docker" },
70
+ { name: "cervella-data", description: "SQL, Analytics, Database Design" },
71
+ {
72
+ name: "cervella-security",
73
+ description: "Security Audit, Vulnerabilities",
74
+ },
75
+ {
76
+ name: "cervella-researcher",
77
+ description: "Research, Analysis, Best Practices",
78
+ },
79
+ ];
80
+ }
81
+ /**
82
+ * Sleep utility
83
+ */
84
+ function sleep(ms) {
85
+ return new Promise((resolve) => setTimeout(resolve, ms));
86
+ }
87
+ /**
88
+ * Build system prompt for worker
89
+ */
90
+ function buildSystemPrompt(worker, context) {
91
+ let prompt = WORKER_PROMPTS[worker];
92
+ if (context) {
93
+ prompt += `\n\nContesto progetto:\n${context}`;
94
+ }
95
+ prompt += `\n\nREGOLE:
96
+ - Scrivi codice REALE che funziona
97
+ - Se crei/modifichi file, indica chiaramente quali
98
+ - Sii conciso ma completo
99
+ - Segui le best practices del linguaggio`;
100
+ return prompt;
101
+ }
102
+ /**
103
+ * Spawn a worker to execute a task
104
+ */
105
+ export async function spawnWorker(worker, task, context) {
106
+ const apiKey = getApiKey();
107
+ if (!apiKey) {
108
+ return {
109
+ success: false,
110
+ error: "API key not configured",
111
+ nextStep: "Run cervellaswarm init or set ANTHROPIC_API_KEY",
112
+ };
113
+ }
114
+ const systemPrompt = buildSystemPrompt(worker, context);
115
+ const model = getDefaultModel();
116
+ const maxTokens = 4096;
117
+ const timeout = getTimeout();
118
+ const maxRetries = getMaxRetries();
119
+ const startTime = Date.now();
120
+ let lastError = null;
121
+ let attempt = 0;
122
+ while (attempt < maxRetries) {
123
+ attempt++;
124
+ try {
125
+ const client = new Anthropic({ apiKey });
126
+ // Create abort controller for timeout
127
+ const controller = new AbortController();
128
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
129
+ try {
130
+ const message = await client.messages.create({
131
+ model,
132
+ max_tokens: maxTokens,
133
+ system: systemPrompt,
134
+ messages: [{ role: "user", content: task }],
135
+ }, { signal: controller.signal });
136
+ clearTimeout(timeoutId);
137
+ const duration = Math.round((Date.now() - startTime) / 1000);
138
+ const output = message.content
139
+ .filter((block) => block.type === "text")
140
+ .map((block) => block.text)
141
+ .join("\n");
142
+ return {
143
+ success: true,
144
+ output: output.trim(),
145
+ duration: `${duration}s`,
146
+ nextStep: NEXT_STEPS[worker],
147
+ usage: {
148
+ inputTokens: message.usage.input_tokens,
149
+ outputTokens: message.usage.output_tokens,
150
+ },
151
+ attempts: attempt,
152
+ };
153
+ }
154
+ finally {
155
+ clearTimeout(timeoutId);
156
+ }
157
+ }
158
+ catch (error) {
159
+ lastError = error instanceof Error ? error : new Error(String(error));
160
+ // Check if retryable
161
+ const status = error.status;
162
+ const isRetryable = status === 429 || status === 500 || status === 503;
163
+ if (!isRetryable || attempt >= maxRetries) {
164
+ const duration = Math.round((Date.now() - startTime) / 1000);
165
+ // Map error to user-friendly message
166
+ let errorMessage = lastError.message;
167
+ let nextStep = "Check the error and try again";
168
+ if (status === 401) {
169
+ errorMessage = "Invalid API key";
170
+ nextStep =
171
+ "Your API key is invalid. Get a new one at https://console.anthropic.com/";
172
+ }
173
+ else if (status === 403) {
174
+ errorMessage = "API key lacks permissions";
175
+ nextStep =
176
+ "Your API key doesn't have the required permissions. Check at https://console.anthropic.com/";
177
+ }
178
+ else if (status === 429) {
179
+ errorMessage = "Rate limit exceeded";
180
+ nextStep =
181
+ "You've hit the rate limit. Wait a few seconds and try again, or upgrade your plan.";
182
+ }
183
+ else if (status === 500) {
184
+ errorMessage = "Anthropic API server error";
185
+ nextStep =
186
+ "Anthropic is having issues. Check https://status.anthropic.com/ and try again later.";
187
+ }
188
+ else if (status === 503) {
189
+ errorMessage = "Anthropic API temporarily unavailable";
190
+ nextStep =
191
+ "The API is temporarily overloaded. Wait a moment and try again.";
192
+ }
193
+ else if (lastError.name === "AbortError") {
194
+ errorMessage = "Request timed out";
195
+ nextStep = `The request took too long. Try a simpler task or increase timeout.`;
196
+ }
197
+ return {
198
+ success: false,
199
+ error: errorMessage,
200
+ duration: `${duration}s`,
201
+ nextStep,
202
+ attempts: attempt,
203
+ };
204
+ }
205
+ // Wait before retry
206
+ const delay = RETRY_DELAYS[attempt - 1] || RETRY_DELAYS[RETRY_DELAYS.length - 1];
207
+ await sleep(delay);
208
+ }
209
+ }
210
+ // Should not reach here
211
+ return {
212
+ success: false,
213
+ error: lastError?.message || "Unknown error after retries",
214
+ nextStep: "Check the error and try again",
215
+ attempts: attempt,
216
+ };
217
+ }
218
+ //# sourceMappingURL=spawner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawner.js","sourceRoot":"","sources":["../../src/agents/spawner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EACL,SAAS,EACT,eAAe,EACf,UAAU,EACV,aAAa,GACd,MAAM,sBAAsB,CAAC;AAE9B,oBAAoB;AACpB,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AA+BxC,wBAAwB;AACxB,MAAM,cAAc,GAA+B;IACjD,OAAO,EAAE;;;wDAG6C;IAEtD,QAAQ,EAAE;;;2CAG+B;IAEzC,MAAM,EAAE;;;2DAGiD;IAEzD,IAAI,EAAE;;;oDAG4C;IAElD,MAAM,EAAE;;;qEAG2D;IAEnE,IAAI,EAAE;;;4CAGoC;IAE1C,QAAQ,EAAE;;;wDAG4C;IAEtD,UAAU,EAAE;;;2DAG6C;CAC1D,CAAC;AAEF,wCAAwC;AACxC,MAAM,UAAU,GAA+B;IAC7C,OAAO,EAAE,mCAAmC;IAC5C,QAAQ,EAAE,iCAAiC;IAC3C,MAAM,EAAE,8BAA8B;IACtC,IAAI,EAAE,kCAAkC;IACxC,MAAM,EAAE,kCAAkC;IAC1C,IAAI,EAAE,uCAAuC;IAC7C,QAAQ,EAAE,0BAA0B;IACpC,UAAU,EAAE,gCAAgC;CAC7C,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,EAAE,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,gCAAgC,EAAE;QAC3E,EAAE,IAAI,EAAE,mBAAmB,EAAE,WAAW,EAAE,6BAA6B,EAAE;QACzE,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,oBAAoB,EAAE;QAC9D,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,+BAA+B,EAAE;QACvE,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,uBAAuB,EAAE;QACjE,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,iCAAiC,EAAE;QACzE;YACE,IAAI,EAAE,mBAAmB;YACzB,WAAW,EAAE,iCAAiC;SAC/C;QACD;YACE,IAAI,EAAE,qBAAqB;YAC3B,WAAW,EAAE,oCAAoC;SAClD;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAAkB,EAAE,OAAgB;IAC7D,IAAI,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAEpC,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,2BAA2B,OAAO,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,IAAI;;;;yCAI6B,CAAC;IAExC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAkB,EAClB,IAAY,EACZ,OAAgB;IAEhB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,wBAAwB;YAC/B,QAAQ,EAAE,iDAAiD;SAC5D,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC;IACvB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,SAAS,GAAiB,IAAI,CAAC;IACnC,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,OAAO,OAAO,GAAG,UAAU,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;QAEV,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YAEzC,sCAAsC;YACtC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;YAEhE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAC1C;oBACE,KAAK;oBACL,UAAU,EAAE,SAAS;oBACrB,MAAM,EAAE,YAAY;oBACpB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;iBAC5C,EACD,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAC9B,CAAC;gBAEF,YAAY,CAAC,SAAS,CAAC,CAAC;gBAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;gBAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO;qBAC3B,MAAM,CAAC,CAAC,KAAK,EAAgC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;qBACtE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;qBAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEd,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;oBACrB,QAAQ,EAAE,GAAG,QAAQ,GAAG;oBACxB,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC;oBAC5B,KAAK,EAAE;wBACL,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY;wBACvC,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa;qBAC1C;oBACD,QAAQ,EAAE,OAAO;iBAClB,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAEtE,qBAAqB;YACrB,MAAM,MAAM,GAAI,KAA6B,CAAC,MAAM,CAAC;YACrD,MAAM,WAAW,GAAG,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,CAAC;YAEvE,IAAI,CAAC,WAAW,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;gBAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;gBAE7D,qCAAqC;gBACrC,IAAI,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC;gBACrC,IAAI,QAAQ,GAAG,+BAA+B,CAAC;gBAE/C,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;oBACnB,YAAY,GAAG,iBAAiB,CAAC;oBACjC,QAAQ;wBACN,0EAA0E,CAAC;gBAC/E,CAAC;qBAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC1B,YAAY,GAAG,2BAA2B,CAAC;oBAC3C,QAAQ;wBACN,6FAA6F,CAAC;gBAClG,CAAC;qBAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC1B,YAAY,GAAG,qBAAqB,CAAC;oBACrC,QAAQ;wBACN,oFAAoF,CAAC;gBACzF,CAAC;qBAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC1B,YAAY,GAAG,4BAA4B,CAAC;oBAC5C,QAAQ;wBACN,sFAAsF,CAAC;gBAC3F,CAAC;qBAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC1B,YAAY,GAAG,uCAAuC,CAAC;oBACvD,QAAQ;wBACN,iEAAiE,CAAC;gBACtE,CAAC;qBAAM,IAAI,SAAS,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBAC3C,YAAY,GAAG,mBAAmB,CAAC;oBACnC,QAAQ,GAAG,oEAAoE,CAAC;gBAClF,CAAC;gBAED,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,YAAY;oBACnB,QAAQ,EAAE,GAAG,QAAQ,GAAG;oBACxB,QAAQ;oBACR,QAAQ,EAAE,OAAO;iBAClB,CAAC;YACJ,CAAC;YAED,oBAAoB;YACpB,MAAM,KAAK,GACT,YAAY,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrE,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,OAAO;QACL,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,SAAS,EAAE,OAAO,IAAI,6BAA6B;QAC1D,QAAQ,EAAE,+BAA+B;QACzC,QAAQ,EAAE,OAAO;KAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * UX Messages for CervellaSwarm Billing
3
+ *
4
+ * User-friendly messages for quota warnings and limits.
5
+ * Designed to be helpful, not aggressive.
6
+ *
7
+ * Copyright 2026 Rafa & Cervella
8
+ * Licensed under the Apache License, Version 2.0
9
+ */
10
+ import type { Tier } from "./types.js";
11
+ /**
12
+ * Get warning message (shown at 80% usage)
13
+ */
14
+ export declare function getWarningMessage(tier: Tier, used: number, limit: number): string;
15
+ /**
16
+ * Get limit exceeded message (shown at 100%)
17
+ */
18
+ export declare function getLimitExceededMessage(tier: Tier, limit: number, resetsAt: string): string;
19
+ /**
20
+ * Get usage status message (for check_usage tool)
21
+ */
22
+ export declare function getUsageStatusMessage(tier: Tier, used: number, limit: number, resetsAt: string): string;
23
+ /**
24
+ * Get first-time welcome message
25
+ */
26
+ export declare function getWelcomeMessage(tier: Tier): string;
27
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/billing/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAqBvC;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,MAAM,CAeR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,MAAM,CAoBR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,MAAM,CAsCR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAQpD"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * UX Messages for CervellaSwarm Billing
3
+ *
4
+ * User-friendly messages for quota warnings and limits.
5
+ * Designed to be helpful, not aggressive.
6
+ *
7
+ * Copyright 2026 Rafa & Cervella
8
+ * Licensed under the Apache License, Version 2.0
9
+ */
10
+ import { TIER_NAMES, TIER_LIMITS, TIER_PRICES, getUpgradeTier, getUpgradeUrl, } from "./tiers.js";
11
+ /**
12
+ * Format date for display
13
+ */
14
+ function formatResetDate(isoDate) {
15
+ const date = new Date(isoDate);
16
+ return date.toLocaleDateString("en-US", {
17
+ month: "long",
18
+ day: "numeric",
19
+ year: "numeric",
20
+ });
21
+ }
22
+ /**
23
+ * Get warning message (shown at 80% usage)
24
+ */
25
+ export function getWarningMessage(tier, used, limit) {
26
+ const remaining = limit - used;
27
+ const nextTier = getUpgradeTier(tier);
28
+ let message = `You're running low on API calls.\n`;
29
+ message += `Used: ${used}/${limit} (${remaining} remaining)\n\n`;
30
+ if (nextTier) {
31
+ const nextLimit = TIER_LIMITS[nextTier];
32
+ const nextPrice = TIER_PRICES[nextTier];
33
+ message += `Upgrade to ${TIER_NAMES[nextTier]} for ${nextLimit} calls/month ($${nextPrice}/mo).\n`;
34
+ message += `${getUpgradeUrl(tier)}`;
35
+ }
36
+ return message;
37
+ }
38
+ /**
39
+ * Get limit exceeded message (shown at 100%)
40
+ */
41
+ export function getLimitExceededMessage(tier, limit, resetsAt) {
42
+ const nextTier = getUpgradeTier(tier);
43
+ const resetDate = formatResetDate(resetsAt);
44
+ let message = `Monthly limit reached.\n\n`;
45
+ message += `You've used all ${limit} calls for ${TIER_NAMES[tier]} plan.\n`;
46
+ message += `Your quota resets on ${resetDate}.\n\n`;
47
+ if (nextTier) {
48
+ const nextLimit = TIER_LIMITS[nextTier];
49
+ const nextPrice = TIER_PRICES[nextTier];
50
+ message += `Upgrade to ${TIER_NAMES[nextTier]} for ${nextLimit} calls/month ($${nextPrice}/mo):\n`;
51
+ message += `${getUpgradeUrl(tier)}\n\n`;
52
+ message += `Or wait until ${resetDate} for your quota to reset.`;
53
+ }
54
+ else {
55
+ message += `Contact us for custom Enterprise plans:\n`;
56
+ message += `https://cervellaswarm.com/contact`;
57
+ }
58
+ return message;
59
+ }
60
+ /**
61
+ * Get usage status message (for check_usage tool)
62
+ */
63
+ export function getUsageStatusMessage(tier, used, limit, resetsAt) {
64
+ const remaining = limit - used;
65
+ const percentage = Math.round((used / limit) * 100);
66
+ const resetDate = formatResetDate(resetsAt);
67
+ let message = `# CervellaSwarm Usage\n\n`;
68
+ message += `**Plan:** ${TIER_NAMES[tier]}\n`;
69
+ message += `**Usage:** ${used}/${limit} calls (${percentage}%)\n`;
70
+ message += `**Remaining:** ${remaining} calls\n`;
71
+ message += `**Resets:** ${resetDate}\n`;
72
+ // Progress bar
73
+ const barLength = 20;
74
+ const filled = Math.round((used / limit) * barLength);
75
+ const empty = barLength - filled;
76
+ const bar = "█".repeat(filled) + "░".repeat(empty);
77
+ message += `\n\`[${bar}]\` ${percentage}%\n`;
78
+ // Status indicator
79
+ if (percentage >= 100) {
80
+ message += `\n⛔ **Limit reached** - Upgrade or wait for reset.\n`;
81
+ }
82
+ else if (percentage >= 80) {
83
+ message += `\n⚠️ **Running low** - Consider upgrading.\n`;
84
+ }
85
+ else {
86
+ message += `\n✅ **Good standing**\n`;
87
+ }
88
+ // Upgrade suggestion if not enterprise
89
+ const nextTier = getUpgradeTier(tier);
90
+ if (nextTier && percentage >= 50) {
91
+ const nextLimit = TIER_LIMITS[nextTier];
92
+ const nextPrice = TIER_PRICES[nextTier];
93
+ message += `\n---\n`;
94
+ message += `**Upgrade to ${TIER_NAMES[nextTier]}:** ${nextLimit} calls/month for $${nextPrice}/mo\n`;
95
+ message += `${getUpgradeUrl(tier)}`;
96
+ }
97
+ return message;
98
+ }
99
+ /**
100
+ * Get first-time welcome message
101
+ */
102
+ export function getWelcomeMessage(tier) {
103
+ const limit = TIER_LIMITS[tier];
104
+ return (`Welcome to CervellaSwarm!\n\n` +
105
+ `You're on the ${TIER_NAMES[tier]} plan with ${limit} calls/month.\n` +
106
+ `Use \`check_status\` anytime to see your usage.`);
107
+ }
108
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/billing/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE;QACtC,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAU,EACV,IAAY,EACZ,KAAa;IAEb,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC;IAC/B,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,OAAO,GAAG,oCAAoC,CAAC;IACnD,OAAO,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,SAAS,iBAAiB,CAAC;IAEjE,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,IAAI,cAAc,UAAU,CAAC,QAAQ,CAAC,QAAQ,SAAS,kBAAkB,SAAS,SAAS,CAAC;QACnG,OAAO,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAU,EACV,KAAa,EACb,QAAgB;IAEhB,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,OAAO,GAAG,4BAA4B,CAAC;IAC3C,OAAO,IAAI,mBAAmB,KAAK,cAAc,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC;IAC5E,OAAO,IAAI,wBAAwB,SAAS,OAAO,CAAC;IAEpD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,IAAI,cAAc,UAAU,CAAC,QAAQ,CAAC,QAAQ,SAAS,kBAAkB,SAAS,SAAS,CAAC;QACnG,OAAO,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QACxC,OAAO,IAAI,iBAAiB,SAAS,2BAA2B,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,2CAA2C,CAAC;QACvD,OAAO,IAAI,mCAAmC,CAAC;IACjD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAU,EACV,IAAY,EACZ,KAAa,EACb,QAAgB;IAEhB,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,OAAO,GAAG,2BAA2B,CAAC;IAC1C,OAAO,IAAI,aAAa,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7C,OAAO,IAAI,cAAc,IAAI,IAAI,KAAK,WAAW,UAAU,MAAM,CAAC;IAClE,OAAO,IAAI,kBAAkB,SAAS,UAAU,CAAC;IACjD,OAAO,IAAI,eAAe,SAAS,IAAI,CAAC;IAExC,eAAe;IACf,MAAM,SAAS,GAAG,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IACjC,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnD,OAAO,IAAI,QAAQ,GAAG,OAAO,UAAU,KAAK,CAAC;IAE7C,mBAAmB;IACnB,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;QACtB,OAAO,IAAI,sDAAsD,CAAC;IACpE,CAAC;SAAM,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QAC5B,OAAO,IAAI,8CAA8C,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,yBAAyB,CAAC;IACvC,CAAC;IAED,uCAAuC;IACvC,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,QAAQ,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,IAAI,SAAS,CAAC;QACrB,OAAO,IAAI,gBAAgB,UAAU,CAAC,QAAQ,CAAC,OAAO,SAAS,qBAAqB,SAAS,OAAO,CAAC;QACrG,OAAO,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU;IAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAEhC,OAAO,CACL,+BAA+B;QAC/B,iBAAiB,UAAU,CAAC,IAAI,CAAC,cAAc,KAAK,iBAAiB;QACrE,iDAAiD,CAClD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Tier Configuration for CervellaSwarm
3
+ *
4
+ * Defines limits and pricing for each subscription tier.
5
+ * Single source of truth for tier-related constants.
6
+ *
7
+ * Copyright 2026 Rafa & Cervella
8
+ * Licensed under the Apache License, Version 2.0
9
+ */
10
+ import type { Tier } from "./types.js";
11
+ /**
12
+ * Monthly call limits per tier
13
+ */
14
+ export declare const TIER_LIMITS: Record<Tier, number>;
15
+ /**
16
+ * Tier pricing (USD/month)
17
+ */
18
+ export declare const TIER_PRICES: Record<Tier, number>;
19
+ /**
20
+ * Tier display names
21
+ */
22
+ export declare const TIER_NAMES: Record<Tier, string>;
23
+ /**
24
+ * Upgrade path (what's the next tier up)
25
+ */
26
+ export declare const TIER_UPGRADE_PATH: Record<Tier, Tier | null>;
27
+ /**
28
+ * Warning threshold (percentage)
29
+ */
30
+ export declare const WARNING_THRESHOLD = 0.8;
31
+ /**
32
+ * Maximum history records to keep
33
+ */
34
+ export declare const MAX_HISTORY_RECORDS = 12;
35
+ /**
36
+ * Current schema version
37
+ */
38
+ export declare const SCHEMA_VERSION = "1.0.0";
39
+ /**
40
+ * Get limit for a tier
41
+ */
42
+ export declare function getLimitForTier(tier: Tier): number;
43
+ /**
44
+ * Get next upgrade tier
45
+ */
46
+ export declare function getUpgradeTier(currentTier: Tier): Tier | null;
47
+ /**
48
+ * Check if tier has unlimited calls
49
+ */
50
+ export declare function isUnlimited(tier: Tier): boolean;
51
+ /**
52
+ * Get upgrade URL (placeholder for now)
53
+ */
54
+ export declare function getUpgradeUrl(fromTier: Tier): string;
55
+ //# sourceMappingURL=tiers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiers.d.ts","sourceRoot":"","sources":["../../src/billing/tiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAK5C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAK5C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAK3C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAKvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;GAEG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;GAEG;AACH,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAElD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAMpD"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Tier Configuration for CervellaSwarm
3
+ *
4
+ * Defines limits and pricing for each subscription tier.
5
+ * Single source of truth for tier-related constants.
6
+ *
7
+ * Copyright 2026 Rafa & Cervella
8
+ * Licensed under the Apache License, Version 2.0
9
+ */
10
+ /**
11
+ * Monthly call limits per tier
12
+ */
13
+ export const TIER_LIMITS = {
14
+ free: 50,
15
+ pro: 500,
16
+ team: 1000,
17
+ enterprise: Infinity,
18
+ };
19
+ /**
20
+ * Tier pricing (USD/month)
21
+ */
22
+ export const TIER_PRICES = {
23
+ free: 0,
24
+ pro: 20,
25
+ team: 35,
26
+ enterprise: -1, // Custom pricing
27
+ };
28
+ /**
29
+ * Tier display names
30
+ */
31
+ export const TIER_NAMES = {
32
+ free: "Free",
33
+ pro: "Pro",
34
+ team: "Team",
35
+ enterprise: "Enterprise",
36
+ };
37
+ /**
38
+ * Upgrade path (what's the next tier up)
39
+ */
40
+ export const TIER_UPGRADE_PATH = {
41
+ free: "pro",
42
+ pro: "team",
43
+ team: "enterprise",
44
+ enterprise: null,
45
+ };
46
+ /**
47
+ * Warning threshold (percentage)
48
+ */
49
+ export const WARNING_THRESHOLD = 0.8; // 80%
50
+ /**
51
+ * Maximum history records to keep
52
+ */
53
+ export const MAX_HISTORY_RECORDS = 12;
54
+ /**
55
+ * Current schema version
56
+ */
57
+ export const SCHEMA_VERSION = "1.0.0";
58
+ /**
59
+ * Get limit for a tier
60
+ */
61
+ export function getLimitForTier(tier) {
62
+ return TIER_LIMITS[tier] ?? TIER_LIMITS.free;
63
+ }
64
+ /**
65
+ * Get next upgrade tier
66
+ */
67
+ export function getUpgradeTier(currentTier) {
68
+ return TIER_UPGRADE_PATH[currentTier];
69
+ }
70
+ /**
71
+ * Check if tier has unlimited calls
72
+ */
73
+ export function isUnlimited(tier) {
74
+ return TIER_LIMITS[tier] === Infinity;
75
+ }
76
+ /**
77
+ * Get upgrade URL (placeholder for now)
78
+ */
79
+ export function getUpgradeUrl(fromTier) {
80
+ const nextTier = getUpgradeTier(fromTier);
81
+ if (!nextTier) {
82
+ return "https://cervellaswarm.com/contact";
83
+ }
84
+ return `https://cervellaswarm.com/upgrade?from=${fromTier}&to=${nextTier}`;
85
+ }
86
+ //# sourceMappingURL=tiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiers.js","sourceRoot":"","sources":["../../src/billing/tiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC/C,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,QAAQ;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC/C,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,EAAE;IACP,IAAI,EAAE,EAAE;IACR,UAAU,EAAE,CAAC,CAAC,EAAE,iBAAiB;CAClC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAyB;IAC9C,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,UAAU,EAAE,YAAY;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA8B;IAC1D,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,YAAY;IAClB,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAC,MAAM;AAE5C;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAU;IACxC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,WAAiB;IAC9C,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAU;IACpC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAc;IAC1C,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,mCAAmC,CAAC;IAC7C,CAAC;IACD,OAAO,0CAA0C,QAAQ,OAAO,QAAQ,EAAE,CAAC;AAC7E,CAAC"}