@bitseek/hermes-webui 0.1.0-beta.0 → 0.1.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 (99) hide show
  1. package/package.json +2 -2
  2. package/vendor/agent-frontend-shell/.bitseek-source.json +2 -2
  3. package/vendor/agent-frontend-shell/CHANGELOG.md +178 -1
  4. package/vendor/agent-frontend-shell/CONTRIBUTORS.md +5 -5
  5. package/vendor/agent-frontend-shell/api/agent_health.py +134 -0
  6. package/vendor/agent-frontend-shell/api/config.py +145 -104
  7. package/vendor/agent-frontend-shell/api/gateway_chat.py +56 -12
  8. package/vendor/agent-frontend-shell/api/helpers.py +4 -2
  9. package/vendor/agent-frontend-shell/api/models.py +202 -20
  10. package/vendor/agent-frontend-shell/api/paths.py +77 -0
  11. package/vendor/agent-frontend-shell/api/plugins.py +185 -0
  12. package/vendor/agent-frontend-shell/api/profiles.py +95 -16
  13. package/vendor/agent-frontend-shell/api/routes.py +831 -30
  14. package/vendor/agent-frontend-shell/api/run_journal.py +1 -0
  15. package/vendor/agent-frontend-shell/api/state_sync.py +5 -4
  16. package/vendor/agent-frontend-shell/api/streaming.py +211 -56
  17. package/vendor/agent-frontend-shell/api/todo_state.py +122 -0
  18. package/vendor/agent-frontend-shell/api/updates.py +30 -3
  19. package/vendor/agent-frontend-shell/api/upload.py +251 -18
  20. package/vendor/agent-frontend-shell/api/workspace.py +323 -65
  21. package/vendor/agent-frontend-shell/bitseek_docs/BitSeek_Claw_Operation_Manual_EN.docx +0 -0
  22. package/vendor/agent-frontend-shell/bitseek_docs/BitSeek_Claw_Operation_Manual_ZH.docx +0 -0
  23. package/vendor/agent-frontend-shell/bitseek_docs/en/00-Installation.md +174 -0
  24. package/vendor/agent-frontend-shell/bitseek_docs/en/01-Overview.md +128 -0
  25. package/vendor/agent-frontend-shell/bitseek_docs/en/02-Page-Operations.md +461 -0
  26. package/vendor/agent-frontend-shell/bitseek_docs/en/README.md +61 -0
  27. package/vendor/agent-frontend-shell/bitseek_docs/en/images/ai-colleagues.png +0 -0
  28. package/vendor/agent-frontend-shell/bitseek_docs/en/images/chat-area.png +0 -0
  29. package/vendor/agent-frontend-shell/bitseek_docs/en/images/kanban.png +0 -0
  30. package/vendor/agent-frontend-shell/bitseek_docs/en/images/main-page.png +0 -0
  31. package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-notes.png +0 -0
  32. package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-overview.png +0 -0
  33. package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-profile.png +0 -0
  34. package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-soul.png +0 -0
  35. package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory.png +0 -0
  36. package/vendor/agent-frontend-shell/bitseek_docs/en/images/navigation-bar.png +0 -0
  37. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-appearance.png +0 -0
  38. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-conversation.png +0 -0
  39. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-overview.png +0 -0
  40. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-plugins.png +0 -0
  41. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-preferences.png +0 -0
  42. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-providers.png +0 -0
  43. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-system.png +0 -0
  44. package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings.png +0 -0
  45. package/vendor/agent-frontend-shell/bitseek_docs/en/images/sidebar.png +0 -0
  46. package/vendor/agent-frontend-shell/bitseek_docs/en/images/skills.png +0 -0
  47. package/vendor/agent-frontend-shell/bitseek_docs/en/images/tasks.png +0 -0
  48. package/vendor/agent-frontend-shell/bitseek_docs/en/images/workspace-panel.png +0 -0
  49. package/vendor/agent-frontend-shell/bitseek_docs/md_to_docx.py +351 -0
  50. package/vendor/agent-frontend-shell/bitseek_docs/zh/00-/345/256/211/350/243/205/345/220/257/345/212/250.md +174 -0
  51. package/vendor/agent-frontend-shell/bitseek_docs/zh/01-/346/225/264/344/275/223/346/246/202/350/247/210.md +128 -0
  52. package/vendor/agent-frontend-shell/bitseek_docs/zh/02-/351/241/265/351/235/242/346/223/215/344/275/234.md +463 -0
  53. package/vendor/agent-frontend-shell/bitseek_docs/zh/README.md +61 -0
  54. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/ai-colleagues.png +0 -0
  55. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/chat-area.png +0 -0
  56. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/kanban.png +0 -0
  57. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/main-page.png +0 -0
  58. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-notes.png +0 -0
  59. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-overview.png +0 -0
  60. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-profile.png +0 -0
  61. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-soul.png +0 -0
  62. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory.png +0 -0
  63. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/navigation-bar.png +0 -0
  64. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-appearance.png +0 -0
  65. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-conversation.png +0 -0
  66. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-overview.png +0 -0
  67. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-plugins.png +0 -0
  68. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-preferences.png +0 -0
  69. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-providers.png +0 -0
  70. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-system.png +0 -0
  71. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings.png +0 -0
  72. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/sidebar.png +0 -0
  73. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/skills.png +0 -0
  74. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/tasks.png +0 -0
  75. package/vendor/agent-frontend-shell/bitseek_docs/zh/images/workspace-panel.png +0 -0
  76. package/vendor/agent-frontend-shell/build-release.sh +62 -0
  77. package/vendor/agent-frontend-shell/ctl.sh +1 -0
  78. package/vendor/agent-frontend-shell/docker-compose.local.yml +33 -0
  79. package/vendor/agent-frontend-shell/docker-compose.yml +8 -0
  80. package/vendor/agent-frontend-shell/docker_init.bash +1 -0
  81. package/vendor/agent-frontend-shell/docs/rfcs/hermes-run-adapter-contract.md +74 -15
  82. package/vendor/agent-frontend-shell/extensions/common/index.css +6 -0
  83. package/vendor/agent-frontend-shell/extensions/manifest.json +6 -0
  84. package/vendor/agent-frontend-shell/extensions/pages/ai-teammates/page.js +60 -14
  85. package/vendor/agent-frontend-shell/readme-simple.md +103 -0
  86. package/vendor/agent-frontend-shell/requirements.txt +5 -0
  87. package/vendor/agent-frontend-shell/server.py +7 -0
  88. package/vendor/agent-frontend-shell/static/boot.js +53 -1
  89. package/vendor/agent-frontend-shell/static/commands.js +20 -10
  90. package/vendor/agent-frontend-shell/static/i18n.js +1142 -1016
  91. package/vendor/agent-frontend-shell/static/index.html +13 -3
  92. package/vendor/agent-frontend-shell/static/messages.js +48 -3
  93. package/vendor/agent-frontend-shell/static/panels.js +199 -30
  94. package/vendor/agent-frontend-shell/static/sessions.js +249 -39
  95. package/vendor/agent-frontend-shell/static/style.css +46 -2
  96. package/vendor/agent-frontend-shell/static/ui.js +323 -79
  97. package/vendor/agent-frontend-shell/static/workspace.js +185 -7
  98. package/vendor/agent-frontend-shell/README-CUSTOM.md +0 -76
  99. package/vendor/agent-frontend-shell/docker-compose.custom.yml +0 -26
