@bitseek/hermes-webui 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +213 -0
  2. package/bin/hermes-webui.mjs +588 -0
  3. package/package.json +25 -0
  4. package/scripts/sync-vendor.mjs +74 -0
  5. package/templates/launchd/com.bitseek.hermes-webui.plist +21 -0
  6. package/templates/systemd/hermes-webui.service +13 -0
  7. package/templates/windows/hermes-webui-task.ps1 +3 -0
  8. package/vendor/agent-frontend-shell/.bitseek-source.json +6 -0
  9. package/vendor/agent-frontend-shell/.dockerignore +7 -0
  10. package/vendor/agent-frontend-shell/.env.docker.example +89 -0
  11. package/vendor/agent-frontend-shell/.env.example +34 -0
  12. package/vendor/agent-frontend-shell/.github/FUNDING.yml +3 -0
  13. package/vendor/agent-frontend-shell/.github/workflows/browser-smoke.yml +42 -0
  14. package/vendor/agent-frontend-shell/.github/workflows/docker-smoke.yml +233 -0
  15. package/vendor/agent-frontend-shell/.github/workflows/native-windows-startup.yml +132 -0
  16. package/vendor/agent-frontend-shell/.github/workflows/release.yml +57 -0
  17. package/vendor/agent-frontend-shell/.github/workflows/tests.yml +88 -0
  18. package/vendor/agent-frontend-shell/.vscode/launch.json +59 -0
  19. package/vendor/agent-frontend-shell/.vscode/settings.json +13 -0
  20. package/vendor/agent-frontend-shell/AGENTS.md +80 -0
  21. package/vendor/agent-frontend-shell/ARCHITECTURE.md +1658 -0
  22. package/vendor/agent-frontend-shell/BUGS.md +52 -0
  23. package/vendor/agent-frontend-shell/CHANGELOG.md +7295 -0
  24. package/vendor/agent-frontend-shell/CONTRIBUTING.md +205 -0
  25. package/vendor/agent-frontend-shell/CONTRIBUTORS.md +107 -0
  26. package/vendor/agent-frontend-shell/DESIGN.md +173 -0
  27. package/vendor/agent-frontend-shell/Dockerfile +91 -0
  28. package/vendor/agent-frontend-shell/LICENSE +21 -0
  29. package/vendor/agent-frontend-shell/README-CUSTOM.md +76 -0
  30. package/vendor/agent-frontend-shell/README.md +705 -0
  31. package/vendor/agent-frontend-shell/ROADMAP.md +351 -0
  32. package/vendor/agent-frontend-shell/SPRINTS.md +147 -0
  33. package/vendor/agent-frontend-shell/TESTING.md +1932 -0
  34. package/vendor/agent-frontend-shell/THEMES.md +170 -0
  35. package/vendor/agent-frontend-shell/api/__init__.py +1 -0
  36. package/vendor/agent-frontend-shell/api/agent_health.py +392 -0
  37. package/vendor/agent-frontend-shell/api/agent_sessions.py +782 -0
  38. package/vendor/agent-frontend-shell/api/auth.py +592 -0
  39. package/vendor/agent-frontend-shell/api/background.py +87 -0
  40. package/vendor/agent-frontend-shell/api/clarify.py +238 -0
  41. package/vendor/agent-frontend-shell/api/commands.py +124 -0
  42. package/vendor/agent-frontend-shell/api/compression_anchor.py +134 -0
  43. package/vendor/agent-frontend-shell/api/config.py +5178 -0
  44. package/vendor/agent-frontend-shell/api/dashboard_probe.py +255 -0
  45. package/vendor/agent-frontend-shell/api/extensions.py +253 -0
  46. package/vendor/agent-frontend-shell/api/gateway_chat.py +435 -0
  47. package/vendor/agent-frontend-shell/api/gateway_watcher.py +230 -0
  48. package/vendor/agent-frontend-shell/api/goals.py +608 -0
  49. package/vendor/agent-frontend-shell/api/helpers.py +474 -0
  50. package/vendor/agent-frontend-shell/api/kanban_bridge.py +1255 -0
  51. package/vendor/agent-frontend-shell/api/metering.py +194 -0
  52. package/vendor/agent-frontend-shell/api/models.py +4210 -0
  53. package/vendor/agent-frontend-shell/api/oauth.py +770 -0
  54. package/vendor/agent-frontend-shell/api/onboarding.py +1046 -0
  55. package/vendor/agent-frontend-shell/api/passkeys.py +365 -0
  56. package/vendor/agent-frontend-shell/api/profiles.py +1499 -0
  57. package/vendor/agent-frontend-shell/api/providers.py +2175 -0
  58. package/vendor/agent-frontend-shell/api/request_diagnostics.py +160 -0
  59. package/vendor/agent-frontend-shell/api/rollback.py +320 -0
  60. package/vendor/agent-frontend-shell/api/routes.py +13990 -0
  61. package/vendor/agent-frontend-shell/api/run_journal.py +284 -0
  62. package/vendor/agent-frontend-shell/api/runner_client.py +156 -0
  63. package/vendor/agent-frontend-shell/api/runtime_adapter.py +431 -0
  64. package/vendor/agent-frontend-shell/api/session_discoverability.py +640 -0
  65. package/vendor/agent-frontend-shell/api/session_events.py +45 -0
  66. package/vendor/agent-frontend-shell/api/session_lifecycle.py +208 -0
  67. package/vendor/agent-frontend-shell/api/session_ops.py +207 -0
  68. package/vendor/agent-frontend-shell/api/session_recovery.py +655 -0
  69. package/vendor/agent-frontend-shell/api/skill_usage.py +32 -0
  70. package/vendor/agent-frontend-shell/api/startup.py +128 -0
  71. package/vendor/agent-frontend-shell/api/state_sync.py +187 -0
  72. package/vendor/agent-frontend-shell/api/streaming.py +7048 -0
  73. package/vendor/agent-frontend-shell/api/system_health.py +167 -0
  74. package/vendor/agent-frontend-shell/api/terminal.py +410 -0
  75. package/vendor/agent-frontend-shell/api/turn_journal.py +214 -0
  76. package/vendor/agent-frontend-shell/api/updates.py +1261 -0
  77. package/vendor/agent-frontend-shell/api/upload.py +322 -0
  78. package/vendor/agent-frontend-shell/api/usage.py +26 -0
  79. package/vendor/agent-frontend-shell/api/workspace.py +867 -0
  80. package/vendor/agent-frontend-shell/api/workspace_git.py +1261 -0
  81. package/vendor/agent-frontend-shell/api/worktrees.py +357 -0
  82. package/vendor/agent-frontend-shell/bootstrap.py +492 -0
  83. package/vendor/agent-frontend-shell/ctl.sh +427 -0
  84. package/vendor/agent-frontend-shell/docker-compose.custom.yml +26 -0
  85. package/vendor/agent-frontend-shell/docker-compose.three-container.yml +168 -0
  86. package/vendor/agent-frontend-shell/docker-compose.two-container.yml +147 -0
  87. package/vendor/agent-frontend-shell/docker-compose.yml +57 -0
  88. package/vendor/agent-frontend-shell/docker_init.bash +459 -0
  89. package/vendor/agent-frontend-shell/docs/CONTRACTS.md +207 -0
  90. package/vendor/agent-frontend-shell/docs/EXTENSIONS.md +212 -0
  91. package/vendor/agent-frontend-shell/docs/ISSUES.md +23 -0
  92. package/vendor/agent-frontend-shell/docs/UIUX-GUIDE.md +196 -0
  93. package/vendor/agent-frontend-shell/docs/advanced-chat-setup.md +83 -0
  94. package/vendor/agent-frontend-shell/docs/docker.md +337 -0
  95. package/vendor/agent-frontend-shell/docs/onboarding-agent-checklist.md +207 -0
  96. package/vendor/agent-frontend-shell/docs/onboarding.md +202 -0
  97. package/vendor/agent-frontend-shell/docs/remote-access.md +75 -0
  98. package/vendor/agent-frontend-shell/docs/rfcs/README.md +53 -0
  99. package/vendor/agent-frontend-shell/docs/rfcs/agent-source-boundary.md +70 -0
  100. package/vendor/agent-frontend-shell/docs/rfcs/canonical-session-resolution.md +124 -0
  101. package/vendor/agent-frontend-shell/docs/rfcs/hermes-run-adapter-contract.md +1079 -0
  102. package/vendor/agent-frontend-shell/docs/rfcs/turn-journal.md +195 -0
  103. package/vendor/agent-frontend-shell/docs/rfcs/webui-run-state-consistency-contract.md +157 -0
  104. package/vendor/agent-frontend-shell/docs/supervisor.md +280 -0
  105. package/vendor/agent-frontend-shell/docs/troubleshooting.md +132 -0
  106. package/vendor/agent-frontend-shell/docs/ui-ux/index.html +863 -0
  107. package/vendor/agent-frontend-shell/docs/ui-ux/two-stage-proposal.html +768 -0
  108. package/vendor/agent-frontend-shell/docs/why-hermes.md +489 -0
  109. package/vendor/agent-frontend-shell/docs/workspace-git.md +92 -0
  110. package/vendor/agent-frontend-shell/docs/wsl-autostart.md +126 -0
  111. package/vendor/agent-frontend-shell/eslint.runtime-guard.config.mjs +35 -0
  112. package/vendor/agent-frontend-shell/extensions/bitseek-design-system.md +330 -0
  113. package/vendor/agent-frontend-shell/extensions/branding/assets/apple-touch-icon.png +0 -0
  114. package/vendor/agent-frontend-shell/extensions/branding/assets/empty-logo.svg +739 -0
  115. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-192.png +0 -0
  116. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-32.png +0 -0
  117. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-512.png +0 -0
  118. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-512.svg +745 -0
  119. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon.ico +0 -0
  120. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon.svg +745 -0
  121. package/vendor/agent-frontend-shell/extensions/branding/assets/titlebar-icon-v2.svg +751 -0
  122. package/vendor/agent-frontend-shell/extensions/branding/assets/titlebar-icon-v3.svg +739 -0
  123. package/vendor/agent-frontend-shell/extensions/branding/assets/titlebar-icon.svg +745 -0
  124. package/vendor/agent-frontend-shell/extensions/branding/branding.js +112 -0
  125. package/vendor/agent-frontend-shell/extensions/branding/config.json +14 -0
  126. package/vendor/agent-frontend-shell/extensions/branding/manifest.json +53 -0
  127. package/vendor/agent-frontend-shell/extensions/index.js +67 -0
  128. package/vendor/agent-frontend-shell/extensions/loader/hermes-loader.js +77 -0
  129. package/vendor/agent-frontend-shell/extensions/manifest.json +16 -0
  130. package/vendor/agent-frontend-shell/extensions/pages/ai-teammates/page.css +333 -0
  131. package/vendor/agent-frontend-shell/extensions/pages/ai-teammates/page.js +487 -0
  132. package/vendor/agent-frontend-shell/extensions/pages/manifest.json +6 -0
  133. package/vendor/agent-frontend-shell/extensions/pages/registry.css +56 -0
  134. package/vendor/agent-frontend-shell/extensions/pages/registry.js +302 -0
  135. package/vendor/agent-frontend-shell/extensions/themes/bitseek/index.css +93 -0
  136. package/vendor/agent-frontend-shell/extensions/themes/bitseek/index.js +98 -0
  137. package/vendor/agent-frontend-shell/install.sh +63 -0
  138. package/vendor/agent-frontend-shell/mcp_server.py +567 -0
  139. package/vendor/agent-frontend-shell/package.json +12 -0
  140. package/vendor/agent-frontend-shell/pyproject.toml +56 -0
  141. package/vendor/agent-frontend-shell/pytest.ini +3 -0
  142. package/vendor/agent-frontend-shell/requirements.txt +5 -0
  143. package/vendor/agent-frontend-shell/server.py +624 -0
  144. package/vendor/agent-frontend-shell/start.ps1 +210 -0
  145. package/vendor/agent-frontend-shell/start.sh +65 -0
  146. package/vendor/agent-frontend-shell/static/apple-touch-icon.png +0 -0
  147. package/vendor/agent-frontend-shell/static/boot.js +1990 -0
  148. package/vendor/agent-frontend-shell/static/commands.js +1402 -0
  149. package/vendor/agent-frontend-shell/static/favicon-192.png +0 -0
  150. package/vendor/agent-frontend-shell/static/favicon-32.png +0 -0
  151. package/vendor/agent-frontend-shell/static/favicon-512.png +0 -0
  152. package/vendor/agent-frontend-shell/static/favicon-512.svg +18 -0
  153. package/vendor/agent-frontend-shell/static/favicon.ico +0 -0
  154. package/vendor/agent-frontend-shell/static/favicon.svg +20 -0
  155. package/vendor/agent-frontend-shell/static/i18n.js +15389 -0
  156. package/vendor/agent-frontend-shell/static/icons.js +92 -0
  157. package/vendor/agent-frontend-shell/static/index.html +1506 -0
  158. package/vendor/agent-frontend-shell/static/login.js +177 -0
  159. package/vendor/agent-frontend-shell/static/manifest.json +53 -0
  160. package/vendor/agent-frontend-shell/static/messages.js +3521 -0
  161. package/vendor/agent-frontend-shell/static/onboarding.js +800 -0
  162. package/vendor/agent-frontend-shell/static/panels.js +7995 -0
  163. package/vendor/agent-frontend-shell/static/pwa-startup.js +83 -0
  164. package/vendor/agent-frontend-shell/static/sessions.js +5165 -0
  165. package/vendor/agent-frontend-shell/static/style.css +4774 -0
  166. package/vendor/agent-frontend-shell/static/sw.js +173 -0
  167. package/vendor/agent-frontend-shell/static/terminal.js +632 -0
  168. package/vendor/agent-frontend-shell/static/ui.js +8997 -0
  169. package/vendor/agent-frontend-shell/static/vendor/js-yaml/4.1.0/js-yaml.min.js +2 -0
  170. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_AMS-Regular.ttf +0 -0
  171. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_AMS-Regular.woff +0 -0
  172. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  173. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  174. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  175. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  176. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  177. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  178. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  179. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  180. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  181. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  182. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  183. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  184. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  185. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Bold.ttf +0 -0
  186. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Bold.woff +0 -0
  187. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Bold.woff2 +0 -0
  188. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  189. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  190. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  191. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Italic.ttf +0 -0
  192. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Italic.woff +0 -0
  193. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Italic.woff2 +0 -0
  194. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Regular.ttf +0 -0
  195. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Regular.woff +0 -0
  196. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Regular.woff2 +0 -0
  197. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  198. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  199. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  200. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-Italic.ttf +0 -0
  201. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-Italic.woff +0 -0
  202. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-Italic.woff2 +0 -0
  203. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  204. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  205. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  206. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  207. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  208. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  209. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  210. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  211. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  212. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Script-Regular.ttf +0 -0
  213. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Script-Regular.woff +0 -0
  214. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Script-Regular.woff2 +0 -0
  215. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size1-Regular.ttf +0 -0
  216. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size1-Regular.woff +0 -0
  217. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  218. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size2-Regular.ttf +0 -0
  219. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size2-Regular.woff +0 -0
  220. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  221. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size3-Regular.ttf +0 -0
  222. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size3-Regular.woff +0 -0
  223. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  224. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size4-Regular.ttf +0 -0
  225. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size4-Regular.woff +0 -0
  226. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  227. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  228. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  229. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  230. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/katex.min.css +1 -0
  231. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/katex.min.js +1 -0
  232. package/vendor/agent-frontend-shell/static/vendor/smd.min.js +29 -0
  233. package/vendor/agent-frontend-shell/static/workspace.js +680 -0
