agentirc-cli 4.1.2__tar.gz → 4.2.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 (310) hide show
  1. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/CHANGELOG.md +18 -0
  2. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/Gemfile +1 -0
  3. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/Gemfile.lock +4 -0
  4. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/PKG-INFO +1 -1
  5. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/_config.yml +1 -0
  6. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/bots/bot_manager.py +3 -0
  7. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/bots/config.py +18 -6
  8. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/_helpers.py +12 -3
  9. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/agent.py +101 -8
  10. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/bot.py +79 -2
  11. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/mesh.py +64 -11
  12. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/server.py +173 -1
  13. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/config.py +102 -0
  14. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/mesh_config.py +10 -0
  15. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/cli.md +66 -2
  16. agentirc_cli-4.2.0/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +253 -0
  17. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/pyproject.toml +1 -1
  18. agentirc_cli-4.2.0/tests/test_archive.py +436 -0
  19. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_mesh_config.py +37 -0
  20. agentirc_cli-4.2.0/tests/test_setup_update_cli.py +185 -0
  21. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/uv.lock +1 -1
  22. agentirc_cli-4.1.2/tests/test_setup_update_cli.py +0 -45
  23. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.claude/skills/pr-review/SKILL.md +0 -0
  24. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.claude/skills/run-tests/SKILL.md +0 -0
  25. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
  26. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.flake8 +0 -0
  27. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.github/workflows/pages.yml +0 -0
  28. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.github/workflows/publish.yml +0 -0
  29. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.github/workflows/security-checks.yml +0 -0
  30. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.github/workflows/tests.yml +0 -0
  31. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.gitignore +0 -0
  32. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.markdownlint-cli2.yaml +0 -0
  33. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.pr_agent.toml +0 -0
  34. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.pre-commit-config.yaml +0 -0
  35. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/.pylintrc +0 -0
  36. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/CLAUDE.md +0 -0
  37. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/CNAME +0 -0
  38. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/LICENSE +0 -0
  39. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/README.md +0 -0
  40. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/SECURITY.md +0 -0
  41. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/_sass/color_schemes/anthropic.scss +0 -0
  42. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/_sass/custom/custom.scss +0 -0
  43. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/__init__.py +0 -0
  44. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/__main__.py +0 -0
  45. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/bots/__init__.py +0 -0
  46. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/bots/bot.py +0 -0
  47. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/bots/http_listener.py +0 -0
  48. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/bots/template_engine.py +0 -0
  49. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/bots/virtual_client.py +0 -0
  50. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/__init__.py +0 -0
  51. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/channel.py +0 -0
  52. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/cli/skills.py +0 -0
  53. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/__init__.py +0 -0
  54. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/__init__.py +0 -0
  55. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/agent_runner.py +0 -0
  56. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/config.py +0 -0
  57. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/daemon.py +0 -0
  58. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/ipc.py +0 -0
  59. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/irc_transport.py +0 -0
  60. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/message_buffer.py +0 -0
  61. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/skill/SKILL.md +0 -0
  62. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/skill/__init__.py +0 -0
  63. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/skill/irc_client.py +0 -0
  64. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/socket_server.py +0 -0
  65. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/supervisor.py +0 -0
  66. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/acp/webhook.py +0 -0
  67. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/__init__.py +0 -0
  68. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/__main__.py +0 -0
  69. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/agent_runner.py +0 -0
  70. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/daemon.py +0 -0
  71. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/ipc.py +0 -0
  72. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/irc_transport.py +0 -0
  73. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/message_buffer.py +0 -0
  74. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/skill/SKILL.md +0 -0
  75. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/skill/__init__.py +0 -0
  76. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/skill/irc_client.py +0 -0
  77. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/socket_server.py +0 -0
  78. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/supervisor.py +0 -0
  79. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/claude/webhook.py +0 -0
  80. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/__init__.py +0 -0
  81. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/agent_runner.py +0 -0
  82. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/config.py +0 -0
  83. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/daemon.py +0 -0
  84. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/ipc.py +0 -0
  85. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/irc_transport.py +0 -0
  86. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/message_buffer.py +0 -0
  87. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/skill/SKILL.md +0 -0
  88. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/skill/__init__.py +0 -0
  89. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/skill/irc_client.py +0 -0
  90. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/socket_server.py +0 -0
  91. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/supervisor.py +0 -0
  92. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/codex/webhook.py +0 -0
  93. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/__init__.py +0 -0
  94. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/agent_runner.py +0 -0
  95. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/config.py +0 -0
  96. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/daemon.py +0 -0
  97. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/ipc.py +0 -0
  98. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/irc_transport.py +0 -0
  99. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/message_buffer.py +0 -0
  100. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/skill/SKILL.md +0 -0
  101. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/skill/__init__.py +0 -0
  102. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/skill/irc_client.py +0 -0
  103. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/socket_server.py +0 -0
  104. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/supervisor.py +0 -0
  105. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/clients/copilot/webhook.py +0 -0
  106. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/__init__.py +0 -0
  107. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/app.py +0 -0
  108. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/client.py +0 -0
  109. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/commands.py +0 -0
  110. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/widgets/__init__.py +0 -0
  111. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/widgets/chat.py +0 -0
  112. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/widgets/info_panel.py +0 -0
  113. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/console/widgets/sidebar.py +0 -0
  114. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/credentials.py +0 -0
  115. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/learn_prompt.py +0 -0
  116. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/observer.py +0 -0
  117. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/overview/__init__.py +0 -0
  118. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/overview/collector.py +0 -0
  119. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/overview/model.py +0 -0
  120. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/overview/renderer_text.py +0 -0
  121. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/overview/renderer_web.py +0 -0
  122. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/overview/web/style.css +0 -0
  123. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/persistence.py +0 -0
  124. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/pidfile.py +0 -0
  125. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/__init__.py +0 -0
  126. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/commands.py +0 -0
  127. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/extensions/federation.md +0 -0
  128. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/extensions/history.md +0 -0
  129. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/extensions/icons.md +0 -0
  130. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/extensions/rooms.md +0 -0
  131. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/extensions/tags.md +0 -0
  132. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/extensions/threads.md +0 -0
  133. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/message.py +0 -0
  134. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/protocol-index.md +0 -0
  135. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/protocol/replies.py +0 -0
  136. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/__init__.py +0 -0
  137. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/__main__.py +0 -0
  138. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/channel.py +0 -0
  139. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/client.py +0 -0
  140. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/config.py +0 -0
  141. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/ircd.py +0 -0
  142. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/remote_client.py +0 -0
  143. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/room_store.py +0 -0
  144. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/rooms_util.py +0 -0
  145. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/server_link.py +0 -0
  146. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/skill.py +0 -0
  147. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/skills/__init__.py +0 -0
  148. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/skills/history.py +0 -0
  149. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/skills/icon.py +0 -0
  150. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/skills/rooms.py +0 -0
  151. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/skills/threads.py +0 -0
  152. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/server/thread_store.py +0 -0
  153. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/culture/skills/culture/SKILL.md +0 -0
  154. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/agent-lifecycle.md +0 -0
  155. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/agentic-self-learn.md +0 -0
  156. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/agent-client.md +0 -0
  157. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/agent-harness-spec.md +0 -0
  158. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/design.md +0 -0
  159. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/harness-conformance.md +0 -0
  160. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/index.md +0 -0
  161. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/layer1-core-irc.md +0 -0
  162. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/layer2-attention.md +0 -0
  163. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/layer3-skills.md +0 -0
  164. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/layer4-federation.md +0 -0
  165. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/layer5-agent-harness.md +0 -0
  166. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/server-architecture.md +0 -0
  167. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/architecture/threads.md +0 -0
  168. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/channel-polling.md +0 -0
  169. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/acp/overview.md +0 -0
  170. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/claude/configuration.md +0 -0
  171. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/claude/context-management.md +0 -0
  172. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/claude/irc-tools.md +0 -0
  173. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/claude/overview.md +0 -0
  174. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/claude/setup.md +0 -0
  175. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/claude/supervisor.md +0 -0
  176. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/claude/webhooks.md +0 -0
  177. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/codex/configuration.md +0 -0
  178. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/codex/context-management.md +0 -0
  179. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/codex/irc-tools.md +0 -0
  180. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/codex/overview.md +0 -0
  181. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/codex/setup.md +0 -0
  182. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/codex/supervisor.md +0 -0
  183. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/codex/webhooks.md +0 -0
  184. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/copilot/configuration.md +0 -0
  185. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/copilot/context-management.md +0 -0
  186. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/copilot/irc-tools.md +0 -0
  187. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/copilot/overview.md +0 -0
  188. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/copilot/setup.md +0 -0
  189. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/copilot/supervisor.md +0 -0
  190. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/clients/copilot/webhooks.md +0 -0
  191. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/culture-cli.md +0 -0
  192. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/getting-started.md +0 -0
  193. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/index.md +0 -0
  194. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/SECURITY.md +0 -0
  195. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/bots.md +0 -0
  196. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/ci.md +0 -0
  197. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/docs-site.md +0 -0
  198. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/index.md +0 -0
  199. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/ops-tooling.md +0 -0
  200. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/overview.md +0 -0
  201. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/operations/publishing.md +0 -0
  202. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  203. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/rooms.md +0 -0
  204. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/server-rename.md +0 -0
  205. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  206. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  207. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  208. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  209. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
  210. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
  211. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
  212. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -0
  213. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/plans/2026-04-06-console-chat.md +0 -0
  214. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  215. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  216. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  217. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  218. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
  219. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
  220. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
  221. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
  222. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -0
  223. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -0
  224. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -0
  225. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -0
  226. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/01-pair-programming.md +0 -0
  227. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/02-code-review-ensemble.md +0 -0
  228. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/03-cross-server-delegation.md +0 -0
  229. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/04-knowledge-propagation.md +0 -0
  230. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/05-the-observer.md +0 -0
  231. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/06-cross-server-ops.md +0 -0
  232. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/07-supervisor-intervention.md +0 -0
  233. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/08-apps-as-agents.md +0 -0
  234. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/09-research-swarm.md +0 -0
  235. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases/10-agent-lifecycle.md +0 -0
  236. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/use-cases-index.md +0 -0
  237. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/docs/what-is-culture.md +0 -0
  238. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/README.md +0 -0
  239. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/config.py +0 -0
  240. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/daemon.py +0 -0
  241. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/ipc.py +0 -0
  242. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/irc_transport.py +0 -0
  243. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/message_buffer.py +0 -0
  244. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/skill/SKILL.md +0 -0
  245. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/skill/irc_client.py +0 -0
  246. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/socket_server.py +0 -0
  247. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/packages/agent-harness/webhook.py +0 -0
  248. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  249. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/plugins/claude-code/skills/culture/SKILL.md +0 -0
  250. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  251. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
  252. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/sonar-project.properties +0 -0
  253. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/__init__.py +0 -0
  254. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/conftest.py +0 -0
  255. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_acp_daemon.py +0 -0
  256. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_agent_runner.py +0 -0
  257. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_bot.py +0 -0
  258. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_bot_config.py +0 -0
  259. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_bot_manager.py +0 -0
  260. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_bots_integration.py +0 -0
  261. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_channel.py +0 -0
  262. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_codex_daemon.py +0 -0
  263. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_connection.py +0 -0
  264. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_console_client.py +0 -0
  265. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_console_commands.py +0 -0
  266. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_console_connection.py +0 -0
  267. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_console_icons.py +0 -0
  268. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_console_integration.py +0 -0
  269. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_copilot_daemon.py +0 -0
  270. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_daemon.py +0 -0
  271. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_daemon_config.py +0 -0
  272. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_daemon_ipc.py +0 -0
  273. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_discovery.py +0 -0
  274. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_federation.py +0 -0
  275. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_history.py +0 -0
  276. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_http_listener.py +0 -0
  277. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_integration_layer5.py +0 -0
  278. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_ipc.py +0 -0
  279. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_irc_transport.py +0 -0
  280. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_link_reconnect.py +0 -0
  281. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_mention_alias.py +0 -0
  282. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_mention_target_cleanup.py +0 -0
  283. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_mentions.py +0 -0
  284. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_message.py +0 -0
  285. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_message_buffer.py +0 -0
  286. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_messaging.py +0 -0
  287. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_modes.py +0 -0
  288. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_overview_cli.py +0 -0
  289. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_overview_collector.py +0 -0
  290. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_overview_model.py +0 -0
  291. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_overview_renderer.py +0 -0
  292. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_overview_web.py +0 -0
  293. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_persistence.py +0 -0
  294. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_pidfile.py +0 -0
  295. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_poll_loop.py +0 -0
  296. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_room_persistence.py +0 -0
  297. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_rooms.py +0 -0
  298. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_rooms_federation.py +0 -0
  299. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_rooms_integration.py +0 -0
  300. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_server_icon_skill.py +0 -0
  301. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_skill_client.py +0 -0
  302. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_skills.py +0 -0
  303. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_socket_server.py +0 -0
  304. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_supervisor.py +0 -0
  305. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_template_engine.py +0 -0
  306. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_thread_buffer.py +0 -0
  307. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_threads.py +0 -0
  308. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_virtual_client.py +0 -0
  309. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_wait_for_port.py +0 -0
  310. {agentirc_cli-4.1.2 → agentirc_cli-4.2.0}/tests/test_webhook.py +0 -0
