fractal.cli package#

Subpackages#

Submodules#

fractal.cli.main module#

Command-line interface for fractal.

fractal.cli.main.cli(**kwargs)[source]#

Run the fractal CLI.

Parameters:

kwargs (Any)

Return type:

None

fractal.cli.utils module#

Shared helpers for fractal CLI commands.

fractal.cli.utils.command(app, name, **kwargs)[source]#

Register a CLI command on app with error wrapping.

Parameters:
  • app (Typer)

  • name (str)

  • kwargs (Any)

Return type:

Callable

fractal.cli.utils.require_non_negative(**limits)[source]#

Reject negative numeric CLI options as BadParameter.

Each keyword maps a limit option’s name to its value (None is skipped); the first negative raises with that option’s flag spelling. Centralizes the >= 0 guard so every numeric --max-* cap is validated uniformly at the CLI boundary – unbounded is expressed by omitting the flag, never by a negative sentinel.

Parameters:

**limits (float | None) – Option name mapped to its value (e.g. max_depth=max_depth).

Raises:

typer.BadParameter – If any value is negative.

Return type:

None

fractal.cli.utils.parse_reserve_budget(value, max_cost, *, default='10%')[source]#

Resolve --reserve-budget to a USD amount.

The value is a USD number or N% of max_cost; when omitted it falls back to default (10% of max_cost), so a budget reserves a cleanup buffer by default, and with no max_cost there is no reserve. The reserve is not enforced – it only moves when the node enters reserve mode (the budget is treated as drained reserve_budget USD before max_cost is reached).

Parameters:
  • value (str | None) – The raw --reserve-budget string (USD or N%), or None to take default.

  • max_cost (float | None) – The node’s --max-cost in USD; required when value is an explicit reserve.

  • default (str) – Reserve applied when value is None (USD or N%).

Return type:

float | None

Returns:

The reserve in USD – default applied to max_cost when value is None, or None when neither value nor max_cost is set.

Raises:

typer.BadParameter – If an explicit value is given without max_cost, is not a number, is negative, or is >= 99% of max_cost.

class fractal.cli.utils.StreamRenderer[source]#

Bases: object

ANSI terminal renderer for parsed agent stream events.

The single CLI renderer over the seam’s normalized events – one instance per stream, passed as the render callback to Agent.stream (the loop’s pane rendering) and Node.chat so core never prints. Branches on kind only, never on the provider; session and cost facts render nothing (they are recorded, not displayed). Tracks the open text run (a delta without a trailing newline) so tool headers and closing summaries start below it, and close() ends a truncated stream on a fresh line with the -- $? placeholder summary. Every write flushes: piped stdout is block-buffered while the driving command’s stderr echoes are write-through, so an unflushed line would land out of order in a merged capture.

Parameters:

self (StreamRenderer)

Initialize StreamRenderer.

Parameters:

self (StreamRenderer)

close()[source]#

End the stream on a fresh line, settling the closing summary.

Called by the driving command after the stream drains – a truncated stream (killed before its result frame) otherwise leaves the cursor mid-line and shows no closing summary, so the -- $? placeholder marks the unaccounted turn. Idempotent, and resets for the next stream (the loop reuses one renderer across steps).

Parameters:

self (StreamRenderer)

Return type:

None

fractal.cli.utils.print_rows(rows, *, csv=False, columns=None)[source]#

Print rows as a formatted table or CSV.

Uses sys.stdout.isatty() to auto-detect format: formatted text table for terminals, CSV for pipes. The csv parameter enables CSV output.

Parameters:
  • rows (list[dict[str, Any]]) – List of row dicts.

  • csv (bool) – Output as CSV.

  • columns (list[str] | None) – Column names for the empty-result header (emitted in both formats so empty output is never ambiguous).

Return type:

None

fractal.cli.utils.print_json(rows, *, columns=None)[source]#

Print rows as a JSON array of objects.

The machine-readable counterpart to print_rows: one object per row, keys in columns order, and an empty result prints [] (never nothing), so parsers see one shape per listing.

Parameters:
  • rows (list[dict[str, Any]]) – List of row dicts.

  • columns (list[str] | None) – Key order for the row objects (default: each row’s own key order).

