agentirc-cli 0.9.0__tar.gz → 0.10.1__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 (200) hide show
  1. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/CHANGELOG.md +20 -0
  2. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/PKG-INFO +8 -1
  3. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/README.md +7 -0
  4. agentirc_cli-0.10.1/agentirc/__init__.py +1 -0
  5. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/daemon.py +0 -17
  6. {agentirc_cli-0.9.0/plugins/claude-code/skills/irc → agentirc_cli-0.10.1/agentirc/clients/claude/skill}/SKILL.md +0 -9
  7. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/skill/irc_client.py +1 -9
  8. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/agent_runner.py +57 -36
  9. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/daemon.py +0 -23
  10. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/skill/irc_client.py +1 -9
  11. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/supervisor.py +13 -0
  12. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/agent_runner.py +47 -30
  13. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/daemon.py +0 -23
  14. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/skill/irc_client.py +1 -9
  15. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/supervisor.py +12 -2
  16. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/agent_runner.py +78 -58
  17. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/daemon.py +0 -23
  18. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/skill/irc_client.py +1 -9
  19. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/supervisor.py +12 -0
  20. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/agent-client.md +1 -1
  21. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/agent-harness-spec.md +0 -2
  22. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/clients/claude/configuration.md +3 -2
  23. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/clients/claude/context-management.md +4 -33
  24. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/clients/claude/irc-tools.md +1 -21
  25. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/clients/claude/overview.md +1 -2
  26. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/clients/claude/webhooks.md +2 -2
  27. agentirc_cli-0.10.1/docs/clients/codex/configuration.md +165 -0
  28. agentirc_cli-0.10.1/docs/clients/codex/context-management.md +66 -0
  29. agentirc_cli-0.10.1/docs/clients/codex/irc-tools.md +188 -0
  30. agentirc_cli-0.10.1/docs/clients/codex/overview.md +109 -0
  31. agentirc_cli-0.10.1/docs/clients/codex/setup.md +216 -0
  32. agentirc_cli-0.10.1/docs/clients/codex/supervisor.md +119 -0
  33. agentirc_cli-0.10.1/docs/clients/codex/webhooks.md +91 -0
  34. agentirc_cli-0.10.1/docs/clients/copilot/configuration.md +215 -0
  35. agentirc_cli-0.10.1/docs/clients/copilot/context-management.md +74 -0
  36. agentirc_cli-0.10.1/docs/clients/copilot/irc-tools.md +188 -0
  37. agentirc_cli-0.10.1/docs/clients/copilot/overview.md +135 -0
  38. agentirc_cli-0.10.1/docs/clients/copilot/setup.md +223 -0
  39. agentirc_cli-0.10.1/docs/clients/copilot/supervisor.md +118 -0
  40. agentirc_cli-0.10.1/docs/clients/copilot/webhooks.md +91 -0
  41. agentirc_cli-0.10.1/docs/clients/opencode/configuration.md +183 -0
  42. agentirc_cli-0.10.1/docs/clients/opencode/context-management.md +73 -0
  43. agentirc_cli-0.10.1/docs/clients/opencode/irc-tools.md +186 -0
  44. agentirc_cli-0.10.1/docs/clients/opencode/overview.md +125 -0
  45. agentirc_cli-0.10.1/docs/clients/opencode/setup.md +214 -0
  46. agentirc_cli-0.10.1/docs/clients/opencode/supervisor.md +126 -0
  47. agentirc_cli-0.10.1/docs/clients/opencode/webhooks.md +91 -0
  48. agentirc_cli-0.10.1/docs/codex-backend.md +6 -0
  49. agentirc_cli-0.10.1/docs/copilot-backend.md +6 -0
  50. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/getting-started.md +1 -0
  51. agentirc_cli-0.10.1/docs/grow-your-agent.md +192 -0
  52. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/layer5-agent-harness.md +8 -10
  53. agentirc_cli-0.10.1/docs/opencode-backend.md +6 -0
  54. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/server-architecture.md +1 -1
  55. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases-index.md +1 -1
  56. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/index.md +11 -0
  57. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/daemon.py +0 -8
  58. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/skill/irc_client.py +1 -9
  59. {agentirc_cli-0.9.0/agentirc/clients/claude/skill → agentirc_cli-0.10.1/plugins/claude-code/skills/irc}/SKILL.md +0 -9
  60. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/pyproject.toml +1 -1
  61. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/uv.lock +1 -1
  62. agentirc_cli-0.9.0/agentirc/__init__.py +0 -1
  63. agentirc_cli-0.9.0/docs/codex-backend.md +0 -80
  64. agentirc_cli-0.9.0/docs/copilot-backend.md +0 -90
  65. agentirc_cli-0.9.0/docs/opencode-backend.md +0 -82
  66. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/.github/workflows/pages.yml +0 -0
  67. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/.github/workflows/publish.yml +0 -0
  68. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/.github/workflows/tests.yml +0 -0
  69. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/.gitignore +0 -0
  70. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/.markdownlint-cli2.yaml +0 -0
  71. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/.pr_agent.toml +0 -0
  72. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/CLAUDE.md +0 -0
  73. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/CNAME +0 -0
  74. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/Gemfile +0 -0
  75. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/Gemfile.lock +0 -0
  76. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/LICENSE +0 -0
  77. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/_config.yml +0 -0
  78. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/_sass/color_schemes/anthropic.scss +0 -0
  79. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/_sass/custom/custom.scss +0 -0
  80. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/cli.py +0 -0
  81. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/__init__.py +0 -0
  82. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/__init__.py +0 -0
  83. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/__main__.py +0 -0
  84. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/agent_runner.py +0 -0
  85. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/config.py +0 -0
  86. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/ipc.py +0 -0
  87. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/irc_transport.py +0 -0
  88. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/message_buffer.py +0 -0
  89. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/skill/__init__.py +0 -0
  90. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/socket_server.py +0 -0
  91. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/supervisor.py +0 -0
  92. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/claude/webhook.py +0 -0
  93. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/__init__.py +0 -0
  94. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/config.py +0 -0
  95. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/ipc.py +0 -0
  96. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/irc_transport.py +0 -0
  97. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/message_buffer.py +0 -0
  98. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/skill/SKILL.md +0 -0
  99. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/skill/__init__.py +0 -0
  100. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/socket_server.py +0 -0
  101. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/codex/webhook.py +0 -0
  102. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/__init__.py +0 -0
  103. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/config.py +0 -0
  104. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/ipc.py +0 -0
  105. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/irc_transport.py +0 -0
  106. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/message_buffer.py +0 -0
  107. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/skill/SKILL.md +0 -0
  108. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/skill/__init__.py +0 -0
  109. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/socket_server.py +0 -0
  110. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/copilot/webhook.py +0 -0
  111. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/__init__.py +0 -0
  112. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/config.py +0 -0
  113. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/ipc.py +0 -0
  114. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/irc_transport.py +0 -0
  115. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/message_buffer.py +0 -0
  116. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/skill/SKILL.md +0 -0
  117. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/skill/__init__.py +0 -0
  118. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/socket_server.py +0 -0
  119. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/clients/opencode/webhook.py +0 -0
  120. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/observer.py +0 -0
  121. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/pidfile.py +0 -0
  122. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/protocol/__init__.py +0 -0
  123. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/protocol/commands.py +0 -0
  124. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/protocol/extensions/federation.md +0 -0
  125. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/protocol/extensions/history.md +0 -0
  126. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/protocol/message.py +0 -0
  127. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/protocol/protocol-index.md +0 -0
  128. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/protocol/replies.py +0 -0
  129. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/__init__.py +0 -0
  130. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/__main__.py +0 -0
  131. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/channel.py +0 -0
  132. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/client.py +0 -0
  133. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/config.py +0 -0
  134. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/ircd.py +0 -0
  135. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/remote_client.py +0 -0
  136. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/server_link.py +0 -0
  137. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/skill.py +0 -0
  138. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/skills/__init__.py +0 -0
  139. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/agentirc/server/skills/history.py +0 -0
  140. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/ci.md +0 -0
  141. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/cli.md +0 -0
  142. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/clients/claude/setup.md +0 -0
  143. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/clients/claude/supervisor.md +0 -0
  144. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/design.md +0 -0
  145. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/docs-site.md +0 -0
  146. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/layer1-core-irc.md +0 -0
  147. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/layer2-attention.md +0 -0
  148. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/layer3-skills.md +0 -0
  149. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/layer4-federation.md +0 -0
  150. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/publishing.md +0 -0
  151. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  152. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  153. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  154. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  155. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  156. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/01-pair-programming.md +0 -0
  157. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/02-code-review-ensemble.md +0 -0
  158. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/03-research-deep-dive.md +0 -0
  159. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/04-agent-delegation.md +0 -0
  160. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/05-benchmark-swarm.md +0 -0
  161. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/06-cross-server-ops.md +0 -0
  162. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/07-knowledge-pipeline.md +0 -0
  163. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/08-supervisor-intervention.md +0 -0
  164. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/docs/use-cases/09-apps-as-agents.md +0 -0
  165. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/README.md +0 -0
  166. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/config.py +0 -0
  167. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/ipc.py +0 -0
  168. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/irc_transport.py +0 -0
  169. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/message_buffer.py +0 -0
  170. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/skill/SKILL.md +0 -0
  171. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/socket_server.py +0 -0
  172. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/packages/agent-harness/webhook.py +0 -0
  173. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  174. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/plugins/codex/skills/agentirc-irc/SKILL.md +0 -0
  175. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/__init__.py +0 -0
  176. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/conftest.py +0 -0
  177. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_agent_runner.py +0 -0
  178. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_channel.py +0 -0
  179. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_codex_daemon.py +0 -0
  180. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_connection.py +0 -0
  181. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_copilot_daemon.py +0 -0
  182. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_daemon.py +0 -0
  183. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_daemon_config.py +0 -0
  184. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_discovery.py +0 -0
  185. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_federation.py +0 -0
  186. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_history.py +0 -0
  187. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_integration_layer5.py +0 -0
  188. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_ipc.py +0 -0
  189. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_irc_transport.py +0 -0
  190. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_mentions.py +0 -0
  191. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_message.py +0 -0
  192. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_message_buffer.py +0 -0
  193. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_messaging.py +0 -0
  194. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_modes.py +0 -0
  195. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_opencode_daemon.py +0 -0
  196. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_skill_client.py +0 -0
  197. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_skills.py +0 -0
  198. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_socket_server.py +0 -0
  199. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_supervisor.py +0 -0
  200. {agentirc_cli-0.9.0 → agentirc_cli-0.10.1}/tests/test_webhook.py +0 -0
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/).
6
6
 
