@polpo-ai/core 0.1.0
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 +21 -0
- package/dist/adapter.d.ts +61 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +9 -0
- package/dist/adapter.js.map +1 -0
- package/dist/agent-manager.d.ts +36 -0
- package/dist/agent-manager.d.ts.map +1 -0
- package/dist/agent-manager.js +176 -0
- package/dist/agent-manager.js.map +1 -0
- package/dist/approval-manager.d.ts +49 -0
- package/dist/approval-manager.d.ts.map +1 -0
- package/dist/approval-manager.js +325 -0
- package/dist/approval-manager.js.map +1 -0
- package/dist/approval-store.d.ts +19 -0
- package/dist/approval-store.d.ts.map +1 -0
- package/dist/approval-store.js +2 -0
- package/dist/approval-store.js.map +1 -0
- package/dist/checkpoint-store.d.ts +20 -0
- package/dist/checkpoint-store.d.ts.map +1 -0
- package/dist/checkpoint-store.js +2 -0
- package/dist/checkpoint-store.js.map +1 -0
- package/dist/config-store.d.ts +13 -0
- package/dist/config-store.d.ts.map +1 -0
- package/dist/config-store.js +2 -0
- package/dist/config-store.js.map +1 -0
- package/dist/cron.d.ts +29 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +105 -0
- package/dist/cron.js.map +1 -0
- package/dist/delay-store.d.ts +21 -0
- package/dist/delay-store.d.ts.map +1 -0
- package/dist/delay-store.js +2 -0
- package/dist/delay-store.js.map +1 -0
- package/dist/escalation-manager.d.ts +31 -0
- package/dist/escalation-manager.d.ts.map +1 -0
- package/dist/escalation-manager.js +281 -0
- package/dist/escalation-manager.js.map +1 -0
- package/dist/event-bus.d.ts +18 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +2 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/events.d.ts +377 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +9 -0
- package/dist/events.js.map +1 -0
- package/dist/hooks.d.ts +185 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +152 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/log-store.d.ts +31 -0
- package/dist/log-store.d.ts.map +1 -0
- package/dist/log-store.js +6 -0
- package/dist/log-store.js.map +1 -0
- package/dist/memory-store.d.ts +17 -0
- package/dist/memory-store.d.ts.map +1 -0
- package/dist/memory-store.js +2 -0
- package/dist/memory-store.js.map +1 -0
- package/dist/notification-router-port.d.ts +11 -0
- package/dist/notification-router-port.d.ts.map +1 -0
- package/dist/notification-router-port.js +2 -0
- package/dist/notification-router-port.js.map +1 -0
- package/dist/notification-store.d.ts +58 -0
- package/dist/notification-store.d.ts.map +1 -0
- package/dist/notification-store.js +9 -0
- package/dist/notification-store.js.map +1 -0
- package/dist/orchestrator-context.d.ts +87 -0
- package/dist/orchestrator-context.d.ts.map +1 -0
- package/dist/orchestrator-context.js +2 -0
- package/dist/orchestrator-context.js.map +1 -0
- package/dist/peer-store.d.ts +29 -0
- package/dist/peer-store.d.ts.map +1 -0
- package/dist/peer-store.js +6 -0
- package/dist/peer-store.js.map +1 -0
- package/dist/quality-controller.d.ts +46 -0
- package/dist/quality-controller.d.ts.map +1 -0
- package/dist/quality-controller.js +373 -0
- package/dist/quality-controller.js.map +1 -0
- package/dist/run-store.d.ts +31 -0
- package/dist/run-store.d.ts.map +1 -0
- package/dist/run-store.js +2 -0
- package/dist/run-store.js.map +1 -0
- package/dist/scheduler.d.ts +35 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +195 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/schemas.d.ts +104 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +200 -0
- package/dist/schemas.js.map +1 -0
- package/dist/session-store.d.ts +50 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +6 -0
- package/dist/session-store.js.map +1 -0
- package/dist/sla-monitor.d.ts +30 -0
- package/dist/sla-monitor.d.ts.map +1 -0
- package/dist/sla-monitor.js +156 -0
- package/dist/sla-monitor.js.map +1 -0
- package/dist/state-machine.d.ts +8 -0
- package/dist/state-machine.d.ts.map +1 -0
- package/dist/state-machine.js +23 -0
- package/dist/state-machine.js.map +1 -0
- package/dist/task-manager.d.ts +38 -0
- package/dist/task-manager.d.ts.map +1 -0
- package/dist/task-manager.js +308 -0
- package/dist/task-manager.js.map +1 -0
- package/dist/task-store.d.ts +33 -0
- package/dist/task-store.d.ts.map +1 -0
- package/dist/task-store.js +2 -0
- package/dist/task-store.js.map +1 -0
- package/dist/task-watcher.d.ts +38 -0
- package/dist/task-watcher.d.ts.map +1 -0
- package/dist/task-watcher.js +103 -0
- package/dist/task-watcher.js.map +1 -0
- package/dist/types.d.ts +1073 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/package.json +170 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { nanoid } from "nanoid";
|
|
2
|
+
/**
|
|
3
|
+
* Manages approval gates — both automatic (condition-based) and human (blocking).
|
|
4
|
+
*
|
|
5
|
+
* Automatic gates evaluate a condition against the hook payload and either
|
|
6
|
+
* allow or block the operation immediately.
|
|
7
|
+
*
|
|
8
|
+
* Human gates pause the operation (task enters "awaiting_approval"),
|
|
9
|
+
* emit a notification event, and wait for external resolution (API call,
|
|
10
|
+
* TUI action, or timeout).
|
|
11
|
+
*/
|
|
12
|
+
export class ApprovalManager {
|
|
13
|
+
ctx;
|
|
14
|
+
store;
|
|
15
|
+
timers = new Map();
|
|
16
|
+
notificationRouter;
|
|
17
|
+
registeredGateRules = new Set();
|
|
18
|
+
constructor(ctx, store) {
|
|
19
|
+
this.ctx = ctx;
|
|
20
|
+
this.store = store;
|
|
21
|
+
}
|
|
22
|
+
/** Wire the notification router so per-gate notifyChannels work. */
|
|
23
|
+
setNotificationRouter(router) {
|
|
24
|
+
this.notificationRouter = router;
|
|
25
|
+
const gates = this.ctx.config.settings.approvalGates;
|
|
26
|
+
if (gates) {
|
|
27
|
+
for (const gate of gates) {
|
|
28
|
+
this.ensureGateNotificationRules(gate);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Initialize: register hooks for all configured approval gates. */
|
|
33
|
+
async init() {
|
|
34
|
+
const gates = this.ctx.config.settings.approvalGates;
|
|
35
|
+
if (!gates || gates.length === 0)
|
|
36
|
+
return;
|
|
37
|
+
for (const gate of gates) {
|
|
38
|
+
this.registerGate(gate);
|
|
39
|
+
}
|
|
40
|
+
// Resume any pending approval timeouts from previous session
|
|
41
|
+
const pending = await this.store.list("pending");
|
|
42
|
+
for (const req of pending) {
|
|
43
|
+
const gate = gates.find(g => g.id === req.gateId);
|
|
44
|
+
if (gate?.timeoutMs && gate.timeoutMs > 0) {
|
|
45
|
+
const elapsed = Date.now() - new Date(req.requestedAt).getTime();
|
|
46
|
+
const remaining = gate.timeoutMs - elapsed;
|
|
47
|
+
if (remaining <= 0) {
|
|
48
|
+
await this.resolveTimeout(req, gate);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.startTimer(req.id, remaining, gate);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
ensureGateNotificationRules(gate) {
|
|
57
|
+
if (!this.notificationRouter)
|
|
58
|
+
return;
|
|
59
|
+
if (!gate.notifyChannels || gate.notifyChannels.length === 0)
|
|
60
|
+
return;
|
|
61
|
+
if (this.registeredGateRules.has(gate.id))
|
|
62
|
+
return;
|
|
63
|
+
this.registeredGateRules.add(gate.id);
|
|
64
|
+
this.notificationRouter.addRule({
|
|
65
|
+
id: `approval-req-${gate.id}`,
|
|
66
|
+
name: `Approval "${gate.name}" Requested (auto)`,
|
|
67
|
+
events: ["approval:requested"],
|
|
68
|
+
condition: { field: "gateId", op: "==", value: gate.id },
|
|
69
|
+
channels: gate.notifyChannels,
|
|
70
|
+
severity: "warning",
|
|
71
|
+
includeOutcomes: gate.includeOutcomes,
|
|
72
|
+
outcomeFilter: ["media", "file"],
|
|
73
|
+
maxAttachmentSize: 10 * 1024 * 1024,
|
|
74
|
+
});
|
|
75
|
+
this.notificationRouter.addRule({
|
|
76
|
+
id: `approval-res-${gate.id}`,
|
|
77
|
+
name: `Approval "${gate.name}" Resolved (auto)`,
|
|
78
|
+
events: ["approval:resolved"],
|
|
79
|
+
channels: gate.notifyChannels,
|
|
80
|
+
severity: "info",
|
|
81
|
+
});
|
|
82
|
+
this.notificationRouter.addRule({
|
|
83
|
+
id: `approval-timeout-${gate.id}`,
|
|
84
|
+
name: `Approval "${gate.name}" Timed Out (auto)`,
|
|
85
|
+
events: ["approval:timeout"],
|
|
86
|
+
channels: gate.notifyChannels,
|
|
87
|
+
severity: "critical",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
registerGate(gate) {
|
|
91
|
+
const hook = gate.hook;
|
|
92
|
+
this.ensureGateNotificationRules(gate);
|
|
93
|
+
this.ctx.hooks.register({
|
|
94
|
+
hook,
|
|
95
|
+
phase: "before",
|
|
96
|
+
priority: gate.priority ?? 50,
|
|
97
|
+
name: `approval-gate:${gate.name}`,
|
|
98
|
+
handler: (ctx) => {
|
|
99
|
+
if (gate.condition?.expression) {
|
|
100
|
+
const matches = this.evaluateCondition(gate.condition.expression, ctx.data);
|
|
101
|
+
if (!matches)
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (gate.handler === "auto") {
|
|
105
|
+
if (gate.condition?.expression) {
|
|
106
|
+
ctx.cancel(`Auto gate "${gate.name}" condition matched — blocking`);
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const request = this.createRequest(gate, ctx.data);
|
|
111
|
+
ctx.cancel(`Awaiting human approval: ${gate.name} (request: ${request.id})`);
|
|
112
|
+
const taskId = this.extractTaskId(ctx.data);
|
|
113
|
+
if (taskId) {
|
|
114
|
+
// Fire-and-forget async transition
|
|
115
|
+
this.ctx.registry.transition(taskId, "awaiting_approval").catch(() => {
|
|
116
|
+
/* Task may already be in a state that doesn't allow this transition */
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
this.ctx.emitter.emit("approval:requested", {
|
|
120
|
+
requestId: request.id,
|
|
121
|
+
gateId: gate.id,
|
|
122
|
+
gateName: gate.name,
|
|
123
|
+
taskId: request.taskId,
|
|
124
|
+
missionId: request.missionId,
|
|
125
|
+
});
|
|
126
|
+
if (gate.timeoutMs && gate.timeoutMs > 0) {
|
|
127
|
+
this.startTimer(request.id, gate.timeoutMs, gate);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
createRequest(gate, payload) {
|
|
133
|
+
const request = {
|
|
134
|
+
id: nanoid(),
|
|
135
|
+
gateId: gate.id,
|
|
136
|
+
gateName: gate.name,
|
|
137
|
+
taskId: this.extractTaskId(payload),
|
|
138
|
+
missionId: this.extractMissionId(payload),
|
|
139
|
+
status: "pending",
|
|
140
|
+
payload,
|
|
141
|
+
requestedAt: new Date().toISOString(),
|
|
142
|
+
};
|
|
143
|
+
// Fire-and-forget async store write
|
|
144
|
+
this.store.upsert(request).catch(() => { });
|
|
145
|
+
return request;
|
|
146
|
+
}
|
|
147
|
+
async approve(requestId, resolvedBy, note) {
|
|
148
|
+
return this.resolve(requestId, "approved", resolvedBy, note);
|
|
149
|
+
}
|
|
150
|
+
async reject(requestId, feedback, resolvedBy) {
|
|
151
|
+
const request = await this.store.get(requestId);
|
|
152
|
+
if (!request || request.status !== "pending")
|
|
153
|
+
return null;
|
|
154
|
+
if (!request.taskId)
|
|
155
|
+
return null;
|
|
156
|
+
const gate = this.ctx.config.settings.approvalGates?.find(g => g.id === request.gateId);
|
|
157
|
+
const maxRevisions = gate?.maxRevisions ?? 3;
|
|
158
|
+
const task = await this.ctx.registry.getTask(request.taskId);
|
|
159
|
+
if (!task)
|
|
160
|
+
return null;
|
|
161
|
+
const currentCount = task.revisionCount ?? 0;
|
|
162
|
+
if (currentCount >= maxRevisions)
|
|
163
|
+
return null;
|
|
164
|
+
request.status = "rejected";
|
|
165
|
+
request.resolvedAt = new Date().toISOString();
|
|
166
|
+
request.resolvedBy = resolvedBy ?? "user";
|
|
167
|
+
request.note = feedback;
|
|
168
|
+
await this.store.upsert(request);
|
|
169
|
+
this.clearTimer(requestId);
|
|
170
|
+
const newCount = currentCount + 1;
|
|
171
|
+
await this.ctx.registry.updateTask(request.taskId, { revisionCount: newCount });
|
|
172
|
+
const separator = "\n\n---\n";
|
|
173
|
+
const feedbackBlock = `**Rejection #${newCount} feedback:** ${feedback}`;
|
|
174
|
+
const updatedDescription = task.description + separator + feedbackBlock;
|
|
175
|
+
await this.ctx.registry.updateTask(request.taskId, { description: updatedDescription });
|
|
176
|
+
this.ctx.emitter.emit("approval:rejected", {
|
|
177
|
+
requestId,
|
|
178
|
+
taskId: request.taskId,
|
|
179
|
+
feedback,
|
|
180
|
+
rejectionCount: newCount,
|
|
181
|
+
resolvedBy: request.resolvedBy,
|
|
182
|
+
});
|
|
183
|
+
await this.ctx.registry.updateTask(request.taskId, { outcomes: [] });
|
|
184
|
+
try {
|
|
185
|
+
await this.ctx.registry.transition(request.taskId, "pending");
|
|
186
|
+
}
|
|
187
|
+
catch { /* Task may have been modified externally */ }
|
|
188
|
+
return request;
|
|
189
|
+
}
|
|
190
|
+
async canReject(requestId) {
|
|
191
|
+
const request = await this.store.get(requestId);
|
|
192
|
+
if (!request || request.status !== "pending" || !request.taskId) {
|
|
193
|
+
return { allowed: false, rejectionCount: 0, maxRejections: 0 };
|
|
194
|
+
}
|
|
195
|
+
const gate = this.ctx.config.settings.approvalGates?.find(g => g.id === request.gateId);
|
|
196
|
+
const maxRejections = gate?.maxRevisions ?? 3;
|
|
197
|
+
const task = await this.ctx.registry.getTask(request.taskId);
|
|
198
|
+
const currentCount = task?.revisionCount ?? 0;
|
|
199
|
+
return { allowed: currentCount < maxRejections, rejectionCount: currentCount, maxRejections };
|
|
200
|
+
}
|
|
201
|
+
async resolve(requestId, status, resolvedBy, note) {
|
|
202
|
+
const request = await this.store.get(requestId);
|
|
203
|
+
if (!request || request.status !== "pending")
|
|
204
|
+
return null;
|
|
205
|
+
request.status = status;
|
|
206
|
+
request.resolvedAt = new Date().toISOString();
|
|
207
|
+
request.resolvedBy = resolvedBy ?? "user";
|
|
208
|
+
request.note = note;
|
|
209
|
+
await this.store.upsert(request);
|
|
210
|
+
this.clearTimer(requestId);
|
|
211
|
+
this.ctx.emitter.emit("approval:resolved", {
|
|
212
|
+
requestId,
|
|
213
|
+
status,
|
|
214
|
+
resolvedBy: request.resolvedBy,
|
|
215
|
+
});
|
|
216
|
+
if (request.taskId) {
|
|
217
|
+
try {
|
|
218
|
+
if (status === "approved") {
|
|
219
|
+
const gate = this.ctx.config.settings.approvalGates?.find(g => g.id === request.gateId);
|
|
220
|
+
const targetStatus = gate?.hook === "task:complete" ? "done" : "assigned";
|
|
221
|
+
await this.ctx.registry.transition(request.taskId, targetStatus);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
await this.ctx.registry.transition(request.taskId, "failed");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch { /* Task may have been modified externally */ }
|
|
228
|
+
}
|
|
229
|
+
return request;
|
|
230
|
+
}
|
|
231
|
+
async resolveTimeout(request, gate) {
|
|
232
|
+
if (request.status !== "pending")
|
|
233
|
+
return;
|
|
234
|
+
const action = gate.timeoutAction ?? "reject";
|
|
235
|
+
request.status = "timeout";
|
|
236
|
+
request.resolvedAt = new Date().toISOString();
|
|
237
|
+
request.resolvedBy = "timeout";
|
|
238
|
+
await this.store.upsert(request);
|
|
239
|
+
this.ctx.emitter.emit("approval:timeout", {
|
|
240
|
+
requestId: request.id,
|
|
241
|
+
action,
|
|
242
|
+
});
|
|
243
|
+
if (request.taskId) {
|
|
244
|
+
try {
|
|
245
|
+
if (action === "approve") {
|
|
246
|
+
await this.ctx.registry.transition(request.taskId, "assigned");
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
await this.ctx.registry.transition(request.taskId, "failed");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch { /* Task may have been modified externally */ }
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async getPending() {
|
|
256
|
+
return this.store.list("pending");
|
|
257
|
+
}
|
|
258
|
+
async getAll(status) {
|
|
259
|
+
return this.store.list(status);
|
|
260
|
+
}
|
|
261
|
+
async getRequest(id) {
|
|
262
|
+
return this.store.get(id);
|
|
263
|
+
}
|
|
264
|
+
// ─── Helpers ───────────────────────────────────────
|
|
265
|
+
startTimer(requestId, ms, gate) {
|
|
266
|
+
const timer = setTimeout(async () => {
|
|
267
|
+
const request = await this.store.get(requestId);
|
|
268
|
+
if (request)
|
|
269
|
+
await this.resolveTimeout(request, gate);
|
|
270
|
+
this.timers.delete(requestId);
|
|
271
|
+
}, ms);
|
|
272
|
+
this.timers.set(requestId, timer);
|
|
273
|
+
}
|
|
274
|
+
clearTimer(requestId) {
|
|
275
|
+
const timer = this.timers.get(requestId);
|
|
276
|
+
if (timer) {
|
|
277
|
+
clearTimeout(timer);
|
|
278
|
+
this.timers.delete(requestId);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
evaluateCondition(expression, data) {
|
|
282
|
+
try {
|
|
283
|
+
const fn = new Function("data", "task", "mission", `try { return !!(${expression}); } catch { return false; }`);
|
|
284
|
+
const taskData = this.isRecord(data) ? data.task : undefined;
|
|
285
|
+
const missionData = this.isRecord(data) ? data.mission : undefined;
|
|
286
|
+
return fn(data, taskData, missionData) === true;
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
isRecord(v) {
|
|
293
|
+
return typeof v === "object" && v !== null;
|
|
294
|
+
}
|
|
295
|
+
extractTaskId(data) {
|
|
296
|
+
if (!this.isRecord(data))
|
|
297
|
+
return undefined;
|
|
298
|
+
const d = data;
|
|
299
|
+
if (typeof d.taskId === "string")
|
|
300
|
+
return d.taskId;
|
|
301
|
+
if (this.isRecord(d.task) && typeof d.task.id === "string") {
|
|
302
|
+
return d.task.id;
|
|
303
|
+
}
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
extractMissionId(data) {
|
|
307
|
+
if (!this.isRecord(data))
|
|
308
|
+
return undefined;
|
|
309
|
+
const d = data;
|
|
310
|
+
if (typeof d.missionId === "string")
|
|
311
|
+
return d.missionId;
|
|
312
|
+
if (this.isRecord(d.mission) && typeof d.mission.id === "string") {
|
|
313
|
+
return d.mission.id;
|
|
314
|
+
}
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
dispose() {
|
|
318
|
+
for (const timer of this.timers.values()) {
|
|
319
|
+
clearTimeout(timer);
|
|
320
|
+
}
|
|
321
|
+
this.timers.clear();
|
|
322
|
+
this.store.close?.();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=approval-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-manager.js","sourceRoot":"","sources":["../src/approval-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAOhC;;;;;;;;;GASG;AACH,MAAM,OAAO,eAAe;IAMhB;IACA;IANF,MAAM,GAAG,IAAI,GAAG,EAAyC,CAAC;IAC1D,kBAAkB,CAA0B;IAC5C,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhD,YACU,GAAwB,EACxB,KAAoB;QADpB,QAAG,GAAH,GAAG,CAAqB;QACxB,UAAK,GAAL,KAAK,CAAe;IAC3B,CAAC;IAEJ,oEAAoE;IACpE,qBAAqB,CAAC,MAA8B;QAClD,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QACrD,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QACrD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAED,6DAA6D;QAC7D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;gBAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;gBACjE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;gBAC3C,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;oBACnB,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACvC,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,2BAA2B,CAAC,IAAkB;QACpD,IAAI,CAAC,IAAI,CAAC,kBAAkB;YAAE,OAAO;QACrC,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACrE,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,OAAO;QAElD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEtC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;YAC9B,EAAE,EAAE,gBAAgB,IAAI,CAAC,EAAE,EAAE;YAC7B,IAAI,EAAE,aAAa,IAAI,CAAC,IAAI,oBAAoB;YAChD,MAAM,EAAE,CAAC,oBAAoB,CAAC;YAC9B,SAAS,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;YACxD,QAAQ,EAAE,IAAI,CAAC,cAAc;YAC7B,QAAQ,EAAE,SAAS;YACnB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;YAChC,iBAAiB,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;YAC9B,EAAE,EAAE,gBAAgB,IAAI,CAAC,EAAE,EAAE;YAC7B,IAAI,EAAE,aAAa,IAAI,CAAC,IAAI,mBAAmB;YAC/C,MAAM,EAAE,CAAC,mBAAmB,CAAC;YAC7B,QAAQ,EAAE,IAAI,CAAC,cAAc;YAC7B,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;YAC9B,EAAE,EAAE,oBAAoB,IAAI,CAAC,EAAE,EAAE;YACjC,IAAI,EAAE,aAAa,IAAI,CAAC,IAAI,oBAAoB;YAChD,MAAM,EAAE,CAAC,kBAAkB,CAAC;YAC5B,QAAQ,EAAE,IAAI,CAAC,cAAc;YAC7B,QAAQ,EAAE,UAAU;SACrB,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,IAAkB;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAqB,CAAC;QAExC,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;YACtB,IAAI;YACJ,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,EAAE;YAC7B,IAAI,EAAE,iBAAiB,IAAI,CAAC,IAAI,EAAE;YAClC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACf,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC;oBAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC5E,IAAI,CAAC,OAAO;wBAAE,OAAO;gBACvB,CAAC;gBAED,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;oBAC5B,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC;wBAC/B,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,IAAI,gCAAgC,CAAC,CAAC;oBACtE,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;gBACnD,GAAG,CAAC,MAAM,CAAC,4BAA4B,IAAI,CAAC,IAAI,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;gBAE7E,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC5C,IAAI,MAAM,EAAE,CAAC;oBACX,mCAAmC;oBACnC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;wBACnE,uEAAuE;oBACzE,CAAC,CAAC,CAAC;gBACL,CAAC;gBAED,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE;oBAC1C,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC7B,CAAC,CAAC;gBAEH,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;oBACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,IAAkB,EAAE,OAAgB;QACxD,MAAM,OAAO,GAAoB;YAC/B,EAAE,EAAE,MAAM,EAAE;YACZ,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;YACnC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACzC,MAAM,EAAE,SAAS;YACjB,OAAO;YACP,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QACF,oCAAoC;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,UAAmB,EAAE,IAAa;QACjE,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB,EAAE,QAAgB,EAAE,UAAmB;QACnE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAC1D,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEjC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACxF,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAEvB,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;QAC7C,IAAI,YAAY,IAAI,YAAY;YAAE,OAAO,IAAI,CAAC;QAE9C,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;QAC5B,OAAO,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC9C,OAAO,CAAC,UAAU,GAAG,UAAU,IAAI,MAAM,CAAC;QAC1C,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;QACxB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAE3B,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC;QAClC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEhF,MAAM,SAAS,GAAG,WAAW,CAAC;QAC9B,MAAM,aAAa,GAAG,gBAAgB,QAAQ,gBAAgB,QAAQ,EAAE,CAAC;QACzE,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;QACxE,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAExF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE;YACzC,SAAS;YACT,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ;YACR,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAErE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;QAExD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,SAAiB;QAC/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QACjE,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACxF,MAAM,aAAa,GAAG,IAAI,EAAE,YAAY,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,EAAE,aAAa,IAAI,CAAC,CAAC;QAE9C,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;IAChG,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,SAAiB,EACjB,MAA+B,EAC/B,UAAmB,EACnB,IAAa;QAEb,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAE1D,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;QACxB,OAAO,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC9C,OAAO,CAAC,UAAU,GAAG,UAAU,IAAI,MAAM,CAAC;QAC1C,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;QACpB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAE3B,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE;YACzC,SAAS;YACT,MAAM;YACN,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;oBAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;oBACxF,MAAM,YAAY,GAAG,IAAI,EAAE,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;oBAC1E,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,YAAmB,CAAC,CAAC;gBAC1E,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,OAAwB,EAAE,IAAkB;QACvE,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO;QAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,IAAI,QAAQ,CAAC;QAC9C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;QAC3B,OAAO,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC9C,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;QAC/B,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE;YACxC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,MAAM;SACP,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAuB;QAClC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,sDAAsD;IAE9C,UAAU,CAAC,SAAiB,EAAE,EAAU,EAAE,IAAkB;QAClE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChD,IAAI,OAAO;gBAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAEO,UAAU,CAAC,SAAiB;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,UAAkB,EAAE,IAAa;QACzD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,UAAU,8BAA8B,CAAC,CAAC;YAChH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAgC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1F,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAgC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;YAChG,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,CAAU;QACzB,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC;IAC7C,CAAC;IAEO,aAAa,CAAC,IAAa;QACjC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,MAAM,CAAC,GAAG,IAA+B,CAAC;QAC1C,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC,MAAM,CAAC;QAClD,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,OAAQ,CAAC,CAAC,IAAgC,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YACxF,OAAQ,CAAC,CAAC,IAAgC,CAAC,EAAY,CAAC;QAC1D,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,gBAAgB,CAAC,IAAa;QACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,MAAM,CAAC,GAAG,IAA+B,CAAC;QAC1C,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC,SAAS,CAAC;QACxD,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,OAAQ,CAAC,CAAC,OAAmC,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC9F,OAAQ,CAAC,CAAC,OAAmC,CAAC,EAAY,CAAC;QAC7D,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ApprovalRequest, ApprovalStatus } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Persistent store for approval requests.
|
|
4
|
+
*/
|
|
5
|
+
export interface ApprovalStore {
|
|
6
|
+
/** Save or update an approval request. */
|
|
7
|
+
upsert(request: ApprovalRequest): Promise<void>;
|
|
8
|
+
/** Get a request by ID. */
|
|
9
|
+
get(id: string): Promise<ApprovalRequest | undefined>;
|
|
10
|
+
/** List all requests, optionally filtered by status. */
|
|
11
|
+
list(status?: ApprovalStatus): Promise<ApprovalRequest[]>;
|
|
12
|
+
/** List pending requests for a specific task. */
|
|
13
|
+
listByTask(taskId: string): Promise<ApprovalRequest[]>;
|
|
14
|
+
/** Delete a request by ID. */
|
|
15
|
+
delete(id: string): Promise<boolean>;
|
|
16
|
+
/** Close the store (cleanup). */
|
|
17
|
+
close?(): Promise<void> | void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=approval-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-store.d.ts","sourceRoot":"","sources":["../src/approval-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,2BAA2B;IAC3B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;IACtD,wDAAwD;IACxD,IAAI,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC1D,iDAAiD;IACjD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACvD,8BAA8B;IAC9B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,iCAAiC;IACjC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-store.js","sourceRoot":"","sources":["../src/approval-store.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CheckpointStore — pure interface for mission checkpoint persistence.
|
|
3
|
+
*
|
|
4
|
+
* FileCheckpointStore (node:fs) implements this in the shell.
|
|
5
|
+
*/
|
|
6
|
+
import type { MissionCheckpoint } from "./types.js";
|
|
7
|
+
export interface CheckpointState {
|
|
8
|
+
definitions: Record<string, MissionCheckpoint[]>;
|
|
9
|
+
active: Record<string, {
|
|
10
|
+
checkpoint: MissionCheckpoint;
|
|
11
|
+
reachedAt: string;
|
|
12
|
+
}>;
|
|
13
|
+
resumed: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface CheckpointStore {
|
|
16
|
+
load(): Promise<CheckpointState>;
|
|
17
|
+
save(state: CheckpointState): Promise<void>;
|
|
18
|
+
removeGroup(state: CheckpointState, group: string): Promise<CheckpointState>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=checkpoint-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,iBAAiB,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,WAAW,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC9E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-store.js","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PolpoConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Persistent store for project-level configuration (.polpo/polpo.json).
|
|
4
|
+
*/
|
|
5
|
+
export interface ConfigStore {
|
|
6
|
+
/** Check if a config has been saved. */
|
|
7
|
+
exists(): Promise<boolean>;
|
|
8
|
+
/** Load the saved config, or undefined if none. */
|
|
9
|
+
get(): Promise<PolpoConfig | undefined>;
|
|
10
|
+
/** Persist the config. Creates the directory if needed. */
|
|
11
|
+
save(config: PolpoConfig): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=config-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3B,mDAAmD;IACnD,GAAG,IAAI,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IACxC,2DAA2D;IAC3D,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-store.js","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":""}
|
package/dist/cron.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
interface CronField {
|
|
2
|
+
values: Set<number>;
|
|
3
|
+
}
|
|
4
|
+
interface ParsedCron {
|
|
5
|
+
minute: CronField;
|
|
6
|
+
hour: CronField;
|
|
7
|
+
dayOfMonth: CronField;
|
|
8
|
+
month: CronField;
|
|
9
|
+
dayOfWeek: CronField;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Parse a 5-field cron expression into a structured object.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseCron(expression: string): ParsedCron;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a given Date matches a parsed cron expression.
|
|
17
|
+
*/
|
|
18
|
+
export declare function matchesCron(cron: ParsedCron, date: Date): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Calculate the next occurrence of a cron expression after the given date.
|
|
21
|
+
* Searches up to ~2 years ahead to avoid infinite loops.
|
|
22
|
+
*/
|
|
23
|
+
export declare function nextCronOccurrence(expression: string, after: Date): Date | null;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a string looks like a cron expression (5 space-separated fields).
|
|
26
|
+
*/
|
|
27
|
+
export declare function isCronExpression(str: string): boolean;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=cron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"AAQA,UAAU,SAAS;IACjB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACrB;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,SAAS,CAAC;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;CACtB;AAuCD;;GAEG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAqBxD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAQjE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAkB/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD"}
|
package/dist/cron.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Minimal cron expression parser — zero external dependencies.
|
|
2
|
+
//
|
|
3
|
+
// Supports standard 5-field cron: minute hour day-of-month month day-of-week
|
|
4
|
+
// - Numbers, ranges (1-5), steps (star/10), lists (1,3,5), wildcards (star)
|
|
5
|
+
// - Day-of-week: 0-7 (0 and 7 = Sunday)
|
|
6
|
+
//
|
|
7
|
+
// Does NOT support: @yearly/@monthly shortcuts, seconds field, L/W/# modifiers.
|
|
8
|
+
const FIELD_RANGES = [
|
|
9
|
+
[0, 59], // minute
|
|
10
|
+
[0, 23], // hour
|
|
11
|
+
[1, 31], // day of month
|
|
12
|
+
[1, 12], // month
|
|
13
|
+
[0, 7], // day of week (0 and 7 = Sunday)
|
|
14
|
+
];
|
|
15
|
+
/** Parse a single cron field (e.g. "1,3,5", "1-5"). */
|
|
16
|
+
function parseField(field, min, max) {
|
|
17
|
+
const values = new Set();
|
|
18
|
+
for (const part of field.split(",")) {
|
|
19
|
+
const stepMatch = part.match(/^(.+)\/(\d+)$/);
|
|
20
|
+
const step = stepMatch ? parseInt(stepMatch[2], 10) : 1;
|
|
21
|
+
const range = stepMatch ? stepMatch[1] : part;
|
|
22
|
+
if (range === "*") {
|
|
23
|
+
for (let i = min; i <= max; i += step)
|
|
24
|
+
values.add(i);
|
|
25
|
+
}
|
|
26
|
+
else if (range.includes("-")) {
|
|
27
|
+
const [startStr, endStr] = range.split("-");
|
|
28
|
+
const start = parseInt(startStr, 10);
|
|
29
|
+
const end = parseInt(endStr, 10);
|
|
30
|
+
if (isNaN(start) || isNaN(end))
|
|
31
|
+
throw new Error(`Invalid cron range: ${range}`);
|
|
32
|
+
for (let i = start; i <= end; i += step) {
|
|
33
|
+
if (i >= min && i <= max)
|
|
34
|
+
values.add(i);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const val = parseInt(range, 10);
|
|
39
|
+
if (isNaN(val))
|
|
40
|
+
throw new Error(`Invalid cron value: ${range}`);
|
|
41
|
+
if (val >= min && val <= max)
|
|
42
|
+
values.add(val);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { values };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Parse a 5-field cron expression into a structured object.
|
|
49
|
+
*/
|
|
50
|
+
export function parseCron(expression) {
|
|
51
|
+
const fields = expression.trim().split(/\s+/);
|
|
52
|
+
if (fields.length !== 5) {
|
|
53
|
+
throw new Error(`Invalid cron expression "${expression}": expected 5 fields, got ${fields.length}`);
|
|
54
|
+
}
|
|
55
|
+
const parsed = {
|
|
56
|
+
minute: parseField(fields[0], ...FIELD_RANGES[0]),
|
|
57
|
+
hour: parseField(fields[1], ...FIELD_RANGES[1]),
|
|
58
|
+
dayOfMonth: parseField(fields[2], ...FIELD_RANGES[2]),
|
|
59
|
+
month: parseField(fields[3], ...FIELD_RANGES[3]),
|
|
60
|
+
dayOfWeek: parseField(fields[4], ...FIELD_RANGES[4]),
|
|
61
|
+
};
|
|
62
|
+
// Normalize day-of-week: 7 → 0 (both mean Sunday)
|
|
63
|
+
if (parsed.dayOfWeek.values.has(7)) {
|
|
64
|
+
parsed.dayOfWeek.values.add(0);
|
|
65
|
+
parsed.dayOfWeek.values.delete(7);
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if a given Date matches a parsed cron expression.
|
|
71
|
+
*/
|
|
72
|
+
export function matchesCron(cron, date) {
|
|
73
|
+
return (cron.minute.values.has(date.getMinutes()) &&
|
|
74
|
+
cron.hour.values.has(date.getHours()) &&
|
|
75
|
+
cron.dayOfMonth.values.has(date.getDate()) &&
|
|
76
|
+
cron.month.values.has(date.getMonth() + 1) && // JS months are 0-based
|
|
77
|
+
cron.dayOfWeek.values.has(date.getDay()));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Calculate the next occurrence of a cron expression after the given date.
|
|
81
|
+
* Searches up to ~2 years ahead to avoid infinite loops.
|
|
82
|
+
*/
|
|
83
|
+
export function nextCronOccurrence(expression, after) {
|
|
84
|
+
const cron = parseCron(expression);
|
|
85
|
+
// Start from the next minute boundary
|
|
86
|
+
const candidate = new Date(after);
|
|
87
|
+
candidate.setSeconds(0, 0);
|
|
88
|
+
candidate.setMinutes(candidate.getMinutes() + 1);
|
|
89
|
+
// Search up to ~2 years ahead (prevent infinite loop)
|
|
90
|
+
const maxIterations = 525_960; // ~365 * 24 * 60 minutes
|
|
91
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
92
|
+
if (matchesCron(cron, candidate)) {
|
|
93
|
+
return candidate;
|
|
94
|
+
}
|
|
95
|
+
candidate.setMinutes(candidate.getMinutes() + 1);
|
|
96
|
+
}
|
|
97
|
+
return null; // No match found within search window
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if a string looks like a cron expression (5 space-separated fields).
|
|
101
|
+
*/
|
|
102
|
+
export function isCronExpression(str) {
|
|
103
|
+
return /^\s*(\S+\s+){4}\S+\s*$/.test(str);
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=cron.js.map
|
package/dist/cron.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DelayStore — pure interface for mission delay persistence.
|
|
3
|
+
*
|
|
4
|
+
* FileDelayStore (node:fs) implements this in the shell.
|
|
5
|
+
*/
|
|
6
|
+
import type { MissionDelay } from "./types.js";
|
|
7
|
+
export interface DelayState {
|
|
8
|
+
definitions: Record<string, MissionDelay[]>;
|
|
9
|
+
active: Record<string, {
|
|
10
|
+
delay: MissionDelay;
|
|
11
|
+
startedAt: string;
|
|
12
|
+
expiresAt: string;
|
|
13
|
+
}>;
|
|
14
|
+
expired: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface DelayStore {
|
|
17
|
+
load(): Promise<DelayState>;
|
|
18
|
+
save(state: DelayState): Promise<void>;
|
|
19
|
+
removeGroup(state: DelayState, group: string): Promise<DelayState>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=delay-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delay-store.d.ts","sourceRoot":"","sources":["../src/delay-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,YAAY,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtF,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACpE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delay-store.js","sourceRoot":"","sources":["../src/delay-store.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { OrchestratorContext } from "./orchestrator-context.js";
|
|
2
|
+
import type { ApprovalManager } from "./approval-manager.js";
|
|
3
|
+
/**
|
|
4
|
+
* Manages the escalation chain when tasks fail repeatedly.
|
|
5
|
+
*
|
|
6
|
+
* 4-level hybrid escalation:
|
|
7
|
+
* Level 0: Retry with same agent (handled by AssessmentOrchestrator — not managed here)
|
|
8
|
+
* Level 1: Escalate to fallback agent (handled by RetryPolicy — not managed here)
|
|
9
|
+
* Level 2: Orchestrator LLM analysis — reformulate the task and retry
|
|
10
|
+
* Level 3: Human-in-the-loop — notify humans and create approval request
|
|
11
|
+
*/
|
|
12
|
+
export declare class EscalationManager {
|
|
13
|
+
private ctx;
|
|
14
|
+
private approvalMgr?;
|
|
15
|
+
private taskLevels;
|
|
16
|
+
private timers;
|
|
17
|
+
constructor(ctx: OrchestratorContext, approvalMgr?: ApprovalManager | undefined);
|
|
18
|
+
init(): void;
|
|
19
|
+
private getStartLevel;
|
|
20
|
+
private escalate;
|
|
21
|
+
private escalateToAgent;
|
|
22
|
+
private escalateToOrchestrator;
|
|
23
|
+
private escalateToHuman;
|
|
24
|
+
private advanceLevel;
|
|
25
|
+
private finalFail;
|
|
26
|
+
private buildFailureContext;
|
|
27
|
+
private startTimer;
|
|
28
|
+
private clearTimer;
|
|
29
|
+
dispose(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=escalation-manager.d.ts.map
|