Modules#
An overview of the packages that make up nur.
The API reference below is generated automatically from the source docstrings.
CLI (nur.cli)#
Typer command-line interface: discovers project tasks and either runs one directly or launches the TUI.
CLI package for the project.
- nur.cli.format_list(registry)[source]#
Render the discovered tasks grouped by provider prefix.
- Parameters:
registry (Registry)
- Return type:
- nur.cli.main(argv=None)[source]#
Entry point: parse args with Typer, returning an int instead of exiting.
Typer/Click raise
SystemExitfor help, version, and every command exit; catching it here keepsmain’s int contract so it stays usable from tests and embedders. Passthrough args are handed to the command viactx.obj.
Discovery (nur.core.discovery)#
Walks the working directory and builds the task registry from every supported source file.
Registry (nur.core.registry)#
Holds discovered tasks and resolves a query to a single task, with ambiguity and close-match handling.
- exception nur.core.registry.AmbiguousTaskError(name, candidates)[source]#
Bases:
ResolutionError
Execution (nur.core.execution)#
Runs a resolved task’s command, propagating its exit code.
- class nur.core.execution.ProcessRunner[source]#
Bases:
objectRuns a command with combined output captured and streamed line-by-line.
Blocking; intended to be driven from a background thread by the TUI.
- nur.core.execution.run_direct(task, extra_args, cwd)[source]#
Run a task with inherited stdio; return the child’s exit code.
A natively-parsed provider (npm/PDM/poe) can surface a task whose runner binary is not installed. Rather than letting
FileNotFoundErrorescape as a traceback, report a controlled error and return127.
Shell (nur.core.shell)#
Quotes literal arguments for the shell that runs shell tasks.
- nur.core.shell.quote_for_cmd(argument)[source]#
Quote one argument for cmd.exe and the MSVC argv parser, only if needed.
Plain tokens stay bare, since cmd.exe built-ins such as
echoprint quotes verbatim. Anything with whitespace, quotes, or cmd.exe operators such as&or>is double-quoted so it stays one literal token. cmd.exe expands%NAME%even inside quotes, so each%is emitted as^%between quoted pieces: the caret keeps it literal, and the quote characters around it stop the text from naming a real variable.
Models (nur.core.models)#
Core data types shared across discovery, the registry, and execution.
Providers (nur.core.providers)#
One module per supported task source (make, npm, deno, composer, just, taskfile, pre-commit, pdm, poe, tox, mise, cargo-make, moon, xc, VS Code tasks, nox, mask, invoke).
- nur.core.providers.make.parse_targets(text)[source]#
Extract target names from Makefile text without executing anything.
Deliberately does NOT shell out to
make: the database dump (make -pRrq) still evaluates$(shell ...)/!=assignments while reading the file, so a repository’s Makefile could run arbitrary commands merely by discovering/listing tasks. Text parsing is safe, at the cost of not resolvingincludedirectives or computed targets.
- nur.core.providers.just.parse_justfile(text, source_file='justfile')[source]#
Extract recipes from
justfiletext without executing anything.Deliberately does NOT shell out to
just --dump: a pure text parse needs nojustbinary on PATH and cannot run recipe bodies. Descriptions come from the comment immediately preceding a recipe (skipping any attribute lines) or from an explicit[doc('...')]attribute. Grammar fidelity is intentionally partial: imports, string interpolation, and computed names are not resolved (see docs/adr/0001).
- nur.core.providers.task.parse_taskfile(text, source_file='Taskfile.yml')[source]#
Parse a Taskfile’s YAML text without executing anything.
Deliberately does NOT run
task --list: go-task evaluates dynamicsh:variables while loading/compiling the file, so listing could run repository-controlled commands during discovery. Reading the YAML directly is safe, at the cost of not resolvingincludes:or generated tasks.
- nur.core.providers.pre_commit.parse_pre_commit_config(text, source_file='.pre-commit-config.yaml')[source]#
Parse a pre-commit config without invoking
pre-commit.Only
repos[].hooks[]declares hooks. In particular, this deliberately does not walk arbitrary YAML mappings, whoseidkeys can be unrelated configuration.
- class nur.core.providers.tox.ToxProvider[source]#
Bases:
objectTask provider for tox test automation configurations.
- nur.core.providers.moon.parse_moon(text, source_file='moon.yml')[source]#
Parse a moon project’s
moon.ymltext without executing anything.Deliberately does NOT run
moon query tasks: enumerating tasks that way boots moon’s toolchain and resolves inherited config, which can run repository-controlled commands during discovery. Reading the YAML directly is safe, at the cost of not resolving inherited tasks from.moon/or project-qualified<project>:<task>addressing across the monorepo.
- nur.core.providers.xc.parse_xc(text, source_file='README.md')[source]#
Parse xc tasks out of a markdown text without executing anything.
Deliberately does NOT run
xc -s: xc executes task scripts, and listing should never be able to run repository-controlled commands. The grammar is documented at https://xcfile.dev/task-syntax/task-list/.
- class nur.core.providers.vscode.VsCodeProvider[source]#
Bases:
objectTask provider for VS Code’s version 2.0.0 tasks configuration.
- nur.core.providers.nox.parse_noxfile(text, source_file='noxfile.py')[source]#
Extract nox sessions from text by AST parsing, never importing it.
nox --listimports and executesnoxfile.pyto build its registry, so discovery reads@nox.session-decorated functions from the syntax tree instead. It only trusts straight-line noxfiles: module code may use imports, plain statements (assignment,del, expression,pass,def,class), andif/tryblocks made of those, where araiseends its branch. Sessions register only from top-leveldefstatements. Anything else (loops,with,match,assert,except*, a star import from another module) makes nox’s registry depend on control flow nur does not follow, so nothing is listed rather than a session nox may not register.python=[...]and@nox.parametrizevariants are surfaced under their base name (nox -s <name>still runs every variant).
Discover Invoke tasks by parsing Python, without importing project code.
- nur.core.providers.invoke.parse_tasks(text, source_file='tasks.py')[source]#
Read top-level decorated functions and literal names/aliases.
Imports are tracked in source order, never executed. Nested/conditional definitions, custom decorators, computed metadata and Collection wiring are not resolved. Task bodies and pre/post hooks remain Invoke’s concern.
- nur.core.providers.mask.parse_mask(text, source_file='maskfile.md', *, windows=False)[source]#
Parse mask commands out of a maskfile text without executing anything.
Mirrors mask’s own parser (https://github.com/jacobdeichert/mask): headings are commands, nested headings are subcommands, the last fenced block under a heading is its script, and the last blockquote its description. A subcommand is named by its path (
test lint) and runs asmask test lint. windows selects whetherpowershell/batch/cmdblocks count, as they do only in mask’s Windows build.
TUI (nur.tui)#
Textual terminal user interface for browsing and running tasks.
- class nur.tui.app.HeaderItem(prefix)[source]#
Bases:
ListItemInitialize a Widget.
- Parameters:
- can_focus = False#
Widget may receive focus.
- can_focus_children = True#
Widget’s children may receive focus.
- class nur.tui.app.NurApp(cwd, scan)[source]#
Bases:
App[None]Create an instance of an app.
- Parameters:
driver_class¶ – Driver class or None to auto-detect. This will be used by some Textual tools.
css_path¶ – Path to CSS or None to use the CSS_PATH class variable. To load multiple CSS files, pass a list of strings or paths which will be loaded in order.
watch_css¶ – Reload CSS if the files changed. This is set automatically if you are using textual run with the dev switch.
ansi_color¶ – Allow ANSI colors if True, or convert ANSI colors to RGB if False, None to use “ansi” parameter from themes.
cwd (Path)
scan (Callable[[], Registry])
- Raises:
CssPathError – When the supplied CSS path(s) are an unexpected type.
- CSS_PATH = 'app.tcss'#
File paths to load CSS from.
- BINDINGS = [('q', 'quit', 'quit'), ('escape', 'quit', 'quit'), ('slash', 'focus_filter', 'filter'), ('j', 'next', 'down'), ('k', 'prev', 'up'), ('r', 'run', 'run'), Binding(key='ctrl+c', action='interrupt', description='interrupt', show=True, key_display=None, priority=True, tooltip='', id=None, system=False, group=None), ('question_mark', 'toggle_help', 'help')]#
The default key bindings.