@famgia/omnify-cli 2.0.9 → 2.0.11

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/cli.js CHANGED
@@ -7,8 +7,8 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
7
7
  });
8
8
 
9
9
  // src/cli.ts
10
- import { existsSync as existsSync13 } from "fs";
11
- import { resolve as resolve13 } from "path";
10
+ import { existsSync as existsSync14 } from "fs";
11
+ import { resolve as resolve14 } from "path";
12
12
  import { Command } from "commander";
13
13
  import { OmnifyError as OmnifyError7 } from "@famgia/omnify-core";
14
14
 
@@ -1108,8 +1108,8 @@ function registerDiffCommand(program2) {
1108
1108
  }
1109
1109
 
1110
1110
  // src/commands/generate.ts
1111
- import { existsSync as existsSync8, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, readdirSync as readdirSync2 } from "fs";
1112
- import { resolve as resolve8, dirname as dirname6, relative } from "path";
1111
+ import { existsSync as existsSync9, mkdirSync as mkdirSync3, writeFileSync as writeFileSync5, readdirSync as readdirSync2 } from "fs";
1112
+ import { resolve as resolve9, dirname as dirname6, relative } from "path";
1113
1113
  import {
1114
1114
  loadSchemas as loadSchemas3,
1115
1115
  mergePartialSchemas as mergePartialSchemas3,
@@ -1144,17 +1144,19 @@ import { generateTypeScript, generateAIGuides as generateTypescriptAIGuides, sho
1144
1144
  // src/guides/index.ts
1145
1145
  import { existsSync as existsSync7, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3 } from "fs";
1146
1146
  import { resolve as resolve7, dirname as dirname5, join } from "path";
1147
- import "url";
1148
- var CLAUDE_MD = `# Omnify Project
1147
+ var OMNIFY_SECTION_START = "<!-- OMNIFY_SECTION_START -->";
1148
+ var OMNIFY_SECTION_END = "<!-- OMNIFY_SECTION_END -->";
1149
+ var OMNIFY_SECTION = `${OMNIFY_SECTION_START}
1150
+ ## Omnify Schema System
1149
1151
 
1150
1152
  This project uses **Omnify** for schema-driven code generation.
1151
1153
 
1152
- ## Quick Reference
1154
+ ### Quick Reference
1153
1155
 
1154
1156
  - **Schema Guide**: @.claude/omnify/guides/omnify/schema-guide.md
1155
1157
  - **Config Guide**: @.claude/omnify/guides/omnify/config-guide.md
1156
1158
 
1157
- ## Commands
1159
+ ### Commands
1158
1160
 
1159
1161
  \`\`\`bash
1160
1162
  npx omnify generate # Generate code from schemas
@@ -1162,41 +1164,52 @@ npx omnify validate # Validate schemas
1162
1164
  php artisan migrate # Run database migrations
1163
1165
  \`\`\`
1164
1166
 
1165
- ## Critical Rules
1167
+ ### Critical Rules
1166
1168
 
1167
- ### \u26D4 DO NOT EDIT Auto-Generated Files
1169
+ #### \u26D4 DO NOT EDIT Auto-Generated Files
1168
1170
  - \`database/migrations/omnify/**\` - Regenerated on \`npx omnify generate\`
1169
1171
  - \`app/Models/OmnifyBase/**\` - Base models (extend, don't edit)
1170
1172
  - \`app/Http/Requests/OmnifyBase/**\` - Base requests
1171
1173
  - \`app/Http/Resources/OmnifyBase/**\` - Base resources
1172
1174
 
1173
- ### \u2705 Schema-First Workflow
1175
+ #### \u2705 Schema-First Workflow
1174
1176
  1. Edit YAML schema in \`schemas/\`
1175
1177
  2. Run \`npx omnify generate\`
1176
1178
  3. Run \`php artisan migrate\`
1177
1179
 
1178
1180
  **NEVER use \`php artisan make:migration\`** - Always use schemas!
1181
+ ${OMNIFY_SECTION_END}`;
1182
+ function updateClaudeMd(rootDir) {
1183
+ const claudeMdPath = resolve7(rootDir, "CLAUDE.md");
1184
+ if (!existsSync7(claudeMdPath)) {
1185
+ writeFileSync3(claudeMdPath, `# Project Documentation
1179
1186
 
1180
- ## Documentation Structure
1181
-
1182
- \`\`\`
1183
- .claude/
1184
- \u251C\u2500\u2500 CLAUDE.md # This file (root pointer)
1185
- \u251C\u2500\u2500 rules/ # Claude Code rules (path-specific)
1186
- \u2502 \u2514\u2500\u2500 omnify/*.md
1187
- \u2514\u2500\u2500 omnify/ # Detailed guides
1188
- \u251C\u2500\u2500 guides/
1189
- \u2502 \u251C\u2500\u2500 omnify/ # Schema & config docs
1190
- \u2502 \u251C\u2500\u2500 laravel/ # Laravel patterns
1191
- \u2502 \u2514\u2500\u2500 react/ # React patterns
1192
- \u251C\u2500\u2500 workflows/ # Step-by-step workflows
1193
- \u2514\u2500\u2500 agents/ # AI agent prompts
1194
- \`\`\`
1195
-
1196
- ## Individual Preferences
1197
-
1198
- Add your personal preferences in \`CLAUDE.local.md\` (gitignored).
1199
- `;
1187
+ ${OMNIFY_SECTION}
1188
+ `);
1189
+ return true;
1190
+ }
1191
+ const currentContent = readFileSync3(claudeMdPath, "utf8");
1192
+ const hasOmnifySection = currentContent.includes(OMNIFY_SECTION_START);
1193
+ if (hasOmnifySection) {
1194
+ const regex = new RegExp(
1195
+ `${escapeRegExp(OMNIFY_SECTION_START)}[\\s\\S]*?${escapeRegExp(OMNIFY_SECTION_END)}`,
1196
+ "g"
1197
+ );
1198
+ const newContent = currentContent.replace(regex, OMNIFY_SECTION);
1199
+ if (newContent !== currentContent) {
1200
+ writeFileSync3(claudeMdPath, newContent);
1201
+ return true;
1202
+ }
1203
+ return false;
1204
+ } else {
1205
+ const newContent = currentContent.trimEnd() + "\n\n" + OMNIFY_SECTION + "\n";
1206
+ writeFileSync3(claudeMdPath, newContent);
1207
+ return true;
1208
+ }
1209
+ }
1210
+ function escapeRegExp(string) {
1211
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1212
+ }
1200
1213
  function copyOmnifyGuides(rootDir) {
1201
1214
  let filesWritten = 0;
1202
1215
  const omnifyPkgPaths = [
@@ -1251,20 +1264,141 @@ function copyOmnifyGuides(rootDir) {
1251
1264
  }
1252
1265
  function generateAIGuides(rootDir, _plugins) {
1253
1266
  let filesWritten = 0;
1254
- const claudeMdPath = resolve7(rootDir, "CLAUDE.md");
1255
- writeFileSync3(claudeMdPath, CLAUDE_MD);
1256
- filesWritten++;
1267
+ if (updateClaudeMd(rootDir)) {
1268
+ filesWritten++;
1269
+ }
1257
1270
  filesWritten += copyOmnifyGuides(rootDir);
1258
1271
  return filesWritten;
1259
1272
  }
1260
1273
 
1274
+ // src/version-lock/index.ts
1275
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync8 } from "fs";
1276
+ import { resolve as resolve8 } from "path";
1277
+ var VERSION_LOCK_FILE = ".omnify-versions.lock";
1278
+ function readVersionLock(rootDir) {
1279
+ const lockPath = resolve8(rootDir, VERSION_LOCK_FILE);
1280
+ if (!existsSync8(lockPath)) {
1281
+ return null;
1282
+ }
1283
+ try {
1284
+ const content = readFileSync4(lockPath, "utf-8");
1285
+ return JSON.parse(content);
1286
+ } catch {
1287
+ return null;
1288
+ }
1289
+ }
1290
+ function writeVersionLock(rootDir, lock) {
1291
+ const lockPath = resolve8(rootDir, VERSION_LOCK_FILE);
1292
+ const content = JSON.stringify(lock, null, 2);
1293
+ writeFileSync4(lockPath, content + "\n");
1294
+ }
1295
+ function parseVersion(version) {
1296
+ const cleanVersion = version.replace(/^v/, "");
1297
+ const match = cleanVersion.match(/^(\d+)\.(\d+)\.(\d+)/);
1298
+ if (!match) {
1299
+ return null;
1300
+ }
1301
+ return {
1302
+ major: parseInt(match[1], 10),
1303
+ minor: parseInt(match[2], 10),
1304
+ patch: parseInt(match[3], 10)
1305
+ };
1306
+ }
1307
+ function compareVersions(a, b) {
1308
+ const parsedA = parseVersion(a);
1309
+ const parsedB = parseVersion(b);
1310
+ if (!parsedA || !parsedB) {
1311
+ return 0;
1312
+ }
1313
+ if (parsedA.major !== parsedB.major) {
1314
+ return parsedA.major > parsedB.major ? 1 : -1;
1315
+ }
1316
+ if (parsedA.minor !== parsedB.minor) {
1317
+ return parsedA.minor > parsedB.minor ? 1 : -1;
1318
+ }
1319
+ if (parsedA.patch !== parsedB.patch) {
1320
+ return parsedA.patch > parsedB.patch ? 1 : -1;
1321
+ }
1322
+ return 0;
1323
+ }
1324
+ function checkPluginVersions(plugins, lockFile) {
1325
+ const mismatches = [];
1326
+ const newPlugins = [];
1327
+ const lockedVersions = /* @__PURE__ */ new Map();
1328
+ for (const entry of lockFile.plugins) {
1329
+ lockedVersions.set(entry.name, entry.version);
1330
+ }
1331
+ for (const plugin of plugins) {
1332
+ const lockedVersion = lockedVersions.get(plugin.name);
1333
+ if (!lockedVersion) {
1334
+ newPlugins.push(plugin.name);
1335
+ continue;
1336
+ }
1337
+ const comparison = compareVersions(plugin.version, lockedVersion);
1338
+ if (comparison < 0) {
1339
+ mismatches.push({
1340
+ name: plugin.name,
1341
+ required: lockedVersion,
1342
+ installed: plugin.version
1343
+ });
1344
+ }
1345
+ }
1346
+ return {
1347
+ valid: mismatches.length === 0,
1348
+ mismatches,
1349
+ newPlugins
1350
+ };
1351
+ }
1352
+ function updateVersionLock(rootDir, plugins, cliVersion) {
1353
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1354
+ const existingLock = readVersionLock(rootDir);
1355
+ const existingEntries = /* @__PURE__ */ new Map();
1356
+ if (existingLock) {
1357
+ for (const entry of existingLock.plugins) {
1358
+ existingEntries.set(entry.name, entry);
1359
+ }
1360
+ }
1361
+ const pluginEntries = [];
1362
+ for (const plugin of plugins) {
1363
+ const existing = existingEntries.get(plugin.name);
1364
+ if (!existing || compareVersions(plugin.version, existing.version) > 0) {
1365
+ pluginEntries.push({
1366
+ name: plugin.name,
1367
+ version: plugin.version,
1368
+ updatedAt: now
1369
+ });
1370
+ } else {
1371
+ pluginEntries.push(existing);
1372
+ }
1373
+ }
1374
+ pluginEntries.sort((a, b) => a.name.localeCompare(b.name));
1375
+ const lock = {
1376
+ version: 1,
1377
+ cliVersion,
1378
+ plugins: pluginEntries,
1379
+ updatedAt: now
1380
+ };
1381
+ writeVersionLock(rootDir, lock);
1382
+ return lock;
1383
+ }
1384
+ function getCliVersion() {
1385
+ try {
1386
+ const pkgPath = new URL("../../package.json", import.meta.url);
1387
+ const pkgContent = readFileSync4(pkgPath, "utf-8");
1388
+ const pkg = JSON.parse(pkgContent);
1389
+ return pkg.version;
1390
+ } catch {
1391
+ return "unknown";
1392
+ }
1393
+ }
1394
+
1261
1395
  // src/commands/generate.ts
1262
1396
  function hasPluginGenerators(plugins) {
1263
1397
  return plugins.some((p) => p.generators && p.generators.length > 0);
1264
1398
  }
1265
1399
  function getExistingMigrationTables(migrationsDir) {
1266
1400
  const existingTables = /* @__PURE__ */ new Set();
1267
- if (!existsSync8(migrationsDir)) {
1401
+ if (!existsSync9(migrationsDir)) {
1268
1402
  return existingTables;
1269
1403
  }
1270
1404
  try {
@@ -1457,17 +1591,17 @@ function schemaChangeToVersionChange(change) {
1457
1591
  function writeGeneratorOutputs(outputs, rootDir) {
1458
1592
  const counts = { migrations: 0, types: 0, models: 0, factories: 0, other: 0 };
1459
1593
  for (const output of outputs) {
1460
- const filePath = resolve8(rootDir, output.path);
1594
+ const filePath = resolve9(rootDir, output.path);
1461
1595
  const dir = dirname6(filePath);
1462
- if (!existsSync8(dir)) {
1596
+ if (!existsSync9(dir)) {
1463
1597
  mkdirSync3(dir, { recursive: true });
1464
1598
  logger.debug(`Created directory: ${dir}`);
1465
1599
  }
1466
- if (output.skipIfExists && existsSync8(filePath)) {
1600
+ if (output.skipIfExists && existsSync9(filePath)) {
1467
1601
  logger.debug(`Skipped (exists): ${output.path}`);
1468
1602
  continue;
1469
1603
  }
1470
- writeFileSync4(filePath, output.content);
1604
+ writeFileSync5(filePath, output.content);
1471
1605
  logger.debug(`Created: ${output.path}`);
1472
1606
  if (output.type === "migration") counts.migrations++;
1473
1607
  else if (output.type === "type") counts.types++;
@@ -1477,7 +1611,7 @@ function writeGeneratorOutputs(outputs, rootDir) {
1477
1611
  }
1478
1612
  return counts;
1479
1613
  }
1480
- async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes) {
1614
+ async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes, localeConfig) {
1481
1615
  const pluginManager = new PluginManager({
1482
1616
  cwd: rootDir,
1483
1617
  verbose,
@@ -1486,7 +1620,8 @@ async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes)
1486
1620
  info: (msg) => logger.info(msg),
1487
1621
  warn: (msg) => logger.warn(msg),
1488
1622
  error: (msg) => logger.error(msg)
1489
- }
1623
+ },
1624
+ localeConfig
1490
1625
  });
1491
1626
  for (const plugin of plugins) {
1492
1627
  await pluginManager.register(plugin);
@@ -1523,8 +1658,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1523
1658
  }
1524
1659
  if (!options.typesOnly && config.output.laravel) {
1525
1660
  logger.step("Generating Laravel migrations...");
1526
- const migrationsDir = resolve8(rootDir, config.output.laravel.migrationsPath);
1527
- if (!existsSync8(migrationsDir)) {
1661
+ const migrationsDir = resolve9(rootDir, config.output.laravel.migrationsPath);
1662
+ if (!existsSync9(migrationsDir)) {
1528
1663
  mkdirSync3(migrationsDir, { recursive: true });
1529
1664
  logger.debug(`Created directory: ${migrationsDir}`);
1530
1665
  }
@@ -1546,8 +1681,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1546
1681
  logger.debug(`Skipped CREATE for ${tableName} (already exists)`);
1547
1682
  continue;
1548
1683
  }
1549
- const filePath = resolve8(migrationsDir, migration.fileName);
1550
- writeFileSync4(filePath, migration.content);
1684
+ const filePath = resolve9(migrationsDir, migration.fileName);
1685
+ writeFileSync5(filePath, migration.content);
1551
1686
  logger.debug(`Created: ${migration.fileName}`);
1552
1687
  migrationsGenerated++;
1553
1688
  }
@@ -1555,8 +1690,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1555
1690
  if (alterChanges.length > 0) {
1556
1691
  const alterMigrations = generateMigrationsFromChanges(alterChanges);
1557
1692
  for (const migration of alterMigrations) {
1558
- const filePath = resolve8(migrationsDir, migration.fileName);
1559
- writeFileSync4(filePath, migration.content);
1693
+ const filePath = resolve9(migrationsDir, migration.fileName);
1694
+ writeFileSync5(filePath, migration.content);
1560
1695
  logger.debug(`Created: ${migration.fileName}`);
1561
1696
  migrationsGenerated++;
1562
1697
  }
@@ -1567,12 +1702,12 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1567
1702
  logger.step("Generating Laravel models...");
1568
1703
  const modelsPath = config.output.laravel.modelsPath;
1569
1704
  const baseModelsPath = config.output.laravel.baseModelsPath ?? `${modelsPath}/OmnifyBase`;
1570
- const modelsDir = resolve8(rootDir, modelsPath);
1571
- const baseModelsDir = resolve8(rootDir, baseModelsPath);
1572
- if (!existsSync8(modelsDir)) {
1705
+ const modelsDir = resolve9(rootDir, modelsPath);
1706
+ const baseModelsDir = resolve9(rootDir, baseModelsPath);
1707
+ if (!existsSync9(modelsDir)) {
1573
1708
  mkdirSync3(modelsDir, { recursive: true });
1574
1709
  }
1575
- if (!existsSync8(baseModelsDir)) {
1710
+ if (!existsSync9(baseModelsDir)) {
1576
1711
  mkdirSync3(baseModelsDir, { recursive: true });
1577
1712
  }
1578
1713
  const providersPath = config.output.laravel.providersPath ?? "app/Providers";
@@ -1583,16 +1718,16 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1583
1718
  customTypes: customTypesMap
1584
1719
  });
1585
1720
  for (const model of models) {
1586
- const filePath = resolve8(rootDir, getModelPath(model));
1721
+ const filePath = resolve9(rootDir, getModelPath(model));
1587
1722
  const fileDir = dirname6(filePath);
1588
- if (!existsSync8(fileDir)) {
1723
+ if (!existsSync9(fileDir)) {
1589
1724
  mkdirSync3(fileDir, { recursive: true });
1590
1725
  }
1591
- if (!model.overwrite && existsSync8(filePath)) {
1726
+ if (!model.overwrite && existsSync9(filePath)) {
1592
1727
  logger.debug(`Skipped (exists): ${getModelPath(model)}`);
1593
1728
  continue;
1594
1729
  }
1595
- writeFileSync4(filePath, model.content);
1730
+ writeFileSync5(filePath, model.content);
1596
1731
  logger.debug(`Created: ${getModelPath(model)}`);
1597
1732
  modelsGenerated++;
1598
1733
  }
@@ -1601,24 +1736,24 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1601
1736
  if (!options.typesOnly && config.output.laravel?.factoriesPath) {
1602
1737
  logger.step("Generating Laravel factories...");
1603
1738
  const factoriesPath = config.output.laravel.factoriesPath;
1604
- const factoriesDir = resolve8(rootDir, factoriesPath);
1605
- if (!existsSync8(factoriesDir)) {
1739
+ const factoriesDir = resolve9(rootDir, factoriesPath);
1740
+ if (!existsSync9(factoriesDir)) {
1606
1741
  mkdirSync3(factoriesDir, { recursive: true });
1607
1742
  }
1608
1743
  const factories = generateFactories(schemas, {
1609
1744
  factoryPath: factoriesPath
1610
1745
  });
1611
1746
  for (const factory of factories) {
1612
- const filePath = resolve8(rootDir, getFactoryPath(factory));
1747
+ const filePath = resolve9(rootDir, getFactoryPath(factory));
1613
1748
  const fileDir = dirname6(filePath);
1614
- if (!existsSync8(fileDir)) {
1749
+ if (!existsSync9(fileDir)) {
1615
1750
  mkdirSync3(fileDir, { recursive: true });
1616
1751
  }
1617
- if (!factory.overwrite && existsSync8(filePath)) {
1752
+ if (!factory.overwrite && existsSync9(filePath)) {
1618
1753
  logger.debug(`Skipped (exists): ${getFactoryPath(factory)}`);
1619
1754
  continue;
1620
1755
  }
1621
- writeFileSync4(filePath, factory.content);
1756
+ writeFileSync5(filePath, factory.content);
1622
1757
  logger.debug(`Created: ${getFactoryPath(factory)}`);
1623
1758
  factoriesGenerated++;
1624
1759
  }
@@ -1627,32 +1762,32 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1627
1762
  if (!options.migrationsOnly && config.output.typescript) {
1628
1763
  logger.step("Generating TypeScript types...");
1629
1764
  const tsConfig = config.output.typescript;
1630
- const basePath = resolve8(rootDir, tsConfig.path);
1631
- const schemasDir = resolve8(basePath, tsConfig.schemasDir ?? "schemas");
1632
- const enumDir = resolve8(basePath, tsConfig.enumDir ?? "enum");
1633
- const omnifyBaseDir = resolve8(rootDir, "node_modules/@omnify-base");
1634
- const pluginEnumDir = resolve8(omnifyBaseDir, "enum");
1635
- const baseSchemasDir = resolve8(omnifyBaseDir, "schemas");
1765
+ const basePath = resolve9(rootDir, tsConfig.path);
1766
+ const schemasDir = resolve9(basePath, tsConfig.schemasDir ?? "schemas");
1767
+ const enumDir = resolve9(basePath, tsConfig.enumDir ?? "enum");
1768
+ const omnifyBaseDir = resolve9(rootDir, "node_modules/@omnify-base");
1769
+ const pluginEnumDir = resolve9(omnifyBaseDir, "enum");
1770
+ const baseSchemasDir = resolve9(omnifyBaseDir, "schemas");
1636
1771
  const enumImportPrefix = relative(schemasDir, enumDir).replace(/\\/g, "/");
1637
- if (!existsSync8(schemasDir)) {
1772
+ if (!existsSync9(schemasDir)) {
1638
1773
  mkdirSync3(schemasDir, { recursive: true });
1639
1774
  logger.debug(`Created directory: ${schemasDir}`);
1640
1775
  }
1641
- if (!existsSync8(enumDir)) {
1776
+ if (!existsSync9(enumDir)) {
1642
1777
  mkdirSync3(enumDir, { recursive: true });
1643
1778
  logger.debug(`Created directory: ${enumDir}`);
1644
1779
  }
1645
- if (!existsSync8(pluginEnumDir)) {
1780
+ if (!existsSync9(pluginEnumDir)) {
1646
1781
  mkdirSync3(pluginEnumDir, { recursive: true });
1647
1782
  logger.debug(`Created directory: ${pluginEnumDir}`);
1648
1783
  }
1649
- if (!existsSync8(baseSchemasDir)) {
1784
+ if (!existsSync9(baseSchemasDir)) {
1650
1785
  mkdirSync3(baseSchemasDir, { recursive: true });
1651
1786
  logger.debug(`Created directory: ${baseSchemasDir}`);
1652
1787
  }
1653
- const omnifyPkgJson = resolve8(omnifyBaseDir, "package.json");
1654
- if (!existsSync8(omnifyPkgJson)) {
1655
- writeFileSync4(omnifyPkgJson, JSON.stringify({
1788
+ const omnifyPkgJson = resolve9(omnifyBaseDir, "package.json");
1789
+ if (!existsSync9(omnifyPkgJson)) {
1790
+ writeFileSync5(omnifyPkgJson, JSON.stringify({
1656
1791
  name: "@omnify-base",
1657
1792
  version: "0.0.0",
1658
1793
  private: true,
@@ -1689,16 +1824,16 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
1689
1824
  } else {
1690
1825
  outputDir = schemasDir;
1691
1826
  }
1692
- const filePath = resolve8(outputDir, outputFilePath);
1827
+ const filePath = resolve9(outputDir, outputFilePath);
1693
1828
  const fileDir = dirname6(filePath);
1694
- if (!existsSync8(fileDir)) {
1829
+ if (!existsSync9(fileDir)) {
1695
1830
  mkdirSync3(fileDir, { recursive: true });
1696
1831
  }
1697
- if (!file.overwrite && existsSync8(filePath)) {
1832
+ if (!file.overwrite && existsSync9(filePath)) {
1698
1833
  logger.debug(`Skipped (exists): ${file.filePath}`);
1699
1834
  continue;
1700
1835
  }
1701
- writeFileSync4(filePath, file.content);
1836
+ writeFileSync5(filePath, file.content);
1702
1837
  logger.debug(`Created: ${file.filePath}`);
1703
1838
  typesGenerated++;
1704
1839
  }
@@ -1728,7 +1863,49 @@ async function runGenerate(options) {
1728
1863
  const { config, configPath: configPath2 } = await loadConfig();
1729
1864
  const rootDir = configPath2 ? dirname6(configPath2) : process.cwd();
1730
1865
  validateConfig(config, rootDir);
1731
- const schemaPath = resolve8(rootDir, config.schemasDir);
1866
+ if (config.plugins.length > 0) {
1867
+ const versionLock = readVersionLock(rootDir);
1868
+ if (versionLock) {
1869
+ logger.debug("Checking plugin versions against lock file...");
1870
+ const versionCheck = checkPluginVersions(config.plugins, versionLock);
1871
+ if (!versionCheck.valid) {
1872
+ logger.newline();
1873
+ logger.error("\u{1F512} PLUGIN VERSION MISMATCH");
1874
+ logger.error("");
1875
+ logger.error("The following plugins are older than required by the version lock:");
1876
+ logger.newline();
1877
+ for (const mismatch of versionCheck.mismatches) {
1878
+ logger.error(` \u2022 ${mismatch.name}`);
1879
+ logger.error(` Required: ${mismatch.required}`);
1880
+ logger.error(` Installed: ${mismatch.installed}`);
1881
+ }
1882
+ logger.newline();
1883
+ logger.error(`Version lock file: ${VERSION_LOCK_FILE}`);
1884
+ logger.newline();
1885
+ logger.info("To fix this, upgrade the outdated plugins:");
1886
+ logger.info("");
1887
+ for (const mismatch of versionCheck.mismatches) {
1888
+ logger.info(` npm install ${mismatch.name}@latest`);
1889
+ }
1890
+ logger.newline();
1891
+ logger.info("Or if you intentionally want to use older versions, delete the lock file:");
1892
+ logger.info(` rm ${VERSION_LOCK_FILE}`);
1893
+ logger.newline();
1894
+ throw new OmnifyError4(
1895
+ "Plugin version mismatch: installed versions are older than lock file requirements",
1896
+ "E501",
1897
+ void 0,
1898
+ "Upgrade plugins or delete the version lock file to regenerate it."
1899
+ );
1900
+ }
1901
+ if (versionCheck.newPlugins.length > 0) {
1902
+ logger.debug(`New plugins detected: ${versionCheck.newPlugins.join(", ")}`);
1903
+ }
1904
+ } else {
1905
+ logger.debug(`No version lock file found (${VERSION_LOCK_FILE})`);
1906
+ }
1907
+ }
1908
+ const schemaPath = resolve9(rootDir, config.schemasDir);
1732
1909
  logger.step(`Loading schemas from ${schemaPath}`);
1733
1910
  let schemas = await loadSchemas3(schemaPath);
1734
1911
  logger.debug(`Found ${Object.keys(schemas).length} schema(s) in main directory`);
@@ -1737,9 +1914,9 @@ async function runGenerate(options) {
1737
1914
  if (additionalPaths.length > 0) {
1738
1915
  logger.step(`Loading schemas from ${additionalPaths.length} additional path(s)`);
1739
1916
  for (const entry of additionalPaths) {
1740
- const absolutePath = resolve8(rootDir, entry.path);
1917
+ const absolutePath = resolve9(rootDir, entry.path);
1741
1918
  logger.debug(` Checking: ${entry.path} \u2192 ${absolutePath}`);
1742
- if (existsSync8(absolutePath)) {
1919
+ if (existsSync9(absolutePath)) {
1743
1920
  let packageSchemas = await loadSchemas3(absolutePath, { skipPartialResolution: true });
1744
1921
  if (entry.output) {
1745
1922
  const schemasWithOutput = {};
@@ -1794,12 +1971,12 @@ async function runGenerate(options) {
1794
1971
  process.exit(2);
1795
1972
  }
1796
1973
  logger.step("Checking for changes...");
1797
- const lockPath = resolve8(rootDir, config.lockFilePath);
1974
+ const lockPath = resolve9(rootDir, config.lockFilePath);
1798
1975
  const existingLock = await readLockFile(lockPath);
1799
1976
  const currentSnapshots = await buildSchemaSnapshots(schemas);
1800
1977
  const v2Lock = existingLock && isLockFileV2(existingLock) ? existingLock : null;
1801
1978
  const comparison = compareSchemasDeep(currentSnapshots, v2Lock);
1802
- const chainFilePath = resolve8(rootDir, VERSION_CHAIN_FILE);
1979
+ const chainFilePath = resolve9(rootDir, VERSION_CHAIN_FILE);
1803
1980
  const versionChain = await readVersionChain(chainFilePath);
1804
1981
  if (versionChain && comparison.hasChanges) {
1805
1982
  const schemaActions = [];
@@ -1836,7 +2013,7 @@ async function runGenerate(options) {
1836
2013
  }
1837
2014
  }
1838
2015
  if (existingLock && config.output.laravel?.migrationsPath) {
1839
- const migrationsDir = resolve8(rootDir, config.output.laravel.migrationsPath);
2016
+ const migrationsDir = resolve9(rootDir, config.output.laravel.migrationsPath);
1840
2017
  const migrationValidation = await validateMigrations(existingLock, migrationsDir);
1841
2018
  if (!migrationValidation.valid) {
1842
2019
  logger.newline();
@@ -1896,7 +2073,7 @@ async function runGenerate(options) {
1896
2073
  const alterMigrations = toRegenerate.filter((m) => m.type === "alter" || m.type === "drop");
1897
2074
  if (createMigrations.length > 0) {
1898
2075
  logger.info(`Regenerating ${createMigrations.length} missing CREATE migration(s) with original timestamps...`);
1899
- const migrationsDir2 = resolve8(rootDir, config.output.laravel.migrationsPath);
2076
+ const migrationsDir2 = resolve9(rootDir, config.output.laravel.migrationsPath);
1900
2077
  const customTypesMap2 = /* @__PURE__ */ new Map();
1901
2078
  for (const plugin of config.plugins) {
1902
2079
  if (plugin.types) {
@@ -1918,8 +2095,8 @@ async function runGenerate(options) {
1918
2095
  customTypes: customTypesMap2
1919
2096
  });
1920
2097
  for (const mig of regenerated) {
1921
- const filePath = resolve8(migrationsDir2, migData.fileName);
1922
- writeFileSync4(filePath, mig.content);
2098
+ const filePath = resolve9(migrationsDir2, migData.fileName);
2099
+ writeFileSync5(filePath, mig.content);
1923
2100
  logger.success(` Regenerated: ${migData.fileName}`);
1924
2101
  }
1925
2102
  }
@@ -1975,7 +2152,8 @@ async function runGenerate(options) {
1975
2152
  schemas,
1976
2153
  rootDir,
1977
2154
  options.verbose ?? false,
1978
- comparison.changes
2155
+ comparison.changes,
2156
+ config.locale
1979
2157
  );
1980
2158
  migrationsGenerated = counts.migrations;
1981
2159
  typesGenerated = counts.types;
@@ -1997,32 +2175,32 @@ async function runGenerate(options) {
1997
2175
  if (!options.migrationsOnly && config.output.typescript && typesGenerated === 0) {
1998
2176
  logger.step("Generating TypeScript types...");
1999
2177
  const tsConfig2 = config.output.typescript;
2000
- const basePath2 = resolve8(rootDir, tsConfig2.path);
2001
- const schemasDir2 = resolve8(basePath2, tsConfig2.schemasDir ?? "schemas");
2002
- const enumDir2 = resolve8(basePath2, tsConfig2.enumDir ?? "enum");
2003
- const omnifyBaseDir2 = resolve8(rootDir, "node_modules/@omnify-base");
2004
- const pluginEnumDir2 = resolve8(omnifyBaseDir2, "enum");
2005
- const baseSchemasDir2 = resolve8(omnifyBaseDir2, "schemas");
2178
+ const basePath2 = resolve9(rootDir, tsConfig2.path);
2179
+ const schemasDir2 = resolve9(basePath2, tsConfig2.schemasDir ?? "schemas");
2180
+ const enumDir2 = resolve9(basePath2, tsConfig2.enumDir ?? "enum");
2181
+ const omnifyBaseDir2 = resolve9(rootDir, "node_modules/@omnify-base");
2182
+ const pluginEnumDir2 = resolve9(omnifyBaseDir2, "enum");
2183
+ const baseSchemasDir2 = resolve9(omnifyBaseDir2, "schemas");
2006
2184
  const enumImportPrefix2 = relative(schemasDir2, enumDir2).replace(/\\/g, "/");
2007
- if (!existsSync8(schemasDir2)) {
2185
+ if (!existsSync9(schemasDir2)) {
2008
2186
  mkdirSync3(schemasDir2, { recursive: true });
2009
2187
  logger.debug(`Created directory: ${schemasDir2}`);
2010
2188
  }
2011
- if (!existsSync8(enumDir2)) {
2189
+ if (!existsSync9(enumDir2)) {
2012
2190
  mkdirSync3(enumDir2, { recursive: true });
2013
2191
  logger.debug(`Created directory: ${enumDir2}`);
2014
2192
  }
2015
- if (!existsSync8(pluginEnumDir2)) {
2193
+ if (!existsSync9(pluginEnumDir2)) {
2016
2194
  mkdirSync3(pluginEnumDir2, { recursive: true });
2017
2195
  logger.debug(`Created directory: ${pluginEnumDir2}`);
2018
2196
  }
2019
- if (!existsSync8(baseSchemasDir2)) {
2197
+ if (!existsSync9(baseSchemasDir2)) {
2020
2198
  mkdirSync3(baseSchemasDir2, { recursive: true });
2021
2199
  logger.debug(`Created directory: ${baseSchemasDir2}`);
2022
2200
  }
2023
- const omnifyPkgJson2 = resolve8(omnifyBaseDir2, "package.json");
2024
- if (!existsSync8(omnifyPkgJson2)) {
2025
- writeFileSync4(omnifyPkgJson2, JSON.stringify({
2201
+ const omnifyPkgJson2 = resolve9(omnifyBaseDir2, "package.json");
2202
+ if (!existsSync9(omnifyPkgJson2)) {
2203
+ writeFileSync5(omnifyPkgJson2, JSON.stringify({
2026
2204
  name: "@omnify-base",
2027
2205
  version: "0.0.0",
2028
2206
  private: true,
@@ -2059,16 +2237,16 @@ async function runGenerate(options) {
2059
2237
  } else {
2060
2238
  outputDir2 = schemasDir2;
2061
2239
  }
2062
- const filePath = resolve8(outputDir2, outputFilePath2);
2240
+ const filePath = resolve9(outputDir2, outputFilePath2);
2063
2241
  const fileDir = dirname6(filePath);
2064
- if (!existsSync8(fileDir)) {
2242
+ if (!existsSync9(fileDir)) {
2065
2243
  mkdirSync3(fileDir, { recursive: true });
2066
2244
  }
2067
- if (!file.overwrite && existsSync8(filePath)) {
2245
+ if (!file.overwrite && existsSync9(filePath)) {
2068
2246
  logger.debug(`Skipped (exists): ${file.filePath}`);
2069
2247
  continue;
2070
2248
  }
2071
- writeFileSync4(filePath, file.content);
2249
+ writeFileSync5(filePath, file.content);
2072
2250
  logger.debug(`Created: ${file.filePath}`);
2073
2251
  typesGenerated++;
2074
2252
  }
@@ -2138,6 +2316,15 @@ async function runGenerate(options) {
2138
2316
  } catch (guideError) {
2139
2317
  logger.debug(`Could not generate AI guides: ${guideError.message}`);
2140
2318
  }
2319
+ if (config.plugins.length > 0) {
2320
+ try {
2321
+ const cliVersion = getCliVersion();
2322
+ const updatedLock = updateVersionLock(rootDir, config.plugins, cliVersion);
2323
+ logger.debug(`Updated version lock: ${updatedLock.plugins.length} plugin(s)`);
2324
+ } catch (lockError) {
2325
+ logger.debug(`Could not update version lock: ${lockError.message}`);
2326
+ }
2327
+ }
2141
2328
  logger.newline();
2142
2329
  logger.success("Generation complete!");
2143
2330
  if (migrationsGenerated > 0 && config.output.laravel) {
@@ -2168,23 +2355,23 @@ function registerGenerateCommand(program2) {
2168
2355
  }
2169
2356
 
2170
2357
  // src/commands/reset.ts
2171
- import { existsSync as existsSync9, readdirSync as readdirSync3, rmSync, statSync } from "fs";
2172
- import { resolve as resolve9, dirname as dirname7, join as join2 } from "path";
2358
+ import { existsSync as existsSync10, readdirSync as readdirSync3, rmSync, statSync } from "fs";
2359
+ import { resolve as resolve10, dirname as dirname7, join as join2 } from "path";
2173
2360
  import { createInterface } from "readline";
2174
2361
  async function confirm2(message) {
2175
2362
  const rl = createInterface({
2176
2363
  input: process.stdin,
2177
2364
  output: process.stdout
2178
2365
  });
2179
- return new Promise((resolve14) => {
2366
+ return new Promise((resolve15) => {
2180
2367
  rl.question(`${message} (y/N) `, (answer) => {
2181
2368
  rl.close();
2182
- resolve14(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
2369
+ resolve15(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
2183
2370
  });
2184
2371
  });
2185
2372
  }
2186
2373
  function countFiles(dir) {
2187
- if (!existsSync9(dir)) return 0;
2374
+ if (!existsSync10(dir)) return 0;
2188
2375
  let count = 0;
2189
2376
  const entries = readdirSync3(dir);
2190
2377
  for (const entry of entries) {
@@ -2199,7 +2386,7 @@ function countFiles(dir) {
2199
2386
  return count;
2200
2387
  }
2201
2388
  function deleteDir(dir, verbose) {
2202
- if (!existsSync9(dir)) return 0;
2389
+ if (!existsSync10(dir)) return 0;
2203
2390
  const count = countFiles(dir);
2204
2391
  rmSync(dir, { recursive: true, force: true });
2205
2392
  if (verbose) {
@@ -2208,7 +2395,7 @@ function deleteDir(dir, verbose) {
2208
2395
  return count;
2209
2396
  }
2210
2397
  function deleteFilesInDir(dir, pattern, verbose) {
2211
- if (!existsSync9(dir)) return 0;
2398
+ if (!existsSync10(dir)) return 0;
2212
2399
  let count = 0;
2213
2400
  const entries = readdirSync3(dir);
2214
2401
  for (const entry of entries) {
@@ -2243,8 +2430,8 @@ async function runReset(options) {
2243
2430
  ];
2244
2431
  for (const { name, paths: relPaths } of omnifyBasePaths) {
2245
2432
  for (const relPath of relPaths) {
2246
- const omnifyBasePath = resolve9(rootDir, relPath);
2247
- if (existsSync9(omnifyBasePath)) {
2433
+ const omnifyBasePath = resolve10(rootDir, relPath);
2434
+ if (existsSync10(omnifyBasePath)) {
2248
2435
  paths.push({ name, path: omnifyBasePath, type: "dir" });
2249
2436
  break;
2250
2437
  }
@@ -2252,8 +2439,8 @@ async function runReset(options) {
2252
2439
  }
2253
2440
  for (const { name, paths: relPaths } of legacyGeneratedPaths) {
2254
2441
  for (const relPath of relPaths) {
2255
- const legacyPath = resolve9(rootDir, relPath);
2256
- if (existsSync9(legacyPath)) {
2442
+ const legacyPath = resolve10(rootDir, relPath);
2443
+ if (existsSync10(legacyPath)) {
2257
2444
  paths.push({ name, path: legacyPath, type: "dir" });
2258
2445
  break;
2259
2446
  }
@@ -2264,8 +2451,8 @@ async function runReset(options) {
2264
2451
  "backend/database/migrations/omnify"
2265
2452
  ];
2266
2453
  for (const relPath of migrationPaths) {
2267
- const migrationsPath = resolve9(rootDir, relPath);
2268
- if (existsSync9(migrationsPath)) {
2454
+ const migrationsPath = resolve10(rootDir, relPath);
2455
+ if (existsSync10(migrationsPath)) {
2269
2456
  paths.push({
2270
2457
  name: "Omnify migrations",
2271
2458
  path: migrationsPath,
@@ -2277,15 +2464,15 @@ async function runReset(options) {
2277
2464
  }
2278
2465
  const laravelConfig = config.output.laravel;
2279
2466
  if (laravelConfig?.modelsPath) {
2280
- const modelsPath = resolve9(rootDir, laravelConfig.modelsPath);
2467
+ const modelsPath = resolve10(rootDir, laravelConfig.modelsPath);
2281
2468
  const omnifyBasePath = join2(modelsPath, "OmnifyBase");
2282
- if (existsSync9(omnifyBasePath) && !paths.some((p) => p.path === omnifyBasePath)) {
2469
+ if (existsSync10(omnifyBasePath) && !paths.some((p) => p.path === omnifyBasePath)) {
2283
2470
  paths.push({ name: "OmnifyBase models", path: omnifyBasePath, type: "dir" });
2284
2471
  }
2285
2472
  }
2286
2473
  if (laravelConfig?.migrationsPath) {
2287
- const migrationsPath = resolve9(rootDir, laravelConfig.migrationsPath);
2288
- if (existsSync9(migrationsPath) && !paths.some((p) => p.path === migrationsPath)) {
2474
+ const migrationsPath = resolve10(rootDir, laravelConfig.migrationsPath);
2475
+ if (existsSync10(migrationsPath) && !paths.some((p) => p.path === migrationsPath)) {
2289
2476
  paths.push({
2290
2477
  name: "Omnify migrations",
2291
2478
  path: migrationsPath,
@@ -2298,18 +2485,18 @@ async function runReset(options) {
2298
2485
  for (const additionalPath of config.additionalSchemaPaths) {
2299
2486
  const pkgOutput = additionalPath.output?.laravel;
2300
2487
  if (pkgOutput?.base) {
2301
- const pkgBase = resolve9(rootDir, pkgOutput.base);
2488
+ const pkgBase = resolve10(rootDir, pkgOutput.base);
2302
2489
  const pkgName = additionalPath.namespace ?? "Package";
2303
2490
  const pkgOmnifyBase = join2(pkgBase, pkgOutput.baseModelsPath ?? "src/Models/OmnifyBase");
2304
- if (existsSync9(pkgOmnifyBase) && !paths.some((p) => p.path === pkgOmnifyBase)) {
2491
+ if (existsSync10(pkgOmnifyBase) && !paths.some((p) => p.path === pkgOmnifyBase)) {
2305
2492
  paths.push({ name: `${pkgName} OmnifyBase`, path: pkgOmnifyBase, type: "dir" });
2306
2493
  }
2307
2494
  const pkgGenerated = join2(pkgBase, "src/Models/Generated");
2308
- if (existsSync9(pkgGenerated) && !paths.some((p) => p.path === pkgGenerated)) {
2495
+ if (existsSync10(pkgGenerated) && !paths.some((p) => p.path === pkgGenerated)) {
2309
2496
  paths.push({ name: `${pkgName} Legacy Generated`, path: pkgGenerated, type: "dir" });
2310
2497
  }
2311
2498
  const pkgMigrations = join2(pkgBase, pkgOutput.migrationsPath ?? "database/migrations/omnify");
2312
- if (existsSync9(pkgMigrations) && !paths.some((p) => p.path === pkgMigrations)) {
2499
+ if (existsSync10(pkgMigrations) && !paths.some((p) => p.path === pkgMigrations)) {
2313
2500
  paths.push({
2314
2501
  name: `${pkgName} migrations`,
2315
2502
  path: pkgMigrations,
@@ -2317,18 +2504,18 @@ async function runReset(options) {
2317
2504
  });
2318
2505
  }
2319
2506
  const pkgProviders = join2(pkgBase, pkgOutput.providersPath ?? "src/Providers");
2320
- if (existsSync9(pkgProviders) && !paths.some((p) => p.path === pkgProviders)) {
2507
+ if (existsSync10(pkgProviders) && !paths.some((p) => p.path === pkgProviders)) {
2321
2508
  paths.push({ name: `${pkgName} Providers`, path: pkgProviders, type: "dir" });
2322
2509
  }
2323
2510
  const pkgFactories = join2(pkgBase, pkgOutput.factoriesPath ?? "database/factories");
2324
- if (existsSync9(pkgFactories) && !paths.some((p) => p.path === pkgFactories)) {
2511
+ if (existsSync10(pkgFactories) && !paths.some((p) => p.path === pkgFactories)) {
2325
2512
  paths.push({ name: `${pkgName} Factories`, path: pkgFactories, type: "dir" });
2326
2513
  }
2327
2514
  }
2328
2515
  }
2329
2516
  }
2330
2517
  const typescriptPath = config.output.typescript?.path;
2331
- const tsBasePath = typescriptPath ? resolve9(rootDir, typescriptPath) : null;
2518
+ const tsBasePath = typescriptPath ? resolve10(rootDir, typescriptPath) : null;
2332
2519
  const commonTsPaths = [
2333
2520
  "resources/ts/omnify",
2334
2521
  "resources/ts/omnify/schemas",
@@ -2338,45 +2525,45 @@ async function runReset(options) {
2338
2525
  "src/types/models"
2339
2526
  ];
2340
2527
  let foundTsPath = tsBasePath;
2341
- if (!foundTsPath || !existsSync9(foundTsPath)) {
2528
+ if (!foundTsPath || !existsSync10(foundTsPath)) {
2342
2529
  for (const relPath of commonTsPaths) {
2343
- const tsPath = resolve9(rootDir, relPath);
2344
- if (existsSync9(tsPath)) {
2530
+ const tsPath = resolve10(rootDir, relPath);
2531
+ if (existsSync10(tsPath)) {
2345
2532
  foundTsPath = tsPath;
2346
2533
  break;
2347
2534
  }
2348
2535
  }
2349
2536
  }
2350
- if (foundTsPath && existsSync9(foundTsPath)) {
2537
+ if (foundTsPath && existsSync10(foundTsPath)) {
2351
2538
  const autoGeneratedDirs = ["base", "enum", "rules", "hooks", "lib"];
2352
2539
  for (const subDir of autoGeneratedDirs) {
2353
2540
  const subPath = join2(foundTsPath, subDir);
2354
- if (existsSync9(subPath)) {
2541
+ if (existsSync10(subPath)) {
2355
2542
  paths.push({ name: `TypeScript ${subDir}`, path: subPath, type: "dir" });
2356
2543
  }
2357
2544
  }
2358
2545
  const autoGeneratedFiles = ["common.ts", "index.ts", "i18n.ts"];
2359
2546
  for (const fileName of autoGeneratedFiles) {
2360
2547
  const filePath = join2(foundTsPath, fileName);
2361
- if (existsSync9(filePath)) {
2548
+ if (existsSync10(filePath)) {
2362
2549
  paths.push({ name: `TypeScript ${fileName}`, path: filePath, type: "file" });
2363
2550
  }
2364
2551
  }
2365
2552
  }
2366
- const lockFilePath = resolve9(rootDir, config.lockFilePath);
2367
- if (existsSync9(lockFilePath)) {
2553
+ const lockFilePath = resolve10(rootDir, config.lockFilePath);
2554
+ if (existsSync10(lockFilePath)) {
2368
2555
  paths.push({ name: "Lock file", path: lockFilePath, type: "file" });
2369
2556
  }
2370
- const versionsDir = resolve9(rootDir, ".omnify-versions");
2371
- if (existsSync9(versionsDir)) {
2557
+ const versionsDir = resolve10(rootDir, ".omnify-versions");
2558
+ if (existsSync10(versionsDir)) {
2372
2559
  paths.push({ name: "Version history", path: versionsDir, type: "dir" });
2373
2560
  }
2374
- const omnifyVersionsDir = resolve9(rootDir, ".omnify/versions");
2375
- if (existsSync9(omnifyVersionsDir)) {
2561
+ const omnifyVersionsDir = resolve10(rootDir, ".omnify/versions");
2562
+ if (existsSync10(omnifyVersionsDir)) {
2376
2563
  paths.push({ name: "Version history (.omnify/versions)", path: omnifyVersionsDir, type: "dir" });
2377
2564
  }
2378
- const logsDir = resolve9(rootDir, ".omnify/logs");
2379
- if (existsSync9(logsDir)) {
2565
+ const logsDir = resolve10(rootDir, ".omnify/logs");
2566
+ if (existsSync10(logsDir)) {
2380
2567
  paths.push({ name: "Logs", path: logsDir, type: "dir" });
2381
2568
  }
2382
2569
  if (paths.length === 0) {
@@ -2447,8 +2634,8 @@ function registerResetCommand(program2) {
2447
2634
 
2448
2635
  // src/commands/create-project.ts
2449
2636
  import { execSync, spawn } from "child_process";
2450
- import { existsSync as existsSync10, rmSync as rmSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "fs";
2451
- import { resolve as resolve10 } from "path";
2637
+ import { existsSync as existsSync11, rmSync as rmSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "fs";
2638
+ import { resolve as resolve11 } from "path";
2452
2639
  var BOILERPLATE_REPO = "https://github.com/omnifyjp/omnify-laravel-boilerplate.git";
2453
2640
  var IS_WINDOWS = process.platform === "win32";
2454
2641
  function checkGit() {
@@ -2549,9 +2736,9 @@ var GITIGNORE_ENTRIES_TO_REMOVE = [
2549
2736
  ".claude/omnify/"
2550
2737
  ];
2551
2738
  function cleanupGitignore(targetDir) {
2552
- const gitignorePath = resolve10(targetDir, ".gitignore");
2553
- if (!existsSync10(gitignorePath)) return;
2554
- const content = readFileSync4(gitignorePath, "utf-8");
2739
+ const gitignorePath = resolve11(targetDir, ".gitignore");
2740
+ if (!existsSync11(gitignorePath)) return;
2741
+ const content = readFileSync5(gitignorePath, "utf-8");
2555
2742
  const lines = content.split("\n");
2556
2743
  const cleanedLines = lines.filter((line) => {
2557
2744
  const trimmed = line.trim();
@@ -2560,13 +2747,13 @@ function cleanupGitignore(targetDir) {
2560
2747
  while (cleanedLines.length > 0 && cleanedLines[0].trim() === "") {
2561
2748
  cleanedLines.shift();
2562
2749
  }
2563
- writeFileSync5(gitignorePath, cleanedLines.join("\n"));
2750
+ writeFileSync6(gitignorePath, cleanedLines.join("\n"));
2564
2751
  }
2565
2752
  function cloneRepo(repo, targetDir) {
2566
2753
  logger.step(`Cloning boilerplate from ${repo}...`);
2567
2754
  execSync(`git clone --depth 1 ${repo} "${targetDir}"`, { stdio: "inherit" });
2568
- const gitDir = resolve10(targetDir, ".git");
2569
- if (existsSync10(gitDir)) {
2755
+ const gitDir = resolve11(targetDir, ".git");
2756
+ if (existsSync11(gitDir)) {
2570
2757
  rmSync2(gitDir, { recursive: true, force: true });
2571
2758
  }
2572
2759
  cleanupGitignore(targetDir);
@@ -2574,7 +2761,7 @@ function cloneRepo(repo, targetDir) {
2574
2761
  logger.success("Repository cloned successfully");
2575
2762
  }
2576
2763
  function runCommand(command, targetDir) {
2577
- return new Promise((resolve14, reject) => {
2764
+ return new Promise((resolve15, reject) => {
2578
2765
  const child = spawn(command, [], {
2579
2766
  cwd: targetDir,
2580
2767
  shell: true,
@@ -2582,7 +2769,7 @@ function runCommand(command, targetDir) {
2582
2769
  });
2583
2770
  child.on("close", (code) => {
2584
2771
  if (code === 0) {
2585
- resolve14();
2772
+ resolve15();
2586
2773
  } else {
2587
2774
  reject(new Error(`Command failed with exit code ${code}`));
2588
2775
  }
@@ -2630,13 +2817,13 @@ async function runSetup(targetDir) {
2630
2817
  }
2631
2818
  }
2632
2819
  async function runCreateProject(projectName, options) {
2633
- const targetDir = resolve10(process.cwd(), projectName);
2820
+ const targetDir = resolve11(process.cwd(), projectName);
2634
2821
  const repo = options.repo ?? BOILERPLATE_REPO;
2635
2822
  if (!checkGit()) {
2636
2823
  logger.error("Git is not installed. Please install git first.");
2637
2824
  process.exit(1);
2638
2825
  }
2639
- if (existsSync10(targetDir)) {
2826
+ if (existsSync11(targetDir)) {
2640
2827
  logger.error(`Directory "${projectName}" already exists.`);
2641
2828
  process.exit(1);
2642
2829
  }
@@ -2662,7 +2849,7 @@ async function runCreateProject(projectName, options) {
2662
2849
  logger.info(" pnpm run dev");
2663
2850
  logger.newline();
2664
2851
  } catch (error) {
2665
- if (!cloneSucceeded && existsSync10(targetDir)) {
2852
+ if (!cloneSucceeded && existsSync11(targetDir)) {
2666
2853
  rmSync2(targetDir, { recursive: true, force: true });
2667
2854
  } else if (cloneSucceeded) {
2668
2855
  logger.newline();
@@ -2688,8 +2875,8 @@ function registerCreateProjectCommand(program2) {
2688
2875
  }
2689
2876
 
2690
2877
  // src/commands/deploy.ts
2691
- import { existsSync as existsSync11 } from "fs";
2692
- import { resolve as resolve11, dirname as dirname8 } from "path";
2878
+ import { existsSync as existsSync12 } from "fs";
2879
+ import { resolve as resolve12, dirname as dirname8 } from "path";
2693
2880
  import { loadSchemas as loadSchemas4, OmnifyError as OmnifyError5 } from "@famgia/omnify-core";
2694
2881
  import {
2695
2882
  VERSION_CHAIN_FILE as VERSION_CHAIN_FILE2,
@@ -2704,7 +2891,7 @@ async function confirmDeploy(schemaCount, environment, version) {
2704
2891
  input: process.stdin,
2705
2892
  output: process.stdout
2706
2893
  });
2707
- return new Promise((resolve14) => {
2894
+ return new Promise((resolve15) => {
2708
2895
  logger.newline();
2709
2896
  logger.warn("\u26A0\uFE0F WARNING: This action is IRREVERSIBLE!");
2710
2897
  logger.warn("");
@@ -2720,7 +2907,7 @@ async function confirmDeploy(schemaCount, environment, version) {
2720
2907
  logger.newline();
2721
2908
  rl.question(' Type "LOCK" to confirm: ', (answer) => {
2722
2909
  rl.close();
2723
- resolve14(answer.trim().toUpperCase() === "LOCK");
2910
+ resolve15(answer.trim().toUpperCase() === "LOCK");
2724
2911
  });
2725
2912
  });
2726
2913
  }
@@ -2743,9 +2930,9 @@ async function runDeploy(options) {
2743
2930
  const { config, configPath: configPath2 } = await loadConfig();
2744
2931
  const rootDir = configPath2 ? dirname8(configPath2) : process.cwd();
2745
2932
  validateConfig(config, rootDir);
2746
- const schemasDir = resolve11(rootDir, config.schemasDir);
2747
- const chainFilePath = resolve11(rootDir, VERSION_CHAIN_FILE2);
2748
- if (!existsSync11(schemasDir)) {
2933
+ const schemasDir = resolve12(rootDir, config.schemasDir);
2934
+ const chainFilePath = resolve12(rootDir, VERSION_CHAIN_FILE2);
2935
+ if (!existsSync12(schemasDir)) {
2749
2936
  throw new OmnifyError5(
2750
2937
  `Schemas directory not found: ${schemasDir}`,
2751
2938
  "E003",
@@ -2899,8 +3086,8 @@ function registerDeployCommand(program2) {
2899
3086
  }
2900
3087
 
2901
3088
  // src/commands/verify.ts
2902
- import { existsSync as existsSync12 } from "fs";
2903
- import { resolve as resolve12, dirname as dirname9 } from "path";
3089
+ import { existsSync as existsSync13 } from "fs";
3090
+ import { resolve as resolve13, dirname as dirname9 } from "path";
2904
3091
  import { OmnifyError as OmnifyError6 } from "@famgia/omnify-core";
2905
3092
  import {
2906
3093
  VERSION_CHAIN_FILE as VERSION_CHAIN_FILE3,
@@ -2918,9 +3105,9 @@ async function runVerify(options) {
2918
3105
  const { config, configPath: configPath2 } = await loadConfig();
2919
3106
  const rootDir = configPath2 ? dirname9(configPath2) : process.cwd();
2920
3107
  validateConfig(config, rootDir);
2921
- const schemasDir = resolve12(rootDir, config.schemasDir);
2922
- const chainFilePath = resolve12(rootDir, VERSION_CHAIN_FILE3);
2923
- if (!existsSync12(chainFilePath)) {
3108
+ const schemasDir = resolve13(rootDir, config.schemasDir);
3109
+ const chainFilePath = resolve13(rootDir, VERSION_CHAIN_FILE3);
3110
+ if (!existsSync13(chainFilePath)) {
2924
3111
  if (options.json) {
2925
3112
  console.log(JSON.stringify({
2926
3113
  valid: true,
@@ -3100,8 +3287,8 @@ process.on("unhandledRejection", (reason) => {
3100
3287
  var args = process.argv.slice(2);
3101
3288
  var firstArg = args[0];
3102
3289
  var hasCommand = firstArg !== void 0 && !firstArg.startsWith("-");
3103
- var configPath = resolve13(process.cwd(), "omnify.config.ts");
3104
- var hasConfig = existsSync13(configPath);
3290
+ var configPath = resolve14(process.cwd(), "omnify.config.ts");
3291
+ var hasConfig = existsSync14(configPath);
3105
3292
  if (!hasCommand && !hasConfig) {
3106
3293
  runInit({}).catch((error) => {
3107
3294
  if (error instanceof Error) {