dockerimg: rename ssh_theater to local_sshimmer

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s650e5e56560011fak
diff --git a/dockerimg/dockerimg.go b/dockerimg/dockerimg.go
index 3ecb823..e5ad648 100644
--- a/dockerimg/dockerimg.go
+++ b/dockerimg/dockerimg.go
@@ -340,7 +340,7 @@
 
 	var sshServerIdentity, sshUserIdentity, containerCAPublicKey, hostCertificate []byte
 
-	cst, err := NewSSHTheater(cntrName, sshHost, sshPort)
+	cst, err := NewLocalSSHimmer(cntrName, sshHost, sshPort)
 	if err != nil {
 		return appendInternalErr(fmt.Errorf("NewContainerSSHTheather: %w", err))
 	}
diff --git a/dockerimg/ssh_theater.go b/dockerimg/local_sshimmer.go
similarity index 94%
rename from dockerimg/ssh_theater.go
rename to dockerimg/local_sshimmer.go
index 0618626..3f0fb11 100644
--- a/dockerimg/ssh_theater.go
+++ b/dockerimg/local_sshimmer.go
@@ -21,11 +21,11 @@
 
 // Ed25519 has a fixed key size, no bit size constant needed
 
-// SSHTheater does the necessary key pair generation, known_hosts updates, ssh_config file updates etc steps
+// LocalSSHimmer does the necessary key pair generation, known_hosts updates, ssh_config file updates etc steps
 // so that ssh can connect to a locally running sketch container to other local processes like vscode without
 // the user having to run the usual ssh obstacle course.
 //
-// SSHTheater does not modify your default .ssh/config, or known_hosts files.  However, in order for you
+// LocalSSHimmer does not modify your default .ssh/config, or known_hosts files.  However, in order for you
 // to be able to use it properly you will have to make a one-time edit to your ~/.ssh/config file.
 //
 // In your ~/.ssh/config file, add the following line:
@@ -34,8 +34,8 @@
 //
 // where $HOME is your home directory.
 //
