lunel-cli 0.1.23 → 0.1.26
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 +81 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { WebSocket } from "ws";
|
|
3
3
|
import qrcode from "qrcode-terminal";
|
|
4
|
-
import {
|
|
4
|
+
import { createOpencodeServer, createOpencodeClient } from "@opencode-ai/sdk";
|
|
5
|
+
import * as crypto from "crypto";
|
|
5
6
|
import Ignore from "ignore";
|
|
6
7
|
const ignore = Ignore.default;
|
|
7
8
|
import * as fs from "fs/promises";
|
|
@@ -1176,18 +1177,36 @@ function requireData(response, label) {
|
|
|
1176
1177
|
const errMsg = response.error
|
|
1177
1178
|
? (typeof response.error === "string" ? response.error : JSON.stringify(response.error))
|
|
1178
1179
|
: `${label} returned no data`;
|
|
1180
|
+
console.error(`[ai] ${label} failed:`, errMsg, "raw response:", JSON.stringify(response).substring(0, 500));
|
|
1179
1181
|
throw new Error(errMsg);
|
|
1180
1182
|
}
|
|
1181
1183
|
return response.data;
|
|
1182
1184
|
}
|
|
1183
1185
|
async function handleAiCreateSession(payload) {
|
|
1184
1186
|
const title = payload.title || undefined;
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
+
console.log("[ai] createSession called, title:", title);
|
|
1188
|
+
try {
|
|
1189
|
+
const response = await opencodeClient.session.create({ body: { title } });
|
|
1190
|
+
console.log("[ai] createSession response ok:", !!response.data, "error:", response.error ? JSON.stringify(response.error).substring(0, 200) : "none");
|
|
1191
|
+
return { session: requireData(response, "session.create") };
|
|
1192
|
+
}
|
|
1193
|
+
catch (err) {
|
|
1194
|
+
console.error("[ai] createSession exception:", err.message, err.stack);
|
|
1195
|
+
throw err;
|
|
1196
|
+
}
|
|
1187
1197
|
}
|
|
1188
1198
|
async function handleAiListSessions() {
|
|
1189
|
-
|
|
1190
|
-
|
|
1199
|
+
console.log("[ai] listSessions called");
|
|
1200
|
+
try {
|
|
1201
|
+
const response = await opencodeClient.session.list();
|
|
1202
|
+
const data = requireData(response, "session.list");
|
|
1203
|
+
console.log("[ai] listSessions returned", Array.isArray(data) ? data.length : typeof data, "sessions");
|
|
1204
|
+
return { sessions: data };
|
|
1205
|
+
}
|
|
1206
|
+
catch (err) {
|
|
1207
|
+
console.error("[ai] listSessions exception:", err.message);
|
|
1208
|
+
throw err;
|
|
1209
|
+
}
|
|
1191
1210
|
}
|
|
1192
1211
|
async function handleAiGetSession(payload) {
|
|
1193
1212
|
const id = payload.id;
|
|
@@ -1203,14 +1222,22 @@ async function handleAiDeleteSession(payload) {
|
|
|
1203
1222
|
}
|
|
1204
1223
|
async function handleAiGetMessages(payload) {
|
|
1205
1224
|
const id = payload.id;
|
|
1206
|
-
|
|
1207
|
-
|
|
1225
|
+
console.log("[ai] getMessages called, sessionId:", id);
|
|
1226
|
+
try {
|
|
1227
|
+
const response = await opencodeClient.session.messages({ path: { id } });
|
|
1228
|
+
return { messages: requireData(response, "session.messages") };
|
|
1229
|
+
}
|
|
1230
|
+
catch (err) {
|
|
1231
|
+
console.error("[ai] getMessages exception:", err.message);
|
|
1232
|
+
throw err;
|
|
1233
|
+
}
|
|
1208
1234
|
}
|
|
1209
1235
|
async function handleAiPrompt(payload) {
|
|
1210
1236
|
const sessionId = payload.sessionId;
|
|
1211
1237
|
const text = payload.text;
|
|
1212
1238
|
const model = payload.model;
|
|
1213
1239
|
const agent = payload.agent;
|
|
1240
|
+
console.log("[ai] prompt called, sessionId:", sessionId, "model:", JSON.stringify(model), "agent:", agent, "text:", text.substring(0, 100));
|
|
1214
1241
|
// Fire and forget — results stream via SSE events forwarded on data channel
|
|
1215
1242
|
opencodeClient.session.prompt({
|
|
1216
1243
|
path: { id: sessionId },
|
|
@@ -1220,6 +1247,7 @@ async function handleAiPrompt(payload) {
|
|
|
1220
1247
|
...(agent ? { agent } : {}),
|
|
1221
1248
|
},
|
|
1222
1249
|
}).catch((err) => {
|
|
1250
|
+
console.error("[ai] prompt error:", err.message);
|
|
1223
1251
|
if (dataChannel && dataChannel.readyState === WebSocket.OPEN) {
|
|
1224
1252
|
dataChannel.send(JSON.stringify({
|
|
1225
1253
|
v: 1,
|
|
@@ -1241,13 +1269,30 @@ async function handleAiAbort(payload) {
|
|
|
1241
1269
|
return {};
|
|
1242
1270
|
}
|
|
1243
1271
|
async function handleAiAgents() {
|
|
1244
|
-
|
|
1245
|
-
|
|
1272
|
+
console.log("[ai] getAgents called");
|
|
1273
|
+
try {
|
|
1274
|
+
const response = await opencodeClient.app.agents();
|
|
1275
|
+
const data = requireData(response, "app.agents");
|
|
1276
|
+
console.log("[ai] getAgents returned:", JSON.stringify(data).substring(0, 300));
|
|
1277
|
+
return { agents: data };
|
|
1278
|
+
}
|
|
1279
|
+
catch (err) {
|
|
1280
|
+
console.error("[ai] getAgents exception:", err.message);
|
|
1281
|
+
throw err;
|
|
1282
|
+
}
|
|
1246
1283
|
}
|
|
1247
1284
|
async function handleAiProviders() {
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1285
|
+
console.log("[ai] getProviders called");
|
|
1286
|
+
try {
|
|
1287
|
+
const response = await opencodeClient.config.providers();
|
|
1288
|
+
const data = requireData(response, "config.providers");
|
|
1289
|
+
console.log("[ai] getProviders returned", data.providers?.length, "providers, defaults:", JSON.stringify(data.default));
|
|
1290
|
+
return { providers: data.providers, default: data.default };
|
|
1291
|
+
}
|
|
1292
|
+
catch (err) {
|
|
1293
|
+
console.error("[ai] getProviders exception:", err.message);
|
|
1294
|
+
throw err;
|
|
1295
|
+
}
|
|
1251
1296
|
}
|
|
1252
1297
|
async function handleAiSetAuth(payload) {
|
|
1253
1298
|
const providerId = payload.providerId;
|
|
@@ -1710,6 +1755,7 @@ async function processMessage(message) {
|
|
|
1710
1755
|
}
|
|
1711
1756
|
catch (error) {
|
|
1712
1757
|
const err = error;
|
|
1758
|
+
console.error(`[router] ${ns}.${action} error:`, err.code || "ERROR", err.message);
|
|
1713
1759
|
return {
|
|
1714
1760
|
v: 1,
|
|
1715
1761
|
id,
|
|
@@ -1879,9 +1925,28 @@ async function main() {
|
|
|
1879
1925
|
console.log("Lunel CLI v" + VERSION);
|
|
1880
1926
|
console.log("=".repeat(20) + "\n");
|
|
1881
1927
|
try {
|
|
1882
|
-
//
|
|
1928
|
+
// Generate auth credentials (like CodeNomad does)
|
|
1929
|
+
const opencodeUsername = "lunel";
|
|
1930
|
+
const opencodePassword = crypto.randomBytes(32).toString("base64url");
|
|
1931
|
+
const authHeader = `Basic ${Buffer.from(`${opencodeUsername}:${opencodePassword}`).toString("base64")}`;
|
|
1932
|
+
// Set auth env vars BEFORE spawning opencode
|
|
1933
|
+
process.env.OPENCODE_SERVER_USERNAME = opencodeUsername;
|
|
1934
|
+
process.env.OPENCODE_SERVER_PASSWORD = opencodePassword;
|
|
1935
|
+
// Start OpenCode server with random port (like CodeNomad: --port 0)
|
|
1883
1936
|
console.log("Starting OpenCode...");
|
|
1884
|
-
const
|
|
1937
|
+
const server = await createOpencodeServer({
|
|
1938
|
+
hostname: "127.0.0.1",
|
|
1939
|
+
port: 0,
|
|
1940
|
+
timeout: 15000,
|
|
1941
|
+
});
|
|
1942
|
+
console.log(`OpenCode server listening on ${server.url}`);
|
|
1943
|
+
// Create client with auth headers
|
|
1944
|
+
const client = createOpencodeClient({
|
|
1945
|
+
baseUrl: server.url,
|
|
1946
|
+
headers: {
|
|
1947
|
+
"Authorization": authHeader,
|
|
1948
|
+
},
|
|
1949
|
+
});
|
|
1885
1950
|
opencodeClient = client;
|
|
1886
1951
|
console.log("OpenCode ready.\n");
|
|
1887
1952
|
// Subscribe to OpenCode events
|
|
@@ -1893,6 +1958,8 @@ async function main() {
|
|
|
1893
1958
|
catch (error) {
|
|
1894
1959
|
if (error instanceof Error) {
|
|
1895
1960
|
console.error(`Error: ${error.message}`);
|
|
1961
|
+
if (error.stack)
|
|
1962
|
+
console.error(error.stack);
|
|
1896
1963
|
}
|
|
1897
1964
|
else {
|
|
1898
1965
|
console.error("An unexpected error occurred");
|