lunel-cli 0.1.33 → 0.1.34
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 +49 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ const __require = createRequire(import.meta.url);
|
|
|
19
19
|
const VERSION = __require("../package.json").version;
|
|
20
20
|
const PTY_RELEASE_INFO_URL = process.env.LUNEL_PTY_INFO_URL ||
|
|
21
21
|
"https://raw.githubusercontent.com/ssbharambe-m/pty-releases/refs/heads/main/info.json";
|
|
22
|
+
const VERBOSE_AI_LOGS = process.env.LUNEL_DEBUG_AI === "1";
|
|
22
23
|
// Root directory - sandbox all file operations to this
|
|
23
24
|
const ROOT_DIR = process.cwd();
|
|
24
25
|
// Terminal sessions (managed by Rust PTY binary)
|
|
@@ -46,6 +47,13 @@ const PORT_SYNC_INTERVAL_MS = 30_000;
|
|
|
46
47
|
let portSyncTimer = null;
|
|
47
48
|
let portScanInFlight = false;
|
|
48
49
|
let lastDiscoveredPorts = [];
|
|
50
|
+
function redactSensitive(input) {
|
|
51
|
+
const text = typeof input === "string" ? input : JSON.stringify(input);
|
|
52
|
+
return text
|
|
53
|
+
.replace(/([A-Za-z0-9\-_]{20,}\.[A-Za-z0-9\-_]{20,}\.[A-Za-z0-9\-_]{20,})/g, "[redacted_jwt]")
|
|
54
|
+
.replace(/(password|token|authorization|resumeToken|x-manager-password)\s*[:=]\s*["']?[^"',\s}]+/gi, "$1=[redacted]")
|
|
55
|
+
.replace(/[A-Za-z0-9+/=_-]{40,}/g, "[redacted_secret]");
|
|
56
|
+
}
|
|
49
57
|
// Popular development server ports to scan on connect
|
|
50
58
|
const DEV_PORTS = [
|
|
51
59
|
1234, // Parcel
|
|
@@ -1375,30 +1383,36 @@ function requireData(response, label) {
|
|
|
1375
1383
|
const errMsg = response.error
|
|
1376
1384
|
? (typeof response.error === "string" ? response.error : JSON.stringify(response.error))
|
|
1377
1385
|
: `${label} returned no data`;
|
|
1378
|
-
console.error(`[ai] ${label} failed:`, errMsg, "raw response:", JSON.stringify(response).substring(0, 500));
|
|
1386
|
+
console.error(`[ai] ${label} failed:`, redactSensitive(errMsg), "raw response:", redactSensitive(JSON.stringify(response).substring(0, 500)));
|
|
1379
1387
|
throw new Error(errMsg);
|
|
1380
1388
|
}
|
|
1381
1389
|
return response.data;
|
|
1382
1390
|
}
|
|
1383
1391
|
async function handleAiCreateSession(payload) {
|
|
1384
1392
|
const title = payload.title || undefined;
|
|
1385
|
-
|
|
1393
|
+
if (VERBOSE_AI_LOGS)
|
|
1394
|
+
console.log("[ai] createSession called");
|
|
1386
1395
|
try {
|
|
1387
1396
|
const response = await opencodeClient.session.create({ body: { title } });
|
|
1388
|
-
|
|
1397
|
+
if (VERBOSE_AI_LOGS) {
|
|
1398
|
+
console.log("[ai] createSession response ok:", !!response.data, "error:", response.error ? redactSensitive(JSON.stringify(response.error).substring(0, 200)) : "none");
|
|
1399
|
+
}
|
|
1389
1400
|
return { session: requireData(response, "session.create") };
|
|
1390
1401
|
}
|
|
1391
1402
|
catch (err) {
|
|
1392
|
-
console.error("[ai] createSession exception:", err.message
|
|
1403
|
+
console.error("[ai] createSession exception:", redactSensitive(err.message));
|
|
1393
1404
|
throw err;
|
|
1394
1405
|
}
|
|
1395
1406
|
}
|
|
1396
1407
|
async function handleAiListSessions() {
|
|
1397
|
-
|
|
1408
|
+
if (VERBOSE_AI_LOGS)
|
|
1409
|
+
console.log("[ai] listSessions called");
|
|
1398
1410
|
try {
|
|
1399
1411
|
const response = await opencodeClient.session.list();
|
|
1400
1412
|
const data = requireData(response, "session.list");
|
|
1401
|
-
|
|
1413
|
+
if (VERBOSE_AI_LOGS) {
|
|
1414
|
+
console.log("[ai] listSessions returned", Array.isArray(data) ? data.length : typeof data, "sessions");
|
|
1415
|
+
}
|
|
1402
1416
|
return { sessions: data };
|
|
1403
1417
|
}
|
|
1404
1418
|
catch (err) {
|
|
@@ -1420,7 +1434,8 @@ async function handleAiDeleteSession(payload) {
|
|
|
1420
1434
|
}
|
|
1421
1435
|
async function handleAiGetMessages(payload) {
|
|
1422
1436
|
const id = payload.id;
|
|
1423
|
-
|
|
1437
|
+
if (VERBOSE_AI_LOGS)
|
|
1438
|
+
console.log("[ai] getMessages called");
|
|
1424
1439
|
try {
|
|
1425
1440
|
const response = await opencodeClient.session.messages({ path: { id } });
|
|
1426
1441
|
const raw = requireData(response, "session.messages");
|
|
@@ -1432,7 +1447,8 @@ async function handleAiGetMessages(payload) {
|
|
|
1432
1447
|
parts: m.parts || [],
|
|
1433
1448
|
time: m.info.time,
|
|
1434
1449
|
}));
|
|
1435
|
-
|
|
1450
|
+
if (VERBOSE_AI_LOGS)
|
|
1451
|
+
console.log("[ai] getMessages returned", messages.length, "messages");
|
|
1436
1452
|
return { messages };
|
|
1437
1453
|
}
|
|
1438
1454
|
catch (err) {
|
|
@@ -1445,7 +1461,14 @@ async function handleAiPrompt(payload) {
|
|
|
1445
1461
|
const text = payload.text;
|
|
1446
1462
|
const model = payload.model;
|
|
1447
1463
|
const agent = payload.agent;
|
|
1448
|
-
|
|
1464
|
+
if (VERBOSE_AI_LOGS) {
|
|
1465
|
+
console.log("[ai] prompt called", {
|
|
1466
|
+
hasSessionId: Boolean(sessionId),
|
|
1467
|
+
model: redactSensitive(JSON.stringify(model || {})),
|
|
1468
|
+
hasAgent: Boolean(agent),
|
|
1469
|
+
textLength: typeof text === "string" ? text.length : 0,
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1449
1472
|
// Fire and forget — results stream via SSE events forwarded on data channel
|
|
1450
1473
|
opencodeClient.session.prompt({
|
|
1451
1474
|
path: { id: sessionId },
|
|
@@ -1477,11 +1500,14 @@ async function handleAiAbort(payload) {
|
|
|
1477
1500
|
return {};
|
|
1478
1501
|
}
|
|
1479
1502
|
async function handleAiAgents() {
|
|
1480
|
-
|
|
1503
|
+
if (VERBOSE_AI_LOGS)
|
|
1504
|
+
console.log("[ai] getAgents called");
|
|
1481
1505
|
try {
|
|
1482
1506
|
const response = await opencodeClient.app.agents();
|
|
1483
1507
|
const data = requireData(response, "app.agents");
|
|
1484
|
-
|
|
1508
|
+
if (VERBOSE_AI_LOGS) {
|
|
1509
|
+
console.log("[ai] getAgents returned:", redactSensitive(JSON.stringify(data).substring(0, 300)));
|
|
1510
|
+
}
|
|
1485
1511
|
return { agents: data };
|
|
1486
1512
|
}
|
|
1487
1513
|
catch (err) {
|
|
@@ -1490,11 +1516,14 @@ async function handleAiAgents() {
|
|
|
1490
1516
|
}
|
|
1491
1517
|
}
|
|
1492
1518
|
async function handleAiProviders() {
|
|
1493
|
-
|
|
1519
|
+
if (VERBOSE_AI_LOGS)
|
|
1520
|
+
console.log("[ai] getProviders called");
|
|
1494
1521
|
try {
|
|
1495
1522
|
const response = await opencodeClient.config.providers();
|
|
1496
1523
|
const data = requireData(response, "config.providers");
|
|
1497
|
-
|
|
1524
|
+
if (VERBOSE_AI_LOGS) {
|
|
1525
|
+
console.log("[ai] getProviders returned", data.providers?.length, "providers, defaults:", redactSensitive(JSON.stringify(data.default)));
|
|
1526
|
+
}
|
|
1498
1527
|
return { providers: data.providers, default: data.default };
|
|
1499
1528
|
}
|
|
1500
1529
|
catch (err) {
|
|
@@ -1572,7 +1601,7 @@ async function subscribeToOpenCodeEvents(client) {
|
|
|
1572
1601
|
? parsed.payload
|
|
1573
1602
|
: parsed;
|
|
1574
1603
|
if (!base || typeof base.type !== "string") {
|
|
1575
|
-
console.warn("[sse] Dropped malformed event:", JSON.stringify(parsed).substring(0, 200));
|
|
1604
|
+
console.warn("[sse] Dropped malformed event:", redactSensitive(JSON.stringify(parsed).substring(0, 200)));
|
|
1576
1605
|
continue;
|
|
1577
1606
|
}
|
|
1578
1607
|
console.log("[sse]", base.type);
|
|
@@ -1784,7 +1813,7 @@ async function processMessage(message) {
|
|
|
1784
1813
|
}
|
|
1785
1814
|
// Validate required fields
|
|
1786
1815
|
if (!ns || !action) {
|
|
1787
|
-
console.warn("[router] Ignoring message with missing ns/action:", JSON.stringify(message).substring(0, 300));
|
|
1816
|
+
console.warn("[router] Ignoring message with missing ns/action:", redactSensitive(JSON.stringify(message).substring(0, 300)));
|
|
1788
1817
|
return {
|
|
1789
1818
|
v: 1,
|
|
1790
1819
|
id,
|
|
@@ -2198,7 +2227,11 @@ async function connectWebSocket() {
|
|
|
2198
2227
|
return;
|
|
2199
2228
|
}
|
|
2200
2229
|
if (message.type === "close_connection") {
|
|
2201
|
-
|
|
2230
|
+
const reason = message.reason || "expired";
|
|
2231
|
+
console.log(`[session] closed by gateway: ${reason}`);
|
|
2232
|
+
if (reason === "session ended from app") {
|
|
2233
|
+
console.log("[session] Run `npx lunel-cli` again and scan the new QR code to reconnect.");
|
|
2234
|
+
}
|
|
2202
2235
|
gracefulShutdown();
|
|
2203
2236
|
return;
|
|
2204
2237
|
}
|