@paperclipai_dld/paperclip-agent-chat
v0.3.3
Published
Full-page chat plugin for Paperclip — have informal conversations with your AI agents
Readme
Agent Chat — Paperclip Plugin
A full-page chat interface for having informal conversations with your Paperclip agents. Think of it as a water cooler for your AI team — ask questions, get context-aware answers, and have real back-and-forth conversations.
The key difference from a generic chatbot: agents respond with full access to their workspace, codebase, project files, and tools. When you ask the Software Architect about a design decision, they can go read the actual ADR. When you ask the Platform Engineer about a Docker issue, they can check the running containers.
Features
- Full-page UI with agent list sidebar and spacious chat area
- Persistent conversation history per agent (stored in Paperclip plugin state)
- Fire-and-forget messaging — no timeout issues, even for long agent responses
- Optimistic UI — your message appears instantly; typing indicator shows while the agent thinks
- Sidebar navigation link for quick access
- Zero dependencies beyond the Plugin SDK and esbuild
How It Works
- You select an agent and type a message
- The plugin saves your message and writes a conversation context file to disk
- The agent wakes up via a session, reads the context file, and responds using its full workspace access
- The UI polls for the response and displays it when ready
Each message triggers a full agent heartbeat — the agent isn't a stripped-down chatbot, it's the real agent with all its capabilities.
Installation
Prerequisites
- A running Paperclip instance
- Node.js 20+ (available inside the Paperclip container)
- Agents using the
claude_localadapter (Claude Code)
1. Build the Plugin
Clone this repo into a directory accessible from your Paperclip container:
git clone https://github.com/bjmillerpa/paperclip-agent-chat.git
cd paperclip-agent-chatInstall dependencies and build (run inside the Paperclip container, or adjust the SDK path):
# If running inside the Paperclip container:
npm install
node build.mjs
# If running outside, update the SDK path in package.json first:
# "@paperclipai/plugin-sdk": "file:/path/to/paperclip/packages/plugins/sdk"2. Register the Plugin
Register via the Paperclip plugin install API, or insert directly into the database:
INSERT INTO plugins (
id, plugin_key, package_name, package_path,
version, api_version, categories, manifest_json, status
) VALUES (
gen_random_uuid(),
'agent-chat',
'paperclip-agent-chat',
'/path/to/paperclip-agent-chat',
'0.2.0',
1,
'["ui"]'::jsonb,
'<manifest JSON — see src/manifest.js>'::jsonb,
'ready'
);Then restart your Paperclip container to pick up the new plugin.
3. Configure Your Agents
Each agent needs a small addition to its AGENTS.md (or equivalent instructions file) so it knows how to handle chat wakes. Add this section:
## Agent Chat
If `$PAPERCLIP_WAKE_REASON` is `Agent Chat`, skip the normal heartbeat workflow. Instead:
1. Read your chat inbox file at `~/.agent-chat/<your-agent-id>.md`
- Get your agent ID: `curl -s -H "Authorization: Bearer $PAPERCLIP_API_KEY" "$PAPERCLIP_API_URL/api/agents/me" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])"`
2. Respond conversationally to the latest message from the board
3. You have full access to your workspace, project files, and tools — use them
4. Output your response as plain text and exit cleanly
5. Do NOT check the task inbox or do regular heartbeat workThat's it. The agent will now respond to chat messages using its full capabilities.
Configuration
Chat Directory
The plugin writes conversation context files so agents can read them. The default path is hardcoded in src/worker.js — edit it to match your setup before building:
// In src/worker.js:
const AGENT_CHAT_DIR = process.env.AGENT_CHAT_DIR || "/home/youruser/.agent-chat";Important: Plugin workers run as child processes that may not inherit container environment variables. If AGENT_CHAT_DIR isn't available at runtime, the hardcoded fallback is used. Make sure the fallback path is correct for your environment.
The directory must be readable by both the plugin worker and your agent processes. It will be created automatically on first use.
History Limit
Conversation history is capped at 100 messages per agent. This is defined as MAX_HISTORY_MESSAGES in src/worker.js.
Architecture
┌─────────────────────────────────────────────────┐
│ Browser — Agent Chat Page │
│ ┌──────────┐ ┌────────────────────────────┐ │
│ │ Agent │ │ Chat Area │ │
│ │ List │ │ Messages + typing indicator│ │
│ │ │ │ Input + send button │ │
│ └──────────┘ └────────────────────────────┘ │
│ │ │ ▲ │
│ │ usePluginAction │ usePluginData │
│ │ (send-message) │ (chat-history)│
│ │ │ │ polls q/3s │
└───────┼──────────────┼──────────┼────────────────┘
│ ▼ │
┌───────┼─────────────────────────┼────────────────┐
│ Plugin Worker │ │
│ │ │ │
│ ┌────┴─────┐ ┌───────────────┴──┐ │
│ │ agents │ │ send-message │ │
│ │ (data) │ │ (action) │ │
│ └──────────┘ │ 1. Save user msg│ │
│ │ 2. Write .md file│ │
│ ┌──────────┐ │ 3. Return immediately │
│ │ history │ │ 4. Background: │ │
│ │ (data) │◄─│ wake agent │ │
│ └──────────┘ │ wait response│ │
│ │ save history │ │
│ └──────────────────┘ │
└─────────────────────┬───────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Agent (Claude Code) │
│ 1. Reads ~/.agent-chat/<id>.md │
│ 2. Has full workspace + tool access │
│ 3. Responds conversationally │
│ 4. Exits cleanly │
└─────────────────────────────────────────────────┘Key Design Decisions
Fire-and-forget, not request-response. The RPC bridge between UI and worker has a 30-second timeout. Agents can take minutes. The action saves the user message and starts the agent session in the background, returning immediately. The UI polls chat-history every 3 seconds to detect the response.
File-based context, not prompt injection. The conversation history is written as a markdown file that the agent reads with its normal file tools. This gives the agent the full conversation in a format it can reason about naturally.
Optimistic local state with server reconciliation. The user's message appears instantly via local React state. When the server history catches up (user message + agent response), the local state clears and server-persisted history takes over.
File Structure
paperclip-agent-chat/
├── src/
│ ├── manifest.js # Plugin manifest (slots, capabilities)
│ ├── worker.js # Worker (data handlers, actions, agent sessions)
│ └── ui/
│ └── index.js # React UI (createElement, no JSX)
├── build.mjs # esbuild script (worker + manifest + UI)
├── package.json
├── LICENSE # MIT
└── README.mdPlugin SDK APIs Used
ctx.data.register—agents(list agents),chat-history(per-agent history)ctx.actions.register—send-message(fire-and-forget),clear-historyctx.state.get/set— persisted chat history scoped per agentctx.agents.sessions.create/sendMessage/close— wake agents and capture responsesusePluginData— data fetching with.refresh()for pollingusePluginAction— async action invocation- UI slots —
page(full-page chat),sidebar(navigation link)
Blog Post
Read the full story behind building this plugin: Building a Water Cooler for AI Agents
License
MIT
