Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions LifeOS/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ Prefer a terminal? There's a shell shortcut for Claude Code on macOS/Linux:
curl -fsSL https://ourlifeos.ai/install.sh | bash
```

### Project-scoped installs

**Want LifeOS scoped to one project instead of every session?** By default LifeOS installs into your harness's global config dir (e.g. `~/.claude`), so its skills/hooks/agents are available everywhere. To confine it to a single project instead — so it only activates when your harness runs from that project's directory — set `CLAUDE_CONFIG_DIR` (and `LIFEOS_DIR` / `LIFEOS_CONFIG_DIR` for the LIFEOS-specific subtree) to a path inside that project, e.g. `<project>/.claude`, before running the install Tools (or pass the equivalent `--config-root`/`--config-dir` flags each Tool accepts). Everything under this document and `Workflows/Setup.md` works identically either way — every install Tool resolves its target through these same env vars, defaulting to the global harness dir only when they're unset.

Everything below is written for the AI doing the install.

---
Expand Down
16 changes: 15 additions & 1 deletion LifeOS/Tools/InstallHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,21 @@ function main(): void {
console.log(JSON.stringify({ ok: false, error: `payload hooks.json not found at ${hooksJsonPath}` }, null, 2));
process.exit(1);
}
const incoming = JSON.parse(readFileSync(hooksJsonPath, "utf-8"))?.hooks ?? {};
let hooksJsonRaw = readFileSync(hooksJsonPath, "utf-8");
// hooks.json ships commands hardcoded to "$HOME/.claude/..." (hooks/, LIFEOS/TOOLS,
// LIFEOS/USER/CONFIG, settings.json) — rewrite the whole prefix to the actual
// configRoot so a non-default --config-root (e.g. a project-scoped install)
// doesn't wire commands pointing at files that were never placed there.
// Only when configRoot actually differs from the default: the literal "$HOME/..."
// form is intentionally portable (shell-expanded at hook-execution time), so a
// plain global install must keep shipping it byte-identical to before this fix —
// baking in a resolved absolute path here would break syncing settings.json
// across machines/users, which the default install never asked for.
const defaultConfigRoot = join(process.env.HOME || "", ".claude");
if (configRoot !== defaultConfigRoot) {
hooksJsonRaw = hooksJsonRaw.split("$HOME/.claude").join(configRoot);
}
const incoming = JSON.parse(hooksJsonRaw)?.hooks ?? {};

// The hook SCRIPTS (*.hook.ts|sh + lib/**) live beside hooks.json in the payload.
// Merging hooks.json into settings.json wires commands that point at these files,
Expand Down
14 changes: 11 additions & 3 deletions LifeOS/Tools/InstallSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,21 @@ export function expandLeadingHome(value: string, home: string): string {
return value;
}

function expandEnvBlock(settings: Record<string, unknown>, home: string): number {
function expandEnvBlock(settings: Record<string, unknown>, home: string, configRoot: string): number {
const env = settings.env;
if (!env || typeof env !== "object") return 0;
const defaultConfigRoot = join(home, ".claude");
let n = 0;
for (const [k, v] of Object.entries(env as Record<string, unknown>)) {
if (typeof v === "string") {
const expanded = expandLeadingHome(v, home);
// Template values under $HOME/.claude belong under configRoot, not the real
// home, when a non-default --config-root is in play (e.g. project-scoped).
let expanded = v;
if (configRoot !== defaultConfigRoot && v.startsWith("$HOME/.claude")) {
expanded = configRoot + v.slice("$HOME/.claude".length);
} else {
expanded = expandLeadingHome(v, home);
}
if (expanded !== v) { (env as Record<string, unknown>)[k] = expanded; n++; }
}
}
Expand All @@ -79,7 +87,7 @@ if (!existsSync(templatePath)) {
}

const template = JSON.parse(readFileSync(templatePath, "utf8")) as Record<string, unknown>;
const expandedCount = expandEnvBlock(template, home);
const expandedCount = expandEnvBlock(template, home, args.configRoot);

const report: Record<string, unknown> = { ok: true, apply: args.apply, target: targetPath, envValuesExpanded: expandedCount };

Expand Down
4 changes: 4 additions & 0 deletions LifeOS/Workflows/Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ curl -s -X POST http://localhost:31337/notify -H "Content-Type: application/json
-d '{"message": "Running the Setup workflow in the LifeOS skill to integrate LifeOS into your system"}' > /dev/null 2>&1 &
```

## Project-scoped installs

Every Tool in this workflow (`InstallSettings`, `DeployCore`, `ScaffoldUser`, `LinkUser`, `InstallHooks`, `DeployComponents`, `ActivateImports`) resolves its target root through `CLAUDE_CONFIG_DIR` (general harness-config paths) and `LIFEOS_DIR`/`LIFEOS_CONFIG_DIR` (the LIFEOS-specific subtree) — or the equivalent `--config-root`/`--config-dir` flags — falling back to the global harness dir (e.g. `~/.claude`) only when unset. If your human wants LifeOS confined to one project instead of every session, set these to a path inside that project before running any step below, and pass the same flags through consistently across all of them. No step in this workflow needs a different invocation to support this — it's the same install, just rooted elsewhere.

