Repository navigation
v0.2.0
Pre-release
Pre-release
Two new core tools — fourteen in all — and new modes on seven of the existing ones, plus a
dashboard that lets you delete old keys and a hosted free tier of 1,000 calls per key per day.
Everything is additive: every call that worked on 0.1.0 returns the same shape on 0.2.0.
Added
New tools
financetool (13th core tool):emi(instalment, totals and amortisation schedule that
reconciles to zero),compound(future value with optional per-period contributions and the
effective annual rate),cagr,npv_irr(IRR by bisection),gst(inclusive/exclusive split
into CGST/SGST or IGST, rounding difference reported) andpercent(change vs percentage
points, stacked vs additive discounts, exact bill splits). The rate's period and whether an
amount is GST-inclusive are required, not guessed.colortool (14th core tool):convertbetween hex (3/4/6/8-digit), RGB, HSL, HSV/HSB,
naive CMYK and Lab with alpha preserved;describenames the nearest of the 148 CSS colours
by CIE76 ΔE and words the colour from fixed HSL bands;swatchreturns a real PNG (stdlib
zlib, 16–256 px, one colour or two side by side);contrastgives the WCAG 2.x ratio,
AA/AAA for normal and large text and the smallest lightness change that passes;mix
blends in sRGB or Lab;harmonyrotates hue for complementary, analogous, triadic and
split-complementary sets;nearestsnaps to a caller's palette with the runner-up;
simulateshows deuteranopia, protanopia and tritanopia (Viénot–Brettel–Mollon 1999);
grayscalegreys by rec709, rec601, lab, average or hsl with an optional ramp and strip.
Bare triples such as58, 26, 241are refused withneeds.options(rgb, hsl, hsv).
New modes and parameters
datetimenowtakes a list astz— zone names or{tz, label}objects — and answers with
the shared instant asutcplus one full per-zone entry underzones, each carrying its
labelback.convert_tzaccepts the same{tz, label}entries into_tz. One round-trip
for "what time is it in each of our offices right now"; the single-tzform is unchanged.datetimefree_slots: common free slots for two or more participants in different time
zones, from weekly windows (09:00–17:00onmon…fri) or one-off local ranges, intersected
in UTC throughzoneinfo. Each slot is shown in every participant's local time and in UTC,
per_daytotals the overlap per date, a window spanning a DST change is expanded to its real
length with a note inassumptions, and no common time isok: truewithslots: []and a
warning naming who never overlaps.convertfuel_economy:mpg_us/mpg_uk/km_per_l/l_per_100kmwith exact
constants; a barempgisambiguous(US or imperial gallon), and any conversion that crosses
L/100 km states the inverse relation inassumptions.convertcooking: cups, tbsp, tsp, ml, fl oz ↔ g, kg, oz, lb. Mass ↔ volume needs
ingredient, looked up in a built-in density table (18 staples; the grams-per-cup used are
stated); a missing or unknown ingredient returns the table asneeds.options.cupselects the
US (240 ml, default and declared), metric, UK or Australian (20 ml tablespoon) system.convertsizes:category=shoeconverts US men / US women / UK / EU / cm on a generic
adult chart, snapping to the nearest half size with a warning;category=clothingmaps XS–XXL
to chest and waist cm bands for a chart chosen byregion(usinch-based,euEN 13402-3)
andgender, both required. Every result warns that sizes are approximate and names the chart.numberssemver: compare or sort version strings as versions (1.10>1.9), with
SemVer 2.0 pre-release precedence, build metadata carried but ignored for ordering, and a
leadingv/ missing minor or patch tolerated and recorded inassumptions.textsimilarity: Levenshtein distance and a 0–1 ratio for a pair, ortext+itemsto
rank candidates and return the best match with its index — mapping typed input onto a menu,
spotting near-duplicate names. Case-folded and whitespace-normalised by default, both stated.collections: every record input (items,a/b,data) also accepts CSV text — the
delimiter is sniffed, the header row detected (first row with no numeric, date or boolean cell;
has_headeroverrides), each field typed as number (exactDecimal, vianumbers.parse),
ISO date, boolean or text, and blank rows andN/A/-/nullcells skipped and counted, all
stated inassumptions; above 5,000 rows the call is refused. New table modes over the same
input:filter(wherepredicates with thevalidate.assertvocabulary, compared in the
field's type),pivot(by×pivot_columns, one aggregate ofcolumn, row and grand
totals, empty cellsnull),running(cumulative total, restarting perby),outliers
(Tukey hinges, 1.5×IQR, fences reported, at least 4 values),summarize(count/nulls/sum/avg/
min/max/median for every numeric field, distinct counts for text, range for dates) andto_csv
(delimiter, chosencolumns). A lone numeric field is assumed forrunning/outliersand
said so; several areambiguous.decimalsrounds computed values only; row-shaped results
echo at most 500 rows with a warning, exceptto_csv.validatecidr: membership (network+value→contains, for an address or a smaller
block) and overlap (a list of networks → every pair withequal/a_contains_b/
b_contains_a/disjoint), plus a block's size, usable hosts, bounds and masks. Host bits
set are read as the network and recorded inassumptions.validateidwithkind=isbnreturns bothisbn10andisbn13for a valid number (a 979
book has no ISBN-10 form).encodehashandchecksumtakeexpectedand answermatches— compared in constant
time against the hex, Base64 (or, for checksums, decimal) form, case- and whitespace-
insensitive, with asha256sum-style<digest> <file>line accepted as-is. A mismatch is
ok: true, matches: false: an answer, not an error.hmacshares the same comparison.filesfile_hash: sha256 (default) / sha1 / md5 / blake2b / crc32 and the other hashlib
algorithms, streamed in 1 MiB chunks so a file's size is bounded only byLEFTBRAIN_FILE_ROOTS,
withbytes, the algorithm used, andexpected→matchesfor verifying a download.
Keys and dashboard
leftbrain-keys set --all --daily N [--rpm N] [--from-daily N]changes limits on every key —
or, with--from-daily, only on keys still at an old default — so a moved default can be
migrated without a database shell or touching keys set by hand. Prints how many keys changed.- Dashboard Delete for a revoked or expired key: removes the row and its usage history for
good (with a confirm). A key that still works must be revoked first; deletion is owner- and
CSRF-checked like the other key routes.
Fixed
- Dashboard: keys issued before the server could show keys again (including the old
POST /keys/signuprows, still namedself-serve signup) are marked legacy and explained
on the row instead of the bare "created before reveal was enabled". They no longer hold one of
the owner's active-key slots, so a first sign-in that inherits three of them can still create a
key./keys/meoutput is unchanged. - Demo endpoint: the 8 KB body cap now applies to chunked requests too, and deeply nested arguments return a contract
invalid_inputinstead of a bare 500. - Docker image build failed after the changelog was bundled into the wheel (
CHANGELOG.mdwas not copied into the image).
Changed
- Free tier is 1,000 calls per key per day (was 5,000);
LEFTBRAIN_DEFAULT_DAILY_QUOTAstill overrides it. Every place the site quotes the limit — landing, sign-in, quickstart, the demo's 429 — now reads the configured value instead of a hard-coded number. - Site shows loading skeletons on navigation, form submits and demo runs; the colour legend on docs pages was dropped.
- Docs key picker shows the key name only (prefix only for unnamed keys).
- Docs examples are labelled Request/Response and colour-coded: blue blocks are what you
send, green blocks are what comes back, and a neutral block marks a setup command.