Repository navigation
·
24 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
[1.0.0] - 2026-11-01
qqq 1.0: the command-line client and the full-screen terminal UI (qqq ui), shipped together as one
binary per platform. Packages: @qrun-io/qqq-cli 1.0.0, @qrun-io/qqq-core 1.0.0 (new),
@qrun-io/qqq-ui-api-client 1.8.0, @qrun-io/qqq-ui-api-conformance 1.6.0. Servers: UI API 1.6.0 up
to 2.0 (QQQ 4.1.0-RC.15 or later). Released as 1.0.0-rc.1 first (tags v1.8.0-rc.2,
cli-v1.0.0-rc.1); this entry is that candidate's plus everything that landed after it. Short commit ids
in parentheses mark the changes made after the candidate.
Added
Command line
- The grammar is
qqq <noun> <verb>(table query,process run, ...); the 0.1 flat commands
(apps,tables,query,get,run,jobs,tail) still work as aliases. - Sign-in: session sign-in for MOCK and anonymous servers; OAuth2 device flow and browser sign-in with
PKCE on a loopback redirect; TABLE_BASEDqqq login --username(password asked, orQQQ_PASSWORD; only
the server session is kept, a refused password stores nothing); refresh before expiry;logout --provider-logoutrevokes (RFC 7009) and opens the end-session page; refused refreshes exit 3. Sign-ins
live in the macOS Keychain, Linux Secret Service, Windows DPAPI or a 0600 file. - Profiles (
--profile,QQQ_PROFILE) with a short name (2 to 6 characters, for the footer and
Home), a description, a sign-in mode for OAuth2 servers (autoasks,browser,device) and
the last use and user; all additive inconfig.json, so files written by 1.0.0-rc.1 load unchanged and
keep theirnote(shown when there is no description).qqq profile list|add|edit|use|remove(also
underqqq config profile):addandedittake--short,--description,--auth-modeand
--check(refuse unless the server answers),edittakes--serverand--rename, an empty value
removes a field,list --probeadds each server's status (d9317f5). - Tables:
list,describe,query(filters, sort, paging,--search,--joinandtable.field
columns,--count,--print-filter, saved views with--view),count,stats(server columnStats, else
computed from the matching records with a note on stderr;--localforces it,--no-localrestores the
error,--max-recordscaps the read at 10,000 by default; 7c66b16),get(sections, adornments,--associations,--links,--follow,--key,--copy),
create,copy,update(-eedits HTML and code fields in$EDITOR),delete,children,
export(csv, tsv, xlsx, json),downloadand--uploadfor file fields,variantsand--variant
everywhere (the chosen variant is remembered per server),columns,actions(what you can do to a
table, with the command for each),api-callandwidget-form. - Forms: contingent fields (country, state, city) with narrowing possible values, labels or unique
partial labels for ids (also in--where), local validation with the server's codes, form adjusters,
interactive-i, CHIP values in their colours. - Filters: the grammar (shorthand operators, quoting, AND/OR groups, expression values such as
now(-7d),thisPeriod(month),me()). Text filters ask for case-insensitive matching (CONTAINS,
STARTS_WITH,ENDS_WITH, quick search);~=,OPERATOR:CSor--case-sensitiveask for a
case-sensitive match. The server does not read the option over the UI API yet (finding 27), so matching
stays case-sensitive until it does. - Processes:
list,describe,runwith every step component (help, HTML as text, view pairs,
process records, the validation review, summary lines, downloads, widgets), asynchronous jobs with
progress,--filefor BLOB fields, back steps, min/max input records, and Ctrl-C that cancels the run on
the server (exit 130). - Bulk load and bulk changes:
table bulk-insertfrom a CSV or Excel file (the upload template, the
server's column suggestion, a mapping document, flags or-i, value mapping, the validation review,
--dry-run),table bulk-editof chosen records or by key rows from a file,table bulk-deletewith
review and confirmation, andbulk-profile list | save | rename | deletefor saved mappings. - Dates: DATE_TIME typed and shown in the local zone (
TZ), sent as UTC instants;--utcfor raw. - More nouns:
apps show(app homes with counts,--widgets),home(counts, quick actions, recent
records),find(the command palette: an app, table, process or report by label),tail,saved-view,
audit list,report runandsaved-report list | show | preview | run | set | pivot | schedules | schedule,share(records of shareable tables),widget(charts and tables as text,--record,
--run),job,prefs,help show,help-search, andapi <operationId>for any of the 219
operations. - Search:
qqq searchshows the matched field and snippet (match), takes--tablerepeated or as a
comma list,--limitper table, names the tables and the total in the footer, searchesfield:value
with a note, lists the quick search syntax in--helpand prints the whole response with--json
(0e07f8a). - Developer mode and scripts:
table apis,table api-doc,table developer, andscript list | show | store | test | logs. - Extensions: a noun per extension the client document knows (14: esb, collab, health, alerts,
assistant, sql-workbench, ...), gated on the server's installed extensions and documented minimum
versions; first-class verbs foresbandcollab(presence, comments, favorites, follow, my work, tags
by id or label). Results print scalars as aligned key/value rows (nested objects as dotted keys) and each
list of objects as a sub-table fitted to the terminal width, with default columns for the inbox,
notebooks, SQL history, comments, tasks, favorites and recents and--columns a,b(or--fields) to
choose;--json, yaml, csv and text are unchanged (5e34433). - Printing (the printing extension, qbit-printing 2.x):
qqq print <table> <id...>renders each record
as a record sheet through the table's Print process, queues one job per record and follows the jobs until
they have printed (--printer,--copies,--no-wait,--timeout; exit 1 when a job failed, 4 when
jobs are still running at the timeout);qqq print list <table>prints a table list (criteria, order,
columns,--page, paper and orientation; up to 10,000 rows);qqq print text [file|-]prints text as a
monospace PDF;qqq print job list|status [--watch]|cancel;qqq printer list|use|show|forget|devices.
The printer chosen is remembered per profile (printing.printersin config.json). Without the extension
the commands exit 5 with the installed list (c1e7bf9, 4bd62b7, d632987, d81c053). - Disabled tables and processes are listed with the reason, and queries, writes, copies, bulk commands
and runs on them are refused before any request, as the web explains the denial. - Shell completion for bash, zsh, fish and PowerShell from the local metadata cache;
cache show | refresh | clear;config set themeanddownload-dir. - Diagnostics and conventions:
qqq doctor,qqq --version(the build and the supported UI API
range), build lines inqqq doctorandqqq ui --check, consistent exit codes (2 usage, 3 auth, 4
unreachable or 502/503/504, 5 not found, 6 validation, 70 server error), downloads that never overwrite a
file or leave--out-dir. - History:
qqq historylists everything you did with the CLI and the TUI on the profile in use,
like a shell history (number, relative or--absolutetime, client, kind, summary;--limit,--since 2h|2026-11-01,--grep,--kind,--all-profiles,--commands,--format);qqq history rerun <n>
runs a line again (asking first for commands that change data),qqq history clearempties it. The
activity log is one JSONL file per profile in~/.local/state/qqq/activity/, rotated once at 5 MB;
secrets (token, password and PIN flags, secret pairs and filter values, Authorization headers) are
written as***;QQQ_HISTORY=offturns it off (0bcc735). - Uploading an attachment to a server without the Object Storage QBit says "This server cannot store
attachments: the Object Storage QBit is not installed."; any server failure naming a missing QBit gets one
such line (437ed3c). - Assistant (assistant extension, qbit-assistant):
qqq assistant ask "<question>"streams the
answer as the model writes it, then prints its numbers (counts, metrics) and the records and tables it
refers to as a table with the command that opens each;--table <t> [--record <id>]sends that page as
context the way the Next UI's panel does,-c <id>continues a conversation,--jsonprints the whole
answer.qqq assistant configshows whether it answers and with which model, or the reason
(NOT_CONFIGURED: no model provider, with what to configure). The generated operation subcommands stay
(a5e0cf4).
Terminal UI (qqq ui)
- A classic full-screen UI in the same binary and on the same profiles and sign-ins as the CLI:
function-key bar (F1 Help to F10 Quit, with Esc+digit for terminals that take the F-keys), PgUp/PgDn
everywhere, Esc back with the screen below keeping its place, a:command line that speaks the CLI
grammar (history, Ctrl+R, Tab completion listing every command with a description, then its arguments),
and a live footer (server and profile, sign-in, UI API version, ping, realtime stream, jobs, clock).
qqq ui table query person -w ...opens a screen directly. - Home: greeting and connection, counts, recently viewed records, quick actions, favorites,
application cards (each with the app's icon as a glyph, an ASCII stand-in under the ASCII-glyphs
setting), work (jobs, alerts, my work, release notes) and the instance's home widgets. F10 offers Quit,
Reset (back to Home with fresh metadata) or Cancel. Home starts with the search line (0691e6f, ef2b554). - Search (F2), the main way into the data: a full screen with a search line, quick search results as you
type grouped by table, each hit's label, key and highlighted snippet with the matched field; ←→/Tab
cycle the tables, Enter opens the record (Esc returns to the hit),oopens the table's grid filtered to
the hits, Space marks hits fora(grid, export, print, bulk, processes),fnarrows to one table,h
recent searches (per profile),?the quick search syntax. The status line shows matches, tables, time,
index size and the last reindex. Without quick search F2 searches names and the records of the current
table.:search <text>opens it. When nothing matches it explains the coverage ("Quick search indexes 17 of 189
tables (Customer, Order, … and 12 more) · 57 records · last reindex 10:38. Tables not indexed cannot be
found here; add them in Quick Search Admin › Quick Search Index, or pressoto search Person by name"),
and the status line names the indexed tables (ef2b554, d76fb03, 81a044f). /finds anything, one search over apps, tables, processes, widgets, reports, records (quick
search, debounced as you type), commands and help, grouped under headers with the best match first
(., Ctrl+K and:find <text>too). F1 and?are only the keyboard reference of the screen: keys
grouped by what they do, the screen's help text and a pointer to/, F9 and:(70c064e). A metadata search index keeps both fast on large instances.- F9, the command center, in two levels: first the areas (Context, Go to, Work, Connection, Settings,
Help) with a count and a one-line summary each, then one area's entries with their keys. ↑↓ moves, Enter
or → opens an area, its first letter jumps to it, ← or Esc goes back, Tab steps to the next area; two
characters search every entry, listed by area; it fits 80x24 (13c020f). - Servers dialog (Ctrl+O,
:servers, F9 › Connection › Servers): every saved profile with its short
name, server, status (UI API version, probed in the background with a 2.5 s timeout), last use, who is
signed in, the sign-in and its description. Enter switches (the stored sign-in is reused, else the
sign-in runs) and Home opens on that server with fresh metadata;nadds,eedits,dremoves,*
makes the default,rprobes again, typing filters. Adding or editing checks that the server answers
/qqq/v1/version(3c45c8e). - Tables: a server-paged grid with columns sized to the screen, fixed rows that never vanish when a
screen overflows, horizontal scroll, sort, view settings, quick search, column statistics, saved views,
table variants, selection with a bulk bar, export and go-to by key. Large tables stay quick (a 10,000 x
40 table draws its first page in about 100 ms). - The filter dialog (F6): every condition is a row of field, operator and value, edited the way its
type asks (text and numbers in place, choices from a searchable list, Space cycles true/false, dates
with presets or typed, operators that fit the field); a row without a value shows(any)and is not
applied; AND/OR and groups are drawn as structure; the help and key lines follow the focus; the footer
shows a live match count. Advanced mode (the grammar, with completion) adds a cheat sheet, a caret under
parse errors and says why it cannot switch back to Guided. Commands are on Ctrl and F keys so letters
always type (Ctrl+N add, Ctrl+D remove, Ctrl+O AND/OR, Ctrl+G group, F2 mode, F10 apply); Esc asks
before discarding changes (067d97c). - Records: sections by tier, links, child lists, next and previous through the list a record came
from, create, edit and copy forms with an editor per field type, contingent pickers that narrow, local and
server validation by field, file uploads and BLOB downloads through a file navigator, audits (A) and
tags (t). - Record collaboration (collaboration extension), at the bottom of the record view so the record starts
right under its title with the cursor on its first field: a dim strip above the key line with the tags,
comments, attachments, open tasks, whether you follow it and who is viewing now with their keys (Tags: none (t) · 0 comments (C) · … · viewing: Admin (you); others viewing or editing replace "(you)" with an accent;
segments drop whole when the width is short), and from 140 columns a right-hand Collaboration panel (view
settingcollaboration panel: auto/on/off) with the latest comments, the next due task, the followers and
each viewer's state. Ina/F9 (keysCPKTW): comments (list, add, reply), follow and stop
following, attachments (list, download through the file navigator, upload, delete), the timeline, tasks
(list, add, done) and the share preview (who could read the record, then send). Strip segments and panel
rows are click zones. Without the extension F9 says "needs the collaboration extension" (b782812, 3e80043). - Developer view (
Don a record or a grid) in sections (Security, Events, Scripts, JSON, Metadata,
Audits, APIs, then any further developer panel; ←→ or 1-9) over a scrollable pane: tables in the grid's
column layout, JSON pretty-printed and tinted (vopens the value viewer,ycopies), web links turned
into TUI actions or shown as browser only, a record's field values, API endpoints, audits and script test
runs, a table's ESB counters, metadata and JSON; F3 goes to the record or the grid (f236c7b). - Processes: the wizard draws every step as the web does (help, HTML, view values, records, the
validation review, widgets, downloads), with back steps, record limits, progress with elapsed time and
cancel. - Bulk load and bulk changes: a wizard for bulk insert and bulk edit from a file (upload through the
file navigator, a column mapping grid with typed defaults and field help, value mapping, review with
optional validation, result), bulk edit of switched-on fields, bulk delete, saved bulk-load profiles and
the upload template. - Reports, saved reports and sharing: run reports (process reports and streaming ones), edit a saved
report's filter, columns and pivot, and share records of shareable tables (Z,:share) with users or
groups. - Sign-in in the UI: TABLE_BASED username and password, OAuth2 in the browser (authorization code with
PKCE, the device flow as the alternative) and Auth0; sign-out ends the server or provider session; a
session that expires mid-use opens sign-in on top and returns to the screen. - Widgets that act: dropdowns and date pickers, parent widgets with children in a grid or tabs, process
widgets, data bag versions, script revisions, export, ad hoc buttons and inputs, dynamicForm editing and
composite widgets; dashboards and widgets drawn in block characters (stats, bar charts, sparklines,
percentage bars, tables, steppers); the ESB overview as:esb overviewshows it (destinations,
publishers, triggers, counters; Enter on a destination offers its table's ESB, messages and dead
letters); disabled tables, processes and apps explain the denial, and capabilities gate new, edit,
delete and copy (19cc3ec). Text and HTML widgets (Quick Search Admin's Search Diagnostics, the SQL Workbench
summary, the alerts cards) are drawn as a document with the web's hierarchy: headings in the accent colour,
leading status words (OK, WARN, FAIL, DEGRADED, DOWN, ...) as fixed-width coloured badges,Label: value
items as an aligned two-column list, ISO timestamps in the profile's date format, paragraphs wrapped at
about 100 cells, enumerations as bullets, button rows of links as items that Enter follows (ASCII badges
and bullets under the ASCII setting) (d7c6e65). - Extension operations on the
:line (:alerts get-inbox,:api <operationId>); widget payloads
without a terminal block show their JSON as key/value rows and sub-tables, andJshows the raw JSON. - Dates: type them or pick them: one date control for DATE and DATE_TIME fields in create and edit
forms, process forms, bulk edit and the filter dialog's value cell. Typed entry shows the value in the
profile's display format with the format hint (and zone), and reads ISO, the display format, partial
dates (2026-3-5,3/5),t/today,n/nowand the filter grammar'snow(-7d)and
startOf(month); a date that does not exist is refused with the reason and the field keeps the focus.
F2 or Ctrl+Space opens a month calendar anchored to the field (arrows, PgUp/PgDn, Shift a year, Home/End,
ttoday) with a time row for DATE_TIME.:dates order ymd|mdy|dmy clock 24h|12h week monday|sunday weeknumbers on|off enter picker|nextsets the format per profile. Values go out as before:YYYY-MM-DD
and DATE_TIME as the UTC instant of the local time, bulk edit included (ad4001d). - Printing: Ctrl+P prints what you see on every screen (also
pon records and grids, F8 where the
screen has no Delete,:print [printer],a, F9 and the Print Screen key where the terminal passes it
on). A record view prints its record sheet; a grid prints a table list with the columns, widths, filter
and sort shown, choosing all rows, this page, or the selection as a list or as record sheets; any other
screen prints its text as a monospace PDF. A printer picker shows unprintable printers with the reason
and preselects the last used one; jobs are followed in the title bar and status line, and:printjobs
lists recent jobs. Without printing, Ctrl+P saves instead (the grid's export, else the screen text). No
Print action is offered without the extension (acfb090, 555c434). - SQL Runner (sql-workbench extension), from the SQL Workbench app,
/, F9 › Work and:sql: an SQL
editor with syntax tint, F5 / Ctrl+Enter running the statement under the cursor, completion popups
(tables after FROM, columns after SELECT, keywords and recent SQL), history; a server-paged,
server-sorted result grid drawn like the main grid; F8 /xexport every row as csv, tsv, xlsx or json
or copy it,yYCtrl+Y copy the cell, row or result; errors inline with their SQL position; EXPLAIN as
a plan tree (F6); a schema browser (F3); notebooks with SQL and markdown cells (F2, F4); quick text bar
charts; the audited run history with re-run (F7). Read-only runs; hidden, and:sqlexplains why, when
the server lacks the extension (cc78396, efc202a). The completion popups of the SQL Runner and the:line take the width they need, in two
columns, with wrapped descriptions (70b6fa1). - The mouse, everywhere (on by default; F9 › Settings › Mouse,
:mouse on|off, saved inui.mouse;
--no-mouse/--mousefor one run): a click selects or focuses, a double-click activates, a right
click opens the actions at that row, the wheel scrolls the pane under the pointer, a drag on a grid
column's edge resizes it and on its header moves it, the F-key bar and the footer's server are
clickable, dialogs, menus, the SQL Runner and the date picker take clicks. With the mouse on, the
terminal selects text with Shift+drag (cbabc31). - A live screen saver (
:lock, the idle timeout,:saver [style]): tiles refreshed every 10 to 30 s
for people online, jobs, health, database sessions, ESB depth and dead letters, unread alerts, realtime
events per minute, ping and favorite table counts, each hidden when its extension is absent and dimmed
when stale; four styles (Bounce, Starfield, Flip clock, Big numbers, or auto) starring Query, the qrun.io
mascot, whose block-letter logo says the connected profile's name (short name up to 6 characters) with
the server host beneath; at most 4 frames a second; with a PIN set the prompt opens over the saver
(c22ae75, 899326a). Each style is one compact group at most about 90 columns wide that moves as a unit
(Big numbers: number, Query, caption and tiles as one centred stack; Flip clock: tiles and Query with the
clock; Bounce: tiles beside the logo, stacked under it on a narrow terminal), with the clock line and the
lock line just above and below it (aff2b00, 98d2076). Against burn-in every element moves (the header and
lock line change place every 30 s, the flip clock drifts, Big numbers changes corners) and the screen dims
after 10 minutes (:saver burnin on|off,:saver dim <minutes|off>) (899326a). - Clipboard copy of CLI equivalents: the "CLI equivalent" dialog copies its command with
y,cor
Enter, the filter dialog has Ctrl+Y, and F9 › Settings › "Copy CLI commands to the clipboard
automatically" (ui.copyCliCommands, default off) copies as soon as the dialog opens (e8f075a). - History screen (
:history, F9 › Work › History): the activity log of the profile, newest at the
bottom; typing filters, Enter does an entry again (runs the:command, opens the record, the table with
its filter, the process),ycopies the CLI equivalent,cor F8 clears. The TUI records its:
commands, opened apps, tables and records, queries with filters, record creates, edits and deletes (no
values), process runs and outcomes, exports, prints, server switches, sign-in and sign-out. Ctrl+R on the
:line is a bash-style reverse search over these commands (Ctrl+R again for older matches, Enter runs,
Esc edits) (0bcc735). - Column statistics fallback:
Son a table without the server capability (or when the server
answers 403 or 404) computes count, nulls, distinct, min, max, sum, mean, median, text lengths and top
values from the rows the grid has loaded; the dialog says so andaloads up to 10,000 rows (e5d6c92). - Help and care: F1 shows the application's help for the app, widget, table, process or step you are
on, and the grid footer shows the column's help; searching ignores case (a term starting with=, or
Match exact case, asks for exact case); themes per profile (high-contrast, classic, light);qqq ui --check(and a quick check at startup) finds tmux key and colour problems and offers fixes;--ascii,
--linear; Ctrl+C or a crash always restores the terminal. A soak test drives the real UI in tmux with
random keys. packages/tui/scripts/smoke.sh --server URL [--profile NAME]runs the tmux smoke test against any
server in an isolated config (6950e9d, f149a47).- Assistant panel (assistant extension):
Ctrl+G,:ask [question]or F9 › Work › Assistant opens a
chat pane on the right (the whole body below 110 columns): the question line at the bottom, the
conversation above with each answer's numbers and links; Tab moves over the links and Enter opens the
record or grid (beside the panel; a full-width panel closes so the screen shows). Questions carry the
record or grid (with its filter) under the panel as context, as the Next UI sends it (Ctrl+D drops it);
↑↓ recall this profile's questions; Ctrl+L starts a new conversation, Ctrl+X stops an answer, Esc closes
(the conversation is kept). Without the extension the entry is disabled and Ctrl+G says what is missing;
when the assistant is off the panel shows the server's reason and what to configure (2c70c3c).
Kernel, client and conformance
@qrun-io/qqq-core(new): everything that is not a terminal, shared by the CLI and the UI: output
formats with JMESPath--query, the filter grammar, an operation index generated from the OpenAPI
document, the form engine, the process runner, records and associations, the widget render model, the
metadata cache, the extension registry, profiles and the keyring,Printing(printers, devices, jobs,
print, cancel, watch;printTableList,printText),formatDocumentfor extension output, and the
date parser and formatter.@qrun-io/qqq-ui-api-clientis generated from UI API 1.8.0 merged with 14 extension documents (219
operations, each tagged with its extension, including the 17 printing 2.0.0 operations, which are the generatedqqq printing ...subcommands for print agents; printing 2.1's table-list and text printing are processes the kernel
runs, reached asqqq print listandqqq print text, not asqqq printingsubcommands), and gains PKCE, revocation and end-session helpers (5cf6243).- Conformance: the suite checks
GET /qbit/printing/sessionand the printing tables when a server
lists printing (05f467c);qqq-dev-idpgains the authorization code with PKCE (Approve/Deny page),
revocation and end-session. - Assistant (
extensions/assistant.ts):Assistant.config()(the feature probe,installed: false
without the extension) andAssistant.ask(question, { context, conversationId, onEvent, signal }),
which creates a conversation with the page context, reads the turn's server-sent events as they arrive
(SseParser) and folds them into an answer (text, numbers, links, tools, usage);parseAppHrefand
assistantContextFormap app paths and pages both ways (a5e0cf4, e5327b2).
Packaging, CI and development
- Distribution: one single-file
qqqbinary per platform with the terminal UI bundled, for macOS arm64
and x64, Linux x64 and arm64 (glibc and musl) and Windows x64 (npm run binaries,--cli-onlywithout
the UI); a curl installer that verifiesSHA256SUMSand installs the newest stablecli-v*release
(--preorQQQ_PRE=1takes prereleases,--dry-runprints the download,--helpworks piped from
curl) (a14cd5c); a Homebrew tap and a Scoop manifest that pass their CI and lint (5563f2f);npm run releasewith the readiness gate,scripts/verify-binary.sh/.ps1anddocs/release-runbook.md. - CI turns on the macOS arm64 and Windows x64 lanes of qqq-orb 0.8.33 (0d62416); the package tests run
without shell globs for the Windows lane (5dd5e2d). - Enterprise test server:
scripts/enterprise-server.shstarts a local enterprise QQQ server with a
MinIO container for object storage (6018cdf), andscripts/enterprise-smoke.shsweeps the CLI over its
qbits (cf0e610);scripts/print-agent.shruns qqq-print-agent's virtual file printer against a local
server (fc47cb8). The enterprise profile gives the assistant a model provider: Claude whenANTHROPIC_API_KEYis
set in the private env file~/.local/state/qqq-enterprise/assistant.env(yours, not a symlink, mode 0600; read
by name, never sourced or printed, exported only into the server's environment), else a local Ollama;--status
and--assistant-statusshow which model answers or why none does (29f3559). - Documentation: npm READMEs for every package, a rewritten repository README,
docs/README.md,
CONTRIBUTING, SECURITY and CODE_OF_CONDUCT, issue and pull request templates, CODEOWNERS and Dependabot
(e46bc6b, 1b0d547, ac86860, 7fed559); TRY-IT as the 1.0.0 walkthrough (cddbea7).
Changed
- Default export names carry the local date and time:
person_2026-11-01_102316.csv, notperson.csv,
fortable export,widget --csv, report downloads, field saves from a record, and every TUI export, save
dialog and screen-text capture (<name>_<YYYY-MM-DD>_<HHmmss>.<ext>, 24-hour, no colons). A name you give
(-o, a name typed in the file dialog) is used exactly as given, and a name the server chooses is kept
unless it is taken, when the stamp goes before the extension (c201f92). - One meaning for
-oacross the CLI:-o/--outis always the output file; the sort is--order
(no short form).table export -o people.csvused to sort by a field namedpeople.csv(the server
answered 403); it now writes the file. Migration: write--orderwherever-omeant the sort. On the
commands that write no file (table query,saved-view save,saved-report previewandset),-o
still sorts until 1.1, with a deprecation note on stderr; a sort field that looks like a file path
(out.csv,./x) is warned about; completion offers fields after--orderonly (0687083). - Changed from 0.1: sign-ins move from
~/.config/qqq-cli/credentials.jsonto named profiles
(~/.config/qqq/config.json) with secrets in the OS keyring; 0.1 sign-ins are imported once, and the old
file is renamed only after the keyring took every entry. The global--serverand--versionhave no
short form any more (-sand-Vcollided with--setand--view). qqq login --server URLagainst an existing profile now asks first (see Fixed).qqq doctorwords its
UI API support from the same range as--version(1fd06db).- The UI's search and help are separate: F2 is Search,
/finds anything, F1/?is only the keyboard
reference, and F9 no longer lists every app, recent record and metadata match (70c064e, ef2b554). - The UI's F9 menu, filter dialog, developer view, date entry and record view were redesigned (see Added
and Fixed); Ctrl+P no longer steps to the previous record (PgUp and[still do; Ctrl+N still steps to
the next) because it prints (555c434). - The conformance suite authenticates every authenticated check the same way, as the CLI does: a JWT as a
bearer token, a session UUID also as thesessionUUIDcookie, and on MOCK and FULLY_ANONYMOUS servers
without a token a server session frommanageSession; its metaData check names the authentication used
(e7108ad). fast-uri3.1.9 (transitive, through ajv in the conformance package) for four URI parsing advisories
(0845036).
Fixed
- Links with a base64
filterparameter (the form the web UI and the assistant write) opened the whole table:
the UI's link reader and the kernel'sparseAppHrefnow decode it, JSON still works, and a filter without
criteria counts as an empty one (e5327b2). - Output piped into a reader that exits early (
qqq table query person | head -1, exports, process logs,
assistant ask) ends quietly with status 0 instead of an unhandledwrite EPIPEstack trace (7c66b16). qqq login --server URLwithQQQ_PROFILE(or--profile) naming an existing profile of another
server silently pointed that profile at the new server. It now warns and needs--yes(or a yes at the
question on a terminal);--profile <new-name>adds a profile instead. A token refresh under a one-off
--serverno longer moves the profile either (a10c834).qqq esb messages <topic>without--triggernames the topic's triggers in the error, and--trigger
takes the process name too; before, the server's "name one of the triggers" did not say which and a
process name answered 404 (248f30f).qqq health get-summaryon a server that serves/healthwithout advertising the health extension shows
that endpoint's checks in the summary shape, with a note, instead of "not installed" (248f30f).- The UI's record view keeps its layout when paging record to record: each child list is a box of fixed
height (5 data rows by default, padded when shorter, scrolled inside with "rows 1-5 of 12" when longer),
empty lists still draw their box, fields and columns are placed from the metadata, and the row count is a
per-table view setting (v,childRows) with a default inui.childRows. Thevdialog is a settings
form like the grid's View settings: Columns cycles auto, 1, 2; Label width (8-60) and Child list rows (1-50) take typed
digits or +/- and Backspace returns them to auto or the profile default; one Collaboration panel row cycles auto, on,
off;rresets with a confirm;*marks values changed from the default An association a section's
childRecordListwidget lists shows once, in the widget's place and under its label (0f7f536). - The UI's filter dialog reads escaped quotes like core's grammar (213c605); before the redesign a
true/false quick filter could be set to true but not changed from the quick row (067d97c). - The UI's jobs widgets showed each statistic's web address; the alerts setup widget ran its columns
together; HTML entities such as·were not decoded; the ESB app showed "(ESB_OVERVIEW: no
terminal rendering yet)" (19cc3ec). - No text in the UI runs outside its container. Lines are cut to the cells they have, measured in terminal
cells (wide characters count double), with…at the cut; dialogs are held inside the screen and their
lines default to the dialog's inner width. View settings shows only the value in each row (Pinned columns
0, not the explanation) and explains the selected row on a help line; its key help breaks between keys
in at most three lines, dropping the least important first;+/-change Pinned columns as the help
said. Screen footers, the record view's, F9's, the Servers dialog's, the SQL Runner's, the date picker's
and message dialogs' included, drop whole keys instead of cutting one in the middle. Process errors wrap
to the pane, the home screen's header lines end in…, and a column width saved wider than the terminal
is held to the grid.Vshows the whole value of the grid cell, or of the record view field row, under
the cursor.packages/tui/scripts/overflow-sweep.shchecks every screen and dialog at 80/100/120/200
columns by 24/50 rows, andsmoke.shchecks its captures the same way (4abfd8d, c94499c, 0e4716a,
da76a35, c2a9e98, 3bc2179). - App cards showed the app's Material icon name instead of a glyph (0691e6f).
- Quitting the UI after the terminal was gone printed "setRawMode failed with errno: 2" and a native
shutdown error (e13e7bf). - A record found by the UI's search opened with an empty key (the server's field is
recordId) and was
listed last (70c064e). - Process help markup is stripped with the core
stripTags(c5b4b47). - The developer view drew the ESB sample event as broken fragments (minified JSON went through the prose
word-wrap); code blocks are pretty-printed and drawn one source line per screen line. npm testruns on Node 20; a question closed with Ctrl-D no longer hangs on Node 22.12; presence tests
wait on state and have deadlines (16be5c2); the PIN storage test no longer flakes (7d754bf); the metadata index test guards by scaling and the dashboard
widget test asserts concurrency, not wall-clock bounds (e3822d2, 508ddc0).- The UI's grid draws adorned cells like the record view (REVEAL values stay masked, HTML as text, chips in
brackets); the create form asks for a text primary key and leaves out generated numeric keys. - The hardening review (
docs/review-2026-10-31.md): option collisions,table updateon contingent
fields, corrupt config and secrets files no longer overwritten, awaited 0.1 imports, Ctrl-C and Ctrl-D at
prompts, REVEAL values masked in query cells, one DATE_TIME, help and download path, checked numeric
options and file arguments. smoke.shskips the sample-only record steps against another server (f149a47).
Security
- Links in the UI's widgets and server HTML are content: Enter opens a table (with a filter that has the
shape of a query filter), a record (a plain key), a process or an app only when the metadata knows it, and
shows the address of anything else without opening a browser. Text starting with:in a server link is
shown, never run. Only links the TUI builds itself (ESB destination rows, keyed so server JSON cannot
forge them) run commands; the command is shown first, server names are quoted, and a command that changes
data asks first (c35def5). scripts/enterprise-server.shkeeps its MinIO credentials, pid file, log and data in a private state
directory (${XDG_STATE_HOME:-~/.local/state}/qqq-enterprise, mode 0700), uses an existing file only if
you own it, it is not a symlink and the credentials are 0600, checks that a pid file holds a number before
signalling it, and parses the credentials file for its two keys instead of sourcing it (3fa81bf).- Fixes for the 21 CodeQL alerts raised on the release pull request:
qqq table editandqqq developerno longer build the editor's shell command from the file name; a
primary key holding shell syntax (such as$(...)) ran as a command when$EDITORopened. The path is
passed to the shell as$1(POSIX) or as a quoted variable (Windows) (4d13ba9).qqq-dev-idpend-session redirects only to a loopbackpost_logout_redirect_uri, rebuilt from its
parts, and answers 400 for any other (9609acf).- Filter values escape backslashes as well as double quotes when printed or completed, and the parser
and tokenizers read\\and\"back (e1694d4). - HTML help and widget text becomes terminal text in one linear pass; entities are decoded once, so
&lt;shows as<(e1694d4). - Regular expressions that took quadratic time on long input are replaced with linear scans: slash
trimming in API paths, BLOB sizes,${name}interpolation and${input.x}dependencies, filter error
positions,tmux list-keysparsing (e1694d4), the search screen's status-line clock time and the date
parser's split of a date from its time (9535e3a). - The release helper escapes every sed metacharacter in the version it puts into its notes command
(d749f14).
Known limitations
- Jobs need a durable-jobs server. Auth0 sign-in (CLI and UI) is built but has not met a real Auth0
tenant (finding 28, qqq-cli#10). Seedocs/server-findings.mdfor the server-side issues the clients
work around, including case-insensitive text filters (finding 27). - The binaries are not Developer ID signed or notarized (macOS: Gatekeeper prompt for browser downloads,
xattr -d com.apple.quarantineclears it) nor Authenticode signed (Windows: SmartScreen warning). The
Windows and macOS x64 binaries are cross-compiled and were not run before this release. - The npm package is the CLI only;
qqq uicomes with the binaries. - Printing needs the printing extension (qbit-printing 2.x) and Search the quick search extension;
without them the UI offers no Print action and F2 searches names and the current table. - Parity with the web UI (
docs/parity/feature-matrix.md): the CLI has no open row (290 pass, 107 n/a, 4
blocked on cited server findings) and the UI has none open (331 pass, 67 n/a, 3 blocked, SEC-030 on
qqq-cli#10 and qqq#1359 among them).npm run release -- --checkreports READY.