@@ -152,20 +152,13 @@ def _resolve_base_hermes_home() -> Path:
152
152
 
153
153
  # Platform default. On Windows this includes the #2905 migration-safety
154
154
  # fallback (prefer the populated legacy %USERPROFILE%\.hermes over an
155
- # empty %LOCALAPPDATA%\hermes). Delegate to config so the base-home
156
- # resolution used for the active-profile pointer can never drift from the
157
- # one config.STATE_DIR is derived from.
158
- try:
159
- from api.config import _platform_default_hermes_home
160
- return _platform_default_hermes_home()
161
- except ImportError:
162
- # Defensive: never let a config import problem break profile resolution.
163
- # Scoped to ImportError so a real bug inside the helper still surfaces.
164
- if os.name == 'nt':
165
- local_app_data = os.getenv('LOCALAPPDATA', '').strip()
166
- if local_app_data:
167
- return Path(local_app_data) / 'hermes'
168
- return Path.home() / '.hermes'
155
+ # empty %LOCALAPPDATA%\hermes). Import the shared path helper directly
156
+ # instead of importing api.config here; api.config imports profiles during
157
+ # startup, so going through config creates a partial-module circular import
158
+ # when api.profiles is imported first.
159
+ from api.paths import _platform_default_hermes_home
160
+
161
+ return _platform_default_hermes_home()
169
162
 
