cli: extract agent and admin commands from main.rs
Move agent handlers (consolidate, replay, digest, experience-mine,
fact-mine, knowledge-loop, apply-*) into cli/agent.rs.
Move admin handlers (init, fsck, dedup, bulk-rename, health,
daily-check, import, export) into cli/admin.rs.
Functions tightly coupled to Clap types (cmd_daemon, cmd_digest,
cmd_apply_agent, cmd_experience_mine) remain in main.rs.
main.rs: 3130 → 1586 lines (49% reduction).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-03-14 18:06:27 -04:00
|
|
|
// cli/agent.rs — agent subcommand handlers
|
|
|
|
|
|
|
|
|
|
use crate::store;
|
2026-04-12 02:12:31 -04:00
|
|
|
use crate::subconscious::digest;
|
cli: extract agent and admin commands from main.rs
Move agent handlers (consolidate, replay, digest, experience-mine,
fact-mine, knowledge-loop, apply-*) into cli/agent.rs.
Move admin handlers (init, fsck, dedup, bulk-rename, health,
daily-check, import, export) into cli/admin.rs.
Functions tightly coupled to Clap types (cmd_daemon, cmd_digest,
cmd_apply_agent, cmd_experience_mine) remain in main.rs.
main.rs: 3130 → 1586 lines (49% reduction).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-03-14 18:06:27 -04:00
|
|
|
|
2026-04-09 20:07:05 -04:00
|
|
|
pub fn cmd_run_agent(agent: &str, count: usize, target: &[String], query: Option<&str>, dry_run: bool, _local: bool, state_dir: Option<&str>) -> Result<(), String> {
|
2026-03-24 12:32:46 -04:00
|
|
|
// Mark as agent so tool calls (e.g. poc-memory render) don't
|
|
|
|
|
// pollute the user's seen set as a side effect
|
|
|
|
|
// SAFETY: single-threaded at this point (CLI startup, before any agent work)
|
|
|
|
|
unsafe { std::env::set_var("POC_AGENT", "1"); }
|
|
|
|
|
|
2026-03-26 14:22:05 -04:00
|
|
|
// Override agent output/state directory if specified
|
|
|
|
|
if let Some(dir) = state_dir {
|
|
|
|
|
std::fs::create_dir_all(dir).map_err(|e| format!("create state dir: {}", e))?;
|
|
|
|
|
unsafe { std::env::set_var("POC_AGENT_OUTPUT_DIR", dir); }
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-16 18:13:24 -04:00
|
|
|
if dry_run {
|
2026-03-18 22:44:36 -04:00
|
|
|
unsafe { std::env::set_var("POC_MEMORY_DRY_RUN", "1"); }
|
2026-03-16 18:13:24 -04:00
|
|
|
}
|
2026-03-21 15:04:47 -04:00
|
|
|
|
2026-03-16 18:13:24 -04:00
|
|
|
let mut store = store::Store::load()?;
|
2026-03-16 19:09:18 -04:00
|
|
|
|
2026-03-17 01:03:43 -04:00
|
|
|
// Resolve targets: explicit --target, --query, or agent's default query
|
|
|
|
|
let resolved_targets: Vec<String> = if !target.is_empty() {
|
|
|
|
|
target.to_vec()
|
|
|
|
|
} else if let Some(q) = query {
|
|
|
|
|
let graph = store.build_graph();
|
2026-04-11 20:42:58 -04:00
|
|
|
let stages = crate::query_parser::parse_stages(q)?;
|
2026-03-17 01:03:43 -04:00
|
|
|
let results = crate::search::run_query(&stages, vec![], &graph, &store, false, count);
|
|
|
|
|
if results.is_empty() {
|
|
|
|
|
return Err(format!("query returned no results: {}", q));
|
|
|
|
|
}
|
|
|
|
|
let keys: Vec<String> = results.into_iter().map(|(k, _)| k).collect();
|
2026-03-22 01:57:47 -04:00
|
|
|
println!("[{}] query matched {} nodes", agent, keys.len());
|
2026-03-17 01:03:43 -04:00
|
|
|
keys
|
|
|
|
|
} else {
|
|
|
|
|
vec![] // use agent's built-in query
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if !resolved_targets.is_empty() {
|
2026-04-09 20:07:05 -04:00
|
|
|
for (i, key) in resolved_targets.iter().enumerate() {
|
|
|
|
|
println!("[{}] [{}/{}] {}", agent, i + 1, resolved_targets.len(), key);
|
|
|
|
|
if i > 0 { store = store::Store::load()?; }
|
|
|
|
|
if let Err(e) = crate::agent::oneshot::run_one_agent(
|
|
|
|
|
&mut store, agent, count, Some(&[key.clone()]),
|
|
|
|
|
) {
|
|
|
|
|
println!("[{}] ERROR on {}: {}", agent, key, e);
|
2026-03-17 01:24:54 -04:00
|
|
|
}
|
|
|
|
|
}
|
2026-03-16 19:09:18 -04:00
|
|
|
} else {
|
2026-03-21 15:04:47 -04:00
|
|
|
// Local execution (--local, --debug, dry-run, or daemon unavailable)
|
2026-04-04 17:25:10 -04:00
|
|
|
crate::agent::oneshot::run_one_agent(
|
2026-04-07 01:23:22 -04:00
|
|
|
&mut store, agent, count, None,
|
2026-03-16 19:09:18 -04:00
|
|
|
)?;
|
|
|
|
|
}
|
2026-03-16 18:13:24 -04:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
cli: extract agent and admin commands from main.rs
Move agent handlers (consolidate, replay, digest, experience-mine,
fact-mine, knowledge-loop, apply-*) into cli/agent.rs.
Move admin handlers (init, fsck, dedup, bulk-rename, health,
daily-check, import, export) into cli/admin.rs.
Functions tightly coupled to Clap types (cmd_daemon, cmd_digest,
cmd_apply_agent, cmd_experience_mine) remain in main.rs.
main.rs: 3130 → 1586 lines (49% reduction).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-03-14 18:06:27 -04:00
|
|
|
pub fn cmd_replay_queue(count: usize) -> Result<(), String> {
|
|
|
|
|
let store = store::Store::load()?;
|
|
|
|
|
let queue = crate::neuro::replay_queue(&store, count);
|
|
|
|
|
println!("Replay queue ({} items):", queue.len());
|
|
|
|
|
for (i, item) in queue.iter().enumerate() {
|
|
|
|
|
println!(" {:2}. [{:.3}] {:>10} {} (interval={}d, emotion={:.1}, spectral={:.1})",
|
|
|
|
|
i + 1, item.priority, item.classification, item.key,
|
|
|
|
|
item.interval_days, item.emotion, item.outlier_score);
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn cmd_digest_links(do_apply: bool) -> Result<(), String> {
|
|
|
|
|
let store = store::Store::load()?;
|
2026-04-12 02:12:31 -04:00
|
|
|
let links = digest::parse_all_digest_links(&store);
|
cli: extract agent and admin commands from main.rs
Move agent handlers (consolidate, replay, digest, experience-mine,
fact-mine, knowledge-loop, apply-*) into cli/agent.rs.
Move admin handlers (init, fsck, dedup, bulk-rename, health,
daily-check, import, export) into cli/admin.rs.
Functions tightly coupled to Clap types (cmd_daemon, cmd_digest,
cmd_apply_agent, cmd_experience_mine) remain in main.rs.
main.rs: 3130 → 1586 lines (49% reduction).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-03-14 18:06:27 -04:00
|
|
|
drop(store);
|
|
|
|
|
println!("Found {} unique links from digest nodes", links.len());
|
|
|
|
|
|
|
|
|
|
if !do_apply {
|
|
|
|
|
for (i, link) in links.iter().enumerate() {
|
|
|
|
|
println!(" {:3}. {} → {}", i + 1, link.source, link.target);
|
|
|
|
|
if !link.reason.is_empty() {
|
2026-04-08 19:33:05 -04:00
|
|
|
println!(" ({})", &link.reason[..link.reason.floor_char_boundary(link.reason.len().min(80))]);
|
cli: extract agent and admin commands from main.rs
Move agent handlers (consolidate, replay, digest, experience-mine,
fact-mine, knowledge-loop, apply-*) into cli/agent.rs.
Move admin handlers (init, fsck, dedup, bulk-rename, health,
daily-check, import, export) into cli/admin.rs.
Functions tightly coupled to Clap types (cmd_daemon, cmd_digest,
cmd_apply_agent, cmd_experience_mine) remain in main.rs.
main.rs: 3130 → 1586 lines (49% reduction).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-03-14 18:06:27 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
println!("\nTo apply: poc-memory digest-links --apply");
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut store = store::Store::load()?;
|
2026-04-12 02:12:31 -04:00
|
|
|
let (applied, skipped, fallbacks) = digest::apply_digest_links(&mut store, &links);
|
cli: extract agent and admin commands from main.rs
Move agent handlers (consolidate, replay, digest, experience-mine,
fact-mine, knowledge-loop, apply-*) into cli/agent.rs.
Move admin handlers (init, fsck, dedup, bulk-rename, health,
daily-check, import, export) into cli/admin.rs.
Functions tightly coupled to Clap types (cmd_daemon, cmd_digest,
cmd_apply_agent, cmd_experience_mine) remain in main.rs.
main.rs: 3130 → 1586 lines (49% reduction).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-03-14 18:06:27 -04:00
|
|
|
println!("\nApplied: {} ({} file-level fallbacks) Skipped: {}", applied, fallbacks, skipped);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|