إنتقل إلى المحتوى الرئيسي

استخدام واجهة برمجة تطبيقات Cursor Cloud Agents وSDK

دليل Cursor Cloud Agents SDK

توفر واجهة برمجة تطبيقات Cursor Cloud Agents وSDK تحكماً برمجياً في وكلاء الترميز السحابيين. بدلاً من تشغيل ومراقبة الوكلاء يدوياً من المحرر، يمكنك بدؤهم وتوجيههم أثناء التشغيل والتقاط مخرجات شاشتهم وتلقي عمليات استدعاء Webhook عند اكتمال المهام. يقدم هذا الدليل شرحاً للمصادقة وإدارة دورة الحياة وأنماط تكامل SDK ونصائح لاستكشاف الأخطاء مستقاة من تجارب المطورين الحقيقية.

المتطلبات الأساسية والإعداد​

قبل التكامل مع واجهة Cloud Agents API، تأكد من توفر ما يلي:

  • حساب Cursor مع تفعيل الوصول إلى Cloud Agents
  • مفتاح API تم إنشاؤه من لوحة إعدادات Cursor
  • Node.js 18 أو أحدث (لـ TypeScript/JavaScript SDK)
  • فهم أساسي لأنماط البرمجة غير المتزامنة
تلميح

قم بتخزين مفتاح API في متغير بيئي بدلاً من تضمينه مباشرة في الكود. استخدم ملف .env أثناء التطوير ومدير أسرار في الإنتاج.

تثبيت SDK​

قم بتثبيت Cursor Cloud Agents SDK من السجل العام:

npm install @cursor/cloud-agents-sdk
# or
yarn add @cursor/cloud-agents-sdk
# or
pnpm add @cursor/cloud-agents-sdk

تحقق من التثبيت عن طريق فحص إصدار الحزمة:

npx @cursor/cloud-agents-sdk --version

مصادقة API​

يتطلب كل طلب إلى Cloud Agents API رمز bearer. يتعامل SDK مع هذا تلقائياً عند تهيئة العميل:

import { CursorCloudClient } from "@cursor/cloud-agents-sdk";

const client = new CursorCloudClient({
apiKey: process.env.CURSOR_API_KEY,
// اختياري: تجاوز نقطة نهاية API الافتراضية
endpoint: "https://api.cursor.sh/v1",
// اختياري: تعيين مهلة افتراضية لجميع العمليات
timeout: 300000, // 5 دقائق
});

إذا كنت تفضل مكالمات HTTP الخام بدلاً من SDK، فقم بتضمين الرأس يدوياً:

import os
import requests

headers = {
"Authorization": f"Bearer {os.environ['CURSOR_API_KEY']}",
"Content-Type": "application/json",
}

response = requests.post(
"https://api.cursor.sh/v1/agents",
headers=headers,
json={
"repo": "https://github.com/my-org/my-repo",
"branch": "feature/auth-refactor",
"task": "Refactor the authentication module to use JWT",
},
)
print(response.json())
warning

لا تقم مطلقاً بإضافة مفتاح API إلى نظام التحكم في الإصدار. إذا تم كشف المفتاح، فقم بإلغائه فوراً من لوحة Cursor وأنشئ مفتاحاً جديداً. قم بتدوير المفاتيح بشكل منتظم.

دورة حياة الوكيل السحابي​

يمر الوكيل السحابي بدورة حياة محددة بوضوح. يساعدك فهم كل حالة في بناء خطوط أنابيب أتمتة قوية.

حالات دورة الحياة​

الحالةالوصف
queuedتم إنشاء الوكيل وهو في انتظار فتحة سحابية
runningالوكيل ينفذ المهمة بنشاط
pausedتم إيقاف الوكيل مؤقتاً بواسطة توجيه أثناء التشغيل أو تدخل يدوي
completedأكمل الوكيل المهمة بنجاح
failedواجه الوكيل خطأً لم يتمكن من التعافي منه
cancelledتم إلغاء الوكيل من قبل المستخدم أو بسبب انتهاء المهلة

