use crate::workspace::Workspace;
use crate::{CliError, CliResult};
use super::load_active;
#[aristo::intent(
"`aristo session active` is wired into Claude Code's \
UserPromptSubmit hook (Layer 2). The hook fires on EVERY prompt \
across EVERY project, not only aristo workspaces. So `active` \
must exit 0 with empty stdout when run outside an aristo \
workspace — a hard error would block every prompt in any \
non-aristo project the user opens. The interactive form (no \
`--hook-format`) follows the same rule for symmetry: an active \
session can only exist within a workspace anyway, so no-workspace \
and no-session are observationally identical at the CLI surface.",
verify = "neural",
id = "session_active_is_noop_outside_workspace"
)]
pub(crate) fn run(hook_format: bool) -> CliResult<()> {
let Ok(ws) = Workspace::find(None) else {
return Ok(());
};
let session = match load_active(&ws) {
Ok(s) => s,
Err(CliError::NotInWorkspace { .. }) => return Ok(()),
Err(e) => return Err(e),
};
if hook_format {
emit_hook_block(session.as_ref());
} else if let Some(s) = session {
println!("{}", s.id);
}
Ok(())
}
fn emit_hook_block(session: Option<&crate::session::types::Session>) {
let Some(s) = session else {
return;
};
let counts = s.bucket_counts();
println!("<system-reminder>");
println!("You are currently in an aristo review session:");
println!(" id: {}", s.id);
println!(" kind: {}", s.kind);
println!(" subject: {}", s.subject);
println!(
" items: {} open, {} accepted, {} rejected, {} pending",
counts.open, counts.accepted, counts.rejected, counts.pending
);
println!();
println!("While this session is active:");
println!(" - You cannot start a different review session, run aristo");
println!(" mutation commands, or move to planning/implementation.");
println!(" - You may: continue this review, run read-only aristo commands,");
println!(" have discussion with the user.");
println!(" - Direct file edits via Edit are allowed but discouraged");
println!(" (any unrelated change should wait for clean exit).");
println!();
println!("Commands:");
println!(" aristo session status # peek state");
println!(" aristo session decide --item <ref> --bucket <accepted|rejected|pending>");
println!(" aristo session exit # strict close (all items decided)");
println!(" aristo session exit --defer-undecided # close, move open items to pending");
println!(" aristo session abort # destructive cancel");
println!("</system-reminder>");
}