add local daemon socket protocol
This commit is contained in:
@@ -14,7 +14,9 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -27,6 +29,7 @@ import (
|
||||
"github.com/hjbdev/patterm/internal/app"
|
||||
"github.com/hjbdev/patterm/internal/mcp"
|
||||
"github.com/hjbdev/patterm/internal/projectkey"
|
||||
"github.com/hjbdev/patterm/internal/protocol"
|
||||
)
|
||||
|
||||
// version is overridden at build time via `-ldflags "-X main.version=..."`.
|
||||
@@ -48,6 +51,15 @@ func main() {
|
||||
runDebugHarness()
|
||||
return
|
||||
}
|
||||
if len(os.Args) >= 2 && os.Args[1] == "daemon" {
|
||||
os.Args = append(os.Args[:1], os.Args[2:]...)
|
||||
runDaemonCommand()
|
||||
return
|
||||
}
|
||||
if len(os.Args) >= 2 && os.Args[1] == "ls" {
|
||||
runDaemonList()
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
projectDir = flag.String("project", "", "project directory (default $PWD)")
|
||||
@@ -194,6 +206,78 @@ func runMCPProxy() {
|
||||
}
|
||||
}
|
||||
|
||||
func runDaemonCommand() {
|
||||
if len(os.Args) >= 2 && os.Args[1] == "stop" {
|
||||
runDaemonStop()
|
||||
return
|
||||
}
|
||||
if len(os.Args) >= 2 && os.Args[1] == "ls" {
|
||||
runDaemonList()
|
||||
return
|
||||
}
|
||||
var projectDir = flag.String("project", "", "initial project directory (default $PWD)")
|
||||
flag.Parse()
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
die("getwd: %v", err)
|
||||
}
|
||||
if *projectDir != "" {
|
||||
cwd = *projectDir
|
||||
}
|
||||
if err := app.RunDaemon(context.Background(), app.DaemonOptions{ProjectDir: cwd}); err != nil {
|
||||
die("daemon: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func runDaemonList() {
|
||||
projects, err := daemonRequest(protocol.Frame{Type: protocol.FrameList})
|
||||
if err != nil {
|
||||
die("ls: %v", err)
|
||||
}
|
||||
for _, p := range projects.Projects {
|
||||
fmt.Printf("%s\t%d\t%s\n", p.Key, p.TabCount, p.Path)
|
||||
}
|
||||
}
|
||||
|
||||
func runDaemonStop() {
|
||||
if _, err := daemonRequest(protocol.Frame{Type: protocol.FrameStop}); err != nil {
|
||||
die("daemon stop: %v", err)
|
||||
}
|
||||
fmt.Println("stopped")
|
||||
}
|
||||
|
||||
func daemonRequest(req protocol.Frame) (protocol.ProjectList, error) {
|
||||
socket, _, err := app.RuntimeDaemonPaths()
|
||||
if err != nil {
|
||||
return protocol.ProjectList{}, err
|
||||
}
|
||||
conn, err := net.Dial("unix", socket)
|
||||
if err != nil {
|
||||
return protocol.ProjectList{}, err
|
||||
}
|
||||
defer conn.Close()
|
||||
t := protocol.NewConnTransport(conn)
|
||||
if err := t.Send(req); err != nil {
|
||||
return protocol.ProjectList{}, err
|
||||
}
|
||||
resp, err := t.Recv()
|
||||
if err != nil {
|
||||
return protocol.ProjectList{}, err
|
||||
}
|
||||
if resp.Type == protocol.FrameError {
|
||||
var msg protocol.Error
|
||||
_ = json.Unmarshal(resp.Payload, &msg)
|
||||
if msg.Message == "" {
|
||||
msg.Message = "daemon returned an error"
|
||||
}
|
||||
return protocol.ProjectList{}, fmt.Errorf("%s", msg.Message)
|
||||
}
|
||||
if resp.Type != protocol.FrameProjectList {
|
||||
return protocol.ProjectList{}, fmt.Errorf("unexpected daemon response %q", resp.Type)
|
||||
}
|
||||
return protocol.Decode[protocol.ProjectList](resp)
|
||||
}
|
||||
|
||||
func versionString() string {
|
||||
commit, date := "unknown", "unknown"
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
|
||||
Reference in New Issue
Block a user