إنشاء وكيل جديد​

const agent = await client.agents.create({
repo: "https://github.com/my-org/my-repo",
branch: "feature/payment-gateway",
task: "Integrate Stripe payment gateway with proper error handling",
// إعدادات اختيارية
model: "cursor-agent-pro",
maxSteps: 50,
autoMerge: false,
environment: {
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
},
});

console.log(`Agent created with ID: ${agent.id}`);
console.log(`Initial status: ${agent.status}`);

مراقبة حالة الوكيل​

يمكنك استطلاع حالة الوكيل أو الاشتراك في التحديثات الفورية:

// نهج الاستطلاع
async function waitForCompletion(agentId: string) {
while (true) {
const status = await client.agents.get(agentId);
console.log(`[${new Date().toISOString()}] Status: ${status.state}`);

if (status.state === "completed") {
return status;
}
if (status.state === "failed" || status.state === "cancelled") {
throw new Error(`Agent ended in state: ${status.state}`);
}

await new Promise((resolve) => setTimeout(resolve, 10000)); // استطلاع كل 10 ثوان
}
}

// نهج البث (موصى به)
const stream = await client.agents.stream(agent.id, (event) => {
console.log(`Event: ${event.type}`, event.data);
});

stream.on("step", (data) => {
console.log(`Agent step: ${data.description}`);
});

stream.on("file_change", (data) => {
console.log(`File modified: ${data.path}`);
});

stream.on("error", (data) => {
console.error(`Agent error: ${data.message}`);
});
تلميح

تفضل نهج البث على الاستطلاع. فهو يقلل من مكالمات API ويوفر تحديثات بزمن استجابة أقل ويتجنب مشاكل حدود المعدل أثناء المهام طويلة الأمد.

التوجيه أثناء التشغيل​

إحدى أقوى ميزات Cloud Agents API هي القدرة على توجيه الوكيل أثناء تشغيله بنشاط. يتيح لك ذلك تصحيح المسار أو إضافة سياق أو تغيير الاتجاه دون البدء من جديد.

إرسال رسالة توجيه​

const steerResult = await client.agents.steer(agent.id, {
message: "Stop using the mock data approach. Please connect to the real database using the connection string in the .env file.",
// اختياري: إرفاق مرجع ملف
attachments: ["src/config/database.ts"],
// اختياري: تغيير النموذج أثناء التشغيل
model: "cursor-agent-pro",
});

console.log(`Steer accepted: ${steerResult.accepted}`);
console.log(`Agent now running with updated context`);

سيناريوهات التوجيه الشائعة​

يكون التوجيه أثناء التشغيل مفيداً في عدة مواقف:

  1. تصحيح نهج خاطئ: يبدأ الوكيل في كتابة اختبارات وهمية عندما كنت تريد اختبارات تكامل.
  2. إضافة سياق مفقود: لا يعرف الوكيل عن وحدة أداة مشتركة أنشأتها الأسبوع الماضي.
  3. تغيير النطاق: تريد من الوكيل أيضاً إضافة توثيق للكود الذي كتبه للتو.
  4. فرض القيود: الوكيل على وشك تعديل ملفات خارج النطاق المقصود.
// مثال: التوجيه لإضافة نطاق التوثيق
await client.agents.steer(agent.id, {
message: "Great progress on the API endpoints. Now also add JSDoc comments to every exported function and update the README with the new endpoint list.",
});

// مثال: التوجيه لفرض حد أمني
await client.agents.steer(agent.id, {
message: "Do not modify any files in the src/legacy/ directory. Those are deprecated modules scheduled for removal.",
});
warning

تتم معالجة رسائل التوجيه بشكل غير متزامن. توجد نافذة زمنية قصيرة بين إرسال التوجيه وتبني الوكيل له. لا ترسل رسائل توجيه متضاربة متعددة في تتابع سريع، لأن ذلك قد يربك الوكيل ويؤدي إلى سلوك غير متسق.

إيقاف الوكلاء مؤقتاً واستئنافهم​

// إيقاف الوكيل قيد التشغيل مؤقتاً
await client.agents.pause(agent.id);
console.log("Agent paused");

// مراجعة الحالة الحالية
const state = await client.agents.get(agent.id);
console.log("Files changed so far:", state.filesChanged);

// الاستئناف عند الاستعداد
await client.agents.resume(agent.id);
console.log("Agent resumed");

واجهة RecordScreen API​

تلتقط واجهة RecordScreen API لقطات بصرية لشاشة الوكيل السحابي في لحظات محددة. هذا لا يقدر بثمن لتصحيح الأخطاء والتدقيق وبناء لوحات معلومات بصرية.

التقاط لقطة شاشة​

// التقاط لقطة شاشة واحدة
const screenshot = await client.agents.recordScreen(agent.id, {
format: "png",
// اختياري: التقاط منطقة معينة فقط
region: { x: 0, y: 0, width: 1920, height: 1080 },
// اختياري: تضمين تراكب موضع المؤشر
showCursor: true,
});

// يتم إرجاع لقطة الشاشة كسلسلة base64
const fs = require("fs");
fs.writeFileSync(`agent-${agent.id}-screenshot.png`, Buffer.from(screenshot.data, "base64"));
console.log(`Screenshot saved. Size: ${screenshot.width}x${screenshot.height}`);

تسجيل مقطع فيديو​

// بدء تسجيل الشاشة
const recording = await client.agents.recordScreen(agent.id, {
mode: "video",
duration: 30000, // 30 ثانية
fps: 15,
format: "webm",
});

// يرجع التسجيل رابطاً قابلاً للتنزيل
console.log(`Recording available at: ${recording.url}`);
console.log(`Recording expires at: ${recording.expiresAt}`);

استكشاف أخطاء RecordScreen وإصلاحها​

قد تفشل مكالمات RecordScreen لعدة أسباب. إليك المشاكل الأكثر شيوعاً وحلولها:

warning

ترجع RecordScreen خطأ 409 Conflict إذا لم يكن الوكيل في حالة running. تأكد من أن الوكيل يعمل بنشاط قبل محاولة التقاط شاشته. إذا تم إيقاف الوكيل مؤقتاً أو اكتمل، فلا يمكنك تسجيل شاشته.

// غلاف RecordScreen آمن مع معالجة الأخطاء
async function safeRecordScreen(agentId: string, options: any) {
const agent = await client.agents.get(agentId);

if (agent.state !== "running") {
console.warn(`Cannot record screen: agent is in ${agent.state} state`);
return null;
}

try {
return await client.agents.recordScreen(agentId, options);
} catch (error: any) {
if (error.code === "SCREEN_CAPTURE_UNAVAILABLE") {
console.error("Screen capture is not available for this agent configuration.");
console.error("Make sure the agent was launched with screen capture enabled.");
} else if (error.code === "RATE_LIMITED") {
console.error("Too many screen capture requests. Please wait before retrying.");
console.log(`Retry after: ${error.retryAfter} seconds`);
} else {
throw error;
}
return null;
}
}

لتمكين التقاط الشاشة عند إنشاء وكيل، اضبط خيار screenCapture:

const agent = await client.agents.create({
repo: "https://github.com/my-org/my-repo",
branch: "main",
task: "Fix the flaky integration tests",
screenCapture: {
enabled: true,
autoCapture: true, // التقاط تلقائي في كل خطوة
captureInterval: 5000, // التقاط كل 5 ثوان
},
});
تلميح

يؤدي تمكين autoCapture إلى إنشاء خط زمني مرئي لعمل الوكيل. يمكنك إعادة تشغيل الجلسة بأكملها لاحقاً لأغراض تصحيح الأخطاء أو مراجعات الامتثال. كن على دراية بأن هذا يزيد من استخدام التخزين وقد يؤثر قليلاً على أداء الوكيل.

عمليات استدعاء Webhook​

تتيح لك Webhooks تلقي إشعارات فورية عند حدوث أحداث للوكيل. هذا ضروري لبناء خطوط أنابيب CI/CD مؤتمتة ولوحات معلومات مراقبة.

