agentirc-cli 2.0.1__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/CHANGELOG.md +13 -0
  2. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/PKG-INFO +14 -13
  3. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/README.md +12 -12
  4. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/cli.py +119 -1
  5. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/config.py +1 -0
  6. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/irc_transport.py +4 -0
  7. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/config.py +1 -0
  8. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/irc_transport.py +4 -0
  9. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/config.py +1 -0
  10. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/irc_transport.py +4 -0
  11. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/config.py +1 -0
  12. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/irc_transport.py +4 -0
  13. agentirc_cli-3.0.0/culture/console/__init__.py +1 -0
  14. agentirc_cli-3.0.0/culture/console/app.py +576 -0
  15. agentirc_cli-3.0.0/culture/console/client.py +381 -0
  16. agentirc_cli-3.0.0/culture/console/commands.py +93 -0
  17. agentirc_cli-3.0.0/culture/console/widgets/__init__.py +1 -0
  18. agentirc_cli-3.0.0/culture/console/widgets/chat.py +147 -0
  19. agentirc_cli-3.0.0/culture/console/widgets/info_panel.py +172 -0
  20. agentirc_cli-3.0.0/culture/console/widgets/sidebar.py +191 -0
  21. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/pidfile.py +39 -0
  22. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/commands.py +1 -0
  23. agentirc_cli-3.0.0/culture/protocol/extensions/icons.md +89 -0
  24. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/client.py +21 -1
  25. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/ircd.py +2 -0
  26. agentirc_cli-3.0.0/culture/server/skills/icon.py +52 -0
  27. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/index.md +17 -0
  28. agentirc_cli-3.0.0/docs/superpowers/plans/2026-04-06-console-chat.md +2246 -0
  29. agentirc_cli-3.0.0/docs/superpowers/specs/2026-04-06-console-chat-design.md +298 -0
  30. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/config.py +1 -0
  31. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/irc_transport.py +4 -0
  32. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/pyproject.toml +2 -1
  33. agentirc_cli-3.0.0/tests/test_console_client.py +298 -0
  34. agentirc_cli-3.0.0/tests/test_console_commands.py +129 -0
  35. agentirc_cli-3.0.0/tests/test_console_connection.py +70 -0
  36. agentirc_cli-3.0.0/tests/test_console_icons.py +228 -0
  37. agentirc_cli-3.0.0/tests/test_console_integration.py +65 -0
  38. agentirc_cli-3.0.0/tests/test_server_icon_skill.py +214 -0
  39. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/uv.lock +58 -1
  40. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.claude/skills/pr-review/SKILL.md +0 -0
  41. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.claude/skills/run-tests/SKILL.md +0 -0
  42. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
  43. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.flake8 +0 -0
  44. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.github/workflows/pages.yml +0 -0
  45. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.github/workflows/publish.yml +0 -0
  46. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.github/workflows/security-checks.yml +0 -0
  47. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.github/workflows/tests.yml +0 -0
  48. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.gitignore +0 -0
  49. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.markdownlint-cli2.yaml +0 -0
  50. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.pr_agent.toml +0 -0
  51. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.pre-commit-config.yaml +0 -0
  52. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/.pylintrc +0 -0
  53. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/CLAUDE.md +0 -0
  54. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/CNAME +0 -0
  55. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/Gemfile +0 -0
  56. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/Gemfile.lock +0 -0
  57. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/LICENSE +0 -0
  58. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/SECURITY.md +0 -0
  59. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/_config.yml +0 -0
  60. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/_sass/color_schemes/anthropic.scss +0 -0
  61. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/_sass/custom/custom.scss +0 -0
  62. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/__init__.py +0 -0
  63. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/__main__.py +0 -0
  64. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/bots/__init__.py +0 -0
  65. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/bots/bot.py +0 -0
  66. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/bots/bot_manager.py +0 -0
  67. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/bots/config.py +0 -0
  68. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/bots/http_listener.py +0 -0
  69. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/bots/template_engine.py +0 -0
  70. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/bots/virtual_client.py +0 -0
  71. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/__init__.py +0 -0
  72. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/__init__.py +0 -0
  73. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/agent_runner.py +0 -0
  74. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/daemon.py +0 -0
  75. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/ipc.py +0 -0
  76. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/message_buffer.py +0 -0
  77. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/skill/SKILL.md +0 -0
  78. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/skill/__init__.py +0 -0
  79. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/skill/irc_client.py +0 -0
  80. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/socket_server.py +0 -0
  81. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/supervisor.py +0 -0
  82. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/acp/webhook.py +0 -0
  83. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/__init__.py +0 -0
  84. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/__main__.py +0 -0
  85. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/agent_runner.py +0 -0
  86. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/daemon.py +0 -0
  87. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/ipc.py +0 -0
  88. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/message_buffer.py +0 -0
  89. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/skill/SKILL.md +0 -0
  90. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/skill/__init__.py +0 -0
  91. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/skill/irc_client.py +0 -0
  92. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/socket_server.py +0 -0
  93. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/supervisor.py +0 -0
  94. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/claude/webhook.py +0 -0
  95. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/__init__.py +0 -0
  96. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/agent_runner.py +0 -0
  97. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/daemon.py +0 -0
  98. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/ipc.py +0 -0
  99. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/message_buffer.py +0 -0
  100. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/skill/SKILL.md +0 -0
  101. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/skill/__init__.py +0 -0
  102. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/skill/irc_client.py +0 -0
  103. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/socket_server.py +0 -0
  104. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/supervisor.py +0 -0
  105. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/codex/webhook.py +0 -0
  106. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/__init__.py +0 -0
  107. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/agent_runner.py +0 -0
  108. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/daemon.py +0 -0
  109. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/ipc.py +0 -0
  110. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/message_buffer.py +0 -0
  111. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/skill/SKILL.md +0 -0
  112. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/skill/__init__.py +0 -0
  113. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/skill/irc_client.py +0 -0
  114. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/socket_server.py +0 -0
  115. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/supervisor.py +0 -0
  116. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/clients/copilot/webhook.py +0 -0
  117. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/credentials.py +0 -0
  118. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/learn_prompt.py +0 -0
  119. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/mesh_config.py +0 -0
  120. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/observer.py +0 -0
  121. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/overview/__init__.py +0 -0
  122. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/overview/collector.py +0 -0
  123. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/overview/model.py +0 -0
  124. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/overview/renderer_text.py +0 -0
  125. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/overview/renderer_web.py +0 -0
  126. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/overview/web/style.css +0 -0
  127. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/persistence.py +0 -0
  128. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/__init__.py +0 -0
  129. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/extensions/federation.md +0 -0
  130. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/extensions/history.md +0 -0
  131. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/extensions/rooms.md +0 -0
  132. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/extensions/tags.md +0 -0
  133. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/extensions/threads.md +0 -0
  134. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/message.py +0 -0
  135. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/protocol-index.md +0 -0
  136. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/protocol/replies.py +0 -0
  137. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/__init__.py +0 -0
  138. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/__main__.py +0 -0
  139. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/channel.py +0 -0
  140. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/config.py +0 -0
  141. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/remote_client.py +0 -0
  142. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/room_store.py +0 -0
  143. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/rooms_util.py +0 -0
  144. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/server_link.py +0 -0
  145. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/skill.py +0 -0
  146. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/skills/__init__.py +0 -0
  147. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/skills/history.py +0 -0
  148. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/skills/rooms.py +0 -0
  149. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/skills/threads.py +0 -0
  150. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/server/thread_store.py +0 -0
  151. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/culture/skills/culture/SKILL.md +0 -0
  152. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/agent-lifecycle.md +0 -0
  153. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/agentic-self-learn.md +0 -0
  154. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/agent-client.md +0 -0
  155. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/agent-harness-spec.md +0 -0
  156. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/design.md +0 -0
  157. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/harness-conformance.md +0 -0
  158. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/index.md +0 -0
  159. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/layer1-core-irc.md +0 -0
  160. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/layer2-attention.md +0 -0
  161. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/layer3-skills.md +0 -0
  162. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/layer4-federation.md +0 -0
  163. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/layer5-agent-harness.md +0 -0
  164. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/server-architecture.md +0 -0
  165. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/architecture/threads.md +0 -0
  166. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/acp/overview.md +0 -0
  167. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/claude/configuration.md +0 -0
  168. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/claude/context-management.md +0 -0
  169. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/claude/irc-tools.md +0 -0
  170. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/claude/overview.md +0 -0
  171. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/claude/setup.md +0 -0
  172. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/claude/supervisor.md +0 -0
  173. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/claude/webhooks.md +0 -0
  174. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/codex/configuration.md +0 -0
  175. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/codex/context-management.md +0 -0
  176. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/codex/irc-tools.md +0 -0
  177. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/codex/overview.md +0 -0
  178. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/codex/setup.md +0 -0
  179. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/codex/supervisor.md +0 -0
  180. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/codex/webhooks.md +0 -0
  181. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/copilot/configuration.md +0 -0
  182. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/copilot/context-management.md +0 -0
  183. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/copilot/irc-tools.md +0 -0
  184. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/copilot/overview.md +0 -0
  185. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/copilot/setup.md +0 -0
  186. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/copilot/supervisor.md +0 -0
  187. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/clients/copilot/webhooks.md +0 -0
  188. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/culture-cli.md +0 -0
  189. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/getting-started.md +0 -0
  190. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/SECURITY.md +0 -0
  191. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/bots.md +0 -0
  192. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/ci.md +0 -0
  193. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/cli.md +0 -0
  194. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/docs-site.md +0 -0
  195. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/index.md +0 -0
  196. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/ops-tooling.md +0 -0
  197. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/overview.md +0 -0
  198. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/operations/publishing.md +0 -0
  199. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  200. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/rooms.md +0 -0
  201. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  202. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  203. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  204. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  205. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
  206. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
  207. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
  208. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -0
  209. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  210. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  211. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  212. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  213. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
  214. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
  215. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
  216. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
  217. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -0
  218. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -0
  219. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/01-pair-programming.md +0 -0
  220. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/02-code-review-ensemble.md +0 -0
  221. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/03-cross-server-delegation.md +0 -0
  222. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/04-knowledge-propagation.md +0 -0
  223. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/05-the-observer.md +0 -0
  224. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/06-cross-server-ops.md +0 -0
  225. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/07-supervisor-intervention.md +0 -0
  226. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/08-apps-as-agents.md +0 -0
  227. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/09-research-swarm.md +0 -0
  228. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases/10-agent-lifecycle.md +0 -0
  229. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/use-cases-index.md +0 -0
  230. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/docs/what-is-culture.md +0 -0
  231. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/README.md +0 -0
  232. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/daemon.py +0 -0
  233. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/ipc.py +0 -0
  234. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/message_buffer.py +0 -0
  235. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/skill/SKILL.md +0 -0
  236. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/skill/irc_client.py +0 -0
  237. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/socket_server.py +0 -0
  238. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/packages/agent-harness/webhook.py +0 -0
  239. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  240. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/plugins/claude-code/skills/culture/SKILL.md +0 -0
  241. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  242. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
  243. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/sonar-project.properties +0 -0
  244. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/__init__.py +0 -0
  245. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/conftest.py +0 -0
  246. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_acp_daemon.py +0 -0
  247. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_agent_runner.py +0 -0
  248. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_bot.py +0 -0
  249. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_bot_config.py +0 -0
  250. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_bot_manager.py +0 -0
  251. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_bots_integration.py +0 -0
  252. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_channel.py +0 -0
  253. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_codex_daemon.py +0 -0
  254. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_connection.py +0 -0
  255. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_copilot_daemon.py +0 -0
  256. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_daemon.py +0 -0
  257. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_daemon_config.py +0 -0
  258. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_daemon_ipc.py +0 -0
  259. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_discovery.py +0 -0
  260. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_federation.py +0 -0
  261. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_history.py +0 -0
  262. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_http_listener.py +0 -0
  263. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_integration_layer5.py +0 -0
  264. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_ipc.py +0 -0
  265. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_irc_transport.py +0 -0
  266. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_link_reconnect.py +0 -0
  267. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_mentions.py +0 -0
  268. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_mesh_config.py +0 -0
  269. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_message.py +0 -0
  270. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_message_buffer.py +0 -0
  271. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_messaging.py +0 -0
  272. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_modes.py +0 -0
  273. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_overview_cli.py +0 -0
  274. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_overview_collector.py +0 -0
  275. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_overview_model.py +0 -0
  276. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_overview_renderer.py +0 -0
  277. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_overview_web.py +0 -0
  278. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_persistence.py +0 -0
  279. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_pidfile.py +0 -0
  280. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_room_persistence.py +0 -0
  281. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_rooms.py +0 -0
  282. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_rooms_federation.py +0 -0
  283. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_rooms_integration.py +0 -0
  284. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_setup_update_cli.py +0 -0
  285. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_skill_client.py +0 -0
  286. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_skills.py +0 -0
  287. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_socket_server.py +0 -0
  288. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_supervisor.py +0 -0
  289. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_template_engine.py +0 -0
  290. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_thread_buffer.py +0 -0
  291. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_threads.py +0 -0
  292. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/tests/test_virtual_client.py +0 -0
  293. {agentirc_cli-2.0.1 → agentirc_cli-3.0.0}/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
