@nikkory/vibe-cli 2.2.1 → 2.3.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/dist/index.js +515 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
|
-
var
|
|
28
|
-
var
|
|
27
|
+
var import_commander6 = require("commander");
|
|
28
|
+
var import_chalk5 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// src/commands/init.ts
|
|
31
31
|
var fs = __toESM(require("fs/promises"));
|
|
@@ -1060,11 +1060,515 @@ var matrixGenerateCommand = new import_commander3.Command("add").alias("gen").al
|
|
|
1060
1060
|
}
|
|
1061
1061
|
});
|
|
1062
1062
|
|
|
1063
|
+
// src/commands/section-generate.ts
|
|
1064
|
+
var import_commander4 = require("commander");
|
|
1065
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
1066
|
+
var import_ora3 = __toESM(require("ora"));
|
|
1067
|
+
|
|
1068
|
+
// src/generators/section-generator.ts
|
|
1069
|
+
var path3 = __toESM(require("path"));
|
|
1070
|
+
|
|
1071
|
+
// src/generators/matrix-engine.ts
|
|
1072
|
+
var fs2 = __toESM(require("fs/promises"));
|
|
1073
|
+
var path2 = __toESM(require("path"));
|
|
1074
|
+
var import_handlebars = __toESM(require("handlebars"));
|
|
1075
|
+
var MatrixEngine = class {
|
|
1076
|
+
handlebars;
|
|
1077
|
+
constructor() {
|
|
1078
|
+
this.handlebars = import_handlebars.default.create();
|
|
1079
|
+
this.registerHelpers();
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Register Handlebars helpers for conditional logic
|
|
1083
|
+
*/
|
|
1084
|
+
registerHelpers() {
|
|
1085
|
+
this.handlebars.registerHelper("eq", (a, b) => a === b);
|
|
1086
|
+
this.handlebars.registerHelper("ne", (a, b) => a !== b);
|
|
1087
|
+
this.handlebars.registerHelper("or", (...args) => {
|
|
1088
|
+
const _options = args[args.length - 1];
|
|
1089
|
+
return args.slice(0, -1).some(Boolean);
|
|
1090
|
+
});
|
|
1091
|
+
this.handlebars.registerHelper("and", (...args) => {
|
|
1092
|
+
const _options = args[args.length - 1];
|
|
1093
|
+
return args.slice(0, -1).every(Boolean);
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Load matrix configuration from config.json
|
|
1098
|
+
*
|
|
1099
|
+
* @param templateDir - Path to template directory
|
|
1100
|
+
* @returns Matrix configuration
|
|
1101
|
+
* @throws Error if config.json not found or invalid
|
|
1102
|
+
*/
|
|
1103
|
+
async loadConfig(templateDir) {
|
|
1104
|
+
const configPath = path2.join(templateDir, "config.json");
|
|
1105
|
+
try {
|
|
1106
|
+
const content = await fs2.readFile(configPath, "utf-8");
|
|
1107
|
+
const config = JSON.parse(content);
|
|
1108
|
+
if (!config.templateName || !config.dimensions || !config.variables) {
|
|
1109
|
+
throw new Error("Invalid matrix config: missing required fields");
|
|
1110
|
+
}
|
|
1111
|
+
return config;
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
if (error.code === "ENOENT") {
|
|
1114
|
+
throw new Error(`Matrix config not found: ${configPath}`);
|
|
1115
|
+
}
|
|
1116
|
+
throw new Error(`Failed to load matrix config: ${error.message}`);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Validate dimension values against configuration
|
|
1121
|
+
*
|
|
1122
|
+
* @param dimensions - Dimension values to validate
|
|
1123
|
+
* @param config - Matrix configuration
|
|
1124
|
+
* @throws Error if invalid dimension values
|
|
1125
|
+
*/
|
|
1126
|
+
validateDimensions(dimensions, config) {
|
|
1127
|
+
for (const [dimName, dimValue] of Object.entries(dimensions)) {
|
|
1128
|
+
const dimDef = config.dimensions[dimName];
|
|
1129
|
+
if (!dimDef) {
|
|
1130
|
+
throw new Error(`Unknown dimension: ${dimName}`);
|
|
1131
|
+
}
|
|
1132
|
+
if (!dimDef.values.includes(dimValue)) {
|
|
1133
|
+
throw new Error(
|
|
1134
|
+
`Invalid value "${dimValue}" for dimension "${dimName}". Valid values: ${dimDef.values.join(", ")}`
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Validate variable values against configuration
|
|
1141
|
+
*
|
|
1142
|
+
* @param variables - Variable values to validate
|
|
1143
|
+
* @param config - Matrix configuration
|
|
1144
|
+
* @throws Error if required variables missing
|
|
1145
|
+
*/
|
|
1146
|
+
validateVariables(variables, config) {
|
|
1147
|
+
for (const [varName, varDef] of Object.entries(config.variables)) {
|
|
1148
|
+
if (varDef.required && !varDef.auto && !variables[varName]) {
|
|
1149
|
+
throw new Error(`Required variable missing: ${varName}`);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Apply defaults to dimensions
|
|
1155
|
+
*
|
|
1156
|
+
* @param dimensions - User-provided dimension values
|
|
1157
|
+
* @param config - Matrix configuration
|
|
1158
|
+
* @returns Dimensions with defaults applied
|
|
1159
|
+
*/
|
|
1160
|
+
applyDimensionDefaults(dimensions, config) {
|
|
1161
|
+
const result = { ...dimensions };
|
|
1162
|
+
for (const [dimName, dimDef] of Object.entries(config.dimensions)) {
|
|
1163
|
+
if (!result[dimName] && dimDef.default) {
|
|
1164
|
+
result[dimName] = dimDef.default;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return result;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Apply auto-filled variables (timestamp, templateVersion)
|
|
1171
|
+
*
|
|
1172
|
+
* @param variables - User-provided variables
|
|
1173
|
+
* @param config - Matrix configuration
|
|
1174
|
+
* @returns Variables with auto-filled values
|
|
1175
|
+
*/
|
|
1176
|
+
applyAutoVariables(variables, config) {
|
|
1177
|
+
const result = { ...variables };
|
|
1178
|
+
for (const [varName, varDef] of Object.entries(config.variables)) {
|
|
1179
|
+
if (varDef.auto) {
|
|
1180
|
+
if (varName === "timestamp") {
|
|
1181
|
+
result[varName] = (/* @__PURE__ */ new Date()).toISOString();
|
|
1182
|
+
} else if (varName === "templateVersion" && varDef.value) {
|
|
1183
|
+
result[varName] = varDef.value;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
return result;
|
|
1188
|
+
}
|
|
1189
|
+
/**
|
|
1190
|
+
* Determine which template file to use based on quality tier
|
|
1191
|
+
*
|
|
1192
|
+
* @param qualityTier - Quality tier (basic, standard, enterprise)
|
|
1193
|
+
* @param config - Matrix configuration
|
|
1194
|
+
* @returns Template definition
|
|
1195
|
+
* @throws Error if template not found
|
|
1196
|
+
*/
|
|
1197
|
+
selectTemplate(qualityTier, config) {
|
|
1198
|
+
const template = config.templates[qualityTier];
|
|
1199
|
+
if (!template) {
|
|
1200
|
+
throw new Error(`No template found for quality tier: ${qualityTier}`);
|
|
1201
|
+
}
|
|
1202
|
+
return template;
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Read and compile template file
|
|
1206
|
+
*
|
|
1207
|
+
* @param templateDir - Template directory path
|
|
1208
|
+
* @param templateFile - Template filename
|
|
1209
|
+
* @returns Compiled Handlebars template
|
|
1210
|
+
*/
|
|
1211
|
+
async compileTemplate(templateDir, templateFile) {
|
|
1212
|
+
const templatePath = path2.join(templateDir, templateFile);
|
|
1213
|
+
try {
|
|
1214
|
+
const content = await fs2.readFile(templatePath, "utf-8");
|
|
1215
|
+
return this.handlebars.compile(content);
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
throw new Error(`Failed to read template ${templateFile}: ${error.message}`);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Generate code from template
|
|
1222
|
+
*
|
|
1223
|
+
* @param genConfig - Generation configuration
|
|
1224
|
+
* @returns Generation result with all files
|
|
1225
|
+
*/
|
|
1226
|
+
async generate(genConfig) {
|
|
1227
|
+
try {
|
|
1228
|
+
const config = await this.loadConfig(genConfig.templateDir);
|
|
1229
|
+
const dimensions = this.applyDimensionDefaults(genConfig.dimensions, config);
|
|
1230
|
+
this.validateDimensions(dimensions, config);
|
|
1231
|
+
const variables = this.applyAutoVariables(genConfig.variables, config);
|
|
1232
|
+
this.validateVariables(variables, config);
|
|
1233
|
+
const qualityTier = dimensions.qualityTier || "enterprise";
|
|
1234
|
+
const template = this.selectTemplate(qualityTier, config);
|
|
1235
|
+
const context = {
|
|
1236
|
+
...variables,
|
|
1237
|
+
...dimensions
|
|
1238
|
+
};
|
|
1239
|
+
const componentTemplate = await this.compileTemplate(
|
|
1240
|
+
genConfig.templateDir,
|
|
1241
|
+
template.file
|
|
1242
|
+
);
|
|
1243
|
+
const componentContent = componentTemplate(context);
|
|
1244
|
+
const files = [];
|
|
1245
|
+
const componentOutputDef = config.output.component;
|
|
1246
|
+
const componentFilename = this.handlebars.compile(componentOutputDef.pattern)(context);
|
|
1247
|
+
const componentPath = path2.join(
|
|
1248
|
+
genConfig.outputDir || componentOutputDef.path,
|
|
1249
|
+
componentFilename
|
|
1250
|
+
);
|
|
1251
|
+
files.push({
|
|
1252
|
+
type: "component",
|
|
1253
|
+
path: componentPath,
|
|
1254
|
+
content: componentContent,
|
|
1255
|
+
template: template.file
|
|
1256
|
+
});
|
|
1257
|
+
if (config.templates.types) {
|
|
1258
|
+
const typesTemplate = await this.compileTemplate(
|
|
1259
|
+
genConfig.templateDir,
|
|
1260
|
+
config.templates.types.file
|
|
1261
|
+
);
|
|
1262
|
+
const typesContent = typesTemplate(context);
|
|
1263
|
+
const typesOutputDef = config.output.types;
|
|
1264
|
+
const typesFilename = this.handlebars.compile(typesOutputDef.pattern)(context);
|
|
1265
|
+
const typesPath = path2.join(
|
|
1266
|
+
genConfig.outputDir || typesOutputDef.path,
|
|
1267
|
+
typesFilename
|
|
1268
|
+
);
|
|
1269
|
+
files.push({
|
|
1270
|
+
type: "types",
|
|
1271
|
+
path: typesPath,
|
|
1272
|
+
content: typesContent,
|
|
1273
|
+
template: config.templates.types.file
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
if (config.templates.test) {
|
|
1277
|
+
const testTemplate = await this.compileTemplate(
|
|
1278
|
+
genConfig.templateDir,
|
|
1279
|
+
config.templates.test.file
|
|
1280
|
+
);
|
|
1281
|
+
const testContent = testTemplate(context);
|
|
1282
|
+
const testOutputDef = config.output.test;
|
|
1283
|
+
const testFilename = this.handlebars.compile(testOutputDef.pattern)(context);
|
|
1284
|
+
const testPath = path2.join(
|
|
1285
|
+
genConfig.outputDir || testOutputDef.path,
|
|
1286
|
+
testFilename
|
|
1287
|
+
);
|
|
1288
|
+
files.push({
|
|
1289
|
+
type: "test",
|
|
1290
|
+
path: testPath,
|
|
1291
|
+
content: testContent,
|
|
1292
|
+
template: config.templates.test.file
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
return {
|
|
1296
|
+
success: true,
|
|
1297
|
+
files,
|
|
1298
|
+
config,
|
|
1299
|
+
metadata: {
|
|
1300
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1301
|
+
dimensions,
|
|
1302
|
+
variables
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
} catch (error) {
|
|
1306
|
+
return {
|
|
1307
|
+
success: false,
|
|
1308
|
+
files: [],
|
|
1309
|
+
error: error.message,
|
|
1310
|
+
config: {},
|
|
1311
|
+
metadata: {
|
|
1312
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1313
|
+
dimensions: genConfig.dimensions,
|
|
1314
|
+
variables: genConfig.variables
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Write generated files to disk
|
|
1321
|
+
*
|
|
1322
|
+
* @param result - Generation result
|
|
1323
|
+
* @returns Array of written file paths
|
|
1324
|
+
*/
|
|
1325
|
+
async writeFiles(result) {
|
|
1326
|
+
if (!result.success) {
|
|
1327
|
+
throw new Error(`Cannot write files: ${result.error}`);
|
|
1328
|
+
}
|
|
1329
|
+
const writtenPaths = [];
|
|
1330
|
+
for (const file of result.files) {
|
|
1331
|
+
const dir = path2.dirname(file.path);
|
|
1332
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
1333
|
+
await fs2.writeFile(file.path, file.content, "utf-8");
|
|
1334
|
+
writtenPaths.push(file.path);
|
|
1335
|
+
}
|
|
1336
|
+
return writtenPaths;
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1340
|
+
// src/generators/section-generator.ts
|
|
1341
|
+
var SectionGenerator = class {
|
|
1342
|
+
engine;
|
|
1343
|
+
templateDir;
|
|
1344
|
+
constructor(templateDir) {
|
|
1345
|
+
this.engine = new MatrixEngine();
|
|
1346
|
+
this.templateDir = templateDir || path3.join(process.cwd(), ".claude", "templates", "settings-section");
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Generate settings section component
|
|
1350
|
+
*
|
|
1351
|
+
* @param options - Section generation options
|
|
1352
|
+
* @returns Generation result
|
|
1353
|
+
*/
|
|
1354
|
+
async generate(options) {
|
|
1355
|
+
const dimensions = {
|
|
1356
|
+
sectionType: options.sectionType,
|
|
1357
|
+
dataPattern: options.dataPattern || "global-inheritance",
|
|
1358
|
+
uiComplexity: options.uiComplexity || "medium",
|
|
1359
|
+
qualityTier: options.qualityTier || "enterprise",
|
|
1360
|
+
framework: options.framework || "react"
|
|
1361
|
+
};
|
|
1362
|
+
const variables = {
|
|
1363
|
+
SectionName: options.sectionName,
|
|
1364
|
+
SectionTitle: options.sectionTitle,
|
|
1365
|
+
Icon: options.icon,
|
|
1366
|
+
DataType: options.dataType,
|
|
1367
|
+
apiMethod: options.apiMethod,
|
|
1368
|
+
saveMethod: options.saveMethod,
|
|
1369
|
+
sectionName: this.toKebabCase(options.sectionName),
|
|
1370
|
+
...options.additionalVariables
|
|
1371
|
+
};
|
|
1372
|
+
const genConfig = {
|
|
1373
|
+
templateDir: this.templateDir,
|
|
1374
|
+
dimensions,
|
|
1375
|
+
variables,
|
|
1376
|
+
outputDir: options.outputDir
|
|
1377
|
+
};
|
|
1378
|
+
return await this.engine.generate(genConfig);
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Write generated files to disk
|
|
1382
|
+
*
|
|
1383
|
+
* @param result - Generation result
|
|
1384
|
+
* @returns Array of written file paths
|
|
1385
|
+
*/
|
|
1386
|
+
async write(result) {
|
|
1387
|
+
return await this.engine.writeFiles(result);
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Convert PascalCase to kebab-case
|
|
1391
|
+
*
|
|
1392
|
+
* @param str - PascalCase string
|
|
1393
|
+
* @returns kebab-case string
|
|
1394
|
+
*
|
|
1395
|
+
* @example
|
|
1396
|
+
* ```typescript
|
|
1397
|
+
* toKebabCase('AIProviderSettings') // 'ai-provider-settings'
|
|
1398
|
+
* ```
|
|
1399
|
+
*/
|
|
1400
|
+
toKebabCase(str) {
|
|
1401
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
// src/commands/section-generate.ts
|
|
1406
|
+
var sectionGenerateCommand = new import_commander4.Command("add:section").alias("section").description("Add/Generate section using Orchestrator (50 sections, composition-based)").argument("<section>", "Section ID (e.g., hero-centered, pricing-cards)").option(
|
|
1407
|
+
"-s, --design-system <system>",
|
|
1408
|
+
"Design system (material-design, ios-hig, glassmorphism, neumorphism, brutalism, minimalism, fluent, carbon, ant-design, chakra, atlassian, blueprint)",
|
|
1409
|
+
"material-design"
|
|
1410
|
+
).option(
|
|
1411
|
+
"-t, --tier <tier>",
|
|
1412
|
+
"Quality tier (basic, standard, enterprise)",
|
|
1413
|
+
"standard"
|
|
1414
|
+
).option(
|
|
1415
|
+
"-o, --output <path>",
|
|
1416
|
+
"Output file path"
|
|
1417
|
+
).action(async (sectionId, options) => {
|
|
1418
|
+
const spinner = (0, import_ora3.default)("Generating section...").start();
|
|
1419
|
+
try {
|
|
1420
|
+
const generator = new SectionGenerator();
|
|
1421
|
+
const result = await generator.generate({
|
|
1422
|
+
sectionId,
|
|
1423
|
+
designSystem: options.designSystem,
|
|
1424
|
+
tier: options.tier
|
|
1425
|
+
});
|
|
1426
|
+
if (!result.success) {
|
|
1427
|
+
spinner.fail(import_chalk3.default.red("Section generation failed"));
|
|
1428
|
+
result.errors.forEach((error) => {
|
|
1429
|
+
console.error(import_chalk3.default.gray(` \u2022 ${error}`));
|
|
1430
|
+
});
|
|
1431
|
+
process.exit(1);
|
|
1432
|
+
}
|
|
1433
|
+
if (options.output) {
|
|
1434
|
+
await generator.writeToFile(options.output, result.composedCode);
|
|
1435
|
+
spinner.succeed(import_chalk3.default.green(`Generated ${result.metadata.sectionId} \u2192 ${options.output}`));
|
|
1436
|
+
} else {
|
|
1437
|
+
spinner.succeed(import_chalk3.default.green(`Generated ${result.metadata.sectionId}`));
|
|
1438
|
+
console.log(result.composedCode);
|
|
1439
|
+
}
|
|
1440
|
+
console.log(import_chalk3.default.cyan("\nSection Info:"));
|
|
1441
|
+
console.log(` ${import_chalk3.default.gray("ID:")} ${result.metadata.sectionId}`);
|
|
1442
|
+
console.log(` ${import_chalk3.default.gray("Type:")} ${result.metadata.sectionType}`);
|
|
1443
|
+
console.log(` ${import_chalk3.default.gray("Tier:")} ${result.metadata.tier}`);
|
|
1444
|
+
console.log(` ${import_chalk3.default.gray("Design System:")} ${result.metadata.designSystem}`);
|
|
1445
|
+
console.log(` ${import_chalk3.default.gray("Components:")} ${result.metadata.componentsGenerated}`);
|
|
1446
|
+
console.log(` ${import_chalk3.default.gray("Lines of Code:")} ${result.metadata.totalLinesOfCode}`);
|
|
1447
|
+
console.log("");
|
|
1448
|
+
} catch (error) {
|
|
1449
|
+
spinner.fail(import_chalk3.default.red(`Error: ${error.message}`));
|
|
1450
|
+
process.exit(1);
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
|
|
1454
|
+
// src/commands/page-generate.ts
|
|
1455
|
+
var import_commander5 = require("commander");
|
|
1456
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
1457
|
+
var import_ora4 = __toESM(require("ora"));
|
|
1458
|
+
|
|
1459
|
+
// src/generators/page-generator.ts
|
|
1460
|
+
var path4 = __toESM(require("path"));
|
|
1461
|
+
var PageGenerator = class {
|
|
1462
|
+
engine;
|
|
1463
|
+
templateDir;
|
|
1464
|
+
constructor(templateDir) {
|
|
1465
|
+
this.engine = new MatrixEngine();
|
|
1466
|
+
this.templateDir = templateDir || path4.join(process.cwd(), ".claude", "templates", "page");
|
|
1467
|
+
}
|
|
1468
|
+
/**
|
|
1469
|
+
* Generate page component
|
|
1470
|
+
*
|
|
1471
|
+
* @param options - Page generation options
|
|
1472
|
+
* @returns Generation result
|
|
1473
|
+
*/
|
|
1474
|
+
async generate(options) {
|
|
1475
|
+
const dimensions = {
|
|
1476
|
+
pageType: options.pageType,
|
|
1477
|
+
qualityTier: options.qualityTier || "enterprise",
|
|
1478
|
+
framework: options.framework || "react"
|
|
1479
|
+
};
|
|
1480
|
+
const variables = {
|
|
1481
|
+
PageName: options.pageName,
|
|
1482
|
+
PageTitle: options.pageTitle,
|
|
1483
|
+
PageDescription: options.pageDescription || "",
|
|
1484
|
+
pageName: this.toKebabCase(options.pageName),
|
|
1485
|
+
sectionsArray: JSON.stringify(options.sections || []),
|
|
1486
|
+
...options.additionalVariables
|
|
1487
|
+
};
|
|
1488
|
+
const genConfig = {
|
|
1489
|
+
templateDir: this.templateDir,
|
|
1490
|
+
dimensions,
|
|
1491
|
+
variables,
|
|
1492
|
+
outputDir: options.outputDir
|
|
1493
|
+
};
|
|
1494
|
+
return await this.engine.generate(genConfig);
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* Write generated files to disk
|
|
1498
|
+
*
|
|
1499
|
+
* @param result - Generation result
|
|
1500
|
+
* @returns Array of written file paths
|
|
1501
|
+
*/
|
|
1502
|
+
async write(result) {
|
|
1503
|
+
return await this.engine.writeFiles(result);
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Convert PascalCase to kebab-case
|
|
1507
|
+
*
|
|
1508
|
+
* @param str - PascalCase string
|
|
1509
|
+
* @returns kebab-case string
|
|
1510
|
+
*/
|
|
1511
|
+
toKebabCase(str) {
|
|
1512
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
// src/commands/page-generate.ts
|
|
1517
|
+
var pageGenerateCommand = new import_commander5.Command("add:page").alias("page").description("Add/Generate full page (multi-section composition)").argument("<page>", "Page ID (e.g., landing, dashboard, auth)").option(
|
|
1518
|
+
"-s, --design-system <system>",
|
|
1519
|
+
"Design system (material-design, ios-hig, glassmorphism, neumorphism, brutalism, minimalism, fluent, carbon, ant-design, chakra, atlassian, blueprint)",
|
|
1520
|
+
"material-design"
|
|
1521
|
+
).option(
|
|
1522
|
+
"-t, --tier <tier>",
|
|
1523
|
+
"Quality tier (basic, standard, enterprise)",
|
|
1524
|
+
"standard"
|
|
1525
|
+
).option(
|
|
1526
|
+
"-o, --output <path>",
|
|
1527
|
+
"Output file path"
|
|
1528
|
+
).action(async (pageId, options) => {
|
|
1529
|
+
const spinner = (0, import_ora4.default)("Generating page...").start();
|
|
1530
|
+
try {
|
|
1531
|
+
const generator = new PageGenerator();
|
|
1532
|
+
const result = await generator.generate({
|
|
1533
|
+
pageId,
|
|
1534
|
+
designSystem: options.designSystem,
|
|
1535
|
+
tier: options.tier
|
|
1536
|
+
});
|
|
1537
|
+
if (!result.success) {
|
|
1538
|
+
spinner.fail(import_chalk4.default.red("Page generation failed"));
|
|
1539
|
+
result.errors.forEach((error) => {
|
|
1540
|
+
console.error(import_chalk4.default.gray(` \u2022 ${error}`));
|
|
1541
|
+
});
|
|
1542
|
+
process.exit(1);
|
|
1543
|
+
}
|
|
1544
|
+
if (options.output) {
|
|
1545
|
+
await generator.writeToFile(options.output, result.composedCode);
|
|
1546
|
+
spinner.succeed(import_chalk4.default.green(`Generated ${result.metadata.pageId} \u2192 ${options.output}`));
|
|
1547
|
+
} else {
|
|
1548
|
+
spinner.succeed(import_chalk4.default.green(`Generated ${result.metadata.pageId}`));
|
|
1549
|
+
console.log(result.composedCode);
|
|
1550
|
+
}
|
|
1551
|
+
console.log(import_chalk4.default.cyan("\nPage Info:"));
|
|
1552
|
+
console.log(` ${import_chalk4.default.gray("ID:")} ${result.metadata.pageId}`);
|
|
1553
|
+
console.log(` ${import_chalk4.default.gray("Type:")} ${result.metadata.pageType}`);
|
|
1554
|
+
console.log(` ${import_chalk4.default.gray("Tier:")} ${result.metadata.tier}`);
|
|
1555
|
+
console.log(` ${import_chalk4.default.gray("Design System:")} ${result.metadata.designSystem}`);
|
|
1556
|
+
console.log(` ${import_chalk4.default.gray("Sections:")} ${result.metadata.sectionsGenerated}`);
|
|
1557
|
+
console.log(` ${import_chalk4.default.gray("Components:")} ${result.metadata.componentsGenerated}`);
|
|
1558
|
+
console.log(` ${import_chalk4.default.gray("Lines of Code:")} ${result.metadata.totalLinesOfCode}`);
|
|
1559
|
+
console.log("");
|
|
1560
|
+
} catch (error) {
|
|
1561
|
+
spinner.fail(import_chalk4.default.red(`Error: ${error.message}`));
|
|
1562
|
+
process.exit(1);
|
|
1563
|
+
}
|
|
1564
|
+
});
|
|
1565
|
+
|
|
1063
1566
|
// src/index.ts
|
|
1064
1567
|
var componentCount = 169;
|
|
1568
|
+
var sectionCount = 50;
|
|
1065
1569
|
var designSystemCount = 12;
|
|
1066
1570
|
var tierCount = 3;
|
|
1067
|
-
var y =
|
|
1571
|
+
var y = import_chalk5.default.hex("#fcb800");
|
|
1068
1572
|
var banner = `
|
|
1069
1573
|
${y.bold("\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557")}
|
|
1070
1574
|
${y.bold("\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D")}
|
|
@@ -1080,16 +1584,18 @@ ${y.bold(" \u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D\u2588\u
|
|
|
1080
1584
|
${y.bold(" \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 ")}
|
|
1081
1585
|
${y.bold(" \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D ")}
|
|
1082
1586
|
|
|
1083
|
-
${y(" happy together")} ${
|
|
1587
|
+
${y(" happy together")} ${import_chalk5.default.white("\u2022 v2.3.0")}
|
|
1084
1588
|
|
|
1085
|
-
${
|
|
1086
|
-
${
|
|
1589
|
+
${import_chalk5.default.gray(" Production-ready code in seconds")}
|
|
1590
|
+
${import_chalk5.default.gray(" https://nikkory.com")}
|
|
1087
1591
|
|
|
1088
|
-
${y(` ${componentCount} Components`)} ${
|
|
1592
|
+
${y(` ${componentCount} Components`)} ${import_chalk5.default.gray("+")} ${y(`${sectionCount} Sections`)} ${import_chalk5.default.gray("\xD7")} ${y(`${designSystemCount} Systems`)} ${import_chalk5.default.gray("\xD7")} ${y(`${tierCount} Tiers`)}
|
|
1089
1593
|
`;
|
|
1090
|
-
var program = new
|
|
1091
|
-
program.name("nikkory-vibe").description("Nikkory Vibe - Production-ready code in seconds").version("2.
|
|
1594
|
+
var program = new import_commander6.Command();
|
|
1595
|
+
program.name("nikkory-vibe").description("Nikkory Vibe - Production-ready code in seconds").version("2.3.0").addHelpText("before", banner);
|
|
1092
1596
|
program.addCommand(matrixGenerateCommand);
|
|
1597
|
+
program.addCommand(sectionGenerateCommand);
|
|
1598
|
+
program.addCommand(pageGenerateCommand);
|
|
1093
1599
|
program.addCommand(listCommand);
|
|
1094
1600
|
program.addCommand(initCommand);
|
|
1095
1601
|
program.parse(process.argv);
|