talkpipe-agents 0.1.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 (49) hide show
  1. talkpipe_agents-0.1.0/.gitea/default_merge_message/MERGE_TEMPLATE.md +1 -0
  2. talkpipe_agents-0.1.0/.gitea/default_merge_message/SQUASH_TEMPLATE.md +1 -0
  3. talkpipe_agents-0.1.0/.github/ISSUE_TEMPLATE/release-checklist.md +20 -0
  4. talkpipe_agents-0.1.0/.github/SECURITY.md +47 -0
  5. talkpipe_agents-0.1.0/.github/dependabot.yml +38 -0
  6. talkpipe_agents-0.1.0/.github/workflows/ci-cd.yml +372 -0
  7. talkpipe_agents-0.1.0/.gitignore +14 -0
  8. talkpipe_agents-0.1.0/.pre-commit-config.yaml +20 -0
  9. talkpipe_agents-0.1.0/.safety-policy.yml +58 -0
  10. talkpipe_agents-0.1.0/CHANGELOG.md +336 -0
  11. talkpipe_agents-0.1.0/CLAUDE.md +69 -0
  12. talkpipe_agents-0.1.0/COPYRIGHT +3 -0
  13. talkpipe_agents-0.1.0/LICENSE +179 -0
  14. talkpipe_agents-0.1.0/MANIFEST.in +3 -0
  15. talkpipe_agents-0.1.0/PKG-INFO +268 -0
  16. talkpipe_agents-0.1.0/README.md +211 -0
  17. talkpipe_agents-0.1.0/RELEASING.md +134 -0
  18. talkpipe_agents-0.1.0/docs/design.md +116 -0
  19. talkpipe_agents-0.1.0/docs/getting-started.md +162 -0
  20. talkpipe_agents-0.1.0/docs/model-providers.md +131 -0
  21. talkpipe_agents-0.1.0/docs/talkpipe-agents.svg +140 -0
  22. talkpipe_agents-0.1.0/docs/testing.md +102 -0
  23. talkpipe_agents-0.1.0/docs/tools-and-skills.md +557 -0
  24. talkpipe_agents-0.1.0/pyproject.toml +184 -0
  25. talkpipe_agents-0.1.0/setup.cfg +4 -0
  26. talkpipe_agents-0.1.0/src/talkpipe_agents/__init__.py +123 -0
  27. talkpipe_agents-0.1.0/src/talkpipe_agents/_pytest_plugin.py +35 -0
  28. talkpipe_agents-0.1.0/src/talkpipe_agents/chat.py +187 -0
  29. talkpipe_agents-0.1.0/src/talkpipe_agents/common_tools.py +497 -0
  30. talkpipe_agents-0.1.0/src/talkpipe_agents/hooks.py +81 -0
  31. talkpipe_agents-0.1.0/src/talkpipe_agents/models.py +313 -0
  32. talkpipe_agents-0.1.0/src/talkpipe_agents/replies.py +116 -0
  33. talkpipe_agents-0.1.0/src/talkpipe_agents/script_tools.py +99 -0
  34. talkpipe_agents-0.1.0/src/talkpipe_agents/segments.py +201 -0
  35. talkpipe_agents-0.1.0/src/talkpipe_agents/support.py +125 -0
  36. talkpipe_agents-0.1.0/src/talkpipe_agents/testing.py +266 -0
  37. talkpipe_agents-0.1.0/src/talkpipe_agents/tools.py +240 -0
  38. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/PKG-INFO +268 -0
  39. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/SOURCES.txt +47 -0
  40. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/dependency_links.txt +1 -0
  41. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/entry_points.txt +5 -0
  42. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/requires.txt +34 -0
  43. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/scm_file_list.json +44 -0
  44. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/scm_version.json +8 -0
  45. talkpipe_agents-0.1.0/src/talkpipe_agents.egg-info/top_level.txt +1 -0
  46. talkpipe_agents-0.1.0/tests/test_agents.py +1109 -0
  47. talkpipe_agents-0.1.0/tests/test_common_tools.py +434 -0
  48. talkpipe_agents-0.1.0/tests/test_plugin.py +49 -0
  49. talkpipe_agents-0.1.0/tests/test_tools_doc_examples.py +271 -0
