summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-29 02:24:48 +0000
committerGitHub <noreply@github.com>2026-01-29 02:24:48 +0000
commitcfe3ea0aae878ae8f591acdc33a48332ac875b9e (patch)
tree49a7f2d17f494f6c5f88d7c0692d57c21dea3244
parent764ace78046e78cce36b64cb3682cc5489bcf9d7 (diff)
downloadsoryu-cfe3ea0aae878ae8f591acdc33a48332ac875b9e.tar.gz
soryu-cfe3ea0aae878ae8f591acdc33a48332ac875b9e.zip
fix: Remove mistaken red team UI from VN frontend (#47)
* feat: Add Red Team UI to makima/frontend contract creation - Add redTeamEnabled and redTeamPrompt state to contracts page - Add "Enable Red Team Monitoring" checkbox with description - Add conditional "Custom Review Criteria" textarea when enabled - Include redTeamEnabled/redTeamPrompt in CreateContractRequest - Reset red team fields when canceling contract creation - Add redTeamEnabled to ContractSummary and Contract types - Add redTeamEnabled/redTeamPrompt to CreateContractRequest type - Add Red Team badge (🔍) to ContractList for enabled contracts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Remove mistaken red team UI from VN frontend PR #39 accidentally added red team UI code to the wrong frontend directory (frontend/ instead of makima/frontend/). The correct implementation is already in makima/frontend/. This commit removes the mistaken changes: - Delete ContractCreateModal.tsx (was added by mistake) - Revert ContractList.tsx to remove red team badge and create modal - Revert ContractDetail.tsx to remove red team tab and notifications - Revert types.ts to remove contract/task types - Revert pc98.css to remove red team styling Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * [WIP] Heartbeat checkpoint - 2026-01-29 02:18:40 UTC --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
-rw-r--r--frontend/src/components/ContractCreateModal.tsx185
-rw-r--r--frontend/src/components/ContractDetail.tsx139
-rw-r--r--frontend/src/components/ContractList.tsx61
-rw-r--r--frontend/src/styles/pc98.css644
-rw-r--r--frontend/src/types.ts95
-rw-r--r--frontend/tsconfig.tsbuildinfo2
6 files changed, 23 insertions, 1103 deletions
diff --git a/frontend/src/components/ContractCreateModal.tsx b/frontend/src/components/ContractCreateModal.tsx
deleted file mode 100644
index e1d9732..0000000
--- a/frontend/src/components/ContractCreateModal.tsx
+++ /dev/null
@@ -1,185 +0,0 @@
-import React, { useState } from 'react'
-
-interface ContractCreateModalProps {
- isOpen: boolean
- onClose: () => void
- onCreated: () => void
-}
-
-interface CreateContractForm {
- name: string
- description: string
- contractType: string
- redTeamEnabled: boolean
- redTeamPrompt: string
-}
-
-export function ContractCreateModal({ isOpen, onClose, onCreated }: ContractCreateModalProps) {
- const [form, setForm] = useState<CreateContractForm>({
- name: '',
- description: '',
- contractType: 'simple',
- redTeamEnabled: false,
- redTeamPrompt: '',
- })
- const [loading, setLoading] = useState(false)
- const [error, setError] = useState<string | null>(null)
-
- if (!isOpen) return null
-
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault()
- setLoading(true)
- setError(null)
-
- try {
- const response = await fetch('/api/v1/contracts', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- name: form.name,
- description: form.description || undefined,
- contract_type: form.contractType,
- red_team_enabled: form.redTeamEnabled,
- red_team_prompt: form.redTeamEnabled && form.redTeamPrompt ? form.redTeamPrompt : undefined,
- }),
- })
-
- if (!response.ok) {
- const errorData = await response.json().catch(() => ({}))
- throw new Error(errorData.message || `Failed to create contract: ${response.statusText}`)
- }
-
- // Reset form and close modal
- setForm({
- name: '',
- description: '',
- contractType: 'simple',
- redTeamEnabled: false,
- redTeamPrompt: '',
- })
- onCreated()
- onClose()
- } catch (err) {
- setError(err instanceof Error ? err.message : 'Unknown error')
- } finally {
- setLoading(false)
- }
- }
-
- return (
- <div className="modal-overlay" onClick={onClose}>
- <div className="settings-modal contract-create-modal" onClick={(e) => e.stopPropagation()}>
- <div className="modal-header">
- <h2 className="modal-title">Create Contract</h2>
- <button className="modal-close-btn" onClick={onClose}>
- ×
- </button>
- </div>
-
- <form onSubmit={handleSubmit}>
- <div className="modal-content">
- {error && (
- <div className="form-error">
- {error}
- </div>
- )}
-
- <div className="settings-section">
- <h3>Contract Details</h3>
-
- <div className="setting-item">
- <label>
- Name
- <input
- type="text"
- value={form.name}
- onChange={(e) => setForm({ ...form, name: e.target.value })}
- placeholder="Enter contract name"
- required
- className="form-input"
- />
- </label>
- </div>
-
- <div className="setting-item">
- <label>
- Description
- <textarea
- value={form.description}
- onChange={(e) => setForm({ ...form, description: e.target.value })}
- placeholder="Enter contract description (optional)"
- className="form-textarea"
- rows={3}
- />
- </label>
- </div>
-
- <div className="setting-item">
- <label>
- Contract Type
- <select
- value={form.contractType}
- onChange={(e) => setForm({ ...form, contractType: e.target.value })}
- className="form-select"
- >
- <option value="simple">Simple</option>
- <option value="specification">Specification</option>
- <option value="execute">Execute</option>
- </select>
- </label>
- </div>
- </div>
-
- <div className="settings-section">
- <h3>Red Team Monitoring</h3>
-
- <div className="setting-item">
- <label className="checkbox-label">
- <input
- type="checkbox"
- checked={form.redTeamEnabled}
- onChange={(e) => setForm({ ...form, redTeamEnabled: e.target.checked })}
- />
- <span>Enable Red Team monitoring</span>
- </label>
- <div className="setting-description">
- Spawns a parallel task that monitors work output for quality and compliance
- </div>
- </div>
-
- {form.redTeamEnabled && (
- <div className="setting-item red-team-prompt-container">
- <label>
- Custom review criteria (optional)
- <textarea
- value={form.redTeamPrompt}
- onChange={(e) => setForm({ ...form, redTeamPrompt: e.target.value })}
- placeholder="Enter custom criteria for the red team to evaluate against... (e.g., 'Ensure all functions have proper error handling', 'Verify security best practices are followed')"
- className="form-textarea"
- rows={4}
- />
- </label>
- <div className="setting-description">
- Provide specific criteria for the red team to focus on during reviews
- </div>
- </div>
- )}
- </div>
- </div>
-
- <div className="modal-footer">
- <button type="button" className="modal-btn secondary" onClick={onClose} disabled={loading}>
- Cancel
- </button>
- <button type="submit" className="modal-btn primary" disabled={loading || !form.name.trim()}>
- {loading ? 'Creating...' : 'Create Contract'}
- </button>
- </div>
- </form>
- </div>
- </div>
- )
-}
diff --git a/frontend/src/components/ContractDetail.tsx b/frontend/src/components/ContractDetail.tsx
index a9dd550..72527ce 100644
--- a/frontend/src/components/ContractDetail.tsx
+++ b/frontend/src/components/ContractDetail.tsx
@@ -12,8 +12,6 @@ interface TaskSummary {
id: string
name: string
status: string
- is_supervisor?: boolean
- is_red_team?: boolean
}
interface ContractRepository {
@@ -32,24 +30,6 @@ interface Contract {
status: string
version: number
created_at: string
- red_team_enabled?: boolean
- red_team_prompt?: string
-}
-
-interface RedTeamNotification {
- id: string
- contract_id: string
- red_team_task_id: string
- related_task_id?: string
- message: string
- severity: 'info' | 'warning' | 'critical'
- file_path?: string
- context?: string
- delivered: boolean
- delivered_at?: string
- acknowledged: boolean
- acknowledged_at?: string
- created_at: string
}
interface ContractWithRelations {
@@ -59,7 +39,7 @@ interface ContractWithRelations {
tasks: TaskSummary[]
}
-type Tab = 'overview' | 'files' | 'tasks' | 'repositories' | 'red-team'
+type Tab = 'overview' | 'files' | 'tasks' | 'repositories'
export function ContractDetail() {
const { id } = useParams<{ id: string }>()
@@ -67,8 +47,6 @@ export function ContractDetail() {
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [activeTab, setActiveTab] = useState<Tab>('overview')
- const [notifications, setNotifications] = useState<RedTeamNotification[]>([])
- const [notificationsLoading, setNotificationsLoading] = useState(false)
useEffect(() => {
async function fetchContract() {
@@ -92,28 +70,6 @@ export function ContractDetail() {
fetchContract()
}, [id])
- // Fetch red team notifications when viewing red-team tab
- useEffect(() => {
- async function fetchNotifications() {
- if (!id || activeTab !== 'red-team' || !data?.contract.red_team_enabled) return
-
- try {
- setNotificationsLoading(true)
- const response = await fetch(`/api/v1/contracts/${id}/red-team/notifications`)
- if (response.ok) {
- const notificationData = await response.json()
- setNotifications(notificationData.notifications || [])
- }
- } catch (err) {
- console.error('Failed to fetch red team notifications:', err)
- } finally {
- setNotificationsLoading(false)
- }
- }
-
- fetchNotifications()
- }, [id, activeTab, data?.contract.red_team_enabled])
-
if (loading) {
return (
<div className="contract-detail-container">
@@ -152,14 +108,7 @@ export function ContractDetail() {
<Link to="/contracts" className="back-link">
Back to Contracts
</Link>
- <h1 className="contract-title">
- {contract.name}
- {contract.red_team_enabled && (
- <span className="red-team-badge" title="Red Team monitoring enabled">
- đŸ›Ąī¸ Red Team
- </span>
- )}
- </h1>
+ <h1 className="contract-title">{contract.name}</h1>
{contract.description && (
<p className="contract-description">{contract.description}</p>
)}
@@ -195,14 +144,6 @@ export function ContractDetail() {
>
Repositories ({repositories.length})
</button>
- {contract.red_team_enabled && (
- <button
- className={`tab-button red-team-tab ${activeTab === 'red-team' ? 'active' : ''}`}
- onClick={() => setActiveTab('red-team')}
- >
- đŸ›Ąī¸ Red Team
- </button>
- )}
</div>
<div className="contract-tab-content">
@@ -253,12 +194,8 @@ export function ContractDetail() {
) : (
<ul className="task-list">
{tasks.map((task) => (
- <li key={task.id} className={`task-item ${task.is_red_team ? 'red-team-task' : ''}`}>
- <h3>
- {task.is_red_team && <span className="task-badge red-team">đŸ›Ąī¸</span>}
- {task.is_supervisor && <span className="task-badge supervisor">👔</span>}
- {task.name}
- </h3>
+ <li key={task.id} className="task-item">
+ <h3>{task.name}</h3>
<span className={`task-status status-${task.status}`}>
{task.status}
</span>
@@ -289,74 +226,6 @@ export function ContractDetail() {
)}
</div>
)}
-
- {activeTab === 'red-team' && contract.red_team_enabled && (
- <div className="tab-panel red-team-panel">
- <h2>đŸ›Ąī¸ Red Team Monitoring</h2>
-
- {contract.red_team_prompt && (
- <div className="red-team-prompt">
- <h3>Review Criteria</h3>
- <p>{contract.red_team_prompt}</p>
- </div>
- )}
-
- <div className="red-team-status">
- <h3>Red Team Task</h3>
- {(() => {
- const redTeamTask = tasks.find(t => t.is_red_team)
- if (redTeamTask) {
- return (
- <div className="red-team-task-info">
- <span className="task-name">{redTeamTask.name}</span>
- <span className={`task-status status-${redTeamTask.status}`}>
- {redTeamTask.status}
- </span>
- </div>
- )
- }
- return <p className="no-task">Red team task not yet spawned</p>
- })()}
- </div>
-
- <div className="red-team-notifications">
- <h3>Alerts ({notifications.length})</h3>
- {notificationsLoading ? (
- <p>Loading notifications...</p>
- ) : notifications.length === 0 ? (
- <p className="no-alerts">No alerts from red team</p>
- ) : (
- <ul className="notification-list">
- {notifications.map((notification) => (
- <li
- key={notification.id}
- className={`notification-item severity-${notification.severity}`}
- >
- <div className="notification-header">
- <span className={`severity-badge ${notification.severity}`}>
- {notification.severity === 'critical' && '🚨'}
- {notification.severity === 'warning' && 'âš ī¸'}
- {notification.severity === 'info' && 'â„šī¸'}
- {notification.severity.toUpperCase()}
- </span>
- <span className="notification-time">
- {new Date(notification.created_at).toLocaleString()}
- </span>
- </div>
- <p className="notification-message">{notification.message}</p>
- {notification.file_path && (
- <span className="notification-file">File: {notification.file_path}</span>
- )}
- {notification.context && (
- <pre className="notification-context">{notification.context}</pre>
- )}
- </li>
- ))}
- </ul>
- )}
- </div>
- </div>
- )}
</div>
</div>
)
diff --git a/frontend/src/components/ContractList.tsx b/frontend/src/components/ContractList.tsx
index 253b44f..77012db 100644
--- a/frontend/src/components/ContractList.tsx
+++ b/frontend/src/components/ContractList.tsx
@@ -1,6 +1,5 @@
-import React, { useEffect, useState, useCallback } from 'react'
+import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
-import { ContractCreateModal } from './ContractCreateModal'
interface ContractSummary {
id: string
@@ -13,35 +12,32 @@ 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<ContractSummary[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
- const [showCreateModal, setShowCreateModal] = useState(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}`)
+ 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 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 (
@@ -61,15 +57,7 @@ export function ContractList() {
return (
<div className="contract-list-container">
- <div className="contract-list-header">
- <h1>Contracts</h1>
- <button
- className="create-contract-btn"
- onClick={() => setShowCreateModal(true)}
- >
- + New Contract
- </button>
- </div>
+ <h1>Contracts</h1>
{contracts.length === 0 ? (
<p>No contracts found</p>
) : (
@@ -77,14 +65,7 @@ export function ContractList() {
{contracts.map((contract) => (
<li key={contract.id} className="contract-item">
<Link to={`/contracts/${contract.id}`}>
- <h2>
- {contract.name}
- {contract.red_team_enabled && (
- <span className="red-team-badge" title="Red Team monitoring enabled">
- 🔍
- </span>
- )}
- </h2>
+ <h2>{contract.name}</h2>
{contract.description && <p>{contract.description}</p>}
<div className="contract-meta">
<span>Phase: {contract.phase}</span>
@@ -97,12 +78,6 @@ export function ContractList() {
))}
</ul>
)}
-
- <ContractCreateModal
- isOpen={showCreateModal}
- onClose={() => setShowCreateModal(false)}
- onCreated={fetchContracts}
- />
</div>
)
}
diff --git a/frontend/src/styles/pc98.css b/frontend/src/styles/pc98.css
index a420115..4dcf15e 100644
--- a/frontend/src/styles/pc98.css
+++ b/frontend/src/styles/pc98.css
@@ -4621,647 +4621,3 @@ button:focus-visible {
display: none;
}
}
-
-/* =============================================================================
- Contract List & Detail Styles
- ============================================================================= */
-
-.contract-list-container,
-.contract-detail-container {
- padding: 20px;
- max-width: 1200px;
- margin: 0 auto;
- font-family: 'MS Gothic', monospace;
- color: #ffffff;
-}
-
-.contract-list-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.contract-list-header h1 {
- font-size: 24px;
- color: #66ccff;
- margin: 0;
- text-transform: uppercase;
- letter-spacing: 1px;
-}
-
-.create-contract-btn {
- appearance: none;
- background: linear-gradient(180deg, #004466, #002233);
- border: 2px solid #66ccff;
- color: #ffffff;
- font-family: 'MS Gothic', monospace;
- font-size: 13px;
- font-weight: bold;
- padding: 8px 16px;
- cursor: pointer;
- border-radius: 4px;
- transition: all 0.2s ease;
-}
-
-.create-contract-btn:hover {
- background: linear-gradient(180deg, #005577, #003344);
- box-shadow: 0 0 10px rgba(102, 204, 255, 0.4);
-}
-
-.contract-list {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-.contract-item {
- margin-bottom: 15px;
- border: 1px solid rgba(102, 204, 255, 0.3);
- background: rgba(0, 0, 0, 0.5);
- transition: all 0.3s ease;
-}
-
-.contract-item:hover {
- border-color: #66ccff;
- background: rgba(102, 204, 255, 0.05);
-}
-
-.contract-item a {
- display: block;
- padding: 15px;
- text-decoration: none;
- color: inherit;
-}
-
-.contract-item h2 {
- font-size: 16px;
- color: #ffffff;
- margin: 0 0 8px 0;
- display: flex;
- align-items: center;
- gap: 10px;
-}
-
-.contract-item p {
- font-size: 13px;
- color: rgba(255, 255, 255, 0.7);
- margin: 0 0 10px 0;
-}
-
-.contract-meta {
- display: flex;
- flex-wrap: wrap;
- gap: 15px;
- font-size: 12px;
- color: rgba(102, 204, 255, 0.8);
-}
-
-/* =============================================================================
- Red Team Styling
- ============================================================================= */
-
-/* Red Team Badge - Contract List and Detail */
-.red-team-badge {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- margin-left: 8px;
- padding: 2px 8px;
- font-size: 12px;
- font-weight: normal;
- background: linear-gradient(180deg, #4a0000, #2d0000);
- border: 1px solid #ff4444;
- border-radius: 4px;
- color: #ff6666;
- vertical-align: middle;
- box-shadow: 0 0 6px rgba(255, 68, 68, 0.3);
-}
-
-/* Contract Detail Header */
-.contract-detail-header {
- margin-bottom: 20px;
-}
-
-.back-link {
- display: inline-block;
- font-size: 12px;
- color: #66ccff;
- text-decoration: none;
- margin-bottom: 15px;
- transition: opacity 0.3s ease;
-}
-
-.back-link:hover {
- opacity: 0.8;
-}
-
-.contract-title {
- display: flex;
- align-items: center;
- gap: 15px;
- flex-wrap: wrap;
- font-size: 24px;
- color: #66ccff;
- margin: 0 0 10px 0;
-}
-
-.contract-description {
- font-size: 14px;
- color: rgba(255, 255, 255, 0.7);
- margin: 10px 0;
-}
-
-/* Contract Tabs */
-.contract-tabs {
- display: flex;
- flex-wrap: wrap;
- gap: 5px;
- margin-bottom: 20px;
- border-bottom: 1px solid rgba(102, 204, 255, 0.3);
- padding-bottom: 10px;
-}
-
-.tab-button {
- font-family: 'MS Gothic', monospace;
- font-size: 12px;
- padding: 8px 16px;
- border: 1px solid rgba(102, 204, 255, 0.3);
- background: rgba(0, 0, 0, 0.3);
- color: rgba(255, 255, 255, 0.7);
- cursor: pointer;
- transition: all 0.3s ease;
-}
-
-.tab-button:hover {
- border-color: #66ccff;
- color: #ffffff;
-}
-
-.tab-button.active {
- background: rgba(102, 204, 255, 0.15);
- border-color: #66ccff;
- color: #66ccff;
-}
-
-/* Red Team Tab Button */
-.tab-button.red-team-tab {
- background: linear-gradient(180deg, #3d0000, #1a0000);
- border-color: #ff4444;
- color: #ff6666;
-}
-
-.tab-button.red-team-tab:hover {
- background: linear-gradient(180deg, #4a0000, #2d0000);
- box-shadow: 0 0 8px rgba(255, 68, 68, 0.4);
-}
-
-.tab-button.red-team-tab.active {
- background: linear-gradient(180deg, #5c0000, #3d0000);
- border-color: #ff6666;
- color: #ffffff;
- box-shadow: 0 0 12px rgba(255, 68, 68, 0.5);
-}
-
-/* Tab Content */
-.tab-panel {
- padding: 20px;
- background: rgba(0, 0, 0, 0.3);
- border: 1px solid rgba(102, 204, 255, 0.2);
-}
-
-.tab-panel h2 {
- font-size: 18px;
- color: #66ccff;
- margin: 0 0 15px 0;
- text-transform: uppercase;
- letter-spacing: 1px;
-}
-
-.overview-list {
- display: grid;
- grid-template-columns: 120px 1fr;
- gap: 10px;
-}
-
-.overview-list dt {
- color: rgba(255, 255, 255, 0.6);
- font-size: 13px;
-}
-
-.overview-list dd {
- color: #ffffff;
- margin: 0;
- font-size: 13px;
-}
-
-/* File/Task/Repository Lists */
-.file-list,
-.task-list,
-.repository-list {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-.file-item,
-.task-item,
-.repository-item {
- padding: 12px;
- margin-bottom: 10px;
- border: 1px solid rgba(102, 204, 255, 0.2);
- background: rgba(0, 0, 0, 0.3);
- transition: all 0.3s ease;
-}
-
-.file-item:hover,
-.task-item:hover,
-.repository-item:hover {
- border-color: rgba(102, 204, 255, 0.4);
-}
-
-.file-item a {
- text-decoration: none;
- color: inherit;
-}
-
-.file-item h3,
-.task-item h3,
-.repository-item h3 {
- font-size: 14px;
- color: #ffffff;
- margin: 0 0 5px 0;
- display: flex;
- align-items: center;
- gap: 8px;
-}
-
-.file-phase {
- font-size: 11px;
- color: rgba(102, 204, 255, 0.7);
-}
-
-.task-status {
- font-size: 11px;
- padding: 2px 8px;
- border-radius: 2px;
-}
-
-.task-status.status-pending {
- background: rgba(255, 255, 0, 0.15);
- color: #ffff00;
- border: 1px solid rgba(255, 255, 0, 0.3);
-}
-
-.task-status.status-active,
-.task-status.status-running {
- background: rgba(0, 255, 0, 0.15);
- color: #00ff00;
- border: 1px solid rgba(0, 255, 0, 0.3);
-}
-
-.task-status.status-completed {
- background: rgba(102, 204, 255, 0.15);
- color: #66ccff;
- border: 1px solid rgba(102, 204, 255, 0.3);
-}
-
-.task-status.status-failed {
- background: rgba(255, 100, 100, 0.15);
- color: #ff6464;
- border: 1px solid rgba(255, 100, 100, 0.3);
-}
-
-/* Task Badges */
-.task-badge {
- margin-right: 6px;
- font-size: 14px;
-}
-
-.task-badge.red-team {
- color: #ff6666;
-}
-
-.task-badge.supervisor {
- color: #66ccff;
-}
-
-.task-item.red-team-task {
- border-left: 3px solid #ff4444;
-}
-
-.primary-badge {
- font-size: 10px;
- padding: 2px 6px;
- background: rgba(102, 204, 255, 0.15);
- color: #66ccff;
- border: 1px solid rgba(102, 204, 255, 0.3);
- margin-left: 8px;
-}
-
-.repo-type {
- font-size: 11px;
- color: rgba(255, 255, 255, 0.6);
-}
-
-/* Red Team Panel */
-.red-team-panel {
- background: linear-gradient(180deg, rgba(60, 0, 0, 0.3), rgba(30, 0, 0, 0.3));
- border-left: 3px solid #ff4444;
-}
-
-.red-team-panel h2 {
- color: #ff6666;
- border-bottom: 2px solid #ff4444;
- padding-bottom: 8px;
-}
-
-.red-team-panel h3 {
- color: #ffaaaa;
- margin-top: 20px;
- margin-bottom: 12px;
-}
-
-/* Red Team Prompt Section */
-.red-team-prompt {
- background: rgba(0, 0, 0, 0.4);
- border: 1px solid #ff4444;
- border-radius: 6px;
- padding: 12px 16px;
- margin-bottom: 16px;
-}
-
-.red-team-prompt h3 {
- margin-top: 0;
- font-size: 14px;
-}
-
-.red-team-prompt p {
- margin: 0;
- color: #cccccc;
- font-style: italic;
-}
-
-/* Red Team Status */
-.red-team-status {
- margin-bottom: 20px;
-}
-
-.red-team-task-info {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 12px;
- background: rgba(0, 0, 0, 0.3);
- border: 1px solid #444;
- border-radius: 4px;
-}
-
-.red-team-task-info .task-name {
- font-weight: bold;
- color: #ffffff;
-}
-
-.no-task, .no-alerts {
- color: #888888;
- font-style: italic;
-}
-
-/* Red Team Notifications */
-.red-team-notifications {
- margin-top: 20px;
-}
-
-.notification-list {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-.notification-item {
- padding: 12px 16px;
- margin-bottom: 12px;
- background: rgba(0, 0, 0, 0.4);
- border-radius: 6px;
- border-left: 4px solid;
-}
-
-.notification-item.severity-info {
- border-left-color: #66ccff;
- background: linear-gradient(90deg, rgba(0, 80, 150, 0.2), transparent);
-}
-
-.notification-item.severity-warning {
- border-left-color: #ffcc00;
- background: linear-gradient(90deg, rgba(150, 120, 0, 0.2), transparent);
-}
-
-.notification-item.severity-critical {
- border-left-color: #ff4444;
- background: linear-gradient(90deg, rgba(150, 0, 0, 0.2), transparent);
-}
-
-.notification-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 8px;
-}
-
-.severity-badge {
- padding: 2px 8px;
- border-radius: 4px;
- font-size: 11px;
- font-weight: bold;
- letter-spacing: 0.5px;
-}
-
-.severity-badge.info {
- background: #003366;
- color: #66ccff;
- border: 1px solid #66ccff;
-}
-
-.severity-badge.warning {
- background: #333300;
- color: #ffcc00;
- border: 1px solid #ffcc00;
-}
-
-.severity-badge.critical {
- background: #660000;
- color: #ff4444;
- border: 1px solid #ff4444;
- animation: pulse-critical 2s infinite;
-}
-
-@keyframes pulse-critical {
- 0%, 100% {
- box-shadow: 0 0 4px rgba(255, 68, 68, 0.5);
- }
- 50% {
- box-shadow: 0 0 12px rgba(255, 68, 68, 0.8);
- }
-}
-
-.notification-time {
- font-size: 11px;
- color: #888888;
-}
-
-.notification-message {
- margin: 0 0 8px 0;
- color: #ffffff;
- line-height: 1.5;
-}
-
-.notification-file {
- display: block;
- font-size: 12px;
- color: #66ccff;
- margin-bottom: 8px;
-}
-
-.notification-context {
- margin: 8px 0 0 0;
- padding: 8px 12px;
- background: rgba(0, 0, 0, 0.5);
- border-radius: 4px;
- font-size: 12px;
- font-family: 'MS Gothic', monospace;
- color: #aaaaaa;
- white-space: pre-wrap;
- overflow-x: auto;
-}
-
-/* =============================================================================
- Contract Create Modal Styles
- ============================================================================= */
-
-.contract-create-modal {
- max-width: 600px;
-}
-
-.contract-create-modal .settings-section:last-child {
- border-top: 1px solid #444;
- padding-top: 16px;
- margin-top: 8px;
-}
-
-.form-input,
-.form-textarea,
-.form-select {
- width: 100%;
- padding: 8px 12px;
- margin-top: 6px;
- background: rgba(0, 0, 0, 0.4);
- border: 1px solid #444;
- border-radius: 4px;
- color: #ffffff;
- font-family: 'MS Gothic', monospace;
- font-size: 13px;
-}
-
-.form-input:focus,
-.form-textarea:focus,
-.form-select:focus {
- outline: none;
- border-color: #66ccff;
- box-shadow: 0 0 6px rgba(102, 204, 255, 0.3);
-}
-
-.form-textarea {
- resize: vertical;
- min-height: 80px;
-}
-
-.form-select {
- cursor: pointer;
-}
-
-.form-select option {
- background: #000000;
- color: #ffffff;
-}
-
-.form-error {
- padding: 10px 14px;
- margin-bottom: 16px;
- background: rgba(255, 0, 0, 0.15);
- border: 1px solid #ff4444;
- border-radius: 4px;
- color: #ff6666;
- font-size: 13px;
-}
-
-.checkbox-label {
- display: flex;
- align-items: center;
- gap: 8px;
- cursor: pointer;
-}
-
-.checkbox-label span {
- color: #ffffff;
-}
-
-.setting-description {
- margin-top: 4px;
- font-size: 11px;
- color: #888888;
- padding-left: 24px;
-}
-
-.red-team-prompt-container {
- margin-top: 12px;
- padding-left: 20px;
-}
-
-.red-team-prompt-container textarea {
- background: rgba(60, 0, 0, 0.2);
- border-color: #ff4444;
-}
-
-.red-team-prompt-container textarea:focus {
- border-color: #ff6666;
- box-shadow: 0 0 8px rgba(255, 68, 68, 0.3);
-}
-
-.modal-btn.primary {
- background: linear-gradient(180deg, #004466, #002233);
- border-color: #66ccff;
- color: #ffffff;
-}
-
-.modal-btn.primary:hover {
- background: linear-gradient(180deg, #005577, #003344);
- box-shadow: 0 0 8px rgba(102, 204, 255, 0.4);
-}
-
-.modal-btn.primary:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-.modal-btn.secondary {
- background: linear-gradient(180deg, #333333, #1a1a1a);
- border-color: #666666;
- color: #cccccc;
-}
-
-.modal-btn.secondary:hover {
- background: linear-gradient(180deg, #444444, #2a2a2a);
-}
-
-.loading,
-.error,
-.not-found {
- padding: 40px;
- text-align: center;
- font-size: 14px;
- color: rgba(255, 255, 255, 0.7);
-}
-
-.error {
- color: #ff6464;
-}
diff --git a/frontend/src/types.ts b/frontend/src/types.ts
index ac8d417..c6d1263 100644
--- a/frontend/src/types.ts
+++ b/frontend/src/types.ts
@@ -9,98 +9,3 @@ export type Choice = {
id: string
label: string
}
-
-// Contract types
-export type ContractType = 'simple' | 'specification' | 'execute'
-export type ContractPhase = 'research' | 'specify' | 'plan' | 'execute' | 'review'
-export type ContractStatus = 'active' | 'completed' | 'archived'
-
-export interface ContractSummary {
- id: string
- name: string
- description?: string
- contractType: string
- phase: string
- status: string
- supervisorTaskId?: string
- localOnly: boolean
- fileCount: number
- taskCount: number
- repositoryCount: number
- version: number
- createdAt: string
- // Red team fields
- redTeamEnabled?: boolean
-}
-
-export interface Contract {
- id: string
- ownerId: string
- name: string
- description?: string
- contractType: string
- phase: string
- status: string
- supervisorTaskId?: string
- autonomousLoop: boolean
- phaseGuard: boolean
- completedDeliverables: Record<string, string[]>
- localOnly: boolean
- redTeamEnabled: boolean
- redTeamPrompt?: string
- version: number
- createdAt: string
- updatedAt: string
-}
-
-export interface CreateContractRequest {
- name: string
- description?: string
- contractType?: string
- initialPhase?: string
- autonomousLoop?: boolean
- phaseGuard?: boolean
- localOnly?: boolean
- redTeamEnabled?: boolean
- redTeamPrompt?: string
-}
-
-export interface TaskSummary {
- id: string
- contractId?: string
- contractName?: string
- contractPhase?: string
- contractStatus?: string
- parentTaskId?: string
- depth: number
- name: string
- status: string
- priority: number
- progressSummary?: string
- subtaskCount: number
- version: number
- isSupervisor: boolean
- isRedTeam: boolean
- hidden: boolean
- createdAt: string
- updatedAt: string
-}
-
-// Red team notification types
-export type NotificationSeverity = 'info' | 'warning' | 'critical'
-
-export interface RedTeamNotification {
- id: string
- contractId: string
- redTeamTaskId: string
- relatedTaskId?: string
- message: string
- severity: NotificationSeverity
- filePath?: string
- context?: string
- delivered: boolean
- deliveredAt?: string
- acknowledged: boolean
- acknowledgedAt?: string
- createdAt: string
-}
diff --git a/frontend/tsconfig.tsbuildinfo b/frontend/tsconfig.tsbuildinfo
index 0fd5af9..79408dc 100644
--- a/frontend/tsconfig.tsbuildinfo
+++ b/frontend/tsconfig.tsbuildinfo
@@ -1 +1 @@
-{"root":["./src/app.tsx","./src/main.tsx","./src/types.ts","./src/components/bottombar.tsx","./src/components/choicemenu.tsx","./src/components/cityscapebackground.tsx","./src/components/configmodal.tsx","./src/components/contractcreatemodal.tsx","./src/components/contractdetail.tsx","./src/components/contractlist.tsx","./src/components/dialoguebox.tsx","./src/components/filedetail.tsx","./src/components/heartlogo.tsx","./src/components/landingpage.tsx","./src/components/loadingscreen.tsx","./src/components/origamidragonlogo.tsx","./src/components/topbar.tsx","./src/components/vnapp.tsx","./src/components/vninterface.tsx","./src/components/vnviewport.tsx","./src/services/ws.ts","./src/stores/index.ts"],"version":"5.9.2"} \ No newline at end of file
+{"root":["./src/app.tsx","./src/main.tsx","./src/types.ts","./src/components/bottombar.tsx","./src/components/choicemenu.tsx","./src/components/cityscapebackground.tsx","./src/components/configmodal.tsx","./src/components/contractdetail.tsx","./src/components/contractlist.tsx","./src/components/dialoguebox.tsx","./src/components/filedetail.tsx","./src/components/heartlogo.tsx","./src/components/landingpage.tsx","./src/components/loadingscreen.tsx","./src/components/origamidragonlogo.tsx","./src/components/topbar.tsx","./src/components/vnapp.tsx","./src/components/vninterface.tsx","./src/components/vnviewport.tsx","./src/services/ws.ts","./src/stores/index.ts"],"version":"5.9.2"} \ No newline at end of file