pokt-cli 1.0.2 → 1.0.4

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
@@ -1,96 +1,96 @@
1
- # Pokt CLI
2
-
3
- CLI de **Vibe Coding** com IA: OpenRouter, Ollama (local e cloud), Gemini e provedor Pokt (controller).
4
-
5
- ## Requisitos
6
-
7
- - **Node.js** >= 18.0.0
8
-
9
- ## Instalação
10
-
11
- ```bash
12
- # Instalação global
13
- npm install -g pokt-cli
14
-
15
- # Ou use sem instalar
16
- npx pokt-cli
17
- ```
18
-
19
- ## Uso
20
-
21
- Sem argumentos, o Pokt abre um menu interativo:
22
-
23
- ```bash
24
- pokt
25
- ```
26
-
27
- Ou use os comandos diretamente:
28
-
29
- ```bash
30
- pokt chat # Iniciar chat (Vibe Coding)
31
- pokt models list # Listar modelos
32
- pokt provider use openrouter
33
- pokt config show
34
- pokt --help
35
- ```
36
-
37
- ## Comandos
38
-
39
- | Comando | Descrição |
40
- |--------|-----------|
41
- | `pokt` | Menu interativo |
42
- | `pokt chat` | Iniciar sessão de chat com a IA |
43
- | `pokt config <action>` | Configurar chaves e tokens |
44
- | `pokt models <action>` | Gerenciar modelos (listar, adicionar, trocar) |
45
- | `pokt provider use <provider>` | Trocar provedor de API |
46
- | `pokt mcp [action]` | Gerenciar servidores MCP (ferramentas externas) |
47
-
48
- ### Config (`config`)
49
-
50
- - `pokt config show` — Mostra a configuração atual (tokens mascarados).
51
- - `pokt config set-openrouter -v <token>` — Token OpenRouter.
52
- - `pokt config set-ollama -v <url>` — URL base do Ollama local.
53
- - `pokt config set-ollama-cloud -v <key>` — API key Ollama Cloud.
54
- - `pokt config set-gemini -v <key>` — API key Google Gemini.
55
- - `pokt config set-pokt-token -v <token>` — Token do controller Pokt.
56
- - `pokt config clear-openrouter` — Remove o token OpenRouter.
57
-
58
- ### Modelos (`models`)
59
-
60
- - `pokt models list` — Lista modelos registrados e o ativo.
61
- - `pokt models fetch-openrouter` — Busca modelos disponíveis no OpenRouter.
62
- - `pokt models fetch-ollama` — Busca modelos do Ollama local.
63
- - `pokt models fetch-ollama-cloud` — Busca modelos do Ollama Cloud.
64
- - `pokt models add-openrouter`, `add-ollama`, `add-ollama-cloud` — Adiciona modelo (use `-i <id>`).
65
- - `pokt models use -i <id> -p <provider>` — Define o modelo ativo.
66
-
67
- ### Provedores (`provider`)
68
-
69
- Provedores suportados: `controller` (Pokt), `openrouter`, `gemini`, `ollama`, `ollama-cloud`.
70
-
71
- ```bash
72
- pokt provider use openrouter
73
- pokt provider use ollama
74
- ```
75
-
76
- ## Desenvolvimento
77
-
78
- ```bash
79
- # Clonar e instalar
80
- git clone https://github.com/PoktWeb/Pokt_CLI.git
81
- cd Pokt_CLI
82
- npm install
83
-
84
- # Desenvolvimento (executa o TypeScript direto)
85
- npm run dev
86
-
87
- # Build
88
- npm run build
89
-
90
- # Executar após o build
91
- npm start
92
- ```
93
-
94
- ## Licença
95
-
96
- ISC · **PoktWeb**
1
+ # Pokt CLI
2
+
3
+ CLI de **Vibe Coding** com IA: OpenRouter, Ollama (local e cloud), Gemini e provedor Pokt (controller).
4
+
5
+ ## Requisitos
6
+
7
+ - **Node.js** >= 18.0.0
8
+
9
+ ## Instalação
10
+
11
+ ```bash
12
+ # Instalação global
13
+ npm install -g pokt-cli
14
+
15
+ # Ou use sem instalar
16
+ npx pokt-cli
17
+ ```
18
+
19
+ ## Uso
20
+
21
+ Sem argumentos, o Pokt abre um menu interativo:
22
+
23
+ ```bash
24
+ pokt
25
+ ```
26
+
27
+ Ou use os comandos diretamente:
28
+
29
+ ```bash
30
+ pokt chat # Iniciar chat (Vibe Coding)
31
+ pokt models list # Listar modelos
32
+ pokt provider use openrouter
33
+ pokt config show
34
+ pokt --help
35
+ ```
36
+
37
+ ## Comandos
38
+
39
+ | Comando | Descrição |
40
+ |--------|-----------|
41
+ | `pokt` | Menu interativo |
42
+ | `pokt chat` | Iniciar sessão de chat com a IA |
43
+ | `pokt config <action>` | Configurar chaves e tokens |
44
+ | `pokt models <action>` | Gerenciar modelos (listar, adicionar, trocar) |
45
+ | `pokt provider use <provider>` | Trocar provedor de API |
46
+ | `pokt mcp [action]` | Gerenciar servidores MCP (ferramentas externas) |
47
+
48
+ ### Config (`config`)
49
+
50
+ - `pokt config show` — Mostra a configuração atual (tokens mascarados).
51
+ - `pokt config set-openrouter -v <token>` — Token OpenRouter.
52
+ - `pokt config set-ollama -v <url>` — URL base do Ollama local.
53
+ - `pokt config set-ollama-cloud -v <key>` — API key Ollama Cloud.
54
+ - `pokt config set-gemini -v <key>` — API key Google Gemini.
55
+ - `pokt config set-pokt-token -v <token>` — Token do controller Pokt.
56
+ - `pokt config clear-openrouter` — Remove o token OpenRouter.
57
+
58
+ ### Modelos (`models`)
59
+
60
+ - `pokt models list` — Lista modelos registrados e o ativo.
61
+ - `pokt models fetch-openrouter` — Busca modelos disponíveis no OpenRouter.
62
+ - `pokt models fetch-ollama` — Busca modelos do Ollama local.
63
+ - `pokt models fetch-ollama-cloud` — Busca modelos do Ollama Cloud.
64
+ - `pokt models add-openrouter`, `add-ollama`, `add-ollama-cloud` — Adiciona modelo (use `-i <id>`).
65
+ - `pokt models use -i <id> -p <provider>` — Define o modelo ativo.
66
+
67
+ ### Provedores (`provider`)
68
+
69
+ Provedores suportados: `controller` (Pokt), `openrouter`, `gemini`, `ollama`, `ollama-cloud`.
70
+
71
+ ```bash
72
+ pokt provider use openrouter
73
+ pokt provider use ollama
74
+ ```
75
+
76
+ ## Desenvolvimento
77
+
78
+ ```bash
79
+ # Clonar e instalar
80
+ git clone https://github.com/PoktWeb/Pokt_CLI.git
81
+ cd Pokt_CLI
82
+ npm install
83
+
84
+ # Desenvolvimento (executa o TypeScript direto)
85
+ npm run dev
86
+
87
+ # Build
88
+ npm run build
89
+
90
+ # Executar após o build
91
+ npm start
92
+ ```
93
+
94
+ ## Licença
95
+
96
+ ISC · **PoktWeb**
@@ -1 +1 @@
1
- export declare function loginWithGoogle(): Promise<void>;
1
+ export declare function loginWithGoogle(): Promise<void>;
@@ -1,49 +1,49 @@
1
- import { OAuth2Client } from 'google-auth-library';
2
- import http from 'http';
3
- import url from 'url';
4
- import open from 'open';
5
- import { config } from '../config.js';
6
- import chalk from 'chalk';
7
- import ora from 'ora';
8
- const REDIRECT_URI = 'http://localhost:3000/oauth2callback';
9
- export async function loginWithGoogle() {
10
- const clientId = config.get('googleClientId');
11
- const clientSecret = config.get('googleClientSecret');
12
- if (!clientId || !clientSecret) {
13
- console.log(chalk.red('\nError: Google OAuth Client ID or Secret not configured.'));
14
- console.log(chalk.yellow('To use Google Login, follow these steps:'));
15
- console.log(chalk.gray('1. Create a project at: https://console.cloud.google.com/'));
16
- console.log(chalk.gray('2. Enable the "Generative Language API"'));
17
- console.log(chalk.gray('3. Create OAuth 2.0 Client ID (Type: Web application)'));
18
- console.log(chalk.gray(`4. Add Authorized redirect URI: ${REDIRECT_URI}`));
19
- console.log(chalk.yellow('\nThen configure Pokt CLI:'));
20
- console.log(chalk.cyan(` pokt config set-google-client-id -v YOUR_CLIENT_ID`));
21
- console.log(chalk.cyan(` pokt config set-google-client-secret -v YOUR_CLIENT_SECRET`));
22
- return;
23
- }
24
- const spinner = ora('Starting Google Login...').start();
25
- const oAuth2Client = new OAuth2Client(clientId, clientSecret, REDIRECT_URI);
26
- const authorizeUrl = oAuth2Client.generateAuthUrl({
27
- access_type: 'offline',
28
- scope: ['https://www.googleapis.com/auth/generative-language'],
29
- });
30
- const server = http.createServer(async (req, res) => {
31
- try {
32
- if (req.url && req.url.includes('/oauth2callback') && req.url.includes('code=')) {
33
- const qs = new url.URL(req.url, 'http://localhost:3000').searchParams;
34
- const code = qs.get('code');
35
- res.end('Authentication successful! You can close this tab.');
36
- server.close();
37
- const { tokens } = await oAuth2Client.getToken(code);
38
- config.set('googleToken', tokens);
39
- console.log(chalk.green('\n✔ Google account connected successfully.'));
40
- }
41
- }
42
- catch (e) {
43
- console.error(chalk.red(`\nAuthentication failed: ${e.message}`));
44
- res.end('Authentication failed.');
45
- }
46
- }).listen(3000);
47
- spinner.succeed(chalk.blue('Opening browser for Google login...'));
48
- await open(authorizeUrl);
49
- }
1
+ import { OAuth2Client } from 'google-auth-library';
2
+ import http from 'http';
3
+ import url from 'url';
4
+ import open from 'open';
5
+ import { config } from '../config.js';
6
+ import chalk from 'chalk';
7
+ import ora from 'ora';
8
+ const REDIRECT_URI = 'http://localhost:3000/oauth2callback';
9
+ export async function loginWithGoogle() {
10
+ const clientId = config.get('googleClientId');
11
+ const clientSecret = config.get('googleClientSecret');
12
+ if (!clientId || !clientSecret) {
13
+ console.log(chalk.red('\nError: Google OAuth Client ID or Secret not configured.'));
14
+ console.log(chalk.yellow('To use Google Login, follow these steps:'));
15
+ console.log(chalk.gray('1. Create a project at: https://console.cloud.google.com/'));
16
+ console.log(chalk.gray('2. Enable the "Generative Language API"'));
17
+ console.log(chalk.gray('3. Create OAuth 2.0 Client ID (Type: Web application)'));
18
+ console.log(chalk.gray(`4. Add Authorized redirect URI: ${REDIRECT_URI}`));
19
+ console.log(chalk.yellow('\nThen configure Pokt CLI:'));
20
+ console.log(chalk.cyan(` pokt config set-google-client-id -v YOUR_CLIENT_ID`));
21
+ console.log(chalk.cyan(` pokt config set-google-client-secret -v YOUR_CLIENT_SECRET`));
22
+ return;
23
+ }
24
+ const spinner = ora('Starting Google Login...').start();
25
+ const oAuth2Client = new OAuth2Client(clientId, clientSecret, REDIRECT_URI);
26
+ const authorizeUrl = oAuth2Client.generateAuthUrl({
27
+ access_type: 'offline',
28
+ scope: ['https://www.googleapis.com/auth/generative-language'],
29
+ });
30
+ const server = http.createServer(async (req, res) => {
31
+ try {
32
+ if (req.url && req.url.includes('/oauth2callback') && req.url.includes('code=')) {
33
+ const qs = new url.URL(req.url, 'http://localhost:3000').searchParams;
34
+ const code = qs.get('code');
35
+ res.end('Authentication successful! You can close this tab.');
36
+ server.close();
37
+ const { tokens } = await oAuth2Client.getToken(code);
38
+ config.set('googleToken', tokens);
39
+ console.log(chalk.green('\n✔ Google account connected successfully.'));
40
+ }
41
+ }
42
+ catch (e) {
43
+ console.error(chalk.red(`\nAuthentication failed: ${e.message}`));
44
+ res.end('Authentication failed.');
45
+ }
46
+ }).listen(3000);
47
+ spinner.succeed(chalk.blue('Opening browser for Google login...'));
48
+ await open(authorizeUrl);
49
+ }
package/dist/chat/loop.js CHANGED
@@ -13,12 +13,17 @@ CORE CAPABILITIES:
13
13
  2. **Autonomous Coding**: You can create new files, rewrite existing ones, and run terminal commands.
