docs: 更新命令前缀从/改为//

更新所有文档和代码中的命令前缀,从单斜杠`/`改为双斜杠`//`,以保持一致性
This commit is contained in:
Yuyao Huang (Sam) 2026-03-30 01:40:53 +08:00
parent 3ca492634d
commit 9c04d47c8e
3 changed files with 47 additions and 47 deletions

View File

@ -41,7 +41,7 @@ PhoneWork uses a **Router + Host Client** architecture that supports both single
| Module | Purpose |
|--------|---------|
| `standalone.py` | Single-process entry point: runs router + host client together |
| `router/main.py` | FastAPI app factory, mounts `/ws/node` endpoint, can be run directly |
| `router/main.py` | FastAPI app factory, mounts `//ws/node` endpoint, can be run directly |
| `shared/protocol.py` | Wire protocol for router-host communication |
| `router/nodes.py` | Node registry, connection management, user-to-node mapping |
| `router/ws.py` | WebSocket endpoint for host clients, heartbeat, message routing |
@ -51,7 +51,7 @@ PhoneWork uses a **Router + Host Client** architecture that supports both single
| `host_client/config.py` | Host client configuration loader |
| `bot/handler.py` | Receives Feishu events via long-connection WebSocket |
| `bot/feishu.py` | Sends text/file replies back to Feishu |
| `bot/commands.py` | Slash command handler (`/new`, `/status`, `/shell`, `/remind`, `/tasks`, `/nodes`, `/node`) |
| `bot/commands.py` | Slash command handler (`//new`, `//status`, `//shell`, `//remind`, `//tasks`, `//nodes`, `//node`) |
| `orchestrator/agent.py` | LangChain agent with per-user history + direct/smart mode + direct Q&A |
| `orchestrator/tools.py` | Tools: session management, shell, file ops, web search, scheduler, task status |
| `agent/manager.py` | Session registry with persistence, idle timeout, and auto-background tasks |
@ -281,30 +281,30 @@ GET /health
| Command | Description |
|---------|-------------|
| `/new <dir> [msg]` | Create a new Claude Code session in `<dir>` |
| `/new <dir> [msg] --timeout N` | Create with custom CC timeout (seconds) |
| `/new <dir> [msg] --idle N` | Create with custom idle timeout (seconds) |
| `/status` | Show your sessions and current mode |
| `/switch <n>` | Switch active session to number `<n>` from `/status` |
| `/close [n]` | Close active session (or session `<n>`) |
| `/direct` | Direct mode: messages go straight to Claude Code (no LLM overhead) |
| `/smart` | Smart mode: messages go through LLM for intelligent routing (default) |
| `/shell <cmd>` | Run a shell command directly (bypasses LLM) |
| `/remind <time> <msg>` | Set a reminder (e.g., `/remind 10m check build`) |
| `/tasks` | List background tasks with status |
| `/nodes` | List connected host nodes (multi-host mode) |
| `/node <name>` | Switch active node (multi-host mode) |
| `/help` | Show command reference |
| `//new <dir> [msg]` | Create a new Claude Code session in `<dir>` |
| `//new <dir> [msg] --timeout N` | Create with custom CC timeout (seconds) |
| `//new <dir> [msg] --idle N` | Create with custom idle timeout (seconds) |
| `//status` | Show your sessions and current mode |
| `//switch <n>` | Switch active session to number `<n>` from `//status` |
| `//close [n]` | Close active session (or session `<n>`) |
| `//direct` | Direct mode: messages go straight to Claude Code (no LLM overhead) |
| `//smart` | Smart mode: messages go through LLM for intelligent routing (default) |
| `//shell <cmd>` | Run a shell command directly (bypasses LLM) |
| `//remind <time> <msg>` | Set a reminder (e.g., `//remind 10m check build`) |
| `//tasks` | List background tasks with status |
| `//nodes` | List connected host nodes (multi-host mode) |
| `//node <name>` | Switch active node (multi-host mode) |
| `//help` | Show command reference |
### Message Routing Modes
**Smart mode (default):** Messages are analyzed by the LLM, which decides whether to create a new session, send to an existing one, or ask for clarification. Useful when you want the bot to understand natural language requests.
**Direct mode:** Messages go straight to the active Claude Code session, bypassing the LLM. Faster and more predictable, but requires an active session. Use `/direct` to enable.
**Direct mode:** Messages go straight to the active Claude Code session, bypassing the LLM. Faster and more predictable, but requires an active session. Use `//direct` to enable.
### Claude Code Commands
Claude Code slash commands (like `/help`, `/clear`, `/compact`, `/cost`) are passed through to Claude Code when you have an active session. Bot commands (`/new`, `/status`, `/switch`, etc.) are handled by the bot first.
Claude Code slash commands (like `//help`, `//clear`, `//compact`, `//cost`) are passed through to Claude Code when you have an active session. Bot commands (`//new`, `//status`, `//switch`, etc.) are handled by the bot first.
---
@ -321,13 +321,13 @@ Claude Code slash commands (like `/help`, `/clear`, `/compact`, `/cost`) are pas
#### Better Interaction
- **Slash commands** - Direct control via `/new`, `/status`, `/switch`, `/close`, `/direct`, `/smart`
- **Slash commands** - Direct control via `//new`, `//status`, `//switch`, `//close`, `//direct`, `//smart`
- **Multi-session switching** - Multiple projects open simultaneously, switch between them
- **Interactive cards** - Session status displayed in Feishu message cards
#### Operational Quality
- **Health checks** - `/health` endpoint shows WebSocket status and can test Claude Code connectivity
- **Health checks** - `//health` endpoint shows WebSocket status and can test Claude Code connectivity
- **Auto-reconnection** - WebSocket automatically reconnects if the connection drops
- **Configurable timeouts** - Each session can have custom idle and execution timeout settings
- **Audit logging** - All conversations logged to files for debugging and accountability
@ -346,7 +346,7 @@ Claude Code slash commands (like `/help`, `/clear`, `/compact`, `/cost`) are pas
- Automatic detection of question-like messages
#### Shell Access
- Execute shell commands remotely via `/shell` or through the LLM
- Execute shell commands remotely via `//shell` or through the LLM
- Safety guards block destructive commands (`rm -rf /`, `sudo rm`, `mkfs`, etc.)
- Configurable timeout (max 120 seconds)
@ -361,7 +361,7 @@ Claude Code slash commands (like `/help`, `/clear`, `/compact`, `/cost`) are pas
- Long-running tasks (timeout > 60s) automatically run in background
- Immediate acknowledgment with task ID
- Feishu notification on completion
- Track task status with `/tasks` command
- Track task status with `//tasks` command
#### Web Search
- Search the web via 秘塔AI Search (requires `METASO_API_KEY`)
@ -370,7 +370,7 @@ Claude Code slash commands (like `/help`, `/clear`, `/compact`, `/cost`) are pas
- Supports multiple scopes: webpage, paper, document, video, podcast
#### Scheduling & Reminders
- Set one-time reminders: `/remind 10m check the build`
- Set one-time reminders: `//remind 10m check the build`
- Schedule recurring reminders
- Notifications delivered to Feishu
- Persistent across server restarts
@ -400,8 +400,8 @@ python -m host_client.main
Connects to router via WebSocket, runs full mailboy stack locally.
#### Node Management
- `/nodes` — View all connected host nodes with status
- `/node <name>` — Switch active node for your user
- `//nodes` — View all connected host nodes with status
- `//node <name>` — Switch active node for your user
- Automatic routing: LLM decides which node handles each message
- Health monitoring: Router tracks node heartbeats
- Reconnection: Host clients auto-reconnect on disconnect

