Skip to main content

life.txt

life.txt is a plain-text format for managing tasks, events, deadlines, reminders, habits, status / presence records, messages, notes, and journal / diary entries in a single human-readable file. Please refer to docs/en/life_txt_format_spec.md or docs/ja/life_txt_format_spec.md for the current grammar of life.txt.

lifetxt is a text-native, user-owned foundation for recording and using important information about a person's past, present, and future, across tools, interfaces, and AI providers. It is built around one durable record rather than one productivity category, so the interface you use today -- editor, CLI, TUI, Web, or AI -- can change without taking your data with it. See docs/en/philosophy.md (or docs/ja/philosophy.md) for the full philosophy and long-term vision.

Documentation

Use the format specification for file grammar and key semantics. Use the CLI guide for command compatibility, filters, output formats, and conversion rules.

Getting Started

lifetxt supports Python 3.10 or newer.

Want to see it work before installing anything of your own? lifetxt tour needs no config, no life.txt, and no setup:

python -m lifetxt tour

New to lifetxt for real? Start with init and doctor:

python -m lifetxt init                 # interactive: creates life.txt + .lifetxt.json
python -m lifetxt init --yes           # non-interactive: accepts all defaults
python -m lifetxt doctor               # checks your environment and files are set up correctly
python -m lifetxt check life.txt       # validate syntax after your first edits
python -m lifetxt summary life.txt     # see what init created
python -m lifetxt add "Buy milk ^tomorrow"  # capture your first real record
python -m lifetxt web                  # open the browser UI against it

init writes a starter life.txt (with #! self:, #! timezone:, and optionally #! project: directives) and a matching .lifetxt.json, prompting for your name, timezone, and default project. Pass --yes to skip every prompt and accept the defaults (self, UTC, no project) — useful in scripts and CI. doctor then reports pass/warn/fail checks for your Python version, optional dependencies (textual, watchdog, matplotlib, fzf), and config/life.txt file health, so you know what to install next. add is the beginner-facing spelling of quick/q; web starts the same server as serve and opens your browser to it. See section 16 ("tour, init, and doctor") of the CLI guide for the full flag reference.

Not sure which of lifetxt's many commands to reach for? lifetxt help gives a role-based index (Getting Started, Query, Projects, and more) plus guided paths for beginners, daily users, power users, AI clients, and administrators — lifetxt help beginner walks through the smallest useful loop, and lifetxt help <command> looks up any one command by name or alias. Add --json for a machine-readable capability catalog. See §1.1 of the CLI guide.

For the fastest introduction to what actually goes inside life.txt, see docs/en/getting-started.md: a five-minute Beginner / Minimal Profile that is a strict subset of the full format, so nothing you write there needs to change when you learn the rest.

Minimal life.txt

[ ] T Write_Report due:2026-06-12 project:university assignee:alice
[ ] E Seminar from:2026-06-08T13:00 to:2026-06-08T14:30 loc:university attendee:alice
[/] S Working from:2026-06-06T14:00 state:busy person:self
[ ] M "Review slides" sender:self recipient:alice notify_at:2026-06-06T09:00 channel:teams
[N] J "Research day" on:2026-06-23 mood:good tag:lab
| Read papers in the morning.
| Wrote parser tests in the afternoon.
[N] N Research_Memo project:research

More sample files are available in examples/:

Tools

This repository includes a dependency-free Python CLI:

python -m lifetxt check life.txt
python -m lifetxt demo --count 50 --date 2026-07-12 -o demo.life.txt
python -m lifetxt to-json life.txt --pretty
python -m lifetxt to-jsonl life.txt --open --type task -o open_tasks.jsonl
python -m lifetxt to-csv life.txt --type journal -o journal.csv
python -m lifetxt markdown life.txt --field all --format html -o markdown.html
python -m lifetxt import-ics google_calendar.ics -o life.txt --append --tag google
python -m lifetxt sync-ics --url-env LIFETXT_GOOGLE_CAL_ICS -o .generated/google_calendar.life.txt --cache-dir .cache/lifetxt --tag google
python -m lifetxt filter life.txt --open --type task -o open_tasks.life.txt
python -m lifetxt filter life.txt --open --type task --canonical -o canonical_tasks.life.txt
python -m lifetxt filter life.txt --assignee alice -o alice_items.life.txt
python -m lifetxt filter "projects/**/*.life.txt" --team research --tag-all urgent,review --exclude-tag archived
python -m lifetxt filter life.txt --after now --type event -o future_schedule.life.txt
python -m lifetxt filter life.txt --type status --person self -o my_status.life.txt
python -m lifetxt filter life.txt --type message --recipient alice -o alice_messages.life.txt
python -m lifetxt status life.txt
python -m lifetxt status life.txt --active
python -m lifetxt status life.txt --format json --pretty
python -m lifetxt notify life.txt --recipient self
python -m lifetxt notify life.txt --watch --interval 30
python -m lifetxt ids life.txt --assign --dry-run
python -m lifetxt ids "projects/**/*.life.txt" --assign --prefix item --dry-run
python -m lifetxt links life.txt --id task_report --direction incoming
python -m lifetxt agenda life.txt --from 2026-06-06T13:00 --to 2026-06-06T18:00
python -m lifetxt agenda life.txt --from 2026-06-06T13:00:30+09:00 --to 2026-06-06T18:00:00+09:00
python -m lifetxt agenda life.txt --around now --window 1w --format life -o agenda.life.txt
python -m lifetxt agenda life.txt --from 2026-06-06 --to 2026-06-06 --open
python -m lifetxt agenda life.txt --from 2026-06-06 --to 2026-06-06 --type task --project research
python -m lifetxt tui life.txt
python -m lifetxt fzf life.txt --open --type task --action done
python -m lifetxt timer start life.txt --id task_report
python -m lifetxt timer stop
python -m lifetxt stats life.txt --project research
python -m lifetxt git-hook status
python -m lifetxt completion bash
python -m lifetxt from-json life.json -o life.txt
python -m lifetxt from-jsonl life.jsonl -o life.txt
python -m lifetxt from-csv journal.csv -o journal.life.txt
python -m lifetxt serve life.txt --host 127.0.0.1 --port 8000
LIFETXT_API_TOKEN=change-me python -m lifetxt serve life.txt --host 0.0.0.0 --token-env LIFETXT_API_TOKEN
python -m lifetxt web life.txt                          # same server as `serve`, opens your browser
python -m lifetxt mcp life.txt
python -m lifetxt serve life.txt .generated/google_calendar.life.txt --write-file life.txt --read-only
python -m lifetxt config init -o .lifetxt.json
echo "Buy milk" | python -m lifetxt quick - --append life.txt
python -m lifetxt add "Buy milk @home #errand !high ^tomorrow" --append life.txt  # `add` is quick's beginner-facing alias
python -m lifetxt import google_calendar.ics -o life.txt --append --tag google  # infers --preset ics from the extension
python -m lifetxt import todoist_export.csv --preset todoist -o life.txt --append
python -m lifetxt done life.txt habit_exercise
python -m lifetxt complete life.txt task_water_plants

Once a release is published to PyPI (see Distribution Channels for the release automation and current status), the primary end-user install is:

pip install lifetxt
lifetxt check examples/minimal_life.txt

Until then, install as a command from a source checkout or a built wheel/sdist (see Stable Release Artifact Verification for building a wheel/sdist yourself):

python -m pip install .
lifetxt check examples/minimal_life.txt

Contributing to lifetxt itself, rather than just using it, needs an editable install instead (pip install -e .) so source edits take effect without reinstalling — see Development environment below.

Most file-reading commands accept multiple input paths, glob patterns, and directories containing life.txt-like .txt files. The filter, to-json, to-jsonl, to-csv, and markdown commands support item filters such as --open, --status, --type, --project, --tag, --tag-all, --exclude-tag, --user, --team, --person, --owner, --assignee, --attendee, --sender, --recipient, --detail, --text, --after, and --before. filter --format life preserves original matching item lines by default; use --canonical to regenerate normalized life.txt lines. Use person: for status / presence targets, assignee: for assigned work, owner: for accountability, and attendee: for event participants.

The import-ics command converts iCalendar .ics files, such as Google Calendar exports, to E event items. Timed events become from: / to:, all-day events become on:, participants become attendee:, and --append can add imported events to an existing life.txt. Imported calendar events include source:ics and uid: metadata. Convenience presets also import Markdown task lists, Todoist CSV exports, and GitHub Issues JSON exports:

python -m lifetxt import-ics tasks.md --preset markdown --project inbox
python -m lifetxt import-ics todoist.csv --preset todoist --tag todoist
python -m lifetxt import-ics github_issues.json --preset github --project repo

For periodic calendar sync, use sync-ics with a secret iCalendar URL stored in an environment variable. Keep manually edited items in life.txt, write ICS-derived items to a generated file such as .generated/google_calendar.life.txt, and pass both files to commands such as agenda or check. Use --merge-existing --soft-delete-missing when you want to preserve comments in the generated output while updating UID-backed records in place.

An optional FastAPI REST API and browser GUI are available with:

pip install -r requirements-web.txt
python -m lifetxt serve life.txt

For MCP-compatible AI clients, use the dependency-free stdio server:

python -m lifetxt mcp life.txt
python -m lifetxt mcp life.txt .generated/google_calendar.life.txt --write-file life.txt
python -m lifetxt serve life.txt --mcp

MCP tools cover item listing, item lookup, create/update/delete/done actions, agenda, graph, blockers, links, latest status, notifications, and message operations. With multiple input files, read tools scan all files and write tools modify only --write-file.

The Web UI uses a header Workspace for Dashboard, Items, Agenda, Timeline, Focus, Review, Messages, Team, Status, Notifications, Stats, Graph, Display, and Kiosk. The header includes a contextual View Guide for the active workspace, exposes the workspace switcher as a keyboard-friendly tablist, and provides a skip-to-content link for dense dashboards. Records open in centered modals with thread replies, dependency links, due quick actions, and Markdown previews. Review supports project/custom date filters and Markdown copy; Timeline preserves range=today|24h|week in the URL, shows guided empty states for ranges with no dated records, and marks records that overlap the selected range from earlier starts as ongoing. The Items view now has action-oriented empty states, and Team cards include a View items action that opens user=PERSON&open_only=true in the shared Items filter. Dashboard cards and theme tokens are configurable through web.dashboard.* and web.theme.*. Display mode has separate light/dark palettes. The + New editor exposes viewport-aware hover/focus help for status, type, title, and detail fields. Press Ctrl+K for the fuzzy command palette, recently opened records, undo history, exports, theme toggles, and common actions. Use --read-only for public or wall-display deployments and --write-file FILE when reading multiple files but writing to a single hand-maintained file.

Terminal-oriented helpers are available through tui, fzf, timer, stats, git-hook, and completion. fzf requires fzf or peco in PATH; the enhanced TUI can use the optional tui extra, while a dependency-free fallback is available by default. TUI supports configurable themes/keymaps, row selection, top-card summaries, an always-visible inspector panel, / search, detail display, mark-done, editor opening, and project filtering:

python -m lifetxt tui life.txt --theme dark --keymap vim --limit 15
python -m lifetxt tui life.txt --theme light --keymap arrows --agenda-window 1d

Dependency chains can also be exported for graph tooling:

python -m lifetxt deps life.txt --root task_report --format mermaid --depth 2
python -m lifetxt deps life.txt --blocked --format dot

The status command prints the latest S status / presence item for each person:. If person: is omitted, it is treated as self for this summary. The latest item is selected by the newest from: datetime. Use --person NAME to filter one person, --active to ignore finished logs with to:, or --format json / --format jsonl for machine-readable output.

The agenda command prints items related to a datetime range. from/to, notify_from/notify_to, and on are treated as intervals, while due, do, at, moved_to, and notify_at are treated as points or all-day spans. Use --around now --window 2h for a near-current-time view, or --format life, json, or jsonl for other output. Datetime values may include seconds, fractional seconds, and explicit timezones, such as 2026-06-06T13:00:30.25+09:00. Simple repeat: values (daily, weekly, monthly, yearly, weekdays) are expanded by agenda and time filters, with optional interval:, until:, and count:. A small dependency-free repeat:RRULE:... subset is also expanded for FREQ=DAILY|WEEKLY|MONTHLY|YEARLY, INTERVAL, COUNT, UNTIL, and daily/weekly BYDAY. Use --open for unfinished workflow items only, or combine filters such as --status, --type, --project, --tag, --tag-all, --user, --team, --person, --detail key=value, and --text. --window accepts seconds, minutes, hours, days, weeks, months approximated as 30 days, and years approximated as 365 days.

Message records use type M. They require sender: and recipient: and can use notify_at: for one notification time or notify_from: / notify_to: for a notification window. Use body: for longer message text when the title should stay short. The web API also provides /api/messages for convenient message listing and creation. /api/items/id/{id} and /api/messages/id/{id} support id-based access, while /api/messages/thread/{id} and /api/messages/id/{id}/reply support message threads via parent:.

Use python -m lifetxt notify life.txt --watch as a resident notification watcher. The browser GUI also has an Enable Notifications button that polls /api/notifications and uses browser notifications after permission is granted. Message notifications can be acknowledged with ack: or snoozed with snooze_until:. The watcher can persist seen notification IDs with notifications.state_file. The same notify command can send due notifications as a plain-text email batch:

python -m lifetxt notify life.txt --recipient self --email --email-to me@example.com --dry-run
python -m lifetxt notify life.txt --watch --once --state-file .generated/notifications.json
python -m lifetxt notify life.txt --watch --email --email-to me@example.com --interval 60

SMTP credentials are read from environment variables such as LIFETXT_SMTP_HOST, LIFETXT_SMTP_USER, and LIFETXT_SMTP_PASS; do not store SMTP passwords in life.txt content.

For release checks, run the fast smoke runner:

python scripts/smoke_test.py

External JSON config is available with --config FILE, LIFETXT_CONFIG, .lifetxt.json, or lifetxt.config.json. Use python -m lifetxt config init to create a starter file with default paths, web settings, message defaults, notification settings, user name, user/team/tag aliases, automatic ID settings, and iCalendar sync sources. With ids.auto: true, created items receive an id: when omitted; existing IDs are checked across configured input files and write_file before writing. Duplicate IDs are reported as warning W213. Use python -m lifetxt ids life.txt to audit present, missing, and duplicate IDs. Use ids --assign with --dry-run first to backfill IDs safely. Set ids.key / api.id_key to use a custom ID detail key.

Journal / diary records use type J; aliases include journal, diary, log, and entry. [N] is the recommended status. Use body: for long text; when the value spans multiple lines, write continuation lines beginning with | after the item. body: is also useful outside J for detailed tasks, event descriptions, messages, and notes. Use note: for short side notes and body: for long-form content.

Input assistance is available in both non-interactive and interactive modes:

python -m lifetxt assist --type task --title "Write Report" --due 2026-06-12 --project university --tag report
python -m lifetxt assist --type status --title "Working" --from 2026-06-06T14:00 --state busy --person self
python -m lifetxt assist --type message --title "Review Slides" --sender self --recipient alice --notify_at 2026-06-06T09:00
python -m lifetxt assist --type diary --title "Research day" --on 2026-06-23 --mood good --body "Read papers."
python -m lifetxt assist --type task --title "Write Report" --due 2026-06-12 --output new_life.txt
python -m lifetxt assist --type task --title "Write Report" --due 2026-06-12 --append life.txt
python -m lifetxt assist --interactive --append life.txt

In create mode, assist --output FILE appends the generated line to FILE. It does not overwrite existing content.

In interactive mode, enter ?, ?type, ?status, or ?detail at a prompt to show contextual help. At the detail prompt, use ?due or another ?key form for key-specific help. When the terminal supports it, Tab completes type, status, and detail-key candidates, and Up/Down recall previous inputs. Use --no-completion to disable the line editing helpers.

Existing data can be updated by line number or by id:. Updates are written in-place unless --output is specified.

python -m lifetxt assist --update life.txt --match-id task_001 --status done --done 2026-06-06
python -m lifetxt assist --update life.txt --line 3 --title "New Title" --add-detail tag=important
python -m lifetxt assist --update life.txt --match-id task_001 --remove-detail tag --output updated_life.txt

The check command reports syntax errors and semantic warnings such as invalid status/type values, malformed key:value details, note/journal status/type mismatches, date/time format issues, unusual key style, and event ranges where to: is earlier than from:. For type:S status / presence records, from: and state: are required. [/] is recommended when the record has no to:, and [x] is recommended when to: is present.

Items can link to other records by ID. Use parent: for hierarchy or message threads, ref: for a generic reference, depends_on: for prerequisites, blocks: for blocked downstream work, and related: for loose links. The check command warns about missing references, self references, and parent: cycles. It also warns when a completed item still depends on an open prerequisite. agenda and health surface open items blocked by open prerequisites. Use python -m lifetxt links life.txt to inspect these relationships. Use python -m lifetxt links life.txt --relation depends_on --relation blocks to focus on dependency edges.

Indented item lines can also express hierarchy. If a child line is indented and does not already have parent:, the parser infers parent: from the nearest less-indented ancestor that has an id:.

[ ] T Research_Project id:proj_research
  [ ] T Literature_Review id:task_lit
    [N] N Reading_Memo

Basic VS Code syntax highlighting and snippets are available in editors/vscode/lifetxt. See docs/en/editor.md for editor setup and the planned language-server direction.

JSON Shape

Details are always represented as arrays so repeated keys round-trip safely:

{
  "status": "[ ]",
  "type": "T",
  "title": "Create_Slides",
  "details": {
    "project": ["research"],
    "tag": ["important", "thesis"]
  }
}

CSV conversion uses status, type, and title columns plus detail-key columns. Repeated detail values are stored as JSON arrays inside cells, and multiline body: values are stored as quoted CSV cells.

Development environment

Every command below assumes python resolves to an interpreter that meets requires-python in pyproject.toml (currently 3.10 or newer). A system python older than that is common, and the failure is quiet rather than obvious: the suite still runs, but test modules that use newer syntax fail to import, so the run covers fewer tests than it appears to and its result is not evidence. tests/test_supported_runtime.py fails with an explicit message in that case instead of letting the run look successful.

If your default python is too old, work from a virtual environment created by a supported one. Creating it is not enough — enter it, or the commands further down still reach the interpreter this section is warning you about:

py -3.12 -m venv .venv            # Windows; use python3.12 -m venv .venv elsewhere
. .\.venv\Scripts\Activate.ps1    # Windows PowerShell; use . .venv/bin/activate elsewhere
python -m pip install -e ".[web,dev]"

Activation lasts for the shell session, and every command below assumes it is active. To skip it, call the interpreter by path instead (.venv/Scripts/python -m unittest discover); do not mix the two styles in one session, which is how a run ends up on the wrong interpreter without anyone noticing.

On Windows this also installs tzdata, the only mandatory runtime dependency. zoneinfo has no timezone database to read there, so without it no timezone resolves at all. Other platforms use the system database and do not receive it.

The web extra is what the Web API tests need; without it those tests skip, which again means a green run proves less than it looks like it does. The dev extra brings in httpx2, which starlette.testclient requires; a pip install -e ".[web]" alone (without dev) makes those tests fail outright rather than skip, since TestClient raises without it.

Run tests with:

python -m unittest discover
python -m unittest tests.test_supported_runtime   # confirms the interpreter first

Install developer tooling and run the configured commands with:

python -m pip install -e ".[dev]"
ruff format lifetxt tests scripts
ruff check lifetxt tests scripts

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lifetxt-1.0.2.tar.gz (1.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lifetxt-1.0.2-py3-none-any.whl (982.4 kB view details)

Uploaded Python 3

File details

Details for the file lifetxt-1.0.2.tar.gz.

File metadata

  • Download URL: lifetxt-1.0.2.tar.gz
  • Upload date:
  • Size: 1.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for lifetxt-1.0.2.tar.gz
Algorithm Hash digest
SHA256 6ee9d367c603dd8fc88be16b61536b188123ea3e9312f0fb6b6076ef75df901f
MD5 2f09f6c3cd0d8f893aaa776823e47811
BLAKE2b-256 9d015ddde95d529e6a908f48b81368547a22878de42e20126dfb5b1fa9c931d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for lifetxt-1.0.2.tar.gz:

Publisher: release.yml on Eruhitsuji/lifetxt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lifetxt-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: lifetxt-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 982.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for lifetxt-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 07f9dd4a98f9295c5dddeca44fb5cb096152a64d9695c6152de87824a711c164
MD5 a2ee79130a8d9df0172a142a64acfbb8
BLAKE2b-256 3ce8cab0de884e94439a2e7e97630e690ff0e34164d65530b9cf798910150325

See more details on using hashes here.

Provenance

The following attestation bundles were made for lifetxt-1.0.2-py3-none-any.whl:

Publisher: release.yml on Eruhitsuji/lifetxt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 files

1.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page