14
14
  3. **Problem Solving**: You analyze errors and propose/apply fixes.
15
15
 
16
+ CRITICAL - FILE CREATION/EDITS (this API does NOT support tool calls):
17
+ - Do NOT reply with only "We will call read_file", "We will call write_file" or similar. Those tools will NOT run. The user will get no file.
18
+ - You MUST output the complete file content in a markdown code block so the CLI can create/edit the file. Format: mention the filename (e.g. hello.py or **hello.py**) then a newline then \`\`\`python then newline then the full file content then \`\`\`.
19
+ - For edits: first "read" the file by inferring its content from the user request and project context, then output the full updated file in a \`\`\`python (or correct language) block with the filename mentioned just above the block.
20
+ - Never end your response with only an intention to call a tool. Always include the actual code in a block.
21
+
16
22
  GUIDELINES:
17
23
  - You will receive the user request first, then the current project structure. Use the project structure to understand the context before creating or editing anything.
18
24
  - When asked to fix something, first **read** the relevant files to understand the context.
19
- - When creating a project, start by planning the structure, then use \`write_file\` to create files.
20
- - **DO NOT repeat the generated code in your chat response** if you have already used the \`write_file\` tool. Simply state that the file has been updated or created.
21
- - You have full access to the current terminal. You can run \`npm install\`, \`tsc\`, or any other command.
25
+ - When creating a project, start by planning the structure, then use \`write_file\` to create each file.
26
+ - You have full access to the current terminal. You can run \`run_command\` for \`npm install\`, \`tsc\`, or any other command.
22
27
  - Be extremely concise in your explanations.
23
28
  - The current working directory is: ${process.cwd()}
24
29
  `;
