agent-shell-py 0.4.0__tar.gz → 0.5.0__tar.gz

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 (183) hide show
  1. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/.github/workflows/build.yml +13 -2
  2. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/.github/workflows/ci.yml +15 -2
  3. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/.gitignore +9 -0
  4. agent_shell_py-0.5.0/AGENTS.md +115 -0
  5. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/PKG-INFO +1 -1
  6. agent_shell_py-0.5.0/docs/architecture/class_diagram.md +501 -0
  7. agent_shell_py-0.5.0/docs/architecture/dependency_boundaries.md +88 -0
  8. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/docs/development/agent_parameter_comparison.md +113 -1
  9. agent_shell_py-0.5.0/docs/development/import_linter_audit.md +79 -0
  10. agent_shell_py-0.5.0/docs/development/issue_25_plan.md +64 -0
  11. agent_shell_py-0.5.0/docs/development/package_management.md +64 -0
  12. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/docs/examples.md +138 -1
  13. agent_shell_py-0.5.0/pyproject.toml +133 -0
  14. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/__init__.py +4 -1
  15. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/_version.py +2 -2
  16. agent_shell_py-0.5.0/src/agent_shell/adapters/agent_adapter_protocol.py +3 -0
  17. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/claude_code_adapter.py +46 -30
  18. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/codex_adapter.py +25 -29
  19. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/copilot_cli_adapter.py +38 -33
  20. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/cursor_adapter.py +31 -30
  21. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/grok_adapter.py +27 -27
  22. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/opencode_adapter.py +37 -31
  23. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/pi_adapter.py +76 -30
  24. agent_shell_py-0.5.0/src/agent_shell/adapters/pi_resources.py +97 -0
  25. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/response.py +15 -3
  26. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/tool_denial.py +6 -0
  27. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/execution.py +7 -79
  28. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/interactive.py +43 -34
  29. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/interactive_terminal.py +117 -64
  30. agent_shell_py-0.5.0/src/agent_shell/models/resources.py +25 -0
  31. agent_shell_py-0.5.0/src/agent_shell/ports/__init__.py +1 -0
  32. agent_shell_py-0.4.0/src/agent_shell/adapters/agent_adapter_protocol.py → agent_shell_py-0.5.0/src/agent_shell/ports/agent.py +7 -2
  33. agent_shell_py-0.5.0/src/agent_shell/ports/execution.py +84 -0
  34. agent_shell_py-0.5.0/src/agent_shell/ports/interactive.py +68 -0
  35. agent_shell_py-0.5.0/src/agent_shell/ports/resources.py +28 -0
  36. agent_shell_py-0.5.0/src/agent_shell/resources.py +162 -0
  37. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/shell.py +65 -33
  38. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/tmux.py +101 -1
  39. agent_shell_py-0.5.0/tests/e2e/test_interactive_attachment_e2e.py +60 -0
  40. agent_shell_py-0.5.0/tests/e2e/test_session_resources_e2e.py +190 -0
  41. agent_shell_py-0.5.0/tests/integration/test_architecture.py +296 -0
  42. agent_shell_py-0.5.0/tests/integration/test_interactive_attachment.py +342 -0
  43. agent_shell_py-0.5.0/tests/integration/test_session_resources.py +778 -0
  44. agent_shell_py-0.5.0/tests/unit/test_interactive_attachment.py +93 -0
  45. agent_shell_py-0.5.0/tests/unit/test_port_exports.py +36 -0
  46. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_shell.py +10 -10
  47. agent_shell_py-0.5.0/tests/unit/test_shell_cancellation.py +32 -0
  48. agent_shell_py-0.5.0/uv.lock +244 -0
  49. agent_shell_py-0.4.0/AGENTS.md +0 -310
  50. agent_shell_py-0.4.0/docs/development/package_management.md +0 -24
  51. agent_shell_py-0.4.0/pyproject.toml +0 -33
  52. agent_shell_py-0.4.0/tests/unit/test_shell_cancellation.py +0 -72
  53. agent_shell_py-0.4.0/uv.lock +0 -104
  54. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/.github/workflows/publish.yml +0 -0
  55. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/.python-version +0 -0
  56. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/LICENSE +0 -0
  57. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/README.md +0 -0
  58. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/docs/assets/agentshell-banner.png +0 -0
  59. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/docs/assets/agentshell-banner.svg +0 -0
  60. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/docs/development/disabled_tools.md +0 -0
  61. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/docs/development/info.md +0 -0
  62. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/docs/development/total_token_count.md +0 -0
  63. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/examples/interactive_demo.py +0 -0
  64. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/skills/delegating-code-review/SKILL.md +0 -0
  65. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/skills/invoking-cli-agents/SKILL.md +0 -0
  66. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/skills/invoking-cli-agents/api-reference.md +0 -0
  67. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/__init__.py +0 -0
  68. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/health.py +0 -0
  69. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/model_discovery.py +0 -0
  70. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/outcome.py +0 -0
  71. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/process_failure.py +0 -0
  72. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/adapters/stderr_format.py +0 -0
  73. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/herdr.py +0 -0
  74. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/herdr_protocol.py +0 -0
  75. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/herdr_worker.py +0 -0
  76. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/interactive_event_writer.py +0 -0
  77. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/interactive_worker.py +0 -0
  78. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/models/__init__.py +0 -0
  79. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/models/agent.py +0 -0
  80. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/process_cleanup.py +0 -0
  81. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/process_guardian.py +0 -0
  82. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/terminal_protocol.py +0 -0
  83. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/terminal_window.py +0 -0
  84. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/terminal_worker.py +0 -0
  85. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/tmux_bridge.py +0 -0
  86. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/tmux_ownership.py +0 -0
  87. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/src/agent_shell/tmux_protocol.py +0 -0
  88. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/__init__.py +0 -0
  89. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/conftest.py +0 -0
  90. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/__init__.py +0 -0
  91. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_claude_code_e2e.py +0 -0
  92. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_codex_e2e.py +0 -0
  93. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_copilot_cli_e2e.py +0 -0
  94. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_cursor_e2e.py +0 -0
  95. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_execution_host_e2e.py +0 -0
  96. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_grok_e2e.py +0 -0
  97. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_health_check_e2e.py +0 -0
  98. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_interactive_harness_e2e.py +0 -0
  99. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_model_discovery_e2e.py +0 -0
  100. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_opencode_e2e.py +0 -0
  101. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_pi_e2e.py +0 -0
  102. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_pi_packages_e2e.py +0 -0
  103. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_terminal_window_execution_host_e2e.py +0 -0
  104. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/e2e/test_tmux_execution_host_e2e.py +0 -0
  105. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/__init__.py +0 -0
  106. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_claude_code_integration.py +0 -0
  107. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_claude_code_mcp_integration.py +0 -0
  108. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_codex_integration.py +0 -0
  109. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_codex_mcp_integration.py +0 -0
  110. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_copilot_cli_integration.py +0 -0
  111. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_copilot_cli_mcp_integration.py +0 -0
  112. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_cursor_integration.py +0 -0
  113. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_cursor_mcp_integration.py +0 -0
  114. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_execution_host.py +0 -0
  115. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_grok_integration.py +0 -0
  116. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_grok_mcp_integration.py +0 -0
  117. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_health_check_integration.py +0 -0
  118. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_herdr_execution_host.py +0 -0
  119. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_interactive_agents.py +0 -0
  120. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_interactive_terminal.py +0 -0
  121. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_model_discovery_integration.py +0 -0
  122. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_opencode_integration.py +0 -0
  123. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_opencode_mcp_integration.py +0 -0
  124. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_packages_unsupported.py +0 -0
  125. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_pi_integration.py +0 -0
  126. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_pi_mcp_integration.py +0 -0
  127. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_pi_packages.py +0 -0
  128. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_process_lifecycle.py +0 -0
  129. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_terminal_window_execution_host.py +0 -0
  130. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/integration/test_tmux_execution_host.py +0 -0
  131. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/__init__.py +0 -0
  132. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/adapter_matrix.py +0 -0
  133. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/codex_fixtures.py +0 -0
  134. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/copilot_fixtures.py +0 -0
  135. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/cursor_fixtures.py +0 -0
  136. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/fixtures.py +0 -0
  137. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/grok_fixtures.py +0 -0
  138. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/opencode_fixtures.py +0 -0
  139. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/pi_fixtures.py +0 -0
  140. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_adapter_transport.py +0 -0
  141. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_cancel.py +0 -0
  142. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_codex_cancel.py +0 -0
  143. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_codex_execute.py +0 -0
  144. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_codex_parse_event.py +0 -0
  145. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_codex_warnings.py +0 -0
  146. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_copilot_cli_cancel.py +0 -0
  147. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_copilot_cli_execute.py +0 -0
  148. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_copilot_cli_parse_event.py +0 -0
  149. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_copilot_cli_stream.py +0 -0
  150. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_cursor_cancel.py +0 -0
  151. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_cursor_execute.py +0 -0
  152. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_cursor_parse_event.py +0 -0
  153. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_cursor_warnings.py +0 -0
  154. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_execute.py +0 -0
  155. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_execute_outcome.py +0 -0
  156. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_grok_cancel.py +0 -0
  157. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_grok_execute.py +0 -0
  158. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_grok_parse_event.py +0 -0
  159. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_grok_warnings.py +0 -0
  160. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_health_probe.py +0 -0
  161. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_mcp_server_spec.py +0 -0
  162. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_model_discovery.py +0 -0
  163. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_models.py +0 -0
  164. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_opencode_cancel.py +0 -0
  165. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_opencode_execute.py +0 -0
  166. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_opencode_parse_event.py +0 -0
  167. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_opencode_spawn.py +0 -0
  168. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_opencode_stream.py +0 -0
  169. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_package_spec.py +0 -0
  170. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_parse_event.py +0 -0
  171. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_pi_cancel.py +0 -0
  172. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_pi_execute.py +0 -0
  173. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_pi_parse_event.py +0 -0
  174. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_pi_warnings.py +0 -0
  175. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_process_cleanup.py +0 -0
  176. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_process_group_registration.py +0 -0
  177. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_public_exports.py +0 -0
  178. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_response_aggregation.py +0 -0
  179. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_shell_mcp.py +0 -0
  180. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_stderr_format.py +0 -0
  181. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_stream.py +0 -0
  182. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_terminal_window_execution_host.py +0 -0
  183. {agent_shell_py-0.4.0 → agent_shell_py-0.5.0}/tests/unit/test_tool_denial.py +0 -0