@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/).
6
6
 
7
+ ## [4.2.0] - 2026-04-07
8
+
9
+
10
+ ### Added
11
+
12
+ - Archive and unarchive commands for servers, agents, and bots
13
+ - Cascade archive: server archive automatically archives all agents and bots
14
+ - Visibility filtering: archived entities hidden from default status/list views
15
+ - --all flag on status/list to reveal archived entities
16
+ - Start guard: archived entities cannot be started until unarchived
17
+
18
+ ## [4.1.3] - 2026-04-06
19
+
20
+
21
+ ### Fixed
22
+
23
+ - mesh update now discovers and restarts all running servers instead of only the one in mesh.yaml
24
+
7
25
  ## [4.1.2] - 2026-04-06
8
26
 
9
27
 
@@ -4,3 +4,4 @@ gem "jekyll", "~> 4.3"
4
4
  gem "just-the-docs", "~> 0.10"
5
5
  gem "jekyll-seo-tag"
6
6
  gem "jekyll-relative-links"
7
+ gem "jekyll-sitemap"
@@ -81,6 +81,8 @@ GEM
81
81
  sass-embedded (~> 1.75)
82
82
  jekyll-seo-tag (2.8.0)
83
83
  jekyll (>= 3.8, < 5.0)
84
+ jekyll-sitemap (1.4.0)
85
+ jekyll (>= 3.7, < 5.0)
84
86
  jekyll-watch (2.2.1)
