pokt-cli 1.0.7 → 1.0.9
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 +39 -3
- package/dist/bin/pokt.js +39 -8
- package/dist/chat/client.js +26 -6
- package/dist/chat/loop.js +523 -66
- package/dist/chat/mcp-from-text.d.ts +23 -0
- package/dist/chat/mcp-from-text.js +364 -0
- package/dist/chat/sessions.d.ts +18 -0
- package/dist/chat/sessions.js +120 -0
- package/dist/chat/slim-tools.d.ts +6 -0
- package/dist/chat/slim-tools.js +65 -0
- package/dist/chat/tools.js +30 -1
- package/dist/commands/chat.js +13 -5
- package/dist/commands/config.js +25 -3
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +82 -0
- package/dist/commands/mcp.d.ts +2 -0
- package/dist/commands/mcp.js +103 -37
- package/dist/commands/models.js +96 -7
- package/dist/commands/provider.js +20 -6
- package/dist/config.d.ts +29 -1
- package/dist/config.js +60 -4
- package/dist/mcp/client.d.ts +12 -7
- package/dist/mcp/client.js +254 -46
- package/dist/mcp/oauth-provider.d.ts +34 -0
- package/dist/mcp/oauth-provider.js +159 -0
- package/dist/mcp/project-mcp.d.ts +38 -0
- package/dist/mcp/project-mcp.js +208 -0
- package/dist/ui.d.ts +6 -1
- package/dist/ui.js +114 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pokt CLI
|
|
2
2
|
|
|
3
|
-
CLI de **Vibe Coding** com IA: OpenRouter, Ollama (local e cloud), Gemini e provedor Pokt (controller).
|
|
3
|
+
CLI de **Vibe Coding** com IA: OpenAI, Grok (xAI), OpenRouter, Ollama (local e cloud), Gemini e provedor Pokt (controller).
|
|
4
4
|
|
|
5
5
|
## Requisitos
|
|
6
6
|
|
|
@@ -60,35 +60,71 @@ pokt --help
|
|
|
60
60
|
| `pokt models <action>` | Gerenciar modelos (listar, adicionar, trocar) |
|
|
61
61
|
| `pokt provider use <provider>` | Trocar provedor de API |
|
|
62
62
|
| `pokt mcp [action]` | Gerenciar servidores MCP (ferramentas externas) |
|
|
63
|
+
| `pokt doctor` | Diagnóstico (credenciais + conectividade) |
|
|
63
64
|
|
|
64
65
|
### Config (`config`)
|
|
65
66
|
|
|
66
67
|
- `pokt config show` — Mostra a configuração atual (tokens mascarados).
|
|
68
|
+
- `pokt config set-openai -v <key>` — API key OpenAI.
|
|
69
|
+
- `pokt config set-grok -v <key>` — API key Grok (xAI).
|
|
67
70
|
- `pokt config set-openrouter -v <token>` — Token OpenRouter.
|
|
68
71
|
- `pokt config set-ollama -v <url>` — URL base do Ollama local.
|
|
69
72
|
- `pokt config set-ollama-cloud -v <key>` — API key Ollama Cloud.
|
|
70
73
|
- `pokt config set-gemini -v <key>` — API key Google Gemini.
|
|
71
74
|
- `pokt config set-pokt-token -v <token>` — Token do controller Pokt.
|
|
72
75
|
- `pokt config clear-openrouter` — Remove o token OpenRouter.
|
|
76
|
+
- `pokt config clear-openai` — Remove a API key OpenAI.
|
|
77
|
+
- `pokt config clear-grok` — Remove a API key Grok (xAI).
|
|
73
78
|
|
|
74
79
|
### Modelos (`models`)
|
|
75
80
|
|
|
76
81
|
- `pokt models list` — Lista modelos registrados e o ativo.
|
|
82
|
+
- `pokt models fetch-openai` — Busca modelos disponíveis na OpenAI.
|
|
83
|
+
- `pokt models fetch-grok` — Busca modelos disponíveis no Grok (xAI).
|
|
77
84
|
- `pokt models fetch-openrouter` — Busca modelos disponíveis no OpenRouter.
|
|
78
85
|
- `pokt models fetch-ollama` — Busca modelos do Ollama local.
|
|
79
86
|
- `pokt models fetch-ollama-cloud` — Busca modelos do Ollama Cloud.
|
|
80
|
-
- `pokt models add-openrouter`, `add-ollama`, `add-ollama-cloud` — Adiciona modelo (use `-i <id>`).
|
|
87
|
+
- `pokt models add-openai`, `add-grok`, `add-openrouter`, `add-ollama`, `add-ollama-cloud` — Adiciona modelo (use `-i <id>`).
|
|
81
88
|
- `pokt models use -i <id> -p <provider>` — Define o modelo ativo.
|
|
82
89
|
|
|
90
|
+
### Variáveis de ambiente (opcional)
|
|
91
|
+
|
|
92
|
+
Se preferir não salvar chaves no computador (ou para CI), você pode usar env vars. O Pokt prioriza env var e depois cai no `pokt config`.
|
|
93
|
+
|
|
94
|
+
- `OPENAI_API_KEY`
|
|
95
|
+
- `XAI_API_KEY` (ou `GROK_API_KEY`)
|
|
96
|
+
- `OPENROUTER_API_KEY` (ou `OPENROUTER_TOKEN`)
|
|
97
|
+
- `GEMINI_API_KEY` (ou `GOOGLE_API_KEY`)
|
|
98
|
+
- `OLLAMA_BASE_URL`
|
|
99
|
+
- `OLLAMA_CLOUD_API_KEY`
|
|
100
|
+
- `POKT_TOKEN`
|
|
101
|
+
|
|
83
102
|
### Provedores (`provider`)
|
|
84
103
|
|
|
85
|
-
Provedores suportados: `controller` (Pokt), `openrouter`, `gemini`, `ollama`, `ollama-cloud`.
|
|
104
|
+
Provedores suportados: `controller` (Pokt), `openai`, `grok`, `openrouter`, `gemini`, `ollama`, `ollama-cloud`.
|
|
86
105
|
|
|
87
106
|
```bash
|
|
107
|
+
pokt provider use openai
|
|
108
|
+
pokt provider use grok
|
|
88
109
|
pokt provider use openrouter
|
|
89
110
|
pokt provider use ollama
|
|
90
111
|
```
|
|
91
112
|
|
|
113
|
+
### MCP por projeto (`pokt_cli/mcp.json`)
|
|
114
|
+
|
|
115
|
+
Na **raiz do seu repositório** (subindo pastas a partir do diretório atual), o Pokt procura uma pasta chamada **`pokt_cli`**, **`Pokt_CLI`**, **`Pot_cli`**, etc. (aceita essas variações, comparação sem diferenciar maiúsculas).
|
|
116
|
+
|
|
117
|
+
Dentro dela, o arquivo **`mcp.json`** define servidores MCP. O Pokt aceita a chave **`mcpServers`** (Cursor/Claude) ou **`servers`** (ex.: Neon e outros). Opcionalmente `mcp.servers` / `mcp.mcpServers`. O Pokt **mescla** isso com servidores **globais** (`pokt mcp add`); se o **mesmo nome** existir nos dois, vale o do **projeto**.
|
|
118
|
+
|
|
119
|
+
- `pokt mcp init` — cria `./pokt_cli/mcp.json` com exemplo (no diretório atual).
|
|
120
|
+
- `pokt mcp list` — mostra origem `[projeto]` / `[global]`.
|
|
121
|
+
- `pokt mcp test` — testa stdio e HTTP (Streamable HTTP ou `transport: "sse"`).
|
|
122
|
+
- `pokt mcp link -n <nome>` — para entradas HTTP com `"oauth": true`: abre o navegador, autoriza e grava tokens em `pokt_cli/.mcp-oauth/` (adicione `.mcp-oauth` ao `.gitignore` se não quiser versionar).
|
|
123
|
+
|
|
124
|
+
Em strings do JSON você pode usar **`${NOME_DA_VARIÁVEL}`** para ler variáveis de ambiente (ex.: tokens em `headers`).
|
|
125
|
+
|
|
126
|
+
No **chat**, as tools MCP aparecem com prefixo `mcp_`; a IA também pode usar `run_command` e `write_file` para scripts (Python, etc.) quando fizer sentido.
|
|
127
|
+
|
|
92
128
|
## Desenvolvimento
|
|
93
129
|
|
|
94
130
|
```bash
|
package/dist/bin/pokt.js
CHANGED
|
@@ -9,10 +9,13 @@ import { mcpCommand } from '../commands/mcp.js';
|
|
|
9
9
|
import { updateCommand } from '../commands/update.js';
|
|
10
10
|
import { uninstallCommand } from '../commands/uninstall.js';
|
|
11
11
|
import { proCommand, runProFlow } from '../commands/pro.js';
|
|
12
|
+
import { doctorCommand } from '../commands/doctor.js';
|
|
12
13
|
import prompts from 'prompts';
|
|
13
14
|
import chalk from 'chalk';
|
|
14
15
|
import { ui } from '../ui.js';
|
|
15
16
|
const argv = hideBin(process.argv);
|
|
17
|
+
/** Banner typewriter só na 1ª vez do menu nesta execução; ao voltar de submenus, banner instantâneo. Novo `pokt` = animação de novo. */
|
|
18
|
+
let mainMenuBannerAnimatedThisProcess = false;
|
|
16
19
|
if (argv.length === 0) {
|
|
17
20
|
showMenu();
|
|
18
21
|
}
|
|
@@ -25,6 +28,7 @@ else {
|
|
|
25
28
|
.command(chatCommand)
|
|
26
29
|
.command(providerCommand)
|
|
27
30
|
.command(mcpCommand)
|
|
31
|
+
.command(doctorCommand)
|
|
28
32
|
.command(updateCommand)
|
|
29
33
|
.command(uninstallCommand)
|
|
30
34
|
.command(proCommand)
|
|
@@ -37,7 +41,10 @@ async function showMenu() {
|
|
|
37
41
|
const active = getEffectiveActiveModel();
|
|
38
42
|
const providerLabel = active ? (PROVIDER_LABELS[active.provider] ?? active.provider) : 'No provider';
|
|
39
43
|
console.log('');
|
|
40
|
-
|
|
44
|
+
const animateBanner = !mainMenuBannerAnimatedThisProcess;
|
|
45
|
+
if (animateBanner)
|
|
46
|
+
mainMenuBannerAnimatedThisProcess = true;
|
|
47
|
+
await ui.printBanner({ animate: animateBanner });
|
|
41
48
|
console.log(ui.statusLine(providerLabel));
|
|
42
49
|
console.log('');
|
|
43
50
|
console.log(ui.separator());
|
|
@@ -52,6 +59,7 @@ async function showMenu() {
|
|
|
52
59
|
{ title: '➕ Add / sync models', value: 'add-models' },
|
|
53
60
|
{ title: '🏠 Switch API Provider (casa de API)', value: 'provider' },
|
|
54
61
|
{ title: '🔌 MCP Servers (tools externos)', value: 'mcp' },
|
|
62
|
+
{ title: '🩺 Doctor (diagnóstico)', value: 'doctor' },
|
|
55
63
|
{ title: '⚙️ Configure API Keys / Tokens', value: 'config' },
|
|
56
64
|
{ title: '⭐ Torne-se Pro (site — pagamento + chave)', value: 'pro' },
|
|
57
65
|
{ title: '🔄 Atualizar Pokt CLI', value: 'update' },
|
|
@@ -64,7 +72,8 @@ async function showMenu() {
|
|
|
64
72
|
}
|
|
65
73
|
if (response.action === 'chat') {
|
|
66
74
|
const { chatCommand } = await import('../commands/chat.js');
|
|
67
|
-
chatCommand.handler({ fromMenu: true });
|
|
75
|
+
await chatCommand.handler({ fromMenu: true });
|
|
76
|
+
return showMenu();
|
|
68
77
|
}
|
|
69
78
|
else if (response.action === 'models') {
|
|
70
79
|
await handleModelsMenu();
|
|
@@ -78,6 +87,11 @@ async function showMenu() {
|
|
|
78
87
|
else if (response.action === 'config') {
|
|
79
88
|
await handleConfigMenu();
|
|
80
89
|
}
|
|
90
|
+
else if (response.action === 'doctor') {
|
|
91
|
+
const { doctorCommand } = await import('../commands/doctor.js');
|
|
92
|
+
await doctorCommand.handler({});
|
|
93
|
+
return showMenu();
|
|
94
|
+
}
|
|
81
95
|
else if (response.action === 'pro') {
|
|
82
96
|
runProFlow();
|
|
83
97
|
return showMenu();
|
|
@@ -98,8 +112,9 @@ async function showMenu() {
|
|
|
98
112
|
name: 'mcpAction',
|
|
99
113
|
message: 'MCP:',
|
|
100
114
|
choices: [
|
|
101
|
-
{ title: '
|
|
102
|
-
{ title: '
|
|
115
|
+
{ title: '📄 Criar pokt_cli/mcp.json neste diretório (init)', value: 'init' },
|
|
116
|
+
{ title: '🧪 Testar conexão (global + projeto)', value: 'test' },
|
|
117
|
+
{ title: '🔙 Voltar', value: 'back' }
|
|
103
118
|
]
|
|
104
119
|
});
|
|
105
120
|
if (mcpResp.mcpAction === 'back')
|
|
@@ -179,9 +194,13 @@ async function handleAddModelsMenu() {
|
|
|
179
194
|
name: 'action',
|
|
180
195
|
message: 'Add or sync models from which provider?',
|
|
181
196
|
choices: [
|
|
197
|
+
{ title: 'OpenAI — sync all from API', value: 'fetch-openai' },
|
|
198
|
+
{ title: 'Grok (xAI) — sync all from API', value: 'fetch-grok' },
|
|
182
199
|
{ title: 'OpenRouter — sync all from API', value: 'fetch-openrouter' },
|
|
183
200
|
{ title: 'Ollama (local) — sync from your Ollama (list models)', value: 'fetch-ollama' },
|
|
184
201
|
{ title: 'Ollama Cloud — sync from API', value: 'fetch-ollama-cloud' },
|
|
202
|
+
{ title: 'OpenAI — add model by ID', value: 'add-openai' },
|
|
203
|
+
{ title: 'Grok (xAI) — add model by ID', value: 'add-grok' },
|
|
185
204
|
{ title: 'OpenRouter — add model by ID', value: 'add-openrouter' },
|
|
186
205
|
{ title: 'Ollama (local) — add model by ID', value: 'add-ollama' },
|
|
187
206
|
{ title: 'Ollama Cloud — add model by ID', value: 'add-ollama-cloud' },
|
|
@@ -190,14 +209,18 @@ async function handleAddModelsMenu() {
|
|
|
190
209
|
});
|
|
191
210
|
if (response.action === 'back')
|
|
192
211
|
return showMenu();
|
|
193
|
-
const addActions = ['add-openrouter', 'add-ollama', 'add-ollama-cloud'];
|
|
212
|
+
const addActions = ['add-openai', 'add-grok', 'add-openrouter', 'add-ollama', 'add-ollama-cloud'];
|
|
194
213
|
if (addActions.includes(response.action)) {
|
|
195
214
|
const idPrompt = await prompts({
|
|
196
215
|
type: 'text',
|
|
197
216
|
name: 'id',
|
|
198
|
-
message: response.action === 'add-
|
|
199
|
-
? 'Model ID (ex:
|
|
200
|
-
:
|
|
217
|
+
message: response.action === 'add-openai'
|
|
218
|
+
? 'Model ID (ex: gpt-4o-mini):'
|
|
219
|
+
: response.action === 'add-grok'
|
|
220
|
+
? 'Model ID (ex: grok-2-latest):'
|
|
221
|
+
: response.action === 'add-openrouter'
|
|
222
|
+
? 'Model ID (ex: google/gemini-2.5-flash):'
|
|
223
|
+
: 'Model ID (ex: llama3):'
|
|
201
224
|
});
|
|
202
225
|
const id = typeof idPrompt.id === 'string' ? idPrompt.id.trim() : '';
|
|
203
226
|
if (id) {
|
|
@@ -222,6 +245,8 @@ async function handleConfigMenu() {
|
|
|
222
245
|
choices: [
|
|
223
246
|
{ title: 'View current config', value: 'show' },
|
|
224
247
|
{ title: 'Pokt Token (do painel — só isso para usar Controller)', value: 'set-pokt-token' },
|
|
248
|
+
{ title: 'OpenAI API Key', value: 'set-openai' },
|
|
249
|
+
{ title: 'Grok (xAI) API Key', value: 'set-grok' },
|
|
225
250
|
{ title: 'OpenRouter Token', value: 'set-openrouter' },
|
|
226
251
|
{ title: 'Gemini API Key', value: 'set-gemini' },
|
|
227
252
|
{ title: 'Ollama Base URL (local)', value: 'set-ollama' },
|
|
@@ -233,6 +258,8 @@ async function handleConfigMenu() {
|
|
|
233
258
|
return showMenu();
|
|
234
259
|
if (response.type === 'show') {
|
|
235
260
|
const { getControllerBaseUrl } = await import('../config.js');
|
|
261
|
+
const openai = config.get('openaiApiKey');
|
|
262
|
+
const grok = config.get('grokApiKey');
|
|
236
263
|
const openrouter = config.get('openrouterToken');
|
|
237
264
|
const gemini = config.get('geminiApiKey');
|
|
238
265
|
const ollama = config.get('ollamaBaseUrl');
|
|
@@ -241,6 +268,8 @@ async function handleConfigMenu() {
|
|
|
241
268
|
console.log(chalk.blue('\nCurrent config (tokens masked):'));
|
|
242
269
|
console.log(ui.dim(' Controller URL:'), getControllerBaseUrl(), ui.dim('(já configurado)'));
|
|
243
270
|
console.log(ui.dim(' Pokt Token:'), poktToken ? poktToken.slice(0, 10) + '****' : '(not set)');
|
|
271
|
+
console.log(ui.dim(' OpenAI API Key:'), openai ? openai.slice(0, 8) + '****' : '(not set)');
|
|
272
|
+
console.log(ui.dim(' Grok (xAI) API Key:'), grok ? grok.slice(0, 8) + '****' : '(not set)');
|
|
244
273
|
console.log(ui.dim(' OpenRouter Token:'), openrouter ? openrouter.slice(0, 8) + '****' : '(not set)');
|
|
245
274
|
console.log(ui.dim(' Gemini API Key:'), gemini ? gemini.slice(0, 8) + '****' : '(not set)');
|
|
246
275
|
console.log(ui.dim(' Ollama Base URL (local):'), ollama || '(not set)');
|
|
@@ -259,6 +288,8 @@ async function handleConfigMenu() {
|
|
|
259
288
|
if (valueResponse.val) {
|
|
260
289
|
const keyMap = {
|
|
261
290
|
'set-gemini': 'geminiApiKey',
|
|
291
|
+
'set-openai': 'openaiApiKey',
|
|
292
|
+
'set-grok': 'grokApiKey',
|
|
262
293
|
'set-openrouter': 'openrouterToken',
|
|
263
294
|
'set-ollama': 'ollamaBaseUrl',
|
|
264
295
|
'set-ollama-cloud': 'ollamaCloudApiKey',
|
package/dist/chat/client.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import {
|
|
2
|
+
import { getControllerBaseUrl, getOpenAIApiKey, getGrokApiKey, getOpenRouterToken, getGeminiApiKey, getOllamaCloudApiKey, getOllamaBaseUrl, getPoktToken, } from '../config.js';
|
|
3
3
|
export async function getClient(modelConfig) {
|
|
4
4
|
if (modelConfig.provider === 'controller') {
|
|
5
5
|
const baseUrl = getControllerBaseUrl();
|
|
6
|
-
const token =
|
|
6
|
+
const token = getPoktToken();
|
|
7
7
|
if (!token) {
|
|
8
8
|
throw new Error('Token Pokt não configurado. No painel gere um token e use: pokt config set-pokt-token -v <token>');
|
|
9
9
|
}
|
|
@@ -16,10 +16,30 @@ export async function getClient(modelConfig) {
|
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
+
else if (modelConfig.provider === 'openai') {
|
|
20
|
+
const apiKey = getOpenAIApiKey();
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
throw new Error('OpenAI API key não configurada. Use: pokt config set-openai -v <key>');
|
|
23
|
+
}
|
|
24
|
+
return new OpenAI({
|
|
25
|
+
baseURL: 'https://api.openai.com/v1',
|
|
26
|
+
apiKey,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else if (modelConfig.provider === 'grok') {
|
|
30
|
+
const apiKey = getGrokApiKey();
|
|
31
|
+
if (!apiKey) {
|
|
32
|
+
throw new Error('Grok (xAI) API key não configurada. Use: pokt config set-grok -v <key>');
|
|
33
|
+
}
|
|
34
|
+
return new OpenAI({
|
|
35
|
+
baseURL: 'https://api.x.ai/v1',
|
|
36
|
+
apiKey,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
19
39
|
else if (modelConfig.provider === 'openrouter') {
|
|
20
40
|
return new OpenAI({
|
|
21
41
|
baseURL: 'https://openrouter.ai/api/v1',
|
|
22
|
-
apiKey:
|
|
42
|
+
apiKey: getOpenRouterToken(),
|
|
23
43
|
defaultHeaders: {
|
|
24
44
|
'HTTP-Referer': 'https://github.com/pokt-cli',
|
|
25
45
|
'X-Title': 'Pokt CLI',
|
|
@@ -27,7 +47,7 @@ export async function getClient(modelConfig) {
|
|
|
27
47
|
});
|
|
28
48
|
}
|
|
29
49
|
else if (modelConfig.provider === 'gemini') {
|
|
30
|
-
const apiKey =
|
|
50
|
+
const apiKey = getGeminiApiKey();
|
|
31
51
|
if (!apiKey) {
|
|
32
52
|
throw new Error('Gemini API key not set. Use: pokt config set-gemini -v <key>');
|
|
33
53
|
}
|
|
@@ -37,7 +57,7 @@ export async function getClient(modelConfig) {
|
|
|
37
57
|
});
|
|
38
58
|
}
|
|
39
59
|
else if (modelConfig.provider === 'ollama-cloud') {
|
|
40
|
-
const apiKey =
|
|
60
|
+
const apiKey = getOllamaCloudApiKey();
|
|
41
61
|
if (!apiKey) {
|
|
42
62
|
throw new Error('Ollama Cloud API key não configurada. Crie uma em https://ollama.com/settings/keys e use: pokt config set-ollama-cloud -v <key>');
|
|
43
63
|
}
|
|
@@ -52,7 +72,7 @@ export async function getClient(modelConfig) {
|
|
|
52
72
|
else {
|
|
53
73
|
// Ollama (local) — não precisa de API key
|
|
54
74
|
return new OpenAI({
|
|
55
|
-
baseURL: `${
|
|
75
|
+
baseURL: `${getOllamaBaseUrl()}/v1`,
|
|
56
76
|
apiKey: 'ollama',
|
|
57
77
|
});
|
|
58
78
|
}
|