lunel-cli 0.1.101 → 0.1.102
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/index.js +40 -85
- package/package.json +2 -2
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
|
|
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
|
|
1247
|
-
const
|
|
1248
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.1.102",
|
|
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": "
|
|
14
|
+
"license": "MIT",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"bin": {
|
|
17
17
|
"lunel-cli": "dist/index.js"
|