mirror of
https://github.com/tcsenpai/vvk.git
synced 2025-06-09 12:37:26 +00:00
release
This commit is contained in:
parent
13ffdff9a6
commit
19e3e38571
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,7 @@
|
||||
node_modules
|
||||
.env
|
||||
dist
|
||||
*.app
|
||||
*.exe
|
||||
*.pkg
|
||||
*.blob
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vvk",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"version": "1.1.0",
|
||||
"description": "A command-line interface tool that converts natural language instructions into shell commands using OpenAI's GPT-4.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "rimraf dist && webpack"
|
||||
@ -22,6 +22,7 @@
|
||||
"webpack-cli": "^6.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.8.1",
|
||||
"child_process": "^1.0.2",
|
||||
"openai": "^4.85.4",
|
||||
"readline": "^1.3.0"
|
||||
|
30
pnpm-lock.yaml
generated
30
pnpm-lock.yaml
generated
@ -8,6 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
axios:
|
||||
specifier: ^1.8.1
|
||||
version: 1.8.1
|
||||
child_process:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
@ -242,6 +245,9 @@ packages:
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
axios@1.8.1:
|
||||
resolution: {integrity: sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
@ -412,6 +418,15 @@ packages:
|
||||
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
|
||||
hasBin: true
|
||||
|
||||
follow-redirects@1.15.9:
|
||||
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||
engines: {node: '>=14'}
|
||||
@ -639,6 +654,9 @@ packages:
|
||||
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
randombytes@2.1.0:
|
||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||
|
||||
@ -1098,6 +1116,14 @@ snapshots:
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
axios@1.8.1:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.9
|
||||
form-data: 4.0.2
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
@ -1241,6 +1267,8 @@ snapshots:
|
||||
|
||||
flat@5.0.2: {}
|
||||
|
||||
follow-redirects@1.15.9: {}
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
@ -1436,6 +1464,8 @@ snapshots:
|
||||
dependencies:
|
||||
find-up: 4.1.0
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
randombytes@2.1.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
@ -17,14 +17,14 @@ export function configCommand(args: string[]) {
|
||||
}
|
||||
const updated = updateConfig({ [key]: parsedValue });
|
||||
console.log('Configuration updated:', updated);
|
||||
} else if (command === 'get') {
|
||||
const config = loadConfig();
|
||||
console.log('Current configuration:', config);
|
||||
} else if (command === 'list') {
|
||||
const config = loadConfig();
|
||||
} else if (command === 'get' || command === 'list') {
|
||||
let config = loadConfig();
|
||||
if (config.key && config.key.length > 0) {
|
||||
config.key = '********';
|
||||
}
|
||||
console.log('Current configuration:', config);
|
||||
} else {
|
||||
console.error('Unknown config command. Use "set" or "get".');
|
||||
console.error('Unknown config command. Use "set" or "list".');
|
||||
}
|
||||
process.exit(0);
|
||||
}
|
||||
|
@ -4,12 +4,16 @@ import os from 'os';
|
||||
|
||||
export interface Config {
|
||||
openaiApiKey: string;
|
||||
userId: string;
|
||||
key: string;
|
||||
confirmCommand: boolean;
|
||||
defaultConfirmation: 'y' | 'n';
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG: Config = {
|
||||
openaiApiKey: '',
|
||||
userId: '',
|
||||
key: '',
|
||||
confirmCommand: true,
|
||||
defaultConfirmation: 'y',
|
||||
};
|
||||
|
@ -1,14 +1,13 @@
|
||||
import OpenAI from 'openai';
|
||||
import { loadConfig } from './config';
|
||||
import axios from 'axios';
|
||||
|
||||
export async function generateCommand(input: string) {
|
||||
const { openaiApiKey } = loadConfig();
|
||||
const { openaiApiKey, key, userId } = loadConfig();
|
||||
|
||||
if (!openaiApiKey) {
|
||||
console.log("Couldn't generage command: Set your OpenAI API Key with vvk config set openaiApiKey <your_api_key>");
|
||||
process.exit(1);
|
||||
}
|
||||
let command;
|
||||
|
||||
if (openaiApiKey && openaiApiKey.length > 1) {
|
||||
const openai = new OpenAI({ apiKey: openaiApiKey });
|
||||
|
||||
const response = await openai.chat.completions.create({
|
||||
@ -23,8 +22,21 @@ export async function generateCommand(input: string) {
|
||||
],
|
||||
});
|
||||
|
||||
const command = response.choices[0]?.message?.content?.trim();
|
||||
command = response.choices[0]?.message?.content?.trim();
|
||||
} else if (key?.length > 1 && userId?.length > 1) {
|
||||
const response = await axios.post('https://vvk.ai/api/command', {
|
||||
input,
|
||||
key,
|
||||
userId,
|
||||
});
|
||||
|
||||
command = response.data.command;
|
||||
} else {
|
||||
console.log(
|
||||
"Couldn't generage command: Set your OpenAI API Key with vvk config set openaiApiKey <your_api_key> or log in with vvk login"
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
if (!command) {
|
||||
console.log("Couldn't generate a command.");
|
||||
process.exit(1);
|
||||
|
32
src/index.ts
32
src/index.ts
@ -1,10 +1,14 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// remove warnings in console
|
||||
process.removeAllListeners('warning');
|
||||
|
||||
import { exec } from 'child_process';
|
||||
import readline from 'readline';
|
||||
import { generateCommand } from './generate-command';
|
||||
import { loadConfig } from './config';
|
||||
import { configCommand } from './config-command';
|
||||
import { login, logout } from './login';
|
||||
|
||||
const config = loadConfig();
|
||||
|
||||
@ -14,15 +18,29 @@ const userInput = args.join(' ');
|
||||
|
||||
if (args[0] === 'config') {
|
||||
configCommand(args);
|
||||
}
|
||||
|
||||
if ((args[0] === '--version' || args[0] === '-v') && args.length === 1) {
|
||||
console.log('1.0.0');
|
||||
} else if (args[0] === 'help' && args.length === 1) {
|
||||
console.log(`
|
||||
Available commands:
|
||||
vvk <command> : Generate and execute a command
|
||||
vvk config set ... : Set configuration options
|
||||
vvk login : Log in to your account
|
||||
vvk logout : Log out of your account
|
||||
vvk --version : Show version
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
if (!userInput) {
|
||||
} else if ((args[0] === '--version' || args[0] === '-v') && args.length === 1) {
|
||||
console.log('1.0.0');
|
||||
} else if (args[0] === 'login' && args.length === 1) {
|
||||
login();
|
||||
} else if (args[0] === 'logout' && args.length === 1) {
|
||||
logout();
|
||||
} else {
|
||||
if (!userInput) {
|
||||
console.log('Usage: vvk <your natural language command>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
processCommand(userInput);
|
||||
}
|
||||
|
||||
// Function to prompt for confirmation
|
||||
@ -87,5 +105,3 @@ async function processCommand(input: string) {
|
||||
|
||||
confirmExecution(command);
|
||||
}
|
||||
|
||||
processCommand(userInput);
|
||||
|
66
src/login.ts
Normal file
66
src/login.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { randomUUID } from 'crypto';
|
||||
import axios from 'axios';
|
||||
import { updateConfig } from './config';
|
||||
import { spawn } from 'child_process';
|
||||
import os from 'os';
|
||||
|
||||
async function openUrl(url: string) {
|
||||
const platform = os.platform();
|
||||
|
||||
if (platform === 'win32') {
|
||||
spawn('cmd', ['/c', 'start', url], { detached: true, stdio: 'ignore' });
|
||||
} else if (platform === 'darwin') {
|
||||
spawn('open', [url], { detached: true, stdio: 'ignore' });
|
||||
} else {
|
||||
spawn('xdg-open', [url], { detached: true, stdio: 'ignore' });
|
||||
}
|
||||
}
|
||||
|
||||
export async function login() {
|
||||
// const { default: open } = await import('open');
|
||||
const loginCode = randomUUID();
|
||||
const loginUrl = `http://vvk.ai/api/cli-login?c=${loginCode}`;
|
||||
await openUrl(loginUrl);
|
||||
|
||||
console.log('🌐 Please log in via the browser. Waiting for authentication...');
|
||||
|
||||
let key, userId;
|
||||
const startTime = Date.now();
|
||||
const timeoutMs = 60 * 1000; // 60 seconds timeout
|
||||
|
||||
while (!key) {
|
||||
// Check if timeout has been reached
|
||||
if (Date.now() - startTime > timeoutMs) {
|
||||
console.log('❌ Login timed out after 60 seconds. Please try again.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
await new Promise((res) => setTimeout(res, 3000)); // Wait 3 seconds between polls
|
||||
|
||||
try {
|
||||
const { data } = await axios.get(`https://vvk.ai/api/cli-auth?c=${loginCode}`);
|
||||
if (data.key && data.userId) {
|
||||
key = data.key;
|
||||
userId = data.userId;
|
||||
}
|
||||
} catch (err) {
|
||||
// Ignore errors while waiting
|
||||
}
|
||||
}
|
||||
|
||||
updateConfig({ key, userId });
|
||||
console.log('✅ Logged in successfully!');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
export async function logout() {
|
||||
try {
|
||||
// Clear user credentials from config
|
||||
updateConfig({ key: '', userId: '' });
|
||||
console.log('✅ Logged out successfully!');
|
||||
process.exit(0);
|
||||
} catch (err: any) {
|
||||
console.error('❌ Error during logout:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user