Changelog
Every release of caique, newest first, from its CHANGELOG.md — what changed and the pull request it came from.
2.1.1
Patch Changes
- #1564
593c0b4Thanks @ofri-peretz! - Measures withlinegauge/v8, string-width 8.3.0's rules, which every incumbent these packages replace still resolves. Nothing a box, table, spinner, prompt, ink screen or help page draws changes:linegauge's root moved to string-width 9.0.0, and these stay on the measurement theirwrapandslicecut by. - Updated dependencies [
593c0b4]:- linegauge@2.2.0
2.1.0
Minor Changes
-
#1548
f190400Thanks @ofri-peretz! -caique/clackfollows@clack/prompts1.9.0 (23 / 23, control 23 / 23). The spinner gains an accessible mode, turned on byaccessible: true, byupdateSettings({ accessible: true })or byACCESSIBLEin the environment. In that mode it prints plain appended lines a screen reader can follow, with no glyph, guide bar or escape:- the start;
still working: <message>every 30 s;- the ending, or
Done,Canceledor the error message when the ending names none.
caique/inquirerfollows@inquirer/prompts8.8.0 (228 / 228) and@inquirer/core12.1.0 (47 / 47):numbercallsvalidatewithundefinedwhen an optional prompt is left empty.selecttakes an index only from plain digits, so2e1is not choice 20.rawlisttakes one only from digits with whitespace around them, so2xis refused.makeThemekeeps the default for a key set toundefined.
Patch Changes
- Updated dependencies [
f190400]:- linegauge@2.1.0
2.0.0
Major Changes
- #1491
5054fb7Thanks @ofri-peretz! - Requires Node 22.13 or later; Node 18 and 20 are end-of-life.engines.nodeis now>=22.13.0(was^20.19.0 || >=22.13.0), and Node 22.13, 24 and 26 are the versions tested.burgee migratenow warns when a project'sengines.nodeadmits a Node below 22.13.0, and its suggested fix isnpm pkg set "engines.node=>=22.13.0".
Patch Changes
-
#1535
bad28b6Thanks @ofri-peretz! -caique/clackpaints its list hints and its required refusal when it draws them, and nests colours the same way on every Node.- The
↑/↓ to navigatehints underselectandmultiselect, and the refusal a required multi-selection shows ("Please select at least one option. Press space to select…"), were painted once, when the module loaded. They took whatever colour support the process had then, not the stream's when the prompt drew, so a prompt in a terminal could show them uncoloured. They are now painted per frame, as clack paints them. - On Node 22.13, an inner colour closing inside an outer one ended the outer one too: the yellow refusal lost its colour after
space. Node 24 reopens the outer colour there, as picocolors does for clack;caique/clacknow does the same on every Node it supports.
- The
-
Updated dependencies [
fca94b2,5054fb7]:- linegauge@2.0.0
- bellpull@2.0.0
- closeout@2.0.0
- paratext@2.0.0
- roundel@2.0.0
1.6.3
Patch Changes
- #1483
3e69fb2Thanks @ofri-peretz! - The package manifest names its author and publishes withpublishConfig{ "access": "public", "provenance": true }. burgee'shomepageis its landing page, https://burgee.interlace.tools. oxmutate gainskeywords, so npm search finds it, and asideEffectslist (its CLI, its worker and its Vitest runner run on load), so a bundler can drop the rest. No code changes. - Updated dependencies [
3e69fb2]:- bellpull@1.0.11
- closeout@1.1.10
- linegauge@1.2.1
- paratext@1.0.13
- roundel@1.3.2
1.6.2
Patch Changes
-
#1469
80fa4fbThanks @ofri-peretz! - Two fixes.- An autocomplete search whose first match is disabled no longer overflows the stack. The cursor search stepped by
Math.sign(0)from a disabled option, which is the same option again; it now searches forward, as upstream does, and lands on the next enabled match. - Line-mode
selectandmultiselectread only an all-digits answer as a number.parseIntread1 2as choice 1,2xas choice 2, and a label typed out, such as3 apples, as choice 3. Those are now refused, and a label that starts with a digit is matched as that label.
- An autocomplete search whose first match is disabled no longer overflows the stack. The cursor search stepped by
-
Updated dependencies [
80fa4fb]:- closeout@1.1.9
1.6.1
Patch Changes
- #1337
9bf2624Thanks @ofri-peretz! -caique/inquirerfollows@inquirer/core12.0.6 andcaique/inquirer/promptsfollows@inquirer/prompts8.7.5. The first render waits a tick only when the input is a terminal, so an answer already piped into a non-TTY stdin before the prompt starts is read instead of dropped.passwordkeeps the space after its message while the mask has nothing to draw, so the cursor sits past it. Their own suites grade them 46 / 46 and 222 / 222, level with the incumbents.
1.6.0
Minor Changes
-
#1316
d565864Thanks @ofri-peretz! -promptForasks for a command's missing option or positional, and refuses when nobody can answer (R1).import { promptFor } from 'caique/prompt-for'.promptFor(command, 'name', { kind: 'text', message: 'Who?' })wraps a command so its handler never sees a missing value. A person at a terminal is asked, on stderr, so the question never lands in the command's data. With no terminal, underCI, under a detected agent, under--jsonor in an--mcptool call, it refuses withUSAGE, naming how to pass the value:<name>for a positional,--dry-runfor adryRunoption. A cancelled question isCANCELLED. burgee leaves with exit 2 or 4.promptFor(command)resolves theprompt:a command already declares on its options or arguments. The command's shape is read structurally, and nothing in caique imports burgee.- The terminal is opened only to ask, handed to the host's exit path while it is open, and closed before the handler runs. Ctrl+C at the question gives the terminal back out of raw mode, on Linux, macOS and Windows.
- A declared prompt is left out of the command's JSON, so
--schemadoes not grow. caique/clack'sspinner({ style })takes a spinner style as data, such as flagstaff'slookupSpinner(name)or a plugin'sspinnersentry. On a terminal its frames turn at its interval. Anywhere else itsstaticline is printed in place of the first frame.decide()andresolvePrompts()take aflag, which is how a refusal names an option when--<option>is not how it is passed.
1.5.2
Patch Changes
- #1285
6570ff2Thanks @ofri-peretz! -caique/inquirerfollows@inquirer/core12.0.5 andcaique/inquirer/promptsfollows@inquirer/prompts8.7.4. A prompt cancelled or aborted before its first render never draws it and leaves no listener on the input.checkboxshows its loading state while an asyncvalidateruns and ignores every key until it answers.numberreads a line of only whitespace as empty: the default, or a refusal underrequired. Their own suites grade them 45 / 45 and 221 / 221, level with the incumbents.
1.5.1
Patch Changes
-
#1258
e3b3a41Thanks @ofri-peretz! -checkreads a.jsonplugin file as data. It handed every file toimport(), and Node refuses a.jsonmodule without an import attribute (ERR_IMPORT_ATTRIBUTE_MISSING), so a plugin written as JSON got Node's message and no verdict, from the host's owncheckand throughburgee check, which runs it. -
#1266
02e6f9fThanks @ofri-peretz! - The family plugin schema (schema.json, identical in every plugin host) now describesformats, burgee's output-format key. This package reads nothing new, and a plugin carryingformatsregisters here as before. -
#1252
efc994eThanks @ofri-peretz! - Every benchmark figure in the README, a ratio, a byte count or a cold-start time, now links to the benchmarks page where it is measured. -
Updated dependencies [
e3b3a41,02e6f9f,efc994e,efc994e]:- bellpull@1.0.10
- closeout@1.1.8
- linegauge@1.1.5
- paratext@1.0.11
- roundel@1.2.1
1.5.0
Minor Changes
- #1201
70a86aaThanks @ofri-peretz! -caique/inquirer/promptsnow carries all ten of@inquirer/prompts' prompts:input,confirm,password,number,expand,rawlist,searchandeditorjoinselectandcheckbox, with their config and theme types.@inquirer/prompts8.7.3's own suites pass 213 / 213, level with@inquirer/promptsitself (the eleveneditorcases that answer through a mock of@inquirer/external-editorare excluded for both sides, D-20261011-inquirer-prompts-editor-mock). The subpath bundles to 44,683 B against the incumbent's 582,754 B.editorstarts the user's editor throughbellpull/cross-spawn, so caique now depends onbellpull.
1.4.5
Patch Changes
- #1186
af24328Thanks @ofri-peretz! - Published declarations now keep each doc comment's first paragraph, its code examples and its@param,@returns,@throws,@example,@deprecated,@defaultand@seetags, and drop the longer design notes below them, so the tarballs are smaller (burgee by 5.7% gzipped, bellpull and closeout by about a fifth). Types are unchanged, and hover text in an editor keeps its summary.burgee's README also namesburgee/program-schema.json, the JSON Schema every--schemadocument validates against. - Updated dependencies [
af24328,122635d]:- closeout@1.1.6
- linegauge@1.1.4
- paratext@1.0.10
- roundel@1.2.0
1.4.4
Patch Changes
- #1160
0b381a0Thanks @ofri-peretz! - Export./package.json.require('<package>/package.json')threwERR_PACKAGE_PATH_NOT_EXPORTED, which broke tools that read a dependency's manifest that way: bundlers, license scanners and version checks. - Updated dependencies [
0b381a0]:- closeout@1.1.5
- linegauge@1.1.3
- paratext@1.0.9
- roundel@1.1.3
1.4.3
Patch Changes
- #1141
711ba15Thanks @ofri-peretz! -caique/clack: a throw from the prompt's own code — arender,onKeyorfinalizethat throws, on a key, on an abort, or on the first frame — now rejects the prompt's promise with that error, after turning raw mode off, removing the keypress listener and showing the cursor again. From a key it used to escape the keypress listener as an unhandledRejection, which kills a Node process by default, and left the prompt unsettled with raw mode on; from an abort it was an uncaught exception; from the first frame the promise rejected but left raw mode on and the keypress listener attached. A validator that throws is still a failed check, as before.
1.4.2
Patch Changes
- #1130
c05c86eThanks @ofri-peretz! - Every drop-in subpath now type-checks undermoduleResolution: node10, and undermodule: commonjswith no resolution set, which is TypeScript's default there.import … from 'burgee/commander'used to fail with TS2307 in such a project, althoughrequire()of the same specifier worked. Each package now declarestypesand atypesVersionsmap, derived fromexports, with one key per typed subpath pointing at the fileexportsalready names.exportsis unchanged, sonode16,nodenextandbundlerread exactly what they read before.controlroom/ink's declarations no longer name the untypedreact-reconciler, which was TS7016 for consumers withskipLibCheck: false. - Updated dependencies [
c05c86e]:- closeout@1.1.4
- linegauge@1.1.2
- paratext@1.0.8
- roundel@1.1.2
1.4.1
Patch Changes
- #1097
3f96896Thanks @ofri-peretz! -caique/clack: a validator that throws, or returns a promise that rejects — a network check that fails, say — is now a failed check: the prompt shows the error's message (or themessages.errorsetting when it has none) and stays open, so the person can retry or cancel. It used to escape the keypress listener as an unhandledRejection, which kills a Node process by default; after an abort it escaped from a prompt that had already answered.@clack/core1.5.1 lets it escape the same way.
1.4.0
Minor Changes
- #1095
98a0004Thanks @ofri-peretz! - A list prompt never outgrows the terminal. The rawselectandmultiselectdraw a list longer than the screen as a window that follows the cursor, with↑ N moreand↓ N morerows for what is outside it, so a repaint never climbs above the top row. The window is the newmaxItemson a prompt spec, clack's name for it, and never more than the terminal's rows less three.renderListtakesmaxItems, and the terminalWriterreportsrows, read live.
1.3.0
Minor Changes
- #1037
50cc502Thanks @ofri-peretz! - New entry pointcaique/inquirer/prompts:@inquirer/prompts'selectandcheckbox, withSeparatorand their config, theme and choice types, overcaique/inquirer's prompt loop. Both are graded by their own suites in@inquirer/prompts8.7.3,select's pagination suite included: 100 of those 100 cases pass, level with the real packages. Paging follows@inquirer/core'susePagination, multi-line choices andloop: falseincluded. The other eight prompts are not built yet, soburgee migratedoes not rewrite@inquirer/promptsimports.caique/inquireris unchanged, and a program that imports it loads none of this.
1.2.1
Patch Changes
- #1068
566b7d7Thanks @ofri-peretz! -caique/clack: Ctrl-C or escape while an async validator is still out now cancels the prompt (it answersCANCEL_SYMBOL), where it used to be dropped. In raw mode Ctrl-C reaches the prompt as a byte, not a signal, so a validator that never answered left no way out.@clack/coredrops the key too, but its readline interface then leaves raw mode, so a second Ctrl-C kills the process. Other keys still wait for the verdict. - Updated dependencies [
4a62884]:- paratext@1.0.7
1.2.0
Minor Changes
-
#1060
52f6c71Thanks @ofri-peretz! ---quietreachescaique/clack's decoration. Every clack call's options take an optionalruntime(roundel's policyRuntime, which is burgee'sctx.runtime). When it saysquiet,spinner,tasks,intro,outro,noteandlog.message,info,step,successandwarnwrite nothing, and the spinner arms no interval; their lifecycle methods still run.log.errorandcancelstill write, and prompts ignorequiet. A call without aruntimebehaves exactly as before, and quiet is never read from argv or the environment.isCI()takes an optional runtime to readCIfrom.burgee's README shows the call under For agents:
spinner({ runtime: ctx.runtime }).
Patch Changes
- Updated dependencies [
1797388]:- closeout@1.1.3
1.1.0
Minor Changes
-
#1045
c4fd9a3Thanks @ofri-peretz! - caique's own chrome can speak the user's language. That covers the instruction under a list, a problem with an answer, the giving-up line, and the no-terminal and cancel refusals. A locale pack registered withregister()carries translations under ids that begincaique., so one object can serve burgee's catalog too. The newcaique/localeentry turns the runtime'slocaleinto the translator:io.say = sayFor(runtime.locale).askandresolvePromptsapply it. Neither reads the catalog itself, and caique never readsLANG. A refusal keeps its Englishmessageandfix, which a host may put in a machine envelope, and addslocalisedbeside them.caique checkrenders a pack's messages, or refuses an unknown id, a stray placeholder or a missing plural form withE_PLUGIN_SCHEMA. With nosayhanded in, every byte is unchanged, andcaique/clackandcaique/inquirerkeep their incumbents' English.burgee: the family plugin schema it publishes describes the
localeskey.
Patch Changes
- #1045
c4fd9a3Thanks @ofri-peretz! - The family plugin schema (schema.json, identical in every plugin host) now describeslocales, burgee's locale-pack key. A plugin carryinglocalesvalidates against the shared schema as it does againstburgee/locale-pack-schema.json, which lists every message id. This package reads nothing new, and a plugin carryinglocalesregisters here as before. - Updated dependencies [
c4fd9a3]:- closeout@1.1.2
- linegauge@1.1.1
- paratext@1.0.6
- roundel@1.1.1
1.0.5
Patch Changes
-
#1012
49d8e94Thanks @ofri-peretz! -@inquirer/promptsis now graded: its ten prompts' own suites (8.7.3) are vendored and run againstcaique/inquirer, with a control of 213 of 213 against the real packages.caique/inquirerpasses 0 of them today, because it exports@inquirer/core's surface and none of the prompts yet, andburgee migratereports@inquirer/promptsas a graded path that is not level, never rewriting it. The eleven@inquirer/editorcases are excluded by title: each answers the prompt through a mock of@inquirer/external-editor, which caique does not import.The oracle gains two host fields for it.
suiteFileslists a monorepo suite's files across several packages and vendors only those;defaultExportgrades a suite that imports its prompt as a default against the named export a program migrates. -
#1022
ecb0a00Thanks @ofri-peretz! - The tarball no longer carries declaration files that noexportsentry reaches. TypeScript could never open them, because a deep import is refused byexports. Every entry's types are unchanged. The ten packages drop 71 files and 118,312 bytes between them, burgee 35 files and 76,504 bytes, which takes its tarball from 251,814 to 225,278 bytes gzipped. -
Updated dependencies [
bfe4ab8,1968eb4,65afee5,bcc438a,ecb0a00]:- linegauge@1.1.0
- paratext@1.0.5
- roundel@1.1.0
- closeout@1.1.1
1.0.4
Patch Changes
- #938
9babb6dThanks @ofri-peretz! - npm description and README: the description says what the package does, then its dependency fact in one of two wordings ("Zero dependencies." or "No dependency outside the burgee family."), then its drop-in paths. The README's family section states how the family is built — the leaves, one-way dependencies, nothing from outside the family, trusted publishing with provenance — and its table column is "Migrates from". No API, compatibility grade or benchmark changes. - Updated dependencies [
9babb6d]:- closeout@1.0.4
- linegauge@1.0.8
- paratext@1.0.4
- roundel@1.0.4
1.0.3
Patch Changes
- #917
735f0f6Thanks @ofri-peretz! - README: the opening paragraph says what the package does first. The drop-in path follows it as one line, naming the incumbent andnpx burgee migrate, and every compatibility row and benchmark is unchanged. - Updated dependencies [
735f0f6]:- closeout@1.0.3
- linegauge@1.0.7
- paratext@1.0.3
- roundel@1.0.3
1.0.2
Patch Changes
- #897
f29f159Thanks @ofri-peretz! - controlroom has its own docs site at https://controlroom.interlace.tools: its README's Docs line, itshomepage, and every family table now link there. - Updated dependencies [
f29f159]:- closeout@1.0.2
- linegauge@1.0.6
- paratext@1.0.2
- roundel@1.0.2
1.0.1
Patch Changes
- #886
d33ae03Thanks @ofri-peretz! - The README and docs index say caique is 1.0, not "Released, pre-1.0.": it shipped 1.0.0 on 2026-10-08.
1.0.0
Major Changes
- #851
446a691Thanks @ofri-peretz! - caique 1.0.0. The spec is fully built,caique/clack(16 / 16) andcaique/inquirer(41 / 41) pass their incumbents' own suites at the latest release, level with the incumbents, and coverage is 100% on all four measures (D-20261007-caique-controlroom-1-0-evidence). The published entries, the pluginschema.jsonand thecaiquebin become a semver contract. No API changed in this release.
Patch Changes
-
#857
d80b2d0Thanks @ofri-peretz! -caique checkrefuses a widget whosestaticthrows on its ownsample. It used to print the throw as a row, then<name>: ok, and exit 0. Now each throwing widget is anE_NO_STATIC_PROJECTIONrefusal that names the widget and what it threw, with afix, and the command exits 1 without printingok. -
#848
6ae533eThanks @ofri-peretz! - The familyschema.jsondescribes what five values look like.contractis1, and burgee refuses a plugin that declares none. A caique widget'sstatic(spec)gets{ kind, message, ...sample.done }. A seniorityranksits between the built-in layers at flag 0, environment 10, config file 20,package.json30 and default 40. A burgee hook'sfilteris{ command: RegExp }, now withcommandrequired, so the schema and the host refuse the same filters. -
#857
d80b2d0Thanks @ofri-peretz! - The familyschema.jsoncloses a bellpull resolver'swhenwithadditionalProperties: false, so the schema and bellpull's own validation refuse the same unknown keys. -
#848
6ae533eThanks @ofri-peretz! - Each README now shows a whole plugin as a default export, the command that checks it (from an install, and from a clone wheredist/has to be built first), and the reportcheckprints when the plugin passes. caique says what a widget'sstatic(spec)receives. seniority gives therankfor each slot between the built-in layers. bellpull says that{VAR}is the only substitution a path gets. -
Updated dependencies [
6ae533e,d80b2d0]:- closeout@1.0.1
- linegauge@1.0.5
- paratext@1.0.1
- roundel@1.0.1
0.7.2
Patch Changes
- Updated dependencies [
1945d65,1945d65,9ebef65,1945d65]:- closeout@1.0.0
- paratext@1.0.0
- roundel@1.0.0
0.7.1
Patch Changes
-
#810
a47209bThanks @ofri-peretz! -caique/terminal:createIo()'s reader no longer drops lines that arrive before a question is asked. It listened for onelineevent perline()call, soprintf 'x\ny\n' | clilost both answers andask()read the missing line as a cancellation. Lines are now queued from a single listener and handed out in order, before the end of the stream is. -
#816
5230016Thanks @ofri-peretz! - controlroom hosts plugins (R10):keymapsandpanesregister throughcontrolroom/plugin'sregister()against the family schema, a screen takes either by name, andcontrolroom check <plugin-file>reports what a plugin contributes. The family schema every host ships gains thekeymapsandpanesdefinitions. -
Updated dependencies [
5230016,5230016,5230016]:- closeout@0.7.0
- paratext@0.9.0
- linegauge@1.0.4
- roundel@0.6.3
0.7.0
Minor Changes
-
#801
81fc994Thanks @ofri-peretz! -caique/editor: the line editor as a component a host drives (editor()returnsinitial, anonKeyreducer andrender), with multi-line entry, history, bracketed paste treated as text, and a completion menu the program feeds. Its commands are acaique/keyskeymap (EDITOR_KEYS). Off a terminal,submissions(stdin)yields one entry per line and ends when the input does. The editing itself moved into a modulecaique/clack's prompts share, so there is one line editor in the package. -
#801
81fc994Thanks @ofri-peretz! -caique/keys: key presses decoded throughnode:readline's keypress events into oneKeyPressshape, keymaps as plain data (match(),bindings()), andreadKeys(), which takes raw mode once throughcloseout/cursorand throwsE_NOT_A_TERMINALwith afixinstead of waiting when stdin is not a terminal.caique/raw'skeyOfis rebuilt on the same decoder, and now reads the application-mode arrows (ESC O A) a terminal can send.
0.6.4
Patch Changes
0.6.3
Patch Changes
-
#764
1817b62Thanks @ofri-peretz! -caique/clacknow grades 16 / 16 against@clack/prompts1.8.1's own suite, level with clack itself at 16 / 16. It was 16 / 17. The pass count did not change. The denominator did: one case,guide.test.ts'sno prompt renders a guide when withGuide is globally false, is now excluded by its exact title. It importsupdateSettingsfrom@clack/coreand asserts that the prompts read that package's module state, so it grades@clack/coreand not@clack/prompts(D-20260930-caique-clack-core-exclusion). The exclusion and its reason are on the compatibility page.Because the row is level,
burgee migratenow rewrites@clack/promptstocaique/clack. It refuses a file that importsbox,progressortaskLog, whichcaique/clackdoes not build, and leaves that file on clack. It does not rewrite@clack/core. So a migrated program that importsupdateSettingsfrom@clack/coreis still changing clack's settings, and caique's prompts never read them. ImportupdateSettingsfromcaique/clackinstead. -
Updated dependencies [
6c2e9c5,6c2e9c5]:- linegauge@1.0.1
- paratext@0.7.5
0.6.2
Patch Changes
- Updated dependencies [
a115799]:- roundel@0.6.0
0.6.1
Patch Changes
- #752
22e6daeThanks @ofri-peretz! - A plugin that declarescontract: 0or a negative contract is now refused withE_PLUGIN_CONTRACT, asschema.json's minimum of 1 always said. These hosts checked only that a contract was not newer than the one they know, so 0 and below registered. - Updated dependencies [
12bac9c,22e6dae]:- paratext@0.7.4
- closeout@0.6.1
- roundel@0.5.6
0.6.0
Minor Changes
- #638
e4c1f69Thanks @ofri-peretz! -caique/clacknow carries@clack/prompts' prompts, not onlylimitOptions:text,password,confirm,multiline,date,path,select,selectKey,multiselect,groupMultiselect,autocompleteandautocompleteMultiselect, withintro,outro,cancel,note,log,stream,spinner,tasks,group, theS_*glyphs,settings/updateSettingsandisCancel, under clack's names and options. They run on caique's own keypress loop and reach nothing outside this repository. Graded by clack's own suite at 16 / 17 (was 14 / 17; the control is 17 / 17): the one case left importsupdateSettingsfrom@clack/core, which caique does not depend on (D-152). The spinner animates only on a terminal outside CI and prints each message once anywhere else.box,progressandtaskLogare not built.burgee migratereports the new grade and, since it is not level with the control, still does not rewrite@clack/prompts.
Patch Changes
-
#708
b52659fThanks @ofri-peretz! -caique/clack: a prompt's raw mode goes throughcloseout/cursor'srawMode, ascaique/rawalready does. A prompt on a stream that was already raw no longer switches raw mode off when it ends, and raw mode it did turn on is also turned off onSIGINTandSIGTERM.caique/clackstill grades 16 / 17 against clack's suite. -
#726
2c631cbThanks @ofri-peretz! - Two fixes incaique/clack, and paths no input could reach are removed. A prompt aborted while its validator was still running drew one more frame after it had closed and given the cursor back, so the frame landed under whatever the program wrote next; it now writes nothing once closed.datetook a locale's field separator from its first literal, which in Pashto is the space after the era, so the fields readyyyy mm ddrather thanyyyy-mm-dd; it now takes the literal after the first field, which is also right where the last literal is a suffix, as in Bulgarian'sг..caique/raw'saskList, called directly with no choices, answered a multiselect with['']after a space; it now answers[]. The fallbacks removed fromclack-core,clack-date,clack-prompts,clack-search,raw,bindingandterminalare for values that are always there; behaviour is otherwise unchanged. -
#727
b9de3f3Thanks @ofri-peretz! - Four checks that could never change a result are removed fromcaique/inquirer; behaviour is unchanged. The screen's last line no longer falls back to an empty string (splitting a string always yields one), the loader no longer defaults a tick thatuseState(0)always sets,INQUIRER_KEYBINDINGS=''no longer has its own early return (it already parses to no bindings), anduseMemono longer asks whether a slot that holds a value was initialised. -
#728
9a65722Thanks @ofri-peretz! -caique/clack'sspinnernow ends on itserrorMessagewhen the process exits with a failing code the program chose (2–127), as clack's does; before this every exit while spinning ended as a cancel, anderrorMessagewas never shown. A signal, and exit codes 0 and 1, still end as a cancel. Unreachable code is removed from the spinner and fromcaique check, whose never-called "replaces" helper is gone; behaviour is otherwise unchanged. -
#680
7f59bc2Thanks @ofri-peretz! - Raw mode is paired with its undo throughcloseout/cursor'srawMode, the way the cursor already was.caique/raw: a list prompt on a stream that was already in raw mode — a prompt library's, or the program's own — no longer switches raw mode off when it ends; it used to callsetRawMode(false)unconditionally and take the keyboard from its owner. Raw mode the prompt did turn on is now turned off onSIGINTandSIGTERMtoo, not only in the prompt's ownfinally.KeyStreamgains an optionalisRaw.flagstaff/ora: stdin-discarder's raw mode goes through the same pairing. Behaviour is unchanged except that an already-raw stdin is no longer written to at all.
-
#677
8bc14e6Thanks @ofri-peretz! - Measuring text against a terminal is linegauge's job, and four places did it by hand.caique/raw: the repaint counted a frame's rows withsplit('\n')and ignored wrapping, so a choice whose hint was wider than the terminal left a stale copy of the question on screen after every keypress. It counts rows with linegauge'slineCountagainst the terminal's width, whichWriternow carries as an optionalcolumns(read through to the output stream bycreateIo). A writer without one is treated as never wrapping, as before.burgee/testing:stripAnsiis linegauge'sstrip. The regex it used left private modes (ESC[?25l), the colon form of a truecolor SGR (ESC[38:2::255:0:0m) and OSC 8 hyperlinks in the text.burgeehelp: descriptions and epilogues are folded bylinegauge/wraprather than a loop of help's own. A styled description now opens and closes its styles on each row instead of running its colour into the next row's indent, and a run of spaces at a break no longer leaves trailing whitespace. Lines the author indented are still kept verbatim, and a word wider than the row still overflows rather than breaking.burgeeconfig explain: the option column is padded in terminal columns, so a CJK option name no longer pushes its value two columns right of the others.
-
#674
e9f45d8Thanks @ofri-peretz! - README: family header, badges, install, migrating, the family table.Every package README now opens the same way — lockup, tagline, one badge row in one order (npm version, downloads, Quality Gate, the package's own coverage, OpenSSF Scorecard, unpacked size, dependencies, types, Node, licence, npm provenance), a row of compatibility badges read from the graded baseline — and carries the same sections in the same order: Install for npm, pnpm, yarn and bun, Quick start, Migrating as a before/after diff, Compatibility, Benchmarks, For agents, API, and a generated table of the nine packages. Links are absolute, so they work on npm as well as GitHub.
-
#684
6c7b55aThanks @ofri-peretz! -paratext/csi: the CSI half ofansi-escapesas a subpath of its own — cursor moves, erases, scrolling, the alternate screen and synchronized output, byte-exact withansi-escapes7.3.0. It is 2,700 bytes and, unlike the package root, registers no built-ins when imported.flagstaff/log-update,flagstaff/ora,caique/rawandcaique/inquirertake their cursor sequences from it instead of carrying their own copies; caique now depends on paratext. Output is unchanged, with one spelling difference:caique/raw's repaint clears withESC[Jrather than the equivalentESC[0J.caique/inquirerkeeps@inquirer/ansi's answer of nothing for a zero-row move, whereansi-escapes'cursorUp(0)isESC[0A. -
#678
088ceccThanks @ofri-peretz! - Whether anybody is there, whether to colour, and whether a tick can be drawn are roundel's questions, and three packages answered them by hand.roundel/terminal(new subpath, 878 B, reaching nothing):interactive(rt)— a terminal on stdin, noCI, and no agent variable (CLAUDECODE,AI_AGENT,CURSOR_AGENT,CODEX_THREAD_ID,GEMINI_CLI, exported asAGENTS), withFORCE_TTY=1as the override — andunicode(rt), is-unicode-supported 2.1.0's table over{ env, platform }.caique/decidenow depends onroundeland asksinteractive(). Behaviour change: under an agent that has a terminal —CLAUDECODE=1and a TTY on stdin — a missing required value is refused with a usage error naming the flag (--x is required when nobody is there to answer) instead of prompting and hanging the agent.FORCE_TTY=1now prompts even without a terminal on stdin, as it does for burgee.caique/inquirer's tick andflagstaff/ora's log symbols and spinner fallback use roundel'sunicode(). caique's copy was a four-condition subset: the Linux console (TERM=linux) now gets√rather than✔, and ConEmu/Cmder, Terminus, Alacritty, rxvt-unicode and JetBrains' terminal on Windows now get✔, asfiguresdraws them.burgeehelp colour is roundel'scolorLevel(rt) > 0. Behaviour changes:NO_COLORnow beatsFORCE_COLOR;--no-colorand--color=…on the command line are honoured;CLI_ACCESSIBLEturns help colour off; and a terminal that sets noTERM(Windows' conhost) gets plain help unlessFORCE_COLOR,--colororCOLORTERMasks for colour.burgee/contrastrounds with roundel'sround2; no output changes.paratext: the supports-color fork behindparatext/terminal-linkis unchanged, and now held to roundel's policy by a parity test everywhere their two incumbents agree.
-
Updated dependencies [
6d8aadf,ff4159d,5e635b0,ff4159d,6ef8227,7c77cd2,6ef8227,6ef8227,e9f45d8,8a338ba,6c7b55a,620fc74,088cecc,4319563]:- closeout@0.6.0
- linegauge@1.0.0
- paratext@0.7.3
- roundel@0.5.5
0.5.4
Patch Changes
-
#627
4a629a9Thanks @ofri-peretz! - Lint with every published Interlace ESLint plugin, and fix what the upgrade surfaced.- caique: the inquirer theme merge skips
__proto__,constructorandprototypekeys, so a theme object cannot swap the merged object's prototype. - burgee: last-element reads use
.at(-1). - burgee, closeout, flagstaff, roundel: helpers that capture nothing from their enclosing function move to module scope.
- seniority: suppression comments name the
no-dynamic-requirerule that now reports the config loader's dynamicrequire.
No public API or output changes.
- caique: the inquirer theme merge skips
-
Updated dependencies [
4a629a9]:- closeout@0.5.4
0.5.3
Patch Changes
- #604
0e7b1e8Thanks @ofri-peretz! - Each README links to its migration guides under the docs link: "Migrating from: chalk", "ora · log-update · boxen · cli-table3", and so on. That puts a path from the npm page to the guide for the library you are replacing. No code changes. - Updated dependencies [
0e7b1e8]:- linegauge@0.5.4
- closeout@0.5.3
0.5.2
Patch Changes
-
#518
866b972Thanks @ofri-peretz! - README weight lines now count every incumbent with a graded drop-in: terminal-link and term-img (paratext), exit-hook (closeout), @inquirer/core (caique). -
#474
1955419Thanks @ofri-peretz! - burgee plugins can hook two more stages.parseruns before the command is resolved: it receives argv and may return a replacement, which is how an alias plugin mapsdtodeploy.shutdownruns once as the program exits, whether the command succeeded or failed. The familyschema.jsonshipped in every package now describes both stages. -
Updated dependencies [
866b972,1955419,1b002e0,77ff1cb]:- closeout@0.5.2
- linegauge@0.5.2
0.5.1
Patch Changes
- #508
1aae1e2Thanks @ofri-peretz! -<package> --helpand--versionanswer instead of crashing. The bin took its first argument as the plugin file to import, soroundel --helpfailed withCannot find module '…/--help'and exit 1.-h/--helpnow print usage and exit 0,-V/--versionprint the version and exit 0, and any other flag where the plugin file belongs is a usage error, exit 2. - Updated dependencies [
1aae1e2]:- closeout@0.5.1
- linegauge@0.5.1
0.5.0
Minor Changes
- #507
b8e97dcThanks @ofri-peretz! - Runs on Node 20 and 22, not just 24+:engines.nodeis now^20.19.0 || >=22.13.0. Those are the first releases whererequire(esm)loads without a warning, so the CommonJSrequire()path keeps working. Every package's test suite runs on exactly 20.19.0 and 22.13.0, on Linux, macOS and Windows. caique's prompts no longer callPromise.withResolvers, which Node 20 doesn't have.
Patch Changes
- #505
9800b43Thanks @ofri-peretz! - Docs: the Benchmarks section's weight ceiling is re-measured against a fresh install of each incumbent's latest release (cosmiconfig 10.0.1, slice-ansi 9.0.1, which 7.0.0, dotenv 18.0.3, …) instead of the copies hoisted in this workspace, and names incumbents that were measured but left out of the ceiling as exactly that. - Updated dependencies [
9800b43,b8e97dc]:- closeout@0.5.0
- linegauge@0.5.0
0.4.3
Patch Changes
- #494
f7f6d4bThanks @ofri-peretz! - Each package'shomepageand README docs link now point at its own documentation site,https://<package>.interlace.tools, instead of a page on burgee's site. The oldburgee.interlace.tools/docs/packages/<package>URLs answer with a 301 to the new host, so nothing already linked breaks. closeout's README override example also resolves to the current release again (npm:closeout@^0.4; the 0.4.0 release left it at^0.3). - Updated dependencies [
f7f6d4b]:- linegauge@0.4.4
- closeout@0.4.1
0.4.2
Patch Changes
0.4.1
Patch Changes
-
#454
b4584e7Thanks @ofri-peretz! - Every package's npmhomepagenow points at its page on the docs site,https://burgee.interlace.tools/docs/packages/<name>, and each README links it under the header. The keywords add what people and models search for:burgeegainscli-framework,argument-parser,subcommands,json-schema,mcp-server,model-context-protocol,ai-agent,llm,shell-completion,typescript,zero-dependency,commander-alternativeandyargs-alternative; the other eight gainagent,ai-agent,non-tty,jsonandzero-dependencywhere the package does that —zero-dependencyonly on the six that install nothing at all.burgee's README gains a short FAQ (commander alternative, agent use, MCP, dependencies) and states the compatibility counts the oracle holds — 1,360 / 1,360 of commander's tests and 804 / 804 of yargs' — where it had said 1,215 and 1,185.caique's README no longer calls a released package pre-release. -
#442
bdaf364Thanks @ofri-peretz! - Every package now listsplugin,pluginsandextensiblein its npm keywords, because every package takes plugins through one shared contract.A plugin is a plain object, validated against the
schema.jsonthat ships in every package, and checked with the package's owncheckcommand. Each package reads its own key and ignores the rest, so one object can extend any subset of the family. The plugins page has a nine-layer example that every package'scheckaccepts in CI. -
#435
7888524Thanks @ofri-peretz! -schema.jsonnow describes every plugin host in the family.The one schema each package ships as its plugin contract used to cover only four hosts: roundel's
tokens, flagstaff'sglyphs,spinners,bordersandcomponents, paratext'scapabilities, and linegauge'swidths. Five hosts validated their keys in their own code, but the file an author (or a model) writes against said nothing about them. It now describes all of them:- bellpull
resolvers, including the absolute-path rule onpaths - caique
widgets - closeout
handlers, including the phases a plugin may use - seniority
sources, including the rank bounds - burgee
commands,hooksandenforce
Where the schema can express a rule, it gives the same verdict as the host's own validator, and a test holds the two together. Function-valued fields (
static,run,read,handler) are described and required, but not typed, because JSON Schema can't say "function".flagstaff now validates a plugin against only its own keys, not the whole family schema. It no longer refuses a plugin over another host's key, which lets one plugin object contribute to several hosts. Its entry points are also 4.7–5.9 KB lighter for it.
- bellpull
-
#445
dac303eThanks @ofri-peretz! - Every package now declaressideEffectstruthfully, so bundlers can drop what you don't import.Six packages declared nothing, so no bundler could drop any of their modules. A named import from the root now bundles to the same bytes as the same import from its subpath:
import before after import { explain } from 'seniority'2,939 B 1,067 B import { decide } from 'caique'1,235 B 734 B import { strip } from 'linegauge'1,102 B 940 B import { once } from 'closeout'353 B 235 B flagstaff and roundel used to declare
false, but each ships acheckcommand whose file runs when loaded. Each now lists that file, which is the true statement. paratext also lists the two modules that register its built-in capabilities when they load. -
#457
44edb2fThanks @ofri-peretz! - flagstaff's npm description no longer says "Zero dependencies" (it takes four, all in-family); caique's README badge names both of its dependencies. -
Updated dependencies [
b4584e7,bdaf364,7888524,dac303e]:- closeout@0.3.1
- linegauge@0.4.1
0.4.0
Minor Changes
-
#421
db3c59eThanks @ofri-peretz! - Every plugin host has acheckcommand.npx linegauge check ./my-widths.mjs npx burgee check ./my-plugin.mjs --jsonPRINCIPLES 7 asks three things of an extension surface: the plugin is data validated against one published schema, there is a
checkcommand that shows it every way it can be seen, and the bar is measured. The first was built in all nine hosts; the second existed inflagstaffalone. So an author writing a plugin for any other host found out what it did by shipping it into a program — and a surface nobody can check is a surface nobody outside this repository can write against.Each command validates, registers, and shows what the host does with the plugin, in the host's own terms: linegauge measures each code point before and after the override, paratext shows a capability's
encodeand itsfallback, roundel each token and what it replaced, caique each widget's static projection rendered with its own sample. burgee's returns a document rather than printing one, soburgee check --jsonis the form an agent that just wrote a plugin reads.They share one contract with the author, held identically across all nine:
- a readable report, contribution by contribution, with
okas the last line; - a refusal with a code from the family's vocabulary and a
fix, exit 1; E_NO_CONTRIBUTIONfor a plugin that contributes nothing to this host — the schema allows unknown keys so one object registers everywhere, which makes a misspelled key silent, and this is how that typo tells on itself;- exit 2 with no file.
Each host also gains an eval case measuring the one-turn claim, proved to discriminate before it was committed: green against a correct plugin, red against the same plugin with one field broken.
- a readable report, contribution by contribution, with
Patch Changes
-
#430
4d1b2b3Thanks @ofri-peretz! -checknow reports every refusal with its code and its fix, wherever it was raised.Some plugin files register themselves on import: they call
register()at the top of the module and export the result. Until now, when such a file was refused, the error was thrown insidecheck'simport(), before the onlytrythat turns aPluginErrorintoE_PLUGIN_SCHEMA: …plus afix:line. The author got the bare message on stderr, with no code and no fix. Now the whole ofcheckruns inside that one handler, so every refusal comes out the same way on every host. -
Updated dependencies [
4d1b2b3,db3c59e,db3c59e]:- closeout@0.3.0
- linegauge@0.4.0
0.3.1
Patch Changes
-
#398
ee35904Thanks @ofri-peretz! - A__proto__key in a caller's corpus stays a style.fromCliSpinnersandfromCliBoxesbuilt their maps by assigningmap[key] = valueover the caller's JSON. JSON can carry the key__proto__, and that assignment hands it to the prototype setter rather than defining a property: the entry vanished from the plugin and whatever it held became the fallback that every otherlookupSpinnerandlookupBorderinherited. Both now build withObject.fromEntries, which defines an own property for every key, and the returned map keepsObject.prototype.The registry's
deepFrozencopy and caique's prompt binding write the same shape from a loop they cannot turn into an expression, and useObject.definePropertyinstead.flagstaff/importis 80 bytes lighter for it — 838 B to 758 B — because two loops became two expressions.
0.3.0
Minor Changes
-
#381
8104eb9Thanks @ofri-peretz! -caique/inquirerandcaique/clack— two drop-in subpaths, and the first measured numbers either incumbent has given caique.caique/inquireris@inquirer/core's surface overnode:readlineandnode:async_hooks:createPrompt,useState,useEffect,useMemo,useRef,useKeypress,usePrefix,makeTheme,Separator, the eight key predicates and the five error classes. Graded 41 / 41, 100.0% against@inquirer/core12.0.3's own suite, up from 0 / 41 — a suite that renders through a headless xterm and asserts the screen, so what passed is the prompt loop rather than a drawing.usePaginationis not implemented and is named as a gap in.sdlc/intents/caique/design.mdrather than shipped ungraded.caique/clackislimitOptions, which is the part of@clack/promptsthat is a rule rather than a drawing. Graded 14 / 17, 82.4%, up from 0 / 606 — and the denominator moved for a reason published in full on the compatibility page: 289 of that suite's 444 assertions aretoMatchSnapshot()across 17 of its 19 files, and those seventeen are subtracted as a declared subset, one named entry each. The three that remain unpassed are all ofguide.test.tsand are a ceiling, not a shortfall: two want clack's twelve prompts drawn frame for frame, and the third asserts we readupdateSettingsout of@clack/core's own module state, which a package with no external dependencies cannot see.Both subpaths reach
linegauge/wrap, andcaique/inquireralso reachescloseout/exit-hook— both published from this repository, both declared, both budgeted inweight.test.ts. The package root is unchanged: nothing in either façade is reachable fromcaiqueitself.
Patch Changes
-
#373
a1f1d40Thanks @ofri-peretz! - Stage 2's artifact is nowspec.md, the name Anthropic's AI-Native SDLC playbook gives it, so the source comments and README sections that cite a package's own design document point atspec.mdrather thandesign.md.No behaviour changes. The published tarballs do move, by two bytes per surviving reference —
design.mdis nine characters andspec.mdis seven — so the four packages carrying a weight band were re-measured against it: linegauge 83,538 to 83,536; paratext 66,343 to 66,341; closeout 84,455 to 84,453; bellpull 86,113 to 86,107. -
Updated dependencies [
a1f1d40]:- closeout@0.2.1
- linegauge@0.3.1
0.2.0
Minor Changes
-
#294
3f92a60Thanks @ofri-peretz! -caique/plugin— a plugin may now ship a prompt kind caique does not have.register({ widgets })keeps thewidgetskey and ignores every other layer's, so the same plugin object works on any subset of the family that is installed (plugin-contractR1, R5). A widget is the same shape a flagstaff component is —{ static, frame?, sample? }— and one withoutstaticis refused withE_NO_STATIC_PROJECTION, the same code and the same fix shape.PromptKindis an open union (… | (string & {})). It was closed, which made a plugin's seventh kind a type error and would have turned hostingwidgetsinto a breaking change written as an additive one; the six literals stay in an editor's completion list, which a barestringwould have thrown away.Because the union is open, a kind nobody registered no longer falls through to a text prompt —
projectionOf()refuses it withE_UNKNOWN_KIND, and the message names the kinds that are registered so the reader sees the typo rather than a text prompt where their widget should have been. The six built-ins are still drawn by caique and a plugin may not replace them:passwordguarantees that nothing writes back what it read, and a third party able to override it could defeat that from a config file.Also ships
caique/schema.json, byte-identical to flagstaff's and roundel's (R2) — the specifier caique's ownE_PLUGIN_SCHEMAfix names, so following the advice resolves.
Patch Changes
-
#326
88f7ba6Thanks @ofri-peretz! - ARuntimeseam on caique (PLAN 4.3, Y9).src/runtime.tsdeclares the slice of the world caique reads —env,stdin,stdoutand the twoisTTYflags — andprocessRuntime(), the one function in the package that namesprocess. It is a function and not a constant, for the reason paratext's is: a runtime built at import freezes the environment as it was when the module graph loaded, which is before a test can say what it wants the world to look like.createIo()now takes no argument and builds over the real process, so a program gets the terminal it was started in without namingprocessitself;streamsOf(runtime)is the mapping for callers that already hold one.decide()is unchanged and still takes the narrower pair it reads, which is what the root export'sRuntimecontinues to name.runtime.test.tsasserts the seam rather than documenting it:runtime.tsis the only non-test source in the package that reads the process, andprocessRuntime()returns two different answers across a change to the environment made after the import. -
#332
3ea38c3Thanks @ofri-peretz! - Restore the cursor when a prompt is killed, by taking the job fromcloseout.raw.tshid the cursor and put it back on one path: the keypress loop, which sees Ctrl-C because raw mode delivers it as a byte rather than a signal. ASIGINTfrom a parent process, aSIGTERM, a crash or aprocess.exit()elsewhere in the program never reached that loop, and left the cursor invisible in the user's shell until they typedreset. Measured against the builtdist/raw.js: hide 1, show 0, forSIGINT,SIGTERMandSIGHUPalike.askList()now hides throughcloseout.hideCursor(), which registers the restore in the same call, withcloseout/exit-hookrunning it on the paths a keypress loop cannot see. The two escape sequences come fromcloseout/cursoras well, so caique no longer carries the family's third copy of them. The bytes on the wire are unchanged for a prompt that ends normally, and a prompt that ended unregisters, so exit writes nothing twice.caique therefore installs one package,
closeout, which this repository publishes and which sits in the foundation tier below it. Nothing outside this repository is installed. -
#339
f295630Thanks @ofri-peretz! -schema.jsonconstrains token names, because it was promising something no host honours.tokenswas described as any name to a#rrggbbcolour.roundel'svalidate()accepts ten semantic names —error,warn,ok,hint,muted,command,flag,value,heading,ground— and throws on everything else. So a plugin author doing exactly what their ownE_PLUGIN_SCHEMAerror tells them, comparing their object againstroundel/schema.json, got a green from the schema and"accent" is not a tokenfromregister(). Measured 2026-09-16 with{ accent: '#336699' }.The schema now carries
propertyNames.enum, andscripts/plugin-contract-lock.test.tspins the enum and the runtime set to each other from both sides, so neither can grow a name the other does not know.Every host ships a byte-identical copy of this file (
plugin-schema-lock.test.tsasserts it), which is why nine packages are listed. Only the keyroundelowns is constrained: describingwidgets,handlers,sources,resolversorcommandsin a file all eight hosts share is what made flagstaff start validating caique's key last time (PluginError: plugin.widgets.later: expected object, got boolean), and those stay inplugin-schema-lock'sUNDESCRIBEDlist with that reason.linegaugeis in the list for a different change:ceilings.json's R9 block now records the bar as D1's tree-inclusive ceiling — 83,538 against 170,342, a ratio of 0.4904 — and keeps the supersededget-east-asian-widthbar beside it with the count of entries that cleared it. -
Updated dependencies [
c8acb28,fc640dd,3f92a60,3ea38c3,f295630]:- closeout@0.2.0
0.1.1
Patch Changes
-
#92
24e025dThanks @ofri-peretz! - Lock caique's weight, per subpath, against clack.caique was the last published package in the family without a
weight.test.ts— so the one package that talks to a person, and to an agent, was the one making an unmeasured claim.The whole package is 25,627 B and reaches no package at all, against
@clack/prompts1.8.0's 101,684 B across six. Deciding not to ask — the case an agent hits — costs 4,986 B and never loads the machinery of asking.Every entry now declares what it may import (nothing), what it may weigh, and what it must never reach; and an entry cannot be added without a budget.
0.1.0
Minor Changes
-
#71
e204772Thanks @ofri-peretz! - Addcaique/raw: arrow-keyselectandmultiselecton a terminal that can take raw mode.askList()draws a moving highlight and repaints in place, and answers the same questionask()does with the same value — line mode stays the floor, this is decoration on top, and the suite proves the two agree by running one spec through both.keyOf()reads a keypress,canRender()says whether a runtime can take raw mode, andrenderList()is one frame so the drawing is asserted rather than screenshotted.Ctrl-Ccancels — in raw mode it arrives as a byte, not a signal — and the terminal is restored (raw mode off, cursor shown) whatever the answer.No dependency on flagstaff: a prompt has no spinner, and the repaint it needs is three escape sequences.
Patch Changes
-
#66
b43e1d3Thanks @ofri-peretz! -ask()— the six prompt kinds in line mode, which is also the accessible rendering rather than a second implementation of it. A stream that ends is a cancellation, not an empty answer; invalid input is re-asked a bounded five times, never forever;projection(spec)gives the question without the conversation. -
#66
b43e1d3Thanks @ofri-peretz! -resolvePrompts()— the pass a framework calls from itspreActionhook: walks a command's options in declaration order, asks only what has to be asked, and stops at the first refusal. One host-agnostic binding rather than one per host, so nothing in caique imports burgee. -
#66
b43e1d3Thanks @ofri-peretz! -decide()— the pure rule that decides whether a person can be asked at all: a value from any source wins,--jsonnever prompts,--yesanswers a confirm and only a confirm, and no terminal means an error naming the flag rather than a wait. All 256 combinations the design names are enumerated in the suite, not sampled. -
#69
2da5883Thanks @ofri-peretz! -createIo()— a reader and writer over real streams, soask()can be used by a program and not only by a test. Apasswordprompt is not echoed, and the muting lives in the one layer that knows what echo is.