@@ -58,6 +63,8 @@ export async function startChatLoop(modelConfig) {
58
63
  ];
59
64
  while (true) {
60
65
  console.log('');
66
+ const cwd = process.cwd();
67
+ console.log(ui.dim(`Diretório atual: ${cwd}`));
61
68
  console.log(ui.shortcutsLine('shift+tab to accept edits', '? for shortcuts'));
62
69
  const response = await prompts({
63
70
  type: 'text',
@@ -87,6 +94,83 @@ export async function startChatLoop(modelConfig) {
87
94
  }
88
95
  const MAX_429_RETRIES = 3;
89
96
  const BASE_429_DELAY_MS = 5000;
97
+ /** Extensões que consideramos como arquivos de código para aplicar fallback */
98
+ const CODE_EXT = /\.(py|js|ts|tsx|jsx|html|css|json|md|txt|java|go|rs|c|cpp|rb|php)$/i;
99
+ /**
100
+ * Quando a API não retorna tool_calls, alguns backends só devolvem texto.
101
+ * Extrai blocos de código da resposta (```lang\n...\n```) e, se encontrar
102
+ * um nome de arquivo mencionado antes do bloco, aplica write_file.
103
+ */
104
+ /** Blocos de comando "como rodar" (bash/sh de 1–2 linhas) não viram arquivo para não poluir. */
105
+ function isRunCommandOnly(lang, code) {
106
+ const shellLike = /^(bash|sh|shell|zsh)$/i.test(lang);
107
+ const lines = code.split('\n').filter((l) => l.trim().length > 0);
108
+ return shellLike && lines.length <= 2;
109
+ }
110
+ /** Remove markdown/formatting do nome de arquivo (ex: **hello.py** → hello.py). */
111
+ function cleanFilename(candidate) {
112
+ return candidate.replace(/^[\s*`'"]+/g, '').replace(/[\s*`'")\]\s]+$/g, '').trim();
113
+ }
114
+ /**
115
+ * Aplica blocos de código da resposta e retorna conteúdo para exibição (sem repetir o código).
116
+ * - Detecta nome de arquivo na mensagem (ex: "updated **hello.py**") para editar o existente.
117
+ * - Blocos já aplicados são substituídos por "[Código aplicado ao arquivo: path]" na mensagem exibida.
118
+ */
119
+ /** Garante que o conteúdo da mensagem seja string (algumas APIs devolvem array). */
120
+ function messageContentToString(content) {
121
+ if (typeof content === 'string')
122
+ return content;
123
+ if (Array.isArray(content)) {
124
+ return content
125
+ .map((part) => (typeof part === 'object' && part != null && 'text' in part ? part.text : String(part)))
126
+ .join('');
127
+ }
128
+ return content != null ? String(content) : '';
129
+ }
130
+ async function applyCodeBlocksFromContent(content) {
131
+ const codeBlockRe = /```(\w*)\n([\s\S]*?)```/g;
132
+ const appliedBlocks = [];
133
+ let applied = false;
134
+ let m;
135
+ const matches = [];
136
+ while ((m = codeBlockRe.exec(content)) !== null) {
137
+ matches.push({
138
+ fullMatch: m[0],
139
+ index: m.index,
140
+ lang: m[1] || '',
141
+ code: m[2].replace(/\r\n/g, '\n').trimEnd(),
142
+ });
143
+ }
144
+ for (const { fullMatch, index, lang, code } of matches) {
145
+ if (isRunCommandOnly(lang, code))
146
+ continue;
147
+ const beforeBlock = content.substring(0, index);
148
+ // Nome de arquivo: aceita "**hello.py**", "hello.py" antes de espaço/newline/backtick, etc.
149
+ const fileMatch = beforeBlock.match(/(\S+\.(?:py|js|ts|tsx|jsx|html|css|json|md|txt|java|go|rs|c|cpp|rb|php))(?=\s|$|[:.)\]*`"])/gi);
150
+ const rawCandidate = fileMatch ? fileMatch[fileMatch.length - 1].trim() : null;
151
+ const candidate = rawCandidate ? cleanFilename(rawCandidate) : null;
152
+ const path = candidate && CODE_EXT.test(candidate) ? candidate : (lang === 'python' ? 'generated.py' : lang ? `generated.${lang}` : null);
153
+ if (path && code) {
154
+ try {
155
+ console.log(ui.warn(`\n[Fallback] Aplicando código da resposta ao arquivo: ${path}`));
156
+ await executeTool('write_file', JSON.stringify({ path, content: code }));
157
+ applied = true;
158
+ appliedBlocks.push({ start: index, end: index + fullMatch.length, path });
159
+ }
160
+ catch {
161
+ // ignora falha em um bloco
162
+ }
163
+ }
164
+ }
165
+ // Monta mensagem para exibição: blocos aplicados viram uma linha curta (evita repetir o código)
166
+ let displayContent = content;
167
+ for (let i = appliedBlocks.length - 1; i >= 0; i--) {
168
+ const { start, end, path } = appliedBlocks[i];
169
+ const placeholder = `\n${ui.dim('[Código aplicado ao arquivo: ' + path + ']')}\n`;
170
+ displayContent = displayContent.substring(0, start) + placeholder + displayContent.substring(end);
171
+ }
172
+ return { applied, displayContent };
173
+ }
90
174
  async function createCompletionWithRetry(client, modelId, messages, toolsList) {
91
175
  let lastError;
92
176
  for (let attempt = 0; attempt <= MAX_429_RETRIES; attempt++) {
@@ -117,10 +201,13 @@ async function processLLMResponse(client, modelId, messages, toolsList) {
117
201
  let completion = await createCompletionWithRetry(client, modelId, messages, toolsList);
118
202
  let message = completion.choices[0].message;
119
203
  spinner.stop();
204
+ let writeFileExecutedThisTurn = false;
120
205
  while (message.tool_calls && message.tool_calls.length > 0) {
121
206
  messages.push(message);
122
207
  for (const toolCall of message.tool_calls) {
123
208
  const name = toolCall.function.name;
209
+ if (name === 'write_file')
210
+ writeFileExecutedThisTurn = true;
124
211
  const args = toolCall.function.arguments ?? '{}';
125
212
  console.log(ui.warn(`\n[Executing Tool: ${name}]`));
126
213
  console.log(ui.dim(`Arguments: ${args}`));
@@ -141,10 +228,59 @@ async function processLLMResponse(client, modelId, messages, toolsList) {
141
228
  message = completion.choices[0].message;
142
229
  spinner.stop();
143
230
  }
144
- if (message.content) {
145
- console.log('\n' + ui.labelPokt());
146
- console.log(message.content);
147
- messages.push({ role: 'assistant', content: message.content });
231
+ const rawContent = message.content;
232
+ let contentStr = messageContentToString(rawContent);
233
+ let finalContent = rawContent ?? contentStr;
234
+ // Quando a API não executa tools, tentar aplicar blocos de código da resposta
235
+ if (!writeFileExecutedThisTurn) {
236
+ let result = await applyCodeBlocksFromContent(contentStr);
237
+ // Se a IA só disse "We will call read_file/write_file" e não há código, pedir o código em um follow-up
238
+ const looksLikeToolIntentOnly = /(We will call|We need to call|Let's call|I will call)\s+(read_file|write_file|run_command)/i.test(contentStr)
239
+ || (/call\s+(read_file|write_file)/i.test(contentStr) && contentStr.length < 400);
240
+ if (!result.applied && looksLikeToolIntentOnly) {
241
+ messages.push({ role: 'assistant', content: rawContent ?? contentStr });
242
+ const followUpSystem = `This API does not support tool calls. You must NOT reply with "We will call X". Output the complete file content in a markdown code block so the user's CLI can create/edit the file. Format: mention the filename (e.g. hello.py) then newline then \`\`\`python then newline then the FULL file content then \`\`\`. Do that now for the user's last request.`;
243
+ messages.push({ role: 'system', content: followUpSystem });
244
+ spinner.start('Getting code...');
245
+ const followUp = await createCompletionWithRetry(client, modelId, messages, toolsList);
246
+ spinner.stop();
247
+ const followUpMsg = followUp.choices[0].message;
248
+ const followUpStr = messageContentToString(followUpMsg.content);
249
+ if (followUpStr.trim() !== '') {
250
+ result = await applyCodeBlocksFromContent(followUpStr);
251
+ contentStr = followUpStr;
252
+ finalContent = followUpMsg.content ?? followUpStr;
253
+ messages.push({ role: 'assistant', content: finalContent });
254
+ }
255
+ else {
256
+ messages.push({ role: 'assistant', content: '' });
257
+ }
258
+ }
259
+ if (contentStr.trim() !== '') {
260
+ let contentToShow = result.applied ? result.displayContent : contentStr;
261
+ console.log('\n' + ui.labelPokt());
262
+ console.log(contentToShow);
263
+ if (!messages.some((m) => m.role === 'assistant' && m.content === finalContent)) {
264
+ messages.push({ role: 'assistant', content: finalContent });
265
+ }
266
+ }
267
+ else {
268
+ console.log('\n' + ui.labelPokt());
269
+ console.log(ui.dim('(A IA não retornou código utilizável. Tente reformular o pedido.)'));
270
+ messages.push({ role: 'assistant', content: '' });
271
+ }
272
+ }
273
+ else {
274
+ if (contentStr.trim() !== '') {
275
+ console.log('\n' + ui.labelPokt());
276
+ console.log(contentStr);
277
+ messages.push({ role: 'assistant', content: finalContent });
278
+ }
279
+ else {
280
+ console.log('\n' + ui.labelPokt());
281
+ console.log(ui.dim('(Sem resposta de texto.)'));
282
+ messages.push({ role: 'assistant', content: '' });
283
+ }
148
284
  }
149
285
  }
150
286
  catch (error) {
@@ -1,2 +1,2 @@
1
- import { CommandModule } from 'yargs';
2
- export declare const authCommand: CommandModule;
1
+ import { CommandModule } from 'yargs';
2
+ export declare const authCommand: CommandModule;
@@ -1,16 +1,16 @@
1
- import { loginWithGoogle } from '../auth/google.js';
2
- export const authCommand = {
3
- command: 'auth <action>',
4
- describe: 'Manage authentication',
5
- builder: (yargs) => yargs
6
- .positional('action', {
7
- describe: 'Action to perform',
8
- type: 'string',
9
- choices: ['login-google']
10
- }),
11
- handler: async (argv) => {
12
- if (argv.action === 'login-google') {
13
- await loginWithGoogle();
14
- }
15
- }
16
- };
1
+ import { loginWithGoogle } from '../auth/google.js';
2
+ export const authCommand = {
3
+ command: 'auth <action>',
4
+ describe: 'Manage authentication',
5
+ builder: (yargs) => yargs
6
+ .positional('action', {
7
+ describe: 'Action to perform',
8
+ type: 'string',
9
+ choices: ['login-google']
10
+ }),
11
+ handler: async (argv) => {
12
+ if (argv.action === 'login-google') {
13
+ await loginWithGoogle();
14
+ }
15
+ }
16
+ };
@@ -34,7 +34,7 @@ export const chatCommand = {
34
34
  console.log('');
35
35
  }
36
36
  console.log(ui.dim('Type "exit" or /quit to end the session.'));
37
- console.log(ui.statusBar({ model: `/model ${activeModel.provider} (${activeModel.id})` }));
37
+ console.log(ui.statusBar({ cwd: process.cwd(), model: `/model ${activeModel.provider} (${activeModel.id})` }));
38
38
  console.log('');
39
39
  await startChatLoop(activeModel);
40
40
  }
package/dist/ui.js CHANGED
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  import { execSync } from 'child_process';
5
- const VERSION = '1.0.1';
5
+ const VERSION = '1.0.4';
6
6
  /** Logo em estilo chevron com gradiente (azul → rosa → roxo) */
7
7
  function logo() {
8
8
  const c = (s, color) => color(s);
package/package.json CHANGED
@@ -1,61 +1,61 @@
1
- {
2
- "name": "pokt-cli",
3
- "version": "1.0.2",
4
- "description": "Vibe Coding AI CLI for OpenRouter and Ollama",
5
- "main": "./dist/bin/pokt.js",
6
- "type": "module",
7
- "bin": {
8
- "pokt": "dist/bin/pokt.js"
9
- },
10
- "scripts": {
11
- "build": "tsc",
12
- "start": "node ./dist/bin/pokt.js",
13
- "dev": "tsx ./src/bin/pokt.ts",
14
- "prepublishOnly": "npm run build"
15
- },
16
- "files": [
17
- "dist",
18
- "package.json",
19
- "README.md"
20
- ],
21
- "keywords": [
22
- "ai",
23
- "cli",
24
- "coding",
25
- "agent",
26
- "openrouter",
27
- "ollama"
28
- ],
29
- "author": "PoktWeb",
30
- "license": "ISC",
31
- "engines": {
32
- "node": ">=18.0.0"
33
- },
34
- "repository": {
35
- "type": "git",
36
- "url": "git+https://github.com/PoktWeb/Pokt_CLI.git"
37
- },
38
- "homepage": "https://github.com/PoktWeb/Pokt_CLI#readme",
39
- "bugs": {
40
- "url": "https://github.com/PoktWeb/Pokt_CLI/issues"
41
- },
42
- "dependencies": {
43
- "@modelcontextprotocol/sdk": "^1.27.1",
44
- "chalk": "^5.3.0",
45
- "conf": "^12.0.0",
46
- "diff": "^8.0.3",
47
- "openai": "^4.28.4",
48
- "ora": "^8.0.1",
49
- "prompts": "^2.4.2",
50
- "yargs": "^17.7.2",
51
- "zod": "^3.23.8"
52
- },
53
- "devDependencies": {
54
- "@types/diff": "^7.0.2",
55
- "@types/node": "^20.11.24",
56
- "@types/prompts": "^2.4.9",
57
- "@types/yargs": "^17.0.32",
58
- "tsx": "^4.7.1",
59
- "typescript": "^5.3.3"
60
- }
61
- }
1
+ {
2
+ "name": "pokt-cli",
3
+ "version": "1.0.4",
4
+ "description": "Vibe Coding AI CLI for OpenRouter and Ollama",
5
+ "main": "./dist/bin/pokt.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "pokt": "dist/bin/pokt.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node ./dist/bin/pokt.js",
13
+ "dev": "tsx ./src/bin/pokt.ts",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "package.json",
19
+ "README.md"
20
+ ],
21
+ "keywords": [
22
+ "ai",
23
+ "cli",
24
+ "coding",
25
+ "agent",
26
+ "openrouter",
27
+ "ollama"
28
+ ],
29
+ "author": "PoktWeb",
30
+ "license": "ISC",
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/PoktWeb/Pokt_CLI.git"
37
+ },
38
+ "homepage": "https://github.com/PoktWeb/Pokt_CLI#readme",
39
+ "bugs": {
40
+ "url": "https://github.com/PoktWeb/Pokt_CLI/issues"
41
+ },
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "^1.27.1",
44
+ "chalk": "^5.3.0",
45
+ "conf": "^12.0.0",
46
+ "diff": "^8.0.3",
47
+ "openai": "^4.28.4",
48
+ "ora": "^8.0.1",
49
+ "prompts": "^2.4.2",
50
+ "yargs": "^17.7.2",
51
+ "zod": "^3.23.8"
52
+ },
53
+ "devDependencies": {
54
+ "@types/diff": "^7.0.2",
55
+ "@types/node": "^20.11.24",
56
+ "@types/prompts": "^2.4.9",
57
+ "@types/yargs": "^17.0.32",
58
+ "tsx": "^4.7.1",
59
+ "typescript": "^5.3.3"
60
+ }
61
+ }