85
87
  listen (~> 3.0)
86
88
  json (2.19.2)
@@ -171,6 +173,7 @@ DEPENDENCIES
171
173
  jekyll (~> 4.3)
172
174
  jekyll-relative-links
173
175
  jekyll-seo-tag
176
+ jekyll-sitemap
174
177
  just-the-docs (~> 0.10)
175
178
 
176
179
  CHECKSUMS
@@ -210,6 +213,7 @@ CHECKSUMS
210
213
  jekyll-relative-links (0.7.0) sha256=831e54c348eeae751845c0d4ac4b244bd73b664341f0e8c9f1803b16f4570835
211
214
  jekyll-sass-converter (3.1.0) sha256=83925d84f1d134410c11d0c6643b0093e82e3a3cf127e90757a85294a3862443
212
215
  jekyll-seo-tag (2.8.0) sha256=3f2ed1916d56f14ebfa38e24acde9b7c946df70cb183af2cb5f0598f21ae6818
216
+ jekyll-sitemap (1.4.0) sha256=0de08c5debc185ea5a8f980e1025c7cd3f8e0c35c8b6ef592f15c46235cf4218
213
217
  jekyll-watch (2.2.1) sha256=bc44ed43f5e0a552836245a54dbff3ea7421ecc2856707e8a1ee203a8387a7e1
