Skip to content

feat: command palette for actions and database objects - #545

Merged
debba merged 32 commits into
TabularisDB:mainfrom
verbaux:feature/command-palette-foundation
Aug 11, 2026
Merged

feat: command palette for actions and database objects#545
debba merged 32 commits into
TabularisDB:mainfrom
verbaux:feature/command-palette-foundation

Conversation

@verbaux

@verbaux verbaux commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces QuickNavigatorModal with a Spotlight-style palette that has two (for now) modes: object search (tables, views, routines, triggers) and an action palette on Cmd/Ctrl+Shift+A.

image

The part worth reviewing is not the UI. Both palettes and the explorer sidebar each used to build their own "open this in the editor" logic — assembling SQL, guessing the tab type, and reading the active connection regardless of which pane the user clicked in. This PR gives them one contract to share.

What changed

Navigation contract

  • src/utils/editorNavigation.ts — router state now carries a typed EditorNavigationRequest; Editor.tsx parses it and opens the tab.
  • src/utils/databaseObjectActions.ts + src/hooks/useDatabaseObjectNavigation.ts — one definition of what "open / count / show definition" means per object type. The sidebar's 16 call sites and both palettes go through it.

Palette

  • src/utils/commandScopeStore.ts + src/hooks/useCommandPaletteScope.ts — each pane registers a command scope; the palette resolves against the active one. This is what makes split view target the right connection.
  • src/components/ui/SpotlightPalette.tsx — shared shell (focus trap, arrow navigation, ARIA combobox/listbox), used by both modes.
  • src/utils/paletteItems.ts + objectPaletteItems.ts — single item pipeline for search, grouping and ranking. Uses Fuse.js, already a dependency.

Modals no longer read the active connection

  • SchemaModal and GenerateSQLModal take an explicit TableTarget { connectionId, tableName, schema }. Before this, opening either from a non-active split pane inspected the wrong connection.

Shortcut

  • command_palette_actionsCmd+Shift+A / Ctrl+Shift+A, overridable in settings.

Test plan

  • pnpm typecheck clean
  • pnpm lint clean
  • pnpm test — 3658/3658 pass, 216 files
  • 17 new test files: command scoping across split panes (active scope, root fallback, missing scope), palette keyboard handling and focus trap, sidebar → navigation wiring for double-click and every context-menu entry, definition loading including the failure path, item search/grouping/ranking, route-state parser
  • Manual: split view, two connections — action palette from each pane targets that pane's table
  • Manual: object palette against Postgres (schemas) and SQLite/MySQL (no schemas)
  • Manual: routine and trigger definitions open read-only where expected

Known limitations

The object palette builds its multi-database list from the saved connection.params.database (src/hooks/useCommandPaletteObjectItems.ts:66), while #524/#530 reconcile dropped databases into selectedDatabases only. A database dropped on the server can still show up in the palette until the connection list reloads.

Not introduced here — QuickNavigatorModal read the same source, and quickNavigator.ts iterated configuredDatabases on main too. Left as-is because the fix is a one-line source swap but the multi-database path has no test fixture yet.

Open questions

Draft because I'd rather hear about the approach before polishing:

  • Scope registration. Panes registering into a store is a new pattern here. If you'd rather the scope came from context, or straight from editor state, say so and I'll rework it.
  • Route state as the contract. It keeps callers honest, but navigation intent now lives in location.state.
  • Nothing shows which palette you're in. The placeholder is the only cue and it disappears as soon as you type. Cheapest fix is a visible mode label in the header. The bigger question is whether these should stay two surfaces on two shortcuts (⌘P objects, ⌘⇧A actions) or become one palette with switchable modes, DataGrip-style.
  • Only two commands so far, deliberately. The action palette ships Open settings and Open current table in SQL console — enough to exercise the registry, the scoping and the navigation contract without padding the diff. Adding a third is one PaletteItem in createBuiltInCommandItems (src/utils/builtInCommands.ts) plus an i18n key. Anything that needs more than connectionId / driver / table extendsCommandScope first — switching connections is the obvious next one and the first case that would need that. Happy to take a list of what you'd want in the initial set.

@verbaux verbaux changed the title Feature/command palette foundation feat: command palette for actions and database objects Jul 28, 2026
@verbaux
verbaux force-pushed the feature/command-palette-foundation branch from a8ef2b7 to a8c3ac6 Compare August 2, 2026 15:54
@debba

debba commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Hi @verbaux , first off, sorry for taking so long to get back to you. This PR deserved a quicker reply, especially since you left such clear questions. And thank you for the work here, the navigation contract cleanup alone is something we've needed for a while.

Going through your points:

Scope registration. Keep the store. The palette is a single modal at the root while the scopes live in the panes, so a context-based approach would force the palette inside the active pane's provider, which doesn't really work with one modal and N panes. The store with useSyncExternalStore decouples who registers from who reads, and the ownership guard on cleanup already handles re-registration races, so I'm comfortable with the pattern. One thing I'd like to double check though: in split view the scope id is the connection id. If the same connection can end up open in two panes at once, they'd overwrite each other's registration. If that's a reachable state, the scope id should probably be the pane id rather than the connection id.

Route state as the contract. Fine by me. You clear the state right after consuming it and dedupe via the navigation key, so refresh and back don't re-run anything. And since split panes execute the intent directly without going through the router, route state stays what it should be: the cross-route contract to the main editor. No rework needed.

Mode indication. Let's do the cheap fix in this PR, a visible mode label in the header. The placeholder disappearing as soon as you type isn't enough of a cue. On the bigger question, I wouldn't block this PR on it. The shared SpotlightPalette shell makes merging the two surfaces into one palette cheap later, so keep the two shortcuts for now and we can revisit once there are more commands to justify a mode switcher.

Initial command set. A few that should fit the current CommandScope without extending anything, since they already exist as object actions: new SQL console at connection level (not just "open current table in console"), inspect / show schema for the current table, generate SQL, count rows. Plus "open connection manager" as pure navigation, same shape as open settings. I agree switching connections is the right first candidate for extending the scope, but I'd leave that for a follow-up rather than grow this diff.

On the known limitation with configuredDatabases: agreed it's pre-existing and fine to leave, but could you open a follow-up issue linking #524/#530 so it doesn't get lost?

Happy to take this out of draft whenever you feel ready, I'll do a proper pass with real data on the split view scenarios then. Thanks again for the thorough writeup, it made this much easier to review.

@verbaux

verbaux commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@debba Thanks for the detailed pass. Went through your points in order.

Scope registration

Keeping the store. On your question about the split view — the same connection cannot end up in two panes, and not by convention: the connection id already is the pane identity.

  • a leaf is { type: 'leaf'; connectionId: string } (connectionLayout.ts:11), so the tree has no separate pane concept to give an id to
  • every write to the split view happens in useConnectionLayout.ts (lines 61, 69, 75, 89, 93, 97, 101), and exactly one of them can introduce a connection that was not already there: addConnectionToSplit at :89, which goes through canAddToSplit (connectionLayout.ts:103) and rejects anything already in connectionIds
  • activateSplit builds the layout from a Set (useConnectionLayout.ts:59)
  • moveInSplit (connectionLayout.ts:219-224) and swapInSplit (connectionLayout.ts:252-256) both require each id to already be in the view, then rearrange in place

So a pane id would be a second name for the value we already use. If opening one connection in two panes ever becomes a feature, the layout tree has to grow a pane identity first, and the scope id follows it there — a small change in getActiveCommandScopeId once that exists.

Mode indication

Added a visible badge in the header carrying the dialog's accessible name — COMMAND PALETTE / DATABASE OBJECTS. It is aria-hidden, since the dialog's own aria-label already announces the mode.

Command set

Added all five, each reusing an action that already exists on database objects, with CommandScope untouched:

  • Open connection manager — plain navigation, same shape as open settings
  • New console — connection level, empty query, inheriting the schema currently in view
  • Inspect structure, Generate SQL templates, Count rows — pinned to the table in scope

Inspect and generate SQL open modals that CommandPaletteModal owns rather than navigating, so they arrive as a separate argument to createBuiltInCommandItems instead of going through CommandScope.runtime — that is what keeps the scope as it was.

Left switching connections out, as you suggested.

configuredDatabases

Filed as #591, linking both PRs. It turned out to be a bit worse than "the list can go stale": in all-databases mode the palette lists nothing at all, because the configured list is empty by design there and getNavigatorItems builds its groups exclusively from it.


Taking it out of draft. What I exercised by hand against a live PostgreSQL connection: the badge in both modes, the four table commands (the inspect modal renders over the closing palette, and count rows opens a console that runs and returns), and the two navigation commands. I have not driven the split-view scenarios with two panes — that part is still only covered by tests, so it is worth your pass with real data.

@verbaux
verbaux marked this pull request as ready for review August 3, 2026 11:39
@debba

debba commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Found one platform-specific issue while testing on Linux, plus a follow-up question.

1. Ctrl+Shift+A never reaches the palette when focus is inside the SQL editor (Linux only).

Monaco's "Toggle Block Comment" is Shift+Alt+A on Mac/Windows, but its Linux default is Ctrl+Shift+A (comment.js, linux: { primary: CtrlCmd | Shift | KeyA }). Since useGlobalShortcuts listens on window in the bubble phase, Monaco's keybinding service consumes the event first and the palette never opens; the editor toggles a block comment instead. That's why it didn't show up in your manual pass, it only bites on Linux.

The repo already has the right pattern for this: SqlEditorWrapper.tsx forwards trigger_suggestions through editor.onKeyDown with preventDefault + stopPropagation, which preempts Monaco's own handling. Extending that to command_palette_actions should be enough. Worth considering rebinding block comment to Shift+Alt+A on Linux too, so the feature stays reachable, it's genuinely useful in a SQL editor.

2. On the two shortcuts.

We agreed to keep Ctrl+P and Ctrl+Shift+A as separate surfaces for now, and I'm not reopening that. But the Monaco conflict makes me curious where you'd put the threshold: at what point (command count, or something else) would you consider the single-palette model with switchable modes worth doing? If we ever go the VS Code route (Ctrl+P plus > prefix), the in-editor shortcut clash mostly disappears on its own, which is one more small point in its favor.

@verbaux
verbaux force-pushed the feature/command-palette-foundation branch from 8a875d9 to b6d19ca Compare August 6, 2026 15:39
@verbaux

verbaux commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

@debba Both done, plus a few things from testing since.

Linux Ctrl+Shift+A. Fixed with the pattern you pointed at — SqlEditorWrapper forwards it through editor.onKeyDown with preventDefault + stopPropagation, same as trigger_suggestions already did. Also took the optional half: block comment moves to Shift+Alt+A on Linux so it stays reachable. Test included.

On the threshold. I don't think it's a command count, and I'd rather not go the VS Code route — typing > to pick a mode is the thing I don't want people thinking about.

What I keep coming back to is JetBrains: direct shortcuts for when you know what you want (⌘P, ⌘O, ⌘⇧A), plus Search Everywhere with tabs on top for when you don't. Which reframes your question — it's not "when do we collapse the two surfaces". Under that model ⌘P and ⌘⇧A stay exactly as they are and become the direct entries; the merged palette is a third thing added over them, with an All tab for when you're not sure what you're looking for.

So my answer: nothing to collapse, and the next step isn't a mode switcher. It's making the per-object actions we already attach — inspect, new console, generate SQL, count — reachable from the keyboard, since today they're click-or-Tab only.

Three things testing turned up, all fixed here:

  • Generate SQL → "Run in console" did nothing from a split pane. It navigated through the router, but with a split up MainLayout renders SplitPaneLayout instead of <Outlet/>, so there's no routed Editor to receive the intent. It now takes the active scope's openEditor, falling back to the router for the explorer.
  • The load-failure banner never cleared once a schema eventually loaded.
  • Opening the palette highlighted whatever row sat under the cursor. Two causes stacked: the row fired mouse enter without the mouse moving, and its CSS hover painted the selected colour on top of the real selection, so two rows looked active. One source of truth now.

Tested by hand: split view with two Postgres connections — the object palette resolves to the focused pane, Generate SQL reads that pane's connection, and "Run in console" lands in that pane. Not exercised: SQLite/MySQL without schemas, and the read-only routine/trigger definitions.

One thing to know before your pass: in split view the palette follows whichever pane has explorer focus, and there's no keyboard way to move it — explorerConnectionId only changes on a click, and ⌘⇧1…9 switches the active connection without touching it. So it's "click the pane, then open the palette". I'd fix that in a follow-up rather than grow this diff: show the target connection in the header, add a pane-focus shortcut. Can file it.

Rebased onto current main, 29 commits, force-pushed. That dropped your Merge branch 'main' (8a875d9) — the main it brought in is an ancestor of what I rebased onto, and the merge had no conflict resolutions of its own, so nothing was lost.

verbaux added 21 commits August 10, 2026 23:48
Overlay clicks are ignored unless a caller opts in with closeOnBackdrop,
so existing modals keep their current behaviour.
Routes that own the whole pane (root, connections, settings) never show a
split view, so the decision lives next to the layout model instead of the
components that render it.
Both palettes and the explorer sidebar used to build their own editor
navigation, each with a slightly different idea of what "open this object"
means. Route state now carries a typed EditorNavigationRequest, and the
sidebar, the palettes and the schema/SQL modals all go through it.

- Extract database object actions and editor navigation into utilities,
  exposed to components through useDatabaseObjectNavigation.
- Drop the separate actions/objects palette providers in favour of item
  hooks over a single palette context.
- Move the schema and generate-SQL modals onto an explicit TableTarget, so
  they no longer read the active connection behind the caller's back.
The locale landed upstream while this branch was in flight, so it was the
only one missing the palette keys.
verbaux and others added 8 commits August 10, 2026 23:48
The placeholder was the only cue for which palette had opened, and it
disappears as soon as the user types. Render the dialog's accessible name
as a visible badge instead, hidden from screen readers so the mode is not
announced twice.
Rounds out the initial command set with actions that already exist on
database objects: open the connection manager, open a console on the
current connection, and inspect, generate SQL for, or count the rows of
the table in scope.

Inspect and generate SQL open modals that CommandPaletteModal owns, so
they arrive as a separate argument rather than through CommandScope,
which stays as it is. Their labels reuse the object palette's, so only
the connection category and the connection manager needed translating.
One comment described how the superseded quick navigator treated views;
the other repeated what the docblock four lines above already said.
The palette resolves its scope from the focused connection. Behind a split
layout MainLayout renders SplitPaneLayout instead of <Outlet/>, so the routed
Editor is unmounted and anything reaching it through the router is dropped.

- GenerateSQLModal takes an optional openEditor, supplied from the active
  scope, and keeps router navigation as the fallback for the explorer
- a missing connection dialect now surfaces inline instead of guessing a
  dialect or firing an alert behind the modal
- failed object loads are reported in the palette and the report is dropped
  again once the schema or database finally loads
- the palette header names the open mode, and Ctrl+Shift+A reaches it from
  inside Monaco on Linux without losing toggle block comment

Tests cover the scope routing end to end, the load-failure recovery, and the
keyboard and focus behaviour of the shared palette shell.
Point the agent rules at the current gitnexus tool names and drop the stale
runner instructions. Ignore the scratch directories local tooling leaves in
the working tree so they cannot be committed by accident.
The banner arrived with the rebase and reads the database context, which this
suite does not provide — it mounts MainLayout with its neighbours stubbed to
assert the palette host alone.
Opening the palette under a resting cursor highlighted the row underneath it.
Two separate causes stacked up: the row fired mouse enter without the user
moving the mouse, and its CSS hover painted the selected background on top of
the row activeIndex already held, so two rows looked active at once.

Selection now has a single source. The pointer routes through activeIndex via
mouse move, which needs real cursor travel, and the hover styling is gone.
@verbaux
verbaux force-pushed the feature/command-palette-foundation branch from b6d19ca to ffae683 Compare August 10, 2026 22:09
});
setExplorerConnectionId(prev => (prev === connectionId ? null : prev));
}, []);
const next = splitView

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CRITICAL: removeConnectionFromSplit reads splitView from the closure instead of using a functional state update. If two panel-close gestures are batched in the same tick, the second callback reads the stale splitView from the original closure and computes the removal against the already-stale layout. The developer's own comment acknowledges this. This can leave an incorrect split layout after rapid multi-panel removal.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Acknowledged and intentional — the tradeoff is documented at useConnectionLayout.ts:74-77. The next layout is needed outside the updater to settle visibility and focus in the same pass.

Both call sites are single user gestures: SplitPaneLayout.tsx:75 (close button, and only reached with ≥3 panels — 2 panels take the deactivateSplit() branch at :69-72) and ConnectionGroupItem.tsx:99 (context menu item). React flushes discrete events separately, so two removals cannot land in one tick from the UI, and there is no programmatic multi-remove in the codebase. If one ever appears, the fix is the reducer noted in the comment.

Comment thread src/components/ui/SqlEditorWrapper.tsx
@@ -15,29 +15,27 @@ interface TableColumn {
interface SchemaModalProps {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Breaking API change. The prop interface changed from tableName: string; schema?: string | null to target: TableTarget. All internal call sites in this PR were updated, but any external consumer, plugin, or test that renders <SchemaModal tableName="..." schema={...} /> will now fail at compile time or runtime.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There are no external consumers.

import type { CommandRuntime } from "../../types/commands";
import { openEditor as navigateToEditor } from "../../utils/editorNavigation";

interface GenerateSQLModalProps {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Breaking API change. The prop interface changed from tableName: string to target: TableTarget. Same concern as SchemaModal.tsx: external callers using the old prop shape will break.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same as SchemaModal — private package, no published surface.

const connectionId = scope?.connectionId ?? null;
const requestDatabaseData = useEffectEvent(loadDatabaseData);
const requestSchemaData = useEffectEvent(loadSchemaData);
const loadAttemptsRef = useRef(new Map<string, number>());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: loadAttemptsRef is a useRef(new Map<string, number>()) that is never cleared when connectionId changes. The keys are namespaced by connection, so they do not collide, but the map grows unbounded across connection switches. Over a long session with many connections, this leaks memory with stale attempt counters that are never evicted.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No unbounded growth here. Entries are deleted on successful load (:112, :134), keys are namespaced per connection (:110, :132), and the hook only lives while the objects palette is open — ObjectPalette mounts conditionally at CommandPaletteModal.tsx:90-95, so the ref is recreated on every open. There is no long-lived instance for the map to accumulate in.

? "sidebar.failGetRoutineDefinition"
: "sidebar.failGetTriggerDefinition",
) + String(error),
{ kind: "error" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: showDefinitionError concatenates the translated label with String(error). For Error objects this includes the full stack trace, producing very long alert messages that expose internal file paths, line numbers, and framework internals to the user. The console.error(error) call already logs the raw error for debugging.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is carry-over of the existing pattern (ExplorerSidebar.tsx:2277, and ExplorerSidebar.tsx:461 on main), not new behavior

window.dispatchEvent(new CustomEvent("tabularis:paste-import"));
return;
}
if (matchesShortcut(e, "quick_navigator")) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: The quick_navigator shortcut handler now calls togglePalette("objects") instead of dispatching the tabularis:open-quick-navigator custom event. The old custom event is removed entirely. Any external code, plugins, or tests listening for tabularis:open-quick-navigator will silently stop working.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

tabularis:open-quick-navigator has zero references left in the repository.

const navigate = useNavigate();
const { matchesShortcut, isMac } = useKeybindings();
const { openConnections, handleSwitch } = useConnectionManager();
const { togglePalette } = useCommandPaletteDispatch();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: useCommandPaletteDispatch() is now called inside useGlobalShortcuts, and this hook throws if not wrapped in CommandPaletteProvider. Previously, useGlobalShortcuts only required KeybindingsProvider and BrowserRouter. This is a new implicit dependency. While the sole caller (MainLayout.tsx) is wrapped in CommandPaletteProvider, any future consumer of useGlobalShortcuts outside that provider will crash the app.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fair catch on the documentation. The dependency itself is fine — useCommandPaletteDispatch throws loudly (useCommandPalette.ts:20-23) rather than failing silently, and the only caller is wrapped (MainLayout.tsx:47-51). But the JSDoc at :15-17 still lists only KeybindingsProvider and BrowserRouter. Updating it to include CommandPaletteProvider.

@kilo-code-bot

kilo-code-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 8 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 2
WARNING 6
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
src/hooks/useConnectionLayout.ts 79 removeConnectionFromSplit reads splitView from closure instead of functional update
src/components/ui/SqlEditorWrapper.tsx 379 Ctrl+Shift+A intercepts Monaco block-comment on all platforms; no alternative on Windows/macOS

WARNING

File Line Issue
src/components/modals/SchemaModal.tsx 15 Breaking API change: prop interface changed from tableName: string to target: TableTarget
src/components/modals/GenerateSQLModal.tsx 22 Breaking API change: prop interface changed from tableName: string to target: TableTarget
src/hooks/useCommandPaletteObjectItems.ts 47 loadAttemptsRef map grows unbounded when connectionId changes
src/hooks/useDatabaseObjectActionRuntime.ts 31 String(error) exposes full stack trace including file paths to user
src/hooks/useGlobalShortcuts.ts 71 quick_navigator custom event tabularis:open-quick-navigator removed
src/hooks/useGlobalShortcuts.ts 23 New implicit dependency on CommandPaletteProvider
Files Reviewed (7 files)
  • src/hooks/useConnectionLayout.ts - 1 issue
  • src/components/ui/SqlEditorWrapper.tsx - 1 issue
  • src/components/modals/SchemaModal.tsx - 1 issue
  • src/components/modals/GenerateSQLModal.tsx - 1 issue
  • src/hooks/useCommandPaletteObjectItems.ts - 1 issue
  • src/hooks/useDatabaseObjectActionRuntime.ts - 1 issue
  • src/hooks/useGlobalShortcuts.ts - 2 issues

Fix these issues in Kilo Cloud

Previous Review Summaries (2 snapshots, latest commit c100325)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit c100325)

Status: 8 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 2
WARNING 6
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
src/hooks/useConnectionLayout.ts 79 removeConnectionFromSplit reads splitView from closure instead of functional update
src/components/ui/SqlEditorWrapper.tsx 379 Ctrl+Shift+A intercepts Monaco block-comment on all platforms; no alternative on Windows/macOS

WARNING

File Line Issue
src/components/modals/SchemaModal.tsx 15 Breaking API change: prop interface changed from tableName: string to target: TableTarget
src/components/modals/GenerateSQLModal.tsx 22 Breaking API change: prop interface changed from tableName: string to target: TableTarget
src/hooks/useCommandPaletteObjectItems.ts 47 loadAttemptsRef map grows unbounded when connectionId changes
src/hooks/useDatabaseObjectActionRuntime.ts 31 String(error) exposes full stack trace including file paths to user
src/hooks/useGlobalShortcuts.ts 71 quick_navigator custom event tabularis:open-quick-navigator removed
src/hooks/useGlobalShortcuts.ts 23 New implicit dependency on CommandPaletteProvider
Files Reviewed (7 files)
  • src/hooks/useConnectionLayout.ts - 1 issue
  • src/components/ui/SqlEditorWrapper.tsx - 1 issue
  • src/components/modals/SchemaModal.tsx - 1 issue
  • src/components/modals/GenerateSQLModal.tsx - 1 issue
  • src/hooks/useCommandPaletteObjectItems.ts - 1 issue
  • src/hooks/useDatabaseObjectActionRuntime.ts - 1 issue
  • src/hooks/useGlobalShortcuts.ts - 2 issues

Fix these issues in Kilo Cloud

Previous review (commit ffae683)

Status: 8 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 2
WARNING 6
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
src/hooks/useConnectionLayout.ts 79 removeConnectionFromSplit reads splitView from closure instead of functional update
src/components/ui/SqlEditorWrapper.tsx 379 Ctrl+Shift+A intercepts Monaco block-comment on all platforms; no alternative on Windows/macOS

WARNING

File Line Issue
src/components/modals/SchemaModal.tsx 15 Breaking API change: prop interface changed from tableName: string to target: TableTarget
src/components/modals/GenerateSQLModal.tsx 22 Breaking API change: prop interface changed from tableName: string to target: TableTarget
src/hooks/useCommandPaletteObjectItems.ts 47 loadAttemptsRef map grows unbounded when connectionId changes
src/hooks/useDatabaseObjectActionRuntime.ts 31 String(error) exposes full stack trace including file paths to user
src/hooks/useGlobalShortcuts.ts 70 quick_navigator custom event tabularis:open-quick-navigator removed
src/hooks/useGlobalShortcuts.ts 22 New implicit dependency on CommandPaletteProvider
Files Reviewed (7 files)
  • src/hooks/useConnectionLayout.ts - 1 issue
  • src/components/ui/SqlEditorWrapper.tsx - 1 issue
  • src/components/modals/SchemaModal.tsx - 1 issue
  • src/components/modals/GenerateSQLModal.tsx - 1 issue
  • src/hooks/useCommandPaletteObjectItems.ts - 1 issue
  • src/hooks/useDatabaseObjectActionRuntime.ts - 1 issue
  • src/hooks/useGlobalShortcuts.ts - 2 issues

Fix these issues in Kilo Cloud


Reviewed by glm-5.2 · Input: 45.7K · Output: 18.4K · Cached: 573.2K

useGlobalShortcuts now calls useCommandPaletteDispatch, which throws
outside CommandPaletteProvider. The JSDoc still listed only
KeybindingsProvider and BrowserRouter.
@debba

debba commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Hi @verbaux,

Sorry for the delay, I’ve been busy with work and some other stuff in Tabularis.

I’ll do a final review today and merge it if everything is ready on your side.

I saw you’re arguing with Kilobot, it’s not worth it.
I’ve had to switch to some free models over the past few weeks because we’d completely used up our credits, but the quality of the reviews is definitely not as good :)

@verbaux

verbaux commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Hi @debba
Thanks, I’ll be waiting for your verdict :)

My replies to Kilobot for anyone reviewing this pull request, in case they have any doubts.

debba
debba previously approved these changes Aug 11, 2026

@debba debba left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I love this feature and how it's implemented. The navigation contract is the right call: I verified locally that every editor navigation in the codebase now goes through the typed request, the split-pane scoping works exactly as described, and removing the silent ?? "sqlite" dialect fallback in GenerateSQLModal is a real fix on top. Typecheck, lint and the full suite (3707 tests) pass on the branch, and i18n is complete across all 11 locales.

From my side this is ready to merge. Just two things that look like local tooling that slipped into the branch, please check them:

  1. AGENTS.md: the GitNexus managed block got regenerated by a different local setup. It drops the explain security-review line and the detect_changes({scope: "compare", base_ref: "main"}) guidance, and replaces the node .gitnexus/run.cjs analyze instructions. Please restore the block as it is on main.
  2. .gitignore: the new entries (.foglamp/, .grove/, .groverc.json, .pnpm-store/, skills-lock.json, tasks/, *.local.md) are your local tools, not project artifacts. Broad patterns like tasks/ could silently hide real project files later. Please drop them (a global gitignore on your machine covers these better).

Once those two files are back to main's version, happy to merge immediately. Thanks for the excellent work!

The gitnexus block was regenerated by a different local setup and the
ignore entries were personal tooling, not project artifacts. Both are
back to main's version per review on TabularisDB#545; the local patterns moved to
.git/info/exclude.
@verbaux

verbaux commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

@debba my bad, with a large number of changes, it’s easy to miss these unwanted changes. I rolled them back to their original state.

@debba

debba commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

No worry.
I will merge in next minutes :)
Thanks a lot @verbaux

@debba
debba merged commit e800618 into TabularisDB:main Aug 11, 2026
2 checks passed
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.

2 participants