diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 2a3b8250..7d924a89 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ blank_issues_enabled: false contact_links: - name: Security vulnerability - url: https://github.com/RichardAtCT/claude-code-telegram/security/advisories/new + url: https://github.com/overwirehq/claude-code-telegram/security/advisories/new about: Report a vulnerability privately. Please do not open a public issue for security problems. - name: v2 roadmap - url: https://github.com/RichardAtCT/claude-code-telegram/blob/main/docs/ROADMAP-v2.md + url: https://github.com/overwirehq/claude-code-telegram/blob/main/docs/ROADMAP-v2.md about: Check whether your idea is already planned before opening a feature request. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index fa00adce..e97a6d64 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -5,7 +5,7 @@ body: - type: markdown attributes: value: | - Before filing, check the [v2 roadmap](https://github.com/RichardAtCT/claude-code-telegram/blob/main/docs/ROADMAP-v2.md) and the open pull requests. If it is already planned, comment on that item instead so effort is not duplicated. + Before filing, check the [v2 roadmap](https://github.com/overwirehq/claude-code-telegram/blob/main/docs/ROADMAP-v2.md) and the open pull requests. If it is already planned, comment on that item instead so effort is not duplicated. - type: textarea id: problem attributes: diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml index c5176a46..9f6b0d1b 100644 --- a/.github/ISSUE_TEMPLATE/question.yml +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -5,7 +5,7 @@ body: - type: markdown attributes: value: | - Check [docs/setup.md](https://github.com/RichardAtCT/claude-code-telegram/blob/main/docs/setup.md) and [docs/configuration.md](https://github.com/RichardAtCT/claude-code-telegram/blob/main/docs/configuration.md) first. If GitHub Discussions is enabled for this repository, questions are better asked there so other users can answer too. + Check [docs/setup.md](https://github.com/overwirehq/claude-code-telegram/blob/main/docs/setup.md) and [docs/configuration.md](https://github.com/overwirehq/claude-code-telegram/blob/main/docs/configuration.md) first. If GitHub Discussions is enabled for this repository, questions are better asked there so other users can answer too. - type: textarea id: question attributes: diff --git a/CHANGELOG.md b/CHANGELOG.md index f51c5180..57adc37e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Documentation +- **v2 roadmap**: `docs/ROADMAP-v2.md` plans the 2.0 release (SDK 0.2, interactive permission and question UX, per-conversation concurrency, session browser, classic-mode removal, container distribution), scoped to work not already covered by open pull requests +- **Community files**: issue forms (bug, feature, question), a pull request template with a hand-testing section, `CODEOWNERS`, `MAINTAINERS.md` (roles, one-week response promise, label set, path to maintainership), a Contributor Covenant 2.1 `CODE_OF_CONDUCT.md`, and a rewritten `CONTRIBUTING.md` (PR scope rules, AI-assisted contribution policy, current project layout) + +### Changed +- **Repository moved to the `overwirehq` organisation**: the canonical location is now `github.com/overwirehq/claude-code-telegram`. GitHub redirects the old URLs, but every link in the README, docs, issue templates and packaging metadata has been updated. Existing clones keep working; `git remote set-url origin https://github.com/overwirehq/claude-code-telegram.git` points one at the new location directly + ### Fixed - **CI now catches lockfile drift**: the `lint` and `test` jobs ran `poetry lock && poetry install`, which regenerated `poetry.lock` in place. A `pyproject.toml` dependency change with a stale lock therefore passed every PR and failed only at release time, as it did for v1.7.0 (#196). Both jobs now verify the lock with `poetry check --lock` and install from the committed lock, so CI tests the dependency set that actually ships rather than resolving a fresh one on every run. +- **Green test suite**: `test_allowed_tools_none_unaffected_by_approval_filter` asserted that `allowed_tools` is `None` under `DISABLE_TOOL_VALIDATION`, but #206 had already changed that value to `[]` for type correctness. #217 was written against a base without #206, so the collision only surfaced once both were on `main`, leaving the default branch red. The expectation is now `[]`, and the test is renamed to say so +- **Project URLs**: the Homepage, Repository and Documentation links in `pyproject.toml` pointed at `github.com/richardatkinson/...`, an owner unrelated to this project, so `pip show` and any future PyPI listing linked to the wrong place + +### Added +- **Dependabot**: weekly PRs for `claude-agent-sdk`, `python-telegram-bot` and `anthropic`; monthly grouped PRs for other Python dependencies and GitHub Actions +- **Claude Code Review workflow**: read-only first-pass review comment on every non-draft pull request, including fork PRs. Requires the `CLAUDE_CODE_OAUTH_TOKEN` (or `ANTHROPIC_API_KEY`) repository secret ## [1.7.0] - 2026-09-11 @@ -20,7 +33,7 @@ behaviour for every deployment. See the upgrade note under **Changed**. ### Changed - **Upgrade note for #220**: tool calls targeting paths outside `APPROVED_DIRECTORY` are now denied where they previously succeeded. This restores the behaviour the documentation always described, but it is a real change for any deployment that relied on the gap. Routing each guarded call through the callback also adds one control-request round trip per call. `DISABLE_TOOL_VALIDATION=true` restores the previous permissive behaviour for trusted environments. -- **Known limitation**: `CLAUDE_ALLOWED_TOOLS` does not block tools left off the list — unlisted tools reach the callback, which allows anything passing its boundary checks. `CLAUDE_DISALLOWED_TOOLS` is the only setting that denies a tool. Tracked in [#221](https://github.com/RichardAtCT/claude-code-telegram/issues/221); `SECURITY.md` and `docs/tools.md` now describe the actual behaviour. +- **Known limitation**: `CLAUDE_ALLOWED_TOOLS` does not block tools left off the list — unlisted tools reach the callback, which allows anything passing its boundary checks. `CLAUDE_DISALLOWED_TOOLS` is the only setting that denies a tool. Tracked in [#221](https://github.com/overwirehq/claude-code-telegram/issues/221); `SECURITY.md` and `docs/tools.md` now describe the actual behaviour. ### Fixed - **Polling no longer dies permanently**: a `getUpdates` request torn down mid-flight (unstable network, proxy or tunnel drop) left its connection checked out of a pool holding exactly one, so every later poll failed with "Pool timeout" and never recovered, even after the network came back (#214, closes #213) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a646eea2..1cf6e88b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -168,7 +168,7 @@ Discussions where enabled. ## Security Do not open a public issue for a vulnerability. Use -[GitHub Security Advisories](https://github.com/RichardAtCT/claude-code-telegram/security/advisories/new) +[GitHub Security Advisories](https://github.com/overwirehq/claude-code-telegram/security/advisories/new) as described in [SECURITY.md](SECURITY.md). ## Community diff --git a/README.md b/README.md index fbb090d7..3b335a03 100644 --- a/README.md +++ b/README.md @@ -45,24 +45,24 @@ Choose your preferred method: ```bash # Using uv (recommended — installs in an isolated environment) -uv tool install git+https://github.com/RichardAtCT/claude-code-telegram@v1.3.0 +uv tool install git+https://github.com/overwirehq/claude-code-telegram@v1.3.0 # Or using pip -pip install git+https://github.com/RichardAtCT/claude-code-telegram@v1.3.0 +pip install git+https://github.com/overwirehq/claude-code-telegram@v1.3.0 # Track the latest stable release -pip install git+https://github.com/RichardAtCT/claude-code-telegram@latest +pip install git+https://github.com/overwirehq/claude-code-telegram@latest ``` #### Option B: From source (for development) ```bash -git clone https://github.com/RichardAtCT/claude-code-telegram.git +git clone https://github.com/overwirehq/claude-code-telegram.git cd claude-code-telegram make dev # requires Poetry ``` -> **Note:** Always install from a tagged release (not `main`) for stability. See [Releases](https://github.com/RichardAtCT/claude-code-telegram/releases) for available versions. +> **Note:** Always install from a tagged release (not `main`) for stability. See [Releases](https://github.com/overwirehq/claude-code-telegram/releases) for available versions. ### 3. Configure @@ -369,7 +369,7 @@ MIT License -- see [LICENSE](LICENSE). ## Star History -[![Star History Chart](https://api.star-history.com/svg?repos=RichardAtCT/claude-code-telegram&type=Date)](https://star-history.com/#RichardAtCT/claude-code-telegram&Date) +[![Star History Chart](https://api.star-history.com/svg?repos=overwirehq/claude-code-telegram&type=Date)](https://star-history.com/#overwirehq/claude-code-telegram&Date) ## Acknowledgments diff --git a/SECURITY.md b/SECURITY.md index 347f7c8a..5172869b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -79,7 +79,7 @@ the guarded tools from the `allowed_tools` it hands the SDK and disables `autoAllowBashIfSandboxed` (a second bypass, which auto-approves sandboxed Bash without a control request). Before this was fixed the checks were wired up but never consulted on a default configuration -([#219](https://github.com/RichardAtCT/claude-code-telegram/issues/219)). +([#219](https://github.com/overwirehq/claude-code-telegram/issues/219)). Routing a tool call through the callback costs one local stdio round trip to the CLI subprocess plus ~30-90 microseconds of validation -- negligible against the @@ -106,7 +106,7 @@ to the callback, which allows anything that passes the boundary checks. Use exists, but `src/main.py` still backs it with `InMemoryTokenStorage`, so issued tokens are lost on restart and there is no supported flow for issuing one. **Use `ALLOWED_USERS` as the access control for any real deployment.** Tracked in -[#58](https://github.com/RichardAtCT/claude-code-telegram/issues/58). +[#58](https://github.com/overwirehq/claude-code-telegram/issues/58). ## Security Configuration @@ -230,7 +230,7 @@ ENVIRONMENT=production # Enables strict security defaults Report it privately through GitHub Security Advisories: -**https://github.com/RichardAtCT/claude-code-telegram/security/advisories/new** +**https://github.com/overwirehq/claude-code-telegram/security/advisories/new** That form is private to you and the maintainers, supports attachments and follow-up discussion, and lets us credit you on the published advisory. You can diff --git a/docs/ROADMAP-v2.md b/docs/ROADMAP-v2.md index 9e438974..ff028ad7 100644 --- a/docs/ROADMAP-v2.md +++ b/docs/ROADMAP-v2.md @@ -1,7 +1,7 @@ # v2 Roadmap **Status:** proposal, September 2026 -**Baseline:** v1.6.2, `claude-agent-sdk ^0.1.39`, 559 tests, 56% coverage +**Baseline:** v1.7.0, `claude-agent-sdk ^0.1.39`, 559 tests, 56% coverage This document plans the 2.0 release. It deliberately excludes work that already exists as an open pull request (see [Out of scope](#out-of-scope-covered-by-open-prs)); @@ -37,7 +37,6 @@ Do not duplicate these in v2 work. Merge, revise, or close them during triage. | Area | PR(s) | Related issue | |------|-------|---------------| -| Per-tool Allow/Deny approval prompt | #217 | #216 | | Alternative model providers (MiniMax, base URL) | #210, #143 | #171, #208 | | Voice replies (TTS) | #167 | | | Sending agent-mentioned images / arbitrary files | #204, #191 | | @@ -53,20 +52,20 @@ Do not duplicate these in v2 work. Merge, revise, or close them during triage. | `/schedule` command | #151 | #150 | | Streaming drafts, rich HTML, follow-up interrupts | #152 | #126 | -Merged in 1.6.2 and therefore no longer listed: #214, #212, #196, #177, #178, -#206, and #220 (guarded tools now routed through `can_use_tool`). +Merged in 1.7.0 and therefore no longer listed: #214, #212, #196, #177, #178, +#206, #220 (guarded tools now routed through `can_use_tool`) and #217 +(per-tool Allow/Deny approval prompt, closing #216). -Two of the remaining PRs interact with v2 work and should be merged first so -v2 builds on them rather than around them: #217 (approval prompt, extended in -M1) and #165 (moves session state from `user_data` to `chat_data`, extended -in M2). +One remaining PR interacts with v2 work and should be merged first so v2 +builds on it rather than around it: #165, which moves session state from +`user_data` to `chat_data` and is extended in M2. ## Milestones Sizes: **S** under a day, **M** two to four days, **L** a week or more. Each item lists the files most likely to change so work can be split. -### M0. Foundations (ship as 1.7, non-breaking) +### M0. Foundations (ship as 1.8, non-breaking) Preparation that every later milestone depends on. Nothing here changes behaviour for a default install. @@ -106,17 +105,17 @@ Agentic tasks routinely need 30 to 50 tool round-trips. Raise the default to **0.4 Distribution.** Add a `Dockerfile` (python:3.12-slim, Node for the Claude Code CLI, non-root user, `data/` volume) and a `docker-compose.yml` -with the three required variables. Publish to GHCR from `release.yml` on -tag. Publish the wheel to PyPI from the same workflow so -`pipx install claude-code-telegram` works. Fix the project URLs in -`pyproject.toml`, which point at `richardatkinson/...` instead of -`RichardAtCT/...`. Done when a fresh machine goes from zero to a responding -bot with `docker compose up` and a three-line `.env`. +with the three required variables. Publish to +`ghcr.io/overwirehq/claude-code-telegram` from `release.yml` on tag. Publish +the wheel to PyPI from the same workflow so +`pipx install claude-code-telegram` works. Done when a fresh machine goes +from zero to a responding bot with `docker compose up` and a three-line +`.env`. **0.5 Hygiene.** Add `.github/ISSUE_TEMPLATE/` (bug, feature, question), `CODEOWNERS`, and a label set (`bug`, `enhancement`, `sdk`, `security`, `good first issue`, `needs-triage`). Restore an automated first-pass review -workflow on pull requests. (`docs/tools.md` was corrected in 1.6.2 and +workflow on pull requests. (`docs/tools.md` was corrected in 1.7.0 and `CONTRIBUTING.md` is rewritten alongside this roadmap.) **0.6 CI.** Test on 3.11, 3.12 and 3.13. Add mypy to the lint job (the @@ -142,7 +141,7 @@ terminal into something the user can do from a Telegram keyboard. asks questions that nobody can answer; the run stalls or Claude guesses. The SDK routes the call through `can_use_tool` with the questions in the tool input, but only for tools that are *not* pre-approved in `allowed_tools` -(#219/#220 established this against a live bot; 1.6.2 strips the +(#219/#220 established this against a live bot; 1.7.0 strips the `GUARDED_TOOLS` set from the allowlist handed to the SDK for exactly this reason). So first add `AskUserQuestion` to that set, then intercept it in the callback: render each question as an inline keyboard (one @@ -189,7 +188,8 @@ user always knows what will and will not prompt. Files: session". Implement by returning `PermissionResultAllow` with a `PermissionUpdate` that adds an allow rule for the tool (and for Bash, the command prefix) scoped to the session. Persist the choice alongside the -session record so it survives a bot restart. Depends on #217 merging. +session record so it survives a bot restart. #217 shipped the Allow/Deny +keyboard in 1.7.0; this adds the third button to it. **1.5 Undo.** Enable `enable_file_checkpointing` together with `extra_args={"replay-user-messages": None}` so the stream carries @@ -310,7 +310,7 @@ of webhooks cannot starve chat. **4.1 Classic mode.** `src/bot/handlers/` and the classic-only parts of `src/bot/features/` are roughly 6,500 lines that duplicate agentic mode -with a different UI. Deprecate in 1.7 (log a warning when +with a different UI. Deprecate in 1.8 (log a warning when `AGENTIC_MODE=false`), remove in 2.0. Keep the three classic commands that have no agentic equivalent as agentic commands: `/cd` (alias of `/repo`), `/export` (session export already lives in `src/bot/features/`), and @@ -351,7 +351,7 @@ message), and the new permission-mode default. ## Release mechanics -1. **1.7.0**: M0 complete. Deprecation warning for classic mode. Announce +1. **1.8.0**: M0 complete. Deprecation warning for classic mode. Announce the v2 plan in the release notes with a link to this document. 2. **2.0.0-beta.1**: M1 and M2 complete on `main`, published as a pre-release tag and a `beta` Docker tag. Two to three weeks of feedback. diff --git a/docs/SDK_DUPLICATION_REVIEW.md b/docs/SDK_DUPLICATION_REVIEW.md index 73811f95..58f28211 100644 --- a/docs/SDK_DUPLICATION_REVIEW.md +++ b/docs/SDK_DUPLICATION_REVIEW.md @@ -569,8 +569,8 @@ Before any refactor: | Date | PR | Findings Addressed | Summary | |------|:---:|:---:|---------| -| 2026-02-20 | [#56](https://github.com/RichardAtCT/claude-code-telegram/pull/56) | F1 (partial), F8, F9 | Migrated `query()` → `ClaudeSDKClient`, eliminated `temp_*` IDs and session swapping, uses `ResultMessage.result`, removed dead `active_sessions` state | -| 2026-02-20 | [#59](https://github.com/RichardAtCT/claude-code-telegram/pull/59) | F3 (complete), F5 (complete) | Deleted CLI subprocess backend (`integration.py`, `parser.py`), removed `use_sdk` flag, passed `disallowed_tools` to SDK, ~1,060 lines removed | +| 2026-02-20 | [#56](https://github.com/overwirehq/claude-code-telegram/pull/56) | F1 (partial), F8, F9 | Migrated `query()` → `ClaudeSDKClient`, eliminated `temp_*` IDs and session swapping, uses `ResultMessage.result`, removed dead `active_sessions` state | +| 2026-02-20 | [#59](https://github.com/overwirehq/claude-code-telegram/pull/59) | F3 (complete), F5 (complete) | Deleted CLI subprocess backend (`integration.py`, `parser.py`), removed `use_sdk` flag, passed `disallowed_tools` to SDK, ~1,060 lines removed | | 2026-02-20 | Phase 3 branch | F2 (complete), F6 (complete) | Replaced `ToolMonitor` with SDK's `can_use_tool` callback, removed bash pattern blocklist, removed facade interception + admin message helpers, removed `ClaudeToolValidationError`, ~350 lines removed | ### Next Steps diff --git a/docs/development.md b/docs/development.md index 6260bf40..8f40ca26 100644 --- a/docs/development.md +++ b/docs/development.md @@ -17,7 +17,7 @@ This document provides detailed information for developers working on the Claude 1. **Clone the repository**: ```bash - git clone https://github.com/RichardAtCT/claude-code-telegram.git + git clone https://github.com/overwirehq/claude-code-telegram.git cd claude-code-telegram ``` diff --git a/docs/setup.md b/docs/setup.md index acb7f906..b7433481 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -47,13 +47,13 @@ Choose your preferred installation method: ```bash # Using uv (recommended — installs in an isolated environment) -uv tool install git+https://github.com/RichardAtCT/claude-code-telegram@v1.3.0 +uv tool install git+https://github.com/overwirehq/claude-code-telegram@v1.3.0 # Or using pip -pip install git+https://github.com/RichardAtCT/claude-code-telegram@v1.3.0 +pip install git+https://github.com/overwirehq/claude-code-telegram@v1.3.0 # Track the latest stable release -pip install git+https://github.com/RichardAtCT/claude-code-telegram@latest +pip install git+https://github.com/overwirehq/claude-code-telegram@latest ``` > **Don't have uv?** Install it with `curl -LsSf https://astral.sh/uv/install.sh | sh`. @@ -61,12 +61,12 @@ pip install git+https://github.com/RichardAtCT/claude-code-telegram@latest #### Option B: From source (for development) ```bash -git clone https://github.com/RichardAtCT/claude-code-telegram.git +git clone https://github.com/overwirehq/claude-code-telegram.git cd claude-code-telegram make dev ``` -> **Important:** Always install from a [tagged release](https://github.com/RichardAtCT/claude-code-telegram/releases), not `main`, for stability. +> **Important:** Always install from a [tagged release](https://github.com/overwirehq/claude-code-telegram/releases), not `main`, for stability. ### 4. Configure Environment @@ -362,4 +362,4 @@ ENABLE_TELEMETRY=true - **Documentation**: Check the main [README.md](../README.md) - **Configuration**: See [configuration.md](configuration.md) for all options - **Security**: See [SECURITY.md](../SECURITY.md) for security concerns -- **Issues**: [Open an issue](https://github.com/RichardAtCT/claude-code-telegram/issues) +- **Issues**: [Open an issue](https://github.com/overwirehq/claude-code-telegram/issues) diff --git a/pyproject.toml b/pyproject.toml index 9cb8b99a..231445b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,9 +23,9 @@ requires-python = ">=3.11" dynamic = ["dependencies"] [project.urls] -Homepage = "https://github.com/RichardAtCT/claude-code-telegram" -Repository = "https://github.com/RichardAtCT/claude-code-telegram" -Documentation = "https://github.com/RichardAtCT/claude-code-telegram/blob/main/docs/" +Homepage = "https://github.com/overwirehq/claude-code-telegram" +Repository = "https://github.com/overwirehq/claude-code-telegram" +Documentation = "https://github.com/overwirehq/claude-code-telegram/blob/main/docs/" [project.scripts] claude-telegram-bot = "src.main:run" diff --git a/tests/unit/test_bot/test_middleware.py b/tests/unit/test_bot/test_middleware.py index 4ff58365..0e4fb645 100644 --- a/tests/unit/test_bot/test_middleware.py +++ b/tests/unit/test_bot/test_middleware.py @@ -4,7 +4,7 @@ violation, rate limit exceeded), ApplicationHandlerStop is raised to prevent subsequent handler groups from processing the update. -Regression tests for: https://github.com/RichardAtCT/claude-code-telegram/issues/44 +Regression tests for: https://github.com/overwirehq/claude-code-telegram/issues/44 """ from unittest.mock import AsyncMock, MagicMock diff --git a/tests/unit/test_claude/test_sdk_integration.py b/tests/unit/test_claude/test_sdk_integration.py index 84f6e066..eb2b412a 100644 --- a/tests/unit/test_claude/test_sdk_integration.py +++ b/tests/unit/test_claude/test_sdk_integration.py @@ -658,8 +658,8 @@ async def test_allowed_tools_untouched_when_interactive_approval_disabled( assert captured_options[0].allowed_tools == config.claude_allowed_tools - async def test_allowed_tools_none_unaffected_by_approval_filter(self, tmp_path): - """When allowed_tools is None (DISABLE_TOOL_VALIDATION), filtering is a no-op.""" + async def test_empty_allowed_tools_unaffected_by_approval_filter(self, tmp_path): + """When DISABLE_TOOL_VALIDATION empties allowed_tools, filtering is a no-op.""" config = Settings( telegram_bot_token="test:token", telegram_bot_username="testbot", @@ -686,7 +686,7 @@ async def test_allowed_tools_none_unaffected_by_approval_filter(self, tmp_path): working_directory=tmp_path, ) - assert captured_options[0].allowed_tools is None + assert captured_options[0].allowed_tools == [] async def test_system_prompt_set_with_working_directory( self, sdk_manager, tmp_path