diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..db7e797 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false + +[*.yml] +indent_style = space +indent_size = 4 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..880a57a --- /dev/null +++ b/.eslintignore @@ -0,0 +1,7 @@ +package.json +package-lock.json +pnpm-lock.yaml +dist +e2e/** +karma.conf.js +commitlint.config.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..4cc85e1 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,49 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint", "unused-imports", "import"], + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "globals": { "BigInt": true, "console": true, "WebAssembly": true }, + "rules": { + "@typescript-eslint/ban-ts-comment": [ + "error", + { + "ts-ignore": "allow-with-description" + } + ], + "import/order": [ + "error", + { + "groups": [ + "builtin", + "external", + "internal", + ["sibling", "parent", "index"], + "type", + "unknown" + ], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + }, + "newlines-between": "always" + } + ], + "no-unused-vars": "off", + "no-useless-escape": "off", + "@typescript-eslint/no-explicit-any": "off", + "curly": "error", + "unused-imports/no-unused-imports": "error", + "@typescript-eslint/no-unused-vars": "off", + "sort-imports": [ + "error", + { + "ignoreDeclarationSort": true, + "ignoreCase": false, + "ignoreMemberSort": false, + "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], + "allowSeparatedGroups": true + } + ], + "no-case-declarations": "off" + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..72d5178 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: tak-bro diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml new file mode 100644 index 0000000..554aa85 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml @@ -0,0 +1,56 @@ +name: Bug report +description: File a bug report +labels: [bug, pending triage] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to file this bug report. + - type: textarea + attributes: + label: Bug description + description: A clear and concise description of the bug. + placeholder: | + + validations: + required: true + - type: input + attributes: + label: aipick version + description: | + Run and paste the output of: + ```sh + aipick --version + ``` + placeholder: v0.0.0 + validations: + required: true + - type: textarea + attributes: + label: Environment + description: | + Run and paste the output of: + ```sh + npx envinfo --system --binaries + ``` + + This information is used to for reproduction and debugging. + placeholder: | + System: + OS: + CPU: + Shell: + Binaries: + Node: + npm: + render: shell + validations: + required: true + - type: checkboxes + attributes: + label: Can you contribute a fix? + description: We would love it if you can open a pull request to fix this bug! + options: + - label: I’m interested in opening a pull request for this issue. diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml new file mode 100644 index 0000000..e2de1d7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml @@ -0,0 +1,43 @@ +name: Feature request +description: Suggest an idea for this project +labels: [feature, pending triage] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to file this feature request. + - type: textarea + attributes: + label: Feature request + description: A description of the feature you would like. + validations: + required: true + - type: textarea + attributes: + label: Why? + description: | + Describe the problem you’re tackling with this feature request. + placeholder: | + + validations: + required: true + - type: textarea + attributes: + label: Alternatives + description: | + Have you considered alternative solutions? Is there a workaround? + placeholder: | + + - type: textarea + attributes: + label: Additional context + description: | + Anything else to share? Screenshots? Links? diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..7830cc6 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,14 @@ +### Issue +Issue number, if available, prefixed with "#" + +### Description +What does this implement/fix? Explain your changes. + +### Testing +How was this change tested? + +### Additional context +Add any other context about the PR here. + +--- +By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a37d5e2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,35 @@ +name: Release + +on: + push: + branches: [main] + +jobs: + release: + name: Release + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write + id-token: write + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version-file: '.nvmrc' + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: true + + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: pnpm dlx semantic-release diff --git a/.github/workflows/stale_issues.yml b/.github/workflows/stale_issues.yml new file mode 100644 index 0000000..25702cb --- /dev/null +++ b/.github/workflows/stale_issues.yml @@ -0,0 +1,45 @@ +name: "Close stale issues" + +# Controls when the action will run. +on: + schedule: + - cron: "0 0 * * *" + +jobs: + cleanup: + runs-on: ubuntu-latest + name: Stale issue job + steps: + - uses: aws-actions/stale-issue-cleanup@v3 + with: + # Setting messages to an empty string will cause the automation to skip + # that category + ancient-issue-message: Greetings! We’re closing this issue because it has been open a long time and hasn’t been updated in a while and may not be getting the attention it deserves. We encourage you to check if this is still an issue in the latest release and if you find that this is still a problem, please feel free to comment or open a new issue. + stale-issue-message: This issue has not received a response in 1 week. If you still think there is a problem, please leave a comment to avoid the issue from automatically closing. + stale-pr-message: This PR has not received a response in 1 week. If you still think there is a problem, please leave a comment to avoid the PR from automatically closing. + # These labels are required + stale-issue-label: stale + exempt-issue-label: 'pinned, security, no-autoclose' + stale-pr-label: stale + exempt-pr-label: pr/needs-review + response-requested-label: response-requested + + # Don't set closed-for-staleness label to skip closing very old issues + # regardless of label + closed-for-staleness-label: closed-for-staleness + + # Issue timing + days-before-stale: 7 + days-before-close: 2 + days-before-ancient: 365 + + # If you don't want to mark a issue as being ancient based on a + # threshold of "upvotes", you can set this here. An "upvote" is + # the total number of +1, heart, hooray, and rocket reactions + # on an issue. + minimum-upvotes-to-exempt: 10 + + repo-token: ${{ secrets.GITHUB_TOKEN }} + loglevel: DEBUG + # Set dry-run to true to not perform label or close actions. + # dry-run: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..5003f48 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,54 @@ +name: Test + +on: + push: + branches: [main, develop] + pull_request: + +jobs: + test: + name: Test + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + + runs-on: ${{ matrix.os }} + timeout-minutes: 10 + + steps: + - name: TODO + run: echo "TODO test" +# - name: Checkout +# uses: actions/checkout@v3 +# +# - name: Use Node.js +# uses: actions/setup-node@v3 +# with: +# node-version-file: '.nvmrc' +# +# - name: Setup pnpm +# uses: pnpm/action-setup@v2 +# with: +# version: 8 +# run_install: true +# +# - name: Type check +# run: pnpm type-check +# +# - name: Lint +# run: pnpm lint +# +# - name: Build +# run: pnpm build +# +# - name: Install tinyproxy +# if: matrix.os == 'ubuntu-latest' +# run: | +# sudo apt-get install tinyproxy +# tinyproxy +# - name: Test +# env: +# OPENAI_KEY: ${{ secrets.OPENAI_KEY }} +# run: | +# pnpm test +# pnpm --use-node-version=14.21.3 test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f5df45 --- /dev/null +++ b/.gitignore @@ -0,0 +1,67 @@ +# macOS +.DS_Store + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Dependency directories +/node_modules/ + +# Output of 'npm pack' +*.tgz + +# dotenv environment variables file +.env +.env.test + +# Distribution +dist + +# Eslint cache +.eslintcache + +# compiled output +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# profiling files +chrome-profiler-events*.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/.angular/cache +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +Thumbs.db + diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..790e110 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.10.0 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d0b804d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +# Add files here to ignore them from prettier formatting + +/dist +/coverage diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6ad1e9c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,19 @@ +{ + "printWidth": 140, + "tabWidth": 4, + "trailingComma": "es5", + "singleQuote": true, + "useTabs": false, + "semi": true, + "bracketSpacing": true, + "arrowParens": "avoid", + "overrides": [ + { + "files": "*.html", + "options": { + "printWidth": 140, + "htmlWhitespaceSensitivity": "ignore" + } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..72446f4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ffe508e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,84 @@ +# Contribution Guide + +## Setting up the project + +Use [nvm](https://nvm.sh) to use the appropriate Node.js version from `.nvmrc`: + +```sh +nvm i +``` + +Install the dependencies using pnpm: + +```sh +pnpm i +``` + +## Building the project + +Run the `build` script: + +```sh +pnpm build +``` + +The package is bundled using [pkgroll](https://github.com/privatenumber/pkgroll) (Rollup). It infers the entry-points from `package.json` so there are no build configurations. + +### Development (watch) mode + +During development, you can use the watch flag (`--watch, -w`) to automatically rebuild the package on file changes: + +```sh +pnpm build -w +``` + +## Running the package locally + +Since pkgroll knows the entry-point is a binary (being in `package.json#bin`), it automatically adds the Node.js hashbang to the top of the file, and chmods it so it's executable. + +You can run the distribution file in any directory: + +```sh +./dist/cli.mjs +``` + +Or in non-UNIX environments, you can use Node.js to run the file: + +```sh +node ./dist/cli.mjs +``` + +## Testing + +Testing requires passing in `OPENAI_KEY` as an environment variable: + +```sh +OPENAI_KEY= pnpm test +``` + +You can still run tests that don't require `OPENAI_KEY` but will not test the main functionality: + +``` +pnpm test +``` + +## Using & testing your changes + +Let's say you made some changes in a fork/branch and you want to test it in a project. You can publish the package to a GitHub branch using [`git-publish`](https://github.com/privatenumber/git-publish): + +Publish your current branch to a `npm/*` branch on your GitHub repository: + +```sh +$ pnpm dlx git-publish + +✔ Successfully published branch! Install with command: + → npm i 'tak-bro/aipick#npm/develop' +``` + +> Note: The `tak-bro/aipick` will be replaced with your fork's URL. + +Now, you can run the branch in your project: + +```sh +$ pnpm dlx 'tak-bro/aipick#npm/develop' # same as running `npx aipick` +``` diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e1d1c7f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Hyungtak Jin + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2ca6539 --- /dev/null +++ b/README.md @@ -0,0 +1,844 @@ +
+
+ AIPick +

AIPick

+
+

+ An interactive CLI tool that leverages Ollama, ChatGPT, Gemini, Claude, Mistral and other AI. +

+
+ +
+ +[![tak-bro](https://img.shields.io/badge/by-tak--bro-293462?logo=github)](https://github.com/tak-bro) +[![license](https://img.shields.io/badge/license-MIT-211A4C.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRiIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0ibTMgNiAzIDFtMCAwLTMgOWE1IDUgMCAwIDAgNi4wMDEgME02IDdsMyA5TTYgN2w2LTJtNiAyIDMtMW0tMyAxLTMgOWE1IDUgMCAwIDAgNi4wMDEgME0xOCA3bDMgOW0tMy05LTYtMm0wLTJ2Mm0wIDE2VjVtMCAxNkg5bTMgMGgzIi8+PC9zdmc+)](https://github.com/tak-bro/aipick/blob/main/LICENSE) +[![version](https://img.shields.io/npm/v/aipick?logo=semanticrelease&label=release&color=A51C2D)](https://www.npmjs.com/package/aipick) +[![downloads](https://img.shields.io/npm/dt/aipick?color=F33535&logo=npm)](https://www.npmjs.com/package/aipick) + +
+ +--- + +## Introduction + +_aipick_ is an interactive CLI tool that leverages multiple AI models. + +## Key Features + +- **Multi-AI Support**: Integrates with OpenAI, Anthropic Claude, Google Gemini, Mistral AI, Cohere, Groq, Huggingface +- **Local Model Support**: Use local AI models via Ollama. +- **Reactive CLI**: Enables simultaneous requests to multiple AIs and selection of the best AI response. +- **Custom Prompts**: Supports user-defined prompt templates. + +## Supported Providers + +### Remote + +- [OpenAI](https://openai.com/) +- [Anthropic Claude](https://console.anthropic.com/) +- [Gemini](https://gemini.google.com/) +- [Mistral AI](https://mistral.ai/) + - [Codestral **(Free till August 1, 2024)**](https://mistral.ai/news/codestral/) +- [Cohere](https://cohere.com/) +- [Groq](https://groq.com/) +- [Huggingface **(Unofficial)**](https://huggingface.co/chat/) + +### Local + +- [Ollama](https://ollama.com/) + +## Setup + +> The minimum supported version of Node.js is the v18. Check your Node.js version with `node --version`. + +1. Install _aipick_: + +```sh +npm install -g aipick +``` + +2. Retrieve and set API keys or Cookie you intend to use: + +It is not necessary to set all keys. **But at least one key must be set up.** + +- [OpenAI](https://platform.openai.com/account/api-keys) +```sh +aipick config set OPENAI_KEY= +``` + +- [Anthropic Claude](https://console.anthropic.com/) +```sh +aipick config set ANTHROPIC_KEY= +``` + +- [Gemini](https://aistudio.google.com/app/apikey) +```sh +aipick config set GEMINI_KEY= +``` + +- [Mistral AI](https://console.mistral.ai/) +```sh +aipick config set MISTRAL_KEY= +``` + +- [Codestral](https://console.mistral.ai/) +```sh +aipick config set CODESTRAL_KEY= +``` + +- [Cohere](https://dashboard.cohere.com/) +```sh +aipick config set COHERE_KEY= +``` + +- [Groq](https://console.groq.com) +```sh +aipick config set GROQ_KEY= +``` + +- [Huggingface **(Unofficial)**](https://github.com/tak-bro/aipick?tab=readme-ov-file#how-to-get-cookieunofficial-api) +```shell +# Please be cautious of Escape characters(\", \') in browser cookie string +aipick config set HUGGINGFACE_COOKIE="" +``` + +This will create a `.aipick` file in your home directory. + +> You may need to create an account and set up billing. + +3. Run aipick with your staged files in git repository: +```shell +git add +aipick +``` + +## Using Locally + +You can also use your model for free with [Ollama](https://ollama.com/) and it is available to use both Ollama and remote providers **simultaneously**. + +1. Install Ollama from [https://ollama.com](https://ollama.com/) + +2. Start it with your model + +```shell +ollama run llama3 # model you want use. ex) codellama, deepseek-coder +``` + +3. Set the model and host + +```sh +aipick config set OLLAMA_MODEL= +``` + +> If you want to use ollama, you must set **OLLAMA_MODEL**. + +4. Run _aipick_ with your staged in git repository +```shell +git add +aipick +``` + +> 👉 **Tip:** Ollama can run LLMs **in parallel** from v0.1.33. Please see [this section](#loading-multiple-ollama-models). + +## How it works + +This CLI tool runs `git diff` to grab all your latest code changes, sends them to configured AI, then returns the AI generated commit message. + +> If the diff becomes too large, AI will not function properly. If you encounter an error saying the message is too long or it's not a valid commit message, **try reducing the commit unit**. + +## Usage + +### CLI mode + +You can call `aipick` directly to generate a commit message for your staged changes: + +```sh +git add +aipick +``` + +`aipick` passes down unknown flags to `git commit`, so you can pass in [`commit` flags](https://git-scm.com/docs/git-commit). + +For example, you can stage all changes in tracked files with as you commit: + +```sh +aipick --all # or -a +``` + +> 👉 **Tip:** Use the `aip` alias if `aipick` is too long for you. + +#### CLI Options + +##### `--locale` or `-l` +- Locale to use for the generated commit messages (default: **en**) + +```sh +aipick --locale # or -l +``` + +##### `--generate` or `-g` +- Number of messages to generate (Warning: generating multiple costs more) (default: **1**) +- Sometimes the recommended commit message isn't the best so you want it to generate a few to pick from. You can generate multiple commit messages at once by passing in the `--generate ` flag, where 'i' is the number of generated messages: + +```sh +aipick --generate # or -g +``` + +> Warning: this uses more tokens, meaning it costs more. + +##### `--all` or `-a` +- Automatically stage changes in tracked files for the commit (default: **false**) + +```sh +aipick --all # or -a +``` + +##### `--type` or `-t` +- Automatically stage changes in tracked files for the commit (default: **conventional**) +- it supports [`conventional`](https://conventionalcommits.org/) and [`gitmoji`](https://gitmoji.dev/) + +```sh +aipick --type conventional # or -t conventional +aipick --type gitmoji # or -t gitmoji +``` + +##### `--confirm` or `-y` +- Skip confirmation when committing after message generation (default: **false**) + +```sh +aipick --confirm # or -y +``` + +##### `--clipboard` or `-c` +- Copy the selected message to the clipboard (default: **false**) +- This is a useful option when you don't want to commit through _aipick_. +- If you give this option, _aipick_ will not commit. + +```sh +aipick --clipboard # or -c +``` + +##### `--promptPath` or `-p` +- Allow users to specify a custom file path for their own prompt template +- Enable users to define and use their own prompts instead of relying solely on the default prompt +- Please see [Custom Prompt Template](#custom-prompt-template) + +```sh +aipick --promptPath # or -p +``` + +### Git hook + +You can also integrate _aipick_ with Git via the [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. This lets you use Git like you normally would, and edit the commit message before committing. + +#### Install + +In the Git repository you want to install the hook in: + +```sh +aipick hook install +``` + +#### Uninstall + +In the Git repository you want to uninstall the hook from: + +```sh +aipick hook uninstall +``` + +#### Usage + +1. Stage your files and commit: + +```sh +git add +git commit # Only generates a message when it's not passed in +``` + +> If you ever want to write your own message instead of generating one, you can simply pass one in: `git commit -m "My message"` + +2. _aipick_ will generate the commit message for you and pass it back to Git. Git will open it with the [configured editor](https://docs.github.com/en/get-started/getting-started-with-git/associating-text-editors-with-git) for you to review/edit it. + +3. Save and close the editor to commit! + +## Configuration + +### Reading a configuration value + +To retrieve a configuration option, use the command: + +```sh +aipick config get +``` + +For example, to retrieve the API key, you can use: + +```sh +aipick config get OPENAI_KEY +``` + +You can also retrieve multiple configuration options at once by separating them with spaces: + +```sh +aipick config get OPENAI_KEY OPENAI_MODEL GEMINI_KEY +``` + +### Setting a configuration value + +To set a configuration option, use the command: + +```sh +aipick config set = +``` + +For example, to set the API key, you can use: + +```sh +aipick config set OPENAI_KEY= +``` + +You can also set multiple configuration options at once by separating them with spaces, like + +```sh +aipick config set OPENAI_KEY= generate=3 locale=en +``` + +## Options + +| Option | Default | Description | +|----------------------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------| +| `OPENAI_KEY` | N/A | The OpenAI API key | +| `OPENAI_MODEL` | `gpt-3.5-turbo` | The OpenAI Model to use | +| `OPENAI_URL` | `https://api.openai.com` | The OpenAI URL | +| `OPENAI_PATH` | `/v1/chat/completions` | The OpenAI request pathname | +| `ANTHROPIC_KEY` | N/A | The Anthropic API key | +| `ANTHROPIC_MODEL` | `claude-3-haiku-20240307` | The Anthropic Model to use | +| `GEMINI_KEY` | N/A | The Gemini API key | +| `GEMINI_MODEL` | `gemini-1.5-pro-latest` | The Gemini Model | +| `MISTRAL_KEY` | N/A | The Mistral API key | +| `MISTRAL_MODEL` | `mistral-tiny` | The Mistral Model to use | +| `CODESTRAL_KEY` | N/A | The Codestral API key | +| `CODESTRAL_MODEL` | `codestral-latest` | The Codestral Model to use | +| `COHERE_KEY` | N/A | The Cohere API Key | +| `COHERE_MODEL` | `command` | The identifier of the Cohere model | +| `GROQ_KEY` | N/A | The Groq API Key | +| `GROQ_MODEL` | `gemma-7b-it` | The Groq model name to use | +| `HUGGINGFACE_COOKIE` | N/A | The HuggingFace Cookie string | +| `HUGGINGFACE_MODEL` | `mistralai/Mixtral-8x7B-Instruct-v0.1` | The HuggingFace Model to use | +| `OLLAMA_MODEL` | N/A | The Ollama Model. It should be downloaded your local | +| `OLLAMA_HOST` | `http://localhost:11434` | The Ollama Host | +| `OLLAMA_TIMEOUT` | `100_000` ms | Request timeout for the Ollama | +| `locale` | `en` | Locale for the generated commit messages | +| `generate` | `1` | Number of commit messages to generate | +| `type` | `conventional` | Type of commit message to generate | +| `proxy` | N/A | Set a HTTP/HTTPS proxy to use for requests(only **OpenAI**) | +| `timeout` | `10_000` ms | Network request timeout | +| `max-length` | `50` | Maximum character length of the generated commit message(Subject) | +| `max-tokens` | `1024` | The maximum number of tokens that the AI models can generate (for **Open AI, Anthropic, Gemini, Mistral, Codestral**) | +| `temperature` | `0.7` | The temperature (0.0-2.0) is used to control the randomness of the output (for **Open AI, Anthropic, Gemini, Mistral, Codestral**) | +| `promptPath` | N/A | Allow users to specify a custom file path for their own prompt template | +| `logging` | `false` | Whether to log AI responses for debugging (true or false) | +| `ignoreBody` | `false` | Whether the commit message includes body (true or false) | + +> **Currently, options are set universally. However, there are plans to develop the ability to set individual options in the future.** + +### Available Options by Model +| | locale | generate | type | proxy | timeout | max-length | max-tokens | temperature | prompt | +|:--------------------:|:------:|:--------:|:-----:|:-----:|:----------------------:|:-----------:|:----------:|:-----------:|:------:| +| **OpenAI** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Anthropic Claude** | ✓ | ✓ | ✓ | | | ✓ | ✓ | ✓ | ✓ | +| **Gemini** | ✓ | ✓ | ✓ | | | ✓ | ✓ | ✓ | ✓ | +| **Mistral AI** | ✓ | ✓ | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Codestral** | ✓ | ✓ | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Cohere** | ✓ | ✓ | ✓ | | | ✓ | ✓ | ✓ | ✓ | +| **Groq** | ✓ | ✓ | ✓ | | ✓ | ✓ | | | ✓ | +| **Huggingface** | ✓ | ✓ | ✓ | | | ✓ | | | ✓ | +| **Ollama** | ✓ | ✓ | ✓ | | ⚠
(OLLAMA_TIMEOUT) | ✓ | | ✓ | ✓ | + + +### Common Options + +##### locale + +Default: `en` + +The locale to use for the generated commit messages. Consult the list of codes in: https://wikipedia.org/wiki/List_of_ISO_639_language_codes. + +##### generate + +Default: `1` + +The number of commit messages to generate to pick from. + +Note, this will use more tokens as it generates more results. + +##### proxy + +Set a HTTP/HTTPS proxy to use for requests. + +To clear the proxy option, you can use the command (note the empty value after the equals sign): + +> **Only supported within the OpenAI** + +```sh +aipick config set proxy= +``` + +##### timeout + +The timeout for network requests to the OpenAI API in milliseconds. + +Default: `10_000` (10 seconds) + +```sh +aipick config set timeout=20000 # 20s +``` + +##### max-length + +The maximum character length of the generated commit message. + +Default: `50` + +```sh +aipick config set max-length=100 +``` + +##### type + +Default: `conventional` + +Supported: `conventional`, `gitmoji` + +The type of commit message to generate. Set this to "conventional" to generate commit messages that follow the Conventional Commits specification: + +```sh +aipick config set type=conventional +``` + +You can clear this option by setting it to an empty string: + +```sh +aipick config set type= +``` + +##### max-tokens +The maximum number of tokens that the AI models can generate. + +Default: `1024` + +```sh +aipick config set max-tokens=3000 +``` + +##### temperature +The temperature (0.0-2.0) is used to control the randomness of the output + +Default: `0.7` + +```sh +aipick config set temperature=0 +``` + +##### promptPath +- Allow users to specify a custom file path for their own prompt template +- Enable users to define and use their own prompts instead of relying solely on the default prompt +- Please see [Custom Prompt Template](#custom-prompt-template) + +```sh +aipick config set promptPath="/path/to/user/prompt.txt" +``` + +##### logging + +Default: `false` + +Option that allows users to decide whether to generate a log file capturing the responses. +The log files will be stored in the `~/.aipick_log` directory(user's home). + +![log-path](https://github.com/tak-bro/aipick/blob/main/img/log_path.png?raw=true) + +```sh +aipick config set logging="true" +``` + +- You can remove all logs below comamnd. + +```sh +aipick log removeAll +``` + +##### ignoreBody + +Default: `false` + +This option determines whether the commit message includes body. If you don't want to include body in message, you can set it to `true`. + +```sh +aipick config set ignoreBody="true" +``` + +![ignore_body_true](https://github.com/tak-bro/aipick/blob/main/img/ignore_body_true.png?raw=true) + + +```sh +aipick config set ignoreBody="false" +``` + +![ignore_body_false](https://github.com/tak-bro/aipick/blob/main/img/ignore_body_false.png?raw=true) + + +### Ollama + +##### OLLAMA_MODEL + +The Ollama Model. Please see [a list of models available](https://ollama.com/library) + +```sh +aipick config set OLLAMA_MODEL="llama3" +aipick config set OLLAMA_MODEL="llama3,codellama" # for multiple models +``` + +##### OLLAMA_HOST + +Default: `http://localhost:11434` + +The Ollama host + +```sh +aipick config set OLLAMA_HOST= +``` + +##### OLLAMA_TIMEOUT + +Default: `100_000` (100 seconds) + +Request timeout for the Ollama. Default OLLAMA_TIMEOUT is **100 seconds** because it can take a long time to run locally. + +```sh +aipick config set OLLAMA_TIMEOUT= +``` + +### OPEN AI + +##### OPENAI_KEY + +The OpenAI API key. You can retrieve it from [OpenAI API Keys page](https://platform.openai.com/account/api-keys). + +##### OPENAI_MODEL + +Default: `gpt-3.5-turbo` + +The Chat Completions (`/v1/chat/completions`) model to use. Consult the list of models available in the [OpenAI Documentation](https://platform.openai.com/docs/models/model-endpoint-compatibility). + +> Tip: If you have access, try upgrading to [`gpt-4`](https://platform.openai.com/docs/models/gpt-4) for next-level code analysis. It can handle double the input size, but comes at a higher cost. Check out OpenAI's website to learn more. + +```sh +aipick config set OPENAI_MODEL=gpt-4 +``` + +##### OPENAI_URL + +Default: `https://api.openai.com` + +The OpenAI URL. Both https and http protocols supported. It allows to run local OpenAI-compatible server. + +##### OPENAI_PATH + +Default: `/v1/chat/completions` + +The OpenAI Path. + +### Anthropic Claude + +##### ANTHROPIC_KEY + +The Anthropic API key. To get started with Anthropic Claude, request access to their API at [anthropic.com/earlyaccess](https://www.anthropic.com/earlyaccess). + +##### ANTHROPIC_MODEL + +Default: `claude-3-haiku-20240307` + +Supported: +- `claude-3-haiku-20240307` +- `claude-3-sonnet-20240229` +- `claude-3-opus-20240229` +- `claude-2.1` +- `claude-2.0` +- `claude-instant-1.2` + +```sh +aipick config set ANTHROPIC_MODEL=claude-instant-1.2 +``` + +### GEMINI + +##### GEMINI_KEY + +The Gemini API key. If you don't have one, create a key in [Google AI Studio](https://aistudio.google.com/app/apikey). + +##### GEMINI_MODEL + +Default: `gemini-1.5-pro-latest` + +Supported: +- `gemini-1.5-pro-latest` +- `gemini-1.5-flash-latest` + +> The models mentioned above are subject to change. + +### MISTRAL + +##### MISTRAL_KEY + +The Mistral API key. If you don't have one, please sign up and subscribe in [Mistral Console](https://console.mistral.ai/). + +##### MISTRAL_MODEL + +Default: `mistral-tiny` + +Supported: +- `open-mistral-7b` +- `mistral-tiny-2312` +- `mistral-tiny` +- `open-mixtral-8x7b` +- `mistral-small-2312` +- `mistral-small` +- `mistral-small-2402` +- `mistral-small-latest` +- `mistral-medium-latest` +- `mistral-medium-2312` +- `mistral-medium` +- `mistral-large-latest` +- `mistral-large-2402` +- `mistral-embed` + +> The models mentioned above are subject to change. + +### CODESTRAL + +##### CODESTRAL_KEY + +The Codestral API key. If you don't have one, please sign up and subscribe in [Mistral Console](https://console.mistral.ai/codestral). + +##### CODESTRAL_MODEL + +Default: `codestral-latest` + +Supported: +- `codestral-latest` +- `codestral-2405` + +> The models mentioned above are subject to change. + +### Cohere + +##### COHERE_KEY + +The Cohere API key. If you don't have one, please sign up and get the API key in [Cohere Dashboard](https://dashboard.cohere.com/). + +##### COHERE_MODEL + +Default: `command` + +Supported: +- `command` +- `command-nightly` +- `command-light` +- `command-light-nightly` + +> The models mentioned above are subject to change. + +### Groq + +##### GROQ_KEY + +The Groq API key. If you don't have one, please sign up and get the API key in [Groq Console](https://console.groq.com). + +##### GROQ_MODEL + +Default: `gemma-7b-it` + +Supported: +- `llama3-8b-8192` +- 'llama3-70b-8192' +- `mixtral-8x7b-32768` +- `gemma-7b-it` + +> The models mentioned above are subject to change. + +### HuggingFace Chat + +##### HUGGINGFACE_COOKIE + +The [Huggingface Chat](https://huggingface.co/chat/) Cookie. Please check [how to get cookie](https://github.com/tak-bro/aipick?tab=readme-ov-file#how-to-get-cookieunofficial-api) + +##### HUGGINGFACE_MODEL + +Default: `CohereForAI/c4ai-command-r-plus` + +Supported: +- `CohereForAI/c4ai-command-r-plus` +- `meta-llama/Meta-Llama-3-70B-Instruct` +- `HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1` +- `mistralai/Mixtral-8x7B-Instruct-v0.1` +- `NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO` +- `01-ai/Yi-1.5-34B-Chat` +- `mistralai/Mistral-7B-Instruct-v0.2` +- `microsoft/Phi-3-mini-4k-instruct` + +> The models mentioned above are subject to change. + +## Upgrading + +Check the installed version with: + +``` +aipick --version +``` + +If it's not the [latest version](https://github.com/tak-bro/aipick/releases/latest), run: + +```sh +npm update -g aipick +``` + +## Custom Prompt Template + +_aipick_ supports custom prompt templates through the `promptPath` option. This feature allows you to define your own prompt structure, giving you more control over the commit message generation process. + +### Using the promptPath Option +To use a custom prompt template, specify the path to your template file when running the tool: +``` +aipick config set promptPath="/path/to/user/prompt.txt" +``` + +### Template Format + +Your custom template can include placeholders for various commit options. +Use curly braces `{}` to denote these placeholders for options. The following placeholders are supported: + +- [{locale}](#locale): The language for the commit message (string) +- [{maxLength}](#max-length): The maximum length for the commit message (number) +- [{type}](#type): The type of the commit (conventional or gitmoji) +- [{generate}](#generate): The number of commit messages to generate (number) + +### Example Template + +Here's an example of how your custom template might look: + +``` +Generate a {type} commit message in {locale}. +The message should not exceed {maxLength} characters. +Please provide {generate} messages. + +Remember to follow these guidelines: +1. Use the imperative mood +2. Be concise and clear +3. Explain the 'why' behind the change +``` + +#### Appended Text + +Please note that the following text will always be appended to the end of your custom prompt: + +``` +Provide your response as a JSON array where each element is an object with "subject", "body", and "footer" keys. +The "subject" should include the type, optional scope, and description . If there's no body or footer, use an empty string for those fields. +Example response format: +[ + { + "subject": "string", + "body": "string", + "footer": "string" + }, + ... +] +``` + +This ensures that the output is consistently formatted as a JSON array, regardless of the custom template used. + +### Notes + +If the specified file cannot be read or parsed, _aipick_ will fall back to using the default prompt generation logic. +Ensure your template includes all necessary instructions for generating appropriate commit messages. +You can still use all other command-line options in conjunction with `promptPath`. + +By using custom templates, you can tailor the commit message generation to your team's specific needs or coding standards. + +> NOTE: For the `promptPath` option, set the **template path**, not the template content + +## Loading Multiple Ollama Models + +OLLAMA_PARALLEL + +You can load and make simultaneous requests to multiple models using Ollama's experimental feature, the `OLLAMA_MAX_LOADED_MODELS` option. +- `OLLAMA_MAX_LOADED_MODELS`: Load multiple models simultaneously + +#### Setup Guide + +Follow these steps to set up and utilize multiple models simultaneously: + +##### 1. Running Ollama Server + +First, launch the Ollama server with the `OLLAMA_MAX_LOADED_MODELS` environment variable set. This variable specifies the maximum number of models to be loaded simultaneously. +For example, to load up to 3 models, use the following command: + +```shell +OLLAMA_MAX_LOADED_MODELS=3 ollama serve +``` +> Refer to [configuration](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-do-i-configure-ollama-server) for detailed instructions. + +##### 2. Configuring _aipick_ + +Next, set up _aipick_ to specify multiple models. You can assign a list of models, separated by **commas(`,`)**, to the OLLAMA_MODEL environment variable. Here's how you do it: + +```shell +aipick config set OLLAMA_MODEL="mistral,dolphin-llama3" +``` + +With this command, _aipick_ is instructed to utilize both the "mistral" and "dolphin-llama3" models when making requests to the Ollama server. + +##### 3. Run _aipick_ + +```shell +aipick +``` + +> Note that this feature is available starting from Ollama version [**0.1.33**](https://github.com/ollama/ollama/releases/tag/v0.1.33) and _aipick_ version [**1.9.5**](https://www.npmjs.com/package/aipick/v/1.9.5). + + +## How to get Cookie(**Unofficial API**) + +* Login to the site you want +* You can get cookie from the browser's developer tools network tab +* See for any requests check out the Cookie, **Copy whole value** +* Check below image for the format of cookie + +> When setting cookies with long string values, ensure to **escape characters** like ", ', and others properly. +> - For double quotes ("), use \\" +> - For single quotes ('), use \\' + +![how-to-get-cookie](https://github.com/tak-bro/aipick/assets/7614353/66f2994d-23d9-4c88-a113-f2d3dc5c0669) + +## Disclaimer + +This project utilizes certain functionalities or data from external APIs, but it is important to note that it is not officially affiliated with or endorsed by the providers of those APIs. The use of external APIs is at the sole discretion and risk of the user. + +## Risk Acknowledgment + +Users are responsible for understanding and abiding by the terms of use, rate limits, and policies set forth by the respective API providers. The project maintainers cannot be held responsible for any misuse, downtime, or issues arising from the use of the external APIs. + +It is recommended that users thoroughly review the API documentation and adhere to best practices to ensure a positive and compliant experience. + +## Please Star ⭐️ +If this project has been helpful to you, I would greatly appreciate it if you could click the Star⭐️ button on this repository! + +## Maintainers + +- [@tak-bro](https://env-tak.github.io/) + +## Contributing + +If you want to help fix a bug or implement a feature in [Issues](https://github.com/tak-bro/aipick/issues), checkout the [Contribution Guide](CONTRIBUTING.md) to learn how to setup and test the project. diff --git a/img/cookie-clovax.png b/img/cookie-clovax.png new file mode 100644 index 0000000..147c91d Binary files /dev/null and b/img/cookie-clovax.png differ diff --git a/img/cookie-huggingface.png b/img/cookie-huggingface.png new file mode 100644 index 0000000..bcea12c Binary files /dev/null and b/img/cookie-huggingface.png differ diff --git a/img/terminalizer/config.yml b/img/terminalizer/config.yml new file mode 100644 index 0000000..14960cd --- /dev/null +++ b/img/terminalizer/config.yml @@ -0,0 +1,107 @@ +# Specify a command to be executed +# like `/bin/bash -l`, `ls`, or any other commands +# the default is bash for Linux +# or powershell.exe for Windows +command: null + +# Specify the current working directory path +# the default is the current working directory path +cwd: null + +# Export additional ENV variables +env: + recording: true + +# Explicitly set the number of columns +# or use `auto` to take the current +# number of columns of your shell +cols: 105 + +# Explicitly set the number of rows +# or use `auto` to take the current +# number of rows of your shell +rows: 20 + +# Amount of times to repeat GIF +# If value is -1, play once +# If value is 0, loop indefinitely +# If value is a positive number, loop n times +repeat: 0 + +# Quality +# 1 - 100 +quality: 100 + +# Delay between frames in ms +# If the value is `auto` use the actual recording delays +frameDelay: auto + +# Maximum delay between frames in ms +# Ignored if the `frameDelay` isn't set to `auto` +# Set to `auto` to prevent limiting the max idle time +maxIdleTime: 2000 + +# The surrounding frame box +# The `type` can be null, window, floating, or solid` +# To hide the title use the value null +# Don't forget to add a backgroundColor style with a null as type +frameBox: + type: floating + title: AIPick + style: + border: 0px black solid + # boxShadow: none + # margin: 0px + +# Add a watermark image to the rendered gif +# You need to specify an absolute path for +# the image on your machine or a URL, and you can also +# add your own CSS styles +watermark: + imagePath: null + style: + position: absolute + right: 15px + bottom: 15px + width: 100px + opacity: 0.9 + +# Cursor style can be one of +# `block`, `underline`, or `bar` +cursorStyle: block + +# Font family +# You can use any font that is installed on your machine +# in CSS-like syntax +fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace" + +# The size of the font +fontSize: 12 + +# The height of lines +lineHeight: 1 + +# The spacing between letters +letterSpacing: 0 + +# Theme +theme: + background: "transparent" + foreground: "#afafaf" + cursor: "#c7c7c7" + black: "#232628" + red: "#fc4384" + green: "#b3e33b" + yellow: "#ffa727" + blue: "#75dff2" + magenta: "#ae89fe" + cyan: "#708387" + white: "#d5d5d0" + brightBlack: "#626566" + brightRed: "#ff7fac" + brightGreen: "#c8ed71" + brightYellow: "#ebdf86" + brightBlue: "#75dff2" + brightMagenta: "#ae89fe" + brightCyan: "#b1c6ca" + brightWhite: "#f9f9f4" diff --git a/img/terminalizer/demo.yml b/img/terminalizer/demo.yml new file mode 100644 index 0000000..0a44c31 --- /dev/null +++ b/img/terminalizer/demo.yml @@ -0,0 +1,301 @@ +# The configurations that used for the recording, feel free to edit them +config: + + # Specify a command to be executed + # like `/bin/bash -l`, `ls`, or any other commands + # the default is bash for Linux + # or powershell.exe for Windows + command: zsh + + # Specify the current working directory path + # the default is the current working directory path + cwd: /Users/tak/workspace/tak-bro/aipick + + # Export additional ENV variables + env: + recording: true + + # Explicitly set the number of columns + # or use `auto` to take the current + # number of columns of your shell + cols: 105 + + # Explicitly set the number of rows + # or use `auto` to take the current + # number of rows of your shell + rows: 20 + + # Amount of times to repeat GIF + # If value is -1, play once + # If value is 0, loop indefinitely + # If value is a positive number, loop n times + repeat: 0 + + # Quality + # 1 - 100 + quality: 100 + + # Delay between frames in ms + # If the value is `auto` use the actual recording delays + frameDelay: auto + + # Maximum delay between frames in ms + # Ignored if the `frameDelay` isn't set to `auto` + # Set to `auto` to prevent limiting the max idle time + maxIdleTime: 2000 + + # The surrounding frame box + # The `type` can be null, window, floating, or solid` + # To hide the title use the value null + # Don't forget to add a backgroundColor style with a null as type + frameBox: + type: floating + title: AIPick + style: + border: 0px black solid + # boxShadow: none + # margin: 0px + + # Add a watermark image to the rendered gif + # You need to specify an absolute path for + # the image on your machine or a URL, and you can also + # add your own CSS styles + watermark: + imagePath: null + style: + position: absolute + right: 15px + bottom: 15px + width: 100px + opacity: 0.9 + + # Cursor style can be one of + # `block`, `underline`, or `bar` + cursorStyle: block + + # Font family + # You can use any font that is installed on your machine + # in CSS-like syntax + fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace" + + # The size of the font + fontSize: 12 + + # The height of lines + lineHeight: 1 + + # The spacing between letters + letterSpacing: 0 + + # Theme + theme: + background: "transparent" + foreground: "#afafaf" + cursor: "#c7c7c7" + black: "#232628" + red: "#fc4384" + green: "#b3e33b" + yellow: "#ffa727" + blue: "#75dff2" + magenta: "#ae89fe" + cyan: "#708387" + white: "#d5d5d0" + brightBlack: "#626566" + brightRed: "#ff7fac" + brightGreen: "#c8ed71" + brightYellow: "#ebdf86" + brightBlue: "#75dff2" + brightMagenta: "#ae89fe" + brightCyan: "#b1c6ca" + brightWhite: "#f9f9f4" + +# Records, feel free to edit them +records: + - delay: 661 + content: "\e[?25l\e8\e[0m\e[49m\e[39m\e[27m\e[24m\e[J\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon/Users/tak/workspace/tak-bro/aipick\e\\\e]697;OSCUnlock=787e168af5ba4af8ad22fbe6fa405bb3\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=59763\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys023\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\e[0m\e[38;5;31m\e[49m\e[39m\e[27m\e[24m\e[1m\e[7m%\e[27m\e[1m\e[0m \r\e[0m\e[49m\e[39m\e[27m\e[24m\e[K\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[38;5;178m \e[38;5;76m feature/update-prompt \e[38;5;76m*2 \e[38;5;178m+1 \e[38;5;39m?1\e[0m\e[38;5;39m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m························\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;66m 19:32:32\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=787e168af5ba4af8ad22fbe6fa405bb3\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?25h\e[?2004h" + - delay: 452 + content: "a\b\e[1m\e[31ma\e[0m\e[39m\b\e[1m\e[31ma\e[0m\e[39m\e[38;5;245micommit2\e[39m\e[8D" + - delay: 73 + content: "\b\e[1m\e[31ma\e[1m\e[31mi\e[0m\e[39m" + - delay: 117 + content: "\b\b\e[1m\e[31ma\e[1m\e[31mi\e[1m\e[31mc\e[0m\e[39m" + - delay: 84 + content: "\b\e[1m\e[31mc\e[1m\e[31mo\e[0m\e[39m" + - delay: 144 + content: "\b\e[1m\e[31mo\e[1m\e[31mm\e[0m\e[39m" + - delay: 104 + content: "\b\e[1m\e[31mm\e[1m\e[31mm\e[0m\e[39m" + - delay: 138 + content: "\b\e[1m\e[31mm\e[1m\e[31mi\e[0m\e[39m" + - delay: 117 + content: "\b\e[1m\e[31mi\e[1m\e[31mt\e[0m\e[39m" + - delay: 86 + content: "\b\e[1m\e[31mt\e[1m\e[31m2\e[0m\e[39m\e[9D\e[0m\e[32ma\e[0m\e[32mi\e[0m\e[32mc\e[0m\e[32mo\e[0m\e[32mm\e[0m\e[32mm\e[0m\e[32mi\e[0m\e[32mt\e[0m\e[32m2\e[39m" + - delay: 187 + content: "\e[?1l\e>\e[?2004l\e[?25l\r\r\e[A\e[0m\e[27m\e[24m\e[J\e[0m\e[49m\e[27m\e[24m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[39m\e[27m\e[24m \e[32maipick\e[39m\e[K\e[?25h\r\r\n\e]697;OSCLock=787e168af5ba4af8ad22fbe6fa405bb3\a\e]697;PreExec\a\e]2;aipick\a\e]1;aipick\a" + - delay: 167 + content: " _ _ _ ___ \r\n __ _(_)__ ___ _ __ _ __ (_) |_|_ )\r\n / _` | / _/ _ \\ ' \\| ' \\| | _|/ / \r\n \\__,_|_\\__\\___/_|_|_|_|_|_|_|\\__/___|\r\n \r\n" + - delay: 9 + content: "\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Detecting staged files" + - delay: 14 + content: "\e[1G\e[0K\e[?25h\e[1m\e[32m✔ \e[39m\e[22m\e[1mDetected 1 staged file:\e[22m\r\n src/utils/prompt.ts\r\n\r\n" + - delay: 5 + content: "\e[?25l⚠ No commit messages were generated\e[35D\e[35C\e[?25l\e[1G\e[1G\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 27 + content: "\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\e[2m(Use arrow keys)\e[22m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m refactor: add additional prompts for generatePrompt function\e[39m \r\n\r\n\e[0D" + - delay: 54 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 17 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m refactor: add additional prompts for generatePrompt function\e[39m \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n\r\n\e[0D" + - delay: 64 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 50 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m refactor: add additional prompts for generatePrompt function\e[39m \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n\r\n\e[0D" + - delay: 31 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 68 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n\e[36m❯ \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[36m\e[49m refactor(prompt): optimize generatePrompt function\e[39m \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n\r\n\e[0D" + - delay: 12 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 17 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n\e[36m❯ \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[36m\e[49m refactor(prompt): optimize generatePrompt function\e[39m \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat: allow additional prompts for generatePrompt \r\n\r\n\e[0D" + - delay: 62 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 79 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 10 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n\e[36m❯ \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[36m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function.\e[39m \r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat: allow additional prompts for generatePrompt \r\n\r\n\e[0D" + - delay: 70 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 13 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n\e[36m❯ \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[36m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function.\e[39m \r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat: allow additional prompts for generatePrompt \r\n \e[48;2;254;210;31m\e[38;2;0;0;0m\e[1m[HuggingFace]\e[22m\e[39m\e[49m chore: update prompt.ts to use additionalPrompts instead of prompt \r\n\r\n\e[0D" + - delay: 67 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 79 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 52 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n\e[36m❯ \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[36m\e[49m feat: allow additional prompts for generatePrompt\e[39m \r\n \e[48;2;254;210;31m\e[38;2;0;0;0m\e[1m[HuggingFace]\e[22m\e[39m\e[49m chore: update prompt.ts to use additionalPrompts instead of prompt \r\n\r\n\e[0D" + - delay: 27 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 54 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n\e[36m❯ \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[36m\e[49m feat: allow additional prompts for generatePrompt\e[39m \r\n \e[48;2;254;210;31m\e[38;2;0;0;0m\e[1m[HuggingFace]\e[22m\e[39m\e[49m chore: update prompt.ts to use additionalPrompts instead of prompt \r\n \e[48;2;0;219;155m\e[38;2;255;255;255m\e[1m[CLOVA X]\e[22m\e[39m\e[49m fix(prompt): fix generatePrompt function to accept additionalPrompts \r\n\r\n\e[0D" + - delay: 26 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 14 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat: allow additional prompts for generatePrompt \r\n\e[36m❯ \e[48;2;254;210;31m\e[38;2;0;0;0m\e[1m[HuggingFace]\e[22m\e[39m\e[36m\e[49m chore: update prompt.ts to use additionalPrompts instead of prompt\e[39m \r\n \e[48;2;0;219;155m\e[38;2;255;255;255m\e[1m[CLOVA X]\e[22m\e[39m\e[49m fix(prompt): fix generatePrompt function to accept additionalPrompts \r\n\r\n\e[0D" + - delay: 66 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 79 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 23 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat: allow additional prompts for generatePrompt \r\n \e[48;2;254;210;31m\e[38;2;0;0;0m\e[1m[HuggingFace]\e[22m\e[39m\e[49m chore: update prompt.ts to use additionalPrompts instead of prompt \r\n\e[36m❯ \e[48;2;0;219;155m\e[38;2;255;255;255m\e[1m[CLOVA X]\e[22m\e[39m\e[36m\e[49m fix(prompt): fix generatePrompt function to accept additionalPrompts\e[39m \r\n\r\n\e[0D" + - delay: 57 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 35 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\e[36mfix(prompt): fix generatePrompt function to accept additionalPrompts\e[39m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: add additional prompts for generatePrompt function \r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m refactor(prompt): optimize generatePrompt function \r\n \e[48;2;252;74;10m\e[38;2;255;255;255m\e[1m[MistralAI]\e[22m\e[39m\e[49m refactor: add optional 'additionalPrompts' to generatePrompt function. \r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat: allow additional prompts for generatePrompt \r\n \e[48;2;254;210;31m\e[38;2;0;0;0m\e[1m[HuggingFace]\e[22m\e[39m\e[49m chore: update prompt.ts to use additionalPrompts instead of prompt \r\n\e[36m❯ \e[48;2;0;219;155m\e[38;2;255;255;255m\e[1m[CLOVA X]\e[22m\e[39m\e[36m\e[49m fix(prompt): fix generatePrompt function to accept additionalPrompts\e[39m \r\n\r\n\e[0D\e[1G\e[0K\e[?25h\e[1G\r\n\e[?25h\e[1A\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22m\e[30D\e[30C" + - delay: 556 + content: "\e[2K\e[G\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[36mYes\e[39m\e[27D\e[27C\r\n\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠹\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠸\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠴\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠇\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m Committing with the generated message" + - delay: 69 + content: "\e[1G\e[0K\e[?25h\e[1G\r\n\e[1m\e[32m✔\e[39m\e[22m \e[1mSuccessfully committed!\e[22m\r\n\e[?25h\e[?25h\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon/Users/tak/workspace/tak-bro/aipick\e\\" + - delay: 46 + content: "\e]697;OSCUnlock=787e168af5ba4af8ad22fbe6fa405bb3\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=59763\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys023\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;76m \e[38;5;76m feature/update-prompt \e[38;5;76m*2 \e[38;5;39m?1\e[0m\e[38;5;39m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m······················\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;101m 6s\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;66m  19:32:40\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=787e168af5ba4af8ad22fbe6fa405bb3\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?2004h" + - delay: 697 + content: "\e[?2004l\r\r\n" diff --git a/img/terminalizer/demo_body.yml b/img/terminalizer/demo_body.yml new file mode 100644 index 0000000..bb41957 --- /dev/null +++ b/img/terminalizer/demo_body.yml @@ -0,0 +1,381 @@ +# The configurations that used for the recording, feel free to edit them +config: + + # Specify a command to be executed + # like `/bin/bash -l`, `ls`, or any other commands + # the default is bash for Linux + # or powershell.exe for Windows + command: zsh + + # Specify the current working directory path + # the default is the current working directory path + cwd: /Users/tak/workspace/tak-bro/aipick + + # Export additional ENV variables + env: + recording: true + + # Explicitly set the number of columns + # or use `auto` to take the current + # number of columns of your shell + cols: 105 + + # Explicitly set the number of rows + # or use `auto` to take the current + # number of rows of your shell + rows: 20 + + # Amount of times to repeat GIF + # If value is -1, play once + # If value is 0, loop indefinitely + # If value is a positive number, loop n times + repeat: 0 + + # Quality + # 1 - 100 + quality: 100 + + # Delay between frames in ms + # If the value is `auto` use the actual recording delays + frameDelay: auto + + # Maximum delay between frames in ms + # Ignored if the `frameDelay` isn't set to `auto` + # Set to `auto` to prevent limiting the max idle time + maxIdleTime: 2000 + + # The surrounding frame box + # The `type` can be null, window, floating, or solid` + # To hide the title use the value null + # Don't forget to add a backgroundColor style with a null as type + frameBox: + type: floating + title: AIPick + style: + border: 0px black solid + # boxShadow: none + # margin: 0px + + # Add a watermark image to the rendered gif + # You need to specify an absolute path for + # the image on your machine or a URL, and you can also + # add your own CSS styles + watermark: + imagePath: null + style: + position: absolute + right: 15px + bottom: 15px + width: 100px + opacity: 0.9 + + # Cursor style can be one of + # `block`, `underline`, or `bar` + cursorStyle: block + + # Font family + # You can use any font that is installed on your machine + # in CSS-like syntax + fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace" + + # The size of the font + fontSize: 12 + + # The height of lines + lineHeight: 1 + + # The spacing between letters + letterSpacing: 0 + + # Theme + theme: + background: "transparent" + foreground: "#afafaf" + cursor: "#c7c7c7" + black: "#232628" + red: "#fc4384" + green: "#b3e33b" + yellow: "#ffa727" + blue: "#75dff2" + magenta: "#ae89fe" + cyan: "#708387" + white: "#d5d5d0" + brightBlack: "#626566" + brightRed: "#ff7fac" + brightGreen: "#c8ed71" + brightYellow: "#ebdf86" + brightBlue: "#75dff2" + brightMagenta: "#ae89fe" + brightCyan: "#b1c6ca" + brightWhite: "#f9f9f4" + +# Records, feel free to edit them +records: + - delay: 253 + content: "\e[?25l\e8\e[0m\e[49m\e[39m\e[27m\e[24m\e[J\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon/Users/tak/workspace/tak-bro/aipick\e\\\e]697;OSCUnlock=609598b4f0704e3085c3ad8e81bab4df\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=60893\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys041\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\e[0m\e[38;5;31m\e[49m\e[39m\e[27m\e[24m\e[1m\e[7m%\e[27m\e[1m\e[0m \r\e[0m\e[49m\e[39m\e[27m\e[24m\e[K\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[38;5;178m \e[38;5;76m feature/support-multiline \e[38;5;76m*23 \e[38;5;178m+1\e[0m\e[38;5;178m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m············\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;70m 20.10.0\e[0m\e[38;5;70m\e[49m\e[38;5;70m\e[0m\e[38;5;70m\e[49m\e[38;5;70m\e[0m\e[38;5;70m\e[49m\e[38;5;66m  17:40:50\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=609598b4f0704e3085c3ad8e81bab4df\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?25h\e[?2004h" + - delay: 219 + content: "a\b\e[1m\e[31ma\e[0m\e[39m\b\e[1m\e[31ma\e[0m\e[39m\e[38;5;245micommit2\e[39m\e[8D" + - delay: 138 + content: "\b\e[1m\e[31ma\e[1m\e[31mi\e[0m\e[39m" + - delay: 283 + content: "\b\b\e[1m\e[31ma\e[1m\e[31mi\e[1m\e[31mc\e[0m\e[39m" + - delay: 213 + content: "\b\e[1m\e[31mc\e[1m\e[31m2\e[0m\e[39m\e[39m \e[39m \e[39m \e[39m \e[39m \b\b\b\b\b\b\b\b\b\e[0m\e[32ma\e[0m\e[32mi\e[0m\e[32mc\e[0m\e[32m2\e[39m\e[38;5;245m -a -c \e[39m\b\b\b\b\b\b\b" + - delay: 313 + content: "\e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \b\b\b\b\b\b\b\e[?1l\e>\e[?2004l\e[?25l\r\r\e[A\e[0m\e[27m\e[24m\e[J\e[0m\e[49m\e[27m\e[24m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[39m\e[27m\e[24m \e[32maip\e[39m\e[K\e[?25h\r\r\n\e]697;OSCLock=609598b4f0704e3085c3ad8e81bab4df\a\e]697;PreExec\a\e]2;./dist/cli.mjs\a\e]1;aip\a" + - delay: 465 + content: " _ _ _ ___ \r\n __ _(_)__ ___ _ __ _ __ (_) |_|_ )\r\n / _` | / _/ _ \\ ' \\| ' \\| | _|/ / \r\n \\__,_|_\\__\\___/_|_|_|_|_|_|_|\\__/___|\r\n \r\n" + - delay: 11 + content: "\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Detecting staged files" + - delay: 15 + content: "\e[1G\e[0K\e[?25h\e[1m\e[32m✔ \e[39m\e[22m\e[1mDetected 1 staged file:\e[22m\r\n src/services/ai/clova-x.service.ts\r\n\r\n" + - delay: 5 + content: "\e[?25l\e[33m⚠ No commit messages were generated\e[39m\e[35D\e[35C\e[?25l\e[1G\e[1G\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 35 + content: "\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\e[2m (Use ↑↓ arrows to move)\e[22m\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add ClovaXService class for AI service integration\e[39m\e[22m\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add ClovaXService class for AI service integration\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe ClovaXService class is added to handle integration with the Clova X AI service. It includes methods \e[22m\r\n\e[2mfor generating commit messages, sending messages, parsing message results, getting conversation IDs, and \e[22m\r\n\e[2mdeleting conversations.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 45 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add ClovaXService class for AI service integration\e[39m\e[22m\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add ClovaXService class for AI service integration\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe ClovaXService class is added to handle integration with the Clova X AI service. It includes methods \e[22m\r\n\e[2mfor generating commit messages, sending messages, parsing message results, getting conversation IDs, and \e[22m\r\n\e[2mdeleting conversations.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 77 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 64 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add ClovaXService class for AI service integration\e[39m\e[22m\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add ClovaXService class for AI service integration\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe ClovaXService class is added to handle integration with the Clova X AI service. It includes methods \e[22m\r\n\e[2mfor generating commit messages, sending messages, parsing message results, getting conversation IDs, and \e[22m\r\n\e[2mdeleting conversations.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 16 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 78 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[1m\e[39m\e[36m\e[49m refactor(ai): remove clova-x service\e[39m\e[22m\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mrefactor(ai): remove clova-x service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe clova-x service is no longer needed, so it has been removed.\e[22m\e[2m\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 9 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[1m\e[39m\e[36m\e[49m docs: remove unused ClovaX service\e[39m\e[22m\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mdocs: remove unused ClovaX service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- The ClovaX service is no longer needed, as it was a part of an experimental feature that has been \e[22m\r\n\e[2mremoved from the codebase.\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- Deleting the `clova-x.service.ts` file to clean up the project.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 71 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 44 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[1m\e[39m\e[36m\e[49m docs: remove unused ClovaX service\e[39m\e[22m\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mdocs: remove unused ClovaX service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- The ClovaX service is no longer needed, as it was a part of an experimental feature that has been \e[22m\r\n\e[2mremoved from the codebase.\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- Deleting the `clova-x.service.ts` file to clean up the project.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[1m\e[39m\e[36m\e[49m docs: remove unused ClovaX service\e[39m\e[22m\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mdocs: remove unused ClovaX service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- The ClovaX service is no longer needed, as it was a part of an experimental feature that has been \e[22m\r\n\e[2mremoved from the codebase.\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- Deleting the `clova-x.service.ts` file to clean up the project.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 13 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 48 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[1m\e[39m\e[36m\e[49m refactor(ai): remove clova-x service\e[39m\e[22m\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mrefactor(ai): remove clova-x service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe clova-x service is no longer needed, so it has been removed.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 33 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[1m\e[39m\e[36m\e[49m docs: remove unused ClovaX service\e[39m\e[22m\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mdocs: remove unused ClovaX service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- The ClovaX service is no longer needed, as it was a part of an experimental feature that has been \e[22m\r\n\e[2mremoved from the codebase.\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- Deleting the `clova-x.service.ts` file to clean up the project.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 78 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 75 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add clova x service\e[39m\e[22m\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add clova x service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mAdd a new AI service for generating commit messages using Clova X.\e[22m\e[2m\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 27 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[1m\e[39m\e[36m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[39m\e[22m\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mCorrected a bug where `generateCommitMessage$` would hang when the API response did not contain any data.\e[22m\r\n\e[2m This involved handling the empty case gracefully.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 53 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 71 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[1m\e[39m\e[36m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[39m\e[22m\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mCorrected a bug where `generateCommitMessage$` would hang when the API response did not contain any data.\e[22m\r\n\e[2m This involved handling the empty case gracefully.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 10 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 10 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[1m\e[39m\e[36m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[39m\e[22m\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mCorrected a bug where `generateCommitMessage$` would hang when the API response did not contain any data.\e[22m\r\n\e[2m This involved handling the empty case gracefully.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 70 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[1m\e[39m\e[36m\e[49m feat: add clova-x service for ai commit message generation\e[39m\e[22m\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat: add clova-x service for ai commit message generation\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mAdd Clova-X service for AI-powered commit message generation, including sending messages, parsing \e[22m\r\n\e[2mresponses, and deleting conversations. Update AI service params and config to include Clova-X specific \e[22m\r\n\e[2mdetails. Handle potential errors and logging.\e[22m\e[2m\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 9 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[1m\e[39m\e[36m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[39m\e[22m\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfix(ai): fix issue where generateCommitMessage$ hangs when response is empty\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mCorrected a bug where `generateCommitMessage$` would hang when the API response did not contain any data.\e[22m\r\n\e[2m This involved handling the empty case gracefully.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 69 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 37 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add clova x service\e[39m\e[22m\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add clova x service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mAdd a new AI service for generating commit messages using Clova X.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 43 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 54 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[1m\e[39m\e[36m\e[49m docs: remove unused ClovaX service\e[39m\e[22m\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mdocs: remove unused ClovaX service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- The ClovaX service is no longer needed, as it was a part of an experimental feature that has been \e[22m\r\n\e[2mremoved from the codebase.\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- Deleting the `clova-x.service.ts` file to clean up the project.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 26 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 61 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[1m\e[39m\e[36m\e[49m refactor(ai): remove clova-x service\e[39m\e[22m\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mrefactor(ai): remove clova-x service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe clova-x service is no longer needed, so it has been removed.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 19 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 79 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add ClovaXService class for AI service integration\e[39m\e[22m\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add ClovaXService class for AI service integration\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe ClovaXService class is added to handle integration with the Clova X AI service. It includes methods \e[22m\r\n\e[2mfor generating commit messages, sending messages, parsing message results, getting conversation IDs, and \e[22m\r\n\e[2mdeleting conversations.\e[22m\e[2m\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 62 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[1m\e[39m\e[36m\e[49m refactor(ai): remove clova-x service\e[39m\e[22m\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mrefactor(ai): remove clova-x service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe clova-x service is no longer needed, so it has been removed.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 19 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 29 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[1m\e[39m\e[36m\e[49m docs: remove unused ClovaX service\e[39m\e[22m\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mdocs: remove unused ClovaX service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- The ClovaX service is no longer needed, as it was a part of an experimental feature that has been \e[22m\r\n\e[2mremoved from the codebase.\e[22m\e[2m\e[22m\r\n\e[2m\e[2m- Deleting the `clova-x.service.ts` file to clean up the project.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 51 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 52 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[39m\e[49m feat(ai): add ClovaXService class for AI service integration\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[1m\e[39m\e[36m\e[49m refactor(ai): remove clova-x service\e[39m\e[22m\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mrefactor(ai): remove clova-x service\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe clova-x service is no longer needed, so it has been removed.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 28 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 32 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add ClovaXService class for AI service integration\e[39m\e[22m\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add ClovaXService class for AI service integration\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe ClovaXService class is added to handle integration with the Clova X AI service. It includes methods \e[22m\r\n\e[2mfor generating commit messages, sending messages, parsing message results, getting conversation IDs, and \e[22m\r\n\e[2mdeleting conversations.\e[22m\e[2m\e[22m\r\n\r\n\e[0D" + - delay: 47 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 63 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[1m\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[1m\e[0m \e[0m\e[22m\e[36mfeat(ai): add ClovaXService class for AI service integration\e[39m\r\n\e[36m\e[39m\r\n\e[36mThe ClovaXService class is added to handle integration with the Clova X AI service. It includes methods \e[39m\r\n\e[36mfor generating commit messages, sending messages, parsing message results, getting conversation IDs, and \e[39m\r\n\e[36mdeleting conversations.\e[39m\r\n \e[36m❯\e[39m \e[1m\e[36m\e[48;2;116;170;156m\e[38;2;255;255;255m\e[1m[ChatGPT]\e[22m\e[1m\e[39m\e[36m\e[49m feat(ai): add ClovaXService class for AI service integration\e[39m\e[22m\r\n \e[48;2;226;140;88m\e[38;2;255;255;255m\e[1m[Codestral]\e[22m\e[39m\e[49m refactor(ai): remove clova-x service\r\n \e[48;2;174;86;48m\e[38;2;255;255;255m\e[1m[Anthropic]\e[22m\e[39m\e[49m docs: remove unused ClovaX service\r\n \e[48;2;0;119;255m\e[38;2;255;255;255m\e[1m[Gemini]\e[22m\e[39m\e[49m feat(ai): add clova x service\r\n \e[48;2;245;80;54m\e[38;2;255;255;255m\e[1m[Groq]\e[22m\e[39m\e[49m fix(ai): fix issue where generateCommitMessage$ hangs when response is empty\r\n \e[48;2;209;142;226m\e[38;2;255;255;255m\e[1m[Cohere]\e[22m\e[39m\e[49m feat: add clova-x service for ai commit message generation\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mfeat(ai): add ClovaXService class for AI service integration\e[22m\e[2m\e[22m\r\n\e[2m\e[2m\e[22m\e[2m\e[22m\r\n\e[2m\e[2mThe ClovaXService class is added to handle integration with the Clova X AI service. It includes methods \e[22m\r\n\e[2mfor generating commit messages, sending messages, parsing message results, getting conversation IDs, and \e[22m\r\n\e[2mdeleting conversations.\e[22m\e[2m\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[?25h\e[1G\r\n\e[?25h\e[1A\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22m\e[30D\e[30C" + - delay: 1257 + content: "\e[2K\e[G\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[36mYes\e[39m\e[27D\e[27C\r\n\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠙\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m Committing with the generated message" + - delay: 56 + content: "\e[1G\e[0K\e[?25h\e[1G\r\n\e[1m\e[32m✔\e[39m\e[22m \e[1mSuccessfully committed!\e[22m\r\n\e[?25h\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon/Users/tak/workspace/tak-bro/aipick\e\\" + - delay: 49 + content: "\e]697;OSCUnlock=609598b4f0704e3085c3ad8e81bab4df\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=60893\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys041\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;76m \e[38;5;76m feature/support-multiline \e[38;5;76m*23\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m·········\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;101m 14s\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;70m  20.10.0\e[0m\e[38;5;70m\e[49m\e[38;5;70m\e[0m\e[38;5;70m\e[49m\e[38;5;70m\e[0m\e[38;5;70m\e[49m\e[38;5;66m  17:41:07\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=609598b4f0704e3085c3ad8e81bab4df\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?2004h" + - delay: 919 + content: "\e[?2004l\r\r\n" diff --git a/img/terminalizer/ollama_parallel.yml b/img/terminalizer/ollama_parallel.yml new file mode 100644 index 0000000..9933b31 --- /dev/null +++ b/img/terminalizer/ollama_parallel.yml @@ -0,0 +1,297 @@ +# The configurations that used for the recording, feel free to edit them +config: + + # Specify a command to be executed + # like `/bin/bash -l`, `ls`, or any other commands + # the default is bash for Linux + # or powershell.exe for Windows + command: zsh + + # Specify the current working directory path + # the default is the current working directory path + cwd: /Users/tak/workspace/tak-bro/aipick + + # Export additional ENV variables + env: + recording: true + + # Explicitly set the number of columns + # or use `auto` to take the current + # number of columns of your shell + cols: 105 + + # Explicitly set the number of rows + # or use `auto` to take the current + # number of rows of your shell + rows: 20 + + # Amount of times to repeat GIF + # If value is -1, play once + # If value is 0, loop indefinitely + # If value is a positive number, loop n times + repeat: 0 + + # Quality + # 1 - 100 + quality: 100 + + # Delay between frames in ms + # If the value is `auto` use the actual recording delays + frameDelay: auto + + # Maximum delay between frames in ms + # Ignored if the `frameDelay` isn't set to `auto` + # Set to `auto` to prevent limiting the max idle time + maxIdleTime: 2000 + + # The surrounding frame box + # The `type` can be null, window, floating, or solid` + # To hide the title use the value null + # Don't forget to add a backgroundColor style with a null as type + frameBox: + type: floating + title: AIPick + style: + border: 0px black solid + # boxShadow: none + # margin: 0px + + # Add a watermark image to the rendered gif + # You need to specify an absolute path for + # the image on your machine or a URL, and you can also + # add your own CSS styles + watermark: + imagePath: null + style: + position: absolute + right: 15px + bottom: 15px + width: 100px + opacity: 0.9 + + # Cursor style can be one of + # `block`, `underline`, or `bar` + cursorStyle: block + + # Font family + # You can use any font that is installed on your machine + # in CSS-like syntax + fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace" + + # The size of the font + fontSize: 12 + + # The height of lines + lineHeight: 1 + + # The spacing between letters + letterSpacing: 0 + + # Theme + theme: + background: "transparent" + foreground: "#afafaf" + cursor: "#c7c7c7" + black: "#232628" + red: "#fc4384" + green: "#b3e33b" + yellow: "#ffa727" + blue: "#75dff2" + magenta: "#ae89fe" + cyan: "#708387" + white: "#d5d5d0" + brightBlack: "#626566" + brightRed: "#ff7fac" + brightGreen: "#c8ed71" + brightYellow: "#ebdf86" + brightBlue: "#75dff2" + brightMagenta: "#ae89fe" + brightCyan: "#b1c6ca" + brightWhite: "#f9f9f4" + +# Records, feel free to edit them +records: + - delay: 733 + content: "\e[?25l\e8\e[0m\e[49m\e[39m\e[27m\e[24m\e[J\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon/Users/tak/workspace/tak-bro/aipick\e\\\e]697;OSCUnlock=7af1761deec94434a5a0a43fff9c8cee\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=28386\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys034\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\e[0m\e[38;5;31m\e[49m\e[39m\e[27m\e[24m\e[1m\e[7m%\e[27m\e[1m\e[0m \r\e[0m\e[49m\e[39m\e[27m\e[24m\e[K\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[38;5;178m \e[38;5;76m feature/support-parallel \e[38;5;76m*14 \e[38;5;178m+1\e[0m\e[38;5;178m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m·······················\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;66m 17:20:29\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=7af1761deec94434a5a0a43fff9c8cee\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?25h\e[?2004h" + - delay: 388 + content: "a\b\e[1m\e[31ma\e[0m\e[39m\b\e[1m\e[31ma\e[0m\e[39m\e[38;5;245mic2\e[39m\b\b\b" + - delay: 142 + content: "\b\e[1m\e[31ma\e[1m\e[31mi\e[0m\e[39m" + - delay: 233 + content: "\b\b\e[1m\e[31ma\e[1m\e[31mi\e[1m\e[31mc\e[0m\e[39m" + - delay: 218 + content: "\b\e[1m\e[31mc\e[1m\e[31m2\e[0m\e[39m" + - delay: 9 + content: "\b\b\b\b\e[0m\e[32ma\e[0m\e[32mi\e[0m\e[32mc\e[0m\e[32m2\e[39m" + - delay: 173 + content: "\b\e[32m2\e[32m \e[39m\b\b\e[32m2\e[39m\e[39m \e[38;5;245mconfig set OLLAMA_MODEL=\"mistral,dolphin-llama3\"\e[39m\e[48D" + - delay: 502 + content: "\e[39mc\e[39mo\e[39mn\e[39mf\e[39mi\e[39mg\e[39m \e[39ms\e[39me\e[39mt\e[39m \e[39mO\e[39mL\e[39mL\e[39mA\e[39mM\e[39mA\e[39m_\e[39mM\e[39mO\e[39mD\e[39mE\e[39mL\e[39m=\e[39m\"\e[39mm\e[39mi\e[39ms\e[39mt\e[39mr\e[39ma\e[39ml\e[39m,\e[39md\e[39mo\e[39ml\e[39mp\e[39mh\e[39mi\e[39mn\e[39m-\e[39ml\e[39ml\e[39ma\e[39mm\e[39ma\e[39m3\e[39m\"" + - delay: 10 + content: "\e[24D\e[33m\"\e[33mm\e[33mi\e[33ms\e[33mt\e[33mr\e[33ma\e[33ml\e[33m,\e[33md\e[33mo\e[33ml\e[33mp\e[33mh\e[33mi\e[33mn\e[33m-\e[33ml\e[33ml\e[33ma\e[33mm\e[33ma\e[33m3\e[33m\"\e[39m" + - delay: 211 + content: "\e[?1l\e>\e[?2004l\e[?25l\r\r\e[A\e[0m\e[27m\e[24m\e[J\e[0m\e[49m\e[27m\e[24m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[39m\e[27m\e[24m \e[32maip\e[39m config set OLLAMA_MODEL=\e[33m\"mistral,dolphin-llama3\"\e[39m\e[K\e[?25h\r\r\n\e]697;OSCLock=7af1761deec94434a5a0a43fff9c8cee\a\e]697;PreExec\a\e]2;./dist/cli.mjs config set OLLAMA_MODEL=\"mistral,dolphin-llama3\"\a\e]1;aip\a" + - delay: 301 + content: "\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon/Users/tak/workspace/tak-bro/aipick\e\\" + - delay: 47 + content: "\e]697;OSCUnlock=7af1761deec94434a5a0a43fff9c8cee\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=28386\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys034\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[38;5;178m \e[38;5;76m feature/support-parallel \e[38;5;76m*14 \e[38;5;178m+1\e[0m\e[38;5;178m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m·······················\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;66m 17:20:32\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=7af1761deec94434a5a0a43fff9c8cee\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?2004h" + - delay: 745 + content: a + - delay: 7 + content: "\b\e[1m\e[31ma\e[0m\e[39m\b\e[1m\e[31ma\e[0m\e[39m\e[38;5;245mic2 config set OLLAMA_MODEL=\"mistral,dolphin-llama3\"\e[39m\e[52D" + - delay: 115 + content: "\b\e[1m\e[31ma\e[1m\e[31mi\e[0m\e[39m" + - delay: 74 + content: "\b\b\e[1m\e[31ma\e[1m\e[31mi\e[1m\e[31mc\e[0m\e[39m" + - delay: 126 + content: "\b\e[1m\e[31mc\e[1m\e[31m2\e[0m\e[39m" + - delay: 7 + content: "\b\b\b\b\e[0m\e[32ma\e[0m\e[32mi\e[0m\e[32mc\e[0m\e[32m2\e[39m" + - delay: 261 + content: "\e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[49D\e[?1l\e>\e[?2004l\e[?25l\r\r\e[A\e[A\e[0m\e[27m\e[24m\e[J\e[0m\e[49m\e[27m\e[24m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[39m\e[27m\e[24m \e[32maip\e[39m\e[K\e[?25h\r\r\n\e]697;OSCLock=7af1761deec94434a5a0a43fff9c8cee\a\e]697;PreExec\a\e]2;./dist/cli.mjs\a\e]1;aip\a" + - delay: 218 + content: " _ _ _ ___ \r\n __ _(_)__ ___ _ __ _ __ (_) |_|_ )\r\n / _` | / _/ _ \\ ' \\| ' \\| | _|/ / \r\n \\__,_|_\\__\\___/_|_|_|_|_|_|_|\\__/___|\r\n \r\n" + - delay: 16 + content: "\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Detecting staged files" + - delay: 15 + content: "\e[1G\e[0K\e[?25h\e[1m\e[32m✔ \e[39m\e[22m\e[1mDetected 1 staged file:\e[22m\r\n src/utils/config.ts\r\n\r\n\e[?25l⚠ No commit messages were generated\e[35D\e[35C\e[?25l\e[1G\e[1G\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\e[2m(Use arrow keys)\e[22m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[36m\e[49m style: refactor formatting in config.ts\e[39m \r\n\r\n\e[0D\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[36m\e[49m style: refactor formatting in config.ts\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m perf: improve OLLAMA_MODEL parsing efficiency in config.ts \r\n\r\n\e[0D\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 79 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[36m\e[49m style: refactor formatting in config.ts\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m perf: improve OLLAMA_MODEL parsing efficiency in config.ts \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[49m feat: add support for multiple models in OLLAMA_MODEL function \r\n\r\n\e[0D\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[36m\e[49m style: refactor formatting in config.ts\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m perf: improve OLLAMA_MODEL parsing efficiency in config.ts \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[49m feat: add support for multiple models in OLLAMA_MODEL function \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[49m fix: ensure parsing of OLLAMA_MODEL returns correct type string[] \r\n\r\n\e[0D" + - delay: 58 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 42 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m style: refactor formatting in config.ts \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[36m\e[49m perf: improve OLLAMA_MODEL parsing efficiency in config.ts\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[49m feat: add support for multiple models in OLLAMA_MODEL function \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[49m fix: ensure parsing of OLLAMA_MODEL returns correct type string[] \r\n\r\n\e[0D" + - delay: 39 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 82 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 28 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m style: refactor formatting in config.ts \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m perf: improve OLLAMA_MODEL parsing efficiency in config.ts \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[36m\e[49m feat: add support for multiple models in OLLAMA_MODEL function\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[49m fix: ensure parsing of OLLAMA_MODEL returns correct type string[] \r\n\r\n\e[0D" + - delay: 53 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 49 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\e[36mfeat: add support for multiple models in OLLAMA_MODEL function\e[39m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m style: refactor formatting in config.ts \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Mistral]\e[22m\e[39m\e[49m perf: improve OLLAMA_MODEL parsing efficiency in config.ts \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[36m\e[49m feat: add support for multiple models in OLLAMA_MODEL function\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Dolphin-llama3]\e[22m\e[39m\e[49m fix: ensure parsing of OLLAMA_MODEL returns correct type string[] \r\n\r\n\e[0D\e[1G\e[0K\e[?25h\e[1G\r\n\e[?25h\e[1A\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22m\e[30D\e[30C" + - delay: 400 + content: "\e[2K\e[G\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[36mYes\e[39m\e[27D\e[27C\r\n\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Committing with the generated message" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠙\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠹\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠦\e[39m Committing with the generated message" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠧\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠏\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠋\e[39m Committing with the generated message" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠙\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠹\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠸\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠧\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m Committing with the generated message" + - delay: 76 + content: "\e[1G\e[0K\e[?25h\e[1G\r\n\e[1m\e[32m✔\e[39m\e[22m \e[1mSuccessfully committed!\e[22m\r\n\e[?25h\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon/Users/tak/workspace/tak-bro/aipick\e\\" + - delay: 54 + content: "\e]697;OSCUnlock=7af1761deec94434a5a0a43fff9c8cee\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=28386\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys034\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;76m \e[38;5;76m feature/support-parallel \e[38;5;76m*14\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m·····················\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;101m 8s\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;66m  17:20:41\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=7af1761deec94434a5a0a43fff9c8cee\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?2004h" diff --git a/img/terminalizer/ollama_stream.yml b/img/terminalizer/ollama_stream.yml new file mode 100644 index 0000000..a7eb86a --- /dev/null +++ b/img/terminalizer/ollama_stream.yml @@ -0,0 +1,451 @@ +# The configurations that used for the recording, feel free to edit them +config: + + # Specify a command to be executed + # like `/bin/bash -l`, `ls`, or any other commands + # the default is bash for Linux + # or powershell.exe for Windows + command: zsh + + # Specify the current working directory path + # the default is the current working directory path + cwd: /Users/tak/workspace/tak-bro/aipick + + # Export additional ENV variables + env: + recording: true + + # Explicitly set the number of columns + # or use `auto` to take the current + # number of columns of your shell + cols: 105 + + # Explicitly set the number of rows + # or use `auto` to take the current + # number of rows of your shell + rows: 20 + + # Amount of times to repeat GIF + # If value is -1, play once + # If value is 0, loop indefinitely + # If value is a positive number, loop n times + repeat: 0 + + # Quality + # 1 - 100 + quality: 100 + + # Delay between frames in ms + # If the value is `auto` use the actual recording delays + frameDelay: auto + + # Maximum delay between frames in ms + # Ignored if the `frameDelay` isn't set to `auto` + # Set to `auto` to prevent limiting the max idle time + maxIdleTime: 2000 + + # The surrounding frame box + # The `type` can be null, window, floating, or solid` + # To hide the title use the value null + # Don't forget to add a backgroundColor style with a null as type + frameBox: + type: floating + title: AIPick + style: + border: 0px black solid + # boxShadow: none + # margin: 0px + + # Add a watermark image to the rendered gif + # You need to specify an absolute path for + # the image on your machine or a URL, and you can also + # add your own CSS styles + watermark: + imagePath: null + style: + position: absolute + right: 15px + bottom: 15px + width: 100px + opacity: 0.9 + + # Cursor style can be one of + # `block`, `underline`, or `bar` + cursorStyle: block + + # Font family + # You can use any font that is installed on your machine + # in CSS-like syntax + fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace" + + # The size of the font + fontSize: 12 + + # The height of lines + lineHeight: 1 + + # The spacing between letters + letterSpacing: 0 + + # Theme + theme: + background: "transparent" + foreground: "#afafaf" + cursor: "#c7c7c7" + black: "#232628" + red: "#fc4384" + green: "#b3e33b" + yellow: "#ffa727" + blue: "#75dff2" + magenta: "#ae89fe" + cyan: "#708387" + white: "#d5d5d0" + brightBlack: "#626566" + brightRed: "#ff7fac" + brightGreen: "#c8ed71" + brightYellow: "#ebdf86" + brightBlue: "#75dff2" + brightMagenta: "#ae89fe" + brightCyan: "#b1c6ca" + brightWhite: "#f9f9f4" + +# Records, feel free to edit them +records: + - delay: 686 + content: "\e[?25l\e8\e[0m\e[49m\e[39m\e[27m\e[24m\e[J\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon.local/Users/tak/workspace/tak-bro/aipick\e\\\e]697;OSCUnlock=58e0f86ba8914f90a6ad6f3a8774bf98\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=81467\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys018\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\e[0m\e[38;5;31m\e[49m\e[39m\e[27m\e[24m\e[1m\e[7m%\e[27m\e[1m\e[0m \r\e[0m\e[49m\e[39m\e[27m\e[24m\e[K\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[38;5;178m \e[38;5;76m feature/update-prompt \e[38;5;76m*2 \e[38;5;178m+1 \e[38;5;39m?1\e[0m\e[38;5;39m\e[49m\e[38;5;178m\e[0m\e[38;5;178m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m························\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;66m 13:46:48\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=58e0f86ba8914f90a6ad6f3a8774bf98\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?25h\e[?2004h" + - delay: 699 + content: a + - delay: 10 + content: "\b\e[1m\e[31ma\e[0m\e[39m\b\e[1m\e[31ma\e[0m\e[39m\e[38;5;245micommit2 -g 5\e[39m\e[13D" + - delay: 79 + content: "\b\e[1m\e[31ma\e[1m\e[31mi\e[0m\e[39m" + - delay: 277 + content: "\e[39mc\e[39mo\e[39mm\e[39mm\e[39mi\e[39mt\e[39m2\e[39m \e[39m-\e[39mg\e[39m \e[39m5\e[14D\e[0m\e[32ma\e[0m\e[32mi\e[32mc\e[32mo\e[32mm\e[32mm\e[32mi\e[32mt\e[32m2\e[39m\e[5C" + - delay: 637 + content: "\e[?1l\e>\e[?2004l" + - delay: 7 + content: "\e[?25l\r\r\e[A\e[0m\e[27m\e[24m\e[J\e[0m\e[49m\e[27m\e[24m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[39m\e[27m\e[24m \e[32maipick\e[39m -g 5\e[K\e[?25h\r\r\n\e]697;OSCLock=58e0f86ba8914f90a6ad6f3a8774bf98\a\e]697;PreExec\a\e]2;aipick -g 5\a\e]1;aipick\a" + - delay: 242 + content: " _ _ _ ___ \r\n __ _(_)__ ___ _ __ _ __ (_) |_|_ )\r\n / _` | / _/ _ \\ ' \\| ' \\| | _|/ / \r\n \\__,_|_\\__\\___/_|_|_|_|_|_|_|\\__/___|\r\n \r\n" + - delay: 9 + content: "\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Detecting staged files" + - delay: 13 + content: "\e[1G\e[0K\e[?25h\e[1m\e[32m✔ \e[39m\e[22m\e[1mDetected 1 staged file:\e[22m\r\n README.md\r\n\r\n\e[?25l⚠ No commit messages were generated\e[35D\e[35C\e[?25l\e[1G\e[1G\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 79 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 56 + content: "\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\e[2m(Use arrow keys)\e[22m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 10 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 15 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 6 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 23 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 11 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 11 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 5 + content: "\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 15 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1 (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. ` (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs (Disabled)\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes" + - delay: 19 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 23 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 15 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 5 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 12 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 8 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2 (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 8 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 13 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. ` (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `ch (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore (Disabled)\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes" + - delay: 17 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 19 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 18 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-col (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 10 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 11 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3 (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 19 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. ` (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 7 + content: "\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 15 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support (Disabled)\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠙\e[39m AI is analyzing your changes" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using O (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 15 + content: "\e[1G\e[0K\e[36m⠹\e[39m AI is analyzing your changes\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Oll (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally (Disabled)\e[22m\r\n\r\n\e[0D" + - delay: 12 + content: "\e[1G\e[0K\e[36m⠸\e[39m AI is analyzing your changes" + - delay: 8 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 10 + content: "\e[1G\e[0K\e[36m⠼\e[39m AI is analyzing your changes" + - delay: 11 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 6 + content: "\e[1G\e[0K\e[36m⠴\e[39m AI is analyzing your changes" + - delay: 16 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 23 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[1G\e[0K\e[36m⠦\e[39m AI is analyzing your changes\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 15 + content: "\e[1G\e[0K\e[36m⠧\e[39m AI is analyzing your changes" + - delay: 5 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 20 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 10 + content: "\e[1G\e[0K\e[36m⠇\e[39m AI is analyzing your changes" + - delay: 11 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 6 + content: "\e[1G\e[0K\e[36m⠏\e[39m AI is analyzing your changes" + - delay: 16 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 21 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D\e[1G\e[0K\e[36m⠋\e[39m AI is analyzing your changes" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 22 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[2m \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[2m\e[39m\e[49m Here are five commit messages in conventional commit type:\e[22m\r\n\e[2m\e[22m\r\n\e[2m1. `docs`: Update README.md with new links and images\e[22m\r\n\e[2m\e[22m\r\n\e[2m2. `chore`: Fix README.md formatting and add missing semi-colons\e[22m\r\n\e[2m\e[22m\r\n\e[2m3. `feat`: Add support for using Ollama model locally\e[22m\r\n\e[2m(Move up and down to reveal more choices)\e[22m\r\n\r\n\e[0D" + - delay: 23 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m docs: update README.md with new links and images\e[39m \r\n\r\n\e[0D\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m docs: update README.md with new links and images\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n\r\n\e[0D\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m docs: update README.md with new links and images\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n\r\n\e[0D\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m docs: update README.md with new links and images\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n\r\n\e[0D\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m docs: update README.md with new links and images\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D" + - delay: 11 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 28 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m docs: update README.md with new links and images \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m chore: fix README.md formatting and add missing semi-colons\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D" + - delay: 52 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 41 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m docs: update README.md with new links and images \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m feat: add support for using Ollama model locally\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D" + - delay: 39 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 79 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m docs: update README.md with new links and images \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m style: correct image src URLs and update badge colors\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 70 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m docs: update README.md with new links and images \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m refactor: simplify README.md code structure and organization\e[39m \r\n\r\n\e[0D" + - delay: 9 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 17 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m docs: update README.md with new links and images \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m style: correct image src URLs and update badge colors\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D" + - delay: 62 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m docs: update README.md with new links and images \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m feat: add support for using Ollama model locally\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D" + - delay: 80 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 79 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 39 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m docs: update README.md with new links and images \r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m chore: fix README.md formatting and add missing semi-colons\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D" + - delay: 42 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 81 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 69 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m docs: update README.md with new links and images\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D" + - delay: 11 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 82 + content: "\e[1G\e[0K\e[32m✔\e[39m \e[1mChanges analyzed\e[22m" + - delay: 44 + content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mPick a commit message to use: \e[22m\e[0m \e[0m\e[36mdocs: update README.md with new links and images\e[39m\r\n\e[36m❯ \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[36m\e[49m docs: update README.md with new links and images\e[39m \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m chore: fix README.md formatting and add missing semi-colons \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m feat: add support for using Ollama model locally \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m style: correct image src URLs and update badge colors \r\n \e[48;2;255;255;255m\e[38;2;0;0;0m\e[1m[Ollama]\e[22m\e[39m\e[49m refactor: simplify README.md code structure and organization \r\n\r\n\e[0D\e[1G\e[0K\e[?25h\e[1G\r\n\e[?25h\e[1A\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22m\e[30D\e[30C" + - delay: 237 + content: "\e[2K\e[G\e[32m?\e[39m \e[1mUse selected message?\e[22m\e[0m \e[0m\e[36mYes\e[39m\e[27D\e[27C\r\n\e[?25l\e[1G\e[1G\e[36m⠋\e[39m Committing with the generated message" + - delay: 82 + content: "\e[1G\e[0K\e[36m⠙\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠹\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠸\e[39m Committing with the generated message" + - delay: 81 + content: "\e[1G\e[0K\e[36m⠼\e[39m Committing with the generated message" + - delay: 80 + content: "\e[1G\e[0K\e[36m⠴\e[39m Committing with the generated message" + - delay: 24 + content: "\e[1G\e[0K\e[?25h\e[1G\r\n\e[1m\e[32m✔\e[39m\e[22m \e[1mSuccessfully committed!\e[22m\r\n\e[?25h\e[?25h\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;tak@louis-lemon:~/workspace/tak-bro/aipick\a\e]1;..bro/aipick\a\e]7;file://louis-lemon.local/Users/tak/workspace/tak-bro/aipick\e\\" + - delay: 47 + content: "\e]697;OSCUnlock=58e0f86ba8914f90a6ad6f3a8774bf98\a\e]697;Dir=/Users/tak/workspace/tak-bro/aipick\a\e]697;Shell=zsh\a\e]697;ShellPath=/opt/homebrew/Cellar/zsh/5.9/bin/zsh\a\e]697;PID=81467\a\e]697;ExitCode=0\a\e]697;TTY=/dev/ttys018\a\e]697;Log=\a\e]697;ZshAutosuggestionColor=fg=245\a\e]697;FigAutosuggestionColor=\a\e]697;User=tak\a\r\e[0m\e[27m\e[24m\e[J\e]697;StartPrompt\a\e[0m\e[49m\e[39m\r\n\r\n\e[A\e[0m\e[49m\e[39m\e[0m\e[49m\e[39m\e[0m\e[49m \e[0m\e[49m\e[38;5;31m \e[1m\e[38;5;31m\e[38;5;39m~\e[0m\e[38;5;39m\e[49m\e[38;5;31m/workspace/tak-bro/\e[1m\e[38;5;31m\e[38;5;39maipick\e[0m\e[38;5;39m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m\e[38;5;31m\e[0m\e[38;5;31m\e[49m \e[0m\e[38;5;31m\e[49m\e[38;5;76m \e[38;5;76m feature/update-prompt \e[38;5;76m*2 \e[38;5;39m?1\e[0m\e[38;5;39m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m \e[0m\e[30m\e[49m\e[39m\e[38;5;238m······················\e[0m\e[38;5;238m\e[49m\e[30m \e[0m\e[30m\e[49m\e[38;5;101m 6s\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;101m\e[0m\e[38;5;101m\e[49m\e[38;5;66m  13:46:57\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[38;5;66m\e[0m\e[38;5;66m\e[49m\e[39m\r\n\e[0m\e[49m\e[39m\e[0m\e[49m\e[38;5;76m❯\e[0m\e[38;5;76m\e[49m\e[38;5;76m\e[0m\e[38;5;76m\e[49m\e[30m\e[0m\e[30m\e[49m\e[39m \e[0m\e[49m\e[39m\e]697;EndPrompt\a\e]697;NewCmd=58e0f86ba8914f90a6ad6f3a8774bf98\a\e[K\e[102C\e]697;StartPrompt\a\e]697;EndPrompt\a\e[102D\e[?1h\e=\e[?2004h" + - delay: 686 + content: "\e[?2004l\r\r\n" diff --git a/package.json b/package.json new file mode 100644 index 0000000..1a84ef0 --- /dev/null +++ b/package.json @@ -0,0 +1,198 @@ +{ + "name": "aipick", + "version": "0.0.0-semantic-release", + "description": "An interactive CLI tool that leverages multiple AI models", + "keywords": [ + "cli", + "ai", + "command-line", + "commandline", + "cli", + "aipick", + "aicommit2", + "openai", + "huggingface", + "hugging face", + "anthropic", + "claude", + "claude3", + "gemini", + "gemini-pro", + "generative-ai", + "mistral", + "codestral", + "ollama", + "llama3", + "llama3.1", + "llm", + "chatgpt", + "cohere", + "groq" + ], + "license": "MIT", + "repository": "tak-bro/aipick", + "author": "Hyungtak Jin(@tak-bro)", + "type": "module", + "files": [ + "dist" + ], + "bin": { + "aipick": "./dist/cli.mjs", + "aip": "./dist/cli.mjs" + }, + "scripts": { + "prepare": "simple-git-hooks", + "build": "pkgroll --minify", + "lint": "eslint --cache .", + "type-check": "tsc", + "test": "tsx tests", + "prepack": "pnpm build && clean-pkg-json", + "prettier": "prettier" + }, + "simple-git-hooks": { + "pre-commit": "pnpm lint-staged" + }, + "lint-staged": { + "*.ts": [ + "prettier --config ./.prettierrc --write", + "eslint --fix" + ] + }, + "dependencies": { + "@anthropic-ai/sdk": "^0.20.8", + "@dqbd/tiktoken": "^1.0.2", + "@google/generative-ai": "^0.15.0", + "@inquirer/prompts": "^3.0.0", + "@pacote/xxhash": "^0.3.2", + "axios": "^1.6.8", + "chalk": "^5.3.0", + "cohere-ai": "^7.11.0", + "copy-paste": "^1.5.3", + "figlet": "^1.7.0", + "formdata-node": "^6.0.3", + "groq-sdk": "^0.4.0", + "inquirer": "9.2.8", + "inquirer-reactive-list-prompt": "^1.0.8", + "ollama": "^0.5.6", + "ora": "^8.0.1", + "readline": "^1.3.0", + "rxjs": "^7.8.1", + "uuid": "^9.0.1" + }, + "devDependencies": { + "@pvtnbr/eslint-config": "^0.33.0", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/commit-analyzer": "^12.0.0", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^10.0.3", + "@semantic-release/npm": "^12.0.0", + "@semantic-release/release-notes-generator": "^13.0.0", + "@types/figlet": "^1.5.8", + "@types/ini": "^1.3.31", + "@types/inquirer": "^9.0.3", + "@types/node": "^18.14.2", + "@types/uuid": "^9.0.8", + "@typescript-eslint/eslint-plugin": "^6.13.2", + "@typescript-eslint/parser": "^6.2.0", + "clean-pkg-json": "^1.2.0", + "cleye": "^1.3.2", + "conventional-changelog-conventionalcommits": "^7.0.2", + "conventional-commits-parser": "^5.0.0", + "eslint": "^8.52.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsonc": "^2.10.0", + "eslint-plugin-no-use-extend-native": "^0.5.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-unicorn": "^49.0.0", + "eslint-plugin-unused-imports": "^3.0.0", + "execa": "^7.0.0", + "fs-fixture": "^1.2.0", + "https-proxy-agent": "^5.0.1", + "ini": "^3.0.1", + "lint-staged": "^13.1.2", + "manten": "^0.7.0", + "openai": "^3.2.1", + "pkgroll": "^1.9.0", + "prettier": "^3.0.0", + "semantic-release": "^23.0.2", + "simple-git-hooks": "^2.8.1", + "tsx": "^3.12.3", + "typescript": "^4.9.5" + }, + "eslintConfig": { + "extends": [ + "@pvtnbr", + "prettier" + ], + "rules": { + "unicorn/no-process-exit": "off" + }, + "overrides": [ + { + "files": "./src/commands/prepare-commit-msg-hook.ts", + "rules": { + "unicorn/prevent-abbreviations": "off" + } + } + ] + }, + "release": { + "branches": [ + "main" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "type": "refactor", + "release": "patch" + }, + { + "type": "chore", + "release": "patch" + }, + { + "type": "feat", + "release": "patch" + }, + { + "scope": "major", + "release": "major" + }, + { + "scope": "minor", + "release": "minor" + }, + { + "scope": "patch", + "release": "patch" + } + ] + } + ], + "@semantic-release/release-notes-generator", + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md" + } + ], + "@semantic-release/github", + [ + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md" + ], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ], + "@semantic-release/npm" + ] + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..30018cd --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,7685 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@anthropic-ai/sdk': + specifier: ^0.20.8 + version: 0.20.9 + '@dqbd/tiktoken': + specifier: ^1.0.2 + version: 1.0.15 + '@google/generative-ai': + specifier: ^0.15.0 + version: 0.15.0 + '@inquirer/prompts': + specifier: ^3.0.0 + version: 3.3.2 + '@pacote/xxhash': + specifier: ^0.3.2 + version: 0.3.2 + axios: + specifier: ^1.6.8 + version: 1.7.2 + chalk: + specifier: ^5.3.0 + version: 5.3.0 + cohere-ai: + specifier: ^7.11.0 + version: 7.11.0(@aws-sdk/client-sso-oidc@3.616.0) + copy-paste: + specifier: ^1.5.3 + version: 1.5.3 + figlet: + specifier: ^1.7.0 + version: 1.7.0 + formdata-node: + specifier: ^6.0.3 + version: 6.0.3 + groq-sdk: + specifier: ^0.4.0 + version: 0.4.0 + inquirer: + specifier: 9.2.8 + version: 9.2.8 + inquirer-reactive-list-prompt: + specifier: ^1.0.8 + version: 1.0.8(inquirer@9.2.8) + ollama: + specifier: ^0.5.6 + version: 0.5.6 + ora: + specifier: ^8.0.1 + version: 8.0.1 + readline: + specifier: ^1.3.0 + version: 1.3.0 + rxjs: + specifier: ^7.8.1 + version: 7.8.1 + uuid: + specifier: ^9.0.1 + version: 9.0.1 + +devDependencies: + '@pvtnbr/eslint-config': + specifier: ^0.33.0 + version: 0.33.0(eslint@8.57.0)(typescript@4.9.5) + '@semantic-release/changelog': + specifier: ^6.0.3 + version: 6.0.3(semantic-release@23.1.1) + '@semantic-release/commit-analyzer': + specifier: ^12.0.0 + version: 12.0.0(semantic-release@23.1.1) + '@semantic-release/git': + specifier: ^10.0.1 + version: 10.0.1(semantic-release@23.1.1) + '@semantic-release/github': + specifier: ^10.0.3 + version: 10.1.1(semantic-release@23.1.1) + '@semantic-release/npm': + specifier: ^12.0.0 + version: 12.0.1(semantic-release@23.1.1) + '@semantic-release/release-notes-generator': + specifier: ^13.0.0 + version: 13.0.0(semantic-release@23.1.1) + '@types/figlet': + specifier: ^1.5.8 + version: 1.5.8 + '@types/ini': + specifier: ^1.3.31 + version: 1.3.34 + '@types/inquirer': + specifier: ^9.0.3 + version: 9.0.7 + '@types/node': + specifier: ^18.14.2 + version: 18.19.42 + '@types/uuid': + specifier: ^9.0.8 + version: 9.0.8 + '@typescript-eslint/eslint-plugin': + specifier: ^6.13.2 + version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: ^6.2.0 + version: 6.21.0(eslint@8.57.0)(typescript@4.9.5) + clean-pkg-json: + specifier: ^1.2.0 + version: 1.2.0 + cleye: + specifier: ^1.3.2 + version: 1.3.2 + conventional-changelog-conventionalcommits: + specifier: ^7.0.2 + version: 7.0.2 + conventional-commits-parser: + specifier: ^5.0.0 + version: 5.0.0 + eslint: + specifier: ^8.52.0 + version: 8.57.0 + eslint-config-prettier: + specifier: ^8.8.0 + version: 8.10.0(eslint@8.57.0) + eslint-plugin-eslint-comments: + specifier: ^3.2.0 + version: 3.2.0(eslint@8.57.0) + eslint-plugin-import: + specifier: ^2.29.1 + version: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0) + eslint-plugin-jsonc: + specifier: ^2.10.0 + version: 2.16.0(eslint@8.57.0) + eslint-plugin-no-use-extend-native: + specifier: ^0.5.0 + version: 0.5.0 + eslint-plugin-promise: + specifier: ^6.1.1 + version: 6.6.0(eslint@8.57.0) + eslint-plugin-unicorn: + specifier: ^49.0.0 + version: 49.0.0(eslint@8.57.0) + eslint-plugin-unused-imports: + specifier: ^3.0.0 + version: 3.2.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.57.0) + execa: + specifier: ^7.0.0 + version: 7.2.0 + fs-fixture: + specifier: ^1.2.0 + version: 1.2.0 + https-proxy-agent: + specifier: ^5.0.1 + version: 5.0.1 + ini: + specifier: ^3.0.1 + version: 3.0.1 + lint-staged: + specifier: ^13.1.2 + version: 13.3.0 + manten: + specifier: ^0.7.0 + version: 0.7.0 + openai: + specifier: ^3.2.1 + version: 3.3.0 + pkgroll: + specifier: ^1.9.0 + version: 1.11.1(typescript@4.9.5) + prettier: + specifier: ^3.0.0 + version: 3.3.3 + semantic-release: + specifier: ^23.0.2 + version: 23.1.1(typescript@4.9.5) + simple-git-hooks: + specifier: ^2.8.1 + version: 2.11.1 + tsx: + specifier: ^3.12.3 + version: 3.14.0 + typescript: + specifier: ^4.9.5 + version: 4.9.5 + +packages: + + /@anthropic-ai/sdk@0.20.9: + resolution: {integrity: sha512-Lq74+DhiEQO6F9/gdVOLmHx57pX45ebK2Q/zH14xYe1157a7QeUVknRqIp0Jz5gQI01o7NKbuv9Dag2uQsLjDg==} + dependencies: + '@types/node': 18.19.42 + '@types/node-fetch': 2.6.11 + abort-controller: 3.0.0 + agentkeepalive: 4.5.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + web-streams-polyfill: 3.3.3 + transitivePeerDependencies: + - encoding + dev: false + + /@aws-crypto/crc32@3.0.0: + resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} + dependencies: + '@aws-crypto/util': 3.0.0 + '@aws-sdk/types': 3.609.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/sha256-browser@5.2.0: + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-locate-window': 3.568.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.3 + dev: false + + /@aws-crypto/sha256-js@5.2.0: + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.609.0 + tslib: 2.6.3 + dev: false + + /@aws-crypto/supports-web-crypto@5.2.0: + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} + dependencies: + tslib: 2.6.3 + dev: false + + /@aws-crypto/util@3.0.0: + resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} + dependencies: + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-utf8-browser': 3.259.0 + tslib: 1.14.1 + dev: false + + /@aws-crypto/util@5.2.0: + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/client-cognito-identity@3.616.0: + resolution: {integrity: sha512-3yli0rchw7FuI8CmxUKW5z6TzrAJzBm9x+Se20Gqm0idXc2X2RT4Z8axtni5umBu8+4QWgNDZAr/WG6bR/JUGA==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/client-sts': 3.616.0 + '@aws-sdk/core': 3.616.0 + '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/middleware-logger': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.616.0 + '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/region-config-resolver': 3.614.0 + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-endpoints': 3.614.0 + '@aws-sdk/util-user-agent-browser': 3.609.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.2.8 + '@smithy/fetch-http-handler': 3.2.2 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.4 + '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.11 + '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-endpoints': 2.0.5 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sagemaker@3.616.0: + resolution: {integrity: sha512-5/mL2lcHi2xs6MwQPjPsyZZMoiNpyRbNXPsDP16F1gtcRgm1hQ/Afo/O+DVqtNf7n1WnbiCYSp69B8PqgoYE0g==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/client-sts': 3.616.0 + '@aws-sdk/core': 3.616.0 + '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/middleware-logger': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.616.0 + '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/region-config-resolver': 3.614.0 + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-endpoints': 3.614.0 + '@aws-sdk/util-user-agent-browser': 3.609.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.2.8 + '@smithy/fetch-http-handler': 3.2.2 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.4 + '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.11 + '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-endpoints': 2.0.5 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 + '@smithy/util-waiter': 3.1.2 + tslib: 2.6.3 + uuid: 9.0.1 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0): + resolution: {integrity: sha512-YY1hpYS/G1uRGjQf88dL8VLHkP/IjGxKeXdhy+JnzMdCkAWl3V9j0fEALw40NZe0x79gr6R2KUOUH/IKYQfUmg==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.616.0 + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sts': 3.616.0 + '@aws-sdk/core': 3.616.0 + '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/middleware-logger': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.616.0 + '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/region-config-resolver': 3.614.0 + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-endpoints': 3.614.0 + '@aws-sdk/util-user-agent-browser': 3.609.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.2.8 + '@smithy/fetch-http-handler': 3.2.2 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.4 + '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.11 + '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-endpoints': 2.0.5 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sso@3.616.0: + resolution: {integrity: sha512-hwW0u1f8U4dSloAe61/eupUiGd5Q13B72BuzGxvRk0cIpYX/2m0KBG8DDl7jW1b2QQ+CflTLpG2XUf2+vRJxGA==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.616.0 + '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/middleware-logger': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.616.0 + '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/region-config-resolver': 3.614.0 + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-endpoints': 3.614.0 + '@aws-sdk/util-user-agent-browser': 3.609.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.2.8 + '@smithy/fetch-http-handler': 3.2.2 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.4 + '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.11 + '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-endpoints': 2.0.5 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/client-sts@3.616.0: + resolution: {integrity: sha512-FP7i7hS5FpReqnysQP1ukQF1OUWy8lkomaOnbu15H415YUrfCp947SIx6+BItjmx+esKxPkEjh/fbCVzw2D6hQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/core': 3.616.0 + '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/middleware-logger': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.616.0 + '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/region-config-resolver': 3.614.0 + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-endpoints': 3.614.0 + '@aws-sdk/util-user-agent-browser': 3.609.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.2.8 + '@smithy/fetch-http-handler': 3.2.2 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.4 + '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.11 + '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-endpoints': 2.0.5 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/core@3.616.0: + resolution: {integrity: sha512-O/urkh2kECs/IqZIVZxyeyHZ7OR2ZWhLNK7btsVQBQvJKrEspLrk/Fp20Qfg5JDerQfBN83ZbyRXLJOOucdZpw==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/core': 2.2.8 + '@smithy/protocol-http': 4.0.4 + '@smithy/signature-v4': 4.0.0 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + fast-xml-parser: 4.2.5 + tslib: 2.6.3 + dev: false + + /@aws-sdk/credential-provider-cognito-identity@3.616.0: + resolution: {integrity: sha512-bcsf36gdGY2SpvTmoxd7t2235q+Rjg6xnTeCiKs9YuzbNezZ4FosqSORs7/vu2CvyaXWwV28909Q1boZ76v4TA==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/client-cognito-identity': 3.616.0 + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - aws-crt + dev: false + + /@aws-sdk/credential-provider-env@3.609.0: + resolution: {integrity: sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/credential-provider-http@3.616.0: + resolution: {integrity: sha512-1rgCkr7XvEMBl7qWCo5BKu3yAxJs71dRaZ55Xnjte/0ZHH6Oc93ZrHzyYy6UH6t0nZrH+FAuw7Yko2YtDDwDeg==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/fetch-http-handler': 3.2.2 + '@smithy/node-http-handler': 3.1.3 + '@smithy/property-provider': 3.1.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/util-stream': 3.1.1 + tslib: 2.6.3 + dev: false + + /@aws-sdk/credential-provider-ini@3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0): + resolution: {integrity: sha512-5gQdMr9cca3xV7FF2SxpxWGH2t6+t4o+XBGiwsHm8muEjf4nUmw7Ij863x25Tjt2viPYV0UStczSb5Sihp7bkA==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.616.0 + dependencies: + '@aws-sdk/client-sts': 3.616.0 + '@aws-sdk/credential-provider-env': 3.609.0 + '@aws-sdk/credential-provider-http': 3.616.0 + '@aws-sdk/credential-provider-process': 3.614.0 + '@aws-sdk/credential-provider-sso': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0) + '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/types': 3.609.0 + '@smithy/credential-provider-imds': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + dev: false + + /@aws-sdk/credential-provider-node@3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0): + resolution: {integrity: sha512-Se+u6DAxjDPjKE3vX1X2uxjkWgGq69BTo0uTB0vDUiWwBVgh16s9BsBhSAlKEH1CCbbJHvOg4YdTrzjwzqyClg==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/credential-provider-env': 3.609.0 + '@aws-sdk/credential-provider-http': 3.616.0 + '@aws-sdk/credential-provider-ini': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/credential-provider-process': 3.614.0 + '@aws-sdk/credential-provider-sso': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0) + '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/types': 3.609.0 + '@smithy/credential-provider-imds': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - '@aws-sdk/client-sts' + - aws-crt + dev: false + + /@aws-sdk/credential-provider-process@3.614.0: + resolution: {integrity: sha512-Q0SI0sTRwi8iNODLs5+bbv8vgz8Qy2QdxbCHnPk/6Cx6LMf7i3dqmWquFbspqFRd8QiqxStrblwxrUYZi09tkA==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/credential-provider-sso@3.616.0(@aws-sdk/client-sso-oidc@3.616.0): + resolution: {integrity: sha512-3rsWs9GBi8Z8Gps5ROwqguxtw+J6OIg1vawZMLRNMqqZoBvbOToe9wEnpid8ylU+27+oG8uibJNlNuRyXApUjw==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/client-sso': 3.616.0 + '@aws-sdk/token-providers': 3.614.0(@aws-sdk/client-sso-oidc@3.616.0) + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + dev: false + + /@aws-sdk/credential-provider-web-identity@3.609.0(@aws-sdk/client-sts@3.616.0): + resolution: {integrity: sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.609.0 + dependencies: + '@aws-sdk/client-sts': 3.616.0 + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/credential-providers@3.617.0(@aws-sdk/client-sso-oidc@3.616.0): + resolution: {integrity: sha512-ZXzdnHI7Tfsk7Y2hezlhxFHlG2VM5tTWQPZ0qZ/cYCzZxyZfsmSFr/rMi6wJGB2J6ZDbbAohEoOWrEblHVq7Cw==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/client-cognito-identity': 3.616.0 + '@aws-sdk/client-sso': 3.616.0 + '@aws-sdk/client-sts': 3.616.0 + '@aws-sdk/credential-provider-cognito-identity': 3.616.0 + '@aws-sdk/credential-provider-env': 3.609.0 + '@aws-sdk/credential-provider-http': 3.616.0 + '@aws-sdk/credential-provider-ini': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/credential-provider-process': 3.614.0 + '@aws-sdk/credential-provider-sso': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0) + '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/types': 3.609.0 + '@smithy/credential-provider-imds': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + dev: false + + /@aws-sdk/middleware-host-header@3.616.0: + resolution: {integrity: sha512-mhNfHuGhCDZwYCABebaOvTgOM44UCZZRq2cBpgPZLVKP0ydAv5aFHXv01goexxXHqgHoEGx0uXWxlw0s2EpFDg==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/protocol-http': 4.0.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/middleware-logger@3.609.0: + resolution: {integrity: sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/middleware-recursion-detection@3.616.0: + resolution: {integrity: sha512-LQKAcrZRrR9EGez4fdCIVjdn0Ot2HMN12ChnoMGEU6oIxnQ2aSC7iASFFCV39IYfeMh7iSCPj7Wopqw8rAouzg==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/protocol-http': 4.0.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/middleware-user-agent@3.616.0: + resolution: {integrity: sha512-iMcAb4E+Z3vuEcrDsG6T2OBNiqWAquwahP9qepHqfmnmJqHr1mSHtXDYTGBNid31+621sUQmneUQ+fagpGAe4w==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-endpoints': 3.614.0 + '@smithy/protocol-http': 4.0.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/protocol-http@3.374.0: + resolution: {integrity: sha512-9WpRUbINdGroV3HiZZIBoJvL2ndoWk39OfwxWs2otxByppJZNN14bg/lvCx5e8ggHUti7IBk5rb0nqQZ4m05pg==} + engines: {node: '>=14.0.0'} + deprecated: This package has moved to @smithy/protocol-http + dependencies: + '@smithy/protocol-http': 1.2.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/region-config-resolver@3.614.0: + resolution: {integrity: sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.3 + tslib: 2.6.3 + dev: false + + /@aws-sdk/signature-v4@3.374.0: + resolution: {integrity: sha512-2xLJvSdzcZZAg0lsDLUAuSQuihzK0dcxIK7WmfuJeF7DGKJFmp9czQmz5f3qiDz6IDQzvgK1M9vtJSVCslJbyQ==} + engines: {node: '>=14.0.0'} + deprecated: This package has moved to @smithy/signature-v4 + dependencies: + '@smithy/signature-v4': 1.1.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.616.0): + resolution: {integrity: sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sso-oidc': ^3.614.0 + dependencies: + '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/types@3.609.0: + resolution: {integrity: sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/util-endpoints@3.614.0: + resolution: {integrity: sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/types': 3.3.0 + '@smithy/util-endpoints': 2.0.5 + tslib: 2.6.3 + dev: false + + /@aws-sdk/util-locate-window@3.568.0: + resolution: {integrity: sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@aws-sdk/util-user-agent-browser@3.609.0: + resolution: {integrity: sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==} + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/types': 3.3.0 + bowser: 2.11.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/util-user-agent-node@3.614.0: + resolution: {integrity: sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==} + engines: {node: '>=16.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@aws-sdk/util-utf8-browser@3.259.0: + resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} + dependencies: + tslib: 2.6.3 + dev: false + + /@babel/code-frame@7.24.7: + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + dev: true + + /@babel/helper-validator-identifier@7.24.7: + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/highlight@7.24.7: + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + dev: true + + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + + /@dqbd/tiktoken@1.0.15: + resolution: {integrity: sha512-a6I67K1xUkuqcuwulobIJiLikkoE7egMaviI1Jg5bxSn2V7QGqXsGE3jTKr8UIOU/o74mAAd5TkeXFNBtaKF4A==} + dev: false + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.11.0: + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.5 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@google/generative-ai@0.15.0: + resolution: {integrity: sha512-zs37judcTYFJf1U7tnuqnh7gdzF6dcWj9pNRxjA5JTONRoiQ0htrRdbefRFiewOIfXwhun5t9hbd2ray7812eQ==} + engines: {node: '>=18.0.0'} + dev: false + + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.5 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.3: + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + dev: true + + /@inquirer/checkbox@1.5.2: + resolution: {integrity: sha512-CifrkgQjDkUkWexmgYYNyB5603HhTHI91vLFeQXh6qrTKiCMVASol01Rs1cv6LP/A2WccZSRlJKZhbaBIs/9ZA==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + figures: 3.2.0 + dev: false + + /@inquirer/confirm@2.0.17: + resolution: {integrity: sha512-EqzhGryzmGpy2aJf6LxJVhndxYmFs+m8cxXzf8nejb1DE3sabf6mUgBcp4J0jAUEiAcYzqmkqRr7LPFh/WdnXA==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + chalk: 4.1.2 + dev: false + + /@inquirer/core@6.0.0: + resolution: {integrity: sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/type': 1.5.1 + '@types/mute-stream': 0.0.4 + '@types/node': 20.14.12 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + figures: 3.2.0 + mute-stream: 1.0.0 + run-async: 3.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: false + + /@inquirer/editor@1.2.15: + resolution: {integrity: sha512-gQ77Ls09x5vKLVNMH9q/7xvYPT6sIs5f7URksw+a2iJZ0j48tVS6crLqm2ugG33tgXHIwiEqkytY60Zyh5GkJQ==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + chalk: 4.1.2 + external-editor: 3.1.0 + dev: false + + /@inquirer/expand@1.1.16: + resolution: {integrity: sha512-TGLU9egcuo+s7PxphKUCnJnpCIVY32/EwPCLLuu+gTvYiD8hZgx8Z2niNQD36sa6xcfpdLY6xXDBiL/+g1r2XQ==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + chalk: 4.1.2 + figures: 3.2.0 + dev: false + + /@inquirer/input@1.2.16: + resolution: {integrity: sha512-Ou0LaSWvj1ni+egnyQ+NBtfM1885UwhRCMtsRt2bBO47DoC1dwtCa+ZUNgrxlnCHHF0IXsbQHYtIIjFGAavI4g==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + chalk: 4.1.2 + dev: false + + /@inquirer/password@1.1.16: + resolution: {integrity: sha512-aZYZVHLUXZ2gbBot+i+zOJrks1WaiI95lvZCn1sKfcw6MtSSlYC8uDX8sTzQvAsQ8epHoP84UNvAIT0KVGOGqw==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + dev: false + + /@inquirer/prompts@3.3.2: + resolution: {integrity: sha512-k52mOMRvTUejrqyF1h8Z07chC+sbaoaUYzzr1KrJXyj7yaX7Nrh0a9vktv8TuocRwIJOQMaj5oZEmkspEcJFYQ==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/checkbox': 1.5.2 + '@inquirer/confirm': 2.0.17 + '@inquirer/core': 6.0.0 + '@inquirer/editor': 1.2.15 + '@inquirer/expand': 1.1.16 + '@inquirer/input': 1.2.16 + '@inquirer/password': 1.1.16 + '@inquirer/rawlist': 1.2.16 + '@inquirer/select': 1.3.3 + dev: false + + /@inquirer/rawlist@1.2.16: + resolution: {integrity: sha512-pZ6TRg2qMwZAOZAV6TvghCtkr53dGnK29GMNQ3vMZXSNguvGqtOVc4j/h1T8kqGJFagjyfBZhUPGwNS55O5qPQ==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + chalk: 4.1.2 + dev: false + + /@inquirer/select@1.3.3: + resolution: {integrity: sha512-RzlRISXWqIKEf83FDC9ZtJ3JvuK1l7aGpretf41BCWYrvla2wU8W8MTRNMiPrPJ+1SIqrRC1nZdZ60hD9hRXLg==} + engines: {node: '>=14.18.0'} + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + figures: 3.2.0 + dev: false + + /@inquirer/type@1.5.1: + resolution: {integrity: sha512-m3YgGQlKNS0BM+8AFiJkCsTqHEFCWn6s/Rqye3mYwvqY6LdfUv12eSwbsgNzrYyrLXiy7IrrjDLPysaSBwEfhw==} + engines: {node: '>=18'} + dependencies: + mute-stream: 1.0.0 + dev: false + + /@jest/expect-utils@29.7.0: + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + dev: true + + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 18.19.42 + '@types/yargs': 17.0.32 + chalk: 4.1.2 + dev: true + + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + dev: true + + /@octokit/auth-token@5.1.1: + resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==} + engines: {node: '>= 18'} + dev: true + + /@octokit/core@6.1.2: + resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==} + engines: {node: '>= 18'} + dependencies: + '@octokit/auth-token': 5.1.1 + '@octokit/graphql': 8.1.1 + '@octokit/request': 9.1.3 + '@octokit/request-error': 6.1.4 + '@octokit/types': 13.5.0 + before-after-hook: 3.0.2 + universal-user-agent: 7.0.2 + dev: true + + /@octokit/endpoint@10.1.1: + resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==} + engines: {node: '>= 18'} + dependencies: + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + dev: true + + /@octokit/graphql@8.1.1: + resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==} + engines: {node: '>= 18'} + dependencies: + '@octokit/request': 9.1.3 + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + dev: true + + /@octokit/openapi-types@22.2.0: + resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==} + dev: true + + /@octokit/plugin-paginate-rest@11.3.3(@octokit/core@6.1.2): + resolution: {integrity: sha512-o4WRoOJZlKqEEgj+i9CpcmnByvtzoUYC6I8PD2SA95M+BJ2x8h7oLcVOg9qcowWXBOdcTRsMZiwvM3EyLm9AfA==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.5.0 + dev: true + + /@octokit/plugin-retry@7.1.1(@octokit/core@6.1.2): + resolution: {integrity: sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + dependencies: + '@octokit/core': 6.1.2 + '@octokit/request-error': 6.1.4 + '@octokit/types': 13.5.0 + bottleneck: 2.19.5 + dev: true + + /@octokit/plugin-throttling@9.3.1(@octokit/core@6.1.2): + resolution: {integrity: sha512-Qd91H4liUBhwLB2h6jZ99bsxoQdhgPk6TdwnClPyTBSDAdviGPceViEgUwj+pcQDmB/rfAXAXK7MTochpHM3yQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': ^6.0.0 + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.5.0 + bottleneck: 2.19.5 + dev: true + + /@octokit/request-error@6.1.4: + resolution: {integrity: sha512-VpAhIUxwhWZQImo/dWAN/NpPqqojR6PSLgLYAituLM6U+ddx9hCioFGwBr5Mi+oi5CLeJkcAs3gJ0PYYzU6wUg==} + engines: {node: '>= 18'} + dependencies: + '@octokit/types': 13.5.0 + dev: true + + /@octokit/request@9.1.3: + resolution: {integrity: sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==} + engines: {node: '>= 18'} + dependencies: + '@octokit/endpoint': 10.1.1 + '@octokit/request-error': 6.1.4 + '@octokit/types': 13.5.0 + universal-user-agent: 7.0.2 + dev: true + + /@octokit/types@13.5.0: + resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==} + dependencies: + '@octokit/openapi-types': 22.2.0 + dev: true + + /@pacote/u64@0.2.2: + resolution: {integrity: sha512-J4xs42l+Anz3/Qq6ocSWq4OSub7nn9DfNHIWC4dd4XPQlBIzKbE2Qf65m9W+ogYMMNzKRwJ2kbqq1RT4sMPfKg==} + dev: false + + /@pacote/xxhash@0.3.2: + resolution: {integrity: sha512-vj6qcyl9kaNXZFZ6xsm8hREMRF2wHk70X9okGVPua0bcL052ZHLvYnxIbc9Bdv6lX/9qvxjg9E0ufi7+CFB6NA==} + dependencies: + '@pacote/u64': 0.2.2 + dev: false + + /@pnpm/config.env-replace@1.1.0: + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + dev: true + + /@pnpm/network.ca-file@1.0.2: + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + dependencies: + graceful-fs: 4.2.10 + dev: true + + /@pnpm/npm-conf@2.2.2: + resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} + engines: {node: '>=12'} + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + dev: true + + /@pvtnbr/eslint-config@0.33.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-27Zs5L1LKtT4DKfFPalPTjImCiU3UMvfTMIModuFWn7nhGhbv4SEUPo5pc8fYoTgmAlnwp/NNMhw3yUUFZKyzw==} + peerDependencies: + eslint: ^7.15.0 || ^8.0.0 + dependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + confusing-browser-globals: 1.0.11 + eslint: 8.57.0 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-jsonc: 2.16.0(eslint@8.57.0) + eslint-plugin-markdown: 3.0.1(eslint@8.57.0) + eslint-plugin-no-use-extend-native: 0.5.0 + eslint-plugin-node: 11.1.0(eslint@8.57.0) + eslint-plugin-promise: 6.6.0(eslint@8.57.0) + eslint-plugin-react: 7.35.0(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + eslint-plugin-regexp: 1.15.0(eslint@8.57.0) + eslint-plugin-unicorn: 44.0.2(eslint@8.57.0) + eslint-plugin-vue: 9.27.0(eslint@8.57.0) + transitivePeerDependencies: + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + - typescript + dev: true + + /@rollup/plugin-alias@4.0.4(rollup@2.79.1): + resolution: {integrity: sha512-0CaAY238SMtYAWEXXptWSR8iz8NYZnH7zNBKuJ14xFJSGwLtPgjvXYsoApAHfzYXXH1ejxpVw7WlHss3zhh9SQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 2.79.1 + slash: 4.0.0 + dev: true + + /@rollup/plugin-commonjs@24.1.0(rollup@2.79.1): + resolution: {integrity: sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.27.0 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-inject@5.0.5(rollup@2.79.1): + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + estree-walker: 2.0.2 + magic-string: 0.30.10 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-json@6.1.0(rollup@2.79.1): + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + rollup: 2.79.1 + dev: true + + /@rollup/plugin-node-resolve@15.2.3(rollup@2.79.1): + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-replace@5.0.7(rollup@2.79.1): + resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + magic-string: 0.30.10 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils@5.1.0(rollup@2.79.1): + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + + /@sec-ant/readable-stream@0.4.1: + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + dev: true + + /@semantic-release/changelog@6.0.3(semantic-release@23.1.1): + resolution: {integrity: sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==} + engines: {node: '>=14.17'} + peerDependencies: + semantic-release: '>=18.0.0' + dependencies: + '@semantic-release/error': 3.0.0 + aggregate-error: 3.1.0 + fs-extra: 11.2.0 + lodash: 4.17.21 + semantic-release: 23.1.1(typescript@4.9.5) + dev: true + + /@semantic-release/commit-analyzer@12.0.0(semantic-release@23.1.1): + resolution: {integrity: sha512-qG+md5gdes+xa8zP7lIo1fWE17zRdO8yMCaxh9lyL65TQleoSv8WHHOqRURfghTytUh+NpkSyBprQ5hrkxOKVQ==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + conventional-changelog-angular: 7.0.0 + conventional-commits-filter: 4.0.0 + conventional-commits-parser: 5.0.0 + debug: 4.3.5 + import-from-esm: 1.3.4 + lodash-es: 4.17.21 + micromatch: 4.0.7 + semantic-release: 23.1.1(typescript@4.9.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@semantic-release/error@3.0.0: + resolution: {integrity: sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==} + engines: {node: '>=14.17'} + dev: true + + /@semantic-release/error@4.0.0: + resolution: {integrity: sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==} + engines: {node: '>=18'} + dev: true + + /@semantic-release/git@10.0.1(semantic-release@23.1.1): + resolution: {integrity: sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==} + engines: {node: '>=14.17'} + peerDependencies: + semantic-release: '>=18.0.0' + dependencies: + '@semantic-release/error': 3.0.0 + aggregate-error: 3.1.0 + debug: 4.3.5 + dir-glob: 3.0.1 + execa: 5.1.1 + lodash: 4.17.21 + micromatch: 4.0.7 + p-reduce: 2.1.0 + semantic-release: 23.1.1(typescript@4.9.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@semantic-release/github@10.1.1(semantic-release@23.1.1): + resolution: {integrity: sha512-sSmsBKGpAlTtXf9rUJf/si16p+FwPEsvsJRjl3KCwFP0WywaSpynvUhlYvE18n5rzkQNbGJnObAKIoo3xFMSjA==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + '@octokit/core': 6.1.2 + '@octokit/plugin-paginate-rest': 11.3.3(@octokit/core@6.1.2) + '@octokit/plugin-retry': 7.1.1(@octokit/core@6.1.2) + '@octokit/plugin-throttling': 9.3.1(@octokit/core@6.1.2) + '@semantic-release/error': 4.0.0 + aggregate-error: 5.0.0 + debug: 4.3.5 + dir-glob: 3.0.1 + globby: 14.0.2 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 + issue-parser: 7.0.1 + lodash-es: 4.17.21 + mime: 4.0.4 + p-filter: 4.1.0 + semantic-release: 23.1.1(typescript@4.9.5) + url-join: 5.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@semantic-release/npm@12.0.1(semantic-release@23.1.1): + resolution: {integrity: sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + '@semantic-release/error': 4.0.0 + aggregate-error: 5.0.0 + execa: 9.3.0 + fs-extra: 11.2.0 + lodash-es: 4.17.21 + nerf-dart: 1.0.0 + normalize-url: 8.0.1 + npm: 10.8.2 + rc: 1.2.8 + read-pkg: 9.0.1 + registry-auth-token: 5.0.2 + semantic-release: 23.1.1(typescript@4.9.5) + semver: 7.6.3 + tempy: 3.1.0 + dev: true + + /@semantic-release/release-notes-generator@13.0.0(semantic-release@23.1.1): + resolution: {integrity: sha512-LEeZWb340keMYuREMyxrODPXJJ0JOL8D/mCl74B4LdzbxhtXV2LrPN2QBEcGJrlQhoqLO0RhxQb6masHytKw+A==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' + dependencies: + conventional-changelog-angular: 7.0.0 + conventional-changelog-writer: 7.0.1 + conventional-commits-filter: 4.0.0 + conventional-commits-parser: 5.0.0 + debug: 4.3.5 + get-stream: 7.0.1 + import-from-esm: 1.3.4 + into-stream: 7.0.0 + lodash-es: 4.17.21 + read-pkg-up: 11.0.0 + semantic-release: 23.1.1(typescript@4.9.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + + /@sindresorhus/is@4.6.0: + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + dev: true + + /@sindresorhus/merge-streams@2.3.0: + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + dev: true + + /@sindresorhus/merge-streams@4.0.0: + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + dev: true + + /@smithy/abort-controller@3.1.1: + resolution: {integrity: sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/config-resolver@3.0.5: + resolution: {integrity: sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.3 + tslib: 2.6.3 + dev: false + + /@smithy/core@2.2.8: + resolution: {integrity: sha512-1Y0XX0Ucyg0LWTfTVLWpmvSRtFRniykUl3dQ0os1sTd03mKDudR6mVyX+2ak1phwPXx2aEWMAAdW52JNi0mc3A==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-serde': 3.0.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.3 + tslib: 2.6.3 + dev: false + + /@smithy/credential-provider-imds@3.1.4: + resolution: {integrity: sha512-NKyH01m97Xa5xf3pB2QOF3lnuE8RIK0hTVNU5zvZAwZU8uspYO4DHQVlK+Y5gwSrujTfHvbfd1D9UFJAc0iYKQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + tslib: 2.6.3 + dev: false + + /@smithy/eventstream-codec@1.1.0: + resolution: {integrity: sha512-3tEbUb8t8an226jKB6V/Q2XU/J53lCwCzULuBPEaF4JjSh+FlCMp7TmogE/Aij5J9DwlsZ4VAD/IRDuQ/0ZtMw==} + dependencies: + '@aws-crypto/crc32': 3.0.0 + '@smithy/types': 1.2.0 + '@smithy/util-hex-encoding': 1.1.0 + tslib: 2.6.3 + dev: false + + /@smithy/fetch-http-handler@3.2.2: + resolution: {integrity: sha512-3LaWlBZObyGrOOd7e5MlacnAKEwFBmAeiW/TOj2eR9475Vnq30uS2510+tnKbxrGjROfNdOhQqGo5j3sqLT6bA==} + dependencies: + '@smithy/protocol-http': 4.0.4 + '@smithy/querystring-builder': 3.0.3 + '@smithy/types': 3.3.0 + '@smithy/util-base64': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/hash-node@3.0.3: + resolution: {integrity: sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/invalid-dependency@3.0.3: + resolution: {integrity: sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/is-array-buffer@1.1.0: + resolution: {integrity: sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/is-array-buffer@2.2.0: + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/is-array-buffer@3.0.0: + resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/middleware-content-length@3.0.4: + resolution: {integrity: sha512-wySGje/KfhsnF8YSh9hP16pZcl3C+X6zRsvSfItQGvCyte92LliilU3SD0nR7kTlxnAJwxY8vE/k4Eoezj847Q==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/protocol-http': 4.0.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/middleware-endpoint@3.0.5: + resolution: {integrity: sha512-V4acqqrh5tDxUEGVTOgf2lYMZqPQsoGntCrjrJZEeBzEzDry2d2vcI1QCXhGltXPPY+BMc6eksZMguA9fIY8vA==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/middleware-serde': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-middleware': 3.0.3 + tslib: 2.6.3 + dev: false + + /@smithy/middleware-retry@3.0.11: + resolution: {integrity: sha512-/TIRWmhwMpv99JCGuMhJPnH7ggk/Lah7s/uNDyr7faF02BxNsyD/fz9Tw7pgCf9tYOKgjimm2Qml1Aq1pbkt6g==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/protocol-http': 4.0.4 + '@smithy/service-error-classification': 3.0.3 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + tslib: 2.6.3 + uuid: 9.0.1 + dev: false + + /@smithy/middleware-serde@3.0.3: + resolution: {integrity: sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/middleware-stack@3.0.3: + resolution: {integrity: sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/node-config-provider@3.1.4: + resolution: {integrity: sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/node-http-handler@3.1.3: + resolution: {integrity: sha512-UiKZm8KHb/JeOPzHZtRUfyaRDO1KPKPpsd7iplhiwVGOeVdkiVJ5bVe7+NhWREMOKomrDIDdSZyglvMothLg0Q==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/abort-controller': 3.1.1 + '@smithy/protocol-http': 4.0.4 + '@smithy/querystring-builder': 3.0.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/property-provider@3.1.3: + resolution: {integrity: sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/protocol-http@1.2.0: + resolution: {integrity: sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 1.2.0 + tslib: 2.6.3 + dev: false + + /@smithy/protocol-http@4.0.4: + resolution: {integrity: sha512-fAA2O4EFyNRyYdFLVIv5xMMeRb+3fRKc/Rt2flh5k831vLvUmNFXcydeg7V3UeEhGURJI4c1asmGJBjvmF6j8Q==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/querystring-builder@3.0.3: + resolution: {integrity: sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + '@smithy/util-uri-escape': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/querystring-parser@3.0.3: + resolution: {integrity: sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/service-error-classification@3.0.3: + resolution: {integrity: sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + dev: false + + /@smithy/shared-ini-file-loader@3.1.4: + resolution: {integrity: sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/signature-v4@1.1.0: + resolution: {integrity: sha512-fDo3m7YqXBs7neciOePPd/X9LPm5QLlDMdIC4m1H6dgNLnXfLMFNIxEfPyohGA8VW9Wn4X8lygnPSGxDZSmp0Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/eventstream-codec': 1.1.0 + '@smithy/is-array-buffer': 1.1.0 + '@smithy/types': 1.2.0 + '@smithy/util-hex-encoding': 1.1.0 + '@smithy/util-middleware': 1.1.0 + '@smithy/util-uri-escape': 1.1.0 + '@smithy/util-utf8': 1.1.0 + tslib: 2.6.3 + dev: false + + /@smithy/signature-v4@4.0.0: + resolution: {integrity: sha512-ervYjQ+ZvmNG51Ui77IOTPri7nOyo8Kembzt9uwwlmtXJPmFXvslOahbA1blvAVs7G0KlYMiOBog1rAt7RVXxg==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/is-array-buffer': 3.0.0 + '@smithy/types': 3.3.0 + '@smithy/util-hex-encoding': 3.0.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-uri-escape': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/smithy-client@3.1.9: + resolution: {integrity: sha512-My2RaInZ4gSwJUPMaiLR/Nk82+c4LlvqpXA+n7lonGYgCZq23Tg+/xFhgmiejJ6XPElYJysTPyV90vKyp17+1g==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-stack': 3.0.3 + '@smithy/protocol-http': 4.0.4 + '@smithy/types': 3.3.0 + '@smithy/util-stream': 3.1.1 + tslib: 2.6.3 + dev: false + + /@smithy/types@1.2.0: + resolution: {integrity: sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/types@3.3.0: + resolution: {integrity: sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/url-parser@3.0.3: + resolution: {integrity: sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==} + dependencies: + '@smithy/querystring-parser': 3.0.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-base64@3.0.0: + resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-body-length-browser@3.0.0: + resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-body-length-node@3.0.0: + resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-buffer-from@1.1.0: + resolution: {integrity: sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/is-array-buffer': 1.1.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-buffer-from@2.2.0: + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-buffer-from@3.0.0: + resolution: {integrity: sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/is-array-buffer': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-config-provider@3.0.0: + resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-defaults-mode-browser@3.0.11: + resolution: {integrity: sha512-O3s9DGb3bmRvEKmT8RwvSWK4A9r6svfd+MnJB+UMi9ZcCkAnoRtliulOnGF0qCMkKF9mwk2tkopBBstalPY/vg==} + engines: {node: '>= 10.0.0'} + dependencies: + '@smithy/property-provider': 3.1.3 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + bowser: 2.11.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-defaults-mode-node@3.0.11: + resolution: {integrity: sha512-qd4a9qtyOa/WY14aHHOkMafhh9z8D2QTwlcBoXMTPnEwtcY+xpe1JyFm9vya7VsB8hHsfn3XodEtwqREiu4ygQ==} + engines: {node: '>= 10.0.0'} + dependencies: + '@smithy/config-resolver': 3.0.5 + '@smithy/credential-provider-imds': 3.1.4 + '@smithy/node-config-provider': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/smithy-client': 3.1.9 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-endpoints@2.0.5: + resolution: {integrity: sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-hex-encoding@1.1.0: + resolution: {integrity: sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-hex-encoding@3.0.0: + resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-middleware@1.1.0: + resolution: {integrity: sha512-6hhckcBqVgjWAqLy2vqlPZ3rfxLDhFWEmM7oLh2POGvsi7j0tHkbN7w4DFhuBExVJAbJ/qqxqZdRY6Fu7/OezQ==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-middleware@3.0.3: + resolution: {integrity: sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-retry@3.0.3: + resolution: {integrity: sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/service-error-classification': 3.0.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-stream@3.1.1: + resolution: {integrity: sha512-EhRnVvl3AhoHAT2rGQ5o+oSDRM/BUSMPLZZdRJZLcNVUsFAjOs4vHaPdNQivTSzRcFxf5DA4gtO46WWU2zimaw==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/fetch-http-handler': 3.2.2 + '@smithy/node-http-handler': 3.1.3 + '@smithy/types': 3.3.0 + '@smithy/util-base64': 3.0.0 + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-hex-encoding': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-uri-escape@1.1.0: + resolution: {integrity: sha512-/jL/V1xdVRt5XppwiaEU8Etp5WHZj609n0xMTuehmCqdoOFbId1M+aEeDWZsQ+8JbEB/BJ6ynY2SlYmOaKtt8w==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-uri-escape@3.0.0: + resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.3 + dev: false + + /@smithy/util-utf8@1.1.0: + resolution: {integrity: sha512-p/MYV+JmqmPyjdgyN2UxAeYDj9cBqCjp0C/NsTWnnjoZUVqoeZ6IrW915L9CAKWVECgv9lVQGc4u/yz26/bI1A==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/util-buffer-from': 1.1.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-utf8@2.3.0: + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-utf8@3.0.0: + resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/util-buffer-from': 3.0.0 + tslib: 2.6.3 + dev: false + + /@smithy/util-waiter@3.1.2: + resolution: {integrity: sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==} + engines: {node: '>=16.0.0'} + dependencies: + '@smithy/abort-controller': 3.1.1 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + dev: false + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true + + /@types/figlet@1.5.8: + resolution: {integrity: sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ==} + dev: true + + /@types/ini@1.3.34: + resolution: {integrity: sha512-FafeLhwmWucTi31ZYg/6aHBZNyrogQ35aDvSW7zMAz3HMhUqQ4G/NBya8c5pe2jwoYsDFwra8O9/yZotong76g==} + dev: true + + /@types/inquirer@9.0.7: + resolution: {integrity: sha512-Q0zyBupO6NxGRZut/JdmqYKOnN95Eg5V8Csg3PGKkP+FnvsUZx1jAyK7fztIszxxMuoBA6E3KXWvdZVXIpx60g==} + dependencies: + '@types/through': 0.0.33 + rxjs: 7.8.1 + dev: true + + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + dev: true + + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + dev: true + + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + dependencies: + '@types/istanbul-lib-report': 3.0.3 + dev: true + + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/mdast@3.0.15: + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + dependencies: + '@types/unist': 2.0.10 + dev: true + + /@types/mute-stream@0.0.4: + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + dependencies: + '@types/node': 18.19.42 + dev: false + + /@types/node-fetch@2.6.11: + resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + dependencies: + '@types/node': 18.19.42 + form-data: 4.0.0 + dev: false + + /@types/node@18.19.42: + resolution: {integrity: sha512-d2ZFc/3lnK2YCYhos8iaNIYu9Vfhr92nHiyJHRltXWjXUBjEE+A4I58Tdbnw4VhggSW+2j5y5gTrLs4biNnubg==} + dependencies: + undici-types: 5.26.5 + + /@types/node@20.14.12: + resolution: {integrity: sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/normalize-package-data@2.4.4: + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + dev: true + + /@types/resolve@1.20.2: + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + dev: true + + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + dev: true + + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + dev: true + + /@types/through@0.0.33: + resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} + dependencies: + '@types/node': 18.19.42 + dev: true + + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + dev: true + + /@types/uuid@9.0.8: + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + dev: true + + /@types/wrap-ansi@3.0.0: + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + dev: false + + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + dev: true + + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + + /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + debug: 4.3.5 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare-lite: 1.4.0 + semver: 7.6.3 + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.5 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + debug: 4.3.5 + eslint: 8.57.0 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.5 + eslint: 8.57.0 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@5.62.0: + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + dev: true + + /@typescript-eslint/scope-manager@6.21.0: + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + dev: true + + /@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + debug: 4.3.5 + eslint: 8.57.0 + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.21.0(typescript@4.9.5) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@4.9.5) + debug: 4.3.5 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@5.62.0: + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/types@6.21.0: + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5): + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.3 + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree@6.21.0(typescript@4.9.5): + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + eslint: 8.57.0 + eslint-scope: 5.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@4.9.5): + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@4.9.5) + eslint: 8.57.0 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@5.62.0: + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@typescript-eslint/visitor-keys@6.21.0: + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.21.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: true + + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: false + + /acorn-jsx@5.3.2(acorn@8.12.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.12.1 + dev: true + + /acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /aggregate-error@5.0.0: + resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==} + engines: {node: '>=18'} + dependencies: + clean-stack: 5.2.0 + indent-string: 5.0.0 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: false + + /ansi-escapes@5.0.0: + resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} + engines: {node: '>=12'} + dependencies: + type-fest: 1.4.0 + dev: true + + /ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + dependencies: + environment: 1.1.0 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /argv-formatter@1.0.0: + resolution: {integrity: sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==} + dev: true + + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + dev: true + + /array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + dev: true + + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + dev: true + + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 + dev: true + + /axios@0.26.1: + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + dependencies: + follow-redirects: 1.15.6 + transitivePeerDependencies: + - debug + dev: true + + /axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /before-after-hook@3.0.2: + resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: false + + /bl@5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: false + + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + dev: true + + /bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: true + + /character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: true + + /character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: true + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: false + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + dev: true + + /clean-pkg-json@1.2.0: + resolution: {integrity: sha512-QHBWWOtpSCv5nfMFKwyxn4WMvkYE0msxj5xiqejYGqYepWVrK7O/om1Vn6nSl/WPtYn8ge9YmSCbTi1Hp8k+Hg==} + hasBin: true + dev: true + + /clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /clean-stack@5.2.0: + resolution: {integrity: sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==} + engines: {node: '>=14.16'} + dependencies: + escape-string-regexp: 5.0.0 + dev: true + + /cleye@1.3.2: + resolution: {integrity: sha512-MngIC2izcCz07iRKr3Pe8Z6ZBv4zbKFl/YnQEN/aMHis6PpH+MxI2e6n0bMUAmSVlMoAyQkdBCSTbfDmtcSovQ==} + dependencies: + terminal-columns: 1.4.1 + type-flag: 3.0.0 + dev: true + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: false + + /cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + + /cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + dev: true + + /cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + dev: false + + /cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + + /cli-truncate@3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.1.2 + dev: true + + /cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + dev: false + + /cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: false + + /cohere-ai@7.11.0(@aws-sdk/client-sso-oidc@3.616.0): + resolution: {integrity: sha512-rtBx1J4ifcg+zbl8o4yN7pzJ0akczj68wmMue1beqelVUEjbcw3uwP3dQ3hR14y41J3CDnCx+eYAh0oizx04fQ==} + dependencies: + '@aws-sdk/client-sagemaker': 3.616.0 + '@aws-sdk/credential-providers': 3.617.0(@aws-sdk/client-sso-oidc@3.616.0) + '@aws-sdk/protocol-http': 3.374.0 + '@aws-sdk/signature-v4': 3.374.0 + form-data: 4.0.0 + form-data-encoder: 4.0.2 + formdata-node: 6.0.3 + js-base64: 3.7.2 + node-fetch: 2.7.0 + qs: 6.11.2 + readable-stream: 4.5.2 + url-join: 4.0.1 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + - encoding + dev: false + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + + /commander@11.0.0: + resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} + engines: {node: '>=16'} + dev: true + + /comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + dev: true + + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + dev: true + + /confusing-browser-globals@1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + dev: true + + /conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} + dependencies: + compare-func: 2.0.0 + dev: true + + /conventional-changelog-conventionalcommits@7.0.2: + resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} + engines: {node: '>=16'} + dependencies: + compare-func: 2.0.0 + dev: true + + /conventional-changelog-writer@7.0.1: + resolution: {integrity: sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==} + engines: {node: '>=16'} + hasBin: true + dependencies: + conventional-commits-filter: 4.0.0 + handlebars: 4.7.8 + json-stringify-safe: 5.0.1 + meow: 12.1.1 + semver: 7.6.3 + split2: 4.2.0 + dev: true + + /conventional-commits-filter@4.0.0: + resolution: {integrity: sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==} + engines: {node: '>=16'} + dev: true + + /conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} + engines: {node: '>=16'} + hasBin: true + dependencies: + JSONStream: 1.3.5 + is-text-path: 2.0.0 + meow: 12.1.1 + split2: 4.2.0 + dev: true + + /convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} + dev: true + + /copy-paste@1.5.3: + resolution: {integrity: sha512-qOnFo+8l8vemGmdcoCiD7gPTefkXEg2rivYE+EBtuKOj754eFivkGhGAM9e/xqShrpuVE11evSxGnHwVAUK1Iw==} + dependencies: + iconv-lite: 0.4.24 + dev: false + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cosmiconfig@9.0.0(typescript@4.9.5): + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + typescript: 4.9.5 + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + dependencies: + type-fest: 1.4.0 + dev: true + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: false + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + dependencies: + is-obj: 2.0.0 + dev: true + + /duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + dependencies: + readable-stream: 2.3.8 + dev: true + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + dev: true + + /enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + + /env-ci@11.0.0: + resolution: {integrity: sha512-apikxMgkipkgTvMdRT9MNqWx5VLOci79F4VBd7Op/7OPjjoanjdAvn6fglMCCEf/1bAh8eOiuEVCUs4V3qP3nQ==} + engines: {node: ^18.17 || >=20.6.1} + dependencies: + execa: 8.0.1 + java-properties: 1.0.2 + dev: true + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: true + + /environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.2 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + /es-iterator-helpers@1.0.19: + resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + iterator.prototype: 1.1.2 + safe-array-concat: 1.1.2 + dev: true + + /es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: true + + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.2 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + /eslint-compat-utils@0.5.1(eslint@8.57.0): + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + eslint: 8.57.0 + semver: 7.6.3 + dev: true + + /eslint-config-prettier@8.10.0(eslint@8.57.0): + resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.57.0 + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.15.0 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + dependencies: + debug: 4.3.5 + enhanced-resolve: 5.17.1 + eslint: 8.57.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.6 + is-core-module: 2.15.0 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + debug: 3.2.7 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + debug: 3.2.7 + eslint: 8.57.0 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@4.9.5) + debug: 3.2.7 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-es@3.0.1(eslint@8.57.0): + resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.57.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-eslint-comments@3.2.0(eslint@8.57.0): + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.57.0 + ignore: 5.3.1 + dev: true + + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.15.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@4.9.5) + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.15.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jsonc@2.16.0(eslint@8.57.0): + resolution: {integrity: sha512-Af/ZL5mgfb8FFNleH6KlO4/VdmDuTqmM+SPnWcdoWywTetv7kq+vQe99UyQb9XO3b0OWLVuTH7H0d/PXYCMdSg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + eslint: 8.57.0 + eslint-compat-utils: 0.5.1(eslint@8.57.0) + espree: 9.6.1 + graphemer: 1.4.0 + jsonc-eslint-parser: 2.4.0 + natural-compare: 1.4.0 + synckit: 0.6.2 + dev: true + + /eslint-plugin-markdown@3.0.1(eslint@8.57.0): + resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.57.0 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-no-use-extend-native@0.5.0: + resolution: {integrity: sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==} + engines: {node: '>=6.0.0'} + dependencies: + is-get-set-prop: 1.0.0 + is-js-type: 2.0.0 + is-obj-prop: 1.0.0 + is-proto-prop: 2.0.0 + dev: true + + /eslint-plugin-node@11.1.0(eslint@8.57.0): + resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=5.16.0' + dependencies: + eslint: 8.57.0 + eslint-plugin-es: 3.0.1(eslint@8.57.0) + eslint-utils: 2.1.0 + ignore: 5.3.1 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 6.3.1 + dev: true + + /eslint-plugin-promise@6.6.0(eslint@8.57.0): + resolution: {integrity: sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + dependencies: + eslint: 8.57.0 + dev: true + + /eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.57.0 + dev: true + + /eslint-plugin-react@7.35.0(eslint@8.57.0): + resolution: {integrity: sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.19 + eslint: 8.57.0 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.values: 1.2.0 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.11 + string.prototype.repeat: 1.0.0 + dev: true + + /eslint-plugin-regexp@1.15.0(eslint@8.57.0): + resolution: {integrity: sha512-YEtQPfdudafU7RBIFci81R/Q1yErm0mVh3BkGnXD2Dk8DLwTFdc2ITYH1wCnHKim2gnHfPFgrkh+b2ozyyU7ag==} + engines: {node: ^12 || >=14} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 + comment-parser: 1.4.1 + eslint: 8.57.0 + grapheme-splitter: 1.0.4 + jsdoctypeparser: 9.0.0 + refa: 0.11.0 + regexp-ast-analysis: 0.6.0 + scslre: 0.2.0 + dev: true + + /eslint-plugin-unicorn@44.0.2(eslint@8.57.0): + resolution: {integrity: sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==} + engines: {node: '>=14.18'} + peerDependencies: + eslint: '>=8.23.1' + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + ci-info: 3.9.0 + clean-regexp: 1.0.0 + eslint: 8.57.0 + eslint-utils: 3.0.0(eslint@8.57.0) + esquery: 1.6.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + safe-regex: 2.1.1 + semver: 7.6.3 + strip-indent: 3.0.0 + dev: true + + /eslint-plugin-unicorn@49.0.0(eslint@8.57.0): + resolution: {integrity: sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==} + engines: {node: '>=16'} + peerDependencies: + eslint: '>=8.52.0' + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + ci-info: 3.9.0 + clean-regexp: 1.0.0 + eslint: 8.57.0 + esquery: 1.6.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.6.3 + strip-indent: 3.0.0 + dev: true + + /eslint-plugin-unused-imports@3.2.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.57.0): + resolution: {integrity: sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': 6 - 7 + eslint: '8' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.57.0)(typescript@4.9.5) + eslint: 8.57.0 + eslint-rule-composer: 0.3.0 + dev: true + + /eslint-plugin-vue@9.27.0(eslint@8.57.0): + resolution: {integrity: sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + eslint: 8.57.0 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.1 + semver: 7.6.3 + vue-eslint-parser: 9.4.3(eslint@8.57.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + dev: true + + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-utils@3.0.0(eslint@8.57.0): + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.5 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 3.4.3 + dev: true + + /esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: false + + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: true + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: false + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + dev: true + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + + /execa@9.3.0: + resolution: {integrity: sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==} + engines: {node: ^18.19.0 || >=20.5.0} + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.3 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 7.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 5.3.0 + pretty-ms: 9.1.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + dev: true + + /expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: false + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fast-xml-parser@4.2.5: + resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} + hasBin: true + dependencies: + strnum: 1.0.5 + dev: false + + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + dependencies: + reusify: 1.0.4 + dev: true + + /figlet@1.7.0: + resolution: {integrity: sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==} + engines: {node: '>= 0.4.0'} + hasBin: true + dev: false + + /figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: false + + /figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + dependencies: + escape-string-regexp: 5.0.0 + is-unicode-supported: 1.3.0 + dev: false + + /figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + dependencies: + is-unicode-supported: 2.0.0 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.2.0 + dev: true + + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up-simple@1.0.0: + resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} + engines: {node: '>=18'} + dev: true + + /find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + dependencies: + locate-path: 2.0.0 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /find-versions@6.0.0: + resolution: {integrity: sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==} + engines: {node: '>=18'} + dependencies: + semver-regex: 4.0.5 + super-regex: 1.0.0 + dev: true + + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + dev: true + + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + dev: true + + /follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + dev: false + + /form-data-encoder@4.0.2: + resolution: {integrity: sha512-KQVhvhK8ZkWzxKxOr56CPulAhH3dobtuQ4+hNQ+HekH/Wp5gSOafqRAeTphQUJAIk0GBvHZgJ2ZGRWd5kphMuw==} + engines: {node: '>= 18'} + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + /formdata-node@4.4.1: + resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} + engines: {node: '>= 12.20'} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + dev: false + + /formdata-node@6.0.3: + resolution: {integrity: sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==} + engines: {node: '>= 18'} + dev: false + + /from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + dev: true + + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + + /fs-fixture@1.2.0: + resolution: {integrity: sha512-bPBNW12US81zxCXzP/BQ6ntSvMXNgX76nHVUxzQJVTmHkzXnbfp+M4mNWeJ9LuCG8M1wyeFov7oiwO9wnCEBjQ==} + engines: {node: '>=16.7.0'} + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + /function-timeout@1.0.2: + resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} + engines: {node: '>=18'} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + dev: false + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + /get-set-props@0.1.0: + resolution: {integrity: sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==} + engines: {node: '>=0.10.0'} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-stream@7.0.1: + resolution: {integrity: sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==} + engines: {node: '>=16'} + dev: true + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + dev: true + + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + dev: true + + /get-tsconfig@4.7.6: + resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /git-log-parser@1.2.1: + resolution: {integrity: sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==} + dependencies: + argv-formatter: 1.0.0 + spawn-error-forwarder: 1.0.0 + split2: 1.0.0 + stream-combiner2: 1.1.1 + through2: 2.0.5 + traverse: 0.6.8 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: true + + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /globby@14.0.2: + resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} + engines: {node: '>=18'} + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.2 + ignore: 5.3.1 + path-type: 5.0.0 + slash: 5.1.0 + unicorn-magic: 0.1.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + + /graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /groq-sdk@0.4.0: + resolution: {integrity: sha512-h79q9sv4hcOBESR05N5eqHlGhAug9H9lr3EIiB+37ysWWekeG+KYQDK2lIIHYCm6O9LzgZzO/VdLdPP298+T0w==} + dependencies: + '@types/node': 18.19.42 + '@types/node-fetch': 2.6.11 + abort-controller: 3.0.0 + agentkeepalive: 4.5.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + web-streams-polyfill: 3.3.3 + transitivePeerDependencies: + - encoding + dev: false + + /handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.0 + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + + /highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + dev: true + + /hook-std@3.0.0: + resolution: {integrity: sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + dependencies: + lru-cache: 10.4.3 + dev: true + + /http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + dev: true + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + + /human-signals@7.0.0: + resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==} + engines: {node: '>=18.18.0'} + dev: true + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /import-from-esm@1.3.4: + resolution: {integrity: sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==} + engines: {node: '>=16.20'} + dependencies: + debug: 4.3.5 + import-meta-resolve: 4.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + dev: true + + /index-to-position@0.1.2: + resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==} + engines: {node: '>=18'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + + /ini@3.0.1: + resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dev: true + + /inquirer-reactive-list-prompt@1.0.8(inquirer@9.2.8): + resolution: {integrity: sha512-4lOxr5uJiZVQ7aMNJhcrnExFrNxb16FlPcuysKYJBR4xYGihNHzn34P3YfAqZ1HFF78elH6tBWGJ7IbUIMHC2A==} + peerDependencies: + inquirer: 9.2.8 + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + figures: 5.0.0 + inquirer: 9.2.8 + ora: 7.0.1 + rxjs: 7.8.1 + dev: false + + /inquirer@9.2.8: + resolution: {integrity: sha512-SJ0fVfgIzZL1AD6WvFhivlh5/3hN6WeAvpvPrpPXH/8MOcQHeXhinmSm5CDJNRC2Q+sLh9YJ5k8F8/5APMXSfw==} + engines: {node: '>=14.18.0'} + dependencies: + ansi-escapes: 4.3.2 + chalk: 5.3.0 + cli-cursor: 3.1.0 + cli-width: 4.1.0 + external-editor: 3.1.0 + figures: 5.0.0 + lodash: 4.17.21 + mute-stream: 1.0.0 + ora: 5.4.1 + run-async: 3.0.0 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + dev: false + + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + dev: true + + /into-stream@7.0.0: + resolution: {integrity: sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==} + engines: {node: '>=12'} + dependencies: + from2: 2.3.0 + p-is-promise: 3.0.0 + dev: true + + /is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: true + + /is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: true + + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.15.0: + resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 + dev: true + + /is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + dependencies: + is-typed-array: 1.1.13 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-get-set-prop@1.0.0: + resolution: {integrity: sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==} + dependencies: + get-set-props: 0.1.0 + lowercase-keys: 1.0.1 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: true + + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: false + + /is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + dev: false + + /is-js-type@2.0.0: + resolution: {integrity: sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==} + dependencies: + js-types: 1.0.0 + dev: true + + /is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + dev: true + + /is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + dev: true + + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj-prop@1.0.0: + resolution: {integrity: sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==} + dependencies: + lowercase-keys: 1.0.1 + obj-props: 1.4.0 + dev: true + + /is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + dev: true + + /is-proto-prop@2.0.0: + resolution: {integrity: sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==} + dependencies: + lowercase-keys: 1.0.1 + proto-props: 2.0.0 + dev: true + + /is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + dependencies: + '@types/estree': 1.0.5 + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + dev: true + + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-text-path@2.0.0: + resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} + engines: {node: '>=8'} + dependencies: + text-extensions: 2.4.0 + dev: true + + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.15 + dev: true + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: false + + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: false + + /is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + /is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /issue-parser@7.0.1: + resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} + engines: {node: ^18.17 || >=20.6.1} + dependencies: + lodash.capitalize: 4.2.1 + lodash.escaperegexp: 4.1.2 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.uniqby: 4.7.0 + dev: true + + /iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 + dev: true + + /java-properties@1.0.2: + resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==} + engines: {node: '>= 0.6.0'} + dev: true + + /jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.24.7 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.7 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 18.19.42 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /js-base64@3.7.2: + resolution: {integrity: sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==} + dev: false + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-types@1.0.0: + resolution: {integrity: sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==} + engines: {node: '>=0.10.0'} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsdoctypeparser@9.0.0: + resolution: {integrity: sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.12.1 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.6.3 + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: true + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + dev: true + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /lint-staged@13.3.0: + resolution: {integrity: sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + dependencies: + chalk: 5.3.0 + commander: 11.0.0 + debug: 4.3.4 + execa: 7.2.0 + lilconfig: 2.1.0 + listr2: 6.6.1 + micromatch: 4.0.5 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.3.1 + transitivePeerDependencies: + - enquirer + - supports-color + dev: true + + /listr2@6.6.1: + resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==} + engines: {node: '>=16.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 3.1.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 5.0.1 + rfdc: 1.4.1 + wrap-ansi: 8.1.0 + dev: true + + /load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + dev: true + + /locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: true + + /lodash.capitalize@4.2.1: + resolution: {integrity: sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==} + dev: true + + /lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.uniqby@4.7.0: + resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: false + + /log-symbols@5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + dev: false + + /log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + dev: false + + /log-update@5.0.1: + resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + ansi-escapes: 5.0.0 + cli-cursor: 4.0.0 + slice-ansi: 5.0.0 + strip-ansi: 7.1.0 + wrap-ansi: 8.1.0 + dev: true + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + dev: true + + /lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + dev: true + + /magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /manten@0.7.0: + resolution: {integrity: sha512-CTGbnhYI9Y8nVUm9BQXuv8KW55Q9FxZMmZYtedMxHQJsBLXMMntdvZJefRAxBCISCFkQk1+/7vBwh/8z22BZ+Q==} + dependencies: + expect: 29.7.0 + dev: true + + /marked-terminal@7.1.0(marked@12.0.2): + resolution: {integrity: sha512-+pvwa14KZL74MVXjYdPR3nSInhGhNvPce/3mqLVZT2oUvt654sL1XImFuLZ1pkA866IYZ3ikDTOFUIC7XzpZZg==} + engines: {node: '>=16.0.0'} + peerDependencies: + marked: '>=1 <14' + dependencies: + ansi-escapes: 7.0.0 + chalk: 5.3.0 + cli-highlight: 2.1.11 + cli-table3: 0.6.5 + marked: 12.0.2 + node-emoji: 2.1.3 + supports-hyperlinks: 3.0.0 + dev: true + + /marked@12.0.2: + resolution: {integrity: sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==} + engines: {node: '>= 18'} + hasBin: true + dev: true + + /mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + dev: true + + /meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + dependencies: + debug: 4.3.5 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + dev: true + + /micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + + /mime@4.0.4: + resolution: {integrity: sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==} + engines: {node: '>=16'} + hasBin: true + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: false + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /nerf-dart@1.0.0: + resolution: {integrity: sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==} + dev: true + + /node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: false + + /node-emoji@2.1.3: + resolution: {integrity: sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==} + engines: {node: '>=18'} + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + dev: true + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + dependencies: + hosted-git-info: 7.0.2 + semver: 7.6.3 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + engines: {node: '>=14.16'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + + /npm@10.8.2: + resolution: {integrity: sha512-x/AIjFIKRllrhcb48dqUNAAZl0ig9+qMuN91RpZo3Cb2+zuibfh+KISl6+kVVyktDz230JKc208UkQwwMqyB+w==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + dev: true + bundledDependencies: + - '@isaacs/string-locale-compare' + - '@npmcli/arborist' + - '@npmcli/config' + - '@npmcli/fs' + - '@npmcli/map-workspaces' + - '@npmcli/package-json' + - '@npmcli/promise-spawn' + - '@npmcli/redact' + - '@npmcli/run-script' + - '@sigstore/tuf' + - abbrev + - archy + - cacache + - chalk + - ci-info + - cli-columns + - fastest-levenshtein + - fs-minipass + - glob + - graceful-fs + - hosted-git-info + - ini + - init-package-json + - is-cidr + - json-parse-even-better-errors + - libnpmaccess + - libnpmdiff + - libnpmexec + - libnpmfund + - libnpmhook + - libnpmorg + - libnpmpack + - libnpmpublish + - libnpmsearch + - libnpmteam + - libnpmversion + - make-fetch-happen + - minimatch + - minipass + - minipass-pipeline + - ms + - node-gyp + - nopt + - normalize-package-data + - npm-audit-report + - npm-install-checks + - npm-package-arg + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - p-map + - pacote + - parse-conflict-json + - proc-log + - qrcode-terminal + - read + - semver + - spdx-expression-parse + - ssri + - supports-color + - tar + - text-table + - tiny-relative-date + - treeverse + - validate-npm-package-name + - which + - write-file-atomic + + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /obj-props@1.4.0: + resolution: {integrity: sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==} + engines: {node: '>=0.10.0'} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + dev: true + + /object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /ollama@0.5.6: + resolution: {integrity: sha512-4BySAMt96+OCt4emL6DE78UBCGqC7GvteM9LRCd6WwJyefn0x9w2BrcUcLm9nJ9bYpRsmkhf0Au18Q5MhsA14w==} + dependencies: + whatwg-fetch: 3.6.20 + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /openai@3.3.0: + resolution: {integrity: sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==} + dependencies: + axios: 0.26.1 + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: true + + /optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + dev: true + + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: false + + /ora@7.0.1: + resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} + engines: {node: '>=16'} + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 1.3.0 + log-symbols: 5.1.0 + stdin-discarder: 0.1.0 + string-width: 6.1.0 + strip-ansi: 7.1.0 + dev: false + + /ora@8.0.1: + resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==} + engines: {node: '>=18'} + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.0.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.0 + dev: false + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: false + + /p-each-series@3.0.0: + resolution: {integrity: sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==} + engines: {node: '>=12'} + dev: true + + /p-filter@4.1.0: + resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==} + engines: {node: '>=18'} + dependencies: + p-map: 7.0.2 + dev: true + + /p-is-promise@3.0.0: + resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} + engines: {node: '>=8'} + dev: true + + /p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + dependencies: + p-try: 1.0.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + dependencies: + p-limit: 1.3.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@7.0.2: + resolution: {integrity: sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==} + engines: {node: '>=18'} + dev: true + + /p-reduce@2.1.0: + resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} + engines: {node: '>=8'} + dev: true + + /p-reduce@3.0.0: + resolution: {integrity: sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==} + engines: {node: '>=12'} + dev: true + + /p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: true + + /parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parse-json@8.1.0: + resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==} + engines: {node: '>=18'} + dependencies: + '@babel/code-frame': 7.24.7 + index-to-position: 0.1.2 + type-fest: 4.23.0 + dev: true + + /parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + dev: true + + /parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + dependencies: + parse5: 6.0.1 + dev: true + + /parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + dev: true + + /parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + dev: true + + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /path-type@5.0.0: + resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} + engines: {node: '>=12'} + dev: true + + /picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: true + + /pkg-conf@2.1.0: + resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} + engines: {node: '>=4'} + dependencies: + find-up: 2.1.0 + load-json-file: 4.0.0 + dev: true + + /pkgroll@1.11.1(typescript@4.9.5): + resolution: {integrity: sha512-jRe/BMDNQNzlpI93FC7OySGwYUI/2f9S+ukGwF6T5TZynkm2AtxyX4V19uc7rj7C2TH3UeZjP3FMlC3XLJHKUQ==} + hasBin: true + peerDependencies: + typescript: ^4.1 || ^5.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@rollup/plugin-alias': 4.0.4(rollup@2.79.1) + '@rollup/plugin-commonjs': 24.1.0(rollup@2.79.1) + '@rollup/plugin-inject': 5.0.5(rollup@2.79.1) + '@rollup/plugin-json': 6.1.0(rollup@2.79.1) + '@rollup/plugin-node-resolve': 15.2.3(rollup@2.79.1) + '@rollup/plugin-replace': 5.0.7(rollup@2.79.1) + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + esbuild: 0.18.20 + magic-string: 0.30.10 + rollup: 2.79.1 + typescript: 4.9.5 + dev: true + + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-selector-parser@6.1.1: + resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + dev: true + + /pretty-ms@9.1.0: + resolution: {integrity: sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==} + engines: {node: '>=18'} + dependencies: + parse-ms: 4.0.0 + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: false + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + dev: true + + /proto-props@2.0.0: + resolution: {integrity: sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==} + engines: {node: '>=4'} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /qs@6.11.2: + resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.6 + dev: false + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: true + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + dev: true + + /read-package-up@11.0.0: + resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} + engines: {node: '>=18'} + dependencies: + find-up-simple: 1.0.0 + read-pkg: 9.0.1 + type-fest: 4.23.0 + dev: true + + /read-pkg-up@11.0.0: + resolution: {integrity: sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==} + engines: {node: '>=18'} + deprecated: Renamed to read-package-up + dependencies: + find-up-simple: 1.0.0 + read-pkg: 9.0.1 + type-fest: 4.23.0 + dev: true + + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 8.1.0 + type-fest: 4.23.0 + unicorn-magic: 0.1.0 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /readable-stream@4.5.2: + resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + dev: false + + /readline@1.3.0: + resolution: {integrity: sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==} + dev: false + + /refa@0.11.0: + resolution: {integrity: sha512-486O8/pQXwj9jV0mVvUnTsxq0uknpBnNJ0eCUhkZqJRQ8KutrT1PhzmumdCeM1hSBF2eMlFPmwECRER4IbKXlQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dependencies: + '@eslint-community/regexpp': 4.11.0 + dev: true + + /reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.3 + dev: true + + /regexp-ast-analysis@0.6.0: + resolution: {integrity: sha512-OLxjyjPkVH+rQlBLb1I/P/VTmamSjGkvN5PTV5BXP432k3uVz727J7H29GA5IFiY0m7e1xBN7049Wn59FY3DEQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dependencies: + '@eslint-community/regexpp': 4.11.0 + refa: 0.11.0 + dev: true + + /regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + dev: true + + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + dev: true + + /regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /registry-auth-token@5.0.2: + resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} + engines: {node: '>=14'} + dependencies: + '@pnpm/npm-conf': 2.2.2 + dev: true + + /regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.15.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.15.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: false + + /restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup@2.79.1: + resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + dev: false + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.6.3 + + /safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + dev: true + + /safe-regex@2.1.1: + resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} + dependencies: + regexp-tree: 0.1.27 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + + /scslre@0.2.0: + resolution: {integrity: sha512-4hc49fUMmX3jM0XdFUAPBrs1xwEcdHa0KyjEsjFs+Zfc66mpFpq5YmRgDtl+Ffo6AtJIilfei+yKw8fUn3N88w==} + dependencies: + '@eslint-community/regexpp': 4.11.0 + refa: 0.11.0 + regexp-ast-analysis: 0.6.0 + dev: true + + /semantic-release@23.1.1(typescript@4.9.5): + resolution: {integrity: sha512-qqJDBhbtHsjUEMsojWKGuL5lQFCJuPtiXKEIlFKyTzDDGTAE/oyvznaP8GeOr5PvcqBJ6LQz4JCENWPLeehSpA==} + engines: {node: '>=20.8.1'} + hasBin: true + dependencies: + '@semantic-release/commit-analyzer': 12.0.0(semantic-release@23.1.1) + '@semantic-release/error': 4.0.0 + '@semantic-release/github': 10.1.1(semantic-release@23.1.1) + '@semantic-release/npm': 12.0.1(semantic-release@23.1.1) + '@semantic-release/release-notes-generator': 13.0.0(semantic-release@23.1.1) + aggregate-error: 5.0.0 + cosmiconfig: 9.0.0(typescript@4.9.5) + debug: 4.3.5 + env-ci: 11.0.0 + execa: 9.3.0 + figures: 6.1.0 + find-versions: 6.0.0 + get-stream: 6.0.1 + git-log-parser: 1.2.1 + hook-std: 3.0.0 + hosted-git-info: 7.0.2 + import-from-esm: 1.3.4 + lodash-es: 4.17.21 + marked: 12.0.2 + marked-terminal: 7.1.0(marked@12.0.2) + micromatch: 4.0.7 + p-each-series: 3.0.0 + p-reduce: 3.0.0 + read-package-up: 11.0.0 + resolve-from: 5.0.0 + semver: 7.6.3 + semver-diff: 4.0.0 + signale: 1.4.0 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + dependencies: + semver: 7.6.3 + dev: true + + /semver-regex@4.0.5: + resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} + engines: {node: '>=12'} + dev: true + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + /signale@1.4.0: + resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} + engines: {node: '>=6'} + dependencies: + chalk: 2.4.2 + figures: 2.0.0 + pkg-conf: 2.1.0 + dev: true + + /simple-git-hooks@2.11.1: + resolution: {integrity: sha512-tgqwPUMDcNDhuf1Xf6KTUsyeqGdgKMhzaH4PAZZuzguOgTl5uuyeYe/8mWgAr6IBxB5V06uqEf6Dy37gIWDtDg==} + hasBin: true + requiresBuild: true + dev: true + + /skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + dependencies: + unicode-emoji-modifier-base: 1.0.0 + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: true + + /slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + dev: true + + /slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spawn-error-forwarder@1.0.0: + resolution: {integrity: sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==} + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.18 + dev: true + + /spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 + dev: true + + /spdx-license-ids@3.0.18: + resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + dev: true + + /split2@1.0.0: + resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} + dependencies: + through2: 2.0.5 + dev: true + + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: true + + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /stdin-discarder@0.1.0: + resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + bl: 5.1.0 + dev: false + + /stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + dev: false + + /stream-combiner2@1.1.1: + resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} + dependencies: + duplexer2: 0.1.4 + readable-stream: 2.3.8 + dev: true + + /string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /string-width@6.1.0: + resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==} + engines: {node: '>=16'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 10.3.0 + strip-ansi: 7.1.0 + dev: false + + /string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + dev: false + + /string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 + dev: true + + /string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + dev: true + + /string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /strnum@1.0.5: + resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + dev: false + + /super-regex@1.0.0: + resolution: {integrity: sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==} + engines: {node: '>=18'} + dependencies: + function-timeout: 1.0.2 + time-span: 5.1.0 + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + + /supports-hyperlinks@3.0.0: + resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + engines: {node: '>=14.18'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /synckit@0.6.2: + resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==} + engines: {node: '>=12.20'} + dependencies: + tslib: 2.6.3 + dev: true + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + + /temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + dev: true + + /tempy@3.1.0: + resolution: {integrity: sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==} + engines: {node: '>=14.16'} + dependencies: + is-stream: 3.0.0 + temp-dir: 3.0.0 + type-fest: 2.19.0 + unique-string: 3.0.0 + dev: true + + /terminal-columns@1.4.1: + resolution: {integrity: sha512-IKVL/itiMy947XWVv4IHV7a0KQXvKjj4ptbi7Ew9MPMcOLzkiQeyx3Gyvh62hKrfJ0RZc4M1nbhzjNM39Kyujw==} + dev: true + + /text-extensions@2.4.0: + resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} + engines: {node: '>=8'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + /time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} + dependencies: + convert-hrtime: 5.0.0 + dev: true + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /traverse@0.6.8: + resolution: {integrity: sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==} + engines: {node: '>= 0.4'} + dev: true + + /ts-api-utils@1.3.0(typescript@4.9.5): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 4.9.5 + dev: true + + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + /tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + /tsutils@3.21.0(typescript@4.9.5): + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + dev: true + + /tsx@3.14.0: + resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} + hasBin: true + dependencies: + esbuild: 0.18.20 + get-tsconfig: 4.7.6 + source-map-support: 0.5.21 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: false + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + dev: true + + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: true + + /type-fest@4.23.0: + resolution: {integrity: sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==} + engines: {node: '>=16'} + dev: true + + /type-flag@3.0.0: + resolution: {integrity: sha512-3YaYwMseXCAhBB14RXW5cRQfJQlEknS6i4C8fCfeUdS3ihG9EdccdR9kt3vP73ZdeTGmPb4bZtkDn5XMIn1DLA==} + dev: true + + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + dev: true + + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /uglify-js@3.19.0: + resolution: {integrity: sha512-wNKHUY2hYYkf6oSFfhwwiHo4WCHzHmzcXsqXYTN9ja3iApYIFbb2U6ics9hBcYLHcYGQoAlwnZlTrf3oF+BL/Q==} + engines: {node: '>=0.8.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + /unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + dev: true + + /unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + dev: true + + /unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + dependencies: + crypto-random-string: 4.0.0 + dev: true + + /unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + dependencies: + '@types/unist': 2.0.10 + dev: true + + /universal-user-agent@7.0.2: + resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} + dev: true + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + dev: false + + /url-join@5.0.0: + resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /vue-eslint-parser@9.4.3(eslint@8.57.0): + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.5 + eslint: 8.57.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + lodash: 4.17.21 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: false + + /web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + dev: false + + /web-streams-polyfill@4.0.0-beta.3: + resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} + engines: {node: '>= 14'} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-fetch@3.6.20: + resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + dev: true + + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yaml@2.3.1: + resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + engines: {node: '>= 14'} + dev: true + + /yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + dev: true diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 0000000..ac2d7fc --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,44 @@ +import { cli } from 'cleye'; + +import aipick from './commands/aipick.js'; +import configCommand from './commands/config.js'; +import logCommand from './commands/log.js'; +import { description, version } from '../package.json'; + +const rawArgv = process.argv.slice(2); + +cli( + { + name: 'aipick', + version, + flags: { + generate: { + type: Number, + description: 'Number of responses to generate (Warning: generating multiple costs more) (default: 1)', + alias: 'g', + }, + message: { + type: String, + description: 'Message to ask to AI', + alias: 'm', + }, + systemPrompt: { + type: String, + description: 'System prompt to let users fine-tune prompt', + alias: 's', + }, + }, + + commands: [configCommand, logCommand], + + help: { + description, + }, + + ignoreArgv: type => type === 'unknown-flag' || type === 'argument', + }, + argv => { + aipick(argv.flags.generate, argv.flags.message, argv.flags.systemPrompt, rawArgv); + }, + rawArgv +); diff --git a/src/commands/aipick.ts b/src/commands/aipick.ts new file mode 100644 index 0000000..d6f9258 --- /dev/null +++ b/src/commands/aipick.ts @@ -0,0 +1,91 @@ +import fs from 'fs'; +import path from 'path'; + +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; + +import { AIRequestManager } from '../managers/ai-request.manager.js'; +import { ConsoleManager } from '../managers/console.manager.js'; +import { ReactivePromptManager } from '../managers/reactive-prompt.manager.js'; +import { ModelName, RawConfig, getConfig, modelNames } from '../utils/config.js'; +import { KnownError, handleCliError } from '../utils/error.js'; + +const consoleManager = new ConsoleManager(); + +export default async (generate: number | undefined, message: string | undefined, systemPrompt: string | undefined, rawArgv: string[]) => + (async () => { + consoleManager.printTitle(); + + if (!message) { + throw new KnownError('No messages found. Please type your message through the `-m` option.'); + } + + const config = await getConfig( + { + generate: generate as number, + systemPrompt: systemPrompt?.toString() as string, + }, + rawArgv + ); + + if (config.systemPromptPath) { + try { + fs.readFileSync(path.resolve(config.systemPromptPath), 'utf-8'); + } catch (error) { + throw new KnownError(`Error reading system prompt file: ${config.systemPromptPath}`); + } + } + + const availableAIs: ModelName[] = Object.entries(config) + .filter(([key]) => modelNames.includes(key as ModelName)) + .map(([key, value]) => [key, value] as [ModelName, RawConfig]) + .filter(([key, value]) => { + if (key === 'OLLAMA') { + return !!value && !!value.model && (value.model as string[]).length > 0; + } + if (key === 'HUGGINGFACE') { + return !!value && !!value.cookie; + } + // @ts-ignore ignore + return !!value.key && value.key.length > 0; + }) + .map(([key]) => key); + + const hasNoAvailableAIs = availableAIs.length === 0; + if (hasNoAvailableAIs) { + throw new KnownError('Please set at least one API key via the `aipick config set` command'); + } + + const aiRequestManager = new AIRequestManager(config, message); + const reactivePromptManager = new ReactivePromptManager(); + const selectPrompt = reactivePromptManager.initPrompt(!config.ignoreBody); + + reactivePromptManager.startLoader(); + const subscription = aiRequestManager.createAIRequests$(availableAIs).subscribe( + (choice: ReactiveListChoice) => reactivePromptManager.refreshChoices(choice), + () => { + /* empty */ + }, + () => reactivePromptManager.checkErrorOnChoices() + ); + const answer = await selectPrompt; + subscription.unsubscribe(); + reactivePromptManager.completeSubject(); + + // NOTE: reactiveListPrompt has 2 blank lines + consoleManager.moveCursorUp(); + + const chosenMessage = answer.aipickPrompt?.value; + if (!chosenMessage) { + throw new KnownError('An error occurred! No selected message'); + } + + // eslint-disable-next-line @typescript-eslint/no-var-requires + const ncp = require('copy-paste'); + ncp.copy(chosenMessage); + consoleManager.printCopied(); + process.exit(); + })().catch(error => { + consoleManager.printErrorMessage(error.message); + handleCliError(error); + process.exit(1); + }); diff --git a/src/commands/config.ts b/src/commands/config.ts new file mode 100644 index 0000000..843b1f5 --- /dev/null +++ b/src/commands/config.ts @@ -0,0 +1,44 @@ +import { command } from 'cleye'; + +import { ConsoleManager } from '../managers/console.manager.js'; +import { addConfigs, getConfig, hasOwn, setConfigs } from '../utils/config.js'; +import { KnownError, handleCliError } from '../utils/error.js'; + +export default command( + { + name: 'config', + parameters: ['', ''], + }, + argv => { + (async () => { + const { mode, keyValue: keyValues } = argv._; + + if (mode === 'get') { + const config = await getConfig({}, []); + for (const key of keyValues) { + if (hasOwn(config, key)) { + console.log(`${key}=${config[key as keyof typeof config]}`); + } + } + return; + } + + if (mode === 'set') { + await setConfigs(keyValues.map(keyValue => keyValue.split('=') as [string, string])); + return; + } + + if (mode === 'add') { + await addConfigs(keyValues.map(keyValue => keyValue.split('=') as [string, string])); + return; + } + + throw new KnownError(`Invalid mode: ${mode}`); + })().catch(error => { + const commandLineManager = new ConsoleManager(); + commandLineManager.printErrorMessage(error.message); + handleCliError(error); + process.exit(1); + }); + } +); diff --git a/src/commands/log.ts b/src/commands/log.ts new file mode 100644 index 0000000..c2b9f8d --- /dev/null +++ b/src/commands/log.ts @@ -0,0 +1,33 @@ +import { rm } from 'node:fs/promises'; + +import chalk from 'chalk'; +import { command } from 'cleye'; + +import { ConsoleManager } from '../managers/console.manager.js'; +import { KnownError, handleCliError } from '../utils/error.js'; +import { logPath } from '../utils/log.js'; + +export default command( + { + name: 'log', + parameters: [''], + }, + argv => { + (async () => { + const { removeAll } = argv._; + + if (removeAll === 'removeAll') { + await rm(logPath, { recursive: true, force: true }); + console.log(`${chalk.green('✔')} All Log files are removed!`); + return; + } + + throw new KnownError(`Invalid mode: ${removeAll}`); + })().catch(error => { + const commandLineManager = new ConsoleManager(); + commandLineManager.printErrorMessage(error.message); + handleCliError(error); + process.exit(1); + }); + } +); diff --git a/src/managers/ai-request.manager.ts b/src/managers/ai-request.manager.ts new file mode 100644 index 0000000..8329636 --- /dev/null +++ b/src/managers/ai-request.manager.ts @@ -0,0 +1,106 @@ +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, from, mergeMap, of } from 'rxjs'; + +import { AIServiceFactory } from '../services/ai/ai-service.factory.js'; +import { AnthropicService } from '../services/ai/anthropic.service.js'; +import { CodestralService } from '../services/ai/codestral.service.js'; +import { CohereService } from '../services/ai/cohere.service.js'; +import { GeminiService } from '../services/ai/gemini.service.js'; +import { GroqService } from '../services/ai/groq.service.js'; +import { HuggingFaceService } from '../services/ai/hugging-face.service.js'; +import { MistralService } from '../services/ai/mistral.service.js'; +import { OllamaService } from '../services/ai/ollama.service.js'; +import { OpenAIService } from '../services/ai/openai.service.js'; +import { ModelName, ValidConfig } from '../utils/config.js'; + +export class AIRequestManager { + constructor( + private readonly config: ValidConfig, + private readonly userMessage: string + ) {} + + createAIRequests$(modelNames: ModelName[]): Observable { + return from(modelNames).pipe( + mergeMap(ai => { + switch (ai) { + case 'OPENAI': + return AIServiceFactory.create(OpenAIService, { + config: this.config.OPENAI, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + case 'GEMINI': + return AIServiceFactory.create(GeminiService, { + config: this.config.GEMINI, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + case 'ANTHROPIC': + return AIServiceFactory.create(AnthropicService, { + config: this.config.ANTHROPIC, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + case 'HUGGINGFACE': + return AIServiceFactory.create(HuggingFaceService, { + config: this.config.HUGGINGFACE, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + case 'MISTRAL': + return AIServiceFactory.create(MistralService, { + config: this.config.MISTRAL, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + case 'CODESTRAL': + return AIServiceFactory.create(CodestralService, { + config: this.config.CODESTRAL, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + case 'OLLAMA': + return from(this.config.OLLAMA.model).pipe( + mergeMap(model => { + return AIServiceFactory.create(OllamaService, { + config: this.config.OLLAMA, + keyName: model as ModelName, + userMessage: this.userMessage, + }).generateChoice$(); + }) + ); + case 'COHERE': + return AIServiceFactory.create(CohereService, { + config: this.config.COHERE, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + case 'GROQ': + return AIServiceFactory.create(GroqService, { + config: this.config.GROQ, + userMessage: this.userMessage, + keyName: ai, + }).generateChoice$(); + default: + const prefixError = chalk.red.bold(`[${ai}]`); + return of({ + name: prefixError + ' Invalid AI type', + value: 'Invalid AI type', + isError: true, + disabled: true, + }); + } + }), + catchError(err => { + const prefixError = chalk.red.bold(`[UNKNOWN]`); + return of({ + name: prefixError + ` ${err.message || ''}`, + value: 'Unknown error', + isError: true, + disabled: true, + }); + }) + ); + } +} diff --git a/src/managers/console.manager.ts b/src/managers/console.manager.ts new file mode 100644 index 0000000..8e87891 --- /dev/null +++ b/src/managers/console.manager.ts @@ -0,0 +1,64 @@ +import readline from 'readline'; + +import chalk from 'chalk'; +import figlet from 'figlet'; +import ora, { Ora } from 'ora'; + +export class ConsoleManager { + private title = 'aipick'; + + printTitle() { + console.log(figlet.textSync(this.title, { font: 'Small' })); + } + + displaySpinner(text: string): Ora { + return ora(text).start(); + } + + stopSpinner(spinner: Ora) { + spinner.stop(); + spinner.clear(); + } + + printAnalyzed() { + console.log(`\n${chalk.bold.green('✔')} ${chalk.bold(`Changes analyzed`)}`); + } + + printCommitted() { + console.log(`\n${chalk.bold.green('✔')} ${chalk.bold(`Successfully committed!`)}`); + } + + printCopied() { + console.log(`\n${chalk.bold.green('✔')} ${chalk.bold(`Successfully copied! Press 'Ctrl + V' to paste`)}`); + } + + printSavedCommitMessage() { + console.log(`\n${chalk.bold.green('✔')} ${chalk.bold(`Saved commit message`)}`); + } + + printCancelledCopied() { + console.log(`\n${chalk.bold.yellow('⚠')} ${chalk.yellow('Copy cancelled')}`); + } + + printErrorMessage(message: string) { + console.log(`\n${chalk.bold.red('✖')} ${chalk.red(`${message}`)}`); + } + + moveCursorUp() { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + readline.moveCursor(process.stdout, 0, -1); + rl.close(); + } + + moveCursorDown() { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + readline.moveCursor(process.stdout, 0, 1); + rl.close(); + } +} diff --git a/src/managers/reactive-prompt.manager.ts b/src/managers/reactive-prompt.manager.ts new file mode 100644 index 0000000..100f53e --- /dev/null +++ b/src/managers/reactive-prompt.manager.ts @@ -0,0 +1,128 @@ +import chalk from 'chalk'; +import inquirer from 'inquirer'; +import ReactiveListPrompt, { ChoiceItem, ReactiveListChoice, ReactiveListLoader } from 'inquirer-reactive-list-prompt'; +import { BehaviorSubject, ReplaySubject } from 'rxjs'; + +import { DONE, sortByDisabled } from '../utils/utils.js'; + +const defaultLoader = { + isLoading: false, + startOption: { + text: 'Generating responses', + }, +}; + +const emptyResponses = `No responses were generated`; + +export class ReactivePromptManager { + private choices$: BehaviorSubject = new BehaviorSubject([]); + private loader$: BehaviorSubject = new BehaviorSubject(defaultLoader); + private destroyed$: ReplaySubject = new ReplaySubject(1); + + constructor() {} + + initPrompt(showDescription: boolean) { + inquirer.registerPrompt('reactiveListPrompt', ReactiveListPrompt); + return inquirer.prompt({ + type: 'reactiveListPrompt', + name: 'aipickPrompt', + message: 'Pick a response to copy: ', + emptyMessage: `⚠ ${emptyResponses}`, + loop: false, + showDescription, + descPageSize: 10, + choices$: this.choices$, + loader$: this.loader$, + }); + } + + startLoader() { + this.loader$.next({ isLoading: true }); + } + + refreshChoices(choice: ReactiveListChoice) { + const { value, isError } = choice; + if (!choice || !value) { + return; + } + const isNotStream = !choice.id; + if (isNotStream) { + this.choices$.next([...this.currentChoices, choice].sort(sortByDisabled)); + return; + } + + this.checkStreamChoice(choice); + } + + checkErrorOnChoices() { + const isAllError = this.choices$ + .getValue() + .map(choice => choice as ReactiveListChoice) + .every(value => value?.isError || value?.disabled); + + if (isAllError) { + this.alertNoGeneratedMessage(); + this.logEmptyCommitMessage(); + process.exit(1); + return; + } + this.stopLoaderOnSuccess(); + } + + completeSubject() { + this.choices$.complete(); + this.loader$.complete(); + this.destroyed$.next(true); + this.destroyed$.complete(); + } + + private alertNoGeneratedMessage() { + this.loader$.next({ + isLoading: false, + message: emptyResponses, + stopOption: { + doneFrame: '⚠', // '✖' + color: 'yellow', // 'red' + }, + }); + } + + private stopLoaderOnSuccess() { + this.loader$.next({ isLoading: false, message: 'Responses generated' }); + } + + private logEmptyCommitMessage() { + console.log(`${chalk.bold.yellow('⚠')} ${chalk.yellow(`${emptyResponses}`)}`); + } + + private checkStreamChoice(choice: ReactiveListChoice) { + const isDone = choice.description === DONE; + if (isDone) { + const findOriginChoice = this.currentChoices.find(origin => { + const originId = origin.id || ''; + const hasNumber = /\d/.test(originId); + return choice.id?.includes(originId) && !hasNumber; + }); + if (findOriginChoice) { + this.choices$.next( + [...this.currentChoices.filter(origin => origin.id !== findOriginChoice.id), choice].sort(sortByDisabled) + ); + return; + } + this.choices$.next([...this.currentChoices, choice].sort(sortByDisabled)); + return; + } + + // isUndone + const origin = this.currentChoices.find(origin => origin?.id === choice.id); + if (origin) { + this.choices$.next(this.currentChoices.map(origin => (origin?.id === choice.id ? choice : origin)).sort(sortByDisabled)); + return; + } + this.choices$.next([...this.currentChoices, choice].sort(sortByDisabled)); + } + + private get currentChoices(): ReactiveListChoice[] { + return this.choices$.getValue().map(origin => origin as ReactiveListChoice); + } +} diff --git a/src/services/ai/ai-service.factory.ts b/src/services/ai/ai-service.factory.ts new file mode 100644 index 0000000..1553090 --- /dev/null +++ b/src/services/ai/ai-service.factory.ts @@ -0,0 +1,7 @@ +import { AIService, AIServiceParams } from './ai.service.js'; + +export class AIServiceFactory { + static create(className: { new (params: AIServiceParams): T }, params: AIServiceParams): T { + return new className(params); + } +} diff --git a/src/services/ai/ai.service.ts b/src/services/ai/ai.service.ts new file mode 100644 index 0000000..5196522 --- /dev/null +++ b/src/services/ai/ai.service.ts @@ -0,0 +1,124 @@ +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, of } from 'rxjs'; + +import { ModelConfig, ModelName } from '../../utils/config.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; + +export interface AIResponse { + title: string; + value: string; +} + +export interface RawAIResponse { + summary: string; + description?: string; +} + +export interface AIServiceParams { + config: ModelConfig; + userMessage: string; + keyName: ModelName; +} + +export interface AIServiceError extends Error { + response?: any; +} + +export interface Theme { + primary: string; + [key: string]: string; +} + +export abstract class AIService { + protected serviceName: string; + protected errorPrefix: string; + protected colors: Theme; + + protected constructor(params: AIServiceParams) { + this.serviceName = 'AI'; + this.errorPrefix = 'ERROR'; + this.colors = { + primary: '', + }; + } + + abstract generateChoice$(): Observable; + + protected buildPrompt(userMessage: string, generate: number, systemPromptPath: string) { + const promptOption: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + userMessage, + generate, + systemPromptPath, + }; + const defaultPrompt = generatePrompt(promptOption); + return `${defaultPrompt}}\n${userMessage}`; + } + + protected handleError$ = (error: AIServiceError): Observable => { + let simpleMessage = 'An error occurred'; + if (error.message) { + simpleMessage = error.message; + } + return of({ + name: `${this.errorPrefix} ${simpleMessage}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; + + protected sanitizeResponse(generatedText: string, maxCount: number, ignoreBody: boolean): AIResponse[] { + try { + const rawResponses: RawAIResponse[] = JSON.parse(generatedText); + const filtedResponses = rawResponses.map((data: RawAIResponse) => { + if (ignoreBody) { + return { + title: `${data.summary}`, + value: `${data.description}`, + }; + } + return { + title: `${data.summary}`, + value: `${data.summary}${data.description ? `\n\n${data.description}` : ''}`, + }; + }); + + if (filtedResponses.length > maxCount) { + return filtedResponses.slice(0, maxCount); + } + return filtedResponses; + } catch (error) { + const jsonPattern = /\[[\s\S]*?\]/; + try { + const jsonMatch = generatedText.match(jsonPattern); + if (!jsonMatch) { + // No valid JSON array found in the response + return []; + } + const jsonStr = jsonMatch[0]; + const rawResponses: RawAIResponse[] = JSON.parse(jsonStr); + const filtedResponses = rawResponses.map((data: RawAIResponse) => { + if (ignoreBody) { + return { + title: `${data.summary}`, + value: `${data.summary}`, + }; + } + return { + title: `${data.summary}`, + value: `${data.summary}${data.description ? `\n\n${data.description}` : ''}`, + }; + }); + + if (filtedResponses.length > maxCount) { + return filtedResponses.slice(0, maxCount); + } + return filtedResponses; + } catch (e) { + // Error parsing JSON + return []; + } + } + } +} diff --git a/src/services/ai/anthropic.service.ts b/src/services/ai/anthropic.service.ts new file mode 100644 index 0000000..3ca46a8 --- /dev/null +++ b/src/services/ai/anthropic.service.ts @@ -0,0 +1,95 @@ +import Anthropic from '@anthropic-ai/sdk'; +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceError, AIServiceParams } from './ai.service.js'; +import { KnownError } from '../../utils/error.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; + +export interface AnthropicServiceError extends AIServiceError { + error?: { + error?: { + message?: string; + }; + }; +} + +export class AnthropicService extends AIService { + private anthropic: Anthropic; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#AE5630', + secondary: '#fff', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold('[Anthropic]'); + this.errorPrefix = chalk.red.bold(`[Anthropic]`); + this.anthropic = new Anthropic({ apiKey: this.params.config.key }); + } + + generateChoice$(): Observable { + return fromPromise(this.generateResponses()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + private async generateResponses(): Promise { + try { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + + const params: Anthropic.MessageCreateParams = { + max_tokens: this.params.config['max-tokens'], + temperature, + system: generatedSystemPrompt, + messages: [ + { + role: 'user', + content: userMessage, + }, + ], + model: this.params.config.model, + }; + const result: Anthropic.Message = await this.anthropic.messages.create(params); + const completion = result.content.map(({ text }) => text).join(''); + logging && createLogResponse('Anthropic', userMessage, generatedSystemPrompt, completion); + return this.sanitizeResponse(completion, generate, this.params.config.ignoreBody); + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny.code === 'ENOTFOUND') { + throw new KnownError(`Error connecting to ${errorAsAny.hostname} (${errorAsAny.syscall})`); + } + throw errorAsAny; + } + } + + handleError$ = (anthropicError: AnthropicServiceError) => { + const simpleMessage = anthropicError.error?.error?.message?.replace(/(\r\n|\n|\r)/gm, '') || 'An error occurred'; + return of({ + name: `${this.errorPrefix} ${simpleMessage}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; +} diff --git a/src/services/ai/codestral.service.ts b/src/services/ai/codestral.service.ts new file mode 100644 index 0000000..4fd2e4e --- /dev/null +++ b/src/services/ai/codestral.service.ts @@ -0,0 +1,122 @@ +import { AxiosResponse } from 'axios'; +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceError, AIServiceParams } from './ai.service.js'; +import { CreateChatCompletionsResponse } from './mistral.service.js'; +import { KnownError } from '../../utils/error.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; +import { getRandomNumber } from '../../utils/utils.js'; +import { HttpRequestBuilder } from '../http/http-request.builder.js'; +export interface CodestralServiceError extends AIServiceError {} + +export class CodestralService extends AIService { + private host = 'https://codestral.mistral.ai'; + private apiKey = ''; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#e28c58', + secondary: '#fff', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[Codestral]`); + this.errorPrefix = chalk.red.bold(`[Codestral]`); + this.apiKey = this.params.config.key; + } + + generateChoice$(): Observable { + return fromPromise(this.generateResponses()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + private async generateResponses(): Promise { + try { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + this.checkAvailableModels(); + const chatResponse = await this.createChatCompletions(generatedSystemPrompt, userMessage); + logging && createLogResponse('Codestral', userMessage, generatedSystemPrompt, chatResponse); + return this.sanitizeResponse(chatResponse, generate, this.params.config.ignoreBody); + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny.code === 'ENOTFOUND') { + throw new KnownError(`Error connecting to ${errorAsAny.hostname} (${errorAsAny.syscall})`); + } + throw errorAsAny; + } + } + handleError$ = (error: CodestralServiceError) => { + const simpleMessage = error.message?.replace(/(\r\n|\n|\r)/gm, '') || 'An error occurred'; + return of({ + name: `${this.errorPrefix} ${simpleMessage}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; + + private checkAvailableModels() { + const supportModels = ['codestral-latest', 'codestral-2405']; + if (supportModels.includes(this.params.config.model)) { + return true; + } + throw new Error(`Invalid model type of Codestral AI`); + } + + private async createChatCompletions(systemPrompt: string, userMessage: string) { + const response: AxiosResponse = await new HttpRequestBuilder({ + method: 'POST', + baseURL: `${this.host}/v1/chat/completions`, + timeout: this.params.config.timeout, + }) + .setHeaders({ + Authorization: `Bearer ${this.apiKey}`, + 'content-type': 'application/json', + }) + .setBody({ + model: this.params.config.model, + messages: [ + { + role: 'system', + content: systemPrompt, + }, + { + role: 'user', + content: userMessage, + }, + ], + temperature: this.params.config.temperature, + top_p: 1, + max_tokens: this.params.config['max-tokens'], + stream: false, + safe_prompt: false, + random_seed: getRandomNumber(10, 1000), + }) + .execute(); + const result: CreateChatCompletionsResponse = response.data; + const hasNoChoices = !result.choices || result.choices.length === 0; + if (hasNoChoices || !result.choices[0].message?.content) { + throw new Error(`No Content on response. Please open a Bug report`); + } + return result.choices[0].message.content; + } +} diff --git a/src/services/ai/cohere.service.ts b/src/services/ai/cohere.service.ts new file mode 100644 index 0000000..63104e6 --- /dev/null +++ b/src/services/ai/cohere.service.ts @@ -0,0 +1,92 @@ +import chalk from 'chalk'; +import { CohereClient, CohereError, CohereTimeoutError } from 'cohere-ai'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceParams } from './ai.service.js'; +import { KnownError } from '../../utils/error.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; + +export class CohereService extends AIService { + private cohere: CohereClient; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#D18EE2', + secondary: '#fff', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold('[Cohere]'); + this.errorPrefix = chalk.red.bold(`[Cohere]`); + this.cohere = new CohereClient({ + token: this.params.config.key, + }); + } + + generateChoice$(): Observable { + return fromPromise(this.generateResponses()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + private async generateResponses(): Promise { + try { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + const maxTokens = this.params.config['max-tokens']; + + const prediction = await this.cohere.chat({ + chatHistory: [{ role: 'SYSTEM', message: generatedSystemPrompt }], + message: userMessage, + connectors: [{ id: 'web-search' }], + maxTokens, + temperature, + model: this.params.config.model, + }); + + logging && createLogResponse('Cohere', userMessage, generatedSystemPrompt, prediction.text); + return this.sanitizeResponse(prediction.text, generate, this.params.config.ignoreBody); + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny instanceof CohereTimeoutError) { + throw new KnownError(`Request timed out error!`); + } + throw errorAsAny; + } + } + + handleError$ = (error: CohereError) => { + const regex = /"message":\s*"([^"]*)"/; + const match = error.message.match(regex); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + let simpleMessage = error?.body?.message; + if (match && match[1]) { + simpleMessage = match[1]; + } + const message = `${error.statusCode} ${simpleMessage}`; + return of({ + name: `${this.errorPrefix} ${message}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; +} diff --git a/src/services/ai/gemini.service.ts b/src/services/ai/gemini.service.ts new file mode 100644 index 0000000..d3e6a92 --- /dev/null +++ b/src/services/ai/gemini.service.ts @@ -0,0 +1,91 @@ +import { GoogleGenerativeAI } from '@google/generative-ai'; +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceError, AIServiceParams } from './ai.service.js'; +import { KnownError } from '../../utils/error.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; + +export class GeminiService extends AIService { + private genAI: GoogleGenerativeAI; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#0077FF', + secondary: '#fff', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold('[Gemini]'); + this.errorPrefix = chalk.red.bold(`[Gemini]`); + this.genAI = new GoogleGenerativeAI(this.params.config.key); + } + + generateChoice$(): Observable { + return fromPromise(this.generateResponses()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + private async generateResponses(): Promise { + try { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const maxTokens = this.params.config['max-tokens']; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + + const model = this.genAI.getGenerativeModel({ + model: this.params.config.model, + systemInstruction: generatedSystemPrompt, + generationConfig: { + maxOutputTokens: maxTokens, + temperature: this.params.config.temperature, + }, + }); + const result = await model.generateContent(userMessage); + const response = await result.response; + const completion = response.text(); + + logging && createLogResponse('Gemini', userMessage, generatedSystemPrompt, completion); + return this.sanitizeResponse(completion, generate, this.params.config.ignoreBody); + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny.code === 'ENOTFOUND') { + throw new KnownError(`Error connecting to ${errorAsAny.hostname} (${errorAsAny.syscall})`); + } + throw errorAsAny; + } + } + + handleError$ = (geminiError: AIServiceError) => { + const geminiErrorMessage = geminiError.message || geminiError.toString(); + const regex = /(\[.*?\]\s*[^[]*)/g; + const matches = [...geminiErrorMessage.matchAll(regex)]; + const result: string[] = []; + matches.forEach(match => result.push(match[1])); + + const message = result[1] || 'An error occurred'; + return of({ + name: `${this.errorPrefix} ${message}`, + value: message, + isError: true, + disabled: true, + }); + }; +} diff --git a/src/services/ai/groq.service.ts b/src/services/ai/groq.service.ts new file mode 100644 index 0000000..3d325ab --- /dev/null +++ b/src/services/ai/groq.service.ts @@ -0,0 +1,99 @@ +import chalk from 'chalk'; +import Groq from 'groq-sdk'; +import { GroqError } from 'groq-sdk/error'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceParams } from './ai.service.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; + +export class GroqService extends AIService { + private groq: Groq; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#f55036', + secondary: '#fff', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold('[Groq]'); + this.errorPrefix = chalk.red.bold(`[Groq]`); + this.groq = new Groq({ apiKey: this.params.config.key }); + } + + generateChoice$(): Observable { + return fromPromise(this.generateResponses()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + private async generateResponses(): Promise { + try { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const maxTokens = this.params.config['max-tokens']; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + + const chatCompletion = await this.groq.chat.completions.create( + { + messages: [ + { + role: 'system', + content: generatedSystemPrompt, + }, + { + role: 'user', + content: userMessage, + }, + ], + model: this.params.config.model, + max_tokens: maxTokens, + temperature, + }, + { + timeout: this.params.config.timeout, + } + ); + + const result = chatCompletion.choices[0].message.content || ''; + logging && createLogResponse('Groq', userMessage, generatedSystemPrompt, result); + return this.sanitizeResponse(result, generate, this.params.config.ignoreBody); + } catch (error) { + throw error as any; + } + } + + handleError$ = (error: GroqError) => { + let simpleMessage = 'An error occurred'; + const regex = /"message":\s*"([^"]*)"/; + const match = error.message.match(regex); + if (match && match[1]) { + simpleMessage = match[1]; + } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + const message = `${error['status']} ${simpleMessage}`; + return of({ + name: `${this.errorPrefix} ${message}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; +} diff --git a/src/services/ai/hugging-face.service.ts b/src/services/ai/hugging-face.service.ts new file mode 100644 index 0000000..fd057d9 --- /dev/null +++ b/src/services/ai/hugging-face.service.ts @@ -0,0 +1,462 @@ +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceParams } from './ai.service.js'; +import { KnownError } from '../../utils/error.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; + +interface Conversation { + id: string; + model: string; + systemPrompt: string; + title: string; + history: History[]; +} + +interface History { + id: string; + role: string; + content: string; + createdAt: number; + updatedAt: number; +} + +interface Model { + id: string | null; + name: string | null; + displayName: string | null; + preprompt: string | null; + promptExamples: { title: string; prompt: string }[]; + websiteUrl: string | null; + description: string | null; + datasetName: string | null; + datasetUrl: string | null; + modelUrl: string | null; + parameters: { [key: string]: any }; +} + +interface ChatResponse { + id: string | undefined; + stream: ReadableStream | undefined; + completeResponsePromise: () => Promise; +} + +// refer: https://github.com/rahulsushilsharma/huggingface-chat +export class HuggingFaceService extends AIService { + private headers = { + accept: '*/*', + 'accept-language': 'en-US,en;q=0.9', + 'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + origin: 'https://huggingface.co', + 'Referrer-Policy': 'strict-origin-when-cross-origin', + }; + private models: Model[] = []; + private currentModel: Model | undefined; + private currentModelId: string | null = null; + private currentConversation: Conversation | undefined = undefined; + private currentConversionID: string | undefined = undefined; + private cookie = ''; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#FED21F', + secondary: '#000', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold('[HuggingFace]'); + this.errorPrefix = chalk.red.bold(`[HuggingFace]`); + this.cookie = this.params.config.cookie; + } + + generateChoice$(): Observable { + return fromPromise(this.generateMessages()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + private async generateMessages(): Promise { + try { + await this.intialize(); + + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const maxTokens = this.params.config['max-tokens']; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + + const conversation = await this.getNewChat(generatedSystemPrompt); + const data = await this.sendMessage(userMessage, conversation.id); + const response = await data.completeResponsePromise(); + // await this.deleteConversation(conversation.id); + + logging && createLogResponse('HuggingFace', userMessage, generatedSystemPrompt, response); + return this.sanitizeResponse(response, generate, this.params.config.ignoreBody); + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny.code === 'ENOTFOUND') { + throw new KnownError(`Error connecting to ${errorAsAny.hostname} (${errorAsAny.syscall})`); + } + throw errorAsAny; + } + } + + /** + * Initializes the ChatBot instance. + * @async + * @returns {Promise} + */ + private async intialize(): Promise { + const models = await this.getRemoteLlms(); + const model = models.find(model => model.name?.toLowerCase() === this.params.config.model.toLowerCase())!; + if (model) { + this.currentModel = model; + this.currentModelId = model.id; + return; + } + this.currentModel = models[0]; + this.currentModelId = models[0].id; + } + + /** + * Fetches remote LLMs from a server. + * @returns {Promise} A promise that resolves to an array of fetched conversations. + * @throws {Error} If the server response is not successful. + */ + private async getRemoteLlms(): Promise { + const response = await fetch('https://huggingface.co/chat/__data.json', { + headers: { + ...this.headers, + cookie: this.cookie, + }, + body: null, + method: 'GET', + }); + + if (response.status !== 200) { + throw new Error(`Failed to get remote LLMs with status code: ${response.status}`); + } + const json = await response.json(); + const data = json.nodes[0].data; + const modelsIndices = data[data[0].models]; + const modelList: Model[] = []; + + const returnDataFromIndex = (index: number): any => (index === -1 ? null : data[index]); + + for (const modelIndex of modelsIndices) { + const modelData = data[modelIndex]; + + // Model is unlisted, skip it + if (data[modelData.unlisted]) { + continue; + } + + const m: Model = { + id: returnDataFromIndex(modelData.id), + name: returnDataFromIndex(modelData.name), + displayName: returnDataFromIndex(modelData.displayName), + preprompt: returnDataFromIndex(modelData.preprompt), + promptExamples: [], + websiteUrl: returnDataFromIndex(modelData.websiteUrl), + description: returnDataFromIndex(modelData.description), + datasetName: returnDataFromIndex(modelData.datasetName), + datasetUrl: returnDataFromIndex(modelData.datasetUrl), + modelUrl: returnDataFromIndex(modelData.modelUrl), + parameters: {}, + }; + + const promptList = returnDataFromIndex(modelData.promptExamples); + if (promptList !== null) { + const _promptExamples = promptList.map((index: number) => returnDataFromIndex(index)); + m.promptExamples = _promptExamples.map((prompt: any) => ({ + title: data[prompt.title], + prompt: data[prompt.prompt], + })); + } + + const indicesParametersDict: { [key: string]: number } = returnDataFromIndex(modelData.parameters); + const outParametersDict: { [key: string]: any } = {}; + for (const [key, value] of Object.entries(indicesParametersDict)) { + if (value === -1) { + outParametersDict[key] = null; + continue; + } + + if (Array.isArray(data[value])) { + outParametersDict[key] = data[value].map((index: number) => data[index]); + continue; + } + + outParametersDict[key] = data[value]; + } + m.parameters = outParametersDict; + modelList.push(m); + } + this.models = modelList; + + return modelList; + } + + /** + * Initializes a new chat conversation. + * @returns {Promise} The conversation ID of the new chat. + * @throws {Error} If the creation of a new conversation fails. + */ + private async getNewChat(systemPrompt?: string): Promise { + const model = { + model: this.currentModelId, + preprompt: systemPrompt, + }; + let retry = 0; + while (retry < 5) { + const response = await fetch('https://huggingface.co/chat/conversation', { + headers: { + ...this.headers, + 'content-type': 'application/json', + cookie: this.cookie, + Referer: 'https://huggingface.co/chat/', + }, + body: JSON.stringify(model), + method: 'POST', + }); + + const { conversationId } = await response.json(); + + if (conversationId) { + this.currentConversionID = conversationId; + break; + } else { + // console.error(`Failed to create new conversation error ${response.statusText}, retrying...`); + retry++; + } + } + + if (!this.currentConversionID) { + throw new Error('Failed to create new conversion'); + } + + return await this.getConversationHistory(this.currentConversionID); + } + + /** + * get the details of current conversation + * @returns {Promise} A Promise that return conversation details + * @throws {Error} If there is an api error + */ + private async getConversationHistory(conversationId: string) { + if (!conversationId) { + throw new Error('conversationId is required for getConversationHistory'); + } + const response = await fetch('https://huggingface.co/chat/conversation/' + conversationId + '/__data.json', { + headers: { + ...this.headers, + cookie: this.cookie, + Referer: 'https://huggingface.co/chat/', + }, + body: null, + method: 'GET', + }); + + if (response.status != 200) { + throw new Error('Unable get conversation details ' + response); + } else { + const json = await response.json(); + return this.metadataParser(json, conversationId); + } + } + + private metadataParser(meta: Record, conversationId: string) { + const conversation: Conversation = { + id: '', + model: '', + systemPrompt: '', + title: '', + history: [], + }; + const data: any = meta.nodes[1].data; + const model = data[data[0].model]; + const systemPrompt = data[data[0].preprompt]; + const title = data[data[0].title]; + + const messages: any[] = data[data[0].messages]; + const history: any[] = []; + + for (const index of messages) { + const nodeMeta = data[index]; + const createdAt = new Date(data[nodeMeta.createdAt][1]).getTime() / 1000; + const updatedAt = new Date(data[nodeMeta.updatedAt][1]).getTime() / 1000; + + history.push({ + id: data[nodeMeta.id], + role: data[nodeMeta.from], + content: data[nodeMeta.content], + createdAt, + updatedAt, + }); + } + + conversation.id = conversationId; + conversation.model = model; + conversation.systemPrompt = systemPrompt; + conversation.title = title; + conversation.history = history; + this.currentConversation = conversation; + return conversation; + } + + /** + * Initiates a chat with the provided text. + * @param {string} text - The user's input text or prompt. + * @param {string} currentConversionId - The conversation ID for the current chat. + * @returns {Promise} An object containing conversation details. + * @throws {Error} If there is an issue with the chat request. + */ + private async sendMessage(text: string, currentConversionId?: string): Promise { + if (text === '') { + throw new Error('the prompt can not be empty.'); + } + + if (!currentConversionId && !this.currentConversionID) { + await this.getNewChat(); // if no chat is avilable + } else if (currentConversionId) { + this.currentConversionID = currentConversionId; + await this.getConversationHistory(currentConversionId); + } else if (this.currentConversionID) { + await this.getConversationHistory(this.currentConversionID); + } + + if (!this.currentConversation) { + throw new Error('Failed to create new conversion'); + } + + const data = { + inputs: text, + id: this.currentConversation.history[this.currentConversation.history.length - 1].id, + is_retry: false, + is_continue: false, + web_search: false, + tools: {}, + }; + const formData = new FormData(); + formData.append('data', JSON.stringify(data)); + + const response = await fetch('https://huggingface.co/chat/conversation/' + this.currentConversionID + '', { + headers: { + ...this.headers, + cookie: this.cookie, + Referer: 'https://huggingface.co/chat/conversation/' + this.currentConversionID + '', + }, + body: formData, + method: 'POST', + }); + + function parseResponse(chunck: string) { + try { + // check if chunk contains multiple jsons + const _jsonArr = chunck.split('\n'); + const newJsonArray: any[] = []; + + for (const val of _jsonArr) { + if (val.trim()) { + newJsonArray.push(JSON.parse(val)); + } + } + return newJsonArray; + } catch (error) { + if (chunck) { + // console.error("Error parsing JSON:", chunck); + } + return [{}]; + } + } + const decoder = new TextDecoder(); + let completeResponse = ''; + + const transformStream = new TransformStream({ + async transform(chunk, controller) { + const decodedChunk = decoder.decode(chunk); + + try { + const modifiedDataArr = parseResponse(decodedChunk); + + for (const modifiedData of modifiedDataArr) { + if (modifiedData.type === 'finalAnswer') { + completeResponse = modifiedData?.text || ''; + controller.terminate(); + } else if (modifiedData.type === 'stream') { + controller.enqueue(modifiedData?.token || ''); + } + } + } catch { + throw new Error('Error during parsing response'); + } + }, + }); + const modifiedStream = response.body?.pipeThrough(transformStream); + + async function completeResponsePromise() { + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { + try { + if (!modifiedStream) { + reject(`ModifiedStream undefined`); + } else { + const reader = modifiedStream.getReader(); + + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value } = await reader.read(); + + if (done) { + resolve(completeResponse); + break; // The streaming has ended. + } + } + } + } catch (error) { + reject(error); // Reject the promise with the caught error + } + }); + } + + return { + id: this.currentConversionID, + stream: modifiedStream, + completeResponsePromise, + }; + } + + private async deleteConversation(conversationId: string): Promise { + const response = await fetch(`https://huggingface.co/chat/conversation/${conversationId}`, { + headers: { + ...this.headers, + cookie: this.cookie, + Referer: 'https://huggingface.co/chat/', + }, + body: null, + method: 'DELETE', + }); + + return response.json(); + } +} diff --git a/src/services/ai/mistral.service.ts b/src/services/ai/mistral.service.ts new file mode 100644 index 0000000..0b415f9 --- /dev/null +++ b/src/services/ai/mistral.service.ts @@ -0,0 +1,171 @@ +import { AxiosResponse } from 'axios'; +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceError, AIServiceParams } from './ai.service.js'; +import { KnownError } from '../../utils/error.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; +import { getRandomNumber } from '../../utils/utils.js'; +import { HttpRequestBuilder } from '../http/http-request.builder.js'; + +export interface MistralServiceError extends AIServiceError {} + +export interface ListAvailableModelsResponse { + object: string; + data: { + id: string; + object: string; + created: number; + owned_by: string; + }[]; +} + +export interface CreateChatCompletionsResponse { + id: string; + object: string; + created: number; + model: string; + choices: { + index: number; + message: { + role: string; + content: string; + }; + finish_reason: string; + }[]; + usage: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + }; +} + +export class MistralService extends AIService { + private host = `https://api.mistral.ai`; + private apiKey = ''; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#ff7000', + secondary: '#fff', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold('[MistralAI]'); + this.errorPrefix = chalk.red.bold(`[MistralAI]`); + this.apiKey = this.params.config.key; + } + + generateChoice$(): Observable { + return fromPromise(this.generateMessages()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + private async generateMessages(): Promise { + try { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const maxTokens = this.params.config['max-tokens']; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + + await this.checkAvailableModels(); + const chatResponse = await this.createChatCompletions(generatedSystemPrompt, userMessage); + logging && createLogResponse('MistralAI', userMessage, generatedSystemPrompt, chatResponse); + return this.sanitizeResponse(chatResponse, generate, this.params.config.ignoreBody); + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny.code === 'ENOTFOUND') { + throw new KnownError(`Error connecting to ${errorAsAny.hostname} (${errorAsAny.syscall})`); + } + throw errorAsAny; + } + } + + handleError$ = (error: MistralServiceError) => { + const simpleMessage = error.message?.replace(/(\r\n|\n|\r)/gm, '') || 'An error occurred'; + return of({ + name: `${this.errorPrefix} ${simpleMessage}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; + + private async checkAvailableModels() { + const availableModels = await this.getAvailableModels(); + if (availableModels.includes(this.params.config.model)) { + return true; + } + throw new Error(`Invalid model type of Mistral AI`); + } + + private async getAvailableModels() { + const response: AxiosResponse = await new HttpRequestBuilder({ + method: 'GET', + baseURL: `${this.host}/v1/models`, + timeout: this.params.config.timeout, + }) + .setHeaders({ + Authorization: `Bearer ${this.apiKey}`, + 'content-type': 'application/json', + }) + .execute(); + + return response.data.data.filter(model => model.object === 'model').map(model => model.id); + } + + private async createChatCompletions(systemPrompt: string, userMessage: string) { + const response: AxiosResponse = await new HttpRequestBuilder({ + method: 'POST', + baseURL: `${this.host}/v1/chat/completions`, + timeout: this.params.config.timeout, + }) + .setHeaders({ + Authorization: `Bearer ${this.apiKey}`, + 'content-type': 'application/json', + }) + .setBody({ + model: this.params.config.model, + messages: [ + { + role: 'system', + content: systemPrompt, + }, + { + role: 'user', + content: userMessage, + }, + ], + temperature: this.params.config.temperature, + top_p: 1, + max_tokens: this.params.config['max-tokens'], + stream: false, + safe_prompt: false, + random_seed: getRandomNumber(10, 1000), + }) + .execute(); + const result: CreateChatCompletionsResponse = response.data; + const hasNoChoices = !result.choices || result.choices.length === 0; + if (hasNoChoices || !result.choices[0].message?.content) { + throw new Error(`No Content on response. Please open a Bug report`); + } + return result.choices[0].message.content; + } +} diff --git a/src/services/ai/ollama.service.ts b/src/services/ai/ollama.service.ts new file mode 100644 index 0000000..21bb55f --- /dev/null +++ b/src/services/ai/ollama.service.ts @@ -0,0 +1,132 @@ +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Ollama } from 'ollama'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceError, AIServiceParams } from './ai.service.js'; +import { DEFAULT_OLLMA_HOST } from '../../utils/config.js'; +import { KnownError } from '../../utils/error.js'; +import { createLogResponse } from '../../utils/log.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; +import { capitalizeFirstLetter } from '../../utils/utils.js'; +import { HttpRequestBuilder } from '../http/http-request.builder.js'; + +export interface OllamaServiceError extends AIServiceError {} + +export class OllamaService extends AIService { + private host = DEFAULT_OLLMA_HOST; + private model = ''; + private ollama: Ollama; + + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#FFF', + secondary: '#000', + }; + this.model = this.params.keyName; + this.serviceName = chalk + .bgHex(this.colors.primary) + .hex(this.colors.secondary) + .bold(`[${capitalizeFirstLetter(this.model)}]`); + this.errorPrefix = chalk.red.bold(`[${capitalizeFirstLetter(this.model)}]`); + this.host = this.params.config.host || DEFAULT_OLLMA_HOST; + this.ollama = new Ollama({ host: this.host }); + } + + generateChoice$(): Observable { + return fromPromise(this.generateMessages()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + handleError$ = (error: OllamaServiceError) => { + if (!!error.response && error.response.data?.error) { + return of({ + name: `${this.errorPrefix} ${error.response.data?.error}`, + value: error.response.data?.error, + isError: true, + disabled: true, + }); + } + const simpleMessage = error.message?.replace(/(\r\n|\n|\r)/gm, '') || 'An error occurred'; + return of({ + name: `${this.errorPrefix} ${simpleMessage}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; + + private async generateMessages(): Promise { + try { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + + await this.checkIsAvailableOllama(); + const chatResponse = await this.createChatCompletions(generatedSystemPrompt, userMessage); + logging && createLogResponse(`Ollama_${this.model}`, userMessage, generatedSystemPrompt, chatResponse); + return this.sanitizeResponse(chatResponse, generate, this.params.config.ignoreBody); + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny.code === 'ENOTFOUND') { + throw new KnownError(`Error connecting to ${errorAsAny.hostname} (${errorAsAny.syscall})`); + } + throw errorAsAny; + } + } + + private async checkIsAvailableOllama() { + try { + const response = await new HttpRequestBuilder({ + method: 'GET', + baseURL: `${this.host}`, + timeout: this.params.config.OLLAMA_TIMEOUT, + }).execute(); + + return response.data; + } catch (e: any) { + if (e.code === 'ECONNREFUSED') { + throw new KnownError(`Error connecting to ${this.host}. Please run Ollama or check host`); + } + throw e; + } + } + + private async createChatCompletions(systemPrompt: string, userMessage: string) { + const response = await this.ollama.chat({ + model: this.model, + messages: [ + { + role: 'system', + content: systemPrompt, + }, + { + role: 'user', + content: userMessage, + }, + ], + stream: false, + options: { + temperature: this.params.config.temperature, + }, + }); + return response.message.content; + } +} diff --git a/src/services/ai/openai.service.ts b/src/services/ai/openai.service.ts new file mode 100644 index 0000000..841eb53 --- /dev/null +++ b/src/services/ai/openai.service.ts @@ -0,0 +1,91 @@ +import chalk from 'chalk'; +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; +import { Observable, catchError, concatMap, from, map, of } from 'rxjs'; +import { fromPromise } from 'rxjs/internal/observable/innerFrom'; + +import { AIResponse, AIService, AIServiceError, AIServiceParams } from './ai.service.js'; +import { generateMessage } from '../../utils/openai.js'; +import { DEFAULT_PROMPT_OPTIONS, PromptOptions, generatePrompt } from '../../utils/prompt.js'; + +export class OpenAIService extends AIService { + constructor(private readonly params: AIServiceParams) { + super(params); + this.colors = { + primary: '#74AA9C', + secondary: '#FFF', + }; + this.serviceName = chalk.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[ChatGPT]`); + this.errorPrefix = chalk.red.bold(`[ChatGPT]`); + } + + generateChoice$(): Observable { + return fromPromise(this.generateMessages()).pipe( + concatMap(messages => from(messages)), + map(data => ({ + name: `${this.serviceName} ${data.title}`, + value: data.value, + description: data.value, + isError: false, + })), + catchError(this.handleError$) + ); + } + + handleError$ = (error: AIServiceError) => { + let simpleMessage = 'An error occurred'; + if (error.message) { + simpleMessage = error.message.split('\n')[0]; + const errorJson = this.extractJSONFromError(error.message); + simpleMessage += `: ${errorJson.error.message}`; + } + return of({ + name: `${this.errorPrefix} ${simpleMessage}`, + value: simpleMessage, + isError: true, + disabled: true, + }); + }; + + private extractJSONFromError(error: string) { + const regex = /[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis; + const matches = error.match(regex); + if (matches) { + return Object.assign({}, ...matches.map((m: any) => JSON.parse(m))); + } + return { + error: { + message: 'Unknown error', + }, + }; + } + + private async generateMessages(): Promise { + const userMessage = this.params.userMessage; + const { generate, systemPrompt, systemPromptPath, logging, temperature } = this.params.config; + const promptOptions: PromptOptions = { + ...DEFAULT_PROMPT_OPTIONS, + generate, + userMessage, + systemPrompt, + systemPromptPath, + }; + const generatedSystemPrompt = generatePrompt(promptOptions); + + const response = await generateMessage( + this.params.config.url, + this.params.config.path, + this.params.config.key, + this.params.config.model, + generate, + this.params.config.timeout, + this.params.config['max-tokens'], + this.params.config.temperature, + userMessage, + generatedSystemPrompt, + this.params.config.logging, + this.params.config.proxy + ); + + return this.sanitizeResponse(response, generate, this.params.config.ignoreBody); + } +} diff --git a/src/services/http/http-request.builder.ts b/src/services/http/http-request.builder.ts new file mode 100644 index 0000000..4c34fb3 --- /dev/null +++ b/src/services/http/http-request.builder.ts @@ -0,0 +1,60 @@ +import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; + +export declare type Body = { + [key: string]: any; +}; + +export declare type Headers = { + [key: string]: any; +}; + +export declare type Params = { + [key: string]: any; +}; + +export class HttpRequestBuilder { + private axiosInstance: AxiosInstance; + private config: AxiosRequestConfig; + + constructor(config: AxiosRequestConfig = {}) { + if (!config.method) { + throw new Error('method should be defined!'); + } + if (!config.baseURL) { + throw new Error('baseURL should be defined!'); + } + this.config = { + ...config, + }; + this.axiosInstance = axios.create(this.config); + } + + setHeaders(headers: Headers): HttpRequestBuilder { + this.config.headers = headers; + return this; + } + + setParams(params: Params): HttpRequestBuilder { + this.config.params = params; + return this; + } + + setBody(data: Body): HttpRequestBuilder { + this.config.data = data; + return this; + } + + setMethod(method: string): HttpRequestBuilder { + this.config.method = method; + return this; + } + + async execute(): Promise> { + // eslint-disable-next-line no-useless-catch + try { + return await this.axiosInstance.request(this.config); + } catch (error) { + throw error; + } + } +} diff --git a/src/utils/config.ts b/src/utils/config.ts new file mode 100644 index 0000000..6ac2527 --- /dev/null +++ b/src/utils/config.ts @@ -0,0 +1,460 @@ +import fs from 'fs/promises'; +import os from 'os'; +import path from 'path'; + +import ini from 'ini'; + +import { KnownError } from './error.js'; +import { fileExists } from './fs.js'; +import { flattenArray } from './utils.js'; + +import type { TiktokenModel } from '@dqbd/tiktoken'; + + +export const DEFAULT_OLLMA_HOST = 'http://localhost:11434'; + +const { hasOwnProperty } = Object.prototype; +export const hasOwn = (object: unknown, key: PropertyKey) => hasOwnProperty.call(object, key); + +const parseAssert = (name: string, condition: any, message: string) => { + if (!condition) { + throw new KnownError(`Invalid config property ${name}: ${message}`); + } +}; + +export const modelNames = ['OPENAI', 'OLLAMA', 'HUGGINGFACE', 'GEMINI', 'ANTHROPIC', 'MISTRAL', 'CODESTRAL', 'COHERE', 'GROQ'] as const; +export type ModelName = (typeof modelNames)[number]; + +const generalConfigParsers = { + systemPrompt(systemPrompt?: string) { + if (!systemPrompt) { + return ''; + } + return systemPrompt; + }, + systemPromptPath(systemPromptPath?: string) { + if (!systemPromptPath) { + return ''; + } + return systemPromptPath; + }, + generate(count?: string) { + if (!count) { + return 1; + } + + parseAssert('generate', /^\d+$/.test(count), 'Must be an integer'); + + const parsed = Number(count); + parseAssert('generate', parsed > 0, 'Must be greater than 0'); + parseAssert('generate', parsed <= 5, 'Must be less or equal to 5'); + + return parsed; + }, + timeout(timeout?: string) { + if (!timeout) { + return 10_000; + } + + parseAssert('timeout', /^\d+$/.test(timeout), 'Must be an integer'); + + const parsed = Number(timeout); + parseAssert('timeout', parsed >= 500, 'Must be greater than 500ms'); + + return parsed; + }, + temperature(temperature?: string) { + if (!temperature) { + return 0.7; + } + + parseAssert('temperature', /^(2|\d)(\.\d{1,2})?$/.test(temperature), 'Must be decimal between 0 and 2'); + + const parsed = Number(temperature); + parseAssert('temperature', parsed > 0.0, 'Must be greater than 0'); + parseAssert('temperature', parsed <= 2.0, 'Must be less than or equal to 2'); + + return parsed; + }, + 'max-tokens'(maxTokens?: string) { + if (!maxTokens) { + return 1024; + } + + parseAssert('max-tokens', /^\d+$/.test(maxTokens), 'Must be an integer'); + return Number(maxTokens); + }, + logging(enable?: string | boolean) { + if (!enable) { + return true; + } + if (typeof enable === 'boolean') { + return enable; + } + parseAssert('logging', /^(?:true|false)$/.test(enable), 'Must be a boolean(true or false)'); + return enable === 'true'; + }, + ignoreBody(ignore?: string | boolean) { + if (!ignore) { + return false; + } + if (typeof ignore === 'boolean') { + return ignore; + } + + parseAssert('ignoreBody', /^(?:true|false)$/.test(ignore), 'Must be a boolean(true or false)'); + return ignore === 'true'; + }, +} as const; + +const modelConfigParsers: Record any>> = { + OPENAI: { + key: (key?: string) => key || '', + model: (model?: string): TiktokenModel => (model || 'gpt-3.5-turbo') as TiktokenModel, + url: (host?: string) => { + if (!host) { + return 'https://api.openai.com'; + } + parseAssert('OPENAI.url', /^https?:\/\//.test(host), 'Must be a valid URL'); + return host; + }, + path: (path?: string) => path || '/v1/chat/completions', + proxy: (proxy?: string) => proxy || '', + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + OLLAMA: { + model: (models?: string | string[]): string[] => { + if (!models) { + return []; + } + const modelList = typeof models === 'string' ? models?.split(',') : models; + return modelList.map(model => model.trim()).filter(model => !!model && model.length > 0); + }, + host: (host?: string) => { + if (!host) { + return DEFAULT_OLLMA_HOST; + } + parseAssert('OLLAMA.host', /^https?:\/\//.test(host), 'Must be a valid URL'); + return host; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + HUGGINGFACE: { + cookie: (cookie?: string) => cookie || '', + model: (model?: string): string => { + if (!model) { + return `CohereForAI/c4ai-command-r-plus`; + } + const supportModels = [ + `CohereForAI/c4ai-command-r-plus`, + `meta-llama/Meta-Llama-3-70B-Instruct`, + `HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1`, + `mistralai/Mixtral-8x7B-Instruct-v0.1`, + `NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO`, + `01-ai/Yi-1.5-34B-Chat`, + `mistralai/Mistral-7B-Instruct-v0.2`, + `microsoft/Phi-3-mini-4k-instruct`, + ]; + + parseAssert('HUGGINGFACE.model', supportModels.includes(model), 'Invalid model type of HuggingFace chat'); + return model; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + GEMINI: { + key: (key?: string) => key || '', + model: (model?: string) => { + if (!model || model.length === 0) { + return 'gemini-1.5-pro-latest'; + } + const supportModels = ['gemini-1.5-flash-latest', 'gemini-1.5-pro-latest']; + parseAssert('GEMINI.model', supportModels.includes(model), 'Invalid model type of Gemini'); + return model; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + ANTHROPIC: { + key: (key?: string) => key || '', + model: (model?: string) => { + if (!model || model.length === 0) { + return 'claude-3-haiku-20240307'; + } + const supportModels = [ + 'claude-2.1', + 'claude-2.0', + 'claude-instant-1.2', + 'claude-3-haiku-20240307', + 'claude-3-sonnet-20240229', + 'claude-3-opus-20240229', + ]; + parseAssert('ANTHROPIC.model', supportModels.includes(model), 'Invalid model type of Anthropic'); + return model; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + MISTRAL: { + key: (key?: string) => key || '', + model: (model?: string) => { + if (!model || model.length === 0) { + return 'mistral-tiny'; + } + const supportModels = [ + 'open-mistral-7b', + 'mistral-tiny-2312', + 'mistral-tiny', + 'open-mixtral-8x7b', + 'mistral-small-2312', + 'mistral-small', + 'mistral-small-2402', + 'mistral-small-latest', + 'mistral-medium-latest', + 'mistral-medium-2312', + 'mistral-medium', + 'mistral-large-latest', + 'mistral-large-2402', + 'mistral-embed', + ]; + + parseAssert('MISTRAL.model', supportModels.includes(model), 'Invalid model type of Mistral AI'); + return model; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + CODESTRAL: { + key: (key?: string) => key || '', + model: (model?: string) => { + if (!model || model.length === 0) { + return 'codestral-latest'; + } + const supportModels = ['codestral-latest', 'codestral-2405']; + + parseAssert('CODESTRAL.model', supportModels.includes(model), 'Invalid model type of Codestral'); + return model; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + COHERE: { + key: (key?: string) => key || '', + model: (model?: string) => { + if (!model || model.length === 0) { + return 'command-r-plus'; + } + const supportModels = ['command-r-plus', 'command-r', 'command', `command-nightly`, `command-light`, `command-light-nightly`]; + parseAssert('COHERE.model', supportModels.includes(model), 'Invalid model type of Cohere'); + return model; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, + GROQ: { + key: (key?: string) => key || '', + model: (model?: string) => { + if (!model || model.length === 0) { + return 'gemma-7b-it'; + } + const supportModels = [`llama3-8b-8192`, 'llama3-70b-8192', `mixtral-8x7b-32768`, `gemma-7b-it`]; + parseAssert('GROQ.model', supportModels.includes(model), 'Invalid model type of Groq'); + return model; + }, + systemPrompt: generalConfigParsers.systemPrompt, + systemPromptPath: generalConfigParsers.systemPromptPath, + generate: generalConfigParsers.generate, + timeout: generalConfigParsers.timeout, + temperature: generalConfigParsers.temperature, + 'max-tokens': generalConfigParsers['max-tokens'], + logging: generalConfigParsers.logging, + ignoreBody: generalConfigParsers.ignoreBody, + }, +}; + +export type RawConfig = { + [key: string]: string | string[] | Record | number; +}; + +export type ValidConfig = { + [Key in keyof typeof generalConfigParsers]: ReturnType<(typeof generalConfigParsers)[Key]>; +} & { + [Model in ModelName]: ModelConfig; +}; + +export type ModelConfig = { + [Key in keyof (typeof modelConfigParsers)[Model]]: ReturnType<(typeof modelConfigParsers)[Model][Key]>; +}; + +const configPath = path.join(os.homedir(), '.aipick'); + +const parseCliArgs = (rawArgv: string[] = []): RawConfig => { + const cliConfig: RawConfig = {}; + for (const arg of rawArgv) { + if (arg.startsWith('--')) { + const [key, value] = arg.slice(2).split('='); + const [modelName, modelKey] = key.split('.'); + if (modelName && modelKey && modelName in modelConfigParsers) { + if (!cliConfig[modelName]) { + cliConfig[modelName] = {}; + } + (cliConfig[modelName] as Record)[modelKey] = value; + } else { + cliConfig[key] = value; + } + } + } + return cliConfig; +}; + +const readConfigFile = async (): Promise => { + const configExists = await fileExists(configPath); + if (!configExists) { + return Object.create(null); + } + + const configString = await fs.readFile(configPath, 'utf8'); + let config = ini.parse(configString); + const hasOllmaModel = hasOwn(config, 'OLLAMA') && hasOwn(config['OLLAMA'], 'model'); + if (hasOllmaModel) { + config = { + ...config, + OLLAMA: { + ...config.OLLAMA, + model: typeof config['OLLAMA'].model === 'string' ? [config['OLLAMA'].model] : config['OLLAMA'].model, + }, + }; + } + return config; +}; + +export const getConfig = async (cliConfig: RawConfig, rawArgv: string[] = []): Promise => { + const config = await readConfigFile(); + const parsedCliArgs = parseCliArgs(rawArgv); + const mergedCliConfig = { ...cliConfig, ...parsedCliArgs }; + const parsedConfig: Record = {}; + + // Helper function to get the value with priority + const getValueWithPriority = (modelName: string, key: string) => { + const cliValue = mergedCliConfig[`${modelName}.${key}`] ?? (mergedCliConfig[modelName] as Record)?.[key]; + const modelValue = (config[modelName] as Record)?.[key]; + const generalValue = mergedCliConfig[key] ?? config[key]; + return cliValue !== undefined ? cliValue : modelValue !== undefined ? modelValue : generalValue; + }; + + // Parse general configs + for (const [key, parser] of Object.entries(generalConfigParsers)) { + const value = mergedCliConfig[key] ?? config[key]; + parsedConfig[key] = parser(value as any); + } + + // Parse model-specific configs + for (const [modelName, modelParsers] of Object.entries(modelConfigParsers)) { + parsedConfig[modelName] = {}; + for (const [key, parser] of Object.entries(modelParsers)) { + const value = getValueWithPriority(modelName, key); + (parsedConfig[modelName] as Record)[key] = parser(value); + } + } + + return parsedConfig as ValidConfig; +}; + +export const setConfigs = async (keyValues: [key: string, value: any][]) => { + const config = await readConfigFile(); + + for (const [key, value] of keyValues) { + const [modelName, modelKey] = key.split('.'); + if (modelName in modelConfigParsers) { + if (!config[modelName]) { + config[modelName] = {}; + } + const parser = modelConfigParsers[modelName as ModelName][modelKey]; + if (!parser) { + throw new KnownError(`Invalid config property: ${key}`); + } + (config[modelName] as Record)[modelKey] = parser(value); + } else { + const parser = generalConfigParsers[key as keyof typeof generalConfigParsers]; + if (!parser) { + throw new KnownError(`Invalid config property: ${key}`); + } + // @ts-ignore ignore + config[key] = parser(value); + } + } + + await fs.writeFile(configPath, ini.stringify(config), 'utf8'); +}; + +export const addConfigs = async (keyValues: [key: string, value: any][]) => { + const config = await readConfigFile(); + + for (const [key, value] of keyValues) { + const [modelName, modelKey] = key.split('.'); + + if (modelName in modelConfigParsers) { + if (!config[modelName]) { + config[modelName] = {}; + } + const isOllamaModel = modelName === 'OLLAMA' && modelKey === 'model'; + const parser = modelConfigParsers[modelName as ModelName][modelKey]; + if (!parser || !isOllamaModel) { + throw new KnownError(`Invalid config property: ${key}. Only supports OLLAMA.model`); + } + const originModels = (config[modelName] as Record)[modelKey] || []; + (config[modelName] as Record)[modelKey] = flattenArray([...originModels, parser(value)]); + } else { + throw new KnownError(`Invalid config property: ${key}. Only supports OLLAMA.model`); + } + } + + await fs.writeFile(configPath, ini.stringify(config), 'utf8'); +}; diff --git a/src/utils/error.ts b/src/utils/error.ts new file mode 100644 index 0000000..48d6dc4 --- /dev/null +++ b/src/utils/error.ts @@ -0,0 +1,22 @@ +import chalk from 'chalk'; + +import { version } from '../../package.json'; + +export class KnownError extends Error {} + +const indent = ' '; + +export const handleCliError = (error: any) => { + const isNotError = !(error instanceof Error); + if (isNotError) { + return; + } + if (!(error instanceof KnownError)) { + if (error.stack) { + console.error(chalk.dim(error.stack.split('\n').slice(1).join('\n'))); + } + console.error(`\n${indent}${chalk.dim(`aipick v${version}`)}`); + console.error(`\n${indent}Please open a Bug report with the information above:`); + console.error(`${indent}https://github.com/tak-bro/aipick/issues/new/choose`); + } +}; diff --git a/src/utils/fs.ts b/src/utils/fs.ts new file mode 100644 index 0000000..bfe8906 --- /dev/null +++ b/src/utils/fs.ts @@ -0,0 +1,8 @@ +import fs from 'fs/promises'; + +// lstat is used because this is also used to check if a symlink file exists +export const fileExists = (filePath: string) => + fs.lstat(filePath).then( + () => true, + () => false + ); diff --git a/src/utils/log.ts b/src/utils/log.ts new file mode 100644 index 0000000..58874f3 --- /dev/null +++ b/src/utils/log.ts @@ -0,0 +1,53 @@ +import fs from 'fs'; +import os from 'os'; +import path from 'path'; + +import { xxh64 } from '@pacote/xxhash'; + +import { removeTextAfterPhrase } from './utils.js'; + +export const logPath = path.join(os.homedir(), '.aipick_log'); + +const now = new Date(); + +export const createLogResponse = (aiName: string, userMessage: string, prompt: string, response: string) => { + const title = `[${aiName} Response]`; + const fileName = generateLogFileName(now, userMessage); + const fullPath = `${logPath}/${fileName}`; + if (fs.existsSync(fullPath)) { + const originData = fs.readFileSync(fullPath, 'utf-8'); + writeFileSyncRecursive(fullPath, `${title}\n${response}\n\n${originData}`); + return; + } + const removedPrompt = removeTextAfterPhrase( + prompt, + 'Example response format:\n[\n {\n "subject": "string",\n "body": "string",\n },\n ...\n]' + ); + writeFileSyncRecursive( + fullPath, + `${title}\n${response}\n\n\n[AIPick System Prompt]\n${removedPrompt}\n\n\n[User Prompt]\n${userMessage}` + ); +}; + +export const generateLogFileName = (date: Date, diff: string) => { + const { year, month, day, hours, minutes, seconds } = getDateString(date); + const hasher = xxh64(0); + const hash = hasher.update(diff).digest('hex'); + return `aip_${year}-${month}-${day}_${hours}:${minutes}:${seconds}_${hash}.log`; +}; + +export const writeFileSyncRecursive = (fileName: string, content: string = '') => { + fs.mkdirSync(path.dirname(fileName), { recursive: true }); + fs.writeFileSync(fileName, content, 'utf-8'); +}; + +export const getDateString = (date: Date) => { + const year = date.getFullYear().toString(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + const hours = date.getHours().toString().padStart(2, '0'); + const minutes = date.getMinutes().toString().padStart(2, '0'); + const seconds = date.getSeconds().toString().padStart(2, '0'); + + return { year, month, day, hours, minutes, seconds }; +}; diff --git a/src/utils/openai.ts b/src/utils/openai.ts new file mode 100644 index 0000000..8e09920 --- /dev/null +++ b/src/utils/openai.ts @@ -0,0 +1,163 @@ +import http from 'http'; +import https from 'https'; + +import { type TiktokenModel } from '@dqbd/tiktoken'; +import createHttpsProxyAgent from 'https-proxy-agent'; + +import { KnownError } from './error.js'; +import { createLogResponse } from './log.js'; + +import type { ClientRequest, IncomingMessage } from 'http'; +import type { CreateChatCompletionRequest, CreateChatCompletionResponse } from 'openai'; + +export const httpsPost = async ( + url: URL, + path: string, + headers: Record, + json: unknown, + timeout: number, + proxy?: string, + port?: number +) => + new Promise<{ + request: ClientRequest; + response: IncomingMessage; + data: string; + }>((resolve, reject) => { + const postContent = JSON.stringify(json); + const httpModule = url.protocol.includes('https') ? https : http; + const request = httpModule.request( + { + port: port ? port : undefined, + hostname: url.hostname, + path, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(postContent), + ...headers, + }, + timeout, + agent: proxy ? createHttpsProxyAgent(proxy) : undefined, + }, + response => { + const body: Buffer[] = []; + response.on('data', chunk => body.push(chunk)); + response.on('end', () => { + resolve({ + request, + response, + data: Buffer.concat(body).toString(), + }); + }); + } + ); + request.on('error', reject); + request.on('timeout', () => { + request.destroy(); + reject(new KnownError(`Time out error: request took over ${timeout}ms. Try increasing the \`timeout\` config`)); + }); + + request.write(postContent); + request.end(); + }); + +const createChatCompletion = async ( + url: string, + path: string, + apiKey: string, + json: CreateChatCompletionRequest, + timeout: number, + proxy?: string +) => { + const openAIUrl = new URL(url); + const { response, data } = await httpsPost( + openAIUrl, + path, + { + Authorization: `Bearer ${apiKey}`, + }, + json, + timeout, + proxy + ); + + if (!response.statusCode || response.statusCode < 200 || response.statusCode > 299) { + let errorMessage = `OpenAI API Error: ${response.statusCode} - ${response.statusMessage}`; + + if (data) { + errorMessage += `\n\n${data}`; + } + + if (response.statusCode === 500) { + errorMessage += '\n\nCheck the API status: https://status.openai.com'; + } + + throw new KnownError(errorMessage); + } + + return JSON.parse(data) as CreateChatCompletionResponse; +}; + +const sanitizeMessage = (message: string) => + message + .trim() + .replace(/[\n\r]/g, '') + .replace(/(\w)\.$/, '$1'); + +export const generateMessage = async ( + url: string, + path: string, + apiKey: string, + model: TiktokenModel, + generate: number, + timeout: number, + maxTokens: number, + temperature: number, + userMessage: string, + systemPrompt: string, + logging: boolean, + proxy?: string +) => { + try { + const completion = await createChatCompletion( + url, + path, + apiKey, + { + model, + messages: [ + { + role: 'system', + content: systemPrompt, + }, + { + role: 'user', + content: userMessage, + }, + ], + temperature, + top_p: 1, + frequency_penalty: 0, + presence_penalty: 0, + max_tokens: maxTokens, + stream: false, + }, + timeout, + proxy + ); + + const fullText = completion.choices + .filter(choice => choice.message?.content) + .map(choice => sanitizeMessage(choice.message!.content as string)) + .join(); + logging && createLogResponse('OPEN AI', userMessage, systemPrompt, fullText); + return fullText; + } catch (error) { + const errorAsAny = error as any; + if (errorAsAny.code === 'ENOTFOUND') { + throw new KnownError(`Error connecting to ${errorAsAny.hostname} (${errorAsAny.syscall})`); + } + throw errorAsAny; + } +}; diff --git a/src/utils/prompt.ts b/src/utils/prompt.ts new file mode 100644 index 0000000..b44256d --- /dev/null +++ b/src/utils/prompt.ts @@ -0,0 +1,69 @@ +import fs from 'fs'; +import path from 'path'; + +export interface PromptOptions { + generate: number; + userMessage: string; + systemPromptPath?: string; + systemPrompt?: string; +} + +export const DEFAULT_PROMPT_OPTIONS: PromptOptions = { + generate: 1, + userMessage: '', + systemPrompt: '', + systemPromptPath: '', +}; + +const parseTemplate = (template: string, options: PromptOptions): string => { + return template.replace(/{(\w+)}/g, (_, key) => { + return ( + options[key as keyof PromptOptions]?.toString() || (DEFAULT_PROMPT_OPTIONS[key as keyof PromptOptions]?.toString() as string) + ); + }); +}; + +const defaultPrompt = (promptOptions: PromptOptions) => { + // TODO: add something + const { generate } = promptOptions; + return [].filter(Boolean).join('\n'); +}; + +const finalPrompt = (generate: number): string => { + return [ + `Generate exactly ${generate} response${generate !== 1 ? 's' : ''} based on the user message.`, + `Provide your response as a JSON array containing exactly ${generate} object${generate !== 1 ? 's' : ''}, each with "summary" and "description" keys.`, + `The array must always contain ${generate} element${generate !== 1 ? 's' : ''}, no more and no less.`, + `Example response format: + [ + ${Array(generate) + .fill(null) + .map( + (_, index) => `{ + "summary": "Brief summary of response ${index + 1}", + "description": "Detailed description of response ${index + 1}" + }` + ) + .join(',\n ')} + ]`, + `Ensure that the JSON array always contains exactly ${generate} element${generate !== 1 ? 's' : ''}, even if you need to provide similar or slightly varied responses to meet this requirement.`, + `The "summary" should be a concise overview, while the "description" should provide more detailed information.`, + `The response should be valid JSON that can be parsed without errors.`, + ] + .filter(Boolean) + .join('\n'); +}; + +export const generatePrompt = (promptOptions: PromptOptions) => { + const { systemPromptPath, generate } = promptOptions; + if (!systemPromptPath) { + return `${finalPrompt(generate)}`; + } + + try { + const systemPromptTemplate = fs.readFileSync(path.resolve(systemPromptPath), 'utf-8'); + return `${parseTemplate(systemPromptTemplate, promptOptions)}\n${finalPrompt(generate)}`; + } catch (error) { + return `${finalPrompt(generate)}`; + } +}; diff --git a/src/utils/utils.ts b/src/utils/utils.ts new file mode 100644 index 0000000..f39dc27 --- /dev/null +++ b/src/utils/utils.ts @@ -0,0 +1,56 @@ +import { ReactiveListChoice } from 'inquirer-reactive-list-prompt'; + +export const createAsyncDelay = (duration: number) => { + return new Promise(resolve => setTimeout(() => resolve(), duration)); +}; + +export const capitalizeFirstLetter = (text: string) => (text ? `${text[0].toUpperCase()}${text.slice(1)}` : text); + +export const getRandomNumber = (min: number, max: number): number => { + const minValue = Math.ceil(min); + const maxValue = Math.floor(max); + return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue; +}; + +export async function* toObservable(promiseAsyncGenerator: Promise>): AsyncGenerator { + const asyncGenerator = await promiseAsyncGenerator; + for await (const value of asyncGenerator) { + yield value; + } +} + +export const truncateString = (str: string, maxLength: number) => { + if (str.length > maxLength) { + return str.slice(0, maxLength); + } else { + return str; + } +}; + +export const sortByDisabled = (a: ReactiveListChoice, b: ReactiveListChoice) => { + if (a.disabled && !b.disabled) { + return 1; + } + if (!a.disabled && b.disabled) { + return -1; + } + return 0; +}; + +export const DONE = `done`; +export const UNDONE = `undone`; + +export const removeTextAfterPhrase = (text: string, phrase: string, includePhrase: boolean = false) => { + const index = text.indexOf(phrase); + if (index !== -1) { + const extraIndex = includePhrase ? phrase.length : 0; + return text.slice(0, index + extraIndex).trim(); + } + return text; +}; + +export const flattenArray = (arr: any[]): string[] => { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flattenArray(toFlatten) : toFlatten); + }, []); +}; diff --git a/system-prompt-template.txt b/system-prompt-template.txt new file mode 100644 index 0000000..e0e44a5 --- /dev/null +++ b/system-prompt-template.txt @@ -0,0 +1,3 @@ +You are a Software Development Tutor. +Your mission is to guide users from zero knowledge to understanding the fundamentals of software. +Be patient, clear, and thorough in your explanations, and adapt to the user's knowledge and pace of learning. diff --git a/tests/fixtures/README.md b/tests/fixtures/README.md new file mode 100644 index 0000000..9eaa6f6 --- /dev/null +++ b/tests/fixtures/README.md @@ -0,0 +1,12 @@ +# Generating diffs + +1. Instruct ChatGPT with the following command: + +``` +I want you to act as a git cli +I will give you the type of content and you will generate a random git diff based on that +``` + +2. Insert the type of change + +ChatGPT will generate a fictional git diff based on the type of change you inserted. diff --git a/tests/fixtures/chore.diff b/tests/fixtures/chore.diff new file mode 100644 index 0000000..b0e6066 --- /dev/null +++ b/tests/fixtures/chore.diff @@ -0,0 +1,18 @@ +diff --git a/package.json b/package.json +index 2a7398e..6b2a3f0 100644 +--- a/package.json ++++ b/package.json +@@ -3,7 +3,7 @@ + "version": "1.0.0", + "description": "A sample project", + "main": "index.js", +- "scripts": { ++ "scripts": { + "start": "node index.js", + "test": "mocha", +- "lint": "eslint ." ++ "lint": "eslint .", ++ "clean": "rm -rf node_modules && npm install" + }, + "dependencies": { + "express": "^4.17.1", diff --git a/tests/fixtures/code-refactoring.diff b/tests/fixtures/code-refactoring.diff new file mode 100644 index 0000000..a68736b --- /dev/null +++ b/tests/fixtures/code-refactoring.diff @@ -0,0 +1,34 @@ +diff --git a/old_example.ts b/new_example.ts +index 1234567..abcdefg 100644 +--- a/old_example.ts ++++ b/new_example.ts + +@@ -1,15 +1,16 @@ +-import { Component, OnInit } from '@angular/core'; ++import { Component } from '@angular/core'; + +-@Component({ +- selector: 'app-example', +- templateUrl: './example.component.html', +- styleUrls: ['./example.component.css'] +-}) +-export class ExampleComponent implements OnInit { +- message: string; ++@Component({ ++ selector: 'app-improved-example', ++ templateUrl: './improved-example.component.html', ++ styleUrls: ['./improved-example.component.css'] ++}) ++export class ImprovedExampleComponent { ++ private _message: string; + +- ngOnInit() { +- this.message = 'Hello, world!'; ++ constructor() { ++ this._message = 'Hello, world!'; + } + ++ get message(): string { ++ return this._message; ++ } + } diff --git a/tests/fixtures/code-style.diff b/tests/fixtures/code-style.diff new file mode 100644 index 0000000..6653a1b --- /dev/null +++ b/tests/fixtures/code-style.diff @@ -0,0 +1,28 @@ +diff --git a/src/app.js b/src/app.js +index 8741c37..91b2e74 100644 +--- a/src/app.js ++++ b/src/app.js +@@ -10,12 +10,12 @@ app.use(express.json()); + // Routes + app.get('/', (req, res) => { +- res.send('Welcome to the API!'); ++ res.send('Welcome to the API!'); + }); + + app.post('/users', (req, res) => { +- const user = createUser(req.body); +- res.status(201).send(user); ++ const user = createUser(req.body); ++ res.status(201).send(user); + }); + + app.get('/users/:id', (req, res) => { +@@ -27,7 +27,7 @@ app.get('/users/:id', (req, res) => { + if (user) { + res.send(user); + } else { +- res.status(404).send('User not found'); ++ res.status(404).send('User not found'); + } + }); + diff --git a/tests/fixtures/continous-integration.diff b/tests/fixtures/continous-integration.diff new file mode 100644 index 0000000..6cb3d15 --- /dev/null +++ b/tests/fixtures/continous-integration.diff @@ -0,0 +1,30 @@ +diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml +new file mode 100644 +index 0000000..b6e5789 +--- /dev/null ++++ b/.github/workflows/ci.yml +@@ -0,0 +1,16 @@ ++name: Continuous Integration ++ ++on: ++ push: ++ branches: ++ - main ++ pull_request: ++ branches: ++ - main ++ ++jobs: ++ build-and-test: ++ runs-on: ubuntu-latest ++ steps: ++ - name: Checkout repository ++ uses: actions/checkout@v2 ++ - name: Set up Node.js ++ uses: actions/setup-node@v2 ++ with: ++ node-version: '16' ++ - name: Install dependencies ++ run: npm ci ++ - name: Run tests ++ run: npm test diff --git a/tests/fixtures/deprecate-feature.diff b/tests/fixtures/deprecate-feature.diff new file mode 100644 index 0000000..1fc7d58 --- /dev/null +++ b/tests/fixtures/deprecate-feature.diff @@ -0,0 +1,27 @@ +diff --git a/old_feature.py b/old_feature.py +index 1234567..abcdefg 100644 +--- a/old_feature.py ++++ b/old_feature.py +@@ -1,7 +1,9 @@ + import warnings + + + class OldFeature: ++ def __init__(self): ++ warnings.warn("OldFeature is deprecated and will be removed in the next release. Please use NewFeature instead.", DeprecationWarning) + + def do_something(self): + print("Doing something with the old feature...") +diff --git a/new_feature.py b/new_feature.py +new file mode 100644 +index 0000000..1111111 +--- /dev/null ++++ b/new_feature.py +@@ -0,0 +1,7 @@ ++class NewFeature: ++ def __init__(self): ++ print("Initializing the new feature...") ++ ++ def do_something(self): ++ print("Doing something with the new feature...") ++ diff --git a/tests/fixtures/documentation-changes.diff b/tests/fixtures/documentation-changes.diff new file mode 100644 index 0000000..b9bbff4 --- /dev/null +++ b/tests/fixtures/documentation-changes.diff @@ -0,0 +1,30 @@ +diff --git a/README.md b/README.md +index a0c3e1b..9d1b6f8 100644 +--- a/README.md ++++ b/README.md +@@ -1,6 +1,11 @@ + # My Awesome Project + ++## Overview ++ ++My Awesome Project is a web application that allows users to manage their tasks and projects in a simple and intuitive way. The project is built with React and Node.js and uses MongoDB for data storage. ++ + ## Installation + ++To install and run My Awesome Project, follow these steps: ++ + 1. Clone the repository: `git clone https://github.com/username/my-awesome-project.git` + 2. Install dependencies: `npm install` + 3. Start the development server: `npm start` +@@ -13,6 +18,11 @@ To install and run My Awesome Project, follow these steps: + ## Usage + + To use My Awesome Project, follow these steps: ++ ++1. Open your web browser and navigate to `http://localhost:3000` ++2. Sign up for a new account or log in to an existing one ++3. Create a new task or project and start managing your work! ++ + ## Contributing + + We welcome contributions from anyone and everyone. To contribute to My Awesome Project, follow these steps: diff --git a/tests/fixtures/fix-nullpointer-exception.diff b/tests/fixtures/fix-nullpointer-exception.diff new file mode 100644 index 0000000..c81d7b2 --- /dev/null +++ b/tests/fixtures/fix-nullpointer-exception.diff @@ -0,0 +1,14 @@ +diff --git a/src/main/java/com/example/MyClass.java b/src/main/java/com/example/MyClass.java +index e7d8f38..caab7f1 100644 +--- a/src/main/java/com/example/MyClass.java ++++ b/src/main/java/com/example/MyClass.java +@@ -23,7 +23,10 @@ public class MyClass { + public void processItems(List items) { + for (Item item : items) { +- if (item.getValue().equalsIgnoreCase("example")) { ++ // Fixing NullPointerException by adding a null check ++ String itemValue = item.getValue(); ++ if (itemValue != null && itemValue.equalsIgnoreCase("example")) { + processExampleItem(item); + } + } diff --git a/tests/fixtures/github-action-build-pipeline.diff b/tests/fixtures/github-action-build-pipeline.diff new file mode 100644 index 0000000..7010ee1 --- /dev/null +++ b/tests/fixtures/github-action-build-pipeline.diff @@ -0,0 +1,21 @@ +diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml +index 1d07d31..085eb64 100644 +--- a/.github/workflows/build.yml ++++ b/.github/workflows/build.yml +@@ -10,6 +10,8 @@ jobs: + - uses: actions/setup-node@v1 + with: + node-version: 12.x ++ - name: Install dependencies ++ run: npm install + - name: Build and test + run: | + npm run build +@@ -22,3 +24,7 @@ jobs: + if: always() + uses: actions/upload-artifact@v1 + with: ++ name: Build artifact ++ path: build ++ - name: Deploy to production ++ uses: some-third-party/deploy-action@v1 diff --git a/tests/fixtures/new-feature.diff b/tests/fixtures/new-feature.diff new file mode 100644 index 0000000..3d46df0 --- /dev/null +++ b/tests/fixtures/new-feature.diff @@ -0,0 +1,47 @@ +diff --git a/src/features/newFeature.js b/src/features/newFeature.js +new file mode 100644 +index 0000000..b6e5789 +--- /dev/null ++++ b/src/features/newFeature.js +@@ -0,0 +1,18 @@ ++/** ++ * New feature: Calculates the factorial of a given number. ++ * @param {number} n - The input number. ++ * @returns {number} - The factorial of the input number. ++ */ ++function factorial(n) { ++ if (n === 0 || n === 1) { ++ return 1; ++ } ++ return n * factorial(n - 1); ++} ++ ++module.exports = { ++ factorial, ++}; ++ +diff --git a/src/app.js b/src/app.js +index 8741c37..91b2e74 100644 +--- a/src/app.js ++++ b/src/app.js +@@ -2,6 +2,7 @@ + const express = require('express'); + const bodyParser = require('body-parser'); + const userRoutes = require('./routes/userRoutes'); ++const { factorial } = require('./features/newFeature'); + + const app = express(); + app.use(bodyParser.json()); +@@ -21,6 +22,12 @@ + res.send('Welcome to the API!'); + }); + ++app.get('/factorial/:number', (req, res) => { ++ const number = parseInt(req.params.number, 10); ++ const result = factorial(number); ++ res.send(`Factorial of ${number} is ${result}`); ++}); ++ + // Other routes... + + module.exports = app; diff --git a/tests/fixtures/performance-improvement.diff b/tests/fixtures/performance-improvement.diff new file mode 100644 index 0000000..d1f399f --- /dev/null +++ b/tests/fixtures/performance-improvement.diff @@ -0,0 +1,26 @@ +diff --git a/src/loop.js b/src/loop.js +index 1d45a2b..8c52e81 100644 +--- a/src/loop.js ++++ b/src/loop.js +@@ -5,14 +5,14 @@ const items = generateItems(100000); + function processData(items) { + let sum = 0; + +- for (let i = 0; i < items.length; i++) { +- const item = items[i]; +- if (item.isValid()) { +- sum += item.value; +- } ++ for (const item of items) { ++ if (item.isValid()) sum += item.value; + } + + return sum; + } + + const startTime = Date.now(); +-const result = processData(items); ++const result = processData(items); // Improved loop iteration + const endTime = Date.now(); + + console.log(`Result: ${result}, Time: ${endTime - startTime} ms`); diff --git a/tests/fixtures/remove-feature.diff b/tests/fixtures/remove-feature.diff new file mode 100644 index 0000000..1ee8511 --- /dev/null +++ b/tests/fixtures/remove-feature.diff @@ -0,0 +1,27 @@ +diff --git a/Controllers/FeatureController.cs b/Controllers/FeatureController.cs +index 8a3b7c1..3e29f9a 100644 +--- a/Controllers/FeatureController.cs ++++ b/Controllers/FeatureController.cs +@@ -1,16 +1,7 @@ + using Microsoft.AspNetCore.Mvc; + using System.Collections.Generic; + + namespace MyWebApi.Controllers + { + [Route("api/[controller]")] + [ApiController] + public class FeatureController : ControllerBase + { +- [HttpGet("old-feature")] +- public ActionResult GetOldFeature() +- { +- return "This is the removed old feature."; +- } +- + [HttpGet("new-feature")] + public ActionResult GetNewFeature() + { + return "This is the new feature."; + } + } + } diff --git a/tests/fixtures/testing-react-application.diff b/tests/fixtures/testing-react-application.diff new file mode 100644 index 0000000..79957e7 --- /dev/null +++ b/tests/fixtures/testing-react-application.diff @@ -0,0 +1,22 @@ +diff --git a/src/components/MyComponent.test.js b/src/components/MyComponent.test.js +index 37eabf2..976c6bf 100644 +--- a/src/components/MyComponent.test.js ++++ b/src/components/MyComponent.test.js +@@ -10,6 +10,7 @@ describe("MyComponent", () => { + }); + + it("renders the component correctly", () => { ++ const props = { name: "John Doe", age: 25 }; + const tree = renderer.create().toJSON(); + expect(tree).toMatchSnapshot(); + }); +@@ -25,6 +26,11 @@ describe("MyComponent", () => { + expect(wrapper.find("h1").text()).toEqual("Hello, John Doe!"); + }); + ++ it("displays the correct age", () => { ++ const props = { name: "Jane Doe", age: 30 }; ++ const wrapper = shallow(); ++ expect(wrapper.find("p").text()).toEqual("Age: 30"); ++ }); + }); diff --git a/tests/index.ts b/tests/index.ts new file mode 100644 index 0000000..e46618b --- /dev/null +++ b/tests/index.ts @@ -0,0 +1,8 @@ +import { describe } from 'manten'; + +describe('aipick', ({ runTestSuite }) => { + runTestSuite(import('./specs/cli/index.js')); + runTestSuite(import('./specs/openai/index.js')); + runTestSuite(import('./specs/config.js')); + runTestSuite(import('./specs/git-hook.js')); +}); diff --git a/tests/specs/cli/commits.ts b/tests/specs/cli/commits.ts new file mode 100644 index 0000000..f8080c7 --- /dev/null +++ b/tests/specs/cli/commits.ts @@ -0,0 +1,436 @@ +import { expect, testSuite } from 'manten'; + +import { assertOpenAiToken, createFixture, createGit, files } from '../../utils.js'; + +export default testSuite(({ describe }) => { + if (process.platform === 'win32') { + // https://github.com/nodejs/node/issues/31409 + console.warn('Skipping tests on Windows because Node.js spawn cant open TTYs'); + return; + } + + assertOpenAiToken(); + + describe('Commits', async ({ test, describe }) => { + test('Excludes files', async () => { + const { fixture, aipick } = await createFixture(files); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + const statusBefore = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusBefore.stdout).toBe('A data.json'); + + const { stdout, exitCode } = await aipick(['--exclude', 'data.json'], { reject: false }); + expect(exitCode).toBe(1); + expect(stdout).toMatch('No staged changes found.'); + await fixture.rm(); + }); + + test('Generates commit message', async () => { + const { fixture, aipick } = await createFixture(files); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick(); + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--pretty=format:%s']); + console.log({ + commitMessage, + length: commitMessage.length, + }); + expect(commitMessage.length).toBeLessThanOrEqual(50); + + await fixture.rm(); + }); + + test('Generated commit message must be under 20 characters', async () => { + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\nmax-length=20`, + }); + + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick(); + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const { stdout: commitMessage } = await git('log', ['--pretty=format:%s']); + console.log({ + commitMessage, + length: commitMessage.length, + }); + expect(commitMessage.length).toBeLessThanOrEqual(20); + + await fixture.rm(); + }); + + test('Accepts --all flag, staging all changes before commit', async () => { + const { fixture, aipick } = await createFixture(files); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + await git('commit', ['-m', 'wip']); + + // Change tracked file + await fixture.writeFile('data.json', 'Test'); + + const statusBefore = await git('status', ['--short']); + expect(statusBefore.stdout).toBe(' M data.json\n?? .aipick'); + + const committing = aipick(['--all']); + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--short']); + expect(statusAfter.stdout).toBe('?? .aipick'); + + const { stdout: commitMessage } = await git('log', ['-n1', '--pretty=format:%s']); + console.log({ + commitMessage, + length: commitMessage.length, + }); + expect(commitMessage.length).toBeLessThanOrEqual(50); + + await fixture.rm(); + }); + + test('Accepts --generate flag, overriding config', async ({ onTestFail }) => { + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\ngenerate=4`, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + // Generate flag should override generate config + const committing = aipick(['--generate', '2']); + + // Hit enter to accept the commit message + committing.stdout!.on('data', function onPrompt(buffer: Buffer) { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('\r'); + committing.stdin!.end(); + committing.stdout?.off('data', onPrompt); + } + }); + + const { stdout } = await committing; + const countChoices = stdout.match(/ {2}[●○]/g)?.length ?? 0; + + onTestFail(() => console.log({ stdout })); + expect(countChoices).toBe(2); + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--pretty=format:%s']); + console.log({ + commitMessage, + length: commitMessage.length, + }); + expect(commitMessage.length).toBeLessThanOrEqual(50); + + await fixture.rm(); + }); + + test('Generates Japanese commit message via locale config', async () => { + // https://stackoverflow.com/a/15034560/911407 + const japanesePattern = /[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFF9F\u4E00-\u9FAF\u3400-\u4DBF]/; + + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\nlocale=ja`, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick(); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--pretty=format:%s']); + console.log({ + commitMessage, + length: commitMessage.length, + }); + expect(commitMessage).toMatch(japanesePattern); + expect(commitMessage.length).toBeLessThanOrEqual(50); + + await fixture.rm(); + }); + + describe('commit types', ({ test }) => { + test('Should not use conventional commits by default', async () => { + const conventionalCommitPattern = /(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test):\s/; + const { fixture, aipick } = await createFixture({ + ...files, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick(); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--oneline']); + console.log('Committed with:', commitMessage); + expect(commitMessage).not.toMatch(conventionalCommitPattern); + + await fixture.rm(); + }); + + test('Conventional commits', async () => { + const conventionalCommitPattern = /(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test):\s/; + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\ntype=conventional`, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick(); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--oneline']); + console.log('Committed with:', commitMessage); + expect(commitMessage).toMatch(conventionalCommitPattern); + + await fixture.rm(); + }); + + test('Accepts --type flag, overriding config', async () => { + const conventionalCommitPattern = /(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test):\s/; + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\ntype=other`, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + // Generate flag should override generate config + const committing = aipick(['--type', 'conventional']); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--oneline']); + console.log('Committed with:', commitMessage); + expect(commitMessage).toMatch(conventionalCommitPattern); + + await fixture.rm(); + }); + + test('Accepts empty --type flag', async () => { + const conventionalCommitPattern = /(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test):\s/; + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\ntype=conventional`, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick(['--type', '']); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--oneline']); + console.log('Committed with:', commitMessage); + expect(commitMessage).not.toMatch(conventionalCommitPattern); + + await fixture.rm(); + }); + }); + + describe('proxy', ({ test }) => { + test('Fails on invalid proxy', async () => { + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\nproxy=http://localhost:1234`, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick([], { + reject: false, + }); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + const { stdout, exitCode } = await committing; + + expect(exitCode).toBe(1); + expect(stdout).toMatch('connect ECONNREFUSED'); + + await fixture.rm(); + }); + + test('Connects with config', async () => { + const { fixture, aipick } = await createFixture({ + ...files, + '.aipick': `${files['.aipick']}\nproxy=http://localhost:8888`, + }); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick(); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--pretty=format:%s']); + console.log({ + commitMessage, + length: commitMessage.length, + }); + expect(commitMessage.length).toBeLessThanOrEqual(50); + + await fixture.rm(); + }); + + test('Connects with env variable', async () => { + const { fixture, aipick } = await createFixture(files); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + + const committing = aipick([], { + env: { + HTTP_PROXY: 'http://localhost:8888', + }, + }); + + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--porcelain', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['--pretty=format:%s']); + console.log({ + commitMessage, + length: commitMessage.length, + }); + expect(commitMessage.length).toBeLessThanOrEqual(50); + + await fixture.rm(); + }); + }); + }); +}); diff --git a/tests/specs/cli/error-cases.ts b/tests/specs/cli/error-cases.ts new file mode 100644 index 0000000..f442759 --- /dev/null +++ b/tests/specs/cli/error-cases.ts @@ -0,0 +1,27 @@ +import { expect, testSuite } from 'manten'; + +import { createFixture, createGit } from '../../utils.js'; + +export default testSuite(({ describe }) => { + describe('Error cases', async ({ test }) => { + test('Fails on non-Git project', async () => { + const { fixture, aipick } = await createFixture(); + const { stdout, exitCode } = await aipick([], { reject: false }); + expect(exitCode).toBe(1); + expect(stdout).toMatch('The current directory must be a Git repository!'); + await fixture.rm(); + }); + + test('Fails on no staged files', async () => { + const { fixture, aipick } = await createFixture(); + await createGit(fixture.path); + + const { stdout, exitCode } = await aipick([], { reject: false }); + expect(exitCode).toBe(1); + expect(stdout).toMatch( + 'No staged changes found. Stage your changes manually, or automatically stage all changes with the `--all` flag.' + ); + await fixture.rm(); + }); + }); +}); diff --git a/tests/specs/cli/index.ts b/tests/specs/cli/index.ts new file mode 100644 index 0000000..b3651cd --- /dev/null +++ b/tests/specs/cli/index.ts @@ -0,0 +1,8 @@ +import { testSuite } from 'manten'; + +export default testSuite(({ describe }) => { + describe('CLI', ({ runTestSuite }) => { + runTestSuite(import('./error-cases.js')); + runTestSuite(import('./commits.js')); + }); +}); diff --git a/tests/specs/config.ts b/tests/specs/config.ts new file mode 100644 index 0000000..77bee91 --- /dev/null +++ b/tests/specs/config.ts @@ -0,0 +1,120 @@ +import fs from 'fs/promises'; +import path from 'path'; + +import { expect, testSuite } from 'manten'; + +import { createFixture } from '../utils.js'; + +export default testSuite(({ describe }) => { + describe('config', async ({ test, describe }) => { + const { fixture, aipick } = await createFixture(); + const configPath = path.join(fixture.path, '.aipick'); + const openAiToken = 'OPENAI_KEY=sk-abc'; + + test('set unknown config file', async () => { + const { stderr } = await aipick(['config', 'set', 'UNKNOWN=1'], { + reject: false, + }); + + expect(stderr).toMatch('Invalid config property: UNKNOWN'); + }); + + test('set invalid OPENAI_KEY', async () => { + const { stderr } = await aipick(['config', 'set', 'OPENAI_KEY=abc'], { + reject: false, + }); + + expect(stderr).toMatch('Invalid config property OPENAI_KEY: Must start with "sk-"'); + }); + + await test('set config file', async () => { + await aipick(['config', 'set', openAiToken]); + + const configFile = await fs.readFile(configPath, 'utf8'); + expect(configFile).toMatch(openAiToken); + }); + + await test('get config file', async () => { + const { stdout } = await aipick(['config', 'get', 'OPENAI_KEY']); + expect(stdout).toBe(openAiToken); + }); + + await test('reading unknown config', async () => { + await fs.appendFile(configPath, 'UNKNOWN=1'); + + const { stdout, stderr } = await aipick(['config', 'get', 'UNKNOWN'], { + reject: false, + }); + + expect(stdout).toBe(''); + expect(stderr).toBe(''); + }); + + await describe('timeout', ({ test }) => { + test('setting invalid timeout config', async () => { + const { stderr } = await aipick(['config', 'set', 'timeout=abc'], { + reject: false, + }); + + expect(stderr).toMatch('Must be an integer'); + }); + + test('setting valid timeout config', async () => { + const timeout = 'timeout=20000'; + await aipick(['config', 'set', timeout]); + + const configFile = await fs.readFile(configPath, 'utf8'); + expect(configFile).toMatch(timeout); + + const get = await aipick(['config', 'get', 'timeout']); + expect(get.stdout).toBe(timeout); + }); + }); + + await describe('max-length', ({ test }) => { + test('must be an integer', async () => { + const { stderr } = await aipick(['config', 'set', 'max-length=abc'], { + reject: false, + }); + + expect(stderr).toMatch('Must be an integer'); + }); + + test('must be at least 20 characters', async () => { + const { stderr } = await aipick(['config', 'set', 'max-length=10'], { + reject: false, + }); + + expect(stderr).toMatch(/must be greater than 20 characters/i); + }); + + test('updates config', async () => { + const defaultConfig = await aipick(['config', 'get', 'max-length']); + expect(defaultConfig.stdout).toBe('max-length=50'); + + const maxLength = 'max-length=60'; + await aipick(['config', 'set', maxLength]); + + const configFile = await fs.readFile(configPath, 'utf8'); + expect(configFile).toMatch(maxLength); + + const get = await aipick(['config', 'get', 'max-length']); + expect(get.stdout).toBe(maxLength); + }); + }); + + await test('set config file', async () => { + await aipick(['config', 'set', openAiToken]); + + const configFile = await fs.readFile(configPath, 'utf8'); + expect(configFile).toMatch(openAiToken); + }); + + await test('get config file', async () => { + const { stdout } = await aipick(['config', 'get', 'OPENAI_KEY']); + expect(stdout).toBe(openAiToken); + }); + + await fixture.rm(); + }); +}); diff --git a/tests/specs/git-hook.ts b/tests/specs/git-hook.ts new file mode 100644 index 0000000..3d81172 --- /dev/null +++ b/tests/specs/git-hook.ts @@ -0,0 +1,64 @@ +import path from 'path'; + +import { expect, testSuite } from 'manten'; + +import { assertOpenAiToken, createFixture, createGit, files } from '../utils.js'; + +export default testSuite(({ describe }) => { + describe('Git hook', ({ test }) => { + assertOpenAiToken(); + + test('errors when not in Git repo', async () => { + const { fixture, aipick } = await createFixture(files); + const { exitCode, stderr } = await aipick(['hook', 'install'], { + reject: false, + }); + + expect(exitCode).toBe(1); + expect(stderr).toMatch('The current directory must be a Git repository'); + + await fixture.rm(); + }); + + test('installs from Git repo subdirectory', async () => { + const { fixture, aipick } = await createFixture({ + ...files, + 'some-dir': { + 'file.txt': '', + }, + }); + await createGit(fixture.path); + + const { stdout } = await aipick(['hook', 'install'], { + cwd: path.join(fixture.path, 'some-dir'), + }); + expect(stdout).toMatch('Hook installed'); + + expect(await fixture.exists('.git/hooks/prepare-commit-msg')).toBe(true); + + await fixture.rm(); + }); + + test('Commits', async () => { + const { fixture, aipick } = await createFixture(files); + const git = await createGit(fixture.path); + + const { stdout } = await aipick(['hook', 'install']); + expect(stdout).toMatch('Hook installed'); + + await git('add', ['data.json']); + await git('commit', ['--no-edit'], { + env: { + HOME: fixture.path, + USERPROFILE: fixture.path, + }, + }); + + const { stdout: commitMessage } = await git('log', ['--pretty=%B']); + console.log('Committed with:', commitMessage); + expect(commitMessage.startsWith('# ')).not.toBe(true); + + await fixture.rm(); + }); + }); +}); diff --git a/tests/specs/openai/conventional-commits.ts b/tests/specs/openai/conventional-commits.ts new file mode 100644 index 0000000..61d2439 --- /dev/null +++ b/tests/specs/openai/conventional-commits.ts @@ -0,0 +1,154 @@ +import { expect, testSuite } from 'manten'; + +import { generateMessage } from '../../../src/utils/openai.js'; +import { getDiff } from '../../utils.js'; + +import type { ValidConfig } from '../../../src/utils/config.js'; + +const { OPENAI_KEY } = process.env; + +export default testSuite(({ describe }) => { + if (!OPENAI_KEY) { + console.warn('⚠️ process.env.OPENAI_KEY is necessary to run these tests. Skipping...'); + return; + } + + describe('Conventional Commits', async ({ test }) => { + await test('Should not translate conventional commit type to Japanase when locale config is set to japanese', async () => { + const japaneseConventionalCommitPattern = + /(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.*\))?: [\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFF9F\u4E00-\u9FAF\u3400-\u4DBF]/; + + const gitDiff = await getDiff('new-feature.diff'); + + const commitMessage = await runGenerateCommitMessage(gitDiff, { + locale: 'ja', + }); + + expect(commitMessage).toMatch(japaneseConventionalCommitPattern); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "feat:" conventional commit when change relate to adding a new feature', async () => { + const gitDiff = await getDiff('new-feature.diff'); + + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "feat:" or "feat():" + expect(commitMessage).toMatch(/(feat(\(.*\))?):/); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "refactor:" conventional commit when change relate to code refactoring', async () => { + const gitDiff = await getDiff('code-refactoring.diff'); + + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "refactor:" or "refactor():" + expect(commitMessage).toMatch(/(refactor(\(.*\))?):/); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "test:" conventional commit when change relate to testing a React application', async () => { + const gitDiff = await getDiff('testing-react-application.diff'); + + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "test:" or "test():" + expect(commitMessage).toMatch(/(test(\(.*\))?):/); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "build:" conventional commit when change relate to github action build pipeline', async () => { + const gitDiff = await getDiff('github-action-build-pipeline.diff'); + + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "build:" or "build():" + expect(commitMessage).toMatch(/((build|ci)(\(.*\))?):/); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "(ci|build):" conventional commit when change relate to continious integration', async () => { + const gitDiff = await getDiff('continous-integration.diff'); + + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "ci:" or "ci(): + // It also sometimes generates build and feat + expect(commitMessage).toMatch(/((ci|build|feat)(\(.*\))?):/); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "docs:" conventional commit when change relate to documentation changes', async () => { + const gitDiff = await getDiff('documentation-changes.diff'); + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "docs:" or "docs():" + expect(commitMessage).toMatch(/(docs(\(.*\))?):/); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "fix:" conventional commit when change relate to fixing code', async () => { + const gitDiff = await getDiff('fix-nullpointer-exception.diff'); + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "fix:" or "fix():" + // Sometimes it generates refactor + expect(commitMessage).toMatch(/((fix|refactor)(\(.*\))?):/); + console.log('Generated message:', commitMessage); + }); + + await test('Should use "style:" conventional commit when change relate to code style improvements', async () => { + const gitDiff = await getDiff('code-style.diff'); + const commitMessage = await runGenerateCommitMessage(gitDiff); + + // should match "style:" or "style(