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.
Files changed (183) hide show
  1. mindroot/coreplugins/admin/__init__.py +3 -1
  2. mindroot/coreplugins/admin/agent_router.py +250 -7
  3. mindroot/coreplugins/admin/asset_manager.py +164 -0
  4. mindroot/coreplugins/admin/command_router.py +236 -1
  5. mindroot/coreplugins/admin/mcp_catalog_routes.py +156 -0
  6. mindroot/coreplugins/admin/mcp_publish_routes.py +450 -0
  7. mindroot/coreplugins/admin/mcp_registry_routes.py +495 -0
  8. mindroot/coreplugins/admin/mcp_routes.py +216 -0
  9. mindroot/coreplugins/admin/mod.py +62 -0
  10. mindroot/coreplugins/admin/oauth_callback_router.py +84 -0
  11. mindroot/coreplugins/admin/persona_handler.py +15 -6
  12. mindroot/coreplugins/admin/persona_router.py +158 -2
  13. mindroot/coreplugins/admin/plugin_manager.py +105 -9
  14. mindroot/coreplugins/admin/plugin_router_fixed.py +23 -0
  15. mindroot/coreplugins/admin/plugin_router_new_not_working.py +145 -0
  16. mindroot/coreplugins/admin/plugin_routes.py +114 -0
  17. mindroot/coreplugins/admin/registry_settings_routes.py +140 -0
  18. mindroot/coreplugins/admin/router.py +116 -15
  19. mindroot/coreplugins/admin/service_models.py +1 -1
  20. mindroot/coreplugins/admin/settings_router.py +1 -0
  21. mindroot/coreplugins/admin/static/css/admin-custom.css +357 -2
  22. mindroot/coreplugins/admin/static/css/dark.css +1 -0
  23. mindroot/coreplugins/admin/static/css/default.css +4 -0
  24. mindroot/coreplugins/admin/static/js/about-info.js +367 -0
  25. mindroot/coreplugins/admin/static/js/agent-form.js +83 -3
  26. mindroot/coreplugins/admin/static/js/api-key-script.js +307 -0
  27. mindroot/coreplugins/admin/static/js/mcp-manager.js +348 -0
  28. mindroot/coreplugins/admin/static/js/mcp-publisher.js +780 -0
  29. mindroot/coreplugins/admin/static/js/persona-editor.js +34 -5
  30. mindroot/coreplugins/admin/static/js/plugin-toggle.js +1 -1
  31. mindroot/coreplugins/admin/static/js/recommended-plugin-install.js +63 -0
  32. mindroot/coreplugins/admin/static/js/registry-auth-section.js +132 -0
  33. mindroot/coreplugins/admin/static/js/registry-manager-base.js +613 -0
  34. mindroot/coreplugins/admin/static/js/registry-manager-publish-old-delete.js +166 -0
  35. mindroot/coreplugins/admin/static/js/registry-manager.js +351 -0
  36. mindroot/coreplugins/admin/static/js/registry-publish-section.js +377 -0
  37. mindroot/coreplugins/admin/static/js/registry-search-section.js +400 -0
  38. mindroot/coreplugins/admin/static/js/registry-search-section.js.bak +3 -0
  39. mindroot/coreplugins/admin/static/js/registry-settings.js +69 -0
  40. mindroot/coreplugins/admin/static/js/registry-shared-services.js +903 -0
  41. mindroot/coreplugins/admin/static/js/registry-simple-sections.js +85 -0
  42. mindroot/coreplugins/admin/static/js/secure-widget-manager.js +438 -0
  43. mindroot/coreplugins/admin/static/logo.png +0 -0
  44. mindroot/coreplugins/admin/templates/admin.jinja2 +275 -110
  45. mindroot/coreplugins/agent/Assistant/agent.json +27 -11
  46. mindroot/coreplugins/agent/agent.py +2 -2
  47. mindroot/coreplugins/agent/command_parser.py +25 -10
  48. mindroot/coreplugins/agent/templates/system.jinja2 +0 -12
  49. mindroot/coreplugins/chat/__init__.py +4 -1
  50. mindroot/coreplugins/chat/router.py +132 -20
  51. mindroot/coreplugins/chat/router_dedup_patch.py +20 -0
  52. mindroot/coreplugins/chat/services.py +31 -1
  53. mindroot/coreplugins/chat/static/css/action-fix.css +32 -0
  54. mindroot/coreplugins/chat/static/css/admin-custom.css +5 -3
  55. mindroot/coreplugins/chat/static/css/dark.css +24 -3
  56. mindroot/coreplugins/chat/static/css/default.css +24 -3
  57. mindroot/coreplugins/chat/static/css/main.css +1 -0
  58. mindroot/coreplugins/chat/static/js/action.js +137 -60
  59. mindroot/coreplugins/chat/static/js/chat-history.js +3 -0
  60. mindroot/coreplugins/chat/static/js/chat.js +59 -16
  61. mindroot/coreplugins/chat/static/js/chat.js.diff +221 -0
  62. mindroot/coreplugins/chat/static/js/chatform.js +2 -2
  63. mindroot/coreplugins/chat/static/site.webmanifest +1 -1
  64. mindroot/coreplugins/chat/templates/chat.jinja2 +3 -3
  65. mindroot/coreplugins/chat/widget_manager.py +139 -0
  66. mindroot/coreplugins/chat/widget_routes.py +287 -0
  67. mindroot/coreplugins/check_list/inject/admin.jinja2 +1 -1
  68. mindroot/coreplugins/email/__init__.py +2 -0
  69. mindroot/coreplugins/email/email_provider.py +2 -2
  70. mindroot/coreplugins/email/mod.py +100 -0
  71. mindroot/coreplugins/email/services.py +5 -3
  72. mindroot/coreplugins/email/smtp_handler.py +9 -3
  73. mindroot/coreplugins/email/test_email_service.py +75 -0
  74. mindroot/coreplugins/env_manager/mod.py +61 -25
  75. mindroot/coreplugins/home/router.py +37 -2
  76. mindroot/coreplugins/home/static/imgs/logo.png +0 -0
  77. mindroot/coreplugins/home/static/imgs/logo.png.bak +0 -0
  78. mindroot/coreplugins/home/static/imgs/logo_teal.png +0 -0
  79. mindroot/coreplugins/home/static/imgs/logo_teal2.png +0 -0
  80. mindroot/coreplugins/home/static/imgs/logo_teal_detailed.png +0 -0
  81. mindroot/coreplugins/home/static/imgs/logo_teal_python.png +0 -0
  82. mindroot/coreplugins/home/templates/home.jinja2 +15 -6
  83. mindroot/coreplugins/index/indices/default/index.json +39 -6
  84. mindroot/coreplugins/jwt_auth/middleware.py +47 -2
  85. mindroot/coreplugins/jwt_auth/mod.py +40 -17
  86. mindroot/coreplugins/l8n/__init__.py +6 -0
  87. mindroot/coreplugins/l8n/debug_loader.py +85 -0
  88. mindroot/coreplugins/l8n/debug_middleware.py +74 -0
  89. mindroot/coreplugins/l8n/l8n_constants.py +19 -0
  90. mindroot/coreplugins/l8n/language_detection.py +183 -0
  91. mindroot/coreplugins/l8n/middleware.py +151 -0
  92. mindroot/coreplugins/l8n/mod.py +277 -0
  93. mindroot/coreplugins/l8n/monkey_patch_to_delete.py +186 -0
  94. mindroot/coreplugins/l8n/test_enhanced.py +298 -0
  95. mindroot/coreplugins/l8n/test_l8n.py +95 -0
  96. mindroot/coreplugins/l8n/test_l8n_standalone.py +251 -0
  97. mindroot/coreplugins/l8n/test_middleware.py +272 -0
  98. mindroot/coreplugins/l8n/utils.py +232 -0
  99. mindroot/coreplugins/mcp_/__init__.py +14 -0
  100. mindroot/coreplugins/mcp_/catalog_commands.py +328 -0
  101. mindroot/coreplugins/mcp_/catalog_manager.py +263 -0
  102. mindroot/coreplugins/mcp_/dynamic_commands.py +154 -0
  103. mindroot/coreplugins/mcp_/mcp_manager.py +1031 -0
  104. mindroot/coreplugins/mcp_/mod.py +367 -0
  105. mindroot/coreplugins/mcp_/oauth_storage.py +144 -0
  106. mindroot/coreplugins/mcp_/server_installer.py +79 -0
  107. mindroot/coreplugins/mcp_/setup.py +26 -0
  108. mindroot/coreplugins/mcp_/test_dynamic_commands.py +134 -0
  109. mindroot/coreplugins/mcp_/testmcpclient.py +92 -0
  110. mindroot/coreplugins/persona/mod.py +12 -7
  111. mindroot/coreplugins/signup/templates/signup.jinja2 +1 -1
  112. mindroot/coreplugins/subscriptions/__init__.py +1 -0
  113. mindroot/coreplugins/subscriptions/mod.py +14 -3
  114. mindroot/coreplugins/subscriptions/router.py +3 -0
  115. mindroot/coreplugins/user_service/__init__.py +1 -2
  116. mindroot/coreplugins/user_service/admin_init.py +1 -0
  117. mindroot/coreplugins/user_service/email_service.py +72 -17
  118. mindroot/coreplugins/user_service/mod.py +10 -2
  119. mindroot/coreplugins/user_service/router.py +2 -0
  120. mindroot/lib/auth/api_key.py +28 -0
  121. mindroot/lib/cli/plugins.py +94 -0
  122. mindroot/lib/plugins/default_plugin_manifest.json +20 -0
  123. mindroot/lib/plugins/installation.py +5 -5
  124. mindroot/lib/plugins/l8n_static_handler.py +225 -0
  125. mindroot/lib/plugins/loader.py +33 -3
  126. mindroot/lib/plugins/loader_with_l8n.py +281 -0
  127. mindroot/lib/plugins/manifest.py +236 -24
  128. mindroot/lib/providers/commands.py +3 -1
  129. mindroot/lib/route_decorators.py +5 -5
  130. mindroot/lib/templates.py +183 -11
  131. mindroot/lib/utils/merge_arrays.py +1 -1
  132. mindroot/migrate.py +39 -20
  133. mindroot/registry/data_access.py +1 -1
  134. mindroot/server.py +42 -13
  135. mindroot/server_missing_normal_args.py +197 -0
  136. mindroot/server_prev.py +173 -0
  137. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/METADATA +7 -2
  138. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/RECORD +143 -113
  139. mindroot/coreplugins/admin/plugin_manager_backup.py +0 -615
  140. mindroot/coreplugins/admin/static/favicon/about.txt +0 -6
  141. mindroot/coreplugins/admin/static/favicon/android-chrome-512x512.png +0 -0
  142. mindroot/coreplugins/admin/static/favicon/apple-touch-icon.png +0 -0
  143. mindroot/coreplugins/admin/static/favicon/favicon-16x16.png +0 -0
  144. mindroot/coreplugins/admin/static/favicon/favicon-32x32.png +0 -0
  145. mindroot/coreplugins/admin/static/favicon/favicon.ico +0 -0
  146. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/about.txt +0 -6
  147. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
  148. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
  149. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
  150. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
  151. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
  152. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon.ico +0 -0
  153. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/site.webmanifest +0 -1
  154. mindroot/coreplugins/admin/static/favicon/logo.png +0 -0
  155. mindroot/coreplugins/admin/static/favicon/site.webmanifest +0 -1
  156. mindroot/coreplugins/admin/static/js/backup/agent-editor.js +0 -186
  157. mindroot/coreplugins/admin/static/js/backup/agent-form.js +0 -1133
  158. mindroot/coreplugins/admin/static/js/backup/agent-list.js +0 -94
  159. mindroot/coreplugins/chat/static/favicon/about.txt +0 -6
  160. mindroot/coreplugins/chat/static/favicon/android-chrome-192x192.png +0 -0
  161. mindroot/coreplugins/chat/static/favicon/android-chrome-512x512.png +0 -0
  162. mindroot/coreplugins/chat/static/favicon/apple-touch-icon.png +0 -0
  163. mindroot/coreplugins/chat/static/favicon/favicon-16x16.png +0 -0
  164. mindroot/coreplugins/chat/static/favicon/favicon-32x32.png +0 -0
  165. mindroot/coreplugins/chat/static/favicon/favicon.ico +0 -0
  166. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/about.txt +0 -6
  167. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
  168. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
  169. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
  170. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
  171. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
  172. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon.ico +0 -0
  173. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/site.webmanifest +0 -1
  174. mindroot/coreplugins/chat/static/favicon/logo.png +0 -0
  175. mindroot/coreplugins/chat/static/favicon/site.webmanifest +0 -1
  176. mindroot/coreplugins/index/default.json +0 -76
  177. mindroot/coreplugins/user_service/file_trigger_service.py +0 -12
  178. mindroot/coreplugins/user_service/hooks.py +0 -23
  179. /mindroot/coreplugins/{admin/static/favicon/android-chrome-192x192.png → home/static/imgs/backuplogo.png} +0 -0
  180. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/WHEEL +0 -0
  181. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/entry_points.txt +0 -0
  182. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/licenses/LICENSE +0 -0
  183. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Registry Publish Section