+ ## [3.0.0] - 2026-04-06
8
+
9
+
10
+ ### Added
11
+
12
+ - Console chat TUI for human participation in the IRC mesh (culture console)
13
+ - ICON IRC protocol extension for custom entity icons
14
+ - User modes (+H/+A/+B) for entity type identification
15
+ - Server discovery and default server management
16
+ - Three-column TUI layout with sidebar, chat, and info panel
17
+ - View switching: overview, status, agent detail
18
+ - Command parser with full CLI command parity
19
+
7
20
  ## [2.0.1] - 2026-04-05
8
21
 
9
22
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 2.0.1
3
+ Version: 3.0.0
4
4
  Summary: Legacy alias for culture — install culture instead
5
5
  Project-URL: Homepage, https://github.com/OriNachum/culture
6
6
  Author: Ori Nachum
@@ -17,6 +17,7 @@ Requires-Dist: anthropic>=0.40
17
17
  Requires-Dist: claude-agent-sdk>=0.1
18
18
  Requires-Dist: mistune>=3.0
19
19
  Requires-Dist: pyyaml>=6.0
20
+ Requires-Dist: textual>=1.0
20
21
  Provides-Extra: copilot
21
22
  Requires-Dist: github-copilot-sdk; extra == 'copilot'
22
23
  Description-Content-Type: text/markdown
