onflyt-cli 0.1.6 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
File without changes
package/dist/index.js CHANGED
@@ -1712,7 +1712,7 @@ var init_config = __esm({
1712
1712
  CONFIG_DIR = join(homedir(), ".onflyt");
1713
1713
  CONFIG_FILE = join(CONFIG_DIR, "config.json");
1714
1714
  PROJECT_CONFIG_FILE = "onflyt.json";
1715
- API_URL = process.env.ONFLYT_API_URL || "https://deploy-api.onflyt.com/api";
1715
+ API_URL = process.env.ONFLYT_API_URL || "https://deploy-api.miiglu.com";
1716
1716
  }
1717
1717
  });
1718
1718
 
@@ -1867,6 +1867,12 @@ function getInstallCommand(frameworkId, packageManager) {
1867
1867
  };
1868
1868
  return installCommands[pm] || `${pm} install`;
1869
1869
  }
1870
+ function getBuildCommand(frameworkId, packageManager) {
1871
+ const pm = packageManager.toLowerCase();
1872
+ const cmd = getDefaultBuildCommand(frameworkId) || "";
1873
+ if (pm === "npm" || pm === "pip" || pm === "poetry") return cmd;
1874
+ return cmd.replace(/^npm /, `${pm} `);
1875
+ }
1870
1876
  var TIER_HOURLY_PRICE, SPEND_THRESHOLDS, TIER_LIMITS, FRAMEWORKS, TEMPLATES;
1871
1877
  var init_shared = __esm({
1872
1878
  "src/shared.ts"() {
@@ -1888,24 +1894,32 @@ var init_shared = __esm({
1888
1894
  free: {
1889
1895
  maxProjects: 3,
1890
1896
  maxInstancesPerProject: 1,
1897
+ maxBuildMinutes: 15,
1898
+ enableLogStreaming: false,
1891
1899
  tier: "free",
1892
1900
  tierLabel: "Free Usage"
1893
1901
  },
1894
1902
  low: {
1895
1903
  maxProjects: 10,
1896
1904
  maxInstancesPerProject: 2,
1905
+ maxBuildMinutes: 30,
1906
+ enableLogStreaming: true,
1897
1907
  tier: "low",
1898
1908
  tierLabel: "Low Spend"
1899
1909
  },
1900
1910
  medium: {
1901
1911
  maxProjects: Infinity,
1902
1912
  maxInstancesPerProject: 4,
1913
+ maxBuildMinutes: 60,
1914
+ enableLogStreaming: true,
1903
1915
  tier: "medium",
1904
1916
  tierLabel: "Medium Spend"
1905
1917
  },
1906
1918
  high: {
1907
1919
  maxProjects: Infinity,
1908
1920
  maxInstancesPerProject: 10,
1921
+ maxBuildMinutes: 120,
1922
+ enableLogStreaming: true,
1909
1923
  tier: "high",
1910
1924
  tierLabel: "High Spend"
1911
1925
  }
@@ -2242,7 +2256,7 @@ async function findOrCreateProject(teamId, projectName, framework, gitUrl, insta
2242
2256
  name: projectName,
2243
2257
  framework: framework || "static",
2244
2258
  teamId,
2245
- gitRepoUrl: gitUrl || null,
2259
+ gitRepository: gitUrl ? { repoUrl: gitUrl, branch: "main" } : void 0,
2246
2260
  instanceSize,
2247
2261
  maxInstances
2248
2262
  });
@@ -2261,7 +2275,7 @@ async function getProjectDetails(projectId) {
2261
2275
  const res = await api.get(`/projects/${projectId}`);
2262
2276
  return res.project || res;
2263
2277
  }
2264
- async function startDeployment(projectId, branch, instanceSize, replicas, envVars, buildCommand, installCommand, outputDirectory) {
2278
+ async function startDeployment(projectId, branch, instanceSize, replicas, envVars, buildCommand, installCommand, outputDirectory, rootDirectory) {
2265
2279
  const deployRes = await api.post(`/deployments/${projectId}/deploy`, {
2266
2280
  branch: branch || "main",
2267
2281
  instanceSize,
@@ -2269,7 +2283,8 @@ async function startDeployment(projectId, branch, instanceSize, replicas, envVar
2269
2283
  envVars,
2270
2284
  buildCommand,
2271
2285
  installCommand,
2272
- outputDirectory
2286
+ outputDirectory,
2287
+ rootDirectory
2273
2288
  });
2274
2289
  return deployRes.deploymentId;
2275
2290
  }
@@ -9901,7 +9916,7 @@ import { useEffect } from "react";
9901
9916
  var Help = () => {
9902
9917
  useEffect(() => {
9903
9918
  console.log(`
9904
- \x1B[38;2;255;191;0m \u2B21 \uFF2F\uFF2E\uFF26\uFF2C\uFF39\uFF34 \x1B[0m\x1B[1m Deploy CLI v0.1.0-beta\x1B[0m
9919
+ \x1B[38;2;255;191;0m \u2B21 \uFF2F\uFF2E\uFF26\uFF2C\uFF39\uFF34 \x1B[0m\x1B[1m Deploy CLI v0.1.11-beta\x1B[0m
9905
9920
 
9906
9921
  \x1B[1mUSAGE\x1B[0m
9907
9922
  $ onflyt <command> [options]
@@ -10628,7 +10643,7 @@ var bigText = (str) => {
10628
10643
  return c;
10629
10644
  }).join("");
10630
10645
  };
10631
- var Logo = () => /* @__PURE__ */ React3.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Box, { alignItems: "center" }, /* @__PURE__ */ React3.createElement(Text2, { color: "rgb(255,191,0)" }, " \u2B21 "), /* @__PURE__ */ React3.createElement(Text2, { bold: true, color: "rgb(255,191,0)" }, bigText("Onflyt")), /* @__PURE__ */ React3.createElement(Text2, null, " "), /* @__PURE__ */ React3.createElement(Text2, { bold: true, color: "black", backgroundColor: "rgb(255,191,0)" }, " ", "0.1.6-beta", " ")));
10646
+ var Logo = () => /* @__PURE__ */ React3.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Box, { alignItems: "center" }, /* @__PURE__ */ React3.createElement(Text2, { color: "rgb(255,191,0)" }, " \u2B21 "), /* @__PURE__ */ React3.createElement(Text2, { bold: true, color: "rgb(255,191,0)" }, bigText("Onflyt")), /* @__PURE__ */ React3.createElement(Text2, null, " "), /* @__PURE__ */ React3.createElement(Text2, { bold: true, color: "black", backgroundColor: "rgb(255,191,0)" }, " ", "0.1.11-beta", " ")));
10632
10647
  var ErrorDisplay = ({ message }) => /* @__PURE__ */ React3.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Logo, null), /* @__PURE__ */ React3.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text2, { bold: true, color: "red" }, "\u2716 Error")), /* @__PURE__ */ React3.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text2, { color: "red" }, message)));
10633
10648
 
10634
10649
  // src/commands/login.tsx
@@ -10883,7 +10898,7 @@ var projects_default = ProjectsList;
10883
10898
  import React8 from "react";
10884
10899
  import { Text as Text7, Box as Box6, useInput as useInput2 } from "ink";
10885
10900
  import { existsSync as existsSync3, writeFileSync as writeFileSync2 } from "fs";
10886
- import { join as join3 } from "path";
10901
+ import { join as join3, relative } from "path";
10887
10902
 
10888
10903
  // src/lib/git.ts
10889
10904
  import { execSync } from "child_process";
@@ -11246,6 +11261,8 @@ var Init = ({
11246
11261
  const [detectedFrameworkId, setDetectedFrameworkId] = React8.useState("");
11247
11262
  const [gitUrl, setGitUrl] = React8.useState(null);
11248
11263
  const [gitBranch, setGitBranch] = React8.useState("main");
11264
+ const [gitRoot, setGitRoot] = React8.useState("");
11265
+ const [rootDirValue, setRootDirValue] = React8.useState("");
11249
11266
  const [remoteUrl, setRemoteUrl] = React8.useState("");
11250
11267
  const [errorMsg, setErrorMsg] = React8.useState("");
11251
11268
  const [savedConfig, setSavedConfig] = React8.useState(
@@ -11312,6 +11329,10 @@ var Init = ({
11312
11329
  setGitUrl(gitInfo.remotes[0].url);
11313
11330
  setGitBranch(gitInfo.currentBranch || "main");
11314
11331
  }
11332
+ if (gitInfo.rootDir && gitInfo.rootDir !== cwd) {
11333
+ setGitRoot(gitInfo.rootDir);
11334
+ setRootDirValue(relative(gitInfo.rootDir, cwd));
11335
+ }
11315
11336
  if (yes) {
11316
11337
  autoSave();
11317
11338
  }
@@ -11335,7 +11356,7 @@ var Init = ({
11335
11356
  const cwd = process.cwd();
11336
11357
  const frameworkDetector = new FrameworkDetector(cwd);
11337
11358
  const detectedOutputDir = frameworkDetector.detectOutputDirectory(fwId);
11338
- const buildCmd = getDefaultBuildCommand(fwId) || "";
11359
+ const buildCmd = getBuildCommand(fwId, pmId);
11339
11360
  const installCmd = getInstallCommand(fwId, pmId);
11340
11361
  const outputDir = detectedOutputDir || getDefaultOutputDirectory(fwId) || ".";
11341
11362
  const startCmd = getDefaultStartCommand(fwId) || "";
@@ -11351,7 +11372,8 @@ var Init = ({
11351
11372
  installCommand: installCmd,
11352
11373
  startCommand: startCmd,
11353
11374
  gitRepoUrl: connectGit ? remoteUrl || gitUrl || void 0 : void 0,
11354
- gitBranch: connectGit ? "main" : void 0
11375
+ gitBranch: connectGit ? gitBranch : void 0,
11376
+ rootDirectory: connectGit && rootDirValue ? rootDirValue : void 0
11355
11377
  };
11356
11378
  saveProjectConfig(projectConfig);
11357
11379
  setSavedConfig(projectConfig);
@@ -11457,10 +11479,10 @@ build/
11457
11479
  setConnectGit((prev) => !prev);
11458
11480
  } else if (key.return) {
11459
11481
  if (connectGit) {
11460
- if (hasGit) {
11461
- autoSave();
11482
+ if (rootDirValue) {
11483
+ goTo("rootDirectory");
11462
11484
  } else {
11463
- goTo("gitRemote");
11485
+ goTo("gitBranch");
11464
11486
  }
11465
11487
  } else {
11466
11488
  autoSave();
@@ -11469,6 +11491,32 @@ build/
11469
11491
  goBack();
11470
11492
  }
11471
11493
  break;
11494
+ case "rootDirectory":
11495
+ if (key.return) {
11496
+ goTo("gitBranch");
11497
+ } else if (key.escape) {
11498
+ goBack();
11499
+ } else if (key.backspace || key.delete) {
11500
+ setRootDirValue(rootDirValue.slice(0, -1));
11501
+ } else if (input && input.match(/^[a-zA-Z0-9-_/.@]$/)) {
11502
+ setRootDirValue(rootDirValue + input);
11503
+ }
11504
+ break;
11505
+ case "gitBranch":
11506
+ if (key.return) {
11507
+ if (connectGit && !hasGit) {
11508
+ goTo("gitRemote");
11509
+ } else {
11510
+ autoSave();
11511
+ }
11512
+ } else if (key.escape) {
11513
+ goBack();
11514
+ } else if (key.backspace || key.delete) {
11515
+ setGitBranch(gitBranch.slice(0, -1));
11516
+ } else if (input && input.match(/^[a-zA-Z0-9-_/.@]$/)) {
11517
+ setGitBranch(gitBranch + input);
11518
+ }
11519
+ break;
11472
11520
  case "gitRemote":
11473
11521
  if (key.return) {
11474
11522
  autoSave();
@@ -11491,7 +11539,7 @@ build/
11491
11539
  if (step === "done") {
11492
11540
  return /* @__PURE__ */ React8.createElement(Box6, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "green" }, "\u2713 Project initialized!"), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "onflyt.json saved to current directory")), savedConfig && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Project: ", savedConfig.name)), /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Framework: ", FRAMEWORKS[savedConfig.framework]?.label)), savedConfig.gitRepoUrl && /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Git: ", savedConfig.gitRepoUrl))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 2 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true }, "Next steps:")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "1. Run 'onflyt deploy' to deploy")), /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "2. Team selection will happen during deploy")));
11493
11541
  }
11494
- return /* @__PURE__ */ React8.createElement(Box6, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React8.createElement(Logo, null), step === "name" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Project Name")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Press keys to edit, Enter to continue")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, ">", " "), /* @__PURE__ */ React8.createElement(Text7, null, projectName || detectedName), /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "_"))), step === "setupType" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Setup Type")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, useTemplate === 0 ? "\u276F " : " ", "Use existing files")), /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, useTemplate === 1 ? "\u276F " : " ", "Use a template (scaffold from starter)"))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "template" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Select Template")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, TEMPLATES.map((t, i) => /* @__PURE__ */ React8.createElement(Box6, { key: t.id }, /* @__PURE__ */ React8.createElement(Text7, null, i === selectedTemplate ? "\u276F " : " ", t.name, " - ", t.description)))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "framework" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Select Framework")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Detected: ", detectedFrameworkId)), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, FRAMEWORK_LIST2.map((fw, i) => /* @__PURE__ */ React8.createElement(Box6, { key: fw.id }, /* @__PURE__ */ React8.createElement(Text7, null, i === selectedFramework ? "\u276F " : " ", fw.name)))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "packageManager" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Select Package Manager")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, PACKAGE_MANAGERS.map((pm, i) => /* @__PURE__ */ React8.createElement(Box6, { key: pm.id }, /* @__PURE__ */ React8.createElement(Text7, null, i === selectedPackageManager ? "\u276F " : " ", pm.name)))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "git" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Git Repository")), gitUrl && /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Detected: ", gitUrl, " (", gitBranch, ")")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, connectGit ? "\u276F " : " ", hasGit ? "Yes, connect git repo" : "Initialize git repo")), /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, !connectGit ? "\u276F " : " ", "Skip git (manual deploys)"))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "gitRemote" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Git Remote URL (optional)")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Press Enter to skip, or enter GitHub repo URL")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "> ", remoteUrl), /* @__PURE__ */ React8.createElement(Text7, { bold: true }, "_")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Enter paste URL \u2022 Backspace delete \u2022 Enter continue"))));
11542
+ return /* @__PURE__ */ React8.createElement(Box6, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React8.createElement(Logo, null), step === "name" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Project Name")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Press keys to edit, Enter to continue")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, ">", " "), /* @__PURE__ */ React8.createElement(Text7, null, projectName || detectedName), /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "_"))), step === "setupType" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Setup Type")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, useTemplate === 0 ? "\u276F " : " ", "Use existing files")), /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, useTemplate === 1 ? "\u276F " : " ", "Use a template (scaffold from starter)"))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "template" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Select Template")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, TEMPLATES.map((t, i) => /* @__PURE__ */ React8.createElement(Box6, { key: t.id }, /* @__PURE__ */ React8.createElement(Text7, null, i === selectedTemplate ? "\u276F " : " ", t.name, " - ", t.description)))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "framework" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Select Framework")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Detected: ", detectedFrameworkId)), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, FRAMEWORK_LIST2.map((fw, i) => /* @__PURE__ */ React8.createElement(Box6, { key: fw.id }, /* @__PURE__ */ React8.createElement(Text7, null, i === selectedFramework ? "\u276F " : " ", fw.name)))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "packageManager" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Select Package Manager")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, PACKAGE_MANAGERS.map((pm, i) => /* @__PURE__ */ React8.createElement(Box6, { key: pm.id }, /* @__PURE__ */ React8.createElement(Text7, null, i === selectedPackageManager ? "\u276F " : " ", pm.name)))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "git" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Git Repository")), gitUrl && /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Detected: ", gitUrl, " (", gitBranch, ")")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, connectGit ? "\u276F " : " ", hasGit ? "Yes, connect git repo" : "Initialize git repo")), /* @__PURE__ */ React8.createElement(Box6, null, /* @__PURE__ */ React8.createElement(Text7, null, !connectGit ? "\u276F " : " ", "Skip git (manual deploys)"))), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, FOOTER))), step === "gitRemote" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Git Remote URL (optional)")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Press Enter to skip, or enter GitHub repo URL")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "> ", remoteUrl), /* @__PURE__ */ React8.createElement(Text7, { bold: true }, "_")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Enter paste URL \u2022 Backspace delete \u2022 Enter continue"))), step === "rootDirectory" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Root Directory")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Subdirectory within git repo where this project lives")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, ">", " "), /* @__PURE__ */ React8.createElement(Text7, null, rootDirValue || "(repo root)"), /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "_")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Edit path \u2022 Backspace delete \u2022 Enter continue"))), step === "gitBranch" && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, null, "Git Branch")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Branch to deploy from")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, ">", " "), /* @__PURE__ */ React8.createElement(Text7, null, gitBranch || "main"), /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "_")), /* @__PURE__ */ React8.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "Edit branch \u2022 Backspace delete \u2022 Enter continue"))));
11495
11543
  };
11496
11544
  var init_default = Init;
11497
11545
 
@@ -11905,7 +11953,8 @@ var Deploy = ({ teamFlag }) => {
11905
11953
  envVars.length > 0 ? envVars : void 0,
11906
11954
  projectConfig?.buildCommand,
11907
11955
  projectConfig?.installCommand,
11908
- projectConfig?.outputDirectory
11956
+ projectConfig?.outputDirectory,
11957
+ projectConfig?.rootDirectory
11909
11958
  );
11910
11959
  setDeploymentId(depId);
11911
11960
  pollStatus(depId);
@@ -12007,7 +12056,7 @@ var Deploy = ({ teamFlag }) => {
12007
12056
  );
12008
12057
  }
12009
12058
  }
12010
- if (details.status === "live") {
12059
+ if (details.status === "deployed") {
12011
12060
  setLiveUrl(
12012
12061
  details.url || `https://${projectConfig?.name}.onflyt.dev`
12013
12062
  );
@@ -12153,6 +12202,7 @@ var Deploy = ({ teamFlag }) => {
12153
12202
  building: "cyan",
12154
12203
  provisioning: "magenta",
12155
12204
  deployed: "green",
12205
+ live: "green",
12156
12206
  failed: "red"
12157
12207
  };
12158
12208
  const statusLabels = {
@@ -12160,6 +12210,7 @@ var Deploy = ({ teamFlag }) => {
12160
12210
  building: "BUILDING",
12161
12211
  provisioning: "PROVISIONING",
12162
12212
  deployed: "DEPLOYED",
12213
+ live: "LIVE",
12163
12214
  failed: "FAILED"
12164
12215
  };
12165
12216
  const statusIcons = {
@@ -12167,6 +12218,7 @@ var Deploy = ({ teamFlag }) => {
12167
12218
  building: "\u{1F528}",
12168
12219
  provisioning: "\u2699\uFE0F",
12169
12220
  deployed: "\u2705",
12221
+ live: "\u2705",
12170
12222
  failed: "\u274C"
12171
12223
  };
12172
12224
  const progressPercent = uploadProgress.total > 0 ? Math.round(uploadProgress.uploaded / uploadProgress.total * 100) : 0;
@@ -12990,14 +13042,14 @@ import { render } from "ink";
12990
13042
  import React16 from "react";
12991
13043
  import { Text as Text13, Box as Box12 } from "ink";
12992
13044
  var App = () => {
12993
- return /* @__PURE__ */ React16.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Text13, { bold: true }, " \u2B21 Onflyt CLI 0.1.6-beta"), /* @__PURE__ */ React16.createElement(Text13, null, "Type onflyt --help for available commands"));
13045
+ return /* @__PURE__ */ React16.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Text13, { bold: true }, " \u2B21 Onflyt CLI 0.1.11-beta"), /* @__PURE__ */ React16.createElement(Text13, null, "Type onflyt --help for available commands"));
12994
13046
  };
12995
13047
  var App_default = App;
12996
13048
 
12997
13049
  // src/index.tsx
12998
13050
  var cli = meow(
12999
13051
  `
13000
- Onflyt CLI 0.1.6-beta
13052
+ Onflyt CLI 0.1.11-beta
13001
13053
 
13002
13054
  Usage
13003
13055
  $ onflyt <command>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "onflyt-cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "description": "Onflyt CLI - Deploy Node.js and Python APIs to serverless pods. Pay only per use.",
6
6
  "repository": {
package/src/App.tsx CHANGED
@@ -4,7 +4,7 @@ import { Text, Box } from "ink";
4
4
  const App = () => {
5
5
  return (
6
6
  <Box flexDirection="column">
7
- <Text bold> ⬡ Onflyt CLI 0.1.6-beta</Text>
7
+ <Text bold> ⬡ Onflyt CLI 0.1.11-beta</Text>
8
8
  <Text>Type onflyt --help for available commands</Text>
9
9
  </Box>
10
10
  );
@@ -286,6 +286,7 @@ const Deploy: React.FC<Props> = ({ teamFlag }) => {
286
286
  projectConfig?.buildCommand,
287
287
  projectConfig?.installCommand,
288
288
  projectConfig?.outputDirectory,
289
+ projectConfig?.rootDirectory,
289
290
  );
290
291
 
291
292
  setDeploymentId(depId);
@@ -399,7 +400,7 @@ const Deploy: React.FC<Props> = ({ teamFlag }) => {
399
400
  }
400
401
  }
401
402
 
402
- if (details.status === "live") {
403
+ if (details.status === "deployed") {
403
404
  setLiveUrl(
404
405
  details.url || `https://${projectConfig?.name}.onflyt.dev`,
405
406
  );
@@ -818,6 +819,7 @@ const Deploy: React.FC<Props> = ({ teamFlag }) => {
818
819
  building: "cyan",
819
820
  provisioning: "magenta",
820
821
  deployed: "green",
822
+ live: "green",
821
823
  failed: "red",
822
824
  };
823
825
  const statusLabels: Record<DeploymentStatus, string> = {
@@ -825,6 +827,7 @@ const Deploy: React.FC<Props> = ({ teamFlag }) => {
825
827
  building: "BUILDING",
826
828
  provisioning: "PROVISIONING",
827
829
  deployed: "DEPLOYED",
830
+ live: "LIVE",
828
831
  failed: "FAILED",
829
832
  };
830
833
  const statusIcons: Record<DeploymentStatus, string> = {
@@ -832,6 +835,7 @@ const Deploy: React.FC<Props> = ({ teamFlag }) => {
832
835
  building: "🔨",
833
836
  provisioning: "⚙️",
834
837
  deployed: "✅",
838
+ live: "✅",
835
839
  failed: "❌",
836
840
  };
837
841
 
@@ -3,7 +3,7 @@ import React, { useEffect } from "react";
3
3
  const Help: React.FC = () => {
4
4
  useEffect(() => {
5
5
  console.log(`
6
- \x1b[38;2;255;191;0m ⬡ ONFLYT \x1b[0m\x1b[1m Deploy CLI v0.1.0-beta\x1b[0m
6
+ \x1b[38;2;255;191;0m ⬡ ONFLYT \x1b[0m\x1b[1m Deploy CLI v0.1.11-beta\x1b[0m
7
7
 
8
8
  \x1b[1mUSAGE\x1b[0m
9
9
  $ onflyt <command> [options]
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Text, Box, useInput } from "ink";
3
3
  import { existsSync, writeFileSync } from "fs";
4
- import { join } from "path";
4
+ import { join, relative } from "path";
5
5
  import { GitDetector } from "../lib/git.js";
6
6
  import { FrameworkDetector } from "../lib/framework.js";
7
7
  import {
@@ -14,6 +14,7 @@ import {
14
14
  FRAMEWORKS,
15
15
  TEMPLATES,
16
16
  getDefaultBuildCommand,
17
+ getBuildCommand,
17
18
  getDefaultOutputDirectory,
18
19
  getDefaultStartCommand,
19
20
  getInstallCommand,
@@ -36,6 +37,8 @@ type Step =
36
37
  | "framework"
37
38
  | "packageManager"
38
39
  | "git"
40
+ | "rootDirectory"
41
+ | "gitBranch"
39
42
  | "gitRemote"
40
43
  | "saving"
41
44
  | "done"
@@ -79,6 +82,8 @@ const Init: React.FC<InitProps> = ({
79
82
  const [detectedFrameworkId, setDetectedFrameworkId] = React.useState("");
80
83
  const [gitUrl, setGitUrl] = React.useState<string | null>(null);
81
84
  const [gitBranch, setGitBranch] = React.useState("main");
85
+ const [gitRoot, setGitRoot] = React.useState("");
86
+ const [rootDirValue, setRootDirValue] = React.useState("");
82
87
  const [remoteUrl, setRemoteUrl] = React.useState("");
83
88
  const [errorMsg, setErrorMsg] = React.useState("");
84
89
  const [savedConfig, setSavedConfig] = React.useState<ProjectConfig | null>(
@@ -163,6 +168,11 @@ const Init: React.FC<InitProps> = ({
163
168
  setGitBranch(gitInfo.currentBranch || "main");
164
169
  }
165
170
 
171
+ if (gitInfo.rootDir && gitInfo.rootDir !== cwd) {
172
+ setGitRoot(gitInfo.rootDir);
173
+ setRootDirValue(relative(gitInfo.rootDir, cwd));
174
+ }
175
+
166
176
  if (yes) {
167
177
  autoSave();
168
178
  }
@@ -193,7 +203,7 @@ const Init: React.FC<InitProps> = ({
193
203
  const frameworkDetector = new FrameworkDetector(cwd);
194
204
  const detectedOutputDir = frameworkDetector.detectOutputDirectory(fwId);
195
205
 
196
- const buildCmd = getDefaultBuildCommand(fwId) || "";
206
+ const buildCmd = getBuildCommand(fwId, pmId);
197
207
  const installCmd = getInstallCommand(fwId, pmId);
198
208
  const outputDir =
199
209
  detectedOutputDir || getDefaultOutputDirectory(fwId) || ".";
@@ -212,7 +222,8 @@ const Init: React.FC<InitProps> = ({
212
222
  installCommand: installCmd,
213
223
  startCommand: startCmd,
214
224
  gitRepoUrl: connectGit ? remoteUrl || gitUrl || undefined : undefined,
215
- gitBranch: connectGit ? "main" : undefined,
225
+ gitBranch: connectGit ? gitBranch : undefined,
226
+ rootDirectory: connectGit && rootDirValue ? rootDirValue : undefined,
216
227
  };
217
228
 
218
229
  saveProjectConfig(projectConfig);
@@ -327,10 +338,10 @@ build/
327
338
  setConnectGit((prev) => !prev);
328
339
  } else if (key.return) {
329
340
  if (connectGit) {
330
- if (hasGit) {
331
- autoSave();
341
+ if (rootDirValue) {
342
+ goTo("rootDirectory");
332
343
  } else {
333
- goTo("gitRemote");
344
+ goTo("gitBranch");
334
345
  }
335
346
  } else {
336
347
  autoSave();
@@ -340,6 +351,34 @@ build/
340
351
  }
341
352
  break;
342
353
 
354
+ case "rootDirectory":
355
+ if (key.return) {
356
+ goTo("gitBranch");
357
+ } else if (key.escape) {
358
+ goBack();
359
+ } else if (key.backspace || key.delete) {
360
+ setRootDirValue(rootDirValue.slice(0, -1));
361
+ } else if (input && input.match(/^[a-zA-Z0-9-_/.@]$/)) {
362
+ setRootDirValue(rootDirValue + input);
363
+ }
364
+ break;
365
+
366
+ case "gitBranch":
367
+ if (key.return) {
368
+ if (connectGit && !hasGit) {
369
+ goTo("gitRemote");
370
+ } else {
371
+ autoSave();
372
+ }
373
+ } else if (key.escape) {
374
+ goBack();
375
+ } else if (key.backspace || key.delete) {
376
+ setGitBranch(gitBranch.slice(0, -1));
377
+ } else if (input && input.match(/^[a-zA-Z0-9-_/.@]$/)) {
378
+ setGitBranch(gitBranch + input);
379
+ }
380
+ break;
381
+
343
382
  case "gitRemote":
344
383
  if (key.return) {
345
384
  autoSave();
@@ -580,6 +619,60 @@ build/
580
619
  </Box>
581
620
  </>
582
621
  )}
622
+
623
+ {step === "rootDirectory" && (
624
+ <>
625
+ <Box marginTop={1}>
626
+ <Text>Root Directory</Text>
627
+ </Box>
628
+ <Box marginTop={1}>
629
+ <Text dimColor>
630
+ Subdirectory within git repo where this project lives
631
+ </Text>
632
+ </Box>
633
+ <Box marginTop={1}>
634
+ <Text bold color="cyan">
635
+ &gt;{" "}
636
+ </Text>
637
+ <Text>{rootDirValue || "(repo root)"}</Text>
638
+ <Text bold color="cyan">
639
+ _
640
+ </Text>
641
+ </Box>
642
+ <Box marginTop={1}>
643
+ <Text dimColor>
644
+ Edit path • Backspace delete • Enter continue
645
+ </Text>
646
+ </Box>
647
+ </>
648
+ )}
649
+
650
+ {step === "gitBranch" && (
651
+ <>
652
+ <Box marginTop={1}>
653
+ <Text>Git Branch</Text>
654
+ </Box>
655
+ <Box marginTop={1}>
656
+ <Text dimColor>
657
+ Branch to deploy from
658
+ </Text>
659
+ </Box>
660
+ <Box marginTop={1}>
661
+ <Text bold color="cyan">
662
+ &gt;{" "}
663
+ </Text>
664
+ <Text>{gitBranch || "main"}</Text>
665
+ <Text bold color="cyan">
666
+ _
667
+ </Text>
668
+ </Box>
669
+ <Box marginTop={1}>
670
+ <Text dimColor>
671
+ Edit branch • Backspace delete • Enter continue
672
+ </Text>
673
+ </Box>
674
+ </>
675
+ )}
583
676
  </Box>
584
677
  );
585
678
  };
@@ -24,7 +24,7 @@ export const Logo: React.FC = () => (
24
24
  <Text> </Text>
25
25
  <Text bold color="black" backgroundColor="rgb(255,191,0)">
26
26
  {" "}
27
- 0.1.6-beta{" "}
27
+ 0.1.11-beta{" "}
28
28
  </Text>
29
29
  </Box>
30
30
  </Box>
package/src/index.tsx CHANGED
@@ -17,7 +17,7 @@ import Rollback from "./commands/rollback.js";
17
17
 
18
18
  const cli = meow(
19
19
  `
20
- Onflyt CLI 0.1.6-beta
20
+ Onflyt CLI 0.1.11-beta
21
21
 
22
22
  Usage
23
23
  $ onflyt <command>
package/src/lib/config.ts CHANGED
@@ -60,6 +60,7 @@ export interface ProjectConfig {
60
60
  gitRepoUrl?: string;
61
61
  gitBranch?: string;
62
62
  gitRepoId?: number;
63
+ rootDirectory?: string;
63
64
  }
64
65
 
65
66
  export function getProjectConfig(
@@ -12,7 +12,6 @@ import {
12
12
  import { join, relative, basename } from "path";
13
13
  import { execSync } from "child_process";
14
14
  import {
15
- CONTAINER_TIER_SPECS,
16
15
  TIER_HOURLY_PRICE,
17
16
  ContainerTier,
18
17
  } from "../shared";
@@ -43,6 +42,7 @@ export interface ProjectConfig {
43
42
  startCommand?: string;
44
43
  gitRepoUrl?: string;
45
44
  gitBranch?: string;
45
+ rootDirectory?: string;
46
46
  }
47
47
 
48
48
  export interface InstanceOption {
@@ -219,7 +219,7 @@ export async function findOrCreateProject(
219
219
  name: projectName,
220
220
  framework: framework || "static",
221
221
  teamId,
222
- gitRepoUrl: gitUrl || null,
222
+ gitRepository: gitUrl ? { repoUrl: gitUrl, branch: 'main' } : undefined,
223
223
  instanceSize,
224
224
  maxInstances,
225
225
  });
@@ -256,6 +256,7 @@ export async function startDeployment(
256
256
  buildCommand?: string,
257
257
  installCommand?: string,
258
258
  outputDirectory?: string,
259
+ rootDirectory?: string,
259
260
  ): Promise<string> {
260
261
  const deployRes = await api.post<any>(`/deployments/${projectId}/deploy`, {
261
262
  branch: branch || "main",
@@ -265,6 +266,7 @@ export async function startDeployment(
265
266
  buildCommand,
266
267
  installCommand,
267
268
  outputDirectory,
269
+ rootDirectory,
268
270
  });
269
271
 
270
272
  return deployRes.deploymentId;
@@ -275,6 +277,7 @@ export type DeploymentStatus =
275
277
  | "building"
276
278
  | "provisioning"
277
279
  | "deployed"
280
+ | "live"
278
281
  | "failed";
279
282
 
280
283
  export interface DeploymentDetails {
package/src/shared.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export type PodTier = "micro" | "lite" | "standard" | "pro" | "business";
2
+ export type ContainerTier = PodTier;
2
3
 
3
4
  export const TIER_HOURLY_PRICE: Record<PodTier, number> = {
4
5
  micro: 0,
@@ -13,6 +14,8 @@ export type SpendTier = "free" | "low" | "medium" | "high";
13
14
  export interface TeamLimits {
14
15
  maxProjects: number;
15
16
  maxInstancesPerProject: number;
17
+ maxBuildMinutes: number;
18
+ enableLogStreaming: boolean;
16
19
  tier: SpendTier;
17
20
  tierLabel: string;
18
21
  }
@@ -28,24 +31,32 @@ export const TIER_LIMITS: Record<SpendTier, TeamLimits> = {
28
31
  free: {
29
32
  maxProjects: 3,
30
33
  maxInstancesPerProject: 1,
34
+ maxBuildMinutes: 15,
35
+ enableLogStreaming: false,
31
36
  tier: "free",
32
37
  tierLabel: "Free Usage",
33
38
  },
34
39
  low: {
35
40
  maxProjects: 10,
36
41
  maxInstancesPerProject: 2,
42
+ maxBuildMinutes: 30,
43
+ enableLogStreaming: true,
37
44
  tier: "low",
38
45
  tierLabel: "Low Spend",
39
46
  },
40
47
  medium: {
41
48
  maxProjects: Infinity,
42
49
  maxInstancesPerProject: 4,
50
+ maxBuildMinutes: 60,
51
+ enableLogStreaming: true,
43
52
  tier: "medium",
44
53
  tierLabel: "Medium Spend",
45
54
  },
46
55
  high: {
47
56
  maxProjects: Infinity,
48
57
  maxInstancesPerProject: 10,
58
+ maxBuildMinutes: 120,
59
+ enableLogStreaming: true,
49
60
  tier: "high",
50
61
  tierLabel: "High Spend",
51
62
  },
@@ -299,6 +310,16 @@ export function getInstallCommand(
299
310
  return installCommands[pm] || `${pm} install`;
300
311
  }
301
312
 
313
+ export function getBuildCommand(
314
+ frameworkId: string,
315
+ packageManager: string,
316
+ ): string {
317
+ const pm = packageManager.toLowerCase();
318
+ const cmd = getDefaultBuildCommand(frameworkId) || "";
319
+ if (pm === "npm" || pm === "pip" || pm === "poetry") return cmd;
320
+ return cmd.replace(/^npm /, `${pm} `);
321
+ }
322
+
302
323
  export interface Template {
303
324
  id: string;
304
325
  name: string;