Μετάβαση στο περιεχόμενο

Γεγονότα τομέα

Ο 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? Μια δεξιότητα εγκαθίσταται ή ενημερώνεται, φέροντας το πόρισμα σάρωσης της αλυσίδας εφοδιασμού της

Το πρώτο μπλοκ είναι ο κύκλος ζωής του ίδιου του PR. Το δεύτερο είναι η παρακολούθηση PR που συντάξατε: σήματα για ένα PR που ανοίξατε εσείς, καθένα από τα οποία φέρει forUserId, ώστε ο περιοδικός έλεγχος να τα δρομολογεί στο πρόσωπο που αφορούν αντί να τα εκπέμπει σε όλους.

Γεγονός Φορτίο Ενεργοποιείται όταν
PullRequestPublished prId, workspaceId, repoOwner, repoName Ο πράκτορας ανοίγει ένα PR
PullRequestStatusChanged status, workspaceId, prId?, repoFullName?, prNumber? PR συγχωνεύτηκε/έκλεισε/άνοιξε/ξανάνοιξε/εγκρίθηκε
PrMerged prId, workspaceId, agentId Το PR συγχωνεύεται — ένα στενό σήμα μόνο για συγχώνευση, που διατηρείται για αναλυτικά στοιχεία/ειδοποιήσεις
PrReviewRequested workspaceId, repoOwner, repoName, prNumber, prTitle Το GitHub ζητά την ανασκόπηση του χρήστη του διακομιστή (περιοδικός έλεγχος ειδοποιήσεων, review_requested)
PrMentioned workspaceId, repoOwner, repoName, prNumber, prTitle Ο χρήστης του διακομιστή αναφέρεται σε ένα PR (περιοδικός έλεγχος ειδοποιήσεων, mention)
ExternalPrMerged workspaceId, repoOwner, repoName, prNumber, prTitle, mergedByLogin? Ένα εξωτερικά παρακολουθούμενο PR (χωρίς πράκτορα) συγχωνεύτηκε, εντοπισμένο από τον περιοδικό έλεγχο ειδοποιήσεων του GitHub· αντιστοιχίζεται στην κατηγορία ειδοποίησης prMerged
ExternalPrDetected repoOwner, repoName, prNumber, prTitle, author, workspaceId? PR χωρίς πράκτορα που βρέθηκε μέσω περιοδικού ελέγχου — μόνο για pipeline (τροφοδοτεί το external_pr_welcome), δεν εγείρει ειδοποίηση
PrHeadChanged repoOwner, repoName, prNumber, prTitle, previousHeadSha, headSha, workspaceId Το head SHA του PR μετακινήθηκε — ο συντάκτης έκανε push
ReviewBecameStale workspaceId, spaceId, repoOwner, repoName, prNumber, prTitle, reviewedHeadSha, headSha Μια ολοκληρωμένη ανασκόπηση με AI δεν περιγράφει πλέον το PR που ανασκόπησε. Ενεργοποιείται μόνο όταν υπάρχει ανασκόπηση για την αντικατασταθείσα υποβολή, ώστε να παραμένει σήμα και όχι ειδοποίηση σε κάθε push

Και τα έξι φέρουν workspaceId, repoOwner, repoName, prNumber, prTitle και ένα προαιρετικό forUserId.

Γεγονός Πρόσθετο φορτίο Ενεργοποιείται όταν
PrMergeReadinessChanged ready, reason Ένα PR που συντάξατε έγινε συγχωνεύσιμο ή έπαψε να είναι
PrReviewDecisionChanged decision, reviewersRemaining, approverLogin? Κάποιος ενέκρινε, ζήτησε αλλαγές ή είδε την έγκρισή του να ακυρώνεται
PrChecksStatusChanged failing, failingCheckName?, failingCheckUrl? Το CI έγινε κόκκινο ή ανέκαμψε
PrCommentMentioned commentId, authorLogin, bodyPreview, isReviewComment, threadId?, path?, line? Κάποιος σας ανέφερε σε σχόλιο PR ή σε σχόλιο ανασκόπησης
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? Ο χώρος εργασίας του χώρου εισέρχεται σε παροχή, φτάνει σε ένα βήμα (κλωνοποίηση αποθετηρίου, checkout PR, ρύθμιση πράκτορα) ή μεταπίπτει σε έτοιμο/αποτυχημένο — η γέφυρα συνομιλίας το αφηγείται στην κάρτα εργασίας της
Γεγονός Φορτίο Ενεργοποιείται όταν
TicketCreated ticketId, workspaceId Δημιουργείται εισιτήριο
TicketAssigned ticketId, ticketTitle, ticketBody?, ticketUrl?, assignedAgentId?, assigneeType, assignedTeamId?, workspaceId Το εισιτήριο ανατίθεται σε υποκείμενο ή ομάδα
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 — Η εργασία παραδίδεται σε ένα backend για εκτέλεση
TaskRunning — Η εργασία άρχισε να παράγει έξοδο
TaskWaitingLocalDirectory lockedPath, holderTaskId? Η εργασία σταθμεύει — μια άλλη εργασία κατέχει το κλείδωμα διαδρομής στον δίσκο που της χρειάζεται
TaskProgress note? Σημείο ελέγχου προόδου στα μισά της εκτέλεσης
TaskMessage messageType, content Μήνυμα σε ροή (text/thinking/tool_use/tool_result/error)· αναφέρεται στη φάση progress
TaskCompleted summary? Η εργασία ολοκληρώθηκε με επιτυχία
TaskFailed errorMessage Η εργασία ολοκληρώθηκε με σφάλμα
TaskCancelled — Η εργασία ακυρώθηκε πριν ολοκληρωθεί

