@generacy-ai/generacy 0.0.0-preview-20260304013206
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +191 -0
- package/README.md +207 -0
- package/bin/generacy.js +11 -0
- package/dist/agency/index.d.ts +68 -0
- package/dist/agency/index.d.ts.map +1 -0
- package/dist/agency/index.js +28 -0
- package/dist/agency/index.js.map +1 -0
- package/dist/agency/network.d.ts +41 -0
- package/dist/agency/network.d.ts.map +1 -0
- package/dist/agency/network.js +133 -0
- package/dist/agency/network.js.map +1 -0
- package/dist/agency/subprocess.d.ts +58 -0
- package/dist/agency/subprocess.d.ts.map +1 -0
- package/dist/agency/subprocess.js +216 -0
- package/dist/agency/subprocess.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +10 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +216 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.js +51 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.js.map +1 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.js +68 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.js.map +1 -0
- package/dist/cli/commands/doctor/checks/config.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/config.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/config.js +81 -0
- package/dist/cli/commands/doctor/checks/config.js.map +1 -0
- package/dist/cli/commands/doctor/checks/devcontainer.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/devcontainer.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/devcontainer.js +58 -0
- package/dist/cli/commands/doctor/checks/devcontainer.js.map +1 -0
- package/dist/cli/commands/doctor/checks/docker.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/docker.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/docker.js +71 -0
- package/dist/cli/commands/doctor/checks/docker.js.map +1 -0
- package/dist/cli/commands/doctor/checks/env-file.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/env-file.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/env-file.js +56 -0
- package/dist/cli/commands/doctor/checks/env-file.js.map +1 -0
- package/dist/cli/commands/doctor/checks/github-token.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/github-token.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/github-token.js +99 -0
- package/dist/cli/commands/doctor/checks/github-token.js.map +1 -0
- package/dist/cli/commands/doctor/checks/npm-packages.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/npm-packages.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/npm-packages.js +117 -0
- package/dist/cli/commands/doctor/checks/npm-packages.js.map +1 -0
- package/dist/cli/commands/doctor/formatter.d.ts +27 -0
- package/dist/cli/commands/doctor/formatter.d.ts.map +1 -0
- package/dist/cli/commands/doctor/formatter.js +162 -0
- package/dist/cli/commands/doctor/formatter.js.map +1 -0
- package/dist/cli/commands/doctor/index.d.ts +5 -0
- package/dist/cli/commands/doctor/index.d.ts.map +1 -0
- package/dist/cli/commands/doctor/index.js +8 -0
- package/dist/cli/commands/doctor/index.js.map +1 -0
- package/dist/cli/commands/doctor/registry.d.ts +48 -0
- package/dist/cli/commands/doctor/registry.d.ts.map +1 -0
- package/dist/cli/commands/doctor/registry.js +166 -0
- package/dist/cli/commands/doctor/registry.js.map +1 -0
- package/dist/cli/commands/doctor/runner.d.ts +14 -0
- package/dist/cli/commands/doctor/runner.d.ts.map +1 -0
- package/dist/cli/commands/doctor/runner.js +257 -0
- package/dist/cli/commands/doctor/runner.js.map +1 -0
- package/dist/cli/commands/doctor/types.d.ts +87 -0
- package/dist/cli/commands/doctor/types.d.ts.map +1 -0
- package/dist/cli/commands/doctor/types.js +2 -0
- package/dist/cli/commands/doctor/types.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +12 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +97 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init/conflicts.d.ts +36 -0
- package/dist/cli/commands/init/conflicts.d.ts.map +1 -0
- package/dist/cli/commands/init/conflicts.js +165 -0
- package/dist/cli/commands/init/conflicts.js.map +1 -0
- package/dist/cli/commands/init/github.d.ts +32 -0
- package/dist/cli/commands/init/github.d.ts.map +1 -0
- package/dist/cli/commands/init/github.js +161 -0
- package/dist/cli/commands/init/github.js.map +1 -0
- package/dist/cli/commands/init/index.d.ts +21 -0
- package/dist/cli/commands/init/index.d.ts.map +1 -0
- package/dist/cli/commands/init/index.js +175 -0
- package/dist/cli/commands/init/index.js.map +1 -0
- package/dist/cli/commands/init/prompts.d.ts +15 -0
- package/dist/cli/commands/init/prompts.d.ts.map +1 -0
- package/dist/cli/commands/init/prompts.js +281 -0
- package/dist/cli/commands/init/prompts.js.map +1 -0
- package/dist/cli/commands/init/repo-utils.d.ts +32 -0
- package/dist/cli/commands/init/repo-utils.d.ts.map +1 -0
- package/dist/cli/commands/init/repo-utils.js +112 -0
- package/dist/cli/commands/init/repo-utils.js.map +1 -0
- package/dist/cli/commands/init/resolver.d.ts +20 -0
- package/dist/cli/commands/init/resolver.d.ts.map +1 -0
- package/dist/cli/commands/init/resolver.js +273 -0
- package/dist/cli/commands/init/resolver.js.map +1 -0
- package/dist/cli/commands/init/summary.d.ts +21 -0
- package/dist/cli/commands/init/summary.d.ts.map +1 -0
- package/dist/cli/commands/init/summary.js +100 -0
- package/dist/cli/commands/init/summary.js.map +1 -0
- package/dist/cli/commands/init/types.d.ts +53 -0
- package/dist/cli/commands/init/types.d.ts.map +1 -0
- package/dist/cli/commands/init/types.js +2 -0
- package/dist/cli/commands/init/types.js.map +1 -0
- package/dist/cli/commands/init/writer.d.ts +22 -0
- package/dist/cli/commands/init/writer.d.ts.map +1 -0
- package/dist/cli/commands/init/writer.js +96 -0
- package/dist/cli/commands/init/writer.js.map +1 -0
- package/dist/cli/commands/orchestrator.d.ts +11 -0
- package/dist/cli/commands/orchestrator.d.ts.map +1 -0
- package/dist/cli/commands/orchestrator.js +291 -0
- package/dist/cli/commands/orchestrator.js.map +1 -0
- package/dist/cli/commands/run.d.ts +10 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +167 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/setup/auth.d.ts +11 -0
- package/dist/cli/commands/setup/auth.d.ts.map +1 -0
- package/dist/cli/commands/setup/auth.js +108 -0
- package/dist/cli/commands/setup/auth.js.map +1 -0
- package/dist/cli/commands/setup/build.d.ts +11 -0
- package/dist/cli/commands/setup/build.d.ts.map +1 -0
- package/dist/cli/commands/setup/build.js +212 -0
- package/dist/cli/commands/setup/build.js.map +1 -0
- package/dist/cli/commands/setup/services.d.ts +11 -0
- package/dist/cli/commands/setup/services.d.ts.map +1 -0
- package/dist/cli/commands/setup/services.js +294 -0
- package/dist/cli/commands/setup/services.js.map +1 -0
- package/dist/cli/commands/setup/workspace.d.ts +11 -0
- package/dist/cli/commands/setup/workspace.d.ts.map +1 -0
- package/dist/cli/commands/setup/workspace.js +215 -0
- package/dist/cli/commands/setup/workspace.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +7 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +19 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +10 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +164 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/worker.d.ts +10 -0
- package/dist/cli/commands/worker.d.ts.map +1 -0
- package/dist/cli/commands/worker.js +224 -0
- package/dist/cli/commands/worker.js.map +1 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +68 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/config.d.ts +49 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +110 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/exec.d.ts +39 -0
- package/dist/cli/utils/exec.d.ts.map +1 -0
- package/dist/cli/utils/exec.js +68 -0
- package/dist/cli/utils/exec.js.map +1 -0
- package/dist/cli/utils/logger.d.ts +47 -0
- package/dist/cli/utils/logger.d.ts.map +1 -0
- package/dist/cli/utils/logger.js +97 -0
- package/dist/cli/utils/logger.js.map +1 -0
- package/dist/config/index.d.ts +10 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +13 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +104 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +266 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +304 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +160 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/validator.d.ts +60 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +112 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/health/server.d.ts +47 -0
- package/dist/health/server.d.ts.map +1 -0
- package/dist/health/server.js +92 -0
- package/dist/health/server.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/async-event-queue.d.ts +28 -0
- package/dist/orchestrator/async-event-queue.d.ts.map +1 -0
- package/dist/orchestrator/async-event-queue.js +57 -0
- package/dist/orchestrator/async-event-queue.js.map +1 -0
- package/dist/orchestrator/client.d.ts +110 -0
- package/dist/orchestrator/client.d.ts.map +1 -0
- package/dist/orchestrator/client.js +288 -0
- package/dist/orchestrator/client.js.map +1 -0
- package/dist/orchestrator/event-bus.d.ts +195 -0
- package/dist/orchestrator/event-bus.d.ts.map +1 -0
- package/dist/orchestrator/event-bus.js +557 -0
- package/dist/orchestrator/event-bus.js.map +1 -0
- package/dist/orchestrator/heartbeat.d.ts +71 -0
- package/dist/orchestrator/heartbeat.d.ts.map +1 -0
- package/dist/orchestrator/heartbeat.js +116 -0
- package/dist/orchestrator/heartbeat.js.map +1 -0
- package/dist/orchestrator/index.d.ts +25 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +15 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/job-handler.d.ts +109 -0
- package/dist/orchestrator/job-handler.d.ts.map +1 -0
- package/dist/orchestrator/job-handler.js +612 -0
- package/dist/orchestrator/job-handler.js.map +1 -0
- package/dist/orchestrator/job-queue.d.ts +81 -0
- package/dist/orchestrator/job-queue.d.ts.map +1 -0
- package/dist/orchestrator/job-queue.js +206 -0
- package/dist/orchestrator/job-queue.js.map +1 -0
- package/dist/orchestrator/label-monitor-bridge.d.ts +25 -0
- package/dist/orchestrator/label-monitor-bridge.d.ts.map +1 -0
- package/dist/orchestrator/label-monitor-bridge.js +57 -0
- package/dist/orchestrator/label-monitor-bridge.js.map +1 -0
- package/dist/orchestrator/log-buffer.d.ts +74 -0
- package/dist/orchestrator/log-buffer.d.ts.map +1 -0
- package/dist/orchestrator/log-buffer.js +104 -0
- package/dist/orchestrator/log-buffer.js.map +1 -0
- package/dist/orchestrator/redis-job-queue.d.ts +44 -0
- package/dist/orchestrator/redis-job-queue.d.ts.map +1 -0
- package/dist/orchestrator/redis-job-queue.js +300 -0
- package/dist/orchestrator/redis-job-queue.js.map +1 -0
- package/dist/orchestrator/router.d.ts +125 -0
- package/dist/orchestrator/router.d.ts.map +1 -0
- package/dist/orchestrator/router.js +143 -0
- package/dist/orchestrator/router.js.map +1 -0
- package/dist/orchestrator/server.d.ts +62 -0
- package/dist/orchestrator/server.d.ts.map +1 -0
- package/dist/orchestrator/server.js +711 -0
- package/dist/orchestrator/server.js.map +1 -0
- package/dist/orchestrator/types.d.ts +184 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +6 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/orchestrator/worker-registry.d.ts +110 -0
- package/dist/orchestrator/worker-registry.d.ts.map +1 -0
- package/dist/orchestrator/worker-registry.js +191 -0
- package/dist/orchestrator/worker-registry.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A fixed-capacity circular buffer that evicts oldest items when full.
|
|
3
|
+
*
|
|
4
|
+
* Tracks a `baseIndex` representing the total number of items ever evicted,
|
|
5
|
+
* so callers can map external IDs (like monotonic counters) to buffer positions.
|
|
6
|
+
*/
|
|
7
|
+
export class RingBuffer {
|
|
8
|
+
_capacity;
|
|
9
|
+
buffer;
|
|
10
|
+
head = 0;
|
|
11
|
+
_size = 0;
|
|
12
|
+
_baseIndex = 0;
|
|
13
|
+
constructor(capacity = 1000) {
|
|
14
|
+
if (capacity < 1) {
|
|
15
|
+
throw new Error('RingBuffer capacity must be at least 1');
|
|
16
|
+
}
|
|
17
|
+
this._capacity = capacity;
|
|
18
|
+
this.buffer = new Array(capacity);
|
|
19
|
+
}
|
|
20
|
+
/** Number of items currently in the buffer. */
|
|
21
|
+
get size() {
|
|
22
|
+
return this._size;
|
|
23
|
+
}
|
|
24
|
+
/** Maximum number of items the buffer can hold. */
|
|
25
|
+
get capacity() {
|
|
26
|
+
return this._capacity;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The number of items that have been evicted over the buffer's lifetime.
|
|
30
|
+
* An item inserted at logical index N is at buffer position (N - baseIndex).
|
|
31
|
+
*/
|
|
32
|
+
get baseIndex() {
|
|
33
|
+
return this._baseIndex;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Push an item into the buffer. O(1).
|
|
37
|
+
* When the buffer is full the oldest item is evicted.
|
|
38
|
+
*/
|
|
39
|
+
push(item) {
|
|
40
|
+
if (this._size === this._capacity) {
|
|
41
|
+
// Overwrite the oldest slot — the head is already pointing at it
|
|
42
|
+
this.buffer[this.head] = item;
|
|
43
|
+
this.head = (this.head + 1) % this._capacity;
|
|
44
|
+
this._baseIndex++;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const writeIndex = (this.head + this._size) % this._capacity;
|
|
48
|
+
this.buffer[writeIndex] = item;
|
|
49
|
+
this._size++;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Return all buffered items in insertion order.
|
|
54
|
+
*/
|
|
55
|
+
getAll() {
|
|
56
|
+
if (this._size === 0)
|
|
57
|
+
return [];
|
|
58
|
+
const result = [];
|
|
59
|
+
for (let i = 0; i < this._size; i++) {
|
|
60
|
+
const index = (this.head + i) % this._capacity;
|
|
61
|
+
result.push(this.buffer[index]);
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Return all items whose logical index is strictly greater than `startIndex`.
|
|
67
|
+
*
|
|
68
|
+
* Logical index = baseIndex + position-in-current-buffer.
|
|
69
|
+
* The first item currently in the buffer has logical index `baseIndex`,
|
|
70
|
+
* the second has `baseIndex + 1`, etc.
|
|
71
|
+
*
|
|
72
|
+
* If `startIndex` is before the buffer's range (i.e. already evicted),
|
|
73
|
+
* all buffered items are returned.
|
|
74
|
+
*/
|
|
75
|
+
getAfterIndex(startIndex) {
|
|
76
|
+
if (this._size === 0)
|
|
77
|
+
return [];
|
|
78
|
+
// How many items to skip from the start of the current buffer
|
|
79
|
+
const skip = startIndex - this._baseIndex + 1;
|
|
80
|
+
if (skip <= 0) {
|
|
81
|
+
// The requested index is before (or at the start of) our buffer — return everything
|
|
82
|
+
return this.getAll();
|
|
83
|
+
}
|
|
84
|
+
if (skip >= this._size) {
|
|
85
|
+
// The requested index is beyond what we have
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
const result = [];
|
|
89
|
+
for (let i = skip; i < this._size; i++) {
|
|
90
|
+
const index = (this.head + i) % this._capacity;
|
|
91
|
+
result.push(this.buffer[index]);
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Remove all items and reset state.
|
|
97
|
+
*/
|
|
98
|
+
clear() {
|
|
99
|
+
this.buffer.fill(undefined);
|
|
100
|
+
this.head = 0;
|
|
101
|
+
this._size = 0;
|
|
102
|
+
this._baseIndex = 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Format a JobEvent as an SSE text frame.
|
|
107
|
+
*
|
|
108
|
+
* Wire format:
|
|
109
|
+
* ```
|
|
110
|
+
* event: {type}
|
|
111
|
+
* id: {id}
|
|
112
|
+
* data: {json}
|
|
113
|
+
*
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
function formatSSE(event) {
|
|
117
|
+
return `event: ${event.type}\nid: ${event.id}\ndata: ${JSON.stringify(event)}\n\n`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* EventBus handles event buffering (per-job ring buffers) and broadcasting
|
|
121
|
+
* to SSE subscribers. It is the core publish/subscribe component for
|
|
122
|
+
* real-time job event streaming.
|
|
123
|
+
*/
|
|
124
|
+
export class EventBus {
|
|
125
|
+
/** Per-job ring buffers */
|
|
126
|
+
buffers = new Map();
|
|
127
|
+
/** Per-job monotonic ID counters */
|
|
128
|
+
counters = new Map();
|
|
129
|
+
/** Per-job SSE subscriber connections */
|
|
130
|
+
subscribers = new Map();
|
|
131
|
+
/** Global SSE subscriber connections with filters */
|
|
132
|
+
globalSubscribers = new Set();
|
|
133
|
+
/** Grace period cleanup timers for terminal jobs */
|
|
134
|
+
cleanupTimers = new Map();
|
|
135
|
+
bufferSize;
|
|
136
|
+
gracePeriod;
|
|
137
|
+
heartbeatInterval;
|
|
138
|
+
jobQueue;
|
|
139
|
+
logBufferManager;
|
|
140
|
+
logger;
|
|
141
|
+
heartbeatTimer = null;
|
|
142
|
+
constructor(options) {
|
|
143
|
+
this.bufferSize = options.bufferSize ?? 1000;
|
|
144
|
+
this.gracePeriod = options.gracePeriod ?? 300_000;
|
|
145
|
+
this.heartbeatInterval = options.heartbeatInterval ?? 30_000;
|
|
146
|
+
this.jobQueue = options.jobQueue;
|
|
147
|
+
this.logBufferManager = options.logBufferManager;
|
|
148
|
+
this.logger = options.logger;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Publish an event for a job.
|
|
152
|
+
*
|
|
153
|
+
* Assigns a monotonic string ID, buffers the event in the job's ring buffer,
|
|
154
|
+
* and broadcasts to all per-job and matching global subscribers.
|
|
155
|
+
*
|
|
156
|
+
* Global subscribers are filtered by looking up the job's current metadata
|
|
157
|
+
* from the job queue. Filters combine with AND logic:
|
|
158
|
+
* - `tags`: job must have at least one matching tag
|
|
159
|
+
* - `workflow`: job's workflow must match (string comparison)
|
|
160
|
+
* - `status`: job's current status must be in the filter list
|
|
161
|
+
*/
|
|
162
|
+
async publish(jobId, event) {
|
|
163
|
+
// Assign monotonic ID
|
|
164
|
+
const counter = (this.counters.get(jobId) ?? 0) + 1;
|
|
165
|
+
this.counters.set(jobId, counter);
|
|
166
|
+
const fullEvent = { ...event, id: String(counter) };
|
|
167
|
+
// Route log:append events to the dedicated LogBuffer (separate from lifecycle
|
|
168
|
+
// events) to avoid drowning out lifecycle events in the per-job RingBuffer.
|
|
169
|
+
if (event.type === 'log:append' && this.logBufferManager) {
|
|
170
|
+
const data = (event.data ?? {});
|
|
171
|
+
this.logBufferManager.getOrCreate(jobId).append({
|
|
172
|
+
timestamp: event.timestamp,
|
|
173
|
+
stream: data.stream,
|
|
174
|
+
stepName: data.stepName,
|
|
175
|
+
content: data.content,
|
|
176
|
+
taskIndex: data.taskIndex,
|
|
177
|
+
taskTitle: data.taskTitle,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// Store lifecycle events in the per-job ring buffer
|
|
182
|
+
let buffer = this.buffers.get(jobId);
|
|
183
|
+
if (!buffer) {
|
|
184
|
+
buffer = new RingBuffer(this.bufferSize);
|
|
185
|
+
this.buffers.set(jobId, buffer);
|
|
186
|
+
}
|
|
187
|
+
buffer.push(fullEvent);
|
|
188
|
+
}
|
|
189
|
+
// Broadcast to per-job subscribers
|
|
190
|
+
const frame = formatSSE(fullEvent);
|
|
191
|
+
const jobSubs = this.subscribers.get(jobId);
|
|
192
|
+
if (jobSubs) {
|
|
193
|
+
for (const res of jobSubs) {
|
|
194
|
+
try {
|
|
195
|
+
res.write(frame);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// Connection dead — clean it up
|
|
199
|
+
this.removeSubscriber(res);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Broadcast to matching global subscribers
|
|
204
|
+
if (this.globalSubscribers.size > 0) {
|
|
205
|
+
const hasFilters = this.anySubscriberHasFilters();
|
|
206
|
+
const job = hasFilters ? await this.jobQueue.getJob(jobId) : null;
|
|
207
|
+
for (const sub of this.globalSubscribers) {
|
|
208
|
+
if (!this.matchesFilters(sub.filters, job))
|
|
209
|
+
continue;
|
|
210
|
+
try {
|
|
211
|
+
sub.res.write(frame);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
this.globalSubscribers.delete(sub);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return fullEvent;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Subscribe to a single job's event stream.
|
|
222
|
+
*
|
|
223
|
+
* If `lastEventId` is provided, replays buffered events after that ID
|
|
224
|
+
* before switching to live mode. If the ID is not found in the buffer,
|
|
225
|
+
* all buffered events are replayed.
|
|
226
|
+
*
|
|
227
|
+
* Automatically unsubscribes when the response connection closes.
|
|
228
|
+
*/
|
|
229
|
+
subscribe(jobId, res, lastEventId) {
|
|
230
|
+
// Get or create per-job subscriber set
|
|
231
|
+
let jobSubs = this.subscribers.get(jobId);
|
|
232
|
+
if (!jobSubs) {
|
|
233
|
+
jobSubs = new Set();
|
|
234
|
+
this.subscribers.set(jobId, jobSubs);
|
|
235
|
+
}
|
|
236
|
+
jobSubs.add(res);
|
|
237
|
+
// Replay buffered events if requested
|
|
238
|
+
if (lastEventId !== undefined) {
|
|
239
|
+
const buffer = this.buffers.get(jobId);
|
|
240
|
+
if (buffer) {
|
|
241
|
+
const eventIdNum = parseInt(lastEventId, 10);
|
|
242
|
+
let events;
|
|
243
|
+
if (isNaN(eventIdNum)) {
|
|
244
|
+
// Unknown format — replay all
|
|
245
|
+
events = buffer.getAll();
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// Replay events after the given counter value.
|
|
249
|
+
// The counter maps to the logical index: counter - 1 + baseIndex
|
|
250
|
+
// because counter starts at 1 and the first buffered item's logical
|
|
251
|
+
// index is baseIndex. Actually the RingBuffer's getAfterIndex uses
|
|
252
|
+
// logical indices where the first item ever pushed (counter=1) has
|
|
253
|
+
// logical index 0. But after eviction, baseIndex shifts.
|
|
254
|
+
//
|
|
255
|
+
// Counter N was stored at logical index (N - 1).
|
|
256
|
+
// getAfterIndex(N - 1) returns items with logical index > (N - 1),
|
|
257
|
+
// which means counter > N — exactly what we want.
|
|
258
|
+
events = buffer.getAfterIndex(eventIdNum - 1);
|
|
259
|
+
}
|
|
260
|
+
for (const event of events) {
|
|
261
|
+
try {
|
|
262
|
+
res.write(formatSSE(event));
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
this.removeSubscriber(res);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Auto-unsubscribe on connection close
|
|
272
|
+
res.on('close', () => {
|
|
273
|
+
this.removeSubscriber(res);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Subscribe to events from all jobs, optionally filtered.
|
|
278
|
+
*
|
|
279
|
+
* If `lastEventId` is provided (format `{jobId}:{counter}`), replays
|
|
280
|
+
* buffered events after that ID from the specified job's buffer, then
|
|
281
|
+
* replays all buffered events from other jobs' buffers (filtered).
|
|
282
|
+
*
|
|
283
|
+
* Filter matching is applied during replay: only events from jobs that
|
|
284
|
+
* match the subscriber's filters are sent.
|
|
285
|
+
*/
|
|
286
|
+
async subscribeAll(res, filters, lastEventId) {
|
|
287
|
+
const sub = { res, filters };
|
|
288
|
+
this.globalSubscribers.add(sub);
|
|
289
|
+
const hasFilters = (filters.tags !== undefined && filters.tags.length > 0) ||
|
|
290
|
+
filters.workflow !== undefined ||
|
|
291
|
+
(filters.status !== undefined && filters.status.length > 0);
|
|
292
|
+
// Replay from buffers if lastEventId provided (format: {jobId}:{counter})
|
|
293
|
+
if (lastEventId !== undefined) {
|
|
294
|
+
const colonIdx = lastEventId.lastIndexOf(':');
|
|
295
|
+
if (colonIdx > 0) {
|
|
296
|
+
const replayJobId = lastEventId.substring(0, colonIdx);
|
|
297
|
+
const replayCounter = parseInt(lastEventId.substring(colonIdx + 1), 10);
|
|
298
|
+
if (!isNaN(replayCounter)) {
|
|
299
|
+
// Replay events from the specified job after the given counter
|
|
300
|
+
const dead = await this.replayJobBuffer(replayJobId, replayCounter, res, sub, filters, hasFilters);
|
|
301
|
+
if (dead)
|
|
302
|
+
return;
|
|
303
|
+
// Replay all buffered events from other jobs (filtered)
|
|
304
|
+
for (const [jobId, buffer] of this.buffers) {
|
|
305
|
+
if (jobId === replayJobId)
|
|
306
|
+
continue;
|
|
307
|
+
const events = buffer.getAll();
|
|
308
|
+
const dead = await this.replayEventsFiltered(jobId, events, res, sub, filters, hasFilters);
|
|
309
|
+
if (dead)
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Auto-unsubscribe on connection close
|
|
316
|
+
res.on('close', () => {
|
|
317
|
+
this.globalSubscribers.delete(sub);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Remove a response from all subscriber sets (per-job and global).
|
|
322
|
+
*/
|
|
323
|
+
unsubscribe(res) {
|
|
324
|
+
this.removeSubscriber(res);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Schedule cleanup of a job's buffers and subscriber data after the grace period.
|
|
328
|
+
*/
|
|
329
|
+
scheduleCleanup(jobId) {
|
|
330
|
+
// Clear any existing timer for this job
|
|
331
|
+
const existing = this.cleanupTimers.get(jobId);
|
|
332
|
+
if (existing) {
|
|
333
|
+
clearTimeout(existing);
|
|
334
|
+
}
|
|
335
|
+
const timer = setTimeout(() => {
|
|
336
|
+
this.buffers.get(jobId)?.clear();
|
|
337
|
+
this.buffers.delete(jobId);
|
|
338
|
+
this.counters.delete(jobId);
|
|
339
|
+
this.subscribers.delete(jobId);
|
|
340
|
+
this.cleanupTimers.delete(jobId);
|
|
341
|
+
this.logger?.info('Cleaned up event buffer for job', { jobId });
|
|
342
|
+
}, this.gracePeriod);
|
|
343
|
+
this.cleanupTimers.set(jobId, timer);
|
|
344
|
+
// Also schedule cleanup for the log buffer
|
|
345
|
+
this.logBufferManager?.scheduleCleanup(jobId);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Close all per-job SSE connections for a job.
|
|
349
|
+
* Sends `res.end()` to each subscriber and removes them from the set.
|
|
350
|
+
*/
|
|
351
|
+
closeJobSubscribers(jobId) {
|
|
352
|
+
const jobSubs = this.subscribers.get(jobId);
|
|
353
|
+
if (!jobSubs)
|
|
354
|
+
return;
|
|
355
|
+
for (const res of jobSubs) {
|
|
356
|
+
try {
|
|
357
|
+
res.end();
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
// Already closed, ignore
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
jobSubs.clear();
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Return all buffered events for a job (for replay-and-close on terminal jobs).
|
|
367
|
+
*/
|
|
368
|
+
getBufferedEvents(jobId) {
|
|
369
|
+
const buffer = this.buffers.get(jobId);
|
|
370
|
+
return buffer ? buffer.getAll() : [];
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Start the heartbeat interval that sends `: ping\n\n` to all active SSE connections.
|
|
374
|
+
*/
|
|
375
|
+
startHeartbeat() {
|
|
376
|
+
if (this.heartbeatTimer)
|
|
377
|
+
return;
|
|
378
|
+
this.heartbeatTimer = setInterval(() => {
|
|
379
|
+
const ping = ': ping\n\n';
|
|
380
|
+
// Ping per-job subscribers
|
|
381
|
+
for (const [, jobSubs] of this.subscribers) {
|
|
382
|
+
for (const res of jobSubs) {
|
|
383
|
+
try {
|
|
384
|
+
res.write(ping);
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
this.removeSubscriber(res);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
// Ping global subscribers
|
|
392
|
+
for (const sub of this.globalSubscribers) {
|
|
393
|
+
try {
|
|
394
|
+
sub.res.write(ping);
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
this.globalSubscribers.delete(sub);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}, this.heartbeatInterval);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Stop the heartbeat interval.
|
|
404
|
+
*/
|
|
405
|
+
stopHeartbeat() {
|
|
406
|
+
if (this.heartbeatTimer) {
|
|
407
|
+
clearInterval(this.heartbeatTimer);
|
|
408
|
+
this.heartbeatTimer = null;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Clean shutdown: stop heartbeat, clear all timers, close all connections, clear state.
|
|
413
|
+
*/
|
|
414
|
+
destroy() {
|
|
415
|
+
this.stopHeartbeat();
|
|
416
|
+
// Clear all cleanup timers
|
|
417
|
+
for (const timer of this.cleanupTimers.values()) {
|
|
418
|
+
clearTimeout(timer);
|
|
419
|
+
}
|
|
420
|
+
this.cleanupTimers.clear();
|
|
421
|
+
// Close all per-job subscribers
|
|
422
|
+
for (const [, jobSubs] of this.subscribers) {
|
|
423
|
+
for (const res of jobSubs) {
|
|
424
|
+
try {
|
|
425
|
+
res.end();
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
// Already closed
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
this.subscribers.clear();
|
|
433
|
+
// Close all global subscribers
|
|
434
|
+
for (const sub of this.globalSubscribers) {
|
|
435
|
+
try {
|
|
436
|
+
sub.res.end();
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
// Already closed
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
this.globalSubscribers.clear();
|
|
443
|
+
// Clear buffers and counters
|
|
444
|
+
this.buffers.clear();
|
|
445
|
+
this.counters.clear();
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Replay events from a specific job's buffer after a given counter value,
|
|
449
|
+
* applying filter matching. Returns true if the connection died during replay.
|
|
450
|
+
*/
|
|
451
|
+
async replayJobBuffer(jobId, afterCounter, res, sub, filters, hasFilters) {
|
|
452
|
+
const buffer = this.buffers.get(jobId);
|
|
453
|
+
if (!buffer)
|
|
454
|
+
return false;
|
|
455
|
+
const events = buffer.getAfterIndex(afterCounter - 1);
|
|
456
|
+
return this.replayEventsFiltered(jobId, events, res, sub, filters, hasFilters);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Send a list of events to a global subscriber, applying filter matching.
|
|
460
|
+
* Returns true if the connection died during replay (subscriber was removed).
|
|
461
|
+
*/
|
|
462
|
+
async replayEventsFiltered(jobId, events, res, sub, filters, hasFilters) {
|
|
463
|
+
if (events.length === 0)
|
|
464
|
+
return false;
|
|
465
|
+
// Check filters if applicable
|
|
466
|
+
if (hasFilters) {
|
|
467
|
+
const job = await this.jobQueue.getJob(jobId);
|
|
468
|
+
if (!this.matchesFilters(filters, job))
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
for (const event of events) {
|
|
472
|
+
try {
|
|
473
|
+
res.write(formatSSE(event));
|
|
474
|
+
}
|
|
475
|
+
catch {
|
|
476
|
+
this.globalSubscribers.delete(sub);
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Check whether any global subscriber has at least one filter set.
|
|
484
|
+
* Used to skip the async job lookup when no filters are active.
|
|
485
|
+
*/
|
|
486
|
+
anySubscriberHasFilters() {
|
|
487
|
+
for (const sub of this.globalSubscribers) {
|
|
488
|
+
const f = sub.filters;
|
|
489
|
+
if ((f.tags && f.tags.length > 0) ||
|
|
490
|
+
f.workflow !== undefined ||
|
|
491
|
+
(f.status && f.status.length > 0)) {
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Evaluate whether a job matches a subscriber's filters.
|
|
499
|
+
*
|
|
500
|
+
* All specified filters combine with AND logic:
|
|
501
|
+
* - `tags`: job must have at least one matching tag
|
|
502
|
+
* - `workflow`: job's workflow must match (string comparison)
|
|
503
|
+
* - `status`: job's current status must be in the filter list
|
|
504
|
+
*
|
|
505
|
+
* If no filters are set (all fields undefined/empty), the event always matches.
|
|
506
|
+
* If the job is null (not found), events are skipped for subscribers with filters.
|
|
507
|
+
*/
|
|
508
|
+
matchesFilters(filters, job) {
|
|
509
|
+
const hasTagsFilter = filters.tags !== undefined && filters.tags.length > 0;
|
|
510
|
+
const hasWorkflowFilter = filters.workflow !== undefined;
|
|
511
|
+
const hasStatusFilter = filters.status !== undefined && filters.status.length > 0;
|
|
512
|
+
// No filters → always matches
|
|
513
|
+
if (!hasTagsFilter && !hasWorkflowFilter && !hasStatusFilter) {
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
// Filters are set but job not found → no match
|
|
517
|
+
if (!job) {
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
// Tags filter: job must have at least one matching tag
|
|
521
|
+
if (hasTagsFilter) {
|
|
522
|
+
const jobTags = job.tags ?? [];
|
|
523
|
+
const hasMatch = filters.tags.some((tag) => jobTags.includes(tag));
|
|
524
|
+
if (!hasMatch)
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
// Workflow filter: job's workflow must match (string comparison)
|
|
528
|
+
if (hasWorkflowFilter) {
|
|
529
|
+
const jobWorkflow = typeof job.workflow === 'string' ? job.workflow : JSON.stringify(job.workflow);
|
|
530
|
+
if (jobWorkflow !== filters.workflow)
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
// Status filter: job's current status must be in the filter list
|
|
534
|
+
if (hasStatusFilter) {
|
|
535
|
+
if (!filters.status.includes(job.status))
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Internal helper to remove a ServerResponse from all subscriber sets.
|
|
542
|
+
*/
|
|
543
|
+
removeSubscriber(res) {
|
|
544
|
+
// Remove from per-job subscriber sets
|
|
545
|
+
for (const [, jobSubs] of this.subscribers) {
|
|
546
|
+
jobSubs.delete(res);
|
|
547
|
+
}
|
|
548
|
+
// Remove from global subscribers
|
|
549
|
+
for (const sub of this.globalSubscribers) {
|
|
550
|
+
if (sub.res === res) {
|
|
551
|
+
this.globalSubscribers.delete(sub);
|
|
552
|
+
break;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
//# sourceMappingURL=event-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../src/orchestrator/event-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { OrchestratorClient } from './client.js';
|
|
2
|
+
import type { HeartbeatCommand } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Heartbeat manager options
|
|
5
|
+
*/
|
|
6
|
+
export interface HeartbeatManagerOptions {
|
|
7
|
+
/** Orchestrator client */
|
|
8
|
+
client: OrchestratorClient;
|
|
9
|
+
/** Worker ID */
|
|
10
|
+
workerId: string;
|
|
11
|
+
/** Heartbeat interval in milliseconds */
|
|
12
|
+
interval?: number;
|
|
13
|
+
/** Callback for commands received */
|
|
14
|
+
onCommand?: (command: HeartbeatCommand) => void;
|
|
15
|
+
/** Callback for heartbeat errors */
|
|
16
|
+
onError?: (error: Error) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Worker status for heartbeat
|
|
20
|
+
*/
|
|
21
|
+
export type WorkerStatus = 'idle' | 'busy' | 'stopping';
|
|
22
|
+
/**
|
|
23
|
+
* Manages periodic heartbeat to orchestrator
|
|
24
|
+
*/
|
|
25
|
+
export declare class HeartbeatManager {
|
|
26
|
+
private readonly client;
|
|
27
|
+
private readonly workerId;
|
|
28
|
+
private readonly interval;
|
|
29
|
+
private readonly onCommand?;
|
|
30
|
+
private readonly onError?;
|
|
31
|
+
private timer;
|
|
32
|
+
private status;
|
|
33
|
+
private currentJob?;
|
|
34
|
+
private progress?;
|
|
35
|
+
private startTime;
|
|
36
|
+
private lastHeartbeat?;
|
|
37
|
+
constructor(options: HeartbeatManagerOptions);
|
|
38
|
+
/**
|
|
39
|
+
* Start the heartbeat loop
|
|
40
|
+
*/
|
|
41
|
+
start(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Stop the heartbeat loop
|
|
44
|
+
*/
|
|
45
|
+
stop(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Update worker status
|
|
48
|
+
*/
|
|
49
|
+
setStatus(status: WorkerStatus): void;
|
|
50
|
+
/**
|
|
51
|
+
* Set current job information
|
|
52
|
+
*/
|
|
53
|
+
setCurrentJob(jobId: string | undefined, progress?: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Get last successful heartbeat time
|
|
56
|
+
*/
|
|
57
|
+
getLastHeartbeat(): Date | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Get uptime in milliseconds
|
|
60
|
+
*/
|
|
61
|
+
getUptime(): number;
|
|
62
|
+
/**
|
|
63
|
+
* Send a heartbeat to the orchestrator
|
|
64
|
+
*/
|
|
65
|
+
private sendHeartbeat;
|
|
66
|
+
/**
|
|
67
|
+
* Collect system metrics
|
|
68
|
+
*/
|
|
69
|
+
private collectMetrics;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/orchestrator/heartbeat.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,0BAA0B;IAC1B,MAAM,EAAE,kBAAkB,CAAC;IAE3B,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IAEjB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,qCAAqC;IACrC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAEhD,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAExD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAsC;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAyB;IAElD,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAO;gBAEjB,OAAO,EAAE,uBAAuB;IAQ5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAIrC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAKjE;;OAEG;IACH,gBAAgB,IAAI,IAAI,GAAG,SAAS;IAIpC;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;YACW,aAAa;IAyB3B;;OAEG;IACH,OAAO,CAAC,cAAc;CAWvB"}
|