swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/crates/fidget-spinner-cli/src/mcp/worker.rs
diff options
context:
space:
mode:
authormain <main@swarm.moe>2026-03-19 10:15:18 -0400
committermain <main@swarm.moe>2026-03-19 10:15:18 -0400
commit7b9bd8b42883f82b090718175b8316296ef18236 (patch)
tree16f2c70b0f630c7757d72a20bd90d17c2e3a8414 /crates/fidget-spinner-cli/src/mcp/worker.rs
downloadfidget_spinner-7b9bd8b42883f82b090718175b8316296ef18236.zip
Initial Fidget Spinner MVP
Diffstat (limited to 'crates/fidget-spinner-cli/src/mcp/worker.rs')
-rw-r--r--crates/fidget-spinner-cli/src/mcp/worker.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/crates/fidget-spinner-cli/src/mcp/worker.rs b/crates/fidget-spinner-cli/src/mcp/worker.rs
new file mode 100644
index 0000000..91c6db9
--- /dev/null
+++ b/crates/fidget-spinner-cli/src/mcp/worker.rs
@@ -0,0 +1,66 @@
+use std::io::{self, BufRead, Write};
+use std::path::PathBuf;
+
+use camino::Utf8PathBuf;
+
+use crate::mcp::fault::{FaultKind, FaultRecord, FaultStage};
+use crate::mcp::protocol::{WorkerOutcome, WorkerRequest, WorkerResponse};
+use crate::mcp::service::WorkerService;
+
+pub(crate) fn serve(project: PathBuf) -> Result<(), fidget_spinner_store_sqlite::StoreError> {
+ let project = Utf8PathBuf::from(project.to_string_lossy().into_owned());
+ let mut service = WorkerService::new(&project)?;
+ let stdin = io::stdin();
+ let mut stdout = io::stdout().lock();
+
+ for line in stdin.lock().lines() {
+ let line = match line {
+ Ok(line) => line,
+ Err(error) => {
+ eprintln!("worker stdin failure: {error}");
+ continue;
+ }
+ };
+ if line.trim().is_empty() {
+ continue;
+ }
+
+ let request = match serde_json::from_str::<WorkerRequest>(&line) {
+ Ok(request) => request,
+ Err(error) => {
+ let response = WorkerResponse {
+ id: crate::mcp::protocol::HostRequestId(0),
+ outcome: WorkerOutcome::Fault {
+ fault: FaultRecord::new(
+ FaultKind::InvalidInput,
+ FaultStage::Protocol,
+ "worker.parse",
+ format!("invalid worker request: {error}"),
+ ),
+ },
+ };
+ write_message(&mut stdout, &response)?;
+ continue;
+ }
+ };
+
+ let WorkerRequest::Execute { id, operation } = request;
+ let outcome = match service.execute(operation) {
+ Ok(result) => WorkerOutcome::Success { result },
+ Err(fault) => WorkerOutcome::Fault { fault },
+ };
+ write_message(&mut stdout, &WorkerResponse { id, outcome })?;
+ }
+
+ Ok(())
+}
+
+fn write_message(
+ stdout: &mut impl Write,
+ response: &WorkerResponse,
+) -> Result<(), fidget_spinner_store_sqlite::StoreError> {
+ serde_json::to_writer(&mut *stdout, response)?;
+ stdout.write_all(b"\n")?;
+ stdout.flush()?;
+ Ok(())
+}