agentirc-cli 1.0.6__tar.gz → 1.0.7__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 (270) hide show
  1. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/CHANGELOG.md +8 -0
  2. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/PKG-INFO +1 -1
  3. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/cli.py +29 -2
  4. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/pidfile.py +21 -0
  5. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/pyproject.toml +1 -1
  6. agentirc_cli-1.0.7/tests/test_pidfile.py +122 -0
  7. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/uv.lock +1 -1
  8. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.claude/skills/pr-review/SKILL.md +0 -0
  9. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.claude/skills/run-tests/SKILL.md +0 -0
  10. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.claude/skills/run-tests/scripts/test.sh +0 -0
  11. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.flake8 +0 -0
  12. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.github/workflows/pages.yml +0 -0
  13. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.github/workflows/publish.yml +0 -0
  14. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.github/workflows/security-checks.yml +0 -0
  15. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.github/workflows/tests.yml +0 -0
  16. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.gitignore +0 -0
  17. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.markdownlint-cli2.yaml +0 -0
  18. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.pr_agent.toml +0 -0
  19. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.pre-commit-config.yaml +0 -0
  20. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/.pylintrc +0 -0
  21. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/CLAUDE.md +0 -0
  22. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/CNAME +0 -0
  23. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/Gemfile +0 -0
  24. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/Gemfile.lock +0 -0
  25. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/LICENSE +0 -0
  26. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/README.md +0 -0
  27. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/SECURITY.md +0 -0
  28. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/_config.yml +0 -0
  29. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/_sass/color_schemes/anthropic.scss +0 -0
  30. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/_sass/custom/custom.scss +0 -0
  31. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/__init__.py +0 -0
  32. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/__main__.py +0 -0
  33. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/bots/__init__.py +0 -0
  34. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/bots/bot.py +0 -0
  35. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/bots/bot_manager.py +0 -0
  36. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/bots/config.py +0 -0
  37. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/bots/http_listener.py +0 -0
  38. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/bots/template_engine.py +0 -0
  39. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/bots/virtual_client.py +0 -0
  40. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/__init__.py +0 -0
  41. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/__init__.py +0 -0
  42. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/agent_runner.py +0 -0
  43. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/config.py +0 -0
  44. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/daemon.py +0 -0
  45. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/ipc.py +0 -0
  46. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/irc_transport.py +0 -0
  47. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/message_buffer.py +0 -0
  48. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/skill/SKILL.md +0 -0
  49. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/skill/__init__.py +0 -0
  50. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/skill/irc_client.py +0 -0
  51. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/socket_server.py +0 -0
  52. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/supervisor.py +0 -0
  53. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/acp/webhook.py +0 -0
  54. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/__init__.py +0 -0
  55. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/__main__.py +0 -0
  56. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/agent_runner.py +0 -0
  57. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/config.py +0 -0
  58. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/daemon.py +0 -0
  59. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/ipc.py +0 -0
  60. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/irc_transport.py +0 -0
  61. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/message_buffer.py +0 -0
  62. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/skill/SKILL.md +0 -0
  63. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/skill/__init__.py +0 -0
  64. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/skill/irc_client.py +0 -0
  65. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/socket_server.py +0 -0
  66. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/supervisor.py +0 -0
  67. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/claude/webhook.py +0 -0
  68. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/__init__.py +0 -0
  69. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/agent_runner.py +0 -0
  70. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/config.py +0 -0
  71. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/daemon.py +0 -0
  72. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/ipc.py +0 -0
  73. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/irc_transport.py +0 -0
  74. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/message_buffer.py +0 -0
  75. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/skill/SKILL.md +0 -0
  76. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/skill/__init__.py +0 -0
  77. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/skill/irc_client.py +0 -0
  78. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/socket_server.py +0 -0
  79. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/supervisor.py +0 -0
  80. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/codex/webhook.py +0 -0
  81. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/__init__.py +0 -0
  82. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/agent_runner.py +0 -0
  83. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/config.py +0 -0
  84. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/daemon.py +0 -0
  85. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/ipc.py +0 -0
  86. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/irc_transport.py +0 -0
  87. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/message_buffer.py +0 -0
  88. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/skill/SKILL.md +0 -0
  89. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/skill/__init__.py +0 -0
  90. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/skill/irc_client.py +0 -0
  91. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/socket_server.py +0 -0
  92. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/supervisor.py +0 -0
  93. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/clients/copilot/webhook.py +0 -0
  94. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/credentials.py +0 -0
  95. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/learn_prompt.py +0 -0
  96. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/mesh_config.py +0 -0
  97. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/observer.py +0 -0
  98. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/overview/__init__.py +0 -0
  99. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/overview/collector.py +0 -0
  100. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/overview/model.py +0 -0
  101. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/overview/renderer_text.py +0 -0
  102. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/overview/renderer_web.py +0 -0
  103. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/overview/web/style.css +0 -0
  104. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/persistence.py +0 -0
  105. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/__init__.py +0 -0
  106. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/commands.py +0 -0
  107. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/extensions/federation.md +0 -0
  108. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/extensions/history.md +0 -0
  109. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/extensions/rooms.md +0 -0
  110. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/extensions/tags.md +0 -0
  111. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/extensions/threads.md +0 -0
  112. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/message.py +0 -0
  113. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/protocol-index.md +0 -0
  114. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/protocol/replies.py +0 -0
  115. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/__init__.py +0 -0
  116. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/__main__.py +0 -0
  117. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/channel.py +0 -0
  118. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/client.py +0 -0
  119. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/config.py +0 -0
  120. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/ircd.py +0 -0
  121. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/remote_client.py +0 -0
  122. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/room_store.py +0 -0
  123. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/rooms_util.py +0 -0
  124. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/server_link.py +0 -0
  125. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/skill.py +0 -0
  126. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/skills/__init__.py +0 -0
  127. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/skills/history.py +0 -0
  128. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/skills/rooms.py +0 -0
  129. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/skills/threads.py +0 -0
  130. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/server/thread_store.py +0 -0
  131. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/culture/skills/culture/SKILL.md +0 -0
  132. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/SECURITY.md +0 -0
  133. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/agent-client.md +0 -0
  134. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/agent-harness-spec.md +0 -0
  135. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/agentic-self-learn.md +0 -0
  136. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/bots.md +0 -0
  137. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/ci.md +0 -0
  138. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/cli.md +0 -0
  139. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/acp/overview.md +0 -0
  140. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/claude/configuration.md +0 -0
  141. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/claude/context-management.md +0 -0
  142. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/claude/irc-tools.md +0 -0
  143. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/claude/overview.md +0 -0
  144. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/claude/setup.md +0 -0
  145. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/claude/supervisor.md +0 -0
  146. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/claude/webhooks.md +0 -0
  147. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/codex/configuration.md +0 -0
  148. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/codex/context-management.md +0 -0
  149. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/codex/irc-tools.md +0 -0
  150. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/codex/overview.md +0 -0
  151. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/codex/setup.md +0 -0
  152. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/codex/supervisor.md +0 -0
  153. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/codex/webhooks.md +0 -0
  154. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/copilot/configuration.md +0 -0
  155. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/copilot/context-management.md +0 -0
  156. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/copilot/irc-tools.md +0 -0
  157. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/copilot/overview.md +0 -0
  158. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/copilot/setup.md +0 -0
  159. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/copilot/supervisor.md +0 -0
  160. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/clients/copilot/webhooks.md +0 -0
  161. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/codex-backend.md +0 -0
  162. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/copilot-backend.md +0 -0
  163. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/design.md +0 -0
  164. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/docs-site.md +0 -0
  165. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/getting-started.md +0 -0
  166. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/grow-your-agent.md +0 -0
  167. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/harness-conformance.md +0 -0
  168. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/layer1-core-irc.md +0 -0
  169. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/layer2-attention.md +0 -0
  170. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/layer3-skills.md +0 -0
  171. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/layer4-federation.md +0 -0
  172. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/layer5-agent-harness.md +0 -0
  173. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/ops-tooling.md +0 -0
  174. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/overview.md +0 -0
  175. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/publishing.md +0 -0
  176. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/resources/github-copilot-sdk-instructions.md +0 -0
  177. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/rooms.md +0 -0
  178. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/server-architecture.md +0 -0
  179. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -0
  180. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -0
  181. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/plans/2026-03-30-overview.md +0 -0
  182. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -0
  183. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -0
  184. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -0
  185. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -0
  186. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -0
  187. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -0
  188. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-03-30-overview-design.md +0 -0
  189. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -0
  190. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -0
  191. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -0
  192. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -0
  193. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -0
  194. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/threads.md +0 -0
  195. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/01-pair-programming.md +0 -0
  196. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/02-code-review-ensemble.md +0 -0
  197. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/03-cross-server-delegation.md +0 -0
  198. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/04-knowledge-propagation.md +0 -0
  199. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/05-the-observer.md +0 -0
  200. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/06-cross-server-ops.md +0 -0
  201. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/07-supervisor-intervention.md +0 -0
  202. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/08-apps-as-agents.md +0 -0
  203. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/09-research-swarm.md +0 -0
  204. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases/10-grow-your-agent.md +0 -0
  205. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/docs/use-cases-index.md +0 -0
  206. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/index.md +0 -0
  207. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/README.md +0 -0
  208. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/config.py +0 -0
  209. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/daemon.py +0 -0
  210. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/ipc.py +0 -0
  211. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/irc_transport.py +0 -0
  212. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/message_buffer.py +0 -0
  213. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/skill/SKILL.md +0 -0
  214. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/skill/irc_client.py +0 -0
  215. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/socket_server.py +0 -0
  216. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/packages/agent-harness/webhook.py +0 -0
  217. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
  218. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/plugins/claude-code/skills/culture/SKILL.md +0 -0
  219. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/plugins/claude-code/skills/irc/SKILL.md +0 -0
  220. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/plugins/codex/skills/culture-irc/SKILL.md +0 -0
  221. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/sonar-project.properties +0 -0
  222. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/__init__.py +0 -0
  223. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/conftest.py +0 -0
  224. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_acp_daemon.py +0 -0
  225. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_agent_runner.py +0 -0
  226. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_bot.py +0 -0
  227. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_bot_config.py +0 -0
  228. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_bot_manager.py +0 -0
  229. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_bots_integration.py +0 -0
  230. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_channel.py +0 -0
  231. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_codex_daemon.py +0 -0
  232. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_connection.py +0 -0
  233. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_copilot_daemon.py +0 -0
  234. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_daemon.py +0 -0
  235. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_daemon_config.py +0 -0
  236. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_daemon_ipc.py +0 -0
  237. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_discovery.py +0 -0
  238. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_federation.py +0 -0
  239. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_history.py +0 -0
  240. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_http_listener.py +0 -0
  241. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_integration_layer5.py +0 -0
  242. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_ipc.py +0 -0
  243. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_irc_transport.py +0 -0
  244. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_link_reconnect.py +0 -0
  245. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_mentions.py +0 -0
  246. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_mesh_config.py +0 -0
  247. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_message.py +0 -0
  248. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_message_buffer.py +0 -0
  249. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_messaging.py +0 -0
  250. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_modes.py +0 -0
  251. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_overview_cli.py +0 -0
  252. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_overview_collector.py +0 -0
  253. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_overview_model.py +0 -0
  254. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_overview_renderer.py +0 -0
  255. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_overview_web.py +0 -0
  256. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_persistence.py +0 -0
  257. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_room_persistence.py +0 -0
  258. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_rooms.py +0 -0
  259. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_rooms_federation.py +0 -0
  260. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_rooms_integration.py +0 -0
  261. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_setup_update_cli.py +0 -0
  262. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_skill_client.py +0 -0
  263. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_skills.py +0 -0
  264. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_socket_server.py +0 -0
  265. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_supervisor.py +0 -0
  266. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_template_engine.py +0 -0
  267. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_thread_buffer.py +0 -0
  268. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_threads.py +0 -0
  269. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_virtual_client.py +0 -0
  270. {agentirc_cli-1.0.6 → agentirc_cli-1.0.7}/tests/test_webhook.py +0 -0
