mindroot 9.2.0__py3-none-any.whl → 9.5.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 +63 -0
- mindroot/coreplugins/admin/plugin_router.py +1 -1
- 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-old.js +385 -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 +857 -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/handlers/plugin_ops.py +1 -1
- mindroot/coreplugins/index/indices/default/index.json +6 -6
- mindroot/coreplugins/jwt_auth/middleware.py +47 -1
- 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/password_reset_service.py +180 -27
- mindroot/coreplugins/user_service/router.py +84 -22
- 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 +238 -17
- 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 +49 -0
- mindroot/registry/data_access.py +1 -1
- mindroot/server.py +47 -13
- mindroot/server_missing_normal_args.py +197 -0
- mindroot/server_prev.py +173 -0
- {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/METADATA +7 -2
- {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/RECORD +147 -114
- 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 -72
- 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.2.0.dist-info → mindroot-9.5.0.dist-info}/WHEEL +0 -0
- {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/entry_points.txt +0 -0
- {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/licenses/LICENSE +0 -0
- {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { html } from '/admin/static/js/lit-core.min.js';
|
|
2
|
+
import { RegistryManagerBase } from './registry-manager-base.js';
|
|
3
|
+
|
|
4
|
+
class RegistryManager extends RegistryManagerBase {
|
|
5
|
+
async checkAuthStatus() {
|
|
6
|
+
if (this.authToken) {
|
|
7
|
+
try {
|
|
8
|
+
const response = await fetch(`${this.registryUrl}/stats`, {
|
|
9
|
+
headers: {
|
|
10
|
+
'Authorization': `Bearer ${this.authToken}`
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (response.ok) {
|
|
15
|
+
this.isLoggedIn = true;
|
|
16
|
+
} else {
|
|
17
|
+
this.logout();
|
|
18
|
+
}
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error('Error checking auth status:', error);
|
|
21
|
+
this.logout();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async loadStats() {
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(`${this.registryUrl}/stats`);
|
|
29
|
+
if (response.ok) {
|
|
30
|
+
this.stats = await response.json();
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('Error loading stats:', error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async loadLocalContent() {
|
|
38
|
+
try {
|
|
39
|
+
const pluginsResponse = await fetch('/admin/plugin-manager/get-all-plugins');
|
|
40
|
+
if (pluginsResponse.ok) {
|
|
41
|
+
const pluginsData = await pluginsResponse.json();
|
|
42
|
+
this.localPlugins = pluginsData.data || [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const agentsResponse = await fetch('/admin/agents/local');
|
|
46
|
+
if (agentsResponse.ok) {
|
|
47
|
+
this.localAgents = await agentsResponse.json();
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('Error loading local content:', error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async handleLogin() {
|
|
55
|
+
const username = this.shadowRoot.getElementById('username').value;
|
|
56
|
+
const password = this.shadowRoot.getElementById('password').value;
|
|
57
|
+
|
|
58
|
+
if (!username || !password) {
|
|
59
|
+
this.error = 'Please enter username and password';
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await this.login(username, password);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async login(username, password) {
|
|
67
|
+
this.loading = true;
|
|
68
|
+
this.error = '';
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const formData = new FormData();
|
|
72
|
+
formData.append('username', username);
|
|
73
|
+
formData.append('password', password);
|
|
74
|
+
|
|
75
|
+
const response = await fetch(`${this.registryUrl}/token`, {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
body: formData
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (response.ok) {
|
|
81
|
+
const data = await response.json();
|
|
82
|
+
this.authToken = data.access_token;
|
|
83
|
+
localStorage.setItem('registry_token', this.authToken);
|
|
84
|
+
this.isLoggedIn = true;
|
|
85
|
+
this.currentUser = { username };
|
|
86
|
+
} else {
|
|
87
|
+
const errorData = await response.json();
|
|
88
|
+
this.error = errorData.detail || 'Login failed';
|
|
89
|
+
}
|
|
90
|
+
} catch (error) {
|
|
91
|
+
this.error = 'Network error: ' + error.message;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.loading = false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
logout() {
|
|
98
|
+
this.authToken = null;
|
|
99
|
+
this.isLoggedIn = false;
|
|
100
|
+
this.currentUser = null;
|
|
101
|
+
localStorage.removeItem('registry_token');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async search(query = this.searchQuery, category = this.selectedCategory) {
|
|
105
|
+
this.loading = true;
|
|
106
|
+
this.error = '';
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const params = new URLSearchParams({
|
|
110
|
+
query: query || '',
|
|
111
|
+
limit: '20',
|
|
112
|
+
semantic: 'true'
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (category && category !== 'all') {
|
|
116
|
+
params.append('category', category);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const response = await fetch(`${this.registryUrl}/search?${params}`);
|
|
120
|
+
|
|
121
|
+
if (response.ok) {
|
|
122
|
+
const data = await response.json();
|
|
123
|
+
this.searchResults = data.results || [];
|
|
124
|
+
} else {
|
|
125
|
+
this.error = 'Search failed';
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
this.error = 'Network error: ' + error.message;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
this.loading = false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async installFromRegistry(item) {
|
|
135
|
+
this.loading = true;
|
|
136
|
+
this.error = '';
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
if (this.authToken) {
|
|
140
|
+
await fetch(`${this.registryUrl}/install/${item.id}`, {
|
|
141
|
+
method: 'POST',
|
|
142
|
+
headers: {
|
|
143
|
+
'Authorization': `Bearer ${this.authToken}`
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (item.category === 'plugin') {
|
|
149
|
+
await this.installPlugin(item);
|
|
150
|
+
} else if (item.category === 'agent') {
|
|
151
|
+
await this.installAgent(item);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
await this.loadLocalContent();
|
|
155
|
+
|
|
156
|
+
} catch (error) {
|
|
157
|
+
this.error = 'Installation failed: ' + error.message;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.loading = false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async installPlugin(item) {
|
|
164
|
+
const installData = {
|
|
165
|
+
plugin: item.title,
|
|
166
|
+
source: item.github_url ? 'github' : 'pypi',
|
|
167
|
+
source_path: item.github_url || item.pypi_module
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const response = await fetch('/admin/plugin-manager/stream-install-plugin', {
|
|
171
|
+
method: 'POST',
|
|
172
|
+
headers: {
|
|
173
|
+
'Content-Type': 'application/json'
|
|
174
|
+
},
|
|
175
|
+
body: JSON.stringify(installData)
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
throw new Error('Plugin installation failed');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async installAgent(item) {
|
|
184
|
+
const agentData = {
|
|
185
|
+
...item.data,
|
|
186
|
+
name: item.title,
|
|
187
|
+
description: item.description
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const response = await fetch('/admin/agents/local', {
|
|
191
|
+
method: 'POST',
|
|
192
|
+
headers: {
|
|
193
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
194
|
+
},
|
|
195
|
+
body: `agent=${encodeURIComponent(JSON.stringify(agentData))}`
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
throw new Error('Agent installation failed');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
_render() {
|
|
204
|
+
return html`
|
|
205
|
+
<div class="registry-manager">
|
|
206
|
+
${this.renderHeader()}
|
|
207
|
+
${this.renderTabs()}
|
|
208
|
+
${this.renderContent()}
|
|
209
|
+
</div>
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
renderHeader() {
|
|
214
|
+
if (this.isLoggedIn) {
|
|
215
|
+
return html`
|
|
216
|
+
<div class="user-info">
|
|
217
|
+
<span>Logged in as: ${this.currentUser?.username}</span>
|
|
218
|
+
<button @click=${this.logout}>Logout</button>
|
|
219
|
+
</div>
|
|
220
|
+
`;
|
|
221
|
+
} else {
|
|
222
|
+
return html`
|
|
223
|
+
<div class="section">
|
|
224
|
+
<h3>Registry Login</h3>
|
|
225
|
+
<div class="login-form">
|
|
226
|
+
<input type="text" placeholder="Username or Email" id="username">
|
|
227
|
+
<input type="password" placeholder="Password" id="password">
|
|
228
|
+
<button class="primary" @click=${this.handleLogin}>Login</button>
|
|
229
|
+
${this.error ? html`<div class="error">${this.error}</div>` : ''}
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
`;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
renderTabs() {
|
|
237
|
+
return html`
|
|
238
|
+
<div class="tabs">
|
|
239
|
+
<div class="tab ${this.activeTab === 'search' ? 'active' : ''}"
|
|
240
|
+
@click=${() => this.activeTab = 'search'}>Search</div>
|
|
241
|
+
<div class="tab ${this.activeTab === 'publish' ? 'active' : ''}"
|
|
242
|
+
@click=${() => this.activeTab = 'publish'}>Publish</div>
|
|
243
|
+
<div class="tab ${this.activeTab === 'stats' ? 'active' : ''}"
|
|
244
|
+
@click=${() => this.activeTab = 'stats'}>Stats</div>
|
|
245
|
+
</div>
|
|
246
|
+
`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
renderContent() {
|
|
250
|
+
switch (this.activeTab) {
|
|
251
|
+
case 'search':
|
|
252
|
+
return this.renderSearch();
|
|
253
|
+
case 'publish':
|
|
254
|
+
return this.renderPublish();
|
|
255
|
+
case 'stats':
|
|
256
|
+
return this.renderStats();
|
|
257
|
+
default:
|
|
258
|
+
return this.renderSearch();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
renderSearch() {
|
|
263
|
+
return html`
|
|
264
|
+
<div class="section">
|
|
265
|
+
<h3>Search Registry</h3>
|
|
266
|
+
<div class="search-form">
|
|
267
|
+
<div class="form-row">
|
|
268
|
+
<input type="text" placeholder="Search plugins and agents..."
|
|
269
|
+
.value=${this.searchQuery}
|
|
270
|
+
@input=${(e) => this.searchQuery = e.target.value}>
|
|
271
|
+
<select .value=${this.selectedCategory}
|
|
272
|
+
@change=${(e) => this.selectedCategory = e.target.value}>
|
|
273
|
+
<option value="all">All</option>
|
|
274
|
+
<option value="plugin">Plugins</option>
|
|
275
|
+
<option value="agent">Agents</option>
|
|
276
|
+
</select>
|
|
277
|
+
<button class="primary" @click=${() => this.search()}>Search</button>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
${this.loading ? html`<div class="loading">Searching...</div>` : ''}
|
|
282
|
+
${this.error ? html`<div class="error">${this.error}</div>` : ''}
|
|
283
|
+
|
|
284
|
+
<div class="search-results">
|
|
285
|
+
${this.searchResults.map(item => this.renderSearchResult(item))}
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
`;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
renderSearchResult(item) {
|
|
292
|
+
return html`
|
|
293
|
+
<div class="result-item">
|
|
294
|
+
<div class="result-header">
|
|
295
|
+
<h4 class="result-title">${item.title}</h4>
|
|
296
|
+
<span class="result-version">v${item.version}</span>
|
|
297
|
+
</div>
|
|
298
|
+
<p class="result-description">${item.description}</p>
|
|
299
|
+
<div class="result-meta">
|
|
300
|
+
<span>Category: ${item.category}</span>
|
|
301
|
+
<span>Downloads: ${item.download_count || 0}</span>
|
|
302
|
+
<span>Rating: ${item.rating || 0}/5</span>
|
|
303
|
+
</div>
|
|
304
|
+
${item.tags && item.tags.length > 0 ? html`
|
|
305
|
+
<div class="result-tags">
|
|
306
|
+
${item.tags.map(tag => html`<span class="tag">${tag}</span>`)}
|
|
307
|
+
</div>
|
|
308
|
+
` : ''}
|
|
309
|
+
<div class="result-actions">
|
|
310
|
+
<button class="success" @click=${() => this.installFromRegistry(item)}>Install</button>
|
|
311
|
+
${item.github_url ? html`<a href="${item.github_url}" target="_blank"><button>GitHub</button></a>` : ''}
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
renderPublish() {
|
|
318
|
+
if (!this.isLoggedIn) {
|
|
319
|
+
return html`
|
|
320
|
+
<div class="section">
|
|
321
|
+
<h3>Publish to Registry</h3>
|
|
322
|
+
<p>Please log in to publish plugins and agents to the registry.</p>
|
|
323
|
+
</div>
|
|
324
|
+
`;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return html`
|
|
328
|
+
<div class="section">
|
|
329
|
+
<h3>Publish to Registry</h3>
|
|
330
|
+
<p>Select a local plugin or agent to publish:</p>
|
|
331
|
+
|
|
332
|
+
<h4>Local Plugins</h4>
|
|
333
|
+
${this.localPlugins.map(plugin => html`
|
|
334
|
+
<div class="result-item">
|
|
335
|
+
<h5>${plugin.name}</h5>
|
|
336
|
+
<p>${plugin.description || 'No description'}</p>
|
|
337
|
+
<button class="primary" @click=${() => this.publishItem(plugin, 'plugin')}>Publish Plugin</button>
|
|
338
|
+
</div>
|
|
339
|
+
`)}
|
|
340
|
+
|
|
341
|
+
<h4>Local Agents</h4>
|
|
342
|
+
${this.localAgents.map(agent => html`
|
|
343
|
+
<div class="result-item">
|
|
344
|
+
<h5>${agent.name}</h5>
|
|
345
|
+
<button class="primary" @click=${() => this.publishItem(agent, 'agent')}>Publish Agent</button>
|
|
346
|
+
</div>
|
|
347
|
+
`)}
|
|
348
|
+
</div>
|
|
349
|
+
`;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
renderStats() {
|
|
353
|
+
return html`
|
|
354
|
+
<div class="section">
|
|
355
|
+
<h3>Registry Statistics</h3>
|
|
356
|
+
<div class="stats-grid">
|
|
357
|
+
<div class="stat-card">
|
|
358
|
+
<div class="stat-number">${this.stats.total_plugins || 0}</div>
|
|
359
|
+
<div class="stat-label">Plugins</div>
|
|
360
|
+
</div>
|
|
361
|
+
<div class="stat-card">
|
|
362
|
+
<div class="stat-number">${this.stats.total_agents || 0}</div>
|
|
363
|
+
<div class="stat-label">Agents</div>
|
|
364
|
+
</div>
|
|
365
|
+
<div class="stat-card">
|
|
366
|
+
<div class="stat-number">${this.stats.total_users || 0}</div>
|
|
367
|
+
<div class="stat-label">Users</div>
|
|
368
|
+
</div>
|
|
369
|
+
<div class="stat-card">
|
|
370
|
+
<div class="stat-number">${this.stats.total_installs || 0}</div>
|
|
371
|
+
<div class="stat-label">Installs</div>
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
`;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async publishItem(item, type) {
|
|
379
|
+
// Implementation for publishing items to registry
|
|
380
|
+
console.log('Publishing', type, item);
|
|
381
|
+
// This would involve creating the proper payload and sending to registry
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
customElements.define('registry-manager', RegistryManager);
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// Additional methods for publishing functionality
|
|
2
|
+
|
|
3
|
+
export function addPublishMethods(RegistryManager) {
|
|
4
|
+
// Add publish tab to tabs
|
|
5
|
+
RegistryManager.prototype.renderTabsWithPublish = function() {
|
|
6
|
+
return `
|
|
7
|
+
<div class="tabs">
|
|
8
|
+
<div class="tab ${this.activeTab === 'search' ? 'active' : ''}"
|
|
9
|
+
onclick="this.activeTab = 'search'; this.requestUpdate();">Search</div>
|
|
10
|
+
${this.isLoggedIn ? `
|
|
11
|
+
<div class="tab ${this.activeTab === 'publish' ? 'active' : ''}"
|
|
12
|
+
onclick="this.activeTab = 'publish'; this.requestUpdate();">Publish</div>
|
|
13
|
+
` : ''}
|
|
14
|
+
<div class="tab ${this.activeTab === 'stats' ? 'active' : ''}"
|
|
15
|
+
onclick="this.activeTab = 'stats'; this.requestUpdate();">Stats</div>
|
|
16
|
+
</div>
|
|
17
|
+
`;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Render publish content
|
|
21
|
+
RegistryManager.prototype.renderPublish = function() {
|
|
22
|
+
if (!this.isLoggedIn) {
|
|
23
|
+
return `
|
|
24
|
+
<div class="section">
|
|
25
|
+
<h3>Publish to Registry</h3>
|
|
26
|
+
<p>Please log in to publish content.</p>
|
|
27
|
+
</div>
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return `
|
|
32
|
+
<div class="section">
|
|
33
|
+
<h3>Publish Plugin</h3>
|
|
34
|
+
<div class="publish-form">
|
|
35
|
+
<input type="text" placeholder="Plugin Title" id="plugin-title">
|
|
36
|
+
<textarea placeholder="Description" id="plugin-description"></textarea>
|
|
37
|
+
<input type="text" placeholder="Version (e.g., 1.0.0)" id="plugin-version">
|
|
38
|
+
<input type="text" placeholder="GitHub URL (e.g., user/repo)" id="plugin-github">
|
|
39
|
+
<input type="text" placeholder="OR PyPI Module Name" id="plugin-pypi">
|
|
40
|
+
<input type="text" placeholder="Tags (comma separated)" id="plugin-tags">
|
|
41
|
+
<button class="primary" onclick="this.handlePublishPlugin()">Publish Plugin</button>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="section">
|
|
46
|
+
<h3>Publish Agent</h3>
|
|
47
|
+
<div class="publish-form">
|
|
48
|
+
<select id="agent-select">
|
|
49
|
+
<option value="">Select an agent...</option>
|
|
50
|
+
${this.localAgents.map(agent => `<option value="${agent.name}">${agent.name}</option>`).join('')}
|
|
51
|
+
</select>
|
|
52
|
+
<textarea placeholder="Description" id="agent-description"></textarea>
|
|
53
|
+
<input type="text" placeholder="Version (e.g., 1.0.0)" id="agent-version">
|
|
54
|
+
<input type="text" placeholder="Tags (comma separated)" id="agent-tags">
|
|
55
|
+
<button class="primary" onclick="this.handlePublishAgent()">Publish Agent</button>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
`;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Handle plugin publishing from GitHub
|
|
62
|
+
RegistryManager.prototype.handlePublishPluginFromGithub = async function() {
|
|
63
|
+
const repo = this.shadowRoot.getElementById('plugin-github-repo').value;
|
|
64
|
+
if (!repo || !repo.includes('/')) {
|
|
65
|
+
this.error = 'Please provide a valid GitHub repository (e.g., user/repo)';
|
|
66
|
+
this.requestUpdate();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.loading = true;
|
|
71
|
+
this.error = '';
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch('/admin/plugins/publish_from_github', {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: {
|
|
77
|
+
'Content-Type': 'application/json',
|
|
78
|
+
'Authorization': `Bearer ${this.authToken}`
|
|
79
|
+
},
|
|
80
|
+
body: JSON.stringify({ repo: repo })
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (response.ok) {
|
|
84
|
+
const result = await response.json();
|
|
85
|
+
this.error = result.message || 'Published successfully!';
|
|
86
|
+
this.shadowRoot.getElementById('plugin-github-repo').value = '';
|
|
87
|
+
setTimeout(() => { this.error = ''; this.requestUpdate(); }, 3000);
|
|
88
|
+
} else {
|
|
89
|
+
const errorData = await response.json();
|
|
90
|
+
this.error = errorData.detail || 'Publishing failed';
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
this.error = 'Network error: ' + error.message;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this.loading = false;
|
|
97
|
+
this.requestUpdate();
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Handle agent publishing
|
|
101
|
+
RegistryManager.prototype.handlePublishAgent = async function() {
|
|
102
|
+
const selectedAgent = this.shadowRoot.getElementById('agent-select').value;
|
|
103
|
+
const description = this.shadowRoot.getElementById('agent-description').value;
|
|
104
|
+
const version = this.shadowRoot.getElementById('agent-version').value;
|
|
105
|
+
const tags = this.shadowRoot.getElementById('agent-tags').value;
|
|
106
|
+
|
|
107
|
+
if (!selectedAgent || !description || !version) {
|
|
108
|
+
this.error = 'Please select an agent and fill in description and version';
|
|
109
|
+
this.requestUpdate();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const agentData = this.localAgents.find(agent => agent.name === selectedAgent);
|
|
114
|
+
if (!agentData) {
|
|
115
|
+
this.error = 'Selected agent not found';
|
|
116
|
+
this.requestUpdate();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const publishData = {
|
|
121
|
+
title: selectedAgent,
|
|
122
|
+
description: description,
|
|
123
|
+
category: 'agent',
|
|
124
|
+
content_type: 'mindroot_agent',
|
|
125
|
+
version: version,
|
|
126
|
+
data: agentData,
|
|
127
|
+
tags: tags ? tags.split(',').map(t => t.trim()) : []
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
await this.publishToRegistry(publishData);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Publish to registry
|
|
134
|
+
RegistryManager.prototype.publishToRegistry = async function(publishData) {
|
|
135
|
+
this.loading = true;
|
|
136
|
+
this.error = '';
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const response = await fetch(`${this.registryUrl}/publish`, {
|
|
140
|
+
method: 'POST',
|
|
141
|
+
headers: {
|
|
142
|
+
'Content-Type': 'application/json',
|
|
143
|
+
'Authorization': `Bearer ${this.authToken}`
|
|
144
|
+
},
|
|
145
|
+
body: JSON.stringify(publishData)
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
if (response.ok) {
|
|
149
|
+
this.error = 'Published successfully!';
|
|
150
|
+
// Clear form fields
|
|
151
|
+
setTimeout(() => {
|
|
152
|
+
this.error = '';
|
|
153
|
+
this.requestUpdate();
|
|
154
|
+
}, 3000);
|
|
155
|
+
} else {
|
|
156
|
+
const errorData = await response.json();
|
|
157
|
+
this.error = errorData.detail || 'Publishing failed';
|
|
158
|
+
}
|
|
159
|
+
} catch (error) {
|
|
160
|
+
this.error = 'Network error: ' + error.message;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
this.loading = false;
|
|
164
|
+
this.requestUpdate();
|
|
165
|
+
};
|
|
166
|
+
}
|