@dubeyvishal/orbital-cli 1.0.4 → 1.0.6
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/images/pic1.png +0 -0
- package/images/pic2.png +0 -0
- package/images/pic3.png +0 -0
- package/package.json +10 -11
- package/server/prisma/migrations/20260105143219_test_migration/migration.sql +7 -0
- package/server/prisma/migrations/20260105151026_authentication/migration.sql +78 -0
- package/server/prisma/migrations/20260114105919_add_devicecode_conversation_message/migration.sql +50 -0
- package/server/prisma/migrations/migration_lock.toml +3 -0
- package/server/prisma/schema.prisma +117 -0
- package/server/{ai → src/cli/ai}/googleService.js +4 -5
- package/server/{chat → src/cli/chat}/chat-with-ai-agent.js +43 -50
- package/server/{chat → src/cli/chat}/chat-with-ai-tools.js +70 -83
- package/server/{chat → src/cli/chat}/chat-with-ai.js +57 -69
- package/server/{commands → src/cli/commands}/General/openApp.js +13 -8
- package/server/{commands → src/cli/commands}/ai/wakeUp.js +18 -20
- package/server/{commands → src/cli/commands}/auth/aboutMe.js +3 -2
- package/server/{commands → src/cli/commands}/auth/login.js +35 -17
- package/server/{commands → src/cli/commands}/auth/logout.js +1 -1
- package/server/src/cli/commands/config/setkey.js +26 -0
- package/server/{main.js → src/cli/main.js} +1 -1
- package/server/src/cli/utils/apiClient.js +66 -0
- package/server/{config → src/config}/agentConfig.js +22 -17
- package/server/src/config/api.js +22 -0
- package/server/src/config/env.js +86 -0
- package/server/{config → src/config}/toolConfig.js +7 -0
- package/server/src/controllers/aiController.js +58 -0
- package/server/src/controllers/cliController.js +77 -0
- package/server/src/db/prisma.js +3 -0
- package/server/src/index.js +108 -0
- package/server/src/lib/auth.js +37 -0
- package/server/src/lib/credentialStore.js +47 -0
- package/server/src/lib/db.js +18 -0
- package/server/src/lib/dbHealth.js +106 -0
- package/server/src/lib/orbitalConfig.js +192 -0
- package/server/{utils → src/lib}/token.js +8 -14
- package/server/src/middleware/auth.js +39 -0
- package/server/src/middleware/errorHandler.js +11 -0
- package/server/src/prisma/migrations/20260107093841_device_flow/migration.sql +94 -0
- package/server/src/prisma/migrations/migration_lock.toml +3 -0
- package/server/src/prisma/schema.prisma +115 -0
- package/server/src/routes/authRoutes.js +14 -0
- package/server/src/routes/cliRoutes.js +18 -0
- package/server/src/service/chatService.js +156 -0
- package/server/src/services/aiService.js +10 -0
- package/server/src/services/chatService.js +1 -0
- package/server/src/types/express.d.ts +19 -0
- package/server/commands/config/setkey.js +0 -19
- package/server/config/env.js +0 -20
- package/server/utils/apiClient.js +0 -40
- package/server/utils/chatServiceClient.js +0 -73
- package/server/utils/orbitalConfig.js +0 -44
- /package/server/{commands → src/cli/commands}/General/playSong.js +0 -0
- /package/server/{commands → src/cli/commands}/General/searchYoutube.js +0 -0
- /package/server/{generalApp → src/cli/generalApp}/Apps.js +0 -0
- /package/server/{config → src/config}/googleConfig.js +0 -0
package/images/pic1.png
ADDED
|
Binary file
|
package/images/pic2.png
ADDED
|
Binary file
|
package/images/pic3.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dubeyvishal/orbital-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
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/main.js"
|
|
10
|
+
"orbital": "server/src/cli/main.js"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"server/
|
|
14
|
-
"server/
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"server/config",
|
|
18
|
-
"server/generalApp",
|
|
19
|
-
"server/utils",
|
|
20
|
-
"README.md"
|
|
13
|
+
"server/src",
|
|
14
|
+
"server/prisma",
|
|
15
|
+
"README.md",
|
|
16
|
+
"images"
|
|
21
17
|
],
|
|
22
18
|
"publishConfig": {
|
|
23
19
|
"access": "public"
|
|
@@ -36,6 +32,7 @@
|
|
|
36
32
|
"commander": "^14.0.2",
|
|
37
33
|
"dotenv": "^17.2.3",
|
|
38
34
|
"figlet": "^1.9.4",
|
|
35
|
+
"keytar": "^7.9.0",
|
|
39
36
|
"marked": "^15.0.12",
|
|
40
37
|
"marked-terminal": "^7.3.0",
|
|
41
38
|
"open": "^11.0.0",
|
|
@@ -44,6 +41,8 @@
|
|
|
44
41
|
"zod": "^4.3.5"
|
|
45
42
|
},
|
|
46
43
|
"scripts": {
|
|
44
|
+
"postinstall": "cd server && npx prisma generate",
|
|
45
|
+
"install-all": "npm install --prefix client && npm install --prefix server",
|
|
47
46
|
"start-client": "npm start --prefix client",
|
|
48
47
|
"start-server": "npm start --prefix server",
|
|
49
48
|
"dev": "npm run start-server && npm run start-client"
|
|
@@ -56,4 +55,4 @@
|
|
|
56
55
|
"client-server",
|
|
57
56
|
"javascript"
|
|
58
57
|
]
|
|
59
|
-
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "user" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"name" TEXT NOT NULL,
|
|
5
|
+
"email" TEXT NOT NULL,
|
|
6
|
+
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
|
|
7
|
+
"image" TEXT,
|
|
8
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
9
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
10
|
+
|
|
11
|
+
CONSTRAINT "user_pkey" PRIMARY KEY ("id")
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
-- CreateTable
|
|
15
|
+
CREATE TABLE "session" (
|
|
16
|
+
"id" TEXT NOT NULL,
|
|
17
|
+
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
18
|
+
"token" TEXT NOT NULL,
|
|
19
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
20
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
21
|
+
"ipAddress" TEXT,
|
|
22
|
+
"userAgent" TEXT,
|
|
23
|
+
"userId" TEXT NOT NULL,
|
|
24
|
+
|
|
25
|
+
CONSTRAINT "session_pkey" PRIMARY KEY ("id")
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
-- CreateTable
|
|
29
|
+
CREATE TABLE "account" (
|
|
30
|
+
"id" TEXT NOT NULL,
|
|
31
|
+
"accountId" TEXT NOT NULL,
|
|
32
|
+
"providerId" TEXT NOT NULL,
|
|
33
|
+
"userId" TEXT NOT NULL,
|
|
34
|
+
"accessToken" TEXT,
|
|
35
|
+
"refreshToken" TEXT,
|
|
36
|
+
"idToken" TEXT,
|
|
37
|
+
"accessTokenExpiresAt" TIMESTAMP(3),
|
|
38
|
+
"refreshTokenExpiresAt" TIMESTAMP(3),
|
|
39
|
+
"scope" TEXT,
|
|
40
|
+
"password" TEXT,
|
|
41
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
42
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
43
|
+
|
|
44
|
+
CONSTRAINT "account_pkey" PRIMARY KEY ("id")
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
-- CreateTable
|
|
48
|
+
CREATE TABLE "verification" (
|
|
49
|
+
"id" TEXT NOT NULL,
|
|
50
|
+
"identifier" TEXT NOT NULL,
|
|
51
|
+
"value" TEXT NOT NULL,
|
|
52
|
+
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
53
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
54
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
55
|
+
|
|
56
|
+
CONSTRAINT "verification_pkey" PRIMARY KEY ("id")
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
-- CreateIndex
|
|
60
|
+
CREATE UNIQUE INDEX "user_email_key" ON "user"("email");
|
|
61
|
+
|
|
62
|
+
-- CreateIndex
|
|
63
|
+
CREATE INDEX "session_userId_idx" ON "session"("userId");
|
|
64
|
+
|
|
65
|
+
-- CreateIndex
|
|
66
|
+
CREATE UNIQUE INDEX "session_token_key" ON "session"("token");
|
|
67
|
+
|
|
68
|
+
-- CreateIndex
|
|
69
|
+
CREATE INDEX "account_userId_idx" ON "account"("userId");
|
|
70
|
+
|
|
71
|
+
-- CreateIndex
|
|
72
|
+
CREATE INDEX "verification_identifier_idx" ON "verification"("identifier");
|
|
73
|
+
|
|
74
|
+
-- AddForeignKey
|
|
75
|
+
ALTER TABLE "session" ADD CONSTRAINT "session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
76
|
+
|
|
77
|
+
-- AddForeignKey
|
|
78
|
+
ALTER TABLE "account" ADD CONSTRAINT "account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
package/server/prisma/migrations/20260114105919_add_devicecode_conversation_message/migration.sql
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "deviceCode" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"deviceCode" TEXT NOT NULL,
|
|
5
|
+
"userCode" TEXT NOT NULL,
|
|
6
|
+
"userId" TEXT,
|
|
7
|
+
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
8
|
+
"status" TEXT NOT NULL,
|
|
9
|
+
"lastPolledAt" TIMESTAMP(3),
|
|
10
|
+
"pollingInterval" INTEGER,
|
|
11
|
+
"clientId" TEXT,
|
|
12
|
+
"scope" TEXT,
|
|
13
|
+
|
|
14
|
+
CONSTRAINT "deviceCode_pkey" PRIMARY KEY ("id")
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
-- CreateTable
|
|
18
|
+
CREATE TABLE "conversation" (
|
|
19
|
+
"id" TEXT NOT NULL,
|
|
20
|
+
"userId" TEXT NOT NULL,
|
|
21
|
+
"title" TEXT NOT NULL,
|
|
22
|
+
"mode" TEXT NOT NULL DEFAULT 'chat',
|
|
23
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
24
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
25
|
+
|
|
26
|
+
CONSTRAINT "conversation_pkey" PRIMARY KEY ("id")
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
-- CreateTable
|
|
30
|
+
CREATE TABLE "message" (
|
|
31
|
+
"id" TEXT NOT NULL,
|
|
32
|
+
"conversationId" TEXT NOT NULL,
|
|
33
|
+
"role" TEXT NOT NULL,
|
|
34
|
+
"content" TEXT NOT NULL,
|
|
35
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
36
|
+
|
|
37
|
+
CONSTRAINT "message_pkey" PRIMARY KEY ("id")
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
-- CreateIndex
|
|
41
|
+
CREATE INDEX "conversation_userId_idx" ON "conversation"("userId");
|
|
42
|
+
|
|
43
|
+
-- CreateIndex
|
|
44
|
+
CREATE INDEX "message_conversationId_idx" ON "message"("conversationId");
|
|
45
|
+
|
|
46
|
+
-- AddForeignKey
|
|
47
|
+
ALTER TABLE "conversation" ADD CONSTRAINT "conversation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
48
|
+
|
|
49
|
+
-- AddForeignKey
|
|
50
|
+
ALTER TABLE "message" ADD CONSTRAINT "message_conversationId_fkey" FOREIGN KEY ("conversationId") REFERENCES "conversation"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
generator client {
|
|
2
|
+
provider = "prisma-client-js"
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
datasource db {
|
|
6
|
+
provider = "postgresql"
|
|
7
|
+
url = env("DATABASE_URL")
|
|
8
|
+
directUrl = env("DIRECT_DATABASE_URL")
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
model Test {
|
|
12
|
+
id String @id @default(cuid())
|
|
13
|
+
name String
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
model User {
|
|
17
|
+
id String @id @default(cuid())
|
|
18
|
+
name String
|
|
19
|
+
email String @unique
|
|
20
|
+
emailVerified Boolean @default(false)
|
|
21
|
+
image String?
|
|
22
|
+
createdAt DateTime @default(now())
|
|
23
|
+
updatedAt DateTime @updatedAt
|
|
24
|
+
accounts Account[]
|
|
25
|
+
conversations Conversation[]
|
|
26
|
+
sessions Session[]
|
|
27
|
+
|
|
28
|
+
@@map("user")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
model Session {
|
|
32
|
+
id String @id @default(cuid())
|
|
33
|
+
expiresAt DateTime
|
|
34
|
+
token String @unique
|
|
35
|
+
createdAt DateTime @default(now())
|
|
36
|
+
updatedAt DateTime @updatedAt
|
|
37
|
+
ipAddress String?
|
|
38
|
+
userAgent String?
|
|
39
|
+
userId String
|
|
40
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
41
|
+
|
|
42
|
+
@@index([userId])
|
|
43
|
+
@@map("session")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
model Account {
|
|
47
|
+
id String @id @default(cuid())
|
|
48
|
+
accountId String
|
|
49
|
+
providerId String
|
|
50
|
+
userId String
|
|
51
|
+
accessToken String?
|
|
52
|
+
refreshToken String?
|
|
53
|
+
idToken String?
|
|
54
|
+
accessTokenExpiresAt DateTime?
|
|
55
|
+
refreshTokenExpiresAt DateTime?
|
|
56
|
+
scope String?
|
|
57
|
+
password String?
|
|
58
|
+
createdAt DateTime @default(now())
|
|
59
|
+
updatedAt DateTime @updatedAt
|
|
60
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
61
|
+
|
|
62
|
+
@@index([userId])
|
|
63
|
+
@@map("account")
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
model Verification {
|
|
67
|
+
id String @id @default(cuid())
|
|
68
|
+
identifier String
|
|
69
|
+
value String
|
|
70
|
+
expiresAt DateTime
|
|
71
|
+
createdAt DateTime @default(now())
|
|
72
|
+
updatedAt DateTime @updatedAt
|
|
73
|
+
|
|
74
|
+
@@index([identifier])
|
|
75
|
+
@@map("verification")
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
model DeviceCode {
|
|
79
|
+
id String @id @default(cuid())
|
|
80
|
+
deviceCode String
|
|
81
|
+
userCode String
|
|
82
|
+
userId String?
|
|
83
|
+
expiresAt DateTime
|
|
84
|
+
status String
|
|
85
|
+
lastPolledAt DateTime?
|
|
86
|
+
pollingInterval Int?
|
|
87
|
+
clientId String?
|
|
88
|
+
scope String?
|
|
89
|
+
|
|
90
|
+
@@map("deviceCode")
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
model Conversation {
|
|
94
|
+
id String @id @default(cuid())
|
|
95
|
+
userId String
|
|
96
|
+
title String
|
|
97
|
+
mode String @default("chat")
|
|
98
|
+
createdAt DateTime @default(now())
|
|
99
|
+
updatedAt DateTime @updatedAt
|
|
100
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
101
|
+
messages Message[]
|
|
102
|
+
|
|
103
|
+
@@index([userId])
|
|
104
|
+
@@map("conversation")
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
model Message {
|
|
108
|
+
id String @id @default(cuid())
|
|
109
|
+
conversationId String
|
|
110
|
+
role String
|
|
111
|
+
content String
|
|
112
|
+
createdAt DateTime @default(now())
|
|
113
|
+
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
114
|
+
|
|
115
|
+
@@index([conversationId])
|
|
116
|
+
@@map("message")
|
|
117
|
+
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { google } from "@ai-sdk/google";
|
|
2
2
|
import { streamText, generateObject } from "ai";
|
|
3
|
-
import { config } from "
|
|
3
|
+
import { config } from "../../config/googleConfig.js";
|
|
4
4
|
import chalk from "chalk";
|
|
5
|
+
import { requireGeminiApiKeySync } from "../../lib/orbitalConfig.js";
|
|
5
6
|
|
|
6
7
|
export class AIService {
|
|
7
8
|
constructor() {
|
|
8
|
-
|
|
9
|
-
throw new Error("GOOGLE_GENERATIVE_AI_API_KEY is not set in env");
|
|
10
|
-
}
|
|
9
|
+
const apiKey = requireGeminiApiKeySync();
|
|
11
10
|
|
|
12
11
|
this.model = google(config.model, {
|
|
13
|
-
apiKey
|
|
12
|
+
apiKey,
|
|
14
13
|
});
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -4,17 +4,18 @@ import { text, isCancel, cancel, intro, outro, confirm } from "@clack/prompts";
|
|
|
4
4
|
import yoctoSpinner from "yocto-spinner";
|
|
5
5
|
import { marked } from "marked";
|
|
6
6
|
import { markedTerminal } from "marked-terminal";
|
|
7
|
+
import { getStoredToken } from "../../lib/token.js";
|
|
8
|
+
import {
|
|
9
|
+
createApplicationFiles,
|
|
10
|
+
displayFileTree,
|
|
11
|
+
generateApplicationPlan,
|
|
12
|
+
} from "../../config/agentConfig.js";
|
|
13
|
+
import { apiRequestSafe } from "../utils/apiClient.js";
|
|
7
14
|
import { AIService } from "../ai/googleService.js";
|
|
8
|
-
import {
|
|
9
|
-
import { getStoredToken } from "../utils/token.js";
|
|
10
|
-
|
|
11
|
-
import { generateApplication } from "../config/agentConfig.js";
|
|
15
|
+
import { requireGeminiApiKey } from "../../lib/orbitalConfig.js";
|
|
12
16
|
|
|
13
17
|
marked.use(markedTerminal());
|
|
14
18
|
|
|
15
|
-
let aiService;
|
|
16
|
-
const chatService = new ChatService();
|
|
17
|
-
|
|
18
19
|
const getEnabledToolNames = () => {
|
|
19
20
|
return [];
|
|
20
21
|
};
|
|
@@ -27,39 +28,30 @@ const getUserFromToken = async () => {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
const spinner = yoctoSpinner({ text: "Authenticating..." }).start();
|
|
30
|
-
|
|
31
|
-
let user;
|
|
32
31
|
try {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
Authorization: `Bearer ${token.access_token}`
|
|
36
|
-
}
|
|
37
|
-
});
|
|
32
|
+
const result = await apiRequestSafe("/api/cli/me");
|
|
33
|
+
const user = result?.user;
|
|
38
34
|
|
|
39
|
-
if (!
|
|
40
|
-
|
|
35
|
+
if (!user) {
|
|
36
|
+
spinner.error("User not found");
|
|
37
|
+
throw new Error("User not found. Please login again");
|
|
41
38
|
}
|
|
42
|
-
const data = await response.json();
|
|
43
|
-
user = data?.user;
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
spinner.success(`Welcome back, ${user.name}!`);
|
|
41
|
+
return user;
|
|
42
|
+
} finally {
|
|
43
|
+
spinner.stop();
|
|
49
44
|
}
|
|
50
|
-
|
|
51
|
-
spinner.success(`Welcome back, ${user.name}!`);
|
|
52
|
-
return user;
|
|
53
45
|
};
|
|
54
46
|
|
|
55
47
|
const initConversation = async (userId, conversationId = null, mode = "tool") => {
|
|
56
48
|
const spinner = yoctoSpinner({ text: "Loading conversation..." }).start();
|
|
57
49
|
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
conversationId,
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
const result = await apiRequestSafe("/api/cli/conversations/init", {
|
|
51
|
+
method: "POST",
|
|
52
|
+
body: { conversationId, mode },
|
|
53
|
+
});
|
|
54
|
+
const conversation = result?.conversation;
|
|
63
55
|
|
|
64
56
|
spinner.success("Conversation Loaded");
|
|
65
57
|
|
|
@@ -90,7 +82,10 @@ const initConversation = async (userId, conversationId = null, mode = "tool") =>
|
|
|
90
82
|
};
|
|
91
83
|
|
|
92
84
|
const saveMessage = async (conversationId, role, content) => {
|
|
93
|
-
return await
|
|
85
|
+
return await apiRequestSafe("/api/cli/messages", {
|
|
86
|
+
method: "POST",
|
|
87
|
+
body: { conversationId, role, content },
|
|
88
|
+
});
|
|
94
89
|
};
|
|
95
90
|
|
|
96
91
|
const agentLoop = async (conversation) => {
|
|
@@ -154,21 +149,27 @@ const agentLoop = async (conversation) => {
|
|
|
154
149
|
await saveMessage(conversation.id, "user", userInput);
|
|
155
150
|
|
|
156
151
|
try {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
process.cwd()
|
|
161
|
-
);
|
|
152
|
+
await requireGeminiApiKey();
|
|
153
|
+
const aiService = new AIService();
|
|
154
|
+
const application = await generateApplicationPlan(userInput, aiService);
|
|
162
155
|
|
|
163
|
-
if (!
|
|
164
|
-
throw new Error("Generation returned no
|
|
156
|
+
if (!application || !Array.isArray(application.files) || application.files.length === 0) {
|
|
157
|
+
throw new Error("Generation returned no files.");
|
|
165
158
|
}
|
|
166
159
|
|
|
160
|
+
displayFileTree(application.files, application.folderName);
|
|
161
|
+
|
|
162
|
+
const appDir = await createApplicationFiles(
|
|
163
|
+
process.cwd(),
|
|
164
|
+
application.folderName,
|
|
165
|
+
application.files
|
|
166
|
+
);
|
|
167
|
+
|
|
167
168
|
const responseMessage =
|
|
168
|
-
`Generated application: ${
|
|
169
|
-
`Files created: ${
|
|
170
|
-
`Location: ${
|
|
171
|
-
`Setup commands:\n${
|
|
169
|
+
`Generated application: ${application.folderName}\n` +
|
|
170
|
+
`Files created: ${application.files.length}\n` +
|
|
171
|
+
`Location: ${appDir}\n\n` +
|
|
172
|
+
`Setup commands:\n${(application.setupCommands || []).join("\n")}`;
|
|
172
173
|
|
|
173
174
|
console.log(
|
|
174
175
|
boxen(chalk.green(responseMessage), {
|
|
@@ -210,14 +211,6 @@ const agentLoop = async (conversation) => {
|
|
|
210
211
|
|
|
211
212
|
export const startAgentChat = async (conversationId = null) => {
|
|
212
213
|
try {
|
|
213
|
-
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY) {
|
|
214
|
-
throw new Error(
|
|
215
|
-
"Gemini API key is not set. Run: orbital setkey <your-gemini-api-key>"
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
aiService = new AIService();
|
|
220
|
-
|
|
221
214
|
intro(
|
|
222
215
|
boxen(
|
|
223
216
|
chalk.bold.magenta("Orbital AI - Agent Mode\n\n") +
|