@@ -4,6 +4,14 @@ 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
+ ## [1.0.7] - 2026-04-05
8
+
9
+
10
+ ### Fixed
11
+
12
+ - Validate PID ownership via /proc/<pid>/cmdline before os.kill() to prevent signaling unrelated processes after PID reuse (SonarCloud S4828)
13
+ - Wrap initial SIGTERM in try/except ProcessLookupError for race condition safety
14
+
7
15
  ## [1.0.6] - 2026-04-05
8
16
 
9
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 1.0.6
3
+ Version: 1.0.7
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
@@ -38,7 +38,13 @@ from culture.clients.claude.config import (
38
38
  load_config_or_default,
39
39
  sanitize_agent_name,
40
40
  )
41
- from culture.pidfile import is_process_alive, read_pid, remove_pid, write_pid
41
+ from culture.pidfile import (
42
+ is_culture_process,
43
+ is_process_alive,
44
+ read_pid,
45
+ remove_pid,
46
+ write_pid,
47
+ )
42
48
 
43
49
  logger = logging.getLogger("culture")
44
50
 
@@ -902,13 +908,27 @@ def _try_pid_shutdown(nick: str) -> None:
902
908
  print(f"No PID file for agent '{nick}'")
903
909
  return
904
910
 
911
+ if pid <= 0:
912
+ print(f"Invalid PID {pid} for agent '{nick}' — removing corrupt PID file")
913
+ remove_pid(pid_name)
914
+ return
915
+
905
916
  if not is_process_alive(pid):
