PushPilot’s provider-agnostic task integration layer
npm install @pushpilot/task-providersPushPilot’s provider-agnostic task integration layer.
This package serves as a stateless, normalized adapter layer for creating and updating tasks in external task management platforms (Asana, Jira, Linear, etc.). It abstracts away the differences between various APIs to provide a consistent interface for PushPilot to link code revisions to task management systems.
- Provider Agnostic: Unified interface for all task managers.
- Stateless: No internal state or database dependencies; pass tokens and config per request.
- Normalized Errors: Consistent error handling for rate limits, auth failures, and validation errors.
- Lightweight: Zero fluff. Does not handle comments, webhooks, or OAuth flows.
``bash`
npm install @pushpilot/task-providers
`typescript
import { createProviderClient, CreateTaskInput } from '@pushpilot/task-providers';
// 1. Instantiate the client (Stateless: you provide the tokens)
const client = createProviderClient('asana', {
tokens: {
accessToken: 'your-asana-access-token',
// refreshToken: '...' // Optional, handled by app logic
}
});
// 2. Create a task
const task = await client.createTask({
title: 'Review Frontend Changes',
description: 'Please review the changes in PR #123',
projectId: '1204567890', // Provider-specific Project/Board ID
externalUrl: 'https://github.com/org/repo/pull/123'
});
console.log(Task Created: ${task.url} (ID: ${task.id}));
// 3. Verify connection (Optional)
const isConnected = await client.verifyConnection();
`
| Provider | ID | Configuration Requirements | Notes |
|----------|----|----------------------------|-------|
| Asana | asana | accessToken | Supports project assignment. Status updates limited to completion. |jira
| Jira | | instanceUrl, accessToken, email | Uses Jira Cloud API v3. Requires specific instance URL. |linear
| Linear | | accessToken | Maps projectId to Linear teamId. |
`typescript`
const jiraClient = createProviderClient('jira', {
tokens: {
instanceUrl: 'https://your-domain.atlassian.net',
email: 'user@example.com',
accessToken: 'api-token-value'
}
});
`typescript`
interface TaskProviderClient {
createTask(input: CreateTaskInput): Promise
updateTask(taskId: string, input: UpdateTaskInput): Promise
verifyConnection(): Promise
getCapabilities(): ProviderCapabilities;
}
typescript
interface CreateTaskInput {
title: string;
description?: string;
projectId?: string; // Asana Project GID, Jira Project ID/Key, Linear Team ID
externalUrl?: string; // Link to the PR or Revision
}
`$3
Returned after creating a task.
`typescript
interface TaskRef {
id: string; // The provider's native ID
url: string; // Direct link to the task in the browser
provider: string; // 'asana', 'jira', etc.
raw?: unknown; // The full original response from the provider
}
`🛡️ Error Handling
Errors are normalized to help the consuming application react logically without parsing provider-specific error strings.
| Error Class | Description |
|-------------|-------------|
|
AuthenticationError | Token is invalid or expired (401/403). Prompt user to reconnect. |
| RateLimitError | Too many requests (429). Check error.resetAt for when to retry. |
| ValidationError | Invalid input (400/422). Check error.fields. |
| ProviderError | General upstream errors (5xx or unknown). |`typescript
try {
await client.createTask(...);
} catch (error) {
if (error instanceof AuthenticationError) {
// Trigger re-auth flow
} else if (error instanceof RateLimitError) {
// Schedule retry after error.resetAt
}
}
`🛠️ Extending
To add a new provider (e.g., Trello):
1. Create the Provider Class:
Create
src/providers/trello/TrelloProvider.ts extending BaseProvider.
`typescript
export class TrelloProvider extends BaseProvider {
constructor(config: ProviderConfig) {
super(config, 'https://api.trello.com/1');
}
// Implement abstract methods...
}
`2. Register the Provider:
Add it to the switch case in
src/index.ts.3. Add Tests:
Create
tests/providers/TrelloProvider.test.ts`.- OAuth Flows: Token retrieval is handled by the main application.
- Webhooks: This package only makes outbound calls.
- Two-way Sync: This is a fire-and-forget integration layer.
- Complex Querying: We do not provide a unified search/filter language.
ISC