@dbx-tools/appkit-graphiti 0.6.127 → 0.6.128

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.
@@ -41,6 +41,7 @@ export declare class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
41
41
  resourceId?: string;
42
42
  }): Promise<unknown>;
43
43
  private forwardMcp;
44
+ private ensureMcpTools;
44
45
  private mcpServer;
45
46
  private onSupervisorExit;
46
47
  private stopSidecars;
package/lib/src/plugin.js CHANGED
@@ -22,7 +22,6 @@ const MCP_PATH = "/api/graphiti/mcp";
22
22
  const MCP_SERVER_IDLE_MS = 30 * 60 * 1000;
23
23
  const MCP_SERVER_SWEEP_MS = 5 * 60 * 1000;
24
24
  const SIDECAR_SHUTDOWN_GRACE_MS = 10_000;
25
- const SIDECAR_STARTUP_TIMEOUT_MS = 10 * 60_000;
26
25
  const SCOPED_TOOL_FIELDS = {
27
26
  add_memory: "group_id",
28
27
  add_triplet: "group_id",
@@ -76,7 +75,8 @@ export class GraphitiPlugin extends Plugin {
76
75
  this.startup = this.startSidecars().catch((error) => {
77
76
  if (this.stopping)
78
77
  return;
79
- this.logger.error("background startup failed; Graphiti remains unavailable", { error });
78
+ this.logger.error("background startup failed", { error });
79
+ process.kill(process.pid, "SIGTERM");
80
80
  });
81
81
  void this.startup;
82
82
  this.logger.info("background startup scheduled");
@@ -126,50 +126,15 @@ export class GraphitiPlugin extends Plugin {
126
126
  prefixColors: false,
127
127
  });
128
128
  this.commands = this.supervision.commands;
129
- void this.supervision.result.then(() => this.onSupervisorExit(), (error) => this.onSupervisorExit(error));
130
- const supervisionFailure = this.supervision.result.then(() => {
131
- throw new Error("Graphiti sidecar supervisor exited during startup");
132
- }, (error) => {
133
- throw error;
134
- });
135
- try {
136
- await Promise.race([
137
- (async () => {
138
- await waitForGraphiti(graphitiPort);
139
- await waitForGraphiti(proxyPort);
140
- })(),
141
- supervisionFailure,
142
- ]);
143
- this.mcp = new MCPClient({
144
- id: `appkit-graphiti-${this.resolved.graphitiPort}`,
145
- servers: {
146
- graphiti: {
147
- url: new URL(`http://127.0.0.1:${this.resolved.proxyPort}/mcp`),
148
- },
149
- },
150
- });
151
- const discovered = await this.mcp.listTools();
152
- this.mcpTools = Object.fromEntries(Object.entries(discovered)
153
- .map(([name, tool]) => [name.replace(/^graphiti_/, ""), tool])
154
- .filter(([name]) => name in SCOPED_TOOL_FIELDS));
155
- const missing = Object.keys(SCOPED_TOOL_FIELDS).filter((name) => !this.mcpTools[name]);
156
- if (missing.length > 0) {
157
- throw new Error(`Graphiti did not publish required scoped tools: ${missing.join(", ")}`);
158
- }
159
- }
160
- catch (error) {
161
- await this.stopSidecars();
162
- throw error;
163
- }
164
129
  this.setupComplete = true;
130
+ void this.supervision.result.then(() => this.onSupervisorExit(), (error) => this.onSupervisorExit(error));
165
131
  this.mcpServerSweep = setInterval(() => this.closeIdleMcpServers(), MCP_SERVER_SWEEP_MS);
166
132
  this.mcpServerSweep.unref();
167
- this.logger.info("ready", {
133
+ this.logger.info("sidecars launched", {
168
134
  graphitiPort: this.resolved.graphitiPort,
169
135
  litellmPort: this.resolved.litellmPort,
170
136
  proxyPort: this.resolved.proxyPort,
171
137
  mcpPath: MCP_PATH,
172
- tools: Object.keys(this.mcpTools),
173
138
  });
174
139
  }
175
140
  injectRoutes(router) {
@@ -193,7 +158,7 @@ export class GraphitiPlugin extends Plugin {
193
158
  return { mcpPath: MCP_PATH };
194
159
  }
195
160
  toolkit() {
196
- return Object.fromEntries(Object.entries(this.mcpTools).map(([name, tool]) => [
161
+ return Object.fromEntries(Object.keys(SCOPED_TOOL_FIELDS).map((name) => [
197
162
  name,
198
163
  {
199
164
  __toolkitRef: true,
@@ -201,8 +166,8 @@ export class GraphitiPlugin extends Plugin {
201
166
  localName: name,
202
167
  def: {
203
168
  name,
204
- description: tool.description,
205
- parameters: tool.inputSchema ?? { type: "object", properties: {} },
169
+ description: `Graphiti ${name.replaceAll("_", " ")}`,
170
+ parameters: { type: "object", properties: {} },
206
171
  },
207
172
  annotations: {
208
173
  effect: WRITE_TOOLS.has(name) ? "write" : "read",
@@ -212,6 +177,7 @@ export class GraphitiPlugin extends Plugin {
212
177
  ]));
213
178
  }
214
179
  async executeAgentTool(name, args, signal, context) {
180
+ await this.ensureMcpTools();
215
181
  const tool = this.mcpTools[name];
216
182
  if (!tool?.execute)
217
183
  throw new Error(`Unknown Graphiti tool: ${name}`);
@@ -221,10 +187,7 @@ export class GraphitiPlugin extends Plugin {
221
187
  });
222
188
  }
223
189
  async forwardMcp(request, response) {
224
- if (!this.resolved) {
225
- response.status(503).json({ error: "Graphiti is not ready" });
226
- return;
227
- }
190
+ await this.ensureMcpTools();
228
191
  const userId = appkitIdentity.requestUserId(request) ?? executionContextUserId();
229
192
  const server = this.mcpServer(userId);
230
193
  await server.startHTTP({
@@ -234,6 +197,26 @@ export class GraphitiPlugin extends Plugin {
234
197
  res: response,
235
198
  });
236
199
  }
200
+ async ensureMcpTools() {
201
+ if (Object.keys(this.mcpTools).length > 0)
202
+ return;
203
+ if (!this.resolved)
204
+ throw new Error("Graphiti sidecars have not launched");
205
+ this.mcp ??= new MCPClient({
206
+ id: `appkit-graphiti-${this.resolved.graphitiPort}`,
207
+ servers: {
208
+ graphiti: { url: new URL(`http://127.0.0.1:${this.resolved.proxyPort}/mcp`) },
209
+ },
210
+ });
211
+ const discovered = await this.mcp.listTools();
212
+ this.mcpTools = Object.fromEntries(Object.entries(discovered)
213
+ .map(([name, tool]) => [name.replace(/^graphiti_/, ""), tool])
214
+ .filter(([name]) => name in SCOPED_TOOL_FIELDS));
215
+ const missing = Object.keys(SCOPED_TOOL_FIELDS).filter((name) => !this.mcpTools[name]);
216
+ if (missing.length > 0) {
217
+ throw new Error(`Graphiti did not publish required scoped tools: ${missing.join(", ")}`);
218
+ }
219
+ }
237
220
  mcpServer(userId) {
238
221
  const existing = this.mcpServers.get(userId);
239
222
  if (existing) {
@@ -363,24 +346,6 @@ function scopedArguments(name, args, scope) {
363
346
  scoped.group_ids = [scope];
364
347
  return scoped;
365
348
  }
366
- async function waitForGraphiti(port) {
367
- for await (const ready of asyncModule.poll(async ({ signal }) => {
368
- try {
369
- const response = await fetch(`http://127.0.0.1:${port}/health`, { signal });
370
- return response.ok;
371
- }
372
- catch {
373
- return false;
374
- }
375
- }, {
376
- intervalMs: 250,
377
- timeoutMs: SIDECAR_STARTUP_TIMEOUT_MS,
378
- predicate: (ready) => !ready,
379
- })) {
380
- if (ready)
381
- return;
382
- }
383
- }
384
349
  async function availablePort() {
385
350
  return new Promise((resolve, reject) => {
386
351
  const server = createServer();
@@ -412,4 +377,4 @@ async function distinctPorts(appPort, graphitiPort, litellmPort, proxyPort) {
412
377
  function commandLine(arguments_) {
413
378
  return arguments_.map((value) => `'${value.replaceAll("'", "'\\''")}'`).join(" ");
414
379
  }
415
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdEMsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixNQUFNLEVBQ04sUUFBUSxFQUNSLFFBQVEsR0FJVCxNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFDTCxNQUFNLElBQUksU0FBUyxFQUNuQixRQUFRLElBQUksY0FBYyxFQUMxQixNQUFNLElBQUksWUFBWSxHQUN2QixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxNQUFNLElBQUksVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzNFLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxvQkFBb0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNuRCxPQUFPLFlBQXVELE1BQU0sY0FBYyxDQUFDO0FBRW5GLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIscUJBQXFCLEdBR3RCLE1BQU0sYUFBYSxDQUFDO0FBRXJCLE1BQU0saUJBQWlCLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO0FBQ3RFLE1BQU0sZUFBZSxH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TyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxLQUFLLFVBQVUsYUFBYSxDQUMxQixPQUFlLEVBQ2YsWUFBb0IsRUFDcEIsV0FBbUIsRUFDbkIsU0FBaUI7SUFFakIsTUFBTSxLQUFLLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN4QixLQUFLLE1BQU0sY0FBYyxJQUFJLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3BFLElBQUksY0FBYyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUNyRCxNQUFNLElBQUksa0JBQWtCLENBQUMsNkRBQTZELENBQUMsQ0FBQztRQUM5RixDQUFDO1FBQ0QsSUFBSSxJQUFJLEdBQUcsY0FBYyxJQUFJLENBQUMsTUFBTSxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3JELE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFBRSxJQUFJLEdBQUcsTUFBTSxhQUFhLEVBQUUsQ0FBQztRQUMxRCxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25CLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUE2QixDQUFDO0FBQ3BELENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxVQUFvQjtJQUN2QyxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBcHBLaXQgcGx1Z2luIHRoYXQgc3VwZXJ2aXNlcyBHcmFwaGl0aSBhbmQgcmVwdWJsaXNoZXMgdXNlci1zY29wZWQgTUNQIHRvb2xzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgZXhlY0ZpbGUgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIgfSBmcm9tIFwibm9kZTpuZXRcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IHByb21pc2lmeSB9IGZyb20gXCJub2RlOnV0aWxcIjtcbmltcG9ydCB7XG4gIENvbmZpZ3VyYXRpb25FcnJvcixcbiAgUGx1Z2luLFxuICBsYWtlYmFzZSxcbiAgdG9QbHVnaW4sXG4gIHR5cGUgSUFwcFJvdXRlcixcbiAgdHlwZSBQbHVnaW5NYW5pZmVzdCxcbiAgdHlwZSBSZXNvdXJjZVJlcXVpcmVtZW50LFxufSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQge1xuICBhcHBraXQgYXMgZGJ4QXBwa2l0LFxuICBpZGVudGl0eSBhcyBhcHBraXRJZGVudGl0eSxcbiAgcGx1Z2luIGFzIGFwcGtpdFBsdWdpbixcbn0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgeyBjb25maWcgYXMgY29yZUNvbmZpZyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IGFzeW5jIGFzIGFzeW5jTW9kdWxlLCBsb2csIG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBjcmVhdGVUb29sLCB0eXBlIFRvb2wgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL3Rvb2xzXCI7XG5pbXBvcnQgeyBNQ1BDbGllbnQsIE1DUFNlcnZlciB9IGZyb20gXCJAbWFzdHJhL21jcFwiO1xuaW1wb3J0IGNvbmN1cnJlbnRseSwgeyB0eXBlIENvbW1hbmQsIHR5cGUgQ29uY3VycmVudGx5UmVzdWx0IH0gZnJvbSBcImNvbmN1cnJlbnRseVwiO1xuaW1wb3J0IHR5cGUgZXhwcmVzcyBmcm9tIFwiZXhwcmVzc1wiO1xuaW1wb3J0IHtcbiAgR1JBUEhJVElfQ09ORklHX1NDSEVNQSxcbiAgcmVzb2x2ZUdyYXBoaXRpQ29uZmlnLFxuICB0eXBlIEdyYXBoaXRpUGx1Z2luQ29uZmlnLFxuICB0eXBlIFJlc29sdmVkR3JhcGhpdGlQbHVnaW5Db25maWcsXG59IGZyb20gXCIuL2NvbmZpZy50c1wiO1xuXG5jb25zdCBMQUtFQkFTRV9NQU5JRkVTVCA9IGFwcGtpdFBsdWdpbi5kYXRhKGxha2ViYXNlKS5wbHVnaW4ubWFuaWZlc3Q7XG5jb25zdCBQQUNLQUdFX1ZFUlNJT04gPSAoXG4gIGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKShcIkBkYngtdG9vbHMvYXBwa2l0LWdyYXBoaXRpL3BhY2thZ2UuanNvblwiKSBhcyB7IHZlcnNpb246IHN0cmluZyB9XG4pLnZlcnNpb247XG5jb25zdCBNQ1BfUEFUSCA9IFwiL2FwaS9ncmFwaGl0aS9tY3BcIjtcbmNvbnN0IE1DUF9TRVJWRVJfSURMRV9NUyA9IDMwICogNjAgKiAxMDAwO1xuY29uc3QgTUNQX1NFUlZFUl9TV0VFUF9NUyA9IDUgKiA2MCAqIDEwMDA7XG5jb25zdCBTSURFQ0FSX1NIVVRET1dOX0dSQUNFX01TID0gMTBfMDAwO1xuY29uc3QgU0lERUNBUl9TVEFSVFVQX1RJTUVPVVRfTVMgPSAxMCAqIDYwXzAwMDtcbmNvbnN0IFNDT1BFRF9UT09MX0ZJRUxEUyA9IHtcbiAgYWRkX21lbW9yeTogXCJncm91cF9pZFwiLFxuICBhZGRfdHJpcGxldDogXCJncm91cF9pZFwiLFxuICBidWlsZF9jb21tdW5pdGllczogXCJncm91cF9pZHNcIixcbiAgZ2V0X2VwaXNvZGVzOiBcImdyb3VwX2lkc1wiLFxuICBnZXRfc3RhdHVzOiB1bmRlZmluZWQsXG4gIHNlYXJjaF9tZW1vcnlfZmFjdHM6IFwiZ3JvdXBfaWRzXCIsXG4gIHNlYXJjaF9ub2RlczogXCJncm91cF9pZHNcIixcbiAgc3VtbWFyaXplX3NhZ2E6IFwiZ3JvdXBfaWRcIixcbn0gYXMgY29uc3Q7XG5jb25zdCBXUklURV9UT09MUyA9IG5ldyBTZXQoW1wiYWRkX21lbW9yeVwiLCBcImFkZF90cmlwbGV0XCIsIFwiYnVpbGRfY29tbXVuaXRpZXNcIiwgXCJzdW1tYXJpemVfc2FnYVwiXSk7XG5jb25zdCBVTlNDT1BFRF9BUkdVTUVOVFMgPSBbXG4gIFwiY2VudGVyX25vZGVfdXVpZFwiLFxuICBcInByZXZpb3VzX2VwaXNvZGVfdXVpZHNcIixcbiAgXCJzYWdhX3ByZXZpb3VzX2VwaXNvZGVfdXVpZFwiLFxuICBcInNvdXJjZV9ub2RlX3V1aWRcIixcbiAgXCJ0YXJnZXRfbm9kZV91dWlkXCIsXG4gIFwidXVpZFwiLFxuXSBhcyBjb25zdDtcblxuaW50ZXJmYWNlIFRvb2xraXRFbnRyeSB7XG4gIHJlYWRvbmx5IF9fdG9vbGtpdFJlZjogdHJ1ZTtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBsb2NhbE5hbWU6IHN0cmluZztcbiAgZGVmOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgcGFyYW1ldGVyczogdW5rbm93bjtcbiAgfTtcbiAgYW5ub3RhdGlvbnM6IHtcbiAgICBlZmZlY3Q6IFwicmVhZFwiIHwgXCJ3cml0ZVwiO1xuICAgIHJlcXVpcmVzVXNlckNvbnRleHQ6IHRydWU7XG4gIH07XG59XG5cbmludGVyZmFjZSBVc2VyTWNwU2VydmVyIHtcbiAgbGFzdFVzZWQ6IG51bWJlcjtcbiAgc2VydmVyOiBNQ1BTZXJ2ZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBHcmFwaGl0aVBsdWdpbiBleHRlbmRzIFBsdWdpbjxHcmFwaGl0aVBsdWdpbkNvbmZpZz4ge1xuICBzdGF0aWMgbWFuaWZlc3Q6IFBsdWdpbk1hbmlmZXN0PFwiZ3JhcGhpdGlcIj4gPSB7XG4gICAgbmFtZTogXCJncmFwaGl0aVwiLFxuICAgIGRpc3BsYXlOYW1lOiBcIkdyYXBoaXRpXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlJ1bnMgdGhlIGRieC10b29scyBHcmFwaGl0aSBNQ1Agc2lkZWNhciB3aXRoIExha2ViYXNlLWJhY2tlZCByZWNvdmVyeSBhbmQgXCIgK1xuICAgICAgXCJwdWJsaXNoZXMgaXQgdGhyb3VnaCB0aGUgQXBwJ3Mgc2luZ2xlIHBvcnQgd2l0aCBDYWRkeS5cIixcbiAgICBzdGFiaWxpdHk6IFwiYmV0YVwiLFxuICAgIHJlc291cmNlczoge1xuICAgICAgcmVxdWlyZWQ6IFtdLFxuICAgICAgb3B0aW9uYWw6IFsuLi5MQUtFQkFTRV9NQU5JRkVTVC5yZXNvdXJjZXMucmVxdWlyZWRdLFxuICAgIH0sXG4gICAgY29uZmlnOiB7IHNjaGVtYTogR1JBUEhJVElfQ09ORklHX1NDSEVNQSB9LFxuICB9O1xuXG4gIHN0YXRpYyBnZXRSZXNvdXJjZVJlcXVpcmVtZW50cygpOiBSZXNvdXJjZVJlcXVpcmVtZW50W10ge1xuICAgIHJldHVybiBMQUtFQkFTRV9NQU5JRkVTVC5yZXNvdXJjZXMucmVxdWlyZWQubWFwKChyZXNvdXJjZSkgPT4gKHtcbiAgICAgIC4uLnJlc291cmNlLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXIgPSBsb2cubG9nZ2VyKHRoaXMpO1xuICBwcml2YXRlIGNvbW1hbmRzOiBDb21tYW5kW10gPSBbXTtcbiAgcHJpdmF0ZSBtY3A/OiBNQ1BDbGllbnQ7XG4gIHByaXZhdGUgbWNwU2VydmVycyA9IG5ldyBNYXA8c3RyaW5nLCBVc2VyTWNwU2VydmVyPigpO1xuICBwcml2YXRlIG1jcFNlcnZlclN3ZWVwPzogTm9kZUpTLlRpbWVvdXQ7XG4gIHByaXZhdGUgbWNwVG9vbHM6IFJlY29yZDxzdHJpbmcsIFRvb2w+ID0ge307XG4gIHByaXZhdGUgcmVzb2x2ZWQ/OiBSZXNvbHZlZEdyYXBoaXRpUGx1Z2luQ29uZmlnO1xuICBwcml2YXRlIHNldHVwQ29tcGxldGUgPSBmYWxzZTtcbiAgcHJpdmF0ZSBzdGFydHVwPzogUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBzdXBlcnZpc2lvbj86IENvbmN1cnJlbnRseVJlc3VsdDtcbiAgcHJpdmF0ZSBzdG9wcGluZyA9IGZhbHNlO1xuXG4gIG92ZXJyaWRlIGFzeW5jIHNldHVwKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RhcnR1cCA9IHRoaXMuc3RhcnRTaWRlY2FycygpLmNhdGNoKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgaWYgKHRoaXMuc3RvcHBpbmcpIHJldHVybjtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFwiYmFja2dyb3VuZCBzdGFydHVwIGZhaWxlZDsgR3JhcGhpdGkgcmVtYWlucyB1bmF2YWlsYWJsZVwiLCB7IGVycm9yIH0pO1xuICAgIH0pO1xuICAgIHZvaWQgdGhpcy5zdGFydHVwO1xuICAgIHRoaXMubG9nZ2VyLmluZm8oXCJiYWNrZ3JvdW5kIHN0YXJ0dXAgc2NoZWR1bGVkXCIpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzdGFydFNpZGVjYXJzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbmZpZ3VyZWQgPSByZXNvbHZlR3JhcGhpdGlDb25maWcodGhpcy5jb25maWcpO1xuICAgIGNvbnN0IFtncmFwaGl0aVBvcnQsIGxpdGVsbG1Qb3J0LCBwcm94eVBvcnRdID0gYXdhaXQgZGlzdGluY3RQb3J0cyhcbiAgICAgIGNvcmVDb25maWcucG9ydCh1bmRlZmluZWQsIFwiREFUQUJSSUNLU19BUFBfUE9SVFwiLCA4MDAwLCBjb3JlQ29uZmlnLkVOVl9PTkxZKSxcbiAgICAgIGNvbmZpZ3VyZWQuZ3JhcGhpdGlQb3J0LFxuICAgICAgY29uZmlndXJlZC5saXRlbGxtUG9ydCxcbiAgICAgIGNvbmZpZ3VyZWQucHJveHlQb3J0LFxuICAgICk7XG4gICAgYXdhaXQgZW5zdXJlR3JhcGhpdGlQeXRob24oY29uZmlndXJlZC5weXRob24pO1xuICAgIHRoaXMucmVzb2x2ZWQgPSB7XG4gICAgICAuLi5jb25maWd1cmVkLFxuICAgICAgZ3JhcGhpdGlQb3J0LFxuICAgICAgbGl0ZWxsbVBvcnQsXG4gICAgICBwcm94eVBvcnQsXG4gICAgfTtcbiAgICB0aGlzLnN1cGVydmlzaW9uID0gY29uY3VycmVudGx5KFxuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJncmFwaGl0aVwiLFxuICAgICAgICAgIGNvbW1hbmQ6IGNvbW1hbmRMaW5lKFt0aGlzLnJlc29sdmVkLnB5dGhvbiwgXCItbVwiLCBcImRieF90b29scy5ncmFwaGl0aVwiLCBcInN0YXJ0XCJdKSxcbiAgICAgICAgICBlbnY6IHtcbiAgICAgICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICAgICAgR1JBUEhJVElfSE9TVDogXCIxMjcuMC4wLjFcIixcbiAgICAgICAgICAgIEdSQVBISVRJX1BPUlQ6IFN0cmluZyh0aGlzLnJlc29sdmVkLmdyYXBoaXRpUG9ydCksXG4gICAgICAgICAgICBKT1VSTkFMX05BTUVTUEFDRTogdGhpcy5yZXNvbHZlZC5qb3VybmFsTmFtZXNwYWNlLFxuICAgICAgICAgICAgTElURUxMTV9IT1NUOiBcIjEyNy4wLjAuMVwiLFxuICAgICAgICAgICAgTElURUxMTV9QT1JUOiBTdHJpbmcodGhpcy5yZXNvbHZlZC5saXRlbGxtUG9ydCksXG4gICAgICAgICAgICBNQU5BR0VfTElURUxMTTogXCJ0cnVlXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY2FkZHlcIixcbiAgICAgICAgICBjb21tYW5kOiBjb21tYW5kTGluZShbXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVkLnB5dGhvbixcbiAgICAgICAgICAgIFwiLW1cIixcbiAgICAgICAgICAgIFwiZGJ4X3Rvb2xzLmdyYXBoaXRpLnByb3h5XCIsXG4gICAgICAgICAgICBcIi0tcHJveHktcG9ydFwiLFxuICAgICAgICAgICAgU3RyaW5nKHRoaXMucmVzb2x2ZWQucHJveHlQb3J0KSxcbiAgICAgICAgICAgIFwiLS1ncmFwaGl0aS1wb3J0XCIsXG4gICAgICAgICAgICBTdHJpbmcodGhpcy5yZXNvbHZlZC5ncmFwaGl0aVBvcnQpLFxuICAgICAgICAgIF0pLFxuICAgICAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAge1xuICAgICAgICBraWxsT3RoZXJzT246IFtcImZhaWx1cmVcIiwgXCJzdWNjZXNzXCJdLFxuICAgICAgICBraWxsU2lnbmFsOiBcIlNJR1RFUk1cIixcbiAgICAgICAga2lsbFRpbWVvdXQ6IFNJREVDQVJfU0hVVERPV05fR1JBQ0VfTVMsXG4gICAgICAgIHByZWZpeDogXCJuYW1lXCIsXG4gICAgICAgIHByZWZpeENvbG9yczogZmFsc2UsXG4gICAgICB9LFxuICAgICk7XG4gICAgdGhpcy5jb21tYW5kcyA9IHRoaXMuc3VwZXJ2aXNpb24uY29tbWFuZHM7XG4gICAgdm9pZCB0aGlzLnN1cGVydmlzaW9uLnJlc3VsdC50aGVuKFxuICAgICAgKCkgPT4gdGhpcy5vblN1cGVydmlzb3JFeGl0KCksXG4gICAgICAoZXJyb3IpID0+IHRoaXMub25TdXBlcnZpc29yRXhpdChlcnJvciksXG4gICAgKTtcbiAgICBjb25zdCBzdXBlcnZpc2lvbkZhaWx1cmUgPSB0aGlzLnN1cGVydmlzaW9uLnJlc3VsdC50aGVuKFxuICAgICAgKCkgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJHcmFwaGl0aSBzaWRlY2FyIHN1cGVydmlzb3IgZXhpdGVkIGR1cmluZyBzdGFydHVwXCIpO1xuICAgICAgfSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0sXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCB3YWl0Rm9yR3JhcGhpdGkoZ3JhcGhpdGlQb3J0KTtcbiAgICAgICAgICBhd2FpdCB3YWl0Rm9yR3JhcGhpdGkocHJveHlQb3J0KTtcbiAgICAgICAgfSkoKSxcbiAgICAgICAgc3VwZXJ2aXNpb25GYWlsdXJlLFxuICAgICAgXSk7XG4gICAgICB0aGlzLm1jcCA9IG5ldyBNQ1BDbGllbnQoe1xuICAgICAgICBpZDogYGFwcGtpdC1ncmFwaGl0aS0ke3RoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0fWAsXG4gICAgICAgIHNlcnZlcnM6IHtcbiAgICAgICAgICBncmFwaGl0aToge1xuICAgICAgICAgICAgdXJsOiBuZXcgVVJMKGBodHRwOi8vMTI3LjAuMC4xOiR7dGhpcy5yZXNvbHZlZC5wcm94eVBvcnR9L21jcGApLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGRpc2NvdmVyZWQgPSBhd2FpdCB0aGlzLm1jcC5saXN0VG9vbHMoKTtcbiAgICAgIHRoaXMubWNwVG9vbHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKGRpc2NvdmVyZWQpXG4gICAgICAgICAgLm1hcCgoW25hbWUsIHRvb2xdKSA9PiBbbmFtZS5yZXBsYWNlKC9eZ3JhcGhpdGlfLywgXCJcIiksIHRvb2wgYXMgVG9vbF0gYXMgY29uc3QpXG4gICAgICAgICAgLmZpbHRlcigoW25hbWVdKSA9PiBuYW1lIGluIFNDT1BFRF9UT09MX0ZJRUxEUyksXG4gICAgICApO1xuICAgICAgY29uc3QgbWlzc2luZyA9IE9iamVjdC5rZXlzKFNDT1BFRF9UT09MX0ZJRUxEUykuZmlsdGVyKChuYW1lKSA9PiAhdGhpcy5tY3BUb29sc1tuYW1lXSk7XG4gICAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgR3JhcGhpdGkgZGlkIG5vdCBwdWJsaXNoIHJlcXVpcmVkIHNjb3BlZCB0b29sczogJHttaXNzaW5nLmpvaW4oXCIsIFwiKX1gKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5zdG9wU2lkZWNhcnMoKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgICB0aGlzLnNldHVwQ29tcGxldGUgPSB0cnVlO1xuICAgIHRoaXMubWNwU2VydmVyU3dlZXAgPSBzZXRJbnRlcnZhbCgoKSA9PiB0aGlzLmNsb3NlSWRsZU1jcFNlcnZlcnMoKSwgTUNQX1NFUlZFUl9TV0VFUF9NUyk7XG4gICAgdGhpcy5tY3BTZXJ2ZXJTd2VlcC51bnJlZigpO1xuICAgIHRoaXMubG9nZ2VyLmluZm8oXCJyZWFkeVwiLCB7XG4gICAgICBncmFwaGl0aVBvcnQ6IHRoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0LFxuICAgICAgbGl0ZWxsbVBvcnQ6IHRoaXMucmVzb2x2ZWQubGl0ZWxsbVBvcnQsXG4gICAgICBwcm94eVBvcnQ6IHRoaXMucmVzb2x2ZWQucHJveHlQb3J0LFxuICAgICAgbWNwUGF0aDogTUNQX1BBVEgsXG4gICAgICB0b29sczogT2JqZWN0LmtleXModGhpcy5tY3BUb29scyksXG4gICAgfSk7XG4gIH1cblxuICBvdmVycmlkZSBpbmplY3RSb3V0ZXMocm91dGVyOiBJQXBwUm91dGVyKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBtZXRob2Qgb2YgW1wiZ2V0XCIsIFwicG9zdFwiLCBcImRlbGV0ZVwiXSBhcyBjb25zdCkge1xuICAgICAgdGhpcy5yb3V0ZShyb3V0ZXIsIHtcbiAgICAgICAgbmFtZTogYCR7bWV0aG9kfU1jcGAsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgcGF0aDogXCIvbWNwXCIsXG4gICAgICAgIGhhbmRsZXI6IChyZXF1ZXN0LCByZXNwb25zZSkgPT4gdGhpcy5mb3J3YXJkTWNwKHJlcXVlc3QsIHJlc3BvbnNlKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG92ZXJyaWRlIGFib3J0QWN0aXZlT3BlcmF0aW9ucygpOiB2b2lkIHtcbiAgICBzdXBlci5hYm9ydEFjdGl2ZU9wZXJhdGlvbnMoKTtcbiAgICB2b2lkIHRoaXMubWNwPy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICBhc3luYyBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnN0b3BTaWRlY2FycygpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZXhwb3J0cygpIHtcbiAgICByZXR1cm4geyBtY3BQYXRoOiBNQ1BfUEFUSCB9O1xuICB9XG5cbiAgdG9vbGtpdCgpOiBSZWNvcmQ8c3RyaW5nLCBUb29sa2l0RW50cnk+IHtcbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5tY3BUb29scykubWFwKChbbmFtZSwgdG9vbF0pID0+IFtcbiAgICAgICAgbmFtZSxcbiAgICAgICAge1xuICAgICAgICAgIF9fdG9vbGtpdFJlZjogdHJ1ZSBhcyBjb25zdCxcbiAgICAgICAgICBwbHVnaW5OYW1lOiBcImdyYXBoaXRpXCIsXG4gICAgICAgICAgbG9jYWxOYW1lOiBuYW1lLFxuICAgICAgICAgIGRlZjoge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0b29sLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogdG9vbC5pbnB1dFNjaGVtYSA/PyB7IHR5cGU6IFwib2JqZWN0XCIsIHByb3BlcnRpZXM6IHt9IH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBhbm5vdGF0aW9uczoge1xuICAgICAgICAgICAgZWZmZWN0OiBXUklURV9UT09MUy5oYXMobmFtZSkgPyAoXCJ3cml0ZVwiIGFzIGNvbnN0KSA6IChcInJlYWRcIiBhcyBjb25zdCksXG4gICAgICAgICAgICByZXF1aXJlc1VzZXJDb250ZXh0OiB0cnVlIGFzIGNvbnN0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdKSxcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZUFnZW50VG9vbChcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgYXJnczogdW5rbm93bixcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgICBjb250ZXh0PzogeyByZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gICk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLm1jcFRvb2xzW25hbWVdO1xuICAgIGlmICghdG9vbD8uZXhlY3V0ZSkgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIEdyYXBoaXRpIHRvb2w6ICR7bmFtZX1gKTtcbiAgICBjb25zdCB1c2VySWQgPSBjb250ZXh0Py5yZXNvdXJjZUlkID8/IGV4ZWN1dGlvbkNvbnRleHRVc2VySWQoKTtcbiAgICByZXR1cm4gdG9vbC5leGVjdXRlKHNjb3BlZEFyZ3VtZW50cyhuYW1lLCBhcmdzLCB1c2VyU2NvcGUodXNlcklkKSksIHtcbiAgICAgIGFib3J0U2lnbmFsOiBzaWduYWwsXG4gICAgfSBhcyBuZXZlcik7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZvcndhcmRNY3AocmVxdWVzdDogZXhwcmVzcy5SZXF1ZXN0LCByZXNwb25zZTogZXhwcmVzcy5SZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5yZXNvbHZlZCkge1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzKDUwMykuanNvbih7IGVycm9yOiBcIkdyYXBoaXRpIGlzIG5vdCByZWFkeVwiIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB1c2VySWQgPSBhcHBraXRJZGVudGl0eS5yZXF1ZXN0VXNlcklkKHJlcXVlc3QpID8/IGV4ZWN1dGlvbkNvbnRleHRVc2VySWQoKTtcbiAgICBjb25zdCBzZXJ2ZXIgPSB0aGlzLm1jcFNlcnZlcih1c2VySWQpO1xuICAgIGF3YWl0IHNlcnZlci5zdGFydEhUVFAoe1xuICAgICAgdXJsOiBuZXcgVVJMKHJlcXVlc3Qub3JpZ2luYWxVcmwsIFwiaHR0cDovL2FwcC5sb2NhbFwiKSxcbiAgICAgIGh0dHBQYXRoOiBNQ1BfUEFUSCxcbiAgICAgIHJlcTogcmVxdWVzdCxcbiAgICAgIHJlczogcmVzcG9uc2UsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG1jcFNlcnZlcih1c2VySWQ6IHN0cmluZyk6IE1DUFNlcnZlciB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLm1jcFNlcnZlcnMuZ2V0KHVzZXJJZCk7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICBleGlzdGluZy5sYXN0VXNlZCA9IERhdGUubm93KCk7XG4gICAgICByZXR1cm4gZXhpc3Rpbmcuc2VydmVyO1xuICAgIH1cbiAgICBjb25zdCBzY29wZSA9IHVzZXJTY29wZSh1c2VySWQpO1xuICAgIGNvbnN0IHRvb2xzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5tY3BUb29scykubWFwKChbbmFtZSwgdG9vbF0pID0+IFtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY3JlYXRlVG9vbCh7XG4gICAgICAgICAgaWQ6IG5hbWUsXG4gICAgICAgICAgZGVzY3JpcHRpb246IHRvb2wuZGVzY3JpcHRpb24gPz8gbmFtZSxcbiAgICAgICAgICAuLi4odG9vbC5pbnB1dFNjaGVtYSA/IHsgaW5wdXRTY2hlbWE6IHRvb2wuaW5wdXRTY2hlbWEgYXMgbmV2ZXIgfSA6IHt9KSxcbiAgICAgICAgICBleGVjdXRlOiAoYXJnczogdW5rbm93biwgY29udGV4dDogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgaWYgKCF0b29sLmV4ZWN1dGUpIHRocm93IG5ldyBFcnJvcihgR3JhcGhpdGkgdG9vbCBjYW5ub3QgZXhlY3V0ZTogJHtuYW1lfWApO1xuICAgICAgICAgICAgcmV0dXJuIHRvb2wuZXhlY3V0ZShzY29wZWRBcmd1bWVudHMobmFtZSwgYXJncywgc2NvcGUpLCBjb250ZXh0IGFzIG5ldmVyKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIF0pLFxuICAgICk7XG4gICAgY29uc3Qgc2VydmVyID0gbmV3IE1DUFNlcnZlcih7XG4gICAgICBuYW1lOiBcIkdyYXBoaXRpXCIsXG4gICAgICB2ZXJzaW9uOiBcIjEuMC4wXCIsXG4gICAgICB0b29scyxcbiAgICB9KTtcbiAgICB0aGlzLm1jcFNlcnZlcnMuc2V0KHVzZXJJZCwgeyBsYXN0VXNlZDogRGF0ZS5ub3coKSwgc2VydmVyIH0pO1xuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICBwcml2YXRlIG9uU3VwZXJ2aXNvckV4aXQoZXJyb3I/OiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RvcHBpbmcgfHwgIXRoaXMuc2V0dXBDb21wbGV0ZSkgcmV0dXJuO1xuICAgIHRoaXMubG9nZ2VyLmVycm9yKFwic2lkZWNhciBzdXBlcnZpc29yIGV4aXRlZFwiLCB7IGVycm9yIH0pO1xuICAgIHByb2Nlc3Mua2lsbChwcm9jZXNzLnBpZCwgXCJTSUdURVJNXCIpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzdG9wU2lkZWNhcnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuc3RvcHBpbmcpIHJldHVybjtcbiAgICB0aGlzLnN0b3BwaW5nID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5tY3BTZXJ2ZXJTd2VlcCkgY2xlYXJJbnRlcnZhbCh0aGlzLm1jcFNlcnZlclN3ZWVwKTtcbiAgICB0aGlzLm1jcFNlcnZlclN3ZWVwID0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGNvbW1hbmRzID0gdGhpcy5jb21tYW5kcztcbiAgICBjb25zdCBzdXBlcnZpc2lvbiA9IHRoaXMuc3VwZXJ2aXNpb247XG4gICAgZm9yIChjb25zdCBjb21tYW5kIG9mIGNvbW1hbmRzKSBjb21tYW5kLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIGNvbnN0IGNsZWFudXAgPSBQcm9taXNlLmFsbFNldHRsZWQoW1xuICAgICAgLi4uWy4uLnRoaXMubWNwU2VydmVycy52YWx1ZXMoKV0ubWFwKCh7IHNlcnZlciB9KSA9PiBzZXJ2ZXIuY2xvc2UoKSksXG4gICAgICB0aGlzLm1jcD8uZGlzY29ubmVjdCgpLFxuICAgICAgc3VwZXJ2aXNpb24/LnJlc3VsdCxcbiAgICBdKTtcbiAgICBjb25zdCBjb21wbGV0ZWQgPSBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgY2xlYW51cC50aGVuKCgpID0+IHRydWUpLFxuICAgICAgYXN5bmNNb2R1bGUuc2xlZXAoU0lERUNBUl9TSFVURE9XTl9HUkFDRV9NUykudGhlbigoKSA9PiBmYWxzZSksXG4gICAgXSk7XG4gICAgaWYgKCFjb21wbGV0ZWQpIHtcbiAgICAgIHRoaXMubG9nZ2VyLndhcm4oXCJzaWRlY2FycyBpZ25vcmVkIFNJR1RFUk07IGVzY2FsYXRpbmcgdG8gU0lHS0lMTFwiKTtcbiAgICAgIGZvciAoY29uc3QgY29tbWFuZCBvZiBjb21tYW5kcykgY29tbWFuZC5raWxsKFwiU0lHS0lMTFwiKTtcbiAgICB9XG4gICAgdGhpcy5tY3BTZXJ2ZXJzLmNsZWFyKCk7XG4gICAgdGhpcy5tY3AgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5tY3BUb29scyA9IHt9O1xuICAgIHRoaXMuY29tbWFuZHMgPSBbXTtcbiAgICB0aGlzLnN1cGVydmlzaW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc3RhcnR1cCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VJZGxlTWNwU2VydmVycygpOiB2b2lkIHtcbiAgICBjb25zdCBjdXRvZmYgPSBEYXRlLm5vdygpIC0gTUNQX1NFUlZFUl9JRExFX01TO1xuICAgIGZvciAoY29uc3QgW3VzZXJJZCwgZW50cnldIG9mIHRoaXMubWNwU2VydmVycykge1xuICAgICAgaWYgKGVudHJ5Lmxhc3RVc2VkID49IGN1dG9mZikgY29udGludWU7XG4gICAgICB0aGlzLm1jcFNlcnZlcnMuZGVsZXRlKHVzZXJJZCk7XG4gICAgICB2b2lkIGVudHJ5LnNlcnZlci5jbG9zZSgpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlci53YXJuKFwiaWRsZSBNQ1Agc2VydmVyIGNsb3NlIGZhaWxlZFwiLCB7IGVycm9yIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbnR5cGUgRXhlY1B5dGhvbiA9IChmaWxlOiBzdHJpbmcsIGFyZ3M6IHN0cmluZ1tdKSA9PiBQcm9taXNlPHVua25vd24+O1xuXG4vKiogRW5zdXJlIERhdGFicmlja3MgQXBwcyBoYXMgdGhlIFB5dGhvbiBzaWRlY2FyIG1hdGNoaW5nIHRoaXMgTm9kZSBwYWNrYWdlLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuc3VyZUdyYXBoaXRpUHl0aG9uKFxuICBweXRob246IHN0cmluZyxcbiAgcnVuOiBFeGVjUHl0aG9uID0gKGZpbGUsIGFyZ3MpID0+IHByb21pc2lmeShleGVjRmlsZSkoZmlsZSwgYXJncyksXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBydW4ocHl0aG9uLCBbXCItY1wiLCBcImltcG9ydCBkYnhfdG9vbHMuZ3JhcGhpdGlcIl0pO1xuICB9IGNhdGNoIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcnVuKHB5dGhvbiwgW1wiLW1cIiwgXCJwaXBcIiwgXCItLXZlcnNpb25cIl0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgYXdhaXQgcnVuKHB5dGhvbiwgW1xuICAgICAgICBcIi1jXCIsXG4gICAgICAgIFwiaW1wb3J0IHVybGxpYi5yZXF1ZXN0OyBleGVjKHVybGxpYi5yZXF1ZXN0LnVybG9wZW4oJ2h0dHBzOi8vYm9vdHN0cmFwLnB5cGEuaW8vZ2V0LXBpcC5weScpLnJlYWQoKSlcIixcbiAgICAgICAgXCItLXVzZXJcIixcbiAgICAgICAgXCItLWJyZWFrLXN5c3RlbS1wYWNrYWdlc1wiLFxuICAgICAgXSk7XG4gICAgfVxuICAgIGF3YWl0IHJ1bihweXRob24sIFtcbiAgICAgIFwiLW1cIixcbiAgICAgIFwicGlwXCIsXG4gICAgICBcImluc3RhbGxcIixcbiAgICAgIFwiLS1kaXNhYmxlLXBpcC12ZXJzaW9uLWNoZWNrXCIsXG4gICAgICBcIi0tdXNlclwiLFxuICAgICAgXCItLWJyZWFrLXN5c3RlbS1wYWNrYWdlc1wiLFxuICAgICAgYGRieC10b29scy1ncmFwaGl0aT09JHtQQUNLQUdFX1ZFUlNJT059YCxcbiAgICBdKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZ3JhcGhpdGkgPSB0b1BsdWdpbihHcmFwaGl0aVBsdWdpbik7XG5cbmZ1bmN0aW9uIGV4ZWN1dGlvbkNvbnRleHRVc2VySWQoKTogc3RyaW5nIHtcbiAgY29uc3QgY29udGV4dCA9IGRieEFwcGtpdC50cnlHZXRFeGVjdXRpb25Db250ZXh0KCk7XG4gIGlmICghY29udGV4dCkgdGhyb3cgbmV3IEVycm9yKFwiR3JhcGhpdGkgbWVtb3J5IHJlcXVpcmVzIGFuIEFwcEtpdCBleGVjdXRpb24gY29udGV4dFwiKTtcbiAgcmV0dXJuIFwidXNlcklkXCIgaW4gY29udGV4dCA/IGNvbnRleHQudXNlcklkIDogY29udGV4dC5zZXJ2aWNlVXNlcklkO1xufVxuXG5mdW5jdGlvbiB1c2VyU2NvcGUodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYHVzZXJfJHtjcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZSh1c2VySWQpLmRpZ2VzdChcImJhc2U2NHVybFwiKX1gO1xufVxuXG5mdW5jdGlvbiBzY29wZWRBcmd1bWVudHMobmFtZTogc3RyaW5nLCBhcmdzOiB1bmtub3duLCBzY29wZTogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICBpZiAoIShuYW1lIGluIFNDT1BFRF9UT09MX0ZJRUxEUykpIHRocm93IG5ldyBFcnJvcihgR3JhcGhpdGkgdG9vbCBpcyBub3QgdXNlci1zY29wZWQ6ICR7bmFtZX1gKTtcbiAgY29uc3Qgc2NvcGVkID0gb2JqZWN0LmlzUmVjb3JkKGFyZ3MpID8geyAuLi5hcmdzIH0gOiB7fTtcbiAgZm9yIChjb25zdCBhcmd1bWVudCBvZiBVTlNDT1BFRF9BUkdVTUVOVFMpIGRlbGV0ZSBzY29wZWRbYXJndW1lbnRdO1xuICBjb25zdCBmaWVsZCA9IFNDT1BFRF9UT09MX0ZJRUxEU1tuYW1lIGFzIGtleW9mIHR5cGVvZiBTQ09QRURfVE9PTF9GSUVMRFNdO1xuICBpZiAoZmllbGQgPT09IFwiZ3JvdXBfaWRcIikgc2NvcGVkLmdyb3VwX2lkID0gc2NvcGU7XG4gIGlmIChmaWVsZCA9PT0gXCJncm91cF9pZHNcIikgc2NvcGVkLmdyb3VwX2lkcyA9IFtzY29wZV07XG4gIHJldHVybiBzY29wZWQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHdhaXRGb3JHcmFwaGl0aShwb3J0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgZm9yIGF3YWl0IChjb25zdCByZWFkeSBvZiBhc3luY01vZHVsZS5wb2xsKFxuICAgIGFzeW5jICh7IHNpZ25hbCB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGBodHRwOi8vMTI3LjAuMC4xOiR7cG9ydH0vaGVhbHRoYCwgeyBzaWduYWwgfSk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5vaztcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICBpbnRlcnZhbE1zOiAyNTAsXG4gICAgICB0aW1lb3V0TXM6IFNJREVDQVJfU1RBUlRVUF9USU1FT1VUX01TLFxuICAgICAgcHJlZGljYXRlOiAocmVhZHkpID0+ICFyZWFkeSxcbiAgICB9LFxuICApKSB7XG4gICAgaWYgKHJlYWR5KSByZXR1cm47XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gYXZhaWxhYmxlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigpO1xuICAgIHNlcnZlci5vbmNlKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICBzZXJ2ZXIubGlzdGVuKDAsIFwiMTI3LjAuMC4xXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgaWYgKCFhZGRyZXNzIHx8IHR5cGVvZiBhZGRyZXNzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKFwiQ291bGQgbm90IGFsbG9jYXRlIGEgR3JhcGhpdGkgbG9vcGJhY2sgcG9ydFwiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlcnZlci5jbG9zZSgoZXJyb3IpID0+IChlcnJvciA/IHJlamVjdChlcnJvcikgOiByZXNvbHZlKGFkZHJlc3MucG9ydCkpKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRpc3RpbmN0UG9ydHMoXG4gIGFwcFBvcnQ6IG51bWJlcixcbiAgZ3JhcGhpdGlQb3J0OiBudW1iZXIsXG4gIGxpdGVsbG1Qb3J0OiBudW1iZXIsXG4gIHByb3h5UG9ydDogbnVtYmVyLFxuKTogUHJvbWlzZTxbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0+IHtcbiAgY29uc3QgcG9ydHMgPSBbYXBwUG9ydF07XG4gIGZvciAoY29uc3QgY29uZmlndXJlZFBvcnQgb2YgW2dyYXBoaXRpUG9ydCwgbGl0ZWxsbVBvcnQsIHByb3h5UG9ydF0pIHtcbiAgICBpZiAoY29uZmlndXJlZFBvcnQgJiYgcG9ydHMuaW5jbHVkZXMoY29uZmlndXJlZFBvcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFwiR3JhcGhpdGkgc2lkZWNhciBwb3J0cyBtdXN0IGRpZmZlciBmcm9tIERBVEFCUklDS1NfQVBQX1BPUlRcIik7XG4gICAgfVxuICAgIGxldCBwb3J0ID0gY29uZmlndXJlZFBvcnQgfHwgKGF3YWl0IGF2YWlsYWJsZVBvcnQoKSk7XG4gICAgd2hpbGUgKHBvcnRzLmluY2x1ZGVzKHBvcnQpKSBwb3J0ID0gYXdhaXQgYXZhaWxhYmxlUG9ydCgpO1xuICAgIHBvcnRzLnB1c2gocG9ydCk7XG4gIH1cbiAgcmV0dXJuIHBvcnRzLnNsaWNlKDEpIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbn1cblxuZnVuY3Rpb24gY29tbWFuZExpbmUoYXJndW1lbnRzXzogc3RyaW5nW10pOiBzdHJpbmcge1xuICByZXR1cm4gYXJndW1lbnRzXy5tYXAoKHZhbHVlKSA9PiBgJyR7dmFsdWUucmVwbGFjZUFsbChcIidcIiwgXCInXFxcXCcnXCIpfSdgKS5qb2luKFwiIFwiKTtcbn1cbiJdfQ==
380
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdEMsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixNQUFNLEVBQ04sUUFBUSxFQUNSLFFBQVEsR0FJVCxNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFDTCxNQUFNLElBQUksU0FBUyxFQUNuQixRQUFRLElBQUksY0FBYyxFQUMxQixNQUFNLElBQUksWUFBWSxHQUN2QixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxNQUFNLElBQUksVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzNFLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxvQkFBb0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNuRCxPQUFPLFlBQXVELE1BQU0sY0FBYyxDQUFDO0FBRW5GLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIscUJBQXFCLEdBR3RCLE1BQU0sYUFBYSxDQUFDO0FBRXJCLE1BQU0saUJBQWlCLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO0FBQ3RFLE1BQU0sZUFBZSxH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QUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELEtBQUssVUFBVSxhQUFhLENBQzFCLE9BQWUsRUFDZixZQUFvQixFQUNwQixXQUFtQixFQUNuQixTQUFpQjtJQUVqQixNQUFNLEtBQUssR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hCLEtBQUssTUFBTSxjQUFjLElBQUksQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDcEUsSUFBSSxjQUFjLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQ3JELE1BQU0sSUFBSSxrQkFBa0IsQ0FBQyw2REFBNkQsQ0FBQyxDQUFDO1FBQzlGLENBQUM7UUFDRCxJQUFJLElBQUksR0FBRyxjQUFjLElBQUksQ0FBQyxNQUFNLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDckQsT0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztZQUFFLElBQUksR0FBRyxNQUFNLGFBQWEsRUFBRSxDQUFDO1FBQzFELEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQTZCLENBQUM7QUFDcEQsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLFVBQW9CO0lBQ3ZDLE9BQU8sVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFwcEtpdCBwbHVnaW4gdGhhdCBzdXBlcnZpc2VzIEdyYXBoaXRpIGFuZCByZXB1Ymxpc2hlcyB1c2VyLXNjb3BlZCBNQ1AgdG9vbHMuXG4gKlxuICogQG1vZHVsZVxuICovXG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgeyBleGVjRmlsZSB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IGNyZWF0ZVNlcnZlciB9IGZyb20gXCJub2RlOm5ldFwiO1xuaW1wb3J0IHsgY3JlYXRlUmVxdWlyZSB9IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuaW1wb3J0IHsgcHJvbWlzaWZ5IH0gZnJvbSBcIm5vZGU6dXRpbFwiO1xuaW1wb3J0IHtcbiAgQ29uZmlndXJhdGlvbkVycm9yLFxuICBQbHVnaW4sXG4gIGxha2ViYXNlLFxuICB0b1BsdWdpbixcbiAgdHlwZSBJQXBwUm91dGVyLFxuICB0eXBlIFBsdWdpbk1hbmlmZXN0LFxuICB0eXBlIFJlc291cmNlUmVxdWlyZW1lbnQsXG59IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7XG4gIGFwcGtpdCBhcyBkYnhBcHBraXQsXG4gIGlkZW50aXR5IGFzIGFwcGtpdElkZW50aXR5LFxuICBwbHVnaW4gYXMgYXBwa2l0UGx1Z2luLFxufSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGNvbmZpZyBhcyBjb3JlQ29uZmlnIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgYXN5bmMgYXMgYXN5bmNNb2R1bGUsIGxvZywgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGNyZWF0ZVRvb2wsIHR5cGUgVG9vbCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvdG9vbHNcIjtcbmltcG9ydCB7IE1DUENsaWVudCwgTUNQU2VydmVyIH0gZnJvbSBcIkBtYXN0cmEvbWNwXCI7XG5pbXBvcnQgY29uY3VycmVudGx5LCB7IHR5cGUgQ29tbWFuZCwgdHlwZSBDb25jdXJyZW50bHlSZXN1bHQgfSBmcm9tIFwiY29uY3VycmVudGx5XCI7XG5pbXBvcnQgdHlwZSBleHByZXNzIGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQge1xuICBHUkFQSElUSV9DT05GSUdfU0NIRU1BLFxuICByZXNvbHZlR3JhcGhpdGlDb25maWcsXG4gIHR5cGUgR3JhcGhpdGlQbHVnaW5Db25maWcsXG4gIHR5cGUgUmVzb2x2ZWRHcmFwaGl0aVBsdWdpbkNvbmZpZyxcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5cbmNvbnN0IExBS0VCQVNFX01BTklGRVNUID0gYXBwa2l0UGx1Z2luLmRhdGEobGFrZWJhc2UpLnBsdWdpbi5tYW5pZmVzdDtcbmNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IChcbiAgY3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpKFwiQGRieC10b29scy9hcHBraXQtZ3JhcGhpdGkvcGFja2FnZS5qc29uXCIpIGFzIHsgdmVyc2lvbjogc3RyaW5nIH1cbikudmVyc2lvbjtcbmNvbnN0IE1DUF9QQVRIID0gXCIvYXBpL2dyYXBoaXRpL21jcFwiO1xuY29uc3QgTUNQX1NFUlZFUl9JRExFX01TID0gMzAgKiA2MCAqIDEwMDA7XG5jb25zdCBNQ1BfU0VSVkVSX1NXRUVQX01TID0gNSAqIDYwICogMTAwMDtcbmNvbnN0IFNJREVDQVJfU0hVVERPV05fR1JBQ0VfTVMgPSAxMF8wMDA7XG5jb25zdCBTQ09QRURfVE9PTF9GSUVMRFMgPSB7XG4gIGFkZF9tZW1vcnk6IFwiZ3JvdXBfaWRcIixcbiAgYWRkX3RyaXBsZXQ6IFwiZ3JvdXBfaWRcIixcbiAgYnVpbGRfY29tbXVuaXRpZXM6IFwiZ3JvdXBfaWRzXCIsXG4gIGdldF9lcGlzb2RlczogXCJncm91cF9pZHNcIixcbiAgZ2V0X3N0YXR1czogdW5kZWZpbmVkLFxuICBzZWFyY2hfbWVtb3J5X2ZhY3RzOiBcImdyb3VwX2lkc1wiLFxuICBzZWFyY2hfbm9kZXM6IFwiZ3JvdXBfaWRzXCIsXG4gIHN1bW1hcml6ZV9zYWdhOiBcImdyb3VwX2lkXCIsXG59IGFzIGNvbnN0O1xuY29uc3QgV1JJVEVfVE9PTFMgPSBuZXcgU2V0KFtcImFkZF9tZW1vcnlcIiwgXCJhZGRfdHJpcGxldFwiLCBcImJ1aWxkX2NvbW11bml0aWVzXCIsIFwic3VtbWFyaXplX3NhZ2FcIl0pO1xuY29uc3QgVU5TQ09QRURfQVJHVU1FTlRTID0gW1xuICBcImNlbnRlcl9ub2RlX3V1aWRcIixcbiAgXCJwcmV2aW91c19lcGlzb2RlX3V1aWRzXCIsXG4gIFwic2FnYV9wcmV2aW91c19lcGlzb2RlX3V1aWRcIixcbiAgXCJzb3VyY2Vfbm9kZV91dWlkXCIsXG4gIFwidGFyZ2V0X25vZGVfdXVpZFwiLFxuICBcInV1aWRcIixcbl0gYXMgY29uc3Q7XG5cbmludGVyZmFjZSBUb29sa2l0RW50cnkge1xuICByZWFkb25seSBfX3Rvb2xraXRSZWY6IHRydWU7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgbG9jYWxOYW1lOiBzdHJpbmc7XG4gIGRlZjoge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgIHBhcmFtZXRlcnM6IHVua25vd247XG4gIH07XG4gIGFubm90YXRpb25zOiB7XG4gICAgZWZmZWN0OiBcInJlYWRcIiB8IFwid3JpdGVcIjtcbiAgICByZXF1aXJlc1VzZXJDb250ZXh0OiB0cnVlO1xuICB9O1xufVxuXG5pbnRlcmZhY2UgVXNlck1jcFNlcnZlciB7XG4gIGxhc3RVc2VkOiBudW1iZXI7XG4gIHNlcnZlcjogTUNQU2VydmVyO1xufVxuXG5leHBvcnQgY2xhc3MgR3JhcGhpdGlQbHVnaW4gZXh0ZW5kcyBQbHVnaW48R3JhcGhpdGlQbHVnaW5Db25maWc+IHtcbiAgc3RhdGljIG1hbmlmZXN0OiBQbHVnaW5NYW5pZmVzdDxcImdyYXBoaXRpXCI+ID0ge1xuICAgIG5hbWU6IFwiZ3JhcGhpdGlcIixcbiAgICBkaXNwbGF5TmFtZTogXCJHcmFwaGl0aVwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJSdW5zIHRoZSBkYngtdG9vbHMgR3JhcGhpdGkgTUNQIHNpZGVjYXIgd2l0aCBMYWtlYmFzZS1iYWNrZWQgcmVjb3ZlcnkgYW5kIFwiICtcbiAgICAgIFwicHVibGlzaGVzIGl0IHRocm91Z2ggdGhlIEFwcCdzIHNpbmdsZSBwb3J0IHdpdGggQ2FkZHkuXCIsXG4gICAgc3RhYmlsaXR5OiBcImJldGFcIixcbiAgICByZXNvdXJjZXM6IHtcbiAgICAgIHJlcXVpcmVkOiBbXSxcbiAgICAgIG9wdGlvbmFsOiBbLi4uTEFLRUJBU0VfTUFOSUZFU1QucmVzb3VyY2VzLnJlcXVpcmVkXSxcbiAgICB9LFxuICAgIGNvbmZpZzogeyBzY2hlbWE6IEdSQVBISVRJX0NPTkZJR19TQ0hFTUEgfSxcbiAgfTtcblxuICBzdGF0aWMgZ2V0UmVzb3VyY2VSZXF1aXJlbWVudHMoKTogUmVzb3VyY2VSZXF1aXJlbWVudFtdIHtcbiAgICByZXR1cm4gTEFLRUJBU0VfTUFOSUZFU1QucmVzb3VyY2VzLnJlcXVpcmVkLm1hcCgocmVzb3VyY2UpID0+ICh7XG4gICAgICAuLi5yZXNvdXJjZSxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgIH0pKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyID0gbG9nLmxvZ2dlcih0aGlzKTtcbiAgcHJpdmF0ZSBjb21tYW5kczogQ29tbWFuZFtdID0gW107XG4gIHByaXZhdGUgbWNwPzogTUNQQ2xpZW50O1xuICBwcml2YXRlIG1jcFNlcnZlcnMgPSBuZXcgTWFwPHN0cmluZywgVXNlck1jcFNlcnZlcj4oKTtcbiAgcHJpdmF0ZSBtY3BTZXJ2ZXJTd2VlcD86IE5vZGVKUy5UaW1lb3V0O1xuICBwcml2YXRlIG1jcFRvb2xzOiBSZWNvcmQ8c3RyaW5nLCBUb29sPiA9IHt9O1xuICBwcml2YXRlIHJlc29sdmVkPzogUmVzb2x2ZWRHcmFwaGl0aVBsdWdpbkNvbmZpZztcbiAgcHJpdmF0ZSBzZXR1cENvbXBsZXRlID0gZmFsc2U7XG4gIHByaXZhdGUgc3RhcnR1cD86IFByb21pc2U8dm9pZD47XG4gIHByaXZhdGUgc3VwZXJ2aXNpb24/OiBDb25jdXJyZW50bHlSZXN1bHQ7XG4gIHByaXZhdGUgc3RvcHBpbmcgPSBmYWxzZTtcblxuICBvdmVycmlkZSBhc3luYyBzZXR1cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnN0YXJ0dXAgPSB0aGlzLnN0YXJ0U2lkZWNhcnMoKS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgIGlmICh0aGlzLnN0b3BwaW5nKSByZXR1cm47XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihcImJhY2tncm91bmQgc3RhcnR1cCBmYWlsZWRcIiwgeyBlcnJvciB9KTtcbiAgICAgIHByb2Nlc3Mua2lsbChwcm9jZXNzLnBpZCwgXCJTSUdURVJNXCIpO1xuICAgIH0pO1xuICAgIHZvaWQgdGhpcy5zdGFydHVwO1xuICAgIHRoaXMubG9nZ2VyLmluZm8oXCJiYWNrZ3JvdW5kIHN0YXJ0dXAgc2NoZWR1bGVkXCIpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzdGFydFNpZGVjYXJzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbmZpZ3VyZWQgPSByZXNvbHZlR3JhcGhpdGlDb25maWcodGhpcy5jb25maWcpO1xuICAgIGNvbnN0IFtncmFwaGl0aVBvcnQsIGxpdGVsbG1Qb3J0LCBwcm94eVBvcnRdID0gYXdhaXQgZGlzdGluY3RQb3J0cyhcbiAgICAgIGNvcmVDb25maWcucG9ydCh1bmRlZmluZWQsIFwiREFUQUJSSUNLU19BUFBfUE9SVFwiLCA4MDAwLCBjb3JlQ29uZmlnLkVOVl9PTkxZKSxcbiAgICAgIGNvbmZpZ3VyZWQuZ3JhcGhpdGlQb3J0LFxuICAgICAgY29uZmlndXJlZC5saXRlbGxtUG9ydCxcbiAgICAgIGNvbmZpZ3VyZWQucHJveHlQb3J0LFxuICAgICk7XG4gICAgYXdhaXQgZW5zdXJlR3JhcGhpdGlQeXRob24oY29uZmlndXJlZC5weXRob24pO1xuICAgIHRoaXMucmVzb2x2ZWQgPSB7XG4gICAgICAuLi5jb25maWd1cmVkLFxuICAgICAgZ3JhcGhpdGlQb3J0LFxuICAgICAgbGl0ZWxsbVBvcnQsXG4gICAgICBwcm94eVBvcnQsXG4gICAgfTtcbiAgICB0aGlzLnN1cGVydmlzaW9uID0gY29uY3VycmVudGx5KFxuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJncmFwaGl0aVwiLFxuICAgICAgICAgIGNvbW1hbmQ6IGNvbW1hbmRMaW5lKFt0aGlzLnJlc29sdmVkLnB5dGhvbiwgXCItbVwiLCBcImRieF90b29scy5ncmFwaGl0aVwiLCBcInN0YXJ0XCJdKSxcbiAgICAgICAgICBlbnY6IHtcbiAgICAgICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICAgICAgR1JBUEhJVElfSE9TVDogXCIxMjcuMC4wLjFcIixcbiAgICAgICAgICAgIEdSQVBISVRJX1BPUlQ6IFN0cmluZyh0aGlzLnJlc29sdmVkLmdyYXBoaXRpUG9ydCksXG4gICAgICAgICAgICBKT1VSTkFMX05BTUVTUEFDRTogdGhpcy5yZXNvbHZlZC5qb3VybmFsTmFtZXNwYWNlLFxuICAgICAgICAgICAgTElURUxMTV9IT1NUOiBcIjEyNy4wLjAuMVwiLFxuICAgICAgICAgICAgTElURUxMTV9QT1JUOiBTdHJpbmcodGhpcy5yZXNvbHZlZC5saXRlbGxtUG9ydCksXG4gICAgICAgICAgICBNQU5BR0VfTElURUxMTTogXCJ0cnVlXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY2FkZHlcIixcbiAgICAgICAgICBjb21tYW5kOiBjb21tYW5kTGluZShbXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVkLnB5dGhvbixcbiAgICAgICAgICAgIFwiLW1cIixcbiAgICAgICAgICAgIFwiZGJ4X3Rvb2xzLmdyYXBoaXRpLnByb3h5XCIsXG4gICAgICAgICAgICBcIi0tcHJveHktcG9ydFwiLFxuICAgICAgICAgICAgU3RyaW5nKHRoaXMucmVzb2x2ZWQucHJveHlQb3J0KSxcbiAgICAgICAgICAgIFwiLS1ncmFwaGl0aS1wb3J0XCIsXG4gICAgICAgICAgICBTdHJpbmcodGhpcy5yZXNvbHZlZC5ncmFwaGl0aVBvcnQpLFxuICAgICAgICAgIF0pLFxuICAgICAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAge1xuICAgICAgICBraWxsT3RoZXJzT246IFtcImZhaWx1cmVcIiwgXCJzdWNjZXNzXCJdLFxuICAgICAgICBraWxsU2lnbmFsOiBcIlNJR1RFUk1cIixcbiAgICAgICAga2lsbFRpbWVvdXQ6IFNJREVDQVJfU0hVVERPV05fR1JBQ0VfTVMsXG4gICAgICAgIHByZWZpeDogXCJuYW1lXCIsXG4gICAgICAgIHByZWZpeENvbG9yczogZmFsc2UsXG4gICAgICB9LFxuICAgICk7XG4gICAgdGhpcy5jb21tYW5kcyA9IHRoaXMuc3VwZXJ2aXNpb24uY29tbWFuZHM7XG4gICAgdGhpcy5zZXR1cENvbXBsZXRlID0gdHJ1ZTtcbiAgICB2b2lkIHRoaXMuc3VwZXJ2aXNpb24ucmVzdWx0LnRoZW4oXG4gICAgICAoKSA9PiB0aGlzLm9uU3VwZXJ2aXNvckV4aXQoKSxcbiAgICAgIChlcnJvcikgPT4gdGhpcy5vblN1cGVydmlzb3JFeGl0KGVycm9yKSxcbiAgICApO1xuICAgIHRoaXMubWNwU2VydmVyU3dlZXAgPSBzZXRJbnRlcnZhbCgoKSA9PiB0aGlzLmNsb3NlSWRsZU1jcFNlcnZlcnMoKSwgTUNQX1NFUlZFUl9TV0VFUF9NUyk7XG4gICAgdGhpcy5tY3BTZXJ2ZXJTd2VlcC51bnJlZigpO1xuICAgIHRoaXMubG9nZ2VyLmluZm8oXCJzaWRlY2FycyBsYXVuY2hlZFwiLCB7XG4gICAgICBncmFwaGl0aVBvcnQ6IHRoaXMucmVzb2x2ZWQuZ3JhcGhpdGlQb3J0LFxuICAgICAgbGl0ZWxsbVBvcnQ6IHRoaXMucmVzb2x2ZWQubGl0ZWxsbVBvcnQsXG4gICAgICBwcm94eVBvcnQ6IHRoaXMucmVzb2x2ZWQucHJveHlQb3J0LFxuICAgICAgbWNwUGF0aDogTUNQX1BBVEgsXG4gICAgfSk7XG4gIH1cblxuICBvdmVycmlkZSBpbmplY3RSb3V0ZXMocm91dGVyOiBJQXBwUm91dGVyKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBtZXRob2Qgb2YgW1wiZ2V0XCIsIFwicG9zdFwiLCBcImRlbGV0ZVwiXSBhcyBjb25zdCkge1xuICAgICAgdGhpcy5yb3V0ZShyb3V0ZXIsIHtcbiAgICAgICAgbmFtZTogYCR7bWV0aG9kfU1jcGAsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgcGF0aDogXCIvbWNwXCIsXG4gICAgICAgIGhhbmRsZXI6IChyZXF1ZXN0LCByZXNwb25zZSkgPT4gdGhpcy5mb3J3YXJkTWNwKHJlcXVlc3QsIHJlc3BvbnNlKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG92ZXJyaWRlIGFib3J0QWN0aXZlT3BlcmF0aW9ucygpOiB2b2lkIHtcbiAgICBzdXBlci5hYm9ydEFjdGl2ZU9wZXJhdGlvbnMoKTtcbiAgICB2b2lkIHRoaXMubWNwPy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICBhc3luYyBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnN0b3BTaWRlY2FycygpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZXhwb3J0cygpIHtcbiAgICByZXR1cm4geyBtY3BQYXRoOiBNQ1BfUEFUSCB9O1xuICB9XG5cbiAgdG9vbGtpdCgpOiBSZWNvcmQ8c3RyaW5nLCBUb29sa2l0RW50cnk+IHtcbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmtleXMoU0NPUEVEX1RPT0xfRklFTERTKS5tYXAoKG5hbWUpID0+IFtcbiAgICAgICAgbmFtZSxcbiAgICAgICAge1xuICAgICAgICAgIF9fdG9vbGtpdFJlZjogdHJ1ZSBhcyBjb25zdCxcbiAgICAgICAgICBwbHVnaW5OYW1lOiBcImdyYXBoaXRpXCIsXG4gICAgICAgICAgbG9jYWxOYW1lOiBuYW1lLFxuICAgICAgICAgIGRlZjoge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgR3JhcGhpdGkgJHtuYW1lLnJlcGxhY2VBbGwoXCJfXCIsIFwiIFwiKX1gLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogeyB0eXBlOiBcIm9iamVjdFwiLCBwcm9wZXJ0aWVzOiB7fSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYW5ub3RhdGlvbnM6IHtcbiAgICAgICAgICAgIGVmZmVjdDogV1JJVEVfVE9PTFMuaGFzKG5hbWUpID8gKFwid3JpdGVcIiBhcyBjb25zdCkgOiAoXCJyZWFkXCIgYXMgY29uc3QpLFxuICAgICAgICAgICAgcmVxdWlyZXNVc2VyQ29udGV4dDogdHJ1ZSBhcyBjb25zdCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSksXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGVBZ2VudFRvb2woXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGFyZ3M6IHVua25vd24sXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICAgY29udGV4dD86IHsgcmVzb3VyY2VJZD86IHN0cmluZyB9LFxuICApOiBQcm9taXNlPHVua25vd24+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZU1jcFRvb2xzKCk7XG4gICAgY29uc3QgdG9vbCA9IHRoaXMubWNwVG9vbHNbbmFtZV07XG4gICAgaWYgKCF0b29sPy5leGVjdXRlKSB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gR3JhcGhpdGkgdG9vbDogJHtuYW1lfWApO1xuICAgIGNvbnN0IHVzZXJJZCA9IGNvbnRleHQ/LnJlc291cmNlSWQgPz8gZXhlY3V0aW9uQ29udGV4dFVzZXJJZCgpO1xuICAgIHJldHVybiB0b29sLmV4ZWN1dGUoc2NvcGVkQXJndW1lbnRzKG5hbWUsIGFyZ3MsIHVzZXJTY29wZSh1c2VySWQpKSwge1xuICAgICAgYWJvcnRTaWduYWw6IHNpZ25hbCxcbiAgICB9IGFzIG5ldmVyKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZm9yd2FyZE1jcChyZXF1ZXN0OiBleHByZXNzLlJlcXVlc3QsIHJlc3BvbnNlOiBleHByZXNzLlJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVNY3BUb29scygpO1xuICAgIGNvbnN0IHVzZXJJZCA9IGFwcGtpdElkZW50aXR5LnJlcXVlc3RVc2VySWQocmVxdWVzdCkgPz8gZXhlY3V0aW9uQ29udGV4dFVzZXJJZCgpO1xuICAgIGNvbnN0IHNlcnZlciA9IHRoaXMubWNwU2VydmVyKHVzZXJJZCk7XG4gICAgYXdhaXQgc2VydmVyLnN0YXJ0SFRUUCh7XG4gICAgICB1cmw6IG5ldyBVUkwocmVxdWVzdC5vcmlnaW5hbFVybCwgXCJodHRwOi8vYXBwLmxvY2FsXCIpLFxuICAgICAgaHR0cFBhdGg6IE1DUF9QQVRILFxuICAgICAgcmVxOiByZXF1ZXN0LFxuICAgICAgcmVzOiByZXNwb25zZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlTWNwVG9vbHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMubWNwVG9vbHMpLmxlbmd0aCA+IDApIHJldHVybjtcbiAgICBpZiAoIXRoaXMucmVzb2x2ZWQpIHRocm93IG5ldyBFcnJvcihcIkdyYXBoaXRpIHNpZGVjYXJzIGhhdmUgbm90IGxhdW5jaGVkXCIpO1xuICAgIHRoaXMubWNwID8/PSBuZXcgTUNQQ2xpZW50KHtcbiAgICAgIGlkOiBgYXBwa2l0LWdyYXBoaXRpLSR7dGhpcy5yZXNvbHZlZC5ncmFwaGl0aVBvcnR9YCxcbiAgICAgIHNlcnZlcnM6IHtcbiAgICAgICAgZ3JhcGhpdGk6IHsgdXJsOiBuZXcgVVJMKGBodHRwOi8vMTI3LjAuMC4xOiR7dGhpcy5yZXNvbHZlZC5wcm94eVBvcnR9L21jcGApIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGNvbnN0IGRpc2NvdmVyZWQgPSBhd2FpdCB0aGlzLm1jcC5saXN0VG9vbHMoKTtcbiAgICB0aGlzLm1jcFRvb2xzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMoZGlzY292ZXJlZClcbiAgICAgICAgLm1hcCgoW25hbWUsIHRvb2xdKSA9PiBbbmFtZS5yZXBsYWNlKC9eZ3JhcGhpdGlfLywgXCJcIiksIHRvb2wgYXMgVG9vbF0gYXMgY29uc3QpXG4gICAgICAgIC5maWx0ZXIoKFtuYW1lXSkgPT4gbmFtZSBpbiBTQ09QRURfVE9PTF9GSUVMRFMpLFxuICAgICk7XG4gICAgY29uc3QgbWlzc2luZyA9IE9iamVjdC5rZXlzKFNDT1BFRF9UT09MX0ZJRUxEUykuZmlsdGVyKChuYW1lKSA9PiAhdGhpcy5tY3BUb29sc1tuYW1lXSk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBHcmFwaGl0aSBkaWQgbm90IHB1Ymxpc2ggcmVxdWlyZWQgc2NvcGVkIHRvb2xzOiAke21pc3Npbmcuam9pbihcIiwgXCIpfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWNwU2VydmVyKHVzZXJJZDogc3RyaW5nKTogTUNQU2VydmVyIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMubWNwU2VydmVycy5nZXQodXNlcklkKTtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIGV4aXN0aW5nLmxhc3RVc2VkID0gRGF0ZS5ub3coKTtcbiAgICAgIHJldHVybiBleGlzdGluZy5zZXJ2ZXI7XG4gICAgfVxuICAgIGNvbnN0IHNjb3BlID0gdXNlclNjb3BlKHVzZXJJZCk7XG4gICAgY29uc3QgdG9vbHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLm1jcFRvb2xzKS5tYXAoKFtuYW1lLCB0b29sXSkgPT4gW1xuICAgICAgICBuYW1lLFxuICAgICAgICBjcmVhdGVUb29sKHtcbiAgICAgICAgICBpZDogbmFtZSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogdG9vbC5kZXNjcmlwdGlvbiA/PyBuYW1lLFxuICAgICAgICAgIC4uLih0b29sLmlucHV0U2NoZW1hID8geyBpbnB1dFNjaGVtYTogdG9vbC5pbnB1dFNjaGVtYSBhcyBuZXZlciB9IDoge30pLFxuICAgICAgICAgIGV4ZWN1dGU6IChhcmdzOiB1bmtub3duLCBjb250ZXh0OiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRvb2wuZXhlY3V0ZSkgdGhyb3cgbmV3IEVycm9yKGBHcmFwaGl0aSB0b29sIGNhbm5vdCBleGVjdXRlOiAke25hbWV9YCk7XG4gICAgICAgICAgICByZXR1cm4gdG9vbC5leGVjdXRlKHNjb3BlZEFyZ3VtZW50cyhuYW1lLCBhcmdzLCBzY29wZSksIGNvbnRleHQgYXMgbmV2ZXIpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgXSksXG4gICAgKTtcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXcgTUNQU2VydmVyKHtcbiAgICAgIG5hbWU6IFwiR3JhcGhpdGlcIixcbiAgICAgIHZlcnNpb246IFwiMS4wLjBcIixcbiAgICAgIHRvb2xzLFxuICAgIH0pO1xuICAgIHRoaXMubWNwU2VydmVycy5zZXQodXNlcklkLCB7IGxhc3RVc2VkOiBEYXRlLm5vdygpLCBzZXJ2ZXIgfSk7XG4gICAgcmV0dXJuIHNlcnZlcjtcbiAgfVxuXG4gIHByaXZhdGUgb25TdXBlcnZpc29yRXhpdChlcnJvcj86IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdG9wcGluZyB8fCAhdGhpcy5zZXR1cENvbXBsZXRlKSByZXR1cm47XG4gICAgdGhpcy5sb2dnZXIuZXJyb3IoXCJzaWRlY2FyIHN1cGVydmlzb3IgZXhpdGVkXCIsIHsgZXJyb3IgfSk7XG4gICAgcHJvY2Vzcy5raWxsKHByb2Nlc3MucGlkLCBcIlNJR1RFUk1cIik7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHN0b3BTaWRlY2FycygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5zdG9wcGluZykgcmV0dXJuO1xuICAgIHRoaXMuc3RvcHBpbmcgPSB0cnVlO1xuICAgIGlmICh0aGlzLm1jcFNlcnZlclN3ZWVwKSBjbGVhckludGVydmFsKHRoaXMubWNwU2VydmVyU3dlZXApO1xuICAgIHRoaXMubWNwU2VydmVyU3dlZXAgPSB1bmRlZmluZWQ7XG4gICAgY29uc3QgY29tbWFuZHMgPSB0aGlzLmNvbW1hbmRzO1xuICAgIGNvbnN0IHN1cGVydmlzaW9uID0gdGhpcy5zdXBlcnZpc2lvbjtcbiAgICBmb3IgKGNvbnN0IGNvbW1hbmQgb2YgY29tbWFuZHMpIGNvbW1hbmQua2lsbChcIlNJR1RFUk1cIik7XG4gICAgY29uc3QgY2xlYW51cCA9IFByb21pc2UuYWxsU2V0dGxlZChbXG4gICAgICAuLi5bLi4udGhpcy5tY3BTZXJ2ZXJzLnZhbHVlcygpXS5tYXAoKHsgc2VydmVyIH0pID0+IHNlcnZlci5jbG9zZSgpKSxcbiAgICAgIHRoaXMubWNwPy5kaXNjb25uZWN0KCksXG4gICAgICBzdXBlcnZpc2lvbj8ucmVzdWx0LFxuICAgIF0pO1xuICAgIGNvbnN0IGNvbXBsZXRlZCA9IGF3YWl0IFByb21pc2UucmFjZShbXG4gICAgICBjbGVhbnVwLnRoZW4oKCkgPT4gdHJ1ZSksXG4gICAgICBhc3luY01vZHVsZS5zbGVlcChTSURFQ0FSX1NIVVRET1dOX0dSQUNFX01TKS50aGVuKCgpID0+IGZhbHNlKSxcbiAgICBdKTtcbiAgICBpZiAoIWNvbXBsZXRlZCkge1xuICAgICAgdGhpcy5sb2dnZXIud2FybihcInNpZGVjYXJzIGlnbm9yZWQgU0lHVEVSTTsgZXNjYWxhdGluZyB0byBTSUdLSUxMXCIpO1xuICAgICAgZm9yIChjb25zdCBjb21tYW5kIG9mIGNvbW1hbmRzKSBjb21tYW5kLmtpbGwoXCJTSUdLSUxMXCIpO1xuICAgIH1cbiAgICB0aGlzLm1jcFNlcnZlcnMuY2xlYXIoKTtcbiAgICB0aGlzLm1jcCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1jcFRvb2xzID0ge307XG4gICAgdGhpcy5jb21tYW5kcyA9IFtdO1xuICAgIHRoaXMuc3VwZXJ2aXNpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5zdGFydHVwID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZUlkbGVNY3BTZXJ2ZXJzKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1dG9mZiA9IERhdGUubm93KCkgLSBNQ1BfU0VSVkVSX0lETEVfTVM7XG4gICAgZm9yIChjb25zdCBbdXNlcklkLCBlbnRyeV0gb2YgdGhpcy5tY3BTZXJ2ZXJzKSB7XG4gICAgICBpZiAoZW50cnkubGFzdFVzZWQgPj0gY3V0b2ZmKSBjb250aW51ZTtcbiAgICAgIHRoaXMubWNwU2VydmVycy5kZWxldGUodXNlcklkKTtcbiAgICAgIHZvaWQgZW50cnkuc2VydmVyLmNsb3NlKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oXCJpZGxlIE1DUCBzZXJ2ZXIgY2xvc2UgZmFpbGVkXCIsIHsgZXJyb3IgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxudHlwZSBFeGVjUHl0aG9uID0gKGZpbGU6IHN0cmluZywgYXJnczogc3RyaW5nW10pID0+IFByb21pc2U8dW5rbm93bj47XG5cbi8qKiBFbnN1cmUgRGF0YWJyaWNrcyBBcHBzIGhhcyB0aGUgUHl0aG9uIHNpZGVjYXIgbWF0Y2hpbmcgdGhpcyBOb2RlIHBhY2thZ2UuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5zdXJlR3JhcGhpdGlQeXRob24oXG4gIHB5dGhvbjogc3RyaW5nLFxuICBydW46IEV4ZWNQeXRob24gPSAoZmlsZSwgYXJncykgPT4gcHJvbWlzaWZ5KGV4ZWNGaWxlKShmaWxlLCBhcmdzKSxcbik6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGF3YWl0IHJ1bihweXRob24sIFtcIi1jXCIsIFwiaW1wb3J0IGRieF90b29scy5ncmFwaGl0aVwiXSk7XG4gIH0gY2F0Y2gge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBydW4ocHl0aG9uLCBbXCItbVwiLCBcInBpcFwiLCBcIi0tdmVyc2lvblwiXSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBhd2FpdCBydW4ocHl0aG9uLCBbXG4gICAgICAgIFwiLWNcIixcbiAgICAgICAgXCJpbXBvcnQgdXJsbGliLnJlcXVlc3Q7IGV4ZWModXJsbGliLnJlcXVlc3QudXJsb3BlbignaHR0cHM6Ly9ib290c3RyYXAucHlwYS5pby9nZXQtcGlwLnB5JykucmVhZCgpKVwiLFxuICAgICAgICBcIi0tdXNlclwiLFxuICAgICAgICBcIi0tYnJlYWstc3lzdGVtLXBhY2thZ2VzXCIsXG4gICAgICBdKTtcbiAgICB9XG4gICAgYXdhaXQgcnVuKHB5dGhvbiwgW1xuICAgICAgXCItbVwiLFxuICAgICAgXCJwaXBcIixcbiAgICAgIFwiaW5zdGFsbFwiLFxuICAgICAgXCItLWRpc2FibGUtcGlwLXZlcnNpb24tY2hlY2tcIixcbiAgICAgIFwiLS11c2VyXCIsXG4gICAgICBcIi0tYnJlYWstc3lzdGVtLXBhY2thZ2VzXCIsXG4gICAgICBgZGJ4LXRvb2xzLWdyYXBoaXRpPT0ke1BBQ0tBR0VfVkVSU0lPTn1gLFxuICAgIF0pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBncmFwaGl0aSA9IHRvUGx1Z2luKEdyYXBoaXRpUGx1Z2luKTtcblxuZnVuY3Rpb24gZXhlY3V0aW9uQ29udGV4dFVzZXJJZCgpOiBzdHJpbmcge1xuICBjb25zdCBjb250ZXh0ID0gZGJ4QXBwa2l0LnRyeUdldEV4ZWN1dGlvbkNvbnRleHQoKTtcbiAgaWYgKCFjb250ZXh0KSB0aHJvdyBuZXcgRXJyb3IoXCJHcmFwaGl0aSBtZW1vcnkgcmVxdWlyZXMgYW4gQXBwS2l0IGV4ZWN1dGlvbiBjb250ZXh0XCIpO1xuICByZXR1cm4gXCJ1c2VySWRcIiBpbiBjb250ZXh0ID8gY29udGV4dC51c2VySWQgOiBjb250ZXh0LnNlcnZpY2VVc2VySWQ7XG59XG5cbmZ1bmN0aW9uIHVzZXJTY29wZSh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgdXNlcl8ke2NyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKHVzZXJJZCkuZGlnZXN0KFwiYmFzZTY0dXJsXCIpfWA7XG59XG5cbmZ1bmN0aW9uIHNjb3BlZEFyZ3VtZW50cyhuYW1lOiBzdHJpbmcsIGFyZ3M6IHVua25vd24sIHNjb3BlOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmICghKG5hbWUgaW4gU0NPUEVEX1RPT0xfRklFTERTKSkgdGhyb3cgbmV3IEVycm9yKGBHcmFwaGl0aSB0b29sIGlzIG5vdCB1c2VyLXNjb3BlZDogJHtuYW1lfWApO1xuICBjb25zdCBzY29wZWQgPSBvYmplY3QuaXNSZWNvcmQoYXJncykgPyB7IC4uLmFyZ3MgfSA6IHt9O1xuICBmb3IgKGNvbnN0IGFyZ3VtZW50IG9mIFVOU0NPUEVEX0FSR1VNRU5UUykgZGVsZXRlIHNjb3BlZFthcmd1bWVudF07XG4gIGNvbnN0IGZpZWxkID0gU0NPUEVEX1RPT0xfRklFTERTW25hbWUgYXMga2V5b2YgdHlwZW9mIFNDT1BFRF9UT09MX0ZJRUxEU107XG4gIGlmIChmaWVsZCA9PT0gXCJncm91cF9pZFwiKSBzY29wZWQuZ3JvdXBfaWQgPSBzY29wZTtcbiAgaWYgKGZpZWxkID09PSBcImdyb3VwX2lkc1wiKSBzY29wZWQuZ3JvdXBfaWRzID0gW3Njb3BlXTtcbiAgcmV0dXJuIHNjb3BlZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gYXZhaWxhYmxlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigpO1xuICAgIHNlcnZlci5vbmNlKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICBzZXJ2ZXIubGlzdGVuKDAsIFwiMTI3LjAuMC4xXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgaWYgKCFhZGRyZXNzIHx8IHR5cGVvZiBhZGRyZXNzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKFwiQ291bGQgbm90IGFsbG9jYXRlIGEgR3JhcGhpdGkgbG9vcGJhY2sgcG9ydFwiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlcnZlci5jbG9zZSgoZXJyb3IpID0+IChlcnJvciA/IHJlamVjdChlcnJvcikgOiByZXNvbHZlKGFkZHJlc3MucG9ydCkpKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRpc3RpbmN0UG9ydHMoXG4gIGFwcFBvcnQ6IG51bWJlcixcbiAgZ3JhcGhpdGlQb3J0OiBudW1iZXIsXG4gIGxpdGVsbG1Qb3J0OiBudW1iZXIsXG4gIHByb3h5UG9ydDogbnVtYmVyLFxuKTogUHJvbWlzZTxbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0+IHtcbiAgY29uc3QgcG9ydHMgPSBbYXBwUG9ydF07XG4gIGZvciAoY29uc3QgY29uZmlndXJlZFBvcnQgb2YgW2dyYXBoaXRpUG9ydCwgbGl0ZWxsbVBvcnQsIHByb3h5UG9ydF0pIHtcbiAgICBpZiAoY29uZmlndXJlZFBvcnQgJiYgcG9ydHMuaW5jbHVkZXMoY29uZmlndXJlZFBvcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFwiR3JhcGhpdGkgc2lkZWNhciBwb3J0cyBtdXN0IGRpZmZlciBmcm9tIERBVEFCUklDS1NfQVBQX1BPUlRcIik7XG4gICAgfVxuICAgIGxldCBwb3J0ID0gY29uZmlndXJlZFBvcnQgfHwgKGF3YWl0IGF2YWlsYWJsZVBvcnQoKSk7XG4gICAgd2hpbGUgKHBvcnRzLmluY2x1ZGVzKHBvcnQpKSBwb3J0ID0gYXdhaXQgYXZhaWxhYmxlUG9ydCgpO1xuICAgIHBvcnRzLnB1c2gocG9ydCk7XG4gIH1cbiAgcmV0dXJuIHBvcnRzLnNsaWNlKDEpIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbn1cblxuZnVuY3Rpb24gY29tbWFuZExpbmUoYXJndW1lbnRzXzogc3RyaW5nW10pOiBzdHJpbmcge1xuICByZXR1cm4gYXJndW1lbnRzXy5tYXAoKHZhbHVlKSA9PiBgJyR7dmFsdWUucmVwbGFjZUFsbChcIidcIiwgXCInXFxcXCcnXCIpfSdgKS5qb2luKFwiIFwiKTtcbn1cbiJdfQ==
package/package.json CHANGED
@@ -26,9 +26,9 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@databricks/appkit": "^0.60.0",
29
- "@dbx-tools/appkit": "0.6.127",
30
- "@dbx-tools/core": "0.6.127",
31
- "@dbx-tools/shared-core": "0.6.127",
29
+ "@dbx-tools/appkit": "0.6.128",
30
+ "@dbx-tools/core": "0.6.128",
31
+ "@dbx-tools/shared-core": "0.6.128",
32
32
  "@mastra/core": "1.47.0",
33
33
  "@mastra/mcp": "1.12.0",
34
34
  "concurrently": "^10.0.3"
@@ -47,7 +47,7 @@
47
47
  "./package.json": "./package.json"
48
48
  }
49
49
  },
50
- "version": "0.6.127",
50
+ "version": "0.6.128",
51
51
  "types": "./lib/index.d.ts",
52
52
  "type": "module",
53
53
  "exports": {
package/src/plugin.ts CHANGED
@@ -43,7 +43,6 @@ const MCP_PATH = "/api/graphiti/mcp";
43
43
  const MCP_SERVER_IDLE_MS = 30 * 60 * 1000;
44
44
  const MCP_SERVER_SWEEP_MS = 5 * 60 * 1000;
45
45
  const SIDECAR_SHUTDOWN_GRACE_MS = 10_000;
46
- const SIDECAR_STARTUP_TIMEOUT_MS = 10 * 60_000;
47
46
  const SCOPED_TOOL_FIELDS = {
48
47
  add_memory: "group_id",
49
48
  add_triplet: "group_id",
@@ -121,7 +120,8 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
121
120
  override async setup(): Promise<void> {
122
121
  this.startup = this.startSidecars().catch((error: unknown) => {
123
122
  if (this.stopping) return;
124
- this.logger.error("background startup failed; Graphiti remains unavailable", { error });
123
+ this.logger.error("background startup failed", { error });
124
+ process.kill(process.pid, "SIGTERM");
125
125
  });
126
126
  void this.startup;
127
127
  this.logger.info("background startup scheduled");
@@ -180,57 +180,18 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
180
180
  },
181
181
  );
182
182
  this.commands = this.supervision.commands;
183
+ this.setupComplete = true;
183
184
  void this.supervision.result.then(
184
185
  () => this.onSupervisorExit(),
185
186
  (error) => this.onSupervisorExit(error),
186
187
  );
187
- const supervisionFailure = this.supervision.result.then(
188
- () => {
189
- throw new Error("Graphiti sidecar supervisor exited during startup");
190
- },
191
- (error) => {
192
- throw error;
193
- },
194
- );
195
- try {
196
- await Promise.race([
197
- (async () => {
198
- await waitForGraphiti(graphitiPort);
199
- await waitForGraphiti(proxyPort);
200
- })(),
201
- supervisionFailure,
202
- ]);
203
- this.mcp = new MCPClient({
204
- id: `appkit-graphiti-${this.resolved.graphitiPort}`,
205
- servers: {
206
- graphiti: {
207
- url: new URL(`http://127.0.0.1:${this.resolved.proxyPort}/mcp`),
208
- },
209
- },
210
- });
211
- const discovered = await this.mcp.listTools();
212
- this.mcpTools = Object.fromEntries(
213
- Object.entries(discovered)
214
- .map(([name, tool]) => [name.replace(/^graphiti_/, ""), tool as Tool] as const)
215
- .filter(([name]) => name in SCOPED_TOOL_FIELDS),
216
- );
217
- const missing = Object.keys(SCOPED_TOOL_FIELDS).filter((name) => !this.mcpTools[name]);
218
- if (missing.length > 0) {
219
- throw new Error(`Graphiti did not publish required scoped tools: ${missing.join(", ")}`);
220
- }
221
- } catch (error) {
222
- await this.stopSidecars();
223
- throw error;
224
- }
225
- this.setupComplete = true;
226
188
  this.mcpServerSweep = setInterval(() => this.closeIdleMcpServers(), MCP_SERVER_SWEEP_MS);
227
189
  this.mcpServerSweep.unref();
228
- this.logger.info("ready", {
190
+ this.logger.info("sidecars launched", {
229
191
  graphitiPort: this.resolved.graphitiPort,
230
192
  litellmPort: this.resolved.litellmPort,
231
193
  proxyPort: this.resolved.proxyPort,
232
194
  mcpPath: MCP_PATH,
233
- tools: Object.keys(this.mcpTools),
234
195
  });
235
196
  }
236
197
 
@@ -260,7 +221,7 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
260
221
 
261
222
  toolkit(): Record<string, ToolkitEntry> {
262
223
  return Object.fromEntries(
263
- Object.entries(this.mcpTools).map(([name, tool]) => [
224
+ Object.keys(SCOPED_TOOL_FIELDS).map((name) => [
264
225
  name,
265
226
  {
266
227
  __toolkitRef: true as const,
@@ -268,8 +229,8 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
268
229
  localName: name,
269
230
  def: {
270
231
  name,
271
- description: tool.description,
272
- parameters: tool.inputSchema ?? { type: "object", properties: {} },
232
+ description: `Graphiti ${name.replaceAll("_", " ")}`,
233
+ parameters: { type: "object", properties: {} },
273
234
  },
274
235
  annotations: {
275
236
  effect: WRITE_TOOLS.has(name) ? ("write" as const) : ("read" as const),
@@ -286,6 +247,7 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
286
247
  signal?: AbortSignal,
287
248
  context?: { resourceId?: string },
288
249
  ): Promise<unknown> {
250
+ await this.ensureMcpTools();
289
251
  const tool = this.mcpTools[name];
290
252
  if (!tool?.execute) throw new Error(`Unknown Graphiti tool: ${name}`);
291
253
  const userId = context?.resourceId ?? executionContextUserId();
@@ -295,10 +257,7 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
295
257
  }
296
258
 
297
259
  private async forwardMcp(request: express.Request, response: express.Response): Promise<void> {
298
- if (!this.resolved) {
299
- response.status(503).json({ error: "Graphiti is not ready" });
300
- return;
301
- }
260
+ await this.ensureMcpTools();
302
261
  const userId = appkitIdentity.requestUserId(request) ?? executionContextUserId();
303
262
  const server = this.mcpServer(userId);
304
263
  await server.startHTTP({
@@ -309,6 +268,27 @@ export class GraphitiPlugin extends Plugin<GraphitiPluginConfig> {
309
268
  });
310
269
  }
311
270
 
271
+ private async ensureMcpTools(): Promise<void> {
272
+ if (Object.keys(this.mcpTools).length > 0) return;
273
+ if (!this.resolved) throw new Error("Graphiti sidecars have not launched");
274
+ this.mcp ??= new MCPClient({
275
+ id: `appkit-graphiti-${this.resolved.graphitiPort}`,
276
+ servers: {
277
+ graphiti: { url: new URL(`http://127.0.0.1:${this.resolved.proxyPort}/mcp`) },
278
+ },
279
+ });
280
+ const discovered = await this.mcp.listTools();
281
+ this.mcpTools = Object.fromEntries(
282
+ Object.entries(discovered)
283
+ .map(([name, tool]) => [name.replace(/^graphiti_/, ""), tool as Tool] as const)
284
+ .filter(([name]) => name in SCOPED_TOOL_FIELDS),
285
+ );
286
+ const missing = Object.keys(SCOPED_TOOL_FIELDS).filter((name) => !this.mcpTools[name]);
287
+ if (missing.length > 0) {
288
+ throw new Error(`Graphiti did not publish required scoped tools: ${missing.join(", ")}`);
289
+ }
290
+ }
291
+
312
292
  private mcpServer(userId: string): MCPServer {
313
293
  const existing = this.mcpServers.get(userId);
314
294
  if (existing) {
@@ -440,26 +420,6 @@ function scopedArguments(name: string, args: unknown, scope: string): Record<str
440
420
  return scoped;
441
421
  }
442
422
 
443
- async function waitForGraphiti(port: number): Promise<void> {
444
- for await (const ready of asyncModule.poll(
445
- async ({ signal }) => {
446
- try {
447
- const response = await fetch(`http://127.0.0.1:${port}/health`, { signal });
448
- return response.ok;
449
- } catch {
450
- return false;
451
- }
452
- },
453
- {
454
- intervalMs: 250,
455
- timeoutMs: SIDECAR_STARTUP_TIMEOUT_MS,
456
- predicate: (ready) => !ready,
457
- },
458
- )) {
459
- if (ready) return;
460
- }
461
- }
462
-
463
423
  async function availablePort(): Promise<number> {
464
424
  return new Promise((resolve, reject) => {
465
425
  const server = createServer();