@dubeyvishal/orbital-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 +13 -0
- package/package.json +10 -7
- package/server/{src/cli/ai → ai}/googleService.js +1 -1
- package/server/{src/cli/chat → chat}/chat-with-ai-agent.js +21 -22
- package/server/{src/cli/chat → chat}/chat-with-ai-tools.js +22 -21
- package/server/{src/cli/chat → chat}/chat-with-ai.js +21 -18
- package/server/commands/General/openApp.js +71 -0
- package/server/commands/General/playSong.js +17 -0
- package/server/commands/General/searchYoutube.js +21 -0
- package/server/{src/cli/commands → commands}/ai/wakeUp.js +19 -28
- package/server/{src/cli/commands → commands}/auth/aboutMe.js +1 -1
- package/server/{src/cli/commands → commands}/auth/login.js +1 -1
- package/server/{src/cli/commands → commands}/auth/logout.js +1 -1
- package/server/{src/cli/commands → commands}/config/setkey.js +1 -1
- package/server/config/env.js +20 -0
- package/server/generalApp/Apps.js +21 -0
- package/server/{src/cli/main.js → main.js} +11 -3
- package/server/utils/apiClient.js +40 -0
- package/server/utils/chatServiceClient.js +73 -0
- package/server/prisma/migrations/20260105143219_test_migration/migration.sql +0 -7
- package/server/prisma/migrations/20260105151026_authentication/migration.sql +0 -78
- package/server/prisma/migrations/20260114105919_add_devicecode_conversation_message/migration.sql +0 -50
- package/server/prisma/migrations/migration_lock.toml +0 -3
- package/server/prisma/schema.prisma +0 -117
- package/server/src/config/env.js +0 -100
- package/server/src/index.js +0 -102
- package/server/src/lib/auth.js +0 -37
- package/server/src/lib/db.js +0 -18
- package/server/src/lib/dbHealth.js +0 -106
- package/server/src/prisma/migrations/20260107093841_device_flow/migration.sql +0 -94
- package/server/src/prisma/migrations/migration_lock.toml +0 -3
- package/server/src/prisma/schema.prisma +0 -115
- package/server/src/service/chatService.js +0 -156
- /package/server/{src/config → config}/agentConfig.js +0 -0
- /package/server/{src/config → config}/googleConfig.js +0 -0
- /package/server/{src/config → config}/toolConfig.js +0 -0
- /package/server/{src/lib → utils}/orbitalConfig.js +0 -0
- /package/server/{src/lib → utils}/token.js +0 -0
package/README.md
CHANGED
|
@@ -6,6 +6,19 @@ Built with **Next.js**, **Node.js**, **Express**, and **Commander.js**, with sec
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## 📸 Project Screenshots
|
|
10
|
+
|
|
11
|
+
### 🔐 Orbital Login Screen
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
### 🛠️ Orbital Wakeup – Tools Loaded
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
### 🤖 Agentic Mode
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
9
22
|
## ✨ Features
|
|
10
23
|
|
|
11
24
|
### AI Chat Mode
|
package/package.json
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dubeyvishal/orbital-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A fullstack CLI-based AI platform with chat mode, multi-tool agents, and agentic AI workflows. Includes GitHub login with device authorization, secure authentication, and modular client–server architecture for building intelligent automation tools.",
|
|
5
5
|
"author": "Vishal Dubey",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
8
8
|
"type": "module",
|
|
9
9
|
"bin": {
|
|
10
|
-
"orbital": "server/
|
|
10
|
+
"orbital": "server/main.js"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"server/
|
|
14
|
-
"server/
|
|
13
|
+
"server/main.js",
|
|
14
|
+
"server/commands",
|
|
15
|
+
"server/chat",
|
|
16
|
+
"server/ai",
|
|
17
|
+
"server/config",
|
|
18
|
+
"server/generalApp",
|
|
19
|
+
"server/utils",
|
|
15
20
|
"README.md"
|
|
16
21
|
],
|
|
17
22
|
"publishConfig": {
|
|
@@ -39,8 +44,6 @@
|
|
|
39
44
|
"zod": "^4.3.5"
|
|
40
45
|
},
|
|
41
46
|
"scripts": {
|
|
42
|
-
"postinstall": "cd server && npx prisma generate",
|
|
43
|
-
"install-all": "npm install --prefix client && npm install --prefix server",
|
|
44
47
|
"start-client": "npm start --prefix client",
|
|
45
48
|
"start-server": "npm start --prefix server",
|
|
46
49
|
"dev": "npm run start-server && npm run start-client"
|
|
@@ -53,4 +56,4 @@
|
|
|
53
56
|
"client-server",
|
|
54
57
|
"javascript"
|
|
55
58
|
]
|
|
56
|
-
}
|
|
59
|
+
}
|
|
@@ -5,11 +5,10 @@ import yoctoSpinner from "yocto-spinner";
|
|
|
5
5
|
import { marked } from "marked";
|
|
6
6
|
import { markedTerminal } from "marked-terminal";
|
|
7
7
|
import { AIService } from "../ai/googleService.js";
|
|
8
|
-
import { ChatService } from "
|
|
9
|
-
import { getStoredToken } from "
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
import { generateApplication } from "../../config/agentConfig.js";
|
|
8
|
+
import { ChatServiceClient as ChatService } from "../utils/chatServiceClient.js";
|
|
9
|
+
import { getStoredToken } from "../utils/token.js";
|
|
10
|
+
|
|
11
|
+
import { generateApplication } from "../config/agentConfig.js";
|
|
13
12
|
|
|
14
13
|
marked.use(markedTerminal());
|
|
15
14
|
|
|
@@ -27,26 +26,26 @@ const getUserFromToken = async () => {
|
|
|
27
26
|
throw new Error("Not authenticated. Please run 'orbital login' first.");
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
const dbOk = await ensureDbConnection();
|
|
31
|
-
if (!dbOk) {
|
|
32
|
-
throw new Error(
|
|
33
|
-
"Database unavailable. Fix DATABASE_URL/connectivity and try again."
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
29
|
const spinner = yoctoSpinner({ text: "Authenticating..." }).start();
|
|
38
30
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
let user;
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch("https://smart-cli-based-agent.onrender.com/api/me", {
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${token.access_token}`
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
throw new Error("Failed to authenticate.");
|
|
41
|
+
}
|
|
42
|
+
const data = await response.json();
|
|
43
|
+
user = data?.user;
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
if (!user) throw new Error("User not found");
|
|
46
|
+
} catch(err) {
|
|
47
|
+
spinner.error("Authentication failed");
|
|
48
|
+
throw new Error("User not found or connection failed. Please login again.");
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
spinner.success(`Welcome back, ${user.name}!`);
|
|
@@ -12,17 +12,16 @@ import yoctoSpinner from "yocto-spinner";
|
|
|
12
12
|
import { marked } from "marked";
|
|
13
13
|
import { markedTerminal } from "marked-terminal";
|
|
14
14
|
import { AIService } from "../ai/googleService.js";
|
|
15
|
-
import { ChatService } from "
|
|
16
|
-
import { getStoredToken } from "
|
|
17
|
-
|
|
18
|
-
import { ensureDbConnection } from "../../lib/dbHealth.js";
|
|
15
|
+
import { ChatServiceClient as ChatService } from "../utils/chatServiceClient.js";
|
|
16
|
+
import { getStoredToken } from "../utils/token.js";
|
|
17
|
+
|
|
19
18
|
import {
|
|
20
19
|
availableTools,
|
|
21
20
|
enableTools,
|
|
22
21
|
getEnabledTools,
|
|
23
22
|
getEnabledToolNames,
|
|
24
23
|
resetTools,
|
|
25
|
-
} from "
|
|
24
|
+
} from "../config/toolConfig.js";
|
|
26
25
|
|
|
27
26
|
marked.use(
|
|
28
27
|
markedTerminal({
|
|
@@ -53,24 +52,26 @@ const getUserFromToken = async () => {
|
|
|
53
52
|
throw new Error("Not authenticated. Please run 'orbital login' first.");
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
const dbOk = await ensureDbConnection();
|
|
57
|
-
if (!dbOk) {
|
|
58
|
-
throw new Error("Database unavailable. Fix DATABASE_URL/connectivity and try again.");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
55
|
const spinner = yoctoSpinner({ text: "Authenticating..." }).start();
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
57
|
+
let user;
|
|
58
|
+
try {
|
|
59
|
+
const response = await fetch("https://smart-cli-based-agent.onrender.com/api/me", {
|
|
60
|
+
headers: {
|
|
61
|
+
Authorization: `Bearer ${token.access_token}`
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new Error("Failed to authenticate.");
|
|
67
|
+
}
|
|
68
|
+
const data = await response.json();
|
|
69
|
+
user = data?.user;
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
if (!user) throw new Error("User not found");
|
|
72
|
+
} catch(err) {
|
|
73
|
+
spinner.error("Authentication failed");
|
|
74
|
+
throw new Error("User not found or connection failed. Please login again.");
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
spinner.success(`Welcome back, ${user.name}!`);
|
|
@@ -88,7 +89,7 @@ const selectTools = async () => {
|
|
|
88
89
|
const toolOptions = availableTools.map((tool) => ({
|
|
89
90
|
value: tool.id,
|
|
90
91
|
label: tool.name,
|
|
91
|
-
|
|
92
|
+
|
|
92
93
|
hint: truncateHint(tool.description),
|
|
93
94
|
}));
|
|
94
95
|
|
|
@@ -5,10 +5,9 @@ import yoctoSpinner from "yocto-spinner";
|
|
|
5
5
|
import {marked} from "marked";
|
|
6
6
|
import {markedTerminal} from "marked-terminal";
|
|
7
7
|
import {AIService} from "../ai/googleService.js";
|
|
8
|
-
import {ChatService} from "
|
|
9
|
-
import {getStoredToken} from "
|
|
10
|
-
|
|
11
|
-
import { ensureDbConnection } from "../../lib/dbHealth.js";
|
|
8
|
+
import { ChatServiceClient as ChatService } from "../utils/chatServiceClient.js";
|
|
9
|
+
import {getStoredToken} from "../utils/token.js";
|
|
10
|
+
|
|
12
11
|
|
|
13
12
|
marked.use(
|
|
14
13
|
markedTerminal({
|
|
@@ -38,22 +37,26 @@ const getUserFromToken = async()=>{
|
|
|
38
37
|
throw new Error("Not authenticated. Please run 'orbital login' first.");
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
const dbOk = await ensureDbConnection();
|
|
42
|
-
if(!dbOk){
|
|
43
|
-
throw new Error("Database unavailable. Fix DATABASE_URL/connectivity and try again.");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
40
|
const spinner = yoctoSpinner({text: "Authenticating..."}).start();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
|
|
42
|
+
let user;
|
|
43
|
+
try {
|
|
44
|
+
const response = await fetch("https://smart-cli-based-agent.onrender.com/api/me", {
|
|
45
|
+
headers: {
|
|
46
|
+
Authorization: `Bearer ${token.access_token}`
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new Error("Failed to authenticate.");
|
|
51
|
+
}
|
|
52
|
+
const data = await response.json();
|
|
53
|
+
user = data?.user;
|
|
54
|
+
if (!user) throw new Error("User not found");
|
|
55
|
+
} catch(err) {
|
|
56
|
+
spinner.error("Authentication failed");
|
|
57
|
+
throw new Error("User not found or connection failed. Please login again.");
|
|
56
58
|
}
|
|
59
|
+
|
|
57
60
|
spinner.success(`Welcome back , ${user.name}!`);
|
|
58
61
|
return user;
|
|
59
62
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import yoctoSpinner from "yocto-spinner";
|
|
4
|
+
import { getApiClient } from "../../utils/apiClient.js";
|
|
5
|
+
import {openGithub , openLinkedin , openLeetcode , openGmail , openWhatsApp} from "../../generalApp/Apps.js"
|
|
6
|
+
|
|
7
|
+
const openAppAction = async () => {
|
|
8
|
+
const spinner = yoctoSpinner({ text: "Fetching user information..." });
|
|
9
|
+
spinner.start();
|
|
10
|
+
|
|
11
|
+
let user;
|
|
12
|
+
try {
|
|
13
|
+
const api = await getApiClient();
|
|
14
|
+
const res = await api.get("/api/me");
|
|
15
|
+
user = res.user;
|
|
16
|
+
} catch (err) {
|
|
17
|
+
console.log(chalk.red(err.message));
|
|
18
|
+
return;
|
|
19
|
+
} finally {
|
|
20
|
+
spinner.stop();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!user) {
|
|
24
|
+
console.log(chalk.red("User not found."));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log(chalk.green(`Welcome back, ${user.name}!\n`));
|
|
29
|
+
|
|
30
|
+
while (true) {
|
|
31
|
+
const choice = await select({
|
|
32
|
+
message: chalk.yellow("Select the app to open"),
|
|
33
|
+
options: [
|
|
34
|
+
{ value: "github", label: "GitHub", hint: "View repositories & projects" },
|
|
35
|
+
{ value: "whatsapp", label: "WhatsApp", hint: "Open messaging app" },
|
|
36
|
+
{ value: "gmail", label: "Gmail", hint: "Check emails quickly" },
|
|
37
|
+
{ value: "linkedin", label: "LinkedIn", hint: "View connections & jobs" },
|
|
38
|
+
{ value: "leetcode", label: "LeetCode", hint: "Practice coding problems" },
|
|
39
|
+
{ value: "exit", label: "Exit", hint: "Close launcher" },
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (choice === "exit") {
|
|
44
|
+
console.log(" Exiting launcher...");
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
switch (choice) {
|
|
49
|
+
case "github":
|
|
50
|
+
openGithub();
|
|
51
|
+
break;
|
|
52
|
+
case "gmail":
|
|
53
|
+
openGmail();
|
|
54
|
+
break;
|
|
55
|
+
case "leetcode":
|
|
56
|
+
openLeetcode();
|
|
57
|
+
break;
|
|
58
|
+
case "linkedin":
|
|
59
|
+
openLinkedin();
|
|
60
|
+
break;
|
|
61
|
+
case "whatsapp":
|
|
62
|
+
openWhatsApp();
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const launch = new Command("launch")
|
|
69
|
+
.description("Open external apps like GitHub, WhatsApp, etc.")
|
|
70
|
+
.alias("open")
|
|
71
|
+
.action(openAppAction);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { exec } from "child_process";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
|
|
5
|
+
const playAction = (songParts) => {
|
|
6
|
+
const song = songParts.join(" ");
|
|
7
|
+
const encoded = encodeURIComponent(song);
|
|
8
|
+
|
|
9
|
+
console.log(chalk.green(`Searching "${song}" on Spotify ...`));
|
|
10
|
+
|
|
11
|
+
exec(`start /min "" spotify:search:${encoded}`);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const play = new Command("play")
|
|
15
|
+
.description("Search and open Spotify minimized")
|
|
16
|
+
.argument("<song...>", "Song name to search")
|
|
17
|
+
.action(playAction);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { exec } from "child_process";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
|
|
5
|
+
const searchYoutubeAction = (query) => {
|
|
6
|
+
if (!query) {
|
|
7
|
+
console.log(chalk.red("Please provide a search query."));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const encodedQuery = encodeURIComponent(query); //removes the special characters so that url does not break
|
|
12
|
+
const url = `https://www.youtube.com/results?search_query=${encodedQuery}`;
|
|
13
|
+
|
|
14
|
+
console.log(chalk.green(`Searching YouTube for: "${query}"`));
|
|
15
|
+
exec(`start "" "${url}"`);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const search = new Command("search")
|
|
19
|
+
.description("Search videos on YouTube")
|
|
20
|
+
.argument("<query>", "Search term")
|
|
21
|
+
.action(searchYoutubeAction);
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import {Command} from "commander";
|
|
3
3
|
import yoctoSpinner from "yocto-spinner";
|
|
4
|
-
import {getStoredToken} from "
|
|
5
|
-
|
|
6
|
-
import { ensureDbConnection } from "../../../lib/dbHealth.js";
|
|
4
|
+
import {getStoredToken} from "../../utils/token.js"
|
|
5
|
+
|
|
7
6
|
import {select} from "@clack/prompts";
|
|
8
|
-
import {startChat} from "
|
|
9
|
-
import {startToolChat} from "
|
|
10
|
-
import {startAgentChat} from "
|
|
7
|
+
import {startChat} from "../../chat/chat-with-ai.js";
|
|
8
|
+
import {startToolChat} from "../../chat/chat-with-ai-tools.js";
|
|
9
|
+
import {startAgentChat} from "../../chat/chat-with-ai-agent.js";
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
const wakeUpAction = async()=>{
|
|
@@ -17,31 +16,23 @@ const wakeUpAction = async()=>{
|
|
|
17
16
|
return ;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
const dbOk = await ensureDbConnection();
|
|
21
|
-
if(!dbOk){
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const spinner = yoctoSpinner({text: "Fetching user information ..."})
|
|
26
|
-
spinner.start()
|
|
27
|
-
|
|
28
19
|
let user;
|
|
29
20
|
try{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
token : token.access_token
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
select : {
|
|
39
|
-
id : true ,
|
|
40
|
-
name : true ,
|
|
41
|
-
email : true ,
|
|
42
|
-
image : true
|
|
43
|
-
}
|
|
21
|
+
const response = await fetch("https://smart-cli-based-agent.onrender.com/api/me", {
|
|
22
|
+
headers: {
|
|
23
|
+
Authorization: `Bearer ${token.access_token}`
|
|
24
|
+
}
|
|
44
25
|
});
|
|
26
|
+
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
throw new Error("Failed to authenticate.");
|
|
29
|
+
}
|
|
30
|
+
const data = await response.json();
|
|
31
|
+
user = data?.user;
|
|
32
|
+
|
|
33
|
+
if (!user) throw new Error("User not found");
|
|
34
|
+
} catch(err) {
|
|
35
|
+
console.log(chalk.red("Failed to authenticate with server."));
|
|
45
36
|
}
|
|
46
37
|
finally{
|
|
47
38
|
spinner.stop();
|
|
@@ -10,7 +10,7 @@ import { createAuthClient } from "better-auth/client";
|
|
|
10
10
|
import { deviceAuthorizationClient } from "better-auth/client/plugins";
|
|
11
11
|
import { logger } from "better-auth";
|
|
12
12
|
import { fileURLToPath } from "url";
|
|
13
|
-
import { getStoredToken, isTokenExpired, storeToken ,TOKEN_FILE } from "
|
|
13
|
+
import { getStoredToken, isTokenExpired, storeToken ,TOKEN_FILE } from "../../utils/token.js";
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { cancel, confirm, intro, outro, isCancel } from "@clack/prompts";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
-
import { clearStoredToken, getStoredToken } from "
|
|
4
|
+
import { clearStoredToken, getStoredToken } from "../../utils/token.js";
|
|
5
5
|
|
|
6
6
|
export const logoutAction = async()=>{
|
|
7
7
|
intro(chalk.bold("Logout"));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
-
import { setGeminiApiKey, ORBITAL_CONFIG_FILE } from "
|
|
3
|
+
import { setGeminiApiKey, ORBITAL_CONFIG_FILE } from "../../utils/orbitalConfig.js";
|
|
4
4
|
|
|
5
5
|
const setKeyAction = async (apiKey) => {
|
|
6
6
|
try {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
|
|
5
|
+
// Load Orbital user config (stored in the user's home directory) and
|
|
6
|
+
// hydrate env vars if they are not already set.
|
|
7
|
+
try {
|
|
8
|
+
const orbitalConfigPath = path.join(os.homedir(), ".orbital", "config.json");
|
|
9
|
+
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY && fs.existsSync(orbitalConfigPath)) {
|
|
10
|
+
const raw = fs.readFileSync(orbitalConfigPath, "utf-8");
|
|
11
|
+
const parsed = JSON.parse(raw);
|
|
12
|
+
if (parsed?.geminiApiKey && typeof parsed.geminiApiKey === "string") {
|
|
13
|
+
process.env.GOOGLE_GENERATIVE_AI_API_KEY = parsed.geminiApiKey.trim();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
} catch {
|
|
17
|
+
// ignore
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
const openApp = (url, name) => {
|
|
5
|
+
console.log(chalk.green(`Opening ${name}...`));
|
|
6
|
+
exec(`start "" "${url}"`);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const openGithub = () => openApp("https://github.com", "GitHub");
|
|
10
|
+
export const openGmail = () => openApp("https://gmail.com", "Gmail");
|
|
11
|
+
export const openLeetcode = () => openApp("https://leetcode.com", "LeetCode");
|
|
12
|
+
export const openLinkedin = () => openApp("https://linkedin.com", "LinkedIn");
|
|
13
|
+
|
|
14
|
+
export const openWhatsApp = () => {
|
|
15
|
+
exec("start whatsapp:", (err) => {
|
|
16
|
+
if (err) {
|
|
17
|
+
exec('start "" "https://web.whatsapp.com"');
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import "
|
|
3
|
+
import "./config/env.js";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import figlet from "figlet";
|
|
6
6
|
import {Command} from "commander";
|
|
@@ -9,6 +9,9 @@ import {logout} from "./commands/auth/logout.js"
|
|
|
9
9
|
import {whoAmI} from "./commands/auth/aboutMe.js"
|
|
10
10
|
import {wakeUp} from "./commands/ai/wakeUp.js"
|
|
11
11
|
import {setkey} from "./commands/config/setkey.js"
|
|
12
|
+
import {launch} from "./commands/General/openApp.js"
|
|
13
|
+
import {search} from "./commands/General/searchYoutube.js"
|
|
14
|
+
import {play} from "./commands/General/playSong.js"
|
|
12
15
|
|
|
13
16
|
const main = async()=>{
|
|
14
17
|
|
|
@@ -23,6 +26,8 @@ const main = async()=>{
|
|
|
23
26
|
console.log(chalk.yellow(" A CLI Based AI Tool \n"));
|
|
24
27
|
|
|
25
28
|
const program = new Command("orbital");
|
|
29
|
+
|
|
30
|
+
|
|
26
31
|
|
|
27
32
|
program.version("0.0.1").
|
|
28
33
|
description("Orbital CLI - A CLI Based AI Tool").
|
|
@@ -30,7 +35,10 @@ const main = async()=>{
|
|
|
30
35
|
addCommand(logout).
|
|
31
36
|
addCommand(whoAmI).
|
|
32
37
|
addCommand(wakeUp).
|
|
33
|
-
addCommand(setkey)
|
|
38
|
+
addCommand(setkey).
|
|
39
|
+
addCommand(launch).
|
|
40
|
+
addCommand(search).
|
|
41
|
+
addCommand(play)
|
|
34
42
|
|
|
35
43
|
program.action(()=>{
|
|
36
44
|
program.help();
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getStoredToken } from "./token.js";
|
|
2
|
+
|
|
3
|
+
const BASE_URL = process.env.API_URL || "https://smart-cli-based-agent.onrender.com";
|
|
4
|
+
|
|
5
|
+
export const getApiClient = async () => {
|
|
6
|
+
const token = await getStoredToken();
|
|
7
|
+
if (!token?.access_token) {
|
|
8
|
+
throw new Error("Not authenticated. Please run 'orbital login' first.");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const headers = {
|
|
12
|
+
"Authorization": `Bearer ${token.access_token}`,
|
|
13
|
+
"Content-Type": "application/json"
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
get: async (endpoint) => {
|
|
18
|
+
const res = await fetch(`${BASE_URL}${endpoint}`, { headers });
|
|
19
|
+
if (!res.ok) {
|
|
20
|
+
let msg = res.statusText;
|
|
21
|
+
try { const errData = await res.json(); msg = errData.error || msg; } catch {}
|
|
22
|
+
throw new Error(`API Error: ${msg}`);
|
|
23
|
+
}
|
|
24
|
+
return res.json();
|
|
25
|
+
},
|
|
26
|
+
post: async (endpoint, data) => {
|
|
27
|
+
const res = await fetch(`${BASE_URL}${endpoint}`, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers,
|
|
30
|
+
body: JSON.stringify(data)
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
let msg = res.statusText;
|
|
34
|
+
try { const errData = await res.json(); msg = errData.error || msg; } catch {}
|
|
35
|
+
throw new Error(`API Error: ${msg}`);
|
|
36
|
+
}
|
|
37
|
+
return res.json();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|