agentirc-cli 8.7.1__tar.gz → 9.1.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 (499) hide show
  1. agentirc_cli-9.1.0/.claude/skills/pr-review/SKILL.md +126 -0
  2. agentirc_cli-9.1.0/.claude/skills/pr-review/scripts/portability-lint.sh +56 -0
  3. agentirc_cli-9.1.0/.claude/skills/pr-review/scripts/pr-batch.sh +57 -0
  4. agentirc_cli-9.1.0/.claude/skills/pr-review/scripts/pr-comments.sh +100 -0
  5. agentirc_cli-9.1.0/.claude/skills/pr-review/scripts/pr-reply.sh +66 -0
  6. agentirc_cli-9.1.0/.claude/skills/pr-review/scripts/pr-status.sh +161 -0
  7. agentirc_cli-9.1.0/.claude/skills/pr-review/scripts/workflow.sh +99 -0
  8. agentirc_cli-9.1.0/.claude/skills.local.yaml.example +12 -0
  9. agentirc_cli-9.1.0/.github/workflows/publish.yml +130 -0
  10. agentirc_cli-9.1.0/.github/workflows/tests.yml +128 -0
  11. {agentirc_cli-8.7.1 → agentirc_cli-9.1.0}/.gitignore +44 -41
  12. agentirc_cli-9.1.0/CHANGELOG.md +57 -0
  13. agentirc_cli-9.1.0/CLAUDE.md +135 -0
  14. {agentirc_cli-8.7.1 → agentirc_cli-9.1.0}/LICENSE +1 -1
  15. agentirc_cli-9.1.0/PKG-INFO +56 -0
  16. agentirc_cli-9.1.0/README.md +2 -0
  17. agentirc_cli-9.1.0/agentirc/__init__.py +9 -0
  18. agentirc_cli-9.1.0/agentirc/__main__.py +4 -0
  19. agentirc_cli-9.1.0/agentirc/_internal/bots/bot_manager.py +38 -0
  20. agentirc_cli-9.1.0/agentirc/_internal/bots/http_listener.py +28 -0
  21. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/telemetry/__init__.py +4 -4
  22. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/telemetry/audit.py +18 -4
  23. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/telemetry/context.py +1 -1
  24. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/telemetry/metrics.py +1 -1
  25. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/telemetry/tracing.py +1 -1
  26. {agentirc_cli-8.7.1/culture/bots → agentirc_cli-9.1.0/agentirc/_internal}/virtual_client.py +10 -10
  27. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/channel.py +5 -5
  28. agentirc_cli-9.1.0/agentirc/cli.py +104 -0
  29. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/events.py +2 -2
  30. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/ircd.py +39 -40
  31. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/remote_client.py +3 -3
  32. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/room_store.py +11 -4
  33. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/server_link.py +20 -20
  34. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/skill.py +7 -7
  35. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/skills/history.py +7 -7
  36. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/skills/icon.py +3 -3
  37. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/skills/rooms.py +17 -17
  38. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/skills/threads.py +32 -33
  39. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/thread_store.py +2 -2
  40. agentirc_cli-9.1.0/docs/steward/onboarding.md +108 -0
  41. agentirc_cli-9.1.0/docs/superpowers/specs/2026-04-30-bootstrap-design.md +265 -0
  42. agentirc_cli-9.1.0/pyproject.toml +248 -0
  43. agentirc_cli-9.1.0/tests/test_cli.py +95 -0
  44. agentirc_cli-9.1.0/uv.lock +789 -0
  45. agentirc_cli-8.7.1/.claude/agents/doc-test-alignment.md +0 -154
  46. agentirc_cli-8.7.1/.claude/skills/pr-review/SKILL.md +0 -218
  47. agentirc_cli-8.7.1/.claude/skills/run-tests/SKILL.md +0 -48
  48. agentirc_cli-8.7.1/.claude/skills/run-tests/scripts/test.sh +0 -47
  49. agentirc_cli-8.7.1/.flake8 +0 -37
  50. agentirc_cli-8.7.1/.github/workflows/docs-check.yml +0 -22
  51. agentirc_cli-8.7.1/.github/workflows/publish.yml +0 -111
  52. agentirc_cli-8.7.1/.github/workflows/security-checks.yml +0 -79
  53. agentirc_cli-8.7.1/.github/workflows/tests.yml +0 -78
  54. agentirc_cli-8.7.1/.markdownlint-cli2.yaml +0 -30
  55. agentirc_cli-8.7.1/.pr_agent.toml +0 -38
  56. agentirc_cli-8.7.1/.pre-commit-config.yaml +0 -48
  57. agentirc_cli-8.7.1/.pylintrc +0 -87
  58. agentirc_cli-8.7.1/CHANGELOG.md +0 -1298
  59. agentirc_cli-8.7.1/CLAUDE.md +0 -88
  60. agentirc_cli-8.7.1/Gemfile +0 -8
  61. agentirc_cli-8.7.1/Gemfile.lock +0 -258
  62. agentirc_cli-8.7.1/PKG-INFO +0 -65
  63. agentirc_cli-8.7.1/README.md +0 -34
  64. agentirc_cli-8.7.1/SECURITY.md +0 -39
  65. agentirc_cli-8.7.1/_config.base.yml +0 -54
  66. agentirc_cli-8.7.1/_config.culture.yml +0 -56
  67. agentirc_cli-8.7.1/_data/sites.yml +0 -5
  68. agentirc_cli-8.7.1/_includes/head_custom.html +0 -8
  69. agentirc_cli-8.7.1/_sass/color_schemes/anthropic.scss +0 -34
  70. agentirc_cli-8.7.1/_sass/color_schemes/dark-terminal.scss +0 -40
  71. agentirc_cli-8.7.1/_sass/custom/custom.scss +0 -348
  72. agentirc_cli-8.7.1/assets/images/IMG_3183.png +0 -0
  73. agentirc_cli-8.7.1/assets/images/apple-touch-icon.png +0 -0
  74. agentirc_cli-8.7.1/assets/images/favicon-16x16.png +0 -0
  75. agentirc_cli-8.7.1/assets/images/favicon-32x32.png +0 -0
  76. agentirc_cli-8.7.1/assets/images/favicon.ico +0 -0
  77. agentirc_cli-8.7.1/assets/images/og-agentirc.png +0 -0
  78. agentirc_cli-8.7.1/assets/images/og-culture.png +0 -0
  79. agentirc_cli-8.7.1/culture/__init__.py +0 -13
  80. agentirc_cli-8.7.1/culture/__main__.py +0 -6
  81. agentirc_cli-8.7.1/culture/agentirc/CLAUDE.md +0 -125
  82. agentirc_cli-8.7.1/culture/agentirc/__main__.py +0 -67
  83. agentirc_cli-8.7.1/culture/agentirc/client.py +0 -1056
  84. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc-architecture.md +0 -178
  85. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc-features.md +0 -192
  86. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc-skill.md +0 -293
  87. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc.md +0 -74
  88. agentirc_cli-8.7.1/culture/bots/bot.py +0 -264
  89. agentirc_cli-8.7.1/culture/bots/bot_manager.py +0 -226
  90. agentirc_cli-8.7.1/culture/bots/config.py +0 -162
  91. agentirc_cli-8.7.1/culture/bots/filter_dsl.py +0 -339
  92. agentirc_cli-8.7.1/culture/bots/http_listener.py +0 -118
  93. agentirc_cli-8.7.1/culture/bots/system/__init__.py +0 -36
  94. agentirc_cli-8.7.1/culture/bots/system/welcome/__init__.py +0 -1
  95. agentirc_cli-8.7.1/culture/bots/system/welcome/bot.yaml +0 -11
  96. agentirc_cli-8.7.1/culture/bots/system/welcome/handler.py +0 -1
  97. agentirc_cli-8.7.1/culture/bots/template_engine.py +0 -68
  98. agentirc_cli-8.7.1/culture/cli/__init__.py +0 -74
  99. agentirc_cli-8.7.1/culture/cli/_passthrough.py +0 -116
  100. agentirc_cli-8.7.1/culture/cli/afi.py +0 -71
  101. agentirc_cli-8.7.1/culture/cli/agent.py +0 -1089
  102. agentirc_cli-8.7.1/culture/cli/bot.py +0 -299
  103. agentirc_cli-8.7.1/culture/cli/channel.py +0 -421
  104. agentirc_cli-8.7.1/culture/cli/devex.py +0 -71
  105. agentirc_cli-8.7.1/culture/cli/introspect.py +0 -189
  106. agentirc_cli-8.7.1/culture/cli/mesh.py +0 -734
  107. agentirc_cli-8.7.1/culture/cli/server.py +0 -654
  108. agentirc_cli-8.7.1/culture/cli/shared/constants.py +0 -54
  109. agentirc_cli-8.7.1/culture/cli/shared/display.py +0 -164
  110. agentirc_cli-8.7.1/culture/cli/shared/formatting.py +0 -5
  111. agentirc_cli-8.7.1/culture/cli/shared/ipc.py +0 -70
  112. agentirc_cli-8.7.1/culture/cli/shared/mesh.py +0 -102
  113. agentirc_cli-8.7.1/culture/cli/shared/process.py +0 -144
  114. agentirc_cli-8.7.1/culture/cli/skills.py +0 -151
  115. agentirc_cli-8.7.1/culture/clients/acp/__init__.py +0 -0
  116. agentirc_cli-8.7.1/culture/clients/acp/agent_runner.py +0 -496
  117. agentirc_cli-8.7.1/culture/clients/acp/config.py +0 -330
  118. agentirc_cli-8.7.1/culture/clients/acp/culture.yaml +0 -32
  119. agentirc_cli-8.7.1/culture/clients/acp/daemon.py +0 -956
  120. agentirc_cli-8.7.1/culture/clients/acp/ipc.py +0 -41
  121. agentirc_cli-8.7.1/culture/clients/acp/irc_transport.py +0 -384
  122. agentirc_cli-8.7.1/culture/clients/acp/message_buffer.py +0 -71
  123. agentirc_cli-8.7.1/culture/clients/acp/skill/SKILL.md +0 -194
  124. agentirc_cli-8.7.1/culture/clients/acp/skill/__init__.py +0 -0
  125. agentirc_cli-8.7.1/culture/clients/acp/skill/irc_client.py +0 -325
  126. agentirc_cli-8.7.1/culture/clients/acp/socket_server.py +0 -122
  127. agentirc_cli-8.7.1/culture/clients/acp/supervisor.py +0 -150
  128. agentirc_cli-8.7.1/culture/clients/acp/telemetry.py +0 -318
  129. agentirc_cli-8.7.1/culture/clients/acp/webhook.py +0 -64
  130. agentirc_cli-8.7.1/culture/clients/claude/__init__.py +0 -0
  131. agentirc_cli-8.7.1/culture/clients/claude/__main__.py +0 -93
  132. agentirc_cli-8.7.1/culture/clients/claude/agent_runner.py +0 -231
  133. agentirc_cli-8.7.1/culture/clients/claude/config.py +0 -440
  134. agentirc_cli-8.7.1/culture/clients/claude/culture.yaml +0 -29
  135. agentirc_cli-8.7.1/culture/clients/claude/daemon.py +0 -848
  136. agentirc_cli-8.7.1/culture/clients/claude/ipc.py +0 -41
  137. agentirc_cli-8.7.1/culture/clients/claude/irc_transport.py +0 -384
  138. agentirc_cli-8.7.1/culture/clients/claude/message_buffer.py +0 -71
  139. agentirc_cli-8.7.1/culture/clients/claude/skill/SKILL.md +0 -187
  140. agentirc_cli-8.7.1/culture/clients/claude/skill/__init__.py +0 -0
  141. agentirc_cli-8.7.1/culture/clients/claude/skill/irc_client.py +0 -322
  142. agentirc_cli-8.7.1/culture/clients/claude/socket_server.py +0 -126
  143. agentirc_cli-8.7.1/culture/clients/claude/supervisor.py +0 -150
  144. agentirc_cli-8.7.1/culture/clients/claude/telemetry.py +0 -318
  145. agentirc_cli-8.7.1/culture/clients/claude/webhook.py +0 -64
  146. agentirc_cli-8.7.1/culture/clients/codex/__init__.py +0 -0
  147. agentirc_cli-8.7.1/culture/clients/codex/agent_runner.py +0 -408
  148. agentirc_cli-8.7.1/culture/clients/codex/config.py +0 -330
  149. agentirc_cli-8.7.1/culture/clients/codex/culture.yaml +0 -29
  150. agentirc_cli-8.7.1/culture/clients/codex/daemon.py +0 -945
  151. agentirc_cli-8.7.1/culture/clients/codex/ipc.py +0 -41
  152. agentirc_cli-8.7.1/culture/clients/codex/irc_transport.py +0 -384
  153. agentirc_cli-8.7.1/culture/clients/codex/message_buffer.py +0 -71
  154. agentirc_cli-8.7.1/culture/clients/codex/skill/SKILL.md +0 -194
  155. agentirc_cli-8.7.1/culture/clients/codex/skill/__init__.py +0 -0
  156. agentirc_cli-8.7.1/culture/clients/codex/skill/irc_client.py +0 -322
  157. agentirc_cli-8.7.1/culture/clients/codex/socket_server.py +0 -126
  158. agentirc_cli-8.7.1/culture/clients/codex/supervisor.py +0 -174
  159. agentirc_cli-8.7.1/culture/clients/codex/telemetry.py +0 -318
  160. agentirc_cli-8.7.1/culture/clients/codex/webhook.py +0 -64
  161. agentirc_cli-8.7.1/culture/clients/copilot/__init__.py +0 -0
  162. agentirc_cli-8.7.1/culture/clients/copilot/agent_runner.py +0 -247
  163. agentirc_cli-8.7.1/culture/clients/copilot/config.py +0 -328
  164. agentirc_cli-8.7.1/culture/clients/copilot/culture.yaml +0 -29
  165. agentirc_cli-8.7.1/culture/clients/copilot/daemon.py +0 -923
  166. agentirc_cli-8.7.1/culture/clients/copilot/ipc.py +0 -41
  167. agentirc_cli-8.7.1/culture/clients/copilot/irc_transport.py +0 -384
  168. agentirc_cli-8.7.1/culture/clients/copilot/message_buffer.py +0 -71
  169. agentirc_cli-8.7.1/culture/clients/copilot/skill/SKILL.md +0 -194
  170. agentirc_cli-8.7.1/culture/clients/copilot/skill/__init__.py +0 -0
  171. agentirc_cli-8.7.1/culture/clients/copilot/skill/irc_client.py +0 -325
  172. agentirc_cli-8.7.1/culture/clients/copilot/socket_server.py +0 -126
  173. agentirc_cli-8.7.1/culture/clients/copilot/supervisor.py +0 -170
  174. agentirc_cli-8.7.1/culture/clients/copilot/telemetry.py +0 -318
  175. agentirc_cli-8.7.1/culture/clients/copilot/webhook.py +0 -65
  176. agentirc_cli-8.7.1/culture/config.py +0 -744
  177. agentirc_cli-8.7.1/culture/console/__init__.py +0 -1
  178. agentirc_cli-8.7.1/culture/console/app.py +0 -724
  179. agentirc_cli-8.7.1/culture/console/client.py +0 -427
  180. agentirc_cli-8.7.1/culture/console/commands.py +0 -95
  181. agentirc_cli-8.7.1/culture/console/status.py +0 -74
  182. agentirc_cli-8.7.1/culture/console/widgets/__init__.py +0 -1
  183. agentirc_cli-8.7.1/culture/console/widgets/chat.py +0 -227
  184. agentirc_cli-8.7.1/culture/console/widgets/info_panel.py +0 -172
  185. agentirc_cli-8.7.1/culture/console/widgets/sidebar.py +0 -205
  186. agentirc_cli-8.7.1/culture/credentials.py +0 -167
  187. agentirc_cli-8.7.1/culture/formatting.py +0 -19
  188. agentirc_cli-8.7.1/culture/learn_prompt.py +0 -299
  189. agentirc_cli-8.7.1/culture/mesh_config.py +0 -139
  190. agentirc_cli-8.7.1/culture/observer.py +0 -267
  191. agentirc_cli-8.7.1/culture/overview/__init__.py +0 -1
  192. agentirc_cli-8.7.1/culture/overview/collector.py +0 -469
  193. agentirc_cli-8.7.1/culture/overview/model.py +0 -80
  194. agentirc_cli-8.7.1/culture/overview/renderer_text.py +0 -267
  195. agentirc_cli-8.7.1/culture/overview/renderer_web.py +0 -272
  196. agentirc_cli-8.7.1/culture/overview/web/style.css +0 -88
  197. agentirc_cli-8.7.1/culture/persistence.py +0 -309
  198. agentirc_cli-8.7.1/culture/pidfile.py +0 -164
  199. agentirc_cli-8.7.1/culture/protocol/__init__.py +0 -0
  200. agentirc_cli-8.7.1/culture/protocol/commands.py +0 -43
  201. agentirc_cli-8.7.1/culture/protocol/extensions/audit.md +0 -109
  202. agentirc_cli-8.7.1/culture/protocol/extensions/events.md +0 -145
  203. agentirc_cli-8.7.1/culture/protocol/extensions/federation.md +0 -120
  204. agentirc_cli-8.7.1/culture/protocol/extensions/history.md +0 -117
  205. agentirc_cli-8.7.1/culture/protocol/extensions/icons.md +0 -117
  206. agentirc_cli-8.7.1/culture/protocol/extensions/rooms.md +0 -69
  207. agentirc_cli-8.7.1/culture/protocol/extensions/tags.md +0 -32
  208. agentirc_cli-8.7.1/culture/protocol/extensions/threads.md +0 -296
  209. agentirc_cli-8.7.1/culture/protocol/extensions/tracing.md +0 -37
  210. agentirc_cli-8.7.1/culture/protocol/protocol-index.md +0 -9
  211. agentirc_cli-8.7.1/culture/skills/culture/SKILL.md +0 -370
  212. agentirc_cli-8.7.1/docs/README.md +0 -10
  213. agentirc_cli-8.7.1/docs/agentirc/architecture-overview.md +0 -82
  214. agentirc_cli-8.7.1/docs/agentirc/audit.md +0 -154
  215. agentirc_cli-8.7.1/docs/agentirc/bots.md +0 -242
  216. agentirc_cli-8.7.1/docs/agentirc/events.md +0 -164
  217. agentirc_cli-8.7.1/docs/agentirc/harness-telemetry.md +0 -302
  218. agentirc_cli-8.7.1/docs/agentirc/index.md +0 -94
  219. agentirc_cli-8.7.1/docs/agentirc/otelcol-template.yaml +0 -25
  220. agentirc_cli-8.7.1/docs/agentirc/telemetry.md +0 -238
  221. agentirc_cli-8.7.1/docs/agentirc/why-agentirc.md +0 -32
  222. agentirc_cli-8.7.1/docs/culture/agent-lifecycle.md +0 -265
  223. agentirc_cli-8.7.1/docs/culture/choose-a-harness.md +0 -44
  224. agentirc_cli-8.7.1/docs/culture/features.md +0 -90
  225. agentirc_cli-8.7.1/docs/culture/index.md +0 -87
  226. agentirc_cli-8.7.1/docs/culture/mental-model.md +0 -74
  227. agentirc_cli-8.7.1/docs/culture/operate.md +0 -16
  228. agentirc_cli-8.7.1/docs/culture/patterns.md +0 -67
  229. agentirc_cli-8.7.1/docs/culture/quickstart.md +0 -137
  230. agentirc_cli-8.7.1/docs/culture/reflective-development.md +0 -134
  231. agentirc_cli-8.7.1/docs/culture/vision-patterns-index.md +0 -12
  232. agentirc_cli-8.7.1/docs/culture/vision.md +0 -85
  233. agentirc_cli-8.7.1/docs/culture/what-is-culture.md +0 -93
  234. agentirc_cli-8.7.1/docs/reference/architecture/agent-harness-spec.md +0 -498
  235. agentirc_cli-8.7.1/docs/reference/architecture/index.md +0 -27
  236. agentirc_cli-8.7.1/docs/reference/architecture/layers.md +0 -350
  237. agentirc_cli-8.7.1/docs/reference/architecture/subsites.md +0 -111
  238. agentirc_cli-8.7.1/docs/reference/architecture/threads.md +0 -210
  239. agentirc_cli-8.7.1/docs/reference/cli/afi.md +0 -95
  240. agentirc_cli-8.7.1/docs/reference/cli/commands.md +0 -193
  241. agentirc_cli-8.7.1/docs/reference/cli/devex.md +0 -129
  242. agentirc_cli-8.7.1/docs/reference/cli/index.md +0 -429
  243. agentirc_cli-8.7.1/docs/reference/console.md +0 -90
  244. agentirc_cli-8.7.1/docs/reference/harnesses/acp.md +0 -329
  245. agentirc_cli-8.7.1/docs/reference/harnesses/claude.md +0 -446
  246. agentirc_cli-8.7.1/docs/reference/harnesses/codex.md +0 -364
  247. agentirc_cli-8.7.1/docs/reference/harnesses/copilot.md +0 -352
  248. agentirc_cli-8.7.1/docs/reference/harnesses/index.md +0 -34
  249. agentirc_cli-8.7.1/docs/reference/index.md +0 -12
  250. agentirc_cli-8.7.1/docs/reference/server/architecture.md +0 -185
  251. agentirc_cli-8.7.1/docs/reference/server/config.md +0 -280
  252. agentirc_cli-8.7.1/docs/reference/server/deployment.md +0 -113
  253. agentirc_cli-8.7.1/docs/reference/server/index.md +0 -78
  254. agentirc_cli-8.7.1/docs/reference/server/security.md +0 -118
  255. agentirc_cli-8.7.1/docs/resources/github-copilot-sdk-instructions.md +0 -766
  256. agentirc_cli-8.7.1/docs/resources/positioning.md +0 -44
  257. agentirc_cli-8.7.1/docs/shared/concepts/federation.md +0 -71
  258. agentirc_cli-8.7.1/docs/shared/concepts/harnesses.md +0 -77
  259. agentirc_cli-8.7.1/docs/shared/concepts/humans-and-agents.md +0 -54
  260. agentirc_cli-8.7.1/docs/shared/concepts/index.md +0 -12
  261. agentirc_cli-8.7.1/docs/shared/concepts/persistence.md +0 -70
  262. agentirc_cli-8.7.1/docs/shared/concepts/rooms.md +0 -91
  263. agentirc_cli-8.7.1/docs/shared/demos/magic-demo.md +0 -87
  264. agentirc_cli-8.7.1/docs/shared/guides/first-session.md +0 -64
  265. agentirc_cli-8.7.1/docs/shared/guides/index.md +0 -12
  266. agentirc_cli-8.7.1/docs/shared/guides/join-as-human.md +0 -95
  267. agentirc_cli-8.7.1/docs/shared/guides/local-setup.md +0 -71
  268. agentirc_cli-8.7.1/docs/shared/guides/multi-machine.md +0 -85
  269. agentirc_cli-8.7.1/docs/shared/use-cases/01-pair-programming.md +0 -226
  270. agentirc_cli-8.7.1/docs/shared/use-cases/02-code-review-ensemble.md +0 -221
  271. agentirc_cli-8.7.1/docs/shared/use-cases/03-cross-server-delegation.md +0 -193
  272. agentirc_cli-8.7.1/docs/shared/use-cases/04-knowledge-propagation.md +0 -127
  273. agentirc_cli-8.7.1/docs/shared/use-cases/05-the-observer.md +0 -196
  274. agentirc_cli-8.7.1/docs/shared/use-cases/06-cross-server-ops.md +0 -173
  275. agentirc_cli-8.7.1/docs/shared/use-cases/07-supervisor-intervention.md +0 -266
  276. agentirc_cli-8.7.1/docs/shared/use-cases/08-apps-as-agents.md +0 -139
  277. agentirc_cli-8.7.1/docs/shared/use-cases/09-research-swarm.md +0 -233
  278. agentirc_cli-8.7.1/docs/shared/use-cases/10-agent-lifecycle.md +0 -416
  279. agentirc_cli-8.7.1/docs/shared/use-cases-index.md +0 -27
  280. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -1654
  281. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -3120
  282. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-30-overview.md +0 -1635
  283. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -3213
  284. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -1885
  285. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -1763
  286. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -801
  287. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -1205
  288. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-06-console-chat.md +0 -2246
  289. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-09-decentralized-agent-config.md +0 -2131
  290. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-12-console-enhancements.md +0 -732
  291. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-15-mesh-events.md +0 -3252
  292. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-18-culture-dev-positioning.md +0 -812
  293. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-22-agex-integration.md +0 -999
  294. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-24-otel-foundation.md +0 -2159
  295. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-25-otel-federation.md +0 -229
  296. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-26-otel-metrics.md +0 -303
  297. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-27-otel-audit.md +0 -247
  298. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-28-otel-harness.md +0 -272
  299. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -411
  300. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -484
  301. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-30-overview-design.md +0 -328
  302. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -488
  303. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -326
  304. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -373
  305. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -353
  306. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -177
  307. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -277
  308. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -219
  309. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -212
  310. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -298
  311. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -305
  312. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-07-reflective-development-reframe-design.md +0 -165
  313. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-08-reflective-development-deepening-design.md +0 -179
  314. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-09-decentralized-agent-config-design.md +0 -361
  315. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-12-console-enhancements-design.md +0 -203
  316. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-15-mesh-events-design.md +0 -380
  317. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-17-sites-repositioning-design.md +0 -101
  318. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-18-culture-dev-positioning-design.md +0 -280
  319. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-22-agex-integration-design.md +0 -258
  320. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-24-otel-observability-design.md +0 -334
  321. agentirc_cli-8.7.1/favicon.ico +0 -0
  322. agentirc_cli-8.7.1/packages/agent-harness/README.md +0 -56
  323. agentirc_cli-8.7.1/packages/agent-harness/config.py +0 -299
  324. agentirc_cli-8.7.1/packages/agent-harness/culture.yaml +0 -28
  325. agentirc_cli-8.7.1/packages/agent-harness/daemon.py +0 -637
  326. agentirc_cli-8.7.1/packages/agent-harness/ipc.py +0 -38
  327. agentirc_cli-8.7.1/packages/agent-harness/irc_transport.py +0 -387
  328. agentirc_cli-8.7.1/packages/agent-harness/message_buffer.py +0 -71
  329. agentirc_cli-8.7.1/packages/agent-harness/skill/SKILL.md +0 -57
  330. agentirc_cli-8.7.1/packages/agent-harness/skill/irc_client.py +0 -325
  331. agentirc_cli-8.7.1/packages/agent-harness/socket_server.py +0 -129
  332. agentirc_cli-8.7.1/packages/agent-harness/telemetry.py +0 -315
  333. agentirc_cli-8.7.1/packages/agent-harness/webhook.py +0 -67
  334. agentirc_cli-8.7.1/plugins/claude-code/.claude-plugin/plugin.json +0 -6
  335. agentirc_cli-8.7.1/plugins/claude-code/skills/culture/SKILL.md +0 -363
  336. agentirc_cli-8.7.1/plugins/claude-code/skills/irc/SKILL.md +0 -187
  337. agentirc_cli-8.7.1/plugins/codex/skills/culture-irc/SKILL.md +0 -194
  338. agentirc_cli-8.7.1/pyproject.toml +0 -101
  339. agentirc_cli-8.7.1/robots.txt +0 -9
  340. agentirc_cli-8.7.1/sitemap-agentirc.html +0 -17
  341. agentirc_cli-8.7.1/sitemap-main.html +0 -19
  342. agentirc_cli-8.7.1/sitemap.html +0 -13
  343. agentirc_cli-8.7.1/sonar-project.properties +0 -32
  344. agentirc_cli-8.7.1/tests/__init__.py +0 -0
  345. agentirc_cli-8.7.1/tests/conftest.py +0 -389
  346. agentirc_cli-8.7.1/tests/harness/__init__.py +0 -0
  347. agentirc_cli-8.7.1/tests/harness/conftest.py +0 -89
  348. agentirc_cli-8.7.1/tests/harness/test_agent_runner_acp.py +0 -233
  349. agentirc_cli-8.7.1/tests/harness/test_agent_runner_claude.py +0 -449
  350. agentirc_cli-8.7.1/tests/harness/test_agent_runner_codex.py +0 -229
  351. agentirc_cli-8.7.1/tests/harness/test_agent_runner_copilot.py +0 -256
  352. agentirc_cli-8.7.1/tests/harness/test_all_backends_parity.py +0 -398
  353. agentirc_cli-8.7.1/tests/harness/test_daemon_telemetry.py +0 -72
  354. agentirc_cli-8.7.1/tests/harness/test_irc_transport_propagation.py +0 -447
  355. agentirc_cli-8.7.1/tests/harness/test_record_llm_call.py +0 -245
  356. agentirc_cli-8.7.1/tests/harness/test_telemetry_module.py +0 -264
  357. agentirc_cli-8.7.1/tests/telemetry/__init__.py +0 -0
  358. agentirc_cli-8.7.1/tests/telemetry/_fakes.py +0 -26
  359. agentirc_cli-8.7.1/tests/telemetry/_metrics_helpers.py +0 -75
  360. agentirc_cli-8.7.1/tests/telemetry/conftest.py +0 -33
  361. agentirc_cli-8.7.1/tests/telemetry/test_audit_emit.py +0 -145
  362. agentirc_cli-8.7.1/tests/telemetry/test_audit_federation.py +0 -132
  363. agentirc_cli-8.7.1/tests/telemetry/test_audit_lifecycle.py +0 -69
  364. agentirc_cli-8.7.1/tests/telemetry/test_audit_module.py +0 -306
  365. agentirc_cli-8.7.1/tests/telemetry/test_audit_parse_error.py +0 -177
  366. agentirc_cli-8.7.1/tests/telemetry/test_bot_event_dispatch_span.py +0 -138
  367. agentirc_cli-8.7.1/tests/telemetry/test_bot_run_span.py +0 -91
  368. agentirc_cli-8.7.1/tests/telemetry/test_config.py +0 -26
  369. agentirc_cli-8.7.1/tests/telemetry/test_config_load.py +0 -36
  370. agentirc_cli-8.7.1/tests/telemetry/test_context.py +0 -147
  371. agentirc_cli-8.7.1/tests/telemetry/test_dispatch_span.py +0 -45
  372. agentirc_cli-8.7.1/tests/telemetry/test_emit_event_span.py +0 -42
  373. agentirc_cli-8.7.1/tests/telemetry/test_federation_propagation.py +0 -141
  374. agentirc_cli-8.7.1/tests/telemetry/test_metrics_bots.py +0 -127
  375. agentirc_cli-8.7.1/tests/telemetry/test_metrics_clients.py +0 -79
  376. agentirc_cli-8.7.1/tests/telemetry/test_metrics_events.py +0 -81
  377. agentirc_cli-8.7.1/tests/telemetry/test_metrics_init.py +0 -58
  378. agentirc_cli-8.7.1/tests/telemetry/test_metrics_irc.py +0 -99
  379. agentirc_cli-8.7.1/tests/telemetry/test_metrics_s2s.py +0 -160
  380. agentirc_cli-8.7.1/tests/telemetry/test_metrics_trace_inbound.py +0 -127
  381. agentirc_cli-8.7.1/tests/telemetry/test_metrics_webhook.py +0 -148
  382. agentirc_cli-8.7.1/tests/telemetry/test_outbound_inject.py +0 -70
  383. agentirc_cli-8.7.1/tests/telemetry/test_parse_error.py +0 -33
  384. agentirc_cli-8.7.1/tests/telemetry/test_privmsg_span.py +0 -45
  385. agentirc_cli-8.7.1/tests/telemetry/test_s2s_dispatch_span.py +0 -156
  386. agentirc_cli-8.7.1/tests/telemetry/test_s2s_relay_span.py +0 -114
  387. agentirc_cli-8.7.1/tests/telemetry/test_s2s_session_span.py +0 -64
  388. agentirc_cli-8.7.1/tests/telemetry/test_server_init.py +0 -29
  389. agentirc_cli-8.7.1/tests/telemetry/test_server_link_inject.py +0 -124
  390. agentirc_cli-8.7.1/tests/telemetry/test_session_span.py +0 -105
  391. agentirc_cli-8.7.1/tests/telemetry/test_tracing.py +0 -49
  392. agentirc_cli-8.7.1/tests/telemetry/test_webhook_http_span.py +0 -45
  393. agentirc_cli-8.7.1/tests/test_acp_daemon.py +0 -256
  394. agentirc_cli-8.7.1/tests/test_agent_runner.py +0 -209
  395. agentirc_cli-8.7.1/tests/test_archive.py +0 -1008
  396. agentirc_cli-8.7.1/tests/test_bot.py +0 -174
  397. agentirc_cli-8.7.1/tests/test_bot_config.py +0 -98
  398. agentirc_cli-8.7.1/tests/test_bot_config_fires_event_toplevel.py +0 -114
  399. agentirc_cli-8.7.1/tests/test_bot_manager.py +0 -147
  400. agentirc_cli-8.7.1/tests/test_bots_integration.py +0 -161
  401. agentirc_cli-8.7.1/tests/test_channel.py +0 -131
  402. agentirc_cli-8.7.1/tests/test_channel_cli.py +0 -301
  403. agentirc_cli-8.7.1/tests/test_cli_afi.py +0 -111
  404. agentirc_cli-8.7.1/tests/test_cli_devex.py +0 -53
  405. agentirc_cli-8.7.1/tests/test_cli_introspect.py +0 -155
  406. agentirc_cli-8.7.1/tests/test_cli_passthrough.py +0 -146
  407. agentirc_cli-8.7.1/tests/test_codex_daemon.py +0 -284
  408. agentirc_cli-8.7.1/tests/test_connection.py +0 -135
  409. agentirc_cli-8.7.1/tests/test_console_chat_markdown.py +0 -241
  410. agentirc_cli-8.7.1/tests/test_console_client.py +0 -398
  411. agentirc_cli-8.7.1/tests/test_console_commands.py +0 -133
  412. agentirc_cli-8.7.1/tests/test_console_connection.py +0 -66
  413. agentirc_cli-8.7.1/tests/test_console_fixes_224_227.py +0 -202
  414. agentirc_cli-8.7.1/tests/test_console_icons.py +0 -227
  415. agentirc_cli-8.7.1/tests/test_console_integration.py +0 -65
  416. agentirc_cli-8.7.1/tests/test_console_status.py +0 -53
  417. agentirc_cli-8.7.1/tests/test_constants.py +0 -86
  418. agentirc_cli-8.7.1/tests/test_copilot_daemon.py +0 -253
  419. agentirc_cli-8.7.1/tests/test_credentials.py +0 -24
  420. agentirc_cli-8.7.1/tests/test_culture_config.py +0 -499
  421. agentirc_cli-8.7.1/tests/test_daemon.py +0 -95
  422. agentirc_cli-8.7.1/tests/test_daemon_config.py +0 -714
  423. agentirc_cli-8.7.1/tests/test_daemon_ipc.py +0 -160
  424. agentirc_cli-8.7.1/tests/test_discovery.py +0 -169
  425. agentirc_cli-8.7.1/tests/test_display.py +0 -226
  426. agentirc_cli-8.7.1/tests/test_events_basic.py +0 -292
  427. agentirc_cli-8.7.1/tests/test_events_bot_chain.py +0 -59
  428. agentirc_cli-8.7.1/tests/test_events_bot_trigger.py +0 -99
  429. agentirc_cli-8.7.1/tests/test_events_cap_fallback.py +0 -59
  430. agentirc_cli-8.7.1/tests/test_events_catalog.py +0 -70
  431. agentirc_cli-8.7.1/tests/test_events_federation.py +0 -110
  432. agentirc_cli-8.7.1/tests/test_events_history.py +0 -64
  433. agentirc_cli-8.7.1/tests/test_events_lifecycle.py +0 -343
  434. agentirc_cli-8.7.1/tests/test_events_reserved_nick.py +0 -68
  435. agentirc_cli-8.7.1/tests/test_federation.py +0 -1251
  436. agentirc_cli-8.7.1/tests/test_filter_dsl.py +0 -99
  437. agentirc_cli-8.7.1/tests/test_history.py +0 -553
  438. agentirc_cli-8.7.1/tests/test_http_listener.py +0 -147
  439. agentirc_cli-8.7.1/tests/test_integration_layer5.py +0 -109
  440. agentirc_cli-8.7.1/tests/test_ipc.py +0 -55
  441. agentirc_cli-8.7.1/tests/test_irc_transport.py +0 -314
  442. agentirc_cli-8.7.1/tests/test_irc_transport_tags.py +0 -106
  443. agentirc_cli-8.7.1/tests/test_learn_prompt.py +0 -54
  444. agentirc_cli-8.7.1/tests/test_link_reconnect.py +0 -222
  445. agentirc_cli-8.7.1/tests/test_manifest_config.py +0 -317
  446. agentirc_cli-8.7.1/tests/test_mention_alias.py +0 -156
  447. agentirc_cli-8.7.1/tests/test_mention_target_cleanup.py +0 -135
  448. agentirc_cli-8.7.1/tests/test_mention_warning.py +0 -62
  449. agentirc_cli-8.7.1/tests/test_mentions.py +0 -155
  450. agentirc_cli-8.7.1/tests/test_mesh_config.py +0 -192
  451. agentirc_cli-8.7.1/tests/test_mesh_readiness.py +0 -93
  452. agentirc_cli-8.7.1/tests/test_message.py +0 -79
  453. agentirc_cli-8.7.1/tests/test_message_buffer.py +0 -71
  454. agentirc_cli-8.7.1/tests/test_message_tags.py +0 -75
  455. agentirc_cli-8.7.1/tests/test_messaging.py +0 -103
  456. agentirc_cli-8.7.1/tests/test_migrate_cli.py +0 -128
  457. agentirc_cli-8.7.1/tests/test_modes.py +0 -327
  458. agentirc_cli-8.7.1/tests/test_overview_cli.py +0 -137
  459. agentirc_cli-8.7.1/tests/test_overview_collector.py +0 -161
  460. agentirc_cli-8.7.1/tests/test_overview_model.py +0 -171
  461. agentirc_cli-8.7.1/tests/test_overview_renderer.py +0 -304
  462. agentirc_cli-8.7.1/tests/test_overview_web.py +0 -179
  463. agentirc_cli-8.7.1/tests/test_persistence.py +0 -105
  464. agentirc_cli-8.7.1/tests/test_persistence_timeout.py +0 -59
  465. agentirc_cli-8.7.1/tests/test_pidfile.py +0 -122
  466. agentirc_cli-8.7.1/tests/test_poll_loop.py +0 -129
  467. agentirc_cli-8.7.1/tests/test_register_cli.py +0 -139
  468. agentirc_cli-8.7.1/tests/test_room_persistence.py +0 -75
  469. agentirc_cli-8.7.1/tests/test_rooms.py +0 -729
  470. agentirc_cli-8.7.1/tests/test_rooms_federation.py +0 -63
  471. agentirc_cli-8.7.1/tests/test_rooms_integration.py +0 -110
  472. agentirc_cli-8.7.1/tests/test_server_icon_skill.py +0 -214
  473. agentirc_cli-8.7.1/tests/test_setup_update_cli.py +0 -185
  474. agentirc_cli-8.7.1/tests/test_skill_client.py +0 -96
  475. agentirc_cli-8.7.1/tests/test_skill_docs.py +0 -130
  476. agentirc_cli-8.7.1/tests/test_skills.py +0 -212
  477. agentirc_cli-8.7.1/tests/test_socket_path_convergence.py +0 -153
  478. agentirc_cli-8.7.1/tests/test_socket_server.py +0 -74
  479. agentirc_cli-8.7.1/tests/test_supervisor.py +0 -258
  480. agentirc_cli-8.7.1/tests/test_template_engine.py +0 -80
  481. agentirc_cli-8.7.1/tests/test_thread_buffer.py +0 -55
  482. agentirc_cli-8.7.1/tests/test_threads.py +0 -384
  483. agentirc_cli-8.7.1/tests/test_virtual_client.py +0 -176
  484. agentirc_cli-8.7.1/tests/test_wait_for_port.py +0 -89
  485. agentirc_cli-8.7.1/tests/test_webhook.py +0 -85
  486. agentirc_cli-8.7.1/tests/test_welcome_bot.py +0 -87
  487. agentirc_cli-8.7.1/uv.lock +0 -2717
  488. {agentirc_cli-8.7.1/culture/agentirc → agentirc_cli-9.1.0/agentirc/_internal}/__init__.py +0 -0
  489. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/aio.py +0 -0
  490. {agentirc_cli-8.7.1/culture/agentirc/skills → agentirc_cli-9.1.0/agentirc/_internal/bots}/__init__.py +0 -0
  491. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/constants.py +0 -0
  492. {agentirc_cli-8.7.1/culture/bots → agentirc_cli-9.1.0/agentirc/_internal/protocol}/__init__.py +0 -0
  493. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/protocol/message.py +0 -0
  494. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0/agentirc/_internal}/protocol/replies.py +0 -0
  495. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/config.py +0 -0
  496. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/history_store.py +0 -0
  497. {agentirc_cli-8.7.1/culture → agentirc_cli-9.1.0}/agentirc/rooms_util.py +0 -0
  498. {agentirc_cli-8.7.1/culture/cli/shared → agentirc_cli-9.1.0/agentirc/skills}/__init__.py +0 -0
  499. {agentirc_cli-8.7.1/culture/clients → agentirc_cli-9.1.0/tests}/__init__.py +0 -0
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: pr-review
3
+ description: >
4
+ PR workflow for agentirc: branch, commit, push, PR, wait for Qodo/Copilot,
5
+ triage, fix, reply, resolve. Includes a portability lint (no absolute /home
6
+ paths, no per-user dotfile refs in committed docs) and an alignment-delta
7
+ check when CLAUDE.md or anything under .claude/skills/ changes. Use when:
8
+ creating PRs, handling review feedback, or the user says "create PR",
9
+ "review comments", "address feedback", "resolve threads".
10
+ ---
11
+
12
+ # PR Review — agentirc edition
13
+
14
+ Vendored from `../steward/.claude/skills/pr-review/` per
15
+ `docs/steward/onboarding.md`. Re-sync explicitly when steward updates upstream
16
+ — there is no auto-sync.
17
+
18
+ agentirc's PRs touch the bootstrap spec, `CLAUDE.md`, vendored skills, and
19
+ (post-bootstrap) the IRCd server core. Two recurring bug classes the generic
20
+ `pr-review` skills miss:
21
+
22
+ - **Path leaks** — committing absolute home-directory paths that work only on
23
+ the author's machine.
24
+ - **Per-user config dependencies** — referencing a dotfile under the user's
25
+ home directory in repo guidance, breaking reproducibility for other
26
+ contributors and CI.
27
+
28
+ Both are caught by `scripts/portability-lint.sh`. The full workflow is
29
+ encapsulated in `scripts/workflow.sh` — follow that, not a manual checklist.
30
+
31
+ ## Prerequisites
32
+
33
+ Hard requirements: `gh` (GitHub CLI), `jq`, `bash`, `python3` (stdlib only),
34
+ `curl` (used by `pr-status.sh`).
35
+
36
+ Per-machine paths (sibling-project layout) live in
37
+ `.claude/skills.local.yaml`; see the committed `.example` for the schema.
38
+
39
+ ## How to run
40
+
41
+ `scripts/workflow.sh` is the entry point. Subcommands:
42
+
43
+ | Command | Purpose |
44
+ |---------|---------|
45
+ | `workflow.sh lint` | Portability lint on the current diff (staged + unstaged). |
46
+ | `workflow.sh poll <PR>` | Fetch and display all review comments. |
47
+ | `workflow.sh delta` | Dump each sibling project's `CLAUDE.md` head + `culture.yaml`. |
48
+ | `workflow.sh reply <PR>` | Batch reply (JSONL on stdin) and resolve threads. |
49
+ | `workflow.sh help` | Print this list. |
50
+
51
+ The single-comment helpers — `pr-reply.sh`, `pr-status.sh` — live next to
52
+ `workflow.sh` and are usable directly when batching isn't appropriate.
53
+
54
+ ## End-to-end flow
55
+
56
+ ```text
57
+ git checkout -b <type>/<desc>
58
+ # ... edit ...
59
+ .claude/skills/pr-review/scripts/workflow.sh lint
60
+ git commit -am "..." && git push -u origin <branch>
61
+ gh pr create --title "..." --body "..." # title <70 chars, body signed "- Claude"
62
+ sleep 300 # wait for Qodo + Copilot
63
+ .claude/skills/pr-review/scripts/workflow.sh poll <PR>
64
+ # triage; if CLAUDE.md / .claude/skills changed:
65
+ .claude/skills/pr-review/scripts/workflow.sh delta
66
+ # fix, re-lint, push
67
+ .claude/skills/pr-review/scripts/workflow.sh reply <PR> < replies.jsonl
68
+ gh pr checks <PR>
69
+ # Wait for human merge — never merge yourself.
70
+ ```
71
+
72
+ Branch naming: `fix/<desc>`, `feat/<desc>`, `docs/<desc>`, `skill/<name>`.
73
+ Commit/PR signature: `- Claude` (workspace convention). The reply script
74
+ auto-appends `- Claude` only if the body isn't already signed, so JSONL
75
+ entries can include or omit it.
76
+
77
+ ## Triage rules
78
+
79
+ For every comment, decide **FIX** or **PUSHBACK** with reasoning.
80
+
81
+ Default to **FIX** for: portability complaints (always valid — recurring bug
82
+ class), test or doc requests, style nits aligned with workspace conventions,
83
+ and inconsistencies the reviewer catches between spec sections.
84
+
85
+ Default to **PUSHBACK** for: architecture opinions that conflict with
86
+ `CLAUDE.md` or the bootstrap spec; greenfield false-positives (e.g. "add
87
+ tests" before there's any source — defer to a later PR with a clear note,
88
+ don't refuse).
89
+
90
+ ### Alignment-delta rule
91
+
92
+ If the PR touches `CLAUDE.md` or anything under `.claude/skills/`, run
93
+ `workflow.sh delta` **before** declaring FIX or PUSHBACK on each comment.
94
+ The script dumps the head of every sibling project's `CLAUDE.md` plus the
95
+ full `culture.yaml`, using `sibling_projects` from `skills.local.yaml`.
96
+ agentirc's siblings are `culture` and `steward` — note any sibling that
97
+ needs a follow-up PR and mention it in your reply.
98
+
99
+ ## Greenfield-aware steps
100
+
101
+ The lint and the workflow script are always-on. Stack-specific steps are
102
+ conditional and currently no-op (greenfield repo until the bootstrap lands):
103
+
104
+ ```bash
105
+ [ -d tests ] && [ -f pyproject.toml ] && uv run pytest tests/ -x -q
106
+ [ -f pyproject.toml ] && bump_version_per_project_convention
107
+ [ -f .markdownlint-cli2.yaml ] && markdownlint-cli2 "$(git diff --name-only --cached '*.md')"
108
+ ```
109
+
110
+ Revisit each line as the corresponding stack element actually lands during
111
+ or after the bootstrap.
112
+
113
+ ## Reply etiquette
114
+
115
+ Every comment must get a reply — no silent fixes. Always pass `--resolve`
116
+ when batch-replying so threads close automatically. Reference the
117
+ review-comment IDs in the fix-up commit message. agentirc currently has no
118
+ SonarCloud project and isn't a registered mesh agent, so skip the
119
+ sonarclaude check and the post-merge IRC ping that culture's `pr-review`
120
+ includes — those will return when agentirc joins those systems (the
121
+ `sonarclaude` skill is on the steward-onboarding vendoring queue).
122
+
123
+ ## All-backends rule
124
+
125
+ agentirc has no agent backends, so the all-backends rule that culture
126
+ enforces does not apply here. If a comment cites it, push back.
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env bash
2
+ # Portability lint: catch path leaks and per-user config dependencies in
3
+ # committed docs/configs before they ship in a PR.
4
+ #
5
+ # Usage: portability-lint.sh [--all]
6
+ # default: lint files modified vs HEAD (staged + unstaged)
7
+ # --all: lint all tracked files
8
+ #
9
+ # Exits 0 if clean, 1 if any leak is found.
10
+
11
+ set -euo pipefail
12
+
13
+ mode="${1:-diff}"
14
+ case "$mode" in
15
+ --all) files=$(git ls-files -- ':(exclude)*.lock') ;;
16
+ diff|--diff) files=$(git diff --diff-filter=AMR --name-only HEAD -- ':(exclude)*.lock') ;;
17
+ *) echo "Usage: $(basename "$0") [--all]" >&2; exit 2 ;;
18
+ esac
19
+
20
+ [ -z "$files" ] && { echo "(no files to check)"; exit 0; }
21
+
22
+ # ----- Check 1: hard-coded /home/<user>/... paths -----
23
+ hits1=$(echo "$files" | xargs -r grep -nE '/home/[a-z][a-z0-9_-]+/' 2>/dev/null || true)
24
+
25
+ # ----- Check 2: per-user dotfile *config* refs in committed docs/configs -----
26
+ # Carve-outs (allowed, NOT flagged):
27
+ # - ~/.claude/skills/<x>/scripts/ vendored tool calls
28
+ # - ~/.culture/ Culture mesh data this skill is supposed to read
29
+ md_yaml=$(echo "$files" | grep -E '\.(md|ya?ml|toml|json|jsonc)$' || true)
30
+ if [ -n "$md_yaml" ]; then
31
+ hits2=$(echo "$md_yaml" | xargs -r grep -nE '~/\.[A-Za-z]' 2>/dev/null \
32
+ | grep -vE '~/\.claude/skills/[^[:space:]"]+/scripts/' \
33
+ | grep -vE '~/\.culture/' \
34
+ || true)
35
+ else
36
+ hits2=""
37
+ fi
38
+
39
+ fail=0
40
+ if [ -n "$hits1" ]; then
41
+ echo "❌ Hard-coded /home/<user>/ paths:"
42
+ echo "$hits1" | sed 's/^/ /'
43
+ echo " Fix: use ../sibling, repo URL, or \$WORKSPACE/sibling instead."
44
+ fail=1
45
+ fi
46
+ if [ -n "$hits2" ]; then
47
+ [ "$fail" -eq 1 ] && echo
48
+ echo "❌ Per-user ~/.<dotfile> config refs in committed doc/config:"
49
+ echo "$hits2" | sed 's/^/ /'
50
+ echo " Allowed carve-outs: ~/.claude/skills/.../scripts/ (tool calls), ~/.culture/ (mesh data)."
51
+ echo " Otherwise: commit a repo-local config or document a portable lookup."
52
+ fail=1
53
+ fi
54
+
55
+ [ "$fail" -eq 0 ] && echo "✓ portability lint clean ($(echo "$files" | wc -l | tr -d ' ') files checked)"
56
+ exit $fail
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Batch reply to PR review comments from JSONL on stdin.
5
+ # Each line: {"comment_id": 123, "body": "reply text"}
6
+ # Usage: pr-batch.sh [--repo OWNER/REPO] [--resolve] PR_NUMBER < input.jsonl
7
+
8
+ REPO=""
9
+ RESOLVE=false
10
+
11
+ while [[ $# -gt 0 ]]; do
12
+ case "$1" in
13
+ --repo) REPO="$2"; shift 2 ;;
14
+ --resolve) RESOLVE=true; shift ;;
15
+ *) break ;;
16
+ esac
17
+ done
18
+
19
+ PR_NUMBER="${1:?Usage: pr-batch.sh [--repo OWNER/REPO] [--resolve] PR_NUMBER < input.jsonl}"
20
+
21
+ if [[ -z "$REPO" ]]; then
22
+ REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
23
+ fi
24
+
25
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
26
+ RESOLVE_FLAG=""
27
+ if [[ "$RESOLVE" == true ]]; then
28
+ RESOLVE_FLAG="--resolve"
29
+ fi
30
+
31
+ SUCCESS=0
32
+ FAIL=0
33
+
34
+ while IFS= read -r line; do
35
+ # Skip empty lines
36
+ [[ -z "$line" ]] && continue
37
+
38
+ COMMENT_ID=$(echo "$line" | jq -r '.comment_id')
39
+ BODY=$(echo "$line" | jq -r '.body')
40
+
41
+ if [[ "$COMMENT_ID" == "null" || "$BODY" == "null" ]]; then
42
+ echo "SKIP: invalid line: $line"
43
+ ((FAIL++)) || true
44
+ continue
45
+ fi
46
+
47
+ echo "--- Comment $COMMENT_ID ---"
48
+ if bash "$SCRIPT_DIR/pr-reply.sh" --repo "$REPO" $RESOLVE_FLAG "$PR_NUMBER" "$COMMENT_ID" "$BODY"; then
49
+ ((SUCCESS++)) || true
50
+ else
51
+ echo "FAILED: comment $COMMENT_ID"
52
+ ((FAIL++)) || true
53
+ fi
54
+ done
55
+
56
+ echo ""
57
+ echo "Done: $SUCCESS succeeded, $FAIL failed"
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Fetch and display all PR feedback in one pass:
5
+ # 1. Inline review comments (with thread resolve status)
6
+ # 2. Issue comments (qodo summaries, sonarcloud, etc.)
7
+ # 3. Top-level reviews with a non-empty body (copilot overview, etc.)
8
+ #
9
+ # Usage: pr-comments.sh [--repo OWNER/REPO] PR_NUMBER
10
+
11
+ REPO=""
12
+
13
+ while [[ $# -gt 0 ]]; do
14
+ case "$1" in
15
+ --repo) REPO="$2"; shift 2 ;;
16
+ *) break ;;
17
+ esac
18
+ done
19
+
20
+ PR_NUMBER="${1:?Usage: pr-comments.sh [--repo OWNER/REPO] PR_NUMBER}"
21
+
22
+ if [[ -z "$REPO" ]]; then
23
+ REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
24
+ fi
25
+
26
+ # ── Section 1: inline review comments ─────────────────────────────────────
27
+ THREADS_JSON=$(gh api graphql -f query="
28
+ {
29
+ repository(owner: \"${REPO%%/*}\", name: \"${REPO##*/}\") {
30
+ pullRequest(number: $PR_NUMBER) {
31
+ reviewThreads(first: 100) {
32
+ nodes {
33
+ id
34
+ isResolved
35
+ comments(first: 100) {
36
+ nodes { databaseId }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }" --jq '.data.repository.pullRequest.reviewThreads.nodes')
43
+
44
+ # Build a map from every comment ID in every thread → its thread metadata,
45
+ # so replies in a thread also show resolved status (not just the first comment).
46
+ THREAD_MAP=$(echo "$THREADS_JSON" | jq -r '
47
+ [.[] as $t | $t.comments.nodes[] | {
48
+ comment_id: .databaseId,
49
+ thread_id: $t.id,
50
+ resolved: $t.isResolved
51
+ }]
52
+ ')
53
+
54
+ INLINE=$(gh api "repos/$REPO/pulls/$PR_NUMBER/comments" --paginate)
55
+ INLINE_COUNT=$(echo "$INLINE" | jq 'length')
56
+
57
+ echo "════════════════ INLINE REVIEW COMMENTS ($INLINE_COUNT) ════════════════"
58
+ echo "$INLINE" | jq -r --argjson threads "$THREAD_MAP" '
59
+ .[] | . as $c |
60
+ ($threads | map(select(.comment_id == $c.id)) | first // {resolved: "unknown", thread_id: "?"}) as $t |
61
+ "──────────────────────────────────────────────────",
62
+ "ID: \($c.id) | Thread: \(if $t.resolved == true then "RESOLVED" elif $t.resolved == false then "UNRESOLVED" else "?" end) | Reply-to: \($c.in_reply_to_id // "none")",
63
+ "File: \($c.path):\($c.original_line // $c.line // "?")",
64
+ "Thread ID: \($t.thread_id)",
65
+ "Author: \($c.user.login)",
66
+ "",
67
+ ($c.body | split("\n") | if length > 10 then .[:10] + ["... (truncated)"] else . end | join("\n")),
68
+ ""
69
+ '
70
+
71
+ # ── Section 2: issue comments (general PR comments) ───────────────────────
72
+ ISSUE=$(gh api "repos/$REPO/issues/$PR_NUMBER/comments" --paginate)
73
+ ISSUE_COUNT=$(echo "$ISSUE" | jq 'length')
74
+
75
+ echo ""
76
+ echo "════════════════ ISSUE COMMENTS ($ISSUE_COUNT) ════════════════"
77
+ echo "$ISSUE" | jq -r '
78
+ .[] |
79
+ "──────────────────────────────────────────────────",
80
+ "ID: \(.id) | Author: \(.user.login) | Created: \(.created_at)",
81
+ "",
82
+ (.body | split("\n") | if length > 10 then .[:10] + ["... (truncated)"] else . end | join("\n")),
83
+ ""
84
+ '
85
+
86
+ # ── Section 3: top-level reviews with a body ──────────────────────────────
87
+ REVIEWS=$(gh api "repos/$REPO/pulls/$PR_NUMBER/reviews" --paginate)
88
+ REVIEWS_WITH_BODY=$(echo "$REVIEWS" | jq '[.[] | select((.body // "") != "")]')
89
+ REVIEW_COUNT=$(echo "$REVIEWS_WITH_BODY" | jq 'length')
90
+
91
+ echo ""
92
+ echo "════════════════ TOP-LEVEL REVIEWS ($REVIEW_COUNT) ════════════════"
93
+ echo "$REVIEWS_WITH_BODY" | jq -r '
94
+ .[] |
95
+ "──────────────────────────────────────────────────",
96
+ "Review ID: \(.id) | Author: \(.user.login) | State: \(.state) | Submitted: \(.submitted_at)",
97
+ "",
98
+ (.body | split("\n") | if length > 10 then .[:10] + ["... (truncated)"] else . end | join("\n")),
99
+ ""
100
+ '
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Reply to a PR review comment, optionally resolve its thread.
5
+ # Usage: pr-reply.sh [--repo OWNER/REPO] [--resolve] PR_NUMBER COMMENT_ID "body"
6
+
7
+ REPO=""
8
+ RESOLVE=false
9
+
10
+ while [[ $# -gt 0 ]]; do
11
+ case "$1" in
12
+ --repo) REPO="$2"; shift 2 ;;
13
+ --resolve) RESOLVE=true; shift ;;
14
+ *) break ;;
15
+ esac
16
+ done
17
+
18
+ PR_NUMBER="${1:?Usage: pr-reply.sh [--repo OWNER/REPO] [--resolve] PR_NUMBER COMMENT_ID \"body\"}"
19
+ COMMENT_ID="${2:?Missing COMMENT_ID}"
20
+ BODY="${3:?Missing reply body}"
21
+
22
+ if [[ -z "$REPO" ]]; then
23
+ REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
24
+ fi
25
+
26
+ # Append signature only if the body isn't already signed.
27
+ if ! printf '%s' "$BODY" | grep -qE '(^|\n)[[:space:]]*-[[:space:]]+Claude[[:space:]]*$'; then
28
+ BODY="${BODY}
29
+
30
+ - Claude"
31
+ fi
32
+
33
+ # Post reply
34
+ REPLY_URL=$(gh api "repos/$REPO/pulls/$PR_NUMBER/comments/$COMMENT_ID/replies" \
35
+ -f body="$BODY" \
36
+ --jq '.html_url')
37
+ echo "Replied: $REPLY_URL"
38
+
39
+ # Resolve thread if requested
40
+ if [[ "$RESOLVE" == true ]]; then
41
+ # Find the thread ID for this comment
42
+ THREAD_ID=$(gh api graphql -f query="
43
+ {
44
+ repository(owner: \"${REPO%%/*}\", name: \"${REPO##*/}\") {
45
+ pullRequest(number: $PR_NUMBER) {
46
+ reviewThreads(first: 100) {
47
+ nodes {
48
+ id
49
+ comments(first: 100) {
50
+ nodes { databaseId }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }" --jq ".data.repository.pullRequest.reviewThreads.nodes[] | select(any(.comments.nodes[]; .databaseId == $COMMENT_ID)) | .id")
57
+
58
+ if [[ -n "$THREAD_ID" ]]; then
59
+ RESOLVED=$(gh api graphql -f query="
60
+ mutation { resolveReviewThread(input: {threadId: \"$THREAD_ID\"}) { thread { isResolved } } }
61
+ " --jq '.data.resolveReviewThread.thread.isResolved')
62
+ echo "Resolved: $RESOLVED (thread $THREAD_ID)"
63
+ else
64
+ echo "Warning: could not find thread for comment $COMMENT_ID"
65
+ fi
66
+ fi
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env bash
2
+ # pr-status.sh — one-shot status overview for a PR.
3
+ #
4
+ # Combines five things review feedback usually scatters across:
5
+ # 1. PR state (open / merged / closed) + branch + author
6
+ # 2. CI checks (build / lint / unit / sonarcloud / cf-pages / etc.)
7
+ # 3. Review-bot pipeline status (Copilot, qodo, SonarCloud, Cloudflare)
8
+ # 4. SonarCloud quality gate + open-issue count
9
+ # 5. Inline-thread resolved-vs-unresolved tally
10
+ #
11
+ # Usage: scripts/pr-status.sh [--repo OWNER/REPO] [--sonar-key KEY] PR_NUMBER
12
+ #
13
+ # Defaults:
14
+ # --repo auto-detected via `gh repo view`
15
+ # --sonar-key derived from repo as `<owner>_<name>` (SonarCloud convention)
16
+ #
17
+ # Requires: gh, jq, curl, python3.
18
+
19
+ set -euo pipefail
20
+
21
+ REPO=""
22
+ SONAR_KEY=""
23
+
24
+ while [[ $# -gt 0 ]]; do
25
+ case "$1" in
26
+ --repo) REPO="$2"; shift 2 ;;
27
+ --sonar-key) SONAR_KEY="$2"; shift 2 ;;
28
+ *) break ;;
29
+ esac
30
+ done
31
+
32
+ PR_NUMBER="${1:?Usage: pr-status.sh [--repo OWNER/REPO] [--sonar-key KEY] PR_NUMBER}"
33
+
34
+ if [[ -z "$REPO" ]]; then
35
+ REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
36
+ fi
37
+ if [[ -z "$SONAR_KEY" ]]; then
38
+ SONAR_KEY="${REPO%%/*}_${REPO##*/}"
39
+ fi
40
+
41
+ # ── 1. PR header ──────────────────────────────────────────────────────────
42
+ PR_JSON=$(gh pr view "$PR_NUMBER" --json \
43
+ number,title,state,isDraft,mergedAt,mergedBy,baseRefName,headRefName,author,url)
44
+
45
+ echo "════════════════════════════════════════════════════════════════════"
46
+ echo "$PR_JSON" | jq -r '
47
+ "PR #\(.number) — \(.title)",
48
+ " \(.url)",
49
+ " Author: \(.author.login)",
50
+ " Branch: \(.headRefName) → \(.baseRefName)",
51
+ " State: \(if .state == "MERGED" then "MERGED at \(.mergedAt) by \(.mergedBy.login)" elif .state == "OPEN" and .isDraft then "OPEN (draft)" else .state end)"
52
+ '
53
+ echo "════════════════════════════════════════════════════════════════════"
54
+
55
+ # ── 2. CI checks ──────────────────────────────────────────────────────────
56
+ echo
57
+ echo "── CI checks ─────────────────────────────────────────────────────────"
58
+ # `gh pr checks` exits non-zero when checks are still pending/failing.
59
+ # We don't care about its exit code here; capture and pretty-print.
60
+ CHECKS=$(gh pr checks "$PR_NUMBER" 2>/dev/null || true)
61
+ if [[ -z "$CHECKS" ]]; then
62
+ echo " (no checks reported)"
63
+ else
64
+ echo "$CHECKS" | awk -F'\t' '
65
+ {
66
+ name = $1
67
+ state = $2
68
+ dur = $3
69
+ sym = "?"
70
+ if (state == "pass") sym = "✅"
71
+ else if (state == "fail") sym = "❌"
72
+ else if (state == "skipping") sym = "⏭"
73
+ else if (state == "pending" || state == "queued" || state == "in_progress") sym = "…"
74
+ printf " %s %-22s %-10s %s\n", sym, name, state, dur
75
+ }
76
+ '
77
+ fi
78
+
79
+ # ── 3. Review bots & comment pipeline ────────────────────────────────────
80
+ echo
81
+ echo "── Review pipeline ───────────────────────────────────────────────────"
82
+
83
+ # Inline-thread tally via GraphQL (resolved vs unresolved).
84
+ THREADS_JSON=$(gh api graphql -f query="
85
+ {
86
+ repository(owner: \"${REPO%%/*}\", name: \"${REPO##*/}\") {
87
+ pullRequest(number: $PR_NUMBER) {
88
+ reviewThreads(first: 100) {
89
+ nodes { id isResolved comments(first: 1) { nodes { author { login } } } }
90
+ }
91
+ }
92
+ }
93
+ }" --jq '.data.repository.pullRequest.reviewThreads.nodes')
94
+
95
+ INLINE_TOTAL=$(echo "$THREADS_JSON" | jq 'length')
96
+ INLINE_RESOLVED=$(echo "$THREADS_JSON" | jq '[.[] | select(.isResolved)] | length')
97
+ INLINE_PENDING=$((INLINE_TOTAL - INLINE_RESOLVED))
98
+
99
+ # Per-bot inline counts.
100
+ COPILOT_INLINE=$(echo "$THREADS_JSON" | jq '[.[] | select((.comments.nodes[0].author.login // "") | startswith("Copilot"))] | length')
101
+ QODO_INLINE=$(echo "$THREADS_JSON" | jq '[.[] | select((.comments.nodes[0].author.login // "") | startswith("qodo"))] | length')
102
+
103
+ # Issue-level comments (qodo summary, sonarcloud quality-gate body, cf-pages preview, etc.).
104
+ # Skip --paginate to avoid array concatenation; per_page=100 covers typical PRs.
105
+ ISSUE=$(gh api "repos/$REPO/issues/$PR_NUMBER/comments?per_page=100")
106
+ QODO_ISSUE=$(echo "$ISSUE" | jq '[.[] | select((.user.login // "") | startswith("qodo"))] | length')
107
+ SONARQUBE_ISSUE=$(echo "$ISSUE" | jq '[.[] | select((.user.login // "") | startswith("sonarqubecloud"))] | length')
108
+ CFPAGES_ISSUE=$(echo "$ISSUE" | jq '[.[] | select((.user.login // "") | test("cloudflare"))] | length')
109
+ COPILOT_TOPLEVEL=$(gh api "repos/$REPO/pulls/$PR_NUMBER/reviews?per_page=100" \
110
+ | jq '[.[] | select((.user.login // "") | startswith("copilot")) | select((.body // "") != "")] | length')
111
+
112
+ # Cloudflare deploy URL hidden in issue-comment bodies (look for pages.dev).
113
+ CF_URL=$(echo "$ISSUE" | jq -r '[.[].body // "" | scan("https?://[a-z0-9.-]+\\.pages\\.dev[^\\s)\"<]*")] | first // ""')
114
+
115
+ printf " %-12s %s\n" "Copilot" "$([[ "$COPILOT_TOPLEVEL" -gt 0 || "$COPILOT_INLINE" -gt 0 ]] && echo "✅ overview×$COPILOT_TOPLEVEL, inline×$COPILOT_INLINE" || echo "— no posts yet")"
116
+ printf " %-12s %s\n" "qodo" "$([[ "$QODO_ISSUE" -gt 0 || "$QODO_INLINE" -gt 0 ]] && echo "✅ summary×$QODO_ISSUE, inline×$QODO_INLINE" || echo "— no posts yet")"
117
+ printf " %-12s %s\n" "Cloudflare" "$([[ -n "$CF_URL" ]] && echo "✅ $CF_URL" || ([[ "$CFPAGES_ISSUE" -gt 0 ]] && echo "✅ ($CFPAGES_ISSUE comments)" || echo "— no deploy preview"))"
118
+
119
+ # ── 4. SonarCloud quality gate + open issues ─────────────────────────────
120
+ SONAR_QG=$(curl -s "https://sonarcloud.io/api/qualitygates/project_status?projectKey=${SONAR_KEY}&pullRequest=${PR_NUMBER}")
121
+ SONAR_QG_STATUS=$(echo "$SONAR_QG" | jq -r '.projectStatus.status // "UNKNOWN"')
122
+ SONAR_OPEN=$(curl -s "https://sonarcloud.io/api/issues/search?componentKeys=${SONAR_KEY}&pullRequest=${PR_NUMBER}&statuses=OPEN,CONFIRMED&ps=1" \
123
+ | jq -r '.total // 0')
124
+ SONAR_HOTSPOTS=$(curl -s "https://sonarcloud.io/api/hotspots/search?projectKey=${SONAR_KEY}&pullRequest=${PR_NUMBER}&status=TO_REVIEW&ps=1" \
125
+ | jq -r '.paging.total // 0')
126
+
127
+ case "$SONAR_QG_STATUS" in
128
+ OK) SONAR_SYM="✅" ;;
129
+ ERROR) SONAR_SYM="❌" ;;
130
+ WARN) SONAR_SYM="⚠ " ;;
131
+ *) SONAR_SYM="?" ;;
132
+ esac
133
+ printf " %-12s %s Quality Gate %s, %d OPEN issue(s), %d hotspot(s)\n" \
134
+ "SonarCloud" "$SONAR_SYM" "$SONAR_QG_STATUS" "$SONAR_OPEN" "$SONAR_HOTSPOTS"
135
+
136
+ # When SonarCloud has OPEN issues, list them — saves a follow-up curl.
137
+ if [[ "$SONAR_OPEN" != "0" ]]; then
138
+ echo
139
+ echo " SonarCloud OPEN issues:"
140
+ curl -s "https://sonarcloud.io/api/issues/search?componentKeys=${SONAR_KEY}&pullRequest=${PR_NUMBER}&statuses=OPEN,CONFIRMED&ps=20" \
141
+ | jq -r '.issues[] | " • [\(.rule)] \(.component | sub("^[^:]+:"; ""))(:\(.line // "?")) (\(.severity)) — \(.message)"'
142
+ fi
143
+
144
+ # ── 5. Tally + summary ────────────────────────────────────────────────────
145
+ echo
146
+ echo "── Inline threads ────────────────────────────────────────────────────"
147
+ printf " Total: %d Resolved: %d Unresolved: %d\n" \
148
+ "$INLINE_TOTAL" "$INLINE_RESOLVED" "$INLINE_PENDING"
149
+
150
+ if [[ "$INLINE_PENDING" -gt 0 ]]; then
151
+ echo
152
+ echo " Unresolved threads:"
153
+ echo "$THREADS_JSON" | jq -r '
154
+ .[] | select(.isResolved == false) |
155
+ " • \(.comments.nodes[0].author.login): thread \(.id)"
156
+ '
157
+ fi
158
+
159
+ echo
160
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
161
+ echo "(For full comment bodies: bash \"$SCRIPT_DIR/pr-comments.sh\" $PR_NUMBER)"
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env bash
2
+ # pr-review workflow entry point.
3
+ #
4
+ # Subcommands:
5
+ # lint run the portability lint on the current diff (staged + unstaged)
6
+ # poll <PR> fetch and display review comments
7
+ # reply <PR> batch reply to review comments (JSONL on stdin), --resolve
8
+ # delta dump CLAUDE.md head + culture.yaml for each sibling project
9
+ # listed in skills.local.yaml (alignment-delta check)
10
+ # help print this message
11
+
12
+ set -euo pipefail
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
16
+ REPO_ROOT="$(cd "$SKILL_DIR/../../.." && pwd)"
17
+
18
+ CFG="$REPO_ROOT/.claude/skills.local.yaml"
19
+ [ -f "$CFG" ] || CFG="$REPO_ROOT/.claude/skills.local.yaml.example"
20
+
21
+ # Read a top-level YAML list from CFG. Schema is intentionally tiny:
22
+ # <key>:
23
+ # - item
24
+ # - item
25
+ # Stops at the next top-level key. No PyYAML dependency.
26
+ read_list() {
27
+ awk -v key="$1" '
28
+ function trim(s) { sub(/^[[:space:]]+/, "", s); sub(/[[:space:]]+$/, "", s); return s }
29
+ {
30
+ line = $0
31
+ sub(/[[:space:]]+#.*$/, "", line)
32
+ }
33
+ in_list && line ~ /^[[:space:]]*-[[:space:]]*/ {
34
+ item = line
35
+ sub(/^[[:space:]]*-[[:space:]]*/, "", item)
36
+ item = trim(item)
37
+ sub(/^["\047]/, "", item); sub(/["\047]$/, "", item)
38
+ if (item != "") print item
39
+ next
40
+ }
41
+ in_list && line ~ /^[^[:space:]#]/ { exit }
42
+ line ~ ("^" key ":[[:space:]]*($|#)") { in_list = 1 }
43
+ ' "$CFG"
44
+ }
45
+
46
+ cmd="${1:-help}"
47
+ shift || true
48
+
49
+ case "$cmd" in
50
+ lint)
51
+ bash "$SCRIPT_DIR/portability-lint.sh"
52
+ ;;
53
+ poll)
54
+ PR="${1:?Usage: workflow.sh poll <PR>}"
55
+ bash "$SCRIPT_DIR/pr-comments.sh" "$PR"
56
+ ;;
57
+ reply)
58
+ PR="${1:?Usage: workflow.sh reply <PR> (JSONL on stdin)}"
59
+ bash "$SCRIPT_DIR/pr-batch.sh" --resolve "$PR"
60
+ ;;
61
+ delta)
62
+ any=0
63
+ while IFS= read -r sibling; do
64
+ [ -z "$sibling" ] && continue
65
+ any=1
66
+ sibling_abs="$REPO_ROOT/$sibling"
67
+ if [ ! -d "$sibling_abs" ] && [ ! -d "$sibling" ]; then
68
+ echo "=== $sibling ==="
69
+ echo "(not present on disk — skipped)"
70
+ continue
71
+ fi
72
+ target="$sibling_abs"
73
+ [ -d "$target" ] || target="$sibling"
74
+ echo "=== $target ==="
75
+ if [ -f "$target/CLAUDE.md" ]; then
76
+ head -40 "$target/CLAUDE.md"
77
+ echo "..."
78
+ else
79
+ echo "(no CLAUDE.md)"
80
+ fi
81
+ echo "--- culture.yaml ---"
82
+ if [ -f "$target/culture.yaml" ]; then
83
+ cat "$target/culture.yaml"
84
+ else
85
+ echo "(no culture.yaml)"
86
+ fi
87
+ echo
88
+ done < <(read_list sibling_projects)
89
+ [ "$any" -eq 0 ] && echo "(no sibling_projects configured in $CFG)"
90
+ ;;
91
+ help|--help|-h)
92
+ sed -n '2,11p' "${BASH_SOURCE[0]}" | sed 's/^# *//'
93
+ ;;
94
+ *)
95
+ echo "unknown subcommand: $cmd" >&2
96
+ echo "run '$(basename "$0") help' for usage." >&2
97
+ exit 2
98
+ ;;
99
+ esac