906
917
  print(f"Agent '{nick}' is not running (stale PID {pid})")
907
918
  remove_pid(pid_name)
908
919
  return
909
920
 
921
+ if not is_culture_process(pid):
922
+ print(f"PID {pid} is not a culture process — removing stale PID file")
923
+ remove_pid(pid_name)
924
+ return
925
+
910
926
  print(f"Stopping agent '{nick}' (PID {pid})...")
911
- os.kill(pid, signal.SIGTERM)
927
+ try:
928
+ os.kill(pid, signal.SIGTERM)
929
+ except ProcessLookupError:
930
+ remove_pid(pid_name)
931
+ return
912
932
 
913
933
  for _ in range(50):
914
934
  if not is_process_alive(pid):
@@ -917,6 +937,13 @@ def _try_pid_shutdown(nick: str) -> None:
917
937
  return
918
938
  time.sleep(0.1)
919
939
 
940
+ # Re-validate ownership before escalating — the original process may have
941
+ # exited and the PID may have been reused during the 5s wait.
942
+ if not is_culture_process(pid):
943
+ print(f"PID {pid} is no longer a culture process — aborting kill")
944
+ remove_pid(pid_name)
945
+ return
946
+
920
947
  # Force kill
921
948
  if sys.platform == "win32":
922
949
  print(f"Agent '{nick}' did not stop gracefully, terminating")
