@constela/cli 0.5.42 → 0.5.48
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/dist/index.js +81 -0
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1185,6 +1185,86 @@ Ready in ${elapsed}ms (Ctrl+Click to open)`);
|
|
|
1185
1185
|
}
|
|
1186
1186
|
}
|
|
1187
1187
|
|
|
1188
|
+
// src/commands/suggest.ts
|
|
1189
|
+
import { readFileSync as readFileSync4, existsSync } from "fs";
|
|
1190
|
+
import { resolve } from "path";
|
|
1191
|
+
import {
|
|
1192
|
+
getProvider,
|
|
1193
|
+
buildSuggestPrompt,
|
|
1194
|
+
parseSuggestions,
|
|
1195
|
+
SUGGEST_SYSTEM_PROMPT
|
|
1196
|
+
} from "@constela/ai";
|
|
1197
|
+
var VALID_ASPECTS = ["accessibility", "performance", "security", "ux"];
|
|
1198
|
+
var VALID_PROVIDERS = ["anthropic", "openai"];
|
|
1199
|
+
async function suggestCommand(input, options) {
|
|
1200
|
+
try {
|
|
1201
|
+
const inputPath = resolve(process.cwd(), input);
|
|
1202
|
+
if (!existsSync(inputPath)) {
|
|
1203
|
+
console.error("Error: File not found - " + inputPath);
|
|
1204
|
+
process.exit(1);
|
|
1205
|
+
}
|
|
1206
|
+
const content = readFileSync4(inputPath, "utf-8");
|
|
1207
|
+
let dsl;
|
|
1208
|
+
try {
|
|
1209
|
+
dsl = JSON.parse(content);
|
|
1210
|
+
} catch {
|
|
1211
|
+
console.error("Error: Invalid JSON in input file");
|
|
1212
|
+
process.exit(1);
|
|
1213
|
+
}
|
|
1214
|
+
const aspect = options.aspect ?? "accessibility";
|
|
1215
|
+
if (!VALID_ASPECTS.includes(aspect)) {
|
|
1216
|
+
console.error("Error: Invalid aspect. Valid options: " + VALID_ASPECTS.join(", "));
|
|
1217
|
+
process.exit(1);
|
|
1218
|
+
}
|
|
1219
|
+
const providerType = options.provider ?? "anthropic";
|
|
1220
|
+
if (!VALID_PROVIDERS.includes(providerType)) {
|
|
1221
|
+
console.error("Error: Invalid provider. Valid options: " + VALID_PROVIDERS.join(", "));
|
|
1222
|
+
process.exit(1);
|
|
1223
|
+
}
|
|
1224
|
+
const apiKeyEnvVar = providerType === "anthropic" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
|
|
1225
|
+
if (!process.env[apiKeyEnvVar]) {
|
|
1226
|
+
console.error("Error: " + apiKeyEnvVar + " environment variable is not set");
|
|
1227
|
+
process.exit(1);
|
|
1228
|
+
}
|
|
1229
|
+
console.log("Analyzing " + input + " for " + aspect + " suggestions...");
|
|
1230
|
+
const provider = getProvider(providerType);
|
|
1231
|
+
const prompt = buildSuggestPrompt({ dsl, aspect });
|
|
1232
|
+
const response = await provider.generate(prompt, {
|
|
1233
|
+
systemPrompt: SUGGEST_SYSTEM_PROMPT
|
|
1234
|
+
});
|
|
1235
|
+
const suggestions = parseSuggestions(response.content);
|
|
1236
|
+
if (options.json) {
|
|
1237
|
+
console.log(JSON.stringify({ suggestions, aspect, file: input }, null, 2));
|
|
1238
|
+
} else {
|
|
1239
|
+
outputSuggestions(suggestions, aspect, input);
|
|
1240
|
+
}
|
|
1241
|
+
} catch (err) {
|
|
1242
|
+
const error = err;
|
|
1243
|
+
console.error("Error: " + error.message);
|
|
1244
|
+
process.exit(1);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
function outputSuggestions(suggestions, aspect, file) {
|
|
1248
|
+
console.log("");
|
|
1249
|
+
console.log("=== Suggestions for " + file + " (" + aspect + ") ===");
|
|
1250
|
+
console.log("");
|
|
1251
|
+
if (suggestions.length === 0) {
|
|
1252
|
+
console.log("No suggestions found. Great job!");
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1255
|
+
for (let i = 0; i < suggestions.length; i++) {
|
|
1256
|
+
const s = suggestions[i];
|
|
1257
|
+
const severityIcon = s.severity === "high" ? "[HIGH]" : s.severity === "medium" ? "[MED]" : "[LOW]";
|
|
1258
|
+
console.log(severityIcon + " " + s.issue);
|
|
1259
|
+
console.log(" Recommendation: " + s.recommendation);
|
|
1260
|
+
if (s.location) {
|
|
1261
|
+
console.log(" Location: " + s.location);
|
|
1262
|
+
}
|
|
1263
|
+
console.log("");
|
|
1264
|
+
}
|
|
1265
|
+
console.log("Total: " + suggestions.length + " suggestion(s)");
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1188
1268
|
// src/index.ts
|
|
1189
1269
|
var program = new Command();
|
|
1190
1270
|
program.name("constela").description("Constela UI framework CLI").version("0.1.0");
|
|
@@ -1194,6 +1274,7 @@ program.command("inspect <input>").description("Inspect Constela program structu
|
|
|
1194
1274
|
program.command("dev").description("Start development server").option("-p, --port <number>", "Port number (default: 3000)").option("--host <string>", "Host address").option("--routesDir <path>", "Routes directory").option("--publicDir <path>", "Public directory").option("--layoutsDir <path>", "Layouts directory").action(devCommand);
|
|
1195
1275
|
program.command("build").description("Build for production").option("-o, --outDir <path>", "Output directory (default: dist)").option("--routesDir <path>", "Routes directory").option("--publicDir <path>", "Public directory").option("--layoutsDir <path>", "Layouts directory").action(buildCommand);
|
|
1196
1276
|
program.command("start").description("Start production server").option("-p, --port <number>", "Port number (default: 3000)").action(startCommand);
|
|
1277
|
+
program.command("suggest <input>").description("Get AI-powered suggestions for Constela DSL").option("--aspect <type>", "Aspect to analyze: accessibility, performance, security, ux").option("--provider <name>", "AI provider: anthropic, openai (default: anthropic)").option("--json", "Output results as JSON").action(suggestCommand);
|
|
1197
1278
|
if (process.argv.length <= 2) {
|
|
1198
1279
|
program.outputHelp();
|
|
1199
1280
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constela/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.48",
|
|
4
4
|
"description": "CLI tools for Constela UI framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,9 +19,10 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"commander": "^12.0.0",
|
|
22
|
-
"@constela/core": "0.
|
|
23
|
-
"@constela/
|
|
24
|
-
"@constela/
|
|
22
|
+
"@constela/core": "0.16.2",
|
|
23
|
+
"@constela/start": "1.8.26",
|
|
24
|
+
"@constela/ai": "1.0.2",
|
|
25
|
+
"@constela/compiler": "0.14.7"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"@types/node": "^20.10.0",
|