You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit cbb8284
Browse filesBrowse the repository at this point in the historyBrowse files
docs: bring READMEs and local docs up to date with this session's changes
README / README.zh-CN
- New "Normal vs. administrator PowerShell" section: the bridge always
runs as a LIMITED task (starting it from an admin shell does not
elevate it); Register-ClaudeReleaseAgent.ps1 must run elevated;
stopping a stale Observer needs an elevated shell when codex3 ran
elevated; everything else runs from either.
- New "Handoff states" table: each state and not-transferable reason,
for Codex and Claude, with what it means and what to do.
- New "What a transfer carries": Last Response on Handoff and Use, and
why Hand Back needs none.
- How codex3 attaches (resume by ID or unique name is immediate) and the
self-exiting Observer; action-only button labels; /help per profile;
re-installing scripts after updates; the UTC test pin.
- New "Known limitations", including card buttons inside a message
thread binding to the group's main chat scope.
local-docs
- 02: covers Claude Code as well as Codex — catalog binding, per-agent
release paths, Last Response, not-transferable states, the Codex
monitor's lifecycle.
- 03: new "Codex attach and Observer lifecycle" with the measured cases;
Last Response on transfers; updated Attach / Observer summaries.
Fix three links in the English 03 that pointed to non-existent *.en.md
files, and point the Chinese 03's references to the Chinese docs.
- 01: how Attach identifies a codex3 session; normalizes the file's
mixed line endings to LF.
- Index descriptions updated.
APPLY / screenshots
- APPLY.md linked to itself for Chinese and listed a non-existent
APPLY.en.md; both APPLY files now list the actual structure and name
the one step that needs an administrator PowerShell.
- screenshots/README notes the screenshots predate the category tabs and
the action-only button labels.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Applying These Documentation Files to an Existing Repository
2
2
3
-
**English** | [简体中文](./APPLY.md)
3
+
**English** | [简体中文](./APPLY.zh-CN.md)
4
4
5
5
The package uses this repository-ready structure:
6
6
7
7
```text
8
-
README.zh-CN.md
9
8
README.md
9
+
README.zh-CN.md
10
10
README.upstream.md
11
11
APPLY.md
12
-
APPLY.en.md
12
+
APPLY.zh-CN.md
13
13
local-docs/
14
-
├─ README.zh-CN.md
15
14
├─ README.md
16
-
├─ 01-codex-third-party-api-key.zh-CN.md
15
+
├─ README.zh-CN.md
17
16
├─ 01-codex-third-party-api-key.md
18
-
├─ 02-lark-bridge-codex-architecture.zh-CN.md
17
+
├─ 01-codex-third-party-api-key.zh-CN.md
19
18
├─ 02-lark-bridge-codex-architecture.md
20
-
├─ 03-codex-session-management.zh-CN.md
21
-
└─ 03-codex-session-management.md
19
+
├─ 02-lark-bridge-codex-architecture.zh-CN.md
20
+
├─ 03-codex-session-management.md
21
+
└─ 03-codex-session-management.zh-CN.md
22
+
screenshots/
23
+
└─ README.md (plus the three screenshots it lists)
22
24
```
23
25
24
26
Before replacing the repository README, preserve the current upstream/local README:
@@ -27,14 +29,16 @@ Before replacing the repository README, preserve the current upstream/local READ
27
29
git mv README.zh-CN.md README.upstream.md
28
30
```
29
31
30
-
Then copy the new `README.zh-CN.md`, `README.md`, and `local-docs/` into the repository.
32
+
Then copy the new `README.md`, `README.zh-CN.md`, `local-docs/`, and `screenshots/` into the repository.
31
33
32
34
If your existing README already contains local changes, keep the file produced by `git mv`; do not overwrite it with the packaged `README.upstream.md`.
These steps only need a normal PowerShell. The one step in this repository that requires an **administrator PowerShell** is registering the Claude Release Agent (`scripts\windows\Register-ClaudeReleaseAgent.ps1`); see the README section *Normal vs. administrator PowerShell*.
Copy file name to clipboardExpand all lines: README.md
+76-13Lines changed: 76 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,19 +80,14 @@ The interactive cards are especially useful on a phone:
80
80
81
81
-`/lark status` shows the current Lark scope and provides quick actions such as **New Lark Session**, **Resume Lark Session**, **Workspace**, and **Help**.
82
82
-`/windows status` shows Windows Codex sessions and adds a **Release** action for sessions that are safe to release.
83
-
-`/session list` shows session ownership and exposes context-aware actions: **Use in this Lark**, **Handoff to this Lark**, or **Hand Back to Windows**.
83
+
-`/session list` shows session ownership and exposes context-aware actions: **Use in Lark**, **Handoff to Lark**, or **Hand Back to Windows**.
84
84
- Lark Web/Desktop can additionally show button `hover_tips`; Lark Mobile relies on the button labels themselves.
85
85
86
-
Action labels are optimized for readability, while execution remains unambiguous:
86
+
Buttons name only the action and its direction (**Use in Lark**, **Handoff to Lark**, **Hand Back to Windows**): the numbered row above them already identifies the Session, and short labels keep two buttons per line on a phone. The hover tip repeats the Session title. Execution stays unambiguous:
87
87
88
88
```text
89
-
Display identity
90
-
Thread Name
91
-
→ duplicate Thread Name + short Session ID
92
-
→ short Session ID when no Thread Name exists
93
-
94
-
Execution identity
95
-
ALWAYS the exact full Session ID
89
+
Display identity the numbered row: Thread Name (short Session ID when unnamed)
90
+
Execution identity ALWAYS the exact full Session ID carried in the button payload
96
91
```
97
92
98
93
Project names and working directories are shown as metadata, but are **not** used as the identity of an action because several sessions can share the same project or cwd.
@@ -114,7 +109,7 @@ Project names and working directories are shown as metadata, but are **not** use
114
109
</tr>
115
110
</table>
116
111
117
-
This makes it possible to inspect and switch Codex ownership remotely from Lark Mobile or Lark Web while keeping the Windows/Lark single-writer rule explicit.
112
+
This makes it possible to inspect and switch session ownership remotely from Lark Mobile or Lark Web while keeping the Windows/Lark single-writer rule explicit.
118
113
119
114
## Claude Code sessions
120
115
@@ -139,7 +134,9 @@ Claude Code needs no Observer to track status: it keeps its own live-process reg
139
134
| Title |`custom-title.json` → latest `ai-title` → first prompt |
140
135
| Running on Windows |`~/.claude/sessions/<pid>.json` — `status: idle / busy`, `entrypoint: cli` for a terminal window |
141
136
142
-
A window that has not been sent anything yet has no transcript; it is listed from the registry as **No conversation yet** and cannot be handed off.
137
+
A window that has not been sent anything yet has no transcript; it is listed from the registry as **No conversation yet** and cannot be handed off. `claude -p` runs — including the bridge's own Lark runs — register too (as `entrypoint: sdk-cli`) and are never treated as Windows writers.
138
+
139
+
`/help` follows the profile: on a Claude bot it describes Claude Code sessions and omits `/windows`, and `/windows` / `/local-status` / `/local-release` reply that they apply to Codex bots only, pointing to `/session list` / `/session handoff`.
143
140
144
141
### Handoff and the Claude Release Agent
145
142
@@ -186,7 +183,8 @@ Start Codex on Windows:
186
183
187
184
```powershell
188
185
cd E:\AI_Tools\codex\AcuPilot
189
-
codex3
186
+
codex3 # new session
187
+
codex3 resume <Session-ID> # or a thread name that only one session uses
190
188
```
191
189
192
190
Inspect Windows sessions from Lark:
@@ -241,6 +239,36 @@ Only one logical writer should own the session at a time.
241
239
242
240
The UI can use a Thread Name for readability, but all destructive or ownership-changing actions target the **full Session ID** internally.
243
241
242
+
Binding a session to a Lark scope (Use / Handoff) writes the bridge's session catalog as well as `sessions.json`, because that catalog is what the next Lark message resumes from; Hand Back archives the catalog entry so Lark stops resuming it.
243
+
244
+
## What a transfer carries
245
+
246
+
| Transfer | Shows the Last Response? | Why |
247
+
|---|---|---|
248
+
| Windows → Lark (**Handoff to Lark**) | Yes — "Last Windows Response" on the result card | Where the Windows conversation left off |
249
+
| Detached → Lark (**Use in Lark**) | Yes — "Last Response" on the result card | A Detached session was usually last used on Windows |
250
+
| Lark → Windows (**Hand Back to Windows**) | Not needed | Lark turns run on the same Windows machine and are written to the same rollout / transcript, so `codex3 resume` / `claude --resume` already shows them |
251
+
252
+
The Last Response is shown to the person only. The model never needs it carried over: a resumed session reads its full history from the rollout / transcript in either direction.
253
+
254
+
## Handoff states — what they mean and what to do
255
+
256
+
The `/session list` card shows a **Handoff** line for sessions running on Windows. A state marked *not transferable* gets no Handoff button, and `/session handoff` refuses it with the same explanation.
257
+
258
+
| State | Agent | Meaning | What to do |
259
+
|---|---|---|---|
260
+
| 🟢 Ready | both | Idle Windows writer, fully identified |**Handoff to Lark**|
261
+
| 🔵 Busy · … | both | The Windows writer is working | Wait until it is idle |
262
+
| ⚪ Detached | both | No Windows writer and no Lark owner |**Use in Lark**|
263
+
| 🟡 Observer heartbeat stale | Codex | The Observer has not reported for over 30 s | Usually recovers; Handoff is still offered and the release chain re-validates |
264
+
| 🟡 Launch mapping unavailable *(not transferable)*| Codex | This Codex was never attached by `codex3` (started before the attach mechanism, by hand, or the attach did not finish), so it has no Release Agent | Exit it on Windows, then **Use in Lark**; open sessions with `codex3` / `codex3 resume` from now on. A hand-started Observer keeps running and must be stopped too |
265
+
| 🟡 Release Agent not recorded *(not transferable)*| Codex | Same cause: nothing can release this writer | Same as above |
266
+
| 🟡 Codex exited; stale Observer (pid N) *(not transferable)*| Codex | The `codex3` terminal was closed without its cleanup and its Observer outlived Codex |`Stop-Process N` (in an administrator PowerShell if `codex3` ran elevated); the session then becomes Detached. Observers started by the current scripts exit on their own |
267
+
| 🟡 Running as administrator — Claude release agent not running *(not transferable)*| Claude | Elevated window; the non-elevated bridge cannot release it | Register the Claude Release Agent ([below](#normal-vs-administrator-powershell)), or exit it on Windows and **Use in Lark**|
268
+
| 🟡 No conversation yet *(not transferable)*| Claude | Open window that has not been sent anything | Nothing to resume — just talk to the bot in Lark |
269
+
| 🟡 Open in *client* — close it there *(not transferable)*| Claude | Running in an IDE or other client, not a terminal | Close it there, then **Use in Lark**|
270
+
| 🟡 Unknown status / Process identity unavailable *(not transferable)*| Claude | Cannot confirm it is safe to terminate | Exit it on Windows, then **Use in Lark**|
271
+
244
272
## Windows monitoring layer
245
273
246
274
```text
@@ -264,6 +292,30 @@ Runtime data is stored under:
264
292
%USERPROFILE%\.claude-monitor\ Claude Release Agent requests / results / heartbeat
265
293
```
266
294
295
+
How `codex3` attaches a session:
296
+
297
+
-`codex3` (a new session) is identified by the first rollout it writes in the current directory.
298
+
-`codex3 resume <Session-ID>` and `codex3 resume <thread name>` are identified **immediately** from the command line — before anything is typed. A thread name is used only when exactly one session carries it; a name shared by several sessions, `resume --last`, or the interactive picker falls back to the first-write matching, so use the Session ID to be certain.
299
+
- The Observer exits by itself when its Codex exits, even if the terminal was closed with the X button, and removes that launch's mapping and claim.
300
+
301
+
Attach logs are in `%USERPROFILE%\.codex-monitor\logs\attach-<launch-id>.log`; `Resume target from command line` confirms an immediate match.
302
+
303
+
## Normal vs. administrator PowerShell
304
+
305
+
The bridge itself always runs as a **LIMITED** (non-elevated) scheduled task — `lark-channel-bridge start` only runs that task, so starting it from an administrator terminal does not elevate it. Windows does not let a non-elevated process inspect or terminate an elevated one, which is what the release agents are for.
306
+
307
+
| Task | Where to run it | Notes |
308
+
|---|---|---|
309
+
|`.\scripts\windows\Register-ClaudeReleaseAgent.ps1` (and `-Unregister`) |**Administrator PowerShell** — the script refuses otherwise | Once. Registers `\LarkChannelBridge.ClaudeReleaseAgent`, a `/RL HIGHEST` logon task, and starts it. Needed only if you start Claude from an administrator terminal |
310
+
|`Stop-Process <pid>` for a stale Observer |**Administrator PowerShell** if `codex3` ran elevated | An elevated process can only be stopped from an elevated shell |
311
+
|`codex3`, `codex3 resume …`| Either | If elevated, its Observer and Release Agent are elevated too, and Codex handoff still works — its own Release Agent does the terminating |
312
+
|`claude`| Either | Elevated windows need the Claude Release Agent for handoff; windows from a normal terminal do not |
313
+
|`.\scripts\windows\Install-CodexBridgeScripts.ps1`| Either | Copies the scripts to `%USERPROFILE%\Scripts`|
314
+
|`lark-channel-bridge start / stop / status`| Either | The bridge runs LIMITED regardless |
315
+
|`pnpm install / test / build`, `npm install -g .`| Normal | — |
316
+
317
+
`whoami /groups | findstr "Mandatory Label"` shows `High Mandatory Level` in an elevated shell.
318
+
267
319
## Build and install
268
320
269
321
```powershell
@@ -286,11 +338,22 @@ lark-channel-bridge start --profile claude
286
338
287
339
Do not replace the local build with `npm install -g lark-channel-bridge@latest`; that installs the upstream registry package and removes the local session-management extensions.
288
340
341
+
After updating `scripts/windows/`, run `Install-CodexBridgeScripts.ps1` again: `codex3` and the release agents run the installed copies in `%USERPROFILE%\Scripts`, and already-running Observers keep the version they started with.
342
+
343
+
The test suite runs in UTC (`vitest.config.ts`) because some tests pin the clock to midnight UTC while log files are named by local date.
344
+
345
+
## Known limitations
346
+
347
+
-**Card buttons inside a message thread.** In a group, a typed command inside a thread belongs to that thread's Lark scope, but a card button clicked inside the thread resolves to the group's main chat scope. A session handed off or used by a button click is therefore bound to the main chat. Prefer typed commands inside threads, or use the buttons from the main chat area.
348
+
-**Codex sessions not attached by `codex3`** (started before the attach mechanism or by hand) cannot be handed off; exit them on Windows and use **Use in Lark**.
349
+
-**Handoff terminates the Windows window.** The conversation is intact on disk, but an unsent draft in the terminal prompt is lost. After a forced Claude exit the terminal may print stray escape sequences such as `[I[` on focus changes; close that tab.
350
+
-**One bot per agent.** A profile runs either Codex or Claude Code; manage the other kind from its own bot.
0 commit comments