@@ -72,6 +72,27 @@ def remove_port(name: str) -> None:
72
72
  pass
73
73
 
74
74
 
75
+ def is_culture_process(pid: int) -> bool:
76
+ """Check whether the given PID belongs to a culture process.
77
+
78
+ Reads /proc/<pid>/cmdline on Linux and checks NUL-separated argv
79
+ tokens for an exact "culture" match (e.g. argv[0] basename or a
80
+ ``-m culture`` argument). On platforms without /proc, returns True
81
+ (assumes valid). On Linux, read/parse failures return False (fail
82
+ closed) to avoid killing unrelated processes after PID reuse.
83
+ """
84
+ if not os.path.isdir("/proc"):
85
+ # /proc not available (macOS / Windows) — can't verify, assume valid
86
+ return True
87
+ try:
88
+ raw = Path(f"/proc/{pid}/cmdline").read_bytes()
89
+ tokens = [t for t in raw.decode(errors="replace").split("\x00") if t]
90
+ return any(os.path.basename(t) == "culture" or t == "culture" for t in tokens)
91
+ except (OSError, PermissionError):
92
+ # On Linux /proc exists but we can't read this PID — fail closed
93
+ return False
94
+
95
+
75
96
  def is_process_alive(pid: int) -> bool:
76
97
  """Check whether a process with the given PID is alive."""
77
98
  try:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentirc-cli"
3
- version = "1.0.6"
3
+ version = "1.0.7"
4
4
  description = "Legacy alias for culture — install culture instead"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -0,0 +1,122 @@
