@telora/mcp-products 0.21.1
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/README.md +276 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +94 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/handlers/agentHandlers.d.ts +3 -0
- package/dist/handlers/agentHandlers.js +97 -0
- package/dist/handlers/agentHandlers.js.map +1 -0
- package/dist/handlers/connectorHandlers.d.ts +3 -0
- package/dist/handlers/connectorHandlers.js +401 -0
- package/dist/handlers/connectorHandlers.js.map +1 -0
- package/dist/handlers/contextHandlers.d.ts +8 -0
- package/dist/handlers/contextHandlers.js +169 -0
- package/dist/handlers/contextHandlers.js.map +1 -0
- package/dist/handlers/deliveryHandlers.d.ts +3 -0
- package/dist/handlers/deliveryHandlers.js +122 -0
- package/dist/handlers/deliveryHandlers.js.map +1 -0
- package/dist/handlers/deploymentProfileHandlers.d.ts +3 -0
- package/dist/handlers/deploymentProfileHandlers.js +104 -0
- package/dist/handlers/deploymentProfileHandlers.js.map +1 -0
- package/dist/handlers/discoverHandler.d.ts +23 -0
- package/dist/handlers/discoverHandler.js +83 -0
- package/dist/handlers/discoverHandler.js.map +1 -0
- package/dist/handlers/factoryHandlers.d.ts +3 -0
- package/dist/handlers/factoryHandlers.js +484 -0
- package/dist/handlers/factoryHandlers.js.map +1 -0
- package/dist/handlers/ideaHandlers.d.ts +3 -0
- package/dist/handlers/ideaHandlers.js +245 -0
- package/dist/handlers/ideaHandlers.js.map +1 -0
- package/dist/handlers/index.d.ts +15 -0
- package/dist/handlers/index.js +19 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/infrastructureHandlers.d.ts +3 -0
- package/dist/handlers/infrastructureHandlers.js +335 -0
- package/dist/handlers/infrastructureHandlers.js.map +1 -0
- package/dist/handlers/issueHandlers.d.ts +3 -0
- package/dist/handlers/issueHandlers.js +94 -0
- package/dist/handlers/issueHandlers.js.map +1 -0
- package/dist/handlers/okrHandlers.d.ts +3 -0
- package/dist/handlers/okrHandlers.js +194 -0
- package/dist/handlers/okrHandlers.js.map +1 -0
- package/dist/handlers/playbookHandlers.d.ts +3 -0
- package/dist/handlers/playbookHandlers.js +93 -0
- package/dist/handlers/playbookHandlers.js.map +1 -0
- package/dist/handlers/productHandlers.d.ts +3 -0
- package/dist/handlers/productHandlers.js +129 -0
- package/dist/handlers/productHandlers.js.map +1 -0
- package/dist/handlers/reportHandlers.d.ts +3 -0
- package/dist/handlers/reportHandlers.js +59 -0
- package/dist/handlers/reportHandlers.js.map +1 -0
- package/dist/handlers/strategyHandlers.d.ts +3 -0
- package/dist/handlers/strategyHandlers.js +116 -0
- package/dist/handlers/strategyHandlers.js.map +1 -0
- package/dist/handlers/workflowHandlers.d.ts +3 -0
- package/dist/handlers/workflowHandlers.js +93 -0
- package/dist/handlers/workflowHandlers.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +284 -0
- package/dist/index.js.map +1 -0
- package/dist/shared.d.ts +77 -0
- package/dist/shared.js +147 -0
- package/dist/shared.js.map +1 -0
- package/package.json +47 -0
- package/scripts/postinstall.js +96 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Daemon connector tool handler: telora_connector_start
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { existsSync, writeFileSync, mkdirSync, readFileSync, openSync } from "node:fs";
|
|
6
|
+
import { spawn, execFileSync } from "node:child_process";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { callProductApi, successResult, wrapHandler, } from "../shared.js";
|
|
10
|
+
// Keys that always come from the fresh config (identity/auth -- may change between restarts).
|
|
11
|
+
// Note: productId is NOT here -- it's been replaced by the products array.
|
|
12
|
+
const IDENTITY_KEYS = ["teloraUrl", "trackerId", "organizationId"];
|
|
13
|
+
/**
|
|
14
|
+
* Merge a fresh daemon config into an existing one.
|
|
15
|
+
*
|
|
16
|
+
* - Identity keys are always overwritten.
|
|
17
|
+
* - Products array: if the fresh product is already in the array, update its
|
|
18
|
+
* repoPath if different; if missing, append the new entry.
|
|
19
|
+
* - Legacy flat `productId` + `repoPath` are migrated into the products array.
|
|
20
|
+
* - Engine sections are only added if missing.
|
|
21
|
+
* - Everything else the user has customized is preserved.
|
|
22
|
+
*
|
|
23
|
+
* Returns { config, action } where action indicates what happened:
|
|
24
|
+
* 'created' -- first-time config (no existing file)
|
|
25
|
+
* 'added' -- new product appended to existing config
|
|
26
|
+
* 'updated' -- existing product's repoPath changed
|
|
27
|
+
* 'no_change' -- product already registered with same repoPath
|
|
28
|
+
*/
|
|
29
|
+
function mergeConfig(existing, freshProduct, fresh) {
|
|
30
|
+
const merged = { ...existing };
|
|
31
|
+
// Always overwrite identity keys
|
|
32
|
+
for (const key of IDENTITY_KEYS) {
|
|
33
|
+
if (key in fresh) {
|
|
34
|
+
merged[key] = fresh[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Migrate legacy flat productId + repoPath into products array
|
|
38
|
+
let products = Array.isArray(merged.products)
|
|
39
|
+
? merged.products
|
|
40
|
+
: [];
|
|
41
|
+
if (products.length === 0 && typeof merged.productId === "string" && merged.productId) {
|
|
42
|
+
// Legacy single-product config -- migrate to products array
|
|
43
|
+
const legacyRepoPath = typeof merged.repoPath === "string" ? merged.repoPath : process.cwd();
|
|
44
|
+
products = [{ id: merged.productId, repoPath: legacyRepoPath }];
|
|
45
|
+
}
|
|
46
|
+
// Remove legacy flat keys (superseded by products array)
|
|
47
|
+
delete merged.productId;
|
|
48
|
+
delete merged.repoPath;
|
|
49
|
+
// Upsert the fresh product into the array
|
|
50
|
+
let action;
|
|
51
|
+
const idx = products.findIndex((p) => p.id === freshProduct.id);
|
|
52
|
+
if (idx >= 0) {
|
|
53
|
+
if (products[idx].repoPath !== freshProduct.repoPath) {
|
|
54
|
+
products[idx] = { ...products[idx], repoPath: freshProduct.repoPath };
|
|
55
|
+
action = "updated";
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
action = "no_change";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
products.push(freshProduct);
|
|
63
|
+
action = "added";
|
|
64
|
+
}
|
|
65
|
+
merged.products = products;
|
|
66
|
+
// Engines: add missing sections, never overwrite existing ones
|
|
67
|
+
const freshEngines = fresh.engines;
|
|
68
|
+
if (freshEngines) {
|
|
69
|
+
if (!merged.engines) {
|
|
70
|
+
merged.engines = freshEngines;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const existingEngines = merged.engines;
|
|
74
|
+
for (const engineKey of Object.keys(freshEngines)) {
|
|
75
|
+
if (!(engineKey in existingEngines)) {
|
|
76
|
+
existingEngines[engineKey] = freshEngines[engineKey];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { config: merged, action };
|
|
82
|
+
}
|
|
83
|
+
/** Read the daemon PID from .telora/daemon.pid. Returns null if missing or invalid. */
|
|
84
|
+
function readPidFile(teloraDir) {
|
|
85
|
+
const pidPath = join(teloraDir, "daemon.pid");
|
|
86
|
+
try {
|
|
87
|
+
const raw = readFileSync(pidPath, "utf-8").trim();
|
|
88
|
+
const pid = parseInt(raw, 10);
|
|
89
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** Check if a process is alive (signal 0 existence check). */
|
|
96
|
+
function isProcessAlive(pid) {
|
|
97
|
+
try {
|
|
98
|
+
process.kill(pid, 0);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Stop the daemon gracefully: SIGTERM, poll for exit, SIGKILL fallback. */
|
|
106
|
+
async function stopDaemon(teloraDir) {
|
|
107
|
+
const pid = readPidFile(teloraDir);
|
|
108
|
+
if (pid === null) {
|
|
109
|
+
return { stopped: false, message: "No PID file found" };
|
|
110
|
+
}
|
|
111
|
+
if (!isProcessAlive(pid)) {
|
|
112
|
+
return { stopped: false, pid, message: "Process not running" };
|
|
113
|
+
}
|
|
114
|
+
// Send SIGTERM
|
|
115
|
+
try {
|
|
116
|
+
process.kill(pid, "SIGTERM");
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return { stopped: false, pid, message: "Failed to send SIGTERM" };
|
|
120
|
+
}
|
|
121
|
+
// Poll every 300ms for up to 10s
|
|
122
|
+
const deadline = Date.now() + 10_000;
|
|
123
|
+
while (Date.now() < deadline) {
|
|
124
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
125
|
+
if (!isProcessAlive(pid)) {
|
|
126
|
+
return { stopped: true, pid, message: "Stopped with SIGTERM" };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// SIGKILL fallback
|
|
130
|
+
try {
|
|
131
|
+
process.kill(pid, "SIGKILL");
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Process may have exited between last check and kill
|
|
135
|
+
if (!isProcessAlive(pid)) {
|
|
136
|
+
return { stopped: true, pid, message: "Stopped with SIGTERM (late exit)" };
|
|
137
|
+
}
|
|
138
|
+
return { stopped: false, pid, message: "Failed to send SIGKILL" };
|
|
139
|
+
}
|
|
140
|
+
// Brief wait after SIGKILL
|
|
141
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
142
|
+
return { stopped: true, pid, message: "Stopped with SIGKILL" };
|
|
143
|
+
}
|
|
144
|
+
export function registerConnectorTools(server, getCreds, profile = 'full') {
|
|
145
|
+
// -- telora_connector_start -------------------------------------------------
|
|
146
|
+
server.tool("telora_connector_start", "Daemon automation: generate configuration and launch the Telora daemon for autonomous agent execution. " +
|
|
147
|
+
"Creates daemon.json with API credentials and engine settings, then starts the background process.", {
|
|
148
|
+
productId: z.string().uuid().optional().describe("Product UUID to scope this daemon to. Required when the organization has multiple products. Auto-detected when there is only one product."),
|
|
149
|
+
}, wrapHandler(async ({ productId: explicitProductId }) => {
|
|
150
|
+
const creds = getCreds();
|
|
151
|
+
// Call whoami to get org ID and tracker info
|
|
152
|
+
const whoami = await callProductApi(creds, {
|
|
153
|
+
action: "whoami",
|
|
154
|
+
});
|
|
155
|
+
// Resolve productId — required so the daemon only picks up work for this repo's product
|
|
156
|
+
const productId = explicitProductId;
|
|
157
|
+
if (!productId) {
|
|
158
|
+
const productsResult = await callProductApi(creds, {
|
|
159
|
+
action: "product_list",
|
|
160
|
+
});
|
|
161
|
+
if (productsResult.products.length === 0) {
|
|
162
|
+
return {
|
|
163
|
+
content: [{
|
|
164
|
+
type: "text",
|
|
165
|
+
text: "No products found in your organization. Create a product first with telora_product_create, then re-run telora_connector_start.",
|
|
166
|
+
}],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const productList = productsResult.products
|
|
170
|
+
.map((p) => ` - ${p.name}: ${p.id}`)
|
|
171
|
+
.join("\n");
|
|
172
|
+
return {
|
|
173
|
+
content: [{
|
|
174
|
+
type: "text",
|
|
175
|
+
text: `The daemon must be scoped to a specific product. ` +
|
|
176
|
+
`Determine which product this repository belongs to, then call telora_connector_start again with the productId parameter.\n\n` +
|
|
177
|
+
`Available products:\n${productList}\n\n` +
|
|
178
|
+
`If this repository needs a new product, create one with telora_product_create first.`,
|
|
179
|
+
}],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Build the fresh config skeleton (no secrets -- safe to commit).
|
|
183
|
+
// Uses the unified engines section format so both strategy and factory
|
|
184
|
+
// engines are enabled by default. The products array replaces the flat
|
|
185
|
+
// productId so one daemon can serve multiple repos.
|
|
186
|
+
const repoPath = process.cwd();
|
|
187
|
+
const freshProduct = { id: productId, repoPath };
|
|
188
|
+
const freshConfig = {
|
|
189
|
+
teloraUrl: creds.teloraUrl,
|
|
190
|
+
trackerId: whoami.trackerId,
|
|
191
|
+
organizationId: whoami.organizationId,
|
|
192
|
+
products: [freshProduct],
|
|
193
|
+
sessionTimeoutMs: 3600000,
|
|
194
|
+
engines: {
|
|
195
|
+
strategy: {
|
|
196
|
+
integrationBranch: "integration",
|
|
197
|
+
maxTotalSessions: 5,
|
|
198
|
+
tokenLimit: 200000,
|
|
199
|
+
costLimit: 10.0,
|
|
200
|
+
},
|
|
201
|
+
factory: {
|
|
202
|
+
maxConcurrentInstances: 3,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
// 1. Resolve config path:
|
|
207
|
+
// - Prefer global ~/.telora/daemon.json when it already exists
|
|
208
|
+
// (multi-product: one daemon config for all repos)
|
|
209
|
+
// - Fall back to repo-local .telora/daemon.json for first-time setup
|
|
210
|
+
const globalTeloraDir = join(homedir(), ".telora");
|
|
211
|
+
const globalConfigPath = join(globalTeloraDir, "daemon.json");
|
|
212
|
+
const localTeloraDir = join(repoPath, ".telora");
|
|
213
|
+
const localConfigPath = join(localTeloraDir, "daemon.json");
|
|
214
|
+
const useGlobal = existsSync(globalConfigPath);
|
|
215
|
+
const configPath = useGlobal ? globalConfigPath : localConfigPath;
|
|
216
|
+
const teloraDir = useGlobal ? globalTeloraDir : localTeloraDir;
|
|
217
|
+
mkdirSync(teloraDir, { recursive: true });
|
|
218
|
+
// 2. Merge with existing config to preserve user customizations
|
|
219
|
+
let finalConfig;
|
|
220
|
+
let mergeAction;
|
|
221
|
+
if (existsSync(configPath)) {
|
|
222
|
+
try {
|
|
223
|
+
const existing = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
224
|
+
const result = mergeConfig(existing, freshProduct, freshConfig);
|
|
225
|
+
finalConfig = result.config;
|
|
226
|
+
mergeAction = result.action;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Existing file is corrupt/unparseable -- overwrite with fresh config
|
|
230
|
+
finalConfig = freshConfig;
|
|
231
|
+
mergeAction = "created";
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
finalConfig = freshConfig;
|
|
236
|
+
mergeAction = "created";
|
|
237
|
+
}
|
|
238
|
+
writeFileSync(configPath, JSON.stringify(finalConfig, null, 2) + "\n");
|
|
239
|
+
const productCount = Array.isArray(finalConfig.products)
|
|
240
|
+
? finalConfig.products.length
|
|
241
|
+
: 1;
|
|
242
|
+
// 3. Ensure .telora/ is in .gitignore (only for repo-local config)
|
|
243
|
+
let gitignoreUpdated = false;
|
|
244
|
+
if (!useGlobal) {
|
|
245
|
+
const gitignorePath = join(repoPath, ".gitignore");
|
|
246
|
+
if (existsSync(gitignorePath)) {
|
|
247
|
+
const content = readFileSync(gitignorePath, "utf-8");
|
|
248
|
+
if (!content.split("\n").some((line) => line.trim() === ".telora/")) {
|
|
249
|
+
writeFileSync(gitignorePath, content.trimEnd() + "\n.telora/\n");
|
|
250
|
+
gitignoreUpdated = true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
writeFileSync(gitignorePath, ".telora/\n");
|
|
255
|
+
gitignoreUpdated = true;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// 4. If nothing changed, check if daemon is actually running.
|
|
259
|
+
// If alive, return early so running agent work is not disrupted.
|
|
260
|
+
// If dead (stale PID file), clean up and fall through to start a new one.
|
|
261
|
+
if (mergeAction === "no_change") {
|
|
262
|
+
const existingPid = readPidFile(globalTeloraDir) ?? readPidFile(localTeloraDir);
|
|
263
|
+
if (existingPid && isProcessAlive(existingPid)) {
|
|
264
|
+
return successResult({
|
|
265
|
+
status: "already_running",
|
|
266
|
+
configAction: mergeAction,
|
|
267
|
+
productCount,
|
|
268
|
+
configPath,
|
|
269
|
+
pid: existingPid,
|
|
270
|
+
gitignoreUpdated,
|
|
271
|
+
organizationId: whoami.organizationId,
|
|
272
|
+
productId,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
// Stale PID file -- process is dead. Clean up and start fresh.
|
|
276
|
+
}
|
|
277
|
+
// 5. Stop any running daemon before starting a new one (restart for config changes).
|
|
278
|
+
// Check both global and local .telora dirs for PID file.
|
|
279
|
+
let stopResult = await stopDaemon(globalTeloraDir);
|
|
280
|
+
if (!stopResult.stopped) {
|
|
281
|
+
stopResult = await stopDaemon(localTeloraDir);
|
|
282
|
+
}
|
|
283
|
+
const previousPid = stopResult.stopped ? stopResult.pid : undefined;
|
|
284
|
+
// 6. Start the daemon as a detached background process.
|
|
285
|
+
// Prefer the local build so edits take effect after a local build.
|
|
286
|
+
// Fall back to the global install if no local build exists.
|
|
287
|
+
const logPath = join(teloraDir, "daemon.log");
|
|
288
|
+
const logFd = openSync(logPath, "a");
|
|
289
|
+
const localDaemonPath = join(process.cwd(), "packages/daemon/dist/index.js");
|
|
290
|
+
// Find global install via `which` (works regardless of npm prefix)
|
|
291
|
+
let globalDaemonPath = null;
|
|
292
|
+
try {
|
|
293
|
+
globalDaemonPath = execFileSync("which", ["telora-daemon"], { encoding: "utf-8" }).trim() || null;
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// Not on PATH — check the common ~/.npm-global location as fallback
|
|
297
|
+
const fallback = join(homedir(), ".npm-global/bin/telora-daemon");
|
|
298
|
+
if (existsSync(fallback))
|
|
299
|
+
globalDaemonPath = fallback;
|
|
300
|
+
}
|
|
301
|
+
let daemonCommand;
|
|
302
|
+
let daemonArgs;
|
|
303
|
+
let daemonSource;
|
|
304
|
+
// Pass --config when using global config so the daemon finds it
|
|
305
|
+
const configArgs = useGlobal ? ["--config", configPath] : [];
|
|
306
|
+
if (existsSync(localDaemonPath)) {
|
|
307
|
+
daemonCommand = process.execPath;
|
|
308
|
+
daemonArgs = [localDaemonPath, "--no-auto-update", ...configArgs];
|
|
309
|
+
daemonSource = "local";
|
|
310
|
+
}
|
|
311
|
+
else if (globalDaemonPath) {
|
|
312
|
+
daemonCommand = globalDaemonPath;
|
|
313
|
+
daemonArgs = [...configArgs];
|
|
314
|
+
daemonSource = "global";
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
return {
|
|
318
|
+
content: [{
|
|
319
|
+
type: "text",
|
|
320
|
+
text: "Could not locate telora-daemon. " +
|
|
321
|
+
`No local build at ${localDaemonPath} and telora-daemon is not on PATH. ` +
|
|
322
|
+
"Install globally with: npm install -g @telora/daemon",
|
|
323
|
+
}],
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const daemonProcess = spawn(daemonCommand, daemonArgs, {
|
|
327
|
+
detached: true,
|
|
328
|
+
stdio: ["ignore", logFd, logFd],
|
|
329
|
+
env: { ...process.env, TELORA_TRACKER_ID: whoami.trackerId },
|
|
330
|
+
cwd: process.cwd(),
|
|
331
|
+
});
|
|
332
|
+
const pid = daemonProcess.pid;
|
|
333
|
+
daemonProcess.unref();
|
|
334
|
+
// 6. Wait briefly and verify the daemon is still running.
|
|
335
|
+
// If it exits immediately (config error, binary not found, etc.),
|
|
336
|
+
// read the log tail and return an actionable error instead of false success.
|
|
337
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
338
|
+
let alive = false;
|
|
339
|
+
try {
|
|
340
|
+
process.kill(pid, 0); // signal 0 = existence check only
|
|
341
|
+
alive = true;
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
// ESRCH = no such process
|
|
345
|
+
}
|
|
346
|
+
if (!alive) {
|
|
347
|
+
let logTail = "";
|
|
348
|
+
try {
|
|
349
|
+
const logContent = readFileSync(logPath, "utf-8");
|
|
350
|
+
const lines = logContent.trim().split("\n");
|
|
351
|
+
logTail = lines.slice(-30).join("\n");
|
|
352
|
+
}
|
|
353
|
+
catch { /* ignore */ }
|
|
354
|
+
return {
|
|
355
|
+
content: [{
|
|
356
|
+
type: "text",
|
|
357
|
+
text: `Daemon process (PID ${pid}) exited immediately after start.\n\n` +
|
|
358
|
+
`Last log output:\n${logTail || "(no log output — check " + logPath + ")"}`,
|
|
359
|
+
}],
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
return successResult({
|
|
363
|
+
status: "started",
|
|
364
|
+
configAction: mergeAction,
|
|
365
|
+
productCount,
|
|
366
|
+
configPath,
|
|
367
|
+
logPath,
|
|
368
|
+
pid,
|
|
369
|
+
previousPid,
|
|
370
|
+
gitignoreUpdated,
|
|
371
|
+
organizationId: whoami.organizationId,
|
|
372
|
+
productId,
|
|
373
|
+
daemonSource,
|
|
374
|
+
});
|
|
375
|
+
}));
|
|
376
|
+
// -- telora_connector_stop --------------------------------------------------
|
|
377
|
+
if (profile !== 'human') {
|
|
378
|
+
server.tool("telora_connector_stop", "Daemon lifecycle: stop the running Telora daemon gracefully (SIGTERM with SIGKILL fallback).", {}, wrapHandler(async () => {
|
|
379
|
+
// Try global config location first, fall back to repo-local
|
|
380
|
+
const globalTeloraDir = join(homedir(), ".telora");
|
|
381
|
+
let result = await stopDaemon(globalTeloraDir);
|
|
382
|
+
if (!result.stopped) {
|
|
383
|
+
const localTeloraDir = join(process.cwd(), ".telora");
|
|
384
|
+
result = await stopDaemon(localTeloraDir);
|
|
385
|
+
}
|
|
386
|
+
if (result.stopped) {
|
|
387
|
+
return successResult({
|
|
388
|
+
status: "stopped",
|
|
389
|
+
pid: result.pid,
|
|
390
|
+
message: result.message,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
return successResult({
|
|
394
|
+
status: "not_running",
|
|
395
|
+
pid: result.pid,
|
|
396
|
+
message: result.message,
|
|
397
|
+
});
|
|
398
|
+
}));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
//# sourceMappingURL=connectorHandlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectorHandlers.js","sourceRoot":"","sources":["../../src/handlers/connectorHandlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type GetCreds, type ToolProfile } from "../shared.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register only the telora_context_assemble tool (for human profile core startup).
|
|
5
|
+
* This avoids loading all context CRUD tools at startup.
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerContextAssembleTool(server: McpServer, getCreds: GetCreds): void;
|
|
8
|
+
export declare function registerContextTools(server: McpServer, getCreds: GetCreds, profile?: ToolProfile): void;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Context document tool handlers (consolidated):
|
|
3
|
+
// telora_product_context (list | create | update | delete | reorder)
|
|
4
|
+
// telora_product_context_link (link | unlink)
|
|
5
|
+
// telora_context_assemble (layered context assembly)
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { callProductApi, successResult, validationError, buildFields, wrapHandler, compactEntity, } from "../shared.js";
|
|
9
|
+
/**
|
|
10
|
+
* Register only the telora_context_assemble tool (for human profile core startup).
|
|
11
|
+
* This avoids loading all context CRUD tools at startup.
|
|
12
|
+
*/
|
|
13
|
+
export function registerContextAssembleTool(server, getCreds) {
|
|
14
|
+
server.tool("telora_context_assemble", "Assemble layered context for a product, strategy, or delivery. " +
|
|
15
|
+
"Returns pre-formatted markdown with product philosophy, context documents, strategy goals, " +
|
|
16
|
+
"delivery details, and issue hierarchy. Use at session start for architectural/design work. " +
|
|
17
|
+
"Each scope level includes the previous: product -> strategy -> delivery.", {
|
|
18
|
+
productId: z.string().uuid().describe("Product UUID (required)"),
|
|
19
|
+
strategyId: z.string().uuid().optional().describe("Strategy UUID (adds strategy + delivery summaries)"),
|
|
20
|
+
deliveryId: z.string().uuid().optional().describe("Delivery UUID (adds tech context + acceptance criteria + issues)"),
|
|
21
|
+
}, wrapHandler(async (params) => {
|
|
22
|
+
if (!params.productId)
|
|
23
|
+
return validationError("productId is required");
|
|
24
|
+
const body = {
|
|
25
|
+
action: "context_assemble",
|
|
26
|
+
productId: params.productId,
|
|
27
|
+
};
|
|
28
|
+
if (params.strategyId)
|
|
29
|
+
body.strategyId = params.strategyId;
|
|
30
|
+
if (params.deliveryId)
|
|
31
|
+
body.deliveryId = params.deliveryId;
|
|
32
|
+
const result = await callProductApi(getCreds(), body);
|
|
33
|
+
return successResult(result);
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
export function registerContextTools(server, getCreds, profile = 'full') {
|
|
37
|
+
// -- telora_product_context (consolidated) ------------------------------------
|
|
38
|
+
const contextActions = (profile === 'full' || profile === 'human')
|
|
39
|
+
? ["list", "create", "update", "delete", "reorder"]
|
|
40
|
+
: ["list"];
|
|
41
|
+
server.tool("telora_product_context", `Knowledge base: product context documents provide background knowledge for AI agents and strategy planning. ` +
|
|
42
|
+
`Documents can be scoped as always-included, linked to specific strategies/deliveries, or draft. ` +
|
|
43
|
+
`Actions: ${contextActions.join(", ")}. ` +
|
|
44
|
+
`list: productId required. create: productId + title + content. update: documentId + fields. ` +
|
|
45
|
+
`delete: documentId. reorder: productId + documentIds.`, {
|
|
46
|
+
action: z.enum(contextActions).describe("Action to perform"),
|
|
47
|
+
productId: z.string().uuid().optional().describe("Product UUID (required for list, create, reorder)"),
|
|
48
|
+
documentId: z.string().uuid().optional().describe("Document UUID (required for update, delete)"),
|
|
49
|
+
strategyId: z.string().uuid().optional().describe("Strategy UUID - list returns always + linked docs, excluding drafts"),
|
|
50
|
+
deliveryId: z.string().uuid().optional().describe("Delivery UUID - list returns always + linked docs, excluding drafts"),
|
|
51
|
+
title: z.string().max(500).optional().describe("Document title (required for create)"),
|
|
52
|
+
content: z.string().optional().describe("Markdown content (required for create)"),
|
|
53
|
+
includeMode: z.enum(["draft", "always", "linked"]).optional().describe("Include mode (list: filter; create: defaults to draft)"),
|
|
54
|
+
documentIds: z.array(z.string().uuid()).optional().describe("Ordered array of document UUIDs for reorder (first = sort_order 0)"),
|
|
55
|
+
limit: z.number().int().min(1).max(500).optional().describe("Max results (1-500, default 50)"),
|
|
56
|
+
offset: z.number().int().min(0).optional().describe("Number of results to skip (default 0)"),
|
|
57
|
+
detail: z.enum(["titles", "summary", "full"]).optional().describe("Response detail level"),
|
|
58
|
+
returnFull: z.boolean().optional().describe("Return full entity (default: compact)"),
|
|
59
|
+
}, wrapHandler(async (params) => {
|
|
60
|
+
switch (params.action) {
|
|
61
|
+
case "list": {
|
|
62
|
+
if (!params.productId)
|
|
63
|
+
return validationError("productId required for list");
|
|
64
|
+
const fields = buildFields({ includeMode: params.includeMode });
|
|
65
|
+
const body = {
|
|
66
|
+
action: "context_list",
|
|
67
|
+
productId: params.productId,
|
|
68
|
+
fields: Object.keys(fields).length > 0 ? fields : undefined,
|
|
69
|
+
};
|
|
70
|
+
if (params.strategyId !== undefined)
|
|
71
|
+
body.strategyId = params.strategyId;
|
|
72
|
+
if (params.deliveryId !== undefined)
|
|
73
|
+
body.deliveryId = params.deliveryId;
|
|
74
|
+
if (params.limit !== undefined)
|
|
75
|
+
body.limit = params.limit;
|
|
76
|
+
if (params.offset !== undefined)
|
|
77
|
+
body.offset = params.offset;
|
|
78
|
+
if (params.detail !== undefined)
|
|
79
|
+
body.detail = params.detail;
|
|
80
|
+
const result = await callProductApi(getCreds(), body);
|
|
81
|
+
return successResult({ items: result.documents, totalCount: result.totalCount });
|
|
82
|
+
}
|
|
83
|
+
case "create": {
|
|
84
|
+
if (!params.productId)
|
|
85
|
+
return validationError("productId required for create");
|
|
86
|
+
if (!params.title)
|
|
87
|
+
return validationError("title required for create");
|
|
88
|
+
if (!params.content)
|
|
89
|
+
return validationError("content required for create");
|
|
90
|
+
const fields = buildFields({ title: params.title, content: params.content, includeMode: params.includeMode });
|
|
91
|
+
const result = await callProductApi(getCreds(), {
|
|
92
|
+
action: "context_create",
|
|
93
|
+
productId: params.productId,
|
|
94
|
+
fields,
|
|
95
|
+
});
|
|
96
|
+
return successResult(compactEntity(result.document, Object.keys(fields), params.returnFull));
|
|
97
|
+
}
|
|
98
|
+
case "update": {
|
|
99
|
+
if (!params.documentId)
|
|
100
|
+
return validationError("documentId required for update");
|
|
101
|
+
const fields = buildFields({ title: params.title, content: params.content, includeMode: params.includeMode });
|
|
102
|
+
if (Object.keys(fields).length === 0) {
|
|
103
|
+
return validationError("Provide at least one field to update");
|
|
104
|
+
}
|
|
105
|
+
const result = await callProductApi(getCreds(), {
|
|
106
|
+
action: "context_update",
|
|
107
|
+
documentId: params.documentId,
|
|
108
|
+
fields,
|
|
109
|
+
});
|
|
110
|
+
return successResult(compactEntity(result.document, Object.keys(fields), params.returnFull));
|
|
111
|
+
}
|
|
112
|
+
case "delete": {
|
|
113
|
+
if (!params.documentId)
|
|
114
|
+
return validationError("documentId required for delete");
|
|
115
|
+
const result = await callProductApi(getCreds(), {
|
|
116
|
+
action: "context_delete",
|
|
117
|
+
documentId: params.documentId,
|
|
118
|
+
});
|
|
119
|
+
return successResult(result);
|
|
120
|
+
}
|
|
121
|
+
case "reorder": {
|
|
122
|
+
if (!params.productId)
|
|
123
|
+
return validationError("productId required for reorder");
|
|
124
|
+
if (!params.documentIds)
|
|
125
|
+
return validationError("documentIds required for reorder");
|
|
126
|
+
const result = await callProductApi(getCreds(), {
|
|
127
|
+
action: "context_reorder",
|
|
128
|
+
productId: params.productId,
|
|
129
|
+
documentIds: params.documentIds,
|
|
130
|
+
});
|
|
131
|
+
return successResult(result.documents);
|
|
132
|
+
}
|
|
133
|
+
default:
|
|
134
|
+
return validationError(`Unknown action: ${params.action}`);
|
|
135
|
+
}
|
|
136
|
+
}));
|
|
137
|
+
// -- telora_product_context_link (consolidated) -------------------------------
|
|
138
|
+
if (profile === 'full' || profile === 'human') {
|
|
139
|
+
server.tool("telora_product_context_link", "Document linking: attach or detach context documents to strategies or deliveries. " +
|
|
140
|
+
"Linked documents are included in the AI agent's context when working on that entity. Actions: link, unlink.", {
|
|
141
|
+
action: z.enum(["link", "unlink"]).describe("Action to perform"),
|
|
142
|
+
documentId: z.string().uuid().describe("Document UUID"),
|
|
143
|
+
entityType: z.enum(["strategy", "delivery"]).describe("Entity type to link/unlink"),
|
|
144
|
+
entityId: z.string().uuid().describe("Entity UUID to link/unlink"),
|
|
145
|
+
}, wrapHandler(async ({ action, documentId, entityType, entityId }) => {
|
|
146
|
+
if (action === "link") {
|
|
147
|
+
const result = await callProductApi(getCreds(), {
|
|
148
|
+
action: "context_link",
|
|
149
|
+
documentId,
|
|
150
|
+
fields: { entityType, entityId },
|
|
151
|
+
});
|
|
152
|
+
return successResult(result.link);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const result = await callProductApi(getCreds(), {
|
|
156
|
+
action: "context_unlink",
|
|
157
|
+
documentId,
|
|
158
|
+
fields: { entityType, entityId },
|
|
159
|
+
});
|
|
160
|
+
return successResult(result);
|
|
161
|
+
}
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
// -- telora_context_assemble (non-human profiles only; human uses registerContextAssembleTool) --
|
|
165
|
+
if (profile === 'full') {
|
|
166
|
+
registerContextAssembleTool(server, getCreds);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=contextHandlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextHandlers.js","sourceRoot":"","sources":["../../src/handlers/contextHandlers.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,iDAAiD;AACjD,uEAAuE;AACvE,gDAAgD;AAChD,uDAAuD;AACvD,8EAA8E;AAE9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,cAAc,EACd,aAAa,EACb,eAAe,EACf,WAAW,EACX,WAAW,EACX,aAAa,GAGd,MAAM,cAAc,CAAC;AAEtB;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAiB,EACjB,QAAkB;IAElB,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,iEAAiE;QACjE,6FAA6F;QAC7F,6FAA6F;QAC7F,0EAA0E,EAC1E;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAChE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QACvG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kEAAkE,CAAC;KACtH,EACD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC3B,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,OAAO,eAAe,CAAC,uBAAuB,CAAC,CAAC;QACvE,MAAM,IAAI,GAA4B;YACpC,MAAM,EAAE,kBAAkB;YAC1B,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC;QACF,IAAI,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAC3D,IAAI,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAC3D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE,IAAI,CAA4B,CAAC;QACjF,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,QAAkB,EAClB,UAAuB,MAAM;IAE7B,gFAAgF;IAEhF,MAAM,cAAc,GAAG,CAAC,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,OAAO,CAAC;QAChE,CAAC,CAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAW;QAC9D,CAAC,CAAE,CAAC,MAAM,CAAW,CAAC;IAExB,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,8GAA8G;QAC9G,kGAAkG;QAClG,YAAY,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QACzC,8FAA8F;QAC9F,uDAAuD,EACvD;QACE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,cAAkD,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAChG,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;QACrG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QAChG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;QACxH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;QACxH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACtF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACjF,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;QAChI,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;QACjI,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QAC9F,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;QAC5F,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QAC1F,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;KACrF,EACD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC3B,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,IAAI,CAAC,MAAM,CAAC,SAAS;oBAAE,OAAO,eAAe,CAAC,6BAA6B,CAAC,CAAC;gBAC7E,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;gBAChE,MAAM,IAAI,GAA4B;oBACpC,MAAM,EAAE,cAAc;oBACtB,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;iBAC5D,CAAC;gBACF,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;oBAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;gBACzE,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;oBAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;gBACzE,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;oBAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;gBAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;oBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC7D,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;oBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC7D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAsE,CAAC;gBAC3H,OAAO,aAAa,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACnF,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,MAAM,CAAC,SAAS;oBAAE,OAAO,eAAe,CAAC,+BAA+B,CAAC,CAAC;gBAC/E,IAAI,CAAC,MAAM,CAAC,KAAK;oBAAE,OAAO,eAAe,CAAC,2BAA2B,CAAC,CAAC;gBACvE,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO,eAAe,CAAC,6BAA6B,CAAC,CAAC;gBAC3E,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC9G,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE;oBAC9C,MAAM,EAAE,gBAAgB;oBACxB,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,MAAM;iBACP,CAA0C,CAAC;gBAC5C,OAAO,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,QAAmC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAC1H,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,MAAM,CAAC,UAAU;oBAAE,OAAO,eAAe,CAAC,gCAAgC,CAAC,CAAC;gBACjF,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC9G,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACrC,OAAO,eAAe,CAAC,sCAAsC,CAAC,CAAC;gBACjE,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE;oBAC9C,MAAM,EAAE,gBAAgB;oBACxB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,MAAM;iBACP,CAA0C,CAAC;gBAC5C,OAAO,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,QAAmC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAC1H,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,MAAM,CAAC,UAAU;oBAAE,OAAO,eAAe,CAAC,gCAAgC,CAAC,CAAC;gBACjF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE;oBAC9C,MAAM,EAAE,gBAAgB;oBACxB,UAAU,EAAE,MAAM,CAAC,UAAU;iBAC9B,CAA4B,CAAC;gBAC9B,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;YACD,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,SAAS;oBAAE,OAAO,eAAe,CAAC,gCAAgC,CAAC,CAAC;gBAChF,IAAI,CAAC,MAAM,CAAC,WAAW;oBAAE,OAAO,eAAe,CAAC,kCAAkC,CAAC,CAAC;gBACpF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE;oBAC9C,MAAM,EAAE,iBAAiB;oBACzB,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;iBAChC,CAAkD,CAAC;gBACpD,OAAO,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACzC,CAAC;YACD;gBACE,OAAO,eAAe,CAAC,mBAAmB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,gFAAgF;IAEhF,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CACT,6BAA6B,EAC7B,oFAAoF;YACpF,6GAA6G,EAC7G;YACE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAChE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;YACvD,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YACnF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SACnE,EACD,WAAW,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;YACjE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE;oBAC9C,MAAM,EAAE,cAAc;oBACtB,UAAU;oBACV,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE;iBACjC,CAAsC,CAAC;gBACxC,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE;oBAC9C,MAAM,EAAE,gBAAgB;oBACxB,UAAU;oBACV,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE;iBACjC,CAA4B,CAAC;gBAC9B,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,kGAAkG;IAElG,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
|