Remove the ink-blue top rank bar, running-state border override, and
green glow shadow from org chart cards. The tree layout already
communicates rank by position, and a dashed ink-blue connection line
plus the bottom-right status dot + ping animation already mark
running agents — duplicating the signal through a card-wide color
band and a cyan/green shadow was pure decoration.
- Drop the rounded-t [4px bg-primary | 2px bg-border] top bar entirely.
- Running state stops overriding border to var(--primary); all running
cards fall back to the neutral border-border like everyone else.
- Running state stops emitting a success-tinted glow (shadow-[0_0_12px
color-mix(... var(--success) 15% ...)]) — kami rule 8 bans drop
shadows, and the tint introduced an unauthorized green.
- Hover switches from shadow-lg + translate-y-0.5 to a subtle
hover:bg-muted/30 tint.
- Active/running avatar circle switches from bg-success-muted
text-success to bg-accent text-primary (kami's ink-blue tint),
removing the last green chrome on the page.
- Heartbeat icon switches from text-success to text-primary.
- Avatar initials move from font-bold (700) to font-semibold (600).
Error / pending_approval keep their destructive border (red), since
kami reserves the warm terra red for genuine error/destructive state
per design.md color system.
Typecheck and build:verify clean.
Previously the agent Edit modal was a 351-LOC wall of 17 stacked form
fields with no visual grouping, mixed header styles between the
skills heading and the field labels, a Save button that was always
enabled, no Cancel affordance, and a Thinking Effort field that
silently disappeared when the selected connector did not support it.
This commit restructures the edit surface into five named sections
— Identity, Runtime, Budget & scope, Behavior, Skills — each with a
consistent SectionHeader (11px uppercase muted, border-top divider).
Every section lives in its own ≤150-LOC file under
agent-form-fields/edit-sections/ so nothing stays god-sized:
EditFormBody.tsx 199 LOC (orchestrator: isDirty, handlers)
IdentitySection.tsx 74 LOC
RuntimeSection.tsx 114 LOC
ConstraintsSection.tsx 58 LOC
SkillsSection.tsx 36 LOC
EditActionBar.tsx 87 LOC
SectionHeader.tsx 18 LOC
Behavioral changes:
- Save is disabled until the form is dirty (trimmed-string + numeric
budget comparison against the persisted agent record). The board
sees whether changes are captured without clicking Save to find out.
- Cancel button added, wired through AgentForm → AgentEditor →
OrganizationSections, which clears selectedAgentId (same as the
modal's close X — a proper bottom action avoids users reaching for
the corner).
- Thinking Effort is always shown. When the connector provider does
not accept the hint the Select is disabled with an inline note,
so the option is discoverable instead of silently hidden.
- Budget shows a live BudgetBar + "Spent $X of $Y" line when the
budget or spend is non-zero. The raw number input on its own left
burn state invisible.
- Capabilities placeholder replaced with a concrete example
("writes React components, reviews PRs, ...") — the previous
"What this agent does" was a circular prompt.
- OrgChart role bar went from three tiers (CEO 4px primary /
manager 3px warning / IC 2px muted 30%) to binary (root 4px
primary / everyone else 2px border). Orange-warning for managers
read as an alert, not a rank; managerial position is already
encoded in the tree's topology.
Also added i18n keys (zh + en):
agent.form.sectionIdentity / sectionRuntime / sectionConstraints /
sectionBehavior / effortNotSupported / budgetBurn; updated
capabilitiesPlaceholder copy.
Covers J2 / J7 / J8 / S5 / S6 / S7 / S8.
Two audit items addressed together because they share the same org-page
render surface and both enforce "read the screen correctly before acting":
1) Status dot colors in OrgChart were undocumented — users saw five
distinct colors (running/active/idle/paused/error/terminated/
pending_approval) with no key. Added a compact top-left legend that
only lists the statuses actually present in the current org, so a
healthy all-running company shows two rows, not seven. Label copy
reuses existing agent.form.status* keys (zh/en).
2) The agent Edit modal offered Delete and Status=terminated on every
agent, including the root (no reportsTo) — the CEO. Deleting or
terminating a root orphans every direct report. Added `isRootAgent`
check in EditFormBody:
- Delete button: disabled, with `rootDeleteBlocked` inline note
telling the user to reassign reports first.
- Status select: `terminated` option hidden; `rootTerminateBlocked`
note explains why.
Scope note: this is UI-level guardrail only. The deleteAgent IPC /
API route is unchanged — same-company power users with DB access can
still do surgical fixes; the board-facing UX just refuses to be a
footgun. Covers J5 / S3 / S4.
OrgChart and AgentRoster both carried a `claude_compat`-prefix fallback
chained against `adapterLabels[connectorId] ?? connectorId` to paper
over the pre-pi-mono connector id space (claude_local / codex_local /
gemini_local / claude_compat_2..10). The migration to pi-mono's catalog
retired those ids months ago — the fallback is dead code that still
runs `String.prototype.startsWith` on every render and forks the label
resolution into two subtly different shapes in two files.
Replaced with `formatConnectorLabel(connector, fallbackId)` in
lib/formatters.ts, used by both OrgChart and AgentRoster.
Also in this commit (typography polish bundled because touching the
same render paths):
- OrgChart connector label: 9px uppercase tracking-0.08em → 11px
tracking-tight. The 9px chip was unreadable at default zoom.
- OrgChart zoom controls: `+` / `−` / "Fit" mixed text + character ops
replaced with Plus / Minus / CornersOut icons (imported from the
existing icon barrel) + a focus-visible ring for keyboard users.
No rendering changes for the non-cosmetic path (status dots, card
layout, edges). The removed `adapterLabels` map was exported from
orgTreeLayout.ts and had no other importers.
Covers J1 / J3 / J4 / J6 from the team-page audit.
Create src/renderer/components/ui/icons.ts as the single re-export point
for every Phosphor icon the renderer touches, then rewrite the 95 files
that previously imported directly from "@phosphor-icons/react" to pull
from the relative-path-to-barrel instead. The TitleBar commit earlier
in this series already used ui/icons; this commit extends the pattern
to the rest of the renderer.
Benefits now wired in:
- one location where bundle tree-shaking can be reasoned about,
- typos like Briefcase vs BriefCase show up against a finite list,
- re-theming or swapping icon sets is a one-file edit,
- a lint rule that flags raw @phosphor-icons/react imports can be
added later without mass-rewriting call sites.
The barrel also re-exports the `Icon` type so call sites that type
icon props against the Phosphor component type work unchanged.
Test count stays at 363 passing; typecheck stays at 156 errors.
- Replace all bg-[color:var(--old)] with bg-background/bg-card/bg-muted/bg-primary etc.
- Replace all text-[color:var(--old)] with text-foreground/text-muted-foreground/text-primary etc.
- Replace all border-[color:var(--line)] with border-border
- Replace all inline var(--old) with var(--new) equivalents
- Replace all rounded-[6px]/rounded-[8px] with rounded-lg
- Replace .surface class with bg-card border border-border shadow-sm
- Replace .focus-ring class with focus-visible Tailwind utilities
- Replace .mono class with font-mono
- Replace data-theme attribute with class-based dark mode
- 99 files updated, ~1265 lines changed, zero old references remaining