@carllee1983/dbcli 1.42.0 → 1.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ui-style.css CHANGED
@@ -1,3 +1,3 @@
1
1
  @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap");
2
2
 
3
- /*! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}body{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));font-family:Inter,system-ui,sans-serif;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.card{overflow:hidden;border-radius:.75rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-shadow:0 2px 15px -3px #00000012,0 4px 6px -2px #0000000d;--tw-shadow-colored:0 2px 15px -3px var(--tw-shadow-color),0 4px 6px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.sticky{position:sticky}.top-0{top:0}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-8{margin-bottom:2rem}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-4{margin-top:1rem}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-\[450px\]{height:450px}.h-full{height:100%}.min-h-0{min-height:0}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.max-w-7xl{max-width:80rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-slate-50>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(248 250 252/var(--tw-divide-opacity))}.overflow-x-auto{overflow-x:auto}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-primary-100{--tw-border-opacity:1;border-color:rgb(219 234 254/var(--tw-border-opacity))}.border-slate-100{--tw-border-opacity:1;border-color:rgb(241 245 249/var(--tw-border-opacity))}.border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity))}.border-l-primary-500{--tw-border-opacity:1;border-left-color:rgb(59 130 246/var(--tw-border-opacity))}.bg-emerald-50{--tw-bg-opacity:1;background-color:rgb(236 253 245/var(--tw-bg-opacity))}.bg-emerald-500{--tw-bg-opacity:1;background-color:rgb(16 185 129/var(--tw-bg-opacity))}.bg-primary-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity))}.bg-primary-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-primary-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-slate-50{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.bg-slate-50\/30{background-color:#f8fafc4d}.bg-slate-50\/50{background-color:#f8fafc80}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-white\/80{background-color:#fffc}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-1{padding-bottom:.25rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-emerald-600{--tw-text-opacity:1;color:rgb(5 150 105/var(--tw-text-opacity))}.text-primary-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.text-primary-900{--tw-text-opacity:1;color:rgb(30 58 138/var(--tw-text-opacity))}.text-slate-300{--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.text-slate-800{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.hover\:bg-primary-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity))}.hover\:bg-primary-50\/30:hover{background-color:#eff6ff4d}.hover\:text-primary-600:hover{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group:hover .group-hover\:text-primary-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity))}@media (min-width:640px){.sm\:flex{display:flex}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:p-8{padding:2rem}}
3
+ /*! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}body{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));font-family:Inter,system-ui,sans-serif;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.card{overflow:hidden;border-radius:.75rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-shadow:0 2px 15px -3px #00000012,0 4px 6px -2px #0000000d;--tw-shadow-colored:0 2px 15px -3px var(--tw-shadow-color),0 4px 6px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.sticky{position:sticky}.top-0{top:0}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-8{margin-bottom:2rem}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-4{margin-top:1rem}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-\[450px\]{height:450px}.h-full{height:100%}.min-h-0{min-height:0}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.max-w-7xl{max-width:80rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-slate-50>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(248 250 252/var(--tw-divide-opacity))}.overflow-x-auto{overflow-x:auto}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-amber-300{--tw-border-opacity:1;border-color:rgb(252 211 77/var(--tw-border-opacity))}.border-primary-100{--tw-border-opacity:1;border-color:rgb(219 234 254/var(--tw-border-opacity))}.border-sky-200{--tw-border-opacity:1;border-color:rgb(186 230 253/var(--tw-border-opacity))}.border-slate-100{--tw-border-opacity:1;border-color:rgb(241 245 249/var(--tw-border-opacity))}.border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity))}.border-l-primary-500{--tw-border-opacity:1;border-left-color:rgb(59 130 246/var(--tw-border-opacity))}.bg-amber-50{--tw-bg-opacity:1;background-color:rgb(255 251 235/var(--tw-bg-opacity))}.bg-emerald-50{--tw-bg-opacity:1;background-color:rgb(236 253 245/var(--tw-bg-opacity))}.bg-emerald-500{--tw-bg-opacity:1;background-color:rgb(16 185 129/var(--tw-bg-opacity))}.bg-primary-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity))}.bg-primary-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-primary-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity))}.bg-sky-50{--tw-bg-opacity:1;background-color:rgb(240 249 255/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-slate-50{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.bg-slate-50\/30{background-color:#f8fafc4d}.bg-slate-50\/50{background-color:#f8fafc80}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-white\/80{background-color:#fffc}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-1{padding-bottom:.25rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-amber-600{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity))}.text-amber-950{--tw-text-opacity:1;color:rgb(69 26 3/var(--tw-text-opacity))}.text-emerald-600{--tw-text-opacity:1;color:rgb(5 150 105/var(--tw-text-opacity))}.text-primary-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.text-primary-900{--tw-text-opacity:1;color:rgb(30 58 138/var(--tw-text-opacity))}.text-sky-600{--tw-text-opacity:1;color:rgb(2 132 199/var(--tw-text-opacity))}.text-sky-950{--tw-text-opacity:1;color:rgb(8 47 73/var(--tw-text-opacity))}.text-slate-300{--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.text-slate-800{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.hover\:bg-primary-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity))}.hover\:bg-primary-50\/30:hover{background-color:#eff6ff4d}.hover\:text-primary-600:hover{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group:hover .group-hover\:text-primary-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity))}@media (min-width:640px){.sm\:flex{display:flex}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:p-8{padding:2rem}}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.42.0",
3
+ "version": "1.43.0",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
5
  "contextFileName": "AGENTS.md"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carllee1983/dbcli",
3
- "version": "1.42.0",
3
+ "version": "1.43.0",
4
4
  "description": "Database CLI for AI agents",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -14,6 +14,10 @@
14
14
  "./core": {
15
15
  "types": "./dist/core.d.ts",
16
16
  "import": "./dist/core.mjs"
17
+ },
18
+ "./agent-core": {
19
+ "types": "./dist/agent-core.d.ts",
20
+ "import": "./dist/agent-core.mjs"
17
21
  }
18
22
  },
19
23
  "license": "MIT",
@@ -71,6 +75,7 @@
71
75
  "docs:check": "bun run scripts/check-user-docs.ts",
72
76
  "skill:check": "bun run scripts/check-skill-parity.ts",
73
77
  "platform:check": "bun run scripts/check-platform-parity.ts",
78
+ "agent-core:check": "bun run scripts/check-agent-core-purity.ts",
74
79
  "typecheck": "tsc --noEmit --pretty false",
75
80
  "test:perf": "bun test ./tests/perf/*.bench.ts",
76
81
  "lint": "eslint src tests scripts --ext .ts --max-warnings=0",
@@ -106,13 +111,14 @@
106
111
  "dts-bundle-generator": "^9.5.1",
107
112
  "eslint": "^10.4.0",
108
113
  "happy-dom": "^20.10.6",
109
- "postcss": "^8.5.14",
114
+ "postcss": "^8.5.25",
110
115
  "prettier": "^3.8.3",
111
116
  "tailwindcss": "3.4.1",
112
117
  "typescript": "^5.9.3",
113
118
  "typescript-eslint": "^8.59.4"
114
119
  },
115
120
  "overrides": {
116
- "brace-expansion": "^5.0.6"
121
+ "brace-expansion": "^5.0.9",
122
+ "postcss": "^8.5.25"
117
123
  }
118
124
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.42.0",
3
+ "version": "1.43.0",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -239,8 +239,10 @@ dbcli init --system elasticsearch \
239
239
  dbcli init --conn-name staging --env-file .env.staging --permission query-only
240
240
  dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
241
241
  dbcli use --list # show all, * marks default
242
- dbcli use prod # switch default
242
+ dbcli use prod # switch default (persists — avoid for one-off queries)
243
243
  dbcli query --use staging "SELECT 1" # one-shot override on any subcommand
244
+ DBCLI_CONNECTION=staging dbcli query "SELECT 1" # one-shot via env; parallel-safe
245
+ dbcli --use staging,prod query "SELECT count(*) FROM users" # read-only fan-out
244
246
  dbcli init --rename staging:stg # rename
245
247
  dbcli init --remove stg # remove
246
248
  ```
@@ -296,7 +298,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
296
298
  | `use` | n/a | Show/switch default named connection (v2 only). |
297
299
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
298
300
  | `schema` | query-only+ | SQL: per-table or full scan into `.dbcli/schemas/`. MongoDB: sampled. ES: flattened mapping. Redis: per-key only (type/TTL/size). Supports `--recovery`. |
299
- | `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard in a browser. Supports `--recovery`. |
301
+ | `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard in a browser. `--fields` (projection), `--truncate` (cell width), `-f/--query-file` (read query from file or stdin), `--use a,b` (read-only fan-out). Supports `--recovery`. See **Query workflow flags**. |
300
302
  | `explain` | query-only+ | **(v1.23)** Read-only query plan with annotations. SQL only. Single query, `@saved-query`, `@file.sql`, or `--bulk @glob/*`. `--analyze` (EXPLAIN ANALYZE / MariaDB ANALYZE SELECT), `--format markdown\|json\|table`. |
301
303
  | `lint` | n/a | Static SQL anti-pattern advisor (no DB connection). 9 rules incl. schema-aware implicit-cast / NOT IN-nullable checks via the layered `.dbcli/schemas/` cache; global `--use <conn>` selects a named cache. Findings carry rewrite drafts + guarded `explain` verify commands (`--analyze` only for proven read-only SQL) — report-only, never executes. `--format text\|json\|markdown`, `--min-severity`, `--no-schema`, `--bulk`. Supports `--recovery`. |
302
304
  | `plan` | n/a | Static SQL risk analyzer (`--format text\|json`); classifies a statement without connecting to the database. |
@@ -304,7 +306,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
304
306
  | `queries` | n/a | Manage saved snippets: `list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`. |
305
307
  | `insert` / `update` | read-write+ | SQL or MongoDB only. JSON `--data` / `--set`; `--where` required on `update`; `--dry-run` first. Redis writes go through `query`. Supports `--recovery`. |
306
308
  | `delete` | data-admin+ | SQL or MongoDB; Redis has a basic implementation (see Redis section). `--where` required; `--dry-run` first. Supports `--recovery`. |
307
- | `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
309
+ | `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. **Fails closed rather than truncating silently**: if the auto-limit would drop rows, the export errors out and you must pass `--no-limit` or `--limit N`. Supports `--recovery`. |
308
310
  | `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
309
311
  | `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
310
312
  | `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`, `--ignore <globs>`, `--format json\|table\|markdown`. Drizzle: point at `drizzle/meta/<NNNN>_snapshot.json` (run `drizzle-kit generate` first; `.ts` sources are rejected with a hint). TypeORM/Sequelize: feed tool-generated DDL (`schema:log` / a schema-only dump); source files are rejected with the exact generation command to run. |
@@ -325,8 +327,9 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
325
327
  | `skill` | n/a | Generate / install AI skill docs (`--install <claude\|gemini\|antigravity\|copilot\|cursor\|codex\|windsurf>`); `skill tasks list/show/plan` for Agent Task Packs; `skill context` for an LLM prompt-context payload (for injecting into another LLM, not needed for normal operation). |
326
328
  | `migrate` | admin | SQL only. **DDL; dry-run by default** — needs `--execute`. |
327
329
 
328
- `--use <name>` on any subcommand (including `status` / `doctor`) targets a v2 connection
329
- without changing the default. `--recovery` is honoured by `query`, `q`, `insert`, `update`,
330
+ Use root-level `dbcli --use <name> <command>` for any command; `query`, `schema`, `list`,
331
+ `export`, and `check` also accept command-level `--use`. Both target a v2 connection without
332
+ changing the default. `--recovery` is honoured by `query`, `q`, `insert`, `update`,
330
333
  `delete`, `export`, `schema`, `inspect`, `lint`, and `diff --against-orm` (see **On failure** above).
331
334
 
332
335
  **Write & query flag semantics** (SQL/Mongo `insert`/`update`):
@@ -344,6 +347,27 @@ without changing the default. `--recovery` is honoured by `query`, `q`, `insert`
344
347
  - `--recovery` is recommended for automated agent pipelines (enables `dbcli recover --apply`
345
348
  after a failure); optional for one-off manual writes.
346
349
 
350
+ ## Query workflow flags
351
+
352
+ These exist so you do not have to pipe output through `head` / `jq` / `python3`
353
+ to make it usable. Reach for them instead of post-processing.
354
+
355
+ | Need | Flag | Notes |
356
+ |------|------|-------|
357
+ | Only some columns | `--fields sn,bet,created_at` | SQL and MongoDB. Mongo pushes a real `projection` / `$project` to the driver; `_id` is dropped unless you ask for it. A field the result lacks comes back as `null`, so verify spellings with `schema` before reading meaning into an all-null column. |
358
+ | Everything except a huge column | `--fields=-raw_response` | Exclusion form. Include and exclude cannot be mixed. |
359
+ | One field is a giant JSON blob | `--truncate 120` | Table output truncates cells at 120 chars **by default** and marks them `…(+3412 chars)`. `--no-truncate` disables it. Explicit truncation flags are rejected on JSON, CSV, HTML, and `--ui` output. |
360
+ | Query has quotes / newlines / `$regex` | `-f pipeline.json` or `-f -` | Reads the query from a file or stdin; use a heredoc for Mongo pipelines. Passing both a file and positional query text is an error, never a silent pick. `-f -` needs piped input — it refuses an interactive terminal rather than hanging. |
361
+ | Same query across connections | `--use hub-prod,site-a` | Read-only fan-out. Per-connection results, one failure does not cancel the others. Exit `0` all-ok, `2` mixed, `1` all-failed. Rejects writes, `--recovery`, `--ui`, CSV/HTML. |
362
+ | Pick a connection for one call | `DBCLI_CONNECTION=hub-prod dbcli query …` | Env var, or `--use` on the subcommand. Priority: `--use` > `DBCLI_CONNECTION` > saved default. Neither writes the default back to disk, so parallel shells never fight. Requires a v2 config — a single-connection (v1) project rejects both rather than silently running its only connection. **Do not** use `dbcli use <name>` just to switch for one query. |
363
+
364
+ **Truncation is reported, never implied.** When the query-only auto-limit trims a
365
+ result, the table footer reads `Rows: 1000 (truncated; limit 1000)`, `--format json`
366
+ carries `metadata.truncated` / `metadata.limit_applied`, and CSV appends a `#`
367
+ comment. `Rows: 1000` with no marker means exactly 1000 rows exist — do not infer
368
+ truncation from a round number. This applies to `query` and to `q` snippets
369
+ (whose own 1000-row guard reports the same way). `export` refuses to truncate at all. Redis replies trimmed by the size guard report the same way, and each size-guard warning is printed on stderr.
370
+
347
371
  ## Permission levels
348
372
 
349
373
  | Level | Allowed |
@@ -112,7 +112,7 @@ dbcli schema --use prod # Scan prod DB; saves to .dbcli/schemas/prod
112
112
 
113
113
  ### query
114
114
 
115
- Execute SQL query (MySQL/PostgreSQL/MariaDB) or JSON filter/pipeline (MongoDB).
115
+ Execute a SQL statement, MongoDB filter/pipeline, allow-listed Redis command, or Elasticsearch DSL/Lucene query.
116
116
 
117
117
  ```bash
118
118
  # SQL databases
@@ -143,13 +143,84 @@ dbcli query "SELECT day, dau FROM dau_daily" --ui # open in brows
143
143
  dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdout
144
144
  ```
145
145
 
146
- **Options:** `--format <table|json|csv|html>`, `--ui` (open the dashboard in the system browser; implies `--format html`), `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`), `--recovery`
146
+ **Options:** `--format <table|json|csv|html>`, `--ui` (open the dashboard in the system browser; implies `--format html`), `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`), `--fields <list>`, `--truncate <number>` / `--no-truncate`, `-f, --query-file <path>`, `--use <name[,name]>`, `--recovery`
147
147
  **Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
148
148
 
149
+ #### Field projection (`--fields`)
150
+
151
+ ```bash
152
+ dbcli query "SELECT * FROM bet_log" --fields sn,currency,bet
153
+ dbcli query "SELECT * FROM bet_log" --fields=-raw_response,-created_at # exclusion
154
+ dbcli query '{"station_code":"cmg9998"}' --collection raw_bet_log --fields sn,bet
155
+ ```
156
+
157
+ Include and exclude forms cannot be mixed. Dotted paths (`user.email`) are supported.
158
+ On MongoDB the selection becomes a driver-level `projection` (find) or a trailing
159
+ `$project` stage (aggregate), so the omitted fields never leave the server; `_id` is
160
+ excluded unless listed explicitly. On SQL the rows are projected after fetch — write
161
+ an explicit column list in the `SELECT` when you also want to cut transfer cost.
162
+ Blacklisted columns stay blacklisted: naming one in `--fields` yields no value and the
163
+ result still carries the blacklist `securityNotification`. A requested field that does
164
+ not exist in the result comes back as `null`.
165
+
166
+ #### Cell truncation (`--truncate`)
167
+
168
+ ```bash
169
+ dbcli query "SELECT sn, raw_response FROM bet_log" # table: 120-char default
170
+ dbcli query "SELECT sn, raw_response FROM bet_log" --truncate 40
171
+ dbcli query "SELECT sn, raw_response FROM bet_log" --no-truncate
172
+ ```
173
+
174
+ Table output truncates each serialized cell at 120 Unicode code points by default and
175
+ appends `…(+N chars)`; counting by code point keeps multi-byte characters and emoji
176
+ intact. `--truncate <n>` sets the width, `--no-truncate` disables it. Explicit truncation
177
+ flags are rejected with JSON, CSV, HTML, and `--ui` output.
178
+
179
+ #### Query from a file or stdin (`-f`)
180
+
181
+ ```bash
182
+ dbcli query -f report.sql
183
+ dbcli query --collection raw_bet_log -f - <<'EOF'
184
+ [{"$match": {"sn": {"$regex": "^SN0000"}}}, {"$group": {"_id": "$currency", "n": {"$sum": 1}}}]
185
+ EOF
186
+ ```
187
+
188
+ Avoids shell quoting entirely — the usual reason a Mongo pipeline containing `$regex`
189
+ or nested date objects fails. Supplying both `--query-file` and positional query text
190
+ is an error rather than a silent choice, and an empty file or empty stdin is refused.
191
+ `-f -` requires piped input: on an interactive terminal dbcli refuses immediately
192
+ instead of waiting silently for input that is never coming.
193
+
194
+ #### One-shot connection selection and read-only fan-out
195
+
196
+ Selection precedence is explicit `--use`, then `DBCLI_CONNECTION`, then the saved default.
197
+ `query`, `schema`, `list`, `export`, and `check` accept command-level `--use`; for other
198
+ commands use root-level `dbcli --use <name> <command>`. One-shot selectors never update the
199
+ saved default and require a v2 config. A legacy v1 single-connection config rejects them
200
+ instead of silently running its only connection.
201
+
202
+ An explicit comma-separated `--use primary,staging` fans one query out to several named
203
+ connections. `DBCLI_CONNECTION` always names one literal connection and never enables
204
+ fan-out. SQL permits `SELECT`, `SHOW`, `DESCRIBE`, and `EXPLAIN`; MongoDB permits filters and
205
+ read-only pipelines without top-level `$out` / `$merge`; Elasticsearch permits searches.
206
+ Redis, writes, `--recovery`, `--ui`, CSV, and HTML are rejected before execution. Each
207
+ connection keeps its own blacklist, limit metadata, audit entry, and error. Aggregate exit
208
+ codes are `0` when all succeed, `2` for mixed outcomes, and `1` when all fail or preflight
209
+ rejects the request.
210
+
211
+ #### Truncation is stated, not implied
212
+
213
+ When the query-only auto-limit trims the result, the table footer reads
214
+ `Rows: 1000 (truncated; limit 1000)`, `--format json` carries
215
+ `metadata.truncated` and `metadata.limit_applied`, and CSV appends a `#` comment line.
216
+ dbcli fetches one row past the cap to decide this, so a result of exactly 1000 rows is
217
+ reported as `truncated: false` — never infer truncation from a round row count.
218
+
149
219
  > **MongoDB notes:**
150
220
  > - SQL syntax is rejected — use JSON object (filter) or JSON array (pipeline)
151
221
  > - `--collection <name>` is required
152
- > - Auto-limit does not apply; use `$limit` in your pipeline if needed
222
+ > - Query-only auto-limit applies to filters and to pipelines without their own
223
+ > `$limit`; the applied cap and truncation are reported in the result metadata
153
224
 
154
225
  > **Redis notes:**
155
226
  > - The first token must be an allow-listed command (`GET`/`SET`/`HGET`/`HSET`/`DEL`/...). Unknown commands are refused.
@@ -661,9 +732,13 @@ dbcli export orders --no-limit --format jsonl # scroll the whole ind
661
732
  **Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`, `--collection <name>` (MongoDB collection) / `--index <name>` (Elasticsearch index; alias for `--collection`), `--limit <number>` (overrides auto-limit), `--no-limit` (Elasticsearch full-index scroll)
662
733
  **Permission:** query-only+ — SQL, MongoDB, and **(v1.22)** Elasticsearch.
663
734
 
735
+ If the query-only auto-limit would omit rows, export fails closed with exit code `1` and
736
+ writes no partial file. Re-run with `--no-limit` to export everything, or `--limit N` to
737
+ accept a bounded export explicitly. This applies to SQL, MongoDB, and Elasticsearch.
738
+
664
739
  The `html` format emits the same self-contained dashboard as `query --ui` (see [Interactive HTML dashboard](#interactive-html-dashboard)). Because `export` runs raw SQL (no snippet metadata), the HTML report is always rendered as a sortable / filterable table — no KPIs or charts. Use `dbcli q @<name> --format html` (or `--ui`) for the charted view.
665
740
 
666
- > **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
741
+ > **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; reaching it fails closed unless the caller explicitly uses `--limit N`, while `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
667
742
 
668
743
  ### blacklist
669
744
 
@@ -239,8 +239,10 @@ dbcli init --system elasticsearch \
239
239
  dbcli init --conn-name staging --env-file .env.staging --permission query-only
240
240
  dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
241
241
  dbcli use --list # show all, * marks default
242
- dbcli use prod # switch default
242
+ dbcli use prod # switch default (persists — avoid for one-off queries)
243
243
  dbcli query --use staging "SELECT 1" # one-shot override on any subcommand
244
+ DBCLI_CONNECTION=staging dbcli query "SELECT 1" # one-shot via env; parallel-safe
245
+ dbcli --use staging,prod query "SELECT count(*) FROM users" # read-only fan-out
244
246
  dbcli init --rename staging:stg # rename
245
247
  dbcli init --remove stg # remove
246
248
  ```
@@ -296,7 +298,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
296
298
  | `use` | n/a | Show/switch default named connection (v2 only). |
297
299
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
298
300
  | `schema` | query-only+ | SQL: per-table or full scan into `.dbcli/schemas/`. MongoDB: sampled. ES: flattened mapping. Redis: per-key only (type/TTL/size). Supports `--recovery`. |
299
- | `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard in a browser. Supports `--recovery`. |
301
+ | `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard in a browser. `--fields` (projection), `--truncate` (cell width), `-f/--query-file` (read query from file or stdin), `--use a,b` (read-only fan-out). Supports `--recovery`. See **Query workflow flags**. |
300
302
  | `explain` | query-only+ | **(v1.23)** Read-only query plan with annotations. SQL only. Single query, `@saved-query`, `@file.sql`, or `--bulk @glob/*`. `--analyze` (EXPLAIN ANALYZE / MariaDB ANALYZE SELECT), `--format markdown\|json\|table`. |
301
303
  | `lint` | n/a | Static SQL anti-pattern advisor (no DB connection). 9 rules incl. schema-aware implicit-cast / NOT IN-nullable checks via the layered `.dbcli/schemas/` cache; global `--use <conn>` selects a named cache. Findings carry rewrite drafts + guarded `explain` verify commands (`--analyze` only for proven read-only SQL) — report-only, never executes. `--format text\|json\|markdown`, `--min-severity`, `--no-schema`, `--bulk`. Supports `--recovery`. |
302
304
  | `plan` | n/a | Static SQL risk analyzer (`--format text\|json`); classifies a statement without connecting to the database. |
@@ -304,7 +306,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
304
306
  | `queries` | n/a | Manage saved snippets: `list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`. |
305
307
  | `insert` / `update` | read-write+ | SQL or MongoDB only. JSON `--data` / `--set`; `--where` required on `update`; `--dry-run` first. Redis writes go through `query`. Supports `--recovery`. |
306
308
  | `delete` | data-admin+ | SQL or MongoDB; Redis has a basic implementation (see Redis section). `--where` required; `--dry-run` first. Supports `--recovery`. |
307
- | `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
309
+ | `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. **Fails closed rather than truncating silently**: if the auto-limit would drop rows, the export errors out and you must pass `--no-limit` or `--limit N`. Supports `--recovery`. |
308
310
  | `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
309
311
  | `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
310
312
  | `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`, `--ignore <globs>`, `--format json\|table\|markdown`. Drizzle: point at `drizzle/meta/<NNNN>_snapshot.json` (run `drizzle-kit generate` first; `.ts` sources are rejected with a hint). TypeORM/Sequelize: feed tool-generated DDL (`schema:log` / a schema-only dump); source files are rejected with the exact generation command to run. |
@@ -325,8 +327,9 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
325
327
  | `skill` | n/a | Generate / install AI skill docs (`--install <claude\|gemini\|antigravity\|copilot\|cursor\|codex\|windsurf>`); `skill tasks list/show/plan` for Agent Task Packs; `skill context` for an LLM prompt-context payload (for injecting into another LLM, not needed for normal operation). |
326
328
  | `migrate` | admin | SQL only. **DDL; dry-run by default** — needs `--execute`. |
327
329
 
328
- `--use <name>` on any subcommand (including `status` / `doctor`) targets a v2 connection
329
- without changing the default. `--recovery` is honoured by `query`, `q`, `insert`, `update`,
330
+ Use root-level `dbcli --use <name> <command>` for any command; `query`, `schema`, `list`,
331
+ `export`, and `check` also accept command-level `--use`. Both target a v2 connection without
332
+ changing the default. `--recovery` is honoured by `query`, `q`, `insert`, `update`,
330
333
  `delete`, `export`, `schema`, `inspect`, `lint`, and `diff --against-orm` (see **On failure** above).
331
334
 
332
335
  **Write & query flag semantics** (SQL/Mongo `insert`/`update`):
@@ -344,6 +347,27 @@ without changing the default. `--recovery` is honoured by `query`, `q`, `insert`
344
347
  - `--recovery` is recommended for automated agent pipelines (enables `dbcli recover --apply`
345
348
  after a failure); optional for one-off manual writes.
346
349
 
350
+ ## Query workflow flags
351
+
352
+ These exist so you do not have to pipe output through `head` / `jq` / `python3`
353
+ to make it usable. Reach for them instead of post-processing.
354
+
355
+ | Need | Flag | Notes |
356
+ |------|------|-------|
357
+ | Only some columns | `--fields sn,bet,created_at` | SQL and MongoDB. Mongo pushes a real `projection` / `$project` to the driver; `_id` is dropped unless you ask for it. A field the result lacks comes back as `null`, so verify spellings with `schema` before reading meaning into an all-null column. |
358
+ | Everything except a huge column | `--fields=-raw_response` | Exclusion form. Include and exclude cannot be mixed. |
359
+ | One field is a giant JSON blob | `--truncate 120` | Table output truncates cells at 120 chars **by default** and marks them `…(+3412 chars)`. `--no-truncate` disables it. Explicit truncation flags are rejected on JSON, CSV, HTML, and `--ui` output. |
360
+ | Query has quotes / newlines / `$regex` | `-f pipeline.json` or `-f -` | Reads the query from a file or stdin; use a heredoc for Mongo pipelines. Passing both a file and positional query text is an error, never a silent pick. `-f -` needs piped input — it refuses an interactive terminal rather than hanging. |
361
+ | Same query across connections | `--use hub-prod,site-a` | Read-only fan-out. Per-connection results, one failure does not cancel the others. Exit `0` all-ok, `2` mixed, `1` all-failed. Rejects writes, `--recovery`, `--ui`, CSV/HTML. |
362
+ | Pick a connection for one call | `DBCLI_CONNECTION=hub-prod dbcli query …` | Env var, or `--use` on the subcommand. Priority: `--use` > `DBCLI_CONNECTION` > saved default. Neither writes the default back to disk, so parallel shells never fight. Requires a v2 config — a single-connection (v1) project rejects both rather than silently running its only connection. **Do not** use `dbcli use <name>` just to switch for one query. |
363
+
364
+ **Truncation is reported, never implied.** When the query-only auto-limit trims a
365
+ result, the table footer reads `Rows: 1000 (truncated; limit 1000)`, `--format json`
366
+ carries `metadata.truncated` / `metadata.limit_applied`, and CSV appends a `#`
367
+ comment. `Rows: 1000` with no marker means exactly 1000 rows exist — do not infer
368
+ truncation from a round number. This applies to `query` and to `q` snippets
369
+ (whose own 1000-row guard reports the same way). `export` refuses to truncate at all. Redis replies trimmed by the size guard report the same way, and each size-guard warning is printed on stderr.
370
+
347
371
  ## Permission levels
348
372
 
349
373
  | Level | Allowed |
@@ -112,7 +112,7 @@ dbcli schema --use prod # Scan prod DB; saves to .dbcli/schemas/prod
112
112
 
113
113
  ### query
114
114
 
115
- Execute SQL query (MySQL/PostgreSQL/MariaDB) or JSON filter/pipeline (MongoDB).
115
+ Execute a SQL statement, MongoDB filter/pipeline, allow-listed Redis command, or Elasticsearch DSL/Lucene query.
116
116
 
117
117
  ```bash
118
118
  # SQL databases
@@ -143,13 +143,84 @@ dbcli query "SELECT day, dau FROM dau_daily" --ui # open in brows
143
143
  dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdout
144
144
  ```
145
145
 
146
- **Options:** `--format <table|json|csv|html>`, `--ui` (open the dashboard in the system browser; implies `--format html`), `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`), `--recovery`
146
+ **Options:** `--format <table|json|csv|html>`, `--ui` (open the dashboard in the system browser; implies `--format html`), `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`), `--fields <list>`, `--truncate <number>` / `--no-truncate`, `-f, --query-file <path>`, `--use <name[,name]>`, `--recovery`
147
147
  **Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
148
148
 
149
+ #### Field projection (`--fields`)
150
+
151
+ ```bash
152
+ dbcli query "SELECT * FROM bet_log" --fields sn,currency,bet
153
+ dbcli query "SELECT * FROM bet_log" --fields=-raw_response,-created_at # exclusion
154
+ dbcli query '{"station_code":"cmg9998"}' --collection raw_bet_log --fields sn,bet
155
+ ```
156
+
157
+ Include and exclude forms cannot be mixed. Dotted paths (`user.email`) are supported.
158
+ On MongoDB the selection becomes a driver-level `projection` (find) or a trailing
159
+ `$project` stage (aggregate), so the omitted fields never leave the server; `_id` is
160
+ excluded unless listed explicitly. On SQL the rows are projected after fetch — write
161
+ an explicit column list in the `SELECT` when you also want to cut transfer cost.
162
+ Blacklisted columns stay blacklisted: naming one in `--fields` yields no value and the
163
+ result still carries the blacklist `securityNotification`. A requested field that does
164
+ not exist in the result comes back as `null`.
165
+
166
+ #### Cell truncation (`--truncate`)
167
+
168
+ ```bash
169
+ dbcli query "SELECT sn, raw_response FROM bet_log" # table: 120-char default
170
+ dbcli query "SELECT sn, raw_response FROM bet_log" --truncate 40
171
+ dbcli query "SELECT sn, raw_response FROM bet_log" --no-truncate
172
+ ```
173
+
174
+ Table output truncates each serialized cell at 120 Unicode code points by default and
175
+ appends `…(+N chars)`; counting by code point keeps multi-byte characters and emoji
176
+ intact. `--truncate <n>` sets the width, `--no-truncate` disables it. Explicit truncation
177
+ flags are rejected with JSON, CSV, HTML, and `--ui` output.
178
+
179
+ #### Query from a file or stdin (`-f`)
180
+
181
+ ```bash
182
+ dbcli query -f report.sql
183
+ dbcli query --collection raw_bet_log -f - <<'EOF'
184
+ [{"$match": {"sn": {"$regex": "^SN0000"}}}, {"$group": {"_id": "$currency", "n": {"$sum": 1}}}]
185
+ EOF
186
+ ```
187
+
188
+ Avoids shell quoting entirely — the usual reason a Mongo pipeline containing `$regex`
189
+ or nested date objects fails. Supplying both `--query-file` and positional query text
190
+ is an error rather than a silent choice, and an empty file or empty stdin is refused.
191
+ `-f -` requires piped input: on an interactive terminal dbcli refuses immediately
192
+ instead of waiting silently for input that is never coming.
193
+
194
+ #### One-shot connection selection and read-only fan-out
195
+
196
+ Selection precedence is explicit `--use`, then `DBCLI_CONNECTION`, then the saved default.
197
+ `query`, `schema`, `list`, `export`, and `check` accept command-level `--use`; for other
198
+ commands use root-level `dbcli --use <name> <command>`. One-shot selectors never update the
199
+ saved default and require a v2 config. A legacy v1 single-connection config rejects them
200
+ instead of silently running its only connection.
201
+
202
+ An explicit comma-separated `--use primary,staging` fans one query out to several named
203
+ connections. `DBCLI_CONNECTION` always names one literal connection and never enables
204
+ fan-out. SQL permits `SELECT`, `SHOW`, `DESCRIBE`, and `EXPLAIN`; MongoDB permits filters and
205
+ read-only pipelines without top-level `$out` / `$merge`; Elasticsearch permits searches.
206
+ Redis, writes, `--recovery`, `--ui`, CSV, and HTML are rejected before execution. Each
207
+ connection keeps its own blacklist, limit metadata, audit entry, and error. Aggregate exit
208
+ codes are `0` when all succeed, `2` for mixed outcomes, and `1` when all fail or preflight
209
+ rejects the request.
210
+
211
+ #### Truncation is stated, not implied
212
+
213
+ When the query-only auto-limit trims the result, the table footer reads
214
+ `Rows: 1000 (truncated; limit 1000)`, `--format json` carries
215
+ `metadata.truncated` and `metadata.limit_applied`, and CSV appends a `#` comment line.
216
+ dbcli fetches one row past the cap to decide this, so a result of exactly 1000 rows is
217
+ reported as `truncated: false` — never infer truncation from a round row count.
218
+
149
219
  > **MongoDB notes:**
150
220
  > - SQL syntax is rejected — use JSON object (filter) or JSON array (pipeline)
151
221
  > - `--collection <name>` is required
152
- > - Auto-limit does not apply; use `$limit` in your pipeline if needed
222
+ > - Query-only auto-limit applies to filters and to pipelines without their own
223
+ > `$limit`; the applied cap and truncation are reported in the result metadata
153
224
 
154
225
  > **Redis notes:**
155
226
  > - The first token must be an allow-listed command (`GET`/`SET`/`HGET`/`HSET`/`DEL`/...). Unknown commands are refused.
@@ -661,9 +732,13 @@ dbcli export orders --no-limit --format jsonl # scroll the whole ind
661
732
  **Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`, `--collection <name>` (MongoDB collection) / `--index <name>` (Elasticsearch index; alias for `--collection`), `--limit <number>` (overrides auto-limit), `--no-limit` (Elasticsearch full-index scroll)
662
733
  **Permission:** query-only+ — SQL, MongoDB, and **(v1.22)** Elasticsearch.
663
734
 
735
+ If the query-only auto-limit would omit rows, export fails closed with exit code `1` and
736
+ writes no partial file. Re-run with `--no-limit` to export everything, or `--limit N` to
737
+ accept a bounded export explicitly. This applies to SQL, MongoDB, and Elasticsearch.
738
+
664
739
  The `html` format emits the same self-contained dashboard as `query --ui` (see [Interactive HTML dashboard](#interactive-html-dashboard)). Because `export` runs raw SQL (no snippet metadata), the HTML report is always rendered as a sortable / filterable table — no KPIs or charts. Use `dbcli q @<name> --format html` (or `--ui`) for the charted view.
665
740
 
666
- > **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
741
+ > **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; reaching it fails closed unless the caller explicitly uses `--limit N`, while `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
667
742
 
668
743
  ### blacklist
669
744