fractal.cli package#
Subpackages#
- fractal.cli.cmd package
- Submodules
- fractal.cli.cmd.channel module
- fractal.cli.cmd.config module
- fractal.cli.cmd.cost module
- fractal.cli.cmd.db module
- fractal.cli.cmd.event module
- fractal.cli.cmd.fractal module
- fractal.cli.cmd.node module
node_init()node_start()node_finish()node_stop()node_pause()node_resume()node_kill()node_merge()node_delete()node_reconcile()node_retire()node_unretire()node_attach()node_status()node_diff()node_reseed()node_list()node_activity()node_approve()node_pending()node_chat()node_update()node_loop()node_launch()node_seed()node_scope()
- fractal.cli.cmd.plan module
- fractal.cli.cmd.radio module
- fractal.cli.cmd.time module
- Module contents
Submodules#
fractal.cli.main module#
Command-line interface for fractal.
fractal.cli.utils module#
Shared helpers for fractal CLI commands.
- fractal.cli.utils.command(app, name, **kwargs)[source]#
Register a CLI command on
appwith error wrapping.A command error prints
Error: <message>on stderr and exits 2, beside typer’s own usage errors, so exit 1 is left to mean exactly the command’s own nonzero outcome and a script gating on one can never read a failed run as the other.- 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 (
Noneis skipped); the first negative raises with that option’s flag spelling. Centralizes the>= 0guard 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.require_timestamp(**instants)[source]#
Reject non-ISO-8601 timestamp CLI options as
BadParameter.Each keyword maps an instant option’s name to its value (
Noneis skipped). The stored instants are ISO 8601 strings and the filters compare them lexicographically, so an unparseable value is not an error downstream – it silently empties the listing (anything sorting above the rows) or silently filters nothing (anything below), and a mistyped--sincebecomes indistinguishable from an empty mailbox. A bare date is accepted: it sorts as the prefix of that day’s first instant, which is exactly the cut it names.- Parameters:
**instants (
str|None) – Option name mapped to its value (e.g.since=since).- Raises:
typer.BadParameter – If any value is not an ISO 8601 date or timestamp.
- Return type:
None
- class fractal.cli.utils.StreamRenderer[source]#
Bases:
objectANSI terminal renderer for parsed agent stream events.
The single CLI renderer over the seam’s normalized events – one instance per stream, passed as the
rendercallback toAgent.stream(the loop’s pane rendering) andNode.chatso core never prints. Branches onkindonly, 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, andclose()ends a truncated stream on a fresh line with the em-dash$?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 em-dash
$?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. Thecsvparameter 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 incolumnsorder, 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
Nodefor init (accepts repo root as-is).When an agent runs init from inside its own worktree (
_NODEset) 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_NODEinNode.init).- Parameters:
path (
str|PathLike)- Return type:
- fractal.cli.utils.resolve_init_target(path)[source]#
Resolve the git-root-anchored node and project path for an init target.
fractal init/node initaccept a repo root or a sub-project folder aspath. The user node and every child must be anchored at the git root –Node.node_dirderives the<project>/prefix from the.worktrees/.projectcache, so anchoring at a sub-project folder would double the prefix. This resolves the target, then returns aNodeat 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)– aNodeat 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), or a directory below a node worktree’s root (the sub-project would be lost).
- fractal.cli.utils.resolve_node(path, *, check=True)[source]#
Resolve a
Nodeinstance from a path argument.- Parameters:
path (
str|PathLike) – Worktree directory (absolute or relative).check (
bool) – Require an initialized node at the resolved path (mirrorsresolve_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 veryconfig.jsonthis checks) passescheck=False.
- Return type:
- Returns:
Node bound to the resolved path.
- Raises:
typer.BadParameter – If
pathis a repo root with active worktrees (should use the worktree path), or (whencheck) the resolved path is not an initialized node.
- fractal.cli.utils.resolve_sender(path)[source]#
Resolve the acting sender:
--pathwhen given, else the calling node.The loop exports
_NODEfor the node whose loop is running, so a production send attributes itssenderto that node wherever the agent’s CLI call runs from (a detached step’s cwd is not a node identity); an explicit--pathstill wins – an operator acting as a node from outside it.- Parameters:
path (
str|None) – Explicit worktree directory, orNonefor the default.- Return type:
- Returns:
Node the message’s
senderattributes to.- Raises:
typer.BadParameter – If the exported
_NODEdoes not name an initialized node (a stale or mistyped export).
- fractal.cli.utils.resolve_headless(headless, node)[source]#
Resolve the launch backend: flag, else
FRACTAL_HEADLESS, else the record.An explicit
--headless/--tmuxwins and re-records the backend. Otherwise the exportedFRACTAL_HEADLESSdecides – the loop derives it for every seat from the parent’s own record, so a delegated child start follows its parent’s backend. With neither set, the node’s.headlessmarker names the backend it last launched with (tmux for a node that has never run headless).- Parameters:
headless (
bool|None) – The--headless/--tmuxflag, orNonewhen not passed.node (
Node) – Resolved launch target, whose recorded backend is the default.
- Return type:
bool- Returns:
Whether the launch runs headless.
- Raises:
typer.BadParameter – If
FRACTAL_HEADLESScarries anything buttrueorfalse(a broken seat env refuses cleanly, never coerces into a backend choice).
- fractal.cli.utils.resolve_user_node(path, name=None)[source]#
Resolve a tree’s user (root) node from any checkout, by config not branch.
The tree-wide verbs (
pause/resume/track/…) must always anchor on the user node, butresolve_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 theconfig.jsonmarkeduser: truefor the named tree (or the one owning the caller’s branch) and pins aNodeto that branch, independent of the git checkout; this wrapper turns its no-such-treeNoneinto the CLI refusal.- Parameters:
path (
str|PathLike) – Any path inside the repo.name (
str|None) – Root branch of the tree to act on;Noneinfers it from the caller’s branch.
- Return type:
- Returns:
The tree’s user (root) node, branch-pinned.
- Raises:
typer.BadParameter – If the repo has no such tree, or several trees leave the caller’s checkout ambiguous.
- fractal.cli.utils.resolve_target(path, node=None)[source]#
Resolve the node to act on, anchored at the caller’s worktree.
pathidentifies the caller’s own worktree (default cwd);node, when given, selects another node by branch name within the same repo. Omittingnodetargets the caller’s own node.- Parameters:
path (
str|PathLike) – Caller’s worktree directory (absolute or relative).node (
str|None) – Target node’s branch name, orNonefor the caller.
- Return type:
- Returns:
Node bound to the resolved target worktree.
- Raises:
typer.BadParameter – If
nodenames 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 (remainingreportsno budgetwithout delegating;spent/breakdownsubstitutelatest_runfor 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, orNonefor the caller.
- Return type:
tuple[Node,str|None,int|None]- Returns:
(node, deleted, latest_run)– the resolved target, the deleted branch name (Nonefor 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.