WebChat - Transform CLI into a Conversation

WebChat makes any agent CLI available through a chat-style interface that users can reach from their browser.

What WebChat Delivers

πŸ’¬

Conversational UI

Stream CLI input/output through a WhatsApp-inspired interface with bubbles, timestamps, and typing indicators.

πŸ”

Token Security

Each session is gated by an access token that lives in .ploinky/.secrets. Share the URL to grant access.

πŸ› οΈ

Agent Ready

When a static workspace agent is configured, WebChat automatically connects to that agent’s manifest cli command.

Access & Tokens

Use ploinky webchat to print the current access URL or pass --rotate to mint a fresh token when needed.

ploinky webchat          # ensure token and show access URL
ploinky webchat --rotate # regenerate the token
Access URL format: http://127.0.0.1:8080/webchat?token=<WEBCHAT_TOKEN>

The token is stored as WEBCHAT_TOKEN in .ploinky/.secrets. Removing the entry or using --rotate forces a regeneration.

How Commands Are Chosen

WebChat derives its runtime command from the static workspace agent:

  1. Static agent – Configure one with ploinky start <agent> <port>. The router records the agent’s manifest path.
  2. Manifest CLI – When the agent’s manifest.json defines a cli command, WebChat runs it inside the agent container.
  3. No CLI? – Sessions still open, but the chat will display a notice that no command is bound.

This flow depends entirely on the static workspace agent: keep its manifest updated to control which CLI the chat session runs.

URL Parameters and CLI Arguments

WebChat accepts arbitrary query parameters in its URL. When an explicit agent query parameter is present, the router keeps the remaining query parameters attached to the WebChat session and forwards them to that agent's CLI command as long-form CLI flags encoded as single tokens.

/webchat?agent=achilles-cli&path=/absolute/path

# launches the selected agent as:
ploinky cli achilles-cli --path=/absolute/path

The router reserves agent for agent selection and tabId for the browser session stream. Agent CLIs are responsible for interpreting any forwarded flags and values.

Session Experience

Message Rendering

  • βœ… Automatic timestamps for each exchange
  • βœ… Rich markdown rendering (tables, code blocks, lists)
  • βœ… Long output folding with β€œShow more” expansion
  • βœ… Agent progress metadata displayed as a collapsible block above the final answer
  • βœ… Side panel to inspect full message history

Input Controls

  • βœ… Auto-resizing composer with keyboard shortcuts (Enter to send, Shift+Enter for new line)
  • βœ… Light/Dark/Explorer/Obsidian Dark theme selector with persistent preference (Explorer loads by default; switch via Settings β†’ Appearance)
  • βœ… Optional speech-to-text and text-to-speech integrations (see cli/server/webchat/strategies)
  • βœ… Slash command autocomplete β€” type / to open a command menu; supports agent-declared subcommands and argument completions
  • βœ… Composer @ autocomplete β€” typing @ opens a grouped menu of static configured tags plus files and folders uploaded in the current WebChat session; selecting a file inserts a stable @file:uploads/<sessionId>/<path> token and attaches a structured reference to the outgoing envelope
  • βœ… Cancel button β€” appears during active processing; sends an interrupt signal to the agent

Session Uploads

WebChat stores uploaded files in a per-session directory under the current working directory: <cwd>/uploads/<webchat_sid>/. webchat_sid is the WebChat session cookie issued to the authenticated browser; it is not the browser tab id.

  • The attachment menu has Upload file and Upload folder entries. Folder uploads preserve file.webkitRelativePath as the relative path inside the session upload directory.
  • Composer @ suggestions search only the current session upload directory. Other sessions' uploads never appear.
  • Uploads use POST /webchat/uploads and are read back via GET /webchat/uploads?path=<session-relative-path>. Downloads reuse stored MIME metadata and set X-Content-Type-Options: nosniff. The server rejects absolute paths, traversal segments, NUL bytes, symlink escapes, and reserved .secrets/*.secrets names.

Security Practices

  • Rotate tokens regularly with ploinky webchat --rotate.
  • Prefer sharing short-lived tokens and revoke access by rotating after a session concludes.
  • Remember that tokens live in .ploinky/.secrets; secure that directory if you back it up or sync it.

Troubleshooting

  • Blank session? Verify the static agent has a cli command in its manifest.
  • 401 errors? Run ploinky webchat again to confirm the token and URL.
  • Need a different command? Update the agent manifest and restart the workspace so WebChat picks up the change.
  • Custom launch flags ignored? Confirm you opened /webchat with ?agent=<name>; without an explicit agent selection the router uses the default WebChat target and does not synthesize agent-specific CLI flags.