3
+ *
4
+ * Handles publishing workflows for plugins, agents, and MCP servers
5
+ * to the registry.
6
+ */
7
+
8
+ import { html } from '/admin/static/js/lit-core.min.js';
9
+
10
+ class RegistryPublishSection {
11
+ constructor(sharedState, mainComponent) {
12
+ this.state = sharedState;
13
+ this.main = mainComponent;
14
+ this.services = null; // Will be set by main component
15
+ }
16
+
17
+ setServices(services) {
18
+ this.services = services;
19
+ }
20
+
21
+ // === Event Handlers ===
22
+
23
+ async handlePublishPluginFromGithub() {
24
+ const repoInput = this.main.shadowRoot.getElementById('plugin-github-repo');
25
+ const repo = repoInput.value;
26
+
27
+ const success = await this.services.publishPluginFromGithub(repo);
28
+ if (success) {
29
+ repoInput.value = '';
30
+ }
31
+ this.main.requestUpdate();
32
+ }
33
+
34
+ async refreshOwnershipCache() {
35
+ await this.services.refreshOwnershipCache();
36
+ this.main.requestUpdate();
37
+ }
38
+
39
+ async publishItem(item, type) {
40
+ if (!this.state.isLoggedIn) {
41
+ this.main.error = 'Please log in to publish items';
42
+ this.main.requestUpdate();
43
+ return;
44
+ }
45
+
46
+ this.state.loading = true;
47
+ this.main.error = '';
48
+
49
+ try {
50
+ let publishData;
51
+
52
+ if (type === 'agent') {
53
+ publishData = await this.buildAgentPublishData(item);
54
+ } else {
55
+ throw new Error('Unknown item type');
56
+ }
57
+
58
+ const response = await fetch(`${this.state.registryUrl}/publish`, {
59
+ method: 'POST',
60
+ headers: {
61
+ 'Content-Type': 'application/json',
62
+ 'Authorization': `Bearer ${this.state.authToken}`
63
+ },
64
+ body: JSON.stringify(publishData)
65
+ });
66
+
67
+ if (response.ok) {
68
+ const result = await response.json();
69
+ this.services.showToast(`Successfully published ${publishData.title}!`, 'success');
70
+ } else {
71
+ const errorData = await response.json();
72
+ this.services.showToast(errorData.details || 'Publishing failed', 'error');
73
+ }
74
+ } catch (error) {
75
+ this.services.showToast('Publishing failed: ' + error.message, 'error');
76
+ }
77
+
78
+ this.state.loading = false;
79
+ this.main.requestUpdate();
80
+ }
81
+
82
+ // === Helper Methods ===
83
+
84
+ async buildAgentPublishData(item) {
85
+ // Load persona data if agent has a persona
86
+ let personaData = null;
87
+ let personaAssets = null;
88
+
89
+ if (item.persona && typeof item.persona === 'string') {
90
+ personaData = await this.loadPersonaData(item.persona);
91
+
92
+ // Clean persona data - remove absolute file paths
93
+ if (personaData) {
94
+ delete personaData.avatar_image_path;
95
+ delete personaData.face_ref_image_path;
96
+ delete personaData.avatar;
97
+ delete personaData.faceref;
98
+ }
99
+
100
+ // Load and upload persona assets to registry
101
+ const localAssets = await this.uploadPersonaAssets(item.persona);
102
+ if (Object.keys(localAssets).length > 0) {
103
+ const assetData = await this.convertAssetsToBase64(localAssets);
104
+ if (personaData) {
105
+ personaData.persona_assets = assetData;
106
+ console.log('Added asset data to persona data:', Object.keys(assetData));
107
+ }
108
+ personaAssets = assetData;
109
+ }
110
+ }
111
+
112
+ return {
113
+ title: item.name,
114
+ description: item.description || `${item.name} agent`,
115
+ category: 'agent',
116
+ content_type: 'mindroot_agent',
117
+ version: item.version || '1.0.0',
118
+ data: {
119
+ agent_config: item,
120
+ persona_ref: personaData ? {
121
+ name: personaData.name,
122
+ owner: this.state.currentUser?.username,
123
+ version: personaData.version || '1.0.0',
124
+ original_path: item.persona
125
+ } : null,
126
+ persona_data: personaData,
127
+ persona_assets: personaAssets,
128
+ persona: item.persona || personaData?.name || {},
129
+ instructions: item.instructions || '',
130
+ model: item.model || 'default'
131
+ },
132
+ tags: item.tags || ['agent'],
133
+ dependencies: item.dependencies || []
134
+ };
135
+ }
136
+
137
+ async loadPersonaData(personaRef) {
138
+ try {
139
+ let personaPath;
140
+ if (personaRef.startsWith('registry/')) {
141
+ personaPath = `/personas/${personaRef}`;
142
+ } else {
143
+ personaPath = `/personas/local/${personaRef}`;
144
+ }
145
+
146
+ const response = await fetch(personaPath);
147
+ if (response.ok) {
148
+ return await response.json();
149
+ }
150
+
151
+ if (!personaRef.startsWith('registry/')) {
152
+ const sharedResponse = await fetch(`/personas/shared/${personaRef}`);
153
+ if (sharedResponse.ok) {
154
+ return await sharedResponse.json();
155
+ }
156
+ }
157
+
158
+ return null;
159
+ } catch (error) {
160
+ console.error('Error loading persona data:', error);
161
+ return null;
162
+ }
163
+ }
164
+
165
+ async uploadPersonaAssets(personaRef) {
166
+ try {
167
+ console.log('Uploading persona assets for:', personaRef);
168
+ const assets = {};
169
+
170
+ // Check for avatar image
171
+ const avatarPath = `/chat/personas/${personaRef}/avatar.png`;
172
+ try {
173
+ const avatarResponse = await fetch(avatarPath);
174
+ if (avatarResponse.ok) {
175
+ const avatarBlob = await avatarResponse.blob();
176
+ console.log('Found avatar image, size:', avatarBlob.size);
177
+ assets.avatar = avatarBlob;
178
+ }
179
+ } catch (e) {
180
+ console.log(`No avatar found for persona ${personaRef}`);
181
+ }
182
+
183
+ // Check for faceref image
184
+ const facerefPath = `/chat/personas/${personaRef}/faceref.png`;
185
+ try {
186
+ const facerefResponse = await fetch(facerefPath);
187
+ if (facerefResponse.ok) {
188
+ const facerefBlob = await facerefResponse.blob();
189
+ console.log('Found faceref image, size:', facerefBlob.size);
190
+ assets.faceref = facerefBlob;
191
+ }
192
+ } catch (e) {
193
+ console.log(`No faceref found for persona ${personaRef}`);
194
+ }
195
+
196
+ console.log('Total assets found:', Object.keys(assets).length);
197
+ return assets;
198
+ } catch (error) {
199
+ console.error('Error loading persona assets for upload:', error);
200
+ return {};
201
+ }
202
+ }
203
+
204
+ async convertAssetsToBase64(assets) {
205
+ try {
206
+ console.log('Converting assets to base64:', Object.keys(assets));
207
+ const assetData = {};
208
+
209
+ for (const [assetType, blob] of Object.entries(assets)) {
210
+ console.log(`Converting ${assetType} to base64...`);
211
+ const arrayBuffer = await blob.arrayBuffer();
212
+ const uint8Array = new Uint8Array(arrayBuffer);
213
+ const binaryString = Array.from(uint8Array, byte => String.fromCharCode(byte)).join('');
214
+ const base64String = btoa(binaryString);
215
+
216
+ assetData[assetType] = {
217
+ data: base64String,
218
+ type: 'image/png',
219
+ size: blob.size
220
+ };
221
+ console.log(`${assetType} converted successfully, size:`, blob.size);
222
+ }
223
+
224
+ console.log('Final asset data keys:', Object.keys(assetData));
225
+ return assetData;
226
+ } catch (error) {
227
+ console.error('Error converting assets to base64:', error);
228
+ return {};
229
+ }
230
+ }
231
+
232
+ // === Render Methods ===
233
+
234
+ renderPublish() {
235
+ if (!this.state.isLoggedIn) {
236
+ return this.renderLoginRequired();
237
+ }
238
+
239
+ return html`
240
+ <div class="publish-details">
241
+ ${this.renderGithubPublishing()}
242
+ ${this.renderLocalPublishing()}
243
+ ${this.renderMcpPublishing()}
244
+ </div>
245
+ `;
246
+ }
247
+
248
+ renderLoginRequired() {
249
+ return html`
250
+ <div class="section">
251
+ <h3>Publish to Registry</h3>
252
+ <p>Please log in to publish plugins and agents to the registry.</p>
253
+ </div>
254
+ `;
255
+ }
256
+
257
+ renderGithubPublishing() {
258
+ return html`
259
+ <details>
260
+ <summary>Publish Plugin from GitHub</summary>
261
+ <div class="publish-form" style="max-width: 500px; display: flex; flex-direction: column; gap: 1rem;">
262
+ <p>Enter the GitHub repository (e.g., user/repo) to publish a plugin directly to the registry.</p>
263
+ <input type="text" placeholder="GitHub Repository (e.g., user/repo)" id="plugin-github-repo">
264
+ <button class="primary" @click=${() => this.handlePublishPluginFromGithub()}>Publish from GitHub</button>
265
+ </div>
266
+ </details>
267
+ `;
268
+ }
269
+
270
+ renderLocalPublishing() {
271
+ return html`
272
+ <!-- <div class="section"> -->
273
+ <details>
274
+ <summary>Publish Agent</summary>
275
+ ${this.renderOwnershipInfo()}
276
+ <p>Select a local plugin or agent to publish to the registry:</p>
277
+
278
+ ${this.renderPublishingStatus()}
279
+ ${this.renderLocalAgents()}
280
+ </details>
281
+ <!-- </div> -->
282
+ `;
283
+ }
284
+
285
+ renderOwnershipInfo() {
286
+ return html`
287
+ <div class="form-row">
288
+ <button @click=${() => this.refreshOwnershipCache()} ?disabled=${this.state.loading}>
289
+ Refresh Ownership Info
290
+ </button>
291
+ <span class="help-text">
292
+ Last scanned: ${this.main.agentOwnership?.scanned_at ?
293
+ new Date(this.main.agentOwnership.scanned_at).toLocaleString() : "Never"}
294
+ </span>
295
+ </div>
296
+ `;
297
+ }
298
+
299
+ renderPublishingStatus() {
300
+ if (this.state.loading) {
301
+ return html`<div class="loading">Publishing...</div>`;
302
+ }
303
+
304
+ if (this.main.publishSuccess) {
305
+ return html`<div class="success">${this.main.publishSuccess}</div>`;
306
+ }
307
+
308
+ if (this.main.error) {
309
+ const isSuccess = this.main.error.includes("Successfully");
310
+ return html`<div class="${isSuccess ? "success" : "error"}">${this.main.error}</div>`;
311
+ }
312
+
313
+ return '';
314
+ }
315
+
316
+ renderLocalAgents() {
317
+ return html`
318
+ <h4>Local Agents (${this.state.localAgents.length})</h4>
319
+ ${this.state.localAgents.length === 0 ? html`
320
+ <p class="help-text">No local agents found. Create some agents first to publish them.</p>
321
+ ` : html`
322
+ ${this.state.localAgents.map(agent => this.renderAgentItem(agent))}
323
+ `}
324
+ `;
325
+ }
326
+
327
+ renderAgentItem(agent) {
328
+ const agentKey = `local/${agent.name}`;
329
+ const ownershipInfo = this.main.agentOwnership?.agents?.[agentKey];
330
+ const hasExternalOwner = ownershipInfo?.has_external_owner || false;
331
+ const canPublish = !hasExternalOwner;
332
+ const ownerName = ownershipInfo?.creator || ownershipInfo?.owner || ownershipInfo?.registry_owner || ownershipInfo?.created_by;
333
+
334
+ return html`
335
+ <div class="result-item">
336
+ <h5 class="result-title">${agent.name}</h5>
337
+ <p class="result-description">${agent.description || "No description available"}</p>
338
+ ${hasExternalOwner ? html`
339
+ <p class="help-text" style="color: #dc3545;">Cannot publish: Agent created by ${ownerName || "another user"}</p>
340
+ ` : ""}
341
+ <div class="result-actions">
342
+ <button class="primary"
343
+ @click=${() => this.publishItem(agent, "agent")}
344
+ ?disabled=${this.state.loading || !canPublish}>
345
+ Publish Agent
346
+ </button>
347
+ </div>
348
+ </div>
349
+ `;
350
+ }
351
+
352
+ renderMcpPublishing() {
353
+ return html`
354
+ <!-- <div class="section"> -->
355
+ <!-- <details>
356
+ <summary>
357
+ <h3>MCP Server Registry</h3>
358
+ </summary>
359
+ <mcp-registry-browser></mcp-registry-browser>
360
+ <!-- </div>
361
+ </details> -->
362
+
363
+ <!-- <div class="section"> -->
364
+ <details>
365
+ <summary>Publish New MCP Server</summary>
366
+ <mcp-publisher
367
+ .registryUrl=${this.state.registryUrl}
368
+ .authToken=${this.state.authToken}
369
+ .isLoggedIn=${this.state.isLoggedIn}
370
+ ></mcp-publisher>
371
+ <!-- </div> -->
372
+ </details>
373
+ `;
374
+ }
375
+ }
376
+
377
+ export { RegistryPublishSection };