Skip to content

Windows install of v7.1.1 is unlaunchable #1694

Description

@dissembler21-png

Windows install of v7.1.1 is unlaunchable: Core launcher depends on the optional hooks tree, and process.env.HOME is undefined on Windows

Environment

LifeOS v7.1.1 (installed via install.sh)
OS Windows 11 Pro 10.0.22631
Harness Claude Code
bun 1.3.14 (Windows x64)
git 2.55.0.windows.3
Config root C:\Users\<user>\.claude

Install path followed: install.sh bootstrap → the Workflows/Setup.md steps (DetectEnv, ScanConflicts, InstallSettings, DeployCore, ScaffoldUser, LinkUser, ActivateImports, DeployComponents). LifeOS Core deployed cleanly — 52 skills, 532 runtime files, identity @-imports all resolving. The two bugs below then made the installed system impossible to launch.


Bug 1 — The Core launcher imports from the Enhancement-tier hooks tree

Workflows/Setup.md presents hooks as à la carte: step 7 says the user picks "some, all, or none", and hooks are deployed only by Tools/InstallHooks.ts. But the launch command is Core (step 8.5, and INSTALL.md step 7), and LIFEOS/TOOLS/lifeos.ts:22 does:

import { getIdentity, getStartupCatchphrase } from "../../hooks/lib/identity";

Tools/DeployCore.ts deploys install/skills/ and install/LIFEOS/ but never install/hooks/. So declining hooks — a documented, supported choice — leaves <configRoot>/hooks/ absent and the launcher dead.

Reproduce

  1. Install v7.1.1.
  2. At the step 7 enhancements menu, decline hooks.
  3. Run lifeos.
error: Cannot find module '../../hooks/lib/identity' from 'C:\Users\<user>\.claude\LIFEOS\TOOLS\lifeos.ts'

This is platform-independent — declining hooks on macOS or Linux should break the launcher identically.

Notes

The dependency is genuinely narrow: lifeos.ts needs only identity from hooks/lib, and identity.ts in turn needs only LIFEOS/TOOLS/LifeosConfig (Core) and yaml (already in the deployed package.json). None of the other 23 files in hooks/lib/ are required.

Suggested fixes

  • Move identity.ts into LIFEOS/TOOLS/ — it is a shared identity loader, not hook logic; or
  • have DeployCore.ts deploy install/hooks/lib/ as a Core library (this registers nothing in settings.json and executes no hooks, so it does not violate the opt-in model); or
  • make the import lazy with a graceful fallback to the default identity when the hooks tree is absent.

Bug 2 — process.env.HOME is undefined on Windows (206 occurrences, 119 files)

Windows does not define HOME; it defines USERPROFILE. hooks/lib/identity.ts:18-19:

const HOME = process.env.HOME!;
const SETTINGS_PATH = join(HOME, '.claude/settings.json');

The non-null assertion (!) suppresses this at compile time, so it surfaces only at runtime, as a confusing error that names paths[0] rather than HOME.

Reproduce

On Windows, run any LIFEOS tool (after working around Bug 1):

TypeError: The "paths[0]" property must be of type string, got undefined
 code: "ERR_INVALID_ARG_TYPE"
      at C:\Users\<user>\.claude\hooks\lib\identity.ts:19:23

Scope

process.env.HOME appears 206 times across 119 files under LIFEOS/, including LIFEOS/TOOLS/ (Doctor.ts, Banner.ts, LifeosConfig.ts, GenerateTelosSummary.ts, MemoryRetriever.ts, …) and most of LIFEOS/PULSE/. So this is not one bad line — the Windows install is broadly affected.

Notably, lifeos.ts itself already does the right thing on line 24:

import { homedir } from "os";
const CLAUDE_DIR = join(homedir(), ".claude");

so the codebase is internally inconsistent about this.

Suggested fix

Prefer homedir() from node:os, which is correct on every platform. Where an env var must be read, use process.env.HOME ?? process.env.USERPROFILE. Dropping the ! assertions would let the type checker surface the remaining cases.

Workaround

Defining HOME in the environment resolves the whole class at once, and with it the launcher, Banner.ts, and Doctor.ts all run correctly:

  • PowerShell launch function: $env:HOME = $env:USERPROFILE
  • Claude Code sessions: "HOME": "C:\\Users\\<user>" in the env block of settings.json

Minor — LinkUser cannot succeed when the config root is the harness tree

Tools/LinkUser.ts tries to symlink the USER tree into the harness tree, but on this layout both resolve to the same path, so it attempts USER → USER:

{
  "ok": false,
  "action": "linked",
  "error": "symlink creation failed (live USER preserved at ...USER.pre-link-backup-<ts>): EEXIST: file already exists, symlink 'C:\\Users\\<user>\\.claude\\LIFEOS\\USER' -> 'C:\\Users\\<user>\\.claude\\LIFEOS\\USER'",
  "contract": { "passed": false, "detail": "USER is not a symlink (system/user separation broken)" }
}

Practically harmless — a real LIFEOS/USER/ directory is exactly what the @LIFEOS/USER/... imports need, and they resolve fine. But it reports ok: false and a failed contract, which reads as a broken install, and it leaves behind a full duplicate of the 95-file USER tree in USER.pre-link-backup-<ts>. Suggest detecting src === dst and treating it as a satisfied no-op.

Minor — install.sh fallback tag points at a nonexistent release

install.sh sets LIFEOS_FALLBACK_TAG="v7.11.0", but no such release exists; the newest published release is v7.1.1. The fallback is unreachable in the normal path (the releases/latest redirect resolves correctly), so this is latent — but it is precisely the path taken when GitHub is rate-limited, which is the scenario the surrounding comment says was already a real incident on 2026-07-12. As stamped, that recovery path would fetch a 404 tarball.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions