Skip to content

Add CLI Tools settings UI, fix stuck cancel, DO-block limit clause, a… - #229

Merged
kix007 merged 4 commits into
mainfrom
feat/cli-tools-settings-ui-and-windows-fixes
Jul 29, 2026
Merged

Add CLI Tools settings UI, fix stuck cancel, DO-block limit clause, a…#229
kix007 merged 4 commits into
mainfrom
feat/cli-tools-settings-ui-and-windows-fixes

Conversation

@kix007

@kix007 kix007 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator
  • Expose a CLI tools management UI (Settings → CLI Tools) #39: Settings -> CLI Tools management UI (status, cached versions with disk usage, remove-cached, pre-download picker) backed by new cli_remove_cached command
  • Cancel querie #212: Cancel Query left the app unable to run further queries; the abandoned run's finally block could still clobber isExecuting/generation state after cancellation
  • applyQueryLimit / query executor no longer appends a LIMIT clause to PL/pgSQL DO $$ ... $$ blocks containing RETURNING
  • Double-clicking a table-nested trigger no longer mis-resolves its DDL lookup path
  • Saved query tabs are no longer wiped from sessions.json by a save/restore race on launch
  • MySQL CLI auto-download now works on Windows (missing URL + binary relocation for .exe-suffixed archives, shared with mongosh)
  • CLI subprocess calls no longer flash a console window on Windows
  • Saved queries no longer silently disappear on Windows due to unstable machine-ID detection; machine ID is now cached in the OS keyring and fingerprint/decrypt failures are now logged instead of swallowed

Summary

Related issue

Changes

Testing notes

Checklist

  • I built the app locally (npm run tauri dev or npm run tauri build) and verified the change works.
  • Frontend typecheck passes (npx tsc --noEmit).
  • Rust build passes (cargo check --manifest-path src-tauri/Cargo.toml).
  • If I added a new #[tauri::command], I registered it in src-tauri/src/lib.rs's generate_handler!.
  • If user-visible: I added a line to CHANGELOG.md under ## [Unreleased].
  • If this touches storage.rs, updater.rs, capabilities/, or the AI assistant code path, I flagged it in the summary above.

Summary by CodeRabbit

  • New Features
    • Added Settings → CLI Tools to manage installed/cached CLI versions, including PATH detection, per-version disk usage, version downloads, and cached removals.
  • Bug Fixes
    • Fixed trigger DDL loading for nested triggers.
    • Resolved session and saved-query restore races; improved Windows machine-ID persistence and surfaced previously silent errors.
    • Strengthened PostgreSQL DO handling (run-all execution, success messaging, and query-limit protection) and made cancellations run-scoped.
    • Improved Windows CLI downloads/extraction and suppressed console popups.
  • Tests
    • Added DO-block regression coverage for query limiting.

@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
queryden Ready Ready Preview, Comment Jul 29, 2026 11:37am

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The update improves Windows CLI execution and caching, adds CLI Tools management in Settings, handles PostgreSQL DO blocks consistently, stabilizes saved-query restoration, improves diagnostics, and fixes trigger DDL lookup and query cancellation behavior.

Changes

CLI and query reliability

Layer / File(s) Summary
Windows CLI execution and archive support
src-tauri/src/cli.rs
Suppresses Windows console windows, selects Windows MySQL archives, relocates .exe binaries, and applies the subprocess configuration across CLI operations.
CLI cache and Settings management
src-tauri/src/cli.rs, src-tauri/src/lib.rs, src/lib/ipc.ts, src/store/cliStore.ts, src/components/settings/SettingsDialog.tsx, CHANGELOG.md
Reports cached tool disk usage, exposes version removal through Tauri and IPC, and adds CLI discovery, downloads, cached-version details, removal confirmation, and refresh behavior to Settings.
Statement splitting and DO-block handling
src/components/editor/QueryEditor.tsx, src/components/layout/MainContent.tsx, src/utils/applyQueryLimit.ts, src/utils/applyQueryLimit.test.ts
Uses shared statement splitting, excludes PostgreSQL DO blocks from SELECT and limit handling, and adds regression coverage and DO-specific messages.
Execution and saved-query persistence
src/components/layout/MainContent.tsx, src-tauri/src/storage.rs, src/store/savedQueryStore.ts, CHANGELOG.md
Gates session writes until restoration, adds run-scoped cancellation and generation guards, persists machine IDs through the OS keyring, and logs saved-query load failures.
Trigger DDL context resolution
src/components/explorer/DatabaseExplorer.tsx, src/contexts/ConnectionContext.tsx
Passes trigger schema and table context into constrained Postgres DDL lookups while preserving non-trigger identifier handling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CliToolsSettings
  participant useCliStore
  participant Tauri
  participant CliManager
  User->>CliToolsSettings: select CLI tool version
  CliToolsSettings->>useCliStore: download or remove cached version
  useCliStore->>Tauri: invoke CLI command
  Tauri->>CliManager: download or remove tool cache
  CliManager-->>Tauri: return operation result
  Tauri-->>useCliStore: refresh cached and detected tools
  useCliStore-->>CliToolsSettings: display updated status and disk usage
