# Gadget Code: GadgetLogTransportSocket

GadgetLog now ships four transports out of the box: **Console**, **File**, **Socket**, and the abstract base. The socket transport (`GadgetLogTransportSocket`) transmits every log entry from `gadget-drone` → `gadget-code:backend` → `gadget-code:frontend` over Socket.IO, rendering live in the IDE's LogPanel.

## Message Flow

```
gadget-drone
  │ GadgetLogTransportSocket.writeLog()
  │ socket.emit("log", timestamp, component, level, message, metadata?)
  ▼
gadget-code:backend (DroneSession.onLog)
  │ SocketService.getCodeSessionByChatSessionId(chatSessionId)
  │ codeSession.onLog(...)
  ▼
gadget-code:backend (CodeSession.onLog)
  │ socket.emit("log", timestamp, component, level, message, metadata?)
  ▼
gadget-code:frontend (SocketClient)
  │ raw socket "log" → internal "log:entry" event
  │ { level, component, message, metadata, timestamp }
  ▼
ChatSessionView.handleLogEntry
  │ setLogs(...)
  ▼
LogPanel — terminal-styled live log viewer
```

## Transport: `GadgetLogTransportSocket`

**File:** `packages/api/src/lib/log-transport-socket.ts`

Accepts a generic emit function (no Socket.IO dependency in `@gadget/api`):

```typescript
export type LogEmitFunction = (
  event: string,
  timestamp: Date,
  component: GadgetComponent,
  level: GadgetLogLevel,
  message: string,
  metadata?: unknown,
) => void;
```

`writeLog()` calls `this.emit("log", ...)` with the same parameters `GadgetLog.writeLog()` receives.

## Registration in gadget-drone

Registered in `gadget-drone.ts` `connectSocket()`, after the Socket.IO connection succeeds:

```typescript
const socketTransport = new GadgetLogTransportSocket((event, ...args) => {
  (this.socket as any)?.emit(event, ...args);
});
GadgetLog.addDefaultTransport(socketTransport);
this.log.transports.push(socketTransport);
AgentService.log.transports.push(socketTransport);
AiService.log.transports.push(socketTransport);
PlatformService.log.transports.push(socketTransport);
```

The transport is injected into all existing loggers (main process + 3 services) and set as a default for future `GadgetLog` instances.

## Backend Routing

### DroneSession (`gadget-code/src/lib/drone-session.ts`)

- Registers `this.socket.on("log", this.onLog.bind(this))`
- `onLog()` guards on `this.chatSessionId`, looks up the `CodeSession` via `SocketService.getCodeSessionByChatSessionId()`, forwards the call.

### CodeSession (`gadget-code/src/lib/code-session.ts`)

- `onLog()` calls `this.socket.emit("log", timestamp, component, level, message, metadata)` forwards to the IDE.

## Frontend Bridging

### SocketClient (`gadget-code/frontend/src/lib/socket.ts`)

The raw Socket.IO `log` event is forwarded to the internal `log:entry` event system:

```typescript
this.socket.on("log", (timestamp, component, level, message, metadata) => {
  this.emit("log:entry", {
    level,
    component: component.name,
    message,
    metadata,
    timestamp: new Date(timestamp).getTime(),
  });
});
```

### ChatSessionView

`handleLogEntry` callback builds a `LogEntry` with all fields and appends to the `logs` state array.

## LogPanel Display

**File:** `gadget-code/frontend/src/components/LogPanel.tsx`

Styled to match the Console Transport:

| Element | Console Color | Tailwind Class |
|---------|---------------|----------------|
| Timestamp | `darkGray` | `text-gray-600` |
| Level: debug | `darkGray` | `text-gray-500` |
| Level: info | `green` | `text-green-400` |
| Level: warn | `yellow` | `text-yellow-400` |
| Level: alert | `red` | `text-red-400` |
| Level: error | `bgRed` + `white` | `bg-red-800 text-white` |
| Level: crit | `bgRed` + `yellow` | `bg-red-800 text-yellow-300` |
| Level: fatal | `bgRed` + `darkGray` | `bg-red-800 text-gray-400` |
| Component | `cyan` | `text-cyan-400` |
| Message | `darkGray` | `text-text-secondary` |

Metadata is displayed as expandable JSON below the log line (toggled with `⊞`/`⊟`).

## Files Changed

| File | Action |
|------|--------|
| `packages/api/src/lib/log-transport-socket.ts` | **NEW** — socket transport |
| `packages/api/src/index.ts` | **MODIFY** — export new transport |
| `gadget-drone/src/gadget-drone.ts` | **MODIFY** — register transport on connect |
| `gadget-drone/src/lib/service.ts` | **MODIFY** — `log` public for transport injection |
| `gadget-code/src/lib/drone-session.ts` | **MODIFY** — `onLog` handler |
| `gadget-code/src/lib/code-session.ts` | **MODIFY** — `onLog` forwarding |
| `gadget-code/frontend/src/lib/socket.ts` | **MODIFY** — bridge `log` → `log:entry` |
| `gadget-code/frontend/src/pages/ChatSessionView.tsx` | **MODIFY** — enriched `LogEntry` |
| `gadget-code/frontend/src/components/LogPanel.tsx` | **REWRITE** — console-styled display |