@@ -4,6 +4,13 @@ on:
4
4
  push:
5
5
  tags: ["v*"]
6
6
 
7
+ permissions:
8
+ contents: read
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
7
14
  jobs:
8
15
  build:
9
16
  runs-on: ubuntu-latest
@@ -12,6 +19,7 @@ jobs:
12
19
  - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
13
20
  with:
14
21
  fetch-depth: 0
22
+ persist-credentials: false
15
23
 
16
24
  - name: Install uv
17
25
  uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
@@ -20,10 +28,13 @@ jobs:
20
28
  run: uv python install 3.12
21
29
 
22
30
  - name: Install dependencies
23
- run: uv sync --group dev && uv pip install -e .
31
+ run: uv sync --locked --group dev
32
+
33
+ - name: Check architecture boundaries
34
+ run: uv run --no-sync lint-imports --no-cache
24
35
 
25
36
  - name: Run unit and integration tests
26
- run: uv run pytest tests/unit tests/integration -v
37
+ run: uv run --no-sync pytest tests/unit tests/integration -v
27
38
 
28
39
  - name: Build package
29
40
  run: uv build
@@ -6,15 +6,25 @@ on:
6
6
  pull_request:
7
7
  branches: [main]
8
8
 
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
9
16
  jobs:
10
17
  test:
