takopi 0.9.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 (46) hide show
  1. takopi-0.9.0/LICENSE +21 -0
  2. takopi-0.9.0/PKG-INFO +184 -0
  3. takopi-0.9.0/pyproject.toml +51 -0
  4. takopi-0.9.0/readme.md +138 -0
  5. takopi-0.9.0/src/takopi/__init__.py +1 -0
  6. takopi-0.9.0/src/takopi/backends.py +25 -0
  7. takopi-0.9.0/src/takopi/backends_helpers.py +14 -0
  8. takopi-0.9.0/src/takopi/cli.py +533 -0
  9. takopi-0.9.0/src/takopi/config.py +260 -0
  10. takopi-0.9.0/src/takopi/context.py +9 -0
  11. takopi-0.9.0/src/takopi/engines.py +71 -0
  12. takopi-0.9.0/src/takopi/events.py +170 -0
  13. takopi-0.9.0/src/takopi/lockfile.py +158 -0
  14. takopi-0.9.0/src/takopi/logging.py +274 -0
  15. takopi-0.9.0/src/takopi/markdown.py +298 -0
  16. takopi-0.9.0/src/takopi/model.py +77 -0
  17. takopi-0.9.0/src/takopi/presenter.py +25 -0
  18. takopi-0.9.0/src/takopi/progress.py +99 -0
  19. takopi-0.9.0/src/takopi/router.py +103 -0
  20. takopi-0.9.0/src/takopi/runner.py +612 -0
  21. takopi-0.9.0/src/takopi/runner_bridge.py +599 -0
  22. takopi-0.9.0/src/takopi/runners/__init__.py +1 -0
  23. takopi-0.9.0/src/takopi/runners/claude.py +532 -0
  24. takopi-0.9.0/src/takopi/runners/codex.py +602 -0
  25. takopi-0.9.0/src/takopi/runners/mock.py +224 -0
  26. takopi-0.9.0/src/takopi/runners/opencode.py +545 -0
  27. takopi-0.9.0/src/takopi/runners/pi.py +487 -0
  28. takopi-0.9.0/src/takopi/scheduler.py +107 -0
  29. takopi-0.9.0/src/takopi/schemas/__init__.py +1 -0
  30. takopi-0.9.0/src/takopi/schemas/claude.py +238 -0
  31. takopi-0.9.0/src/takopi/schemas/codex.py +169 -0
  32. takopi-0.9.0/src/takopi/schemas/opencode.py +51 -0
  33. takopi-0.9.0/src/takopi/schemas/pi.py +108 -0
  34. takopi-0.9.0/src/takopi/telegram/__init__.py +5 -0
  35. takopi-0.9.0/src/takopi/telegram/bridge.py +810 -0
  36. takopi-0.9.0/src/takopi/telegram/client.py +725 -0
  37. takopi-0.9.0/src/takopi/telegram/config.py +31 -0
  38. takopi-0.9.0/src/takopi/telegram/onboarding.py +437 -0
  39. takopi-0.9.0/src/takopi/telegram/render.py +39 -0
  40. takopi-0.9.0/src/takopi/transport.py +61 -0
  41. takopi-0.9.0/src/takopi/utils/__init__.py +1 -0
  42. takopi-0.9.0/src/takopi/utils/git.py +81 -0
  43. takopi-0.9.0/src/takopi/utils/paths.py +47 -0
  44. takopi-0.9.0/src/takopi/utils/streams.py +44 -0
  45. takopi-0.9.0/src/takopi/utils/subprocess.py +84 -0
  46. takopi-0.9.0/src/takopi/worktrees.py +119 -0
