huskies: merge 858

This commit is contained in:
dave
2026-04-29 10:41:32 +00:00
parent be5db846cc
commit 11d111360d
79 changed files with 265 additions and 0 deletions
+1
View File
@@ -200,6 +200,7 @@ fn map_svc_error(err: svc::Error) -> poem::Error {
}
}
/// OpenAPI endpoint group for agent management (start, stop, list, inspect).
pub struct AgentsApi {
pub ctx: Arc<AppContext>,
}
+2
View File
@@ -15,11 +15,13 @@ enum AnthropicTags {
Anthropic,
}
/// OpenAPI endpoint group for Anthropic API key and model operations.
pub struct AnthropicApi {
ctx: Arc<AppContext>,
}
impl AnthropicApi {
/// Create a new `AnthropicApi` bound to the given application context.
pub fn new(ctx: Arc<AppContext>) -> Self {
Self { ctx }
}
+1
View File
@@ -36,6 +36,7 @@ struct BotCommandResponse {
response: String,
}
/// OpenAPI endpoint group for bot slash-command execution.
pub struct BotCommandApi {
pub ctx: Arc<AppContext>,
}
+1
View File
@@ -22,6 +22,7 @@ struct BotConfigPayload {
pub slack_channel_ids: Option<Vec<String>>,
}
/// OpenAPI endpoint group for reading and writing bot configuration.
pub struct BotConfigApi {
pub ctx: Arc<AppContext>,
}
+1
View File
@@ -9,6 +9,7 @@ enum ChatTags {
Chat,
}
/// OpenAPI endpoint group for the LLM-powered chat interface.
pub struct ChatApi {
pub ctx: Arc<AppContext>,
}
+5
View File
@@ -34,6 +34,7 @@ pub struct PermissionForward {
}
#[derive(Clone)]
/// Shared application state threaded through all HTTP handlers via Poem's `Data` extractor.
pub struct AppContext {
pub state: Arc<SessionState>,
pub store: Arc<JsonFileStore>,
@@ -78,6 +79,7 @@ pub struct AppContext {
#[cfg(test)]
impl AppContext {
/// Build a minimal `AppContext` for unit tests with an in-memory store.
pub fn new_test(project_root: std::path::PathBuf) -> Self {
use crate::agents::AgentPool;
let state = SessionState::default();
@@ -119,12 +121,15 @@ impl AppContext {
}
}
/// Alias for `poem::Result<T>` used by OpenAPI handler return types.
pub type OpenApiResult<T> = poem::Result<T>;
/// Return a 400 Bad Request error with the given message.
pub fn bad_request(message: String) -> poem::Error {
poem::Error::from_string(message, StatusCode::BAD_REQUEST)
}
/// Return a 404 Not Found error with the given message.
pub fn not_found(message: String) -> poem::Error {
poem::Error::from_string(message, StatusCode::NOT_FOUND)
}
+1
View File
@@ -37,6 +37,7 @@ struct ExecShellPayload {
pub args: Vec<String>,
}
/// OpenAPI endpoint group for filesystem I/O operations (read, write, list, search).
pub struct IoApi {
pub ctx: Arc<AppContext>,
}
+9
View File
@@ -9,14 +9,23 @@ use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use std::sync::Arc;
/// MCP tools for agent start, stop, wait, list, and inspect.
pub mod agent_tools;
/// MCP tools for server logs, CRDT dump, version, and story movement.
pub mod diagnostics;
/// MCP tools for git operations scoped to agent worktrees.
pub mod git_tools;
/// MCP tools for merge status and merge-to-master operations.
pub mod merge_tools;
/// MCP tools for QA request, approve, and reject workflows.
pub mod qa_tools;
/// MCP tools for running shell commands and test suites.
pub mod shell_tools;
/// MCP tools for pipeline status, story todos, and triage dump.
pub mod status_tools;
/// MCP tools for creating, updating, and managing stories and bugs.
pub mod story_tools;
/// MCP tools for the project setup wizard.
pub mod wizard_tools;
mod dispatch;
+25
View File
@@ -1,26 +1,46 @@
//! HTTP server — module declarations for all REST, MCP, WebSocket, and SSE endpoints.
/// Agent management HTTP endpoints.
pub mod agents;
/// Server-sent event stream for real-time agent output.
pub mod agents_sse;
/// Anthropic API key management endpoints.
pub mod anthropic;
/// Static asset serving (embedded frontend files).
pub mod assets;
/// Bot slash-command HTTP endpoint.
pub mod bot_command;
/// Bot configuration read/write endpoints.
pub mod bot_config;
/// Chat session HTTP endpoints.
pub mod chat;
/// Shared application context threaded through handlers.
pub mod context;
/// Server-sent event stream for pipeline/watcher events.
pub mod events;
/// Node identity endpoint (public key, node ID).
pub mod identity;
/// Filesystem I/O HTTP endpoints (read, write, list, search).
pub mod io;
/// Model Context Protocol (MCP) HTTP endpoint and tool modules.
pub mod mcp;
/// LLM model selection and listing endpoints.
pub mod model;
/// OAuth 2.0 PKCE flow endpoints for Anthropic authentication.
pub mod oauth;
/// Project settings HTTP endpoints.
pub mod settings;
#[cfg(test)]
pub(crate) mod test_helpers;
/// Workflow helpers for story/bug file operations.
pub mod workflow;
/// Gateway-mode HTTP endpoints for multi-project proxy.
pub mod gateway;
/// Project open/close/list HTTP endpoints.
pub mod project;
/// Setup wizard HTTP endpoints.
pub mod wizard;
/// WebSocket handler for real-time frontend communication.
pub mod ws;
use agents::AgentsApi;
@@ -44,26 +64,31 @@ use crate::chat::transport::whatsapp::WhatsAppWebhookContext;
const DEFAULT_PORT: u16 = 3001;
/// Parse an optional port string, falling back to the default (3001).
pub fn parse_port(value: Option<String>) -> u16 {
value
.and_then(|v| v.parse::<u16>().ok())
.unwrap_or(DEFAULT_PORT)
}
/// Read the server port from the `HUSKIES_PORT` env var, or use the default.
pub fn resolve_port() -> u16 {
parse_port(std::env::var("HUSKIES_PORT").ok())
}
/// Write a `.huskies_port` file so other processes can discover the port.
pub fn write_port_file(dir: &Path, port: u16) -> Option<PathBuf> {
let path = dir.join(".huskies_port");
std::fs::write(&path, port.to_string()).ok()?;
Some(path)
}
/// Delete the `.huskies_port` file on shutdown.
pub fn remove_port_file(path: &Path) {
let _ = std::fs::remove_file(path);
}
/// Assemble the full Poem route tree (API, WebSocket, MCP, OAuth, assets).
pub fn build_routes(
ctx: AppContext,
whatsapp_ctx: Option<Arc<WhatsAppWebhookContext>>,
+1
View File
@@ -16,6 +16,7 @@ struct ModelPayload {
model: String,
}
/// OpenAPI endpoint group for LLM model selection and listing.
pub struct ModelApi {
pub ctx: Arc<AppContext>,
}
+1
View File
@@ -27,6 +27,7 @@ fn map_project_error(e: ProjectError) -> poem::Error {
}
}
/// OpenAPI endpoint group for project open, close, and listing operations.
pub struct ProjectApi {
pub ctx: Arc<AppContext>,
}
+1
View File
@@ -55,6 +55,7 @@ struct OpenFileResponse {
success: bool,
}
/// OpenAPI endpoint group for user preferences and editor configuration.
pub struct SettingsApi {
pub ctx: Arc<AppContext>,
}
+1
View File
@@ -68,6 +68,7 @@ fn parse_step(step_str: &str) -> Result<WizardStep, poem::Error> {
.map_err(|_| not_found(format!("Unknown wizard step: {step_str}")))
}
/// OpenAPI endpoint group for the multi-step project setup wizard.
pub struct WizardApi {
pub ctx: Arc<AppContext>,
}
@@ -6,6 +6,7 @@ use super::super::{
slugify_name, story_stage, write_story_content,
};
/// Write a new story file to the CRDT content store and return the generated story ID.
pub fn create_story_file(
root: &std::path::Path,
name: &str,
@@ -8,6 +8,7 @@ use super::super::{
slugify_name, story_stage, write_story_content,
};
/// Toggle an acceptance criterion checkbox (`- [ ]` → `- [x]`) by its 0-based index among unchecked items.
pub fn check_criterion_in_file(
project_root: &Path,
story_id: &str,