Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
39ade9d
(in progress) Implement checkpointing using git CLI commands
Aug 13, 2025
c5c033f
feat: Add new checkpointing functionality using git CLI
Aug 18, 2025
1760839
feat: Add user message for turn-level checkpoints, clean command
Aug 19, 2025
5a27533
fix: Fix shadow repo deletion logic
Aug 19, 2025
643912d
chore: Run formatter and fix clippy warnings
Aug 19, 2025
7f0cba9
feat: Add checkpoint diff
Aug 19, 2025
30b5a95
fix: Fix last messsage handling for checkpoints
Aug 21, 2025
8eb341a
fix: Fix commit message handling again
Aug 22, 2025
566f0c9
Merge commit
Aug 22, 2025
e38c1f8
Fix merge conflicts
Sep 11, 2025
eae59d5
chore: Run formatter
Sep 11, 2025
bc23993
Removed old comment
Sep 11, 2025
b709854
Merge branch 'main' of github.com:aws/amazon-q-developer-cli into kir…
Sep 11, 2025
a97f3f8
define a global capture dirctory
evanliu048 Sep 12, 2025
25645b1
revise the capture path
evanliu048 Sep 15, 2025
0f74051
fix cpature clean bug
evanliu048 Sep 16, 2025
a9801c0
add a clean all flag
evanliu048 Sep 16, 2025
13a1385
Merge branch 'main' into snapshot_revise
evanliu048 Sep 16, 2025
e1a3cfe
add auto drop method for capture feature
evanliu048 Sep 16, 2025
a44f814
support file details when expand
evanliu048 Sep 17, 2025
3829fa2
add the file summary when list and expand
evanliu048 Sep 17, 2025
0a6e993
revise structure and print no diff msg
evanliu048 Sep 18, 2025
58ea878
delete all flag, add summry when fs read
evanliu048 Sep 18, 2025
f1b76f8
refactor code
evanliu048 Sep 22, 2025
e2c3590
revise ui
evanliu048 Sep 22, 2025
f1f0816
add capture into experiement
evanliu048 Sep 22, 2025
1c366e4
clippy
evanliu048 Sep 22, 2025
594305b
rename to checkpoint
evanliu048 Sep 22, 2025
e9f30d9
reverse false renaming
evanliu048 Sep 22, 2025
9211e75
recover history
evanliu048 Sep 24, 2025
e16541e
disable tangent mode in checkpoint
evanliu048 Sep 24, 2025
049ea08
fix cr
evanliu048 Sep 24, 2025
e479178
nit: keep checkpoint name
evanliu048 Sep 24, 2025
3601482
allow both tangent & checkpoint enabled
evanliu048 Sep 25, 2025
163ed21
Merge branch 'main' into snapshot_revise
evanliu048 Sep 25, 2025
a313dfd
ci
evanliu048 Sep 25, 2025
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
422 changes: 422 additions & 0 deletions crates/chat-cli/src/cli/chat/checkpoint.rs

Large diffs are not rendered by default.

