lifeos-cli 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +275 -0
- package/dist/lifeos.mjs +197 -6
- package/logo.svg +5 -0
- package/package.json +16 -4
- package/scripts/postinstall.mjs +115 -0
package/README.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/MichielMAnalytics/lifeos/main/packages/cli/logo.svg" alt="LifeOS" width="320" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h3 align="center">Personal Life Operating System</h3>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Manage tasks, goals, journals, day plans, weekly plans, ideas, thoughts, wins, resources, reminders, and reviews — all from your terminal.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/lifeos-cli"><img src="https://img.shields.io/npm/v/lifeos-cli.svg" alt="npm version" /></a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/lifeos-cli"><img src="https://img.shields.io/npm/l/lifeos-cli.svg" alt="license" /></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g lifeos-cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
On first install, the CLI will offer to install agent skills for Claude Code or Codex.
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
lifeos config set-url <your-convex-site-url>
|
|
30
|
+
lifeos config set-key <your-api-key> # lifeos_sk_...
|
|
31
|
+
lifeos whoami # verify it works
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Generate an API key from your LifeOS dashboard settings page.
|
|
35
|
+
|
|
36
|
+
## Agent Skills
|
|
37
|
+
|
|
38
|
+
LifeOS ships with embedded skills that let AI coding agents (Claude Code, Codex) manage your LifeOS hands-free.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
lifeos skills install # install for Claude Code (default)
|
|
42
|
+
lifeos skills install --agent codex # install for Codex
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### `/lifeos-init`
|
|
46
|
+
|
|
47
|
+
The init skill walks your agent through setting up LifeOS: connecting the CLI, learning about your goals and routines, creating your first goals and tasks, and setting up daily rhythms. Just type `/lifeos-init` in your agent.
|
|
48
|
+
|
|
49
|
+
After setup, your agent can:
|
|
50
|
+
- Pull your morning briefing and summarize your day
|
|
51
|
+
- Capture ideas, thoughts, and wins as you mention them
|
|
52
|
+
- Write your evening journal and log wins
|
|
53
|
+
- Run weekly reviews and help plan the next week
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Commands
|
|
58
|
+
|
|
59
|
+
Every command supports `--json` for machine-readable output. IDs can be passed as full Convex IDs or short 8-character prefixes (e.g. `ks7bgmwf`).
|
|
60
|
+
|
|
61
|
+
### Auth & Config
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
lifeos whoami Show current authenticated user
|
|
65
|
+
lifeos config set-url <url> Set the API server URL
|
|
66
|
+
lifeos config set-key <key> Set the API key
|
|
67
|
+
lifeos config show Display current config (URL + masked key)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Tasks
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
lifeos task list [options] List tasks
|
|
74
|
+
-s, --status <status> Filter: todo, done, dropped
|
|
75
|
+
-d, --due <due> Filter: today, tomorrow, week, overdue, all
|
|
76
|
+
|
|
77
|
+
lifeos task create <title> [options] Create a task
|
|
78
|
+
-d, --due <date> Due date (YYYY-MM-DD)
|
|
79
|
+
-p, --project <id> Link to project
|
|
80
|
+
-g, --goal <id> Link to goal
|
|
81
|
+
-n, --notes <notes> Add notes
|
|
82
|
+
|
|
83
|
+
lifeos task show <id> Show task details
|
|
84
|
+
lifeos task complete <id> Mark task as done
|
|
85
|
+
lifeos task update <id> [options] Update a task
|
|
86
|
+
-t, --title <title> New title
|
|
87
|
+
-d, --due <date> Due date
|
|
88
|
+
-n, --notes <notes> Notes
|
|
89
|
+
-g, --goal <id> Goal ID
|
|
90
|
+
|
|
91
|
+
lifeos task delete <id> Delete a task
|
|
92
|
+
lifeos task bulk-complete <ids...> Mark multiple tasks as done
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Projects
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
lifeos project list [options] List projects
|
|
99
|
+
-s, --status <status> Filter: active, completed, archived
|
|
100
|
+
|
|
101
|
+
lifeos project create <title> [options] Create a project
|
|
102
|
+
-d, --description <text> Description
|
|
103
|
+
|
|
104
|
+
lifeos project show <id> Show project details
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Goals
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
lifeos goal list [options] List goals
|
|
111
|
+
-q, --quarter <quarter> Filter by quarter (e.g. 2026-Q2)
|
|
112
|
+
-s, --status <status> Filter: active, completed, dropped
|
|
113
|
+
|
|
114
|
+
lifeos goal create <title> [options] Create a goal
|
|
115
|
+
-t, --target-date <date> Target date (YYYY-MM-DD)
|
|
116
|
+
-q, --quarter <quarter> Quarter (e.g. 2026-Q2)
|
|
117
|
+
-d, --description <desc> Description
|
|
118
|
+
|
|
119
|
+
lifeos goal show <id> Show goal details
|
|
120
|
+
lifeos goal health [id] Show health for one goal or all active goals
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Journal
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
lifeos journal [date] Show journal entry (default: today)
|
|
127
|
+
lifeos journal write [options] Write today's journal entry
|
|
128
|
+
--mit <text> Most Important Thing
|
|
129
|
+
--p1 <text> Priority 1
|
|
130
|
+
--p2 <text> Priority 2
|
|
131
|
+
--notes <text> Notes
|
|
132
|
+
|
|
133
|
+
lifeos journal wins [date] List wins for a date (default: today)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Day Plans
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
lifeos plan today Show today's plan
|
|
140
|
+
lifeos plan tomorrow Show tomorrow's plan
|
|
141
|
+
lifeos plan set <date> [options] Create or update a day plan
|
|
142
|
+
-w, --wake <time> Wake time (HH:MM)
|
|
143
|
+
--mit <taskId> MIT task ID
|
|
144
|
+
--p1 <taskId> P1 task ID
|
|
145
|
+
--p2 <taskId> P2 task ID
|
|
146
|
+
|
|
147
|
+
lifeos plan complete-mit Mark MIT as done for today
|
|
148
|
+
lifeos plan complete-p1 Mark P1 as done for today
|
|
149
|
+
lifeos plan complete-p2 Mark P2 as done for today
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Weekly Plans
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
lifeos week [week-start] Show weekly plan (default: current Monday)
|
|
156
|
+
lifeos week create [options] Create weekly plan for this week
|
|
157
|
+
-t, --theme <theme> Week theme
|
|
158
|
+
|
|
159
|
+
lifeos week score <1-10> Set review score for this week
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Quick Capture
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
lifeos idea <content> [options] Capture an idea
|
|
166
|
+
-a, --actionability <level> high, medium, or low
|
|
167
|
+
|
|
168
|
+
lifeos thought <content> [options] Capture a thought
|
|
169
|
+
-t, --title <title> Optional title
|
|
170
|
+
|
|
171
|
+
lifeos win <content> Record a win
|
|
172
|
+
|
|
173
|
+
lifeos resource <title> [options] Save a resource
|
|
174
|
+
-u, --url <url> URL
|
|
175
|
+
-t, --type <type> article, tool, book, video, other
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Reviews
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
lifeos review list [options] List reviews
|
|
182
|
+
-t, --type <type> Filter: daily, weekly, monthly, quarterly
|
|
183
|
+
|
|
184
|
+
lifeos review daily Trigger daily review
|
|
185
|
+
lifeos review weekly Trigger weekly review
|
|
186
|
+
lifeos review show <id> Show review details
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Reminders
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
lifeos reminder list [options] List reminders
|
|
193
|
+
-s, --status <status> Filter: pending, delivered, snoozed, done
|
|
194
|
+
|
|
195
|
+
lifeos reminder create <title> [options] Create a reminder
|
|
196
|
+
-a, --at <datetime> Scheduled time (ISO datetime)
|
|
197
|
+
-b, --body <body> Reminder body
|
|
198
|
+
|
|
199
|
+
lifeos reminder snooze <id> [options] Snooze a reminder
|
|
200
|
+
-m, --minutes <min> Duration in minutes (default: 60)
|
|
201
|
+
|
|
202
|
+
lifeos reminder done <id> Mark reminder as done
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Search
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
lifeos search <query> [options] Search across all entities
|
|
209
|
+
-t, --type <type> Filter: tasks, goals, ideas, journal, resources
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Triggers
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
lifeos trigger <name> Fire a named trigger
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Available triggers:
|
|
219
|
+
|
|
220
|
+
| Trigger | Description |
|
|
221
|
+
|---------|-------------|
|
|
222
|
+
| `morning-briefing` | Pull today's plan, tasks, and reminders |
|
|
223
|
+
| `daily-review` | Summarize the day's activity |
|
|
224
|
+
| `weekly-review` | Summarize the week with stats |
|
|
225
|
+
| `overdue-triage` | Surface overdue tasks for triage |
|
|
226
|
+
| `reminder-check` | Check pending reminders |
|
|
227
|
+
| `goal-health` | Health check across all active goals |
|
|
228
|
+
|
|
229
|
+
### Dashboard Config
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
lifeos dashboard config Show current dashboard configuration
|
|
233
|
+
lifeos dashboard nav-mode <mode> Set nav mode: sidebar or header
|
|
234
|
+
lifeos dashboard nav-order <pages...> Set page order (e.g. today tasks goals)
|
|
235
|
+
lifeos dashboard hide <page> Hide a page from navigation
|
|
236
|
+
lifeos dashboard show <page> Unhide a page
|
|
237
|
+
lifeos dashboard preset <page> <preset> Set page preset
|
|
238
|
+
lifeos dashboard presets <page> List available presets for a page
|
|
239
|
+
lifeos dashboard reset Reset dashboard to defaults
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Undo
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
lifeos undo Undo the last mutation
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Daily Rhythm
|
|
251
|
+
|
|
252
|
+
LifeOS is built around the **MIT + P1 + P2** priority system:
|
|
253
|
+
|
|
254
|
+
- **MIT** — Most Important Thing. The one task that makes your day a success.
|
|
255
|
+
- **P1** — Priority 1. Important but secondary.
|
|
256
|
+
- **P2** — Priority 2. Nice to get done.
|
|
257
|
+
|
|
258
|
+
Each day plan has a wake time, your three priorities linked to tasks, and optional time-block schedule. Journals track reflections with the same MIT/P1/P2 structure plus wins.
|
|
259
|
+
|
|
260
|
+
## Architecture
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
lifeos-cli
|
|
264
|
+
├── dist/lifeos.mjs Single-file bundle (ships to npm)
|
|
265
|
+
├── skills/ Embedded agent skills
|
|
266
|
+
│ └── lifeos-init/ Setup & onboarding skill
|
|
267
|
+
└── scripts/
|
|
268
|
+
└── postinstall.mjs Auto-installs skills on npm install -g
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The CLI talks to a Convex backend via HTTP API, authenticated with API keys (`Bearer lifeos_sk_...`). It's part of the [LifeOS monorepo](https://github.com/MichielMAnalytics/lifeos) which also includes the real-time dashboard and shared type definitions.
|
|
272
|
+
|
|
273
|
+
## License
|
|
274
|
+
|
|
275
|
+
MIT
|
package/dist/lifeos.mjs
CHANGED
|
@@ -3236,7 +3236,7 @@ var planCommand = new Command("plan").description("Manage day plans");
|
|
|
3236
3236
|
planCommand.command("today").description("Show today's plan").action(async () => {
|
|
3237
3237
|
try {
|
|
3238
3238
|
const client = createClient();
|
|
3239
|
-
const res = await client.get(`/api/v1/plans/${todayStr2()}`);
|
|
3239
|
+
const res = await client.get(`/api/v1/day-plans/${todayStr2()}`);
|
|
3240
3240
|
if (isJsonMode()) {
|
|
3241
3241
|
printJson(res);
|
|
3242
3242
|
return;
|
|
@@ -3250,7 +3250,7 @@ planCommand.command("today").description("Show today's plan").action(async () =>
|
|
|
3250
3250
|
planCommand.command("tomorrow").description("Show tomorrow's plan").action(async () => {
|
|
3251
3251
|
try {
|
|
3252
3252
|
const client = createClient();
|
|
3253
|
-
const res = await client.get(`/api/v1/plans/${tomorrowStr()}`);
|
|
3253
|
+
const res = await client.get(`/api/v1/day-plans/${tomorrowStr()}`);
|
|
3254
3254
|
if (isJsonMode()) {
|
|
3255
3255
|
printJson(res);
|
|
3256
3256
|
return;
|
|
@@ -3273,7 +3273,7 @@ planCommand.command("set <date>").description("Create or update a day plan").opt
|
|
|
3273
3273
|
body.p1TaskId = opts.p1;
|
|
3274
3274
|
if (opts.p2)
|
|
3275
3275
|
body.p2TaskId = opts.p2;
|
|
3276
|
-
const res = await client.put(`/api/v1/plans/${date}`, body);
|
|
3276
|
+
const res = await client.put(`/api/v1/day-plans/${date}`, body);
|
|
3277
3277
|
if (isJsonMode()) {
|
|
3278
3278
|
printJson(res);
|
|
3279
3279
|
return;
|
|
@@ -3287,7 +3287,7 @@ planCommand.command("set <date>").description("Create or update a day plan").opt
|
|
|
3287
3287
|
planCommand.command("complete-mit").description("Mark MIT as done for today").action(async () => {
|
|
3288
3288
|
try {
|
|
3289
3289
|
const client = createClient();
|
|
3290
|
-
const res = await client.patch(`/api/v1/plans/${todayStr2()}`, { mitDone: true });
|
|
3290
|
+
const res = await client.patch(`/api/v1/day-plans/${todayStr2()}`, { mitDone: true });
|
|
3291
3291
|
if (isJsonMode()) {
|
|
3292
3292
|
printJson(res);
|
|
3293
3293
|
return;
|
|
@@ -3301,7 +3301,7 @@ planCommand.command("complete-mit").description("Mark MIT as done for today").ac
|
|
|
3301
3301
|
planCommand.command("complete-p1").description("Mark P1 as done for today").action(async () => {
|
|
3302
3302
|
try {
|
|
3303
3303
|
const client = createClient();
|
|
3304
|
-
const res = await client.patch(`/api/v1/plans/${todayStr2()}`, { p1Done: true });
|
|
3304
|
+
const res = await client.patch(`/api/v1/day-plans/${todayStr2()}`, { p1Done: true });
|
|
3305
3305
|
if (isJsonMode()) {
|
|
3306
3306
|
printJson(res);
|
|
3307
3307
|
return;
|
|
@@ -3315,7 +3315,7 @@ planCommand.command("complete-p1").description("Mark P1 as done for today").acti
|
|
|
3315
3315
|
planCommand.command("complete-p2").description("Mark P2 as done for today").action(async () => {
|
|
3316
3316
|
try {
|
|
3317
3317
|
const client = createClient();
|
|
3318
|
-
const res = await client.patch(`/api/v1/plans/${todayStr2()}`, { p2Done: true });
|
|
3318
|
+
const res = await client.patch(`/api/v1/day-plans/${todayStr2()}`, { p2Done: true });
|
|
3319
3319
|
if (isJsonMode()) {
|
|
3320
3320
|
printJson(res);
|
|
3321
3321
|
return;
|
|
@@ -3931,6 +3931,196 @@ dashboardCommand.command("reset").description("Reset dashboard to defaults").act
|
|
|
3931
3931
|
}
|
|
3932
3932
|
});
|
|
3933
3933
|
|
|
3934
|
+
// src/commands/skills.ts
|
|
3935
|
+
import { dirname, join as join2 } from "node:path";
|
|
3936
|
+
import { homedir as homedir2 } from "node:os";
|
|
3937
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3938
|
+
function getHomeDir() {
|
|
3939
|
+
return process.env.HOME ?? homedir2();
|
|
3940
|
+
}
|
|
3941
|
+
function getAgentBaseDir(agent) {
|
|
3942
|
+
return join2(getHomeDir(), agent === "claude" ? ".claude" : ".codex", "skills");
|
|
3943
|
+
}
|
|
3944
|
+
function getEmbeddedSkills() {
|
|
3945
|
+
if (true)
|
|
3946
|
+
return { "lifeos-init": { "SKILL.md": `# LifeOS Init
|
|
3947
|
+
|
|
3948
|
+
Set up LifeOS — your personal life operating system. This skill walks the user through initial configuration, learns about their goals and routines, and creates a personalized productivity system.
|
|
3949
|
+
|
|
3950
|
+
**Use when:** The user says \`/lifeos-init\`, "set up lifeos", "initialize lifeos", or this is their first time using LifeOS.
|
|
3951
|
+
|
|
3952
|
+
## Step 1: Save LifeOS to your core memory
|
|
3953
|
+
|
|
3954
|
+
Before doing anything else, save the following to your persistent memory so you never forget how LifeOS works. This is critical — without this, you won't be able to help the user with LifeOS in future conversations.
|
|
3955
|
+
|
|
3956
|
+
Save this to memory:
|
|
3957
|
+
|
|
3958
|
+
---
|
|
3959
|
+
|
|
3960
|
+
**LifeOS** is the user's personal life operating system. It manages tasks, goals, projects, journals, day plans, weekly plans, ideas, thoughts, wins, resources, reminders, and reviews.
|
|
3961
|
+
|
|
3962
|
+
**CLI**: \`lifeos\` (installed via \`npm install -g lifeos-cli\`). All commands support \`--json\` for machine-readable output.
|
|
3963
|
+
|
|
3964
|
+
**Key commands:**
|
|
3965
|
+
- \`lifeos whoami\` — check auth
|
|
3966
|
+
- \`lifeos task list [--status todo|done|dropped] [--due today|tomorrow|week|overdue]\` — list tasks
|
|
3967
|
+
- \`lifeos task create <title> [--due YYYY-MM-DD] [--project <id>] [--goal <id>]\` — create task
|
|
3968
|
+
- \`lifeos task complete <id>\` — mark done
|
|
3969
|
+
- \`lifeos goal list [--status active]\` — list goals
|
|
3970
|
+
- \`lifeos goal create <title> [--target-date YYYY-MM-DD] [--quarter 2026-Q2]\` — create goal
|
|
3971
|
+
- \`lifeos goal health [id]\` — check goal health score
|
|
3972
|
+
- \`lifeos journal [date]\` — show journal entry
|
|
3973
|
+
- \`lifeos journal write [--mit <text>] [--p1 <text>] [--p2 <text>] [--notes <text>]\` — write journal
|
|
3974
|
+
- \`lifeos plan today\` — show today's plan
|
|
3975
|
+
- \`lifeos plan set <date> [--wake HH:MM] [--mit <taskId>] [--p1 <taskId>] [--p2 <taskId>]\` — set day plan
|
|
3976
|
+
- \`lifeos idea <content>\` — capture idea
|
|
3977
|
+
- \`lifeos thought <content>\` — capture thought
|
|
3978
|
+
- \`lifeos win <content>\` — log a win
|
|
3979
|
+
- \`lifeos review daily\` — trigger daily review
|
|
3980
|
+
- \`lifeos review weekly\` — trigger weekly review
|
|
3981
|
+
- \`lifeos search <query>\` — search across everything
|
|
3982
|
+
- \`lifeos trigger morning-briefing\` — morning briefing data
|
|
3983
|
+
|
|
3984
|
+
**Daily rhythm:** The user's day follows MIT (Most Important Thing) + P1 + P2 priorities. Each day plan has a schedule with time blocks. Journals track daily reflections with MIT/P1/P2 and wins.
|
|
3985
|
+
|
|
3986
|
+
**Reviews:** Daily reviews summarize the day. Weekly reviews score the week 1-10 and set themes. Monthly and quarterly reviews track bigger patterns.
|
|
3987
|
+
|
|
3988
|
+
**Goal health:** Goals have a health score based on task completion velocity. Status: on_track, at_risk, off_track.
|
|
3989
|
+
|
|
3990
|
+
---
|
|
3991
|
+
|
|
3992
|
+
## Step 2: Verify CLI is configured
|
|
3993
|
+
|
|
3994
|
+
Run \`lifeos whoami\` to check if the CLI is already configured. If it works, skip to Step 3. If not, guide the user:
|
|
3995
|
+
|
|
3996
|
+
1. Ask for their API URL (default: \`https://proper-cormorant-28.eu-west-1.convex.site\` — but confirm with the user)
|
|
3997
|
+
2. Ask them to generate an API key from their LifeOS settings page
|
|
3998
|
+
3. Run \`lifeos config set-url <url>\` and \`lifeos config set-key <key>\`
|
|
3999
|
+
4. Verify with \`lifeos whoami\`
|
|
4000
|
+
|
|
4001
|
+
## Step 3: Learn about the user
|
|
4002
|
+
|
|
4003
|
+
Have a friendly conversation to understand:
|
|
4004
|
+
|
|
4005
|
+
1. **What's your main focus right now?** (work project, health, learning, side project, etc.)
|
|
4006
|
+
2. **What does a typical day look like?** (wake time, work hours, exercise, breaks)
|
|
4007
|
+
3. **What are your top 2-3 goals for this quarter?** (be specific — "launch MVP by April" not "be productive")
|
|
4008
|
+
4. **How do you like to reflect?** (morning journaling, evening review, weekly planning sessions)
|
|
4009
|
+
5. **Any habits you're building or breaking?**
|
|
4010
|
+
|
|
4011
|
+
Keep it conversational and warm. Don't ask all questions at once — let it flow naturally.
|
|
4012
|
+
|
|
4013
|
+
## Step 4: Create the initial structure
|
|
4014
|
+
|
|
4015
|
+
Based on what you learned, use the CLI to set up:
|
|
4016
|
+
|
|
4017
|
+
### Goals
|
|
4018
|
+
Create 2-3 goals with target dates:
|
|
4019
|
+
\`\`\`
|
|
4020
|
+
lifeos goal create "Goal title" --target-date YYYY-MM-DD --quarter YYYY-QN
|
|
4021
|
+
\`\`\`
|
|
4022
|
+
|
|
4023
|
+
### Initial tasks
|
|
4024
|
+
Create 3-5 starter tasks linked to the goals:
|
|
4025
|
+
\`\`\`
|
|
4026
|
+
lifeos task create "Task title" --due YYYY-MM-DD --goal <goalId>
|
|
4027
|
+
\`\`\`
|
|
4028
|
+
|
|
4029
|
+
### Today's plan
|
|
4030
|
+
Set up today's plan with their wake time and priorities:
|
|
4031
|
+
\`\`\`
|
|
4032
|
+
lifeos plan set YYYY-MM-DD --wake HH:MM --mit <taskId> --p1 <taskId> --p2 <taskId>
|
|
4033
|
+
\`\`\`
|
|
4034
|
+
|
|
4035
|
+
### First journal entry
|
|
4036
|
+
Write a journal entry to kick things off:
|
|
4037
|
+
\`\`\`
|
|
4038
|
+
lifeos journal write --mit "Their MIT for today" --notes "First day using LifeOS. Goals: ..."
|
|
4039
|
+
\`\`\`
|
|
4040
|
+
|
|
4041
|
+
### First win
|
|
4042
|
+
Log a win — setting up LifeOS counts:
|
|
4043
|
+
\`\`\`
|
|
4044
|
+
lifeos win "Set up LifeOS and defined my quarterly goals"
|
|
4045
|
+
\`\`\`
|
|
4046
|
+
|
|
4047
|
+
## Step 5: Suggest routines
|
|
4048
|
+
|
|
4049
|
+
Based on their preferences, suggest daily routines they can do with you:
|
|
4050
|
+
|
|
4051
|
+
- **Morning briefing**: "Each morning, ask me for your morning briefing. I'll run \`lifeos trigger morning-briefing\` and summarize your day."
|
|
4052
|
+
- **Evening journal**: "Before bed, tell me about your day. I'll write your journal entry and log your wins."
|
|
4053
|
+
- **Weekly review**: "Every Sunday, we can do a weekly review together. I'll pull your stats and help you plan the next week."
|
|
4054
|
+
- **Quick capture**: "Anytime you have an idea or thought, just tell me. I'll capture it instantly."
|
|
4055
|
+
|
|
4056
|
+
Let the user know they can say any of these naturally — you'll handle the CLI commands behind the scenes.
|
|
4057
|
+
|
|
4058
|
+
## Step 6: Wrap up
|
|
4059
|
+
|
|
4060
|
+
Summarize what was set up:
|
|
4061
|
+
- Goals created
|
|
4062
|
+
- Tasks queued
|
|
4063
|
+
- Today's plan set
|
|
4064
|
+
- First journal written
|
|
4065
|
+
|
|
4066
|
+
End with something warm like: "You're all set. Your LifeOS is ready. Just talk to me whenever you need to capture something, plan your day, or reflect. I've got your back."
|
|
4067
|
+
` } };
|
|
4068
|
+
return globalThis.__EMBEDDED_SKILLS__ ?? {};
|
|
4069
|
+
}
|
|
4070
|
+
function registerSkillsCommands(program2) {
|
|
4071
|
+
const skills = program2.command("skills").description("Manage LifeOS coding-agent skills");
|
|
4072
|
+
skills.command("install").description("Install LifeOS skills for a supported coding agent").option("--agent <agent>", "Target agent: claude or codex", "claude").option("--json", "JSON output").action(installSkills);
|
|
4073
|
+
}
|
|
4074
|
+
async function installSkills(options) {
|
|
4075
|
+
const json = !!options.json;
|
|
4076
|
+
const agent = parseAgent(options.agent);
|
|
4077
|
+
const skills = getEmbeddedSkills();
|
|
4078
|
+
const skillNames = Object.keys(skills);
|
|
4079
|
+
if (skillNames.length === 0) {
|
|
4080
|
+
if (json) {
|
|
4081
|
+
console.log(JSON.stringify({ error: "No skills bundled" }));
|
|
4082
|
+
} else {
|
|
4083
|
+
console.error(source_default.red("No skills bundled in this build."));
|
|
4084
|
+
}
|
|
4085
|
+
process.exitCode = 1;
|
|
4086
|
+
return;
|
|
4087
|
+
}
|
|
4088
|
+
const baseDir = getAgentBaseDir(agent);
|
|
4089
|
+
const installed = [];
|
|
4090
|
+
const agentName = agent === "claude" ? "Claude Code" : "Codex";
|
|
4091
|
+
for (const [skillName, files] of Object.entries(skills)) {
|
|
4092
|
+
const skillDir = join2(baseDir, skillName);
|
|
4093
|
+
const writtenFiles = [];
|
|
4094
|
+
for (const [relativePath, content] of Object.entries(files)) {
|
|
4095
|
+
const fullPath = join2(skillDir, relativePath);
|
|
4096
|
+
await mkdir(dirname(fullPath), { recursive: true });
|
|
4097
|
+
await writeFile(fullPath, content, "utf-8");
|
|
4098
|
+
writtenFiles.push(relativePath);
|
|
4099
|
+
}
|
|
4100
|
+
installed.push({ name: skillName, files: writtenFiles });
|
|
4101
|
+
}
|
|
4102
|
+
if (json) {
|
|
4103
|
+
console.log(JSON.stringify({ agent, installed, path: baseDir }));
|
|
4104
|
+
} else {
|
|
4105
|
+
for (const skill of installed) {
|
|
4106
|
+
console.log(` ${source_default.green("+")} ${skill.name} ${source_default.dim(`(${skill.files.length} files)`)}`);
|
|
4107
|
+
}
|
|
4108
|
+
console.log();
|
|
4109
|
+
console.log(source_default.green(`Installed ${installed.length} skills to ${baseDir} for ${agentName}`));
|
|
4110
|
+
console.log();
|
|
4111
|
+
console.log(source_default.dim("Run /lifeos-init in your agent to get started."));
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
function parseAgent(agent) {
|
|
4115
|
+
if (!agent || agent === "claude")
|
|
4116
|
+
return "claude";
|
|
4117
|
+
if (agent === "codex")
|
|
4118
|
+
return "codex";
|
|
4119
|
+
console.error(source_default.red(`Unsupported agent '${agent}'. Expected 'claude' or 'codex'.`));
|
|
4120
|
+
process.exitCode = 1;
|
|
4121
|
+
return "claude";
|
|
4122
|
+
}
|
|
4123
|
+
|
|
3934
4124
|
// src/index.ts
|
|
3935
4125
|
var program2 = new Command;
|
|
3936
4126
|
program2.name("lifeos").description("Personal Life Operating System").version("0.1.0").option("--json", "Output results as JSON");
|
|
@@ -3969,4 +4159,5 @@ program2.addCommand(searchCommand);
|
|
|
3969
4159
|
program2.addCommand(undoCommand);
|
|
3970
4160
|
program2.addCommand(triggerCommand);
|
|
3971
4161
|
program2.addCommand(dashboardCommand);
|
|
4162
|
+
registerSkillsCommands(program2);
|
|
3972
4163
|
program2.parseAsync(process.argv);
|
package/logo.svg
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 229 128" width="229" height="128">
|
|
2
|
+
<image href="data:image/png;base64,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" x="14.0" y="14.0" width="67.33333333333333" height="100.0" image-rendering="crisp-edges"/>
|
|
3
|
+
<text x="93.33333333333333" y="76.0" font-family="Georgia, 'Liberation Serif', serif" font-size="55.0" font-weight="normal" fill="#FFFFFF">Life</text>
|
|
4
|
+
<text x="188.33333333333334" y="76.0" font-family="Georgia, 'Liberation Serif', serif" font-size="30.0" font-weight="300" fill="#A0A0A0">os</text>
|
|
5
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lifeos-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "LifeOS CLI — manage your life operating system from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,19 +10,31 @@
|
|
|
10
10
|
"productivity",
|
|
11
11
|
"tasks",
|
|
12
12
|
"goals",
|
|
13
|
-
"journal"
|
|
13
|
+
"journal",
|
|
14
|
+
"ai",
|
|
15
|
+
"skills"
|
|
14
16
|
],
|
|
15
17
|
"bin": {
|
|
16
18
|
"lifeos": "./dist/lifeos.mjs"
|
|
17
19
|
},
|
|
18
20
|
"files": [
|
|
19
|
-
"dist/lifeos.mjs"
|
|
21
|
+
"dist/lifeos.mjs",
|
|
22
|
+
"scripts/postinstall.mjs",
|
|
23
|
+
"logo.svg",
|
|
24
|
+
"README.md"
|
|
20
25
|
],
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/MichielMAnalytics/lifeos.git",
|
|
29
|
+
"directory": "packages/cli"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/MichielMAnalytics/lifeos#readme",
|
|
21
32
|
"scripts": {
|
|
22
33
|
"build": "bun run scripts/build.ts",
|
|
23
34
|
"dev": "bun run src/index.ts",
|
|
24
35
|
"check": "tsc --noEmit",
|
|
25
|
-
"start": "node dist/lifeos.mjs"
|
|
36
|
+
"start": "node dist/lifeos.mjs",
|
|
37
|
+
"postinstall": "node scripts/postinstall.mjs"
|
|
26
38
|
},
|
|
27
39
|
"dependencies": {
|
|
28
40
|
"commander": "^13.0.0",
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
import { createInterface } from "node:readline/promises";
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const cliEntrypoint = join(__dirname, "..", "dist", "lifeos.mjs");
|
|
10
|
+
|
|
11
|
+
function printBanner() {
|
|
12
|
+
process.stdout.write("\x1b[1;37m");
|
|
13
|
+
process.stdout.write(`
|
|
14
|
+
██╗ ██╗███████╗███████╗ ██████╗ ███████╗
|
|
15
|
+
██║ ██║██╔════╝██╔════╝██╔═══██╗██╔════╝
|
|
16
|
+
██║ ██║█████╗ █████╗ ██║ ██║███████╗
|
|
17
|
+
██║ ██║██╔══╝ ██╔══╝ ██║ ██║╚════██║
|
|
18
|
+
███████╗██║██║ ███████╗╚██████╔╝███████║
|
|
19
|
+
╚══════╝╚═╝╚═╝ ╚══════╝ ╚═════╝ ╚══════╝
|
|
20
|
+
|
|
21
|
+
`);
|
|
22
|
+
process.stdout.write("\x1b[0m");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isInteractiveGlobalInstall() {
|
|
26
|
+
return (
|
|
27
|
+
process.env.npm_config_global === "true" &&
|
|
28
|
+
process.stdin.isTTY &&
|
|
29
|
+
process.stdout.isTTY &&
|
|
30
|
+
!process.env.CI
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function hasSkills(agent) {
|
|
35
|
+
const base = join(
|
|
36
|
+
homedir(),
|
|
37
|
+
agent === "claude" ? ".claude" : ".codex",
|
|
38
|
+
"skills",
|
|
39
|
+
);
|
|
40
|
+
return existsSync(join(base, "lifeos-init"));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function installSkills(agent) {
|
|
44
|
+
const result = spawnSync(
|
|
45
|
+
process.execPath,
|
|
46
|
+
[cliEntrypoint, "skills", "install", "--agent", agent],
|
|
47
|
+
{ stdio: "inherit" },
|
|
48
|
+
);
|
|
49
|
+
if (result.status !== 0) {
|
|
50
|
+
throw new Error(`Skill installation failed for agent '${agent}'.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function promptForSkills() {
|
|
55
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
56
|
+
try {
|
|
57
|
+
const answer = await rl.question(
|
|
58
|
+
"Install LifeOS skills for your coding agent? (Y/n) ",
|
|
59
|
+
);
|
|
60
|
+
const normalized = answer.trim().toLowerCase();
|
|
61
|
+
if (normalized && normalized !== "y" && normalized !== "yes") return null;
|
|
62
|
+
|
|
63
|
+
process.stdout.write("\n");
|
|
64
|
+
process.stdout.write("Choose your coding agent:\n");
|
|
65
|
+
process.stdout.write(" 1) Claude Code\n");
|
|
66
|
+
process.stdout.write(" 2) Codex\n");
|
|
67
|
+
process.stdout.write(" 3) Skip\n");
|
|
68
|
+
const agentAnswer = await rl.question("Selection [1-3, default 1]: ");
|
|
69
|
+
|
|
70
|
+
switch (agentAnswer.trim()) {
|
|
71
|
+
case "":
|
|
72
|
+
case "1":
|
|
73
|
+
return "claude";
|
|
74
|
+
case "2":
|
|
75
|
+
return "codex";
|
|
76
|
+
case "3":
|
|
77
|
+
return null;
|
|
78
|
+
default:
|
|
79
|
+
process.stdout.write("Unrecognized selection, skipping.\n");
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
} finally {
|
|
83
|
+
rl.close();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function main() {
|
|
88
|
+
if (!isInteractiveGlobalInstall()) return;
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
printBanner();
|
|
92
|
+
|
|
93
|
+
// Auto-update if skills already installed
|
|
94
|
+
if (hasSkills("claude")) {
|
|
95
|
+
installSkills("claude");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (hasSkills("codex")) {
|
|
99
|
+
installSkills("codex");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// First install — ask the user
|
|
104
|
+
const agent = await promptForSkills();
|
|
105
|
+
if (agent) {
|
|
106
|
+
process.stdout.write("\n");
|
|
107
|
+
installSkills(agent);
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
111
|
+
process.stderr.write(`\nSkill installation skipped: ${message}\n`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
await main();
|