Return type:

None

fractal.cli.utils.init_node(path)[source]#

Resolve a Node for init (accepts repo root as-is).

When an agent runs init from inside its own worktree (_NODE set) with the default path, resolve to the caller’s repo root so the new node nests under the main repo rather than the worktree (the parent is resolved from _NODE in Node.init).

Parameters:

path (str | PathLike)

Return type:

Node

fractal.cli.utils.resolve_init_target(path)[source]#

Resolve the git-root-anchored node and project path for an init target.

fractal init/node init accept a repo root or a sub-project folder as path. The user node and every child must be anchored at the git root – Node.node_dir derives the <project>/ prefix from the .worktrees/.project cache, so anchoring at a sub-project folder would double the prefix. This resolves the target, then returns a Node at its git root plus the target’s project-relative path.

Parameters:

path (str | PathLike) – Repo root or sub-project folder (absolute or relative).

Return type:

tuple[Node, Path]

Returns:

(node, path) – a Node at the git root and the target’s path relative to it (. for the repo root).

Raises:

typer.BadParameter – If the target is a linked git worktree (outside the main repo root, so never a sub-project path).

fractal.cli.utils.resolve_node(path, *, check=True)[source]#

Resolve a Node instance from a path argument.

Parameters:
  • path (str | PathLike) – Worktree directory (absolute or relative).

  • check (bool) – Require an initialized node at the resolved path (mirrors resolve_target), so a user-facing command run outside a node fails cleanly instead of leaking a raw internal error. The pre-init private setter (config _set, which writes the very config.json this checks) passes check=False.

Return type:

Node

Returns:

Node bound to the resolved path.

Raises:

typer.BadParameter – If path is a repo root with active worktrees (should use the worktree path), or (when check) the resolved path is not an initialized node.

fractal.cli.utils.resolve_user_node(path)[source]#

Resolve the tree’s user (root) node from any checkout, by config not branch.

The tree-wide brake (pause/resume) must always anchor on the user node, but resolve_node() keys on the repo’s current branch – so on a non-init checkout (the user on their own branch while nodes run) it silently mis-scopes to a lone child or dies on two. Node.resolve_user() finds the config.json marked user: true and pins a Node to that branch, independent of the git checkout; this wrapper turns its no-fractal None into the CLI refusal.

Parameters:

path (str | PathLike) – Any path inside the repo.

Return type:

Node

Returns:

The user (root) node, branch-pinned.

Raises:

typer.BadParameter – If the repo has no user node (no fractal).

fractal.cli.utils.resolve_target(path, node=None)[source]#

Resolve the node to act on, anchored at the caller’s worktree.

path identifies the caller’s own worktree (default cwd); node, when given, selects another node by branch name within the same repo. Omitting node targets the caller’s own node.

Parameters:
  • path (str | PathLike) – Caller’s worktree directory (absolute or relative).

  • node (str | None) – Target node’s branch name, or None for the caller.

Return type:

Node

Returns:

Node bound to the resolved target worktree.

Raises:

typer.BadParameter – If node names a branch with no worktree, or the resolved target is not an initialized node.

fractal.cli.utils.resolve_ledger_target(path, node)[source]#

Resolve a cost-ledger target, answering for deleted branches.

A live target resolves normally as (node, None, None). A deleted branch fails resolution while its recorded history persists in the shared db, so it resolves through the caller as (caller, branch, latest_run) – how the fallback applies stays per command (remaining reports no budget without delegating; spent/breakdown substitute latest_run for an absent scope). The fallback accepts the same unique short names live resolution does: the registry rows that expansion consults die with the node, so the trailing segment expands against the recorded runs instead.

Parameters:
  • path (str | PathLike) – Caller’s worktree directory (absolute or relative).

  • node (str | None) – Target node’s branch name, or None for the caller.

Return type:

tuple[Node, str | None, int | None]

Returns:

(node, deleted, latest_run) – the resolved target, the deleted branch name (None for a live target), and the deleted branch’s latest recorded run id.

Raises:

typer.BadParameter – If resolution fails and the branch never recorded a run (there is no history to answer from), or a short name matches several live or recorded branches.

Module contents#

Command-line interface for fractal.