use super::*;
pub(super) async fn list_workspaces(
State(state): State<ServerState>,
) -> Result<Json<WorkspaceListResponse>, ApiFailure> {
Ok(Json(WorkspaceListResponse {
workspaces: backend(&state)?.list_workspaces().await?,
}))
}
pub(super) async fn create_workspace(
State(state): State<ServerState>,
Json(request): Json<CreateWorkspaceRequest>,
) -> Result<Json<CreateWorkspaceResponse>, ApiFailure> {
let (name, name_key) = mj_core::workspace::normalize_workspace_name(&request.name)
.map_err(|error| ApiFailure::bad_request(format!("{error:#}")))?;
let backend = backend(&state)?;
if name_key == mj_core::workspace::DEFAULT_WORKSPACE_ID
&& !backend
.list_workspaces()
.await?
.iter()
.any(|workspace| workspace.name.to_lowercase() == name_key)
{
return Err(ApiFailure::bad_request(RESERVED_WORKSPACE_NAME));
}
Ok(Json(CreateWorkspaceResponse {
workspace: backend.create_workspace(name).await?,
}))
}
const RESERVED_WORKSPACE_NAME: &str = "the workspace name \"default\" is reserved: it holds sessions made before Mjolnir had workspaces; choose another name";
pub(super) async fn workspace_for_new_session(
backend: &Arc<dyn SubagentBackend>,
requested: Option<String>,
) -> Result<String, ApiFailure> {
if let Some(requested) = requested {
return Ok(requested);
}
if backend.list_workspaces().await?.is_empty() {
return Err(ApiFailure::conflict(
"this instance has no workspace yet; create one with POST /api/v1/workspaces \
or `mj workspaces create NAME`, then name it in workspace_id",
));
}
Ok(String::new())
}