remote: fetch host_info, inject PWD for remote prompt resolution
prompt_resolver: when cmd.Dir cannot be set (remote CWD does not exist locally), inject PWD=cwd into subprocess env so envsubst in prime sees the correct working directory. remote.Server: fetch host_info RPC after connect, expose HostInfo struct with platform, arch, is_git_repo for the session to pass to prompts.
This commit is contained in:
parent
414220c2e5
commit
a53d5b9618
|
|
@ -46,11 +46,13 @@ func resolveExecPrompt(cmds []string, cwd string, env []string) (string, error)
|
|||
if cwd != "" {
|
||||
if info, err := os.Stat(cwd); err == nil && info.IsDir() {
|
||||
cmd.Dir = cwd
|
||||
} else {
|
||||
// CWD doesn't exist locally (remote session). Inject PWD so
|
||||
// scripts that use ${PWD} via envsubst see the correct value.
|
||||
env = append(env, "PWD="+cwd)
|
||||
}
|
||||
}
|
||||
if len(env) > 0 {
|
||||
cmd.Env = append(os.Environ(), env...)
|
||||
}
|
||||
cmd.Env = append(os.Environ(), env...)
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
|
@ -101,11 +103,17 @@ func resolveStringPrompt(prompt, cwd string, env []string) (string, error) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, "sh", "-c", cmdStr)
|
||||
var cmdEnv []string
|
||||
if cwd != "" {
|
||||
if info, err := os.Stat(cwd); err == nil && info.IsDir() {
|
||||
cmd.Dir = cwd
|
||||
} else {
|
||||
cmdEnv = append(cmdEnv, "PWD="+cwd)
|
||||
}
|
||||
}
|
||||
if len(cmdEnv) > 0 {
|
||||
cmd.Env = append(os.Environ(), cmdEnv...)
|
||||
}
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ import (
|
|||
//go:embed bootstrap.sh
|
||||
var bootstrapTemplate string
|
||||
|
||||
// HostInfo holds environment details from the remote host.
|
||||
type HostInfo struct {
|
||||
Platform string `json:"platform"`
|
||||
Arch string `json:"arch"`
|
||||
IsGitRepo bool `json:"is_git_repo"`
|
||||
}
|
||||
|
||||
// Server implements tools.Server by forwarding calls to a remote
|
||||
// ollie-remote process over SSH.
|
||||
type Server struct {
|
||||
|
|
@ -41,6 +48,7 @@ type Server struct {
|
|||
enc *json.Encoder
|
||||
dec *json.Decoder
|
||||
nextID atomic.Int64
|
||||
Info HostInfo
|
||||
}
|
||||
|
||||
// Config holds the parameters for connecting to a remote host.
|
||||
|
|
@ -179,6 +187,15 @@ func Dial(ctx context.Context, cfg Config) (*Server, error) {
|
|||
return nil, fmt.Errorf("remote ping failed: %w", err)
|
||||
}
|
||||
|
||||
// Fetch remote host info for prompt resolution.
|
||||
// FIXME: This duplicates information that prime scripts also try to detect
|
||||
// locally (platform, is_git_repo). Eventually unify so prompt resolution
|
||||
// always uses these env vars rather than running local checks against a
|
||||
// non-existent remote CWD.
|
||||
if info, err := s.fetchHostInfo(ctx); err == nil {
|
||||
s.Info = info
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
|
@ -300,6 +317,35 @@ func (s *Server) CallTool(ctx context.Context, tool string, args json.RawMessage
|
|||
return resp.Result, nil
|
||||
}
|
||||
|
||||
// fetchHostInfo retrieves environment details from the remote host.
|
||||
func (s *Server) fetchHostInfo(ctx context.Context) (HostInfo, error) {
|
||||
id := s.nextID.Add(1)
|
||||
req := rpcRequest{
|
||||
JSONRPC: "2.0",
|
||||
ID: id,
|
||||
Method: "host_info",
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if err := s.enc.Encode(req); err != nil {
|
||||
return HostInfo{}, err
|
||||
}
|
||||
var resp rpcResponse
|
||||
if err := s.dec.Decode(&resp); err != nil {
|
||||
return HostInfo{}, err
|
||||
}
|
||||
if resp.Error != nil {
|
||||
return HostInfo{}, fmt.Errorf("%s", resp.Error.Message)
|
||||
}
|
||||
var info HostInfo
|
||||
if err := json.Unmarshal(resp.Result, &info); err != nil {
|
||||
return HostInfo{}, err
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// ping verifies the remote server is responsive.
|
||||
func (s *Server) ping(ctx context.Context) error {
|
||||
id := s.nextID.Add(1)
|
||||
|
|
|
|||
Reference in New Issue