agentirc-cli 4.3.4__tar.gz → 4.3.5__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-4.3.4 → agentirc_cli-4.3.5}/CHANGELOG.md +7 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/PKG-INFO +1 -1
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/agent.py +188 -135
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/bot.py +11 -5
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/mesh.py +84 -65
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/server.py +80 -40
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/agent_runner.py +79 -67
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/daemon.py +43 -36
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/irc_transport.py +15 -6
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/skill/irc_client.py +8 -5
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/daemon.py +41 -34
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/irc_transport.py +15 -6
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/agent_runner.py +83 -70
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/daemon.py +43 -36
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/irc_transport.py +15 -6
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/supervisor.py +13 -11
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/agent_runner.py +14 -8
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/daemon.py +43 -36
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/irc_transport.py +15 -6
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/skill/irc_client.py +8 -5
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/observer.py +22 -9
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/overview/collector.py +27 -8
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/overview/renderer_web.py +100 -40
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/persistence.py +130 -97
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/server_link.py +92 -57
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/skills/rooms.py +93 -61
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/skills/threads.py +114 -97
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/daemon.py +35 -21
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/pyproject.toml +1 -1
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/uv.lock +1 -1
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.claude/skills/pr-review/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.claude/skills/run-tests/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.flake8 +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.github/workflows/pages.yml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.github/workflows/publish.yml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.github/workflows/security-checks.yml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.github/workflows/tests.yml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.gitignore +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.markdownlint-cli2.yaml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.pr_agent.toml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.pre-commit-config.yaml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/.pylintrc +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/CLAUDE.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/CNAME +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/Gemfile +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/Gemfile.lock +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/LICENSE +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/README.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/SECURITY.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/_config.yml +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/_sass/color_schemes/anthropic.scss +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/_sass/custom/custom.scss +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/__main__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/aio.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/bots/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/bots/bot.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/bots/bot_manager.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/bots/config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/bots/http_listener.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/bots/template_engine.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/bots/virtual_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/channel.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/shared/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/shared/constants.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/shared/display.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/shared/ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/shared/mesh.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/shared/process.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/cli/skills.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/message_buffer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/skill/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/skill/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/socket_server.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/supervisor.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/acp/webhook.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/__main__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/agent_runner.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/message_buffer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/skill/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/skill/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/skill/irc_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/socket_server.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/supervisor.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/claude/webhook.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/message_buffer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/skill/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/skill/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/skill/irc_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/socket_server.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/codex/webhook.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/message_buffer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/skill/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/skill/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/socket_server.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/supervisor.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/clients/copilot/webhook.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/app.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/commands.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/widgets/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/widgets/chat.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/widgets/info_panel.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/console/widgets/sidebar.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/credentials.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/learn_prompt.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/mesh_config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/overview/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/overview/model.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/overview/renderer_text.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/overview/web/style.css +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/pidfile.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/commands.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/extensions/federation.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/extensions/history.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/extensions/icons.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/extensions/rooms.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/extensions/tags.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/extensions/threads.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/message.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/protocol-index.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/protocol/replies.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/__main__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/channel.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/ircd.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/remote_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/room_store.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/rooms_util.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/skill.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/skills/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/skills/history.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/skills/icon.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/server/thread_store.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/culture/skills/culture/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/agent-lifecycle.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/agentic-self-learn.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/agent-client.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/agent-harness-spec.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/harness-conformance.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/index.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/layer1-core-irc.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/layer2-attention.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/layer3-skills.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/layer4-federation.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/layer5-agent-harness.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/server-architecture.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/architecture/threads.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/channel-polling.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/acp/overview.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/claude/configuration.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/claude/context-management.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/claude/irc-tools.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/claude/overview.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/claude/setup.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/claude/supervisor.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/claude/webhooks.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/codex/configuration.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/codex/context-management.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/codex/irc-tools.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/codex/overview.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/codex/setup.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/codex/supervisor.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/codex/webhooks.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/copilot/configuration.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/copilot/context-management.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/copilot/irc-tools.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/copilot/overview.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/copilot/setup.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/copilot/supervisor.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/clients/copilot/webhooks.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/culture-cli.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/getting-started.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/index.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/SECURITY.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/bots.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/ci.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/cli.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/docs-site.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/index.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/ops-tooling.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/overview.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/operations/publishing.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/resources/github-copilot-sdk-instructions.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/rooms.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/server-rename.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/01-pair-programming.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/02-code-review-ensemble.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/03-cross-server-delegation.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/04-knowledge-propagation.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/05-the-observer.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/06-cross-server-ops.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/07-supervisor-intervention.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/08-apps-as-agents.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/09-research-swarm.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases/10-agent-lifecycle.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/use-cases-index.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/docs/what-is-culture.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/README.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/irc_transport.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/message_buffer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/skill/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/skill/irc_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/socket_server.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/packages/agent-harness/webhook.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/plugins/claude-code/skills/culture/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/plugins/claude-code/skills/irc/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/sonar-project.properties +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/__init__.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/conftest.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_acp_daemon.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_agent_runner.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_archive.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_bot.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_bot_config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_bot_manager.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_bots_integration.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_channel.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_codex_daemon.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_connection.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_console_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_console_commands.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_console_connection.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_console_icons.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_console_integration.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_copilot_daemon.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_daemon.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_daemon_config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_daemon_ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_discovery.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_federation.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_history.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_http_listener.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_integration_layer5.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_ipc.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_irc_transport.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_link_reconnect.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_mention_alias.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_mention_target_cleanup.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_mentions.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_mesh_config.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_message.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_message_buffer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_messaging.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_modes.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_overview_cli.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_overview_collector.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_overview_model.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_overview_renderer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_overview_web.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_persistence.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_pidfile.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_poll_loop.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_room_persistence.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_rooms.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_rooms_federation.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_rooms_integration.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_server_icon_skill.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_setup_update_cli.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_skill_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_skills.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_socket_server.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_supervisor.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_template_engine.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_thread_buffer.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_threads.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_virtual_client.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_wait_for_port.py +0 -0
- {agentirc_cli-4.3.4 → agentirc_cli-4.3.5}/tests/test_webhook.py +0 -0
|
@@ -4,6 +4,13 @@ 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
|
+
## [4.3.5] - 2026-04-07
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Reduce cognitive complexity in 30+ functions across backend clients, server code, CLI submodules, and standalone files to meet SonarCloud threshold (≤15)
|
|
13
|
+
|
|
7
14
|
## [4.3.4] - 2026-04-07
|
|
8
15
|
|
|
9
16
|
|
|
@@ -201,59 +201,83 @@ def dispatch(args: argparse.Namespace) -> None:
|
|
|
201
201
|
# -----------------------------------------------------------------------
|
|
202
202
|
|
|
203
203
|
|
|
204
|
-
def
|
|
205
|
-
"""Build a
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
)
|
|
215
|
-
if args.agent == "copilot":
|
|
216
|
-
from culture.clients.copilot.config import AgentConfig as CopilotAgentConfig
|
|
217
|
-
|
|
218
|
-
return CopilotAgentConfig(
|
|
219
|
-
nick=full_nick,
|
|
220
|
-
agent="copilot",
|
|
221
|
-
directory=os.getcwd(),
|
|
222
|
-
channels=[DEFAULT_CHANNEL],
|
|
223
|
-
)
|
|
224
|
-
if args.agent == "acp":
|
|
225
|
-
import json as _json
|
|
204
|
+
def _create_codex_config(full_nick: str) -> AgentConfig:
|
|
205
|
+
"""Build a CodexAgentConfig."""
|
|
206
|
+
from culture.clients.codex.config import AgentConfig as CodexAgentConfig
|
|
207
|
+
|
|
208
|
+
return CodexAgentConfig(
|
|
209
|
+
nick=full_nick,
|
|
210
|
+
agent="codex",
|
|
211
|
+
directory=os.getcwd(),
|
|
212
|
+
channels=[DEFAULT_CHANNEL],
|
|
213
|
+
)
|
|
226
214
|
|
|
227
|
-
from culture.clients.acp.config import AgentConfig as ACPAgentConfig
|
|
228
215
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
216
|
+
def _create_copilot_config(full_nick: str) -> AgentConfig:
|
|
217
|
+
"""Build a CopilotAgentConfig."""
|
|
218
|
+
from culture.clients.copilot.config import AgentConfig as CopilotAgentConfig
|
|
219
|
+
|
|
220
|
+
return CopilotAgentConfig(
|
|
221
|
+
nick=full_nick,
|
|
222
|
+
agent="copilot",
|
|
223
|
+
directory=os.getcwd(),
|
|
224
|
+
channels=[DEFAULT_CHANNEL],
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _parse_acp_command(raw_command: str | None) -> list[str]:
|
|
229
|
+
"""Parse and validate the ACP command from CLI args."""
|
|
230
|
+
import json as _json
|
|
231
|
+
|
|
232
|
+
acp_cmd = ["opencode", "acp"]
|
|
233
|
+
if raw_command:
|
|
234
|
+
try:
|
|
235
|
+
acp_cmd = _json.loads(raw_command)
|
|
236
|
+
except _json.JSONDecodeError:
|
|
237
|
+
acp_cmd = raw_command.split()
|
|
238
|
+
if not isinstance(acp_cmd, list) or not acp_cmd or not all(isinstance(s, str) for s in acp_cmd):
|
|
239
|
+
print("Error: --acp-command must be a non-empty list of strings", file=sys.stderr)
|
|
240
|
+
sys.exit(1)
|
|
241
|
+
return acp_cmd
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def _create_acp_config(full_nick: str, args: argparse.Namespace) -> AgentConfig:
|
|
245
|
+
"""Build an ACPAgentConfig."""
|
|
246
|
+
from culture.clients.acp.config import AgentConfig as ACPAgentConfig
|
|
247
|
+
|
|
248
|
+
acp_cmd = _parse_acp_command(args.acp_command)
|
|
249
|
+
return ACPAgentConfig(
|
|
250
|
+
nick=full_nick,
|
|
251
|
+
agent="acp",
|
|
252
|
+
acp_command=acp_cmd,
|
|
253
|
+
directory=os.getcwd(),
|
|
254
|
+
channels=[DEFAULT_CHANNEL],
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _create_default_config(full_nick: str, backend: str) -> AgentConfig:
|
|
259
|
+
"""Build a default (claude) AgentConfig."""
|
|
249
260
|
return AgentConfig(
|
|
250
261
|
nick=full_nick,
|
|
251
|
-
agent=
|
|
262
|
+
agent=backend,
|
|
252
263
|
directory=os.getcwd(),
|
|
253
264
|
channels=[DEFAULT_CHANNEL],
|
|
254
265
|
)
|
|
255
266
|
|
|
256
267
|
|
|
268
|
+
def _create_agent_config(args: argparse.Namespace, full_nick: str) -> AgentConfig:
|
|
269
|
+
"""Build a backend-specific AgentConfig from CLI args."""
|
|
270
|
+
factories = {
|
|
271
|
+
"codex": lambda: _create_codex_config(full_nick),
|
|
272
|
+
"copilot": lambda: _create_copilot_config(full_nick),
|
|
273
|
+
"acp": lambda: _create_acp_config(full_nick, args),
|
|
274
|
+
}
|
|
275
|
+
factory = factories.get(args.agent)
|
|
276
|
+
if factory:
|
|
277
|
+
return factory()
|
|
278
|
+
return _create_default_config(full_nick, args.agent)
|
|
279
|
+
|
|
280
|
+
|
|
257
281
|
def _cmd_create(args: argparse.Namespace) -> None:
|
|
258
282
|
config = load_config_or_default(args.config)
|
|
259
283
|
|
|
@@ -387,6 +411,32 @@ def _probe_server_connection(host: str, port: int, server_name: str) -> None:
|
|
|
387
411
|
sys.exit(1)
|
|
388
412
|
|
|
389
413
|
|
|
414
|
+
def _start_foreground(config: DaemonConfig, agents: list[AgentConfig]) -> None:
|
|
415
|
+
"""Start a single agent in the foreground."""
|
|
416
|
+
if len(agents) != 1:
|
|
417
|
+
print("--foreground requires a single agent nick, not --all", file=sys.stderr)
|
|
418
|
+
sys.exit(1)
|
|
419
|
+
agent = agents[0]
|
|
420
|
+
print(f"Starting agent {agent.nick} in foreground...")
|
|
421
|
+
asyncio.run(_run_single_agent(config, agent))
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def _start_background(config: DaemonConfig, agents: list[AgentConfig]) -> None:
|
|
425
|
+
"""Start agents in background mode (fork on Unix, single on Windows)."""
|
|
426
|
+
if sys.platform == "win32":
|
|
427
|
+
if len(agents) != 1:
|
|
428
|
+
print(
|
|
429
|
+
"Multi-agent daemon mode not supported on Windows. Start agents individually.",
|
|
430
|
+
file=sys.stderr,
|
|
431
|
+
)
|
|
432
|
+
sys.exit(1)
|
|
433
|
+
agent = agents[0]
|
|
434
|
+
print(f"Starting agent {agent.nick}...")
|
|
435
|
+
asyncio.run(_run_single_agent(config, agent))
|
|
436
|
+
else:
|
|
437
|
+
_run_multi_agents(config, agents)
|
|
438
|
+
|
|
439
|
+
|
|
390
440
|
def _cmd_start(args: argparse.Namespace) -> None:
|
|
391
441
|
config = load_config(args.config)
|
|
392
442
|
|
|
@@ -395,86 +445,88 @@ def _cmd_start(args: argparse.Namespace) -> None:
|
|
|
395
445
|
server_name = config.server.name
|
|
396
446
|
_probe_server_connection(config.server.host, config.server.port, server_name)
|
|
397
447
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
if foreground:
|
|
401
|
-
if len(agents) != 1:
|
|
402
|
-
print("--foreground requires a single agent nick, not --all", file=sys.stderr)
|
|
403
|
-
sys.exit(1)
|
|
404
|
-
agent = agents[0]
|
|
405
|
-
print(f"Starting agent {agent.nick} in foreground...")
|
|
406
|
-
asyncio.run(_run_single_agent(config, agent))
|
|
448
|
+
if getattr(args, "foreground", False):
|
|
449
|
+
_start_foreground(config, agents)
|
|
407
450
|
else:
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
451
|
+
_start_background(config, agents)
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def _make_backend_config(config: DaemonConfig, backend_daemon_config_cls):
|
|
455
|
+
"""Build a backend-specific DaemonConfig from the base config."""
|
|
456
|
+
return backend_daemon_config_cls(
|
|
457
|
+
server=config.server,
|
|
458
|
+
webhooks=config.webhooks,
|
|
459
|
+
buffer_size=config.buffer_size,
|
|
460
|
+
agents=config.agents,
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def _create_codex_daemon(config: DaemonConfig, agent: AgentConfig):
|
|
465
|
+
"""Create a Codex backend daemon."""
|
|
466
|
+
from culture.clients.codex.config import DaemonConfig as CodexDaemonConfig
|
|
467
|
+
from culture.clients.codex.daemon import CodexDaemon
|
|
468
|
+
|
|
469
|
+
return CodexDaemon(_make_backend_config(config, CodexDaemonConfig), agent)
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
def _coerce_to_acp_agent(agent: AgentConfig):
|
|
473
|
+
"""Ensure agent is an ACPAgentConfig, converting if necessary."""
|
|
474
|
+
from culture.clients.acp.config import AgentConfig as ACPAgentConfig
|
|
475
|
+
|
|
476
|
+
if isinstance(agent, ACPAgentConfig):
|
|
477
|
+
return agent
|
|
478
|
+
return ACPAgentConfig(
|
|
479
|
+
nick=agent.nick,
|
|
480
|
+
agent="acp",
|
|
481
|
+
acp_command=getattr(agent, "acp_command", None) or ["opencode", "acp"],
|
|
482
|
+
directory=agent.directory,
|
|
483
|
+
channels=agent.channels,
|
|
484
|
+
model=agent.model,
|
|
485
|
+
system_prompt=agent.system_prompt,
|
|
486
|
+
tags=agent.tags,
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
def _create_acp_daemon(config: DaemonConfig, agent: AgentConfig):
|
|
491
|
+
"""Create an ACP backend daemon."""
|
|
492
|
+
from culture.clients.acp.config import DaemonConfig as ACPDaemonConfig
|
|
493
|
+
from culture.clients.acp.daemon import ACPDaemon
|
|
494
|
+
|
|
495
|
+
return ACPDaemon(
|
|
496
|
+
_make_backend_config(config, ACPDaemonConfig),
|
|
497
|
+
_coerce_to_acp_agent(agent),
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
def _create_copilot_daemon(config: DaemonConfig, agent: AgentConfig):
|
|
502
|
+
"""Create a Copilot backend daemon."""
|
|
503
|
+
from culture.clients.copilot.config import DaemonConfig as CopilotDaemonConfig
|
|
504
|
+
from culture.clients.copilot.daemon import CopilotDaemon
|
|
505
|
+
|
|
506
|
+
return CopilotDaemon(_make_backend_config(config, CopilotDaemonConfig), agent)
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
def _create_claude_daemon(config: DaemonConfig, agent: AgentConfig):
|
|
510
|
+
"""Create the default Claude backend daemon."""
|
|
511
|
+
from culture.clients.claude.daemon import AgentDaemon
|
|
512
|
+
|
|
513
|
+
return AgentDaemon(config, agent)
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
_BACKEND_DAEMON_FACTORIES = {
|
|
517
|
+
"codex": _create_codex_daemon,
|
|
518
|
+
"acp": _create_acp_daemon,
|
|
519
|
+
"opencode": _create_acp_daemon,
|
|
520
|
+
"copilot": _create_copilot_daemon,
|
|
521
|
+
}
|
|
421
522
|
|
|
422
523
|
|
|
423
524
|
async def _run_single_agent(config: DaemonConfig, agent: AgentConfig) -> None:
|
|
424
525
|
"""Run a single agent daemon in the foreground."""
|
|
425
526
|
backend = getattr(agent, "agent", "claude")
|
|
426
527
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
from culture.clients.codex.daemon import CodexDaemon
|
|
430
|
-
|
|
431
|
-
codex_config = CodexDaemonConfig(
|
|
432
|
-
server=config.server,
|
|
433
|
-
webhooks=config.webhooks,
|
|
434
|
-
buffer_size=config.buffer_size,
|
|
435
|
-
agents=config.agents,
|
|
436
|
-
)
|
|
437
|
-
daemon = CodexDaemon(codex_config, agent)
|
|
438
|
-
elif backend in ("acp", "opencode"):
|
|
439
|
-
from culture.clients.acp.config import AgentConfig as ACPAgentConfig
|
|
440
|
-
from culture.clients.acp.config import DaemonConfig as ACPDaemonConfig
|
|
441
|
-
from culture.clients.acp.daemon import ACPDaemon
|
|
442
|
-
|
|
443
|
-
acp_config = ACPDaemonConfig(
|
|
444
|
-
server=config.server,
|
|
445
|
-
webhooks=config.webhooks,
|
|
446
|
-
buffer_size=config.buffer_size,
|
|
447
|
-
agents=config.agents,
|
|
448
|
-
)
|
|
449
|
-
if not isinstance(agent, ACPAgentConfig):
|
|
450
|
-
acp_agent = ACPAgentConfig(
|
|
451
|
-
nick=agent.nick,
|
|
452
|
-
agent="acp",
|
|
453
|
-
acp_command=getattr(agent, "acp_command", None) or ["opencode", "acp"],
|
|
454
|
-
directory=agent.directory,
|
|
455
|
-
channels=agent.channels,
|
|
456
|
-
model=agent.model,
|
|
457
|
-
system_prompt=agent.system_prompt,
|
|
458
|
-
tags=agent.tags,
|
|
459
|
-
)
|
|
460
|
-
else:
|
|
461
|
-
acp_agent = agent
|
|
462
|
-
daemon = ACPDaemon(acp_config, acp_agent)
|
|
463
|
-
elif backend == "copilot":
|
|
464
|
-
from culture.clients.copilot.config import DaemonConfig as CopilotDaemonConfig
|
|
465
|
-
from culture.clients.copilot.daemon import CopilotDaemon
|
|
466
|
-
|
|
467
|
-
copilot_config = CopilotDaemonConfig(
|
|
468
|
-
server=config.server,
|
|
469
|
-
webhooks=config.webhooks,
|
|
470
|
-
buffer_size=config.buffer_size,
|
|
471
|
-
agents=config.agents,
|
|
472
|
-
)
|
|
473
|
-
daemon = CopilotDaemon(copilot_config, agent)
|
|
474
|
-
else:
|
|
475
|
-
from culture.clients.claude.daemon import AgentDaemon
|
|
476
|
-
|
|
477
|
-
daemon = AgentDaemon(config, agent)
|
|
528
|
+
factory = _BACKEND_DAEMON_FACTORIES.get(backend, _create_claude_daemon)
|
|
529
|
+
daemon = factory(config, agent)
|
|
478
530
|
|
|
479
531
|
stop_event = asyncio.Event()
|
|
480
532
|
daemon.set_stop_event(stop_event)
|
|
@@ -524,30 +576,31 @@ def _run_multi_agents(config: DaemonConfig, agents: list[AgentConfig]) -> None:
|
|
|
524
576
|
print(f"Started {agent.nick} (PID {pid})")
|
|
525
577
|
|
|
526
578
|
|
|
527
|
-
def
|
|
528
|
-
|
|
529
|
-
|
|
579
|
+
def _resolve_agents_to_stop(config, args) -> list:
|
|
580
|
+
"""Resolve which agents should be stopped, or exit with an error."""
|
|
530
581
|
if args.all:
|
|
531
|
-
|
|
532
|
-
|
|
582
|
+
return config.agents
|
|
583
|
+
if args.nick:
|
|
533
584
|
agent = config.get_agent(args.nick)
|
|
534
585
|
if not agent:
|
|
535
586
|
print(f"Agent '{args.nick}' not found in config", file=sys.stderr)
|
|
536
587
|
sys.exit(1)
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
)
|
|
549
|
-
sys.exit(1)
|
|
588
|
+
return [agent]
|
|
589
|
+
if len(config.agents) == 1:
|
|
590
|
+
return config.agents
|
|
591
|
+
if len(config.agents) == 0:
|
|
592
|
+
print(NO_AGENTS_MSG, file=sys.stderr)
|
|
593
|
+
sys.exit(1)
|
|
594
|
+
print(
|
|
595
|
+
"Multiple agents configured. Specify a nick or use --all.",
|
|
596
|
+
file=sys.stderr,
|
|
597
|
+
)
|
|
598
|
+
sys.exit(1)
|
|
550
599
|
|
|
600
|
+
|
|
601
|
+
def _cmd_stop(args: argparse.Namespace) -> None:
|
|
602
|
+
config = load_config_or_default(args.config)
|
|
603
|
+
agents = _resolve_agents_to_stop(config, args)
|
|
551
604
|
for agent in agents:
|
|
552
605
|
stop_agent(agent.nick)
|
|
553
606
|
|
|
@@ -152,6 +152,15 @@ def _bot_stop(args: argparse.Namespace) -> None:
|
|
|
152
152
|
print("(Live reload via IPC will be available in a future release.)")
|
|
153
153
|
|
|
154
154
|
|
|
155
|
+
def _should_include_bot(bot_config, owner: str | None, show_archived: bool) -> bool:
|
|
156
|
+
"""Return True if the bot should be included in the listing."""
|
|
157
|
+
if owner and bot_config.owner != owner:
|
|
158
|
+
return False
|
|
159
|
+
if not show_archived and bot_config.archived:
|
|
160
|
+
return False
|
|
161
|
+
return True
|
|
162
|
+
|
|
163
|
+
|
|
155
164
|
def _load_and_filter_bots(args) -> list:
|
|
156
165
|
"""Load bot configs, filtering by owner and archived status."""
|
|
157
166
|
from culture.bots.config import BOTS_DIR, load_bot_config
|
|
@@ -168,11 +177,8 @@ def _load_and_filter_bots(args) -> list:
|
|
|
168
177
|
config = load_bot_config(yaml_path)
|
|
169
178
|
except Exception:
|
|
170
179
|
continue
|
|
171
|
-
if
|
|
172
|
-
|
|
173
|
-
if not show_all and config.archived:
|
|
174
|
-
continue
|
|
175
|
-
bots.append(config)
|
|
180
|
+
if _should_include_bot(config, args.owner, show_all):
|
|
181
|
+
bots.append(config)
|
|
176
182
|
return bots
|
|
177
183
|
|
|
178
184
|
|
|
@@ -124,36 +124,16 @@ def dispatch(args: argparse.Namespace) -> None:
|
|
|
124
124
|
# -----------------------------------------------------------------------
|
|
125
125
|
|
|
126
126
|
|
|
127
|
-
def
|
|
128
|
-
"""
|
|
127
|
+
def _collect_mesh_data(host: str, port: int, server_name: str, message_limit: int):
|
|
128
|
+
"""Collect mesh state, exiting with an error message on connection failure."""
|
|
129
129
|
from culture.overview.collector import collect_mesh_state
|
|
130
|
-
from culture.overview.renderer_text import render_text
|
|
131
|
-
|
|
132
|
-
config = load_config_or_default(args.config)
|
|
133
|
-
message_limit = max(1, min(args.messages, 20))
|
|
134
|
-
refresh_interval = max(1, args.refresh)
|
|
135
|
-
|
|
136
|
-
if args.serve:
|
|
137
|
-
from culture.overview.renderer_web import serve_web
|
|
138
130
|
|
|
139
|
-
serve_web(
|
|
140
|
-
host=config.server.host,
|
|
141
|
-
port=config.server.port,
|
|
142
|
-
server_name=config.server.name,
|
|
143
|
-
room_filter=args.room,
|
|
144
|
-
agent_filter=args.agent,
|
|
145
|
-
message_limit=message_limit,
|
|
146
|
-
refresh_interval=refresh_interval,
|
|
147
|
-
)
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
host, port = config.server.host, config.server.port
|
|
151
131
|
try:
|
|
152
|
-
|
|
132
|
+
return asyncio.run(
|
|
153
133
|
collect_mesh_state(
|
|
154
134
|
host=host,
|
|
155
135
|
port=port,
|
|
156
|
-
server_name=
|
|
136
|
+
server_name=server_name,
|
|
157
137
|
message_limit=message_limit,
|
|
158
138
|
)
|
|
159
139
|
)
|
|
@@ -165,13 +145,40 @@ def _cmd_overview(args: argparse.Namespace) -> None:
|
|
|
165
145
|
sys.exit(1)
|
|
166
146
|
except TimeoutError:
|
|
167
147
|
print(
|
|
168
|
-
f"Error: server at {host}:{port} not responding
|
|
148
|
+
f"Error: server at {host}:{port} not responding — it may still be starting up",
|
|
169
149
|
file=sys.stderr,
|
|
170
150
|
)
|
|
171
151
|
sys.exit(1)
|
|
172
152
|
except OSError as exc:
|
|
173
153
|
print(f"Error: {exc}", file=sys.stderr)
|
|
174
154
|
sys.exit(1)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _cmd_overview(args: argparse.Namespace) -> None:
|
|
158
|
+
"""Show mesh overview."""
|
|
159
|
+
from culture.overview.renderer_text import render_text
|
|
160
|
+
|
|
161
|
+
config = load_config_or_default(args.config)
|
|
162
|
+
message_limit = max(1, min(args.messages, 20))
|
|
163
|
+
refresh_interval = max(1, args.refresh)
|
|
164
|
+
|
|
165
|
+
if args.serve:
|
|
166
|
+
from culture.overview.renderer_web import serve_web
|
|
167
|
+
|
|
168
|
+
serve_web(
|
|
169
|
+
host=config.server.host,
|
|
170
|
+
port=config.server.port,
|
|
171
|
+
server_name=config.server.name,
|
|
172
|
+
room_filter=args.room,
|
|
173
|
+
agent_filter=args.agent,
|
|
174
|
+
message_limit=message_limit,
|
|
175
|
+
refresh_interval=refresh_interval,
|
|
176
|
+
)
|
|
177
|
+
return
|
|
178
|
+
|
|
179
|
+
mesh = _collect_mesh_data(
|
|
180
|
+
config.server.host, config.server.port, config.server.name, message_limit
|
|
181
|
+
)
|
|
175
182
|
output = render_text(
|
|
176
183
|
mesh,
|
|
177
184
|
room_filter=args.room,
|
|
@@ -466,6 +473,32 @@ def _wait_for_server_port(port: int, retries: int = 50, interval: float = 0.1) -
|
|
|
466
473
|
time.sleep(interval)
|
|
467
474
|
|
|
468
475
|
|
|
476
|
+
def _dry_run_restart(mesh, server_name: str) -> None:
|
|
477
|
+
"""Print what a restart would do without executing."""
|
|
478
|
+
for agent in mesh.agents:
|
|
479
|
+
print(f"[dry-run] Would stop agent {server_name}-{agent.nick}")
|
|
480
|
+
print(f"[dry-run] Would stop server {server_name}")
|
|
481
|
+
print("[dry-run] Would regenerate auto-start entries")
|
|
482
|
+
print(f"[dry-run] Would start server {server_name}")
|
|
483
|
+
for agent in mesh.agents:
|
|
484
|
+
print(f"[dry-run] Would start agent {server_name}-{agent.nick}")
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def _restart_single_service(svc_name: str, fallback_cmd: list[str], restart_service_fn) -> None:
|
|
488
|
+
"""Restart a service, falling back to a CLI command if no service file exists."""
|
|
489
|
+
print(f" Restarting {svc_name}...")
|
|
490
|
+
if restart_service_fn(svc_name):
|
|
491
|
+
return
|
|
492
|
+
if sys.platform == "win32":
|
|
493
|
+
print(
|
|
494
|
+
" No service file found. Run 'culture mesh setup' to install services; starting via CLI...",
|
|
495
|
+
file=sys.stderr,
|
|
496
|
+
)
|
|
497
|
+
else:
|
|
498
|
+
print(" No service file found, starting via CLI...")
|
|
499
|
+
subprocess.run(fallback_cmd, check=False)
|
|
500
|
+
|
|
501
|
+
|
|
469
502
|
def _restart_mesh_services(
|
|
470
503
|
mesh, server_name: str, culture_bin: str, config_path: str, dry_run: bool
|
|
471
504
|
) -> None:
|
|
@@ -473,13 +506,7 @@ def _restart_mesh_services(
|
|
|
473
506
|
print(f"Restarting mesh node '{server_name}'...")
|
|
474
507
|
|
|
475
508
|
if dry_run:
|
|
476
|
-
|
|
477
|
-
print(f"[dry-run] Would stop agent {server_name}-{agent.nick}")
|
|
478
|
-
print(f"[dry-run] Would stop server {server_name}")
|
|
479
|
-
print("[dry-run] Would regenerate auto-start entries")
|
|
480
|
-
print(f"[dry-run] Would start server {server_name}")
|
|
481
|
-
for agent in mesh.agents:
|
|
482
|
-
print(f"[dry-run] Would start agent {server_name}-{agent.nick}")
|
|
509
|
+
_dry_run_restart(mesh, server_name)
|
|
483
510
|
return
|
|
484
511
|
|
|
485
512
|
for agent in mesh.agents:
|
|
@@ -511,45 +538,37 @@ def _restart_mesh_services(
|
|
|
511
538
|
install_service(f"culture-agent-{full_nick}", agent_cmd, f"culture agent {full_nick}")
|
|
512
539
|
|
|
513
540
|
server_svc = f"culture-server-{server_name}"
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
"--name",
|
|
529
|
-
server_name,
|
|
530
|
-
"--host",
|
|
531
|
-
mesh.server.host,
|
|
532
|
-
"--port",
|
|
533
|
-
str(mesh.server.port),
|
|
534
|
-
"--mesh-config",
|
|
535
|
-
config_path,
|
|
536
|
-
],
|
|
537
|
-
check=False,
|
|
538
|
-
)
|
|
541
|
+
server_fallback = [
|
|
542
|
+
culture_bin,
|
|
543
|
+
"server",
|
|
544
|
+
"start",
|
|
545
|
+
"--name",
|
|
546
|
+
server_name,
|
|
547
|
+
"--host",
|
|
548
|
+
mesh.server.host,
|
|
549
|
+
"--port",
|
|
550
|
+
str(mesh.server.port),
|
|
551
|
+
"--mesh-config",
|
|
552
|
+
config_path,
|
|
553
|
+
]
|
|
554
|
+
_restart_single_service(server_svc, server_fallback, restart_service)
|
|
539
555
|
|
|
540
556
|
_wait_for_server_port(mesh.server.port)
|
|
541
557
|
|
|
542
558
|
for agent in mesh.agents:
|
|
543
559
|
full_nick = f"{server_name}-{agent.nick}"
|
|
544
560
|
agent_svc = f"culture-agent-{full_nick}"
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
561
|
+
workdir = os.path.expanduser(agent.workdir)
|
|
562
|
+
agent_config_path = os.path.join(workdir, CULTURE_DIR, AGENTS_YAML)
|
|
563
|
+
agent_fallback = [
|
|
564
|
+
culture_bin,
|
|
565
|
+
"agent",
|
|
566
|
+
"start",
|
|
567
|
+
full_nick,
|
|
568
|
+
"--config",
|
|
569
|
+
agent_config_path,
|
|
570
|
+
]
|
|
571
|
+
_restart_single_service(agent_svc, agent_fallback, restart_service)
|
|
553
572
|
|
|
554
573
|
print()
|
|
555
574
|
|