This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / pipelines / ssh / session.go
2.1 kB 60 lines
1package ssh 2 3import ( 4 "fmt" 5 6 "github.com/bluesky-social/indigo/atproto/syntax" 7 tea "github.com/charmbracelet/bubbletea" 8 "github.com/charmbracelet/ssh" 9 wishtea "github.com/charmbracelet/wish/bubbletea" 10 "tangled.org/core/appview/db" 11 "tangled.org/core/orm" 12) 13 14func (s *Server) teaHandler(sess ssh.Session) (tea.Model, []tea.ProgramOption) { 15 remote := sess.RemoteAddr().String() 16 args := sess.Command() 17 l := s.logger.With("remote", remote) 18 l.Info("SSH connection", "args", args) 19 defer l.Info("SSH connection closed", "remote", remote) 20 21 renderer := wishtea.MakeRenderer(sess) 22 23 if len(args) != 1 { 24 l.Warn("bad invocation", "args", args) 25 return newErrorModel(renderer, "usage: ssh -t <host> -p 2222 <at-uri>\nexample: ssh -t host -p 2222 at://did:web:knot.example/sh.tangled.pipeline/abc123"), wishtea.MakeOptions(sess) 26 } 27 28 rawURI := args[0] 29 aturi, err := syntax.ParseATURI(rawURI) 30 if err != nil { 31 l.Warn("invalid AT URI", "uri", rawURI, "err", err) 32 return newErrorModel(renderer, fmt.Sprintf("invalid AT URI %q: %v", rawURI, err)), wishtea.MakeOptions(sess) 33 } 34 35 did := aturi.Authority().String() 36 const didWebPrefix = "did:web:" 37 if len(did) <= len(didWebPrefix) { 38 l.Warn("unsupported DID format", "did", did) 39 return newErrorModel(renderer, fmt.Sprintf("unsupported DID format %q (expected did:web:...)", did)), wishtea.MakeOptions(sess) 40 } 41 knot := did[len(didWebPrefix):] 42 rkey := aturi.RecordKey().String() 43 44 l = l.With("knot", knot, "rkey", rkey) 45 46 pipelines, err := db.GetPipelineStatuses(s.db, 1, 47 orm.FilterEq("p.knot", knot), 48 orm.FilterEq("p.rkey", rkey), 49 ) 50 if err != nil || len(pipelines) == 0 { 51 l.Warn("pipeline not found", "err", err) 52 return newErrorModel(renderer, fmt.Sprintf("pipeline not found: %s", rawURI)), wishtea.MakeOptions(sess) 53 } 54 55 pipeline := pipelines[0] 56 l.Info("serving pipeline", "workflows", len(pipeline.Statuses)) 57 pty, _, _ := sess.Pty() 58 opts := append(wishtea.MakeOptions(sess), tea.WithAltScreen()) 59 return newPipelineModel(renderer, s, pipeline, pty.Window.Width, pty.Window.Height), opts 60}