7
+ ## [0.10.1] - 2026-03-26
8
+
9
+ ### Added
10
+
11
+ - docs: add Grow Your Agent lifecycle guide
12
+
13
+ ## [0.10.0] - 2026-03-26
14
+
15
+
16
+ ### Added
17
+
18
+ - Client documentation for Codex, OpenCode, and Copilot backends (7 docs each)
19
+
20
+
21
+ ### Changed
22
+
23
+ - Remove set_directory from all backends — agents stay in their init directory
24
+ - Active config isolation for Codex, OpenCode, Copilot (isolated HOME env prevents loading platform home config)
25
+ - Replace single-page backend docs with comprehensive multi-page docs
26
+
7
27
  ## [0.9.0] - 2026-03-25
8
28
 
9
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 0.9.0
3
+ Version: 0.10.1
4
4
  Summary: IRC protocol chatrooms for AI agents (and humans allowed)
5
5
  Project-URL: Homepage, https://github.com/OriNachum/agentirc
6
6
  Author: Ori Nachum
@@ -48,6 +48,9 @@ IRC Protocol ChatRooms for Agents (And humans allowed)
48
48
 
49
49
  > **New here?** See the [Getting Started guide](docs/getting-started.md) for a complete walkthrough
50
50
  > from fresh machine to working setup — server, agents, and human participation.
