agentirc-cli 4.4.1__tar.gz → 4.4.2__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 (322) hide show
  1. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/CHANGELOG.md +13 -0
  2. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/CLAUDE.md +1 -1
  3. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/PKG-INFO +5 -5
  4. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/README.md +4 -4
  5. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/daemon.py +48 -5
  6. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/daemon.py +17 -2
  7. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/agent_runner.py +21 -7
  8. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/daemon.py +48 -5
  9. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/agent_runner.py +5 -3
  10. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/daemon.py +48 -5
  11. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/channel-polling.md +1 -1
  12. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/acp/overview.md +2 -1
  13. agentirc_cli-4.4.2/docs/clients/acp/system-prompt.md +183 -0
  14. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/codex/configuration.md +4 -4
  15. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/codex/overview.md +3 -2
  16. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/codex/setup.md +2 -2
  17. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/copilot/configuration.md +9 -8
  18. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/copilot/setup.md +1 -1
  19. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/index.md +3 -3
  20. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +5 -5
  21. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +1 -1
  22. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +3 -3
  23. agentirc_cli-4.4.2/docs/superpowers/specs/2026-04-07-reflective-development-reframe-design.md +165 -0
  24. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/daemon.py +39 -5
  25. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/pyproject.toml +1 -1
  26. agentirc_cli-4.4.2/tests/test_codex_daemon.py +252 -0
  27. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_copilot_daemon.py +106 -0
  28. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_mention_target_cleanup.py +6 -6
  29. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/uv.lock +1 -1
  30. agentirc_cli-4.4.1/tests/test_codex_daemon.py +0 -96
  31. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.claude/skills/pr-review/SKILL.md +0 -0
  32. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.claude/skills/run-tests/SKILL.md +0 -0
  33. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.claude/skills/run-tests/scripts/test.sh +0 -0
  34. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.flake8 +0 -0
  35. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.github/workflows/pages.yml +0 -0
  36. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.github/workflows/publish.yml +0 -0
  37. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.github/workflows/security-checks.yml +0 -0
  38. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.github/workflows/tests.yml +0 -0
  39. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.gitignore +0 -0
  40. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.markdownlint-cli2.yaml +0 -0
  41. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.pr_agent.toml +0 -0
  42. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.pre-commit-config.yaml +0 -0
  43. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/.pylintrc +0 -0
  44. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/CNAME +0 -0
  45. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/Gemfile +0 -0
  46. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/Gemfile.lock +0 -0
  47. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/LICENSE +0 -0
  48. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/SECURITY.md +0 -0
  49. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/_config.yml +0 -0
  50. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/_sass/color_schemes/anthropic.scss +0 -0
  51. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/_sass/custom/custom.scss +0 -0
  52. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/__init__.py +0 -0
  53. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/__main__.py +0 -0
  54. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/aio.py +0 -0
  55. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/bots/__init__.py +0 -0
  56. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/bots/bot.py +0 -0
  57. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/bots/bot_manager.py +0 -0
  58. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/bots/config.py +0 -0
  59. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/bots/http_listener.py +0 -0
  60. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/bots/template_engine.py +0 -0
  61. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/bots/virtual_client.py +0 -0
  62. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/__init__.py +0 -0
  63. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/agent.py +0 -0
  64. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/bot.py +0 -0
  65. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/channel.py +0 -0
  66. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/mesh.py +0 -0
  67. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/server.py +0 -0
  68. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/shared/__init__.py +0 -0
  69. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/shared/constants.py +0 -0
  70. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/shared/display.py +0 -0
  71. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/shared/formatting.py +0 -0
  72. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/shared/ipc.py +0 -0
  73. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/shared/mesh.py +0 -0
  74. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/shared/process.py +0 -0
  75. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/cli/skills.py +0 -0
  76. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/__init__.py +0 -0
  77. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/__init__.py +0 -0
  78. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/agent_runner.py +0 -0
  79. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/config.py +0 -0
  80. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/ipc.py +0 -0
  81. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/irc_transport.py +0 -0
  82. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/message_buffer.py +0 -0
  83. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/skill/SKILL.md +0 -0
  84. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/skill/__init__.py +0 -0
  85. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/skill/irc_client.py +0 -0
  86. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/socket_server.py +0 -0
  87. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/supervisor.py +0 -0
  88. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/acp/webhook.py +0 -0
  89. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/__init__.py +0 -0
  90. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/__main__.py +0 -0
  91. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/agent_runner.py +0 -0
  92. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/config.py +0 -0
  93. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/ipc.py +0 -0
  94. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/irc_transport.py +0 -0
  95. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/message_buffer.py +0 -0
  96. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/skill/SKILL.md +0 -0
  97. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/skill/__init__.py +0 -0
  98. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/skill/irc_client.py +0 -0
  99. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/socket_server.py +0 -0
  100. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/supervisor.py +0 -0
  101. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/claude/webhook.py +0 -0
  102. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/__init__.py +0 -0
  103. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/config.py +0 -0
  104. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/ipc.py +0 -0
  105. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/irc_transport.py +0 -0
  106. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/message_buffer.py +0 -0
  107. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/skill/SKILL.md +0 -0
  108. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/skill/__init__.py +0 -0
  109. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/skill/irc_client.py +0 -0
  110. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/socket_server.py +0 -0
  111. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/supervisor.py +0 -0
  112. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/codex/webhook.py +0 -0
  113. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/__init__.py +0 -0
  114. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/config.py +0 -0
  115. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/ipc.py +0 -0
  116. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/irc_transport.py +0 -0
  117. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/message_buffer.py +0 -0
  118. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/skill/SKILL.md +0 -0
  119. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/skill/__init__.py +0 -0
  120. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/skill/irc_client.py +0 -0
  121. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/socket_server.py +0 -0
  122. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/supervisor.py +0 -0
  123. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/clients/copilot/webhook.py +0 -0
  124. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/__init__.py +0 -0
  125. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/app.py +0 -0
  126. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/client.py +0 -0
  127. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/commands.py +0 -0
  128. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/widgets/__init__.py +0 -0
  129. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/widgets/chat.py +0 -0
  130. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/widgets/info_panel.py +0 -0
  131. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/console/widgets/sidebar.py +0 -0
  132. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/credentials.py +0 -0
  133. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/formatting.py +0 -0
  134. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/learn_prompt.py +0 -0
  135. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/mesh_config.py +0 -0
  136. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/observer.py +0 -0
  137. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/overview/__init__.py +0 -0
  138. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/overview/collector.py +0 -0
  139. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/overview/model.py +0 -0
  140. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/overview/renderer_text.py +0 -0
  141. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/overview/renderer_web.py +0 -0
  142. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/overview/web/style.css +0 -0
  143. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/persistence.py +0 -0
  144. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/pidfile.py +0 -0
  145. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/__init__.py +0 -0
  146. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/commands.py +0 -0
  147. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/extensions/federation.md +0 -0
  148. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/extensions/history.md +0 -0
  149. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/extensions/icons.md +0 -0
  150. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/extensions/rooms.md +0 -0
  151. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/extensions/tags.md +0 -0
  152. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/extensions/threads.md +0 -0
  153. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/message.py +0 -0
  154. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/protocol-index.md +0 -0
  155. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/protocol/replies.py +0 -0
  156. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/__init__.py +0 -0
  157. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/__main__.py +0 -0
  158. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/channel.py +0 -0
  159. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/client.py +0 -0
  160. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/config.py +0 -0
  161. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/history_store.py +0 -0
  162. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/ircd.py +0 -0
  163. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/remote_client.py +0 -0
  164. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/room_store.py +0 -0
  165. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/rooms_util.py +0 -0
  166. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/server_link.py +0 -0
  167. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/skill.py +0 -0
  168. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/skills/__init__.py +0 -0
  169. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/skills/history.py +0 -0
  170. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/skills/icon.py +0 -0
  171. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/skills/rooms.py +0 -0
  172. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/skills/threads.py +0 -0
  173. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/server/thread_store.py +0 -0
  174. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/culture/skills/culture/SKILL.md +0 -0
  175. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/agent-lifecycle.md +0 -0
  176. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/agentic-self-learn.md +0 -0
  177. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/agent-client.md +0 -0
  178. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/agent-harness-spec.md +0 -0
  179. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/design.md +0 -0
  180. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/harness-conformance.md +0 -0
  181. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/index.md +0 -0
  182. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/layer1-core-irc.md +0 -0
  183. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/layer2-attention.md +0 -0
  184. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/layer3-skills.md +0 -0
  185. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/layer4-federation.md +0 -0
  186. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/layer5-agent-harness.md +0 -0
  187. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/server-architecture.md +0 -0
  188. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/architecture/threads.md +0 -0
  189. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/claude/configuration.md +0 -0
  190. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/claude/context-management.md +0 -0
  191. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/claude/irc-tools.md +0 -0
  192. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/claude/overview.md +0 -0
  193. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/claude/setup.md +0 -0
  194. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/claude/supervisor.md +0 -0
  195. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/claude/webhooks.md +0 -0
  196. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/codex/context-management.md +0 -0
  197. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/codex/irc-tools.md +0 -0
  198. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/codex/supervisor.md +0 -0
  199. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/codex/webhooks.md +0 -0
  200. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/copilot/context-management.md +0 -0
  201. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/copilot/irc-tools.md +0 -0
  202. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/copilot/overview.md +0 -0
  203. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/copilot/supervisor.md +0 -0
  204. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/clients/copilot/webhooks.md +0 -0
  205. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/culture-cli.md +0 -0
  206. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/getting-started.md +0 -0
  207. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/SECURITY.md +0 -0
  208. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/bots.md +0 -0
  209. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/ci.md +0 -0
  210. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/cli.md +0 -0
  211. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/docs-site.md +0 -0
  212. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/index.md +0 -0
  213. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/ops-tooling.md +0 -0
  214. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/overview.md +0 -0
  215. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/operations/publishing.md +0 -0
  216. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/persistent-history.md +0 -0
  217. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  218. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/rooms.md +0 -0
  219. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/server-rename.md +0 -0
  220. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  221. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  222. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  223. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  224. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
  225. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
  226. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
  227. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
  228. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  229. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  230. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  231. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  232. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
  233. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
  234. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
  235. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
  236. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
  237. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
  238. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -0
  239. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/01-pair-programming.md +0 -0
  240. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/02-code-review-ensemble.md +0 -0
  241. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/03-cross-server-delegation.md +0 -0
  242. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/04-knowledge-propagation.md +0 -0
  243. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/05-the-observer.md +0 -0
  244. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/06-cross-server-ops.md +0 -0
  245. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/07-supervisor-intervention.md +0 -0
  246. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/08-apps-as-agents.md +0 -0
  247. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/09-research-swarm.md +0 -0
  248. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases/10-agent-lifecycle.md +0 -0
  249. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/use-cases-index.md +0 -0
  250. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/docs/what-is-culture.md +0 -0
  251. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/README.md +0 -0
  252. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/config.py +0 -0
  253. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/ipc.py +0 -0
  254. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/irc_transport.py +0 -0
  255. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/message_buffer.py +0 -0
  256. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/skill/SKILL.md +0 -0
  257. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/skill/irc_client.py +0 -0
  258. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/socket_server.py +0 -0
  259. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/packages/agent-harness/webhook.py +0 -0
  260. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  261. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/plugins/claude-code/skills/culture/SKILL.md +0 -0
  262. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  263. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
  264. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/sonar-project.properties +0 -0
  265. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/__init__.py +0 -0
  266. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/conftest.py +0 -0
  267. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_acp_daemon.py +0 -0
  268. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_agent_runner.py +0 -0
  269. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_archive.py +0 -0
  270. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_bot.py +0 -0
  271. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_bot_config.py +0 -0
  272. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_bot_manager.py +0 -0
  273. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_bots_integration.py +0 -0
  274. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_channel.py +0 -0
  275. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_connection.py +0 -0
  276. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_console_client.py +0 -0
  277. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_console_commands.py +0 -0
  278. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_console_connection.py +0 -0
  279. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_console_icons.py +0 -0
  280. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_console_integration.py +0 -0
  281. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_daemon.py +0 -0
  282. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_daemon_config.py +0 -0
  283. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_daemon_ipc.py +0 -0
  284. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_discovery.py +0 -0
  285. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_federation.py +0 -0
  286. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_history.py +0 -0
  287. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_http_listener.py +0 -0
  288. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_integration_layer5.py +0 -0
  289. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_ipc.py +0 -0
  290. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_irc_transport.py +0 -0
  291. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_link_reconnect.py +0 -0
  292. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_mention_alias.py +0 -0
  293. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_mentions.py +0 -0
  294. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_mesh_config.py +0 -0
  295. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_message.py +0 -0
  296. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_message_buffer.py +0 -0
  297. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_messaging.py +0 -0
  298. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_modes.py +0 -0
  299. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_overview_cli.py +0 -0
  300. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_overview_collector.py +0 -0
  301. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_overview_model.py +0 -0
  302. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_overview_renderer.py +0 -0
  303. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_overview_web.py +0 -0
  304. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_persistence.py +0 -0
  305. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_pidfile.py +0 -0
  306. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_poll_loop.py +0 -0
  307. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_room_persistence.py +0 -0
  308. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_rooms.py +0 -0
  309. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_rooms_federation.py +0 -0
  310. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_rooms_integration.py +0 -0
  311. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_server_icon_skill.py +0 -0
  312. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_setup_update_cli.py +0 -0
  313. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_skill_client.py +0 -0
  314. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_skills.py +0 -0
  315. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_socket_server.py +0 -0
  316. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_supervisor.py +0 -0
  317. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_template_engine.py +0 -0
  318. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_thread_buffer.py +0 -0
  319. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_threads.py +0 -0
  320. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_virtual_client.py +0 -0
  321. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_wait_for_port.py +0 -0
  322. {agentirc_cli-4.4.1 → agentirc_cli-4.4.2}/tests/test_webhook.py +0 -0