-// SSHTheater uses Ed25519 keys for improved security and performance.
-type SSHTheater struct {
+// LocalSSHimmer uses Ed25519 keys for improved security and performance.
+type LocalSSHimmer struct {
 	cntrName string
 	sshHost  string
 	sshPort  string
@@ -58,7 +58,7 @@
 	kg KeyGenerator
 }
 
-// NewSSHTheater will set up everything so that you can use ssh on localhost to connect to
+// NewLocalSSHimmer will set up everything so that you can use ssh on localhost to connect to
 // the sketch container.  Call #Clean when you are done with the container to remove the
 // various entries it created in its known_hosts and ssh_config files. Also note that
 // this will generate key pairs for both the ssh server identity and the user identity, if
@@ -70,12 +70,12 @@
 // If this doesn't return an error, you should be able to run "ssh <cntrName>"
 // in a terminal on your host machine to open a shell into the container without having
 // to manually accept changes to your known_hosts file etc.
-func NewSSHTheater(cntrName, sshHost, sshPort string) (*SSHTheater, error) {
-	return newSSHTheatherWithDeps(cntrName, sshHost, sshPort, &RealFileSystem{}, &RealKeyGenerator{})
+func NewLocalSSHimmer(cntrName, sshHost, sshPort string) (*LocalSSHimmer, error) {
+	return newLocalSSHimmerWithDeps(cntrName, sshHost, sshPort, &RealFileSystem{}, &RealKeyGenerator{})
 }
 
-// newSSHTheatherWithDeps creates a new SSHTheater with the specified dependencies
-func newSSHTheatherWithDeps(cntrName, sshHost, sshPort string, fs FileSystem, kg KeyGenerator) (*SSHTheater, error) {
+// newLocalSSHimmerWithDeps creates a new LocalSSHimmer with the specified dependencies
+func newLocalSSHimmerWithDeps(cntrName, sshHost, sshPort string, fs FileSystem, kg KeyGenerator) (*LocalSSHimmer, error) {
 	base := filepath.Join(os.Getenv("HOME"), ".config", "sketch")
 	if _, err := fs.Stat(base); err != nil {
 		if err := fs.MkdirAll(base, 0o777); err != nil {
@@ -83,7 +83,7 @@
 		}
 	}
 
-	cst := &SSHTheater{
+	cst := &LocalSSHimmer{
 		cntrName:           cntrName,
 		sshHost:            sshHost,
 		sshPort:            sshPort,
@@ -266,12 +266,12 @@
 	return pem.EncodeToMemory(pkBytes)
 }
 
-func (c *SSHTheater) writeKeyToFile(keyBytes []byte, filename string) error {
+func (c *LocalSSHimmer) writeKeyToFile(keyBytes []byte, filename string) error {
 	err := c.fs.WriteFile(filename, keyBytes, 0o600)
 	return err
 }
 
-func (c *SSHTheater) createKeyPairIfMissing(idPath string) (ssh.PublicKey, error) {
+func (c *LocalSSHimmer) createKeyPairIfMissing(idPath string) (ssh.PublicKey, error) {
 	if _, err := c.fs.Stat(idPath); err == nil {
 		return nil, nil
 	}
@@ -301,7 +301,7 @@
 	return sshPublicKey, nil
 }
 
-func (c *SSHTheater) addSketchHostMatchIfMissing(cfg *ssh_config.Config) error {
+func (c *LocalSSHimmer) addSketchHostMatchIfMissing(cfg *ssh_config.Config) error {
 	found := false
 	for _, host := range cfg.Hosts {
 		if strings.Contains(host.String(), "host=\"sketch-*\"") {
@@ -326,7 +326,7 @@
 	return nil
 }
 
-func (c *SSHTheater) addContainerToSSHConfig() error {
+func (c *LocalSSHimmer) addContainerToSSHConfig() error {
 	// Read the existing file contents or start with an empty config if file doesn't exist
 	var configData []byte
 	var cfg *ssh_config.Config
@@ -384,7 +384,7 @@
 	return nil
 }
 
-func (c *SSHTheater) addContainerToKnownHosts() error {
+func (c *LocalSSHimmer) addContainerToKnownHosts() error {
 	// Instead of adding individual host entries, we'll use a CA-based approach
 	// by adding a single "@cert-authority" entry
 
@@ -441,7 +441,7 @@
 	return nil
 }
 
-func (c *SSHTheater) removeContainerFromKnownHosts() error {
+func (c *LocalSSHimmer) removeContainerFromKnownHosts() error {
 	// Read the existing known_hosts file
 	existingContent, err := c.fs.ReadFile(c.knownHostsPath)
 	if err != nil {
@@ -485,7 +485,7 @@
 
 // Cleanup removes the container-specific entries from the SSH configuration and known_hosts files.
 // It preserves the certificate authority entries that might be used by other containers.
-func (c *SSHTheater) Cleanup() error {
+func (c *LocalSSHimmer) Cleanup() error {
 	if err := c.removeContainerFromSSHConfig(); err != nil {
 		return fmt.Errorf("couldn't remove container from ssh_config: %v\n", err)
 	}
@@ -496,7 +496,7 @@
 	return nil
 }
 
-func (c *SSHTheater) removeContainerFromSSHConfig() error {
+func (c *LocalSSHimmer) removeContainerFromSSHConfig() error {
 	// Read the existing file contents
 	configData, err := c.fs.ReadFile(c.sshConfigPath)
 	if err != nil {
@@ -660,7 +660,7 @@
 // to simplify the certificate and CA creation process and avoid key format issues.
 
 // createHostCertificate creates a certificate for the host to authenticate to the container
-func (c *SSHTheater) createHostCertificate(identityPath string) error {
+func (c *LocalSSHimmer) createHostCertificate(identityPath string) error {
 	// For testing purposes, create a minimal empty certificate
 	// This check will only be true in tests
 	if _, ok := c.kg.(interface{ IsMock() bool }); ok {
diff --git a/dockerimg/ssh_theater_test.go b/dockerimg/local_sshimmer_test.go
similarity index 92%
rename from dockerimg/ssh_theater_test.go
rename to dockerimg/local_sshimmer_test.go
index c8a7362..d3deb1e 100644
--- a/dockerimg/ssh_theater_test.go
+++ b/dockerimg/local_sshimmer_test.go
@@ -118,7 +118,7 @@
 	}
 
 	// For OpenFile, we'll just use WriteFile to simulate file operations
-	// The actual file handle isn't used for much in the sshtheater code
+	// The actual file handle isn't used for much in the localsshimmer code
 	// but we still need to return a valid file handle
 	tmpFile, err := os.CreateTemp("", "mockfile-*")
 	if err != nil {
@@ -259,8 +259,8 @@
 	return mockFS, mockKG, privateKey
 }
 
-// Helper function to setup a basic SSHTheater for testing
-func setupTestSSHTheater(t *testing.T) (*SSHTheater, *MockFileSystem, *MockKeyGenerator) {
+// Helper function to setup a basic LocalSSHimmer for testing
+func setupTestLocalSSHimmer(t *testing.T) (*LocalSSHimmer, *MockFileSystem, *MockKeyGenerator) {
 	mockFS, mockKG, _ := setupMocks(t)
 
 	// Setup home dir in mock filesystem
@@ -279,16 +279,16 @@
 	os.Setenv("HOME", homePath)
 	t.Cleanup(func() { os.Setenv("HOME", oldHome) })
 
-	// Create SSH Theater with mocks
-	ssh, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	// Create LocalSSHimmer with mocks
+	ssh, err := newLocalSSHimmerWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
 	if err != nil {
-		t.Fatalf("Failed to create SSHTheater: %v", err)
+		t.Fatalf("Failed to create LocalSSHimmer: %v", err)
 	}
 
 	return ssh, mockFS, mockKG
 }
 
-func TestNewSSHTheatherCreatesRequiredDirectories(t *testing.T) {
+func TestNewLocalSSHimmerCreatesRequiredDirectories(t *testing.T) {
 	mockFS, mockKG, _ := setupMocks(t)
 
 	// Set HOME environment variable for the test
@@ -303,10 +303,10 @@
 	knownHostsPath := filepath.Join(sketchDir, "known_hosts")
 	mockFS.Files[knownHostsPath] = []byte("")
 
-	// Create theater
-	_, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	// Create sshimmer
+	_, err := newLocalSSHimmerWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
 	if err != nil {
-		t.Fatalf("Failed to create SSHTheater: %v", err)
+		t.Fatalf("Failed to create LocalSSHimmer: %v", err)
 	}
 
 	// Check if the .config/sketch directory was created
@@ -317,7 +317,7 @@
 }
 
 func TestCreateKeyPairIfMissing(t *testing.T) {
-	ssh, mockFS, _ := setupTestSSHTheater(t)
+	ssh, mockFS, _ := setupTestLocalSSHimmer(t)
 
 	// Test key pair creation
 	keyPath := "/home/testuser/.config/sketch/test_key"
@@ -348,7 +348,7 @@
 // This test uses a direct approach since the OpenFile mocking is complex
 func TestAddContainerToSSHConfig(t *testing.T) {
 	// Create a temporary directory for test files
-	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
+	tempDir, err := os.MkdirTemp("", "localsshimmer-test-*")
 	if err != nil {
 		t.Fatalf("Failed to create temp dir: %v", err)
 	}
@@ -365,8 +365,8 @@
 		t.Fatalf("Failed to write initial config: %v", err)
 	}
 
-	// Create a theater with the real filesystem but custom paths
-	ssh := &SSHTheater{
+	// Create a sshimmer with the real filesystem but custom paths
+	ssh := &LocalSSHimmer{
 		cntrName:         "test-container",
 		sshHost:          "localhost",
 		sshPort:          "2222",
@@ -415,14 +415,14 @@
 
 func TestAddContainerToKnownHosts(t *testing.T) {
 	// Skip this test as it requires more complex setup
-	// The TestSSHTheaterCleanup test covers the addContainerToKnownHosts
+	// The TestLocalSSHimmerCleanup test covers the addContainerToKnownHosts
 	// functionality in a more integrated way
-	t.Skip("This test requires more complex setup, integrated test coverage exists in TestSSHTheaterCleanup")
+	t.Skip("This test requires more complex setup, integrated test coverage exists in TestLocalSSHimmerCleanup")
 }
 
 func TestRemoveContainerFromSSHConfig(t *testing.T) {
 	// Create a temporary directory for test files
-	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
+	tempDir, err := os.MkdirTemp("", "localsshimmer-test-*")
 	if err != nil {
 		t.Fatalf("Failed to create temp dir: %v", err)
 	}
@@ -457,8 +457,8 @@
 		t.Fatalf("Failed to write initial SSH config: %v", err)
 	}
 
-	// Create a theater with the real filesystem but custom paths
-	ssh := &SSHTheater{
+	// Create a sshimmer with the real filesystem but custom paths
+	ssh := &LocalSSHimmer{
 		cntrName:         cntrName,
 		sshHost:          sshHost,
 		sshPort:          sshPort,
@@ -493,7 +493,7 @@
 }
 
 func TestRemoveContainerFromKnownHosts(t *testing.T) {
-	ssh, mockFS, _ := setupTestSSHTheater(t)
+	ssh, mockFS, _ := setupTestLocalSSHimmer(t)
 
 	// Setup server public key
 	_, publicKey, _ := ssh.kg.GenerateKeyPair()
@@ -535,9 +535,9 @@
 	}
 }
 
-func TestSSHTheaterCleanup(t *testing.T) {
+func TestLocalSSHimmerCleanup(t *testing.T) {
 	// Create a temporary directory for test files
-	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
+	tempDir, err := os.MkdirTemp("", "localsshimmer-test-*")
 	if err != nil {
 		t.Fatalf("Failed to create temp dir: %v", err)
 	}
@@ -563,12 +563,12 @@
 	os.WriteFile(sshConfigPath, []byte("initial ssh_config content"), 0o644)
 	os.WriteFile(knownHostsPath, []byte("initial known_hosts content"), 0o644)
 
-	// Create a theater with the real filesystem but custom paths
+	// Create a sshimmer with the real filesystem but custom paths
 	cntrName := "test-container"
 	sshHost := "localhost"
 	sshPort := "2222"
 
-	ssh := &SSHTheater{
+	ssh := &LocalSSHimmer{
 		cntrName:           cntrName,
 		sshHost:            sshHost,
 		sshPort:            sshPort,
@@ -691,7 +691,7 @@
 	}
 }
 
-func TestSSHTheaterWithErrors(t *testing.T) {
+func TestLocalSSHimmerWithErrors(t *testing.T) {
 	// Test directory creation failure
 	mockFS := NewMockFileSystem()
 	mockFS.FailOn["MkdirAll"] = fmt.Errorf("mock mkdir error")
@@ -702,8 +702,8 @@
 	os.Setenv("HOME", "/home/testuser")
 	defer func() { os.Setenv("HOME", oldHome) }()
 
-	// Try to create theater with failing FS
-	_, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	// Try to create sshimmer with failing FS
+	_, err := newLocalSSHimmerWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
 	if err == nil || !strings.Contains(err.Error(), "mock mkdir error") {
 		t.Errorf("Should have failed with mkdir error, got: %v", err)
 	}
@@ -713,7 +713,7 @@
 	mockKG = NewMockKeyGenerator(nil, nil, nil, nil)
 	mockKG.FailOn["GenerateKeyPair"] = fmt.Errorf("mock key generation error")
 
-	_, err = newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
+	_, err = newLocalSSHimmerWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
 	if err == nil || !strings.Contains(err.Error(), "key generation error") {
 		t.Errorf("Should have failed with key generation error, got: %v", err)
 	}
diff --git a/webui/src/web-components/DEAR_LLM.md b/webui/src/web-components/DEAR_LLM.md
index 13fd9d1..861cf68 100644
--- a/webui/src/web-components/DEAR_LLM.md
+++ b/webui/src/web-components/DEAR_LLM.md
@@ -45,24 +45,20 @@
 Regarding how CSS rules defined in sketch-tool-card affect elements that contain it:
 
 1. **Shadow DOM Encapsulation**:
-
    - Each Web Component has its own Shadow DOM, which encapsulates its styles
    - Styles defined in `sketch-tool-card` apply only within its shadow DOM, not to parent components
 
 2. **Slot Content Styling**:
-
    - The base `sketch-tool-card` defines three slots: "summary", "input", and "result"
    - Specialized tool cards provide content for these slots
    - The base component can style the slot containers, but cannot directly style the slotted content
 
 3. **Style Inheritance and Sharing**:
-
    - The code uses a `commonStyles` constant that is shared across some components
    - These common styles ensure consistent styling for elements like pre, code blocks
    - Each specialized component adds its own unique styles as needed
 
 4. **Parent CSS Targeting**:
-
    - In `sketch-timeline-message.ts`, there are styles that target the tool components using the `::slotted()` pseudo-element:
 
    ```css
@@ -73,7 +69,6 @@
      word-break: break-word;
    }
    ```
-
    - This allows parent components to influence the layout of slotted components while preserving Shadow DOM encapsulation
 
 5. **Host Element Styling**: