diff --git a/AGENTS.md b/AGENTS.md index dad6684f..bdfa3e5d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,9 @@ Before making changes, read in this order: - `ui/`: React + Vite board UI - `packages/db/`: Drizzle schema, migrations, DB clients - `packages/shared/`: shared types, constants, validators, API path constants +- `packages/adapters/`: agent adapter implementations (Claude, Codex, Cursor, etc.) +- `packages/adapter-utils/`: shared adapter utilities +- `packages/plugins/`: plugin system packages - `doc/`: operational and product docs ## 4. Dev Setup (Auto DB) diff --git a/doc/SPEC.md b/doc/SPEC.md index 82315bce..6a7039ca 100644 --- a/doc/SPEC.md +++ b/doc/SPEC.md @@ -186,17 +186,21 @@ The heartbeat is a protocol, not a runtime. Paperclip defines how to initiate an ### Execution Adapters -Agent configuration includes an **adapter** that defines how Paperclip invokes the agent. Initial adapters: +Agent configuration includes an **adapter** that defines how Paperclip invokes the agent. Built-in adapters include: -| Adapter | Mechanism | Example | -| -------------------- | ----------------------- | --------------------------------------------- | -| `process` | Execute a child process | `python run_agent.py --agent-id {id}` | -| `http` | Send an HTTP request | `POST https://openclaw.example.com/hook/{id}` | -| `openclaw_gateway` | OpenClaw gateway API | Managed OpenClaw agent via gateway | -| `gemini_local` | Gemini CLI process | Local Gemini CLI with sandbox and approval | -| `hermes_local` | Hermes agent process | Local Hermes agent | +| Adapter | Mechanism | Example | +| ---------------- | -------------------------- | -------------------------------------------------- | +| `process` | Execute a child process | `python run_agent.py --agent-id {id}` | +| `http` | Send an HTTP request | `POST https://openclaw.example.com/hook/{id}` | +| `claude_local` | Local Claude Code process | Claude Code heartbeat worker | +| `codex_local` | Local Codex process | Codex CLI heartbeat worker | +| `opencode_local` | Local OpenCode process | OpenCode heartbeat worker | +| `pi_local` | Local Pi process | Pi CLI heartbeat worker | +| `cursor` | Cursor API/CLI bridge | Cursor-integrated heartbeat worker | +| `openclaw_gateway` | OpenClaw gateway API | Managed OpenClaw agent via gateway | +| `hermes_local` | Local Hermes process | Hermes agent heartbeat worker | -The `process` and `http` adapters ship as defaults. Additional adapters have been added for specific agent runtimes (see list above), and new adapter types can be registered via the plugin system (see Plugin / Extension Architecture). +The `process` and `http` adapters ship as generic defaults. Additional built-in adapters cover common local coding runtimes (see list above), and new adapter types can be registered via the plugin system (see Plugin / Extension Architecture). ### Adapter Interface @@ -376,7 +380,7 @@ Flow: | Layer | Technology | | -------- | ------------------------------------------------------------ | | Frontend | React + Vite | -| Backend | TypeScript + Hono (REST API, not tRPC — need non-TS clients) | +| Backend | TypeScript + Express (REST API, not tRPC — need non-TS clients) | | Database | PostgreSQL (see [doc/DATABASE.md](./doc/DATABASE.md) for details — PGlite embedded for dev, Docker or hosted Supabase for production) | | Auth | [Better Auth](https://www.better-auth.com/) | @@ -406,7 +410,7 @@ No separate "agent API" vs. "board API." Same endpoints, different authorization ### Work Artifacts -Paperclip does **not** manage work artifacts (code repos, file systems, deployments, documents). That's entirely the agent's domain. Paperclip tracks tasks and costs. Where and how work gets done is outside scope. +Paperclip manages task-linked work artifacts: issue documents (rich-text plans, specs, notes attached to issues) and file attachments. Agents read and write these through the API as part of normal task execution. Full delivery infrastructure (code repos, deployments, production runtime) remains the agent's domain — Paperclip orchestrates the work, not the build pipeline. ### Open Questions @@ -476,15 +480,14 @@ Each is a distinct page/route: - [ ] **Default agent** — basic Claude Code/Codex loop with Paperclip skill - [ ] **Default CEO** — strategic planning, delegation, board communication - [ ] **Paperclip skill (SKILL.md)** — teaches agents to interact with the API -- [ ] **REST API** — full API for agent interaction (Hono) +- [ ] **REST API** — full API for agent interaction (Express) - [ ] **Web UI** — React/Vite: org chart, task board, dashboard, cost views - [ ] **Agent auth** — connection string generation with URL + key + instructions - [ ] **One-command dev setup** — embedded PGlite, everything local -- [ ] **Multiple Adapter types** (HTTP Adapter, OpenClaw Adapter) +- [ ] **Multiple Adapter types** (HTTP, OpenClaw gateway, and local coding adapters) ### Not V1 -- Template export/import - Knowledge base - a future plugin - Advanced governance models (hiring budgets, multi-member boards) - Revenue/expense tracking beyond token costs - a future plugin @@ -509,7 +512,7 @@ Things Paperclip explicitly does **not** do: - **Not a SaaS** — single-tenant, self-hosted - **Not opinionated about Agent implementation** — any language, any framework, any runtime - **Not automatically self-healing** — surfaces problems, doesn't silently fix them -- **Does not manage work artifacts** — no repo management, no deployment, no file systems +- **Does not manage delivery infrastructure** — no repo management, no deployment, no file systems (but does manage task-linked documents and attachments) - **Does not auto-reassign work** — stale tasks are surfaced, not silently redistributed - **Does not track external revenue/expenses** — that's a future plugin. Token/LLM cost budgeting is core. diff --git a/docs/agents-runtime.md b/docs/agents-runtime.md index bda72729..f3672723 100644 --- a/docs/agents-runtime.md +++ b/docs/agents-runtime.md @@ -1,7 +1,7 @@ # Agent Runtime Guide -Status: User-facing guide -Last updated: 2026-02-17 +Status: User-facing guide +Last updated: 2026-03-26 Audience: Operators setting up and running agents in Paperclip ## 1. What this system does @@ -32,14 +32,19 @@ If an agent is already running, new wakeups are merged (coalesced) instead of la ## 3.1 Adapter choice -Common choices: +Built-in adapters: - `claude_local`: runs your local `claude` CLI - `codex_local`: runs your local `codex` CLI +- `opencode_local`: runs your local `opencode` CLI +- `hermes_local`: runs your local `hermes` CLI +- `cursor`: runs Cursor in background mode +- `pi_local`: runs an embedded Pi agent locally +- `openclaw_gateway`: connects to an OpenClaw gateway endpoint - `process`: generic shell command adapter - `http`: calls an external HTTP endpoint -For `claude_local` and `codex_local`, Paperclip assumes the CLI is already installed and authenticated on the host machine. +For local CLI adapters (`claude_local`, `codex_local`, `opencode_local`, `hermes_local`), Paperclip assumes the CLI is already installed and authenticated on the host machine. ## 3.2 Runtime behavior @@ -69,6 +74,8 @@ You can set: Templates support variables like `{{agent.id}}`, `{{agent.name}}`, and run context values. +> **Note:** `bootstrapPromptTemplate` is deprecated and should not be used for new agents. Existing configs that use it will continue to work but should be migrated to the managed instructions bundle system. + ## 4. Session resume behavior Paperclip stores session IDs for resumable adapters. @@ -133,7 +140,7 @@ If the connection drops, the UI reconnects automatically. If runs fail repeatedly: -1. Check adapter command availability (`claude`/`codex` installed and logged in). +1. Check adapter command availability (e.g. `claude`/`codex`/`opencode`/`hermes` installed and logged in). 2. Verify `cwd` exists and is accessible. 3. Inspect run error + stderr excerpt, then full log. 4. Confirm timeout is not too low. @@ -166,9 +173,9 @@ Start with least privilege where possible, and avoid exposing secrets in broad r ## 10. Minimal setup checklist -1. Choose adapter (`claude_local` or `codex_local`). -2. Set `cwd` to the target workspace. -3. Add bootstrap + normal prompt templates. +1. Choose adapter (e.g. `claude_local`, `codex_local`, `opencode_local`, `hermes_local`, `cursor`, or `openclaw_gateway`). +2. Set `cwd` to the target workspace (for local adapters). +3. Optionally add a prompt template (`promptTemplate`) or use the managed instructions bundle. 4. Configure heartbeat policy (timer and/or assignment wakeups). 5. Trigger a manual wakeup. 6. Confirm run succeeds and session/token usage is recorded. diff --git a/ui/src/components/MarkdownEditor.tsx b/ui/src/components/MarkdownEditor.tsx index 342a74de..68469761 100644 --- a/ui/src/components/MarkdownEditor.tsx +++ b/ui/src/components/MarkdownEditor.tsx @@ -8,6 +8,7 @@ import { useState, type DragEvent, } from "react"; +import { createPortal } from "react-dom"; import { CodeMirrorEditor, MDXEditor, @@ -82,6 +83,9 @@ interface MentionState { query: string; top: number; left: number; + /** Viewport-relative coords for portal positioning */ + viewportTop: number; + viewportLeft: number; textNode: Text; atPos: number; endPos: number; @@ -155,6 +159,8 @@ function detectMention(container: HTMLElement): MentionState | null { query, top: rect.bottom - containerRect.top, left: rect.left - containerRect.left, + viewportTop: rect.bottom, + viewportLeft: rect.left, textNode: textNode as Text, atPos, endPos: offset, @@ -554,46 +560,48 @@ export const MarkdownEditor = forwardRef plugins={plugins} /> - {/* Mention dropdown */} - {mentionActive && filteredMentions.length > 0 && ( -
- {filteredMentions.map((option, i) => ( - - ))} -
- )} + {/* Mention dropdown — rendered via portal so it isn't clipped by overflow containers */} + {mentionActive && filteredMentions.length > 0 && + createPortal( +
+ {filteredMentions.map((option, i) => ( + + ))} +
, + document.body, + )} {isDragOver && canDropImage && (