diff --git a/dockerimg/dockerimg.go b/dockerimg/dockerimg.go
new file mode 100644
index 0000000..72110da
--- /dev/null
+++ b/dockerimg/dockerimg.go
@@ -0,0 +1,626 @@
+// Package dockerimg
+package dockerimg
+
+import (
+	"bytes"
+	"context"
+	"crypto/sha256"
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"io"
+	"log/slog"
+	"net"
+	"net/http"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"time"
+
+	"sketch.dev/skribe"
+)
+
+// ContainerConfig holds all configuration for launching a container
+type ContainerConfig struct {
+	// SessionID is the unique identifier for this session
+	SessionID string
+
+	// LocalAddr is the initial address to use (though it may be overwritten later)
+	LocalAddr string
+
+	// SkabandAddr is the address of the skaband service if available
+	SkabandAddr string
+
+	// AntURL is the URL of the LLM service.
+	AntURL string
+
+	// AntAPIKey is the API key for LLM service.
+	AntAPIKey string
+
+	// Path is the local filesystem path to use
+	Path string
+
+	// GitUsername is the username to use for git operations
+	GitUsername string
+
+	// GitEmail is the email to use for git operations
+	GitEmail string
+
+	// OpenBrowser determines whether to open a browser automatically
+	OpenBrowser bool
+
+	// NoCleanup prevents container cleanup when set to true
+	NoCleanup bool
+
+	// ForceRebuild forces rebuilding of the Docker image even if it exists
+	ForceRebuild bool
+
+	// Host directory to copy container logs into, if not set to ""
+	ContainerLogDest string
+
+	// Path to pre-built linux sketch binary, or build a new one if set to ""
+	SketchBinaryLinux string
+
+	// Sketch client public key.
+	SketchPubKey string
+}
+
+// LaunchContainer creates a docker container for a project, installs sketch and opens a connection to it.
+// It writes status to stdout.
+func LaunchContainer(ctx context.Context, stdout, stderr io.Writer, config ContainerConfig) error {
+	if _, err := exec.LookPath("docker"); err != nil {
+		return fmt.Errorf("cannot find `docker` binary; run: brew install docker colima && colima start")
+	}
+
+	if out, err := combinedOutput(ctx, "docker", "ps"); err != nil {
+		// `docker ps` provides a good error message here that can be
+		// easily chatgpt'ed by users, so send it to the user as-is:
+		//		Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
+		return fmt.Errorf("docker ps: %s (%w)", out, err)
+	}
+
+	_, hostPort, err := net.SplitHostPort(config.LocalAddr)
+	if err != nil {
+		return err
+	}
+
+	gitRoot, err := findGitRoot(ctx, config.Path)
+	if err != nil {
+		return err
+	}
+
+	imgName, err := findOrBuildDockerImage(ctx, stdout, stderr, config.Path, gitRoot, config.AntURL, config.AntAPIKey, config.ForceRebuild)
+	if err != nil {
+		return err
+	}
+
+	linuxSketchBin := config.SketchBinaryLinux
+	if linuxSketchBin == "" {
+		linuxSketchBin, err = buildLinuxSketchBin(ctx, config.Path)
+		if err != nil {
+			return err
+		}
+		defer os.Remove(linuxSketchBin)
+	}
+
+	cntrName := imgName + "-" + config.SessionID
+	defer func() {
+		if config.NoCleanup {
+			return
+		}
+		if out, err := combinedOutput(ctx, "docker", "kill", cntrName); err != nil {
+			// TODO: print in verbose mode? fmt.Fprintf(os.Stderr, "docker kill: %s: %v\n", out, err)
+			_ = out
+		}
+		if out, err := combinedOutput(ctx, "docker", "rm", cntrName); err != nil {
+			// TODO: print in verbose mode? fmt.Fprintf(os.Stderr, "docker kill: %s: %v\n", out, err)
+			_ = out
+		}
+	}()
+
+	// errCh receives errors from operations that this function calls in separate goroutines.
+	errCh := make(chan error)
+
+	// Start the git server
+	gitSrv, err := newGitServer(gitRoot)
+	if err != nil {
+		return fmt.Errorf("failed to start git server: %w", err)
+	}
+	defer gitSrv.shutdown(ctx)
+
+	go func() {
+		errCh <- gitSrv.serve(ctx)
+	}()
+
+	// Get the current host git commit
+	var commit string
+	if out, err := combinedOutput(ctx, "git", "rev-parse", "HEAD"); err != nil {
+		return fmt.Errorf("git rev-parse HEAD: %w", err)
+	} else {
+		commit = strings.TrimSpace(string(out))
+	}
+	if out, err := combinedOutput(ctx, "git", "config", "http.receivepack", "true"); err != nil {
+		return fmt.Errorf("git config http.receivepack true: %s: %w", out, err)
+	}
+
+	relPath, err := filepath.Rel(gitRoot, config.Path)
+	if err != nil {
+		return err
+	}
+
+	// Create the sketch container
+	if err := createDockerContainer(ctx, cntrName, hostPort, relPath, imgName, config); err != nil {
+		return err
+	}
+
+	// Copy the sketch linux binary into the container
+	if out, err := combinedOutput(ctx, "docker", "cp", linuxSketchBin, cntrName+":/bin/sketch"); err != nil {
+		return fmt.Errorf("docker cp: %s, %w", out, err)
+	}
+
+	fmt.Printf("starting container %s\ncommits made by the agent will be pushed to \033[1msketch/*\033[0m\n", cntrName)
+
+	// Start the sketch container
+	if out, err := combinedOutput(ctx, "docker", "start", cntrName); err != nil {
+		return fmt.Errorf("docker start: %s, %w", out, err)
+	}
+
+	// Copies structured logs from the container to the host.
+	copyLogs := func() {
+		if config.ContainerLogDest == "" {
+			return
+		}
+		out, err := combinedOutput(ctx, "docker", "logs", cntrName)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "docker logs failed: %v\n", err)
+			return
+		}
+		logLines := strings.Split(string(out), "\n")
+		for _, logLine := range logLines {
+			if !strings.HasPrefix(logLine, "structured logs:") {
+				continue
+			}
+			logFile := strings.TrimSpace(strings.TrimPrefix(logLine, "structured logs:"))
+			srcPath := fmt.Sprintf("%s:%s", cntrName, logFile)
+			logFileName := filepath.Base(logFile)
+			dstPath := filepath.Join(config.ContainerLogDest, logFileName)
+			_, err := combinedOutput(ctx, "docker", "cp", srcPath, dstPath)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "docker cp %s %s failed: %v\n", srcPath, dstPath, err)
+			}
+			fmt.Fprintf(os.Stderr, "\ncopied container log %s to %s\n", srcPath, dstPath)
+		}
+	}
+
+	// NOTE: we want to see what the internal sketch binary prints
+	// regardless of the setting of the verbosity flag on the external
+	// binary, so reading "docker logs", which is the stdout/stderr of
+	// the internal binary is not conditional on the verbose flag.
+	appendInternalErr := func(err error) error {
+		if err == nil {
+			return nil
+		}
+		out, logsErr := combinedOutput(ctx, "docker", "logs", cntrName)
+		if err != nil {
+			return fmt.Errorf("%w; and docker logs failed: %s, %v", err, out, logsErr)
+		}
+		out = bytes.TrimSpace(out)
+		if len(out) > 0 {
+			return fmt.Errorf("docker logs: %s;\n%w", out, err)
+		}
+		return err
+	}
+
+	// Get the sketch server port from the container
+	localAddr, err := getContainerPort(ctx, cntrName)
+	if err != nil {
+		return appendInternalErr(err)
+	}
+
+	// Tell the sketch container which git server port and commit to initialize with.
+	go func() {
+		// TODO: Why is this called in a goroutine? I have found that when I pull this out
+		// of the goroutine and call it inline, then the terminal UI clears itself and all
+		// the scrollback (which is not good, but also not fatal).  I can't see why it does this
+		// though, since none of the calls in postContainerInitConfig obviously write to stdout
+		// or stderr.
+		if err := postContainerInitConfig(ctx, localAddr, commit, gitSrv.gitPort); err != nil {
+			slog.ErrorContext(ctx, "LaunchContainer.postContainerInitConfig", slog.String("err", err.Error()))
+			errCh <- appendInternalErr(err)
+		}
+	}()
+
+	if config.OpenBrowser {
+		OpenBrowser(ctx, "http://"+localAddr)
+	}
+
+	go func() {
+		cmd := exec.CommandContext(ctx, "docker", "attach", cntrName)
+		cmd.Stdin = os.Stdin
+		cmd.Stdout = os.Stdout
+		cmd.Stderr = os.Stderr
+		errCh <- run(ctx, "docker attach", cmd)
+	}()
+
+	defer copyLogs()
+
+	for {
+		select {
+		case <-ctx.Done():
+			return ctx.Err()
+		case err := <-errCh:
+			if err != nil {
+				return appendInternalErr(fmt.Errorf("container process: %w", err))
+			}
+			return nil
+		}
+	}
+}
+
+func combinedOutput(ctx context.Context, cmdName string, args ...string) ([]byte, error) {
+	cmd := exec.CommandContext(ctx, cmdName, args...)
+	// Really only needed for the "go build" command for the linux sketch binary
+	cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0")
+	start := time.Now()
+
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		slog.ErrorContext(ctx, cmdName, slog.Duration("elapsed", time.Now().Sub(start)), slog.String("err", err.Error()), slog.String("path", cmd.Path), slog.String("args", fmt.Sprintf("%v", skribe.Redact(cmd.Args))))
+	} else {
+		slog.DebugContext(ctx, cmdName, slog.Duration("elapsed", time.Now().Sub(start)), slog.String("path", cmd.Path), slog.String("args", fmt.Sprintf("%v", skribe.Redact(cmd.Args))))
+	}
+	return out, err
+}
+
+func run(ctx context.Context, cmdName string, cmd *exec.Cmd) error {
+	start := time.Now()
+	err := cmd.Run()
+	if err != nil {
+		slog.ErrorContext(ctx, cmdName, slog.Duration("elapsed", time.Now().Sub(start)), slog.String("err", err.Error()), slog.String("path", cmd.Path), slog.String("args", fmt.Sprintf("%v", skribe.Redact(cmd.Args))))
+	} else {
+		slog.DebugContext(ctx, cmdName, slog.Duration("elapsed", time.Now().Sub(start)), slog.String("path", cmd.Path), slog.String("args", fmt.Sprintf("%v", skribe.Redact(cmd.Args))))
+	}
+	return err
+}
+
+type gitServer struct {
+	gitLn   net.Listener
+	gitPort string
+	srv     *http.Server
+}
+
+func (gs *gitServer) shutdown(ctx context.Context) {
+	gs.srv.Shutdown(ctx)
+	gs.gitLn.Close()
+}
+
+// Serve a git remote from the host for the container to fetch from and push to.
+func (gs *gitServer) serve(ctx context.Context) error {
+	slog.DebugContext(ctx, "starting git server", slog.String("git_remote_addr", "http://host.docker.internal:"+gs.gitPort+"/.git"))
+	return gs.srv.Serve(gs.gitLn)
+}
+
+func newGitServer(gitRoot string) (*gitServer, error) {
+	ret := &gitServer{}
+	gitLn, err := net.Listen("tcp4", ":0")
+	if err != nil {
+		return nil, fmt.Errorf("git listen: %w", err)
+	}
+	ret.gitLn = gitLn
+
+	srv := http.Server{
+		Handler: &gitHTTP{gitRepoRoot: gitRoot},
+	}
+	ret.srv = &srv
+
+	_, gitPort, err := net.SplitHostPort(gitLn.Addr().String())
+	if err != nil {
+		return nil, fmt.Errorf("git port: %w", err)
+	}
+	ret.gitPort = gitPort
+	return ret, nil
+}
+
+func createDockerContainer(ctx context.Context, cntrName, hostPort, relPath, imgName string, config ContainerConfig) error {
+	//, config.SessionID, config.GitUsername, config.GitEmail, config.SkabandAddr
+	// sessionID, gitUsername, gitEmail, skabandAddr string
+	cmdArgs := []string{"create",
+		"-it",
+		"--name", cntrName,
+		"-p", hostPort + ":80", // forward container port 80 to a host port
+		"-e", "ANTHROPIC_API_KEY=" + config.AntAPIKey,
+	}
+	if config.AntURL != "" {
+		cmdArgs = append(cmdArgs, "-e", "ANT_URL="+config.AntURL)
+	}
+	if config.SketchPubKey != "" {
+		cmdArgs = append(cmdArgs, "-e", "SKETCH_PUB_KEY="+config.SketchPubKey)
+	}
+	if relPath != "." {
+		cmdArgs = append(cmdArgs, "-w", "/app/"+relPath)
+	}
+	cmdArgs = append(
+		cmdArgs,
+		imgName,
+		"/bin/sketch",
+		"-unsafe",
+		"-addr=:80",
+		"-session-id="+config.SessionID,
+		"-git-username="+config.GitUsername, "-git-email="+config.GitEmail,
+	)
+	if config.SkabandAddr != "" {
+		cmdArgs = append(cmdArgs, "-skaband-addr="+config.SkabandAddr)
+	}
+	if out, err := combinedOutput(ctx, "docker", cmdArgs...); err != nil {
+		return fmt.Errorf("docker create: %s, %w", out, err)
+	}
+	return nil
+}
+
+func buildLinuxSketchBin(ctx context.Context, path string) (string, error) {
+	start := time.Now()
+	linuxSketchBin := filepath.Join(path, "tmp-sketch-binary-linux")
+	cmd := exec.CommandContext(ctx, "go", "build", "-o", linuxSketchBin, "sketch.dev/cmd/sketch")
+	cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0")
+
+	fmt.Printf("building linux agent binary...\n")
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		slog.ErrorContext(ctx, "go", slog.Duration("elapsed", time.Now().Sub(start)), slog.String("err", err.Error()), slog.String("path", cmd.Path), slog.String("args", fmt.Sprintf("%v", skribe.Redact(cmd.Args))))
+		return "", fmt.Errorf("failed to build linux sketch binary: %s: %w", out, err)
+	} else {
+		slog.DebugContext(ctx, "go", slog.Duration("elapsed", time.Now().Sub(start)), slog.String("path", cmd.Path), slog.String("args", fmt.Sprintf("%v", skribe.Redact(cmd.Args))))
+	}
+
+	fmt.Printf("built linux agent binary in %s\n", time.Since(start).Round(100*time.Millisecond))
+
+	return linuxSketchBin, nil
+}
+
+func getContainerPort(ctx context.Context, cntrName string) (string, error) {
+	localAddr := ""
+	if out, err := combinedOutput(ctx, "docker", "port", cntrName, "80"); err != nil {
+		return "", fmt.Errorf("failed to find container port: %s: %v", out, err)
+	} else {
+		v4, _, found := strings.Cut(string(out), "\n")
+		if !found {
+			return "", fmt.Errorf("failed to find container port: %s: %v", out, err)
+		}
+		localAddr = v4
+		if strings.HasPrefix(localAddr, "0.0.0.0") {
+			localAddr = "127.0.0.1" + strings.TrimPrefix(localAddr, "0.0.0.0")
+		}
+	}
+	return localAddr, nil
+}
+
+// Contact the container and configure it.
+func postContainerInitConfig(ctx context.Context, localAddr, commit, gitPort string) error {
+	localURL := "http://" + localAddr
+	initMsg, err := json.Marshal(map[string]string{
+		"commit":          commit,
+		"git_remote_addr": "http://host.docker.internal:" + gitPort + "/.git",
+		"host_addr":       localAddr,
+	})
+	if err != nil {
+		return fmt.Errorf("init msg: %w", err)
+	}
+
+	slog.DebugContext(ctx, "/init POST", slog.String("initMsg", string(initMsg)))
+
+	// Note: this /init POST is handled in loop/server/loophttp.go:
+	initMsgByteReader := bytes.NewReader(initMsg)
+	req, err := http.NewRequest("POST", localURL+"/init", initMsgByteReader)
+	if err != nil {
+		return err
+	}
+
+	var res *http.Response
+	for i := 0; ; i++ {
+		time.Sleep(100 * time.Millisecond)
+		// If you DON'T reset this byteReader, then subsequent retries may end up sending 0 bytes.
+		initMsgByteReader.Reset(initMsg)
+		res, err = http.DefaultClient.Do(req)
+		if err != nil {
+			// In addition to "connection refused", we also occasionally see "EOF" errors that can succeed on retries.
+			if i < 100 && (strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "EOF")) {
+				slog.DebugContext(ctx, "postContainerInitConfig retrying", slog.Int("retry", i), slog.String("err", err.Error()))
+				continue
+			}
+			return fmt.Errorf("failed to %s/init sketch in container, NOT retrying: err: %v", localURL, err)
+		}
+		break
+	}
+	resBytes, _ := io.ReadAll(res.Body)
+	if res.StatusCode != http.StatusOK {
+		return fmt.Errorf("failed to initialize sketch in container, response status code %d: %s", res.StatusCode, resBytes)
+	}
+	return nil
+}
+
+func findOrBuildDockerImage(ctx context.Context, stdout, stderr io.Writer, cwd, gitRoot, antURL, antAPIKey string, forceRebuild bool) (imgName string, err error) {
+	h := sha256.Sum256([]byte(gitRoot))
+	imgName = "sketch-" + hex.EncodeToString(h[:6])
+
+	var curImgInitFilesHash string
+	if out, err := combinedOutput(ctx, "docker", "inspect", "--format", "{{json .Config.Labels}}", imgName); err != nil {
+		if strings.Contains(string(out), "No such object") {
+			// Image does not exist, continue and build it.
+			curImgInitFilesHash = ""
+		} else {
+			return "", fmt.Errorf("docker inspect failed: %s, %v", out, err)
+		}
+	} else {
+		m := map[string]string{}
+		if err := json.Unmarshal(bytes.TrimSpace(out), &m); err != nil {
+			return "", fmt.Errorf("docker inspect output unparsable: %s, %v", out, err)
+		}
+		curImgInitFilesHash = m["sketch_context"]
+	}
+
+	candidates, err := findRepoDockerfiles(cwd, gitRoot)
+	if err != nil {
+		return "", fmt.Errorf("find dockerfile: %w", err)
+	}
+
+	var initFiles map[string]string
+	var dockerfilePath string
+
+	// TODO: prefer a "Dockerfile.sketch" so users can tailor any env to this tool.
+	if len(candidates) == 1 && strings.ToLower(filepath.Base(candidates[0])) == "dockerfile" {
+		dockerfilePath = candidates[0]
+		contents, err := os.ReadFile(dockerfilePath)
+		if err != nil {
+			return "", err
+		}
+		fmt.Printf("using %s as dev env\n", candidates[0])
+		if hashInitFiles(map[string]string{dockerfilePath: string(contents)}) == curImgInitFilesHash && !forceRebuild {
+			fmt.Printf("using existing docker image %s\n", imgName)
+			return imgName, nil
+		}
+	} else {
+		initFiles, err = readInitFiles(os.DirFS(gitRoot))
+		if err != nil {
+			return "", err
+		}
+		subPathWorkingDir, err := filepath.Rel(gitRoot, cwd)
+		if err != nil {
+			return "", err
+		}
+		initFileHash := hashInitFiles(initFiles)
+		if curImgInitFilesHash == initFileHash && !forceRebuild {
+			fmt.Printf("using existing docker image %s\n", imgName)
+			return imgName, nil
+		}
+
+		start := time.Now()
+		dockerfile, err := createDockerfile(ctx, http.DefaultClient, antURL, antAPIKey, initFiles, subPathWorkingDir)
+		if err != nil {
+			return "", fmt.Errorf("create dockerfile: %w", err)
+		}
+		dockerfilePath = filepath.Join(cwd, "tmp-sketch-dockerfile")
+		if err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0o666); err != nil {
+			return "", err
+		}
+		defer os.Remove(dockerfilePath)
+
+		fmt.Fprintf(stderr, "generated Dockerfile in %s:\n\t%s\n\n", time.Since(start).Round(time.Millisecond), strings.Replace(dockerfile, "\n", "\n\t", -1))
+	}
+
+	var gitUserEmail, gitUserName string
+	if out, err := combinedOutput(ctx, "git", "config", "--get", "user.email"); err != nil {
+		return "", fmt.Errorf("git config: %s: %v", out, err)
+	} else {
+		gitUserEmail = strings.TrimSpace(string(out))
+	}
+	if out, err := combinedOutput(ctx, "git", "config", "--get", "user.name"); err != nil {
+		return "", fmt.Errorf("git config: %s: %v", out, err)
+	} else {
+		gitUserName = strings.TrimSpace(string(out))
+	}
+
+	start := time.Now()
+	cmd := exec.CommandContext(ctx,
+		"docker", "build",
+		"-t", imgName,
+		"-f", dockerfilePath,
+		"--build-arg", "GIT_USER_EMAIL="+gitUserEmail,
+		"--build-arg", "GIT_USER_NAME="+gitUserName,
+		".",
+	)
+	cmd.Dir = gitRoot
+	cmd.Stdout = stdout
+	cmd.Stderr = stderr
+	fmt.Printf("building docker image %s...\n", imgName)
+
+	err = run(ctx, "docker build", cmd)
+	if err != nil {
+		return "", fmt.Errorf("docker build failed: %v", err)
+	}
+	fmt.Printf("built docker image %s in %s\n", imgName, time.Since(start).Round(time.Millisecond))
+	return imgName, nil
+}
+
+func findRepoDockerfiles(cwd, gitRoot string) ([]string, error) {
+	files, err := findDirDockerfiles(cwd)
+	if err != nil {
+		return nil, err
+	}
+	if len(files) > 0 {
+		return files, nil
+	}
+
+	path := cwd
+	for path != gitRoot {
+		path = filepath.Dir(path)
+		files, err := findDirDockerfiles(path)
+		if err != nil {
+			return nil, err
+		}
+		if len(files) > 0 {
+			return files, nil
+		}
+	}
+	return files, nil
+}
+
+// findDirDockerfiles finds all "Dockerfile*" files in a directory.
+func findDirDockerfiles(root string) (res []string, err error) {
+	err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
+		if info.IsDir() && root != path {
+			return filepath.SkipDir
+		}
+		name := strings.ToLower(info.Name())
+		if name == "dockerfile" || strings.HasPrefix(name, "dockerfile.") {
+			res = append(res, path)
+		}
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func findGitRoot(ctx context.Context, path string) (string, error) {
+	cmd := exec.CommandContext(ctx, "git", "rev-parse", "--git-common-dir")
+	cmd.Dir = path
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		if strings.Contains(string(out), "not a git repository") {
+			return "", fmt.Errorf(`sketch needs to run from within a git repo, but %s is not part of a git repo.
+Consider one of the following options:
+	- cd to a different dir that is already part of a git repo first, or
+	- to create a new git repo from this directory (%s), run this command:
+
+		git init . && git commit --allow-empty -m "initial commit"
+
+and try running sketch again.
+`, path, path)
+		}
+		return "", fmt.Errorf("git rev-parse --git-common-dir: %s: %w", out, err)
+	}
+	gitDir := strings.TrimSpace(string(out)) // location of .git dir, often as a relative path
+	absGitDir := filepath.Join(path, gitDir)
+	return filepath.Dir(absGitDir), err
+}
+
+func OpenBrowser(ctx context.Context, url string) {
+	var cmd *exec.Cmd
+	switch runtime.GOOS {
+	case "darwin":
+		cmd = exec.CommandContext(ctx, "open", url)
+	case "windows":
+		cmd = exec.CommandContext(ctx, "cmd", "/c", "start", url)
+	default: // Linux and other Unix-like systems
+		cmd = exec.CommandContext(ctx, "xdg-open", url)
+	}
+	if b, err := cmd.CombinedOutput(); err != nil {
+		fmt.Fprintf(os.Stderr, "failed to open browser: %v: %s\n", err, b)
+	}
+}