تسجيل Webhook​

const webhook = await client.webhooks.create({
url: "https://my-app.com/api/cursor-webhook",
events: [
"agent.created",
"agent.step_completed",
"agent.completed",
"agent.failed",
"agent.steer_received",
],
// اختياري: إضافة سر للتحقق من التوقيع
secret: process.env.WEBHOOK_SECRET,
});

console.log(`Webhook registered with ID: ${webhook.id}`);

معالجة حمولات Webhook​

إليك مثال على نقطة نهاية Express تستقبل وتتحقق من عمليات استدعاء Webhook:

const express = require("express");
const crypto = require("crypto");
const app = express();
app.use(express.raw({ type: "application/json" }));

app.post("/api/cursor-webhook", (req, res) => {
// التحقق من توقيع Webhook
const signature = req.headers["x-cursor-signature"];
const expectedSignature = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(req.body)
.digest("hex");

if (signature !== expectedSignature) {
return res.status(401).send("Invalid signature");
}

const event = JSON.parse(req.body.toString());

switch (event.type) {
case "agent.created":
console.log(`Agent ${event.data.agentId} created for repo ${event.data.repo}`);
break;

case "agent.step_completed":
console.log(`Agent ${event.data.agentId} completed step ${event.data.stepNumber}`);
console.log(` Files changed: ${event.data.filesChanged.join(", ")}`);
break;

case "agent.completed":
console.log(`Agent ${event.data.agentId} completed successfully`);
console.log(` Pull request: ${event.data.pullRequestUrl}`);
// تشغيل خط أنابيب CI النهائي
triggerCIPipeline(event.data.agentId);
break;

case "agent.failed":
console.error(`Agent ${event.data.agentId} failed: ${event.data.error}`);
// إرسال تنبيه إلى قناة الفريق
sendAlert(event.data);
break;
}

// الرد دائماً بـ 200 للتأكيد على الاستلام
res.status(200).send("OK");
});

app.listen(3000, () => {
console.log("Webhook server listening on port 3000");
});
warning

تحقق دائماً من توقيعات Webhook. بدون التحقق من التوقيع، يمكن لمهاجم إرسال حمولات Webhook مزيفة إلى نقطة النهاية الخاصة بك. يحتوي رأس x-cursor-signature على تجزئة HMAC-SHA256 لجسم الطلب الخام الموقع بسر Webhook الخاص بك.

سلوك إعادة محاولة Webhook​

إذا لم تستجب نقطة النهاية الخاصة بك بحالة 200 خلال 10 ثوان، فستعيد API محاولة التسليم. جدول إعادة المحاولة هو:

المحاولةالتأخير
إعادة المحاولة الأولى1 دقيقة
إعادة المحاولة الثانية5 دقائق
إعادة المحاولة الثالثة30 دقيقة
إعادة المحاولة الرابعة2 ساعة
المحاولة النهائية12 ساعة

بعد المحاولة النهائية، يُتم وضع علامة على تسليم Webhook كفاشل، وستحتاج إلى التحقق من حالة الوكيل يدوياً عبر API.

تلميح

إذا كانت معالجة Webhook الخاصة بك تتضمن عمليات طويلة الأمد، فاستجب بـ 200 فوراً وادفع العمل إلى قائمة انتظار خلفية. هذا يتجنب انتهاء المهلة ويضمن تسليم Webhook موثوقاً.

أنماط تكامل SDK​

النمط 1: تكامل خط أنابيب CI/CD​

إنشاء وكيل سحابي تلقائياً عند فتح طلب سحب:

import { CursorCloudClient } from "@cursor/cloud-agents-sdk";

const client = new CursorCloudClient({
apiKey: process.env.CURSOR_API_KEY,
});

export async function onPullRequestOpened(pr: any) {
const agent = await client.agents.create({
repo: pr.repositoryUrl,
branch: pr.headBranch,
task: `Review and improve this pull request. Focus on: ${pr.description}`,
autoMerge: false,
screenCapture: { enabled: true },
});

// التعليق على طلب السحب برابط الوكيل
await pr.addComment(
`A Cursor Cloud Agent is now reviewing this PR. ` +
`Track progress: https://cursor.sh/agents/${agent.id}`
);

return agent;
}

