Skip to content

v6.0.5: DetectEnv/InstallEngine has no OpenCode detection — defaults to claude-code unconditionally, and lifeos.ts hardcodes the claude binary #1448

Description

@McCarthyCode

Human-generated content

I installed via OpenCode (running Sonnet 5 – medium), which was partially successful, but it failed at runtime:

❯ lifeos

                                           ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

                                                             LIFEOS | Your Life Operating System

                                                             "Magnifying human capabilities..."


                                                                  █████   │
                                                                  █████   │  "LifeOS here, ready to go..."
                                                                  █████   │  ────────────────────────
                                                                  █████   │  ⬢  LifeOS    6.0.5
                                                             ██████████   │  ⚙  Algo      6.24.0
                                                             ██████████   │  ✦  SKILLS    50
                                                        ███████████████   │  ↪  HOOKS     45
                                                        ███████████████   │  ────────────────────────
                                                   ████████████████████   │
                                                   ████████████████████   │


                                                             → github.com/danielmiessler/LifeOS

                                           ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

433 |   // interactive session uses OAuth (`claude /login`) instead of API-key billing.
434 |   // Mirrors the protection in cmdPrompt() — same hazard, same fix.
435 |   const launchEnv = { ...process.env };
436 |   delete launchEnv.ANTHROPIC_API_KEY;
437 |   launchEnv.CLAUDE_CODE_WORKFLOWS = "1";
438 |   const proc = spawn(args, {
                     ^
error: Executable not found in $PATH: "claude"
  path: "claude",
 errno: -2,
  code: "ENOENT"

      at cmdLaunch (/Users/matt/.claude/LIFEOS/TOOLS/lifeos.ts:438:16)
      at main (/Users/matt/.claude/LIFEOS/TOOLS/lifeos.ts:765:13)
      at /Users/matt/.claude/LIFEOS/TOOLS/lifeos.ts:769:1

Bot-generated content

Title

v6.0.5: DetectEnv/InstallEngine has no OpenCode (or other non-Claude-Code harness) detection — defaults to claude-code unconditionally, and lifeos.ts hardcodes the claude binary, so lifeos fails with Executable not found in $PATH: "claude" on any machine without Claude Code CLI installed

Summary

Installed LifeOS 6.0.5 via the agentic installer (https://ourlifeos.ai/install) using OpenCode as the installing AI/harness. Setup completed with no errors and all verification probes passed, but the resulting lifeos launch command fails immediately:

$ lifeos
error: Executable not found in $PATH: "claude"
  path: "claude",
  errno: -2,
  code: "ENOENT"

      at cmdLaunch (~/.claude/LIFEOS/TOOLS/lifeos.ts:438:16)
      at main (~/.claude/LIFEOS/TOOLS/lifeos.ts:765:13)

Root cause

Two related gaps in the shipped v6.0.5 code:

  1. Tools/InstallEngine.ts — the Harness type and detectHarness() only recognize four harnesses:

    export type Harness = "claude-code" | "hermes" | "cursor" | "openclaw" | "unknown";

    detectHarness() checks for ~/.claude, ~/.hermes, ~/.cursor, ~/.openclaw and, if none of those directories exist, falls back to "claude-code" as the default assumption:

    // Default assumption when nothing is present yet (a clean machine pre-bootstrap).
    return { name: "claude-code", configRoot: join(home, ".claude"), skillsDir: join(home, ".claude", "skills") };

    There is no "opencode" entry, and no fallback branch for "harness I don't recognize — ask, or treat as generic." Every non-listed harness (OpenCode included) is silently treated as Claude Code.

    In my case, a leftover ~/.claude directory already existed on the machine (unrelated prior activity, just config.json/sessions/ide), so detectHarness() matched the claude-code candidate directly — but even without that leftover dir, the unconditional fallback means any OpenCode-only machine still gets misreported as claude-code.

  2. install/LIFEOS/TOOLS/lifeos.ts — the launch command wraps the claude CLI binary directly, with no harness abstraction:

    const result = spawnSync(["claude", "--version"]);      // line 129
    const args = ["claude"];                                 // line 397
    const args = ["claude", "-p", prompt];                    // line 573
    ...
    const proc = spawn(args, { stdio: [...], env: launchEnv }); // line 438

    INSTALL.md/Workflows/Setup.md (step 7/8.5) do document that the lifeos alias + hooks are Claude-Code-specific, and that "any other harness" should instead get an AGENTS.md/context file pointing at LIFEOS_SYSTEM_PROMPT.md and use that harness's own system-prompt flag. But because DetectEnv misreports the harness as claude-code by default, the installing AI (correctly, per the docs, given the wrong detection) takes the Claude-Code branch: it wires the Claude-Code-specific hooks into settings.json and the lifeos alias, neither of which work without the Claude Code CLI installed.

Why I'm filing this (context for maintainers)

This is the same class of issue as #1300 ("Installing PAI v5.0 on OpenCode") and #1231 ("Platform Agnostic?"), both closed by the same maintainer response about the then-upcoming "agentic installer" model:

"Instead of cloning a full ~/.claude directory... LifeOS is becoming a skill you install through an agentic installer. The installer hands integration to your own AI, which reads your actual machine (your OS, your paths, your harness) and wires the hooks and system prompt in where they belong."

That model has since shipped (this is exactly the flow I went through — an agentic installer, read by OpenCode, which then ran DetectEnv/DeployCore/etc.). The 6.0.5 release notes describe this cycle as "the rename reaches the code" and claim the identifier-level rename is complete ("Same system as 6.0.0, cleaner throughout"). But the underlying harness-detection gap that #1300/#1231 were actually about is still present in the code itself, unrelated to naming — detectHarness()'s candidate list and lifeos.ts's claude-binary assumption were not revisited as part of the agentic-installer rework, so the closing rationale for #1300/#1231 doesn't actually resolve them for OpenCode users. It just moves the failure from "install script doesn't know where to put files" (the old complaint) to "install completes cleanly, but the launch command silently assumed Claude Code and fails at runtime" (this issue).

Suggested fix

  • Add "opencode" (and ideally a generic "other"/"unknown-agentic" fallback instead of defaulting to "claude-code") to Harness in InstallEngine.ts, with real detection (e.g. ~/.config/opencode, OPENCODE_CONFIG_DIR env, or presence of an opencode binary) rather than defaulting unrecognized environments to Claude Code.
  • Have DetectEnv's output make it unambiguous when harness detection is a guess vs. confirmed (e.g. "harnessConfidence": "assumed" | "detected"), so the installing AI/Setup workflow doesn't silently proceed down the Claude-Code branch (hooks + lifeos alias) on unconfirmed detections.
  • In lifeos.ts, gate the claude-binary spawn behind an actual Claude Code CLI presence check with a clear error message ("Claude Code CLI not found — install it or use your harness's own system-prompt flag against LIFEOS_SYSTEM_PROMPT.md") instead of a bare ENOENT stack trace.

Environment

  • LifeOS 6.0.5 (v6.0.5 tag)
  • macOS 26.5.1, arm64
  • Installing AI/harness: OpenCode (not Claude Code)
  • Claude Code CLI: not installed on this machine

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