lunel-cli 0.1.101 → 0.1.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ai/index.js CHANGED
@@ -11,7 +11,8 @@ export class AiManager {
11
11
  this.tryInit("codex"),
12
12
  ]);
13
13
  if (this._available.length === 0) {
14
- throw new Error("No AI backend could be started. Ensure opencode or codex is installed.");
14
+ console.warn("[ai] No AI backends available. CLI will continue without AI features.");
15
+ return;
15
16
  }
16
17
  if (DEBUG_MODE) {
17
18
  console.log(`[ai] Available backends: ${this._available.join(", ")}`);
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import * as fssync from "fs";
11
11
  import * as path from "path";
12
12
  import * as os from "os";
13
13
  import { randomBytes } from "crypto";
14
- import { spawn, spawnSync, execSync, execFileSync } from "child_process";
14
+ import { spawn, spawnSync, execSync } from "child_process";
15
15
  import { createServer, createConnection } from "net";
16
16
  import { createInterface } from "readline";
17
17
  const DEFAULT_PROXY_URL = normalizeGatewayUrl(process.env.LUNEL_PROXY_URL || "https://gateway.lunel.dev");
@@ -29,9 +29,22 @@ if (DEBUG_MODE) {
29
29
  import { createRequire } from "module";
30
30
  const __require = createRequire(import.meta.url);
31
31
  const VERSION = __require("../package.json").version;
32
- const PTY_RELEASE_INFO_URL = process.env.LUNEL_PTY_INFO_URL ||
33
- "https://raw.githubusercontent.com/ssbharambe-m/pty-releases/refs/heads/main/info.json";
34
32
  const VERBOSE_AI_LOGS = process.env.LUNEL_DEBUG_AI === "1";
33
+ const PTY_RELEASE_BASE_URL = "https://github.com/lunel-dev/lunel/releases/download/v0";
34
+ const PTY_RELEASES = {
35
+ "linux:x64": {
36
+ fileName: "lunel-pty-linux-x8664-0",
37
+ url: `${PTY_RELEASE_BASE_URL}/lunel-pty-linux-x8664-0`,
38
+ },
39
+ "darwin:arm64": {
40
+ fileName: "lunel-pty-macos-arm64-0",
41
+ url: `${PTY_RELEASE_BASE_URL}/lunel-pty-macos-arm64-0`,
42
+ },
43
+ "win32:x64": {
44
+ fileName: "lunel-pty-windows-x8664-0.exe",
45
+ url: `${PTY_RELEASE_BASE_URL}/lunel-pty-windows-x8664-0.exe`,
46
+ },
47
+ };
35
48
  // Root directory - sandbox all file operations to this
36
49
  const ROOT_DIR = (() => {
37
50
  try {
@@ -1219,18 +1232,6 @@ let ensurePtyBinaryPromise = null;
1219
1232
  function normalizeJsonWithTrailingCommas(text) {
1220
1233
  return text.replace(/,\s*([}\]])/g, "$1");
1221
1234
  }
1222
- function compareSemver(a, b) {
1223
- const aParts = a.split(".").map((part) => Number.parseInt(part, 10) || 0);
1224
- const bParts = b.split(".").map((part) => Number.parseInt(part, 10) || 0);
1225
- const max = Math.max(aParts.length, bParts.length);
1226
- for (let i = 0; i < max; i++) {
1227
- const left = aParts[i] ?? 0;
1228
- const right = bParts[i] ?? 0;
1229
- if (left !== right)
1230
- return left > right ? 1 : -1;
1231
- }
1232
- return 0;
1233
- }
1234
1235
  function getLunelConfigDir() {
1235
1236
  const platform = os.platform();
1236
1237
  if (platform === "win32") {
@@ -1243,52 +1244,14 @@ function getLunelConfigDir() {
1243
1244
  const xdg = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
1244
1245
  return path.join(xdg, "lunel");
1245
1246
  }
1246
- function getPtyBinaryPath() {
1247
- const binName = os.platform() === "win32" ? "lunel-pty.exe" : "lunel-pty";
1248
- return path.join(getLunelConfigDir(), "pty-releases", binName);
1249
- }
1250
- function getPtyPlatformKey() {
1251
- const platform = os.platform();
1252
- if (platform === "win32")
1253
- return "windows";
1254
- if (platform === "linux")
1255
- return "linux";
1256
- if (platform === "darwin")
1257
- return "macos";
1258
- throw new Error(`Unsupported platform for PTY: ${platform}`);
1259
- }
1260
- function getPtyArchKey() {
1261
- const arch = os.arch();
1262
- if (arch === "arm64" || arch === "arm")
1263
- return "arm";
1264
- if (arch === "x64" || arch === "ia32")
1265
- return "x86";
1266
- throw new Error(`Unsupported architecture for PTY: ${arch}`);
1267
- }
1268
- async function fetchPtyReleaseInfo() {
1269
- const response = await fetch(PTY_RELEASE_INFO_URL);
1270
- if (!response.ok) {
1271
- throw new Error(`Failed to fetch PTY release info (${response.status})`);
1272
- }
1273
- const raw = await response.text();
1274
- const parsed = JSON.parse(raw);
1275
- if (!parsed?.version) {
1276
- throw new Error("Invalid PTY release info: missing version");
1277
- }
1278
- return parsed;
1279
- }
1280
- function readInstalledPtyVersion(binPath) {
1281
- try {
1282
- const output = execFileSync(binPath, ["--version"], {
1283
- encoding: "utf8",
1284
- stdio: ["ignore", "pipe", "ignore"],
1285
- });
1286
- const version = output.trim();
1287
- return version || null;
1288
- }
1289
- catch {
1247
+ function getPtyReleaseTarget() {
1248
+ const release = PTY_RELEASES[`${os.platform()}:${os.arch()}`];
1249
+ if (!release)
1290
1250
  return null;
1291
- }
1251
+ return release;
1252
+ }
1253
+ function getPtyBinaryPath(fileName) {
1254
+ return path.join(getLunelConfigDir(), "pty-releases", fileName);
1292
1255
  }
1293
1256
  async function downloadPtyBinary(url, destination) {
1294
1257
  const tempPath = `${destination}.download`;
@@ -1324,36 +1287,20 @@ async function ensurePtyBinaryReady() {
1324
1287
  if (ensurePtyBinaryPromise)
1325
1288
  return ensurePtyBinaryPromise;
1326
1289
  ensurePtyBinaryPromise = (async () => {
1327
- const binPath = getPtyBinaryPath();
1290
+ const release = getPtyReleaseTarget();
1291
+ if (!release)
1292
+ return null;
1293
+ const binPath = getPtyBinaryPath(release.fileName);
1328
1294
  await fs.mkdir(path.dirname(binPath), { recursive: true });
1329
- const releaseInfo = await fetchPtyReleaseInfo();
1330
- const platformKey = getPtyPlatformKey();
1331
- const archKey = getPtyArchKey();
1332
- const downloadUrl = releaseInfo[platformKey]?.[archKey] || null;
1333
- if (!downloadUrl) {
1334
- throw new Error(`PTY binary is not available for ${platformKey}/${archKey} in release ${releaseInfo.version}`);
1335
- }
1336
- let hasBinary = true;
1337
1295
  try {
1338
1296
  await fs.access(binPath);
1297
+ return binPath;
1339
1298
  }
1340
1299
  catch {
1341
- hasBinary = false;
1342
- }
1343
- const installedVersion = hasBinary ? readInstalledPtyVersion(binPath) : null;
1344
- const shouldDownload = !hasBinary ||
1345
- !installedVersion ||
1346
- compareSemver(installedVersion, releaseInfo.version) < 0;
1347
- if (!shouldDownload)
1300
+ console.log(`[pty] PTY missing. Installing ${release.fileName}...`);
1301
+ await downloadPtyBinary(release.url, binPath);
1348
1302
  return binPath;
1349
- if (!hasBinary) {
1350
- console.log(`[pty] PTY missing. Installing ${releaseInfo.version}...`);
1351
1303
  }
1352
- else {
1353
- console.log(`[pty] PTY outdated (${installedVersion} -> ${releaseInfo.version}). Updating...`);
1354
- }
1355
- await downloadPtyBinary(downloadUrl, binPath);
1356
- return binPath;
1357
1304
  })();
1358
1305
  try {
1359
1306
  return await ensurePtyBinaryPromise;
@@ -1366,6 +1313,9 @@ async function ensurePtyProcess() {
1366
1313
  if (ptyProcess && ptyProcess.exitCode === null)
1367
1314
  return;
1368
1315
  const binPath = await ensurePtyBinaryReady();
1316
+ if (!binPath) {
1317
+ throw new Error(`PTY is not supported on ${os.platform()}/${os.arch()}`);
1318
+ }
1369
1319
  ptyProcess = spawn(binPath, [], {
1370
1320
  cwd: ROOT_DIR,
1371
1321
  stdio: ["pipe", "pipe", "pipe"],
@@ -3122,8 +3072,13 @@ async function main() {
3122
3072
  const cliConfig = await getCliConfig();
3123
3073
  const savedSession = getSavedSessionForRoot(cliConfig, ROOT_DIR);
3124
3074
  debugLog("Checking PTY runtime...");
3125
- await ensurePtyBinaryReady();
3126
- debugLog("PTY runtime ready.\n");
3075
+ const ptyBinaryPath = await ensurePtyBinaryReady();
3076
+ if (ptyBinaryPath) {
3077
+ debugLog("PTY runtime ready.\n");
3078
+ }
3079
+ else {
3080
+ debugLog(`PTY runtime unsupported on ${os.platform()}/${os.arch()}. Skipping prefetch.\n`);
3081
+ }
3127
3082
  // Start both AI backends (OpenCode + Codex). Unavailable ones are skipped.
3128
3083
  aiManager = await createAiManager();
3129
3084
  // Wire provider events → mobile app data channel, tagged with backend name.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lunel-cli",
3
- "version": "0.1.101",
3
+ "version": "0.1.103",
4
4
  "author": [
5
5
  {
6
6
  "name": "Soham Bharambe",
@@ -11,7 +11,7 @@
11
11
  "email": "rinkit@lunel.dev"
12
12
  }
13
13
  ],
14
- "license": "Functional Source License, Version 1.1, Apache 2.0 Future License",
14
+ "license": "MIT",
15
15
  "type": "module",
16
16
  "bin": {
17
17
  "lunel-cli": "dist/index.js"