lunel-cli 0.1.22 → 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.
Files changed (2) hide show
  1. package/dist/index.js +96 -17
  2. 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 { createOpencode } from "@opencode-ai/sdk";
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";
@@ -1171,35 +1172,72 @@ async function handleHttpRequest(payload) {
1171
1172
  // ============================================================================
1172
1173
  // AI Handlers (OpenCode SDK)
1173
1174
  // ============================================================================
1175
+ function requireData(response, label) {
1176
+ if (!response.data) {
1177
+ const errMsg = response.error
1178
+ ? (typeof response.error === "string" ? response.error : JSON.stringify(response.error))
1179
+ : `${label} returned no data`;
1180
+ console.error(`[ai] ${label} failed:`, errMsg, "raw response:", JSON.stringify(response).substring(0, 500));
1181
+ throw new Error(errMsg);
1182
+ }
1183
+ return response.data;
1184
+ }
1174
1185
  async function handleAiCreateSession(payload) {
1175
1186
  const title = payload.title || undefined;
1176
- const response = await opencodeClient.session.create({ body: { title } });
1177
- return { session: response.data };
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
+ }
1178
1197
  }
1179
1198
  async function handleAiListSessions() {
1180
- const response = await opencodeClient.session.list();
1181
- return { sessions: response.data };
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
+ }
1182
1210
  }
1183
1211
  async function handleAiGetSession(payload) {
1184
1212
  const id = payload.id;
1185
1213
  const response = await opencodeClient.session.get({ path: { id } });
1186
- return { session: response.data };
1214
+ return { session: requireData(response, "session.get") };
1187
1215
  }
1188
1216
  async function handleAiDeleteSession(payload) {
1189
1217
  const id = payload.id;
1190
- await opencodeClient.session.delete({ path: { id } });
1218
+ const response = await opencodeClient.session.delete({ path: { id } });
1219
+ if (response.error)
1220
+ throw new Error(JSON.stringify(response.error));
1191
1221
  return {};
1192
1222
  }
1193
1223
  async function handleAiGetMessages(payload) {
1194
1224
  const id = payload.id;
1195
- const response = await opencodeClient.session.messages({ path: { id } });
1196
- return { messages: response.data };
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
+ }
1197
1234
  }
1198
1235
  async function handleAiPrompt(payload) {
1199
1236
  const sessionId = payload.sessionId;
1200
1237
  const text = payload.text;
1201
1238
  const model = payload.model;
1202
1239
  const agent = payload.agent;
1240
+ console.log("[ai] prompt called, sessionId:", sessionId, "model:", JSON.stringify(model), "agent:", agent, "text:", text.substring(0, 100));
1203
1241
  // Fire and forget — results stream via SSE events forwarded on data channel
1204
1242
  opencodeClient.session.prompt({
1205
1243
  path: { id: sessionId },
@@ -1209,6 +1247,7 @@ async function handleAiPrompt(payload) {
1209
1247
  ...(agent ? { agent } : {}),
1210
1248
  },
1211
1249
  }).catch((err) => {
1250
+ console.error("[ai] prompt error:", err.message);
1212
1251
  if (dataChannel && dataChannel.readyState === WebSocket.OPEN) {
1213
1252
  dataChannel.send(JSON.stringify({
1214
1253
  v: 1,
@@ -1230,12 +1269,30 @@ async function handleAiAbort(payload) {
1230
1269
  return {};
1231
1270
  }
1232
1271
  async function handleAiAgents() {
1233
- const response = await opencodeClient.app.agents();
1234
- return { agents: response.data };
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
+ }
1235
1283
  }
1236
1284
  async function handleAiProviders() {
1237
- const response = await opencodeClient.config.providers();
1238
- return { providers: response.data };
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
+ }
1239
1296
  }
1240
1297
  async function handleAiSetAuth(payload) {
1241
1298
  const providerId = payload.providerId;
@@ -1254,7 +1311,7 @@ async function handleAiCommand(payload) {
1254
1311
  path: { id: sessionId },
1255
1312
  body: { command, arguments: args },
1256
1313
  });
1257
- return { result: response.data };
1314
+ return { result: response.data ?? null };
1258
1315
  }
1259
1316
  async function handleAiRevert(payload) {
1260
1317
  const sessionId = payload.sessionId;
@@ -1273,7 +1330,7 @@ async function handleAiUnrevert(payload) {
1273
1330
  async function handleAiShare(payload) {
1274
1331
  const sessionId = payload.sessionId;
1275
1332
  const response = await opencodeClient.session.share({ path: { id: sessionId } });
1276
- return { share: response.data };
1333
+ return { share: requireData(response, "session.share") };
1277
1334
  }
1278
1335
  async function handleAiPermissionReply(payload) {
1279
1336
  const permissionId = payload.permissionId;
@@ -1698,6 +1755,7 @@ async function processMessage(message) {
1698
1755
  }
1699
1756
  catch (error) {
1700
1757
  const err = error;
1758
+ console.error(`[router] ${ns}.${action} error:`, err.code || "ERROR", err.message);
1701
1759
  return {
1702
1760
  v: 1,
1703
1761
  id,
@@ -1867,9 +1925,28 @@ async function main() {
1867
1925
  console.log("Lunel CLI v" + VERSION);
1868
1926
  console.log("=".repeat(20) + "\n");
1869
1927
  try {
1870
- // Start OpenCode server + client
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)
1871
1936
  console.log("Starting OpenCode...");
1872
- const { client } = await createOpencode();
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
+ });
1873
1950
  opencodeClient = client;
1874
1951
  console.log("OpenCode ready.\n");
1875
1952
  // Subscribe to OpenCode events
@@ -1881,6 +1958,8 @@ async function main() {
1881
1958
  catch (error) {
1882
1959
  if (error instanceof Error) {
1883
1960
  console.error(`Error: ${error.message}`);
1961
+ if (error.stack)
1962
+ console.error(error.stack);
1884
1963
  }
1885
1964
  else {
1886
1965
  console.error("An unexpected error occurred");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lunel-cli",
3
- "version": "0.1.22",
3
+ "version": "0.1.26",
4
4
  "author": [
5
5
  {
6
6
  "name": "Soham Bharambe",