51
+ >
52
+ > **Want the big picture?** Read [Grow Your Agent](docs/grow-your-agent.md) to understand
53
+ > the agent lifecycle: Plant → Warm → Root → Tend → Prune.
51
54
 
52
55
  ### Install
53
56
 
@@ -131,6 +134,10 @@ uv run pytest -v
131
134
 
132
135
  Full docs at **[agentirc.dev](https://agentirc.dev)** -- or browse below.
133
136
 
137
+ | Guide | Description |
138
+ |---|---|
139
+ | 🌱 **[Grow Your Agent](docs/grow-your-agent.md)** | The agent lifecycle: Plant → Warm → Root → Tend |
140
+
134
141
  <details open>
135
142
  <summary><b>Server Layers</b></summary>
136
143
 
@@ -27,6 +27,9 @@ IRC Protocol ChatRooms for Agents (And humans allowed)
27
27
 
28
28
  > **New here?** See the [Getting Started guide](docs/getting-started.md) for a complete walkthrough
29
29
  > from fresh machine to working setup — server, agents, and human participation.
30
+ >
31
+ > **Want the big picture?** Read [Grow Your Agent](docs/grow-your-agent.md) to understand
32
+ > the agent lifecycle: Plant → Warm → Root → Tend → Prune.
30
33
 
31
34
  ### Install
32
35
 
@@ -110,6 +113,10 @@ uv run pytest -v
110
113
 
111
114
  Full docs at **[agentirc.dev](https://agentirc.dev)** -- or browse below.
112
115
 
116
+ | Guide | Description |
117
+ |---|---|
118
+ | 🌱 **[Grow Your Agent](docs/grow-your-agent.md)** | The agent lifecycle: Plant → Warm → Root → Tend |
119
+
113
120
  <details open>
114
121
  <summary><b>Server Layers</b></summary>
115
122
 
@@ -0,0 +1 @@
1
+ __version__ = "0.10.1"
@@ -299,9 +299,6 @@ class AgentDaemon:
299
299
  elif msg_type == "irc_ask":
300
300
  return await self._ipc_irc_ask(req_id, msg)
301
301
 
302
- elif msg_type == "set_directory":
303
- return await self._ipc_set_directory(req_id, msg)
304
-
305
302
  elif msg_type == "compact":
306
303
  return await self._ipc_compact(req_id)
307
304
 
@@ -395,20 +392,6 @@ class AgentDaemon:
395
392
  # Response matching is TODO
396
393
  return make_response(req_id, ok=True)
397
394
 
398
- async def _ipc_set_directory(self, req_id: str, msg: dict) -> dict:
399
- path = msg.get("path", "")
400
- if not path:
401
- return make_response(req_id, ok=False, error="Missing 'path'")
402
- claude_md = os.path.join(path, "CLAUDE.md")
403
- claude_md_content = None
404
- if os.path.isfile(claude_md):
405
- with open(claude_md) as f:
406
- claude_md_content = f.read()
407
- return make_response(req_id, ok=True, data={
408
- "directory": path,
409
- "claude_md": claude_md_content,
410
- })
411
-
412
395
  async def _ipc_compact(self, req_id: str) -> dict:
413
396
  if self._agent_runner is None or not self._agent_runner.is_running():
414
397
  return make_response(req_id, ok=False, error="Agent runner is not running")
@@ -154,14 +154,6 @@ Sends `/clear` to the agent session via the daemon's prompt queue.
154
154
 
155
155
  ---
156
156
 
157
- ### set-directory — change the agent's working directory
158
-
159
- ```bash
160
- python3 -m agentirc.clients.claude.skill.irc_client set-directory /path/to/project
161
- ```
162
-
163
- ---
164
-
165
157
  ## Whispers
166
158
 
167
159
  The daemon may send unsolicited **whisper** messages to guide the agent.
@@ -193,7 +185,6 @@ result = await client.irc_channels()
193
185
  result = await client.irc_who("#general")
194
186
  result = await client.compact()
195
187
  result = await client.clear()
196
- result = await client.set_directory("/home/agent/project")
197
188
 
198
189
  # Collect whispers queued during the session
199
190
  whispers = client.drain_whispers()
@@ -173,10 +173,6 @@ class SkillClient:
173
173
  """Send /clear to the Claude agent runner."""
174
174
  return await self._request("clear")
175
175
 
176
- async def set_directory(self, directory: str) -> dict[str, Any]:
177
- """Change the working directory for the agent runner."""
178
- return await self._request("set_directory", path=directory)
179
-
180
176
 
181
177
  # ---------------------------------------------------------------------------
182
178
  # CLI
@@ -197,7 +193,7 @@ async def _main(args: list[str]) -> None:
197
193
  if not args:
198
194
  print(
199
195
  "Usage: irc_client.py <subcommand> [args...]\n"
200
- "Subcommands: send, read, ask, join, part, channels, who, compact, clear, set-directory",
196
+ "Subcommands: send, read, ask, join, part, channels, who, compact, clear",
201
197
  file=sys.stderr,
202
198
  )
203
199
  sys.exit(1)
@@ -255,10 +251,6 @@ async def _main(args: list[str]) -> None:
255
251
  elif subcommand == "clear":
256
252
  result = await client.clear()
257
253
 
258
- elif subcommand == "set-directory":
259
- directory = args[1]
260
- result = await client.set_directory(directory)
261
-
262
254
  else:
263
255
  print(f"ERROR: Unknown subcommand: {subcommand!r}", file=sys.stderr)
264
256
  sys.exit(1)
@@ -5,6 +5,9 @@ from __future__ import annotations
5
5
  import asyncio
6
6
  import json
7
7
  import logging
8
+ import os
9
+ import shutil
10
+ import tempfile
8
11
  from typing import Any, Awaitable, Callable
9
12
 
10
13
  logger = logging.getLogger(__name__)
@@ -27,6 +30,7 @@ class CodexAgentRunner:
27
30
  self.on_exit = on_exit
28
31
  self.on_message = on_message
29
32
 
33
+ self._isolated_home: str | None = None
30
34
  self._process: asyncio.subprocess.Process | None = None
31
35
  self._thread_id: str | None = None
32
36
  self._running = False
@@ -50,42 +54,55 @@ class CodexAgentRunner:
50
54
  """Start codex app-server as a subprocess and initialize a thread."""
51
55
  self._stopping = False
52
56
 
53
- # Spawn codex app-server in stdio mode
54
- self._process = await asyncio.create_subprocess_exec(
55
- "codex", "app-server",
56
- stdin=asyncio.subprocess.PIPE,
57
- stdout=asyncio.subprocess.PIPE,
58
- stderr=asyncio.subprocess.DEVNULL,
59
- )
60
-
61
- # Start reading responses
62
- self._reader_task = asyncio.create_task(self._read_loop())
63
-
64
- # Initialize
65
- resp = await self._send_request("initialize", {
66
- "clientInfo": {"name": "agentirc-codex", "version": "0.1.0"},
67
- })
68
- logger.info("Codex initialized: %s", resp)
69
-
70
- # Start a thread
71
- resp = await self._send_request("thread/start", {
72
- "cwd": self.directory,
73
- "model": self.model,
74
- "approvalPolicy": "never",
75
- "baseInstructions": self.system_prompt or None,
76
- })
77
-
78
- logger.info("Codex thread/start raw response: %s", json.dumps(resp)[:500])
79
- thread = resp.get("result", {}).get("thread", {})
80
- self._thread_id = thread.get("id")
81
- self._running = True
82
- logger.info("Codex thread started: %s", self._thread_id)
83
-
84
- # Start the prompt processing loop
85
- self._task = asyncio.create_task(self._prompt_loop())
86
-
87
- if initial_prompt:
88
- await self.send_prompt(initial_prompt)
57
+ # Isolate from host config (~/.codex/, XDG, etc.)
58
+ self._isolated_home = tempfile.mkdtemp(prefix="agentirc-codex-")
59
+ isolated_env = dict(os.environ)
60
+ isolated_env["HOME"] = self._isolated_home
61
+ isolated_env.pop("CODEX_HOME", None)
62
+ isolated_env.pop("XDG_CONFIG_HOME", None)
63
+
64
+ try:
65
+ # Spawn codex app-server in stdio mode
66
+ self._process = await asyncio.create_subprocess_exec(
67
+ "codex", "app-server",
68
+ stdin=asyncio.subprocess.PIPE,
69
+ stdout=asyncio.subprocess.PIPE,
70
+ stderr=asyncio.subprocess.DEVNULL,
71
+ env=isolated_env,
72
+ )
73
+
74
+ # Start reading responses
75
+ self._reader_task = asyncio.create_task(self._read_loop())
76
+
77
+ # Initialize
78
+ resp = await self._send_request("initialize", {
79
+ "clientInfo": {"name": "agentirc-codex", "version": "0.1.0"},
80
+ })
81
+ logger.info("Codex initialized: %s", resp)
82
+
83
+ # Start a thread
84
+ resp = await self._send_request("thread/start", {
85
+ "cwd": self.directory,
86
+ "model": self.model,
87
+ "approvalPolicy": "never",
88
+ "baseInstructions": self.system_prompt or None,
89
+ })
90
+
91
+ logger.info("Codex thread/start raw response: %s", json.dumps(resp)[:500])
92
+ thread = resp.get("result", {}).get("thread", {})
93
+ self._thread_id = thread.get("id")
94
+ self._running = True
95
+ logger.info("Codex thread started: %s", self._thread_id)
96
+
97
+ # Start the prompt processing loop
98
+ self._task = asyncio.create_task(self._prompt_loop())
99
+
100
+ if initial_prompt:
101
+ await self.send_prompt(initial_prompt)
102
+ except Exception:
103
+ shutil.rmtree(self._isolated_home, ignore_errors=True)
104
+ self._isolated_home = None
105
+ raise
89
106
 
90
107
  async def stop(self) -> None:
91
108
  """Stop the codex app-server."""
@@ -122,6 +139,10 @@ class CodexAgentRunner:
122
139
  future.set_exception(ConnectionError("Runner stopped"))
123
140
  self._pending.clear()
124
141
 
142
+ if self._isolated_home:
143
+ shutil.rmtree(self._isolated_home, ignore_errors=True)
144
+ self._isolated_home = None
145
+
125
146
  async def send_prompt(self, text: str) -> None:
126
147
  """Queue a prompt for the agent."""
127
148
  await self._prompt_queue.put(text)
@@ -327,9 +327,6 @@ class CodexDaemon:
327
327
  elif msg_type == "irc_ask":
328
328
  return await self._ipc_irc_ask(req_id, msg)
329
329
 
330
- elif msg_type == "set_directory":
331
- return await self._ipc_set_directory(req_id, msg)
332
-
333
330
  elif msg_type == "compact":
334
331
  return await self._ipc_compact(req_id)
335
332
 
@@ -423,26 +420,6 @@ class CodexDaemon:
423
420
  # Response matching is TODO
424
421
  return make_response(req_id, ok=True)
425
422
 
426
- async def _ipc_set_directory(self, req_id: str, msg: dict) -> dict:
427
- path = msg.get("path", "")
428
- if not path:
429
- return make_response(req_id, ok=False, error="Missing 'path'")
430
- new_cwd = os.path.abspath(path)
431
- if not os.path.isdir(new_cwd):
432
- return make_response(req_id, ok=False, error=f"Not a directory: {new_cwd}")
433
- # Update the daemon's working directory
434
- self.agent.directory = new_cwd
435
- # Check for AGENTS.md (Codex equivalent of CLAUDE.md)
436
- agents_md = os.path.join(new_cwd, "AGENTS.md")
437
- agents_md_content = None
438
- if os.path.isfile(agents_md):
439
- with open(agents_md) as f:
440
- agents_md_content = f.read()
441
- return make_response(req_id, ok=True, data={
442
- "directory": new_cwd,
443
- "agents_md": agents_md_content,
444
- })
445
-
446
423
  async def _ipc_compact(self, req_id: str) -> dict:
447
424
  if self._agent_runner is None or not self._agent_runner.is_running():
448
425
  return make_response(req_id, ok=False, error="Agent runner is not running")
@@ -173,10 +173,6 @@ class SkillClient:
173
173
  """Send /clear to the Codex agent runner."""
174
174
  return await self._request("clear")
175
175
 
176
- async def set_directory(self, directory: str) -> dict[str, Any]:
177
- """Change the working directory for the agent runner."""
178
- return await self._request("set_directory", path=directory)
179
-
180
176
 
181
177
  # ---------------------------------------------------------------------------
182
178
  # CLI
@@ -197,7 +193,7 @@ async def _main(args: list[str]) -> None:
197
193
  if not args:
198
194
  print(
199
195
  "Usage: irc_client.py <subcommand> [args...]\n"
200
- "Subcommands: send, read, ask, join, part, channels, who, compact, clear, set-directory",
196
+ "Subcommands: send, read, ask, join, part, channels, who, compact, clear",
201
197
  file=sys.stderr,
202
198
  )
203
199
  sys.exit(1)
@@ -255,10 +251,6 @@ async def _main(args: list[str]) -> None:
255
251
  elif subcommand == "clear":
256
252
  result = await client.clear()
257
253
 
258
- elif subcommand == "set-directory":
259
- directory = args[1]
260
- result = await client.set_directory(directory)
261
-
262
254
  else:
263
255
  print(f"ERROR: Unknown subcommand: {subcommand!r}", file=sys.stderr)
264
256
  sys.exit(1)
@@ -4,6 +4,9 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import logging
7
+ import os
8
+ import shutil
9
+ import tempfile
7
10
  from dataclasses import dataclass
8
11
  from typing import Any, Awaitable, Callable
9
12
 
@@ -85,6 +88,13 @@ class CodexSupervisor:
85
88
  transcript = self._format_transcript()
86
89
  prompt = SUPERVISOR_PROMPT.format(transcript=transcript)
87
90
 
91
+ # Isolate from host config (~/.codex/, XDG, etc.)
92
+ isolated_home = tempfile.mkdtemp(prefix="agentirc-codex-sv-")
93
+ isolated_env = dict(os.environ)
94
+ isolated_env["HOME"] = isolated_home
95
+ isolated_env.pop("CODEX_HOME", None)
96
+ isolated_env.pop("XDG_CONFIG_HOME", None)
97
+
88
98
  proc = None
89
99
  try:
90
100
  proc = await asyncio.create_subprocess_exec(
@@ -92,6 +102,7 @@ class CodexSupervisor:
92
102
  stdin=asyncio.subprocess.PIPE,
93
103
  stdout=asyncio.subprocess.PIPE,
94
104
  stderr=asyncio.subprocess.DEVNULL,
105
+ env=isolated_env,
95
106
  )
96
107
  stdout, _ = await asyncio.wait_for(
97
108
  proc.communicate(prompt.encode()),
@@ -116,6 +127,8 @@ class CodexSupervisor:
116
127
  pass
117
128
  await proc.wait()
118
129
  return
130
+ finally:
131
+ shutil.rmtree(isolated_home, ignore_errors=True)
119
132
 
120
133
  if verdict.action == "ESCALATION":
121
134
  self._escalation_count += 1
@@ -4,6 +4,9 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import logging
7
+ import os
8
+ import shutil
9
+ import tempfile
7
10
  from typing import Any, Awaitable, Callable
8
11
 
9
12
  logger = logging.getLogger(__name__)
@@ -28,6 +31,7 @@ class CopilotAgentRunner:
28
31
  self.on_exit = on_exit
29
32
  self.on_message = on_message
30
33
 
34
+ self._isolated_home: str | None = None
31
35
  self._client: Any = None
32
36
  self._session: Any = None
33
37
  self._session_id: str | None = None
@@ -50,41 +54,50 @@ class CopilotAgentRunner:
50
54
  # Lazy import — github-copilot-sdk is only needed at runtime
51
55
  from copilot import CopilotClient, PermissionHandler, SubprocessConfig
52
56
 
53
- # Create and start the CopilotClient (spawns copilot CLI process)
54
- subprocess_config = SubprocessConfig(cwd=self.directory)
55
- self._client = CopilotClient(config=subprocess_config)
56
- await self._client.start()
57
+ # Isolate from host config
58
+ self._isolated_home = tempfile.mkdtemp(prefix="agentirc-copilot-")
59
+ isolated_env = {**os.environ, "HOME": self._isolated_home}
60
+ isolated_env.pop("XDG_CONFIG_HOME", None)
57
61
 
58
- # Create a session with model and permissions.
59
- # Wrap in try/except so a partial start doesn't leak the CLI process.
60
62
  try:
61
- session_kwargs: dict[str, Any] = {
62
- "on_permission_request": PermissionHandler.approve_all,
63
- "model": self.model,
64
- }
65
- if self.system_prompt:
66
- session_kwargs["system_message"] = {"content": self.system_prompt}
67
- if self.skill_directories:
68
- session_kwargs["skill_directories"] = self.skill_directories
69
-
70
- self._session = await self._client.create_session(**session_kwargs)
71
- except Exception:
72
- await self._client.stop()
73
- self._client = None
74
- raise
75
- self._session_id = getattr(self._session, "id", None)
76
- self._running = True
63
+ # Create and start the CopilotClient (spawns copilot CLI process)
64
+ subprocess_config = SubprocessConfig(cwd=self.directory, env=isolated_env)
65
+ self._client = CopilotClient(config=subprocess_config)
66
+ await self._client.start()
67
+
68
+ # Create a session with model and permissions.
69
+ try:
70
+ session_kwargs: dict[str, Any] = {
71
+ "on_permission_request": PermissionHandler.approve_all,
72
+ "model": self.model,
73
+ }
74
+ if self.system_prompt:
75
+ session_kwargs["system_message"] = {"content": self.system_prompt}
76
+ if self.skill_directories:
77
+ session_kwargs["skill_directories"] = self.skill_directories
78
+
79
+ self._session = await self._client.create_session(**session_kwargs)
80
+ except Exception:
81
+ await self._client.stop()
82
+ self._client = None
83
+ raise
84
+ self._session_id = getattr(self._session, "id", None)
85
+ self._running = True
77
86
 
78
- logger.info(
79
- "CopilotAgentRunner started (model=%s, session=%s)",
80
- self.model, self._session_id,
81
- )
87
+ logger.info(
88
+ "CopilotAgentRunner started (model=%s, session=%s)",
89
+ self.model, self._session_id,
90
+ )
82
91
 
83
- # Start the prompt processing loop
84
- self._task = asyncio.create_task(self._prompt_loop())
92
+ # Start the prompt processing loop
93
+ self._task = asyncio.create_task(self._prompt_loop())
85
94
 
86
- if initial_prompt:
87
- await self.send_prompt(initial_prompt)
95
+ if initial_prompt:
96
+ await self.send_prompt(initial_prompt)
97
+ except Exception:
98
+ shutil.rmtree(self._isolated_home, ignore_errors=True)
99
+ self._isolated_home = None
100
+ raise
88
101
 
89
102
  async def stop(self) -> None:
90
103
  """Stop the Copilot session and client."""
@@ -113,6 +126,10 @@ class CopilotAgentRunner:
113
126
  logger.debug("Client stop error (ignoring)", exc_info=True)
114
127
  self._client = None
115
128
 
129
+ if self._isolated_home:
130
+ shutil.rmtree(self._isolated_home, ignore_errors=True)
131
+ self._isolated_home = None
132
+
116
133
  async def send_prompt(self, text: str) -> None:
117
134
  """Queue a prompt for the agent."""
118
135
  await self._prompt_queue.put(text)
@@ -334,9 +334,6 @@ class CopilotDaemon:
334
334
  elif msg_type == "irc_ask":
335
335
  return await self._ipc_irc_ask(req_id, msg)
336
336
 
337
- elif msg_type == "set_directory":
338
- return await self._ipc_set_directory(req_id, msg)
339
-
340
337
  elif msg_type == "compact":
341
338
  return await self._ipc_compact(req_id)
342
339
 
@@ -430,26 +427,6 @@ class CopilotDaemon:
430
427
  # Response matching is TODO
431
428
  return make_response(req_id, ok=True)
432
429
 
433
- async def _ipc_set_directory(self, req_id: str, msg: dict) -> dict:
434
- path = msg.get("path", "")
435
- if not path:
436
- return make_response(req_id, ok=False, error="Missing 'path'")
437
- new_cwd = os.path.abspath(path)
438
- if not os.path.isdir(new_cwd):
439
- return make_response(req_id, ok=False, error=f"Not a directory: {new_cwd}")
440
- # Update the daemon's working directory
441
- self.agent.directory = new_cwd
442
- # Check for .github/copilot-instructions.md (Copilot's project instructions)
443
- copilot_instructions = os.path.join(new_cwd, ".github", "copilot-instructions.md")
444
- instructions_content = None
445
- if os.path.isfile(copilot_instructions):
446
- with open(copilot_instructions) as f:
447
- instructions_content = f.read()
448
- return make_response(req_id, ok=True, data={
449
- "directory": new_cwd,
450
- "copilot_instructions": instructions_content,
451
- })
452
-
453
430
  async def _ipc_compact(self, req_id: str) -> dict:
454
431
  if self._agent_runner is None or not self._agent_runner.is_running():
455
432
  return make_response(req_id, ok=False, error="Agent runner is not running")
@@ -173,10 +173,6 @@ class SkillClient:
173
173
  """Send /clear to the Copilot agent runner."""
174
174
  return await self._request("clear")
175
175
 
176
- async def set_directory(self, directory: str) -> dict[str, Any]:
177
- """Change the working directory for the agent runner."""
178
- return await self._request("set_directory", path=directory)
179
-
180
176
 
181
177
  # ---------------------------------------------------------------------------
182
178
  # CLI
@@ -197,7 +193,7 @@ async def _main(args: list[str]) -> None:
197
193
  if not args:
198
194
  print(
199
195
  "Usage: irc_client.py <subcommand> [args...]\n"
200
- "Subcommands: send, read, ask, join, part, channels, who, compact, clear, set-directory",
196
+ "Subcommands: send, read, ask, join, part, channels, who, compact, clear",
201
197
  file=sys.stderr,
202
198
  )
203
199
  sys.exit(1)
@@ -255,10 +251,6 @@ async def _main(args: list[str]) -> None:
255
251
  elif subcommand == "clear":
256
252
  result = await client.clear()
257
253
 
258
- elif subcommand == "set-directory":
259
- directory = args[1]
260
- result = await client.set_directory(directory)
261
-
262
254
  else:
263
255
  print(f"ERROR: Unknown subcommand: {subcommand!r}", file=sys.stderr)
264
256
  sys.exit(1)
@@ -4,6 +4,9 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import logging
7
+ import os
8
+ import shutil
9
+ import tempfile
7
10
  from dataclasses import dataclass
8
11
  from typing import Any, Awaitable, Callable
9
12
 
@@ -85,11 +88,16 @@ class CopilotSupervisor:
85
88
  transcript = self._format_transcript()
86
89
  prompt = SUPERVISOR_PROMPT.format(transcript=transcript)
87
90
 
91
+ # Isolate from host config
92
+ isolated_home = tempfile.mkdtemp(prefix="agentirc-copilot-sv-")
93
+
88
94
  try:
89
- from copilot import CopilotClient
95
+ from copilot import CopilotClient, SubprocessConfig
90
96
  from copilot.session import PermissionHandler
91
97
 
92
- client = CopilotClient()
98
+ isolated_env = {**os.environ, "HOME": isolated_home}
99
+ subprocess_config = SubprocessConfig(env=isolated_env)
100
+ client = CopilotClient(config=subprocess_config)
93
101
  await client.start()
94
102
  try:
95
103
  session = await client.create_session(
@@ -117,6 +125,8 @@ class CopilotSupervisor:
117
125
  except Exception:
118
126
  logger.exception("Copilot supervisor evaluation failed")
119
127
  return
128
+ finally:
129
+ shutil.rmtree(isolated_home, ignore_errors=True)
120
130
 
121
131
  if verdict.action == "ESCALATION":
122
132
  self._escalation_count += 1