feat(console): runtime-injectable worker UI with per-worker toggles - #570
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedToo many files! This PR contains 157 files, which is 57 over the limit of 100. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (158)
You can disable this status message by setting the ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
skill-check — worker0 verified, 47 skipped (no docs/).
Four for four. Nicely done. |
530ab00 to
223e95b
Compare
The nested console/web/pnpm-workspace.yaml (added on main for standalone esbuild allowBuilds) made pnpm treat web/ as its own workspace root, so --frozen-lockfile installs stopped finding the repo-root lockfile. The root workspace already declares allowBuilds for esbuild. Also fix the rust job's pre-build loop paths, which were double-prefixed with the worker dir and silently skipped the build.
Ships the database worker's #/ext/database page over the injectable-UI protocol (#570): a schema tree with lazy per-driver column/PK/FK/index introspection, a sortable paginated row grid with a row inspector, and a read-only SQL panel (shared Monaco CodeEditor, EXPLAIN, per-db history, client-side write-verb gate). Reads the live database via database::query and database::listDatabases. Registered through host.pages.register in the existing database/ui setup, alongside the function-trigger renderer. The SQL editor feeds the live table names plus SQL keywords to the CodeEditor completions prop for as-you-type suggestions.
…598) * feat(database): injectable console page (schema browser + SQL panel) Ships the database worker's #/ext/database page over the injectable-UI protocol (#570): a schema tree with lazy per-driver column/PK/FK/index introspection, a sortable paginated row grid with a row inspector, and a read-only SQL panel (shared Monaco CodeEditor, EXPLAIN, per-db history, client-side write-verb gate). Reads the live database via database::query and database::listDatabases. Registered through host.pages.register in the existing database/ui setup, alongside the function-trigger renderer. The SQL editor feeds the live table names plus SQL keywords to the CodeEditor completions prop for as-you-type suggestions. * fix(database): address review on the injectable page - read-only SQL gate hardened: single-statement only (semicolons in strings/comments ignored), reject any write/DDL keyword anywhere so mutating CTEs and EXPLAIN ANALYZE cannot slip past the leading keyword, and reject writable PRAGMA forms (journal_mode=WAL) while keeping read PRAGMAs - listDbs throws on a shape mismatch like runQuery, so a malformed response is distinguishable from an empty database list - fetchTablePage fetches a pageSize+1 sentinel row so pagination stays bounded when the row count is unknown; normalize page/size to non-negative integers before interpolating - copyText swallows the async clipboard rejection via ?.catch, not just the sync call - icons preserve caller aria-hidden/aria-label (labeled icons stay accessible) instead of forcing aria-hidden - result grid sets aria-sort on sortable headers Worker-side read-only transaction enforcement is out of scope here (it is a database worker change); this tightens the client gate as defense in depth. SqlPanel already remounts per database via its key, so no separate db-change reset is needed.
#597) * feat(console): CodeEditor completions prop for as-you-type suggestions Adds an opt-in `completions?: readonly string[]` to the shared CodeEditor (#579). Non-empty turns on the suggest popup (the default stays prose-quiet, so markdown/json/yaml behavior is byte-for-byte unchanged) and registers a Monaco completion provider for the editor's language offering those words, disposed on unmount. The database SQL panel is the first consumer, feeding it the live table names plus SQL keywords. * feat(database): injectable console page (schema browser + SQL panel) (#598) * feat(database): injectable console page (schema browser + SQL panel) Ships the database worker's #/ext/database page over the injectable-UI protocol (#570): a schema tree with lazy per-driver column/PK/FK/index introspection, a sortable paginated row grid with a row inspector, and a read-only SQL panel (shared Monaco CodeEditor, EXPLAIN, per-db history, client-side write-verb gate). Reads the live database via database::query and database::listDatabases. Registered through host.pages.register in the existing database/ui setup, alongside the function-trigger renderer. The SQL editor feeds the live table names plus SQL keywords to the CodeEditor completions prop for as-you-type suggestions. * fix(database): address review on the injectable page - read-only SQL gate hardened: single-statement only (semicolons in strings/comments ignored), reject any write/DDL keyword anywhere so mutating CTEs and EXPLAIN ANALYZE cannot slip past the leading keyword, and reject writable PRAGMA forms (journal_mode=WAL) while keeping read PRAGMAs - listDbs throws on a shape mismatch like runQuery, so a malformed response is distinguishable from an empty database list - fetchTablePage fetches a pageSize+1 sentinel row so pagination stays bounded when the row count is unknown; normalize page/size to non-negative integers before interpolating - copyText swallows the async clipboard rejection via ?.catch, not just the sync call - icons preserve caller aria-hidden/aria-label (labeled icons stay accessible) instead of forcing aria-hidden - result grid sets aria-sort on sortable headers Worker-side read-only transaction enforcement is out of scope here (it is a database worker change); this tightens the client gate as defense in depth. SqlPanel already remounts per database via its key, so no separate db-change reset is needed. * fix(database): page edge cases from review - Subtitle: a database configured without a `url` no longer reads "no database configured"; it falls back to the database name, and the worker-unavailable / nothing-configured copy stays for the absent cases. - SQL panel is keyed by database only, so a refresh reloads metadata instead of remounting the editor and discarding an in-progress statement and its results. - "open in sql" seeds through quoteTableRef, so a schema-qualified postgres table quotes component-wise instead of becoming one identifier. - Selectable grid rows are tabbable and activate on Enter/Space, matching the click path; non-clickable rows are unchanged. - SQL history state is bounded by HISTORY_LIMIT, matching what is persisted. - Re-expanding a table whose schema read failed retries instead of staying on the error row forever. - Copy feedback moves into a shared useCopyFeedback hook that cancels its pending timer on unmount, replacing the duplicate implementations in the grid and the row inspector.
Keeps both nav sources in `viewOptions`: this branch's presence-gated `promptsAvailable` entry and the injected extension pages that #570 added on main. Resolving to either side alone drops one of the two.
PR #570 moved the pnpm version to the repo-root packageManager field and removed the version: 10 pin from ci.yml and _rust-binary.yml, but _bundle.yml kept its pin. pnpm/action-setup refuses to run when both are set, so every deploy: bundle worker release fails at setup. Drop the pin so the bundle workflow reads packageManager like the other two.
Workers now ship UI into the running console at runtime — React pages, function-trigger renderers, config-form overrides, and scoped stylesheets — over three new trigger types (
console:script,console:style,console:assets). No console rebuild, hot reload on re-registration, teardown on disconnect.Best part: the console dogfoods its own protocol. The Workers tab's Console entry renders a toggle board — itself injected UI — to enable or disable each worker's injected UI. Saving applies live: every open tab drops or restores the affected assets, no restarts anywhere.
The entire worker side is one builder call:
New libraries:
iii-console-ui(crates/console-ui) — Rust crate owning the worker-side contract: content function, Message-path triggers, hot-reload watcher. Path-linked, never published.@iii-dev/console-ui(packages/console-ui) — typedsetup(host)surface plus the console's shared component library; adds zero bytes to worker bundles (resolved at runtime through the console's import map).Authoring guide: docs/sops/injectable-console-ui.md