summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-28 03:51:07 +0000
committerGitHub <noreply@github.com>2026-01-28 03:51:07 +0000
commitb141fca0c0604bdeba9fa563a8049cf29cc03bcf (patch)
treecea451e6e12dc7fa0fe2882f6c2bed4b8eddff82
parent9b53f6c6b01da85ef73bd5960b32ec319df0b947 (diff)
downloadsoryu-b141fca0c0604bdeba9fa563a8049cf29cc03bcf.tar.gz
soryu-b141fca0c0604bdeba9fa563a8049cf29cc03bcf.zip
Fix starting phase dropdown to show correct phase names from templates (#42)
* Add comprehensive Red Team system specification Defines the adversarial review feature for contracts that monitors work tasks in real-time to catch quality issues, plan deviations, and standards violations. Key components specified: - Contract configuration (red_team_enabled, red_team_prompt) - Red team task lifecycle and spawning logic - makima red-team notify CLI command for supervisor alerts - Task output subscription for real-time monitoring - Database schema changes (contracts, tasks, notifications table) - API endpoints for notification and status - System prompt template for red team behavior - Security considerations and access control Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Task completion checkpoint * Task completion checkpoint * Task completion checkpoint * Fix starting phase dropdown to show correct phase names from templates Add phaseNames map to ContractTypeTemplate to preserve display names from custom templates loaded from localStorage. The dropdown now uses the template's phase name (e.g., 'Design & Architecture') instead of naive capitalization of the phase ID. Falls back to capitalization for built-in templates that don't provide phaseNames. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
-rw-r--r--makima/frontend/src/lib/api.ts2
-rw-r--r--makima/frontend/src/routes/contracts.tsx19
2 files changed, 15 insertions, 6 deletions
diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts
index ca04ce7..c9648a2 100644
--- a/makima/frontend/src/lib/api.ts
+++ b/makima/frontend/src/lib/api.ts
@@ -1636,6 +1636,8 @@ export interface ContractTypeTemplate {
defaultPhase: ContractPhase;
/** Whether this is a built-in type (always available) */
isBuiltin: boolean;
+ /** Optional mapping from phase ID to display name */
+ phaseNames?: Record<string, string>;
}
/** Response from list contract types endpoint */
diff --git a/makima/frontend/src/routes/contracts.tsx b/makima/frontend/src/routes/contracts.tsx
index aa62bd9..9891f29 100644
--- a/makima/frontend/src/routes/contracts.tsx
+++ b/makima/frontend/src/routes/contracts.tsx
@@ -108,11 +108,12 @@ function ContractsPageContent() {
// Convert user templates to ContractTypeTemplate format, excluding built-ins
return templates
.filter((t: { isBuiltIn?: boolean }) => !t.isBuiltIn)
- .map((t: { id: string; name: string; description: string; phases: { id: string }[] }) => ({
+ .map((t: { id: string; name: string; description: string; phases: { id: string; name: string }[] }) => ({
id: t.id,
name: t.name,
description: t.description,
phases: t.phases.map((p: { id: string }) => p.id) as ContractPhase[],
+ phaseNames: Object.fromEntries(t.phases.map((p: { id: string; name: string }) => [p.id, p.name])),
defaultPhase: (t.phases[0]?.id || "execute") as ContractPhase,
isBuiltin: false,
}));
@@ -652,11 +653,17 @@ function ContractsPageContent() {
onChange={(e) => setInitialPhase(e.target.value as ContractPhase)}
className="w-full px-3 py-2 bg-[#0d1b2d] border border-[#3f6fb3] text-[#dbe7ff] font-mono text-sm focus:outline-none focus:border-[#75aafc]"
>
- {(contractTypes.find((t) => t.id === contractType)?.phases || []).map((phase) => (
- <option key={phase} value={phase}>
- {phase.charAt(0).toUpperCase() + phase.slice(1)}
- </option>
- ))}
+ {(() => {
+ const template = contractTypes.find((t) => t.id === contractType);
+ return (template?.phases || []).map((phase) => {
+ const displayName = template?.phaseNames?.[phase] || (phase.charAt(0).toUpperCase() + phase.slice(1));
+ return (
+ <option key={phase} value={phase}>
+ {displayName}
+ </option>
+ );
+ });
+ })()}
</select>
<p className="mt-1 font-mono text-xs text-[#8b949e]">
{contractType === "simple"