rafaygen-cli 1.0.0 → 1.0.2

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/rgcli.js CHANGED
@@ -3,7 +3,7 @@
3
3
  import { Command } from "commander";
4
4
  import chalk from "chalk";
5
5
  import { setToken, setApiUrl } from "../src/auth.js";
6
- import { askAgent } from "../src/agent.js";
6
+ import { askAgent, startInteractiveLoop } from "../src/agent.js";
7
7
  import { printSuccess } from "../src/ui.js";
8
8
  import fs from "fs";
9
9
 
@@ -32,14 +32,21 @@ program
32
32
 
33
33
  program
34
34
  .command("ask")
35
- .description("Ask RafayGen to write code, modify files, or run commands")
35
+ .description("Ask RafayGen a one-off question")
36
36
  .argument("<prompt...>", "What do you want to build?")
37
37
  .action((promptWords) => {
38
38
  const prompt = promptWords.join(" ");
39
- askAgent(prompt);
39
+ askAgent(prompt).then(() => process.exit(0));
40
40
  });
41
41
 
42
- // Handle default command if no args provided
42
+ program
43
+ .command("chat")
44
+ .description("Start an interactive chat session")
45
+ .action(() => {
46
+ startInteractiveLoop();
47
+ });
48
+
49
+ // Handle default command if no args provided -> Start Chat Loop
43
50
  if (process.argv.length === 2) {
44
51
  console.log(chalk.cyan.bold(`
45
52
  ____ __ _____
@@ -51,7 +58,7 @@ if (process.argv.length === 2) {
51
58
  __/ |
52
59
  |___/
53
60
  `));
54
- program.help();
61
+ startInteractiveLoop();
62
+ } else {
63
+ program.parse(process.argv);
55
64
  }
56
-
57
- program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rafaygen-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,6 +21,7 @@
21
21
  "commander": "^14.0.3",
22
22
  "diff": "^9.0.0",
23
23
  "inquirer": "^13.4.3",
24
+ "open": "^11.0.0",
24
25
  "ora": "^9.4.0"
25
26
  },
