77 Commits

Author SHA1 Message Date
c03e887b71 fix(chat): decode pg_class.reltuples as f32 in sample_data probe
Some checks failed
CI / lint-and-build (push) Failing after 1m15s
pg_class.reltuples is `real` (FLOAT4). Reading it as f64 via query_scalar made
the sample_data tool fail with a sqlx type-mismatch ("f64 (FLOAT8) is not
compatible with FLOAT4") before any rows were fetched. Decode as f32 and widen.
2026-05-23 18:17:55 +03:00
ff212e4d0b docs: update CLAUDE.md to reflect recent AI refactoring, UI redesign, and state changes
- state.rs: remove stale schema_cache/columns_cache refs; add
  overview_cache, tables_by_db_cache, ai_settings, MCP channels,
  ClickHouse flavor
- commands/: list all current modules (ai, chat, chat_tools, memory,
  settings) instead of an outdated subset
- frontend: document tool-calling chat architecture (tool-registry.ts,
  ChatPanel) replacing the former AiBar/explain/fix/ChartPreview
- ui: mention "Graphite & Honey" theme, IBM Plex Mono, custom
  CodeMirror theme
- conventions: add rule for adding AI chat tools
2026-05-23 16:11:07 +03:00
da0001e77e feat(ui): "Graphite & Honey" redesign — warm dark, monospace-first
- new design system in globals.css: warm graphite surfaces, ivory text, honey
  accent; semantic status/data-type/syntax tokens replacing hardcoded colors
- IBM Plex Mono as the universal UI font (sans + mono), tabular numerals
- custom CodeMirror SQL theme (src/lib/editor-theme.ts) matching the palette
- data grid: zebra striping + honey row hover, stronger sticky header
- route status dots, JSON syntax, EXPLAIN cost, schema-tree icons and the
  read/write toggle through the new tokens
- TUSK wordmark in the toolbar
2026-05-23 15:02:19 +03:00
c73339bb4c chore: add app:dev / app:bundle npm aliases and document them
Thin aliases for `tauri dev` / `tauri build`; raw `npm run tauri <cmd>` still works.
2026-05-23 15:02:05 +03:00
8c13b4ec97 chore(icons): refresh app icon set + add android/ios variants and source
Regenerate desktop icons (png/ico/icns), add 64x64 and mobile (android mipmap,
ios AppIcon) variants, and keep the editable icon-source.svg/png.
2026-05-23 15:02:01 +03:00
0cba457fb7 refactor(ai): consolidate AI around chat tool-calling; add OpenRouter
- rework chat backend (chat.rs, chat_tools.rs, ai.rs, models, state) around tool calls
- add OpenRouter provider alongside Ollama/Fireworks in settings
- drop inline AiBar, ResultsPanel explain/fix UI and ChartPreview in favour of the chat panel
- add frontend chat tool-registry
2026-05-23 15:01:52 +03:00
a485cf7ee3 fix(greenplum): drop ctid from table-data SELECT and friendly-fail PK-less edits
Browsing any GP table threw "column ctid does not exist" because the
table-viewer's pagination query unconditionally appended `ctid::text`
to the SELECT. AO and AOCO tables (the dominant storage in GP)
genuinely have no ctid, and even on heap tables the value isn't
reliable across segments — so editing by ctid would be wrong even when
the column exists.

- get_table_data: skip the ctid column entirely on Greenplum (`SELECT *`
  instead of `SELECT *, ctid::text`); ctids field stays as an empty Vec.
- update_row / delete_rows: when the table has no PK on a GP connection,
  return an actionable error instead of falling through to the ctid
  path. Tells the user to add a PK or use raw SQL.

Vanilla Postgres behavior is unchanged.
2026-05-07 00:27:24 +03:00
95c9470411 feat: scope Saved Queries panel to active connection + clean up on delete
Two changes that close the "everything lives in one global pool" gap.

UI: Saved Queries sidebar now defaults to "This connection" and lists
only entries with `connection_id == activeConnectionId` plus unattached
entries (legacy global saves before F2). A small toggle ("All") above
the search box brings the previous behavior back when copying queries
between databases. Each row in "All" mode shows a tag with the source
connection's name; legacy global entries show "unattached".

Backend: delete_connection now best-effort cleans persisted state for
that connection — removes `memory/<id>.md` (delete_memory_core in
memory.rs) and drops every entry in saved_queries.json with the
matching `connection_id` (delete_by_connection_core in
saved_queries.rs). Entries with `connection_id == None` are deliberately
preserved. Cleanup errors are logged but don't block the deletion since
connections.json is the source of truth.

Memory was already per-connection (F1); query history already filters
by connection. This commit makes saved queries behave the same and
stops orphan files from accumulating.
2026-05-07 00:21:27 +03:00
93e526af72 fix: cap overview table list and surface friendly prompt-overflow message
Two changes that together kill the "prompt is too long: 1991577 tokens"
crash on large Greenplum catalogs.

1. Overview table cap (build_overview_postgres):
   The agent re-injects the full overview into the system prompt every
   turn. On a multi-thousand-table catalog (typical for GP data lakes)
   this was megabytes per call and quickly overran even Kimi-K2's 256K
   window. Now we list at most 400 tables and replace the rest with
   per-schema counts plus a hint to call list_tables for specifics.

2. Friendly Fireworks-400 rewrite:
   Detect "prompt is too long" / "maximum context length" in the
   Fireworks 400 body and turn it into an actionable message asking
   the user to /compact, instead of leaking raw API JSON to the chat.
2026-05-07 00:12:37 +03:00
5c5d256cee feat(greenplum): expose distribution key + storage type to chat agent
When connected to a Greenplum cluster, schema introspection now surfaces
the two attributes that dominate query performance there: the data
distribution policy (DISTRIBUTED BY / RANDOMLY) and the storage kind
(heap / AO row / AO column). Without these, the agent writes
PG-optimal SQL that triggers Redistribute Motion in GP and runs orders
of magnitude slower than necessary.

- track Greenplum major version (6 vs 7) at connect time, since GP6
  uses pg_class.relstorage and GP7 dropped it in favor of pg_am
- new fetch_gp_table_extras helper queries gp_distribution_policy and
  the version-appropriate storage catalog, returns a per-table map
- format_table_block prints `  -- GP: DISTRIBUTED BY (...) | STORAGE: ...`
  under the TABLE header when extras are available
- build_overview_postgres appends a GREENPLUM NOTES block with the
  distribution-aware-join rules and a skew-detection one-liner; the
  agent sees this in every system prompt on a GP connection
- build_schema_context (legacy generate_sql / explain_sql / fix_sql_error
  path) and the chat get_columns tool both feed extras into format_table_block

P0 of the GP support arc — partitioning, EXPLAIN motion-aware parsing,
external tables, resource queues, and a skew-check tool are deliberately
deferred to follow-up commits.
2026-05-06 23:34:44 +03:00
223a09c636 fix: make SQL editor scrollable when query overflows the panel
Some checks failed
CI / lint-and-build (push) Failing after 3m14s
@uiw/react-codemirror's outer wrapper inherited h-full but the inner
.cm-editor / .cm-scroller had no height constraint, so long queries
spilled outside the visible area with no way to scroll. Pass
`height="100%"` to the CodeMirror component and pin .cm-editor to the
wrapper height via a Tailwind arbitrary selector so the scroller
renders correctly inside the resizable panel.
2026-05-06 23:20:00 +03:00
9a424dcd34 fix: use provider-aware context budget so Fireworks doesn't show 150% on small threads
The chat usage badge was hardcoded to ~8K-token Ollama defaults
(`CONTEXT_BUDGET_CHARS = 24_000`), which made every Fireworks session
look 150%+ full after a few hops even though models like Kimi-K2 carry
256K context windows. Now the budget is selected per-provider:

- Ollama → 24K chars (~8K tok), unchanged
- Fireworks → 384K chars (~128K tok), a safe floor for the smallest
  Fireworks chat models (qwen2.5-coder 32K) while not stuffing the bar
  for the larger ones

Auto-compact thresholds and the % badge both read this back from the
backend, so they now scale correctly when the user switches providers.
2026-05-06 23:11:56 +03:00
96a54edcd0 feat: add Fireworks AI provider for chat agent
Routes chat-completions through a managed OpenAI-compatible inference
endpoint as an alternative to local Ollama, useful when the agent needs
fast multi-hop reasoning that local hardware can't sustain.

- backend: rename `call_ollama_chat_messages` → `call_chat_messages`,
  dispatch by provider; add `call_fireworks` branch (Bearer auth,
  `response_format: json_object` mapped from internal `format="json"`)
  and `list_fireworks_models` Tauri command
- settings: extend `AiProvider` enum + `AiSettings.fireworks_api_key`
  (serde-default for legacy config compat); Fireworks base URL hardcoded
- UI: provider selector in both popover and AppSettingsSheet (only
  ollama+fireworks shown; legacy openai/anthropic kept for serde-compat
  but normalized to ollama in UI); password input + dynamic model list
  for Fireworks; switching provider clears stale model selection
- 4 unit tests: serde round-trip, legacy settings deserialization,
  Fireworks chat-completions parsing, models-list parsing
2026-05-06 23:04:10 +03:00
532ebf3b44 feat: chart support — make_chart tool with recharts rendering
Adds inline data visualisation to the chat agent. After a successful
run_query, the agent can call make_chart(chart_type, x, y, [group,
title, orientation]) and the result is rendered as a bar / line / area
/ pie chart inline in the chat thread, sourced from the previous query
result.

Backend (commands/chat.rs, models/chat.rs)
- New ChartConfig{chart_type, x, y, group?, title?, orientation?} model.
- New AgentAction::MakeChart{config} variant. Parser accepts both
  `chart_type` and the alternative `type` field name (qwen3 sometimes
  emits the latter). Validates chart_type is one of bar/line/area/pie.
- last_successful_query_result helper finds the most recent successful
  run_query in the working thread.
- MakeChart dispatcher: validates that x/y/group columns exist in the
  attached query result, emits a tool_result with the same QueryResult
  in `result` and the chart_config JSON in `text`. Mismatches surface
  as a clear error ("y column `name` is not in the last result.
  Available: company_name, legal_name, …").
- build_history compression unchanged: make_chart's tool_result text
  field (the small chart_config JSON) is included in LLM history; the
  large QueryResult.rows are NOT, since the per-tool branch only emits
  text for non-run_query tools.
- System prompt: documents make_chart with concrete usage hints
  (top-N → bar, time series → line/area, proportions → pie; skip for
  ≤2 or >500 rows). 7 new parser/dispatcher tests.

Frontend (src/components/chat/)
- recharts ^3.8 added.
- New ChartPreview component renders bar (vertical+horizontal), line,
  area, pie. Supports grouped series via the `group` config field by
  pivoting rows into a wide format. Y values coerced to numbers
  (parses strings, nulls → 0). Caps to 500 points to keep things
  responsive on huge results.
- ChatMessageView routes tool=="make_chart" tool_result through a new
  ChartToolResult that parses the config JSON from the message text
  and feeds the embedded QueryResult into ChartPreview.
- New labels/icons (BarChart3) and preview-extraction for make_chart
  in tool-call collapsed headers (`bar: carrier_name → trip_count`).

Verification: cargo test --lib 77 pass (+7), tsc clean, vitest 20
pass.
2026-05-06 21:10:52 +03:00
eb25409d9d fix: forced-final synthesis on hop limit + sharper column rule
The previous symptom: agent succeeded on its 8th run_query (got 30
rows) but the loop ended without a final because that was the last
allowed hop. Result: "Stopped after 8 tool calls" and the data was
wasted. Also: agent kept assuming `legal_entities.name` existed even
after get_columns showed it didn't.

Backend (commands/chat.rs)
- MAX_HOPS 8 -> 10. With list_databases / list_tables / get_columns /
  switch_database / run_query / remember / save_query / find_queries
  available, complex investigations need a bit more headroom.
- New force_final_synthesis: when the loop falls through MAX_HOPS,
  one extra LLM call is made WITHOUT the JSON action protocol,
  asking the model to write a plain-text answer based on whatever
  data was already collected. This rescues cases where the agent
  succeeded on the last hop but had no budget for a final. Output
  goes through clean_summary so any stray JSON or fences are stripped.
- Stronger RULES in system prompt:
  * Explicit ban on guessing column names: "After get_columns, your
    next run_query must use ONLY column names that appear verbatim
    in that output."
  * Concrete example of how to read PG's "column le.name does not
    exist" — the alias `le` tells you which table is missing it.
  * Mention the new hop budget (10) so the model spends it
    deliberately.

Verification: cargo test --lib 70 pass, tsc clean.
2026-05-06 20:38:55 +03:00
5e72a80376 fix: surface PG error HINT/DETAIL and stop the agent after repeated SQL failures
The previous loop burned all 8 hops re-running the same broken query
("operator does not exist: character varying = uuid") because (a) the
agent never saw PostgreSQL's HINT — only the bare error message — and
(b) the prompt's "retry once" rule was advisory, not enforced.

Backend (commands/chat.rs)
- New format_db_error helper. When the error is sqlx::Error::Database
  with a PostgreSQL backend, downcast to PgDatabaseError and append
  DETAIL and HINT lines. Common PG hints are exactly the spelled-out
  fix the agent needs ("You might need to add explicit type casts").
- New last_run_query_error helper to fish the most recent failing SQL
  text out of working history for the give-up message.
- Hard server-side guard: track consecutive_query_errors. On
  consecutive run_query failures >= 2, force-emit a `final` message
  that quotes the last error and suggests next steps (cast hints,
  open the table in sidebar, switch to Advanced mode). The model
  cannot loop past this regardless of how many hops remain.
- Counter resets to 0 when the model takes any non-RunQuery action
  (get_columns, list_tables, etc.) — investigation buys a fresh
  error budget.
- Stronger prompt RULES section: explicitly walks through three of
  the most common PG error classes ("operator does not exist",
  "column does not exist", "relation does not exist") and the
  matching fixes. Tells the model the harness force-stops after 2
  consecutive failures.

Tests (4 new): format_db_error fallback, last_run_query_error finds
most recent / handles empty / handles no-errors thread.

Verification: cargo test --lib 70 pass (+4), tsc clean, vitest 20
pass.
2026-05-06 20:11:11 +03:00
83f204816a fix: handle PG INTERVAL type, robust compact LLM output + feedback
INTERVAL handling
- pg_value_to_json now decodes PG INTERVAL via PgInterval and renders
  it psql-style: `1 year 2 mons 3 days 04:05:06`. Previously
  AVG(timestamp - timestamp) and similar interval-returning queries
  showed `<unsupported type: INTERVAL>` in chat results.
- 7 unit tests covering zero, days-only, mixed, negative, microsecond
  fraction, and the singular/plural unit rules.

Compact reliability
- Sharper system prompt: explicitly instructs plain text starting with
  `-`, no JSON, no fences, no field names. qwen3-coder is heavily
  trained on the agent JSON protocol and was sometimes returning
  `{"action":"final","text":"..."}` even for the compact prompt.
- New clean_summary helper strips ``` fences (with or without lang
  identifier) and extracts the underlying string from a JSON envelope
  if the model still wraps the answer (looks for text/summary/content/
  answer/output keys). 6 unit tests.
- Frontend useChat.compact: success/no-op/error toasts via sonner so
  the user sees what happened. "Nothing to compact" appears when there
  is no older history beyond the last user turn (previously silent).

Verification: cargo test --lib 66 pass (+13), tsc clean, vitest 20
pass.
2026-05-06 20:01:50 +03:00
27fed0dbf8 feat: chat context-usage display, /compact slash command, auto-compact
Adds visibility into how much of the model context window the chat agent
is using and a way to free space when it fills up.

Backend
- New ContextUsage{used_chars, budget_chars} returned from chat_send
  alongside messages (return type ChatTurnResult). Computed by running
  build_history once at end of turn and counting char bytes — same data
  path as the actual LLM call, so the count is exact for the chosen
  budget unit.
- CONTEXT_BUDGET_CHARS = 24,000 (~6-8K tokens). Tuned for Ollama
  defaults; can be exposed via AiSettings later.
- New chat_compact Tauri command. Splits the thread at the last user
  turn, LLM-summarises everything before it (3-6 bullet points,
  language-aware, < 800 chars), and returns a thread of
  [Assistant("📋 Compacted N messages: …"), <last_user_turn?>]. The
  recent user turn is preserved untouched so the agent can keep
  answering it.
- render_thread_for_summary skips QueryResult.rows entirely so a single
  large run_query can't blow the summariser's context.
- 3 new unit tests (last_user_turn_index, render skipping rows, empty
  thread no-op).

Frontend
- ChatPanel header gets a usage badge: progress bar + `Xk / Yk tok ·
  P%`, color-coded green (<30%) / muted (<60%) / amber (<85%) / red
  (≥85%). Tooltip explains and nudges /compact when ≥60%.
- Compact button next to Clear in the header.
- Slash commands in ChatComposer: /compact, /clear.
- Empty-state shows the slash-command hint.
- Auto-compact: if the previous turn pushed usage past 85% AND the
  thread has more than one message, the next user turn first runs
  chat_compact transparently before chat_send. The compaction surfaces
  as a visible Assistant("📋 Compacted …") message so the user can see
  what the agent kept.
- app-store gets chatUsage map per tab + replaceChatThread + setChatUsage
  actions; closeTab and clearChatThread clean up usage too.

Verification: cargo check clean, cargo test --lib 53 pass (+3),
tsc --noEmit clean, vitest run 20 pass.
2026-05-06 19:44:11 +03:00
b41c84dab8 chore: switch dev server to port 5174
Vite default 5173 frequently conflicts with parallel local projects.
Move Tusk's vite dev server (and tauri devUrl) to 5174 so it can
coexist with another project running on the default port.
2026-05-06 19:30:54 +03:00
4f7afc17f4 feat: rescope to AI-first DB harness with multi-DB chat agent
Removes enterprise/DBA features and replaces the marginal AI bar with a
central chat agent that has progressive-discovery tools, cross-session
memory, saved-query reuse, and inline result actions. Adds ClickHouse
support alongside PostgreSQL/Greenplum.

Cleanup
- Drop ~10k LOC of advanced features: Docker, Snapshots, Validation,
  Index Advisor, Role/User Management, Data Generator, ERD, Lookup.
- Trim deps: drop @xyflow/react, dagre, @types/dagre; cut tokio features
  to rt-multi-thread/sync/time/net/macros.
- Remove unused TuskError variants and dead helpers (topological_sort,
  invalidate_schema_cache).

Multi-DB (PostgreSQL + ClickHouse)
- New src-tauri/src/db/ module: ChClient (HTTP-based, reuses reqwest),
  sql_guard (cross-flavor read-only whitelist with 8 tests).
- ConnectionConfig gains db_flavor and secure fields with serde defaults
  for backwards-compatible connections.json.
- All connection/query/schema/data commands dispatch by flavor; CH
  covers connect, execute_query, list_databases/schemas/tables/views/
  columns/completion_schema, paginated table fetch.
- Frontend: dbCapabilities matrix, ConnectionDialog engine selector
  with port auto-swap and HTTPS toggle, SqlEditor switches to
  StandardSQL dialect for CH, TableDataView surfaces CH connections as
  read-only.

AI-first chat agent
- New src/components/chat/ panel with composer, message rendering,
  collapsible tool-call/result blocks, top-level ErrorBoundary.
- Backend agent loop in commands/chat.rs with strict-JSON tool
  protocol. Nine tools: list_databases, list_tables, get_columns,
  switch_database, run_query, remember, save_query, find_queries, final.
  Forgiving parser accepts both flat and nested-input shapes.
- Compressed history: only the last 4 run_query results carry sample
  rows (≤10, cells truncated to 200 chars) into LLM context; older
  results marked omitted.
- System prompt uses lite OVERVIEW (DB list + active-DB tables only)
  instead of full DDL — schema details are loaded on demand via
  get_columns. CH OVERVIEW shows cross-DB tables since CH allows
  db.table queries.

Cross-session memory (F1)
- Per-connection markdown file at app_data_dir/memory/<connection_id>.md,
  16KB cap with oldest-block eviction. Agent appends via remember()
  tool; the file is injected into LEARNED NOTES section of every system
  prompt.
- New Memory sidebar tab with editable textarea, badge for note count,
  empty-state with template. Edits picked up on the next agent turn.

Saved-query reuse (F2)
- Tools save_query and find_queries scoped to current connection.
  save_query attaches a UUID + timestamp; find_queries returns top 10
  matches with SQL preview ≤500 chars.
- Storage shared with the sidebar Saved panel.

Inline result actions (F3)
- run_query result block in chat gets Open-full (90vw × 80vh modal with
  full ResultsTable, no row cap) and Export (reuses ExportDialog for
  CSV/JSON via existing exportCsv/exportJson commands).

Verification
- cargo check clean, zero warnings.
- cargo test --lib: 50 pass (20 chat parser + 4 memory + 8 sql_guard +
  6 clean_sql + 12 escape_ident).
- npx tsc --noEmit clean.
- npx vitest run: 20 pass.
2026-05-06 19:30:44 +03:00
652937f7f5 feat: add visual filter builder with SQL fallback for table data
All checks were successful
CI / lint-and-build (push) Successful in 9m8s
Replace raw WHERE input with a dual-mode filter:
- Visual mode: column/operator/value dropdowns with AND/OR support
- SQL mode: raw WHERE clause input (auto-strips "where" prefix)
2026-04-08 15:30:29 +03:00
931e2b9408 ci: skip AppImage bundle, build only deb and rpm
All checks were successful
CI / lint-and-build (push) Successful in 9m8s
2026-04-08 12:24:23 +03:00
02ea9db25d ci: set APPIMAGE_EXTRACT_AND_RUN for linuxdeploy in container
Some checks failed
CI / lint-and-build (push) Failing after 9m42s
2026-04-08 12:02:46 +03:00
318210bdd8 ci: add xdg-utils for AppImage bundling
Some checks failed
CI / lint-and-build (push) Failing after 9m42s
2026-04-08 11:47:51 +03:00
11e35fcb5c chore: bump MSRV to 1.80.0 for LazyLock support
Some checks failed
CI / lint-and-build (push) Failing after 9m7s
2026-04-08 11:35:56 +03:00
50214fec0f perf: optimize backend — HTTP client, DB queries, error handling, and config cleanup
Some checks failed
CI / lint-and-build (push) Failing after 2m55s
2026-04-08 10:50:40 +03:00
28aa4ef8cc style: apply rustfmt to docker and snapshot commands
Some checks failed
CI / lint-and-build (push) Failing after 2m51s
2026-04-08 10:38:07 +03:00
ba9b58ff3a ci: replace actions/checkout with manual git clone for act runner
Some checks failed
CI / lint-and-build (push) Failing after 1m12s
The act-based Gitea runner executes JS actions inside the specified
container, but ubuntu:22.04 has no Node.js. Use git clone directly
to avoid the dependency.
2026-04-08 10:23:58 +03:00
33b07a31da ci: add workflow_dispatch trigger to CI workflow
Some checks failed
CI / lint-and-build (push) Failing after 2s
2026-04-08 10:09:30 +03:00
2d2dcdc4a8 fix: resolve all 25 ESLint react-hooks and react-refresh violations
Replace useEffect-based state resets in dialogs with React's render-time
state adjustment pattern. Wrap ref assignments in hooks with useEffect.
Suppress known third-party library warnings (shadcn CVA exports,
TanStack Table). Remove warn downgrades from eslint config.
2026-04-08 07:41:34 +03:00
9237c7dd8e perf: optimize HTTP client, DB queries, and clean up dead code
- Make reqwest::Client a LazyLock singleton instead of per-call allocation
- Parallelize 3 independent DB queries in get_index_advisor_report with tokio::join!
- Eliminate per-iteration Vec allocation in snapshot FK dependency loop
- Hoist try_local_pg_dump() call in SampleData clone mode to avoid double execution
- Evict stale schema cache entries on write to prevent unbounded memory growth
- Remove unused ValidationReport struct and config_path field
- Rename IndexRecommendationType variants to remove redundant suffix
2026-04-06 13:13:03 +03:00
6b925d6260 style: apply rustfmt, fix clippy warnings, and minor code cleanup
Reformat Rust code with rustfmt, suppress clippy::too_many_arguments
for Tauri IPC commands, derive Default for AppSettings, fix unused
variable pattern in TableDataView, and add unit tests for utils.
2026-04-06 13:12:52 +03:00
1e002d801a chore: update build config, linting, and add test infrastructure
Replace install -D with mkdir -p + install for macOS portability,
add vitest with jsdom and testing-library, configure eslint for
react-hooks v7 warnings, and add tokio test deps for Rust.
2026-04-06 13:12:43 +03:00
f8dd94a6c7 chore: remove node_modules prerequisite from make dev 2026-04-06 10:27:24 +03:00
4e5714b291 feat: redesign UI with Twilight design system
Outfit + JetBrains Mono typography, soft dark palette with blue
undertones, electric teal primary, purple-branded AI features,
noise texture, glow effects, glassmorphism, and refined grid/tree.
2026-04-06 10:27:20 +03:00
64e27f79a4 ci: configure Gitea Actions for Docker-based runner
Some checks failed
CI / lint-and-build (push) Failing after 2s
Use explicit ubuntu:22.04 container instead of marketplace actions
that may not work on self-hosted Gitea runners. Install Node.js and
Rust toolchain directly via curl/rustup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:38:00 +03:00
ab898262dd ci: add Gitea Actions workflows for Linux-only CI and release
Some checks failed
CI / lint-and-test (push) Failing after 1m20s
CI / build (push) Has been skipped
Adapt GitHub Actions workflows for Gitea with Docker runner:
- Linux-only builds (no macOS/Windows matrix)
- Manual `npm run tauri build` instead of tauri-action
- Release creation via Gitea API with asset upload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:30:40 +03:00
e984bf233e ci: add cross-platform builds for Linux, macOS (Intel + ARM), and Windows
Some checks failed
CI / lint-and-test (push) Failing after 27s
CI / build (, tusk-linux-x64, ubuntu-22.04, ) (push) Has been skipped
CI / build (, tusk-windows-x64, windows-latest, ) (push) Has been skipped
CI / build (--target aarch64-apple-darwin, tusk-macos-arm64, macos-latest, aarch64-apple-darwin) (push) Has been skipped
CI / build (--target x86_64-apple-darwin, tusk-macos-x64, macos-13, x86_64-apple-darwin) (push) Has been skipped
- Add macOS Intel build (macos-13 / x86_64-apple-darwin) to CI matrix
- Add artifact upload step to CI build job
- Add release workflow triggered by v* tags with draft GitHub Release
- Add AppImage to Linux bundle targets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:21:09 +03:00
34c80809f1 fix: prevent snapshot hang caused by u8 overflow in progress calculation
When creating/restoring snapshots with 4+ tables, the progress percentage
calculation overflowed u8 (e.g. 4*80=320 > 255), causing a panic that left
the IPC call unresolved. Also deduplicate fetch_foreign_keys_raw call.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:45:58 +03:00
a3b05b0328 feat: add AI data validation, test data generator, index advisor, and snapshots
Four new killer features leveraging AI (Ollama) and PostgreSQL internals:

- Data Validation: describe quality rules in natural language, AI generates
  SQL to find violations, run with pass/fail results and sample violations
- Test Data Generator: right-click table to generate realistic FK-aware test
  data with AI, preview before inserting in a transaction
- Index Advisor: analyze pg_stat tables + AI recommendations for CREATE/DROP
  INDEX with one-click apply
- Data Snapshots: export selected tables to JSON (FK-ordered), restore from
  file with optional truncate in a transaction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:27:41 +03:00
d507162377 fix: harden security, reduce duplication, and improve robustness
- Fix SQL injection in data.rs by wrapping get_table_data in READ ONLY transaction
- Fix SQL injection in docker.rs CREATE DATABASE via escape_ident
- Fix command injection in docker.rs by validating pg_version/container_name
  and escaping shell-interpolated values
- Fix UTF-8 panic on stderr truncation with char_indices
- Wrap delete_rows in a transaction for atomicity
- Replace .expect() with proper error propagation in lib.rs
- Cache AI settings in AppState to avoid repeated disk reads
- Cap JSONB column discovery at 50 to prevent unbounded queries
- Fix ERD colorMode to respect system theme via useTheme()
- Extract AppState::get_pool() replacing ~19 inline pool patterns
- Extract shared AiSettingsFields component (DRY popover + sheet)
- Make get_connections_path pub(crate) and reuse from docker.rs
- Deduplicate check_docker by delegating to check_docker_internal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 11:41:14 +03:00
baa794b66a feat: fallback to ctid for editing tables without primary key
When a table has no PRIMARY KEY, use PostgreSQL's ctid (physical row ID)
to identify rows for UPDATE/DELETE operations instead of blocking edits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 16:14:26 +03:00
e76a96deb8 feat: add unified Settings sheet, MCP indicator, and Docker host config
- Add AppSettingsSheet (gear icon in Toolbar) with MCP, Docker, and AI sections
- MCP Server: toggle on/off, port config, status badge, endpoint URL with copy
- Docker: local/remote daemon selector with remote URL input
- AI: moved Ollama settings into the unified sheet
- MCP status probes actual TCP port for reliable running detection
- Docker commands respect configurable docker host (-H flag) for remote daemons
- MCP server supports graceful shutdown via tokio watch channel
- Settings persisted to app_settings.json alongside existing config files
- StatusBar shows MCP indicator (green/gray dot) with tooltip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 09:04:12 +03:00
20b00e55b0 fix: improve Docker clone reliability and log display
- Use bash with pipefail instead of sh to detect pg_dump failures in pipes
- Switch full clone from binary format (pg_dump -Fc | pg_restore) to plain
  text (pg_dump | psql) for reliable transfer through docker exec
- Add --no-owner --no-acl flags to avoid errors from missing roles
- Extract shared run_pipe_cmd helper with proper error handling
- Remove shell commands from progress events to prevent credential leaks
- Fix process log layout overflow with break-all and block-level details

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:41:59 +03:00
1ce5f78de8 feat: add Clone Database to Docker functionality
Clone any database to a local Docker PostgreSQL container with schema
and/or data transfer via pg_dump. Supports three modes: schema only,
full clone, and sample data. Includes container lifecycle management
(start/stop/remove) in the Admin panel, progress tracking with
collapsible process log, and automatic connection creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:27:16 +03:00
f68057beef fix: remove duplicate app name from toolbar
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 16:38:57 +03:00
94df94db7c feat: add ER diagram and enhance TableStructure with FK details, triggers, comments
- Add interactive ER diagram with ReactFlow + dagre auto-layout, accessible
  via right-click context menu on schema nodes in the sidebar
- Enhance TableStructure: column comments, FK referenced table/columns,
  ON UPDATE/DELETE rules, new Triggers tab
- Backend: rewrite get_table_constraints using pg_constraint for proper
  composite FK support, add get_table_triggers and get_schema_erd commands

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 16:37:38 +03:00
b44254bb29 fix: preserve tab state when switching between tabs
Render all tabs simultaneously with display:none for inactive ones,
instead of conditionally rendering only the active tab. This prevents
React from unmounting/remounting components on tab switch, preserving
query results, editor cursor, AI explanations, and other local state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:45:45 +03:00
a71afe8d5e fix: enable horizontal scroll in entity lookup and increase timeout to 120s
Replace Radix ScrollArea with plain overflow-auto div to allow nested
horizontal scrolling in lookup result tables. Add overflow-auto to
table containers. Increase per-database search timeout from 30s to 120s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:26:33 +03:00
f8a53e1166 fix: add PostgreSQL array type support in pg_value_to_json
Handle _BOOL, _INT2, _INT4, _INT8, _FLOAT4, _FLOAT8, _TEXT, _VARCHAR,
_CHAR, _BPCHAR, _NAME, _UUID, _JSON, _JSONB array types so they render
as JSON arrays instead of "<unsupported type>".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:17:50 +03:00