@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.
Files changed (2) hide show
  1. package/dist/index.js +81 -0
  2. 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.42",
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.15.2",
23
- "@constela/compiler": "0.14.3",
24
- "@constela/start": "1.8.20"
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",