@vfarcic/dot-ai 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/core/ai-provider-factory.d.ts.map +1 -1
  2. package/dist/core/ai-provider-factory.js +1 -2
  3. package/dist/core/embedding-service.d.ts.map +1 -1
  4. package/dist/core/model-config.d.ts +3 -4
  5. package/dist/core/model-config.d.ts.map +1 -1
  6. package/dist/core/model-config.js +4 -5
  7. package/dist/core/providers/vercel-provider.d.ts.map +1 -1
  8. package/dist/core/providers/vercel-provider.js +6 -5
  9. package/dist/core/rbac/audit-logger.d.ts +23 -0
  10. package/dist/core/rbac/audit-logger.d.ts.map +1 -0
  11. package/dist/core/rbac/audit-logger.js +63 -0
  12. package/dist/core/rbac/check-access.d.ts +48 -0
  13. package/dist/core/rbac/check-access.d.ts.map +1 -0
  14. package/dist/core/rbac/check-access.js +156 -0
  15. package/dist/core/rbac/index.d.ts +3 -0
  16. package/dist/core/rbac/index.d.ts.map +1 -0
  17. package/dist/core/rbac/index.js +11 -0
  18. package/dist/core/schema.d.ts.map +1 -1
  19. package/dist/core/schema.js +14 -1
  20. package/dist/interfaces/mcp.d.ts.map +1 -1
  21. package/dist/interfaces/mcp.js +129 -44
  22. package/dist/interfaces/rest-api.d.ts.map +1 -1
  23. package/dist/interfaces/rest-api.js +70 -1
  24. package/dist/tools/generate-manifests.d.ts.map +1 -1
  25. package/dist/tools/generate-manifests.js +22 -2
  26. package/dist/tools/manage-knowledge.d.ts.map +1 -1
  27. package/dist/tools/manage-knowledge.js +20 -0
  28. package/dist/tools/operate.d.ts.map +1 -1
  29. package/dist/tools/operate.js +37 -0
  30. package/dist/tools/organizational-data.d.ts.map +1 -1
  31. package/dist/tools/organizational-data.js +27 -0
  32. package/dist/tools/recommend.d.ts.map +1 -1
  33. package/dist/tools/recommend.js +24 -0
  34. package/dist/tools/remediate.d.ts.map +1 -1
  35. package/dist/tools/remediate.js +67 -18
  36. package/package.json +12 -9
  37. package/shared-prompts/prd-update-decisions.md +7 -0
@@ -29,6 +29,7 @@ const rest_registry_1 = require("./rest-registry");
29
29
  const rest_api_1 = require("./rest-api");
30
30
  const oauth_1 = require("./oauth");
31
31
  const request_context_1 = require("./request-context");
32
+ const rbac_1 = require("../core/rbac");
32
33
  const express_1 = __importDefault(require("express"));
33
34
  const router_js_1 = require("@modelcontextprotocol/sdk/server/auth/router.js");
34
35
  const error_response_1 = require("./error-response");
