agentirc-cli 8.7.0__tar.gz → 8.7.1__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 (476) hide show
  1. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/CHANGELOG.md +15 -0
  2. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/PKG-INFO +1 -1
  3. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/channel.py +36 -1
  4. agentirc_cli-8.7.1/culture/cli/shared/constants.py +54 -0
  5. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/daemon.py +2 -1
  6. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/skill/irc_client.py +2 -2
  7. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/daemon.py +2 -1
  8. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/skill/irc_client.py +2 -2
  9. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/daemon.py +2 -1
  10. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/skill/irc_client.py +2 -2
  11. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/daemon.py +2 -1
  12. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/skill/irc_client.py +2 -2
  13. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/overview/collector.py +2 -2
  14. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/architecture/agent-harness-spec.md +12 -1
  15. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/cli/index.md +13 -0
  16. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/daemon.py +2 -1
  17. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/skill/irc_client.py +2 -2
  18. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/pyproject.toml +1 -1
  19. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_channel_cli.py +78 -1
  20. agentirc_cli-8.7.1/tests/test_constants.py +86 -0
  21. agentirc_cli-8.7.1/tests/test_socket_path_convergence.py +153 -0
  22. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/uv.lock +1 -1
  23. agentirc_cli-8.7.0/culture/cli/shared/constants.py +0 -43
  24. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.claude/agents/doc-test-alignment.md +0 -0
  25. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.claude/skills/pr-review/SKILL.md +0 -0
  26. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.claude/skills/run-tests/SKILL.md +0 -0
  27. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.claude/skills/run-tests/scripts/test.sh +0 -0
  28. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.flake8 +0 -0
  29. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.github/workflows/docs-check.yml +0 -0
  30. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.github/workflows/publish.yml +0 -0
  31. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.github/workflows/security-checks.yml +0 -0
  32. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.github/workflows/tests.yml +0 -0
  33. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.gitignore +0 -0
  34. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.markdownlint-cli2.yaml +0 -0
  35. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.pr_agent.toml +0 -0
  36. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.pre-commit-config.yaml +0 -0
  37. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/.pylintrc +0 -0
  38. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/CLAUDE.md +0 -0
  39. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/Gemfile +0 -0
  40. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/Gemfile.lock +0 -0
  41. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/LICENSE +0 -0
  42. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/README.md +0 -0
  43. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/SECURITY.md +0 -0
  44. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/_config.base.yml +0 -0
  45. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/_config.culture.yml +0 -0
  46. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/_data/sites.yml +0 -0
  47. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/_includes/head_custom.html +0 -0
  48. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/_sass/color_schemes/anthropic.scss +0 -0
  49. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/_sass/color_schemes/dark-terminal.scss +0 -0
  50. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/_sass/custom/custom.scss +0 -0
  51. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/assets/images/IMG_3183.png +0 -0
  52. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/assets/images/apple-touch-icon.png +0 -0
  53. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/assets/images/favicon-16x16.png +0 -0
  54. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/assets/images/favicon-32x32.png +0 -0
  55. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/assets/images/favicon.ico +0 -0
  56. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/assets/images/og-agentirc.png +0 -0
  57. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/assets/images/og-culture.png +0 -0
  58. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/__init__.py +0 -0
  59. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/__main__.py +0 -0
  60. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/CLAUDE.md +0 -0
  61. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/__init__.py +0 -0
  62. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/__main__.py +0 -0
  63. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/channel.py +0 -0
  64. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/client.py +0 -0
  65. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/config.py +0 -0
  66. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/docs/agentirc-architecture.md +0 -0
  67. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/docs/agentirc-features.md +0 -0
  68. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/docs/agentirc-skill.md +0 -0
  69. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/docs/agentirc.md +0 -0
  70. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/events.py +0 -0
  71. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/history_store.py +0 -0
  72. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/ircd.py +0 -0
  73. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/remote_client.py +0 -0
  74. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/room_store.py +0 -0
  75. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/rooms_util.py +0 -0
  76. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/server_link.py +0 -0
  77. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/skill.py +0 -0
  78. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/skills/__init__.py +0 -0
  79. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/skills/history.py +0 -0
  80. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/skills/icon.py +0 -0
  81. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/skills/rooms.py +0 -0
  82. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/skills/threads.py +0 -0
  83. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/agentirc/thread_store.py +0 -0
  84. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/aio.py +0 -0
  85. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/__init__.py +0 -0
  86. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/bot.py +0 -0
  87. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/bot_manager.py +0 -0
  88. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/config.py +0 -0
  89. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/filter_dsl.py +0 -0
  90. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/http_listener.py +0 -0
  91. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/system/__init__.py +0 -0
  92. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/system/welcome/__init__.py +0 -0
  93. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/system/welcome/bot.yaml +0 -0
  94. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/system/welcome/handler.py +0 -0
  95. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/template_engine.py +0 -0
  96. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/bots/virtual_client.py +0 -0
  97. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/__init__.py +0 -0
  98. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/_passthrough.py +0 -0
  99. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/afi.py +0 -0
  100. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/agent.py +0 -0
  101. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/bot.py +0 -0
  102. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/devex.py +0 -0
  103. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/introspect.py +0 -0
  104. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/mesh.py +0 -0
  105. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/server.py +0 -0
  106. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/shared/__init__.py +0 -0
  107. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/shared/display.py +0 -0
  108. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/shared/formatting.py +0 -0
  109. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/shared/ipc.py +0 -0
  110. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/shared/mesh.py +0 -0
  111. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/shared/process.py +0 -0
  112. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/cli/skills.py +0 -0
  113. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/__init__.py +0 -0
  114. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/__init__.py +0 -0
  115. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/agent_runner.py +0 -0
  116. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/config.py +0 -0
  117. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/culture.yaml +0 -0
  118. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/ipc.py +0 -0
  119. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/irc_transport.py +0 -0
  120. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/message_buffer.py +0 -0
  121. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/skill/SKILL.md +0 -0
  122. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/skill/__init__.py +0 -0
  123. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/socket_server.py +0 -0
  124. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/supervisor.py +0 -0
  125. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/telemetry.py +0 -0
  126. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/acp/webhook.py +0 -0
  127. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/__init__.py +0 -0
  128. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/__main__.py +0 -0
  129. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/agent_runner.py +0 -0
  130. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/config.py +0 -0
  131. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/culture.yaml +0 -0
  132. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/ipc.py +0 -0
  133. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/irc_transport.py +0 -0
  134. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/message_buffer.py +0 -0
  135. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/skill/SKILL.md +0 -0
  136. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/skill/__init__.py +0 -0
  137. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/socket_server.py +0 -0
  138. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/supervisor.py +0 -0
  139. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/telemetry.py +0 -0
  140. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/claude/webhook.py +0 -0
  141. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/__init__.py +0 -0
  142. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/agent_runner.py +0 -0
  143. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/config.py +0 -0
  144. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/culture.yaml +0 -0
  145. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/ipc.py +0 -0
  146. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/irc_transport.py +0 -0
  147. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/message_buffer.py +0 -0
  148. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/skill/SKILL.md +0 -0
  149. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/skill/__init__.py +0 -0
  150. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/socket_server.py +0 -0
  151. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/supervisor.py +0 -0
  152. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/telemetry.py +0 -0
  153. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/codex/webhook.py +0 -0
  154. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/__init__.py +0 -0
  155. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/agent_runner.py +0 -0
  156. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/config.py +0 -0
  157. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/culture.yaml +0 -0
  158. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/ipc.py +0 -0
  159. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/irc_transport.py +0 -0
  160. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/message_buffer.py +0 -0
  161. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/skill/SKILL.md +0 -0
  162. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/skill/__init__.py +0 -0
  163. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/socket_server.py +0 -0
  164. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/supervisor.py +0 -0
  165. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/telemetry.py +0 -0
  166. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/clients/copilot/webhook.py +0 -0
  167. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/config.py +0 -0
  168. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/__init__.py +0 -0
  169. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/app.py +0 -0
  170. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/client.py +0 -0
  171. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/commands.py +0 -0
  172. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/status.py +0 -0
  173. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/widgets/__init__.py +0 -0
  174. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/widgets/chat.py +0 -0
  175. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/widgets/info_panel.py +0 -0
  176. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/console/widgets/sidebar.py +0 -0
  177. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/constants.py +0 -0
  178. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/credentials.py +0 -0
  179. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/formatting.py +0 -0
  180. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/learn_prompt.py +0 -0
  181. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/mesh_config.py +0 -0
  182. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/observer.py +0 -0
  183. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/overview/__init__.py +0 -0
  184. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/overview/model.py +0 -0
  185. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/overview/renderer_text.py +0 -0
  186. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/overview/renderer_web.py +0 -0
  187. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/overview/web/style.css +0 -0
  188. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/persistence.py +0 -0
  189. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/pidfile.py +0 -0
  190. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/__init__.py +0 -0
  191. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/commands.py +0 -0
  192. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/audit.md +0 -0
  193. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/events.md +0 -0
  194. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/federation.md +0 -0
  195. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/history.md +0 -0
  196. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/icons.md +0 -0
  197. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/rooms.md +0 -0
  198. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/tags.md +0 -0
  199. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/threads.md +0 -0
  200. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/extensions/tracing.md +0 -0
  201. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/message.py +0 -0
  202. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/protocol-index.md +0 -0
  203. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/protocol/replies.py +0 -0
  204. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/skills/culture/SKILL.md +0 -0
  205. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/telemetry/__init__.py +0 -0
  206. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/telemetry/audit.py +0 -0
  207. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/telemetry/context.py +0 -0
  208. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/telemetry/metrics.py +0 -0
  209. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/culture/telemetry/tracing.py +0 -0
  210. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/README.md +0 -0
  211. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/architecture-overview.md +0 -0
  212. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/audit.md +0 -0
  213. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/bots.md +0 -0
  214. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/events.md +0 -0
  215. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/harness-telemetry.md +0 -0
  216. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/index.md +0 -0
  217. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/otelcol-template.yaml +0 -0
  218. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/telemetry.md +0 -0
  219. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/agentirc/why-agentirc.md +0 -0
  220. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/agent-lifecycle.md +0 -0
  221. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/choose-a-harness.md +0 -0
  222. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/features.md +0 -0
  223. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/index.md +0 -0
  224. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/mental-model.md +0 -0
  225. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/operate.md +0 -0
  226. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/patterns.md +0 -0
  227. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/quickstart.md +0 -0
  228. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/reflective-development.md +0 -0
  229. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/vision-patterns-index.md +0 -0
  230. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/vision.md +0 -0
  231. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/culture/what-is-culture.md +0 -0
  232. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/architecture/index.md +0 -0
  233. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/architecture/layers.md +0 -0
  234. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/architecture/subsites.md +0 -0
  235. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/architecture/threads.md +0 -0
  236. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/cli/afi.md +0 -0
  237. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/cli/commands.md +0 -0
  238. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/cli/devex.md +0 -0
  239. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/console.md +0 -0
  240. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/harnesses/acp.md +0 -0
  241. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/harnesses/claude.md +0 -0
  242. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/harnesses/codex.md +0 -0
  243. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/harnesses/copilot.md +0 -0
  244. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/harnesses/index.md +0 -0
  245. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/index.md +0 -0
  246. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/server/architecture.md +0 -0
  247. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/server/config.md +0 -0
  248. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/server/deployment.md +0 -0
  249. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/server/index.md +0 -0
  250. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/reference/server/security.md +0 -0
  251. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  252. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/resources/positioning.md +0 -0
  253. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/concepts/federation.md +0 -0
  254. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/concepts/harnesses.md +0 -0
  255. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/concepts/humans-and-agents.md +0 -0
  256. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/concepts/index.md +0 -0
  257. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/concepts/persistence.md +0 -0
  258. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/concepts/rooms.md +0 -0
  259. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/demos/magic-demo.md +0 -0
  260. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/guides/first-session.md +0 -0
  261. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/guides/index.md +0 -0
  262. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/guides/join-as-human.md +0 -0
  263. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/guides/local-setup.md +0 -0
  264. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/guides/multi-machine.md +0 -0
  265. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/01-pair-programming.md +0 -0
  266. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/02-code-review-ensemble.md +0 -0
  267. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/03-cross-server-delegation.md +0 -0
  268. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/04-knowledge-propagation.md +0 -0
  269. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/05-the-observer.md +0 -0
  270. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/06-cross-server-ops.md +0 -0
  271. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/07-supervisor-intervention.md +0 -0
  272. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/08-apps-as-agents.md +0 -0
  273. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/09-research-swarm.md +0 -0
  274. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases/10-agent-lifecycle.md +0 -0
  275. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/shared/use-cases-index.md +0 -0
  276. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  277. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  278. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  279. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  280. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
  281. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
  282. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
  283. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -0
  284. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
  285. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-09-decentralized-agent-config.md +0 -0
  286. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-12-console-enhancements.md +0 -0
  287. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-15-mesh-events.md +0 -0
  288. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-18-culture-dev-positioning.md +0 -0
  289. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-22-agex-integration.md +0 -0
  290. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-24-otel-foundation.md +0 -0
  291. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-25-otel-federation.md +0 -0
  292. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-26-otel-metrics.md +0 -0
  293. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-27-otel-audit.md +0 -0
  294. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/plans/2026-04-28-otel-harness.md +0 -0
  295. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  296. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  297. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  298. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  299. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
  300. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
  301. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
  302. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
  303. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -0
  304. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -0
  305. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
  306. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
  307. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -0
  308. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-07-reflective-development-reframe-design.md +0 -0
  309. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-08-reflective-development-deepening-design.md +0 -0
  310. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-09-decentralized-agent-config-design.md +0 -0
  311. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-12-console-enhancements-design.md +0 -0
  312. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-15-mesh-events-design.md +0 -0
  313. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-17-sites-repositioning-design.md +0 -0
  314. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-18-culture-dev-positioning-design.md +0 -0
  315. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-22-agex-integration-design.md +0 -0
  316. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/docs/superpowers/specs/2026-04-24-otel-observability-design.md +0 -0
  317. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/favicon.ico +0 -0
  318. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/README.md +0 -0
  319. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/config.py +0 -0
  320. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/culture.yaml +0 -0
  321. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/ipc.py +0 -0
  322. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/irc_transport.py +0 -0
  323. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/message_buffer.py +0 -0
  324. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/skill/SKILL.md +0 -0
  325. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/socket_server.py +0 -0
  326. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/telemetry.py +0 -0
  327. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/packages/agent-harness/webhook.py +0 -0
  328. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  329. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/plugins/claude-code/skills/culture/SKILL.md +0 -0
  330. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  331. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
  332. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/robots.txt +0 -0
  333. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/sitemap-agentirc.html +0 -0
  334. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/sitemap-main.html +0 -0
  335. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/sitemap.html +0 -0
  336. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/sonar-project.properties +0 -0
  337. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/__init__.py +0 -0
  338. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/conftest.py +0 -0
  339. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/__init__.py +0 -0
  340. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/conftest.py +0 -0
  341. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_agent_runner_acp.py +0 -0
  342. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_agent_runner_claude.py +0 -0
  343. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_agent_runner_codex.py +0 -0
  344. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_agent_runner_copilot.py +0 -0
  345. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_all_backends_parity.py +0 -0
  346. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_daemon_telemetry.py +0 -0
  347. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_irc_transport_propagation.py +0 -0
  348. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_record_llm_call.py +0 -0
  349. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/harness/test_telemetry_module.py +0 -0
  350. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/__init__.py +0 -0
  351. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/_fakes.py +0 -0
  352. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/_metrics_helpers.py +0 -0
  353. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/conftest.py +0 -0
  354. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_audit_emit.py +0 -0
  355. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_audit_federation.py +0 -0
  356. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_audit_lifecycle.py +0 -0
  357. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_audit_module.py +0 -0
  358. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_audit_parse_error.py +0 -0
  359. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_bot_event_dispatch_span.py +0 -0
  360. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_bot_run_span.py +0 -0
  361. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_config.py +0 -0
  362. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_config_load.py +0 -0
  363. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_context.py +0 -0
  364. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_dispatch_span.py +0 -0
  365. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_emit_event_span.py +0 -0
  366. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_federation_propagation.py +0 -0
  367. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_bots.py +0 -0
  368. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_clients.py +0 -0
  369. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_events.py +0 -0
  370. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_init.py +0 -0
  371. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_irc.py +0 -0
  372. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_s2s.py +0 -0
  373. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_trace_inbound.py +0 -0
  374. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_metrics_webhook.py +0 -0
  375. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_outbound_inject.py +0 -0
  376. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_parse_error.py +0 -0
  377. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_privmsg_span.py +0 -0
  378. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_s2s_dispatch_span.py +0 -0
  379. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_s2s_relay_span.py +0 -0
  380. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_s2s_session_span.py +0 -0
  381. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_server_init.py +0 -0
  382. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_server_link_inject.py +0 -0
  383. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_session_span.py +0 -0
  384. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_tracing.py +0 -0
  385. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/telemetry/test_webhook_http_span.py +0 -0
  386. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_acp_daemon.py +0 -0
  387. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_agent_runner.py +0 -0
  388. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_archive.py +0 -0
  389. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_bot.py +0 -0
  390. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_bot_config.py +0 -0
  391. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_bot_config_fires_event_toplevel.py +0 -0
  392. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_bot_manager.py +0 -0
  393. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_bots_integration.py +0 -0
  394. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_channel.py +0 -0
  395. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_cli_afi.py +0 -0
  396. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_cli_devex.py +0 -0
  397. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_cli_introspect.py +0 -0
  398. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_cli_passthrough.py +0 -0
  399. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_codex_daemon.py +0 -0
  400. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_connection.py +0 -0
  401. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_chat_markdown.py +0 -0
  402. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_client.py +0 -0
  403. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_commands.py +0 -0
  404. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_connection.py +0 -0
  405. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_fixes_224_227.py +0 -0
  406. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_icons.py +0 -0
  407. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_integration.py +0 -0
  408. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_console_status.py +0 -0
  409. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_copilot_daemon.py +0 -0
  410. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_credentials.py +0 -0
  411. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_culture_config.py +0 -0
  412. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_daemon.py +0 -0
  413. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_daemon_config.py +0 -0
  414. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_daemon_ipc.py +0 -0
  415. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_discovery.py +0 -0
  416. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_display.py +0 -0
  417. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_basic.py +0 -0
  418. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_bot_chain.py +0 -0
  419. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_bot_trigger.py +0 -0
  420. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_cap_fallback.py +0 -0
  421. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_catalog.py +0 -0
  422. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_federation.py +0 -0
  423. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_history.py +0 -0
  424. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_lifecycle.py +0 -0
  425. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_events_reserved_nick.py +0 -0
  426. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_federation.py +0 -0
  427. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_filter_dsl.py +0 -0
  428. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_history.py +0 -0
  429. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_http_listener.py +0 -0
  430. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_integration_layer5.py +0 -0
  431. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_ipc.py +0 -0
  432. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_irc_transport.py +0 -0
  433. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_irc_transport_tags.py +0 -0
  434. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_learn_prompt.py +0 -0
  435. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_link_reconnect.py +0 -0
  436. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_manifest_config.py +0 -0
  437. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_mention_alias.py +0 -0
  438. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_mention_target_cleanup.py +0 -0
  439. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_mention_warning.py +0 -0
  440. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_mentions.py +0 -0
  441. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_mesh_config.py +0 -0
  442. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_mesh_readiness.py +0 -0
  443. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_message.py +0 -0
  444. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_message_buffer.py +0 -0
  445. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_message_tags.py +0 -0
  446. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_messaging.py +0 -0
  447. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_migrate_cli.py +0 -0
  448. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_modes.py +0 -0
  449. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_overview_cli.py +0 -0
  450. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_overview_collector.py +0 -0
  451. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_overview_model.py +0 -0
  452. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_overview_renderer.py +0 -0
  453. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_overview_web.py +0 -0
  454. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_persistence.py +0 -0
  455. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_persistence_timeout.py +0 -0
  456. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_pidfile.py +0 -0
  457. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_poll_loop.py +0 -0
  458. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_register_cli.py +0 -0
  459. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_room_persistence.py +0 -0
  460. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_rooms.py +0 -0
  461. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_rooms_federation.py +0 -0
  462. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_rooms_integration.py +0 -0
  463. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_server_icon_skill.py +0 -0
  464. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_setup_update_cli.py +0 -0
  465. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_skill_client.py +0 -0
  466. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_skill_docs.py +0 -0
  467. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_skills.py +0 -0
  468. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_socket_server.py +0 -0
  469. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_supervisor.py +0 -0
  470. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_template_engine.py +0 -0
  471. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_thread_buffer.py +0 -0
  472. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_threads.py +0 -0
  473. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_virtual_client.py +0 -0
  474. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_wait_for_port.py +0 -0
  475. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_webhook.py +0 -0
  476. {agentirc_cli-8.7.0 → agentirc_cli-8.7.1}/tests/test_welcome_bot.py +0 -0
