> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase01-session03-cli-lifecycle-parity/spec.md).

# Session Specification

**Session ID**: `phase01-session03-cli-lifecycle-parity` **Phase**: 01 - Core Runtime Hardening **Status**: Completed **Created**: 2026-05-29 **Package**: Cross-cutting (`apps/cli`, `apps/hooks`) **Package Stack**: JavaScript ESM CLI and hooks, Node built-ins, Vitest node tests, Markdown docs

***

## 1. Session Overview

This session brings the current FactionOS CLI lifecycle closer to the retained original command affordances while staying honest about the current npm workspace architecture. The current CLI supports `init`, `status`, `doctor`, and `uninstall`, but the old package also exposed launch/start, daemon mode, browser open, stop, PID, port, and project-root behavior. Phase 01 requires those behaviors to be implemented or explicitly documented in the current workspace instead of remaining an implicit gap.

The work focuses on `apps/cli` and `apps/hooks`. `apps/cli` owns the command surface, local lifecycle state, process launch and stop behavior, status and doctor output, and README guidance. `apps/hooks` owns the install and uninstall script parity that backs up and merges user-owned Claude settings without clobbering unrelated hooks. The session preserves local-first behavior, avoids hosted services, and treats `EXAMPLES/` as source evidence only.

The implementation should separate the FactionOS runtime root from the user workspace root. The runtime root is where workspace scripts such as `npm run dev` can be launched. The workspace root is the current project being monitored and should be persisted deterministically for diagnostics, without requiring the CLI to copy or inspect private project contents.

***

## 2. Objectives

1. Add or document CLI launch/start, open, stop, status, doctor, install, and uninstall lifecycle parity for the current workspace.
2. Persist PID, port, server URL, and workspace-root state with atomic writes and deterministic stale-state cleanup.
3. Preserve hook install, backup, merge, and uninstall behavior without deleting user-owned Claude settings or unrelated hook entries.
4. Add filesystem fixture tests that prove lifecycle, settings, PID, port, and workspace behavior without touching real user state.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase01-session01-event-ingest-contract-reconciliation` - provides the supported `/event` and hook ingest baseline used by CLI setup.
* [x] `phase01-session02-hook-runtime-safety` - provides hook runtime safety, atomic local-state helpers, listener diagnostics, and CLI fixture patterns.

### Required Tools/Knowledge

* Node.js 20 or newer.
* npm workspace commands from the repository root.
* Current CLI commands in `apps/cli/src/commands/`.
* Current hook install and uninstall scripts in `apps/hooks/scripts/`.
* Current root launch scripts and default ports from `package.json`, `scripts/dev.mjs`, `apps/server/package.json`, and `apps/web/package.json`.
* Original CLI evidence in `EXAMPLES/1st-pass-artifacts/` and `EXAMPLES/package-0.4.1/lib/`.

### Environment Requirements

* Work from the repository root.
* Use temporary homes and fake process/server fixtures in tests.
* Do not touch real `~/.claude`, `~/.factionos`, browser state, or live process managers during automated tests.
* Do not add hosted-service requirements, API keys, or non-loopback defaults.

***

## 4. Scope

### In Scope (MVP)

* Developer can run a clear CLI launch path for the current workspace - add `start` and `launch` behavior or document exact current equivalents where a package-distribution boundary prevents implementation.
* Developer can run `open` to open the current local web URL only when the local lifecycle state or health probe indicates that FactionOS is reachable.
* Developer can run `stop` to terminate the CLI-managed local process using a PID file, with stale PID cleanup and bounded graceful shutdown.
* Developer can run `status` and `doctor` to diagnose server health, configured port, listener PID files, CLI-managed PID state, hook installation, spool posture, workspace root, Node version, and missing current-workspace scripts.
* Developer can run `init` or an `install` alias to preserve current install behavior while matching the retained original command vocabulary.
* Hook install and uninstall scripts preserve unrelated Claude settings, maintain backups, remove only FactionOS-managed entries, and use atomic writes where practical.
* Maintainer can verify install, backup, merge, uninstall, PID, port, workspace-root, and command-surface behavior with Vitest fixtures.
* User-facing docs explain exactly which lifecycle commands are supported in the monorepo today and which publishing or non-Claude launch affordances are deferred.

### Out of Scope (Deferred)

* Publishing an npm package - Reason: release packaging belongs to later release hardening.
* Hosted auth, cloud account setup, Supabase, Umami, PostHog, or remote relay dependencies - Reason: core CLI lifecycle must remain local-first.
* Non-Claude provider launch or command spawning - Reason: this session may document compatibility hooks, but full provider launch belongs to later orchestration phases.
* Web cockpit redesign or settings UI changes - Reason: product-surface work belongs to Phase 02.
* Replacing the root development runner with a production process supervisor - Reason: this session needs deterministic local lifecycle behavior, not a deployment system.

***

## 5. Technical Approach

### Architecture

Create a CLI lifecycle layer that keeps process and file-state logic out of individual command files. The helper should resolve the FactionOS runtime root, validate that current workspace scripts exist, normalize server and web URLs, write PID and project-root records atomically, probe health with bounded timeouts, and clean stale PID files before taking action.

The command layer should remain thin. `start` and `launch` should call the lifecycle helper, apply duplicate-trigger prevention when a managed process is already alive, and register cleanup for foreground runs. `stop` should read and validate the managed PID before sending signals. `open` should avoid adding a runtime dependency by using platform-specific opener commands through Node built-ins, with a clear fallback message. `status` and `doctor` should report the new lifecycle state without printing prompts, raw hook payloads, spool contents, command bodies, tokens, or private file contents.

Hook scripts should be aligned with the safer patterns introduced in Session 02. The CLI path already performs atomic settings writes, but `apps/hooks/scripts/install.js` and `apps/hooks/scripts/uninstall.js` still need fixture-tested behavior for malformed settings, backups, merge preservation, managed-entry removal, and atomic write cleanup.

### Design Patterns

* Lifecycle facade: keep spawn, PID, port, workspace, open, and health-probe behavior in one tested helper.
* Atomic local writes: write PID, settings, and workspace metadata through a temp-file-plus-rename path.
* Idempotent state mutation: `start`, `install`, and `uninstall` should be safe to repeat and should not duplicate managed hook entries.
* Explicit current-workspace boundary: fail clearly when the CLI cannot find the current FactionOS monorepo scripts instead of implying published-package behavior.
* Fixture isolation: tests use temporary homes, fake servers, and controllable child processes.

### Technology Stack

* JavaScript ESM in `apps/cli` and `apps/hooks`.
* Node.js built-ins: `child_process`, `fs`, `http`, `net`, `os`, `path`, and `url`.
* Vitest 4 node project tests.
* Biome format and lint commands.
* Existing npm workspace scripts; no new runtime dependency is expected.

***

## 6. Deliverables

### Files to Create

| File                                      | Purpose                                                                                    | Est. Lines |
| ----------------------------------------- | ------------------------------------------------------------------------------------------ | ---------- |
| `apps/cli/src/lib/lifecycle.js`           | CLI lifecycle helpers for runtime root, PID, port, workspace, process, and health behavior | \~220      |
| `apps/cli/src/lib/browser.js`             | Platform browser opener helper using Node built-ins and fallback messaging                 | \~80       |
| `apps/cli/src/commands/start.js`          | `start` and `launch` command behavior for foreground and daemon workflows                  | \~150      |
| `apps/cli/src/commands/stop.js`           | Managed stop command with stale PID cleanup and bounded termination                        | \~90       |
| `apps/cli/src/commands/open.js`           | Browser open command with reachability checks                                              | \~70       |
| `apps/cli/tests/lifecycle.test.js`        | Lifecycle fixture tests for PID, port, workspace, start, stop, and open helpers            | \~260      |
| `apps/hooks/tests/installScripts.test.js` | Hook install/uninstall fixture tests for backup, merge, atomic writes, and managed removal | \~220      |

### Files to Modify

| File                                | Changes                                                                                      | Est. Lines |
| ----------------------------------- | -------------------------------------------------------------------------------------------- | ---------- |
| `apps/cli/src/index.js`             | Add dispatch, aliases, help text, and flag handling for lifecycle commands                   | \~80       |
| `apps/cli/src/lib/localFiles.js`    | Add PID, project-root, config, stale cleanup, and atomic helper coverage                     | \~120      |
| `apps/cli/src/commands/init.js`     | Keep install behavior, add install alias compatibility, and update next-step guidance        | \~50       |
| `apps/cli/src/commands/status.js`   | Include CLI-managed lifecycle state, port, workspace root, and stale PID reporting           | \~80       |
| `apps/cli/src/commands/doctor.js`   | Add lifecycle, Node, workspace script, port, and managed PID diagnostics                     | \~100      |
| `apps/cli/tests/cliRuntime.test.js` | Extend existing CLI fixture coverage for command aliases and diagnostics                     | \~160      |
| `apps/hooks/scripts/install.js`     | Use safe parsing, merge preservation, backups, and atomic settings writes                    | \~90       |
| `apps/hooks/scripts/uninstall.js`   | Restore or surgically remove managed entries with safe parsing and atomic writes             | \~90       |
| `apps/cli/README_cli.md`            | Document current lifecycle commands, daemon limits, PID files, ports, and workspace behavior | \~120      |
| `apps/hooks/README_hooks.md`        | Document install/uninstall script safety and managed-entry removal behavior                  | \~50       |
| `README.md`                         | Update quick-start CLI lifecycle guidance without overstating publish support                | \~60       |
| `docs/privacy-and-security.md`      | Note local lifecycle state, PID/project metadata, and sensitive-output limits                | \~30       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] `factionos start` and `factionos launch` provide a supported current workspace launch path or fail with a precise explanation of the missing workspace scripts.
* [ ] `factionos start --daemon` records a managed PID and refuses duplicate starts while that PID is alive.
* [ ] `factionos stop` terminates the managed process, clears stale PID state, and does not kill unrelated processes.
* [ ] `factionos open` opens the local web URL only after a bounded health or lifecycle-state check, and prints a clear manual URL fallback.
* [ ] `factionos status` and `factionos doctor` report server, port, PID, listener, spool, hook, and workspace state without raw sensitive payloads.
* [ ] `factionos install` preserves current `init` behavior or is documented as an alias to it.
* [ ] Hook install and uninstall preserve user-owned settings and remove only FactionOS-managed entries.

### Testing Requirements

* [ ] CLI lifecycle tests cover start, daemon duplicate prevention, stop, open, stale PID cleanup, port parsing, and workspace-root persistence.
* [ ] CLI runtime tests cover install/init alias behavior, status output, and doctor output with sanitized fixture state.
* [ ] Hook script tests cover backup creation, malformed settings fallback, managed hook replacement, uninstall with backup, uninstall without backup, and atomic write cleanup.
* [ ] Focused Vitest command passes for CLI and hook lifecycle tests.

### Non-Functional Requirements

* [ ] Lifecycle commands use bounded probes, bounded termination, and explicit fallback paths.
* [ ] Local state writes use temp-file-plus-rename where practical.
* [ ] Diagnostics avoid raw hook payloads, prompts, command bodies, terminal output, file contents, tokens, and secret values.
* [ ] Optional hosted services and API keys remain unnecessary.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] Focused tests pass before validation.

***

## 8. Implementation Notes

### Key Considerations

* The old package bundled server and frontend artifacts differently. The current repo is an npm workspace, so launch behavior must be clear about current-workspace support and later publishing limits.
* CLI lifecycle state should be stored under `~/.factionos/` and should not expose private prompts, file contents, or raw hook payloads.
* A PID file proves only that a process existed. Every start, stop, status, and doctor path must validate process liveness and clean stale state deterministically.
* Hook installation must remain idempotent. Re-running install should update managed entries without duplicating them or deleting unrelated user hooks.

### Potential Challenges

* Current workspace launch vs. published package launch: implement a repo-root resolver with precise errors when required package scripts are unavailable.
* Cross-platform browser opening: use platform-specific built-in commands and keep a manual URL fallback.
* Process cleanup in tests: use controlled child processes or mocks and always clean temporary homes and child processes in test teardown.
* Port customization limits: support deterministic server-port state and document any current web-client limitations that are not fixed in this package-focused session.

### Relevant Considerations

* \[P00-apps/hooks+apps/cli] **Atomic-write gap**: Apply temp-write-plus-rename to lifecycle, settings, PID, and hook configuration writes where practical.
* \[P00] **Prompt and path privacy**: Keep diagnostics free of prompts, raw hook payloads, command bodies, file contents, tokens, and secret values.
* \[P00] **Local-first boundary**: Lifecycle commands must not require hosted accounts, optional services, API keys, or remote relays.
* \[P00] **Historical artifacts quarantined**: Use `EXAMPLES/` as evidence only; do not copy old runtime code into current source.
* \[P00] **Monorepo package map**: Keep package boundaries clear and document current command ownership in package READMEs.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Starting the local runtime twice and leaving conflicting child processes or stale PID files behind.
* Removing or corrupting user-owned Claude settings during hook install or uninstall.
* Printing sensitive local data in status, doctor, or error output.

***

## 9. Testing Strategy

### Unit Tests

* Test lifecycle helper behavior for runtime-root resolution, PID read/write, stale cleanup, port parsing, project-root persistence, health probe results, and URL formatting.
* Test browser opener command construction with fake platform branches and a manual fallback path.
* Test hook install/uninstall script helpers against temporary Claude settings.

### Integration Tests

* Run CLI command functions against temporary homes and fake local servers.
* Use controlled child processes or mocks to prove daemon duplicate prevention, stop behavior, and cleanup without touching real user processes.
* Verify install/init aliases and command help text through the CLI dispatch entry point where practical.

### Manual Testing

* From the repository root, run the planned CLI lifecycle commands against a clean temporary `FACTIONOS_HOME` and confirm the reported web and server URLs.
* Confirm `status` and `doctor` output includes lifecycle posture without raw spool contents or hook payloads.
* Confirm `uninstall` removes only FactionOS-managed hook entries in a fixture settings file.

### Edge Cases

* Missing FactionOS workspace scripts.
* Port already in use.
* PID file points to a dead process.
* PID file contains invalid content.
* Server health endpoint is unreachable or times out.
* Existing Claude settings are malformed.
* Existing Claude settings contain unrelated hooks and env values.
* Backup exists before install.
* Uninstall runs without a backup file.

***

## 10. Dependencies

### External Libraries

* None expected. Use Node.js built-ins and existing workspace dependencies.

### Other Sessions

* **Depends on**: `phase01-session01-event-ingest-contract-reconciliation`, `phase01-session02-hook-runtime-safety`
* **Depended by**: `phase01-session04-server-routes-and-authorization-boundaries`, `phase01-session07-runtime-contract-documentation`

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase01-session03-cli-lifecycle-parity/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