11
18
  runs-on: ubuntu-latest
12
19
  strategy:
20
+ fail-fast: false
13
21
  matrix:
14
22
  python-version: ["3.12"]
15
23
 
16
24
  steps:
17
25
  - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
26
+ with:
27
+ persist-credentials: false
18
28
 
19
29
  - name: Install uv
20
30
  uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
@@ -23,7 +33,10 @@ jobs:
23
33
  run: uv python install ${{ matrix.python-version }}
24
34
 
25
35
  - name: Install dependencies
26
- run: uv sync --group dev && uv pip install -e .
36
+ run: uv sync --locked --group dev
37
+
38
+ - name: Check architecture boundaries
39
+ run: uv run --no-sync lint-imports --no-cache
27
40
 
28
41
  - name: Run unit and integration tests
29
- run: uv run pytest tests/unit tests/integration -v
42
+ run: uv run --no-sync pytest tests/unit tests/integration -v
@@ -9,3 +9,12 @@ src/agent_shell/_version.py
9
9
 
10
10
  # Virtual environments
11
11
  .venv
12
+
13
+ # Local Pi workspace data
14
+ /.pi/
15
+
16
+ # Local credentials
17
+ /.env
18
+
19
+ # Local SonarQube configuration and scanner output
20
+ /.sonarqube/
@@ -0,0 +1,115 @@
1
+ # Agent Shell
2
+
3
+ A lightweight, async Python package that executes CLI coding agents headlessly and returns output
4
+ through a unified interface. Each agent's CLI differences are hidden behind a common adapter
5
+ protocol, so consuming code never changes regardless of which agent is running underneath.
6
+
7
+ ## Architecture
8
+
9
+ Before any planning, discussion of solution or code change work begins, you must read the
10
+ [architecture class diagram](docs/architecture/class_diagram.md). It documents the interfaces,
11
+ execution hosts, isolation policies, interactive sessions, and API behaviour.
12
+
13
+ Keep agent-specific CLI flags, raw output parsing, configuration formats, and workarounds in
14
+ that agent's adapter or agent-specific helpers. Shared code must use protocols and normalised
15
+ models, not agent-name branches, concrete-adapter checks, private adapter state, or copied
16
+ agent-specific logic. Host-specific terminal/process details belong in execution hosts.
17
+ Concrete agent-adapter imports are permitted only in `shell.py` for construction/selection;
18
+ shared helpers under `adapters/` are not exempt. Import Linter contracts in `pyproject.toml`
19
+ enforce the [dependency boundaries](docs/architecture/dependency_boundaries.md), including
20
+ indirect imports. New inner code uses `ports/`, not implementation-bearing compatibility
21
+ facades. New top-level modules and adapter helpers must be classified in the contracts.
22
+ Review must still catch copied agent-specific logic and dynamic imports.
23
+ If a shared contract cannot express a feature, discuss the boundary change before adding a
24
+ workaround or weakening the test.
25
+
26
+ ## Supported Agents
27
+
28
+ - [x] Claude Code
29
+ - [x] OpenCode
30
+ - [x] Copilot CLI
31
+ - [x] Codex
32
+ - [x] Pi
33
+ - [x] Cursor
34
+ - [x] Grok
35
+
36
+ ## MCP Server Configuration
37
+
38
+ `AgentShell` exposes a unified API for registering MCP servers across all supported agents:
39
+
40
+ ```python
41
+ from agent_shell.shell import AgentShell
42
+ from agent_shell.models.agent import AgentType, MCPServerSpec, MCPServerType
43
+
44
+ shell = AgentShell(agent_type=AgentType.CLAUDE_CODE)
45
+
46
+ await shell.add_mcp_server(MCPServerSpec(
47
+ name="forgetful",
48
+ type=MCPServerType.STDIO,
49
+ command="uvx",
50
+ args=["forgetful-ai"],
51
+ env={"FORGETFUL_API_KEY": "..."},
52
+ ))
53
+ ```
54
+
55
+ All adapters write to user-scope configuration:
56
+
57
+ | Agent | Mechanism | Location |
58
+ |-------|-----------|----------|
59
+ | Claude Code | `claude mcp add --scope user` subprocess | `~/.claude.json` (managed by CLI) |
60
+ | OpenCode | direct JSON file write | `~/.config/opencode/opencode.json` |
61
+ | Copilot CLI | direct JSON file write | `~/.copilot/mcp-config.json` |
62
+ | Codex | `codex mcp add` subprocess | Codex config |
63
+ | Cursor | direct JSON file write | `~/.cursor/mcp.json` |
64
+ | Grok | `grok mcp add --scope user` subprocess | `~/.grok/config.toml` (managed by CLI) |
65
+
66
+ Adds are idempotent (update existing entries with the same name). Cursor preserves native fields
67
+ that `MCPServerSpec` cannot represent when an update keeps the same transport, and writes its file
68
+ atomically with user-only permissions. Removes warn rather than raise when the named server is not
69
+ found. Claude Code listing reads the user-scope `mcpServers`
70
+ entries from `~/.claude.json` directly, avoiding the health checks and human-readable output of
71
+ `claude mcp list`. Cursor manages user-scope MCP entries directly in `~/.cursor/mcp.json` because
72
+ its `mcp` subcommands have no add/remove commands. Grok listing reads user-scope `mcp_servers`
73
+ entries from `~/.grok/config.toml` directly for the same reason. Pi's MCP add/remove/list methods
74
+ raise `NotImplementedError`.
75
+
76
+ ## Package Management
77
+
78
+ See [package management](docs/development/package_management.md) for the API, Pi behaviour,
79
+ scope, and validation details.
80
+
81
+ ## Test Philosophy
82
+
83
+ Tests validate real functionality, not code coverage metrics. Three tiers, each with a distinct
84
+ purpose:
85
+
86
+ | Tier | Scope | Runs in CI | Real CLI calls |
87
+ |------|-------|-----------|----------------|
88
+ | **Unit** | Isolated parsing, adapter resolution, input validation | Yes | No |
89
+ | **Integration** | Shell -> adapter -> parser, with mocked agent subprocess | Yes | No |
90
+ | **E2E** | Real CLI calls; usually real API costs | No (local only) | Yes |
91
+
92
+ The model-discovery E2E test is the exception: it calls all seven real CLIs but only reads
93
+ metadata, so it sends no inference request and incurs no model-token cost.
94
+
95
+ Integration tests mirror the E2E tests but substitute mocked subprocesses emitting captured CLI
96
+ output fixtures. This lets CI validate the full class interaction chain without credentials or API
97
+ spend. E2E tests remain local smoke tests for the real agents.
98
+
99
+ All tests follow the **AAA pattern** (Arrange, Act, Assert).
100
+
101
+ ```bash
102
+ # Architecture contracts (development dependency only)
103
+ uv run --locked lint-imports --no-cache
104
+
105
+ # CI suite (unit + integration, including deliberate boundary violations in temp copies)
106
+ uv run --locked pytest tests/unit tests/integration -v
107
+
108
+ # Full suite including E2E (requires agent CLI + credentials)
109
+ uv run pytest -v
110
+ ```
111
+
112
+ ## CI/CD
113
+
114
+ - **CI**: Runs architecture contracts and unit + integration tests on every push and PR
115
+ - **Build**: Triggers on `v*` tags, runs contracts/tests then builds release artifacts
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agent-shell-py
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: A lightweight abstraction for executing CLI coding agents headlessly
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE