Repository navigation
feat: Commands system enhancements - #396
Conversation
Co-authored-by: Ilya Boyandin <[email protected]>
Co-authored-by: Ilya Boyandin <[email protected]>
Co-authored-by: Ilya Boyandin <[email protected]>
|
Cursor Agent can help with this pull request. Just |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds keystroke-aggregated command handling, a middleware pipeline with lifecycle events and telemetry hooks, updates the command palette to use keystrokes, wires createCommandProps through room-shell, expands public exports/types, updates docs, and adds tests for the new invocation flow. (≤50 words) Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Palette as Command Palette
participant Store as Command Slice
participant Middleware as Middleware Stack
participant Cmd as Command Execute
participant Telemetry as Telemetry Callbacks
User->>Palette: Press keystroke
Palette->>Palette: normalizeKeyboardEventKeystroke()
Palette->>Palette: check palette toggle keystroke
Palette->>Store: lookup command via keystrokeCommandMap
Store->>Telemetry: onCommandInvokeStart(...)
Store->>Middleware: runCommandExecutionMiddleware(command, input, context)
Middleware->>Cmd: invoke command.execute(input, context)
Cmd-->>Middleware: result / throw error
Middleware->>Store: return result or propagate error
alt Success
Store->>Telemetry: onCommandInvokeSuccess(..., duration)
else Failure
Store->>Telemetry: onCommandInvokeFailure(..., duration)
else Error
Store->>Telemetry: onCommandInvokeError(..., duration)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/commands.md`:
- Around line 62-69: The example middleware uses await inside a non-async arrow
function; change the anonymous middleware signature to an async function so
await next() is valid (e.g., make the arrow function async (command, input,
context, next) => { const result = await next(); return result; }); ensure the
symbols mentioned (next and result) remain and the function signature reflects
async to match the later example.
In `@packages/room-store/src/CommandSlice.ts`:
- Around line 389-404: The code unconditionally calls
invokeCommandSliceCallback(props?.onCommandInvokeSuccess, ...) even when
normalizeCommandExecuteResult(command.id, rawResult) yields a failure object;
change the flow in CommandSlice.ts so that after computing normalizedResult you
check normalizedResult.success (or equivalent flag) and only call
invokeCommandSliceCallback with props?.onCommandInvokeSuccess when success ===
true; when success === false, call the failure callback
(props?.onCommandInvokeFailure or the appropriate failure handler) with the same
payload (command, input, context, result, durationMs) and use
get().room.captureException for error reporting—update the branches around
normalizeCommandExecuteResult and invokeCommandSliceCallback to reflect this
conditional dispatch.
- Around line 687-694: The invokeMiddleware chain currently hands middleware a
raw async next() allowing multiple calls; wrap the next callback returned to
each middleware with a local "called" guard so calling next() more than once
throws an error (or returns a rejected promise) to prevent duplicate execution.
In practice, inside invokeMiddleware(index) capture currentMiddleware and supply
it a wrapped next that checks a boolean flag (e.g., called) and sets it before
invoking invokeMiddleware(index+1), throwing/rejecting if called is already
true; keep the existing fallback to command.execute(context, input) when no
middleware remains. This change touches invokeMiddleware, currentMiddleware,
middleware, command.execute and the next() callback passed into middleware.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
docs/.vitepress/config.tsdocs/commands.mdpackages/room-shell/src/RoomShellCommandPalette.tsxpackages/room-shell/src/RoomShellSlice.tspackages/room-shell/src/index.tspackages/room-store/__tests__/CommandSlice.test.tspackages/room-store/src/CommandSlice.tspackages/room-store/src/index.tspackages/sql-editor/src/SqlEditorSlice.tsx
Co-authored-by: Ilya Boyandin <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/room-store/src/CommandSlice.ts (1)
364-371: Emit lifecycle callbacks for disabled-command early exits.Disabled commands currently return before lifecycle callbacks are emitted, so these failed invocations are invisible to telemetry subscribers.
💡 Suggested adjustment
+ const invocationStartEvent: RoomCommandInvokeStartEvent<RS> = { + command, + input, + context: executionContext, + }; + const invocationStartedAt = Date.now(); + invokeCommandSliceCallback( + props?.onCommandInvokeStart, + invocationStartEvent, + get().room.captureException, + ); + if (!resolveCommandEnabled(command, executionContext)) { - return { + const disabledResult: RoomCommandResult = { success: false, commandId: command.id, code: 'command-disabled', error: `Command "${command.name}" is currently disabled.`, }; + invokeCommandSliceCallback( + props?.onCommandInvokeFailure, + { + ...invocationStartEvent, + result: disabledResult, + durationMs: Date.now() - invocationStartedAt, + }, + get().room.captureException, + ); + return disabledResult; } - - const invocationStartEvent: RoomCommandInvokeStartEvent<RS> = { - command, - input, - context: executionContext, - }; - const invocationStartedAt = Date.now(); - invokeCommandSliceCallback( - props?.onCommandInvokeStart, - invocationStartEvent, - get().room.captureException, - );Also applies to: 373-383
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/room-store/src/CommandSlice.ts` around lines 364 - 371, The early-return when resolveCommandEnabled(command, executionContext) is false should still fire the same lifecycle callbacks as other failure paths: before returning the { success: false, commandId: command.id, code: 'command-disabled', ... } result, invoke the lifecycle/telemetry emission used elsewhere in this file for failed invocations (the same pattern used in the other early-exit branches around lines 373-383) and pass the command id, name, executionContext and the error payload (code 'command-disabled' and the message) so telemetry subscribers receive the disabled-command event.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/room-store/src/CommandSlice.ts`:
- Around line 594-601: The loop over keystrokes currently calls keystroke.trim()
assuming every element is a string; guard against malformed/non-string elements
by checking typeof keystroke === 'string' before calling trim (or use
String(keystroke).trim() if you want to coerce), skip empty results, and then
add the normalized value to deduplicated; apply the same defensive change to the
other identical block that operates on keystrokes (the block referenced around
symbols keystroke, keystrokes, deduplicated).
---
Nitpick comments:
In `@packages/room-store/src/CommandSlice.ts`:
- Around line 364-371: The early-return when resolveCommandEnabled(command,
executionContext) is false should still fire the same lifecycle callbacks as
other failure paths: before returning the { success: false, commandId:
command.id, code: 'command-disabled', ... } result, invoke the
lifecycle/telemetry emission used elsewhere in this file for failed invocations
(the same pattern used in the other early-exit branches around lines 373-383)
and pass the command id, name, executionContext and the error payload (code
'command-disabled' and the message) so telemetry subscribers receive the
disabled-command event.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
docs/commands.mdpackages/room-shell/src/index.tspackages/room-store/__tests__/CommandSlice.test.tspackages/room-store/src/CommandSlice.tspackages/room-store/src/index.ts
✅ Files skipped from review due to trivial changes (1)
- packages/room-store/tests/CommandSlice.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/commands.md
Co-authored-by: Ilya Boyandin <[email protected]>
Co-authored-by: Ilya Boyandin <[email protected]>
Adds command keystroke support and a middleware pipeline, along with expanded test coverage and documentation, to enhance command system usability and extensibility.
Summary by CodeRabbit
New Features
Documentation
Improvements
Tests