Read, query and edit a LifeOS / Obsidian PARA vault (notes, tasks, periodic notes, theme notes, tags, AI Wiki) from the command line via the `lifeos` CLI — h...
---
name: lifeos
description: "Read, query and edit a LifeOS / Obsidian PARA vault (notes, tasks, periodic notes, theme notes, tags, AI Wiki) from the command line via the `lifeos` CLI — headless, no Obsidian or Aino needed. Use when the user asks about their tasks or 待办; periodic notes — daily/weekly/monthly/quarterly/yearly review or 日记/周记/月记/季记/年记; theme notes / PARA — projects/areas/resources/archives or 项目/领域/资源/归档/主题; tags / theme tags or 标签/主题标签; the LifeOS AI Wiki / `.AI.md` topic synthesis pages or 整理主题 / 更新 AI Wiki; or wants to find/search notes, capture a thought, or check/update what's on their plate in their LifeOS vault."
---
# LifeOS
Drive a LifeOS vault through the `lifeos` CLI. It is **config-aware** — it reads
the user's real PARA folder names, periodic-note formats and section headers from
their own plugin / Aino settings — and **headless**, working directly on the vault
folder without Obsidian running. Query results match what the user sees in the app.
## Core concepts (核心概念)
LifeOS organises a vault as two complementary kinds of note. Knowing which one a
request is about tells you which command to reach for.
**Periodic notes (周期笔记)** — organised by **time**. One file per period; resolve
its path with `npx -y @life-os/cli <period>`. The longer the period the less predictable it is,
so longer periods are for goals and shorter ones for tasks:
- **yearly (年记)** / **quarterly (季记)** — long-term: **goal management (目标管理)**,
set the direction for the year / quarter.
- **monthly (月记)** / **weekly (周记)** — short-term: **task management (任务管理)**,
break those goals into this month's / week's tasks.
- **daily (日记)** — daily records: real-time capture of thoughts, tasks and time
tracking. Most capture lands here.
**Theme notes (主题笔记)** — organised by **subject**, usually via **PARA**. These live
in the user's PARA folders (see `npx -y @life-os/cli config`); reach them with `search`/`read`.
The later→earlier order is increasing actionability (archive → resource → area → project):
- **project (项目)** — most actionable: a concrete goal with a deadline, e.g. 「完成季度报告」.
- **area (领域)** — an ongoing responsibility to maintain, e.g. 「健康」「财务」.
- **resource (资源)** — a topic of interest or reference material, e.g. 「读书笔记」.
- **archive (归档)** — finished or inactive projects / areas / resources.
- PARA is just the common shape; a theme can be any subject (e.g. 「#节日」).
**The link between them — theme tags (主题标签)**: each theme note is identified by a
unique tag. Any task / fleeting note / file anywhere — including inside a daily or
other periodic note — that carries that tag is **automatically indexed** into the
theme note. This is what makes capture stress-free: jot with the right `#tag` now,
find it under the theme later.
- **Top-down (自上而下)**: tasks planned in a theme note surface in the daily note on
their planned date, so `tasks due=today` reflects project/goal plans.
- **Bottom-up (自下而上)**: a tagged thought or todo in the daily note is collected
back into the matching theme note via its tag.
So: when a user talks about a 项目/领域/资源/主题, work in the theme note; when they
talk about a day/week/month/quarter/year or "what's on my plate today", work in the
periodic note — and reuse the theme's tag so the two stay linked.
**AI Wiki (`.AI.md`)** — a third layer that sits **beside** the topic note as a
sibling `{filename}.AI.md` file. It is the LifeOS AI Wiki: a synthesised
summary page of what the vault knows about that topic, maintained
incrementally by this skill. Only **topic / index notes** get one — never
captures, dailies, meeting notes, or other one-off source files. When the
user says "整理一下 X 主题"、"更新 AI Wiki"、"看看 AI Wiki 怎么说", follow the
rules in [`references/ai-wiki.md`](references/ai-wiki.md): it covers source
scope, page schema, ingest / query / lint flows, and the concrete CLI
recipes that touch `7 索引/7. AI Wiki 索引.md` and `7 索引/AI Wiki 变更日志.md`.
## Invocation
Run the CLI with **`npx -y @life-os/cli`** — npx fetches the published package on
first use and `-y` skips the install prompt; nothing needs to be installed
globally. Every example below is written in that form.
## First moves
1. Run `npx -y @life-os/cli config` to confirm which vault and settings are in
effect. If it can't find a vault, ask the user for the path and pass
`vault=<path>`.
2. `npx -y @life-os/cli help` is the authoritative command list. For exhaustive
flags, output shapes and error codes, read
[`references/commands.md`](references/commands.md).
3. For LifeOS AI Wiki maintenance (`.AI.md` topic pages, the central index,
the changelog and lint checks), read
[`references/ai-wiki.md`](references/ai-wiki.md).
## Syntax
- Options are `key=value` (e.g. `tag=work`, `limit=10`). `--key=value` also works.
- Flags are bare words after `--` (e.g. `--json`) or plain (`overwrite`, `case`).
- Quote values with spaces: `vault="~/My Vault/LifeOS"`.
- Add `--json` whenever you need to parse output programmatically.
## Vault selection
This skill is installed **inside the user's vault**, so you normally run from
within it — the CLI auto-detects the vault from the current directory. Resolution
order (first match wins): `vault=` → `$LIFEOS_VAULT` → walk up from cwd for
`.obsidian/`/`.lifeos/` → the folder Aino last opened (fallback). Only pass
`vault=` when the user means a _different_ vault than the one you're in.
## Commands at a glance
```bash
# every command is invoked as: npx -y @life-os/cli <args>
npx -y @life-os/cli config # vault + effective settings (run this first)
npx -y @life-os/cli tasks [todo|done|all] # tasks; filters: tag= keyword= due=today|week|overdue limit=
npx -y @life-os/cli search query=<text> # type=file (default) | tag | content ; add `case` for content
npx -y @life-os/cli read file=<name>|path=<p> # print a note
npx -y @life-os/cli daily|weekly|monthly|quarterly|yearly # show the period note's path + whether it exists
npx -y @life-os/cli <period>:read # print the period note
npx -y @life-os/cli <period>:create # create the period note from its configured template
npx -y @life-os/cli <period>:append content=<t> # append (creates from template if missing)
npx -y @life-os/cli theme:create type=project|area|resource|archive|theme tag=<t> path=<p> # create a PARA note from its template
npx -y @life-os/cli append path=<p> content=<t> # append to an existing note
npx -y @life-os/cli create path=<p> [content=] # create a plain note (no template; add `overwrite` to replace)
npx -y @life-os/cli task done|todo ref=<file>:<n> # toggle a task by its file:line reference
```
**Template-aware creation:** `<period>:create`, `theme:create`, and the auto-create
inside `<period>:append` all render the user's **configured template** through the
same engine the plugin/Aino use — `{{snapshot:Project}}`, `{{if weekday}}`,
`{{date}}` etc. are expanded, and theme notes get their tag injected into
frontmatter. Plain `create path=…` stays template-free (use it for arbitrary notes).
## Recipes (chain commands like this)
**Morning review** — what's on my plate, then capture the plan:
```bash
npx -y @life-os/cli tasks due=today --json # today's open tasks
npx -y @life-os/cli tasks due=overdue --json # anything slipping
npx -y @life-os/cli daily:append section="日常记录" content="- 08:30 #计划 今天先做 ..."
```
**Quick capture** — "记一下:想法X" (drop a timestamped line into today's record section):
```bash
npx -y @life-os/cli daily:append section="日常记录" content="- 14:30 #摘抄 想法X" # echoes the resolved path
```
**Find then act** — never write blind:
```bash
npx -y @life-os/cli tasks keyword="季度报告" # locate the task, note its file:line
npx -y @life-os/cli task done ref="0. 周期笔记/2025/Daily/05/2025-05-30.md:14"
```
**Research a topic across the vault**:
```bash
npx -y @life-os/cli search query="超线性回报" type=content limit=20 # path:line + matching text
npx -y @life-os/cli read path="-1. 捕获/....md" # open the most relevant hit
```
**Weekly review**:
```bash
npx -y @life-os/cli weekly # confirm this week's note path / existence
npx -y @life-os/cli tasks done due=week # what got done
npx -y @life-os/cli weekly:append content="## 复盘\n..."
```
## Journaling (日记)
The daily note is where most capture lands. Do it precisely:
1. **Locate** — `npx -y @life-os/cli daily` shows today's path and `Exists`. Pass
`date=YYYY-MM-DD` for another day, `locale=` for weekday/month names.
2. **Insert in the right place** — append into the record section with
`section=<header>`, not the file tail. The header is the daily note's main
record heading (commonly `日常记录` / `Daily Record`); confirm it by reading a
recent daily note. `section=` lands the line at the **end of that section**
(e.g. before `习惯打卡` / `Habit`) and creates the section only if absent.
3. **Format** — default to `- HH:mm #tag 内容`. Use the current time from the
environment; the user is usually in their local timezone. Reuse existing tags —
`npx -y @life-os/cli search type=tag keyword=<x>` — rather than inventing
fine-grained ones; 1–3 tags unless the entry needs more.
4. **Polish, don't transcribe** — lightly smooth the user's words while keeping
their facts, stance, emotion and first-person voice; add no judgments, advice
or conclusions they didn't make. When they say `原文`/`逐字`/`原样`/`摘抄`/verbatim,
or paste a quote, keep it exact and only tidy Markdown.
5. **Creating a missing daily note** — just use `<period>:create` (or let
`<period>:append` auto-create it). The CLI renders the user's configured
template via the shared engine: `{{snapshot:Project}}` expands to the live PARA
index list, `{{if weekday}}`/`{{date}}`/etc. are resolved, and LifeOS query
blocks (`ProjectListByTime`, `TaskDueListByTime`) are kept verbatim for the
plugin to render at view time. No manual template rendering needed — the
resulting note matches what the plugin/Aino would create.
The same `section=` works on `weekly|monthly|...:append` and on plain
`append path=<p> section=<h>`, so you can log into any note's heading.
## Creating theme notes (项目/领域/资源/归档)
Use `theme:create` so the note is built from the PARA type's template and gets
its theme tag wired into frontmatter (so the theme index collects it):
```bash
# read config first for the real PARA folder names, then place the note yourself
npx -y @life-os/cli config
npx -y @life-os/cli theme:create type=project tag="项目/季度OKR" path="1. 项目/季度OKR/季度OKR.md"
```
- `type=` picks the template (`<type>TemplateFilePath` → `<typeDir>/Template.md` → built-in).
- `tag=` is the theme tag; it's injected into `tags`/`aliases` frontmatter.
- `path=` is yours to choose — the convention is `<paraDir>/<name>/<name>.md` (a
folder + same-named index note, which is what `{{snapshot}}` lists). Add
`overwrite` to replace.
## Upgrading the skill
The skill files inside `.agents/skills/lifeos/` should match your CLI version.
Run this after upgrading `@life-os/cli`:
```bash
npx -y @life-os/cli skill install
```
It copies the bundled SKILL.md + references into your vault's `.agents/skills/lifeos/`
from the npm package you just upgraded to — no manual download, no git clone.
## Writing safely
- Writes (`append`, `create`, `task`, `<period>:append`) take an **explicit
`path=` / `ref=`** — they never guess a note from a loose name, so you won't
write to the wrong same-named file. `search`/`tasks` first to get the exact
target, then write.
- `create` errors with _"A note already exists…"_ unless you pass `overwrite`.
- Periodic `:append` **echoes the resolved path** and creates the note if missing.
If `Exists: no` surprises you, the vault's format config may differ from how
existing notes were named — surface the path to the user rather than creating a
stray note.
## Interpreting results
- Tasks print `[ ]`/`[x] <text> (due … !priority #tags) — <file>:<line>`.
The `<file>:<line>` is the stable reference for `task done|todo`.
- `tasks` defaults to open (todo); pass `done`/`all` to widen. `due=` queries also
hide completed tasks by default.
- PARA folder names are the user's own (e.g. `1. 项目`) — see `npx -y @life-os/cli config`.
- Errors are human-readable and exit non-zero (e.g. file-not-found, already-exists).
## Performance
Index-backed commands (`tasks`, `search type=file|tag`) rebuild the index per run
(~1s on a ~5k-note vault); `search type=content` scans note bodies (~0.5s). Fine
for interactive use; avoid tight loops of many index queries.
## Scope
Reading, querying and editing note content (notes, tasks, periodic notes, PARA,
tags). **Not** in scope: Google Calendar / CalDAV sync, and the plugin's UI —
those live in the LifeOS plugin and Aino app.
don't have the plugin yet? install it then click "run inline in claude" again.
added explicit intent, structured inputs with edge cases (rate limits, auth, empty results, network timeouts), detailed 12-step procedure with inputs/outputs per step, decision points for periodic vs theme routing and capture logic, output contract with all result formats, and outcome signals covering task queries, search, reads, writes and config confirmation.
drive a lifeos vault through the lifeos cli. it's config-aware, reading your real para folder names, periodic-note formats and section headers from your plugin / aino settings, and headless, working directly on the vault folder without obsidian running. query results match what you see in the app.
use this skill when you need to read, query or edit your lifeos vault from the command line. reach for it when the user asks about their tasks or 待办; periodic notes (daily/weekly/monthly/quarterly/yearly review or 日记/周记/月记/季记/年记); theme notes / para (projects/areas/resources/archives or 项目/领域/资源/归档/主题); tags / theme tags or 标签/主题标签; the lifeos ai wiki / .AI.md topic synthesis pages or 整理主题 / 更新 ai wiki; or wants to find, search, capture a thought, or check/update what's on their plate in their lifeos vault. the skill is config-aware and headless, working without obsidian running.
vault location
vault=<path> parameter, $LIFEOS_VAULT env var, walk up from cwd for .obsidian/ or .lifeos/, last vault opened by aino.vault=<path> only when targeting a different vault than your current directory.cli setup
npx -y @life-os/cli (no global install needed; -y skips the install prompt).npx -y @life-os/cli config to confirm vault and settings.vault structure and settings
{{snapshot:Project}}, {{if weekday}}, {{date}} are resolved by the shared engine that powers the plugin and aino.references/ai-wiki.md (bundled in .agents/skills/lifeos/).external data (optional, context-dependent)
#工作, #健康) must already exist in your vault or be created with theme:create before tagging tasks or captures with them.due=today.edge cases and constraints
tasks, search type=file|tag) rebuild the index per run (about 1 second on a 5k-note vault).search type=content scans note bodies (about 0.5 seconds) and can be slow on very large vaults.path= or ref= to prevent accidental overwrites (never guesses a note from a loose name).Exists: no before creating missing daily notes.input: user asks to work with their lifeos vault. output: vault path, para folders, periodic-note format, effective settings.
run npx -y @life-os/cli config. this is mandatory first. if the cli can't find a vault, ask the user for the path and run with vault=<path>.
input: user's request (e.g. "what's on my plate today", "update the quarterly goals", "find notes on X topic"). output: determination of whether to query periodic notes (time-organised) or theme notes (subject-organised).
periodic notes are organised by time (yearly, quarterly, monthly, weekly, daily); use them for goals, tasks and daily records. theme notes are organised by subject via para (project, area, resource, archive) or custom tags; use them for topics. the two stay linked via theme tags. if the user mentions a day/week/month/quarter/year or "what's on my plate", work in periodic notes. if they mention a project, area, resource or named topic, work in theme notes.
input: optional filters: tag=, keyword=, due=today|week|overdue, limit=, done|todo|all, date=YYYY-MM-DD for another day, --json for parsing.
output: list of tasks with format [ ]/[x] <text> (due … !priority #tags) , <file>:<line>.
run npx -y @life-os/cli tasks [todo|done|all] with any filters. default filters to open tasks (todo); pass done or all to widen. due= queries hide completed tasks by default. note the <file>:<line> reference for later actions (e.g. toggling a task done).
input: search query, type (file, tag, content), optional case flag for content, limit=, --json for parsing.
output: list of matching files or tags with path:line + snippet (for content type).
run npx -y @life-os/cli search query=<text> type=file|tag|content limit=<n>. default type is file. use case for case-sensitive content search. never write blind: search first to get the exact path or tag, then act.
input: file name or full path. output: note content.
run npx -y @life-os/cli read file=<name> or read path=<p>. use this before editing to avoid overwriting unintended content. for periodic notes, run npx -y @life-os/cli <period> (e.g. daily, weekly) to check the path and whether the note exists, then npx -y @life-os/cli <period>:read to print it.
input: period (daily, weekly, monthly, quarterly, yearly), optional date (e.g. date=2025-05-30), optional section header (e.g. section="日常记录"), optional content, overwrite flag if replacing.
output: resolved path, echoed after append or create.
for a daily note: run npx -y @life-os/cli daily to confirm the path, then npx -y @life-os/cli daily:append section="日常记录" content="- HH:mm #tag 内容". if the note doesn't exist, :append auto-creates it from the configured template. use section= to append into the right record heading, not the file tail. the section is created only if absent. pass date=YYYY-MM-DD to target another day.
for a missing daily note: run npx -y @life-os/cli daily:create to create it from the configured template (renders {{snapshot:Project}}, {{if weekday}}, etc.). no manual template rendering needed.
input: para type (project, area, resource, archive, or theme), theme tag (e.g. tag="项目/季度OKR"), file path (e.g. path="1. 项目/季度OKR/季度OKR.md"), optional overwrite flag.
output: created note with template rendered and theme tag injected into frontmatter.
run npx -y @life-os/cli theme:create type=<t> tag=<tag> path=<p>. read config first to get the real para folder names. the tag is injected into frontmatter so the theme index collects it. convention is <paraDir>/<name>/<name>.md (folder + same-named index note). pass overwrite to replace an existing note.
input: optional time (use current time from environment), optional tags (reuse existing ones from search type=tag), entry text.
output: entry logged in the daily record section, resolved path echoed.
run npx -y @life-os/cli daily:append section="日常记录" content="- HH:mm #tag 内容". format as - HH:mm #tag 内容 by default. reuse existing tags (1 to 3 unless the entry needs more) rather than inventing fine-grained ones; get them via npx -y @life-os/cli search type=tag keyword=<x>. polish the user's words lightly while keeping facts, stance, emotion and first-person voice; add no judgments or advice they didn't make. when they say 原文/逐字/原样/摘抄 or paste a quote, keep it exact and only tidy markdown.
input: task reference in format <file>:<line> (from a prior tasks query result).
output: task marked done or undone.
run npx -y @life-os/cli task done ref="<file>:<line>" or task todo ref="<file>:<line>". use the exact reference from the earlier tasks query result; never guess or construct a reference manually.
input: file path, optional section header, content. output: content appended, resolved path echoed.
run npx -y @life-os/cli append path=<p> section=<h> content=<t>. if section= is provided, the content is appended at the end of that heading (creates the section only if absent). without section=, appends to the file tail.
input: file path, optional content, optional overwrite flag. output: created note.
run npx -y @life-os/cli create path=<p> [content=]. this does not render a template (unlike <period>:create or theme:create). pass overwrite to replace an existing note. use for arbitrary notes outside the structured periodic / para system.
input: user upgrades @life-os/cli npm package.
output: skill files in .agents/skills/lifeos/ synced with the new cli version.
run npx -y @life-os/cli skill install after upgrading @life-os/cli. it copies the bundled SKILL.md and references from the npm package into your vault's .agents/skills/lifeos/ directory , no manual download or git clone.
if the user mentions a specific day/week/month/quarter/year or "what's on my plate today":
tasks due=<period> or run <period>:read to see the current state. use <period>:append to add entries.else if the user mentions a project, area, resource, topic name or custom theme tag:
search query=<name> type=file or search type=tag keyword=<name> to find the note, then read path=<p> to open it. use theme:create to set up a new theme note, or append path=<p> to add content to an existing one.if the vault path is ambiguous or the cli can't auto-detect it:
vault=<path> to all commands.if a periodic note doesn't exist and the user wants to read or append to it:
<period> (e.g. daily) first , it echoes Exists: no. then either run <period>:create to create it from the template, or let <period>:append auto-create it. do not create a stray note manually.if a search or task query returns zero results:
theme:create) or check spelling / tags. don't guess or invent alternatives.if the user wants to capture a thought or task into their daily note:
daily:append with the section="日常记录" (or your vault's configured record header). never append to the file tail or the wrong section. use the current time from the environment (user is in their local timezone). reuse existing tags rather than inventing new ones.if the user says 原文/逐字/原样/摘抄 or pastes a quote:
if the user asks to update or maintain the ai wiki (.AI.md topic pages, central index, changelog):
references/ai-wiki.md (bundled in .agents/skills/lifeos/). it covers source scope, page schema, ingest, query and lint flows, and the concrete cli recipes that touch 7 索引/7. AI Wiki 索引.md and 7 索引/AI Wiki 变更日志.md.if the cli can't find a note even after searching:
if a write would overwrite an existing note:
overwrite is passed. respect this guard. always confirm with the user before adding overwrite.task queries
[ ]/[x] <text> (due … !priority #tags) , <file>:<line>, one per line.<file>:<line> is the stable reference for task done|todo.--json to get structured output for parsing.search results
file: list of file paths matching the query.tag: list of tags matching the query.content: list of path:line + matching snippet, up to limit=<n>.--json for structured output.read output
period path queries
<resolved-path> and Exists: yes|no.append / create / task toggle
config output
1. 项目), periodic-note format, section headers, effective settings.ai wiki maintenance
7 索引/7. AI Wiki 索引.md (central index), 7 索引/AI Wiki 变更日志.md (changelog), and .AI.md sibling files next to topic notes.references/ai-wiki.md for ingest, query and lint recipes.[ ] <text> (due … !priority #tags) , <file>:<line>, matching what appears in the plugin/aino.tasks to verify the change.<paraDir>/<name>/<name>.md), so the theme index collects it.