@@ -92,7 +93,9 @@ class MCPServer {
92
93
  */
93
94
  registerRestTool(name, description, inputSchema, handler, category, tags) {
94
95
  const restTracedHandler = async (args) => {
95
- return await (0, tracing_1.withToolTracing)(name, args, handler, { mcpClient: { name: 'http', version: 'rest-api' } });
96
+ return await (0, tracing_1.withToolTracing)(name, args, handler, {
97
+ mcpClient: { name: 'http', version: 'rest-api' },
98
+ });
96
99
  };
97
100
  this.restRegistry.registerTool({
98
101
  name,
@@ -100,7 +103,7 @@ class MCPServer {
100
103
  inputSchema: inputSchema,
101
104
  handler: restTracedHandler,
102
105
  category,
103
- tags
106
+ tags,
104
107
  });
105
108
  }
106
109
  /**
@@ -108,12 +111,32 @@ class MCPServer {
108
111
  */
109
112
  registerMcpTool(server, session, name, description, inputSchema, handler) {
110
113
  const mcpTracedHandler = async (args) => {
111
- return await (0, tracing_1.withToolTracing)(name, args, handler, { mcpClient: session.clientInfo });
114
+ // RBAC enforcement (PRD #392) invocation-time check as second layer of defense
115
+ const identity = (0, request_context_1.getCurrentIdentity)();
116
+ if (identity) {
117
+ const rbacResult = await (0, rbac_1.checkToolAccess)(identity, { toolName: name });
118
+ if (!rbacResult.allowed) {
119
+ return {
120
+ content: [
121
+ {
122
+ type: 'text',
123
+ text: JSON.stringify({
124
+ error: 'FORBIDDEN',
125
+ message: `Access denied: tool '${name}' not authorized for user '${identity.email}'`,
126
+ }),
127
+ },
128
+ ],
129
+ };
130
+ }
131
+ }
132
+ return await (0, tracing_1.withToolTracing)(name, args, handler, {
133
+ mcpClient: session.clientInfo,
134
+ });
112
135
  };
113
136
  /* eslint-disable @typescript-eslint/no-explicit-any -- MCP SDK type compatibility */
114
137
  server.registerTool(name, {
115
138
  description,
116
- inputSchema: inputSchema
139
+ inputSchema: inputSchema,
117
140
  }, mcpTracedHandler);
118
141
  /* eslint-enable @typescript-eslint/no-explicit-any */
119
142
  }
@@ -123,90 +146,123 @@ class MCPServer {
123
146
  getToolDefs() {
124
147
  return [
125
148
  {
126
- name: recommend_1.RECOMMEND_TOOL_NAME, description: recommend_1.RECOMMEND_TOOL_DESCRIPTION,
149
+ name: recommend_1.RECOMMEND_TOOL_NAME,
150
+ description: recommend_1.RECOMMEND_TOOL_DESCRIPTION,
127
151
  schema: recommend_1.RECOMMEND_TOOL_INPUT_SCHEMA,
128
152
  handler: async (args) => {
129
153
  const requestId = this.generateRequestId();
130
- this.logger.info(`Processing ${recommend_1.RECOMMEND_TOOL_NAME} tool request`, { requestId });
154
+ this.logger.info(`Processing ${recommend_1.RECOMMEND_TOOL_NAME} tool request`, {
155
+ requestId,
156
+ });
131
157
  if (!this.pluginManager)
132
158
  throw new Error('Plugin system not available. Recommend tool requires agentic-tools plugin.');
133
159
  return await (0, recommend_1.handleRecommendTool)(args, this.dotAI, this.logger, requestId, this.pluginManager);
134
160
  },
135
- category: 'Deployment', tags: ['recommendation', 'kubernetes', 'deployment', 'workflow'],
161
+ category: 'Deployment',
162
+ tags: ['recommendation', 'kubernetes', 'deployment', 'workflow'],
136
163
  },
137
164
  {
138
- name: version_1.VERSION_TOOL_NAME, description: version_1.VERSION_TOOL_DESCRIPTION,
165
+ name: version_1.VERSION_TOOL_NAME,
166
+ description: version_1.VERSION_TOOL_DESCRIPTION,
139
167
  schema: version_1.VERSION_TOOL_INPUT_SCHEMA,
140
168
  handler: async (args) => {
141
169
  const requestId = this.generateRequestId();
142
- this.logger.info(`Processing ${version_1.VERSION_TOOL_NAME} tool request`, { requestId });
170
+ this.logger.info(`Processing ${version_1.VERSION_TOOL_NAME} tool request`, {
171
+ requestId,
172
+ });
143
173
  return await (0, version_1.handleVersionTool)(args, this.logger, requestId);
144
174
  },
145
- category: 'System', tags: ['version', 'diagnostics', 'status'],
175
+ category: 'System',
176
+ tags: ['version', 'diagnostics', 'status'],
146
177
  },
147
178
  {
148
- name: organizational_data_1.ORGANIZATIONAL_DATA_TOOL_NAME, description: organizational_data_1.ORGANIZATIONAL_DATA_TOOL_DESCRIPTION,
179
+ name: organizational_data_1.ORGANIZATIONAL_DATA_TOOL_NAME,
180
+ description: organizational_data_1.ORGANIZATIONAL_DATA_TOOL_DESCRIPTION,
149
181
  schema: organizational_data_1.ORGANIZATIONAL_DATA_TOOL_INPUT_SCHEMA,
150
182
  handler: async (args) => {
151
183
  const requestId = this.generateRequestId();
152
184
  this.logger.info(`Processing ${organizational_data_1.ORGANIZATIONAL_DATA_TOOL_NAME} tool request`, { requestId });
153
185
  return await (0, organizational_data_1.handleOrganizationalDataTool)(args, this.dotAI, this.logger, requestId);
154
186
  },
155
- category: 'Management', tags: ['patterns', 'policies', 'capabilities', 'data'],
187
+ category: 'Management',
188
+ tags: ['patterns', 'policies', 'capabilities', 'data'],
156
189
  },
157
190
  {
158
- name: remediate_1.REMEDIATE_TOOL_NAME, description: remediate_1.REMEDIATE_TOOL_DESCRIPTION,
191
+ name: remediate_1.REMEDIATE_TOOL_NAME,
192
+ description: remediate_1.REMEDIATE_TOOL_DESCRIPTION,
159
193
  schema: remediate_1.REMEDIATE_TOOL_INPUT_SCHEMA,
160
194
  handler: async (args) => {
161
195
  const requestId = this.generateRequestId();
162
- this.logger.info(`Processing ${remediate_1.REMEDIATE_TOOL_NAME} tool request`, { requestId });
196
+ this.logger.info(`Processing ${remediate_1.REMEDIATE_TOOL_NAME} tool request`, {
197
+ requestId,
198
+ });
163
199
  if (!(0, plugin_registry_1.isPluginInitialized)())
164
200
  throw new Error('Plugin system not available. Remediate tool requires agentic-tools plugin for kubectl operations.');
165
201
  return await (0, remediate_1.handleRemediateTool)(args);
166
202
  },
167
- category: 'Troubleshooting', tags: ['remediation', 'troubleshooting', 'kubernetes', 'analysis'],
203
+ category: 'Troubleshooting',
204
+ tags: ['remediation', 'troubleshooting', 'kubernetes', 'analysis'],
168
205
  },
169
206
  {
170
- name: operate_1.OPERATE_TOOL_NAME, description: operate_1.OPERATE_TOOL_DESCRIPTION,
207
+ name: operate_1.OPERATE_TOOL_NAME,
208
+ description: operate_1.OPERATE_TOOL_DESCRIPTION,
171
209
  schema: operate_1.OPERATE_TOOL_INPUT_SCHEMA,
172
210
  handler: async (args) => {
173
211
  const requestId = this.generateRequestId();
174
- this.logger.info(`Processing ${operate_1.OPERATE_TOOL_NAME} tool request`, { requestId });
212
+ this.logger.info(`Processing ${operate_1.OPERATE_TOOL_NAME} tool request`, {
213
+ requestId,
214
+ });
175
215
  if (!this.pluginManager)
176
216
  throw new Error('Plugin system not available. Operate tool requires agentic-tools plugin for kubectl operations.');
177
217
  return await (0, operate_1.handleOperateTool)(args, this.pluginManager);
178
218
  },
179
- category: 'Operations', tags: ['operate', 'operations', 'kubernetes', 'day2', 'update', 'scale'],
219
+ category: 'Operations',
220
+ tags: [
221
+ 'operate',
222
+ 'operations',
223
+ 'kubernetes',
224
+ 'day2',
225
+ 'update',
226
+ 'scale',
227
+ ],
180
228
  },
181
229
  {
182
- name: project_setup_1.PROJECT_SETUP_TOOL_NAME, description: project_setup_1.PROJECT_SETUP_TOOL_DESCRIPTION,
230
+ name: project_setup_1.PROJECT_SETUP_TOOL_NAME,
231
+ description: project_setup_1.PROJECT_SETUP_TOOL_DESCRIPTION,
183
232
  schema: project_setup_1.PROJECT_SETUP_TOOL_INPUT_SCHEMA,
184
233
  handler: async (args) => {
185
234
  const requestId = this.generateRequestId();
186
235
  this.logger.info(`Processing ${project_setup_1.PROJECT_SETUP_TOOL_NAME} tool request`, { requestId });
187
236
  return await (0, project_setup_1.handleProjectSetupTool)(args, this.logger);
188
237
  },
189
- category: 'Project Setup', tags: ['governance', 'infrastructure', 'configuration', 'files'],
238
+ category: 'Project Setup',
239
+ tags: ['governance', 'infrastructure', 'configuration', 'files'],
190
240
  },
191
241
  {
192
- name: query_1.QUERY_TOOL_NAME, description: query_1.QUERY_TOOL_DESCRIPTION,
242
+ name: query_1.QUERY_TOOL_NAME,
243
+ description: query_1.QUERY_TOOL_DESCRIPTION,
193
244
  schema: query_1.QUERY_TOOL_INPUT_SCHEMA,
194
245
  handler: async (args) => {
195
246
  const requestId = this.generateRequestId();
196
- this.logger.info(`Processing ${query_1.QUERY_TOOL_NAME} tool request`, { requestId });
247
+ this.logger.info(`Processing ${query_1.QUERY_TOOL_NAME} tool request`, {
248
+ requestId,
249
+ });
197
250
  return await (0, query_1.handleQueryTool)(args, this.pluginManager);
198
251
  },
199
- category: 'Intelligence', tags: ['query', 'search', 'discover', 'capabilities', 'cluster'],
252
+ category: 'Intelligence',
253
+ tags: ['query', 'search', 'discover', 'capabilities', 'cluster'],
200
254
  },
201
255
  {
202
- name: manage_knowledge_1.MANAGE_KNOWLEDGE_TOOL_NAME, description: manage_knowledge_1.MANAGE_KNOWLEDGE_TOOL_DESCRIPTION,
256
+ name: manage_knowledge_1.MANAGE_KNOWLEDGE_TOOL_NAME,
257
+ description: manage_knowledge_1.MANAGE_KNOWLEDGE_TOOL_DESCRIPTION,
203
258
  schema: manage_knowledge_1.MANAGE_KNOWLEDGE_TOOL_INPUT_SCHEMA,
204
259
  handler: async (args) => {
205
260
  const requestId = this.generateRequestId();
206
261
  this.logger.info(`Processing ${manage_knowledge_1.MANAGE_KNOWLEDGE_TOOL_NAME} tool request`, { requestId });
207
262
  return await (0, manage_knowledge_1.handleManageKnowledgeTool)(args, this.dotAI, this.logger, requestId);
208
263
  },
209
- category: 'Knowledge', tags: ['knowledge', 'documents', 'ingest', 'semantic', 'search'],
264
+ category: 'Knowledge',
265
+ tags: ['knowledge', 'documents', 'ingest', 'semantic', 'search'],
210
266
  },
211
267
  ];
212
268
  }
@@ -228,13 +284,16 @@ class MCPServer {
228
284
  * Each MCP client session gets its own server instance (SDK limitation:
229
285
  * Protocol only supports one transport per server).
230
286
  */
231
- createSessionServer(session) {
287
+ async createSessionServer(session, authIdentity) {
232
288
  const server = new mcp_js_1.McpServer({ name: this.config.name, version: this.config.version }, { capabilities: { tools: {}, prompts: {} } });
233
289
  // Track client info per session
234
290
  server.server.oninitialized = () => {
235
291
  const clientVersion = server.server.getClientVersion();
236
292
  if (clientVersion) {
237
- session.clientInfo = { name: clientVersion.name, version: clientVersion.version };
293
+ session.clientInfo = {
294
+ name: clientVersion.name,
295
+ version: clientVersion.version,
296
+ };
238
297
  (0, telemetry_1.getTelemetry)().trackClientConnected(session.clientInfo);
239
298
  this.logger.info('MCP client connected', {
240
299
  client: clientVersion.name,
@@ -242,8 +301,10 @@ class MCPServer {
242
301
  });
243
302
  }
244
303
  };
245
- // Register all tools on this session server
246
- for (const def of this.getToolDefs()) {
304
+ // Register tools on this session server, filtered by RBAC (PRD #392)
305
+ const allDefs = this.getToolDefs();
306
+ const defs = await (0, rbac_1.filterAuthorizedTools)(authIdentity, allDefs);
307
+ for (const def of defs) {
247
308
  this.registerMcpTool(server, session, def.name, def.description, def.schema, def.handler);
248
309
  }
249
310
  // Register prompts
@@ -263,14 +324,19 @@ class MCPServer {
263
324
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK type compatibility
264
325
  server.server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => {
265
326
  const requestId = this.generateRequestId();
266
- this.logger.info('Processing prompts/get request', { requestId, promptName: request.params?.name });
327
+ this.logger.info('Processing prompts/get request', {
328
+ requestId,
329
+ promptName: request.params?.name,
330
+ });
267
331
  return await (0, prompts_1.handlePromptsGetRequest)(request.params || { name: '' }, this.logger, requestId);
268
332
  });
269
333
  }
270
334
  configureHostProvider() {
271
335
  const aiProvider = this.dotAI.ai;
272
336
  this.logger.info('Using configured AI Provider', {
273
- type: aiProvider.getProviderType ? aiProvider.getProviderType() : 'unknown'
337
+ type: aiProvider.getProviderType
338
+ ? aiProvider.getProviderType()
339
+ : 'unknown',
274
340
  });
275
341
  }
276
342
  /**
@@ -298,7 +364,11 @@ class MCPServer {
298
364
  this.initialized = true;
299
365
  }
300
366
  async startHttpTransport() {
301
- const port = process.env.PORT ? parseInt(process.env.PORT) : (this.config.port !== undefined ? this.config.port : 3456);
367
+ const port = process.env.PORT
368
+ ? parseInt(process.env.PORT)
369
+ : this.config.port !== undefined
370
+ ? this.config.port
371
+ : 3456;
302
372
  const host = process.env.HOST || this.config.host || '0.0.0.0';
303
373
  this.logger.info('Using HTTP/SSE transport', { port, host });
304
374
  // Create OAuth provider and Express sub-app with SDK router
@@ -328,7 +398,7 @@ class MCPServer {
328
398
  this.logger.debug('HTTP request received', {
329
399
  method: req.method,
330
400
  url: req.url,
331
- headers: req.headers
401
+ headers: req.headers,
332
402
  });
333
403
  // Handle CORS for browser-based clients
334
404
  res.setHeader('Access-Control-Allow-Origin', '*');
@@ -370,10 +440,14 @@ class MCPServer {
370
440
  if (!isOpenApiEndpoint) {
371
441
  const authResult = (0, oauth_1.checkBearerAuth)(req);
372
442
  if (!authResult.authorized) {
373
- this.logger.warn('Authentication failed', { message: authResult.message });
443
+ this.logger.warn('Authentication failed', {
444
+ message: authResult.message,
445
+ });
374
446
  const issuerHref = this.issuerUrl.href.replace(/\/$/, '');
375
447
  const resourceMetadataUrl = `${issuerHref}/.well-known/oauth-protected-resource`;
376
- (0, error_response_1.sendErrorResponse)(res, 401, 'UNAUTHORIZED', authResult.message || 'Authentication required', undefined, { 'WWW-Authenticate': `Bearer resource_metadata="${resourceMetadataUrl}"` });
448
+ (0, error_response_1.sendErrorResponse)(res, 401, 'UNAUTHORIZED', authResult.message || 'Authentication required', undefined, {
449
+ 'WWW-Authenticate': `Bearer resource_metadata="${resourceMetadataUrl}"`,
450
+ });
377
451
  endSpan(401);
378
452
  return;
379
453
  }
@@ -388,7 +462,9 @@ class MCPServer {
388
462
  }
389
463
  // Check if this is a REST API request
390
464
  if (this.restApiRouter.isApiRequest(req.url || '')) {
391
- this.logger.debug('Routing to REST API handler', { url: req.url });
465
+ this.logger.debug('Routing to REST API handler', {
466
+ url: req.url,
467
+ });
392
468
  // Mark span as REST API request
393
469
  span.setAttribute('request.type', 'rest-api');
394
470
  try {
@@ -410,7 +486,8 @@ class MCPServer {
410
486
  span.updateName('MCP ' + (req.url || '/'));
411
487
  try {
412
488
  // Determine if this is an initialize request (needs new transport)
413
- const isInit = req.method === 'POST' && body != null &&
489
+ const isInit = req.method === 'POST' &&
490
+ body != null &&
414
491
  (Array.isArray(body)
415
492
  ? body.some(m => (0, types_js_1.isInitializeRequest)(m))
416
493
  : (0, types_js_1.isInitializeRequest)(body));
@@ -418,16 +495,20 @@ class MCPServer {
418
495
  // Create a new McpServer + transport pair for this client session.
419
496
  // Each session gets its own McpServer instance because the SDK's
420
497
  // Protocol class only supports one transport at a time.
421
- const session = { lastActivity: Date.now() };
498
+ const session = {
499
+ lastActivity: Date.now(),
500
+ };
422
501
  const transport = new streamableHttp_js_1.StreamableHTTPServerTransport({
423
502
  sessionIdGenerator: () => (0, node_crypto_1.randomUUID)(),
424
503
  enableJsonResponse: false,
425
504
  onsessioninitialized: (sid) => {
426
- this.logger.info('Session initialized', { sessionId: sid });
505
+ this.logger.info('Session initialized', {
506
+ sessionId: sid,
507
+ });
427
508
  this.sessions.set(sid, session);
428
509
  },
429
510
  });
430
- const server = this.createSessionServer(session);
511
+ const server = await this.createSessionServer(session, authIdentity);
431
512
  session.server = server;
432
513
  session.transport = transport;
433
514
  transport.onclose = () => {
@@ -443,7 +524,9 @@ class MCPServer {
443
524
  else {
444
525
  // Route to existing session by Mcp-Session-Id header
445
526
  const sessionId = req.headers['mcp-session-id'];
446
- const session = sessionId ? this.sessions.get(sessionId) : undefined;
527
+ const session = sessionId
528
+ ? this.sessions.get(sessionId)
529
+ : undefined;
447
530
  if (!session) {
448
531
  (0, error_response_1.sendErrorResponse)(res, 404, 'SESSION_NOT_FOUND', 'Session not found');
449
532
  endSpan(404);
@@ -485,7 +568,7 @@ class MCPServer {
485
568
  async parseRequestBody(req) {
486
569
  return new Promise((resolve, reject) => {
487
570
  let body = '';
488
- req.on('data', chunk => body += chunk.toString());
571
+ req.on('data', chunk => (body += chunk.toString()));
489
572
  req.on('end', () => {
490
573
  try {
491
574
  resolve(body ? JSON.parse(body) : undefined);
@@ -513,12 +596,14 @@ class MCPServer {
513
596
  try {
514
597
  await session.server.close();
515
598
  }
516
- catch { /* ignore */ }
599
+ catch {
600
+ /* ignore */
601
+ }
517
602
  this.sessions.delete(sid);
518
603
  }
519
604
  // Stop HTTP server if running
520
605
  if (this.httpServer) {
521
- await new Promise((resolve) => {
606
+ await new Promise(resolve => {
522
607
  this.httpServer.close(() => {
523
608
  this.logger.info('HTTP server stopped');
524
609
  resolve();
@@ -1 +1 @@
1
- {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/rest-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/rest-api.ts"],"names":[],"mappings":"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"}
@@ -57,6 +57,8 @@ const mermaid_tools_1 = require("../core/mermaid-tools");
57
57
  const plugin_registry_1 = require("../core/plugin-registry");
58
58
  const manage_knowledge_1 = require("../tools/manage-knowledge");
59
59
  const user_management_1 = require("./oauth/user-management");
60
+ const request_context_1 = require("./request-context");
61
+ const rbac_1 = require("../core/rbac");
60
62
  /**
61
63
  * HTTP status codes for REST responses
62
64
  */
@@ -222,7 +224,27 @@ class RestApiRouter {
222
224
  const category = searchParams.get('category') || undefined;
223
225
  const tag = searchParams.get('tag') || undefined;
224
226
  const search = searchParams.get('search') || undefined;
225
- const tools = this.registry.getToolsFiltered({ category, tag, search });
227
+ let tools = this.registry.getToolsFiltered({ category, tag, search });
228
+ // RBAC-filtered tool discovery (PRD #392) — OAuth users only see authorized tools
229
+ const discoveryIdentity = (0, request_context_1.getCurrentIdentity)();
230
+ tools = await (0, rbac_1.filterAuthorizedTools)(discoveryIdentity, tools);
231
+ // Check user management access and include as virtual "users" tool (PRD #392)
232
+ const userAccessResult = await (0, rbac_1.checkToolAccess)(discoveryIdentity, {
233
+ toolName: 'manageUsers',
234
+ resource: 'users',
235
+ });
236
+ if (userAccessResult.allowed) {
237
+ tools = [
238
+ ...tools,
239
+ {
240
+ name: 'users',
241
+ description: 'Manage users (create, list, delete)',
242
+ schema: { type: 'object', properties: {} },
243
+ category: 'Administration',
244
+ tags: ['users', 'administration', 'management'],
245
+ },
246
+ ];
247
+ }
226
248
  const categories = this.registry.getCategories();
227
249
  const tags = this.registry.getTags();
228
250
  const response = {
@@ -261,6 +283,15 @@ class RestApiRouter {
261
283
  await this.sendErrorResponse(res, requestId, HttpStatus.NOT_FOUND, 'TOOL_NOT_FOUND', `Tool '${toolName}' not found`);
262
284
  return;
263
285
  }
286
+ // RBAC enforcement (PRD #392) — check tool-level authorization for OAuth users
287
+ const identity = (0, request_context_1.getCurrentIdentity)();
288
+ if (identity) {
289
+ const rbacResult = await (0, rbac_1.checkToolAccess)(identity, { toolName });
290
+ if (!rbacResult.allowed) {
291
+ await this.sendErrorResponse(res, requestId, 403, 'FORBIDDEN', `Access denied: tool '${toolName}' not authorized for user '${identity.email}'`);
292
+ return;
293
+ }
294
+ }
264
295
  // Validate request body
265
296
  if (!body || typeof body !== 'object') {
266
297
  await this.sendErrorResponse(res, requestId, HttpStatus.BAD_REQUEST, 'INVALID_REQUEST', 'Request body must be a JSON object');
@@ -1795,6 +1826,18 @@ class RestApiRouter {
1795
1826
  */
1796
1827
  async handleCreateUser(_req, res, requestId, body) {
1797
1828
  try {
1829
+ // RBAC enforcement (PRD #392) — user management requires dotai-admin role
1830
+ const identity = (0, request_context_1.getCurrentIdentity)();
1831
+ if (identity) {
1832
+ const rbacResult = await (0, rbac_1.checkToolAccess)(identity, {
1833
+ toolName: 'users',
1834
+ resource: 'users',
1835
+ });
1836
+ if (!rbacResult.allowed) {
1837
+ await this.sendErrorResponse(res, requestId, 403, 'FORBIDDEN', 'User management requires dotai-admin role');
1838
+ return;
1839
+ }
1840
+ }
1798
1841
  if (!body ||
1799
1842
  typeof body !== 'object' ||
1800
1843
  !('email' in body) ||
@@ -1812,6 +1855,7 @@ class RestApiRouter {
1812
1855
  return;
1813
1856
  }
1814
1857
  const result = await (0, user_management_1.createUser)(email, password);
1858
+ (0, rbac_1.logUserManagementOperation)(identity, 'created', email);
1815
1859
  await this.sendJsonResponse(res, HttpStatus.OK, {
1816
1860
  success: true,
1817
1861
  data: result,
@@ -1839,6 +1883,18 @@ class RestApiRouter {
1839
1883
  */
1840
1884
  async handleListUsers(_req, res, requestId) {
1841
1885
  try {
1886
+ // RBAC enforcement (PRD #392) — user management requires dotai-admin role
1887
+ const identity = (0, request_context_1.getCurrentIdentity)();
1888
+ if (identity) {
1889
+ const rbacResult = await (0, rbac_1.checkToolAccess)(identity, {
1890
+ toolName: 'users',
1891
+ resource: 'users',
1892
+ });
1893
+ if (!rbacResult.allowed) {
1894
+ await this.sendErrorResponse(res, requestId, 403, 'FORBIDDEN', 'User management requires dotai-admin role');
1895
+ return;
1896
+ }
1897
+ }
1842
1898
  const users = await (0, user_management_1.listUsers)();
1843
1899
  await this.sendJsonResponse(res, HttpStatus.OK, {
1844
1900
  success: true,
@@ -1861,6 +1917,18 @@ class RestApiRouter {
1861
1917
  */
1862
1918
  async handleDeleteUser(_req, res, requestId, email) {
1863
1919
  try {
1920
+ // RBAC enforcement (PRD #392) — user management requires dotai-admin role
1921
+ const identity = (0, request_context_1.getCurrentIdentity)();
1922
+ if (identity) {
1923
+ const rbacResult = await (0, rbac_1.checkToolAccess)(identity, {
1924
+ toolName: 'users',
1925
+ resource: 'users',
1926
+ });
1927
+ if (!rbacResult.allowed) {
1928
+ await this.sendErrorResponse(res, requestId, 403, 'FORBIDDEN', 'User management requires dotai-admin role');
1929
+ return;
1930
+ }
1931
+ }
1864
1932
  let decodedEmail;
1865
1933
  try {
1866
1934
  decodedEmail = decodeURIComponent(email);
@@ -1870,6 +1938,7 @@ class RestApiRouter {
1870
1938
  return;
1871
1939
  }
1872
1940
  const result = await (0, user_management_1.deleteUser)(decodedEmail);
1941
+ (0, rbac_1.logUserManagementOperation)(identity, 'deleted', decodedEmail);
1873
1942
  await this.sendJsonResponse(res, HttpStatus.OK, {
1874
1943
  success: true,
1875
1944
  data: result,
@@ -1 +1 @@
1
- {"version":3,"file":"generate-manifests.d.ts","sourceRoot":"","sources":["../../src/tools/generate-manifests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,EAAE,KAAK,EAA0B,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAgBhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAsD5D,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAC/D,eAAO,MAAM,kCAAkC,+IAC+F,CAAC;AAG/I,eAAO,MAAM,mCAAmC;;;CAa/C,CAAC;AAq8BF;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,EACrD,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CA0WxD"}
1
+ {"version":3,"file":"generate-manifests.d.ts","sourceRoot":"","sources":["../../src/tools/generate-manifests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,EAAE,KAAK,EAA0B,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAgBhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA8E5D,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAC/D,eAAO,MAAM,kCAAkC,+IAC+F,CAAC;AAG/I,eAAO,MAAM,mCAAmC;;;CAa/C,CAAC;AAq8BF;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,EACrD,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CA0WxD"}
@@ -57,7 +57,27 @@ const solution_cr_1 = require("../core/solution-cr");
57
57
  const packaging_1 = require("../core/packaging");
58
58
  const visualization_1 = require("../core/visualization");
59
59
  const plugin_registry_1 = require("../core/plugin-registry");
60
+ const request_context_1 = require("../interfaces/request-context");
61
+ const rbac_1 = require("../core/rbac");
60
62
  // PRD #359: All helm operations via unified plugin registry
63
+ /**
64
+ * PRD #392 Milestone 2: Build agent instructions based on deploy permission.
65
+ * When the user has 'apply' permission, includes the deploy option.
66
+ * When they don't, explains that deploying requires 'apply' permission.
67
+ */
68
+ async function buildDeployInstructions(outputPath, outputFormat) {
69
+ const writeInstr = `Write the files to "${outputPath}".`;
70
+ const formatInstr = outputFormat === 'helm' ? ' The output is a Helm chart.' : outputFormat === 'raw' ? '' : ' The output is a Kustomize overlay.';
71
+ const identity = (0, request_context_1.getCurrentIdentity)();
72
+ const rbacResult = await (0, rbac_1.checkToolAccess)(identity, {
73
+ toolName: 'recommend',
74
+ verb: 'apply',
75
+ });
76
+ if (rbacResult.allowed) {
77
+ return `${writeInstr}${formatInstr} If immediate deployment is desired, call the recommend tool with stage: "deployManifests".`;
78
+ }
79
+ return `${writeInstr}${formatInstr} Deploying manifests requires 'apply' permission on 'recommend', which is not granted for the current user. Save the files locally or push to Git to apply them through your own workflow.`;
80
+ }
61
81
  /**
62
82
  * Ensure tmp directory exists
63
83
  */
@@ -915,7 +935,7 @@ async function handleGenerateManifestsTool(args, dotAI, logger, requestId, plugi
915
935
  validationAttempts: attempt,
916
936
  packagingAttempts: packagingResult.attempts,
917
937
  timestamp: new Date().toISOString(),
918
- agentInstructions: `Write the files to "${outputPath}". The output is a ${outputFormat === 'helm' ? 'Helm chart' : 'Kustomize overlay'}. If immediate deployment is desired, call the recommend tool with stage: "deployManifests".`,
938
+ agentInstructions: await buildDeployInstructions(outputPath, outputFormat),
919
939
  ...(visualizationUrl ? { visualizationUrl } : {}),
920
940
  };
921
941
  // Build content blocks - JSON for REST API, agent instruction for MCP agents
@@ -957,7 +977,7 @@ async function handleGenerateManifestsTool(args, dotAI, logger, requestId, plugi
957
977
  files: [{ relativePath: 'manifests.yaml', content: manifests }],
958
978
  validationAttempts: attempt,
959
979
  timestamp: new Date().toISOString(),
960
- agentInstructions: `Write the files to "${outputPath}". If immediate deployment is desired, call the recommend tool with stage: "deployManifests".`,
980
+ agentInstructions: await buildDeployInstructions(outputPath, outputFormat),
961
981
  ...(visualizationUrl ? { visualizationUrl } : {}),
962
982
  };
963
983
  // Build content blocks - JSON for REST API, agent instruction for MCP agents
@@ -1 +1 @@
1
- {"version":3,"file":"manage-knowledge.d.ts","sourceRoot":"","sources":["../../src/tools/manage-knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,OAAO,EAIL,yBAAyB,EAE1B,MAAM,yBAAyB,CAAC;AAQjC,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,iCAAiC,QAKgB,CAAC;AAG/D,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;CAkC9C,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiPD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CA4HrC;AA2ND;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAgBD;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,KAAK,GAAG,IAAI,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CA8B1B"}
1
+ {"version":3,"file":"manage-knowledge.d.ts","sourceRoot":"","sources":["../../src/tools/manage-knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,OAAO,EAIL,yBAAyB,EAE1B,MAAM,yBAAyB,CAAC;AAUjC,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,iCAAiC,QAKgB,CAAC;AAG/D,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;CAkC9C,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiPD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CA4HrC;AA2ND;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAgBD;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,KAAK,GAAG,IAAI,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAiD1B"}
@@ -14,6 +14,8 @@ exports.handleManageKnowledgeTool = handleManageKnowledgeTool;
14
14
  const zod_1 = require("zod");
15
15
  const plugin_registry_1 = require("../core/plugin-registry");
16
16
  const embedding_service_1 = require("../core/embedding-service");
17
+ const request_context_1 = require("../interfaces/request-context");
18
+ const rbac_1 = require("../core/rbac");
17
19
  /**
18
20
  * Collection name for knowledge base chunks in Qdrant
19
21
  */
@@ -550,6 +552,24 @@ async function handleManageKnowledgeTool(args, _dotAI, logger, requestId) {
550
552
  requestId,
551
553
  operation: args.operation,
552
554
  });
555
+ // PRD #392 Milestone 8: Mutating operations require 'apply' verb
556
+ const MUTATING_KNOWLEDGE_OPS = new Set(['ingest', 'deleteByUri']);
557
+ if (MUTATING_KNOWLEDGE_OPS.has(args.operation)) {
558
+ const identity = (0, request_context_1.getCurrentIdentity)();
559
+ const rbacResult = await (0, rbac_1.checkToolAccess)(identity, {
560
+ toolName: 'manageKnowledge',
561
+ verb: 'apply',
562
+ });
563
+ if (!rbacResult.allowed) {
564
+ return wrapMcpResponse({
565
+ error: 'FORBIDDEN',
566
+ message: `Access denied: '${args.operation}' on knowledge base requires 'apply' permission on 'manageKnowledge'. Search is available with 'execute' permission.`,
567
+ tool: 'manageKnowledge',
568
+ operation: args.operation,
569
+ user: identity?.email,
570
+ });
571
+ }
572
+ }
553
573
  // Route to appropriate handler based on operation
554
574
  let response;
555
575
  switch (args.operation) {
@@ -1 +1 @@
1
- {"version":3,"file":"operate.d.ts","sourceRoot":"","sources":["../../src/tools/operate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAIL,MAAM,EAEP,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAIvD,OAAO,EACL,qBAAqB,EACrB,YAAY,EACb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,wBAAwB,6TACuR,CAAC;AAG7T,eAAO,MAAM,yBAAyB;;;;;;CA+BrC,CAAC;AAGF,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB;IAC/D,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,eAAe,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,EAAE;QAChB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;QAC7B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,EAAE;QACL,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QACjC,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EACF,WAAW,GACX,mBAAmB,GACnB,WAAW,GACX,uBAAuB,GACvB,sBAAsB,GACtB,QAAQ,CAAC;IACb,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;CACtC;AAGD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,kBAAkB,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,YAAY,EAAE,kBAAkB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,wBAAwB,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,eAAe,CAAC;QACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,gBAAgB,EAAE;YAChB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;YAC7B,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,KAAK,EAAE;YACL,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;YACjC,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,eAAe,EAAE,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,CAAC,CAkF1B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAiBxE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAkB/D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAgB7E;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,YAAY,EAClB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,aAAa,CAAC,CAyDxB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,YAAY,EAClB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAoB7D"}
1
+ {"version":3,"file":"operate.d.ts","sourceRoot":"","sources":["../../src/tools/operate.ts"],"names":[],"mappings":"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"}