realitydb 0.1.2 → 0.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.
Files changed (2) hide show
  1. package/dist/index.js +882 -62
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -4253,6 +4253,11 @@ function createSeededRandom(seed) {
4253
4253
  };
4254
4254
  }
4255
4255
 
4256
+ // ../../packages/shared/dist/output.js
4257
+ function formatCIOutput(result) {
4258
+ return JSON.stringify(result, null, 2);
4259
+ }
4260
+
4256
4261
  // ../../packages/generators/dist/foreignKeyResolver.js
4257
4262
  function resolveForeignKey(ctx, ref) {
4258
4263
  const referencedTable = ctx.allGeneratedTables.get(ref.referencedTable);
@@ -6145,6 +6150,13 @@ async function truncateTables(pool, tableNames, cascade) {
6145
6150
  };
6146
6151
  }
6147
6152
 
6153
+ // ../../packages/db/dist/readTable.js
6154
+ async function readTableRows(pool, tableName, columns) {
6155
+ const quotedColumns = columns.map((c) => `"${c}"`).join(", ");
6156
+ const result = await pool.query(`SELECT ${quotedColumns} FROM "${tableName}"`);
6157
+ return result.rows;
6158
+ }
6159
+
6148
6160
  // ../../packages/schema/dist/normalizer.js
