v0.4.1 : Phase 1 complete (17/17) - dashboard TUI (#33), favoris/notes/tags (#39), profils d'environnement (#40), completions dynamiques + man pages (#41), packaging officiel + CI (#42), self-update Gitea, state v3, 212 tests
release / linux (push) Failing after 23s
release / windows (push) Canceled after 0s
release / macos (push) Canceled after 0s

This commit is contained in:
2026-08-17 10:50:13 -04:00
parent 4f4cd034b2
commit 56732d672b
93 changed files with 9412 additions and 1270 deletions
+53 -6
View File
@@ -28,12 +28,47 @@ pub fn start(app: &App, opts: &StartArgs) -> Result<i32> {
start_with_cwd(app, opts, None)
}
/// Apply the environment profile (issue #40): the explicit --profile wins;
/// otherwise the current project's default profile applies when launching
/// the project's default agent.
fn apply_profile(
app: &App,
explicit: Option<&str>,
project_default_agent: bool,
extra_args: &[String],
extra_env: &BTreeMap<String, String>,
) -> Result<(Vec<String>, BTreeMap<String, String>)> {
let mut profile = explicit;
if profile.is_none() && project_default_agent {
let current = std::env::current_dir().unwrap_or_default();
if let Some((_, pp)) = crate::projects::profile_for(app, &current) {
profile = pp.profile.as_deref();
}
}
crate::commands::profile_cmd::apply(app, profile, extra_args, extra_env)
}
/// Start with an explicit working directory (used by sessions resume).
pub fn start_with_cwd(app: &App, opts: &StartArgs, cwd: Option<&std::path::Path>) -> Result<i32> {
let current = std::env::current_dir().unwrap_or_default();
let target = resolve_start_target(app, &current, opts.agent.as_deref())?;
let explicit = opts.agent.as_deref().filter(|s| !s.is_empty());
// A profile may declare its own default agent (issue #40).
let profile_default = profile_cmd::default_agent(app, opts.profile.as_deref())?;
let target = match (explicit, profile_default) {
(Some(a), _) => a.to_string(),
(None, Some(a)) => a.to_string(),
(None, None) => resolve_start_target(app, &current, None)?,
};
let extra_env = parse_env_list(&opts.env)?;
let extra_args = parse_extra_args(&opts.args);
let project_default_agent = explicit.is_none() && profile_default.is_none();
let (extra_args, extra_env) = apply_profile(
app,
opts.profile.as_deref(),
project_default_agent,
&extra_args,
&extra_env,
)?;
if let Some(group) = crate::catalog::Catalog::parse_group_selector(&target) {
let members = app.catalog.group_members(group);
if members.is_empty() {
@@ -228,7 +263,23 @@ fn stop_one(app: &App, agent: &AgentDef, force: bool, timeout: u64) -> Result<i3
pub fn restart(app: &App, opts: &StartArgs, force: bool, timeout: Option<u64>) -> Result<i32> {
let timeout = timeout.unwrap_or_else(|| app.config.settings.stop_timeout());
let cwd = std::env::current_dir().unwrap_or_default();
let target = resolve_start_target(app, &cwd, opts.agent.as_deref())?;
let explicit = opts.agent.as_deref().filter(|s| !s.is_empty());
let profile_default = profile_cmd::default_agent(app, opts.profile.as_deref())?;
let target = match (explicit, profile_default) {
(Some(a), _) => a.to_string(),
(None, Some(a)) => a.to_string(),
(None, None) => resolve_start_target(app, &cwd, None)?,
};
let extra_env = parse_env_list(&opts.env)?;
let extra_args = parse_extra_args(&opts.args);
let project_default_agent = explicit.is_none() && profile_default.is_none();
let (extra_args, extra_env) = apply_profile(
app,
opts.profile.as_deref(),
project_default_agent,
&extra_args,
&extra_env,
)?;
if let Some(group) = crate::catalog::Catalog::parse_group_selector(&target) {
let members = app.catalog.group_members(group);
if members.is_empty() {
@@ -237,8 +288,6 @@ pub fn restart(app: &App, opts: &StartArgs, force: bool, timeout: Option<u64>) -
for m in members.iter().rev() {
stop_one(app, m, force, timeout)?;
}
let extra_env = parse_env_list(&opts.env)?;
let extra_args = parse_extra_args(&opts.args);
for m in members {
start_one(app, m, &extra_args, &extra_env, opts.notify, true, None)?;
}
@@ -246,8 +295,6 @@ pub fn restart(app: &App, opts: &StartArgs, force: bool, timeout: Option<u64>) -
}
let agent = require_agent(app, &target)?;
stop_one(app, agent, force, timeout)?;
let extra_env = parse_env_list(&opts.env)?;
let extra_args = parse_extra_args(&opts.args);
start_one(app, agent, &extra_args, &extra_env, opts.notify, opts.background, None)
}