all: support popping a browser from termui
- Add 'browser', 'open', and 'b' command aliases to termui
- Open the current conversation URL in default browser
- Add help documentation for the new command
Add browser launch endpoint to Git server for Docker support.
We'll probably want to set up a proper mux for the no-longer-just-git
server pretty soon.
Co-Authored-By: sketch <hello@sketch.dev>
diff --git a/dockerimg/dockerimg.go b/dockerimg/dockerimg.go
index baaf506..555b87e 100644
--- a/dockerimg/dockerimg.go
+++ b/dockerimg/dockerimg.go
@@ -396,9 +396,14 @@
}
ret.gitLn = gitLn
- srv := http.Server{
- Handler: &gitHTTP{gitRepoRoot: gitRoot, pass: []byte(ret.pass)},
- }
+ browserC := make(chan string, 1) // channel of URLs to open in browser
+ go func() {
+ for url := range browserC {
+ browser.Open(url)
+ }
+ }()
+
+ srv := http.Server{Handler: &gitHTTP{gitRepoRoot: gitRoot, pass: []byte(ret.pass), browserC: browserC}}
ret.srv = &srv
_, gitPort, err := net.SplitHostPort(gitLn.Addr().String())
@@ -551,6 +556,7 @@
initMsg, err := json.Marshal(
server.InitRequest{
Commit: commit,
+ OutsideHTTP: fmt.Sprintf("http://sketch:%s@host.docker.internal:%s", gitPass, gitPort),
GitRemoteAddr: fmt.Sprintf("http://sketch:%s@host.docker.internal:%s/.git", gitPass, gitPort),
HostAddr: localAddr,
SSHAuthorizedKeys: sshAuthorizedKeys,
diff --git a/dockerimg/githttp.go b/dockerimg/githttp.go
index 38a8b54..6270838 100644
--- a/dockerimg/githttp.go
+++ b/dockerimg/githttp.go
@@ -3,6 +3,7 @@
import (
"crypto/subtle"
"fmt"
+ "io"
"log/slog"
"net/http"
"net/http/cgi"
@@ -14,6 +15,7 @@
type gitHTTP struct {
gitRepoRoot string
pass []byte
+ browserC chan string // browser launch requests
}
func (g *gitHTTP) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -46,6 +48,33 @@
return
}
+ // TODO: real mux?
+ if strings.HasPrefix(r.URL.Path, "/browser") {
+ if r.Method != http.MethodPost {
+ http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+ return
+ }
+ body, err := io.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "Failed to read request body: "+err.Error(), http.StatusBadRequest)
+ return
+ }
+ defer r.Body.Close()
+ url := strings.TrimSpace(string(body))
+ if len(url) == 0 {
+ http.Error(w, "URL cannot be empty", http.StatusBadRequest)
+ return
+ }
+ select {
+ case g.browserC <- string(url):
+ slog.InfoContext(r.Context(), "open browser", "url", url)
+ w.WriteHeader(http.StatusOK)
+ default:
+ http.Error(w, "Too many browser launch requests", http.StatusTooManyRequests)
+ }
+ return
+ }
+
if runtime.GOOS == "darwin" {
// On the Mac, Docker connections show up from localhost. On Linux, the docker
// network is more arbitrary, so we don't do this additional check there.