diff options
| author | main <main@swarm.moe> | 2026-03-20 20:17:52 -0400 |
|---|---|---|
| committer | main <main@swarm.moe> | 2026-03-20 20:17:52 -0400 |
| commit | 45106b90f3bc57ac360b6f128e3beed4ec2fdc16 (patch) | |
| tree | c2c118f592404764c7225eb7fc8ee83f1f172e70 /crates | |
| parent | 7df3b42de1d040d2c2b628bb528d10f51ea51f3b (diff) | |
| download | adequate-rust-mcp-45106b90f3bc57ac360b6f128e3beed4ec2fdc16.zip | |
Diffstat (limited to 'crates')
7 files changed, 56 insertions, 4 deletions
diff --git a/crates/adequate-rust-mcp/Cargo.toml b/crates/adequate-rust-mcp/Cargo.toml index 9702887..5b12c3d 100644 --- a/crates/adequate-rust-mcp/Cargo.toml +++ b/crates/adequate-rust-mcp/Cargo.toml @@ -26,6 +26,7 @@ tracing-subscriber.workspace = true url.workspace = true [dev-dependencies] +libmcp-testkit.workspace = true serial_test.workspace = true tempfile.workspace = true diff --git a/crates/adequate-rust-mcp/src/worker/schema.rs b/crates/adequate-rust-mcp/src/worker/schema.rs index 7ea8067..345060c 100644 --- a/crates/adequate-rust-mcp/src/worker/schema.rs +++ b/crates/adequate-rust-mcp/src/worker/schema.rs @@ -390,7 +390,8 @@ pub(super) struct FixStepOutput { pub(super) standard_error_excerpt: Option<String>, } -#[derive(Debug, Clone, Serialize, JsonSchema)] +#[derive(Debug, Clone, Serialize, JsonSchema, libmcp::ToolProjection)] +#[libmcp(kind = "ops")] pub(super) struct HealthOutput { pub(super) state: HealthStateOutput, pub(super) generation: u64, @@ -413,7 +414,8 @@ pub(super) struct FaultOutput { pub(super) detail: String, } -#[derive(Debug, Clone, Serialize, JsonSchema)] +#[derive(Debug, Clone, Serialize, JsonSchema, libmcp::ToolProjection)] +#[libmcp(kind = "ops")] pub(super) struct TelemetryOutput { pub(super) uptime_ms: u64, pub(super) state: HealthStateOutput, diff --git a/crates/adequate-rust-mcp/src/worker/tests.rs b/crates/adequate-rust-mcp/src/worker/tests.rs index ee9e22c..fc821a7 100644 --- a/crates/adequate-rust-mcp/src/worker/tests.rs +++ b/crates/adequate-rust-mcp/src/worker/tests.rs @@ -1,11 +1,13 @@ use super::{ AbsolutePathInput, AdvancedLspMethod, AdvancedLspRequestInput, CommonRenderConfig, CommonRenderInput, DiagnosticsInput, DiagnosticsJsonOutput, DiagnosticsModeInput, - DiagnosticsPathStyleInput, DiagnosticsRenderConfig, DiagnosticsRenderInput, HoverPayload, - OneIndexedInput, PathStyleInput, SnapshotRenderInput, SymbolQueryInput, + DiagnosticsPathStyleInput, DiagnosticsRenderConfig, DiagnosticsRenderInput, FaultOutput, + HealthOutput, HealthStateOutput, HoverPayload, MethodTelemetryOutput, OneIndexedInput, + PathStyleInput, SnapshotRenderInput, SymbolQueryInput, TelemetryOutput, TelemetryTotalsOutput, parse_clippy_json_stream, read_workspace_tool_command, read_workspace_tool_metadata, render_definition_porcelain, render_hover_porcelain, resolve_workspace_fix_command_specs, }; +use libmcp_testkit::assert_projection_doctrine; use ra_mcp_domain::types::{ OneIndexedColumn, OneIndexedLine, SourceFilePath, SourcePoint, SourceRange, }; @@ -232,6 +234,49 @@ fn diagnostics_input_defaults_to_compact_porcelain_absolute_without_limits() { } #[test] +fn ops_outputs_obey_projection_doctrine() { + let health = HealthOutput { + state: HealthStateOutput::Ready, + generation: 7, + last_fault: Some(FaultOutput { + class: "transport".to_owned(), + code: "worker_crash".to_owned(), + detail: "worker died during replay".to_owned(), + }), + }; + assert!(assert_projection_doctrine(&health).is_ok()); + + let telemetry = TelemetryOutput { + uptime_ms: 12_345, + state: HealthStateOutput::Recovering, + generation: 9, + consecutive_failures: 2, + restart_count: 4, + totals: TelemetryTotalsOutput { + request_count: 17, + success_count: 13, + response_error_count: 1, + transport_fault_count: 2, + retry_count: 3, + }, + methods: vec![MethodTelemetryOutput { + method: "tools/call:diagnostics".to_owned(), + request_count: 8, + success_count: 6, + response_error_count: 1, + transport_fault_count: 1, + retry_count: 2, + last_latency_ms: Some(42), + max_latency_ms: 88, + avg_latency_ms: 51, + last_error: Some("index warming".to_owned()), + }], + last_fault: None, + }; + assert!(assert_projection_doctrine(&telemetry).is_ok()); +} + +#[test] fn diagnostics_input_rejects_legacy_format_field() { let parsed = serde_json::from_value::<DiagnosticsInput>(json!({ "file_path": "/tmp/diagnostics_defaults.rs", diff --git a/crates/adequate-rust-mcp/tests/diagnostics_warmup_retry.rs b/crates/adequate-rust-mcp/tests/diagnostics_warmup_retry.rs index b27c34f..df1cc70 100644 --- a/crates/adequate-rust-mcp/tests/diagnostics_warmup_retry.rs +++ b/crates/adequate-rust-mcp/tests/diagnostics_warmup_retry.rs @@ -401,3 +401,4 @@ fn resolve_fake_ra_binary() -> Result<PathBuf, Box<dyn Error>> { Ok(target_debug.join("fake-rust-analyzer")) } use libmcp as _; +use libmcp_testkit as _; diff --git a/crates/adequate-rust-mcp/tests/e2e_gauntlet.rs b/crates/adequate-rust-mcp/tests/e2e_gauntlet.rs index a5a2861..1079064 100644 --- a/crates/adequate-rust-mcp/tests/e2e_gauntlet.rs +++ b/crates/adequate-rust-mcp/tests/e2e_gauntlet.rs @@ -924,3 +924,4 @@ async fn rust_analyzer_available(binary: &str) -> bool { matches!(status, Ok(status) if status.success()) } use libmcp as _; +use libmcp_testkit as _; diff --git a/crates/adequate-rust-mcp/tests/host_inflight_replay.rs b/crates/adequate-rust-mcp/tests/host_inflight_replay.rs index 17088d6..8b3d439 100644 --- a/crates/adequate-rust-mcp/tests/host_inflight_replay.rs +++ b/crates/adequate-rust-mcp/tests/host_inflight_replay.rs @@ -655,3 +655,4 @@ fn read_jsonl_events(path: &Path) -> Result<Vec<Value>, Box<dyn Error>> { Ok(events) } use libmcp as _; +use libmcp_testkit as _; diff --git a/crates/adequate-rust-mcp/tests/worktree_workspace_rebind.rs b/crates/adequate-rust-mcp/tests/worktree_workspace_rebind.rs index ca61753..4b0329e 100644 --- a/crates/adequate-rust-mcp/tests/worktree_workspace_rebind.rs +++ b/crates/adequate-rust-mcp/tests/worktree_workspace_rebind.rs @@ -381,3 +381,4 @@ fn resolve_fake_ra_binary() -> Result<PathBuf, Box<dyn Error>> { Ok(target_debug.join("fake-rust-analyzer")) } use libmcp as _; +use libmcp_testkit as _; |