paperclip-ai-orchestration by aradotso/trending-skills
npx skills add https://github.com/aradotso/trending-skills --skill paperclip-ai-orchestration由 ara.so 提供的技能 — Daily 2026 Skills 系列。
Paperclip 是一个开源的 Node.js + React 平台,用于运行一个由 AI 智能体构成的公司。它提供组织结构图、目标对齐、基于工单的任务管理、预算强制执行、心跳调度、治理和完整的审计日志——让你专注于管理业务成果,而不是单个智能体会话。
npx paperclipai onboard --yes
此命令会克隆代码库、安装依赖项、初始化嵌入式 PostgreSQL 数据库并启动服务器。
git clone https://github.com/paperclipai/paperclip.git
cd paperclip
pnpm install
pnpm dev
要求:
API 服务器启动于 http://localhost:3100。嵌入式 PostgreSQL 数据库会自动创建——本地开发无需手动设置数据库。
通过环境变量将 Paperclip 指向外部 Postgres 实例和对象存储:
# .env
DATABASE_URL=postgresql://user:password@host:5432/paperclip
STORAGE_BUCKET=your-s3-bucket
STORAGE_REGION=us-east-1
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
PORT=3100
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
pnpm dev # 以开发模式启动 API + UI
pnpm build # 构建生产版本
pnpm start # 启动生产服务器
pnpm db:migrate # 运行待处理的数据库迁移
pnpm db:seed # 填充演示数据
pnpm test # 运行测试套件
npx paperclipai onboard --yes # 完整的自动化入门设置
| 概念 | 描述 |
|---|---|
| 公司 | 顶级命名空间。所有智能体、目标、任务和预算都限定在一个公司内。 |
| 智能体 | 一个 AI 工作者(OpenClaw、Claude Code、Codex、Cursor、HTTP 机器人、Bash 脚本)。 |
| 目标 | 分层级的业务目标。任务继承目标层级,因此智能体知道“为什么”要做。 |
| 任务 / 工单 | 分配给智能体的一个工作单元。对话和工具调用都关联到它。 |
| 心跳 | 一种 cron 风格的调度,用于唤醒智能体检查工作或执行周期性任务。 |
| 组织结构图 | 分层级的汇报结构。智能体有经理、直接下属、角色和头衔。 |
| 预算 | 每个智能体每月的令牌/成本上限。原子级强制执行——预算耗尽时智能体停止工作。 |
| 治理 | 用于招聘、策略变更和配置回滚的审批门。你就是董事会。 |
Paperclip API 服务地址为 http://localhost:3100/api/v1。
// 所有请求都需要 Bearer 令牌
const headers = {
'Authorization': `Bearer ${process.env.PAPERCLIP_API_KEY}`,
'Content-Type': 'application/json',
};
const response = await fetch('http://localhost:3100/api/v1/companies', {
method: 'POST',
headers,
body: JSON.stringify({
name: 'NoteGenius Inc.',
mission: '打造排名第一的 AI 笔记应用,实现 100 万美元月度经常性收入。',
slug: 'notegenius',
}),
});
const { company } = await response.json();
console.log(company.id); // "cmp_abc123"
const agent = await fetch(`http://localhost:3100/api/v1/companies/${companyId}/agents`, {
method: 'POST',
headers,
body: JSON.stringify({
name: 'Alice',
role: 'CTO',
runtime: 'claude-code', // 'openclaw' | 'claude-code' | 'codex' | 'cursor' | 'bash' | 'http'
endpoint: process.env.ALICE_AGENT_ENDPOINT,
budget: {
monthly_usd: 200,
},
heartbeat: {
cron: '0 * * * *', // 每小时
enabled: true,
},
reports_to: ceoAgentId, // 组织结构图中的上级
}),
}).then(r => r.json());
const goal = await fetch(`http://localhost:3100/api/v1/companies/${companyId}/goals`, {
method: 'POST',
headers,
body: JSON.stringify({
title: '在 Product Hunt 上发布 v1 版本',
description: '发布 MVP 并在发布日获得 500 个点赞。',
parent_goal_id: null, // null = 顶级目标
owner_agent_id: ctoAgentId,
due_date: '2026-06-01',
}),
}).then(r => r.json());
const task = await fetch(`http://localhost:3100/api/v1/companies/${companyId}/tasks`, {
method: 'POST',
headers,
body: JSON.stringify({
title: '为笔记实现离线同步',
description: '使用 CRDT 合并离线编辑的笔记。参见 ADR-004。',
assigned_to: engineerAgentId,
goal_id: goal.id, // 将任务链接到目标层级
priority: 'high',
}),
}).then(r => r.json());
console.log(task.id); // "tsk_xyz789"
const { tasks } = await fetch(
`http://localhost:3100/api/v1/agents/${agentId}/tasks?status=open`,
{ headers }
).then(r => r.json());
await fetch(`http://localhost:3100/api/v1/tasks/${taskId}/messages`, {
method: 'POST',
headers,
body: JSON.stringify({
role: 'agent',
content: '已实现 CRDT 合并逻辑。测试通过。等待审核。',
tool_calls: [
{
tool: 'bash',
input: 'pnpm test --filter=sync',
output: '42 个测试在 3.1 秒内通过',
},
],
}),
});
智能体自行报告令牌使用情况;Paperclip 原子性地强制执行预算:
await fetch(`http://localhost:3100/api/v1/agents/${agentId}/cost`, {
method: 'POST',
headers,
body: JSON.stringify({
tokens_in: 12400,
tokens_out: 3800,
model: 'claude-opus-4-5',
task_id: taskId,
}),
});
智能体在每次计划唤醒时调用此端点:
const { instructions, tasks } = await fetch(
`http://localhost:3100/api/v1/agents/${agentId}/heartbeat`,
{ method: 'POST', headers }
).then(r => r.json());
// instructions — 组织当前指示关注的重点
// tasks — 分配给此智能体的开放任务
包装 REST API 以实现更简洁的智能体集成:
// lib/paperclip-client.ts
export class PaperclipClient {
private base: string;
private headers: Record<string, string>;
constructor(
base = process.env.PAPERCLIP_BASE_URL ?? 'http://localhost:3100',
apiKey = process.env.PAPERCLIP_API_KEY ?? '',
) {
this.base = `${base}/api/v1`;
this.headers = {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
};
}
private async req<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${this.base}${path}`, {
...init,
headers: { ...this.headers, ...init?.headers },
});
if (!res.ok) {
const body = await res.text();
throw new Error(`Paperclip API ${res.status}: ${body}`);
}
return res.json() as Promise<T>;
}
heartbeat(agentId: string) {
return this.req<{ instructions: string; tasks: Task[] }>(
`/agents/${agentId}/heartbeat`,
{ method: 'POST' },
);
}
completeTask(taskId: string, summary: string) {
return this.req(`/tasks/${taskId}`, {
method: 'PATCH',
body: JSON.stringify({ status: 'done', completion_summary: summary }),
});
}
reportCost(agentId: string, payload: CostPayload) {
return this.req(`/agents/${agentId}/cost`, {
method: 'POST',
body: JSON.stringify(payload),
});
}
}
一个与 Paperclip 集成的最小化智能体循环:
// agent.ts
import { PaperclipClient } from './lib/paperclip-client';
const client = new PaperclipClient();
const AGENT_ID = process.env.PAPERCLIP_AGENT_ID!;
async function runHeartbeat() {
console.log('[agent] heartbeat ping');
const { instructions, tasks } = await client.heartbeat(AGENT_ID);
for (const task of tasks) {
console.log(`[agent] working on task: ${task.title}`);
try {
// --- 你的智能体逻辑写在这里 ---
const result = await doWork(task, instructions);
await client.completeTask(task.id, result.summary);
await client.reportCost(AGENT_ID, {
tokens_in: result.tokensIn,
tokens_out: result.tokensOut,
model: result.model,
task_id: task.id,
});
console.log(`[agent] task ${task.id} done`);
} catch (err) {
console.error(`[agent] task ${task.id} failed`, err);
// Paperclip 将根据治理规则重新分配任务或升级处理
}
}
}
// 心跳通常由 Paperclip 的 cron 驱动,但你也可以自行轮询:
setInterval(runHeartbeat, 60_000);
runHeartbeat();
任何可通过 HTTP 访问的进程都可以成为智能体。Paperclip 会向你的端点发送 POST 请求:
// Paperclip 调用你的智能体的 POST /work 端点,数据结构如下:
interface PaperclipWorkPayload {
agent_id: string;
task: {
id: string;
title: string;
description: string;
goal_ancestry: string[]; // 完整链条:公司使命 → 目标 → 子目标
};
instructions: string; // 当前组织层面的指示
context: Record<string, unknown>;
}
响应格式:
interface PaperclipWorkResponse {
status: 'done' | 'blocked' | 'delegated';
summary: string;
tokens_in?: number;
tokens_out?: number;
model?: string;
delegate_to?: string; // 如果 status === 'delegated',则为 agent_id
}
// 在一个部署中创建隔离的公司
const companies = await Promise.all([
createCompany({ name: 'NoteGenius', mission: 'Best note app' }),
createCompany({ name: 'ShipFast', mission: 'Fastest deploy tool' }),
]);
// 每个公司都有自己的智能体、目标、任务、预算和审计日志
// 公司之间数据不泄露
// 获取待处理的审批请求(你就是董事会)
const { approvals } = await fetch(
`http://localhost:3100/api/v1/companies/${companyId}/approvals?status=pending`,
{ headers }
).then(r => r.json());
// 批准一项招聘
await fetch(`http://localhost:3100/api/v1/approvals/${approvals[0].id}`, {
method: 'PATCH',
headers,
body: JSON.stringify({ decision: 'approved', note: 'Looks good.' }),
});
// 回滚错误的配置更改
await fetch(`http://localhost:3100/api/v1/agents/${agentId}/config/rollback`, {
method: 'POST',
headers,
body: JSON.stringify({ revision: 3 }),
});
# 必需
PAPERCLIP_API_KEY= # 用于 Paperclip 服务器的 API 密钥
# 数据库(开发环境默认为嵌入式 Postgres)
DATABASE_URL= # postgresql://user:pass@host:5432/db
# 存储(开发环境默认为本地文件系统)
STORAGE_DRIVER=local # 'local' | 's3'
STORAGE_BUCKET= # S3 存储桶名称
STORAGE_REGION= # AWS 区域
AWS_ACCESS_KEY_ID= # 来自你的环境
AWS_SECRET_ACCESS_KEY= # 来自你的环境
# 服务器
PORT=3100
BASE_URL=http://localhost:3100
# 智能体端(在智能体进程内部使用)
PAPERCLIP_BASE_URL=http://localhost:3100
PAPERCLIP_AGENT_ID= # 来自 Paperclip 的智能体 UUID
// 在你的经理智能体的心跳处理程序中:
const { tasks } = await client.heartbeat(MANAGER_AGENT_ID);
for (const task of tasks) {
if (task.complexity === 'high') {
// 沿组织结构图向下委派
await fetch(`http://localhost:3100/api/v1/tasks/${task.id}/delegate`, {
method: 'POST',
headers,
body: JSON.stringify({ to_agent_id: engineerAgentId }),
});
}
}
await fetch(`http://localhost:3100/api/v1/tasks/${taskId}/messages`, {
method: 'POST',
headers,
body: JSON.stringify({
role: 'human',
content: `@${designerAgentId} 你能评审一下这个功能的 UI 吗?`,
}),
});
// Paperclip 将此次提及作为触发器,在设计师智能体的下一次心跳时传递给它
const blob = await fetch(
`http://localhost:3100/api/v1/companies/${companyId}/export`,
{ headers }
).then(r => r.blob());
// 保存一个 .paperclip 包,其中机密信息已被清理
fs.writeFileSync('my-saas-company.paperclip', Buffer.from(await blob.arrayBuffer()));
const form = new FormData();
form.append('file', fs.createReadStream('my-saas-company.paperclip'));
await fetch('http://localhost:3100/api/v1/companies/import', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PAPERCLIP_API_KEY}` },
body: form,
});
| 问题 | 解决方法 |
|---|---|
ECONNREFUSED localhost:3100 | 服务器未运行。先运行 pnpm dev。 |
401 Unauthorized | 检查 PAPERCLIP_API_KEY 是否已设置且与服务器配置匹配。 |
| 智能体从不唤醒 | 确认 heartbeat.enabled: true 且 cron 表达式有效。检查服务器日志中的调度器错误。 |
| 预算立即耗尽 | monthly_usd 预算过低或 tokens_in/tokens_out 被过度报告。检查 POST /agents/:id/cost 负载。 |
任务卡在 open 状态 | 智能体可能离线或心跳配置错误。检查 /api/v1/agents/:id/status。 |
| 数据库迁移错误 | 拉取新提交后运行 pnpm db:migrate。 |
| 嵌入式 Postgres 无法启动 | 端口 5433 可能已被占用。在 .env 中设置 EMBEDDED_PG_PORT=5434。 |
| 组织结构图无法解析 | 在创建下属之前,reports_to 智能体 ID 必须存在。自上而下创建。 |
每周安装次数
349
代码库
GitHub 星标数
10
首次出现
8 天前
安全审计
已安装于
gemini-cli345
github-copilot345
codex345
amp345
cline345
kimi-cli345
Skill by ara.so — Daily 2026 Skills collection.
Paperclip is an open-source Node.js + React platform that runs a company made of AI agents. It provides org charts, goal alignment, ticket-based task management, budget enforcement, heartbeat scheduling, governance, and a full audit log — so you manage business outcomes instead of individual agent sessions.
npx paperclipai onboard --yes
This clones the repo, installs dependencies, seeds an embedded PostgreSQL database, and starts the server.
git clone https://github.com/paperclipai/paperclip.git
cd paperclip
pnpm install
pnpm dev
Requirements:
The API server starts at http://localhost:3100. An embedded PostgreSQL database is created automatically — no manual DB setup needed for local development.
Point Paperclip at an external Postgres instance and object storage via environment variables:
# .env
DATABASE_URL=postgresql://user:password@host:5432/paperclip
STORAGE_BUCKET=your-s3-bucket
STORAGE_REGION=us-east-1
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
PORT=3100
pnpm dev # Start API + UI in development mode
pnpm build # Build for production
pnpm start # Start production server
pnpm db:migrate # Run pending database migrations
pnpm db:seed # Seed demo data
pnpm test # Run test suite
npx paperclipai onboard --yes # Full automated onboarding
| Concept | Description |
|---|---|
| Company | Top-level namespace. All agents, goals, tasks, and budgets are scoped to a company. |
| Agent | An AI worker (OpenClaw, Claude Code, Codex, Cursor, HTTP bot, Bash script). |
| Goal | Hierarchical business objective. Tasks inherit goal ancestry so agents know the "why". |
| Task / Ticket | A unit of work assigned to an agent. Conversations and tool calls are threaded to it. |
| Heartbeat | A cron-style schedule that wakes an agent to check for work or perform recurring tasks. |
| Org Chart | Hierarchical reporting structure. Agents have managers, direct reports, roles, and titles. |
| Budget | Monthly token/cost cap per agent. Atomic enforcement — agent stops when budget exhausted. |
| Governance | Approval gates for hires, strategy changes, and config rollbacks. You are the board. |
The Paperclip API is served at http://localhost:3100/api/v1.
// All requests require a bearer token
const headers = {
'Authorization': `Bearer ${process.env.PAPERCLIP_API_KEY}`,
'Content-Type': 'application/json',
};
const response = await fetch('http://localhost:3100/api/v1/companies', {
method: 'POST',
headers,
body: JSON.stringify({
name: 'NoteGenius Inc.',
mission: 'Build the #1 AI note-taking app to $1M MRR.',
slug: 'notegenius',
}),
});
const { company } = await response.json();
console.log(company.id); // "cmp_abc123"
const agent = await fetch(`http://localhost:3100/api/v1/companies/${companyId}/agents`, {
method: 'POST',
headers,
body: JSON.stringify({
name: 'Alice',
role: 'CTO',
runtime: 'claude-code', // 'openclaw' | 'claude-code' | 'codex' | 'cursor' | 'bash' | 'http'
endpoint: process.env.ALICE_AGENT_ENDPOINT,
budget: {
monthly_usd: 200,
},
heartbeat: {
cron: '0 * * * *', // every hour
enabled: true,
},
reports_to: ceoAgentId, // parent in org chart
}),
}).then(r => r.json());
const goal = await fetch(`http://localhost:3100/api/v1/companies/${companyId}/goals`, {
method: 'POST',
headers,
body: JSON.stringify({
title: 'Launch v1 to Product Hunt',
description: 'Ship the MVP and generate 500 upvotes on launch day.',
parent_goal_id: null, // null = top-level goal
owner_agent_id: ctoAgentId,
due_date: '2026-06-01',
}),
}).then(r => r.json());
const task = await fetch(`http://localhost:3100/api/v1/companies/${companyId}/tasks`, {
method: 'POST',
headers,
body: JSON.stringify({
title: 'Implement offline sync for notes',
description: 'Use CRDTs to merge note edits made offline. See ADR-004.',
assigned_to: engineerAgentId,
goal_id: goal.id, // links task to goal ancestry
priority: 'high',
}),
}).then(r => r.json());
console.log(task.id); // "tsk_xyz789"
const { tasks } = await fetch(
`http://localhost:3100/api/v1/agents/${agentId}/tasks?status=open`,
{ headers }
).then(r => r.json());
await fetch(`http://localhost:3100/api/v1/tasks/${taskId}/messages`, {
method: 'POST',
headers,
body: JSON.stringify({
role: 'agent',
content: 'Implemented CRDT merge logic. Tests passing. Ready for review.',
tool_calls: [
{
tool: 'bash',
input: 'pnpm test --filter=sync',
output: '42 tests passed in 3.1s',
},
],
}),
});
Agents self-report token usage; Paperclip enforces budget atomically:
await fetch(`http://localhost:3100/api/v1/agents/${agentId}/cost`, {
method: 'POST',
headers,
body: JSON.stringify({
tokens_in: 12400,
tokens_out: 3800,
model: 'claude-opus-4-5',
task_id: taskId,
}),
});
Agents call this endpoint on each scheduled wake-up:
const { instructions, tasks } = await fetch(
`http://localhost:3100/api/v1/agents/${agentId}/heartbeat`,
{ method: 'POST', headers }
).then(r => r.json());
// instructions — what the org says to focus on now
// tasks — open tasks assigned to this agent
Wrap the REST API for cleaner agent integration:
// lib/paperclip-client.ts
export class PaperclipClient {
private base: string;
private headers: Record<string, string>;
constructor(
base = process.env.PAPERCLIP_BASE_URL ?? 'http://localhost:3100',
apiKey = process.env.PAPERCLIP_API_KEY ?? '',
) {
this.base = `${base}/api/v1`;
this.headers = {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
};
}
private async req<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${this.base}${path}`, {
...init,
headers: { ...this.headers, ...init?.headers },
});
if (!res.ok) {
const body = await res.text();
throw new Error(`Paperclip API ${res.status}: ${body}`);
}
return res.json() as Promise<T>;
}
heartbeat(agentId: string) {
return this.req<{ instructions: string; tasks: Task[] }>(
`/agents/${agentId}/heartbeat`,
{ method: 'POST' },
);
}
completeTask(taskId: string, summary: string) {
return this.req(`/tasks/${taskId}`, {
method: 'PATCH',
body: JSON.stringify({ status: 'done', completion_summary: summary }),
});
}
reportCost(agentId: string, payload: CostPayload) {
return this.req(`/agents/${agentId}/cost`, {
method: 'POST',
body: JSON.stringify(payload),
});
}
}
A minimal agent loop that integrates with Paperclip:
// agent.ts
import { PaperclipClient } from './lib/paperclip-client';
const client = new PaperclipClient();
const AGENT_ID = process.env.PAPERCLIP_AGENT_ID!;
async function runHeartbeat() {
console.log('[agent] heartbeat ping');
const { instructions, tasks } = await client.heartbeat(AGENT_ID);
for (const task of tasks) {
console.log(`[agent] working on task: ${task.title}`);
try {
// --- your agent logic here ---
const result = await doWork(task, instructions);
await client.completeTask(task.id, result.summary);
await client.reportCost(AGENT_ID, {
tokens_in: result.tokensIn,
tokens_out: result.tokensOut,
model: result.model,
task_id: task.id,
});
console.log(`[agent] task ${task.id} done`);
} catch (err) {
console.error(`[agent] task ${task.id} failed`, err);
// Paperclip will reassign or escalate based on governance rules
}
}
}
// Heartbeat is usually driven by Paperclip's cron, but you can also self-poll:
setInterval(runHeartbeat, 60_000);
runHeartbeat();
Any process reachable over HTTP can be an agent. Paperclip sends a POST to your endpoint:
// Paperclip calls POST /work on your agent with this shape:
interface PaperclipWorkPayload {
agent_id: string;
task: {
id: string;
title: string;
description: string;
goal_ancestry: string[]; // full chain: company mission → goal → sub-goal
};
instructions: string; // current org-level directives
context: Record<string, unknown>;
}
Respond with:
interface PaperclipWorkResponse {
status: 'done' | 'blocked' | 'delegated';
summary: string;
tokens_in?: number;
tokens_out?: number;
model?: string;
delegate_to?: string; // agent_id if status === 'delegated'
}
// Create isolated companies in one deployment
const companies = await Promise.all([
createCompany({ name: 'NoteGenius', mission: 'Best note app' }),
createCompany({ name: 'ShipFast', mission: 'Fastest deploy tool' }),
]);
// Each company has its own agents, goals, tasks, budgets, and audit log
// No data leaks between companies
// Fetch pending approval requests (you are the board)
const { approvals } = await fetch(
`http://localhost:3100/api/v1/companies/${companyId}/approvals?status=pending`,
{ headers }
).then(r => r.json());
// Approve a hire
await fetch(`http://localhost:3100/api/v1/approvals/${approvals[0].id}`, {
method: 'PATCH',
headers,
body: JSON.stringify({ decision: 'approved', note: 'Looks good.' }),
});
// Roll back a bad config change
await fetch(`http://localhost:3100/api/v1/agents/${agentId}/config/rollback`, {
method: 'POST',
headers,
body: JSON.stringify({ revision: 3 }),
});
# Required
PAPERCLIP_API_KEY= # Your API key for the Paperclip server
# Database (defaults to embedded Postgres in dev)
DATABASE_URL= # postgresql://user:pass@host:5432/db
# Storage (defaults to local filesystem in dev)
STORAGE_DRIVER=local # 'local' | 's3'
STORAGE_BUCKET= # S3 bucket name
STORAGE_REGION= # AWS region
AWS_ACCESS_KEY_ID= # From your environment
AWS_SECRET_ACCESS_KEY= # From your environment
# Server
PORT=3100
BASE_URL=http://localhost:3100
# Agent-side (used inside agent processes)
PAPERCLIP_BASE_URL=http://localhost:3100
PAPERCLIP_AGENT_ID= # The agent's UUID from Paperclip
// In your manager agent's heartbeat handler:
const { tasks } = await client.heartbeat(MANAGER_AGENT_ID);
for (const task of tasks) {
if (task.complexity === 'high') {
// Delegate down the org chart
await fetch(`http://localhost:3100/api/v1/tasks/${task.id}/delegate`, {
method: 'POST',
headers,
body: JSON.stringify({ to_agent_id: engineerAgentId }),
});
}
}
await fetch(`http://localhost:3100/api/v1/tasks/${taskId}/messages`, {
method: 'POST',
headers,
body: JSON.stringify({
role: 'human',
content: `@${designerAgentId} Can you review the UI for this feature?`,
}),
});
// Paperclip delivers the mention as a trigger to the designer agent's next heartbeat
const blob = await fetch(
`http://localhost:3100/api/v1/companies/${companyId}/export`,
{ headers }
).then(r => r.blob());
// Saves a .paperclip bundle with secrets scrubbed
fs.writeFileSync('my-saas-company.paperclip', Buffer.from(await blob.arrayBuffer()));
const form = new FormData();
form.append('file', fs.createReadStream('my-saas-company.paperclip'));
await fetch('http://localhost:3100/api/v1/companies/import', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PAPERCLIP_API_KEY}` },
body: form,
});
| Problem | Fix |
|---|---|
ECONNREFUSED localhost:3100 | Server not running. Run pnpm dev first. |
401 Unauthorized | Check PAPERCLIP_API_KEY is set and matches server config. |
| Agent never wakes up | Verify heartbeat.enabled: true and cron expression is valid. Check server logs for scheduler errors. |
| Budget exhausted immediately | monthly_usd budget too low or tokens_in/tokens_out are being over-reported. Check POST /agents/:id/cost payloads. |
Weekly Installs
349
Repository
GitHub Stars
10
First Seen
8 days ago
Security Audits
Gen Agent Trust HubWarnSocketPassSnykPass
Installed on
gemini-cli345
github-copilot345
codex345
amp345
cline345
kimi-cli345
AI Elements:基于shadcn/ui的AI原生应用组件库,快速构建对话界面
54,900 周安装
Google Ads Manager 技能:广告系列管理、关键词研究、出价优化与效果分析
311 周安装
Telegram机器人开发教程:构建AI助手、通知系统与群组自动化工具
311 周安装
AI图像生成提示词优化指南:DALL-E、Midjourney、Stable Diffusion提示工程技巧
311 周安装
AI协作头脑风暴工具 - 将想法转化为完整设计规范,支持代码模板与项目管理
311 周安装
解决 Docker 沙盒 npm 安装崩溃:sandbox-npm-install 技能详解与使用指南
311 周安装
网页设计方法论:生产级HTML/CSS构建模式与BEM命名规范
311 周安装
Task stuck in open | Agent may be offline or heartbeat misconfigured. Check /api/v1/agents/:id/status. |
| Database migration errors | Run pnpm db:migrate after pulling new commits. |
| Embedded Postgres won't start | Port 5433 may be in use. Set EMBEDDED_PG_PORT=5434 in .env. |
| Org chart not resolving | reports_to agent ID must exist before creating the subordinate. Create top-down. |