Remove cmd/anvilweb, cmd/anvilwebgw, cmd/anvillm, and elisp/
Drop legacy frontend proof-of-concepts (TUI, web UI, HTTP gateway, Emacs major mode) to focus on the core. Assist remains as the primary frontend; any 9P-speaking program can serve as a frontend. Update README, mkfile, .gitignore, and architecture/client-interactions diagrams accordingly.
This commit is contained in:
parent
304bf25bf1
commit
c5e95eb1ea
|
|
@ -2,13 +2,10 @@ Q
|
||||||
Prompt
|
Prompt
|
||||||
Q-Reset
|
Q-Reset
|
||||||
Q-Login
|
Q-Login
|
||||||
/anvillm
|
|
||||||
/anvilweb
|
|
||||||
/anvilmcp
|
/anvilmcp
|
||||||
.claude
|
.claude
|
||||||
.kiro
|
.kiro
|
||||||
*.elc
|
*.elc
|
||||||
/Assist
|
/Assist
|
||||||
/anvilsrv
|
/anvilsrv
|
||||||
/anvilwebgw
|
|
||||||
*.test
|
*.test
|
||||||
|
|
|
||||||
39
README.md
39
README.md
|
|
@ -6,8 +6,8 @@ LLM orchestrator using 9P — scriptable, multi-backend, crash-resilient
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Core:** anvilsrv (9P daemon), anvilmcp (MCP server), anvilwebgw (API proxy)
|
**Core:** anvilsrv (9P daemon), anvilmcp (MCP server)
|
||||||
**Clients:** Assist (Acme), anvillm.el (Emacs), anvillm (TUI), anvilweb (web)
|
**Frontends:** Any 9P-speaking program — currently Assist (Acme)
|
||||||
**Benefits:** Shared sessions, crash recovery, scriptable via 9P, cross-backend agent communication
|
**Benefits:** Shared sessions, crash recovery, scriptable via 9P, cross-backend agent communication
|
||||||
|
|
||||||
## Why 9P?
|
## Why 9P?
|
||||||
|
|
@ -56,30 +56,19 @@ NAMESPACE=/tmp/ns.$USER.:1 anvilsrv start
|
||||||
NAMESPACE=/tmp/ns.$USER.:1 Assist
|
NAMESPACE=/tmp/ns.$USER.:1 Assist
|
||||||
```
|
```
|
||||||
|
|
||||||
### Clients
|
### Frontends
|
||||||
|
|
||||||
**TUI:** `anvillm` — Keys: `s` start | `p` prompt | `t` stop | `R` restart | `K` kill | `a` alias | `r` refresh | `d` daemon | `?` help | `q` quit
|
Any program that speaks 9P can be a frontend. The 9P filesystem exposes session management, state, messaging, and configuration as plain files — so building a new frontend is just reading and writing files. Past prototypes have included a TUI, a web UI with HTTP gateway, and an Emacs major mode, all built against the same API. The current frontend is:
|
||||||
|
|
||||||
**Emacs:** `(require 'anvillm)` then `M-x anvillm` — Keys: `s` start | `p` prompt | `P` prompt (minibuffer) | `t` stop | `R` restart | `K` kill | `a` alias | `r`/`g` refresh | `d` daemon | `?` help | `q` quit
|
- **Assist** — an Acme client (middle-click `Assist` to launch)
|
||||||
|
|
||||||
**Web:** `anvilweb` (port :8080) — ⚠️ NO auth, localhost only — Remote: `ssh -L 8080:localhost:8080 user@remote`
|
For web frontends that can't speak 9P directly, `anvilwebgw` bridges HTTP to 9P.
|
||||||
|
|
||||||
**Acme:** Type `Assist` and middle-click
|
The `mcptools` scripts (served via 9P at `tools/`) also provide convenient building blocks for frontends:
|
||||||
|
|
||||||
**Tag commands:** `Get Attach Stop Restart Kill Alias Context Daemon Inbox Archive`
|
```sh
|
||||||
|
bash <(9p read tools/<scriptname>)
|
||||||
**Interaction:** Right-click ID for prompt window, 2-1 chord for fire-and-forget
|
```
|
||||||
|
|
||||||
| Command | Action |
|
|
||||||
|---------|--------|
|
|
||||||
| `Get` | Refresh session list |
|
|
||||||
| `Kiro <dir>` / `Claude <dir>` / `Ollama <dir>` | Start session |
|
|
||||||
| `Attach <id>` | Open tmux |
|
|
||||||
| `Stop <id>` / `Restart <id>` / `Kill <id>` | Control session |
|
|
||||||
| `Alias <id> <name>` | Name session |
|
|
||||||
| `Context <id>` | Edit context |
|
|
||||||
| `Daemon` | Manage daemon |
|
|
||||||
| `Inbox [id]` / `Archive [id]` | View messages |
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|
@ -307,7 +296,7 @@ Bot templates provide pre-configured agents for common tasks. Templates are shel
|
||||||
./bot-templates/Conductor kiro /path/to/project
|
./bot-templates/Conductor kiro /path/to/project
|
||||||
```
|
```
|
||||||
|
|
||||||
Templates set up context, roles, and initial configuration. Interact via any client (Assist, TUI, Emacs, Web) or directly via 9P mailbox.
|
Templates set up context, roles, and initial configuration. Interact via Assist or directly via 9P mailbox.
|
||||||
|
|
||||||
**Creating Templates:** Shell scripts that write to `anvillm/ctl` and configure `context`, `role`, `tasks`. See existing templates for examples.
|
**Creating Templates:** Shell scripts that write to `anvillm/ctl` and configure `context`, `role`, `tasks`. See existing templates for examples.
|
||||||
|
|
||||||
|
|
@ -321,7 +310,7 @@ Conductor receives the top-level bead ID, analyzes dependencies, and spawns agen
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
Examples use raw 9P calls. These actions can also be performed from any front-end (Assist, TUI, Emacs, Web).
|
Examples use raw 9P calls. These actions can also be performed from Assist.
|
||||||
|
|
||||||
**1. Taskmaster: Create tasks from project plan**
|
**1. Taskmaster: Create tasks from project plan**
|
||||||
|
|
||||||
|
|
@ -348,7 +337,7 @@ echo '{"to":"'$CONDUCTOR_ID'","type":"WORK_REQUEST","subject":"Execute","body":"
|
||||||
|
|
||||||
Conductor analyzes dependencies, spawns specialized bots, and delegates work in parallel.
|
Conductor analyzes dependencies, spawns specialized bots, and delegates work in parallel.
|
||||||
|
|
||||||
**Monitoring:** Use any front-end (Assist, TUI, Emacs, Web). For custom integrations, see `EVENTS.md`.
|
**Monitoring:** Use Assist or any 9P client. For custom integrations, see `EVENTS.md`.
|
||||||
|
|
||||||
## MCP Integration
|
## MCP Integration
|
||||||
|
|
||||||
|
|
@ -382,6 +371,4 @@ See [Code Execution User Guide](docs/code-execution-user-guide.md) for details.
|
||||||
| 9P not working | `9p ls agent` |
|
| 9P not working | `9p ls agent` |
|
||||||
| Stale PID | `anvilsrv stop` auto-cleans |
|
| Stale PID | `anvilsrv stop` auto-cleans |
|
||||||
| Daemon won't stop | `anvilsrv fgstart` for logs |
|
| Daemon won't stop | `anvilsrv fgstart` for logs |
|
||||||
| anvilweb issues | Check anvilsrv running, namespace matches |
|
|
||||||
|
|
||||||
See Configuration section for environment variables.
|
See Configuration section for environment variables.
|
||||||
|
|
|
||||||
1980
cmd/anvillm/main.go
1980
cmd/anvillm/main.go
File diff suppressed because it is too large
Load Diff
|
|
@ -1,60 +0,0 @@
|
||||||
// anvilweb - AnviLLM static web frontend server
|
|
||||||
//
|
|
||||||
// Serves the AnviLLM web frontend (static files) and proxies /api/* requests
|
|
||||||
// to anvilwebgw (the HTTP gateway service). Run anvilwebgw separately to
|
|
||||||
// handle the 9P-connected API endpoints.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"anvillm/internal/logging"
|
|
||||||
"embed"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httputil"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed static/*
|
|
||||||
var static embed.FS
|
|
||||||
|
|
||||||
var (
|
|
||||||
addr = flag.String("addr", ":8080", "HTTP server address")
|
|
||||||
gwAddr = flag.String("gw", "http://localhost:8081", "anvilwebgw gateway URL for /api/* requests")
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if err := logging.Init(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Failed to initialize logging: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer logging.Logger().Sync()
|
|
||||||
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
gwURL, err := url.Parse(*gwAddr)
|
|
||||||
if err != nil {
|
|
||||||
logging.Logger().Fatal("invalid gateway URL", zap.String("url", *gwAddr), zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
staticFS, err := fs.Sub(static, "static")
|
|
||||||
if err != nil {
|
|
||||||
logging.Logger().Fatal("failed to load static files", zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse proxy for /api/* to anvilwebgw
|
|
||||||
proxy := httputil.NewSingleHostReverseProxy(gwURL)
|
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
|
||||||
mux.Handle("/api/", proxy)
|
|
||||||
mux.Handle("/", http.FileServer(http.FS(staticFS)))
|
|
||||||
|
|
||||||
logging.Logger().Info("starting anvilweb", zap.String("addr", *addr), zap.String("gateway", *gwAddr))
|
|
||||||
if err := http.ListenAndServe(*addr, mux); err != nil {
|
|
||||||
logging.Logger().Fatal("server error", zap.Error(err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
anvilweb:V:
|
|
||||||
cd cmd/anvilweb && go build -o $home/bin/anvilweb
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,15 +1,15 @@
|
||||||
graph TB
|
graph TB
|
||||||
subgraph Clients
|
subgraph Clients["Frontends (any 9P client)"]
|
||||||
Assist["Assist<br/>(Acme)"]
|
Assist["Assist<br/>(Acme)"]
|
||||||
TUI["TUI"]
|
Custom["Custom<br/>(your own)"]
|
||||||
Emacs["Emacs"]
|
|
||||||
Web["Web"]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
WebApp["Web App"]
|
||||||
|
|
||||||
subgraph Core["Core Services"]
|
subgraph Core["Core Services"]
|
||||||
anvilsrv["anvilsrv<br/>(9P daemon)"]
|
anvilsrv["anvilsrv<br/>(9P daemon)"]
|
||||||
anvilmcp["anvilmcp<br/>(MCP server)"]
|
anvilmcp["anvilmcp<br/>(MCP server)"]
|
||||||
anvilwebgw["anvilwebgw<br/>(API proxy)"]
|
anvilwebgw["anvilwebgw<br/>(HTTP↔9P bridge)"]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph Backends
|
subgraph Backends
|
||||||
|
|
@ -20,9 +20,8 @@ graph TB
|
||||||
end
|
end
|
||||||
|
|
||||||
Assist -->|9P| anvilsrv
|
Assist -->|9P| anvilsrv
|
||||||
TUI -->|9P| anvilsrv
|
Custom -->|9P| anvilsrv
|
||||||
Emacs -->|9P| anvilsrv
|
WebApp -->|HTTP| anvilwebgw
|
||||||
Web -->|HTTP| anvilwebgw
|
|
||||||
anvilwebgw -->|9P| anvilsrv
|
anvilwebgw -->|9P| anvilsrv
|
||||||
|
|
||||||
anvilsrv --> Claude
|
anvilsrv --> Claude
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
|
|
@ -1,9 +1,8 @@
|
||||||
graph TB
|
graph TB
|
||||||
Assist["Assist"]
|
Frontend["Frontend<br/>(any 9P client)"]
|
||||||
TUI["TUI"]
|
|
||||||
Script["Script"]
|
Script["Script"]
|
||||||
FS["anvillm/<br/>(9P filesystem)"]
|
FS["anvillm/<br/>(9P filesystem)"]
|
||||||
|
|
||||||
Assist -->|9p read<br/>anvillm/list| FS
|
Frontend -->|9p read<br/>anvillm/list| FS
|
||||||
TUI -->|9p write<br/>anvillm/ctl| FS
|
Frontend -->|9p write<br/>anvillm/ctl| FS
|
||||||
Script -->|9p read<br/>anvillm/events| FS
|
Script -->|9p read<br/>anvillm/events| FS
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.8 KiB |
1640
elisp/anvillm.el
1640
elisp/anvillm.el
File diff suppressed because it is too large
Load Diff
4
mkfile
4
mkfile
|
|
@ -5,9 +5,6 @@ all:V: install
|
||||||
build:V:
|
build:V:
|
||||||
go build -o $INSTALL_PATH/anvilsrv ./cmd/anvilsrv
|
go build -o $INSTALL_PATH/anvilsrv ./cmd/anvilsrv
|
||||||
go build -o $INSTALL_PATH/Assist ./cmd/Assist
|
go build -o $INSTALL_PATH/Assist ./cmd/Assist
|
||||||
go build -o $INSTALL_PATH/anvillm ./cmd/anvillm
|
|
||||||
go build -o $INSTALL_PATH/anvilweb ./cmd/anvilweb
|
|
||||||
go build -o $INSTALL_PATH/anvilwebgw ./cmd/anvilwebgw
|
|
||||||
go build -o $INSTALL_PATH/anvilmcp ./cmd/anvilmcp
|
go build -o $INSTALL_PATH/anvilmcp ./cmd/anvilmcp
|
||||||
cp scripts/Alog $INSTALL_PATH/Alog
|
cp scripts/Alog $INSTALL_PATH/Alog
|
||||||
chmod 0755 $INSTALL_PATH/Alog
|
chmod 0755 $INSTALL_PATH/Alog
|
||||||
|
|
@ -71,5 +68,4 @@ cron-remove:V:
|
||||||
|
|
||||||
clean:V:
|
clean:V:
|
||||||
rm -f $INSTALL_PATH/anvilsrv
|
rm -f $INSTALL_PATH/anvilsrv
|
||||||
rm -f $INSTALL_PATH/anvilwebgw
|
|
||||||
rm -f $INSTALL_PATH/Assist
|
rm -f $INSTALL_PATH/Assist
|
||||||
|
|
|
||||||
Reference in New Issue