## Flow CLI Architecture ### Layers `flow` now follows a stricter adapter/service/runtime split: - `flow.cli` - global startup, platform/config loading, top-level error handling - `flow.commands.*` - argparse registration and compatibility wrappers only - `flow.services.*` - domain behavior for SSH entry, containers, dotfiles, bootstrap, packages, and project sync - `flow.core.system` - shared process, git, filesystem, and JSON state primitives - `flow.core.*` - config loading, platform detection, console output, variables ### Runtime Safety Mutating operations are centralized behind `flow.core.system`: - `CommandRunner` - subprocess execution and shell streaming - `GitClient` - repository-scoped git execution - `FileSystem` - directory creation, copy, symlink, removal, JSON/text writes - `JsonStateStore` - state persistence with explicit paths This keeps command handlers out of the business of directly creating, deleting, or overwriting filesystem state. ### Domain Boundaries - `services.ssh` - parses enter targets, resolves host templates, builds the SSH handoff - `services.containers` - owns container create/exec/connect/list/stop/remove/respawn logic - `services.projects` - owns git status/fetch/summary logic for project directories - `services.package_defs` - normalizes manifest package definitions and binary package install logic - `services.packages` - package state listing/install/remove behavior - `services.bootstrap` - provisioning orchestration, package-manager resolution, hooks, shell/locale/hostname setup - `services.dotfiles` - repo sync, module discovery, link planning, transactional undo, status, edit flow ### Compatibility Strategy The current CLI surface is preserved. The command modules still expose a small set of legacy helper symbols because the existing tests use them directly, but the behavioral implementation now lives in the service layer.