lua-cli 1.3.2-alpha.2 → 2.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.
- package/CHANGELOG.md +25 -0
- package/README.md +2 -2
- package/dist/commands/agents.js +1 -1
- package/dist/commands/apiKey.js +2 -4
- package/dist/commands/compile.js +632 -973
- package/dist/commands/deploy.js +1 -1
- package/dist/commands/dev.js +352 -81
- package/dist/commands/init.js +52 -78
- package/dist/commands/push.js +1 -1
- package/dist/commands/test.js +49 -11
- package/dist/index.js +7 -9
- package/dist/services/api.d.ts +4 -1
- package/dist/services/api.js +7 -6
- package/dist/services/auth.d.ts +0 -4
- package/dist/services/auth.js +2 -129
- package/dist/skill.d.ts +5 -0
- package/dist/skill.js +6 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/utils/files.d.ts +1 -1
- package/dist/utils/files.js +13 -28
- package/dist/utils/sandbox.d.ts +8 -70
- package/dist/utils/sandbox.js +153 -7
- package/dist/web/app.css +4709 -796
- package/dist/web/app.js +22 -20
- package/dist/web/tools-page.css +0 -13
- package/package.json +4 -2
- package/template/env.example +17 -0
- package/template/lua.skill.yaml +14 -15
- package/template/package.json +3 -1
- package/template/src/index.ts +46 -6
- package/template/src/seed.ts +46 -0
- package/template/src/tools/GetWeatherTool.ts +32 -15
- package/template/src/tools/PaymentTool.ts +51 -0
- package/template/src/tools/SearchProducts.ts +43 -0
- package/dist/commands/deploy-new.d.ts +0 -0
- package/dist/commands/deploy-new.js +0 -130
- package/template/package-lock.json +0 -1523
package/dist/web/tools-page.css
CHANGED
|
@@ -16,19 +16,6 @@
|
|
|
16
16
|
gap: 16px;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
.loading-spinner {
|
|
20
|
-
width: 32px;
|
|
21
|
-
height: 32px;
|
|
22
|
-
border: 3px solid #3e3e42;
|
|
23
|
-
border-top: 3px solid #007acc;
|
|
24
|
-
border-radius: 50%;
|
|
25
|
-
animation: spin 1s linear infinite;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@keyframes spin {
|
|
29
|
-
0% { transform: rotate(0deg); }
|
|
30
|
-
100% { transform: rotate(360deg); }
|
|
31
|
-
}
|
|
32
19
|
|
|
33
20
|
/* Tools List View */
|
|
34
21
|
.tools-list-view {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lua-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Command-line interface for Lua AI platform - develop, test, and deploy LuaSkills with custom tools",
|
|
5
5
|
"readmeFilename": "README.md",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -66,8 +66,10 @@
|
|
|
66
66
|
"react": "^18.2.0",
|
|
67
67
|
"react-dom": "^18.2.0",
|
|
68
68
|
"socket.io-client": "^4.7.2",
|
|
69
|
+
"ts-morph": "^27.0.0",
|
|
69
70
|
"ws": "^8.18.3",
|
|
70
|
-
"zod": "^
|
|
71
|
+
"zod": "^3.24.1",
|
|
72
|
+
"zod-to-json-schema": "^3.24.6"
|
|
71
73
|
},
|
|
72
74
|
"devDependencies": {
|
|
73
75
|
"@types/inquirer": "^9.0.9",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Example environment variables file
|
|
2
|
+
# Copy this to .env and update with your actual API keys
|
|
3
|
+
|
|
4
|
+
# OpenAI API Key (for AI tools)
|
|
5
|
+
OPENAI_API_KEY=your-openai-api-key-here
|
|
6
|
+
|
|
7
|
+
# Pinecone API Key (for vector search tools)
|
|
8
|
+
PINECONE_API_KEY=your-pinecone-api-key-here
|
|
9
|
+
|
|
10
|
+
# Stripe API Key (for payment tools)
|
|
11
|
+
STRIPE_SECRET_KEY=your-stripe-secret-key-here
|
|
12
|
+
|
|
13
|
+
# Custom application settings
|
|
14
|
+
BASE_URL=http://localhost:3000
|
|
15
|
+
API_KEY=your-api-key-here
|
|
16
|
+
|
|
17
|
+
# Note: Values in lua.skill.yaml will override values in this .env file
|
package/template/lua.skill.yaml
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
agent:
|
|
2
|
-
agentId:
|
|
3
|
-
orgId:
|
|
4
|
-
persona:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
PINECONE_API_KEY: "pcsk_5iFtQD_CzPDnQgjMwhDgVKwJhiYRq53U7agFc6yXiiwwJrTeEWoh1BveSZzvZwA8ZVXoky"
|
|
2
|
+
agentId: baseAgent_agent_1758705162448_cyu7ybbhx
|
|
3
|
+
orgId: ae25d3f8-5446-4135-806f-daf4ec55d010
|
|
4
|
+
persona: Your name is Stefan always remember that
|
|
5
|
+
welcomeMessage: 'Hi, I am your AI assistant. How can I help you today?'
|
|
6
|
+
skills:
|
|
7
|
+
- name: general-skill
|
|
8
|
+
version: 0.0.2
|
|
9
|
+
skillId: 24294a5a-bd95-4167-89b1-aebad352196a
|
|
10
|
+
- name: user-data-skill
|
|
11
|
+
version: 0.0.1
|
|
12
|
+
skillId: 5c167305-9f59-4e20-84e9-fd1b50856ec4
|
|
13
|
+
- name: eccomerce-skill
|
|
14
|
+
version: 0.0.1
|
|
15
|
+
skillId: dbec43db-9786-4223-9eac-8087d976d22d
|
package/template/package.json
CHANGED
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
+
"@pinecone-database/pinecone": "^6.1.2",
|
|
16
17
|
"@types/inquirer": "^9.0.9",
|
|
17
18
|
"@types/js-yaml": "^4.0.9",
|
|
18
19
|
"axios": "^1.6.0",
|
|
19
20
|
"inquirer": "^12.9.6",
|
|
20
21
|
"js-yaml": "^4.1.0",
|
|
21
|
-
"lua-cli": "
|
|
22
|
+
"lua-cli": "2.0.0",
|
|
23
|
+
"openai": "^5.23.0",
|
|
22
24
|
"zod": "^4.1.9"
|
|
23
25
|
},
|
|
24
26
|
"devDependencies": {
|
package/template/src/index.ts
CHANGED
|
@@ -1,15 +1,50 @@
|
|
|
1
1
|
import { LuaSkill } from "lua-cli/skill";
|
|
2
|
-
|
|
3
2
|
import GetWeatherTool from "./tools/GetWeatherTool";
|
|
4
3
|
import { GetUserDataTool, CreateUserDataTool, UpdateUserDataTool } from "./tools/UserDataTool";
|
|
5
4
|
import CreatePostTool from "./tools/CreatePostTool";
|
|
5
|
+
import { SearchProductsTool } from "./tools/SearchProducts";
|
|
6
|
+
import CreatePaymentLinkTool from "./tools/PaymentTool";
|
|
6
7
|
|
|
7
8
|
// Initialize skill with tools
|
|
8
|
-
const
|
|
9
|
+
const generalSkill = new LuaSkill({
|
|
10
|
+
name: "general-skill",
|
|
11
|
+
version: "0.0.2",
|
|
9
12
|
description: "A comprehensive Lua skill with weather, user data, post creation, and mathematical tools",
|
|
10
13
|
context: "This skill provides various utilities including weather information, user data retrieval, post creation, basic calculator operations, and advanced mathematical functions. Use get_weather to fetch current weather conditions for any city, get_user_data to retrieve user information, create_post to publish new posts, calculator for basic arithmetic operations, and advanced_math for complex mathematical computations like factorials, prime checking, fibonacci sequences, and greatest common divisor calculations."
|
|
11
14
|
});
|
|
12
|
-
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
generalSkill.addTools([
|
|
18
|
+
new GetWeatherTool(),
|
|
19
|
+
new CreatePostTool()
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const userDataSkill = new LuaSkill({
|
|
24
|
+
name: "user-data-skill",
|
|
25
|
+
version: "0.0.1",
|
|
26
|
+
description: "A specific Lua skill with user data",
|
|
27
|
+
context: "This skill provides various utilities including user data retrieval, creation, and updating.",
|
|
28
|
+
tools: [
|
|
29
|
+
new GetUserDataTool(),
|
|
30
|
+
new CreateUserDataTool(),
|
|
31
|
+
new UpdateUserDataTool()
|
|
32
|
+
]
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
const eccomerceSkill = new LuaSkill({
|
|
37
|
+
name: "eccomerce-skill",
|
|
38
|
+
version: "0.0.1",
|
|
39
|
+
description: "A specific Lua skill with eccomerce",
|
|
40
|
+
context: "This skill provides various utilities including eccomerce."
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
eccomerceSkill.addTools([
|
|
44
|
+
new SearchProductsTool(),
|
|
45
|
+
new CreatePaymentLinkTool()
|
|
46
|
+
]);
|
|
47
|
+
|
|
13
48
|
|
|
14
49
|
// Test cases
|
|
15
50
|
const testCases = [
|
|
@@ -26,13 +61,18 @@ const testCases = [
|
|
|
26
61
|
];
|
|
27
62
|
|
|
28
63
|
async function runTests() {
|
|
64
|
+
// await seedProducts();
|
|
29
65
|
console.log("🧪 Running tool tests...\n");
|
|
30
|
-
|
|
66
|
+
|
|
31
67
|
for (const [index, testCase] of testCases.entries()) {
|
|
32
68
|
try {
|
|
33
69
|
console.log(`Test ${index + 1}: ${testCase.tool}`);
|
|
34
|
-
const
|
|
35
|
-
console.log("✅ Success:",
|
|
70
|
+
const resultGeneral = await generalSkill.run(testCase);
|
|
71
|
+
console.log("✅ Success:", resultGeneral);
|
|
72
|
+
const resultUserData = await userDataSkill.run(testCase);
|
|
73
|
+
console.log("✅ Success:", resultUserData);
|
|
74
|
+
const resultEccomerce = await eccomerceSkill.run(testCase);
|
|
75
|
+
console.log("✅ Success:", resultEccomerce);
|
|
36
76
|
} catch (error: any) {
|
|
37
77
|
console.log("❌ Error:", error.message);
|
|
38
78
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fetch from "node-fetch";
|
|
2
|
+
import OpenAI from "openai";
|
|
3
|
+
import { Pinecone } from "@pinecone-database/pinecone";
|
|
4
|
+
import { env } from "lua-cli/skill";
|
|
5
|
+
|
|
6
|
+
const openai = new OpenAI({ apiKey: env("OPENAI_API_KEY") || "" });
|
|
7
|
+
const pinecone = new Pinecone({ apiKey: env("PINECONE_API_KEY") || "" });
|
|
8
|
+
const indexName = "products-demo";
|
|
9
|
+
|
|
10
|
+
async function embed(text: string) {
|
|
11
|
+
const res = await openai.embeddings.create({
|
|
12
|
+
model: "text-embedding-3-small",
|
|
13
|
+
input: text,
|
|
14
|
+
});
|
|
15
|
+
return res.data[0].embedding;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default async function seedProducts() {
|
|
19
|
+
const index = pinecone.Index(indexName);
|
|
20
|
+
|
|
21
|
+
// Example: Fake Store API
|
|
22
|
+
const response = await fetch("https://fakestoreapi.com/products");
|
|
23
|
+
const products = await response.json() as any[];
|
|
24
|
+
|
|
25
|
+
const vectors = await Promise.all(
|
|
26
|
+
products.map(async (product) => {
|
|
27
|
+
const embedding = await embed(`${product.title}. ${product.description}`);
|
|
28
|
+
return {
|
|
29
|
+
id: product.id.toString(),
|
|
30
|
+
values: embedding,
|
|
31
|
+
metadata: {
|
|
32
|
+
title: product.title,
|
|
33
|
+
description: product.description,
|
|
34
|
+
category: product.category,
|
|
35
|
+
price: product.price,
|
|
36
|
+
image: product.image,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
await index.upsert(vectors);
|
|
43
|
+
console.log("Dummy products inserted!");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
seedProducts().catch(console.error);
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { LuaTool
|
|
1
|
+
import { LuaTool } from "lua-cli/skill";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import GetWeatherService from "../services/GetWeather";
|
|
4
|
-
|
|
5
3
|
|
|
6
4
|
export default class GetWeatherTool implements LuaTool {
|
|
7
5
|
name = "get_weather";
|
|
@@ -17,20 +15,39 @@ export default class GetWeatherTool implements LuaTool {
|
|
|
17
15
|
description: z.string().optional()
|
|
18
16
|
});
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
async execute(input: z.infer<typeof this.inputSchema>) {
|
|
19
|
+
// Step 1: Geocode city → lat/lon (use Open-Meteo’s free geocoding API)
|
|
20
|
+
const geoUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(
|
|
21
|
+
input.city
|
|
22
|
+
)}&count=1`;
|
|
23
|
+
|
|
24
|
+
const geoRes = await fetch(geoUrl);
|
|
25
|
+
if (!geoRes.ok) {
|
|
26
|
+
throw new Error(`Failed to fetch location: ${geoRes.statusText}`);
|
|
27
|
+
}
|
|
28
|
+
const geoData = await geoRes.json();
|
|
29
|
+
if (!geoData.results || geoData.results.length === 0) {
|
|
30
|
+
throw new Error(`No location found for ${input.city}`);
|
|
31
|
+
}
|
|
21
32
|
|
|
22
|
-
|
|
23
|
-
this.weatherService = new GetWeatherService();
|
|
24
|
-
}
|
|
33
|
+
const { latitude, longitude, name } = geoData.results[0];
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const baseUrl = env('BASE_URL');
|
|
29
|
-
const apiKey = env('API_KEY');
|
|
30
|
-
const agentId = env('AGENT_ID');
|
|
35
|
+
// Step 2: Get weather for lat/lon
|
|
36
|
+
const weatherUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t_weather=true`;
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
const weatherRes = await fetch(weatherUrl);
|
|
39
|
+
if (!weatherRes.ok) {
|
|
40
|
+
throw new Error(`Failed to fetch weather: ${weatherRes.statusText}`);
|
|
41
|
+
}
|
|
42
|
+
const weatherData = await weatherRes.json();
|
|
43
|
+
const current = weatherData.current_weather;
|
|
33
44
|
|
|
34
|
-
return
|
|
45
|
+
return {
|
|
46
|
+
weather: current.weathercode?.toString() || "Unknown",
|
|
47
|
+
city: name,
|
|
48
|
+
temperature: current.temperature,
|
|
49
|
+
humidity: undefined, // Open-Meteo current_weather does not include humidity
|
|
50
|
+
description: `Windspeed ${current.windspeed} km/h`
|
|
51
|
+
};
|
|
35
52
|
}
|
|
36
|
-
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { LuaTool, env } from "lua-cli/skill";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export default class CreatePaymentLinkTool implements LuaTool {
|
|
5
|
+
name = "create_payment_link";
|
|
6
|
+
description = "Create a Stripe payment link for a one-time payment";
|
|
7
|
+
inputSchema = z.object({
|
|
8
|
+
amount: z.number().int().positive(), // in cents
|
|
9
|
+
currency: z.string().default("usd")
|
|
10
|
+
});
|
|
11
|
+
outputSchema = z.object({
|
|
12
|
+
url: z.string(),
|
|
13
|
+
id: z.string(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
async execute(input: z.infer<typeof this.inputSchema>) {
|
|
17
|
+
const apiKey = env("STRIPE_SECRET_KEY");
|
|
18
|
+
if (!apiKey) {
|
|
19
|
+
throw new Error("STRIPE_SECRET_KEY is not set in environment variables");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Create a one-time Checkout Session with dummy redirect URLs
|
|
23
|
+
const sessionRes = await fetch("https://api.stripe.com/v1/checkout/sessions", {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${apiKey}`,
|
|
27
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
28
|
+
},
|
|
29
|
+
body: new URLSearchParams({
|
|
30
|
+
mode: "payment",
|
|
31
|
+
"line_items[0][price_data][currency]": input.currency,
|
|
32
|
+
"line_items[0][price_data][product_data][name]": "One-time Payment",
|
|
33
|
+
"line_items[0][price_data][unit_amount]": input.amount.toString(),
|
|
34
|
+
"line_items[0][quantity]": "1",
|
|
35
|
+
success_url: "https://example.com/success",
|
|
36
|
+
cancel_url: "https://example.com/cancel",
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (!sessionRes.ok) {
|
|
41
|
+
throw new Error(`Failed to create checkout session: ${await sessionRes.text()}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const session = await sessionRes.json();
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
url: session.url,
|
|
48
|
+
id: session.id,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { env, LuaTool } from "lua-cli/skill";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { user } from 'lua-cli/user-data-api';
|
|
4
|
+
import { Pinecone, Index } from '@pinecone-database/pinecone';
|
|
5
|
+
import OpenAI from "openai";
|
|
6
|
+
export class SearchProductsTool implements LuaTool {
|
|
7
|
+
name = "search_products";
|
|
8
|
+
description = "Search for products";
|
|
9
|
+
inputSchema = z.object({
|
|
10
|
+
query: z.string()
|
|
11
|
+
});
|
|
12
|
+
pinecone: Pinecone;
|
|
13
|
+
openai: OpenAI;
|
|
14
|
+
index: Index;
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
const pinecone = new Pinecone({
|
|
18
|
+
apiKey: env('PINECONE_API_KEY') || ''
|
|
19
|
+
});
|
|
20
|
+
this.openai = new OpenAI({ apiKey: env('OPENAI_API_KEY') || '' });
|
|
21
|
+
this.pinecone = pinecone;
|
|
22
|
+
this.index = pinecone.Index('products-demo');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async embedText(text: string) {
|
|
26
|
+
const embeddingResponse = await this.openai.embeddings.create({
|
|
27
|
+
model: "text-embedding-3-small",
|
|
28
|
+
input: text,
|
|
29
|
+
});
|
|
30
|
+
return embeddingResponse.data[0].embedding;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async execute(input: z.infer<typeof this.inputSchema>) {
|
|
34
|
+
const queryVector = await this.embedText(input.query);
|
|
35
|
+
const results = await this.index.query({
|
|
36
|
+
vector: queryVector,
|
|
37
|
+
topK: 3,
|
|
38
|
+
includeMetadata: true,
|
|
39
|
+
});
|
|
40
|
+
console.log(results);
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
File without changes
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// import fs from 'fs';
|
|
3
|
-
// import path from 'path';
|
|
4
|
-
// import inquirer from 'inquirer';
|
|
5
|
-
// import { loadApiKey, checkApiKey } from '../services/auth.js';
|
|
6
|
-
// import { readSkillConfig } from '../utils/files.js';
|
|
7
|
-
// export interface VersionInfo {
|
|
8
|
-
// version: string;
|
|
9
|
-
// createdDate: string;
|
|
10
|
-
// createdBy: string;
|
|
11
|
-
// isCurrent: boolean;
|
|
12
|
-
// createdByEmail: string;
|
|
13
|
-
// createdByFullName: string;
|
|
14
|
-
// }
|
|
15
|
-
// export interface VersionsResponse {
|
|
16
|
-
// versions: VersionInfo[];
|
|
17
|
-
// }
|
|
18
|
-
// export interface PublishResponse {
|
|
19
|
-
// message: string;
|
|
20
|
-
// skillId: string;
|
|
21
|
-
// activeVersionId: string;
|
|
22
|
-
// publishedAt: string;
|
|
23
|
-
// }
|
|
24
|
-
// export async function fetchVersions(apiKey: string, agentId: string, skillId: string): Promise<VersionsResponse> {
|
|
25
|
-
// try {
|
|
26
|
-
// const response = await fetch(`http://localhost:3022/developer/skills/${agentId}/${skillId}/versions`, {
|
|
27
|
-
// method: "GET",
|
|
28
|
-
// headers: {
|
|
29
|
-
// "accept": "application/json",
|
|
30
|
-
// "Authorization": `Bearer ${apiKey}`
|
|
31
|
-
// }
|
|
32
|
-
// });
|
|
33
|
-
// if (!response.ok) {
|
|
34
|
-
// throw new Error(`Failed to fetch versions: ${response.status} ${response.statusText}`);
|
|
35
|
-
// }
|
|
36
|
-
// return await response.json() as VersionsResponse;
|
|
37
|
-
// } catch (error) {
|
|
38
|
-
// console.error("❌ Error fetching versions:", error);
|
|
39
|
-
// throw error;
|
|
40
|
-
// }
|
|
41
|
-
// }
|
|
42
|
-
// export async function publishVersion(apiKey: string, agentId: string, skillId: string, version: string): Promise<PublishResponse> {
|
|
43
|
-
// try {
|
|
44
|
-
// const response = await fetch(`http://localhost:3022/developer/skills/${agentId}/${skillId}/${version}/publish`, {
|
|
45
|
-
// method: "PUT",
|
|
46
|
-
// headers: {
|
|
47
|
-
// "accept": "application/json",
|
|
48
|
-
// "Authorization": `Bearer ${apiKey}`
|
|
49
|
-
// }
|
|
50
|
-
// });
|
|
51
|
-
// if (!response.ok) {
|
|
52
|
-
// throw new Error(`Failed to publish version: ${response.status} ${response.statusText}`);
|
|
53
|
-
// }
|
|
54
|
-
// return await response.json() as PublishResponse;
|
|
55
|
-
// } catch (error) {
|
|
56
|
-
// console.error("❌ Error publishing version:", error);
|
|
57
|
-
// throw error;
|
|
58
|
-
// }
|
|
59
|
-
// }
|
|
60
|
-
// function formatVersionChoice(version: VersionInfo): string {
|
|
61
|
-
// const currentIndicator = version.isCurrent ? ' (CURRENT)' : '';
|
|
62
|
-
// const date = new Date(version.createdDate).toLocaleDateString();
|
|
63
|
-
// return `${version.version}${currentIndicator} - Created: ${date} by ${version.createdByEmail}`;
|
|
64
|
-
// }
|
|
65
|
-
// export async function deployCommand(): Promise<void> {
|
|
66
|
-
// try {
|
|
67
|
-
// // Check if we're in a skill directory
|
|
68
|
-
// const config = readSkillConfig();
|
|
69
|
-
// if (!config || !config.agent?.agentId || !config.skill?.skillId) {
|
|
70
|
-
// console.error("❌ No lua.skill.yaml found or missing agentId/skillId. Please run this command from a skill directory.");
|
|
71
|
-
// process.exit(1);
|
|
72
|
-
// }
|
|
73
|
-
// // Load API key
|
|
74
|
-
// const apiKey = await loadApiKey();
|
|
75
|
-
// if (!apiKey) {
|
|
76
|
-
// console.error("❌ No API key found. Please run 'lua configure' to set up your API key.");
|
|
77
|
-
// process.exit(1);
|
|
78
|
-
// }
|
|
79
|
-
// // Validate API key
|
|
80
|
-
// const userData = await checkApiKey(apiKey);
|
|
81
|
-
// console.log(`✅ Authenticated as ${userData.email}`);
|
|
82
|
-
// // Fetch available versions
|
|
83
|
-
// console.log("🔄 Fetching available versions...");
|
|
84
|
-
// const versionsResponse = await fetchVersions(apiKey, config.agent.agentId, config.skill.skillId);
|
|
85
|
-
// if (!versionsResponse.versions || versionsResponse.versions.length === 0) {
|
|
86
|
-
// console.log("❌ No versions found for this skill.");
|
|
87
|
-
// process.exit(1);
|
|
88
|
-
// }
|
|
89
|
-
// // Sort versions by creation date (newest first)
|
|
90
|
-
// const sortedVersions = versionsResponse.versions.sort((a, b) =>
|
|
91
|
-
// new Date(b.createdDate).getTime() - new Date(a.createdDate).getTime()
|
|
92
|
-
// );
|
|
93
|
-
// // Let user select a version
|
|
94
|
-
// const { selectedVersion } = await inquirer.prompt([
|
|
95
|
-
// {
|
|
96
|
-
// type: "list",
|
|
97
|
-
// name: "selectedVersion",
|
|
98
|
-
// message: "Select a version to deploy:",
|
|
99
|
-
// choices: sortedVersions.map(version => ({
|
|
100
|
-
// name: formatVersionChoice(version),
|
|
101
|
-
// value: version.version
|
|
102
|
-
// }))
|
|
103
|
-
// }
|
|
104
|
-
// ]);
|
|
105
|
-
// // Show warning and confirm deployment
|
|
106
|
-
// const { confirmed } = await inquirer.prompt([
|
|
107
|
-
// {
|
|
108
|
-
// type: "confirm",
|
|
109
|
-
// name: "confirmed",
|
|
110
|
-
// message: "⚠️ Warning: This version will be deployed to all users. Do you want to proceed?",
|
|
111
|
-
// default: false
|
|
112
|
-
// }
|
|
113
|
-
// ]);
|
|
114
|
-
// if (!confirmed) {
|
|
115
|
-
// console.log("❌ Deployment cancelled.");
|
|
116
|
-
// process.exit(0);
|
|
117
|
-
// }
|
|
118
|
-
// // Publish the selected version
|
|
119
|
-
// console.log(`🔄 Publishing version ${selectedVersion}...`);
|
|
120
|
-
// const publishResponse = await publishVersion(apiKey, config.agent.agentId, config.skill.skillId, selectedVersion);
|
|
121
|
-
// console.log("✅ Deployment successful!");
|
|
122
|
-
// console.log(`📦 Version: ${publishResponse.activeVersionId}`);
|
|
123
|
-
// console.log(`🆔 Skill ID: ${publishResponse.skillId}`);
|
|
124
|
-
// console.log(`📅 Published at: ${new Date(publishResponse.publishedAt).toLocaleString()}`);
|
|
125
|
-
// console.log(`💬 ${publishResponse.message}`);
|
|
126
|
-
// } catch (error: any) {
|
|
127
|
-
// console.error("❌ Error during deployment:", error.message);
|
|
128
|
-
// process.exit(1);
|
|
129
|
-
// }
|
|
130
|
-
// }
|