View File

@ -40,7 +40,7 @@ returns: {stdout, stderr, exit_code}
approved by the user (raise a confirmation request)
- Timeout hard cap: 120 s; for longer tasks see M2.4
**New slash command:** `/shell <command>` (bypasses LLM; runs directly)
**New slash command:** `//shell <command>` (bypasses LLM; runs directly)
---
@ -86,7 +86,7 @@ fire-and-forget with completion notification.
**New tool:** `run_background` — explicitly submits any shell command or CC prompt as a
background task and returns `task_id` immediately.
**New slash command:** `/tasks` — list running/completed background tasks with status.
**New slash command:** `//tasks` — list running/completed background tasks with status.
**New tool:** `task_status` — check status of a specific `task_id`, optionally get output so far.
@ -145,7 +145,7 @@ args: action ("remind" | "repeat"), delay_seconds (int), interval_seconds (int),
message (str), conv_id (str, optional — if set, forward to that CC session)
```
**New slash command:** `/remind <N>m|h|s <message>` — set a reminder without LLM
**New slash command:** `//remind <N>m|h|s <message>` — set a reminder without LLM
---
@ -168,7 +168,7 @@ args: action ("remind" | "repeat"), delay_seconds (int), interval_seconds (int),
| `orchestrator/tools.py` | Add `ShellTool`, `FileOpsTool`, `WebTool`, `TaskStatusTool`, `SchedulerTool` |
| `agent/task_runner.py` | New — `TaskRunner` singleton, `BackgroundTask` dataclass |
| `agent/scheduler.py` | New — `schedule_once`, `schedule_recurring` |
| `bot/commands.py` | Add `/shell`, `/tasks`, `/remind` commands |
| `bot/commands.py` | Add `//shell`, `//tasks`, `//remind` commands |
| `bot/feishu.py` | Add `chat_id` context var for file send from tool |
| `bot/handler.py` | Pass `chat_id` into context var alongside `user_id` |
| `requirements.txt` | Add `httpx` (if not already present as transitive dep) |
@ -183,10 +183,10 @@ args: action ("remind" | "repeat"), delay_seconds (int), interval_seconds (int),
- [x] M2.3: Send "show me the last 50 lines of audit/abc123.jsonl" — file content returned
- [x] M2.3: Send "send me the sessions.json file" — file arrives in Feishu chat
- [x] M2.4: Start a long CC task (e.g. `--timeout 120`) — bot replies immediately, notifies on finish
- [x] M2.4: `/tasks` — lists running task with elapsed time
- [x] M2.4: `//tasks` — lists running task with elapsed time
- [x] M2.5: "Python 3.13 有哪些新特性?" — `web ask` returns RAG answer from metaso
- [x] M2.5: "帮我读取这个URL: https://example.com" — page content extracted as markdown
- [x] M2.6: `/remind 10m deploy check` — 10 min later, message arrives in Feishu
- [x] M2.6: `//remind 10m deploy check` — 10 min later, message arrives in Feishu
---
---
@ -342,7 +342,7 @@ node to forward each message to.
`display_name`, `connected_at`, `last_heartbeat`
- `get_nodes_for_user(open_id) -> list[NodeConnection]` — may return multiple
- `get_active_node(user_id) -> NodeConnection | None` — per-user active node preference
- `set_active_node(user_id, node_id)` — updated by router LLM or `/node` command
- `set_active_node(user_id, node_id)` — updated by router LLM or `//node` command
**Router LLM** (`router/routing_agent.py`):
@ -383,7 +383,7 @@ Authorization: Bearer <ROUTER_SECRET>
- On `ForwardResponse`, resolves Future with `reply` or raises on `error`
**Modified files:**
- `main.py` → mounts `/ws/node`, starts `NodeRegistry`
- `main.py` → mounts `//ws/node`, starts `NodeRegistry`
- `bot/handler.py` → after allowlist check, calls `routing_agent.route(user_id, chat_id, text)`
instead of `agent.run(user_id, text)` directly
- `config.py` → adds `ROUTER_SECRET`, `ROUTER_LLM_*` (can be same or different model)
@ -437,7 +437,7 @@ all LLM/CC config from it. User only maintains one config file.
### M3.5 — Node Health + User-Facing Status
**`/nodes` slash command** (handled at router, before forwarding):
**`//nodes` slash command** (handled at router, before forwarding):
```
Connected Nodes:
→ home-pc [ACTIVE] sessions=2 online 3h
@ -446,9 +446,9 @@ Connected Nodes:
Use "/node <name>" to switch active node.
```
**`/node <name>` slash command** — sets active node for user.
**`//node <name>` slash command** — sets active node for user.
**Router `/health` updates:**
**Router `//health` updates:**
```json
{
"nodes": [
@ -513,7 +513,7 @@ PhoneWork/
2. **M3.2** — Host client daemon (wrap existing mailboy + agent stack)
3. **M3.3** — Router (node registry, WS, routing LLM, refactor handler)
4. **M3.4** — Standalone script
5. **M3.5** — Node health, `/nodes`, `/node` commands
5. **M3.5** — Node health, `//nodes`, `//node` commands
---
@ -522,8 +522,8 @@ PhoneWork/
- [x] `python standalone.py` — works identically to current `python main.py`
- [x] Router starts, host client connects, registration logged
- [x] Feishu message → routing LLM selects node → forwarded → reply returned
- [x] `/nodes` shows all connected nodes with active marker
- [x] `/node work-server` — switches active node, confirmed in next message
- [x] `//nodes` shows all connected nodes with active marker
- [x] `//node work-server` — switches active node, confirmed in next message
- [x] Two nodes serving same user — message routed to active node
- [x] Kill host client → router marks offline, user sees "Node home-pc is offline"
- [x] Host client reconnects → re-registered, messages flow again
@ -543,8 +543,8 @@ The current `commands.py` calls `agent._active_conv`, `manager.list_sessions()`,
`task_runner.list_tasks()`, `scheduler` — all of which move to the host client in M3.
**Resolution:** At the router, `bot/commands.py` is reduced to two commands:
`/nodes` and `/node <name>`. All other slash commands (`/new`, `/status`, `/close`,
`/switch`, `/direct`, `/smart`, `/shell`, `/tasks`, `/remind`) are forwarded to the
`//nodes` and `//node <name>`. All other slash commands (`//new`, `//status`, `//close`,
`//switch`, `//direct`, `//smart`, `//shell`, `//tasks`, `//remind`) are forwarded to the
active node as-is — the node's mailboy handles them using its local `commands.py`.
The node's command handler remains unchanged from M2.

