Token导航 LogoToken导航TokenDH.com
前端设计只读github未标认证来源可访问许可证需确认审计通过

tl-pg-bossTL PG 老板

Agent Skill

tl-pg-boss 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

267

周安装

11

GitHub Stars

公开资料未说明

下载量

87
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:tl-pg-boss(TL PG 老板)
来源仓库:https://github.com/toddlevy/tl-agent-skills
仓库路径:skills/tl-pg-boss
安装命令:
npx skills add https://github.com/toddlevy/tl-agent-skills --skill tl-pg-boss
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/toddlevy/tl-agent-skills --skill tl-pg-boss

简介

tl-pg-boss 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态或协作事项进行整理。

  • 适用于代码协作和仓库管理场景,可结合来源仓库和原始 README 核验用法。
  • 通过 npx skills add 命令从 GitHub 安装,支持主流 AI 宿主环境。
  • 安装前建议确认权限范围、维护状态,以及是否会触发联网或文件读写。
  • tl-pg-boss 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

tl-pg-boss

PostgreSQL-backed job queue for Node.js with exactly-once delivery, cron scheduling, and transactional safety.

When to Use

  • "Add background jobs to my app"
  • "I need a job queue but already use Postgres"
  • "Set up cron jobs / scheduled tasks"
  • "Process async work with retries"
  • User mentions: job queue, background processing, task scheduling, worker

When to Consider Alternatives

For managed background jobs with dashboard UI, consider Trigger.dev instead. pg-boss is best when:

  • You want self-hosted, PostgreSQL-native job queues
  • You already have Postgres and don't want external dependencies
  • You need transactional job enqueuing (same transaction as your data writes)
  • Cost matters (pg-boss is free, managed services charge per job)

Trigger.dev is better when:

  • You need a polished dashboard out of the box
  • You want managed infrastructure with auto-scaling
  • Your team prefers a hosted SaaS experience
  • You need complex workflows with visual orchestration

Outcomes

  • Patch: pg-boss installed and configured with typed job handlers
  • Artifact: Job definitions with proper queue setup
  • Decision: Queue structure, job patterns, monitoring approach

Requirements

RequirementVersion
Node.js22.12+
PostgreSQL13+
PrivilegeCREATE on database

Installation

pnpm add pg-boss

Auto-creates pgboss schema on first start(). No manual migrations needed.


Core Concepts

SKIP LOCKED

PostgreSQL's SKIP LOCKED provides exactly-once delivery without distributed transactions.

Always Call start()

Critical: Every process must call start(), even producers.

const boss = new PgBoss(connectionString);
await boss.start(); // Required in EVERY process

Even with multiple processes calling start(), only one runs supervision.

One Queue Per Job Type

await boss.createQueue("send-email");
await boss.createQueue("process-image");

Basic Setup

import { PgBoss } from "pg-boss";

const boss = new PgBoss({
  connectionString: process.env.DATABASE_URL,
  schema: "pgboss",
});

boss.on("error", console.error);
await boss.start();
await boss.createQueue("my-queue");

Job Patterns

Send a Job

const jobId = await boss.send("my-queue", { userId: "123" });

Send with Options

await boss.send("my-queue", payload, {
  retryLimit: 3,
  retryDelay: 60,
  expireInMinutes: 30,
  priority: 1,
});
Full options: See references/send-options.md

Delayed Job

await boss.send("my-queue", payload, {
  startAfter: new Date(Date.now() + 60000),
});

Cron Scheduling

await boss.schedule("daily-report", "0 9 * * *", { type: "daily" });

Unschedule (Remove Cron)

await boss.unschedule("daily-report");
Schedule management: See references/schedule-management.md

Worker Patterns

Basic Worker

await boss.work("my-queue", async ([job]) => {
  console.log(`Processing ${job.id}`);
  // Auto-completes on return, throw to fail
});

Note: Callback receives an array even with batchSize: 1.

Batch Processing

await boss.work("bulk-import", { batchSize: 10 }, async (jobs) => {
  for (const job of jobs) {
    await processItem(job.data);
  }
});

Typed Jobs

interface EmailJob {
  to: string;
  subject: string;
}

await boss.send<EmailJob>("send-email", { to: "user@example.com", subject: "Hi" });

await boss.work<EmailJob>("send-email", async ([job]) => {
  await sendEmail(job.data.to, job.data.subject);
});
TypeScript patterns: See references/typescript-patterns.md

Queue Configuration

Dead Letter Queue

await boss.createQueue("my-queue", { deadLetter: "my-queue-dlq" });
await boss.createQueue("my-queue-dlq");

Retention

await boss.createQueue("my-queue", { retentionMinutes: 60 * 24 });

Fastify Integration

import Fastify from "fastify";
import { PgBoss } from "pg-boss";

const fastify = Fastify();
const boss = new PgBoss(process.env.DATABASE_URL);

fastify.decorate("boss", boss);

fastify.addHook("onReady", async () => {
  boss.on("error", fastify.log.error.bind(fastify.log));
  await boss.start();
  await boss.createQueue("my-queue");
  await boss.work("my-queue", handler);
});

fastify.addHook("onClose", async () => {
  await boss.stop({ graceful: true });
});

Monitoring

Dashboard

pnpm add @pg-boss/dashboard
DATABASE_URL="postgres://..." npx pg-boss-dashboard

Quick SQL

-- Pending by queue
SELECT name, COUNT(*) FROM pgboss.job WHERE state = 'created' GROUP BY name;

-- Failed jobs
SELECT * FROM pgboss.job WHERE state = 'failed' ORDER BY completedon DESC LIMIT 20;
Full monitoring: See references/monitoring.md

Sharp Edges

GotchaSolution
Must call start() everywhereEven producers need it
Jobs array in workerUse ([job]) not (job)
No LISTEN/NOTIFYPolling only, set pollingIntervalSeconds
Schema needs CREATE privilegeOr use CLI: npx pg-boss migrate --dry-run
Once completed, can't failDon't mix work() with manual fail()
No pauseQueue() in v10Use unschedule() + direct SQL
Schedules re-register on restartCode calls schedule() on init; unschedule is temporary

Best Practices

  1. Set expiration to prevent zombies: expireInMinutes: 30
  2. Archive aggressively with retention policies
  3. Idempotent handlers using upserts
  4. Graceful shutdown: boss.stop({graceful: true})

Observability

Prometheus Metrics

Expose queue metrics for monitoring:

import { register, Gauge, Counter } from 'prom-client';

const queueSize = new Gauge({
  name: 'pgboss_queue_size',
  help: 'Number of jobs in queue',
  labelNames: ['queue', 'state'],
});

const jobsProcessed = new Counter({
  name: 'pgboss_jobs_processed_total',
  help: 'Total jobs processed',
  labelNames: ['queue', 'status'],
});

async function collectMetrics(boss: PgBoss) {
  const queues = await boss.getQueues();
  for (const queue of queues) {
    const stats = await boss.getQueueSize(queue.name);
    queueSize.set({ queue: queue.name, state: 'active' }, stats.active);
    queueSize.set({ queue: queue.name, state: 'created' }, stats.created);
  }
}

boss.on('job', (job) => jobsProcessed.inc({ queue: job.name, status: 'completed' }));
boss.on('fail', (job) => jobsProcessed.inc({ queue: job.name, status: 'failed' }));

Alerting Rules

groups:
  - name: pgboss
    rules:
      - alert: JobQueueBacklog
        expr: pgboss_queue_size{state="created"} > 1000
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Job queue {{ $labels.queue }} has backlog"

      - alert: JobFailureRate
        expr: rate(pgboss_jobs_processed_total{status="failed"}[5m]) > 0.1
        for: 5m
        labels:
          severity: critical

Testing Patterns

Unit Testing Job Handlers

describe('EmailJob', () => {
  it('sends email with correct parameters', async () => {
    const sendEmail = vi.fn();
    const handler = createEmailHandler({ sendEmail });

    await handler({ to: 'test@example.com', subject: 'Test' });

    expect(sendEmail).toHaveBeenCalledWith({
      to: 'test@example.com',
      subject: 'Test',
    });
  });
});

Integration Testing with Real Database

import { PgBoss } from 'pg-boss';

describe('Job Queue Integration', () => {
  let boss: PgBoss;

  beforeAll(async () => {
    boss = new PgBoss(process.env.TEST_DATABASE_URL);
    await boss.start();
    await boss.createQueue('test-queue');
  });

  afterAll(async () => {
    await boss.stop();
  });

  it('processes job end-to-end', async () => {
    const results: any[] = [];
    await boss.work('test-queue', async (job) => {
      results.push(job.data);
    });

    await boss.send('test-queue', { id: 1 });
    await new Promise((r) => setTimeout(r, 1000));

    expect(results).toEqual([{ id: 1 }]);
  });
});

Mocking pg-boss

const mockBoss = {
  start: vi.fn().mockResolvedValue(undefined),
  send: vi.fn().mockResolvedValue('job-id'),
  work: vi.fn().mockResolvedValue(undefined),
  createQueue: vi.fn().mockResolvedValue(undefined),
};

vi.mock('pg-boss', () => ({
  PgBoss: vi.fn(() => mockBoss),
}));

Kubernetes Deployment

Worker Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: job-worker
spec:
  replicas: 3
  selector:
    matchLabels:
      app: job-worker
  template:
    metadata:
      labels:
        app: job-worker
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: worker
          image: app:latest
          command: ["node", "dist/worker.js"]
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
          resources:
            requests:
              memory: "256Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 10
          lifecycle:
            preStop:
              exec:
                command: ["/bin/sh", "-c", "sleep 10"]

Graceful Shutdown Handler

process.on('SIGTERM', async () => {
  console.log('SIGTERM received, stopping gracefully...');
  await boss.stop({ graceful: true, timeout: 30000 });
  process.exit(0);
});

Verification

  1. boss.start() completes without error
  2. boss.createQueue() succeeds
  3. boss.send() returns a job ID
  4. Worker processes the job
  5. Job state changes to completed

References

Quilted Skills

First-Party Documentation

PostgreSQL Resources

Alternative Solutions

Skill References

  • references/send-options.md — Full send options
  • references/typescript-patterns.md — BaseJob, JobManager
  • references/monitoring.md — Dashboard + SQL queries
  • references/advanced-patterns.md — Singleton, throttling, pub/sub
  • references/schedule-management.md — Cron schedules, unschedule, pause patterns
  • references/wordpress-migration.md — WP-Cron & Action Scheduler mapping

Attribution

SourceAuthorContribution
pg-bossTim Gilbert (@timgit)Core library, official docs
TypeScript Deep DiveShayan (@ImSh4yy)BaseJob class, JobManager pattern
pg-boss-admin-dashboardLyubomir Petrov (@lpetrov)Alternative dashboard with JMESPath

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.58%
按下载量换算32

Claude

31.2%
按下载量换算27

Cursor

20.27%
按下载量换算18

Gemini CLI

9.87%
按下载量换算9

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills