How the Pack Cockpit Persists Lieutenant Chat and Injects Responses in SwarmForge

The pack cockpit persists lieutenant chat by writing messages to a text file in .swarmforge/sessions/lieutenant/pane.txt and injects responses by reading that same file via the pane-status-lines-for function.

The pack cockpit is the browser-based dashboard that visualizes SwarmForge state. Understanding how the pack cockpit persists lieutenant chat and injects responses reveals a lightweight, file-based approach that enables durable, real-time chat functionality without complex database infrastructure.

Persisting Lieutenant Chat to Disk

When a lieutenant pane is created, SwarmForge writes chat lines to a file inside the project's hidden .swarmforge directory:


.swarmforge/sessions/lieutenant/pane.txt

This plain-text storage provides durability across sessions. The conversation history survives browser refreshes and system restarts because it lives on disk rather than in volatile memory.

The pane-status-lines-for function reads this file and returns the lines as a list of status strings. In swarmforge/scripts/pack_web.bb, line 803 implements this retrieval:

:lieutenant_status (pane-status-lines-for root "lieutenant")

This key-value pair becomes part of the data object served to the cockpit interface.

Injecting Responses into the Cockpit UI

The cockpit's HTML page ([swarmforge/scripts/pack/dashboard.html](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/pack/dashboard.html)) expects the lieutenant_status field. When the page loads, JavaScript pulls the data and renders each line in the cockpit area.

Line 1372 of dashboard.html shows the initialization:

const statusLines = data.lieutenant_status || [];

The front-end then updates the display whenever new lines appear in the pane file. This polling-based mechanism lets lieutenant replies appear in real-time without WebSocket infrastructure.

The UI includes pending-reply markers—visualized as a green "|" under the request—indicating when the lieutenant is processing a message.

End-to-End Message Flow

The complete lifecycle of a chat message follows this pattern:

  1. User input: A message typed in the cockpit's chat composer is written to the pane file via the SwarmForge CLI
  2. Agent processing: The lieutenant agent (default: grok) reads the new entry and generates a response
  3. Response persistence: The lieutenant appends its reply to the same pane file
  4. UI refresh: The next poll of pane-status-lines-for returns the updated list, which the cockpit renders

This file-based architecture decouples the web interface from the agent logic, allowing either component to be restarted independently without message loss.

Test Coverage for Chat Persistence

The implementation is verified by two key test suites:

Summary

  • Persistence mechanism: Plain-text file at .swarmforge/sessions/lieutenant/pane.txt
  • Read function: pane-status-lines-for in pack_web.bb extracts status lines
  • Data binding: :lieutenant_status key in the cockpit data object
  • UI rendering: JavaScript in dashboard.html polls and displays status lines
  • Real-time updates: File modifications propagate through repeated function calls
  • Visual indicators: Green "|" markers show pending lieutenant activity

Frequently Asked Questions

What file format does SwarmForge use for lieutenant chat history?

SwarmForge stores lieutenant chat as plain text in .swarmforge/sessions/lieutenant/pane.txt. This format prioritizes simplicity and human readability over structured serialization. Each line represents one status entry or message, making debugging and manual inspection straightforward.

How does the cockpit detect new lieutenant responses?

The cockpit detects new responses through polling the pane-status-lines-for function. Rather than using push-based mechanisms like WebSockets, the dashboard periodically re-reads the pane file. When the returned line count or content changes, the UI updates to display the new messages. This trade-off reduces infrastructure complexity at the cost of slight latency.

Can multiple users view the same lieutenant conversation simultaneously?

Yes. Because the chat state lives in a shared file on disk, any number of cockpit instances can read from .swarmforge/sessions/lieutenant/pane.txt simultaneously. Each viewer independently polls pane-status-lines-for and receives the same conversation history. However, write operations typically require coordination through the SwarmForge CLI to prevent race conditions.

What happens to chat history when the lieutenant process restarts?

The chat history persists across restarts because it is file-based rather than memory-resident. When the lieutenant agent restarts, it reopens pane.txt and continues appending to the existing content. The cockpit similarly resumes polling from the same file, displaying the complete conversation history including messages from before the restart.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →