mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 09:41:04 +01:00
Agents working on the Paperclip repository need to satisfy commitperclip's linked-issue gate when opening PRs. Document the required PR template section, the public issue or inline-description paths, the skip-prefix behavior, and the no-internal-reference rule in the repo-local AGENTS.md instructions. Keep the bundled github-pr-workflow skill generic so these Paperclip-specific rules are not shipped to every Paperclip user. Co-Authored-By: Paperclip <noreply@paperclip.ing>
239 lines
11 KiB
Markdown
239 lines
11 KiB
Markdown
# AGENTS.md
|
|
|
|
Guidance for human and AI contributors working in this repository.
|
|
|
|
## 1. Purpose
|
|
|
|
Paperclip is a control plane for AI-agent companies.
|
|
The current implementation target is V1 and is defined in `doc/SPEC-implementation.md`.
|
|
|
|
## 2. Read This First
|
|
|
|
Before making changes, read in this order:
|
|
|
|
1. `doc/GOAL.md`
|
|
2. `doc/PRODUCT.md`
|
|
3. `doc/SPEC-implementation.md`
|
|
4. `doc/DEVELOPING.md`
|
|
5. `doc/DATABASE.md`
|
|
|
|
`doc/SPEC.md` is long-horizon product context.
|
|
`doc/SPEC-implementation.md` is the concrete V1 build contract.
|
|
|
|
## 3. Repo Map
|
|
|
|
- `server/`: Express REST API and orchestration services
|
|
- `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)
|
|
|
|
Use embedded PGlite in dev by leaving `DATABASE_URL` unset.
|
|
|
|
```sh
|
|
pnpm install
|
|
pnpm dev
|
|
```
|
|
|
|
This starts:
|
|
|
|
- API: `http://localhost:3100`
|
|
- UI: `http://localhost:3100` (served by API server in dev middleware mode)
|
|
|
|
Quick checks:
|
|
|
|
```sh
|
|
curl http://localhost:3100/api/health
|
|
curl http://localhost:3100/api/companies
|
|
```
|
|
|
|
Reset local dev DB:
|
|
|
|
```sh
|
|
rm -rf data/pglite
|
|
pnpm dev
|
|
```
|
|
|
|
## 5. Core Engineering Rules
|
|
|
|
1. Keep changes company-scoped.
|
|
Every domain entity should be scoped to a company and company boundaries must be enforced in routes/services.
|
|
|
|
2. Keep contracts synchronized.
|
|
If you change schema/API behavior, update all impacted layers:
|
|
- `packages/db` schema and exports
|
|
- `packages/shared` types/constants/validators
|
|
- `server` routes/services
|
|
- `ui` API clients and pages
|
|
|
|
3. Preserve control-plane invariants.
|
|
- Single-assignee task model
|
|
- Atomic issue checkout semantics
|
|
- Approval gates for governed actions
|
|
- Budget hard-stop auto-pause behavior
|
|
- Activity logging for mutating actions
|
|
|
|
4. Do not replace strategic docs wholesale unless asked.
|
|
Prefer additive updates. Keep `doc/SPEC.md` and `doc/SPEC-implementation.md` aligned.
|
|
|
|
5. Keep repo plan docs dated and centralized.
|
|
When you are creating a plan file in the repository itself, new plan documents belong in `doc/plans/` and should use `YYYY-MM-DD-slug.md` filenames. This does not replace Paperclip issue planning: if a Paperclip issue asks for a plan, update the issue `plan` document per the `paperclip` skill instead of creating a repo markdown file.
|
|
|
|
6. Attach inspectable generated artifacts.
|
|
When your task produces a user-inspectable deliverable file, follow the Paperclip skill's "Generated Artifacts and Work Products" workflow before final disposition. In this repo, prefer the self-contained skill helper at `skills/paperclip/scripts/paperclip-upload-artifact.sh` so the file is available through the Paperclip API, create/update an artifact work product when the file is the deliverable, link the uploaded artifact in the final issue comment, and then set status. Do not rely on local filesystem paths as the only access path. If an important file intentionally remains workspace-only, create/update a work product with `metadata.resourceRef.kind: "workspace_file"` and a workspace-relative path, then name that work product and path in the final comment. Treat browse/search as a fallback for recovering workspace files, not the preferred deliverable path. See `doc/AGENT-ARTIFACTS.md` for details and `.mp4`/`.webm` examples.
|
|
|
|
## 6. Database Change Workflow
|
|
|
|
When changing data model:
|
|
|
|
1. Edit `packages/db/src/schema/*.ts`
|
|
2. Ensure new tables are exported from `packages/db/src/schema/index.ts`
|
|
3. Generate migration:
|
|
|
|
```sh
|
|
pnpm db:generate
|
|
```
|
|
|
|
4. Validate compile:
|
|
|
|
```sh
|
|
pnpm -r typecheck
|
|
```
|
|
|
|
Notes:
|
|
- `packages/db/drizzle.config.ts` reads compiled schema from `dist/schema/*.js`
|
|
- `pnpm db:generate` compiles `packages/db` first
|
|
|
|
## 7. Verification Before Hand-off
|
|
|
|
Default local/agent test path:
|
|
|
|
```sh
|
|
pnpm test
|
|
```
|
|
|
|
This is the cheap default and only runs the Vitest suite. Browser suites stay opt-in:
|
|
|
|
```sh
|
|
pnpm test:e2e
|
|
pnpm test:release-smoke
|
|
```
|
|
|
|
Run the browser suites only when your change touches them or when you are explicitly verifying CI/release flows.
|
|
|
|
For normal issue work, run the smallest relevant verification first. Do not default to repo-wide typecheck/build/test on every heartbeat when a narrower check is enough to prove the change.
|
|
|
|
Run this full check before claiming repo work done in a PR-ready hand-off, or when the change scope is broad enough that targeted checks are not sufficient:
|
|
|
|
```sh
|
|
pnpm -r typecheck
|
|
pnpm test:run
|
|
pnpm build
|
|
```
|
|
|
|
If anything cannot be run, explicitly report what was not run and why.
|
|
|
|
## 8. API and Auth Expectations
|
|
|
|
- Base path: `/api`
|
|
- Board access is treated as full-control operator context
|
|
- Agent access uses bearer API keys (`agent_api_keys`), hashed at rest
|
|
- Agent keys must not access other companies
|
|
|
|
When adding endpoints:
|
|
|
|
- apply company access checks
|
|
- enforce actor permissions (board vs agent)
|
|
- write activity log entries for mutations
|
|
- return consistent HTTP errors (`400/401/403/404/409/422/500`)
|
|
|
|
## 9. UI Expectations
|
|
|
|
- Keep routes and nav aligned with available API surface
|
|
- Use company selection context for company-scoped pages
|
|
- Surface failures clearly; do not silently ignore API errors
|
|
|
|
## 10. Pull Request Requirements
|
|
|
|
When creating a pull request (via `gh pr create` or any other method), you **must** read and fill in every section of [`.github/PULL_REQUEST_TEMPLATE.md`](.github/PULL_REQUEST_TEMPLATE.md). Do not craft ad-hoc PR bodies — use the template as the structure for your PR description. Required sections:
|
|
|
|
- **Thinking Path** — trace reasoning from project context to this change (see `CONTRIBUTING.md` for examples)
|
|
- **Linked Issues or Issue Description** — see below; this is the most common reason `commitperclip` fails a PR
|
|
- **What Changed** — bullet list of concrete changes
|
|
- **Verification** — how a reviewer can confirm it works
|
|
- **Risks** — what could go wrong
|
|
- **Model Used** — the AI model that produced or assisted with the change (provider, exact model ID, context window, capabilities). Write "None — human-authored" if no AI was used.
|
|
- **Checklist** — all items checked
|
|
|
|
### Linked issue (avoid the most common `commitperclip` failure)
|
|
|
|
`commitperclip` runs on every PR and **fails it** unless the body satisfies one of the two paths below. Do this when you write the PR body, not after the bot complains:
|
|
|
|
1. **A public GitHub issue exists** — tag it in the body with `Fixes #123`, `Closes #123`, `Resolves #123`, or `Refs #123` (a bare `#123` also counts). Link **all** related/duplicate issues and prior PRs, not just one.
|
|
2. **No public issue exists** — describe the problem inline so a reviewer gets the same fields a filed issue would give them. Include **at least 3** headings/labels from the matching issue template:
|
|
- **Bug:** `What happened`, `Expected behavior`, `Steps to reproduce`, `Paperclip version or commit`, `Deployment mode`
|
|
- **Feature:** `Problem or motivation`, `Proposed solution`, `Alternatives considered`, `Roadmap alignment`
|
|
- **Adapter:** `Agent or provider`, `Why this adapter is useful`, `How the agent is invoked`
|
|
|
|
Write each as its own `## Heading`, `**Bold label**`, or `Label:` line — that is what the check scans for.
|
|
|
|
The check is **skipped** only for PRs whose title uses a `docs:`, `chore:`, `build:`, `ci:`, `style:`, `test:`, or `revert:` conventional-commit prefix. Everything else (`feat:`, `fix:`, `refactor:`, `perf:`, or no prefix) requires path 1 or path 2.
|
|
|
|
> **Only reference public GitHub issues.** Never put internal/instance-local Paperclip references in the PR title, body, commits, or branch name — no `PAPA-123` / `PAP-224` ticket ids, no `/PAP/issues/...` or `agent://...` links, no `localhost`/tailnet URLs. The working branch is usually named after an internal ticket (e.g. `PAPA-945-...`); rename it to describe the change (e.g. `docs/...`, `fix/...`) before pushing. If an internal issue had useful context, restate it in plain English. See `CONTRIBUTING.md` → "No Internal Issue References".
|
|
|
|
## 11. Definition of Done
|
|
|
|
A change is done when all are true:
|
|
|
|
1. Behavior matches `doc/SPEC-implementation.md`
|
|
2. Typecheck, tests, and build pass
|
|
3. Contracts are synced across db/shared/server/ui
|
|
4. Docs updated when behavior or commands change
|
|
5. PR description follows the [PR template](.github/PULL_REQUEST_TEMPLATE.md) with all sections filled in (including Model Used)
|
|
|
|
## 11. Fork-Specific: HenkDz/paperclip
|
|
|
|
This is a fork of `paperclipai/paperclip` with QoL patches and an **external-only** Hermes adapter story on branch `feat/externalize-hermes-adapter` ([tree](https://github.com/HenkDz/paperclip/tree/feat/externalize-hermes-adapter)).
|
|
|
|
### Branch Strategy
|
|
|
|
- `feat/externalize-hermes-adapter` → core has **no** `hermes-paperclip-adapter` dependency and **no** built-in `hermes_local` registration. Install Hermes via the Adapter Plugin manager (`@henkey/hermes-paperclip-adapter` or a `file:` path).
|
|
- Older fork branches may still document built-in Hermes; treat this file as authoritative for the externalize branch.
|
|
|
|
### Hermes (plugin only)
|
|
|
|
- Register through **Board → Adapter manager** (same as Droid). Type remains `hermes_local` once the package is loaded.
|
|
- UI uses generic **config-schema** + **ui-parser.js** from the package — no Hermes imports in `server/` or `ui/` source.
|
|
- Optional: `file:` entry in `~/.paperclip/adapter-plugins.json` for local dev of the adapter repo.
|
|
|
|
### Local Dev
|
|
|
|
- Fork runs on port 3101+ (auto-detects if 3100 is taken by upstream instance)
|
|
- `npx vite build` hangs on NTFS — use `node node_modules/vite/bin/vite.js build` instead
|
|
- Server startup from NTFS takes 30-60s — don't assume failure immediately
|
|
- Kill ALL paperclip processes before starting: `pkill -f "paperclip"; pkill -f "tsx.*index.ts"`
|
|
- Vite cache survives `rm -rf dist` — delete both: `rm -rf ui/dist ui/node_modules/.vite`
|
|
|
|
### Fork QoL Patches (not in upstream)
|
|
|
|
These are local modifications in the fork's UI. If re-copying source, these must be re-applied:
|
|
|
|
1. **stderr_group** — amber accordion for MCP init noise in `RunTranscriptView.tsx`
|
|
2. **tool_group** — accordion for consecutive non-terminal tools (write, read, search, browser)
|
|
3. **Dashboard excerpt** — `LatestRunCard` strips markdown, shows first 3 lines/280 chars
|
|
|
|
### Plugin System
|
|
|
|
PR #2218 (`feat/external-adapter-phase1`) adds external adapter support. See root `AGENTS.md` for full details.
|
|
|
|
- Adapters can be loaded as external plugins via `~/.paperclip/adapter-plugins.json`
|
|
- The plugin-loader should have ZERO hardcoded adapter imports — pure dynamic loading
|
|
- `createServerAdapter()` must include ALL optional fields (especially `detectModel`)
|
|
- Built-in UI adapters can shadow external plugin parsers — remove built-in when fully externalizing
|
|
- Reference external adapters: Hermes (`@henkey/hermes-paperclip-adapter` or `file:`) and Droid (npm)
|