214
218
  json (2.19.2) sha256=e7e1bd318b2c37c4ceee2444841c86539bc462e81f40d134cf97826cb14e83cf
215
219
  just-the-docs (0.12.0) sha256=15f2839ac9082898d60f33b978aa6f8e46fc50ba8fac20ae7a7f0e1fb295523e
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 4.1.2
3
+ Version: 4.2.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
@@ -24,6 +24,7 @@ footer_content: >-
24
24
  plugins:
25
25
  - jekyll-seo-tag
26
26
  - jekyll-relative-links
27
+ - jekyll-sitemap
27
28
 
28
29
  relative_links:
29
30
  enabled: true
@@ -32,6 +32,9 @@ class BotManager:
32
32
  continue
33
33
  try:
34
34
  config = load_bot_config(yaml_path)
35
+ if config.archived:
36
+ logger.info("Skipping archived bot %s", config.name)
37
+ continue
35
38
  bot = Bot(config, self.server)
36
39
  self.bots[config.name] = bot
37
40
  await bot.start()
@@ -26,6 +26,9 @@ class BotConfig:
26
26
  mention: str | None = None
27
27
  template: str | None = None
28
28
  fallback: str = "json"
29
+ archived: bool = False
30
+ archived_at: str = ""
31
+ archived_reason: str = ""
29
32
 
30
33
  @property
31
34
  def has_handler(self) -> bool:
@@ -54,6 +57,9 @@ def load_bot_config(path: Path) -> BotConfig:
54
57
  mention=output_section.get("mention"),
55
58
  template=output_section.get("template"),
56
59
  fallback=output_section.get("fallback", "json"),
60
+ archived=bot_section.get("archived", False),
61
+ archived_at=bot_section.get("archived_at", ""),
62
+ archived_reason=bot_section.get("archived_reason", ""),
57
63
  )
58
64
 
59
65
 
@@ -61,13 +67,19 @@ def save_bot_config(path: Path, config: BotConfig) -> None:
61
67
  """Serialize a BotConfig to YAML and write atomically."""
62
68
  path.parent.mkdir(parents=True, exist_ok=True)
63
69
 
