mirror of
https://github.com/abhagsain/ai-cli.git
synced 2024-10-03 21:47:36 +03:00
feat: ✅ add gpt3
This commit is contained in:
commit
103e9a1733
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@ -0,0 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@ -0,0 +1 @@
|
||||
/dist
|
22
.github/dependabot.yml
vendored
Normal file
22
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
day: 'saturday'
|
||||
versioning-strategy: 'increase'
|
||||
labels:
|
||||
- 'dependencies'
|
||||
open-pull-requests-limit: 5
|
||||
pull-request-branch-name:
|
||||
separator: '-'
|
||||
commit-message:
|
||||
# cause a release for non-dev-deps
|
||||
prefix: fix(deps)
|
||||
# no release for dev-deps
|
||||
prefix-development: chore(dev-deps)
|
||||
ignore:
|
||||
- dependency-name: '@salesforce/dev-scripts'
|
||||
- dependency-name: '*'
|
||||
update-types: ['version-update:semver-major']
|
10
.github/workflows/automerge.yml
vendored
Normal file
10
.github/workflows/automerge.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
name: automerge
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '17 2,5,8,11 * * *'
|
||||
|
||||
jobs:
|
||||
automerge:
|
||||
uses: oclif/github-workflows/.github/workflows/automerge.yml@main
|
||||
secrets: inherit
|
43
.github/workflows/failureNotifications.yml
vendored
Normal file
43
.github/workflows/failureNotifications.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: failureNotifications
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- version, tag and github release
|
||||
- publish
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
failure-notify:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
|
||||
steps:
|
||||
- name: Announce Failure
|
||||
id: slack
|
||||
uses: slackapi/slack-github-action@v1.21.0
|
||||
env:
|
||||
# for non-CLI-team-owned plugins, you can send this anywhere you like
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.CLI_ALERTS_SLACK_WEBHOOK }}
|
||||
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
|
||||
with:
|
||||
payload: |
|
||||
{
|
||||
"text": "${{ github.event.workflow_run.name }} failed: ${{ github.event.workflow_run.repository.name }}",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "header",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": ":bh-alert: ${{ github.event.workflow_run.name }} failed: ${{ github.event.workflow_run.repository.name }} :bh-alert:"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Repo: ${{ github.event.workflow_run.repository.html_url }}\nWorkflow name: `${{ github.event.workflow_run.name }}`\nJob url: ${{ github.event.workflow_run.html_url }}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
36
.github/workflows/manualRelease.yml
vendored
Normal file
36
.github/workflows/manualRelease.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
name: manual release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }}
|
||||
- name: Conventional Changelog Action
|
||||
id: changelog
|
||||
uses: TriPSs/conventional-changelog-action@d360fad3a42feca6462f72c97c165d60a02d4bf2
|
||||
# overriding some of the basic behaviors to just get the changelog
|
||||
with:
|
||||
git-user-name: svc-cli-bot
|
||||
git-user-email: svc_cli_bot@salesforce.com
|
||||
github-token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }}
|
||||
output-file: false
|
||||
# always do the release, even if there are no semantic commits
|
||||
skip-on-empty: false
|
||||
tag-prefix: ''
|
||||
- uses: notiz-dev/github-action-json-property@2192e246737701f108a4571462b76c75e7376216
|
||||
id: packageVersion
|
||||
with:
|
||||
path: 'package.json'
|
||||
prop_path: 'version'
|
||||
- name: Create Github Release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.packageVersion.outputs.prop }}
|
||||
release_name: ${{ steps.packageVersion.outputs.prop }}
|
23
.github/workflows/notify-slack-on-pr-open.yml
vendored
Normal file
23
.github/workflows/notify-slack-on-pr-open.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
name: Pull Request Slack Notification
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify Slack on PR open
|
||||
env:
|
||||
WEBHOOK_URL : ${{ secrets.CLI_TEAM_SLACK_WEBHOOK_URL }}
|
||||
PULL_REQUEST_AUTHOR_ICON_URL : ${{ github.event.pull_request.user.avatar_url }}
|
||||
PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }}
|
||||
PULL_REQUEST_AUTHOR_PROFILE_URL: ${{ github.event.pull_request.user.html_url }}
|
||||
PULL_REQUEST_BASE_BRANCH_NAME : ${{ github.event.pull_request.base.ref }}
|
||||
PULL_REQUEST_COMPARE_BRANCH_NAME : ${{ github.event.pull_request.head.ref }}
|
||||
PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }}
|
||||
PULL_REQUEST_REPO: ${{ github.event.pull_request.head.repo.name }}
|
||||
PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }}
|
||||
PULL_REQUEST_URL : ${{ github.event.pull_request.html_url }}
|
||||
uses: salesforcecli/github-workflows/.github/actions/prNotification@main
|
18
.github/workflows/onPushToMain.yml
vendored
Normal file
18
.github/workflows/onPushToMain.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# test
|
||||
name: version, tag and github release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
uses: oclif/github-workflows/.github/workflows/githubRelease.yml@main
|
||||
secrets: inherit
|
||||
|
||||
# most repos won't use this
|
||||
# depends on previous job to avoid git collisions, not for any functionality reason
|
||||
# docs:
|
||||
# uses: salesforcecli/github-workflows/.github/workflows/publishTypedoc.yml@main
|
||||
# secrets: inherit
|
||||
# needs: release
|
19
.github/workflows/onRelease.yml
vendored
Normal file
19
.github/workflows/onRelease.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
# support manual release in case something goes wrong and needs to be repeated or tested
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: tag that needs to publish
|
||||
type: string
|
||||
required: true
|
||||
jobs:
|
||||
npm:
|
||||
uses: oclif/github-workflows/.github/workflows/npmPublish.yml@main
|
||||
with:
|
||||
tag: latest
|
||||
githubTag: ${{ github.event.release.tag_name || inputs.tag }}
|
||||
secrets: inherit
|
9
.github/workflows/test.yml
vendored
Normal file
9
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
name: tests
|
||||
on:
|
||||
push:
|
||||
branches-ignore: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
uses: oclif/github-workflows/.github/workflows/unitTest.yml@main
|
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
*-debug.log
|
||||
*-error.log
|
||||
/.nyc_output
|
||||
/dist
|
||||
/lib
|
||||
/package-lock.json
|
||||
/tmp
|
||||
/yarn.lock
|
||||
node_modules
|
||||
oclif.manifest.json
|
||||
.env
|
12
.mocharc.json
Normal file
12
.mocharc.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"require": [
|
||||
"test/helpers/init.js",
|
||||
"ts-node/register"
|
||||
],
|
||||
"watch-extensions": [
|
||||
"ts"
|
||||
],
|
||||
"recursive": true,
|
||||
"reporter": "spec",
|
||||
"timeout": 60000
|
||||
}
|
18
.vscode/launch.json
vendored
Normal file
18
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Execute Command",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}/bin/dev",
|
||||
"args": [
|
||||
"hello",
|
||||
"world",
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Salesforce
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
334
README.md
Normal file
334
README.md
Normal file
@ -0,0 +1,334 @@
|
||||
oclif-hello-world
|
||||
=================
|
||||
|
||||
oclif example Hello World CLI
|
||||
|
||||
[![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io)
|
||||
[![Version](https://img.shields.io/npm/v/oclif-hello-world.svg)](https://npmjs.org/package/oclif-hello-world)
|
||||
[![CircleCI](https://circleci.com/gh/oclif/hello-world/tree/main.svg?style=shield)](https://circleci.com/gh/oclif/hello-world/tree/main)
|
||||
[![Downloads/week](https://img.shields.io/npm/dw/oclif-hello-world.svg)](https://npmjs.org/package/oclif-hello-world)
|
||||
[![License](https://img.shields.io/npm/l/oclif-hello-world.svg)](https://github.com/oclif/hello-world/blob/main/package.json)
|
||||
|
||||
<!-- toc -->
|
||||
* [Usage](#usage)
|
||||
* [Commands](#commands)
|
||||
<!-- tocstop -->
|
||||
# Usage
|
||||
<!-- usage -->
|
||||
```sh-session
|
||||
$ npm install -g ai-cli
|
||||
$ ai COMMAND
|
||||
running command...
|
||||
$ ai (--version)
|
||||
ai-cli/0.0.0 darwin-x64 node-v14.18.3
|
||||
$ ai --help [COMMAND]
|
||||
USAGE
|
||||
$ ai COMMAND
|
||||
...
|
||||
```
|
||||
<!-- usagestop -->
|
||||
# Commands
|
||||
<!-- commands -->
|
||||
* [`ai hello PERSON`](#ai-hello-person)
|
||||
* [`ai hello world`](#ai-hello-world)
|
||||
* [`ai help [COMMAND]`](#ai-help-command)
|
||||
* [`ai plugins`](#ai-plugins)
|
||||
* [`ai plugins:install PLUGIN...`](#ai-pluginsinstall-plugin)
|
||||
* [`ai plugins:inspect PLUGIN...`](#ai-pluginsinspect-plugin)
|
||||
* [`ai plugins:install PLUGIN...`](#ai-pluginsinstall-plugin-1)
|
||||
* [`ai plugins:link PLUGIN`](#ai-pluginslink-plugin)
|
||||
* [`ai plugins:uninstall PLUGIN...`](#ai-pluginsuninstall-plugin)
|
||||
* [`ai plugins:uninstall PLUGIN...`](#ai-pluginsuninstall-plugin-1)
|
||||
* [`ai plugins:uninstall PLUGIN...`](#ai-pluginsuninstall-plugin-2)
|
||||
* [`ai plugins update`](#ai-plugins-update)
|
||||
|
||||
## `ai hello PERSON`
|
||||
|
||||
Say hello
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai hello [PERSON] -f <value>
|
||||
|
||||
ARGUMENTS
|
||||
PERSON Person to say hello to
|
||||
|
||||
FLAGS
|
||||
-f, --from=<value> (required) Who is saying hello
|
||||
|
||||
DESCRIPTION
|
||||
Say hello
|
||||
|
||||
EXAMPLES
|
||||
$ oex hello friend --from oclif
|
||||
hello friend from oclif! (./src/commands/hello/index.ts)
|
||||
```
|
||||
|
||||
_See code: [dist/commands/hello/index.ts](https://github.com/abhagsain/ai-cli/blob/v0.0.0/dist/commands/hello/index.ts)_
|
||||
|
||||
## `ai hello world`
|
||||
|
||||
Say hello world
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai hello world
|
||||
|
||||
DESCRIPTION
|
||||
Say hello world
|
||||
|
||||
EXAMPLES
|
||||
$ ai hello world
|
||||
hello world! (./src/commands/hello/world.ts)
|
||||
```
|
||||
|
||||
## `ai help [COMMAND]`
|
||||
|
||||
Display help for ai.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai help [COMMAND] [-n]
|
||||
|
||||
ARGUMENTS
|
||||
COMMAND Command to show help for.
|
||||
|
||||
FLAGS
|
||||
-n, --nested-commands Include all nested commands in the output.
|
||||
|
||||
DESCRIPTION
|
||||
Display help for ai.
|
||||
```
|
||||
|
||||
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.17/src/commands/help.ts)_
|
||||
|
||||
## `ai plugins`
|
||||
|
||||
List installed plugins.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins [--core]
|
||||
|
||||
FLAGS
|
||||
--core Show core plugins.
|
||||
|
||||
DESCRIPTION
|
||||
List installed plugins.
|
||||
|
||||
EXAMPLES
|
||||
$ ai plugins
|
||||
```
|
||||
|
||||
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.1.6/src/commands/plugins/index.ts)_
|
||||
|
||||
## `ai plugins:install PLUGIN...`
|
||||
|
||||
Installs a plugin into the CLI.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins:install PLUGIN...
|
||||
|
||||
ARGUMENTS
|
||||
PLUGIN Plugin to install.
|
||||
|
||||
FLAGS
|
||||
-f, --force Run yarn install with force flag.
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Installs a plugin into the CLI.
|
||||
Can be installed from npm or a git url.
|
||||
|
||||
Installation of a user-installed plugin will override a core plugin.
|
||||
|
||||
e.g. If you have a core plugin that has a 'hello' command, installing a user-installed plugin with a 'hello' command
|
||||
will override the core plugin implementation. This is useful if a user needs to update core plugin functionality in
|
||||
the CLI without the need to patch and update the whole CLI.
|
||||
|
||||
|
||||
ALIASES
|
||||
$ ai plugins add
|
||||
|
||||
EXAMPLES
|
||||
$ ai plugins:install myplugin
|
||||
|
||||
$ ai plugins:install https://github.com/someuser/someplugin
|
||||
|
||||
$ ai plugins:install someuser/someplugin
|
||||
```
|
||||
|
||||
## `ai plugins:inspect PLUGIN...`
|
||||
|
||||
Displays installation properties of a plugin.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins:inspect PLUGIN...
|
||||
|
||||
ARGUMENTS
|
||||
PLUGIN [default: .] Plugin to inspect.
|
||||
|
||||
FLAGS
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Displays installation properties of a plugin.
|
||||
|
||||
EXAMPLES
|
||||
$ ai plugins:inspect myplugin
|
||||
```
|
||||
|
||||
## `ai plugins:install PLUGIN...`
|
||||
|
||||
Installs a plugin into the CLI.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins:install PLUGIN...
|
||||
|
||||
ARGUMENTS
|
||||
PLUGIN Plugin to install.
|
||||
|
||||
FLAGS
|
||||
-f, --force Run yarn install with force flag.
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Installs a plugin into the CLI.
|
||||
Can be installed from npm or a git url.
|
||||
|
||||
Installation of a user-installed plugin will override a core plugin.
|
||||
|
||||
e.g. If you have a core plugin that has a 'hello' command, installing a user-installed plugin with a 'hello' command
|
||||
will override the core plugin implementation. This is useful if a user needs to update core plugin functionality in
|
||||
the CLI without the need to patch and update the whole CLI.
|
||||
|
||||
|
||||
ALIASES
|
||||
$ ai plugins add
|
||||
|
||||
EXAMPLES
|
||||
$ ai plugins:install myplugin
|
||||
|
||||
$ ai plugins:install https://github.com/someuser/someplugin
|
||||
|
||||
$ ai plugins:install someuser/someplugin
|
||||
```
|
||||
|
||||
## `ai plugins:link PLUGIN`
|
||||
|
||||
Links a plugin into the CLI for development.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins:link PLUGIN
|
||||
|
||||
ARGUMENTS
|
||||
PATH [default: .] path to plugin
|
||||
|
||||
FLAGS
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Links a plugin into the CLI for development.
|
||||
Installation of a linked plugin will override a user-installed or core plugin.
|
||||
|
||||
e.g. If you have a user-installed or core plugin that has a 'hello' command, installing a linked plugin with a 'hello'
|
||||
command will override the user-installed or core plugin implementation. This is useful for development work.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
$ ai plugins:link myplugin
|
||||
```
|
||||
|
||||
## `ai plugins:uninstall PLUGIN...`
|
||||
|
||||
Removes a plugin from the CLI.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins:uninstall PLUGIN...
|
||||
|
||||
ARGUMENTS
|
||||
PLUGIN plugin to uninstall
|
||||
|
||||
FLAGS
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Removes a plugin from the CLI.
|
||||
|
||||
ALIASES
|
||||
$ ai plugins unlink
|
||||
$ ai plugins remove
|
||||
```
|
||||
|
||||
## `ai plugins:uninstall PLUGIN...`
|
||||
|
||||
Removes a plugin from the CLI.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins:uninstall PLUGIN...
|
||||
|
||||
ARGUMENTS
|
||||
PLUGIN plugin to uninstall
|
||||
|
||||
FLAGS
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Removes a plugin from the CLI.
|
||||
|
||||
ALIASES
|
||||
$ ai plugins unlink
|
||||
$ ai plugins remove
|
||||
```
|
||||
|
||||
## `ai plugins:uninstall PLUGIN...`
|
||||
|
||||
Removes a plugin from the CLI.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins:uninstall PLUGIN...
|
||||
|
||||
ARGUMENTS
|
||||
PLUGIN plugin to uninstall
|
||||
|
||||
FLAGS
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Removes a plugin from the CLI.
|
||||
|
||||
ALIASES
|
||||
$ ai plugins unlink
|
||||
$ ai plugins remove
|
||||
```
|
||||
|
||||
## `ai plugins update`
|
||||
|
||||
Update installed plugins.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ ai plugins update [-h] [-v]
|
||||
|
||||
FLAGS
|
||||
-h, --help Show CLI help.
|
||||
-v, --verbose
|
||||
|
||||
DESCRIPTION
|
||||
Update installed plugins.
|
||||
```
|
||||
<!-- commandsstop -->
|
17
bin/dev
Executable file
17
bin/dev
Executable file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const oclif = require('@oclif/core')
|
||||
|
||||
const path = require('path')
|
||||
const project = path.join(__dirname, '..', 'tsconfig.json')
|
||||
|
||||
// In dev mode -> use ts-node and dev plugins
|
||||
process.env.NODE_ENV = 'development'
|
||||
|
||||
require('ts-node').register({project})
|
||||
|
||||
// In dev mode, always show stack traces
|
||||
oclif.settings.debug = true;
|
||||
|
||||
// Start the CLI
|
||||
oclif.run().then(oclif.flush).catch(oclif.Errors.handle)
|
3
bin/dev.cmd
Normal file
3
bin/dev.cmd
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
|
||||
node "%~dp0\dev" %*
|
5
bin/run
Executable file
5
bin/run
Executable file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const oclif = require('@oclif/core')
|
||||
|
||||
oclif.run().then(require('@oclif/core/flush')).catch(require('@oclif/core/handle'))
|
3
bin/run.cmd
Normal file
3
bin/run.cmd
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
|
||||
node "%~dp0\run" %*
|
78
package.json
Normal file
78
package.json
Normal file
@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "ai-cli",
|
||||
"version": "0.0.0",
|
||||
"description": "oclif example Hello World CLI",
|
||||
"author": "Anurag Bhagsain @abhagsain",
|
||||
"bin": {
|
||||
"ai": "./bin/run"
|
||||
},
|
||||
"homepage": "https://github.com/abhagsain/ai-cli",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"repository": "abhagsain/ai-cli",
|
||||
"files": [
|
||||
"/bin",
|
||||
"/dist",
|
||||
"/npm-shrinkwrap.json",
|
||||
"/oclif.manifest.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@oclif/core": "^1.19.1",
|
||||
"@oclif/plugin-help": "^5",
|
||||
"@oclif/plugin-plugins": "^2.1.6",
|
||||
"chalk": "^4.1.2",
|
||||
"clipboardy": "^3.0.0",
|
||||
"inquirer": "^8.2.2",
|
||||
"openai": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@oclif/test": "^2.2.8",
|
||||
"@types/chai": "^4",
|
||||
"@types/clipboardy": "^2.0.1",
|
||||
"@types/inquirer": "^8.2.1",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^16.18.3",
|
||||
"chai": "^4",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-oclif": "^4",
|
||||
"eslint-config-oclif-typescript": "^1.0.3",
|
||||
"mocha": "^9",
|
||||
"oclif": "^3",
|
||||
"shx": "^0.3.3",
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"oclif": {
|
||||
"bin": "ai",
|
||||
"dirname": "ai",
|
||||
"commands": "./dist/commands",
|
||||
"plugins": [
|
||||
"@oclif/plugin-help",
|
||||
"@oclif/plugin-plugins"
|
||||
],
|
||||
"topicSeparator": " ",
|
||||
"topics": {
|
||||
"hello": {
|
||||
"description": "Say hello to the world and others"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "shx rm -rf dist && tsc -b",
|
||||
"lint": "eslint . --ext .ts --config .eslintrc",
|
||||
"postpack": "shx rm -f oclif.manifest.json",
|
||||
"posttest": "yarn lint",
|
||||
"prepack": "yarn build && oclif manifest && oclif readme",
|
||||
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
||||
"version": "oclif readme && git add README.md"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"bugs": "https://github.com/abhagsain/ai-cli/issues",
|
||||
"keywords": [
|
||||
"oclif"
|
||||
],
|
||||
"types": "dist/index.d.ts"
|
||||
}
|
131
src/commands/ai/index.ts
Normal file
131
src/commands/ai/index.ts
Normal file
@ -0,0 +1,131 @@
|
||||
import { Command, CliUx } from "@oclif/core";
|
||||
import * as inquirer from "inquirer";
|
||||
const { Configuration, OpenAIApi } = require("openai");
|
||||
// import clipboardy from "clipboardy";
|
||||
import chalk from "chalk";
|
||||
|
||||
export default class AI extends Command {
|
||||
static description = "Say hello";
|
||||
|
||||
static examples = [
|
||||
`$ oex hello friend --from oclif
|
||||
hello friend from oclif! (./src/commands/hello/index.ts)
|
||||
`,
|
||||
];
|
||||
|
||||
static args = [
|
||||
{
|
||||
name: "question",
|
||||
description: "Your question. Eg. Check process running on a port",
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
async getAnswers(question: string): Promise<any> {
|
||||
const configuration = new Configuration({
|
||||
apiKey:
|
||||
|
||||
process.env.OPENAI_API_KEY,
|
||||
});
|
||||
const openai = new OpenAIApi(configuration);
|
||||
const response = await openai.createCompletion({
|
||||
model: "text-davinci-002",
|
||||
prompt:
|
||||
'Correctly answer the asked question. Return \'Sorry, Can\'t answer that.\' if the question isn\'t related to technology.\n\nQ - get into a docker container.\nA - `docker exec -it mongodb`\n\nQ - Check what\'s listening on a port.\nA - `lsof -i tcp:4000`\n\nQ - How to ssh into a server with a specific file.\nA - `ssh -i ~/.ssh/id_rsa user@127.0.0.1`\n\nQ - How to set relative line numbers in vim.\nA - `:set relativenumber`\n\nQ - How to create alias?\nA - `alias my_command="my_real_command"`\n\nQ - Tail docker logs.\nA - `docker logs -f mongodb`\n\nQ - Forward port in kubectl.\nA - `kubectl port-forward <pod_name> 8080:3000`\n\nQ - Check if a port is accessible.\nA - `nc -vz host port`\n\nQ - Reverse SSH Tunnel Syntax.\nA - `ssh -R <remote_port>:<local_host>:<local_port> <user>@<remote_host>`\n\nQ - Kill a process running on port 3000.\nA - `lsof -ti tcp:3000 | xargs kill`\n\nQ - Backup database from a mongodb container.\nA - `docker exec -it mongodb bash -c "mongoexport --db mongodb --collection collections --outdir backup"`\n\nQ - SSH Tunnel Remote Host port into a local port.\nA - `ssh -L <local_port>:<remote_host>:<remote_port> <user>@<remote_host>`\n\nQ - Copy local file to S3.\nA - `aws s3 cp <local_file> s3://<bucket_name>/<remote_file>`\n\nQ - Copy S3 file to local.\nA - `aws s3 cp s3://<bucket_name>/<remote_file> <local_file>`\n\nQ - Recursively remove a folder.\nA - `rm -rf <folder_name>`\n\nQ - Copy a file from local to ssh server.\nA - ` scp /path/to/file user@server:/path/to/destination`\n\nQ - Curl syntax with port.\nA - `curl http://localhost:3000`\n\nQ - Download a file from a URL with curl.\nA - `curl -o <file_name> <URL>`\n\nQ - Git commit with message.\nA - `git commit -m "my commit message"`\n\nQ - Give a user sudo permissions.\nA - `sudo usermod -aG sudo <user>`\n\nQ - Check what\'s running on a port?\nA - `lsof -i tcp:<port>`\n\nQ - View last 5 files from history\nA - `history | tail -5`\n\nQ - When was China founded?\nA - Sorry, Can\'t answer that.\n\nQ - Pass auth header with curl\nA - `curl -H "Authorization: Bearer <token>" <URL>`\n\nQ - Filter docker container with labels\nA - `docker ps --filter "label=<KEY>"`\n\nQ - When was Abraham Lincon born?\nA - Sorry, Can\'t answer that.\n\nQ - Get into a running kubernetes pod\nA - `kubectl exec -it <pod_name> bash`\n\nQ - Capital city of Ukrain?\nA - Sorry, Can\'t answer that.\n\nQ - ' +
|
||||
question.trim() +
|
||||
"\nA - ",
|
||||
temperature: 0.8,
|
||||
max_tokens: 64,
|
||||
top_p: 1,
|
||||
frequency_penalty: 0.5,
|
||||
presence_penalty: 0,
|
||||
stop: ['"""'],
|
||||
});
|
||||
const code = /`(.*?)`/;
|
||||
const value = response.data.choices[0].text.trim();
|
||||
const match = value.match(code)?.length > 1 ? value.match(code)[1] : value;
|
||||
return match;
|
||||
}
|
||||
|
||||
async showStuff(answer: string): Promise<void> {
|
||||
const options = ["Copy to clipboard", "Exit"];
|
||||
const choices = [
|
||||
...options,
|
||||
// ...[answer].map((value) => `Run command ${value}`),
|
||||
// "Exit",
|
||||
];
|
||||
|
||||
const r: any = await inquirer.prompt([
|
||||
{
|
||||
name: "command",
|
||||
message: "Select an option",
|
||||
type: "list",
|
||||
choices,
|
||||
// choices: ['one', 'two', 'three'],
|
||||
},
|
||||
]);
|
||||
|
||||
const command = r.command;
|
||||
switch (command) {
|
||||
case "Copy to clipboard": {
|
||||
const clipboardy = (await import("clipboardy")).default;
|
||||
clipboardy.writeSync(answer);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
return;
|
||||
}
|
||||
// default:
|
||||
// console.log("Running command", command);
|
||||
// const clipboardy = (await import("clipboardy")).default;
|
||||
// exec(answer, (error: any, stdout: any, stderr: any) => {
|
||||
// if (error) {
|
||||
// console.log(`error: ${error.message}`);
|
||||
// return;
|
||||
// }
|
||||
// if (stderr) {
|
||||
// console.log(`stderr: ${stderr}`);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// clipboardy.writeSync(answer);
|
||||
// });
|
||||
// // break;
|
||||
}
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
const responses: any = await inquirer.prompt([
|
||||
{
|
||||
name: "question",
|
||||
message: "Enter the question",
|
||||
type: "input",
|
||||
validate(value) {
|
||||
if (!value.length) return "Please enter a question";
|
||||
return true;
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const question = responses.question;
|
||||
CliUx.ux.action.start("⌛");
|
||||
const answer = await this.getAnswers(question);
|
||||
CliUx.ux.action.stop("");
|
||||
if (answer.toLowerCase().startsWith("sorry")) {
|
||||
this.log(answer);
|
||||
return;
|
||||
}
|
||||
this.log(
|
||||
`> ${chalk.green(`Command is`)} ${chalk.bold.yellowBright(
|
||||
`\`${answer}\``
|
||||
)}`
|
||||
);
|
||||
await this.showStuff((answer || "").trim());
|
||||
this.log(
|
||||
`${chalk.red(
|
||||
"Please don't run a command that you don't understand."
|
||||
)} ${chalk.underline.red("Especially destructive commands")} `
|
||||
);
|
||||
}
|
||||
}
|
1
src/index.ts
Normal file
1
src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export {run} from '@oclif/core'
|
10
test/commands/hello/index.test.ts
Normal file
10
test/commands/hello/index.test.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {expect, test} from '@oclif/test'
|
||||
|
||||
describe('hello', () => {
|
||||
test
|
||||
.stdout()
|
||||
.command(['hello', 'friend', '--from=oclif'])
|
||||
.it('runs hello cmd', ctx => {
|
||||
expect(ctx.stdout).to.contain('hello friend from oclif!')
|
||||
})
|
||||
})
|
10
test/commands/hello/world.test.ts
Normal file
10
test/commands/hello/world.test.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {expect, test} from '@oclif/test'
|
||||
|
||||
describe('hello world', () => {
|
||||
test
|
||||
.stdout()
|
||||
.command(['hello:world'])
|
||||
.it('runs hello world cmd', ctx => {
|
||||
expect(ctx.stdout).to.contain('hello world!')
|
||||
})
|
||||
})
|
6
test/helpers/init.js
Normal file
6
test/helpers/init.js
Normal file
@ -0,0 +1,6 @@
|
||||
const path = require('path')
|
||||
process.env.TS_NODE_PROJECT = path.resolve('test/tsconfig.json')
|
||||
process.env.NODE_ENV = 'development'
|
||||
|
||||
global.oclif = global.oclif || {}
|
||||
global.oclif.columns = 80
|
9
test/tsconfig.json
Normal file
9
test/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../tsconfig",
|
||||
"compilerOptions": {
|
||||
"noEmit": true
|
||||
},
|
||||
"references": [
|
||||
{"path": ".."}
|
||||
]
|
||||
}
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"importHelpers": true,
|
||||
"module": "Node16",
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"target": "es2019"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user