Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ pub(crate) struct Args {
#[arg(long = "models", global = true, value_delimiter = ',')]
pub(crate) scoped_models: Vec<String>,

/// Set the human-readable title (display name) of the new session. Visible
/// in `jcode --resume` and the session picker. Equivalent to setting
/// `JCODE_SESSION_NAME`. Existing sessions are unaffected — use
/// `jcode session rename <id> <name>` for those.
#[arg(long = "name", alias = "session-name", global = true)]
pub(crate) session_name: Option<String>,

/// Log tool inputs/outputs and token usage to stderr
#[arg(long, global = true)]
pub(crate) trace: bool,
Expand Down
9 changes: 9 additions & 0 deletions src/cli/startup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ fn parse_and_prepare_args() -> Result<Args> {
}
}

// --name <title>: translate to env so the next freshly-created top-level
// session picks it up as `Session::title`. Issue #99.
if let Some(ref text) = args.session_name {
let trimmed = text.trim();
if !trimmed.is_empty() {
crate::env::set_var("JCODE_SESSION_NAME", trimmed);
}
}

if let Some(ref socket) = args.socket {
server::set_socket_path(socket);
}
Expand Down
14 changes: 14 additions & 0 deletions src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,20 @@ impl Session {
}

pub fn create(parent_id: Option<String>, title: Option<String>) -> Self {
// Issue #99: top-level user sessions can be auto-titled via
// `jcode --name <title>` (translated to `JCODE_SESSION_NAME`). Only
// apply when the caller didn't pass an explicit title and there is
// no parent (subagents/spawned children should not inherit the env).
let title = title.or_else(|| {
if parent_id.is_none() {
std::env::var("JCODE_SESSION_NAME")
.ok()
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
} else {
None
}
});
let now = Utc::now();
let (id, short_name) = new_memorable_session_id();
let is_debug = default_is_test_session();
Expand Down
24 changes: 24 additions & 0 deletions src/session_tests/cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,3 +1223,27 @@ fn test_render_messages_and_images_share_tool_resolution_and_labels() {
}
);
}

#[test]
fn jcode_session_name_env_titles_top_level_session() {
// Issue #99: `jcode --name "my-session"` is wired through the
// JCODE_SESSION_NAME env var so a freshly-created top-level session picks
// it up as Session::title. Subagents (parent_id=Some) must not inherit it
// so spawn children stay random-named for clarity.
let _lock = crate::storage::lock_test_env();
let _name = EnvVarGuard::set("JCODE_SESSION_NAME", "my custom title");

let top = Session::create(None, None);
assert_eq!(top.title.as_deref(), Some("my custom title"));

let spawned = Session::create(Some("parent_x".to_string()), None);
assert!(
spawned.title.is_none(),
"child sessions must not inherit JCODE_SESSION_NAME, got {:?}",
spawned.title
);

// Explicit title still wins over the env.
let explicit = Session::create(None, Some("explicit".to_string()));
assert_eq!(explicit.title.as_deref(), Some("explicit"));
}