howto

Command line parsing in typescript

its no thor but its ok

tags
typescript
cli
cmd-ts
1
2
3
4
  npm init -y
  npm install cmd-ts
  npm install -D @types/node tsx typescript @types/dotenv
  npx tsc --init

Test

1
console.log( "Hello from typescript" );
1
ts-node test.ts
Hello from typescript

Commands

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  
  // commands.ts
  import {
    command,
    run,
    string,
    positional,
    restPositionals,
    boolean,
    flag,
  } from "cmd-ts";

  const app = command({
    name: "app",
    args: {
      debug: flag({
        long: "debug",
        short: "d",
        type: boolean,
        description: "Enable debug mode",
        defaultValue: () => false,
      }),
      first: positional({ type: string, displayName: "first arg" }),
      rest: restPositionals({ type: string, displayName: "rest" }),
    },
    handler: ({ debug, first, rest }) => {
      console.log({ debug });
      console.log({ first });
      console.log({ rest });
    },
  });

  run(app, process.argv.slice(2));
1
ts-node commands.ts 2>&1
error: found 1 error

  1. No value provided for first arg

hint: for more information, try 'app --help'
1
  ts-node commands "first argument"
{ debug: false }
{ first: 'first argument' }
{ rest: [] }
1
  ts-node commands "first argument" -d everything else that i put in here
{ debug: true }
{ first: 'first argument' }
{ rest: [ 'everything', 'else', 'that', 'i', 'put', 'in', 'here' ] }

Subcommands

You can combind commands into subcommands, and build out a nice little cli app.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  import {
    command,
    run,
    string,
    restPositionals,
    option,
    subcommands,
  } from "cmd-ts";

  const models_list = command({
    name: "list",
    description: "List all models",
    args: {},
    handler: () => {
      console.log("list");
    },
  });

  const models_subcommand = subcommands({
    name: "models",
    description: "Manage models",
    cmds: {
      list: models_list,
    },
  });

  const run_prompt = command({
    name: "run",
    description: "Run a prompt",
    args: {
      model: option({
        long: "model",
        short: "m",
        description: "The model to use",
        defaultValue: () => "gpt-4o",
      }),
      prompt: restPositionals({ type: string, displayName: "prompt" }),
    },
    handler: ({ model, prompt }) => {
      console.log("model", model);
      console.log("prompt", prompt.join(" "));
    },
  });

  const app = subcommands({
    name: "app",
    cmds: { run: run_prompt, models: models_subcommand },
  });

  run(app, process.argv.slice(2)).catch(console.error);
1
  ts-node cli.ts
app <subcommand>

where <subcommand> can be one of:

- run - Run a prompt
- models - Manage models

For more help, try running `app <subcommand> --help`
1
  ts-node cli.ts models list
list
1
ts-node cli.ts run -m llama "This is my arg are I really like it"
model llama
prompt This is my arg are I really like it

Previously

labnotes

Using python venv in docker

ruby and python, sitting in a tree

tags
ruby
python
docker

Next

labnotes

Playing with Vercel AI SDK

is this easier than langchain?

tags
ai
javascript
vercel