70
+ bot_section = {
71
+ "name": config.name,
72
+ "owner": config.owner,
73
+ "description": config.description,
74
+ "created": config.created,
75
+ }
76
+ if config.archived:
77
+ bot_section["archived"] = config.archived
78
+ bot_section["archived_at"] = config.archived_at
79
+ bot_section["archived_reason"] = config.archived_reason
80
+
64
81
  data = {
65
- "bot": {
66
- "name": config.name,
67
- "owner": config.owner,
68
- "description": config.description,
69
- "created": config.created,
70
- },
82
+ "bot": bot_section,
71
83
  "trigger": {
72
84
  "type": config.trigger_type,
73
85
  },
@@ -381,7 +381,9 @@ def print_agent_detail(agent, config_path: str, args: argparse.Namespace) -> Non
381
381
  print(f" Config: {config_path}")
382
382
 
383
383
 
384
- def print_agents_overview(agents: list, show_activity: bool) -> None:
384
+ def print_agents_overview(
385
+ agents: list, show_activity: bool, show_archived_marker: bool = False
386
+ ) -> None:
385
387
  """Print a table of all agents with status, PID, and optionally activity."""
386
388
  if show_activity:
387
389
  print(f"{'NICK':<30} {'STATUS':<12} {'PID':<10} {'ACTIVITY'}")
@@ -391,10 +393,17 @@ def print_agents_overview(agents: list, show_activity: bool) -> None:
391
393
  print("-" * 52)
392
394
 
393
395
  for agent in agents:
394
- status, pid = agent_process_status(agent)
396
+ archived = getattr(agent, "archived", False)
397
+ base_status, pid = agent_process_status(agent)
398
+ status = base_status
399
+ if archived:
400
+ if show_archived_marker:
401
+ status = f"{base_status} (archived)"
402
+ elif base_status == "stopped":
403
+ status = "archived"
395
404
  activity = "-"
396
405
 
397
- if show_activity and status == "running":
406
+ if show_activity and base_status == "running":
398
407
  resp = asyncio.run(ipc_request(agent_socket_path(agent.nick), "status"))
399
408
  if resp and resp.get("ok"):
400
409
  activity = resp.get("data", {}).get("description", "nothing")
@@ -13,9 +13,11 @@ from culture.clients.claude.config import (
13
13
  AgentConfig,
14
14
  DaemonConfig,
15
15
  add_agent_to_config,
16
+ archive_agent,
16
17
  load_config,
17
18
  load_config_or_default,
18
19
  sanitize_agent_name,
20
+ unarchive_agent,
19
21
  )
20
22
  from culture.pidfile import (
21
23
  is_process_alive,
@@ -99,6 +101,7 @@ def register(subparsers: argparse._SubParsersAction) -> None:
99
101
  status_parser.add_argument(
100
102
  "--full", action="store_true", help="Query agents for activity status"
101
103
  )
104
+ status_parser.add_argument("--all", action="store_true", help="Include archived agents")
102
105
  status_parser.add_argument("--config", default=DEFAULT_CONFIG, help=_CONFIG_HELP)
103
106
 
104
107
  # -- rename ---------------------------------------------------------------
@@ -144,11 +147,22 @@ def register(subparsers: argparse._SubParsersAction) -> None:
144
147
  read_parser.add_argument("--limit", "-n", type=int, default=50, help="Number of messages")
145
148
  read_parser.add_argument("--config", default=DEFAULT_CONFIG, help=_CONFIG_HELP)
146
149
 
150
+ # -- archive --------------------------------------------------------------
151
+ archive_parser = agent_sub.add_parser("archive", help="Archive an agent (stop and retire)")
152
+ archive_parser.add_argument("nick", help="Agent nick to archive")
153
+ archive_parser.add_argument("--reason", default="", help="Reason for archiving")
154
+ archive_parser.add_argument("--config", default=DEFAULT_CONFIG, help=_CONFIG_HELP)
155
+
156
+ # -- unarchive ------------------------------------------------------------
157
+ unarchive_parser = agent_sub.add_parser("unarchive", help="Restore an archived agent")
158
+ unarchive_parser.add_argument("nick", help="Agent nick to unarchive")
159
+ unarchive_parser.add_argument("--config", default=DEFAULT_CONFIG, help=_CONFIG_HELP)
160
+
147
161
 
148
162
  def dispatch(args: argparse.Namespace) -> None:
149
163
  if not args.agent_command:
150
164
  print(
151
- "Usage: culture agent {create|join|start|stop|status|rename|assign|sleep|wake|learn|message|read}",
165
+ "Usage: culture agent {create|join|start|stop|status|rename|assign|sleep|wake|learn|message|read|archive|unarchive}",
152
166
  file=sys.stderr,
153
167
  )
154
168
  sys.exit(1)
@@ -166,6 +180,8 @@ def dispatch(args: argparse.Namespace) -> None:
166
180
  "learn": _cmd_learn,
167
181
  "message": _cmd_message,
168
182
  "read": _cmd_read,
183
+ "archive": _cmd_archive,
184
+ "unarchive": _cmd_unarchive,
169
185
  }
170
186
  handler = handlers.get(args.agent_command)
171
187
  if handler:
@@ -291,25 +307,42 @@ def _cmd_join(args: argparse.Namespace) -> None:
291
307
  def _resolve_agents_to_start(config, args) -> list:
292
308
  """Return the list of agents to start, or exit with an error message."""
293
309
  if args.all:
294
- agents = config.agents
310
+ # Skip archived agents when starting --all
311
+ agents = [a for a in config.agents if not a.archived]
295
312
  elif args.nick:
296
313
  agent = config.get_agent(args.nick)
297
314
  if not agent:
298
315
  print(f"Agent '{args.nick}' not found in config", file=sys.stderr)
299
316
  sys.exit(1)
317
+ if agent.archived:
318
+ print(
319
+ f"Agent '{args.nick}' is archived. Unarchive first:",
320
+ file=sys.stderr,
321
+ )
322
+ print(f" culture agent unarchive {args.nick}", file=sys.stderr)
323
+ sys.exit(1)
300
324
  agents = [agent]
301
325
  else:
302
- if len(config.agents) == 1:
303
- agents = config.agents
304
- elif len(config.agents) == 0:
305
- print("No agents configured. Run 'culture agent create' first.", file=sys.stderr)
326
+ active = [a for a in config.agents if not a.archived]
327
+ if len(active) == 1:
328
+ agents = active
329
+ elif len(active) == 0:
330
+ archived_count = sum(1 for a in config.agents if a.archived)
331
+ if archived_count:
332
+ print(
333
+ f"No active agents ({archived_count} archived). "
334
+ "Unarchive an agent or create a new one.",
335
+ file=sys.stderr,
336
+ )
337
+ else:
338
+ print("No agents configured. Run 'culture agent create' first.", file=sys.stderr)
306
339
  sys.exit(1)
307
340
  else:
308
341
  print(
309
342
  "Multiple agents configured. Specify a nick or use --all.",
310
343
  file=sys.stderr,
311
344
  )
312
- for a in config.agents:
345
+ for a in active:
313
346
  print(f" {a.nick}", file=sys.stderr)
314
347
  sys.exit(1)
315
348
 
@@ -527,9 +560,27 @@ def _cmd_status(args: argparse.Namespace) -> None:
527
560
  sys.exit(1)
528
561
 
529
562
  print_agent_detail(agent, args.config, args)
563
+ if agent.archived:
564
+ print(f"\n [archived since {agent.archived_at}]")
565
+ if agent.archived_reason:
566
+ print(f" Reason: {agent.archived_reason}")
567
+ return
568
+
569
+ show_all = getattr(args, "all", False)
570
+ if show_all:
571
+ agents = config.agents
572
+ else:
573
+ agents = [a for a in config.agents if not a.archived]
574
+
575
+ if not agents and not show_all:
576
+ archived_count = sum(1 for a in config.agents if a.archived)
577
+ if archived_count:
578
+ print(f"No active agents ({archived_count} archived, use --all to show)")
579
+ else:
580
+ print("No agents configured")
530
581
  return
531
582
 
532
- print_agents_overview(config.agents, args.full)
583
+ print_agents_overview(agents, args.full, show_archived_marker=show_all)
533
584
  print_bot_listing()
534
585
 
535
586
 
@@ -738,3 +789,45 @@ def _cmd_read(args: argparse.Namespace) -> None:
738
789
  )