@@ -72,18 +73,18 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
72
73
 
73
74
  ## Why Culture
74
75
 
75
- | | Culture | Ruflo |
76
- |---|---|---|
77
- | **Architecture** | Peer mesh — no hierarchy, servers link as equals | Queen-led swarm hierarchies with centralized ledger |
78
- | **Protocol** | IRC (simple, text-native, LLM-familiar) — any client connects | Proprietary CLI/MCP with custom messaging |
79
- | **Federation** | Real server-to-server across machines | Within single orchestration instance |
80
- | **Agent backends** | Claude, Codex, Copilot, ACP (any) — each runs natively | Multi-LLM routing, primarily Claude-focused |
81
- | **Human participation** | First-class — same protocol, any IRC client | Pair programming modes with verification gates |
82
- | **Lifecycle** | Persistent daemons with sleep/wake cycles | Lifecycle hooks, no explicit sleep/wake |
83
- | **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + fallback agents |
84
- | **Observability** | Live web dashboard + any IRC client | CLI commands (metrics partially mocked) |
85
- | **Self-organization** | Tag-driven room membership | ML-based routing with learning pipeline |
86
- | **Philosophy** | Simple, organic, transparent | Enterprise-complex (130+ skills, vector DB, Q-learning) |
76
+ | | Culture | Agent Orchestrator | Ruflo |
77
+ |---|---|---|---|
78
+ | **Architecture** | Peer mesh — no hierarchy, servers link as equals | Plugin-based orchestrator — spawns workers per issue | Queen-led swarm hierarchies with centralized ledger |
79
+ | **Protocol** | IRC (simple, text-native, LLM-familiar) — any client connects | Git worktrees + GitHub/GitLab APIs | Proprietary CLI/MCP with custom messaging |
80
+ | **Federation** | Real server-to-server across machines | Single-machine orchestration | Within single orchestration instance |
81
+ | **Agent backends** | Claude, Codex, Copilot, ACP (any) — each runs natively | Claude Code, Codex, Aider, OpenCode — plugin-swappable | Multi-LLM routing, primarily Claude-focused |
82
+ | **Human participation** | First-class — same protocol, any IRC client | Dashboard supervisor — pulled in for approvals | Pair programming modes with verification gates |
83
+ | **Lifecycle** | Persistent daemons with sleep/wake cycles | Spawns per-issue, cleans up after merge | Lifecycle hooks, no explicit sleep/wake |
84
+ | **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + escalation timeouts | Retry limits + fallback agents |
85
+ | **Observability** | Live web dashboard + any IRC client | Web dashboard + Slack/Discord/webhook alerts | CLI commands (metrics partially mocked) |
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
88
 
88
89
  ---
89
90
 
@@ -49,18 +49,18 @@ Claude Code · Codex · Copilot · ACP (Cline, Kiro, OpenCode, Gemini, ...)
49
49
 
50
50
  ## Why Culture
51
51
 
52
- | | Culture | Ruflo |
53
- |---|---|---|
54
- | **Architecture** | Peer mesh — no hierarchy, servers link as equals | Queen-led swarm hierarchies with centralized ledger |
55
- | **Protocol** | IRC (simple, text-native, LLM-familiar) — any client connects | Proprietary CLI/MCP with custom messaging |
56
- | **Federation** | Real server-to-server across machines | Within single orchestration instance |
57
- | **Agent backends** | Claude, Codex, Copilot, ACP (any) — each runs natively | Multi-LLM routing, primarily Claude-focused |
58
- | **Human participation** | First-class — same protocol, any IRC client | Pair programming modes with verification gates |
59
- | **Lifecycle** | Persistent daemons with sleep/wake cycles | Lifecycle hooks, no explicit sleep/wake |
60
- | **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + fallback agents |
61
- | **Observability** | Live web dashboard + any IRC client | CLI commands (metrics partially mocked) |
62
- | **Self-organization** | Tag-driven room membership | ML-based routing with learning pipeline |
63
- | **Philosophy** | Simple, organic, transparent | Enterprise-complex (130+ skills, vector DB, Q-learning) |
52
+ | | Culture | Agent Orchestrator | Ruflo |
53
+ |---|---|---|---|
54
+ | **Architecture** | Peer mesh — no hierarchy, servers link as equals | Plugin-based orchestrator — spawns workers per issue | Queen-led swarm hierarchies with centralized ledger |
55
+ | **Protocol** | IRC (simple, text-native, LLM-familiar) — any client connects | Git worktrees + GitHub/GitLab APIs | Proprietary CLI/MCP with custom messaging |
56
+ | **Federation** | Real server-to-server across machines | Single-machine orchestration | Within single orchestration instance |
57
+ | **Agent backends** | Claude, Codex, Copilot, ACP (any) — each runs natively | Claude Code, Codex, Aider, OpenCode — plugin-swappable | Multi-LLM routing, primarily Claude-focused |
58
+ | **Human participation** | First-class — same protocol, any IRC client | Dashboard supervisor — pulled in for approvals | Pair programming modes with verification gates |
59
+ | **Lifecycle** | Persistent daemons with sleep/wake cycles | Spawns per-issue, cleans up after merge | Lifecycle hooks, no explicit sleep/wake |
60
+ | **Spiraling detection** | AI supervisor reads conversation meaning | Retry limits + escalation timeouts | Retry limits + fallback agents |
61
+ | **Observability** | Live web dashboard + any IRC client | Web dashboard + Slack/Discord/webhook alerts | CLI commands (metrics partially mocked) |
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) |
64
64
 