## Two-tier model

Deployment is **two tiers**, and the install presents them that way:
Expand Down
6 changes: 4 additions & 2 deletions LifeOS/install/CLAUDE.template.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

Constitutional rules, the unified response format, verification doctrine, hard prohibitions, security protocol, and operational rules all live in the system prompt: `LIFEOS/LIFEOS_SYSTEM_PROMPT.md`. When this file and the system prompt disagree, the system prompt wins.

This file is the **routing table** — it tells you where everything lives. The only mandatory startup `@`-import shipped with public LifeOS is `ARCHITECTURE_SUMMARY`. The five identity files (`PRINCIPAL_TELOS`, `PRINCIPAL_IDENTITY`, `DA_IDENTITY`, `PROJECTS`, `OPERATIONAL_RULES`) are commented out above — the agentic `/lifeos-setup` (via `Tools/ActivateImports.ts`) uncomments them once the principal's USER scaffold is populated. Claude Code does not follow transitive `@`-imports from inside imported files, so each identity file must be listed here at top level. Everything below is **on-demand** lookup. Paths are relative to `~/.claude/` unless noted.
This file is the **routing table** — it tells you where everything lives. The only mandatory startup `@`-import shipped with public LifeOS is `ARCHITECTURE_SUMMARY`. The five identity files (`PRINCIPAL_TELOS`, `PRINCIPAL_IDENTITY`, `DA_IDENTITY`, `PROJECTS`, `OPERATIONAL_RULES`) are commented out above — the agentic `/lifeos-setup` (via `Tools/ActivateImports.ts`) uncomments them once the principal's USER scaffold is populated. Claude Code does not follow transitive `@`-imports from inside imported files, so each identity file must be listed here at top level. Everything below is **on-demand** lookup. Paths are relative to your resolved config root — check the `CLAUDE_CONFIG_DIR` / `LIFEOS_DIR` environment variables first (a project-scoped install sets these), otherwise `~/.claude/`.

> **A literal `~/.claude/...` in ANY doc (this file, DOCUMENTATION/, or any skill's SKILL.md/Workflows/) is an illustrative example, not a fact about this install.** Resolve the real root first — `echo $CLAUDE_CONFIG_DIR $LIFEOS_DIR` or check `settings.json`'s `env` block — and substitute before running any command. A project-scoped install never actually lives at the literal `~/.claude/` path shown in examples.

## LifeOS System (paths under `LIFEOS/DOCUMENTATION/` unless noted)

Expand Down Expand Up @@ -81,7 +83,7 @@ Populated during `/lifeos-setup`. Typical layout:
- Finances — `FINANCES/`
- Integration configs — `INTEGRATIONS/*.yaml`
- Work system — `WORK/config.yaml`
- Secrets — `~/.claude/.env` (canonical; see OPERATIONAL_RULES.md)
- Secrets — `.env` in your resolved config root (`$CLAUDE_CONFIG_DIR/.env` if set, else `~/.claude/.env`; canonical; see OPERATIONAL_RULES.md)

## Project-Specific Rules

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ version: 1.2.3

# Freshness System

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> Freshness protects the loop's inputs. The LifeOS (`LifeOs/LifeOsThesis.md`) hill-climbs against its picture of your current state and your TELOS — if those files silently age, the OS optimizes toward a person who no longer exists. The convention below makes constitutional staleness visible before it becomes drift.

Every file that loads into the DA's context at session start carries a known recency. This is the freshness convention — `pai-freshness-v1`. It exists because constitutional context that drifts silently is worse than missing context: the model behaves with confidence on stale ground and the principal can't tell.
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Hooks/HookSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ version: 1.2.50

# Hook System

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> Hooks are why the LifeOS runs when nobody is looking. The thesis (`LifeOs/LifeOsThesis.md`) assigns them their job: automate the loop — capture current state, enforce doctrine, fire the next move — without the principal having to ask. A hill-climb that only advances when prompted is a chatbot; the hook lifecycle below is what makes it an operating system.

> **LifeOS 5.0** — Stable event-driven automation infrastructure.
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Isa/IsaHtmlMirror.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ version: 1.0.15

# ISA HTML Mirror

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

The ISA is the canonical articulation of "done" for any Algorithm run. It lives as `ISA.md` markdown in a working directory the principal does not normally look at. The **HTML Mirror** is a deterministic, zero-token, branded sibling — `ISA.html` next to every `ISA.md` — produced by a fast CLI on completion events and refreshed in-place by Interceptor.

## Canonical Theme — UL Technical v1.0.0 (2026-05-13)
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Memory/MemorySystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ version: 1.5.19

# Memory System

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> In Life OS terms (`LIFEOS/DOCUMENTATION/LifeOs/LifeOsThesis.md`), memory is how the OS knows your **current state**. The hill-climb is only as good as the system's picture of where you actually are — what you're working on, what failed, who you know, what you learned. Every capture pipeline below exists to sharpen that picture so the gap to ideal state is measured against reality, not guesses.

**LifeOS's file-system-based memory. Everything we know, everything we've learned, everything we've researched, everything we're working on.**
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Pulse/PulseSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ version: 1.6.17

# The Pulse System

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

**Pulse is the Life Dashboard.** It is the visible surface of the LifeOS Life Operating System — the place where you (and your DA) see and interact with everything the OS is doing. LifeOS is the OS; Pulse is how you watch it run.

Every Pulse module is a sub-surface of the Dashboard: real-time observability, voice notifications, chat surfaces (iMessage/Telegram), scheduled work, background worker state, DA heartbeat, and — as the dashboard grows — live views of current state vs ideal state, goal progress, workflows, and day-in-the-life preview. A LifeOS with no dashboard would still be a LifeOS; Pulse is what keeps it visible.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ generator: LIFEOS/TOOLS/Services.ts (run `bun Services.ts doc` to regenerate the

# LifeOS Background Services

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> **Every recurring Mac service LifeOS runs, in one place — what it is, how often it fires, and how to install it. One tool controls them all: `LIFEOS/TOOLS/Services.ts`.** Before this doc, the install story was scattered across a dozen `Install*.ts` scripts, Pulse `manage.sh` files, and hand-installed launchd jobs, with nothing that listed what was actually running. This is the fix.

## The one-shot
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Skills/SkillSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ version: 1.5.1

# Custom Skill System

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> Skills are the Life OS's action surface. The thesis (`LIFEOS/DOCUMENTATION/LifeOs/LifeOsThesis.md`) puts it directly: "Skills expand so the DA can take more actions to close the gap." Every skill added is a new class of move the DA can make in the current→ideal-state hill-climb; the structure rules below exist so those moves stay discoverable, composable, and safe to ship.

**This document is the authoritative definition of the required structure for every LifeOS skill; all skill creation — including CreateSkill's — conforms to it. "Canonicalize a skill" = restructure to match this exact format, including TitleCase naming. A skill that doesn't follow it is not properly configured and will not work correctly.**
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/SystemUserBoundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ version: 1.1.4

# System / User Boundary

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> This boundary is the thesis's deepest structural commitment (`LIFEOS/DOCUMENTATION/LifeOs/LifeOsThesis.md`): LifeOS the OS is universal and public; the life it runs is singular and private. The four zones below are how one repo can be everyone's Life OS without ever containing anyone's life.

> The structural contract that makes the LifeOS live tree publishable by construction rather than by scrub.
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Tools/Cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ version: 1.1.10

# LifeOS Command-Line Tools

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> CLI-first is how the Life OS stays deterministic (`LIFEOS/DOCUMENTATION/LifeOs/LifeOsThesis.md`): the hill-climb's moves are code you can script, test, and trust — prompts orchestrate, code executes.

LifeOS provides two CLI tools for running infrastructure from the terminal:
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Tools/Tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ version: 1.8.0

# LifeOS Tools - CLI Utilities Reference

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> CLI-first is how the Life OS stays deterministic (`LIFEOS/DOCUMENTATION/LifeOs/LifeOsThesis.md`): the hill-climb's moves are code you can script, test, and trust — prompts orchestrate, code executes.

This file documents single-purpose CLI utilities that have been consolidated from individual skills. These are pure command-line tools that wrap APIs or external commands.
Expand Down
2 changes: 2 additions & 0 deletions LifeOS/install/LIFEOS/DOCUMENTATION/Work/WorkSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ version: 1.0.3

# Work System

> **Path note:** Any `~/.claude/...` path in this doc's examples is illustrative, not a fact about your install. This system may be installed project-scoped (`CLAUDE_CONFIG_DIR`/`LIFEOS_DIR` pointed at a project folder) rather than at the literal global path shown — resolve the actual root (check those env vars, or `CLAUDE.md`) before running any command literally.

> The Work System is the hill-climb's ledger (`LIFEOS/DOCUMENTATION/LifeOs/LifeOsThesis.md`). Every captured unit of work is a step taken toward ideal state, and the TELOS sweep is the loop closing on itself: an active goal with no open issue is a declared ideal state with no next move — exactly the gap the OS exists to surface.

> The Work System turns every meaningful unit of work the principal does — Algorithm sessions, NATIVE work that touched files, explicit reminders, periodic check-ins on stale projects, TELOS goals without a next action — into a labeled GitHub issue in one configured private repo. The repo is the system of record. The Pulse Work tab, the auto-regenerated TASKLIST.md, and the agent claim flow are all readers.
Expand Down
Loading