739
790
  print("Use 'culture channel read <channel>' for channel history.", file=sys.stderr)
740
791
  sys.exit(1)
792
+
793
+
794
+ # -----------------------------------------------------------------------
795
+ # Archive / Unarchive
796
+ # -----------------------------------------------------------------------
797
+
798
+
799
+ def _cmd_archive(args: argparse.Namespace) -> None:
800
+ """Archive an agent: stop if running, set archived flag."""
801
+ config = load_config_or_default(args.config)
802
+ agent = config.get_agent(args.nick)
803
+ if not agent:
804
+ print(f"Agent '{args.nick}' not found in config", file=sys.stderr)
805
+ sys.exit(1)
806
+
807
+ if agent.archived:
808
+ print(f"Agent '{args.nick}' is already archived")
809
+ return
810
+
811
+ # Stop the agent if it's running
812
+ pid = read_pid(f"agent-{args.nick}")
813
+ if pid and is_process_alive(pid):
814
+ stop_agent(args.nick)
815
+
816
+ archive_agent(args.config, args.nick, reason=args.reason)
817
+
818
+ print(f"Agent archived: {args.nick}")
819
+ if args.reason:
820
+ print(f" Reason: {args.reason}")
821
+ print(f"\nTo restore: culture agent unarchive {args.nick}")
822
+
823
+
824
+ def _cmd_unarchive(args: argparse.Namespace) -> None:
825
+ """Restore an archived agent."""
826
+ try:
827
+ unarchive_agent(args.config, args.nick)
828
+ except ValueError as exc:
829
+ print(str(exc), file=sys.stderr)
830
+ sys.exit(1)
831
+
832
+ print(f"Agent unarchived: {args.nick}")
833
+ print(f"\nStart with: culture agent start {args.nick}")
@@ -40,15 +40,26 @@ def register(subparsers: argparse._SubParsersAction) -> None:
40
40
 
