@calimero-network/registry-cli 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import chalk6 from 'chalk';
4
4
  import ora6 from 'ora';
5
5
  import { table } from 'table';
6
6
  import axios from 'axios';
7
- import fs3, { existsSync, writeFileSync } from 'fs';
7
+ import fs9, { existsSync, writeFileSync } from 'fs';
8
8
  import path7 from 'path';
9
9
  import os from 'os';
10
10
  import crypto from 'crypto';
@@ -430,10 +430,10 @@ var LocalConfig = class {
430
430
  allowedTypes: ["wasm", "js", "html"]
431
431
  }
432
432
  };
433
- if (fs3.existsSync(this.configPath)) {
433
+ if (fs9.existsSync(this.configPath)) {
434
434
  try {
435
435
  const existingConfig = JSON.parse(
436
- fs3.readFileSync(this.configPath, "utf8")
436
+ fs9.readFileSync(this.configPath, "utf8")
437
437
  );
438
438
  return {
439
439
  server: {
@@ -457,10 +457,10 @@ var LocalConfig = class {
457
457
  }
458
458
  saveConfig() {
459
459
  const configDir = path7.dirname(this.configPath);
460
- if (!fs3.existsSync(configDir)) {
461
- fs3.mkdirSync(configDir, { recursive: true });
460
+ if (!fs9.existsSync(configDir)) {
461
+ fs9.mkdirSync(configDir, { recursive: true });
462
462
  }
463
- fs3.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));
463
+ fs9.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));
464
464
  }
465
465
  // Server configuration
466
466
  getPort() {
@@ -518,8 +518,8 @@ var LocalConfig = class {
518
518
  path7.join(this.getDataDir(), "logs")
519
519
  ];
520
520
  dirs.forEach((dir) => {
521
- if (!fs3.existsSync(dir)) {
522
- fs3.mkdirSync(dir, { recursive: true });
521
+ if (!fs9.existsSync(dir)) {
522
+ fs9.mkdirSync(dir, { recursive: true });
523
523
  }
524
524
  });
525
525
  }
@@ -574,21 +574,21 @@ var LocalDataStore = class {
574
574
  }
575
575
  loadData() {
576
576
  try {
577
- if (fs3.existsSync(this.appsFile)) {
578
- const appsData = JSON.parse(fs3.readFileSync(this.appsFile, "utf8"));
577
+ if (fs9.existsSync(this.appsFile)) {
578
+ const appsData = JSON.parse(fs9.readFileSync(this.appsFile, "utf8"));
579
579
  this.data.apps = new Map(Object.entries(appsData));
580
580
  }
581
- if (fs3.existsSync(this.bundleManifestsFile)) {
581
+ if (fs9.existsSync(this.bundleManifestsFile)) {
582
582
  const bundleManifestsData = JSON.parse(
583
- fs3.readFileSync(this.bundleManifestsFile, "utf8")
583
+ fs9.readFileSync(this.bundleManifestsFile, "utf8")
584
584
  );
585
585
  this.data.bundleManifests = new Map(
586
586
  Object.entries(bundleManifestsData)
587
587
  );
588
588
  }
589
- if (fs3.existsSync(this.artifactsFile)) {
589
+ if (fs9.existsSync(this.artifactsFile)) {
590
590
  const artifactsData = JSON.parse(
591
- fs3.readFileSync(this.artifactsFile, "utf8")
591
+ fs9.readFileSync(this.artifactsFile, "utf8")
592
592
  );
593
593
  this.data.artifacts = new Map(Object.entries(artifactsData));
594
594
  }
@@ -600,14 +600,14 @@ var LocalDataStore = class {
600
600
  try {
601
601
  this.config.ensureDirectories();
602
602
  const appsObj = Object.fromEntries(this.data.apps);
603
- fs3.writeFileSync(this.appsFile, JSON.stringify(appsObj, null, 2));
603
+ fs9.writeFileSync(this.appsFile, JSON.stringify(appsObj, null, 2));
604
604
  const bundleManifestsObj = Object.fromEntries(this.data.bundleManifests);
605
- fs3.writeFileSync(
605
+ fs9.writeFileSync(
606
606
  this.bundleManifestsFile,
607
607
  JSON.stringify(bundleManifestsObj, null, 2)
608
608
  );
609
609
  const artifactsObj = Object.fromEntries(this.data.artifacts);
610
- fs3.writeFileSync(
610
+ fs9.writeFileSync(
611
611
  this.artifactsFile,
612
612
  JSON.stringify(artifactsObj, null, 2)
613
613
  );
@@ -690,8 +690,8 @@ var LocalDataStore = class {
690
690
  `backup-${timestamp}.json`
691
691
  );
692
692
  const backupDir = path7.dirname(backupPath);
693
- if (!fs3.existsSync(backupDir)) {
694
- fs3.mkdirSync(backupDir, { recursive: true });
693
+ if (!fs9.existsSync(backupDir)) {
694
+ fs9.mkdirSync(backupDir, { recursive: true });
695
695
  }
696
696
  const backupData = {
697
697
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -699,14 +699,14 @@ var LocalDataStore = class {
699
699
  bundleManifests: Object.fromEntries(this.data.bundleManifests),
700
700
  artifacts: Object.fromEntries(this.data.artifacts)
701
701
  };
702
- fs3.writeFileSync(backupPath, JSON.stringify(backupData, null, 2));
702
+ fs9.writeFileSync(backupPath, JSON.stringify(backupData, null, 2));
703
703
  return backupPath;
704
704
  }
705
705
  async restore(backupPath) {
706
- if (!fs3.existsSync(backupPath)) {
706
+ if (!fs9.existsSync(backupPath)) {
707
707
  throw new Error(`Backup file not found: ${backupPath}`);
708
708
  }
709
- const backupData = JSON.parse(fs3.readFileSync(backupPath, "utf8"));
709
+ const backupData = JSON.parse(fs9.readFileSync(backupPath, "utf8"));
710
710
  this.data.apps = new Map(Object.entries(backupData.apps || {}));
711
711
  this.data.bundleManifests = new Map(
712
712
  Object.entries(backupData.bundleManifests || {})
@@ -774,21 +774,21 @@ var LocalArtifactServer = class {
774
774
  this.ensureArtifactsDir();
775
775
  }
776
776
  ensureArtifactsDir() {
777
- if (!fs3.existsSync(this.artifactsDir)) {
778
- fs3.mkdirSync(this.artifactsDir, { recursive: true });
777
+ if (!fs9.existsSync(this.artifactsDir)) {
778
+ fs9.mkdirSync(this.artifactsDir, { recursive: true });
779
779
  }
780
780
  }
781
781
  // Copy artifact to local storage
782
782
  async copyArtifactToLocal(sourcePath, appId, version, filename) {
783
- if (!fs3.existsSync(sourcePath)) {
783
+ if (!fs9.existsSync(sourcePath)) {
784
784
  throw new Error(`Source file not found: ${sourcePath}`);
785
785
  }
786
786
  const appVersionDir = path7.join(this.artifactsDir, appId, version);
787
- if (!fs3.existsSync(appVersionDir)) {
788
- fs3.mkdirSync(appVersionDir, { recursive: true });
787
+ if (!fs9.existsSync(appVersionDir)) {
788
+ fs9.mkdirSync(appVersionDir, { recursive: true });
789
789
  }
790
790
  const targetPath = path7.join(appVersionDir, filename);
791
- fs3.copyFileSync(sourcePath, targetPath);
791
+ fs9.copyFileSync(sourcePath, targetPath);
792
792
  const fileHash = await this.calculateFileHash(targetPath);
793
793
  this.dataStore.setArtifactPath(fileHash, targetPath);
794
794
  return targetPath;
@@ -796,26 +796,26 @@ var LocalArtifactServer = class {
796
796
  // Serve artifact by app ID, version, and filename
797
797
  async serveArtifact(appId, version, filename) {
798
798
  const artifactPath = path7.join(this.artifactsDir, appId, version, filename);
799
- if (!fs3.existsSync(artifactPath)) {
799
+ if (!fs9.existsSync(artifactPath)) {
800
800
  throw new Error(`Artifact not found: ${artifactPath}`);
801
801
  }
802
- return fs3.readFileSync(artifactPath);
802
+ return fs9.readFileSync(artifactPath);
803
803
  }
804
804
  // Serve artifact by hash
805
805
  async serveByHash(hash) {
806
806
  const artifactPath = this.dataStore.getArtifactPath(hash);
807
- if (!artifactPath || !fs3.existsSync(artifactPath)) {
807
+ if (!artifactPath || !fs9.existsSync(artifactPath)) {
808
808
  throw new Error(`Artifact not found for hash: ${hash}`);
809
809
  }
810
- return fs3.readFileSync(artifactPath);
810
+ return fs9.readFileSync(artifactPath);
811
811
  }
812
812
  // Validate artifact file
813
813
  async validateArtifact(filePath) {
814
- if (!fs3.existsSync(filePath)) {
814
+ if (!fs9.existsSync(filePath)) {
815
815
  throw new Error(`File not found: ${filePath}`);
816
816
  }
817
- const stats = fs3.statSync(filePath);
818
- const fileBuffer = fs3.readFileSync(filePath);
817
+ const stats = fs9.statSync(filePath);
818
+ const fileBuffer = fs9.readFileSync(filePath);
819
819
  const sha256 = crypto.createHash("sha256").update(fileBuffer).digest("hex");
820
820
  return {
821
821
  size: stats.size,
@@ -824,7 +824,7 @@ var LocalArtifactServer = class {
824
824
  }
825
825
  // Calculate file hash
826
826
  async calculateFileHash(filePath) {
827
- const fileBuffer = fs3.readFileSync(filePath);
827
+ const fileBuffer = fs9.readFileSync(filePath);
828
828
  return crypto.createHash("sha256").update(fileBuffer).digest("hex");
829
829
  }
830
830
  // Get artifact URL for local serving
@@ -864,10 +864,10 @@ var LocalArtifactServer = class {
864
864
  const now = Date.now();
865
865
  const getAllFiles = (dir) => {
866
866
  let files = [];
867
- const items = fs3.readdirSync(dir);
867
+ const items = fs9.readdirSync(dir);
868
868
  for (const item of items) {
869
869
  const fullPath = path7.join(dir, item);
870
- const stat = fs3.statSync(fullPath);
870
+ const stat = fs9.statSync(fullPath);
871
871
  if (stat.isDirectory()) {
872
872
  files = files.concat(getAllFiles(fullPath));
873
873
  } else {
@@ -878,10 +878,10 @@ var LocalArtifactServer = class {
878
878
  };
879
879
  const allFiles = getAllFiles(this.artifactsDir);
880
880
  for (const file of allFiles) {
881
- const stats = fs3.statSync(file);
881
+ const stats = fs9.statSync(file);
882
882
  const age = now - stats.mtime.getTime();
883
883
  if (age > maxAge) {
884
- fs3.unlinkSync(file);
884
+ fs9.unlinkSync(file);
885
885
  console.log(`Cleaned up old artifact: ${file}`);
886
886
  }
887
887
  }
@@ -893,10 +893,10 @@ var LocalArtifactServer = class {
893
893
  let oldestFile = null;
894
894
  const getAllFiles = (dir) => {
895
895
  let files = [];
896
- const items = fs3.readdirSync(dir);
896
+ const items = fs9.readdirSync(dir);
897
897
  for (const item of items) {
898
898
  const fullPath = path7.join(dir, item);
899
- const stat = fs3.statSync(fullPath);
899
+ const stat = fs9.statSync(fullPath);
900
900
  if (stat.isDirectory()) {
901
901
  files = files.concat(getAllFiles(fullPath));
902
902
  } else {
@@ -905,10 +905,10 @@ var LocalArtifactServer = class {
905
905
  }
906
906
  return files;
907
907
  };
908
- if (fs3.existsSync(this.artifactsDir)) {
908
+ if (fs9.existsSync(this.artifactsDir)) {
909
909
  const allFiles = getAllFiles(this.artifactsDir);
910
910
  for (const file of allFiles) {
911
- const stats = fs3.statSync(file);
911
+ const stats = fs9.statSync(file);
912
912
  totalFiles++;
913
913
  totalSize += stats.size;
914
914
  if (!oldestFile || stats.mtime < oldestFile) {
@@ -994,7 +994,7 @@ var LocalRegistryClient = class {
994
994
  const processedManifest = { ...manifest };
995
995
  if (manifest.artifact?.uri?.startsWith("file://")) {
996
996
  const filePath = manifest.artifact.uri.replace("file://", "");
997
- if (fs3.existsSync(filePath)) {
997
+ if (fs9.existsSync(filePath)) {
998
998
  const filename = path7.basename(filePath);
999
999
  try {
1000
1000
  await this.artifactServer.copyArtifactToLocal(
@@ -1138,12 +1138,12 @@ var appsCommand = new Command("apps").description("Manage SSApp applications").a
1138
1138
  const spinner2 = ora6("Reading manifest file...").start();
1139
1139
  try {
1140
1140
  const manifestPath = path7.resolve(manifestFile);
1141
- if (!fs3.existsSync(manifestPath)) {
1141
+ if (!fs9.existsSync(manifestPath)) {
1142
1142
  spinner2.fail("Manifest file not found");
1143
1143
  console.error(chalk6.red(`File not found: ${manifestFile}`));
1144
1144
  process.exit(1);
1145
1145
  }
1146
- const manifestContent = fs3.readFileSync(manifestPath, "utf8");
1146
+ const manifestContent = fs9.readFileSync(manifestPath, "utf8");
1147
1147
  const manifest = JSON.parse(manifestContent);
1148
1148
  spinner2.text = "Submitting application manifest...";
1149
1149
  const result = await client.submitAppManifest(manifest);
@@ -1423,8 +1423,8 @@ var LocalRegistryServer = class {
1423
1423
  async reset() {
1424
1424
  this.dataStore.reset();
1425
1425
  const artifactsDir = this.config.getArtifactsDir();
1426
- if (fs3.existsSync(artifactsDir)) {
1427
- fs3.rmSync(artifactsDir, { recursive: true, force: true });
1426
+ if (fs9.existsSync(artifactsDir)) {
1427
+ fs9.rmSync(artifactsDir, { recursive: true, force: true });
1428
1428
  }
1429
1429
  }
1430
1430
  async backup(outputPath) {
@@ -1727,7 +1727,7 @@ localCommand.addCommand(
1727
1727
  new Command("restore").description("Restore local registry data from backup").argument("<backup-file>", "Path to backup file").action(async (backupFile) => {
1728
1728
  const spinner2 = ora6("Restoring from backup...").start();
1729
1729
  try {
1730
- if (!fs3.existsSync(backupFile)) {
1730
+ if (!fs9.existsSync(backupFile)) {
1731
1731
  spinner2.fail("Backup file not found");
1732
1732
  console.error(chalk6.red(`File not found: ${backupFile}`));
1733
1733
  process.exit(1);
@@ -1786,10 +1786,10 @@ var RemoteConfig = class {
1786
1786
  url: "https://apps.calimero.network"
1787
1787
  }
1788
1788
  };
1789
- if (fs3.existsSync(this.configPath)) {
1789
+ if (fs9.existsSync(this.configPath)) {
1790
1790
  try {
1791
1791
  const existingConfig = JSON.parse(
1792
- fs3.readFileSync(this.configPath, "utf8")
1792
+ fs9.readFileSync(this.configPath, "utf8")
1793
1793
  );
1794
1794
  return {
1795
1795
  registry: {
@@ -1805,8 +1805,8 @@ var RemoteConfig = class {
1805
1805
  }
1806
1806
  saveConfig() {
1807
1807
  const configDir = path7.dirname(this.configPath);
1808
- if (!fs3.existsSync(configDir)) {
1809
- fs3.mkdirSync(configDir, { recursive: true });
1808
+ if (!fs9.existsSync(configDir)) {
1809
+ fs9.mkdirSync(configDir, { recursive: true });
1810
1810
  }
1811
1811
  const configToSave = {
1812
1812
  registry: {
@@ -1815,7 +1815,7 @@ var RemoteConfig = class {
1815
1815
  ...this.config.registry.apiKey ? { apiKey: this.config.registry.apiKey } : {}
1816
1816
  }
1817
1817
  };
1818
- fs3.writeFileSync(this.configPath, JSON.stringify(configToSave, null, 2));
1818
+ fs9.writeFileSync(this.configPath, JSON.stringify(configToSave, null, 2));
1819
1819
  }
1820
1820
  /**
1821
1821
  * Get registry URL with priority:
@@ -1905,7 +1905,7 @@ function createCreateCommand() {
1905
1905
  (value, prev) => {
1906
1906
  return [...prev || [], value];
1907
1907
  }
1908
- ).addHelpText(
1908
+ ).option("--abi <path>", "Path to ABI JSON file to include in bundle").addHelpText(
1909
1909
  "after",
1910
1910
  `
1911
1911
  Examples:
@@ -1913,6 +1913,8 @@ Examples:
1913
1913
  $ calimero-registry bundle create app.wasm --manifest bundle-manifest.json
1914
1914
  $ calimero-registry bundle create app.wasm --manifest bundle-manifest.json -o output.mpk
1915
1915
  $ calimero-registry bundle create app.wasm com.calimero.myapp 1.0.0 --name "My App" --frontend https://app.example.com
1916
+ $ calimero-registry bundle create app.wasm com.calimero.myapp 1.0.0 --abi abi.json
1917
+ $ calimero-registry bundle create app.wasm --manifest manifest.json --abi res/abi.json
1916
1918
 
1917
1919
  Manifest File Format (JSON):
1918
1920
  {
@@ -1926,7 +1928,8 @@ Manifest File Format (JSON):
1926
1928
  "github": "https://github.com/user/repo",
1927
1929
  "docs": "https://docs.example.com",
1928
1930
  "exports": ["interface1", "interface2"],
1929
- "uses": ["interface3"]
1931
+ "uses": ["interface3"],
1932
+ "abi": "res/abi.json"
1930
1933
  }
1931
1934
 
1932
1935
  Note:
@@ -1934,18 +1937,20 @@ Note:
1934
1937
  - CLI arguments take precedence over manifest file values
1935
1938
  - If using manifest file, package and version can be omitted from command line
1936
1939
  - The -o/--output option overrides manifest.output if both are provided
1940
+ - ABI can be provided via --abi flag or manifest.abi field (file path string)
1941
+ - ABI file will be included in the bundle and referenced in the manifest
1937
1942
  `
1938
1943
  ).action(async (wasmFile, pkg, version, options) => {
1939
1944
  try {
1940
1945
  let manifestConfig = {};
1941
1946
  if (options.manifest) {
1942
1947
  const manifestPath = path7.resolve(options.manifest);
1943
- if (!fs3.existsSync(manifestPath)) {
1948
+ if (!fs9.existsSync(manifestPath)) {
1944
1949
  console.error(`\u274C Manifest file not found: ${options.manifest}`);
1945
1950
  process.exit(1);
1946
1951
  }
1947
1952
  try {
1948
- const manifestContent = fs3.readFileSync(manifestPath, "utf8");
1953
+ const manifestContent = fs9.readFileSync(manifestPath, "utf8");
1949
1954
  const parsed = JSON.parse(manifestContent);
1950
1955
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
1951
1956
  console.error(`\u274C Invalid manifest file: ${options.manifest}`);
@@ -2013,14 +2018,59 @@ Note:
2013
2018
  process.exit(1);
2014
2019
  }
2015
2020
  const wasmPath = path7.resolve(wasmFile);
2016
- if (!fs3.existsSync(wasmPath)) {
2021
+ if (!fs9.existsSync(wasmPath)) {
2017
2022
  console.error(`\u274C WASM file not found: ${wasmFile}`);
2018
2023
  process.exit(1);
2019
2024
  }
2020
2025
  console.log(`\u{1F4E6} Creating MPK bundle from: ${path7.basename(wasmPath)}`);
2021
- const wasmContent = fs3.readFileSync(wasmPath);
2026
+ const wasmContent = fs9.readFileSync(wasmPath);
2022
2027
  const wasmSize = wasmContent.length;
2023
- const hash = crypto.createHash("sha256").update(wasmContent).digest("hex");
2028
+ const wasmHash = crypto.createHash("sha256").update(wasmContent).digest("hex");
2029
+ let abiArtifact = void 0;
2030
+ let abiContent = null;
2031
+ const abiPathFromOption = options.abi;
2032
+ const abiPathFromManifest = typeof manifestConfig.abi === "string" ? manifestConfig.abi : null;
2033
+ const abiFilePath = abiPathFromOption || abiPathFromManifest;
2034
+ if (abiFilePath) {
2035
+ const abiResolvedPath = abiPathFromOption ? path7.resolve(abiFilePath) : options.manifest && abiPathFromManifest ? path7.resolve(
2036
+ path7.dirname(path7.resolve(options.manifest)),
2037
+ abiFilePath
2038
+ ) : path7.resolve(abiFilePath);
2039
+ if (!fs9.existsSync(abiResolvedPath)) {
2040
+ console.error(`\u274C ABI file not found: ${abiFilePath}`);
2041
+ console.error(` Resolved path: ${abiResolvedPath}`);
2042
+ process.exit(1);
2043
+ }
2044
+ try {
2045
+ abiContent = fs9.readFileSync(abiResolvedPath);
2046
+ JSON.parse(abiContent.toString("utf8"));
2047
+ const abiHash = crypto.createHash("sha256").update(abiContent).digest("hex");
2048
+ abiArtifact = {
2049
+ path: "abi.json",
2050
+ hash: abiHash,
2051
+ size: abiContent.length
2052
+ };
2053
+ console.log(
2054
+ ` Including ABI file: ${path7.basename(abiResolvedPath)}`
2055
+ );
2056
+ } catch (error) {
2057
+ console.error(
2058
+ `\u274C Failed to read or parse ABI file: ${abiFilePath}`
2059
+ );
2060
+ console.error(
2061
+ error instanceof Error ? error.message : "Invalid JSON"
2062
+ );
2063
+ process.exit(1);
2064
+ }
2065
+ } else if (manifestConfig.abi && typeof manifestConfig.abi === "object") {
2066
+ console.error(
2067
+ "\u274C Manifest provides ABI as object, but --abi flag is required to include the ABI file in bundle"
2068
+ );
2069
+ console.error(
2070
+ " Provide the ABI file path with --abi flag, or change manifest.abi to a file path string"
2071
+ );
2072
+ process.exit(1);
2073
+ }
2024
2074
  const metadata = {
2025
2075
  name: finalName || finalPackage,
2026
2076
  description: finalDescription || "",
@@ -2042,10 +2092,10 @@ Note:
2042
2092
  interfaces: interfaces.exports.length > 0 || interfaces.uses.length > 0 ? interfaces : void 0,
2043
2093
  wasm: {
2044
2094
  path: "app.wasm",
2045
- hash,
2095
+ hash: wasmHash,
2046
2096
  size: wasmSize
2047
2097
  },
2048
- abi: null,
2098
+ abi: abiArtifact || void 0,
2049
2099
  migrations: [],
2050
2100
  links: Object.keys(links).length > 0 ? links : void 0,
2051
2101
  signature: void 0
@@ -2057,8 +2107,8 @@ Note:
2057
2107
  finalPackage,
2058
2108
  finalVersion
2059
2109
  );
2060
- if (!fs3.existsSync(outputDir)) {
2061
- fs3.mkdirSync(outputDir, { recursive: true });
2110
+ if (!fs9.existsSync(outputDir)) {
2111
+ fs9.mkdirSync(outputDir, { recursive: true });
2062
2112
  }
2063
2113
  outputPath = path7.join(
2064
2114
  outputDir,
@@ -2067,38 +2117,46 @@ Note:
2067
2117
  } else {
2068
2118
  outputPath = path7.resolve(outputPath);
2069
2119
  const outputDir = path7.dirname(outputPath);
2070
- if (!fs3.existsSync(outputDir)) {
2071
- fs3.mkdirSync(outputDir, { recursive: true });
2120
+ if (!fs9.existsSync(outputDir)) {
2121
+ fs9.mkdirSync(outputDir, { recursive: true });
2072
2122
  }
2073
2123
  }
2074
2124
  const tempDir = path7.join(
2075
2125
  path7.dirname(outputPath),
2076
2126
  `.temp-bundle-${Date.now()}`
2077
2127
  );
2078
- fs3.mkdirSync(tempDir, { recursive: true });
2128
+ fs9.mkdirSync(tempDir, { recursive: true });
2079
2129
  try {
2080
- fs3.writeFileSync(
2130
+ fs9.writeFileSync(
2081
2131
  path7.join(tempDir, "manifest.json"),
2082
2132
  JSON.stringify(manifest, null, 2)
2083
2133
  );
2084
- fs3.writeFileSync(path7.join(tempDir, "app.wasm"), wasmContent);
2134
+ fs9.writeFileSync(path7.join(tempDir, "app.wasm"), wasmContent);
2135
+ const archiveFiles = ["manifest.json", "app.wasm"];
2136
+ if (abiContent) {
2137
+ fs9.writeFileSync(path7.join(tempDir, "abi.json"), abiContent);
2138
+ archiveFiles.push("abi.json");
2139
+ }
2085
2140
  await tar.create(
2086
2141
  {
2087
2142
  gzip: true,
2088
2143
  file: outputPath,
2089
2144
  cwd: tempDir
2090
2145
  },
2091
- ["manifest.json", "app.wasm"]
2146
+ archiveFiles
2092
2147
  );
2093
- const outputSize = fs3.statSync(outputPath).size;
2148
+ const outputSize = fs9.statSync(outputPath).size;
2094
2149
  console.log(`\u2705 Created MPK bundle: ${outputPath}`);
2095
2150
  console.log(` Package: ${finalPackage}`);
2096
2151
  console.log(` Version: ${finalVersion}`);
2097
2152
  console.log(` Size: ${outputSize} bytes`);
2098
- console.log(` WASM Hash: ${hash}`);
2153
+ console.log(` WASM Hash: ${wasmHash}`);
2154
+ if (abiArtifact) {
2155
+ console.log(` ABI Hash: ${abiArtifact.hash}`);
2156
+ }
2099
2157
  } finally {
2100
- if (fs3.existsSync(tempDir)) {
2101
- fs3.rmSync(tempDir, { recursive: true, force: true });
2158
+ if (fs9.existsSync(tempDir)) {
2159
+ fs9.rmSync(tempDir, { recursive: true, force: true });
2102
2160
  }
2103
2161
  }
2104
2162
  } catch (error) {
@@ -2164,7 +2222,7 @@ Note:
2164
2222
  process.exit(1);
2165
2223
  }
2166
2224
  const fullPath = path7.resolve(bundleFile);
2167
- if (!fs3.existsSync(fullPath)) {
2225
+ if (!fs9.existsSync(fullPath)) {
2168
2226
  console.error(`\u274C File not found: ${bundleFile}`);
2169
2227
  process.exit(1);
2170
2228
  }
@@ -2243,7 +2301,7 @@ function createGetCommand() {
2243
2301
  async function pushToRemote(bundlePath, manifest, registryUrl, apiKey) {
2244
2302
  try {
2245
2303
  console.log(`\u{1F4E4} Pushing to remote registry: ${registryUrl}`);
2246
- const bundleBuffer = fs3.readFileSync(bundlePath);
2304
+ const bundleBuffer = fs9.readFileSync(bundlePath);
2247
2305
  const bundleSize = bundleBuffer.length;
2248
2306
  console.log(` Bundle size: ${bundleSize} bytes`);
2249
2307
  const bundleHex = bundleBuffer.toString("hex");
@@ -2417,8 +2475,8 @@ async function extractManifest(bundlePath) {
2417
2475
  }
2418
2476
  });
2419
2477
  const extractDir = path7.join(path7.dirname(bundlePath), `.temp-${Date.now()}`);
2420
- if (!fs3.existsSync(extractDir)) {
2421
- fs3.mkdirSync(extractDir);
2478
+ if (!fs9.existsSync(extractDir)) {
2479
+ fs9.mkdirSync(extractDir);
2422
2480
  }
2423
2481
  try {
2424
2482
  await tar.x({
@@ -2427,14 +2485,14 @@ async function extractManifest(bundlePath) {
2427
2485
  filter: (path8) => path8 === "manifest.json"
2428
2486
  });
2429
2487
  const manifestPath = path7.join(extractDir, "manifest.json");
2430
- if (fs3.existsSync(manifestPath)) {
2431
- const content = fs3.readFileSync(manifestPath, "utf8");
2488
+ if (fs9.existsSync(manifestPath)) {
2489
+ const content = fs9.readFileSync(manifestPath, "utf8");
2432
2490
  manifestContent = content;
2433
2491
  }
2434
2492
  } catch {
2435
2493
  } finally {
2436
- if (fs3.existsSync(extractDir)) {
2437
- fs3.rmSync(extractDir, { recursive: true, force: true });
2494
+ if (fs9.existsSync(extractDir)) {
2495
+ fs9.rmSync(extractDir, { recursive: true, force: true });
2438
2496
  }
2439
2497
  }
2440
2498
  if (manifestContent) {
@@ -2531,7 +2589,7 @@ function createConfigListCommand() {
2531
2589
  const config = new RemoteConfig();
2532
2590
  console.log(chalk6.blue("\n\u{1F4CB} Remote Registry Configuration\n"));
2533
2591
  const configPath = config.getConfigPath();
2534
- const configFileExists = fs3.existsSync(configPath);
2592
+ const configFileExists = fs9.existsSync(configPath);
2535
2593
  const url = config.getRegistryUrl();
2536
2594
  let urlSource;
2537
2595
  if (process.env.CALIMERO_REGISTRY_URL) {