opencode-talk-bridge 0.2.7__tar.gz → 0.3.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.
- opencode_talk_bridge-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +49 -0
- opencode_talk_bridge-0.3.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- opencode_talk_bridge-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +33 -0
- opencode_talk_bridge-0.3.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/CHANGELOG.md +31 -1
- opencode_talk_bridge-0.3.0/CONTRIBUTING.md +101 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/PKG-INFO +38 -10
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/README.md +37 -9
- opencode_talk_bridge-0.3.0/SECURITY.md +51 -0
- opencode_talk_bridge-0.3.0/docs/publishing.md +49 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/pyproject.toml +1 -1
- opencode_talk_bridge-0.3.0/src/opencode_talk_bridge/__init__.py +15 -0
- opencode_talk_bridge-0.3.0/tests/test_version.py +12 -0
- opencode_talk_bridge-0.2.7/docs/publishing.md +0 -58
- opencode_talk_bridge-0.2.7/src/opencode_talk_bridge/__init__.py +0 -8
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/.env.example +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/.github/workflows/ci.yml +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/.github/workflows/publish.yml +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/.gitignore +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/LICENSE +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/deploy/com.leiverkus.opencode-talk-bridge.plist +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/docs/smoke-test.md +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/__main__.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/allowlist.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/bridge.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/commands.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/config.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/events.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/init.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/messages.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/opencode.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/pending.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/permissions.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/scheduler.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/sessions.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/status.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/streaming.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/stt.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/talk.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/tts.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/webdav.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/conftest.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_allowlist.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_bridge.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_commands.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_config.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_events.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_init.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_main.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_messages.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_opencode.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_pending.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_permissions.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_scheduler.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_sessions.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_status.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_streaming.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_talk.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_voice.py +0 -0
- {opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/tests/test_webdav.py +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something doesn't work as expected
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for the report! **Do not paste secrets** — app passwords, tokens,
|
|
9
|
+
or full `.env` contents. For security vulnerabilities use
|
|
10
|
+
[private reporting](../../security/advisories/new) instead (see SECURITY.md).
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: what-happened
|
|
13
|
+
attributes:
|
|
14
|
+
label: What happened?
|
|
15
|
+
description: What did you do, what did you expect, what happened instead?
|
|
16
|
+
placeholder: Steps to reproduce, expected vs actual behaviour.
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: input
|
|
20
|
+
id: bridge-version
|
|
21
|
+
attributes:
|
|
22
|
+
label: opencode-talk-bridge version
|
|
23
|
+
description: "Output of `opencode-talk-bridge --help` header or `pip show opencode-talk-bridge`."
|
|
24
|
+
placeholder: "0.3.0"
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: input
|
|
28
|
+
id: opencode-version
|
|
29
|
+
attributes:
|
|
30
|
+
label: OpenCode version
|
|
31
|
+
description: "`opencode --version`"
|
|
32
|
+
placeholder: "1.15.11"
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
- type: input
|
|
36
|
+
id: environment
|
|
37
|
+
attributes:
|
|
38
|
+
label: OS / Python / Nextcloud
|
|
39
|
+
placeholder: "macOS 15, Python 3.12, Nextcloud 30 / Talk 20"
|
|
40
|
+
validations:
|
|
41
|
+
required: false
|
|
42
|
+
- type: textarea
|
|
43
|
+
id: logs
|
|
44
|
+
attributes:
|
|
45
|
+
label: Relevant logs
|
|
46
|
+
description: "Run with `LOG_LEVEL=DEBUG`. Redact tokens, paths, and message contents you don't want public."
|
|
47
|
+
render: text
|
|
48
|
+
validations:
|
|
49
|
+
required: false
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability
|
|
4
|
+
url: https://github.com/leiverkus/opencode-talk-bridge/security/advisories/new
|
|
5
|
+
about: Report security issues privately — do NOT open a public issue. See SECURITY.md.
|
|
6
|
+
- name: Question / discussion
|
|
7
|
+
url: https://github.com/leiverkus/opencode-talk-bridge/discussions
|
|
8
|
+
about: For usage questions and ideas (if Discussions is enabled).
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an improvement or new capability
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: Problem / motivation
|
|
9
|
+
description: What are you trying to do that's hard or impossible today?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: proposal
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed solution
|
|
16
|
+
description: What would you like to see? A new command, config option, behaviour?
|
|
17
|
+
validations:
|
|
18
|
+
required: false
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: alternatives
|
|
21
|
+
attributes:
|
|
22
|
+
label: Alternatives considered
|
|
23
|
+
validations:
|
|
24
|
+
required: false
|
|
25
|
+
- type: checkboxes
|
|
26
|
+
id: scope
|
|
27
|
+
attributes:
|
|
28
|
+
label: Scope check
|
|
29
|
+
options:
|
|
30
|
+
- label: "This is about the bridge itself (not OpenCode, Nextcloud, or nextcloud-talk-core)."
|
|
31
|
+
required: true
|
|
32
|
+
- label: "It does not weaken the allowlist / permission model (or I've explained why that's safe)."
|
|
33
|
+
required: true
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!-- Thanks for contributing! Keep PRs focused; see CONTRIBUTING.md. -->
|
|
2
|
+
|
|
3
|
+
## What & why
|
|
4
|
+
|
|
5
|
+
<!-- What does this change, and why? Link any issue: Fixes #123 -->
|
|
6
|
+
|
|
7
|
+
## Checklist
|
|
8
|
+
|
|
9
|
+
- [ ] `ruff check src tests` and `ruff format --check src tests` pass
|
|
10
|
+
- [ ] `pytest` passes; new behaviour has tests (both sides mocked, no live calls)
|
|
11
|
+
- [ ] CHANGELOG "Unreleased" updated if user-facing
|
|
12
|
+
- [ ] Docs / `.env.example` updated if config, commands, or behaviour changed
|
|
13
|
+
|
|
14
|
+
## Security model
|
|
15
|
+
|
|
16
|
+
<!-- Required if this touches the allowlist, permission/question flow, or what
|
|
17
|
+
gets posted to Talk. Otherwise write "n/a". -->
|
|
18
|
+
|
|
19
|
+
- [ ] Does not let the bridge act on a message without an allowlist check
|
|
20
|
+
- [ ] Does not post secrets or raw OpenCode/Nextcloud responses into Talk
|
|
@@ -6,6 +6,34 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.3.0] - 2026-06-01
|
|
10
|
+
|
|
11
|
+
v1 candidate — documentation, security, and stability hygiene (no behaviour
|
|
12
|
+
changes). Still `0.x` / Beta until a live smoke test on a real instance.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- `SECURITY.md` — private vulnerability reporting, scope, and response policy.
|
|
16
|
+
- README **Stability** section: the SemVer public contract from `1.0.0` (CLI
|
|
17
|
+
flags, `.env` keys, Talk commands, status JSON, forward-compatible migrations).
|
|
18
|
+
- `CONTRIBUTING.md`: the live smoke test is now a **required gate before a stable
|
|
19
|
+
release**, plus a pre-1.0 checklist (incl. flipping the classifier).
|
|
20
|
+
- Issue forms (`bug_report`, `feature_request`), an issue-template `config`
|
|
21
|
+
routing security reports to private advisories, and a PR template.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `__version__` is derived from package metadata — single source of truth in
|
|
25
|
+
`pyproject.toml` (no second bump in `__init__.py`).
|
|
26
|
+
- Clarified OpenCode compatibility: **tested against 1.15.11**, expected
|
|
27
|
+
compatible with the 1.15+ HTTP API.
|
|
28
|
+
- Refreshed `docs/publishing.md` for the live (post-first-publish) state.
|
|
29
|
+
|
|
30
|
+
## [0.2.8] - 2026-06-01
|
|
31
|
+
|
|
32
|
+
### Docs
|
|
33
|
+
- Republish so the **PyPI project description** reflects the corrected README
|
|
34
|
+
(the `uv tool install opencode-talk-bridge` instructions). The 0.2.7 page was
|
|
35
|
+
built from the README commit just before the PyPI-primary install flip.
|
|
36
|
+
|
|
9
37
|
## [0.2.7] - 2026-06-01
|
|
10
38
|
|
|
11
39
|
First release published to **PyPI** — `uv tool install opencode-talk-bridge`
|
|
@@ -163,7 +191,9 @@ Initial release.
|
|
|
163
191
|
- `nextcloud-talk-core`, pinned to the `core-v1.0.0` git tag.
|
|
164
192
|
- `httpx >= 0.27`.
|
|
165
193
|
|
|
166
|
-
[Unreleased]: https://github.com/leiverkus/opencode-talk-bridge/compare/v0.
|
|
194
|
+
[Unreleased]: https://github.com/leiverkus/opencode-talk-bridge/compare/v0.3.0...HEAD
|
|
195
|
+
[0.3.0]: https://github.com/leiverkus/opencode-talk-bridge/compare/v0.2.8...v0.3.0
|
|
196
|
+
[0.2.8]: https://github.com/leiverkus/opencode-talk-bridge/compare/v0.2.7...v0.2.8
|
|
167
197
|
[0.2.7]: https://github.com/leiverkus/opencode-talk-bridge/compare/v0.2.6...v0.2.7
|
|
168
198
|
[0.2.6]: https://github.com/leiverkus/opencode-talk-bridge/compare/v0.2.5...v0.2.6
|
|
169
199
|
[0.2.5]: https://github.com/leiverkus/opencode-talk-bridge/compare/v0.2.4...v0.2.5
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Contributing & maintaining
|
|
2
|
+
|
|
3
|
+
## Dev setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/leiverkus/opencode-talk-bridge.git
|
|
7
|
+
cd opencode-talk-bridge
|
|
8
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
9
|
+
pip install -e ".[dev]" # editable install + ruff/pytest
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Checks (what CI runs)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
ruff check src tests # lint
|
|
16
|
+
ruff format --check src tests # formatting (drop --check to apply)
|
|
17
|
+
pytest # tests + coverage (pytest-cov)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
All tests mock both sides (Talk via `nextcloud-talk-core`/httpx, OpenCode via
|
|
21
|
+
mocked REST + a fake SSE stream) — **no live calls**. CI runs the matrix on
|
|
22
|
+
Python 3.10–3.13. Please keep new code covered and the suite green.
|
|
23
|
+
|
|
24
|
+
## Layout
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/opencode_talk_bridge/
|
|
28
|
+
__main__.py CLI (--init / --check / run), signals
|
|
29
|
+
config.py env/.env config (mandatory allowlist lives here)
|
|
30
|
+
opencode.py OpenCode HTTP + SSE client
|
|
31
|
+
talk.py Nextcloud Talk gateway (poll/send/edit/share, raw actorId)
|
|
32
|
+
webdav.py WebDAV upload/download for attachments
|
|
33
|
+
bridge.py orchestration: poll loop, SSE dispatch, prompt workers
|
|
34
|
+
pending.py one pending interaction per conversation (perm/question/select)
|
|
35
|
+
streaming.py live message-edit streaming
|
|
36
|
+
events.py typed SSE event classification
|
|
37
|
+
permissions.py / commands.py / sessions.py / status.py / scheduler.py
|
|
38
|
+
stt.py / tts.py voice (optional)
|
|
39
|
+
messages.py i18n catalog (de/en)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Conventions
|
|
43
|
+
|
|
44
|
+
- **Code comments in English.** Ruff line length 110; rules in `pyproject.toml`.
|
|
45
|
+
- The **`ALLOWED_USERS` allowlist is mandatory** — never add a path that lets
|
|
46
|
+
the bridge act on a message without checking `actor_id`/`actor_type`.
|
|
47
|
+
- **Never post raw OpenCode HTTP responses or secrets into Talk.** HTTP errors
|
|
48
|
+
(`OpenCodeError`) get a generic user message; details go to the log only.
|
|
49
|
+
- Verify external API assumptions against a live `opencode serve` (`/doc`
|
|
50
|
+
OpenAPI) rather than guessing — see `docs/smoke-test.md`.
|
|
51
|
+
|
|
52
|
+
## Cutting a release
|
|
53
|
+
|
|
54
|
+
Releases publish to PyPI automatically via Trusted Publishing on a version tag
|
|
55
|
+
(`.github/workflows/publish.yml`). One command set:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# 1. bump the version in ONE place — pyproject.toml -> version = "X.Y.Z".
|
|
59
|
+
# (__version__ is read from the installed metadata; no second edit needed.)
|
|
60
|
+
# 2. move the CHANGELOG "Unreleased" items under "## [X.Y.Z] - <date>" and add
|
|
61
|
+
# the compare links at the bottom.
|
|
62
|
+
# 3. ship it:
|
|
63
|
+
git commit -am "Release X.Y.Z: <summary>"
|
|
64
|
+
git tag -a vX.Y.Z -m "opencode-talk-bridge X.Y.Z"
|
|
65
|
+
git push origin main && git push origin vX.Y.Z # -> publish.yml builds + publishes to PyPI
|
|
66
|
+
gh release create vX.Y.Z --title "vX.Y.Z — <title>" --notes "<notes>"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The publish workflow **guards** that the tag matches `pyproject.toml` and runs
|
|
70
|
+
`twine check`, so a version mismatch fails fast and never reaches PyPI. How
|
|
71
|
+
Trusted Publishing is wired up is documented in
|
|
72
|
+
[`docs/publishing.md`](docs/publishing.md).
|
|
73
|
+
|
|
74
|
+
### Live smoke test (required before a *stable* release)
|
|
75
|
+
|
|
76
|
+
The automated suite is entirely mocked. Before tagging a stable release
|
|
77
|
+
(`1.0.0` or any later non-pre-release), complete
|
|
78
|
+
[`docs/smoke-test.md`](docs/smoke-test.md) against a **real** Nextcloud Talk
|
|
79
|
+
instance + `opencode serve`, and record the OpenCode version you tested. A
|
|
80
|
+
`0.x` or `-rc` release may ship without it, but the install/feature surface it
|
|
81
|
+
exercises (allowlist on real `actorId`, permission flow, streaming) is only
|
|
82
|
+
verifiable live.
|
|
83
|
+
|
|
84
|
+
### Pre-1.0 checklist
|
|
85
|
+
|
|
86
|
+
When promoting to `1.0.0`:
|
|
87
|
+
|
|
88
|
+
1. The live smoke test above has passed on a real instance.
|
|
89
|
+
2. Bump the classifier `Development Status :: 4 - Beta` →
|
|
90
|
+
`5 - Production/Stable` in `pyproject.toml` (do this **only** at `1.0.0`, not
|
|
91
|
+
while still on `0.x`).
|
|
92
|
+
3. Re-read the [Stability](README.md#stability) contract — anything you are not
|
|
93
|
+
prepared to keep stable must change *before* `1.0.0`, not after.
|
|
94
|
+
4. Consider a `1.0.0rc1` (or a final `0.x`) used live for a while first, then
|
|
95
|
+
`1.0.0`.
|
|
96
|
+
|
|
97
|
+
## Reporting
|
|
98
|
+
|
|
99
|
+
Issues and PRs welcome. For anything touching the security model (allowlist,
|
|
100
|
+
permission flow, what gets posted to Talk), please call it out explicitly in the
|
|
101
|
+
PR description.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencode-talk-bridge
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Drive a local OpenCode instance from Nextcloud Talk via polling — a self-hosted chat bridge for a coding agent.
|
|
5
5
|
Project-URL: Homepage, https://github.com/leiverkus/opencode-talk-bridge
|
|
6
6
|
Project-URL: Repository, https://github.com/leiverkus/opencode-talk-bridge
|
|
@@ -32,6 +32,7 @@ Description-Content-Type: text/markdown
|
|
|
32
32
|
# opencode-talk-bridge
|
|
33
33
|
|
|
34
34
|
[](https://github.com/leiverkus/opencode-talk-bridge/actions/workflows/ci.yml)
|
|
35
|
+
[](https://pypi.org/project/opencode-talk-bridge/)
|
|
35
36
|
[](https://github.com/leiverkus/opencode-talk-bridge/releases/latest)
|
|
36
37
|
[](https://github.com/leiverkus/opencode-talk-bridge/blob/main/pyproject.toml)
|
|
37
38
|
[](LICENSE)
|
|
@@ -76,23 +77,23 @@ Nextcloud Talk ──long-poll──▶ bridge ──HTTP──▶ opencode
|
|
|
76
77
|
- Python ≥ 3.10, macOS or Linux.
|
|
77
78
|
- A Nextcloud account with **Talk** and an **app password**
|
|
78
79
|
(Settings → Security → App passwords) — not your login password.
|
|
79
|
-
- A running `opencode serve
|
|
80
|
+
- A running `opencode serve`. **Tested against OpenCode 1.15.11**; expected
|
|
81
|
+
compatible with the OpenCode 1.15+ HTTP API until it changes. Default endpoint
|
|
80
82
|
`http://127.0.0.1:4096`.
|
|
81
83
|
|
|
82
84
|
## Install
|
|
83
85
|
|
|
84
|
-
**One command** — installs the `opencode-talk-bridge` CLI into an
|
|
85
|
-
environment and onto your `PATH` ([uv](https://docs.astral.sh/uv/) or
|
|
86
|
+
**One command** — installs the `opencode-talk-bridge` CLI from PyPI into an
|
|
87
|
+
isolated environment and onto your `PATH` ([uv](https://docs.astral.sh/uv/) or
|
|
86
88
|
[pipx](https://pipx.pypa.io/)):
|
|
87
89
|
|
|
88
90
|
```bash
|
|
89
|
-
uv tool install
|
|
90
|
-
# or: pipx install
|
|
91
|
+
uv tool install opencode-talk-bridge
|
|
92
|
+
# or: pipx install opencode-talk-bridge
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
> [docs/publishing.md](docs/publishing.md).
|
|
95
|
+
For the unreleased latest commit, install from git instead:
|
|
96
|
+
`uv tool install git+https://github.com/leiverkus/opencode-talk-bridge.git`.
|
|
96
97
|
|
|
97
98
|
Then create your config interactively and run:
|
|
98
99
|
|
|
@@ -264,16 +265,43 @@ instance as semi-trusted infrastructure. The trust boundary and mitigations:
|
|
|
264
265
|
- **Local-only OpenCode.** Keep `opencode serve` bound to `127.0.0.1`. If you
|
|
265
266
|
expose it, secure it with `OPENCODE_USERNAME`/`OPENCODE_PASSWORD`.
|
|
266
267
|
|
|
268
|
+
To report a vulnerability, see [SECURITY.md](SECURITY.md) (please don't open a
|
|
269
|
+
public issue).
|
|
270
|
+
|
|
271
|
+
## Stability
|
|
272
|
+
|
|
273
|
+
This project follows [SemVer](https://semver.org/). **From `1.0.0`**, the
|
|
274
|
+
following are the stable public contract — breaking changes to them only happen
|
|
275
|
+
on a major bump:
|
|
276
|
+
|
|
277
|
+
- **CLI:** the `opencode-talk-bridge` command and its flags (`--init`,
|
|
278
|
+
`--check`, `--env-file`).
|
|
279
|
+
- **Configuration:** the documented `.env` keys (see [`.env.example`](.env.example))
|
|
280
|
+
and their meaning.
|
|
281
|
+
- **Talk commands:** the slash-command names (`/new`, `/sessions`, …).
|
|
282
|
+
- **Status file:** the JSON schema and its `state` values.
|
|
283
|
+
- **State store:** SQLite migrations stay forward-compatible — upgrading never
|
|
284
|
+
requires deleting your database.
|
|
285
|
+
|
|
286
|
+
**Not** covered (may change in any release): the Python module/API layout,
|
|
287
|
+
exact wording of bot replies and log lines (the i18n strings), and which
|
|
288
|
+
OpenCode/Nextcloud versions are supported.
|
|
289
|
+
|
|
290
|
+
Pre-`1.0.0` (the current `0.x` line) these may still change between minor
|
|
291
|
+
versions; pin a version you have tested.
|
|
292
|
+
|
|
267
293
|
## Development
|
|
268
294
|
|
|
269
295
|
```bash
|
|
296
|
+
pip install -e ".[dev]"
|
|
270
297
|
ruff check src tests
|
|
271
298
|
ruff format --check src tests
|
|
272
299
|
pytest
|
|
273
300
|
```
|
|
274
301
|
|
|
275
302
|
All tests use mocked HTTP for both Talk and OpenCode — no live calls. CI runs
|
|
276
|
-
the matrix on Python 3.10–3.13.
|
|
303
|
+
the matrix on Python 3.10–3.13. Dev setup, conventions, and the (one-command)
|
|
304
|
+
release process are in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
277
305
|
|
|
278
306
|
## Changelog
|
|
279
307
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# opencode-talk-bridge
|
|
2
2
|
|
|
3
3
|
[](https://github.com/leiverkus/opencode-talk-bridge/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/opencode-talk-bridge/)
|
|
4
5
|
[](https://github.com/leiverkus/opencode-talk-bridge/releases/latest)
|
|
5
6
|
[](https://github.com/leiverkus/opencode-talk-bridge/blob/main/pyproject.toml)
|
|
6
7
|
[](LICENSE)
|
|
@@ -45,23 +46,23 @@ Nextcloud Talk ──long-poll──▶ bridge ──HTTP──▶ opencode
|
|
|
45
46
|
- Python ≥ 3.10, macOS or Linux.
|
|
46
47
|
- A Nextcloud account with **Talk** and an **app password**
|
|
47
48
|
(Settings → Security → App passwords) — not your login password.
|
|
48
|
-
- A running `opencode serve
|
|
49
|
+
- A running `opencode serve`. **Tested against OpenCode 1.15.11**; expected
|
|
50
|
+
compatible with the OpenCode 1.15+ HTTP API until it changes. Default endpoint
|
|
49
51
|
`http://127.0.0.1:4096`.
|
|
50
52
|
|
|
51
53
|
## Install
|
|
52
54
|
|
|
53
|
-
**One command** — installs the `opencode-talk-bridge` CLI into an
|
|
54
|
-
environment and onto your `PATH` ([uv](https://docs.astral.sh/uv/) or
|
|
55
|
+
**One command** — installs the `opencode-talk-bridge` CLI from PyPI into an
|
|
56
|
+
isolated environment and onto your `PATH` ([uv](https://docs.astral.sh/uv/) or
|
|
55
57
|
[pipx](https://pipx.pypa.io/)):
|
|
56
58
|
|
|
57
59
|
```bash
|
|
58
|
-
uv tool install
|
|
59
|
-
# or: pipx install
|
|
60
|
+
uv tool install opencode-talk-bridge
|
|
61
|
+
# or: pipx install opencode-talk-bridge
|
|
60
62
|
```
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
> [docs/publishing.md](docs/publishing.md).
|
|
64
|
+
For the unreleased latest commit, install from git instead:
|
|
65
|
+
`uv tool install git+https://github.com/leiverkus/opencode-talk-bridge.git`.
|
|
65
66
|
|
|
66
67
|
Then create your config interactively and run:
|
|
67
68
|
|
|
@@ -233,16 +234,43 @@ instance as semi-trusted infrastructure. The trust boundary and mitigations:
|
|
|
233
234
|
- **Local-only OpenCode.** Keep `opencode serve` bound to `127.0.0.1`. If you
|
|
234
235
|
expose it, secure it with `OPENCODE_USERNAME`/`OPENCODE_PASSWORD`.
|
|
235
236
|
|
|
237
|
+
To report a vulnerability, see [SECURITY.md](SECURITY.md) (please don't open a
|
|
238
|
+
public issue).
|
|
239
|
+
|
|
240
|
+
## Stability
|
|
241
|
+
|
|
242
|
+
This project follows [SemVer](https://semver.org/). **From `1.0.0`**, the
|
|
243
|
+
following are the stable public contract — breaking changes to them only happen
|
|
244
|
+
on a major bump:
|
|
245
|
+
|
|
246
|
+
- **CLI:** the `opencode-talk-bridge` command and its flags (`--init`,
|
|
247
|
+
`--check`, `--env-file`).
|
|
248
|
+
- **Configuration:** the documented `.env` keys (see [`.env.example`](.env.example))
|
|
249
|
+
and their meaning.
|
|
250
|
+
- **Talk commands:** the slash-command names (`/new`, `/sessions`, …).
|
|
251
|
+
- **Status file:** the JSON schema and its `state` values.
|
|
252
|
+
- **State store:** SQLite migrations stay forward-compatible — upgrading never
|
|
253
|
+
requires deleting your database.
|
|
254
|
+
|
|
255
|
+
**Not** covered (may change in any release): the Python module/API layout,
|
|
256
|
+
exact wording of bot replies and log lines (the i18n strings), and which
|
|
257
|
+
OpenCode/Nextcloud versions are supported.
|
|
258
|
+
|
|
259
|
+
Pre-`1.0.0` (the current `0.x` line) these may still change between minor
|
|
260
|
+
versions; pin a version you have tested.
|
|
261
|
+
|
|
236
262
|
## Development
|
|
237
263
|
|
|
238
264
|
```bash
|
|
265
|
+
pip install -e ".[dev]"
|
|
239
266
|
ruff check src tests
|
|
240
267
|
ruff format --check src tests
|
|
241
268
|
pytest
|
|
242
269
|
```
|
|
243
270
|
|
|
244
271
|
All tests use mocked HTTP for both Talk and OpenCode — no live calls. CI runs
|
|
245
|
-
the matrix on Python 3.10–3.13.
|
|
272
|
+
the matrix on Python 3.10–3.13. Dev setup, conventions, and the (one-command)
|
|
273
|
+
release process are in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
246
274
|
|
|
247
275
|
## Changelog
|
|
248
276
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
`opencode-talk-bridge` runs AI coding-agent actions (file writes, shell commands
|
|
4
|
+
via OpenCode) on your machine, triggered by chat messages in a Nextcloud Talk
|
|
5
|
+
instance you may not administer. Security is therefore a primary concern — see
|
|
6
|
+
the [threat model](README.md#threat-model) for the trust boundary and built-in
|
|
7
|
+
mitigations (mandatory allowlist on stable user id, permission prompts, no secret
|
|
8
|
+
or server-text leakage into chat).
|
|
9
|
+
|
|
10
|
+
## Reporting a vulnerability
|
|
11
|
+
|
|
12
|
+
**Please do not open a public issue for security problems.**
|
|
13
|
+
|
|
14
|
+
Use GitHub's private vulnerability reporting:
|
|
15
|
+
[**Report a vulnerability**](https://github.com/leiverkus/opencode-talk-bridge/security/advisories/new)
|
|
16
|
+
(Security tab → "Report a vulnerability"). This opens a private advisory visible
|
|
17
|
+
only to you and the maintainer.
|
|
18
|
+
|
|
19
|
+
If private reporting is unavailable, open a minimal public issue asking the
|
|
20
|
+
maintainer to open a private channel — **without** technical details.
|
|
21
|
+
|
|
22
|
+
Please include: affected version, a description, reproduction steps, and the
|
|
23
|
+
impact you see. A proof of concept is helpful but not required.
|
|
24
|
+
|
|
25
|
+
## Scope
|
|
26
|
+
|
|
27
|
+
**In scope** — the bridge's own security model:
|
|
28
|
+
- allowlist bypass (acting on a message from a non-allowlisted `actorId`/`actorType`),
|
|
29
|
+
- the permission/question approval flow being skippable or spoofable,
|
|
30
|
+
- leakage of secrets or raw OpenCode/Nextcloud responses into a Talk message,
|
|
31
|
+
- the `.env` / app password handling, the status file, or the SQLite store
|
|
32
|
+
exposing credentials.
|
|
33
|
+
|
|
34
|
+
**Out of scope** — issues in dependencies or the surrounding system:
|
|
35
|
+
- OpenCode itself, Nextcloud / Talk, or `nextcloud-talk-core`,
|
|
36
|
+
- you exposing `opencode serve` on a public interface (keep it on `127.0.0.1`),
|
|
37
|
+
- misconfiguration (e.g. an over-broad `ALLOWED_USERS`, a shared bot account).
|
|
38
|
+
|
|
39
|
+
Report those to the respective upstream projects.
|
|
40
|
+
|
|
41
|
+
## Supported versions
|
|
42
|
+
|
|
43
|
+
This is a young project; only the **latest released version** receives security
|
|
44
|
+
fixes. Pin a version you trust and upgrade promptly when an advisory is published.
|
|
45
|
+
|
|
46
|
+
## Response
|
|
47
|
+
|
|
48
|
+
Best effort by a small maintainer team. Expect an acknowledgement within about a
|
|
49
|
+
week, and a fix or mitigation as soon as practical for confirmed, in-scope
|
|
50
|
+
issues. Fixes ship as a new release with a CHANGELOG entry; credit is given
|
|
51
|
+
unless you prefer otherwise.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Publishing to PyPI
|
|
2
|
+
|
|
3
|
+
Releases publish automatically to [PyPI](https://pypi.org/project/opencode-talk-bridge/)
|
|
4
|
+
by [`.github/workflows/publish.yml`](../.github/workflows/publish.yml) on every
|
|
5
|
+
`vX.Y.Z` tag, using **Trusted Publishing (OIDC)** — no API token is stored in the
|
|
6
|
+
repository.
|
|
7
|
+
|
|
8
|
+
The canonical "how to cut a release" steps live in
|
|
9
|
+
[CONTRIBUTING.md](../CONTRIBUTING.md#cutting-a-release). This file documents how
|
|
10
|
+
the publishing is *wired up*.
|
|
11
|
+
|
|
12
|
+
## How it works
|
|
13
|
+
|
|
14
|
+
On a tag push the workflow:
|
|
15
|
+
|
|
16
|
+
1. **guards** that the tag (`vX.Y.Z`) matches the `pyproject.toml` version —
|
|
17
|
+
fails fast on a mismatch, so nothing wrong reaches PyPI;
|
|
18
|
+
2. builds the sdist + wheel and runs `twine check` (validates the README renders
|
|
19
|
+
on the PyPI page);
|
|
20
|
+
3. publishes via OIDC to the `pypi` GitHub environment — no secrets.
|
|
21
|
+
|
|
22
|
+
`__version__` is read from the installed package metadata, so the version has a
|
|
23
|
+
single source of truth: `pyproject.toml`.
|
|
24
|
+
|
|
25
|
+
## Trusted Publisher configuration (already set up)
|
|
26
|
+
|
|
27
|
+
The PyPI project is configured with a Trusted Publisher pointing at this repo:
|
|
28
|
+
|
|
29
|
+
| Field | Value |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| PyPI Project Name | `opencode-talk-bridge` |
|
|
32
|
+
| Owner | `leiverkus` |
|
|
33
|
+
| Repository name | `opencode-talk-bridge` |
|
|
34
|
+
| Workflow name | `publish.yml` |
|
|
35
|
+
| Environment name | `pypi` |
|
|
36
|
+
|
|
37
|
+
To reconfigure (e.g. transfer ownership), edit it under PyPI → the project →
|
|
38
|
+
*Manage → Publishing*. If you rename the workflow file or the `pypi` environment,
|
|
39
|
+
update this Trusted Publisher to match, or OIDC will reject the publish.
|
|
40
|
+
|
|
41
|
+
(Optional) In GitHub → Settings → Environments, give the `pypi` environment a
|
|
42
|
+
required-reviewer rule so each publish needs a human approval.
|
|
43
|
+
|
|
44
|
+
## Local dry run
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
python -m build
|
|
48
|
+
python -m twine check dist/*
|
|
49
|
+
```
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "opencode-talk-bridge"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Drive a local OpenCode instance from Nextcloud Talk via polling — a self-hosted chat bridge for a coding agent."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""opencode-talk-bridge: drive a local OpenCode instance from Nextcloud Talk.
|
|
2
|
+
|
|
3
|
+
A polling bridge (no webhooks) that forwards allowlisted Talk messages to a
|
|
4
|
+
local `opencode serve` HTTP API and posts the agent's replies back into the
|
|
5
|
+
conversation. See README.md for the threat model and the status-file contract.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from importlib.metadata import PackageNotFoundError
|
|
9
|
+
from importlib.metadata import version as _version
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
# Single source of truth: the version declared in pyproject.toml.
|
|
13
|
+
__version__ = _version("opencode-talk-bridge")
|
|
14
|
+
except PackageNotFoundError: # running from a raw checkout without an install
|
|
15
|
+
__version__ = "0.0.0+unknown"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import version
|
|
4
|
+
|
|
5
|
+
import opencode_talk_bridge
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_version_resolves_from_metadata():
|
|
9
|
+
# __version__ is derived from the installed distribution metadata
|
|
10
|
+
# (single source of truth = pyproject.toml), not a hardcoded literal.
|
|
11
|
+
assert opencode_talk_bridge.__version__ == version("opencode-talk-bridge")
|
|
12
|
+
assert opencode_talk_bridge.__version__ != "0.0.0+unknown" # not the fallback
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Publishing to PyPI
|
|
2
|
-
|
|
3
|
-
Releases are published automatically by
|
|
4
|
-
[`.github/workflows/publish.yml`](../.github/workflows/publish.yml) on every
|
|
5
|
-
`vX.Y.Z` tag, using **PyPI Trusted Publishing (OIDC)** — no API token is stored
|
|
6
|
-
in the repository.
|
|
7
|
-
|
|
8
|
-
## One-time PyPI setup (do this once)
|
|
9
|
-
|
|
10
|
-
Because the project does not exist on PyPI yet, register a **pending publisher**;
|
|
11
|
-
the first tagged build will create the project and publish it.
|
|
12
|
-
|
|
13
|
-
1. Create / sign in to a [PyPI](https://pypi.org/) account.
|
|
14
|
-
2. Go to **Account settings → Publishing →
|
|
15
|
-
[Add a pending publisher](https://pypi.org/manage/account/publishing/)**.
|
|
16
|
-
3. Fill in exactly:
|
|
17
|
-
| Field | Value |
|
|
18
|
-
| --- | --- |
|
|
19
|
-
| PyPI Project Name | `opencode-talk-bridge` |
|
|
20
|
-
| Owner | `leiverkus` |
|
|
21
|
-
| Repository name | `opencode-talk-bridge` |
|
|
22
|
-
| Workflow name | `publish.yml` |
|
|
23
|
-
| Environment name | `pypi` |
|
|
24
|
-
4. Save.
|
|
25
|
-
|
|
26
|
-
(Optional) In GitHub → Settings → Environments, create an environment named
|
|
27
|
-
`pypi` and add a required-reviewer protection rule, so a human approves each
|
|
28
|
-
publish.
|
|
29
|
-
|
|
30
|
-
## Cutting a release
|
|
31
|
-
|
|
32
|
-
Same flow as before — the tag now also triggers the PyPI publish:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
# bump version in pyproject.toml and src/opencode_talk_bridge/__init__.py,
|
|
36
|
-
# update CHANGELOG, commit, then:
|
|
37
|
-
git tag -a vX.Y.Z -m "opencode-talk-bridge X.Y.Z"
|
|
38
|
-
git push origin main && git push origin vX.Y.Z
|
|
39
|
-
gh release create vX.Y.Z --title "…" --notes "…" # GitHub release (separate)
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
On the tag push, the workflow:
|
|
43
|
-
1. **guards** that the tag matches the `pyproject.toml` version (fails fast on a mismatch),
|
|
44
|
-
2. builds the sdist + wheel and runs `twine check`,
|
|
45
|
-
3. publishes to PyPI via OIDC (no secrets).
|
|
46
|
-
|
|
47
|
-
After the **first** successful publish, `uv tool install opencode-talk-bridge`
|
|
48
|
-
(or `pipx install opencode-talk-bridge`) works without a git URL — update the
|
|
49
|
-
README install command accordingly.
|
|
50
|
-
|
|
51
|
-
## Local dry run
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
python -m build
|
|
55
|
-
python -m twine check dist/*
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
`twine check` validates that the README renders on the PyPI page.
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"""opencode-talk-bridge: drive a local OpenCode instance from Nextcloud Talk.
|
|
2
|
-
|
|
3
|
-
A polling bridge (no webhooks) that forwards allowlisted Talk messages to a
|
|
4
|
-
local `opencode serve` HTTP API and posts the agent's replies back into the
|
|
5
|
-
conversation. See README.md for the threat model and the status-file contract.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
__version__ = "0.2.7"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/__main__.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/allowlist.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/bridge.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/commands.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/config.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/events.py
RENAMED
|
File without changes
|
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/messages.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/opencode.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/pending.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/permissions.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/scheduler.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/sessions.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/status.py
RENAMED
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/streaming.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opencode_talk_bridge-0.2.7 → opencode_talk_bridge-0.3.0}/src/opencode_talk_bridge/webdav.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|