@evitcastudio/kit 3.2.0 → 3.2.2

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.
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
+ // @bun
2
3
 
3
4
  /*!
4
- * @evitcastudio/kit@3.1.1 git+https://github.com/EvitcaStudio/Kit.git
5
- * Compiled Wed, 09 Sep 2026 07:29:03 UTC
5
+ * @evitcastudio/kit@3.2.2 git+https://github.com/EvitcaStudio/Kit.git
6
+ * Compiled Wed, 09 Sep 2026 14:01:08 UTC
6
7
  * Copyright (c) 2026 Jared Bates, Evitca Studio, "doubleactii"
7
8
  *
8
9
  * @evitcastudio/kit is licensed under the MIT License.
9
10
  * http://www.opensource.org/licenses/mit-license
10
11
  */
11
- import { createRequire } from "node:module";
12
12
  var __create = Object.create;
13
13
  var __getProtoOf = Object.getPrototypeOf;
14
14
  var __defProp = Object.defineProperty;
@@ -26,7 +26,6 @@ var __toESM = (mod, isNodeMode, target) => {
26
26
  return to;
27
27
  };
28
28
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
29
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
29
 
31
30
  // node_modules/commander/lib/error.js
32
31
  var require_error = __commonJS((exports) => {
@@ -351,7 +350,7 @@ var require_help = __commonJS((exports) => {
351
350
  return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
352
351
  }
353
352
  wrap(str, width, indent, minColumnWidth = 40) {
354
- const indents = " \\f\\t\\v   -    \uFEFF";
353
+ const indents = " \\f\\t\\v\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF";
355
354
  const manualIndent = new RegExp(`[\\n][${indents}]+`);
356
355
  if (str.match(manualIndent))
357
356
  return str;
@@ -363,7 +362,7 @@ var require_help = __commonJS((exports) => {
363
362
  `, `
364
363
  `);
365
364
  const indentString = " ".repeat(indent);
366
- const zeroWidthSpace = "";
365
+ const zeroWidthSpace = "\u200B";
367
366
  const breaks = `\\s${zeroWidthSpace}`;
368
367
  const regex = new RegExp(`
369
368
  |.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, "g");
@@ -606,11 +605,11 @@ var require_suggestSimilar = __commonJS((exports) => {
606
605
 
607
606
  // node_modules/commander/lib/command.js
608
607
  var require_command = __commonJS((exports) => {
609
- var EventEmitter = __require("node:events").EventEmitter;
610
- var childProcess = __require("node:child_process");
611
- var path = __require("node:path");
612
- var fs = __require("node:fs");
613
- var process2 = __require("node:process");
608
+ var EventEmitter = import.meta.require("events").EventEmitter;
609
+ var childProcess = import.meta.require("child_process");
610
+ var path = import.meta.require("path");
611
+ var fs = import.meta.require("fs");
612
+ var process2 = import.meta.require("process");
614
613
  var { Argument, humanReadableArgName } = require_argument();
615
614
  var { CommanderError } = require_error();
616
615
  var { Help } = require_help();
@@ -1943,8 +1942,8 @@ var {
1943
1942
  } = import__.default;
1944
1943
 
1945
1944
  // src/cli/resource-builder.ts
1946
- import { promises as fs, watch as fsWatch } from "fs";
1947
- import { join, extname, basename, resolve } from "path";
1945
+ import { promises as fs2, watch as fsWatch, existsSync as existsSync2 } from "fs";
1946
+ import { join as join2, extname as extname2, basename, resolve } from "path";
1948
1947
 
1949
1948
  // node_modules/chalk/source/vendor/ansi-styles/index.js
1950
1949
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -2124,9 +2123,9 @@ var ansiStyles = assembleStyles();
2124
2123
  var ansi_styles_default = ansiStyles;
2125
2124
 
2126
2125
  // node_modules/chalk/source/vendor/supports-color/index.js
2127
- import process2 from "node:process";
2128
- import os from "node:os";
2129
- import tty from "node:tty";
2126
+ import process2 from "process";
2127
+ import os from "os";
2128
+ import tty from "tty";
2130
2129
  function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
2131
2130
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
2132
2131
  const position = argv.indexOf(prefix + flag);
@@ -7987,6 +7986,215 @@ class WorkerPool {
7987
7986
  }
7988
7987
  }
7989
7988
 
7989
+ // src/cli/app-bundler.ts
7990
+ import { promises as fs, existsSync } from "fs";
7991
+ import { join, dirname, extname } from "path";
7992
+ var Bun2 = globalThis.Bun;
7993
+ function detectArchitecture(pSrcDir) {
7994
+ const hasClientEntry = existsSync(join(pSrcDir, "client", "index.ts"));
7995
+ const hasServerEntry = existsSync(join(pSrcDir, "server", "index.ts"));
7996
+ const hasSingleEntry = existsSync(join(pSrcDir, "index.ts"));
7997
+ if (hasClientEntry || hasServerEntry) {
7998
+ return "multi";
7999
+ }
8000
+ if (hasSingleEntry) {
8001
+ return "single";
8002
+ }
8003
+ return "none";
8004
+ }
8005
+ async function copyDirectoryRecursive(pSourceDir, pDestDir) {
8006
+ if (!existsSync(pSourceDir))
8007
+ return;
8008
+ const entries = await fs.readdir(pSourceDir, { withFileTypes: true });
8009
+ await fs.mkdir(pDestDir, { recursive: true });
8010
+ for (const entry of entries) {
8011
+ const srcPath = join(pSourceDir, entry.name);
8012
+ const destPath = join(pDestDir, entry.name);
8013
+ if (entry.isDirectory()) {
8014
+ await copyDirectoryRecursive(srcPath, destPath);
8015
+ } else {
8016
+ await fs.copyFile(srcPath, destPath);
8017
+ }
8018
+ }
8019
+ }
8020
+ async function copyStaticWebFiles(pSourceDir, pDestDir, pBaseDir) {
8021
+ if (!existsSync(pSourceDir))
8022
+ return;
8023
+ const entries = await fs.readdir(pSourceDir, { withFileTypes: true });
8024
+ for (const entry of entries) {
8025
+ const fullPath = join(pSourceDir, entry.name);
8026
+ if (entry.isDirectory()) {
8027
+ if (entry.name === "vendor" || entry.name === "resources" || entry.name === "node_modules") {
8028
+ continue;
8029
+ }
8030
+ await copyStaticWebFiles(fullPath, pDestDir, pBaseDir);
8031
+ } else {
8032
+ const ext = extname(entry.name).toLowerCase();
8033
+ if ([".html", ".css", ".ico"].includes(ext)) {
8034
+ const relativePath = fullPath.slice(pBaseDir.length).replace(/^[/\\]+/, "");
8035
+ const targetPath = join(pDestDir, relativePath);
8036
+ await fs.mkdir(dirname(targetPath), { recursive: true });
8037
+ await fs.copyFile(fullPath, targetPath);
8038
+ if ([".css", ".ico"].includes(ext)) {
8039
+ const rootTargetPath = join(pDestDir, entry.name);
8040
+ if (targetPath !== rootTargetPath && !existsSync(rootTargetPath)) {
8041
+ await fs.copyFile(fullPath, rootTargetPath);
8042
+ }
8043
+ }
8044
+ }
8045
+ }
8046
+ }
8047
+ }
8048
+ async function bundleApp(pProjectRoot, pOutDir, pOptions = {}) {
8049
+ const srcDir = join(pProjectRoot, "src");
8050
+ const architecture = detectArchitecture(srcDir);
8051
+ const isVerbose = Boolean(pOptions.verbose);
8052
+ if (architecture === "none") {
8053
+ if (isVerbose) {
8054
+ console.log(source_default.yellow("[Kit CLI] No application entrypoint detected (src/index.ts or src/client/index.ts). Skipping code bundle."));
8055
+ }
8056
+ return { architecture: "none", success: true };
8057
+ }
8058
+ const isProd = Boolean(pOptions.prod);
8059
+ const shouldMinify = isProd || Boolean(pOptions.minify);
8060
+ const shouldObfuscate = isProd || Boolean(pOptions.obfuscate);
8061
+ const sourcemapMode = pOptions.sourcemap ?? (isProd ? "none" : "linked");
8062
+ let banner = "";
8063
+ const pkgPath = join(pProjectRoot, "package.json");
8064
+ if (existsSync(pkgPath)) {
8065
+ try {
8066
+ const pkg = JSON.parse(await fs.readFile(pkgPath, "utf8"));
8067
+ banner = [
8068
+ "/*!",
8069
+ ` * ${pkg.name || "game"}@${pkg.version || "1.0.0"}`,
8070
+ ` * Compiled ${new Date().toUTCString().replace(/GMT/g, "UTC")}`,
8071
+ " *",
8072
+ ` * ${pkg.name || "game"} is privately licensed. All rights reserved.`,
8073
+ ` * Author: ${pkg.author ?? "Unnamed"}`,
8074
+ " */"
8075
+ ].join(`
8076
+ `);
8077
+ } catch {
8078
+ }
8079
+ }
8080
+ try {
8081
+ if (architecture === "single") {
8082
+ const startStamp = Date.now();
8083
+ const clientResult = await Bun2.build({
8084
+ entrypoints: [join(srcDir, "index.ts")],
8085
+ naming: "index.js",
8086
+ outdir: pOutDir,
8087
+ target: "browser",
8088
+ banner,
8089
+ sourcemap: sourcemapMode,
8090
+ minify: shouldMinify ? {
8091
+ identifiers: shouldObfuscate,
8092
+ syntax: true,
8093
+ whitespace: true
8094
+ } : false
8095
+ });
8096
+ if (!clientResult.success) {
8097
+ console.error(clientResult.logs);
8098
+ throw new AggregateError(clientResult.logs, "Client build failed");
8099
+ }
8100
+ await copyStaticWebFiles(srcDir, pOutDir, srcDir);
8101
+ const rootFavicon = join(pProjectRoot, "favicon.ico");
8102
+ if (existsSync(rootFavicon)) {
8103
+ await fs.copyFile(rootFavicon, join(pOutDir, "favicon.ico"));
8104
+ }
8105
+ const vendorDir = join(srcDir, "vendor");
8106
+ if (existsSync(vendorDir)) {
8107
+ await copyDirectoryRecursive(vendorDir, join(pOutDir, "vendor"));
8108
+ }
8109
+ const elapsed = Date.now() - startStamp;
8110
+ if (isVerbose) {
8111
+ console.log(source_default.hex("#ffa552")(`[Kit CLI] Singleplayer Client Build took: ${elapsed}ms`));
8112
+ }
8113
+ return { architecture: "single", clientBuildTime: elapsed, success: true };
8114
+ }
8115
+ if (architecture === "multi") {
8116
+ const clientEntry = join(srcDir, "client", "index.ts");
8117
+ const serverEntry = join(srcDir, "server", "index.ts");
8118
+ let clientElapsed = 0;
8119
+ let serverElapsed = 0;
8120
+ if (existsSync(clientEntry)) {
8121
+ const clientStart = Date.now();
8122
+ const clientResult = await Bun2.build({
8123
+ entrypoints: [clientEntry],
8124
+ naming: "index.js",
8125
+ outdir: pOutDir,
8126
+ target: "browser",
8127
+ banner,
8128
+ sourcemap: sourcemapMode,
8129
+ minify: shouldMinify ? {
8130
+ identifiers: shouldObfuscate,
8131
+ syntax: true,
8132
+ whitespace: true
8133
+ } : false
8134
+ });
8135
+ if (!clientResult.success) {
8136
+ console.error(clientResult.logs);
8137
+ throw new AggregateError(clientResult.logs, "Multiplayer client build failed");
8138
+ }
8139
+ const clientSrc = join(srcDir, "client");
8140
+ await copyStaticWebFiles(clientSrc, pOutDir, clientSrc);
8141
+ const clientVendor = join(clientSrc, "vendor");
8142
+ if (existsSync(clientVendor)) {
8143
+ await copyDirectoryRecursive(clientVendor, join(pOutDir, "vendor"));
8144
+ }
8145
+ clientElapsed = Date.now() - clientStart;
8146
+ }
8147
+ if (existsSync(serverEntry)) {
8148
+ const serverStart = Date.now();
8149
+ const serverResult = await Bun2.build({
8150
+ entrypoints: [serverEntry],
8151
+ naming: "server.js",
8152
+ outdir: pOutDir,
8153
+ target: "node",
8154
+ banner,
8155
+ sourcemap: sourcemapMode,
8156
+ minify: shouldMinify ? {
8157
+ identifiers: shouldObfuscate,
8158
+ syntax: true,
8159
+ whitespace: true
8160
+ } : false
8161
+ });
8162
+ if (!serverResult.success) {
8163
+ console.error(serverResult.logs);
8164
+ throw new AggregateError(serverResult.logs, "Multiplayer server build failed");
8165
+ }
8166
+ const settingsFile = join(srcDir, "server", "settings.json");
8167
+ if (existsSync(settingsFile)) {
8168
+ await fs.copyFile(settingsFile, join(pOutDir, "settings.json"));
8169
+ }
8170
+ serverElapsed = Date.now() - serverStart;
8171
+ }
8172
+ const rootFavicon = join(pProjectRoot, "favicon.ico");
8173
+ if (existsSync(rootFavicon)) {
8174
+ await fs.copyFile(rootFavicon, join(pOutDir, "favicon.ico"));
8175
+ }
8176
+ if (isVerbose) {
8177
+ if (clientElapsed) {
8178
+ console.log(source_default.hex("#ffa552")(`[Kit CLI] Multiplayer Client Build took: ${clientElapsed}ms`));
8179
+ }
8180
+ if (serverElapsed) {
8181
+ console.log(source_default.hex("#ffa552")(`[Kit CLI] Multiplayer Server Build took: ${serverElapsed}ms`));
8182
+ }
8183
+ }
8184
+ return {
8185
+ architecture: "multi",
8186
+ clientBuildTime: clientElapsed,
8187
+ serverBuildTime: serverElapsed,
8188
+ success: true
8189
+ };
8190
+ }
8191
+ return { architecture: "none", success: true };
8192
+ } catch (pError) {
8193
+ console.error(source_default.hex("#c42847")(`[Kit CLI Build Error] ${pError}`));
8194
+ return { architecture, success: false };
8195
+ }
8196
+ }
8197
+
7990
8198
  // src/cli/resource-builder.ts
7991
8199
  var log = console.log;
7992
8200
  var info = source_default.hex("#ffa552");
@@ -8009,7 +8217,7 @@ function initializeResourceJSON() {
8009
8217
  }, {});
8010
8218
  }
8011
8219
  function prepareFileForProcessing(pFilePath) {
8012
- const extension = extname(pFilePath).slice(1);
8220
+ const extension = extname2(pFilePath).slice(1);
8013
8221
  const fileName = basename(pFilePath);
8014
8222
  const resourceIdentifier = `${v4_default()}.vyr`;
8015
8223
  const type = getResourceType(extension);
@@ -8045,19 +8253,19 @@ function getResourceType(pExtension) {
8045
8253
  }
8046
8254
  async function processDirectory(pDirectoryPath) {
8047
8255
  try {
8048
- const contents = await fs.readdir(pDirectoryPath);
8256
+ const contents = await fs2.readdir(pDirectoryPath);
8049
8257
  for (const item of contents) {
8050
- const itemPath = join(pDirectoryPath, item);
8258
+ const itemPath = join2(pDirectoryPath, item);
8051
8259
  if (resolve(itemPath) === resourceOutDirectory) {
8052
8260
  continue;
8053
8261
  }
8054
- const stats = await fs.stat(itemPath);
8262
+ const stats = await fs2.stat(itemPath);
8055
8263
  if (stats.isDirectory()) {
8056
8264
  if (pDirectoryPath === resourceInDirectory) {
8057
8265
  subdirectoriesToMirror.push(item);
8058
8266
  }
8059
8267
  await processDirectory(itemPath);
8060
- } else if (isValidExtension(extname(itemPath).slice(1))) {
8268
+ } else if (isValidExtension(extname2(itemPath).slice(1))) {
8061
8269
  prepareFileForProcessing(itemPath);
8062
8270
  }
8063
8271
  }
@@ -8068,18 +8276,22 @@ async function processDirectory(pDirectoryPath) {
8068
8276
  function isValidExtension(pExtension) {
8069
8277
  return VALID_EXTENSIONS.includes(pExtension);
8070
8278
  }
8279
+ var ENGINE_EXTENSIONS = ["vyint", "vyi", "vym", "vymac"];
8280
+ function isEngineExtension(pExtension) {
8281
+ return ENGINE_EXTENSIONS.includes(pExtension);
8282
+ }
8071
8283
  async function mirrorDirectory(pSourceDir, pDestDir) {
8072
- const entries = await fs.readdir(pSourceDir, { withFileTypes: true });
8073
- await fs.mkdir(pDestDir, { recursive: true });
8284
+ const entries = await fs2.readdir(pSourceDir, { withFileTypes: true });
8285
+ await fs2.mkdir(pDestDir, { recursive: true });
8074
8286
  for (const entry of entries) {
8075
- const srcPath = join(pSourceDir, entry.name);
8076
- const destPath = join(pDestDir, entry.name);
8287
+ const srcPath = join2(pSourceDir, entry.name);
8288
+ const destPath = join2(pDestDir, entry.name);
8077
8289
  if (entry.isDirectory()) {
8078
8290
  await mirrorDirectory(srcPath, destPath);
8079
8291
  } else {
8080
- const ext = extname(entry.name).slice(1);
8081
- if (!isValidExtension(ext)) {
8082
- await fs.copyFile(srcPath, destPath);
8292
+ const ext = extname2(entry.name).slice(1);
8293
+ if (!isEngineExtension(ext)) {
8294
+ await fs2.copyFile(srcPath, destPath);
8083
8295
  }
8084
8296
  }
8085
8297
  }
@@ -8093,14 +8305,14 @@ async function processAllFiles() {
8093
8305
  if (!resource) {
8094
8306
  throw new Error(`Resource not found for file: ${fileName}`);
8095
8307
  }
8096
- const destination = join(resourceOutDirectory, "resources");
8308
+ const destination = join2(resourceOutDirectory, "resources");
8097
8309
  const resourceName = resource.resourceIdentifier;
8098
8310
  return copyFile(filePath, destination, resourceName);
8099
8311
  });
8100
8312
  await Promise.all(copyOperations);
8101
8313
  for (const subDir of subdirectoriesToMirror) {
8102
- const srcPath = join(resourceInDirectory, subDir);
8103
- const destPath = join(resourceOutDirectory, "resources", subDir);
8314
+ const srcPath = join2(resourceInDirectory, subDir);
8315
+ const destPath = join2(resourceOutDirectory, "resources", subDir);
8104
8316
  await mirrorDirectory(srcPath, destPath);
8105
8317
  }
8106
8318
  logVerbose(`[Kit CLI] All resources have been processed.`);
@@ -8122,7 +8334,7 @@ async function buildBoundsJSON() {
8122
8334
  if (type !== "icon")
8123
8335
  continue;
8124
8336
  try {
8125
- const fileBuffer = await fs.readFile(filePath);
8337
+ const fileBuffer = await fs2.readFile(filePath);
8126
8338
  const vyi = new VYI().parse(fileBuffer);
8127
8339
  const atlasName = basename(filePath, ".vyi");
8128
8340
  const atlasEntry = {};
@@ -8163,7 +8375,7 @@ async function buildBoundsJSON() {
8163
8375
  async function saveBoundsJSON(pBoundsData) {
8164
8376
  const filePath = "bounds.json";
8165
8377
  try {
8166
- await fs.writeFile(filePath, JSON.stringify(pBoundsData));
8378
+ await fs2.writeFile(filePath, JSON.stringify(pBoundsData));
8167
8379
  } catch (pError) {
8168
8380
  logError(`[Error] Saving bounds JSON: ${pError}`);
8169
8381
  }
@@ -8174,7 +8386,7 @@ async function buildIconPointsJSON() {
8174
8386
  if (type !== "icon")
8175
8387
  continue;
8176
8388
  try {
8177
- const fileBuffer = await fs.readFile(filePath);
8389
+ const fileBuffer = await fs2.readFile(filePath);
8178
8390
  const vyi = new VYI().parse(fileBuffer);
8179
8391
  const atlasName = basename(filePath, ".vyi");
8180
8392
  const atlasEntry = {};
@@ -8233,7 +8445,7 @@ async function buildIconPointsJSON() {
8233
8445
  async function saveIconPointsJSON(pPointsData) {
8234
8446
  const filePath = "icon-points.json";
8235
8447
  try {
8236
- await fs.writeFile(filePath, JSON.stringify(pPointsData));
8448
+ await fs2.writeFile(filePath, JSON.stringify(pPointsData));
8237
8449
  } catch (pError) {
8238
8450
  logError(`[Error] Saving icon points JSON: ${pError}`);
8239
8451
  }
@@ -8244,7 +8456,7 @@ async function buildSizesJSON() {
8244
8456
  if (type !== "icon")
8245
8457
  continue;
8246
8458
  try {
8247
- const fileBuffer = await fs.readFile(filePath);
8459
+ const fileBuffer = await fs2.readFile(filePath);
8248
8460
  const vyi = new VYI().parse(fileBuffer);
8249
8461
  const atlasName = basename(filePath, ".vyi");
8250
8462
  const atlasEntry = {};
@@ -8266,16 +8478,16 @@ async function buildSizesJSON() {
8266
8478
  async function saveSizesJSON(pSizesData) {
8267
8479
  const filePath = "sizes.json";
8268
8480
  try {
8269
- await fs.writeFile(filePath, JSON.stringify(pSizesData));
8481
+ await fs2.writeFile(filePath, JSON.stringify(pSizesData));
8270
8482
  } catch (pError) {
8271
8483
  logError(`[Error] Saving sizes JSON: ${pError}`);
8272
8484
  }
8273
8485
  }
8274
8486
  async function clearResourceTypeDirectories(pBaseDirectory) {
8275
8487
  try {
8276
- const directoryExists = await fs.stat(pBaseDirectory).then((stat) => stat.isDirectory()).catch(() => false);
8488
+ const directoryExists = await fs2.stat(pBaseDirectory).then((stat) => stat.isDirectory()).catch(() => false);
8277
8489
  if (directoryExists) {
8278
- await fs.rm(pBaseDirectory, { recursive: true });
8490
+ await fs2.rm(pBaseDirectory, { recursive: true });
8279
8491
  }
8280
8492
  } catch (pError) {
8281
8493
  log(`${error(`[Error]`)} clearing resource directory: ${pError}`);
@@ -8283,8 +8495,8 @@ async function clearResourceTypeDirectories(pBaseDirectory) {
8283
8495
  }
8284
8496
  async function copyFile(pSource, pDestinationDir, pNewName) {
8285
8497
  try {
8286
- await fs.mkdir(pDestinationDir, { recursive: true });
8287
- await fs.copyFile(pSource, join(pDestinationDir, pNewName));
8498
+ await fs2.mkdir(pDestinationDir, { recursive: true });
8499
+ await fs2.copyFile(pSource, join2(pDestinationDir, pNewName));
8288
8500
  } catch (pError) {
8289
8501
  logError(`[Error] Copying file ${pSource}: ${pError}`);
8290
8502
  }
@@ -8293,16 +8505,21 @@ async function saveResourceJSON() {
8293
8505
  const jsonContent = JSON.stringify(resourceJSON, null, 4);
8294
8506
  const targetPath = customManifestPath || "resource.json";
8295
8507
  try {
8296
- await fs.writeFile(targetPath, jsonContent, "utf8");
8508
+ await fs2.writeFile(targetPath, jsonContent, "utf8");
8297
8509
  } catch (pError) {
8298
8510
  logError(`[Error] Saving resource JSON to ${targetPath}: ${pError}`);
8299
8511
  }
8300
8512
  }
8513
+ var shouldBundleApp = false;
8514
+ var projectRootDirectory = "";
8515
+ var appBundleOptions = {};
8301
8516
  async function runBuild() {
8302
8517
  resourceJSON = initializeResourceJSON();
8303
8518
  resourcesToProcess.length = 0;
8304
8519
  subdirectoriesToMirror.length = 0;
8305
- await processDirectory(resourceInDirectory);
8520
+ if (existsSync2(resourceInDirectory)) {
8521
+ await processDirectory(resourceInDirectory);
8522
+ }
8306
8523
  if (resourcesToProcess.length > 0 || subdirectoriesToMirror.length > 0) {
8307
8524
  await processAllFiles();
8308
8525
  } else {
@@ -8312,35 +8529,70 @@ async function runBuild() {
8312
8529
  await saveIconPointsJSON({});
8313
8530
  await saveSizesJSON({});
8314
8531
  }
8532
+ if (shouldBundleApp && projectRootDirectory) {
8533
+ await bundleApp(projectRootDirectory, resourceOutDirectory, {
8534
+ ...appBundleOptions,
8535
+ verbose: Boolean(isVerbose)
8536
+ });
8537
+ }
8315
8538
  logVerbose(`[Kit CLI] Resources built successfully.`);
8316
8539
  }
8317
8540
  async function runWatch() {
8318
8541
  await runBuild();
8319
8542
  console.log(source_default.cyan(`
8320
- \uD83D\uDC40 Watching for changes in: ${source_default.bold(resourceInDirectory)}`));
8543
+ Watching for changes in: ${source_default.bold(resourceInDirectory)}`));
8321
8544
  let debounceTimer = null;
8322
- const watcher = fsWatch(resourceInDirectory, { recursive: true }, (_eventType, pFilename) => {
8323
- if (!pFilename)
8324
- return;
8545
+ const triggerRebuild = (pFilename) => {
8325
8546
  if (debounceTimer)
8326
8547
  clearTimeout(debounceTimer);
8327
8548
  debounceTimer = setTimeout(async () => {
8328
8549
  console.log(source_default.dim(`
8329
- Asset changed: ${pFilename}, rebuilding...`));
8550
+ File changed: ${pFilename}, rebuilding...`));
8330
8551
  await runBuild();
8331
8552
  }, 150);
8332
- });
8553
+ };
8554
+ const watchers = [];
8555
+ if (existsSync2(resourceInDirectory)) {
8556
+ const resWatcher = fsWatch(resourceInDirectory, { recursive: true }, (_eventType, pFilename) => {
8557
+ if (pFilename)
8558
+ triggerRebuild(pFilename);
8559
+ });
8560
+ watchers.push(resWatcher);
8561
+ }
8562
+ const srcDir = join2(projectRootDirectory, "src");
8563
+ if (shouldBundleApp && existsSync2(srcDir) && srcDir !== resourceInDirectory) {
8564
+ const srcWatcher = fsWatch(srcDir, { recursive: true }, (_eventType, pFilename) => {
8565
+ if (!pFilename)
8566
+ return;
8567
+ if (pFilename.startsWith("resources"))
8568
+ return;
8569
+ triggerRebuild(pFilename);
8570
+ });
8571
+ watchers.push(srcWatcher);
8572
+ }
8333
8573
  process.on("SIGINT", () => {
8334
- watcher.close();
8574
+ for (const w of watchers)
8575
+ w.close();
8335
8576
  process.exit(0);
8336
8577
  });
8337
8578
  }
8338
- async function processResources({ inDirectory, outDirectory, manifestPath, watch, verbose, ignoreSound }) {
8339
- resourceInDirectory = inDirectory ? resolve(inDirectory) : "";
8340
- resourceOutDirectory = outDirectory ? resolve(outDirectory) : "";
8579
+ async function processResources({ inDirectory, outDirectory, manifestPath, watch, verbose, ignoreSound, app, minify, obfuscate, sourcemap, prod }) {
8580
+ projectRootDirectory = process.cwd();
8581
+ const resolvedIn = inDirectory || (existsSync2(join2(projectRootDirectory, "src", "resources")) ? "src/resources" : "");
8582
+ const resolvedOut = outDirectory || "dist";
8583
+ resourceInDirectory = resolvedIn ? resolve(resolvedIn) : "";
8584
+ resourceOutDirectory = resolvedOut ? resolve(resolvedOut) : "";
8341
8585
  customManifestPath = manifestPath;
8342
8586
  isVerbose = verbose;
8343
8587
  ignoringSound = ignoreSound;
8588
+ appBundleOptions = {
8589
+ minify,
8590
+ obfuscate,
8591
+ sourcemap,
8592
+ prod
8593
+ };
8594
+ const hasAppEntry = existsSync2(join2(projectRootDirectory, "src", "index.ts")) || existsSync2(join2(projectRootDirectory, "src", "client", "index.ts")) || existsSync2(join2(projectRootDirectory, "src", "server", "index.ts"));
8595
+ shouldBundleApp = app !== undefined ? app : hasAppEntry;
8344
8596
  if (!resourceInDirectory || !resourceOutDirectory) {
8345
8597
  logError("[Error] Input and output directories must be specified");
8346
8598
  return;
@@ -8364,11 +8616,11 @@ function logAlert(pMessage) {
8364
8616
 
8365
8617
  // node_modules/@clack/core/dist/index.mjs
8366
8618
  var import_sisteransi = __toESM(require_src(), 1);
8367
- import { styleText as D } from "node:util";
8368
- import { stdout as R, stdin as q } from "node:process";
8369
- import * as k from "node:readline";
8370
- import ot from "node:readline";
8371
- import { ReadStream as J } from "node:tty";
8619
+ import { styleText as D } from "util";
8620
+ import { stdout as R, stdin as q } from "process";
8621
+ import * as k from "readline";
8622
+ import ot from "readline";
8623
+ import { ReadStream as J } from "tty";
8372
8624
  function x(t, e, s) {
8373
8625
  if (!s.some((u) => !u.disabled))
8374
8626
  return t;
@@ -8452,7 +8704,7 @@ var X = (t, e = {}, s = {}) => {
8452
8704
  var pt = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
8453
8705
  var S = (t, e = {}) => X(t, pt, e).width;
8454
8706
  var T = "\x1B";
8455
- var Z = "›";
8707
+ var Z = "\x9B";
8456
8708
  var Ft = 39;
8457
8709
  var j = "\x07";
8458
8710
  var Q = "[";
@@ -8773,7 +9025,7 @@ class Vt extends B {
8773
9025
  if (!this.userInput)
8774
9026
  return D(["inverse", "hidden"], "_");
8775
9027
  if (this._cursor >= this.userInput.length)
8776
- return `${this.userInput}█`;
9028
+ return `${this.userInput}\u2588`;
8777
9029
  const e = this.userInput.slice(0, this._cursor), [s, ...i] = this.userInput.slice(this._cursor);
8778
9030
  return `${e}${D("inverse", s)}${i.join("")}`;
8779
9031
  }
@@ -8916,7 +9168,7 @@ class $t extends B {
8916
9168
  return this.userInput;
8917
9169
  const e = this.userInput;
8918
9170
  if (this.cursor >= e.length)
8919
- return `${this.userInput}█`;
9171
+ return `${this.userInput}\u2588`;
8920
9172
  const s = e.slice(0, this.cursor), [i, ...r] = e.slice(this.cursor);
8921
9173
  return `${s}${D("inverse", i)}${r.join("")}`;
8922
9174
  }
@@ -8933,8 +9185,8 @@ class $t extends B {
8933
9185
  }
8934
9186
 
8935
9187
  // node_modules/@clack/prompts/dist/index.mjs
8936
- import { styleText as t, stripVTControlCharacters as ue } from "node:util";
8937
- import N2 from "node:process";
9188
+ import { styleText as t, stripVTControlCharacters as ue } from "util";
9189
+ import N2 from "process";
8938
9190
  var import_sisteransi2 = __toESM(require_src(), 1);
8939
9191
  function pt2() {
8940
9192
  return N2.platform !== "win32" ? N2.env.TERM !== "linux" : !!N2.env.CI || !!N2.env.WT_SESSION || !!N2.env.TERMINUS_SUBLIME || N2.env.ConEmuTask === "{cmd::Cmder}" || N2.env.TERM_PROGRAM === "Terminus-Sublime" || N2.env.TERM_PROGRAM === "vscode" || N2.env.TERM === "xterm-256color" || N2.env.TERM === "alacritty" || N2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
@@ -8942,31 +9194,31 @@ function pt2() {
8942
9194
  var ee = pt2();
8943
9195
  var ce = () => process.env.CI === "true";
8944
9196
  var I2 = (e, r) => ee ? e : r;
8945
- var Re = I2("", "*");
8946
- var $e = I2("", "x");
8947
- var de = I2("", "x");
8948
- var V = I2("", "o");
8949
- var he = I2("", "T");
8950
- var h = I2("", "|");
8951
- var x2 = I2("", "");
8952
- var Oe = I2("", "T");
8953
- var Pe = I2("", "");
8954
- var z2 = I2("", ">");
8955
- var H2 = I2("", " ");
8956
- var te = I2("", "[]");
8957
- var U2 = I2("", "[+]");
8958
- var q2 = I2("", "[ ]");
8959
- var Ne = I2("", "");
8960
- var se = I2("", "-");
8961
- var pe = I2("", "+");
8962
- var We = I2("", "+");
8963
- var me = I2("", "+");
8964
- var ge = I2("", "+");
8965
- var Ge = I2("", "+");
8966
- var fe = I2("", "");
8967
- var Fe = I2("", "*");
8968
- var ye = I2("", "!");
8969
- var Ee = I2("", "x");
9197
+ var Re = I2("\u25C6", "*");
9198
+ var $e = I2("\u25A0", "x");
9199
+ var de = I2("\u25B2", "x");
9200
+ var V = I2("\u25C7", "o");
9201
+ var he = I2("\u250C", "T");
9202
+ var h = I2("\u2502", "|");
9203
+ var x2 = I2("\u2514", "\u2014");
9204
+ var Oe = I2("\u2510", "T");
9205
+ var Pe = I2("\u2518", "\u2014");
9206
+ var z2 = I2("\u25CF", ">");
9207
+ var H2 = I2("\u25CB", " ");
9208
+ var te = I2("\u25FB", "[\u2022]");
9209
+ var U2 = I2("\u25FC", "[+]");
9210
+ var q2 = I2("\u25FB", "[ ]");
9211
+ var Ne = I2("\u25AA", "\u2022");
9212
+ var se = I2("\u2500", "-");
9213
+ var pe = I2("\u256E", "+");
9214
+ var We = I2("\u251C", "+");
9215
+ var me = I2("\u256F", "+");
9216
+ var ge = I2("\u2570", "+");
9217
+ var Ge = I2("\u256D", "+");
9218
+ var fe = I2("\u25CF", "\u2022");
9219
+ var Fe = I2("\u25C6", "*");
9220
+ var ye = I2("\u25B2", "!");
9221
+ var Ee = I2("\u25A0", "x");
8970
9222
  var W2 = (e) => {
8971
9223
  switch (e) {
8972
9224
  case "initial":
@@ -9070,7 +9322,7 @@ var Le = (e, r = {}, s = {}) => {
9070
9322
  var Et2 = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
9071
9323
  var D2 = (e, r = {}) => Le(e, Et2, r).width;
9072
9324
  var ae = "\x1B";
9073
- var je = "›";
9325
+ var je = "\x9B";
9074
9326
  var vt2 = 39;
9075
9327
  var Ce = "\x07";
9076
9328
  var ke = "[";
@@ -9273,7 +9525,7 @@ ${t("gray", f + se.repeat(n + 2) + me)}
9273
9525
  `);
9274
9526
  };
9275
9527
  var Kt = (e) => t("magenta", e);
9276
- var be = ({ indicator: e = "dots", onCancel: r, output: s = process.stdout, cancelMessage: i, errorMessage: a, frames: o = ee ? ["", "", "", ""] : ["", "o", "O", "0"], delay: u = ee ? 80 : 120, signal: l, ...n } = {}) => {
9528
+ var be = ({ indicator: e = "dots", onCancel: r, output: s = process.stdout, cancelMessage: i, errorMessage: a, frames: o = ee ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], delay: u = ee ? 80 : 120, signal: l, ...n } = {}) => {
9277
9529
  const c = ce();
9278
9530
  let p, f, g = false, E = false, $ = "", m, d = performance.now();
9279
9531
  const F = rt(s), y2 = n?.styleFrame ?? Kt, v = (B2) => {
@@ -9330,7 +9582,7 @@ var be = ({ indicator: e = "dots", onCancel: r, output: s = process.stdout, canc
9330
9582
  return E;
9331
9583
  } };
9332
9584
  };
9333
- var ze = { light: I2("", "-"), heavy: I2("", "="), block: I2("", "#") };
9585
+ var ze = { light: I2("\u2500", "-"), heavy: I2("\u2501", "="), block: I2("\u2588", "#") };
9334
9586
  var oe = (e, r) => e.includes(`
9335
9587
  `) ? e.split(`
9336
9588
  `).map((s) => r(s)).join(`
@@ -9408,15 +9660,15 @@ ${l}
9408
9660
  } }).prompt();
9409
9661
 
9410
9662
  // src/cli/init.ts
9411
- import fs2 from "node:fs";
9412
- import path from "node:path";
9413
- import { fileURLToPath } from "node:url";
9414
- import { spawnSync, execSync } from "node:child_process";
9415
- import os2 from "node:os";
9663
+ import fs3 from "fs";
9664
+ import path from "path";
9665
+ import { fileURLToPath } from "url";
9666
+ import { spawnSync, execSync } from "child_process";
9667
+ import os2 from "os";
9416
9668
  // package.json
9417
9669
  var package_default = {
9418
9670
  name: "@evitcastudio/kit",
9419
- version: "3.1.1",
9671
+ version: "3.2.2",
9420
9672
  author: "doubleactii 56242467+doubleactii@users.noreply.github.com (https://evitcastudio.com)",
9421
9673
  main: "./lib/index.js",
9422
9674
  types: "./lib/index.d.ts",
@@ -9459,7 +9711,7 @@ var package_default = {
9459
9711
  "build-all": "bun run build-types && bun run build && bun run build-docs"
9460
9712
  },
9461
9713
  bin: {
9462
- kit: "lib/bundle/cli/cli.js"
9714
+ kit: "lib/cli-runner.cjs"
9463
9715
  },
9464
9716
  devDependencies: {
9465
9717
  "@eslint/create-config": "1.4.0",
@@ -9516,15 +9768,15 @@ function installBun() {
9516
9768
  }
9517
9769
  }
9518
9770
  function copyTemplate(pSrc, pDest, pProjectName, pVersion, pAuthor) {
9519
- if (!fs2.existsSync(pDest)) {
9520
- fs2.mkdirSync(pDest, { recursive: true });
9771
+ if (!fs3.existsSync(pDest)) {
9772
+ fs3.mkdirSync(pDest, { recursive: true });
9521
9773
  }
9522
- const files = fs2.readdirSync(pSrc);
9774
+ const files = fs3.readdirSync(pSrc);
9523
9775
  for (const file of files) {
9524
9776
  const srcPath = path.join(pSrc, file);
9525
9777
  const destFile = file === "_gitignore" ? ".gitignore" : file;
9526
9778
  const destPath = path.join(pDest, destFile);
9527
- const stats = fs2.statSync(srcPath);
9779
+ const stats = fs3.statSync(srcPath);
9528
9780
  if (stats.isDirectory()) {
9529
9781
  if (file === ".git")
9530
9782
  continue;
@@ -9533,13 +9785,13 @@ function copyTemplate(pSrc, pDest, pProjectName, pVersion, pAuthor) {
9533
9785
  const ext = path.extname(file).toLowerCase();
9534
9786
  const textExtensions = [".ts", ".js", ".json", ".html", ".css", ".md", ".txt"];
9535
9787
  if (textExtensions.includes(ext)) {
9536
- let content = fs2.readFileSync(srcPath, "utf8");
9788
+ let content = fs3.readFileSync(srcPath, "utf8");
9537
9789
  content = content.replace(/{{PROJECT_NAME}}/g, pProjectName);
9538
9790
  content = content.replace(/{{VERSION}}/g, pVersion);
9539
9791
  content = content.replace(/{{PROJECT_AUTHOR}}/g, pAuthor);
9540
- fs2.writeFileSync(destPath, content);
9792
+ fs3.writeFileSync(destPath, content);
9541
9793
  } else {
9542
- fs2.copyFileSync(srcPath, destPath);
9794
+ fs3.copyFileSync(srcPath, destPath);
9543
9795
  }
9544
9796
  }
9545
9797
  }
@@ -9619,7 +9871,7 @@ Note: Kit projects cannot build or run without Bun.`);
9619
9871
  projectName = "kit-project";
9620
9872
  }
9621
9873
  const projectDir = path.join(process.cwd(), projectName);
9622
- if (fs2.existsSync(projectDir)) {
9874
+ if (fs3.existsSync(projectDir)) {
9623
9875
  if (isInteractive) {
9624
9876
  const overwrite = await Rt({
9625
9877
  message: `Directory ${source_default.cyan(projectName)} already exists. Overwrite?`,
@@ -9639,18 +9891,18 @@ Error: Destination directory '${projectName}' already exists. Use --force (-f) t
9639
9891
  s.start(`Scaffolding ${source_default.cyan(projectName)}...`);
9640
9892
  try {
9641
9893
  const projectPath = path.join(process.cwd(), projectName);
9642
- if (fs2.existsSync(projectPath)) {
9643
- fs2.rmSync(projectPath, { recursive: true, force: true });
9894
+ if (fs3.existsSync(projectPath)) {
9895
+ fs3.rmSync(projectPath, { recursive: true, force: true });
9644
9896
  }
9645
- fs2.mkdirSync(projectPath, { recursive: true });
9897
+ fs3.mkdirSync(projectPath, { recursive: true });
9646
9898
  let templateType = gameType;
9647
9899
  if (gameType === "both")
9648
9900
  templateType = "multi";
9649
9901
  const templatesDir = path.join(path.dirname(fileURLToPath(import.meta.url)), "kit-game-templates", templateType);
9650
9902
  const author = getGitUser();
9651
- if (!fs2.existsSync(templatesDir)) {
9903
+ if (!fs3.existsSync(templatesDir)) {
9652
9904
  const localTemplatesDir = path.join(process.cwd(), "kit-game-templates", templateType);
9653
- if (!fs2.existsSync(localTemplatesDir)) {
9905
+ if (!fs3.existsSync(localTemplatesDir)) {
9654
9906
  console.error(source_default.red(`Error: Templates not found at ${templatesDir} or ${localTemplatesDir}`));
9655
9907
  process.exit(1);
9656
9908
  }
@@ -9678,23 +9930,23 @@ Error: Destination directory '${projectName}' already exists. Use --force (-f) t
9678
9930
  installSpinner.stop(source_default.yellow("Dependency installation finished with warnings."));
9679
9931
  }
9680
9932
  }
9681
- console.log(`${source_default.cyan("")}`);
9682
- console.log(`${source_default.cyan("")} ${source_default.white.bold("Next steps:")}`);
9683
- console.log(`${source_default.cyan("")} ${source_default.dim("1.")} cd ${source_default.cyan(projectName)}`);
9933
+ console.log(`${source_default.cyan("\u2502")}`);
9934
+ console.log(`${source_default.cyan("\u2502")} ${source_default.white.bold("Next steps:")}`);
9935
+ console.log(`${source_default.cyan("\u2502")} ${source_default.dim("1.")} cd ${source_default.cyan(projectName)}`);
9684
9936
  if (!shouldInstall) {
9685
- console.log(`${source_default.cyan("")} ${source_default.dim("2.")} bun install`);
9686
- console.log(`${source_default.cyan("")} ${source_default.dim("3.")} bun run build`);
9937
+ console.log(`${source_default.cyan("\u2502")} ${source_default.dim("2.")} bun install`);
9938
+ console.log(`${source_default.cyan("\u2502")} ${source_default.dim("3.")} bun run build`);
9687
9939
  } else {
9688
- console.log(`${source_default.cyan("")} ${source_default.dim("2.")} bun run build`);
9940
+ console.log(`${source_default.cyan("\u2502")} ${source_default.dim("2.")} bun run build`);
9689
9941
  }
9690
- console.log(`${source_default.cyan("")}`);
9942
+ console.log(`${source_default.cyan("\u2502")}`);
9691
9943
  Gt(source_default.green.bold("Happy coding!"));
9692
9944
  } catch (pError) {
9693
9945
  s.stop(source_default.red("Scaffolding failed."));
9694
9946
  if (projectName) {
9695
9947
  const projectPath = path.join(process.cwd(), projectName);
9696
- if (fs2.existsSync(projectPath)) {
9697
- fs2.rmSync(projectPath, { recursive: true, force: true });
9948
+ if (fs3.existsSync(projectPath)) {
9949
+ fs3.rmSync(projectPath, { recursive: true, force: true });
9698
9950
  }
9699
9951
  }
9700
9952
  console.error(pError);
@@ -9703,9 +9955,9 @@ Error: Destination directory '${projectName}' already exists. Use --force (-f) t
9703
9955
  }
9704
9956
 
9705
9957
  // src/cli/doctor.ts
9706
- import { spawnSync as spawnSync2 } from "node:child_process";
9707
- import { existsSync, readFileSync } from "node:fs";
9708
- import { join as join2 } from "node:path";
9958
+ import { spawnSync as spawnSync2 } from "child_process";
9959
+ import { existsSync as existsSync3, readFileSync } from "fs";
9960
+ import { join as join3 } from "path";
9709
9961
  async function processDoctor(pOptions = {}) {
9710
9962
  const isVerbose2 = Boolean(pOptions.verbose);
9711
9963
  const results = [];
@@ -9745,8 +9997,8 @@ async function processDoctor(pOptions = {}) {
9745
9997
  });
9746
9998
  }
9747
9999
  const cwd = process.cwd();
9748
- const pkgPath = join2(cwd, "package.json");
9749
- const hasPackageJson = existsSync(pkgPath);
10000
+ const pkgPath = join3(cwd, "package.json");
10001
+ const hasPackageJson = existsSync3(pkgPath);
9750
10002
  if (hasPackageJson) {
9751
10003
  try {
9752
10004
  const rawPkg = readFileSync(pkgPath, "utf8");
@@ -9766,8 +10018,8 @@ async function processDoctor(pOptions = {}) {
9766
10018
  });
9767
10019
  const isKitCoreRepo = pkg.name === "@evitcastudio/kit";
9768
10020
  if (!isKitCoreRepo) {
9769
- const resourcesDir = join2(cwd, "src", "resources");
9770
- const hasResources = existsSync(resourcesDir);
10021
+ const resourcesDir = join3(cwd, "src", "resources");
10022
+ const hasResources = existsSync3(resourcesDir);
9771
10023
  results.push({
9772
10024
  category: "Project",
9773
10025
  title: "Asset Directory (src/resources)",
@@ -9775,6 +10027,25 @@ async function processDoctor(pOptions = {}) {
9775
10027
  details: hasResources ? "Asset directory present" : "src/resources not found"
9776
10028
  });
9777
10029
  }
10030
+ const hasClientEntry = existsSync3(join3(cwd, "src", "client", "index.ts"));
10031
+ const hasServerEntry = existsSync3(join3(cwd, "src", "server", "index.ts"));
10032
+ const hasSingleEntry = existsSync3(join3(cwd, "src", "index.ts"));
10033
+ let projectType = "Unknown";
10034
+ if (hasClientEntry && hasServerEntry) {
10035
+ projectType = "Multiplayer (Client & Server)";
10036
+ } else if (hasClientEntry) {
10037
+ projectType = "Multiplayer (Client)";
10038
+ } else if (hasServerEntry) {
10039
+ projectType = "Dedicated Server";
10040
+ } else if (hasSingleEntry) {
10041
+ projectType = "Singleplayer";
10042
+ }
10043
+ results.push({
10044
+ category: "Project",
10045
+ title: "Project Architecture",
10046
+ passed: projectType !== "Unknown" || isKitCoreRepo,
10047
+ details: isKitCoreRepo ? "Kit Core Framework Repository" : `Detected Type: ${projectType}`
10048
+ });
9778
10049
  } catch {
9779
10050
  results.push({
9780
10051
  category: "Project",
@@ -9783,13 +10054,31 @@ async function processDoctor(pOptions = {}) {
9783
10054
  details: "package.json is malformed or invalid JSON"
9784
10055
  });
9785
10056
  }
9786
- const buildScript = join2(cwd, "bun-build.ts");
9787
- const hasBuildScript = existsSync(buildScript);
10057
+ const buildScript = join3(cwd, "bun-build.ts");
10058
+ const hasBuildScript = existsSync3(buildScript);
10059
+ let hasKitBuildScript = false;
10060
+ try {
10061
+ const rawPkg = readFileSync(pkgPath, "utf8");
10062
+ const pkg = JSON.parse(rawPkg);
10063
+ if (pkg.scripts && typeof pkg.scripts.build === "string" && pkg.scripts.build.includes("kit build")) {
10064
+ hasKitBuildScript = true;
10065
+ }
10066
+ } catch {
10067
+ }
10068
+ const buildPipelinePassed = hasBuildScript || hasKitBuildScript;
10069
+ let buildDetails = "No build pipeline configured";
10070
+ if (hasKitBuildScript && hasBuildScript) {
10071
+ buildDetails = "Kit CLI build pipeline with bun-build.ts present";
10072
+ } else if (hasKitBuildScript) {
10073
+ buildDetails = "Kit CLI native build pipeline configured";
10074
+ } else if (hasBuildScript) {
10075
+ buildDetails = "Legacy bun-build.ts present";
10076
+ }
9788
10077
  results.push({
9789
10078
  category: "Project",
9790
- title: "Build Pipeline (bun-build.ts)",
9791
- passed: hasBuildScript,
9792
- details: hasBuildScript ? "Build script present" : "bun-build.ts not found"
10079
+ title: "Build Pipeline",
10080
+ passed: buildPipelinePassed,
10081
+ details: buildDetails
9793
10082
  });
9794
10083
  } else {
9795
10084
  results.push({
@@ -9801,7 +10090,7 @@ async function processDoctor(pOptions = {}) {
9801
10090
  }
9802
10091
  let allPassed = true;
9803
10092
  for (const res of results) {
9804
- const icon = res.passed ? source_default.green("") : source_default.red("");
10093
+ const icon = res.passed ? source_default.green("\u2713") : source_default.red("\u2717");
9805
10094
  const titleText = res.passed ? source_default.white(res.title) : source_default.red.bold(res.title);
9806
10095
  console.log(` ${icon} [${source_default.cyan(res.category)}] ${titleText}`);
9807
10096
  if (res.details && (!res.passed || isVerbose2)) {
@@ -9824,8 +10113,8 @@ async function processDoctor(pOptions = {}) {
9824
10113
  }
9825
10114
 
9826
10115
  // src/cli/create.ts
9827
- import { promises as fs3 } from "node:fs";
9828
- import { join as join3 } from "node:path";
10116
+ import { promises as fs4 } from "fs";
10117
+ import { join as join4 } from "path";
9829
10118
  function toPascalCase(pName) {
9830
10119
  return pName.replace(/[-_](\w)/g, (_2, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toUpperCase());
9831
10120
  }
@@ -9868,20 +10157,20 @@ Error: Unknown create type '${type}'. Supported types: 'plugin'`));
9868
10157
  }
9869
10158
  const className = toPascalCase(name);
9870
10159
  const fileName = `${toKebabCase(name)}.ts`;
9871
- const pluginsDir = join3(process.cwd(), "src", "plugins");
9872
- const targetPath = join3(pluginsDir, fileName);
10160
+ const pluginsDir = join4(process.cwd(), "src", "plugins");
10161
+ const targetPath = join4(pluginsDir, fileName);
9873
10162
  try {
9874
- await fs3.mkdir(pluginsDir, { recursive: true });
9875
- const fileExists = await fs3.stat(targetPath).then(() => true).catch(() => false);
10163
+ await fs4.mkdir(pluginsDir, { recursive: true });
10164
+ const fileExists = await fs4.stat(targetPath).then(() => true).catch(() => false);
9876
10165
  if (fileExists) {
9877
10166
  console.error(source_default.red(`
9878
10167
  Error: File already exists at ${targetPath}`));
9879
10168
  process.exit(1);
9880
10169
  }
9881
10170
  const sourceCode = generatePluginSource(className, className);
9882
- await fs3.writeFile(targetPath, sourceCode, "utf8");
10171
+ await fs4.writeFile(targetPath, sourceCode, "utf8");
9883
10172
  console.log(`
9884
- ${source_default.green("")} Created plugin ${source_default.cyan(className)} at ${source_default.dim(targetPath)}
10173
+ ${source_default.green("\u2713")} Created plugin ${source_default.cyan(className)} at ${source_default.dim(targetPath)}
9885
10174
  `);
9886
10175
  if (verbose) {
9887
10176
  console.log(source_default.dim(sourceCode));
@@ -9894,6 +10183,132 @@ Error creating plugin: ${message}`));
9894
10183
  }
9895
10184
  }
9896
10185
 
10186
+ // src/cli/host.ts
10187
+ import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
10188
+ import { join as join5, resolve as resolve2 } from "path";
10189
+ import { networkInterfaces } from "os";
10190
+ function getNetworkAddress() {
10191
+ const interfaces = networkInterfaces();
10192
+ for (const name of Object.keys(interfaces)) {
10193
+ const netList = interfaces[name];
10194
+ if (!netList)
10195
+ continue;
10196
+ for (const net of netList) {
10197
+ if (net.family === "IPv4" && !net.internal) {
10198
+ return net.address;
10199
+ }
10200
+ }
10201
+ }
10202
+ return "localhost";
10203
+ }
10204
+ async function processHost(pOptions = {}) {
10205
+ const cwd = process.cwd();
10206
+ const defaultPort = 8090;
10207
+ const port = pOptions.port || defaultPort;
10208
+ const distDir = pOptions.directory ? resolve2(pOptions.directory) : join5(cwd, "dist");
10209
+ const architecture = detectArchitecture(join5(cwd, "src"));
10210
+ if (!existsSync4(distDir)) {
10211
+ const message = `Target directory "${distDir}" does not exist. Run "kit build" or use "kit host -b" first.`;
10212
+ console.error(source_default.red(`
10213
+ [Kit Host] ${message}
10214
+ `));
10215
+ return { success: false, message };
10216
+ }
10217
+ if (architecture === "multi") {
10218
+ const serverJsPath = join5(distDir, "server.js");
10219
+ if (!existsSync4(serverJsPath)) {
10220
+ const message = `Cannot host multiplayer project: "${serverJsPath}" was not found. Please compile the server first using "kit build".`;
10221
+ console.error(source_default.red(`
10222
+ [Kit Host] ${message}
10223
+ `));
10224
+ return { success: false, message };
10225
+ }
10226
+ console.log(source_default.cyan(`
10227
+ Starting Multiplayer Server from ${source_default.bold(distDir)}...
10228
+ `));
10229
+ let serverSettingsPort = port;
10230
+ const settingsPath = join5(distDir, "settings.json");
10231
+ if (existsSync4(settingsPath)) {
10232
+ try {
10233
+ const settings = JSON.parse(readFileSync2(settingsPath, "utf8"));
10234
+ if (settings.port)
10235
+ serverSettingsPort = Number(settings.port);
10236
+ } catch {
10237
+ }
10238
+ }
10239
+ const proc = Bun.spawn(["node", "server.js"], {
10240
+ cwd: distDir,
10241
+ stdout: "inherit",
10242
+ stderr: "inherit",
10243
+ stdin: "inherit"
10244
+ });
10245
+ console.log(source_default.green(`\u2713 Multiplayer server process spawned (configured port: ${serverSettingsPort})`));
10246
+ process.on("SIGINT", () => {
10247
+ proc.kill();
10248
+ process.exit(0);
10249
+ });
10250
+ process.on("SIGTERM", () => {
10251
+ proc.kill();
10252
+ process.exit(0);
10253
+ });
10254
+ await proc.exited;
10255
+ return { success: true, message: "Multiplayer server finished running." };
10256
+ }
10257
+ const indexPath = join5(distDir, "index.html");
10258
+ if (!existsSync4(indexPath)) {
10259
+ const message = `Missing entrypoint: "${indexPath}" was not found in dist. Run "kit build" or use "kit host -b" to compile.`;
10260
+ console.error(source_default.red(`
10261
+ [Kit Host] ${message}
10262
+ `));
10263
+ return { success: false, message };
10264
+ }
10265
+ const lanIp = getNetworkAddress();
10266
+ const server = Bun.serve({
10267
+ port,
10268
+ async fetch(pReq) {
10269
+ const path2 = new URL(pReq.url).pathname;
10270
+ const target = path2 === "/" ? "/index.html" : decodeURIComponent(path2);
10271
+ const file = Bun.file(join5(distDir, target));
10272
+ if (!await file.exists()) {
10273
+ if (pOptions.verbose) {
10274
+ console.warn(source_default.yellow(`[Kit Host] 404 Not Found: ${target}`));
10275
+ }
10276
+ return new Response("Not Found", { status: 404 });
10277
+ }
10278
+ return new Response(file);
10279
+ }
10280
+ });
10281
+ console.log(source_default.cyan(`
10282
+ Kit Game Host Server
10283
+ `));
10284
+ console.log(` ${source_default.bold("Local:")} ${source_default.green(`http://localhost:${server.port}`)}`);
10285
+ if (lanIp !== "localhost") {
10286
+ console.log(` ${source_default.bold("Network:")} ${source_default.green(`http://${lanIp}:${server.port}`)}`);
10287
+ }
10288
+ console.log(source_default.dim(`
10289
+ Serving files from: ${distDir}`));
10290
+ console.log(source_default.dim(`Press Ctrl+C to stop the server
10291
+ `));
10292
+ process.on("SIGINT", () => {
10293
+ console.log(source_default.yellow(`
10294
+ Shutting down host server...`));
10295
+ server.stop();
10296
+ process.exit(0);
10297
+ });
10298
+ process.on("SIGTERM", () => {
10299
+ server.stop();
10300
+ process.exit(0);
10301
+ });
10302
+ return {
10303
+ success: true,
10304
+ message: `Serving files on port ${server.port}`,
10305
+ server: {
10306
+ stop: () => server.stop(),
10307
+ port: server.port
10308
+ }
10309
+ };
10310
+ }
10311
+
9897
10312
  // src/cli/main.ts
9898
10313
  class KitCLI {
9899
10314
  static async processResources(pProcessOptions) {
@@ -9908,6 +10323,9 @@ class KitCLI {
9908
10323
  static async create(pCreateOptions) {
9909
10324
  await processCreate(pCreateOptions);
9910
10325
  }
10326
+ static async host(pHostOptions = {}) {
10327
+ return await processHost(pHostOptions);
10328
+ }
9911
10329
  }
9912
10330
 
9913
10331
  // bin/cli.ts
@@ -9991,6 +10409,12 @@ var formatHelp = (pCmd) => {
9991
10409
  }
9992
10410
  if (isRoot || name === "doctor") {
9993
10411
  output += ` ${source_default.cyan("kit doctor")}
10412
+ `;
10413
+ }
10414
+ if (isRoot || name === "host") {
10415
+ output += ` ${source_default.cyan("kit host")}
10416
+ `;
10417
+ output += ` ${source_default.cyan("kit host -p 8080 -b")}
9994
10418
  `;
9995
10419
  }
9996
10420
  if (isRoot) {
@@ -10023,24 +10447,23 @@ var initCommand = program2.command("init [name]").description("Initialize a new
10023
10447
  });
10024
10448
  });
10025
10449
  initCommand.helpInformation = () => formatHelp(initCommand);
10026
- var buildCommand = program2.command("build [help]").description("Build resources from the specified directory").option("-i, --in <path>", "Input directory (required)").option("-o, --out <path>", "Output directory (required)").option("-m, --manifest <path>", "Custom manifest file path").option("-w, --watch", "Watch input directory for changes and rebuild", false).option("-is, --ignore-sound", "Ignore sound files", false).action((pHelp, pCmdOptions) => {
10450
+ var buildCommand = program2.command("build [help]").description("Build resources and bundle game application").option("-i, --in <path>", "Input directory (defaults to ./src/resources)").option("-o, --out <path>", "Output directory (defaults to ./dist)").option("-m, --manifest <path>", "Custom manifest file path").option("-w, --watch", "Watch files for changes and rebuild automatically", false).option("-is, --ignore-sound", "Ignore sound files", false).option("--app", "Bundle game code and static assets (enabled by default when project entrypoints exist)").option("--no-app", "Disable game code bundling and only process resources").option("-p, --prod", "Production build: enables minification, identifier obfuscation, and strips sourcemaps", false).option("--minify", "Minify bundled JavaScript syntax, whitespace, and identifiers", false).option("--obfuscate", "Mangle and obfuscate variable and property identifiers", false).option("--sourcemap <mode>", "Sourcemap generation mode (none, linked, inline, external)").action((pHelp, pCmdOptions) => {
10027
10451
  if (pHelp === "help") {
10028
10452
  console.log(buildCommand.helpInformation());
10029
10453
  return;
10030
10454
  }
10031
10455
  const verbose = program2.opts().verbose;
10032
- if (!pCmdOptions.in || !pCmdOptions.out) {
10033
- console.error(source_default.red(`
10034
- Error: --in and --out are required flags for the build command.`));
10035
- console.log(buildCommand.helpInformation());
10036
- process.exit(1);
10037
- }
10038
10456
  const processOptions = {
10039
10457
  inDirectory: pCmdOptions.in,
10040
10458
  outDirectory: pCmdOptions.out,
10041
10459
  manifestPath: pCmdOptions.manifest,
10042
10460
  watch: pCmdOptions.watch || false,
10043
10461
  ignoreSound: pCmdOptions.ignoreSound || false,
10462
+ app: pCmdOptions.app,
10463
+ minify: pCmdOptions.minify || false,
10464
+ obfuscate: pCmdOptions.obfuscate || false,
10465
+ sourcemap: pCmdOptions.sourcemap,
10466
+ prod: pCmdOptions.prod || false,
10044
10467
  verbose: verbose || false
10045
10468
  };
10046
10469
  KitCLI.processResources(processOptions);
@@ -10067,6 +10490,21 @@ var doctorCommand = program2.command("doctor").description("Inspect environment
10067
10490
  }
10068
10491
  });
10069
10492
  doctorCommand.helpInformation = () => formatHelp(doctorCommand);
10493
+ var hostCommand = program2.command("host").description("Host the game application locally").option("-p, --port <number>", "Port to run host server on (default: 8090)", "8090").option("-d, --dir <path>", "Directory to serve (default: ./dist)").option("-b, --build", "Build the project before hosting", false).action(async (pCmdOptions) => {
10494
+ const verbose = program2.opts().verbose;
10495
+ if (pCmdOptions.build) {
10496
+ await KitCLI.processResources({ verbose });
10497
+ }
10498
+ const result = await KitCLI.host({
10499
+ port: Number(pCmdOptions.port) || 8090,
10500
+ directory: pCmdOptions.dir,
10501
+ verbose
10502
+ });
10503
+ if (!result.success) {
10504
+ process.exitCode = 1;
10505
+ }
10506
+ });
10507
+ hostCommand.helpInformation = () => formatHelp(hostCommand);
10070
10508
  program2.command("help [command]").description("Display help for a command").action((pCommandName) => {
10071
10509
  if (pCommandName) {
10072
10510
  const cmd = program2.commands.find((c) => c.name() === pCommandName);
@@ -1 +1 @@
1
- {"version":3,"file":"app-bundler.d.ts","sourceRoot":"","sources":["../../src/cli/app-bundler.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC5B,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAYvE;AAsDD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6KhI"}
1
+ {"version":3,"file":"app-bundler.d.ts","sourceRoot":"","sources":["../../src/cli/app-bundler.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC5B,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAYvE;AA+DD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6KhI"}
@@ -65,6 +65,14 @@ async function copyStaticWebFiles(pSourceDir, pDestDir, pBaseDir) {
65
65
  const targetPath = join(pDestDir, relativePath);
66
66
  await fs.mkdir(dirname(targetPath), { recursive: true });
67
67
  await fs.copyFile(fullPath, targetPath);
68
+ // If the asset is located in a nested directory, also provide a copy at destination root
69
+ // to support projects where root HTML references sub-folder styles directly
70
+ if (['.css', '.ico'].includes(ext)) {
71
+ const rootTargetPath = join(pDestDir, entry.name);
72
+ if (targetPath !== rootTargetPath && !existsSync(rootTargetPath)) {
73
+ await fs.copyFile(fullPath, rootTargetPath);
74
+ }
75
+ }
68
76
  }
69
77
  }
70
78
  }
package/lib/cli/host.js CHANGED
@@ -46,7 +46,7 @@ export async function processHost(pOptions = {}) {
46
46
  console.error(chalk.red(`\n[Kit Host] ${message}\n`));
47
47
  return { success: false, message };
48
48
  }
49
- console.log(chalk.cyan(`\n🎮 Starting Multiplayer Server from ${chalk.bold(distDir)}...\n`));
49
+ console.log(chalk.cyan(`\nStarting Multiplayer Server from ${chalk.bold(distDir)}...\n`));
50
50
  let serverSettingsPort = port;
51
51
  const settingsPath = join(distDir, 'settings.json');
52
52
  if (existsSync(settingsPath)) {
@@ -100,7 +100,7 @@ export async function processHost(pOptions = {}) {
100
100
  return new Response(file);
101
101
  }
102
102
  });
103
- console.log(chalk.cyan('\n🎮 Kit Game Host Server\n'));
103
+ console.log(chalk.cyan('\nKit Game Host Server\n'));
104
104
  console.log(` ${chalk.bold('Local:')} ${chalk.green(`http://localhost:${server.port}`)}`);
105
105
  if (lanIp !== 'localhost') {
106
106
  console.log(` ${chalk.bold('Network:')} ${chalk.green(`http://${lanIp}:${server.port}`)}`);
@@ -1 +1 @@
1
- {"version":3,"file":"resource-builder.d.ts","sourceRoot":"","sources":["../../src/cli/resource-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAggB9C;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCvL"}
1
+ {"version":3,"file":"resource-builder.d.ts","sourceRoot":"","sources":["../../src/cli/resource-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA+gB9C;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCvL"}
@@ -100,9 +100,22 @@ async function processDirectory(pDirectoryPath) {
100
100
  function isValidExtension(pExtension) {
101
101
  return VALID_EXTENSIONS.includes(pExtension);
102
102
  }
103
+ // Engine resource formats handled by Vylocity obfuscation
104
+ const ENGINE_EXTENSIONS = ['vyint', 'vyi', 'vym', 'vymac'];
105
+ /**
106
+ * Checks if a file extension is a Vylocity engine binary/definition format.
107
+ * @param pExtension - The file extension to test.
108
+ * @returns True if the extension is an engine format.
109
+ */
110
+ function isEngineExtension(pExtension) {
111
+ return ENGINE_EXTENSIONS.includes(pExtension);
112
+ }
103
113
  /**
104
114
  * Recursively copies a directory to destination, preserving subdirectories and files.
105
- * Ignores engine resource files that are already handled by Vylocity obfuscation.
115
+ * Ignores engine resource files (vyint, vyi, vym, vymac) that are handled by Vylocity obfuscation,
116
+ * while ensuring media and custom assets (sounds, images, fonts, json) retain their structure.
117
+ * @param pSourceDir - The source directory to copy.
118
+ * @param pDestDir - The target destination directory.
106
119
  */
107
120
  async function mirrorDirectory(pSourceDir, pDestDir) {
108
121
  const entries = await fs.readdir(pSourceDir, { withFileTypes: true });
@@ -115,8 +128,8 @@ async function mirrorDirectory(pSourceDir, pDestDir) {
115
128
  }
116
129
  else {
117
130
  const ext = extname(entry.name).slice(1);
118
- // Only copy non-engine files (images, custom JSON, fonts, etc.)
119
- if (!isValidExtension(ext)) {
131
+ // Copy all assets except internal Vylocity engine binary formats
132
+ if (!isEngineExtension(ext)) {
120
133
  await fs.copyFile(srcPath, destPath);
121
134
  }
122
135
  }
@@ -417,7 +430,7 @@ async function runBuild() {
417
430
  */
418
431
  async function runWatch() {
419
432
  await runBuild();
420
- console.log(chalk.cyan(`\n👀 Watching for changes in: ${chalk.bold(resourceInDirectory)}`));
433
+ console.log(chalk.cyan(`\nWatching for changes in: ${chalk.bold(resourceInDirectory)}`));
421
434
  let debounceTimer = null;
422
435
  const triggerRebuild = (pFilename) => {
423
436
  if (debounceTimer)
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ const { spawnSync } = require('child_process');
3
+ const path = require('path');
4
+
5
+ // Target the compiled Bun bundle
6
+ const cliScript = path.join(__dirname, 'bundle', 'cli', 'cli.js');
7
+
8
+ // If currently running under Bun, import and execute directly
9
+ if (typeof Bun !== 'undefined') {
10
+ import(cliScript);
11
+ } else {
12
+ // Running under Node.js -> delegate to Bun runtime
13
+ const result = spawnSync('bun', [cliScript, ...process.argv.slice(2)], {
14
+ stdio: 'inherit',
15
+ shell: process.platform === 'win32'
16
+ });
17
+ process.exit(result.status ?? 0);
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evitcastudio/kit",
3
- "version": "3.2.0",
3
+ "version": "3.2.2",
4
4
  "author": "doubleactii 56242467+doubleactii@users.noreply.github.com (https://evitcastudio.com)",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -43,7 +43,7 @@
43
43
  "build-all": "bun run build-types && bun run build && bun run build-docs"
44
44
  },
45
45
  "bin": {
46
- "kit": "lib/bundle/cli/cli.js"
46
+ "kit": "lib/cli-runner.cjs"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@eslint/create-config": "1.4.0",