Beautify Input and Output

listr - terminal task list


oclif utilities for input & output

import cli from 'cli-ux'
cli.prompt('What is your password?', {type: 'mask'})


Make a command to list Github tasks


Use @oclif/cli-ux or any other tools to

npx oclif command github:issues
my-oclif-cli github:issues
Getting a list of issues... done
Number Title                                      Assignee      State Link                                     
66     workshop CLI                               korzio        open 
65     fix: Changed the formatting of exercises   null          open   
64     Workshop CLI in TS on Saturday 9am 3 hours korzio        open 
63     Add test section and example to workshop   paulcodiny    open

Configure an access

1. Create a Personal token

2. Add it to the config file .githubrc to variable GITHUB_PERSONAL_TOKEN


3. Export this variable to the current shell with source command

source config/.githubrc

4. Use the auth key with @octokit/rest

5. Get the list of Github issues

Install NPM dependencies

npm i cli-ux chalk @octokit/rest

Write the code

1. Import cli from cli-ux to use advanced formatting

import cli from 'cli-ux'

2. Import chalk from chalk to use colors

import chalk from 'chalk'

3. Require the Octokit. This library is imported in a specific way

import Octokit = require('@octokit/rest')

4. Set a description for your command

static description = 'Get a list of issues'

5. Add arguments: one for an owner and for a repository

static args = [
    name: 'owner',
    required: false,
    description: 'An owner of a repository',
    default: 'korzio',
    name: 'repo',
    required: false,
    description: 'A repository',
    default: 'note',

6. Add a GITHUB_PERSONAL_TOKEN flag to flags definition so oclif will put the environment variable to a flag

static flags = {
    char: 'h'
  githubPersonalToken: flags.string({
    description: `Environment variable GITHUB_PERSONAL_TOKEN`,
    required: true

7. Use cli.action.start to show the loader with some useful information what is happening

cli.action.start('Getting the list of the issues')

8. Create a new instance of Octokit with an object argument containing the "auth" property with the auth key created in the previous section

const octokit = new Octokit({
  auth: flags.githubPersonalToken

9. Call the "issues.listForRepo" method with an object argument containing "owner" and "repo" keys. You can pass "korzio" as an owner and "note" as a repository. Documentation of the method
The result of this method is an object containing "data" property

const { data: issues } = await octokit.issues.listForRepo({
  owner: 'korzio',
  repo: 'note',

10. Stop the loader with cli.action.stop


11. Show tha table with the "data" as the first argument and the object with table description as the second. You can use columns "number", "title", "assignee" with a getter to get deep property, "state" with a getter to color the resulting state, "html_url" with a different header

cli.table(issues, {
  number: {},
  title: {},
  assignee: {
    get: row => row.assignee ? row.assignee.login : null,
  state: {
    get: row => row.state === 'open' ?'open') :'closed'),
  html_url: {
    header: 'Link'

spoiler alert

Get a list of issues code

Develop a command to change an assignee

Use @oclif/cli-ux - prompt() functionality.

my-oclif-cli github:assignee
Do you want to start working on an issue? (Y/n) [y]: y
Which issue you want to pick up? Please provide the ID: 62
What is your GitHub login?: paulcodiny

1. Ask whether the user wants to start working on an issue. Use capital letter to communicate the default choice even though oclif helps with this

const startWorking = await cli.prompt('Do you want to start working on an issue? (y/N)', {
  required: false,
  default: 'y'

2. If the choice is "y" then show additional promts

if (['y', 'yes'].includes(startWorking.toLowerCase())) {
  const issueNumber = await cli.prompt('Which issue you want to pick up? Please provide the Number')
  const assignee = await cli.prompt('What is your GitHub login?')
  // ...

3. After the CLI script gathers all required inputs we can perform an update

await octokit.issues.update({
  owner: args.owner,
  repo: args.repo,
  issue_number: issueNumber,
  assignees: [assignee]

4. Do not forget to communicate back the success message.

this.log(`Assignee of the issue #${issueNumber} has been successfully changed to "${assignee}"!`)

spoiler alert

Change an assignee code