Skip to content

Commit df79b34

Browse files
committed
Workspace rules for Claude sessions will use the original session ID if available
1 parent 6f611da commit df79b34

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

crates/but-claude/src/db.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ pub fn get_session_by_id(
5252
}
5353
}
5454

55+
pub fn get_session_by_current_id(
56+
ctx: &mut CommandContext,
57+
current_id: Uuid,
58+
) -> anyhow::Result<Option<ClaudeSession>> {
59+
let session = ctx
60+
.db()?
61+
.claude_sessions()
62+
.get_by_current_id(&current_id.to_string())?;
63+
match session {
64+
Some(s) => Ok(Some(s.try_into()?)),
65+
None => Ok(None),
66+
}
67+
}
68+
5569
/// Deletes a Claude session and all associated messages from the database. This is what we want to use when we want to delete a session completely.
5670
pub fn delete_session_and_messages_by_id(
5771
ctx: &mut CommandContext,

crates/but-claude/src/hooks/mod.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,11 @@ pub async fn handle_stop() -> anyhow::Result<ClaudeHookOutput> {
118118
let prompt = transcript.prompt().unwrap_or_default();
119119

120120
let ctx = &mut CommandContext::open(&project, AppSettings::load_from_default_path_creating()?)?;
121+
let session_id = original_session_id(ctx, input.session_id.clone())?;
121122

122123
let defer = ClearLocksGuard {
123124
ctx,
124-
session_id: input.session_id.clone(),
125+
session_id: session_id.clone(),
125126
file_path: None,
126127
};
127128

@@ -131,14 +132,14 @@ pub async fn handle_stop() -> anyhow::Result<ClaudeHookOutput> {
131132

132133
// If the session stopped, but there's no session persisted in the database, we create a new one.
133134
// If the session is already persisted, we just retrieve it.
134-
let stack_id = get_or_create_session(defer.ctx, &input.session_id, stacks, vb_state)?;
135+
let stack_id = get_or_create_session(defer.ctx, &session_id, stacks, vb_state)?;
135136

136137
let (id, outcome) = but_action::handle_changes(
137138
defer.ctx,
138139
&summary,
139140
Some(prompt.clone()),
140141
ActionHandler::HandleChangesSimple,
141-
Source::ClaudeCode(input.session_id),
142+
Source::ClaudeCode(session_id),
142143
Some(stack_id),
143144
)?;
144145

@@ -310,8 +311,9 @@ pub fn handle_pre_tool_call() -> anyhow::Result<ClaudeHookOutput> {
310311
input.tool_input.file_path = relative_file_path;
311312

312313
let ctx = &mut CommandContext::open(&project, AppSettings::load_from_default_path_creating()?)?;
314+
let session_id = original_session_id(ctx, input.session_id.clone())?;
313315

314-
file_lock::obtain(ctx, input.session_id, input.tool_input.file_path.clone())?;
316+
file_lock::obtain(ctx, session_id, input.tool_input.file_path.clone())?;
315317

316318
Ok(ClaudeHookOutput {
317319
do_continue: true,
@@ -355,18 +357,19 @@ pub fn handle_post_tool_call() -> anyhow::Result<ClaudeHookOutput> {
355357
input.tool_response.file_path = relative_file_path;
356358

357359
let ctx = &mut CommandContext::open(&project, AppSettings::load_from_default_path_creating()?)?;
360+
let session_id = original_session_id(ctx, input.session_id.clone())?;
358361

359362
let defer = ClearLocksGuard {
360363
ctx,
361-
session_id: input.session_id.clone(),
364+
session_id: session_id.clone(),
362365
file_path: Some(input.tool_response.file_path.clone()),
363366
};
364367

365368
let stacks = list_stacks(defer.ctx)?;
366369

367370
let vb_state = &VirtualBranchesHandle::new(defer.ctx.project().gb_dir());
368371

369-
let stack_id = get_or_create_session(defer.ctx, &input.session_id, stacks, vb_state)?;
372+
let stack_id = get_or_create_session(defer.ctx, &session_id, stacks, vb_state)?;
370373

371374
let changes = but_core::diff::ui::worktree_changes_by_worktree_dir(project.path)?.changes;
372375
let (assignments, _assignments_error) = but_hunk_assignment::assignments_with_fallback(
@@ -404,6 +407,16 @@ pub fn handle_post_tool_call() -> anyhow::Result<ClaudeHookOutput> {
404407
})
405408
}
406409

410+
fn original_session_id(ctx: &mut CommandContext, current_id: String) -> Result<String> {
411+
let original_session_id =
412+
crate::db::get_session_by_current_id(ctx, Uuid::parse_str(&current_id)?)?;
413+
if let Some(session) = original_session_id {
414+
Ok(session.id.to_string())
415+
} else {
416+
Ok(current_id)
417+
}
418+
}
419+
407420
fn get_or_create_session(
408421
ctx: &mut CommandContext,
409422
session_id: &str,

crates/but-db/src/claude.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ impl ClaudeSessionsHandle<'_> {
112112
Ok(session)
113113
}
114114

115+
pub fn get_by_current_id(
116+
&mut self,
117+
current_id: &str,
118+
) -> Result<Option<ClaudeSession>, diesel::result::Error> {
119+
let session = claude_sessions
120+
.filter(crate::schema::claude_sessions::current_id.eq(current_id))
121+
.first::<ClaudeSession>(&mut self.db.conn)
122+
.optional()?;
123+
Ok(session)
124+
}
125+
115126
pub fn list(&mut self) -> Result<Vec<ClaudeSession>, diesel::result::Error> {
116127
let sessions = claude_sessions.load::<ClaudeSession>(&mut self.db.conn)?;
117128
Ok(sessions)

0 commit comments

Comments
 (0)