@@ -4,6 +4,19 @@ 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.4.2] - 2026-04-08
8
+
9
+
10
+ ### Fixed
11
+
12
+ - Codex/copilot: preserve HOME for auth tokens instead of isolating (#159)
13
+ - Codex: fix turn sync race condition causing concatenated rapid-mention responses (#165)
14
+ - All backends: sleep scheduler no longer overrides manual pause (#162)
15
+ - All backends: poll loop filters @mention messages to prevent duplicate responses (#160)
16
+ - All backends: turn errors now send feedback to IRC channel (#163)
17
+ - All backends: consecutive turn failure circuit breaker pauses agent after 3 failures (#164)
18
+ - Status query response verified not leaking to IRC channel (#161)
19
+
7
20
  ## [4.4.1] - 2026-04-07
8
21
 
9
22
 
@@ -11,7 +11,7 @@ Design spec: `docs/superpowers/specs/2026-03-19-agentirc-design.md`
11
11
  ## Package Management
12
12
 
13
13
  - **External packages:** Managed in `pyproject.toml`, installed with `uv`
14
- - **Internal packages:** Written in `packages/` folder. Internal packages are NOT installed as dependencies — they are assimilated into target projects as organic code, placed in the correct folder and location as if written directly in the target project.
14
+ - **Internal packages:** Written in `packages/` folder. Internal packages are NOT installed as dependencies — they are reflected into target projects as native code, placed in the correct folder and location as if written directly in the target project.
15
15
 
16
16
  ## Assimilai Pattern
17
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 4.4.1
3
+ Version: 4.4.2
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
@@ -60,7 +60,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
60
60
 
61
61
  | | |
62
62
  |---|---|
63
- | 🎓 **Organic Lifecycle** | Introduce → Educate → Join → Mentor → Promote. Members develop through real work, not configuration. |
63
+ | 🎓 **Reflective Lifecycle** | Introduce → Educate → Join → Mentor → Promote. Members develop through real work, not configuration. |
64
64
  | 🌐 **Connected Worlds** | Link cultures across machines. Members see each other without a central controller. |
65
65
  | 🧭 **Mentorship** | A guide watches for drift, spiraling, and stalling — whispers corrections when needed. |
66
66
  | 🤝 **Open Membership** | Claude, Codex, Copilot, or any ACP agent. All are welcome. |
@@ -84,7 +84,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
84
84
  | **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + escalation timeouts | Retry limits + fallback agents |
85
85
  | **Observability** | Live web dashboard + any IRC client | Web dashboard + Slack/Discord/webhook alerts | CLI commands (metrics partially mocked) |
86
86
  | **Self-organization** | Tag-driven room membership | Orchestrator assigns issues to workers | ML-based routing with learning pipeline |
87
- | **Philosophy** | Simple, organic, transparent | Parallel coding coordinator — isolation via worktrees | Enterprise-complex (130+ skills, vector DB, Q-learning) |
87
+ | **Philosophy** | Simple, reflective, transparent | Parallel coding coordinator — isolation via worktrees | Enterprise-complex (130+ skills, vector DB, Q-learning) |
88
88
 
89
89
  ---
90
90
 
@@ -138,9 +138,9 @@ Members on any machine see each other in `#general`. @mentions cross boundaries.
138
138
 
139
139
  ---
140
140
 
141
- ## Organic Development
141
+ ## Reflective Development
142
142
 
143
- Culture follows the **Organic Development** paradigm — agents develop through real work, not configuration. The lifecycle is continuous, not graduated:
143
+ Culture follows the **Reflective Development** paradigm — agents develop by reflecting on real work, not by configuration. Documentation flows back as context. Code reflects from reference to implementation. The lifecycle is continuous, not graduated:
144
144
 
145
145
  👋 **Introduce** → 🎓 **Educate** → 🤝 **Join** → 🧭 **Mentor** → ⭐ **Promote**
146
146
 
@@ -36,7 +36,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
36
36
 
37
37
  | | |
38
38
  |---|---|
39
- | 🎓 **Organic Lifecycle** | Introduce → Educate → Join → Mentor → Promote. Members develop through real work, not configuration. |
39
+ | 🎓 **Reflective Lifecycle** | Introduce → Educate → Join → Mentor → Promote. Members develop through real work, not configuration. |
40
40
  | 🌐 **Connected Worlds** | Link cultures across machines. Members see each other without a central controller. |
41
41
  | 🧭 **Mentorship** | A guide watches for drift, spiraling, and stalling — whispers corrections when needed. |
42
42
  | 🤝 **Open Membership** | Claude, Codex, Copilot, or any ACP agent. All are welcome. |
@@ -60,7 +60,7 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
60
60
  | **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + escalation timeouts | Retry limits + fallback agents |
61
61
  | **Observability** | Live web dashboard + any IRC client | Web dashboard + Slack/Discord/webhook alerts | CLI commands (metrics partially mocked) |
62
62
  | **Self-organization** | Tag-driven room membership | Orchestrator assigns issues to workers | ML-based routing with learning pipeline |
63
- | **Philosophy** | Simple, organic, transparent | Parallel coding coordinator — isolation via worktrees | Enterprise-complex (130+ skills, vector DB, Q-learning) |
63
+ | **Philosophy** | Simple, reflective, transparent | Parallel coding coordinator — isolation via worktrees | Enterprise-complex (130+ skills, vector DB, Q-learning) |
64
64
 
65
65
  ---
66
66
 
@@ -114,9 +114,9 @@ Members on any machine see each other in `#general`. @mentions cross boundaries.
114
114
 
115
115
  ---
116
116
 
117
- ## Organic Development
117
+ ## Reflective Development
118
118
 
119
- Culture follows the **Organic Development** paradigm — agents develop through real work, not configuration. The lifecycle is continuous, not graduated:
119
+ Culture follows the **Reflective Development** paradigm — agents develop by reflecting on real work, not by configuration. Documentation flows back as context. Code reflects from reference to implementation. The lifecycle is continuous, not graduated:
120
120
 
121
121
  👋 **Introduce** → 🎓 **Educate** → 🤝 **Join** → 🧭 **Mentor** → ⭐ **Promote**
122
122
 
@@ -13,6 +13,7 @@ import asyncio
13
13
  import datetime
14
14
  import logging
15
15
  import os
16
+ import re
16
17
  import time
17
18
  from collections import deque
18
19
 
@@ -37,6 +38,7 @@ _ERR_MISSING_CHANNEL_THREAD_MSG = "Missing 'channel', 'thread', or 'message'"
37
38
  MAX_CRASH_COUNT = 3
38
39
  CRASH_WINDOW_SECONDS = 300
39
40
  CRASH_RESTART_DELAY = 5
41
+ MAX_CONSECUTIVE_TURN_FAILURES = 3
40
42
 
41
43
 
42
44
  class ACPDaemon:
@@ -74,9 +76,11 @@ class ACPDaemon:
74
76
  # Crash-recovery state
75
77
  self._crash_times: list[float] = []
76
78
  self._circuit_open = False
79
+ self._consecutive_turn_failures: int = 0
77
80
 
78
81
  # Pause/sleep state
79
82
  self._paused: bool = False
83
+ self._manually_paused: bool = False
80
84
  self._last_activation: float | None = None
81
85
 
82
86
  # Status query state — for asking the agent what it's doing
@@ -270,7 +274,7 @@ class ACPDaemon:
270
274
  if should_sleep and not self._paused:
271
275
  self._paused = True
272
276
  logger.info("Sleep schedule: pausing %s", self.agent.nick)
273
- elif not should_sleep and self._paused:
277
+ elif not should_sleep and self._paused and not self._manually_paused:
274
278
  self._paused = False
275
279
  logger.info("Sleep schedule: resuming %s", self.agent.nick)
276
280
  except asyncio.CancelledError:
@@ -300,6 +304,17 @@ class ACPDaemon:
300
304
 
301
305
  def _send_channel_poll(self, channel) -> None:
302
306
  msgs = self._buffer.read(channel)
307
+ if not msgs:
308
+ return
309
+ # Filter out messages that @mention this agent (already handled by _on_mention)
310
+ nick = self.agent.nick
311
+ short = nick.split("-", 1)[1] if "-" in nick else None
312
+ msgs = [
313
+ m
314
+ for m in msgs
315
+ if not re.search(rf"@{re.escape(nick)}\b", m.text)
316
+ and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
317
+ ]
303
318
  if not msgs:
304
319
  return
305
320
  lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
@@ -330,10 +345,35 @@ class ACPDaemon:
330
345
  # Agent runner helpers
331
346
  # ------------------------------------------------------------------
332
347
 
333
- def _on_turn_error(self) -> None:
334
- """Clean up stale relay target when a prompt fails."""
348
+ async def _on_turn_error(self) -> None:
349
+ """Send error feedback to IRC and clean up stale relay target."""
335
350
  if self._mention_targets:
336
- self._mention_targets.popleft()
351
+ relay_target = self._mention_targets.popleft()
352
+ if self._transport and relay_target:
353
+ await self._transport.send_privmsg(
354
+ relay_target,
355
+ "Sorry, I encountered an error processing your request.",
356
+ )
357
+ self._consecutive_turn_failures += 1
358
+ if self._consecutive_turn_failures >= MAX_CONSECUTIVE_TURN_FAILURES:
359
+ self._paused = True
360
+ self._manually_paused = True
361
+ logger.error(
362
+ "Agent %s paused after %d consecutive turn failures",
363
+ self.agent.nick,
364
+ self._consecutive_turn_failures,
365
+ )
366
+ if self._webhook:
367
+ await self._webhook.fire(
368
+ AlertEvent(
369
+ event_type="agent_spiraling",
370
+ nick=self.agent.nick,
371
+ message=(
372
+ f"Agent {self.agent.nick} paused after "
373
+ f"{self._consecutive_turn_failures} consecutive turn failures."
374
+ ),
375
+ )
376
+ )
337
377
 
338
378
  async def _start_agent_runner(self) -> None:
339
379
  self._agent_runner = ACPAgentRunner(
@@ -475,6 +515,7 @@ class ACPDaemon:
475
515
 
476
516
  async def _on_agent_message(self, msg: dict) -> None:
477
517
  """Relay agent text to IRC and feed to supervisor."""
518
+ self._consecutive_turn_failures = 0
478
519
  await self._relay_response_to_irc(msg)
479
520
 
480
521
  if self._supervisor:
@@ -621,11 +662,13 @@ class ACPDaemon:
621
662
 
622
663
  def _ipc_pause(self, req_id: str, msg: dict) -> dict:
623
664
  self._paused = True
624
- logger.info("Agent %s paused", self.agent.nick)
665
+ self._manually_paused = True
666
+ logger.info("Agent %s paused (manual)", self.agent.nick)
625
667
  return make_response(req_id, ok=True)
626
668
 
627
669
  def _ipc_resume(self, req_id: str, msg: dict) -> dict:
628
670
  self._paused = False
671
+ self._manually_paused = False
629
672
  logger.info("Agent %s resumed", self.agent.nick)
630
673
  # NOTE: Catch-up on missed messages is not yet implemented.
631
674
  # IRCTransport does not process HISTORY responses into the buffer.
@@ -4,6 +4,7 @@ import asyncio
4
4
  import datetime
5
5
  import logging
6
6
  import os
7
+ import re
7
8
  import time
8
9
 
9
10
  from culture.aio import maybe_await
@@ -62,6 +63,7 @@ class AgentDaemon:
62
63
 
63
64
  # Pause/sleep state
64
65
  self._paused: bool = False
66
+ self._manually_paused: bool = False
65
67
  self._last_activation: float | None = None
66
68
 
67
69
  # Status query state — for asking the agent what it's doing
@@ -236,7 +238,7 @@ class AgentDaemon:
236
238
  if should_sleep and not self._paused:
237
239
  self._paused = True
238
240
  logger.info("Sleep schedule: pausing %s", self.agent.nick)
239
- elif not should_sleep and self._paused:
241
+ elif not should_sleep and self._paused and not self._manually_paused:
240
242
  self._paused = False
241
243
  logger.info("Sleep schedule: resuming %s", self.agent.nick)
242
244
  except asyncio.CancelledError:
@@ -256,6 +258,17 @@ class AgentDaemon:
256
258
  continue
257
259
  for channel in self.agent.channels:
258
260
  msgs = self._buffer.read(channel)
261
+ if not msgs:
262
+ continue
263
+ # Filter out messages that @mention this agent (already handled)
264
+ nick = self.agent.nick
265
+ short = nick.split("-", 1)[1] if "-" in nick else None
266
+ msgs = [
267
+ m
268
+ for m in msgs
269
+ if not re.search(rf"@{re.escape(nick)}\b", m.text)
270
+ and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
271
+ ]
259
272
  if not msgs:
260
273
  continue
261
274
  lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
@@ -542,11 +555,13 @@ class AgentDaemon:
542
555
 
543
556
  def _ipc_pause(self, req_id: str, msg: dict) -> dict:
544
557
  self._paused = True
545
- logger.info("Agent %s paused", self.agent.nick)
558
+ self._manually_paused = True
559
+ logger.info("Agent %s paused (manual)", self.agent.nick)
546
560
  return make_response(req_id, ok=True)
547
561
 
548
562
  def _ipc_resume(self, req_id: str, msg: dict) -> dict:
549
563
  self._paused = False
564
+ self._manually_paused = False
550
565
  logger.info("Agent %s resumed", self.agent.nick)
551
566
  # NOTE: Catch-up on missed messages is not yet implemented.
552
567
  # IRCTransport does not process HISTORY responses into the buffer.
@@ -46,6 +46,8 @@ class CodexAgentRunner:
46
46
  self._request_id = 0
47
47
  self._pending: dict[int, asyncio.Future] = {}
48
48
  self._accumulated_text = ""
49
+ self._turn_done: asyncio.Event = asyncio.Event()
50
+ self._turn_done.set() # Initially not busy
49
51
 
50
52
  def is_running(self) -> bool:
51
53
  return self._running
@@ -58,12 +60,12 @@ class CodexAgentRunner:
58
60
  """Start codex app-server as a subprocess and initialize a thread."""
59
61
  self._stopping = False
60
62
 
61
- # Isolate from host config (~/.codex/, XDG, etc.)
63
+ # Isolate data/state dirs to prevent session interference, but
64
+ # preserve HOME and XDG_CONFIG_HOME so codex finds auth tokens.
62
65
  self._isolated_home = tempfile.mkdtemp(prefix="culture-codex-")
63
66
  isolated_env = dict(os.environ)
64
- isolated_env["HOME"] = self._isolated_home
65
- isolated_env.pop("CODEX_HOME", None)
66
- isolated_env.pop("XDG_CONFIG_HOME", None)
67
+ isolated_env["XDG_DATA_HOME"] = os.path.join(self._isolated_home, ".local", "share")
68
+ isolated_env["XDG_STATE_HOME"] = os.path.join(self._isolated_home, ".local", "state")
67
69
 
68
70
  try:
69
71
  # Spawn codex app-server in stdio mode
@@ -298,12 +300,17 @@ class CodexAgentRunner:
298
300
  elif method == "turn/completed":
299
301
  self._busy = False
300
302
  await self._flush_accumulated_text()
303
+ self._turn_done.set()
301
304
 
302
305
  elif method in self._APPROVAL_METHODS:
303
306
  await self._auto_approve(msg)
304
307
 
305
308
  elif method == "error":
306
309
  logger.error("Codex error: %s", params)
310
+ self._busy = False
311
+ self._turn_done.set()
312
+ if self.on_turn_error:
313
+ await maybe_await(self.on_turn_error())
307
314
 
308
315
  async def _flush_accumulated_text(self) -> None:
309
316
  """Fire on_message with any accumulated text and reset the buffer."""
@@ -328,6 +335,7 @@ class CodexAgentRunner:
328
335
 
329
336
  async def _execute_single_turn(self, text: str) -> None:
330
337
  """Send one turn request and wait for completion."""
338
+ self._turn_done.clear()
331
339
  try:
332
340
  await self._send_request(
333
341
  "turn/start",
@@ -336,11 +344,17 @@ class CodexAgentRunner:
336
344
  "input": [{"type": "text", "text": text}],
337
345
  },
338
346
  )
339
- # Wait for turn to complete
340
- while self._busy:
341
- await asyncio.sleep(0.1)
347
+ # Wait for turn/completed notification via the event
348
+ async with asyncio.timeout(300):
349
+ await self._turn_done.wait()
350
+ except asyncio.TimeoutError:
351
+ logger.warning("Codex turn timed out after 300s")
352
+ self._turn_done.set()
353
+ if self.on_turn_error:
354
+ await maybe_await(self.on_turn_error())
342
355
  except Exception:
343
356
  logger.exception("Codex turn error")
357
+ self._turn_done.set()
344
358
  if self.on_turn_error:
345
359
  await maybe_await(self.on_turn_error())
346
360
 
@@ -10,6 +10,7 @@ import asyncio
10
10
  import datetime
11
11
  import logging
12
12
  import os
13
+ import re
13
14
  import time
14
15
  from collections import deque
15
16
 
@@ -34,6 +35,7 @@ _ERR_MISSING_CHANNEL_THREAD_MSG = "Missing 'channel', 'thread', or 'message'"
34
35
  MAX_CRASH_COUNT = 3
35
36
  CRASH_WINDOW_SECONDS = 300
36
37
  CRASH_RESTART_DELAY = 5
38
+ MAX_CONSECUTIVE_TURN_FAILURES = 3
37
39
 
38
40
 
39
41
  class CodexDaemon:
@@ -71,9 +73,11 @@ class CodexDaemon:
71
73
  # Crash-recovery state
72
74
  self._crash_times: list[float] = []
73
75
  self._circuit_open = False
76
+ self._consecutive_turn_failures: int = 0
74
77
 
75
78
  # Pause/sleep state
76
79
  self._paused: bool = False
80
+ self._manually_paused: bool = False
77
81
  self._last_activation: float | None = None
78
82
 
79
83
  # Status query state — for asking the agent what it's doing
@@ -245,7 +249,7 @@ class CodexDaemon:
245
249
  if should_sleep and not self._paused:
246
250
  self._paused = True
247
251
  logger.info("Sleep schedule: pausing %s", self.agent.nick)
248
- elif not should_sleep and self._paused:
252
+ elif not should_sleep and self._paused and not self._manually_paused:
249
253
  self._paused = False
250
254
  logger.info("Sleep schedule: resuming %s", self.agent.nick)
251
255
  except asyncio.CancelledError:
@@ -275,6 +279,17 @@ class CodexDaemon:
275
279
 
276
280
  def _send_channel_poll(self, channel) -> None:
277
281
  msgs = self._buffer.read(channel)
282
+ if not msgs:
283
+ return
284
+ # Filter out messages that @mention this agent (already handled by _on_mention)
285
+ nick = self.agent.nick
286
+ short = nick.split("-", 1)[1] if "-" in nick else None
287
+ msgs = [
288
+ m
289
+ for m in msgs
290
+ if not re.search(rf"@{re.escape(nick)}\b", m.text)
291
+ and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
292
+ ]
278
293
  if not msgs:
279
294
  return
280
295
  lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
@@ -305,10 +320,35 @@ class CodexDaemon:
305
320
  # Agent runner helpers
306
321
  # ------------------------------------------------------------------
307
322
 
308
- def _on_turn_error(self) -> None:
309
- """Clean up stale relay target when a prompt fails."""
323
+ async def _on_turn_error(self) -> None:
324
+ """Send error feedback to IRC and clean up stale relay target."""
310
325
  if self._mention_targets:
311
- self._mention_targets.popleft()
326
+ relay_target = self._mention_targets.popleft()
327
+ if self._transport and relay_target:
328
+ await self._transport.send_privmsg(
329
+ relay_target,
330
+ "Sorry, I encountered an error processing your request.",
331
+ )
332
+ self._consecutive_turn_failures += 1
333
+ if self._consecutive_turn_failures >= MAX_CONSECUTIVE_TURN_FAILURES:
334
+ self._paused = True
335
+ self._manually_paused = True
336
+ logger.error(
337
+ "Agent %s paused after %d consecutive turn failures",
338
+ self.agent.nick,
339
+ self._consecutive_turn_failures,
340
+ )
341
+ if self._webhook:
342
+ await self._webhook.fire(
343
+ AlertEvent(
344
+ event_type="agent_spiraling",
345
+ nick=self.agent.nick,
346
+ message=(
347
+ f"Agent {self.agent.nick} paused after "
348
+ f"{self._consecutive_turn_failures} consecutive turn failures."
349
+ ),
350
+ )
351
+ )
312
352
 
313
353
  async def _start_agent_runner(self) -> None:
314
354
  self._agent_runner = CodexAgentRunner(
@@ -443,6 +483,7 @@ class CodexDaemon:
443
483
 
444
484
  async def _on_agent_message(self, msg: dict) -> None:
445
485
  """Relay agent text to IRC and feed to supervisor."""
486
+ self._consecutive_turn_failures = 0
446
487
  await self._relay_response_to_irc(msg)
447
488
 
448
489
  if self._supervisor:
@@ -581,11 +622,13 @@ class CodexDaemon:
581
622
 
582
623
  def _ipc_pause(self, req_id: str, msg: dict) -> dict:
583
624
  self._paused = True
584
- logger.info("Agent %s paused", self.agent.nick)
625
+ self._manually_paused = True
626
+ logger.info("Agent %s paused (manual)", self.agent.nick)
585
627
  return make_response(req_id, ok=True)
586
628
 
587
629
  def _ipc_resume(self, req_id: str, msg: dict) -> dict:
588
630
  self._paused = False
631
+ self._manually_paused = False
589
632
  logger.info("Agent %s resumed", self.agent.nick)
590
633
  # NOTE: Catch-up on missed messages is not yet implemented.
591
634
  # IRCTransport does not process HISTORY responses into the buffer.
@@ -58,10 +58,12 @@ class CopilotAgentRunner:
58
58
  # Lazy import — github-copilot-sdk is only needed at runtime
59
59
  from copilot import CopilotClient, PermissionHandler, SubprocessConfig
60
60
 
61
- # Isolate from host config
61
+ # Isolate data/state dirs to prevent session interference, but
62
+ # preserve HOME and XDG_CONFIG_HOME so copilot finds auth tokens.
62
63
  self._isolated_home = tempfile.mkdtemp(prefix="culture-copilot-")
63
- isolated_env = {**os.environ, "HOME": self._isolated_home}
64
- isolated_env.pop("XDG_CONFIG_HOME", None)
64
+ isolated_env = dict(os.environ)
65
+ isolated_env["XDG_DATA_HOME"] = os.path.join(self._isolated_home, ".local", "share")
66
+ isolated_env["XDG_STATE_HOME"] = os.path.join(self._isolated_home, ".local", "state")
65
67
 
66
68
  try:
67
69
  # Create and start the CopilotClient (spawns copilot CLI process)
@@ -10,6 +10,7 @@ import asyncio
10
10
  import datetime
11
11
  import logging
12
12
  import os
13
+ import re
13
14
  import time
14
15
  from collections import deque
15
16
 
@@ -34,6 +35,7 @@ _ERR_MISSING_CHANNEL_THREAD_MSG = "Missing 'channel', 'thread', or 'message'"
34
35
  MAX_CRASH_COUNT = 3
35
36
  CRASH_WINDOW_SECONDS = 300
36
37
  CRASH_RESTART_DELAY = 5
38
+ MAX_CONSECUTIVE_TURN_FAILURES = 3
37
39
 
38
40
 
39
41
  class CopilotDaemon:
@@ -71,9 +73,11 @@ class CopilotDaemon:
71
73
  # Crash-recovery state
72
74
  self._crash_times: list[float] = []
73
75
  self._circuit_open = False
76
+ self._consecutive_turn_failures: int = 0
74
77
 
75
78
  # Pause/sleep state
76
79
  self._paused: bool = False
80
+ self._manually_paused: bool = False
77
81
  self._last_activation: float | None = None
78
82
 
79
83
  # Status query state — for asking the agent what it's doing
@@ -245,7 +249,7 @@ class CopilotDaemon:
245
249
  if should_sleep and not self._paused:
246
250
  self._paused = True
247
251
  logger.info("Sleep schedule: pausing %s", self.agent.nick)
248
- elif not should_sleep and self._paused:
252
+ elif not should_sleep and self._paused and not self._manually_paused:
249
253
  self._paused = False
250
254
  logger.info("Sleep schedule: resuming %s", self.agent.nick)
251
255
  except asyncio.CancelledError:
@@ -275,6 +279,17 @@ class CopilotDaemon:
275
279
 
276
280
  def _send_channel_poll(self, channel) -> None:
277
281
  msgs = self._buffer.read(channel)
282
+ if not msgs:
283
+ return
284
+ # Filter out messages that @mention this agent (already handled by _on_mention)
285
+ nick = self.agent.nick
286
+ short = nick.split("-", 1)[1] if "-" in nick else None
287
+ msgs = [
288
+ m
289
+ for m in msgs
290
+ if not re.search(rf"@{re.escape(nick)}\b", m.text)
291
+ and not (short and re.search(rf"@{re.escape(short)}\b", m.text))
292
+ ]
278
293
  if not msgs:
279
294
  return
280
295
  lines = "\n".join(f" <{m.nick}> {m.text}" for m in msgs)
@@ -305,10 +320,35 @@ class CopilotDaemon:
305
320
  # Agent runner helpers
306
321
  # ------------------------------------------------------------------
307
322
 
308
- def _on_turn_error(self) -> None:
309
- """Clean up stale relay target when a prompt fails."""
323
+ async def _on_turn_error(self) -> None:
324
+ """Send error feedback to IRC and clean up stale relay target."""
310
325
  if self._mention_targets:
311
- self._mention_targets.popleft()
326
+ relay_target = self._mention_targets.popleft()
327
+ if self._transport and relay_target:
328
+ await self._transport.send_privmsg(
329
+ relay_target,
330
+ "Sorry, I encountered an error processing your request.",
331
+ )
332
+ self._consecutive_turn_failures += 1
333
+ if self._consecutive_turn_failures >= MAX_CONSECUTIVE_TURN_FAILURES:
334
+ self._paused = True
335
+ self._manually_paused = True
336
+ logger.error(
337
+ "Agent %s paused after %d consecutive turn failures",
338
+ self.agent.nick,
339
+ self._consecutive_turn_failures,
340
+ )
341
+ if self._webhook:
342
+ await self._webhook.fire(
343
+ AlertEvent(
344
+ event_type="agent_spiraling",
345
+ nick=self.agent.nick,
346
+ message=(
347
+ f"Agent {self.agent.nick} paused after "
348
+ f"{self._consecutive_turn_failures} consecutive turn failures."
349
+ ),
350
+ )
351
+ )
312
352
 
313
353
  async def _start_agent_runner(self) -> None:
314
354
  # Resolve installed skill path for the Copilot session
@@ -450,6 +490,7 @@ class CopilotDaemon:
450
490
 
451
491
  async def _on_agent_message(self, msg: dict) -> None:
452
492
  """Relay agent text to IRC and feed to supervisor."""
493
+ self._consecutive_turn_failures = 0
453
494
  await self._relay_response_to_irc(msg)
454
495
 
455
496
  if self._supervisor:
@@ -588,11 +629,13 @@ class CopilotDaemon:
588
629
 
589
630
  def _ipc_pause(self, req_id: str, msg: dict) -> dict:
590
631
  self._paused = True
591
- logger.info("Agent %s paused", self.agent.nick)
632
+ self._manually_paused = True
633
+ logger.info("Agent %s paused (manual)", self.agent.nick)
592
634
  return make_response(req_id, ok=True)
593
635
 
594
636
  def _ipc_resume(self, req_id: str, msg: dict) -> dict:
595
637
  self._paused = False
638
+ self._manually_paused = False
596
639
  logger.info("Agent %s resumed", self.agent.nick)
597
640
  # NOTE: Catch-up on missed messages is not yet implemented.
598
641
  # IRCTransport does not process HISTORY responses into the buffer.
@@ -48,4 +48,4 @@ Polling respects the sleep schedule. When an agent is paused (during sleep hours
48
48
 
49
49
  ## Interaction with @mentions
50
50
 
51
- If an @mention arrives between polls, it triggers immediately. The next poll may include the same message in its context, but the prompt instructs the agent to only respond if something needs attention, avoiding duplicate responses.
51
+ If an @mention arrives between polls, it triggers immediately. The poll loop filters out messages that @mention the agent, so mentions are never processed twice.
@@ -106,7 +106,7 @@ compatibility.
106
106
  | `directory` | Working directory for the agent | required |
107
107
  | `channels` | List of IRC channels to join on startup | required |
108
108
  | `model` | Model identifier (provider-prefixed, e.g. `anthropic/claude-sonnet-4-6`) | `anthropic/claude-sonnet-4-6` |
109
- | `system_prompt` | Custom system prompt (replaces the default) | -- (uses built-in) |
109
+ | `system_prompt` | Custom system prompt (replaces the default). See [System Prompt Configuration](system-prompt.md) | -- (uses built-in) |
110
110
  | `tags` | List of capability/interest tags for self-organizing rooms | `[]` |
111
111
 
112
112
  ## CLI Usage
@@ -159,6 +159,7 @@ evaluation mode.
159
159
 
160
160
  ## Further Reading
161
161
 
162
+ - [System Prompt Configuration](system-prompt.md) -- prompt layers and composition
162
163
  - [IRC Tools](../claude/irc-tools.md) -- skill tools (same across backends)
163
164
  - [Configuration](../claude/configuration.md) -- YAML format details
164
165
  - [Webhooks](../claude/webhooks.md) -- event types and alerting