41
41
  bot_list = bot_sub.add_parser("list", help="List bots")
42
42
  bot_list.add_argument("owner", nargs="?", default=None, help="Filter by owner nick")
43
+ bot_list.add_argument("--all", action="store_true", help="Include archived bots")
43
44
 
44
45
  bot_inspect = bot_sub.add_parser("inspect", help="Show bot details")
45
46
  bot_inspect.add_argument("name", help="Bot name")
46
47
  bot_inspect.add_argument("--config", default=DEFAULT_CONFIG, help=_CONFIG_HELP)
47
48
 
49
+ bot_archive = bot_sub.add_parser("archive", help="Archive a bot")
50
+ bot_archive.add_argument("name", help="Bot name to archive")
51
+ bot_archive.add_argument("--reason", default="", help="Reason for archiving")
52
+
53
+ bot_unarchive = bot_sub.add_parser("unarchive", help="Restore an archived bot")
54
+ bot_unarchive.add_argument("name", help="Bot name to unarchive")
55
+
48
56
 
49
57
  def dispatch(args: argparse.Namespace) -> None:
50
58
  if not args.bot_command:
51
- print("Usage: culture bot {create|start|stop|list|inspect}", file=sys.stderr)
59
+ print(
60
+ "Usage: culture bot {create|start|stop|list|inspect|archive|unarchive}",
61
+ file=sys.stderr,
62
+ )
52
63
  sys.exit(1)
53
64
 
54
65
  handlers = {
@@ -57,6 +68,8 @@ def dispatch(args: argparse.Namespace) -> None:
57
68
  "stop": _bot_stop,
58
69
  "list": _bot_list,
59
70
  "inspect": _bot_inspect,
71
+ "archive": _bot_archive,
72
+ "unarchive": _bot_unarchive,
60
73
  }
61
74
  handler = handlers.get(args.bot_command)
62
75
  if handler:
@@ -146,6 +159,7 @@ def _bot_list(args: argparse.Namespace) -> None:
146
159
  print("No bots configured.")
147
160
  return
148
161
 
162
+ show_all = getattr(args, "all", False)
149
163
  bots = []
150
164
  for bot_dir in sorted(BOTS_DIR.iterdir()):
151
165
  yaml_path = bot_dir / "bot.yaml"
@@ -155,6 +169,8 @@ def _bot_list(args: argparse.Namespace) -> None:
155
169
  config = load_bot_config(yaml_path)
156
170
  if args.owner and config.owner != args.owner:
157
171
  continue
172
+ if not show_all and config.archived:
173
+ continue
158
174
  bots.append(config)
159
175
  except Exception:
160
176
  continue
@@ -169,7 +185,10 @@ def _bot_list(args: argparse.Namespace) -> None:
169
185
  print(f"{'NAME':<35} {'TRIGGER':<10} {'CHANNELS':<20} {'OWNER':<20}")
170
186
  for config in bots:
171
187
  channels = ", ".join(config.channels) if config.channels else "-"
172
- print(f"{config.name:<35} {config.trigger_type:<10} {channels:<20} {config.owner:<20}")
188
+ name = config.name
189
+ if show_all and config.archived:
190
+ name = f"{name} [archived]"
191
+ print(f"{name:<35} {config.trigger_type:<10} {channels:<20} {config.owner:<20}")
173
192
 
174
193
 
175
194
  def _bot_inspect(args: argparse.Namespace) -> None:
@@ -201,3 +220,61 @@ def _bot_inspect(args: argparse.Namespace) -> None:
201
220
  first_line = first_line[:57] + "..."
202
221
  print(f"Template: {first_line}")
203
222
  print(f"Handler: {'custom (handler.py)' if config.has_handler else 'template'}")
