securedblink 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. securedblink-0.5.0/.github/workflows/ci.yml +56 -0
  2. securedblink-0.5.0/.github/workflows/release.yml +212 -0
  3. securedblink-0.5.0/.gitignore +249 -0
  4. securedblink-0.5.0/.python-version +1 -0
  5. securedblink-0.5.0/CHANGELOG.md +4 -0
  6. securedblink-0.5.0/CODE_OF_CONDUCT.md +133 -0
  7. securedblink-0.5.0/CONTRIBUTING.md +156 -0
  8. securedblink-0.5.0/LICENSE +674 -0
  9. securedblink-0.5.0/PKG-INFO +359 -0
  10. securedblink-0.5.0/README.md +314 -0
  11. securedblink-0.5.0/RELEASE.md +219 -0
  12. securedblink-0.5.0/SECURITY.md +110 -0
  13. securedblink-0.5.0/SETUP_RELEASE.md +322 -0
  14. securedblink-0.5.0/cliff.toml +46 -0
  15. securedblink-0.5.0/install.ps1 +22 -0
  16. securedblink-0.5.0/install.sh +47 -0
  17. securedblink-0.5.0/pyproject.toml +139 -0
  18. securedblink-0.5.0/run.sh +233 -0
  19. securedblink-0.5.0/securedblink/__init__.py +7 -0
  20. securedblink-0.5.0/securedblink/classifier.py +52 -0
  21. securedblink-0.5.0/securedblink/connections.py +154 -0
  22. securedblink-0.5.0/securedblink/log.py +73 -0
  23. securedblink-0.5.0/securedblink/py.typed +0 -0
  24. securedblink-0.5.0/securedblink/server.py +645 -0
  25. securedblink-0.5.0/securedblink/vault/__init__.py +74 -0
  26. securedblink-0.5.0/securedblink/vault/parsers.py +343 -0
  27. securedblink-0.5.0/securedblink/vault/pathguard.py +145 -0
  28. securedblink-0.5.0/securedblink/vault/redact.py +129 -0
  29. securedblink-0.5.0/securedblink/vault/resolver.py +152 -0
  30. securedblink-0.5.0/securedblink/vault/store.py +416 -0
  31. securedblink-0.5.0/tests/conftest.py +72 -0
  32. securedblink-0.5.0/tests/test_classifier.py +121 -0
  33. securedblink-0.5.0/tests/test_cli.py +186 -0
  34. securedblink-0.5.0/tests/test_connections.py +96 -0
  35. securedblink-0.5.0/tests/test_resolver.py +84 -0
  36. securedblink-0.5.0/tests/test_server.py +452 -0
  37. securedblink-0.5.0/tests/test_vault.py +831 -0
  38. securedblink-0.5.0/uv.lock +1636 -0
