agentirc-cli 9.5.0a2__tar.gz → 9.6.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 (122) hide show
  1. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/CHANGELOG.md +48 -0
  2. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/CLAUDE.md +18 -14
  3. agentirc_cli-9.6.0/PKG-INFO +321 -0
  4. agentirc_cli-9.6.0/README.md +266 -0
  5. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/bots/http_listener.py +9 -1
  6. agentirc_cli-9.6.0/agentirc/_internal/event_subscriptions.py +282 -0
  7. agentirc_cli-9.6.0/agentirc/_internal/virtual_client.py +32 -0
  8. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/channel.py +32 -5
  9. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/client.py +177 -16
  10. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/ircd.py +25 -28
  11. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/server_link.py +1 -1
  12. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/skills/rooms.py +1 -1
  13. {agentirc_cli-9.5.0a2/agentirc/_internal → agentirc_cli-9.6.0/agentirc}/virtual_client.py +36 -17
  14. agentirc_cli-9.6.0/docs/api-stability.md +417 -0
  15. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/docs/cli.md +1 -1
  16. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/docs/deployment.md +11 -3
  17. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/docs/extension-api.md +5 -5
  18. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/pyproject.toml +15 -3
  19. agentirc_cli-9.6.0/tests/test_api_stability_embedding.py +138 -0
  20. agentirc_cli-9.6.0/tests/test_bot_capability.py +204 -0
  21. agentirc_cli-9.6.0/tests/test_event_subscriptions.py +335 -0
  22. agentirc_cli-9.6.0/tests/test_eventpub.py +194 -0
  23. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/uv.lock +1 -1
  24. agentirc_cli-9.5.0a2/PKG-INFO +0 -57
  25. agentirc_cli-9.5.0a2/README.md +0 -2
  26. agentirc_cli-9.5.0a2/docs/api-stability.md +0 -290
  27. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/SKILL.md +0 -0
  28. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/scripts/portability-lint.sh +0 -0
  29. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/scripts/pr-batch.sh +0 -0
  30. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/scripts/pr-comments.sh +0 -0
  31. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/scripts/pr-reply.sh +0 -0
  32. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/scripts/pr-sonar.sh +0 -0
  33. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/scripts/pr-status.sh +0 -0
  34. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills/pr-review/scripts/workflow.sh +0 -0
  35. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.claude/skills.local.yaml.example +0 -0
  36. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.github/workflows/publish.yml +0 -0
  37. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.github/workflows/tests.yml +0 -0
  38. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/.gitignore +0 -0
  39. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/LICENSE +0 -0
  40. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/__init__.py +0 -0
  41. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/__main__.py +0 -0
  42. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/__init__.py +0 -0
  43. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/aio.py +0 -0
  44. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/bots/__init__.py +0 -0
  45. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/bots/bot_manager.py +0 -0
  46. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/cli_shared/__init__.py +0 -0
  47. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/cli_shared/constants.py +0 -0
  48. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/cli_shared/mesh.py +0 -0
  49. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/constants.py +0 -0
  50. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/pidfile.py +0 -0
  51. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/protocol/__init__.py +0 -0
  52. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/protocol/message.py +0 -0
  53. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/protocol/replies.py +0 -0
  54. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/telemetry/__init__.py +0 -0
  55. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/telemetry/audit.py +0 -0
  56. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/telemetry/context.py +0 -0
  57. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/telemetry/metrics.py +0 -0
  58. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/_internal/telemetry/tracing.py +0 -0
  59. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/cli.py +0 -0
  60. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/config.py +0 -0
  61. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/events.py +0 -0
  62. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/history_store.py +0 -0
  63. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/protocol.py +0 -0
  64. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/remote_client.py +0 -0
  65. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/room_store.py +0 -0
  66. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/rooms_util.py +0 -0
  67. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/skill.py +0 -0
  68. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/skills/__init__.py +0 -0
  69. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/skills/history.py +0 -0
  70. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/skills/icon.py +0 -0
  71. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/skills/threads.py +0 -0
  72. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/agentirc/thread_store.py +0 -0
  73. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/docs/steward/onboarding.md +0 -0
  74. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/docs/superpowers/specs/2026-04-30-bootstrap-design.md +0 -0
  75. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/docs/superpowers/specs/2026-05-01-bot-extension-api-design.md +0 -0
  76. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/docs/superpowers/specs/2026-05-01-task14-audit.md +0 -0
  77. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/__init__.py +0 -0
  78. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/_helpers.py +0 -0
  79. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/conftest.py +0 -0
  80. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/__init__.py +0 -0
  81. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/_fakes.py +0 -0
  82. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/_metrics_helpers.py +0 -0
  83. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_audit_emit.py +0 -0
  84. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_audit_lifecycle.py +0 -0
  85. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_audit_module.py +0 -0
  86. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_audit_parse_error.py +0 -0
  87. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_config.py +0 -0
  88. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_dispatch_span.py +0 -0
  89. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_emit_event_span.py +0 -0
  90. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_metrics_init.py +0 -0
  91. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_metrics_s2s.py +0 -0
  92. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_outbound_inject.py +0 -0
  93. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_parse_error.py +0 -0
  94. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_s2s_relay_span.py +0 -0
  95. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_server_init.py +0 -0
  96. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_server_link_inject.py +0 -0
  97. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/telemetry/test_tracing.py +0 -0
  98. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_channel.py +0 -0
  99. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_cli.py +0 -0
  100. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_config_loader.py +0 -0
  101. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_connection.py +0 -0
  102. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_discovery.py +0 -0
  103. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_events_basic.py +0 -0
  104. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_events_catalog.py +0 -0
  105. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_events_federation.py +0 -0
  106. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_events_history.py +0 -0
  107. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_events_lifecycle.py +0 -0
  108. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_events_reserved_nick.py +0 -0
  109. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_federation.py +0 -0
  110. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_history.py +0 -0
  111. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_link_reconnect.py +0 -0
  112. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_mentions.py +0 -0
  113. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_messaging.py +0 -0
  114. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_modes.py +0 -0
  115. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_protocol_bot_exports.py +0 -0
  116. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_room_persistence.py +0 -0
  117. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_rooms_federation.py +0 -0
  118. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_rooms_integration.py +0 -0
  119. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_server_icon_skill.py +0 -0
  120. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_skills.py +0 -0
  121. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_threads.py +0 -0
  122. {agentirc_cli-9.5.0a2 → agentirc_cli-9.6.0}/tests/test_wire_format_envelope.py +0 -0
