Skip to content

Add broker activity tail command#925

Merged
willwashburn merged 2 commits into
mainfrom
codex/broker-activity-tail
May 20, 2026
Merged

Add broker activity tail command#925
willwashburn merged 2 commits into
mainfrom
codex/broker-activity-tail

Conversation

@willwashburn
Copy link
Copy Markdown
Member

Summary:

  • Add agent-relay activity to stream broker /ws events in a readable tail.
  • Support JSON Lines output plus kind, name, stream, and since-seq filters.
  • Document the command in the Unreleased changelog.

Tests:

  • npx vitest run src/cli/commands/activity.test.ts src/cli/bootstrap.test.ts
  • npm run typecheck

@willwashburn willwashburn requested a review from khaliqgant as a code owner May 20, 2026 02:07
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e206c3ba-41f3-47ac-8756-5c852affab61

📥 Commits

Reviewing files that changed from the base of the PR and between 2454032 and aa21631.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • src/cli/commands/activity.test.ts
  • src/cli/commands/activity.ts
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

Adds a new agent-relay activity CLI command that connects to a broker WebSocket event stream to tail broker-wide activity with optional filtering by event kind/name and output as pretty or JSON Lines. The command is wired into CLI bootstrap, fully tested, and documented in CHANGELOG.md.

Changes

Agent Activity CLI Command

Layer / File(s) Summary
Activity Command Implementation
src/cli/commands/activity.ts
Defines WebSocket/dependency types and defaults; implements helpers to extract fields and sanitize previews; formatActivityEvent maps many broker event kinds to human-readable lines or returns null for suppressed stream previews; parses --since-seq, --kind, --name, and builds WebSocket URL/query; runActivitySession manages connection, JSON parsing, filtering, output (pretty or JSON Lines), shutdown, and exit codes; registerActivityCommands wires CLI flags.
CLI Bootstrap Integration
src/cli/bootstrap.ts, src/cli/bootstrap.test.ts
Imports and registers registerActivityCommands during program creation and updates bootstrap tests to include agents:logs activity as a leaf command.
Activity Command Tests
src/cli/commands/activity.test.ts
Adds test harness (FakeWebSocket, ExitSignal, createHarness), unit tests for formatActivityEvent, and behavioral tests for runActivitySession covering URL/header wiring, pretty vs JSON Lines, filtering, non-JSON tolerance, stream suppression, error cases, and SIGINT handling; also verifies command registration and --no-streams behavior.
Changelog Documentation
CHANGELOG.md
Adds an Unreleased bullet describing agent-relay activity and updates the 6.2.4/6.2.3 sections under Technical Perspective and Releases.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as registerActivityCommands
  participant Session as runActivitySession
  participant Resolver as Connection Resolver
  participant WS as WebSocketFactory/WebSocket
  participant Parser as JSON Parser
  participant Formatter as formatActivityEvent
  participant Output as stdout/JSON Lines
  CLI->>Session: invoke with options
  Session->>Resolver: resolve broker URL & api key
  Session->>Session: validate sinceSeq & filters
  Session->>WS: open connection with URL & API key header
  WS->>Parser: message frames (text/binary)
  Parser->>Parser: parse JSON, apply kind/name/streams filters
  Parser->>Formatter: format matching events
  Formatter->>Output: emit pretty line or JSON Line
  WS->>Session: close (code/reason)
  Session->>CLI: return exit code
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • khaliqgant

Poem

🐰 A little relay wakes at dawn,
Listening where broker breaths are drawn,
Lines of JSON, tidy and bright,
Filters dancing through the night,
I hop and log with pure delight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add broker activity tail command' accurately and concisely summarizes the main change—adding a new CLI command for tailing broker activity events.
Description check ✅ Passed The description covers key implementation details and lists completed tests, though it does not follow the provided template structure with explicit checkbox sections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/broker-activity-tail

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/cli/commands/activity.ts (1)

147-410: 💤 Low value

Consider refactoring to reduce complexity.

The static analysis tool flags this function with complexity 88 (max 15). While the code is a straightforward formatting dispatch table and works correctly, consider extracting formatters into a map structure to improve maintainability:

const formatters: Record<string, (event: ActivityEvent, nowIso: string) => string | null> = {
  relay_inbound: (event, nowIso) => { /* ... */ },
  relaycast_published: (event, nowIso) => { /* ... */ },
  // etc.
};

export function formatActivityEvent(event: ActivityEvent, nowIso: string): string | null {
  const kind = readString(event, 'kind');
  const formatter = formatters[kind ?? ''] ?? formatters.default;
  return formatter(event, nowIso);
}

This would reduce complexity metrics while maintaining readability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/commands/activity.ts` around lines 147 - 410, The function
formatActivityEvent is too complex; extract each case's logic into a
Record-based dispatcher named formatters: Record<string, (event: ActivityEvent,
nowIso: string) => string | null>, implement one entry per kind (e.g.
"relay_inbound", "relaycast_published", "delivery_retry", etc.) that calls the
existing helpers (formatLine, formatDelivery, detail, quotePreview, actorName,
eventId, deliveryId, readString, readCount) and add a formatters.default for the
current default branch; then simplify formatActivityEvent to read kind, select
formatters[kind ?? ''] ?? formatters.default and return formatter(event,
nowIso), keeping all formatting behavior identical to the switch-based
implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/cli/commands/activity.ts`:
- Around line 147-410: The function formatActivityEvent is too complex; extract
each case's logic into a Record-based dispatcher named formatters:
Record<string, (event: ActivityEvent, nowIso: string) => string | null>,
implement one entry per kind (e.g. "relay_inbound", "relaycast_published",
"delivery_retry", etc.) that calls the existing helpers (formatLine,
formatDelivery, detail, quotePreview, actorName, eventId, deliveryId,
readString, readCount) and add a formatters.default for the current default
branch; then simplify formatActivityEvent to read kind, select formatters[kind
?? ''] ?? formatters.default and return formatter(event, nowIso), keeping all
formatting behavior identical to the switch-based implementation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2247bdf9-2d0c-44e4-9cd6-1c1372cdab25

📥 Commits

Reviewing files that changed from the base of the PR and between cf82bf5 and 2454032.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • src/cli/bootstrap.test.ts
  • src/cli/bootstrap.ts
  • src/cli/commands/activity.test.ts
  • src/cli/commands/activity.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2454032f1e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cli/commands/activity.ts Outdated
return formatLine(
nowIso,
'ERROR',
`${actorName(event)} ${readString(event, 'code') ?? 'worker_error'}${quotePreview(readString(event, 'message'), 120)}`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include nested worker_error payload details

worker_error events from the broker carry diagnostics under an error object ({"kind":"worker_error","name":...,"error":{...}} in crates/broker/src/runtime/worker_events.rs), but this formatter only reads top-level code/message. In practice, agent-relay activity will print a generic worker_error line and drop the actual failure reason whenever a worker emits an error, which defeats the command’s debugging purpose for one of its most important event types.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 6 additional findings.

Open in Devin Review

@willwashburn willwashburn merged commit 6bb74e5 into main May 20, 2026
47 checks passed
@willwashburn willwashburn deleted the codex/broker-activity-tail branch May 20, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant