@pushpilot/task-providers
v0.1.0
Published
PushPilot’s provider-agnostic task integration layer
Maintainers
Readme
@pushpilot/task-providers
PushPilot’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.
✨ Features
- 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.
📦 Installation
npm install @pushpilot/task-providers🚀 Quick Start
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();🔌 Supported Providers
| 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. |
Jira Configuration Example
Jira requires the instance URL and email (for Basic Auth with API Token).
const jiraClient = createProviderClient('jira', {
tokens: {
instanceUrl: 'https://your-domain.atlassian.net',
email: '[email protected]',
accessToken: 'api-token-value'
}
});📚 API Reference
createProviderClient(providerId, config)
Factory function to create a client instance.
TaskProviderClient Interface
All providers implement this interface:
interface TaskProviderClient {
createTask(input: CreateTaskInput): Promise<TaskRef>;
updateTask(taskId: string, input: UpdateTaskInput): Promise<void>;
verifyConnection(): Promise<boolean>;
getCapabilities(): ProviderCapabilities;
}CreateTaskInput
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
}TaskRef
Returned after creating a task.
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). |
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):
Create the Provider Class: Create
src/providers/trello/TrelloProvider.tsextendingBaseProvider.export class TrelloProvider extends BaseProvider { constructor(config: ProviderConfig) { super(config, 'https://api.trello.com/1'); } // Implement abstract methods... }Register the Provider: Add it to the switch case in
src/index.ts.Add Tests: Create
tests/providers/TrelloProvider.test.ts.
❌ explicit Non-Goals
- 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.
License
ISC
