codlyy 1.0.2 → 1.0.5

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/bin/codlyy.js CHANGED
@@ -1,71 +1,63 @@
1
1
  #!/usr/bin/env node
2
2
 
3
-
4
- import clear from "clear";
5
- import figlet from "figlet";
6
- import chalk from "chalk";
7
- import gradient from "gradient-string";
8
- import readline from "readline";
9
-
10
- // Clear terminal
11
- clear();
12
-
13
- // Ocean blue gradient
14
- const ocean = gradient(['#00c6ff', '#0072ff']);
15
-
16
- // Banner
17
- console.log(
18
- ocean(
19
- figlet.textSync("CODLYY", {
20
- font: "Block",
21
- horizontalLayout: "default",
22
- verticalLayout: "default"
23
- })
24
- )
3
+ import { Command } from 'commander';
4
+ import { readFileSync } from 'fs';
5
+ import { fileURLToPath } from 'url';
6
+ import { dirname, join } from 'path';
7
+ import chalk from 'chalk';
8
+ import { login } from '../src/commands/login.js';
9
+ import { logout } from '../src/commands/logout.js';
10
+ import { info } from '../src/commands/info.js';
11
+ import { startRepl } from '../src/repl.js';
12
+ import { getConfig } from '../src/utils/config.js';
13
+
14
+ // ---- GET VERSION FROM package.json ----
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ const pkg = JSON.parse(
18
+ readFileSync(join(__dirname, "../package.json"), "utf-8")
25
19
  );
26
-
27
- console.log(chalk.gray("⚡ Welcome to Codlyy CLI (research preview)"));
28
- console.log(chalk.gray("Type your prompt and press Enter"));
29
- console.log(chalk.gray("Type 'exit' to quit\n"));
30
-
31
- // Readline interface (Claude-style)
32
- const rl = readline.createInterface({
33
- input: process.stdin,
34
- output: process.stdout,
35
- prompt: chalk.cyanBright("❯ ")
36
- });
37
-
38
- // Start prompt
39
- rl.prompt();
40
-
41
- // Handle input
42
- rl.on("line", (input) => {
43
- const prompt = input.trim().toLowerCase();
44
-
45
- if (prompt === "exit" || prompt === "quit") {
46
- console.log(chalk.gray("\n👋 Exiting Codlyy. See you soon!\n"));
47
- process.exit(0);
48
- }
49
-
50
- if (prompt.length === 0) {
51
- rl.prompt();
52
- return;
20
+ const VERSION = pkg.version;
21
+
22
+ const program = new Command();
23
+
24
+ program
25
+ .name('codlyy')
26
+ .description('Codlyy AI CLI – Ocean Blue developer assistant')
27
+ .version(VERSION);
28
+
29
+ program
30
+ .command('login')
31
+ .description('Login to Codlyy with your browser')
32
+ .action(async () => {
33
+ await login();
34
+ });
35
+
36
+ program
37
+ .command('logout')
38
+ .description('Logout from Codlyy')
39
+ .action(async () => {
40
+ await logout();
41
+ });
42
+
43
+ program
44
+ .command('info')
45
+ .description('Show CLI status and available commands')
46
+ .action(async () => {
47
+ await info(VERSION);
48
+ });
49
+
50
+ // Handle default command (REPL)
51
+ if (process.argv.length <= 2) {
52
+ const config = getConfig();
53
+ if (config.token) {
54
+ // User is logged in, start REPL
55
+ startRepl(VERSION);
56
+ } else {
57
+ // User is not logged in
58
+ console.log(chalk.yellow('\nYou are not logged in.'));
59
+ console.log(`Please run ${chalk.cyan('codlyy login')} to authenticate.\n`);
53
60
  }
54
-
55
- // Coming soon response
56
- console.log(
57
- chalk.blueBright("\n🚧 Coming soon...")
58
- );
59
- console.log(
60
- chalk.gray("Codlyy AI engine is under development.\n")
61
- );
62
-
63
- // Wait for next prompt
64
- rl.prompt();
65
- });
66
-
67
- // Ctrl + C handling
68
- rl.on("SIGINT", () => {
69
- console.log(chalk.gray("\n👋 Codlyy closed.\n"));
70
- process.exit(0);
71
- });
61
+ } else {
62
+ program.parse(process.argv);
63
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codlyy",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "description": "Codlyy AI CLI – Ocean Blue developer assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,6 +24,7 @@
24
24
  "clear": "^0.1.0",
25
25
  "commander": "^14.0.2",
26
26
  "figlet": "^1.10.0",
27
- "gradient-string": "^3.0.0"
27
+ "gradient-string": "^3.0.0",
28
+ "open": "^11.0.0"
28
29
  }
29
30
  }
@@ -0,0 +1,34 @@
1
+ import chalk from 'chalk';
2
+ import { getConfig } from '../utils/config.js';
3
+
4
+ export async function info(version) {
5
+ const config = getConfig();
6
+ const isLoggedIn = !!config.token;
7
+
8
+ console.log(chalk.bold.blue('\n⚡ Codlyy CLI Information\n'));
9
+
10
+ // Version Info
11
+ console.log(`${chalk.bold('Version:')} ${version}`);
12
+
13
+ // User Info
14
+ if (isLoggedIn) {
15
+ console.log(`${chalk.bold('Status:')} ${chalk.green('Logged In')}`);
16
+ console.log(`${chalk.bold('User:')} ${config.name || config.email || 'Unknown'}`);
17
+ if (config.email && config.name) {
18
+ console.log(`${chalk.bold('Email:')} ${config.email}`);
19
+ }
20
+ } else {
21
+ console.log(`${chalk.bold('Status:')} ${chalk.yellow('Not Logged In')}`);
22
+ }
23
+
24
+ console.log(''); // Spacer
25
+
26
+ // Commands List
27
+ console.log(chalk.bold('Available Commands:'));
28
+ console.log(` ${chalk.cyan('codlyy login')} ${chalk.gray('Login using your browser')}`);
29
+ console.log(` ${chalk.cyan('codlyy logout')} ${chalk.gray('Logout and clear credentials')}`);
30
+ console.log(` ${chalk.cyan('codlyy info')} ${chalk.gray('Show this information page')}`);
31
+ console.log(` ${chalk.cyan('codlyy')} ${chalk.gray('Start the AI assistant REPL (requires login)')}`);
32
+
33
+ console.log('');
34
+ }
@@ -0,0 +1,116 @@
1
+ import http from 'http';
2
+ import open from 'open';
3
+ import { saveConfig, getConfig } from '../utils/config.js';
4
+ import chalk from 'chalk';
5
+ import readline from 'readline';
6
+
7
+ const PORT = 8989;
8
+
9
+ export async function login() {
10
+ console.log(chalk.blue('Opening browser for authentication...'));
11
+
12
+ try {
13
+ const userData = await startAuthServer();
14
+
15
+ // Save initial data immediately
16
+ saveConfig(userData);
17
+
18
+ console.log(chalk.green(`\nSuccessfully logged in as ${userData.name || userData.email}!`));
19
+
20
+ // Ask if they want to update their name
21
+ await askToEditName(userData);
22
+
23
+ } catch (err) {
24
+ console.error(chalk.red('\nLogin failed:'), err.message);
25
+ process.exit(1);
26
+ }
27
+ }
28
+
29
+ function startAuthServer() {
30
+ return new Promise((resolve, reject) => {
31
+ const server = http.createServer((req, res) => {
32
+ const url = new URL(req.url, `http://localhost:${PORT}`);
33
+
34
+ if (url.pathname === '/callback') {
35
+ const token = url.searchParams.get('token');
36
+ const email = url.searchParams.get('email');
37
+ const name = url.searchParams.get('name');
38
+ const picture = url.searchParams.get('picture');
39
+
40
+ if (token) {
41
+ // 1. Display success message to user in browser
42
+ res.writeHead(200, { 'Content-Type': 'text/html' });
43
+ res.end(`
44
+ <html>
45
+ <body style="font-family: sans-serif; text-align: center; padding: 50px;">
46
+ <h1>Login Successful</h1>
47
+ <p>You can close this tab now and return to the CLI.</p>
48
+ <script>window.close()</script>
49
+ </body>
50
+ </html>
51
+ `);
52
+
53
+ // 2. Stop the server and resolve
54
+ res.on('finish', () => {
55
+ server.close();
56
+ resolve({ token, email, name, picture });
57
+ });
58
+
59
+ } else {
60
+ res.writeHead(400);
61
+ res.end('No token found');
62
+ server.close();
63
+ reject(new Error('No token received'));
64
+ }
65
+ } else {
66
+ res.writeHead(404);
67
+ res.end();
68
+ }
69
+ });
70
+
71
+ server.listen(PORT, async () => {
72
+ try {
73
+ await open(`https://codlyy.vercel.app/auth/cli-login?port=${PORT}`);
74
+ } catch (err) {
75
+ console.error(chalk.red('Failed to open browser:'), err);
76
+ console.log(chalk.yellow(`Please open this URL manually: https://codlyy.vercel.app/auth/cli-login?port=${PORT}`));
77
+ }
78
+ });
79
+
80
+ server.on('error', (err) => {
81
+ reject(err);
82
+ });
83
+ });
84
+ }
85
+
86
+ function askToEditName(userData) {
87
+ const rl = readline.createInterface({
88
+ input: process.stdin,
89
+ output: process.stdout
90
+ });
91
+
92
+ return new Promise((resolve) => {
93
+ // Add a small delay/newline to visually separate from previous logs
94
+ console.log('');
95
+
96
+ rl.question(chalk.yellow(`Your display name is currently "${userData.name}". Do you want to edit it? (y/N) `), (answer) => {
97
+ if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
98
+ rl.question(chalk.cyan('Enter new name: '), (newName) => {
99
+ const trimmedName = newName.trim();
100
+ if (trimmedName) {
101
+ saveConfig({ ...userData, name: trimmedName });
102
+ console.log(chalk.green(`Name updated to: ${trimmedName}`));
103
+ } else {
104
+ console.log(chalk.gray('Name unchanged.'));
105
+ }
106
+ rl.close();
107
+ resolve();
108
+ });
109
+ } else {
110
+ console.log(chalk.gray('Name unchanged.'));
111
+ rl.close();
112
+ resolve();
113
+ }
114
+ });
115
+ });
116
+ }
@@ -0,0 +1,7 @@
1
+ import { clearConfig } from '../utils/config.js';
2
+ import chalk from 'chalk';
3
+
4
+ export async function logout() {
5
+ clearConfig();
6
+ console.log(chalk.green('Successfully logged out.'));
7
+ }
package/src/repl.js ADDED
@@ -0,0 +1,82 @@
1
+ import clear from "clear";
2
+ import figlet from "figlet";
3
+ import chalk from "chalk";
4
+ import gradient from "gradient-string";
5
+ import readline from "readline";
6
+ import { getConfig } from "./utils/config.js";
7
+
8
+ export function startRepl(version) {
9
+ // Clear terminal
10
+ clear();
11
+
12
+ // Ocean blue gradient
13
+ const ocean = gradient(["#00c6ff", "#0072ff"]);
14
+
15
+ // Banner
16
+ console.log(
17
+ ocean(
18
+ figlet.textSync("CODLYY", {
19
+ font: "Block",
20
+ horizontalLayout: "default",
21
+ verticalLayout: "default",
22
+ })
23
+ )
24
+ );
25
+
26
+ const config = getConfig();
27
+ const displayName = config.name || config.email || "User";
28
+
29
+ // Header info
30
+ console.log(
31
+ chalk.gray(`⚡ Codlyy CLI v${version} · Research Preview`)
32
+ );
33
+ console.log(chalk.blue(`Welcome back, ${displayName}!`));
34
+ console.log(chalk.gray("Type your prompt and press Enter"));
35
+ console.log(chalk.gray("Type 'exit' to quit\n"));
36
+
37
+ // Readline interface
38
+ const rl = readline.createInterface({
39
+ input: process.stdin,
40
+ output: process.stdout,
41
+ prompt: chalk.cyanBright("❯ "),
42
+ });
43
+
44
+ // Start prompt
45
+ rl.prompt();
46
+
47
+ // Handle input
48
+ rl.on("line", (input) => {
49
+ const prompt = input.trim().toLowerCase();
50
+
51
+ if (prompt === "exit" || prompt === "quit") {
52
+ console.log(chalk.gray("\n👋 Exiting Codlyy. See you soon!\n"));
53
+ process.exit(0);
54
+ }
55
+
56
+ if (prompt === "version" || prompt === "--version" || prompt === "-v") {
57
+ console.log(chalk.blueBright(`\nCodlyy CLI v${version}\n`));
58
+ rl.prompt();
59
+ return;
60
+ }
61
+
62
+ if (prompt.length === 0) {
63
+ rl.prompt();
64
+ return;
65
+ }
66
+
67
+ // Coming soon response
68
+ console.log(chalk.blueBright("\n🚧 Coming soon..."));
69
+ console.log(
70
+ chalk.gray("Codlyy AI engine is under development.\n")
71
+ );
72
+
73
+ // Wait for next prompt
74
+ rl.prompt();
75
+ });
76
+
77
+ // Ctrl + C handling
78
+ rl.on("SIGINT", () => {
79
+ console.log(chalk.gray("\n👋 Codlyy closed.\n"));
80
+ process.exit(0);
81
+ });
82
+ }
@@ -0,0 +1,41 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+
5
+ const CONFIG_PATH = path.join(os.homedir(), '.codlyyrc');
6
+
7
+ export function saveConfig(data) {
8
+ try {
9
+ const current = getConfig();
10
+ const newConfig = { ...current, ...data };
11
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(newConfig, null, 2));
12
+ return true;
13
+ } catch (error) {
14
+ console.error('Error saving config:', error);
15
+ return false;
16
+ }
17
+ }
18
+
19
+ export function getConfig() {
20
+ try {
21
+ if (fs.existsSync(CONFIG_PATH)) {
22
+ const data = fs.readFileSync(CONFIG_PATH, 'utf-8');
23
+ return JSON.parse(data);
24
+ }
25
+ } catch (error) {
26
+ // Ignore error if file doesn't exist or is invalid
27
+ }
28
+ return {};
29
+ }
30
+
31
+ export function clearConfig() {
32
+ try {
33
+ if(fs.existsSync(CONFIG_PATH)) {
34
+ fs.unlinkSync(CONFIG_PATH);
35
+ return true;
36
+ }
37
+ } catch (error) {
38
+ console.error('Error clearing config:', error);
39
+ }
40
+ return false;
41
+ }