65
65
  ---
66
66
 
@@ -18,6 +18,7 @@ Subcommands:
18
18
  culture overview [--room X] [--agent X] Show mesh overview
19
19
  culture setup [--config X] [--uninstall] Set up mesh from mesh.yaml
20
20
  culture update [--dry-run] [--skip-upgrade] Upgrade and restart mesh
21
+ culture console [server_name] Interactive admin console TUI
21
22
  """
22
23
 
23
24
  from __future__ import annotations
@@ -131,6 +132,9 @@ def _build_parser() -> argparse.ArgumentParser:
131
132
  srv_status = server_sub.add_parser("status", help="Check server daemon status")
132
133
  srv_status.add_argument("--name", default="culture", help="Server name")
133
134
 
135
+ srv_default = server_sub.add_parser("default", help="Set default server")
136
+ srv_default.add_argument("name", help="Server name to set as default")
137
+
134
138
  # -- create / join subcommands -----------------------------------------
135
139
  # 'create' registers an agent definition; 'join' adds it to the mesh.
136
140
  # 'init' is a deprecated alias for 'create'.
@@ -316,6 +320,20 @@ def _build_parser() -> argparse.ArgumentParser:
316
320
  bot_inspect.add_argument("name", help="Bot name")
317
321
  bot_inspect.add_argument("--config", default=DEFAULT_CONFIG, help="Config file path")
318
322
 
323
+ # -- console subcommand ------------------------------------------------
324
+ console_parser = sub.add_parser("console", help="Interactive admin console")
325
+ console_parser.add_argument(
326
+ "server_name",
327
+ nargs="?",
328
+ default=None,
329
+ help="Server to connect to (auto-detects if omitted)",
330
+ )
331
+ console_parser.add_argument(
332
+ "--config",
333
+ default=DEFAULT_CONFIG,
334
+ help="Config file path",
335
+ )
336
+
319
337
  return parser
320
338
 
321
339
 
@@ -353,6 +371,7 @@ def main() -> None:
353
371
  "setup": _cmd_setup,
354
372
  "update": _cmd_update,
355
373
  "bot": _cmd_bot,
374
+ "console": _cmd_console,
356
375
  }
357
376
  handler = dispatch.get(args.command)
358
377
  if handler:
@@ -367,6 +386,90 @@ def main() -> None:
367
386
  sys.exit(1)
368
387
 
369
388
 
389
+ # -----------------------------------------------------------------------
390
+ # Console subcommand
391
+ # -----------------------------------------------------------------------
392
+
393
+
394
+ def _resolve_server(server_name: str | None) -> tuple[str, int] | None:
395
+ """Resolve server name and port from running servers.
396
+
397
+ Returns (server_name, port) or None if no servers are running.
398
+ """
399
+ from culture.pidfile import list_servers, read_default_server, read_port
400
+
401
+ if server_name:
402
+ p = read_port(server_name)
403
+ port = p if p else 6667
404
+ return server_name, port
405
+
406
+ servers = list_servers()
407
+ if not servers:
408
+ return None
409
+
410
+ if len(servers) == 1:
411
+ return servers[0]["name"], servers[0]["port"]
412
+
413
+ default = read_default_server()
414
+ if default:
415
+ match = [s for s in servers if s["name"] == default]
416
+ if match:
417
+ return match[0]["name"], match[0]["port"]
418
+
419
+ return servers[0]["name"], servers[0]["port"]
420
+
421
+
422
+ def _cmd_console(args: argparse.Namespace) -> None:
423
+ """Launch the interactive console TUI."""
424
+ result = _resolve_server(args.server_name)
425
+ if result is None:
426
+ print("No culture servers running. Start one with: culture server start")
427
+ return
428
+
429
+ server_name, port = result
430
+ host = "127.0.0.1"
431
+
432
+ nick_suffix = _resolve_console_nick()
433
+ nick = f"{server_name}-{nick_suffix}"
434
+
435
+ from culture.console.app import ConsoleApp
436
+ from culture.console.client import ConsoleIRCClient
437
+
438
+ client = ConsoleIRCClient(host=host, port=port, nick=nick, mode="H")
439
+
440
+ async def run():
441
+ await client.connect()
442
+ app = ConsoleApp(irc_client=client, server_name=server_name)
443
+ await app.run_async()
444
+
445
+ asyncio.run(run())
446
+
447
+
448
+ def _resolve_console_nick() -> str:
449
+ """Resolve the human nick: git username -> OS user -> config override."""
450
+ import re
451
+ import subprocess
452
+
453
+ try:
454
+ result = subprocess.run(
455
+ ["git", "config", "user.name"],
456
+ capture_output=True,
457
+ text=True,
458
+ timeout=2,
459
+ )
460
+ if result.returncode == 0 and result.stdout.strip():
461
+ name = result.stdout.strip().lower()
462
+ name = re.sub(r"[^a-z0-9-]", "", name.replace(" ", "-"))
463
+ if name:
464
+ return name
465
+ except (subprocess.SubprocessError, FileNotFoundError):
466
+ pass
467
+
468
+ import os
469
+
470
+ return os.environ.get("USER", "human")
471
+
472
+
370
473
  # -----------------------------------------------------------------------
371
474
  # Server subcommands
372
475
  # -----------------------------------------------------------------------
@@ -374,7 +477,7 @@ def main() -> None:
374
477
 
375
478
  def _cmd_server(args: argparse.Namespace) -> None:
376
479
  if not args.server_command:
377
- print("Usage: culture server {start|stop|status}", file=sys.stderr)
480
+ print("Usage: culture server {start|stop|status|default}", file=sys.stderr)
378
481
  sys.exit(1)
379
482
 
380
483
  if args.server_command == "start":
@@ -383,6 +486,11 @@ def _cmd_server(args: argparse.Namespace) -> None:
383
486
  _server_stop(args)
384
487
  elif args.server_command == "status":
385
488
  _server_status(args)
489
+ elif args.server_command == "default":
490
+ from culture.pidfile import write_default_server
491
+
492
+ write_default_server(args.name)
493
+ print(f"Default server set to '{args.name}'")
386
494
 
387
495
 
388
496
  def _server_start(args: argparse.Namespace) -> None:
@@ -406,6 +514,11 @@ def _server_start(args: argparse.Namespace) -> None:
406
514
  print(f"Server '{args.name}' starting in foreground (PID {os.getpid()})")
407
515
  print(f" Listening on {args.host}:{args.port}")
408
516
  print(f" Webhook port: {args.webhook_port}")
517
+ # Auto-set default server if none is set
518
+ from culture.pidfile import read_default_server, write_default_server
519
+
520
+ if read_default_server() is None:
521
+ write_default_server(args.name)
409
522
  try:
410
523
  asyncio.run(_run_server(args.name, args.host, args.port, links, args.webhook_port))
411
524
  finally:
@@ -424,6 +537,11 @@ def _server_start(args: argparse.Namespace) -> None:
424
537
  print(f"Server '{args.name}' started (PID {pid})")
425
538
  print(f" Listening on {args.host}:{args.port}")
426
539
  print(f" Logs: {LOG_DIR}/server-{args.name}.log")
540
+ # Auto-set default server if none is set
541
+ from culture.pidfile import read_default_server, write_default_server
542
+
543
+ if read_default_server() is None:
544
+ write_default_server(args.name)
427
545
  else:
428
546
  print(f"Server '{args.name}' failed to start", file=sys.stderr)
429
547
  sys.exit(1)
@@ -59,6 +59,7 @@ class AgentConfig:
59
59
  model: str = "anthropic/claude-sonnet-4-6"
60
60
  system_prompt: str = ""
61
61
  tags: list[str] = field(default_factory=list)
62
+ icon: str | None = None
62
63
 
63
64
 
64
65
  @dataclass
@@ -24,6 +24,7 @@ class IRCTransport:
24
24
  on_mention: Callable[[str, str, str], None] | None = None,
25
25
  tags: list[str] | None = None,
26
26
  on_roominvite: Callable[[str, str], None] | None = None,
27
+ icon: str | None = None,
27
28
  ):
28
29
  self.host = host
29
30
  self.port = port
@@ -34,6 +35,7 @@ class IRCTransport:
34
35
  self.on_mention = on_mention
35
36
  self.tags = tags or []
36
37
  self.on_roominvite = on_roominvite
38
+ self.icon = icon
37
39
  self.connected = False
38
40
  self._reader: asyncio.StreamReader | None = None
39
41
  self._writer: asyncio.StreamWriter | None = None
@@ -174,6 +176,8 @@ class IRCTransport:
174
176
  if self.tags:
175
177
  tags_str = ",".join(self.tags)
176
178
  await self._send_raw(f"TAGS {self.nick} {tags_str}")
179
+ if self.icon:
180
+ await self._send_raw(f"ICON {self.icon}")
177
181
 
178
182
  async def _on_privmsg(self, msg: Message) -> None:
179
183
  if len(msg.params) < 2:
@@ -59,6 +59,7 @@ class AgentConfig:
59
59
  thinking: str = "medium"
60
60
  system_prompt: str = ""
61
61
  tags: list[str] = field(default_factory=list)
62
+ icon: str | None = None
62
63
 
63
64
 
64
65
  @dataclass
@@ -24,6 +24,7 @@ class IRCTransport:
24
24
  on_mention: Callable[[str, str, str], None] | None = None,
25
25
  tags: list[str] | None = None,
26
26
  on_roominvite: Callable[[str, str], None] | None = None,
27
+ icon: str | None = None,
27
28
  ):
28
29
  self.host = host
29
30
  self.port = port
@@ -34,6 +35,7 @@ class IRCTransport:
34
35
  self.on_mention = on_mention
35
36
  self.tags = tags or []
36
37
  self.on_roominvite = on_roominvite
38
+ self.icon = icon
37
39
  self.connected = False
38
40
  self._reader: asyncio.StreamReader | None = None
39
41
  self._writer: asyncio.StreamWriter | None = None
@@ -174,6 +176,8 @@ class IRCTransport:
174
176
  if self.tags:
175
177
  tags_str = ",".join(self.tags)
176
178
  await self._send_raw(f"TAGS {self.nick} {tags_str}")
179
+ if self.icon:
180
+ await self._send_raw(f"ICON {self.icon}")
177
181
 
178
182
  async def _on_privmsg(self, msg: Message) -> None:
179
183
  if len(msg.params) < 2:
@@ -57,6 +57,7 @@ class AgentConfig:
57
57
  model: str = "gpt-5.4"
58
58
  system_prompt: str = ""
59
59
  tags: list[str] = field(default_factory=list)
60
+ icon: str | None = None
60
61
 
61
62
 
62
63
  @dataclass
@@ -24,6 +24,7 @@ class IRCTransport:
24
24
  on_mention: Callable[[str, str, str], None] | None = None,
25
25
  tags: list[str] | None = None,
26
26
  on_roominvite: Callable[[str, str], None] | None = None,
27
+ icon: str | None = None,
27
28
  ):
28
29
  self.host = host
29
30
  self.port = port
@@ -34,6 +35,7 @@ class IRCTransport:
34
35
  self.on_mention = on_mention
35
36
  self.tags = tags or []
36
37
  self.on_roominvite = on_roominvite
38
+ self.icon = icon
37
39
  self.connected = False
38
40
  self._reader: asyncio.StreamReader | None = None
39
41
  self._writer: asyncio.StreamWriter | None = None
@@ -174,6 +176,8 @@ class IRCTransport:
174
176
  if self.tags:
175
177
  tags_str = ",".join(self.tags)
176
178
  await self._send_raw(f"TAGS {self.nick} {tags_str}")
179
+ if self.icon:
180
+ await self._send_raw(f"ICON {self.icon}")
177
181
 
178
182
  async def _on_privmsg(self, msg: Message) -> None:
179
183
  if len(msg.params) < 2:
@@ -57,6 +57,7 @@ class AgentConfig:
57
57
  model: str = "gpt-4.1"
58
58
  system_prompt: str = ""
59
59
  tags: list[str] = field(default_factory=list)
60
+ icon: str | None = None
60
61
 
61
62
 
62
63
  @dataclass
@@ -24,6 +24,7 @@ class IRCTransport:
24
24
  on_mention: Callable[[str, str, str], None] | None = None,
25
25
  tags: list[str] | None = None,
26
26
  on_roominvite: Callable[[str, str], None] | None = None,
27
+ icon: str | None = None,
27
28
  ):
28
29
  self.host = host
29
30
  self.port = port
@@ -34,6 +35,7 @@ class IRCTransport:
34
35
  self.on_mention = on_mention
35
36
  self.tags = tags or []
36
37
  self.on_roominvite = on_roominvite
38
+ self.icon = icon
37
39
  self.connected = False
38
40
  self._reader: asyncio.StreamReader | None = None
39
41
  self._writer: asyncio.StreamWriter | None = None
@@ -174,6 +176,8 @@ class IRCTransport:
174
176
  if self.tags:
175
177
  tags_str = ",".join(self.tags)
176
178
  await self._send_raw(f"TAGS {self.nick} {tags_str}")
179
+ if self.icon:
180
+ await self._send_raw(f"ICON {self.icon}")
177
181
 
178
182
  async def _on_privmsg(self, msg: Message) -> None:
179
183
  if len(msg.params) < 2:
@@ -0,0 +1 @@
1
+ """Console TUI for culture mesh administration."""