agentirc-cli 6.2.3__tar.gz → 7.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.github/workflows/security-checks.yml +1 -1
  2. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/CHANGELOG.md +95 -0
  3. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/PKG-INFO +1 -1
  4. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/client.py +185 -46
  5. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/config.py +1 -0
  6. agentirc_cli-7.1.0/culture/agentirc/events.py +117 -0
  7. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/ircd.py +260 -27
  8. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/server_link.py +131 -31
  9. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/skill.py +19 -9
  10. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/skills/history.py +28 -0
  11. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/skills/rooms.py +17 -1
  12. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/bots/bot.py +121 -16
  13. agentirc_cli-7.1.0/culture/bots/bot_manager.py +197 -0
  14. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/bots/config.py +61 -10
  15. agentirc_cli-7.1.0/culture/bots/filter_dsl.py +339 -0
  16. agentirc_cli-7.1.0/culture/bots/system/__init__.py +36 -0
  17. agentirc_cli-7.1.0/culture/bots/system/welcome/__init__.py +1 -0
  18. agentirc_cli-7.1.0/culture/bots/system/welcome/bot.yaml +11 -0
  19. agentirc_cli-7.1.0/culture/bots/system/welcome/handler.py +1 -0
  20. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/bots/template_engine.py +11 -6
  21. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/bots/virtual_client.py +43 -5
  22. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/agent.py +11 -5
  23. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/channel.py +14 -12
  24. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/mesh.py +64 -33
  25. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/server.py +58 -49
  26. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/shared/display.py +49 -36
  27. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/agent_runner.py +52 -47
  28. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/daemon.py +16 -11
  29. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/irc_transport.py +13 -0
  30. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/agent_runner.py +19 -16
  31. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/daemon.py +36 -29
  32. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/irc_transport.py +13 -0
  33. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/daemon.py +34 -20
  34. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/irc_transport.py +13 -0
  35. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/daemon.py +16 -11
  36. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/irc_transport.py +13 -0
  37. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/client.py +1 -1
  38. agentirc_cli-7.1.0/culture/constants.py +20 -0
  39. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/observer.py +34 -18
  40. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/persistence.py +34 -15
  41. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/commands.py +1 -0
  42. agentirc_cli-7.1.0/culture/protocol/extensions/events.md +145 -0
  43. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/extensions/federation.md +4 -0
  44. agentirc_cli-7.1.0/culture/protocol/extensions/icons.md +117 -0
  45. agentirc_cli-7.1.0/culture/protocol/message.py +128 -0
  46. agentirc_cli-7.1.0/docs/agentirc/bots.md +223 -0
  47. agentirc_cli-7.1.0/docs/agentirc/events.md +146 -0
  48. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/cli/index.md +6 -0
  49. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/server/architecture.md +4 -1
  50. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/server/config.md +18 -0
  51. agentirc_cli-7.1.0/docs/superpowers/plans/2026-04-15-mesh-events.md +3252 -0
  52. agentirc_cli-7.1.0/docs/superpowers/specs/2026-04-15-mesh-events-design.md +380 -0
  53. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/daemon.py +38 -31
  54. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/irc_transport.py +18 -0
  55. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/pyproject.toml +2 -1
  56. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/conftest.py +121 -6
  57. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_agent_runner.py +1 -2
  58. agentirc_cli-7.1.0/tests/test_bot_config_fires_event_toplevel.py +114 -0
  59. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_console_client.py +8 -6
  60. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_console_fixes_224_227.py +4 -1
  61. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_daemon_config.py +3 -7
  62. agentirc_cli-7.1.0/tests/test_events_basic.py +292 -0
  63. agentirc_cli-7.1.0/tests/test_events_bot_chain.py +59 -0
  64. agentirc_cli-7.1.0/tests/test_events_bot_trigger.py +99 -0
  65. agentirc_cli-7.1.0/tests/test_events_cap_fallback.py +59 -0
  66. agentirc_cli-7.1.0/tests/test_events_catalog.py +70 -0
  67. agentirc_cli-7.1.0/tests/test_events_federation.py +110 -0
  68. agentirc_cli-7.1.0/tests/test_events_history.py +64 -0
  69. agentirc_cli-7.1.0/tests/test_events_lifecycle.py +343 -0
  70. agentirc_cli-7.1.0/tests/test_events_reserved_nick.py +68 -0
  71. agentirc_cli-7.1.0/tests/test_filter_dsl.py +99 -0
  72. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_history.py +21 -19
  73. agentirc_cli-7.1.0/tests/test_irc_transport_tags.py +106 -0
  74. agentirc_cli-7.1.0/tests/test_message_tags.py +75 -0
  75. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_overview_collector.py +26 -12
  76. agentirc_cli-7.1.0/tests/test_persistence_timeout.py +59 -0
  77. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_skills.py +7 -3
  78. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_supervisor.py +1 -2
  79. agentirc_cli-7.1.0/tests/test_welcome_bot.py +87 -0
  80. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/uv.lock +1 -1
  81. agentirc_cli-6.2.3/culture/bots/bot_manager.py +0 -111
  82. agentirc_cli-6.2.3/culture/protocol/extensions/icons.md +0 -89
  83. agentirc_cli-6.2.3/culture/protocol/message.py +0 -58
  84. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.claude/agents/doc-test-alignment.md +0 -0
  85. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.claude/skills/pr-review/SKILL.md +0 -0
  86. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.claude/skills/run-tests/SKILL.md +0 -0
  87. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
  88. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.flake8 +0 -0
  89. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.github/workflows/docs-check.yml +0 -0
  90. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.github/workflows/publish.yml +0 -0
  91. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.github/workflows/tests.yml +0 -0
  92. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.gitignore +0 -0
  93. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.markdownlint-cli2.yaml +0 -0
  94. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.pr_agent.toml +0 -0
  95. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.pre-commit-config.yaml +0 -0
  96. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/.pylintrc +0 -0
  97. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/CLAUDE.md +0 -0
  98. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/Gemfile +0 -0
  99. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/Gemfile.lock +0 -0
  100. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/LICENSE +0 -0
  101. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/README.md +0 -0
  102. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/SECURITY.md +0 -0
  103. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_config.agentirc.yml +0 -0
  104. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_config.base.yml +0 -0
  105. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_config.culture.yml +0 -0
  106. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_data/sites.yml +0 -0
  107. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_includes/head_custom.html +0 -0
  108. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_plugins/site_filter.rb +0 -0
  109. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_sass/color_schemes/anthropic.scss +0 -0
  110. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_sass/color_schemes/dark-terminal.scss +0 -0
  111. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/_sass/custom/custom.scss +0 -0
  112. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/assets/images/IMG_3183.png +0 -0
  113. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/assets/images/apple-touch-icon.png +0 -0
  114. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/assets/images/favicon-16x16.png +0 -0
  115. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/assets/images/favicon-32x32.png +0 -0
  116. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/assets/images/favicon.ico +0 -0
  117. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/assets/images/og-agentirc.png +0 -0
  118. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/assets/images/og-culture.png +0 -0
  119. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/__init__.py +0 -0
  120. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/__main__.py +0 -0
  121. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/CLAUDE.md +0 -0
  122. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/__init__.py +0 -0
  123. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/__main__.py +0 -0
  124. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/channel.py +0 -0
  125. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/docs/agentirc-architecture.md +0 -0
  126. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/docs/agentirc-features.md +0 -0
  127. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/docs/agentirc-skill.md +0 -0
  128. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/docs/agentirc.md +0 -0
  129. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/history_store.py +0 -0
  130. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/remote_client.py +0 -0
  131. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/room_store.py +0 -0
  132. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/rooms_util.py +0 -0
  133. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/skills/__init__.py +0 -0
  134. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/skills/icon.py +0 -0
  135. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/skills/threads.py +0 -0
  136. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/agentirc/thread_store.py +0 -0
  137. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/aio.py +0 -0
  138. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/bots/__init__.py +0 -0
  139. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/bots/http_listener.py +0 -0
  140. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/__init__.py +0 -0
  141. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/bot.py +0 -0
  142. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/shared/__init__.py +0 -0
  143. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/shared/constants.py +0 -0
  144. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/shared/formatting.py +0 -0
  145. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/shared/ipc.py +0 -0
  146. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/shared/mesh.py +0 -0
  147. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/shared/process.py +0 -0
  148. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/cli/skills.py +0 -0
  149. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/__init__.py +0 -0
  150. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/__init__.py +0 -0
  151. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/config.py +0 -0
  152. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/culture.yaml +0 -0
  153. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/ipc.py +0 -0
  154. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/message_buffer.py +0 -0
  155. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/skill/SKILL.md +0 -0
  156. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/skill/__init__.py +0 -0
  157. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/skill/irc_client.py +0 -0
  158. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/socket_server.py +0 -0
  159. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/supervisor.py +0 -0
  160. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/acp/webhook.py +0 -0
  161. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/__init__.py +0 -0
  162. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/__main__.py +0 -0
  163. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/config.py +0 -0
  164. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/culture.yaml +0 -0
  165. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/ipc.py +0 -0
  166. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/message_buffer.py +0 -0
  167. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/skill/SKILL.md +0 -0
  168. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/skill/__init__.py +0 -0
  169. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/skill/irc_client.py +0 -0
  170. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/socket_server.py +0 -0
  171. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/supervisor.py +0 -0
  172. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/claude/webhook.py +0 -0
  173. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/__init__.py +0 -0
  174. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/agent_runner.py +0 -0
  175. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/config.py +0 -0
  176. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/culture.yaml +0 -0
  177. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/ipc.py +0 -0
  178. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/message_buffer.py +0 -0
  179. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/skill/SKILL.md +0 -0
  180. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/skill/__init__.py +0 -0
  181. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/skill/irc_client.py +0 -0
  182. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/socket_server.py +0 -0
  183. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/supervisor.py +0 -0
  184. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/codex/webhook.py +0 -0
  185. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/__init__.py +0 -0
  186. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/agent_runner.py +0 -0
  187. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/config.py +0 -0
  188. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/culture.yaml +0 -0
  189. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/ipc.py +0 -0
  190. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/message_buffer.py +0 -0
  191. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/skill/SKILL.md +0 -0
  192. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/skill/__init__.py +0 -0
  193. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/skill/irc_client.py +0 -0
  194. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/socket_server.py +0 -0
  195. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/supervisor.py +0 -0
  196. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/clients/copilot/webhook.py +0 -0
  197. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/config.py +0 -0
  198. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/__init__.py +0 -0
  199. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/app.py +0 -0
  200. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/commands.py +0 -0
  201. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/status.py +0 -0
  202. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/widgets/__init__.py +0 -0
  203. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/widgets/chat.py +0 -0
  204. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/widgets/info_panel.py +0 -0
  205. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/console/widgets/sidebar.py +0 -0
  206. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/credentials.py +0 -0
  207. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/formatting.py +0 -0
  208. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/learn_prompt.py +0 -0
  209. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/mesh_config.py +0 -0
  210. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/overview/__init__.py +0 -0
  211. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/overview/collector.py +0 -0
  212. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/overview/model.py +0 -0
  213. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/overview/renderer_text.py +0 -0
  214. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/overview/renderer_web.py +0 -0
  215. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/overview/web/style.css +0 -0
  216. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/pidfile.py +0 -0
  217. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/__init__.py +0 -0
  218. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/extensions/history.md +0 -0
  219. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/extensions/rooms.md +0 -0
  220. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/extensions/tags.md +0 -0
  221. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/extensions/threads.md +0 -0
  222. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/protocol-index.md +0 -0
  223. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/protocol/replies.py +0 -0
  224. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/culture/skills/culture/SKILL.md +0 -0
  225. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/README.md +0 -0
  226. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/agentirc/architecture-overview.md +0 -0
  227. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/agentirc/index.md +0 -0
  228. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/agentirc/why-agentirc.md +0 -0
  229. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/agent-lifecycle.md +0 -0
  230. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/choose-a-harness.md +0 -0
  231. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/index.md +0 -0
  232. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/mental-model.md +0 -0
  233. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/operate.md +0 -0
  234. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/patterns.md +0 -0
  235. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/quickstart.md +0 -0
  236. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/reflective-development.md +0 -0
  237. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/vision-patterns-index.md +0 -0
  238. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/vision.md +0 -0
  239. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/culture/why-culture.md +0 -0
  240. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/architecture/agent-harness-spec.md +0 -0
  241. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/architecture/index.md +0 -0
  242. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/architecture/layers.md +0 -0
  243. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/architecture/threads.md +0 -0
  244. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/cli/commands.md +0 -0
  245. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/harnesses/acp.md +0 -0
  246. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/harnesses/claude.md +0 -0
  247. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/harnesses/codex.md +0 -0
  248. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/harnesses/copilot.md +0 -0
  249. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/harnesses/index.md +0 -0
  250. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/index.md +0 -0
  251. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/server/deployment.md +0 -0
  252. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/server/index.md +0 -0
  253. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/reference/server/security.md +0 -0
  254. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  255. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/concepts/federation.md +0 -0
  256. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/concepts/harnesses.md +0 -0
  257. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/concepts/humans-and-agents.md +0 -0
  258. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/concepts/index.md +0 -0
  259. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/concepts/persistence.md +0 -0
  260. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/concepts/rooms.md +0 -0
  261. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/demos/magic-demo.md +0 -0
  262. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/guides/first-session.md +0 -0
  263. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/guides/index.md +0 -0
  264. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/guides/join-as-human.md +0 -0
  265. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/guides/local-setup.md +0 -0
  266. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/guides/multi-machine.md +0 -0
  267. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/01-pair-programming.md +0 -0
  268. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/02-code-review-ensemble.md +0 -0
  269. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/03-cross-server-delegation.md +0 -0
  270. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/04-knowledge-propagation.md +0 -0
  271. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/05-the-observer.md +0 -0
  272. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/06-cross-server-ops.md +0 -0
  273. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/07-supervisor-intervention.md +0 -0
  274. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/08-apps-as-agents.md +0 -0
  275. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/09-research-swarm.md +0 -0
  276. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases/10-agent-lifecycle.md +0 -0
  277. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/shared/use-cases-index.md +0 -0
  278. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  279. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  280. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  281. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  282. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
  283. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
  284. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
  285. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -0
  286. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
  287. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-04-09-decentralized-agent-config.md +0 -0
  288. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/plans/2026-04-12-console-enhancements.md +0 -0
  289. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  290. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  291. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  292. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  293. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
  294. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
  295. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
  296. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
  297. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -0
  298. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -0
  299. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
  300. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
  301. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -0
  302. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-07-reflective-development-reframe-design.md +0 -0
  303. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-08-reflective-development-deepening-design.md +0 -0
  304. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-09-decentralized-agent-config-design.md +0 -0
  305. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/docs/superpowers/specs/2026-04-12-console-enhancements-design.md +0 -0
  306. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/favicon.ico +0 -0
  307. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/README.md +0 -0
  308. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/config.py +0 -0
  309. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/culture.yaml +0 -0
  310. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/ipc.py +0 -0
  311. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/message_buffer.py +0 -0
  312. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/skill/SKILL.md +0 -0
  313. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/skill/irc_client.py +0 -0
  314. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/socket_server.py +0 -0
  315. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/packages/agent-harness/webhook.py +0 -0
  316. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  317. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/plugins/claude-code/skills/culture/SKILL.md +0 -0
  318. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  319. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
  320. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/robots.txt +0 -0
  321. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/sonar-project.properties +0 -0
  322. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/__init__.py +0 -0
  323. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_acp_daemon.py +0 -0
  324. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_archive.py +0 -0
  325. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_bot.py +0 -0
  326. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_bot_config.py +0 -0
  327. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_bot_manager.py +0 -0
  328. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_bots_integration.py +0 -0
  329. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_channel.py +0 -0
  330. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_channel_cli.py +0 -0
  331. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_codex_daemon.py +0 -0
  332. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_connection.py +0 -0
  333. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_console_commands.py +0 -0
  334. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_console_connection.py +0 -0
  335. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_console_icons.py +0 -0
  336. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_console_integration.py +0 -0
  337. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_console_status.py +0 -0
  338. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_copilot_daemon.py +0 -0
  339. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_credentials.py +0 -0
  340. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_culture_config.py +0 -0
  341. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_daemon.py +0 -0
  342. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_daemon_ipc.py +0 -0
  343. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_discovery.py +0 -0
  344. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_display.py +0 -0
  345. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_federation.py +0 -0
  346. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_http_listener.py +0 -0
  347. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_integration_layer5.py +0 -0
  348. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_ipc.py +0 -0
  349. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_irc_transport.py +0 -0
  350. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_learn_prompt.py +0 -0
  351. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_link_reconnect.py +0 -0
  352. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_manifest_config.py +0 -0
  353. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_mention_alias.py +0 -0
  354. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_mention_target_cleanup.py +0 -0
  355. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_mention_warning.py +0 -0
  356. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_mentions.py +0 -0
  357. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_mesh_config.py +0 -0
  358. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_mesh_readiness.py +0 -0
  359. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_message.py +0 -0
  360. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_message_buffer.py +0 -0
  361. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_messaging.py +0 -0
  362. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_migrate_cli.py +0 -0
  363. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_modes.py +0 -0
  364. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_overview_cli.py +0 -0
  365. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_overview_model.py +0 -0
  366. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_overview_renderer.py +0 -0
  367. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_overview_web.py +0 -0
  368. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_persistence.py +0 -0
  369. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_pidfile.py +0 -0
  370. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_poll_loop.py +0 -0
  371. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_register_cli.py +0 -0
  372. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_room_persistence.py +0 -0
  373. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_rooms.py +0 -0
  374. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_rooms_federation.py +0 -0
  375. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_rooms_integration.py +0 -0
  376. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_server_icon_skill.py +0 -0
  377. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_setup_update_cli.py +0 -0
  378. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_skill_client.py +0 -0
  379. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_skill_docs.py +0 -0
  380. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_socket_server.py +0 -0
  381. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_template_engine.py +0 -0
  382. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_thread_buffer.py +0 -0
  383. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_threads.py +0 -0
  384. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_virtual_client.py +0 -0
  385. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_wait_for_port.py +0 -0
  386. {agentirc_cli-6.2.3 → agentirc_cli-7.1.0}/tests/test_webhook.py +0 -0