@@ -0,0 +1,56 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ name: Lint & type-check
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Install uv
17
+ uses: astral-sh/setup-uv@v5
18
+ with:
19
+ enable-cache: true
20
+
21
+ - name: Set up Python
22
+ run: uv python install
23
+
24
+ - name: Install dependencies
25
+ run: uv sync --all-extras --group dev
26
+
27
+ - name: Ruff lint
28
+ run: uv run ruff check .
29
+
30
+ - name: Ruff format check
31
+ run: uv run ruff format --check .
32
+
33
+ - name: Mypy
34
+ run: uv run mypy securedblink/
35
+
36
+ test:
37
+ name: Test (Python ${{ matrix.python-version }})
38
+ runs-on: ubuntu-latest
39
+ strategy:
40
+ fail-fast: false
41
+ matrix:
42
+ python-version: ["3.12", "3.13", "3.14"]
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+
46
+ - name: Install uv
47
+ uses: astral-sh/setup-uv@v5
48
+ with:
49
+ enable-cache: true
50
+ python-version: ${{ matrix.python-version }}
51
+
52
+ - name: Install dependencies
53
+ run: uv sync --all-extras --group test
54
+
55
+ - name: Run tests
56
+ run: uv run pytest --cov --cov-report=xml -v
@@ -0,0 +1,212 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ permissions:
9
+ contents: write # needed to create releases and upload assets
10
+ id-token: write # needed for PyPI OIDC publishing
11
+
12
+ jobs:
13
+ # ── 1. Generate changelog ─────────────────────────────────────────────────
14
+ changelog:
15
+ name: Generate changelog
16
+ runs-on: ubuntu-latest
17
+ outputs:
18
+ release_body: ${{ steps.cliff.outputs.content }}
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ with:
22
+ fetch-depth: 0 # full history required by git-cliff
23
+
24
+ - name: Generate release notes with git-cliff
25
+ id: cliff
26
+ uses: orhun/git-cliff-action@v4
27
+ with:
28
+ config: cliff.toml
29
+ args: --latest --strip header
30
+ env:
31
+ OUTPUT: CHANGES.md
32
+ GITHUB_REPO: ${{ github.repository }}
33
+
34
+ # ── 2. Build standalone binaries (PyInstaller) ────────────────────────────
35
+ build-binaries:
36
+ name: Build binary (${{ matrix.os }})
37
+ needs: changelog
38
+ runs-on: ${{ matrix.os }}
39
+ strategy:
40
+ fail-fast: false
41
+ matrix:
42
+ include:
43
+ - os: ubuntu-latest
44
+ asset_name: securedblink-linux-x86_64
45
+ artifact_suffix: linux-x86_64
46
+ - os: macos-15-intel # Intel runner — covers x86_64 Mac users
47
+ asset_name: securedblink-macos-x86_64
48
+ artifact_suffix: macos-x86_64
49
+ - os: macos-latest # Apple Silicon (M-series)
50
+ asset_name: securedblink-macos-aarch64
51
+ artifact_suffix: macos-aarch64
52
+ - os: windows-latest
53
+ asset_name: securedblink-windows-x86_64.exe
54
+ artifact_suffix: windows-x86_64
55
+ steps:
56
+ - uses: actions/checkout@v4
57
+
58
+ - name: Install uv
59
+ uses: astral-sh/setup-uv@v5
60
+ with:
61
+ enable-cache: true
62
+
63
+ - name: Update version to match tag
64
+ shell: bash
65
+ run: |
66
+ TAG_VERSION="${GITHUB_REF_NAME#v}"
67
+ sed -i.bak "s/^version = \".*\"/version = \"${TAG_VERSION}\"/" pyproject.toml
68
+ rm -f pyproject.toml.bak
69
+ uv lock
70
+
71
+ - name: Install project + PyInstaller
72
+ # --frozen ensures CI uses the committed uv.lock exactly — no silent dep drift
73
+ run: uv sync --frozen --all-extras
74
+
75
+ - name: Build binary (Linux)
76
+ if: runner.os == 'Linux'
77
+ run: |
78
+ uv run pyinstaller \
79
+ --onefile \
80
+ --name "${{ matrix.asset_name }}" \
81
+ --hidden-import mcp.cli \
82
+ --hidden-import psycopg2 \
83
+ --hidden-import sqlalchemy.dialects.postgresql \
84
+ --hidden-import keyring.backends.Linux \
85
+ --hidden-import keyring.backends.secretstorage \
86
+ securedblink/server.py
87
+
88
+ - name: Build binary (macOS)
89
+ if: runner.os == 'macOS'
90
+ run: |
91
+ uv run pyinstaller \
92
+ --onefile \
93
+ --name "${{ matrix.asset_name }}" \
94
+ --hidden-import mcp.cli \
95
+ --hidden-import psycopg2 \
96
+ --hidden-import sqlalchemy.dialects.postgresql \
97
+ --hidden-import keyring.backends.macOS \
98
+ securedblink/server.py
99
+
100
+ - name: Build binary (Windows)
101
+ if: runner.os == 'Windows'
102
+ shell: pwsh
103
+ run: |
104
+ uv run pyinstaller `
105
+ --onefile `
106
+ --name "${{ matrix.asset_name }}" `
107
+ --hidden-import mcp.cli `
108
+ --hidden-import psycopg2 `
109
+ --hidden-import sqlalchemy.dialects.postgresql `
110
+ --hidden-import keyring.backends.Windows `
111
+ securedblink/server.py
112
+
113
+ - name: Upload binary artifact
114
+ uses: actions/upload-artifact@v4
115
+ with:
116
+ name: binary-${{ matrix.artifact_suffix }}
117
+ path: dist/${{ matrix.asset_name }}*
118
+ retention-days: 1
119
+
120
+ # ── 3. Build Python distribution (wheel + sdist) ─────────────────────────
121
+ build-python:
122
+ name: Build Python package
123
+ needs: changelog
124
+ runs-on: ubuntu-latest
125
+ steps:
126
+ - uses: actions/checkout@v4
127
+
128
+ - name: Install uv
129
+ uses: astral-sh/setup-uv@v5
130
+ with:
131
+ enable-cache: true
132
+
133
+ - name: Update version to match tag
134
+ shell: bash
135
+ run: |
136
+ TAG_VERSION="${GITHUB_REF_NAME#v}"
137
+ sed -i.bak "s/^version = \".*\"/version = \"${TAG_VERSION}\"/" pyproject.toml
138
+ rm -f pyproject.toml.bak
139
+ uv lock
140
+
141
+ - name: Build wheel and source distribution
142
+ shell: bash
143
+ run: |
144
+ uv build
145
+
146
+ - name: Validate Python artifacts
147
+ shell: bash
148
+ run: |
149
+ test -f dist/*.whl
150
+ test -f dist/*.tar.gz
151
+ uvx --from check-wheel-contents check-wheel-contents dist/*.whl
152
+ WHEEL=$(ls dist/*.whl)
153
+ uv run --isolated --no-project --with "${WHEEL}" python -c \
154
+ "import securedblink; from importlib.metadata import version; assert version('securedblink') == '${GITHUB_REF_NAME#v}'"
155
+
156
+ - name: Upload dist artifacts
157
+ uses: actions/upload-artifact@v4
158
+ with:
159
+ name: python-dist
160
+ path: dist/
161
+ retention-days: 1
162
+
163
+ # ── 4. Create GitHub Release ──────────────────────────────────────────────
164
+ create-release:
165
+ name: Create GitHub Release
166
+ needs: [changelog, build-binaries, build-python]
167
+ runs-on: ubuntu-latest
168
+ steps:
169
+ - uses: actions/checkout@v4
170
+
171
+ - name: Download all artifacts
172
+ uses: actions/download-artifact@v4
173
+ with:
174
+ path: release-assets/
175
+ merge-multiple: true
176
+
177
+ - name: Create release and upload assets
178
+ uses: softprops/action-gh-release@v2
179
+ with:
180
+ tag_name: ${{ github.ref_name }}
181
+ name: "${{ github.ref_name }}"
182
+ body: ${{ needs.changelog.outputs.release_body }}
183
+ draft: false
184
+ prerelease: ${{ contains(github.ref_name, '-rc') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-alpha') }}
185
+ files: release-assets/**/*
186
+ env:
187
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
188
+
189
+ # ── 5. Publish to PyPI ────────────────────────────────────────────────────
190
+ publish-pypi:
191
+ name: Publish to PyPI
192
+ needs: [create-release]
193
+ runs-on: ubuntu-latest
194
+ environment:
195
+ name: pypi
196
+ url: https://pypi.org/project/securedblink/
197
+ steps:
198
+ - uses: actions/checkout@v4
199
+
200
+ - name: Download Python distribution artifacts
201
+ uses: actions/download-artifact@v4
202
+ with:
203
+ name: python-dist
204
+ path: dist/
205
+
206
+ - name: Install uv
207
+ uses: astral-sh/setup-uv@v5
208
+ with:
209
+ enable-cache: true
210
+
211
+ - name: Publish to PyPI (OIDC — no token needed)
212
+ run: uv publish --trusted-publishing always
@@ -0,0 +1,249 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,macos,linux
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python,visualstudiocode,macos,linux
3
+
4
+ ### Linux ###
5
+ *~
6
+
7
+ # temporary files which can be created if a process still has a handle open of a deleted file
8
+ .fuse_hidden*
9
+
10
+ # KDE directory preferences
11
+ .directory
12
+
13
+ # Linux trash folder which might appear on any partition or disk
14
+ .Trash-*
15
+
16
+ # .nfs files are created when an open file is removed but is still being accessed
17
+ .nfs*
18
+
19
+ ### macOS ###
20
+ # General
21
+ .DS_Store
22
+ .AppleDouble
23
+ .LSOverride
24
+
25
+ # Icon must end with two \r
26
+ Icon
27
+
28
+
29
+ # Thumbnails
30
+ ._*
31
+
32
+ # Files that might appear in the root of a volume
33
+ .DocumentRevisions-V100
34
+ .fseventsd
35
+ .Spotlight-V100
36
+ .TemporaryItems
37
+ .Trashes
38
+ .VolumeIcon.icns
39
+ .com.apple.timemachine.donotpresent
40
+
41
+ # Directories potentially created on remote AFP share
42
+ .AppleDB
43
+ .AppleDesktop
44
+ Network Trash Folder
45
+ Temporary Items
46
+ .apdisk
47
+
48
+ ### macOS Patch ###
49
+ # iCloud generated files
50
+ *.icloud
51
+
52
+ ### Python ###
53
+ # Byte-compiled / optimized / DLL files
54
+ __pycache__/
55
+ *.py[cod]
56
+ *$py.class
57
+
58
+ # C extensions
59
+ *.so
60
+
61
+ # Distribution / packaging
62
+ .Python
63
+ build/
64
+ develop-eggs/
65
+ dist/
66
+ downloads/
67
+ eggs/
68
+ .eggs/
69
+ lib/
70
+ lib64/
71
+ parts/
72
+ sdist/
73
+ var/
74
+ wheels/
75
+ share/python-wheels/
76
+ *.egg-info/
77
+ .installed.cfg
78
+ *.egg
79
+ MANIFEST
80
+
81
+ # PyInstaller
82
+ # Usually these files are written by a python script from a template
83
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
84
+ *.manifest
85
+ *.spec
86
+
87
+ # Installer logs
88
+ pip-log.txt
89
+ pip-delete-this-directory.txt
90
+
91
+ # Unit test / coverage reports
92
+ htmlcov/
93
+ .tox/
94
+ .nox/
95
+ .coverage
96
+ .coverage.*
97
+ .cache
98
+ nosetests.xml
99
+ coverage.xml
100
+ *.cover
101
+ *.py,cover
102
+ .hypothesis/
103
+ .pytest_cache/
104
+ cover/
105
+
106
+ # Translations
107
+ *.mo
108
+ *.pot
109
+
110
+ # Django stuff:
111
+ *.log
112
+ local_settings.py
113
+ db.sqlite3
114
+ db.sqlite3-journal
115
+
116
+ # Flask stuff:
117
+ instance/
118
+ .webassets-cache
119
+
120
+ # Scrapy stuff:
121
+ .scrapy
122
+
123
+ # Sphinx documentation
124
+ docs/_build/
125
+
126
+ # PyBuilder
127
+ .pybuilder/
128
+ target/
129
+
130
+ # Jupyter Notebook
131
+ .ipynb_checkpoints
132
+
133
+ # IPython
134
+ profile_default/
135
+ ipython_config.py
136
+
137
+ # pyenv
138
+ # For a library or package, you might want to ignore these files since the code is
139
+ # intended to run in multiple environments; otherwise, check them in:
140
+ # .python-version
141
+
142
+ # pipenv
143
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
144
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
145
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
146
+ # install all needed dependencies.
147
+ #Pipfile.lock
148
+
149
+ # poetry
150
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
151
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
152
+ # commonly ignored for libraries.
153
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
154
+ #poetry.lock
155
+
156
+ # pdm
157
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
158
+ #pdm.lock
159
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
160
+ # in version control.
161
+ # https://pdm.fming.dev/#use-with-ide
162
+ .pdm.toml
163
+
164
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
165
+ __pypackages__/
166
+
167
+ # Celery stuff
168
+ celerybeat-schedule
169
+ celerybeat.pid
170
+
171
+ # SageMath parsed files
172
+ *.sage.py
173
+
174
+ # Environments
175
+ .Env
176
+ .venv
177
+ env/
178
+ venv/
179
+ ENV/
180
+ env.bak/
181
+ venv.bak/
182
+
183
+ # Test databases (untracked, created by quick-start; not for version control)
184
+ test.db
185
+
186
+ # Spyder project settings
187
+ .spyderproject
188
+ .spyproject
189
+
190
+ # Rope project settings
191
+ .ropeproject
192
+
193
+ # mkdocs documentation
194
+ /site
195
+
196
+ # mypy
197
+ .mypy_cache/
198
+ .dmypy.json
199
+ dmypy.json
200
+
201
+ # Pyre type checker
202
+ .pyre/
203
+
204
+ # pytype static type analyzer
205
+ .pytype/
206
+
207
+ # Cython debug symbols
208
+ cython_debug/
209
+
210
+ # PyCharm
211
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
212
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
213
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
214
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
215
+ #.idea/
216
+
217
+ ### Python Patch ###
218
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
219
+ poetry.toml
220
+
221
+ # ruff
222
+ .ruff_cache/
223
+
224
+ # LSP config files
225
+ pyrightconfig.json
226
+
227
+ ### VisualStudioCode ###
228
+ .vscode/*
229
+ !.vscode/settings.json
230
+ !.vscode/tasks.json
231
+ !.vscode/launch.json
232
+ !.vscode/extensions.json
233
+ !.vscode/*.code-snippets
234
+
235
+ # Local History for Visual Studio Code
236
+ .history/
237
+
238
+ # Built Visual Studio Code Extensions
239
+ *.vsix
240
+
241
+ ### VisualStudioCode Patch ###
242
+ # Ignore all local history of files
243
+ .history
244
+ .ionide
245
+
246
+ # git-cliff
247
+ CHANGES.md
248
+
249
+ # End of https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,macos,linux
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,4 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ Generated by [git-cliff](https://github.com/orhun/git-cliff).
@@ -0,0 +1,133 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the overall
26
+ community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or advances of
31
+ any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email address,
35
+ without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official e-mail address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement at
63
+ **paulushc@gmail.com**.
64
+
65
+ All complaints will be reviewed and investigated promptly and fairly.
66
+
67
+ All community leaders are obligated to respect the privacy and security of the
68
+ reporter of any incident.
69
+
70
+ ## Enforcement Guidelines
71
+
72
+ Community leaders will follow these Community Impact Guidelines in determining
73
+ the consequences for any action they deem in violation of this Code of Conduct:
74
+
75
+ ### 1. Correction
76
+
77
+ **Community Impact**: Use of inappropriate language or other behavior deemed
78
+ unprofessional or unwelcome in the community.
79
+
80
+ **Consequence**: A private, written warning from community leaders, providing
81
+ clarity around the nature of the violation and an explanation of why the
82
+ behavior was inappropriate. A public apology may be requested.
83
+
84
+ ### 2. Warning
85
+
86
+ **Community Impact**: A violation through a single incident or series of
87
+ actions.
88
+
89
+ **Consequence**: A warning with consequences for continued behavior. No
90
+ interaction with the people involved, including unsolicited interaction with
91
+ those enforcing the Code of Conduct, for a specified period of time. This
92
+ includes avoiding interactions in community spaces as well as external channels
93
+ like social media. Violating these terms may lead to a temporary or permanent
94
+ ban.
95
+
96
+ ### 3. Temporary Ban
97
+
98
+ **Community Impact**: A serious violation of community standards, including
99
+ sustained inappropriate behavior.
100
+
101
+ **Consequence**: A temporary ban from any sort of interaction or public
102
+ communication with the community for a specified period of time. No public or
103
+ private interaction with the people involved, including unsolicited interaction
104
+ with those enforcing the Code of Conduct, is allowed during this period.
105
+ Violating these terms may lead to a permanent ban.
106
+
107
+ ### 4. Permanent Ban
108
+
109
+ **Community Impact**: Demonstrating a pattern of violation of community
110
+ standards, including sustained inappropriate behavior, harassment of an
111
+ individual, or aggression toward or disparagement of classes of individuals.
112
+
113
+ **Consequence**: A permanent ban from any sort of public interaction within the
114
+ community.
115
+
116
+ ## Attribution
117
+
118
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
119
+ version 2.1, available at
120
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
121
+
122
+ Community Impact Guidelines were inspired by
123
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
124
+
125
+ For answers to common questions about this code of conduct, see the FAQ at
126
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
127
+ [https://www.contributor-covenant.org/translations][translations].
128
+
129
+ [homepage]: https://www.contributor-covenant.org
130
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
131
+ [Mozilla CoC]: https://github.com/mozilla/diversity
132
+ [FAQ]: https://www.contributor-covenant.org/faq
133
+ [translations]: https://www.contributor-covenant.org/translations