Skip to content

[DX-978] Implemented missing rooms presence commands#179

Open
sacOO7 wants to merge 6 commits intomainfrom
feature/add-chat-presence-commands
Open

[DX-978] Implemented missing rooms presence commands#179
sacOO7 wants to merge 6 commits intomainfrom
feature/add-chat-presence-commands

Conversation

@sacOO7
Copy link
Contributor

@sacOO7 sacOO7 commented Mar 20, 2026

  • Added rooms presence get, updated description to perform presence update operation.
  • presence update not needed, since exact same behaviour can be achieved using presence enter twice (added description for the same).
  • Publishing presence on behalf for given clientId also gives exact same output ( new connectionId with same clientId )
  • Refactored rooms enter for better status update --json/--pretty-json flag
  • Fixes https://ably.atlassian.net/browse/DX-978

Summary by CodeRabbit

  • New Features

    • Added rooms presence get-all (fetch members, --limit default 100, JSON/pretty-json)
    • Added rooms presence update (required --data, optional --duration/--client-id, JSON/pretty-json)
  • Improvements

    • Improved rooms presence enter and subscribe output and status reporting for both JSON and human modes
  • Documentation

    • README updated with new presence commands, flags, and examples
  • Tests

    • Added/updated unit tests for get-all, update, enter, and subscribe behaviors

@vercel
Copy link

vercel bot commented Mar 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cli-web-cli Ready Ready Preview, Comment Mar 25, 2026 6:49am

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b43980d5-abff-41be-a159-988f0a3918b2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Added two new room-presence CLI commands (rooms presence get-all, rooms presence update), revised presence event logging/JSON outputs for enter and subscribe, updated README examples, and added/updated unit tests for enter, get-all, update, and subscribe.

Changes

Cohort / File(s) Summary
Documentation
README.md
Added ably rooms presence get-all and ably rooms presence update entries, usage examples, and flags (--limit, --data, --duration, --client-id, --json, --pretty-json).
Presence: enter (output changes)
src/commands/rooms/presence/enter.ts
Reworked logging and JSON shape: emits structured presenceMessage JSON on enter, adds unconditional JSON status: "holding", prints non-JSON progress after attach, and removed prior finally cleanup logs.
Presence: get-all (new command)
src/commands/rooms/presence/get-all.ts
New command requiring room arg and --limit flag (default 100); uses REST channel room::$chat to fetch paginated presence, emits JSON result (members, hasMore, next, total) or human-readable output with pagination warnings.
Presence: update (new command)
src/commands/rooms/presence/update.ts
New command requiring room and --data (JSON); creates Chat client, attaches to room, calls presence.enter then presence.update, emits structured JSON presenceMessage (action update) or human-readable success and "Holding presence", then waits for cleanup/duration.
Presence: subscribe (output changes)
src/commands/rooms/presence/subscribe.ts
Removed current-members fetch, simplified client creation failure handling, changed per-event payload to flattened presenceMessage (action, room, clientId, connectionId, data, timestamp), emits { presenceMessage: ... } for JSON and updated multi-line human-readable blocks; removed finally logging.
Tests: enter (updated)
test/unit/commands/rooms/presence/enter.test.ts
Reorganized tests; added non-JSON progress assertion; updated JSON NDJSON expectations to assert result.presenceMessage and status records; adjusted show-others filtering and data handling checks.
Tests: get-all (new)
test/unit/commands/rooms/presence/get-all.test.ts
New unit tests covering default/custom --limit, JSON/pretty-json output, human-readable output, empty results, pagination metadata (hasMore, next, total), channel naming, and error cases.
Tests: update (new)
test/unit/commands/rooms/presence/update.test.ts
New unit tests validating --data parsing, attach ordering, presence.enter/presence.update invocation, JSON presenceMessage and status emission, invalid-JSON and API error propagation.
Tests: subscribe (updated)
test/unit/commands/rooms/presence/subscribe.test.ts
Updated simulated events to include connectionId and updatedAt; JSON assertions now read parsed.presenceMessage fields (action, clientId, connectionId).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as "CLI (get-all)"
    participant REST as "Ably REST"
    participant Channel as "Chat SDK Channel"
    participant Formatter as "Output Formatter"

    User->>CLI: ably rooms presence get-all ROOM --limit 100
    CLI->>REST: create REST client
    REST->>Channel: channels.get("ROOM::$chat")
    CLI->>Channel: presence.get({ limit: 100 })
    Channel-->>CLI: paginated presence members
    CLI->>CLI: collectPaginatedResults()
    CLI->>Formatter: emit fetched state / progress (non-JSON)
    alt JSON mode
        CLI->>Formatter: output JSON result (presenceMembers, hasMore, next, total)
    else Human-readable
        CLI->>Formatter: print formatted member list (clientId, connectionId, action, timestamp, Data)
    end
    Formatter-->>User: display results
Loading
sequenceDiagram
    participant User
    participant CLI as "CLI (update)"
    participant ChatClient as "Ably Chat Client"
    participant Room as "Room"
    participant Presence as "Presence API"
    participant Formatter as "Output Formatter"

    User->>CLI: ably rooms presence update ROOM --data '{"k":"v"}' --duration 30
    CLI->>ChatClient: create chat client
    ChatClient->>Room: rooms.get("ROOM")
    Room->>Room: attach()
    CLI->>Presence: presence.enter(parsedData)
    Presence-->>CLI: enter confirmed
    CLI->>Presence: presence.update(parsedData)
    Presence-->>CLI: update confirmed
    alt JSON mode
        CLI->>Formatter: output JSON result (presenceMessage action: update)
    else Human-readable
        CLI->>Formatter: print success, clientId, connectionId, Data, "Holding presence"
    end
    CLI->>Formatter: emit status "holding"
    CLI->>CLI: waitAndTrackCleanup(duration)
    Formatter-->>User: display result and hold state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped to tweak presence logs and play,
Fetching who’s near and nudging who’ll stay,
Enter now reports and update sends a cheer,
Tests hop through cases, tidy and clear,
The burrow’s brighter — carrots for the changelog!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: implementing two new rooms presence commands (get-all and update) plus refactoring the enter command for improved JSON output behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/add-chat-presence-commands

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.

@sacOO7 sacOO7 changed the title [DX-978] Implemented missing rooms presence [DX-978] Implemented missing rooms presence commands Mar 20, 2026
@umair-ably umair-ably force-pushed the feature/implement-missing-presence-commands branch from 3659708 to 4b182f3 Compare March 20, 2026 11:38
@sacOO7
Copy link
Contributor Author

sacOO7 commented Mar 20, 2026

@coderabbitai review

@sacOO7 sacOO7 requested a review from Copilot March 20, 2026 11:58
@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from 4afc78c to eecc67a Compare March 20, 2026 12:03
@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds the missing Rooms Presence CLI surface area and aligns rooms presence “enter/update” behavior with the newer JSON/status output patterns used across long-running commands.

Changes:

  • Introduces rooms presence get-all (REST-backed) and rooms presence update (Chat SDK-backed) commands.
  • Refactors rooms presence enter to emit progress output (human mode) and structured JSON result + “holding” status (JSON mode).
  • Adds unit tests and updates README command docs for the new rooms presence commands.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/unit/commands/rooms/presence/update.test.ts Adds unit coverage for the new rooms presence update command (human + JSON + error cases).