@@ -0,0 +1 @@
1
+ Merge branch '${HeadBranch}': ${PullRequestTitle}
@@ -0,0 +1 @@
1
+ ${PullRequestTitle}
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Release Checklist
3
+ about: Steps for doing a new release (see RELEASING.md for detail)
4
+ title: Release vX.Y.Z
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ Assumes the TalkPipe release this depends on is already out and working.
11
+
12
+ - [ ] `main` up to date, CI green, working tree clean
13
+ - [ ] `talkpipe>=…` floor in `pyproject.toml` matches what this release needs (`uv lock` if changed)
14
+ - [ ] CHANGELOG: `## Unreleased` → `## X.Y.Z (YYYY-MM-DD)`, fresh empty section above; merged via MR
15
+ - [ ] Build the wheel and install it into a **new** virtual environment; `chatterlang_script` runs an `llmAgent[...]` step against a real model (Ollama or another configured provider)
16
+ - [ ] Anything found: fix via MR, re-test
17
+ - [ ] Tag the merge commit on `main` (`git tag -a vX.Y.Z -m vX.Y.Z`) and push the tag; advance `stable` for a full release
18
+ - [ ] Push `main`, the tag, and `stable` to GitHub
19
+ - [ ] Publish the release on GitHub (pre-release for alphas/betas/rcs); watch `publish-package` finish
20
+ - [ ] Verify: `pip install talkpipe-agents==X.Y.Z` in a fresh venv, `python -c "import talkpipe_agents; print(talkpipe_agents.__version__)"` prints `X.Y.Z`
@@ -0,0 +1,47 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ Security fixes go into the latest release only.
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | Latest | :white_check_mark: |
10
+
11
+ ## Reporting a Vulnerability
12
+
13
+ If you discover a security vulnerability in talkpipe-agents, please report
14
+ it responsibly:
15
+
16
+ 1. **Do not** open a public GitHub issue for it.
17
+ 2. Email the report to tlbauer@sandia.gov.
18
+ 3. Include a description of the vulnerability, steps to reproduce it, the
19
+ potential impact, and a suggested fix if you have one.
20
+
21
+ A vulnerability in the agent's tool suite (for example a tool that reads
22
+ files or fetches URLs doing more than its documentation says) counts; one in
23
+ [talkpipe](https://github.com/sandialabs/talkpipe) or in
24
+ [Strands Agents](https://github.com/strands-agents/sdk-python) belongs to
25
+ that project.
26
+
27
+ ### What to Expect
28
+
29
+ - **Response**: we aim to acknowledge receipt within 2 business days.
30
+ - **Assessment**: an initial assessment within 5 business days.
31
+ - **Updates**: progress updates every 7 days until resolution.
32
+ - **Disclosure**: public disclosure is coordinated with the reporter once a
33
+ fix is released.
34
+
35
+ ### Security Measures
36
+
37
+ - Dependency scanning with Safety and static analysis with Bandit on every
38
+ CI run, both gating the build.
39
+ - Static code analysis with CodeQL.
40
+ - Automated dependency updates via Dependabot.
41
+ - Declared dependency floors are security minimums: the lowest release of
42
+ each dependency with no known advisory.
43
+
44
+ ### Acknowledgments
45
+
46
+ Researchers who responsibly disclose vulnerabilities are acknowledged in the
47
+ release notes unless they prefer to remain anonymous.
@@ -0,0 +1,38 @@
1
+ version: 2
2
+ updates:
3
+ # Enable version updates for Python dependencies
4
+ - package-ecosystem: "pip"
5
+ directory: "/"
6
+ target-branch: "main"
7
+ schedule:
8
+ interval: "weekly"
9
+ open-pull-requests-limit: 10
10
+ reviewers:
11
+ - "tlbauer2"
12
+ assignees:
13
+ - "tlbauer2"
14
+ commit-message:
15
+ prefix: "deps"
16
+ prefix-development: "dev-deps"
17
+ include: "scope"
18
+
19
+ # Enable version updates for GitHub Actions
20
+ - package-ecosystem: "github-actions"
21
+ directory: "/"
22
+ target-branch: "main"
23
+ schedule:
24
+ interval: "weekly"
25
+ open-pull-requests-limit: 5
26
+ reviewers:
27
+ - "tlbauer2"
28
+ assignees:
29
+ - "tlbauer2"
30
+ commit-message:
31
+ prefix: "ci"
32
+ include: "scope"
33
+ # CodeQL refuses to run when its steps are on different versions, so
34
+ # update all github/codeql-action steps in one PR.
35
+ groups:
36
+ codeql-action:
37
+ patterns:
38
+ - "github/codeql-action*"
@@ -0,0 +1,372 @@
1
+ name: CI/CD Pipeline
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, 'bugfix/**', 'feature/**', 'chore/**' ]
6
+ tags: [ 'v*' ] # a version tag runs the gate and then publish-registry
7
+ pull_request:
8
+ branches: [ main, 'bugfix/**', 'feature/**', 'chore/**' ]
9
+ release:
10
+ types: [ published ]
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ python-version: ['3.11', '3.12', '3.13']
18
+
19
+ steps:
20
+ - uses: actions/checkout@v7
21
+ with:
22
+ fetch-depth: 0 # setuptools_scm derives the version from tags
23
+
24
+ - name: Set up Python ${{ matrix.python-version }}
25
+ uses: actions/setup-python@v7
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+
29
+ - name: Cache pip dependencies
30
+ uses: actions/cache@v6
31
+ with:
32
+ path: ~/.cache/pip
33
+ key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
34
+ restore-keys: |
35
+ ${{ runner.os }}-pip-
36
+
37
+ - name: Install dependencies
38
+ run: |
39
+ # Install into a project venv rather than the interpreter itself. On a
40
+ # self-hosted runner /opt/hostedtoolcache is a volume shared by every
41
+ # job, so installing there leaks packages between repos.
42
+ python -m venv .venv
43
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
44
+ .venv/bin/python -m pip install --upgrade pip
45
+ .venv/bin/pip install -e .[dev]
46
+
47
+ - name: Run tests with coverage
48
+ run: |
49
+ pytest --cov=src --cov-report=xml --cov-report=html
50
+
51
+ - name: Upload coverage to Codecov
52
+ # the action uploads to codecov.io on behalf of a GitHub repo; there is
53
+ # no equivalent when this runs on Gitea
54
+ if: matrix.python-version == '3.11' && github.server_url == 'https://github.com'
55
+ uses: codecov/codecov-action@v7
56
+ with:
57
+ files: ./coverage.xml
58
+ flags: unittests
59
+
60
+ lint:
61
+ # Ruff (lint + format) and mypy gate the build; there is no advisory
62
+ # pass and nothing here may swallow a failure. Local equivalent:
63
+ # `pre-commit run --all-files`, or the three commands below.
64
+ runs-on: ubuntu-latest
65
+
66
+ steps:
67
+ - uses: actions/checkout@v7
68
+ with:
69
+ fetch-depth: 0 # setuptools_scm derives the version from tags
70
+
71
+ - name: Set up Python
72
+ uses: actions/setup-python@v7
73
+ with:
74
+ python-version: '3.11'
75
+
76
+ - name: Install dependencies
77
+ run: |
78
+ # see the note on the test job's install step
79
+ python -m venv .venv
80
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
81
+ .venv/bin/python -m pip install --upgrade pip
82
+ .venv/bin/pip install -e .[dev]
83
+
84
+ - name: Ruff lint
85
+ run: ruff check --output-format=github .
86
+
87
+ - name: Ruff format check
88
+ run: ruff format --check --diff .
89
+
90
+ - name: mypy
91
+ run: mypy
92
+
93
+ package:
94
+ # Build the sdist and wheel the way a release would, then install the
95
+ # wheel into a clean venv and prove it works as a talkpipe plugin.
96
+ # Without this a broken wheel is only discovered by the publish jobs, at
97
+ # release time. Host-neutral: runs unchanged on any Actions-compatible
98
+ # runner.
99
+ runs-on: ubuntu-latest
100
+
101
+ steps:
102
+ - uses: actions/checkout@v7
103
+ with:
104
+ fetch-depth: 0 # setuptools_scm derives the version from tags
105
+
106
+ - name: Set up Python
107
+ uses: actions/setup-python@v7
108
+ with:
109
+ python-version: '3.11'
110
+
111
+ - name: Build sdist and wheel
112
+ run: |
113
+ # see the note on the test job's install step
114
+ python -m venv .venv
115
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
116
+ .venv/bin/python -m pip install --upgrade pip
117
+ .venv/bin/pip install build twine
118
+ .venv/bin/python -m build
119
+ .venv/bin/twine check dist/*
120
+
121
+ - name: Install the wheel into a clean venv and smoke-test it
122
+ run: |
123
+ python -m venv .smoke
124
+ .smoke/bin/python -m pip install --upgrade pip
125
+ # pytest only so the pytest11 entry point (the scripted_model
126
+ # fixture) can be loaded below; it is what imports that module.
127
+ .smoke/bin/pip install dist/*.whl pytest
128
+ # The version metadata must resolve from the installed wheel.
129
+ .smoke/bin/python -c "import talkpipe_agents; print(talkpipe_agents.__version__)"
130
+ # The plugin contract: importing talkpipe alone -- no import of
131
+ # talkpipe_agents -- must register the segments, and every declared
132
+ # entry point must resolve in the installed wheel.
133
+ .smoke/bin/python - <<'PY'
134
+ from importlib.metadata import entry_points
135
+
136
+ import talkpipe # noqa: F401
137
+ from talkpipe.chatterlang import registry
138
+
139
+ for name in ("llmAgent", "scriptTool"):
140
+ if name not in registry.segment_registry.available_names:
141
+ raise SystemExit(f"{name} is not registered after importing talkpipe")
142
+ bad = []
143
+ for group in ("talkpipe.plugins", "pytest11"):
144
+ for ep in entry_points(group=group):
145
+ try:
146
+ ep.load()
147
+ except Exception as exc: # noqa: BLE001
148
+ bad.append(f"{group}:{ep.name} -> {exc!r}")
149
+ if bad:
150
+ raise SystemExit("unresolvable entry points:\n" + "\n".join(bad))
151
+ print("plugin registers and all entry points resolve")
152
+ PY
153
+
154
+ lockfile-check:
155
+ # uv.lock is a development convenience only -- CI installs with pip on
156
+ # purpose (see README, "Development environment"). This job installs
157
+ # nothing from the lock; it only fails when uv.lock has drifted out of
158
+ # sync with pyproject.toml, so the committed lock cannot go stale
159
+ # unnoticed.
160
+ runs-on: ubuntu-latest
161
+
162
+ steps:
163
+ - uses: actions/checkout@v7
164
+ with:
165
+ fetch-depth: 0 # setuptools_scm derives the version from tags
166
+
167
+ - name: Install uv
168
+ uses: astral-sh/setup-uv@v7
169
+
170
+ - name: Check uv.lock is in sync with pyproject.toml
171
+ run: uv lock --check
172
+
173
+ security-scan:
174
+ runs-on: ubuntu-latest
175
+ needs: [test, lint]
176
+ env:
177
+ SAFETY_API_KEY: ${{ secrets.SAFETY_API_KEY }}
178
+
179
+ steps:
180
+ - uses: actions/checkout@v7
181
+ with:
182
+ fetch-depth: 0 # setuptools_scm derives the version from tags
183
+
184
+ - name: Set up Python
185
+ uses: actions/setup-python@v7
186
+ with:
187
+ python-version: '3.11'
188
+
189
+ - name: Install dependencies for security scan
190
+ run: |
191
+ # see the note on the test job's install step
192
+ python -m venv .venv
193
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
194
+ # Safety scans the whole installed environment, including the
195
+ # setuptools that `python -m venv` seeds on Python 3.11, which is not a
196
+ # project dependency and is not touched by upgrading pip. Upgrade it
197
+ # past CVE-2026-59890 (fixed in 83.0.0) so the scan reports only
198
+ # findings the project can act on.
199
+ .venv/bin/python -m pip install --upgrade pip "setuptools>=83"
200
+ # No extras: `dev` also installs the scanners.
201
+ .venv/bin/pip install -e .
202
+ # The scanners get a venv of their own, outside the workspace, so the
203
+ # scan covers what the project installs and not the scanners' own
204
+ # dependencies (safety brings in nltk, which nothing here depends on).
205
+ python -m venv "$RUNNER_TEMP/scan-tools"
206
+ echo "$RUNNER_TEMP/scan-tools/bin" >> "$GITHUB_PATH"
207
+ "$RUNNER_TEMP/scan-tools/bin/python" -m pip install --upgrade pip
208
+ "$RUNNER_TEMP/scan-tools/bin/pip" install bandit safety
209
+
210
+ - name: Run Bandit security scan
211
+ run: |
212
+ bandit -c pyproject.toml -r src/ -f json -o bandit-report.json
213
+ bandit -c pyproject.toml -r src/ -f txt
214
+
215
+ - name: Run Safety dependency scan
216
+ run: |
217
+ if [ -n "${SAFETY_API_KEY:-}" ]; then
218
+ # Authenticated: the commercial database, gated by .safety-policy.yml.
219
+ safety scan --save-as json safety-report.json
220
+ safety scan
221
+ else
222
+ # Gitea withholds every secret from pull_request runs -- it flags AGit
223
+ # merge requests as fork pull requests even when head and base are the
224
+ # same repo. Rather than skip the scan there (silently unscanned) or
225
+ # fail it for lack of auth, fall back to the free database. This still
226
+ # fails the build on a known vulnerability; the data is just staler
227
+ # than the authenticated scan that gates pushes.
228
+ echo "SAFETY_API_KEY unavailable; falling back to 'safety check' (free database)."
229
+ # `check` is the legacy command and the only one that runs without an
230
+ # account. It rejects .safety-policy.yml because that file is v3.0 and
231
+ # only `scan` parses v3, so run it from a directory holding no policy
232
+ # file. Left to itself it scans the venv it runs from, so hand it
233
+ # the project venv's packages instead.
234
+ report="$PWD/safety-report.json"
235
+ workdir="$(mktemp -d)"
236
+ .venv/bin/python -m pip freeze --exclude-editable > "$workdir/installed.txt"
237
+ (cd "$workdir" && safety check --stdin --save-json "$report" < installed.txt)
238
+ fi
239
+
240
+ - name: Upload security scan results
241
+ uses: actions/upload-artifact@v7
242
+ # upload-artifact v4+ refuses to run when the server isn't github.com
243
+ if: always() && github.server_url == 'https://github.com'
244
+ with:
245
+ name: security-reports
246
+ path: |
247
+ bandit-report.json
248
+ safety-report.json
249
+
250
+ codeql-analysis:
251
+ name: CodeQL Analysis
252
+ runs-on: ubuntu-latest
253
+ # needs GitHub's code-scanning API, which Gitea does not implement
254
+ if: github.server_url == 'https://github.com'
255
+ permissions:
256
+ actions: read
257
+ contents: read
258
+ security-events: write
259
+
260
+ strategy:
261
+ fail-fast: false
262
+ matrix:
263
+ language: [ 'python' ]
264
+
265
+ steps:
266
+ - name: Checkout repository
267
+ uses: actions/checkout@v7
268
+ with:
269
+ fetch-depth: 0 # setuptools_scm derives the version from tags
270
+
271
+ - name: Initialize CodeQL
272
+ uses: github/codeql-action/init@v4
273
+ with:
274
+ languages: ${{ matrix.language }}
275
+
276
+ - name: Autobuild
277
+ uses: github/codeql-action/autobuild@v4
278
+
279
+ - name: Perform CodeQL Analysis
280
+ uses: github/codeql-action/analyze@v4
281
+
282
+ publish-registry:
283
+ # Pushing a version tag (vX.Y.Z) to a self-hosted server uploads the
284
+ # sdist and wheel to that server's PyPI package registry, from where
285
+ # `pip install` on the same network can fetch them. The registry URL is
286
+ # derived from the server running the job, so nothing about the host is
287
+ # recorded here.
288
+ #
289
+ # Never runs on github.com: there, publish-package below uploads to PyPI
290
+ # from a published release instead. To stop publishing to the local
291
+ # registry (once consumers install from PyPI), set the repository
292
+ # Actions variable PUBLISH_REGISTRY to `false`; no workflow change needed.
293
+ # `push` only: a release published for the same tag would otherwise run
294
+ # this job a second time and fail on the already-uploaded version.
295
+ runs-on: ubuntu-latest
296
+ needs: [test, lint, package, security-scan]
297
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.server_url != 'https://github.com' && vars.PUBLISH_REGISTRY != 'false'
298
+
299
+ steps:
300
+ - uses: actions/checkout@v7
301
+ with:
302
+ fetch-depth: 0 # setuptools_scm derives the version from tags
303
+
304
+ - name: Set up Python
305
+ uses: actions/setup-python@v7
306
+ with:
307
+ python-version: '3.11'
308
+
309
+ - name: Build sdist and wheel
310
+ run: |
311
+ # see the note on the test job's install step
312
+ python -m venv .venv
313
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
314
+ .venv/bin/python -m pip install --upgrade pip
315
+ .venv/bin/pip install build twine
316
+ .venv/bin/python -m build
317
+ .venv/bin/twine check dist/*
318
+ # The built version must be the tag's: anything else (a .devN or
319
+ # +dirty version) means the checkout is not the tagged commit.
320
+ ls dist/*-"${GITHUB_REF_NAME#v}".tar.gz
321
+
322
+ - name: Upload to the package registry
323
+ env:
324
+ TWINE_REPOSITORY_URL: ${{ github.server_url }}/api/packages/${{ github.repository_owner }}/pypi
325
+ TWINE_USERNAME: ${{ github.repository_owner }}
326
+ # The job's own token can read packages but not write them, so this
327
+ # is an access token with package write permission, stored as an
328
+ # Actions secret (owner-level, inherited by every repository).
329
+ TWINE_PASSWORD: ${{ secrets.PUBLISH_TOKEN }}
330
+ run: |
331
+ if [ -z "${TWINE_PASSWORD:-}" ]; then
332
+ echo "::error::PUBLISH_TOKEN secret is not set; nothing was uploaded."
333
+ exit 1
334
+ fi
335
+ twine upload dist/*
336
+
337
+ publish-package:
338
+ runs-on: ubuntu-latest
339
+ needs: [test, lint, package, security-scan]
340
+ # Publishes to PyPI with the PYPI_API_TOKEN repository secret, which
341
+ # exists only on GitHub: a release cut on a self-hosted server must not
342
+ # try to upload (publish-registry serves that side). Version tags only:
343
+ # a release under any other tag would upload a distribution whose
344
+ # setuptools_scm version came from a tag that is not one.
345
+ if: github.event_name == 'release' && github.event.action == 'published' && startsWith(github.event.release.tag_name, 'v') && github.server_url == 'https://github.com'
346
+
347
+ steps:
348
+ - uses: actions/checkout@v7
349
+ with:
350
+ fetch-depth: 0 # setuptools_scm derives the version from tags
351
+
352
+ - name: Set up Python
353
+ uses: actions/setup-python@v7
354
+ with:
355
+ python-version: '3.11'
356
+
357
+ - name: Install build dependencies
358
+ run: |
359
+ python -m pip install --upgrade pip
360
+ pip install build twine
361
+
362
+ - name: Build package
363
+ run: python -m build
364
+
365
+ - name: Check package
366
+ run: twine check dist/*
367
+
368
+ - name: Publish to PyPI
369
+ env:
370
+ TWINE_USERNAME: __token__
371
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
372
+ run: twine upload dist/*
@@ -0,0 +1,14 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ .pytest_cache/
6
+ build/
7
+ dist/
8
+ .coverage
9
+ coverage.xml
10
+ htmlcov/
11
+ .mypy_cache/
12
+ bandit-report.json
13
+ safety-report.json
14
+ .ruff_cache/
@@ -0,0 +1,20 @@
1
+ # Opt-in desktop hooks mirroring the CI lint job: `pre-commit install` once
2
+ # per clone; `pre-commit run --all-files` reproduces the gate locally.
3
+ repos:
4
+ - repo: https://github.com/astral-sh/ruff-pre-commit
5
+ rev: v0.17.0 # keep in step with the ruff pin in pyproject.toml
6
+ hooks:
7
+ - id: ruff-check
8
+ args: [--fix, --show-fixes]
9
+ - id: ruff-format
10
+ - repo: local
11
+ hooks:
12
+ - id: mypy
13
+ name: mypy
14
+ # The project venv's mypy (so versions match uv.lock): install and
15
+ # run pre-commit from inside it -- `uv run pre-commit ...` or an
16
+ # activated .venv -- so `mypy` resolves on PATH.
17
+ entry: mypy
18
+ language: system
19
+ types: [python]
20
+ pass_filenames: false
@@ -0,0 +1,58 @@
1
+ version: '3.0'
2
+
3
+ scanning-settings:
4
+ max-depth: 6
5
+ exclude: []
6
+ include-files: []
7
+ system:
8
+ targets: []
9
+
10
+
11
+ report:
12
+ dependency-vulnerabilities:
13
+ enabled: true
14
+ auto-ignore-in-report:
15
+ python:
16
+ # Both are deliberately false: findings against the installed
17
+ # environment and against unpinned declared requirements must show up
18
+ # in the report and fail the scan. Do not flip these back to true to
19
+ # get a red build green -- fix the requirement instead.
20
+ environment-results: false
21
+ unpinned-requirements: false
22
+ cvss-severity: []
23
+
24
+
25
+ fail-scan-with-exit-code:
26
+ dependency-vulnerabilities:
27
+ enabled: true
28
+ fail-on-any-of:
29
+ cvss-severity:
30
+ - high
31
+ - medium
32
+ - critical
33
+ exploitability:
34
+ - high
35
+ - medium
36
+ - critical
37
+
38
+ security-updates:
39
+ dependency-vulnerabilities:
40
+ auto-security-updates-limit:
41
+ - patch
42
+
43
+ installation:
44
+ default-action: allow
45
+ audit-logging:
46
+ enabled: true
47
+ allow:
48
+ packages: []
49
+ vulnerabilities: {}
50
+ deny:
51
+ packages: {}
52
+ vulnerabilities:
53
+ warning-on-any-of:
54
+ cvss-severity: []
55
+ block-on-any-of:
56
+ cvss-severity: []
57
+
58
+