View File

@ -202,8 +202,8 @@ async def _cmd_status(user_id: str) -> str:
perm = _perm_label(s.get("permission_mode", DEFAULT_PERMISSION_MODE))
lines.append(f"{marker}{i}. `{s['conv_id']}` - `{s['cwd']}` [{perm}]")
lines.append(f"\n**Mode:** {mode}")
lines.append("Use `/switch <n>` to activate a session.")
lines.append("Use `/direct` or `/smart` to change mode.")
lines.append("Use `//switch <n>` to activate a session.")
lines.append("Use `//direct` or `//smart` to change mode.")
return "\n".join(lines)
@ -247,7 +247,7 @@ async def _cmd_close(user_id: str, args: str) -> str:
else:
conv_id = agent.get_active_conv(user_id)
if not conv_id:
return "No active session. Use `/close <conv_id>` or `/close <n>`."
return "No active session. Use `//close <conv_id>` or `//close <n>`."
try:
success = await manager.close(conv_id, user_id=user_id)
@ -302,7 +302,7 @@ async def _cmd_perm(user_id: str, args: str) -> str:
return f"Unknown mode '{alias}'. Valid: bypass, accept, plan"
if not conv_id:
return "No active session. Use `/perm <mode> <conv_id>` or activate a session first."
return "No active session. Use `//perm <mode> <conv_id>` or activate a session first."
try:
manager.set_permission_mode(conv_id, permission_mode, user_id=user_id)
@ -323,7 +323,7 @@ def _cmd_direct(user_id: str) -> str:
"""Enable direct mode - messages go straight to Claude Code."""
conv = agent.get_active_conv(user_id)
if not conv:
return "No active session. Use `/new` or `/switch` first."
return "No active session. Use `//new` or `//switch` first."
agent.set_passthrough(user_id, True)
return f"✓ Direct mode ON. Messages go directly to session `{conv}`."
@ -430,7 +430,7 @@ async def _cmd_nodes(user_id: str, args: str) -> str:
marker = "" if n["node_id"] == active_node_id else " "
status = "🟢" if n["status"] == "online" else "🔴"
lines.append(f"{marker}{n['display_name']} {status} sessions={n['sessions']}")
lines.append("\nUse `/node <name>` to switch active node.")
lines.append("\nUse `//node <name>` to switch active node.")
return "\n".join(lines)