@@ -0,0 +1,487 @@
1
+ /**
2
+ * AI Teammates Extension Page
3
+ * AI 同事 - 创建基于角色的 AI 同事,并进入他们的专属聊天
4
+ */
5
+ (function() {
6
+ 'use strict';
7
+
8
+ // ── i18n ──────────────────────────────────────────────────────────
9
+ if (typeof LOCALES !== 'undefined') {
10
+ function addTranslations(lang, translations) {
11
+ if (LOCALES[lang]) Object.assign(LOCALES[lang], translations);
12
+ }
13
+
14
+ addTranslations('en', {
15
+ tab_ai_teammates: 'AI Teammates',
16
+ ai_teammates_title: 'AI Teammates',
17
+ ai_teammates_subtitle: 'Create role-based AI teammates and enter their dedicated chats.',
18
+ ai_teammates_available_roles: 'Available roles',
19
+ ai_teammates_role_count: '{0} roles',
20
+ ai_teammates_refresh: 'Refresh',
21
+ ai_teammates_create: 'Create',
22
+ ai_teammates_loading: 'Loading...',
23
+ ai_teammates_empty: 'No AI teammates found.',
24
+ ai_teammates_error: 'Failed to load AI teammates: {0}',
25
+ ai_teammates_enter_chat: 'Enter Chat',
26
+ ai_teammates_create_title: 'Create AI Teammate',
27
+ ai_teammates_confirm_delete: 'Are you sure you want to delete this AI teammate?',
28
+ ai_teammates_profile_prefix: 'bitseek_',
29
+ });
30
+
31
+ addTranslations('zh', {
32
+ tab_ai_teammates: 'AI 同事',
33
+ ai_teammates_title: 'AI 同事',
34
+ ai_teammates_subtitle: '创建基于角色的 AI 同事,并进入他们的专属聊天。',
35
+ ai_teammates_available_roles: '可用角色',
36
+ ai_teammates_role_count: '{0} 个角色',
37
+ ai_teammates_refresh: '刷新',
38
+ ai_teammates_create: '创建',
39
+ ai_teammates_loading: '加载中...',
40
+ ai_teammates_empty: '暂未发现 AI 同事。',
41
+ ai_teammates_error: '加载 AI 同事失败:{0}',
42
+ ai_teammates_enter_chat: '进入聊天',
43
+ ai_teammates_create_title: '创建 AI 同事',
44
+ ai_teammates_confirm_delete: '确定要删除这个 AI 同事吗?',
45
+ ai_teammates_profile_prefix: 'bitseek_',
46
+ });
47
+
48
+ addTranslations('ja', {
49
+ tab_ai_teammates: 'AI同僚',
50
+ ai_teammates_title: 'AI同僚',
51
+ ai_teammates_subtitle: '役割ベースのAI同僚を作成し、専用チャットに入ります。',
52
+ ai_teammates_available_roles: '利用可能な役割',
53
+ ai_teammates_role_count: '{0}個の役割',
54
+ ai_teammates_refresh: '更新',
55
+ ai_teammates_create: '作成',
56
+ ai_teammates_loading: '読み込み中...',
57
+ ai_teammates_empty: 'AI同僚が見つかりません。',
58
+ ai_teammates_error: 'AI同僚の読み込みに失敗しました:{0}',
59
+ ai_teammates_enter_chat: 'チャットに入る',
60
+ ai_teammates_create_title: 'AI同僚を作成',
61
+ ai_teammates_confirm_delete: 'このAI同僚を削除してもよろしいですか?',
62
+ ai_teammates_profile_prefix: 'bitseek_',
63
+ });
64
+
65
+ addTranslations('ru', {
66
+ tab_ai_teammates: 'AI коллеги',
67
+ ai_teammates_title: 'AI коллеги',
68
+ ai_teammates_subtitle: 'Создавайте AI коллег на основе ролей и входите в их专属 чаты.',
69
+ ai_teammates_available_roles: 'Доступные роли',
70
+ ai_teammates_role_count: '{0} ролей',
71
+ ai_teammates_refresh: 'Обновить',
72
+ ai_teammates_create: 'Создать',
73
+ ai_teammates_loading: 'Загрузка...',
74
+ ai_teammates_empty: 'AI коллеги не найдены.',
75
+ ai_teammates_error: 'Не удалось загрузить AI коллег: {0}',
76
+ ai_teammates_enter_chat: 'Войти в чат',
77
+ ai_teammates_create_title: 'Создать AI коллегу',
78
+ ai_teammates_confirm_delete: 'Вы уверены, что хотите удалить этого AI коллегу?',
79
+ ai_teammates_profile_prefix: 'bitseek_',
80
+ });
81
+
82
+ addTranslations('es', {
83
+ tab_ai_teammates: 'Colegas AI',
84
+ ai_teammates_title: 'Colegas AI',
85
+ ai_teammates_subtitle: 'Crea colegas AI basados en roles y entra en sus chats dedicados.',
86
+ ai_teammates_available_roles: 'Roles disponibles',
87
+ ai_teammates_role_count: '{0} roles',
88
+ ai_teammates_refresh: 'Actualizar',
89
+ ai_teammates_create: 'Crear',
90
+ ai_teammates_loading: 'Cargando...',
91
+ ai_teammates_empty: 'No se encontraron colegas AI.',
92
+ ai_teammates_error: 'Error al cargar colegas AI: {0}',
93
+ ai_teammates_enter_chat: 'Entrar al chat',
94
+ ai_teammates_create_title: 'Crear colega AI',
95
+ ai_teammates_confirm_delete: '¿Estás seguro de que quieres eliminar este colega AI?',
96
+ ai_teammates_profile_prefix: 'bitseek_',
97
+ });
98
+
99
+ addTranslations('de', {
100
+ tab_ai_teammates: 'AI-Kollegen',
101
+ ai_teammates_title: 'AI-Kollegen',
102
+ ai_teammates_subtitle: 'Erstellen Sie rollenbasierte AI-Kollegen und betreten Sie deren dedizierte Chats.',
103
+ ai_teammates_available_roles: 'Verfügbare Rollen',
104
+ ai_teammates_role_count: '{0} Rollen',
105
+ ai_teammates_refresh: 'Aktualisieren',
106
+ ai_teammates_create: 'Erstellen',
107
+ ai_teammates_loading: 'Laden...',
108
+ ai_teammates_empty: 'Keine AI-Kollegen gefunden.',
109
+ ai_teammates_error: 'AI-Kollegen konnten nicht geladen werden: {0}',
110
+ ai_teammates_enter_chat: 'Chat beitreten',
111
+ ai_teammates_create_title: 'AI-Kollegen erstellen',
112
+ ai_teammates_confirm_delete: 'Sind Sie sicher, dass Sie diesen AI-Kollegen löschen möchten?',
113
+ ai_teammates_profile_prefix: 'bitseek_',
114
+ });
115
+
116
+ addTranslations('it', {
117
+ tab_ai_teammates: 'Colleghi AI',
118
+ ai_teammates_title: 'Colleghi AI',
119
+ ai_teammates_subtitle: 'Crea colleghi AI basati sui ruoli e accedi alle loro chat dedicate.',
120
+ ai_teammates_available_roles: 'Ruoli disponibili',
121
+ ai_teammates_role_count: '{0} ruoli',
122
+ ai_teammates_refresh: 'Aggiorna',
123
+ ai_teammates_create: 'Crea',
124
+ ai_teammates_loading: 'Caricamento...',
125
+ ai_teammates_empty: 'Nessun collega AI trovato.',
126
+ ai_teammates_error: 'Impossibile caricare i colleghi AI: {0}',
127
+ ai_teammates_enter_chat: 'Entra nella chat',
128
+ ai_teammates_create_title: 'Crea collega AI',
129
+ ai_teammates_confirm_delete: 'Sei sicuro di voler eliminare questo collega AI?',
130
+ ai_teammates_profile_prefix: 'bitseek_',
131
+ });
132
+ }
133
+
134
+ // ── state ──────────────────────────────────────────────────────────
135
+ var _bitseekRoles = []; // filtered bitseek_ profiles
136
+ var _isSwitching = false; // prevent multiple clicks during profile switch
137
+ var _groupedRoles = {}; // { category: [role, ...] }
138
+ var _categoryOrder = []; // sorted category names
139
+ var _isLoading = false;
140
+
141
+ // ── helpers ────────────────────────────────────────────────────────
142
+ function esc(s) {
143
+ if (typeof window.esc === 'function') return window.esc(s);
144
+ if (s == null) return '';
145
+ return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
146
+ }
147
+
148
+ function t(key) {
149
+ if (typeof window.t === 'function') {
150
+ // Pass all arguments after key for placeholder substitution
151
+ var args = Array.prototype.slice.call(arguments, 1);
152
+ return window.t.apply(null, [key].concat(args));
153
+ }
154
+ return key;
155
+ }
156
+
157
+ /**
158
+ * Parse a bitseek profile name into { category, displayName, initials }
159
+ * Pattern: bitseek_[category]_[displayName]
160
+ * e.g. bitseek_collaboration_dingtalk → { category: '协作办公', displayName: '钉钉助手' }
161
+ */
162
+ function parseBitseekName(name) {
163
+ var prefix = 'bitseek_';
164
+ if (!name || name.indexOf(prefix) !== 0) return null;
165
+ var rest = name.slice(prefix.length);
166
+ var parts = rest.split('_');
167
+ if (parts.length < 2) return null;
168
+
169
+ // The category is the first segment, everything after is the display name
170
+ // Categories may be in English (collaboration, marketing, sales) — we map them
171
+ var rawCategory = parts[0];
172
+ var rawDisplayName = parts.slice(1).join('_');
173
+
174
+ // Map English category keys to Chinese display names
175
+ var categoryMap = {
176
+ 'collaboration': '协作办公',
177
+ 'marketing': '营销增长',
178
+ 'sales': '销售营收',
179
+ 'support': '客户服务',
180
+ 'hr': '人力资源',
181
+ 'finance': '财务法务',
182
+ 'product': '产品设计',
183
+ 'tech': '技术研发',
184
+ 'operations': '运营管理',
185
+ 'data': '数据分析',
186
+ };
187
+
188
+ var category = categoryMap[rawCategory] || rawCategory;
189
+
190
+ // Convert raw display name to readable (snake_case → title case as fallback)
191
+ var displayName = rawDisplayName
192
+ .replace(/_/g, ' ')
193
+ .replace(/\b\w/g, function(c) { return c.toUpperCase(); });
194
+
195
+ // Generate initials from display name (first 2 chars, uppercase)
196
+ var initials = displayName.slice(0, 2).toUpperCase();
197
+
198
+ return {
199
+ category: category,
200
+ displayName: displayName,
201
+ initials: initials,
202
+ rawName: name,
203
+ };
204
+ }
205
+
206
+ /**
207
+ * Group roles by category and sort them
208
+ */
209
+ function groupRoles(roles) {
210
+ var grouped = {};
211
+ var order = [];
212
+
213
+ roles.forEach(function(role) {
214
+ var cat = role.category;
215
+ if (!grouped[cat]) {
216
+ grouped[cat] = [];
217
+ order.push(cat);
218
+ }
219
+ grouped[cat].push(role);
220
+ });
221
+
222
+ // Sort categories by number of roles (descending), then alphabetically
223
+ order.sort(function(a, b) {
224
+ return grouped[b].length - grouped[a].length || a.localeCompare(b);
225
+ });
226
+
227
+ return { grouped: grouped, order: order };
228
+ }
229
+
230
+ /**
231
+ * Build the abbreviation text (first 2 chars uppercase)
232
+ */
233
+ function getInitials(displayName) {
234
+ // For Chinese names, take first 2 characters
235
+ // For English names, take first letter of each word (up to 2)
236
+ var isChinese = /[一-鿿]/.test(displayName);
237
+ if (isChinese) {
238
+ return displayName.slice(0, 2);
239
+ }
240
+ var words = displayName.split(/\s+/);
241
+ if (words.length >= 2) {
242
+ return (words[0][0] + words[1][0]).toUpperCase();
243
+ }
244
+ return displayName.slice(0, 2).toUpperCase();
245
+ }
246
+
247
+ // ── data loading ───────────────────────────────────────────────────
248
+ async function loadAiTeammates() {
249
+ if (_isLoading) return;
250
+ _isLoading = true;
251
+
252
+ var mainBody = document.getElementById('aiTeammatesBody');
253
+ if (mainBody) {
254
+ mainBody.innerHTML = '<div class="ai-teammates-loading">' + esc(t('ai_teammates_loading')) + '</div>';
255
+ }
256
+
257
+ try {
258
+ var data = await api('/api/profiles');
259
+
260
+ // Filter profiles with bitseek_ prefix
261
+ _bitseekRoles = (data.profiles || [])
262
+ .map(function(p) {
263
+ var parsed = parseBitseekName(p.name);
264
+ if (!parsed) return null;
265
+ return {
266
+ name: p.name,
267
+ category: parsed.category,
268
+ displayName: parsed.displayName,
269
+ initials: getInitials(parsed.displayName),
270
+ description: p.description || '',
271
+ model: p.model || '',
272
+ provider: p.provider || '',
273
+ is_active: p.is_active,
274
+ rawProfile: p,
275
+ };
276
+ })
277
+ .filter(Boolean);
278
+
279
+ // Group by category
280
+ var result = groupRoles(_bitseekRoles);
281
+ _groupedRoles = result.grouped;
282
+ _categoryOrder = result.order;
283
+
284
+ renderMainContent();
285
+ } catch (e) {
286
+ if (mainBody) {
287
+ mainBody.innerHTML = '<div class="ai-teammates-error">' + esc(t('ai_teammates_error', e.message)) + '</div>';
288
+ }
289
+ console.error('[ai-teammates] Failed to load:', e);
290
+ } finally {
291
+ _isLoading = false;
292
+ }
293
+ }
294
+
295
+ // ── rendering ──────────────────────────────────────────────────────
296
+ function renderMainContent() {
297
+ // Registry creates id as 'main' + capitalize(name) = 'mainAi-teammates'
298
+ var mainView = document.getElementById('mainAi-teammates');
299
+ if (!mainView) return;
300
+
301
+ var totalCount = _bitseekRoles.length;
302
+
303
+ var html = '';
304
+
305
+ // ── page header ──
306
+ html += '<div class="at-page-header">';
307
+ html += ' <h1 class="at-page-title" data-i18n="ai_teammates_title">' + esc(t('ai_teammates_title')) + '</h1>';
308
+ html += ' <p class="at-page-subtitle" data-i18n="ai_teammates_subtitle">' + esc(t('ai_teammates_subtitle')) + '</p>';
309
+ html += '</div>';
310
+
311
+ // ── content card ──
312
+ html += '<div class="at-content-card">';
313
+
314
+ // ── card header ──
315
+ html += ' <div class="at-card-header">';
316
+ html += ' <div class="at-card-header-left">';
317
+ html += ' <span class="at-card-title" data-i18n="ai_teammates_title">' + esc(t('ai_teammates_title')) + '</span>';
318
+ html += ' <span class="at-card-count">' + esc(t('ai_teammates_role_count', totalCount)) + '</span>';
319
+ html += ' </div>';
320
+ html += ' <div class="at-card-header-right">';
321
+ html += ' <button class="at-btn at-btn-outline" id="atBtnRefresh" onclick="window._atRefresh()">';
322
+ html += ' <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>';
323
+ html += ' <span data-i18n="ai_teammates_refresh">' + esc(t('ai_teammates_refresh')) + '</span>';
324
+ html += ' </button>';
325
+ html += ' <button class="at-btn at-btn-primary" id="atBtnCreate" onclick="window._atCreate()" style="display:none">';
326
+ html += ' <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>';
327
+ html += ' <span data-i18n="ai_teammates_create">' + esc(t('ai_teammates_create')) + '</span>';
328
+ html += ' </button>';
329
+ html += ' </div>';
330
+ html += ' </div>';
331
+
332
+ // ── categories ──
333
+ if (_categoryOrder.length === 0) {
334
+ html += ' <div class="at-empty">';
335
+ html += ' <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="color:var(--muted);opacity:0.4">';
336
+ html += ' <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>';
337
+ html += ' <circle cx="9" cy="7" r="4"/>';
338
+ html += ' <path d="M23 21v-2a4 4 0 0 0-3-3.87"/>';
339
+ html += ' <path d="M16 3.13a4 4 0 0 1 0 7.75"/>';
340
+ html += ' </svg>';
341
+ html += ' <div class="at-empty-text">' + esc(t('ai_teammates_empty')) + '</div>';
342
+ html += ' </div>';
343
+ } else {
344
+ _categoryOrder.forEach(function(category) {
345
+ var roles = _groupedRoles[category];
346
+
347
+ html += '<div class="at-category">';
348
+ html += ' <div class="at-category-header">';
349
+ html += ' <span class="at-category-dot"></span>';
350
+ html += ' <span class="at-category-name">' + esc(category) + '</span>';
351
+ html += ' <span class="at-category-count">' + esc(t('ai_teammates_role_count', roles.length)) + '</span>';
352
+ html += ' </div>';
353
+ html += ' <div class="at-role-grid">';
354
+
355
+ roles.forEach(function(role) {
356
+ html += renderRoleCard(role);
357
+ });
358
+
359
+ html += ' </div>';
360
+ html += '</div>';
361
+ });
362
+ }
363
+
364
+ html += '</div>'; // at-content-card
365
+
366
+ mainView.innerHTML = html;
367
+
368
+ // Apply i18n
369
+ if (typeof applyLocaleToDOM === 'function') {
370
+ applyLocaleToDOM();
371
+ }
372
+ }
373
+
374
+ function renderRoleCard(role) {
375
+ var html = '';
376
+ html += '<div class="at-role-card" data-profile="' + esc(role.name) + '" onclick="window._atEnterChat(\'' + esc(role.name) + '\')">';
377
+ html += ' <div class="at-role-card-body">';
378
+ html += ' <div class="at-role-avatar">';
379
+ html += ' <span class="at-role-initials">' + esc(role.initials) + '</span>';
380
+ html += ' </div>';
381
+ html += ' <div class="at-role-info">';
382
+ html += ' <div class="at-role-name">' + esc(role.displayName) + '</div>';
383
+ html += ' <div class="at-role-desc">' + esc(role.description || role.rawProfile?.description || '') + '</div>';
384
+ html += ' </div>';
385
+ html += ' </div>';
386
+ html += ' <div class="at-role-arrow">';
387
+ html += ' <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>';
388
+ html += ' </div>';
389
+ html += '</div>';
390
+ return html;
391
+ }
392
+
393
+ // ── actions ────────────────────────────────────────────────────────
394
+ window._atRefresh = function() {
395
+ loadAiTeammates();
396
+ };
397
+
398
+ window._atCreate = function() {
399
+ // Switch to profiles panel for creation
400
+ if (typeof switchPanel === 'function') {
401
+ switchPanel('profiles');
402
+ }
403
+ // Try to open profile create form
404
+ if (typeof openProfileCreate === 'function') {
405
+ setTimeout(openProfileCreate, 100);
406
+ }
407
+ };
408
+
409
+ window._atEnterChat = function(profileName) {
410
+ // Prevent click during switching
411
+ if (_isSwitching) return;
412
+
413
+ var card = document.querySelector('[data-profile="' + profileName + '"]');
414
+ if (!card) return;
415
+
416
+ _isSwitching = true;
417
+
418
+ // Show loading state on all cards
419
+ document.querySelectorAll('.at-role-card').forEach(function(c) {
420
+ c.classList.add('at-role-card--loading');
421
+ });
422
+
423
+ // Show spinner on clicked card
424
+ var arrow = card.querySelector('.at-role-arrow');
425
+ if (arrow) {
426
+ arrow.innerHTML = '<svg class="at-spinner" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg>';
427
+ }
428
+
429
+ // Use the global switchToProfile function for proper profile switching
430
+ if (typeof switchToProfile === 'function') {
431
+ switchToProfile(profileName).then(function() {
432
+ // Reset switching state
433
+ _isSwitching = false;
434
+ // Navigate to chat page after switching
435
+ if (typeof switchPanel === 'function') {
436
+ switchPanel('chat');
437
+ }
438
+ }).catch(function() {
439
+ // Remove loading state on error
440
+ _isSwitching = false;
441
+ document.querySelectorAll('.at-role-card').forEach(function(c) {
442
+ c.classList.remove('at-role-card--loading');
443
+ });
444
+ });
445
+ } else {
446
+ console.error('[ai-teammates] switchToProfile function not available');
447
+ _isSwitching = false;
448
+ document.querySelectorAll('.at-role-card').forEach(function(c) {
449
+ c.classList.remove('at-role-card--loading');
450
+ });
451
+ }
452
+ };
453
+
454
+ // ── register panel ─────────────────────────────────────────────────
455
+ if (!window.hermes || typeof window.hermes.registerPanel !== 'function') {
456
+ console.warn('[ai-teammates] pages-registry.js not loaded');
457
+ return;
458
+ }
459
+
460
+ window.hermes.registerPanel({
461
+ name: 'ai-teammates',
462
+ label: 'AI Teammates',
463
+ labelKey: 'tab_ai_teammates',
464
+ tooltip: 'AI Teammates',
465
+ tooltipKey: 'tab_ai_teammates',
466
+ position: 'before-tasks',
467
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
468
+
469
+ // No sidebar panel — main content only
470
+ panel: '',
471
+
472
+ // Main content area
473
+ main: '<div id="aiTeammatesBody" class="ai-teammates-body">' +
474
+ '<div class="ai-teammates-loading">' + esc(t('ai_teammates_loading')) + '</div>' +
475
+ '</div>',
476
+
477
+ onActivate: function() {
478
+ if (typeof applyLocaleToDOM === 'function') applyLocaleToDOM();
479
+ loadAiTeammates();
480
+ },
481
+
482
+ onDeactivate: function() {
483
+ // cleanup if needed
484
+ }
485
+ });
486
+
487
+ })();
@@ -0,0 +1,6 @@
1
+ {
2
+ "pages": [
3
+ "/extensions/pages/ai-teammates/page.css",
4
+ "/extensions/pages/ai-teammates/page.js"
5
+ ]
6
+ }
@@ -0,0 +1,56 @@
1
+ /* Extension Pages Registry - Base CSS */
2
+
3
+ .ext-panel-view {
4
+ display: none;
5
+ flex: 1;
6
+ overflow: hidden;
7
+ flex-direction: column;
8
+ }
9
+
10
+ .ext-panel-view.active {
11
+ display: flex;
12
+ }
13
+
14
+ .ext-main-view {
15
+ flex: 1;
16
+ min-height: 0;
17
+ min-width: 0;
18
+ display: none;
19
+ flex-direction: column;
20
+ background: var(--bg);
21
+ }
22
+
23
+ .ext-main-view.active {
24
+ display: flex;
25
+ }
26
+
27
+ /* Coming soon placeholder */
28
+ .ext-coming-soon {
29
+ display: flex;
30
+ flex-direction: column;
31
+ align-items: center;
32
+ justify-content: center;
33
+ flex: 1;
34
+ padding: 32px;
35
+ text-align: center;
36
+ gap: 16px;
37
+ }
38
+
39
+ .ext-coming-soon-icon {
40
+ width: 64px;
41
+ height: 64px;
42
+ color: var(--muted);
43
+ opacity: 0.5;
44
+ }
45
+
46
+ .ext-coming-soon-title {
47
+ font-size: 18px;
48
+ font-weight: 600;
49
+ color: var(--text);
50
+ }
51
+
52
+ .ext-coming-soon-desc {
53
+ font-size: 14px;
54
+ color: var(--muted);
55
+ max-width: 320px;
56
+ }