Loading

Possibly related PRs

Suggested reviewers: keens007

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title names the main changes and is concise, though slightly truncated.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cli-tools-settings-ui-and-windows-fixes

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src-tauri/src/cli.rs (1)

390-409: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve the MySQL ZIP runtime layout.

relocate_binaries() only moves the MySQL binaries into versioned_dir/bin; the extracted lib, share, and related installation-tree resources stay behind in the ZIP’s root directory. Move/copy the complete MySQL installation tree for Windows ZIP downloads, then keep the versioned binary path pointing inside it.

🤖 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-tauri/src/cli.rs` around lines 390 - 409, Update relocate_binaries() to
preserve the complete MySQL Windows ZIP installation tree, including lib, share,
and related root resources, when selecting the extracted archive layout. Move or
copy that tree into the versioned destination and ensure the resulting MySQL
binary path points to its bin directory within the relocated tree, while leaving
other archive types’ behavior unchanged.
🤖 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.

Inline comments:
In `@src-tauri/src/storage.rs`:
- Around line 151-162: Serialize the machine-ID cache-miss initialization around
detect_machine_id, cache insertion, and keyring persistence using a shared lock.
In the relevant storage initialization function, recheck MACHINE_ID_CACHE after
acquiring the lock, and persist only the ID successfully established by the
winning cache set; avoid writing IDs from losing concurrent callers.

In `@src/components/editor/QueryEditor.tsx`:
- Around line 622-623: Update the statement parsing flow in QueryEditor to pass
the original untrimmed editor text to splitStatements, preserving leading blank
lines for accurate lineNumber values. Keep trimming limited to any separate
execution or display use, and continue mapping the parsed statements into
allStatements unchanged.

In `@src/components/explorer/DatabaseExplorer.tsx`:
- Around line 1649-1667: Add a nearby Vitest regression test for the DDL lookup
flow in DatabaseExplorer, using the nested trigger identifier
trig-public.orders-audit_trigger and asserting it calls getDDL with type
"trigger" and name "audit_trigger" only. Ensure the test would fail if the table
name is included in the trigger lookup.

In `@src/components/layout/MainContent.tsx`:
- Around line 552-556: Update the session restoration flow in MainContent so
sessionRestoredRef.current remains false until the load_sessions await
completes, assigning true only in the completion/finally path after restoration
has finished. Preserve the save guard in the effect, and add an executable
regression test covering delayed restoration to ensure the initial empty
queryTabs list is not saved while loading.
- Around line 2087-2090: Update the cancellation flow around isExecutingRef and
executionGenRef so a cancelled run remains prevented from overlapping a newly
started run until its promise/loop fully settles; avoid resetting shared
cancelFlagRef in a way that lets the abandoned run continue, using a per-run
cancellation token or retaining the execution gate until completion. Preserve
generation checks for stale cleanup, and add a regression test covering
cancel-then-run-again, including run-all behavior.

In `@src/components/settings/SettingsDialog.tsx`:
- Around line 1531-1535: Update the cache-removal handler around
cli.removeCached to catch rejected deletions and surface the error through the
SettingsDialog UI or existing toast mechanism. Preserve the finally cleanup that
calls setRemovingKey(null), and ensure failures no longer propagate as unhandled
event-handler rejections.

In `@src/utils/applyQueryLimit.test.ts`:
- Around line 87-106: Update applyQueryLimit’s DO-block detection to recognize
an optional LANGUAGE clause between DO and the dollar-quoted or string body,
preventing LIMIT from being appended to forms such as DO LANGUAGE plpgsql. Add a
regression test covering this syntax and preserve unchanged behavior for
existing DO blocks.

In `@src/utils/applyQueryLimit.ts`:
- Around line 21-24: Centralize the DO-statement predicate used by
applyQueryLimit so it recognizes both dollar/quote forms and DO LANGUAGE plpgsql
statements, then reuse it in the run-all classification logic at
src/components/layout/MainContent.tsx lines 1003-1011, 1363-1372, and 1684-1693
using the cleaned statement text rather than raw text. Update
src/utils/applyQueryLimit.ts lines 21-24 to consume the shared predicate, and
add a regression case for DO LANGUAGE plpgsql in
src/utils/applyQueryLimit.test.ts lines 87-106.

---

Outside diff comments:
In `@src-tauri/src/cli.rs`:
- Around line 390-409: Update relocate_binaries() to preserve the complete MySQL
Windows ZIP installation tree, including lib, share, and related root resources,
when selecting the extracted archive layout. Move or copy that tree into the
versioned destination and ensure the resulting MySQL binary path points to its
bin directory within the relocated tree, while leaving other archive types’
behavior unchanged.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8c3b5b0-9861-4397-88d1-e2a736c5aa39

📥 Commits

Reviewing files that changed from the base of the PR and between 651a0f3 and 39b4835.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • src-tauri/src/cli.rs
  • src-tauri/src/lib.rs
  • src-tauri/src/storage.rs
  • src/components/editor/QueryEditor.tsx
  • src/components/explorer/DatabaseExplorer.tsx
  • src/components/layout/MainContent.tsx
  • src/components/settings/SettingsDialog.tsx
  • src/lib/ipc.ts
  • src/store/cliStore.ts
  • src/store/savedQueryStore.ts
  • src/utils/applyQueryLimit.test.ts
  • src/utils/applyQueryLimit.ts

Comment thread src-tauri/src/storage.rs
Comment thread src/components/editor/QueryEditor.tsx Outdated
Comment thread src/components/explorer/DatabaseExplorer.tsx Outdated
Comment thread src/components/layout/MainContent.tsx
Comment thread src/components/layout/MainContent.tsx Outdated
Comment thread src/components/settings/SettingsDialog.tsx
Comment thread src/utils/applyQueryLimit.test.ts
Comment thread src/utils/applyQueryLimit.ts Outdated
…nd Windows CLI/session bugs

- #39: Settings -> CLI Tools management UI (status, cached versions with
  disk usage, remove-cached, pre-download picker) backed by new
  cli_remove_cached command
- #212: Cancel Query left the app unable to run further queries; the
  abandoned run's finally block could still clobber isExecuting/generation
  state after cancellation
- applyQueryLimit / query executor no longer appends a LIMIT clause to
  PL/pgSQL DO $$ ... $$ blocks containing RETURNING
- Double-clicking a table-nested trigger no longer mis-resolves its DDL
  lookup path
- Saved query tabs are no longer wiped from sessions.json by a save/restore
  race on launch
- MySQL CLI auto-download now works on Windows (missing URL + binary
  relocation for .exe-suffixed archives, shared with mongosh)
- CLI subprocess calls no longer flash a console window on Windows
- Saved queries no longer silently disappear on Windows due to unstable
  machine-ID detection; machine ID is now cached in the OS keyring and
  fingerprint/decrypt failures are now logged instead of swallowed
@kix007
kix007 force-pushed the feat/cli-tools-settings-ui-and-windows-fixes branch from 39b4835 to a9438ec Compare July 29, 2026 07:21

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

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

Inline comments:
In `@src/components/explorer/DatabaseExplorer.tsx`:
- Around line 1649-1664: Update the trigger DDL resolution flow around getDDL so
it passes the trigger’s schema and parent table, rather than relying on
node.name/tgname alone. Extend the lookup contract and pg_trigger query to
constrain by schema, parent relation, and trigger name, preserving the intended
trigger definition when names duplicate across tables.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4691dd6c-9a37-4809-bec4-945337f612bc

📥 Commits

Reviewing files that changed from the base of the PR and between 39b4835 and a9438ec.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • src-tauri/src/cli.rs
  • src-tauri/src/lib.rs
  • src-tauri/src/storage.rs
  • src/components/editor/QueryEditor.tsx
  • src/components/explorer/DatabaseExplorer.tsx
  • src/components/layout/MainContent.tsx
  • src/components/settings/SettingsDialog.tsx
  • src/lib/ipc.ts
  • src/store/cliStore.ts
  • src/store/savedQueryStore.ts
  • src/utils/applyQueryLimit.test.ts
  • src/utils/applyQueryLimit.ts
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/utils/applyQueryLimit.ts
  • src/store/savedQueryStore.ts
  • src/utils/applyQueryLimit.test.ts
  • src/store/cliStore.ts
  • src-tauri/src/lib.rs
  • src/components/editor/QueryEditor.tsx
  • src-tauri/src/storage.rs
  • src/lib/ipc.ts
  • src-tauri/src/cli.rs
  • src/components/settings/SettingsDialog.tsx
  • CHANGELOG.md
  • src/components/layout/MainContent.tsx

Comment thread src/components/explorer/DatabaseExplorer.tsx Outdated
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

⚠️ Branch updated during autofix.

The branch was updated while autofix was in progress. Please try again.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 2 file(s) based on 1 unresolved review comment.

Files modified:

  • src/components/explorer/DatabaseExplorer.tsx
  • src/contexts/ConnectionContext.tsx

Commit: c80ed17dc7efd7a0e74b6b10e63ac95fd2f7c1f4

The changes have been pushed to the feat/cli-tools-settings-ui-and-windows-fixes branch.

Time taken: 5m 4s

Fixed 2 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 3 file(s) based on 4 unresolved review comments.

Files modified:

  • src-tauri/src/storage.rs
  • src/components/layout/MainContent.tsx
  • src/components/settings/SettingsDialog.tsx

Commit: fad365e35553a01c087a070c6dc148072eb7ccd0

The changes have been pushed to the feat/cli-tools-settings-ui-and-windows-fixes branch.

Time taken: 7m 58s

Fixed 3 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
- Document the two trigger node.id formats (schema-level vs table-nested)
  and the limitation with  in quoted identifiers
- Clarify that cancelFlagRef is not legacy — it is still the primary
  cancel signal for the CLI psql path (run-all, \watch, post-exec bail,
  catch block)
@kix007
kix007 merged commit eb4dc05 into main Jul 29, 2026
9 of 10 checks passed

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

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

Inline comments:
In `@src/contexts/ConnectionContext.tsx`:
- Around line 1333-1347: The trigger lookup logic must preserve schema context
when only schema is provided and must not silently choose among duplicate
matches. Update the query branching around currentDb.select to add a
schema-filtered lookup for schema without table, and validate the returned rows
so multiple matches are reported as ambiguous rather than always using
result[0]; retain the existing schema-and-table constraint and name-only
fallback for their respective cases.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 322bacad-080a-4b11-808d-fd7262bca458

📥 Commits

Reviewing files that changed from the base of the PR and between a9438ec and 9b05510.

📒 Files selected for processing (5)
  • src-tauri/src/storage.rs
  • src/components/explorer/DatabaseExplorer.tsx
  • src/components/layout/MainContent.tsx
  • src/components/settings/SettingsDialog.tsx
  • src/contexts/ConnectionContext.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • src-tauri/src/storage.rs
  • src/components/explorer/DatabaseExplorer.tsx
  • src/components/layout/MainContent.tsx
  • src/components/settings/SettingsDialog.tsx

Comment on lines +1333 to +1347
let result;
// If schema and table are provided, constrain lookup to avoid ambiguity
// when the same trigger name exists on different tables
if (schema && table) {
result = await currentDb.select(`
SELECT pg_get_triggerdef(t.oid)
FROM pg_trigger t
JOIN pg_class c ON t.tgrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE t.tgname = $1 AND n.nspname = $2 AND c.relname = $3
`, [name, schema, table]);
} else {
// Fallback: look up by trigger name alone (may be ambiguous)
result = await currentDb.select("SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE tgname = $1", [name]);
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve schema context for schema-only trigger lookups.

src/components/explorer/DatabaseExplorer.tsx passes triggerSchema for trig-<schema>.<triggerName> nodes while table is undefined. This enters the fallback query, which searches every schema by trigger name and returns the first row. Duplicate trigger names can therefore open the wrong DDL. Add a schema-filtered branch, and report ambiguity when multiple matches remain instead of blindly using result[0].

🤖 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/contexts/ConnectionContext.tsx` around lines 1333 - 1347, The trigger
lookup logic must preserve schema context when only schema is provided and must
not silently choose among duplicate matches. Update the query branching around
currentDb.select to add a schema-filtered lookup for schema without table, and
validate the returned rows so multiple matches are reported as ambiguous rather
than always using result[0]; retain the existing schema-and-table constraint and
name-only fallback for their respective cases.

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