sketch: Propagate host vs. runtime OS/WorkingDir/Hostname

If you have a bunch of sketch sessions, you need to know where they were
launched. The container hostnames (some random thing) and working dirs (always /app)
aren't very helpful, so we want to keep around both. I've updated the UI
to show them as well.

This commit chooses "Host" and "Runtime" as the names of the "Outside"
and "Inside" sketch. I'm open to suggestions for better names.

Co-Authored-By: sketch, but it did a so-so job
diff --git a/loop/server/gzhandler/gzhandler_test.go b/loop/server/gzhandler/gzhandler_test.go
index 958f8ab..7fff5f4 100644
--- a/loop/server/gzhandler/gzhandler_test.go
+++ b/loop/server/gzhandler/gzhandler_test.go
@@ -16,23 +16,23 @@
 	testFS := fstest.MapFS{
 		"regular.txt": &fstest.MapFile{
 			Data: []byte("This is a regular text file"),
-			Mode: 0644,
+			Mode: 0o644,
 		},
 		"regular.txt.gz": &fstest.MapFile{
 			Data: compressString(t, "This is a regular text file"),
-			Mode: 0644,
+			Mode: 0o644,
 		},
 		"regular.js": &fstest.MapFile{
 			Data: []byte("console.log('Hello world');"),
-			Mode: 0644,
+			Mode: 0o644,
 		},
 		"regular.js.gz": &fstest.MapFile{
 			Data: compressString(t, "console.log('Hello world');"),
-			Mode: 0644,
+			Mode: 0o644,
 		},
 		"nogzip.css": &fstest.MapFile{
 			Data: []byte(".body { color: red; }"),
-			Mode: 0644,
+			Mode: 0o644,
 		},
 	}
 
@@ -165,15 +165,15 @@
 	// Create a test filesystem with a directory
 	testFS := fstest.MapFS{
 		"dir": &fstest.MapFile{
-			Mode: fs.ModeDir | 0755,
+			Mode: fs.ModeDir | 0o755,
 		},
 		"dir/index.html": &fstest.MapFile{
 			Data: []byte("<html>Directory index</html>"),
-			Mode: 0644,
+			Mode: 0o644,
 		},
 		"dir/index.html.gz": &fstest.MapFile{
 			Data: compressString(t, "<html>Directory index</html>"),
-			Mode: 0644,
+			Mode: 0o644,
 		},
 	}
 
diff --git a/loop/server/loophttp.go b/loop/server/loophttp.go
index 0660357..a814551 100644
--- a/loop/server/loophttp.go
+++ b/loop/server/loophttp.go
@@ -51,11 +51,19 @@
 type State struct {
 	MessageCount  int                  `json:"message_count"`
 	TotalUsage    *ant.CumulativeUsage `json:"total_usage,omitempty"`
-	Hostname      string               `json:"hostname"`
-	WorkingDir    string               `json:"working_dir"`
 	InitialCommit string               `json:"initial_commit"`
 	Title         string               `json:"title"`
-	OS            string               `json:"os"`
+	Hostname      string               `json:"hostname"`    // deprecated
+	WorkingDir    string               `json:"working_dir"` // deprecated
+	OS            string               `json:"os"`          // deprecated
+	GitOrigin     string               `json:"git_origin,omitempty"`
+
+	HostHostname      string `json:"host_hostname,omitempty"`
+	RuntimeHostname   string `json:"runtime_hostname,omitempty"`
+	HostOS            string `json:"host_os,omitempty"`
+	RuntimeOS         string `json:"runtime_os,omitempty"`
+	HostWorkingDir    string `json:"host_working_dir,omitempty"`
+	RuntimeWorkingDir string `json:"runtime_working_dir,omitempty"`
 }
 
 // Server serves sketch HTTP. Server implements http.Handler.
@@ -323,13 +331,20 @@
 		w.Header().Set("Content-Type", "application/json")
 
 		state := State{
-			MessageCount:  serverMessageCount,
-			TotalUsage:    &totalUsage,
-			Hostname:      s.hostname,
-			WorkingDir:    getWorkingDir(),
-			InitialCommit: agent.InitialCommit(),
-			Title:         agent.Title(),
-			OS:            agent.OS(),
+			MessageCount:      serverMessageCount,
+			TotalUsage:        &totalUsage,
+			Hostname:          s.hostname,
+			WorkingDir:        getWorkingDir(),
+			InitialCommit:     agent.InitialCommit(),
+			Title:             agent.Title(),
+			OS:                agent.OS(),
+			HostHostname:      agent.HostHostname(),
+			RuntimeHostname:   s.hostname,
+			HostOS:            agent.HostOS(),
+			RuntimeOS:         agent.OS(),
+			HostWorkingDir:    agent.HostWorkingDir(),
+			RuntimeWorkingDir: getWorkingDir(),
+			GitOrigin:         agent.GitOrigin(),
 		}
 
 		// Create a JSON encoder with indentation for pretty-printing