mindroot 9.3.0__py3-none-any.whl → 9.6.0__py3-none-any.whl
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.
- mindroot/coreplugins/admin/__init__.py +3 -1
- mindroot/coreplugins/admin/agent_router.py +250 -7
- mindroot/coreplugins/admin/asset_manager.py +164 -0
- mindroot/coreplugins/admin/command_router.py +236 -1
- mindroot/coreplugins/admin/mcp_catalog_routes.py +156 -0
- mindroot/coreplugins/admin/mcp_publish_routes.py +450 -0
- mindroot/coreplugins/admin/mcp_registry_routes.py +495 -0
- mindroot/coreplugins/admin/mcp_routes.py +216 -0
- mindroot/coreplugins/admin/mod.py +62 -0
- mindroot/coreplugins/admin/oauth_callback_router.py +84 -0
- mindroot/coreplugins/admin/persona_handler.py +15 -6
- mindroot/coreplugins/admin/persona_router.py +158 -2
- mindroot/coreplugins/admin/plugin_manager.py +105 -9
- mindroot/coreplugins/admin/plugin_router_fixed.py +23 -0
- mindroot/coreplugins/admin/plugin_router_new_not_working.py +145 -0
- mindroot/coreplugins/admin/plugin_routes.py +114 -0
- mindroot/coreplugins/admin/registry_settings_routes.py +140 -0
- mindroot/coreplugins/admin/router.py +116 -15
- mindroot/coreplugins/admin/service_models.py +1 -1
- mindroot/coreplugins/admin/settings_router.py +1 -0
- mindroot/coreplugins/admin/static/css/admin-custom.css +357 -2
- mindroot/coreplugins/admin/static/css/dark.css +1 -0
- mindroot/coreplugins/admin/static/css/default.css +4 -0
- mindroot/coreplugins/admin/static/js/about-info.js +367 -0
- mindroot/coreplugins/admin/static/js/agent-form.js +83 -3
- mindroot/coreplugins/admin/static/js/api-key-script.js +307 -0
- mindroot/coreplugins/admin/static/js/mcp-manager.js +348 -0
- mindroot/coreplugins/admin/static/js/mcp-publisher.js +780 -0
- mindroot/coreplugins/admin/static/js/persona-editor.js +34 -5
- mindroot/coreplugins/admin/static/js/plugin-toggle.js +1 -1
- mindroot/coreplugins/admin/static/js/recommended-plugin-install.js +63 -0
- mindroot/coreplugins/admin/static/js/registry-auth-section.js +132 -0
- mindroot/coreplugins/admin/static/js/registry-manager-base.js +613 -0
- mindroot/coreplugins/admin/static/js/registry-manager-publish-old-delete.js +166 -0
- mindroot/coreplugins/admin/static/js/registry-manager.js +351 -0
- mindroot/coreplugins/admin/static/js/registry-publish-section.js +377 -0
- mindroot/coreplugins/admin/static/js/registry-search-section.js +400 -0
- mindroot/coreplugins/admin/static/js/registry-search-section.js.bak +3 -0
- mindroot/coreplugins/admin/static/js/registry-settings.js +69 -0
- mindroot/coreplugins/admin/static/js/registry-shared-services.js +903 -0
- mindroot/coreplugins/admin/static/js/registry-simple-sections.js +85 -0
- mindroot/coreplugins/admin/static/js/secure-widget-manager.js +438 -0
- mindroot/coreplugins/admin/static/logo.png +0 -0
- mindroot/coreplugins/admin/templates/admin.jinja2 +275 -110
- mindroot/coreplugins/agent/Assistant/agent.json +27 -11
- mindroot/coreplugins/agent/agent.py +2 -2
- mindroot/coreplugins/agent/command_parser.py +25 -10
- mindroot/coreplugins/agent/templates/system.jinja2 +0 -12
- mindroot/coreplugins/chat/__init__.py +4 -1
- mindroot/coreplugins/chat/router.py +132 -20
- mindroot/coreplugins/chat/router_dedup_patch.py +20 -0
- mindroot/coreplugins/chat/services.py +31 -1
- mindroot/coreplugins/chat/static/css/action-fix.css +32 -0
- mindroot/coreplugins/chat/static/css/admin-custom.css +5 -3
- mindroot/coreplugins/chat/static/css/dark.css +24 -3
- mindroot/coreplugins/chat/static/css/default.css +24 -3
- mindroot/coreplugins/chat/static/css/main.css +1 -0
- mindroot/coreplugins/chat/static/js/action.js +137 -60
- mindroot/coreplugins/chat/static/js/chat-history.js +3 -0
- mindroot/coreplugins/chat/static/js/chat.js +59 -16
- mindroot/coreplugins/chat/static/js/chat.js.diff +221 -0
- mindroot/coreplugins/chat/static/js/chatform.js +2 -2
- mindroot/coreplugins/chat/static/site.webmanifest +1 -1
- mindroot/coreplugins/chat/templates/chat.jinja2 +3 -3
- mindroot/coreplugins/chat/widget_manager.py +139 -0
- mindroot/coreplugins/chat/widget_routes.py +287 -0
- mindroot/coreplugins/check_list/inject/admin.jinja2 +1 -1
- mindroot/coreplugins/email/__init__.py +2 -0
- mindroot/coreplugins/email/email_provider.py +2 -2
- mindroot/coreplugins/email/mod.py +100 -0
- mindroot/coreplugins/email/services.py +5 -3
- mindroot/coreplugins/email/smtp_handler.py +9 -3
- mindroot/coreplugins/email/test_email_service.py +75 -0
- mindroot/coreplugins/env_manager/mod.py +61 -25
- mindroot/coreplugins/home/router.py +37 -2
- mindroot/coreplugins/home/static/imgs/logo.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo.png.bak +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal2.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal_detailed.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal_python.png +0 -0
- mindroot/coreplugins/home/templates/home.jinja2 +15 -6
- mindroot/coreplugins/index/indices/default/index.json +39 -6
- mindroot/coreplugins/jwt_auth/middleware.py +47 -2
- mindroot/coreplugins/jwt_auth/mod.py +40 -17
- mindroot/coreplugins/l8n/__init__.py +6 -0
- mindroot/coreplugins/l8n/debug_loader.py +85 -0
- mindroot/coreplugins/l8n/debug_middleware.py +74 -0
- mindroot/coreplugins/l8n/l8n_constants.py +19 -0
- mindroot/coreplugins/l8n/language_detection.py +183 -0
- mindroot/coreplugins/l8n/middleware.py +151 -0
- mindroot/coreplugins/l8n/mod.py +277 -0
- mindroot/coreplugins/l8n/monkey_patch_to_delete.py +186 -0
- mindroot/coreplugins/l8n/test_enhanced.py +298 -0
- mindroot/coreplugins/l8n/test_l8n.py +95 -0
- mindroot/coreplugins/l8n/test_l8n_standalone.py +251 -0
- mindroot/coreplugins/l8n/test_middleware.py +272 -0
- mindroot/coreplugins/l8n/utils.py +232 -0
- mindroot/coreplugins/mcp_/__init__.py +14 -0
- mindroot/coreplugins/mcp_/catalog_commands.py +328 -0
- mindroot/coreplugins/mcp_/catalog_manager.py +263 -0
- mindroot/coreplugins/mcp_/dynamic_commands.py +154 -0
- mindroot/coreplugins/mcp_/mcp_manager.py +1031 -0
- mindroot/coreplugins/mcp_/mod.py +367 -0
- mindroot/coreplugins/mcp_/oauth_storage.py +144 -0
- mindroot/coreplugins/mcp_/server_installer.py +79 -0
- mindroot/coreplugins/mcp_/setup.py +26 -0
- mindroot/coreplugins/mcp_/test_dynamic_commands.py +134 -0
- mindroot/coreplugins/mcp_/testmcpclient.py +92 -0
- mindroot/coreplugins/persona/mod.py +12 -7
- mindroot/coreplugins/signup/templates/signup.jinja2 +1 -1
- mindroot/coreplugins/subscriptions/__init__.py +1 -0
- mindroot/coreplugins/subscriptions/mod.py +14 -3
- mindroot/coreplugins/subscriptions/router.py +3 -0
- mindroot/coreplugins/user_service/__init__.py +1 -2
- mindroot/coreplugins/user_service/admin_init.py +1 -0
- mindroot/coreplugins/user_service/email_service.py +72 -17
- mindroot/coreplugins/user_service/mod.py +10 -2
- mindroot/coreplugins/user_service/router.py +2 -0
- mindroot/lib/auth/api_key.py +28 -0
- mindroot/lib/cli/plugins.py +94 -0
- mindroot/lib/plugins/default_plugin_manifest.json +20 -0
- mindroot/lib/plugins/installation.py +5 -5
- mindroot/lib/plugins/l8n_static_handler.py +225 -0
- mindroot/lib/plugins/loader.py +33 -3
- mindroot/lib/plugins/loader_with_l8n.py +281 -0
- mindroot/lib/plugins/manifest.py +236 -24
- mindroot/lib/providers/commands.py +3 -1
- mindroot/lib/route_decorators.py +5 -5
- mindroot/lib/templates.py +183 -11
- mindroot/lib/utils/merge_arrays.py +1 -1
- mindroot/migrate.py +39 -20
- mindroot/registry/data_access.py +1 -1
- mindroot/server.py +42 -13
- mindroot/server_missing_normal_args.py +197 -0
- mindroot/server_prev.py +173 -0
- {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/METADATA +7 -2
- {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/RECORD +143 -113
- mindroot/coreplugins/admin/plugin_manager_backup.py +0 -615
- mindroot/coreplugins/admin/static/favicon/about.txt +0 -6
- mindroot/coreplugins/admin/static/favicon/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/admin/static/favicon/apple-touch-icon.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon-16x16.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon-32x32.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon.ico +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/about.txt +0 -6
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon.ico +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/site.webmanifest +0 -1
- mindroot/coreplugins/admin/static/favicon/logo.png +0 -0
- mindroot/coreplugins/admin/static/favicon/site.webmanifest +0 -1
- mindroot/coreplugins/admin/static/js/backup/agent-editor.js +0 -186
- mindroot/coreplugins/admin/static/js/backup/agent-form.js +0 -1133
- mindroot/coreplugins/admin/static/js/backup/agent-list.js +0 -94
- mindroot/coreplugins/chat/static/favicon/about.txt +0 -6
- mindroot/coreplugins/chat/static/favicon/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/chat/static/favicon/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/chat/static/favicon/apple-touch-icon.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon-16x16.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon-32x32.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon.ico +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/about.txt +0 -6
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon.ico +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/site.webmanifest +0 -1
- mindroot/coreplugins/chat/static/favicon/logo.png +0 -0
- mindroot/coreplugins/chat/static/favicon/site.webmanifest +0 -1
- mindroot/coreplugins/index/default.json +0 -76
- mindroot/coreplugins/user_service/file_trigger_service.py +0 -12
- mindroot/coreplugins/user_service/hooks.py +0 -23
- /mindroot/coreplugins/{admin/static/favicon/android-chrome-192x192.png → home/static/imgs/backuplogo.png} +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/WHEEL +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/entry_points.txt +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/licenses/LICENSE +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry Search Section
|
|
3
|
+
*
|
|
4
|
+
* Handles search UI, category filtering, and results display
|
|
5
|
+
* for the registry manager.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { html } from '/admin/static/js/lit-core.min.js';
|
|
9
|
+
|
|
10
|
+
class RegistrySearchSection {
|
|
11
|
+
constructor(sharedState, mainComponent) {
|
|
12
|
+
this.state = sharedState;
|
|
13
|
+
this.main = mainComponent;
|
|
14
|
+
this.services = null; // Will be set by main component
|
|
15
|
+
this.searchTimeout = null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setServices(services) {
|
|
19
|
+
this.services = services;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// === Event Handlers ===
|
|
23
|
+
|
|
24
|
+
handleSearchInput(e) {
|
|
25
|
+
this.main.searchQuery = e.target.value;
|
|
26
|
+
|
|
27
|
+
// Clear existing timeout
|
|
28
|
+
if (this.searchTimeout) {
|
|
29
|
+
clearTimeout(this.searchTimeout);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Set new timeout for auto-search after 500ms of no typing
|
|
33
|
+
this.searchTimeout = setTimeout(() => {
|
|
34
|
+
this.services.search();
|
|
35
|
+
this.main.requestUpdate();
|
|
36
|
+
}, 500);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
handleCategoryChange(category) {
|
|
40
|
+
this.main.selectedCategory = category;
|
|
41
|
+
this.services.search();
|
|
42
|
+
this.main.requestUpdate();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async loadTopContent() {
|
|
46
|
+
await this.services.loadTopContent();
|
|
47
|
+
this.main.requestUpdate();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async installFromRegistry(item) {
|
|
51
|
+
await this.services.installFromRegistry(item);
|
|
52
|
+
this.main.requestUpdate();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// === Helper Methods ===
|
|
56
|
+
|
|
57
|
+
getInstalledMcpServer(item) {
|
|
58
|
+
if (!this.main.localMcpServers || this.main.localMcpServers.length === 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
// Use a fuzzy match: check if the item's title contains the server's name.
|
|
62
|
+
// This handles cases where title is "Calculator Server" and name is "calculator".
|
|
63
|
+
const normalizedTitle = item.title.toLowerCase();
|
|
64
|
+
return this.main.localMcpServers.find(s =>
|
|
65
|
+
normalizedTitle.includes(s.name.toLowerCase())
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// === Render Methods ===
|
|
70
|
+
|
|
71
|
+
renderSearch() {
|
|
72
|
+
return html`
|
|
73
|
+
<div class="section">
|
|
74
|
+
<h3>Registry Browser</h3>
|
|
75
|
+
${this.renderSearchForm()}
|
|
76
|
+
${this.renderSearchStatus()}
|
|
77
|
+
${this.renderSearchResults()}
|
|
78
|
+
</div>
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
renderSearchForm() {
|
|
83
|
+
return html`
|
|
84
|
+
<div class="search-form">
|
|
85
|
+
<div class="form-row">
|
|
86
|
+
<input type="text" placeholder="Search plugins and agents..."
|
|
87
|
+
.value=${this.main.searchQuery}
|
|
88
|
+
@input=${(e) => this.handleSearchInput(e)}>
|
|
89
|
+
</div>
|
|
90
|
+
${this.renderCategoryTabs()}
|
|
91
|
+
</div>
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
renderCategoryTabs() {
|
|
96
|
+
return html`
|
|
97
|
+
<div class="category-tabs">
|
|
98
|
+
<button class="category-tab ${this.main.selectedCategory === 'all' ? 'active' : ''}"
|
|
99
|
+
@click=${() => this.handleCategoryChange('all')}>
|
|
100
|
+
<span class="material-icons">apps</span>
|
|
101
|
+
All
|
|
102
|
+
</button>
|
|
103
|
+
<button class="category-tab ${this.main.selectedCategory === 'plugin' ? 'active' : ''}"
|
|
104
|
+
@click=${() => this.handleCategoryChange('plugin')}>
|
|
105
|
+
<span class="material-icons">extension</span>
|
|
106
|
+
Plugins
|
|
107
|
+
</button>
|
|
108
|
+
<button class="category-tab ${this.main.selectedCategory === 'agent' ? 'active' : ''}"
|
|
109
|
+
@click=${() => this.handleCategoryChange('agent')}>
|
|
110
|
+
<span class="material-icons">smart_toy</span>
|
|
111
|
+
Agents
|
|
112
|
+
</button>
|
|
113
|
+
<button class="category-tab ${this.main.selectedCategory === 'mcp_server' ? 'active' : ''}"
|
|
114
|
+
@click=${() => this.handleCategoryChange('mcp_server')}>
|
|
115
|
+
<span class="material-icons">dns</span>
|
|
116
|
+
MCP Servers
|
|
117
|
+
</button>
|
|
118
|
+
</div>
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
renderSearchStatus() {
|
|
123
|
+
if (this.state.loading) {
|
|
124
|
+
return html`<div class="loading">Searching...</div>`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (this.main.error) {
|
|
128
|
+
return html`<div class="error">${this.main.error}</div>`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return '';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
renderSearchResults() {
|
|
135
|
+
return html`
|
|
136
|
+
<div class="search-results">
|
|
137
|
+
${this.main.searchResults.length === 0 && !this.state.loading ? html`
|
|
138
|
+
<div class="no-results">
|
|
139
|
+
<p>No items found. Try adjusting your search terms or check your connection to the registry.</p>
|
|
140
|
+
<button @click=${() => this.loadTopContent()}>Load Popular Items</button>
|
|
141
|
+
</div>
|
|
142
|
+
` : ''}
|
|
143
|
+
${this.main.searchResults.map(item => this.renderSearchResult(item))}
|
|
144
|
+
</div>
|
|
145
|
+
`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
renderSearchResult(item) {
|
|
149
|
+
const installedServer = item.category === 'mcp_server' ? this.getInstalledMcpServer(item) : null;
|
|
150
|
+
const isInstalled = !!installedServer;
|
|
151
|
+
|
|
152
|
+
console.log('[SearchSection] Rendering item:', JSON.stringify(item, null, 2));
|
|
153
|
+
|
|
154
|
+
return html`
|
|
155
|
+
<div class="result-item">
|
|
156
|
+
${this.renderResultAvatar(item)}
|
|
157
|
+
<div class="result-content">
|
|
158
|
+
${this.renderSemanticBadge(item)}
|
|
159
|
+
${this.renderResultHeader(item, item.data?.auth_type === 'oauth2')}
|
|
160
|
+
<p class="result-description">${item.description}</p>
|
|
161
|
+
${this.renderResultMeta(item)}
|
|
162
|
+
${this.renderResultTags(item)}
|
|
163
|
+
${this.renderRemote(item)}
|
|
164
|
+
${this.renderCommandArgs(item)}
|
|
165
|
+
${this.renderMcpSecretsForm(item, isInstalled, installedServer)}
|
|
166
|
+
${this.renderResultActions(item, installedServer)}
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
`;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
renderCommandArgs(item) {
|
|
173
|
+
if (item?.data?.command) {
|
|
174
|
+
const argsString = item?.data?.args?.join(' ') || '';
|
|
175
|
+
const commandLine = `${item.data.command} ${argsString}`.trim();
|
|
176
|
+
if (commandLine.length === 0) return '';
|
|
177
|
+
return html`
|
|
178
|
+
<div class="command-args">
|
|
179
|
+
<strong>Command:</strong>
|
|
180
|
+
<pre><code class="command-line">${commandLine}</code></pre>
|
|
181
|
+
</div>
|
|
182
|
+
`;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
renderRemote(item) {
|
|
187
|
+
if (item?.data?.url) {
|
|
188
|
+
return html`
|
|
189
|
+
<div class="key-details">${item.data.url}</div>
|
|
190
|
+
`
|
|
191
|
+
} else return '';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
renderResultAvatar(item) {
|
|
195
|
+
if (item.category !== 'agent') return '';
|
|
196
|
+
|
|
197
|
+
const hasAssets = item.data?.persona_data?.persona_assets;
|
|
198
|
+
const hasHashes = item.data?.persona_data?.asset_hashes;
|
|
199
|
+
|
|
200
|
+
if (hasAssets && (hasAssets.faceref || hasAssets.avatar)) {
|
|
201
|
+
const asset = hasAssets.faceref || hasAssets.avatar;
|
|
202
|
+
return html`
|
|
203
|
+
<div class="result-avatar">
|
|
204
|
+
<img src="data:${asset.type};base64,${asset.data}"
|
|
205
|
+
alt="${item.title} avatar"
|
|
206
|
+
class="agent-avatar-large"
|
|
207
|
+
onerror="this.style.display='none'">
|
|
208
|
+
</div>
|
|
209
|
+
`;
|
|
210
|
+
} else if (hasHashes && (hasHashes.faceref || hasHashes.avatar)) {
|
|
211
|
+
const hash = hasHashes.faceref || hasHashes.avatar;
|
|
212
|
+
return html`
|
|
213
|
+
<div class="result-avatar">
|
|
214
|
+
<img src="${this.state.registryUrl}/assets/${hash}"
|
|
215
|
+
alt="${item.title} avatar"
|
|
216
|
+
class="agent-avatar-large"
|
|
217
|
+
onerror="this.style.display='none'">
|
|
218
|
+
</div>
|
|
219
|
+
`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return '';
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
renderSemanticBadge(item) {
|
|
226
|
+
if (!item.is_semantic) return '';
|
|
227
|
+
|
|
228
|
+
return html`
|
|
229
|
+
<div class="semantic-badge">
|
|
230
|
+
<span class="material-icons">psychology</span>
|
|
231
|
+
Semantic Match ${item.distance_score ? `(${(1 - item.distance_score).toFixed(2)})` : ''}
|
|
232
|
+
</div>
|
|
233
|
+
`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
renderResultHeader(item, requiresOAuth) {
|
|
237
|
+
const hasAvatar = item.category === 'agent' &&
|
|
238
|
+
(item.data?.persona_data?.persona_assets?.faceref ||
|
|
239
|
+
item.data?.persona_data?.persona_assets?.avatar ||
|
|
240
|
+
item.data?.persona_data?.asset_hashes?.faceref ||
|
|
241
|
+
item.data?.persona_data?.asset_hashes?.avatar);
|
|
242
|
+
|
|
243
|
+
return html`
|
|
244
|
+
<div class="result-header">
|
|
245
|
+
${hasAvatar ? html`
|
|
246
|
+
<div class="agent-name-with-face">${item.title}</div>
|
|
247
|
+
` : html`
|
|
248
|
+
<h4 class="result-title">${item.title}</h4>
|
|
249
|
+
`}
|
|
250
|
+
<span class="result-version">v${item.version}</span>
|
|
251
|
+
${requiresOAuth ? html`
|
|
252
|
+
<span class="oauth-badge" title="Requires OAuth 2.0 authentication">
|
|
253
|
+
<span class="material-icons">security</span>
|
|
254
|
+
OAuth 2.0
|
|
255
|
+
</span>
|
|
256
|
+
` : ''}
|
|
257
|
+
</div>
|
|
258
|
+
`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
renderResultMeta(item) {
|
|
262
|
+
return html`
|
|
263
|
+
<div class="result-meta">
|
|
264
|
+
<span>Category: ${item.category}</span>
|
|
265
|
+
<span>Downloads: ${item.download_count || 0}</span>
|
|
266
|
+
<span>Rating: ${item.rating || 0}/5</span>
|
|
267
|
+
</div>
|
|
268
|
+
`;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
renderResultTags(item) {
|
|
272
|
+
if (!item.tags || item.tags.length === 0) return '';
|
|
273
|
+
|
|
274
|
+
return html`
|
|
275
|
+
<div class="result-tags">
|
|
276
|
+
${item.tags.map(tag => html`<span class="tag">${tag}</span>`)}
|
|
277
|
+
</div>
|
|
278
|
+
`;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
renderResultActions(item, installedServer) {
|
|
282
|
+
const isMcp = item.category === 'mcp_server';
|
|
283
|
+
const isInstalled = !!installedServer;
|
|
284
|
+
|
|
285
|
+
return html`
|
|
286
|
+
<div class="result-actions">
|
|
287
|
+
${isMcp ?
|
|
288
|
+
(isInstalled ?
|
|
289
|
+
this.renderInstalledMcpActions(installedServer) :
|
|
290
|
+
this.renderUninstalledMcpActions(item)
|
|
291
|
+
) :
|
|
292
|
+
(this.state.localPlugins.some(p => p.name === item.title) ?
|
|
293
|
+
html`<div class="installed-badge"><span class="material-icons">check_circle</span> Installed</div>` :
|
|
294
|
+
html`<button class="success" @click=${() => this.installFromRegistry(item)} ?disabled=${this.state.loading}>Install</button>`
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
${item.github_url ? html`
|
|
298
|
+
<a href="${item.github_url}" target="_blank">
|
|
299
|
+
<button>GitHub</button>
|
|
300
|
+
</a>
|
|
301
|
+
` : ''}
|
|
302
|
+
</div>
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
renderMcpSecretsForm(item, isInstalled, installedServer) {
|
|
307
|
+
try {
|
|
308
|
+
const isUninstalledLocal = !isInstalled && item.category === 'mcp_server' && item.data?.server_type === 'local';
|
|
309
|
+
const isInstalledLocal = isInstalled && installedServer && installedServer.status !== 'connected' && installedServer.server_type === 'local';
|
|
310
|
+
|
|
311
|
+
if (!isInstalled) { //!isUninstalledLocal && !isInstalledLocal) {
|
|
312
|
+
|
|
313
|
+
console.log('No env vars form because: ',{isUninstalledLocal, isInstalledLocal, item})
|
|
314
|
+
return '';
|
|
315
|
+
}
|
|
316
|
+
console.log("SearchSection] Rendering secrets form for item:", item.title)
|
|
317
|
+
|
|
318
|
+
//const configSource = isInstalledLocal ? installedServer : item.data;
|
|
319
|
+
const configSource = item.data;
|
|
320
|
+
|
|
321
|
+
const configString = JSON.stringify(configSource);
|
|
322
|
+
const placeholderRegex = /<([A-Z0-9_]+)>/g;
|
|
323
|
+
const placeholders = new Set();
|
|
324
|
+
|
|
325
|
+
if (configSource.env) {
|
|
326
|
+
Object.keys(configSource.env).forEach(key => placeholders.add(key));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
let match;
|
|
330
|
+
while ((match = placeholderRegex.exec(configString)) !== null) {
|
|
331
|
+
placeholders.add(match[1]);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const requiredPlaceholders = Array.from(placeholders);
|
|
335
|
+
if (requiredPlaceholders.length === 0) return '';
|
|
336
|
+
|
|
337
|
+
const serverName = isInstalledLocal ? installedServer.name : item.title;
|
|
338
|
+
console.log(`[SearchSection] Rendering secrets form for '${serverName}' with placeholders:`, requiredPlaceholders);
|
|
339
|
+
return html`
|
|
340
|
+
<div class="mcp-secrets-form section" style="margin-top: 1rem; background: rgba(0,0,0,0.2);">
|
|
341
|
+
<h5 class="secrets-title">Required Environment Variables</h5>
|
|
342
|
+
<p class="help-text">Provide values to be used on ${isInstalledLocal ? 'connect' : 'install'}. These are not published.</p>
|
|
343
|
+
${requiredPlaceholders.map(p => this.renderSecretInput(item, p, serverName))}
|
|
344
|
+
</div>
|
|
345
|
+
`;
|
|
346
|
+
} catch (error) {
|
|
347
|
+
console.error('[SearchSection] Error rendering MCP secrets form:', error);
|
|
348
|
+
return html``
|
|
349
|
+
//return html`<div class="error">Error loading secrets form. Please check the console.</div>`;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
renderSecretInput(item, placeholder, serverName) {
|
|
354
|
+
const key = serverName || item.id;
|
|
355
|
+
const secretsForItem = this.main.mcpInstallSecrets[key] || {};
|
|
356
|
+
return html`
|
|
357
|
+
<div class="form-group secret-input-group">
|
|
358
|
+
<label for="secret-install-${item.id}-${placeholder}">${placeholder}</label>
|
|
359
|
+
<input type="password"
|
|
360
|
+
id="secret-install-${item.id}-${placeholder}"
|
|
361
|
+
.value=${secretsForItem[placeholder] || ''}
|
|
362
|
+
@input=${e => this.main.handleMcpInstallSecretChange(key, placeholder, e.target.value)} autocomplete="off">
|
|
363
|
+
</div>
|
|
364
|
+
`;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
renderInstalledMcpActions(server) {
|
|
368
|
+
return html`
|
|
369
|
+
<div class="installed-badge">
|
|
370
|
+
<span class="material-icons">check_circle</span>
|
|
371
|
+
${server.status === 'connected' ? 'Connected' : 'Installed'}
|
|
372
|
+
</div>
|
|
373
|
+
${server.status === 'connected' ? html`
|
|
374
|
+
<button class="danger" @click=${() => this.main.toggleMcpServerConnection(server.name, false)} ?disabled=${this.state.loading}>
|
|
375
|
+
Disconnect
|
|
376
|
+
</button>
|
|
377
|
+
` : html`
|
|
378
|
+
<button class="success" @click=${() => this.main.toggleMcpServerConnection(server.name, true)} ?disabled=${this.state.loading}>
|
|
379
|
+
Connect
|
|
380
|
+
</button>
|
|
381
|
+
`}
|
|
382
|
+
<button class="danger" @click=${() => this.main.removeMcpServer(server.name)} ?disabled=${this.state.loading}>
|
|
383
|
+
Remove
|
|
384
|
+
</button>
|
|
385
|
+
`;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
renderUninstalledMcpActions(item) {
|
|
389
|
+
const requiresOAuth = item.data && item.data.auth_type === 'oauth2';
|
|
390
|
+
return html`
|
|
391
|
+
<button class="success"
|
|
392
|
+
@click=${() => this.installFromRegistry(item)}
|
|
393
|
+
?disabled=${this.state.loading}>
|
|
394
|
+
${requiresOAuth ? 'Connect' : 'Install'}
|
|
395
|
+
</button>
|
|
396
|
+
`;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export { RegistrySearchSection };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Registry Settings functionality
|
|
2
|
+
export class RegistrySettings {
|
|
3
|
+
constructor(component) {
|
|
4
|
+
this.component = component;
|
|
5
|
+
this.loadRegistryUrl();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
loadRegistryUrl() {
|
|
9
|
+
// Load from localStorage, environment variable, or default
|
|
10
|
+
this.component.registryUrl = localStorage.getItem('registry_url') ||
|
|
11
|
+
window.MR_REGISTRY_URL ||
|
|
12
|
+
'https://registry.mindroot.io';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
updateRegistryUrl(newUrl) {
|
|
16
|
+
this.component.registryUrl = newUrl;
|
|
17
|
+
localStorage.setItem('registry_url', newUrl);
|
|
18
|
+
// Clear auth token when URL changes
|
|
19
|
+
this.component.logout();
|
|
20
|
+
// Reload stats with new URL
|
|
21
|
+
this.component.loadStats();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
renderSettings() {
|
|
25
|
+
return `
|
|
26
|
+
<details class="settings-section">
|
|
27
|
+
<summary>
|
|
28
|
+
<span class="material-icons">settings</span>
|
|
29
|
+
<span>Settings</span>
|
|
30
|
+
</summary>
|
|
31
|
+
<div class="section">
|
|
32
|
+
<h4>Registry Configuration</h4>
|
|
33
|
+
<div class="form-row">
|
|
34
|
+
<label for="registry-url">Registry URL:</label>
|
|
35
|
+
<input type="url"
|
|
36
|
+
id="registry-url"
|
|
37
|
+
value="${this.component.registryUrl}"
|
|
38
|
+
placeholder="https://registry.mindroot.io">
|
|
39
|
+
<button onclick="registrySettings.handleUrlChange()">Update URL</button>
|
|
40
|
+
<button onclick="registrySettings.testConnection()">Test Connection</button>
|
|
41
|
+
</div>
|
|
42
|
+
<p class="help-text">
|
|
43
|
+
Default: https://registry.mindroot.io or MR_REGISTRY_URL environment variable
|
|
44
|
+
</p>
|
|
45
|
+
</div>
|
|
46
|
+
</details>
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
handleUrlChange() {
|
|
51
|
+
const input = document.getElementById('registry-url');
|
|
52
|
+
if (input && input.value) {
|
|
53
|
+
this.updateRegistryUrl(input.value);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async testConnection() {
|
|
58
|
+
try {
|
|
59
|
+
const response = await fetch(`${this.component.registryUrl}/alive`);
|
|
60
|
+
if (response.ok) {
|
|
61
|
+
alert('Connection successful!');
|
|
62
|
+
} else {
|
|
63
|
+
alert('Connection failed: Server responded with status ' + response.status);
|
|
64
|
+
}
|
|
65
|
+
} catch (error) {
|
|
66
|
+
alert('Connection failed: ' + error.message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|