@@ -33,7 +33,7 @@ jobs:
33
33
  continue-on-error: true
34
34
 
35
35
  - name: Run Safety dependency check
36
- run: uv run safety check --full-report --output json > safety-results.json
36
+ run: uv run safety check --output json > safety-results.json
37
37
  continue-on-error: true
38
38
 
39
39
  - name: Upload Security Results
@@ -4,6 +4,101 @@ 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
+ ## [7.1.0] - 2026-04-17
8
+
9
+
10
+ ### Changed
11
+
12
+ - Refactored _handle_channel_mode in culture/agentirc/client.py: extracted _apply_mode_char and _broadcast_mode_change helpers to drop cognitive complexity from 21 to ≤15 (SonarCloud S3776)
13
+ - Background task GC safety in ircd.py _notify_local_quit: asyncio.ensure_future replaced with a tracked asyncio.create_task using the existing self._background_tasks set + add_done_callback(discard) pattern
14
+
15
+
16
+ ### Fixed
17
+
18
+ - culture mesh update no longer hangs on broken/unresponsive systemd units — all subprocess calls in persistence.py and cli/mesh.py now have explicit timeouts (30s for service restarts, 30s for CLI fallbacks, 120s for package upgrade)
19
+ - fires_event chain not triggering downstream bots (#260) — the bot.yaml loader now accepts fires_event at the top level as well as under output:, so configs that put the block at the top level emit events as expected
20
+ - Daemon log flushing stops after startup — replaced logging.basicConfig's default StreamHandler (which inherits stderr buffering from interpreter startup) with an explicit logging.FileHandler so runtime log records flush per-record
21
+
22
+ ## [7.0.4] - 2026-04-17
23
+
24
+
25
+ ### Fixed
26
+
27
+ - Reduce cognitive complexity and fix code quality issues across CLI modules (SonarCloud S3776, S1192, S5886, S108)
28
+
29
+ ## [7.0.3] - 2026-04-17
30
+
31
+
32
+ ### Fixed
33
+
34
+ - Duplicate _ERR_CHANNEL_PREFIX string in all 5 daemon files (S1192)
35
+ - Cognitive complexity in claude/daemon.py _poll_loop (CC 22, S3776)
36
+ - Cognitive complexity in agent-harness/daemon.py _poll_loop (CC 22, S3776)
37
+ - Cognitive complexity in codex/daemon.py _relay_response_to_irc (CC 44, S3776)
38
+ - Cognitive complexity in copilot/daemon.py _relay_response_to_irc (CC 23, S3776)
39
+ - Cognitive complexity in acp/daemon.py _relay_response_to_irc (CC 23, S3776)
40
+ - Cognitive complexity in acp/agent_runner.py start() (CC 17, S3776)
41
+
42
+ ## [7.0.2] - 2026-04-17
43
+
44
+
45
+ ### Fixed
46
+
47
+ - Cognitive complexity in observer.py (CC 22→~13)
48
+ - Cognitive complexity in ircd.py (CC 18→~12)
49
+ - Cognitive complexity in server_link.py (CC 33→~14)
50
+
51
+ ## [7.0.1] - 2026-04-17
52
+
53
+
54
+ ### Fixed
55
+
56
+ - Wrong AgentConfig/DaemonConfig import types in test helpers (S5655)
57
+ - Constant if-False condition replaced with unreachable yield pattern (S5797)
58
+
59
+ ## [7.0.0] - 2026-04-17
60
+
61
+ Mesh Events (issue #123) — lifecycle and activity notifications as IRCv3-tagged
62
+ PRIVMSGs, event-triggered bots, and pub/sub composition chains.
63
+
64
+ > Versions 6.3.0 through 6.11.2 were development increments for this feature
65
+ > and were never published. Their changes are consolidated here as 7.0.0.
66
+
67
+ ### Breaking Changes
68
+
69
+ None. Existing clients, bots, and federation links continue to work unchanged.
70
+ The major bump reflects the scope of the feature addition (new protocol verb,
71
+ new subsystem, new bot trigger type).
72
+
73
+ ### Added
74
+
75
+ - **Event system** — `system-<server>` pseudo-user surfaces lifecycle events
76
+ as IRCv3-tagged PRIVMSGs with `@event=<type>;event-data=<b64json>` tags
77
+ - **Built-in event catalog** — 18 event types across channel-scoped
78
+ (`user.join/part/quit`, `room.create/archive/meta`, `tags.update`) and global
79
+ (`agent.connect/disconnect`, `server.wake/sleep/link/unlink`,
80
+ `console.open/close`)
81
+ - **IRCv3 message-tags** — `Message.parse()` extracts tags; CAP negotiation
82
+ (`CAP REQ :message-tags`) in all agent backends and server
83
+ - **`#system` channel** — auto-created at startup for global event delivery;
84
+ `system-<server>` VirtualClient auto-joined
85
+ - **Reserved `system-*` nicks** — rejected for non-server clients
86
+ (`432 ERR_ERRONEUSNICKNAME`)
87
+ - **SEVENT S2S verb** — generic federation relay for lifecycle events with
88
+ `_origin` loop prevention and trust policy filtering
89
+ - **HistorySkill** stores lifecycle events — `HISTORY RECENT` replays
90
+ agent.connect, server.wake, room.create, etc.
91
+ - **Filter DSL** — safe recursive-descent expression parser (`==`, `!=`, `in`,
92
+ `and`, `or`, `not`, dotted field access) for bot event triggers
93
+ - **Bot event triggers** — `trigger.type: event` with filter DSL evaluation;
94
+ `fires_event` output for pub/sub bot chains with rate limiting (10/sec)
95
+ - **System bots** — package-bundled bots discovered at startup from
96
+ `culture/bots/system/<name>/bot.yaml`; welcome bot greets on `user.join`
97
+ - **All-backends CAP** — claude, codex, copilot, acp, and agent-harness
98
+ transports negotiate `message-tags` during connection
99
+ - **Documentation** — `docs/agentirc/events.md`, `docs/agentirc/bots.md`,
100
+ `culture/protocol/extensions/events.md`
101
+
7
102
  ## [6.2.3] - 2026-04-15
8
103
 
9
104
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 6.2.3
3
+ Version: 7.1.0
4
4
  Summary: Legacy alias for culture — install culture instead
5
5
  Project-URL: Homepage, https://github.com/OriNachum/culture
6
6
  Author: Ori Nachum
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING
9
9
  from culture.agentirc.channel import Channel
10
10
  from culture.agentirc.skill import Event, EventType
11
11
  from culture.aio import maybe_await
12
+ from culture.constants import SYSTEM_USER_PREFIX
12
13
  from culture.protocol import replies
13
14
  from culture.protocol.message import Message
14
15
 
@@ -35,6 +36,7 @@ class Client:
35
36
  self.channels: set[Channel] = set()
36
37
  self._registered = False
37
38
  self.tags: list[str] = []
39
+ self.caps: set[str] = set()
38
40
  self.modes: set[str] = set()
39
41
  self.icon: str | None = None
40
42
 
@@ -49,6 +51,28 @@ class Client:
49
51
  except OSError:
50
52
  pass # Client disconnected; cleanup happens in ircd._handle_connection
51
53
 
54
+ async def send_raw(self, line: str) -> None:
55
+ """Write a pre-formatted IRC line to the client socket.
56
+
57
+ Appends CRLF internally, matching ServerLink.send_raw convention.
58
+ """
59
+ try:
60
+ self.writer.write(f"{line}\r\n".encode("utf-8"))
61
+ await self.writer.drain()
62
+ except OSError:
63
+ pass # Client disconnected; cleanup happens in ircd._handle_connection
64
+
65
+ async def send_tagged(self, msg: Message) -> None:
66
+ """Send a Message, stripping tags for clients that haven't negotiated message-tags."""
67
+ if msg.tags and "message-tags" not in self.caps:
68
+ msg = Message(
69
+ tags={},
70
+ prefix=msg.prefix,
71
+ command=msg.command,
72
+ params=list(msg.params),
73
+ )
74
+ await self.send(msg)
75
+
52
76
  async def send_numeric(self, code: str, *params: str) -> None:
53
77
  target = self.nick or "*"
54
78
  msg = Message(
@@ -114,6 +138,29 @@ class Client:
114
138
  def _handle_pong(self, msg: Message) -> None:
115
139
  pass # Client responding to our ping
116
140
 
141
+ async def _handle_cap(self, msg: Message) -> None:
142
+ sub = msg.params[0].upper() if msg.params else ""
143
+ if sub == "LS":
144
+ await self.send_raw(
145
+ f":{self.server.config.name} CAP {self.nick or '*'} LS :message-tags"
146
+ )
147
+ elif sub == "REQ":
148
+ requested = msg.params[1].split() if len(msg.params) >= 2 else []
149
+ supported = {"message-tags"}
150
+ if all(cap in supported for cap in requested):
151
+ self.caps.update(requested)
152
+ await self.send_raw(
153
+ f":{self.server.config.name} CAP {self.nick or '*'}"
154
+ f" ACK :{' '.join(requested)}"
155
+ )
156
+ else:
157
+ await self.send_raw(
158
+ f":{self.server.config.name} CAP {self.nick or '*'}"
159
+ f" NAK :{' '.join(requested)}"
160
+ )
161
+ elif sub == "END":
162
+ pass # no registration-gating in v1
163
+
117
164
  async def _handle_nick(self, msg: Message) -> None:
118
165
  if not msg.params:
119
166
  await self.send_numeric(replies.ERR_NONICKNAMEGIVEN, "No nickname given")
@@ -121,6 +168,15 @@ class Client:
121
168
 
122
169
  nick = msg.params[0]
123
170
 
171
+ # Reject reserved system-* nick prefix
172
+ if nick.startswith(SYSTEM_USER_PREFIX):
173
+ await self.send_numeric(
174
+ replies.ERR_ERRONEUSNICKNAME,
175
+ nick,
176
+ "Nickname prefix 'system-' is reserved",
177
+ )
178
+ return
179
+
124
180
  # Enforce server name prefix
125
181
  expected_prefix = f"{self.server.config.name}-"
126
182
  if not nick.startswith(expected_prefix):
@@ -227,10 +283,6 @@ class Client:
227
283
  for member in list(channel.members):
228
284
  await member.send(join_msg)
229
285
 
230
- await self.server.emit_event(
231
- Event(type=EventType.JOIN, channel=channel_name, nick=self.nick)
232
- )
233
-
234
286
  # Send topic if set
235
287
  if channel.topic:
236
288
  await self.send_numeric(replies.RPL_TOPIC, channel_name, channel.topic)
@@ -238,6 +290,12 @@ class Client:
238
290
  # Send names list
239
291
  await self._send_names(channel)
240
292
 
293
+ # Emit event AFTER delivering all join-related numerics (topic, NAMES)
294
+ # so that the event PRIVMSG doesn't interleave with 353/366 in client buffers.
295
+ await self.server.emit_event(
296
+ Event(type=EventType.JOIN, channel=channel_name, nick=self.nick)
297
+ )
298
+
241
299
  async def _handle_part(self, msg: Message) -> None:
242
300
  if not msg.params:
243
301
  await self.send_numeric(replies.ERR_NEEDMOREPARAMS, "PART", replies.MSG_NEEDMOREPARAMS)
@@ -386,6 +444,56 @@ class Client:
386
444
  applied_modes.append(("+" if adding else "-") + ch)
387
445
  applied_params.append(target_nick)
388
446
 
447
+ _PARAM_MODES = frozenset({"o", "v", "S"})
448
+
449
+ async def _apply_mode_char(
450
+ self,
451
+ channel,
452
+ channel_name: str,
453
+ ch: str,
454
+ adding: bool,
455
+ param_queue: list[str],
456
+ applied_modes: list[str],
457
+ applied_params: list[str],
458
+ ) -> None:
459
+ """Apply a single mode character. Consumes one param from param_queue when needed."""
460
+ if ch == "R":
461
+ self._apply_mode_r(channel, adding, applied_modes)
462
+ return
463
+ if ch not in self._PARAM_MODES or not param_queue:
464
+ return
465
+ param_value = param_queue.pop(0)
466
+ if ch == "S":
467
+ self._apply_mode_s(channel, adding, param_value, applied_modes, applied_params)
468
+ else:
469
+ await self._apply_mode_membership(
470
+ channel,
471
+ channel_name,
472
+ ch,
473
+ adding,
474
+ param_value,
475
+ applied_modes,
476
+ applied_params,
477
+ )
478
+
479
+ async def _broadcast_mode_change(
480
+ self,
481
+ channel,
482
+ channel_name: str,
483
+ applied_modes: list[str],
484
+ applied_params: list[str],
485
+ ) -> None:
486
+ """Send the aggregated MODE message to all channel members."""
487
+ if not applied_modes:
488
+ return
489
+ mode_msg = Message(
490
+ prefix=self.prefix,
491
+ command="MODE",
492
+ params=[channel_name, "".join(applied_modes)] + applied_params,
493
+ )
494
+ for member in list(channel.members):
495
+ await member.send(mode_msg)
496
+
389
497
  async def _handle_channel_mode(self, msg: Message) -> None:
390
498
  channel_name = msg.params[0]
391
499
  channel = self.server.channels.get(channel_name)
@@ -399,7 +507,6 @@ class Client:
399
507
  await self.send_numeric(replies.RPL_CHANNELMODEIS, channel_name, "+")
400
508
  return
401
509
 
402
- modestring = msg.params[1]
403
510
  if not channel.is_operator(self):
404
511
  await self.send_numeric(
405
512
  replies.ERR_CHANOPRIVSNEEDED,
@@ -408,50 +515,90 @@ class Client:
408
515
  )
409
516
  return
410
517
 
518
+ modestring = msg.params[1]
411
519
  param_queue = list(msg.params[2:])
412
- param_modes = {"o", "v", "S"}
413
-
414
520
  adding = True
415
- applied_modes = []
521
+ applied_modes: list[str] = []
416
522
  applied_params: list[str] = []
417
523
  for ch in modestring:
418
524
  if ch == "+":
419
525
  adding = True
420
526
  elif ch == "-":
421
527
  adding = False
422
- elif ch == "R":
423
- self._apply_mode_r(channel, adding, applied_modes)
424
- elif ch in param_modes:
425
- if not param_queue:
426
- continue
427
- param_value = param_queue.pop(0)
428
- if ch == "S":
429
- self._apply_mode_s(channel, adding, param_value, applied_modes, applied_params)
430
- else:
431
- await self._apply_mode_membership(
432
- channel,
433
- channel_name,
434
- ch,
435
- adding,
436
- param_value,
437
- applied_modes,
438
- applied_params,
439
- )
528
+ else:
529
+ await self._apply_mode_char(
530
+ channel,
531
+ channel_name,
532
+ ch,
533
+ adding,
534
+ param_queue,
535
+ applied_modes,
536
+ applied_params,
537
+ )
440
538
 
441
539
  # Auto-promote if no operators remain
442
540
  if not channel.operators and channel.members:
443
541
  channel.operators.add(min(channel.members, key=lambda m: m.nick))
444
542
 
445
- if applied_modes:
446
- mode_msg = Message(
447
- prefix=self.prefix,
448
- command="MODE",
449
- params=[channel_name, "".join(applied_modes)] + applied_params,
543
+ await self._broadcast_mode_change(channel, channel_name, applied_modes, applied_params)
544
+
545
+ _VALID_USER_MODE_CHARS = frozenset("HABC")
546
+ _USER_MODE_EDGE_EVENTS: dict[tuple[str, bool], EventType] = {
547
+ ("A", True): EventType.AGENT_CONNECT,
548
+ ("A", False): EventType.AGENT_DISCONNECT,
549
+ ("C", True): EventType.CONSOLE_OPEN,
550
+ ("C", False): EventType.CONSOLE_CLOSE,
551
+ }
552
+
553
+ def _apply_user_mode_char(self, ch: str, adding: bool) -> EventType | None:
554
+ """Mutate ``self.modes`` for a single mode char and return the edge event, if any.
555
+
556
+ Returns None if the char is unknown or the transition was a no-op
557
+ (setting an already-set mode or clearing an already-clear one).
558
+ """
559
+ if ch not in self._VALID_USER_MODE_CHARS:
560
+ return None
561
+ had = ch in self.modes
562
+ if adding:
563
+ self.modes.add(ch)
564
+ else:
565
+ self.modes.discard(ch)
566
+ if had == adding:
567
+ return None
568
+ return self._USER_MODE_EDGE_EVENTS.get((ch, adding))
569
+
570
+ def _parse_mode_edges(self, modestring: str) -> list[EventType]:
571
+ """Apply each char of ``modestring`` and collect the emitted edge events."""
572
+ pending: list[EventType] = []
573
+ adding = True
574
+ for ch in modestring:
575
+ if ch == "+":
576
+ adding = True
577
+ elif ch == "-":
578
+ adding = False
579
+ else:
580
+ event = self._apply_user_mode_char(ch, adding)
581
+ if event is not None:
582
+ pending.append(event)
583
+ return pending
584
+
585
+ async def _emit_user_mode_events(self, pending: list[EventType]) -> None:
586
+ for event_type in pending:
587
+ await self.server.emit_event(
588
+ Event(
589
+ type=event_type,
590
+ channel=None,
591
+ nick=self.nick,
592
+ data={"nick": self.nick},
593
+ )
450
594
  )
451
- for member in list(channel.members):
452
- await member.send(mode_msg)
453
595
 
454
596
  async def _handle_user_mode(self, msg: Message) -> None:
597
+ # Reject pre-registration so an unregistered socket cannot inject
598
+ # agent.connect / console.open into #system by sending MODE after NICK
599
+ # but before USER.
600
+ if not self._registered:
601
+ return
455
602
  target_nick = msg.params[0]
456
603
  if target_nick != self.nick:
457
604
  await self.send_numeric(
@@ -459,19 +606,11 @@ class Client:
459
606
  "Can't change mode for other users",
460
607
  )
461
608
  return
462
- if len(msg.params) > 1:
463
- modestring = msg.params[1]
464
- adding = True
465
- for ch in modestring:
466
- if ch == "+":
467
- adding = True
468
- elif ch == "-":
469
- adding = False
470
- elif ch in ("H", "A", "B"):
471
- if adding:
472
- self.modes.add(ch)
473
- else:
474
- self.modes.discard(ch)
609
+
610
+ modestring = msg.params[1] if len(msg.params) > 1 else ""
611
+ pending = self._parse_mode_edges(modestring)
612
+ await self._emit_user_mode_events(pending)
613
+
475
614
  mode_str = "+" + "".join(sorted(self.modes)) if self.modes else "+"
476
615
  await self.send_numeric(replies.RPL_UMODEIS, mode_str)
477
616
 
@@ -22,3 +22,4 @@ class ServerConfig:
22
22
  webhook_port: int = 7680
23
23
  data_dir: str = ""
24
24
  links: list[LinkConfig] = field(default_factory=list)
25
+ system_bots: dict = field(default_factory=dict)
@@ -0,0 +1,117 @@
1
+ """Event type catalog and render-template registry.
2
+
3
+ Event type names follow the dotted-lowercase convention enforced by
4
+ `EVENT_TYPE_RE` in `culture.constants`. Render templates map a type to a
5
+ function that produces the human-readable PRIVMSG body for humans and
6
+ vanilla IRC clients. The structured payload is attached as IRCv3 message
7
+ tags by the server's emit path (see `culture/agentirc/ircd.py`); this
8
+ module is presentation-only.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import logging
14
+ from typing import Any, Callable
15
+
16
+ from culture.agentirc.skill import EventType
17
+ from culture.constants import EVENT_TYPE_RE
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ # Event types whose content is already delivered to clients via the normal
22
+ # IRC path (PRIVMSG, NOTICE, TOPIC) or has dedicated storage (threads).
23
+ # Used by both IRCd._surface_event_privmsg (to avoid double-delivery) and
24
+ # HistorySkill (to avoid double-storage). Keep this as the single source
25
+ # of truth — do not duplicate.
26
+ NO_SURFACE_EVENT_TYPES: frozenset[str] = frozenset(
27
+ {
28
+ EventType.MESSAGE.value,
29
+ EventType.THREAD_CREATE.value,
30
+ EventType.THREAD_MESSAGE.value,
31
+ EventType.THREAD_CLOSE.value,
32
+ EventType.TOPIC.value,
33
+ }
34
+ )
35
+
36
+ RenderFn = Callable[[dict[str, Any], str | None], str]
37
+
38
+ _TEMPLATES: dict[str, RenderFn] = {}
39
+
40
+
41
+ def register(event_type: str, fn: RenderFn) -> None:
42
+ _TEMPLATES[event_type] = fn
43
+
44
+
45
+ def validate_event_type(name: str) -> bool:
46
+ return bool(EVENT_TYPE_RE.match(name))
47
+
48
+
49
+ def render_event(event_type: str, data: dict[str, Any], channel: str | None) -> str:
50
+ fn = _TEMPLATES.get(event_type)
51
+ if fn is None:
52
+ return f"{event_type} {data}"
53
+ try:
54
+ return fn(data, channel)
55
+ except Exception:
56
+ logger.exception("render template for %s failed", event_type)
57
+ return f"{event_type} {data}"
58
+
59
+
60
+ # -------- built-in render templates --------
61
+
62
+
63
+ def _nick_action(verb: str) -> RenderFn:
64
+ def _render(data, channel):
65
+ nick = data.get("nick", "<unknown>")
66
+ if channel:
67
+ return f"{nick} {verb} {channel}"
68
+ return f"{nick} {verb}"
69
+
70
+ return _render
71
+
72
+
73
+ register("user.join", _nick_action("joined"))
74
+ register("user.part", _nick_action("left"))
75
+ register(
76
+ "user.quit",
77
+ lambda d, c: f"{d.get('nick', '<unknown>')} quit: {d.get('reason', '')}".rstrip(": "),
78
+ )
79
+
80
+ register("agent.connect", lambda d, c: f"{d.get('nick', '<unknown>')} connected")
81
+ register(
82
+ "agent.disconnect",
83
+ lambda d, c: f"{d.get('nick', '<unknown>')} disconnected",
84
+ )
85
+
86
+ register("console.open", lambda d, c: f"{d.get('nick', '<unknown>')} opened a console")
87
+ register("console.close", lambda d, c: f"{d.get('nick', '<unknown>')} closed their console")
88
+
89
+ register("server.wake", lambda d, c: f"server {d.get('server', '<unknown>')} is up")
90
+ register(
91
+ "server.sleep",
92
+ lambda d, c: f"server {d.get('server', '<unknown>')} is shutting down",
93
+ )
94
+ register("server.link", lambda d, c: f"linked to {d.get('peer', '<unknown>')}")
95
+ register("server.unlink", lambda d, c: f"unlinked from {d.get('peer', '<unknown>')}")
96
+
97
+ register("room.create", lambda d, c: f"{d.get('nick', '<unknown>')} created room {c}")
98
+ register("room.archive", lambda d, c: f"{d.get('nick', '<unknown>')} archived {c}")
99
+ register("room.meta", lambda d, c: f"{d.get('nick', '<unknown>')} updated {c} metadata")
100
+
101
+ register(
102
+ "thread.create",
103
+ lambda d, c: f"{d.get('nick', '<unknown>')} started thread [{d.get('thread', '?')}] in {c}",
104
+ )
105
+ register(
106
+ "thread.message",
107
+ lambda d, c: f"[{d.get('thread', '?')}] {d.get('nick', '<unknown>')}: {d.get('text', '')}",
108
+ )
109
+ register(
110
+ "thread.close",
111
+ lambda d, c: f"thread [{d.get('thread', '?')}] in {c} closed",
112
+ )
113
+
114
+ register(
115
+ "tags.update",
116
+ lambda d, c: f"{d.get('nick', '<unknown>')} tags → {', '.join(d.get('tags', []))}",
117
+ )