-
Members
-
- {total} {total === 1 ? "member" : "members"} · {employees.length} {employees.length === 1 ? "human" : "humans"} · {agents.length} {agents.length === 1 ? "agent" : "agents"}
-
-
-
-
Member
Type
Department
Budget
-
- {employees.map((employee) => (
-
-
-
-
-
{employee.displayName}
-
{employee.role}
-
-
-
-
—
-
—
-
- ))}
- {agents.map((agent, index) => (
-
-
-
-
-
{agent.name}
-
{agent.role}
-
-
-
-
{agent.department}
-
{money(agent.budgetCents)}
-
- ))}
-
-
Identity & Access
-
-
-
Principal
Identity source
Roles
-
- {employees.map((employee, index) => (
-
- ))}
- {agents.map((agent, index) => {
- const serviceIdentity = serviceIdentities.find((identity) => identity.agentId === agent.id);
- return (
-
- );
- })}
-
-
- );
-}
-
-function AccessRow({
- name,
- detail,
- source,
- roles,
- bot,
- last,
-}: {
- name: string;
- detail: string;
- source: string;
- roles: string[];
- bot: boolean;
- last: boolean;
-}) {
- return (
-
-
Models
-
Models that agents reference, derived from connected providers and agent assignments.
-
-
-
Provider
Model
Agents
Source
-
- {rows.map((row, index) => (
-
-
-
{row.providerLabel}
-
{row.authType}
-
-
{row.model}
-
{row.agentCount}
-
{row.source === "default" ?
Provider default :
Agent assignment}
-
- ))}
-
-
- );
-}
-
-interface ModelRow {
- providerId: string;
- providerLabel: string;
- authType: string;
- model: string;
- agentCount: number;
- source: "default" | "agent";
-}
-
-function collectModels(providers: ProviderRecord[], agents: AgentRecord[]): ModelRow[] {
- const map = new Map();
- for (const provider of providers) {
- if (!provider.enabled || !provider.model) continue;
- const key = `${provider.id}::${provider.model}`;
- map.set(key, {
- providerId: provider.id,
- providerLabel: provider.label,
- authType: humanAuth(provider.authType),
- model: provider.model,
- agentCount: 0,
- source: "default",
- });
- }
- for (const agent of agents) {
- if (!agent.modelProviderId) continue;
- const provider = providers.find((item) => item.id === agent.modelProviderId);
- if (!provider) continue;
- const effectiveModel = agent.modelId ?? provider.model;
- if (!effectiveModel) continue;
- const key = `${provider.id}::${effectiveModel}`;
- const existing = map.get(key);
- if (existing) {
- existing.agentCount += 1;
- continue;
- }
- map.set(key, {
- providerId: provider.id,
- providerLabel: provider.label,
- authType: humanAuth(provider.authType),
- model: effectiveModel,
- agentCount: 1,
- source: "agent",
- });
- }
- return [...map.values()].sort((a, b) => a.providerLabel.localeCompare(b.providerLabel));
-}
-
-function humanAuth(authType: string): string {
- if (authType === "api_key") return "API key";
- if (authType === "oauth_pkce") return "OAuth";
- if (authType === "account_subscription") return "Account";
- if (authType === "cloud") return "Cloud";
- return authType;
-}
diff --git a/AgentCompany-New/src/renderer/src/pages/settings/OperationsPanel.tsx b/AgentCompany-New/src/renderer/src/pages/settings/OperationsPanel.tsx
deleted file mode 100644
index 954e605d..00000000
--- a/AgentCompany-New/src/renderer/src/pages/settings/OperationsPanel.tsx
+++ /dev/null
@@ -1,197 +0,0 @@
-import { Button, Pill } from "../../shared/ui";
-import type {
- ChaosDrillRecord,
- ChaosDrillRunRecord,
- FeatureFlagRecord,
- OperationalEventRecord,
- SloTargetRecord,
-} from "../../../../shared/domain";
-import type { SnapshotActions } from "../../app/useSnapshot";
-import { formatRelative } from "../types";
-
-export function OperationsPanel({
- orgId,
- featureFlags,
- sloTargets,
- operationalEvents,
- chaosDrills,
- chaosDrillRuns,
- actions,
-}: {
- orgId: string;
- featureFlags: FeatureFlagRecord[];
- sloTargets: SloTargetRecord[];
- operationalEvents: OperationalEventRecord[];
- chaosDrills: ChaosDrillRecord[];
- chaosDrillRuns: ChaosDrillRunRecord[];
- actions: SnapshotActions;
-}) {
- return (
-
-
Operations
-
{featureFlags.length} flags / {sloTargets.length} SLOs / {chaosDrills.length} drills.
-
-
-
-
- );
-}
-
-function FeatureFlagsTable({
- orgId,
- flags,
- actions,
-}: {
- orgId: string;
- flags: FeatureFlagRecord[];
- actions: SnapshotActions;
-}) {
- return (
- <>
- Feature flags
-
-
- {flags.map((flag, index) => (
-
-
-
{flag.label}
-
{flag.key}
-
-
-
{formatRelative(flag.updatedAt)}
-
- ))}
-
- >
- );
-}
-
-function SloTable({
- targets,
- events,
-}: {
- targets: SloTargetRecord[];
- events: OperationalEventRecord[];
-}) {
- return (
- <>
- SLO targets
-
-
-
Signal
Target
Current
Samples
-
- {targets.map((target, index) => {
- const samples = events.filter((event) => event.signalKey === target.signalKey && withinWindow(event.createdAt, target.windowMinutes));
- const successes = samples.filter((event) => event.success).length;
- return (
-
-
-
{target.label}
-
{target.signalKey}
-
-
{formatBasisPoints(target.targetBasisPoints)}
-
0 && currentBasisPoints(successes, samples.length) < target.targetBasisPoints ? "amber" : undefined}>{formatCurrent(successes, samples.length)}
-
{samples.length}
-
- );
- })}
-
- >
- );
-}
-
-function ChaosDrillsTable({
- orgId,
- drills,
- runs,
- actions,
-}: {
- orgId: string;
- drills: ChaosDrillRecord[];
- runs: ChaosDrillRunRecord[];
- actions: SnapshotActions;
-}) {
- return (
- <>
- Chaos drills
-
-
-
Drill
Last run
Result
Action
-
- {drills.map((drill, index) => {
- const run = runs.find((item) => item.drillId === drill.id) ?? null;
- return (
-
-
-
{drill.label}
-
{drill.scenarioKey}
-
-
{run ? formatRelative(run.startedAt) : "0 runs"}
-
-
-
- );
- })}
-
- >
- );
-}
-
-function withinWindow(iso: string, windowMinutes: number): boolean {
- const createdAt = new Date(iso).getTime();
- if (Number.isNaN(createdAt)) return false;
- return Date.now() - createdAt <= windowMinutes * 60_000;
-}
-
-function currentBasisPoints(successes: number, samples: number): number {
- if (samples === 0) return 0;
- return Math.round((successes / samples) * 10000);
-}
-
-function formatCurrent(successes: number, samples: number): string {
- if (samples === 0) return "0 / 0";
- return formatBasisPoints(currentBasisPoints(successes, samples));
-}
-
-function formatBasisPoints(value: number): string {
- return `${(value / 100).toFixed(value % 100 === 0 ? 0 : 2)}%`;
-}
diff --git a/AgentCompany-New/src/renderer/src/pages/settings/PoliciesPanel.tsx b/AgentCompany-New/src/renderer/src/pages/settings/PoliciesPanel.tsx
deleted file mode 100644
index 8837fb64..00000000
--- a/AgentCompany-New/src/renderer/src/pages/settings/PoliciesPanel.tsx
+++ /dev/null
@@ -1,173 +0,0 @@
-import { Pill } from "../../shared/ui";
-import type {
- AgentRecord,
- ApprovalAssignmentRecord,
- ApprovalRoutingRuleRecord,
- EmployeeRecord,
- HiringPolicyRecord,
- OrgDepartmentRecord,
- PolicyRuleRecord,
-} from "../../../../shared/domain";
-import { money } from "../types";
-
-export function PoliciesPanel({
- policies,
- agents,
- employees,
- orgDepartments,
- hiringPolicies,
- approvalRoutingRules,
- approvalAssignments,
-}: {
- policies: PolicyRuleRecord[];
- agents: AgentRecord[];
- employees: EmployeeRecord[];
- orgDepartments: OrgDepartmentRecord[];
- hiringPolicies: HiringPolicyRecord[];
- approvalRoutingRules: ApprovalRoutingRuleRecord[];
- approvalAssignments: ApprovalAssignmentRecord[];
-}) {
- return (
-
-
Policies
-
Policy rules evaluated for actions across the workspace.
-
Rules
-
-
-
Action
Effect
Risk ceiling
Subject
-
- {policies.map((policy, index) => (
-
-
{policy.action.replaceAll("_", " ")}
-
{policy.effect.replaceAll("_", " ")}
-
-
- {policy.riskCeiling}
-
-
-
{policy.subjectType}
-
- ))}
-
-
-
Hiring policies
-
-
-
Department
Headcount
Budget cap
Review
-
- {hiringPolicies.map((policy, index) => (
-
item.name === policy.departmentName) ?? null}
- agents={agents}
- last={index === hiringPolicies.length - 1}
- />
- ))}
-
-
-
Review routing
-
-
-
Kind
Min risk
Route
Assigned
-
- {approvalRoutingRules.map((rule, index) => (
-
assignment.routingRuleId === rule.id).length}
- last={index === approvalRoutingRules.length - 1}
- />
- ))}
-
-
- );
-}
-
-function HiringPolicyRow({
- policy,
- department,
- agents,
- last,
-}: {
- policy: HiringPolicyRecord;
- department: OrgDepartmentRecord | null;
- agents: AgentRecord[];
- last: boolean;
-}) {
- if (!department) throw new Error(`Department governance is missing for ${policy.departmentName}.`);
- const roster = agents.filter((agent) => agent.department === policy.departmentName && agent.lifecycle === "active");
- const budgetCents = roster.reduce((sum, agent) => sum + agent.budgetCents, 0);
- return (
-
-
{policy.departmentName}
-
{roster.length} / {department.headcountLimit}
-
{money(budgetCents)} / {money(policy.monthlyBudgetLimitCents)}
-
{money(policy.requireApprovalAboveCents)}
-
- );
-}
-
-function RoutingRuleRow({
- rule,
- employees,
- agents,
- assignmentCount,
- last,
-}: {
- rule: ApprovalRoutingRuleRecord;
- employees: EmployeeRecord[];
- agents: AgentRecord[];
- assignmentCount: number;
- last: boolean;
-}) {
- return (
-
-
{rule.kind}
-
-
- {routeLabel(rule, employees, agents)}
-
-
{assignmentCount}
-
- );
-}
-
-function routeLabel(rule: ApprovalRoutingRuleRecord, employees: EmployeeRecord[], agents: AgentRecord[]): string {
- if (rule.routeToType === "board") return "Board";
- if (rule.routeToType === "employee") {
- const employee = employees.find((item) => item.id === rule.routeToId);
- if (!employee) throw new Error("Approval route employee is missing.");
- return employee.displayName;
- }
- const agent = agents.find((item) => item.id === rule.routeToId);
- if (!agent) throw new Error("Approval route agent is missing.");
- return agent.name;
-}
diff --git a/AgentCompany-New/src/renderer/src/pages/settings/SdlcPanel.tsx b/AgentCompany-New/src/renderer/src/pages/settings/SdlcPanel.tsx
deleted file mode 100644
index 0e623f9a..00000000
--- a/AgentCompany-New/src/renderer/src/pages/settings/SdlcPanel.tsx
+++ /dev/null
@@ -1,240 +0,0 @@
-import { Button, Pill } from "../../shared/ui";
-import type {
- EvalCaseRecord,
- EvalRunRecord,
- EvalSuiteRecord,
- MigrationReportRecord,
- PolicyRuleRecord,
- PrBotGateRecord,
- SdlcReviewAgentRecord,
- SdlcReviewRunRecord,
- SdlcReviewTargetType,
-} from "../../../../shared/domain";
-import { SDLC_REVIEW_AGENT_KEY, SDLC_REVIEW_TARGET_TYPE } from "../../../../shared/domain";
-import type { SnapshotActions } from "../../app/useSnapshot";
-import { formatRelative } from "../types";
-
-export function SdlcPanel({
- orgId,
- reviewAgents,
- reviewRuns,
- evalSuites,
- evalCases,
- evalRuns,
- prBotGates,
- migrationReports,
- policies,
- actions,
-}: {
- orgId: string;
- reviewAgents: SdlcReviewAgentRecord[];
- reviewRuns: SdlcReviewRunRecord[];
- evalSuites: EvalSuiteRecord[];
- evalCases: EvalCaseRecord[];
- evalRuns: EvalRunRecord[];
- prBotGates: PrBotGateRecord[];
- migrationReports: MigrationReportRecord[];
- policies: PolicyRuleRecord[];
- actions: SnapshotActions;
-}) {
- return (
-
-
SDLC
-
{reviewAgents.length} agents / {evalSuites.length} suites / {prBotGates.length} gates.
-
-
-
-
- );
-}
-
-function ReviewAgentsTable({
- orgId,
- agents,
- runs,
- migrationReports,
- policies,
- actions,
-}: {
- orgId: string;
- agents: SdlcReviewAgentRecord[];
- runs: SdlcReviewRunRecord[];
- migrationReports: MigrationReportRecord[];
- policies: PolicyRuleRecord[];
- actions: SnapshotActions;
-}) {
- return (
- <>
- Review agents
-
-
-
Agent
Target
Last run
Action
-
- {agents.map((agent, index) => {
- const target = resolveReviewTarget(agent, orgId, migrationReports, policies);
- const run = runs.find((item) => item.reviewAgentId === agent.id) ?? null;
- return (
-
-
-
{agent.label}
-
{agent.specialty}
-
-
-
{run ? `${run.state} · ${formatRelative(run.createdAt)}` : "0 runs"}
-
-
- );
- })}
-
- >
- );
-}
-
-function EvalSuitesTable({
- orgId,
- suites,
- cases,
- runs,
- actions,
-}: {
- orgId: string;
- suites: EvalSuiteRecord[];
- cases: EvalCaseRecord[];
- runs: EvalRunRecord[];
- actions: SnapshotActions;
-}) {
- return (
- <>
- Eval suites
-
-
-
Suite
Cases
Last run
Action
-
- {suites.map((suite, index) => {
- const run = runs.find((item) => item.suiteId === suite.id) ?? null;
- const caseCount = cases.filter((item) => item.suiteId === suite.id).length;
- return (
-
-
-
{suite.label}
-
{suite.scope}
-
-
{caseCount}
-
{run ? `${run.state} · ${formatRelative(run.createdAt)}` : "0 runs"}
-
-
- );
- })}
-
- >
- );
-}
-
-function PrBotGatesTable({
- orgId,
- gates,
- actions,
-}: {
- orgId: string;
- gates: PrBotGateRecord[];
- actions: SnapshotActions;
-}) {
- return (
- <>
- PR bot gates
-
-
- {gates.map((gate, index) => (
-
-
-
{gate.label}
-
{gate.gateType}
-
-
-
{formatRelative(gate.updatedAt)}
-
- ))}
-
- >
- );
-}
-
-function resolveReviewTarget(
- agent: SdlcReviewAgentRecord,
- orgId: string,
- migrationReports: MigrationReportRecord[],
- policies: PolicyRuleRecord[],
-): { type: SdlcReviewTargetType; ref: string; label: string; ready: boolean } {
- if (agent.key === SDLC_REVIEW_AGENT_KEY.MIGRATION_REVIEWER) {
- const report = migrationReports[0] ?? null;
- return {
- type: SDLC_REVIEW_TARGET_TYPE.MIGRATION,
- ref: report?.id ?? orgId,
- label: report ? "migration" : "migration report",
- ready: Boolean(report),
- };
- }
- if (agent.key === SDLC_REVIEW_AGENT_KEY.POLICY_REVIEWER) {
- const policy = policies[0] ?? null;
- return {
- type: SDLC_REVIEW_TARGET_TYPE.POLICY,
- ref: policy?.id ?? orgId,
- label: policy ? "policy" : "policy rule",
- ready: Boolean(policy),
- };
- }
- return { type: SDLC_REVIEW_TARGET_TYPE.WORKSPACE, ref: orgId, label: "workspace", ready: true };
-}
diff --git a/AgentCompany-New/src/renderer/src/shared/Shell.tsx b/AgentCompany-New/src/renderer/src/shared/Shell.tsx
index fd94d674..417a9128 100644
--- a/AgentCompany-New/src/renderer/src/shared/Shell.tsx
+++ b/AgentCompany-New/src/renderer/src/shared/Shell.tsx
@@ -14,7 +14,6 @@ export type RouteId =
| "files"
| "docs"
| "knowledge"
- | "automation"
| "inbox"
| "runs"
| "meetings"
@@ -35,18 +34,17 @@ const FLUSH_ROUTES = new Set(["chat", "settings", "files", "social", "r
const primaryNav: NavSpec[] = [
{ id: "home", label: "Home", icon: "home" },
- { id: "team", label: "Team", icon: "team" },
+ { id: "inbox", label: "Inbox", icon: "approve" },
{ id: "work", label: "Work", icon: "work" },
+ { id: "approvals", label: "Approvals", icon: "approve" },
+ { id: "team", label: "Team", icon: "team" },
{ id: "chat", label: "Messages", icon: "chat" },
{ id: "files", label: "Files", icon: "docs" },
- { id: "inbox", label: "Inbox", icon: "approve" },
{ id: "docs", label: "Documents", icon: "file" },
{ id: "knowledge", label: "Knowledge", icon: "sparkle" },
{ id: "runs", label: "Runs", icon: "send" },
- { id: "automation", label: "Automation", icon: "bot" },
{ id: "meetings", label: "Meetings", icon: "team" },
{ id: "sprints", label: "Sprints", icon: "work" },
- { id: "approvals", label: "Approvals", icon: "approve" },
{ id: "social", label: "Social", icon: "social" },
];
@@ -134,7 +132,6 @@ export function Shell({
diff --git a/AgentCompany-New/tests/e2e/desktop.spec.ts b/AgentCompany-New/tests/e2e/desktop.spec.ts
index 36125948..762be85c 100644
--- a/AgentCompany-New/tests/e2e/desktop.spec.ts
+++ b/AgentCompany-New/tests/e2e/desktop.spec.ts
@@ -76,29 +76,6 @@ test("onboards, hires, and creates work in the Electron shell", async () => {
expect(hiredAgent.workspaceId).toBe(hiredAgent.primaryWorkspaceId);
expect(hiredAgent.heartbeatEnabled).toBe(true);
expect(hiredAgent.heartbeatIntervalSec).toBe(120);
- await page.getByRole("button", { name: "Settings" }).click();
- await page.getByRole("button", { name: "Members" }).click();
- await expect(page.getByText("Identity & Access")).toBeVisible();
- await expect(page.getByText("org admin").first()).toBeVisible();
- await expect(page.getByText("scoped agent").first()).toBeVisible();
- await page.getByRole("button", { name: "Policies" }).click();
- await expect(page.getByText("Hiring policies")).toBeVisible();
- await expect(page.getByText("Review routing")).toBeVisible();
- await page.getByRole("button", { name: "Operations", exact: true }).click();
- await expect(page.getByText("Feature flags")).toBeVisible();
- await expect(page.getByText("SLO targets")).toBeVisible();
- await expect(page.getByText("Chaos drills").first()).toBeVisible();
- await page.getByRole("button", { name: "Run" }).first().click();
- await expect(page.getByText("passed").first()).toBeVisible();
- await page.getByRole("button", { name: "SDLC", exact: true }).click();
- await expect(page.getByText("Review agents", { exact: true })).toBeVisible();
- await expect(page.getByText("Eval suites", { exact: true })).toBeVisible();
- await expect(page.getByText("PR bot gates", { exact: true })).toBeVisible();
- await page.getByRole("button", { name: "Run" }).first().click();
- await expect(page.getByText("passed").first()).toBeVisible();
- await page.getByRole("button", { name: "Run" }).nth(3).click();
- await expect(page.getByText(/passed ·/).first()).toBeVisible();
-
await page.getByRole("button", { name: "Work", exact: true }).click();
await page.getByRole("button", { name: "New task" }).click();
await page.getByLabel("Title").fill("Production deploy");
@@ -177,14 +154,6 @@ test("onboards, hires, and creates work in the Electron shell", async () => {
await expect(page.getByText("Never run").first()).toBeVisible();
await page.getByRole("button", { name: "Run tests" }).click();
await expect(page.getByText("1/1 passed").first()).toBeVisible();
- await page.getByRole("button", { name: "Compliance" }).click();
- await page.getByRole("button", { name: "Create" }).click();
- await expect(page.getByText("gdpr export · employee").first()).toBeVisible();
- await expect(page.getByText("Thread replay")).toBeVisible();
- await page.getByRole("button", { name: "Run" }).click();
- await expect(page.getByText("Replay runs", { exact: true })).toBeVisible();
- await expect(page.getByText(/\d+ events ·/).first()).toBeVisible();
-
const legacyPath = createLegacyDatabase();
await page.getByRole("button", { name: "Migration" }).click();
await page.getByRole("button", { name: "Report" }).click();
@@ -238,7 +207,7 @@ async function verifyPagesDoNotOverflow(page: Page): Promise {
await page.getByRole("button", { name: nav, exact: true }).click();
await expectPageToFit(page);
}
- for (const tab of ["Workspace", "Members", "Billing", "Models", "Providers", "Skills", "Policies", "Operations", "SDLC", "Compliance", "Migration", "Profile", "Notifications", "Security"]) {
+ for (const tab of ["Workspace", "Billing", "Providers", "Skills", "Migration"]) {
await page.getByRole("button", { name: "Settings" }).click();
await page.getByRole("button", { name: tab, exact: true }).click();
await expectPageToFit(page);
diff --git a/AgentCompany-New/tests/e2e/screenshots.spec.ts b/AgentCompany-New/tests/e2e/screenshots.spec.ts
index 31b696b0..e6b1872e 100644
--- a/AgentCompany-New/tests/e2e/screenshots.spec.ts
+++ b/AgentCompany-New/tests/e2e/screenshots.spec.ts
@@ -49,7 +49,7 @@ test("captures every page for visual review", async () => {
await go(page, "Social", outDir, "16-social");
await go(page, "Settings", outDir, "17-settings");
- for (const tab of ["Workspace", "Members", "Billing", "Models", "Skills", "Policies", "Compliance", "Migration", "Profile", "Notifications", "Security"]) {
+ for (const tab of ["Workspace", "Billing", "Skills", "Migration"]) {
await page.getByRole("button", { name: "Settings" }).click();
await page.getByRole("button", { name: tab }).first().click();
await snap(page, outDir, `settings-${tab.toLowerCase()}`);