223
+ if config.archived:
224
+ print(f"Archived: yes (since {config.archived_at})")
225
+ if config.archived_reason:
226
+ print(f"Reason: {config.archived_reason}")
227
+
228
+
229
+ # -----------------------------------------------------------------------
230
+ # Archive / Unarchive
231
+ # -----------------------------------------------------------------------
232
+
233
+
234
+ def _bot_archive(args: argparse.Namespace) -> None:
235
+ import time as _time
236
+
237
+ from culture.bots.config import BOTS_DIR, load_bot_config, save_bot_config
238
+
239
+ bot_dir = BOTS_DIR / args.name
240
+ yaml_path = bot_dir / "bot.yaml"
241
+ if not yaml_path.is_file():
242
+ print(f"Bot '{args.name}' not found at {bot_dir}", file=sys.stderr)
243
+ sys.exit(1)
244
+
245
+ config = load_bot_config(yaml_path)
246
+ if config.archived:
247
+ print(f"Bot '{args.name}' is already archived")
248
+ return
249
+
250
+ config.archived = True
251
+ config.archived_at = _time.strftime("%Y-%m-%d")
252
+ config.archived_reason = args.reason
253
+ save_bot_config(yaml_path, config)
254
+
255
+ print(f"Bot archived: {args.name}")
256
+ if args.reason:
257
+ print(f" Reason: {args.reason}")
258
+ print(f"\nTo restore: culture bot unarchive {args.name}")
259
+
260
+
261
+ def _bot_unarchive(args: argparse.Namespace) -> None:
262
+ from culture.bots.config import BOTS_DIR, load_bot_config, save_bot_config
263
+
264
+ bot_dir = BOTS_DIR / args.name
265
+ yaml_path = bot_dir / "bot.yaml"
266
+ if not yaml_path.is_file():
267
+ print(f"Bot '{args.name}' not found at {bot_dir}", file=sys.stderr)
268
+ sys.exit(1)
269
+
270
+ config = load_bot_config(yaml_path)
271
+ if not config.archived:
272
+ print(f"Bot '{args.name}' is not archived", file=sys.stderr)
273
+ sys.exit(1)
274
+
275
+ config.archived = False
276
+ config.archived_at = ""
277
+ config.archived_reason = ""
278
+ save_bot_config(yaml_path, config)
279
+
280
+ print(f"Bot unarchived: {args.name}")
@@ -549,23 +549,76 @@ def _restart_mesh_services(
549
549
  check=False,
550
550
  )
551
551
 
552
- print("\nUpdate complete. All services restarted.")
553
-
554
-
555
- def _cmd_update(args: argparse.Namespace) -> None:
556
- from culture.mesh_config import load_mesh_config
552
+ print()
553
+
554
+
555
+ def _resolve_mesh_for_server(server_name: str, config_path: str):
556
+ """Find or build a MeshConfig for *server_name*.
557
+
558
+ Resolution order:
559
+ 1. mesh.yaml — use directly if its server.name matches.
560
+ 2. agents.yaml — build via from_daemon_config(), preserving host, port,
561
+ and links from the old mesh.yaml. Saves the updated mesh.yaml so
562
+ future runs are consistent.
563
+ """
564
+ from culture.mesh_config import (
565
+ from_daemon_config,
566
+ load_mesh_config,
567
+ merge_links,
568
+ save_mesh_config,
569
+ )
557
570
 
571
+ old_server = None
558
572
  try:
559
- mesh = load_mesh_config(args.config)
573
+ old_mesh = load_mesh_config(config_path)
574
+ if old_mesh.server.name == server_name:
575
+ return old_mesh
576
+ old_server = old_mesh.server
560
577
  except FileNotFoundError:
561
- mesh = generate_mesh_from_agents(args.config)
562
- if mesh is None:
563
- sys.exit(1)
578
+ pass
579
+
580
+ if os.path.isfile(DEFAULT_CONFIG):
581
+ daemon_config = load_config(DEFAULT_CONFIG)
582
+ if daemon_config.server.name == server_name:
583
+ mesh = from_daemon_config(daemon_config)
584
+ if old_server is not None:
585
+ mesh.server.host = old_server.host
586
+ mesh.server.port = old_server.port
587
+ merge_links(mesh, old_server.links)
588
+ save_mesh_config(mesh, config_path)
589
+ return mesh
590
+
591
+ return None
564
592
 
565
- server_name = mesh.server.name
593
+
594
+ def _cmd_update(args: argparse.Namespace) -> None:
595
+ from culture.mesh_config import load_mesh_config
596
+ from culture.pidfile import list_servers
566
597
 
567
598
  if not _upgrade_culture_package(args):
568
599
  return
569
600
 
570
601
  culture_bin = shutil.which("culture") or "culture"
571
- _restart_mesh_services(mesh, server_name, culture_bin, args.config, args.dry_run)
602
+
603
+ running = list_servers()
604
+
605
+ if running:
606
+ for srv in running:
607
+ mesh = _resolve_mesh_for_server(srv["name"], args.config)
608
+ if mesh is None:
609
+ print(
610
+ f" Warning: no config found for server '{srv['name']}', skipping",
611
+ file=sys.stderr,
612
+ )
613
+ continue
614
+ _restart_mesh_services(mesh, srv["name"], culture_bin, args.config, args.dry_run)
615
+ else:
616
+ try:
617
+ mesh = load_mesh_config(args.config)
618
+ except FileNotFoundError:
619
+ mesh = generate_mesh_from_agents(args.config)
620
+ if mesh is None:
621
+ sys.exit(1)
622
+ _restart_mesh_services(mesh, mesh.server.name, culture_bin, args.config, args.dry_run)
623
+
624
+ print("Update complete. All services restarted.")