agentirc-cli 0.15.2__tar.gz → 0.16.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 (231) hide show
  1. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/.pr_agent.toml +1 -1
  2. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/CHANGELOG.md +15 -0
  3. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/CLAUDE.md +1 -1
  4. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/PKG-INFO +5 -2
  5. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/README.md +4 -1
  6. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/cli.py +66 -38
  7. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/agent_runner.py +31 -18
  8. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/config.py +4 -2
  9. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/daemon.py +43 -30
  10. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/irc_transport.py +1 -1
  11. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/SKILL.md +9 -9
  12. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/irc_client.py +5 -5
  13. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/socket_server.py +1 -1
  14. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/webhook.py +1 -1
  15. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/config.py +5 -1
  16. agentirc_cli-0.16.0/agentirc/clients/claude/supervisor.py +141 -0
  17. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/config.py +3 -1
  18. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/config.py +3 -1
  19. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/learn_prompt.py +5 -2
  20. agentirc_cli-0.16.0/docs/agent-client.md +28 -0
  21. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/agent-harness-spec.md +7 -6
  22. agentirc_cli-0.16.0/docs/clients/acp/overview.md +140 -0
  23. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/harness-conformance.md +1 -1
  24. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/layer5-agent-harness.md +1 -1
  25. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/pyproject.toml +2 -2
  26. agentirc_cli-0.15.2/tests/test_opencode_daemon.py → agentirc_cli-0.16.0/tests/test_acp_daemon.py +26 -24
  27. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/uv.lock +1 -1
  28. agentirc_cli-0.15.2/agentirc/clients/opencode/supervisor.py +0 -163
  29. agentirc_cli-0.15.2/docs/agent-client.md +0 -11
  30. agentirc_cli-0.15.2/docs/clients/opencode/configuration.md +0 -187
  31. agentirc_cli-0.15.2/docs/clients/opencode/context-management.md +0 -73
  32. agentirc_cli-0.15.2/docs/clients/opencode/irc-tools.md +0 -186
  33. agentirc_cli-0.15.2/docs/clients/opencode/overview.md +0 -125
  34. agentirc_cli-0.15.2/docs/clients/opencode/setup.md +0 -214
  35. agentirc_cli-0.15.2/docs/clients/opencode/supervisor.md +0 -126
  36. agentirc_cli-0.15.2/docs/clients/opencode/webhooks.md +0 -91
  37. agentirc_cli-0.15.2/docs/opencode-backend.md +0 -6
  38. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/.claude/skills/pr-review/SKILL.md +0 -0
  39. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/.github/workflows/pages.yml +0 -0
  40. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/.github/workflows/publish.yml +0 -0
  41. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/.github/workflows/tests.yml +0 -0
  42. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/.gitignore +0 -0
  43. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/.markdownlint-cli2.yaml +0 -0
  44. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/CNAME +0 -0
  45. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/Gemfile +0 -0
  46. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/Gemfile.lock +0 -0
  47. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/LICENSE +0 -0
  48. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/_config.yml +0 -0
  49. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/_sass/color_schemes/anthropic.scss +0 -0
  50. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/_sass/custom/custom.scss +0 -0
  51. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/__init__.py +0 -0
  52. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/__main__.py +0 -0
  53. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/__init__.py +0 -0
  54. {agentirc_cli-0.15.2/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/__init__.py +0 -0
  55. {agentirc_cli-0.15.2/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/ipc.py +0 -0
  56. {agentirc_cli-0.15.2/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/message_buffer.py +0 -0
  57. {agentirc_cli-0.15.2/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/__init__.py +0 -0
  58. {agentirc_cli-0.15.2/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/supervisor.py +0 -0
  59. {agentirc_cli-0.15.2/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/__init__.py +0 -0
  60. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/__main__.py +0 -0
  61. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/agent_runner.py +0 -0
  62. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/daemon.py +0 -0
  63. {agentirc_cli-0.15.2/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/ipc.py +0 -0
  64. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/irc_transport.py +0 -0
  65. {agentirc_cli-0.15.2/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/message_buffer.py +0 -0
  66. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/skill/SKILL.md +0 -0
  67. {agentirc_cli-0.15.2/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/skill/__init__.py +0 -0
  68. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/skill/irc_client.py +0 -0
  69. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/socket_server.py +0 -0
  70. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/claude/webhook.py +0 -0
  71. {agentirc_cli-0.15.2/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/__init__.py +0 -0
  72. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/agent_runner.py +0 -0
  73. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/daemon.py +0 -0
  74. {agentirc_cli-0.15.2/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/ipc.py +0 -0
  75. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/irc_transport.py +0 -0
  76. {agentirc_cli-0.15.2/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/message_buffer.py +0 -0
  77. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/skill/SKILL.md +0 -0
  78. {agentirc_cli-0.15.2/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/skill/__init__.py +0 -0
  79. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/skill/irc_client.py +0 -0
  80. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/socket_server.py +0 -0
  81. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/supervisor.py +0 -0
  82. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/codex/webhook.py +0 -0
  83. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/__init__.py +0 -0
  84. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/agent_runner.py +0 -0
  85. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/daemon.py +0 -0
  86. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/ipc.py +0 -0
  87. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/irc_transport.py +0 -0
  88. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/message_buffer.py +0 -0
  89. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/skill/SKILL.md +0 -0
  90. {agentirc_cli-0.15.2/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/skill/__init__.py +0 -0
  91. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/skill/irc_client.py +0 -0
  92. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/socket_server.py +0 -0
  93. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/supervisor.py +0 -0
  94. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/clients/copilot/webhook.py +0 -0
  95. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/observer.py +0 -0
  96. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/overview/__init__.py +0 -0
  97. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/overview/collector.py +0 -0
  98. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/overview/model.py +0 -0
  99. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/overview/renderer_text.py +0 -0
  100. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/overview/renderer_web.py +0 -0
  101. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/overview/web/style.css +0 -0
  102. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/pidfile.py +0 -0
  103. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/__init__.py +0 -0
  104. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/commands.py +0 -0
  105. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/federation.md +0 -0
  106. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/history.md +0 -0
  107. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/rooms.md +0 -0
  108. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/tags.md +0 -0
  109. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/message.py +0 -0
  110. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/protocol-index.md +0 -0
  111. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/protocol/replies.py +0 -0
  112. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/__init__.py +0 -0
  113. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/__main__.py +0 -0
  114. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/channel.py +0 -0
  115. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/client.py +0 -0
  116. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/config.py +0 -0
  117. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/ircd.py +0 -0
  118. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/remote_client.py +0 -0
  119. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/room_store.py +0 -0
  120. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/rooms_util.py +0 -0
  121. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/server_link.py +0 -0
  122. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/skill.py +0 -0
  123. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/skills/__init__.py +0 -0
  124. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/skills/history.py +0 -0
  125. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/agentirc/server/skills/rooms.py +0 -0
  126. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/ci.md +0 -0
  127. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/cli.md +0 -0
  128. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/claude/configuration.md +0 -0
  129. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/claude/context-management.md +0 -0
  130. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/claude/irc-tools.md +0 -0
  131. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/claude/overview.md +0 -0
  132. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/claude/setup.md +0 -0
  133. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/claude/supervisor.md +0 -0
  134. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/claude/webhooks.md +0 -0
  135. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/codex/configuration.md +0 -0
  136. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/codex/context-management.md +0 -0
  137. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/codex/irc-tools.md +0 -0
  138. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/codex/overview.md +0 -0
  139. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/codex/setup.md +0 -0
  140. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/codex/supervisor.md +0 -0
  141. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/codex/webhooks.md +0 -0
  142. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/copilot/configuration.md +0 -0
  143. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/copilot/context-management.md +0 -0
  144. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/copilot/irc-tools.md +0 -0
  145. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/copilot/overview.md +0 -0
  146. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/copilot/setup.md +0 -0
  147. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/copilot/supervisor.md +0 -0
  148. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/clients/copilot/webhooks.md +0 -0
  149. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/codex-backend.md +0 -0
  150. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/copilot-backend.md +0 -0
  151. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/design.md +0 -0
  152. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/docs-site.md +0 -0
  153. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/getting-started.md +0 -0
  154. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/grow-your-agent.md +0 -0
  155. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/layer1-core-irc.md +0 -0
  156. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/layer2-attention.md +0 -0
  157. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/layer3-skills.md +0 -0
  158. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/layer4-federation.md +0 -0
  159. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/overview.md +0 -0
  160. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/publishing.md +0 -0
  161. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  162. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/rooms.md +0 -0
  163. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/server-architecture.md +0 -0
  164. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  165. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  166. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  167. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  168. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  169. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  170. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  171. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  172. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/01-pair-programming.md +0 -0
  173. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/02-code-review-ensemble.md +0 -0
  174. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/03-cross-server-delegation.md +0 -0
  175. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/04-knowledge-propagation.md +0 -0
  176. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/05-the-observer.md +0 -0
  177. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/06-cross-server-ops.md +0 -0
  178. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/07-supervisor-intervention.md +0 -0
  179. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/08-apps-as-agents.md +0 -0
  180. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/09-research-swarm.md +0 -0
  181. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases/10-grow-your-agent.md +0 -0
  182. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/docs/use-cases-index.md +0 -0
  183. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/index.md +0 -0
  184. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/README.md +0 -0
  185. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/config.py +0 -0
  186. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/daemon.py +0 -0
  187. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/ipc.py +0 -0
  188. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/irc_transport.py +0 -0
  189. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/message_buffer.py +0 -0
  190. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/skill/SKILL.md +0 -0
  191. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/skill/irc_client.py +0 -0
  192. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/socket_server.py +0 -0
  193. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/packages/agent-harness/webhook.py +0 -0
  194. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  195. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  196. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/plugins/codex/skills/agentirc-irc/SKILL.md +0 -0
  197. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/__init__.py +0 -0
  198. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/conftest.py +0 -0
  199. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_agent_runner.py +0 -0
  200. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_channel.py +0 -0
  201. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_codex_daemon.py +0 -0
  202. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_connection.py +0 -0
  203. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_copilot_daemon.py +0 -0
  204. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_daemon.py +0 -0
  205. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_daemon_config.py +0 -0
  206. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_daemon_ipc.py +0 -0
  207. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_discovery.py +0 -0
  208. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_federation.py +0 -0
  209. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_history.py +0 -0
  210. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_integration_layer5.py +0 -0
  211. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_ipc.py +0 -0
  212. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_irc_transport.py +0 -0
  213. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_mentions.py +0 -0
  214. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_message.py +0 -0
  215. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_message_buffer.py +0 -0
  216. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_messaging.py +0 -0
  217. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_modes.py +0 -0
  218. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_overview_cli.py +0 -0
  219. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_overview_collector.py +0 -0
  220. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_overview_model.py +0 -0
  221. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_overview_renderer.py +0 -0
  222. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_overview_web.py +0 -0
  223. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_room_persistence.py +0 -0
  224. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_rooms.py +0 -0
  225. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_rooms_federation.py +0 -0
  226. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_rooms_integration.py +0 -0
  227. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_skill_client.py +0 -0
  228. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_skills.py +0 -0
  229. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_socket_server.py +0 -0
  230. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_supervisor.py +0 -0
  231. {agentirc_cli-0.15.2 → agentirc_cli-0.16.0}/tests/test_webhook.py +0 -0
@@ -10,7 +10,7 @@ extra_instructions = """
10
10
 
11
11
  ## Harness Conformance (CRITICAL)
12
12
 
13
- The authoritative spec is `docs/agent-harness-spec.md`. There are 4 agent backends under `agentirc/clients/` — claude, codex, copilot, opencode — plus a reference implementation in `packages/agent-harness/`. The all-backends rule: a feature that exists in only one backend is a bug.
13
+ The authoritative spec is `docs/agent-harness-spec.md`. There are 4 agent backends under `agentirc/clients/` — claude, codex, copilot, acp — plus a reference implementation in `packages/agent-harness/`. The ACP backend supports any agent implementing the Agent Client Protocol (Cline, OpenCode, Kiro, etc.) via a configurable `acp_command`. The all-backends rule: a feature that exists in only one backend is a bug.
14
14
 
15
15
  When reviewing changes to any file under `agentirc/clients/` or `packages/agent-harness/`, apply these checks:
16
16
 
@@ -4,6 +4,21 @@ 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.16.0] - 2026-03-31
8
+
9
+
10
+ ### Added
11
+
12
+ - Generic ACP backend — supports Cline, OpenCode, Kiro, Gemini, and any ACP-compatible agent via configurable spawn command
13
+ - CLI --agent acp with --acp-command flag for registering ACP agents
14
+
15
+
16
+ ### Changed
17
+
18
+ - Replaced OpenCode-specific backend with generic ACP backend (clients/acp/)
19
+ - ACP supervisor uses SDK-based evaluation (vendor-agnostic) instead of opencode --non-interactive
20
+ - Backward compat: existing agent: opencode configs map to ACP backend automatically
21
+
7
22
  ## [0.15.2] - 2026-03-31
8
23
 
9
24
 
@@ -25,7 +25,7 @@ For agent backends (`clients/claude/`, `clients/codex/`, etc.):
25
25
 
26
26
  If you improve a generic component (e.g., `irc_transport.py`), update the reference in `packages/` too so the next backend starts from the latest version.
27
27
 
28
- **All-backends rule:** When adding or changing a feature in any agent harness (config fields, transport capabilities, daemon handlers), propagate the change to **all** backends (`claude`, `codex`, `copilot`, `opencode`) and update `docs/` accordingly. A feature that only exists in one backend is a bug.
28
+ **All-backends rule:** When adding or changing a feature in any agent harness (config fields, transport capabilities, daemon handlers), propagate the change to **all** backends (`claude`, `codex`, `copilot`, `acp`) and update `docs/` accordingly. A feature that only exists in one backend is a bug.
29
29
 
30
30
  ## Documentation
31
31
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 0.15.2
3
+ Version: 0.16.0
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
@@ -27,6 +27,8 @@ Description-Content-Type: text/markdown
27
27
 
28
28
  IRC Protocol ChatRooms for Agents (And humans allowed)
29
29
 
30
+ Supports Claude Code, Codex, Copilot, and any ACP agent (Cline, OpenCode, Kiro, Gemini)
31
+
30
32
  <br>
31
33
 
32
34
  <a href="https://agentirc.dev"><img src="https://img.shields.io/badge/docs-agentirc.dev-D97706?style=flat&labelColor=2D2B27" alt="Docs"></a>
@@ -162,7 +164,7 @@ Full docs at **[agentirc.dev](https://agentirc.dev)** -- or browse below.
162
164
  </details>
163
165
 
164
166
  <details>
165
- <summary><b>Agent Client</b> <sub>7 docs</sub></summary>
167
+ <summary><b>Agent Client</b> <sub>8 docs</sub></summary>
166
168
 
167
169
  | Doc | Description |
168
170
  |-----|-------------|
@@ -173,6 +175,7 @@ Full docs at **[agentirc.dev](https://agentirc.dev)** -- or browse below.
173
175
  | [Context Management](docs/clients/claude/context-management.md) | Compact, clear, set directory |
174
176
  | [Supervisor](docs/clients/claude/supervisor.md) | Human oversight and intervention |
175
177
  | [Webhooks](docs/clients/claude/webhooks.md) | Alerting and event notifications |
178
+ | [ACP Backend](docs/clients/acp/overview.md) | Cline, OpenCode, Kiro, Gemini, and any ACP agent |
176
179
 
177
180
  </details>
178
181
 
@@ -5,6 +5,8 @@
5
5
 
6
6
  IRC Protocol ChatRooms for Agents (And humans allowed)
7
7
 
8
+ Supports Claude Code, Codex, Copilot, and any ACP agent (Cline, OpenCode, Kiro, Gemini)
9
+
8
10
  <br>
9
11
 
10
12
  <a href="https://agentirc.dev"><img src="https://img.shields.io/badge/docs-agentirc.dev-D97706?style=flat&labelColor=2D2B27" alt="Docs"></a>
@@ -140,7 +142,7 @@ Full docs at **[agentirc.dev](https://agentirc.dev)** -- or browse below.
140
142
  </details>
141
143
 
142
144
  <details>
143
- <summary><b>Agent Client</b> <sub>7 docs</sub></summary>
145
+ <summary><b>Agent Client</b> <sub>8 docs</sub></summary>
144
146
 
145
147
  | Doc | Description |
146
148
  |-----|-------------|
@@ -151,6 +153,7 @@ Full docs at **[agentirc.dev](https://agentirc.dev)** -- or browse below.
151
153
  | [Context Management](docs/clients/claude/context-management.md) | Compact, clear, set directory |
152
154
  | [Supervisor](docs/clients/claude/supervisor.md) | Human oversight and intervention |
153
155
  | [Webhooks](docs/clients/claude/webhooks.md) | Alerting and event notifications |
156
+ | [ACP Backend](docs/clients/acp/overview.md) | Cline, OpenCode, Kiro, Gemini, and any ACP agent |
154
157
 
155
158
  </details>
156
159
 
@@ -103,7 +103,8 @@ def _build_parser() -> argparse.ArgumentParser:
103
103
  init_parser = sub.add_parser("init", help="Register an agent for the current directory")
104
104
  init_parser.add_argument("--server", default=None, help="Server name prefix")
105
105
  init_parser.add_argument("--nick", default=None, help="Agent suffix (after server-)")
106
- init_parser.add_argument("--agent", default="claude", choices=["claude", "codex", "opencode", "copilot"], help="Agent backend")
106
+ init_parser.add_argument("--agent", default="claude", choices=["claude", "codex", "copilot", "acp"], help="Agent backend")
107
+ init_parser.add_argument("--acp-command", default=None, help="ACP spawn command as JSON list (e.g. '[\"cline\",\"--acp\"]')")
107
108
  init_parser.add_argument("--config", default=DEFAULT_CONFIG, help="Config file path")
108
109
 
109
110
  # -- start subcommand --------------------------------------------------
@@ -167,8 +168,8 @@ def _build_parser() -> argparse.ArgumentParser:
167
168
  skills_sub = skills_parser.add_subparsers(dest="skills_command")
168
169
  skills_install = skills_sub.add_parser("install", help="Install IRC skill for an agent")
169
170
  skills_install.add_argument(
170
- "target", choices=["claude", "codex", "opencode", "copilot", "all"],
171
- help="Target agent: claude, codex, opencode, copilot, or all",
171
+ "target", choices=["claude", "codex", "copilot", "acp", "opencode", "all"],
172
+ help="Target agent: claude, codex, copilot, acp, opencode (alias of acp), or all",
172
173
  )
173
174
 
174
175
  # -- overview subcommand -----------------------------------------------
@@ -413,14 +414,6 @@ def _cmd_init(args: argparse.Namespace) -> None:
413
414
  directory=os.getcwd(),
414
415
  channels=["#general"],
415
416
  )
416
- elif args.agent == "opencode":
417
- from agentirc.clients.opencode.config import AgentConfig as OpenCodeAgentConfig
418
- agent = OpenCodeAgentConfig(
419
- nick=full_nick,
420
- agent="opencode",
421
- directory=os.getcwd(),
422
- channels=["#general"],
423
- )
424
417
  elif args.agent == "copilot":
425
418
  from agentirc.clients.copilot.config import AgentConfig as CopilotAgentConfig
426
419
  agent = CopilotAgentConfig(
@@ -429,6 +422,26 @@ def _cmd_init(args: argparse.Namespace) -> None:
429
422
  directory=os.getcwd(),
430
423
  channels=["#general"],
431
424
  )
425
+ elif args.agent == "acp":
426
+ import json as _json
427
+ from agentirc.clients.acp.config import AgentConfig as ACPAgentConfig
428
+ acp_cmd = ["opencode", "acp"]
429
+ if args.acp_command:
430
+ try:
431
+ acp_cmd = _json.loads(args.acp_command)
432
+ except _json.JSONDecodeError:
433
+ # Treat as a simple command name (e.g. "cline --acp")
434
+ acp_cmd = args.acp_command.split()
435
+ if not isinstance(acp_cmd, list) or not acp_cmd or not all(isinstance(s, str) for s in acp_cmd):
436
+ print("Error: --acp-command must be a non-empty list of strings", file=sys.stderr)
437
+ sys.exit(1)
438
+ agent = ACPAgentConfig(
439
+ nick=full_nick,
440
+ agent="acp",
441
+ acp_command=acp_cmd,
442
+ directory=os.getcwd(),
443
+ channels=["#general"],
444
+ )
432
445
  else:
433
446
  agent = AgentConfig(
434
447
  nick=full_nick,
@@ -529,19 +542,34 @@ async def _run_single_agent(config: DaemonConfig, agent: AgentConfig) -> None:
529
542
  agents=config.agents,
530
543
  )
531
544
  daemon = CodexDaemon(codex_config, agent)
532
- elif backend == "opencode":
533
- from agentirc.clients.opencode.daemon import OpenCodeDaemon
534
- from agentirc.clients.opencode.config import (
535
- DaemonConfig as OpenCodeDaemonConfig,
545
+ elif backend in ("acp", "opencode"):
546
+ from agentirc.clients.acp.daemon import ACPDaemon
547
+ from agentirc.clients.acp.config import (
548
+ DaemonConfig as ACPDaemonConfig,
549
+ AgentConfig as ACPAgentConfig,
536
550
  )
537
- # Re-load config through OpenCode module for correct supervisor defaults
538
- opencode_config = OpenCodeDaemonConfig(
551
+ # Re-load config through ACP module for correct supervisor defaults
552
+ acp_config = ACPDaemonConfig(
539
553
  server=config.server,
540
554
  webhooks=config.webhooks,
541
555
  buffer_size=config.buffer_size,
542
556
  agents=config.agents,
543
557
  )
544
- daemon = OpenCodeDaemon(opencode_config, agent)
558
+ # Backward compat: opencode -> acp with default command
559
+ if not isinstance(agent, ACPAgentConfig):
560
+ acp_agent = ACPAgentConfig(
561
+ nick=agent.nick,
562
+ agent="acp",
563
+ acp_command=getattr(agent, "acp_command", None) or ["opencode", "acp"],
564
+ directory=agent.directory,
565
+ channels=list(agent.channels),
566
+ model=agent.model,
567
+ system_prompt=agent.system_prompt,
568
+ tags=list(agent.tags),
569
+ )
570
+ else:
571
+ acp_agent = agent
572
+ daemon = ACPDaemon(acp_config, acp_agent)
545
573
  elif backend == "copilot":
546
574
  from agentirc.clients.copilot.daemon import CopilotDaemon
547
575
  from agentirc.clients.copilot.config import (
@@ -1018,45 +1046,45 @@ def _install_skill_codex() -> None:
1018
1046
  print(f"Installed Codex skill: {dest}")
1019
1047
 
1020
1048
 
1021
- def _get_bundled_opencode_skill_path() -> str:
1022
- """Return the path to the bundled OpenCode SKILL.md in the installed package."""
1049
+ def _get_bundled_copilot_skill_path() -> str:
1050
+ """Return the path to the bundled Copilot SKILL.md in the installed package."""
1023
1051
  import agentirc
1024
- return os.path.join(os.path.dirname(agentirc.__file__), "clients", "opencode", "skill", "SKILL.md")
1052
+ return os.path.join(os.path.dirname(agentirc.__file__), "clients", "copilot", "skill", "SKILL.md")
1025
1053
 
1026
1054
 
1027
- def _install_skill_opencode() -> None:
1028
- """Install IRC skill for OpenCode."""
1029
- src = _get_bundled_opencode_skill_path()
1030
- dest_dir = os.path.expanduser("~/.opencode/skills/agentirc-irc")
1055
+ def _install_skill_copilot() -> None:
1056
+ """Install IRC skill for GitHub Copilot."""
1057
+ src = _get_bundled_copilot_skill_path()
1058
+ dest_dir = os.path.expanduser("~/.copilot_skills/agentirc-irc")
1031
1059
  dest = os.path.join(dest_dir, "SKILL.md")
1032
1060
 
1033
1061
  os.makedirs(dest_dir, exist_ok=True)
1034
1062
  import shutil
1035
1063
  shutil.copy2(src, dest)
1036
- print(f"Installed OpenCode skill: {dest}")
1064
+ print(f"Installed Copilot skill: {dest}")
1037
1065
 
1038
1066
 
1039
- def _get_bundled_copilot_skill_path() -> str:
1040
- """Return the path to the bundled Copilot SKILL.md in the installed package."""
1067
+ def _get_bundled_acp_skill_path() -> str:
1068
+ """Return the path to the bundled ACP SKILL.md in the installed package."""
1041
1069
  import agentirc
1042
- return os.path.join(os.path.dirname(agentirc.__file__), "clients", "copilot", "skill", "SKILL.md")
1070
+ return os.path.join(os.path.dirname(agentirc.__file__), "clients", "acp", "skill", "SKILL.md")
1043
1071
 
1044
1072
 
1045
- def _install_skill_copilot() -> None:
1046
- """Install IRC skill for GitHub Copilot."""
1047
- src = _get_bundled_copilot_skill_path()
1048
- dest_dir = os.path.expanduser("~/.copilot_skills/agentirc-irc")
1073
+ def _install_skill_acp() -> None:
1074
+ """Install IRC skill for ACP agents (Cline, OpenCode, etc.)."""
1075
+ src = _get_bundled_acp_skill_path()
1076
+ dest_dir = os.path.expanduser("~/.acp/skills/agentirc-irc")
1049
1077
  dest = os.path.join(dest_dir, "SKILL.md")
1050
1078
 
1051
1079
  os.makedirs(dest_dir, exist_ok=True)
1052
1080
  import shutil
1053
1081
  shutil.copy2(src, dest)
1054
- print(f"Installed Copilot skill: {dest}")
1082
+ print(f"Installed ACP skill: {dest}")
1055
1083
 
1056
1084
 
1057
1085
  def _cmd_skills(args: argparse.Namespace) -> None:
1058
1086
  if not hasattr(args, "skills_command") or args.skills_command != "install":
1059
- print("Usage: agentirc skills install <claude|codex|opencode|copilot|all>", file=sys.stderr)
1087
+ print("Usage: agentirc skills install <claude|codex|copilot|acp|all>", file=sys.stderr)
1060
1088
  sys.exit(1)
1061
1089
 
1062
1090
  target = args.target
@@ -1065,13 +1093,13 @@ def _cmd_skills(args: argparse.Namespace) -> None:
1065
1093
  _install_skill_claude()
1066
1094
  if target in ("codex", "all"):
1067
1095
  _install_skill_codex()
1068
- if target in ("opencode", "all"):
1069
- _install_skill_opencode()
1070
1096
  if target in ("copilot", "all"):
1071
1097
  _install_skill_copilot()
1098
+ if target in ("acp", "opencode", "all"):
1099
+ _install_skill_acp()
1072
1100
 
1073
1101
  if target == "all":
1074
- print("\nSkills installed for Claude Code, Codex, OpenCode, and Copilot.")
1102
+ print("\nSkills installed for Claude Code, Codex, Copilot, and ACP.")
1075
1103
  print(f"\nSet AGENTIRC_NICK in your shell profile to enable the skill.")
1076
1104
 
1077
1105
 
@@ -1,4 +1,8 @@
1
- """OpenCode agent runner — manages opencode acp via ACP/JSON-RPC over stdio."""
1
+ """ACP agent runner — manages any ACP-compatible agent via JSON-RPC over stdio.
2
+
3
+ Supports any agent that implements the Agent Client Protocol (ACP), such as
4
+ Cline (cline --acp), OpenCode (opencode acp), and others.
5
+ """
2
6
 
3
7
  from __future__ import annotations
4
8
 
@@ -13,19 +17,26 @@ from typing import Any, Awaitable, Callable
13
17
  logger = logging.getLogger(__name__)
14
18
 
15
19
 
16
- class OpenCodeAgentRunner:
17
- """Manages an OpenCode ACP session for the agentirc daemon."""
20
+ class ACPAgentRunner:
21
+ """Manages an ACP session for the agentirc daemon.
22
+
23
+ Works with any ACP-compatible agent by configuring the spawn command
24
+ via the ``acp_command`` parameter (e.g. ``["cline", "--acp"]`` or
25
+ ``["opencode", "acp"]``).
26
+ """
18
27
 
19
28
  def __init__(
20
29
  self,
21
30
  model: str,
22
31
  directory: str,
32
+ acp_command: list[str] | None = None,
23
33
  system_prompt: str = "",
24
34
  on_exit: Callable[[int], Awaitable[None]] | None = None,
25
35
  on_message: Callable[[dict[str, Any]], Awaitable[None]] | None = None,
26
36
  ) -> None:
27
37
  self.model = model
28
38
  self.directory = directory
39
+ self.acp_command = acp_command or ["opencode", "acp"]
29
40
  self.system_prompt = system_prompt
30
41
  self.on_exit = on_exit
31
42
  self.on_message = on_message
@@ -52,21 +63,22 @@ class OpenCodeAgentRunner:
52
63
  return self._session_id
53
64
 
54
65
  async def start(self, initial_prompt: str = "") -> None:
55
- """Start opencode acp as a subprocess and initialize a session."""
66
+ """Start the ACP agent as a subprocess and initialize a session."""
56
67
  self._stopping = False
57
68
 
58
- # Isolate from host config (~/.config/opencode/, XDG, etc.)
59
- self._isolated_home = tempfile.mkdtemp(prefix="agentirc-opencode-")
69
+ # Isolate from host config (XDG, etc.)
70
+ self._isolated_home = tempfile.mkdtemp(prefix="agentirc-acp-")
60
71
  isolated_env = dict(os.environ)
61
72
  isolated_env["HOME"] = self._isolated_home
62
73
  isolated_env.pop("XDG_CONFIG_HOME", None)
63
74
 
75
+ cmd_label = " ".join(self.acp_command)
64
76
  try:
65
- # Spawn opencode acp in stdio mode
77
+ # Spawn ACP agent in stdio mode
66
78
  # Use a large stdout buffer — ACP messages (especially session/new with
67
79
  # all available models) can exceed asyncio's default 64KB line limit.
68
80
  self._process = await asyncio.create_subprocess_exec(
69
- "opencode", "acp",
81
+ *self.acp_command,
70
82
  stdin=asyncio.subprocess.PIPE,
71
83
  stdout=asyncio.subprocess.PIPE,
72
84
  stderr=asyncio.subprocess.PIPE,
@@ -85,9 +97,9 @@ class OpenCodeAgentRunner:
85
97
  "fs": {"readTextFile": True, "writeTextFile": True},
86
98
  "terminal": True,
87
99
  },
88
- "clientInfo": {"name": "agentirc-opencode", "version": "0.1.0"},
100
+ "clientInfo": {"name": "agentirc-acp", "version": "0.1.0"},
89
101
  })
90
- logger.info("OpenCode initialized: %s", resp)
102
+ logger.info("ACP initialized (%s): %s", cmd_label, resp)
91
103
 
92
104
  # Create a session with model selection
93
105
  session_params = {
@@ -98,11 +110,11 @@ class OpenCodeAgentRunner:
98
110
  session_params["model"] = self.model
99
111
  resp = await self._send_request("session/new", session_params)
100
112
 
101
- logger.info("OpenCode session/new raw response: %s", json.dumps(resp)[:500])
113
+ logger.info("ACP session/new raw response: %s", json.dumps(resp)[:500])
102
114
  result = resp.get("result", {})
103
115
  self._session_id = result.get("sessionId")
104
116
  self._running = True
105
- logger.info("OpenCode session started: %s", self._session_id)
117
+ logger.info("ACP session started (%s): %s", cmd_label, self._session_id)
106
118
 
107
119
  # Start the prompt processing loop
108
120
  self._task = asyncio.create_task(self._prompt_loop())
@@ -120,7 +132,7 @@ class OpenCodeAgentRunner:
120
132
  raise
121
133
 
122
134
  async def stop(self) -> None:
123
- """Stop the opencode acp process."""
135
+ """Stop the ACP agent process."""
124
136
  self._stopping = True
125
137
  self._running = False
126
138
 
@@ -238,7 +250,7 @@ class OpenCodeAgentRunner:
238
250
  except (asyncio.CancelledError, ConnectionError):
239
251
  pass
240
252
  except Exception:
241
- logger.exception("OpenCode read loop error")
253
+ logger.exception("ACP read loop error")
242
254
  finally:
243
255
  # Wait for process to fully exit and notify daemon for crash recovery
244
256
  returncode = -1
@@ -270,9 +282,10 @@ class OpenCodeAgentRunner:
270
282
  await self.on_exit(returncode)
271
283
 
272
284
  async def _stderr_loop(self) -> None:
273
- """Log stderr output from the opencode process."""
285
+ """Log stderr output from the ACP agent process."""
274
286
  if not self._process or not self._process.stderr:
275
287
  return
288
+ cmd_name = self.acp_command[0]
276
289
  try:
277
290
  while True:
278
291
  line = await self._process.stderr.readline()
@@ -280,7 +293,7 @@ class OpenCodeAgentRunner:
280
293
  break
281
294
  text = line.decode("utf-8", errors="replace").rstrip()
282
295
  if text:
283
- logger.warning("opencode stderr: %s", text)
296
+ logger.warning("acp[%s] stderr: %s", cmd_name, text)
284
297
  except (asyncio.CancelledError, ConnectionError):
285
298
  pass
286
299
 
@@ -324,7 +337,7 @@ class OpenCodeAgentRunner:
324
337
  await self._process.stdin.drain()
325
338
 
326
339
  elif method == "error":
327
- logger.error("OpenCode error: %s", params)
340
+ logger.error("ACP error (%s): %s", self.acp_command[0], params)
328
341
 
329
342
  async def _prompt_loop(self) -> None:
330
343
  """Process queued prompts one at a time."""
@@ -360,7 +373,7 @@ class OpenCodeAgentRunner:
360
373
  await asyncio.sleep(0.1)
361
374
 
362
375
  except Exception:
363
- logger.exception("OpenCode turn error")
376
+ logger.exception("ACP turn error")
364
377
 
365
378
  except asyncio.CancelledError:
366
379
  pass
@@ -20,7 +20,8 @@ class ServerConnConfig:
20
20
  @dataclass
21
21
  class SupervisorConfig:
22
22
  """Supervisor sub-agent settings."""
23
- model: str = "anthropic/claude-sonnet-4-6"
23
+ model: str = "claude-sonnet-4-6"
24
+ thinking: str = ""
24
25
  window_size: int = 20
25
26
  eval_interval: int = 5
26
27
  escalation_threshold: int = 3
@@ -42,7 +43,8 @@ class WebhookConfig:
42
43
  class AgentConfig:
43
44
  """Per-agent settings."""
44
45
  nick: str = ""
45
- agent: str = "opencode"
46
+ agent: str = "acp"
47
+ acp_command: list[str] = field(default_factory=lambda: ["opencode", "acp"])
46
48
  directory: str = "."
47
49
  channels: list[str] = field(default_factory=lambda: ["#general"])
48
50
  model: str = "anthropic/claude-sonnet-4-6"
@@ -1,7 +1,10 @@
1
- """OpenCode agent daemon — bridges an OpenCode agent to the IRC network.
1
+ """ACP agent daemon — bridges any ACP-compatible agent to the IRC network.
2
2
 
3
- Uses OpenCodeAgentRunner (opencode acp over ACP/JSON-RPC/stdio) and
4
- OpenCodeSupervisor (opencode --non-interactive for periodic evaluation).
3
+ Supports Cline (cline --acp), OpenCode (opencode acp), and any other agent
4
+ that implements the Agent Client Protocol over stdio.
5
+
6
+ Uses ACPAgentRunner (JSON-RPC/stdio) and an SDK-based Supervisor
7
+ (Claude Agent SDK for periodic evaluation).
5
8
  """
6
9
 
7
10
  from __future__ import annotations
@@ -14,14 +17,14 @@ import time
14
17
  from collections import deque
15
18
  from typing import Any
16
19
 
17
- from agentirc.clients.opencode.config import DaemonConfig, AgentConfig
18
- from agentirc.clients.opencode.ipc import make_response
19
- from agentirc.clients.opencode.irc_transport import IRCTransport
20
- from agentirc.clients.opencode.message_buffer import MessageBuffer
21
- from agentirc.clients.opencode.socket_server import SocketServer
22
- from agentirc.clients.opencode.webhook import WebhookClient, AlertEvent
23
- from agentirc.clients.opencode.agent_runner import OpenCodeAgentRunner
24
- from agentirc.clients.opencode.supervisor import OpenCodeSupervisor
20
+ from agentirc.clients.acp.config import DaemonConfig, AgentConfig
21
+ from agentirc.clients.acp.ipc import make_response
22
+ from agentirc.clients.acp.irc_transport import IRCTransport
23
+ from agentirc.clients.acp.message_buffer import MessageBuffer
24
+ from agentirc.clients.acp.socket_server import SocketServer
25
+ from agentirc.clients.acp.webhook import WebhookClient, AlertEvent
26
+ from agentirc.clients.acp.agent_runner import ACPAgentRunner
27
+ from agentirc.clients.acp.supervisor import Supervisor, make_sdk_evaluate_fn
25
28
  from agentirc.pidfile import write_pid, remove_pid
26
29
 
27
30
  logger = logging.getLogger(__name__)
@@ -31,20 +34,20 @@ CRASH_WINDOW_SECONDS = 300
31
34
  CRASH_RESTART_DELAY = 5
32
35
 
33
36
 
34
- class OpenCodeDaemon:
37
+ class ACPDaemon:
35
38
  """Central orchestrator that ties together the IRC transport, socket server,
36
- OpenCode agent runner, supervisor, and webhook client for a single agent nick."""
39
+ ACP agent runner, supervisor, and webhook client for a single agent nick."""
37
40
 
38
41
  def __init__(
39
42
  self,
40
43
  config: DaemonConfig,
41
44
  agent: AgentConfig,
42
45
  socket_dir: str | None = None,
43
- skip_opencode: bool = False,
46
+ skip_agent: bool = False,
44
47
  ) -> None:
45
48
  self.config = config
46
49
  self.agent = agent
47
- self.skip_opencode = skip_opencode
50
+ self.skip_agent = skip_agent
48
51
 
49
52
  self._socket_path = os.path.join(
50
53
  socket_dir or os.environ.get("XDG_RUNTIME_DIR", "/tmp"),
@@ -55,8 +58,8 @@ class OpenCodeDaemon:
55
58
  self._transport: IRCTransport | None = None
56
59
  self._webhook: WebhookClient | None = None
57
60
  self._socket_server: SocketServer | None = None
58
- self._agent_runner: OpenCodeAgentRunner | None = None
59
- self._supervisor: OpenCodeSupervisor | None = None
61
+ self._agent_runner: ACPAgentRunner | None = None
62
+ self._supervisor: Supervisor | None = None
60
63
 
61
64
  # FIFO queue of relay targets — each @mention enqueues a target,
62
65
  # each agent response dequeues one, ensuring correct routing even
@@ -86,6 +89,8 @@ class OpenCodeDaemon:
86
89
 
87
90
  async def start(self) -> None:
88
91
  """Start all components in dependency order."""
92
+ cmd_label = " ".join(self.agent.acp_command)
93
+
89
94
  # 0. Write PID file for this agent
90
95
  self._pid_name = f"agent-{self.agent.nick}"
91
96
  write_pid(self._pid_name, os.getpid())
@@ -120,25 +125,28 @@ class OpenCodeDaemon:
120
125
  )
121
126
  await self._socket_server.start()
122
127
 
123
- # 5. Supervisor using opencode --non-interactive
124
- self._supervisor = OpenCodeSupervisor(
125
- model=self.config.supervisor.model,
128
+ # 5. SDK-based supervisor (vendor-agnostic)
129
+ self._supervisor = Supervisor(
126
130
  window_size=self.config.supervisor.window_size,
127
131
  eval_interval=self.config.supervisor.eval_interval,
128
132
  escalation_threshold=self.config.supervisor.escalation_threshold,
133
+ evaluate_fn=make_sdk_evaluate_fn(
134
+ model=self.config.supervisor.model,
135
+ thinking=self.config.supervisor.thinking or None,
136
+ prompt_override=self.config.supervisor.prompt_override,
137
+ ),
129
138
  on_whisper=self._on_supervisor_whisper,
130
139
  on_escalation=self._on_supervisor_escalation,
131
- prompt_override=self.config.supervisor.prompt_override,
132
140
  )
133
141
 
134
- # 6. Optionally start the OpenCode agent runner
135
- if not self.skip_opencode:
142
+ # 6. Optionally start the ACP agent runner
143
+ if not self.skip_agent:
136
144
  try:
137
145
  await self._start_agent_runner()
138
146
  except Exception:
139
147
  logger.exception(
140
- "Failed to start agent runner for %s, scheduling retry",
141
- self.agent.nick,
148
+ "Failed to start agent runner for %s (%s), scheduling retry",
149
+ self.agent.nick, cmd_label,
142
150
  )
143
151
  self._agent_runner = None
144
152
  self._crash_times.append(time.time())
@@ -148,7 +156,8 @@ class OpenCodeDaemon:
148
156
  self._sleep_task = asyncio.create_task(self._sleep_scheduler())
149
157
 
150
158
  logger.info(
151
- "OpenCodeDaemon started for %s (socket=%s)", self.agent.nick, self._socket_path
159
+ "ACPDaemon started for %s (cmd=%s, socket=%s)",
160
+ self.agent.nick, cmd_label, self._socket_path,
152
161
  )
153
162
 
154
163
  async def stop(self) -> None:
@@ -177,7 +186,7 @@ class OpenCodeDaemon:
177
186
  if self._pid_name:
178
187
  remove_pid(self._pid_name)
179
188
 
180
- logger.info("OpenCodeDaemon stopped for %s", self.agent.nick)
189
+ logger.info("ACPDaemon stopped for %s", self.agent.nick)
181
190
 
182
191
  def _parse_sleep_schedule(self) -> tuple[int, int] | None:
183
192
  """Parse sleep_start/sleep_end into minutes. Returns None if invalid."""
@@ -245,9 +254,10 @@ class OpenCodeDaemon:
245
254
  # ------------------------------------------------------------------
246
255
 
247
256
  async def _start_agent_runner(self) -> None:
248
- self._agent_runner = OpenCodeAgentRunner(
257
+ self._agent_runner = ACPAgentRunner(
249
258
  model=self.agent.model,
250
259
  directory=self.agent.directory,
260
+ acp_command=self.agent.acp_command,
251
261
  system_prompt=self._build_system_prompt(),
252
262
  on_exit=self._on_agent_exit,
253
263
  on_message=self._on_agent_message,
@@ -255,12 +265,15 @@ class OpenCodeDaemon:
255
265
  # Absorb the system prompt response without relaying to IRC
256
266
  self._mention_targets.append(None)
257
267
  await self._agent_runner.start()
258
- logger.info("OpenCodeAgentRunner started for %s", self.agent.nick)
268
+ logger.info(
269
+ "ACPAgentRunner started for %s (cmd=%s)",
270
+ self.agent.nick, " ".join(self.agent.acp_command),
271
+ )
259
272
 
260
273
  def _on_mention(self, target: str, sender: str, text: str) -> None:
261
274
  """Called by IRCTransport when the agent is @mentioned or DM'd.
262
275
 
263
- Formats a prompt and enqueues it so the OpenCode session picks it up.
276
+ Formats a prompt and enqueues it so the ACP session picks it up.
264
277
  """
265
278
  if self._paused:
266
279
  return
@@ -5,7 +5,7 @@ import logging
5
5
  from typing import Callable
6
6
 
7
7
  from agentirc.protocol.message import Message
8
- from agentirc.clients.opencode.message_buffer import MessageBuffer
8
+ from agentirc.clients.acp.message_buffer import MessageBuffer
9
9
 
10
10
  logger = logging.getLogger(__name__)
11
11