النمط 2: تنسيق متعدد الوكلاء​

تشغيل عدة وكلاء بالتوازي في مهام مختلفة:

async function runParallelAgents(repo: string) {
const tasks = [
"Write unit tests for the authentication module",
"Write unit tests for the payment module",
"Write integration tests for the API endpoints",
"Update API documentation with OpenAPI specs",
];

const agents = await Promise.all(
tasks.map((task) =>
client.agents.create({
repo,
branch: "main",
task,
model: "cursor-agent-pro",
})
)
);

console.log(`Launched ${agents.length} agents in parallel`);

// انتظار اكتمال جميع الوكلاء
const results = await Promise.allSettled(
agents.map((agent) => waitForCompletion(agent.id))
);

// تلخيص النتائج
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`Task ${index + 1}: Completed - ${result.value.filesChanged.length} files changed`);
} else {
console.error(`Task ${index + 1}: Failed - ${result.reason.message}`);
}
});
}
warning

تشغيل عدة وكلاء بالتوازي يستهلك موارد سحابية بسرعة. راقب استخدامك واضبط حد maxSteps معقول لكل وكيل للتحكم في التكاليف. تحقق من حد الوكلاء المتزامنين في خطتك قبل إطلاق دفعات كبيرة.

النمط 3: مراجعة بشرية في الحلقة​

الجمع بين Webhooks والتوجيه أثناء التشغيل لإنشاء نقطة فحص مراجعة بشرية:

// عندما يصل الوكيل إلى خطوة معينة، أوقفه مؤقتاً للمراجعة البشرية
const stream = await client.agents.stream(agent.id, async (event) => {
if (event.type === "step" && event.data.stepNumber === 10) {
// إيقاف الوكيل مؤقتاً للمراجعة البشرية
await client.agents.pause(agent.id);

// إرسال إشعار إلى قناة المراجعة
await sendSlackNotification({
channel: "#code-review",
text: `Agent ${agent.id} has paused for review. Check the changes before resuming.`,
});

// سيقوم المراجع البشري باستئناف أو توجيه الوكيل يدوياً
}
});

النمط 4: التعافي التلقائي من الأخطاء​

async function runWithRetry(repo: string, task: string, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const agent = await client.agents.create({
repo,
branch: "main",
task,
maxSteps: 30,
});

try {
const result = await waitForCompletion(agent.id);

if (result.state === "completed") {
return result;
}
} catch (error) {
console.error(`Attempt ${attempt} failed: ${error.message}`);

if (attempt < maxRetries) {
// توجيه المحاولة التالية بسياق الخطأ
task = `${task}\n\nPrevious attempt failed with: ${error.message}. Please avoid this approach.`;
}
}
}

throw new Error(`Agent failed after ${maxRetries} attempts`);
}

استكشاف المشاكل الشائعة وإصلاحها​

وكيل عالق في حالة الانتظار​

إذا بقي الوكيل في حالة queued لفترة طويلة، فعادةً ما يعني ذلك أن جميع الفتحات السحابية مشغولة.

// التحقق من الاستخدام الحالي لحسابك
const usage = await client.usage.get();
console.log(`Active agents: ${usage.activeAgents}/${usage.maxConcurrentAgents}`);
console.log(`Queue length: ${usage.queueLength}`);

if (usage.activeAgents >= usage.maxConcurrentAgents) {
console.log("All slots are in use. Consider upgrading your plan or waiting for agents to complete.");
}

أخطاء مصادقة SDK​

إذا تلقيت خطأ 401 Unauthorized، فتحقق مما يلي:

  1. مفتاح API الخاص بك صالح ولم يتم إلغاؤه
  2. تم تفعيل نطاق cloud-agents للمفتاح
  3. تستخدم عنوان URL الصحيح لنقطة النهاية
  4. تم تحميل المتغير البيئي بشكل صحيح
// تصحيح المصادقة
const client = new CursorCloudClient({
apiKey: process.env.CURSOR_API_KEY,
});

try {
const me = await client.auth.verify();
console.log("Authentication successful");
console.log(`Account: ${me.accountName}`);
console.log(`Plan: ${me.plan}`);
console.log(`Scopes: ${me.scopes.join(", ")}`);
} catch (error) {
console.error("Authentication failed:", error.message);
console.log("Check your API key and ensure it has the 'cloud-agents' scope.");
}

فشل تسليم Webhook​

إذا لم تصل Webhooks إلى نقطة النهاية الخاصة بك:

  1. تحقق من أن عنوان URL الخاص بـ Webhook متاح للوصول العام (وليس localhost)
  2. تأكد من أن خادمك يرجع 200 خلال 10 ثوان
  3. تحقق من أن شهادة SSL الخاصة بك صالحة
  4. تأكد من أن جدار الحماية الخاص بك يسمح بالاتصالات الواردة من نطاقات IP الخاصة بـ Cursor
// اختبار إمكانية الوصول إلى نقطة نهاية Webhook
const test = await client.webhooks.test(webhook.id);
console.log(`Test result: ${test.status}`);
console.log(`Response time: ${test.responseTime}ms`);
if (test.error) {
console.error(`Error: ${test.error}`);
}
تلميح

استخدم خدمة مثل webhook.site أو ngrok أثناء التطوير لاختبار تسليم Webhook بسرعة دون نشر خادم كامل. يساعد هذا في عزل ما إذا كانت المشكلة في نقطة النهاية الخاصة بك أو في تكوين Webhook.

ملخص أفضل الممارسات​

إليك قائمة تحقق بأفضل الممارسات التي يجب اتباعها عند البناء باستخدام Cursor Cloud Agents API وSDK:

  • قم دائماً بتخزين مفاتيح API في متغيرات بيئية أو مدير أسرار
  • استخدم البث بدلاً من الاستطلاع للتحديثات الفورية
  • نفذ التحقق من توقيع Webhook في كل نقطة نهاية
  • اضبط حدود maxSteps معقولة للتحكم في التكاليف ومنع الوكلاء الجامحين
  • استخدم التوجيه أثناء التشغيل لتصحيح المسار بدلاً من إعادة تشغيل الوكلاء
  • فعّل التقاط الشاشة لتصحيح الأخطاء ومسارات التدقيق في المهام الحرجة
  • نفذ التراجع الأسي عند إعادة محاولة مكالمات API الفاشلة
  • راقب استخدام الوكيل المتزامن لتجنب مجاعة قائمة الانتظار
  • اختبر نقاط نهاية Webhook بنقطة نهاية الاختبار المدمجة قبل الإطلاق المباشر
  • سجل جميع أحداث الوكيل لتحليل ما بعد الحادثة والامتثال
warning

كن يقظاً بشأن حدود المعدل. تفرض API حداً افتراضياً يبلغ 100 طلب في الدقيقة. إذا تجاوزت هذا الحد، فستتلقى استجابة 429 Too Many Requests. نفذ تراجعاً أسياً مع ارتجاج للتعامل مع إعادات محاولة حدود المعدل بسلاسة.

الخاتمة​

توفر Cursor Cloud Agents API وSDK واجهة برمجية قوية لأتمتة مهام الترميز على نطاق واسع. من خلال الجمع بين إدارة دورة حياة الوكيل والتوجيه أثناء التشغيل وواجهة RecordScreen API وعمليات استدعاء Webhook، يمكنك بناء خطوط أنابيب أتمتة متطورة تتكامل بسلاسة مع سير عمل التطوير الحالي.

ابدأ بإعداد وكيل واحد بسيط، ثم أضف تدريجياً تكامل Webhook والتنسيق المتوازي ونقاط فحص المراجعة البشرية مع نمو ثقتك. يجعل تصميم SDK المتمحور حول TypeScript سهولة التكامل في تطبيقات Node.js الحديثة، بينما تدعم واجهة HTTP الخام أي لغة برمجة.