573 changes: 573 additions & 0 deletions crates/chat-cli/src/cli/chat/cli/checkpoint.rs

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions crates/chat-cli/src/cli/chat/cli/experiment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ static AVAILABLE_EXPERIMENTS: &[Experiment] = &[
description: "Enables Q to create todo lists that can be viewed and managed using /todos",
setting_key: Setting::EnabledTodoList,
},
Experiment {
name: "Checkpoint",
description: concat!(
"Enables workspace checkpoints to snapshot, list, expand, diff, and restore files (/checkpoint)\n",
" ",
"Cannot be used in tangent mode (to avoid mixing up conversation history)"
),
setting_key: Setting::EnabledCheckpoint,
},
Experiment {
name: "Context Usage Indicator",
description: "Shows context usage percentage in the prompt (e.g., [rust-agent] 6% >)",
Expand Down
6 changes: 6 additions & 0 deletions crates/chat-cli/src/cli/chat/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod changelog;
pub mod checkpoint;
pub mod clear;
pub mod compact;
pub mod context;
Expand Down Expand Up @@ -35,6 +36,7 @@ use tangent::TangentArgs;
use todos::TodoSubcommand;
use tools::ToolsArgs;

use crate::cli::chat::cli::checkpoint::CheckpointSubcommand;
use crate::cli::chat::cli::subscribe::SubscribeArgs;
use crate::cli::chat::cli::usage::UsageArgs;
use crate::cli::chat::consts::AGENT_MIGRATION_DOC_URL;
Expand Down Expand Up @@ -102,6 +104,8 @@ pub enum SlashCommand {
Persist(PersistSubcommand),
// #[command(flatten)]
// Root(RootSubcommand),
#[command(subcommand)]
Checkpoint(CheckpointSubcommand),
/// View, manage, and resume to-do lists
#[command(subcommand)]
Todos(TodoSubcommand),
Expand Down Expand Up @@ -169,6 +173,7 @@ impl SlashCommand {
// skip_printing_tools: true,
// })
// },
Self::Checkpoint(subcommand) => subcommand.execute(os, session).await,
Self::Todos(subcommand) => subcommand.execute(os, session).await,
}
}
Expand Down Expand Up @@ -198,6 +203,7 @@ impl SlashCommand {
PersistSubcommand::Save { .. } => "save",
PersistSubcommand::Load { .. } => "load",
},
Self::Checkpoint(_) => "checkpoint",
Self::Todos(_) => "todos",
}
}
Expand Down
33 changes: 33 additions & 0 deletions crates/chat-cli/src/cli/chat/cli/tangent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ impl TangentArgs {

match self.subcommand {
Some(TangentSubcommand::Tail) => {
// Check if checkpoint is enabled
if os
.database
.settings
.get_bool(Setting::EnabledCheckpoint)
.unwrap_or(false)
{
execute!(
session.stderr,
style::SetForegroundColor(Color::Yellow),
style::Print(
"⚠️ Checkpoint is disabled while in tangent mode. Please exit tangent mode if you want to use checkpoint.\n"
),
style::SetForegroundColor(Color::Reset),
)?;
}
if session.conversation.is_in_tangent_mode() {
let duration_seconds = session.conversation.get_tangent_duration_seconds().unwrap_or(0);
session.conversation.exit_tangent_mode_with_tail();
Expand Down Expand Up @@ -106,6 +122,23 @@ impl TangentArgs {
style::SetForegroundColor(Color::Reset)
)?;
} else {
// Check if checkpoint is enabled
if os
.database
.settings
.get_bool(Setting::EnabledCheckpoint)
.unwrap_or(false)
{
execute!(
session.stderr,
style::SetForegroundColor(Color::Yellow),
style::Print(
"⚠️ Checkpoint is disabled while in tangent mode. Please exit tangent mode if you want to use checkpoint.\n"
),
style::SetForegroundColor(Color::Reset),
)?;
}

session.conversation.enter_tangent_mode();

// Get the configured tangent mode key for display
Expand Down
21 changes: 21 additions & 0 deletions crates/chat-cli/src/cli/chat/conversation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ use crate::cli::agent::hook::{
HookTrigger,
};
use crate::cli::chat::ChatError;
use crate::cli::chat::checkpoint::{
Checkpoint,
CheckpointManager,
};
use crate::cli::chat::cli::model::{
ModelInfo,
get_model_info,
Expand Down Expand Up @@ -138,6 +142,8 @@ pub struct ConversationState {
/// Maps from a file path to [FileLineTracker]
#[serde(default)]
pub file_line_tracker: HashMap<String, FileLineTracker>,

pub checkpoint_manager: Option<CheckpointManager>,
#[serde(default = "default_true")]
pub mcp_enabled: bool,
/// Tangent mode checkpoint - stores main conversation when in tangent mode
Expand Down Expand Up @@ -203,6 +209,7 @@ impl ConversationState {
model: None,
model_info: model,
file_line_tracker: HashMap::new(),
checkpoint_manager: None,
mcp_enabled,
tangent_state: None,
}
Expand Down Expand Up @@ -891,6 +898,20 @@ Return only the JSON configuration, no additional text.",
self.transcript.push_back(message);
}

/// Restore conversation from a checkpoint's history snapshot
pub fn restore_to_checkpoint(&mut self, checkpoint: &Checkpoint) -> Result<(), eyre::Report> {
// 1. Restore history from snapshot
self.history = checkpoint.history_snapshot.clone();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious? Can a checkpoint corrupt conversation history by any means? Like a tool use without tool results and so on?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checkpoint is created after the tool executes successfully and in handle_response, so that should be fine. Thanks for the callout — we can test it more thoroughly during the bug bash


// 2. Clear any pending next message (uncommitted state)
self.next_message = None;

// 3. Update valid history range
self.valid_history_range = (0, self.history.len());

Ok(())
}

/// Swapping agent involves the following:
/// - Reinstantiate the context manager
/// - Swap agent on tool manager
Expand Down
Loading
Loading