@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 +109 -0
- package/dist/agents/spawner.d.ts +36 -0
- package/dist/agents/spawner.d.ts.map +1 -0
- package/dist/agents/spawner.js +218 -0
- package/dist/agents/spawner.js.map +1 -0
- package/dist/billing/messages.d.ts +27 -0
- package/dist/billing/messages.d.ts.map +1 -0
- package/dist/billing/messages.js +108 -0
- package/dist/billing/messages.js.map +1 -0
- package/dist/billing/tiers.d.ts +55 -0
- package/dist/billing/tiers.d.ts.map +1 -0
- package/dist/billing/tiers.js +86 -0
- package/dist/billing/tiers.js.map +1 -0
- package/dist/billing/types.d.ts +113 -0
- package/dist/billing/types.d.ts.map +1 -0
- package/dist/billing/types.js +19 -0
- package/dist/billing/types.js.map +1 -0
- package/dist/billing/usage.d.ts +95 -0
- package/dist/billing/usage.d.ts.map +1 -0
- package/dist/billing/usage.js +383 -0
- package/dist/billing/usage.js.map +1 -0
- package/dist/config/manager.d.ts +31 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +160 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +261 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
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":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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"}
|