├── .devcontainer └── devcontainer.json ├── .dockerignore ├── .editorconfig ├── .github ├── actions │ ├── build-api-doc │ │ └── action.yml │ ├── setup-node │ │ └── action.yml │ └── setup-python │ │ └── action.yml ├── dependabot.yml └── workflows │ ├── docker.yml │ ├── release.yml │ ├── ruff.yml │ ├── website-deploy.yml │ └── website-preview.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .prettierignore ├── .prettierrc ├── .yarnrc ├── Dockerfile ├── LICENSE ├── README.md ├── nb_cli ├── __init__.py ├── __main__.py ├── cli │ ├── __init__.py │ ├── commands │ │ ├── __init__.py │ │ ├── adapter.py │ │ ├── driver.py │ │ ├── plugin.py │ │ ├── project.py │ │ └── self.py │ ├── customize.py │ └── utils.py ├── compat.py ├── config │ ├── __init__.py │ ├── model.py │ └── parser.py ├── consts.py ├── exceptions.py ├── extensions.py ├── handlers │ ├── __init__.py │ ├── adapter.py │ ├── data.py │ ├── driver.py │ ├── meta.py │ ├── pip.py │ ├── plugin.py │ ├── process.py │ ├── project.py │ ├── reloader.py │ ├── script.py │ ├── signal.py │ ├── store.py │ └── venv.py ├── i18n.py ├── locale │ └── zh_CN │ │ └── LC_MESSAGES │ │ └── nb-cli.po ├── log │ └── __init__.py ├── py.typed └── template │ ├── adapter │ ├── cookiecutter.json │ └── {{cookiecutter.adapter_slug}} │ │ ├── __init__.{{cookiecutter.py}} │ │ ├── adapter.{{cookiecutter.py}} │ │ ├── bot.{{cookiecutter.py}} │ │ ├── config.{{cookiecutter.py}} │ │ ├── event.{{cookiecutter.py}} │ │ └── message.{{cookiecutter.py}} │ ├── plugin │ ├── cookiecutter.json │ ├── hooks │ │ └── post_gen_project.py │ └── {{cookiecutter.plugin_slug}} │ │ ├── __init__.{{cookiecutter.py}} │ │ ├── config.{{cookiecutter.py}} │ │ └── plugins │ │ └── .gitkeep │ ├── project │ ├── bootstrap │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── pre_gen_project.py │ │ └── {{cookiecutter.computed.project_slug}} │ │ │ ├── .env.prod │ │ │ ├── README.md │ │ │ └── pyproject.toml │ └── simple │ │ ├── cookiecutter.json │ │ ├── hooks │ │ ├── post_gen_project.py │ │ └── pre_gen_project.py │ │ └── {{cookiecutter.computed.project_slug}} │ │ ├── .env │ │ ├── .env.dev │ │ ├── .env.prod │ │ ├── .gitignore │ │ ├── README.md │ │ ├── pyproject.toml │ │ └── {{cookiecutter.custom.source_dir}} │ │ └── plugins │ │ └── .gitkeep │ └── scripts │ ├── meta │ ├── _package_version.py.jinja │ ├── nonebot_version.py.jinja │ ├── pip_version.py.jinja │ └── python_version.py.jinja │ ├── plugin │ └── list_builtin_plugin.py.jinja │ ├── project │ ├── _prepare.py.jinja │ └── run_project.py.jinja │ └── script │ ├── _entrypoint.py.jinja │ ├── list_scripts.py.jinja │ └── run_script.py.jinja ├── package.json ├── pdm.lock ├── pdm_build.py ├── pyproject.toml ├── website ├── babel.config.js ├── docs │ ├── README.md │ ├── api │ │ └── .gitkeep │ └── guide │ │ ├── create-a-project.mdx │ │ ├── installation.md │ │ ├── plugin.md │ │ ├── project-management.mdx │ │ ├── run-bot.mdx │ │ ├── script.md │ │ ├── self-management.mdx │ │ └── shell-completion.md ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src │ ├── components │ │ ├── Hero.tsx │ │ ├── RunCLI.tsx │ │ └── RunPython.tsx │ ├── css │ │ ├── custom.css │ │ └── index.module.css │ ├── pages │ │ └── index.tsx │ ├── scripts │ │ ├── nb_adapter.py │ │ ├── nb_create.py │ │ ├── nb_driver.py │ │ ├── nb_generate.py │ │ ├── nb_plugin.py │ │ ├── nb_run.py │ │ └── nb_self.py │ └── theme │ │ ├── FooterCopyright │ │ └── index.tsx │ │ ├── LayoutProviders │ │ └── index.tsx │ │ ├── PyodideContext.ts │ │ ├── PyodideProvider │ │ └── index.tsx │ │ └── hooks │ │ ├── usePyodide.ts │ │ └── usePyodideContext.ts ├── static │ ├── img │ │ └── favicon.ico │ └── logo.png ├── tailwind.config.js └── tsconfig.json └── yarn.lock /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Default Linux Universal", 3 | "image": "mcr.microsoft.com/devcontainers/universal:2-linux", 4 | "features": { 5 | "ghcr.io/devcontainers-contrib/features/pdm:2": {} 6 | }, 7 | "postCreateCommand": "pdm config venv.in_project true && pdm config venv.with_pip true && pdm sync && pdm run pre-commit install && pdm run compile && yarn install", 8 | "customizations": { 9 | "vscode": { 10 | "settings": { 11 | "python.analysis.diagnosticMode": "workspace", 12 | "python.analysis.typeCheckingMode": "basic", 13 | "[python]": { 14 | "editor.defaultFormatter": "ms-python.black-formatter", 15 | "editor.codeActionsOnSave": { 16 | "source.organizeImports": true 17 | } 18 | }, 19 | "[javascript]": { 20 | "editor.defaultFormatter": "esbenp.prettier-vscode" 21 | }, 22 | "[html]": { 23 | "editor.defaultFormatter": "esbenp.prettier-vscode" 24 | }, 25 | "[typescript]": { 26 | "editor.defaultFormatter": "esbenp.prettier-vscode" 27 | }, 28 | "[javascriptreact]": { 29 | "editor.defaultFormatter": "esbenp.prettier-vscode" 30 | }, 31 | "[typescriptreact]": { 32 | "editor.defaultFormatter": "esbenp.prettier-vscode" 33 | }, 34 | "files.exclude": { 35 | "**/__pycache__": true 36 | }, 37 | "files.watcherExclude": { 38 | "**/target/**": true, 39 | "**/__pycache__": true 40 | } 41 | }, 42 | "extensions": [ 43 | "ms-python.python", 44 | "ms-python.vscode-pylance", 45 | "ms-python.isort", 46 | "ms-python.black-formatter", 47 | "EditorConfig.EditorConfig", 48 | "esbenp.prettier-vscode", 49 | "bradlc.vscode-tailwindcss" 50 | ] 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .devcontainer/ 2 | .github/ 3 | .venv/ 4 | .vscode/ 5 | node_modules/ 6 | website/ 7 | .dockerignore 8 | .editorconfig 9 | .gitignore 10 | .pre-commit-config.yaml 11 | .prettier* 12 | .yarnrc 13 | Dockerfile 14 | LICENSE 15 | package.json 16 | yarn.lock 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | # The JSON files contain newlines inconsistently 13 | [*.json] 14 | insert_final_newline = ignore 15 | 16 | # Minified JavaScript files shouldn't be changed 17 | [**.min.js] 18 | indent_style = ignore 19 | insert_final_newline = ignore 20 | 21 | # Makefiles always use tabs for indentation 22 | [Makefile] 23 | indent_style = tab 24 | 25 | # Batch files use tabs for indentation 26 | [*.bat] 27 | indent_style = tab 28 | 29 | [*.md] 30 | trim_trailing_whitespace = false 31 | 32 | # Matches the exact files either package.json or .travis.yml 33 | [{package.json,.travis.yml}] 34 | indent_size = 2 35 | 36 | [{*.py,*.pyi}] 37 | indent_size = 4 38 | -------------------------------------------------------------------------------- /.github/actions/build-api-doc/action.yml: -------------------------------------------------------------------------------- 1 | name: Build API Doc 2 | description: Build API Doc 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - run: | 8 | pdm run autodoc 9 | yarn prettier 10 | shell: bash 11 | -------------------------------------------------------------------------------- /.github/actions/setup-node/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup Node 2 | description: Setup Node 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - uses: actions/setup-node@v4 8 | with: 9 | node-version: "16" 10 | 11 | - id: yarn-cache-dir-path 12 | run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT 13 | shell: bash 14 | 15 | - uses: actions/cache@v4 16 | with: 17 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} 18 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 19 | 20 | - run: yarn install 21 | shell: bash 22 | -------------------------------------------------------------------------------- /.github/actions/setup-python/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup Python 2 | description: Setup Python 3 | 4 | inputs: 5 | python-version: 6 | description: Python version 7 | required: false 8 | default: "3.10" 9 | 10 | runs: 11 | using: "composite" 12 | steps: 13 | - uses: pdm-project/setup-pdm@v4 14 | name: Setup PDM 15 | with: 16 | python-version: ${{ inputs.python-version }} 17 | architecture: "x64" 18 | cache: true 19 | 20 | - run: pdm sync && pdm run compile 21 | shell: bash 22 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | groups: 8 | actions: 9 | patterns: 10 | - "*" 11 | 12 | - package-ecosystem: github-actions 13 | directory: "/.github/actions/build-api-doc" 14 | schedule: 15 | interval: daily 16 | groups: 17 | actions: 18 | patterns: 19 | - "*" 20 | 21 | - package-ecosystem: github-actions 22 | directory: "/.github/actions/setup-node" 23 | schedule: 24 | interval: daily 25 | groups: 26 | actions: 27 | patterns: 28 | - "*" 29 | 30 | - package-ecosystem: github-actions 31 | directory: "/.github/actions/setup-python" 32 | schedule: 33 | interval: daily 34 | groups: 35 | actions: 36 | patterns: 37 | - "*" 38 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Build Docker Image 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * 0" 6 | workflow_dispatch: 7 | workflow_run: 8 | workflows: ["Release"] 9 | types: 10 | - completed 11 | 12 | env: 13 | LATEST_PYTHON_VERSION: "3.12" 14 | 15 | jobs: 16 | metadata: 17 | runs-on: ubuntu-latest 18 | if: |- 19 | github.event_name != 'workflow_run' || 20 | (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') 21 | permissions: 22 | contents: read 23 | outputs: 24 | LATEST_RELEASE: ${{ steps.workflow.outputs.LATEST_RELEASE || steps.api.outputs.LATEST_RELEASE }} 25 | 26 | steps: 27 | - name: Get latest release from previous workflow 28 | id: workflow 29 | if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' 30 | run: | 31 | tag=${{ github.event.workflow_run.head_branch }} 32 | echo "LATEST_RELEASE=${tag#refs/tags/}" >> $GITHUB_OUTPUT 33 | 34 | - name: Get latest release from api 35 | id: api 36 | if: github.event_name != 'workflow_run' 37 | run: | 38 | gh api repos/${{ github.repository }}/releases/latest | jq -r '.tag_name' | xargs -0 printf "LATEST_RELEASE=%s" >> $GITHUB_OUTPUT 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | 42 | build: 43 | runs-on: ubuntu-latest 44 | needs: metadata 45 | permissions: 46 | contents: read 47 | packages: write 48 | concurrency: 49 | group: ${{ github.workflow }}-${{ needs.metadata.outputs.LATEST_RELEASE }}-${{ matrix.python_version }}${{ matrix.python_variant }}-${{ matrix.platform }} 50 | cancel-in-progress: true 51 | strategy: 52 | fail-fast: true 53 | matrix: 54 | python_version: 55 | - "3.9" 56 | - "3.10" 57 | - "3.11" 58 | - "3.12" 59 | python_variant: 60 | - "" 61 | - "-slim" 62 | platform: 63 | - linux/amd64 64 | - linux/arm64 65 | 66 | steps: 67 | - name: Checkout 68 | uses: actions/checkout@v4 69 | with: 70 | ref: ${{ needs.metadata.outputs.LATEST_RELEASE }} 71 | 72 | - name: Set up QEMU 73 | uses: docker/setup-qemu-action@v3 74 | 75 | - name: Setup Docker 76 | uses: docker/setup-buildx-action@v3 77 | 78 | - name: Login to DockerHub 79 | uses: docker/login-action@v3 80 | with: 81 | username: ${{ secrets.DOCKERHUB_USERNAME }} 82 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 83 | 84 | - name: Generate Image Name and Scope 85 | id: image 86 | run: | 87 | echo "IMAGE=${GITHUB_REPOSITORY@L}" >> $GITHUB_OUTPUT 88 | echo "SCOPE=${{ hashFiles('**/pdm.lock') }}-${{ matrix.python_version }}${{ matrix.python_variant }}-${{ matrix.platform }}" >> $GITHUB_OUTPUT 89 | platform="${{ matrix.platform }}" 90 | echo "ARTIFACT=${{ matrix.python_version }}${{ matrix.python_variant }}-${platform/\//-}-digests" >> $GITHUB_OUTPUT 91 | 92 | - name: Generate Labels 93 | uses: docker/metadata-action@v5 94 | id: metadata 95 | with: 96 | images: ${{ steps.image.outputs.IMAGE }} 97 | 98 | - name: Build and Publish 99 | uses: docker/build-push-action@v6 100 | id: build 101 | with: 102 | context: . 103 | platforms: ${{ matrix.platform }} 104 | pull: true 105 | build-args: | 106 | PYTHON_IMAGE=${{ matrix.python_version }} 107 | VARIANT=${{ matrix.python_variant }} 108 | labels: ${{ steps.metadata.outputs.labels }} 109 | cache-from: type=gha,scope=${{ steps.image.outputs.SCOPE }} 110 | cache-to: type=gha,scope=${{ steps.image.outputs.SCOPE }},mode=max 111 | outputs: type=image,name=${{ steps.image.outputs.IMAGE }},push-by-digest=true,name-canonical=true,push=true 112 | 113 | - name: Export digest 114 | run: | 115 | mkdir -p /tmp/digests/ 116 | digest="${{ steps.build.outputs.digest }}" 117 | touch "/tmp/digests/${digest#sha256:}" 118 | 119 | - name: Upload digest 120 | uses: actions/upload-artifact@v4 121 | with: 122 | name: ${{ steps.image.outputs.ARTIFACT }} 123 | path: /tmp/digests/* 124 | if-no-files-found: error 125 | retention-days: 1 126 | 127 | push: 128 | runs-on: ubuntu-latest 129 | needs: [metadata, build] 130 | strategy: 131 | matrix: 132 | python_version: 133 | - "3.9" 134 | - "3.10" 135 | - "3.11" 136 | python_variant: 137 | - "" 138 | - "-slim" 139 | 140 | steps: 141 | - name: Checkout 142 | uses: actions/checkout@v4 143 | with: 144 | ref: ${{ needs.metadata.outputs.LATEST_RELEASE }} 145 | 146 | - name: Download digests 147 | uses: actions/download-artifact@v4 148 | with: 149 | path: /tmp/artifacts 150 | pattern: "*-digests" 151 | 152 | - name: Copy digests 153 | run: | 154 | mkdir -p /tmp/digests 155 | cp /tmp/artifacts/${{ matrix.python_version }}${{ matrix.python_variant }}-*-digests/* /tmp/digests 156 | 157 | - name: Set up Docker Buildx 158 | uses: docker/setup-buildx-action@v3 159 | 160 | - name: Login to DockerHub 161 | uses: docker/login-action@v3 162 | with: 163 | username: ${{ secrets.DOCKERHUB_USERNAME }} 164 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 165 | 166 | - name: Generate Image Name 167 | id: image 168 | run: | 169 | echo "IMAGE=${GITHUB_REPOSITORY@L}" >> $GITHUB_OUTPUT 170 | 171 | - name: Generate Tags 172 | uses: docker/metadata-action@v5 173 | id: metadata 174 | with: 175 | context: git 176 | images: | 177 | ${{ github.repository }} 178 | flavor: | 179 | suffix=-py${{ matrix.python_version }}${{ matrix.python_variant }},onlatest=true 180 | tags: | 181 | type=semver,pattern={{version}} 182 | type=semver,pattern={{major}}.{{minor}} 183 | type=semver,pattern={{major}} 184 | 185 | - name: Create manifest list and push 186 | working-directory: /tmp/digests 187 | run: | 188 | docker buildx imagetools create --dry-run $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ 189 | $(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *) 190 | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ 191 | $(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *) 192 | 193 | - name: Generate Tags 194 | uses: docker/metadata-action@v5 195 | id: metadata-latest 196 | if: matrix.python_version == env.LATEST_PYTHON_VERSION 197 | with: 198 | context: git 199 | images: | 200 | ${{ github.repository }} 201 | flavor: | 202 | suffix=${{ matrix.python_variant }},onlatest=true 203 | tags: | 204 | type=semver,pattern={{version}} 205 | type=semver,pattern={{major}}.{{minor}} 206 | type=semver,pattern={{major}} 207 | 208 | - name: Create manifest list and push for latest python version 209 | if: matrix.python_version == env.LATEST_PYTHON_VERSION 210 | working-directory: /tmp/digests 211 | run: | 212 | docker buildx imagetools create --dry-run $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ 213 | $(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *) 214 | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ 215 | $(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *) 216 | 217 | - name: Docker Hub Description 218 | uses: peter-evans/dockerhub-description@v4 219 | with: 220 | username: ${{ secrets.DOCKERHUB_USERNAME }} 221 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 222 | short-description: ${{ github.event.repository.description }} 223 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | id-token: write 13 | contents: write 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Setup Python environment 18 | uses: ./.github/actions/setup-python 19 | 20 | - name: Get Version 21 | id: version 22 | run: | 23 | echo "VERSION=$(pdm show --version)" >> $GITHUB_OUTPUT 24 | echo "TAG_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT 25 | echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT 26 | 27 | - name: Check Version 28 | if: steps.version.outputs.VERSION != steps.version.outputs.TAG_VERSION 29 | run: exit 1 30 | 31 | - name: Build and Publish Package 32 | run: | 33 | pdm publish 34 | gh release upload --clobber ${{ steps.version.outputs.TAG_NAME }} dist/*.tar.gz dist/*.whl 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | -------------------------------------------------------------------------------- /.github/workflows/ruff.yml: -------------------------------------------------------------------------------- 1 | name: Ruff Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | ruff: 11 | name: Ruff Lint 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | 16 | - name: Run Ruff Lint 17 | uses: chartboost/ruff-action@v1 18 | -------------------------------------------------------------------------------- /.github/workflows/website-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Site Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | concurrency: 12 | group: website-deploy-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Setup Python Environment 19 | uses: ./.github/actions/setup-python 20 | 21 | - name: Setup Node Environment 22 | uses: ./.github/actions/setup-node 23 | 24 | - name: Build API Doc 25 | uses: ./.github/actions/build-api-doc 26 | 27 | - name: Build Doc 28 | run: yarn build 29 | 30 | - name: Get Branch Name 31 | run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_ENV 32 | 33 | - name: Deploy to Netlify 34 | uses: nwtgck/actions-netlify@v3 35 | with: 36 | publish-dir: "./website/build" 37 | production-deploy: true 38 | github-token: ${{ secrets.GITHUB_TOKEN }} 39 | deploy-message: "Deploy ${{ env.BRANCH_NAME }}@${{ github.sha }}" 40 | enable-commit-comment: false 41 | alias: ${{ env.BRANCH_NAME }} 42 | env: 43 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 44 | NETLIFY_SITE_ID: ${{ secrets.SITE_ID }} 45 | -------------------------------------------------------------------------------- /.github/workflows/website-preview.yml: -------------------------------------------------------------------------------- 1 | name: Site Deploy(Preview) 2 | 3 | on: 4 | pull_request_target: 5 | 6 | jobs: 7 | preview: 8 | runs-on: ubuntu-latest 9 | concurrency: 10 | group: pull-request-preview-${{ github.event.number }} 11 | cancel-in-progress: true 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | ref: ${{ github.event.pull_request.head.sha }} 17 | 18 | - name: Setup Python Environment 19 | uses: ./.github/actions/setup-python 20 | 21 | - name: Setup Node Environment 22 | uses: ./.github/actions/setup-node 23 | 24 | - name: Build API Doc 25 | uses: ./.github/actions/build-api-doc 26 | 27 | - name: Build Doc 28 | run: yarn build 29 | 30 | - name: Get Deploy Name 31 | run: | 32 | echo "DEPLOY_NAME=deploy-preview-${{ github.event.number }}" >> $GITHUB_ENV 33 | 34 | - name: Deploy to Netlify 35 | uses: nwtgck/actions-netlify@v3 36 | with: 37 | publish-dir: "./website/build" 38 | production-deploy: false 39 | github-token: ${{ secrets.GITHUB_TOKEN }} 40 | deploy-message: "Deploy ${{ env.DEPLOY_NAME }}@${{ github.sha }}" 41 | enable-commit-comment: false 42 | alias: ${{ env.DEPLOY_NAME }} 43 | env: 44 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 45 | NETLIFY_SITE_ID: ${{ secrets.SITE_ID }} 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ----- Project ----- 2 | 3 | .idea 4 | .vscode 5 | dev 6 | docs_build/_build 7 | !tests/.env 8 | .docusaurus 9 | website/docs/api/**/*.md 10 | website/static/packages/*.whl 11 | !nb_cli/project/{{cookiecutter.project_slug}}/.env 12 | 13 | # Created by https://www.toptal.com/developers/gitignore/api/node,macos,linux,python,windows,jetbrains,visualstudiocode 14 | # Edit at https://www.toptal.com/developers/gitignore?templates=node,macos,linux,python,windows,jetbrains,visualstudiocode 15 | 16 | ### JetBrains ### 17 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 18 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 19 | 20 | # User-specific stuff 21 | .idea/**/workspace.xml 22 | .idea/**/tasks.xml 23 | .idea/**/usage.statistics.xml 24 | .idea/**/dictionaries 25 | .idea/**/shelf 26 | 27 | # AWS User-specific 28 | .idea/**/aws.xml 29 | 30 | # Generated files 31 | .idea/**/contentModel.xml 32 | 33 | # Sensitive or high-churn files 34 | .idea/**/dataSources/ 35 | .idea/**/dataSources.ids 36 | .idea/**/dataSources.local.xml 37 | .idea/**/sqlDataSources.xml 38 | .idea/**/dynamic.xml 39 | .idea/**/uiDesigner.xml 40 | .idea/**/dbnavigator.xml 41 | 42 | # Gradle 43 | .idea/**/gradle.xml 44 | .idea/**/libraries 45 | 46 | # Gradle and Maven with auto-import 47 | # When using Gradle or Maven with auto-import, you should exclude module files, 48 | # since they will be recreated, and may cause churn. Uncomment if using 49 | # auto-import. 50 | # .idea/artifacts 51 | # .idea/compiler.xml 52 | # .idea/jarRepositories.xml 53 | # .idea/modules.xml 54 | # .idea/*.iml 55 | # .idea/modules 56 | # *.iml 57 | # *.ipr 58 | 59 | # CMake 60 | cmake-build-*/ 61 | 62 | # Mongo Explorer plugin 63 | .idea/**/mongoSettings.xml 64 | 65 | # File-based project format 66 | *.iws 67 | 68 | # IntelliJ 69 | out/ 70 | 71 | # mpeltonen/sbt-idea plugin 72 | .idea_modules/ 73 | 74 | # JIRA plugin 75 | atlassian-ide-plugin.xml 76 | 77 | # Cursive Clojure plugin 78 | .idea/replstate.xml 79 | 80 | # SonarLint plugin 81 | .idea/sonarlint/ 82 | 83 | # Crashlytics plugin (for Android Studio and IntelliJ) 84 | com_crashlytics_export_strings.xml 85 | crashlytics.properties 86 | crashlytics-build.properties 87 | fabric.properties 88 | 89 | # Editor-based Rest Client 90 | .idea/httpRequests 91 | 92 | # Android studio 3.1+ serialized cache file 93 | .idea/caches/build_file_checksums.ser 94 | 95 | ### JetBrains Patch ### 96 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 97 | 98 | # *.iml 99 | # modules.xml 100 | # .idea/misc.xml 101 | # *.ipr 102 | 103 | # Sonarlint plugin 104 | # https://plugins.jetbrains.com/plugin/7973-sonarlint 105 | .idea/**/sonarlint/ 106 | 107 | # SonarQube Plugin 108 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin 109 | .idea/**/sonarIssues.xml 110 | 111 | # Markdown Navigator plugin 112 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced 113 | .idea/**/markdown-navigator.xml 114 | .idea/**/markdown-navigator-enh.xml 115 | .idea/**/markdown-navigator/ 116 | 117 | # Cache file creation bug 118 | # See https://youtrack.jetbrains.com/issue/JBR-2257 119 | .idea/$CACHE_FILE$ 120 | 121 | # CodeStream plugin 122 | # https://plugins.jetbrains.com/plugin/12206-codestream 123 | .idea/codestream.xml 124 | 125 | # Azure Toolkit for IntelliJ plugin 126 | # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij 127 | .idea/**/azureSettings.xml 128 | 129 | ### Linux ### 130 | *~ 131 | 132 | # temporary files which can be created if a process still has a handle open of a deleted file 133 | .fuse_hidden* 134 | 135 | # KDE directory preferences 136 | .directory 137 | 138 | # Linux trash folder which might appear on any partition or disk 139 | .Trash-* 140 | 141 | # .nfs files are created when an open file is removed but is still being accessed 142 | .nfs* 143 | 144 | ### macOS ### 145 | # General 146 | .DS_Store 147 | .AppleDouble 148 | .LSOverride 149 | 150 | # Icon must end with two \r 151 | Icon 152 | 153 | # Thumbnails 154 | ._* 155 | 156 | # Files that might appear in the root of a volume 157 | .DocumentRevisions-V100 158 | .fseventsd 159 | .Spotlight-V100 160 | .TemporaryItems 161 | .Trashes 162 | .VolumeIcon.icns 163 | .com.apple.timemachine.donotpresent 164 | 165 | # Directories potentially created on remote AFP share 166 | .AppleDB 167 | .AppleDesktop 168 | Network Trash Folder 169 | Temporary Items 170 | .apdisk 171 | 172 | ### macOS Patch ### 173 | # iCloud generated files 174 | *.icloud 175 | 176 | ### Node ### 177 | # Logs 178 | logs 179 | *.log 180 | npm-debug.log* 181 | yarn-debug.log* 182 | yarn-error.log* 183 | lerna-debug.log* 184 | .pnpm-debug.log* 185 | 186 | # Diagnostic reports (https://nodejs.org/api/report.html) 187 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 188 | 189 | # Runtime data 190 | pids 191 | *.pid 192 | *.seed 193 | *.pid.lock 194 | 195 | # Directory for instrumented libs generated by jscoverage/JSCover 196 | lib-cov 197 | 198 | # Coverage directory used by tools like istanbul 199 | coverage 200 | *.lcov 201 | 202 | # nyc test coverage 203 | .nyc_output 204 | 205 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 206 | .grunt 207 | 208 | # Bower dependency directory (https://bower.io/) 209 | bower_components 210 | 211 | # node-waf configuration 212 | .lock-wscript 213 | 214 | # Compiled binary addons (https://nodejs.org/api/addons.html) 215 | build/Release 216 | 217 | # Dependency directories 218 | node_modules/ 219 | jspm_packages/ 220 | 221 | # Snowpack dependency directory (https://snowpack.dev/) 222 | web_modules/ 223 | 224 | # TypeScript cache 225 | *.tsbuildinfo 226 | 227 | # Optional npm cache directory 228 | .npm 229 | 230 | # Optional eslint cache 231 | .eslintcache 232 | 233 | # Optional stylelint cache 234 | .stylelintcache 235 | 236 | # Microbundle cache 237 | .rpt2_cache/ 238 | .rts2_cache_cjs/ 239 | .rts2_cache_es/ 240 | .rts2_cache_umd/ 241 | 242 | # Optional REPL history 243 | .node_repl_history 244 | 245 | # Output of 'npm pack' 246 | *.tgz 247 | 248 | # Yarn Integrity file 249 | .yarn-integrity 250 | 251 | # dotenv environment variable files 252 | .env 253 | .env.development.local 254 | .env.test.local 255 | .env.production.local 256 | .env.local 257 | 258 | # parcel-bundler cache (https://parceljs.org/) 259 | .cache 260 | .parcel-cache 261 | 262 | # Next.js build output 263 | .next 264 | out 265 | 266 | # Nuxt.js build / generate output 267 | .nuxt 268 | dist 269 | 270 | # Gatsby files 271 | .cache/ 272 | # Comment in the public line in if your project uses Gatsby and not Next.js 273 | # https://nextjs.org/blog/next-9-1#public-directory-support 274 | # public 275 | 276 | # vuepress build output 277 | .vuepress/dist 278 | 279 | # vuepress v2.x temp and cache directory 280 | .temp 281 | 282 | # Docusaurus cache and generated files 283 | .docusaurus 284 | 285 | # Serverless directories 286 | .serverless/ 287 | 288 | # FuseBox cache 289 | .fusebox/ 290 | 291 | # DynamoDB Local files 292 | .dynamodb/ 293 | 294 | # TernJS port file 295 | .tern-port 296 | 297 | # Stores VSCode versions used for testing VSCode extensions 298 | .vscode-test 299 | 300 | # yarn v2 301 | .yarn/cache 302 | .yarn/unplugged 303 | .yarn/build-state.yml 304 | .yarn/install-state.gz 305 | .pnp.* 306 | 307 | ### Node Patch ### 308 | # Serverless Webpack directories 309 | .webpack/ 310 | 311 | # Optional stylelint cache 312 | 313 | # SvelteKit build / generate output 314 | .svelte-kit 315 | 316 | ### Python ### 317 | # Byte-compiled / optimized / DLL files 318 | __pycache__/ 319 | *.py[cod] 320 | *$py.class 321 | 322 | # C extensions 323 | *.so 324 | 325 | # Distribution / packaging 326 | .Python 327 | build/ 328 | develop-eggs/ 329 | dist/ 330 | downloads/ 331 | eggs/ 332 | .eggs/ 333 | lib/ 334 | lib64/ 335 | parts/ 336 | sdist/ 337 | var/ 338 | wheels/ 339 | share/python-wheels/ 340 | *.egg-info/ 341 | .installed.cfg 342 | *.egg 343 | MANIFEST 344 | 345 | # PyInstaller 346 | # Usually these files are written by a python script from a template 347 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 348 | *.manifest 349 | *.spec 350 | 351 | # Installer logs 352 | pip-log.txt 353 | pip-delete-this-directory.txt 354 | 355 | # Unit test / coverage reports 356 | htmlcov/ 357 | .tox/ 358 | .nox/ 359 | .coverage 360 | .coverage.* 361 | nosetests.xml 362 | coverage.xml 363 | *.cover 364 | *.py,cover 365 | .hypothesis/ 366 | .pytest_cache/ 367 | cover/ 368 | 369 | # Translations 370 | *.mo 371 | *.pot 372 | 373 | # Django stuff: 374 | local_settings.py 375 | db.sqlite3 376 | db.sqlite3-journal 377 | 378 | # Flask stuff: 379 | instance/ 380 | .webassets-cache 381 | 382 | # Scrapy stuff: 383 | .scrapy 384 | 385 | # Sphinx documentation 386 | docs/_build/ 387 | 388 | # PyBuilder 389 | .pybuilder/ 390 | target/ 391 | 392 | # Jupyter Notebook 393 | .ipynb_checkpoints 394 | 395 | # IPython 396 | profile_default/ 397 | ipython_config.py 398 | 399 | # pyenv 400 | # For a library or package, you might want to ignore these files since the code is 401 | # intended to run in multiple environments; otherwise, check them in: 402 | # .python-version 403 | 404 | # pipenv 405 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 406 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 407 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 408 | # install all needed dependencies. 409 | #Pipfile.lock 410 | 411 | # poetry 412 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 413 | # This is especially recommended for binary packages to ensure reproducibility, and is more 414 | # commonly ignored for libraries. 415 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 416 | #poetry.lock 417 | 418 | # pdm 419 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 420 | #pdm.lock 421 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 422 | # in version control. 423 | # https://pdm.fming.dev/#use-with-ide 424 | .pdm.toml 425 | pdm.toml 426 | .pdm-python 427 | 428 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 429 | __pypackages__/ 430 | 431 | # Celery stuff 432 | celerybeat-schedule 433 | celerybeat.pid 434 | 435 | # SageMath parsed files 436 | *.sage.py 437 | 438 | # Environments 439 | .venv 440 | env/ 441 | venv/ 442 | ENV/ 443 | env.bak/ 444 | venv.bak/ 445 | 446 | # Spyder project settings 447 | .spyderproject 448 | .spyproject 449 | 450 | # Rope project settings 451 | .ropeproject 452 | 453 | # mkdocs documentation 454 | /site 455 | 456 | # mypy 457 | .mypy_cache/ 458 | .dmypy.json 459 | dmypy.json 460 | 461 | # Pyre type checker 462 | .pyre/ 463 | 464 | # pytype static type analyzer 465 | .pytype/ 466 | 467 | # Cython debug symbols 468 | cython_debug/ 469 | 470 | # PyCharm 471 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 472 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 473 | # and can be added to the global gitignore or merged into this file. For a more nuclear 474 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 475 | #.idea/ 476 | 477 | ### Python Patch ### 478 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration 479 | poetry.toml 480 | 481 | # ruff 482 | .ruff_cache/ 483 | 484 | # LSP config files 485 | pyrightconfig.json 486 | 487 | ### VisualStudioCode ### 488 | .vscode/* 489 | !.vscode/settings.json 490 | !.vscode/tasks.json 491 | !.vscode/launch.json 492 | !.vscode/extensions.json 493 | !.vscode/*.code-snippets 494 | 495 | # Local History for Visual Studio Code 496 | .history/ 497 | 498 | # Built Visual Studio Code Extensions 499 | *.vsix 500 | 501 | ### VisualStudioCode Patch ### 502 | # Ignore all local history of files 503 | .history 504 | .ionide 505 | 506 | ### Windows ### 507 | # Windows thumbnail cache files 508 | Thumbs.db 509 | Thumbs.db:encryptable 510 | ehthumbs.db 511 | ehthumbs_vista.db 512 | 513 | # Dump file 514 | *.stackdump 515 | 516 | # Folder config file 517 | [Dd]esktop.ini 518 | 519 | # Recycle Bin used on file shares 520 | $RECYCLE.BIN/ 521 | 522 | # Windows Installer files 523 | *.cab 524 | *.msi 525 | *.msix 526 | *.msm 527 | *.msp 528 | 529 | # Windows shortcuts 530 | *.lnk 531 | 532 | # End of https://www.toptal.com/developers/gitignore/api/node,macos,linux,python,windows,jetbrains,visualstudiocode 533 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_install_hook_types: [pre-commit, prepare-commit-msg] 2 | ci: 3 | autofix_commit_msg: ":rotating_light: auto fix by pre-commit hooks" 4 | autofix_prs: true 5 | autoupdate_branch: master 6 | autoupdate_schedule: monthly 7 | autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks" 8 | repos: 9 | - repo: https://github.com/astral-sh/ruff-pre-commit 10 | rev: v0.11.8 11 | hooks: 12 | - id: ruff 13 | args: [--fix, --exit-non-zero-on-fix] 14 | stages: [pre-commit] 15 | 16 | - repo: https://github.com/pycqa/isort 17 | rev: 6.0.1 18 | hooks: 19 | - id: isort 20 | stages: [pre-commit] 21 | 22 | - repo: https://github.com/psf/black 23 | rev: 25.1.0 24 | hooks: 25 | - id: black 26 | stages: [pre-commit] 27 | 28 | - repo: https://github.com/pre-commit/mirrors-prettier 29 | rev: v4.0.0-alpha.8 30 | hooks: 31 | - id: prettier 32 | types_or: [javascript, jsx, ts, tsx, markdown, yaml, json] 33 | stages: [pre-commit] 34 | 35 | - repo: https://github.com/nonebot/nonemoji 36 | rev: v0.1.4 37 | hooks: 38 | - id: nonemoji 39 | stages: [prepare-commit-msg] 40 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .github/**/*.md 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "endOfLine": "lf", 5 | "arrowParens": "always", 6 | "singleQuote": false, 7 | "trailingComma": "es5", 8 | "semi": true, 9 | "overrides": [ 10 | { 11 | "files": [ 12 | "**/devcontainer.json", 13 | "**/tsconfig.json", 14 | "**/tsconfig.*.json" 15 | ], 16 | "options": { 17 | "parser": "json" 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | registry "https://registry.npmjs.org/" 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | ARG PYTHON_IMAGE=3.11 4 | ARG VARIANT= 5 | 6 | # build stage 7 | FROM python:${PYTHON_IMAGE}${VARIANT} AS build-stage 8 | 9 | RUN pip install pipx 10 | 11 | COPY . /project/ 12 | 13 | WORKDIR /project 14 | 15 | RUN mkdir __pypackages__ && \ 16 | python -m pipx run --no-cache pdm sync --prod --no-editable 17 | 18 | # run stage 19 | FROM python:${PYTHON_IMAGE}${VARIANT} 20 | 21 | ARG PYTHON_IMAGE 22 | 23 | ENV PYTHONPATH=/opt/nb-cli/pkgs 24 | 25 | COPY --from=build-stage /project/__pypackages__/${PYTHON_IMAGE}/lib /opt/nb-cli/pkgs 26 | COPY --from=build-stage /project/__pypackages__/${PYTHON_IMAGE}/bin/* /bin/ 27 | 28 | WORKDIR /workspaces 29 | 30 | ENTRYPOINT ["nb"] 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ju4tCode 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
5 | 6 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
44 | 文档 45 | · 46 | 安装 47 | · 48 | NoneBot 文档 49 |
50 | 51 | ## 功能 52 | 53 | - 创建新的 Nonebot 项目 54 | - 启动 Nonebot 55 | - 管理插件 56 | - 创建新的插件 57 | - 搜索/安装/更新/卸载在官方商店上发布的插件 58 | - 管理适配器 59 | - 创建新的适配器 60 | - 搜索/安装/更新/卸载在官方商店上发布的适配器 61 | - 管理驱动器 62 | - 搜索/安装/更新/卸载在官方商店上发布的驱动器 63 | - 支持 CLI 插件和运行脚本 64 | 65 | ## 使用 66 | 67 | 完整使用文档请参考 [文档](https://cli.nonebot.dev/)。 68 | 69 | ### 安装 70 | 71 | 使用 pipx 安装 72 | 73 | ```shell 74 | pipx install nb-cli 75 | ``` 76 | 77 | 使用 Docker 运行 78 | 79 | ```shell 80 | docker pull nonebot/nb-cli:latest 81 | ``` 82 | 83 | Docker 镜像可以选择以下版本: 84 | 85 | - `latest`, `latest-slim`:最新的稳定版本 86 | - `latest-${python版本}`, `latest-${python版本}-slim`:指定 Python 版本的最新稳定版本 87 | - `${cli版本}`, `${cli版本}-slim`:指定 CLI 版本的最新稳定版本 88 | - `${cli版本}-${python版本}`, `${cli版本}-${python版本}-slim`:指定 CLI 和 Python 版本的最新稳定版本 89 | 90 | ### 命令行使用 91 | 92 | ```shell 93 | nb --help 94 | ``` 95 | 96 | > **Warning** 97 | > 98 | > 如果找不到 `nb` 命令,请尝试 `pipx ensurepath` 来添加路径到环境变量 99 | 100 | - `nb create (init)` 创建新的 NoneBot 项目 101 | - `nb run` 在当前目录启动 NoneBot 102 | - `nb generate` 在当前目录生成启动脚本 103 | - `nb driver` 管理驱动器 104 | - `nb plugin` 管理插件 105 | - `nb adapter` 管理适配器 106 | - `nb self` 管理 CLI 内部环境 107 | - `nb