diff --git a/internal/p9/server.go b/internal/p9/server.go index 997b8e2..86515b5 100644 --- a/internal/p9/server.go +++ b/internal/p9/server.go @@ -202,6 +202,8 @@ func (s *Server) pathType(path string) string { return "dir" case len(parts) == 1 && parts[0] == "sk": return "dir" + case len(parts) == 1 && parts[0] == "t": + return "dir" case len(parts) == 2 && parts[0] == "prompts": if _, err := os.Stat(s.promptsDir + "/" + parts[1]); err == nil { return "file" @@ -211,6 +213,10 @@ func (s *Server) pathType(path string) string { if _, err := skills.Read(name); err == nil { return "file" } + case len(parts) == 2 && parts[0] == "t": + if _, err := os.Stat(execute.ToolsPath() + "/" + parts[1]); err == nil { + return "file" + } case len(parts) == 2 && parts[0] == "s": s.mu.RLock() _, ok := s.sessions[parts[1]] @@ -394,6 +400,24 @@ func (s *Server) read(cs *connState, fc *plan9.Fcall) *plan9.Fcall { return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(len(data)), Data: data} } + // Tool files are served from the tools path. + if strings.HasPrefix(path, "/t/") { + content, err := os.ReadFile(execute.ToolsPath() + "/" + pathBase(path)) + if err != nil { + return errFcall(fc, err.Error()) + } + var data []byte + off := int(fc.Offset) + if off < len(content) { + end := off + int(fc.Count) + if end > len(content) { + end = len(content) + } + data = content[off:end] + } + return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(len(data)), Data: data} + } + content := s.readFile(path) var data []byte off := int(fc.Offset) @@ -569,6 +593,14 @@ func (s *Server) handleWrite(path, input string) { return } + // Tool file writes go directly to disk. + if strings.HasPrefix(path, "/t/") { + if err := os.WriteFile(execute.ToolsPath()+"/"+pathBase(path), []byte(input), 0755); err != nil { + fmt.Fprintf(os.Stderr, "olliesrv: write tool: %v\n", err) + } + return + } + // Path format: /s/{sessid}/{file} parts := strings.SplitN(strings.TrimPrefix(path, "/"), "/", 3) if len(parts) != 3 || parts[0] != "s" { @@ -877,6 +909,7 @@ func (s *Server) readDir(path string, offset uint64, count uint32) []byte { dirs = append(dirs, makeDir("prompts", "/prompts", true, plan9.DMDIR|0555)) dirs = append(dirs, makeDir("s", "/s", true, plan9.DMDIR|0555)) dirs = append(dirs, makeDir("sk", "/sk", true, plan9.DMDIR|0555)) + dirs = append(dirs, makeDir("t", "/t", true, plan9.DMDIR|0555)) } else if path == "/prompts" { entries, _ := os.ReadDir(s.promptsDir) for _, e := range entries { @@ -889,6 +922,13 @@ func (s *Server) readDir(path string, offset uint64, count uint32) []byte { name := m.Name + ".md" dirs = append(dirs, makeDir(name, "/sk/"+name, false, 0444)) } + } else if path == "/t" { + entries, _ := os.ReadDir(execute.ToolsPath()) + for _, e := range entries { + if !e.IsDir() { + dirs = append(dirs, makeDir(e.Name(), "/t/"+e.Name(), false, 0666)) + } + } } else if path == "/s" { s.mu.RLock() for id := range s.sessions { @@ -979,6 +1019,8 @@ func (s *Server) makeStat(path string) plan9.Dir { mode = 0666 } else if strings.HasPrefix(path, "/sk/") { mode = 0444 + } else if strings.HasPrefix(path, "/t/") { + mode = 0666 } else { mode = 0444 }