claude-mpm 5.0.9__py3-none-any.whl → 5.4.41__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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/{PM_INSTRUCTIONS_TEACH.md → CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md} +721 -41
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +468 -468
- claude_mpm/agents/WORKFLOW.md +5 -254
- claude_mpm/agents/agent_loader.py +13 -44
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/frontmatter_validator.py +70 -2
- claude_mpm/agents/templates/circuit-breakers.md +431 -45
- claude_mpm/cli/__init__.py +0 -1
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/agent_state_manager.py +18 -27
- claude_mpm/cli/commands/agents.py +175 -37
- claude_mpm/cli/commands/auto_configure.py +723 -236
- claude_mpm/cli/commands/config.py +88 -2
- claude_mpm/cli/commands/configure.py +1262 -157
- claude_mpm/cli/commands/configure_agent_display.py +25 -6
- claude_mpm/cli/commands/mpm_init/core.py +225 -46
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
- claude_mpm/cli/commands/postmortem.py +1 -1
- claude_mpm/cli/commands/profile.py +277 -0
- claude_mpm/cli/commands/skills.py +214 -189
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +21 -3
- claude_mpm/cli/interactive/agent_wizard.py +85 -10
- claude_mpm/cli/parsers/agents_parser.py +54 -9
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +12 -0
- claude_mpm/cli/parsers/config_parser.py +153 -83
- claude_mpm/cli/parsers/profile_parser.py +148 -0
- claude_mpm/cli/parsers/skills_parser.py +3 -2
- claude_mpm/cli/startup.py +879 -149
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +9 -22
- claude_mpm/commands/mpm-help.md +5 -287
- claude_mpm/commands/mpm-init.md +81 -507
- claude_mpm/commands/mpm-monitor.md +15 -402
- claude_mpm/commands/mpm-organize.md +120 -0
- claude_mpm/commands/mpm-postmortem.md +6 -108
- claude_mpm/commands/mpm-session-resume.md +12 -363
- claude_mpm/commands/mpm-status.md +5 -69
- claude_mpm/commands/mpm-ticket-view.md +52 -495
- claude_mpm/commands/mpm-version.md +5 -107
- claude_mpm/config/agent_sources.py +27 -0
- claude_mpm/core/config.py +2 -4
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/logger.py +13 -0
- claude_mpm/core/optimized_startup.py +59 -0
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/socketio_pool.py +3 -3
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
- claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/init.py +63 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +3 -3
- claude_mpm/scripts/claude-hook-handler.sh +58 -18
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/cache_git_manager.py +6 -6
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -5
- claude_mpm/services/agents/deployment/agent_template_builder.py +5 -3
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +320 -29
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +546 -68
- claude_mpm/services/agents/git_source_manager.py +36 -2
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
- claude_mpm/services/agents/sources/git_source_sync_service.py +13 -6
- claude_mpm/services/agents/startup_sync.py +22 -2
- claude_mpm/services/agents/toolchain_detector.py +10 -6
- claude_mpm/services/analysis/__init__.py +11 -1
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/command_deployment_service.py +81 -10
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/git/git_operations_service.py +101 -16
- claude_mpm/services/monitor/daemon.py +9 -2
- claude_mpm/services/monitor/daemon_manager.py +39 -3
- claude_mpm/services/monitor/management/lifecycle.py +8 -1
- claude_mpm/services/monitor/server.py +698 -22
- claude_mpm/services/pm_skills_deployer.py +676 -0
- claude_mpm/services/profile_manager.py +331 -0
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/skills/__init__.py +3 -0
- claude_mpm/services/skills/git_skill_source_manager.py +130 -2
- claude_mpm/services/skills/selective_skill_deployer.py +704 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_deployer.py +126 -9
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/server/core.py +386 -108
- claude_mpm/services/version_control/git_operations.py +103 -0
- claude_mpm/skills/skill_manager.py +92 -3
- claude_mpm/utils/agent_dependency_loader.py +14 -2
- claude_mpm/utils/agent_filters.py +17 -44
- claude_mpm/utils/gitignore.py +3 -0
- claude_mpm/utils/migration.py +4 -4
- claude_mpm/utils/robust_installer.py +47 -3
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +57 -87
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +160 -211
- claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -480
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent_loader.py +0 -601
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
- claude_mpm/commands/mpm-agents-detect.md +0 -177
- claude_mpm/commands/mpm-agents-list.md +0 -131
- claude_mpm/commands/mpm-agents-recommend.md +0 -223
- claude_mpm/commands/mpm-config-view.md +0 -150
- claude_mpm/commands/mpm-ticket-organize.md +0 -304
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1914
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/socket-client.js +0 -1474
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm-5.0.9.dist-info/entry_points.txt +0 -10
- claude_mpm-5.0.9.dist-info/licenses/LICENSE +0 -21
- /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
|
@@ -5,6 +5,7 @@ This module handles:
|
|
|
5
5
|
2. Output style extraction from framework instructions
|
|
6
6
|
3. One-time deployment to Claude Code >= 1.0.83 at startup
|
|
7
7
|
4. Fallback injection for older versions
|
|
8
|
+
5. Support for multiple output styles (professional and teaching modes)
|
|
8
9
|
|
|
9
10
|
The output style is set once at startup and not monitored or enforced after that.
|
|
10
11
|
Users can change it if they want, and the system will respect their choice.
|
|
@@ -14,7 +15,7 @@ import json
|
|
|
14
15
|
import re
|
|
15
16
|
import subprocess
|
|
16
17
|
from pathlib import Path
|
|
17
|
-
from typing import Dict, Optional
|
|
18
|
+
from typing import Any, Dict, Literal, Optional, TypedDict, cast
|
|
18
19
|
|
|
19
20
|
from ..utils.imports import safe_import
|
|
20
21
|
|
|
@@ -25,22 +26,56 @@ get_logger = safe_import("claude_mpm.core.logger", "core.logger", ["get_logger"]
|
|
|
25
26
|
_CACHED_CLAUDE_VERSION: Optional[str] = None
|
|
26
27
|
_VERSION_DETECTED: bool = False
|
|
27
28
|
|
|
29
|
+
# Output style types
|
|
30
|
+
OutputStyleType = Literal["professional", "teaching"]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class StyleConfig(TypedDict):
|
|
34
|
+
"""Configuration for an output style."""
|
|
35
|
+
|
|
36
|
+
source: Path
|
|
37
|
+
target: Path
|
|
38
|
+
name: str
|
|
39
|
+
|
|
28
40
|
|
|
29
41
|
class OutputStyleManager:
|
|
30
|
-
"""Manages output style deployment and version-based handling.
|
|
42
|
+
"""Manages output style deployment and version-based handling.
|
|
43
|
+
|
|
44
|
+
Supports two output styles:
|
|
45
|
+
- professional: Default Claude MPM style (claude-mpm.md)
|
|
46
|
+
- teaching: Adaptive teaching mode (claude-mpm-teach.md)
|
|
47
|
+
"""
|
|
31
48
|
|
|
32
|
-
def __init__(self):
|
|
49
|
+
def __init__(self) -> None:
|
|
33
50
|
"""Initialize the output style manager."""
|
|
34
|
-
self.logger = get_logger("output_style_manager")
|
|
51
|
+
self.logger = get_logger("output_style_manager") # type: ignore[misc]
|
|
35
52
|
self.claude_version = self._detect_claude_version()
|
|
36
|
-
|
|
37
|
-
|
|
53
|
+
|
|
54
|
+
# Deploy to ~/.claude/styles/ directory (NOT output-styles/)
|
|
55
|
+
self.output_style_dir = Path.home() / ".claude" / "styles"
|
|
38
56
|
self.settings_file = Path.home() / ".claude" / "settings.json"
|
|
39
57
|
|
|
40
|
-
#
|
|
41
|
-
self.
|
|
42
|
-
|
|
43
|
-
|
|
58
|
+
# Style definitions
|
|
59
|
+
self.styles: Dict[str, StyleConfig] = {
|
|
60
|
+
"professional": StyleConfig(
|
|
61
|
+
source=Path(__file__).parent.parent
|
|
62
|
+
/ "agents"
|
|
63
|
+
/ "CLAUDE_MPM_OUTPUT_STYLE.md",
|
|
64
|
+
target=self.output_style_dir / "claude-mpm.md",
|
|
65
|
+
name="claude-mpm",
|
|
66
|
+
),
|
|
67
|
+
"teaching": StyleConfig(
|
|
68
|
+
source=Path(__file__).parent.parent
|
|
69
|
+
/ "agents"
|
|
70
|
+
/ "CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md",
|
|
71
|
+
target=self.output_style_dir / "claude-mpm-teach.md",
|
|
72
|
+
name="claude-mpm-teach",
|
|
73
|
+
),
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Default style path (for backward compatibility)
|
|
77
|
+
self.output_style_path = self.styles["professional"]["target"]
|
|
78
|
+
self.mpm_output_style_path = self.styles["professional"]["source"]
|
|
44
79
|
|
|
45
80
|
def _detect_claude_version(self) -> Optional[str]:
|
|
46
81
|
"""
|
|
@@ -158,56 +193,77 @@ class OutputStyleManager:
|
|
|
158
193
|
"""
|
|
159
194
|
return not self.supports_output_styles()
|
|
160
195
|
|
|
161
|
-
def extract_output_style_content(
|
|
196
|
+
def extract_output_style_content(
|
|
197
|
+
self, framework_loader: Any = None, style: OutputStyleType = "professional"
|
|
198
|
+
) -> str:
|
|
162
199
|
"""
|
|
163
|
-
Read output style content from
|
|
200
|
+
Read output style content from style source file.
|
|
164
201
|
|
|
165
202
|
Args:
|
|
166
203
|
framework_loader: Optional framework loader (kept for compatibility, not used)
|
|
204
|
+
style: Style type to extract ("professional" or "teaching")
|
|
167
205
|
|
|
168
206
|
Returns:
|
|
169
207
|
Complete output style content from file
|
|
170
208
|
"""
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
209
|
+
style_config = self.styles[style]
|
|
210
|
+
source_path = style_config["source"]
|
|
211
|
+
|
|
212
|
+
if source_path.exists():
|
|
213
|
+
content = source_path.read_text()
|
|
214
|
+
self.logger.info(
|
|
215
|
+
f"Read {style} style from {source_path.name} ({len(content)} chars)"
|
|
216
|
+
)
|
|
175
217
|
return content
|
|
218
|
+
|
|
176
219
|
# Fallback error
|
|
177
|
-
error_msg = f"
|
|
220
|
+
error_msg = f"{style} style not found at {source_path}"
|
|
178
221
|
self.logger.error(error_msg)
|
|
179
222
|
raise FileNotFoundError(error_msg)
|
|
180
223
|
|
|
181
|
-
def save_output_style(
|
|
224
|
+
def save_output_style(
|
|
225
|
+
self, content: str, style: OutputStyleType = "professional"
|
|
226
|
+
) -> Path:
|
|
182
227
|
"""
|
|
183
|
-
Save output style content to
|
|
228
|
+
Save output style content to source file.
|
|
184
229
|
|
|
185
230
|
Args:
|
|
186
231
|
content: The formatted output style content
|
|
232
|
+
style: Style type to save ("professional" or "teaching")
|
|
187
233
|
|
|
188
234
|
Returns:
|
|
189
235
|
Path to the saved file
|
|
190
236
|
"""
|
|
191
237
|
try:
|
|
238
|
+
style_config = self.styles[style]
|
|
239
|
+
source_path = style_config["source"]
|
|
240
|
+
|
|
192
241
|
# Ensure the parent directory exists
|
|
193
|
-
|
|
242
|
+
source_path.parent.mkdir(parents=True, exist_ok=True)
|
|
194
243
|
|
|
195
244
|
# Write the content
|
|
196
|
-
|
|
197
|
-
self.logger.info(f"Saved
|
|
245
|
+
source_path.write_text(content, encoding="utf-8")
|
|
246
|
+
self.logger.info(f"Saved {style} style to {source_path}")
|
|
198
247
|
|
|
199
|
-
return
|
|
248
|
+
return source_path
|
|
200
249
|
except Exception as e:
|
|
201
|
-
self.logger.error(f"Failed to save
|
|
250
|
+
self.logger.error(f"Failed to save {style} style: {e}")
|
|
202
251
|
raise
|
|
203
252
|
|
|
204
|
-
def deploy_output_style(
|
|
253
|
+
def deploy_output_style(
|
|
254
|
+
self,
|
|
255
|
+
content: Optional[str] = None,
|
|
256
|
+
style: OutputStyleType = "professional",
|
|
257
|
+
activate: bool = True,
|
|
258
|
+
) -> bool:
|
|
205
259
|
"""
|
|
206
260
|
Deploy output style to Claude Code if version >= 1.0.83.
|
|
207
|
-
Deploys the style file and activates it
|
|
261
|
+
Deploys the style file and optionally activates it.
|
|
208
262
|
|
|
209
263
|
Args:
|
|
210
|
-
content: The output style content to deploy
|
|
264
|
+
content: The output style content to deploy (if None, reads from source)
|
|
265
|
+
style: Style type to deploy ("professional" or "teaching")
|
|
266
|
+
activate: Whether to activate the style after deployment
|
|
211
267
|
|
|
212
268
|
Returns:
|
|
213
269
|
True if deployed successfully, False otherwise
|
|
@@ -219,26 +275,37 @@ class OutputStyleManager:
|
|
|
219
275
|
return False
|
|
220
276
|
|
|
221
277
|
try:
|
|
222
|
-
|
|
278
|
+
style_config = self.styles[style]
|
|
279
|
+
target_path = style_config["target"]
|
|
280
|
+
style_name = style_config["name"]
|
|
281
|
+
|
|
282
|
+
# If content not provided, read from source
|
|
283
|
+
if content is None:
|
|
284
|
+
content = self.extract_output_style_content(style=style)
|
|
285
|
+
|
|
286
|
+
# Ensure styles directory exists
|
|
223
287
|
self.output_style_dir.mkdir(parents=True, exist_ok=True)
|
|
224
288
|
|
|
225
289
|
# Write the output style file
|
|
226
|
-
|
|
227
|
-
self.logger.info(f"Deployed
|
|
290
|
+
target_path.write_text(content, encoding="utf-8")
|
|
291
|
+
self.logger.info(f"Deployed {style} style to {target_path}")
|
|
228
292
|
|
|
229
|
-
# Activate the
|
|
230
|
-
|
|
293
|
+
# Activate the style if requested
|
|
294
|
+
if activate:
|
|
295
|
+
self._activate_output_style(style_name)
|
|
231
296
|
|
|
232
297
|
return True
|
|
233
298
|
|
|
234
299
|
except Exception as e:
|
|
235
|
-
self.logger.error(f"Failed to deploy
|
|
300
|
+
self.logger.error(f"Failed to deploy {style} style: {e}")
|
|
236
301
|
return False
|
|
237
302
|
|
|
238
|
-
def _activate_output_style(self) -> bool:
|
|
303
|
+
def _activate_output_style(self, style_name: str = "claude-mpm") -> bool:
|
|
239
304
|
"""
|
|
240
|
-
Update Claude Code settings to activate
|
|
241
|
-
|
|
305
|
+
Update Claude Code settings to activate a specific output style.
|
|
306
|
+
|
|
307
|
+
Args:
|
|
308
|
+
style_name: Name of the style to activate (e.g., "claude-mpm", "claude-mpm-teach")
|
|
242
309
|
|
|
243
310
|
Returns:
|
|
244
311
|
True if activated successfully, False otherwise
|
|
@@ -257,9 +324,9 @@ class OutputStyleManager:
|
|
|
257
324
|
# Check current active style
|
|
258
325
|
current_style = settings.get("activeOutputStyle")
|
|
259
326
|
|
|
260
|
-
# Update active output style
|
|
261
|
-
if current_style !=
|
|
262
|
-
settings["activeOutputStyle"] =
|
|
327
|
+
# Update active output style if different
|
|
328
|
+
if current_style != style_name:
|
|
329
|
+
settings["activeOutputStyle"] = style_name
|
|
263
330
|
|
|
264
331
|
# Ensure settings directory exists
|
|
265
332
|
self.settings_file.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -270,10 +337,10 @@ class OutputStyleManager:
|
|
|
270
337
|
)
|
|
271
338
|
|
|
272
339
|
self.logger.info(
|
|
273
|
-
f"✅ Activated
|
|
340
|
+
f"✅ Activated {style_name} output style (was: {current_style or 'none'})"
|
|
274
341
|
)
|
|
275
342
|
else:
|
|
276
|
-
self.logger.debug("
|
|
343
|
+
self.logger.debug(f"{style_name} output style already active")
|
|
277
344
|
|
|
278
345
|
return True
|
|
279
346
|
|
|
@@ -319,7 +386,9 @@ class OutputStyleManager:
|
|
|
319
386
|
|
|
320
387
|
return status
|
|
321
388
|
|
|
322
|
-
def get_injectable_content(
|
|
389
|
+
def get_injectable_content(
|
|
390
|
+
self, framework_loader: Any = None, style: OutputStyleType = "professional"
|
|
391
|
+
) -> str:
|
|
323
392
|
"""
|
|
324
393
|
Get output style content for injection into instructions (for Claude < 1.0.83).
|
|
325
394
|
|
|
@@ -328,12 +397,13 @@ class OutputStyleManager:
|
|
|
328
397
|
|
|
329
398
|
Args:
|
|
330
399
|
framework_loader: Optional FrameworkLoader instance to reuse loaded content
|
|
400
|
+
style: Style type to extract ("professional" or "teaching")
|
|
331
401
|
|
|
332
402
|
Returns:
|
|
333
403
|
Simplified output style content for injection
|
|
334
404
|
"""
|
|
335
405
|
# Extract the same content but without YAML frontmatter
|
|
336
|
-
full_content = self.extract_output_style_content(framework_loader)
|
|
406
|
+
full_content = self.extract_output_style_content(framework_loader, style=style)
|
|
337
407
|
|
|
338
408
|
# Remove YAML frontmatter
|
|
339
409
|
lines = full_content.split("\n")
|
|
@@ -351,3 +421,63 @@ class OutputStyleManager:
|
|
|
351
421
|
|
|
352
422
|
# If no frontmatter found, return as-is
|
|
353
423
|
return full_content
|
|
424
|
+
|
|
425
|
+
def deploy_all_styles(self, activate_default: bool = True) -> Dict[str, bool]:
|
|
426
|
+
"""
|
|
427
|
+
Deploy all available output styles to Claude Code.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
activate_default: Whether to activate the professional style after deployment
|
|
431
|
+
|
|
432
|
+
Returns:
|
|
433
|
+
Dictionary mapping style names to deployment success status
|
|
434
|
+
"""
|
|
435
|
+
results: Dict[str, bool] = {}
|
|
436
|
+
|
|
437
|
+
for style_type_key in self.styles:
|
|
438
|
+
# Deploy without activation
|
|
439
|
+
# Cast is safe because we know self.styles keys are OutputStyleType
|
|
440
|
+
style_type = cast("OutputStyleType", style_type_key)
|
|
441
|
+
success = self.deploy_output_style(style=style_type, activate=False)
|
|
442
|
+
results[style_type] = success
|
|
443
|
+
|
|
444
|
+
# Activate the default style if requested
|
|
445
|
+
if activate_default and results.get("professional", False):
|
|
446
|
+
self._activate_output_style("claude-mpm")
|
|
447
|
+
|
|
448
|
+
return results
|
|
449
|
+
|
|
450
|
+
def deploy_teaching_style(self, activate: bool = False) -> bool:
|
|
451
|
+
"""
|
|
452
|
+
Deploy the teaching style specifically.
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
activate: Whether to activate the teaching style after deployment
|
|
456
|
+
|
|
457
|
+
Returns:
|
|
458
|
+
True if deployed successfully, False otherwise
|
|
459
|
+
"""
|
|
460
|
+
return self.deploy_output_style(style="teaching", activate=activate)
|
|
461
|
+
|
|
462
|
+
def list_available_styles(self) -> Dict[str, Dict[str, str]]:
|
|
463
|
+
"""
|
|
464
|
+
List all available output styles with their metadata.
|
|
465
|
+
|
|
466
|
+
Returns:
|
|
467
|
+
Dictionary mapping style types to their configuration
|
|
468
|
+
"""
|
|
469
|
+
available_styles = {}
|
|
470
|
+
|
|
471
|
+
for style_type, config in self.styles.items():
|
|
472
|
+
source_exists = config["source"].exists()
|
|
473
|
+
target_exists = config["target"].exists()
|
|
474
|
+
|
|
475
|
+
available_styles[style_type] = {
|
|
476
|
+
"name": config["name"],
|
|
477
|
+
"source_path": str(config["source"]),
|
|
478
|
+
"target_path": str(config["target"]),
|
|
479
|
+
"source_exists": str(source_exists),
|
|
480
|
+
"deployed": str(target_exists),
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return available_styles
|
|
@@ -51,7 +51,7 @@ class ConfigLoader:
|
|
|
51
51
|
search_paths=[".", ".claude-mpm", "agents"],
|
|
52
52
|
env_prefix="CLAUDE_MPM_AGENT_",
|
|
53
53
|
defaults={"timeout": 30, "max_retries": 3, "log_level": "INFO"},
|
|
54
|
-
required_keys=["name",
|
|
54
|
+
required_keys=["name"], # model is optional - defaults to sonnet if not specified
|
|
55
55
|
)
|
|
56
56
|
|
|
57
57
|
MEMORY_CONFIG = ConfigPattern(
|
claude_mpm/core/socketio_pool.py
CHANGED
|
@@ -55,8 +55,8 @@ class CircuitState(Enum):
|
|
|
55
55
|
class ConnectionStats:
|
|
56
56
|
"""Connection statistics for monitoring."""
|
|
57
57
|
|
|
58
|
-
created_at: datetime = field(default_factory=datetime.now)
|
|
59
|
-
last_used: datetime = field(default_factory=datetime.now)
|
|
58
|
+
created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
59
|
+
last_used: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
60
60
|
events_sent: int = 0
|
|
61
61
|
errors: int = 0
|
|
62
62
|
consecutive_errors: int = 0
|
|
@@ -70,7 +70,7 @@ class BatchEvent:
|
|
|
70
70
|
namespace: str
|
|
71
71
|
event: str
|
|
72
72
|
data: Dict[str, Any]
|
|
73
|
-
timestamp: datetime = field(default_factory=datetime.now)
|
|
73
|
+
timestamp: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
class CircuitBreaker:
|
|
@@ -84,6 +84,12 @@ class AgentMetadata:
|
|
|
84
84
|
version: str = "1.0.0"
|
|
85
85
|
author: str = ""
|
|
86
86
|
tags: List[str] = None
|
|
87
|
+
# NEW: Collection-based identification fields
|
|
88
|
+
collection_id: Optional[str] = None # Format: owner/repo-name
|
|
89
|
+
source_path: Optional[str] = None # Relative path in repo
|
|
90
|
+
canonical_id: Optional[str] = (
|
|
91
|
+
None # Format: collection_id:agent_id or legacy:filename
|
|
92
|
+
)
|
|
87
93
|
|
|
88
94
|
def __post_init__(self):
|
|
89
95
|
"""Initialize default values for mutable fields."""
|
|
@@ -168,26 +174,16 @@ class UnifiedAgentRegistry:
|
|
|
168
174
|
if project_path.exists():
|
|
169
175
|
self.discovery_paths.append(project_path)
|
|
170
176
|
|
|
171
|
-
#
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
local_project_path.exists()
|
|
175
|
-
and local_project_path not in self.discovery_paths
|
|
176
|
-
):
|
|
177
|
-
self.discovery_paths.append(local_project_path)
|
|
178
|
-
logger.debug(f"Added local project templates path: {local_project_path}")
|
|
177
|
+
# NOTE: .claude-mpm/agents/ is deprecated in the simplified architecture
|
|
178
|
+
# Source agents come from ~/.claude-mpm/cache/agents/
|
|
179
|
+
# Deployed agents go to .claude/agents/
|
|
179
180
|
|
|
180
|
-
# User-level agents
|
|
181
|
+
# User-level agents (deprecated in simplified architecture)
|
|
182
|
+
# Keeping for backward compatibility but not actively used
|
|
181
183
|
user_path = self.path_manager.get_user_agents_dir()
|
|
182
184
|
if user_path.exists():
|
|
183
185
|
self.discovery_paths.append(user_path)
|
|
184
186
|
|
|
185
|
-
# Also check for user JSON templates in ~/.claude-mpm/agents/
|
|
186
|
-
local_user_path = Path.home() / ".claude-mpm" / "agents"
|
|
187
|
-
if local_user_path.exists() and local_user_path not in self.discovery_paths:
|
|
188
|
-
self.discovery_paths.append(local_user_path)
|
|
189
|
-
logger.debug(f"Added local user templates path: {local_user_path}")
|
|
190
|
-
|
|
191
187
|
# System-level agents (includes templates as a subdirectory)
|
|
192
188
|
system_path = self.path_manager.get_system_agents_dir()
|
|
193
189
|
if system_path.exists():
|
|
@@ -690,6 +686,111 @@ class UnifiedAgentRegistry:
|
|
|
690
686
|
"""Get all memory-aware agents."""
|
|
691
687
|
return self.list_agents(agent_type=AgentType.MEMORY_AWARE)
|
|
692
688
|
|
|
689
|
+
def get_agents_by_collection(self, collection_id: str) -> List[AgentMetadata]:
|
|
690
|
+
"""Get all agents from a specific collection.
|
|
691
|
+
|
|
692
|
+
NEW: Enables collection-based agent selection.
|
|
693
|
+
|
|
694
|
+
Args:
|
|
695
|
+
collection_id: Collection identifier (e.g., "bobmatnyc/claude-mpm-agents")
|
|
696
|
+
|
|
697
|
+
Returns:
|
|
698
|
+
List of agents from the specified collection
|
|
699
|
+
|
|
700
|
+
Example:
|
|
701
|
+
>>> registry = get_agent_registry()
|
|
702
|
+
>>> agents = registry.get_agents_by_collection("bobmatnyc/claude-mpm-agents")
|
|
703
|
+
>>> len(agents)
|
|
704
|
+
45
|
|
705
|
+
"""
|
|
706
|
+
if not self.registry:
|
|
707
|
+
self.discover_agents()
|
|
708
|
+
|
|
709
|
+
collection_agents = [
|
|
710
|
+
agent
|
|
711
|
+
for agent in self.registry.values()
|
|
712
|
+
if agent.collection_id == collection_id
|
|
713
|
+
]
|
|
714
|
+
|
|
715
|
+
return sorted(collection_agents, key=lambda a: a.name)
|
|
716
|
+
|
|
717
|
+
def list_collections(self) -> List[Dict[str, Any]]:
|
|
718
|
+
"""List all available collections with agent counts.
|
|
719
|
+
|
|
720
|
+
NEW: Provides overview of available collections.
|
|
721
|
+
|
|
722
|
+
Returns:
|
|
723
|
+
List of collection info dictionaries with:
|
|
724
|
+
- collection_id: Collection identifier
|
|
725
|
+
- agent_count: Number of agents in collection
|
|
726
|
+
- agents: List of agent names in collection
|
|
727
|
+
|
|
728
|
+
Example:
|
|
729
|
+
>>> registry = get_agent_registry()
|
|
730
|
+
>>> collections = registry.list_collections()
|
|
731
|
+
>>> collections
|
|
732
|
+
[
|
|
733
|
+
{
|
|
734
|
+
"collection_id": "bobmatnyc/claude-mpm-agents",
|
|
735
|
+
"agent_count": 45,
|
|
736
|
+
"agents": ["pm", "engineer", "qa", ...]
|
|
737
|
+
}
|
|
738
|
+
]
|
|
739
|
+
"""
|
|
740
|
+
if not self.registry:
|
|
741
|
+
self.discover_agents()
|
|
742
|
+
|
|
743
|
+
# Group agents by collection_id
|
|
744
|
+
collections_map: Dict[str, List[str]] = {}
|
|
745
|
+
|
|
746
|
+
for agent in self.registry.values():
|
|
747
|
+
if not agent.collection_id:
|
|
748
|
+
# Skip agents without collection (legacy or local)
|
|
749
|
+
continue
|
|
750
|
+
|
|
751
|
+
if agent.collection_id not in collections_map:
|
|
752
|
+
collections_map[agent.collection_id] = []
|
|
753
|
+
|
|
754
|
+
collections_map[agent.collection_id].append(agent.name)
|
|
755
|
+
|
|
756
|
+
# Convert to list format
|
|
757
|
+
collections = [
|
|
758
|
+
{
|
|
759
|
+
"collection_id": coll_id,
|
|
760
|
+
"agent_count": len(agent_names),
|
|
761
|
+
"agents": sorted(agent_names),
|
|
762
|
+
}
|
|
763
|
+
for coll_id, agent_names in collections_map.items()
|
|
764
|
+
]
|
|
765
|
+
|
|
766
|
+
return sorted(collections, key=lambda c: c["collection_id"])
|
|
767
|
+
|
|
768
|
+
def get_agent_by_canonical_id(self, canonical_id: str) -> Optional[AgentMetadata]:
|
|
769
|
+
"""Get agent by canonical ID (primary matching key).
|
|
770
|
+
|
|
771
|
+
NEW: Primary matching method using canonical_id.
|
|
772
|
+
|
|
773
|
+
Args:
|
|
774
|
+
canonical_id: Canonical identifier (e.g., "bobmatnyc/claude-mpm-agents:pm")
|
|
775
|
+
|
|
776
|
+
Returns:
|
|
777
|
+
AgentMetadata if found, None otherwise
|
|
778
|
+
|
|
779
|
+
Example:
|
|
780
|
+
>>> registry = get_agent_registry()
|
|
781
|
+
>>> agent = registry.get_agent_by_canonical_id("bobmatnyc/claude-mpm-agents:pm")
|
|
782
|
+
>>> agent.name
|
|
783
|
+
'Project Manager Agent'
|
|
784
|
+
"""
|
|
785
|
+
if not self.registry:
|
|
786
|
+
self.discover_agents()
|
|
787
|
+
|
|
788
|
+
for agent in self.registry.values():
|
|
789
|
+
if agent.canonical_id == canonical_id:
|
|
790
|
+
return agent
|
|
791
|
+
|
|
792
|
+
return None
|
|
793
|
+
|
|
693
794
|
def add_discovery_path(self, path: Union[str, Path]) -> None:
|
|
694
795
|
"""Add a new path for agent discovery."""
|
|
695
796
|
path = Path(path)
|
|
@@ -809,6 +910,21 @@ def get_registry_stats() -> Dict[str, Any]:
|
|
|
809
910
|
return get_agent_registry().get_registry_stats()
|
|
810
911
|
|
|
811
912
|
|
|
913
|
+
def get_agents_by_collection(collection_id: str) -> List[AgentMetadata]:
|
|
914
|
+
"""Get all agents from a specific collection."""
|
|
915
|
+
return get_agent_registry().get_agents_by_collection(collection_id)
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
def list_collections() -> List[Dict[str, Any]]:
|
|
919
|
+
"""List all available collections."""
|
|
920
|
+
return get_agent_registry().list_collections()
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
def get_agent_by_canonical_id(canonical_id: str) -> Optional[AgentMetadata]:
|
|
924
|
+
"""Get agent by canonical ID."""
|
|
925
|
+
return get_agent_registry().get_agent_by_canonical_id(canonical_id)
|
|
926
|
+
|
|
927
|
+
|
|
812
928
|
# Legacy function names for backward compatibility
|
|
813
929
|
def listAgents() -> List[str]:
|
|
814
930
|
"""Legacy function: Get list of agent names."""
|
|
@@ -838,14 +954,16 @@ __all__ = [
|
|
|
838
954
|
"discover_agents",
|
|
839
955
|
"discover_agents_sync",
|
|
840
956
|
"get_agent",
|
|
957
|
+
"get_agent_by_canonical_id",
|
|
841
958
|
"get_agent_names",
|
|
842
959
|
"get_agent_registry",
|
|
960
|
+
"get_agents_by_collection",
|
|
843
961
|
"get_core_agents",
|
|
844
962
|
"get_project_agents",
|
|
845
963
|
"get_registry_stats",
|
|
846
964
|
"get_specialized_agents",
|
|
847
|
-
# Legacy compatibility
|
|
848
965
|
"listAgents",
|
|
849
966
|
"list_agents",
|
|
850
967
|
"list_agents_all",
|
|
968
|
+
"list_collections",
|
|
851
969
|
]
|
|
@@ -218,6 +218,27 @@ class DevelopmentConfig(BaseModel):
|
|
|
218
218
|
)
|
|
219
219
|
|
|
220
220
|
|
|
221
|
+
class DocumentationConfig(BaseModel):
|
|
222
|
+
"""Documentation routing and management configuration."""
|
|
223
|
+
|
|
224
|
+
docs_path: str = Field(
|
|
225
|
+
default="docs/research/",
|
|
226
|
+
description="Default path for session documentation (relative to project root)",
|
|
227
|
+
)
|
|
228
|
+
attach_to_tickets: bool = Field(
|
|
229
|
+
default=True,
|
|
230
|
+
description="Attach work products to tickets when ticket context exists",
|
|
231
|
+
)
|
|
232
|
+
backup_locally: bool = Field(
|
|
233
|
+
default=True,
|
|
234
|
+
description="Always create local backup copies of documentation",
|
|
235
|
+
)
|
|
236
|
+
enable_ticket_detection: bool = Field(
|
|
237
|
+
default=True,
|
|
238
|
+
description="Enable automatic ticket context detection from user messages",
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
|
|
221
242
|
class UnifiedConfig(BaseSettings):
|
|
222
243
|
"""
|
|
223
244
|
Unified configuration model for Claude MPM.
|
|
@@ -242,6 +263,7 @@ class UnifiedConfig(BaseSettings):
|
|
|
242
263
|
performance: PerformanceConfig = Field(default_factory=PerformanceConfig)
|
|
243
264
|
sessions: SessionConfig = Field(default_factory=SessionConfig)
|
|
244
265
|
development: DevelopmentConfig = Field(default_factory=DevelopmentConfig)
|
|
266
|
+
documentation: DocumentationConfig = Field(default_factory=DocumentationConfig)
|
|
245
267
|
|
|
246
268
|
# Path configuration
|
|
247
269
|
base_path: Optional[Path] = Field(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const env={}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.static{position:static}.relative{position:relative}.sticky{position:sticky}.top-0{top:0}.mx-auto{margin-left:auto;margin-right:auto}.-ml-1{margin-left:-.25rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-12{height:3rem}.h-16{height:4rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[calc\(100vh-280px\)\]{max-height:calc(100vh - 280px)}.min-h-0{min-height:0px}.min-h-screen{min-height:100vh}.w-1\/3{width:33.333333%}.w-12{width:3rem}.w-16{width:4rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-64{width:16rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.grid-cols-\[110px_120px_160px_120px_100px\]{grid-template-columns:110px 120px 160px 120px 100px}.grid-cols-\[140px_1fr_80px_100px\]{grid-template-columns:140px 1fr 80px 100px}.grid-cols-\[50px_1fr_100px_120px\]{grid-template-columns:50px 1fr 100px 120px}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.625rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-slate-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(226 232 240 / var(--tw-divide-opacity, 1))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-500\/20{border-color:#3b82f633}.border-blue-500\/30{border-color:#3b82f64d}.border-green-500\/20{border-color:#22c55e33}.border-green-500\/30{border-color:#22c55e4d}.border-purple-200{--tw-border-opacity: 1;border-color:rgb(233 213 255 / var(--tw-border-opacity, 1))}.border-purple-500\/20{border-color:#a855f733}.border-purple-500\/30{border-color:#a855f74d}.border-red-500\/20{border-color:#ef444433}.border-slate-200{--tw-border-opacity: 1;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1))}.border-slate-300{--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity, 1))}.border-slate-500\/20{border-color:#64748b33}.border-slate-500\/30{border-color:#64748b4d}.border-l-cyan-500{--tw-border-opacity: 1;border-left-color:rgb(6 182 212 / var(--tw-border-opacity, 1))}.border-l-transparent{border-left-color:transparent}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-200{--tw-bg-opacity: 1;background-color:rgb(253 230 138 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500\/20{background-color:#3b82f633}.bg-blue-500\/5{background-color:#3b82f60d}.bg-cyan-50{--tw-bg-opacity: 1;background-color:rgb(236 254 255 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-500\/20{background-color:#22c55e33}.bg-green-500\/5{background-color:#22c55e0d}.bg-purple-50{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.bg-purple-500\/20{background-color:#a855f733}.bg-purple-500\/5{background-color:#a855f70d}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/5{background-color:#ef44440d}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-slate-200{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity, 1))}.bg-slate-50{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.bg-slate-500\/20{background-color:#64748b33}.bg-slate-500\/5{background-color:#64748b0d}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-2{padding-bottom:.5rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.leading-none{line-height:1}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-cyan-400{--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-cyan-600{--tw-text-opacity: 1;color:rgb(8 145 178 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-red-900{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-800{--tw-text-opacity: 1;color:rgb(30 41 59 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.placeholder-slate-400::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity, 1))}.placeholder-slate-400::placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity, 1))}.opacity-50{opacity:.5}.outline{outline-style:solid}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-cyan-300{--tw-ring-opacity: 1;--tw-ring-color: rgb(103 232 249 / var(--tw-ring-opacity, 1))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;--color-bg-primary: #ffffff;--color-bg-secondary: #f8fafc;--color-bg-code: #f1f5f9;--color-text-primary: #0f172a;--color-text-secondary: #475569;--color-text-tertiary: #64748b;--color-border: #e2e8f0;--color-primary: #0891b2}.dark{--color-bg-primary: #0f172a;--color-bg-secondary: #1e293b;--color-bg-code: #334155;--color-text-primary: #f1f5f9;--color-text-secondary: #cbd5e1;--color-text-tertiary: #94a3b8;--color-border: #334155;--color-primary: #06b6d4}body{margin:0;padding:0;background-color:#0f172a;color:#e2e8f0}.hover\:border-slate-300:hover{--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity, 1))}.hover\:bg-blue-500\/10:hover{background-color:#3b82f61a}.hover\:bg-green-500\/10:hover{background-color:#22c55e1a}.hover\:bg-purple-500\/10:hover{background-color:#a855f71a}.hover\:bg-red-500\/10:hover{background-color:#ef44441a}.hover\:bg-slate-100:hover{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-200:hover{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-50:hover{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-500\/10:hover{background-color:#64748b1a}.hover\:text-slate-900:hover{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:border-transparent:focus{border-color:transparent}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-cyan-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(6 182 212 / var(--tw-ring-opacity, 1))}.dark\:divide-slate-700:is(.dark *)>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(51 65 85 / var(--tw-divide-opacity, 1))}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:border-blue-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 64 175 / var(--tw-border-opacity, 1))}.dark\:border-purple-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(107 33 168 / var(--tw-border-opacity, 1))}.dark\:border-slate-600:is(.dark *){--tw-border-opacity: 1;border-color:rgb(71 85 105 / var(--tw-border-opacity, 1))}.dark\:border-slate-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity, 1))}.dark\:border-l-cyan-400:is(.dark *){--tw-border-opacity: 1;border-left-color:rgb(34 211 238 / var(--tw-border-opacity, 1))}.dark\:bg-amber-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.dark\:bg-amber-900\/20:is(.dark *){background-color:#78350f33}.dark\:bg-amber-900\/30:is(.dark *){background-color:#78350f4d}.dark\:bg-black\/30:is(.dark *){background-color:#0000004d}.dark\:bg-blue-900\/20:is(.dark *){background-color:#1e3a8a33}.dark\:bg-blue-900\/30:is(.dark *){background-color:#1e3a8a4d}.dark\:bg-cyan-500\/20:is(.dark *){background-color:#06b6d433}.dark\:bg-green-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(20 83 45 / var(--tw-bg-opacity, 1))}.dark\:bg-green-900\/30:is(.dark *){background-color:#14532d4d}.dark\:bg-purple-900\/20:is(.dark *){background-color:#581c8733}.dark\:bg-red-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(127 29 29 / var(--tw-bg-opacity, 1))}.dark\:bg-red-900\/20:is(.dark *){background-color:#7f1d1d33}.dark\:bg-slate-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-800\/20:is(.dark *){background-color:#1e293b33}.dark\:bg-slate-800\/40:is(.dark *){background-color:#1e293b66}.dark\:bg-slate-800\/50:is(.dark *){background-color:#1e293b80}.dark\:bg-slate-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-cyan-400:is(.dark *){--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.dark\:text-green-200:is(.dark *){--tw-text-opacity: 1;color:rgb(187 247 208 / var(--tw-text-opacity, 1))}.dark\:text-green-300:is(.dark *){--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-purple-400:is(.dark *){--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.dark\:text-red-100:is(.dark *){--tw-text-opacity: 1;color:rgb(254 226 226 / var(--tw-text-opacity, 1))}.dark\:text-red-200:is(.dark *){--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity, 1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-slate-100:is(.dark *){--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.dark\:text-slate-200:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.dark\:text-slate-300:is(.dark *){--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.dark\:text-slate-400:is(.dark *){--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.dark\:text-slate-500:is(.dark *){--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.dark\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:placeholder-slate-500:is(.dark *)::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.dark\:placeholder-slate-500:is(.dark *)::placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.dark\:ring-cyan-500\/30:is(.dark *){--tw-ring-color: rgb(6 182 212 / .3)}.dark\:hover\:border-slate-600:hover:is(.dark *){--tw-border-opacity: 1;border-color:rgb(71 85 105 / var(--tw-border-opacity, 1))}.dark\:hover\:bg-slate-600:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-slate-700:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-slate-700\/30:hover:is(.dark *){background-color:#3341554d}.dark\:hover\:bg-slate-700\/50:hover:is(.dark *){background-color:#33415580}.dark\:hover\:bg-slate-800:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:hover\:text-slate-200:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}
|