MCPcopy Create free account
hub / github.com/cursor/plugins / AndonPoller

Class AndonPoller

orchestrate/skills/orchestrate/scripts/core/andon.ts:17–155  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

15}
16
17export class AndonPoller {
18 private attentionLogged = false;
19 private cacheAttentionLogged = false;
20 clearedDuringLoop = false;
21
22 constructor(
23 private readonly args: {
24 source?: AndonSource;
25 getState: () => State;
26 saveState: (reason?: string) => void;
27 logAttention: (line: string) => void;
28 pollSource: boolean;
29 cachedState?: {
30 workspace: string;
31 ref: string;
32 path: string;
33 };
34 }
35 ) {}
36
37 async drainEvents(): Promise<void> {
38 if (!this.args.pollSource) {
39 this.syncFromCachedState();
40 return;
41 }
42 if (!this.args.source) return;
43 const state = this.args.getState();
44 const before = JSON.stringify(state.andon ?? null);
45 try {
46 const next = await this.args.source.snapshot();
47 let syncReason: string | undefined;
48 if (next.active) {
49 const { active: _active, ...nextAndon } = next;
50 if (!isAndonActive(state.andon)) {
51 state.andon = {
52 ...nextAndon,
53 reason: truncateAndonBody(nextAndon.reason ?? ""),
54 cleared: false,
55 };
56 syncReason = "andon state changed";
57 this.clearedDuringLoop = false;
58 } else {
59 // Keep state.json fresh so operators can see the root is still polling.
60 const reasonChanged =
61 nextAndon.reason !== undefined &&
62 nextAndon.reason !== state.andon.reason;
63 state.andon = {
64 ...state.andon,
65 reason:
66 nextAndon.reason !== undefined
67 ? truncateAndonBody(nextAndon.reason)
68 : state.andon.reason,
69 lastCheckedAt: nextAndon.lastCheckedAt,
70 };
71 if (reasonChanged) syncReason = "andon state changed";
72 }
73 } else if (state.andon) {
74 if (isAndonActive(state.andon)) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected