This document is a secondary overview of the current lifeos CLI.
Command-specific facts such as arguments, examples, constraints, and command notes must live in lifeos --help, lifeos <resource> --help, and lifeos <resource> <action> --help.
Use this document for cross-command guidance only. Do not treat it as the source of truth for resource-level command details.
The CLI follows one stable grammar:
lifeos <resource> <action> [arguments] [options]
The public command tree prefers:
- short resource names
- short action verbs such as
add,list,show,update, anddelete listas the main query entrypoint for structured resources- grouped namespaces such as
batchfor multi-record writes
Single-object versus multi-object rules: delete accepts one or more
identifiers (lifeos area delete <id>...) because deletion only needs
identity; show and update stay single-record because they carry or
return record-specific values. Multi-record mutations use the batch
namespaces and data batch-* commands, whose help cross-references the
single-object forms.
To avoid duplicate maintenance, the documentation boundary is:
- Help is the primary command reference.
- Repository docs summarize cross-resource concepts and operating rules.
- When command behavior changes, update help first.
- Only update this file when a cross-command model, workflow, or policy changes.
Practical rule:
- If a user needs to know how to run one command correctly, that information belongs in help.
The current CLI output stays intentionally simple and scriptable.
listcommands print compact summary rowsshowcommands print labeled fieldsaddandupdatecommands print short confirmation messages- public
deletecommands report soft-delete results only
list, search, and show read commands accept an opt-in --json flag that leaves the default text output untouched:
- JSON output is pretty-printed, preserves non-ASCII characters, and is emitted as one array of record objects for list-style commands
- commands that support
--countemit{"items": [...], "total_count": N}when--count --jsonare combined - timestamps render as explicit UTC ISO strings (for example
2026-04-10T12:00:00Z), UUIDs render as strings, and Decimal amounts render as strings so precision is preserved - JSON payloads expose the full underlying record fields; for example note content is not truncated or whitespace-normalized the way text summaries are
Aggregated read commands (schedule show/list, planning show) and config show
also accept --json; config show --json keeps database passwords masked unless
--show-secrets is passed.
The --json shape follows the Web API serialization conventions where the two surfaces overlap, so callers that already consume the API can reuse their field handling.
Install the published CLI:
uv tool install lifeos-cliInitialize local configuration:
lifeos initInspect the effective runtime configuration:
lifeos config showCheck database connectivity and migrations:
lifeos db ping
lifeos db upgradeThe CLI persists a small set of runtime preferences:
timezonelanguageday_starts_atweek_starts_onvision_experience_rate_per_hour
Time-oriented behavior follows these rules:
eventandtimelogdatetimes are stored in UTC-normalized form- CLI timestamp rendering uses the configured
timezone - date-based queries also use the configured
day_starts_at - weekly habit summaries use the configured
week_starts_on
The current command tree is organized around a few stable families:
- planning resources such as
area,vision,task,planning,note,person, andtag - scheduling and tracking resources such as
event,schedule,timelog,habit, andhabit-action - financial reality resources such as
finance - system, Web, and portability commands such as
init,config,db,web, anddata
finance uses nested namespaces (finance asset, finance tree, finance node,
finance snapshot, and finance rate-snapshot), each with the standard
add/list/show/update/delete actions. Command names follow the singular
person convention and the nested finance namespaces are the only supported
command shape.
data import --mode upsert --key <field> supports idempotent natural-key sync for area.name, vision.name, person.name, and habit.title: each row is matched against existing active records, updated when one match exists, and inserted otherwise (a fresh id is generated when the row has none). Ambiguous keys and missing key values are reported as row-level failures.
Use lifeos <resource> --help to enter one family and then follow the resource-level help into the action or namespace you need.
The CLI help tree is broad enough that manual spot checks are not sufficient for release review. Use the help audit script when reviewing command documentation:
uv run python scripts/audit_cli_help.pyThe script walks the parser tree, executes every discovered --help invocation, and renders a Markdown report with command output and failures. Use --path-prefix for focused reviews such as:
uv run python scripts/audit_cli_help.py --path-prefix "timelog stats"The same script emits a machine-readable command reference without spawning subprocesses:
uv run python scripts/audit_cli_help.py --format json
uv run python scripts/audit_cli_help.py --format json --path-prefix "task list"The JSON reference is locale-aware, includes the package version, and describes every command node with its summary, description, usage, examples, notes, and structured arguments (name, kind, metavar, choices, required, nargs, default). It is intended for agents and tooling that need the full command grammar in one fetch instead of walking --help one level at a time.
The same script renders a plain-text command tree that is committed as docs/cli-tree.md and kept current by a pre-commit check:
LIFEOS_LANGUAGE=en uv run python scripts/audit_cli_help.py --format tree --output docs/cli-tree.mdRegenerate the file whenever a command, argument, or summary changes; the
cli-tree-sync pre-commit hook fails when the artifact drifts.
Localized help should be reviewed through the same command surface by setting the runtime language preference or LIFEOS_LANGUAGE.
The public CLI is intentionally conservative.
- public
deletecommands only soft-delete records - public
deletecommands accept one or more identifiers and only soft-delete records - hard delete stays outside the public CLI
This boundary should remain stable as more resources are added.
If the caller is an agent or another automation layer:
- start from
listto discover identifiers - use
showbefore destructive or state-changing operations - treat help as the only authoritative command-level reference
- run
lifeos config showbefore writing human-authored payload fields - use
Preference languageas the payload language for titles, descriptions, and note content unless the human explicitly asks for another language - keep flows identifier-driven after discovery
- decide whether the record belongs to the human, the agent, or both before writing data
- prefer resource help and action help over repository docs whenever an operation depends on exact flags, scope rules, or examples