agentirc-cli 9.2.0__tar.gz → 9.4.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 (110) hide show
  1. agentirc_cli-9.4.0/.claude/skills/pr-review/scripts/pr-sonar.sh +93 -0
  2. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills/pr-review/scripts/workflow.sh +8 -1
  3. agentirc_cli-9.4.0/CHANGELOG.md +264 -0
  4. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/CLAUDE.md +25 -11
  5. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/PKG-INFO +4 -3
  6. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/cli.py +178 -71
  7. agentirc_cli-9.4.0/agentirc/config.py +126 -0
  8. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/server_link.py +1 -1
  9. agentirc_cli-9.4.0/docs/api-stability.md +232 -0
  10. agentirc_cli-9.4.0/docs/cli.md +267 -0
  11. agentirc_cli-9.4.0/docs/deployment.md +233 -0
  12. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/docs/superpowers/specs/2026-04-30-bootstrap-design.md +12 -2
  13. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/pyproject.toml +186 -7
  14. agentirc_cli-9.4.0/tests/_helpers.py +96 -0
  15. agentirc_cli-9.4.0/tests/conftest.py +295 -0
  16. agentirc_cli-9.4.0/tests/telemetry/__init__.py +0 -0
  17. agentirc_cli-9.4.0/tests/telemetry/_fakes.py +26 -0
  18. agentirc_cli-9.4.0/tests/telemetry/_metrics_helpers.py +75 -0
  19. agentirc_cli-9.4.0/tests/telemetry/test_audit_emit.py +145 -0
  20. agentirc_cli-9.4.0/tests/telemetry/test_audit_lifecycle.py +69 -0
  21. agentirc_cli-9.4.0/tests/telemetry/test_audit_module.py +306 -0
  22. agentirc_cli-9.4.0/tests/telemetry/test_audit_parse_error.py +177 -0
  23. agentirc_cli-9.4.0/tests/telemetry/test_config.py +26 -0
  24. agentirc_cli-9.4.0/tests/telemetry/test_dispatch_span.py +45 -0
  25. agentirc_cli-9.4.0/tests/telemetry/test_emit_event_span.py +42 -0
  26. agentirc_cli-9.4.0/tests/telemetry/test_metrics_init.py +58 -0
  27. agentirc_cli-9.4.0/tests/telemetry/test_metrics_s2s.py +160 -0
  28. agentirc_cli-9.4.0/tests/telemetry/test_outbound_inject.py +70 -0
  29. agentirc_cli-9.4.0/tests/telemetry/test_parse_error.py +33 -0
  30. agentirc_cli-9.4.0/tests/telemetry/test_s2s_relay_span.py +114 -0
  31. agentirc_cli-9.4.0/tests/telemetry/test_server_init.py +29 -0
  32. agentirc_cli-9.4.0/tests/telemetry/test_server_link_inject.py +124 -0
  33. agentirc_cli-9.4.0/tests/telemetry/test_tracing.py +49 -0
  34. agentirc_cli-9.4.0/tests/test_channel.py +131 -0
  35. agentirc_cli-9.4.0/tests/test_config_loader.py +251 -0
  36. agentirc_cli-9.4.0/tests/test_connection.py +135 -0
  37. agentirc_cli-9.4.0/tests/test_discovery.py +169 -0
  38. agentirc_cli-9.4.0/tests/test_events_basic.py +284 -0
  39. agentirc_cli-9.4.0/tests/test_events_catalog.py +70 -0
  40. agentirc_cli-9.4.0/tests/test_events_federation.py +110 -0
  41. agentirc_cli-9.4.0/tests/test_events_history.py +64 -0
  42. agentirc_cli-9.4.0/tests/test_events_lifecycle.py +343 -0
  43. agentirc_cli-9.4.0/tests/test_events_reserved_nick.py +68 -0
  44. agentirc_cli-9.4.0/tests/test_federation.py +1163 -0
  45. agentirc_cli-9.4.0/tests/test_history.py +553 -0
  46. agentirc_cli-9.4.0/tests/test_link_reconnect.py +141 -0
  47. agentirc_cli-9.4.0/tests/test_mentions.py +155 -0
  48. agentirc_cli-9.4.0/tests/test_messaging.py +103 -0
  49. agentirc_cli-9.4.0/tests/test_modes.py +327 -0
  50. agentirc_cli-9.4.0/tests/test_room_persistence.py +75 -0
  51. agentirc_cli-9.4.0/tests/test_rooms_federation.py +63 -0
  52. agentirc_cli-9.4.0/tests/test_rooms_integration.py +110 -0
  53. agentirc_cli-9.4.0/tests/test_server_icon_skill.py +214 -0
  54. agentirc_cli-9.4.0/tests/test_skills.py +212 -0
  55. agentirc_cli-9.4.0/tests/test_threads.py +384 -0
  56. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/uv.lock +5 -118
  57. agentirc_cli-9.2.0/CHANGELOG.md +0 -118
  58. agentirc_cli-9.2.0/agentirc/config.py +0 -49
  59. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills/pr-review/SKILL.md +0 -0
  60. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills/pr-review/scripts/portability-lint.sh +0 -0
  61. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills/pr-review/scripts/pr-batch.sh +0 -0
  62. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills/pr-review/scripts/pr-comments.sh +0 -0
  63. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills/pr-review/scripts/pr-reply.sh +0 -0
  64. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills/pr-review/scripts/pr-status.sh +0 -0
  65. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.claude/skills.local.yaml.example +0 -0
  66. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.github/workflows/publish.yml +0 -0
  67. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.github/workflows/tests.yml +0 -0
  68. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/.gitignore +0 -0
  69. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/LICENSE +0 -0
  70. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/README.md +0 -0
  71. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/__init__.py +0 -0
  72. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/__main__.py +0 -0
  73. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/__init__.py +0 -0
  74. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/aio.py +0 -0
  75. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/bots/__init__.py +0 -0
  76. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/bots/bot_manager.py +0 -0
  77. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/bots/http_listener.py +0 -0
  78. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/cli_shared/__init__.py +0 -0
  79. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/cli_shared/constants.py +0 -0
  80. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/cli_shared/mesh.py +0 -0
  81. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/constants.py +0 -0
  82. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/pidfile.py +0 -0
  83. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/protocol/__init__.py +0 -0
  84. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/protocol/message.py +0 -0
  85. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/protocol/replies.py +0 -0
  86. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/telemetry/__init__.py +0 -0
  87. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/telemetry/audit.py +0 -0
  88. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/telemetry/context.py +0 -0
  89. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/telemetry/metrics.py +0 -0
  90. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/telemetry/tracing.py +0 -0
  91. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/_internal/virtual_client.py +0 -0
  92. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/channel.py +0 -0
  93. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/client.py +0 -0
  94. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/events.py +0 -0
  95. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/history_store.py +0 -0
  96. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/ircd.py +0 -0
  97. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/protocol.py +0 -0
  98. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/remote_client.py +0 -0
  99. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/room_store.py +0 -0
  100. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/rooms_util.py +0 -0
  101. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/skill.py +0 -0
  102. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/skills/__init__.py +0 -0
  103. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/skills/history.py +0 -0
  104. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/skills/icon.py +0 -0
  105. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/skills/rooms.py +0 -0
  106. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/skills/threads.py +0 -0
  107. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/agentirc/thread_store.py +0 -0
  108. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/docs/steward/onboarding.md +0 -0
  109. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/tests/__init__.py +0 -0
  110. {agentirc_cli-9.2.0 → agentirc_cli-9.4.0}/tests/test_cli.py +0 -0
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env bash
2
+ # pr-sonar.sh — list every SonarCloud finding attached to a PR.
3
+ #
4
+ # Surfaces what the GitHub-side `poll` cannot: SonarCloud issues,
5
+ # security hotspots, and the duplication breakdown. The
6
+ # sonarqubecloud[bot] PR comment only links to the dashboard — actual
7
+ # findings live behind the SonarCloud API.
8
+ #
9
+ # Usage: pr-sonar.sh [--repo OWNER/REPO] [--sonar-key KEY] PR_NUMBER
10
+ #
11
+ # Defaults:
12
+ # --repo auto-detected via `gh repo view`
13
+ # --sonar-key derived from repo as `<owner>_<name>`
14
+ #
15
+ # Anonymous SonarCloud access is sufficient for public projects.
16
+ # Requires: gh, jq, curl, python3.
17
+
18
+ set -euo pipefail
19
+
20
+ REPO=""
21
+ SONAR_KEY=""
22
+
23
+ while [[ $# -gt 0 ]]; do
24
+ case "$1" in
25
+ --repo) REPO="$2"; shift 2 ;;
26
+ --sonar-key) SONAR_KEY="$2"; shift 2 ;;
27
+ *) break ;;
28
+ esac
29
+ done
30
+
31
+ PR_NUMBER="${1:?Usage: pr-sonar.sh [--repo OWNER/REPO] [--sonar-key KEY] PR_NUMBER}"
32
+
33
+ if [[ -z "$REPO" ]]; then
34
+ REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
35
+ fi
36
+ if [[ -z "$SONAR_KEY" ]]; then
37
+ SONAR_KEY="${REPO%%/*}_${REPO##*/}"
38
+ fi
39
+
40
+ echo "════════════════ SONARCLOUD (project=$SONAR_KEY, PR=$PR_NUMBER) ════════════════"
41
+
42
+ # ── Quality gate
43
+ QG=$(curl -fsS "https://sonarcloud.io/api/qualitygates/project_status?projectKey=${SONAR_KEY}&pullRequest=${PR_NUMBER}" || echo '{}')
44
+ QG_STATUS=$(echo "$QG" | jq -r '.projectStatus.status // "UNKNOWN"')
45
+ echo "Quality Gate: $QG_STATUS"
46
+ echo "$QG" | jq -r '.projectStatus.conditions[]? | select(.status != "OK") | " ✗ \(.metricKey) = \(.actualValue) (threshold \(.comparator) \(.errorThreshold))"' || true
47
+
48
+ # ── Issues (BUG / VULNERABILITY / CODE_SMELL)
49
+ ISSUES=$(curl -fsS "https://sonarcloud.io/api/issues/search?componentKeys=${SONAR_KEY}&pullRequest=${PR_NUMBER}&statuses=OPEN,CONFIRMED&ps=500" || echo '{}')
50
+ ISSUE_TOTAL=$(echo "$ISSUES" | jq -r '.total // 0')
51
+ echo
52
+ echo "── Issues ($ISSUE_TOTAL OPEN/CONFIRMED) ─────────────────────────────"
53
+ if [[ "$ISSUE_TOTAL" != "0" ]]; then
54
+ echo "$ISSUES" | jq -r '
55
+ .issues[] |
56
+ " [\(.rule)] \(.severity) \(.component | sub("^[^:]+:"; ""))(:\(.line // "?"))\n \(.message)"
57
+ '
58
+ fi
59
+
60
+ # ── Security hotspots
61
+ HOTSPOTS=$(curl -fsS "https://sonarcloud.io/api/hotspots/search?projectKey=${SONAR_KEY}&pullRequest=${PR_NUMBER}&status=TO_REVIEW&ps=500" || echo '{}')
62
+ HOTSPOT_TOTAL=$(echo "$HOTSPOTS" | jq -r '.paging.total // 0')
63
+ echo
64
+ echo "── Hotspots ($HOTSPOT_TOTAL TO_REVIEW) ──────────────────────────────"
65
+ if [[ "$HOTSPOT_TOTAL" != "0" ]]; then
66
+ echo "$HOTSPOTS" | jq -r '
67
+ .hotspots[] |
68
+ " [\(.ruleKey)] \(.vulnerabilityProbability) \(.component | sub("^[^:]+:"; ""))(:\(.line // "?"))\n \(.message)"
69
+ '
70
+ fi
71
+
72
+ # ── Duplication
73
+ MEAS=$(curl -fsS "https://sonarcloud.io/api/measures/component?component=${SONAR_KEY}&pullRequest=${PR_NUMBER}&metricKeys=new_duplicated_lines_density,new_duplicated_lines,new_duplicated_blocks" || echo '{}')
74
+ DUP_PCT=$(echo "$MEAS" | jq -r '.component.measures[]? | select(.metric == "new_duplicated_lines_density") | .periods[0].value // ""')
75
+ DUP_LINES=$(echo "$MEAS" | jq -r '.component.measures[]? | select(.metric == "new_duplicated_lines") | .periods[0].value // ""')
76
+ DUP_BLOCKS=$(echo "$MEAS" | jq -r '.component.measures[]? | select(.metric == "new_duplicated_blocks") | .periods[0].value // ""')
77
+ echo
78
+ echo "── Duplication on new code ──────────────────────────────────────────"
79
+ echo " density: ${DUP_PCT:-?}% lines: ${DUP_LINES:-?} blocks: ${DUP_BLOCKS:-?}"
80
+
81
+ if [[ "${DUP_BLOCKS:-0}" != "0" && -n "${DUP_BLOCKS:-}" ]]; then
82
+ # Per-file duplication: list every file with duplicated_lines on new code.
83
+ # Sonar doesn't expose per-PR duplication-by-file directly; surface the
84
+ # files that appear in the issues + hotspots as a weak proxy.
85
+ DUP_FILES=$(echo "$ISSUES" | jq -r '[.issues[] | .component | sub("^[^:]+:"; "")] | unique | .[]')
86
+ if [[ -n "$DUP_FILES" ]]; then
87
+ echo " files with findings (likely duplication source):"
88
+ echo "$DUP_FILES" | sed 's/^/ - /'
89
+ fi
90
+ fi
91
+
92
+ echo
93
+ echo "Dashboard: https://sonarcloud.io/dashboard?id=${SONAR_KEY}&pullRequest=${PR_NUMBER}"
@@ -3,7 +3,8 @@
3
3
  #
