openhorizon-cli 1.0.3 → 1.0.5

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 +59 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -64,6 +64,23 @@ function appendHistory(entry) {
64
64
  function getHistoryPath() {
65
65
  return HISTORY_FILE;
66
66
  }
67
+ function getHistoryEntries() {
68
+ if (!fs2.existsSync(HISTORY_FILE)) {
69
+ return [];
70
+ }
71
+ try {
72
+ const raw = fs2.readFileSync(HISTORY_FILE, "utf-8");
73
+ return raw.split("\n").filter((line) => line.trim().length > 0).map((line) => {
74
+ try {
75
+ return JSON.parse(line);
76
+ } catch {
77
+ return null;
78
+ }
79
+ }).filter((entry) => entry !== null);
80
+ } catch {
81
+ return [];
82
+ }
83
+ }
67
84
 
68
85
  // src/update.ts
69
86
  import chalk from "chalk";
@@ -171,7 +188,7 @@ async function* streamCompletion(baseUrl, apiKey, model, messages) {
171
188
  Authorization: `Bearer ${apiKey}`,
172
189
  "x-api-key": apiKey,
173
190
  "x-client": "openhorizon-cli",
174
- "x-client-version": "1.0.3"
191
+ "x-client-version": "1.0.5"
175
192
  },
176
193
  body: JSON.stringify({ model, messages, stream: true })
177
194
  });
@@ -221,7 +238,7 @@ async function runChatLoop(options) {
221
238
  console.log(
222
239
  chalk2.gray(
223
240
  `
224
- Commands: ${chalk2.white("/model")} ${chalk2.white("/clear")} ${chalk2.white("/help")} ${chalk2.white("exit")}
241
+ Commands: ${chalk2.white("/model")} ${chalk2.white("/clear")} ${chalk2.white("/help")} ${chalk2.white("/version")} ${chalk2.white("/update")} ${chalk2.white("exit")}
225
242
  `
226
243
  )
227
244
  );
@@ -253,12 +270,12 @@ async function runChatLoop(options) {
253
270
  }
254
271
  if (trimmed === "/version") {
255
272
  console.log(chalk2.blue(`
256
- OpenHorizon CLI version: ${chalk2.bold("1.0.3")}
273
+ OpenHorizon CLI version: ${chalk2.bold("1.0.5")}
257
274
  `));
258
275
  continue;
259
276
  }
260
277
  if (trimmed === "/update") {
261
- await runUpdate("1.0.3");
278
+ await runUpdate("1.0.5");
262
279
  continue;
263
280
  }
264
281
  if (trimmed === "/model") {
@@ -289,9 +306,8 @@ async function runChatLoop(options) {
289
306
  console.log(chalk2.red(" \u276F No response received.\n"));
290
307
  break;
291
308
  }
292
- const rendered = String(await marked(fullResponse)).trimEnd();
293
- process.stdout.write(chalk2.green("\u276F ") + "\n");
294
- process.stdout.write(rendered + "\n");
309
+ const rendered = String(await marked(fullResponse)).trim();
310
+ process.stdout.write(chalk2.green("\u276F ") + rendered + "\n");
295
311
  const usageStr = promptTokens || completionTokens ? chalk2.dim(` \u2191${promptTokens} \u2193${completionTokens} tok \xB7 ${elapsed}s`) : chalk2.dim(` ${elapsed}s`);
296
312
  process.stdout.write(usageStr + "\n\n");
297
313
  appendHistory({
@@ -335,7 +351,7 @@ async function runChatLoop(options) {
335
351
  // src/index.ts
336
352
  dotenv.config();
337
353
  var program = new Command();
338
- var version = "1.0.3";
354
+ var version = "1.0.5";
339
355
  program.name("openhorizon").description("CLI to interact with OpenHorizon AI Models").version(version, "-v, --version", "Output the current version");
340
356
  program.command("version").description("Show the current CLI version").action(() => {
341
357
  console.log(chalk3.blue(`OpenHorizon CLI version: ${chalk3.bold(version)}`));
@@ -343,6 +359,41 @@ program.command("version").description("Show the current CLI version").action(()
343
359
  program.command("update").description("Check for and perform CLI updates").action(async () => {
344
360
  await runUpdate(version);
345
361
  });
362
+ program.command("history").description("Show local chat history").option("-l, --limit <number>", "Limit the number of messages to show", "50").option("--raw", "Show raw JSONL history").action((options) => {
363
+ const entries = getHistoryEntries();
364
+ if (entries.length === 0) {
365
+ console.log(chalk3.gray("\n No history found.\n"));
366
+ return;
367
+ }
368
+ if (options.raw) {
369
+ entries.slice(-Number(options.limit)).forEach((e) => console.log(JSON.stringify(e)));
370
+ return;
371
+ }
372
+ console.log(chalk3.bold.blue(`
373
+ Recent Chat History (last ${options.limit})
374
+ `));
375
+ const limit = Number(options.limit);
376
+ const subset = entries.slice(-limit);
377
+ subset.forEach((entry, i) => {
378
+ const date = new Date(entry.ts).toLocaleString([], {
379
+ month: "short",
380
+ day: "numeric",
381
+ hour: "2-digit",
382
+ minute: "2-digit"
383
+ });
384
+ const roleStr = entry.role === "user" ? chalk3.green("\u276F You") : chalk3.blue("\u276F Assistant");
385
+ const prevEntry = subset[i - 1];
386
+ if (!prevEntry || prevEntry.session !== entry.session) {
387
+ console.log(chalk3.dim(` \u2500\u2500 Session: ${entry.session.slice(0, 8)}\u2026 \u2500\u2500`));
388
+ }
389
+ console.log(`${chalk3.dim(date)} ${roleStr}`);
390
+ console.log(` ${entry.content.replace(/\n/g, "\n ")}`);
391
+ if (entry.usage) {
392
+ console.log(chalk3.dim(` tokens: \u2191${entry.usage.promptTokens} \u2193${entry.usage.completionTokens} \xB7 ${entry.latencyMs}ms`));
393
+ }
394
+ console.log("");
395
+ });
396
+ });
346
397
  program.command("chat", { isDefault: true }).description("Start an interactive chat session with the AI").option("-m, --model <model>", "Specify a model to use for this session").option("-b, --base-url <url>", "Base API URL (e.g. https://api.openhorizon.devwtf.in/v1)").action(async (options) => {
347
398
  const config = getConfig();
348
399
  await checkForUpdate(version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openhorizon-cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Official CLI for OpenHorizon — chat with AI models directly from your terminal",
5
5
  "type": "module",
6
6
  "bin": {