1
+ """Tests for culture.pidfile — PID file management and process validation."""
2
+
3
+ import os
4
+ from pathlib import Path
5
+ from unittest.mock import patch
6
+
7
+ import pytest
8
+
9
+ from culture.pidfile import (
10
+ is_culture_process,
11
+ is_process_alive,
12
+ read_pid,
13
+ remove_pid,
14
+ write_pid,
15
+ )
16
+
17
+
18
+ @pytest.fixture()
19
+ def pid_dir(tmp_path):
20
+ """Use a temporary directory for PID files."""
21
+ with patch("culture.pidfile.PID_DIR", str(tmp_path)):
22
+ yield tmp_path
23
+
24
+
25
+ class TestWriteReadRemove:
26
+ def test_write_and_read(self, pid_dir):
27
+ write_pid("agent-bot", 12345)
28
+ assert read_pid("agent-bot") == 12345
29
+
30
+ def test_read_missing(self, pid_dir):
31
+ assert read_pid("nonexistent") is None
32
+
33
+ def test_remove(self, pid_dir):
34
+ write_pid("agent-bot", 12345)
35
+ remove_pid("agent-bot")
36
+ assert read_pid("agent-bot") is None
37
+
38
+ def test_remove_missing_is_noop(self, pid_dir):
39
+ remove_pid("nonexistent") # should not raise
40
+
41
+
42
+ class TestIsProcessAlive:
43
+ def test_current_process_alive(self):
44
+ assert is_process_alive(os.getpid()) is True
45
+
46
+ def test_nonexistent_pid(self):
47
+ # Use a very high PID unlikely to exist.
48
+ assert is_process_alive(4_000_000) is False
49
+
50
+
51
+ class TestIsCultureProcess:
52
+ @pytest.mark.skipif(
53
+ not Path("/proc/self/cmdline").exists(),
54
+ reason="/proc not available",
55
+ )
56
+ def test_current_process_is_python(self):
57
+ # We're running under pytest — cmdline won't contain "culture"
58
+ # as an exact argv token, so this should return False.
59
+ result = is_culture_process(os.getpid())
60
+ assert isinstance(result, bool)
61
+
62
+ def test_cmdline_with_culture_token(self):
63
+ """Exact argv token 'culture' is recognized (e.g. -m culture)."""
64
+ raw = b"/usr/bin/python3\x00-m\x00culture\x00start\x00"
65
+ with (
66
+ patch("culture.pidfile.Path") as mock_path,
67
+ patch("culture.pidfile.os.path.isdir", return_value=True),
68
+ ):
69
+ mock_path.return_value.read_bytes.return_value = raw
70
+ assert is_culture_process(999) is True
71
+
72
+ def test_cmdline_with_culture_basename(self):
73
+ """argv[0] with basename 'culture' is recognized."""
74
+ raw = b"/home/user/.local/bin/culture\x00server\x00start\x00"
75
+ with (
76
+ patch("culture.pidfile.Path") as mock_path,
77
+ patch("culture.pidfile.os.path.isdir", return_value=True),
78
+ ):
79
+ mock_path.return_value.read_bytes.return_value = raw
80
+ assert is_culture_process(999) is True
81
+
82
+ def test_cmdline_without_culture(self):
83
+ """Process with unrelated cmdline is rejected."""
84
+ raw = b"/sbin/init\x00--system\x00"
85
+ with (
86
+ patch("culture.pidfile.Path") as mock_path,
87
+ patch("culture.pidfile.os.path.isdir", return_value=True),
88
+ ):
89
+ mock_path.return_value.read_bytes.return_value = raw
90
+ assert is_culture_process(999) is False
91
+
92
+ def test_cmdline_substring_not_matched(self):
93
+ """Substring 'culture' inside another token is NOT matched."""
94
+ raw = b"/usr/bin/agriculture-daemon\x00--flag\x00"
95
+ with (
96
+ patch("culture.pidfile.Path") as mock_path,
97
+ patch("culture.pidfile.os.path.isdir", return_value=True),
98
+ ):
99
+ mock_path.return_value.read_bytes.return_value = raw
100
+ assert is_culture_process(999) is False
101
+
102
+ def test_no_proc_returns_true(self):
103
+ """When /proc doesn't exist (macOS/Windows), assume valid."""
104
+ with patch("culture.pidfile.os.path.isdir", return_value=False):
105
+ assert is_culture_process(999) is True
106
+
107
+ def test_oserror_on_linux_returns_false(self):
108
+ """On Linux, read failures fail closed (return False)."""
109
+ with (
110
+ patch("culture.pidfile.Path") as mock_path,
111
+ patch("culture.pidfile.os.path.isdir", return_value=True),
112
+ ):
113
+ mock_path.return_value.read_bytes.side_effect = OSError("denied")
114
+ assert is_culture_process(999) is False
115
+
116
+ @pytest.mark.skipif(
117
+ not Path("/proc/self/cmdline").exists(),
118
+ reason="/proc not available",
119
+ )
120
+ def test_nonexistent_pid_fails_closed(self):
121
+ """/proc exists but PID doesn't — should return False."""
122
+ assert is_culture_process(4_000_000) is False
@@ -561,7 +561,7 @@ wheels = [
561
561
 
562
562
  [[package]]
563
563
  name = "culture"
564
- version = "1.0.6"
564
+ version = "1.0.7"
565
565
  source = { editable = "." }
566
566
  dependencies = [
567
567
  { name = "aiohttp" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes