rafaygen-cli 1.0.0

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.
@@ -0,0 +1,18 @@
1
+ const token = "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";
2
+
3
+ async function main() {
4
+ const jobsRes = await fetch("https://api.github.com/repos/rafay0342/rgcli/actions/runs/26226725358/jobs", {
5
+ headers: { "Authorization": `Bearer ${token}` }
6
+ });
7
+ const jobsData = await jobsRes.json();
8
+ const job = jobsData.jobs[0];
9
+
10
+ console.log("Fetching annotations for job id:", job.id);
11
+ const annRes = await fetch(`https://api.github.com/repos/rafay0342/rgcli/check-runs/${job.id}/annotations`, {
12
+ headers: { "Authorization": `Bearer ${token}` }
13
+ });
14
+ const annData = await annRes.json();
15
+ console.log("Annotations:");
16
+ console.log(JSON.stringify(annData, null, 2));
17
+ }
18
+ main();
package/fetch_logs.js ADDED
@@ -0,0 +1,24 @@
1
+ const token = "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";
2
+
3
+ async function main() {
4
+ const res = await fetch("https://api.github.com/repos/rafay0342/rgcli/actions/runs/26226725358/jobs", {
5
+ headers: { "Authorization": `token ${token}` }
6
+ });
7
+ const data = await res.json();
8
+ const job = data.jobs[0];
9
+ console.log("Steps:");
10
+ for (const step of job.steps) {
11
+ if (step.conclusion === "failure") {
12
+ console.log(`Failed Step: ${step.name}`);
13
+ console.log(step);
14
+
15
+ // Try to get logs for this job
16
+ const logRes = await fetch(job.url + "/logs", { headers: { "Authorization": `token ${token}` }});
17
+ const logs = await logRes.text();
18
+ // Only print the last 50 lines
19
+ console.log("=== LOGS ===");
20
+ console.log(logs.split('\\n').slice(-50).join('\\n'));
21
+ }
22
+ }
23
+ }
24
+ main();
package/install.sh ADDED
@@ -0,0 +1,30 @@
1
+ #!/bin/bash
2
+ # RafayGen CLI (rgcli) Installation Script
3
+
4
+ echo "Installing RafayGen CLI..."
5
+
6
+ # Check for Node.js
7
+ if ! command -v npm &> /dev/null; then
8
+ echo "Error: npm is not installed. Please install Node.js first."
9
+ exit 1
10
+ fi
11
+
12
+ echo "Installing rgcli globally via npm..."
13
+ npm install -g rgcli
14
+
15
+ echo ""
16
+ echo "=================================================="
17
+ echo "✔ RafayGen CLI installed successfully!"
18
+ echo "=================================================="
19
+ echo ""
20
+ echo "To get started, authenticate with your web app:"
21
+ echo " rgcli login <your-token>"
22
+ echo ""
23
+ echo "Then ask RafayGen to code anything:"
24
+ echo " rgcli ask \"build a simple python web server\""
25
+ echo ""
26
+ echo "For advanced users (Apt/Snap/Brew):"
27
+ echo " sudo snap install rgcli"
28
+ echo " sudo apt install rgcli"
29
+ echo " brew install rgcli"
30
+ echo "*(Native binary distribution coming soon via CI/CD pipelines)*"
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "rafaygen-cli",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "type": "module",
13
+ "bin": {
14
+ "rgcli": "./bin/rgcli.js"
15
+ },
16
+ "dependencies": {
17
+ "axios": "^1.16.1",
18
+ "boxen": "^8.0.1",
19
+ "chalk": "^5.6.2",
20
+ "cli-highlight": "^2.1.11",
21
+ "commander": "^14.0.3",
22
+ "diff": "^9.0.0",
23
+ "inquirer": "^13.4.3",
24
+ "ora": "^9.4.0"
25
+ },
26
+ "devDependencies": {
27
+ "esbuild": "^0.28.0",
28
+ "pkg": "^5.8.1"
29
+ },
30
+ "pkg": {
31
+ "scripts": [
32
+ "dist/bundle.cjs"
33
+ ],
34
+ "targets": [
35
+ "node18-linux-x64",
36
+ "node18-macos-x64",
37
+ "node18-win-x64"
38
+ ],
39
+ "outputPath": "binaries"
40
+ }
41
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "scripts": [
3
+ "dist/bundle.cjs"
4
+ ],
5
+ "targets": [
6
+ "node18-linux-x64",
7
+ "node18-macos-x64",
8
+ "node18-win-x64"
9
+ ],
10
+ "outputPath": "binaries"
11
+ }
package/rgcli.deb ADDED
Binary file
package/src/agent.js ADDED
@@ -0,0 +1,104 @@
1
+ import { getToken, getApiUrl } from "./auth.js";
2
+ import { renderBox, renderDiffBox, printError, printStep, printSuccess } from "./ui.js";
3
+ import inquirer from "inquirer";
4
+ import chalk from "chalk";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import { exec } from "child_process";
8
+
9
+ export async function askAgent(promptText) {
10
+ const token = getToken();
11
+ if (!token) {
12
+ printError("Not logged in. Please run 'rgcli login <token>' first.");
13
+ process.exit(1);
14
+ }
15
+
16
+ printStep("Connecting to RafayGen...");
17
+
18
+ try {
19
+ const res = await fetch(getApiUrl(), {
20
+ method: "POST",
21
+ headers: {
22
+ "Content-Type": "application/json",
23
+ "Authorization": `Bearer ${token}`
24
+ },
25
+ body: JSON.stringify({ prompt: promptText })
26
+ });
27
+
28
+ if (!res.ok) {
29
+ throw new Error(`API Error: ${res.statusText}`);
30
+ }
31
+
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
+ const data = await res.json();
35
+
36
+ if (data.message) {
37
+ renderBox(" RafayGen ", data.message, "cyan");
38
+ }
39
+
40
+ if (data.actions && data.actions.length > 0) {
41
+ for (const action of data.actions) {
42
+ await handleAction(action);
43
+ }
44
+ } else {
45
+ printSuccess("Done.");
46
+ }
47
+
48
+ } catch (error) {
49
+ printError(error.message);
50
+ }
51
+ }
52
+
53
+ async function handleAction(action) {
54
+ if (action.type === "write") {
55
+ const filepath = path.resolve(process.cwd(), action.file);
56
+ let original = "";
57
+ if (fs.existsSync(filepath)) {
58
+ original = fs.readFileSync(filepath, "utf-8");
59
+ }
60
+
61
+ // Show diff
62
+ renderDiffBox(action.file, original, action.content);
63
+
64
+ // Ask user to confirm
65
+ const { confirm } = await inquirer.prompt([
66
+ {
67
+ type: "confirm",
68
+ name: "confirm",
69
+ message: `Allow RafayGen to write to ${action.file}?`,
70
+ default: true
71
+ }
72
+ ]);
73
+
74
+ if (confirm) {
75
+ fs.mkdirSync(path.dirname(filepath), { recursive: true });
76
+ fs.writeFileSync(filepath, action.content, "utf-8");
77
+ printSuccess(`Saved ${action.file}`);
78
+ } else {
79
+ console.log(chalk.yellow("Skipped write."));
80
+ }
81
+ } else if (action.type === "execute") {
82
+ renderBox(` Execute Command `, action.command, "magenta");
83
+ const { confirm } = await inquirer.prompt([
84
+ {
85
+ type: "confirm",
86
+ name: "confirm",
87
+ message: `Allow RafayGen to execute this command?`,
88
+ default: true
89
+ }
90
+ ]);
91
+
92
+ if (confirm) {
93
+ await new Promise((resolve) => {
94
+ const proc = exec(action.command, (err, stdout, stderr) => {
95
+ if (stdout) console.log(chalk.gray(stdout));
96
+ if (stderr) console.log(chalk.red(stderr));
97
+ if (err) printError(`Command failed with code ${err.code}`);
98
+ else printSuccess("Command executed successfully.");
99
+ resolve();
100
+ });
101
+ });
102
+ }
103
+ }
104
+ }
package/src/auth.js ADDED
@@ -0,0 +1,40 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import os from "os";
4
+
5
+ const CONFIG_PATH = path.join(os.homedir(), ".rgcli.json");
6
+
7
+ export function loadConfig() {
8
+ if (fs.existsSync(CONFIG_PATH)) {
9
+ try {
10
+ const data = fs.readFileSync(CONFIG_PATH, "utf-8");
11
+ return JSON.parse(data);
12
+ } catch (e) {
13
+ return {};
14
+ }
15
+ }
16
+ return {};
17
+ }
18
+
19
+ export function saveConfig(config) {
20
+ const existing = loadConfig();
21
+ const updated = { ...existing, ...config };
22
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(updated, null, 2), "utf-8");
23
+ }
24
+
25
+ export function getToken() {
26
+ return loadConfig().token;
27
+ }
28
+
29
+ export function setToken(token) {
30
+ saveConfig({ token });
31
+ }
32
+
33
+ export function getApiUrl() {
34
+ // Default to localhost for local testing, can be overridden by environment variable or config
35
+ return process.env.RG_API_URL || loadConfig().apiUrl || "http://localhost:3000/api/cli";
36
+ }
37
+
38
+ export function setApiUrl(apiUrl) {
39
+ saveConfig({ apiUrl });
40
+ }
package/src/ui.js ADDED
@@ -0,0 +1,70 @@
1
+ import boxen from "boxen";
2
+ import chalk from "chalk";
3
+ import { highlight } from "cli-highlight";
4
+ import * as Diff from "diff";
5
+ import fs from "fs";
6
+ import path from "path";
7
+
8
+ // Formats a message in a nice outlined box
9
+ export function renderBox(title, content, color = "cyan") {
10
+ const c = chalk[color] || chalk.cyan;
11
+ console.log(
12
+ boxen(content, {
13
+ title: c.bold(title),
14
+ titleAlignment: "left",
15
+ padding: 1,
16
+ margin: { top: 1, bottom: 1 },
17
+ borderStyle: "round",
18
+ borderColor: color,
19
+ })
20
+ );
21
+ }
22
+
23
+ // Renders syntax highlighted code in a box
24
+ export function renderCodeBox(filename, code, language = "typescript") {
25
+ const highlighted = highlight(code, {
26
+ language,
27
+ ignoreIllegals: true,
28
+ });
29
+ renderBox(` File: ${filename} `, highlighted, "blue");
30
+ }
31
+
32
+ // Renders a git-like diff for code modifications
33
+ export function renderDiffBox(filename, original, modified) {
34
+ const diffResult = Diff.diffLines(original, modified);
35
+ let output = "";
36
+
37
+ diffResult.forEach((part) => {
38
+ // Add prefix and color based on diff status
39
+ let prefix = " ";
40
+ let colorize = chalk.dim;
41
+
42
+ if (part.added) {
43
+ prefix = chalk.green("+ ");
44
+ colorize = chalk.green;
45
+ } else if (part.removed) {
46
+ prefix = chalk.red("- ");
47
+ colorize = chalk.red;
48
+ }
49
+
50
+ // Split part into lines and format
51
+ const lines = part.value.replace(/\n$/, "").split("\n");
52
+ lines.forEach((line) => {
53
+ output += colorize(`${prefix}${line}`) + "\n";
54
+ });
55
+ });
56
+
57
+ renderBox(` Diff: ${filename} `, output.trimEnd(), "yellow");
58
+ }
59
+
60
+ export function printError(msg) {
61
+ console.log(chalk.red.bold("\n✖ Error: ") + chalk.red(msg) + "\n");
62
+ }
63
+
64
+ export function printSuccess(msg) {
65
+ console.log(chalk.green.bold("\n✔ Success: ") + chalk.green(msg) + "\n");
66
+ }
67
+
68
+ export function printStep(msg) {
69
+ console.log(chalk.cyan.bold("❯ ") + msg);
70
+ }