test/unit/commands/rooms/presence/get-all.test.ts Adds unit coverage for the new rooms presence get-all command, including pagination and JSON output.
test/unit/commands/rooms/presence/enter.test.ts Updates/refactors tests to match the new progress + JSON result/status behavior for rooms presence enter.
src/commands/rooms/presence/update.ts Implements rooms presence update using Chat SDK, with long-running “hold” semantics and JSON result/status output.
src/commands/rooms/presence/get-all.ts Implements rooms presence get-all by querying the underlying room::$chat channel presence via REST + pagination utilities.
src/commands/rooms/presence/enter.ts Adds progress output and JSON result/status emission; removes prior finally/logging behavior.
README.md Documents the new commands and adds them to the command index.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sacOO7 sacOO7 changed the base branch from feature/implement-missing-presence-commands to main March 20, 2026 12:06
Copy link

@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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/commands/rooms/presence/get-all.ts (1)

123-126: Keep the empty-state warning on stdout.

This is the only warning path in the command that goes to stderr; the pagination warnings in the same file already use stdout, so rooms presence get-all ends up behaving differently from the rest of the CLI for human-mode warnings.

♻️ Suggested change
-      } else if (items.length === 0) {
-        this.logToStderr(
-          formatWarning("No members currently present in this room."),
-        );
+      } else if (items.length === 0) {
+        this.log(formatWarning("No members currently present in this room."));
       } else {

Based on learnings, warnings produced by formatWarning(...) in src/commands/** should be emitted via this.log(...) on stdout when human output is enabled.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/rooms/presence/get-all.ts` around lines 123 - 126, In the
empty-state branch inside the rooms presence get-all command, replace the stderr
emission with stdout: change the call that uses
this.logToStderr(formatWarning("No members currently present in this room.")) to
emit via this.log(...) so the formatted warning follows the same human-mode
stdout pattern as other pagination warnings; locate the branch that checks
items.length === 0 and update the call to use this.log with formatWarning to
maintain consistent CLI behavior.
test/unit/commands/rooms/presence/enter.test.ts (1)

99-151: Assert on runCommand() output here instead of spying on console.log.

runCommand() already captures oclif output for unit tests, so this adds a second capture path and makes the test more fragile than the rest of the suite.

♻️ Suggested change
-      const capturedLogs: string[] = [];
-
-      const logSpy = vi.spyOn(console, "log").mockImplementation((msg) => {
-        capturedLogs.push(String(msg));
-      });
-
       let presenceCallback: ((event: unknown) => void) | null = null;
       room.presence.subscribe.mockImplementation((callback) => {
         presenceCallback = callback;
         return { unsubscribe: vi.fn() };
       });
@@
-      await commandPromise;
-      logSpy.mockRestore();
-
-      const output = capturedLogs.join("\n");
+      const { stdout } = await commandPromise;
+      const output = stdout;

Based on learnings, unit tests in this repo should assert stdout from runCommand() and reserve console.log spies for integration/e2e coverage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/rooms/presence/enter.test.ts` around lines 99 - 151,
Remove the console.log spy and assert on the oclif-captured output from
runCommand instead: stop creating capturedLogs and vi.spyOn(console,"log"), keep
the mock room and presence.subscribe setup and the presenceCallback event
simulation, but call and await runCommand(...) to get its stdout (e.g., const
output = await runCommand(["rooms:presence:enter","test-room","--show-others"],
import.meta.url)), then assert output contains "other-user" and does not contain
mock.clientId; also remove logSpy.mockRestore() and any capturedLogs.join usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Line 4250: The new fenced code blocks currently lack a language tag which
triggers markdownlint MD040; update the two newly added triple-backtick fences
(the anonymous fenced blocks around the command docs) to include an appropriate
language label such as text or sh-session so CI passes, and if these sections
are generated, change the generator/source that emits those fences instead of
just patching the README.

---

Nitpick comments:
In `@src/commands/rooms/presence/get-all.ts`:
- Around line 123-126: In the empty-state branch inside the rooms presence
get-all command, replace the stderr emission with stdout: change the call that
uses this.logToStderr(formatWarning("No members currently present in this
room.")) to emit via this.log(...) so the formatted warning follows the same
human-mode stdout pattern as other pagination warnings; locate the branch that
checks items.length === 0 and update the call to use this.log with formatWarning
to maintain consistent CLI behavior.

In `@test/unit/commands/rooms/presence/enter.test.ts`:
- Around line 99-151: Remove the console.log spy and assert on the
oclif-captured output from runCommand instead: stop creating capturedLogs and
vi.spyOn(console,"log"), keep the mock room and presence.subscribe setup and the
presenceCallback event simulation, but call and await runCommand(...) to get its
stdout (e.g., const output = await
runCommand(["rooms:presence:enter","test-room","--show-others"],
import.meta.url)), then assert output contains "other-user" and does not contain
mock.clientId; also remove logSpy.mockRestore() and any capturedLogs.join usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 135fd8ff-2d03-4243-a03c-8ed5ce4fbe28

📥 Commits

Reviewing files that changed from the base of the PR and between 4b182f3 and 4afc78c.

📒 Files selected for processing (7)
  • README.md
  • src/commands/rooms/presence/enter.ts
  • src/commands/rooms/presence/get-all.ts
  • src/commands/rooms/presence/update.ts
  • test/unit/commands/rooms/presence/enter.test.ts
  • test/unit/commands/rooms/presence/get-all.test.ts
  • test/unit/commands/rooms/presence/update.test.ts

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@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.

♻️ Duplicate comments (1)
README.md (1)

4252-4276: ⚠️ Potential issue | 🟡 Minor

Add language tags to these fenced command blocks (MD040).
Both new fenced blocks are still missing a language identifier, so markdownlint will keep failing.

Suggested patch
-```
+```text
 USAGE
   $ ably rooms presence get-all ROOM [-v] [--json | --pretty-json] [--limit <value>]
@@
   $ ably rooms presence get-all my-room --pretty-json

@@
- +text
USAGE
$ ably rooms presence update ROOM --data [-v] [--json | --pretty-json] [--client-id ] [-D ]
@@
$ ably rooms presence update my-room --data '{"status":"online"}' --duration 60

Also applies to: 4316-4344

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 4252 - 4276, The markdown fenced code blocks for the
CLI examples (the blocks showing "USAGE ... ably rooms presence get-all ..." and
the block for "ably rooms presence update ...") lack a language identifier and
trigger MD040; update each opening fence from ``` to ```text for the two shown
examples (and the other occurrences noted around the presence update example and
the duplicate region) so the blocks are explicitly marked as plain text and
markdownlint stops flagging them.
🧹 Nitpick comments (1)
test/unit/commands/rooms/presence/enter.test.ts (1)

104-151: Use stdout from runCommand() result instead of console.log spying for consistency with other tests.

This test manually spies on console.log to capture presence event output, but the pattern in similar streaming tests (e.g., rooms:typing:subscribe) shows that runCommand() properly captures all this.log() calls in stdout. Simply await the command and use the result's stdout property, which is cleaner and aligns with repository standards.

Suggested refactor
-      const capturedLogs: string[] = [];
-
-      const logSpy = vi.spyOn(console, "log").mockImplementation((msg) => {
-        capturedLogs.push(String(msg));
-      });
-
       let presenceCallback: ((event: unknown) => void) | null = null;
       room.presence.subscribe.mockImplementation((callback) => {
         presenceCallback = callback;
         return { unsubscribe: vi.fn() };
       });
 
-      const commandPromise = runCommand(
+      const result = await runCommand(
         ["rooms:presence:enter", "test-room", "--show-others"],
         import.meta.url,
       );
 
       await vi.waitFor(
         () => {
           expect(room.presence.subscribe).toHaveBeenCalled();
         },
         { timeout: 1000 },
       );
 
       // Simulate a self event (should be filtered out)
       if (presenceCallback) {
         presenceCallback({
           type: "enter",
           member: {
             clientId: mock.clientId,
             data: {},
           },
         });
 
         // Simulate another user's event (should be shown)
         presenceCallback({
           type: "enter",
           member: {
             clientId: "other-user",
             data: {},
           },
         });
       }
-
-      await commandPromise;
-      logSpy.mockRestore();
-
-      const output = capturedLogs.join("\n");
+      const output = result.stdout;
       expect(output).toContain("other-user");
       expect(output).not.toContain(mock.clientId);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/rooms/presence/enter.test.ts` around lines 104 - 151,
Remove the manual console.log spy and capturedLogs logic and instead await the
runCommand(...) call to get its result object, use room.presence.subscribe mock
to capture presenceCallback as before, invoke presenceCallback with the self and
other-user events, then await the runCommand result and assert against
result.stdout (expect it to contain "other-user" and not contain mock.clientId);
update references to runCommand, room.presence.subscribe, presenceCallback, and
mock.clientId accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@README.md`:
- Around line 4252-4276: The markdown fenced code blocks for the CLI examples
(the blocks showing "USAGE ... ably rooms presence get-all ..." and the block
for "ably rooms presence update ...") lack a language identifier and trigger
MD040; update each opening fence from ``` to ```text for the two shown examples
(and the other occurrences noted around the presence update example and the
duplicate region) so the blocks are explicitly marked as plain text and
markdownlint stops flagging them.

---

Nitpick comments:
In `@test/unit/commands/rooms/presence/enter.test.ts`:
- Around line 104-151: Remove the manual console.log spy and capturedLogs logic
and instead await the runCommand(...) call to get its result object, use
room.presence.subscribe mock to capture presenceCallback as before, invoke
presenceCallback with the self and other-user events, then await the runCommand
result and assert against result.stdout (expect it to contain "other-user" and
not contain mock.clientId); update references to runCommand,
room.presence.subscribe, presenceCallback, and mock.clientId accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a3bf8989-db81-4a1d-b372-a98736a158a8

📥 Commits

Reviewing files that changed from the base of the PR and between 4afc78c and eecc67a.

📒 Files selected for processing (7)
  • README.md
  • src/commands/rooms/presence/enter.ts
  • src/commands/rooms/presence/get-all.ts
  • src/commands/rooms/presence/update.ts
  • test/unit/commands/rooms/presence/enter.test.ts
  • test/unit/commands/rooms/presence/get-all.test.ts
  • test/unit/commands/rooms/presence/update.test.ts
✅ Files skipped from review due to trivial changes (2)
  • test/unit/commands/rooms/presence/get-all.test.ts
  • src/commands/rooms/presence/enter.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/commands/rooms/presence/get-all.ts
  • src/commands/rooms/presence/update.ts
  • test/unit/commands/rooms/presence/update.test.ts

@sacOO7
Copy link
Contributor Author

sacOO7 commented Mar 20, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/commands/rooms/presence/enter.ts:70

  • --data "{}" is currently treated as “no data” (rawData !== "{}"), which makes this.data stay null even though the command will still enter presence with a non-null payload (see the presence.enter(this.data || {}) call below). This can lead to the CLI reporting data: null in JSON/human output while the actual presence data is {}. Consider removing the special-case for "{}" and always parsing provided JSON, including an empty object, so output reflects the actual presence payload.
    const rawData = flags.data;
    if (rawData && rawData !== "{}") {
      const parsed = this.parseJsonFlag(rawData, "data", flags);
      this.data = parsed as PresenceData;
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/commands/rooms/presence/subscribe.ts (1)

115-117: Consider removing the redundant timestamp line.

Line 116 outputs a visual timestamp via formatTimestamp(timestamp), and line 117 immediately outputs the same timestamp with a label. This results in the timestamp appearing twice in the output. If the visual separator is intentional, consider adding a brief comment explaining the purpose.

♻️ Proposed fix to remove redundancy
         const lines: string[] = [
-          formatTimestamp(timestamp),
           `${formatLabel("Timestamp")} ${timestamp}`,
           `${formatLabel("Action")} ${formatEventType(event.type)}`,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/rooms/presence/subscribe.ts` around lines 115 - 117, The lines
array currently contains both formatTimestamp(timestamp) and
`${formatLabel("Timestamp")} ${timestamp}`, causing the same timestamp to appear
twice; open the const lines definition in subscribe.ts (look for formatTimestamp
and formatLabel usage) and remove the redundant entry (prefer keeping the visual
formatTimestamp(timestamp) and delete the `${formatLabel("Timestamp")}
${timestamp}` line), or if the visual separator is intentional keep both but add
a short comment explaining why both are present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/rooms/presence/get-all.ts`:
- Around line 72-77: The log messages currently interpolate raw roomName when
calling this.logCliEvent in get-all (e.g., the "Fetching presence members for
room ${roomName}" message and the later message around the membership result);
replace those interpolations with formatted output by calling
formatResource(roomName) so the room name is displayed consistently (cyan)
across command output; update both places where roomName is embedded in the
message and any related metadata strings passed to this.logCliEvent to use
formatResource(roomName) instead of the raw variable.

---

Nitpick comments:
In `@src/commands/rooms/presence/subscribe.ts`:
- Around line 115-117: The lines array currently contains both
formatTimestamp(timestamp) and `${formatLabel("Timestamp")} ${timestamp}`,
causing the same timestamp to appear twice; open the const lines definition in
subscribe.ts (look for formatTimestamp and formatLabel usage) and remove the
redundant entry (prefer keeping the visual formatTimestamp(timestamp) and delete
the `${formatLabel("Timestamp")} ${timestamp}` line), or if the visual separator
is intentional keep both but add a short comment explaining why both are
present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a8134939-1be5-4f2e-9ac7-5b3b5f2b66dd

📥 Commits

Reviewing files that changed from the base of the PR and between eecc67a and bc04fe3.

📒 Files selected for processing (8)
  • src/commands/rooms/presence/enter.ts
  • src/commands/rooms/presence/get-all.ts
  • src/commands/rooms/presence/subscribe.ts
  • src/commands/rooms/presence/update.ts
  • test/unit/commands/rooms/presence/enter.test.ts
  • test/unit/commands/rooms/presence/get-all.test.ts
  • test/unit/commands/rooms/presence/subscribe.test.ts
  • test/unit/commands/rooms/presence/update.test.ts
✅ Files skipped from review due to trivial changes (1)
  • test/unit/commands/rooms/presence/get-all.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/unit/commands/rooms/presence/update.test.ts
  • src/commands/rooms/presence/update.ts
  • src/commands/rooms/presence/enter.ts

@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from 768467a to 432c8d3 Compare March 23, 2026 06:48
@sacOO7 sacOO7 marked this pull request as ready for review March 23, 2026 07:02
@sacOO7 sacOO7 requested a review from umair-ably March 23, 2026 07:21
@@ -0,0 +1,166 @@
import { Args, Flags } from "@oclif/core";
Copy link
Contributor

Choose a reason for hiding this comment

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

Chat doesn't have the concept of get-all for presence, it has get (getAll is a spaces thing) - the CLI should probably follow the SDKs patterns unless we have a good reason to deviate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, but this retrieves presence for all chat members, correct? The term get sounds singular and might not stay consistent with the rest of the commands.
Since we’re not strictly adhering to product-specific command patterns anyway.. wdyt

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Btw, we also use get-all for channels presence
i.e.

Ably channel presence commands:

  ably channels presence enter       - Enter presence on a channel and listen for presence events
  ably channels presence get-all     - Get all current presence members on a channel
  ably channels presence subscribe   - Subscribe to presence events on a channel
  ably channels presence update      - Update presence data on a channel

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 3f6a2f1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for channels presence get-all fix, created PR -> #186

);

// Show pagination warning early (before main output)
const paginationWarning = formatPaginationLog(
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a note on the warning message here, its the individual messages that count towards the billable messages, not the pages consumed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

fixed here #183

@@ -0,0 +1,162 @@
import { ChatClient, PresenceData, Room } from "@ably/chat";
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the thinking behind this command?

So update will come through as an update event, but you won't be updating an "existing" presence member, you'll just get 2 members (even if you use the same clientId). If that's the intention, fine - but just checking reality vs expectation for users :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's true. If someone wants to test user presence on UI for given client-id where they don't really care about connectionId, this command should make sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel things get tricky when we use CLI to achieve same behaviour as SDK methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

chat rooms only respect identified clients, updating clientId on behalf of another user with wildcard (*) isn't supported, so we can accordingly add a warning message here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 3f6a2f1

Copy link
Contributor Author

@sacOO7 sacOO7 Mar 24, 2026

Choose a reason for hiding this comment

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

  • Removed presence update command since exact same behaviour can be achieved using presence enter twice ( added description for the same )
  • Publishing presence on behalf for given clientId also gives exact same output ( new connectionId with same clientId )
  • presence update doesn't seem to serve any meaningful purpose, we can only mark clientId as required and presence update always emits enter as first event, since connectionId is always different 
  • presence member is identified based on combination of clientId and connectionId

@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from 7ca5070 to c776aa5 Compare March 24, 2026 09:34
@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from c776aa5 to 3f6a2f1 Compare March 24, 2026 09:52
@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from 3f6a2f1 to c524e64 Compare March 24, 2026 10:08
@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from c524e64 to 3a407f1 Compare March 24, 2026 10:10
@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from 3a407f1 to 1980ecd Compare March 24, 2026 10:22
@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from 1980ecd to f3e1e90 Compare March 24, 2026 15:15
@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from f3e1e90 to 9f516fa Compare March 24, 2026 15:25
@sacOO7 sacOO7 force-pushed the feature/add-chat-presence-commands branch from 9f516fa to 54319c4 Compare March 24, 2026 16:17
- Marked clientId as mandatory while updating a presence, added warning about
how enter and update works

static override description =
"Enter presence in a chat room and remain present until terminated";
"Enter presence in a chat room and remain present until terminated. Provide clientId and data to update existing presence member.";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Provide clientId and data to update existing presence member

is this entirely true? I thought the combination of connection id and client id basically acts like a new presence for the same user? That's not the same as updating an existing presence member?

Copy link
Contributor Author

@sacOO7 sacOO7 Mar 25, 2026

Choose a reason for hiding this comment

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

I tested it using wildcard clientId * as per Publishing presence on behalf with channel.presence.update method.
It emitted enter event in subscriber with same clientId but had a different connectionId.
This is same behavior we get when using channels presence update or channels presence enter --client-id=my-id

Copy link
Collaborator

Choose a reason for hiding this comment

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

yes, but as per the docs, if you had already entered presence with clientID = example on a different client e.g. an iOS app and then tried to "update" the same clientID = example on the cli, this would in fact show as 2 presence enters?

it's not really an update because of how we treat the combination of client ids and connection ids as unique presence events?

Copy link
Collaborator

Choose a reason for hiding this comment

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

the point i'm making is that I don't think we need a change to the description given you are still just entering presence again with the same member - it's not an update.

Copy link
Contributor Author

@sacOO7 sacOO7 Mar 25, 2026

Choose a reason for hiding this comment

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

Yes, presence.update method call shows two presence enter if request is coming from different ably clients, because connectionId is always different.
It will only work, if presence.update call is made on the same ably connection.
Different connectionId denotes presence on different devices for same user clientId.
Users can filter by clientId and timestamp to calculate latest presence if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, makes sense.
It's tricky to tell how to update their presence for given clientId using presence enter.
Maybe it's better to drop the new description.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants