claude-mpm 5.6.1__py3-none-any.whl → 5.6.76__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/PM_INSTRUCTIONS.md +8 -3
  3. claude_mpm/auth/__init__.py +35 -0
  4. claude_mpm/auth/callback_server.py +328 -0
  5. claude_mpm/auth/models.py +104 -0
  6. claude_mpm/auth/oauth_manager.py +266 -0
  7. claude_mpm/auth/providers/__init__.py +12 -0
  8. claude_mpm/auth/providers/base.py +165 -0
  9. claude_mpm/auth/providers/google.py +261 -0
  10. claude_mpm/auth/token_storage.py +252 -0
  11. claude_mpm/cli/commands/commander.py +174 -4
  12. claude_mpm/cli/commands/mcp.py +29 -17
  13. claude_mpm/cli/commands/mcp_command_router.py +39 -0
  14. claude_mpm/cli/commands/mcp_service_commands.py +304 -0
  15. claude_mpm/cli/commands/oauth.py +481 -0
  16. claude_mpm/cli/commands/skill_source.py +51 -2
  17. claude_mpm/cli/commands/skills.py +5 -3
  18. claude_mpm/cli/executor.py +9 -0
  19. claude_mpm/cli/helpers.py +1 -1
  20. claude_mpm/cli/parsers/base_parser.py +13 -0
  21. claude_mpm/cli/parsers/commander_parser.py +43 -10
  22. claude_mpm/cli/parsers/mcp_parser.py +79 -0
  23. claude_mpm/cli/parsers/oauth_parser.py +165 -0
  24. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  25. claude_mpm/cli/parsers/skills_parser.py +5 -0
  26. claude_mpm/cli/startup.py +300 -33
  27. claude_mpm/cli/startup_display.py +4 -2
  28. claude_mpm/cli/startup_migrations.py +236 -0
  29. claude_mpm/commander/__init__.py +6 -0
  30. claude_mpm/commander/adapters/__init__.py +32 -3
  31. claude_mpm/commander/adapters/auggie.py +260 -0
  32. claude_mpm/commander/adapters/base.py +98 -1
  33. claude_mpm/commander/adapters/claude_code.py +32 -1
  34. claude_mpm/commander/adapters/codex.py +237 -0
  35. claude_mpm/commander/adapters/example_usage.py +310 -0
  36. claude_mpm/commander/adapters/mpm.py +389 -0
  37. claude_mpm/commander/adapters/registry.py +204 -0
  38. claude_mpm/commander/api/app.py +32 -16
  39. claude_mpm/commander/api/errors.py +21 -0
  40. claude_mpm/commander/api/routes/messages.py +11 -11
  41. claude_mpm/commander/api/routes/projects.py +20 -20
  42. claude_mpm/commander/api/routes/sessions.py +37 -26
  43. claude_mpm/commander/api/routes/work.py +86 -50
  44. claude_mpm/commander/api/schemas.py +4 -0
  45. claude_mpm/commander/chat/cli.py +47 -5
  46. claude_mpm/commander/chat/commands.py +44 -16
  47. claude_mpm/commander/chat/repl.py +1729 -82
  48. claude_mpm/commander/config.py +5 -3
  49. claude_mpm/commander/core/__init__.py +10 -0
  50. claude_mpm/commander/core/block_manager.py +325 -0
  51. claude_mpm/commander/core/response_manager.py +323 -0
  52. claude_mpm/commander/daemon.py +215 -10
  53. claude_mpm/commander/env_loader.py +59 -0
  54. claude_mpm/commander/events/manager.py +61 -1
  55. claude_mpm/commander/frameworks/base.py +91 -1
  56. claude_mpm/commander/frameworks/mpm.py +9 -14
  57. claude_mpm/commander/git/__init__.py +5 -0
  58. claude_mpm/commander/git/worktree_manager.py +212 -0
  59. claude_mpm/commander/instance_manager.py +546 -15
  60. claude_mpm/commander/memory/__init__.py +45 -0
  61. claude_mpm/commander/memory/compression.py +347 -0
  62. claude_mpm/commander/memory/embeddings.py +230 -0
  63. claude_mpm/commander/memory/entities.py +310 -0
  64. claude_mpm/commander/memory/example_usage.py +290 -0
  65. claude_mpm/commander/memory/integration.py +325 -0
  66. claude_mpm/commander/memory/search.py +381 -0
  67. claude_mpm/commander/memory/store.py +657 -0
  68. claude_mpm/commander/models/events.py +6 -0
  69. claude_mpm/commander/persistence/state_store.py +95 -1
  70. claude_mpm/commander/registry.py +10 -4
  71. claude_mpm/commander/runtime/monitor.py +32 -2
  72. claude_mpm/commander/tmux_orchestrator.py +3 -2
  73. claude_mpm/commander/work/executor.py +38 -20
  74. claude_mpm/commander/workflow/event_handler.py +25 -3
  75. claude_mpm/config/skill_sources.py +16 -0
  76. claude_mpm/constants.py +5 -0
  77. claude_mpm/core/claude_runner.py +152 -0
  78. claude_mpm/core/config.py +30 -22
  79. claude_mpm/core/config_constants.py +74 -9
  80. claude_mpm/core/constants.py +56 -12
  81. claude_mpm/core/hook_manager.py +2 -1
  82. claude_mpm/core/interactive_session.py +5 -4
  83. claude_mpm/core/logger.py +16 -2
  84. claude_mpm/core/logging_utils.py +40 -16
  85. claude_mpm/core/network_config.py +148 -0
  86. claude_mpm/core/oneshot_session.py +7 -6
  87. claude_mpm/core/output_style_manager.py +37 -7
  88. claude_mpm/core/socketio_pool.py +47 -15
  89. claude_mpm/core/unified_paths.py +68 -80
  90. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +30 -31
  91. claude_mpm/hooks/claude_hooks/event_handlers.py +285 -194
  92. claude_mpm/hooks/claude_hooks/hook_handler.py +115 -32
  93. claude_mpm/hooks/claude_hooks/installer.py +222 -54
  94. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  95. claude_mpm/hooks/claude_hooks/response_tracking.py +40 -59
  96. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  97. claude_mpm/hooks/claude_hooks/services/connection_manager.py +25 -30
  98. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +24 -28
  99. claude_mpm/hooks/claude_hooks/services/container.py +326 -0
  100. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  101. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  102. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +49 -75
  103. claude_mpm/hooks/session_resume_hook.py +22 -18
  104. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  105. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  106. claude_mpm/init.py +21 -14
  107. claude_mpm/mcp/__init__.py +9 -0
  108. claude_mpm/mcp/google_workspace_server.py +610 -0
  109. claude_mpm/scripts/claude-hook-handler.sh +10 -9
  110. claude_mpm/services/agents/agent_selection_service.py +2 -2
  111. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  112. claude_mpm/services/command_deployment_service.py +44 -26
  113. claude_mpm/services/hook_installer_service.py +77 -8
  114. claude_mpm/services/mcp_config_manager.py +99 -19
  115. claude_mpm/services/mcp_service_registry.py +294 -0
  116. claude_mpm/services/monitor/server.py +6 -1
  117. claude_mpm/services/pm_skills_deployer.py +5 -3
  118. claude_mpm/services/skills/git_skill_source_manager.py +79 -8
  119. claude_mpm/services/skills/selective_skill_deployer.py +28 -0
  120. claude_mpm/services/skills/skill_discovery_service.py +17 -1
  121. claude_mpm/services/skills_deployer.py +31 -5
  122. claude_mpm/skills/__init__.py +2 -1
  123. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  124. claude_mpm/skills/registry.py +295 -90
  125. {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/METADATA +28 -3
  126. {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/RECORD +131 -93
  127. {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/WHEEL +1 -1
  128. {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/entry_points.txt +2 -0
  129. {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE +0 -0
  130. {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  131. {claude_mpm-5.6.1.dist-info → claude_mpm-5.6.76.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,13 @@ import re
9
9
  import shlex
10
10
  from typing import List, Optional, Set
11
11
 
12
- from .base import Capability, ParsedResponse, RuntimeAdapter
12
+ from .base import (
13
+ Capability,
14
+ ParsedResponse,
15
+ RuntimeAdapter,
16
+ RuntimeCapability,
17
+ RuntimeInfo,
18
+ )
13
19
 
14
20
  logger = logging.getLogger(__name__)
15
21
 
@@ -96,6 +102,31 @@ class ClaudeCodeAdapter(RuntimeAdapter):
96
102
  Capability.COMPLEX_REASONING,
97
103
  }
98
104
 
105
+ @property
106
+ def runtime_info(self) -> RuntimeInfo:
107
+ """Return detailed runtime information."""
108
+ return RuntimeInfo(
109
+ name="claude-code",
110
+ version=None, # Version detection could be added
111
+ capabilities={
112
+ RuntimeCapability.FILE_READ,
113
+ RuntimeCapability.FILE_EDIT,
114
+ RuntimeCapability.FILE_CREATE,
115
+ RuntimeCapability.BASH_EXECUTION,
116
+ RuntimeCapability.GIT_OPERATIONS,
117
+ RuntimeCapability.TOOL_USE,
118
+ RuntimeCapability.WEB_SEARCH,
119
+ RuntimeCapability.COMPLEX_REASONING,
120
+ RuntimeCapability.AGENT_DELEGATION, # Claude Code supports Task tool
121
+ RuntimeCapability.HOOKS, # Claude Code supports hooks
122
+ RuntimeCapability.SKILLS, # Claude Code can load skills
123
+ RuntimeCapability.MONITOR, # Can be monitored
124
+ },
125
+ command="claude",
126
+ supports_agents=True, # Claude Code supports agent delegation
127
+ instruction_file="CLAUDE.md",
128
+ )
129
+
99
130
  def build_launch_command(
100
131
  self, project_path: str, agent_prompt: Optional[str] = None
101
132
  ) -> str:
@@ -0,0 +1,237 @@
1
+ """Codex CLI runtime adapter.
2
+
3
+ This module implements the RuntimeAdapter interface for Codex,
4
+ an AI coding assistant (limited support currently).
5
+ """
6
+
7
+ import logging
8
+ import re
9
+ import shlex
10
+ from typing import List, Optional, Set
11
+
12
+ from .base import (
13
+ Capability,
14
+ ParsedResponse,
15
+ RuntimeAdapter,
16
+ RuntimeCapability,
17
+ RuntimeInfo,
18
+ )
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class CodexAdapter(RuntimeAdapter):
24
+ """Adapter for Codex CLI.
25
+
26
+ Codex is an AI coding assistant. This adapter provides basic support,
27
+ with limited capabilities compared to Claude Code or MPM.
28
+
29
+ Note:
30
+ Agent delegation and advanced features not yet supported.
31
+
32
+ Example:
33
+ >>> adapter = CodexAdapter()
34
+ >>> cmd = adapter.build_launch_command("/home/user/project")
35
+ >>> print(cmd)
36
+ cd '/home/user/project' && codex
37
+ """
38
+
39
+ # Idle detection patterns
40
+ IDLE_PATTERNS = [
41
+ r"^>\s*$", # Simple prompt
42
+ r"codex>\s*$", # Named prompt
43
+ r"Ready",
44
+ r"Waiting for input",
45
+ ]
46
+
47
+ # Error patterns
48
+ ERROR_PATTERNS = [
49
+ r"Error:",
50
+ r"Failed:",
51
+ r"Exception:",
52
+ r"Permission denied",
53
+ r"not found",
54
+ r"Traceback",
55
+ r"FATAL:",
56
+ ]
57
+
58
+ # Question patterns
59
+ QUESTION_PATTERNS = [
60
+ r"Which option",
61
+ r"Should I proceed",
62
+ r"Please choose",
63
+ r"\(y/n\)\?",
64
+ r"Are you sure",
65
+ r"\[Y/n\]",
66
+ ]
67
+
68
+ # ANSI escape code pattern
69
+ ANSI_ESCAPE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
70
+
71
+ @property
72
+ def name(self) -> str:
73
+ """Return the runtime identifier."""
74
+ return "codex"
75
+
76
+ @property
77
+ def capabilities(self) -> Set[Capability]:
78
+ """Return the set of capabilities supported by Codex."""
79
+ return {
80
+ Capability.TOOL_USE,
81
+ Capability.FILE_EDIT,
82
+ Capability.FILE_CREATE,
83
+ Capability.SHELL_COMMANDS,
84
+ Capability.COMPLEX_REASONING,
85
+ }
86
+
87
+ @property
88
+ def runtime_info(self) -> RuntimeInfo:
89
+ """Return detailed runtime information."""
90
+ return RuntimeInfo(
91
+ name="codex",
92
+ version=None, # Version detection could be added
93
+ capabilities={
94
+ RuntimeCapability.FILE_READ,
95
+ RuntimeCapability.FILE_EDIT,
96
+ RuntimeCapability.FILE_CREATE,
97
+ RuntimeCapability.BASH_EXECUTION,
98
+ RuntimeCapability.TOOL_USE,
99
+ RuntimeCapability.COMPLEX_REASONING,
100
+ },
101
+ command="codex",
102
+ supports_agents=False, # No agent support
103
+ instruction_file=None, # No custom instructions support
104
+ )
105
+
106
+ def build_launch_command(
107
+ self, project_path: str, agent_prompt: Optional[str] = None
108
+ ) -> str:
109
+ """Generate shell command to start Codex.
110
+
111
+ Args:
112
+ project_path: Absolute path to the project directory
113
+ agent_prompt: Optional system prompt (may not be supported)
114
+
115
+ Returns:
116
+ Shell command string ready to execute
117
+
118
+ Example:
119
+ >>> adapter = CodexAdapter()
120
+ >>> adapter.build_launch_command("/home/user/project")
121
+ "cd '/home/user/project' && codex"
122
+ """
123
+ quoted_path = shlex.quote(project_path)
124
+ cmd = f"cd {quoted_path} && codex"
125
+
126
+ # Note: Codex may not support custom prompts
127
+ # Adjust based on actual Codex CLI capabilities
128
+ if agent_prompt:
129
+ logger.warning("Codex may not support custom prompts")
130
+
131
+ logger.debug(f"Built Codex launch command: {cmd}")
132
+ return cmd
133
+
134
+ def format_input(self, message: str) -> str:
135
+ """Prepare message for Codex's input format."""
136
+ formatted = message.strip()
137
+ logger.debug(f"Formatted input: {formatted[:100]}...")
138
+ return formatted
139
+
140
+ def strip_ansi(self, text: str) -> str:
141
+ """Remove ANSI escape codes from text."""
142
+ return self.ANSI_ESCAPE.sub("", text)
143
+
144
+ def detect_idle(self, output: str) -> bool:
145
+ """Recognize when Codex is waiting for input."""
146
+ if not output:
147
+ return False
148
+
149
+ clean = self.strip_ansi(output)
150
+ lines = clean.strip().split("\n")
151
+
152
+ if not lines:
153
+ return False
154
+
155
+ last_line = lines[-1].strip()
156
+
157
+ for pattern in self.IDLE_PATTERNS:
158
+ if re.search(pattern, last_line):
159
+ logger.debug(f"Detected idle state with pattern: {pattern}")
160
+ return True
161
+
162
+ return False
163
+
164
+ def detect_error(self, output: str) -> Optional[str]:
165
+ """Recognize error states and extract error message."""
166
+ clean = self.strip_ansi(output)
167
+
168
+ for pattern in self.ERROR_PATTERNS:
169
+ match = re.search(pattern, clean, re.IGNORECASE)
170
+ if match:
171
+ for line in clean.split("\n"):
172
+ if re.search(pattern, line, re.IGNORECASE):
173
+ error_msg = line.strip()
174
+ logger.warning(f"Detected error: {error_msg}")
175
+ return error_msg
176
+
177
+ return None
178
+
179
+ def detect_question(
180
+ self, output: str
181
+ ) -> tuple[bool, Optional[str], Optional[List[str]]]:
182
+ """Detect if Codex is asking a question."""
183
+ clean = self.strip_ansi(output)
184
+
185
+ for pattern in self.QUESTION_PATTERNS:
186
+ if re.search(pattern, clean, re.IGNORECASE):
187
+ lines = clean.strip().split("\n")
188
+ question = None
189
+ options = []
190
+
191
+ for line in lines:
192
+ if re.search(pattern, line, re.IGNORECASE):
193
+ question = line.strip()
194
+
195
+ # Look for numbered options
196
+ opt_match = re.match(r"^\s*(\d+)[.):]\s*(.+)$", line)
197
+ if opt_match:
198
+ options.append(opt_match.group(2).strip())
199
+
200
+ logger.debug(
201
+ f"Detected question: {question}, options: {options if options else 'none'}"
202
+ )
203
+ return True, question, options if options else None
204
+
205
+ return False, None, None
206
+
207
+ def parse_response(self, output: str) -> ParsedResponse:
208
+ """Extract meaningful content from Codex output."""
209
+ if not output:
210
+ return ParsedResponse(
211
+ content="",
212
+ is_complete=False,
213
+ is_error=False,
214
+ is_question=False,
215
+ )
216
+
217
+ clean = self.strip_ansi(output)
218
+ error_msg = self.detect_error(output)
219
+ is_question, question_text, options = self.detect_question(output)
220
+ is_complete = self.detect_idle(output)
221
+
222
+ response = ParsedResponse(
223
+ content=clean,
224
+ is_complete=is_complete,
225
+ is_error=error_msg is not None,
226
+ error_message=error_msg,
227
+ is_question=is_question,
228
+ question_text=question_text,
229
+ options=options,
230
+ )
231
+
232
+ logger.debug(
233
+ f"Parsed response: complete={is_complete}, error={error_msg is not None}, "
234
+ f"question={is_question}"
235
+ )
236
+
237
+ return response
@@ -0,0 +1,310 @@
1
+ """Example usage of multi-runtime adapter architecture.
2
+
3
+ This module demonstrates how to use the adapter registry and
4
+ individual adapters for different AI coding runtimes.
5
+ """
6
+
7
+ import logging
8
+ from typing import Optional
9
+
10
+ from claude_mpm.commander.adapters import (
11
+ AdapterRegistry,
12
+ AuggieAdapter,
13
+ ClaudeCodeAdapter,
14
+ CodexAdapter,
15
+ MPMAdapter,
16
+ RuntimeAdapter,
17
+ RuntimeCapability,
18
+ )
19
+
20
+ # Configure logging
21
+ logging.basicConfig(
22
+ level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
23
+ )
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ def example_registry_usage() -> None:
28
+ """Demonstrate adapter registry usage."""
29
+ print("\n" + "=" * 60)
30
+ print("ADAPTER REGISTRY USAGE")
31
+ print("=" * 60 + "\n")
32
+
33
+ # List all registered adapters
34
+ registered = AdapterRegistry.list_registered()
35
+ print(f"Registered adapters: {registered}")
36
+
37
+ # Detect available runtimes on system
38
+ available = AdapterRegistry.detect_available()
39
+ print(f"Available runtimes: {available}")
40
+
41
+ # Get default adapter (best available)
42
+ default_adapter = AdapterRegistry.get_default()
43
+ if default_adapter:
44
+ print(f"\nDefault adapter: {default_adapter.name}")
45
+ print(f"Capabilities: {default_adapter.capabilities}")
46
+ else:
47
+ print("\nNo adapters available on this system")
48
+
49
+ # Get specific adapter
50
+ mpm_adapter = AdapterRegistry.get("mpm")
51
+ if mpm_adapter:
52
+ print(f"\nMPM adapter available: {mpm_adapter.name}")
53
+ else:
54
+ print("\nMPM adapter not available")
55
+
56
+ # Check if specific runtime is available
57
+ if AdapterRegistry.is_available("claude-code"):
58
+ print("\nClaude Code is available")
59
+ else:
60
+ print("\nClaude Code is NOT available")
61
+
62
+
63
+ def example_adapter_capabilities() -> None:
64
+ """Demonstrate checking adapter capabilities."""
65
+ print("\n" + "=" * 60)
66
+ print("ADAPTER CAPABILITIES")
67
+ print("=" * 60 + "\n")
68
+
69
+ adapters = [
70
+ ClaudeCodeAdapter(),
71
+ AuggieAdapter(),
72
+ CodexAdapter(),
73
+ MPMAdapter(),
74
+ ]
75
+
76
+ for adapter in adapters:
77
+ print(f"\n{adapter.name.upper()} Adapter:")
78
+ print(
79
+ f" Command: {adapter.runtime_info.command if adapter.runtime_info else 'N/A'}"
80
+ )
81
+
82
+ # Check for specific capabilities
83
+ info = adapter.runtime_info
84
+ if info:
85
+ print(f" Supports agents: {info.supports_agents}")
86
+ print(f" Instruction file: {info.instruction_file or 'None'}")
87
+
88
+ # Check for advanced features
89
+ if RuntimeCapability.AGENT_DELEGATION in info.capabilities:
90
+ print(" ✓ Agent delegation supported")
91
+ else:
92
+ print(" ✗ Agent delegation NOT supported")
93
+
94
+ if RuntimeCapability.HOOKS in info.capabilities:
95
+ print(" ✓ Lifecycle hooks supported")
96
+ else:
97
+ print(" ✗ Lifecycle hooks NOT supported")
98
+
99
+ if RuntimeCapability.MCP_TOOLS in info.capabilities:
100
+ print(" ✓ MCP tools supported")
101
+ else:
102
+ print(" ✗ MCP tools NOT supported")
103
+
104
+ if RuntimeCapability.SKILLS in info.capabilities:
105
+ print(" ✓ Skills supported")
106
+ else:
107
+ print(" ✗ Skills NOT supported")
108
+
109
+ if RuntimeCapability.MONITOR in info.capabilities:
110
+ print(" ✓ Real-time monitoring supported")
111
+ else:
112
+ print(" ✗ Real-time monitoring NOT supported")
113
+
114
+
115
+ def example_build_commands() -> None:
116
+ """Demonstrate building launch commands."""
117
+ print("\n" + "=" * 60)
118
+ print("BUILD LAUNCH COMMANDS")
119
+ print("=" * 60 + "\n")
120
+
121
+ project_path = "/home/user/my-project"
122
+ agent_prompt = "You are a Python expert specializing in FastAPI and async code."
123
+
124
+ adapters = [
125
+ ClaudeCodeAdapter(),
126
+ AuggieAdapter(),
127
+ CodexAdapter(),
128
+ MPMAdapter(),
129
+ ]
130
+
131
+ for adapter in adapters:
132
+ print(f"\n{adapter.name.upper()}:")
133
+
134
+ # Basic launch command
135
+ cmd = adapter.build_launch_command(project_path)
136
+ print(f" Basic: {cmd}")
137
+
138
+ # With agent prompt
139
+ cmd_with_prompt = adapter.build_launch_command(project_path, agent_prompt)
140
+ print(f" With prompt: {cmd_with_prompt}")
141
+
142
+
143
+ def example_inject_instructions() -> None:
144
+ """Demonstrate injecting custom instructions."""
145
+ print("\n" + "=" * 60)
146
+ print("INJECT CUSTOM INSTRUCTIONS")
147
+ print("=" * 60 + "\n")
148
+
149
+ instructions = """You are a senior Python engineer.
150
+ Follow PEP 8 strictly.
151
+ Write comprehensive tests for all code.
152
+ Use type hints everywhere."""
153
+
154
+ adapters = [
155
+ ClaudeCodeAdapter(),
156
+ AuggieAdapter(),
157
+ CodexAdapter(),
158
+ MPMAdapter(),
159
+ ]
160
+
161
+ for adapter in adapters:
162
+ print(f"\n{adapter.name.upper()}:")
163
+
164
+ cmd = adapter.inject_instructions(instructions)
165
+ if cmd:
166
+ print(f" Command: {cmd}")
167
+ else:
168
+ print(" Not supported")
169
+
170
+
171
+ def example_inject_agent_context() -> None:
172
+ """Demonstrate injecting agent context."""
173
+ print("\n" + "=" * 60)
174
+ print("INJECT AGENT CONTEXT")
175
+ print("=" * 60 + "\n")
176
+
177
+ agent_id = "eng-001"
178
+ context = {
179
+ "role": "Engineer",
180
+ "specialty": "Backend Python",
181
+ "task": "Implement API endpoints",
182
+ }
183
+
184
+ adapters = [
185
+ ClaudeCodeAdapter(),
186
+ AuggieAdapter(),
187
+ CodexAdapter(),
188
+ MPMAdapter(),
189
+ ]
190
+
191
+ for adapter in adapters:
192
+ print(f"\n{adapter.name.upper()}:")
193
+
194
+ cmd = adapter.inject_agent_context(agent_id, context)
195
+ if cmd:
196
+ print(f" Command: {cmd[:100]}...")
197
+ else:
198
+ print(" Not supported")
199
+
200
+
201
+ def example_parse_response() -> None:
202
+ """Demonstrate parsing runtime output."""
203
+ print("\n" + "=" * 60)
204
+ print("PARSE RUNTIME OUTPUT")
205
+ print("=" * 60 + "\n")
206
+
207
+ # Simulate different output scenarios
208
+ outputs = {
209
+ "idle": "File created successfully.\n> ",
210
+ "error": "Error: File not found: config.py\n> ",
211
+ "question": "Should I proceed with the changes? (y/n)?",
212
+ "processing": "Processing your request...",
213
+ }
214
+
215
+ adapter = ClaudeCodeAdapter()
216
+
217
+ for scenario, output in outputs.items():
218
+ print(f"\n{scenario.upper()}:")
219
+ parsed = adapter.parse_response(output)
220
+ print(f" Content: {parsed.content[:50]}...")
221
+ print(f" Is complete: {parsed.is_complete}")
222
+ print(f" Is error: {parsed.is_error}")
223
+ print(f" Is question: {parsed.is_question}")
224
+ if parsed.error_message:
225
+ print(f" Error message: {parsed.error_message}")
226
+ if parsed.question_text:
227
+ print(f" Question: {parsed.question_text}")
228
+
229
+
230
+ def example_runtime_selection() -> None:
231
+ """Demonstrate selecting runtime based on requirements."""
232
+ print("\n" + "=" * 60)
233
+ print("RUNTIME SELECTION LOGIC")
234
+ print("=" * 60 + "\n")
235
+
236
+ def select_runtime(
237
+ needs_agents: bool = False, needs_mcp: bool = False
238
+ ) -> Optional[RuntimeAdapter]:
239
+ """Select appropriate runtime based on requirements."""
240
+ # Get all available adapters
241
+ available = AdapterRegistry.detect_available()
242
+
243
+ # Filter by requirements
244
+ for name in available:
245
+ adapter = AdapterRegistry.get(name)
246
+ if not adapter or not adapter.runtime_info:
247
+ continue
248
+
249
+ info = adapter.runtime_info
250
+
251
+ # Check agent requirement
252
+ if needs_agents and not info.supports_agents:
253
+ continue
254
+
255
+ # Check MCP requirement
256
+ if needs_mcp and RuntimeCapability.MCP_TOOLS not in info.capabilities:
257
+ continue
258
+
259
+ # Found suitable runtime
260
+ return adapter
261
+
262
+ return None
263
+
264
+ # Example 1: Need agent delegation
265
+ print("Requirement: Agent delegation")
266
+ adapter = select_runtime(needs_agents=True)
267
+ if adapter:
268
+ print(f" Selected: {adapter.name}")
269
+ else:
270
+ print(" No suitable runtime found")
271
+
272
+ # Example 2: Need MCP tools
273
+ print("\nRequirement: MCP tools")
274
+ adapter = select_runtime(needs_mcp=True)
275
+ if adapter:
276
+ print(f" Selected: {adapter.name}")
277
+ else:
278
+ print(" No suitable runtime found")
279
+
280
+ # Example 3: Need both
281
+ print("\nRequirement: Agent delegation + MCP tools")
282
+ adapter = select_runtime(needs_agents=True, needs_mcp=True)
283
+ if adapter:
284
+ print(f" Selected: {adapter.name}")
285
+ else:
286
+ print(" No suitable runtime found")
287
+
288
+
289
+ def main() -> None:
290
+ """Run all examples."""
291
+ print("\n" + "#" * 60)
292
+ print("# MULTI-RUNTIME ADAPTER ARCHITECTURE EXAMPLES")
293
+ print("#" * 60)
294
+
295
+ # Run all examples
296
+ example_registry_usage()
297
+ example_adapter_capabilities()
298
+ example_build_commands()
299
+ example_inject_instructions()
300
+ example_inject_agent_context()
301
+ example_parse_response()
302
+ example_runtime_selection()
303
+
304
+ print("\n" + "#" * 60)
305
+ print("# EXAMPLES COMPLETE")
306
+ print("#" * 60 + "\n")
307
+
308
+
309
+ if __name__ == "__main__":
310
+ main()