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.
Files changed (186) 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 +63 -0
  14. mindroot/coreplugins/admin/plugin_router.py +1 -1
  15. mindroot/coreplugins/admin/plugin_router_fixed.py +23 -0
  16. mindroot/coreplugins/admin/plugin_router_new_not_working.py +145 -0
  17. mindroot/coreplugins/admin/plugin_routes.py +114 -0
  18. mindroot/coreplugins/admin/registry_settings_routes.py +140 -0
  19. mindroot/coreplugins/admin/router.py +116 -15
  20. mindroot/coreplugins/admin/service_models.py +1 -1
  21. mindroot/coreplugins/admin/settings_router.py +1 -0
  22. mindroot/coreplugins/admin/static/css/admin-custom.css +357 -2
  23. mindroot/coreplugins/admin/static/css/dark.css +1 -0
  24. mindroot/coreplugins/admin/static/css/default.css +4 -0
  25. mindroot/coreplugins/admin/static/js/about-info.js +367 -0
  26. mindroot/coreplugins/admin/static/js/agent-form.js +83 -3
  27. mindroot/coreplugins/admin/static/js/api-key-script.js +307 -0
  28. mindroot/coreplugins/admin/static/js/mcp-manager.js +348 -0
  29. mindroot/coreplugins/admin/static/js/mcp-publisher.js +780 -0
  30. mindroot/coreplugins/admin/static/js/persona-editor.js +34 -5
  31. mindroot/coreplugins/admin/static/js/plugin-toggle.js +1 -1
  32. mindroot/coreplugins/admin/static/js/recommended-plugin-install.js +63 -0
  33. mindroot/coreplugins/admin/static/js/registry-auth-section.js +132 -0
  34. mindroot/coreplugins/admin/static/js/registry-manager-base.js +613 -0
  35. mindroot/coreplugins/admin/static/js/registry-manager-old.js +385 -0
  36. mindroot/coreplugins/admin/static/js/registry-manager-publish-old-delete.js +166 -0
  37. mindroot/coreplugins/admin/static/js/registry-manager.js +351 -0
  38. mindroot/coreplugins/admin/static/js/registry-publish-section.js +377 -0
  39. mindroot/coreplugins/admin/static/js/registry-search-section.js +400 -0
  40. mindroot/coreplugins/admin/static/js/registry-search-section.js.bak +3 -0
  41. mindroot/coreplugins/admin/static/js/registry-settings.js +69 -0
  42. mindroot/coreplugins/admin/static/js/registry-shared-services.js +857 -0
  43. mindroot/coreplugins/admin/static/js/registry-simple-sections.js +85 -0
  44. mindroot/coreplugins/admin/static/js/secure-widget-manager.js +438 -0
  45. mindroot/coreplugins/admin/static/logo.png +0 -0
  46. mindroot/coreplugins/admin/templates/admin.jinja2 +275 -110
  47. mindroot/coreplugins/agent/Assistant/agent.json +27 -11
  48. mindroot/coreplugins/agent/agent.py +2 -2
  49. mindroot/coreplugins/agent/command_parser.py +25 -10
  50. mindroot/coreplugins/agent/templates/system.jinja2 +0 -12
  51. mindroot/coreplugins/chat/__init__.py +4 -1
  52. mindroot/coreplugins/chat/router.py +132 -20
  53. mindroot/coreplugins/chat/router_dedup_patch.py +20 -0
  54. mindroot/coreplugins/chat/services.py +31 -1
  55. mindroot/coreplugins/chat/static/css/action-fix.css +32 -0
  56. mindroot/coreplugins/chat/static/css/admin-custom.css +5 -3
  57. mindroot/coreplugins/chat/static/css/dark.css +24 -3
  58. mindroot/coreplugins/chat/static/css/default.css +24 -3
  59. mindroot/coreplugins/chat/static/css/main.css +1 -0
  60. mindroot/coreplugins/chat/static/js/action.js +137 -60
  61. mindroot/coreplugins/chat/static/js/chat-history.js +3 -0
  62. mindroot/coreplugins/chat/static/js/chat.js +59 -16
  63. mindroot/coreplugins/chat/static/js/chat.js.diff +221 -0
  64. mindroot/coreplugins/chat/static/js/chatform.js +2 -2
  65. mindroot/coreplugins/chat/static/site.webmanifest +1 -1
  66. mindroot/coreplugins/chat/templates/chat.jinja2 +3 -3
  67. mindroot/coreplugins/chat/widget_manager.py +139 -0
  68. mindroot/coreplugins/chat/widget_routes.py +287 -0
  69. mindroot/coreplugins/check_list/inject/admin.jinja2 +1 -1
  70. mindroot/coreplugins/email/__init__.py +2 -0
  71. mindroot/coreplugins/email/email_provider.py +2 -2
  72. mindroot/coreplugins/email/mod.py +100 -0
  73. mindroot/coreplugins/email/services.py +5 -3
  74. mindroot/coreplugins/email/smtp_handler.py +9 -3
  75. mindroot/coreplugins/email/test_email_service.py +75 -0
  76. mindroot/coreplugins/env_manager/mod.py +61 -25
  77. mindroot/coreplugins/home/router.py +37 -2
  78. mindroot/coreplugins/home/static/imgs/logo.png +0 -0
  79. mindroot/coreplugins/home/static/imgs/logo.png.bak +0 -0
  80. mindroot/coreplugins/home/static/imgs/logo_teal.png +0 -0
  81. mindroot/coreplugins/home/static/imgs/logo_teal2.png +0 -0
  82. mindroot/coreplugins/home/static/imgs/logo_teal_detailed.png +0 -0
  83. mindroot/coreplugins/home/static/imgs/logo_teal_python.png +0 -0
  84. mindroot/coreplugins/home/templates/home.jinja2 +15 -6
  85. mindroot/coreplugins/index/handlers/plugin_ops.py +1 -1
  86. mindroot/coreplugins/index/indices/default/index.json +6 -6
  87. mindroot/coreplugins/jwt_auth/middleware.py +47 -1
  88. mindroot/coreplugins/jwt_auth/mod.py +40 -17
  89. mindroot/coreplugins/l8n/__init__.py +6 -0
  90. mindroot/coreplugins/l8n/debug_loader.py +85 -0
  91. mindroot/coreplugins/l8n/debug_middleware.py +74 -0
  92. mindroot/coreplugins/l8n/l8n_constants.py +19 -0
  93. mindroot/coreplugins/l8n/language_detection.py +183 -0
  94. mindroot/coreplugins/l8n/middleware.py +151 -0
  95. mindroot/coreplugins/l8n/mod.py +277 -0
  96. mindroot/coreplugins/l8n/monkey_patch_to_delete.py +186 -0
  97. mindroot/coreplugins/l8n/test_enhanced.py +298 -0
  98. mindroot/coreplugins/l8n/test_l8n.py +95 -0
  99. mindroot/coreplugins/l8n/test_l8n_standalone.py +251 -0
  100. mindroot/coreplugins/l8n/test_middleware.py +272 -0
  101. mindroot/coreplugins/l8n/utils.py +232 -0
  102. mindroot/coreplugins/mcp_/__init__.py +14 -0
  103. mindroot/coreplugins/mcp_/catalog_commands.py +328 -0
  104. mindroot/coreplugins/mcp_/catalog_manager.py +263 -0
  105. mindroot/coreplugins/mcp_/dynamic_commands.py +154 -0
  106. mindroot/coreplugins/mcp_/mcp_manager.py +1031 -0
  107. mindroot/coreplugins/mcp_/mod.py +367 -0
  108. mindroot/coreplugins/mcp_/oauth_storage.py +144 -0
  109. mindroot/coreplugins/mcp_/server_installer.py +79 -0
  110. mindroot/coreplugins/mcp_/setup.py +26 -0
  111. mindroot/coreplugins/mcp_/test_dynamic_commands.py +134 -0
  112. mindroot/coreplugins/mcp_/testmcpclient.py +92 -0
  113. mindroot/coreplugins/persona/mod.py +12 -7
  114. mindroot/coreplugins/signup/templates/signup.jinja2 +1 -1
  115. mindroot/coreplugins/subscriptions/__init__.py +1 -0
  116. mindroot/coreplugins/subscriptions/mod.py +14 -3
  117. mindroot/coreplugins/subscriptions/router.py +3 -0
  118. mindroot/coreplugins/user_service/__init__.py +1 -2
  119. mindroot/coreplugins/user_service/admin_init.py +1 -0
  120. mindroot/coreplugins/user_service/email_service.py +72 -17
  121. mindroot/coreplugins/user_service/mod.py +10 -2
  122. mindroot/coreplugins/user_service/password_reset_service.py +180 -27
  123. mindroot/coreplugins/user_service/router.py +84 -22
  124. mindroot/lib/auth/api_key.py +28 -0
  125. mindroot/lib/cli/plugins.py +94 -0
  126. mindroot/lib/plugins/default_plugin_manifest.json +20 -0
  127. mindroot/lib/plugins/installation.py +5 -5
  128. mindroot/lib/plugins/l8n_static_handler.py +225 -0
  129. mindroot/lib/plugins/loader.py +33 -3
  130. mindroot/lib/plugins/loader_with_l8n.py +281 -0
  131. mindroot/lib/plugins/manifest.py +238 -17
  132. mindroot/lib/providers/commands.py +3 -1
  133. mindroot/lib/route_decorators.py +5 -5
  134. mindroot/lib/templates.py +183 -11
  135. mindroot/lib/utils/merge_arrays.py +1 -1
  136. mindroot/migrate.py +49 -0
  137. mindroot/registry/data_access.py +1 -1
  138. mindroot/server.py +47 -13
  139. mindroot/server_missing_normal_args.py +197 -0
  140. mindroot/server_prev.py +173 -0
  141. {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/METADATA +7 -2
  142. {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/RECORD +147 -114
  143. mindroot/coreplugins/admin/static/favicon/about.txt +0 -6
  144. mindroot/coreplugins/admin/static/favicon/android-chrome-512x512.png +0 -0
  145. mindroot/coreplugins/admin/static/favicon/apple-touch-icon.png +0 -0
  146. mindroot/coreplugins/admin/static/favicon/favicon-16x16.png +0 -0
  147. mindroot/coreplugins/admin/static/favicon/favicon-32x32.png +0 -0
  148. mindroot/coreplugins/admin/static/favicon/favicon.ico +0 -0
  149. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/about.txt +0 -6
  150. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
  151. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
  152. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
  153. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
  154. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
  155. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon.ico +0 -0
  156. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/site.webmanifest +0 -1
  157. mindroot/coreplugins/admin/static/favicon/logo.png +0 -0
  158. mindroot/coreplugins/admin/static/favicon/site.webmanifest +0 -1
  159. mindroot/coreplugins/admin/static/js/backup/agent-editor.js +0 -186
  160. mindroot/coreplugins/admin/static/js/backup/agent-form.js +0 -1133
  161. mindroot/coreplugins/admin/static/js/backup/agent-list.js +0 -94
  162. mindroot/coreplugins/chat/static/favicon/about.txt +0 -6
  163. mindroot/coreplugins/chat/static/favicon/android-chrome-192x192.png +0 -0
  164. mindroot/coreplugins/chat/static/favicon/android-chrome-512x512.png +0 -0
  165. mindroot/coreplugins/chat/static/favicon/apple-touch-icon.png +0 -0
  166. mindroot/coreplugins/chat/static/favicon/favicon-16x16.png +0 -0
  167. mindroot/coreplugins/chat/static/favicon/favicon-32x32.png +0 -0
  168. mindroot/coreplugins/chat/static/favicon/favicon.ico +0 -0
  169. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/about.txt +0 -6
  170. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
  171. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
  172. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
  173. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
  174. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
  175. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon.ico +0 -0
  176. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/site.webmanifest +0 -1
  177. mindroot/coreplugins/chat/static/favicon/logo.png +0 -0
  178. mindroot/coreplugins/chat/static/favicon/site.webmanifest +0 -1
  179. mindroot/coreplugins/index/default.json +0 -76
  180. mindroot/coreplugins/user_service/file_trigger_service.py +0 -72
  181. mindroot/coreplugins/user_service/hooks.py +0 -23
  182. /mindroot/coreplugins/{admin/static/favicon/android-chrome-192x192.png → home/static/imgs/backuplogo.png} +0 -0
  183. {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/WHEEL +0 -0
  184. {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/entry_points.txt +0 -0
  185. {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/licenses/LICENSE +0 -0
  186. {mindroot-9.2.0.dist-info → mindroot-9.5.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,367 @@
1
+ import { LitElement, html, css } from '/admin/static/js/lit-core.min.js';
2
+ import { BaseEl } from '/admin/static/js/base.js';
3
+
4
+ class AboutInfo extends BaseEl {
5
+ static properties = {
6
+ versionInfo: { type: Object },
7
+ loading: { type: Boolean },
8
+ updating: { type: Boolean },
9
+ updateResult: { type: Object },
10
+ error: { type: String }
11
+ }
12
+
13
+ static styles = css`
14
+ :host {
15
+ display: block;
16
+ width: 100%;
17
+ height: 100%;
18
+ }
19
+
20
+ .about-container {
21
+ display: flex;
22
+ flex-direction: column;
23
+ width: 100%;
24
+ max-width: 800px;
25
+ margin: 0 auto;
26
+ gap: 20px;
27
+ }
28
+
29
+ .section {
30
+ background: rgb(10, 10, 25);
31
+ border-radius: 8px;
32
+ padding: 1.5rem;
33
+ border: 1px solid rgba(255, 255, 255, 0.1);
34
+ }
35
+
36
+ .section h2 {
37
+ margin: 0 0 1rem 0;
38
+ color: #fff;
39
+ font-size: 1.2rem;
40
+ font-weight: 500;
41
+ }
42
+
43
+ .version-info {
44
+ display: grid;
45
+ grid-template-columns: auto 1fr;
46
+ gap: 0.5rem 1rem;
47
+ align-items: center;
48
+ }
49
+
50
+ .label {
51
+ font-weight: 500;
52
+ color: rgba(255, 255, 255, 0.8);
53
+ }
54
+
55
+ .value {
56
+ font-family: monospace;
57
+ background: rgba(0, 0, 0, 0.2);
58
+ padding: 0.25rem 0.5rem;
59
+ border-radius: 4px;
60
+ color: #fff;
61
+ word-break: break-all;
62
+ }
63
+
64
+ .loading {
65
+ text-align: center;
66
+ padding: 2rem;
67
+ color: rgba(255, 255, 255, 0.6);
68
+ }
69
+
70
+ .error {
71
+ color: #ff6b6b;
72
+ background: rgba(255, 107, 107, 0.1);
73
+ padding: 1rem;
74
+ border-radius: 4px;
75
+ border: 1px solid rgba(255, 107, 107, 0.2);
76
+ }
77
+
78
+ .success {
79
+ color: #51cf66;
80
+ background: rgba(81, 207, 102, 0.1);
81
+ padding: 1rem;
82
+ border-radius: 4px;
83
+ border: 1px solid rgba(81, 207, 102, 0.2);
84
+ }
85
+
86
+ .warning {
87
+ color: #ffd43b;
88
+ background: rgba(255, 212, 59, 0.1);
89
+ padding: 1rem;
90
+ border-radius: 4px;
91
+ border: 1px solid rgba(255, 212, 59, 0.2);
92
+ }
93
+
94
+ .info {
95
+ color: #74c0fc;
96
+ background: rgba(116, 192, 252, 0.1);
97
+ padding: 1rem;
98
+ border-radius: 4px;
99
+ border: 1px solid rgba(116, 192, 252, 0.2);
100
+ }
101
+
102
+ .btn {
103
+ background: #2a2a40;
104
+ color: #fff;
105
+ border: 1px solid rgba(255, 255, 255, 0.1);
106
+ padding: 0.5rem 1rem;
107
+ border-radius: 4px;
108
+ cursor: pointer;
109
+ transition: background 0.2s;
110
+ margin-top: 1rem;
111
+ margin-right: 0.5rem;
112
+ }
113
+
114
+ .btn:hover:not(:disabled) {
115
+ background: #3a3a50;
116
+ }
117
+
118
+ .btn:disabled {
119
+ opacity: 0.5;
120
+ cursor: not-allowed;
121
+ }
122
+
123
+ .btn.update {
124
+ background: #2a4a2a;
125
+ }
126
+
127
+ .btn.update:hover:not(:disabled) {
128
+ background: #3a5a3a;
129
+ }
130
+
131
+ .logo-section {
132
+ text-align: center;
133
+ }
134
+
135
+ .logo-section img {
136
+ max-width: 200px;
137
+ height: auto;
138
+ }
139
+
140
+ .title {
141
+ font-size: 2rem;
142
+ font-weight: bold;
143
+ color: #fff;
144
+ margin: 1rem 0;
145
+ }
146
+
147
+ .description {
148
+ color: rgba(255, 255, 255, 0.8);
149
+ line-height: 1.6;
150
+ }
151
+
152
+ .update-output {
153
+ background: rgba(0, 0, 0, 0.3);
154
+ padding: 1rem;
155
+ border-radius: 4px;
156
+ font-family: monospace;
157
+ font-size: 0.9rem;
158
+ white-space: pre-wrap;
159
+ max-height: 300px;
160
+ overflow-y: auto;
161
+ margin-top: 1rem;
162
+ }
163
+
164
+ .button-group {
165
+ display: flex;
166
+ gap: 0.5rem;
167
+ margin-top: 1rem;
168
+ }
169
+
170
+ .restart-notice {
171
+ margin-top: 1rem;
172
+ }
173
+
174
+ .restart-notice p {
175
+ margin: 0 0 0.5rem 0;
176
+ }
177
+
178
+ .tab-link {
179
+ color: #74c0fc;
180
+ text-decoration: underline;
181
+ cursor: pointer;
182
+ }
183
+
184
+ .tab-link:hover {
185
+ color: #91d5ff;
186
+ }
187
+ `;
188
+
189
+ constructor() {
190
+ super();
191
+ this.versionInfo = null;
192
+ this.loading = false;
193
+ this.updating = false;
194
+ this.updateResult = null;
195
+ this.error = null;
196
+ this.loadVersionInfo();
197
+ }
198
+
199
+ async loadVersionInfo() {
200
+ this.loading = true;
201
+ this.error = null;
202
+
203
+ try {
204
+ // First try to get git info and update version.txt
205
+ const response = await fetch('/admin/get-version-info', {
206
+ method: 'POST',
207
+ headers: {
208
+ 'Content-Type': 'application/json',
209
+ }
210
+ });
211
+
212
+ if (response.ok) {
213
+ const result = await response.json();
214
+ this.versionInfo = result;
215
+ } else {
216
+ throw new Error('Failed to get version info');
217
+ }
218
+ } catch (error) {
219
+ console.error('Error loading version info:', error);
220
+ this.error = 'Failed to load version information';
221
+ } finally {
222
+ this.loading = false;
223
+ }
224
+ }
225
+
226
+ async handleUpdate() {
227
+ this.updating = true;
228
+ this.updateResult = null;
229
+ this.error = null;
230
+
231
+ try {
232
+ const response = await fetch('/admin/update-mindroot', {
233
+ method: 'POST',
234
+ headers: {
235
+ 'Content-Type': 'application/json',
236
+ }
237
+ });
238
+
239
+ if (response.ok) {
240
+ const result = await response.json();
241
+ this.updateResult = result;
242
+
243
+ // If successful, refresh version info after a short delay
244
+ if (result.success) {
245
+ setTimeout(() => {
246
+ this.loadVersionInfo();
247
+ }, 2000);
248
+ }
249
+ } else {
250
+ throw new Error('Failed to update MindRoot');
251
+ }
252
+ } catch (error) {
253
+ console.error('Error updating MindRoot:', error);
254
+ this.error = 'Failed to update MindRoot';
255
+ } finally {
256
+ this.updating = false;
257
+ }
258
+ }
259
+
260
+ handleRefresh() {
261
+ this.loadVersionInfo();
262
+ }
263
+
264
+ switchToServerTab() {
265
+ // Find and click the Server Control tab
266
+ const serverTab = document.querySelector('details[data-tab="server"] summary');
267
+ if (serverTab) {
268
+ // Close current tab if it's open
269
+ const currentTab = document.querySelector('details[open]');
270
+ if (currentTab && currentTab !== serverTab.parentElement) {
271
+ currentTab.removeAttribute('open');
272
+ }
273
+ // Open server tab
274
+ serverTab.parentElement.setAttribute('open', '');
275
+ serverTab.scrollIntoView({ behavior: 'smooth' });
276
+ }
277
+ }
278
+
279
+ formatDate(dateString) {
280
+ if (!dateString) return 'Unknown';
281
+ try {
282
+ return new Date(dateString).toLocaleString();
283
+ } catch {
284
+ return dateString;
285
+ }
286
+ }
287
+
288
+ _render() {
289
+ return html`
290
+ <div class="about-container">
291
+ <div class="section logo-section">
292
+ <img src="/admin/static/logo.png" alt="MindRoot Logo" />
293
+ <div class="title">MindRoot</div>
294
+ <div class="description">
295
+ Advanced AI agent framework with modular plugin architecture
296
+ </div>
297
+ </div>
298
+
299
+ <div class="section">
300
+ <h2>Version Information</h2>
301
+
302
+ ${this.loading ? html`
303
+ <div class="loading">Loading version information...</div>
304
+ ` : this.error ? html`
305
+ <div class="error">${this.error}</div>
306
+ <button class="btn" @click=${this.handleRefresh}>Retry</button>
307
+ ` : this.versionInfo ? html`
308
+ <div class="version-info">
309
+ <div class="label">Commit Hash:</div>
310
+ <div class="value">${this.versionInfo.commit_hash || 'Unknown'}</div>
311
+
312
+ <div class="label">Last Commit:</div>
313
+ <div class="value">${this.formatDate(this.versionInfo.commit_date)}</div>
314
+
315
+ <div class="label">Retrieved:</div>
316
+ <div class="value">${this.formatDate(this.versionInfo.retrieved_at)}</div>
317
+ </div>
318
+
319
+ <div class="button-group">
320
+ <button class="btn" @click=${this.handleRefresh}>Refresh</button>
321
+ <button
322
+ class="btn update"
323
+ @click=${this.handleUpdate}
324
+ ?disabled=${this.updating}
325
+ >
326
+ ${this.updating ? 'Updating...' : 'Update MindRoot'}
327
+ </button>
328
+ </div>
329
+ ` : html`
330
+ <div class="error">No version information available</div>
331
+ <button class="btn" @click=${this.handleRefresh}>Retry</button>
332
+ `}
333
+ </div>
334
+
335
+ ${this.updateResult ? html`
336
+ <div class="section">
337
+ <h2>Update Result</h2>
338
+
339
+ ${this.updateResult.success ? html`
340
+ <div class="success">
341
+ ${this.updateResult.message}
342
+ </div>
343
+
344
+ <div class="restart-notice">
345
+ <div class="info">
346
+ <p><strong>Restart Required:</strong> To use the updated version, you need to restart the MindRoot server.</p>
347
+ <p>You can restart the server using the <span class="tab-link" @click=${this.switchToServerTab}>Server Control</span> tab.</p>
348
+ </div>
349
+ </div>
350
+ ` : html`
351
+ <div class="error">
352
+ ${this.updateResult.message}
353
+ ${this.updateResult.error ? html`<br><strong>Error:</strong> ${this.updateResult.error}` : ''}
354
+ </div>
355
+ `}
356
+
357
+ ${this.updateResult.output ? html`
358
+ <div class="update-output">${this.updateResult.output}</div>
359
+ ` : ''}
360
+ </div>
361
+ ` : ''}
362
+ </div>
363
+ `;
364
+ }
365
+ }
366
+
367
+ customElements.define('about-info', AboutInfo);
@@ -257,7 +257,7 @@ class AgentForm extends BaseEl {
257
257
 
258
258
  .commands-grid {
259
259
  display: grid;
260
- grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
260
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
261
261
  gap: 12px;
262
262
  }
263
263
 
@@ -265,7 +265,7 @@ class AgentForm extends BaseEl {
265
265
  display: flex;
266
266
  align-items: center;
267
267
  justify-content: space-between;
268
- padding: 8px 12px;
268
+ padding: 10px 15px;
269
269
  background: rgba(255, 255, 255, 0.05);
270
270
  border: 1px solid rgba(255, 255, 255, 0.1);
271
271
  border-radius: 6px;
@@ -280,13 +280,17 @@ class AgentForm extends BaseEl {
280
280
 
281
281
  .command-info {
282
282
  flex: 1;
283
- margin-right: 12px;
283
+ margin-right: 20px;
284
+ min-width: 0; /* Allow flex item to shrink below content size */
284
285
  position: relative;
285
286
  }
286
287
 
287
288
  .command-name {
288
289
  color: #f0f0f0;
289
290
  font-weight: 500;
291
+ white-space: nowrap;
292
+ overflow: hidden;
293
+ text-overflow: ellipsis;
290
294
  }
291
295
 
292
296
  .tooltip-text {
@@ -403,6 +407,7 @@ class AgentForm extends BaseEl {
403
407
  handleNewAgent() {
404
408
  this.agent = {
405
409
  name: '',
410
+ description: '',
406
411
  hashver: '',
407
412
  commands: [],
408
413
  preferred_providers: [],
@@ -1033,11 +1038,67 @@ class AgentForm extends BaseEl {
1033
1038
  `;
1034
1039
  }
1035
1040
 
1041
+ async handleExportAgent() {
1042
+ if (!this.agent?.name) {
1043
+ showNotification('error', 'No agent selected for export');
1044
+ return;
1045
+ }
1046
+
1047
+ try {
1048
+ const response = await fetch(`/agents/local/${this.agent.name}/export`);
1049
+ if (!response.ok) throw new Error('Failed to export agent');
1050
+
1051
+ // Create download link
1052
+ const blob = await response.blob();
1053
+ const url = window.URL.createObjectURL(blob);
1054
+ const a = document.createElement('a');
1055
+ a.href = url;
1056
+ a.download = `${this.agent.name}_agent.zip`;
1057
+ document.body.appendChild(a);
1058
+ a.click();
1059
+ document.body.removeChild(a);
1060
+ window.URL.revokeObjectURL(url);
1061
+
1062
+ showNotification('success', `Agent ${this.agent.name} exported successfully`);
1063
+ } catch (error) {
1064
+ showNotification('error', `Error exporting agent: ${error.message}`);
1065
+ }
1066
+ }
1067
+
1068
+ async handleImportAgent(event) {
1069
+ const file = event.target.files[0];
1070
+ if (!file) return;
1071
+
1072
+ if (!file.name.endsWith('.zip')) {
1073
+ showNotification('error', 'Please select a zip file');
1074
+ return;
1075
+ }
1076
+
1077
+ try {
1078
+ const formData = new FormData();
1079
+ formData.append('file', file);
1080
+
1081
+ const response = await fetch('/agents/local/import-zip', {
1082
+ method: 'POST',
1083
+ body: formData
1084
+ });
1085
+
1086
+ const result = await response.json();
1087
+ if (!response.ok) throw new Error(result.detail || 'Import failed');
1088
+
1089
+ showNotification('success', result.message);
1090
+ await this.fetchAgents(); // Refresh agent list
1091
+ } catch (error) {
1092
+ showNotification('error', `Error importing agent: ${error.message}`);
1093
+ }
1094
+ }
1095
+
1036
1096
  _render() {
1037
1097
  // Default structure for rendering when this.agent is null
1038
1098
  // This ensures the DOM structure is present but hidden.
1039
1099
  const agentForRender = this.agent || {
1040
1100
  name: '',
1101
+ description: '',
1041
1102
  persona: '',
1042
1103
  instructions: '',
1043
1104
  technicalInstructions: '',
@@ -1059,6 +1120,18 @@ class AgentForm extends BaseEl {
1059
1120
  <button class="btn btn-secondary" @click=${this.handleNewAgent}>
1060
1121
  New Agent
1061
1122
  </button>
1123
+ <button class="btn btn-secondary" @click=${this.handleExportAgent} ?disabled=${!this.agent}>
1124
+ Export Agent
1125
+ </button>
1126
+ <label class="btn btn-secondary" style="cursor: pointer; display: inline-block;">
1127
+ Import Agent
1128
+ <input
1129
+ type="file"
1130
+ accept=".zip"
1131
+ @change=${this.handleImportAgent}
1132
+ style="display: none;"
1133
+ >
1134
+ </label>
1062
1135
  </div>
1063
1136
 
1064
1137
  <form class="agent-form ${!this.agent ? 'form-hidden-when-no-agent' : ''}" @submit=${this.handleSubmit}>
@@ -1069,6 +1142,13 @@ class AgentForm extends BaseEl {
1069
1142
  @input=${this.handleInputChange}>
1070
1143
  </div>
1071
1144
 
1145
+ <div class="form-group">
1146
+ <label>Description:</label>
1147
+ <input type="text" name="description"
1148
+ .value=${agentForRender.description || ''}
1149
+ @input=${this.handleInputChange}>
1150
+ </div>
1151
+
1072
1152
  <div class="form-group">
1073
1153
  <label class="required">Persona:</label>
1074
1154
  <select name="persona"