@@ -4,6 +4,21 @@ 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
+ ## [8.7.1] - 2026-04-27
8
+
9
+ ### Added
10
+
11
+ - `tests/test_socket_path_convergence.py`: parametric regression test asserting all 8 daemon+skill resolvers agree with the CLI's `agent_socket_path()` for both `XDG_RUNTIME_DIR` set and unset.
12
+ - `tests/test_constants.py`: unit tests pinning `culture_runtime_dir()` contract (env precedence, `~/.culture/run/` fallback, mode 0700).
13
+
14
+ ### Changed
15
+
16
+ - `culture channel {message,list,read}`: when `CULTURE_NICK` is set but the daemon IPC is unreachable or rejects the request, the CLI now prints a stderr warning naming the nick, the socket path, and the GitHub issue tracker before falling back to the peek-nick observer. The fallback itself is preserved for human use (no `CULTURE_NICK`).
17
+
18
+ ### Fixed
19
+
20
+ - Converged all socket-path resolvers (4 backend daemons, 4 skill irc_clients, overview collector, harness package reference impl) on `culture_runtime_dir()` so the CLI and daemon agree on the IPC socket path when `XDG_RUNTIME_DIR` is unset (macOS default). Previously the daemon listened on `/tmp/culture-<nick>.sock` while the CLI looked in `~/.culture/run/`, causing `culture channel message` to silently fall back to an anonymous `_peek<random>` nick (#302, regression of #203).
21
+
7
22
  ## [8.7.0] - 2026-04-26
8
23
 
9
24
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 8.7.0
3
+ Version: 8.7.1
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
@@ -24,11 +24,43 @@ def _valid_nick(nick: str) -> bool:
24
24
  return len(parts) == 2 and all(parts)
25
25
 
26
26
 
27
+ _ISSUE_TRACKER_URL = "https://github.com/agentculture/culture/issues"
28
+
29
+
30
+ def _warn_observer_fallback(operation: str) -> None:
31
+ """Warn on stderr when an observer-fallback command silently went anonymous.
32
+
33
+ Called only by the three commands that do fall back to the observer
34
+ connection (`message`, `list`, `read`). `topic` and the `_require_ipc`
35
+ commands exit on failure instead, so this helper is not used there —
36
+ a misleading "falling back" notice would contradict the actual error.
37
+
38
+ Issue #302: a daemon/CLI socket-path mismatch on macOS hid behind the
39
+ silent peek fallback for two releases. The warning names the issue
40
+ tracker so the next reproducer takes seconds to file.
41
+ """
42
+ nick = os.environ.get("CULTURE_NICK")
43
+ if not nick or not _valid_nick(nick):
44
+ return # Human use without CULTURE_NICK — observer is the intended path.
45
+ sock = agent_socket_path(nick)
46
+ print(
47
+ f"Warning: agent daemon IPC for {nick} failed ({sock}).\n"
48
+ f" Falling back to observer connection — `{operation}` will not run\n"
49
+ f" through the agent daemon and the action will not appear under {nick}.\n"
50
+ f" Verify the daemon is running: culture agent status {nick}\n"
51
+ f" If it is running, this is a bug. Please open an issue:\n"
52
+ f" {_ISSUE_TRACKER_URL}",
53
+ file=sys.stderr,
54
+ )
55
+
56
+
27
57
  def _try_ipc(msg_type: str, **kwargs) -> dict | None:
28
58
  """Try to route a command through the agent daemon's IPC socket.
29
59
 
30
60
  Returns the response dict if CULTURE_NICK is set and the daemon is
31
- reachable, otherwise None (caller should fall back to observer).
61
+ reachable, otherwise None (caller should fall back to observer or
62
+ surface its own error — see `_warn_observer_fallback` for the
63
+ observer-fallback path).
32
64
  """
33
65
  nick = os.environ.get("CULTURE_NICK")
34
66
  if not nick or not _valid_nick(nick):
@@ -169,6 +201,7 @@ def _cmd_list(args: argparse.Namespace) -> None:
169
201
  print(f" {ch}")
170
202
  return
171
203
 
204
+ _warn_observer_fallback("channel list")
172
205
  observer = get_observer(args.config)
173
206
  channels = asyncio.run(observer.list_channels())
174
207
 
@@ -199,6 +232,7 @@ def _cmd_read(args: argparse.Namespace) -> None:
199
232
  print(f"<{nick}> {text}")
200
233
  return
201
234
 
235
+ _warn_observer_fallback("channel read")
202
236
  observer = get_observer(args.config)
203
237
  messages = asyncio.run(observer.read_channel(channel, limit=args.limit))
204
238
 
@@ -267,6 +301,7 @@ def _cmd_message(args: argparse.Namespace) -> None:
267
301
  print(f"Sent to {target}")
268
302
  return
269
303
 
304
+ _warn_observer_fallback("channel message")
270
305
  observer = get_observer(args.config)
271
306
  asyncio.run(observer.send_message(target, text))
272
307
  print(f"Sent to {target}")
@@ -0,0 +1,54 @@
1
+ """Shared constants for culture CLI modules."""
2
+
3
+ import os
4
+ import stat
5
+
6
+ from culture.bots.config import BOT_CONFIG_FILE # noqa: F401
7
+
8
+ DEFAULT_CONFIG = os.path.expanduser("~/.culture/server.yaml")
9
+ LOG_DIR = os.path.expanduser("~/.culture/logs")
10
+
11
+ _CONFIG_HELP = "Config file path"
12
+ _SERVER_NAME_HELP = "Server name"
13
+ _BOT_NAME_HELP = "Bot name"
14
+
15
+ DEFAULT_CHANNEL = "#general"
16
+ NO_AGENTS_MSG = "No agents configured"
17
+ CULTURE_DIR = ".culture"
18
+ AGENTS_YAML = "agents.yaml"
19
+
20
+ DEFAULT_SERVER_CONFIG = os.path.expanduser("~/.culture/server.yaml")
21
+ LEGACY_CONFIG = os.path.expanduser("~/.culture/agents.yaml")
22
+
23
+
24
+ def culture_runtime_dir() -> str:
25
+ """Return a user-private directory for culture daemon sockets.
26
+
27
+ Resolution order:
28
+
29
+ 1. ``$XDG_RUNTIME_DIR`` when set (Linux/systemd default — already
30
+ user-private at ``/run/user/<uid>``).
31
+ 2. ``~/.culture/run/`` otherwise (typical macOS path), created mode
32
+ 0700 if missing and re-tightened to 0700 on every call so a
33
+ hand-created or pre-existing dir cannot leak sockets.
34
+
35
+ Raises ``RuntimeError`` when neither ``XDG_RUNTIME_DIR`` nor a
36
+ resolvable home directory is available — silently writing a literal
37
+ ``~/.culture/run`` directory in CWD would surprise callers and the
38
+ daemons (which now route through this resolver) would fail at
39
+ socket-bind time anyway.
40
+ """
41
+ xdg = os.environ.get("XDG_RUNTIME_DIR")
42
+ if xdg:
43
+ return xdg
44
+ home = os.path.expanduser("~")
45
+ if not home or home == "~" or not os.path.isabs(home):
46
+ raise RuntimeError(
47
+ "culture_runtime_dir(): cannot resolve a home directory "
48
+ "(os.path.expanduser('~') returned %r). Set $HOME or "
49
+ "$XDG_RUNTIME_DIR before running culture commands." % home
50
+ )
51
+ fallback = os.path.join(home, ".culture", "run")
52
+ os.makedirs(fallback, mode=0o700, exist_ok=True)
53
+ os.chmod(fallback, stat.S_IRWXU)
54
+ return fallback
@@ -18,6 +18,7 @@ import time
18
18
  from collections import deque
19
19
 
20
20
  from culture.aio import maybe_await
21
+ from culture.cli.shared.constants import culture_runtime_dir
21
22
  from culture.clients.acp.agent_runner import ACPAgentRunner
22
23
  from culture.clients.acp.config import AgentConfig, DaemonConfig
23
24
  from culture.clients.acp.ipc import make_response
@@ -62,7 +63,7 @@ class ACPDaemon:
62
63
  self.skip_agent = skip_agent
63
64
 
64
65
  self._socket_path = os.path.join(
65
- socket_dir or os.environ.get("XDG_RUNTIME_DIR", "/tmp"),
66
+ socket_dir or culture_runtime_dir(),
66
67
  f"culture-{agent.nick}.sock",
67
68
  )
68
69
 
@@ -16,6 +16,7 @@ import os
16
16
  import sys
17
17
  from typing import Any
18
18
 
19
+ from culture.cli.shared.constants import culture_runtime_dir
19
20
  from culture.clients.acp.ipc import (
20
21
  MSG_TYPE_RESPONSE,
21
22
  MSG_TYPE_WHISPER,
@@ -192,8 +193,7 @@ def _sock_path_from_env() -> str:
192
193
  if not nick:
193
194
  print("ERROR: CULTURE_NICK environment variable is not set", file=sys.stderr)
194
195
  sys.exit(1)
195
- runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
196
- return os.path.join(runtime_dir, f"culture-{nick}.sock")
196
+ return os.path.join(culture_runtime_dir(), f"culture-{nick}.sock")
197
197
 
198
198
 
199
199
  def _parse_ask_timeout(remaining: list[str]) -> tuple[int, list[str]]:
@@ -8,6 +8,7 @@ import re
8
8
  import time
9
9
 
10
10
  from culture.aio import maybe_await
11
+ from culture.cli.shared.constants import culture_runtime_dir
11
12
  from culture.clients.claude.agent_runner import AgentRunner
12
13
  from culture.clients.claude.config import AgentConfig, DaemonConfig
13
14
  from culture.clients.claude.ipc import make_response
@@ -51,7 +52,7 @@ class AgentDaemon:
51
52
  self.skip_claude = skip_claude
52
53
 
53
54
  self._socket_path = os.path.join(
54
- socket_dir or os.environ.get("XDG_RUNTIME_DIR", "/tmp"),
55
+ socket_dir or culture_runtime_dir(),
55
56
  f"culture-{agent.nick}.sock",
56
57
  )
57
58
 
@@ -16,6 +16,7 @@ import os
16
16
  import sys
17
17
  from typing import Any
18
18
 
19
+ from culture.cli.shared.constants import culture_runtime_dir
19
20
  from culture.clients.claude.ipc import (
20
21
  MSG_TYPE_RESPONSE,
21
22
  MSG_TYPE_WHISPER,
@@ -189,8 +190,7 @@ def _sock_path_from_env() -> str:
189
190
  if not nick:
190
191
  print("ERROR: CULTURE_NICK environment variable is not set", file=sys.stderr)
191
192
  sys.exit(1)
192
- runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
193
- return os.path.join(runtime_dir, f"culture-{nick}.sock")
193
+ return os.path.join(culture_runtime_dir(), f"culture-{nick}.sock")
194
194
 
195
195
 
196
196
  def _parse_ask_timeout(remaining: list[str]) -> tuple[int, list[str]]:
@@ -15,6 +15,7 @@ import time
15
15
  from collections import deque
16
16
 
17
17
  from culture.aio import maybe_await
18
+ from culture.cli.shared.constants import culture_runtime_dir
18
19
  from culture.clients.codex.agent_runner import CodexAgentRunner
19
20
  from culture.clients.codex.config import AgentConfig, DaemonConfig
20
21
  from culture.clients.codex.ipc import make_response
@@ -66,7 +67,7 @@ class CodexDaemon:
66
67
  self.skip_codex = skip_codex
67
68
 
68
69
  self._socket_path = os.path.join(
69
- socket_dir or os.environ.get("XDG_RUNTIME_DIR", "/tmp"),
70
+ socket_dir or culture_runtime_dir(),
70
71
  f"culture-{agent.nick}.sock",
71
72
  )
72
73
 
@@ -16,6 +16,7 @@ import os
16
16
  import sys
17
17
  from typing import Any
18
18
 
19
+ from culture.cli.shared.constants import culture_runtime_dir
19
20
  from culture.clients.codex.ipc import (
20
21
  MSG_TYPE_RESPONSE,
21
22
  MSG_TYPE_WHISPER,
@@ -189,8 +190,7 @@ def _sock_path_from_env() -> str:
189
190
  if not nick:
190
191
  print("ERROR: CULTURE_NICK environment variable is not set", file=sys.stderr)
191
192
  sys.exit(1)
192
- runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
193
- return os.path.join(runtime_dir, f"culture-{nick}.sock")
193
+ return os.path.join(culture_runtime_dir(), f"culture-{nick}.sock")
194
194
 
195
195
 
196
196
  def _parse_ask_timeout(remaining: list[str]) -> tuple[int, list[str]]:
@@ -15,6 +15,7 @@ import time
15
15
  from collections import deque
16
16
 
17
17
  from culture.aio import maybe_await
18
+ from culture.cli.shared.constants import culture_runtime_dir
18
19
  from culture.clients.copilot.agent_runner import CopilotAgentRunner
19
20
  from culture.clients.copilot.config import AgentConfig, DaemonConfig
20
21
  from culture.clients.copilot.ipc import make_response
@@ -59,7 +60,7 @@ class CopilotDaemon:
59
60
  self.skip_copilot = skip_copilot
60
61
 
61
62
  self._socket_path = os.path.join(
62
- socket_dir or os.environ.get("XDG_RUNTIME_DIR", "/tmp"),
63
+ socket_dir or culture_runtime_dir(),
63
64
  f"culture-{agent.nick}.sock",
64
65
  )
65
66
 
@@ -16,6 +16,7 @@ import os
16
16
  import sys
17
17
  from typing import Any
18
18
 
19
+ from culture.cli.shared.constants import culture_runtime_dir
19
20
  from culture.clients.copilot.ipc import (
20
21
  MSG_TYPE_RESPONSE,
21
22
  MSG_TYPE_WHISPER,
@@ -192,8 +193,7 @@ def _sock_path_from_env() -> str:
192
193
  if not nick:
193
194
  print("ERROR: CULTURE_NICK environment variable is not set", file=sys.stderr)
194
195
  sys.exit(1)
195
- runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
196
- return os.path.join(runtime_dir, f"culture-{nick}.sock")
196
+ return os.path.join(culture_runtime_dir(), f"culture-{nick}.sock")
197
197
 
198
198
 
199
199
  def _parse_ask_timeout(remaining: list[str]) -> tuple[int, list[str]]:
@@ -7,6 +7,7 @@ import glob
7
7
  import os
8
8
 
9
9
  from culture.bots.config import BOT_CONFIG_FILE
10
+ from culture.cli.shared.constants import culture_runtime_dir
10
11
  from culture.protocol.message import Message as IRCMessage
11
12
 
12
13
  from .model import Agent, BotInfo, MeshState, Message, Room
@@ -428,8 +429,7 @@ async def _enrich_via_ipc(agents: dict[str, Agent], server_name: str) -> None:
428
429
  """Enrich local agents with daemon IPC status data."""
429
430
  from culture.clients.claude.ipc import decode_message, encode_message, make_request
430
431
 
431
- runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
432
- socket_pattern = os.path.join(runtime_dir, "culture-*.sock")
432
+ socket_pattern = os.path.join(culture_runtime_dir(), "culture-*.sock")
433
433
 
434
434
  for sock_path in glob.glob(socket_pattern):
435
435
  # Extract nick from socket filename: culture-<nick>.sock
@@ -295,7 +295,18 @@ Unix socket.
295
295
  $XDG_RUNTIME_DIR/culture-<nick>.sock
296
296
  ```
297
297
 
298
- Falls back to `/tmp/culture-<nick>.sock` if `XDG_RUNTIME_DIR` is not set.
298
+ Falls back to `~/.culture/run/culture-<nick>.sock` (mode 0700) if
299
+ `XDG_RUNTIME_DIR` is not set — typical on macOS. The fallback is
300
+ user-private rather than world-writable like `/tmp/`.
301
+
302
+ All socket-path resolvers (4 backend daemons, 4 skill irc_clients, the
303
+ CLI in `culture/cli/shared/constants.py::culture_runtime_dir()`, the
304
+ overview collector, and the console status reader) MUST go through
305
+ `culture_runtime_dir()`. A regression test in
306
+ `tests/test_socket_path_convergence.py` parametrically asserts every
307
+ site agrees, with `XDG_RUNTIME_DIR` both set and unset. Any future site
308
+ that re-introduces a raw `os.environ.get("XDG_RUNTIME_DIR", "/tmp")`
309
+ will fail that test (issue #302).
299
310
 
300
311
  ### Message Format
301
312
 
@@ -250,6 +250,19 @@ culture channel message "#general" "hello from the CLI"
250
250
 
251
251
  Uses an ephemeral IRC connection — no daemon required.
252
252
 
253
+ **Sending under an agent's nick.** Set `CULTURE_NICK=<server>-<agent>` and
254
+ `culture channel message` (along with `list` and `read`) routes through
255
+ the agent daemon's Unix socket so the message appears under the agent's
256
+ real nick instead of an ephemeral peek connection.
257
+
258
+ If `CULTURE_NICK` is set but the daemon's IPC socket is unreachable (or
259
+ the daemon rejects the request), the CLI falls back to the peek path
260
+ *and* prints a stderr warning that names the nick, the socket path, and
261
+ the issue tracker. Treat the warning as actionable: check
262
+ `culture agent status <nick>`, and if the daemon is running, file a bug
263
+ at <https://github.com/agentculture/culture/issues> — a silent fallback
264
+ here masked a macOS path-mismatch bug for two releases (#302).
265
+
253
266
  **Multi-line messages.** The message text interprets `\n` as a newline and
254
267
  `\t` as a tab, so the shell can pass multi-line input without needing
255
268
  `$'...'` quoting. Each line is sent as a separate IRC `PRIVMSG` (required by
@@ -22,6 +22,7 @@ from typing import Any
22
22
 
23
23
  # These imports point to YOUR backend's copies of these files:
24
24
  from culture.aio import maybe_await
25
+ from culture.cli.shared.constants import culture_runtime_dir
25
26
  from culture.clients.BACKEND.config import AgentConfig, DaemonConfig
26
27
  from culture.clients.BACKEND.ipc import make_response
27
28
  from culture.clients.BACKEND.irc_transport import IRCTransport
@@ -66,7 +67,7 @@ class AgentDaemon:
66
67
  self.skip_agent = skip_agent
67
68
 
68
69
  self._socket_path = os.path.join(
69
- socket_dir or os.environ.get("XDG_RUNTIME_DIR", "/tmp"),
70
+ socket_dir or culture_runtime_dir(),
70
71
  f"culture-{agent.nick}.sock",
71
72
  )
72
73
 
@@ -19,6 +19,7 @@ import os
19
19
  import sys
20
20
  from typing import Any
21
21
 
22
+ from culture.cli.shared.constants import culture_runtime_dir
22
23
  from culture.clients.BACKEND.ipc import (
23
24
  MSG_TYPE_RESPONSE,
24
25
  MSG_TYPE_WHISPER,
@@ -192,8 +193,7 @@ def _sock_path_from_env() -> str:
192
193
  if not nick:
193
194
  print("ERROR: CULTURE_NICK environment variable is not set", file=sys.stderr)
194
195
  sys.exit(1)
195
- runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
196
- return os.path.join(runtime_dir, f"culture-{nick}.sock")
196
+ return os.path.join(culture_runtime_dir(), f"culture-{nick}.sock")
197
197
 
198
198
 
199
199
  def _parse_ask_timeout(remaining: list[str]) -> tuple[int, list[str]]:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentirc-cli"
3
- version = "8.7.0"
3
+ version = "8.7.1"
4
4
  description = "Legacy alias for culture — install culture instead"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -12,6 +12,7 @@ from culture.cli.channel import (
12
12
  _require_ipc,
13
13
  _try_ipc,
14
14
  _valid_nick,
15
+ _warn_observer_fallback,
15
16
  dispatch,
16
17
  register,
17
18
  )
@@ -87,7 +88,8 @@ class TestMessageIpcRouting:
87
88
  monkeypatch.setenv("CULTURE_NICK", "spark-claude")
88
89
  monkeypatch.setenv("XDG_RUNTIME_DIR", tempfile.mkdtemp())
89
90
 
90
- # _try_ipc should return None when socket doesn't exist
91
+ # _try_ipc itself stays silent the warning is emitted by the
92
+ # observer-fallback caller (see TestObserverFallbackWarning).
91
93
  result = _try_ipc("irc_send", channel="#general", message="hello")
92
94
  assert result is None
93
95
 
@@ -98,6 +100,81 @@ class TestMessageIpcRouting:
98
100
  assert result is None
99
101
 
100
102
 
103
+ class TestObserverFallbackWarning:
104
+ """Issue #302: the three observer-fallback callers must warn loudly.
105
+
106
+ Before the fix, a daemon/CLI socket-path mismatch on macOS caused
107
+ `culture channel message` to silently fall back to an anonymous peek
108
+ connection. The CLI printed `Sent to #general` either way, so the
109
+ bug hid for two releases. The warning must (a) name the nick that
110
+ was attempted, (b) name the operation, and (c) point at the GitHub
111
+ issue tracker so the next reproducer takes seconds to file.
112
+
113
+ The warning lives in `_warn_observer_fallback`, called only by
114
+ `_cmd_message`, `_cmd_list`, and `_cmd_read`. `_topic_read` and the
115
+ `_require_ipc` commands exit on failure instead, so no spurious
116
+ "falling back" notice contradicts their actual error.
117
+ """
118
+
119
+ def test_warns_when_nick_set_and_daemon_unreachable(self, monkeypatch, capsys):
120
+ """CULTURE_NICK set + IPC down → stderr warning naming op + nick + issues URL."""
121
+ monkeypatch.setenv("CULTURE_NICK", "spark-claude")
122
+ monkeypatch.setenv("XDG_RUNTIME_DIR", tempfile.mkdtemp())
123
+
124
+ _warn_observer_fallback("channel message")
125
+
126
+ err = capsys.readouterr().err
127
+ assert "spark-claude" in err
128
+ assert "channel message" in err
129
+ assert "Falling back to observer" in err
130
+ assert "https://github.com/agentculture/culture/issues" in err
131
+
132
+ def test_warning_text_is_operation_specific(self, monkeypatch, capsys):
133
+ """Each caller passes its own operation name; helper renders it verbatim."""
134
+ monkeypatch.setenv("CULTURE_NICK", "spark-claude")
135
+ monkeypatch.setenv("XDG_RUNTIME_DIR", tempfile.mkdtemp())
136
+
137
+ _warn_observer_fallback("channel list")
138
+ err = capsys.readouterr().err
139
+ assert "channel list" in err
140
+ assert "channel message" not in err # no leakage from sibling callers
141
+
142
+ def test_no_warning_when_nick_unset(self, monkeypatch, capsys):
143
+ """Human use without CULTURE_NICK is the legitimate observer path — no warning."""
144
+ monkeypatch.delenv("CULTURE_NICK", raising=False)
145
+
146
+ _warn_observer_fallback("channel message")
147
+
148
+ assert capsys.readouterr().err == ""
149
+
150
+ def test_no_warning_when_nick_invalid(self, monkeypatch, capsys):
151
+ """Invalid nick falls into the same human-use bucket — no warning."""
152
+ monkeypatch.setenv("CULTURE_NICK", "nodash")
153
+
154
+ _warn_observer_fallback("channel message")
155
+
156
+ assert capsys.readouterr().err == ""
157
+
158
+ def test_topic_read_does_not_warn(self, monkeypatch, capsys):
159
+ """_topic_read uses _try_ipc but exits on failure — no fallback, no warning.
160
+
161
+ Regression guard against the Qodo/Copilot review on PR #304: the
162
+ previous design auto-warned inside `_try_ipc` and printed a
163
+ misleading 'falling back' notice for `topic` (which actually exits).
164
+ """
165
+ from culture.cli.channel import _topic_read
166
+
167
+ monkeypatch.setenv("CULTURE_NICK", "spark-claude")
168
+ monkeypatch.setenv("XDG_RUNTIME_DIR", tempfile.mkdtemp())
169
+
170
+ with pytest.raises(SystemExit):
171
+ _topic_read("#general")
172
+
173
+ err = capsys.readouterr().err
174
+ assert "Falling back" not in err
175
+ assert "topic query requires" in err
176
+
177
+
101
178
  class TestNickValidation:
102
179
  """Issue #202 review: CULTURE_NICK must match <server>-<agent> format."""
103
180
 
@@ -0,0 +1,86 @@
1
+ """Unit tests for culture/cli/shared/constants.py.
2
+
3
+ Issue #302 turned `culture_runtime_dir()` into the single source of truth
4
+ for the daemon socket directory. Pin its contract so any future refactor
5
+ that breaks the env-var precedence, fallback path, or 0700 mode is caught
6
+ in CI rather than at runtime on macOS.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import stat
13
+ from pathlib import Path
14
+
15
+ from culture.cli.shared.constants import culture_runtime_dir
16
+
17
+
18
+ def test_uses_xdg_runtime_dir_when_set(monkeypatch, tmp_path):
19
+ """When XDG_RUNTIME_DIR is set, the value is returned verbatim."""
20
+ monkeypatch.setenv("XDG_RUNTIME_DIR", str(tmp_path))
21
+ assert culture_runtime_dir() == str(tmp_path)
22
+
23
+
24
+ def test_falls_back_to_culture_run_when_xdg_unset(monkeypatch, tmp_path):
25
+ """When XDG_RUNTIME_DIR is missing, fall back to ~/.culture/run/.
26
+
27
+ macOS regression: this used to fall back to /tmp in the daemons but to
28
+ ~/.culture/run/ in the CLI. The fix converged everyone on the latter.
29
+ """
30
+ monkeypatch.delenv("XDG_RUNTIME_DIR", raising=False)
31
+ monkeypatch.setenv("HOME", str(tmp_path))
32
+ expected = str(tmp_path / ".culture" / "run")
33
+ assert culture_runtime_dir() == expected
34
+
35
+
36
+ def test_creates_fallback_dir_with_user_only_permissions(monkeypatch, tmp_path):
37
+ """The fallback directory is created mode 0700 (user-private).
38
+
39
+ /tmp would have been world-writable; ~/.culture/run/ is mode 0700 so
40
+ sockets there cannot be observed or hijacked by other local users.
41
+ """
42
+ monkeypatch.delenv("XDG_RUNTIME_DIR", raising=False)
43
+ monkeypatch.setenv("HOME", str(tmp_path))
44
+ path = Path(culture_runtime_dir())
45
+ assert path.exists()
46
+ assert path.is_dir()
47
+ mode = stat.S_IMODE(os.stat(path).st_mode)
48
+ assert mode == 0o700, f"expected mode 0700, got {oct(mode)}"
49
+
50
+
51
+ def test_raises_when_home_unresolvable(monkeypatch):
52
+ """Both XDG_RUNTIME_DIR and HOME unset → RuntimeError, not a literal '~' dir.
53
+
54
+ Qodo flagged that the pre-fix resolver would silently `mkdir` a literal
55
+ `~/.culture/run` in CWD if `os.path.expanduser('~')` could not resolve.
56
+ Now that 9 daemons/skills depend on this resolver, fail loud instead.
57
+ """
58
+ monkeypatch.delenv("XDG_RUNTIME_DIR", raising=False)
59
+ monkeypatch.delenv("HOME", raising=False)
60
+ # On Linux, expanduser may still consult /etc/passwd via pwd. Force
61
+ # the fallback path by also clearing the user's pwd entry lookup.
62
+ monkeypatch.setattr(os.path, "expanduser", lambda p: p)
63
+
64
+ import pytest
65
+
66
+ with pytest.raises(RuntimeError, match="cannot resolve a home directory"):
67
+ culture_runtime_dir()
68
+
69
+
70
+ def test_enforces_permissions_on_existing_dir(monkeypatch, tmp_path):
71
+ """Even if the fallback dir already exists with wrong perms, it's tightened.
72
+
73
+ Defensive: a previous version of culture (or a hand-created dir) may
74
+ have left ~/.culture/run/ at 0755. Re-tighten on every call so the
75
+ invariant always holds at runtime.
76
+ """
77
+ monkeypatch.delenv("XDG_RUNTIME_DIR", raising=False)
78
+ monkeypatch.setenv("HOME", str(tmp_path))
79
+ pre_existing = tmp_path / ".culture" / "run"
80
+ pre_existing.mkdir(parents=True, mode=0o755)
81
+ os.chmod(pre_existing, 0o755) # noqa: S103 — intentional: test that loose perms get tightened
82
+
83
+ culture_runtime_dir()
84
+
85
+ mode = stat.S_IMODE(os.stat(pre_existing).st_mode)
86
+ assert mode == 0o700