@@ -4,6 +4,54 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/).
6
6
 
7
+ ## [9.6.0] - 2026-05-02
8
+
9
+ Closes [agentculture/agentirc#22](https://github.com/agentculture/agentirc/issues/22) — promote the in-process embedding API. Unblocks [agentculture/culture#308](https://github.com/agentculture/culture/issues/308) Phase A2-Bridge: culture's `culture/bots/virtual_client.py` (231 LOC, near-line-for-line copy of agentirc's internal `VirtualClient`) collapses to a thin wrapper around the public class, and `culture/cli/server.py:_run_server` can construct an `agentirc.ircd.IRCd` directly instead of going through the `agentirc serve` subprocess.
10
+
11
+ ### Added
12
+
13
+ - **`agentirc.virtual_client.VirtualClient`** is now public, semver-tracked. `from agentirc.virtual_client import VirtualClient` is the canonical import. Class behaviour is unchanged — the file moved from `agentirc/_internal/virtual_client.py` to `agentirc/virtual_client.py` with no edits to the class body.
14
+ - **`agentirc.ircd.IRCd`** is now public, semver-tracked. The locked-in surface is the constructor (`IRCd(config: ServerConfig)`), the lifecycle methods (`await ircd.start()`, `await ircd.stop()`), `await ircd.emit_event(event)`, and the `subscription_registry`, `clients`, `channels`, `config`, and `system_client` attributes. Other attributes on `IRCd` remain implementation detail and may change without a major bump.
15
+ - **Embedding worked example** in `docs/api-stability.md` showing how to construct an `IRCd` in-process, register a `VirtualClient`, and run until shutdown. Includes a member-by-member breakdown of the public `IRCd` surface and the `VirtualClient` constructor / method signatures.
16
+
17
+ ### Deprecated
18
+
19
+ - **`agentirc._internal.virtual_client.VirtualClient`** still resolves via a transitional re-export module that emits `DeprecationWarning` on import. Removal is scheduled for 10.0.0. All in-tree call sites (`ircd.py`, `server_link.py`, `channel.py`, `skills/rooms.py`) have been retargeted at the public path so the shim never fires under our own tests.
20
+
21
+ ### Notes
22
+
23
+ - This release is purely additive at the Python level. No protocol changes, no CLI changes, no behaviour changes. The wire surface (the `agentirc.io/bot` CAP, `EVENTSUB`/`EVENTUNSUB`/`EVENT`/`EVENTERR`/`EVENTPUB` verbs, the canonical 5-field envelope) is identical to 9.5.0 and stays byte-locked.
24
+ - Citation manifest updated: `culture-virtual-client` now targets `agentirc/virtual_client.py`. New entry `agentirc-internal-virtual-client-shim` covers the deprecation re-export.
25
+
26
+ ## [9.5.0] - 2026-05-02
27
+
28
+ Closes [agentculture/agentirc#15](https://github.com/agentculture/agentirc/issues/15) — out-of-process bot extension API. Unblocks [agentculture/culture#308](https://github.com/agentculture/culture/issues/308) Phase A2 (bot rewrite against the public API).
29
+
30
+ ### Added
31
+
32
+ - **IRCv3 `agentirc.io/bot` capability.** Advertised in `CAP LS` output. When negotiated via `CAP REQ`, gates four behaviours: silent JOIN/PART/QUIT broadcasts (other channel members see nothing), no auto-op on a fresh-channel first-joiner, `+` prefix in NAMES output, `B` flag in WHO output. Channel membership is added normally; events still fire (subscribers see them via `EVENTSUB`).
33
+ - **`EVENTSUB` / `EVENTUNSUB` / `EVENT` / `EVENTERR` IRC verbs** for streaming events to bots out-of-process. `EVENTSUB <sub-id> [type=<glob>] [channel=<name>] [nick=<glob>]`: filters AND-ed; `type` and `nick` accept `fnmatch`-style globs; `channel` accepts an exact name, `*`, or empty (nick-scoped only). Multiple concurrent subscriptions per client are allowed. Wire format: `:server EVENT <sub-id> <type> <channel-or-*> <nick> :<base64-json-envelope>` carrying the canonical 5-field envelope. Per-subscription bounded queue (default 1024); on overflow the server emits `EVENTERR <sub-id> :backpressure-overflow` and drops the subscription (connection stays open). Subscriptions die on client disconnect.
34
+ - **`EVENTPUB` IRC verb** for bots to emit custom-typed events back into the stream. `EVENTPUB <type> <channel-or-*> :<base64-json-data>`. Type validated against `EVENT_TYPE_RE` (dotted lowercase, ≥1 dot — single-segment names like `message` and `topic` are reserved for built-in vocabulary). Server fills `nick` from the bot's connection nick (not spoofable) and `timestamp` from `time.time()` so federation peers see consistent clocks. `_`-prefixed keys are stripped from the payload before emit.
35
+ - New internal module `agentirc._internal.event_subscriptions` with the `Subscription` dataclass and `SubscriptionRegistry`. `IRCd.subscription_registry` exposes the registry; `IRCd.emit_event` dispatches every event through it.
36
+ - `agentirc.protocol.SEVENT` verb constant (added in 9.5.0a2; reaffirmed here).
37
+
38
+ ### Changed
39
+
40
+ - **`webhook_port` is no longer bound by `IRCd.start()`.** The field stays in `ServerConfig` so culture's `~/.culture/server.yaml` keeps loading unchanged, but `agentirc` no longer instantiates the HTTP listener. Consumers that need webhook→bot dispatch host their own listener (see `docs/deployment.md`). No deprecation warning at runtime — the docs change is sufficient.
41
+ - `Channel.add()` no longer auto-ops bot-CAP clients (real or `VirtualClient`). A bot joining an empty channel stays unprivileged; the next human becomes op.
42
+ - `Channel.get_prefix()` returns `+` for bot-CAP members in NAMES output.
43
+ - `Client._build_who_flags()` adds the `B` flag for bot-CAP members in WHO output (composes with `H` and `@`/`+`).
44
+ - `VirtualClient` gains a class-level `caps = frozenset({"agentirc.io/bot", "message-tags"})` so the in-process system bot is treated identically to a real CAP-bot.
45
+ - `Client._handle_cap` `CAP LS` reply now lists supported caps from a class-level `_SUPPORTED_CAPS` frozenset (centralised; removing a cap is a major bump).
46
+ - `agentirc/_internal/bots/http_listener.py` module docstring notes the no-op stub is scheduled for removal in 9.6.0.
47
+
48
+ ### Notes
49
+
50
+ - This is the **final slice** of the bot extension API. `9.5.0a1` shipped the public `agentirc.protocol` declarations; `9.5.0a2` switched the federation wire format to the 5-field envelope; this release wires the actual behaviour.
51
+ - **Federation interop unchanged from 9.5.0a2.** 9.4→9.5 federation works (sniff tolerance); 9.5→9.4 emit breaks until peers upgrade.
52
+ - The `agentirc.skill.{Event, EventType}` re-export shim from 9.5.0a1 stays through the 9.x line; removal is scheduled for 10.0.0.
53
+ - The `agentirc/_internal/bots/` synthesize stubs (`bot_manager.py`, `http_listener.py`) stay through the 9.5.x cycle; removal is scheduled for 9.6.0 once Phase A2 confirms no consumer imports them.
54
+
7
55
  ## [9.5.0a2] - 2026-05-02
8
56
 
9
57
  ### Changed
@@ -2,20 +2,22 @@
2
2
 
3
3
  This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
4
 
5
- ## Current state: bootstrap complete (9.4.0 released)
5
+ ## Current state: bootstrap closed; bot extension API + in-process embedding API shipped (9.6.0 released)
6
6
 
7
- This repo is the agentirc server-core extraction out of the sibling project [`culture`](https://github.com/agentculture/culture). As of 9.4.0 (tagged at `5590256` and live on PyPI):
7
+ This repo is the agentirc server-core extraction out of the sibling project [`culture`](https://github.com/agentculture/culture). The bootstrap is closed; 9.0.0 through 9.6.0 are live on PyPI. The most recent ship is the in-process embedding API (9.6.0, closed [#22](https://github.com/agentculture/agentirc/issues/22)) — promoting `agentirc.ircd.IRCd` and `agentirc.virtual_client.VirtualClient` to public, semver-tracked status so culture's Phase A2-Bridge can construct an IRCd in-process and host bots inside it without going through the `agentirc serve` subprocess. The previous ship was the out-of-process bot extension API (9.5.0, closed [#15](https://github.com/agentculture/agentirc/issues/15)). The repo currently contains:
8
8
 
9
9
  - **Server-core** (`agentirc/{ircd,server_link,channel,events,skill,remote_client,…}.py`, `agentirc/skills/{rooms,threads,history,icon}.py`) — vendored from `culture@df50942` via the `cite-don't-copy` pattern (see `[tool.citation]` in `pyproject.toml`).
10
10
  - **Client transport** (`agentirc/client.py`) — vendored from `culture/agentirc/client.py` in PR-B2.
11
11
  - **Public CLI** (`agentirc/cli.py`) — real verb dispatch extracted from `culture/cli/server.py`. Verbs: `serve` (foreground, no PID; for systemd `Type=simple` and containers), `start`/`stop`/`status` (lifecycle), `restart`, `link` (peer-spec validator), `logs` (cat / tail of `~/.culture/logs/server-<name>.log`), `version`. Since 9.4.0, `serve`/`start`/`restart` overlay CLI flags on `--config` YAML (precedence: CLI > YAML > built-in default).
12
- - **Public config** (`agentirc/config.py`) — `ServerConfig`, `LinkConfig`, `TelemetryConfig` dataclasses plus the `ServerConfig.from_yaml(path)` classmethod (added 9.4.0). Recognises `server`/`telemetry`/`links`/`webhook_port`/`data_dir`/`system_bots` keys; silently ignores culture-only keys (`supervisor`, `agents`, `buffer_size`, etc.) so the same `~/.culture/server.yaml` can drive both daemons.
13
- - **Public protocol** (`agentirc/protocol.py`) — verb name constants, numerics, IRCv3 tag names. Wire-format quirks (`ROOMETAEND`, `ROOMETASET` typos, `ERR_NOSUCHCHANNEL` semantic misuse, `STHREAD` verb collapse) preserved verbatim — they need coordinated cross-repo bumps to fix.
14
- - **Test suite** (PR-B3, 9.3.0; +13 in 9.4.0) 36 tests vendored from `culture@df50942` (~6.5kloc) plus 13 new agentirc-native tests in `tests/test_config_loader.py`. 328 tests run under `pytest -n auto` in ~28s on default workers. Three telemetry tests (`test_bot_event_dispatch_span`, `test_bot_run_span`, `test_metrics_bots`) and `test_welcome_bot` stay in culture because they depend on the real `BotManager`.
15
- - **Internal support** (`agentirc/_internal/`) `aio`, `constants`, `protocol/`, `telemetry/`, `virtual_client`, `pidfile`, `cli_shared/`, `bots/` stubs.
16
- - **Bootstrap docs** (PR-B4, 9.4.0) — `docs/api-stability.md` (3 public modules + semver contract), `docs/cli.md` (verb table, flag reference, exit codes, YAML/CLI precedence, agentirc-vs-culture diff table), `docs/deployment.md` (on-disk footprint, systemd `Type=simple` example, container deployment, multi-host federation, log rotation, coexistence with culture, backup).
12
+ - **Public config** (`agentirc/config.py`) — `ServerConfig`, `LinkConfig`, `TelemetryConfig` dataclasses plus the `ServerConfig.from_yaml(path)` classmethod (added 9.4.0). Recognises `server`/`telemetry`/`links`/`webhook_port`/`data_dir`/`system_bots`/`event_subscription_queue_max` keys; silently ignores culture-only keys (`supervisor`, `agents`, `buffer_size`, etc.) so the same `~/.culture/server.yaml` can drive both daemons. Since 9.5.0, `webhook_port` is accepted but no longer bound by `IRCd.start()` — the field stays in `ServerConfig` for backward compat with culture's YAML, but consumers needing webhook→bot dispatch host their own listener.
13
+ - **Public protocol** (`agentirc/protocol.py`) — verb name constants, numerics, IRCv3 tag names. Since 9.5.0 also exports the bot extension surface: `Event` dataclass, `EventType` (`StrEnum`), 20 `EVENT_TYPE_*` constants, `EVENTSUB`/`EVENTUNSUB`/`EVENT`/`EVENTERR`/`EVENTPUB` verb constants, `SEVENT` federation verb, and `BOT_CAP = "agentirc.io/bot"`. Wire-format quirks (`ROOMETAEND`, `ROOMETASET` typos, `ERR_NOSUCHCHANNEL` semantic misuse, `STHREAD` verb collapse) preserved verbatim — they need coordinated cross-repo bumps to fix.
14
+ - **Bot extension API (9.5.0)** IRCv3 `agentirc.io/bot` capability gates four behaviours when negotiated via `CAP REQ`: silent JOIN/PART/QUIT broadcasts, no auto-op on a fresh-channel first-joiner, `+` prefix in NAMES output, `B` flag in WHO output. `EVENTSUB <sub-id> [type=<glob>] [channel=<name>] [nick=<glob>]` opens a streaming subscription; `EVENTPUB <type> <channel-or-*> :<base64-json-data>` emits a custom-typed event back into the stream (server fills `nick` and `timestamp` so federation peers see consistent values). Per-subscription bounded queue (default 1024); on overflow the server emits `EVENTERR <sub-id> :backpressure-overflow` and drops the subscription. Quick reference at [`docs/extension-api.md`](docs/extension-api.md); design spec at [`docs/superpowers/specs/2026-05-01-bot-extension-api-design.md`](docs/superpowers/specs/2026-05-01-bot-extension-api-design.md).
15
+ - **Test suite** — 36 tests vendored from `culture@df50942` (~6.5kloc) plus agentirc-native tests in `tests/test_config_loader.py` and `tests/test_wire_format_envelope.py` (the 9.5.0a2 golden-file lock-in). `pytest -n auto` in ~30s on default workers. Three telemetry tests (`test_bot_event_dispatch_span`, `test_bot_run_span`, `test_metrics_bots`) and `test_welcome_bot` stay in culture because they depend on the real `BotManager`.
16
+ - **In-process embedding API (9.6.0)** — `agentirc.ircd.IRCd` and `agentirc.virtual_client.VirtualClient` promoted to the public surface. The `IRCd` public contract is the constructor (`IRCd(config: ServerConfig)`), `await ircd.start()`/`stop()`, `await ircd.emit_event(event)`, plus the `subscription_registry`/`clients`/`channels`/`config`/`system_client` attributes; everything else on `IRCd` remains implementation detail. `VirtualClient` moved from `agentirc/_internal/virtual_client.py` to `agentirc/virtual_client.py` with no body edits; the legacy import path resolves via a deprecation re-export (removal in 10.0.0). Worked example + member breakdown live in [`docs/api-stability.md`](docs/api-stability.md#embedding-agentirc-in-process). Same wire surface as 9.5.0; no protocol changes.
17
+ - **Internal support** (`agentirc/_internal/`) — `aio`, `constants`, `protocol/`, `telemetry/`, `pidfile`, `cli_shared/`, `bots/` stubs, `event_subscriptions/` (added 9.5.0). The `_internal/virtual_client.py` module remains as a deprecation re-export of the now-public `agentirc.virtual_client.VirtualClient`; emits `DeprecationWarning` on import; scheduled for removal in 10.0.0.
18
+ - **Bootstrap docs** (PR-B4, 9.4.0) — `docs/api-stability.md` (3 public modules + semver contract), `docs/cli.md` (verb table, flag reference, exit codes, YAML/CLI precedence, agentirc-vs-culture diff table), `docs/deployment.md` (on-disk footprint, systemd `Type=simple` example, container deployment, multi-host federation, log rotation, coexistence with culture, backup), and `docs/extension-api.md` (bot-author quick reference, added 9.5.0). Public-facing `README.md` rewritten for issue [#19](https://github.com/agentculture/agentirc/issues/19).
17
19
 
18
- End-to-end verified: `agentirc start --port <p>` boots a real IRCd, TCP NICK/USER handshake returns `001 RPL_WELCOME`, `agentirc stop` shuts cleanly. `agentirc serve --config server.yaml --port 9999` correctly overlays CLI flag on YAML. `pip install agentirc-cli==9.4.0` from real PyPI in a clean venv produces both `agentirc` and `agentirc-cli` binaries; both reach the same `agentirc.cli:main` entry point. Acceptance audit recorded at [`docs/superpowers/specs/2026-05-01-task14-audit.md`](docs/superpowers/specs/2026-05-01-task14-audit.md). Culture-side cutover unblocked via [agentculture/culture#308](https://github.com/agentculture/culture/issues/308).
20
+ End-to-end verified: `agentirc start --port <p>` boots a real IRCd, TCP NICK/USER handshake returns `001 RPL_WELCOME`, `agentirc stop` shuts cleanly. `agentirc serve --config server.yaml --port 9999` correctly overlays CLI flag on YAML. `pip install agentirc-cli==9.5.0` from real PyPI in a clean venv produces both `agentirc` and `agentirc-cli` binaries; both reach the same `agentirc.cli:main` entry point. Acceptance audit for the bootstrap recorded at [`docs/superpowers/specs/2026-05-01-task14-audit.md`](docs/superpowers/specs/2026-05-01-task14-audit.md). Culture-side cutover unblocked via [agentculture/culture#308](https://github.com/agentculture/culture/issues/308).
19
21
 
20
22
  **Outstanding follow-ups (non-blocking; the bootstrap itself is closed):**
21
23
  - **Cross-repo wire-format fixes (Track A)** — [#7](https://github.com/agentculture/agentirc/issues/7) (`ROOMETAEND`/`ROOMETASET` typos), [#8](https://github.com/agentculture/agentirc/issues/8) (`ERR_NOSUCHCHANNEL` overload), [#9](https://github.com/agentculture/agentirc/issues/9) (`STHREAD` verb collapse). Each requires culture-side change first then agentirc bump.
@@ -59,13 +61,15 @@ When migrating tests, the rule is: pure server tests come here, transport tests
59
61
 
60
62
  ## Public API contract (semver-tracked)
61
63
 
62
- Only three modules are public. Everything else is internal and may be refactored without a major bump.
64
+ Five modules are public. Everything else is internal and may be refactored without a major bump.
63
65
 
64
- | Module | Members |
65
- |---|---|
66
- | `agentirc.config` | `ServerConfig`, `LinkConfig`, `TelemetryConfig` |
67
- | `agentirc.cli` | `main()`, `dispatch(argv) -> int` |
68
- | `agentirc.protocol` | verb name constants, numeric reply codes, extension tag names |
66
+ | Module | Members | Since |
67
+ |---|---|---|
68
+ | `agentirc.config` | `ServerConfig`, `LinkConfig`, `TelemetryConfig` | 9.0.0 |
69
+ | `agentirc.cli` | `main()`, `dispatch(argv) -> int` | 9.2.0 |
70
+ | `agentirc.protocol` | verb name constants, numeric reply codes, extension tag names; bot extension surface (`Event`, `EventType`, `EVENT_TYPE_*`, `EVENTSUB`/`EVENTUNSUB`/`EVENT`/`EVENTERR`/`EVENTPUB`/`SEVENT` verbs, `BOT_CAP`) | 9.2.0 (extended 9.5.0) |
71
+ | `agentirc.ircd` | `IRCd` (constructor + `start`/`stop`/`emit_event`/`subscription_registry`/`clients`/`channels`/`config`/`system_client`) | 9.6.0 |
72
+ | `agentirc.virtual_client` | `VirtualClient` | 9.6.0 |
69
73
 
70
74
  `agentirc.cli.dispatch(argv)` is the function `culture`'s `culture server` shim calls — it must accept the exact same flag set, exit codes, and stderr formatting that `culture server` produces today. Do not "improve" CLI ergonomics during the bootstrap; that breaks the transparency contract culture relies on. `dispatch()` returns `int` on successful command dispatch and lets argparse's `SystemExit` propagate on `--help`/`--version`/parse-errors per Python convention; in-process callers (i.e. culture's shim) must catch `SystemExit` themselves or use `subprocess`.
71
75
 
@@ -0,0 +1,321 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentirc-cli
3
+ Version: 9.6.0
4
+ Summary: Agent-friendly IRCd: server core for AI agent meshes
5
+ Project-URL: Homepage, https://github.com/agentculture/agentirc
6
+ Project-URL: Issues, https://github.com/agentculture/agentirc/issues
7
+ Author: Ori Nachum
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 agentculture
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ License-File: LICENSE
30
+ Keywords: agents,culture,irc,ircd,mesh
31
+ Classifier: Development Status :: 3 - Alpha
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Programming Language :: Python :: 3.13
38
+ Classifier: Topic :: Communications :: Chat :: Internet Relay Chat
39
+ Requires-Python: >=3.11
40
+ Requires-Dist: opentelemetry-api>=1.22
41
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.22
42
+ Requires-Dist: opentelemetry-sdk>=1.22
43
+ Requires-Dist: pyyaml>=6.0
44
+ Provides-Extra: dev
45
+ Requires-Dist: bandit; extra == 'dev'
46
+ Requires-Dist: black; extra == 'dev'
47
+ Requires-Dist: citation-cli; extra == 'dev'
48
+ Requires-Dist: flake8; extra == 'dev'
49
+ Requires-Dist: isort; extra == 'dev'
50
+ Requires-Dist: pylint; extra == 'dev'
51
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
52
+ Requires-Dist: pytest-xdist>=3; extra == 'dev'
53
+ Requires-Dist: pytest>=8; extra == 'dev'
54
+ Description-Content-Type: text/markdown
55
+
56
+ # AgentIRC
57
+
58
+ [![PyPI version](https://img.shields.io/pypi/v/agentirc-cli.svg)](https://pypi.org/project/agentirc-cli/)
59
+ [![Python versions](https://img.shields.io/pypi/pyversions/agentirc-cli.svg)](https://pypi.org/project/agentirc-cli/)
60
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
61
+
62
+ **Agent-friendly IRCd for AI agent meshes.**
63
+
64
+ `agentirc` is a standalone IRC runtime for human-and-agent rooms. It speaks
65
+ classic IRC ([RFC 2812](https://datatracker.ietf.org/doc/html/rfc2812))
66
+ plus IRCv3 message-tags, room/thread/tag skill verbs, server-to-server
67
+ federation with trust levels, and an out-of-process bot extension API
68
+ (`agentirc.io/bot` capability + `EVENTSUB`/`EVENTUNSUB`/`EVENTPUB` verbs).
69
+ It ships with a small, semver-tracked Python API (`agentirc.config`,
70
+ `agentirc.cli`, `agentirc.protocol`) so other tools can drive an IRCd as a
71
+ library, and a CLI (`agentirc serve`, `agentirc start`, …) for operators.
72
+
73
+ It is the runtime/protocol layer extracted from
74
+ [`culture`](https://github.com/agentculture/culture), the AgentCulture
75
+ agent-mesh project. You don't need culture to use it — `pip install
76
+ agentirc-cli` is a complete IRCd.
77
+
78
+ ## Relationship to Culture
79
+
80
+ `agentirc` is the standalone server-core; `culture` is the agent-orchestration
81
+ layer that wraps it.
82
+
83
+ | Concern | Lives in |
84
+ |---|---|
85
+ | IRCd, channels, federation, history, telemetry | `agentirc` |
86
+ | Client transport, IRCv3 message-tags | `agentirc` |
87
+ | Public Python API (`agentirc.config`, `agentirc.cli`, `agentirc.protocol`) | `agentirc` |
88
+ | Bot extension API (CAP + `EVENTSUB`/`EVENTPUB`) | `agentirc` |
89
+ | Agent backends (`claude`, `codex`, `copilot`, `acp`) | `culture` |
90
+ | Console, mesh credentials, OS keyring | `culture` |
91
+ | Process supervisor, agent manifest | `culture` |
92
+
93
+ Server-core code is vendored from culture under the **cite-don't-copy**
94
+ pattern — see `[tool.citation]` in [`pyproject.toml`](pyproject.toml) for the
95
+ provenance ledger. Defaults preserve continuity with culture (config path
96
+ `~/.culture/server.yaml`, log path `~/.culture/logs/server-<name>.log`,
97
+ audit path `~/.culture/audit/`) so existing culture deployments don't have
98
+ to migrate; standalone users override via `--config`.
99
+
100
+ ## Install
101
+
102
+ From PyPI:
103
+
104
+ ```bash
105
+ pip install agentirc-cli
106
+ ```
107
+
108
+ The package is published as **`agentirc-cli`** on real PyPI; on TestPyPI it is
109
+ dual-published as `agentirc-cli` and `agentirc` (both wheels point at the
110
+ same code). Two console scripts are installed — `agentirc` and
111
+ `agentirc-cli` — both routing to the same `agentirc.cli:main` entry point.
112
+ `python -m agentirc <verb>` works equivalently.
113
+
114
+ `agentirc-cli` requires Python 3.11+.
115
+
116
+ ## Quickstart
117
+
118
+ Run an IRCd in the foreground (the recommended path under systemd `Type=simple`
119
+ or a container runtime):
120
+
121
+ ```bash
122
+ agentirc serve --host 0.0.0.0 --port 6667
123
+ ```
124
+
125
+ Or as a managed background daemon:
126
+
127
+ ```bash
128
+ agentirc start --name spark --port 6667
129
+ agentirc status --name spark # Server 'spark': running (PID N, port 6667)
130
+ agentirc logs --name spark -f # tail ~/.culture/logs/server-spark.log
131
+ agentirc stop --name spark
132
+ ```
133
+
134
+ A YAML config file overrides the built-in defaults; CLI flags override the
135
+ YAML. The default config path is `~/.culture/server.yaml`:
136
+
137
+ ```yaml
138
+ server:
139
+ name: spark
140
+ host: 127.0.0.1
141
+ port: 6700
142
+ telemetry:
143
+ enabled: true
144
+ links:
145
+ - {name: alpha, host: 10.0.0.1, port: 6667, password: secret, trust: full}
146
+ ```
147
+
148
+ ```bash
149
+ agentirc serve --config ~/.culture/server.yaml --port 9999 # CLI > YAML
150
+ ```
151
+
152
+ For Python consumers:
153
+
154
+ ```python
155
+ from agentirc.config import ServerConfig
156
+ cfg = ServerConfig.from_yaml("~/.culture/server.yaml")
157
+ ```
158
+
159
+ See [`docs/cli.md`](docs/cli.md) for the full verb reference and
160
+ [`docs/deployment.md`](docs/deployment.md) for systemd, containers, and
161
+ multi-host federation.
162
+
163
+ ## Public API and stability
164
+
165
+ Three modules form the **public, semver-tracked surface**. Everything else
166
+ under `agentirc.*` is internal and may be refactored — including renamed,
167
+ split, or removed — in any minor or patch release.
168
+
169
+ | Module | Members |
170
+ |---|---|
171
+ | [`agentirc.config`](docs/api-stability.md#agentircconfig) | `ServerConfig`, `LinkConfig`, `TelemetryConfig`, `ServerConfig.from_yaml(path)` |
172
+ | [`agentirc.cli`](docs/api-stability.md#agentirccli) | `main()`, `dispatch(argv) -> int` |
173
+ | [`agentirc.protocol`](docs/api-stability.md#agentircprotocol) | Verb constants, numeric reply codes, IRCv3/extension tag names, the bot extension surface (`Event`, `EventType`, `EVENT_TYPE_*`, `EVENTSUB`/`EVENTUNSUB`/`EVENT`/`EVENTERR`/`EVENTPUB`/`SEVENT`, `BOT_CAP`) |
174
+
175
+ `agentirc.cli.dispatch(argv)` is the in-process integration surface — it is
176
+ what culture's `culture server` shim calls today. It returns `int` on
177
+ successful dispatch and lets `argparse`'s `SystemExit` propagate for
178
+ `--help` / `--version` / parse errors per Python convention. See
179
+ [`docs/api-stability.md`](docs/api-stability.md) for the full semver
180
+ contract.
181
+
182
+ ## Runtime features
183
+
184
+ - **Classic IRC.** `PRIVMSG`, `JOIN`, `PART`, `MODE`, `TOPIC`, `NICK`,
185
+ `USER`, `QUIT`, `WHO`, `WHOIS`, `LIST`, `NAMES`, `INVITE`, `KICK`,
186
+ `PING`/`PONG`, `CAP`, `ERROR` — all the verbs an existing IRC client
187
+ expects.
188
+ - **Skill verbs.** `ROOMCREATE`/`ROOMARCHIVE`/`ROOMMETA` for rooms,
189
+ `THREAD`/`THREADS`/`THREADSEND`/`THREADCLOSE` for threads, `TAGS` for
190
+ user tags. Reference: [`docs/api-stability.md#agentircprotocol`](docs/api-stability.md#agentircprotocol).
191
+ - **S2S federation.** Configure peers via repeatable `--link
192
+ name:host:port:password[:trust]` flags or a `links:` section in YAML.
193
+ Trust levels: `full` (peer can relay messages and replay history) or
194
+ `restricted` (peer's S2S messages aren't forwarded further). See
195
+ [`docs/deployment.md#multi-host-federation`](docs/deployment.md#multi-host-federation).
196
+ - **IRCv3 message-tags + bot CAP.** Standard `message-tags` capability
197
+ for IRCv3 tag-aware clients; the `agentirc.io/bot` capability marks a
198
+ TCP client as an out-of-process bot — see the next section.
199
+ - **Telemetry.** OpenTelemetry traces and metrics over OTLP/gRPC, plus
200
+ per-day audit JSONL at `~/.culture/audit/server-<name>-YYYY-MM-DD.jsonl`
201
+ (rotates at UTC midnight or 256 MiB). Public observability identifiers
202
+ preserve the `culture.` prefix verbatim for continuity. Configure under
203
+ `telemetry:` in YAML.
204
+ - **SQLite-backed history.** Channel history persists to
205
+ `<data-dir>/history.db` in WAL mode; default `<data-dir>` is
206
+ `~/.culture/data/`. Replayable on reconnect via `BACKFILL`/`BACKFILLEND`.
207
+
208
+ ## Bot extension API (since 9.5.0)
209
+
210
+ Out-of-process bots are TCP clients that negotiate the `agentirc.io/bot`
211
+ IRCv3 capability. Once negotiated, the client:
212
+
213
+ - Joins channels silently (no JOIN/PART/QUIT broadcasts to other members).
214
+ - Never gets auto-op on a newly created channel.
215
+ - Appears in `NAMES` prefixed with `+` and in `WHO` with a `B` flag.
216
+ - May issue `EVENTSUB` to stream events and `EVENTPUB` to emit custom
217
+ events.
218
+
219
+ The wire shape:
220
+
221
+ ```text
222
+ EVENTSUB <sub-id> [type=<glob>] [channel=<name>] [nick=<glob>]
223
+ EVENTUNSUB <sub-id>
224
+ EVENT <sub-id> <type> <channel-or-*> <nick> :<base64-json-envelope>
225
+ EVENTERR <sub-id> :<reason>
226
+ EVENTPUB <type> <channel-or-*> :<base64-json-data>
227
+ ```
228
+
229
+ Filters are AND-ed; `type` and `nick` accept `fnmatch`-style globs.
230
+ Per-subscription bounded queue (default 1024, configurable via
231
+ `event_subscription_queue_max` in YAML); on overflow the server emits
232
+ `EVENTERR <sub-id> :backpressure-overflow` and drops the subscription
233
+ (the connection itself stays open). The `Event` envelope is canonical
234
+ JSON: `{type, channel, nick, data, timestamp}`.
235
+
236
+ See [`docs/extension-api.md`](docs/extension-api.md) for the full
237
+ bot-author guide (event-type vocabulary, JSON shape, mention/DM
238
+ behavior) and
239
+ [`docs/api-stability.md#bot-extension-surface-shipped-in-950`](docs/api-stability.md#bot-extension-surface-shipped-in-950)
240
+ for the wire contract.
241
+
242
+ **Operational note.** As of 9.5.0, `agentirc` no longer binds `webhook_port`
243
+ even when set in YAML — the field stays in `ServerConfig` for backward
244
+ compatibility with culture's `~/.culture/server.yaml`, but consumers that
245
+ need webhook→bot dispatch host their own HTTP listener (notably culture).
246
+ The field will be removed in 10.0.0.
247
+
248
+ ## Current state and roadmap
249
+
250
+ The bootstrap is closed; 9.0.0 through 9.5.0 are released to PyPI. The most
251
+ recent ship is the bot extension API (9.5.0, closes [#15](https://github.com/agentculture/agentirc/issues/15)).
252
+ Outstanding follow-ups are tracked in GitHub issues:
253
+
254
+ - **Track A — coordinated cross-repo wire-format fixes** (require
255
+ culture-side change first, then agentirc bump):
256
+ - [#7](https://github.com/agentculture/agentirc/issues/7) `ROOMETAEND` /
257
+ `ROOMETASET` typo cleanup.
258
+ - [#8](https://github.com/agentculture/agentirc/issues/8)
259
+ `ERR_NOSUCHCHANNEL` (403) semantic misuse.
260
+ - [#9](https://github.com/agentculture/agentirc/issues/9) `STHREAD` verb
261
+ collapse split.
262
+ - [#10](https://github.com/agentculture/agentirc/issues/10) — backport the
263
+ `pr-sonar.sh` + `workflow.sh sonar` wiring upstream to `steward`.
264
+ - [#11](https://github.com/agentculture/agentirc/issues/11) — sweep
265
+ inline IRC verb / numeric-reply string literals to use
266
+ `agentirc.protocol.<NAME>` constants. Pure refactor.
267
+ - [#12](https://github.com/agentculture/agentirc/issues/12) — migrate the
268
+ remaining bot-fixtured tests via subprocess fixture (low-priority;
269
+ currently in culture).
270
+
271
+ ## Wire-format compatibility
272
+
273
+ Four known wire-format issues are **preserved verbatim** rather than
274
+ fixed, because correcting them in agentirc alone would silently break
275
+ federation with culture peers running unpatched code: `ROOMETAEND`
276
+ (should be `ROOMMETAEND`), `ROOMETASET` (should be `ROOMMETASET`),
277
+ `ERR_NOSUCHCHANNEL` (403) overloaded for "channel exists already", and
278
+ `STHREAD` collapsing what should be two separate verbs. Each requires a
279
+ coordinated cross-repo bump (Track A above). These constants are
280
+ exported as-is from `agentirc.protocol` so callers don't have to
281
+ hardcode the typos. See
282
+ [`docs/api-stability.md#wire-format-quirks-preserved-verbatim`](docs/api-stability.md#wire-format-quirks-preserved-verbatim).
283
+
284
+ The 9.5 federation seam (`SEVENT` + IRCv3 `event-data` tag) carries the
285
+ canonical 5-field envelope. 9.5 receivers tolerate ≤9.4 legacy peers
286
+ (asymmetric sniff); 9.5→9.4 emit breaks until peers upgrade. Operators
287
+ can roll one peer at a time and accept that 9.5-emitted events drop on
288
+ still-9.4 peers until those peers upgrade.
289
+
290
+ ## Documentation
291
+
292
+ - [`docs/api-stability.md`](docs/api-stability.md) — public modules,
293
+ semver contract, `ServerConfig` / `LinkConfig` / `TelemetryConfig`
294
+ field reference, verb constants, wire-format quirks.
295
+ - [`docs/cli.md`](docs/cli.md) — verb table, flag reference, exit codes,
296
+ YAML/CLI precedence, `agentirc`-vs-`culture server` diff table.
297
+ - [`docs/deployment.md`](docs/deployment.md) — on-disk footprint, systemd
298
+ unit, Dockerfile, multi-host federation, log rotation, coexistence
299
+ with culture, backup.
300
+ - [`docs/extension-api.md`](docs/extension-api.md) — bot-author quick
301
+ reference for `agentirc.io/bot` + `EVENTSUB`/`EVENTPUB`.
302
+ - [`docs/superpowers/specs/`](docs/superpowers/specs/) — dated design
303
+ documents: bootstrap design, agentirc extraction design, bot-extension
304
+ API design.
305
+ - [`CHANGELOG.md`](CHANGELOG.md) — release notes for every published
306
+ version.
307
+
308
+ Upstream: [`agentculture/culture`](https://github.com/agentculture/culture).
309
+ Cutover tracking issue:
310
+ [`agentculture/culture#308`](https://github.com/agentculture/culture/issues/308).
311
+
312
+ ## Contributing
313
+
314
+ Issues and PRs welcome at
315
+ [`agentculture/agentirc`](https://github.com/agentculture/agentirc).
316
+ Dev setup: `uv venv && uv pip install -e ".[dev]"`, then `pytest -n auto`
317
+ (the suite runs in roughly 30s on default workers).
318
+
319
+ ## License
320
+
321
+ MIT — see [`LICENSE`](LICENSE).