appback-remoteagent 0.13.0
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.
- package/.env.example +39 -0
- package/LICENSE +21 -0
- package/README.md +371 -0
- package/bin/remoteagent.js +2 -0
- package/dist/adapters/claude-adapter.js +78 -0
- package/dist/adapters/codex-adapter.js +241 -0
- package/dist/adapters/provider-adapter.js +1 -0
- package/dist/adapters/shell-adapter.js +44 -0
- package/dist/adapters/windows-shell.js +111 -0
- package/dist/bot.js +2135 -0
- package/dist/config.js +170 -0
- package/dist/index.js +534 -0
- package/dist/secret-helper.js +24 -0
- package/dist/services/agent-memory-service.js +737 -0
- package/dist/services/bot-management-service.js +626 -0
- package/dist/services/bridge-service.js +807 -0
- package/dist/services/local-ui-service.js +533 -0
- package/dist/services/provider-setup-service.js +284 -0
- package/dist/services/remote-shell-service.js +97 -0
- package/dist/store/file-store.js +690 -0
- package/dist/telegram-fetch.js +85 -0
- package/dist/types.js +1 -0
- package/docs/ARCHITECTURE.md +170 -0
- package/docs/COKACDIR_NOTES.md +79 -0
- package/docs/ERROR_NORMALIZATION.md +46 -0
- package/docs/MINI_APP.md +112 -0
- package/docs/MVP.md +108 -0
- package/docs/OPERATIONS.md +181 -0
- package/docs/RELEASING.md +87 -0
- package/docs/SESSION_DIRECTORY_PLAN.md +506 -0
- package/package.json +47 -0
- package/scripts/bump-version.sh +23 -0
- package/scripts/finish-claude-login.sh +48 -0
- package/scripts/install-claude.sh +6 -0
- package/scripts/install-codex.sh +8 -0
- package/scripts/install.ps1 +51 -0
- package/scripts/install.sh +101 -0
- package/scripts/mock-adapter.sh +7 -0
- package/scripts/restart-after-bot-op.sh +118 -0
- package/scripts/selftest-telegram-update.mjs +359 -0
- package/scripts/start-claude-login.sh +4 -0
- package/scripts/start.ps1 +39 -0
- package/scripts/start.sh +54 -0
- package/scripts/stop.ps1 +40 -0
- package/scripts/stop.sh +39 -0
- package/tsconfig.json +20 -0
package/.env.example
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
TELEGRAM_BOT_TOKEN=your-telegram-bot-token
|
|
2
|
+
TELEGRAM_BOT_TOKENS=
|
|
3
|
+
TELEGRAM_MAIN_BOT_ID=
|
|
4
|
+
TELEGRAM_OWNER_ID=
|
|
5
|
+
TELEGRAM_MESSAGE_BATCH_MS=1500
|
|
6
|
+
TELEGRAM_AUTO_PROGRESS_MAX_TURNS=6
|
|
7
|
+
TELEGRAM_EMPTY_RESPONSE_RETRIES=1
|
|
8
|
+
TELEGRAM_RETRYABLE_ERROR_RETRIES=2
|
|
9
|
+
TELEGRAM_RETRYABLE_ERROR_DELAY_MS=5000
|
|
10
|
+
TELEGRAM_UNTAGGED_INTENT_RETRIES=2
|
|
11
|
+
ARTIFACT_CLEANUP_ENABLED=true
|
|
12
|
+
ARTIFACT_RETENTION_DAYS=30
|
|
13
|
+
ARTIFACT_CLEANUP_INTERVAL_MS=86400000
|
|
14
|
+
REMOTEAGENT_WATCHDOG_ENABLED=true
|
|
15
|
+
REMOTEAGENT_WATCHDOG_INTERVAL_MS=300000
|
|
16
|
+
REMOTEAGENT_WATCHDOG_CPU_PERCENT=90
|
|
17
|
+
REMOTEAGENT_WATCHDOG_MIN_AGE_MS=120000
|
|
18
|
+
DATA_DIR=
|
|
19
|
+
DEFAULT_WORKSPACE=
|
|
20
|
+
WORKSPACE_ROOT=
|
|
21
|
+
DEFAULT_MODE=codex
|
|
22
|
+
COMMAND_TIMEOUT_MS=600000
|
|
23
|
+
SETUP_COMMAND_TIMEOUT_MS=600000
|
|
24
|
+
CODEX_BIN=codex
|
|
25
|
+
CODEX_SANDBOX_MODE=
|
|
26
|
+
CODEX_COMMAND=
|
|
27
|
+
CODEX_INSTALL_COMMAND=
|
|
28
|
+
CLAUDE_BIN=claude
|
|
29
|
+
CLAUDE_COMMAND=
|
|
30
|
+
CLAUDE_PERMISSION_MODE=bypassPermissions
|
|
31
|
+
CLAUDE_INSTALL_COMMAND=
|
|
32
|
+
CLAUDE_LOGIN_START_COMMAND=
|
|
33
|
+
CLAUDE_LOGIN_FINISH_COMMAND=
|
|
34
|
+
LOCAL_UI_ENABLED=true
|
|
35
|
+
LOCAL_UI_HOST=127.0.0.1
|
|
36
|
+
LOCAL_UI_PORT=3794
|
|
37
|
+
|
|
38
|
+
REMOTEAGENT_SERVICE_NAME=remoteagent
|
|
39
|
+
BOT_RESTART_HELPER_PATH=
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 appback
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# RemoteAgent
|
|
2
|
+
|
|
3
|
+
RemoteAgent is a personal installable runtime for controlling coding sessions from Telegram, a terminal, and an optional Telegram Mini App.
|
|
4
|
+
|
|
5
|
+
It is built for one owner running their own agents on their own machine, then continuing that work remotely without introducing a hosted multi-user backend.
|
|
6
|
+
|
|
7
|
+
## What it is
|
|
8
|
+
|
|
9
|
+
RemoteAgent is not a hosted SaaS and not a Telegram-only app.
|
|
10
|
+
|
|
11
|
+
It has three layers:
|
|
12
|
+
|
|
13
|
+
1. **Runtime server** - the installed machine that actually runs Codex, Claude Code, shell commands, and file operations.
|
|
14
|
+
2. **Telegram bot** - the default remote messaging interface.
|
|
15
|
+
3. **Telegram Mini App** - an optional richer UI that opens inside Telegram and controls the same runtime.
|
|
16
|
+
|
|
17
|
+
The runtime machine is the source of truth. Telegram is the client.
|
|
18
|
+
|
|
19
|
+
## What it does
|
|
20
|
+
|
|
21
|
+
RemoteAgent is currently organized around six core capabilities.
|
|
22
|
+
|
|
23
|
+
| Capability | What it means today | Status |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| Telegram control | Telegram chat can start, attach, switch, inspect, and reset local sessions | Supported |
|
|
26
|
+
| Terminal control | The owner can run restricted remote shell commands from Telegram | Supported with restrictions |
|
|
27
|
+
| Telegram <-> Codex | A Telegram chat can start or attach to a Codex session and continue it | Supported |
|
|
28
|
+
| Telegram <-> Claude Code | A Telegram chat can start or attach to a Claude Code session and continue it | Supported |
|
|
29
|
+
| Telegram attachments | Telegram can send images, text, Markdown, PDF, Word documents, spreadsheet files, archives, and audio/voice inputs into the runtime | Supported |
|
|
30
|
+
| Telegram Mini App UI | A richer Telegram-native UI can sit on top of the same runtime and session model | Planned next |
|
|
31
|
+
|
|
32
|
+
## Product direction
|
|
33
|
+
|
|
34
|
+
RemoteAgent is a self-hosted personal runtime, not a hosted SaaS.
|
|
35
|
+
|
|
36
|
+
The intended shape is:
|
|
37
|
+
|
|
38
|
+
1. the machine running RemoteAgent is the source of truth
|
|
39
|
+
2. Telegram chat is the baseline remote client for that runtime
|
|
40
|
+
3. a Telegram Mini App is an optional UI layer over the same runtime
|
|
41
|
+
4. Codex and Claude Code are provider adapters behind one local session model
|
|
42
|
+
5. terminal control is an owner-only extension of that same runtime
|
|
43
|
+
6. files sent from Telegram are materialized locally and then routed through the active session
|
|
44
|
+
|
|
45
|
+
This repository is optimized for continuity:
|
|
46
|
+
|
|
47
|
+
- start work on the machine
|
|
48
|
+
- continue from Telegram
|
|
49
|
+
- optionally open a Mini App for richer session controls
|
|
50
|
+
- come back and keep going from the same runtime-owned session state
|
|
51
|
+
|
|
52
|
+
## Why a Mini App fits
|
|
53
|
+
|
|
54
|
+
A Telegram Mini App does **not** replace the runtime server.
|
|
55
|
+
It gives RemoteAgent a better control surface inside Telegram.
|
|
56
|
+
|
|
57
|
+
That means a Mini App can expose:
|
|
58
|
+
|
|
59
|
+
- session list and switching
|
|
60
|
+
- current provider and model
|
|
61
|
+
- recent logs and progress states
|
|
62
|
+
- stop and continue actions
|
|
63
|
+
- attachment history
|
|
64
|
+
- safer structured controls than raw slash commands
|
|
65
|
+
|
|
66
|
+
But the Mini App still depends on the installed RemoteAgent runtime and the local provider CLIs.
|
|
67
|
+
|
|
68
|
+
## Current scope
|
|
69
|
+
|
|
70
|
+
In scope:
|
|
71
|
+
|
|
72
|
+
- one owner
|
|
73
|
+
- one installable local runtime
|
|
74
|
+
- local session persistence
|
|
75
|
+
- Telegram control
|
|
76
|
+
- Codex and Claude Code adapters
|
|
77
|
+
- restricted terminal control
|
|
78
|
+
- Telegram attachment intake
|
|
79
|
+
- future Telegram Mini App control UI for the same runtime
|
|
80
|
+
|
|
81
|
+
Out of scope:
|
|
82
|
+
|
|
83
|
+
- multi-tenant hosted backend
|
|
84
|
+
- account resale
|
|
85
|
+
- team-facing SaaS control plane
|
|
86
|
+
- pretending to mirror official desktop apps exactly
|
|
87
|
+
- making Telegram the actual execution backend
|
|
88
|
+
|
|
89
|
+
## Current capabilities
|
|
90
|
+
|
|
91
|
+
### 1. Telegram control
|
|
92
|
+
|
|
93
|
+
Telegram is the main remote control surface today.
|
|
94
|
+
|
|
95
|
+
Current command surface implemented in `src/bot.ts`:
|
|
96
|
+
|
|
97
|
+
| Command | What it does |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| `/start [codex|claude]` | Starts a fresh fixed-mode session in a new managed workspace under `WORKSPACE_ROOT` |
|
|
100
|
+
| `/help` | Shows the current command list |
|
|
101
|
+
| `/list` | Lists recent sessions |
|
|
102
|
+
| `/list -a` | Lists all sessions with active/unused status, managed workspace size, and last update time |
|
|
103
|
+
| `/new` | Creates and binds a new session using the saved default mode in a new managed workspace |
|
|
104
|
+
| `/switch <session>` | Rebinds this chat to an existing RemoteAgent session |
|
|
105
|
+
| `/status` | Shows current session, workspace, provider, and sandbox state |
|
|
106
|
+
| `/option retry <count>` | Sets the automatic continuation turn limit and persists it to `~/.remoteagent/.env` |
|
|
107
|
+
| `/option timeout <seconds>` | Sets the provider execution timeout and persists it to `~/.remoteagent/.env` |
|
|
108
|
+
| `/option intent <count>` | Sets retries for untagged intent-only provider replies and persists it to `~/.remoteagent/.env` |
|
|
109
|
+
| `/state` | Shows the session ledger that is injected as provider context |
|
|
110
|
+
| `/state clear` | Clears the current session ledger without deleting the session |
|
|
111
|
+
| `/state note <text>` | Adds an operator note to the session ledger |
|
|
112
|
+
| `/bots` | Lists the currently configured Telegram bots |
|
|
113
|
+
| `/bot add <token>` | Adds a conversation bot, restarts the runtime, and confirms the result after restart |
|
|
114
|
+
| `/bot doctor` | Checks configured Telegram bots and removes bots that Telegram reports as permanently dead |
|
|
115
|
+
| `/bot main <number\|@username\|id>` | Selects the main bot. If no valid main is configured, the oldest configured bot is used |
|
|
116
|
+
| `/bot remove <username\|id>` | Removes a configured Telegram bot, restarts the runtime, and confirms the result after restart |
|
|
117
|
+
| `/bot reload` | Restarts the runtime and confirms the result after restart |
|
|
118
|
+
| `/install codex\|claude` | Runs the configured provider install or update command for the bot owner |
|
|
119
|
+
| `/login codex` | Starts the Codex device-auth login flow and returns a browser URL when available |
|
|
120
|
+
| `/login claude [token]` | Starts or finishes the configured Claude Code login flow for the bot owner |
|
|
121
|
+
| `/reset` | Clears the current chat binding |
|
|
122
|
+
| `/batch start` | Starts manual batching of multiple text messages |
|
|
123
|
+
| `/batch send` | Sends the collected batch |
|
|
124
|
+
| `/batch done` | Alias for `/batch send` |
|
|
125
|
+
| `/batch cancel` | Discards the current batch |
|
|
126
|
+
| `/batch status` | Shows current batch state |
|
|
127
|
+
|
|
128
|
+
### 2. Terminal control
|
|
129
|
+
|
|
130
|
+
Remote shell control is available through:
|
|
131
|
+
|
|
132
|
+
- `/! <command>`
|
|
133
|
+
- `/!cmd <command>`
|
|
134
|
+
- `/!bash <command>`
|
|
135
|
+
|
|
136
|
+
This is intentionally restricted.
|
|
137
|
+
|
|
138
|
+
Remote shell requires all of the following:
|
|
139
|
+
|
|
140
|
+
- private 1:1 Telegram chat
|
|
141
|
+
- sender matches `TELEGRAM_OWNER_ID`
|
|
142
|
+
- active Codex binding exists
|
|
143
|
+
- current Codex sandbox is `danger-full-access`
|
|
144
|
+
|
|
145
|
+
### 3. Telegram and Codex
|
|
146
|
+
|
|
147
|
+
RemoteAgent supports both fresh Codex pairing and attach/resume.
|
|
148
|
+
|
|
149
|
+
Current Codex entry commands:
|
|
150
|
+
|
|
151
|
+
- `/start codex`
|
|
152
|
+
- `/attach codex <thread_id>`
|
|
153
|
+
- `/sandbox codex <read-only|workspace-write|danger-full-access>`
|
|
154
|
+
|
|
155
|
+
Current Codex behavior:
|
|
156
|
+
|
|
157
|
+
- fresh pairing from Telegram
|
|
158
|
+
- attach to existing `thread_id`
|
|
159
|
+
- continue the same Codex session across turns
|
|
160
|
+
- per-session sandbox selection
|
|
161
|
+
|
|
162
|
+
### 4. Telegram and Claude Code
|
|
163
|
+
|
|
164
|
+
RemoteAgent also supports fresh Claude Code pairing and attach/resume.
|
|
165
|
+
|
|
166
|
+
Current Claude entry commands:
|
|
167
|
+
|
|
168
|
+
- `/start claude`
|
|
169
|
+
- `/attach claude <session_id>`
|
|
170
|
+
|
|
171
|
+
Current Claude behavior:
|
|
172
|
+
|
|
173
|
+
- fresh pairing from Telegram
|
|
174
|
+
- attach to existing `session_id`
|
|
175
|
+
- continue the same Claude Code session across turns
|
|
176
|
+
- optional owner-only install/login flow through `/install claude` and `/login claude [token]`
|
|
177
|
+
|
|
178
|
+
### 5. Telegram attachments
|
|
179
|
+
|
|
180
|
+
Telegram attachments are written into the local runtime under `~/.remoteagent/uploads/telegram/<bot>/<chat>/...` and then routed through the active session. Artifact metadata is indexed at `~/.remoteagent/managed/artifacts.json`.
|
|
181
|
+
|
|
182
|
+
Attachments can be inspected with `/artifacts list` and cleaned manually with `/artifacts cleanup <days>`. RemoteAgent also runs periodic artifact cleanup when `ARTIFACT_CLEANUP_ENABLED=true`; by default it keeps 30 days and also removes old unindexed files under `uploads/telegram`.
|
|
183
|
+
|
|
184
|
+
Current supported attachment classes:
|
|
185
|
+
|
|
186
|
+
- photos
|
|
187
|
+
- image files
|
|
188
|
+
- text files
|
|
189
|
+
- Markdown files
|
|
190
|
+
- PDF documents
|
|
191
|
+
- Word documents (.docx, basic .doc intake)
|
|
192
|
+
- spreadsheet files (.xlsx, .xlsm, basic .xls intake)
|
|
193
|
+
- archive files
|
|
194
|
+
- voice messages
|
|
195
|
+
- audio files
|
|
196
|
+
|
|
197
|
+
Attachment handling is triggered from ordinary Telegram messages.
|
|
198
|
+
If the message contains a supported file or media payload, RemoteAgent downloads it, stores it locally, builds an attachment prompt, and sends that into the active provider session.
|
|
199
|
+
|
|
200
|
+
### 6. Telegram Mini App
|
|
201
|
+
|
|
202
|
+
The Mini App is the next UI layer, not a second execution engine.
|
|
203
|
+
|
|
204
|
+
The Mini App should talk to the same runtime state used by the bot, including:
|
|
205
|
+
|
|
206
|
+
- session ids
|
|
207
|
+
- session bindings
|
|
208
|
+
- provider metadata
|
|
209
|
+
- event logs
|
|
210
|
+
- attachment history
|
|
211
|
+
- stop and continue controls
|
|
212
|
+
|
|
213
|
+
See [docs/MINI_APP.md](docs/MINI_APP.md) for the planned Mini App shape.
|
|
214
|
+
|
|
215
|
+
## Provider support matrix
|
|
216
|
+
|
|
217
|
+
| Capability | Codex | Claude Code | OpenClaw |
|
|
218
|
+
| --- | --- | --- | --- |
|
|
219
|
+
| Fresh Telegram pairing | Yes | Yes | Planned |
|
|
220
|
+
| Attach to existing session | Yes | Yes | Planned |
|
|
221
|
+
| Resume same session across turns | Yes | Yes | Planned |
|
|
222
|
+
| Telegram-based remote shell participation | Yes | No | Planned |
|
|
223
|
+
| Per-session sandbox control from Telegram | Yes | No | Planned |
|
|
224
|
+
| Attachment routing through active session | Yes | Yes | Planned |
|
|
225
|
+
| Telegram Mini App control surface | Planned | Planned | Planned |
|
|
226
|
+
| Production adapter in this repo | Yes | Yes | No |
|
|
227
|
+
|
|
228
|
+
## Release policy
|
|
229
|
+
|
|
230
|
+
Every production deployment must bump the package version using semantic versioning.
|
|
231
|
+
|
|
232
|
+
- `MAJOR`: breaking changes or migration-required runtime changes
|
|
233
|
+
- `MINOR`: new capabilities or non-breaking feature expansion
|
|
234
|
+
- `PATCH`: bug fixes, hardening, and maintenance updates
|
|
235
|
+
|
|
236
|
+
A change is not considered finished until it is committed and pushed.
|
|
237
|
+
A deployment on server 30 is not considered complete until machine 21's npm-installed runtime is updated as well.
|
|
238
|
+
|
|
239
|
+
See [docs/RELEASING.md](docs/RELEASING.md) for the release checklist and version bump commands.
|
|
240
|
+
See [docs/ERROR_NORMALIZATION.md](docs/ERROR_NORMALIZATION.md) for provider error classification and retry behavior.
|
|
241
|
+
|
|
242
|
+
## Runtime layout
|
|
243
|
+
|
|
244
|
+
Installed runtime data lives in:
|
|
245
|
+
|
|
246
|
+
- Linux/macOS: `~/.remoteagent`
|
|
247
|
+
- Windows: `%USERPROFILE%\.remoteagent`
|
|
248
|
+
|
|
249
|
+
Typical directories and files include:
|
|
250
|
+
|
|
251
|
+
Managed workspaces created by `/start` without an explicit path live under `WORKSPACE_ROOT` and use random 8-character uid folder names, while public session ids like `S001` remain display-only ids.
|
|
252
|
+
|
|
253
|
+
- `.env`
|
|
254
|
+
- `logs/`
|
|
255
|
+
- `uploads/telegram/`
|
|
256
|
+
- `sessions/`
|
|
257
|
+
- `channels/telegram/`
|
|
258
|
+
- `state.json`
|
|
259
|
+
|
|
260
|
+
## Environment
|
|
261
|
+
|
|
262
|
+
Useful runtime variables:
|
|
263
|
+
|
|
264
|
+
Provider install/login hooks are optional and are executed only from owner-only Telegram commands.
|
|
265
|
+
|
|
266
|
+
Recommended Linux hooks in this repo:
|
|
267
|
+
|
|
268
|
+
- `scripts/install-codex.sh`
|
|
269
|
+
- `scripts/install-claude.sh`
|
|
270
|
+
- `scripts/start-claude-login.sh`
|
|
271
|
+
- `scripts/finish-claude-login.sh`
|
|
272
|
+
|
|
273
|
+
- `TELEGRAM_BOT_TOKEN`
|
|
274
|
+
- `TELEGRAM_BOT_TOKENS`
|
|
275
|
+
- `TELEGRAM_OWNER_ID`
|
|
276
|
+
- `DEFAULT_WORKSPACE`
|
|
277
|
+
- `WORKSPACE_ROOT`
|
|
278
|
+
- `COMMAND_TIMEOUT_MS`
|
|
279
|
+
- `SETUP_COMMAND_TIMEOUT_MS`
|
|
280
|
+
- `ARTIFACT_CLEANUP_ENABLED`
|
|
281
|
+
- `ARTIFACT_RETENTION_DAYS`
|
|
282
|
+
- `ARTIFACT_CLEANUP_INTERVAL_MS`
|
|
283
|
+
- `CODEX_BIN`
|
|
284
|
+
- `CODEX_SANDBOX_MODE`
|
|
285
|
+
- `CODEX_INSTALL_COMMAND`
|
|
286
|
+
- `CLAUDE_BIN`
|
|
287
|
+
- `CLAUDE_COMMAND`
|
|
288
|
+
- `CLAUDE_PERMISSION_MODE`
|
|
289
|
+
- `CLAUDE_INSTALL_COMMAND`
|
|
290
|
+
- `CLAUDE_LOGIN_START_COMMAND`
|
|
291
|
+
- `CLAUDE_LOGIN_FINISH_COMMAND`
|
|
292
|
+
- `REMOTEAGENT_SERVICE_NAME`
|
|
293
|
+
- `BOT_RESTART_HELPER_PATH`
|
|
294
|
+
- `LOCAL_UI_ENABLED`
|
|
295
|
+
- `LOCAL_UI_HOST`
|
|
296
|
+
- `LOCAL_UI_PORT`
|
|
297
|
+
|
|
298
|
+
## Quick start
|
|
299
|
+
|
|
300
|
+
### Linux / macOS
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
npm install -g appback-remoteagent
|
|
304
|
+
remoteagent-install
|
|
305
|
+
remoteagent-start
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
`remoteagent-install` seeds provider install/login hook paths into `~/.remoteagent/.env` automatically, so `/install codex` and `/install claude` work on a fresh machine without manual hook wiring.
|
|
309
|
+
|
|
310
|
+
For one-line installs on a fresh machine:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
curl -fsSL https://raw.githubusercontent.com/appback/remoteagent/main/scripts/install.sh | bash
|
|
314
|
+
remoteagent-start
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
The piped installer installs `appback-remoteagent` from npm. It does not deploy a Git checkout as the runtime.
|
|
318
|
+
|
|
319
|
+
### Windows PowerShell
|
|
320
|
+
|
|
321
|
+
Native Windows service packaging is not finalized yet. For now, use WSL/Linux for production runtimes, or run the repository-local PowerShell scripts during development:
|
|
322
|
+
|
|
323
|
+
```powershell
|
|
324
|
+
.\scripts\install.ps1
|
|
325
|
+
.\scripts\start.ps1
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
The installer also writes default provider install/login hook paths into `%USERPROFILE%\.remoteagent\.env`.
|
|
329
|
+
|
|
330
|
+
After `/install codex` or `/install claude`, RemoteAgent now also checks whether the provider still needs authentication and tells the operator the next login step.
|
|
331
|
+
|
|
332
|
+
Then open Telegram and start with one of these common flows. `/start` without a mode uses the saved default mode once a provider has been started or attached at least once.
|
|
333
|
+
|
|
334
|
+
```text
|
|
335
|
+
/start
|
|
336
|
+
/start codex
|
|
337
|
+
/start claude
|
|
338
|
+
/install codex
|
|
339
|
+
/install claude
|
|
340
|
+
/login codex
|
|
341
|
+
/login claude
|
|
342
|
+
/login claude <token>
|
|
343
|
+
/attach codex <thread_id>
|
|
344
|
+
/attach claude <session_id>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Once a chat is bound, ordinary text messages continue the active session. Supported attachments can also be sent directly as normal Telegram messages.
|
|
348
|
+
|
|
349
|
+
## Architecture and operations
|
|
350
|
+
|
|
351
|
+
High-level architecture: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
|
|
352
|
+
|
|
353
|
+
Mini App plan: [docs/MINI_APP.md](docs/MINI_APP.md)
|
|
354
|
+
|
|
355
|
+
MVP scope: [docs/MVP.md](docs/MVP.md)
|
|
356
|
+
|
|
357
|
+
Operational ownership and deployment rules: [docs/OPERATIONS.md](docs/OPERATIONS.md)
|
|
358
|
+
|
|
359
|
+
Reference notes about `cokacdir`: [docs/COKACDIR_NOTES.md](docs/COKACDIR_NOTES.md)
|
|
360
|
+
|
|
361
|
+
## Development
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
npm install
|
|
365
|
+
npm run check
|
|
366
|
+
npm run build
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## License
|
|
370
|
+
|
|
371
|
+
This project is licensed under the MIT License. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { spawnWithPlatformShell } from "./windows-shell.js";
|
|
3
|
+
export class ClaudeAdapter {
|
|
4
|
+
claudeBin;
|
|
5
|
+
timeoutMs;
|
|
6
|
+
permissionMode;
|
|
7
|
+
constructor(claudeBin, timeoutMs, permissionMode) {
|
|
8
|
+
this.claudeBin = claudeBin;
|
|
9
|
+
this.timeoutMs = timeoutMs;
|
|
10
|
+
this.permissionMode = permissionMode;
|
|
11
|
+
}
|
|
12
|
+
async send(request) {
|
|
13
|
+
const sessionId = request.sessionId ?? randomUUID();
|
|
14
|
+
const args = this.buildArgs(request, sessionId);
|
|
15
|
+
const { stdout, stderr, code, timedOut } = await this.runClaude(args, request.cwd, request.remoteSessionId, request.publicSessionId);
|
|
16
|
+
if (code !== 0) {
|
|
17
|
+
throw new Error(this.formatProcessError(stdout, stderr, timedOut));
|
|
18
|
+
}
|
|
19
|
+
if (timedOut) {
|
|
20
|
+
throw new Error(this.formatTimeoutError());
|
|
21
|
+
}
|
|
22
|
+
const output = stdout.trim();
|
|
23
|
+
if (!output) {
|
|
24
|
+
throw new Error("Claude returned an empty response.");
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
provider: "claude",
|
|
28
|
+
sessionId,
|
|
29
|
+
cwd: request.cwd,
|
|
30
|
+
output,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
buildArgs(request, sessionId) {
|
|
34
|
+
const args = [
|
|
35
|
+
"--print",
|
|
36
|
+
"--output-format",
|
|
37
|
+
"text",
|
|
38
|
+
"--permission-mode",
|
|
39
|
+
this.permissionMode,
|
|
40
|
+
];
|
|
41
|
+
if (request.model) {
|
|
42
|
+
args.push("--model", request.model);
|
|
43
|
+
}
|
|
44
|
+
if (request.sessionId) {
|
|
45
|
+
args.push("--resume", sessionId, request.message);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
args.push("--session-id", sessionId, request.message);
|
|
49
|
+
}
|
|
50
|
+
return args;
|
|
51
|
+
}
|
|
52
|
+
runClaude(args, cwd, remoteSessionId, publicSessionId) {
|
|
53
|
+
return spawnWithPlatformShell(this.claudeBin, args, cwd, this.currentTimeoutMs(), undefined, remoteSessionId, {
|
|
54
|
+
REMOTEAGENT_SESSION_ID: remoteSessionId,
|
|
55
|
+
REMOTEAGENT_PUBLIC_SESSION_ID: publicSessionId ?? "",
|
|
56
|
+
REMOTEAGENT_WORKSPACE: cwd,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
formatProcessError(stdout, stderr, timedOut = false) {
|
|
60
|
+
const text = [stderr, stdout]
|
|
61
|
+
.map((value) => value.trim())
|
|
62
|
+
.filter(Boolean)
|
|
63
|
+
.join("\n")
|
|
64
|
+
.trim();
|
|
65
|
+
if (text) {
|
|
66
|
+
return text;
|
|
67
|
+
}
|
|
68
|
+
return timedOut
|
|
69
|
+
? this.formatTimeoutError()
|
|
70
|
+
: "Claude execution failed without any output.";
|
|
71
|
+
}
|
|
72
|
+
formatTimeoutError() {
|
|
73
|
+
return `Claude timed out after ${Math.round(this.currentTimeoutMs() / 1000)}s without returning a final reply.`;
|
|
74
|
+
}
|
|
75
|
+
currentTimeoutMs() {
|
|
76
|
+
return typeof this.timeoutMs === "function" ? this.timeoutMs() : this.timeoutMs;
|
|
77
|
+
}
|
|
78
|
+
}
|