@korl3one/ccode 2.0.1 → 2.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 CHANGED
@@ -148,7 +148,7 @@ La IA compara los **criterios de aceptacion** de cada tarea con los **archivos r
148
148
 
149
149
  | Accion | Que hace |
150
150
  |--------|----------|
151
- | **Conectar IA** | Configura Claude o Ollama como proveedor |
151
+ | **Conectar IA** | Configura tu proveedor de IA (Claude, OpenAI, Gemini, DeepSeek, Groq, Ollama) |
152
152
  | **Siguiente tarea** | Muestra la tarea mas prioritaria y ofrece iniciarla |
153
153
  | **Verificar progreso** | La IA escanea el proyecto y actualiza estados |
154
154
  | **Completar tarea** | Marca como completada, registra en memoria |
@@ -158,6 +158,23 @@ La IA compara los **criterios de aceptacion** de cada tarea con los **archivos r
158
158
 
159
159
  ---
160
160
 
161
+ ## Proveedores de IA soportados
162
+
163
+ CCODE funciona con cualquiera de estos proveedores. Solo necesitas una API Key (excepto Ollama que corre local):
164
+
165
+ | Proveedor | Modelos | Nota |
166
+ |-----------|---------|------|
167
+ | **Claude** (Anthropic) | Sonnet 4, Haiku 3.5, Opus 4 | Recomendado |
168
+ | **OpenAI** (ChatGPT) | GPT-4o, GPT-4o mini, GPT-4.1, o3-mini | El mas popular |
169
+ | **Google Gemini** | 2.5 Flash, 2.5 Pro, 2.0 Flash | Gratis con limites |
170
+ | **DeepSeek** | Chat, Reasoner | Economico |
171
+ | **Groq** | Llama 3.3 70B, Llama 3.1 8B, Mixtral 8x7B | Ultra-rapido, tier gratis |
172
+ | **Ollama** | Cualquier modelo local | Sin internet, sin API key |
173
+
174
+ Al ejecutar "Conectar IA" desde el menu, CCODE te muestra los proveedores disponibles, te pide la API Key y te deja elegir el modelo. Prueba la conexion automaticamente antes de guardar.
175
+
176
+ ---
177
+
161
178
  ## POR QUE CCODE
162
179
 
163
180
  ### El problema
@@ -224,9 +241,13 @@ src/
224
241
  prompt-builder.ts → Meta-prompts adaptativos, generacion y verificacion
225
242
  ai/
226
243
  provider.ts → Interfaz comun IAIProvider (patron Adapter)
227
- claude.ts → Adapter para Claude (API de Anthropic)
244
+ claude.ts → Adapter para Claude (Anthropic)
245
+ openai.ts → Adapter para OpenAI (ChatGPT)
246
+ gemini.ts → Adapter para Google Gemini
247
+ deepseek.ts → Adapter para DeepSeek
248
+ groq.ts → Adapter para Groq (inferencia ultra-rapida)
228
249
  ollama.ts → Adapter para Ollama (modelos locales)
229
- manager.ts → Gestion de configuracion y conexion
250
+ manager.ts → Factory y gestion de configuracion
230
251
  utils/
231
252
  files.ts → Abstraccion del sistema de archivos