6149
6161
  function normalizeSchema(raw) {
6150
6162
  const primaryKeyMap = /* @__PURE__ */ new Map();
@@ -6335,6 +6347,85 @@ async function introspectDatabase(pool, schemaName = "public") {
6335
6347
  return schema;
6336
6348
  }
6337
6349
 
6350
+ // ../../packages/schema/dist/generateDDL.js
6351
+ function generateCreateTableDDL(schema) {
6352
+ const orderedNames = orderByDependency(schema.tables, schema.foreignKeys);
6353
+ const tableMap = /* @__PURE__ */ new Map();
6354
+ for (const table of schema.tables) {
6355
+ tableMap.set(table.name, table);
6356
+ }
6357
+ const fksBySource = /* @__PURE__ */ new Map();
6358
+ for (const fk of schema.foreignKeys) {
6359
+ const existing = fksBySource.get(fk.sourceTable) ?? [];
6360
+ existing.push(fk);
6361
+ fksBySource.set(fk.sourceTable, existing);
6362
+ }
6363
+ const statements = [];
6364
+ for (const tableName of orderedNames) {
6365
+ const table = tableMap.get(tableName);
6366
+ if (!table)
6367
+ continue;
6368
+ const columnDefs = table.columns.sort((a, b) => a.ordinalPosition - b.ordinalPosition).map((col) => formatColumnDef(col));
6369
+ if (table.primaryKey) {
6370
+ columnDefs.push(` PRIMARY KEY ("${table.primaryKey.columnName}")`);
6371
+ }
6372
+ const tableFks = fksBySource.get(tableName) ?? [];
6373
+ for (const fk of tableFks) {
6374
+ columnDefs.push(` FOREIGN KEY ("${fk.sourceColumn}") REFERENCES "${fk.targetTable}" ("${fk.targetColumn}")`);
6375
+ }
6376
+ statements.push(`CREATE TABLE "${tableName}" (
6377
+ ${columnDefs.join(",\n")}
6378
+ );`);
6379
+ }
6380
+ return statements.join("\n\n") + "\n";
6381
+ }
6382
+ function formatColumnDef(col) {
6383
+ let typeName = col.dataType.toUpperCase();
6384
+ if (col.maxLength && (typeName === "CHARACTER VARYING" || typeName === "VARCHAR")) {
6385
+ typeName = `VARCHAR(${col.maxLength})`;
6386
+ }
6387
+ let def = ` "${col.name}" ${typeName}`;
6388
+ if (!col.isNullable) {
6389
+ def += " NOT NULL";
6390
+ }
6391
+ if (col.hasDefault && col.defaultValue !== null) {
6392
+ def += ` DEFAULT ${col.defaultValue}`;
6393
+ }
6394
+ return def;
6395
+ }
6396
+ function orderByDependency(tables, foreignKeys) {
6397
+ const tableNames = new Set(tables.map((t) => t.name));
6398
+ const deps = /* @__PURE__ */ new Map();
6399
+ for (const name of tableNames) {
6400
+ deps.set(name, /* @__PURE__ */ new Set());
6401
+ }
6402
+ for (const fk of foreignKeys) {
6403
+ if (fk.sourceTable !== fk.targetTable && tableNames.has(fk.targetTable)) {
6404
+ deps.get(fk.sourceTable).add(fk.targetTable);
6405
+ }
6406
+ }
6407
+ const result = [];
6408
+ const visited = /* @__PURE__ */ new Set();
6409
+ const visiting = /* @__PURE__ */ new Set();
6410
+ function visit(name) {
6411
+ if (visited.has(name))
6412
+ return;
6413
+ if (visiting.has(name))
6414
+ return;
6415
+ visiting.add(name);
6416
+ for (const dep of deps.get(name) ?? []) {
6417
+ visit(dep);
6418
+ }
6419
+ visiting.delete(name);
6420
+ visited.add(name);
6421
+ result.push(name);
6422
+ }
6423
+ for (const name of tableNames) {
6424
+ visit(name);
6425
+ }
6426
+ return result;
6427
+ }
6428
+
6338
6429
  // ../../packages/core/dist/scanPipeline.js
6339
6430
  async function scanDatabase(config) {
6340
6431
  const pool = createPostgresClient(config.database.connectionString);
@@ -6623,6 +6714,198 @@ function packDatasetToGenerated(pack) {
6623
6714
  };
6624
6715
  }
6625
6716
 
6717
+ // ../../packages/core/dist/capturePipeline.js
6718
+ function maskConnection(connectionString) {
6719
+ try {
6720
+ const url = new URL(connectionString);
6721
+ if (url.password) {
6722
+ url.password = "****";
6723
+ }
6724
+ return url.toString();
6725
+ } catch {
6726
+ return connectionString.replace(/:([^@/]+)@/, ":****@");
6727
+ }
6728
+ }
6729
+ async function captureDatabase(config, options) {
6730
+ const start = performance.now();
6731
+ const pool = createPostgresClient(config.database.connectionString);
6732
+ try {
6733
+ await testConnection(pool);
6734
+ const schema = await introspectDatabase(pool);
6735
+ const graph = buildDependencyGraph(schema.foreignKeys);
6736
+ const sorted = topologicalSort(graph);
6737
+ const graphOrder = sorted.order;
6738
+ const allTableNames = schema.tables.map((t) => t.name);
6739
+ const tableOrder = [
6740
+ ...graphOrder,
6741
+ ...allTableNames.filter((t) => !graphOrder.includes(t))
6742
+ ];
6743
+ let tablesToCapture;
6744
+ if (options.tables && options.tables.length > 0) {
6745
+ let addDeps2 = function(tableName) {
6746
+ if (allDeps.has(tableName))
6747
+ return;
6748
+ allDeps.add(tableName);
6749
+ for (const fk of schema.foreignKeys) {
6750
+ if (fk.sourceTable === tableName && fk.sourceTable !== fk.targetTable) {
6751
+ addDeps2(fk.targetTable);
6752
+ }
6753
+ }
6754
+ };
6755
+ var addDeps = addDeps2;
6756
+ const requested = new Set(options.tables);
6757
+ const allDeps = /* @__PURE__ */ new Set();
6758
+ for (const t of requested) {
6759
+ addDeps2(t);
6760
+ }
6761
+ tablesToCapture = tableOrder.filter((t) => allDeps.has(t));
6762
+ } else {
6763
+ tablesToCapture = tableOrder;
6764
+ }
6765
+ const capturedTableSet = new Set(tablesToCapture);
6766
+ const filteredTables = schema.tables.filter((t) => capturedTableSet.has(t.name));
6767
+ const filteredFKs = schema.foreignKeys.filter((fk) => capturedTableSet.has(fk.sourceTable) && capturedTableSet.has(fk.targetTable));
6768
+ const filteredSchema = {
6769
+ ...schema,
6770
+ tables: filteredTables,
6771
+ foreignKeys: filteredFKs,
6772
+ tableCount: filteredTables.length,
6773
+ foreignKeyCount: filteredFKs.length
6774
+ };
6775
+ const ddl = generateCreateTableDDL(filteredSchema);
6776
+ const packDataset = { tables: {} };
6777
+ const tableDetails = [];
6778
+ let totalRows = 0;
6779
+ for (const tableName of tablesToCapture) {
6780
+ const tableSchema = filteredTables.find((t) => t.name === tableName);
6781
+ if (!tableSchema)
6782
+ continue;
6783
+ const columns = tableSchema.columns.map((c) => c.name);
6784
+ const rows = await readTableRows(pool, tableName, columns);
6785
+ const rowCount = rows.length;
6786
+ packDataset.tables[tableName] = {
6787
+ columns,
6788
+ rows,
6789
+ rowCount
6790
+ };
6791
+ tableDetails.push({ name: tableName, rowCount });
6792
+ totalRows += rowCount;
6793
+ }
6794
+ const packSchema = {
6795
+ tables: filteredTables.map((t) => ({
6796
+ name: t.name,
6797
+ columns: t.columns.map((c) => ({
6798
+ name: c.name,
6799
+ dataType: c.dataType,
6800
+ nullable: c.isNullable,
6801
+ maxLength: c.maxLength
6802
+ })),
6803
+ primaryKey: t.primaryKey?.columnName
6804
+ })),
6805
+ foreignKeys: filteredFKs.map((fk) => ({
6806
+ sourceTable: fk.sourceTable,
6807
+ sourceColumn: fk.sourceColumn,
6808
+ targetTable: fk.targetTable,
6809
+ targetColumn: fk.targetColumn
6810
+ }))
6811
+ };
6812
+ const plan = {
6813
+ version: "1.0",
6814
+ planId: `capture-${options.name}-${Date.now()}`,
6815
+ tables: [],
6816
+ tableOrder: tablesToCapture,
6817
+ config: {
6818
+ targetDatabase: "postgres",
6819
+ defaultRowCount: 0,
6820
+ batchSize: config.seed?.batchSize ?? 1e3,
6821
+ environment: "dev"
6822
+ },
6823
+ reproducibility: {
6824
+ randomSeed: 0,
6825
+ strategyVersion: "0.3.0"
6826
+ }
6827
+ };
6828
+ const masked = maskConnection(config.database.connectionString);
6829
+ const pack = {
6830
+ format: "databox-reality-pack",
6831
+ version: "1.0",
6832
+ metadata: {
6833
+ name: options.name,
6834
+ description: options.description,
6835
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
6836
+ seed: 0,
6837
+ totalRows,
6838
+ tableCount: tablesToCapture.length,
6839
+ ddl,
6840
+ capturedFrom: masked
6841
+ },
6842
+ schema: packSchema,
6843
+ plan,
6844
+ dataset: packDataset
6845
+ };
6846
+ const outputDir = options.outputDir ?? ".";
6847
+ const filePath = await saveRealityPack(pack, outputDir);
6848
+ const durationMs = Math.round(performance.now() - start);
6849
+ return {
6850
+ pack,
6851
+ filePath,
6852
+ totalRows,
6853
+ tableCount: tablesToCapture.length,
6854
+ durationMs,
6855
+ tableDetails
6856
+ };
6857
+ } finally {
6858
+ await closeConnection(pool);
6859
+ }
6860
+ }
6861
+
6862
+ // ../../packages/core/dist/sharePipeline.js
6863
+ var import_promises6 = require("fs/promises");
6864
+ function formatSize(bytes) {
6865
+ if (bytes < 1024)
6866
+ return `${bytes} B`;
6867
+ const kb = Math.round(bytes / 1024);
6868
+ if (kb < 1024)
6869
+ return `${kb} KB`;
6870
+ const mb = (bytes / (1024 * 1024)).toFixed(1);
6871
+ return `${mb} MB`;
6872
+ }
6873
+ async function shareRealityPack(filePath, options) {
6874
+ const pack = await loadRealityPack(filePath);
6875
+ const fileStat = await (0, import_promises6.stat)(filePath);
6876
+ const size = formatSize(fileStat.size);
6877
+ const method = options?.method ?? "file";
6878
+ if (method === "gist") {
6879
+ const token = process.env.GITHUB_TOKEN;
6880
+ if (!token) {
6881
+ return {
6882
+ method: "file",
6883
+ location: filePath,
6884
+ packName: pack.metadata.name,
6885
+ size,
6886
+ tableCount: pack.metadata.tableCount,
6887
+ totalRows: pack.metadata.totalRows
6888
+ };
6889
+ }
6890
+ return {
6891
+ method: "file",
6892
+ location: filePath,
6893
+ packName: pack.metadata.name,
6894
+ size,
6895
+ tableCount: pack.metadata.tableCount,
6896
+ totalRows: pack.metadata.totalRows
6897
+ };
6898
+ }
6899
+ return {
6900
+ method: "file",
6901
+ location: filePath,
6902
+ packName: pack.metadata.name,
6903
+ size,
6904
+ tableCount: pack.metadata.tableCount,
6905
+ totalRows: pack.metadata.totalRows
6906
+ };
6907
+ }
6908
+
6626
6909
  // src/utils.ts
6627
6910
  function maskConnectionString(connectionString) {
6628
6911
  try {
@@ -6637,12 +6920,40 @@ function maskConnectionString(connectionString) {
6637
6920
  }
6638
6921
 
6639
6922
  // src/commands/scan.ts
6640
- async function scanCommand() {
6923
+ var VERSION2 = "0.3.0";
6924
+ async function scanCommand(options) {
6925
+ const start = performance.now();
6641
6926
  try {
6642
6927
  const config = await loadConfig();
6643
6928
  const result = await scanDatabase(config);
6644
6929
  const { schema } = result;
6645
6930
  const masked = maskConnectionString(config.database.connectionString);
6931
+ const durationMs = Math.round(performance.now() - start);
6932
+ if (options.ci) {
6933
+ console.log(formatCIOutput({
6934
+ success: true,
6935
+ command: "scan",
6936
+ version: VERSION2,
6937
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6938
+ durationMs,
6939
+ data: {
6940
+ database: masked,
6941
+ tableCount: schema.tableCount,
6942
+ foreignKeyCount: schema.foreignKeyCount,
6943
+ tables: schema.tables.map((t) => ({
6944
+ name: t.name,
6945
+ columnCount: t.columns.length,
6946
+ primaryKey: t.primaryKey?.columnName ?? null
6947
+ })),
6948
+ foreignKeys: schema.foreignKeys.map((fk) => ({
6949
+ source: `${fk.sourceTable}.${fk.sourceColumn}`,
6950
+ target: `${fk.targetTable}.${fk.targetColumn}`
6951
+ })),
6952
+ insertionOrder: result.insertionOrder
6953
+ }
6954
+ }));
6955
+ return;
6956
+ }
6646
6957
  console.log("");
6647
6958
  console.log("RealityDB Schema Scan");
6648
6959
  console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
@@ -6683,13 +6994,26 @@ async function scanCommand() {
6683
6994
  console.log("");
6684
6995
  } catch (err) {
6685
6996
  const message = err instanceof Error ? err.message : String(err);
6997
+ if (options.ci) {
6998
+ console.log(formatCIOutput({
6999
+ success: false,
7000
+ command: "scan",
7001
+ version: VERSION2,
7002
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7003
+ durationMs: Math.round(performance.now() - start),
7004
+ error: message
7005
+ }));
7006
+ process.exit(1);
7007
+ }
6686
7008
  console.error(`[realitydb] Scan failed: ${message}`);
6687
7009
  process.exit(1);
6688
7010
  }
6689
7011
  }
6690
7012
 
6691
7013
  // src/commands/seed.ts
7014
+ var VERSION3 = "0.3.0";
6692
7015
  async function seedCommand(options) {
7016
+ const start = performance.now();
6693
7017
  try {
6694
7018
  const config = await loadConfig();
6695
7019
  const records = options.records ? parseInt(options.records, 10) : void 0;
@@ -6703,6 +7027,17 @@ async function seedCommand(options) {
6703
7027
  const template = registry.get(templateName);
6704
7028
  if (!template) {
6705
7029
  const available = registry.list();
7030
+ if (options.ci) {
7031
+ console.log(formatCIOutput({
7032
+ success: false,
7033
+ command: "seed",
7034
+ version: VERSION3,
7035
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7036
+ durationMs: Math.round(performance.now() - start),
7037
+ error: `Template "${templateName}" not found. Available: ${available.map((t) => t.name).join(", ")}`
7038
+ }));
7039
+ process.exit(1);
7040
+ }
6706
7041
  console.error(`[realitydb] Template "${templateName}" not found.`);
6707
7042
  console.error("");
6708
7043
  if (available.length > 0) {
@@ -6721,6 +7056,17 @@ async function seedCommand(options) {
6721
7056
  const scenarioNames = scenario.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
6722
7057
  for (const name of scenarioNames) {
6723
7058
  if (!scenarioRegistry.get(name)) {
7059
+ if (options.ci) {
7060
+ console.log(formatCIOutput({
7061
+ success: false,
7062
+ command: "seed",
7063
+ version: VERSION3,
7064
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7065
+ durationMs: Math.round(performance.now() - start),
7066
+ error: `Scenario "${name}" not found`
7067
+ }));
7068
+ process.exit(1);
7069
+ }
6724
7070
  const available = scenarioRegistry.list();
6725
7071
  console.error(`[realitydb] Scenario "${name}" not found.`);
6726
7072
  console.error("");
@@ -6735,29 +7081,31 @@ async function seedCommand(options) {
6735
7081
  const effectiveSeed = seed ?? config.seed.randomSeed ?? 42;
6736
7082
  const effectiveRecords = records ?? config.seed.defaultRecords;
6737
7083
  const masked = maskConnectionString(config.database.connectionString);
6738
- console.log("");
6739
- console.log("RealityDB Seed");
6740
- console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
6741
- console.log(`Database: ${masked}`);
6742
- if (templateName) {
6743
- console.log(`Template: ${templateName}`);
6744
- }
6745
- if (timeline) {
6746
- console.log(`Timeline: ${timeline}`);
6747
- console.log(`Growth: s-curve`);
6748
- }
6749
- console.log(`Seed: ${effectiveSeed}`);
6750
- console.log(`Records per table: ${effectiveRecords}`);
6751
- if (scenario) {
6752
- const scenarioNames = scenario.split(",").map((s) => s.trim());
6753
- const scenarioDisplay = scenarioNames.map((s) => `${s} (${scenarioIntensity})`).join(", ");
6754
- console.log(`Scenarios: ${scenarioDisplay}`);
6755
- }
6756
- console.log("");
6757
- if (timeline) {
6758
- console.log("Generating with timeline...");
6759
- } else {
6760
- console.log("Seeding...");
7084
+ if (!options.ci) {
7085
+ console.log("");
7086
+ console.log("RealityDB Seed");
7087
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
7088
+ console.log(`Database: ${masked}`);
7089
+ if (templateName) {
7090
+ console.log(`Template: ${templateName}`);
7091
+ }
7092
+ if (timeline) {
7093
+ console.log(`Timeline: ${timeline}`);
7094
+ console.log(`Growth: s-curve`);
7095
+ }
7096
+ console.log(`Seed: ${effectiveSeed}`);
7097
+ console.log(`Records per table: ${effectiveRecords}`);
7098
+ if (scenario) {
7099
+ const scenarioNames = scenario.split(",").map((s) => s.trim());
7100
+ const scenarioDisplay = scenarioNames.map((s) => `${s} (${scenarioIntensity})`).join(", ");
7101
+ console.log(`Scenarios: ${scenarioDisplay}`);
7102
+ }
7103
+ console.log("");
7104
+ if (timeline) {
7105
+ console.log("Generating with timeline...");
7106
+ } else {
7107
+ console.log("Seeding...");
7108
+ }
6761
7109
  }
6762
7110
  const result = await seedDatabase(config, {
6763
7111
  records,
@@ -6767,6 +7115,32 @@ async function seedCommand(options) {
6767
7115
  scenarios: scenario,
6768
7116
  scenarioIntensity
6769
7117
  });
7118
+ const durationMs = Math.round(performance.now() - start);
7119
+ if (options.ci) {
7120
+ console.log(formatCIOutput({
7121
+ success: true,
7122
+ command: "seed",
7123
+ version: VERSION3,
7124
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7125
+ durationMs,
7126
+ data: {
7127
+ database: masked,
7128
+ template: templateName ?? null,
7129
+ seed: effectiveSeed,
7130
+ recordsPerTable: effectiveRecords,
7131
+ totalRows: result.totalRows,
7132
+ tables: result.insertResult.tables.map((t) => ({
7133
+ name: t.tableName,
7134
+ rowsInserted: t.rowsInserted,
7135
+ batchCount: t.batchCount,
7136
+ durationMs: t.durationMs
7137
+ })),
7138
+ timelineUsed: !!timeline,
7139
+ scenariosApplied: result.scenariosApplied ?? []
7140
+ }
7141
+ }));
7142
+ return;
7143
+ }
6770
7144
  if (result.scenariosApplied && result.scenariosApplied.length > 0) {
6771
7145
  console.log("");
6772
7146
  console.log("Applying scenarios...");
@@ -6787,6 +7161,17 @@ async function seedCommand(options) {
6787
7161
  console.log("");
6788
7162
  } catch (err) {
6789
7163
  const message = err instanceof Error ? err.message : String(err);
7164
+ if (options.ci) {
7165
+ console.log(formatCIOutput({
7166
+ success: false,
7167
+ command: "seed",
7168
+ version: VERSION3,
7169
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7170
+ durationMs: Math.round(performance.now() - start),
7171
+ error: message
7172
+ }));
7173
+ process.exit(1);
7174
+ }
6790
7175
  if (message.includes("Config file not found")) {
6791
7176
  console.error(`[realitydb] ${message}`);
6792
7177
  console.error("Hint: Copy realitydb.config.json to realitydb.config.json");
@@ -6804,8 +7189,10 @@ async function seedCommand(options) {
6804
7189
  }
6805
7190
 
6806
7191
  // src/commands/reset.ts
7192
+ var VERSION4 = "0.3.0";
6807
7193
  async function resetCommand(options) {
6808
- if (!options.confirm) {
7194
+ const start = performance.now();
7195
+ if (!options.ci && !options.confirm) {
6809
7196
  console.log("");
6810
7197
  console.log("This will delete ALL seeded data. Run with --confirm to proceed.");
6811
7198
  console.log("");
@@ -6814,13 +7201,31 @@ async function resetCommand(options) {
6814
7201
  try {
6815
7202
  const config = await loadConfig();
6816
7203
  const masked = maskConnectionString(config.database.connectionString);
6817
- console.log("");
6818
- console.log("RealityDB Reset");
6819
- console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
6820
- console.log(`Database: ${masked}`);
6821
- console.log("");
6822
- console.log("Clearing tables...");
7204
+ if (!options.ci) {
7205
+ console.log("");
7206
+ console.log("RealityDB Reset");
7207
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
7208
+ console.log(`Database: ${masked}`);
7209
+ console.log("");
7210
+ console.log("Clearing tables...");
7211
+ }
6823
7212
  const result = await resetDatabase(config);
7213
+ const durationMs = Math.round(performance.now() - start);
7214
+ if (options.ci) {
7215
+ console.log(formatCIOutput({
7216
+ success: true,
7217
+ command: "reset",
7218
+ version: VERSION4,
7219
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7220
+ durationMs,
7221
+ data: {
7222
+ database: masked,
7223
+ tablesCleared: result.tablesCleared,
7224
+ tableCount: result.tablesCleared.length
7225
+ }
7226
+ }));
7227
+ return;
7228
+ }
6824
7229
  for (const tableName of result.tablesCleared) {
6825
7230
  console.log(` ${tableName}: cleared`);
6826
7231
  }
@@ -6829,6 +7234,17 @@ async function resetCommand(options) {
6829
7234
  console.log("");
6830
7235
  } catch (err) {
6831
7236
  const message = err instanceof Error ? err.message : String(err);
7237
+ if (options.ci) {
7238
+ console.log(formatCIOutput({
7239
+ success: false,
7240
+ command: "reset",
7241
+ version: VERSION4,
7242
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7243
+ durationMs: Math.round(performance.now() - start),
7244
+ error: message
7245
+ }));
7246
+ process.exit(1);
7247
+ }
6832
7248
  if (message.includes("Config file not found")) {
6833
7249
  console.error(`[realitydb] ${message}`);
6834
7250
  console.error("Hint: Copy realitydb.config.json to realitydb.config.json");
@@ -6843,7 +7259,9 @@ async function resetCommand(options) {
6843
7259
  }
6844
7260
 
6845
7261
  // src/commands/export.ts
7262
+ var VERSION5 = "0.3.0";
6846
7263
  async function exportCommand(options) {
7264
+ const start = performance.now();
6847
7265
  try {
6848
7266
  const config = await loadConfig();
6849
7267
  const format = options.format ?? config.export?.defaultFormat ?? "json";
@@ -6861,6 +7279,17 @@ async function exportCommand(options) {
6861
7279
  const template = registry.get(templateName);
6862
7280
  if (!template) {
6863
7281
  const available = registry.list();
7282
+ if (options.ci) {
7283
+ console.log(formatCIOutput({
7284
+ success: false,
7285
+ command: "export",
7286
+ version: VERSION5,
7287
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7288
+ durationMs: Math.round(performance.now() - start),
7289
+ error: `Template "${templateName}" not found. Available: ${available.map((t) => t.name).join(", ")}`
7290
+ }));
7291
+ process.exit(1);
7292
+ }
6864
7293
  console.error(`[realitydb] Template "${templateName}" not found.`);
6865
7294
  console.error("");
6866
7295
  if (available.length > 0) {
@@ -6879,6 +7308,17 @@ async function exportCommand(options) {
6879
7308
  const scenarioNames = scenario.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
6880
7309
  for (const name of scenarioNames) {
6881
7310
  if (!scenarioRegistry.get(name)) {
7311
+ if (options.ci) {
7312
+ console.log(formatCIOutput({
7313
+ success: false,
7314
+ command: "export",
7315
+ version: VERSION5,
7316
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7317
+ durationMs: Math.round(performance.now() - start),
7318
+ error: `Scenario "${name}" not found`
7319
+ }));
7320
+ process.exit(1);
7321
+ }
6882
7322
  const available = scenarioRegistry.list();
6883
7323
  console.error(`[realitydb] Scenario "${name}" not found.`);
6884
7324
  console.error("");
@@ -6890,27 +7330,29 @@ async function exportCommand(options) {
6890
7330
  }
6891
7331
  }
6892
7332
  }
6893
- console.log("");
6894
- console.log("RealityDB Export");
6895
- console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
6896
- console.log(`Database: ${masked}`);
6897
- if (templateName) {
6898
- console.log(`Template: ${templateName}`);
6899
- }
6900
- if (timeline) {
6901
- console.log(`Timeline: ${timeline}`);
6902
- console.log(`Growth: s-curve`);
6903
- }
6904
- console.log(`Format: ${format}`);
6905
- console.log(`Output: ${outputDir}`);
6906
- console.log(`Records per table: ${effectiveRecords}`);
6907
- if (scenario) {
6908
- const scenarioNames = scenario.split(",").map((s) => s.trim());
6909
- const scenarioDisplay = scenarioNames.map((s) => `${s} (${scenarioIntensity})`).join(", ");
6910
- console.log(`Scenarios: ${scenarioDisplay}`);
7333
+ if (!options.ci) {
7334
+ console.log("");
7335
+ console.log("RealityDB Export");
7336
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
7337
+ console.log(`Database: ${masked}`);
7338
+ if (templateName) {
7339
+ console.log(`Template: ${templateName}`);
7340
+ }
7341
+ if (timeline) {
7342
+ console.log(`Timeline: ${timeline}`);
7343
+ console.log(`Growth: s-curve`);
7344
+ }
7345
+ console.log(`Format: ${format}`);
7346
+ console.log(`Output: ${outputDir}`);
7347
+ console.log(`Records per table: ${effectiveRecords}`);
7348
+ if (scenario) {
7349
+ const scenarioNames = scenario.split(",").map((s) => s.trim());
7350
+ const scenarioDisplay = scenarioNames.map((s) => `${s} (${scenarioIntensity})`).join(", ");
7351
+ console.log(`Scenarios: ${scenarioDisplay}`);
7352
+ }
7353
+ console.log("");
7354
+ console.log("Generating dataset...");
6911
7355
  }
6912
- console.log("");
6913
- console.log("Generating dataset...");
6914
7356
  const result = await exportDataset(config, {
6915
7357
  format,
6916
7358
  outputDir,
@@ -6921,6 +7363,24 @@ async function exportCommand(options) {
6921
7363
  scenarios: scenario,
6922
7364
  scenarioIntensity
6923
7365
  });
7366
+ const durationMs = Math.round(performance.now() - start);
7367
+ if (options.ci) {
7368
+ console.log(formatCIOutput({
7369
+ success: true,
7370
+ command: "export",
7371
+ version: VERSION5,
7372
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7373
+ durationMs,
7374
+ data: {
7375
+ format,
7376
+ outputDir,
7377
+ files: result.files,
7378
+ totalRows: result.totalRows,
7379
+ fileCount: result.files.length
7380
+ }
7381
+ }));
7382
+ return;
7383
+ }
6924
7384
  if (result.scenariosApplied && result.scenariosApplied.length > 0) {
6925
7385
  console.log("Applying scenarios...");
6926
7386
  for (const sr of result.scenariosApplied) {
@@ -6936,6 +7396,17 @@ async function exportCommand(options) {
6936
7396
  console.log("");
6937
7397
  } catch (err) {
6938
7398
  const message = err instanceof Error ? err.message : String(err);
7399
+ if (options.ci) {
7400
+ console.log(formatCIOutput({
7401
+ success: false,
7402
+ command: "export",
7403
+ version: VERSION5,
7404
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7405
+ durationMs: Math.round(performance.now() - start),
7406
+ error: message
7407
+ }));
7408
+ process.exit(1);
7409
+ }
6939
7410
  if (message.includes("Config file not found")) {
6940
7411
  console.error(`[realitydb] ${message}`);
6941
7412
  console.error("Hint: Copy realitydb.config.json to realitydb.config.json");
@@ -6981,7 +7452,7 @@ function scenariosCommand() {
6981
7452
  }
6982
7453
 
6983
7454
  // src/commands/pack.ts
6984
- var import_promises6 = require("fs/promises");
7455
+ var import_promises7 = require("fs/promises");
6985
7456
  async function packExportCommand(options) {
6986
7457
  try {
6987
7458
  const config = await loadConfig();
@@ -7058,7 +7529,7 @@ async function packExportCommand(options) {
7058
7529
  scenarios: options.scenario,
7059
7530
  scenarioIntensity
7060
7531
  });
7061
- const fileStat = await (0, import_promises6.stat)(result.filePath);
7532
+ const fileStat = await (0, import_promises7.stat)(result.filePath);
7062
7533
  const sizeKb = Math.round(fileStat.size / 1024);
7063
7534
  console.log("");
7064
7535
  console.log(`Tables: ${result.pack.metadata.tableCount}`);
@@ -7138,24 +7609,373 @@ async function packImportCommand(filePath, options) {
7138
7609
  }
7139
7610
  }
7140
7611
 
7612
+ // src/commands/capture.ts
7613
+ var import_promises8 = require("fs/promises");
7614
+ var VERSION6 = "0.3.0";
7615
+ async function captureCommand(options) {
7616
+ const start = performance.now();
7617
+ try {
7618
+ if (!options.name) {
7619
+ const msg = "Missing required --name flag.";
7620
+ if (options.ci) {
7621
+ console.log(formatCIOutput({
7622
+ success: false,
7623
+ command: "capture",
7624
+ version: VERSION6,
7625
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7626
+ durationMs: 0,
7627
+ error: msg
7628
+ }));
7629
+ process.exit(1);
7630
+ }
7631
+ console.error(`[realitydb] ${msg}`);
7632
+ console.error("Usage: realitydb capture --name <name>");
7633
+ process.exit(1);
7634
+ }
7635
+ const config = await loadConfig();
7636
+ const masked = maskConnectionString(config.database.connectionString);
7637
+ const tables = options.tables ? options.tables.split(",").map((t) => t.trim()).filter((t) => t.length > 0) : void 0;
7638
+ if (!options.ci) {
7639
+ console.log("");
7640
+ console.log("RealityDB Capture");
7641
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
7642
+ console.log(`Database: ${masked}`);
7643
+ console.log(`Name: ${options.name}`);
7644
+ if (tables) {
7645
+ console.log(`Tables: ${tables.join(", ")}`);
7646
+ }
7647
+ console.log("");
7648
+ console.log("Capturing...");
7649
+ }
7650
+ const result = await captureDatabase(config, {
7651
+ name: options.name,
7652
+ description: options.description,
7653
+ tables,
7654
+ outputDir: options.output
7655
+ });
7656
+ const durationMs = Math.round(performance.now() - start);
7657
+ if (options.ci) {
7658
+ console.log(formatCIOutput({
7659
+ success: true,
7660
+ command: "capture",
7661
+ version: VERSION6,
7662
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7663
+ durationMs,
7664
+ data: {
7665
+ database: masked,
7666
+ name: options.name,
7667
+ filePath: result.filePath,
7668
+ tableCount: result.tableCount,
7669
+ totalRows: result.totalRows,
7670
+ tables: result.tableDetails.map((t) => ({
7671
+ name: t.name,
7672
+ rowCount: t.rowCount
7673
+ })),
7674
+ ddlIncluded: true
7675
+ }
7676
+ }));
7677
+ return;
7678
+ }
7679
+ for (const table of result.tableDetails) {
7680
+ console.log(` ${table.name}: ${table.rowCount} rows`);
7681
+ }
7682
+ const fileStat = await (0, import_promises8.stat)(result.filePath);
7683
+ const sizeKb = Math.round(fileStat.size / 1024);
7684
+ console.log("");
7685
+ console.log(`Captured: ${result.filePath} (${sizeKb} KB)`);
7686
+ console.log("Schema DDL included. Share this file to reproduce the environment.");
7687
+ console.log("");
7688
+ } catch (err) {
7689
+ const message = err instanceof Error ? err.message : String(err);
7690
+ if (options.ci) {
7691
+ console.log(formatCIOutput({
7692
+ success: false,
7693
+ command: "capture",
7694
+ version: VERSION6,
7695
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7696
+ durationMs: Math.round(performance.now() - start),
7697
+ error: message
7698
+ }));
7699
+ process.exit(1);
7700
+ }
7701
+ if (message.includes("Config file not found")) {
7702
+ console.error(`[realitydb] ${message}`);
7703
+ } else if (message.includes("connection") || message.includes("ECONNREFUSED")) {
7704
+ console.error(`[realitydb] Capture failed: ${message}`);
7705
+ console.error("Hint: Check that your database is running (e.g. Docker)");
7706
+ } else {
7707
+ console.error(`[realitydb] Capture failed: ${message}`);
7708
+ }
7709
+ process.exit(1);
7710
+ }
7711
+ }
7712
+
7713
+ // src/commands/share.ts
7714
+ var VERSION7 = "0.3.0";
7715
+ async function shareCommand(filePath, options) {
7716
+ const start = performance.now();
7717
+ try {
7718
+ if (!filePath) {
7719
+ const msg = "Missing file path argument.";
7720
+ if (options.ci) {
7721
+ console.log(formatCIOutput({
7722
+ success: false,
7723
+ command: "share",
7724
+ version: VERSION7,
7725
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7726
+ durationMs: 0,
7727
+ error: msg
7728
+ }));
7729
+ process.exit(1);
7730
+ }
7731
+ console.error(`[realitydb] ${msg}`);
7732
+ console.error("Usage: realitydb share <file>");
7733
+ process.exit(1);
7734
+ }
7735
+ const result = await shareRealityPack(filePath);
7736
+ const durationMs = Math.round(performance.now() - start);
7737
+ if (options.ci) {
7738
+ console.log(formatCIOutput({
7739
+ success: true,
7740
+ command: "share",
7741
+ version: VERSION7,
7742
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7743
+ durationMs,
7744
+ data: {
7745
+ method: result.method,
7746
+ location: result.location,
7747
+ packName: result.packName,
7748
+ size: result.size,
7749
+ tableCount: result.tableCount,
7750
+ totalRows: result.totalRows
7751
+ }
7752
+ }));
7753
+ return;
7754
+ }
7755
+ console.log("");
7756
+ console.log("RealityDB Share");
7757
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
7758
+ console.log(`Pack: ${result.packName} (${result.tableCount} tables, ${result.totalRows} rows, ${result.size})`);
7759
+ console.log("");
7760
+ console.log("Share this file:");
7761
+ console.log(` File: ${result.location}`);
7762
+ console.log(` Size: ${result.size}`);
7763
+ console.log("");
7764
+ console.log("The receiver can load it with:");
7765
+ console.log(` realitydb load ${result.location} --confirm`);
7766
+ console.log("");
7767
+ console.log("Tip: To create the schema first, the receiver can run:");
7768
+ console.log(` realitydb load ${result.location} --show-ddl`);
7769
+ console.log("");
7770
+ } catch (err) {
7771
+ const message = err instanceof Error ? err.message : String(err);
7772
+ if (options.ci) {
7773
+ console.log(formatCIOutput({
7774
+ success: false,
7775
+ command: "share",
7776
+ version: VERSION7,
7777
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7778
+ durationMs: Math.round(performance.now() - start),
7779
+ error: message
7780
+ }));
7781
+ process.exit(1);
7782
+ }
7783
+ console.error(`[realitydb] Share failed: ${message}`);
7784
+ process.exit(1);
7785
+ }
7786
+ }
7787
+
7788
+ // src/commands/load.ts
7789
+ var VERSION8 = "0.3.0";
7790
+ async function loadCommand(filePath, options) {
7791
+ const start = performance.now();
7792
+ try {
7793
+ if (!filePath) {
7794
+ const msg = "Missing file path argument.";
7795
+ if (options.ci) {
7796
+ console.log(formatCIOutput({
7797
+ success: false,
7798
+ command: "load",
7799
+ version: VERSION8,
7800
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7801
+ durationMs: 0,
7802
+ error: msg
7803
+ }));
7804
+ process.exit(1);
7805
+ }
7806
+ console.error(`[realitydb] ${msg}`);
7807
+ console.error("Usage: realitydb load <file> --confirm");
7808
+ process.exit(1);
7809
+ }
7810
+ const pack = await loadRealityPack(filePath);
7811
+ if (options.showDdl) {
7812
+ const ddl = pack.metadata.ddl;
7813
+ if (options.ci) {
7814
+ console.log(formatCIOutput({
7815
+ success: true,
7816
+ command: "load",
7817
+ version: VERSION8,
7818
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7819
+ durationMs: Math.round(performance.now() - start),
7820
+ data: {
7821
+ packName: pack.metadata.name,
7822
+ ddlAvailable: !!ddl,
7823
+ ddl: ddl ?? null
7824
+ }
7825
+ }));
7826
+ return;
7827
+ }
7828
+ if (ddl) {
7829
+ console.log("");
7830
+ console.log("Schema DDL (run this SQL to create tables):");
7831
+ console.log("");
7832
+ console.log(ddl);
7833
+ } else {
7834
+ console.log("");
7835
+ console.log("No DDL available in this Reality Pack.");
7836
+ console.log("This pack was created with pack export (generated data), not capture.");
7837
+ console.log("");
7838
+ }
7839
+ return;
7840
+ }
7841
+ const config = await loadConfig();
7842
+ const masked = maskConnectionString(config.database.connectionString);
7843
+ if (!options.ci) {
7844
+ console.log("");
7845
+ console.log("RealityDB Load");
7846
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
7847
+ console.log(`Database: ${masked}`);
7848
+ console.log(`Pack: ${pack.metadata.name} (v${pack.version})`);
7849
+ if (pack.metadata.templateName) {
7850
+ console.log(`Template: ${pack.metadata.templateName}`);
7851
+ }
7852
+ console.log(`Tables: ${pack.metadata.tableCount}`);
7853
+ console.log(`Total rows: ${pack.metadata.totalRows}`);
7854
+ const ddl = pack.metadata.ddl;
7855
+ if (ddl) {
7856
+ console.log("Schema DDL: included");
7857
+ }
7858
+ console.log("");
7859
+ }
7860
+ if (!options.ci && !options.confirm) {
7861
+ console.error("[realitydb] Load requires --confirm flag.");
7862
+ console.error("Hint: This will insert data into your database. Use --confirm to proceed.");
7863
+ console.error("");
7864
+ console.error("To view the schema DDL first:");
7865
+ console.error(` realitydb load ${filePath} --show-ddl`);
7866
+ process.exit(1);
7867
+ }
7868
+ if (!options.ci) {
7869
+ console.log("Loading...");
7870
+ }
7871
+ const result = await importPack(config, filePath);
7872
+ const durationMs = Math.round(performance.now() - start);
7873
+ if (options.ci) {
7874
+ console.log(formatCIOutput({
7875
+ success: true,
7876
+ command: "load",
7877
+ version: VERSION8,
7878
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7879
+ durationMs,
7880
+ data: {
7881
+ database: masked,
7882
+ packName: pack.metadata.name,
7883
+ totalRows: result.totalRows,
7884
+ tables: result.insertResult.tables.map((t) => ({
7885
+ name: t.tableName,
7886
+ rowsInserted: t.rowsInserted,
7887
+ durationMs: t.durationMs
7888
+ }))
7889
+ }
7890
+ }));
7891
+ return;
7892
+ }
7893
+ for (const tableResult of result.insertResult.tables) {
7894
+ console.log(
7895
+ ` ${tableResult.tableName}: ${tableResult.rowsInserted} rows loaded`
7896
+ );
7897
+ }
7898
+ const totalTime = (result.durationMs / 1e3).toFixed(1);
7899
+ console.log("");
7900
+ console.log(`Load complete. ${result.totalRows} rows in ${totalTime}s`);
7901
+ console.log("");
7902
+ } catch (err) {
7903
+ const message = err instanceof Error ? err.message : String(err);
7904
+ if (options.ci) {
7905
+ console.log(formatCIOutput({
7906
+ success: false,
7907
+ command: "load",
7908
+ version: VERSION8,
7909
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7910
+ durationMs: Math.round(performance.now() - start),
7911
+ error: message
7912
+ }));
7913
+ process.exit(1);
7914
+ }
7915
+ if (message.includes("Config file not found")) {
7916
+ console.error(`[realitydb] ${message}`);
7917
+ } else if (message.includes("Cannot import Reality Pack")) {
7918
+ console.error(`[realitydb] ${message}`);
7919
+ const ddlHint = "Tip: Use --show-ddl to get the schema creation SQL.";
7920
+ console.error(ddlHint);
7921
+ } else if (message.includes("connection") || message.includes("ECONNREFUSED")) {
7922
+ console.error(`[realitydb] Load failed: ${message}`);
7923
+ console.error("Hint: Check that your database is running (e.g. Docker)");
7924
+ } else {
7925
+ console.error(`[realitydb] Load failed: ${message}`);
7926
+ }
7927
+ process.exit(1);
7928
+ }
7929
+ }
7930
+
7141
7931
  // src/cli.ts
7932
+ var VERSION9 = "0.3.0";
7142
7933
  function run(argv) {
7143
7934
  const program2 = new Command();
7144
- program2.name("realitydb").description("RealityDB \u2014 Developer Reality Platform").version("0.1.2").option("--config <path>", "Path to config file").option("--verbose", "Enable verbose output", false);
7145
- program2.command("scan").description("Scan database schema").action(scanCommand);
7146
- program2.command("seed").description("Seed database with generated data").option("--records <count>", "Number of records per table").option("--template <name>", "Template to use").option("--seed <number>", "Random seed for reproducibility").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").action(seedCommand);
7147
- program2.command("reset").description("Reset seeded data").option("--confirm", "Confirm destructive operation").action(resetCommand);
7148
- program2.command("export").description("Export generated data").option("--format <format>", "Output format (json|csv|sql)", "json").option("--output <dir>", "Output directory", "./.realitydb").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").action(exportCommand);
7935
+ program2.name("realitydb").description("RealityDB \u2014 Developer Reality Platform").version(VERSION9).option("--config <path>", "Path to config file").option("--ci", "CI mode: JSON output, no prompts, proper exit codes", false).option("--verbose", "Enable verbose output", false);
7936
+ program2.command("scan").description("Scan database schema").action(async () => {
7937
+ const opts = program2.opts();
7938
+ await scanCommand({ ci: opts.ci });
7939
+ });
7940
+ program2.command("seed").description("Seed database with generated data").option("--records <count>", "Number of records per table").option("--template <name>", "Template to use").option("--seed <number>", "Random seed for reproducibility").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").action(async (cmdOpts) => {
7941
+ const opts = program2.opts();
7942
+ await seedCommand({ ...cmdOpts, ci: opts.ci });
7943
+ });
7944
+ program2.command("reset").description("Reset seeded data").option("--confirm", "Confirm destructive operation").action(async (cmdOpts) => {
7945
+ const opts = program2.opts();
7946
+ await resetCommand({ ...cmdOpts, ci: opts.ci });
7947
+ });
7948
+ program2.command("export").description("Export generated data").option("--format <format>", "Output format (json|csv|sql)", "json").option("--output <dir>", "Output directory", "./.realitydb").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").action(async (cmdOpts) => {
7949
+ const opts = program2.opts();
7950
+ await exportCommand({ ...cmdOpts, ci: opts.ci });
7951
+ });
7149
7952
  program2.command("templates").description("List available domain templates").action(templatesCommand);
7150
7953
  program2.command("scenarios").description("List available scenarios").action(scenariosCommand);
7954
+ program2.command("capture").description("Capture live database state into a Reality Pack").requiredOption("--name <name>", "Name for the captured pack").option("--description <desc>", "Pack description").option("--tables <tables>", "Comma-separated list of tables to capture").option("--output <dir>", "Output directory", ".").action(async (cmdOpts) => {
7955
+ const opts = program2.opts();
7956
+ await captureCommand({ ...cmdOpts, ci: opts.ci });
7957
+ });
7958
+ program2.command("share <file>").description("Share a Reality Pack file").action(async (filePath) => {
7959
+ const opts = program2.opts();
7960
+ await shareCommand(filePath, { ci: opts.ci });
7961
+ });
7962
+ program2.command("load <file>").description("Load a Reality Pack into the database").option("--confirm", "Confirm import operation").option("--show-ddl", "Show schema DDL without importing").action(async (filePath, cmdOpts) => {
7963
+ const opts = program2.opts();
7964
+ await loadCommand(filePath, { ...cmdOpts, ci: opts.ci });
7965
+ });
7151
7966
  const pack = program2.command("pack").description("Reality Pack operations");
7152
7967
  pack.command("export").description("Export environment as Reality Pack").option("--name <name>", "Pack name").option("--description <desc>", "Pack description").option("--output <dir>", "Output directory", ".").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").action(packExportCommand);
7153
7968
  pack.command("import <file>").description("Import Reality Pack into database").option("--confirm", "Confirm import operation").action(packImportCommand);
7154
7969
  program2.action(() => {
7155
- console.log("");
7156
- console.log("RealityDB v0.1.2 \u2014 Developer Reality Platform");
7157
- console.log("Run `realitydb --help` for available commands.");
7158
- console.log("");
7970
+ const opts = program2.opts();
7971
+ if (opts.ci) {
7972
+ console.log(JSON.stringify({ name: "realitydb", version: VERSION9 }));
7973
+ } else {
7974
+ console.log("");
7975
+ console.log(`RealityDB v${VERSION9} \u2014 Developer Reality Platform`);
7976
+ console.log("Run `realitydb --help` for available commands.");
7977
+ console.log("");
7978
+ }
7159
7979
  });
7160
7980
  program2.parse(argv);
7161
7981
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "realitydb",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Developer Reality Platform - realistic database environments from your schema",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -48,6 +48,7 @@
48
48
  "@databox/config": "workspace:^",
49
49
  "@databox/core": "workspace:^",
50
50
  "@databox/schema": "workspace:^",
51
+ "@databox/shared": "workspace:^",
51
52
  "@databox/templates": "workspace:^",
52
53
  "commander": "^14.0.3",
53
54
  "tsup": "^8.5.1",