@llmist/cli 9.1.1 → 9.2.0

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/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # @llmist/cli
2
+
3
+ <p align="center">
4
+ <a href="https://github.com/zbigniewsobiecki/llmist/actions/workflows/ci.yml"><img src="https://github.com/zbigniewsobiecki/llmist/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
5
+ <a href="https://www.npmjs.com/package/@llmist/cli"><img src="https://img.shields.io/npm/v/@llmist/cli.svg" alt="npm version"></a>
6
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License"></a>
7
+ </p>
8
+
9
+ **Command-line interface for llmist - run LLM agents from the terminal.**
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install -g @llmist/cli
15
+ # or
16
+ bunx @llmist/cli
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ # Set your API key
23
+ export OPENAI_API_KEY="sk-..."
24
+
25
+ # Quick completion
26
+ llmist complete "Explain TypeScript generics in one paragraph"
27
+
28
+ # Run an agent with gadgets
29
+ llmist agent "Search for files" --gadgets ./my-gadgets/
30
+
31
+ # Interactive chat
32
+ llmist chat
33
+ ```
34
+
35
+ ## Commands
36
+
37
+ | Command | Description |
38
+ |---------|-------------|
39
+ | `complete <prompt>` | One-shot LLM completion |
40
+ | `agent <prompt>` | Run agent with gadgets |
41
+ | `chat` | Interactive chat session |
42
+ | `tui` | Launch terminal UI |
43
+
44
+ ## Using Gadgets
45
+
46
+ Load gadgets from various sources:
47
+
48
+ ```bash
49
+ # Local directory
50
+ llmist agent "Do something" --gadgets ./gadgets/
51
+
52
+ # npm package
53
+ llmist agent "Search the web" --gadgets dhalsim/BrowseWeb
54
+
55
+ # Git URL
56
+ llmist agent "Process files" --gadgets github:user/repo
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ Create a `llmist.toml` file for reusable configurations:
62
+
63
+ ```toml
64
+ [agent]
65
+ model = "sonnet"
66
+ system = "You are a helpful assistant"
67
+
68
+ [gadgets]
69
+ paths = ["./gadgets"]
70
+ external = ["dhalsim/BrowseWeb"]
71
+
72
+ [display]
73
+ markdown = true
74
+ colors = true
75
+ ```
76
+
77
+ Use with:
78
+
79
+ ```bash
80
+ llmist agent "Do something" --config ./llmist.toml
81
+ ```
82
+
83
+ ## Terminal UI
84
+
85
+ The TUI provides an interactive interface to browse execution history, inspect raw payloads, and debug agent runs:
86
+
87
+ ```bash
88
+ llmist tui
89
+ ```
90
+
91
+ ## Documentation
92
+
93
+ Full documentation at [llmist.dev/cli](https://llmist.dev/cli/getting-started/introduction/)
94
+
95
+ - [Configuration Reference](https://llmist.dev/cli/configuration/toml-reference/)
96
+ - [Writing Gadgets](https://llmist.dev/cli/gadgets/local-gadgets/)
97
+ - [External Gadgets](https://llmist.dev/cli/gadgets/external-gadgets/)
98
+ - [TUI Guide](https://llmist.dev/cli/tui/overview/)
99
+
100
+ ## Related Packages
101
+
102
+ - [`llmist`](https://www.npmjs.com/package/llmist) - Core library
103
+ - [`@llmist/testing`](https://www.npmjs.com/package/@llmist/testing) - Testing utilities
104
+
105
+ ## License
106
+
107
+ MIT
package/dist/cli.js CHANGED
@@ -79,7 +79,7 @@ import { Command, InvalidArgumentError as InvalidArgumentError2 } from "commande
79
79
  // package.json
80
80
  var package_default = {
81
81
  name: "@llmist/cli",
82
- version: "9.1.1",
82
+ version: "9.2.0",
83
83
  description: "CLI for llmist - run LLM agents from the command line",
84
84
  type: "module",
85
85
  main: "dist/cli.js",
@@ -91,7 +91,8 @@ var package_default = {
91
91
  build: "tsup",
92
92
  typecheck: "tsc --noEmit",
93
93
  test: "bun test src",
94
- clean: "rimraf dist"
94
+ clean: "rimraf dist",
95
+ postinstall: "node scripts/postinstall.js"
95
96
  },
96
97
  repository: {
97
98
  type: "git",
@@ -102,7 +103,8 @@ var package_default = {
102
103
  access: "public"
103
104
  },
104
105
  files: [
105
- "dist"
106
+ "dist",
107
+ "scripts"
106
108
  ],
107
109
  keywords: [
108
110
  "llmist",
@@ -358,6 +360,84 @@ import { AbstractGadget } from "llmist";
358
360
  import { z as z2 } from "zod";
359
361
  import { createGadget as createGadget2 } from "llmist";
360
362
 
363
+ // src/spawn.ts
364
+ import { spawn as nodeSpawn } from "child_process";
365
+ var isBun = typeof Bun !== "undefined";
366
+ function adaptBunProcess(proc) {
367
+ return {
368
+ exited: proc.exited,
369
+ stdout: proc.stdout ?? null,
370
+ stderr: proc.stderr ?? null,
371
+ stdin: proc.stdin ? {
372
+ write(data) {
373
+ proc.stdin?.write(data);
374
+ },
375
+ end() {
376
+ proc.stdin?.end();
377
+ }
378
+ } : null,
379
+ kill: () => proc.kill()
380
+ };
381
+ }
382
+ function nodeStreamToReadableStream(nodeStream) {
383
+ if (!nodeStream) return null;
384
+ return new ReadableStream({
385
+ start(controller) {
386
+ nodeStream.on("data", (chunk) => {
387
+ controller.enqueue(new Uint8Array(chunk));
388
+ });
389
+ nodeStream.on("end", () => {
390
+ controller.close();
391
+ });
392
+ nodeStream.on("error", (err) => {
393
+ controller.error(err);
394
+ });
395
+ },
396
+ cancel() {
397
+ nodeStream.destroy();
398
+ }
399
+ });
400
+ }
401
+ function spawn(argv, options = {}) {
402
+ if (isBun) {
403
+ return adaptBunProcess(Bun.spawn(argv, options));
404
+ }
405
+ const [command, ...args] = argv;
406
+ const proc = nodeSpawn(command, args, {
407
+ cwd: options.cwd,
408
+ stdio: [
409
+ options.stdin === "pipe" ? "pipe" : options.stdin ?? "ignore",
410
+ options.stdout === "pipe" ? "pipe" : options.stdout ?? "ignore",
411
+ options.stderr === "pipe" ? "pipe" : options.stderr ?? "ignore"
412
+ ]
413
+ });
414
+ const exited = new Promise((resolve2, reject) => {
415
+ proc.on("exit", (code) => {
416
+ resolve2(code ?? 1);
417
+ });
418
+ proc.on("error", (err) => {
419
+ reject(err);
420
+ });
421
+ });
422
+ const stdin = proc.stdin ? {
423
+ write(data) {
424
+ proc.stdin?.write(data);
425
+ },
426
+ end() {
427
+ proc.stdin?.end();
428
+ }
429
+ } : null;
430
+ return {
431
+ exited,
432
+ stdout: nodeStreamToReadableStream(proc.stdout),
433
+ stderr: nodeStreamToReadableStream(proc.stderr),
434
+ stdin,
435
+ kill() {
436
+ proc.kill();
437
+ }
438
+ };
439
+ }
440
+
361
441
  // src/builtins/filesystem/utils.ts
362
442
  import fs from "fs";
363
443
  import path from "path";
@@ -447,11 +527,16 @@ q`
447
527
  const validatedPath = validatePathIsWithinCwd(filePath);
448
528
  const safeCommands = filterDangerousCommands(commands);
449
529
  try {
450
- const proc = Bun.spawn(["ed", validatedPath], {
530
+ const proc = spawn(["ed", validatedPath], {
451
531
  stdin: "pipe",
452
532
  stdout: "pipe",
453
533
  stderr: "pipe"
454
534
  });
535
+ if (!proc.stdin) {
536
+ return `path=${filePath}
537
+
538
+ error: Failed to open stdin for ed process`;
539
+ }
455
540
  proc.stdin.write(`${safeCommands}
456
541
  `);
457
542
  proc.stdin.end();
@@ -771,7 +856,7 @@ var runCommand = createGadget6({
771
856
  }
772
857
  let timeoutId;
773
858
  try {
774
- const proc = Bun.spawn(argv, {
859
+ const proc = spawn(argv, {
775
860
  cwd: workingDir,
776
861
  stdout: "pipe",
777
862
  stderr: "pipe"