agentirc-cli 8.7.1__tar.gz → 9.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (496) hide show
  1. agentirc_cli-9.0.0/.claude/skills/pr-review/SKILL.md +126 -0
  2. agentirc_cli-9.0.0/.claude/skills/pr-review/scripts/portability-lint.sh +56 -0
  3. agentirc_cli-9.0.0/.claude/skills/pr-review/scripts/pr-batch.sh +57 -0
  4. agentirc_cli-9.0.0/.claude/skills/pr-review/scripts/pr-comments.sh +100 -0
  5. agentirc_cli-9.0.0/.claude/skills/pr-review/scripts/pr-reply.sh +66 -0
  6. agentirc_cli-9.0.0/.claude/skills/pr-review/scripts/pr-status.sh +161 -0
  7. agentirc_cli-9.0.0/.claude/skills/pr-review/scripts/workflow.sh +99 -0
  8. agentirc_cli-9.0.0/.claude/skills.local.yaml.example +12 -0
  9. agentirc_cli-9.0.0/.github/workflows/publish.yml +130 -0
  10. agentirc_cli-9.0.0/.github/workflows/tests.yml +128 -0
  11. {agentirc_cli-8.7.1 → agentirc_cli-9.0.0}/.gitignore +44 -41
  12. agentirc_cli-9.0.0/CLAUDE.md +126 -0
  13. {agentirc_cli-8.7.1 → agentirc_cli-9.0.0}/LICENSE +1 -1
  14. agentirc_cli-9.0.0/PKG-INFO +52 -0
  15. agentirc_cli-9.0.0/README.md +2 -0
  16. agentirc_cli-9.0.0/agentirc/__init__.py +9 -0
  17. agentirc_cli-9.0.0/agentirc/__main__.py +4 -0
  18. agentirc_cli-9.0.0/agentirc/cli.py +104 -0
  19. agentirc_cli-9.0.0/docs/steward/onboarding.md +108 -0
  20. agentirc_cli-9.0.0/docs/superpowers/specs/2026-04-30-bootstrap-design.md +248 -0
  21. agentirc_cli-9.0.0/pyproject.toml +51 -0
  22. agentirc_cli-9.0.0/tests/test_cli.py +95 -0
  23. agentirc_cli-9.0.0/uv.lock +564 -0
  24. agentirc_cli-8.7.1/.claude/agents/doc-test-alignment.md +0 -154
  25. agentirc_cli-8.7.1/.claude/skills/pr-review/SKILL.md +0 -218
  26. agentirc_cli-8.7.1/.claude/skills/run-tests/SKILL.md +0 -48
  27. agentirc_cli-8.7.1/.claude/skills/run-tests/scripts/test.sh +0 -47
  28. agentirc_cli-8.7.1/.flake8 +0 -37
  29. agentirc_cli-8.7.1/.github/workflows/docs-check.yml +0 -22
  30. agentirc_cli-8.7.1/.github/workflows/publish.yml +0 -111
  31. agentirc_cli-8.7.1/.github/workflows/security-checks.yml +0 -79
  32. agentirc_cli-8.7.1/.github/workflows/tests.yml +0 -78
  33. agentirc_cli-8.7.1/.markdownlint-cli2.yaml +0 -30
  34. agentirc_cli-8.7.1/.pr_agent.toml +0 -38
  35. agentirc_cli-8.7.1/.pre-commit-config.yaml +0 -48
  36. agentirc_cli-8.7.1/.pylintrc +0 -87
  37. agentirc_cli-8.7.1/CHANGELOG.md +0 -1298
  38. agentirc_cli-8.7.1/CLAUDE.md +0 -88
  39. agentirc_cli-8.7.1/Gemfile +0 -8
  40. agentirc_cli-8.7.1/Gemfile.lock +0 -258
  41. agentirc_cli-8.7.1/PKG-INFO +0 -65
  42. agentirc_cli-8.7.1/README.md +0 -34
  43. agentirc_cli-8.7.1/SECURITY.md +0 -39
  44. agentirc_cli-8.7.1/_config.base.yml +0 -54
  45. agentirc_cli-8.7.1/_config.culture.yml +0 -56
  46. agentirc_cli-8.7.1/_data/sites.yml +0 -5
  47. agentirc_cli-8.7.1/_includes/head_custom.html +0 -8
  48. agentirc_cli-8.7.1/_sass/color_schemes/anthropic.scss +0 -34
  49. agentirc_cli-8.7.1/_sass/color_schemes/dark-terminal.scss +0 -40
  50. agentirc_cli-8.7.1/_sass/custom/custom.scss +0 -348
  51. agentirc_cli-8.7.1/assets/images/IMG_3183.png +0 -0
  52. agentirc_cli-8.7.1/assets/images/apple-touch-icon.png +0 -0
  53. agentirc_cli-8.7.1/assets/images/favicon-16x16.png +0 -0
  54. agentirc_cli-8.7.1/assets/images/favicon-32x32.png +0 -0
  55. agentirc_cli-8.7.1/assets/images/favicon.ico +0 -0
  56. agentirc_cli-8.7.1/assets/images/og-agentirc.png +0 -0
  57. agentirc_cli-8.7.1/assets/images/og-culture.png +0 -0
  58. agentirc_cli-8.7.1/culture/__init__.py +0 -13
  59. agentirc_cli-8.7.1/culture/__main__.py +0 -6
  60. agentirc_cli-8.7.1/culture/agentirc/CLAUDE.md +0 -125
  61. agentirc_cli-8.7.1/culture/agentirc/__main__.py +0 -67
  62. agentirc_cli-8.7.1/culture/agentirc/channel.py +0 -80
  63. agentirc_cli-8.7.1/culture/agentirc/client.py +0 -1056
  64. agentirc_cli-8.7.1/culture/agentirc/config.py +0 -49
  65. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc-architecture.md +0 -178
  66. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc-features.md +0 -192
  67. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc-skill.md +0 -293
  68. agentirc_cli-8.7.1/culture/agentirc/docs/agentirc.md +0 -74
  69. agentirc_cli-8.7.1/culture/agentirc/events.py +0 -117
  70. agentirc_cli-8.7.1/culture/agentirc/history_store.py +0 -91
  71. agentirc_cli-8.7.1/culture/agentirc/ircd.py +0 -719
  72. agentirc_cli-8.7.1/culture/agentirc/remote_client.py +0 -43
  73. agentirc_cli-8.7.1/culture/agentirc/room_store.py +0 -64
  74. agentirc_cli-8.7.1/culture/agentirc/rooms_util.py +0 -56
  75. agentirc_cli-8.7.1/culture/agentirc/server_link.py +0 -1166
  76. agentirc_cli-8.7.1/culture/agentirc/skill.py +0 -61
  77. agentirc_cli-8.7.1/culture/agentirc/skills/__init__.py +0 -0
  78. agentirc_cli-8.7.1/culture/agentirc/skills/history.py +0 -225
  79. agentirc_cli-8.7.1/culture/agentirc/skills/icon.py +0 -52
  80. agentirc_cli-8.7.1/culture/agentirc/skills/rooms.py +0 -834
  81. agentirc_cli-8.7.1/culture/agentirc/skills/threads.py +0 -710
  82. agentirc_cli-8.7.1/culture/agentirc/thread_store.py +0 -52
  83. agentirc_cli-8.7.1/culture/aio.py +0 -12
  84. agentirc_cli-8.7.1/culture/bots/__init__.py +0 -0
  85. agentirc_cli-8.7.1/culture/bots/bot.py +0 -264
  86. agentirc_cli-8.7.1/culture/bots/bot_manager.py +0 -226
  87. agentirc_cli-8.7.1/culture/bots/config.py +0 -162
  88. agentirc_cli-8.7.1/culture/bots/filter_dsl.py +0 -339
  89. agentirc_cli-8.7.1/culture/bots/http_listener.py +0 -118
  90. agentirc_cli-8.7.1/culture/bots/system/__init__.py +0 -36
  91. agentirc_cli-8.7.1/culture/bots/system/welcome/__init__.py +0 -1
  92. agentirc_cli-8.7.1/culture/bots/system/welcome/bot.yaml +0 -11
  93. agentirc_cli-8.7.1/culture/bots/system/welcome/handler.py +0 -1
  94. agentirc_cli-8.7.1/culture/bots/template_engine.py +0 -68
  95. agentirc_cli-8.7.1/culture/bots/virtual_client.py +0 -231
  96. agentirc_cli-8.7.1/culture/cli/__init__.py +0 -74
  97. agentirc_cli-8.7.1/culture/cli/_passthrough.py +0 -116
  98. agentirc_cli-8.7.1/culture/cli/afi.py +0 -71
  99. agentirc_cli-8.7.1/culture/cli/agent.py +0 -1089
  100. agentirc_cli-8.7.1/culture/cli/bot.py +0 -299
  101. agentirc_cli-8.7.1/culture/cli/channel.py +0 -421
  102. agentirc_cli-8.7.1/culture/cli/devex.py +0 -71
  103. agentirc_cli-8.7.1/culture/cli/introspect.py +0 -189
  104. agentirc_cli-8.7.1/culture/cli/mesh.py +0 -734
  105. agentirc_cli-8.7.1/culture/cli/server.py +0 -654
  106. agentirc_cli-8.7.1/culture/cli/shared/__init__.py +0 -0
  107. agentirc_cli-8.7.1/culture/cli/shared/constants.py +0 -54
  108. agentirc_cli-8.7.1/culture/cli/shared/display.py +0 -164
  109. agentirc_cli-8.7.1/culture/cli/shared/formatting.py +0 -5
  110. agentirc_cli-8.7.1/culture/cli/shared/ipc.py +0 -70
  111. agentirc_cli-8.7.1/culture/cli/shared/mesh.py +0 -102
  112. agentirc_cli-8.7.1/culture/cli/shared/process.py +0 -144
  113. agentirc_cli-8.7.1/culture/cli/skills.py +0 -151
  114. agentirc_cli-8.7.1/culture/clients/__init__.py +0 -0
  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/constants.py +0 -17
  187. agentirc_cli-8.7.1/culture/credentials.py +0 -167
  188. agentirc_cli-8.7.1/culture/formatting.py +0 -19
  189. agentirc_cli-8.7.1/culture/learn_prompt.py +0 -299
  190. agentirc_cli-8.7.1/culture/mesh_config.py +0 -139
  191. agentirc_cli-8.7.1/culture/observer.py +0 -267
  192. agentirc_cli-8.7.1/culture/overview/__init__.py +0 -1
  193. agentirc_cli-8.7.1/culture/overview/collector.py +0 -469
  194. agentirc_cli-8.7.1/culture/overview/model.py +0 -80
  195. agentirc_cli-8.7.1/culture/overview/renderer_text.py +0 -267
  196. agentirc_cli-8.7.1/culture/overview/renderer_web.py +0 -272
  197. agentirc_cli-8.7.1/culture/overview/web/style.css +0 -88
  198. agentirc_cli-8.7.1/culture/persistence.py +0 -309
  199. agentirc_cli-8.7.1/culture/pidfile.py +0 -164
  200. agentirc_cli-8.7.1/culture/protocol/__init__.py +0 -0
  201. agentirc_cli-8.7.1/culture/protocol/commands.py +0 -43
  202. agentirc_cli-8.7.1/culture/protocol/extensions/audit.md +0 -109
  203. agentirc_cli-8.7.1/culture/protocol/extensions/events.md +0 -145
  204. agentirc_cli-8.7.1/culture/protocol/extensions/federation.md +0 -120
  205. agentirc_cli-8.7.1/culture/protocol/extensions/history.md +0 -117
  206. agentirc_cli-8.7.1/culture/protocol/extensions/icons.md +0 -117
  207. agentirc_cli-8.7.1/culture/protocol/extensions/rooms.md +0 -69
  208. agentirc_cli-8.7.1/culture/protocol/extensions/tags.md +0 -32
  209. agentirc_cli-8.7.1/culture/protocol/extensions/threads.md +0 -296
  210. agentirc_cli-8.7.1/culture/protocol/extensions/tracing.md +0 -37
  211. agentirc_cli-8.7.1/culture/protocol/message.py +0 -128
  212. agentirc_cli-8.7.1/culture/protocol/protocol-index.md +0 -9
  213. agentirc_cli-8.7.1/culture/protocol/replies.py +0 -52
  214. agentirc_cli-8.7.1/culture/skills/culture/SKILL.md +0 -370
  215. agentirc_cli-8.7.1/culture/telemetry/__init__.py +0 -34
  216. agentirc_cli-8.7.1/culture/telemetry/audit.py +0 -380
  217. agentirc_cli-8.7.1/culture/telemetry/context.py +0 -121
  218. agentirc_cli-8.7.1/culture/telemetry/metrics.py +0 -250
  219. agentirc_cli-8.7.1/culture/telemetry/tracing.py +0 -117
  220. agentirc_cli-8.7.1/docs/README.md +0 -10
  221. agentirc_cli-8.7.1/docs/agentirc/architecture-overview.md +0 -82
  222. agentirc_cli-8.7.1/docs/agentirc/audit.md +0 -154
  223. agentirc_cli-8.7.1/docs/agentirc/bots.md +0 -242
  224. agentirc_cli-8.7.1/docs/agentirc/events.md +0 -164
  225. agentirc_cli-8.7.1/docs/agentirc/harness-telemetry.md +0 -302
  226. agentirc_cli-8.7.1/docs/agentirc/index.md +0 -94
  227. agentirc_cli-8.7.1/docs/agentirc/otelcol-template.yaml +0 -25
  228. agentirc_cli-8.7.1/docs/agentirc/telemetry.md +0 -238
  229. agentirc_cli-8.7.1/docs/agentirc/why-agentirc.md +0 -32
  230. agentirc_cli-8.7.1/docs/culture/agent-lifecycle.md +0 -265
  231. agentirc_cli-8.7.1/docs/culture/choose-a-harness.md +0 -44
  232. agentirc_cli-8.7.1/docs/culture/features.md +0 -90
  233. agentirc_cli-8.7.1/docs/culture/index.md +0 -87
  234. agentirc_cli-8.7.1/docs/culture/mental-model.md +0 -74
  235. agentirc_cli-8.7.1/docs/culture/operate.md +0 -16
  236. agentirc_cli-8.7.1/docs/culture/patterns.md +0 -67
  237. agentirc_cli-8.7.1/docs/culture/quickstart.md +0 -137
  238. agentirc_cli-8.7.1/docs/culture/reflective-development.md +0 -134
  239. agentirc_cli-8.7.1/docs/culture/vision-patterns-index.md +0 -12
  240. agentirc_cli-8.7.1/docs/culture/vision.md +0 -85
  241. agentirc_cli-8.7.1/docs/culture/what-is-culture.md +0 -93
  242. agentirc_cli-8.7.1/docs/reference/architecture/agent-harness-spec.md +0 -498
  243. agentirc_cli-8.7.1/docs/reference/architecture/index.md +0 -27
  244. agentirc_cli-8.7.1/docs/reference/architecture/layers.md +0 -350
  245. agentirc_cli-8.7.1/docs/reference/architecture/subsites.md +0 -111
  246. agentirc_cli-8.7.1/docs/reference/architecture/threads.md +0 -210
  247. agentirc_cli-8.7.1/docs/reference/cli/afi.md +0 -95
  248. agentirc_cli-8.7.1/docs/reference/cli/commands.md +0 -193
  249. agentirc_cli-8.7.1/docs/reference/cli/devex.md +0 -129
  250. agentirc_cli-8.7.1/docs/reference/cli/index.md +0 -429
  251. agentirc_cli-8.7.1/docs/reference/console.md +0 -90
  252. agentirc_cli-8.7.1/docs/reference/harnesses/acp.md +0 -329
  253. agentirc_cli-8.7.1/docs/reference/harnesses/claude.md +0 -446
  254. agentirc_cli-8.7.1/docs/reference/harnesses/codex.md +0 -364
  255. agentirc_cli-8.7.1/docs/reference/harnesses/copilot.md +0 -352
  256. agentirc_cli-8.7.1/docs/reference/harnesses/index.md +0 -34
  257. agentirc_cli-8.7.1/docs/reference/index.md +0 -12
  258. agentirc_cli-8.7.1/docs/reference/server/architecture.md +0 -185
  259. agentirc_cli-8.7.1/docs/reference/server/config.md +0 -280
  260. agentirc_cli-8.7.1/docs/reference/server/deployment.md +0 -113
  261. agentirc_cli-8.7.1/docs/reference/server/index.md +0 -78
  262. agentirc_cli-8.7.1/docs/reference/server/security.md +0 -118
  263. agentirc_cli-8.7.1/docs/resources/github-copilot-sdk-instructions.md +0 -766
  264. agentirc_cli-8.7.1/docs/resources/positioning.md +0 -44
  265. agentirc_cli-8.7.1/docs/shared/concepts/federation.md +0 -71
  266. agentirc_cli-8.7.1/docs/shared/concepts/harnesses.md +0 -77
  267. agentirc_cli-8.7.1/docs/shared/concepts/humans-and-agents.md +0 -54
  268. agentirc_cli-8.7.1/docs/shared/concepts/index.md +0 -12
  269. agentirc_cli-8.7.1/docs/shared/concepts/persistence.md +0 -70
  270. agentirc_cli-8.7.1/docs/shared/concepts/rooms.md +0 -91
  271. agentirc_cli-8.7.1/docs/shared/demos/magic-demo.md +0 -87
  272. agentirc_cli-8.7.1/docs/shared/guides/first-session.md +0 -64
  273. agentirc_cli-8.7.1/docs/shared/guides/index.md +0 -12
  274. agentirc_cli-8.7.1/docs/shared/guides/join-as-human.md +0 -95
  275. agentirc_cli-8.7.1/docs/shared/guides/local-setup.md +0 -71
  276. agentirc_cli-8.7.1/docs/shared/guides/multi-machine.md +0 -85
  277. agentirc_cli-8.7.1/docs/shared/use-cases/01-pair-programming.md +0 -226
  278. agentirc_cli-8.7.1/docs/shared/use-cases/02-code-review-ensemble.md +0 -221
  279. agentirc_cli-8.7.1/docs/shared/use-cases/03-cross-server-delegation.md +0 -193
  280. agentirc_cli-8.7.1/docs/shared/use-cases/04-knowledge-propagation.md +0 -127
  281. agentirc_cli-8.7.1/docs/shared/use-cases/05-the-observer.md +0 -196
  282. agentirc_cli-8.7.1/docs/shared/use-cases/06-cross-server-ops.md +0 -173
  283. agentirc_cli-8.7.1/docs/shared/use-cases/07-supervisor-intervention.md +0 -266
  284. agentirc_cli-8.7.1/docs/shared/use-cases/08-apps-as-agents.md +0 -139
  285. agentirc_cli-8.7.1/docs/shared/use-cases/09-research-swarm.md +0 -233
  286. agentirc_cli-8.7.1/docs/shared/use-cases/10-agent-lifecycle.md +0 -416
  287. agentirc_cli-8.7.1/docs/shared/use-cases-index.md +0 -27
  288. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-19-layer1-core-irc.md +0 -1654
  289. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-21-layer5-agent-harness.md +0 -3120
  290. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-30-overview.md +0 -1635
  291. agentirc_cli-8.7.1/docs/superpowers/plans/2026-03-30-rooms-management.md +0 -3213
  292. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-02-conversation-threads.md +0 -1885
  293. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-02-ops-tooling.md +0 -1763
  294. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-04-culture-rename.md +0 -801
  295. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-05-docs-speak-culture.md +0 -1205
  296. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-06-console-chat.md +0 -2246
  297. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-09-decentralized-agent-config.md +0 -2131
  298. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-12-console-enhancements.md +0 -732
  299. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-15-mesh-events.md +0 -3252
  300. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-18-culture-dev-positioning.md +0 -812
  301. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-22-agex-integration.md +0 -999
  302. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-24-otel-foundation.md +0 -2159
  303. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-25-otel-federation.md +0 -229
  304. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-26-otel-metrics.md +0 -303
  305. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-27-otel-audit.md +0 -247
  306. agentirc_cli-8.7.1/docs/superpowers/plans/2026-04-28-otel-harness.md +0 -272
  307. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-19-agentirc-design.md +0 -411
  308. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-21-layer5-agent-harness-design.md +0 -484
  309. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-30-overview-design.md +0 -328
  310. agentirc_cli-8.7.1/docs/superpowers/specs/2026-03-30-rooms-management-design.md +0 -488
  311. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-02-conversation-threads-design.md +0 -326
  312. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-02-ops-tooling-design.md +0 -373
  313. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-03-bots-webhooks-design.md +0 -353
  314. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-04-culture-rename-design.md +0 -177
  315. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-05-docs-speak-culture-design.md +0 -277
  316. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-05-lifecycle-reframe-design.md +0 -219
  317. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-06-cli-reorganization-design.md +0 -212
  318. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-06-console-chat-design.md +0 -298
  319. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-07-entity-archiving-design.md +0 -305
  320. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-07-reflective-development-reframe-design.md +0 -165
  321. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-08-reflective-development-deepening-design.md +0 -179
  322. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-09-decentralized-agent-config-design.md +0 -361
  323. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-12-console-enhancements-design.md +0 -203
  324. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-15-mesh-events-design.md +0 -380
  325. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-17-sites-repositioning-design.md +0 -101
  326. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-18-culture-dev-positioning-design.md +0 -280
  327. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-22-agex-integration-design.md +0 -258
  328. agentirc_cli-8.7.1/docs/superpowers/specs/2026-04-24-otel-observability-design.md +0 -334
  329. agentirc_cli-8.7.1/favicon.ico +0 -0
  330. agentirc_cli-8.7.1/packages/agent-harness/README.md +0 -56
  331. agentirc_cli-8.7.1/packages/agent-harness/config.py +0 -299
  332. agentirc_cli-8.7.1/packages/agent-harness/culture.yaml +0 -28
  333. agentirc_cli-8.7.1/packages/agent-harness/daemon.py +0 -637
  334. agentirc_cli-8.7.1/packages/agent-harness/ipc.py +0 -38
  335. agentirc_cli-8.7.1/packages/agent-harness/irc_transport.py +0 -387
  336. agentirc_cli-8.7.1/packages/agent-harness/message_buffer.py +0 -71
  337. agentirc_cli-8.7.1/packages/agent-harness/skill/SKILL.md +0 -57
  338. agentirc_cli-8.7.1/packages/agent-harness/skill/irc_client.py +0 -325
  339. agentirc_cli-8.7.1/packages/agent-harness/socket_server.py +0 -129
  340. agentirc_cli-8.7.1/packages/agent-harness/telemetry.py +0 -315
  341. agentirc_cli-8.7.1/packages/agent-harness/webhook.py +0 -67
  342. agentirc_cli-8.7.1/plugins/claude-code/.claude-plugin/plugin.json +0 -6
  343. agentirc_cli-8.7.1/plugins/claude-code/skills/culture/SKILL.md +0 -363
  344. agentirc_cli-8.7.1/plugins/claude-code/skills/irc/SKILL.md +0 -187
  345. agentirc_cli-8.7.1/plugins/codex/skills/culture-irc/SKILL.md +0 -194
  346. agentirc_cli-8.7.1/pyproject.toml +0 -101
  347. agentirc_cli-8.7.1/robots.txt +0 -9
  348. agentirc_cli-8.7.1/sitemap-agentirc.html +0 -17
  349. agentirc_cli-8.7.1/sitemap-main.html +0 -19
  350. agentirc_cli-8.7.1/sitemap.html +0 -13
  351. agentirc_cli-8.7.1/sonar-project.properties +0 -32
  352. agentirc_cli-8.7.1/tests/__init__.py +0 -0
  353. agentirc_cli-8.7.1/tests/conftest.py +0 -389
  354. agentirc_cli-8.7.1/tests/harness/__init__.py +0 -0
  355. agentirc_cli-8.7.1/tests/harness/conftest.py +0 -89
  356. agentirc_cli-8.7.1/tests/harness/test_agent_runner_acp.py +0 -233
  357. agentirc_cli-8.7.1/tests/harness/test_agent_runner_claude.py +0 -449
  358. agentirc_cli-8.7.1/tests/harness/test_agent_runner_codex.py +0 -229
  359. agentirc_cli-8.7.1/tests/harness/test_agent_runner_copilot.py +0 -256
  360. agentirc_cli-8.7.1/tests/harness/test_all_backends_parity.py +0 -398
  361. agentirc_cli-8.7.1/tests/harness/test_daemon_telemetry.py +0 -72
  362. agentirc_cli-8.7.1/tests/harness/test_irc_transport_propagation.py +0 -447
  363. agentirc_cli-8.7.1/tests/harness/test_record_llm_call.py +0 -245
  364. agentirc_cli-8.7.1/tests/harness/test_telemetry_module.py +0 -264
  365. agentirc_cli-8.7.1/tests/telemetry/__init__.py +0 -0
  366. agentirc_cli-8.7.1/tests/telemetry/_fakes.py +0 -26
  367. agentirc_cli-8.7.1/tests/telemetry/_metrics_helpers.py +0 -75
  368. agentirc_cli-8.7.1/tests/telemetry/conftest.py +0 -33
  369. agentirc_cli-8.7.1/tests/telemetry/test_audit_emit.py +0 -145
  370. agentirc_cli-8.7.1/tests/telemetry/test_audit_federation.py +0 -132
  371. agentirc_cli-8.7.1/tests/telemetry/test_audit_lifecycle.py +0 -69
  372. agentirc_cli-8.7.1/tests/telemetry/test_audit_module.py +0 -306
  373. agentirc_cli-8.7.1/tests/telemetry/test_audit_parse_error.py +0 -177
  374. agentirc_cli-8.7.1/tests/telemetry/test_bot_event_dispatch_span.py +0 -138
  375. agentirc_cli-8.7.1/tests/telemetry/test_bot_run_span.py +0 -91
  376. agentirc_cli-8.7.1/tests/telemetry/test_config.py +0 -26
  377. agentirc_cli-8.7.1/tests/telemetry/test_config_load.py +0 -36
  378. agentirc_cli-8.7.1/tests/telemetry/test_context.py +0 -147
  379. agentirc_cli-8.7.1/tests/telemetry/test_dispatch_span.py +0 -45
  380. agentirc_cli-8.7.1/tests/telemetry/test_emit_event_span.py +0 -42
  381. agentirc_cli-8.7.1/tests/telemetry/test_federation_propagation.py +0 -141
  382. agentirc_cli-8.7.1/tests/telemetry/test_metrics_bots.py +0 -127
  383. agentirc_cli-8.7.1/tests/telemetry/test_metrics_clients.py +0 -79
  384. agentirc_cli-8.7.1/tests/telemetry/test_metrics_events.py +0 -81
  385. agentirc_cli-8.7.1/tests/telemetry/test_metrics_init.py +0 -58
  386. agentirc_cli-8.7.1/tests/telemetry/test_metrics_irc.py +0 -99
  387. agentirc_cli-8.7.1/tests/telemetry/test_metrics_s2s.py +0 -160
  388. agentirc_cli-8.7.1/tests/telemetry/test_metrics_trace_inbound.py +0 -127
  389. agentirc_cli-8.7.1/tests/telemetry/test_metrics_webhook.py +0 -148
  390. agentirc_cli-8.7.1/tests/telemetry/test_outbound_inject.py +0 -70
  391. agentirc_cli-8.7.1/tests/telemetry/test_parse_error.py +0 -33
  392. agentirc_cli-8.7.1/tests/telemetry/test_privmsg_span.py +0 -45
  393. agentirc_cli-8.7.1/tests/telemetry/test_s2s_dispatch_span.py +0 -156
  394. agentirc_cli-8.7.1/tests/telemetry/test_s2s_relay_span.py +0 -114
  395. agentirc_cli-8.7.1/tests/telemetry/test_s2s_session_span.py +0 -64
  396. agentirc_cli-8.7.1/tests/telemetry/test_server_init.py +0 -29
  397. agentirc_cli-8.7.1/tests/telemetry/test_server_link_inject.py +0 -124
  398. agentirc_cli-8.7.1/tests/telemetry/test_session_span.py +0 -105
  399. agentirc_cli-8.7.1/tests/telemetry/test_tracing.py +0 -49
  400. agentirc_cli-8.7.1/tests/telemetry/test_webhook_http_span.py +0 -45
  401. agentirc_cli-8.7.1/tests/test_acp_daemon.py +0 -256
  402. agentirc_cli-8.7.1/tests/test_agent_runner.py +0 -209
  403. agentirc_cli-8.7.1/tests/test_archive.py +0 -1008
  404. agentirc_cli-8.7.1/tests/test_bot.py +0 -174
  405. agentirc_cli-8.7.1/tests/test_bot_config.py +0 -98
  406. agentirc_cli-8.7.1/tests/test_bot_config_fires_event_toplevel.py +0 -114
  407. agentirc_cli-8.7.1/tests/test_bot_manager.py +0 -147
  408. agentirc_cli-8.7.1/tests/test_bots_integration.py +0 -161
  409. agentirc_cli-8.7.1/tests/test_channel.py +0 -131
  410. agentirc_cli-8.7.1/tests/test_channel_cli.py +0 -301
  411. agentirc_cli-8.7.1/tests/test_cli_afi.py +0 -111
  412. agentirc_cli-8.7.1/tests/test_cli_devex.py +0 -53
  413. agentirc_cli-8.7.1/tests/test_cli_introspect.py +0 -155
  414. agentirc_cli-8.7.1/tests/test_cli_passthrough.py +0 -146
  415. agentirc_cli-8.7.1/tests/test_codex_daemon.py +0 -284
  416. agentirc_cli-8.7.1/tests/test_connection.py +0 -135
  417. agentirc_cli-8.7.1/tests/test_console_chat_markdown.py +0 -241
  418. agentirc_cli-8.7.1/tests/test_console_client.py +0 -398
  419. agentirc_cli-8.7.1/tests/test_console_commands.py +0 -133
  420. agentirc_cli-8.7.1/tests/test_console_connection.py +0 -66
  421. agentirc_cli-8.7.1/tests/test_console_fixes_224_227.py +0 -202
  422. agentirc_cli-8.7.1/tests/test_console_icons.py +0 -227
  423. agentirc_cli-8.7.1/tests/test_console_integration.py +0 -65
  424. agentirc_cli-8.7.1/tests/test_console_status.py +0 -53
  425. agentirc_cli-8.7.1/tests/test_constants.py +0 -86
  426. agentirc_cli-8.7.1/tests/test_copilot_daemon.py +0 -253
  427. agentirc_cli-8.7.1/tests/test_credentials.py +0 -24
  428. agentirc_cli-8.7.1/tests/test_culture_config.py +0 -499
  429. agentirc_cli-8.7.1/tests/test_daemon.py +0 -95
  430. agentirc_cli-8.7.1/tests/test_daemon_config.py +0 -714
  431. agentirc_cli-8.7.1/tests/test_daemon_ipc.py +0 -160
  432. agentirc_cli-8.7.1/tests/test_discovery.py +0 -169
  433. agentirc_cli-8.7.1/tests/test_display.py +0 -226
  434. agentirc_cli-8.7.1/tests/test_events_basic.py +0 -292
  435. agentirc_cli-8.7.1/tests/test_events_bot_chain.py +0 -59
  436. agentirc_cli-8.7.1/tests/test_events_bot_trigger.py +0 -99
  437. agentirc_cli-8.7.1/tests/test_events_cap_fallback.py +0 -59
  438. agentirc_cli-8.7.1/tests/test_events_catalog.py +0 -70
  439. agentirc_cli-8.7.1/tests/test_events_federation.py +0 -110
  440. agentirc_cli-8.7.1/tests/test_events_history.py +0 -64
  441. agentirc_cli-8.7.1/tests/test_events_lifecycle.py +0 -343
  442. agentirc_cli-8.7.1/tests/test_events_reserved_nick.py +0 -68
  443. agentirc_cli-8.7.1/tests/test_federation.py +0 -1251
  444. agentirc_cli-8.7.1/tests/test_filter_dsl.py +0 -99
  445. agentirc_cli-8.7.1/tests/test_history.py +0 -553
  446. agentirc_cli-8.7.1/tests/test_http_listener.py +0 -147
  447. agentirc_cli-8.7.1/tests/test_integration_layer5.py +0 -109
  448. agentirc_cli-8.7.1/tests/test_ipc.py +0 -55
  449. agentirc_cli-8.7.1/tests/test_irc_transport.py +0 -314
  450. agentirc_cli-8.7.1/tests/test_irc_transport_tags.py +0 -106
  451. agentirc_cli-8.7.1/tests/test_learn_prompt.py +0 -54
  452. agentirc_cli-8.7.1/tests/test_link_reconnect.py +0 -222
  453. agentirc_cli-8.7.1/tests/test_manifest_config.py +0 -317
  454. agentirc_cli-8.7.1/tests/test_mention_alias.py +0 -156
  455. agentirc_cli-8.7.1/tests/test_mention_target_cleanup.py +0 -135
  456. agentirc_cli-8.7.1/tests/test_mention_warning.py +0 -62
  457. agentirc_cli-8.7.1/tests/test_mentions.py +0 -155
  458. agentirc_cli-8.7.1/tests/test_mesh_config.py +0 -192
  459. agentirc_cli-8.7.1/tests/test_mesh_readiness.py +0 -93
  460. agentirc_cli-8.7.1/tests/test_message.py +0 -79
  461. agentirc_cli-8.7.1/tests/test_message_buffer.py +0 -71
  462. agentirc_cli-8.7.1/tests/test_message_tags.py +0 -75
  463. agentirc_cli-8.7.1/tests/test_messaging.py +0 -103
  464. agentirc_cli-8.7.1/tests/test_migrate_cli.py +0 -128
  465. agentirc_cli-8.7.1/tests/test_modes.py +0 -327
  466. agentirc_cli-8.7.1/tests/test_overview_cli.py +0 -137
  467. agentirc_cli-8.7.1/tests/test_overview_collector.py +0 -161
  468. agentirc_cli-8.7.1/tests/test_overview_model.py +0 -171
  469. agentirc_cli-8.7.1/tests/test_overview_renderer.py +0 -304
  470. agentirc_cli-8.7.1/tests/test_overview_web.py +0 -179
  471. agentirc_cli-8.7.1/tests/test_persistence.py +0 -105
  472. agentirc_cli-8.7.1/tests/test_persistence_timeout.py +0 -59
  473. agentirc_cli-8.7.1/tests/test_pidfile.py +0 -122
  474. agentirc_cli-8.7.1/tests/test_poll_loop.py +0 -129
  475. agentirc_cli-8.7.1/tests/test_register_cli.py +0 -139
  476. agentirc_cli-8.7.1/tests/test_room_persistence.py +0 -75
  477. agentirc_cli-8.7.1/tests/test_rooms.py +0 -729
  478. agentirc_cli-8.7.1/tests/test_rooms_federation.py +0 -63
  479. agentirc_cli-8.7.1/tests/test_rooms_integration.py +0 -110
  480. agentirc_cli-8.7.1/tests/test_server_icon_skill.py +0 -214
  481. agentirc_cli-8.7.1/tests/test_setup_update_cli.py +0 -185
  482. agentirc_cli-8.7.1/tests/test_skill_client.py +0 -96
  483. agentirc_cli-8.7.1/tests/test_skill_docs.py +0 -130
  484. agentirc_cli-8.7.1/tests/test_skills.py +0 -212
  485. agentirc_cli-8.7.1/tests/test_socket_path_convergence.py +0 -153
  486. agentirc_cli-8.7.1/tests/test_socket_server.py +0 -74
  487. agentirc_cli-8.7.1/tests/test_supervisor.py +0 -258
  488. agentirc_cli-8.7.1/tests/test_template_engine.py +0 -80
  489. agentirc_cli-8.7.1/tests/test_thread_buffer.py +0 -55
  490. agentirc_cli-8.7.1/tests/test_threads.py +0 -384
  491. agentirc_cli-8.7.1/tests/test_virtual_client.py +0 -176
  492. agentirc_cli-8.7.1/tests/test_wait_for_port.py +0 -89
  493. agentirc_cli-8.7.1/tests/test_webhook.py +0 -85
  494. agentirc_cli-8.7.1/tests/test_welcome_bot.py +0 -87
  495. agentirc_cli-8.7.1/uv.lock +0 -2717
  496. {agentirc_cli-8.7.1/culture/agentirc → agentirc_cli-9.0.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