cmp-standards 2.6.0 → 2.8.0-alpha
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 +633 -633
- package/dist/cache/EmbeddingCache.d.ts +109 -0
- package/dist/cache/EmbeddingCache.d.ts.map +1 -0
- package/dist/cache/EmbeddingCache.js +239 -0
- package/dist/cache/EmbeddingCache.js.map +1 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/db/turso-client.js +11 -11
- package/dist/eslint/rules/no-async-useeffect.js +6 -6
- package/dist/events/EventBus.d.ts +87 -0
- package/dist/events/EventBus.d.ts.map +1 -0
- package/dist/events/EventBus.js +200 -0
- package/dist/events/EventBus.js.map +1 -0
- package/dist/events/index.d.ts +7 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +9 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +989 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +136 -0
- package/dist/events/types.js.map +1 -0
- package/dist/experts/ConsensusEngine.d.ts +57 -0
- package/dist/experts/ConsensusEngine.d.ts.map +1 -0
- package/dist/experts/ConsensusEngine.js +146 -0
- package/dist/experts/ConsensusEngine.js.map +1 -0
- package/dist/experts/ExpertPanelService.d.ts +84 -0
- package/dist/experts/ExpertPanelService.d.ts.map +1 -0
- package/dist/experts/ExpertPanelService.js +204 -0
- package/dist/experts/ExpertPanelService.js.map +1 -0
- package/dist/experts/ExpertRouter.d.ts +68 -0
- package/dist/experts/ExpertRouter.d.ts.map +1 -0
- package/dist/experts/ExpertRouter.js +374 -0
- package/dist/experts/ExpertRouter.js.map +1 -0
- package/dist/experts/VoteCollector.d.ts +58 -0
- package/dist/experts/VoteCollector.d.ts.map +1 -0
- package/dist/experts/VoteCollector.js +146 -0
- package/dist/experts/VoteCollector.js.map +1 -0
- package/dist/experts/index.d.ts +9 -0
- package/dist/experts/index.d.ts.map +1 -0
- package/dist/experts/index.js +13 -0
- package/dist/experts/index.js.map +1 -0
- package/dist/hooks/cloud-pre-tool-use.js +20 -20
- package/dist/hooks/expert-review.d.ts +74 -0
- package/dist/hooks/expert-review.d.ts.map +1 -0
- package/dist/hooks/expert-review.js +220 -0
- package/dist/hooks/expert-review.js.map +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/performance/Debouncer.d.ts +91 -0
- package/dist/performance/Debouncer.d.ts.map +1 -0
- package/dist/performance/Debouncer.js +198 -0
- package/dist/performance/Debouncer.js.map +1 -0
- package/dist/performance/MemoryDecay.d.ts +82 -0
- package/dist/performance/MemoryDecay.d.ts.map +1 -0
- package/dist/performance/MemoryDecay.js +153 -0
- package/dist/performance/MemoryDecay.js.map +1 -0
- package/dist/performance/index.d.ts +7 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +9 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/schema/expert-types.d.ts +395 -0
- package/dist/schema/expert-types.d.ts.map +1 -0
- package/dist/schema/expert-types.js +250 -0
- package/dist/schema/expert-types.js.map +1 -0
- package/dist/schema/plans.d.ts +16 -16
- package/dist/schema/tracking.d.ts +90 -90
- package/dist/services/ContextGenerator.js +7 -7
- package/dist/services/ProjectScaffold.js +76 -76
- package/dist/services/context-injector.d.ts +6 -0
- package/dist/services/context-injector.d.ts.map +1 -1
- package/dist/services/context-injector.js +43 -3
- package/dist/services/context-injector.js.map +1 -1
- package/dist/services/memory-router.d.ts +25 -1
- package/dist/services/memory-router.d.ts.map +1 -1
- package/dist/services/memory-router.js +176 -32
- package/dist/services/memory-router.js.map +1 -1
- package/dist/services/pattern-tracker.d.ts +5 -1
- package/dist/services/pattern-tracker.d.ts.map +1 -1
- package/dist/services/pattern-tracker.js +114 -36
- package/dist/services/pattern-tracker.js.map +1 -1
- package/dist/services/semantic-search.js +2 -2
- package/dist/types/index.d.ts +329 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +186 -9
- package/dist/types/index.js.map +1 -1
- package/package.json +105 -100
- package/standards/README.md +50 -50
- package/standards/experts/expert-routing.md +215 -215
- package/standards/general/code-quality.md +86 -86
- package/standards/general/memory-usage.md +205 -205
- package/standards/general/sync-workflow.md +235 -235
- package/standards/general/workflow.md +82 -82
- package/standards/hooks/mandatory-tracking.md +446 -446
- package/standards/infrastructure/cloud-database.md +287 -287
- package/standards/mcp/server-design.md +243 -243
- package/standards/mcp/tool-patterns.md +354 -354
- package/standards/skills/skill-structure.md +286 -286
- package/standards/skills/workflow-design.md +323 -323
- package/standards/tools/tool-design.md +297 -297
- package/templates/agents/architecture-expert.md +61 -61
- package/templates/agents/database-expert.md +62 -62
- package/templates/agents/documentation-expert.md +57 -57
- package/templates/agents/memory-expert.md +88 -88
- package/templates/agents/performance-expert.md +61 -61
- package/templates/agents/security-expert.md +59 -59
- package/templates/agents/ux-expert.md +63 -63
- package/templates/agents/worker.md +75 -75
- package/templates/ai-skills/SKILL_TEMPLATE.md +55 -55
- package/templates/claude-settings.json +72 -72
- package/templates/commands/experts.md +138 -138
- package/templates/hooks/README.md +158 -158
- package/templates/hooks/project.config.json.template +77 -77
- package/templates/hooks/settings.local.json.template +57 -57
- package/templates/memory-config.json +56 -56
- package/templates/memory-config.schema.json +212 -212
- package/templates/settings.json +58 -58
- package/templates/skills/continue.md +205 -205
- package/templates/workflows/business-improvement.md +264 -264
- package/templates/workflows/expert-review.md +153 -153
- package/templates/workflows/internal-app.md +245 -245
- package/templates/workflows/sync-docs.md +187 -187
|
@@ -1,287 +1,287 @@
|
|
|
1
|
-
# Infraestructura de Base de Datos Cloud
|
|
2
|
-
|
|
3
|
-
## Stack Recomendado (100% Gratuito)
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
7
|
-
│ ARQUITECTURA CLOUD │
|
|
8
|
-
├─────────────────────────────────────────────────────────────┤
|
|
9
|
-
│ │
|
|
10
|
-
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
11
|
-
│ │ Turso │ │ Upstash │ │ Upstash │ │
|
|
12
|
-
│ │ (SQLite) │ │ (Vector) │ │ (Redis) │ │
|
|
13
|
-
│ │ │ │ │ │ │ │
|
|
14
|
-
│ │ • Tareas │ │ • Embeddings│ │ • Cache │ │
|
|
15
|
-
│ │ • Mejoras │ │ • Semantic │ │ • Sessions │ │
|
|
16
|
-
│ │ • Sesiones │ │ Search │ │ • Config │ │
|
|
17
|
-
│ │ • Memorias │ │ │ │ │ │
|
|
18
|
-
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
19
|
-
│ │ │ │ │
|
|
20
|
-
│ └────────────────┼────────────────┘ │
|
|
21
|
-
│ │ │
|
|
22
|
-
│ ▼ │
|
|
23
|
-
│ ┌─────────────────────┐ │
|
|
24
|
-
│ │ MCP Server │ │
|
|
25
|
-
│ │ (Vercel Edge) │ │
|
|
26
|
-
│ └─────────────────────┘ │
|
|
27
|
-
│ │ │
|
|
28
|
-
│ ▼ │
|
|
29
|
-
│ ┌─────────────────────┐ │
|
|
30
|
-
│ │ Claude Code │ │
|
|
31
|
-
│ └─────────────────────┘ │
|
|
32
|
-
│ │
|
|
33
|
-
└─────────────────────────────────────────────────────────────┘
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Turso (SQLite Edge)
|
|
37
|
-
|
|
38
|
-
**Propósito**: Base de datos principal para tareas, mejoras, memorias.
|
|
39
|
-
|
|
40
|
-
### Free Tier
|
|
41
|
-
- 500M rows read/mes
|
|
42
|
-
- 10M rows written/mes
|
|
43
|
-
- 5GB storage
|
|
44
|
-
- 100 databases
|
|
45
|
-
- Sin tarjeta de crédito
|
|
46
|
-
|
|
47
|
-
### Setup
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
# Instalar CLI
|
|
51
|
-
brew install tursodatabase/tap/turso
|
|
52
|
-
|
|
53
|
-
# Login
|
|
54
|
-
turso auth login
|
|
55
|
-
|
|
56
|
-
# Crear database
|
|
57
|
-
turso db create cmp-memory
|
|
58
|
-
|
|
59
|
-
# Obtener URL
|
|
60
|
-
turso db show cmp-memory --url
|
|
61
|
-
# → libsql://cmp-memory-username.turso.io
|
|
62
|
-
|
|
63
|
-
# Crear token
|
|
64
|
-
turso db tokens create cmp-memory
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Configuración
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
// src/db/turso-client.ts
|
|
71
|
-
import { createClient } from '@libsql/client'
|
|
72
|
-
import { drizzle } from 'drizzle-orm/libsql'
|
|
73
|
-
|
|
74
|
-
export function createTursoDB() {
|
|
75
|
-
const client = createClient({
|
|
76
|
-
url: process.env.TURSO_DATABASE_URL!,
|
|
77
|
-
authToken: process.env.TURSO_AUTH_TOKEN!
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
return drizzle(client)
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Variables de Entorno
|
|
85
|
-
|
|
86
|
-
```env
|
|
87
|
-
TURSO_DATABASE_URL=libsql://cmp-memory-username.turso.io
|
|
88
|
-
TURSO_AUTH_TOKEN=eyJ...
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Upstash Vector
|
|
92
|
-
|
|
93
|
-
**Propósito**: Búsqueda semántica de memorias y contexto.
|
|
94
|
-
|
|
95
|
-
### Free Tier
|
|
96
|
-
- 200M vectors
|
|
97
|
-
- 1GB data/metadata
|
|
98
|
-
- 10K queries/día
|
|
99
|
-
- Built-in embeddings
|
|
100
|
-
|
|
101
|
-
### Setup
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
# Crear en dashboard: https://console.upstash.com/vector
|
|
105
|
-
# Obtener UPSTASH_VECTOR_REST_URL y UPSTASH_VECTOR_REST_TOKEN
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### Configuración
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
// src/db/vector-client.ts
|
|
112
|
-
import { Index } from '@upstash/vector'
|
|
113
|
-
|
|
114
|
-
export const vectorIndex = new Index({
|
|
115
|
-
url: process.env.UPSTASH_VECTOR_REST_URL!,
|
|
116
|
-
token: process.env.UPSTASH_VECTOR_REST_TOKEN!
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
// Insertar con embedding automático
|
|
120
|
-
await vectorIndex.upsert({
|
|
121
|
-
id: 'mem_123',
|
|
122
|
-
data: 'Este es el contenido de la memoria...',
|
|
123
|
-
metadata: {
|
|
124
|
-
type: 'memory',
|
|
125
|
-
domain: 'video-studio',
|
|
126
|
-
createdAt: new Date().toISOString()
|
|
127
|
-
}
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
// Buscar por similitud
|
|
131
|
-
const results = await vectorIndex.query({
|
|
132
|
-
data: 'buscar memorias sobre video',
|
|
133
|
-
topK: 5,
|
|
134
|
-
includeMetadata: true
|
|
135
|
-
})
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### Variables de Entorno
|
|
139
|
-
|
|
140
|
-
```env
|
|
141
|
-
UPSTASH_VECTOR_REST_URL=https://abc-xyz.upstash.io
|
|
142
|
-
UPSTASH_VECTOR_REST_TOKEN=AXxx...
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Upstash Redis
|
|
146
|
-
|
|
147
|
-
**Propósito**: Cache de configuración y sesiones activas.
|
|
148
|
-
|
|
149
|
-
### Free Tier
|
|
150
|
-
- 10K commands/día
|
|
151
|
-
- 256MB storage
|
|
152
|
-
- Global replication
|
|
153
|
-
|
|
154
|
-
### Setup
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
# Crear en dashboard: https://console.upstash.com/redis
|
|
158
|
-
# Obtener UPSTASH_REDIS_REST_URL y UPSTASH_REDIS_REST_TOKEN
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Configuración
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
// src/db/redis-client.ts
|
|
165
|
-
import { Redis } from '@upstash/redis'
|
|
166
|
-
|
|
167
|
-
export const redis = new Redis({
|
|
168
|
-
url: process.env.UPSTASH_REDIS_REST_URL!,
|
|
169
|
-
token: process.env.UPSTASH_REDIS_REST_TOKEN!
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
// Cache de config (TTL 1 hora)
|
|
173
|
-
await redis.set('config:SWARMSCALE', config, { ex: 3600 })
|
|
174
|
-
|
|
175
|
-
// Leer config
|
|
176
|
-
const cached = await redis.get('config:SWARMSCALE')
|
|
177
|
-
|
|
178
|
-
// Sesiones activas
|
|
179
|
-
await redis.hset('sessions:active', {
|
|
180
|
-
[sessionId]: JSON.stringify(sessionData)
|
|
181
|
-
})
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Variables de Entorno
|
|
185
|
-
|
|
186
|
-
```env
|
|
187
|
-
UPSTASH_REDIS_REST_URL=https://def-uvw.upstash.io
|
|
188
|
-
UPSTASH_REDIS_REST_TOKEN=AYyy...
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## Migración desde PlanetScale/Railway
|
|
192
|
-
|
|
193
|
-
### Estrategia
|
|
194
|
-
|
|
195
|
-
1. **Fase 1**: Dual-write (escribir a ambos)
|
|
196
|
-
2. **Fase 2**: Read from Turso, write to both
|
|
197
|
-
3. **Fase 3**: Full migration, keep PlanetScale as backup
|
|
198
|
-
|
|
199
|
-
### Script de Migración
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
// scripts/migrate-to-turso.ts
|
|
203
|
-
import { db as planetscale } from './db/planetscale'
|
|
204
|
-
import { db as turso } from './db/turso'
|
|
205
|
-
|
|
206
|
-
async function migrate() {
|
|
207
|
-
console.log('Fetching memories from PlanetScale...')
|
|
208
|
-
|
|
209
|
-
const memories = await planetscale.query.devItems.findMany({
|
|
210
|
-
where: eq(devItems.system, 'SWARMSCALE')
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
console.log(`Found ${memories.length} memories`)
|
|
214
|
-
|
|
215
|
-
// Batch insert to Turso
|
|
216
|
-
for (const batch of chunk(memories, 100)) {
|
|
217
|
-
await turso.insert(devItems).values(batch)
|
|
218
|
-
console.log(`Migrated ${batch.length} items`)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
console.log('Migration complete!')
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
## Costos Estimados
|
|
226
|
-
|
|
227
|
-
| Uso | Turso | Vector | Redis | Total |
|
|
228
|
-
|-----|-------|--------|-------|-------|
|
|
229
|
-
| Desarrollo | $0 | $0 | $0 | **$0** |
|
|
230
|
-
| Producción pequeña | $0 | $0 | $0 | **$0** |
|
|
231
|
-
| Producción media | $4.99 | $0 | $0 | **$4.99** |
|
|
232
|
-
| Producción alta | $29 | $60 | $10 | **$99** |
|
|
233
|
-
|
|
234
|
-
## Configuración Completa
|
|
235
|
-
|
|
236
|
-
```env
|
|
237
|
-
# .env.cloud
|
|
238
|
-
|
|
239
|
-
# Turso (SQLite)
|
|
240
|
-
TURSO_DATABASE_URL=libsql://cmp-memory-username.turso.io
|
|
241
|
-
TURSO_AUTH_TOKEN=eyJ...
|
|
242
|
-
|
|
243
|
-
# Upstash Vector
|
|
244
|
-
UPSTASH_VECTOR_REST_URL=https://abc-xyz.upstash.io
|
|
245
|
-
UPSTASH_VECTOR_REST_TOKEN=AXxx...
|
|
246
|
-
|
|
247
|
-
# Upstash Redis
|
|
248
|
-
UPSTASH_REDIS_REST_URL=https://def-uvw.upstash.io
|
|
249
|
-
UPSTASH_REDIS_REST_TOKEN=AYyy...
|
|
250
|
-
|
|
251
|
-
# Embeddings (para generar si no usas built-in de Upstash)
|
|
252
|
-
OPENAI_API_KEY=sk-...
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
## Package Dependencies
|
|
256
|
-
|
|
257
|
-
```json
|
|
258
|
-
{
|
|
259
|
-
"dependencies": {
|
|
260
|
-
"@libsql/client": "^0.5.0",
|
|
261
|
-
"@upstash/vector": "^1.0.0",
|
|
262
|
-
"@upstash/redis": "^1.28.0",
|
|
263
|
-
"drizzle-orm": "^0.30.0"
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
## Fallback Strategy
|
|
269
|
-
|
|
270
|
-
Si un servicio falla, tener fallback:
|
|
271
|
-
|
|
272
|
-
```typescript
|
|
273
|
-
async function getMemories(query: string) {
|
|
274
|
-
try {
|
|
275
|
-
// Primary: Upstash Vector (semantic search)
|
|
276
|
-
return await vectorIndex.query({ data: query, topK: 10 })
|
|
277
|
-
} catch (error) {
|
|
278
|
-
console.error('Vector search failed, falling back to SQL')
|
|
279
|
-
|
|
280
|
-
// Fallback: Turso (SQL LIKE search)
|
|
281
|
-
return await turso.query.devItems.findMany({
|
|
282
|
-
where: like(devItems.content, `%${query}%`),
|
|
283
|
-
limit: 10
|
|
284
|
-
})
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
```
|
|
1
|
+
# Infraestructura de Base de Datos Cloud
|
|
2
|
+
|
|
3
|
+
## Stack Recomendado (100% Gratuito)
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
7
|
+
│ ARQUITECTURA CLOUD │
|
|
8
|
+
├─────────────────────────────────────────────────────────────┤
|
|
9
|
+
│ │
|
|
10
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
11
|
+
│ │ Turso │ │ Upstash │ │ Upstash │ │
|
|
12
|
+
│ │ (SQLite) │ │ (Vector) │ │ (Redis) │ │
|
|
13
|
+
│ │ │ │ │ │ │ │
|
|
14
|
+
│ │ • Tareas │ │ • Embeddings│ │ • Cache │ │
|
|
15
|
+
│ │ • Mejoras │ │ • Semantic │ │ • Sessions │ │
|
|
16
|
+
│ │ • Sesiones │ │ Search │ │ • Config │ │
|
|
17
|
+
│ │ • Memorias │ │ │ │ │ │
|
|
18
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
19
|
+
│ │ │ │ │
|
|
20
|
+
│ └────────────────┼────────────────┘ │
|
|
21
|
+
│ │ │
|
|
22
|
+
│ ▼ │
|
|
23
|
+
│ ┌─────────────────────┐ │
|
|
24
|
+
│ │ MCP Server │ │
|
|
25
|
+
│ │ (Vercel Edge) │ │
|
|
26
|
+
│ └─────────────────────┘ │
|
|
27
|
+
│ │ │
|
|
28
|
+
│ ▼ │
|
|
29
|
+
│ ┌─────────────────────┐ │
|
|
30
|
+
│ │ Claude Code │ │
|
|
31
|
+
│ └─────────────────────┘ │
|
|
32
|
+
│ │
|
|
33
|
+
└─────────────────────────────────────────────────────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Turso (SQLite Edge)
|
|
37
|
+
|
|
38
|
+
**Propósito**: Base de datos principal para tareas, mejoras, memorias.
|
|
39
|
+
|
|
40
|
+
### Free Tier
|
|
41
|
+
- 500M rows read/mes
|
|
42
|
+
- 10M rows written/mes
|
|
43
|
+
- 5GB storage
|
|
44
|
+
- 100 databases
|
|
45
|
+
- Sin tarjeta de crédito
|
|
46
|
+
|
|
47
|
+
### Setup
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Instalar CLI
|
|
51
|
+
brew install tursodatabase/tap/turso
|
|
52
|
+
|
|
53
|
+
# Login
|
|
54
|
+
turso auth login
|
|
55
|
+
|
|
56
|
+
# Crear database
|
|
57
|
+
turso db create cmp-memory
|
|
58
|
+
|
|
59
|
+
# Obtener URL
|
|
60
|
+
turso db show cmp-memory --url
|
|
61
|
+
# → libsql://cmp-memory-username.turso.io
|
|
62
|
+
|
|
63
|
+
# Crear token
|
|
64
|
+
turso db tokens create cmp-memory
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Configuración
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// src/db/turso-client.ts
|
|
71
|
+
import { createClient } from '@libsql/client'
|
|
72
|
+
import { drizzle } from 'drizzle-orm/libsql'
|
|
73
|
+
|
|
74
|
+
export function createTursoDB() {
|
|
75
|
+
const client = createClient({
|
|
76
|
+
url: process.env.TURSO_DATABASE_URL!,
|
|
77
|
+
authToken: process.env.TURSO_AUTH_TOKEN!
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
return drizzle(client)
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Variables de Entorno
|
|
85
|
+
|
|
86
|
+
```env
|
|
87
|
+
TURSO_DATABASE_URL=libsql://cmp-memory-username.turso.io
|
|
88
|
+
TURSO_AUTH_TOKEN=eyJ...
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Upstash Vector
|
|
92
|
+
|
|
93
|
+
**Propósito**: Búsqueda semántica de memorias y contexto.
|
|
94
|
+
|
|
95
|
+
### Free Tier
|
|
96
|
+
- 200M vectors
|
|
97
|
+
- 1GB data/metadata
|
|
98
|
+
- 10K queries/día
|
|
99
|
+
- Built-in embeddings
|
|
100
|
+
|
|
101
|
+
### Setup
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Crear en dashboard: https://console.upstash.com/vector
|
|
105
|
+
# Obtener UPSTASH_VECTOR_REST_URL y UPSTASH_VECTOR_REST_TOKEN
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Configuración
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// src/db/vector-client.ts
|
|
112
|
+
import { Index } from '@upstash/vector'
|
|
113
|
+
|
|
114
|
+
export const vectorIndex = new Index({
|
|
115
|
+
url: process.env.UPSTASH_VECTOR_REST_URL!,
|
|
116
|
+
token: process.env.UPSTASH_VECTOR_REST_TOKEN!
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
// Insertar con embedding automático
|
|
120
|
+
await vectorIndex.upsert({
|
|
121
|
+
id: 'mem_123',
|
|
122
|
+
data: 'Este es el contenido de la memoria...',
|
|
123
|
+
metadata: {
|
|
124
|
+
type: 'memory',
|
|
125
|
+
domain: 'video-studio',
|
|
126
|
+
createdAt: new Date().toISOString()
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// Buscar por similitud
|
|
131
|
+
const results = await vectorIndex.query({
|
|
132
|
+
data: 'buscar memorias sobre video',
|
|
133
|
+
topK: 5,
|
|
134
|
+
includeMetadata: true
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Variables de Entorno
|
|
139
|
+
|
|
140
|
+
```env
|
|
141
|
+
UPSTASH_VECTOR_REST_URL=https://abc-xyz.upstash.io
|
|
142
|
+
UPSTASH_VECTOR_REST_TOKEN=AXxx...
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Upstash Redis
|
|
146
|
+
|
|
147
|
+
**Propósito**: Cache de configuración y sesiones activas.
|
|
148
|
+
|
|
149
|
+
### Free Tier
|
|
150
|
+
- 10K commands/día
|
|
151
|
+
- 256MB storage
|
|
152
|
+
- Global replication
|
|
153
|
+
|
|
154
|
+
### Setup
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Crear en dashboard: https://console.upstash.com/redis
|
|
158
|
+
# Obtener UPSTASH_REDIS_REST_URL y UPSTASH_REDIS_REST_TOKEN
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Configuración
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// src/db/redis-client.ts
|
|
165
|
+
import { Redis } from '@upstash/redis'
|
|
166
|
+
|
|
167
|
+
export const redis = new Redis({
|
|
168
|
+
url: process.env.UPSTASH_REDIS_REST_URL!,
|
|
169
|
+
token: process.env.UPSTASH_REDIS_REST_TOKEN!
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
// Cache de config (TTL 1 hora)
|
|
173
|
+
await redis.set('config:SWARMSCALE', config, { ex: 3600 })
|
|
174
|
+
|
|
175
|
+
// Leer config
|
|
176
|
+
const cached = await redis.get('config:SWARMSCALE')
|
|
177
|
+
|
|
178
|
+
// Sesiones activas
|
|
179
|
+
await redis.hset('sessions:active', {
|
|
180
|
+
[sessionId]: JSON.stringify(sessionData)
|
|
181
|
+
})
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Variables de Entorno
|
|
185
|
+
|
|
186
|
+
```env
|
|
187
|
+
UPSTASH_REDIS_REST_URL=https://def-uvw.upstash.io
|
|
188
|
+
UPSTASH_REDIS_REST_TOKEN=AYyy...
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Migración desde PlanetScale/Railway
|
|
192
|
+
|
|
193
|
+
### Estrategia
|
|
194
|
+
|
|
195
|
+
1. **Fase 1**: Dual-write (escribir a ambos)
|
|
196
|
+
2. **Fase 2**: Read from Turso, write to both
|
|
197
|
+
3. **Fase 3**: Full migration, keep PlanetScale as backup
|
|
198
|
+
|
|
199
|
+
### Script de Migración
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// scripts/migrate-to-turso.ts
|
|
203
|
+
import { db as planetscale } from './db/planetscale'
|
|
204
|
+
import { db as turso } from './db/turso'
|
|
205
|
+
|
|
206
|
+
async function migrate() {
|
|
207
|
+
console.log('Fetching memories from PlanetScale...')
|
|
208
|
+
|
|
209
|
+
const memories = await planetscale.query.devItems.findMany({
|
|
210
|
+
where: eq(devItems.system, 'SWARMSCALE')
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
console.log(`Found ${memories.length} memories`)
|
|
214
|
+
|
|
215
|
+
// Batch insert to Turso
|
|
216
|
+
for (const batch of chunk(memories, 100)) {
|
|
217
|
+
await turso.insert(devItems).values(batch)
|
|
218
|
+
console.log(`Migrated ${batch.length} items`)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
console.log('Migration complete!')
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Costos Estimados
|
|
226
|
+
|
|
227
|
+
| Uso | Turso | Vector | Redis | Total |
|
|
228
|
+
|-----|-------|--------|-------|-------|
|
|
229
|
+
| Desarrollo | $0 | $0 | $0 | **$0** |
|
|
230
|
+
| Producción pequeña | $0 | $0 | $0 | **$0** |
|
|
231
|
+
| Producción media | $4.99 | $0 | $0 | **$4.99** |
|
|
232
|
+
| Producción alta | $29 | $60 | $10 | **$99** |
|
|
233
|
+
|
|
234
|
+
## Configuración Completa
|
|
235
|
+
|
|
236
|
+
```env
|
|
237
|
+
# .env.cloud
|
|
238
|
+
|
|
239
|
+
# Turso (SQLite)
|
|
240
|
+
TURSO_DATABASE_URL=libsql://cmp-memory-username.turso.io
|
|
241
|
+
TURSO_AUTH_TOKEN=eyJ...
|
|
242
|
+
|
|
243
|
+
# Upstash Vector
|
|
244
|
+
UPSTASH_VECTOR_REST_URL=https://abc-xyz.upstash.io
|
|
245
|
+
UPSTASH_VECTOR_REST_TOKEN=AXxx...
|
|
246
|
+
|
|
247
|
+
# Upstash Redis
|
|
248
|
+
UPSTASH_REDIS_REST_URL=https://def-uvw.upstash.io
|
|
249
|
+
UPSTASH_REDIS_REST_TOKEN=AYyy...
|
|
250
|
+
|
|
251
|
+
# Embeddings (para generar si no usas built-in de Upstash)
|
|
252
|
+
OPENAI_API_KEY=sk-...
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Package Dependencies
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"dependencies": {
|
|
260
|
+
"@libsql/client": "^0.5.0",
|
|
261
|
+
"@upstash/vector": "^1.0.0",
|
|
262
|
+
"@upstash/redis": "^1.28.0",
|
|
263
|
+
"drizzle-orm": "^0.30.0"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Fallback Strategy
|
|
269
|
+
|
|
270
|
+
Si un servicio falla, tener fallback:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
async function getMemories(query: string) {
|
|
274
|
+
try {
|
|
275
|
+
// Primary: Upstash Vector (semantic search)
|
|
276
|
+
return await vectorIndex.query({ data: query, topK: 10 })
|
|
277
|
+
} catch (error) {
|
|
278
|
+
console.error('Vector search failed, falling back to SQL')
|
|
279
|
+
|
|
280
|
+
// Fallback: Turso (SQL LIKE search)
|
|
281
|
+
return await turso.query.devItems.findMany({
|
|
282
|
+
where: like(devItems.content, `%${query}%`),
|
|
283
|
+
limit: 10
|
|
284
|
+
})
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|