(
project_path: &Path,
home: &Path,
options: CodexAutomationInstall,
)
| 135 | } |
| 136 | |
| 137 | async fn install_codex_daemon_automation( |
| 138 | project_path: &Path, |
| 139 | home: &Path, |
| 140 | options: CodexAutomationInstall, |
| 141 | ) -> tracedecay::errors::Result<PathBuf> { |
| 142 | let auto_apply = options.auto_apply; |
| 143 | if tracedecay::agents::codex::remove_legacy_codex_native_automation(home)? { |
| 144 | eprintln!( |
| 145 | "\x1b[32m✔\x1b[0m Removed the legacy Codex-native scheduled automation; the TraceDecay daemon loop replaces it." |
| 146 | ); |
| 147 | } |
| 148 | |
| 149 | let cg = open_or_init_codex_daemon_automation_project(project_path).await?; |
| 150 | let dashboard_root = cg.store_layout().dashboard_root.clone(); |
| 151 | let patch = AutomationConfigPatch { |
| 152 | enabled: Some(true), |
| 153 | backend: Some(AutomationBackend::CodexAppServer), |
| 154 | host_mode: Some(AutomationHostMode::Standalone), |
| 155 | model: Some(Some("gpt-5.5".to_string())), |
| 156 | // Unattended memory-op apply is opt-in: without --auto-apply these |
| 157 | // stay unset so AutomationConfig::default() keeps dashboard approval |
| 158 | // required, and re-running the installer never weakens stricter |
| 159 | // settings a user already chose. |
| 160 | require_dashboard_approval: auto_apply.then_some(false), |
| 161 | auto_apply_memory_ops: auto_apply.then_some(true), |
| 162 | memory_curator: codex_daemon_interval_task(15 * 60), |
| 163 | session_reflector: codex_daemon_interval_task(15 * 60), |
| 164 | skill_writer: AutomationTaskPatch { |
| 165 | min_idle_secs: Some(Some(15 * 60)), |
| 166 | ..codex_daemon_interval_task(60 * 60) |
| 167 | }, |
| 168 | ..AutomationConfigPatch::default() |
| 169 | }; |
| 170 | |
| 171 | let global = tracedecay::user_config::UserConfig::load().automation; |
| 172 | apply_project_config_patch(&dashboard_root, &global, patch).await?; |
| 173 | let path = project_config_path(&dashboard_root); |
| 174 | eprintln!( |
| 175 | "\x1b[32m✔\x1b[0m Enabled TraceDecay daemon automation loop at {}", |
| 176 | path.display() |
| 177 | ); |
| 178 | eprintln!( |
| 179 | " The daemon scheduler will run memory_curator, session_reflector, and skill_writer via the Codex app-server backend." |
| 180 | ); |
| 181 | if auto_apply { |
| 182 | eprintln!( |
| 183 | "\x1b[33m⚠\x1b[0m --auto-apply: accepted memory-curation ops (deletes and merges) will be applied without dashboard approval. There is no archive; removals are permanent." |
| 184 | ); |
| 185 | } |
| 186 | if !tracedecay::daemon::daemon_reachable() { |
| 187 | eprintln!( |
| 188 | "\x1b[33m⚠\x1b[0m The TraceDecay daemon is not running, so the automation loop will stay idle. Enable it with `tracedecay daemon install-service`." |
| 189 | ); |
| 190 | } |
| 191 | Ok(path) |
| 192 | } |
| 193 | |
| 194 | async fn open_or_init_codex_daemon_automation_project( |
no test coverage detected