opalserve 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +19 -0
- package/AGENTS.md +23 -0
- package/README.md +109 -0
- package/config/servers.example.yaml +67 -0
- package/config/servers.yaml +2 -0
- package/dist/cli/discover.d.ts +3 -0
- package/dist/cli/discover.d.ts.map +1 -0
- package/dist/cli/discover.js +160 -0
- package/dist/cli/discover.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +32 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/connectors/base.d.ts +49 -0
- package/dist/connectors/base.d.ts.map +1 -0
- package/dist/connectors/base.js +45 -0
- package/dist/connectors/base.js.map +1 -0
- package/dist/connectors/custom.d.ts +19 -0
- package/dist/connectors/custom.d.ts.map +1 -0
- package/dist/connectors/custom.js +129 -0
- package/dist/connectors/custom.js.map +1 -0
- package/dist/connectors/github.d.ts +18 -0
- package/dist/connectors/github.d.ts.map +1 -0
- package/dist/connectors/github.js +188 -0
- package/dist/connectors/github.js.map +1 -0
- package/dist/connectors/google-drive.d.ts +18 -0
- package/dist/connectors/google-drive.d.ts.map +1 -0
- package/dist/connectors/google-drive.js +209 -0
- package/dist/connectors/google-drive.js.map +1 -0
- package/dist/connectors/index.d.ts +11 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +76 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/postgres.d.ts +18 -0
- package/dist/connectors/postgres.d.ts.map +1 -0
- package/dist/connectors/postgres.js +140 -0
- package/dist/connectors/postgres.js.map +1 -0
- package/dist/connectors/slack.d.ts +18 -0
- package/dist/connectors/slack.d.ts.map +1 -0
- package/dist/connectors/slack.js +181 -0
- package/dist/connectors/slack.js.map +1 -0
- package/dist/core/auth.d.ts +26 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +81 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/registry.d.ts +33 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +237 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/tokenizer.d.ts +16 -0
- package/dist/core/tokenizer.d.ts.map +1 -0
- package/dist/core/tokenizer.js +29 -0
- package/dist/core/tokenizer.js.map +1 -0
- package/dist/governance/audit.d.ts +27 -0
- package/dist/governance/audit.d.ts.map +1 -0
- package/dist/governance/audit.js +149 -0
- package/dist/governance/audit.js.map +1 -0
- package/dist/governance/index.d.ts +5 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +5 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/policy.d.ts +20 -0
- package/dist/governance/policy.d.ts.map +1 -0
- package/dist/governance/policy.js +162 -0
- package/dist/governance/policy.js.map +1 -0
- package/dist/governance/rate-limiter.d.ts +20 -0
- package/dist/governance/rate-limiter.d.ts.map +1 -0
- package/dist/governance/rate-limiter.js +73 -0
- package/dist/governance/rate-limiter.js.map +1 -0
- package/dist/governance/types.d.ts +246 -0
- package/dist/governance/types.d.ts.map +1 -0
- package/dist/governance/types.js +72 -0
- package/dist/governance/types.js.map +1 -0
- package/dist/identity/access-control.d.ts +15 -0
- package/dist/identity/access-control.d.ts.map +1 -0
- package/dist/identity/access-control.js +81 -0
- package/dist/identity/access-control.js.map +1 -0
- package/dist/identity/index.d.ts +4 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +4 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/manager.d.ts +29 -0
- package/dist/identity/manager.d.ts.map +1 -0
- package/dist/identity/manager.js +167 -0
- package/dist/identity/manager.js.map +1 -0
- package/dist/identity/types.d.ts +237 -0
- package/dist/identity/types.d.ts.map +1 -0
- package/dist/identity/types.js +80 -0
- package/dist/identity/types.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/registry/server.d.ts +14 -0
- package/dist/registry/server.d.ts.map +1 -0
- package/dist/registry/server.js +173 -0
- package/dist/registry/server.js.map +1 -0
- package/dist/types/index.d.ts +639 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +76 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/config.d.ts +29 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +47 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +44 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/workflow/engine.d.ts +18 -0
- package/dist/workflow/engine.d.ts.map +1 -0
- package/dist/workflow/engine.js +155 -0
- package/dist/workflow/engine.js.map +1 -0
- package/dist/workflow/index.d.ts +4 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +4 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/templates.d.ts +4 -0
- package/dist/workflow/templates.d.ts.map +1 -0
- package/dist/workflow/templates.js +218 -0
- package/dist/workflow/templates.js.map +1 -0
- package/dist/workflow/types.d.ts +255 -0
- package/dist/workflow/types.d.ts.map +1 -0
- package/dist/workflow/types.js +48 -0
- package/dist/workflow/types.js.map +1 -0
- package/eslint.config.js +25 -0
- package/package.json +78 -0
- package/src/cli/discover.ts +223 -0
- package/src/cli/index.ts +40 -0
- package/src/connectors/base.ts +75 -0
- package/src/connectors/custom.ts +139 -0
- package/src/connectors/github.ts +195 -0
- package/src/connectors/google-drive.ts +217 -0
- package/src/connectors/index.ts +86 -0
- package/src/connectors/postgres.ts +148 -0
- package/src/connectors/slack.ts +188 -0
- package/src/core/auth.ts +109 -0
- package/src/core/registry.ts +301 -0
- package/src/core/tokenizer.ts +40 -0
- package/src/governance/audit.ts +182 -0
- package/src/governance/index.ts +4 -0
- package/src/governance/policy.ts +187 -0
- package/src/governance/rate-limiter.ts +95 -0
- package/src/governance/types.ts +100 -0
- package/src/identity/access-control.ts +119 -0
- package/src/identity/index.ts +3 -0
- package/src/identity/manager.ts +207 -0
- package/src/identity/types.ts +91 -0
- package/src/index.ts +16 -0
- package/src/registry/server.ts +195 -0
- package/src/types/index.ts +128 -0
- package/src/utils/config.ts +78 -0
- package/src/utils/index.ts +47 -0
- package/src/workflow/engine.ts +187 -0
- package/src/workflow/index.ts +3 -0
- package/src/workflow/templates.ts +220 -0
- package/src/workflow/types.ts +89 -0
- package/tsconfig.json +25 -0
package/.env.example
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# MCP Registry Configuration
|
|
2
|
+
PORT=3000
|
|
3
|
+
HOST=localhost
|
|
4
|
+
LOG_LEVEL=info
|
|
5
|
+
|
|
6
|
+
# Security
|
|
7
|
+
JWT_SECRET=your-secret-key-change-in-production
|
|
8
|
+
API_KEY=your-api-key
|
|
9
|
+
|
|
10
|
+
# Server Configurations
|
|
11
|
+
GITHUB_TOKEN=your-github-token
|
|
12
|
+
SLACK_BOT_TOKEN=xoxb-your-slack-token
|
|
13
|
+
POSTGRES_URL=postgresql://localhost:5432/mcp
|
|
14
|
+
GOOGLE_SERVICE_ACCOUNT=./config/google-service-account.json
|
|
15
|
+
|
|
16
|
+
# Registry Settings
|
|
17
|
+
MAX_TOOLS_PER_RESPONSE=50
|
|
18
|
+
CONTEXT_TOKEN_BUDGET=128000
|
|
19
|
+
ENABLE_AUTH=false
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Great — here's the full architect's breakdown. Let me start with the conceptual foundation, then get concrete on building.
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
**What MCP actually is (no fluff):**
|
|
6
|
+
|
|
7
|
+
MCP was introduced by Anthropic in November 2024 as an open standard to solve the "N×M" integration problem — before MCP, developers had to build a custom connector for every combination of AI model and data source. It's a client-server protocol where the AI model acts as the MCP client, and tools/databases/APIs act as MCP servers. Communication follows JSON-RPC 2.0 over either stdio for local processes or HTTP with Server-Sent Events for remote servers.
|
|
8
|
+
|
|
9
|
+
The current MCP spec focuses on "Host-to-Server" communication. The next frontier — which is exactly what your project targets — is "Agent-to-Agent" communication.
|
|
10
|
+
|
|
11
|
+
The enterprise pain points are real: context bloat when thousands of tools must be loaded into an agent's window, missing identity standards for fine-grained authorization, and the "Confused Deputy" security problem where malicious prompts can trick an agent into doing unauthorized actions. These are exactly the gaps your interop layer would solve.Here's a full architecture diagram showing how MCP works today, and where your interop bridge layer fits on top of it:Now here's the concrete build roadmap — broken into 3 phases with exact tech choices and the UI mockup of the visual workflow builder:---
|
|
12
|
+
|
|
13
|
+
Here's the thing that makes this project genuinely timely as of April 7, 2026:
|
|
14
|
+
|
|
15
|
+
The most consequential MCP development in 2026 isn't in the spec itself — it's the governance transfer to the Linux Foundation's Agentic AI Foundation. The USB-C analogy is apt but incomplete: USB-C works because no single manufacturer controls the spec. Protocols that stay with their original creator follow a predictable path where the spec evolves to match the company's product roadmap. This transfer means MCP is becoming a true open standard — and the tooling ecosystem above it is wide open.
|
|
16
|
+
|
|
17
|
+
MCP's 2026 roadmap has maintainers turning attention to what needs to be fixed before the protocol can hold up in real production use — and the exact gaps (auth, agent-to-agent discovery, governance) are precisely what your bridge layer fills.
|
|
18
|
+
|
|
19
|
+
Tools represent 99% of tracked MCP client adoption — but the enterprise pain points remain: context bloat from loading all tool definitions at once, no standardized user identity propagation, and the "Confused Deputy" security problem where malicious prompts can trick agents into unauthorized actions.
|
|
20
|
+
|
|
21
|
+
**The business angle is real too:** the enterprise agentic AI market has reached $7.51 billion in 2026, with 40% of all enterprise software now featuring deeply integrated task-specific AI agents — and 72% of organizations report a critical shortage of "agentic engineers" who can actually architect autonomous workflows. Your visual workflow builder directly addresses that shortage by making agentic systems accessible to non-engineers.
|
|
22
|
+
|
|
23
|
+
The fastest path to a working demo is: start with Phase 1 only (the registry + discovery endpoint), point it at 5 real MCP servers (GitHub, Slack, Postgres, Google Drive, a custom one you write), and build a small CLI tool that shows an agent asking "what can I do?" and getting back a smart, context-sized answer. That demo alone is shareable and technically impressive. Want me to write the actual code for Phase 1 right now?
|
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Nexus
|
|
2
|
+
|
|
3
|
+
**MCP Tool Registry & Discovery Hub for Enterprise AI Agents**
|
|
4
|
+
|
|
5
|
+
Nexus solves the "N×M" integration problem in AI agent tooling. Instead of building custom connectors for every AI model and tool combination, Nexus provides a centralized registry with intelligent, context-sized tool discovery.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Intelligent Discovery**: Context-sized responses with relevance scoring
|
|
10
|
+
- **5 Pre-built Connectors**: GitHub, Slack, PostgreSQL, Google Drive, Custom
|
|
11
|
+
- **40+ Tools**: Ready-to-use MCP tools with full schema documentation
|
|
12
|
+
- **Security First**: JWT auth, fine-grained authorization, Confused Deputy prevention
|
|
13
|
+
- **Zero-Dependency HTTP**: Uses native Node.js fetch (no axios - security fix!)
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Install dependencies
|
|
19
|
+
pnpm install
|
|
20
|
+
|
|
21
|
+
# Configure environment
|
|
22
|
+
cp .env.example .env
|
|
23
|
+
# Edit .env with your tokens
|
|
24
|
+
|
|
25
|
+
# Start the registry
|
|
26
|
+
pnpm start
|
|
27
|
+
|
|
28
|
+
# Discover available tools
|
|
29
|
+
pnpm discover "what can I do?"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
36
|
+
│ N E X U S │
|
|
37
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐│
|
|
38
|
+
│ │ Discovery │ │ Auth & │ │ Tool Registry ││
|
|
39
|
+
│ │ Endpoint │──│ Authorization│──│ & Indexing ││
|
|
40
|
+
│ └─────────────┘ └─────────────┘ └─────────────────────┘│
|
|
41
|
+
└─────────────────────────────────────────────────────────────┘
|
|
42
|
+
│ │ │
|
|
43
|
+
▼ ▼ ▼
|
|
44
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
45
|
+
│ GitHub │ │ Slack │ │ PostgreSQL │
|
|
46
|
+
│ Connector │ │ Connector │ │ Connector │
|
|
47
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
48
|
+
│ │ │
|
|
49
|
+
▼ ▼ ▼
|
|
50
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
51
|
+
│ Google Drive│ │ Custom │ │ More... │
|
|
52
|
+
│ Connector │ │ Connector │ │ │
|
|
53
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## API Endpoints
|
|
57
|
+
|
|
58
|
+
| Method | Endpoint | Description |
|
|
59
|
+
|--------|----------|-------------|
|
|
60
|
+
| GET | `/api/v1/health` | Health check |
|
|
61
|
+
| GET | `/api/v1/discover?query=<text>` | Discover available tools |
|
|
62
|
+
| GET | `/api/v1/tools` | List all registered tools |
|
|
63
|
+
| GET | `/api/v1/tools/:id` | Get specific tool details |
|
|
64
|
+
| GET | `/api/v1/servers` | List registered MCP servers |
|
|
65
|
+
| POST | `/api/v1/servers/register` | Register a new MCP server |
|
|
66
|
+
| POST | `/api/v1/auth/token` | Generate JWT token |
|
|
67
|
+
|
|
68
|
+
## Discovery Query Examples
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# What can I do with GitHub?
|
|
72
|
+
nexus-discover "github repository"
|
|
73
|
+
|
|
74
|
+
# Find messaging tools
|
|
75
|
+
nexus-discover "slack message channel"
|
|
76
|
+
|
|
77
|
+
# Database operations
|
|
78
|
+
nexus-discover "postgres query database"
|
|
79
|
+
|
|
80
|
+
# File operations
|
|
81
|
+
nexus-discover "google drive files"
|
|
82
|
+
|
|
83
|
+
# Custom HTTP operations
|
|
84
|
+
nexus-discover "http request webhook"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Security
|
|
88
|
+
|
|
89
|
+
- **JWT Authentication**: Secure agent identity propagation
|
|
90
|
+
- **Fine-grained Authorization**: Permission-based access control
|
|
91
|
+
- **Confused Deputy Prevention**: Prevents malicious prompt injection
|
|
92
|
+
- **No External HTTP Dependencies**: Uses native Node.js fetch (post-axios vulnerability)
|
|
93
|
+
|
|
94
|
+
## Environment Variables
|
|
95
|
+
|
|
96
|
+
```env
|
|
97
|
+
PORT=3000
|
|
98
|
+
HOST=localhost
|
|
99
|
+
JWT_SECRET=your-secret-key
|
|
100
|
+
GITHUB_TOKEN=ghp_xxx
|
|
101
|
+
SLACK_BOT_TOKEN=xoxb-xxx
|
|
102
|
+
POSTGRES_URL=postgresql://...
|
|
103
|
+
GOOGLE_SERVICE_ACCOUNT=./config/google-service-account.json
|
|
104
|
+
ENABLE_AUTH=false
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# MCP Interoperability Layer - Server Configuration
|
|
2
|
+
# This file defines the MCP servers to register with the registry
|
|
3
|
+
|
|
4
|
+
servers:
|
|
5
|
+
- id: github
|
|
6
|
+
name: GitHub
|
|
7
|
+
type: github
|
|
8
|
+
enabled: true
|
|
9
|
+
description: GitHub MCP server for repository, issue, and PR management
|
|
10
|
+
auth:
|
|
11
|
+
type: api-key
|
|
12
|
+
envVar: GITHUB_TOKEN
|
|
13
|
+
tags:
|
|
14
|
+
- repository
|
|
15
|
+
- github
|
|
16
|
+
- code
|
|
17
|
+
|
|
18
|
+
- id: slack
|
|
19
|
+
name: Slack
|
|
20
|
+
type: slack
|
|
21
|
+
enabled: true
|
|
22
|
+
description: Slack MCP server for messaging and channel management
|
|
23
|
+
auth:
|
|
24
|
+
type: api-key
|
|
25
|
+
envVar: SLACK_BOT_TOKEN
|
|
26
|
+
tags:
|
|
27
|
+
- messaging
|
|
28
|
+
- slack
|
|
29
|
+
- notifications
|
|
30
|
+
|
|
31
|
+
- id: postgres
|
|
32
|
+
name: PostgreSQL
|
|
33
|
+
type: postgres
|
|
34
|
+
enabled: true
|
|
35
|
+
description: PostgreSQL MCP server for database operations
|
|
36
|
+
auth:
|
|
37
|
+
type: none
|
|
38
|
+
envVar: POSTGRES_URL
|
|
39
|
+
tags:
|
|
40
|
+
- database
|
|
41
|
+
- postgres
|
|
42
|
+
- sql
|
|
43
|
+
|
|
44
|
+
- id: google-drive
|
|
45
|
+
name: Google Drive
|
|
46
|
+
type: google-drive
|
|
47
|
+
enabled: true
|
|
48
|
+
description: Google Drive MCP server for file management
|
|
49
|
+
auth:
|
|
50
|
+
type: oauth
|
|
51
|
+
envVar: GOOGLE_SERVICE_ACCOUNT
|
|
52
|
+
tags:
|
|
53
|
+
- files
|
|
54
|
+
- google
|
|
55
|
+
- documents
|
|
56
|
+
|
|
57
|
+
- id: custom
|
|
58
|
+
name: Custom Tools
|
|
59
|
+
type: custom
|
|
60
|
+
enabled: true
|
|
61
|
+
description: Custom HTTP and webhook tools
|
|
62
|
+
auth:
|
|
63
|
+
type: none
|
|
64
|
+
tags:
|
|
65
|
+
- custom
|
|
66
|
+
- http
|
|
67
|
+
- webhooks
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/cli/discover.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
const DEFAULT_REGISTRY_URL = 'http://localhost:3000';
|
|
6
|
+
async function httpGet(url, timeout = 10000) {
|
|
7
|
+
const controller = new AbortController();
|
|
8
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
9
|
+
try {
|
|
10
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
11
|
+
clearTimeout(timeoutId);
|
|
12
|
+
if (!response.ok) {
|
|
13
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
14
|
+
}
|
|
15
|
+
return response.json();
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
clearTimeout(timeoutId);
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
if (error.name === 'AbortError') {
|
|
21
|
+
throw new Error('Request timeout');
|
|
22
|
+
}
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function discover(query, options) {
|
|
29
|
+
const url = options.registryUrl || DEFAULT_REGISTRY_URL;
|
|
30
|
+
const spinner = ora('Discovering available tools...').start();
|
|
31
|
+
try {
|
|
32
|
+
const params = new URLSearchParams();
|
|
33
|
+
params.append('query', query);
|
|
34
|
+
if (options.limit)
|
|
35
|
+
params.append('limit', String(options.limit));
|
|
36
|
+
const result = await httpGet(`${url}/api/v1/discover?${params}`);
|
|
37
|
+
spinner.succeed();
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
spinner.fail();
|
|
42
|
+
if (error instanceof Error) {
|
|
43
|
+
if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch')) {
|
|
44
|
+
console.error(chalk.red(`\nError: Cannot connect to registry at ${url}`));
|
|
45
|
+
console.log(chalk.yellow('\nMake sure the registry is running:'));
|
|
46
|
+
console.log(chalk.cyan(' nexus start\n'));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.error(chalk.red(`\nError: ${error.message}`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function formatResults(result, json) {
|
|
56
|
+
if (json) {
|
|
57
|
+
console.log(JSON.stringify(result, null, 2));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
console.log(chalk.bold('\n🔍 Query Interpretation:'));
|
|
61
|
+
console.log(` ${result.queryInterpretation}\n`);
|
|
62
|
+
console.log(chalk.bold(`📊 Found ${result.totalMatches} matching tools`));
|
|
63
|
+
console.log(chalk.gray(` Context used: ${result.contextUsed} / ${result.contextBudget} tokens\n`));
|
|
64
|
+
if (result.tools.length === 0) {
|
|
65
|
+
console.log(chalk.yellow('No tools matched your query. Try a different search term.'));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.log(chalk.bold('\n🛠️ Available Tools:\n'));
|
|
69
|
+
for (const { tool, relevanceScore, matchReasons } of result.tools) {
|
|
70
|
+
const scoreColor = relevanceScore > 0.7 ? 'green' : relevanceScore > 0.4 ? 'yellow' : 'gray';
|
|
71
|
+
console.log(` ${chalk[scoreColor](`[${Math.round(relevanceScore * 100)}%]`)} ${chalk.cyan(tool.name)}`);
|
|
72
|
+
console.log(` ${tool.description}`);
|
|
73
|
+
console.log(` ${chalk.gray('Server:')} ${chalk.white(tool.serverName)}`);
|
|
74
|
+
if (tool.tags.length > 0) {
|
|
75
|
+
console.log(` ${chalk.gray('Tags:')} ${tool.tags.map(t => chalk.magenta(t)).join(', ')}`);
|
|
76
|
+
}
|
|
77
|
+
if (matchReasons.length > 0) {
|
|
78
|
+
console.log(` ${chalk.gray('Matched:')} ${matchReasons.join(', ')}`);
|
|
79
|
+
}
|
|
80
|
+
console.log();
|
|
81
|
+
}
|
|
82
|
+
if (result.servers.length > 0) {
|
|
83
|
+
console.log(chalk.bold('\n🖥️ Connected Servers:\n'));
|
|
84
|
+
for (const server of result.servers) {
|
|
85
|
+
const statusColor = server.health.status === 'healthy' ? 'green' : server.health.status === 'degraded' ? 'yellow' : 'red';
|
|
86
|
+
console.log(` ${chalk[statusColor]('●')} ${chalk.white(server.name)} (${server.type})`);
|
|
87
|
+
}
|
|
88
|
+
console.log();
|
|
89
|
+
}
|
|
90
|
+
if (result.suggestions.length > 0) {
|
|
91
|
+
console.log(chalk.bold('\n💡 Suggestions:'));
|
|
92
|
+
for (const suggestion of result.suggestions) {
|
|
93
|
+
console.log(` • ${suggestion}`);
|
|
94
|
+
}
|
|
95
|
+
console.log();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function interactiveMode(registryUrl) {
|
|
99
|
+
console.log(chalk.bold('\n🎯 Nexus Discovery CLI - Interactive Mode\n'));
|
|
100
|
+
console.log(chalk.gray('Type your query or "exit" to quit\n'));
|
|
101
|
+
const { query } = await inquirer.prompt([
|
|
102
|
+
{
|
|
103
|
+
type: 'input',
|
|
104
|
+
name: 'query',
|
|
105
|
+
message: 'What would you like to do?',
|
|
106
|
+
default: 'what can I do?',
|
|
107
|
+
},
|
|
108
|
+
]);
|
|
109
|
+
if (query.toLowerCase() === 'exit') {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const result = await discover(query, { registryUrl });
|
|
113
|
+
formatResults(result, false);
|
|
114
|
+
await interactiveMode(registryUrl);
|
|
115
|
+
}
|
|
116
|
+
async function main() {
|
|
117
|
+
const args = process.argv.slice(2);
|
|
118
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
119
|
+
console.log(`
|
|
120
|
+
${chalk.bold('Nexus Discovery CLI')}
|
|
121
|
+
|
|
122
|
+
${chalk.underline('Usage:')}
|
|
123
|
+
nexus-discover [query] [options]
|
|
124
|
+
|
|
125
|
+
${chalk.underline('Options:')}
|
|
126
|
+
--url <url> Registry URL (default: http://localhost:3000)
|
|
127
|
+
--limit <n> Maximum tools to return (default: 20)
|
|
128
|
+
--json Output as JSON
|
|
129
|
+
--interactive Interactive mode
|
|
130
|
+
--help, -h Show this help
|
|
131
|
+
|
|
132
|
+
${chalk.underline('Examples:')}
|
|
133
|
+
nexus-discover "what can I do?"
|
|
134
|
+
nexus-discover "github repository" --limit 10
|
|
135
|
+
nexus-discover --json
|
|
136
|
+
nexus-discover --interactive
|
|
137
|
+
`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const interactive = args.includes('--interactive');
|
|
141
|
+
const json = args.includes('--json');
|
|
142
|
+
const urlArg = args.indexOf('--url');
|
|
143
|
+
const registryUrl = urlArg !== -1 ? args[urlArg + 1] : DEFAULT_REGISTRY_URL;
|
|
144
|
+
const limitArg = args.indexOf('--limit');
|
|
145
|
+
const limit = limitArg !== -1 ? parseInt(args[limitArg + 1], 10) : 20;
|
|
146
|
+
if (interactive) {
|
|
147
|
+
await interactiveMode(registryUrl);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const query = args.filter(a => !a.startsWith('--')).join(' ') || 'what can I do?';
|
|
151
|
+
try {
|
|
152
|
+
const result = await discover(query, { registryUrl, limit, json });
|
|
153
|
+
formatResults(result, json);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
main().catch(console.error);
|
|
160
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/cli/discover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAIA,OAAO,eAAe,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { RegistryServer } from '../registry/server.js';
|
|
3
|
+
import 'dotenv/config';
|
|
4
|
+
const config = {
|
|
5
|
+
port: parseInt(process.env.PORT || '3000', 10),
|
|
6
|
+
host: process.env.HOST || 'localhost',
|
|
7
|
+
jwtSecret: process.env.JWT_SECRET || 'dev-secret-change-in-production',
|
|
8
|
+
apiKey: process.env.API_KEY,
|
|
9
|
+
maxToolsPerResponse: parseInt(process.env.MAX_TOOLS_PER_RESPONSE || '50', 10),
|
|
10
|
+
contextTokenBudget: parseInt(process.env.CONTEXT_TOKEN_BUDGET || '128000', 10),
|
|
11
|
+
enableAuth: process.env.ENABLE_AUTH === 'true',
|
|
12
|
+
};
|
|
13
|
+
const server = new RegistryServer(config);
|
|
14
|
+
process.on('SIGINT', async () => {
|
|
15
|
+
await server.stop();
|
|
16
|
+
process.exit(0);
|
|
17
|
+
});
|
|
18
|
+
process.on('SIGTERM', async () => {
|
|
19
|
+
await server.stop();
|
|
20
|
+
process.exit(0);
|
|
21
|
+
});
|
|
22
|
+
console.log(`
|
|
23
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
24
|
+
║ N E X U S ║
|
|
25
|
+
║ MCP Tool Registry & Discovery Hub ║
|
|
26
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
27
|
+
`);
|
|
28
|
+
server.start().catch((error) => {
|
|
29
|
+
console.error('Failed to start server:', error);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,eAAe,CAAC;AAEvB,MAAM,MAAM,GAAmB;IAC7B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC;IAC9C,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,WAAW;IACrC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,iCAAiC;IACtE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO;IAC3B,mBAAmB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,IAAI,EAAE,EAAE,CAAC;IAC7E,kBAAkB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,QAAQ,EAAE,EAAE,CAAC;IAC9E,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM;CAC/C,CAAC;AAEF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;AAE1C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,GAAG,CAAC;;;;;CAKX,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC7B,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { MCPServer, Tool, ConnectorConfig } from '../types/index.js';
|
|
2
|
+
export declare abstract class BaseConnector implements MCPServer {
|
|
3
|
+
abstract id: string;
|
|
4
|
+
abstract name: string;
|
|
5
|
+
abstract type: string;
|
|
6
|
+
protected config: ConnectorConfig;
|
|
7
|
+
protected connected: boolean;
|
|
8
|
+
tools: Tool[];
|
|
9
|
+
constructor(config: ConnectorConfig);
|
|
10
|
+
abstract connect(): Promise<void>;
|
|
11
|
+
abstract disconnect(): Promise<void>;
|
|
12
|
+
abstract healthCheck(): Promise<{
|
|
13
|
+
healthy: boolean;
|
|
14
|
+
latencyMs?: number;
|
|
15
|
+
}>;
|
|
16
|
+
abstract refreshTools(): Promise<Tool[]>;
|
|
17
|
+
getTools(): Tool[];
|
|
18
|
+
isConnected(): boolean;
|
|
19
|
+
protected createTool(partial: {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
inputSchema: Record<string, unknown>;
|
|
23
|
+
tags?: string[];
|
|
24
|
+
capabilities?: string[];
|
|
25
|
+
authRequirements?: {
|
|
26
|
+
required?: string[];
|
|
27
|
+
optional?: string[];
|
|
28
|
+
};
|
|
29
|
+
contextRequirements?: {
|
|
30
|
+
minTokens?: number;
|
|
31
|
+
maxTokens?: number;
|
|
32
|
+
};
|
|
33
|
+
metadata?: Record<string, unknown>;
|
|
34
|
+
}): Tool;
|
|
35
|
+
protected measureLatency<T>(fn: () => Promise<T>): Promise<{
|
|
36
|
+
result: T;
|
|
37
|
+
latencyMs: number;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export interface Connector {
|
|
41
|
+
connect(): Promise<void>;
|
|
42
|
+
disconnect(): Promise<void>;
|
|
43
|
+
healthCheck(): Promise<{
|
|
44
|
+
healthy: boolean;
|
|
45
|
+
latencyMs?: number;
|
|
46
|
+
}>;
|
|
47
|
+
getTools(): Tool[];
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/connectors/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE1E,8BAAsB,aAAc,YAAW,SAAS;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC;IAClC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAS;IACrC,KAAK,EAAE,IAAI,EAAE,CAAM;gBAEP,MAAM,EAAE,eAAe;IAInC,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,QAAQ,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAExC,QAAQ,IAAI,IAAI,EAAE;IAIlB,WAAW,IAAI,OAAO;IAItB,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE;QAC5B,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,gBAAgB,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAChE,mBAAmB,CAAC,EAAE;YAAE,SAAS,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACjE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GAAG,IAAI;cAyBQ,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAMnG;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,WAAW,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,QAAQ,IAAI,IAAI,EAAE,CAAC;CACpB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export class BaseConnector {
|
|
2
|
+
config;
|
|
3
|
+
connected = false;
|
|
4
|
+
tools = [];
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
}
|
|
8
|
+
getTools() {
|
|
9
|
+
return this.tools;
|
|
10
|
+
}
|
|
11
|
+
isConnected() {
|
|
12
|
+
return this.connected;
|
|
13
|
+
}
|
|
14
|
+
createTool(partial) {
|
|
15
|
+
const now = new Date().toISOString();
|
|
16
|
+
return {
|
|
17
|
+
id: `${this.id}:${partial.name}`,
|
|
18
|
+
serverId: this.id,
|
|
19
|
+
serverName: this.name,
|
|
20
|
+
createdAt: now,
|
|
21
|
+
updatedAt: now,
|
|
22
|
+
name: partial.name,
|
|
23
|
+
description: partial.description,
|
|
24
|
+
inputSchema: partial.inputSchema,
|
|
25
|
+
tags: partial.tags || [],
|
|
26
|
+
capabilities: partial.capabilities || [],
|
|
27
|
+
authRequirements: {
|
|
28
|
+
required: partial.authRequirements?.required || [],
|
|
29
|
+
optional: partial.authRequirements?.optional || [],
|
|
30
|
+
},
|
|
31
|
+
contextRequirements: {
|
|
32
|
+
minTokens: partial.contextRequirements?.minTokens || 0,
|
|
33
|
+
maxTokens: partial.contextRequirements?.maxTokens || 1000,
|
|
34
|
+
},
|
|
35
|
+
metadata: partial.metadata || {},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async measureLatency(fn) {
|
|
39
|
+
const start = performance.now();
|
|
40
|
+
const result = await fn();
|
|
41
|
+
const latencyMs = Math.round(performance.now() - start);
|
|
42
|
+
return { result, latencyMs };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/connectors/base.ts"],"names":[],"mappings":"AAEA,MAAM,OAAgB,aAAa;IAIvB,MAAM,CAAkB;IACxB,SAAS,GAAY,KAAK,CAAC;IACrC,KAAK,GAAW,EAAE,CAAC;IAEnB,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAOD,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAES,UAAU,CAAC,OASpB;QACC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,OAAO;YACL,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE;YAChC,QAAQ,EAAE,IAAI,CAAC,EAAE;YACjB,UAAU,EAAE,IAAI,CAAC,IAAI;YACrB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;YACxB,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE;YACxC,gBAAgB,EAAE;gBAChB,QAAQ,EAAE,OAAO,CAAC,gBAAgB,EAAE,QAAQ,IAAI,EAAE;gBAClD,QAAQ,EAAE,OAAO,CAAC,gBAAgB,EAAE,QAAQ,IAAI,EAAE;aACnD;YACD,mBAAmB,EAAE;gBACnB,SAAS,EAAE,OAAO,CAAC,mBAAmB,EAAE,SAAS,IAAI,CAAC;gBACtD,SAAS,EAAE,OAAO,CAAC,mBAAmB,EAAE,SAAS,IAAI,IAAI;aAC1D;YACD,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;SACjC,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,cAAc,CAAI,EAAoB;QACpD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;QACxD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseConnector } from './base.js';
|
|
2
|
+
import { ConnectorConfig, Tool, ToolDefinition } from '../types/index.js';
|
|
3
|
+
export declare class CustomConnector extends BaseConnector {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
type: string;
|
|
7
|
+
constructor(config: ConnectorConfig);
|
|
8
|
+
connect(): Promise<void>;
|
|
9
|
+
disconnect(): Promise<void>;
|
|
10
|
+
healthCheck(): Promise<{
|
|
11
|
+
healthy: boolean;
|
|
12
|
+
latencyMs?: number;
|
|
13
|
+
}>;
|
|
14
|
+
refreshTools(): Promise<Tool[]>;
|
|
15
|
+
registerCustomTool(definition: ToolDefinition): void;
|
|
16
|
+
unregisterCustomTool(name: string): boolean;
|
|
17
|
+
private buildTools;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=custom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../src/connectors/custom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA+F1E,qBAAa,eAAgB,SAAQ,aAAa;IAChD,EAAE,SAAY;IACd,IAAI,SAAkB;IACtB,IAAI,SAAY;gBAEJ,MAAM,EAAE,eAAe;IAK7B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,WAAW,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAIhE,YAAY,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAIrC,kBAAkB,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI;IAIpD,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS3C,OAAO,CAAC,UAAU;CAGnB"}
|