170
163
  _DEFAULT_HERMES_HOME = _resolve_base_hermes_home()
171
164
 
@@ -898,6 +891,7 @@ def switch_profile(name: str, *, process_wide: bool = True) -> dict:
898
891
  raise ValueError(f"Profile '{name}' does not exist.")
899
892
 
900
893
  with _profile_lock:
894
+ _SKILLS_STATS_CACHE.clear()
901
895
  if process_wide:
902
896
  global _active_profile
903
897
  _active_profile = name
@@ -996,6 +990,81 @@ def switch_profile(name: str, *, process_wide: bool = True) -> dict:
996
990
  }
997
991
 
998
992
 
993
+ _SKILLS_STATS_CACHE: dict[Path, tuple[int, int, float]] = {}
994
+ _SKILLS_STATS_CACHE_TTL = 8.0 # seconds
995
+
996
+
997
+ def _get_profile_skills_stats(profile_dir: Path) -> tuple[int, int]:
998
+ """Calculate (enabled_count, compatible_count) for a profile directory."""
999
+ import time
1000
+ profile_dir = Path(profile_dir).resolve()
1001
+ now = time.time()
1002
+ # Read via .get() (not membership-check + index) so a concurrent
1003
+ # _SKILLS_STATS_CACHE.clear() on another thread can't raise KeyError
1004
+ # between the `in` test and the lookup.
1005
+ cached = _SKILLS_STATS_CACHE.get(profile_dir)
1006
+ if cached is not None:
1007
+ enabled, compat, expiry = cached
1008
+ if now < expiry:
1009
+ return enabled, compat
1010
+
1011
+ skills_dir = profile_dir / "skills"
1012
+ if not skills_dir.is_dir():
1013
+ res = (0, 0)
1014
+ _SKILLS_STATS_CACHE[profile_dir] = (res[0], res[1], now + _SKILLS_STATS_CACHE_TTL)
1015
+ return res
1016
+
1017
+ disabled = set()
1018
+ config_path = profile_dir / "config.yaml"
1019
+ if config_path.exists():
1020
+ try:
1021
+ import yaml as _yaml
1022
+ cfg = _yaml.safe_load(config_path.read_text(encoding="utf-8"))
1023
+ if isinstance(cfg, dict):
1024
+ skills_cfg = cfg.get("skills")
1025
+ if isinstance(skills_cfg, dict):
1026
+ # Align with get_disabled_skill_names(platform="webui") behavior:
1027
+ platform_disabled = (skills_cfg.get("platform_disabled") or {}).get("webui")
1028
+ if platform_disabled is not None:
1029
+ disabled_val = platform_disabled
1030
+ else:
1031
+ disabled_val = skills_cfg.get("disabled")
1032
+
1033
+ if disabled_val is not None:
1034
+ if isinstance(disabled_val, str):
1035
+ disabled_val = [disabled_val]
1036
+ disabled = {str(v).strip() for v in disabled_val if str(v).strip()}
1037
+ except Exception:
1038
+ pass
1039
+
1040
+ from agent.skill_utils import iter_skill_index_files, parse_frontmatter, skill_matches_platform
1041
+
1042
+ seen_names = set()
1043
+ enabled_count = 0
1044
+ compatible_count = 0
1045
+
1046
+ for skill_md in iter_skill_index_files(skills_dir, "SKILL.md"):
1047
+ try:
1048
+ content = skill_md.read_text(encoding="utf-8")[:4000]
1049
+ frontmatter, _ = parse_frontmatter(content)
1050
+ if not skill_matches_platform(frontmatter):
1051
+ continue
1052
+ name = frontmatter.get("name", skill_md.parent.name)[:64]
1053
+ if name in seen_names:
1054
+ continue
1055
+ seen_names.add(name)
1056
+
1057
+ compatible_count += 1
1058
+ if name not in disabled:
1059
+ enabled_count += 1
1060
+ except Exception:
1061
+ pass
1062
+
1063
+ res = (enabled_count, compatible_count)
1064
+ _SKILLS_STATS_CACHE[profile_dir] = (res[0], res[1], now + _SKILLS_STATS_CACHE_TTL)
1065
+ return res
1066
+
1067
+
999
1068
  def list_profiles_api() -> list:
