construct/commands/install.rs
1//! `construct install` — unified post-build install flow.
2//!
3//! Today only the `--sidecars-only` path is implemented: it provisions the
4//! Kumiho + Operator Python MCP sidecars under `~/.construct/`. The full
5//! install flow (prerequisite checks, onboard, dashboard launch) will migrate
6//! into this module over time; until then, `install.sh` / `setup.bat` remain
7//! canonical for a full install.
8
9use anyhow::{Result, anyhow};
10
11use crate::sidecars::{self, SidecarInstallOptions};
12
13/// Options for `construct install`.
14#[derive(Debug, Default, Clone)]
15pub struct InstallOptions {
16 /// Install only the Python MCP sidecars (Kumiho + Operator).
17 pub sidecars_only: bool,
18 /// Skip installing the Kumiho sidecar.
19 pub skip_kumiho: bool,
20 /// Skip installing the Operator sidecar.
21 pub skip_operator: bool,
22 /// Opt-in: install the Node.js Session Manager sidecar.
23 ///
24 /// Default `false`. When false, agents run via the subprocess path
25 /// (`claude --print` + `codex exec`) which uses each CLI's own OAuth
26 /// → routes spawned-agent calls through the user's Claude Pro/Max +
27 /// Codex CLI subscriptions. When true, agents run via the Claude
28 /// Agent SDK in the Session Manager — supports streaming timeline
29 /// events but requires `ANTHROPIC_API_KEY` (pay-per-token).
30 pub with_session_manager: bool,
31 /// Print what would be done without executing.
32 pub dry_run: bool,
33 /// Optional explicit Python interpreter.
34 pub python: Option<String>,
35}
36
37/// Run the install command with the given options.
38pub async fn run(opts: InstallOptions) -> Result<()> {
39 if !opts.sidecars_only {
40 return Err(anyhow!(
41 "Full install is not yet implemented as a Rust subcommand.\n\
42 Use one of:\n \
43 construct install --sidecars-only # install Kumiho + Operator Python MCP sidecars\n \
44 ./install.sh # full POSIX install (source build + sidecars + onboard)\n \
45 setup.bat # full Windows install"
46 ));
47 }
48
49 sidecars::install_sidecars(&SidecarInstallOptions {
50 skip_kumiho: opts.skip_kumiho,
51 skip_operator: opts.skip_operator,
52 with_session_manager: opts.with_session_manager,
53 dry_run: opts.dry_run,
54 python: opts.python,
55 })
56 .await
57}