remote-coder 0.4.1__tar.gz → 0.4.2__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.
- remote_coder-0.4.2/PKG-INFO +520 -0
- remote_coder-0.4.2/README.md +298 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/__init__.py +1 -1
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/router.py +12 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/i18n.js +20 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/templates/admin.html +126 -0
- remote_coder-0.4.2/app/cli.py +133 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/config.py +1 -1
- remote_coder-0.4.2/app/diagnostics.py +37 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/pyproject.toml +11 -11
- remote_coder-0.4.2/remote_coder.egg-info/PKG-INFO +520 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/remote_coder.egg-info/SOURCES.txt +2 -0
- remote_coder-0.4.2/remote_coder.egg-info/requires.txt +12 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_admin_router.py +34 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_cli.py +3 -36
- remote_coder-0.4.2/tests/test_diagnostics.py +32 -0
- remote_coder-0.4.1/PKG-INFO +0 -520
- remote_coder-0.4.1/README.md +0 -298
- remote_coder-0.4.1/app/cli.py +0 -238
- remote_coder-0.4.1/remote_coder.egg-info/PKG-INFO +0 -520
- remote_coder-0.4.1/remote_coder.egg-info/requires.txt +0 -12
- {remote_coder-0.4.1 → remote_coder-0.4.2}/LICENSE +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/advanced_settings.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/database_browser.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/icons/advanced.svg +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/icons/database.svg +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/icons/download.svg +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/icons/home.svg +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/icons/logs.svg +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/icons/projects.svg +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/static/summary.js +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/templates/advanced.html +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/templates/database.html +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/templates/logs.html +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/admin/templates/projects.html +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/base.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/claude.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/codex.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/factory.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/gemini.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/model_catalog.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/ai/usage.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/git/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/git/ai_commit.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/git/branch_naming.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/git/commit_message.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/git/service.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/jobs/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/jobs/manager.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/jobs/schemas.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/jobs/store.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/main.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/models.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/monitoring/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/monitoring/code.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/monitoring/events.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/monitoring/git.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/monitoring/log_buffer.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/monitoring/memory.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/monitoring/model.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/projects/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/projects/registry.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/security/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/security/auth.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/system_startup.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/bot_instances.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/__init__.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/base.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/branch.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/clear_stop.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/fix.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/model.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/monitor.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/registry.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/status.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/commands/system.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/confirmations.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/conversation.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/i18n.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/model_preferences.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/notifier.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/parser.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/webhook.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/telegram/webhook_registration.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/app/tunnel.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/remote_coder.egg-info/dependency_links.txt +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/remote_coder.egg-info/entry_points.txt +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/remote_coder.egg-info/top_level.txt +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/setup.cfg +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_ai_base.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_ai_commit.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_ai_factory.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_auth.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_bot_instance_manager.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_branch_naming.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_claude_runner.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_codex_runner.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_command_parser.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_commands.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_commit_message_formatter.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_config.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_conversation_store.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_database_browser.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_event_logger.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_gemini_runner.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_git_service.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_i18n.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_job_manager.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_job_status.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_job_store.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_log_buffer.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_monitoring.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_notifier.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_project_registry.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_project_scoped_state.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_system_startup.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_tunnel.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_webhook.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_webhook_multibot.py +0 -0
- {remote_coder-0.4.1 → remote_coder-0.4.2}/tests/test_webhook_registration.py +0 -0
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: remote-coder
|
|
3
|
+
Version: 0.4.2
|
|
4
|
+
Summary: Telegram-based remote AI coding automation server
|
|
5
|
+
Author: Remote AI Coder contributors
|
|
6
|
+
License: Apache License
|
|
7
|
+
Version 2.0, January 2004
|
|
8
|
+
http://www.apache.org/licenses/
|
|
9
|
+
|
|
10
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
11
|
+
|
|
12
|
+
1. Definitions.
|
|
13
|
+
|
|
14
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
15
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
16
|
+
|
|
17
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
18
|
+
the copyright owner that is granting the License.
|
|
19
|
+
|
|
20
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
21
|
+
other entities that control, are controlled by, or are under common
|
|
22
|
+
control with that entity. For the purposes of this definition,
|
|
23
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
24
|
+
direction or management of such entity, whether by contract or
|
|
25
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
26
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
27
|
+
|
|
28
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
29
|
+
exercising permissions granted by this License.
|
|
30
|
+
|
|
31
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
32
|
+
including but not limited to software source code, documentation
|
|
33
|
+
source, and configuration files.
|
|
34
|
+
|
|
35
|
+
"Object" form shall mean any form resulting from mechanical
|
|
36
|
+
transformation or translation of a Source form, including but
|
|
37
|
+
not limited to compiled object code, generated documentation,
|
|
38
|
+
and conversions to other media types.
|
|
39
|
+
|
|
40
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
41
|
+
Object form, made available under the License, as indicated by a
|
|
42
|
+
copyright notice that is included in or attached to the work
|
|
43
|
+
(an example is provided in the Appendix below).
|
|
44
|
+
|
|
45
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
46
|
+
form, that is based on (or derived from) the Work and for which the
|
|
47
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
48
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
49
|
+
of this License, Derivative Works shall not include works that remain
|
|
50
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
51
|
+
the Work and Derivative Works thereof.
|
|
52
|
+
|
|
53
|
+
"Contribution" shall mean any work of authorship, including
|
|
54
|
+
the original version of the Work and any modifications or additions
|
|
55
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
56
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
57
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
58
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
59
|
+
means any form of electronic, verbal, or written communication sent
|
|
60
|
+
to the Licensor or its representatives, including but not limited to
|
|
61
|
+
communication on electronic mailing lists, source code control systems,
|
|
62
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
63
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
64
|
+
excluding communication that is conspicuously marked or otherwise
|
|
65
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
66
|
+
|
|
67
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
68
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
69
|
+
subsequently incorporated within the Work.
|
|
70
|
+
|
|
71
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
72
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
73
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
74
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
75
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
76
|
+
Work and such Derivative Works in Source or Object form.
|
|
77
|
+
|
|
78
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
79
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
80
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
81
|
+
(except as stated in this section) patent license to make, have made,
|
|
82
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
83
|
+
where such license applies only to those patent claims licensable
|
|
84
|
+
by such Contributor that are necessarily infringed by their
|
|
85
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
86
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
87
|
+
institute patent litigation against any entity (including a
|
|
88
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
89
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
90
|
+
or contributory patent infringement, then any patent licenses
|
|
91
|
+
granted to You under this License for that Work shall terminate
|
|
92
|
+
as of the date such litigation is filed.
|
|
93
|
+
|
|
94
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
95
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
96
|
+
modifications, and in Source or Object form, provided that You
|
|
97
|
+
meet the following conditions:
|
|
98
|
+
|
|
99
|
+
(a) You must give any other recipients of the Work or
|
|
100
|
+
Derivative Works a copy of this License; and
|
|
101
|
+
|
|
102
|
+
(b) You must cause any modified files to carry prominent notices
|
|
103
|
+
stating that You changed the files; and
|
|
104
|
+
|
|
105
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
106
|
+
that You distribute, all copyright, patent, trademark, and
|
|
107
|
+
attribution notices from the Source form of the Work,
|
|
108
|
+
excluding those notices that do not pertain to any part of
|
|
109
|
+
the Derivative Works; and
|
|
110
|
+
|
|
111
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
112
|
+
distribution, then any Derivative Works that You distribute must
|
|
113
|
+
include a readable copy of the attribution notices contained
|
|
114
|
+
within such NOTICE file, excluding those notices that do not
|
|
115
|
+
pertain to any part of the Derivative Works, in at least one
|
|
116
|
+
of the following places: within a NOTICE text file distributed
|
|
117
|
+
as part of the Derivative Works; within the Source form or
|
|
118
|
+
documentation, if provided along with the Derivative Works; or,
|
|
119
|
+
within a display generated by the Derivative Works, if and
|
|
120
|
+
wherever such third-party notices normally appear. The contents
|
|
121
|
+
of the NOTICE file are for informational purposes only and
|
|
122
|
+
do not modify the License. You may add Your own attribution
|
|
123
|
+
notices within Derivative Works that You distribute, alongside
|
|
124
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
125
|
+
that such additional attribution notices cannot be construed
|
|
126
|
+
as modifying the License.
|
|
127
|
+
|
|
128
|
+
You may add Your own copyright statement to Your modifications and
|
|
129
|
+
may provide additional or different license terms and conditions
|
|
130
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
131
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
132
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
133
|
+
the conditions stated in this License.
|
|
134
|
+
|
|
135
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
136
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
137
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
138
|
+
this License, without any additional terms or conditions.
|
|
139
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
140
|
+
the terms of any separate license agreement you may have executed
|
|
141
|
+
with Licensor regarding such Contributions.
|
|
142
|
+
|
|
143
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
144
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
145
|
+
except as required for reasonable and customary use in describing the
|
|
146
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
147
|
+
|
|
148
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
149
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
150
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
151
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
152
|
+
implied, including, without limitation, any warranties or conditions
|
|
153
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
154
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
155
|
+
appropriateness of using or redistributing the Work and assume any
|
|
156
|
+
risks associated with Your exercise of permissions under this License.
|
|
157
|
+
|
|
158
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
159
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
160
|
+
unless required by applicable law (such as deliberate and grossly
|
|
161
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
162
|
+
liable to You for damages, including any direct, indirect, special,
|
|
163
|
+
incidental, or consequential damages of any character arising as a
|
|
164
|
+
result of this License or out of the use or inability to use the
|
|
165
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
166
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
167
|
+
other commercial damages or losses), even if such Contributor
|
|
168
|
+
has been advised of the possibility of such damages.
|
|
169
|
+
|
|
170
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
171
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
172
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
173
|
+
or other liability obligations and/or rights consistent with this
|
|
174
|
+
License. However, in accepting such obligations, You may act only
|
|
175
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
176
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
177
|
+
defend, and hold each Contributor harmless for any liability
|
|
178
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
179
|
+
of your accepting any such warranty or additional liability.
|
|
180
|
+
|
|
181
|
+
END OF TERMS AND CONDITIONS
|
|
182
|
+
|
|
183
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
184
|
+
|
|
185
|
+
To apply the Apache License to your work, attach the following
|
|
186
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
187
|
+
replaced with your own identifying information. (Don't include
|
|
188
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
189
|
+
comment syntax for the file format. We also recommend that a
|
|
190
|
+
file or class name and description of purpose be included on the
|
|
191
|
+
same "printed page" as the copyright notice for easier
|
|
192
|
+
identification within third-party archives.
|
|
193
|
+
|
|
194
|
+
Copyright 2026 maroomir
|
|
195
|
+
|
|
196
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
197
|
+
you may not use this file except in compliance with the License.
|
|
198
|
+
You may obtain a copy of the License at
|
|
199
|
+
|
|
200
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
201
|
+
|
|
202
|
+
Unless required by applicable law or agreed to in writing, software
|
|
203
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
204
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
205
|
+
See the License for the specific language governing permissions and
|
|
206
|
+
limitations under the License.
|
|
207
|
+
Requires-Python: >=3.11
|
|
208
|
+
Description-Content-Type: text/markdown
|
|
209
|
+
License-File: LICENSE
|
|
210
|
+
Requires-Dist: fastapi<1.0,>=0.115
|
|
211
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
212
|
+
Requires-Dist: pydantic<3.0,>=2.7
|
|
213
|
+
Requires-Dist: pydantic-settings<3.0,>=2.3
|
|
214
|
+
Requires-Dist: python-dotenv<2.0,>=1.0
|
|
215
|
+
Requires-Dist: pyyaml<7.0,>=6.0
|
|
216
|
+
Requires-Dist: uvicorn[standard]<1.0,>=0.30
|
|
217
|
+
Provides-Extra: dev
|
|
218
|
+
Requires-Dist: pytest<10.0,>=8.0; extra == "dev"
|
|
219
|
+
Requires-Dist: pytest-asyncio<2.0,>=0.23; extra == "dev"
|
|
220
|
+
Requires-Dist: respx<1.0,>=0.21; extra == "dev"
|
|
221
|
+
Dynamic: license-file
|
|
222
|
+
|
|
223
|
+
# Remote AI Coder
|
|
224
|
+
|
|
225
|
+
An MVP that runs AI coding tasks on your local development machine through Telegram messages and reports Git branch/commit results back as notifications.
|
|
226
|
+
|
|
227
|
+
> [!WARNING]
|
|
228
|
+
> This project runs AI CLI and Git operations on your local machine via Telegram messages. Do not expose the server or admin UI directly to the public internet. Always configure the Telegram allowlist (and optionally a webhook secret) and use it only in a private, trusted environment.
|
|
229
|
+
|
|
230
|
+
## Multi-bot model (summary)
|
|
231
|
+
|
|
232
|
+
- **Each registered project gets its own Telegram bot.** There is no `/project` command to switch the target repository from chat.
|
|
233
|
+
- Each bot has a distinct webhook path: `POST /telegram/webhook/{first 16 hex chars of SHA-256(bot token)}` (the token itself is never placed in the URL).
|
|
234
|
+
- Bot token, allowed Chat/User IDs, and an optional webhook secret are stored in the **project registry** (`projects.json`, etc.). **Tokens are stored in plain text**, so keep strict file permissions and a careful backup policy.
|
|
235
|
+
- See [`docs/multi-bot-setup.md`](docs/multi-bot-setup.md) for the full procedure.
|
|
236
|
+
- When a project is **disabled or deleted**, the server stops routing updates arriving with that token hash prefix. Even if an old URL remains registered on Telegram, this app ignores it. To clear or repoint a bot's webhook, call the Bot API `deleteWebhook` or re-run [`scripts/set_webhook.py`](scripts/set_webhook.py) against the current registry.
|
|
237
|
+
|
|
238
|
+
## Publishing / security notes
|
|
239
|
+
|
|
240
|
+
- Never commit `TELEGRAM_BOT_TOKEN` (optional seed), the registry `bot_token`, Chat/User IDs, webhook secrets, AI API keys, or personal paths to code or docs.
|
|
241
|
+
- `.env`, `.remote-coder/` (especially `projects.json`), worktrees, logs, and the SQLite conversation-memory file are local-only data. This repository's `.gitignore` excludes them by default.
|
|
242
|
+
- The admin UI (`/`, `/projects`, `/advanced`, `/logs`, `/database`) is designed for localhost only. Do not expose it externally via reverse proxy, ngrok, port forwarding, etc.
|
|
243
|
+
- Options such as Claude `--dangerously-skip-permissions`, Gemini `--approval-mode yolo`, and Codex `danger-full-access` can modify local files. Use them only after restricting the allowed projects and trusted users.
|
|
244
|
+
- The conversation-memory SQLite may store users' Telegram requests and Job summaries. Do not paste sensitive code into messages, and clean up with `/clear memory` or the admin UI advanced settings when needed.
|
|
245
|
+
|
|
246
|
+
See [`SECURITY.md`](SECURITY.md) for vulnerability reporting and pre-publication review steps.
|
|
247
|
+
|
|
248
|
+
## Prerequisites
|
|
249
|
+
|
|
250
|
+
- Python 3.11+ or Conda
|
|
251
|
+
- A Telegram Bot Token (BotFather) per project, plus allowed Chat IDs (required) and User IDs (optional)
|
|
252
|
+
- An HTTPS tunnel tool (e.g. ngrok for development)
|
|
253
|
+
- At least one of: Claude Code CLI, Codex CLI, Gemini CLI
|
|
254
|
+
- A target Git project and a local directory for worktrees
|
|
255
|
+
|
|
256
|
+
## Quick start (recommended)
|
|
257
|
+
|
|
258
|
+
Install with a single `pip` command — no separate Conda environment required. This installs the `remote-coder` CLI; check prerequisites (ngrok, AI CLIs) with `remote-coder doctor`.
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
pip install remote-coder
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
> Before the first PyPI release, install straight from the git source (this is still `pip`):
|
|
265
|
+
>
|
|
266
|
+
> ```bash
|
|
267
|
+
> pip install git+https://github.com/maroomir/remote-coder.git
|
|
268
|
+
> ```
|
|
269
|
+
|
|
270
|
+
After installing, start the server and finish setup in the browser:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
remote-coder up # ngrok tunnel + Telegram webhook registration + server, all at once (stop: Ctrl+C)
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
- On the first run (no projects yet), open the local admin UI at **http://127.0.0.1:8000/** and use the **First-time setup** card to add your first project (bot token, allowed Chat IDs, target repo path). The bot goes live as soon as the project is saved.
|
|
277
|
+
- The project registry (`projects.json` under `REMOTE_CODER_HOME`, default `~/.remote-coder`) is the source of truth; the admin UI writes to it. A global `REMOTE_CODER_HOME/.env` is optional and used only to seed the first project.
|
|
278
|
+
- Prerequisites: `ngrok` (after installing, run `ngrok config add-authtoken <token>`) and at least one AI CLI (`claude`/`codex`/`gemini`). Check them with `remote-coder doctor` or in the setup card.
|
|
279
|
+
- To run the server only, without a tunnel: `remote-coder up --no-tunnel`.
|
|
280
|
+
|
|
281
|
+
### Other installation methods
|
|
282
|
+
|
|
283
|
+
If you prefer isolated installs, use [pipx](https://pipx.pypa.io/) or [uv](https://docs.astral.sh/uv/). (Before the PyPI release, use `git+https://github.com/maroomir/remote-coder.git` instead of the package name.)
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
pipx install remote-coder
|
|
287
|
+
uv tool install remote-coder
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
There is also an install script that handles prerequisite checks in one go (isolated install via uv):
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
curl -fsSL https://raw.githubusercontent.com/maroomir/remote-coder/main/scripts/install.sh | bash
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Development install
|
|
297
|
+
|
|
298
|
+
Editable install from a source checkout:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
python -m pip install -e ".[dev]"
|
|
302
|
+
remote-coder up --no-tunnel --reload
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
`remote-coder up --no-tunnel` runs the server only, without tunnel/webhook registration — equivalent to `uvicorn app.main:app`.
|
|
306
|
+
|
|
307
|
+
### Building distribution packages
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
python -m pip install build
|
|
311
|
+
python -m build
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Outputs are `dist/remote_coder-<version>.tar.gz` and `dist/remote_coder-<version>-py3-none-any.whl`. Pushing a tag (`vX.Y.Z`) makes GitHub Actions build, publish to PyPI (Trusted Publishing), and create a GitHub Release automatically.
|
|
315
|
+
|
|
316
|
+
### Homebrew distribution
|
|
317
|
+
|
|
318
|
+
Since this is a CLI/server package, a Formula (`brew install remote-coder`) is a better fit than a macOS app-bundle Cask. A draft Formula is at [`packaging/homebrew/remote-coder.rb`](packaging/homebrew/remote-coder.rb).
|
|
319
|
+
|
|
320
|
+
After a release you still need to:
|
|
321
|
+
|
|
322
|
+
- Replace `homepage` with the actual repository URL
|
|
323
|
+
- Replace `url` with the `remote_coder-<version>.tar.gz` URL from PyPI or the GitHub Release
|
|
324
|
+
- Replace `sha256` with the value from `shasum -a 256 dist/remote_coder-<version>.tar.gz`
|
|
325
|
+
- Generate the Python dependency `resource` blocks with a tool like `brew pypi-poet remote-coder` and add them to the Formula
|
|
326
|
+
|
|
327
|
+
> Sections "1) – 3)" below are for **developers/contributors** who work directly from the repository or handle configuration manually instead of using `remote-coder up` plus the admin UI. Skip them if the quick start is enough.
|
|
328
|
+
|
|
329
|
+
## 1) Environment setup (Conda, for developers/contributors)
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
conda env create -f environment.yml
|
|
333
|
+
conda activate remote-coder
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## 2) Configuration
|
|
337
|
+
|
|
338
|
+
Copy and edit this `.env` only when configuring manually instead of using the admin UI. The `.env` is optional and seeds the first project when the registry is empty. (When running globally, `REMOTE_CODER_HOME/.env` takes precedence; when developing inside the repo, the current directory's `.env` takes precedence.)
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
cp .env.example .env
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Fill in the following values in `.env`:
|
|
345
|
+
|
|
346
|
+
- Optional (initial seed): `TELEGRAM_BOT_TOKEN`, `TELEGRAM_ALLOWED_CHAT_IDS`, `TELEGRAM_ALLOWED_USER_IDS`, `TELEGRAM_WEBHOOK_SECRET` — used only to create the first project when the registry is empty. Production settings prefer the **per-project** fields in the admin UI or `projects.json`.
|
|
347
|
+
- Optional: `GIT_REMOTE_NAME` (default `origin`) — used for push after commit and for `/rebase`, `/pr`, `/clear`
|
|
348
|
+
- Optional: `PROJECTS_CONFIG_PATH` — path to the registry file (JSON or `.yaml`) for multiple Git projects
|
|
349
|
+
- Optional: `CONVERSATION_DB_PATH` — SQLite path for per-project + per-chat conversation memory (defaults to `PROJECT_ROOT/.remote-coder/conversations.sqlite3`)
|
|
350
|
+
- Optional: `CONVERSATION_RECENT_LIMIT` — number of recent records appended to the runner for ambiguous follow-ups (default `10`)
|
|
351
|
+
- Optional: `CODEX_SANDBOX` — the Codex `codex exec --sandbox` value (`read-only`, `workspace-write`, `danger-full-access`). Default `workspace-write` (files can be edited in the Job worktree)
|
|
352
|
+
- Optional: to use Gemini, install the Gemini CLI with `npm install -g @google/gemini-cli` and make sure `gemini` is on your PATH
|
|
353
|
+
- Initial seed (one-time): `DEFAULT_PROJECT`, `PROJECT_ROOT`, `WORKTREE_BASE_DIR`
|
|
354
|
+
|
|
355
|
+
If you were using a single `.env` before → move each project's `bot_token`/allowlist into the admin UI, or clean sensitive values from `.env` after the seed is created. See the migration section in [`docs/multi-bot-setup.md`](docs/multi-bot-setup.md).
|
|
356
|
+
|
|
357
|
+
## 2.5) Local admin UI (project registration)
|
|
358
|
+
|
|
359
|
+
After starting the server, open it in a browser **on the same machine**.
|
|
360
|
+
|
|
361
|
+
- Admin hub: `http://127.0.0.1:8000/` (summary, navigation to other pages)
|
|
362
|
+
- Project registration: `http://127.0.0.1:8000/projects` (list, add/edit/delete, fallback defaults, **bot token / allowlist / webhook secret**, per-bot webhook path. While `remote-coder up` is running, the Telegram webhook and `/` command menu for active projects you add/edit are refreshed immediately)
|
|
363
|
+
- Advanced settings: `http://127.0.0.1:8000/advanced`
|
|
364
|
+
- Server logs: `http://127.0.0.1:8000/logs` (in-memory ring buffer for the `app` logger; auto-refresh, category and `chat_id`/`job_id` filters)
|
|
365
|
+
- Data browser: `http://127.0.0.1:8000/database` (browse the conversation-memory SQLite tables, export CSV)
|
|
366
|
+
- The natural-language task target is **bound to its bot**. The `project:` token is not supported.
|
|
367
|
+
- If `PROJECTS_CONFIG_PATH` is unset, the default path `PROJECT_ROOT/.remote-coder/projects.json` is used.
|
|
368
|
+
- If the registry file is missing, it is created automatically from the `.env` seed values (`DEFAULT_PROJECT`, `PROJECT_ROOT`, `WORKTREE_BASE_DIR`).
|
|
369
|
+
|
|
370
|
+
### Server log (event) logger naming convention
|
|
371
|
+
|
|
372
|
+
Entries shown in the admin UI `/logs` and the API `GET /api/logs` are recorded by `app` package loggers. The main logger names and their purposes:
|
|
373
|
+
|
|
374
|
+
| Logger name | Purpose |
|
|
375
|
+
|-------------|---------|
|
|
376
|
+
| `app.telegram.inbound` | Webhook receipt, empty-message skips |
|
|
377
|
+
| `app.telegram.outbound` | `sendMessage` success/failure, Job intake/result notifications |
|
|
378
|
+
| `app.telegram.command` | Slash-command handling, natural-language Job intake, state changes like `/init`/`/clear` confirmations |
|
|
379
|
+
| `app.security.auth` | Webhook secret mismatch, allowlist rejection |
|
|
380
|
+
| `app.jobs.lifecycle` | Job submission, stages (`git_worktree`/`runner`/…), success, failure |
|
|
381
|
+
| `app.git.service` | Git adapter: worktree creation, commit, push, cleanup, rebase integration |
|
|
382
|
+
| `app.ai.claude` / `app.ai.codex` / `app.ai.gemini` | Runner start/end/timeout |
|
|
383
|
+
|
|
384
|
+
Structured fields (`category`, `chat_id`, `user_id`, `project`, `job_id`) can be filtered/badged in the UI. In code, use `app.monitoring.events.EventLogger` and the `app.monitoring.log_buffer.LOG_RECORD_CONTEXT_KEYS` whitelist.
|
|
385
|
+
|
|
386
|
+
### Advanced settings (dangerous options)
|
|
387
|
+
|
|
388
|
+
On the admin UI **Advanced settings** page (`http://127.0.0.1:8000/advanced`) you can read and save the global settings file `PROJECT_ROOT/.remote-coder/advanced_settings.json`. **Interface language** (`ui_language`): the default is **English**, and it governs not only the Telegram bot's messages and button labels but the **entire admin UI** (`/`, `/projects`, `/advanced`, `/logs`, `/database`). Switching to **Korean**, saving, and refreshing renders both the admin UI and Telegram responses in Korean. (The admin UI renders English by default and overlays Korean on the client.)
|
|
389
|
+
|
|
390
|
+
Defaults differ per option (e.g. server-lifecycle Telegram notifications are on by default; `git pull` on server start is off by default); an option left off behaves as if that feature is disabled. Keys used only by older versions are ignored on load (e.g. the removed `auto_pull_on_project_switch`).
|
|
391
|
+
|
|
392
|
+
> [!WARNING]
|
|
393
|
+
> The "immediately apply the request result to main/master and push" option auto-merges AI changes into the integration branch. Unless this is a personal experimental repository, keep the default (off) and verify remote branch protection and your backup policy before enabling it.
|
|
394
|
+
|
|
395
|
+
- **Immediately apply the request result to main/master and push**: When a Job succeeds through commit and branch push, similar to `/rebase`, it fast-forward-merges that branch into the integration branch (`main` or `master`) and pushes to the remote. If integration fails (conflict, non-ff, etc.), the Job is recorded as failed.
|
|
396
|
+
- **SQLite conversation-memory size limit**: When enabled, it targets the whole `conversation_entries` table and deletes oldest rows first. At least one of **max row count** and **max DB size (bytes)** must be a positive number; if both are set, it first meets the row-count limit, then repeats delete/`VACUUM` to meet the size limit. `message_branch_links` orphan links are cleaned up.
|
|
397
|
+
|
|
398
|
+
## 3) Run it all at once
|
|
399
|
+
|
|
400
|
+
With the installed CLI, `remote-coder up` handles ngrok startup, webhook registration, and server start in one command. It passes the public ngrok URL to the server as `TELEGRAM_WEBHOOK_PUBLIC_BASE_URL`, so even without restarting the server, the Telegram webhook and `/` command menu for active projects you add/edit in the admin UI are refreshed immediately.
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
remote-coder up
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
For multi-bot setups, you can also pass just the public HTTPS Base URL to register the webhook and command menu for each active project with `python scripts/set_webhook.py <URL>`.
|
|
407
|
+
|
|
408
|
+
On Windows PowerShell you can use the following script:
|
|
409
|
+
|
|
410
|
+
```powershell
|
|
411
|
+
.\run.ps1
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Or use the batch wrapper that auto-bypasses the PowerShell execution policy:
|
|
415
|
+
|
|
416
|
+
```bat
|
|
417
|
+
run.bat
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
On Windows, `ngrok.exe` must be installed and runnable from PATH before running. Verify:
|
|
421
|
+
|
|
422
|
+
```powershell
|
|
423
|
+
ngrok version
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
- After running the script, just message the bot on Telegram and it works.
|
|
427
|
+
- Press `Ctrl+C` to stop the server, which also terminates ngrok.
|
|
428
|
+
|
|
429
|
+
## 4) Supported commands (MVP)
|
|
430
|
+
|
|
431
|
+
Refreshing the Telegram registration with `remote-coder up` or `python scripts/set_webhook.py <URL>` registers the same `/` command menu on each project bot that you would configure in BotFather.
|
|
432
|
+
|
|
433
|
+
- `/start` : Inline menu hub (shortcut buttons for model, monitor, clear, admin items)
|
|
434
|
+
- `/help` : Command help (inline buttons for model, monitor, clear items)
|
|
435
|
+
- `/model` : Show the default model (select via inline buttons)
|
|
436
|
+
- `/model claude` : Change this chat's default model to claude
|
|
437
|
+
- `/model codex` : Change this chat's default model to codex
|
|
438
|
+
- `/model gemini` : Change this chat's default model to gemini
|
|
439
|
+
- `/status` : Select from the recent Job list via inline buttons
|
|
440
|
+
- `/status <job_id>` : Query job status
|
|
441
|
+
- `/init` : Reset this chat's default-model override, `/clear`, and natural-language Job confirmation-pending state (the bot-bound project is unchanged; SQLite and Git are untouched)
|
|
442
|
+
- `/reports` : SQL-aggregate the SQLite conversation memory for the current chat + current working project into a summary report
|
|
443
|
+
- `/branch` : Show the currently checked-out branch of this chat's **bound project** repository
|
|
444
|
+
- `/branch <name>` : `git switch` only when a local branch exists in the bound project (errors if missing; does not auto-create branches that exist only on the remote)
|
|
445
|
+
- `/pull` : Fetch all branch info from the remote and pull the current branch. Also attempts fast-forward updates for other local branches (including main) that are not checked out.
|
|
446
|
+
- `/rebase` : Select a branch that exists both locally and on the remote (excluding main/master) via inline buttons, then rebase onto `main` (or `master`) → fast-forward merge → push to remote
|
|
447
|
+
- `/rebase <branch>` : Rebase a directly specified branch
|
|
448
|
+
- `/pr` : Select a local branch via inline buttons and create a GitHub Pull Request. The PR body includes the requests and AI results exchanged while working on that branch. Requires the GitHub CLI (`gh`) (`gh auth login`).
|
|
449
|
+
- `/pr <branch>` : Create a PR for a directly specified branch
|
|
450
|
+
- `/clear branch` : Clean up `remote-*` local/remote branches and their linked worktrees, **only in this bot's bound project**
|
|
451
|
+
- `/clear worktrees` : Clean up the managed worktrees of **this bot's project** + prune stale entries
|
|
452
|
+
- `/clear memory` : Delete only the conversation memory (SQLite) of **this bot's project + the current chat**
|
|
453
|
+
- `/stop` : Select an in-progress Job from a list via inline buttons to cancel it
|
|
454
|
+
- `/stop <job_id>` : Force-stop the specified Job (only for queued/running states)
|
|
455
|
+
- `/fix` : Rework a previous Job's commit message (`commit`) or source (`source`). Overwrites the existing commit with `git commit --amend` and reflects it to the remote with `git push --force-with-lease`. The commit trailer `committed by remote-coder: <id>` keeps the **original Job ID**.
|
|
456
|
+
- `/fix commit <job_id>` : Regenerate only the AI commit message and preview it → amend on `y`/`Y` confirmation
|
|
457
|
+
- `/fix source <job_id>` : Take a follow-up message as fix instructions and re-run the AI in the same branch worktree → amend + push on `y`/`Y` confirmation
|
|
458
|
+
- Replying to a previous bot message with `fix: <instruction>` (or `수정: <instruction>`) immediately shows a source-mode fix confirmation for that Job. The target Job must be in `SUCCEEDED + branch + commit` state.
|
|
459
|
+
- `/monitor model` : Based on the current chat's default model, a CLI probe (Claude `claude auth status` / Codex `codex --version` / Gemini `gemini --version`) plus a usage summary observed from local CLI logs. If a Codex session log has `rate_limits`, it shows the 5-hour/weekly remaining rates and reset times; Claude/Gemini show per-model token/request details from local transcript/chat logs.
|
|
460
|
+
- `/monitor memory` : SQLite conversation-memory row counts, rows per role, and DB file size for this chat + current **bound project**
|
|
461
|
+
- `/monitor branch` : Branch summary of the bound project repository (local/remote counts and lists)
|
|
462
|
+
- `/monitor worktrees` : Linked worktree list, detached count, and Remote Coder managed candidate summary
|
|
463
|
+
- `/monitor code` : Estimated code file/line counts based on the bound project root (extension whitelist; excludes `.git`, `node_modules`, etc.)
|
|
464
|
+
- `/monitor project` : Summary of the project record **bound to this bot** (name, enabled state, path, default model, worktree directory)
|
|
465
|
+
- Natural-language message: After agent/plan/ask parsing succeeds, it shows the current project, working branch, model in use, and mode, then creates an AI task (Job) after receiving `y`/`Y` (or an inline confirmation button when advanced settings enable it). Messages starting with the `plan:`/`ask:`/`계획:`/`질문:` prefix (colon `:` or `:`) or `/plan`/`/ask` run in **read-only** plan/ask mode and do not commit/push when the Job runs.
|
|
466
|
+
|
|
467
|
+
e.g. `plan: just outline how to refactor the login flow`, `/plan model: codex risks only`, `ask: what's the test command in this repo?`, `/ask the role of JobManager`
|
|
468
|
+
|
|
469
|
+
Notes:
|
|
470
|
+
|
|
471
|
+
- A per-chat default model overridden with `/model` is in-memory. On server restart it reverts to the project's `default_model` in the registry.
|
|
472
|
+
- The **bound project is always the name bound to this bot instance**. **`/branch`, `/rebase`, `/monitor memory|branch|worktrees|code|project`, etc. operate against that repository.**
|
|
473
|
+
- `/init` reverts the per-chat model override and confirmation-pending state (without touching the conversation-memory SQLite or Git repository).
|
|
474
|
+
- An AI Job creates a detached worktree from the **current `HEAD` commit** of the **project repository used for the request**, then runs. It creates a working branch and commits **only when the working tree has changes**. If there is a commit, it pushes to `GIT_REMOTE_NAME` (default `origin`). To change the repository branch, switch the local branch first with `/branch <name>`.
|
|
475
|
+
- Auto-generated commit messages use the following format:
|
|
476
|
+
|
|
477
|
+
```text
|
|
478
|
+
type: title
|
|
479
|
+
- contents1
|
|
480
|
+
- contents2
|
|
481
|
+
|
|
482
|
+
committed by remote-coder: job-id
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
`title` summarizes the functional change in one line, and the first body item describes what the AI agent changed — not the user's raw request or a list of recently modified files. The list of changed files is shown separately in the Job result notification.
|
|
486
|
+
|
|
487
|
+
- In natural-language messages you can also use the tokens `model: codex`, `model: gemini`, `branch: my-branch`, `no commit`. (The `branch:` value is validated by the same rules as `/branch`. In `plan:`/`ask:` mode, `branch:` and `no commit` are ignored.)
|
|
488
|
+
- Natural-language requests do not run immediately after parsing. The confirmation message shows the current project, working branch, and model/mode, and a Job is created only after `y` or `Y` (or an inline confirmation). If a new parseable natural-language message arrives while a confirmation is pending, it silently replaces the previous pending one; if an unparseable input arrives, the pending one is canceled.
|
|
489
|
+
- **Conversation memory (SQLite)**: User messages and Job intake/result summaries accumulate in SQLite per the same Telegram chat + same working project. It persists across server restarts. If you previously sent a specific instruction and then send a short follow-up like "start the task", "go ahead", "do that", or "begin", it merges recent records into an AI instruction. If there is no context, the bot sends a guidance message.
|
|
490
|
+
- **Reply chains**: For each natural-language request sent as a reply to a previous message, the bodies of ancestor messages remaining in SQLite and the Job-result summaries linked to each message are prepended to the Codex/Claude instruction as a `[Reply chain context]` block. (Restored only if the bot received and stored those messages.)
|
|
491
|
+
- You can pass a recent display count, like `/reports 7`. The allowed range is `1–10`, default `5`.
|
|
492
|
+
- Writability is checked right after worktree creation. If the AI output contains expressions like read-only/cannot-modify and there is no Git change, it is treated as a **failure**, not a success.
|
|
493
|
+
- Task completion/failure messages include a summary of the AI execution result (`stdout`/`stderr`).
|
|
494
|
+
- The full raw output is available in the worktree log file (`WORKTREE_BASE_DIR/_logs/<job_id>.log`).
|
|
495
|
+
|
|
496
|
+
## 5) Per-model usage guides
|
|
497
|
+
|
|
498
|
+
- Multi-bot / webhook / migration: [`docs/multi-bot-setup.md`](docs/multi-bot-setup.md)
|
|
499
|
+
- Claude users: [`docs/claude-guide.md`](docs/claude-guide.md)
|
|
500
|
+
- Codex users: [`docs/codex-guide.md`](docs/codex-guide.md)
|
|
501
|
+
- Gemini users: [`docs/gemini-guide.md`](docs/gemini-guide.md)
|
|
502
|
+
- When a worktree fails as read-only: [`docs/read-only-workspace.md`](docs/read-only-workspace.md)
|
|
503
|
+
|
|
504
|
+
**Runner operation notes:** The Gemini CLI is wired primarily for non-interactive execution, so expectations may differ from an interactive TUI. The Codex CLI may restrict network or some tool calls depending on its sandbox/approval policy.
|
|
505
|
+
|
|
506
|
+
## 6) Tests
|
|
507
|
+
|
|
508
|
+
Multi-bot routing, notification isolation, and project-scoped state are covered by `tests/test_webhook_multibot.py`, `tests/test_bot_instance_manager.py`, `tests/test_project_scoped_state.py`, etc.
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
conda activate remote-coder
|
|
512
|
+
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest -q -p pytest_asyncio.plugin -p respx.fixtures
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
## 7) Public repository management
|
|
516
|
+
|
|
517
|
+
- License: [Apache License 2.0](LICENSE)
|
|
518
|
+
- How to contribute: [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
519
|
+
- Security policy: [SECURITY.md](SECURITY.md)
|
|
520
|
+
- Before opening a Pull Request, run `PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 conda run -n remote-coder pytest -q -p pytest_asyncio.plugin -p respx.fixtures`.
|