agentirc-cli 0.15.1__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 (233) hide show
  1. agentirc_cli-0.16.0/.pr_agent.toml +38 -0
  2. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/CHANGELOG.md +22 -0
  3. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/CLAUDE.md +1 -1
  4. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/PKG-INFO +5 -2
  5. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/README.md +4 -1
  6. agentirc_cli-0.16.0/agentirc/__init__.py +3 -0
  7. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/cli.py +66 -38
  8. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/agent_runner.py +31 -18
  9. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/config.py +4 -2
  10. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/daemon.py +43 -30
  11. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/irc_transport.py +1 -1
  12. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/SKILL.md +9 -9
  13. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/irc_client.py +5 -5
  14. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/socket_server.py +1 -1
  15. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/webhook.py +1 -1
  16. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/config.py +5 -1
  17. agentirc_cli-0.16.0/agentirc/clients/claude/supervisor.py +141 -0
  18. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/config.py +3 -1
  19. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/config.py +3 -1
  20. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/learn_prompt.py +5 -2
  21. agentirc_cli-0.16.0/docs/agent-client.md +28 -0
  22. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/agent-harness-spec.md +7 -6
  23. agentirc_cli-0.16.0/docs/clients/acp/overview.md +140 -0
  24. agentirc_cli-0.16.0/docs/harness-conformance.md +84 -0
  25. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer5-agent-harness.md +1 -1
  26. agentirc_cli-0.16.0/docs/superpowers/plans/2026-03-30-overview.md +1626 -0
  27. agentirc_cli-0.16.0/docs/superpowers/specs/2026-03-30-overview-design.md +328 -0
  28. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/pyproject.toml +2 -2
  29. agentirc_cli-0.15.1/tests/test_opencode_daemon.py → agentirc_cli-0.16.0/tests/test_acp_daemon.py +26 -24
  30. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/uv.lock +1 -1
  31. agentirc_cli-0.15.1/.pr_agent.toml +0 -9
  32. agentirc_cli-0.15.1/agentirc/__init__.py +0 -1
  33. agentirc_cli-0.15.1/agentirc/clients/opencode/supervisor.py +0 -163
  34. agentirc_cli-0.15.1/docs/agent-client.md +0 -11
  35. agentirc_cli-0.15.1/docs/clients/opencode/configuration.md +0 -187
  36. agentirc_cli-0.15.1/docs/clients/opencode/context-management.md +0 -73
  37. agentirc_cli-0.15.1/docs/clients/opencode/irc-tools.md +0 -186
  38. agentirc_cli-0.15.1/docs/clients/opencode/overview.md +0 -125
  39. agentirc_cli-0.15.1/docs/clients/opencode/setup.md +0 -214
  40. agentirc_cli-0.15.1/docs/clients/opencode/supervisor.md +0 -126
  41. agentirc_cli-0.15.1/docs/clients/opencode/webhooks.md +0 -91
  42. agentirc_cli-0.15.1/docs/opencode-backend.md +0 -6
  43. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.claude/skills/pr-review/SKILL.md +0 -0
  44. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.github/workflows/pages.yml +0 -0
  45. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.github/workflows/publish.yml +0 -0
  46. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.github/workflows/tests.yml +0 -0
  47. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.gitignore +0 -0
  48. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.markdownlint-cli2.yaml +0 -0
  49. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/CNAME +0 -0
  50. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/Gemfile +0 -0
  51. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/Gemfile.lock +0 -0
  52. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/LICENSE +0 -0
  53. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/_config.yml +0 -0
  54. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/_sass/color_schemes/anthropic.scss +0 -0
  55. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/_sass/custom/custom.scss +0 -0
  56. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/__main__.py +0 -0
  57. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/__init__.py +0 -0
  58. {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/__init__.py +0 -0
  59. {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/ipc.py +0 -0
  60. {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/message_buffer.py +0 -0
  61. {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/__init__.py +0 -0
  62. {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/supervisor.py +0 -0
  63. {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/__init__.py +0 -0
  64. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/__main__.py +0 -0
  65. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/agent_runner.py +0 -0
  66. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/daemon.py +0 -0
  67. {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/ipc.py +0 -0
  68. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/irc_transport.py +0 -0
  69. {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/message_buffer.py +0 -0
  70. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/skill/SKILL.md +0 -0
  71. {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/skill/__init__.py +0 -0
  72. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/skill/irc_client.py +0 -0
  73. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/socket_server.py +0 -0
  74. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/webhook.py +0 -0
  75. {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/__init__.py +0 -0
  76. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/agent_runner.py +0 -0
  77. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/daemon.py +0 -0
  78. {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/ipc.py +0 -0
  79. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/irc_transport.py +0 -0
  80. {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/message_buffer.py +0 -0
  81. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/skill/SKILL.md +0 -0
  82. {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/skill/__init__.py +0 -0
  83. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/skill/irc_client.py +0 -0
  84. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/socket_server.py +0 -0
  85. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/supervisor.py +0 -0
  86. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/webhook.py +0 -0
  87. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/__init__.py +0 -0
  88. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/agent_runner.py +0 -0
  89. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/daemon.py +0 -0
  90. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/ipc.py +0 -0
  91. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/irc_transport.py +0 -0
  92. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/message_buffer.py +0 -0
  93. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/skill/SKILL.md +0 -0
  94. {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/skill/__init__.py +0 -0
  95. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/skill/irc_client.py +0 -0
  96. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/socket_server.py +0 -0
  97. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/supervisor.py +0 -0
  98. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/webhook.py +0 -0
  99. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/observer.py +0 -0
  100. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/__init__.py +0 -0
  101. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/collector.py +0 -0
  102. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/model.py +0 -0
  103. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/renderer_text.py +0 -0
  104. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/renderer_web.py +0 -0
  105. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/web/style.css +0 -0
  106. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/pidfile.py +0 -0
  107. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/__init__.py +0 -0
  108. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/commands.py +0 -0
  109. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/federation.md +0 -0
  110. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/history.md +0 -0
  111. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/rooms.md +0 -0
  112. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/tags.md +0 -0
  113. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/message.py +0 -0
  114. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/protocol-index.md +0 -0
  115. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/replies.py +0 -0
  116. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/__init__.py +0 -0
  117. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/__main__.py +0 -0
  118. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/channel.py +0 -0
  119. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/client.py +0 -0
  120. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/config.py +0 -0
  121. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/ircd.py +0 -0
  122. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/remote_client.py +0 -0
  123. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/room_store.py +0 -0
  124. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/rooms_util.py +0 -0
  125. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/server_link.py +0 -0
  126. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skill.py +0 -0
  127. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skills/__init__.py +0 -0
  128. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skills/history.py +0 -0
  129. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skills/rooms.py +0 -0
  130. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/ci.md +0 -0
  131. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/cli.md +0 -0
  132. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/configuration.md +0 -0
  133. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/context-management.md +0 -0
  134. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/irc-tools.md +0 -0
  135. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/overview.md +0 -0
  136. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/setup.md +0 -0
  137. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/supervisor.md +0 -0
  138. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/webhooks.md +0 -0
  139. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/configuration.md +0 -0
  140. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/context-management.md +0 -0
  141. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/irc-tools.md +0 -0
  142. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/overview.md +0 -0
  143. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/setup.md +0 -0
  144. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/supervisor.md +0 -0
  145. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/webhooks.md +0 -0
  146. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/configuration.md +0 -0
  147. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/context-management.md +0 -0
  148. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/irc-tools.md +0 -0
  149. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/overview.md +0 -0
  150. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/setup.md +0 -0
  151. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/supervisor.md +0 -0
  152. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/webhooks.md +0 -0
  153. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/codex-backend.md +0 -0
  154. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/copilot-backend.md +0 -0
  155. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/design.md +0 -0
  156. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/docs-site.md +0 -0
  157. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/getting-started.md +0 -0
  158. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/grow-your-agent.md +0 -0
  159. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer1-core-irc.md +0 -0
  160. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer2-attention.md +0 -0
  161. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer3-skills.md +0 -0
  162. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer4-federation.md +0 -0
  163. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/overview.md +0 -0
  164. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/publishing.md +0 -0
  165. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  166. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/rooms.md +0 -0
  167. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/server-architecture.md +0 -0
  168. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  169. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  170. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  171. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  172. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  173. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  174. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/01-pair-programming.md +0 -0
  175. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/02-code-review-ensemble.md +0 -0
  176. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/03-cross-server-delegation.md +0 -0
  177. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/04-knowledge-propagation.md +0 -0
  178. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/05-the-observer.md +0 -0
  179. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/06-cross-server-ops.md +0 -0
  180. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/07-supervisor-intervention.md +0 -0
  181. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/08-apps-as-agents.md +0 -0
  182. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/09-research-swarm.md +0 -0
  183. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/10-grow-your-agent.md +0 -0
  184. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases-index.md +0 -0
  185. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/index.md +0 -0
  186. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/README.md +0 -0
  187. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/config.py +0 -0
  188. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/daemon.py +0 -0
  189. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/ipc.py +0 -0
  190. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/irc_transport.py +0 -0
  191. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/message_buffer.py +0 -0
  192. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/skill/SKILL.md +0 -0
  193. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/skill/irc_client.py +0 -0
  194. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/socket_server.py +0 -0
  195. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/webhook.py +0 -0
  196. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  197. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  198. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/plugins/codex/skills/agentirc-irc/SKILL.md +0 -0
  199. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/__init__.py +0 -0
  200. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/conftest.py +0 -0
  201. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_agent_runner.py +0 -0
  202. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_channel.py +0 -0
  203. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_codex_daemon.py +0 -0
  204. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_connection.py +0 -0
  205. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_copilot_daemon.py +0 -0
  206. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_daemon.py +0 -0
  207. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_daemon_config.py +0 -0
  208. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_daemon_ipc.py +0 -0
  209. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_discovery.py +0 -0
  210. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_federation.py +0 -0
  211. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_history.py +0 -0
  212. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_integration_layer5.py +0 -0
  213. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_ipc.py +0 -0
  214. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_irc_transport.py +0 -0
  215. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_mentions.py +0 -0
  216. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_message.py +0 -0
  217. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_message_buffer.py +0 -0
  218. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_messaging.py +0 -0
  219. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_modes.py +0 -0
  220. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_cli.py +0 -0
  221. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_collector.py +0 -0
  222. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_model.py +0 -0
  223. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_renderer.py +0 -0
  224. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_web.py +0 -0
  225. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_room_persistence.py +0 -0
  226. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_rooms.py +0 -0
  227. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_rooms_federation.py +0 -0
  228. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_rooms_integration.py +0 -0
  229. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_skill_client.py +0 -0
  230. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_skills.py +0 -0
  231. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_socket_server.py +0 -0
  232. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_supervisor.py +0 -0
  233. {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_webhook.py +0 -0
@@ -0,0 +1,38 @@
1
+ [pr_reviewer]
2
+ extra_instructions = """
3
+ ## Project Context
4
+
5
+ - The `packages/` directory is ONLY for the "assimilai" pattern (internal packages copied into other projects). Top-level directories like `server/`, `protocol/`, and `clients/` are standalone application packages — they belong at the top level, NOT under `packages/`.
6
+ - The "no mocks for the server" testing rule applies to IRC server tests only. Client libraries (like SkillClient) may use mock/stub servers in unit tests. Integration tests in `test_integration_layer5.py` exercise the real server stack.
7
+ - Nick format validation (`<server>-<agent>`) is enforced by the IRC server at connection time. Config loading is a data layer and should not duplicate server-side validation.
8
+ - Features explicitly marked as TODO or listed in the spec's "Deferred Features" section are known limitations, not bugs.
9
+ - The `clients/` directory contains agent client harnesses (daemons). It is NOT an internal package for assimilation.
10
+
11
+ ## Harness Conformance (CRITICAL)
12
+
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
+
15
+ When reviewing changes to any file under `agentirc/clients/` or `packages/agent-harness/`, apply these checks:
16
+
17
+ ### Cross-backend propagation
18
+ When a PR changes a file in `agentirc/clients/<backend>/`, check whether the same change must be applied to the other 3 backends. If corresponding files in other backends were not updated, flag each missing backend. Exception: `agent_runner.py` and `supervisor.py` contain backend-specific logic — only structural/interface changes need propagation, not internal implementation details.
19
+
20
+ ### Generic file identity
21
+ These files MUST be identical across all 4 backends and `packages/agent-harness/`, except for import paths (`from agentirc.clients.<backend>.`): `irc_transport.py`, `message_buffer.py`, `socket_server.py`, `ipc.py`, `webhook.py`, `skill/irc_client.py`. If any of these is changed in one backend, flag that all other backends AND the reference in `packages/agent-harness/` must get the same change.
22
+
23
+ ### Interface contract
24
+ If `agent_runner.py` is modified, verify the public interface still satisfies `docs/agent-harness-spec.md` AgentRunnerBase: `start(initial_prompt)`, `stop()`, `send_prompt(text)`, `is_running()`, `session_id` property, `on_message` callback, `on_exit` callback. If `supervisor.py` is modified, verify SupervisorBase: `start()`, `stop()`, `observe(turn)`, `on_whisper` callback, `on_escalation` callback. Flag any missing or renamed interface members.
25
+
26
+ ### Daemon contract
27
+ If `daemon.py` is modified, verify all IPC dispatch handlers are still present: `irc_send`, `irc_read`, `irc_ask`, `irc_join`, `irc_part`, `irc_who`, `irc_channels`, `compact`, `clear`, `shutdown`. Also verify structural features (crash recovery, `_mention_targets`, sleep scheduler) are consistent across backends. If a structural feature is added to one daemon, flag its absence in the others.
28
+
29
+ ### Config schema
30
+ If `config.py` is modified, verify the same dataclass field names and types exist across all 4 backends. Only default values may differ by backend (e.g., model names). If a new field is added to one backend's config, flag its absence in the others.
31
+
32
+ ### SKILL.md consistency
33
+ If any `SKILL.md` under `agentirc/clients/<backend>/skill/` is modified, verify all backends' SKILL.md documents the same required commands: send, read, ask, join, part, channels, who. Flag format or content inconsistencies.
34
+
35
+ ### Spec-doc alignment
36
+ If `docs/agent-harness-spec.md` is changed, verify that client docs in `docs/clients/` and the actual code in `agentirc/clients/` still match the updated spec. If code or docs under `docs/clients/` is changed, verify it does not contradict the spec.
37
+ """
38
+ num_max_findings = 10
@@ -4,6 +4,28 @@ 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
+
22
+ ## [0.15.2] - 2026-03-31
23
+
24
+
25
+ ### Changed
26
+
27
+ - Extended .pr_agent.toml with harness conformance checks for cross-backend validation
28
+
7
29
  ## [0.15.1] - 2026-03-30
8
30
 
9
31
 
@@ -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.1
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
 
@@ -0,0 +1,3 @@
1
+ from importlib.metadata import version as _v
2
+
3
+ __version__ = _v("agentirc-cli")
@@ -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"