travelagent-core 1.11.1

Core library for travelagent code review tool
Documentation
//! Shared MCP request DTOs used by both the TUI-embedded bridge
//! (`travelagent-tui::mcp_bridge`) and the standalone MCP server
//! (`travelagent-mcp::server`).
//!
//! Each type derives `serde::Deserialize` + `schemars::JsonSchema` so `rmcp`
//! can pick it up as a tool input. Field `#[schemars(description = ...)]`
//! attributes seed the auto-generated schema that the MCP tool list exposes
//! to the agent — keep them clear and keep both surfaces in sync by using
//! only the types defined here.
//!
//! Bridge-only inputs (tour navigation, `SelectFile`, etc.) stay in the TUI
//! crate because they mutate App state the standalone server has no access
//! to.

// Use rmcp's re-exported `schemars` so we pick up whatever version rmcp is
// compiled against — a direct dep on `schemars` at a different major risks
// two copies in the graph and breaks the `JsonSchema` trait bound on
// `rmcp::Parameters<T>`.
use rmcp::schemars::{self, JsonSchema};
use serde::Deserialize;

/// Input for `trv_get_diff`: fetch the parsed diff for a single file.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct GetDiffRequest {
    #[schemars(description = "File path to get diff for")]
    pub file: String,
}

/// Input for `trv_add_comment`: attach a line-scoped review comment.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct AddCommentRequest {
    #[schemars(description = "File path")]
    pub file: String,
    #[schemars(description = "Line number")]
    pub line: u32,
    #[schemars(description = "Side: 'old' or 'new'")]
    pub side: String,
    #[schemars(description = "Comment text")]
    pub body: String,
    #[schemars(description = "Comment type: note, suggestion, issue, praise, question")]
    pub comment_type: Option<String>,
}

/// Input for `trv_mark_reviewed`: flag a file as reviewed in the session.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct MarkReviewedRequest {
    #[schemars(description = "File path to mark as reviewed")]
    pub file: String,
}

/// Input for `trv_get_comments`: list/filter comments, optionally with a
/// unix-ms `since` cursor.
///
/// When `since` is absent the response is a plain JSON array (legacy shape).
/// When `since` is set the response is wrapped in `{comments, server_time}`
/// so the agent can literally round-trip `server_time` as the next `since`.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct GetCommentsRequest {
    #[schemars(description = "Optional file path to filter comments")]
    pub file: Option<String>,
    /// Unix milliseconds cursor. When set, only return comments whose
    /// `created_at` is at or after this timestamp, or whose anchor flipped
    /// to `Orphaned` at or after it, or whose anchor flipped back from
    /// `Orphaned` to `Anchored` at or after it. When absent the response is
    /// a plain array (legacy shape); when present it is wrapped in
    /// `{"comments": [...], "server_time": <unix-ms i64>}` so agents can
    /// literally round-trip `server_time` as the next `since`.
    #[serde(default)]
    #[schemars(
        description = "Optional unix-ms cursor. Filters to comments created at/after this timestamp, or whose anchor flipped to Orphaned at/after it. When set, the response is wrapped with a server_time cursor."
    )]
    pub since: Option<i64>,
}

/// Input for `trv_submit_review`: post a review to the remote forge.
///
/// Lives in core so the forthcoming `ReviewController` trait (Phase 4) can
/// share the same shape across both servers, even though the bridge doesn't
/// currently expose this tool.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct SubmitReviewRequest {
    #[schemars(description = "Review verdict: 'comment', 'approve', or 'request_changes'")]
    pub verdict: String,
    #[schemars(description = "Review body text")]
    pub body: String,
}

/// Input for tools that take no arguments (e.g. `trv_list_files`). Kept as a
/// distinct unit struct because `rmcp` expects every tool to have an input
/// type with a `JsonSchema` implementation.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct EmptyRequest {}

/// Input for `trv_set_ai_summary`: replace the in-memory AI summary.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct SetAiSummaryRequest {
    #[schemars(
        description = "Markdown body that will replace the current AI summary. Capped at 64KB."
    )]
    pub markdown: String,
}

/// Input for `trv_list_prs`: list PRs/MRs on a repository.
///
/// Lives in core so the standalone server and the eventual controller trait
/// share the same shape.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct ListPrsRequest {
    #[schemars(
        description = "Repository owner/org. Optional; defaults to the remote PR's owner when one is loaded."
    )]
    pub owner: Option<String>,
    #[schemars(
        description = "Repository name. Optional; defaults to the remote PR's repo when one is loaded."
    )]
    pub repo: Option<String>,
    #[schemars(description = "Filter by state: 'open', 'closed', or 'merged'. Default: open.")]
    pub state: Option<String>,
    #[schemars(description = "Filter by author login.")]
    pub author: Option<String>,
    #[schemars(description = "Max rows to return (capped at 100).")]
    pub max: Option<u32>,
}