self-heal-sdk
v0.0.8
Published
Automatic bug fixing and feature implementation using Cursor Background Agents
Downloads
42
Maintainers
Readme
Self-Healing SDK
Automatic bug fixing and feature implementation using Cursor Background Agents. Build applications that can heal themselves and implement user feedback autonomously.
📦 Installation
npm install self-heal-sdk🏃♂️ Quick Start
Basic Setup (Config)
Use explicit configuration parameters:
// src/lib/self-heal.ts
import { selfHealAgent } from "self-heal-sdk";
export const agent = selfHealAgent({
apiKey: "your_cursor_api_key",
repository: "https://github.com/your-username/your-repo",
branch: "main",
enableInDevelopment: true,
});Basic Setup (Environment Variables)
Set up environment variables and use no config:
# .env
CURSOR_API_KEY=your_cursor_api_key_here
CURSOR_AGENT_GITHUB_URL=https://github.com/your-username/your-repo
# Optional
CURSOR_AGENT_GIT_BRANCH=main
CURSOR_AGENT_WEBHOOK_URL=https://your-app.com/api/webhooks/agent-status
SELF_HEAL_ENABLE_IN_DEV=true
SELF_HEAL_DEBUG=true// src/lib/self-heal.ts
import { selfHealAgent } from "self-heal-sdk";
export const agent = selfHealAgent();Agent Memory
Add memory option to avoid duplicate PRs for the same error:
import { selfHealAgent, type AgentResponse } from "self-heal-sdk";
import { kv } from "lib/redis.ts";
export const agent = selfHealAgent({
apiKey: "your_cursor_api_key",
repository: "https://github.com/your-username/your-repo",
memory: {
async get(hash: string): Promise<AgentResponse | null> {
const data = await kv.get(`self-heal:${hash}`);
return data as AgentResponse | null;
},
async put(hash: string, response: AgentResponse): Promise<AgentResponse> {
await kv.set(`self-heal:${hash}`, response, { ex: 86400 }); // 24h TTL
return response;
},
},
});Duplicate Detection: When the same error occurs multiple times, the SDK returns the cached AgentResponse, preventing redundant agents:
const response = await agent.fix(error);
if (response?.isDuplicate) {
console.log("Found existing agent:", response.agentId);
} else {
console.log("Created new agent:", response.agentId);
}Use Cases
Automatic Bug Fixing
import { agent } from "./lib/self-heal";
async function deleteUser(userId: string) {
try {
await db.users.delete({ where: { id: userId } });
return { success: true };
} catch (error) {
// Automatically create a PR to fix the bug
await agent.fix(error, {
context: "User deletion failed due to database constraint",
filePath: "src/lib/database.ts",
traceId: "req_12345",
});
throw error; // Re-throw for UI handling
}
}User Feedback Implementation
// Minimal usage - just the feedback
await agent.improve({
feedback: "Add a confirmation dialog before deleting records",
});
// With optional details
await agent.improve({
feedback: "Add a confirmation dialog before deleting records",
category: "improvement",
priority: "medium",
currentPage: "/admin/users",
context: { userId: "123", role: "admin", sessionId: "xyz" },
traceId: "feedback_987",
});Next.js Integration
Automatically catch and fix errors in your Next.js API routes without manual try/catch blocks.
Pages Router (pages/api/)
Wrap your API handlers with either an existing agent or configuration:
// pages/api/users.ts
import { wrapApiHandlerWithSelfHeal } from "self-heal-sdk/nextjs";
import type { NextApiRequest, NextApiResponse } from "next";
async function handler(req: NextApiRequest, res: NextApiResponse) {
// Your code here - errors are automatically caught and fixed
const users = await db.users.findMany();
res.json({ users });
}
// Option 1: Use existing agent from your app
import { agent } from "../lib/self-heal";
export default wrapApiHandlerWithSelfHeal(handler, agent);
// Option 2: Create new agent with config
export default wrapApiHandlerWithSelfHeal(handler, {
apiKey: "your_cursor_api_key",
repository: "https://github.com/your-username/your-repo",
enableInDevelopment: true,
});App Router (app/api/)
Wrap your route handlers with either an existing agent or configuration:
// app/api/users/route.ts
import { wrapRouteHandlerWithSelfHeal } from "self-heal-sdk/nextjs";
async function GET() {
// Your code here - errors are automatically caught and fixed
const users = await db.users.findMany();
return Response.json({ users });
}
async function POST(request: Request) {
const body = await request.json();
const user = await db.users.create({ data: body });
return Response.json({ user });
}
// Option 1: Use existing agent from your app
import { agent } from "../../lib/self-heal";
export const { GET: wrappedGET, POST: wrappedPOST } =
wrapRouteHandlerWithSelfHeal({ GET, POST }, agent);
export { wrappedGET as GET, wrappedPOST as POST };
// Option 2: Create new agent with config
export const { GET: wrappedGET, POST: wrappedPOST } =
wrapRouteHandlerWithSelfHeal(
{ GET, POST },
{
apiKey: "your_cursor_api_key",
repository: "https://github.com/your-username/your-repo",
enableInDevelopment: true,
},
);
export { wrappedGET as GET, wrappedPOST as POST };🔧 Configuration
selfHealAgent() Factory Function
The selfHealAgent() function uses this priority order:
- Explicit parameters - Values passed directly to the function
- Environment variables - Fallback values from your
.envfile - Defaults - Built-in defaults for optional parameters
interface SelfHealingConfig {
apiKey?: string; // Cursor API key (required via config or env)
repository?: string; // GitHub repository URL (required via config or env)
branch?: string; // Git branch (default: 'main')
enableInDevelopment?: boolean; // Enable in dev mode (default: false)
debug?: boolean; // Enable debug logging (default: false)
webhookUrl?: string; // Webhook for status updates
memory?: SelfHealingMemory; // Optional memory system
prompts?: PromptOverrides; // Optional custom prompt generators
}Configuration Examples
// 1. Explicit configuration
const agent = selfHealAgent({
apiKey: "your-key",
repository: "https://github.com/user/repo",
branch: "development",
});
// 2. Environment variables only
const agent = selfHealAgent();
// 3. Mixed - explicit overrides env
const agent = selfHealAgent({
branch: "feature-branch", // overrides default 'main'
enableInDevelopment: true, // overrides env/default
});Custom Prompts
Override the default AI prompts with your own logic:
import {
selfHealAgent,
type FixPromptParams,
type ImprovementPromptParams,
} from "self-heal-sdk";
const agent = selfHealAgent({
apiKey: "your-cursor-api-key",
repository: "https://github.com/user/repo",
prompts: {
getFixPrompt: ({
error,
contextString,
filePath,
traceId,
}: FixPromptParams) => {
return `
URGENT BUG FIX NEEDED ${traceId ? `[${traceId}]` : ""}
Error: ${error.message}
Context: ${contextString}
File: ${filePath}
Please fix this immediately following our coding standards.
`.trim();
},
getImprovementPrompt: ({
feedback,
category,
priority,
traceId,
}: ImprovementPromptParams) => {
return `
FEATURE REQUEST ${traceId ? `[${traceId}]` : ""}
Priority: ${priority.toUpperCase()}
Category: ${category}
Request: ${feedback}
Implement this feature using our design system.
`.trim();
},
},
});📝 API Reference
Functions
selfHealAgent(config?)
Factory function to create a SelfHealingAgent instance.
Parameters:
config?: SelfHealingConfig- Optional configuration object
Returns: SelfHealingAgent
SelfHealingAgent Class
fix(input, options?)
Automatically create a background agent to fix bugs when errors occur.
Parameters:
input: unknown- The error/issue that occurred (accepts any type)options?: SelfHealOptions- Optional context about the error
Returns: Promise<AgentResponse | null>
improve(options)
Automatically create a background agent to implement user feedback.
Parameters:
options: SelfImproveOptions- Feedback details and context
Returns: Promise<AgentResponse | null>
Interfaces
SelfHealingConfig
apiKey?: string- Cursor API keyrepository?: string- GitHub repository URLbranch?: string- Git branch (default: 'main')enableInDevelopment?: boolean- Enable in dev mode (default: false)debug?: boolean- Enable debug logging (default: false)webhookUrl?: string- Webhook for status updatesmemory?: SelfHealingMemory- Optional memory systemprompts?: PromptOverrides- Optional custom prompt generators
SelfHealOptions
context?: string | Record<string, any>- Context about the errorfilePath?: string- File path where error occurredtraceId?: string- Trace ID for request tracking
SelfImproveOptions
feedback: string- User feedback or feature requestcategory?: string- Feedback categorypriority?: string- Priority levelcurrentPage?: string- Current page/routeadditionalContext?: string- Additional contextcontext?: string | Record<string, any>- User/session contexttraceId?: string- Trace ID for request tracking
AgentResponse
agentId: string- Unique Cursor agent IDstatus?: string- Current statusrepository?: string- Repository URLbranch?: string- Branch namesummary?: string- Agent summaryisDuplicate?: boolean- Whether retrieved from memory cache
SelfHealingMemory
get(hash: string): Promise<AgentResponse | null>- Retrieve cached responseput(hash: string, response: AgentResponse): Promise<AgentResponse>- Store response
PromptOverrides
getFixPrompt?: (params: FixPromptParams) => string- Custom fix prompt generatorgetImprovementPrompt?: (params: ImprovementPromptParams) => string- Custom improvement prompt generator
FixPromptParams
error: Error- The error objectcontextString: string- Stringified contextfilePath: string- File pathtraceId?: string- Trace IDerrorHash?: string- Error hasherrorSignature?: string- Error signature
ImprovementPromptParams
feedback: string- User feedbackcategory: string- Feedback categorypriority: string- Priority levelcurrentPage?: string- Current pageadditionalContext?: string- Additional contextcontext?: string- User contexttraceId?: string- Trace ID
Environment Variables
| Variable | Required | Description |
| -------------------------- | -------- | -------------------------------------- |
| CURSOR_API_KEY | Yes* | Your Cursor API key |
| CURSOR_AGENT_GITHUB_URL | Yes* | GitHub repository URL |
| CURSOR_AGENT_GIT_BRANCH | No | Git branch name (default: main) |
| CURSOR_AGENT_WEBHOOK_URL | No | Webhook URL for status updates |
| SELF_HEAL_ENABLE_IN_DEV | No | Enable in development (default: false) |
| SELF_HEAL_DEBUG | No | Enable debug logging (default: false) |
*Required if not provided in config object