26
27
  "devDependencies": {
package/src/agent.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { getToken, getApiUrl } from "./auth.js";
2
- import { renderBox, renderDiffBox, printError, printStep, printSuccess } from "./ui.js";
2
+ import { startAuthLoop } from "./auth.js";
3
+ import { renderBox, renderDiffBox, printError, printStep, printSuccess, printAsciiLogo, printRandomWelcome } from "./ui.js";
3
4
  import inquirer from "inquirer";
4
5
  import chalk from "chalk";
5
6
  import fs from "fs";
@@ -7,10 +8,10 @@ import path from "path";
7
8
  import { exec } from "child_process";
8
9
 
9
10
  export async function askAgent(promptText) {
10
- const token = getToken();
11
+ let token = getToken();
11
12
  if (!token) {
12
- printError("Not logged in. Please run 'rgcli login <token>' first.");
13
- process.exit(1);
13
+ await startAuthLoop();
14
+ token = getToken();
14
15
  }
15
16
 
16
17
  printStep("Connecting to RafayGen...");
@@ -29,8 +30,6 @@ export async function askAgent(promptText) {
29
30
  throw new Error(`API Error: ${res.statusText}`);
30
31
  }
31
32
 
32
- // Since this is a simple implementation, we'll read the full JSON response.
33
- // In a fully streaming CLI, you'd parse the stream.
34
33
  const data = await res.json();
35
34
 
36
35
  if (data.message) {
@@ -50,6 +49,54 @@ export async function askAgent(promptText) {
50
49
  }
51
50
  }
52
51
 
52
+ export async function startInteractiveLoop() {
53
+ let token = getToken();
54
+ if (!token) {
55
+ await startAuthLoop();
56
+ token = getToken();
57
+ } else {
58
+ printAsciiLogo();
59
+ }
60
+
61
+ printRandomWelcome();
62
+ console.log(chalk.gray("Type /help for slash commands, or /exit to quit."));
63
+
64
+ while (true) {
65
+ const { prompt } = await inquirer.prompt([
66
+ {
67
+ type: "input",
68
+ name: "prompt",
69
+ message: chalk.magenta.bold("rgcli> "),
70
+ prefix: ""
71
+ }
72
+ ]);
73
+
74
+ const input = prompt.trim();
75
+
76
+ if (!input) continue;
77
+
78
+ if (input === "/exit" || input === "/quit") {
79
+ console.log(chalk.gray("Goodbye!"));
80
+ process.exit(0);
81
+ }
82
+
83
+ if (input === "/clear") {
84
+ console.clear();
85
+ continue;
86
+ }
87
+
88
+ if (input === "/help") {
89
+ console.log(chalk.cyan("\\nAvailable Slash Commands:"));
90
+ console.log(chalk.white(" /clear") + chalk.gray(" - Clear the terminal window"));
91
+ console.log(chalk.white(" /exit ") + chalk.gray(" - Exit the interactive shell"));
92
+ console.log(chalk.white(" /help ") + chalk.gray(" - Show this message\\n"));
93
+ continue;
94
+ }
95
+
96
+ await askAgent(input);
97
+ }
98
+ }
99
+
53
100
  async function handleAction(action) {
54
101
  if (action.type === "write") {
55
102
  const filepath = path.resolve(process.cwd(), action.file);
package/src/auth.js CHANGED
@@ -38,3 +38,97 @@ export function getApiUrl() {
38
38
  export function setApiUrl(apiUrl) {
39
39
  saveConfig({ apiUrl });
40
40
  }
41
+
42
+ export async function startAuthLoop() {
43
+ const inquirer = (await import("inquirer")).default;
44
+ const chalk = (await import("chalk")).default;
45
+ const open = (await import("open")).default;
46
+ const { printAsciiLogo, printSuccess } = await import("./ui.js");
47
+
48
+ printAsciiLogo();
49
+ console.log(chalk.yellow("You are not logged in. Let's get you authenticated!\\n"));
50
+
51
+ while (true) {
52
+ const { method } = await inquirer.prompt([
53
+ {
54
+ type: "list",
55
+ name: "method",
56
+ message: "How would you like to login to RafayGen?",
57
+ choices: [
58
+ { name: "Browser Login (Recommended)", value: "browser" },
59
+ { name: "Paste Token Manually", value: "token" },
60
+ { name: "Device Code (Headless)", value: "device" },
61
+ { name: "Exit CLI", value: "exit" }
62
+ ]
63
+ }
64
+ ]);
65
+
66
+ if (method === "exit") {
67
+ process.exit(0);
68
+ }
69
+
70
+ if (method === "token") {
71
+ const { token } = await inquirer.prompt([
72
+ {
73
+ type: "password",
74
+ name: "token",
75
+ message: "Paste your RafayGen Personal Access Token:"
76
+ }
77
+ ]);
78
+ if (token.trim()) {
79
+ setToken(token.trim());
80
+ printSuccess("Successfully logged in to RafayGen!");
81
+ return;
82
+ } else {
83
+ console.log(chalk.red("Token cannot be empty. Try again."));
84
+ }
85
+ }
86
+
87
+ if (method === "browser") {
88
+ const loginUrl = "https://rafaygen.com/settings/tokens";
89
+ console.log(chalk.cyan(`\\nOpening browser to: ${loginUrl}`));
90
+ console.log(chalk.gray("If the browser doesn't open, copy and paste the URL manually."));
91
+ try {
92
+ await open(loginUrl);
93
+ } catch (e) {
94
+ // Ignore open errors
95
+ }
96
+
97
+ const { token } = await inquirer.prompt([
98
+ {
99
+ type: "password",
100
+ name: "token",
101
+ message: "Once you create a token, paste it here:"
102
+ }
103
+ ]);
104
+ if (token.trim()) {
105
+ setToken(token.trim());
106
+ printSuccess("Successfully logged in to RafayGen!");
107
+ return;
108
+ }
109
+ }
110
+
111
+ if (method === "device") {
112
+ const code = Math.floor(100000 + Math.random() * 900000);
113
+ console.log(chalk.magenta.bold(`\\nYour Device Code is: ${code}`));
114
+ console.log(chalk.white(`1. Go to https://rafaygen.com/device on your phone or computer.`));
115
+ console.log(chalk.white(`2. Enter the code above.`));
116
+
117
+ // In a real implementation, you'd poll the API here.
118
+ // We will simulate the polling for now until the backend endpoint is fully built.
119
+ console.log(chalk.gray("(Device flow polling is simulated in this CLI version)"));
120
+ const { token } = await inquirer.prompt([
121
+ {
122
+ type: "password",
123
+ name: "token",
124
+ message: "Or just paste the token manually for now:"
125
+ }
126
+ ]);
127
+ if (token.trim()) {
128
+ setToken(token.trim());
129
+ printSuccess("Successfully logged in to RafayGen!");
130
+ return;
131
+ }
132
+ }
133
+ }
134
+ }
package/src/ui.js CHANGED
@@ -68,3 +68,34 @@ export function printSuccess(msg) {
68
68
  export function printStep(msg) {
69
69
  console.log(chalk.cyan.bold("❯ ") + msg);
70
70
  }
71
+
72
+ export function printAsciiLogo() {
73
+ console.log(chalk.cyan.bold(`
74
+ ____ __ _____
75
+ | _ \\ / _| / ____|
76
+ | |_) | __ _| |_ __ _ _ _| | __ ___ _ __
77
+ | _ < / _\` | _/ _\` | | | | |_ / _ \\ '_ \\
78
+ | |_) | (_| | || (_| | |_| |__| | __/ | | |
79
+ |____/ \\__,_|_| \\__,_|\\__, \\_____\\___|_| |_|
80
+ __/ |
81
+ |___/
82
+ `));
83
+ }
84
+
85
+ export function printRandomWelcome() {
86
+ const messages = [
87
+ "Welcome to RafayGen. Ready to architect something beautiful?",
88
+ "RafayGen Agent initialized. Standing by for instructions.",
89
+ "Authentication successful. Let's write some code.",
90
+ "System online. Awaiting your creative vision.",
91
+ "RafayGen connected. What are we building today?",
92
+ "Agent is active. Drop your prompt below.",
93
+ ];
94
+
95
+ const colors = ["green", "cyan", "magenta", "blueBright", "greenBright", "yellowBright"];
96
+
97
+ const randMsg = messages[Math.floor(Math.random() * messages.length)];
98
+ const randColor = colors[Math.floor(Math.random() * colors.length)];
99
+
100
+ console.log(chalk[randColor].bold(`\\n✨ ${randMsg}\\n`));
101
+ }