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
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import https from "node:https";
|
|
3
|
+
import { URL } from "node:url";
|
|
4
|
+
function normalizeBody(body) {
|
|
5
|
+
if (body == null) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
if (typeof body === "string") {
|
|
9
|
+
return Buffer.from(body, "utf8");
|
|
10
|
+
}
|
|
11
|
+
if (body instanceof URLSearchParams) {
|
|
12
|
+
return Buffer.from(body.toString(), "utf8");
|
|
13
|
+
}
|
|
14
|
+
if (Buffer.isBuffer(body)) {
|
|
15
|
+
return body;
|
|
16
|
+
}
|
|
17
|
+
if (ArrayBuffer.isView(body)) {
|
|
18
|
+
return Buffer.from(body.buffer, body.byteOffset, body.byteLength);
|
|
19
|
+
}
|
|
20
|
+
if (body instanceof ArrayBuffer) {
|
|
21
|
+
return Buffer.from(body);
|
|
22
|
+
}
|
|
23
|
+
throw new TypeError("Unsupported fetch body type.");
|
|
24
|
+
}
|
|
25
|
+
export async function telegramFetch(input, init) {
|
|
26
|
+
const target = new URL(typeof input === "string"
|
|
27
|
+
? input
|
|
28
|
+
: input instanceof URL
|
|
29
|
+
? input.toString()
|
|
30
|
+
: input.url);
|
|
31
|
+
const requestInit = init ?? {};
|
|
32
|
+
const method = requestInit.method ?? (input instanceof Request ? input.method : "GET");
|
|
33
|
+
const headers = new Headers(input instanceof Request ? input.headers : undefined);
|
|
34
|
+
if (requestInit.headers) {
|
|
35
|
+
const extra = new Headers(requestInit.headers);
|
|
36
|
+
extra.forEach((value, key) => headers.set(key, value));
|
|
37
|
+
}
|
|
38
|
+
const rawBody = requestInit.body ?? (input instanceof Request ? await input.arrayBuffer() : undefined);
|
|
39
|
+
const body = normalizeBody(rawBody);
|
|
40
|
+
if (body && !headers.has("content-length")) {
|
|
41
|
+
headers.set("content-length", String(body.byteLength));
|
|
42
|
+
}
|
|
43
|
+
return await new Promise((resolve, reject) => {
|
|
44
|
+
const client = target.protocol === "http:" ? http : https;
|
|
45
|
+
const req = client.request(target, {
|
|
46
|
+
method,
|
|
47
|
+
headers: Object.fromEntries(headers.entries()),
|
|
48
|
+
}, (res) => {
|
|
49
|
+
const chunks = [];
|
|
50
|
+
res.on("data", (chunk) => {
|
|
51
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
52
|
+
});
|
|
53
|
+
res.on("end", () => {
|
|
54
|
+
const responseHeaders = new Headers();
|
|
55
|
+
for (const [key, value] of Object.entries(res.headers)) {
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
responseHeaders.set(key, value.join(", "));
|
|
58
|
+
}
|
|
59
|
+
else if (value !== undefined) {
|
|
60
|
+
responseHeaders.set(key, value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
resolve(new Response(Buffer.concat(chunks), {
|
|
64
|
+
status: res.statusCode ?? 500,
|
|
65
|
+
statusText: res.statusMessage ?? "",
|
|
66
|
+
headers: responseHeaders,
|
|
67
|
+
}));
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
req.on("error", reject);
|
|
71
|
+
if (requestInit.signal) {
|
|
72
|
+
if (requestInit.signal.aborted) {
|
|
73
|
+
req.destroy(new Error("The operation was aborted."));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
requestInit.signal.addEventListener("abort", () => {
|
|
77
|
+
req.destroy(new Error("The operation was aborted."));
|
|
78
|
+
}, { once: true });
|
|
79
|
+
}
|
|
80
|
+
if (body) {
|
|
81
|
+
req.write(body);
|
|
82
|
+
}
|
|
83
|
+
req.end();
|
|
84
|
+
});
|
|
85
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Intent
|
|
4
|
+
|
|
5
|
+
RemoteAgent is a personal installable runtime for six primary jobs:
|
|
6
|
+
|
|
7
|
+
1. Telegram control
|
|
8
|
+
2. terminal control
|
|
9
|
+
3. Telegram to Codex session continuity
|
|
10
|
+
4. Telegram to Claude Code session continuity
|
|
11
|
+
5. Telegram attachment intake for images, documents, and related files
|
|
12
|
+
6. Telegram Mini App UI over the same runtime state
|
|
13
|
+
|
|
14
|
+
The runtime machine is the source of truth.
|
|
15
|
+
Telegram is a client of that runtime, not the owner of the session state.
|
|
16
|
+
The Mini App is a richer client of the same runtime, not a separate backend.
|
|
17
|
+
|
|
18
|
+
## Core principles
|
|
19
|
+
|
|
20
|
+
1. One owner, one runtime, local control.
|
|
21
|
+
2. Sessions belong to the local runtime.
|
|
22
|
+
3. Telegram chat is a remote control surface over those sessions.
|
|
23
|
+
4. A Telegram Mini App is an optional structured UI over the same sessions.
|
|
24
|
+
5. Codex and Claude Code are adapters behind a shared local session model.
|
|
25
|
+
6. Terminal control is gated and attached to runtime-owned session state.
|
|
26
|
+
7. Telegram attachments are materialized locally before provider routing.
|
|
27
|
+
8. Process ownership must remain single-instance and deterministic.
|
|
28
|
+
|
|
29
|
+
## System shape
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
Telegram chat client Telegram Mini App UI
|
|
33
|
+
\ /
|
|
34
|
+
\ /
|
|
35
|
+
-> RemoteAgent runtime on the owner machine
|
|
36
|
+
-> session store
|
|
37
|
+
-> chat/session bindings
|
|
38
|
+
-> event logs
|
|
39
|
+
-> attachment store
|
|
40
|
+
-> provider router
|
|
41
|
+
-> owner-only terminal gateway
|
|
42
|
+
-> Codex adapter
|
|
43
|
+
-> Claude Code adapter
|
|
44
|
+
-> future providers
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Main subsystems
|
|
48
|
+
|
|
49
|
+
### Telegram control layer
|
|
50
|
+
|
|
51
|
+
Responsibilities:
|
|
52
|
+
|
|
53
|
+
- accept Telegram commands and messages
|
|
54
|
+
- bind chats to runtime sessions
|
|
55
|
+
- expose status/list/switch/reset flows
|
|
56
|
+
- accept attachments and route them to the active session
|
|
57
|
+
- gate privileged commands such as remote shell
|
|
58
|
+
|
|
59
|
+
### Telegram Mini App layer
|
|
60
|
+
|
|
61
|
+
Responsibilities:
|
|
62
|
+
|
|
63
|
+
- present the same sessions in a richer UI
|
|
64
|
+
- expose session lists, status, logs, and actions without relying on raw slash commands
|
|
65
|
+
- submit structured actions back to the runtime server
|
|
66
|
+
- stay thin: no provider execution, no separate session source of truth
|
|
67
|
+
|
|
68
|
+
### Session layer
|
|
69
|
+
|
|
70
|
+
Responsibilities:
|
|
71
|
+
|
|
72
|
+
- own RemoteAgent session ids
|
|
73
|
+
- persist workspace metadata
|
|
74
|
+
- track provider bindings
|
|
75
|
+
- record append-only event history
|
|
76
|
+
- serialize work per session when needed
|
|
77
|
+
|
|
78
|
+
### Provider adapter layer
|
|
79
|
+
|
|
80
|
+
Responsibilities:
|
|
81
|
+
|
|
82
|
+
- start or continue provider sessions
|
|
83
|
+
- translate runtime requests into provider-specific commands
|
|
84
|
+
- store provider session identifiers such as Codex `thread_id` and Claude `session_id`
|
|
85
|
+
- return normalized outputs back to the runtime
|
|
86
|
+
|
|
87
|
+
### Terminal control layer
|
|
88
|
+
|
|
89
|
+
Responsibilities:
|
|
90
|
+
|
|
91
|
+
- execute owner-only shell commands in the active workspace
|
|
92
|
+
- enforce private-chat and owner-only restrictions
|
|
93
|
+
- keep terminal access tied to Codex danger-full-access mode
|
|
94
|
+
|
|
95
|
+
### Attachment layer
|
|
96
|
+
|
|
97
|
+
Responsibilities:
|
|
98
|
+
|
|
99
|
+
- download Telegram-hosted files
|
|
100
|
+
- store them under runtime-owned local paths
|
|
101
|
+
- build attachment prompts for the active provider flow
|
|
102
|
+
- keep internal runtime paths out of user-facing responses where possible
|
|
103
|
+
|
|
104
|
+
## Provider support today
|
|
105
|
+
|
|
106
|
+
| Provider | Current state | Resume identifier | Notes |
|
|
107
|
+
| --- | --- | --- | --- |
|
|
108
|
+
| Codex | Implemented | `thread_id` | Supports Telegram sandbox control and remote-shell gating |
|
|
109
|
+
| Claude Code | Implemented | `session_id` | Supports attach/resume through the same runtime model |
|
|
110
|
+
| OpenClaw | Planned | TBD | Not yet implemented |
|
|
111
|
+
|
|
112
|
+
## Mini App role
|
|
113
|
+
|
|
114
|
+
The Mini App should be treated as a control-plane UI for an already-installed runtime.
|
|
115
|
+
|
|
116
|
+
It is not:
|
|
117
|
+
|
|
118
|
+
- a replacement for the runtime server
|
|
119
|
+
- a hosted multi-tenant backend
|
|
120
|
+
- a place where provider CLIs run directly
|
|
121
|
+
|
|
122
|
+
It is:
|
|
123
|
+
|
|
124
|
+
- a Telegram-native web UI
|
|
125
|
+
- an easier way to view and manage sessions
|
|
126
|
+
- a better surface for logs, buttons, state, and attachments
|
|
127
|
+
- a future replacement for some slash-command-heavy workflows
|
|
128
|
+
|
|
129
|
+
## Operational constraints
|
|
130
|
+
|
|
131
|
+
The runtime must behave as a single owned process.
|
|
132
|
+
|
|
133
|
+
That means:
|
|
134
|
+
|
|
135
|
+
- `systemd` owns the production runtime on server 30
|
|
136
|
+
- ad hoc duplicate `node dist/index.js` processes must not coexist
|
|
137
|
+
- stale PID and stale lock state must not become the effective source of truth
|
|
138
|
+
- image and attachment incidents must be debugged against one live process generation, not many
|
|
139
|
+
|
|
140
|
+
The production operating rules are documented in [OPERATIONS.md](./OPERATIONS.md).
|
|
141
|
+
|
|
142
|
+
## Current status
|
|
143
|
+
|
|
144
|
+
Stable today:
|
|
145
|
+
|
|
146
|
+
- Telegram control
|
|
147
|
+
- owner-only terminal control
|
|
148
|
+
- Telegram <-> Codex session handling
|
|
149
|
+
- Telegram <-> Claude Code session handling
|
|
150
|
+
- Telegram attachment download and local materialization
|
|
151
|
+
- single-instance runtime locking on server 30
|
|
152
|
+
|
|
153
|
+
Planned next:
|
|
154
|
+
|
|
155
|
+
- Telegram Mini App UI over existing runtime state
|
|
156
|
+
- structured session controls in Telegram beyond slash commands
|
|
157
|
+
- richer attachment and log inspection UX
|
|
158
|
+
|
|
159
|
+
Still improving:
|
|
160
|
+
|
|
161
|
+
- attachment response policy and user-facing output quality
|
|
162
|
+
- broader inspection and debugging UX
|
|
163
|
+
- future local PC chat UI maturity
|
|
164
|
+
|
|
165
|
+
## Non-goals
|
|
166
|
+
|
|
167
|
+
- hosted multi-tenant control plane
|
|
168
|
+
- account pooling or resale
|
|
169
|
+
- pretending RemoteAgent is the official Codex or Claude desktop product
|
|
170
|
+
- treating Telegram itself as the execution backend
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# COKACDIR Notes
|
|
2
|
+
|
|
3
|
+
## What was referenced
|
|
4
|
+
|
|
5
|
+
`cokacdir` was used as a reference point for product shape, not as a codebase to mirror exactly.
|
|
6
|
+
|
|
7
|
+
The useful high-level ideas are:
|
|
8
|
+
|
|
9
|
+
- installable owner-run runtime
|
|
10
|
+
- Telegram as a remote control surface for an existing coding agent
|
|
11
|
+
- no separate hosted AI backend required
|
|
12
|
+
- local session persistence
|
|
13
|
+
- strong operator tooling around logs, processes, and files
|
|
14
|
+
|
|
15
|
+
## What `cokacdir` appears to optimize for
|
|
16
|
+
|
|
17
|
+
From its public README and local repository layout, `cokacdir` is broader than RemoteAgent.
|
|
18
|
+
It combines:
|
|
19
|
+
|
|
20
|
+
- Telegram bot control
|
|
21
|
+
- multi-provider execution
|
|
22
|
+
- terminal/file manager style tooling
|
|
23
|
+
- process management
|
|
24
|
+
- SSH/SFTP and other power-user utilities
|
|
25
|
+
- a larger installable desktop/runtime surface
|
|
26
|
+
|
|
27
|
+
That is a different product envelope from RemoteAgent.
|
|
28
|
+
|
|
29
|
+
## What RemoteAgent should borrow
|
|
30
|
+
|
|
31
|
+
The main lessons worth borrowing are operational, not cosmetic:
|
|
32
|
+
|
|
33
|
+
1. one installable runtime per owner
|
|
34
|
+
2. stable local state directories
|
|
35
|
+
3. explicit environment-driven configuration
|
|
36
|
+
4. practical operator commands for logs, status, and process control
|
|
37
|
+
5. Telegram as a client of the runtime, not the source of truth
|
|
38
|
+
|
|
39
|
+
## What RemoteAgent should not copy blindly
|
|
40
|
+
|
|
41
|
+
RemoteAgent is intentionally narrower.
|
|
42
|
+
It should not drift into a giant terminal/file-manager product just because `cokacdir` supports that.
|
|
43
|
+
|
|
44
|
+
RemoteAgent should stay focused on:
|
|
45
|
+
|
|
46
|
+
- personal session runtime
|
|
47
|
+
- Codex/Claude style provider adapters
|
|
48
|
+
- Telegram and future local chat UI over the same session model
|
|
49
|
+
- predictable session/workspace ownership
|
|
50
|
+
- safe process lifecycle
|
|
51
|
+
|
|
52
|
+
## Key difference in current implementation
|
|
53
|
+
|
|
54
|
+
A critical design decision for RemoteAgent is:
|
|
55
|
+
|
|
56
|
+
- server 30 is the canonical runtime for `codex_remoteagent_bot`
|
|
57
|
+
- local machine 21 is separate for `sqream_bot`
|
|
58
|
+
- runtime ownership matters more than chat UX convenience
|
|
59
|
+
|
|
60
|
+
This means RemoteAgent must care deeply about:
|
|
61
|
+
|
|
62
|
+
- which machine owns the provider session
|
|
63
|
+
- where the workspace actually lives
|
|
64
|
+
- where the runtime state is stored
|
|
65
|
+
- which exact process is answering Telegram
|
|
66
|
+
|
|
67
|
+
That last point became important during the image-send incident.
|
|
68
|
+
The bug felt like an attachment bug, but the root problem was that multiple runtime generations could coexist.
|
|
69
|
+
|
|
70
|
+
## Current conclusion
|
|
71
|
+
|
|
72
|
+
`cokacdir` is a useful reference for the installable Telegram-controlled agent idea.
|
|
73
|
+
But RemoteAgent should keep its own simpler model:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
Telegram/local UI -> single local runtime -> provider adapters -> local sessions/workspaces
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The value is continuity across the owner's own machines and sessions, not reproducing every feature from a broader terminal product.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Error Normalization
|
|
2
|
+
|
|
3
|
+
RemoteAgent should never leak raw provider event payloads directly to Telegram users.
|
|
4
|
+
|
|
5
|
+
## Goals
|
|
6
|
+
|
|
7
|
+
- normalize provider failures into stable user-facing messages
|
|
8
|
+
- classify retryable vs non-retryable failures
|
|
9
|
+
- keep internal details in logs, not in Telegram replies
|
|
10
|
+
- make retry behavior predictable for long-running Telegram sessions
|
|
11
|
+
- tell users when a retryable issue is being retried and when automatic retries stop
|
|
12
|
+
|
|
13
|
+
## Current retryable classes
|
|
14
|
+
|
|
15
|
+
- `provider.capacity.retryable`
|
|
16
|
+
- example: `Selected model is at capacity`
|
|
17
|
+
- behavior: send a progress-style retry notice, wait, retry automatically
|
|
18
|
+
- `provider.empty_response.retryable`
|
|
19
|
+
- example: provider returned no usable final text after progress
|
|
20
|
+
- behavior: send a progress-style retry notice, wait, retry automatically
|
|
21
|
+
- `provider.timeout.final`
|
|
22
|
+
- example: `Codex timed out after 600s without returning a final reply`
|
|
23
|
+
- behavior: do not retry automatically; explain the exact configured timeout that killed the provider process
|
|
24
|
+
|
|
25
|
+
## Current terminal behavior
|
|
26
|
+
|
|
27
|
+
When retries are exhausted:
|
|
28
|
+
|
|
29
|
+
- capacity -> say the selected model is at capacity, then ask the user to retry later or switch models
|
|
30
|
+
- empty response -> explain that automatic continuation stopped after repeated empty follow-up replies
|
|
31
|
+
|
|
32
|
+
When a provider process reaches `COMMAND_TIMEOUT_MS`:
|
|
33
|
+
|
|
34
|
+
- report that the provider process exceeded the configured execution timeout
|
|
35
|
+
- do not say only that "response was delayed"
|
|
36
|
+
- do not invent a cause such as context compaction, provider outage, or model quality unless the provider output explicitly says that
|
|
37
|
+
- tell the operator to increase `/option timeout <seconds>` for long-running work
|
|
38
|
+
|
|
39
|
+
## Maintenance rule
|
|
40
|
+
|
|
41
|
+
When a new provider error shape appears:
|
|
42
|
+
|
|
43
|
+
1. capture the raw provider output in logs
|
|
44
|
+
2. add a stable classifier
|
|
45
|
+
3. map it to a retry policy or a final user-facing message
|
|
46
|
+
4. keep raw JSON and internal event envelopes out of Telegram replies
|
package/docs/MINI_APP.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Telegram Mini App Plan
|
|
2
|
+
|
|
3
|
+
## Positioning
|
|
4
|
+
|
|
5
|
+
RemoteAgent should treat a Telegram Mini App as a richer control UI for the same installable runtime.
|
|
6
|
+
|
|
7
|
+
It should not be described as:
|
|
8
|
+
|
|
9
|
+
- a standalone hosted app
|
|
10
|
+
- a replacement for the runtime server
|
|
11
|
+
- a separate agent execution environment
|
|
12
|
+
|
|
13
|
+
It should be described as:
|
|
14
|
+
|
|
15
|
+
- a Telegram-native web UI
|
|
16
|
+
- an optional control plane for the installed runtime
|
|
17
|
+
- a structured companion to the existing Telegram bot chat
|
|
18
|
+
|
|
19
|
+
## Why it fits RemoteAgent
|
|
20
|
+
|
|
21
|
+
RemoteAgent already has:
|
|
22
|
+
|
|
23
|
+
- Telegram bot identity and chat entry points
|
|
24
|
+
- persisted sessions
|
|
25
|
+
- session switching
|
|
26
|
+
- provider metadata
|
|
27
|
+
- stop and continue controls
|
|
28
|
+
- attachment history
|
|
29
|
+
- event logs
|
|
30
|
+
|
|
31
|
+
A Mini App can expose those features more clearly than raw commands.
|
|
32
|
+
|
|
33
|
+
## First MVP
|
|
34
|
+
|
|
35
|
+
The first Mini App should focus on runtime visibility and control, not on replacing chat.
|
|
36
|
+
|
|
37
|
+
### MVP screens
|
|
38
|
+
|
|
39
|
+
1. Session list
|
|
40
|
+
- public session id
|
|
41
|
+
- provider mode
|
|
42
|
+
- workspace label
|
|
43
|
+
- updated time
|
|
44
|
+
|
|
45
|
+
2. Session detail
|
|
46
|
+
- current provider
|
|
47
|
+
- model
|
|
48
|
+
- sandbox state
|
|
49
|
+
- workspace path summary
|
|
50
|
+
- provider binding state
|
|
51
|
+
|
|
52
|
+
3. Activity view
|
|
53
|
+
- recent event log items
|
|
54
|
+
- progress/result/blocked states
|
|
55
|
+
- attachment entries
|
|
56
|
+
|
|
57
|
+
4. Actions
|
|
58
|
+
- switch session
|
|
59
|
+
- continue
|
|
60
|
+
- stop
|
|
61
|
+
- new session
|
|
62
|
+
- reset binding
|
|
63
|
+
|
|
64
|
+
## Runtime boundary
|
|
65
|
+
|
|
66
|
+
The Mini App should call runtime-owned APIs.
|
|
67
|
+
It should not directly execute Codex, Claude Code, or shell commands on its own.
|
|
68
|
+
|
|
69
|
+
The runtime remains responsible for:
|
|
70
|
+
|
|
71
|
+
- provider execution
|
|
72
|
+
- session storage
|
|
73
|
+
- authorization
|
|
74
|
+
- attachment download and send
|
|
75
|
+
- error normalization
|
|
76
|
+
|
|
77
|
+
## Authentication model
|
|
78
|
+
|
|
79
|
+
The Mini App should trust Telegram launch context only as an input signal.
|
|
80
|
+
Runtime-side checks still matter.
|
|
81
|
+
|
|
82
|
+
Expected checks:
|
|
83
|
+
|
|
84
|
+
- Telegram user id matches `TELEGRAM_OWNER_ID` for privileged actions
|
|
85
|
+
- current bot/chat context maps to the expected runtime channel
|
|
86
|
+
- action is valid for the target session
|
|
87
|
+
|
|
88
|
+
## Suggested rollout
|
|
89
|
+
|
|
90
|
+
### Phase 1
|
|
91
|
+
|
|
92
|
+
- menu button launches Mini App
|
|
93
|
+
- read-only session list and session detail
|
|
94
|
+
- stop and continue buttons
|
|
95
|
+
|
|
96
|
+
### Phase 2
|
|
97
|
+
|
|
98
|
+
- attachment history
|
|
99
|
+
- structured model selection
|
|
100
|
+
- better progress log browsing
|
|
101
|
+
|
|
102
|
+
### Phase 3
|
|
103
|
+
|
|
104
|
+
- richer batch composition
|
|
105
|
+
- per-session settings views
|
|
106
|
+
- safer admin flows for bot/runtime management
|
|
107
|
+
|
|
108
|
+
## Non-goals
|
|
109
|
+
|
|
110
|
+
- replacing Telegram chat entirely
|
|
111
|
+
- multi-user SaaS dashboard
|
|
112
|
+
- separate hosted control plane detached from the runtime machine
|
package/docs/MVP.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# MVP
|
|
2
|
+
|
|
3
|
+
## Objective
|
|
4
|
+
|
|
5
|
+
The MVP is a usable personal runtime that proves five things together:
|
|
6
|
+
|
|
7
|
+
1. Telegram can control the runtime
|
|
8
|
+
2. the owner can use terminal control safely
|
|
9
|
+
3. Telegram can continue Codex work
|
|
10
|
+
4. Telegram can continue Claude Code work
|
|
11
|
+
5. Telegram can pass images and documents into the active session flow
|
|
12
|
+
|
|
13
|
+
Success means the owner can work on their machine, continue from Telegram, and return without losing the local runtime context.
|
|
14
|
+
|
|
15
|
+
## Product boundary
|
|
16
|
+
|
|
17
|
+
This MVP is for:
|
|
18
|
+
|
|
19
|
+
- one owner
|
|
20
|
+
- one installable local runtime
|
|
21
|
+
- personal provider credentials
|
|
22
|
+
- local state only
|
|
23
|
+
|
|
24
|
+
This MVP is not for:
|
|
25
|
+
|
|
26
|
+
- hosted SaaS
|
|
27
|
+
- external users
|
|
28
|
+
- team billing or org management
|
|
29
|
+
- account sharing
|
|
30
|
+
|
|
31
|
+
## MVP pillars
|
|
32
|
+
|
|
33
|
+
### 1. Telegram control
|
|
34
|
+
|
|
35
|
+
Minimum requirements:
|
|
36
|
+
|
|
37
|
+
- create or bind a local session from Telegram
|
|
38
|
+
- inspect status
|
|
39
|
+
- switch sessions
|
|
40
|
+
- reset a chat binding
|
|
41
|
+
- send normal Telegram text messages into the active provider session
|
|
42
|
+
|
|
43
|
+
### 2. Terminal control
|
|
44
|
+
|
|
45
|
+
Minimum requirements:
|
|
46
|
+
|
|
47
|
+
- run shell commands from Telegram
|
|
48
|
+
- keep this owner-only
|
|
49
|
+
- keep this private-chat-only
|
|
50
|
+
- tie dangerous shell access to the current Codex sandbox policy
|
|
51
|
+
|
|
52
|
+
### 3. Codex integration
|
|
53
|
+
|
|
54
|
+
Minimum requirements:
|
|
55
|
+
|
|
56
|
+
- start a fresh Codex pairing
|
|
57
|
+
- attach to an existing Codex `thread_id`
|
|
58
|
+
- continue the same Codex session across turns
|
|
59
|
+
- keep workspace metadata with the session
|
|
60
|
+
|
|
61
|
+
### 4. Claude Code integration
|
|
62
|
+
|
|
63
|
+
Minimum requirements:
|
|
64
|
+
|
|
65
|
+
- start a fresh Claude pairing
|
|
66
|
+
- attach to an existing Claude `session_id`
|
|
67
|
+
- continue the same Claude session across turns
|
|
68
|
+
- keep workspace metadata with the session
|
|
69
|
+
|
|
70
|
+
### 5. Attachment intake
|
|
71
|
+
|
|
72
|
+
Minimum requirements:
|
|
73
|
+
|
|
74
|
+
- accept Telegram photos and supported files
|
|
75
|
+
- materialize them locally in runtime-owned storage
|
|
76
|
+
- route them through the active session flow
|
|
77
|
+
- avoid leaking internal local paths in normal user-facing replies when possible
|
|
78
|
+
|
|
79
|
+
## Supporting runtime requirements
|
|
80
|
+
|
|
81
|
+
To make the five pillars actually usable, the runtime also needs:
|
|
82
|
+
|
|
83
|
+
- local session persistence
|
|
84
|
+
- provider binding persistence
|
|
85
|
+
- append-only event logs
|
|
86
|
+
- stable runtime-owned session ids
|
|
87
|
+
- deterministic single-instance process ownership
|
|
88
|
+
- recoverable restart behavior
|
|
89
|
+
|
|
90
|
+
## Acceptance criteria
|
|
91
|
+
|
|
92
|
+
The MVP is done when all of the following are true:
|
|
93
|
+
|
|
94
|
+
1. Telegram can control a local runtime session reliably.
|
|
95
|
+
2. Terminal control works under explicit restrictions.
|
|
96
|
+
3. Codex can be paired or attached from Telegram.
|
|
97
|
+
4. Claude Code can be paired or attached from Telegram.
|
|
98
|
+
5. Telegram image/document inputs reach the active session flow.
|
|
99
|
+
6. Restarts do not create ambiguous multi-process ownership.
|
|
100
|
+
7. Session state survives process restarts.
|
|
101
|
+
|
|
102
|
+
## Explicit non-goals
|
|
103
|
+
|
|
104
|
+
- hosted sync service
|
|
105
|
+
- public multi-user bot service
|
|
106
|
+
- account resale
|
|
107
|
+
- exact parity with official desktop apps
|
|
108
|
+
- turning RemoteAgent into a general-purpose terminal file manager
|