takopi-0.9.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 banteg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
takopi-0.9.0/PKG-INFO ADDED
@@ -0,0 +1,184 @@
1
+ Metadata-Version: 2.3
2
+ Name: takopi
3
+ Version: 0.9.0
4
+ Summary: Telegram bridge for Codex, Claude Code, and other agent CLIs.
5
+ Author: banteg
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 banteg
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Classifier: License :: OSI Approved :: MIT License
28
+ Classifier: Programming Language :: Python :: 3
29
+ Classifier: Programming Language :: Python :: 3.14
30
+ Classifier: Programming Language :: Python :: 3 :: Only
31
+ Classifier: Operating System :: OS Independent
32
+ Requires-Dist: anyio>=4.12.0
33
+ Requires-Dist: httpx>=0.28.1
34
+ Requires-Dist: markdown-it-py
35
+ Requires-Dist: msgspec>=0.20.0
36
+ Requires-Dist: questionary>=2.1.1
37
+ Requires-Dist: rich>=14.2.0
38
+ Requires-Dist: structlog>=25.5.0
39
+ Requires-Dist: sulguk>=0.11.1
40
+ Requires-Dist: typer>=0.21.0
41
+ Requires-Python: >=3.14
42
+ Project-URL: Homepage, https://github.com/banteg/takopi
43
+ Project-URL: Issues, https://github.com/banteg/takopi/issues
44
+ Project-URL: Repository, https://github.com/banteg/takopi
45
+ Description-Content-Type: text/markdown
46
+
47
+ # takopi
48
+
49
+ 🐙 *he just wants to help-pi*
50
+
51
+ telegram bridge for codex, claude code, opencode, pi, and [other agents](docs/adding-a-runner.md). manage multiple projects and worktrees, stream progress, and resume sessions anywhere.
52
+
53
+ ## features
54
+
55
+ projects and worktrees: register repos with `takopi init`, target them via `/project`, route to branches with `@branch`.
56
+
57
+ stateless resume: continue a thread in the chat or pick up in the terminal.
58
+
59
+ progress updates while agent runs (commands, tools, notes, file changes, elapsed time).
60
+
61
+ robust markdown rendering of output with a lot of quality of life tweaks.
62
+
63
+ parallel runs across threads, per thread queue support.
64
+
65
+ `/cancel` a running task.
66
+
67
+ ## requirements
68
+
69
+ - `uv` for installation (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
70
+ - python 3.14+ (uv can install it: `uv python install 3.14`)
71
+ - at least one engine installed:
72
+ - `codex` on PATH (`npm install -g @openai/codex` or `brew install codex`)
73
+ - `claude` on PATH (`npm install -g @anthropic-ai/claude-code`)
74
+ - `opencode` on PATH (`npm install -g opencode-ai@latest`)
75
+ - `pi` on PATH (`npm install -g @mariozechner/pi-coding-agent`)
76
+
77
+ ## install
78
+
79
+ - `uv python install 3.14`
80
+ - `uv tool install -U takopi` to install as `takopi`
81
+ - or try it with `uvx takopi@latest`
82
+
83
+ ## setup
84
+
85
+ run `takopi` and follow the interactive prompts. it will:
86
+
87
+ - help you create a bot token (via @BotFather)
88
+ - capture your `chat_id` from the most recent message you send to the bot
89
+ - check installed agents and set a default engine
90
+
91
+ to re-run onboarding (and overwrite config), use `takopi --onboard`.
92
+
93
+ run your agent cli once interactively in the repo to trust the directory.
94
+
95
+ ## config
96
+
97
+ global config `~/.takopi/takopi.toml`
98
+
99
+ ```toml
100
+ default_engine = "codex"
101
+
102
+ bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
103
+ chat_id = 123456789
104
+
105
+ [codex]
106
+ # optional: profile from ~/.codex/config.toml
107
+ profile = "takopi"
108
+
109
+ [claude]
110
+ model = "sonnet"
111
+ # optional: defaults to ["Bash", "Read", "Edit", "Write"]
112
+ allowed_tools = ["Bash", "Read", "Edit", "Write", "WebSearch"]
113
+ dangerously_skip_permissions = false
114
+ # uses subscription by default, override to use api billing
115
+ use_api_billing = false
116
+
117
+ [opencode]
118
+ model = "claude-sonnet-4-20250514"
119
+
120
+ [pi]
121
+ model = "gpt-4.1"
122
+ provider = "openai"
123
+ # optional: additional CLI arguments
124
+ extra_args = ["--no-color"]
125
+ ```
126
+
127
+ ## projects
128
+
129
+ register the current repo as a project alias:
130
+
131
+ ```sh
132
+ takopi init z80
133
+ ```
134
+
135
+ `takopi init` writes the repo root to `[projects.<alias>].path`. if you run it inside a git worktree, it resolves the main checkout and records that path instead of the worktree.
136
+
137
+ example:
138
+
139
+ ```toml
140
+ default_project = "z80"
141
+
142
+ [projects.z80]
143
+ path = "~/dev/z80"
144
+ worktrees_dir = ".worktrees"
145
+ default_engine = "codex"
146
+ worktree_base = "master"
147
+ ```
148
+
149
+ ## usage
150
+
151
+ start takopi in the repo you want to work on:
152
+
153
+ ```sh
154
+ cd ~/dev/your-repo
155
+ takopi
156
+ # or override the default engine for new threads:
157
+ takopi claude
158
+ takopi opencode
159
+ takopi pi
160
+ ```
161
+
162
+ resume lines always route to the matching engine; subcommands only override the default for new threads.
163
+
164
+ send a message to the bot.
165
+
166
+ start a new thread with a specific engine by prefixing your message with `/codex`, `/claude`, `/opencode`, or `/pi`.
167
+
168
+ to continue a thread, reply to a bot message containing a resume line.
169
+ you can also copy it to resume an interactive session in your terminal.
170
+
171
+ to stop a run, reply to the progress message with `/cancel`.
172
+
173
+ default: progress is silent, final answer is sent as a new message so you receive a notification, progress message is deleted.
174
+
175
+ if you prefer no notifications, `--no-final-notify` edits the progress message into the final answer.
176
+
177
+ ## notes
178
+
179
+ * the bot only responds to the configured `chat_id` (private or group)
180
+ * run only one takopi instance per bot token: multiple instances will race telegram's `getUpdates` offsets and cause missed updates
181
+
182
+ ## development
183
+
184
+ see [`docs/specification.md`](docs/specification.md) and [`docs/developing.md`](docs/developing.md).
@@ -0,0 +1,51 @@
1
+ [project]
2
+ name = "takopi"
3
+ authors = [{name = "banteg"}]
4
+ version = "0.9.0"
5
+ description = "Telegram bridge for Codex, Claude Code, and other agent CLIs."
6
+ readme = "readme.md"
7
+ license = { file = "LICENSE" }
8
+ requires-python = ">=3.14"
9
+ dependencies = [
10
+ "anyio>=4.12.0",
11
+ "httpx>=0.28.1",
12
+ "markdown-it-py",
13
+ "msgspec>=0.20.0",
14
+ "questionary>=2.1.1",
15
+ "rich>=14.2.0",
16
+ "structlog>=25.5.0",
17
+ "sulguk>=0.11.1",
18
+ "typer>=0.21.0",
19
+ ]
20
+ classifiers = [
21
+ "License :: OSI Approved :: MIT License",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.14",
24
+ "Programming Language :: Python :: 3 :: Only",
25
+ "Operating System :: OS Independent",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/banteg/takopi"
30
+ Repository = "https://github.com/banteg/takopi"
31
+ Issues = "https://github.com/banteg/takopi/issues"
32
+
33
+ [project.scripts]
34
+ takopi = "takopi.cli:main"
35
+
36
+ [build-system]
37
+ requires = ["uv_build>=0.9.18,<0.10.0"]
38
+ build-backend = "uv_build"
39
+
40
+ [dependency-groups]
41
+ dev = [
42
+ "pytest>=9.0.2",
43
+ "pytest-anyio>=0.0.0",
44
+ "pytest-cov>=7.0.0",
45
+ "ruff>=0.14.10",
46
+ "ty>=0.0.8",
47
+ ]
48
+
49
+ [tool.pytest.ini_options]
50
+ addopts = ["--cov=takopi", "--cov-report=term-missing", "--cov-fail-under=70"]
51
+ testpaths = ["tests"]
takopi-0.9.0/readme.md ADDED
@@ -0,0 +1,138 @@
1
+ # takopi
2
+
3
+ 🐙 *he just wants to help-pi*
4
+
5
+ telegram bridge for codex, claude code, opencode, pi, and [other agents](docs/adding-a-runner.md). manage multiple projects and worktrees, stream progress, and resume sessions anywhere.
6
+
7
+ ## features
8
+
9
+ projects and worktrees: register repos with `takopi init`, target them via `/project`, route to branches with `@branch`.
10
+
11
+ stateless resume: continue a thread in the chat or pick up in the terminal.
12
+
13
+ progress updates while agent runs (commands, tools, notes, file changes, elapsed time).
14
+
15
+ robust markdown rendering of output with a lot of quality of life tweaks.
16
+
17
+ parallel runs across threads, per thread queue support.
18
+
19
+ `/cancel` a running task.
20
+
21
+ ## requirements
22
+
23
+ - `uv` for installation (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
24
+ - python 3.14+ (uv can install it: `uv python install 3.14`)
25
+ - at least one engine installed:
26
+ - `codex` on PATH (`npm install -g @openai/codex` or `brew install codex`)
27
+ - `claude` on PATH (`npm install -g @anthropic-ai/claude-code`)
28
+ - `opencode` on PATH (`npm install -g opencode-ai@latest`)
29
+ - `pi` on PATH (`npm install -g @mariozechner/pi-coding-agent`)
30
+
31
+ ## install
32
+
33
+ - `uv python install 3.14`
34
+ - `uv tool install -U takopi` to install as `takopi`
35
+ - or try it with `uvx takopi@latest`
36
+
37
+ ## setup
38
+
39
+ run `takopi` and follow the interactive prompts. it will:
40
+
41
+ - help you create a bot token (via @BotFather)
42
+ - capture your `chat_id` from the most recent message you send to the bot
43
+ - check installed agents and set a default engine
44
+
45
+ to re-run onboarding (and overwrite config), use `takopi --onboard`.
46
+
47
+ run your agent cli once interactively in the repo to trust the directory.
48
+
49
+ ## config
50
+
51
+ global config `~/.takopi/takopi.toml`
52
+
53
+ ```toml
54
+ default_engine = "codex"
55
+
56
+ bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
57
+ chat_id = 123456789
58
+
59
+ [codex]
60
+ # optional: profile from ~/.codex/config.toml
61
+ profile = "takopi"
62
+
63
+ [claude]
64
+ model = "sonnet"
65
+ # optional: defaults to ["Bash", "Read", "Edit", "Write"]
66
+ allowed_tools = ["Bash", "Read", "Edit", "Write", "WebSearch"]
67
+ dangerously_skip_permissions = false
68
+ # uses subscription by default, override to use api billing
69
+ use_api_billing = false
70
+
71
+ [opencode]
72
+ model = "claude-sonnet-4-20250514"
73
+
74
+ [pi]
75
+ model = "gpt-4.1"
76
+ provider = "openai"
77
+ # optional: additional CLI arguments
78
+ extra_args = ["--no-color"]
79
+ ```
80
+
81
+ ## projects
82
+
83
+ register the current repo as a project alias:
84
+
85
+ ```sh
86
+ takopi init z80
87
+ ```
88
+
89
+ `takopi init` writes the repo root to `[projects.<alias>].path`. if you run it inside a git worktree, it resolves the main checkout and records that path instead of the worktree.
90
+
91
+ example:
92
+
93
+ ```toml
94
+ default_project = "z80"
95
+
96
+ [projects.z80]
97
+ path = "~/dev/z80"
98
+ worktrees_dir = ".worktrees"
99
+ default_engine = "codex"
100
+ worktree_base = "master"
101
+ ```
102
+
103
+ ## usage
104
+
105
+ start takopi in the repo you want to work on:
106
+
107
+ ```sh
108
+ cd ~/dev/your-repo
109
+ takopi
110
+ # or override the default engine for new threads:
111
+ takopi claude
112
+ takopi opencode
113
+ takopi pi
114
+ ```
115
+
116
+ resume lines always route to the matching engine; subcommands only override the default for new threads.
117
+
118
+ send a message to the bot.
119
+
120
+ start a new thread with a specific engine by prefixing your message with `/codex`, `/claude`, `/opencode`, or `/pi`.
121
+
122
+ to continue a thread, reply to a bot message containing a resume line.
123
+ you can also copy it to resume an interactive session in your terminal.
124
+
125
+ to stop a run, reply to the progress message with `/cancel`.
126
+
127
+ default: progress is silent, final answer is sent as a new message so you receive a notification, progress message is deleted.
128
+
129
+ if you prefer no notifications, `--no-final-notify` edits the progress message into the final answer.
130
+
131
+ ## notes
132
+
133
+ * the bot only responds to the configured `chat_id` (private or group)
134
+ * run only one takopi instance per bot token: multiple instances will race telegram's `getUpdates` offsets and cause missed updates
135
+
136
+ ## development
137
+
138
+ see [`docs/specification.md`](docs/specification.md) and [`docs/developing.md`](docs/developing.md).
@@ -0,0 +1 @@
1
+ __version__ = "0.9.0"
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Callable
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ if TYPE_CHECKING:
9
+ from .runner import Runner
10
+
11
+ EngineConfig = dict[str, Any]
12
+
13
+
14
+ @dataclass(frozen=True, slots=True)
15
+ class SetupIssue:
16
+ title: str
17
+ lines: tuple[str, ...]
18
+
19
+
20
+ @dataclass(frozen=True, slots=True)
21
+ class EngineBackend:
22
+ id: str
23
+ build_runner: Callable[[EngineConfig, Path], Runner]
24
+ cli_cmd: str | None = None
25
+ install_cmd: str | None = None
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ from .backends import SetupIssue
4
+
5
+
6
+ def install_issue(cmd: str, install_cmd: str | None) -> SetupIssue:
7
+ if install_cmd:
8
+ lines = (f" [dim]$[/] {install_cmd}",)
9
+ else:
10
+ lines = (" [dim]See engine setup docs for install instructions.[/]",)
11
+ return SetupIssue(
12
+ f"install {cmd}",
13
+ lines,
14
+ )