4
4
  # Subcommands:
5
5
  # lint run the portability lint on the current diff (staged + unstaged)
6
- # poll <PR> fetch and display review comments
6
+ # poll <PR> fetch and display review comments + SonarCloud findings
7
+ # sonar <PR> list every SonarCloud issue / hotspot / duplication on a PR
7
8
  # reply <PR> batch reply to review comments (JSONL on stdin), --resolve
8
9
  # delta dump CLAUDE.md head + culture.yaml for each sibling project
9
10
  # listed in skills.local.yaml (alignment-delta check)
@@ -53,6 +54,12 @@ case "$cmd" in
53
54
  poll)
54
55
  PR="${1:?Usage: workflow.sh poll <PR>}"
55
56
  bash "$SCRIPT_DIR/pr-comments.sh" "$PR"
57
+ echo
58
+ bash "$SCRIPT_DIR/pr-sonar.sh" "$PR"
59
+ ;;
60
+ sonar)
61
+ PR="${1:?Usage: workflow.sh sonar <PR>}"
62
+ bash "$SCRIPT_DIR/pr-sonar.sh" "$PR"
56
63
  ;;
57
64
  reply)
58
65
  PR="${1:?Usage: workflow.sh reply <PR> (JSONL on stdin)}"
@@ -0,0 +1,264 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ Format follows [Keep a Changelog](https://keepachangelog.com/).
6
+
7
+ ## [9.4.0] - 2026-05-01
8
+
9
+ ### Added
10
+
11
+ - `ServerConfig.from_yaml(path)` — public classmethod on
12
+ `agentirc.config.ServerConfig` that loads `~/.culture/server.yaml`
13
+ (or any YAML file). Recognises `server`, `telemetry`, `links`,
14
+ `webhook_port`, `data_dir`, `system_bots` keys; silently ignores
15
+ culture-only top-level keys (`supervisor`, `agents`, `buffer_size`,
16
+ `poll_interval`, `sleep_start`, `sleep_end`, `webhooks`) so the same
17
+ file can drive both `culture server` and `agentirc` daemons.
18
+ - CLI handlers (`serve`, `start`, `restart`) now overlay CLI flags on
19
+ top of YAML config. Precedence: explicit CLI flag (sentinel-`None`
20
+ detection) > YAML key > built-in default. Closes the bootstrap
21
+ acceptance criterion *"`agentirc start --config <path>` behaves
22
+ indistinguishably from `culture server start`"*.
23
+ - New runtime dependency: `pyyaml>=6.0`.
24
+ - `docs/api-stability.md` — semver contract for the three public
25
+ modules (`agentirc.config`, `agentirc.cli`, `agentirc.protocol`),
26
+ full member list per module, internal-may-refactor list, wire-format
27
+ quirks paragraph, versioning history.
28
+ - `docs/cli.md` — verb table (8 verbs), per-verb flag reference, exit
29
+ codes, stderr formatting, YAML/CLI precedence, and the agentirc-vs-
30
+ culture differences table.
31
+ - `docs/deployment.md` — on-disk footprint, systemd `Type=simple`
32
+ example unit, container deployment, standalone deployment,
33
+ multi-host federation, log rotation (logrotate `copytruncate` rule),
34
+ coexistence with culture, backup recommendations.
35
+
36
+ ### Changed
37
+
38
+ - `agentirc/cli.py:_add_start_flags` — argparse defaults for `--name`,
39
+ `--host`, `--port`, `--link`, `--webhook-port`, `--data-dir` are now
40
+ sentinel `None` rather than concrete values. The user-visible
41
+ defaults (`0.0.0.0`, `6667`, `7680`, `~/.culture/data`) are still
42
+ documented in help strings and live on the `ServerConfig` dataclass;
43
+ the change lets `_resolve_config` distinguish "user-supplied" from
44
+ "argparse-filled" when overlaying CLI on YAML.
45
+
46
+ ### Removed
47
+
48
+ - `agentirc/cli.py:_maybe_warn_unused_config` — the
49
+ *"`--config` was supplied, but YAML config loading is not yet wired
50
+ (PR-B4)"* warning that PR #4 review (Qodo + Copilot) requested. YAML
51
+ loading is now wired; the warning was the placeholder for this PR.
52
+
53
+ ### Notes
54
+
55
+ - Bootstrap is functionally + docs complete as of 9.4.0. Remaining
56
+ work per the spec status note: acceptance-criteria spot-check (Task
57
+ 14) and release ceremony (Tasks 16–18 — tag, publish, report-back to
58
+ culture). The cross-repo wire-format fixes (Track A) and steward
59
+ backport of `pr-sonar.sh` are the only outstanding follow-ups.
60
+ - 13 new tests in `tests/test_config_loader.py` exercise
61
+ `ServerConfig.from_yaml` (missing/empty/malformed files, unknown-key
62
+ tolerance, telemetry/links sections) and the `_resolve_config` merge
63
+ (CLI overrides YAML, YAML used when CLI absent, defaults on both
64
+ absent, links wholesale-replace). Total suite: 328 tests, ~28s under
65
+ `pytest -n auto`.
66
+
67
+ ## [9.3.0] - 2026-05-01
68
+
69
+ ### Added
70
+
71
+ - Test suite migration (PR-B3): 36 server-core / telemetry tests
72
+ vendored from `culture@df50942` (~6,500 LOC). 315 tests run under
73
+ `pytest -n auto` in ~29 seconds.
74
+ - 21 server-core tests in `tests/` cover IRC lifecycle, channels,
75
+ rooms, threads, history, federation (S2S), events, mentions,
76
+ and the icon skill.
77
+ - 15 telemetry integration tests in `tests/telemetry/` cover audit
78
+ JSONL emission, OTLP span injection on dispatch, S2S relay
79
+ spans, metrics initialization, and trace-context propagation.
80
+ - Test helper modules `_fakes.py` and `_metrics_helpers.py` also
81
+ vendored verbatim under the same package.
82
+ - `tests/conftest.py` — adapted from culture. Drops the
83
+ `_BOTS_DIR_*` patches and the `server_with_bot` /
84
+ `server_with_bots` fixtures (see Changed below). Keeps the
85
+ `IRCTestClient` raw-TCP helper and the IRCd lifecycle, telemetry,
86
+ and audit fixtures.
87
+ - `.claude/skills/pr-review/scripts/pr-sonar.sh` — new script that
88
+ fetches every SonarCloud issue, security hotspot, and duplication
89
+ measure for a PR via the SonarCloud API. `workflow.sh poll` now
90
+ runs it after `pr-comments.sh`; `workflow.sh sonar <PR>` runs it
91
+ standalone. Closes the gap where the GitHub-side poll only saw
92
+ the SonarCloud bot's "Quality Gate failed" link without the
93
+ underlying findings. Re-vendor to `steward` after this PR merges.
94
+ - Three `[tool.citation]` packages:
95
+ `culture-tests-conftest` (paraphrase),
96
+ `culture-tests-server-core` (mostly quote, paraphrase for
97
+ `test_events_basic.py`), and `culture-tests-telemetry` (mostly
98
+ quote, paraphrase for `test_tracing.py`).
99
+
100
+ ### Changed
101
+
102
+ - `agentirc/server_link.py:_replay_event` — parameter renamed from
103
+ `_seq` (PR-B1's unused-arg compliance variant) back to `seq` to
104
+ match the upstream signature culture's tests assume; signature
105
+ carries `# noqa: ARG002 # NOSONAR S1172`. Hash refreshed.
106
+
107
+ ### Fixed (post-review)
108
+
109
+ - `requires-python = ">=3.10"` → `">=3.11"`; classifiers updated
110
+ (drop 3.10, add 3.13). Resolves Copilot/Qodo "asyncio.timeout
111
+ not in 3.10" findings. The 3.10 floor was inherited from PR-B1/B2
112
+ and would have ImportError'd on the first test run.
113
+ - 2 SonarCloud `python:S5332` security hotspots cleared via
114
+ `# NOSONAR S5332` annotations on `tests/telemetry/test_config.py`'s
115
+ localhost OTLP test fixtures (URLs never reach the wire).
116
+ - New `tests/_helpers.py` (agentirc-native, not cited) extracts the
117
+ duplicated "boot two linked IRCds" pattern into `boot_linked_pair`
118
+ + `link_pair`. Refactored 9 sites that previously inlined ~22
119
+ lines of identical scaffolding: 5 in `test_federation.py`, 3 in
120
+ `test_link_reconnect.py`, plus the `linked_servers` conftest
121
+ fixture. Drops ~180 duplicated lines, addressing SonarCloud's
122
+ >3% duplication threshold while keeping the cited test bodies
123
+ readable. Re-snapshots from culture replay this extraction
124
+ mechanically.
125
+ - 42 SonarCloud OPEN issues cleared via inline `# NOSONAR <rule>`
126
+ annotations: `python:S1172` (server_link `_replay_event`'s upstream
127
+ signature compat), `python:S2068` (3 test fixture passwords),
128
+ `python:S7483` (3 `IRCTestClient.recv*` / `_wait_for_span` timeout
129
+ params kept by upstream design — see `RECV_TIMEOUT_SECONDS`
130
+ module-level note), `python:S7494` (2 `dict(t.split("=") for t in
131
+ tags)` patterns vendored verbatim from culture), `python:S125`
132
+ (1 `# 311 RPL_WHOISUSER` documentation comment SonarCloud
133
+ misclassified as commented-out code), `python:S1481` × 21
134
+ (`server_a, server_b = linked_servers` tuple-unpack sites where
135
+ one or both vars are used by the federation fixture but unread in
136
+ the test body — same idiom across 3 files; underscore-prefix
137
+ rename would diverge from culture upstream and complicate
138
+ re-snapshots).
139
+
140
+ ### Deferred / out of scope
141
+
142
+ - Three bot-fixtured telemetry tests
143
+ (`test_bot_event_dispatch_span.py`, `test_bot_run_span.py`,
144
+ `test_metrics_bots.py`) and `test_welcome_bot.py` stay in culture
145
+ — they depend on the real `BotManager` (forbidden by agentirc's
146
+ dependency boundary). Bucket C tests (cli/console/daemon/clients)
147
+ also remain in culture indefinitely.
148
+ - `tests/telemetry/conftest.py` is not migrated; its only consumer
149
+ was the deferred bot-fixtured tests above.
150
+ - Bootstrap docs (`docs/api-stability.md`, `docs/cli.md`,
151
+ `docs/deployment.md`) ship in PR-B4.
152
+
153
+ ## [9.2.0] - 2026-05-01
154
+
155
+ ### Added
156
+
157
+ - `agentirc/protocol.py` — public, semver-tracked module consolidating
158
+ IRC verb names, numeric reply codes (re-exported from
159
+ `_internal.protocol.replies`), and IRCv3 / agentirc tag names. Wire-
160
+ format quirks (`ROOMETAEND`, `ROOMETASET` typos; `ERR_NOSUCHCHANNEL`
161
+ semantic misuse; `STHREAD` verb collapse) are preserved verbatim with
162
+ explanatory comments — they require coordinated cross-repo bumps to
163
+ fix.
164
+ - `agentirc/client.py` — IRC client transport vendored from
165
+ `culture/agentirc/client.py` at SHA `df50942`. Body unchanged; only
166
+ imports rewritten. The bootstrap spec originally said this would
167
+ "stay in culture" but its dependency surface (already-vendored
168
+ `_internal` support modules + opentelemetry) made vendoring the
169
+ cleaner path. Without it, `agentirc/ircd.py:580`'s runtime
170
+ `from agentirc.client import Client` raised `ImportError` on the
171
+ first TCP IRC connection.
172
+ - Real `agentirc/cli.py` — verb dispatch extracted from
173
+ `culture/cli/server.py`. New verbs: `serve` (foreground, no PID;
174
+ for systemd `Type=simple` and containers), `restart`, `link`
175
+ (peer-spec validator), `logs` (cat / tail of `~/.culture/logs/server-
176
+ <name>.log`). Existing verbs `start`/`stop`/`status` reuse culture's
177
+ proven daemonize / `_wait_for_port` / `_wait_for_graceful_stop` /
178
+ `_force_kill` helpers.
179
+ - Internal support modules:
180
+ - `agentirc/_internal/pidfile.py` — PID/port file management.
181
+ `is_managed_process()` recognizes both `culture` and
182
+ `agentirc`/`agentirc-cli` argv tokens; `is_culture_process` is
183
+ preserved as a thin alias.
184
+ - `agentirc/_internal/cli_shared/{constants,mesh}.py` — minimal
185
+ subset of `culture/cli/shared`. Keeps `DEFAULT_CONFIG`, `LOG_DIR`,
186
+ `culture_runtime_dir()`, `parse_link()`. Drops everything that
187
+ touched `culture.bots.config`, `culture.credentials`,
188
+ `culture.mesh_config`.
189
+ - Citations recorded in `[tool.citation]`: `culture-pidfile`,
190
+ `culture-cli-shared`, `culture-client`, `culture-cli-server`.
191
+
192
+ ### Changed
193
+
194
+ - Default server name changed from `culture` to `agentirc` in
195
+ `agentirc.cli`. PID/port files at `~/.culture/pids/server-<name>.{pid,
196
+ port}` keep their existing layout per the "Defaults preserve culture
197
+ continuity" rule, but the default fallback name no longer collides
198
+ with culture's daemon when both run on the same host.
199
+ - Dropped culture-only verbs (`default`, `rename`, `archive`,
200
+ `unarchive`) from agentirc's CLI surface — they manage culture's
201
+ agent manifest, which agentirc does not own.
202
+ - Dropped `--mesh-config` from `agentirc start` — depends on
203
+ `culture.credentials` / `culture.mesh_config` (out of scope).
204
+
205
+ ### Notes
206
+
207
+ - End-to-end smoke verified: `agentirc start --port 16667` boots,
208
+ TCP NICK/USER handshake returns `001 RPL_WELCOME` from a real
209
+ `IRCd`, `agentirc stop` shuts cleanly. `agentirc serve` is now
210
+ byte-indistinguishable from `culture server start` for the lifecycle
211
+ contract culture's shim relies on.
212
+ - Test suite migration (PR-B3) is the only remaining bootstrap slice.
213
+
214
+ ## [9.1.0] - 2026-04-30
215
+
216
+ ### Added
217
+
218
+ - Server-core vendored from `culture` at SHA `df50942`. The `agentirc`
219
+ package now contains the IRCd (`ircd.py`), server-to-server linking
220
+ (`server_link.py`), channel/event/store/skill modules, `remote_client.py`
221
+ (peer-server ghost client), and the four built-in skills
222
+ (`skills/{rooms,threads,history,icon}.py`).
223
+ - Internal vendored support modules under `agentirc/_internal/`:
224
+ - `aio` (`maybe_await`)
225
+ - `constants` (system user/channel constants)
226
+ - `protocol/` (IRC `Message` and numeric `replies`)
227
+ - `telemetry/` (OpenTelemetry audit/tracing/metrics — full subpackage)
228
+ - `virtual_client` (`VirtualClient` for in-process bot integration)
229
+ - `bots/{bot_manager,http_listener}` (no-op stubs; culture replaces
230
+ these at runtime when wrapping an `IRCd`)
231
+ - `[tool.citation]` block in `pyproject.toml` enumerating every vendored
232
+ file with a quote/paraphrase/synthesize status, source URL, and
233
+ sha256, validated by `cite check`.
234
+ - Runtime dependencies: `opentelemetry-api`, `opentelemetry-sdk`,
235
+ `opentelemetry-exporter-otlp-proto-grpc` (all `>=1.22`).
236
+ - Dev dependency: `citation-cli` (provides the `cite` console script).
237
+
238
+ ### Changed
239
+
240
+ - Bootstrap spec deviation: `remote_client.py` was originally listed as
241
+ "do not copy" but turned out to be server-side (used by `server_link`
242
+ and `virtual_client` for peer-server users in channel member lists).
243
+ Vendored as public `agentirc/remote_client.py`. See commit `8b4a6d8`.
244
+
245
+ ### Notes
246
+
247
+ - `agentirc/cli.py` still ships only `version`; the `serve|start|stop|
248
+ restart|status|link|logs` lifecycle verbs remain stubs. The real CLI
249
+ is the next slice (PR-B2).
250
+ - Tests are not migrated yet (PR-B3).
251
+
252
+ ## [9.0.0] - 2026-04-30
253
+
254
+ ### Added
255
+
256
+ - Initial bootstrap of `agentirc-cli` as an installable Python package.
257
+ - Skeleton `agentirc/{__init__,__main__,cli}.py` with `version` verb
258
+ wired up and lifecycle verbs (`serve|start|stop|restart|status|link|
259
+ logs`) as stubs.
260
+ - Console scripts: both `agentirc` and `agentirc-cli` map to
261
+ `agentirc.cli:main`.
262
+ - Major version starts at `9.0.0` to leapfrog the
263
+ `agentirc-cli==8.7.X.devN` squat that culture previously published to
264
+ TestPyPI, so dev releases sort as the actual "Latest".
@@ -2,20 +2,26 @@
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: server-core + real CLI + protocol module landed (9.2.0)
5
+ ## Current state: bootstrap functionally + docs complete (9.4.0); release ceremony remains
6
6
 
7
- This repo is the agentirc server-core extraction out of the sibling project [`culture`](https://github.com/OriNachum/culture). As of 9.2.0:
7
+ This repo is the agentirc server-core extraction out of the sibling project [`culture`](https://github.com/OriNachum/culture). As of 9.4.0:
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
- - **Client transport** (`agentirc/client.py`) — vendored from `culture/agentirc/client.py` in PR-B2. The bootstrap spec originally said this would "stay in culture", but the dependency-boundary analysis after PR-B1 showed `client.py` only imports already-vendored support modules plus opentelemetry. Without it, `agentirc/ircd.py:580`'s runtime `from agentirc.client import Client` raised `ImportError` on the first TCP IRC connection.
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`.
10
+ - **Client transport** (`agentirc/client.py`) — vendored from `culture/agentirc/client.py` in PR-B2.
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.
12
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.
13
- - **Internal support** (`agentirc/_internal/`) — `aio`, `constants`, `protocol/`, `telemetry/`, `virtual_client`, `pidfile` (PR-B2), `cli_shared/` (PR-B2), `bots/` stubs.
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).
14
17
 
15
- 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` is byte-indistinguishable from `culture server start` for the lifecycle contract culture's shim relies on.
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.
16
19
 
17
20
  What is **not** done yet:
18
- - **Test suite migration** is PR-B3 — only remaining bootstrap slice.
21
+ - **Acceptance-criteria spot-check** (Task 14 in the bootstrap spec) read-only audit to confirm every bullet in §"Acceptance criteria" is ✅ before tagging.
22
+ - **Release ceremony** (Tasks 16–18) — tag `v9.4.0`, the existing `publish.yml` CI pushes to PyPI on push to `main`, then report version + source SHA back so culture's cutover PR can pin against it.
23
+ - **Cross-repo wire-format fixes (Track A)** — `ROOMETAEND`/`ROOMETASET` typos, `ERR_NOSUCHCHANNEL` overload, `STHREAD` collapse. Each requires culture-side change first then agentirc bump.
24
+ - **Steward backport** — port the 9.3.0 `pr-sonar.sh` + `workflow.sh` SonarCloud wiring back to the steward skills repo.
19
25
 
20
26
  Read the bootstrap spec at `docs/superpowers/specs/2026-04-30-bootstrap-design.md` for the full plan; it is the operative source of truth and is intentionally self-contained. The culture-side counterpart spec is at `../culture/docs/superpowers/specs/2026-04-30-agentirc-extraction-design.md` — not normally needed, but explains *why* if a decision looks arbitrary.
21
27
 
@@ -44,6 +50,13 @@ There are three different names in play. Don't conflate them:
44
50
 
45
51
  When migrating tests, the rule is: pure server tests come here, transport tests **also** come here now that we own `client.py`, mixed tests stay in culture and get rewritten to drive `agentirc serve` as a subprocess fixture rather than importing `IRCd` directly. When unsure, **prefer copying the test here** — this repo owns the IRCd and the client transport.
46
52
 
53
+ ### Test layout (since 9.3.0)
54
+
55
+ - `tests/conftest.py` — paraphrase of culture's conftest. Drops the `_BOTS_DIR_*` `unittest.mock.patch` calls (no-op against agentirc's bot stubs) and the `server_with_bot` / `server_with_bots` fixtures. Keeps `IRCTestClient`, the IRCd lifecycle fixtures (`server`, `linked_servers`, `make_client*`, `server_welcome_disabled`), telemetry fixtures (`tracing_exporter`, `metrics_reader`, `audit_dir`), and the `TEST_LINK_PASSWORD` constant.
56
+ - `tests/test_*.py` — 21 server-core tests + the agentirc-native `test_cli.py`. Cover IRC lifecycle, channels, rooms, threads, history, federation, events, mentions, the icon skill.
57
+ - `tests/telemetry/test_*.py` — 15 telemetry integration tests covering audit JSONL emission, OTLP span injection on dispatch, S2S relay spans, metrics initialization, trace-context propagation. Uses two private helper modules `_fakes.py` (FakeWriter etc.) and `_metrics_helpers.py`. No `tests/telemetry/conftest.py` (the upstream one was bot-coupled).
58
+ - Tests left in culture: `test_bot_event_dispatch_span.py`, `test_bot_run_span.py`, `test_metrics_bots.py`, `test_welcome_bot.py` (bot-manager-coupled), plus the entire bucket-C surface (cli, console, daemon, clients, credentials).
59
+
47
60
  ## Public API contract (semver-tracked)
48
61
 
49
62
  Only three modules are public. Everything else is internal and may be refactored without a major bump.
@@ -82,7 +95,7 @@ Do not rename on-disk artifacts during the bootstrap. That is explicitly out of
82
95
  # Dev setup
83
96
  uv venv && uv pip install -e ".[dev]"
84
97
 
85
- # Tests (the spec mandates parallel; no tests yet — collected 0)
98
+ # Tests (315 collected, ~29s on default workers)
86
99
  pytest -n auto
87
100
 
88
101
  # Run a single test
@@ -91,7 +104,7 @@ pytest tests/path/to/test_file.py::test_name -v
91
104
  # CLI smoke
92
105
  agentirc --help
93
106
  agentirc-cli --help # alias of agentirc
94
- agentirc version # prints "agentirc 9.2.0"
107
+ agentirc version # prints "agentirc 9.3.0"
95
108
  python -m agentirc version # equivalent
96
109
 
97
110
  # Lifecycle (functional since 9.2.0)
@@ -146,7 +159,8 @@ Per-machine paths for these skills go in `.claude/skills.local.yaml` (gitignored
146
159
 
147
160
  The full list lives in §"Acceptance criteria" of the bootstrap spec. The non-obvious ones:
148
161
 
149
- - `pip install agentirc-cli==9.2.0` on a clean venv produces working `agentirc` *and* `agentirc-cli` binaries (both pointing at `agentirc.cli:main`). ✅ since 9.0.0.
162
+ - `pip install agentirc-cli==9.3.0` on a clean venv produces working `agentirc` *and* `agentirc-cli` binaries (both pointing at `agentirc.cli:main`). ✅ since 9.0.0.
150
163
  - `agentirc serve` is byte-indistinguishable from `culture server start` (same socket, same logs, same systemd integration). ✅ since 9.2.0.
151
164
  - `agentirc.config.{ServerConfig, LinkConfig, TelemetryConfig}`, `agentirc.cli.{main, dispatch}`, `agentirc.protocol.*` all import from a clean Python session. ✅ since 9.2.0.
152
- - `docs/api-stability.md` names the three public modules. pending.
165
+ - `pytest -n auto` passes for the migrated suite (315 tests, ~29s). since 9.3.0.
166
+ - `docs/api-stability.md` names the three public modules. ⏳ pending PR-B4.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentirc-cli
3
- Version: 9.2.0
3
+ Version: 9.4.0
4
4
  Summary: Agent-friendly IRCd: server core for AI agent meshes
5
5
  Project-URL: Homepage, https://github.com/OriNachum/agentirc
6
6
  Project-URL: Issues, https://github.com/OriNachum/agentirc/issues
@@ -32,14 +32,15 @@ Classifier: Development Status :: 3 - Alpha
32
32
  Classifier: Intended Audience :: Developers
33
33
  Classifier: License :: OSI Approved :: MIT License
34
34
  Classifier: Programming Language :: Python :: 3
35
- Classifier: Programming Language :: Python :: 3.10
36
35
  Classifier: Programming Language :: Python :: 3.11
37
36
  Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Programming Language :: Python :: 3.13
38
38
  Classifier: Topic :: Communications :: Chat :: Internet Relay Chat
39
- Requires-Python: >=3.10
39
+ Requires-Python: >=3.11
40
40
  Requires-Dist: opentelemetry-api>=1.22
41
41
  Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.22
42
42
  Requires-Dist: opentelemetry-sdk>=1.22
43
+ Requires-Dist: pyyaml>=6.0
43
44
  Provides-Extra: dev
44
45
  Requires-Dist: bandit; extra == 'dev'
45
46
  Requires-Dist: black; extra == 'dev'