rename(phase 1): CapaKraken → Nexus across code, UI, docs, CI (#61)
CI / Architecture Guardrails (push) Successful in 2m38s
CI / Assistant Split Regression (push) Successful in 3m33s
CI / Typecheck (push) Successful in 3m51s
CI / Lint (push) Successful in 5m2s
CI / E2E Tests (push) Has been cancelled
CI / Fresh-Linux Docker Deploy (push) Has been cancelled
CI / Release Images (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled

rename(phase 1): CapaKraken → Nexus across code, UI, docs, CI (#61)

Co-authored-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com>
Co-committed-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com>
This commit was merged in pull request #61.
This commit is contained in:
2026-05-21 16:28:40 +02:00
committed by Hartmut
parent d9a7ec0338
commit b41c1d2501
943 changed files with 24548 additions and 16832 deletions
@@ -1,8 +1,8 @@
"use client";
import { useState, useMemo, useCallback } from "react";
import { FieldType } from "@capakraken/shared";
import type { BlueprintFieldDefinition, FieldOption, StaffingRequirement } from "@capakraken/shared";
import { FieldType } from "@nexus/shared";
import type { BlueprintFieldDefinition, FieldOption, StaffingRequirement } from "@nexus/shared";
import { trpc } from "~/lib/trpc/client.js";
import { RolePresetsEditor } from "./RolePresetsEditor.js";
import { FieldCard } from "./FieldCard.js";
@@ -48,10 +48,7 @@ interface FieldState {
// Helpers: Convert between FieldState and BlueprintFieldDefinition
// ---------------------------------------------------------------------------
function fieldDefToState(
def: BlueprintFieldDefinition,
target: BlueprintTargetValue,
): FieldState {
function fieldDefToState(def: BlueprintFieldDefinition, target: BlueprintTargetValue): FieldState {
const catalogField = findCatalogField(target, def.key);
if (catalogField) {
return {
@@ -186,9 +183,7 @@ export function BlueprintFieldCatalog({
// Build initial state from existing fieldDefs + catalog
// ---------------------------------------------------------------------------
const [catalogOverrides, setCatalogOverrides] = useState<
Record<string, FieldOverrides>
>(() => {
const [catalogOverrides, setCatalogOverrides] = useState<Record<string, FieldOverrides>>(() => {
const map: Record<string, FieldOverrides> = {};
// Start with all catalog fields disabled
for (const cf of catalog) {
@@ -269,21 +264,13 @@ export function BlueprintFieldCatalog({
// Handlers
// ---------------------------------------------------------------------------
const handleCatalogFieldChange = useCallback(
(key: string, overrides: FieldOverrides) => {
setCatalogOverrides((prev) => ({ ...prev, [key]: overrides }));
},
[],
);
const handleCatalogFieldChange = useCallback((key: string, overrides: FieldOverrides) => {
setCatalogOverrides((prev) => ({ ...prev, [key]: overrides }));
}, []);
const handleCustomFieldChange = useCallback(
(idx: number, overrides: FieldOverrides) => {
setCustomFields((prev) =>
prev.map((f, i) => (i === idx ? { ...f, overrides } : f)),
);
},
[],
);
const handleCustomFieldChange = useCallback((idx: number, overrides: FieldOverrides) => {
setCustomFields((prev) => prev.map((f, i) => (i === idx ? { ...f, overrides } : f)));
}, []);
function removeCustomField(idx: number) {
setCustomFields((prev) => prev.filter((_, i) => i !== idx));
@@ -370,9 +357,7 @@ export function BlueprintFieldCatalog({
// Collapsed categories
// ---------------------------------------------------------------------------
const [collapsedCategories, setCollapsedCategories] = useState<Set<string>>(
new Set(),
);
const [collapsedCategories, setCollapsedCategories] = useState<Set<string>>(new Set());
function toggleCategory(name: string) {
setCollapsedCategories((prev) => {
@@ -502,15 +487,16 @@ export function BlueprintFieldCatalog({
{/* Field cards */}
<div className="flex-1 overflow-y-auto px-4 py-4 space-y-6">
{categories
.filter(
(cat) =>
activeCategory === null ||
activeCategory === cat.name,
)
.filter((cat) => activeCategory === null || activeCategory === cat.name)
.map((cat) => {
const fields = fieldsByCategory.get(cat.name) ?? [];
if (fields.length === 0 && searchQuery.trim()) return null;
if (fields.length === 0 && activeCategory !== null && activeCategory !== cat.name) return null;
if (
fields.length === 0 &&
activeCategory !== null &&
activeCategory !== cat.name
)
return null;
const isCollapsed = collapsedCategories.has(cat.name);
@@ -527,9 +513,7 @@ export function BlueprintFieldCatalog({
<h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider">
{cat.name}
</h3>
<span className="text-xs text-gray-400">
{cat.description}
</span>
<span className="text-xs text-gray-400">{cat.description}</span>
</button>
{!isCollapsed && (
<div className="grid grid-cols-1 gap-2">
@@ -538,9 +522,7 @@ export function BlueprintFieldCatalog({
key={field.key}
field={field}
overrides={catalogOverrides[field.key]!}
onChange={(ov) =>
handleCatalogFieldChange(field.key, ov)
}
onChange={(ov) => handleCatalogFieldChange(field.key, ov)}
/>
))}
{fields.length === 0 && (
@@ -555,8 +537,7 @@ export function BlueprintFieldCatalog({
})}
{/* Custom Fields section */}
{(activeCategory === null ||
activeCategory === "Custom Fields") && (
{(activeCategory === null || activeCategory === "Custom Fields") && (
<div>
<button
type="button"
@@ -564,9 +545,7 @@ export function BlueprintFieldCatalog({
className="flex items-center gap-2 mb-3 w-full text-left group"
>
<span className="text-xs text-gray-400 transition-transform group-hover:text-gray-600">
{collapsedCategories.has("Custom Fields")
? "\u25B6"
: "\u25BC"}
{collapsedCategories.has("Custom Fields") ? "\u25B6" : "\u25BC"}
</span>
<h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider">
Custom Fields
@@ -585,8 +564,7 @@ export function BlueprintFieldCatalog({
label: cf.custom.label,
type: cf.custom.type,
category: "Custom Fields",
description:
cf.overrides.description || "Custom field",
description: cf.overrides.description || "Custom field",
...(cf.custom.options.length > 0
? { options: cf.custom.options }
: {}),
@@ -597,9 +575,7 @@ export function BlueprintFieldCatalog({
<FieldCard
field={pseudoCatalog}
overrides={cf.overrides}
onChange={(ov) =>
handleCustomFieldChange(idx, ov)
}
onChange={(ov) => handleCustomFieldChange(idx, ov)}
/>
<button
type="button"
@@ -619,19 +595,13 @@ export function BlueprintFieldCatalog({
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div className="flex flex-col gap-1">
<label className="text-xs font-medium text-gray-600">
Key{" "}
<span className="text-red-500">*</span>
Key <span className="text-red-500">*</span>
</label>
<input
type="text"
value={customKey}
onChange={(e) =>
setCustomKey(
e.target.value.replace(
/[^a-zA-Z0-9_]/g,
"",
),
)
setCustomKey(e.target.value.replace(/[^a-zA-Z0-9_]/g, ""))
}
placeholder="field_key"
className="app-input font-mono"
@@ -639,30 +609,21 @@ export function BlueprintFieldCatalog({
</div>
<div className="flex flex-col gap-1">
<label className="text-xs font-medium text-gray-600">
Label{" "}
<span className="text-red-500">*</span>
Label <span className="text-red-500">*</span>
</label>
<input
type="text"
value={customLabel}
onChange={(e) =>
setCustomLabel(e.target.value)
}
onChange={(e) => setCustomLabel(e.target.value)}
placeholder="Display Label"
className="app-input"
/>
</div>
<div className="flex flex-col gap-1">
<label className="text-xs font-medium text-gray-600">
Type
</label>
<label className="text-xs font-medium text-gray-600">Type</label>
<select
value={customType}
onChange={(e) =>
setCustomType(
e.target.value as FieldType,
)
}
onChange={(e) => setCustomType(e.target.value as FieldType)}
className="app-input"
>
{FIELD_TYPES.map((ft) => (
@@ -677,9 +638,7 @@ export function BlueprintFieldCatalog({
<button
type="button"
onClick={addCustomField}
disabled={
!customKey.trim() || !customLabel.trim()
}
disabled={!customKey.trim() || !customLabel.trim()}
className={BTN_PRIMARY}
>
Add
@@ -704,8 +663,7 @@ export function BlueprintFieldCatalog({
onClick={() => setShowCustomForm(true)}
className="flex items-center gap-1.5 text-sm text-brand-600 hover:text-brand-800 font-medium py-2"
>
<span className="text-lg leading-none">+</span>{" "}
Add Custom Field
<span className="text-lg leading-none">+</span> Add Custom Field
</button>
)}
</div>
@@ -726,8 +684,7 @@ export function BlueprintFieldCatalog({
{/* Footer */}
<div className="flex items-center justify-between gap-3 px-6 py-4 border-t border-gray-200 dark:border-gray-700 shrink-0">
<span className="text-xs text-gray-400">
{enabledCount} field{enabledCount !== 1 ? "s" : ""} will be
saved
{enabledCount} field{enabledCount !== 1 ? "s" : ""} will be saved
</span>
<div className="flex items-center gap-3">
<button type="button" onClick={onClose} className={BTN_SECONDARY}>
@@ -747,8 +704,8 @@ export function BlueprintFieldCatalog({
) : (
<div className="px-6 py-4 overflow-y-auto">
<p className="text-xs text-gray-500 mb-4">
Role presets are auto-loaded in Step 3 of the Project Creation
Wizard when this blueprint is selected.
Role presets are auto-loaded in Step 3 of the Project Creation Wizard when this
blueprint is selected.
</p>
<RolePresetsEditor
initialPresets={initialRolePresets}