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.
- agentirc_cli-0.16.0/.pr_agent.toml +38 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/CHANGELOG.md +22 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/CLAUDE.md +1 -1
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/PKG-INFO +5 -2
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/README.md +4 -1
- agentirc_cli-0.16.0/agentirc/__init__.py +3 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/cli.py +66 -38
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/agent_runner.py +31 -18
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/config.py +4 -2
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/daemon.py +43 -30
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/irc_transport.py +1 -1
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/SKILL.md +9 -9
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/irc_client.py +5 -5
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/socket_server.py +1 -1
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/webhook.py +1 -1
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/config.py +5 -1
- agentirc_cli-0.16.0/agentirc/clients/claude/supervisor.py +141 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/config.py +3 -1
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/config.py +3 -1
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/learn_prompt.py +5 -2
- agentirc_cli-0.16.0/docs/agent-client.md +28 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/agent-harness-spec.md +7 -6
- agentirc_cli-0.16.0/docs/clients/acp/overview.md +140 -0
- agentirc_cli-0.16.0/docs/harness-conformance.md +84 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer5-agent-harness.md +1 -1
- agentirc_cli-0.16.0/docs/superpowers/plans/2026-03-30-overview.md +1626 -0
- agentirc_cli-0.16.0/docs/superpowers/specs/2026-03-30-overview-design.md +328 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/pyproject.toml +2 -2
- agentirc_cli-0.15.1/tests/test_opencode_daemon.py → agentirc_cli-0.16.0/tests/test_acp_daemon.py +26 -24
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/uv.lock +1 -1
- agentirc_cli-0.15.1/.pr_agent.toml +0 -9
- agentirc_cli-0.15.1/agentirc/__init__.py +0 -1
- agentirc_cli-0.15.1/agentirc/clients/opencode/supervisor.py +0 -163
- agentirc_cli-0.15.1/docs/agent-client.md +0 -11
- agentirc_cli-0.15.1/docs/clients/opencode/configuration.md +0 -187
- agentirc_cli-0.15.1/docs/clients/opencode/context-management.md +0 -73
- agentirc_cli-0.15.1/docs/clients/opencode/irc-tools.md +0 -186
- agentirc_cli-0.15.1/docs/clients/opencode/overview.md +0 -125
- agentirc_cli-0.15.1/docs/clients/opencode/setup.md +0 -214
- agentirc_cli-0.15.1/docs/clients/opencode/supervisor.md +0 -126
- agentirc_cli-0.15.1/docs/clients/opencode/webhooks.md +0 -91
- agentirc_cli-0.15.1/docs/opencode-backend.md +0 -6
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.claude/skills/pr-review/SKILL.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.github/workflows/pages.yml +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.github/workflows/publish.yml +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.github/workflows/tests.yml +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.gitignore +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/.markdownlint-cli2.yaml +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/CNAME +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/Gemfile +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/Gemfile.lock +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/LICENSE +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/_config.yml +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/_sass/color_schemes/anthropic.scss +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/_sass/custom/custom.scss +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/__main__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/__init__.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/__init__.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/ipc.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/message_buffer.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/skill/__init__.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/claude → agentirc_cli-0.16.0/agentirc/clients/acp}/supervisor.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/__main__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/agent_runner.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/daemon.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/ipc.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/irc_transport.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/message_buffer.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/skill/SKILL.md +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/codex → agentirc_cli-0.16.0/agentirc/clients/claude}/skill/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/skill/irc_client.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/socket_server.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/claude/webhook.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/agent_runner.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/daemon.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/ipc.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/irc_transport.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/message_buffer.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/skill/SKILL.md +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/copilot → agentirc_cli-0.16.0/agentirc/clients/codex}/skill/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/skill/irc_client.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/socket_server.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/supervisor.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/codex/webhook.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/agent_runner.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/daemon.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/ipc.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/irc_transport.py +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/message_buffer.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/skill/SKILL.md +0 -0
- {agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/copilot}/skill/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/skill/irc_client.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/socket_server.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/supervisor.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/clients/copilot/webhook.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/observer.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/collector.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/model.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/renderer_text.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/renderer_web.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/overview/web/style.css +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/pidfile.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/commands.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/federation.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/history.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/rooms.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/extensions/tags.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/message.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/protocol-index.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/protocol/replies.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/__main__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/channel.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/client.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/config.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/ircd.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/remote_client.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/room_store.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/rooms_util.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/server_link.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skill.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skills/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skills/history.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/agentirc/server/skills/rooms.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/ci.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/cli.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/configuration.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/context-management.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/irc-tools.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/overview.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/setup.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/supervisor.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/claude/webhooks.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/configuration.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/context-management.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/irc-tools.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/overview.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/setup.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/supervisor.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/codex/webhooks.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/configuration.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/context-management.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/irc-tools.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/overview.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/setup.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/supervisor.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/clients/copilot/webhooks.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/codex-backend.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/copilot-backend.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/design.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/docs-site.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/getting-started.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/grow-your-agent.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer1-core-irc.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer2-attention.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer3-skills.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/layer4-federation.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/overview.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/publishing.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/resources/github-copilot-sdk-instructions.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/rooms.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/server-architecture.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/01-pair-programming.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/02-code-review-ensemble.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/03-cross-server-delegation.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/04-knowledge-propagation.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/05-the-observer.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/06-cross-server-ops.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/07-supervisor-intervention.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/08-apps-as-agents.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/09-research-swarm.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases/10-grow-your-agent.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/docs/use-cases-index.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/index.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/README.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/config.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/daemon.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/ipc.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/irc_transport.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/message_buffer.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/skill/SKILL.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/skill/irc_client.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/socket_server.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/packages/agent-harness/webhook.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/plugins/claude-code/skills/irc/SKILL.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/plugins/codex/skills/agentirc-irc/SKILL.md +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/__init__.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/conftest.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_agent_runner.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_channel.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_codex_daemon.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_connection.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_copilot_daemon.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_daemon.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_daemon_config.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_daemon_ipc.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_discovery.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_federation.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_history.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_integration_layer5.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_ipc.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_irc_transport.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_mentions.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_message.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_message_buffer.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_messaging.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_modes.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_cli.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_collector.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_model.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_renderer.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_overview_web.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_room_persistence.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_rooms.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_rooms_federation.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_rooms_integration.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_skill_client.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_skills.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_socket_server.py +0 -0
- {agentirc_cli-0.15.1 → agentirc_cli-0.16.0}/tests/test_supervisor.py +0 -0
- {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`, `
|
|
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.
|
|
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>
|
|
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>
|
|
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", "
|
|
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", "
|
|
171
|
-
help="Target agent: claude, codex,
|
|
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
|
|
533
|
-
from agentirc.clients.
|
|
534
|
-
from agentirc.clients.
|
|
535
|
-
DaemonConfig as
|
|
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
|
|
538
|
-
|
|
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
|
-
|
|
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
|
|
1022
|
-
"""Return the path to the bundled
|
|
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", "
|
|
1052
|
+
return os.path.join(os.path.dirname(agentirc.__file__), "clients", "copilot", "skill", "SKILL.md")
|
|
1025
1053
|
|
|
1026
1054
|
|
|
1027
|
-
def
|
|
1028
|
-
"""Install IRC skill for
|
|
1029
|
-
src =
|
|
1030
|
-
dest_dir = os.path.expanduser("~/.
|
|
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
|
|
1064
|
+
print(f"Installed Copilot skill: {dest}")
|
|
1037
1065
|
|
|
1038
1066
|
|
|
1039
|
-
def
|
|
1040
|
-
"""Return the path to the bundled
|
|
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", "
|
|
1070
|
+
return os.path.join(os.path.dirname(agentirc.__file__), "clients", "acp", "skill", "SKILL.md")
|
|
1043
1071
|
|
|
1044
1072
|
|
|
1045
|
-
def
|
|
1046
|
-
"""Install IRC skill for
|
|
1047
|
-
src =
|
|
1048
|
-
dest_dir = os.path.expanduser("~/.
|
|
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
|
|
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|
|
|
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,
|
|
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
|
-
"""
|
|
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
|
|
17
|
-
"""Manages an
|
|
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
|
|
66
|
+
"""Start the ACP agent as a subprocess and initialize a session."""
|
|
56
67
|
self._stopping = False
|
|
57
68
|
|
|
58
|
-
# Isolate from host config (
|
|
59
|
-
self._isolated_home = tempfile.mkdtemp(prefix="agentirc-
|
|
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
|
|
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
|
-
|
|
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-
|
|
100
|
+
"clientInfo": {"name": "agentirc-acp", "version": "0.1.0"},
|
|
89
101
|
})
|
|
90
|
-
logger.info("
|
|
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("
|
|
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("
|
|
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
|
|
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("
|
|
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
|
|
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("
|
|
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("
|
|
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("
|
|
376
|
+
logger.exception("ACP turn error")
|
|
364
377
|
|
|
365
378
|
except asyncio.CancelledError:
|
|
366
379
|
pass
|
{agentirc_cli-0.15.1/agentirc/clients/opencode → agentirc_cli-0.16.0/agentirc/clients/acp}/config.py
RENAMED
|
@@ -20,7 +20,8 @@ class ServerConnConfig:
|
|
|
20
20
|
@dataclass
|
|
21
21
|
class SupervisorConfig:
|
|
22
22
|
"""Supervisor sub-agent settings."""
|
|
23
|
-
model: str = "
|
|
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 = "
|
|
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"
|