232
253
  ```
@@ -314,7 +335,7 @@ El proyecto incluye una guia de aprendizaje modular bajo la metodologia **QP2C**
314
335
  | [01 — CLI y Sesion](docs/learning/modules/01-cli-session.md) | Arquitectura CLI, loop persistente, menu contextual |
315
336
  | [02 — Contexto Persistente](docs/learning/modules/02-context-persistence.md) | ContextEngine, TaskEngine, estado en `.ccode/` |
316
337
  | [03 — Generacion de Contexto](docs/learning/modules/03-context-generation.md) | PromptBuilder, meta-prompts, adaptacion de complejidad |
317
- | [04 — Proveedores de IA](docs/learning/modules/04-ai-providers.md) | Patron Adapter, Claude, Ollama, AIManager |
338
+ | [04 — Proveedores de IA](docs/learning/modules/04-ai-providers.md) | Patron Adapter, 6 proveedores, AIManager |
318
339
  | [05 — Watcher y Verificacion](docs/learning/modules/05-watcher-verify.md) | FileWatcher, verificacion automatica de tareas |
319
340
 
320
341
  Documentos adicionales:
@@ -0,0 +1,11 @@
1
+ import { IAIProvider, IAIConfig } from './provider.js';
2
+ /**
3
+ * Adaptador para DeepSeek.
4
+ * Usa formato compatible con OpenAI.
5
+ */
6
+ export declare class DeepSeekAdapter implements IAIProvider {
7
+ private config;
8
+ constructor(config: IAIConfig);
9
+ getName(): string;
10
+ generate(prompt: string): Promise<string>;
11
+ }
@@ -0,0 +1,35 @@
1
+ import axios from 'axios';
2
+ /**
3
+ * Adaptador para DeepSeek.
4
+ * Usa formato compatible con OpenAI.
5
+ */
6
+ export class DeepSeekAdapter {
7
+ config;
8
+ constructor(config) {
9
+ this.config = {
10
+ apiKey: config.apiKey || '',
11
+ model: config.model || 'deepseek-chat',
12
+ baseUrl: config.baseUrl || 'https://api.deepseek.com/v1/chat/completions',
13
+ };
14
+ }
15
+ getName() {
16
+ return `DeepSeek (${this.config.model})`;
17
+ }
18
+ async generate(prompt) {
19
+ if (!this.config.apiKey) {
20
+ throw new Error('API Key de DeepSeek no configurada.');
21
+ }
22
+ const response = await axios.post(this.config.baseUrl, {
23
+ model: this.config.model,
24
+ max_tokens: 8096,
25
+ messages: [{ role: 'user', content: prompt }],
26
+ }, {
27
+ headers: {
28
+ 'Authorization': `Bearer ${this.config.apiKey}`,
29
+ 'Content-Type': 'application/json',
30
+ },
31
+ timeout: 120000,
32
+ });
33
+ return response.data.choices[0].message.content;
34
+ }
35
+ }
@@ -0,0 +1,10 @@
1
+ import { IAIProvider, IAIConfig } from './provider.js';
2
+ /**
3
+ * Adaptador para Google Gemini.
4
+ */
5
+ export declare class GeminiAdapter implements IAIProvider {
6
+ private config;
7
+ constructor(config: IAIConfig);
8
+ getName(): string;
9
+ generate(prompt: string): Promise<string>;
10
+ }
@@ -0,0 +1,31 @@
1
+ import axios from 'axios';
2
+ /**
3
+ * Adaptador para Google Gemini.
4
+ */
5
+ export class GeminiAdapter {
6
+ config;
7
+ constructor(config) {
8
+ this.config = {
9
+ apiKey: config.apiKey || '',
10
+ model: config.model || 'gemini-2.5-flash',
11
+ baseUrl: config.baseUrl || 'https://generativelanguage.googleapis.com/v1beta/models',
12
+ };
13
+ }
14
+ getName() {
15
+ return `Gemini (${this.config.model})`;
16
+ }
17
+ async generate(prompt) {
18
+ if (!this.config.apiKey) {
19
+ throw new Error('API Key de Google AI no configurada.');
20
+ }
21
+ const url = `${this.config.baseUrl}/${this.config.model}:generateContent?key=${this.config.apiKey}`;
22
+ const response = await axios.post(url, {
23
+ contents: [{ parts: [{ text: prompt }] }],
24
+ generationConfig: { maxOutputTokens: 8096 },
25
+ }, {
26
+ headers: { 'Content-Type': 'application/json' },
27
+ timeout: 120000,
28
+ });
29
+ return response.data.candidates[0].content.parts[0].text;
30
+ }
31
+ }
@@ -0,0 +1,11 @@
1
+ import { IAIProvider, IAIConfig } from './provider.js';
2
+ /**
3
+ * Adaptador para Groq (inferencia ultra-rápida).
4
+ * Usa formato compatible con OpenAI.
5
+ */
6
+ export declare class GroqAdapter implements IAIProvider {
7
+ private config;
8
+ constructor(config: IAIConfig);
9
+ getName(): string;
10
+ generate(prompt: string): Promise<string>;
11
+ }
@@ -0,0 +1,35 @@
1
+ import axios from 'axios';
2
+ /**
3
+ * Adaptador para Groq (inferencia ultra-rápida).
4
+ * Usa formato compatible con OpenAI.
5
+ */
6
+ export class GroqAdapter {
7
+ config;
8
+ constructor(config) {
9
+ this.config = {
10
+ apiKey: config.apiKey || '',
11
+ model: config.model || 'llama-3.3-70b-versatile',
12
+ baseUrl: config.baseUrl || 'https://api.groq.com/openai/v1/chat/completions',
13
+ };
14
+ }
15
+ getName() {
16
+ return `Groq (${this.config.model})`;
17
+ }
18
+ async generate(prompt) {
19
+ if (!this.config.apiKey) {
20
+ throw new Error('API Key de Groq no configurada.');
21
+ }
22
+ const response = await axios.post(this.config.baseUrl, {
23
+ model: this.config.model,
24
+ max_tokens: 8096,
25
+ messages: [{ role: 'user', content: prompt }],
26
+ }, {
27
+ headers: {
28
+ 'Authorization': `Bearer ${this.config.apiKey}`,
29
+ 'Content-Type': 'application/json',
30
+ },
31
+ timeout: 60000,
32
+ });
33
+ return response.data.choices[0].message.content;
34
+ }
35
+ }
@@ -1,6 +1,7 @@
1
1
  import { IAIProvider } from './provider.js';
2
+ export type ProviderName = 'claude' | 'openai' | 'gemini' | 'deepseek' | 'groq' | 'ollama';
2
3
  export interface ICCODEConfig {
3
- provider: 'claude' | 'ollama';
4
+ provider: ProviderName;
4
5
  apiKey?: string;
5
6
  model?: string;
6
7
  baseUrl?: string;
@@ -1,5 +1,9 @@
1
1
  import * as path from 'path';
2
2
  import { ClaudeAdapter } from './claude.js';
3
+ import { OpenAIAdapter } from './openai.js';
4
+ import { GeminiAdapter } from './gemini.js';
5
+ import { DeepSeekAdapter } from './deepseek.js';
6
+ import { GroqAdapter } from './groq.js';
3
7
  import { OllamaAdapter } from './ollama.js';
4
8
  import { FileUtils } from '../utils/files.js';
5
9
  /**
@@ -22,6 +26,14 @@ export class AIManager {
22
26
  switch (config.provider) {
23
27
  case 'claude':
24
28
  return new ClaudeAdapter({ apiKey: config.apiKey, model: config.model });
29
+ case 'openai':
30
+ return new OpenAIAdapter({ apiKey: config.apiKey, model: config.model });
31
+ case 'gemini':
32
+ return new GeminiAdapter({ apiKey: config.apiKey, model: config.model });
33
+ case 'deepseek':
34
+ return new DeepSeekAdapter({ apiKey: config.apiKey, model: config.model });
35
+ case 'groq':
36
+ return new GroqAdapter({ apiKey: config.apiKey, model: config.model });
25
37
  case 'ollama':
26
38
  return new OllamaAdapter({ model: config.model, baseUrl: config.baseUrl });
27
39
  default:
@@ -0,0 +1,10 @@
1
+ import { IAIProvider, IAIConfig } from './provider.js';
2
+ /**
3
+ * Adaptador para OpenAI (ChatGPT).
4
+ */
5
+ export declare class OpenAIAdapter implements IAIProvider {
6
+ private config;
7
+ constructor(config: IAIConfig);
8
+ getName(): string;
9
+ generate(prompt: string): Promise<string>;
10
+ }
@@ -0,0 +1,34 @@
1
+ import axios from 'axios';
2
+ /**
3
+ * Adaptador para OpenAI (ChatGPT).
4
+ */
5
+ export class OpenAIAdapter {
6
+ config;
7
+ constructor(config) {
8
+ this.config = {
9
+ apiKey: config.apiKey || '',
10
+ model: config.model || 'gpt-4o',
11
+ baseUrl: config.baseUrl || 'https://api.openai.com/v1/chat/completions',
12
+ };
13
+ }
14
+ getName() {
15
+ return `OpenAI (${this.config.model})`;
16
+ }
17
+ async generate(prompt) {
18
+ if (!this.config.apiKey) {
19
+ throw new Error('API Key de OpenAI no configurada.');
20
+ }
21
+ const response = await axios.post(this.config.baseUrl, {
22
+ model: this.config.model,
23
+ max_tokens: 8096,
24
+ messages: [{ role: 'user', content: prompt }],
25
+ }, {
26
+ headers: {
27
+ 'Authorization': `Bearer ${this.config.apiKey}`,
28
+ 'Content-Type': 'application/json',
29
+ },
30
+ timeout: 120000,
31
+ });
32
+ return response.data.choices[0].message.content;
33
+ }
34
+ }
package/dist/cli/index.js CHANGED
@@ -39,37 +39,73 @@ async function promptAIConfig() {
39
39
  message: 'Proveedor de IA:',
40
40
  choices: [
41
41
  { name: ' Claude (Anthropic) — Recomendado', value: 'claude' },
42
- { name: ' Ollama (Local)', value: 'ollama' },
42
+ { name: ' OpenAI (ChatGPT)', value: 'openai' },
43
+ { name: ' Google Gemini', value: 'gemini' },
44
+ { name: ' DeepSeek', value: 'deepseek' },
45
+ { name: ' Groq (ultra-rápido)', value: 'groq' },
46
+ { name: ' Ollama (local, sin API key)', value: 'ollama' },
43
47
  ],
44
48
  }]);
45
49
  const config = { provider };
46
- if (provider === 'claude') {
50
+ // Modelos por proveedor
51
+ const modelChoices = {
52
+ claude: [
53
+ { name: 'Claude Sonnet 4 (recomendado)', value: 'claude-sonnet-4-20250514' },
54
+ { name: 'Claude Haiku 3.5 (rápido)', value: 'claude-haiku-4-5-20251001' },
55
+ { name: 'Claude Opus 4 (máxima calidad)', value: 'claude-opus-4-20250514' },
56
+ ],
57
+ openai: [
58
+ { name: 'GPT-4o (recomendado)', value: 'gpt-4o' },
59
+ { name: 'GPT-4o mini (rápido)', value: 'gpt-4o-mini' },
60
+ { name: 'GPT-4.1 (último)', value: 'gpt-4.1' },
61
+ { name: 'o3-mini (razonamiento)', value: 'o3-mini' },
62
+ ],
63
+ gemini: [
64
+ { name: 'Gemini 2.5 Flash (recomendado)', value: 'gemini-2.5-flash' },
65
+ { name: 'Gemini 2.5 Pro (máxima calidad)', value: 'gemini-2.5-pro' },
66
+ { name: 'Gemini 2.0 Flash (rápido)', value: 'gemini-2.0-flash' },
67
+ ],
68
+ deepseek: [
69
+ { name: 'DeepSeek Chat (recomendado)', value: 'deepseek-chat' },
70
+ { name: 'DeepSeek Reasoner', value: 'deepseek-reasoner' },
71
+ ],
72
+ groq: [
73
+ { name: 'Llama 3.3 70B (recomendado)', value: 'llama-3.3-70b-versatile' },
74
+ { name: 'Llama 3.1 8B (rápido)', value: 'llama-3.1-8b-instant' },
75
+ { name: 'Mixtral 8x7B', value: 'mixtral-8x7b-32768' },
76
+ ],
77
+ };
78
+ // API Key (todos excepto Ollama)
79
+ if (provider !== 'ollama') {
80
+ const providerNames = {
81
+ claude: 'Anthropic', openai: 'OpenAI', gemini: 'Google AI',
82
+ deepseek: 'DeepSeek', groq: 'Groq',
83
+ };
47
84
  const { apiKey } = await inquirer.prompt([{
48
85
  type: 'password',
49
86
  name: 'apiKey',
50
- message: 'API Key de Anthropic:',
87
+ message: `API Key de ${providerNames[provider]}:`,
51
88
  mask: '*',
52
89
  validate: (v) => v.length > 10 || 'Ingresa una API Key válida',
53
90
  }]);
54
91
  config.apiKey = apiKey;
92
+ }
93
+ // Selección de modelo
94
+ if (provider === 'ollama') {
55
95
  const { model } = await inquirer.prompt([{
56
- type: 'select',
96
+ type: 'input',
57
97
  name: 'model',
58
- message: 'Modelo:',
59
- choices: [
60
- { name: 'Claude Sonnet 4 (recomendado)', value: 'claude-sonnet-4-20250514' },
61
- { name: 'Claude Haiku 3.5 (rápido)', value: 'claude-haiku-4-5-20251001' },
62
- { name: 'Claude Opus 4 (máxima calidad)', value: 'claude-opus-4-20250514' },
63
- ],
98
+ message: 'Modelo de Ollama:',
99
+ default: 'llama3',
64
100
  }]);
65
101
  config.model = model;
66
102
  }
67
103
  else {
68
104
  const { model } = await inquirer.prompt([{
69
- type: 'input',
105
+ type: 'select',
70
106
  name: 'model',
71
- message: 'Modelo de Ollama:',
72
- default: 'llama3',
107
+ message: 'Modelo:',
108
+ choices: modelChoices[provider],
73
109
  }]);
74
110
  config.model = model;
75
111
  }
@@ -353,7 +389,7 @@ async function handleConnect() {
353
389
  }
354
390
  else {
355
391
  spinner.fail(c.error('No se pudo conectar'));
356
- showError('Verifica credenciales o que Ollama esté corriendo.');
392
+ showError('Verifica tu API Key, conexión a internet, o que Ollama esté corriendo.');
357
393
  }
358
394
  }
359
395
  // ─── PLAN ───────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@korl3one/ccode",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "CLI de contexto persistente para desarrollo asistido por IA. Genera documentacion, arquitectura, reglas y tareas verificables.",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",