@rodyssey/cli 0.0.8 → 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 +313 -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
  {
@@ -2154,6 +2416,11 @@ var FILES = [
2154
2416
  path: "public/game-sdk.js",
2155
2417
  description: "GameSDK JavaScript library"
2156
2418
  },
2419
+ {
2420
+ url: `${BASE_URL}/game-sdk-reactions.js`,
2421
+ path: "public/game-sdk-reactions.js",
2422
+ description: "GameSDK Reactions JavaScript library"
2423
+ },
2157
2424
  {
2158
2425
  url: `${BASE_URL}/game-sdk.d.ts`,
2159
2426
  path: "src/types/game-sdk.d.ts",
@@ -2174,11 +2441,11 @@ async function downloadFile(url, path3, description) {
2174
2441
  const dir = dirname(path3);
2175
2442
  await mkdir(dir, { recursive: true });
2176
2443
  await writeFile(path3, content, "utf-8");
2177
- console.log(`✅ Downloaded ${description} (${content.length} bytes)
2444
+ console.log(`\u2705 Downloaded ${description} (${content.length} bytes)
2178
2445
  `);
2179
2446
  return true;
2180
2447
  } catch (error) {
2181
- console.error(`❌ Failed to download ${description}:`);
2448
+ console.error(`\u274C Failed to download ${description}:`);
2182
2449
  console.error(` ${error instanceof Error ? error.message : String(error)}
2183
2450
  `);
2184
2451
  return false;
@@ -2195,14 +2462,14 @@ async function downloadManifest() {
2195
2462
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
2196
2463
  }
2197
2464
  const manifest = await response.json();
2198
- console.log(`✅ Manifest downloaded successfully`);
2465
+ console.log(`\u2705 Manifest downloaded successfully`);
2199
2466
  console.log(` Name: ${manifest.name}`);
2200
2467
  console.log(` Version: ${manifest.version}`);
2201
2468
  console.log(` Documentation files: ${manifest.documentation.length}
2202
2469
  `);
2203
2470
  return manifest;
2204
2471
  } catch (error) {
2205
- console.error(" Failed to download manifest:");
2472
+ console.error("\u274C Failed to download manifest:");
2206
2473
  console.error(` ${error instanceof Error ? error.message : String(error)}
2207
2474
  `);
2208
2475
  return null;
@@ -2215,7 +2482,7 @@ async function downloadDocumentation(manifest) {
2215
2482
  let failCount = 0;
2216
2483
  for (const doc of manifest.documentation) {
2217
2484
  const url = `${BASE_URL}/skills/${doc.file}`;
2218
- const path3 = join(".agent", "skills", "game-sdk", doc.file);
2485
+ const path3 = join2(".agent", "skills", "game-sdk", doc.file);
2219
2486
  const description = `${doc.title} (${doc.category})`;
2220
2487
  const success = await downloadFile(url, path3, description);
2221
2488
  if (success) {
@@ -2226,9 +2493,9 @@ async function downloadDocumentation(manifest) {
2226
2493
  }
2227
2494
  console.log(`
2228
2495
  \uD83D\uDCCA Documentation download summary:`);
2229
- console.log(` Success: ${successCount}`);
2496
+ console.log(` \u2705 Success: ${successCount}`);
2230
2497
  if (failCount > 0) {
2231
- console.log(` Failed: ${failCount}`);
2498
+ console.log(` \u274C Failed: ${failCount}`);
2232
2499
  }
2233
2500
  console.log();
2234
2501
  return { successCount, failCount };
@@ -2241,8 +2508,8 @@ async function updateGameSdk() {
2241
2508
  let totalFail = 0;
2242
2509
  console.log(`\uD83D\uDCE6 Downloading core SDK files...
2243
2510
  `);
2244
- for (const file of FILES) {
2245
- 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);
2246
2513
  if (success) {
2247
2514
  totalSuccess++;
2248
2515
  } else {
@@ -2255,27 +2522,27 @@ async function updateGameSdk() {
2255
2522
  totalSuccess += successCount;
2256
2523
  totalFail += failCount;
2257
2524
  } else {
2258
- console.log(`⚠️ Skipping documentation download due to manifest error
2525
+ console.log(`\u26A0\uFE0F Skipping documentation download due to manifest error
2259
2526
  `);
2260
2527
  }
2261
2528
  console.log("=".repeat(60));
2262
2529
  console.log(`\uD83C\uDF89 Download Complete!
2263
2530
  `);
2264
2531
  console.log(`\uD83D\uDCCA Final Summary:`);
2265
- console.log(` Successfully downloaded: ${totalSuccess} files`);
2532
+ console.log(` \u2705 Successfully downloaded: ${totalSuccess} files`);
2266
2533
  if (totalFail > 0) {
2267
- console.log(` Failed: ${totalFail} files`);
2534
+ console.log(` \u274C Failed: ${totalFail} files`);
2268
2535
  console.log(`
2269
- ⚠️ Some files failed to download. Please check the errors above.`);
2536
+ \u26A0\uFE0F Some files failed to download. Please check the errors above.`);
2270
2537
  process.exit(1);
2271
2538
  } else {
2272
2539
  console.log(`
2273
- All files downloaded successfully!`);
2540
+ \u2728 All files downloaded successfully!`);
2274
2541
  }
2275
2542
  }
2276
2543
 
2277
2544
  // src/cli.ts
2278
- var TEMPLATES = {
2545
+ var TEMPLATES2 = {
2279
2546
  webapp: {
2280
2547
  name: "webapp",
2281
2548
  description: "Frontend-only webapp (Vite + React Router 7)",
@@ -2288,15 +2555,15 @@ var TEMPLATES = {
2288
2555
  }
2289
2556
  };
2290
2557
  async function selectTemplate() {
2291
- const entries = Object.values(TEMPLATES);
2558
+ const entries = Object.values(TEMPLATES2);
2292
2559
  console.log(`
2293
2560
  Available templates:
2294
2561
  `);
2295
2562
  entries.forEach((t, i) => {
2296
- console.log(` ${i + 1}. ${t.name} ${t.description}`);
2563
+ console.log(` ${i + 1}. ${t.name} \u2014 ${t.description}`);
2297
2564
  });
2298
2565
  console.log();
2299
- const readline = await import("node:readline");
2566
+ const readline = await import("readline");
2300
2567
  const rl = readline.createInterface({
2301
2568
  input: process.stdin,
2302
2569
  output: process.stdout
@@ -2314,23 +2581,29 @@ Available templates:
2314
2581
  });
2315
2582
  });
2316
2583
  }
2317
- 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");
2318
2585
  var app = program.command("app").description("Manage webapp projects");
2319
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) => {
2320
2587
  let templateName;
2321
2588
  if (options.template) {
2322
- if (!(options.template in TEMPLATES)) {
2323
- 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(", ")}`);
2324
2591
  process.exit(1);
2325
2592
  }
2326
2593
  templateName = options.template;
2327
2594
  } else {
2328
2595
  templateName = await selectTemplate();
2329
2596
  }
2330
- const template = TEMPLATES[templateName];
2597
+ const template = TEMPLATES2[templateName];
2331
2598
  await create(projectName, template.repo, templateName);
2332
2599
  });
2333
2600
  app.command("update-game-sdk").description("Download and update the GameSDK library, types, and documentation").action(async () => {
2334
2601
  await updateGameSdk();
2335
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
+ });
2336
2609
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rodyssey/cli",
3
- "version": "0.0.8",
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
  },