huskies: merge 858
This commit is contained in:
@@ -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>,
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ struct BotCommandResponse {
|
||||
response: String,
|
||||
}
|
||||
|
||||
/// OpenAPI endpoint group for bot slash-command execution.
|
||||
pub struct BotCommandApi {
|
||||
pub ctx: Arc<AppContext>,
|
||||
}
|
||||
|
||||
@@ -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>,
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ enum ChatTags {
|
||||
Chat,
|
||||
}
|
||||
|
||||
/// OpenAPI endpoint group for the LLM-powered chat interface.
|
||||
pub struct ChatApi {
|
||||
pub ctx: Arc<AppContext>,
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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>>,
|
||||
|
||||
@@ -16,6 +16,7 @@ struct ModelPayload {
|
||||
model: String,
|
||||
}
|
||||
|
||||
/// OpenAPI endpoint group for LLM model selection and listing.
|
||||
pub struct ModelApi {
|
||||
pub ctx: Arc<AppContext>,
|
||||
}
|
||||
|
||||
@@ -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>,
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ struct OpenFileResponse {
|
||||
success: bool,
|
||||
}
|
||||
|
||||
/// OpenAPI endpoint group for user preferences and editor configuration.
|
||||
pub struct SettingsApi {
|
||||
pub ctx: Arc<AppContext>,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user