1000
1069
  """List all profiles with metadata, serialized for JSON response."""
1001
1070
  try:
@@ -1008,6 +1077,7 @@ def list_profiles_api() -> list:
1008
1077
  active = get_active_profile_name()
1009
1078
  result = []
1010
1079
  for p in infos:
1080
+ enabled_count, total_count = _get_profile_skills_stats(p.path)
1011
1081
  result.append({
1012
1082
  'name': p.name,
1013
1083
  'path': str(p.path),
@@ -1017,13 +1087,16 @@ def list_profiles_api() -> list:
1017
1087
  'model': p.model,
1018
1088
  'provider': p.provider,
1019
1089
  'has_env': p.has_env,
1020
- 'skill_count': p.skill_count,
1090
+ 'skill_count': enabled_count,
1091
+ 'enabled_skills': enabled_count,
1092
+ 'total_skills': total_count,
1021
1093
  })
1022
1094
  return result
1023
1095
 
1024
1096
 
1025
1097
  def _default_profile_dict() -> dict:
1026
1098
  """Fallback profile dict when hermes_cli is not importable."""
1099
+ enabled_count, compatible_count = _get_profile_skills_stats(_DEFAULT_HERMES_HOME)
1027
1100
  return {
1028
1101
  'name': 'default',
1029
1102
  'path': str(_DEFAULT_HERMES_HOME),
@@ -1033,7 +1106,9 @@ def _default_profile_dict() -> dict:
1033
1106
  'model': None,
1034
1107
  'provider': None,
1035
1108
  'has_env': (_DEFAULT_HERMES_HOME / '.env').exists(),
1036
- 'skill_count': 0,
1109
+ 'skill_count': enabled_count,
1110
+ 'enabled_skills': enabled_count,
1111
+ 'total_skills': compatible_count,
1037
1112
  }
1038
1113
 
1039
1114
 
@@ -1444,6 +1519,7 @@ def create_profile_api(name: str, clone_from: str = None,
1444
1519
 
1445
1520
  # Invalidate cached root-profile-name lookup; create_profile may have added
1446
1521
  # a new profile that flips is_default semantics on the agent side (#1612).
1522
+ _SKILLS_STATS_CACHE.clear()
1447
1523
  _invalidate_root_profile_cache()
1448
1524
 
1449
1525
  # Find and return the newly created profile info.
@@ -1463,6 +1539,8 @@ def create_profile_api(name: str, clone_from: str = None,
1463
1539
  'provider': None,
1464
1540
  'has_env': (profile_path / '.env').exists(),
1465
1541
  'skill_count': 0,
1542
+ 'enabled_skills': 0,
1543
+ 'total_skills': 0,
1466
1544
  }
1467
1545
 
1468
1546
 
@@ -1495,5 +1573,6 @@ def delete_profile_api(name: str) -> dict:
1495
1573
  raise ValueError(f"Profile '{name}' does not exist.")
1496
1574
 
1497
1575
  # Drop cached root-profile-name lookup — list_profiles_api() shape changed.
1576
+ _SKILLS_STATS_CACHE.clear()
1498
1577
  _invalidate_root_profile_cache()
1499
1578
  return {'ok': True, 'name': name}