@insforge/cli 0.1.50 → 0.1.51

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { readFileSync as readFileSync7 } from "fs";
5
- import { join as join9, dirname } from "path";
5
+ import { join as join10, dirname } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { Command } from "commander";
8
8
  import * as clack11 from "@clack/prompts";
@@ -1123,7 +1123,7 @@ async function reportCliUsage(toolName, success, maxRetries = 1, explicitConfig)
1123
1123
 
1124
1124
  // src/lib/analytics.ts
1125
1125
  import { PostHog } from "posthog-node";
1126
- var POSTHOG_API_KEY = "phc_ueV1ii62wdBTkH7E70ugyeqHIHu8dFDdjs0qq3TZhJz";
1126
+ var POSTHOG_API_KEY = "";
1127
1127
  var POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.i.posthog.com";
1128
1128
  var client = null;
1129
1129
  function getClient() {
@@ -1247,10 +1247,13 @@ async function readEnvFile(cwd) {
1247
1247
  // src/commands/deployments/deploy.ts
1248
1248
  import * as path2 from "path";
1249
1249
  import * as fs2 from "fs/promises";
1250
+ import { createReadStream } from "fs";
1251
+ import { createHash as createHash2 } from "crypto";
1250
1252
  import * as clack6 from "@clack/prompts";
1251
1253
  import archiver from "archiver";
1252
1254
  var POLL_INTERVAL_MS = 5e3;
1253
1255
  var POLL_TIMEOUT_MS = 3e5;
1256
+ var DIRECT_UPLOAD_CONCURRENCY = 8;
1254
1257
  var EXCLUDE_PATTERNS = [
1255
1258
  "node_modules",
1256
1259
  ".git",
@@ -1278,6 +1281,12 @@ var EXCLUDE_PATTERNS = [
1278
1281
  "skills",
1279
1282
  "coverage"
1280
1283
  ];
1284
+ var DirectDeploymentUnsupportedError = class extends Error {
1285
+ constructor() {
1286
+ super("Direct deployment endpoints are not available on this backend");
1287
+ this.name = "DirectDeploymentUnsupportedError";
1288
+ }
1289
+ };
1281
1290
  function shouldExclude(name) {
1282
1291
  const normalized = name.replace(/\\/g, "/");
1283
1292
  for (const pattern of EXCLUDE_PATTERNS) {
@@ -1288,6 +1297,56 @@ function shouldExclude(name) {
1288
1297
  if (normalized.endsWith(".log")) return true;
1289
1298
  return false;
1290
1299
  }
1300
+ function isInsforgeCloudOssHost(ossHost) {
1301
+ try {
1302
+ return new URL(ossHost).hostname.endsWith(".insforge.app");
1303
+ } catch {
1304
+ return false;
1305
+ }
1306
+ }
1307
+ function normalizeRelativePath(sourceDir, absolutePath) {
1308
+ return path2.relative(sourceDir, absolutePath).split(path2.sep).join("/").replace(/\\/g, "/");
1309
+ }
1310
+ async function hashFile(filePath) {
1311
+ const hash = createHash2("sha1");
1312
+ let size = 0;
1313
+ for await (const chunk of createReadStream(filePath)) {
1314
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
1315
+ size += buffer.length;
1316
+ hash.update(buffer);
1317
+ }
1318
+ return { sha: hash.digest("hex"), size };
1319
+ }
1320
+ async function collectDeploymentFiles(sourceDir) {
1321
+ const files = [];
1322
+ async function walk(currentDir) {
1323
+ const entries = await fs2.readdir(currentDir, { withFileTypes: true });
1324
+ entries.sort((a, b) => a.name.localeCompare(b.name));
1325
+ for (const entry of entries) {
1326
+ const absolutePath = path2.join(currentDir, entry.name);
1327
+ const normalizedPath = normalizeRelativePath(sourceDir, absolutePath);
1328
+ if (!normalizedPath || shouldExclude(normalizedPath)) {
1329
+ continue;
1330
+ }
1331
+ if (entry.isDirectory()) {
1332
+ await walk(absolutePath);
1333
+ continue;
1334
+ }
1335
+ if (!entry.isFile()) {
1336
+ continue;
1337
+ }
1338
+ const { sha, size } = await hashFile(absolutePath);
1339
+ files.push({
1340
+ absolutePath,
1341
+ path: normalizedPath,
1342
+ sha,
1343
+ size
1344
+ });
1345
+ }
1346
+ }
1347
+ await walk(sourceDir);
1348
+ return files;
1349
+ }
1291
1350
  async function createZipBuffer(sourceDir) {
1292
1351
  return new Promise((resolve4, reject) => {
1293
1352
  const archive = archiver("zip", { zlib: { level: 9 } });
@@ -1302,40 +1361,84 @@ async function createZipBuffer(sourceDir) {
1302
1361
  void archive.finalize();
1303
1362
  });
1304
1363
  }
1305
- async function deployProject(opts) {
1306
- const { sourceDir, startBody = {}, spinner: s } = opts;
1307
- s?.start("Creating deployment...");
1308
- const createRes = await ossFetch("/api/deployments", { method: "POST" });
1309
- const { id: deploymentId, uploadUrl, uploadFields } = await createRes.json();
1310
- s?.message("Compressing source files...");
1311
- const zipBuffer = await createZipBuffer(sourceDir);
1312
- s?.message("Uploading...");
1313
- const formData = new FormData();
1314
- for (const [key, value] of Object.entries(uploadFields)) {
1315
- formData.append(key, value);
1364
+ async function runWithConcurrency(items, concurrency, worker) {
1365
+ let nextIndex = 0;
1366
+ async function runWorker() {
1367
+ while (nextIndex < items.length) {
1368
+ const index = nextIndex;
1369
+ nextIndex += 1;
1370
+ await worker(items[index], index);
1371
+ }
1316
1372
  }
1317
- formData.append(
1318
- "file",
1319
- new Blob([zipBuffer], { type: "application/zip" }),
1320
- "deployment.zip"
1321
- );
1322
- const uploadRes = await fetch(uploadUrl, { method: "POST", body: formData });
1323
- if (!uploadRes.ok) {
1324
- const uploadErr = await uploadRes.text();
1325
- throw new CLIError(`Failed to upload: ${uploadErr}`);
1373
+ const workerCount = Math.min(concurrency, items.length);
1374
+ await Promise.all(Array.from({ length: workerCount }, () => runWorker()));
1375
+ }
1376
+ async function createDirectDeploymentSession(config, files) {
1377
+ const url = `${config.oss_host}/api/deployments/direct`;
1378
+ let response;
1379
+ try {
1380
+ response = await fetch(url, {
1381
+ method: "POST",
1382
+ headers: {
1383
+ "Content-Type": "application/json",
1384
+ Authorization: `Bearer ${config.api_key}`
1385
+ },
1386
+ body: JSON.stringify({ files })
1387
+ });
1388
+ } catch (error) {
1389
+ throw new CLIError(formatFetchError(error, url));
1326
1390
  }
1327
- s?.message("Starting deployment...");
1328
- const startRes = await ossFetch(`/api/deployments/${deploymentId}/start`, {
1391
+ if (response.status === 404) {
1392
+ throw new DirectDeploymentUnsupportedError();
1393
+ }
1394
+ if (!response.ok) {
1395
+ const err = await response.json().catch(() => ({}));
1396
+ let message = err.message ?? err.error ?? `OSS request failed: ${response.status}`;
1397
+ if (err.nextActions) {
1398
+ message += `
1399
+ ${err.nextActions}`;
1400
+ }
1401
+ throw new CLIError(message);
1402
+ }
1403
+ const payload = await response.json();
1404
+ if (!payload.id || !Array.isArray(payload.files)) {
1405
+ throw new CLIError("Unexpected response from direct deployment create endpoint.");
1406
+ }
1407
+ return payload;
1408
+ }
1409
+ async function uploadDirectDeploymentFile(deploymentId, manifestFile, localFile) {
1410
+ const requestInit = {
1411
+ method: "PUT",
1412
+ headers: {
1413
+ "Content-Type": "application/octet-stream",
1414
+ "Content-Length": String(localFile.size)
1415
+ },
1416
+ body: createReadStream(localFile.absolutePath),
1417
+ duplex: "half"
1418
+ };
1419
+ await ossFetch(
1420
+ `/api/deployments/${encodeURIComponent(deploymentId)}/files/${encodeURIComponent(manifestFile.fileId)}/content`,
1421
+ requestInit
1422
+ );
1423
+ }
1424
+ async function startDirectDeployment(deploymentId, startBody) {
1425
+ const response = await ossFetch(`/api/deployments/${encodeURIComponent(deploymentId)}/start`, {
1329
1426
  method: "POST",
1427
+ headers: { "Content-Type": "application/json" },
1330
1428
  body: JSON.stringify(startBody)
1331
1429
  });
1332
- await startRes.json();
1333
- s?.message("Building and deploying...");
1430
+ await response.json();
1431
+ }
1432
+ async function pollDeployment(deploymentId, spinner7, syncBeforeRead) {
1433
+ spinner7?.message("Building and deploying...");
1334
1434
  const startTime = Date.now();
1335
1435
  let deployment = null;
1336
1436
  while (Date.now() - startTime < POLL_TIMEOUT_MS) {
1337
- await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
1437
+ await new Promise((resolve4) => setTimeout(resolve4, POLL_INTERVAL_MS));
1338
1438
  try {
1439
+ if (syncBeforeRead) {
1440
+ await ossFetch(`/api/deployments/${deploymentId}/sync`, { method: "POST" });
1441
+ }
1339
1442
  const statusRes = await ossFetch(`/api/deployments/${deploymentId}`);
1340
1443
  deployment = await statusRes.json();
1341
1444
  const status = deployment.status.toUpperCase();
@@ -1343,11 +1446,13 @@ async function deployProject(opts) {
1343
1446
  break;
1344
1447
  }
1345
1448
  if (status === "ERROR" || status === "CANCELED") {
1346
- s?.stop("Deployment failed");
1347
- throw new CLIError(getDeploymentError(deployment.metadata) ?? `Deployment failed with status: ${deployment.status}`);
1449
+ spinner7?.stop("Deployment failed");
1450
+ throw new CLIError(
1451
+ getDeploymentError(deployment.metadata) ?? `Deployment failed with status: ${deployment.status}`
1452
+ );
1348
1453
  }
1349
1454
  const elapsed = Math.round((Date.now() - startTime) / 1e3);
1350
- s?.message(`Building and deploying... (${elapsed}s, status: ${deployment.status})`);
1455
+ spinner7?.message(`Building and deploying... (${elapsed}s, status: ${deployment.status})`);
1351
1456
  } catch (err) {
1352
1457
  if (err instanceof CLIError) throw err;
1353
1458
  }
@@ -1356,8 +1461,78 @@ async function deployProject(opts) {
1356
1461
  const liveUrl = isReady ? deployment?.url ?? null : null;
1357
1462
  return { deploymentId, deployment, isReady, liveUrl };
1358
1463
  }
1464
+ async function deployProjectDirect(opts, config) {
1465
+ const { sourceDir, startBody = {}, spinner: spinner7 } = opts;
1466
+ spinner7?.start("Scanning source files...");
1467
+ const localFiles = await collectDeploymentFiles(sourceDir);
1468
+ if (localFiles.length === 0) {
1469
+ throw new CLIError("No deployable files found in the source directory.");
1470
+ }
1471
+ spinner7?.message("Creating deployment...");
1472
+ const createResult = await createDirectDeploymentSession(
1473
+ config,
1474
+ localFiles.map(({ path: relativePath, sha, size }) => ({ path: relativePath, sha, size }))
1475
+ );
1476
+ const localFileByPath = new Map(localFiles.map((file) => [file.path, file]));
1477
+ const pendingFiles = createResult.files.filter((file) => !file.uploadedAt);
1478
+ spinner7?.message(`Uploading ${pendingFiles.length} file${pendingFiles.length === 1 ? "" : "s"}...`);
1479
+ await runWithConcurrency(pendingFiles, DIRECT_UPLOAD_CONCURRENCY, async (manifestFile) => {
1480
+ const localFile = localFileByPath.get(manifestFile.path);
1481
+ if (!localFile) {
1482
+ throw new CLIError(`Backend returned an unknown file path: ${manifestFile.path}`);
1483
+ }
1484
+ if (localFile.sha !== manifestFile.sha || localFile.size !== manifestFile.size) {
1485
+ throw new CLIError(`Backend file metadata mismatch for: ${manifestFile.path}`);
1486
+ }
1487
+ await uploadDirectDeploymentFile(createResult.id, manifestFile, localFile);
1488
+ });
1489
+ spinner7?.message("Starting deployment...");
1490
+ await startDirectDeployment(createResult.id, startBody);
1491
+ return await pollDeployment(createResult.id, spinner7, !isInsforgeCloudOssHost(config.oss_host));
1492
+ }
1493
+ async function deployProjectLegacy(opts) {
1494
+ const { sourceDir, startBody = {}, spinner: spinner7 } = opts;
1495
+ spinner7?.message("Creating deployment...");
1496
+ const createRes = await ossFetch("/api/deployments", { method: "POST" });
1497
+ const { id: deploymentId, uploadUrl, uploadFields } = await createRes.json();
1498
+ spinner7?.message("Compressing source files...");
1499
+ const zipBuffer = await createZipBuffer(sourceDir);
1500
+ spinner7?.message("Uploading...");
1501
+ const formData = new FormData();
1502
+ for (const [key, value] of Object.entries(uploadFields)) {
1503
+ formData.append(key, value);
1504
+ }
1505
+ formData.append("file", new Blob([zipBuffer], { type: "application/zip" }), "deployment.zip");
1506
+ const uploadRes = await fetch(uploadUrl, { method: "POST", body: formData });
1507
+ if (!uploadRes.ok) {
1508
+ const uploadErr = await uploadRes.text();
1509
+ throw new CLIError(`Failed to upload: ${uploadErr}`);
1510
+ }
1511
+ spinner7?.message("Starting deployment...");
1512
+ const startRes = await ossFetch(`/api/deployments/${deploymentId}/start`, {
1513
+ method: "POST",
1514
+ body: JSON.stringify(startBody)
1515
+ });
1516
+ await startRes.json();
1517
+ return await pollDeployment(deploymentId, spinner7, false);
1518
+ }
1519
+ async function deployProject(opts) {
1520
+ const config = getProjectConfig();
1521
+ if (!config) {
1522
+ throw new ProjectNotLinkedError();
1523
+ }
1524
+ try {
1525
+ return await deployProjectDirect(opts, config);
1526
+ } catch (error) {
1527
+ if (!(error instanceof DirectDeploymentUnsupportedError)) {
1528
+ throw error;
1529
+ }
1530
+ opts.spinner?.message("Direct deployment is not available on this backend. Falling back to the legacy zip upload flow...");
1531
+ return await deployProjectLegacy(opts);
1532
+ }
1533
+ }
1359
1534
  function registerDeploymentsDeployCommand(deploymentsCmd2) {
1360
- deploymentsCmd2.command("deploy [directory]").description("Deploy a frontend project to Vercel").option("--env <vars>", `Environment variables as JSON (e.g. '{"KEY":"value"}')`).option("--meta <meta>", "Deployment metadata as JSON").action(async (directory, opts, cmd) => {
1535
+ deploymentsCmd2.command("deploy [directory]").description("Deploy a frontend project to Vercel").option("--env <vars>", 'Environment variables as JSON (e.g. {"KEY":"value"})').option("--meta <meta>", "Deployment metadata as JSON").action(async (directory, opts, cmd) => {
1361
1536
  const { json } = getRootOpts(cmd);
1362
1537
  try {
1363
1538
  await requireAuth();
@@ -1370,17 +1545,24 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
1370
1545
  }
1371
1546
  const dirName = path2.basename(sourceDir);
1372
1547
  if (EXCLUDE_PATTERNS.includes(dirName)) {
1373
- throw new CLIError(`"${dirName}" is an excluded directory and cannot be used as a deploy source. Please specify your project root or output directory instead.`);
1548
+ throw new CLIError(
1549
+ `"${dirName}" is an excluded directory and cannot be used as a deploy source. Please specify your project root or output directory instead.`
1550
+ );
1374
1551
  }
1375
- const s = !json ? clack6.spinner() : null;
1552
+ const spinner7 = !json ? clack6.spinner() : null;
1376
1553
  const startBody = {};
1377
1554
  if (opts.env) {
1378
1555
  try {
1379
1556
  const parsed = JSON.parse(opts.env);
1380
1557
  if (Array.isArray(parsed)) {
1381
1558
  startBody.envVars = parsed;
1559
+ } else if (parsed && typeof parsed === "object") {
1560
+ startBody.envVars = Object.entries(parsed).map(([key, value]) => ({
1561
+ key,
1562
+ value: String(value)
1563
+ }));
1382
1564
  } else {
1383
- startBody.envVars = Object.entries(parsed).map(([key, value]) => ({ key, value }));
1565
+ throw new CLIError("Invalid --env JSON. Expected an object or array.");
1384
1566
  }
1385
1567
  } catch {
1386
1568
  throw new CLIError("Invalid --env JSON.");
@@ -1393,9 +1575,9 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
1393
1575
  throw new CLIError("Invalid --meta JSON.");
1394
1576
  }
1395
1577
  }
1396
- const result = await deployProject({ sourceDir, startBody, spinner: s });
1578
+ const result = await deployProject({ sourceDir, startBody, spinner: spinner7 });
1397
1579
  if (result.isReady) {
1398
- s?.stop("Deployment complete");
1580
+ spinner7?.stop("Deployment complete");
1399
1581
  if (json) {
1400
1582
  outputJson(result.deployment);
1401
1583
  } else {
@@ -1405,9 +1587,13 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
1405
1587
  clack6.log.info(`Deployment ID: ${result.deploymentId}`);
1406
1588
  }
1407
1589
  } else {
1408
- s?.stop("Deployment is still building");
1590
+ spinner7?.stop("Deployment is still building");
1409
1591
  if (json) {
1410
- outputJson({ id: result.deploymentId, status: result.deployment?.status ?? "building", timedOut: true });
1592
+ outputJson({
1593
+ id: result.deploymentId,
1594
+ status: result.deployment?.status ?? "building",
1595
+ timedOut: true
1596
+ });
1411
1597
  } else {
1412
1598
  clack6.log.info(`Deployment ID: ${result.deploymentId}`);
1413
1599
  clack6.log.warn("Deployment did not finish within 5 minutes.");
@@ -2666,17 +2852,17 @@ function registerFunctionsCommands(functionsCmd2) {
2666
2852
 
2667
2853
  // src/commands/functions/deploy.ts
2668
2854
  import { readFileSync as readFileSync4, existsSync as existsSync3 } from "fs";
2669
- import { join as join6 } from "path";
2855
+ import { join as join7 } from "path";
2670
2856
  function registerFunctionsDeployCommand(functionsCmd2) {
2671
2857
  functionsCmd2.command("deploy <slug>").description("Deploy an edge function (create or update)").option("--file <path>", "Path to the function source file").option("--name <name>", "Function display name").option("--description <desc>", "Function description").action(async (slug, opts, cmd) => {
2672
2858
  const { json } = getRootOpts(cmd);
2673
2859
  try {
2674
2860
  await requireAuth();
2675
- const filePath = opts.file ?? join6(process.cwd(), "insforge", "functions", slug, "index.ts");
2861
+ const filePath = opts.file ?? join7(process.cwd(), "insforge", "functions", slug, "index.ts");
2676
2862
  if (!existsSync3(filePath)) {
2677
2863
  throw new CLIError(
2678
2864
  `Source file not found: ${filePath}
2679
- Specify --file <path> or create ${join6("insforge", "functions", slug, "index.ts")}`
2865
+ Specify --file <path> or create ${join7("insforge", "functions", slug, "index.ts")}`
2680
2866
  );
2681
2867
  }
2682
2868
  const code = readFileSync4(filePath, "utf-8");
@@ -2910,7 +3096,7 @@ function registerStorageUploadCommand(storageCmd2) {
2910
3096
 
2911
3097
  // src/commands/storage/download.ts
2912
3098
  import { writeFileSync as writeFileSync3 } from "fs";
2913
- import { join as join7, basename as basename6 } from "path";
3099
+ import { join as join8, basename as basename6 } from "path";
2914
3100
  function registerStorageDownloadCommand(storageCmd2) {
2915
3101
  storageCmd2.command("download <objectKey>").description("Download a file from a storage bucket").requiredOption("--bucket <name>", "Source bucket name").option("--output <path>", "Output file path (defaults to current directory)").action(async (objectKey, opts, cmd) => {
2916
3102
  const { json } = getRootOpts(cmd);
@@ -2930,7 +3116,7 @@ function registerStorageDownloadCommand(storageCmd2) {
2930
3116
  throw new CLIError(err.error ?? `Download failed: ${res.status}`);
2931
3117
  }
2932
3118
  const buffer = Buffer.from(await res.arrayBuffer());
2933
- const outputPath = opts.output ?? join7(process.cwd(), basename6(objectKey));
3119
+ const outputPath = opts.output ?? join8(process.cwd(), basename6(objectKey));
2934
3120
  writeFileSync3(outputPath, buffer);
2935
3121
  if (json) {
2936
3122
  outputJson({ success: true, path: outputPath, size: buffer.length });
@@ -4038,10 +4224,10 @@ function registerComputeLogsCommand(computeCmd2) {
4038
4224
 
4039
4225
  // src/commands/compute/deploy.ts
4040
4226
  import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, renameSync } from "fs";
4041
- import { join as join8 } from "path";
4227
+ import { join as join9 } from "path";
4042
4228
  import { execSync, spawn } from "child_process";
4043
4229
  function parseFlyToml(dir) {
4044
- const tomlPath = join8(dir, "fly.toml");
4230
+ const tomlPath = join9(dir, "fly.toml");
4045
4231
  if (!existsSync5(tomlPath)) return {};
4046
4232
  const content = readFileSync6(tomlPath, "utf-8");
4047
4233
  const config = {};
@@ -4113,7 +4299,7 @@ function registerComputeDeployCommand(computeCmd2) {
4113
4299
  checkFlyctl();
4114
4300
  const flyToken = getFlyToken();
4115
4301
  const dir = directory ?? process.cwd();
4116
- const dockerfilePath = join8(dir, "Dockerfile");
4302
+ const dockerfilePath = join9(dir, "Dockerfile");
4117
4303
  if (!existsSync5(dockerfilePath)) {
4118
4304
  throw new CLIError(`No Dockerfile found in ${dir}`);
4119
4305
  }
@@ -4159,8 +4345,8 @@ function registerComputeDeployCommand(computeCmd2) {
4159
4345
  serviceId = service.id;
4160
4346
  flyAppId = service.flyAppId;
4161
4347
  }
4162
- const existingTomlPath = join8(dir, "fly.toml");
4163
- const backupTomlPath = join8(dir, "fly.toml.insforge-backup");
4348
+ const existingTomlPath = join9(dir, "fly.toml");
4349
+ const backupTomlPath = join9(dir, "fly.toml.insforge-backup");
4164
4350
  let hadExistingToml = false;
4165
4351
  if (existsSync5(existingTomlPath)) {
4166
4352
  hadExistingToml = true;
@@ -4888,7 +5074,7 @@ function registerDiagnoseCommands(diagnoseCmd2) {
4888
5074
  const s = !json ? clack10.spinner() : null;
4889
5075
  s?.start("Collecting diagnostic data...");
4890
5076
  const data2 = await collectDiagnosticData(projectId, ossMode, apiUrl);
4891
- const cliVersion = "0.1.50";
5077
+ const cliVersion = "0.1.51";
4892
5078
  s?.stop("Data collected");
4893
5079
  if (!json) {
4894
5080
  console.log(`
@@ -5116,7 +5302,7 @@ function formatBytesCompact(bytes) {
5116
5302
 
5117
5303
  // src/index.ts
5118
5304
  var __dirname = dirname(fileURLToPath(import.meta.url));
5119
- var pkg = JSON.parse(readFileSync7(join9(__dirname, "../package.json"), "utf-8"));
5305
+ var pkg = JSON.parse(readFileSync7(join10(__dirname, "../package.json"), "utf-8"));
5120
5306
  var INSFORGE_LOGO = `
5121
5307
  \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
5122
5308
  \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D