Το enum 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 refresh token ενός συνδεδεμένου λογαριασμού είναι μόνιμα άκυρο (δημοσιεύεται μία φορά ανά επεισόδιο αποσύνδεσης)
MeetingStartingSoon workspaceId, eventId, title, startTime, meetingUrl? Ένα γεγονός ημερολογίου ξεκινά εντός του διαμορφωμένου χρονικού περιθωρίου
MeetingRecordingStopped workspaceId, meetingId, title, userNotes, transcript, summaryInstructions? Μια καταγραφή σύσκεψης ολοκληρώνεται και ενεργοποιεί το ενσωματωμένο pipeline 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 και τα συναφή γράφουν και επιστρέφουν· η ανάκληση διαβάζει. Τίποτα δεν δημοσιεύει όταν δημιουργείται ένα γεγονός ή μια σύγκρουση
Ενορχήστρωση Η πρόταση, η έγκρισή της και η παραγόμενη εκτέλεση pipeline είναι γραμμές και κλήσεις RPC
Έγγραφα σχεδίου Το submit_plan γράφει μια αναθεώρηση· η έγκριση υλοποιεί μια ενορχήστρωση. Κανένα από τα δύο δεν ανακοινώνεται
Τεχνουργήματα Τα publish_artifact / revise_artifact γράφουν αναθεωρήσεις απευθείας
Εγκρίσεις Η κλιμάκωση χειρίζεται μέσα στην υπηρεσία ροής εγκρίσεων
Συγχρονισμός εισιτηρίων Ο συντονιστής προμηθευτών εγγράφεται στα παραπάνω γεγονότα εισιτηρίων· τα εισερχόμενα webhooks εφαρμόζονται απευθείας
Ανανέωση ημερολογίου Ένας συγχρονισμός εισάγει ή ενημερώνει γεγονότα και ο πελάτης ξαναδιαβάζει· δεν υπάρχει εκπομπή ανανέωσης
Συγχωνεύσεις worktree Καταγράφονται στο 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 — εξερχόμενες απαντήσεις συνομιλίας PR
NotificationFeedRecorder Τα είκοσι δύο γεγονότα κλάσης ειδοποιήσεων παρακάτω
RemoteEventForwarder Αυτά τα είκοσι δύο συν το TicketReassigned και κάθε TaskLifecycleEvent. Τα τρία γεγονότα ιδιότητας μέλους ακυρώνουν μόνο την προσωρινή μνήμη ιδιότητας μέλους ανά χώρο εργασίας· δεν προωθούνται ως πλαίσια
LocalRpcServer / RemoteRelayHost WorkspaceMemberRemoved — απορρίπτει τις συνδεδεμένες συνδρομές χώρου εργασίας αυτού του χρήστη· η υποδοχή παραμένει ανοιχτή

Το TicketAssigned είναι σήμα ελέγχου και ειδοποίησης και ενεργοποιητής pipeline. Η ανάθεση σε έναν πράκτορα καταγράφει την κυριότητα και δεν ξεκινά καμία εκτέλεση — δεν υπάρχει αποστολέας εισιτηρίων. Η ανάθεση σε ομάδα (όταν έχει οριστεί το 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

Το πλαίσιο ανάληψης σταθμού δεν παραδίδεται πίσω σε όποιον πήρε το τιμόνι, μια απελευθέρωση είναι χωρίς φίλτρο (το γεγονός δεν καταγράφει ποιος άφησε) και μόνο ένα κλείσιμο backendFailure παράγει πλαίσιο rig_closed — οι άλλοι λόγοι είτε είναι ζητημένοι είτε καλύπτονται ήδη από το πλαίσιο περισυλλογής.

Το AgentAwaitingInput δημοσιεύεται από το AgentAwaitingInputPublisher, το οποίο παρακολουθεί τα μητρώα εγκρίσεων και αποκλεισμένων διαπιστευτηρίων για νέες καταχωρίσεις και ενημερώνεται για κάθε ερώτηση ask_user από το AgentQuestionService. Μία αναμονή είναι ένα γεγονός· όταν η αναμονή τελειώνει, δεν δημοσιεύεται τίποτα.

Οι πέντε κατηγορίες PR που συντάξατε φέρουν forUserId, οπότε φτάνουν στον συντάκτη και όχι σε όλους στον χώρο εργασίας.

Ο RemoteEventForwarder προωθεί επιπλέον το TicketReassigned ως notifications/ticket_reassigned και κάθε TaskLifecycleEvent ως notifications/task_<phase>. Κανένα από τα δύο δεν αντιστοιχίζεται σε κατηγορία ειδοποίησης — τροφοδοτούν ζωντανή διεπαφή χρήστη, όχι το κέντρο ειδοποιήσεων. Τα γεγονότα ιδιότητας μέλους δεν προωθούνται ως πλαίσια: ακυρώνουν την προσωρινή μνήμη του προωθητή και οι οικοδεσπότες συνεδριών απορρίπτουν τις συνδρομές χώρου εργασίας του μέλους που αφαιρέθηκε.