تخطَّ إلى المحتوى

أحداث النطاق

DomainEventBus ناقل بث داخل العملية، بنمط النشر والاشتراك. يستدعي الناشرون publish(event)، ويستهلك المشتركون مجرى on<T>() مُنمَّطًا. كل حدث ينفّذ DomainEvent ويحمل occurredAt.

الناقل يعمل داخل cc_server. كل ناشر وكل مشترك حي يعيش هناك. لا يرى أي عميل هذا الناقل. يعيد الخادم توجيه مجموعة منتقاة كإطارات JSON-RPC من النمط notifications/*، مصفّاة لكل مشترك وفق عضوية مساحة العمل.

المقياس العدد
أصناف الأحداث الملموسة 54
ملفات المصدر (packages/cc_domain/lib/core/domain/events/) 14 (إضافة إلى domain_event_bus.dart)
القواعد المجرّدة التي لا تُنشَر مباشرة 1 (TaskLifecycleEvent، تسلسل هرمي مختوم)

كل حدث في الفهرس أدناه يعيش في ذلك الدليل الواحد، ولا تُعلَن أحداث نطاق في غيره.

أحداث مساحة العمل والوكيل والمستودع

قسم بعنوان “أحداث مساحة العمل والوكيل والمستودع”
الحدث الحمولة متى يُطلَق
WorkspaceCreated workspaceId تُنشأ مساحة العمل
AgentRunCompleted agentId، runId?، workspaceId?، conversationId? ينهي الوكيل تشغيلًا (نجاحًا أو فشلًا)
AgentAwaitingInput workspaceId، kind، summary، spaceId?، conversationId?، agentId?، agentName? يبدأ وكيل انتظار إنسان: موافقة، أو سؤال ask_user، أو تشغيل متوقّف بسبب بيانات اعتماد (قيمة kind هي approval أو question أو credential)
RepoAdded repoId، path، workspaceId يُسجَّل مستودع، ويُطلَق فهرسة الشفرة في الخلفية
SkillUpdated workspaceId، slug، origin، computedHash، scanVerdict? تُثبَّت مهارة أو تُحدَّث، حاملة حكم فحص سلسلة التوريد

الكتلة الأولى هي دورة حياة طلب السحب نفسه. والثانية هي مراقبة طلب السحب المؤلَّف: إشارات عن طلب سحب فتحته أنت، وكل منها يحمل forUserId حتى يستطيع الاستطلاع توجيهها إلى الشخص المعني بدل بثّها.

الحدث الحمولة متى يُطلَق
PullRequestPublished prId، workspaceId، repoOwner، repoName يفتح الوكيل طلب سحب
PullRequestStatusChanged status، workspaceId، prId?، repoFullName?، prNumber? يُدمَج طلب السحب أو يُغلَق أو يُفتَح أو يُعاد فتحه أو يُوافَق عليه
PrMerged prId، workspaceId، agentId يُدمَج طلب السحب. إشارة ضيقة خاصة بالدمج، تُحفَظ للتحليلات والإشعارات
PrReviewRequested workspaceId، repoOwner، repoName، prNumber، prTitle يطلب GitHub مراجعة مستخدم الخادم (استطلاع الإشعارات، review_requested)
PrMentioned workspaceId، repoOwner، repoName، prNumber، prTitle يُشار إلى مستخدم الخادم في طلب سحب (استطلاع الإشعارات، mention)
ExternalPrMerged workspaceId، repoOwner، repoName، prNumber، prTitle، mergedByLogin? دُمج طلب سحب متتبَّع خارجيًا (ليس من وكيل)، اكتشفه استطلاع إشعارات GitHub، ويُقابَل بفئة الإشعار prMerged
ExternalPrDetected repoOwner، repoName، prNumber، prTitle، author، workspaceId? وُجد طلب سحب ليس من وكيل عبر الاستطلاع. لخط الأنابيب فقط (يدفع external_pr_welcome)، ولا يرفع إشعارًا
PrHeadChanged repoOwner، repoName، prNumber، prTitle، previousHeadSha، headSha، workspaceId تحرّك SHA رأس طلب السحب. دفع المؤلف
ReviewBecameStale workspaceId، spaceId، repoOwner، repoName، prNumber، prTitle، reviewedHeadSha، headSha لم تعد مراجعة ذكاء اصطناعي منتهية تصف طلب السحب الذي راجعته. لا يُطلَق إلا حين توجد مراجعة للإيداع المستبدَل، فيبقى إشارة لا تنبيهًا عند كل دفع

تحمل الستة كلها workspaceId وrepoOwner وrepoName وprNumber وprTitle وforUserId اختياريًا.

الحدث حمولة إضافية متى يُطلَق
PrMergeReadinessChanged ready، reason صار طلب سحب ألّفته قابلًا للدمج، أو كفّ عن ذلك
PrReviewDecisionChanged decision، reviewersRemaining، approverLogin? وافق مراجع، أو طلب تغييرات، أو أُسقطت موافقة
PrChecksStatusChanged failing، failingCheckName?، failingCheckUrl? احمرّ CI، أو تعافى
PrCommentMentioned commentId، authorLogin، bodyPreview، isReviewComment، threadId?، path?، line? أشار إليك أحد في تعليق على طلب السحب أو في تعليق مراجعة
PrThreadReplied commentId، authorLogin، bodyPreview، threadId?، path?، line? رد أحد في خيط مراجعة أنت فيه
PrThreadResolved threadId، commentId?، path?، line? حلّ أحد خيط مراجعة أنت فيه
الحدث الحمولة متى يُطلَق
MessageReceived spaceId، messageId، senderName، contentPreview، isAgentMessage، workspaceId?، mentions، requestedByUserId?، senderUserId? تصل رسالة جديدة
SpaceCreated spaceId، workspaceId تُنشأ مساحة
SpaceDeleted spaceId، workspaceId تُحذف مساحة
SpaceProvisioningChanged workspaceId، spaceId، status، step? تدخل مساحة العمل التابعة للمساحة في التجهيز، أو تبلغ خطوة (استنساخ مستودع، أو إخراج طلب سحب، أو إعداد وكيل)، أو تنقلب إلى جاهز أو فاشل. يروي جسر الدردشة ذلك على بطاقة مهمته
الحدث الحمولة متى يُطلَق
TicketCreated ticketId، workspaceId تُنشأ تذكرة
TicketAssigned ticketId، ticketTitle، ticketBody?، ticketUrl?، assignedAgentId?، assigneeType، assignedTeamId?، workspaceId تُسنَد التذكرة إلى Principal أو إلى فريق
TicketCompleted ticketId ينتهي العمل (نهائي)
TicketFailed ticketId، errorMessage يفشل الوكيل (نهائي)
TicketCancelled ticketId تُلغى التذكرة (نهائي)
TicketStatusChanged ticketId، workspaceId، from، to أي تغيّر في الحالة
TicketReassigned ticketId، workspaceId، fromAgentId?، toAgentId? تُعاد إسناد التذكرة
TicketDetailsUpdated ticketId، workspaceId يتغيّر العنوان أو الوصف أو الأولوية

مجرى دورة حياة المهمة الموحّد: تشغيل وكيل مُرسَل واحد، مفتاحه معرّف سجل التشغيل. يحمل كل حدث taskId، وseq رتيبًا لكل مهمة، وworkspaceId?، وagentId?، وphase، ولا تسرد الصفوف أدناه إلا الحقول الإضافية.

الحدث الحمولة متى يُطلَق
TaskDispatched — تُسلَّم المهمة إلى خلفية للتنفيذ
TaskRunning — بدأت المهمة إنتاج مخرج
TaskWaitingLocalDirectory lockedPath، holderTaskId? تُوقَف المهمة. تملك مهمة أخرى قفل المسار على القرص الذي تحتاجه
TaskProgress note? نقطة تفتيش لتقدّم في منتصف التشغيل
TaskMessage messageType، content رسالة متدفقة (text/thinking/tool_use/tool_result/error)، وتُبلَّغ تحت طور progress
TaskCompleted summary? انتهت المهمة بنجاح
TaskFailed errorMessage انتهت المهمة بخطأ
TaskCancelled — أُلغيت المهمة قبل الاكتمال

يحمل تعداد TaskPhase أيضًا عضو queued، لكن لا شيء ينشر حدث انتظار، فلا يوجد صنف TaskQueued. أول إطار يمكن ملاحظته لمهمة هو TaskDispatched.

الحدث الحمولة متى يُطلَق
PipelineRunCompleted workspaceId، pipelineRunId، templateId ينتهي التشغيل
PipelineRunCancelled workspaceId، pipelineRunId، templateId يُلغى التشغيل (من المستخدم أو من النظام). توقّف متعمّد، لا خطأ
PipelineRunFailed workspaceId، pipelineRunId، templateId، errorMessage يفشل التشغيل

لا تُنشَر إلا الانتقالات النهائية. لا يوجد PipelineRunStarted ولا حدث لكل خطوة: يصل تقدّم الخطوة إلى العملاء عبر صفوف التشغيل نفسه ومجرى دورة حياة المهمة للوكيل الذي أرسلته، لا عبر الناقل.

الحدث الحمولة متى يُطلَق
ActivityLogged id، actorType، actorId?، action، entityType، entityId?، details?، workspaceId?، runId? يُنشأ بند في سجل النشاط
BudgetThresholdCrossed scopeType، scopeId، spentCents، budgetCents، isHardStop يتجاوز الإنفاق العتبة
الحدث الحمولة متى يُطلَق
WorkspaceMemberAdded workspaceId، userId، role ينضم مستخدم إلى مساحة عمل (استرداد دعوة أو إضافة من مسؤول)
WorkspaceMemberRemoved workspaceId، userId يُزال عضو. يجب أن تعيد الجلسات الحيّة لذلك المستخدم، المحصورة في مساحة العمل، التحقق من الوصول فورًا
WorkspaceMemberRoleChanged workspaceId، userId، role يتغيّر دور عضو

العضوية هي سطح الهوية كله على الناقل. يحدث إنشاء المستخدم وإلغاء الجهاز، لكنهما لا يُنشران كأحداث نطاق. يُفرَض الإلغاء مباشرة على الجلسات الحيّة بدل توجيهه عبر الناقل.

الحدث الحمولة متى يُطلَق
CalendarAuthExpired workspaceId، accountEmail يصير رمز تحديث OAuth لحساب متصل غير صالح بشكل دائم (يُنشَر مرة واحدة لكل حادثة انقطاع)
MeetingStartingSoon workspaceId، eventId، title، startTime، meetingUrl? يوشك حدث تقويم أن يبدأ ضمن نافذة الاستباق المُعدّة
MeetingRecordingStopped workspaceId، meetingId، title، userNotes، transcript، summaryInstructions? ينتهي تسجيل اجتماع ويُطلِق خط الأنابيب المضمّن meeting_summary
الحدث الحمولة متى يُطلَق
RigClosedEvent workspaceId، rigId، reason زالت منصة، ومعها سبب إغلاقها. لا يتصرف المستهلكون إلا عند backendFailure. كل سبب آخر مطلوب أو مصحوب بـ RigReaped
RigControlChanged workspaceId، rigId، controller? تولّى إنسان التحكم الحصري بمنصة أو أعادها (controller يساوي null عند التحرير. لا يسجّل الحدث من أفلت التحكم)
RigReaped workspaceId، rigId، reason، agentId? استرد النظام آلة: خمول، أو TTL، أو طرد بسبب ضغط الذاكرة (يُبلَّغ كـ idleTimeout)، مع الوكيل الدافع

فتح منصة ليس حدثًا. يكتمل الإقلاع وينقلب صف المنصة إلى جاهز، ولا يُنشَر شيء، فلا يوجد RigOpened للاشتراك فيه.

نطاقات فرعية بلا أحداث أصلًا

قسم بعنوان “نطاقات فرعية بلا أحداث أصلًا”

عدة أنظمة فرعية تبدو من الخارج مدفوعة بالأحداث، وهي ليست كذلك. تُدرَج هنا لأن غيابها قرار تصميم يجدر معرفته قبل البحث عن خطاف:

النطاق الفرعي كيف تتحرك الحالة بدل ذلك
الذاكرة record_memory_fact وأشباهها تكتب وتعيد، والاسترجاع يقرأ. لا يُنشَر شيء عند حقيقة أو تعارض
التنسيق الاقتراح وموافقته وتشغيل خط الأنابيب المولَّد صفوف واستدعاءات RPC
مستندات الخطط submit_plan يكتب إصدارًا، والموافقة تجسّد تنسيقًا. لا يُعلَن أي منهما
المخرجات publish_artifact / revise_artifact يكتبان الإصدارات مباشرة
الموافقات يُعالَج التصعيد داخل خدمة سير عمل الموافقة
مزامنة التذاكر يشترك منسّق المزوّد في أحداث التذاكر أعلاه، وتُطبَّق ويب هوك الواردة مباشرة
تحديث التقويم تُدرج المزامنة الأحداث أو تحدّثها، ويعيد العميل قراءتها، ولا يوجد بث للتحديث
دمج أشجار العمل يُسجَّل في worktree_merge_log ويُقرأ من هناك

يُبنى كل مشترك أدناه داخل runCcServer (أو خدمة يبنيها). لا يوجد مشترك على جانب العميل.

المشترك الأحداث التي يستهلكها
WorkspaceSeeder WorkspaceCreated
بذر حزمة التقييم الابتدائية (مضمّن) WorkspaceCreated
تجهيز مساحة الدردشة (مضمّن) SpaceCreated
PipelineTriggerDispatcher كل DomainEvent، ويصفّي كل مشغّل مفعّل حسب نوعه
SubPipelineResumeListener PipelineRunCompleted، PipelineRunFailed
PipelineCostRollupListener AgentRunCompleted
BudgetEvaluationListener AgentRunCompleted
MeetingSummaryReconciler PipelineRunCompleted، PipelineRunFailed، PipelineRunCancelled (تشغيلات meeting_summary فقط)
PipelineStepResumeListener AgentRunCompleted
AgentRunTaskCompleter AgentRunCompleted
GoalSupervisor AgentRunCompleted
CheckerDispatchListener AgentRunCompleted
TeamRoutingService AgentRunCompleted، TicketAssigned
OrchestrationRunListener PipelineRunCancelled، PipelineRunFailed
MultiVendorTicketSyncCoordinator TicketCreated، TicketAssigned، TicketReassigned، TicketStatusChanged، TicketDetailsUpdated
WorktreeGcListener TicketCompleted، TicketCancelled، SpaceDeleted، PrMerged، PullRequestStatusChanged
ChatBridgeService MessageReceived، SpaceProvisioningChanged
ActivityLogPersister ActivityLogged
RigEventListener RigControlChanged، RigReaped، RigClosedEvent. يحقن إشعارًا بلغة واضحة في مسار توجيه الوكيل الدافع
StaleReviewWatcher PrHeadChanged. ينشر ReviewBecameStale فقط حين توجد مراجعة منتهية للإيداع المستبدَل
GitHubPrConversationBridge AgentRunCompleted. ردود صادرة في محادثة طلب السحب
NotificationFeedRecorder أحداث صنف الإشعارات الاثنان والعشرون أدناه
RemoteEventForwarder تلك الاثنان والعشرون إضافة إلى TicketReassigned وكل TaskLifecycleEvent. أحداث العضوية الثلاثة تُبطل فقط ذاكرة عضويته المؤقتة لكل مساحة عمل، ولا تُمرَّر كإطارات
LocalRpcServer / RemoteRelayHost WorkspaceMemberRemoved. يُسقط اشتراكات مساحات العمل المرتبطة بذلك المستخدم، ويبقى المقبس مفتوحًا

TicketAssigned إشارة تدقيق وإشعار، ومشغّل لخط أنابيب. الإسناد إلى وكيل يسجّل الملكية ولا يبدأ تشغيلًا، فلا يوجد موزّع تذاكر. الإسناد إلى فريق (عند تعيين assignedTeamId) هو الاستثناء: يرسل TeamRoutingService قائد الفريق.

TicketRemoteSyncHandler مُعلَن، لكنه لا يُبنى في شفرة الإنتاج، فلا يشترك في شيء اليوم. لا يُبنى NotificationEventMapper على جانب العميل إلا في اختباره، وهو بقية المسار داخل العملية من قبل فصل العميل عن الخادم. الإشعارات المنبثقة الحيّة تأتي من إطارات السلك أدناه.

على الخادم يحوّل NotificationFeedRecorder وRemoteEventForwarder هذه الأحداث إلى إطارات سلك من النمط notifications/* (notification_wire.dart). على العميل يحوّل RpcNotificationMapper ثم mapNotificationFrame الإطار إلى AppNotification.

هناك سبع عشرة فئة إشعار بالضبط. تُقابَل عدة أحداث بأكثر من أسلوب سلك، لأن الإطار يحمل الحافة (الفشل مقابل التعافي) بينما تحمل الفئة السؤال («ماذا يفعل CI؟»).

الفئة حدث المصدر أسلوب السلك
newMessage MessageReceived notifications/message_received (يشير إليك)
agentRunCompleted MessageReceived notifications/message_received (is_agent_message، دون إشارة إليك)
agentAwaitingInput AgentAwaitingInput notifications/agent_awaiting_input
ticketAssigned TicketAssigned notifications/ticket_assigned
ticketStatusChanged TicketStatusChanged notifications/ticket_status_changed
pullRequestPublished PullRequestPublished notifications/pr_published
prMerged PrMerged notifications/pr_merged
prMerged ExternalPrMerged notifications/external_pr_merged
prMentioned PrMentioned notifications/pr_mentioned
prMentioned PrCommentMentioned notifications/pr_comment_mentioned
reviewRequested PrReviewRequested notifications/pr_review_requested
reviewStale ReviewBecameStale notifications/review_stale
prMergeReadiness PrMergeReadinessChanged notifications/pr_ready_to_merge / pr_merge_blocked
prReviewDecision PrReviewDecisionChanged notifications/pr_approved / pr_changes_requested / pr_review_dismissed
prChecksStatus PrChecksStatusChanged notifications/pr_checks_failed / pr_checks_recovered
prThreadActivity PrThreadReplied notifications/pr_thread_replied
prThreadActivity PrThreadResolved notifications/pr_thread_resolved
meetingStartsSoon MeetingStartingSoon notifications/meeting_starting_soon
calendarAuthExpired CalendarAuthExpired notifications/calendar_auth_expired
rigStatusChanged RigControlChanged notifications/rig_control_changed
rigStatusChanged RigReaped notifications/rig_reaped
rigStatusChanged RigClosedEvent notifications/rig_closed

لا يُعاد إطار تولّي المنصة إلى من أخذ التحكم، ويُمرَّر التحرير بلا تصفية (لا يسجّل الحدث من أفلت التحكم)، ولا ينتج إطار rig_closed إلا إغلاق بسبب backendFailure. الأسباب الأخرى إما مطلوبة، أو يغطيها إطار الاسترداد أصلًا.

ينشر AgentAwaitingInputPublisher الحدث AgentAwaitingInput، فهو يراقب سجلَّي الموافقات وحظر بيانات الاعتماد بحثًا عن إدخالات جديدة، ويُبلغه AgentQuestionService بكل سؤال ask_user. الانتظار الواحد حدث واحد، ولا يُنشَر شيء عند انتهاء الانتظار.

تحمل فئات طلب السحب المؤلَّف الخمس forUserId، فتصل إلى المؤلف لا إلى كل من في مساحة العمل.

يُمرِّر RemoteEventForwarder أيضًا TicketReassigned بصورة notifications/ticket_reassigned، وكل TaskLifecycleEvent بصورة notifications/task_<phase>. لا يُقابَل أي منهما بفئة إشعار: يقودان الواجهة الحيّة، لا مركز الإشعارات. لا تُمرَّر أحداث العضوية كإطارات: تُبطل ذاكرة المُمرِّر المؤقتة، وتُسقط مضيفات الجلسة اشتراكات مساحة العمل الخاصة بالعضو المُزال.