)]}'
{
  "commit": "138ec2436631f136dd2e8b4891211f896587ff00",
  "tree": "80afc394ad900e6e7a0a7b524972a303ef90ef15",
  "parents": [
    "457dfd12f281dbe9b1af8d1a7429f2977e234a6f"
  ],
  "author": {
    "name": "Sean McCullough",
    "email": "banksean@gmail.com",
    "time": "Mon Jun 02 22:42:06 2025 +0000"
  },
  "committer": {
    "name": "Sean McCullough",
    "email": "banksean@gmail.com",
    "time": "Mon Jun 02 17:52:38 2025 -0700"
  },
  "message": "loop: automatic host/container ssh port tunneling\n\nFix for #47\n\nAdd comprehensive port event monitoring and automatic SSH tunnel management\nsystem that enables real-time port forwarding for container services.\n\nContainer processes need automatic port forwarding when services start or stop\nlistening on ports during agent execution. Previously, users had to manually\ncreate SSH tunnels using commands like \u0027ssh -L8000:localhost:8888 container\u0027,\nwhich required manual intervention and knowledge of when ports become available.\n\n- Extended PortMonitor with thread-safe event storage using circular buffer\n- Added PortEvent struct with type (opened/closed), port info, and timestamps\n- Maintained backward compatibility with existing logging functionality\n- Events stored in 100-item circular buffer with efficient timestamp filtering\n\n- Added /port-events endpoint in loophttp.go for container-to-host communication\n- Supports optional \u0027since\u0027 query parameter for incremental event fetching\n- Returns JSON array of recent port events with proper error handling\n- Integrated with existing Agent interface via GetPortMonitor() method\n\n- Created TunnelManager component for host-side tunnel orchestration\n- Polls container /port-events endpoint every 10 seconds for new events\n- Automatically creates SSH tunnels when ports open using same port numbers\n- Properly cleans up tunnels when ports close or context cancels\n- Skips common system ports (SSH, HTTP, SMTP) to avoid conflicts\n\n- Integrated TunnelManager into dockerimg.LaunchContainer() workflow\n- Starts tunnel manager alongside existing container management goroutines\n- Only activates when SSH is available and configured properly\n- Uses existing SSH infrastructure and container naming conventions\n\n- Container PortMonitor detects port changes via ss -lntu command\n- Events stored with RFC3339 timestamps for precise filtering\n- Thread-safe access patterns with dedicated mutex protection\n- Circular buffer prevents unbounded memory growth\n\n- RESTful GET /port-events endpoint with time-based filtering\n- Proper JSON encoding/decoding with error handling\n- Integration with existing HTTP server infrastructure\n- Non-blocking polling pattern with configurable intervals\n\n- Uses existing SSH theater configuration and host keys\n- Creates tunnels with format: ssh -L hostPort:localhost:containerPort container\n- Background monitoring of tunnel processes with automatic cleanup\n- Proper context cancellation and resource management\n\n- Added comprehensive port event storage and filtering tests\n- HTTP endpoint testing with mock agents and proper status codes\n- Verified thread-safe access patterns and circular buffer behavior\n- All existing loop package tests continue to pass\n\n- Confirmed HTTP endpoint returns proper JSON responses\n- Validated tunnel manager integrates with container launch process\n- Verified SSH tunnel creation follows existing authentication patterns\n- Build verification confirms no regressions in existing functionality\n\n- Automatic port forwarding eliminates manual SSH tunnel management\n- Real-time port detection provides immediate service accessibility\n- Transparent integration with existing Sketch container workflow\n- Maintains all existing SSH functionality and manual override options\n\n- Clean separation between container monitoring and host tunnel management\n- Extensible event-based architecture for future port-related features\n- Minimal performance impact with efficient polling and filtering\n- Robust error handling and graceful degradation when SSH unavailable\n\nThis enhancement provides seamless port forwarding automation while maintaining\nthe reliability and security of the existing SSH infrastructure, significantly\nimproving the developer experience when working with containerized services.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s6bc363ed64835e5dk\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "66fd691b6ec1a8d0886dbb62f0daf7dab6d5dcf3",
      "old_mode": 33188,
      "old_path": "dockerimg/dockerimg.go",
      "new_id": "ad1824625976248b1e6c2ac13e960d88f346d2d1",
      "new_mode": 33188,
      "new_path": "dockerimg/dockerimg.go"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "6cd50ff64dcbbb8152eb029f5a3a68ae75007257",
      "new_mode": 33188,
      "new_path": "dockerimg/tunnel_manager.go"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f43055934a01c02a5648e11c4fd0757a7eeaedd4",
      "new_mode": 33188,
      "new_path": "dockerimg/tunnel_manager_test.go"
    },
    {
      "type": "modify",
      "old_id": "c4cbd05eeab933b719138d40b8e59afde5a50a39",
      "old_mode": 33188,
      "old_path": "loop/agent.go",
      "new_id": "4a27ab082aefad6be06554fac162ac05118b0546",
      "new_mode": 33188,
      "new_path": "loop/agent.go"
    },
    {
      "type": "modify",
      "old_id": "514e92813effa8b4c77b65bd81264424eefc1d27",
      "old_mode": 33188,
      "old_path": "loop/port_monitor.go",
      "new_id": "9614db20608793493cc5844da25221c73f659389",
      "new_mode": 33188,
      "new_path": "loop/port_monitor.go"
    },
    {
      "type": "modify",
      "old_id": "8f474e0b16b916de437d3c7dacb5607970d942bf",
      "old_mode": 33188,
      "old_path": "loop/port_monitor_test.go",
      "new_id": "a1dad57830cf48dacc3ec8f93e51f748730e7eb0",
      "new_mode": 33188,
      "new_path": "loop/port_monitor_test.go"
    },
    {
      "type": "modify",
      "old_id": "53776aa170ff114debb55a33d0d8c4c0c8eb2558",
      "old_mode": 33188,
      "old_path": "loop/server/loophttp.go",
      "new_id": "784d20b938ce405bfc7c147d9550234d4c0c9aab",
      "new_mode": 33188,
      "new_path": "loop/server/loophttp.go"
    },
    {
      "type": "modify",
      "old_id": "d755717eb2e8890c2edadbb3120cab7fdfd2870c",
      "old_mode": 33188,
      "old_path": "loop/server/loophttp_test.go",
      "new_id": "a6dab625fc42329247a656c1c742d7ff1beda63a",
      "new_mode": 33188,
      "new_path": "loop/server/loophttp_test.go"
    }
  ]
}
