返回 CodeWhale
load.rs
根目录 / crates / tui / src / commands / groups / session / load.rs
1 //! `/load` command.
2
3 use super::CommandResult;
4
5 use codewhale_command_contract::facets::CommandSessionLifecycleContext;
6 use codewhale_command_contract::handler::{CommandContexts, CommandHandler};
7 use codewhale_command_contract::metadata::{
8 CommandInfo as ContractInfo, RegisterCommand as ContractRegisterCommand,
9 };
10
11 pub(in crate::commands) struct LoadCmd;
12
13 // ---------------------------------------------------------------------------
14 // FEAT-023 Phase 4 (D3/D5/D6): portable contextual registration and handler.
15 // The handler owns parsing, branch order, exact messages, guidance appends,
16 // and action composition; all concrete host work stays behind the lifecycle
17 // facet. Missing lifecycle authority fails safely with the exact capability
18 // error (never a panic).
19 // ---------------------------------------------------------------------------
20
21 pub(in crate::commands) const CONTRACT_INFO: ContractInfo = ContractInfo {
22 name: "load",
23 aliases: &["jiazai"],
24 usage: "/load [path]",
25 description_key: "cmd_load_description",
26 };
27
28 impl ContractRegisterCommand<CommandResult> for LoadCmd {
29 fn info() -> &'static ContractInfo {
30 &CONTRACT_INFO
31 }
32 fn handler() -> CommandHandler<CommandResult> {
33 CommandHandler::Contextual {
34 capabilities:
35 codewhale_command_contract::handler::CommandCapabilities::SESSION_LIFECYCLE,
36 handler: load_contextual,
37 }
38 }
39 }
40
41 pub(in crate::commands) fn load_contextual(
42 contexts: CommandContexts<'_>,
43 arg: Option<&str>,
44 ) -> CommandResult {
45 let mut parts = contexts.into_parts();
46 let Some(lifecycle) = parts.lifecycle.as_deref_mut() else {
47 return CommandResult::error(
48 "Command capability unavailable: session_lifecycle".to_string(),
49 );
50 };
51 load_portable(lifecycle, arg)
52 }
53
54 pub(in crate::commands) fn load_portable(
55 lifecycle: &mut dyn CommandSessionLifecycleContext,
56 arg: Option<&str>,
57 ) -> CommandResult {
58 if lifecycle.transition_blocked() {
59 return CommandResult::error(
60 "Cannot load a session while runtime work is active. Wait for the current turn, maintenance, and background tasks to finish, or cancel that specific work first."
61 .to_string(),
62 );
63 }
64 let Some(path) = arg.map(str::trim).filter(|p| !p.is_empty()) else {
65 return CommandResult::error("Usage: /load <path>".to_string());
66 };
67 match lifecycle.load_session(path) {
68 Ok(load_path) => CommandResult::action(crate::tui::app::AppAction::LoadSession(load_path)),
69 Err(error) => CommandResult::error(error),
70 }
71 }
72
72 lines RUST