@@ -11,6 +11,7 @@ Localcoder is a Claude-like command-line AI assistant implemented in Rust. The c
1111- ✅ Ollama-backed chat with streaming responses and one-shot mode
1212- ✅ Tool calling runtime with file, search, Bash, web, and LSP tools
1313- ✅ Interactive REPL with model switching, session resume, config UI, and output styles
14+ - ✅ Local server mode with HTTP and WebSocket entrypoints
1415- ✅ Context compaction, git workflows, memory extraction, plan mode, and skills
1516- ✅ Lightweight runtime with fast startup and low memory usage
1617
@@ -20,7 +21,7 @@ Localcoder is a Claude-like command-line AI assistant implemented in Rust. The c
2021
2122## 📊 Implementation Status
2223
23- The staged roadmap in [ ` docs/P00-plan.md ` ] ( ./docs/P00-plan.md ) is mostly implemented. Current status: ** 15 / 20 stages completed** .
24+ The staged roadmap in [ ` docs/P00-plan.md ` ] ( ./docs/P00-plan.md ) is mostly implemented. Current status: ** 16 / 21 stages completed** .
2425
2526| Stage | Area | Status | Deliverable |
2627| ------| ------| ------| ------|
@@ -44,6 +45,7 @@ The staged roadmap in [`docs/P00-plan.md`](./docs/P00-plan.md) is mostly impleme
4445| S17 | MCP integration | ❌ | MCP client and transport support are not implemented yet |
4546| S18 | Output styles | ✅ | Output style loading and ` /output-style ` |
4647| S19 | LSP integration | ✅ | Language-server-backed code navigation via ` Lsp ` |
48+ | S20 | Server mode | ✅ | Axum-based local HTTP and WebSocket server via ` /server ` |
4749
4850---
4951
@@ -93,7 +95,7 @@ On startup, Localcoder automatically checks for a settings file:
9395
9496- It first looks for ` .localcoder/settings.json ` in the current directory
9597- If that file does not exist, it falls back to ` $HOME/.localcoder/settings.json `
96- - If neither exists, it creates a default config in the current directory
98+ - If neither exists, it creates a default config in ` $HOME/.localcoder/settings.json `
9799
98100The default config format is:
99101
@@ -150,8 +152,77 @@ localcoder --continue
150152
151153# Resume a specific session
152154localcoder --resume s1712345678-12345
155+
156+ # Start the local server in the foreground
157+ localcoder -- " /server"
158+
159+ # Start the local server on a custom address
160+ localcoder -- " /server 127.0.0.1:4000"
161+ ```
162+
163+ ---
164+
165+ ## 🌐 Server Mode
166+
167+ Localcoder can also run as a local HTTP and WebSocket server. The default bind address is ` 127.0.0.1:3000 ` .
168+
169+ You can start it in either mode:
170+
171+ ``` bash
172+ # Start in the REPL, but keep the REPL usable
173+ /server
174+ /server status
175+ /server stop
176+
177+ # Start in one-shot mode and keep the process in the foreground
178+ localcoder -- " /server"
179+ localcoder -- " /server 127.0.0.1:4000"
180+ ```
181+
182+ Available routes:
183+
184+ - ` GET /healthz `
185+ - ` POST /v1/message `
186+ - ` GET /v1/ws `
187+
188+ Example HTTP request:
189+
190+ ``` bash
191+ curl -X POST http://127.0.0.1:3000/v1/message \
192+ -H " content-type: application/json" \
193+ -d ' {
194+ "message": "Explain the role of src/main.rs",
195+ "session_id": "",
196+ "output_style": "default"
197+ }'
198+ ```
199+
200+ Example response:
201+
202+ ``` json
203+ {
204+ "session_id" : " s1746690000000-12345-0" ,
205+ "reply" : " src/main.rs bootstraps configuration, registers tools, and decides between REPL and one-shot execution." ,
206+ "model" : " qwen3.5:4b"
207+ }
153208```
154209
210+ WebSocket messages are JSON-based and currently one request maps to one full agent execution:
211+
212+ ``` json
213+ {
214+ "type" : " message" ,
215+ "message" : " Continue the previous turn and summarize main.rs" ,
216+ "session_id" : " s1746690000000-12345-0"
217+ }
218+ ```
219+
220+ The server is intentionally local-first:
221+
222+ - It listens on ` 127.0.0.1 ` by default
223+ - There is no built-in auth or TLS yet
224+ - ` wss ` should be handled by a reverse proxy if needed
225+
155226---
156227
157228## 🛠️ Built-in Tools
@@ -189,6 +260,7 @@ localcoder -- "Fetch https://www.rust-lang.org/"
189260| ` /output-style [name] ` | List or switch output styles |
190261| ` /web <query> ` | Search the public web directly |
191262| ` /fetch <url> ` | Fetch a public web page |
263+ | ` /server [status\|stop\|host:port] ` | Start, stop, or inspect the local HTTP/WebSocket server |
192264| ` /plan ` | Show plan-mode status |
193265| ` /plan on ` | Enable plan mode manually |
194266| ` /plan off ` | Disable plan mode manually |
@@ -218,7 +290,7 @@ localcoder/
218290├── README.zh.md # Chinese documentation
219291├── docs/ # Roadmap and stage-by-stage implementation notes
220292│ ├── P00-plan.md # Overall staged plan
221- │ └── S00-S19 *.md # Detailed stage documents
293+ │ └── S00-S20 *.md # Detailed stage documents
222294├── examples/ # Example programs
223295│ ├── basic.rs # Basic API usage
224296│ ├── streaming.rs # Streaming responses
@@ -236,6 +308,8 @@ localcoder/
236308 ├── output_style.rs # Output style loading and prompt injection
237309 ├── plan.rs # Plan mode state and todo management
238310 ├── repl.rs # Interactive REPL interface
311+ ├── runtime.rs # Shared runtime/bootstrap helpers
312+ ├── server.rs # Local HTTP and WebSocket server mode
239313 ├── session.rs # JSONL session persistence
240314 ├── skills.rs # SKILL.md loading and activation
241315 ├── tools/ # Built-in tools
@@ -251,6 +325,7 @@ localcoder/
251325| ------| ----------|
252326| Async runtime | tokio 1.40 |
253327| HTTP client | reqwest 0.12 |
328+ | Local server | axum 0.8 |
254329| JSON handling | serde + serde_json 1.0 |
255330| Line editing | rustyline 14.0 |
256331| Error handling | anyhow |
0 commit comments