@rodyssey/cli 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +308 -40
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createRequire } from "node:module";
2
+ // @bun
3
3
  var __create = Object.create;
4
4
  var __getProtoOf = Object.getPrototypeOf;
5
5
  var __defProp = Object.defineProperty;
@@ -17,7 +17,7 @@ var __toESM = (mod, isNodeMode, target) => {
17
17
  return to;
18
18
  };
19
19
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
20
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
+ var __require = import.meta.require;
21
21
 
22
22
  // node_modules/commander/lib/error.js
23
23
  var require_error = __commonJS((exports) => {
@@ -725,11 +725,11 @@ var require_suggestSimilar = __commonJS((exports) => {
725
725
 
726
726
  // node_modules/commander/lib/command.js
727
727
  var require_command = __commonJS((exports) => {
728
- var EventEmitter = __require("node:events").EventEmitter;
729
- var childProcess = __require("node:child_process");
730
- var path = __require("node:path");
731
- var fs = __require("node:fs");
732
- var process2 = __require("node:process");
728
+ var EventEmitter = __require("events").EventEmitter;
729
+ var childProcess = __require("child_process");
730
+ var path = __require("path");
731
+ var fs = __require("fs");
732
+ var process2 = __require("process");
733
733
  var { Argument, humanReadableArgName } = require_argument();
734
734
  var { CommanderError } = require_error();
735
735
  var { Help, stripColor } = require_help();
@@ -2070,13 +2070,13 @@ var {
2070
2070
  } = import__.default;
2071
2071
 
2072
2072
  // src/create.ts
2073
- import { execSync } from "node:child_process";
2074
- import { existsSync, rmSync } from "node:fs";
2075
- import path2 from "node:path";
2073
+ import { execSync } from "child_process";
2074
+ import { existsSync, rmSync } from "fs";
2075
+ import path2 from "path";
2076
2076
 
2077
2077
  // src/utils.ts
2078
- import { readFileSync, writeFileSync } from "node:fs";
2079
- import path from "node:path";
2078
+ import { readFileSync, writeFileSync } from "fs";
2079
+ import path from "path";
2080
2080
  function replaceInFile(filePath, search, replace) {
2081
2081
  const content = readFileSync(filePath, "utf-8");
2082
2082
  const updated = content.replaceAll(search, replace);
@@ -2104,12 +2104,12 @@ async function create(projectName, repoUrl, templateName) {
2104
2104
  const targetDir = path2.resolve(process.cwd(), projectName);
2105
2105
  if (existsSync(targetDir)) {
2106
2106
  console.error(`
2107
- Directory "${projectName}" already exists.
2107
+ \u2716 Directory "${projectName}" already exists.
2108
2108
  `);
2109
2109
  process.exit(1);
2110
2110
  }
2111
2111
  console.log(`
2112
- Cloning template "${templateName}"...
2112
+ \u23F3 Cloning template "${templateName}"...
2113
2113
  `);
2114
2114
  try {
2115
2115
  execSync(`git clone --depth 1 ${repoUrl} ${projectName}`, {
@@ -2118,7 +2118,7 @@ async function create(projectName, repoUrl, templateName) {
2118
2118
  });
2119
2119
  } catch {
2120
2120
  console.error(`
2121
- Failed to clone template. Make sure you have SSH access to the repo.
2121
+ \u2716 Failed to clone template. Make sure you have SSH access to the repo.
2122
2122
  `);
2123
2123
  process.exit(1);
2124
2124
  }
@@ -2134,7 +2134,7 @@ async function create(projectName, repoUrl, templateName) {
2134
2134
  }
2135
2135
  execSync("git init", { stdio: "ignore", cwd: targetDir });
2136
2136
  console.log(`
2137
- Project "${projectName}" created successfully!
2137
+ \u2705 Project "${projectName}" created successfully!
2138
2138
 
2139
2139
  Next steps:
2140
2140
 
@@ -2144,9 +2144,271 @@ async function create(projectName, repoUrl, templateName) {
2144
2144
  `);
2145
2145
  }
2146
2146
 
2147
+ // src/deploy.ts
2148
+ var {$ } = globalThis.Bun;
2149
+ var {file } = globalThis.Bun;
2150
+ import { existsSync as existsSync2, readdirSync, statSync } from "fs";
2151
+ import { join } from "path";
2152
+ var DEVELOPMENT_URL = "https://development-cms.rodyssey.ai/api/webapps/deploy";
2153
+ var STAGING_URL = "https://staging-cms.rodyssey.ai/api/webapps/deploy";
2154
+ var PRODUCTION_URL = "https://cms.rodyssey.ai/api/webapps/deploy";
2155
+ var DEPLOY_URLS = {
2156
+ development: DEVELOPMENT_URL,
2157
+ staging: STAGING_URL,
2158
+ production: PRODUCTION_URL
2159
+ };
2160
+ var BUILD_DIR = "dist";
2161
+ var ZIP_FILE = "webapp-build.zip";
2162
+ var MAX_FILES_PER_BATCH = 5;
2163
+ var MAX_SIZE_PER_BATCH = 30 * 1024 * 1024;
2164
+ function getAllFiles(dirPath, arrayOfFiles = []) {
2165
+ if (!existsSync2(dirPath))
2166
+ return arrayOfFiles;
2167
+ const files = readdirSync(dirPath);
2168
+ files.forEach(function(f) {
2169
+ const fullPath = join(dirPath, f);
2170
+ if (statSync(fullPath).isDirectory()) {
2171
+ arrayOfFiles = getAllFiles(fullPath, arrayOfFiles);
2172
+ } else {
2173
+ arrayOfFiles.push(fullPath);
2174
+ }
2175
+ });
2176
+ return arrayOfFiles;
2177
+ }
2178
+ async function deploy(env = "development") {
2179
+ const DEPLOY_URL = DEPLOY_URLS[env];
2180
+ if (!DEPLOY_URL) {
2181
+ console.error(`\u274C Unknown environment "${env}". Available: ${Object.keys(DEPLOY_URLS).join(", ")}`);
2182
+ process.exit(1);
2183
+ }
2184
+ const ASSETS_URL = DEPLOY_URL.replace("/webapps/deploy", "/webapps/assets");
2185
+ console.log(`\uD83D\uDE80 Starting deployment process for [${env}] environment...
2186
+ `);
2187
+ console.log(`\uD83D\uDCCD Deploy URL: ${DEPLOY_URL}`);
2188
+ console.log(`\uD83D\uDCCD Assets URL: ${ASSETS_URL}
2189
+ `);
2190
+ if (!process.env.DEPLOY_TOKEN) {
2191
+ console.error("\u274C Error: DEPLOY_TOKEN is not set in environment variables.");
2192
+ console.info(`\uD83D\uDCA1 Please check your .env or .env.${env} file.`);
2193
+ process.exit(1);
2194
+ }
2195
+ console.log("\uD83D\uDCE6 Step 1: Building the webapp...");
2196
+ await $`bun run build`;
2197
+ console.log(`\u2705 Build completed
2198
+ `);
2199
+ const allFiles = getAllFiles(BUILD_DIR);
2200
+ const htmlFiles = allFiles.filter((f) => f.endsWith(".html"));
2201
+ const scriptFiles = allFiles.filter((f) => f.includes("/api/") || f.includes("/cron-jobs/") || f.endsWith("cron.config.json"));
2202
+ const heavyFiles = allFiles.filter((f) => !f.endsWith(".html") && !scriptFiles.includes(f));
2203
+ console.log(`\uD83D\uDCE4 Step 2: Uploading ${heavyFiles.length} heavy assets...`);
2204
+ if (heavyFiles.length > 0) {
2205
+ const batches = [];
2206
+ let currentBatch = [];
2207
+ let currentBatchSize = 0;
2208
+ for (const filePath of heavyFiles) {
2209
+ const size = statSync(filePath).size;
2210
+ if (currentBatch.length >= MAX_FILES_PER_BATCH || currentBatchSize + size > MAX_SIZE_PER_BATCH) {
2211
+ if (currentBatch.length > 0)
2212
+ batches.push(currentBatch);
2213
+ currentBatch = [];
2214
+ currentBatchSize = 0;
2215
+ }
2216
+ currentBatch.push(filePath);
2217
+ currentBatchSize += size;
2218
+ }
2219
+ if (currentBatch.length > 0)
2220
+ batches.push(currentBatch);
2221
+ console.log(`Divided into ${batches.length} batches.`);
2222
+ let batchIndex = 0;
2223
+ const uploadPromises = batches.map(async (batch) => {
2224
+ const formData = new FormData;
2225
+ for (const filePath of batch) {
2226
+ const relativePath = filePath.substring(BUILD_DIR.length + 1).replace(/\\/g, "/");
2227
+ formData.append(relativePath, file(filePath));
2228
+ }
2229
+ const response = await fetch(ASSETS_URL, {
2230
+ method: "POST",
2231
+ headers: {
2232
+ Authorization: `Bearer ${process.env.DEPLOY_TOKEN}`
2233
+ },
2234
+ body: formData
2235
+ });
2236
+ if (!response.ok) {
2237
+ const errorText = await response.text();
2238
+ throw new Error(`Asset upload failed: ${response.status} ${response.statusText}
2239
+ ${errorText}`);
2240
+ }
2241
+ batchIndex++;
2242
+ console.log(`\u2705 Batch ${batchIndex}/${batches.length} uploaded successfully`);
2243
+ });
2244
+ await Promise.all(uploadPromises);
2245
+ } else {
2246
+ console.log("\u2705 No heavy assets to upload");
2247
+ }
2248
+ console.log();
2249
+ if (scriptFiles.length > 0) {
2250
+ console.log(`\uD83D\uDCDC Step 3: Setting up ${scriptFiles.length} scripts (APIs & Crons)...`);
2251
+ const scriptsPayload = { api: {}, cron: {}, cronConfig: null };
2252
+ for (const f of scriptFiles) {
2253
+ const content = await Bun.file(f).text();
2254
+ const relativePath = f.substring(BUILD_DIR.length + 1).replace(/\\/g, "/");
2255
+ if (relativePath === "cron-jobs/cron.config.json") {
2256
+ scriptsPayload.cronConfig = JSON.parse(content);
2257
+ } else if (relativePath.startsWith("api/")) {
2258
+ const endpoint = relativePath.substring(4, relativePath.lastIndexOf(".js"));
2259
+ scriptsPayload.api[endpoint] = content;
2260
+ } else if (relativePath.startsWith("cron-jobs/")) {
2261
+ const scriptName = relativePath.substring(10);
2262
+ scriptsPayload.cron[scriptName] = content;
2263
+ }
2264
+ }
2265
+ const scriptsUrl = DEPLOY_URL.replace("/webapps/deploy", "/webapps/scripts-setup");
2266
+ const response = await fetch(scriptsUrl, {
2267
+ method: "POST",
2268
+ headers: {
2269
+ Authorization: `Bearer ${process.env.DEPLOY_TOKEN}`,
2270
+ "Content-Type": "application/json"
2271
+ },
2272
+ body: JSON.stringify(scriptsPayload)
2273
+ });
2274
+ if (!response.ok) {
2275
+ const errorText = await response.text();
2276
+ throw new Error(`Scripts setup failed: ${response.status} ${response.statusText}
2277
+ ${errorText}`);
2278
+ }
2279
+ console.log(`\u2705 Scripts synced successfully`);
2280
+ } else {
2281
+ console.log(`\uD83D\uDCDC Step 3: No scripts found to sync.`);
2282
+ }
2283
+ console.log();
2284
+ console.log(`\uD83D\uDDDC\uFE0F Step 4: Zipping ${htmlFiles.length} HTML files...`);
2285
+ if (htmlFiles.length === 0) {
2286
+ console.warn("\u26A0\uFE0F No HTML files found to zip! Deployment might fail if CMS expects an HTML file.");
2287
+ }
2288
+ const relativeHtmlFiles = htmlFiles.map((f) => f.substring(BUILD_DIR.length + 1).replace(/\\/g, "/"));
2289
+ await $`cd ${BUILD_DIR} && zip ../${ZIP_FILE} ${relativeHtmlFiles}`;
2290
+ console.log(`\u2705 Created ${ZIP_FILE}
2291
+ `);
2292
+ console.log("\u2601\uFE0F Step 5: Deploying HTML zip to server...");
2293
+ const zipFile = file(ZIP_FILE);
2294
+ try {
2295
+ const response = await fetch(DEPLOY_URL, {
2296
+ method: "POST",
2297
+ headers: {
2298
+ Authorization: `Bearer ${process.env.DEPLOY_TOKEN}`,
2299
+ "Content-Type": "application/zip"
2300
+ },
2301
+ body: zipFile
2302
+ });
2303
+ if (!response.ok) {
2304
+ const errorText = await response.text();
2305
+ throw new Error(`Deploy failed: ${response.status} ${response.statusText}
2306
+ ${errorText}`);
2307
+ }
2308
+ const result = await response.json();
2309
+ console.log("\u2705 Deploy completed");
2310
+ console.log(`
2311
+ \uD83D\uDCCB Deployment result:`, result);
2312
+ } catch (error) {
2313
+ console.error("\u274C Deploy failed:", error);
2314
+ throw error;
2315
+ } finally {
2316
+ if (existsSync2(ZIP_FILE)) {
2317
+ await $`rm ${ZIP_FILE}`;
2318
+ console.log(`
2319
+ \uD83E\uDDF9 Cleaned up ${ZIP_FILE}`);
2320
+ }
2321
+ }
2322
+ console.log(`
2323
+ \u2728 Deployment successful!`);
2324
+ }
2325
+
2326
+ // src/upgrade-agent.ts
2327
+ import { execSync as execSync2 } from "child_process";
2328
+ import { existsSync as existsSync3 } from "fs";
2329
+ var TEMPLATES = {
2330
+ webapp: {
2331
+ name: "webapp (SPA)",
2332
+ repo: "https://github.com/airconcepts/webapp-template.git",
2333
+ remoteName: "template",
2334
+ checkoutFiles: ["AGENTS.md", ".agent/", "src/types/webapp.d.ts", "src/types/game-sdk.d.ts"],
2335
+ newFiles: [
2336
+ "src/exp-engine/cli.ts",
2337
+ "src/exp-engine/evaluate.ts",
2338
+ "src/exp-engine/README.md",
2339
+ "src/types/exp-engine.d.ts"
2340
+ ]
2341
+ },
2342
+ "webapp-fullstack": {
2343
+ name: "webapp (Fullstack)",
2344
+ repo: "https://github.com/airconcepts/webapp-template-fullstack.git",
2345
+ remoteName: "template",
2346
+ checkoutFiles: ["AGENTS.md", ".agent/", "app/types/webapp.d.ts", "app/types/game-sdk.d.ts"],
2347
+ newFiles: [
2348
+ "app/exp-engine/cli.ts",
2349
+ "app/exp-engine/evaluate.ts",
2350
+ "app/exp-engine/README.md",
2351
+ "app/types/exp-engine.d.ts"
2352
+ ]
2353
+ }
2354
+ };
2355
+ function detectTemplate() {
2356
+ if (existsSync3("app")) {
2357
+ console.log(`\uD83D\uDD0D Detected fullstack template (found app/ directory)
2358
+ `);
2359
+ return TEMPLATES["webapp-fullstack"];
2360
+ }
2361
+ if (existsSync3("src")) {
2362
+ console.log(`\uD83D\uDD0D Detected SPA template (found src/ directory)
2363
+ `);
2364
+ return TEMPLATES["webapp"];
2365
+ }
2366
+ console.log(`\u26A0\uFE0F Could not detect template type, defaulting to SPA
2367
+ `);
2368
+ return TEMPLATES["webapp"];
2369
+ }
2370
+ async function upgradeAgent() {
2371
+ const template = detectTemplate();
2372
+ try {
2373
+ console.log(`\uD83D\uDD04 Starting Agent Upgrade for ${template.name}...`);
2374
+ let remoteExists = false;
2375
+ try {
2376
+ execSync2(`git remote get-url ${template.remoteName}`, { stdio: "ignore" });
2377
+ remoteExists = true;
2378
+ } catch {}
2379
+ if (!remoteExists) {
2380
+ console.log(`\u2795 Adding remote '${template.remoteName}'...`);
2381
+ execSync2(`git remote add ${template.remoteName} ${template.repo}`, { stdio: "inherit" });
2382
+ } else {
2383
+ console.log(`\u2139\uFE0F Remote '${template.remoteName}' already exists.`);
2384
+ }
2385
+ console.log("\u2B07\uFE0F Fetching latest changes from template...");
2386
+ execSync2(`git fetch ${template.remoteName}`, { stdio: "inherit" });
2387
+ console.log("\uD83D\uDCC2 Updating agent files...");
2388
+ const checkoutList = template.checkoutFiles.join(" ");
2389
+ execSync2(`git checkout ${template.remoteName}/main -- ${checkoutList}`, { stdio: "inherit" });
2390
+ for (const file2 of template.newFiles) {
2391
+ if (!existsSync3(file2)) {
2392
+ console.log(`\uD83D\uDCC2 Checking out ${file2}...`);
2393
+ try {
2394
+ execSync2(`git checkout ${template.remoteName}/main -- ${file2}`, { stdio: "inherit" });
2395
+ } catch {
2396
+ console.log(`\u26A0\uFE0F Failed to checkout ${file2}`);
2397
+ }
2398
+ } else {
2399
+ console.log(`\u23ED\uFE0F Skipping ${file2} (already exists)`);
2400
+ }
2401
+ }
2402
+ console.log("\u2705 Agent upgrade complete! Please check git status for changes.");
2403
+ } catch (error) {
2404
+ console.error("\u274C Upgrade failed:", error);
2405
+ process.exit(1);
2406
+ }
2407
+ }
2408
+
2147
2409
  // src/update-game-sdk.ts
2148
- import { mkdir, writeFile } from "node:fs/promises";
2149
- import { dirname, join } from "node:path";
2410
+ import { mkdir, writeFile } from "fs/promises";
2411
+ import { dirname, join as join2 } from "path";
2150
2412
  var BASE_URL = "https://development-app.rodyssey.ai";
2151
2413
  var FILES = [
2152
2414
  {
@@ -2179,11 +2441,11 @@ async function downloadFile(url, path3, description) {
2179
2441
  const dir = dirname(path3);
2180
2442
  await mkdir(dir, { recursive: true });
2181
2443
  await writeFile(path3, content, "utf-8");
2182
- console.log(`✅ Downloaded ${description} (${content.length} bytes)
2444
+ console.log(`\u2705 Downloaded ${description} (${content.length} bytes)
2183
2445
  `);
2184
2446
  return true;
2185
2447
  } catch (error) {
2186
- console.error(`❌ Failed to download ${description}:`);
2448
+ console.error(`\u274C Failed to download ${description}:`);
2187
2449
  console.error(` ${error instanceof Error ? error.message : String(error)}
2188
2450
  `);
2189
2451
  return false;
@@ -2200,14 +2462,14 @@ async function downloadManifest() {
2200
2462
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
2201
2463
  }
2202
2464
  const manifest = await response.json();
2203
- console.log(`✅ Manifest downloaded successfully`);
2465
+ console.log(`\u2705 Manifest downloaded successfully`);
2204
2466
  console.log(` Name: ${manifest.name}`);
2205
2467
  console.log(` Version: ${manifest.version}`);
2206
2468
  console.log(` Documentation files: ${manifest.documentation.length}
2207
2469
  `);
2208
2470
  return manifest;
2209
2471
  } catch (error) {
2210
- console.error(" Failed to download manifest:");
2472
+ console.error("\u274C Failed to download manifest:");
2211
2473
  console.error(` ${error instanceof Error ? error.message : String(error)}
2212
2474
  `);
2213
2475
  return null;
@@ -2220,7 +2482,7 @@ async function downloadDocumentation(manifest) {
2220
2482
  let failCount = 0;
2221
2483
  for (const doc of manifest.documentation) {
2222
2484
  const url = `${BASE_URL}/skills/${doc.file}`;
2223
- const path3 = join(".agent", "skills", "game-sdk", doc.file);
2485
+ const path3 = join2(".agent", "skills", "game-sdk", doc.file);
2224
2486
  const description = `${doc.title} (${doc.category})`;
2225
2487
  const success = await downloadFile(url, path3, description);
2226
2488
  if (success) {
@@ -2231,9 +2493,9 @@ async function downloadDocumentation(manifest) {
2231
2493
  }
2232
2494
  console.log(`
2233
2495
  \uD83D\uDCCA Documentation download summary:`);
2234
- console.log(` Success: ${successCount}`);
2496
+ console.log(` \u2705 Success: ${successCount}`);
2235
2497
  if (failCount > 0) {
2236
- console.log(` Failed: ${failCount}`);
2498
+ console.log(` \u274C Failed: ${failCount}`);
2237
2499
  }
2238
2500
  console.log();
2239
2501
  return { successCount, failCount };
@@ -2246,8 +2508,8 @@ async function updateGameSdk() {
2246
2508
  let totalFail = 0;
2247
2509
  console.log(`\uD83D\uDCE6 Downloading core SDK files...
2248
2510
  `);
2249
- for (const file of FILES) {
2250
- const success = await downloadFile(file.url, file.path, file.description);
2511
+ for (const file2 of FILES) {
2512
+ const success = await downloadFile(file2.url, file2.path, file2.description);
2251
2513
  if (success) {
2252
2514
  totalSuccess++;
2253
2515
  } else {
@@ -2260,27 +2522,27 @@ async function updateGameSdk() {
2260
2522
  totalSuccess += successCount;
2261
2523
  totalFail += failCount;
2262
2524
  } else {
2263
- console.log(`⚠️ Skipping documentation download due to manifest error
2525
+ console.log(`\u26A0\uFE0F Skipping documentation download due to manifest error
2264
2526
  `);
2265
2527
  }
2266
2528
  console.log("=".repeat(60));
2267
2529
  console.log(`\uD83C\uDF89 Download Complete!
2268
2530
  `);
2269
2531
  console.log(`\uD83D\uDCCA Final Summary:`);
2270
- console.log(` Successfully downloaded: ${totalSuccess} files`);
2532
+ console.log(` \u2705 Successfully downloaded: ${totalSuccess} files`);
2271
2533
  if (totalFail > 0) {
2272
- console.log(` Failed: ${totalFail} files`);
2534
+ console.log(` \u274C Failed: ${totalFail} files`);
2273
2535
  console.log(`
2274
- ⚠️ Some files failed to download. Please check the errors above.`);
2536
+ \u26A0\uFE0F Some files failed to download. Please check the errors above.`);
2275
2537
  process.exit(1);
2276
2538
  } else {
2277
2539
  console.log(`
2278
- All files downloaded successfully!`);
2540
+ \u2728 All files downloaded successfully!`);
2279
2541
  }
2280
2542
  }
2281
2543
 
2282
2544
  // src/cli.ts
2283
- var TEMPLATES = {
2545
+ var TEMPLATES2 = {
2284
2546
  webapp: {
2285
2547
  name: "webapp",
2286
2548
  description: "Frontend-only webapp (Vite + React Router 7)",
@@ -2293,15 +2555,15 @@ var TEMPLATES = {
2293
2555
  }
2294
2556
  };
2295
2557
  async function selectTemplate() {
2296
- const entries = Object.values(TEMPLATES);
2558
+ const entries = Object.values(TEMPLATES2);
2297
2559
  console.log(`
2298
2560
  Available templates:
2299
2561
  `);
2300
2562
  entries.forEach((t, i) => {
2301
- console.log(` ${i + 1}. ${t.name} ${t.description}`);
2563
+ console.log(` ${i + 1}. ${t.name} \u2014 ${t.description}`);
2302
2564
  });
2303
2565
  console.log();
2304
- const readline = await import("node:readline");
2566
+ const readline = await import("readline");
2305
2567
  const rl = readline.createInterface({
2306
2568
  input: process.stdin,
2307
2569
  output: process.stdout
@@ -2319,23 +2581,29 @@ Available templates:
2319
2581
  });
2320
2582
  });
2321
2583
  }
2322
- program.name("@rodyssey/cli").description("Airconcepts CLI toolkit").version("0.0.5");
2584
+ program.name("@rodyssey/cli").description("Airconcepts CLI toolkit").version("0.1.0");
2323
2585
  var app = program.command("app").description("Manage webapp projects");
2324
2586
  app.command("create").argument("<project-name>", "Name of the project to create").option("-t, --template <template>", "Template to use (webapp | webapp-fullstack)").description("Create a new project from a template").action(async (projectName, options) => {
2325
2587
  let templateName;
2326
2588
  if (options.template) {
2327
- if (!(options.template in TEMPLATES)) {
2328
- console.error(`Unknown template "${options.template}". Available: ${Object.keys(TEMPLATES).join(", ")}`);
2589
+ if (!(options.template in TEMPLATES2)) {
2590
+ console.error(`Unknown template "${options.template}". Available: ${Object.keys(TEMPLATES2).join(", ")}`);
2329
2591
  process.exit(1);
2330
2592
  }
2331
2593
  templateName = options.template;
2332
2594
  } else {
2333
2595
  templateName = await selectTemplate();
2334
2596
  }
2335
- const template = TEMPLATES[templateName];
2597
+ const template = TEMPLATES2[templateName];
2336
2598
  await create(projectName, template.repo, templateName);
2337
2599
  });
2338
2600
  app.command("update-game-sdk").description("Download and update the GameSDK library, types, and documentation").action(async () => {
2339
2601
  await updateGameSdk();
2340
2602
  });
2603
+ app.command("deploy").description("Build and deploy the webapp to the server").option("-e, --env <environment>", "Target environment (development | staging | production)", "development").action(async (options) => {
2604
+ await deploy(options.env);
2605
+ });
2606
+ app.command("upgrade-agent").description("Upgrade agent files from the template repository").action(async () => {
2607
+ await upgradeAgent();
2608
+ });
2341
2609
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rodyssey/cli",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "description": "Scaffold new projects from airconcepts templates",
5
5
  "bin": {
6
6
  "@rodyssey/cli": "dist/cli.js"
@@ -11,7 +11,7 @@
11
11
  "type": "module",
12
12
  "module": "index.ts",
13
13
  "scripts": {
14
- "build": "bun build src/cli.ts --outdir dist --target node",
14
+ "build": "bun build src/cli.ts --outdir dist --target bun",
15
15
  "start": "bun dist/cli.js",
16
16
  "prepublishOnly": "bun run build"
17
17
  },