From c618174e60e4632d36d7352d83399508c72b2f42 Mon Sep 17 00:00:00 2001 From: soryu Date: Tue, 27 Jan 2026 11:04:20 +0000 Subject: Add Red Team CLI command and frontend UI (#39) * Add Red Team CLI command and frontend UI Backend additions: - Add `makima red-team notify` CLI command for red team tasks - Add RedTeamCommand enum with Notify subcommand - Add red_team API client module for notify endpoint - Add RedTeamNotifyArgs with severity, task, file, context options Frontend additions: - Add ContractCreateModal with red team toggle and prompt input - Update ContractDetail with red-team tab for notifications - Update ContractList with red team enabled badge - Add TypeScript types for RedTeamNotification and related interfaces Co-Authored-By: Claude Opus 4.5 * Add CSS styles for Red Team frontend components Add comprehensive styling for: - Contract list and detail containers - Red team badge styling with gradient backgrounds - Tab navigation with red team specific styling - Red team notifications panel with severity indicators - Contract creation modal form elements - Task badges for supervisor and red team roles Co-Authored-By: Claude Opus 4.5 * Fix missing local_only field in TUI CreateContractRequest Add the missing local_only field to the CreateContractRequest struct initialization in the TUI contract creation handler. Co-Authored-By: Claude Opus 4.5 * [WIP] Heartbeat checkpoint - 2026-01-27 03:07:28 UTC --------- Co-authored-by: Claude Opus 4.5 --- frontend/src/components/ContractList.tsx | 61 ++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 18 deletions(-) (limited to 'frontend/src/components/ContractList.tsx') diff --git a/frontend/src/components/ContractList.tsx b/frontend/src/components/ContractList.tsx index 77012db..253b44f 100644 --- a/frontend/src/components/ContractList.tsx +++ b/frontend/src/components/ContractList.tsx @@ -1,5 +1,6 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState, useCallback } from 'react' import { Link } from 'react-router-dom' +import { ContractCreateModal } from './ContractCreateModal' interface ContractSummary { id: string @@ -12,32 +13,35 @@ interface ContractSummary { task_count: number repository_count: number created_at: string + // Red team fields + red_team_enabled?: boolean } export function ContractList() { const [contracts, setContracts] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) + const [showCreateModal, setShowCreateModal] = useState(false) - useEffect(() => { - async function fetchContracts() { - try { - setLoading(true) - const response = await fetch('/api/v1/contracts') - if (!response.ok) { - throw new Error(`Failed to fetch contracts: ${response.statusText}`) - } - const data = await response.json() - setContracts(data.contracts || []) - } catch (err) { - setError(err instanceof Error ? err.message : 'Unknown error') - } finally { - setLoading(false) + const fetchContracts = useCallback(async () => { + try { + setLoading(true) + const response = await fetch('/api/v1/contracts') + if (!response.ok) { + throw new Error(`Failed to fetch contracts: ${response.statusText}`) } + const data = await response.json() + setContracts(data.contracts || []) + } catch (err) { + setError(err instanceof Error ? err.message : 'Unknown error') + } finally { + setLoading(false) } + }, []) + useEffect(() => { fetchContracts() - }, []) + }, [fetchContracts]) if (loading) { return ( @@ -57,7 +61,15 @@ export function ContractList() { return (
-

Contracts

+
+

Contracts

+ +
{contracts.length === 0 ? (

No contracts found

) : ( @@ -65,7 +77,14 @@ export function ContractList() { {contracts.map((contract) => (
  • -

    {contract.name}

    +

    + {contract.name} + {contract.red_team_enabled && ( + + 🔍 + + )} +

    {contract.description &&

    {contract.description}

    }
    Phase: {contract.phase} @@ -78,6 +97,12 @@ export function ContractList() { ))} )} + + setShowCreateModal(false)} + onCreated={fetchContracts} + />
    ) } -- cgit v1.2.3