Repository navigation
chore: release v3.0.0 - #21
Merged
Merged
Conversation
github-actions
Bot
force-pushed
the
tegami/version-packages
branch
18 times, most recently
from
September 29, 2026 15:21
67dd855 to
19ccf80
Compare
github-actions
Bot
force-pushed
the
tegami/version-packages
branch
from
September 29, 2026 16:38
19ccf80 to
ff4532c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
All bumped packages.
@padrone/root2.1.03.0.0@padrone/docs2.1.03.0.0@padrone/pizza-example2.1.03.0.0padrone2.1.03.0.0@padrone/deploy-example2.1.03.0.0@padrone/tasks-example2.1.03.0.0Changelogs
output-apis.mdShow Bumped Packages (1)
npm:padronejq interpolation and generators, safer output formats, logger serializers and streams, ora-style progress
--jqsupports string interpolation ("\(.name) (\(.id))"), formats applied to interpolated values (@sh "echo \(.name)"), and the@shand@base64dformats.--jqaddsrange,limit,first(f)/last(f),any/all(with a generator and condition too),values/nulls/scalarsand the other type selectors,recurseand..,paths,paths(f),leaf_paths,getpath,setpath,delpaths,tostream,with_entries,error,envand$ENV. Evaluation is lazy, sofirst(f)andlimitstop early.--jq/--templaterun has a step budget, so a runaway expression like[range(1e9)]fails fast with an error. Set it withpadroneJson({ jqLimits: { maxSteps, remoteMaxSteps } }); serve, MCP andtool()calls get a lower default budget and an empty$ENV.jqfunction gets{ env }as a third argument.padroneFormat({ sanitize: true })strips terminal escape sequences and control characters from yaml, csv, tsv and table values; the table primitive takessanitize: truetoo.padroneFormat({ csvFormulaEscape: true })prefixes'on csv/tsv cells that start with=,+,-,@, a tab or a carriage return, leaving numbers alone.padroneLogger({ serializers })turns fields and child bindings into what's logged by key, before redaction; errors go througherr.padroneLogger({ destination: [...] })writes to several destinations, each{ destination?, level?, format? }with its own level and format.ctx.context.progress.stopAndPersist({ symbol, text })stops the indicator and leaves a final line with a custom symbol, andprefixText/suffixText(in the config orupdate()) add text around the indicator and its final line.schema-aware-parsing.mdShow Bumped Packages (1)
npm:padroneSchema-aware CLI parsing
build --verbose file.txtkeepsfile.txtpositional, andgroup --verbose substill routes tosub. Explicit boolean words (--verbose false) still work.-n5,-ofile,-vn5.-(--pattern -foo), and reportOption "--name" requires a valuewhen it's missing.--title=[WIP]stays a string; the bracket array syntax only applies to array options.--user.id 7→7).-and negative numbers are positionals, never command names.--__proto__.x=1.rawArgsviameta.options, so the parser knows whether each takes a value.eval()andparse()accept an argv array in their types.plugin-parity.mdShow Bumped Packages (1)
npm:padroneLogs on stderr,
--jq/--template, layered config, task lists, a help pager, dry runs andversion --verbosepadroneLogger()writes every level to stderr by default, so logs never mix with command output;stdout: truesendstrace,debugandinfoto stdout as before. Level labels are colored on color terminals, andformat: 'json'writes JSON lines (logger.info({ userId }, 'signed in')adds fields, errors are written aserr).padroneJson()adds--jq <expression>(a built-in jq subset, or plug in a full implementation withjq) and--template '{{.name}}'to filter and format the result.--jsonorformat: 'json'), including errors an error interceptor replaced.padroneConfig()addsmerge: trueto layer every config found (user config directory, then parent directories, then cwd), and followsextendskeys in config files (disable withextends: false).ctx.context.progress.tasks([...])runs a list of tasks drawn live, like listr2, with subtasks, skips, concurrency andexitOnError.taskRendererreplaces the drawing.--versionworks on subcommands (single-character flags stay root-only), andversion --verboseshows the runtime, platform, architecture and shell.padroneVersion({ info })adds fields.builtins: { help: { pager: true } }shows help taller than the terminal through a pager, like git:$PAGER, orless -FRX. Only incli()on a terminal;--no-pagerprints the help directly and--pagerpages it even when it fits. The runtime'sterminalgainsrows..dryRun(handler)builder method: the command accepts--dry-run/-n, and under that flag the handler runs instead of the action (after validation) and its return value is printed. Only commands with a dry-run handler accept the flag or show it in help, so it's never silently ignored. Returning the action's type keeps the result type; a different type extends it to a union. Interceptors seectx.dryRun,padroneConfirm()skips its prompt,tool()needs no approval, and MCP/serve take adryRunargument.--no-colorand--color=…apply to errors from failed parsing too.padroneTracing()records errors thrown while parsing in a root span.padroneInk()returns the first frame as text for serve, MCP andtool()calls instead of mounting the app.sweep4-input.mdShow Bumped Packages (1)
npm:padroneFourth extension sweep: input and prompts
suggestions: { run: 'prompt' }and help'spickSubcommandno longer ask with--no-interactive.$Nplaceholders take fails (Alias "pr" needs 1 argument) instead of passing$1on literally.lifecycle-additions.mdShow Bumped Packages (1)
npm:padroneLogger, task list, signal and timing additions
padroneLogger({ redact })censors paths in logged objects, pino-style (['user.password', '*.token'], or{ paths, censor }).padroneLogger({ destination })writes log lines to a file path, a function or a{ write }stream instead of stderr.logger.child({ requestId })adds bindings to every line it writes, in text (requestId=…) and JSON formats.runtime.terminal.stderrIsTTY), not stdout; withstdout: true, lines sent to stdout follow stdout.retry: n(or{ tries, delay }) and arollbackhandler run once a task has failed for good;t.retrytells which attempt is running.tasks(list, { rendererOptions: { collapseSubtasks: true } })hides the subtasks of finished tasks. Without a TTY or in CI, task lists now print start and finish lines (createSimpleTaskList, also usable astaskRenderer).ctx.context.progress.isActiveandisPausedreport the indicator's state.padroneSignalHandling({ forceExitMs, onForceExit })(orbuiltins: { signal: { … } }) sets the double Ctrl+C window and runs a cleanup hook before a force exit.padroneTiming({ format })customizes the timing line, which now readsFailed after …when the command fails.padroneTiming()registered on a command prints after the error message, like on the root: a failed command's shutdown handlers now run after the root error handlers.runtime.open()on Windows quotes targets with spaces and escapes cmd metacharacters.CI=falseorCI=0.sweep4-lifecycle.mdShow Bumped Packages (1)
npm:padroneFourth extension sweep: logging, progress and lifecycle
upgrade --checkno longer asks for confirmation underpadroneConfirm(), andupgrade --check --dry-runreports the check.padroneUpgrade()detects yarn global installs on Windows.timeandlevel, and a message argument wins over amsgfield.padroneTiming()rounds before choosing the unit, so it no longer prints1000msor60.00s.padroneUpdateCheck()treatsCI=falseandCI=0as not CI, and only checks when the program has aversion, instead of comparing against the working directory'spackage.jsonornpm_package_version.TERM=dumb; they print final lines only.progress.pause()is in effect no longer redraws the indicator beforeresume().config-env-apis.mdShow Bumped Packages (1)
npm:padroneConfig, env, response file and alias additions
{ command, env, envName, profile };defineConfig()from'padrone'types it.searchParents: 'project'stops the parent search at the nearest directory with.gitorpackage.json, andstopDirsets the last directory to search.$production: { ... }and$env: { staging: { ... } }in a config override its values for the active environment (envName,NODE_ENVby default);$keys are never option values.padroneEnv()splits variables for array options on commas (APP_TAGS=a,b;arraySeparatorchanges it,[...]reads JSON), andnestedSeparatorreplaces the__in nested variable names..envfiles support${VAR:+alt},${VAR+alt},${VAR:?message}and${VAR?message}; a missing required variable is an error naming the file.padroneResponseFiles({ relativeTo: 'file' })resolves nested response files beside the file that names them.alias import <file|->adds aliases from YAML or JSON (--clobberoverwrites existing ones),alias export [file]writes them, andalias listnow prints YAML that imports back.variadic-options.mdShow Bumped Packages (1)
npm:padroneVariadic options
variadic: trueon an array option takes every following value up to the next option:--tags a b c. Positionals after it need--, and--tags=astill takes a single value.security-sweep.mdShow Bumped Packages (1)
npm:padronePlugin and security hardening
padroneUpgrade()runs the installer without a shell on Windows and checks the package name.padroneUpgrade()has--rollback, andverifySignature()checks Ed25519 or ECDSA release signatures.padronePlugins()ignores unsafeplugins.jsonnames, writes it privately and atomically, and pins each plugin's version and file hash.padronePlugins()hasallow,apiVersion(plugins declarepadroneApi),override,ignoreScripts,plugins update,plugins infoandplugins list --json.padroneConfig({ scripts })refuses or vets script configs, which run code.padroneExternalCommands({ env })limits the variables external commands inherit.padroneCredentialshaslist(), and the file backend handles a__proto__service safely.padroneUpdateCheck({ channel })follows a dist-tag with its own cache.remote-additions.mdShow Bumped Packages (1)
npm:padroneRemote caller improvements
.configure({ needsApproval })is typed: a boolean, or a function of the command's validated args..configure({ outputSchema }): advertised as the MCP tool'soutputSchemaand documented as the OpenAPIresult.structuredContentas well as text.corsorigin (403), guarding against DNS rebinding.DELETEaborts its tool calls in flight.stderr.sensitivefields in GET query strings and leaves them out of the OpenAPI GET parameters.<caller> <command>(such asserve deploy), uses a server span kind for serve and MCP, and sets the span status message from the error.sweep5-security-fixes.mdShow Bumped Packages (1)
npm:padroneFifth sweep: security hardening and plugin fixes
config,alias,upgrade, …), andconfig,alias,completion,man,serve,mcpandupgraderefuse serve, MCP andtool()calls.Originthat isn't loopback, the server's own host or thecorsorigin gets 403.Hostheader (DNS rebinding).maxBodySizeoption for serve and MCP over HTTP (default 4 MiB); larger request bodies get 413.sensitivefield, and leaves them out of the OpenAPI GET parameters.package.jsonkey) can no longerextendsa script config.historySize: 0keeps no history.runtime.editor()andpadrone linkshims quote file paths for the shell; static completion scripts quote enum values.padrone initwrites names and descriptions with quotes as valid JSON and TypeScript.--replor thereplcommand), Ctrl+C interrupts the running command instead of the session; a Ctrl+C after a caller'ssignalaborted the run stops it instead of force-exiting.getRootCommand()work from the subcommands of mounted programs.db.password) get masked prompts, and under-ia blank answer to a masked prompt keeps the given value..envfiles: an unclosed quote is read as an unquoted value, a tab before#starts a comment,$toString-style names don't expand, and trailing whitespace on a multiline value's first line is kept.stdinwithisTTY: trueisn't read forstdinfields, and afromFile-no longer conflicts with astdinfield that wouldn't read.--jq:from_entriesfollows jq 1.7.1, fractional slice bounds round like jq, strings sort by code point, and__proto__keys are kept in constructed objects.redactalso censors class instances...plugin-audit.mdShow Bumped Packages (1)
npm:padroneExtension fixes, plus env
prefixand config search options--helprespects--no-colorand--json: the help was rendered before those flags were read. Under--json(orformat: 'json'), help is printed once as a JSON object instead of a JSON-encoded string.help,repl,completion,man,mcp,serve) list their options in help, and their boolean options no longer take the next word as a value (completion --setup bashnow sets up bash). Thehelpcommand takes-d/-ffor--detail/--format.padroneLogger()andpadroneTiming()work when applied to a single command: their flags were rejected as unknown options, and timing measured from process start.tool()calls (over MCP's stdio transport, that's where requests arrive). Progress indicators are no-ops and timing isn't printed for those calls.--colortakesalways,neverandauto, which were taken as theme names.padroneConfig()imports JS/TS config files by file URL, so absolute Windows paths work in Node.PadroneConfigOptions,PadroneEnvOptions,PadroneAutoOutputOptionsandPadroneTimingOptionsare exported from'padrone'.padroneEnv({ prefix: 'MY_APP' })reads every option fromMY_APP_*variables (--dry-run←MY_APP_DRY_RUN), like yargs'.env(). The variables are shown in help.padroneConfig()options:searchParentsalso searches parent directories, andpackageJsonreads config from apackage.jsonkey, like cosmiconfig.help-topics-callers-events.mdShow Bumped Packages (1)
npm:padroneHelp topics, interceptor callers and custom events
builtins: { help: { topics: { environment: { title, description, content } } } }(orpadroneHelp({ topics })) adds help topics:app help environmentprints the topic (through the pager when it's on;{ topic, title, content }under JSON output). The program's help lists them under "Additional help topics",help <typo>suggests them, completion offers them afterhelp, and Markdown docs get a page per topic. A command of the same name wins.callersruns an interceptor only for the listed callers (LOCAL_CALLERSandREMOTE_CALLERSare exported).defineEvent<T>(id), handled withinterceptor.on(event, handler)and emitted withctx.emit(event, payload)from actions and interceptors (orprogram.emit()outside an execution). Handlers run in interceptor order, andemit()resolves once they have.createPadrone(name, { builtins })are now contextually typed.dx-sample-3.mdShow Bumped Packages (1)
npm:padroneFix typing and context gaps found writing a third sample program
defineCommand()group keep their names, soeval(),parse()andtestCli()still infer the command instead ofneverrun()rejects a command name it doesn't know (run('lsit', {})); astringvariable is still acceptedtool(),serve()andmcp()take acontext, required when the program declares one; theserveandmcpcommands pass on the context given tocli()defineInterceptor({ name }).on(event, handler)defines an interceptor that only handles an eventOption "-l" requires a valueis no longer prefixed with the option's name.context(transform)no longer changes the context callers pass: after.context<{ url: string }>().context((ctx) => ({ db: connect(ctx.url) })),cli()/eval()/run()take{ url }and commands get{ db }; later transforms get the previous one's outputundefinedor{}inrun()andapi()(program.run('status'),api.status()), and serve accepts anullbody for themargs(in actions, hooks andresult.args) as{}, matching what they receive, instead ofvoidremote-apis.mdShow Bumped Packages (1)
npm:padroneRemote access controls for serve, MCP and tool()
.configure({ expose })says which callers may run a command and its subcommands:falsefor local callers only, or a list such as['cli', 'mcp']. Servers don't list a command they can't run, and running it from another caller fails. Built-in commands (config,alias,plugins,upgrade, …) are local only;helpandversionstay available.serve()andmcp()takeinclude/exclude(command paths, globs like'db.**', or a predicate) to offer only some commands.auth(a function of theRequest) andbearer(tokens) authenticate requests toserve()and MCP over HTTP; refused ones get 401. Actions, hooks and interceptors read the identity asctx.auth, whicheval()andcli()also take asauth.allowedHostslists theHostnames a server answers, protecting non-loopback bindings from DNS rebinding too;trueturns the check off.timeoutaborts a command that runs too long (serve: 504; MCP: a JSON-RPC error), andmaxConcurrentrefuses requests over a limit (serve: 503).tool({ timeout })works the same way.sessionTtlms without requests, andmaxSessions(1000 by default) drops the least recently used one.serve()andmcp()log the port they actually listen on, soport: 0works.authorbearer, an MCP session only answers the identity that created it.from-file.mdShow Bumped Packages (1)
npm:padroneOption values from files, and response files
fromFile: truefield meta: a command-line value@pathreads the file,-reads stdin, and@@textpasses@text. Values from env, config files and serve/MCP/tool()calls are taken as given. Help marks such options(@file or - for stdin).padroneResponseFiles()expands@filearguments into the arguments listed in the file (one or more per line,#comments, nested files), incli(),eval()and the REPL. A missing file is an error;@@escapes a leading@.dx-sample-2.mdShow Bumped Packages (1)
npm:padroneGlobal args for commands in their own files
defineCommand()and mounted programs take the program's global args inrun(),api()andInferArgsOutput, as inline commands already did.defineCommand<Context, typeof globals>()types the global args inside the command. Its result can be reused for every command.Help and suggestions
--helplists the options ofpadroneFormat()(-o),padroneJson()(--json,--jq,--template),padroneLogger()andpadroneTiming(), leaving out short flags a command's own options use.Run "... --help"hint instead of showing it before the options.Did you mean "list"?, not"list" or "ls".dx-sample-2-recommendations.mdShow Bumped Packages (1)
npm:padroneClearer help and errors
<value>for options that take a value and[value]only where it can be left out (--json [fields]), marks required options(required), and showsboolean | stringoptions as[string].Unknown option "--limt". Did you mean "--limit"?, without thelimt:in front.Config and env
sections: 'auto'):{ "list": { "limit": 1 } }sets--limitforlist, unless the running command has an option namedlist.sections: falserestores the old behavior.padroneEnv({ prefix: 'APP', scope: 'command' })reads a subcommand's own options fromAPP_<COMMAND>_<OPTION>(APP_LIST_LIMIT), so commands don't share variables. Global options keepAPP_<OPTION>.Typing
conflicts,implies,requires,requiredIfandrequiredUnlessin.arguments()fields only accept the command's options and global options.testCli(program).run(input)typesresult,argsandcommandby the command the input names, and.context()by the program's context.sweep4-help.mdShow Bumped Packages (1)
npm:padroneFourth extension sweep: help, REPL and completion
--files a.ts <TAB>).help db <TAB>completes the subcommands ofdb, not only the first word afterhelp.'') command, which such options run..scope db migratein the REPL scopes into the nested command instead of failing, and.scopereports the full path it couldn't use.padroneHelp({ flags })) instead of always--help/-h, and no longer offers an empty alias.[],'') of positionals too; man pages no longer show abooleanplaceholder after flags; Markdown command tables keep descriptions with|or line breaks in one row.completion-hints.mdShow Bumped Packages (1)
npm:padroneCompletion descriptions, value hints and value names
completeitems, which may now be{ value, description }(zsh, fish and PowerShell; bash shows values). The scripts call<program> __complete2, which printsvalue<TAB>descriptionlines and a directive;__completestill prints values only, so regenerate scripts installed from an earlier version to get the new behavior.hint('file','dir',{ ext: ['json'] },'command','url','none') sets what completion offers for a value when no candidate matches, in dynamic and static scripts. Values with enum values orcompleteno longer fall back to file names unless hinted.valueNamesets the value placeholder in help, docs and man pages:--out <DIR>, and<DIR>for a positional.config-additions.mdShow Bumped Packages (1)
npm:padroneConfig and env additions
--config/-cis listed in help.padroneConfig({ sections: true }): per-command sections ({ "serve": { "port": 3000 }, "db": { "migrate": { ... } } }) override top-level values for that command.help,config,serve, …);builtins: trueonpadroneConfig()/padroneEnv()opts back in, and.configure({ builtin: true })marks your own.padroneEnv({ prefix })reads nested options with a double underscore (APP_DB__HOST→db.host), and dottedvarskeys set nested values.APP_PORT=) now count as unset;padroneEnv({ allowEmpty: true })keeps them as empty strings.… (from APP_PORT),… (from config.json).--profileis an unknown option for serve, MCP andtool()calls unlessprofiles: { remote: true }.config set/config unsetchange the value in place, keeping comments and formatting in JSON, JSONC and rc files.name: 123for a string option gives"123").config get|set|unset|list|path|edittake--local(the project config file) and--file <path>.global-args-gaps.mdShow Bumped Packages (1)
npm:padroneGlobal args in prompts, completions and docs
interactive: truealso prompts for missing required global args, and.globalArgs(schema, { interactive })prompts for them in every command of the subtree.extension-sweep.mdShow Bumped Packages (1)
npm:padroneExtension fixes and additions
cli()prints errors from every phase: errors thrown in arouteinterceptor, by a config file or by a validate interceptor were silent. An error is printed once even when auto-output is applied to the command too.padroneUpdateCheck()shows its notice (it never did), including after sync commands. The check only runs incli(), is skipped with--no-update-checkorNO_UPDATE_NOTIFIER, and times out after 3 seconds. A release now counts as newer than its own pre-releases. NewupdateCommandoption customizes the suggested command.padroneConfig(): a missing--configfile or an unparsable config file is aConfigErrorinstead of being ignored. JSON config files load outside Bun, with comments and trailing commas allowed.--no-colorand--color=falsedisable colors, and--colorforces them; they only changed the theme before.FORCE_COLORis honored.padroneLogger()prints errors with their stack instead of{}, and no longer throws on bigints or circular objects. Newenvoption reads the level from an environment variable.padroneTracing()works withrun(), names spans by the full command path, and addspadrone.commandandpadrone.callerattributes.--reploption is no longer taken over by the REPL flag, and--replafter positional values scopes to the command.<cmd> helpshows the command's help for commands without positionals, and no longer swallows ahelpvalue of a positional argument.padroneEnv()loads.envfiles when any file option (dir,local,base,override) is set, not onlymodes.cli({ runtime: { argv } })readsargvfrom the given runtime.signalpreference foreval(),cli()andrun()cancels a run throughctx.signal.markErrorReported()is exported for extensions that print errors themselves.strict-cli-defaults.mdShow Bumped Packages (1)
npm:padroneStricter CLI defaults
Too many arguments) instead of being joined into the last positional with spaces. Positionals passed to a command that declares none are reported instead of silently dropped. Use a variadic (...rest) to accept any number.0x10,Infinityand whitespace-padded values are rejected.Run "app build --help" for usage.instead of the full help. Opt back in withcreatePadrone(name, { builtins: { help: { showHelpOnError: true } } })orpadroneHelp({ showHelpOnError: true }).cli()or the REPL prints a warning to stderr.padroneLogger()no longer consumes--verbose,--quietand the other level flags when the command defines an option with that name.root:prefix.lifecycle-apis.mdShow Bumped Packages (1)
npm:padroneLifecycle hooks, command-not-found handling, external commands and runtime plugins
.hook('preAction' | 'postAction', handler)runs code around the action of a command and all its subcommands, with typed args and context.commandNotFoundevent: a handler can run something in place of an unknown command (event.handle()) or route another input (event.reroute()); otherwise the usual error and suggestions follow.padroneExternalCommands()extension:my-cli foorunsmy-cli-foofromPATH, with its exit code; external commands show in help and completion.padronePlugins()extension: plugins users install at runtime, loaded at startup, withplugins list|install|uninstall|link.extraCommandsmeta.progress-fixes.mdShow Bumped Packages (1)
npm:padroneProgress indicator fixes
padroneProgress()no longer crashes withrun(); the indicator starts right before the action.succeed(),fail()orstop()yourself is no longer followed by a second auto-managed message.update()message instead of the initial one.widthunder 3) no longer throw.pause()no longer writes escape codes to stdout, which corrupted piped output.success/errormessage callback throws.output-format.mdShow Bumped Packages (1)
npm:padroneOutput formats and
--jsonfieldspadroneFormat()extension:--output/-o <format>prints results astext(default),json,yaml,csv,tsvortable.formats,defaultandflagscustomize it, andtableFlags: trueadds--columns a,b,--sort [-]columnand--no-header. Errors print as JSON under-o json.padroneJson({ fields: true }):--json=name,urlprints only those fields of the result (or of each item). Withfields: 'required',--json name,urlalso works and a bare--jsonfails listing the available fields, likegh;availableFieldsdeclares them up front.header: false.completion-system-apis.mdShow Bumped Packages (1)
npm:padroneCompletion, wrap, upgrade, update-check and man options
.configure({ complete })completes a command's positionals in one place, like cobra'sValidArgsFunction: it gets the word'sposition,fieldand thepositionalsbefore it. A positional field's owncompletestill wins.completecallbacks also get thefield, theruntimeand thecontext, and may return{ values, directive }to set the fallback ('files','dirs','ext:json','commands','nofiles').padroneCompletion({ mode: 'static' })orcompletion <shell> --staticprints the static script;descriptions: falseor--no-descriptionsleaves descriptions out.--setupkeeps these flags and writes under the runtime'sHOME.program.completion(shell, { mode, descriptions })takes them too..wrap({ separator: '--' })puts positionals after--, andflagStyle: 'equals'passes--key=value.padroneUpgrade({ verify })checks a release before installing it; resolvingfalserefuses the upgrade. NewverifySha256(data, expected, fileName?)checks a download against a digest or aSHA256SUMSfile in a custom installer.padroneUpdateCheck({ shouldNotify, format })suppresses or rewords the update notice (formatalso applies toversion --check).padroneMan({ section, dir })sets the man section and whereman --setupinstalls;generateDocstakessection.man --setupnow readsXDG_DATA_HOMEandHOMEfrom the runtime env, and"in.THarguments is escaped.inheritance-and-env-fixes.mdShow Bumped Packages (1)
npm:padroneFix schema inheritance and invalid env values
.arguments((parent) => parent.extend({...}))now receives the parent command's schema; it used to receiveundefinedand throw. Passingmeta(e.g.positional) alongside it no longer breaks type inference.padroneEnv()reports a set but invalid variable as a validation error instead of silently ignoring every env value.prompt-credentials.mdShow Bumped Packages (1)
npm:padronePrompts in actions, confirm options and credential storage
ctx.promptwithtext,password,confirm,select,multiselectandgroup(steps see earlier answers); interceptors get the same withcreatePrompt(ctx).PromptCancelledError(exit code 130), distinct from an empty answer; custom runtimes cancel by returningPROMPT_CANCEL, andisPromptCancel()checks both.tool()calls,ctx.promptreturns the prompt'sdefaultor throws aPromptUnavailableErrorinstead of waiting.testCli().prompt()answersctx.promptquestions by name (a group step's key by default).padroneConfirm({ nonInteractive: 'yes' | 'no' })runs or aborts a command that can't ask instead of failing;.configure({ confirm })sets a command's question or turns it off; cancelling the question aborts.padroneCredentials()extension:ctx.context.credentials.get/set/deletestore secrets in the macOS keychain or the Linux Secret Service (secrets passed on stdin), falling back to a0600file; serve, MCP andtool()calls can't read them unlessremote: true.db.host) and select defaults of number enums work with the Enquirer prompt.repl-exit.mdShow Bumped Packages (1)
npm:padroneREPL:
exitandquit, and tab completion like shell completionexitandquitleave the REPL, like.exit, unless the program or current scope has a command with that name.--dry-run, not--dryRun), never hidden ones, and deprecated commands and options only when nothing else matches what's typed.core-additions.mdShow Bumped Packages (1)
npm:padroneJSON values for object options, non-mutating interceptor chaining, same-id interceptors across layers
--db '{"host":"x"}',--items '[{"name":"a"}]', or one--items '{"name":"a"}'per item), alongside dotted keys, which merge with it (the later value wins). Invalid JSON is reported as a validation issue. JSON from env variables andfromFilefiles (--db @db.json) is parsed too.stringify()pass objects that dotted keys can't express (record keys with dots, arrays inside, empty objects) and arrays of objects as JSON, so they reach the command intact.stringify()quotes values with quotes in them.OptionArityhas a new'json'value for these options..on()and.requires()on an interceptor return a new interceptor instead of changing the one they're called on, so a handler added to a shared interceptor no longer leaks into other programs.idas a root one now replaces it in the error and shutdown phases too, instead of both running.help-additions.mdShow Bumped Packages (1)
npm:padroneCompletion, REPL, help search and man page improvements
-v) when the word is-or-v, and only the kebab-case name of camelCase options (--dry-run, not--dryRun), as help shows them.src/*.completion <shell> --instructionsprints how to install the script, for the named shell or the detected one; the instructions above a detected shell's script are now comments, so evaluating the output only loads the script.historyFilekeeps history between sessions (truestores it inprogram.dirs.state), capped byhistorySize(default 1000). Initialhistoryentries now come up in the right order..scopegets "Did you mean", andhelp <command>inside a scope shows help for the scope's commands.help --search <term>(-s) lists commands and help topics matching every word of the term.<program> <version>in.TH(the date fromgenerateDocs's newdateoption,SOURCE_DATE_EPOCH, or today) and link the parent and subcommand pages under SEE ALSO.plugin-additions.mdShow Bumped Packages (1)
npm:padroneSelf-update, aliases, and more prompts
padroneUpgrade()adds anupgradecommand that installs the latest version with the package manager the program was installed with (npm, bun, pnpm, yarn or Homebrew, detected).--checkonly reports,--to <version>installs a given version,--channel nextfollows another dist-tag, and--dry-runshows the command. A custominstallercan perform the upgrade itself.padroneAliases()expands command aliases before routing. The program can define some (aliases: { co: 'checkout' }), and people add their own withalias set pr "checkout pr/$1",alias listandalias delete, kept in the program's config directory.builtins: { suggestions: { run: 'prompt' } }asks whether to run the closest command after an unknown one.builtins: { help: { pickSubcommand: true } }asks which subcommand to run when a group command runs without one.ctx.runtime.editor(text)opens the user's editor and returns what they saved,ctx.runtime.open(url)opens a URL or file with the default app, andctx.runtime.page(text)shows long output through a pager. All three can be replaced in the runtime.program.dirsgives the program's standardconfig,cache,data,stateandlogdirectories for each platform (XDG on Linux);getProgramDirs()computes them for any name..arguments(schema, { exactlyOne: ['file', 'url'], atLeastOne: ['email', 'slack'] })requires exactly one, or at least one, of a group of options (several groups as an array of arrays; also on.globalArgs())..requires<T>('padrone:logger')(orrequiresin interceptor meta) checks at runtime that the named interceptors are registered, and fails with an error naming a missing one.beta.10afterbeta.2,alphabeforebeta) in update checks.asyncis kept bydefineInterceptor(meta, factory), so config and env loading no longer print the "not marked as async" warning.plugin-api-additions.mdShow Bumped Packages (1)
npm:padroneMore plugin and extension safeguards
padronePlugins()ignores manifest entries with option-like specs or control characters in names, refusesplugins updatefor names outsideallow, re-readsplugins.jsonbefore writing, and hasonError.padroneExternalCommands({ allow })limits which external command names run.version --verboseis plain for remote callers unlesspadroneVersion({ remoteVerbose: true }).opentargets starting with-are made relative, andverifySha256accepts a bare digest.exclude,include,exposeorhiddenwithhold.stripJsoncand response files are bounded (no regex backtracking, at most 1000 files per expansion).config setredactssensitivevalues, and a new user config file is private (0600).config-command.mdShow Bumped Packages (1)
npm:padroneConfig profiles and a
configcommandpadroneConfig({ profiles: true }): a config'sprofiles.<name>values override its top-level ones when selected with--profile <name>, the<PROGRAM>_PROFILEenvironment variable, or a top-levelprofilekey. An unknown profile fails with the available ones.{ flag, env }renames the flag and the variable. Help lists--profile.padroneConfig({ command: true })addsconfig get|set|unset|list|path|editfor the user config file, likegit config.setchecks the key against the program's options and coerces and validates the value; only JSON files are written.listshows where each value comes from, andeditsaves only a config that still parses.meta.helpOptions.input-additions.mdShow Bumped Packages (1)
npm:padroneInput improvements: aliases, response files, prompts, stdin and confirm
padroneAliases()names, and unknown options are matched against options extensions declare (--json,--yes,--interactive, …), leaving out help's own options. A default command's empty name is never suggested.$@placeholder for the words no$Ntakes (without$@they're still appended), and@filewords in an alias expand as response files.alias set co checkout --forceworks without quotes: every word after the name is the expansion.padroneResponseFiles(), the value of afromFileoption (--body @notes.md) is read byfromFileinstead of expanded as a response file, so--body @@xnow passes@x.db.host,db.port), and ask again after a blank answer to a required field.stdin: { field, trim: true }trims piped text; number and boolean stdin fields are always trimmed (echo 21 | my-cli double), and a lone-value reads stdin (my-cli cat -).padroneConfirm()runs without asking when<PROGRAM>_YESis set (e.g.MY_CLI_YES=1);envrenames the variable,env: falseturns it off.output-additions.mdShow Bumped Packages (1)
npm:padroneMore jq, table and color options
--jqsupportsif … then … elif … else … end,. as $x | …variables, arithmetic (+ - * / %, with jq's rules for strings, arrays and objects),min/max/min_by/max_by/group_by/unique_by,split,ltrimstr/rtrimstr,tojson/fromjson,test/sub/gsubwith regex flags, and the@csv,@tsv,@json,@text,@html,@uriand@base64formats.joinfollows jq for numbers, booleans and nested values.--jqprints non-string outputs as compact JSON, one per line, when stdout isn't a terminal, and indented on a terminal, likegh --jq.padroneFormat({ columns: { id: 'ID', name: 'Name' } })sets the default columns and their header labels for table, csv and tsv (or a function for per-command columns).padroneFormat({ pipedTable: 'tsv' })prints-o tableas tab-separated rows when stdout isn't a terminal. Tables are still printed as tables by default.padroneFormat({ csvLineEnding: 'crlf' })ends csv lines with\r\n(RFC 4180).--color=<theme>with an unknown theme is an error listing the themes.CI=falseandCI=0no longer turn colors off.CLICOLOR=0turns them off andCLICOLOR_FORCE=1forces them on;NO_COLORandFORCE_COLORtake precedence.messageno longer repeats the "Did you mean" hint listed insuggestions.extension-sweep-3.mdShow Bumped Packages (1)
npm:padroneThird extension sweep
MCP, serve and
tool():MCP-Protocol-Versionheaders with JSON-RPC errors instead of hanging or answering them;initializeaccepts2025-06-18and2025-03-26clients; cancelling a call no longer aborts another client's call with the same id.helptool is namedpadrone_helpwhen a command is calledhelp, and help for an unknown command is an error.output, documents nested arguments as the dotted query parameters it accepts, allows trailing slashes andAuthorizationin CORS, and works with IPv6 hosts under Node.tool()reports errors, validation failures and unknown commands inerror, and itsabortSignalcancels the command.nullarguments from serve and MCP mean unset; objects written withruntime.outputcome back as JSON;--replis an unknown option for these callers instead of starting a REPL.remote: 'exit'stops when the call is aborted and returns render errors as errors.Prompts, config and env:
padroneConfirm()fails without--yesinstead of hanging on piped input, and--no-interactivemakes it fail too..envvariables are visible toctx.runtime.env()in the action. Single-quoted.envvalues aren't expanded, chained references expand, and process env wins over.envfiles unlessoverride.toStringare ignored.--jq/--templateand--json=1print JSON errors after an unknown command;has,tonumber,to_entries,selectandlengthin--jqmatch jq.Output and progress:
--verbose=false/--verbose=0no longer enable debug logs;%sprints objects as JSON; the logger'sprefixcan come from context.ctx.context.outputand returns a value prints once; streamed results are closed when printing fails.padroneProgress()uses the context's messages.Help, completion and aliases:
--colortakes a value only with=(--color hellokeepshelloas an argument);--color=off/nodisable colors.help <unknown>suggests similar commands and no longer lists hidden built-ins.--opt=valuein bash, offers no subcommands after--, and follows the help flags' names; fish scripts handle backslashes in descriptions; the shell is detected from the runtime's environment.alias setkeeps quoted words together, andalias set/deleteare mutation commands.suggestions: { run: 'prompt' }only replaces the mistyped command, never an option value spelled the same.Upgrade and update check:
padroneUpgrade()detects npm installs under Homebrew's Node and pnpm installs run by Bun, refuses--to/--channelwith Homebrew, and validates versions before running the installer.upgrade, and build metadata (+build) is ignored when comparing versions.env-in-help.mdShow Bumped Packages (1)
npm:padroneEnv variables in help
padroneEnv({ vars: { port: 'APP_PORT' } })maps args to environment variables without a schema. Values are coerced by the command's schema, and each option's variables are shown in help asEnv: APP_PORT. Interceptors can declare the variables they read viameta.env.drain-finalized.mdShow Bumped Packages (1)
npm:padronedrain()fixesdrain()is cached: draining a result twice gives the same answer, even for an iterator result with auto-output turned off.drain().cli()sets the exit code for an error that surfaces while draining only once.repl-context-and-tables.mdShow Bumped Packages (1)
npm:padroneREPL context, prompt, test context and table fixes
replcommand and--replnow pass the context given tocli()to every command in the session.repl()takes acontextoption.testCli(program).context(value)sets the context for.run()and.repl(), so programs that declare one can be tested.output: 'table',ctx.context.output.table()) line up in color terminals, and the divider is as wide as the rows.z.number()) accept42instead of re-prompting forever.field-dependencies-sensitive.mdShow Bumped Packages (1)
npm:padroneDependent and sensitive options
requires: ['password'],requiredIf: { format: 'file' }andrequiredUnless: ['user', 'key']field meta make an option required depending on the others. They work in.globalArgs()too, are shown in help, and a missing option covered byinteractiveis prompted.sensitive: truemarks a secret: it's prompted without echo, its default and examples are left out of help, and MCP/serve input schemas mark itwriteOnly.redactArgs(command, args)returns args with sensitive values replaced by'[redacted]', for extensions that log them.Implied values with interactive prompting
implies: { color: false },conflicts: 'color') no longer fails on its own in commands with interactive prompting.sweep4-output.mdShow Bumped Packages (1)
npm:padroneFourth extension sweep: output
---delimiter row and escape|in cells.[]/{}under JSON output.padroneAutoOutput({ output })streams generator results item by item instead of printing{}, and prints non-object results as text undertree.-o yamlprints string results, such as--helpand--version, as text..5and...that would read back as a number or a document end.--jq: string slices count code points,ascii_downcase/ascii_upcaseonly change ASCII letters, and comparisons with several outputs follow jq's order.--colorvalues are case-insensitive (--color=NEVER), andTERM=dumbturns colors off unlessFORCE_COLORis set.extension-sweep-2.mdShow Bumped Packages (1)
npm:padroneExtension fixes
negativekeyword. MCP no longer returns a command's output twice, andtool()no longer repeats the result inlogs."", each HTTP client gets its own session,/mcp?x=1matches the endpoint, and notifications get no response.basePathworks without a trailing slash, and paths outside it are 404s. Bad input (e.g. an extra positional) is a 400bad_requestinstead of a 404, validation errors go throughonErrorwith amessage, an empty POST body means no arguments, and a throwingonRequestoronErrorgives a 500 instead of a hung request.--yes=false,--json=false,--help=false,--no-repland similar are off, not on.nullmeans unset, nested objects merge under CLI values, and a positional typed on the command line wins over config and env. Config values are applied before interactive prompts..envvariables that aren't options are no longer rejected as unknown, and are visible toruntime.env().Set,MaporUint8Arrayas one value instead of item by item, and--jqapplies to commands with a declarativeoutputformat.reasonis aSignalError, soctx.signal.throwIfAborted()exits 130/143. A repeated SIGTERM or SIGHUP force-exits.padroneConfirmprompts, a streamed result succeeds or fails when it's consumed,--dry-runshows no success message, and a task whoseskip()throws is marked failed.--log-levelaccepts any case and rejects unknown levels.padroneUpdateCheck()works on a command, and a failed check is cached so offline machines don't wait every run.padroneTracing()marks validation failures on the span and records the failing phase.padroneInk()keeps sync commands sync. Newremote: 'exit'option mounts the app headlessly for serve, MCP andtool()calls and returns its last frame.--helpno longer reads piped stdin first;help <unknown>is an unknown-command error;--alllists only registered built-ins; the subcommand hint includes the program name; option suggestions use kebab-case names and catch case-only typos.--versionkeeps flags like--json.replcommand no longer prints the session's results when it ends, uses the runtime passed tocli()(newruntimeREPL option), honorsFORCE_COLOR, and doesn't crash when started inside a REPL.<program>-<command>.1so they can't shadow system pages, and lines starting with.are escaped.-c file); the bash script handles:in words and quotes candidates with spaces; static scripts fix fish long aliases, bash spacing and PowerShell enum values.async: truemarks interceptors that may make validation async.help-customization.mdShow Bumped Packages (1)
npm:padroneHelp customization
.configure({ help: { usage, before, after } })replaces a command's usage line and adds text before or after its help..configure({ help: (info, ctx) => ... })customizes help with a function for a command and its subcommands. It returns modified help info or the final string, andctx.rendergives the built-in renderer.builtins: { help: { flags: ['help', '?'] }, version: { flags: ['version'] } }.update-additions.mdShow Bumped Packages (1)
npm:padroneVersion, update check and upgrade improvements
.configure({ version }),--version,upgradeand the update check read the version from thepackage.jsonof the package the program's script belongs to, instead of the working directory's project ornpm_package_version.upgrade --check --exit-codeexits with 1 when a newer version exists, likenpm outdated.upgradeasks the registry first: when already up to date it says so without apadroneConfirm()prompt, and asks only when there is something to install.padroneUpdateCheck()never delays the exit: the notice comes from the version cached by an earlier run, and a stale cache is refreshed in a detached background process.update-check.jsoninprogram.dirs.cache; the old~/.config/<name>-update-check.jsonis moved there.<program> upgradewhenpadroneUpgrade()is registered, and uses its package name and registry.version --check(also--version --check) asks the registry and adds an "Update available" notice, likegh version; under JSON output it returns{ name, version, latest, updateAvailable }. Remote callers get the version without a check.sweep4-remote.mdShow Bumped Packages (1)
npm:padroneFourth extension sweep: MCP, serve, tracing and Ink
falsereaches booleans whose--no-prefix is disabled, empty arrays stay empty instead of taking the default, and array items like[x]aren't split as list syntax.stringify()follows.?name=) is an empty string instead of taking the next param as its value; for a boolean (?verbose) it still turns it on.tools/callwithargumentsthat aren't an object is an invalid-params error.tool(): what a successful command writes to stderr (warnings, logs) is inlogs, noterror.extension-additions.mdShow Bumped Packages (1)
npm:padroneNew extensions and extension options
padroneJson()adds a--jsonflag: the result is printed as JSON (iterator items one per line), and incli()errors are printed as{ "error": { ... } }on stdout, with validation issues. Withformat: 'json', auto-output prints values as JSON incli(),eval()and the REPL.padroneConfirm()asks before runningmutation: truecommands incli()and the REPL.--yes/-yskips the question; without a terminal the command fails unless--yesis given.padroneCompletion(), the generated scripts ask the program (<program> __complete ...) and complete per command — its subcommands, options and inherited global options, enum values, and values from a field's newcompletecallback.padroneLogger():--verbosecan be repeated (twice istrace), andshortFlags: trueadds-v,-vvand-q. Interceptors can declarecountoptions.padroneTracing(): passapi: { context, trace }from@opentelemetry/apisotracing.span()children and instrumented libraries are parented to the command's span.DEBUG=1orbuiltins: { autoOutput: { errorStack: true } }to print an error's stack andcausechain incli().serve()aborts a command'sctx.signalwhen the client disconnects, and MCP aborts a tool call onnotifications/cancelledor disconnect. The MCP stdio transport handles messages concurrently.-i/--interactiveis accepted, and ignored, on commands without interactive fields instead of failing as an unknown option.stdinfield makes the command async, so reading piped input no longer warns about a missing.async().--yes) are no longer rejected as unknown before prompting.dx-review.mdShow Bumped Packages (1)
npm:padroneTyping fixes and shorthands
defineCommand()take the name they're registered under, sorun(),api()andfind()resolve them, and they no longer break the typing of other commands.defineCommand<Context>()((c) => ...)types a command with the program's context.defineCommand<Context>(fn)is now a type error: it lost the command's type..context<T>()must be passed tocli(),eval(),run(),repl()andapi(). A.context(() => ...)transform on the program creates the context, so callers pass none.InferCommandworks for programs with a context.defineInterceptor(meta).provides<T>().factory(fn)type-checks thecontexthandlers pass tonext().MaybePromiseCommandResult,PadroneAPI,MaybePromiseandThenableare exported, so results can be exported fromdeclarationbuilds.stringify()args can leave out fields that have defaults..extend()takes several extensions:.extend(padroneJson(), padroneFormat())..describe(text)sets a command's description.run()andapi()run()checks args against the schema and applies its defaults. Invalid args return inargsResult.issues.run()andapi()no longer print results.api()takes{ context, signal }. Its functions throw on invalid args or a failing action instead of returningundefined.Command-line output
suggestionsare printed after the message.Missing required argument/Missing required optionandExpected number, got "abc".Unknown option: "x". Did you mean "--y"?.--yeson commandspadroneConfirm()may ask for, puts global options after the command's own, shows env variables inline as(env: APP_PORT), and shows variadic positionals as<files...>.a, b.sweep4-config.mdShow Bumped Packages (1)
npm:padroneFourth extension sweep: config and env
tool()calls can no longer pass--config/-c, which let a request make the program read, or import, any local file. It's now an unknown option for them.config getandconfig unsettake an option's alias or kebab-case name (dry-run), likeconfig setdoes.config listshows the values ofsensitiveoptions as[redacted].config pathandconfig editwork whenfileshas no JSON name, andconfig editcan create a YAML or TOML user config.nullin a nested config value unsets that option, as it does at the top level..envfiles:${VAR:-default}defaults can contain variables (${API:-http://${HOST}}), and multiline values in files with CRLF line endings no longer keep\r.global-args.mdShow Bumped Packages (1)
npm:padroneAdd
.globalArgs()Define options once for a command and every subcommand below it:
createPadrone('app').globalArgs(z.object({ verbose: z.boolean().optional() })). They are accepted before or after the subcommand name, merged into each command's typedargs, validated separately, and listed under "Global Options" in help and in MCP/serve input schemas. A subcommand overrides a global by defining a field of the same name, or extends the globals for its subtree with.globalArgs((inherited) => inherited.extend({...})).option-rules.mdShow Bumped Packages (1)
npm:padroneCounting, conflicting and implied options
count: trueon a number option counts repeated flags:-vvv→3.conflicts: ['table']rejects options used together, andimplies: { color: false }sets other options when one is used. Both are shown in help.--version,--color,--help,--config,--interactive,--timing,--no-update-check) no longer takes over a command's own option of the same name.dx-sample-4.mdShow Bumped Packages (1)
npm:padroneResults and running other commands
run()awaits an async action's result, likeeval():(await program.run('sync')).resultis the resolved value, and a rejected action is reported inerror. Results are typed as the awaited value, and the call as a promise when the action is async.ctx.run(name, args), which runs another command with this run's context and signal and resolves to its result.ctx.program.run()accepts args again (it rejected every args object).Typing
defineCommand().requires<T>()command is a type error at.command()when nothing providesT.ctx.contextis typed by the interceptor's.requires<T>().defineArgsMeta(schema, meta)types an arguments meta kept apart from.arguments()/.globalArgs(), with noas const..configure()callbacks used before.arguments()now get an error that says to call.configure()after.arguments().Parsing
[method] <url>) only takes a value when the required one still gets one:http https://xsetsurl.key=value:-q page=2 -q sort=asc.eval()) gives nothing instead of failing withPremature close.Help and errors
{"max":5}) instead of[object Object]; empty objects are left out.--json,-o,--config, …) are listed under Global Options, after the program's global args.Invalid value "nocolon" for "--header": …instead ofheader.0: ….<key=value>in help.Testing
testCli(program).cli(input)runs a command ascli()does: confirmations, printed errors and deprecation warnings.exitCode.Publish
The following packages will be published if merged:
padrone3.0.0npm