// toolsrv — tool execution server. // // Accepts JSON-RPC 2.0 connections. Executes tool calls in a sandboxed // environment. Used both locally (spawned by olliesrv) and remotely // (deployed via SSH bootstrap). // // Usage: // // toolsrv serve --cwd /path/to/project [--listen /path/to/sock] [--yolo] // // When --listen is provided, accepts connections on a Unix socket. // Otherwise, serves a single session over stdin/stdout (bootstrap mode). package main import ( "context" "flag" "fmt" "os" "os/signal" "path/filepath" "syscall" "ollie/env" "ollie/toolsrv" ) var ( cwd = flag.String("cwd", ".", "working directory for execution") listenPath = flag.String("listen", "", "Unix socket path to listen on (default: stdio mode)") yolo = flag.Bool("yolo", false, "skip sandbox enforcement") ) func main() { if len(os.Args) < 2 || os.Args[1] != "serve" { fmt.Fprintln(os.Stderr, "usage: toolsrv serve --cwd [--listen ]") os.Exit(1) } flag.CommandLine.Parse(os.Args[2:]) env.EnsureDefaults() // Prepend our bin dir to PATH so landrun is found (deployed alongside us). home, _ := os.UserHomeDir() binDir := filepath.Join(home, ".config", "ollie", "bin") os.Setenv("PATH", binDir+":"+os.Getenv("PATH")) toolReg, _ := toolsrv.NewRegistry() sessionID := os.Getenv("OLLIE_SESSION_ID") var opts []toolsrv.Option if *yolo { opts = append(opts, toolsrv.WithYolo()) } if toolReg != nil && sessionID != "" { opts = append(opts, toolsrv.WithToolRegistry(toolReg, sessionID)) } server := toolsrv.New(*cwd) for _, o := range opts { o(server) } // Wire up environment propagation for late-arriving session IDs. server.OnEnvSet = func(key, value string) { switch key { case "OLLIE_SESSION_ID": os.Setenv("OLLIE_SESSION_ID", value) if toolReg != nil { server.SetToolRegistry(toolReg, value) } case "OLLIE_UNAME": os.Setenv("OLLIE_UNAME", value) } } ctx, cancel := context.WithCancel(context.Background()) defer cancel() sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigCh cancel() }() if *listenPath != "" { if err := server.ServeSocket(ctx, *listenPath); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } } else { server.ServeRPC(ctx, os.Stdin, os.Stdout) } }