Skip to content

Commit 43da33a

Browse files
committed
release: v0.1.5 current stability + plan interaction
1 parent 260c2e9 commit 43da33a

17 files changed

Lines changed: 1749 additions & 146 deletions

File tree

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Control your local Codex threads from Telegram. Keep working while away from you
1313

1414
Quick links: [Download](https://github.com/tonyHu08/CodeX_Telegram/releases) · [Commands](./docs/COMMANDS.md) · [FAQ](./docs/FAQ.md) · [Troubleshooting](./docs/TROUBLESHOOTING.md) · [Press kit](./assets/press-kit/README.md) · [Report issue](https://github.com/tonyHu08/CodeX_Telegram/issues)
1515

16+
Latest: **v0.1.5**`/current` stability patch (degrade-first snapshot), native Plan interaction path hardening, and full regression gate before release.
17+
1618
---
1719

1820
## English
@@ -33,14 +35,15 @@ Codex is great on desktop, but it is not remote-first: your work stalls the mome
3335

3436
| Desktop app home | Telegram remote control |
3537
| --- | --- |
36-
| ![Desktop app home](./docs/assets/readme/desktop-home.png) | ![Telegram remote control](./docs/assets/readme/telegram-threads.png) |
38+
| ![Desktop app home](./docs/assets/readme/desktop-home-real.png) | ![Telegram remote control](./docs/assets/readme/telegram-threads-real.png) |
3739

3840
### Features ✨
3941

4042
- **Remote chat with context**: keep using the same local Codex thread from Telegram.
4143
- **Approvals**: when Codex wants to run commands or change files, you can approve/deny from Telegram.
4244
- **Queue + cancel**: long runs can be cancelled with `/cancel`.
4345
- **Usage**: check your remaining limits with `/usage` (alias: `/limits`).
46+
- **Native Plan mode with interaction**: toggle with `/plan on|off|status`, answer plan questions in Telegram buttons/text, then confirm `Execute / Refine / Cancel`.
4447

4548
Notes:
4649

@@ -70,12 +73,16 @@ Notes:
7073
| `/current` | Show snapshot of the current bound thread |
7174
| `/status` | Show bridge status |
7275
| `/usage` / `/limits` | Show Codex rate limits remaining |
76+
| `/plan on` | Enable native Plan mode |
77+
| `/plan off` | Switch back to Code mode |
78+
| `/plan status` | Show mode + pending plan questions + pending execution confirmation |
7379
| `/cancel` | Cancel the current task |
7480
| `/unbind` | Clear current binding |
7581

7682
### Recent stability fixes 🛠️
7783

7884
- `/threads` is now resilient: if `thread/list` is slow/unavailable, it degrades to the Codex sidebar cache so Telegram still gets a fast reply.
85+
- `/current` is now degrade-first: if full `includeTurns` read is slow, it returns a fallback snapshot instead of failing hard.
7986
- Reduced “stuck waiting” cases caused by Keychain prompts/hangs (best-effort Keychain access with short timeouts).
8087

8188
### Visual flow
@@ -149,14 +156,15 @@ Codex 在桌面端很强,但它不是“随时随地继续工作”的工具
149156

150157
| 电脑端主页 | Telegram 远程控制 |
151158
| --- | --- |
152-
| ![Desktop app home](./docs/assets/readme/desktop-home.png) | ![Telegram remote control](./docs/assets/readme/telegram-threads.png) |
159+
| ![Desktop app home](./docs/assets/readme/desktop-home-real.png) | ![Telegram remote control](./docs/assets/readme/telegram-threads-real.png) |
153160

154161
### 功能亮点 ✨
155162

156163
- **带上下文的远程续聊**:不是消息转发,是继续你本机的真实 thread。
157164
- **审批**:需要执行命令/修改文件时,可在 Telegram 一键同意/拒绝。
158165
- **队列与终止**:长任务可以用 `/cancel` 主动停止。
159166
- **用量**`/usage`(别名 `/limits`)查看剩余额度。
167+
- **原生 Plan 模式(可交互)**:通过 `/plan on|off|status` 切换,并可在 Telegram 内回答计划问题,最终确认“执行 / 继续改 / 取消”。
160168

161169
说明:
162170

@@ -186,12 +194,16 @@ Codex 在桌面端很强,但它不是“随时随地继续工作”的工具
186194
| `/current` | 查看当前会话快照 |
187195
| `/status` | 查看桥接状态 |
188196
| `/usage` / `/limits` | 查看剩余用量与重置时间 |
197+
| `/plan on` | 开启原生 Plan 模式 |
198+
| `/plan off` | 切回 Code 模式 |
199+
| `/plan status` | 查看当前模式、待回答计划问题、待确认执行状态 |
189200
| `/cancel` | 终止当前任务 |
190201
| `/unbind` | 解除绑定 |
191202

192203
### 最近稳定性修复 🛠️
193204

194205
- `/threads` 更稳:`thread/list` 超时会降级到 Codex 侧边栏缓存,确保 Telegram 仍能快速拿到列表。
206+
- `/current` 改为“降级优先”:`includeTurns` 读取慢时仍返回基础快照,不再直接红叉失败。
195207
- 降低 Keychain 造成的“卡住/无回包”风险(Keychain 访问改为短超时 best-effort)。
196208

197209
### 相关文档

apps/desktop/electron/local-relay.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ interface IncomingUserMessageEvent {
4343
createdAt: number;
4444
}
4545

46-
type ControlCommandName = 'threads' | 'bind' | 'status' | 'current' | 'active' | 'detail' | 'usage' | 'unbind' | 'cancel' | 'help';
46+
type ControlCommandName = 'threads' | 'bind' | 'status' | 'current' | 'active' | 'detail' | 'usage' | 'plan' | 'unbind' | 'cancel' | 'help';
4747

4848
interface IncomingControlCommandEvent {
4949
type: 'incomingControlCommand';
@@ -550,6 +550,9 @@ function parseSupportedCommand(rawText: string): { command: ControlCommandName;
550550
if (name === 'usage' || name === 'limits') {
551551
return { command: 'usage', args };
552552
}
553+
if (name === 'plan') {
554+
return { command: 'plan', args };
555+
}
553556
if (name === 'unbind') {
554557
return { command: 'unbind', args };
555558
}
@@ -588,6 +591,18 @@ function parseCallbackCommand(data: string): { command: ControlCommandName; args
588591
if (value === 'usage') {
589592
return { command: 'usage', args: '' };
590593
}
594+
if (value === 'plan_on') {
595+
return { command: 'plan', args: 'on' };
596+
}
597+
if (value === 'plan_off') {
598+
return { command: 'plan', args: 'off' };
599+
}
600+
if (value === 'plan_status') {
601+
return { command: 'plan', args: 'status' };
602+
}
603+
if (/^plan_[artsxcef]:/i.test(value)) {
604+
return { command: 'plan', args: `callback ${value}` };
605+
}
591606
if (value === 'unbind') {
592607
return { command: 'unbind', args: '' };
593608
}
@@ -609,7 +624,9 @@ function buildMainReplyKeyboard(): Record<string, unknown> {
609624
[{ text: '/threads' }, { text: '/bind latest' }],
610625
[{ text: '/usage' }, { text: '/status' }],
611626
[{ text: '/active' }, { text: '/current' }],
612-
[{ text: '/detail' }, { text: '/cancel' }],
627+
[{ text: '/plan on' }, { text: '/plan off' }],
628+
[{ text: '/plan status' }, { text: '/cancel' }],
629+
[{ text: '/detail' }],
613630
[{ text: '/unbind' }],
614631
],
615632
resize_keyboard: true,
@@ -848,6 +865,7 @@ export async function startLocalRelay(options: LocalRelayStartOptions): Promise<
848865
return;
849866
}
850867

868+
const baseOptions = event.options || {};
851869
const failureText = event.text.trim();
852870
const isFailure = /^(|execution failed)[:]?/i.test(failureText) || /app-server stopped/i.test(failureText);
853871
if (isFailure) {
@@ -856,11 +874,13 @@ export async function startLocalRelay(options: LocalRelayStartOptions): Promise<
856874
? `${failureText}\n\n${t('建议:请确认 Codex App 已打开且在线,然后重试。', 'Tip: make sure Codex App is open and online, then retry.')}`
857875
: failureText;
858876
void sendTelegramMessage(event.chatId, `❌ ${decoratedFailure}`, {
859-
replyMarkup: buildMainReplyKeyboard(),
877+
...baseOptions,
878+
replyMarkup: baseOptions.replyMarkup || buildMainReplyKeyboard(),
860879
});
861880
} else {
862881
void sendTelegramMessage(event.chatId, `${t('✅ 已完成', '✅ Completed')}\n\n${event.text}`, {
863-
replyMarkup: buildMainReplyKeyboard(),
882+
...baseOptions,
883+
replyMarkup: baseOptions.replyMarkup || buildMainReplyKeyboard(),
864884
});
865885
}
866886
}
@@ -1365,6 +1385,7 @@ export async function startLocalRelay(options: LocalRelayStartOptions): Promise<
13651385
{ command: 'bind', description: t('绑定会话(/bind latest 或 /bind <id>)', 'Bind a thread (/bind latest or /bind <id>)') },
13661386
{ command: 'usage', description: t('查询 Codex 剩余用量', 'Show Codex usage limits') },
13671387
{ command: 'limits', description: t('查询 Codex 剩余用量(别名)', 'Show Codex usage limits (alias)') },
1388+
{ command: 'plan', description: t('切换 Plan 模式(on/off/status)', 'Switch Plan mode (on/off/status)') },
13681389
{ command: 'current', description: t('查看当前会话快照', 'Show current thread snapshot') },
13691390
{ command: 'active', description: t('查看当前会话标题', 'Show active thread title') },
13701391
{ command: 'detail', description: t('查看会话详情(来源/ID/CWD)', 'Show thread details (source/ID/CWD)') },

apps/desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@codex-bridge/desktop",
3-
"version": "0.1.4",
3+
"version": "0.1.5",
44
"private": true,
55
"main": "dist/electron/main.js",
66
"scripts": {

docs/COMMANDS.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
- `/bind <threadId|index>`
1818
- `/usage` (alias: `/limits`)
1919
- Show Codex rate limits remaining and reset time.
20+
- `/plan on|off|status`
21+
- Toggle/query native Codex collaboration mode (Plan/Code).
22+
- In Plan mode, if Codex asks follow-up questions, answer directly with Telegram buttons or text.
23+
- After plan draft is produced, Telegram shows confirmation buttons:
24+
- Execute plan
25+
- Refine plan
26+
- Cancel
2027
- `/active`
2128
- `/current`
2229
- `/detail <index|threadId|current|latest>`
@@ -46,6 +53,13 @@
4653
- `/bind <threadId|编号>`
4754
- `/usage`(别名:`/limits`
4855
- 查询 Codex 剩余用量与重置时间。
56+
- `/plan on|off|status`
57+
- 切换/查询 Codex 原生协作模式(Plan/Code)。
58+
- Plan 模式下如果 Codex 追问决策点,可直接在 Telegram 中点按钮或发文本回答。
59+
- 计划草稿完成后会出现确认按钮:
60+
- 确认并执行
61+
- 继续改计划
62+
- 取消本轮
4963
- `/active`
5064
- `/current`
5165
- `/detail <编号|threadId|current|latest>`

docs/E2E_NEW_USER_REPORT.md

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,61 @@
1-
# E2E New User Report (Real Desktop App + Real Telegram)
1+
# E2E New User Report (v0.1.5 Gate)
22

3-
Date: 2026-02-15
4-
Target: validate "fresh install -> pair -> /threads -> bind -> remote ask -> final reply" loop.
3+
Date: 2026-02-25
4+
Target: verify the full Telegram remote control loop and ensure `/current` no longer hard-fails with `12000ms` timeout.
55

66
## Summary
77

88
### Pass
9-
- Local relay starts and stays healthy.
10-
- Device WebSocket stream connects (`/v1/devices/stream`, `websocketClients: 1`).
11-
- Telegram outbound replies (from device -> relay -> Telegram) work.
12-
- `/threads` is now resilient:
13-
- If `thread/list` is slow/unavailable, it degrades to Codex sidebar cache so Telegram always gets a reply quickly.
9+
- `/threads` works and returns list.
10+
- `/bind latest` works.
11+
- `/current` called 10 times continuously: no red-cross hard timeout failure text.
12+
- `/status` and `/usage` return expected data.
13+
- `/plan on`, `/plan status`, `/plan off` are accepted.
14+
- Baseline Plan interaction path is available.
15+
- `/cancel` works.
1416

15-
### Notes (Test Harness)
16-
- Telegram UI automation via shell AppleScript is unreliable in this environment, so it is not used as a requirement.
17-
- Manual Telegram interaction is the primary verification method (real user -> bot updates).
18-
- The relay injection endpoint (`POST /v1/bot/incoming`) is still useful as a fast regression test for the device outbound path.
17+
### Key result for this release
18+
- `/current` is now degrade-first. Under busy thread/read conditions, it returns a fallback snapshot instead of hard-failing the command.
1919

2020
## Environment
21-
- Desktop: CodeX Telegram (packaged app in `/Applications`)
21+
22+
- Repo: `CodeX_Telegram`
23+
- Desktop app: CodeX Telegram
2224
- Relay mode: local (`http://127.0.0.1:8787`)
23-
- Telegram bot: `@tony_test_2_bot`
24-
- Device binding:
25-
- `~/.codex-bridge/data/local-relay-store.json`
25+
- Test harness: synthetic Telegram command loop through local relay (`/v1/bot/incoming`) with live agent websocket
26+
27+
## Evidence
2628

27-
## Evidence (Screens)
28-
- `docs/assets/e2e/01-onboarding-initial.png`
29-
- `docs/assets/e2e/02-telegram-pairing-attempt.png`
30-
- `docs/assets/e2e/03-pairing-confirmed.png`
31-
- `docs/assets/e2e/04-telegram-start-pressed.png`
32-
- `docs/assets/e2e/05-threads-response.png`
33-
- `docs/assets/readme/desktop-home.png`
34-
- `docs/assets/readme/telegram-threads.png`
29+
- Result JSON: `/tmp/cb_v015_release_e2e_result.json`
30+
- Screens:
31+
- `docs/assets/readme/desktop-home-real.png`
32+
- `docs/assets/readme/telegram-threads-real.png`
3533

36-
## Key Fixes Landed During This Run
34+
## Automated checks
3735

38-
### 1) `/threads` reply stability
39-
- Behavior:
40-
- Try `thread/list` once with a short timeout.
41-
- On failure, degrade to Codex Desktop sidebar cache (`~/.codex/.codex-global-state.json`) and still return a usable list.
42-
- User-facing note:
43-
- When degraded, the reply includes a short warning that timestamps may be missing.
36+
1. `/threads returns list`
37+
2. `/bind latest works`
38+
3. `/current x10 no hard timeout text`
39+
4. `/status works`
40+
5. `/usage works`
41+
6. `/plan on accepted`
42+
7. `/plan status works`
43+
8. `plan interaction baseline`
44+
9. `/cancel works`
45+
10. `/plan off works`
4446

45-
### 2) Device stream reliability (Keychain pitfalls)
46-
- Avoid blocking flows caused by Keychain writeback prompts/hangs.
47-
- Keychain reads are now best-effort with a short timeout, and token restoration can fall back to local relay store.
47+
## Notes
4848

49-
## Verification Steps Executed
49+
- This gate focuses on command reliability and regression safety for release.
50+
- Telegram UI automation is intentionally not treated as required; command-path verification is done through the bridge agent test harness plus manual message checks.
5051

51-
### Phase A: Health + binding
52-
1. Confirm relay health:
53-
- `GET /healthz` returns `telegramEnabled: true` and the expected `botUsername`.
54-
2. Confirm device stream:
55-
- `GET /v1/devices/me` (Bearer token from local relay store) returns `connected: true`.
5652

57-
### Phase B: Command loop (real Telegram)
58-
1. In Telegram, run `/threads`, bind a thread, and send a short prompt.
59-
2. Verify relay forwards device outbound event and Telegram receives message:
60-
- Relay logs show `eventType: finalResponse` with the command/turn content preview.
53+
### Release gate evidence
6154

62-
## Follow-ups
63-
- Add an in-app "Send test command" (local-only) button in onboarding to validate inbound/outbound without requiring UI automation.
64-
- Improve end-user diagnostics when Telegram polling is unhealthy:
65-
- Show last polling error + a "Restart bot polling" action.
55+
- `/threads` x5 pass
56+
- `/bind latest` pass
57+
- `/current` x10 pass (no `thread/read timed out after 12000ms` red-cross failure)
58+
- `/status` pass
59+
- `/usage` pass
60+
- `/plan on` + `/plan status` + plan message + `/plan off` pass
61+
- `/cancel` pass
1.59 MB
Loading
2.59 MB
Loading

docs/releases/v0.1.5.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# v0.1.5
2+
3+
Release date: 2026-02-25
4+
5+
## Highlights
6+
7+
- `/current` stability fix:
8+
- Reworked thread snapshot read into a degrade-first pipeline.
9+
- Increased stage timeouts and removed old hard-fail behavior in busy/large threads.
10+
- If full turns cannot be loaded in time, Telegram now gets a fallback snapshot instead of a red-cross fatal timeout.
11+
- Native Plan mode interaction loop:
12+
- `/plan on|off|status` available in command parser + keyboard.
13+
- Preserved callback keyboards in final responses so plan confirmations are actionable.
14+
- Reliability hardening:
15+
- Better retry/degrade logs for `thread/read` and `thread/resume`.
16+
17+
## Regression checklist
18+
19+
- `/threads` works repeatedly
20+
- `/bind latest` works
21+
- `/current` no hard timeout red-cross across repeated calls
22+
- `/status` and `/usage` work
23+
- `/plan on`/`/plan off`/`/plan status` work
24+
- `/cancel` works
25+
26+
## Assets
27+
28+
- `CodeX Telegram-0.1.5-arm64.dmg`
29+
- `CodeX Telegram-0.1.5-arm64-mac.zip`

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codex-telegram",
3-
"version": "0.1.4",
3+
"version": "0.1.5",
44
"private": true,
55
"license": "MIT",
66
"description": "CodeX Telegram monorepo (bridge-core + desktop app + cloud relay)",

0 commit comments

Comments
 (0)